diff options
527 files changed, 20374 insertions, 3737 deletions
@@ -3401,10 +3401,10 @@ S: Czech Republic | |||
3401 | 3401 | ||
3402 | N: Thibaut Varene | 3402 | N: Thibaut Varene |
3403 | E: T-Bone@parisc-linux.org | 3403 | E: T-Bone@parisc-linux.org |
3404 | W: http://www.parisc-linux.org/ | 3404 | W: http://www.parisc-linux.org/~varenet/ |
3405 | P: 1024D/B7D2F063 E67C 0D43 A75E 12A5 BB1C FA2F 1E32 C3DA B7D2 F063 | 3405 | P: 1024D/B7D2F063 E67C 0D43 A75E 12A5 BB1C FA2F 1E32 C3DA B7D2 F063 |
3406 | D: PA-RISC port minion, PDC and GSCPS2 drivers, debuglocks and other bits | 3406 | D: PA-RISC port minion, PDC and GSCPS2 drivers, debuglocks and other bits |
3407 | D: Some bits in an ARM port, S1D13XXX FB driver, random patches here and there | 3407 | D: Some ARM at91rm9200 bits, S1D13XXX FB driver, random patches here and there |
3408 | D: AD1889 sound driver | 3408 | D: AD1889 sound driver |
3409 | S: Paris, France | 3409 | S: Paris, France |
3410 | 3410 | ||
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile index 5a2882d275ba..66e1cf733571 100644 --- a/Documentation/DocBook/Makefile +++ b/Documentation/DocBook/Makefile | |||
@@ -10,7 +10,8 @@ DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \ | |||
10 | kernel-hacking.xml kernel-locking.xml deviceiobook.xml \ | 10 | kernel-hacking.xml kernel-locking.xml deviceiobook.xml \ |
11 | procfs-guide.xml writing_usb_driver.xml \ | 11 | procfs-guide.xml writing_usb_driver.xml \ |
12 | kernel-api.xml journal-api.xml lsm.xml usb.xml \ | 12 | kernel-api.xml journal-api.xml lsm.xml usb.xml \ |
13 | gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml | 13 | gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \ |
14 | genericirq.xml | ||
14 | 15 | ||
15 | ### | 16 | ### |
16 | # The build process is as follows (targets): | 17 | # The build process is as follows (targets): |
diff --git a/Documentation/DocBook/genericirq.tmpl b/Documentation/DocBook/genericirq.tmpl new file mode 100644 index 000000000000..0f4a4b6321e4 --- /dev/null +++ b/Documentation/DocBook/genericirq.tmpl | |||
@@ -0,0 +1,474 @@ | |||
1 | <?xml version="1.0" encoding="UTF-8"?> | ||
2 | <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" | ||
3 | "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []> | ||
4 | |||
5 | <book id="Generic-IRQ-Guide"> | ||
6 | <bookinfo> | ||
7 | <title>Linux generic IRQ handling</title> | ||
8 | |||
9 | <authorgroup> | ||
10 | <author> | ||
11 | <firstname>Thomas</firstname> | ||
12 | <surname>Gleixner</surname> | ||
13 | <affiliation> | ||
14 | <address> | ||
15 | <email>tglx@linutronix.de</email> | ||
16 | </address> | ||
17 | </affiliation> | ||
18 | </author> | ||
19 | <author> | ||
20 | <firstname>Ingo</firstname> | ||
21 | <surname>Molnar</surname> | ||
22 | <affiliation> | ||
23 | <address> | ||
24 | <email>mingo@elte.hu</email> | ||
25 | </address> | ||
26 | </affiliation> | ||
27 | </author> | ||
28 | </authorgroup> | ||
29 | |||
30 | <copyright> | ||
31 | <year>2005-2006</year> | ||
32 | <holder>Thomas Gleixner</holder> | ||
33 | </copyright> | ||
34 | <copyright> | ||
35 | <year>2005-2006</year> | ||
36 | <holder>Ingo Molnar</holder> | ||
37 | </copyright> | ||
38 | |||
39 | <legalnotice> | ||
40 | <para> | ||
41 | This documentation is free software; you can redistribute | ||
42 | it and/or modify it under the terms of the GNU General Public | ||
43 | License version 2 as published by the Free Software Foundation. | ||
44 | </para> | ||
45 | |||
46 | <para> | ||
47 | This program is distributed in the hope that it will be | ||
48 | useful, but WITHOUT ANY WARRANTY; without even the implied | ||
49 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
50 | See the GNU General Public License for more details. | ||
51 | </para> | ||
52 | |||
53 | <para> | ||
54 | You should have received a copy of the GNU General Public | ||
55 | License along with this program; if not, write to the Free | ||
56 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
57 | MA 02111-1307 USA | ||
58 | </para> | ||
59 | |||
60 | <para> | ||
61 | For more details see the file COPYING in the source | ||
62 | distribution of Linux. | ||
63 | </para> | ||
64 | </legalnotice> | ||
65 | </bookinfo> | ||
66 | |||
67 | <toc></toc> | ||
68 | |||
69 | <chapter id="intro"> | ||
70 | <title>Introduction</title> | ||
71 | <para> | ||
72 | The generic interrupt handling layer is designed to provide a | ||
73 | complete abstraction of interrupt handling for device drivers. | ||
74 | It is able to handle all the different types of interrupt controller | ||
75 | hardware. Device drivers use generic API functions to request, enable, | ||
76 | disable and free interrupts. The drivers do not have to know anything | ||
77 | about interrupt hardware details, so they can be used on different | ||
78 | platforms without code changes. | ||
79 | </para> | ||
80 | <para> | ||
81 | This documentation is provided to developers who want to implement | ||
82 | an interrupt subsystem based for their architecture, with the help | ||
83 | of the generic IRQ handling layer. | ||
84 | </para> | ||
85 | </chapter> | ||
86 | |||
87 | <chapter id="rationale"> | ||
88 | <title>Rationale</title> | ||
89 | <para> | ||
90 | The original implementation of interrupt handling in Linux is using | ||
91 | the __do_IRQ() super-handler, which is able to deal with every | ||
92 | type of interrupt logic. | ||
93 | </para> | ||
94 | <para> | ||
95 | Originally, Russell King identified different types of handlers to | ||
96 | build a quite universal set for the ARM interrupt handler | ||
97 | implementation in Linux 2.5/2.6. He distinguished between: | ||
98 | <itemizedlist> | ||
99 | <listitem><para>Level type</para></listitem> | ||
100 | <listitem><para>Edge type</para></listitem> | ||
101 | <listitem><para>Simple type</para></listitem> | ||
102 | </itemizedlist> | ||
103 | In the SMP world of the __do_IRQ() super-handler another type | ||
104 | was identified: | ||
105 | <itemizedlist> | ||
106 | <listitem><para>Per CPU type</para></listitem> | ||
107 | </itemizedlist> | ||
108 | </para> | ||
109 | <para> | ||
110 | This split implementation of highlevel IRQ handlers allows us to | ||
111 | optimize the flow of the interrupt handling for each specific | ||
112 | interrupt type. This reduces complexity in that particular codepath | ||
113 | and allows the optimized handling of a given type. | ||
114 | </para> | ||
115 | <para> | ||
116 | The original general IRQ implementation used hw_interrupt_type | ||
117 | structures and their ->ack(), ->end() [etc.] callbacks to | ||
118 | differentiate the flow control in the super-handler. This leads to | ||
119 | a mix of flow logic and lowlevel hardware logic, and it also leads | ||
120 | to unnecessary code duplication: for example in i386, there is a | ||
121 | ioapic_level_irq and a ioapic_edge_irq irq-type which share many | ||
122 | of the lowlevel details but have different flow handling. | ||
123 | </para> | ||
124 | <para> | ||
125 | A more natural abstraction is the clean separation of the | ||
126 | 'irq flow' and the 'chip details'. | ||
127 | </para> | ||
128 | <para> | ||
129 | Analysing a couple of architecture's IRQ subsystem implementations | ||
130 | reveals that most of them can use a generic set of 'irq flow' | ||
131 | methods and only need to add the chip level specific code. | ||
132 | The separation is also valuable for (sub)architectures | ||
133 | which need specific quirks in the irq flow itself but not in the | ||
134 | chip-details - and thus provides a more transparent IRQ subsystem | ||
135 | design. | ||
136 | </para> | ||
137 | <para> | ||
138 | Each interrupt descriptor is assigned its own highlevel flow | ||
139 | handler, which is normally one of the generic | ||
140 | implementations. (This highlevel flow handler implementation also | ||
141 | makes it simple to provide demultiplexing handlers which can be | ||
142 | found in embedded platforms on various architectures.) | ||
143 | </para> | ||
144 | <para> | ||
145 | The separation makes the generic interrupt handling layer more | ||
146 | flexible and extensible. For example, an (sub)architecture can | ||
147 | use a generic irq-flow implementation for 'level type' interrupts | ||
148 | and add a (sub)architecture specific 'edge type' implementation. | ||
149 | </para> | ||
150 | <para> | ||
151 | To make the transition to the new model easier and prevent the | ||
152 | breakage of existing implementations, the __do_IRQ() super-handler | ||
153 | is still available. This leads to a kind of duality for the time | ||
154 | being. Over time the new model should be used in more and more | ||
155 | architectures, as it enables smaller and cleaner IRQ subsystems. | ||
156 | </para> | ||
157 | </chapter> | ||
158 | <chapter id="bugs"> | ||
159 | <title>Known Bugs And Assumptions</title> | ||
160 | <para> | ||
161 | None (knock on wood). | ||
162 | </para> | ||
163 | </chapter> | ||
164 | |||
165 | <chapter id="Abstraction"> | ||
166 | <title>Abstraction layers</title> | ||
167 | <para> | ||
168 | There are three main levels of abstraction in the interrupt code: | ||
169 | <orderedlist> | ||
170 | <listitem><para>Highlevel driver API</para></listitem> | ||
171 | <listitem><para>Highlevel IRQ flow handlers</para></listitem> | ||
172 | <listitem><para>Chiplevel hardware encapsulation</para></listitem> | ||
173 | </orderedlist> | ||
174 | </para> | ||
175 | <sect1> | ||
176 | <title>Interrupt control flow</title> | ||
177 | <para> | ||
178 | Each interrupt is described by an interrupt descriptor structure | ||
179 | irq_desc. The interrupt is referenced by an 'unsigned int' numeric | ||
180 | value which selects the corresponding interrupt decription structure | ||
181 | in the descriptor structures array. | ||
182 | The descriptor structure contains status information and pointers | ||
183 | to the interrupt flow method and the interrupt chip structure | ||
184 | which are assigned to this interrupt. | ||
185 | </para> | ||
186 | <para> | ||
187 | Whenever an interrupt triggers, the lowlevel arch code calls into | ||
188 | the generic interrupt code by calling desc->handle_irq(). | ||
189 | This highlevel IRQ handling function only uses desc->chip primitives | ||
190 | referenced by the assigned chip descriptor structure. | ||
191 | </para> | ||
192 | </sect1> | ||
193 | <sect1> | ||
194 | <title>Highlevel Driver API</title> | ||
195 | <para> | ||
196 | The highlevel Driver API consists of following functions: | ||
197 | <itemizedlist> | ||
198 | <listitem><para>request_irq()</para></listitem> | ||
199 | <listitem><para>free_irq()</para></listitem> | ||
200 | <listitem><para>disable_irq()</para></listitem> | ||
201 | <listitem><para>enable_irq()</para></listitem> | ||
202 | <listitem><para>disable_irq_nosync() (SMP only)</para></listitem> | ||
203 | <listitem><para>synchronize_irq() (SMP only)</para></listitem> | ||
204 | <listitem><para>set_irq_type()</para></listitem> | ||
205 | <listitem><para>set_irq_wake()</para></listitem> | ||
206 | <listitem><para>set_irq_data()</para></listitem> | ||
207 | <listitem><para>set_irq_chip()</para></listitem> | ||
208 | <listitem><para>set_irq_chip_data()</para></listitem> | ||
209 | </itemizedlist> | ||
210 | See the autogenerated function documentation for details. | ||
211 | </para> | ||
212 | </sect1> | ||
213 | <sect1> | ||
214 | <title>Highlevel IRQ flow handlers</title> | ||
215 | <para> | ||
216 | The generic layer provides a set of pre-defined irq-flow methods: | ||
217 | <itemizedlist> | ||
218 | <listitem><para>handle_level_irq</para></listitem> | ||
219 | <listitem><para>handle_edge_irq</para></listitem> | ||
220 | <listitem><para>handle_simple_irq</para></listitem> | ||
221 | <listitem><para>handle_percpu_irq</para></listitem> | ||
222 | </itemizedlist> | ||
223 | The interrupt flow handlers (either predefined or architecture | ||
224 | specific) are assigned to specific interrupts by the architecture | ||
225 | either during bootup or during device initialization. | ||
226 | </para> | ||
227 | <sect2> | ||
228 | <title>Default flow implementations</title> | ||
229 | <sect3> | ||
230 | <title>Helper functions</title> | ||
231 | <para> | ||
232 | The helper functions call the chip primitives and | ||
233 | are used by the default flow implementations. | ||
234 | The following helper functions are implemented (simplified excerpt): | ||
235 | <programlisting> | ||
236 | default_enable(irq) | ||
237 | { | ||
238 | desc->chip->unmask(irq); | ||
239 | } | ||
240 | |||
241 | default_disable(irq) | ||
242 | { | ||
243 | if (!delay_disable(irq)) | ||
244 | desc->chip->mask(irq); | ||
245 | } | ||
246 | |||
247 | default_ack(irq) | ||
248 | { | ||
249 | chip->ack(irq); | ||
250 | } | ||
251 | |||
252 | default_mask_ack(irq) | ||
253 | { | ||
254 | if (chip->mask_ack) { | ||
255 | chip->mask_ack(irq); | ||
256 | } else { | ||
257 | chip->mask(irq); | ||
258 | chip->ack(irq); | ||
259 | } | ||
260 | } | ||
261 | |||
262 | noop(irq) | ||
263 | { | ||
264 | } | ||
265 | |||
266 | </programlisting> | ||
267 | </para> | ||
268 | </sect3> | ||
269 | </sect2> | ||
270 | <sect2> | ||
271 | <title>Default flow handler implementations</title> | ||
272 | <sect3> | ||
273 | <title>Default Level IRQ flow handler</title> | ||
274 | <para> | ||
275 | handle_level_irq provides a generic implementation | ||
276 | for level-triggered interrupts. | ||
277 | </para> | ||
278 | <para> | ||
279 | The following control flow is implemented (simplified excerpt): | ||
280 | <programlisting> | ||
281 | desc->chip->start(); | ||
282 | handle_IRQ_event(desc->action); | ||
283 | desc->chip->end(); | ||
284 | </programlisting> | ||
285 | </para> | ||
286 | </sect3> | ||
287 | <sect3> | ||
288 | <title>Default Edge IRQ flow handler</title> | ||
289 | <para> | ||
290 | handle_edge_irq provides a generic implementation | ||
291 | for edge-triggered interrupts. | ||
292 | </para> | ||
293 | <para> | ||
294 | The following control flow is implemented (simplified excerpt): | ||
295 | <programlisting> | ||
296 | if (desc->status & running) { | ||
297 | desc->chip->hold(); | ||
298 | desc->status |= pending | masked; | ||
299 | return; | ||
300 | } | ||
301 | desc->chip->start(); | ||
302 | desc->status |= running; | ||
303 | do { | ||
304 | if (desc->status & masked) | ||
305 | desc->chip->enable(); | ||
306 | desc-status &= ~pending; | ||
307 | handle_IRQ_event(desc->action); | ||
308 | } while (status & pending); | ||
309 | desc-status &= ~running; | ||
310 | desc->chip->end(); | ||
311 | </programlisting> | ||
312 | </para> | ||
313 | </sect3> | ||
314 | <sect3> | ||
315 | <title>Default simple IRQ flow handler</title> | ||
316 | <para> | ||
317 | handle_simple_irq provides a generic implementation | ||
318 | for simple interrupts. | ||
319 | </para> | ||
320 | <para> | ||
321 | Note: The simple flow handler does not call any | ||
322 | handler/chip primitives. | ||
323 | </para> | ||
324 | <para> | ||
325 | The following control flow is implemented (simplified excerpt): | ||
326 | <programlisting> | ||
327 | handle_IRQ_event(desc->action); | ||
328 | </programlisting> | ||
329 | </para> | ||
330 | </sect3> | ||
331 | <sect3> | ||
332 | <title>Default per CPU flow handler</title> | ||
333 | <para> | ||
334 | handle_percpu_irq provides a generic implementation | ||
335 | for per CPU interrupts. | ||
336 | </para> | ||
337 | <para> | ||
338 | Per CPU interrupts are only available on SMP and | ||
339 | the handler provides a simplified version without | ||
340 | locking. | ||
341 | </para> | ||
342 | <para> | ||
343 | The following control flow is implemented (simplified excerpt): | ||
344 | <programlisting> | ||
345 | desc->chip->start(); | ||
346 | handle_IRQ_event(desc->action); | ||
347 | desc->chip->end(); | ||
348 | </programlisting> | ||
349 | </para> | ||
350 | </sect3> | ||
351 | </sect2> | ||
352 | <sect2> | ||
353 | <title>Quirks and optimizations</title> | ||
354 | <para> | ||
355 | The generic functions are intended for 'clean' architectures and chips, | ||
356 | which have no platform-specific IRQ handling quirks. If an architecture | ||
357 | needs to implement quirks on the 'flow' level then it can do so by | ||
358 | overriding the highlevel irq-flow handler. | ||
359 | </para> | ||
360 | </sect2> | ||
361 | <sect2> | ||
362 | <title>Delayed interrupt disable</title> | ||
363 | <para> | ||
364 | This per interrupt selectable feature, which was introduced by Russell | ||
365 | King in the ARM interrupt implementation, does not mask an interrupt | ||
366 | at the hardware level when disable_irq() is called. The interrupt is | ||
367 | kept enabled and is masked in the flow handler when an interrupt event | ||
368 | happens. This prevents losing edge interrupts on hardware which does | ||
369 | not store an edge interrupt event while the interrupt is disabled at | ||
370 | the hardware level. When an interrupt arrives while the IRQ_DISABLED | ||
371 | flag is set, then the interrupt is masked at the hardware level and | ||
372 | the IRQ_PENDING bit is set. When the interrupt is re-enabled by | ||
373 | enable_irq() the pending bit is checked and if it is set, the | ||
374 | interrupt is resent either via hardware or by a software resend | ||
375 | mechanism. (It's necessary to enable CONFIG_HARDIRQS_SW_RESEND when | ||
376 | you want to use the delayed interrupt disable feature and your | ||
377 | hardware is not capable of retriggering an interrupt.) | ||
378 | The delayed interrupt disable can be runtime enabled, per interrupt, | ||
379 | by setting the IRQ_DELAYED_DISABLE flag in the irq_desc status field. | ||
380 | </para> | ||
381 | </sect2> | ||
382 | </sect1> | ||
383 | <sect1> | ||
384 | <title>Chiplevel hardware encapsulation</title> | ||
385 | <para> | ||
386 | The chip level hardware descriptor structure irq_chip | ||
387 | contains all the direct chip relevant functions, which | ||
388 | can be utilized by the irq flow implementations. | ||
389 | <itemizedlist> | ||
390 | <listitem><para>ack()</para></listitem> | ||
391 | <listitem><para>mask_ack() - Optional, recommended for performance</para></listitem> | ||
392 | <listitem><para>mask()</para></listitem> | ||
393 | <listitem><para>unmask()</para></listitem> | ||
394 | <listitem><para>retrigger() - Optional</para></listitem> | ||
395 | <listitem><para>set_type() - Optional</para></listitem> | ||
396 | <listitem><para>set_wake() - Optional</para></listitem> | ||
397 | </itemizedlist> | ||
398 | These primitives are strictly intended to mean what they say: ack means | ||
399 | ACK, masking means masking of an IRQ line, etc. It is up to the flow | ||
400 | handler(s) to use these basic units of lowlevel functionality. | ||
401 | </para> | ||
402 | </sect1> | ||
403 | </chapter> | ||
404 | |||
405 | <chapter id="doirq"> | ||
406 | <title>__do_IRQ entry point</title> | ||
407 | <para> | ||
408 | The original implementation __do_IRQ() is an alternative entry | ||
409 | point for all types of interrupts. | ||
410 | </para> | ||
411 | <para> | ||
412 | This handler turned out to be not suitable for all | ||
413 | interrupt hardware and was therefore reimplemented with split | ||
414 | functionality for egde/level/simple/percpu interrupts. This is not | ||
415 | only a functional optimization. It also shortens code paths for | ||
416 | interrupts. | ||
417 | </para> | ||
418 | <para> | ||
419 | To make use of the split implementation, replace the call to | ||
420 | __do_IRQ by a call to desc->chip->handle_irq() and associate | ||
421 | the appropriate handler function to desc->chip->handle_irq(). | ||
422 | In most cases the generic handler implementations should | ||
423 | be sufficient. | ||
424 | </para> | ||
425 | </chapter> | ||
426 | |||
427 | <chapter id="locking"> | ||
428 | <title>Locking on SMP</title> | ||
429 | <para> | ||
430 | The locking of chip registers is up to the architecture that | ||
431 | defines the chip primitives. There is a chip->lock field that can be used | ||
432 | for serialization, but the generic layer does not touch it. The per-irq | ||
433 | structure is protected via desc->lock, by the generic layer. | ||
434 | </para> | ||
435 | </chapter> | ||
436 | <chapter id="structs"> | ||
437 | <title>Structures</title> | ||
438 | <para> | ||
439 | This chapter contains the autogenerated documentation of the structures which are | ||
440 | used in the generic IRQ layer. | ||
441 | </para> | ||
442 | !Iinclude/linux/irq.h | ||
443 | </chapter> | ||
444 | |||
445 | <chapter id="pubfunctions"> | ||
446 | <title>Public Functions Provided</title> | ||
447 | <para> | ||
448 | This chapter contains the autogenerated documentation of the kernel API functions | ||
449 | which are exported. | ||
450 | </para> | ||
451 | !Ekernel/irq/manage.c | ||
452 | !Ekernel/irq/chip.c | ||
453 | </chapter> | ||
454 | |||
455 | <chapter id="intfunctions"> | ||
456 | <title>Internal Functions Provided</title> | ||
457 | <para> | ||
458 | This chapter contains the autogenerated documentation of the internal functions. | ||
459 | </para> | ||
460 | !Ikernel/irq/handle.c | ||
461 | !Ikernel/irq/chip.c | ||
462 | </chapter> | ||
463 | |||
464 | <chapter id="credits"> | ||
465 | <title>Credits</title> | ||
466 | <para> | ||
467 | The following people have contributed to this document: | ||
468 | <orderedlist> | ||
469 | <listitem><para>Thomas Gleixner<email>tglx@linutronix.de</email></para></listitem> | ||
470 | <listitem><para>Ingo Molnar<email>mingo@elte.hu</email></para></listitem> | ||
471 | </orderedlist> | ||
472 | </para> | ||
473 | </chapter> | ||
474 | </book> | ||
diff --git a/Documentation/IRQ.txt b/Documentation/IRQ.txt new file mode 100644 index 000000000000..1011e7175021 --- /dev/null +++ b/Documentation/IRQ.txt | |||
@@ -0,0 +1,22 @@ | |||
1 | What is an IRQ? | ||
2 | |||
3 | An IRQ is an interrupt request from a device. | ||
4 | Currently they can come in over a pin, or over a packet. | ||
5 | Several devices may be connected to the same pin thus | ||
6 | sharing an IRQ. | ||
7 | |||
8 | An IRQ number is a kernel identifier used to talk about a hardware | ||
9 | interrupt source. Typically this is an index into the global irq_desc | ||
10 | array, but except for what linux/interrupt.h implements the details | ||
11 | are architecture specific. | ||
12 | |||
13 | An IRQ number is an enumeration of the possible interrupt sources on a | ||
14 | machine. Typically what is enumerated is the number of input pins on | ||
15 | all of the interrupt controller in the system. In the case of ISA | ||
16 | what is enumerated are the 16 input pins on the two i8259 interrupt | ||
17 | controllers. | ||
18 | |||
19 | Architectures can assign additional meaning to the IRQ numbers, and | ||
20 | are encouraged to in the case where there is any manual configuration | ||
21 | of the hardware involved. The ISA IRQs are a classic example of | ||
22 | assigning this kind of additional meaning. | ||
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 0d189c93eeaf..25f8d20dac53 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -1689,9 +1689,14 @@ running once the system is up. | |||
1689 | decrease the size and leave more room for directly | 1689 | decrease the size and leave more room for directly |
1690 | mapped kernel RAM. | 1690 | mapped kernel RAM. |
1691 | 1691 | ||
1692 | vmhalt= [KNL,S390] | 1692 | vmhalt= [KNL,S390] Perform z/VM CP command after system halt. |
1693 | Format: <command> | ||
1693 | 1694 | ||
1694 | vmpoff= [KNL,S390] | 1695 | vmpanic= [KNL,S390] Perform z/VM CP command after kernel panic. |
1696 | Format: <command> | ||
1697 | |||
1698 | vmpoff= [KNL,S390] Perform z/VM CP command after power off. | ||
1699 | Format: <command> | ||
1695 | 1700 | ||
1696 | waveartist= [HW,OSS] | 1701 | waveartist= [HW,OSS] |
1697 | Format: <io>,<irq>,<dma>,<dma2> | 1702 | Format: <io>,<irq>,<dma>,<dma2> |
diff --git a/Documentation/keys-request-key.txt b/Documentation/keys-request-key.txt index 22488d791168..c1f64fdf84cb 100644 --- a/Documentation/keys-request-key.txt +++ b/Documentation/keys-request-key.txt | |||
@@ -3,16 +3,23 @@ | |||
3 | =================== | 3 | =================== |
4 | 4 | ||
5 | The key request service is part of the key retention service (refer to | 5 | The key request service is part of the key retention service (refer to |
6 | Documentation/keys.txt). This document explains more fully how that the | 6 | Documentation/keys.txt). This document explains more fully how the requesting |
7 | requesting algorithm works. | 7 | algorithm works. |
8 | 8 | ||
9 | The process starts by either the kernel requesting a service by calling | 9 | The process starts by either the kernel requesting a service by calling |
10 | request_key(): | 10 | request_key*(): |
11 | 11 | ||
12 | struct key *request_key(const struct key_type *type, | 12 | struct key *request_key(const struct key_type *type, |
13 | const char *description, | 13 | const char *description, |
14 | const char *callout_string); | 14 | const char *callout_string); |
15 | 15 | ||
16 | or: | ||
17 | |||
18 | struct key *request_key_with_auxdata(const struct key_type *type, | ||
19 | const char *description, | ||
20 | const char *callout_string, | ||
21 | void *aux); | ||
22 | |||
16 | Or by userspace invoking the request_key system call: | 23 | Or by userspace invoking the request_key system call: |
17 | 24 | ||
18 | key_serial_t request_key(const char *type, | 25 | key_serial_t request_key(const char *type, |
@@ -20,16 +27,26 @@ Or by userspace invoking the request_key system call: | |||
20 | const char *callout_info, | 27 | const char *callout_info, |
21 | key_serial_t dest_keyring); | 28 | key_serial_t dest_keyring); |
22 | 29 | ||
23 | The main difference between the two access points is that the in-kernel | 30 | The main difference between the access points is that the in-kernel interface |
24 | interface does not need to link the key to a keyring to prevent it from being | 31 | does not need to link the key to a keyring to prevent it from being immediately |
25 | immediately destroyed. The kernel interface returns a pointer directly to the | 32 | destroyed. The kernel interface returns a pointer directly to the key, and |
26 | key, and it's up to the caller to destroy the key. | 33 | it's up to the caller to destroy the key. |
34 | |||
35 | The request_key_with_auxdata() call is like the in-kernel request_key() call, | ||
36 | except that it permits auxiliary data to be passed to the upcaller (the default | ||
37 | is NULL). This is only useful for those key types that define their own upcall | ||
38 | mechanism rather than using /sbin/request-key. | ||
27 | 39 | ||
28 | The userspace interface links the key to a keyring associated with the process | 40 | The userspace interface links the key to a keyring associated with the process |
29 | to prevent the key from going away, and returns the serial number of the key to | 41 | to prevent the key from going away, and returns the serial number of the key to |
30 | the caller. | 42 | the caller. |
31 | 43 | ||
32 | 44 | ||
45 | The following example assumes that the key types involved don't define their | ||
46 | own upcall mechanisms. If they do, then those should be substituted for the | ||
47 | forking and execution of /sbin/request-key. | ||
48 | |||
49 | |||
33 | =========== | 50 | =========== |
34 | THE PROCESS | 51 | THE PROCESS |
35 | =========== | 52 | =========== |
@@ -40,8 +57,8 @@ A request proceeds in the following manner: | |||
40 | interface]. | 57 | interface]. |
41 | 58 | ||
42 | (2) request_key() searches the process's subscribed keyrings to see if there's | 59 | (2) request_key() searches the process's subscribed keyrings to see if there's |
43 | a suitable key there. If there is, it returns the key. If there isn't, and | 60 | a suitable key there. If there is, it returns the key. If there isn't, |
44 | callout_info is not set, an error is returned. Otherwise the process | 61 | and callout_info is not set, an error is returned. Otherwise the process |
45 | proceeds to the next step. | 62 | proceeds to the next step. |
46 | 63 | ||
47 | (3) request_key() sees that A doesn't have the desired key yet, so it creates | 64 | (3) request_key() sees that A doesn't have the desired key yet, so it creates |
@@ -62,7 +79,7 @@ A request proceeds in the following manner: | |||
62 | instantiation. | 79 | instantiation. |
63 | 80 | ||
64 | (7) The program may want to access another key from A's context (say a | 81 | (7) The program may want to access another key from A's context (say a |
65 | Kerberos TGT key). It just requests the appropriate key, and the keyring | 82 | Kerberos TGT key). It just requests the appropriate key, and the keyring |
66 | search notes that the session keyring has auth key V in its bottom level. | 83 | search notes that the session keyring has auth key V in its bottom level. |
67 | 84 | ||
68 | This will permit it to then search the keyrings of process A with the | 85 | This will permit it to then search the keyrings of process A with the |
@@ -79,10 +96,11 @@ A request proceeds in the following manner: | |||
79 | (10) The program then exits 0 and request_key() deletes key V and returns key | 96 | (10) The program then exits 0 and request_key() deletes key V and returns key |
80 | U to the caller. | 97 | U to the caller. |
81 | 98 | ||
82 | This also extends further. If key W (step 7 above) didn't exist, key W would be | 99 | This also extends further. If key W (step 7 above) didn't exist, key W would |
83 | created uninstantiated, another auth key (X) would be created (as per step 3) | 100 | be created uninstantiated, another auth key (X) would be created (as per step |
84 | and another copy of /sbin/request-key spawned (as per step 4); but the context | 101 | 3) and another copy of /sbin/request-key spawned (as per step 4); but the |
85 | specified by auth key X will still be process A, as it was in auth key V. | 102 | context specified by auth key X will still be process A, as it was in auth key |
103 | V. | ||
86 | 104 | ||
87 | This is because process A's keyrings can't simply be attached to | 105 | This is because process A's keyrings can't simply be attached to |
88 | /sbin/request-key at the appropriate places because (a) execve will discard two | 106 | /sbin/request-key at the appropriate places because (a) execve will discard two |
@@ -118,17 +136,17 @@ A search of any particular keyring proceeds in the following fashion: | |||
118 | 136 | ||
119 | (2) It considers all the non-keyring keys within that keyring and, if any key | 137 | (2) It considers all the non-keyring keys within that keyring and, if any key |
120 | matches the criteria specified, calls key_permission(SEARCH) on it to see | 138 | matches the criteria specified, calls key_permission(SEARCH) on it to see |
121 | if the key is allowed to be found. If it is, that key is returned; if | 139 | if the key is allowed to be found. If it is, that key is returned; if |
122 | not, the search continues, and the error code is retained if of higher | 140 | not, the search continues, and the error code is retained if of higher |
123 | priority than the one currently set. | 141 | priority than the one currently set. |
124 | 142 | ||
125 | (3) It then considers all the keyring-type keys in the keyring it's currently | 143 | (3) It then considers all the keyring-type keys in the keyring it's currently |
126 | searching. It calls key_permission(SEARCH) on each keyring, and if this | 144 | searching. It calls key_permission(SEARCH) on each keyring, and if this |
127 | grants permission, it recurses, executing steps (2) and (3) on that | 145 | grants permission, it recurses, executing steps (2) and (3) on that |
128 | keyring. | 146 | keyring. |
129 | 147 | ||
130 | The process stops immediately a valid key is found with permission granted to | 148 | The process stops immediately a valid key is found with permission granted to |
131 | use it. Any error from a previous match attempt is discarded and the key is | 149 | use it. Any error from a previous match attempt is discarded and the key is |
132 | returned. | 150 | returned. |
133 | 151 | ||
134 | When search_process_keyrings() is invoked, it performs the following searches | 152 | When search_process_keyrings() is invoked, it performs the following searches |
@@ -153,7 +171,7 @@ The moment one succeeds, all pending errors are discarded and the found key is | |||
153 | returned. | 171 | returned. |
154 | 172 | ||
155 | Only if all these fail does the whole thing fail with the highest priority | 173 | Only if all these fail does the whole thing fail with the highest priority |
156 | error. Note that several errors may have come from LSM. | 174 | error. Note that several errors may have come from LSM. |
157 | 175 | ||
158 | The error priority is: | 176 | The error priority is: |
159 | 177 | ||
diff --git a/Documentation/keys.txt b/Documentation/keys.txt index 61c0fad2fe2f..e373f0212843 100644 --- a/Documentation/keys.txt +++ b/Documentation/keys.txt | |||
@@ -780,6 +780,17 @@ payload contents" for more information. | |||
780 | See also Documentation/keys-request-key.txt. | 780 | See also Documentation/keys-request-key.txt. |
781 | 781 | ||
782 | 782 | ||
783 | (*) To search for a key, passing auxiliary data to the upcaller, call: | ||
784 | |||
785 | struct key *request_key_with_auxdata(const struct key_type *type, | ||
786 | const char *description, | ||
787 | const char *callout_string, | ||
788 | void *aux); | ||
789 | |||
790 | This is identical to request_key(), except that the auxiliary data is | ||
791 | passed to the key_type->request_key() op if it exists. | ||
792 | |||
793 | |||
783 | (*) When it is no longer required, the key should be released using: | 794 | (*) When it is no longer required, the key should be released using: |
784 | 795 | ||
785 | void key_put(struct key *key); | 796 | void key_put(struct key *key); |
@@ -1031,6 +1042,24 @@ The structure has a number of fields, some of which are mandatory: | |||
1031 | as might happen when the userspace buffer is accessed. | 1042 | as might happen when the userspace buffer is accessed. |
1032 | 1043 | ||
1033 | 1044 | ||
1045 | (*) int (*request_key)(struct key *key, struct key *authkey, const char *op, | ||
1046 | void *aux); | ||
1047 | |||
1048 | This method is optional. If provided, request_key() and | ||
1049 | request_key_with_auxdata() will invoke this function rather than | ||
1050 | upcalling to /sbin/request-key to operate upon a key of this type. | ||
1051 | |||
1052 | The aux parameter is as passed to request_key_with_auxdata() or is NULL | ||
1053 | otherwise. Also passed are the key to be operated upon, the | ||
1054 | authorisation key for this operation and the operation type (currently | ||
1055 | only "create"). | ||
1056 | |||
1057 | This function should return only when the upcall is complete. Upon return | ||
1058 | the authorisation key will be revoked, and the target key will be | ||
1059 | negatively instantiated if it is still uninstantiated. The error will be | ||
1060 | returned to the caller of request_key*(). | ||
1061 | |||
1062 | |||
1034 | ============================ | 1063 | ============================ |
1035 | REQUEST-KEY CALLBACK SERVICE | 1064 | REQUEST-KEY CALLBACK SERVICE |
1036 | ============================ | 1065 | ============================ |
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 87d76a5c73d0..f61af23dd85d 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt | |||
@@ -472,6 +472,22 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
472 | 472 | ||
473 | The power-management is supported. | 473 | The power-management is supported. |
474 | 474 | ||
475 | Module snd-darla20 | ||
476 | ------------------ | ||
477 | |||
478 | Module for Echoaudio Darla20 | ||
479 | |||
480 | This module supports multiple cards. | ||
481 | The driver requires the firmware loader support on kernel. | ||
482 | |||
483 | Module snd-darla24 | ||
484 | ------------------ | ||
485 | |||
486 | Module for Echoaudio Darla24 | ||
487 | |||
488 | This module supports multiple cards. | ||
489 | The driver requires the firmware loader support on kernel. | ||
490 | |||
475 | Module snd-dt019x | 491 | Module snd-dt019x |
476 | ----------------- | 492 | ----------------- |
477 | 493 | ||
@@ -499,6 +515,14 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
499 | 515 | ||
500 | The power-management is supported. | 516 | The power-management is supported. |
501 | 517 | ||
518 | Module snd-echo3g | ||
519 | ----------------- | ||
520 | |||
521 | Module for Echoaudio 3G cards (Gina3G/Layla3G) | ||
522 | |||
523 | This module supports multiple cards. | ||
524 | The driver requires the firmware loader support on kernel. | ||
525 | |||
502 | Module snd-emu10k1 | 526 | Module snd-emu10k1 |
503 | ------------------ | 527 | ------------------ |
504 | 528 | ||
@@ -657,6 +681,22 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
657 | 681 | ||
658 | The power-management is supported. | 682 | The power-management is supported. |
659 | 683 | ||
684 | Module snd-gina20 | ||
685 | ----------------- | ||
686 | |||
687 | Module for Echoaudio Gina20 | ||
688 | |||
689 | This module supports multiple cards. | ||
690 | The driver requires the firmware loader support on kernel. | ||
691 | |||
692 | Module snd-gina24 | ||
693 | ----------------- | ||
694 | |||
695 | Module for Echoaudio Gina24 | ||
696 | |||
697 | This module supports multiple cards. | ||
698 | The driver requires the firmware loader support on kernel. | ||
699 | |||
660 | Module snd-gusclassic | 700 | Module snd-gusclassic |
661 | --------------------- | 701 | --------------------- |
662 | 702 | ||
@@ -760,12 +800,18 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
760 | basic fixed pin assignment w/o SPDIF | 800 | basic fixed pin assignment w/o SPDIF |
761 | auto auto-config reading BIOS (default) | 801 | auto auto-config reading BIOS (default) |
762 | 802 | ||
763 | ALC882/883/885 | 803 | ALC882/885 |
764 | 3stack-dig 3-jack with SPDIF I/O | 804 | 3stack-dig 3-jack with SPDIF I/O |
765 | 6stck-dig 6-jack digital with SPDIF I/O | 805 | 6stck-dig 6-jack digital with SPDIF I/O |
766 | auto auto-config reading BIOS (default) | 806 | auto auto-config reading BIOS (default) |
767 | 807 | ||
768 | ALC861 | 808 | ALC883/888 |
809 | 3stack-dig 3-jack with SPDIF I/O | ||
810 | 6stack-dig 6-jack digital with SPDIF I/O | ||
811 | 6stack-dig-demo 6-stack digital for Intel demo board | ||
812 | auto auto-config reading BIOS (default) | ||
813 | |||
814 | ALC861/660 | ||
769 | 3stack 3-jack | 815 | 3stack 3-jack |
770 | 3stack-dig 3-jack with SPDIF I/O | 816 | 3stack-dig 3-jack with SPDIF I/O |
771 | 6stack-dig 6-jack with SPDIF I/O | 817 | 6stack-dig 6-jack with SPDIF I/O |
@@ -937,6 +983,30 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
937 | driver isn't configured properly or you want to try another | 983 | driver isn't configured properly or you want to try another |
938 | type for testing. | 984 | type for testing. |
939 | 985 | ||
986 | Module snd-indigo | ||
987 | ----------------- | ||
988 | |||
989 | Module for Echoaudio Indigo | ||
990 | |||
991 | This module supports multiple cards. | ||
992 | The driver requires the firmware loader support on kernel. | ||
993 | |||
994 | Module snd-indigodj | ||
995 | ------------------- | ||
996 | |||
997 | Module for Echoaudio Indigo DJ | ||
998 | |||
999 | This module supports multiple cards. | ||
1000 | The driver requires the firmware loader support on kernel. | ||
1001 | |||
1002 | Module snd-indigoio | ||
1003 | ------------------- | ||
1004 | |||
1005 | Module for Echoaudio Indigo IO | ||
1006 | |||
1007 | This module supports multiple cards. | ||
1008 | The driver requires the firmware loader support on kernel. | ||
1009 | |||
940 | Module snd-intel8x0 | 1010 | Module snd-intel8x0 |
941 | ------------------- | 1011 | ------------------- |
942 | 1012 | ||
@@ -1036,6 +1106,22 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
1036 | 1106 | ||
1037 | This module supports multiple cards. | 1107 | This module supports multiple cards. |
1038 | 1108 | ||
1109 | Module snd-layla20 | ||
1110 | ------------------ | ||
1111 | |||
1112 | Module for Echoaudio Layla20 | ||
1113 | |||
1114 | This module supports multiple cards. | ||
1115 | The driver requires the firmware loader support on kernel. | ||
1116 | |||
1117 | Module snd-layla24 | ||
1118 | ------------------ | ||
1119 | |||
1120 | Module for Echoaudio Layla24 | ||
1121 | |||
1122 | This module supports multiple cards. | ||
1123 | The driver requires the firmware loader support on kernel. | ||
1124 | |||
1039 | Module snd-maestro3 | 1125 | Module snd-maestro3 |
1040 | ------------------- | 1126 | ------------------- |
1041 | 1127 | ||
@@ -1056,6 +1142,14 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
1056 | 1142 | ||
1057 | The power-management is supported. | 1143 | The power-management is supported. |
1058 | 1144 | ||
1145 | Module snd-mia | ||
1146 | --------------- | ||
1147 | |||
1148 | Module for Echoaudio Mia | ||
1149 | |||
1150 | This module supports multiple cards. | ||
1151 | The driver requires the firmware loader support on kernel. | ||
1152 | |||
1059 | Module snd-miro | 1153 | Module snd-miro |
1060 | --------------- | 1154 | --------------- |
1061 | 1155 | ||
@@ -1088,6 +1182,14 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
1088 | When no hotplug fw loader is available, you need to load the | 1182 | When no hotplug fw loader is available, you need to load the |
1089 | firmware via mixartloader utility in alsa-tools package. | 1183 | firmware via mixartloader utility in alsa-tools package. |
1090 | 1184 | ||
1185 | Module snd-mona | ||
1186 | --------------- | ||
1187 | |||
1188 | Module for Echoaudio Mona | ||
1189 | |||
1190 | This module supports multiple cards. | ||
1191 | The driver requires the firmware loader support on kernel. | ||
1192 | |||
1091 | Module snd-mpu401 | 1193 | Module snd-mpu401 |
1092 | ----------------- | 1194 | ----------------- |
1093 | 1195 | ||
diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c index da677f829f76..63af36cf7f6e 100644 --- a/arch/alpha/kernel/irq.c +++ b/arch/alpha/kernel/irq.c | |||
@@ -49,15 +49,15 @@ select_smp_affinity(unsigned int irq) | |||
49 | static int last_cpu; | 49 | static int last_cpu; |
50 | int cpu = last_cpu + 1; | 50 | int cpu = last_cpu + 1; |
51 | 51 | ||
52 | if (!irq_desc[irq].handler->set_affinity || irq_user_affinity[irq]) | 52 | if (!irq_desc[irq].chip->set_affinity || irq_user_affinity[irq]) |
53 | return 1; | 53 | return 1; |
54 | 54 | ||
55 | while (!cpu_possible(cpu)) | 55 | while (!cpu_possible(cpu)) |
56 | cpu = (cpu < (NR_CPUS-1) ? cpu + 1 : 0); | 56 | cpu = (cpu < (NR_CPUS-1) ? cpu + 1 : 0); |
57 | last_cpu = cpu; | 57 | last_cpu = cpu; |
58 | 58 | ||
59 | irq_affinity[irq] = cpumask_of_cpu(cpu); | 59 | irq_desc[irq].affinity = cpumask_of_cpu(cpu); |
60 | irq_desc[irq].handler->set_affinity(irq, cpumask_of_cpu(cpu)); | 60 | irq_desc[irq].chip->set_affinity(irq, cpumask_of_cpu(cpu)); |
61 | return 0; | 61 | return 0; |
62 | } | 62 | } |
63 | #endif /* CONFIG_SMP */ | 63 | #endif /* CONFIG_SMP */ |
@@ -93,7 +93,7 @@ show_interrupts(struct seq_file *p, void *v) | |||
93 | for_each_online_cpu(j) | 93 | for_each_online_cpu(j) |
94 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[irq]); | 94 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[irq]); |
95 | #endif | 95 | #endif |
96 | seq_printf(p, " %14s", irq_desc[irq].handler->typename); | 96 | seq_printf(p, " %14s", irq_desc[irq].chip->typename); |
97 | seq_printf(p, " %c%s", | 97 | seq_printf(p, " %c%s", |
98 | (action->flags & SA_INTERRUPT)?'+':' ', | 98 | (action->flags & SA_INTERRUPT)?'+':' ', |
99 | action->name); | 99 | action->name); |
diff --git a/arch/alpha/kernel/irq_alpha.c b/arch/alpha/kernel/irq_alpha.c index 9d34ce26e5ef..f20f2dff9c43 100644 --- a/arch/alpha/kernel/irq_alpha.c +++ b/arch/alpha/kernel/irq_alpha.c | |||
@@ -233,7 +233,7 @@ void __init | |||
233 | init_rtc_irq(void) | 233 | init_rtc_irq(void) |
234 | { | 234 | { |
235 | irq_desc[RTC_IRQ].status = IRQ_DISABLED; | 235 | irq_desc[RTC_IRQ].status = IRQ_DISABLED; |
236 | irq_desc[RTC_IRQ].handler = &rtc_irq_type; | 236 | irq_desc[RTC_IRQ].chip = &rtc_irq_type; |
237 | setup_irq(RTC_IRQ, &timer_irqaction); | 237 | setup_irq(RTC_IRQ, &timer_irqaction); |
238 | } | 238 | } |
239 | 239 | ||
diff --git a/arch/alpha/kernel/irq_i8259.c b/arch/alpha/kernel/irq_i8259.c index b188683b83fd..ac893bd48036 100644 --- a/arch/alpha/kernel/irq_i8259.c +++ b/arch/alpha/kernel/irq_i8259.c | |||
@@ -109,7 +109,7 @@ init_i8259a_irqs(void) | |||
109 | 109 | ||
110 | for (i = 0; i < 16; i++) { | 110 | for (i = 0; i < 16; i++) { |
111 | irq_desc[i].status = IRQ_DISABLED; | 111 | irq_desc[i].status = IRQ_DISABLED; |
112 | irq_desc[i].handler = &i8259a_irq_type; | 112 | irq_desc[i].chip = &i8259a_irq_type; |
113 | } | 113 | } |
114 | 114 | ||
115 | setup_irq(2, &cascade); | 115 | setup_irq(2, &cascade); |
diff --git a/arch/alpha/kernel/irq_pyxis.c b/arch/alpha/kernel/irq_pyxis.c index 146a20b9e3d5..3b581415bab0 100644 --- a/arch/alpha/kernel/irq_pyxis.c +++ b/arch/alpha/kernel/irq_pyxis.c | |||
@@ -120,7 +120,7 @@ init_pyxis_irqs(unsigned long ignore_mask) | |||
120 | if ((ignore_mask >> i) & 1) | 120 | if ((ignore_mask >> i) & 1) |
121 | continue; | 121 | continue; |
122 | irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; | 122 | irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; |
123 | irq_desc[i].handler = &pyxis_irq_type; | 123 | irq_desc[i].chip = &pyxis_irq_type; |
124 | } | 124 | } |
125 | 125 | ||
126 | setup_irq(16+7, &isa_cascade_irqaction); | 126 | setup_irq(16+7, &isa_cascade_irqaction); |
diff --git a/arch/alpha/kernel/irq_srm.c b/arch/alpha/kernel/irq_srm.c index 0a87e466918c..8e4d121f84cc 100644 --- a/arch/alpha/kernel/irq_srm.c +++ b/arch/alpha/kernel/irq_srm.c | |||
@@ -67,7 +67,7 @@ init_srm_irqs(long max, unsigned long ignore_mask) | |||
67 | if (i < 64 && ((ignore_mask >> i) & 1)) | 67 | if (i < 64 && ((ignore_mask >> i) & 1)) |
68 | continue; | 68 | continue; |
69 | irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; | 69 | irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; |
70 | irq_desc[i].handler = &srm_irq_type; | 70 | irq_desc[i].chip = &srm_irq_type; |
71 | } | 71 | } |
72 | } | 72 | } |
73 | 73 | ||
diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c index 2a8b364c822e..4ea6711e55aa 100644 --- a/arch/alpha/kernel/pci.c +++ b/arch/alpha/kernel/pci.c | |||
@@ -124,12 +124,12 @@ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_final); | |||
124 | 124 | ||
125 | void | 125 | void |
126 | pcibios_align_resource(void *data, struct resource *res, | 126 | pcibios_align_resource(void *data, struct resource *res, |
127 | unsigned long size, unsigned long align) | 127 | resource_size_t size, resource_size_t align) |
128 | { | 128 | { |
129 | struct pci_dev *dev = data; | 129 | struct pci_dev *dev = data; |
130 | struct pci_controller *hose = dev->sysdata; | 130 | struct pci_controller *hose = dev->sysdata; |
131 | unsigned long alignto; | 131 | unsigned long alignto; |
132 | unsigned long start = res->start; | 132 | resource_size_t start = res->start; |
133 | 133 | ||
134 | if (res->flags & IORESOURCE_IO) { | 134 | if (res->flags & IORESOURCE_IO) { |
135 | /* Make sure we start at our min on all hoses */ | 135 | /* Make sure we start at our min on all hoses */ |
diff --git a/arch/alpha/kernel/sys_alcor.c b/arch/alpha/kernel/sys_alcor.c index d7f0e97fe56f..1a1a2c7a3d94 100644 --- a/arch/alpha/kernel/sys_alcor.c +++ b/arch/alpha/kernel/sys_alcor.c | |||
@@ -144,7 +144,7 @@ alcor_init_irq(void) | |||
144 | if (i >= 16+20 && i <= 16+30) | 144 | if (i >= 16+20 && i <= 16+30) |
145 | continue; | 145 | continue; |
146 | irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; | 146 | irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; |
147 | irq_desc[i].handler = &alcor_irq_type; | 147 | irq_desc[i].chip = &alcor_irq_type; |
148 | } | 148 | } |
149 | i8259a_irq_type.ack = alcor_isa_mask_and_ack_irq; | 149 | i8259a_irq_type.ack = alcor_isa_mask_and_ack_irq; |
150 | 150 | ||
diff --git a/arch/alpha/kernel/sys_cabriolet.c b/arch/alpha/kernel/sys_cabriolet.c index 8e3374d34c95..8c9e443d93ad 100644 --- a/arch/alpha/kernel/sys_cabriolet.c +++ b/arch/alpha/kernel/sys_cabriolet.c | |||
@@ -124,7 +124,7 @@ common_init_irq(void (*srm_dev_int)(unsigned long v, struct pt_regs *r)) | |||
124 | 124 | ||
125 | for (i = 16; i < 35; ++i) { | 125 | for (i = 16; i < 35; ++i) { |
126 | irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; | 126 | irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; |
127 | irq_desc[i].handler = &cabriolet_irq_type; | 127 | irq_desc[i].chip = &cabriolet_irq_type; |
128 | } | 128 | } |
129 | } | 129 | } |
130 | 130 | ||
diff --git a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c index d5da6b1b28ee..b28c8f1c6e10 100644 --- a/arch/alpha/kernel/sys_dp264.c +++ b/arch/alpha/kernel/sys_dp264.c | |||
@@ -300,7 +300,7 @@ init_tsunami_irqs(struct hw_interrupt_type * ops, int imin, int imax) | |||
300 | long i; | 300 | long i; |
301 | for (i = imin; i <= imax; ++i) { | 301 | for (i = imin; i <= imax; ++i) { |
302 | irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; | 302 | irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; |
303 | irq_desc[i].handler = ops; | 303 | irq_desc[i].chip = ops; |
304 | } | 304 | } |
305 | } | 305 | } |
306 | 306 | ||
diff --git a/arch/alpha/kernel/sys_eb64p.c b/arch/alpha/kernel/sys_eb64p.c index 61a79c354f0b..aeb8e0277905 100644 --- a/arch/alpha/kernel/sys_eb64p.c +++ b/arch/alpha/kernel/sys_eb64p.c | |||
@@ -137,7 +137,7 @@ eb64p_init_irq(void) | |||
137 | 137 | ||
138 | for (i = 16; i < 32; ++i) { | 138 | for (i = 16; i < 32; ++i) { |
139 | irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; | 139 | irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; |
140 | irq_desc[i].handler = &eb64p_irq_type; | 140 | irq_desc[i].chip = &eb64p_irq_type; |
141 | } | 141 | } |
142 | 142 | ||
143 | common_init_isa_dma(); | 143 | common_init_isa_dma(); |
diff --git a/arch/alpha/kernel/sys_eiger.c b/arch/alpha/kernel/sys_eiger.c index bd6e5f0e43c7..64a785baf53a 100644 --- a/arch/alpha/kernel/sys_eiger.c +++ b/arch/alpha/kernel/sys_eiger.c | |||
@@ -154,7 +154,7 @@ eiger_init_irq(void) | |||
154 | 154 | ||
155 | for (i = 16; i < 128; ++i) { | 155 | for (i = 16; i < 128; ++i) { |
156 | irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; | 156 | irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; |
157 | irq_desc[i].handler = &eiger_irq_type; | 157 | irq_desc[i].chip = &eiger_irq_type; |
158 | } | 158 | } |
159 | } | 159 | } |
160 | 160 | ||
diff --git a/arch/alpha/kernel/sys_jensen.c b/arch/alpha/kernel/sys_jensen.c index fcabb7c96a16..0148e095638f 100644 --- a/arch/alpha/kernel/sys_jensen.c +++ b/arch/alpha/kernel/sys_jensen.c | |||
@@ -206,11 +206,11 @@ jensen_init_irq(void) | |||
206 | { | 206 | { |
207 | init_i8259a_irqs(); | 207 | init_i8259a_irqs(); |
208 | 208 | ||
209 | irq_desc[1].handler = &jensen_local_irq_type; | 209 | irq_desc[1].chip = &jensen_local_irq_type; |
210 | irq_desc[4].handler = &jensen_local_irq_type; | 210 | irq_desc[4].chip = &jensen_local_irq_type; |
211 | irq_desc[3].handler = &jensen_local_irq_type; | 211 | irq_desc[3].chip = &jensen_local_irq_type; |
212 | irq_desc[7].handler = &jensen_local_irq_type; | 212 | irq_desc[7].chip = &jensen_local_irq_type; |
213 | irq_desc[9].handler = &jensen_local_irq_type; | 213 | irq_desc[9].chip = &jensen_local_irq_type; |
214 | 214 | ||
215 | common_init_isa_dma(); | 215 | common_init_isa_dma(); |
216 | } | 216 | } |
diff --git a/arch/alpha/kernel/sys_marvel.c b/arch/alpha/kernel/sys_marvel.c index e32fee505220..36d215954376 100644 --- a/arch/alpha/kernel/sys_marvel.c +++ b/arch/alpha/kernel/sys_marvel.c | |||
@@ -303,7 +303,7 @@ init_io7_irqs(struct io7 *io7, | |||
303 | /* Set up the lsi irqs. */ | 303 | /* Set up the lsi irqs. */ |
304 | for (i = 0; i < 128; ++i) { | 304 | for (i = 0; i < 128; ++i) { |
305 | irq_desc[base + i].status = IRQ_DISABLED | IRQ_LEVEL; | 305 | irq_desc[base + i].status = IRQ_DISABLED | IRQ_LEVEL; |
306 | irq_desc[base + i].handler = lsi_ops; | 306 | irq_desc[base + i].chip = lsi_ops; |
307 | } | 307 | } |
308 | 308 | ||
309 | /* Disable the implemented irqs in hardware. */ | 309 | /* Disable the implemented irqs in hardware. */ |
@@ -317,7 +317,7 @@ init_io7_irqs(struct io7 *io7, | |||
317 | /* Set up the msi irqs. */ | 317 | /* Set up the msi irqs. */ |
318 | for (i = 128; i < (128 + 512); ++i) { | 318 | for (i = 128; i < (128 + 512); ++i) { |
319 | irq_desc[base + i].status = IRQ_DISABLED | IRQ_LEVEL; | 319 | irq_desc[base + i].status = IRQ_DISABLED | IRQ_LEVEL; |
320 | irq_desc[base + i].handler = msi_ops; | 320 | irq_desc[base + i].chip = msi_ops; |
321 | } | 321 | } |
322 | 322 | ||
323 | for (i = 0; i < 16; ++i) | 323 | for (i = 0; i < 16; ++i) |
@@ -335,7 +335,7 @@ marvel_init_irq(void) | |||
335 | /* Reserve the legacy irqs. */ | 335 | /* Reserve the legacy irqs. */ |
336 | for (i = 0; i < 16; ++i) { | 336 | for (i = 0; i < 16; ++i) { |
337 | irq_desc[i].status = IRQ_DISABLED; | 337 | irq_desc[i].status = IRQ_DISABLED; |
338 | irq_desc[i].handler = &marvel_legacy_irq_type; | 338 | irq_desc[i].chip = &marvel_legacy_irq_type; |
339 | } | 339 | } |
340 | 340 | ||
341 | /* Init the io7 irqs. */ | 341 | /* Init the io7 irqs. */ |
diff --git a/arch/alpha/kernel/sys_mikasa.c b/arch/alpha/kernel/sys_mikasa.c index d78a0daa6168..b741600e3761 100644 --- a/arch/alpha/kernel/sys_mikasa.c +++ b/arch/alpha/kernel/sys_mikasa.c | |||
@@ -117,7 +117,7 @@ mikasa_init_irq(void) | |||
117 | 117 | ||
118 | for (i = 16; i < 32; ++i) { | 118 | for (i = 16; i < 32; ++i) { |
119 | irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; | 119 | irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; |
120 | irq_desc[i].handler = &mikasa_irq_type; | 120 | irq_desc[i].chip = &mikasa_irq_type; |
121 | } | 121 | } |
122 | 122 | ||
123 | init_i8259a_irqs(); | 123 | init_i8259a_irqs(); |
diff --git a/arch/alpha/kernel/sys_noritake.c b/arch/alpha/kernel/sys_noritake.c index 65061f5d7410..55db02d318d7 100644 --- a/arch/alpha/kernel/sys_noritake.c +++ b/arch/alpha/kernel/sys_noritake.c | |||
@@ -139,7 +139,7 @@ noritake_init_irq(void) | |||
139 | 139 | ||
140 | for (i = 16; i < 48; ++i) { | 140 | for (i = 16; i < 48; ++i) { |
141 | irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; | 141 | irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; |
142 | irq_desc[i].handler = &noritake_irq_type; | 142 | irq_desc[i].chip = &noritake_irq_type; |
143 | } | 143 | } |
144 | 144 | ||
145 | init_i8259a_irqs(); | 145 | init_i8259a_irqs(); |
diff --git a/arch/alpha/kernel/sys_rawhide.c b/arch/alpha/kernel/sys_rawhide.c index 05888a02a604..949607e3d6fb 100644 --- a/arch/alpha/kernel/sys_rawhide.c +++ b/arch/alpha/kernel/sys_rawhide.c | |||
@@ -180,7 +180,7 @@ rawhide_init_irq(void) | |||
180 | 180 | ||
181 | for (i = 16; i < 128; ++i) { | 181 | for (i = 16; i < 128; ++i) { |
182 | irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; | 182 | irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; |
183 | irq_desc[i].handler = &rawhide_irq_type; | 183 | irq_desc[i].chip = &rawhide_irq_type; |
184 | } | 184 | } |
185 | 185 | ||
186 | init_i8259a_irqs(); | 186 | init_i8259a_irqs(); |
diff --git a/arch/alpha/kernel/sys_rx164.c b/arch/alpha/kernel/sys_rx164.c index 58404243057b..6ae506052635 100644 --- a/arch/alpha/kernel/sys_rx164.c +++ b/arch/alpha/kernel/sys_rx164.c | |||
@@ -117,7 +117,7 @@ rx164_init_irq(void) | |||
117 | rx164_update_irq_hw(0); | 117 | rx164_update_irq_hw(0); |
118 | for (i = 16; i < 40; ++i) { | 118 | for (i = 16; i < 40; ++i) { |
119 | irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; | 119 | irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; |
120 | irq_desc[i].handler = &rx164_irq_type; | 120 | irq_desc[i].chip = &rx164_irq_type; |
121 | } | 121 | } |
122 | 122 | ||
123 | init_i8259a_irqs(); | 123 | init_i8259a_irqs(); |
diff --git a/arch/alpha/kernel/sys_sable.c b/arch/alpha/kernel/sys_sable.c index a7ff84474ace..24dea40c9bfe 100644 --- a/arch/alpha/kernel/sys_sable.c +++ b/arch/alpha/kernel/sys_sable.c | |||
@@ -537,7 +537,7 @@ sable_lynx_init_irq(int nr_irqs) | |||
537 | 537 | ||
538 | for (i = 0; i < nr_irqs; ++i) { | 538 | for (i = 0; i < nr_irqs; ++i) { |
539 | irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; | 539 | irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; |
540 | irq_desc[i].handler = &sable_lynx_irq_type; | 540 | irq_desc[i].chip = &sable_lynx_irq_type; |
541 | } | 541 | } |
542 | 542 | ||
543 | common_init_isa_dma(); | 543 | common_init_isa_dma(); |
diff --git a/arch/alpha/kernel/sys_takara.c b/arch/alpha/kernel/sys_takara.c index 7955bdfc2db0..2c75cd1fd81a 100644 --- a/arch/alpha/kernel/sys_takara.c +++ b/arch/alpha/kernel/sys_takara.c | |||
@@ -154,7 +154,7 @@ takara_init_irq(void) | |||
154 | 154 | ||
155 | for (i = 16; i < 128; ++i) { | 155 | for (i = 16; i < 128; ++i) { |
156 | irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; | 156 | irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; |
157 | irq_desc[i].handler = &takara_irq_type; | 157 | irq_desc[i].chip = &takara_irq_type; |
158 | } | 158 | } |
159 | 159 | ||
160 | common_init_isa_dma(); | 160 | common_init_isa_dma(); |
diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c index 2551fb49ae09..13f3ed8ed7ac 100644 --- a/arch/alpha/kernel/sys_titan.c +++ b/arch/alpha/kernel/sys_titan.c | |||
@@ -189,7 +189,7 @@ init_titan_irqs(struct hw_interrupt_type * ops, int imin, int imax) | |||
189 | long i; | 189 | long i; |
190 | for (i = imin; i <= imax; ++i) { | 190 | for (i = imin; i <= imax; ++i) { |
191 | irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; | 191 | irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; |
192 | irq_desc[i].handler = ops; | 192 | irq_desc[i].chip = ops; |
193 | } | 193 | } |
194 | } | 194 | } |
195 | 195 | ||
diff --git a/arch/alpha/kernel/sys_wildfire.c b/arch/alpha/kernel/sys_wildfire.c index 1553f470246e..22c5798fe083 100644 --- a/arch/alpha/kernel/sys_wildfire.c +++ b/arch/alpha/kernel/sys_wildfire.c | |||
@@ -199,14 +199,14 @@ wildfire_init_irq_per_pca(int qbbno, int pcano) | |||
199 | if (i == 2) | 199 | if (i == 2) |
200 | continue; | 200 | continue; |
201 | irq_desc[i+irq_bias].status = IRQ_DISABLED | IRQ_LEVEL; | 201 | irq_desc[i+irq_bias].status = IRQ_DISABLED | IRQ_LEVEL; |
202 | irq_desc[i+irq_bias].handler = &wildfire_irq_type; | 202 | irq_desc[i+irq_bias].chip = &wildfire_irq_type; |
203 | } | 203 | } |
204 | 204 | ||
205 | irq_desc[36+irq_bias].status = IRQ_DISABLED | IRQ_LEVEL; | 205 | irq_desc[36+irq_bias].status = IRQ_DISABLED | IRQ_LEVEL; |
206 | irq_desc[36+irq_bias].handler = &wildfire_irq_type; | 206 | irq_desc[36+irq_bias].chip = &wildfire_irq_type; |
207 | for (i = 40; i < 64; ++i) { | 207 | for (i = 40; i < 64; ++i) { |
208 | irq_desc[i+irq_bias].status = IRQ_DISABLED | IRQ_LEVEL; | 208 | irq_desc[i+irq_bias].status = IRQ_DISABLED | IRQ_LEVEL; |
209 | irq_desc[i+irq_bias].handler = &wildfire_irq_type; | 209 | irq_desc[i+irq_bias].chip = &wildfire_irq_type; |
210 | } | 210 | } |
211 | 211 | ||
212 | setup_irq(32+irq_bias, &isa_enable); | 212 | setup_irq(32+irq_bias, &isa_enable); |
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index 302fc1401547..45da06fc1ba1 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c | |||
@@ -304,7 +304,7 @@ static inline int pdev_bad_for_parity(struct pci_dev *dev) | |||
304 | static void __devinit | 304 | static void __devinit |
305 | pdev_fixup_device_resources(struct pci_sys_data *root, struct pci_dev *dev) | 305 | pdev_fixup_device_resources(struct pci_sys_data *root, struct pci_dev *dev) |
306 | { | 306 | { |
307 | unsigned long offset; | 307 | resource_size_t offset; |
308 | int i; | 308 | int i; |
309 | 309 | ||
310 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | 310 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { |
@@ -634,9 +634,9 @@ char * __init pcibios_setup(char *str) | |||
634 | * which might be mirrored at 0x0100-0x03ff.. | 634 | * which might be mirrored at 0x0100-0x03ff.. |
635 | */ | 635 | */ |
636 | void pcibios_align_resource(void *data, struct resource *res, | 636 | void pcibios_align_resource(void *data, struct resource *res, |
637 | unsigned long size, unsigned long align) | 637 | resource_size_t size, resource_size_t align) |
638 | { | 638 | { |
639 | unsigned long start = res->start; | 639 | resource_size_t start = res->start; |
640 | 640 | ||
641 | if (res->flags & IORESOURCE_IO && start & 0x300) | 641 | if (res->flags & IORESOURCE_IO && start & 0x300) |
642 | start = (start + 0x3ff) & ~0x3ff; | 642 | start = (start + 0x3ff) & ~0x3ff; |
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 093ccba0503c..6bdf70def01f 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
@@ -119,9 +119,24 @@ DEFINE_PER_CPU(struct cpuinfo_arm, cpu_data); | |||
119 | * Standard memory resources | 119 | * Standard memory resources |
120 | */ | 120 | */ |
121 | static struct resource mem_res[] = { | 121 | static struct resource mem_res[] = { |
122 | { "Video RAM", 0, 0, IORESOURCE_MEM }, | 122 | { |
123 | { "Kernel text", 0, 0, IORESOURCE_MEM }, | 123 | .name = "Video RAM", |
124 | { "Kernel data", 0, 0, IORESOURCE_MEM } | 124 | .start = 0, |
125 | .end = 0, | ||
126 | .flags = IORESOURCE_MEM | ||
127 | }, | ||
128 | { | ||
129 | .name = "Kernel text", | ||
130 | .start = 0, | ||
131 | .end = 0, | ||
132 | .flags = IORESOURCE_MEM | ||
133 | }, | ||
134 | { | ||
135 | .name = "Kernel data", | ||
136 | .start = 0, | ||
137 | .end = 0, | ||
138 | .flags = IORESOURCE_MEM | ||
139 | } | ||
125 | }; | 140 | }; |
126 | 141 | ||
127 | #define video_ram mem_res[0] | 142 | #define video_ram mem_res[0] |
@@ -129,9 +144,24 @@ static struct resource mem_res[] = { | |||
129 | #define kernel_data mem_res[2] | 144 | #define kernel_data mem_res[2] |
130 | 145 | ||
131 | static struct resource io_res[] = { | 146 | static struct resource io_res[] = { |
132 | { "reserved", 0x3bc, 0x3be, IORESOURCE_IO | IORESOURCE_BUSY }, | 147 | { |
133 | { "reserved", 0x378, 0x37f, IORESOURCE_IO | IORESOURCE_BUSY }, | 148 | .name = "reserved", |
134 | { "reserved", 0x278, 0x27f, IORESOURCE_IO | IORESOURCE_BUSY } | 149 | .start = 0x3bc, |
150 | .end = 0x3be, | ||
151 | .flags = IORESOURCE_IO | IORESOURCE_BUSY | ||
152 | }, | ||
153 | { | ||
154 | .name = "reserved", | ||
155 | .start = 0x378, | ||
156 | .end = 0x37f, | ||
157 | .flags = IORESOURCE_IO | IORESOURCE_BUSY | ||
158 | }, | ||
159 | { | ||
160 | .name = "reserved", | ||
161 | .start = 0x278, | ||
162 | .end = 0x27f, | ||
163 | .flags = IORESOURCE_IO | IORESOURCE_BUSY | ||
164 | } | ||
135 | }; | 165 | }; |
136 | 166 | ||
137 | #define lp0 io_res[0] | 167 | #define lp0 io_res[0] |
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index 856b665020e7..6a1238a29d6c 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig | |||
@@ -28,6 +28,10 @@ config GENERIC_CALIBRATE_DELAY | |||
28 | bool | 28 | bool |
29 | default y | 29 | default y |
30 | 30 | ||
31 | config IRQ_PER_CPU | ||
32 | bool | ||
33 | default y | ||
34 | |||
31 | config CRIS | 35 | config CRIS |
32 | bool | 36 | bool |
33 | default y | 37 | default y |
diff --git a/arch/cris/arch-v10/kernel/irq.c b/arch/cris/arch-v10/kernel/irq.c index 4b368a122015..2d5be93b5197 100644 --- a/arch/cris/arch-v10/kernel/irq.c +++ b/arch/cris/arch-v10/kernel/irq.c | |||
@@ -172,7 +172,7 @@ init_IRQ(void) | |||
172 | 172 | ||
173 | /* Initialize IRQ handler descriptiors. */ | 173 | /* Initialize IRQ handler descriptiors. */ |
174 | for(i = 2; i < NR_IRQS; i++) { | 174 | for(i = 2; i < NR_IRQS; i++) { |
175 | irq_desc[i].handler = &crisv10_irq_type; | 175 | irq_desc[i].chip = &crisv10_irq_type; |
176 | set_int_vector(i, interrupt[i]); | 176 | set_int_vector(i, interrupt[i]); |
177 | } | 177 | } |
178 | 178 | ||
diff --git a/arch/cris/arch-v32/drivers/pci/bios.c b/arch/cris/arch-v32/drivers/pci/bios.c index 1e9d062103ae..a2b9c60c2777 100644 --- a/arch/cris/arch-v32/drivers/pci/bios.c +++ b/arch/cris/arch-v32/drivers/pci/bios.c | |||
@@ -43,10 +43,10 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | |||
43 | 43 | ||
44 | void | 44 | void |
45 | pcibios_align_resource(void *data, struct resource *res, | 45 | pcibios_align_resource(void *data, struct resource *res, |
46 | unsigned long size, unsigned long align) | 46 | resource_size_t size, resource_size_t align) |
47 | { | 47 | { |
48 | if (res->flags & IORESOURCE_IO) { | 48 | if (res->flags & IORESOURCE_IO) { |
49 | unsigned long start = res->start; | 49 | resource_size_t start = res->start; |
50 | 50 | ||
51 | if (start & 0x300) { | 51 | if (start & 0x300) { |
52 | start = (start + 0x3ff) & ~0x3ff; | 52 | start = (start + 0x3ff) & ~0x3ff; |
diff --git a/arch/cris/arch-v32/kernel/irq.c b/arch/cris/arch-v32/kernel/irq.c index c78cc2685133..06260874f018 100644 --- a/arch/cris/arch-v32/kernel/irq.c +++ b/arch/cris/arch-v32/kernel/irq.c | |||
@@ -369,7 +369,7 @@ init_IRQ(void) | |||
369 | 369 | ||
370 | /* Point all IRQ's to bad handlers. */ | 370 | /* Point all IRQ's to bad handlers. */ |
371 | for (i = FIRST_IRQ, j = 0; j < NR_IRQS; i++, j++) { | 371 | for (i = FIRST_IRQ, j = 0; j < NR_IRQS; i++, j++) { |
372 | irq_desc[j].handler = &crisv32_irq_type; | 372 | irq_desc[j].chip = &crisv32_irq_type; |
373 | set_exception_vector(i, interrupt[j]); | 373 | set_exception_vector(i, interrupt[j]); |
374 | } | 374 | } |
375 | 375 | ||
diff --git a/arch/cris/kernel/irq.c b/arch/cris/kernel/irq.c index b504def3e346..6547bb646364 100644 --- a/arch/cris/kernel/irq.c +++ b/arch/cris/kernel/irq.c | |||
@@ -69,7 +69,7 @@ int show_interrupts(struct seq_file *p, void *v) | |||
69 | for_each_online_cpu(j) | 69 | for_each_online_cpu(j) |
70 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); | 70 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); |
71 | #endif | 71 | #endif |
72 | seq_printf(p, " %14s", irq_desc[i].handler->typename); | 72 | seq_printf(p, " %14s", irq_desc[i].chip->typename); |
73 | seq_printf(p, " %s", action->name); | 73 | seq_printf(p, " %s", action->name); |
74 | 74 | ||
75 | for (action=action->next; action; action = action->next) | 75 | for (action=action->next; action; action = action->next) |
diff --git a/arch/frv/mb93090-mb00/pci-frv.c b/arch/frv/mb93090-mb00/pci-frv.c index 0a26bf6f1cd4..4f165c93be42 100644 --- a/arch/frv/mb93090-mb00/pci-frv.c +++ b/arch/frv/mb93090-mb00/pci-frv.c | |||
@@ -64,10 +64,10 @@ pcibios_update_resource(struct pci_dev *dev, struct resource *root, | |||
64 | */ | 64 | */ |
65 | void | 65 | void |
66 | pcibios_align_resource(void *data, struct resource *res, | 66 | pcibios_align_resource(void *data, struct resource *res, |
67 | unsigned long size, unsigned long align) | 67 | resource_size_t size, resource_size_t align) |
68 | { | 68 | { |
69 | if (res->flags & IORESOURCE_IO) { | 69 | if (res->flags & IORESOURCE_IO) { |
70 | unsigned long start = res->start; | 70 | resource_size_t start = res->start; |
71 | 71 | ||
72 | if (start & 0x300) { | 72 | if (start & 0x300) { |
73 | start = (start + 0x3ff) & ~0x3ff; | 73 | start = (start + 0x3ff) & ~0x3ff; |
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index 3bb221db164a..1718429286d4 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig | |||
@@ -529,6 +529,7 @@ config X86_PAE | |||
529 | bool | 529 | bool |
530 | depends on HIGHMEM64G | 530 | depends on HIGHMEM64G |
531 | default y | 531 | default y |
532 | select RESOURCES_64BIT | ||
532 | 533 | ||
533 | # Common NUMA Features | 534 | # Common NUMA Features |
534 | config NUMA | 535 | config NUMA |
@@ -737,7 +738,7 @@ config KEXEC | |||
737 | but it is independent of the system firmware. And like a reboot | 738 | but it is independent of the system firmware. And like a reboot |
738 | you can start any kernel with it, not just Linux. | 739 | you can start any kernel with it, not just Linux. |
739 | 740 | ||
740 | The name comes from the similiarity to the exec system call. | 741 | The name comes from the similarity to the exec system call. |
741 | 742 | ||
742 | It is an ongoing process to be certain the hardware in a machine | 743 | It is an ongoing process to be certain the hardware in a machine |
743 | is properly shutdown, so do not be surprised if this code does not | 744 | is properly shutdown, so do not be surprised if this code does not |
@@ -794,6 +795,9 @@ config COMPAT_VDSO | |||
794 | 795 | ||
795 | endmenu | 796 | endmenu |
796 | 797 | ||
798 | config ARCH_ENABLE_MEMORY_HOTPLUG | ||
799 | def_bool y | ||
800 | depends on HIGHMEM | ||
797 | 801 | ||
798 | menu "Power management options (ACPI, APM)" | 802 | menu "Power management options (ACPI, APM)" |
799 | depends on !X86_VOYAGER | 803 | depends on !X86_VOYAGER |
diff --git a/arch/i386/kernel/efi.c b/arch/i386/kernel/efi.c index 9202b67c4b2e..8beb0f07d999 100644 --- a/arch/i386/kernel/efi.c +++ b/arch/i386/kernel/efi.c | |||
@@ -601,8 +601,10 @@ efi_initialize_iomem_resources(struct resource *code_resource, | |||
601 | res->end = res->start + ((md->num_pages << EFI_PAGE_SHIFT) - 1); | 601 | res->end = res->start + ((md->num_pages << EFI_PAGE_SHIFT) - 1); |
602 | res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; | 602 | res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; |
603 | if (request_resource(&iomem_resource, res) < 0) | 603 | if (request_resource(&iomem_resource, res) < 0) |
604 | printk(KERN_ERR PFX "Failed to allocate res %s : 0x%lx-0x%lx\n", | 604 | printk(KERN_ERR PFX "Failed to allocate res %s : " |
605 | res->name, res->start, res->end); | 605 | "0x%llx-0x%llx\n", res->name, |
606 | (unsigned long long)res->start, | ||
607 | (unsigned long long)res->end); | ||
606 | /* | 608 | /* |
607 | * We don't know which region contains kernel data so we try | 609 | * We don't know which region contains kernel data so we try |
608 | * it repeatedly and let the resource manager test it. | 610 | * it repeatedly and let the resource manager test it. |
diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c index c1a42feba286..3c6063671a9f 100644 --- a/arch/i386/kernel/i8259.c +++ b/arch/i386/kernel/i8259.c | |||
@@ -132,7 +132,7 @@ void make_8259A_irq(unsigned int irq) | |||
132 | { | 132 | { |
133 | disable_irq_nosync(irq); | 133 | disable_irq_nosync(irq); |
134 | io_apic_irqs &= ~(1<<irq); | 134 | io_apic_irqs &= ~(1<<irq); |
135 | irq_desc[irq].handler = &i8259A_irq_type; | 135 | irq_desc[irq].chip = &i8259A_irq_type; |
136 | enable_irq(irq); | 136 | enable_irq(irq); |
137 | } | 137 | } |
138 | 138 | ||
@@ -386,12 +386,12 @@ void __init init_ISA_irqs (void) | |||
386 | /* | 386 | /* |
387 | * 16 old-style INTA-cycle interrupts: | 387 | * 16 old-style INTA-cycle interrupts: |
388 | */ | 388 | */ |
389 | irq_desc[i].handler = &i8259A_irq_type; | 389 | irq_desc[i].chip = &i8259A_irq_type; |
390 | } else { | 390 | } else { |
391 | /* | 391 | /* |
392 | * 'high' PCI IRQs filled in on demand | 392 | * 'high' PCI IRQs filled in on demand |
393 | */ | 393 | */ |
394 | irq_desc[i].handler = &no_irq_type; | 394 | irq_desc[i].chip = &no_irq_type; |
395 | } | 395 | } |
396 | } | 396 | } |
397 | } | 397 | } |
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 72ae414e4d49..ec9ea0269d36 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c | |||
@@ -581,7 +581,7 @@ static int balanced_irq(void *unused) | |||
581 | 581 | ||
582 | /* push everything to CPU 0 to give us a starting point. */ | 582 | /* push everything to CPU 0 to give us a starting point. */ |
583 | for (i = 0 ; i < NR_IRQS ; i++) { | 583 | for (i = 0 ; i < NR_IRQS ; i++) { |
584 | pending_irq_cpumask[i] = cpumask_of_cpu(0); | 584 | irq_desc[i].pending_mask = cpumask_of_cpu(0); |
585 | set_pending_irq(i, cpumask_of_cpu(0)); | 585 | set_pending_irq(i, cpumask_of_cpu(0)); |
586 | } | 586 | } |
587 | 587 | ||
@@ -1205,15 +1205,17 @@ static struct hw_interrupt_type ioapic_edge_type; | |||
1205 | #define IOAPIC_EDGE 0 | 1205 | #define IOAPIC_EDGE 0 |
1206 | #define IOAPIC_LEVEL 1 | 1206 | #define IOAPIC_LEVEL 1 |
1207 | 1207 | ||
1208 | static inline void ioapic_register_intr(int irq, int vector, unsigned long trigger) | 1208 | static void ioapic_register_intr(int irq, int vector, unsigned long trigger) |
1209 | { | 1209 | { |
1210 | unsigned idx = use_pci_vector() && !platform_legacy_irq(irq) ? vector : irq; | 1210 | unsigned idx; |
1211 | |||
1212 | idx = use_pci_vector() && !platform_legacy_irq(irq) ? vector : irq; | ||
1211 | 1213 | ||
1212 | if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || | 1214 | if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || |
1213 | trigger == IOAPIC_LEVEL) | 1215 | trigger == IOAPIC_LEVEL) |
1214 | irq_desc[idx].handler = &ioapic_level_type; | 1216 | irq_desc[idx].chip = &ioapic_level_type; |
1215 | else | 1217 | else |
1216 | irq_desc[idx].handler = &ioapic_edge_type; | 1218 | irq_desc[idx].chip = &ioapic_edge_type; |
1217 | set_intr_gate(vector, interrupt[idx]); | 1219 | set_intr_gate(vector, interrupt[idx]); |
1218 | } | 1220 | } |
1219 | 1221 | ||
@@ -1325,7 +1327,7 @@ static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, in | |||
1325 | * The timer IRQ doesn't have to know that behind the | 1327 | * The timer IRQ doesn't have to know that behind the |
1326 | * scene we have a 8259A-master in AEOI mode ... | 1328 | * scene we have a 8259A-master in AEOI mode ... |
1327 | */ | 1329 | */ |
1328 | irq_desc[0].handler = &ioapic_edge_type; | 1330 | irq_desc[0].chip = &ioapic_edge_type; |
1329 | 1331 | ||
1330 | /* | 1332 | /* |
1331 | * Add it to the IO-APIC irq-routing table: | 1333 | * Add it to the IO-APIC irq-routing table: |
@@ -2069,6 +2071,13 @@ static void set_ioapic_affinity_vector (unsigned int vector, | |||
2069 | #endif | 2071 | #endif |
2070 | #endif | 2072 | #endif |
2071 | 2073 | ||
2074 | static int ioapic_retrigger(unsigned int irq) | ||
2075 | { | ||
2076 | send_IPI_self(IO_APIC_VECTOR(irq)); | ||
2077 | |||
2078 | return 1; | ||
2079 | } | ||
2080 | |||
2072 | /* | 2081 | /* |
2073 | * Level and edge triggered IO-APIC interrupts need different handling, | 2082 | * Level and edge triggered IO-APIC interrupts need different handling, |
2074 | * so we use two separate IRQ descriptors. Edge triggered IRQs can be | 2083 | * so we use two separate IRQ descriptors. Edge triggered IRQs can be |
@@ -2088,6 +2097,7 @@ static struct hw_interrupt_type ioapic_edge_type __read_mostly = { | |||
2088 | #ifdef CONFIG_SMP | 2097 | #ifdef CONFIG_SMP |
2089 | .set_affinity = set_ioapic_affinity, | 2098 | .set_affinity = set_ioapic_affinity, |
2090 | #endif | 2099 | #endif |
2100 | .retrigger = ioapic_retrigger, | ||
2091 | }; | 2101 | }; |
2092 | 2102 | ||
2093 | static struct hw_interrupt_type ioapic_level_type __read_mostly = { | 2103 | static struct hw_interrupt_type ioapic_level_type __read_mostly = { |
@@ -2101,6 +2111,7 @@ static struct hw_interrupt_type ioapic_level_type __read_mostly = { | |||
2101 | #ifdef CONFIG_SMP | 2111 | #ifdef CONFIG_SMP |
2102 | .set_affinity = set_ioapic_affinity, | 2112 | .set_affinity = set_ioapic_affinity, |
2103 | #endif | 2113 | #endif |
2114 | .retrigger = ioapic_retrigger, | ||
2104 | }; | 2115 | }; |
2105 | 2116 | ||
2106 | static inline void init_IO_APIC_traps(void) | 2117 | static inline void init_IO_APIC_traps(void) |
@@ -2135,7 +2146,7 @@ static inline void init_IO_APIC_traps(void) | |||
2135 | make_8259A_irq(irq); | 2146 | make_8259A_irq(irq); |
2136 | else | 2147 | else |
2137 | /* Strange. Oh, well.. */ | 2148 | /* Strange. Oh, well.. */ |
2138 | irq_desc[irq].handler = &no_irq_type; | 2149 | irq_desc[irq].chip = &no_irq_type; |
2139 | } | 2150 | } |
2140 | } | 2151 | } |
2141 | } | 2152 | } |
@@ -2351,7 +2362,7 @@ static inline void check_timer(void) | |||
2351 | printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); | 2362 | printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); |
2352 | 2363 | ||
2353 | disable_8259A_irq(0); | 2364 | disable_8259A_irq(0); |
2354 | irq_desc[0].handler = &lapic_irq_type; | 2365 | irq_desc[0].chip = &lapic_irq_type; |
2355 | apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */ | 2366 | apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */ |
2356 | enable_8259A_irq(0); | 2367 | enable_8259A_irq(0); |
2357 | 2368 | ||
diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c index 9eec9435318e..16b491703967 100644 --- a/arch/i386/kernel/irq.c +++ b/arch/i386/kernel/irq.c | |||
@@ -82,6 +82,10 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs) | |||
82 | } | 82 | } |
83 | #endif | 83 | #endif |
84 | 84 | ||
85 | if (!irq_desc[irq].handle_irq) { | ||
86 | __do_IRQ(irq, regs); | ||
87 | goto out_exit; | ||
88 | } | ||
85 | #ifdef CONFIG_4KSTACKS | 89 | #ifdef CONFIG_4KSTACKS |
86 | 90 | ||
87 | curctx = (union irq_ctx *) current_thread_info(); | 91 | curctx = (union irq_ctx *) current_thread_info(); |
@@ -121,6 +125,7 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs) | |||
121 | #endif | 125 | #endif |
122 | __do_IRQ(irq, regs); | 126 | __do_IRQ(irq, regs); |
123 | 127 | ||
128 | out_exit: | ||
124 | irq_exit(); | 129 | irq_exit(); |
125 | 130 | ||
126 | return 1; | 131 | return 1; |
@@ -249,7 +254,7 @@ int show_interrupts(struct seq_file *p, void *v) | |||
249 | for_each_online_cpu(j) | 254 | for_each_online_cpu(j) |
250 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); | 255 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); |
251 | #endif | 256 | #endif |
252 | seq_printf(p, " %14s", irq_desc[i].handler->typename); | 257 | seq_printf(p, " %14s", irq_desc[i].chip->typename); |
253 | seq_printf(p, " %s", action->name); | 258 | seq_printf(p, " %s", action->name); |
254 | 259 | ||
255 | for (action=action->next; action; action = action->next) | 260 | for (action=action->next; action; action = action->next) |
@@ -291,13 +296,13 @@ void fixup_irqs(cpumask_t map) | |||
291 | if (irq == 2) | 296 | if (irq == 2) |
292 | continue; | 297 | continue; |
293 | 298 | ||
294 | cpus_and(mask, irq_affinity[irq], map); | 299 | cpus_and(mask, irq_desc[irq].affinity, map); |
295 | if (any_online_cpu(mask) == NR_CPUS) { | 300 | if (any_online_cpu(mask) == NR_CPUS) { |
296 | printk("Breaking affinity for irq %i\n", irq); | 301 | printk("Breaking affinity for irq %i\n", irq); |
297 | mask = map; | 302 | mask = map; |
298 | } | 303 | } |
299 | if (irq_desc[irq].handler->set_affinity) | 304 | if (irq_desc[irq].chip->set_affinity) |
300 | irq_desc[irq].handler->set_affinity(irq, mask); | 305 | irq_desc[irq].chip->set_affinity(irq, mask); |
301 | else if (irq_desc[irq].action && !(warned++)) | 306 | else if (irq_desc[irq].action && !(warned++)) |
302 | printk("Cannot set affinity for irq %i\n", irq); | 307 | printk("Cannot set affinity for irq %i\n", irq); |
303 | } | 308 | } |
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 4a65040cc624..6712f0d2eb37 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c | |||
@@ -1314,8 +1314,10 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat | |||
1314 | probe_roms(); | 1314 | probe_roms(); |
1315 | for (i = 0; i < e820.nr_map; i++) { | 1315 | for (i = 0; i < e820.nr_map; i++) { |
1316 | struct resource *res; | 1316 | struct resource *res; |
1317 | #ifndef CONFIG_RESOURCES_64BIT | ||
1317 | if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL) | 1318 | if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL) |
1318 | continue; | 1319 | continue; |
1320 | #endif | ||
1319 | res = kzalloc(sizeof(struct resource), GFP_ATOMIC); | 1321 | res = kzalloc(sizeof(struct resource), GFP_ATOMIC); |
1320 | switch (e820.map[i].type) { | 1322 | switch (e820.map[i].type) { |
1321 | case E820_RAM: res->name = "System RAM"; break; | 1323 | case E820_RAM: res->name = "System RAM"; break; |
diff --git a/arch/i386/mach-visws/setup.c b/arch/i386/mach-visws/setup.c index 8a9e1a6f745d..1f84cdb24779 100644 --- a/arch/i386/mach-visws/setup.c +++ b/arch/i386/mach-visws/setup.c | |||
@@ -140,8 +140,8 @@ void __init time_init_hook(void) | |||
140 | 140 | ||
141 | #define MB (1024 * 1024) | 141 | #define MB (1024 * 1024) |
142 | 142 | ||
143 | static unsigned long sgivwfb_mem_phys; | 143 | unsigned long sgivwfb_mem_phys; |
144 | static unsigned long sgivwfb_mem_size; | 144 | unsigned long sgivwfb_mem_size; |
145 | 145 | ||
146 | long long mem_size __initdata = 0; | 146 | long long mem_size __initdata = 0; |
147 | 147 | ||
@@ -177,8 +177,4 @@ char * __init machine_specific_memory_setup(void) | |||
177 | add_memory_region(sgivwfb_mem_phys, sgivwfb_mem_size, E820_RESERVED); | 177 | add_memory_region(sgivwfb_mem_phys, sgivwfb_mem_size, E820_RESERVED); |
178 | 178 | ||
179 | return "PROM"; | 179 | return "PROM"; |
180 | |||
181 | /* Remove gcc warnings */ | ||
182 | (void) sanitize_e820_map(NULL, NULL); | ||
183 | (void) copy_e820_map(NULL, 0); | ||
184 | } | 180 | } |
diff --git a/arch/i386/mach-visws/visws_apic.c b/arch/i386/mach-visws/visws_apic.c index 3e64fb721291..c418521dd554 100644 --- a/arch/i386/mach-visws/visws_apic.c +++ b/arch/i386/mach-visws/visws_apic.c | |||
@@ -278,22 +278,22 @@ void init_VISWS_APIC_irqs(void) | |||
278 | irq_desc[i].depth = 1; | 278 | irq_desc[i].depth = 1; |
279 | 279 | ||
280 | if (i == 0) { | 280 | if (i == 0) { |
281 | irq_desc[i].handler = &cobalt_irq_type; | 281 | irq_desc[i].chip = &cobalt_irq_type; |
282 | } | 282 | } |
283 | else if (i == CO_IRQ_IDE0) { | 283 | else if (i == CO_IRQ_IDE0) { |
284 | irq_desc[i].handler = &cobalt_irq_type; | 284 | irq_desc[i].chip = &cobalt_irq_type; |
285 | } | 285 | } |
286 | else if (i == CO_IRQ_IDE1) { | 286 | else if (i == CO_IRQ_IDE1) { |
287 | irq_desc[i].handler = &cobalt_irq_type; | 287 | irq_desc[i].chip = &cobalt_irq_type; |
288 | } | 288 | } |
289 | else if (i == CO_IRQ_8259) { | 289 | else if (i == CO_IRQ_8259) { |
290 | irq_desc[i].handler = &piix4_master_irq_type; | 290 | irq_desc[i].chip = &piix4_master_irq_type; |
291 | } | 291 | } |
292 | else if (i < CO_IRQ_APIC0) { | 292 | else if (i < CO_IRQ_APIC0) { |
293 | irq_desc[i].handler = &piix4_virtual_irq_type; | 293 | irq_desc[i].chip = &piix4_virtual_irq_type; |
294 | } | 294 | } |
295 | else if (IS_CO_APIC(i)) { | 295 | else if (IS_CO_APIC(i)) { |
296 | irq_desc[i].handler = &cobalt_irq_type; | 296 | irq_desc[i].chip = &cobalt_irq_type; |
297 | } | 297 | } |
298 | } | 298 | } |
299 | 299 | ||
diff --git a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c index 8242af9ebc6f..5b8b579a079f 100644 --- a/arch/i386/mach-voyager/voyager_smp.c +++ b/arch/i386/mach-voyager/voyager_smp.c | |||
@@ -1419,7 +1419,7 @@ smp_intr_init(void) | |||
1419 | * This is for later: first 16 correspond to PC IRQs; next 16 | 1419 | * This is for later: first 16 correspond to PC IRQs; next 16 |
1420 | * are Primary MC IRQs and final 16 are Secondary MC IRQs */ | 1420 | * are Primary MC IRQs and final 16 are Secondary MC IRQs */ |
1421 | for(i = 0; i < 48; i++) | 1421 | for(i = 0; i < 48; i++) |
1422 | irq_desc[i].handler = &vic_irq_type; | 1422 | irq_desc[i].chip = &vic_irq_type; |
1423 | } | 1423 | } |
1424 | 1424 | ||
1425 | /* send a CPI at level cpi to a set of cpus in cpuset (set 1 bit per | 1425 | /* send a CPI at level cpi to a set of cpus in cpuset (set 1 bit per |
diff --git a/arch/i386/pci/i386.c b/arch/i386/pci/i386.c index a151f7a99f5e..10154a2cac68 100644 --- a/arch/i386/pci/i386.c +++ b/arch/i386/pci/i386.c | |||
@@ -48,10 +48,10 @@ | |||
48 | */ | 48 | */ |
49 | void | 49 | void |
50 | pcibios_align_resource(void *data, struct resource *res, | 50 | pcibios_align_resource(void *data, struct resource *res, |
51 | unsigned long size, unsigned long align) | 51 | resource_size_t size, resource_size_t align) |
52 | { | 52 | { |
53 | if (res->flags & IORESOURCE_IO) { | 53 | if (res->flags & IORESOURCE_IO) { |
54 | unsigned long start = res->start; | 54 | resource_size_t start = res->start; |
55 | 55 | ||
56 | if (start & 0x300) { | 56 | if (start & 0x300) { |
57 | start = (start + 0x3ff) & ~0x3ff; | 57 | start = (start + 0x3ff) & ~0x3ff; |
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index a56df7bf022d..b487e227a1f7 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig | |||
@@ -271,6 +271,9 @@ config HOTPLUG_CPU | |||
271 | can be controlled through /sys/devices/system/cpu/cpu#. | 271 | can be controlled through /sys/devices/system/cpu/cpu#. |
272 | Say N if you want to disable CPU hotplug. | 272 | Say N if you want to disable CPU hotplug. |
273 | 273 | ||
274 | config ARCH_ENABLE_MEMORY_HOTPLUG | ||
275 | def_bool y | ||
276 | |||
274 | config SCHED_SMT | 277 | config SCHED_SMT |
275 | bool "SMT scheduler support" | 278 | bool "SMT scheduler support" |
276 | depends on SMP | 279 | depends on SMP |
@@ -489,6 +492,10 @@ config GENERIC_PENDING_IRQ | |||
489 | depends on GENERIC_HARDIRQS && SMP | 492 | depends on GENERIC_HARDIRQS && SMP |
490 | default y | 493 | default y |
491 | 494 | ||
495 | config IRQ_PER_CPU | ||
496 | bool | ||
497 | default y | ||
498 | |||
492 | source "arch/ia64/hp/sim/Kconfig" | 499 | source "arch/ia64/hp/sim/Kconfig" |
493 | 500 | ||
494 | menu "Instrumentation Support" | 501 | menu "Instrumentation Support" |
diff --git a/arch/ia64/hp/sim/hpsim_irq.c b/arch/ia64/hp/sim/hpsim_irq.c index c0d25a2a3e9c..8145547bb52d 100644 --- a/arch/ia64/hp/sim/hpsim_irq.c +++ b/arch/ia64/hp/sim/hpsim_irq.c | |||
@@ -44,8 +44,8 @@ hpsim_irq_init (void) | |||
44 | int i; | 44 | int i; |
45 | 45 | ||
46 | for (i = 0; i < NR_IRQS; ++i) { | 46 | for (i = 0; i < NR_IRQS; ++i) { |
47 | idesc = irq_descp(i); | 47 | idesc = irq_desc + i; |
48 | if (idesc->handler == &no_irq_type) | 48 | if (idesc->chip == &no_irq_type) |
49 | idesc->handler = &irq_type_hp_sim; | 49 | idesc->chip = &irq_type_hp_sim; |
50 | } | 50 | } |
51 | } | 51 | } |
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index d58c1c5c903a..efc7df4b0fd2 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c | |||
@@ -456,7 +456,7 @@ iosapic_startup_edge_irq (unsigned int irq) | |||
456 | static void | 456 | static void |
457 | iosapic_ack_edge_irq (unsigned int irq) | 457 | iosapic_ack_edge_irq (unsigned int irq) |
458 | { | 458 | { |
459 | irq_desc_t *idesc = irq_descp(irq); | 459 | irq_desc_t *idesc = irq_desc + irq; |
460 | 460 | ||
461 | move_native_irq(irq); | 461 | move_native_irq(irq); |
462 | /* | 462 | /* |
@@ -659,14 +659,14 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery, | |||
659 | else | 659 | else |
660 | irq_type = &irq_type_iosapic_level; | 660 | irq_type = &irq_type_iosapic_level; |
661 | 661 | ||
662 | idesc = irq_descp(vector); | 662 | idesc = irq_desc + vector; |
663 | if (idesc->handler != irq_type) { | 663 | if (idesc->chip != irq_type) { |
664 | if (idesc->handler != &no_irq_type) | 664 | if (idesc->chip != &no_irq_type) |
665 | printk(KERN_WARNING | 665 | printk(KERN_WARNING |
666 | "%s: changing vector %d from %s to %s\n", | 666 | "%s: changing vector %d from %s to %s\n", |
667 | __FUNCTION__, vector, | 667 | __FUNCTION__, vector, |
668 | idesc->handler->typename, irq_type->typename); | 668 | idesc->chip->typename, irq_type->typename); |
669 | idesc->handler = irq_type; | 669 | idesc->chip = irq_type; |
670 | } | 670 | } |
671 | return 0; | 671 | return 0; |
672 | } | 672 | } |
@@ -793,14 +793,14 @@ again: | |||
793 | return -ENOSPC; | 793 | return -ENOSPC; |
794 | } | 794 | } |
795 | 795 | ||
796 | spin_lock_irqsave(&irq_descp(vector)->lock, flags); | 796 | spin_lock_irqsave(&irq_desc[vector].lock, flags); |
797 | spin_lock(&iosapic_lock); | 797 | spin_lock(&iosapic_lock); |
798 | { | 798 | { |
799 | if (gsi_to_vector(gsi) > 0) { | 799 | if (gsi_to_vector(gsi) > 0) { |
800 | if (list_empty(&iosapic_intr_info[vector].rtes)) | 800 | if (list_empty(&iosapic_intr_info[vector].rtes)) |
801 | free_irq_vector(vector); | 801 | free_irq_vector(vector); |
802 | spin_unlock(&iosapic_lock); | 802 | spin_unlock(&iosapic_lock); |
803 | spin_unlock_irqrestore(&irq_descp(vector)->lock, | 803 | spin_unlock_irqrestore(&irq_desc[vector].lock, |
804 | flags); | 804 | flags); |
805 | goto again; | 805 | goto again; |
806 | } | 806 | } |
@@ -810,7 +810,7 @@ again: | |||
810 | polarity, trigger); | 810 | polarity, trigger); |
811 | if (err < 0) { | 811 | if (err < 0) { |
812 | spin_unlock(&iosapic_lock); | 812 | spin_unlock(&iosapic_lock); |
813 | spin_unlock_irqrestore(&irq_descp(vector)->lock, | 813 | spin_unlock_irqrestore(&irq_desc[vector].lock, |
814 | flags); | 814 | flags); |
815 | return err; | 815 | return err; |
816 | } | 816 | } |
@@ -825,7 +825,7 @@ again: | |||
825 | set_rte(gsi, vector, dest, mask); | 825 | set_rte(gsi, vector, dest, mask); |
826 | } | 826 | } |
827 | spin_unlock(&iosapic_lock); | 827 | spin_unlock(&iosapic_lock); |
828 | spin_unlock_irqrestore(&irq_descp(vector)->lock, flags); | 828 | spin_unlock_irqrestore(&irq_desc[vector].lock, flags); |
829 | 829 | ||
830 | printk(KERN_INFO "GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d\n", | 830 | printk(KERN_INFO "GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d\n", |
831 | gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"), | 831 | gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"), |
@@ -860,7 +860,7 @@ iosapic_unregister_intr (unsigned int gsi) | |||
860 | } | 860 | } |
861 | vector = irq_to_vector(irq); | 861 | vector = irq_to_vector(irq); |
862 | 862 | ||
863 | idesc = irq_descp(irq); | 863 | idesc = irq_desc + irq; |
864 | spin_lock_irqsave(&idesc->lock, flags); | 864 | spin_lock_irqsave(&idesc->lock, flags); |
865 | spin_lock(&iosapic_lock); | 865 | spin_lock(&iosapic_lock); |
866 | { | 866 | { |
@@ -903,7 +903,7 @@ iosapic_unregister_intr (unsigned int gsi) | |||
903 | BUG_ON(iosapic_intr_info[vector].count); | 903 | BUG_ON(iosapic_intr_info[vector].count); |
904 | 904 | ||
905 | /* Clear the interrupt controller descriptor */ | 905 | /* Clear the interrupt controller descriptor */ |
906 | idesc->handler = &no_irq_type; | 906 | idesc->chip = &no_irq_type; |
907 | 907 | ||
908 | /* Clear the interrupt information */ | 908 | /* Clear the interrupt information */ |
909 | memset(&iosapic_intr_info[vector], 0, | 909 | memset(&iosapic_intr_info[vector], 0, |
diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c index 9c72ea3f6432..7852382de2fa 100644 --- a/arch/ia64/kernel/irq.c +++ b/arch/ia64/kernel/irq.c | |||
@@ -76,7 +76,7 @@ int show_interrupts(struct seq_file *p, void *v) | |||
76 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); | 76 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); |
77 | } | 77 | } |
78 | #endif | 78 | #endif |
79 | seq_printf(p, " %14s", irq_desc[i].handler->typename); | 79 | seq_printf(p, " %14s", irq_desc[i].chip->typename); |
80 | seq_printf(p, " %s", action->name); | 80 | seq_printf(p, " %s", action->name); |
81 | 81 | ||
82 | for (action=action->next; action; action = action->next) | 82 | for (action=action->next; action; action = action->next) |
@@ -100,7 +100,7 @@ void set_irq_affinity_info (unsigned int irq, int hwid, int redir) | |||
100 | cpu_set(cpu_logical_id(hwid), mask); | 100 | cpu_set(cpu_logical_id(hwid), mask); |
101 | 101 | ||
102 | if (irq < NR_IRQS) { | 102 | if (irq < NR_IRQS) { |
103 | irq_affinity[irq] = mask; | 103 | irq_desc[irq].affinity = mask; |
104 | irq_redir[irq] = (char) (redir & 0xff); | 104 | irq_redir[irq] = (char) (redir & 0xff); |
105 | } | 105 | } |
106 | } | 106 | } |
@@ -120,7 +120,7 @@ static void migrate_irqs(void) | |||
120 | int irq, new_cpu; | 120 | int irq, new_cpu; |
121 | 121 | ||
122 | for (irq=0; irq < NR_IRQS; irq++) { | 122 | for (irq=0; irq < NR_IRQS; irq++) { |
123 | desc = irq_descp(irq); | 123 | desc = irq_desc + irq; |
124 | 124 | ||
125 | /* | 125 | /* |
126 | * No handling for now. | 126 | * No handling for now. |
@@ -131,7 +131,7 @@ static void migrate_irqs(void) | |||
131 | if (desc->status == IRQ_PER_CPU) | 131 | if (desc->status == IRQ_PER_CPU) |
132 | continue; | 132 | continue; |
133 | 133 | ||
134 | cpus_and(mask, irq_affinity[irq], cpu_online_map); | 134 | cpus_and(mask, irq_desc[irq].affinity, cpu_online_map); |
135 | if (any_online_cpu(mask) == NR_CPUS) { | 135 | if (any_online_cpu(mask) == NR_CPUS) { |
136 | /* | 136 | /* |
137 | * Save it for phase 2 processing | 137 | * Save it for phase 2 processing |
@@ -144,15 +144,15 @@ static void migrate_irqs(void) | |||
144 | /* | 144 | /* |
145 | * Al three are essential, currently WARN_ON.. maybe panic? | 145 | * Al three are essential, currently WARN_ON.. maybe panic? |
146 | */ | 146 | */ |
147 | if (desc->handler && desc->handler->disable && | 147 | if (desc->chip && desc->chip->disable && |
148 | desc->handler->enable && desc->handler->set_affinity) { | 148 | desc->chip->enable && desc->chip->set_affinity) { |
149 | desc->handler->disable(irq); | 149 | desc->chip->disable(irq); |
150 | desc->handler->set_affinity(irq, mask); | 150 | desc->chip->set_affinity(irq, mask); |
151 | desc->handler->enable(irq); | 151 | desc->chip->enable(irq); |
152 | } else { | 152 | } else { |
153 | WARN_ON((!(desc->handler) || !(desc->handler->disable) || | 153 | WARN_ON((!(desc->chip) || !(desc->chip->disable) || |
154 | !(desc->handler->enable) || | 154 | !(desc->chip->enable) || |
155 | !(desc->handler->set_affinity))); | 155 | !(desc->chip->set_affinity))); |
156 | } | 156 | } |
157 | } | 157 | } |
158 | } | 158 | } |
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index ef9a2b49307a..f5035304594e 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c | |||
@@ -249,9 +249,9 @@ register_percpu_irq (ia64_vector vec, struct irqaction *action) | |||
249 | 249 | ||
250 | for (irq = 0; irq < NR_IRQS; ++irq) | 250 | for (irq = 0; irq < NR_IRQS; ++irq) |
251 | if (irq_to_vector(irq) == vec) { | 251 | if (irq_to_vector(irq) == vec) { |
252 | desc = irq_descp(irq); | 252 | desc = irq_desc + irq; |
253 | desc->status |= IRQ_PER_CPU; | 253 | desc->status |= IRQ_PER_CPU; |
254 | desc->handler = &irq_type_ia64_lsapic; | 254 | desc->chip = &irq_type_ia64_lsapic; |
255 | if (action) | 255 | if (action) |
256 | setup_irq(irq, action); | 256 | setup_irq(irq, action); |
257 | } | 257 | } |
diff --git a/arch/ia64/kernel/irq_lsapic.c b/arch/ia64/kernel/irq_lsapic.c index ea14e6a04409..1ab58b09f3d7 100644 --- a/arch/ia64/kernel/irq_lsapic.c +++ b/arch/ia64/kernel/irq_lsapic.c | |||
@@ -26,6 +26,13 @@ lsapic_noop (unsigned int irq) | |||
26 | /* nuthing to do... */ | 26 | /* nuthing to do... */ |
27 | } | 27 | } |
28 | 28 | ||
29 | static int lsapic_retrigger(unsigned int irq) | ||
30 | { | ||
31 | ia64_resend_irq(irq); | ||
32 | |||
33 | return 1; | ||
34 | } | ||
35 | |||
29 | struct hw_interrupt_type irq_type_ia64_lsapic = { | 36 | struct hw_interrupt_type irq_type_ia64_lsapic = { |
30 | .typename = "LSAPIC", | 37 | .typename = "LSAPIC", |
31 | .startup = lsapic_noop_startup, | 38 | .startup = lsapic_noop_startup, |
@@ -33,5 +40,6 @@ struct hw_interrupt_type irq_type_ia64_lsapic = { | |||
33 | .enable = lsapic_noop, | 40 | .enable = lsapic_noop, |
34 | .disable = lsapic_noop, | 41 | .disable = lsapic_noop, |
35 | .ack = lsapic_noop, | 42 | .ack = lsapic_noop, |
36 | .end = lsapic_noop | 43 | .end = lsapic_noop, |
44 | .retrigger = lsapic_retrigger, | ||
37 | }; | 45 | }; |
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 6a0880639bc9..d7dc5e63de63 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c | |||
@@ -1788,7 +1788,7 @@ ia64_mca_late_init(void) | |||
1788 | cpe_poll_enabled = 0; | 1788 | cpe_poll_enabled = 0; |
1789 | for (irq = 0; irq < NR_IRQS; ++irq) | 1789 | for (irq = 0; irq < NR_IRQS; ++irq) |
1790 | if (irq_to_vector(irq) == cpe_vector) { | 1790 | if (irq_to_vector(irq) == cpe_vector) { |
1791 | desc = irq_descp(irq); | 1791 | desc = irq_desc + irq; |
1792 | desc->status |= IRQ_PER_CPU; | 1792 | desc->status |= IRQ_PER_CPU; |
1793 | setup_irq(irq, &mca_cpe_irqaction); | 1793 | setup_irq(irq, &mca_cpe_irqaction); |
1794 | ia64_cpe_irq = irq; | 1794 | ia64_cpe_irq = irq; |
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 6d7bc8ff7b3a..a0055d3d695c 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c | |||
@@ -6165,7 +6165,7 @@ pfm_load_regs (struct task_struct *task) | |||
6165 | /* | 6165 | /* |
6166 | * will replay the PMU interrupt | 6166 | * will replay the PMU interrupt |
6167 | */ | 6167 | */ |
6168 | if (need_irq_resend) hw_resend_irq(NULL, IA64_PERFMON_VECTOR); | 6168 | if (need_irq_resend) ia64_resend_irq(IA64_PERFMON_VECTOR); |
6169 | 6169 | ||
6170 | pfm_stats[smp_processor_id()].pfm_replay_ovfl_intr_count++; | 6170 | pfm_stats[smp_processor_id()].pfm_replay_ovfl_intr_count++; |
6171 | } | 6171 | } |
@@ -6305,7 +6305,7 @@ pfm_load_regs (struct task_struct *task) | |||
6305 | /* | 6305 | /* |
6306 | * will replay the PMU interrupt | 6306 | * will replay the PMU interrupt |
6307 | */ | 6307 | */ |
6308 | if (need_irq_resend) hw_resend_irq(NULL, IA64_PERFMON_VECTOR); | 6308 | if (need_irq_resend) ia64_resend_irq(IA64_PERFMON_VECTOR); |
6309 | 6309 | ||
6310 | pfm_stats[smp_processor_id()].pfm_replay_ovfl_intr_count++; | 6310 | pfm_stats[smp_processor_id()].pfm_replay_ovfl_intr_count++; |
6311 | } | 6311 | } |
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 44e9547878ac..5203df78f150 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c | |||
@@ -677,16 +677,16 @@ int migrate_platform_irqs(unsigned int cpu) | |||
677 | new_cpei_cpu = any_online_cpu(cpu_online_map); | 677 | new_cpei_cpu = any_online_cpu(cpu_online_map); |
678 | mask = cpumask_of_cpu(new_cpei_cpu); | 678 | mask = cpumask_of_cpu(new_cpei_cpu); |
679 | set_cpei_target_cpu(new_cpei_cpu); | 679 | set_cpei_target_cpu(new_cpei_cpu); |
680 | desc = irq_descp(ia64_cpe_irq); | 680 | desc = irq_desc + ia64_cpe_irq; |
681 | /* | 681 | /* |
682 | * Switch for now, immediatly, we need to do fake intr | 682 | * Switch for now, immediatly, we need to do fake intr |
683 | * as other interrupts, but need to study CPEI behaviour with | 683 | * as other interrupts, but need to study CPEI behaviour with |
684 | * polling before making changes. | 684 | * polling before making changes. |
685 | */ | 685 | */ |
686 | if (desc) { | 686 | if (desc) { |
687 | desc->handler->disable(ia64_cpe_irq); | 687 | desc->chip->disable(ia64_cpe_irq); |
688 | desc->handler->set_affinity(ia64_cpe_irq, mask); | 688 | desc->chip->set_affinity(ia64_cpe_irq, mask); |
689 | desc->handler->enable(ia64_cpe_irq); | 689 | desc->chip->enable(ia64_cpe_irq); |
690 | printk ("Re-targetting CPEI to cpu %d\n", new_cpei_cpu); | 690 | printk ("Re-targetting CPEI to cpu %d\n", new_cpei_cpu); |
691 | } | 691 | } |
692 | } | 692 | } |
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 77375a55da31..5bef0e3603f2 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c | |||
@@ -568,7 +568,7 @@ pcibios_disable_device (struct pci_dev *dev) | |||
568 | 568 | ||
569 | void | 569 | void |
570 | pcibios_align_resource (void *data, struct resource *res, | 570 | pcibios_align_resource (void *data, struct resource *res, |
571 | unsigned long size, unsigned long align) | 571 | resource_size_t size, resource_size_t align) |
572 | { | 572 | { |
573 | } | 573 | } |
574 | 574 | ||
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c index 677c6c0fd661..7bb6ad188ba3 100644 --- a/arch/ia64/sn/kernel/irq.c +++ b/arch/ia64/sn/kernel/irq.c | |||
@@ -225,8 +225,8 @@ void sn_irq_init(void) | |||
225 | ia64_last_device_vector = IA64_SN2_LAST_DEVICE_VECTOR; | 225 | ia64_last_device_vector = IA64_SN2_LAST_DEVICE_VECTOR; |
226 | 226 | ||
227 | for (i = 0; i < NR_IRQS; i++) { | 227 | for (i = 0; i < NR_IRQS; i++) { |
228 | if (base_desc[i].handler == &no_irq_type) { | 228 | if (base_desc[i].chip == &no_irq_type) { |
229 | base_desc[i].handler = &irq_type_sn; | 229 | base_desc[i].chip = &irq_type_sn; |
230 | } | 230 | } |
231 | } | 231 | } |
232 | } | 232 | } |
diff --git a/arch/m32r/kernel/irq.c b/arch/m32r/kernel/irq.c index a4634b06f675..3841861df6a2 100644 --- a/arch/m32r/kernel/irq.c +++ b/arch/m32r/kernel/irq.c | |||
@@ -54,7 +54,7 @@ int show_interrupts(struct seq_file *p, void *v) | |||
54 | for_each_online_cpu(j) | 54 | for_each_online_cpu(j) |
55 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); | 55 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); |
56 | #endif | 56 | #endif |
57 | seq_printf(p, " %14s", irq_desc[i].handler->typename); | 57 | seq_printf(p, " %14s", irq_desc[i].chip->typename); |
58 | seq_printf(p, " %s", action->name); | 58 | seq_printf(p, " %s", action->name); |
59 | 59 | ||
60 | for (action=action->next; action; action = action->next) | 60 | for (action=action->next; action; action = action->next) |
diff --git a/arch/m32r/kernel/setup_m32104ut.c b/arch/m32r/kernel/setup_m32104ut.c index 6328e1357a80..f9f56c270195 100644 --- a/arch/m32r/kernel/setup_m32104ut.c +++ b/arch/m32r/kernel/setup_m32104ut.c | |||
@@ -87,7 +87,7 @@ void __init init_IRQ(void) | |||
87 | #if defined(CONFIG_SMC91X) | 87 | #if defined(CONFIG_SMC91X) |
88 | /* INT#0: LAN controller on M32104UT-LAN (SMC91C111)*/ | 88 | /* INT#0: LAN controller on M32104UT-LAN (SMC91C111)*/ |
89 | irq_desc[M32R_IRQ_INT0].status = IRQ_DISABLED; | 89 | irq_desc[M32R_IRQ_INT0].status = IRQ_DISABLED; |
90 | irq_desc[M32R_IRQ_INT0].handler = &m32104ut_irq_type; | 90 | irq_desc[M32R_IRQ_INT0].chip = &m32104ut_irq_type; |
91 | irq_desc[M32R_IRQ_INT0].action = 0; | 91 | irq_desc[M32R_IRQ_INT0].action = 0; |
92 | irq_desc[M32R_IRQ_INT0].depth = 1; | 92 | irq_desc[M32R_IRQ_INT0].depth = 1; |
93 | icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN | M32R_ICUCR_ISMOD11; /* "H" level sense */ | 93 | icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN | M32R_ICUCR_ISMOD11; /* "H" level sense */ |
@@ -96,7 +96,7 @@ void __init init_IRQ(void) | |||
96 | 96 | ||
97 | /* MFT2 : system timer */ | 97 | /* MFT2 : system timer */ |
98 | irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; | 98 | irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; |
99 | irq_desc[M32R_IRQ_MFT2].handler = &m32104ut_irq_type; | 99 | irq_desc[M32R_IRQ_MFT2].chip = &m32104ut_irq_type; |
100 | irq_desc[M32R_IRQ_MFT2].action = 0; | 100 | irq_desc[M32R_IRQ_MFT2].action = 0; |
101 | irq_desc[M32R_IRQ_MFT2].depth = 1; | 101 | irq_desc[M32R_IRQ_MFT2].depth = 1; |
102 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; | 102 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; |
@@ -105,7 +105,7 @@ void __init init_IRQ(void) | |||
105 | #ifdef CONFIG_SERIAL_M32R_SIO | 105 | #ifdef CONFIG_SERIAL_M32R_SIO |
106 | /* SIO0_R : uart receive data */ | 106 | /* SIO0_R : uart receive data */ |
107 | irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; | 107 | irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; |
108 | irq_desc[M32R_IRQ_SIO0_R].handler = &m32104ut_irq_type; | 108 | irq_desc[M32R_IRQ_SIO0_R].chip = &m32104ut_irq_type; |
109 | irq_desc[M32R_IRQ_SIO0_R].action = 0; | 109 | irq_desc[M32R_IRQ_SIO0_R].action = 0; |
110 | irq_desc[M32R_IRQ_SIO0_R].depth = 1; | 110 | irq_desc[M32R_IRQ_SIO0_R].depth = 1; |
111 | icu_data[M32R_IRQ_SIO0_R].icucr = M32R_ICUCR_IEN; | 111 | icu_data[M32R_IRQ_SIO0_R].icucr = M32R_ICUCR_IEN; |
@@ -113,7 +113,7 @@ void __init init_IRQ(void) | |||
113 | 113 | ||
114 | /* SIO0_S : uart send data */ | 114 | /* SIO0_S : uart send data */ |
115 | irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; | 115 | irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; |
116 | irq_desc[M32R_IRQ_SIO0_S].handler = &m32104ut_irq_type; | 116 | irq_desc[M32R_IRQ_SIO0_S].chip = &m32104ut_irq_type; |
117 | irq_desc[M32R_IRQ_SIO0_S].action = 0; | 117 | irq_desc[M32R_IRQ_SIO0_S].action = 0; |
118 | irq_desc[M32R_IRQ_SIO0_S].depth = 1; | 118 | irq_desc[M32R_IRQ_SIO0_S].depth = 1; |
119 | icu_data[M32R_IRQ_SIO0_S].icucr = M32R_ICUCR_IEN; | 119 | icu_data[M32R_IRQ_SIO0_S].icucr = M32R_ICUCR_IEN; |
diff --git a/arch/m32r/kernel/setup_m32700ut.c b/arch/m32r/kernel/setup_m32700ut.c index fad1fc99bb27..b6ab00eff580 100644 --- a/arch/m32r/kernel/setup_m32700ut.c +++ b/arch/m32r/kernel/setup_m32700ut.c | |||
@@ -301,7 +301,7 @@ void __init init_IRQ(void) | |||
301 | #if defined(CONFIG_SMC91X) | 301 | #if defined(CONFIG_SMC91X) |
302 | /* INT#0: LAN controller on M32700UT-LAN (SMC91C111)*/ | 302 | /* INT#0: LAN controller on M32700UT-LAN (SMC91C111)*/ |
303 | irq_desc[M32700UT_LAN_IRQ_LAN].status = IRQ_DISABLED; | 303 | irq_desc[M32700UT_LAN_IRQ_LAN].status = IRQ_DISABLED; |
304 | irq_desc[M32700UT_LAN_IRQ_LAN].handler = &m32700ut_lanpld_irq_type; | 304 | irq_desc[M32700UT_LAN_IRQ_LAN].chip = &m32700ut_lanpld_irq_type; |
305 | irq_desc[M32700UT_LAN_IRQ_LAN].action = 0; | 305 | irq_desc[M32700UT_LAN_IRQ_LAN].action = 0; |
306 | irq_desc[M32700UT_LAN_IRQ_LAN].depth = 1; /* disable nested irq */ | 306 | irq_desc[M32700UT_LAN_IRQ_LAN].depth = 1; /* disable nested irq */ |
307 | lanpld_icu_data[irq2lanpldirq(M32700UT_LAN_IRQ_LAN)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02; /* "H" edge sense */ | 307 | lanpld_icu_data[irq2lanpldirq(M32700UT_LAN_IRQ_LAN)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02; /* "H" edge sense */ |
@@ -310,7 +310,7 @@ void __init init_IRQ(void) | |||
310 | 310 | ||
311 | /* MFT2 : system timer */ | 311 | /* MFT2 : system timer */ |
312 | irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; | 312 | irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; |
313 | irq_desc[M32R_IRQ_MFT2].handler = &m32700ut_irq_type; | 313 | irq_desc[M32R_IRQ_MFT2].chip = &m32700ut_irq_type; |
314 | irq_desc[M32R_IRQ_MFT2].action = 0; | 314 | irq_desc[M32R_IRQ_MFT2].action = 0; |
315 | irq_desc[M32R_IRQ_MFT2].depth = 1; | 315 | irq_desc[M32R_IRQ_MFT2].depth = 1; |
316 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; | 316 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; |
@@ -318,7 +318,7 @@ void __init init_IRQ(void) | |||
318 | 318 | ||
319 | /* SIO0 : receive */ | 319 | /* SIO0 : receive */ |
320 | irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; | 320 | irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; |
321 | irq_desc[M32R_IRQ_SIO0_R].handler = &m32700ut_irq_type; | 321 | irq_desc[M32R_IRQ_SIO0_R].chip = &m32700ut_irq_type; |
322 | irq_desc[M32R_IRQ_SIO0_R].action = 0; | 322 | irq_desc[M32R_IRQ_SIO0_R].action = 0; |
323 | irq_desc[M32R_IRQ_SIO0_R].depth = 1; | 323 | irq_desc[M32R_IRQ_SIO0_R].depth = 1; |
324 | icu_data[M32R_IRQ_SIO0_R].icucr = 0; | 324 | icu_data[M32R_IRQ_SIO0_R].icucr = 0; |
@@ -326,7 +326,7 @@ void __init init_IRQ(void) | |||
326 | 326 | ||
327 | /* SIO0 : send */ | 327 | /* SIO0 : send */ |
328 | irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; | 328 | irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; |
329 | irq_desc[M32R_IRQ_SIO0_S].handler = &m32700ut_irq_type; | 329 | irq_desc[M32R_IRQ_SIO0_S].chip = &m32700ut_irq_type; |
330 | irq_desc[M32R_IRQ_SIO0_S].action = 0; | 330 | irq_desc[M32R_IRQ_SIO0_S].action = 0; |
331 | irq_desc[M32R_IRQ_SIO0_S].depth = 1; | 331 | irq_desc[M32R_IRQ_SIO0_S].depth = 1; |
332 | icu_data[M32R_IRQ_SIO0_S].icucr = 0; | 332 | icu_data[M32R_IRQ_SIO0_S].icucr = 0; |
@@ -334,7 +334,7 @@ void __init init_IRQ(void) | |||
334 | 334 | ||
335 | /* SIO1 : receive */ | 335 | /* SIO1 : receive */ |
336 | irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; | 336 | irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; |
337 | irq_desc[M32R_IRQ_SIO1_R].handler = &m32700ut_irq_type; | 337 | irq_desc[M32R_IRQ_SIO1_R].chip = &m32700ut_irq_type; |
338 | irq_desc[M32R_IRQ_SIO1_R].action = 0; | 338 | irq_desc[M32R_IRQ_SIO1_R].action = 0; |
339 | irq_desc[M32R_IRQ_SIO1_R].depth = 1; | 339 | irq_desc[M32R_IRQ_SIO1_R].depth = 1; |
340 | icu_data[M32R_IRQ_SIO1_R].icucr = 0; | 340 | icu_data[M32R_IRQ_SIO1_R].icucr = 0; |
@@ -342,7 +342,7 @@ void __init init_IRQ(void) | |||
342 | 342 | ||
343 | /* SIO1 : send */ | 343 | /* SIO1 : send */ |
344 | irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; | 344 | irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; |
345 | irq_desc[M32R_IRQ_SIO1_S].handler = &m32700ut_irq_type; | 345 | irq_desc[M32R_IRQ_SIO1_S].chip = &m32700ut_irq_type; |
346 | irq_desc[M32R_IRQ_SIO1_S].action = 0; | 346 | irq_desc[M32R_IRQ_SIO1_S].action = 0; |
347 | irq_desc[M32R_IRQ_SIO1_S].depth = 1; | 347 | irq_desc[M32R_IRQ_SIO1_S].depth = 1; |
348 | icu_data[M32R_IRQ_SIO1_S].icucr = 0; | 348 | icu_data[M32R_IRQ_SIO1_S].icucr = 0; |
@@ -350,7 +350,7 @@ void __init init_IRQ(void) | |||
350 | 350 | ||
351 | /* DMA1 : */ | 351 | /* DMA1 : */ |
352 | irq_desc[M32R_IRQ_DMA1].status = IRQ_DISABLED; | 352 | irq_desc[M32R_IRQ_DMA1].status = IRQ_DISABLED; |
353 | irq_desc[M32R_IRQ_DMA1].handler = &m32700ut_irq_type; | 353 | irq_desc[M32R_IRQ_DMA1].chip = &m32700ut_irq_type; |
354 | irq_desc[M32R_IRQ_DMA1].action = 0; | 354 | irq_desc[M32R_IRQ_DMA1].action = 0; |
355 | irq_desc[M32R_IRQ_DMA1].depth = 1; | 355 | irq_desc[M32R_IRQ_DMA1].depth = 1; |
356 | icu_data[M32R_IRQ_DMA1].icucr = 0; | 356 | icu_data[M32R_IRQ_DMA1].icucr = 0; |
@@ -359,7 +359,7 @@ void __init init_IRQ(void) | |||
359 | #ifdef CONFIG_SERIAL_M32R_PLDSIO | 359 | #ifdef CONFIG_SERIAL_M32R_PLDSIO |
360 | /* INT#1: SIO0 Receive on PLD */ | 360 | /* INT#1: SIO0 Receive on PLD */ |
361 | irq_desc[PLD_IRQ_SIO0_RCV].status = IRQ_DISABLED; | 361 | irq_desc[PLD_IRQ_SIO0_RCV].status = IRQ_DISABLED; |
362 | irq_desc[PLD_IRQ_SIO0_RCV].handler = &m32700ut_pld_irq_type; | 362 | irq_desc[PLD_IRQ_SIO0_RCV].chip = &m32700ut_pld_irq_type; |
363 | irq_desc[PLD_IRQ_SIO0_RCV].action = 0; | 363 | irq_desc[PLD_IRQ_SIO0_RCV].action = 0; |
364 | irq_desc[PLD_IRQ_SIO0_RCV].depth = 1; /* disable nested irq */ | 364 | irq_desc[PLD_IRQ_SIO0_RCV].depth = 1; /* disable nested irq */ |
365 | pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_RCV)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03; | 365 | pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_RCV)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03; |
@@ -367,7 +367,7 @@ void __init init_IRQ(void) | |||
367 | 367 | ||
368 | /* INT#1: SIO0 Send on PLD */ | 368 | /* INT#1: SIO0 Send on PLD */ |
369 | irq_desc[PLD_IRQ_SIO0_SND].status = IRQ_DISABLED; | 369 | irq_desc[PLD_IRQ_SIO0_SND].status = IRQ_DISABLED; |
370 | irq_desc[PLD_IRQ_SIO0_SND].handler = &m32700ut_pld_irq_type; | 370 | irq_desc[PLD_IRQ_SIO0_SND].chip = &m32700ut_pld_irq_type; |
371 | irq_desc[PLD_IRQ_SIO0_SND].action = 0; | 371 | irq_desc[PLD_IRQ_SIO0_SND].action = 0; |
372 | irq_desc[PLD_IRQ_SIO0_SND].depth = 1; /* disable nested irq */ | 372 | irq_desc[PLD_IRQ_SIO0_SND].depth = 1; /* disable nested irq */ |
373 | pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_SND)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03; | 373 | pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_SND)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03; |
@@ -376,7 +376,7 @@ void __init init_IRQ(void) | |||
376 | 376 | ||
377 | /* INT#1: CFC IREQ on PLD */ | 377 | /* INT#1: CFC IREQ on PLD */ |
378 | irq_desc[PLD_IRQ_CFIREQ].status = IRQ_DISABLED; | 378 | irq_desc[PLD_IRQ_CFIREQ].status = IRQ_DISABLED; |
379 | irq_desc[PLD_IRQ_CFIREQ].handler = &m32700ut_pld_irq_type; | 379 | irq_desc[PLD_IRQ_CFIREQ].chip = &m32700ut_pld_irq_type; |
380 | irq_desc[PLD_IRQ_CFIREQ].action = 0; | 380 | irq_desc[PLD_IRQ_CFIREQ].action = 0; |
381 | irq_desc[PLD_IRQ_CFIREQ].depth = 1; /* disable nested irq */ | 381 | irq_desc[PLD_IRQ_CFIREQ].depth = 1; /* disable nested irq */ |
382 | pld_icu_data[irq2pldirq(PLD_IRQ_CFIREQ)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01; /* 'L' level sense */ | 382 | pld_icu_data[irq2pldirq(PLD_IRQ_CFIREQ)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01; /* 'L' level sense */ |
@@ -384,7 +384,7 @@ void __init init_IRQ(void) | |||
384 | 384 | ||
385 | /* INT#1: CFC Insert on PLD */ | 385 | /* INT#1: CFC Insert on PLD */ |
386 | irq_desc[PLD_IRQ_CFC_INSERT].status = IRQ_DISABLED; | 386 | irq_desc[PLD_IRQ_CFC_INSERT].status = IRQ_DISABLED; |
387 | irq_desc[PLD_IRQ_CFC_INSERT].handler = &m32700ut_pld_irq_type; | 387 | irq_desc[PLD_IRQ_CFC_INSERT].chip = &m32700ut_pld_irq_type; |
388 | irq_desc[PLD_IRQ_CFC_INSERT].action = 0; | 388 | irq_desc[PLD_IRQ_CFC_INSERT].action = 0; |
389 | irq_desc[PLD_IRQ_CFC_INSERT].depth = 1; /* disable nested irq */ | 389 | irq_desc[PLD_IRQ_CFC_INSERT].depth = 1; /* disable nested irq */ |
390 | pld_icu_data[irq2pldirq(PLD_IRQ_CFC_INSERT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD00; /* 'L' edge sense */ | 390 | pld_icu_data[irq2pldirq(PLD_IRQ_CFC_INSERT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD00; /* 'L' edge sense */ |
@@ -392,7 +392,7 @@ void __init init_IRQ(void) | |||
392 | 392 | ||
393 | /* INT#1: CFC Eject on PLD */ | 393 | /* INT#1: CFC Eject on PLD */ |
394 | irq_desc[PLD_IRQ_CFC_EJECT].status = IRQ_DISABLED; | 394 | irq_desc[PLD_IRQ_CFC_EJECT].status = IRQ_DISABLED; |
395 | irq_desc[PLD_IRQ_CFC_EJECT].handler = &m32700ut_pld_irq_type; | 395 | irq_desc[PLD_IRQ_CFC_EJECT].chip = &m32700ut_pld_irq_type; |
396 | irq_desc[PLD_IRQ_CFC_EJECT].action = 0; | 396 | irq_desc[PLD_IRQ_CFC_EJECT].action = 0; |
397 | irq_desc[PLD_IRQ_CFC_EJECT].depth = 1; /* disable nested irq */ | 397 | irq_desc[PLD_IRQ_CFC_EJECT].depth = 1; /* disable nested irq */ |
398 | pld_icu_data[irq2pldirq(PLD_IRQ_CFC_EJECT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02; /* 'H' edge sense */ | 398 | pld_icu_data[irq2pldirq(PLD_IRQ_CFC_EJECT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02; /* 'H' edge sense */ |
@@ -416,7 +416,7 @@ void __init init_IRQ(void) | |||
416 | outw(USBCR_OTGS, USBCR); /* USBCR: non-OTG */ | 416 | outw(USBCR_OTGS, USBCR); /* USBCR: non-OTG */ |
417 | 417 | ||
418 | irq_desc[M32700UT_LCD_IRQ_USB_INT1].status = IRQ_DISABLED; | 418 | irq_desc[M32700UT_LCD_IRQ_USB_INT1].status = IRQ_DISABLED; |
419 | irq_desc[M32700UT_LCD_IRQ_USB_INT1].handler = &m32700ut_lcdpld_irq_type; | 419 | irq_desc[M32700UT_LCD_IRQ_USB_INT1].chip = &m32700ut_lcdpld_irq_type; |
420 | irq_desc[M32700UT_LCD_IRQ_USB_INT1].action = 0; | 420 | irq_desc[M32700UT_LCD_IRQ_USB_INT1].action = 0; |
421 | irq_desc[M32700UT_LCD_IRQ_USB_INT1].depth = 1; | 421 | irq_desc[M32700UT_LCD_IRQ_USB_INT1].depth = 1; |
422 | lcdpld_icu_data[irq2lcdpldirq(M32700UT_LCD_IRQ_USB_INT1)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01; /* "L" level sense */ | 422 | lcdpld_icu_data[irq2lcdpldirq(M32700UT_LCD_IRQ_USB_INT1)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01; /* "L" level sense */ |
@@ -434,7 +434,7 @@ void __init init_IRQ(void) | |||
434 | * INT3# is used for AR | 434 | * INT3# is used for AR |
435 | */ | 435 | */ |
436 | irq_desc[M32R_IRQ_INT3].status = IRQ_DISABLED; | 436 | irq_desc[M32R_IRQ_INT3].status = IRQ_DISABLED; |
437 | irq_desc[M32R_IRQ_INT3].handler = &m32700ut_irq_type; | 437 | irq_desc[M32R_IRQ_INT3].chip = &m32700ut_irq_type; |
438 | irq_desc[M32R_IRQ_INT3].action = 0; | 438 | irq_desc[M32R_IRQ_INT3].action = 0; |
439 | irq_desc[M32R_IRQ_INT3].depth = 1; | 439 | irq_desc[M32R_IRQ_INT3].depth = 1; |
440 | icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; | 440 | icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; |
diff --git a/arch/m32r/kernel/setup_mappi.c b/arch/m32r/kernel/setup_mappi.c index 00f253209cb3..c268044185f5 100644 --- a/arch/m32r/kernel/setup_mappi.c +++ b/arch/m32r/kernel/setup_mappi.c | |||
@@ -86,7 +86,7 @@ void __init init_IRQ(void) | |||
86 | #ifdef CONFIG_NE2000 | 86 | #ifdef CONFIG_NE2000 |
87 | /* INT0 : LAN controller (RTL8019AS) */ | 87 | /* INT0 : LAN controller (RTL8019AS) */ |
88 | irq_desc[M32R_IRQ_INT0].status = IRQ_DISABLED; | 88 | irq_desc[M32R_IRQ_INT0].status = IRQ_DISABLED; |
89 | irq_desc[M32R_IRQ_INT0].handler = &mappi_irq_type; | 89 | irq_desc[M32R_IRQ_INT0].chip = &mappi_irq_type; |
90 | irq_desc[M32R_IRQ_INT0].action = 0; | 90 | irq_desc[M32R_IRQ_INT0].action = 0; |
91 | irq_desc[M32R_IRQ_INT0].depth = 1; | 91 | irq_desc[M32R_IRQ_INT0].depth = 1; |
92 | icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; | 92 | icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; |
@@ -95,7 +95,7 @@ void __init init_IRQ(void) | |||
95 | 95 | ||
96 | /* MFT2 : system timer */ | 96 | /* MFT2 : system timer */ |
97 | irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; | 97 | irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; |
98 | irq_desc[M32R_IRQ_MFT2].handler = &mappi_irq_type; | 98 | irq_desc[M32R_IRQ_MFT2].chip = &mappi_irq_type; |
99 | irq_desc[M32R_IRQ_MFT2].action = 0; | 99 | irq_desc[M32R_IRQ_MFT2].action = 0; |
100 | irq_desc[M32R_IRQ_MFT2].depth = 1; | 100 | irq_desc[M32R_IRQ_MFT2].depth = 1; |
101 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; | 101 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; |
@@ -104,7 +104,7 @@ void __init init_IRQ(void) | |||
104 | #ifdef CONFIG_SERIAL_M32R_SIO | 104 | #ifdef CONFIG_SERIAL_M32R_SIO |
105 | /* SIO0_R : uart receive data */ | 105 | /* SIO0_R : uart receive data */ |
106 | irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; | 106 | irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; |
107 | irq_desc[M32R_IRQ_SIO0_R].handler = &mappi_irq_type; | 107 | irq_desc[M32R_IRQ_SIO0_R].chip = &mappi_irq_type; |
108 | irq_desc[M32R_IRQ_SIO0_R].action = 0; | 108 | irq_desc[M32R_IRQ_SIO0_R].action = 0; |
109 | irq_desc[M32R_IRQ_SIO0_R].depth = 1; | 109 | irq_desc[M32R_IRQ_SIO0_R].depth = 1; |
110 | icu_data[M32R_IRQ_SIO0_R].icucr = 0; | 110 | icu_data[M32R_IRQ_SIO0_R].icucr = 0; |
@@ -112,7 +112,7 @@ void __init init_IRQ(void) | |||
112 | 112 | ||
113 | /* SIO0_S : uart send data */ | 113 | /* SIO0_S : uart send data */ |
114 | irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; | 114 | irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; |
115 | irq_desc[M32R_IRQ_SIO0_S].handler = &mappi_irq_type; | 115 | irq_desc[M32R_IRQ_SIO0_S].chip = &mappi_irq_type; |
116 | irq_desc[M32R_IRQ_SIO0_S].action = 0; | 116 | irq_desc[M32R_IRQ_SIO0_S].action = 0; |
117 | irq_desc[M32R_IRQ_SIO0_S].depth = 1; | 117 | irq_desc[M32R_IRQ_SIO0_S].depth = 1; |
118 | icu_data[M32R_IRQ_SIO0_S].icucr = 0; | 118 | icu_data[M32R_IRQ_SIO0_S].icucr = 0; |
@@ -120,7 +120,7 @@ void __init init_IRQ(void) | |||
120 | 120 | ||
121 | /* SIO1_R : uart receive data */ | 121 | /* SIO1_R : uart receive data */ |
122 | irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; | 122 | irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; |
123 | irq_desc[M32R_IRQ_SIO1_R].handler = &mappi_irq_type; | 123 | irq_desc[M32R_IRQ_SIO1_R].chip = &mappi_irq_type; |
124 | irq_desc[M32R_IRQ_SIO1_R].action = 0; | 124 | irq_desc[M32R_IRQ_SIO1_R].action = 0; |
125 | irq_desc[M32R_IRQ_SIO1_R].depth = 1; | 125 | irq_desc[M32R_IRQ_SIO1_R].depth = 1; |
126 | icu_data[M32R_IRQ_SIO1_R].icucr = 0; | 126 | icu_data[M32R_IRQ_SIO1_R].icucr = 0; |
@@ -128,7 +128,7 @@ void __init init_IRQ(void) | |||
128 | 128 | ||
129 | /* SIO1_S : uart send data */ | 129 | /* SIO1_S : uart send data */ |
130 | irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; | 130 | irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; |
131 | irq_desc[M32R_IRQ_SIO1_S].handler = &mappi_irq_type; | 131 | irq_desc[M32R_IRQ_SIO1_S].chip = &mappi_irq_type; |
132 | irq_desc[M32R_IRQ_SIO1_S].action = 0; | 132 | irq_desc[M32R_IRQ_SIO1_S].action = 0; |
133 | irq_desc[M32R_IRQ_SIO1_S].depth = 1; | 133 | irq_desc[M32R_IRQ_SIO1_S].depth = 1; |
134 | icu_data[M32R_IRQ_SIO1_S].icucr = 0; | 134 | icu_data[M32R_IRQ_SIO1_S].icucr = 0; |
@@ -138,7 +138,7 @@ void __init init_IRQ(void) | |||
138 | #if defined(CONFIG_M32R_PCC) | 138 | #if defined(CONFIG_M32R_PCC) |
139 | /* INT1 : pccard0 interrupt */ | 139 | /* INT1 : pccard0 interrupt */ |
140 | irq_desc[M32R_IRQ_INT1].status = IRQ_DISABLED; | 140 | irq_desc[M32R_IRQ_INT1].status = IRQ_DISABLED; |
141 | irq_desc[M32R_IRQ_INT1].handler = &mappi_irq_type; | 141 | irq_desc[M32R_IRQ_INT1].chip = &mappi_irq_type; |
142 | irq_desc[M32R_IRQ_INT1].action = 0; | 142 | irq_desc[M32R_IRQ_INT1].action = 0; |
143 | irq_desc[M32R_IRQ_INT1].depth = 1; | 143 | irq_desc[M32R_IRQ_INT1].depth = 1; |
144 | icu_data[M32R_IRQ_INT1].icucr = M32R_ICUCR_IEN | M32R_ICUCR_ISMOD00; | 144 | icu_data[M32R_IRQ_INT1].icucr = M32R_ICUCR_IEN | M32R_ICUCR_ISMOD00; |
@@ -146,7 +146,7 @@ void __init init_IRQ(void) | |||
146 | 146 | ||
147 | /* INT2 : pccard1 interrupt */ | 147 | /* INT2 : pccard1 interrupt */ |
148 | irq_desc[M32R_IRQ_INT2].status = IRQ_DISABLED; | 148 | irq_desc[M32R_IRQ_INT2].status = IRQ_DISABLED; |
149 | irq_desc[M32R_IRQ_INT2].handler = &mappi_irq_type; | 149 | irq_desc[M32R_IRQ_INT2].chip = &mappi_irq_type; |
150 | irq_desc[M32R_IRQ_INT2].action = 0; | 150 | irq_desc[M32R_IRQ_INT2].action = 0; |
151 | irq_desc[M32R_IRQ_INT2].depth = 1; | 151 | irq_desc[M32R_IRQ_INT2].depth = 1; |
152 | icu_data[M32R_IRQ_INT2].icucr = M32R_ICUCR_IEN | M32R_ICUCR_ISMOD00; | 152 | icu_data[M32R_IRQ_INT2].icucr = M32R_ICUCR_IEN | M32R_ICUCR_ISMOD00; |
diff --git a/arch/m32r/kernel/setup_mappi2.c b/arch/m32r/kernel/setup_mappi2.c index eebc9d8b4e72..bd2327d5cca2 100644 --- a/arch/m32r/kernel/setup_mappi2.c +++ b/arch/m32r/kernel/setup_mappi2.c | |||
@@ -87,7 +87,7 @@ void __init init_IRQ(void) | |||
87 | #if defined(CONFIG_SMC91X) | 87 | #if defined(CONFIG_SMC91X) |
88 | /* INT0 : LAN controller (SMC91111) */ | 88 | /* INT0 : LAN controller (SMC91111) */ |
89 | irq_desc[M32R_IRQ_INT0].status = IRQ_DISABLED; | 89 | irq_desc[M32R_IRQ_INT0].status = IRQ_DISABLED; |
90 | irq_desc[M32R_IRQ_INT0].handler = &mappi2_irq_type; | 90 | irq_desc[M32R_IRQ_INT0].chip = &mappi2_irq_type; |
91 | irq_desc[M32R_IRQ_INT0].action = 0; | 91 | irq_desc[M32R_IRQ_INT0].action = 0; |
92 | irq_desc[M32R_IRQ_INT0].depth = 1; | 92 | irq_desc[M32R_IRQ_INT0].depth = 1; |
93 | icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; | 93 | icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; |
@@ -96,7 +96,7 @@ void __init init_IRQ(void) | |||
96 | 96 | ||
97 | /* MFT2 : system timer */ | 97 | /* MFT2 : system timer */ |
98 | irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; | 98 | irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; |
99 | irq_desc[M32R_IRQ_MFT2].handler = &mappi2_irq_type; | 99 | irq_desc[M32R_IRQ_MFT2].chip = &mappi2_irq_type; |
100 | irq_desc[M32R_IRQ_MFT2].action = 0; | 100 | irq_desc[M32R_IRQ_MFT2].action = 0; |
101 | irq_desc[M32R_IRQ_MFT2].depth = 1; | 101 | irq_desc[M32R_IRQ_MFT2].depth = 1; |
102 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; | 102 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; |
@@ -105,7 +105,7 @@ void __init init_IRQ(void) | |||
105 | #ifdef CONFIG_SERIAL_M32R_SIO | 105 | #ifdef CONFIG_SERIAL_M32R_SIO |
106 | /* SIO0_R : uart receive data */ | 106 | /* SIO0_R : uart receive data */ |
107 | irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; | 107 | irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; |
108 | irq_desc[M32R_IRQ_SIO0_R].handler = &mappi2_irq_type; | 108 | irq_desc[M32R_IRQ_SIO0_R].chip = &mappi2_irq_type; |
109 | irq_desc[M32R_IRQ_SIO0_R].action = 0; | 109 | irq_desc[M32R_IRQ_SIO0_R].action = 0; |
110 | irq_desc[M32R_IRQ_SIO0_R].depth = 1; | 110 | irq_desc[M32R_IRQ_SIO0_R].depth = 1; |
111 | icu_data[M32R_IRQ_SIO0_R].icucr = 0; | 111 | icu_data[M32R_IRQ_SIO0_R].icucr = 0; |
@@ -113,14 +113,14 @@ void __init init_IRQ(void) | |||
113 | 113 | ||
114 | /* SIO0_S : uart send data */ | 114 | /* SIO0_S : uart send data */ |
115 | irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; | 115 | irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; |
116 | irq_desc[M32R_IRQ_SIO0_S].handler = &mappi2_irq_type; | 116 | irq_desc[M32R_IRQ_SIO0_S].chip = &mappi2_irq_type; |
117 | irq_desc[M32R_IRQ_SIO0_S].action = 0; | 117 | irq_desc[M32R_IRQ_SIO0_S].action = 0; |
118 | irq_desc[M32R_IRQ_SIO0_S].depth = 1; | 118 | irq_desc[M32R_IRQ_SIO0_S].depth = 1; |
119 | icu_data[M32R_IRQ_SIO0_S].icucr = 0; | 119 | icu_data[M32R_IRQ_SIO0_S].icucr = 0; |
120 | disable_mappi2_irq(M32R_IRQ_SIO0_S); | 120 | disable_mappi2_irq(M32R_IRQ_SIO0_S); |
121 | /* SIO1_R : uart receive data */ | 121 | /* SIO1_R : uart receive data */ |
122 | irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; | 122 | irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; |
123 | irq_desc[M32R_IRQ_SIO1_R].handler = &mappi2_irq_type; | 123 | irq_desc[M32R_IRQ_SIO1_R].chip = &mappi2_irq_type; |
124 | irq_desc[M32R_IRQ_SIO1_R].action = 0; | 124 | irq_desc[M32R_IRQ_SIO1_R].action = 0; |
125 | irq_desc[M32R_IRQ_SIO1_R].depth = 1; | 125 | irq_desc[M32R_IRQ_SIO1_R].depth = 1; |
126 | icu_data[M32R_IRQ_SIO1_R].icucr = 0; | 126 | icu_data[M32R_IRQ_SIO1_R].icucr = 0; |
@@ -128,7 +128,7 @@ void __init init_IRQ(void) | |||
128 | 128 | ||
129 | /* SIO1_S : uart send data */ | 129 | /* SIO1_S : uart send data */ |
130 | irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; | 130 | irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; |
131 | irq_desc[M32R_IRQ_SIO1_S].handler = &mappi2_irq_type; | 131 | irq_desc[M32R_IRQ_SIO1_S].chip = &mappi2_irq_type; |
132 | irq_desc[M32R_IRQ_SIO1_S].action = 0; | 132 | irq_desc[M32R_IRQ_SIO1_S].action = 0; |
133 | irq_desc[M32R_IRQ_SIO1_S].depth = 1; | 133 | irq_desc[M32R_IRQ_SIO1_S].depth = 1; |
134 | icu_data[M32R_IRQ_SIO1_S].icucr = 0; | 134 | icu_data[M32R_IRQ_SIO1_S].icucr = 0; |
@@ -138,7 +138,7 @@ void __init init_IRQ(void) | |||
138 | #if defined(CONFIG_USB) | 138 | #if defined(CONFIG_USB) |
139 | /* INT1 : USB Host controller interrupt */ | 139 | /* INT1 : USB Host controller interrupt */ |
140 | irq_desc[M32R_IRQ_INT1].status = IRQ_DISABLED; | 140 | irq_desc[M32R_IRQ_INT1].status = IRQ_DISABLED; |
141 | irq_desc[M32R_IRQ_INT1].handler = &mappi2_irq_type; | 141 | irq_desc[M32R_IRQ_INT1].chip = &mappi2_irq_type; |
142 | irq_desc[M32R_IRQ_INT1].action = 0; | 142 | irq_desc[M32R_IRQ_INT1].action = 0; |
143 | irq_desc[M32R_IRQ_INT1].depth = 1; | 143 | irq_desc[M32R_IRQ_INT1].depth = 1; |
144 | icu_data[M32R_IRQ_INT1].icucr = M32R_ICUCR_ISMOD01; | 144 | icu_data[M32R_IRQ_INT1].icucr = M32R_ICUCR_ISMOD01; |
@@ -147,7 +147,7 @@ void __init init_IRQ(void) | |||
147 | 147 | ||
148 | /* ICUCR40: CFC IREQ */ | 148 | /* ICUCR40: CFC IREQ */ |
149 | irq_desc[PLD_IRQ_CFIREQ].status = IRQ_DISABLED; | 149 | irq_desc[PLD_IRQ_CFIREQ].status = IRQ_DISABLED; |
150 | irq_desc[PLD_IRQ_CFIREQ].handler = &mappi2_irq_type; | 150 | irq_desc[PLD_IRQ_CFIREQ].chip = &mappi2_irq_type; |
151 | irq_desc[PLD_IRQ_CFIREQ].action = 0; | 151 | irq_desc[PLD_IRQ_CFIREQ].action = 0; |
152 | irq_desc[PLD_IRQ_CFIREQ].depth = 1; /* disable nested irq */ | 152 | irq_desc[PLD_IRQ_CFIREQ].depth = 1; /* disable nested irq */ |
153 | icu_data[PLD_IRQ_CFIREQ].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01; | 153 | icu_data[PLD_IRQ_CFIREQ].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01; |
@@ -156,7 +156,7 @@ void __init init_IRQ(void) | |||
156 | #if defined(CONFIG_M32R_CFC) | 156 | #if defined(CONFIG_M32R_CFC) |
157 | /* ICUCR41: CFC Insert */ | 157 | /* ICUCR41: CFC Insert */ |
158 | irq_desc[PLD_IRQ_CFC_INSERT].status = IRQ_DISABLED; | 158 | irq_desc[PLD_IRQ_CFC_INSERT].status = IRQ_DISABLED; |
159 | irq_desc[PLD_IRQ_CFC_INSERT].handler = &mappi2_irq_type; | 159 | irq_desc[PLD_IRQ_CFC_INSERT].chip = &mappi2_irq_type; |
160 | irq_desc[PLD_IRQ_CFC_INSERT].action = 0; | 160 | irq_desc[PLD_IRQ_CFC_INSERT].action = 0; |
161 | irq_desc[PLD_IRQ_CFC_INSERT].depth = 1; /* disable nested irq */ | 161 | irq_desc[PLD_IRQ_CFC_INSERT].depth = 1; /* disable nested irq */ |
162 | icu_data[PLD_IRQ_CFC_INSERT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD00; | 162 | icu_data[PLD_IRQ_CFC_INSERT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD00; |
@@ -164,7 +164,7 @@ void __init init_IRQ(void) | |||
164 | 164 | ||
165 | /* ICUCR42: CFC Eject */ | 165 | /* ICUCR42: CFC Eject */ |
166 | irq_desc[PLD_IRQ_CFC_EJECT].status = IRQ_DISABLED; | 166 | irq_desc[PLD_IRQ_CFC_EJECT].status = IRQ_DISABLED; |
167 | irq_desc[PLD_IRQ_CFC_EJECT].handler = &mappi2_irq_type; | 167 | irq_desc[PLD_IRQ_CFC_EJECT].chip = &mappi2_irq_type; |
168 | irq_desc[PLD_IRQ_CFC_EJECT].action = 0; | 168 | irq_desc[PLD_IRQ_CFC_EJECT].action = 0; |
169 | irq_desc[PLD_IRQ_CFC_EJECT].depth = 1; /* disable nested irq */ | 169 | irq_desc[PLD_IRQ_CFC_EJECT].depth = 1; /* disable nested irq */ |
170 | icu_data[PLD_IRQ_CFC_EJECT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; | 170 | icu_data[PLD_IRQ_CFC_EJECT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; |
diff --git a/arch/m32r/kernel/setup_mappi3.c b/arch/m32r/kernel/setup_mappi3.c index d2ff021e2d3d..014b51d17505 100644 --- a/arch/m32r/kernel/setup_mappi3.c +++ b/arch/m32r/kernel/setup_mappi3.c | |||
@@ -87,7 +87,7 @@ void __init init_IRQ(void) | |||
87 | #if defined(CONFIG_SMC91X) | 87 | #if defined(CONFIG_SMC91X) |
88 | /* INT0 : LAN controller (SMC91111) */ | 88 | /* INT0 : LAN controller (SMC91111) */ |
89 | irq_desc[M32R_IRQ_INT0].status = IRQ_DISABLED; | 89 | irq_desc[M32R_IRQ_INT0].status = IRQ_DISABLED; |
90 | irq_desc[M32R_IRQ_INT0].handler = &mappi3_irq_type; | 90 | irq_desc[M32R_IRQ_INT0].chip = &mappi3_irq_type; |
91 | irq_desc[M32R_IRQ_INT0].action = 0; | 91 | irq_desc[M32R_IRQ_INT0].action = 0; |
92 | irq_desc[M32R_IRQ_INT0].depth = 1; | 92 | irq_desc[M32R_IRQ_INT0].depth = 1; |
93 | icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; | 93 | icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; |
@@ -96,7 +96,7 @@ void __init init_IRQ(void) | |||
96 | 96 | ||
97 | /* MFT2 : system timer */ | 97 | /* MFT2 : system timer */ |
98 | irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; | 98 | irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; |
99 | irq_desc[M32R_IRQ_MFT2].handler = &mappi3_irq_type; | 99 | irq_desc[M32R_IRQ_MFT2].chip = &mappi3_irq_type; |
100 | irq_desc[M32R_IRQ_MFT2].action = 0; | 100 | irq_desc[M32R_IRQ_MFT2].action = 0; |
101 | irq_desc[M32R_IRQ_MFT2].depth = 1; | 101 | irq_desc[M32R_IRQ_MFT2].depth = 1; |
102 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; | 102 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; |
@@ -105,7 +105,7 @@ void __init init_IRQ(void) | |||
105 | #ifdef CONFIG_SERIAL_M32R_SIO | 105 | #ifdef CONFIG_SERIAL_M32R_SIO |
106 | /* SIO0_R : uart receive data */ | 106 | /* SIO0_R : uart receive data */ |
107 | irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; | 107 | irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; |
108 | irq_desc[M32R_IRQ_SIO0_R].handler = &mappi3_irq_type; | 108 | irq_desc[M32R_IRQ_SIO0_R].chip = &mappi3_irq_type; |
109 | irq_desc[M32R_IRQ_SIO0_R].action = 0; | 109 | irq_desc[M32R_IRQ_SIO0_R].action = 0; |
110 | irq_desc[M32R_IRQ_SIO0_R].depth = 1; | 110 | irq_desc[M32R_IRQ_SIO0_R].depth = 1; |
111 | icu_data[M32R_IRQ_SIO0_R].icucr = 0; | 111 | icu_data[M32R_IRQ_SIO0_R].icucr = 0; |
@@ -113,14 +113,14 @@ void __init init_IRQ(void) | |||
113 | 113 | ||
114 | /* SIO0_S : uart send data */ | 114 | /* SIO0_S : uart send data */ |
115 | irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; | 115 | irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; |
116 | irq_desc[M32R_IRQ_SIO0_S].handler = &mappi3_irq_type; | 116 | irq_desc[M32R_IRQ_SIO0_S].chip = &mappi3_irq_type; |
117 | irq_desc[M32R_IRQ_SIO0_S].action = 0; | 117 | irq_desc[M32R_IRQ_SIO0_S].action = 0; |
118 | irq_desc[M32R_IRQ_SIO0_S].depth = 1; | 118 | irq_desc[M32R_IRQ_SIO0_S].depth = 1; |
119 | icu_data[M32R_IRQ_SIO0_S].icucr = 0; | 119 | icu_data[M32R_IRQ_SIO0_S].icucr = 0; |
120 | disable_mappi3_irq(M32R_IRQ_SIO0_S); | 120 | disable_mappi3_irq(M32R_IRQ_SIO0_S); |
121 | /* SIO1_R : uart receive data */ | 121 | /* SIO1_R : uart receive data */ |
122 | irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; | 122 | irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; |
123 | irq_desc[M32R_IRQ_SIO1_R].handler = &mappi3_irq_type; | 123 | irq_desc[M32R_IRQ_SIO1_R].chip = &mappi3_irq_type; |
124 | irq_desc[M32R_IRQ_SIO1_R].action = 0; | 124 | irq_desc[M32R_IRQ_SIO1_R].action = 0; |
125 | irq_desc[M32R_IRQ_SIO1_R].depth = 1; | 125 | irq_desc[M32R_IRQ_SIO1_R].depth = 1; |
126 | icu_data[M32R_IRQ_SIO1_R].icucr = 0; | 126 | icu_data[M32R_IRQ_SIO1_R].icucr = 0; |
@@ -128,7 +128,7 @@ void __init init_IRQ(void) | |||
128 | 128 | ||
129 | /* SIO1_S : uart send data */ | 129 | /* SIO1_S : uart send data */ |
130 | irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; | 130 | irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; |
131 | irq_desc[M32R_IRQ_SIO1_S].handler = &mappi3_irq_type; | 131 | irq_desc[M32R_IRQ_SIO1_S].chip = &mappi3_irq_type; |
132 | irq_desc[M32R_IRQ_SIO1_S].action = 0; | 132 | irq_desc[M32R_IRQ_SIO1_S].action = 0; |
133 | irq_desc[M32R_IRQ_SIO1_S].depth = 1; | 133 | irq_desc[M32R_IRQ_SIO1_S].depth = 1; |
134 | icu_data[M32R_IRQ_SIO1_S].icucr = 0; | 134 | icu_data[M32R_IRQ_SIO1_S].icucr = 0; |
@@ -138,7 +138,7 @@ void __init init_IRQ(void) | |||
138 | #if defined(CONFIG_USB) | 138 | #if defined(CONFIG_USB) |
139 | /* INT1 : USB Host controller interrupt */ | 139 | /* INT1 : USB Host controller interrupt */ |
140 | irq_desc[M32R_IRQ_INT1].status = IRQ_DISABLED; | 140 | irq_desc[M32R_IRQ_INT1].status = IRQ_DISABLED; |
141 | irq_desc[M32R_IRQ_INT1].handler = &mappi3_irq_type; | 141 | irq_desc[M32R_IRQ_INT1].chip = &mappi3_irq_type; |
142 | irq_desc[M32R_IRQ_INT1].action = 0; | 142 | irq_desc[M32R_IRQ_INT1].action = 0; |
143 | irq_desc[M32R_IRQ_INT1].depth = 1; | 143 | irq_desc[M32R_IRQ_INT1].depth = 1; |
144 | icu_data[M32R_IRQ_INT1].icucr = M32R_ICUCR_ISMOD01; | 144 | icu_data[M32R_IRQ_INT1].icucr = M32R_ICUCR_ISMOD01; |
@@ -147,7 +147,7 @@ void __init init_IRQ(void) | |||
147 | 147 | ||
148 | /* CFC IREQ */ | 148 | /* CFC IREQ */ |
149 | irq_desc[PLD_IRQ_CFIREQ].status = IRQ_DISABLED; | 149 | irq_desc[PLD_IRQ_CFIREQ].status = IRQ_DISABLED; |
150 | irq_desc[PLD_IRQ_CFIREQ].handler = &mappi3_irq_type; | 150 | irq_desc[PLD_IRQ_CFIREQ].chip = &mappi3_irq_type; |
151 | irq_desc[PLD_IRQ_CFIREQ].action = 0; | 151 | irq_desc[PLD_IRQ_CFIREQ].action = 0; |
152 | irq_desc[PLD_IRQ_CFIREQ].depth = 1; /* disable nested irq */ | 152 | irq_desc[PLD_IRQ_CFIREQ].depth = 1; /* disable nested irq */ |
153 | icu_data[PLD_IRQ_CFIREQ].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01; | 153 | icu_data[PLD_IRQ_CFIREQ].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01; |
@@ -156,7 +156,7 @@ void __init init_IRQ(void) | |||
156 | #if defined(CONFIG_M32R_CFC) | 156 | #if defined(CONFIG_M32R_CFC) |
157 | /* ICUCR41: CFC Insert & eject */ | 157 | /* ICUCR41: CFC Insert & eject */ |
158 | irq_desc[PLD_IRQ_CFC_INSERT].status = IRQ_DISABLED; | 158 | irq_desc[PLD_IRQ_CFC_INSERT].status = IRQ_DISABLED; |
159 | irq_desc[PLD_IRQ_CFC_INSERT].handler = &mappi3_irq_type; | 159 | irq_desc[PLD_IRQ_CFC_INSERT].chip = &mappi3_irq_type; |
160 | irq_desc[PLD_IRQ_CFC_INSERT].action = 0; | 160 | irq_desc[PLD_IRQ_CFC_INSERT].action = 0; |
161 | irq_desc[PLD_IRQ_CFC_INSERT].depth = 1; /* disable nested irq */ | 161 | irq_desc[PLD_IRQ_CFC_INSERT].depth = 1; /* disable nested irq */ |
162 | icu_data[PLD_IRQ_CFC_INSERT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD00; | 162 | icu_data[PLD_IRQ_CFC_INSERT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD00; |
@@ -166,7 +166,7 @@ void __init init_IRQ(void) | |||
166 | 166 | ||
167 | /* IDE IREQ */ | 167 | /* IDE IREQ */ |
168 | irq_desc[PLD_IRQ_IDEIREQ].status = IRQ_DISABLED; | 168 | irq_desc[PLD_IRQ_IDEIREQ].status = IRQ_DISABLED; |
169 | irq_desc[PLD_IRQ_IDEIREQ].handler = &mappi3_irq_type; | 169 | irq_desc[PLD_IRQ_IDEIREQ].chip = &mappi3_irq_type; |
170 | irq_desc[PLD_IRQ_IDEIREQ].action = 0; | 170 | irq_desc[PLD_IRQ_IDEIREQ].action = 0; |
171 | irq_desc[PLD_IRQ_IDEIREQ].depth = 1; /* disable nested irq */ | 171 | irq_desc[PLD_IRQ_IDEIREQ].depth = 1; /* disable nested irq */ |
172 | icu_data[PLD_IRQ_IDEIREQ].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; | 172 | icu_data[PLD_IRQ_IDEIREQ].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; |
diff --git a/arch/m32r/kernel/setup_oaks32r.c b/arch/m32r/kernel/setup_oaks32r.c index 0e9e63538c0f..ea64831aef7a 100644 --- a/arch/m32r/kernel/setup_oaks32r.c +++ b/arch/m32r/kernel/setup_oaks32r.c | |||
@@ -85,7 +85,7 @@ void __init init_IRQ(void) | |||
85 | #ifdef CONFIG_NE2000 | 85 | #ifdef CONFIG_NE2000 |
86 | /* INT3 : LAN controller (RTL8019AS) */ | 86 | /* INT3 : LAN controller (RTL8019AS) */ |
87 | irq_desc[M32R_IRQ_INT3].status = IRQ_DISABLED; | 87 | irq_desc[M32R_IRQ_INT3].status = IRQ_DISABLED; |
88 | irq_desc[M32R_IRQ_INT3].handler = &oaks32r_irq_type; | 88 | irq_desc[M32R_IRQ_INT3].chip = &oaks32r_irq_type; |
89 | irq_desc[M32R_IRQ_INT3].action = 0; | 89 | irq_desc[M32R_IRQ_INT3].action = 0; |
90 | irq_desc[M32R_IRQ_INT3].depth = 1; | 90 | irq_desc[M32R_IRQ_INT3].depth = 1; |
91 | icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; | 91 | icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; |
@@ -94,7 +94,7 @@ void __init init_IRQ(void) | |||
94 | 94 | ||
95 | /* MFT2 : system timer */ | 95 | /* MFT2 : system timer */ |
96 | irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; | 96 | irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; |
97 | irq_desc[M32R_IRQ_MFT2].handler = &oaks32r_irq_type; | 97 | irq_desc[M32R_IRQ_MFT2].chip = &oaks32r_irq_type; |
98 | irq_desc[M32R_IRQ_MFT2].action = 0; | 98 | irq_desc[M32R_IRQ_MFT2].action = 0; |
99 | irq_desc[M32R_IRQ_MFT2].depth = 1; | 99 | irq_desc[M32R_IRQ_MFT2].depth = 1; |
100 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; | 100 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; |
@@ -103,7 +103,7 @@ void __init init_IRQ(void) | |||
103 | #ifdef CONFIG_SERIAL_M32R_SIO | 103 | #ifdef CONFIG_SERIAL_M32R_SIO |
104 | /* SIO0_R : uart receive data */ | 104 | /* SIO0_R : uart receive data */ |
105 | irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; | 105 | irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; |
106 | irq_desc[M32R_IRQ_SIO0_R].handler = &oaks32r_irq_type; | 106 | irq_desc[M32R_IRQ_SIO0_R].chip = &oaks32r_irq_type; |
107 | irq_desc[M32R_IRQ_SIO0_R].action = 0; | 107 | irq_desc[M32R_IRQ_SIO0_R].action = 0; |
108 | irq_desc[M32R_IRQ_SIO0_R].depth = 1; | 108 | irq_desc[M32R_IRQ_SIO0_R].depth = 1; |
109 | icu_data[M32R_IRQ_SIO0_R].icucr = 0; | 109 | icu_data[M32R_IRQ_SIO0_R].icucr = 0; |
@@ -111,7 +111,7 @@ void __init init_IRQ(void) | |||
111 | 111 | ||
112 | /* SIO0_S : uart send data */ | 112 | /* SIO0_S : uart send data */ |
113 | irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; | 113 | irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; |
114 | irq_desc[M32R_IRQ_SIO0_S].handler = &oaks32r_irq_type; | 114 | irq_desc[M32R_IRQ_SIO0_S].chip = &oaks32r_irq_type; |
115 | irq_desc[M32R_IRQ_SIO0_S].action = 0; | 115 | irq_desc[M32R_IRQ_SIO0_S].action = 0; |
116 | irq_desc[M32R_IRQ_SIO0_S].depth = 1; | 116 | irq_desc[M32R_IRQ_SIO0_S].depth = 1; |
117 | icu_data[M32R_IRQ_SIO0_S].icucr = 0; | 117 | icu_data[M32R_IRQ_SIO0_S].icucr = 0; |
@@ -119,7 +119,7 @@ void __init init_IRQ(void) | |||
119 | 119 | ||
120 | /* SIO1_R : uart receive data */ | 120 | /* SIO1_R : uart receive data */ |
121 | irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; | 121 | irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; |
122 | irq_desc[M32R_IRQ_SIO1_R].handler = &oaks32r_irq_type; | 122 | irq_desc[M32R_IRQ_SIO1_R].chip = &oaks32r_irq_type; |
123 | irq_desc[M32R_IRQ_SIO1_R].action = 0; | 123 | irq_desc[M32R_IRQ_SIO1_R].action = 0; |
124 | irq_desc[M32R_IRQ_SIO1_R].depth = 1; | 124 | irq_desc[M32R_IRQ_SIO1_R].depth = 1; |
125 | icu_data[M32R_IRQ_SIO1_R].icucr = 0; | 125 | icu_data[M32R_IRQ_SIO1_R].icucr = 0; |
@@ -127,7 +127,7 @@ void __init init_IRQ(void) | |||
127 | 127 | ||
128 | /* SIO1_S : uart send data */ | 128 | /* SIO1_S : uart send data */ |
129 | irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; | 129 | irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; |
130 | irq_desc[M32R_IRQ_SIO1_S].handler = &oaks32r_irq_type; | 130 | irq_desc[M32R_IRQ_SIO1_S].chip = &oaks32r_irq_type; |
131 | irq_desc[M32R_IRQ_SIO1_S].action = 0; | 131 | irq_desc[M32R_IRQ_SIO1_S].action = 0; |
132 | irq_desc[M32R_IRQ_SIO1_S].depth = 1; | 132 | irq_desc[M32R_IRQ_SIO1_S].depth = 1; |
133 | icu_data[M32R_IRQ_SIO1_S].icucr = 0; | 133 | icu_data[M32R_IRQ_SIO1_S].icucr = 0; |
diff --git a/arch/m32r/kernel/setup_opsput.c b/arch/m32r/kernel/setup_opsput.c index 548e8fc7949b..55e8972d455a 100644 --- a/arch/m32r/kernel/setup_opsput.c +++ b/arch/m32r/kernel/setup_opsput.c | |||
@@ -302,7 +302,7 @@ void __init init_IRQ(void) | |||
302 | #if defined(CONFIG_SMC91X) | 302 | #if defined(CONFIG_SMC91X) |
303 | /* INT#0: LAN controller on OPSPUT-LAN (SMC91C111)*/ | 303 | /* INT#0: LAN controller on OPSPUT-LAN (SMC91C111)*/ |
304 | irq_desc[OPSPUT_LAN_IRQ_LAN].status = IRQ_DISABLED; | 304 | irq_desc[OPSPUT_LAN_IRQ_LAN].status = IRQ_DISABLED; |
305 | irq_desc[OPSPUT_LAN_IRQ_LAN].handler = &opsput_lanpld_irq_type; | 305 | irq_desc[OPSPUT_LAN_IRQ_LAN].chip = &opsput_lanpld_irq_type; |
306 | irq_desc[OPSPUT_LAN_IRQ_LAN].action = 0; | 306 | irq_desc[OPSPUT_LAN_IRQ_LAN].action = 0; |
307 | irq_desc[OPSPUT_LAN_IRQ_LAN].depth = 1; /* disable nested irq */ | 307 | irq_desc[OPSPUT_LAN_IRQ_LAN].depth = 1; /* disable nested irq */ |
308 | lanpld_icu_data[irq2lanpldirq(OPSPUT_LAN_IRQ_LAN)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02; /* "H" edge sense */ | 308 | lanpld_icu_data[irq2lanpldirq(OPSPUT_LAN_IRQ_LAN)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02; /* "H" edge sense */ |
@@ -311,7 +311,7 @@ void __init init_IRQ(void) | |||
311 | 311 | ||
312 | /* MFT2 : system timer */ | 312 | /* MFT2 : system timer */ |
313 | irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; | 313 | irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; |
314 | irq_desc[M32R_IRQ_MFT2].handler = &opsput_irq_type; | 314 | irq_desc[M32R_IRQ_MFT2].chip = &opsput_irq_type; |
315 | irq_desc[M32R_IRQ_MFT2].action = 0; | 315 | irq_desc[M32R_IRQ_MFT2].action = 0; |
316 | irq_desc[M32R_IRQ_MFT2].depth = 1; | 316 | irq_desc[M32R_IRQ_MFT2].depth = 1; |
317 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; | 317 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; |
@@ -319,7 +319,7 @@ void __init init_IRQ(void) | |||
319 | 319 | ||
320 | /* SIO0 : receive */ | 320 | /* SIO0 : receive */ |
321 | irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; | 321 | irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; |
322 | irq_desc[M32R_IRQ_SIO0_R].handler = &opsput_irq_type; | 322 | irq_desc[M32R_IRQ_SIO0_R].chip = &opsput_irq_type; |
323 | irq_desc[M32R_IRQ_SIO0_R].action = 0; | 323 | irq_desc[M32R_IRQ_SIO0_R].action = 0; |
324 | irq_desc[M32R_IRQ_SIO0_R].depth = 1; | 324 | irq_desc[M32R_IRQ_SIO0_R].depth = 1; |
325 | icu_data[M32R_IRQ_SIO0_R].icucr = 0; | 325 | icu_data[M32R_IRQ_SIO0_R].icucr = 0; |
@@ -327,7 +327,7 @@ void __init init_IRQ(void) | |||
327 | 327 | ||
328 | /* SIO0 : send */ | 328 | /* SIO0 : send */ |
329 | irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; | 329 | irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; |
330 | irq_desc[M32R_IRQ_SIO0_S].handler = &opsput_irq_type; | 330 | irq_desc[M32R_IRQ_SIO0_S].chip = &opsput_irq_type; |
331 | irq_desc[M32R_IRQ_SIO0_S].action = 0; | 331 | irq_desc[M32R_IRQ_SIO0_S].action = 0; |
332 | irq_desc[M32R_IRQ_SIO0_S].depth = 1; | 332 | irq_desc[M32R_IRQ_SIO0_S].depth = 1; |
333 | icu_data[M32R_IRQ_SIO0_S].icucr = 0; | 333 | icu_data[M32R_IRQ_SIO0_S].icucr = 0; |
@@ -335,7 +335,7 @@ void __init init_IRQ(void) | |||
335 | 335 | ||
336 | /* SIO1 : receive */ | 336 | /* SIO1 : receive */ |
337 | irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; | 337 | irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; |
338 | irq_desc[M32R_IRQ_SIO1_R].handler = &opsput_irq_type; | 338 | irq_desc[M32R_IRQ_SIO1_R].chip = &opsput_irq_type; |
339 | irq_desc[M32R_IRQ_SIO1_R].action = 0; | 339 | irq_desc[M32R_IRQ_SIO1_R].action = 0; |
340 | irq_desc[M32R_IRQ_SIO1_R].depth = 1; | 340 | irq_desc[M32R_IRQ_SIO1_R].depth = 1; |
341 | icu_data[M32R_IRQ_SIO1_R].icucr = 0; | 341 | icu_data[M32R_IRQ_SIO1_R].icucr = 0; |
@@ -343,7 +343,7 @@ void __init init_IRQ(void) | |||
343 | 343 | ||
344 | /* SIO1 : send */ | 344 | /* SIO1 : send */ |
345 | irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; | 345 | irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; |
346 | irq_desc[M32R_IRQ_SIO1_S].handler = &opsput_irq_type; | 346 | irq_desc[M32R_IRQ_SIO1_S].chip = &opsput_irq_type; |
347 | irq_desc[M32R_IRQ_SIO1_S].action = 0; | 347 | irq_desc[M32R_IRQ_SIO1_S].action = 0; |
348 | irq_desc[M32R_IRQ_SIO1_S].depth = 1; | 348 | irq_desc[M32R_IRQ_SIO1_S].depth = 1; |
349 | icu_data[M32R_IRQ_SIO1_S].icucr = 0; | 349 | icu_data[M32R_IRQ_SIO1_S].icucr = 0; |
@@ -351,7 +351,7 @@ void __init init_IRQ(void) | |||
351 | 351 | ||
352 | /* DMA1 : */ | 352 | /* DMA1 : */ |
353 | irq_desc[M32R_IRQ_DMA1].status = IRQ_DISABLED; | 353 | irq_desc[M32R_IRQ_DMA1].status = IRQ_DISABLED; |
354 | irq_desc[M32R_IRQ_DMA1].handler = &opsput_irq_type; | 354 | irq_desc[M32R_IRQ_DMA1].chip = &opsput_irq_type; |
355 | irq_desc[M32R_IRQ_DMA1].action = 0; | 355 | irq_desc[M32R_IRQ_DMA1].action = 0; |
356 | irq_desc[M32R_IRQ_DMA1].depth = 1; | 356 | irq_desc[M32R_IRQ_DMA1].depth = 1; |
357 | icu_data[M32R_IRQ_DMA1].icucr = 0; | 357 | icu_data[M32R_IRQ_DMA1].icucr = 0; |
@@ -360,7 +360,7 @@ void __init init_IRQ(void) | |||
360 | #ifdef CONFIG_SERIAL_M32R_PLDSIO | 360 | #ifdef CONFIG_SERIAL_M32R_PLDSIO |
361 | /* INT#1: SIO0 Receive on PLD */ | 361 | /* INT#1: SIO0 Receive on PLD */ |
362 | irq_desc[PLD_IRQ_SIO0_RCV].status = IRQ_DISABLED; | 362 | irq_desc[PLD_IRQ_SIO0_RCV].status = IRQ_DISABLED; |
363 | irq_desc[PLD_IRQ_SIO0_RCV].handler = &opsput_pld_irq_type; | 363 | irq_desc[PLD_IRQ_SIO0_RCV].chip = &opsput_pld_irq_type; |
364 | irq_desc[PLD_IRQ_SIO0_RCV].action = 0; | 364 | irq_desc[PLD_IRQ_SIO0_RCV].action = 0; |
365 | irq_desc[PLD_IRQ_SIO0_RCV].depth = 1; /* disable nested irq */ | 365 | irq_desc[PLD_IRQ_SIO0_RCV].depth = 1; /* disable nested irq */ |
366 | pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_RCV)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03; | 366 | pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_RCV)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03; |
@@ -368,7 +368,7 @@ void __init init_IRQ(void) | |||
368 | 368 | ||
369 | /* INT#1: SIO0 Send on PLD */ | 369 | /* INT#1: SIO0 Send on PLD */ |
370 | irq_desc[PLD_IRQ_SIO0_SND].status = IRQ_DISABLED; | 370 | irq_desc[PLD_IRQ_SIO0_SND].status = IRQ_DISABLED; |
371 | irq_desc[PLD_IRQ_SIO0_SND].handler = &opsput_pld_irq_type; | 371 | irq_desc[PLD_IRQ_SIO0_SND].chip = &opsput_pld_irq_type; |
372 | irq_desc[PLD_IRQ_SIO0_SND].action = 0; | 372 | irq_desc[PLD_IRQ_SIO0_SND].action = 0; |
373 | irq_desc[PLD_IRQ_SIO0_SND].depth = 1; /* disable nested irq */ | 373 | irq_desc[PLD_IRQ_SIO0_SND].depth = 1; /* disable nested irq */ |
374 | pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_SND)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03; | 374 | pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_SND)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03; |
@@ -378,7 +378,7 @@ void __init init_IRQ(void) | |||
378 | #if defined(CONFIG_M32R_CFC) | 378 | #if defined(CONFIG_M32R_CFC) |
379 | /* INT#1: CFC IREQ on PLD */ | 379 | /* INT#1: CFC IREQ on PLD */ |
380 | irq_desc[PLD_IRQ_CFIREQ].status = IRQ_DISABLED; | 380 | irq_desc[PLD_IRQ_CFIREQ].status = IRQ_DISABLED; |
381 | irq_desc[PLD_IRQ_CFIREQ].handler = &opsput_pld_irq_type; | 381 | irq_desc[PLD_IRQ_CFIREQ].chip = &opsput_pld_irq_type; |
382 | irq_desc[PLD_IRQ_CFIREQ].action = 0; | 382 | irq_desc[PLD_IRQ_CFIREQ].action = 0; |
383 | irq_desc[PLD_IRQ_CFIREQ].depth = 1; /* disable nested irq */ | 383 | irq_desc[PLD_IRQ_CFIREQ].depth = 1; /* disable nested irq */ |
384 | pld_icu_data[irq2pldirq(PLD_IRQ_CFIREQ)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01; /* 'L' level sense */ | 384 | pld_icu_data[irq2pldirq(PLD_IRQ_CFIREQ)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01; /* 'L' level sense */ |
@@ -386,7 +386,7 @@ void __init init_IRQ(void) | |||
386 | 386 | ||
387 | /* INT#1: CFC Insert on PLD */ | 387 | /* INT#1: CFC Insert on PLD */ |
388 | irq_desc[PLD_IRQ_CFC_INSERT].status = IRQ_DISABLED; | 388 | irq_desc[PLD_IRQ_CFC_INSERT].status = IRQ_DISABLED; |
389 | irq_desc[PLD_IRQ_CFC_INSERT].handler = &opsput_pld_irq_type; | 389 | irq_desc[PLD_IRQ_CFC_INSERT].chip = &opsput_pld_irq_type; |
390 | irq_desc[PLD_IRQ_CFC_INSERT].action = 0; | 390 | irq_desc[PLD_IRQ_CFC_INSERT].action = 0; |
391 | irq_desc[PLD_IRQ_CFC_INSERT].depth = 1; /* disable nested irq */ | 391 | irq_desc[PLD_IRQ_CFC_INSERT].depth = 1; /* disable nested irq */ |
392 | pld_icu_data[irq2pldirq(PLD_IRQ_CFC_INSERT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD00; /* 'L' edge sense */ | 392 | pld_icu_data[irq2pldirq(PLD_IRQ_CFC_INSERT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD00; /* 'L' edge sense */ |
@@ -394,7 +394,7 @@ void __init init_IRQ(void) | |||
394 | 394 | ||
395 | /* INT#1: CFC Eject on PLD */ | 395 | /* INT#1: CFC Eject on PLD */ |
396 | irq_desc[PLD_IRQ_CFC_EJECT].status = IRQ_DISABLED; | 396 | irq_desc[PLD_IRQ_CFC_EJECT].status = IRQ_DISABLED; |
397 | irq_desc[PLD_IRQ_CFC_EJECT].handler = &opsput_pld_irq_type; | 397 | irq_desc[PLD_IRQ_CFC_EJECT].chip = &opsput_pld_irq_type; |
398 | irq_desc[PLD_IRQ_CFC_EJECT].action = 0; | 398 | irq_desc[PLD_IRQ_CFC_EJECT].action = 0; |
399 | irq_desc[PLD_IRQ_CFC_EJECT].depth = 1; /* disable nested irq */ | 399 | irq_desc[PLD_IRQ_CFC_EJECT].depth = 1; /* disable nested irq */ |
400 | pld_icu_data[irq2pldirq(PLD_IRQ_CFC_EJECT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02; /* 'H' edge sense */ | 400 | pld_icu_data[irq2pldirq(PLD_IRQ_CFC_EJECT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02; /* 'H' edge sense */ |
@@ -420,7 +420,7 @@ void __init init_IRQ(void) | |||
420 | outw(USBCR_OTGS, USBCR); /* USBCR: non-OTG */ | 420 | outw(USBCR_OTGS, USBCR); /* USBCR: non-OTG */ |
421 | 421 | ||
422 | irq_desc[OPSPUT_LCD_IRQ_USB_INT1].status = IRQ_DISABLED; | 422 | irq_desc[OPSPUT_LCD_IRQ_USB_INT1].status = IRQ_DISABLED; |
423 | irq_desc[OPSPUT_LCD_IRQ_USB_INT1].handler = &opsput_lcdpld_irq_type; | 423 | irq_desc[OPSPUT_LCD_IRQ_USB_INT1].chip = &opsput_lcdpld_irq_type; |
424 | irq_desc[OPSPUT_LCD_IRQ_USB_INT1].action = 0; | 424 | irq_desc[OPSPUT_LCD_IRQ_USB_INT1].action = 0; |
425 | irq_desc[OPSPUT_LCD_IRQ_USB_INT1].depth = 1; | 425 | irq_desc[OPSPUT_LCD_IRQ_USB_INT1].depth = 1; |
426 | lcdpld_icu_data[irq2lcdpldirq(OPSPUT_LCD_IRQ_USB_INT1)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01; /* "L" level sense */ | 426 | lcdpld_icu_data[irq2lcdpldirq(OPSPUT_LCD_IRQ_USB_INT1)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01; /* "L" level sense */ |
@@ -438,7 +438,7 @@ void __init init_IRQ(void) | |||
438 | * INT3# is used for AR | 438 | * INT3# is used for AR |
439 | */ | 439 | */ |
440 | irq_desc[M32R_IRQ_INT3].status = IRQ_DISABLED; | 440 | irq_desc[M32R_IRQ_INT3].status = IRQ_DISABLED; |
441 | irq_desc[M32R_IRQ_INT3].handler = &opsput_irq_type; | 441 | irq_desc[M32R_IRQ_INT3].chip = &opsput_irq_type; |
442 | irq_desc[M32R_IRQ_INT3].action = 0; | 442 | irq_desc[M32R_IRQ_INT3].action = 0; |
443 | irq_desc[M32R_IRQ_INT3].depth = 1; | 443 | irq_desc[M32R_IRQ_INT3].depth = 1; |
444 | icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; | 444 | icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; |
diff --git a/arch/m32r/kernel/setup_usrv.c b/arch/m32r/kernel/setup_usrv.c index 64be659a23e7..7fa12d8f66b4 100644 --- a/arch/m32r/kernel/setup_usrv.c +++ b/arch/m32r/kernel/setup_usrv.c | |||
@@ -158,7 +158,7 @@ void __init init_IRQ(void) | |||
158 | 158 | ||
159 | /* MFT2 : system timer */ | 159 | /* MFT2 : system timer */ |
160 | irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; | 160 | irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; |
161 | irq_desc[M32R_IRQ_MFT2].handler = &mappi_irq_type; | 161 | irq_desc[M32R_IRQ_MFT2].chip = &mappi_irq_type; |
162 | irq_desc[M32R_IRQ_MFT2].action = 0; | 162 | irq_desc[M32R_IRQ_MFT2].action = 0; |
163 | irq_desc[M32R_IRQ_MFT2].depth = 1; | 163 | irq_desc[M32R_IRQ_MFT2].depth = 1; |
164 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; | 164 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; |
@@ -167,7 +167,7 @@ void __init init_IRQ(void) | |||
167 | #if defined(CONFIG_SERIAL_M32R_SIO) | 167 | #if defined(CONFIG_SERIAL_M32R_SIO) |
168 | /* SIO0_R : uart receive data */ | 168 | /* SIO0_R : uart receive data */ |
169 | irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; | 169 | irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; |
170 | irq_desc[M32R_IRQ_SIO0_R].handler = &mappi_irq_type; | 170 | irq_desc[M32R_IRQ_SIO0_R].chip = &mappi_irq_type; |
171 | irq_desc[M32R_IRQ_SIO0_R].action = 0; | 171 | irq_desc[M32R_IRQ_SIO0_R].action = 0; |
172 | irq_desc[M32R_IRQ_SIO0_R].depth = 1; | 172 | irq_desc[M32R_IRQ_SIO0_R].depth = 1; |
173 | icu_data[M32R_IRQ_SIO0_R].icucr = 0; | 173 | icu_data[M32R_IRQ_SIO0_R].icucr = 0; |
@@ -175,7 +175,7 @@ void __init init_IRQ(void) | |||
175 | 175 | ||
176 | /* SIO0_S : uart send data */ | 176 | /* SIO0_S : uart send data */ |
177 | irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; | 177 | irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; |
178 | irq_desc[M32R_IRQ_SIO0_S].handler = &mappi_irq_type; | 178 | irq_desc[M32R_IRQ_SIO0_S].chip = &mappi_irq_type; |
179 | irq_desc[M32R_IRQ_SIO0_S].action = 0; | 179 | irq_desc[M32R_IRQ_SIO0_S].action = 0; |
180 | irq_desc[M32R_IRQ_SIO0_S].depth = 1; | 180 | irq_desc[M32R_IRQ_SIO0_S].depth = 1; |
181 | icu_data[M32R_IRQ_SIO0_S].icucr = 0; | 181 | icu_data[M32R_IRQ_SIO0_S].icucr = 0; |
@@ -183,7 +183,7 @@ void __init init_IRQ(void) | |||
183 | 183 | ||
184 | /* SIO1_R : uart receive data */ | 184 | /* SIO1_R : uart receive data */ |
185 | irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; | 185 | irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; |
186 | irq_desc[M32R_IRQ_SIO1_R].handler = &mappi_irq_type; | 186 | irq_desc[M32R_IRQ_SIO1_R].chip = &mappi_irq_type; |
187 | irq_desc[M32R_IRQ_SIO1_R].action = 0; | 187 | irq_desc[M32R_IRQ_SIO1_R].action = 0; |
188 | irq_desc[M32R_IRQ_SIO1_R].depth = 1; | 188 | irq_desc[M32R_IRQ_SIO1_R].depth = 1; |
189 | icu_data[M32R_IRQ_SIO1_R].icucr = 0; | 189 | icu_data[M32R_IRQ_SIO1_R].icucr = 0; |
@@ -191,7 +191,7 @@ void __init init_IRQ(void) | |||
191 | 191 | ||
192 | /* SIO1_S : uart send data */ | 192 | /* SIO1_S : uart send data */ |
193 | irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; | 193 | irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; |
194 | irq_desc[M32R_IRQ_SIO1_S].handler = &mappi_irq_type; | 194 | irq_desc[M32R_IRQ_SIO1_S].chip = &mappi_irq_type; |
195 | irq_desc[M32R_IRQ_SIO1_S].action = 0; | 195 | irq_desc[M32R_IRQ_SIO1_S].action = 0; |
196 | irq_desc[M32R_IRQ_SIO1_S].depth = 1; | 196 | irq_desc[M32R_IRQ_SIO1_S].depth = 1; |
197 | icu_data[M32R_IRQ_SIO1_S].icucr = 0; | 197 | icu_data[M32R_IRQ_SIO1_S].icucr = 0; |
@@ -201,7 +201,7 @@ void __init init_IRQ(void) | |||
201 | /* INT#67-#71: CFC#0 IREQ on PLD */ | 201 | /* INT#67-#71: CFC#0 IREQ on PLD */ |
202 | for (i = 0 ; i < CONFIG_CFC_NUM ; i++ ) { | 202 | for (i = 0 ; i < CONFIG_CFC_NUM ; i++ ) { |
203 | irq_desc[PLD_IRQ_CF0 + i].status = IRQ_DISABLED; | 203 | irq_desc[PLD_IRQ_CF0 + i].status = IRQ_DISABLED; |
204 | irq_desc[PLD_IRQ_CF0 + i].handler = &m32700ut_pld_irq_type; | 204 | irq_desc[PLD_IRQ_CF0 + i].chip = &m32700ut_pld_irq_type; |
205 | irq_desc[PLD_IRQ_CF0 + i].action = 0; | 205 | irq_desc[PLD_IRQ_CF0 + i].action = 0; |
206 | irq_desc[PLD_IRQ_CF0 + i].depth = 1; /* disable nested irq */ | 206 | irq_desc[PLD_IRQ_CF0 + i].depth = 1; /* disable nested irq */ |
207 | pld_icu_data[irq2pldirq(PLD_IRQ_CF0 + i)].icucr | 207 | pld_icu_data[irq2pldirq(PLD_IRQ_CF0 + i)].icucr |
@@ -212,7 +212,7 @@ void __init init_IRQ(void) | |||
212 | #if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) | 212 | #if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) |
213 | /* INT#76: 16552D#0 IREQ on PLD */ | 213 | /* INT#76: 16552D#0 IREQ on PLD */ |
214 | irq_desc[PLD_IRQ_UART0].status = IRQ_DISABLED; | 214 | irq_desc[PLD_IRQ_UART0].status = IRQ_DISABLED; |
215 | irq_desc[PLD_IRQ_UART0].handler = &m32700ut_pld_irq_type; | 215 | irq_desc[PLD_IRQ_UART0].chip = &m32700ut_pld_irq_type; |
216 | irq_desc[PLD_IRQ_UART0].action = 0; | 216 | irq_desc[PLD_IRQ_UART0].action = 0; |
217 | irq_desc[PLD_IRQ_UART0].depth = 1; /* disable nested irq */ | 217 | irq_desc[PLD_IRQ_UART0].depth = 1; /* disable nested irq */ |
218 | pld_icu_data[irq2pldirq(PLD_IRQ_UART0)].icucr | 218 | pld_icu_data[irq2pldirq(PLD_IRQ_UART0)].icucr |
@@ -221,7 +221,7 @@ void __init init_IRQ(void) | |||
221 | 221 | ||
222 | /* INT#77: 16552D#1 IREQ on PLD */ | 222 | /* INT#77: 16552D#1 IREQ on PLD */ |
223 | irq_desc[PLD_IRQ_UART1].status = IRQ_DISABLED; | 223 | irq_desc[PLD_IRQ_UART1].status = IRQ_DISABLED; |
224 | irq_desc[PLD_IRQ_UART1].handler = &m32700ut_pld_irq_type; | 224 | irq_desc[PLD_IRQ_UART1].chip = &m32700ut_pld_irq_type; |
225 | irq_desc[PLD_IRQ_UART1].action = 0; | 225 | irq_desc[PLD_IRQ_UART1].action = 0; |
226 | irq_desc[PLD_IRQ_UART1].depth = 1; /* disable nested irq */ | 226 | irq_desc[PLD_IRQ_UART1].depth = 1; /* disable nested irq */ |
227 | pld_icu_data[irq2pldirq(PLD_IRQ_UART1)].icucr | 227 | pld_icu_data[irq2pldirq(PLD_IRQ_UART1)].icucr |
@@ -232,7 +232,7 @@ void __init init_IRQ(void) | |||
232 | #if defined(CONFIG_IDC_AK4524) || defined(CONFIG_IDC_AK4524_MODULE) | 232 | #if defined(CONFIG_IDC_AK4524) || defined(CONFIG_IDC_AK4524_MODULE) |
233 | /* INT#80: AK4524 IREQ on PLD */ | 233 | /* INT#80: AK4524 IREQ on PLD */ |
234 | irq_desc[PLD_IRQ_SNDINT].status = IRQ_DISABLED; | 234 | irq_desc[PLD_IRQ_SNDINT].status = IRQ_DISABLED; |
235 | irq_desc[PLD_IRQ_SNDINT].handler = &m32700ut_pld_irq_type; | 235 | irq_desc[PLD_IRQ_SNDINT].chip = &m32700ut_pld_irq_type; |
236 | irq_desc[PLD_IRQ_SNDINT].action = 0; | 236 | irq_desc[PLD_IRQ_SNDINT].action = 0; |
237 | irq_desc[PLD_IRQ_SNDINT].depth = 1; /* disable nested irq */ | 237 | irq_desc[PLD_IRQ_SNDINT].depth = 1; /* disable nested irq */ |
238 | pld_icu_data[irq2pldirq(PLD_IRQ_SNDINT)].icucr | 238 | pld_icu_data[irq2pldirq(PLD_IRQ_SNDINT)].icucr |
diff --git a/arch/m68knommu/kernel/comempci.c b/arch/m68knommu/kernel/comempci.c index 8670938f1107..db7a0c1cebae 100644 --- a/arch/m68knommu/kernel/comempci.c +++ b/arch/m68knommu/kernel/comempci.c | |||
@@ -357,7 +357,8 @@ void pcibios_fixup_bus(struct pci_bus *b) | |||
357 | 357 | ||
358 | /*****************************************************************************/ | 358 | /*****************************************************************************/ |
359 | 359 | ||
360 | void pcibios_align_resource(void *data, struct resource *res, unsigned long size, unsigned long align) | 360 | void pcibios_align_resource(void *data, struct resource *res, |
361 | resource_size_t size, resource_size_t align) | ||
361 | { | 362 | { |
362 | } | 363 | } |
363 | 364 | ||
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 8e10f027e561..747a9c1228f2 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -1647,6 +1647,11 @@ config GENERIC_IRQ_PROBE | |||
1647 | bool | 1647 | bool |
1648 | default y | 1648 | default y |
1649 | 1649 | ||
1650 | config IRQ_PER_CPU | ||
1651 | depends on SMP | ||
1652 | bool | ||
1653 | default y | ||
1654 | |||
1650 | # | 1655 | # |
1651 | # - Highmem only makes sense for the 32-bit kernel. | 1656 | # - Highmem only makes sense for the 32-bit kernel. |
1652 | # - The current highmem code will only work properly on physically indexed | 1657 | # - The current highmem code will only work properly on physically indexed |
diff --git a/arch/mips/au1000/common/irq.c b/arch/mips/au1000/common/irq.c index ab444c717404..12d6edee895e 100644 --- a/arch/mips/au1000/common/irq.c +++ b/arch/mips/au1000/common/irq.c | |||
@@ -333,31 +333,31 @@ static void setup_local_irq(unsigned int irq_nr, int type, int int_req) | |||
333 | au_writel(1<<(irq_nr-32), IC1_CFG2CLR); | 333 | au_writel(1<<(irq_nr-32), IC1_CFG2CLR); |
334 | au_writel(1<<(irq_nr-32), IC1_CFG1CLR); | 334 | au_writel(1<<(irq_nr-32), IC1_CFG1CLR); |
335 | au_writel(1<<(irq_nr-32), IC1_CFG0SET); | 335 | au_writel(1<<(irq_nr-32), IC1_CFG0SET); |
336 | irq_desc[irq_nr].handler = &rise_edge_irq_type; | 336 | irq_desc[irq_nr].chip = &rise_edge_irq_type; |
337 | break; | 337 | break; |
338 | case INTC_INT_FALL_EDGE: /* 0:1:0 */ | 338 | case INTC_INT_FALL_EDGE: /* 0:1:0 */ |
339 | au_writel(1<<(irq_nr-32), IC1_CFG2CLR); | 339 | au_writel(1<<(irq_nr-32), IC1_CFG2CLR); |
340 | au_writel(1<<(irq_nr-32), IC1_CFG1SET); | 340 | au_writel(1<<(irq_nr-32), IC1_CFG1SET); |
341 | au_writel(1<<(irq_nr-32), IC1_CFG0CLR); | 341 | au_writel(1<<(irq_nr-32), IC1_CFG0CLR); |
342 | irq_desc[irq_nr].handler = &fall_edge_irq_type; | 342 | irq_desc[irq_nr].chip = &fall_edge_irq_type; |
343 | break; | 343 | break; |
344 | case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */ | 344 | case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */ |
345 | au_writel(1<<(irq_nr-32), IC1_CFG2CLR); | 345 | au_writel(1<<(irq_nr-32), IC1_CFG2CLR); |
346 | au_writel(1<<(irq_nr-32), IC1_CFG1SET); | 346 | au_writel(1<<(irq_nr-32), IC1_CFG1SET); |
347 | au_writel(1<<(irq_nr-32), IC1_CFG0SET); | 347 | au_writel(1<<(irq_nr-32), IC1_CFG0SET); |
348 | irq_desc[irq_nr].handler = &either_edge_irq_type; | 348 | irq_desc[irq_nr].chip = &either_edge_irq_type; |
349 | break; | 349 | break; |
350 | case INTC_INT_HIGH_LEVEL: /* 1:0:1 */ | 350 | case INTC_INT_HIGH_LEVEL: /* 1:0:1 */ |
351 | au_writel(1<<(irq_nr-32), IC1_CFG2SET); | 351 | au_writel(1<<(irq_nr-32), IC1_CFG2SET); |
352 | au_writel(1<<(irq_nr-32), IC1_CFG1CLR); | 352 | au_writel(1<<(irq_nr-32), IC1_CFG1CLR); |
353 | au_writel(1<<(irq_nr-32), IC1_CFG0SET); | 353 | au_writel(1<<(irq_nr-32), IC1_CFG0SET); |
354 | irq_desc[irq_nr].handler = &level_irq_type; | 354 | irq_desc[irq_nr].chip = &level_irq_type; |
355 | break; | 355 | break; |
356 | case INTC_INT_LOW_LEVEL: /* 1:1:0 */ | 356 | case INTC_INT_LOW_LEVEL: /* 1:1:0 */ |
357 | au_writel(1<<(irq_nr-32), IC1_CFG2SET); | 357 | au_writel(1<<(irq_nr-32), IC1_CFG2SET); |
358 | au_writel(1<<(irq_nr-32), IC1_CFG1SET); | 358 | au_writel(1<<(irq_nr-32), IC1_CFG1SET); |
359 | au_writel(1<<(irq_nr-32), IC1_CFG0CLR); | 359 | au_writel(1<<(irq_nr-32), IC1_CFG0CLR); |
360 | irq_desc[irq_nr].handler = &level_irq_type; | 360 | irq_desc[irq_nr].chip = &level_irq_type; |
361 | break; | 361 | break; |
362 | case INTC_INT_DISABLED: /* 0:0:0 */ | 362 | case INTC_INT_DISABLED: /* 0:0:0 */ |
363 | au_writel(1<<(irq_nr-32), IC1_CFG0CLR); | 363 | au_writel(1<<(irq_nr-32), IC1_CFG0CLR); |
@@ -385,31 +385,31 @@ static void setup_local_irq(unsigned int irq_nr, int type, int int_req) | |||
385 | au_writel(1<<irq_nr, IC0_CFG2CLR); | 385 | au_writel(1<<irq_nr, IC0_CFG2CLR); |
386 | au_writel(1<<irq_nr, IC0_CFG1CLR); | 386 | au_writel(1<<irq_nr, IC0_CFG1CLR); |
387 | au_writel(1<<irq_nr, IC0_CFG0SET); | 387 | au_writel(1<<irq_nr, IC0_CFG0SET); |
388 | irq_desc[irq_nr].handler = &rise_edge_irq_type; | 388 | irq_desc[irq_nr].chip = &rise_edge_irq_type; |
389 | break; | 389 | break; |
390 | case INTC_INT_FALL_EDGE: /* 0:1:0 */ | 390 | case INTC_INT_FALL_EDGE: /* 0:1:0 */ |
391 | au_writel(1<<irq_nr, IC0_CFG2CLR); | 391 | au_writel(1<<irq_nr, IC0_CFG2CLR); |
392 | au_writel(1<<irq_nr, IC0_CFG1SET); | 392 | au_writel(1<<irq_nr, IC0_CFG1SET); |
393 | au_writel(1<<irq_nr, IC0_CFG0CLR); | 393 | au_writel(1<<irq_nr, IC0_CFG0CLR); |
394 | irq_desc[irq_nr].handler = &fall_edge_irq_type; | 394 | irq_desc[irq_nr].chip = &fall_edge_irq_type; |
395 | break; | 395 | break; |
396 | case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */ | 396 | case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */ |
397 | au_writel(1<<irq_nr, IC0_CFG2CLR); | 397 | au_writel(1<<irq_nr, IC0_CFG2CLR); |
398 | au_writel(1<<irq_nr, IC0_CFG1SET); | 398 | au_writel(1<<irq_nr, IC0_CFG1SET); |
399 | au_writel(1<<irq_nr, IC0_CFG0SET); | 399 | au_writel(1<<irq_nr, IC0_CFG0SET); |
400 | irq_desc[irq_nr].handler = &either_edge_irq_type; | 400 | irq_desc[irq_nr].chip = &either_edge_irq_type; |
401 | break; | 401 | break; |
402 | case INTC_INT_HIGH_LEVEL: /* 1:0:1 */ | 402 | case INTC_INT_HIGH_LEVEL: /* 1:0:1 */ |
403 | au_writel(1<<irq_nr, IC0_CFG2SET); | 403 | au_writel(1<<irq_nr, IC0_CFG2SET); |
404 | au_writel(1<<irq_nr, IC0_CFG1CLR); | 404 | au_writel(1<<irq_nr, IC0_CFG1CLR); |
405 | au_writel(1<<irq_nr, IC0_CFG0SET); | 405 | au_writel(1<<irq_nr, IC0_CFG0SET); |
406 | irq_desc[irq_nr].handler = &level_irq_type; | 406 | irq_desc[irq_nr].chip = &level_irq_type; |
407 | break; | 407 | break; |
408 | case INTC_INT_LOW_LEVEL: /* 1:1:0 */ | 408 | case INTC_INT_LOW_LEVEL: /* 1:1:0 */ |
409 | au_writel(1<<irq_nr, IC0_CFG2SET); | 409 | au_writel(1<<irq_nr, IC0_CFG2SET); |
410 | au_writel(1<<irq_nr, IC0_CFG1SET); | 410 | au_writel(1<<irq_nr, IC0_CFG1SET); |
411 | au_writel(1<<irq_nr, IC0_CFG0CLR); | 411 | au_writel(1<<irq_nr, IC0_CFG0CLR); |
412 | irq_desc[irq_nr].handler = &level_irq_type; | 412 | irq_desc[irq_nr].chip = &level_irq_type; |
413 | break; | 413 | break; |
414 | case INTC_INT_DISABLED: /* 0:0:0 */ | 414 | case INTC_INT_DISABLED: /* 0:0:0 */ |
415 | au_writel(1<<irq_nr, IC0_CFG0CLR); | 415 | au_writel(1<<irq_nr, IC0_CFG0CLR); |
diff --git a/arch/mips/au1000/pb1200/irqmap.c b/arch/mips/au1000/pb1200/irqmap.c index bacc0c6bfe67..5dd164fc1889 100644 --- a/arch/mips/au1000/pb1200/irqmap.c +++ b/arch/mips/au1000/pb1200/irqmap.c | |||
@@ -172,7 +172,7 @@ void _board_init_irq(void) | |||
172 | 172 | ||
173 | for (irq_nr = PB1200_INT_BEGIN; irq_nr <= PB1200_INT_END; irq_nr++) | 173 | for (irq_nr = PB1200_INT_BEGIN; irq_nr <= PB1200_INT_END; irq_nr++) |
174 | { | 174 | { |
175 | irq_desc[irq_nr].handler = &external_irq_type; | 175 | irq_desc[irq_nr].chip = &external_irq_type; |
176 | pb1200_disable_irq(irq_nr); | 176 | pb1200_disable_irq(irq_nr); |
177 | } | 177 | } |
178 | 178 | ||
diff --git a/arch/mips/ddb5xxx/ddb5477/irq_5477.c b/arch/mips/ddb5xxx/ddb5477/irq_5477.c index 5fcd5f070cdc..63c3d6534b3a 100644 --- a/arch/mips/ddb5xxx/ddb5477/irq_5477.c +++ b/arch/mips/ddb5xxx/ddb5477/irq_5477.c | |||
@@ -107,7 +107,7 @@ void __init vrc5477_irq_init(u32 irq_base) | |||
107 | irq_desc[i].status = IRQ_DISABLED; | 107 | irq_desc[i].status = IRQ_DISABLED; |
108 | irq_desc[i].action = NULL; | 108 | irq_desc[i].action = NULL; |
109 | irq_desc[i].depth = 1; | 109 | irq_desc[i].depth = 1; |
110 | irq_desc[i].handler = &vrc5477_irq_controller; | 110 | irq_desc[i].chip = &vrc5477_irq_controller; |
111 | } | 111 | } |
112 | 112 | ||
113 | vrc5477_irq_base = irq_base; | 113 | vrc5477_irq_base = irq_base; |
diff --git a/arch/mips/dec/ioasic-irq.c b/arch/mips/dec/ioasic-irq.c index d5bca5d233b6..da2dbb42f913 100644 --- a/arch/mips/dec/ioasic-irq.c +++ b/arch/mips/dec/ioasic-irq.c | |||
@@ -144,13 +144,13 @@ void __init init_ioasic_irqs(int base) | |||
144 | irq_desc[i].status = IRQ_DISABLED; | 144 | irq_desc[i].status = IRQ_DISABLED; |
145 | irq_desc[i].action = 0; | 145 | irq_desc[i].action = 0; |
146 | irq_desc[i].depth = 1; | 146 | irq_desc[i].depth = 1; |
147 | irq_desc[i].handler = &ioasic_irq_type; | 147 | irq_desc[i].chip = &ioasic_irq_type; |
148 | } | 148 | } |
149 | for (; i < base + IO_IRQ_LINES; i++) { | 149 | for (; i < base + IO_IRQ_LINES; i++) { |
150 | irq_desc[i].status = IRQ_DISABLED; | 150 | irq_desc[i].status = IRQ_DISABLED; |
151 | irq_desc[i].action = 0; | 151 | irq_desc[i].action = 0; |
152 | irq_desc[i].depth = 1; | 152 | irq_desc[i].depth = 1; |
153 | irq_desc[i].handler = &ioasic_dma_irq_type; | 153 | irq_desc[i].chip = &ioasic_dma_irq_type; |
154 | } | 154 | } |
155 | 155 | ||
156 | ioasic_irq_base = base; | 156 | ioasic_irq_base = base; |
diff --git a/arch/mips/dec/kn02-irq.c b/arch/mips/dec/kn02-irq.c index 898bed502a34..d44c00d9e80f 100644 --- a/arch/mips/dec/kn02-irq.c +++ b/arch/mips/dec/kn02-irq.c | |||
@@ -123,7 +123,7 @@ void __init init_kn02_irqs(int base) | |||
123 | irq_desc[i].status = IRQ_DISABLED; | 123 | irq_desc[i].status = IRQ_DISABLED; |
124 | irq_desc[i].action = 0; | 124 | irq_desc[i].action = 0; |
125 | irq_desc[i].depth = 1; | 125 | irq_desc[i].depth = 1; |
126 | irq_desc[i].handler = &kn02_irq_type; | 126 | irq_desc[i].chip = &kn02_irq_type; |
127 | } | 127 | } |
128 | 128 | ||
129 | kn02_irq_base = base; | 129 | kn02_irq_base = base; |
diff --git a/arch/mips/gt64120/ev64120/irq.c b/arch/mips/gt64120/ev64120/irq.c index 46c468b26b30..f489a8067a93 100644 --- a/arch/mips/gt64120/ev64120/irq.c +++ b/arch/mips/gt64120/ev64120/irq.c | |||
@@ -138,7 +138,7 @@ void __init arch_init_irq(void) | |||
138 | /* Let's initialize our IRQ descriptors */ | 138 | /* Let's initialize our IRQ descriptors */ |
139 | for (i = 0; i < NR_IRQS; i++) { | 139 | for (i = 0; i < NR_IRQS; i++) { |
140 | irq_desc[i].status = 0; | 140 | irq_desc[i].status = 0; |
141 | irq_desc[i].handler = &no_irq_type; | 141 | irq_desc[i].chip = &no_irq_type; |
142 | irq_desc[i].action = NULL; | 142 | irq_desc[i].action = NULL; |
143 | irq_desc[i].depth = 0; | 143 | irq_desc[i].depth = 0; |
144 | spin_lock_init(&irq_desc[i].lock); | 144 | spin_lock_init(&irq_desc[i].lock); |
diff --git a/arch/mips/ite-boards/generic/irq.c b/arch/mips/ite-boards/generic/irq.c index 77be7216bdd0..a6749c56fe38 100644 --- a/arch/mips/ite-boards/generic/irq.c +++ b/arch/mips/ite-boards/generic/irq.c | |||
@@ -208,10 +208,10 @@ void __init arch_init_irq(void) | |||
208 | #endif | 208 | #endif |
209 | 209 | ||
210 | for (i = 0; i <= IT8172_LAST_IRQ; i++) { | 210 | for (i = 0; i <= IT8172_LAST_IRQ; i++) { |
211 | irq_desc[i].handler = &it8172_irq_type; | 211 | irq_desc[i].chip = &it8172_irq_type; |
212 | spin_lock_init(&irq_desc[i].lock); | 212 | spin_lock_init(&irq_desc[i].lock); |
213 | } | 213 | } |
214 | irq_desc[MIPS_CPU_TIMER_IRQ].handler = &cp0_irq_type; | 214 | irq_desc[MIPS_CPU_TIMER_IRQ].chip = &cp0_irq_type; |
215 | set_c0_status(ALLINTS_NOTIMER); | 215 | set_c0_status(ALLINTS_NOTIMER); |
216 | } | 216 | } |
217 | 217 | ||
diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c index becc9accd495..478be9858a1e 100644 --- a/arch/mips/jazz/irq.c +++ b/arch/mips/jazz/irq.c | |||
@@ -73,7 +73,7 @@ void __init init_r4030_ints(void) | |||
73 | irq_desc[i].status = IRQ_DISABLED; | 73 | irq_desc[i].status = IRQ_DISABLED; |
74 | irq_desc[i].action = 0; | 74 | irq_desc[i].action = 0; |
75 | irq_desc[i].depth = 1; | 75 | irq_desc[i].depth = 1; |
76 | irq_desc[i].handler = &r4030_irq_type; | 76 | irq_desc[i].chip = &r4030_irq_type; |
77 | } | 77 | } |
78 | 78 | ||
79 | r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, 0); | 79 | r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, 0); |
diff --git a/arch/mips/jmr3927/rbhma3100/irq.c b/arch/mips/jmr3927/rbhma3100/irq.c index 11304d1354f4..380046ea1db5 100644 --- a/arch/mips/jmr3927/rbhma3100/irq.c +++ b/arch/mips/jmr3927/rbhma3100/irq.c | |||
@@ -435,7 +435,7 @@ void jmr3927_irq_init(u32 irq_base) | |||
435 | irq_desc[i].status = IRQ_DISABLED; | 435 | irq_desc[i].status = IRQ_DISABLED; |
436 | irq_desc[i].action = NULL; | 436 | irq_desc[i].action = NULL; |
437 | irq_desc[i].depth = 1; | 437 | irq_desc[i].depth = 1; |
438 | irq_desc[i].handler = &jmr3927_irq_controller; | 438 | irq_desc[i].chip = &jmr3927_irq_controller; |
439 | } | 439 | } |
440 | 440 | ||
441 | jmr3927_irq_base = irq_base; | 441 | jmr3927_irq_base = irq_base; |
diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c index 0cb8ed5662f3..91ffb1233cad 100644 --- a/arch/mips/kernel/i8259.c +++ b/arch/mips/kernel/i8259.c | |||
@@ -120,7 +120,7 @@ int i8259A_irq_pending(unsigned int irq) | |||
120 | void make_8259A_irq(unsigned int irq) | 120 | void make_8259A_irq(unsigned int irq) |
121 | { | 121 | { |
122 | disable_irq_nosync(irq); | 122 | disable_irq_nosync(irq); |
123 | irq_desc[irq].handler = &i8259A_irq_type; | 123 | irq_desc[irq].chip = &i8259A_irq_type; |
124 | enable_irq(irq); | 124 | enable_irq(irq); |
125 | } | 125 | } |
126 | 126 | ||
@@ -327,7 +327,7 @@ void __init init_i8259_irqs (void) | |||
327 | irq_desc[i].status = IRQ_DISABLED; | 327 | irq_desc[i].status = IRQ_DISABLED; |
328 | irq_desc[i].action = NULL; | 328 | irq_desc[i].action = NULL; |
329 | irq_desc[i].depth = 1; | 329 | irq_desc[i].depth = 1; |
330 | irq_desc[i].handler = &i8259A_irq_type; | 330 | irq_desc[i].chip = &i8259A_irq_type; |
331 | } | 331 | } |
332 | 332 | ||
333 | setup_irq(2, &irq2); | 333 | setup_irq(2, &irq2); |
diff --git a/arch/mips/kernel/irq-msc01.c b/arch/mips/kernel/irq-msc01.c index 97ebdc754b9e..f8cd1ac64d88 100644 --- a/arch/mips/kernel/irq-msc01.c +++ b/arch/mips/kernel/irq-msc01.c | |||
@@ -174,14 +174,14 @@ void __init init_msc_irqs(unsigned int base, msc_irqmap_t *imp, int nirq) | |||
174 | 174 | ||
175 | switch (imp->im_type) { | 175 | switch (imp->im_type) { |
176 | case MSC01_IRQ_EDGE: | 176 | case MSC01_IRQ_EDGE: |
177 | irq_desc[base+n].handler = &msc_edgeirq_type; | 177 | irq_desc[base+n].chip = &msc_edgeirq_type; |
178 | if (cpu_has_veic) | 178 | if (cpu_has_veic) |
179 | MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT); | 179 | MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT); |
180 | else | 180 | else |
181 | MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT | imp->im_lvl); | 181 | MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT | imp->im_lvl); |
182 | break; | 182 | break; |
183 | case MSC01_IRQ_LEVEL: | 183 | case MSC01_IRQ_LEVEL: |
184 | irq_desc[base+n].handler = &msc_levelirq_type; | 184 | irq_desc[base+n].chip = &msc_levelirq_type; |
185 | if (cpu_has_veic) | 185 | if (cpu_has_veic) |
186 | MSCIC_WRITE(MSC01_IC_SUP+n*8, 0); | 186 | MSCIC_WRITE(MSC01_IC_SUP+n*8, 0); |
187 | else | 187 | else |
diff --git a/arch/mips/kernel/irq-mv6434x.c b/arch/mips/kernel/irq-mv6434x.c index 0613f1f36b1b..f9c763a65547 100644 --- a/arch/mips/kernel/irq-mv6434x.c +++ b/arch/mips/kernel/irq-mv6434x.c | |||
@@ -155,7 +155,7 @@ void __init mv64340_irq_init(unsigned int base) | |||
155 | irq_desc[i].status = IRQ_DISABLED; | 155 | irq_desc[i].status = IRQ_DISABLED; |
156 | irq_desc[i].action = 0; | 156 | irq_desc[i].action = 0; |
157 | irq_desc[i].depth = 2; | 157 | irq_desc[i].depth = 2; |
158 | irq_desc[i].handler = &mv64340_irq_type; | 158 | irq_desc[i].chip = &mv64340_irq_type; |
159 | } | 159 | } |
160 | 160 | ||
161 | irq_base = base; | 161 | irq_base = base; |
diff --git a/arch/mips/kernel/irq-rm7000.c b/arch/mips/kernel/irq-rm7000.c index 0b130c5ac5d9..121da385a94d 100644 --- a/arch/mips/kernel/irq-rm7000.c +++ b/arch/mips/kernel/irq-rm7000.c | |||
@@ -91,7 +91,7 @@ void __init rm7k_cpu_irq_init(int base) | |||
91 | irq_desc[i].status = IRQ_DISABLED; | 91 | irq_desc[i].status = IRQ_DISABLED; |
92 | irq_desc[i].action = NULL; | 92 | irq_desc[i].action = NULL; |
93 | irq_desc[i].depth = 1; | 93 | irq_desc[i].depth = 1; |
94 | irq_desc[i].handler = &rm7k_irq_controller; | 94 | irq_desc[i].chip = &rm7k_irq_controller; |
95 | } | 95 | } |
96 | 96 | ||
97 | irq_base = base; | 97 | irq_base = base; |
diff --git a/arch/mips/kernel/irq-rm9000.c b/arch/mips/kernel/irq-rm9000.c index 9b5f20c32acb..25109c103e44 100644 --- a/arch/mips/kernel/irq-rm9000.c +++ b/arch/mips/kernel/irq-rm9000.c | |||
@@ -139,11 +139,11 @@ void __init rm9k_cpu_irq_init(int base) | |||
139 | irq_desc[i].status = IRQ_DISABLED; | 139 | irq_desc[i].status = IRQ_DISABLED; |
140 | irq_desc[i].action = NULL; | 140 | irq_desc[i].action = NULL; |
141 | irq_desc[i].depth = 1; | 141 | irq_desc[i].depth = 1; |
142 | irq_desc[i].handler = &rm9k_irq_controller; | 142 | irq_desc[i].chip = &rm9k_irq_controller; |
143 | } | 143 | } |
144 | 144 | ||
145 | rm9000_perfcount_irq = base + 1; | 145 | rm9000_perfcount_irq = base + 1; |
146 | irq_desc[rm9000_perfcount_irq].handler = &rm9k_perfcounter_irq; | 146 | irq_desc[rm9000_perfcount_irq].chip = &rm9k_perfcounter_irq; |
147 | 147 | ||
148 | irq_base = base; | 148 | irq_base = base; |
149 | } | 149 | } |
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index 3dce742e716f..5c9dcd5eed59 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c | |||
@@ -95,7 +95,7 @@ int show_interrupts(struct seq_file *p, void *v) | |||
95 | for_each_online_cpu(j) | 95 | for_each_online_cpu(j) |
96 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); | 96 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); |
97 | #endif | 97 | #endif |
98 | seq_printf(p, " %14s", irq_desc[i].handler->typename); | 98 | seq_printf(p, " %14s", irq_desc[i].chip->typename); |
99 | seq_printf(p, " %s", action->name); | 99 | seq_printf(p, " %s", action->name); |
100 | 100 | ||
101 | for (action=action->next; action; action = action->next) | 101 | for (action=action->next; action; action = action->next) |
@@ -137,7 +137,7 @@ void __init init_IRQ(void) | |||
137 | irq_desc[i].status = IRQ_DISABLED; | 137 | irq_desc[i].status = IRQ_DISABLED; |
138 | irq_desc[i].action = NULL; | 138 | irq_desc[i].action = NULL; |
139 | irq_desc[i].depth = 1; | 139 | irq_desc[i].depth = 1; |
140 | irq_desc[i].handler = &no_irq_type; | 140 | irq_desc[i].chip = &no_irq_type; |
141 | spin_lock_init(&irq_desc[i].lock); | 141 | spin_lock_init(&irq_desc[i].lock); |
142 | #ifdef CONFIG_MIPS_MT_SMTC | 142 | #ifdef CONFIG_MIPS_MT_SMTC |
143 | irq_hwmask[i] = 0; | 143 | irq_hwmask[i] = 0; |
diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c index 5db67e31ec1a..0e455a8ad860 100644 --- a/arch/mips/kernel/irq_cpu.c +++ b/arch/mips/kernel/irq_cpu.c | |||
@@ -167,14 +167,14 @@ void __init mips_cpu_irq_init(int irq_base) | |||
167 | irq_desc[i].status = IRQ_DISABLED; | 167 | irq_desc[i].status = IRQ_DISABLED; |
168 | irq_desc[i].action = NULL; | 168 | irq_desc[i].action = NULL; |
169 | irq_desc[i].depth = 1; | 169 | irq_desc[i].depth = 1; |
170 | irq_desc[i].handler = &mips_mt_cpu_irq_controller; | 170 | irq_desc[i].chip = &mips_mt_cpu_irq_controller; |
171 | } | 171 | } |
172 | 172 | ||
173 | for (i = irq_base + 2; i < irq_base + 8; i++) { | 173 | for (i = irq_base + 2; i < irq_base + 8; i++) { |
174 | irq_desc[i].status = IRQ_DISABLED; | 174 | irq_desc[i].status = IRQ_DISABLED; |
175 | irq_desc[i].action = NULL; | 175 | irq_desc[i].action = NULL; |
176 | irq_desc[i].depth = 1; | 176 | irq_desc[i].depth = 1; |
177 | irq_desc[i].handler = &mips_cpu_irq_controller; | 177 | irq_desc[i].chip = &mips_cpu_irq_controller; |
178 | } | 178 | } |
179 | 179 | ||
180 | mips_cpu_irq_base = irq_base; | 180 | mips_cpu_irq_base = irq_base; |
diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c index 2d3472b21ebb..9316a024a818 100644 --- a/arch/mips/lasat/interrupt.c +++ b/arch/mips/lasat/interrupt.c | |||
@@ -156,6 +156,6 @@ void __init arch_init_irq(void) | |||
156 | irq_desc[i].status = IRQ_DISABLED; | 156 | irq_desc[i].status = IRQ_DISABLED; |
157 | irq_desc[i].action = 0; | 157 | irq_desc[i].action = 0; |
158 | irq_desc[i].depth = 1; | 158 | irq_desc[i].depth = 1; |
159 | irq_desc[i].handler = &lasat_irq_type; | 159 | irq_desc[i].chip = &lasat_irq_type; |
160 | } | 160 | } |
161 | } | 161 | } |
diff --git a/arch/mips/mips-boards/atlas/atlas_int.c b/arch/mips/mips-boards/atlas/atlas_int.c index db53950b7cfb..9dd6b8925581 100644 --- a/arch/mips/mips-boards/atlas/atlas_int.c +++ b/arch/mips/mips-boards/atlas/atlas_int.c | |||
@@ -215,7 +215,7 @@ void __init arch_init_irq(void) | |||
215 | irq_desc[i].status = IRQ_DISABLED; | 215 | irq_desc[i].status = IRQ_DISABLED; |
216 | irq_desc[i].action = 0; | 216 | irq_desc[i].action = 0; |
217 | irq_desc[i].depth = 1; | 217 | irq_desc[i].depth = 1; |
218 | irq_desc[i].handler = &atlas_irq_type; | 218 | irq_desc[i].chip = &atlas_irq_type; |
219 | spin_lock_init(&irq_desc[i].lock); | 219 | spin_lock_init(&irq_desc[i].lock); |
220 | } | 220 | } |
221 | } | 221 | } |
diff --git a/arch/mips/momentum/ocelot_c/cpci-irq.c b/arch/mips/momentum/ocelot_c/cpci-irq.c index bd885785e2f9..31d179c4673f 100644 --- a/arch/mips/momentum/ocelot_c/cpci-irq.c +++ b/arch/mips/momentum/ocelot_c/cpci-irq.c | |||
@@ -147,6 +147,6 @@ void cpci_irq_init(void) | |||
147 | irq_desc[i].status = IRQ_DISABLED; | 147 | irq_desc[i].status = IRQ_DISABLED; |
148 | irq_desc[i].action = 0; | 148 | irq_desc[i].action = 0; |
149 | irq_desc[i].depth = 2; | 149 | irq_desc[i].depth = 2; |
150 | irq_desc[i].handler = &cpci_irq_type; | 150 | irq_desc[i].chip = &cpci_irq_type; |
151 | } | 151 | } |
152 | } | 152 | } |
diff --git a/arch/mips/momentum/ocelot_c/uart-irq.c b/arch/mips/momentum/ocelot_c/uart-irq.c index 755bde5146be..852265026fd1 100644 --- a/arch/mips/momentum/ocelot_c/uart-irq.c +++ b/arch/mips/momentum/ocelot_c/uart-irq.c | |||
@@ -137,10 +137,10 @@ void uart_irq_init(void) | |||
137 | irq_desc[80].status = IRQ_DISABLED; | 137 | irq_desc[80].status = IRQ_DISABLED; |
138 | irq_desc[80].action = 0; | 138 | irq_desc[80].action = 0; |
139 | irq_desc[80].depth = 2; | 139 | irq_desc[80].depth = 2; |
140 | irq_desc[80].handler = &uart_irq_type; | 140 | irq_desc[80].chip = &uart_irq_type; |
141 | 141 | ||
142 | irq_desc[81].status = IRQ_DISABLED; | 142 | irq_desc[81].status = IRQ_DISABLED; |
143 | irq_desc[81].action = 0; | 143 | irq_desc[81].action = 0; |
144 | irq_desc[81].depth = 2; | 144 | irq_desc[81].depth = 2; |
145 | irq_desc[81].handler = &uart_irq_type; | 145 | irq_desc[81].chip = &uart_irq_type; |
146 | } | 146 | } |
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index 4dfce154d4af..ba66f8c9bd4e 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c | |||
@@ -51,11 +51,11 @@ unsigned long PCIBIOS_MIN_MEM = 0; | |||
51 | */ | 51 | */ |
52 | void | 52 | void |
53 | pcibios_align_resource(void *data, struct resource *res, | 53 | pcibios_align_resource(void *data, struct resource *res, |
54 | unsigned long size, unsigned long align) | 54 | resource_size_t size, resource_size_t align) |
55 | { | 55 | { |
56 | struct pci_dev *dev = data; | 56 | struct pci_dev *dev = data; |
57 | struct pci_controller *hose = dev->sysdata; | 57 | struct pci_controller *hose = dev->sysdata; |
58 | unsigned long start = res->start; | 58 | resource_size_t start = res->start; |
59 | 59 | ||
60 | if (res->flags & IORESOURCE_IO) { | 60 | if (res->flags & IORESOURCE_IO) { |
61 | /* Make sure we start at our min on all hoses */ | 61 | /* Make sure we start at our min on all hoses */ |
diff --git a/arch/mips/philips/pnx8550/common/int.c b/arch/mips/philips/pnx8550/common/int.c index 39ee6314f627..8f18764a2359 100644 --- a/arch/mips/philips/pnx8550/common/int.c +++ b/arch/mips/philips/pnx8550/common/int.c | |||
@@ -236,7 +236,7 @@ void __init arch_init_irq(void) | |||
236 | int configPR; | 236 | int configPR; |
237 | 237 | ||
238 | for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) { | 238 | for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) { |
239 | irq_desc[i].handler = &level_irq_type; | 239 | irq_desc[i].chip = &level_irq_type; |
240 | pnx8550_ack(i); /* mask the irq just in case */ | 240 | pnx8550_ack(i); /* mask the irq just in case */ |
241 | } | 241 | } |
242 | 242 | ||
@@ -273,7 +273,7 @@ void __init arch_init_irq(void) | |||
273 | /* mask/priority is still 0 so we will not get any | 273 | /* mask/priority is still 0 so we will not get any |
274 | * interrupts until it is unmasked */ | 274 | * interrupts until it is unmasked */ |
275 | 275 | ||
276 | irq_desc[i].handler = &level_irq_type; | 276 | irq_desc[i].chip = &level_irq_type; |
277 | } | 277 | } |
278 | 278 | ||
279 | /* Priority level 0 */ | 279 | /* Priority level 0 */ |
@@ -282,12 +282,12 @@ void __init arch_init_irq(void) | |||
282 | /* Set int vector table address */ | 282 | /* Set int vector table address */ |
283 | PNX8550_GIC_VECTOR_0 = PNX8550_GIC_VECTOR_1 = 0; | 283 | PNX8550_GIC_VECTOR_0 = PNX8550_GIC_VECTOR_1 = 0; |
284 | 284 | ||
285 | irq_desc[MIPS_CPU_GIC_IRQ].handler = &level_irq_type; | 285 | irq_desc[MIPS_CPU_GIC_IRQ].chip = &level_irq_type; |
286 | setup_irq(MIPS_CPU_GIC_IRQ, &gic_action); | 286 | setup_irq(MIPS_CPU_GIC_IRQ, &gic_action); |
287 | 287 | ||
288 | /* init of Timer interrupts */ | 288 | /* init of Timer interrupts */ |
289 | for (i = PNX8550_INT_TIMER_MIN; i <= PNX8550_INT_TIMER_MAX; i++) { | 289 | for (i = PNX8550_INT_TIMER_MIN; i <= PNX8550_INT_TIMER_MAX; i++) { |
290 | irq_desc[i].handler = &level_irq_type; | 290 | irq_desc[i].chip = &level_irq_type; |
291 | } | 291 | } |
292 | 292 | ||
293 | /* Stop Timer 1-3 */ | 293 | /* Stop Timer 1-3 */ |
@@ -295,7 +295,7 @@ void __init arch_init_irq(void) | |||
295 | configPR |= 0x00000038; | 295 | configPR |= 0x00000038; |
296 | write_c0_config7(configPR); | 296 | write_c0_config7(configPR); |
297 | 297 | ||
298 | irq_desc[MIPS_CPU_TIMER_IRQ].handler = &level_irq_type; | 298 | irq_desc[MIPS_CPU_TIMER_IRQ].chip = &level_irq_type; |
299 | setup_irq(MIPS_CPU_TIMER_IRQ, &timer_action); | 299 | setup_irq(MIPS_CPU_TIMER_IRQ, &timer_action); |
300 | } | 300 | } |
301 | 301 | ||
diff --git a/arch/mips/pmc-sierra/yosemite/ht.c b/arch/mips/pmc-sierra/yosemite/ht.c index 54b65a80abf5..fb523ebcafa8 100644 --- a/arch/mips/pmc-sierra/yosemite/ht.c +++ b/arch/mips/pmc-sierra/yosemite/ht.c | |||
@@ -383,12 +383,12 @@ void pcibios_update_resource(struct pci_dev *dev, struct resource *root, | |||
383 | 383 | ||
384 | 384 | ||
385 | void pcibios_align_resource(void *data, struct resource *res, | 385 | void pcibios_align_resource(void *data, struct resource *res, |
386 | unsigned long size, unsigned long align) | 386 | resource_size_t size, resource_size_t align) |
387 | { | 387 | { |
388 | struct pci_dev *dev = data; | 388 | struct pci_dev *dev = data; |
389 | 389 | ||
390 | if (res->flags & IORESOURCE_IO) { | 390 | if (res->flags & IORESOURCE_IO) { |
391 | unsigned long start = res->start; | 391 | resource_size_t start = res->start; |
392 | 392 | ||
393 | /* We need to avoid collisions with `mirrored' VGA ports | 393 | /* We need to avoid collisions with `mirrored' VGA ports |
394 | and other strange ISA hardware, so we always want the | 394 | and other strange ISA hardware, so we always want the |
diff --git a/arch/mips/sgi-ip22/ip22-eisa.c b/arch/mips/sgi-ip22/ip22-eisa.c index b19820110aa3..989167b49ce9 100644 --- a/arch/mips/sgi-ip22/ip22-eisa.c +++ b/arch/mips/sgi-ip22/ip22-eisa.c | |||
@@ -279,9 +279,9 @@ int __init ip22_eisa_init(void) | |||
279 | irq_desc[i].action = 0; | 279 | irq_desc[i].action = 0; |
280 | irq_desc[i].depth = 1; | 280 | irq_desc[i].depth = 1; |
281 | if (i < (SGINT_EISA + 8)) | 281 | if (i < (SGINT_EISA + 8)) |
282 | irq_desc[i].handler = &ip22_eisa1_irq_type; | 282 | irq_desc[i].chip = &ip22_eisa1_irq_type; |
283 | else | 283 | else |
284 | irq_desc[i].handler = &ip22_eisa2_irq_type; | 284 | irq_desc[i].chip = &ip22_eisa2_irq_type; |
285 | } | 285 | } |
286 | 286 | ||
287 | /* Cannot use request_irq because of kmalloc not being ready at such | 287 | /* Cannot use request_irq because of kmalloc not being ready at such |
diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c index fc6a7e2b189c..18906af69691 100644 --- a/arch/mips/sgi-ip22/ip22-int.c +++ b/arch/mips/sgi-ip22/ip22-int.c | |||
@@ -436,7 +436,7 @@ void __init arch_init_irq(void) | |||
436 | irq_desc[i].status = IRQ_DISABLED; | 436 | irq_desc[i].status = IRQ_DISABLED; |
437 | irq_desc[i].action = 0; | 437 | irq_desc[i].action = 0; |
438 | irq_desc[i].depth = 1; | 438 | irq_desc[i].depth = 1; |
439 | irq_desc[i].handler = handler; | 439 | irq_desc[i].chip = handler; |
440 | } | 440 | } |
441 | 441 | ||
442 | /* vector handler. this register the IRQ as non-sharable */ | 442 | /* vector handler. this register the IRQ as non-sharable */ |
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c index 0b61a39ce2bb..869566c360ae 100644 --- a/arch/mips/sgi-ip27/ip27-irq.c +++ b/arch/mips/sgi-ip27/ip27-irq.c | |||
@@ -386,7 +386,7 @@ void __devinit register_bridge_irq(unsigned int irq) | |||
386 | irq_desc[irq].status = IRQ_DISABLED; | 386 | irq_desc[irq].status = IRQ_DISABLED; |
387 | irq_desc[irq].action = 0; | 387 | irq_desc[irq].action = 0; |
388 | irq_desc[irq].depth = 1; | 388 | irq_desc[irq].depth = 1; |
389 | irq_desc[irq].handler = &bridge_irq_type; | 389 | irq_desc[irq].chip = &bridge_irq_type; |
390 | } | 390 | } |
391 | 391 | ||
392 | int __devinit request_bridge_irq(struct bridge_controller *bc) | 392 | int __devinit request_bridge_irq(struct bridge_controller *bc) |
diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c index 8ba08047d164..00b94aaf6371 100644 --- a/arch/mips/sgi-ip32/ip32-irq.c +++ b/arch/mips/sgi-ip32/ip32-irq.c | |||
@@ -591,7 +591,7 @@ void __init arch_init_irq(void) | |||
591 | irq_desc[irq].status = IRQ_DISABLED; | 591 | irq_desc[irq].status = IRQ_DISABLED; |
592 | irq_desc[irq].action = 0; | 592 | irq_desc[irq].action = 0; |
593 | irq_desc[irq].depth = 0; | 593 | irq_desc[irq].depth = 0; |
594 | irq_desc[irq].handler = controller; | 594 | irq_desc[irq].chip = controller; |
595 | } | 595 | } |
596 | setup_irq(CRIME_MEMERR_IRQ, &memerr_irq); | 596 | setup_irq(CRIME_MEMERR_IRQ, &memerr_irq); |
597 | setup_irq(CRIME_CPUERR_IRQ, &cpuerr_irq); | 597 | setup_irq(CRIME_CPUERR_IRQ, &cpuerr_irq); |
diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c index e61760b14d99..610df40cb820 100644 --- a/arch/mips/sibyte/bcm1480/irq.c +++ b/arch/mips/sibyte/bcm1480/irq.c | |||
@@ -276,10 +276,10 @@ void __init init_bcm1480_irqs(void) | |||
276 | irq_desc[i].action = 0; | 276 | irq_desc[i].action = 0; |
277 | irq_desc[i].depth = 1; | 277 | irq_desc[i].depth = 1; |
278 | if (i < BCM1480_NR_IRQS) { | 278 | if (i < BCM1480_NR_IRQS) { |
279 | irq_desc[i].handler = &bcm1480_irq_type; | 279 | irq_desc[i].chip = &bcm1480_irq_type; |
280 | bcm1480_irq_owner[i] = 0; | 280 | bcm1480_irq_owner[i] = 0; |
281 | } else { | 281 | } else { |
282 | irq_desc[i].handler = &no_irq_type; | 282 | irq_desc[i].chip = &no_irq_type; |
283 | } | 283 | } |
284 | } | 284 | } |
285 | } | 285 | } |
diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c index f853c32f60a0..fcc61940f1ff 100644 --- a/arch/mips/sibyte/sb1250/irq.c +++ b/arch/mips/sibyte/sb1250/irq.c | |||
@@ -246,10 +246,10 @@ void __init init_sb1250_irqs(void) | |||
246 | irq_desc[i].action = 0; | 246 | irq_desc[i].action = 0; |
247 | irq_desc[i].depth = 1; | 247 | irq_desc[i].depth = 1; |
248 | if (i < SB1250_NR_IRQS) { | 248 | if (i < SB1250_NR_IRQS) { |
249 | irq_desc[i].handler = &sb1250_irq_type; | 249 | irq_desc[i].chip = &sb1250_irq_type; |
250 | sb1250_irq_owner[i] = 0; | 250 | sb1250_irq_owner[i] = 0; |
251 | } else { | 251 | } else { |
252 | irq_desc[i].handler = &no_irq_type; | 252 | irq_desc[i].chip = &no_irq_type; |
253 | } | 253 | } |
254 | } | 254 | } |
255 | } | 255 | } |
diff --git a/arch/mips/sni/irq.c b/arch/mips/sni/irq.c index 7365b4853ddb..c19e158ec402 100644 --- a/arch/mips/sni/irq.c +++ b/arch/mips/sni/irq.c | |||
@@ -203,7 +203,7 @@ void __init arch_init_irq(void) | |||
203 | irq_desc[i].status = IRQ_DISABLED; | 203 | irq_desc[i].status = IRQ_DISABLED; |
204 | irq_desc[i].action = 0; | 204 | irq_desc[i].action = 0; |
205 | irq_desc[i].depth = 1; | 205 | irq_desc[i].depth = 1; |
206 | irq_desc[i].handler = &pciasic_irq_type; | 206 | irq_desc[i].chip = &pciasic_irq_type; |
207 | } | 207 | } |
208 | 208 | ||
209 | change_c0_status(ST0_IM, IE_IRQ1|IE_IRQ2|IE_IRQ3|IE_IRQ4); | 209 | change_c0_status(ST0_IM, IE_IRQ1|IE_IRQ2|IE_IRQ3|IE_IRQ4); |
diff --git a/arch/mips/tx4927/common/tx4927_irq.c b/arch/mips/tx4927/common/tx4927_irq.c index 8ca68015cf40..a42be00483e6 100644 --- a/arch/mips/tx4927/common/tx4927_irq.c +++ b/arch/mips/tx4927/common/tx4927_irq.c | |||
@@ -227,7 +227,7 @@ static void __init tx4927_irq_cp0_init(void) | |||
227 | irq_desc[i].status = IRQ_DISABLED; | 227 | irq_desc[i].status = IRQ_DISABLED; |
228 | irq_desc[i].action = 0; | 228 | irq_desc[i].action = 0; |
229 | irq_desc[i].depth = 1; | 229 | irq_desc[i].depth = 1; |
230 | irq_desc[i].handler = &tx4927_irq_cp0_type; | 230 | irq_desc[i].chip = &tx4927_irq_cp0_type; |
231 | } | 231 | } |
232 | 232 | ||
233 | return; | 233 | return; |
@@ -435,7 +435,7 @@ static void __init tx4927_irq_pic_init(void) | |||
435 | irq_desc[i].status = IRQ_DISABLED; | 435 | irq_desc[i].status = IRQ_DISABLED; |
436 | irq_desc[i].action = 0; | 436 | irq_desc[i].action = 0; |
437 | irq_desc[i].depth = 2; | 437 | irq_desc[i].depth = 2; |
438 | irq_desc[i].handler = &tx4927_irq_pic_type; | 438 | irq_desc[i].chip = &tx4927_irq_pic_type; |
439 | } | 439 | } |
440 | 440 | ||
441 | setup_irq(TX4927_IRQ_NEST_PIC_ON_CP0, &tx4927_irq_pic_action); | 441 | setup_irq(TX4927_IRQ_NEST_PIC_ON_CP0, &tx4927_irq_pic_action); |
diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c index aee07ff2212a..c67978b6dae4 100644 --- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c +++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c | |||
@@ -368,7 +368,7 @@ static void __init toshiba_rbtx4927_irq_ioc_init(void) | |||
368 | irq_desc[i].status = IRQ_DISABLED; | 368 | irq_desc[i].status = IRQ_DISABLED; |
369 | irq_desc[i].action = 0; | 369 | irq_desc[i].action = 0; |
370 | irq_desc[i].depth = 3; | 370 | irq_desc[i].depth = 3; |
371 | irq_desc[i].handler = &toshiba_rbtx4927_irq_ioc_type; | 371 | irq_desc[i].chip = &toshiba_rbtx4927_irq_ioc_type; |
372 | } | 372 | } |
373 | 373 | ||
374 | setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_IOC_ON_PIC, | 374 | setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_IOC_ON_PIC, |
@@ -526,7 +526,7 @@ static void __init toshiba_rbtx4927_irq_isa_init(void) | |||
526 | irq_desc[i].action = 0; | 526 | irq_desc[i].action = 0; |
527 | irq_desc[i].depth = | 527 | irq_desc[i].depth = |
528 | ((i < TOSHIBA_RBTX4927_IRQ_ISA_MID) ? (4) : (5)); | 528 | ((i < TOSHIBA_RBTX4927_IRQ_ISA_MID) ? (4) : (5)); |
529 | irq_desc[i].handler = &toshiba_rbtx4927_irq_isa_type; | 529 | irq_desc[i].chip = &toshiba_rbtx4927_irq_isa_type; |
530 | } | 530 | } |
531 | 531 | ||
532 | setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC, | 532 | setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC, |
@@ -692,13 +692,13 @@ void toshiba_rbtx4927_irq_dump(char *key) | |||
692 | { | 692 | { |
693 | u32 i, j = 0; | 693 | u32 i, j = 0; |
694 | for (i = 0; i < NR_IRQS; i++) { | 694 | for (i = 0; i < NR_IRQS; i++) { |
695 | if (strcmp(irq_desc[i].handler->typename, "none") | 695 | if (strcmp(irq_desc[i].chip->typename, "none") |
696 | == 0) | 696 | == 0) |
697 | continue; | 697 | continue; |
698 | 698 | ||
699 | if ((i >= 1) | 699 | if ((i >= 1) |
700 | && (irq_desc[i - 1].handler->typename == | 700 | && (irq_desc[i - 1].chip->typename == |
701 | irq_desc[i].handler->typename)) { | 701 | irq_desc[i].chip->typename)) { |
702 | j++; | 702 | j++; |
703 | } else { | 703 | } else { |
704 | j = 0; | 704 | j = 0; |
@@ -707,12 +707,12 @@ void toshiba_rbtx4927_irq_dump(char *key) | |||
707 | (TOSHIBA_RBTX4927_IRQ_INFO, | 707 | (TOSHIBA_RBTX4927_IRQ_INFO, |
708 | "%s irq=0x%02x/%3d s=0x%08x h=0x%08x a=0x%08x ah=0x%08x d=%1d n=%s/%02d\n", | 708 | "%s irq=0x%02x/%3d s=0x%08x h=0x%08x a=0x%08x ah=0x%08x d=%1d n=%s/%02d\n", |
709 | key, i, i, irq_desc[i].status, | 709 | key, i, i, irq_desc[i].status, |
710 | (u32) irq_desc[i].handler, | 710 | (u32) irq_desc[i].chip, |
711 | (u32) irq_desc[i].action, | 711 | (u32) irq_desc[i].action, |
712 | (u32) (irq_desc[i].action ? irq_desc[i]. | 712 | (u32) (irq_desc[i].action ? irq_desc[i]. |
713 | action->handler : 0), | 713 | action->handler : 0), |
714 | irq_desc[i].depth, | 714 | irq_desc[i].depth, |
715 | irq_desc[i].handler->typename, j); | 715 | irq_desc[i].chip->typename, j); |
716 | } | 716 | } |
717 | } | 717 | } |
718 | #endif | 718 | #endif |
diff --git a/arch/mips/tx4938/common/irq.c b/arch/mips/tx4938/common/irq.c index 873805178d8e..0b2f8c849218 100644 --- a/arch/mips/tx4938/common/irq.c +++ b/arch/mips/tx4938/common/irq.c | |||
@@ -102,7 +102,7 @@ tx4938_irq_cp0_init(void) | |||
102 | irq_desc[i].status = IRQ_DISABLED; | 102 | irq_desc[i].status = IRQ_DISABLED; |
103 | irq_desc[i].action = 0; | 103 | irq_desc[i].action = 0; |
104 | irq_desc[i].depth = 1; | 104 | irq_desc[i].depth = 1; |
105 | irq_desc[i].handler = &tx4938_irq_cp0_type; | 105 | irq_desc[i].chip = &tx4938_irq_cp0_type; |
106 | } | 106 | } |
107 | 107 | ||
108 | return; | 108 | return; |
@@ -306,7 +306,7 @@ tx4938_irq_pic_init(void) | |||
306 | irq_desc[i].status = IRQ_DISABLED; | 306 | irq_desc[i].status = IRQ_DISABLED; |
307 | irq_desc[i].action = 0; | 307 | irq_desc[i].action = 0; |
308 | irq_desc[i].depth = 2; | 308 | irq_desc[i].depth = 2; |
309 | irq_desc[i].handler = &tx4938_irq_pic_type; | 309 | irq_desc[i].chip = &tx4938_irq_pic_type; |
310 | } | 310 | } |
311 | 311 | ||
312 | setup_irq(TX4938_IRQ_NEST_PIC_ON_CP0, &tx4938_irq_pic_action); | 312 | setup_irq(TX4938_IRQ_NEST_PIC_ON_CP0, &tx4938_irq_pic_action); |
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/irq.c b/arch/mips/tx4938/toshiba_rbtx4938/irq.c index 9cd9c0fe2265..3b8245dc5bd3 100644 --- a/arch/mips/tx4938/toshiba_rbtx4938/irq.c +++ b/arch/mips/tx4938/toshiba_rbtx4938/irq.c | |||
@@ -146,7 +146,7 @@ toshiba_rbtx4938_irq_ioc_init(void) | |||
146 | irq_desc[i].status = IRQ_DISABLED; | 146 | irq_desc[i].status = IRQ_DISABLED; |
147 | irq_desc[i].action = 0; | 147 | irq_desc[i].action = 0; |
148 | irq_desc[i].depth = 3; | 148 | irq_desc[i].depth = 3; |
149 | irq_desc[i].handler = &toshiba_rbtx4938_irq_ioc_type; | 149 | irq_desc[i].chip = &toshiba_rbtx4938_irq_ioc_type; |
150 | } | 150 | } |
151 | 151 | ||
152 | setup_irq(RBTX4938_IRQ_IOCINT, | 152 | setup_irq(RBTX4938_IRQ_IOCINT, |
diff --git a/arch/mips/vr41xx/common/icu.c b/arch/mips/vr41xx/common/icu.c index 07ae19cf0c29..b9323302cc4e 100644 --- a/arch/mips/vr41xx/common/icu.c +++ b/arch/mips/vr41xx/common/icu.c | |||
@@ -722,10 +722,10 @@ static int __init vr41xx_icu_init(void) | |||
722 | icu2_write(MGIUINTHREG, 0xffff); | 722 | icu2_write(MGIUINTHREG, 0xffff); |
723 | 723 | ||
724 | for (i = SYSINT1_IRQ_BASE; i <= SYSINT1_IRQ_LAST; i++) | 724 | for (i = SYSINT1_IRQ_BASE; i <= SYSINT1_IRQ_LAST; i++) |
725 | irq_desc[i].handler = &sysint1_irq_type; | 725 | irq_desc[i].chip = &sysint1_irq_type; |
726 | 726 | ||
727 | for (i = SYSINT2_IRQ_BASE; i <= SYSINT2_IRQ_LAST; i++) | 727 | for (i = SYSINT2_IRQ_BASE; i <= SYSINT2_IRQ_LAST; i++) |
728 | irq_desc[i].handler = &sysint2_irq_type; | 728 | irq_desc[i].chip = &sysint2_irq_type; |
729 | 729 | ||
730 | cascade_irq(INT0_IRQ, icu_get_irq); | 730 | cascade_irq(INT0_IRQ, icu_get_irq); |
731 | cascade_irq(INT1_IRQ, icu_get_irq); | 731 | cascade_irq(INT1_IRQ, icu_get_irq); |
diff --git a/arch/mips/vr41xx/common/irq.c b/arch/mips/vr41xx/common/irq.c index 86796bb63c3c..66aa50802deb 100644 --- a/arch/mips/vr41xx/common/irq.c +++ b/arch/mips/vr41xx/common/irq.c | |||
@@ -73,13 +73,13 @@ static void irq_dispatch(unsigned int irq, struct pt_regs *regs) | |||
73 | if (cascade->get_irq != NULL) { | 73 | if (cascade->get_irq != NULL) { |
74 | unsigned int source_irq = irq; | 74 | unsigned int source_irq = irq; |
75 | desc = irq_desc + source_irq; | 75 | desc = irq_desc + source_irq; |
76 | desc->handler->ack(source_irq); | 76 | desc->chip->ack(source_irq); |
77 | irq = cascade->get_irq(irq, regs); | 77 | irq = cascade->get_irq(irq, regs); |
78 | if (irq < 0) | 78 | if (irq < 0) |
79 | atomic_inc(&irq_err_count); | 79 | atomic_inc(&irq_err_count); |
80 | else | 80 | else |
81 | irq_dispatch(irq, regs); | 81 | irq_dispatch(irq, regs); |
82 | desc->handler->end(source_irq); | 82 | desc->chip->end(source_irq); |
83 | } else | 83 | } else |
84 | do_IRQ(irq, regs); | 84 | do_IRQ(irq, regs); |
85 | } | 85 | } |
diff --git a/arch/mips/vr41xx/common/vrc4173.c b/arch/mips/vr41xx/common/vrc4173.c index 3e31f8193d21..2d287b8893d9 100644 --- a/arch/mips/vr41xx/common/vrc4173.c +++ b/arch/mips/vr41xx/common/vrc4173.c | |||
@@ -483,7 +483,7 @@ static inline int vrc4173_icu_init(int cascade_irq) | |||
483 | vr41xx_set_irq_level(GIU_IRQ_TO_PIN(cascade_irq), LEVEL_LOW); | 483 | vr41xx_set_irq_level(GIU_IRQ_TO_PIN(cascade_irq), LEVEL_LOW); |
484 | 484 | ||
485 | for (i = VRC4173_IRQ_BASE; i <= VRC4173_IRQ_LAST; i++) | 485 | for (i = VRC4173_IRQ_BASE; i <= VRC4173_IRQ_LAST; i++) |
486 | irq_desc[i].handler = &vrc4173_irq_type; | 486 | irq_desc[i].chip = &vrc4173_irq_type; |
487 | 487 | ||
488 | return 0; | 488 | return 0; |
489 | } | 489 | } |
diff --git a/arch/mips/vr41xx/nec-cmbvr4133/irq.c b/arch/mips/vr41xx/nec-cmbvr4133/irq.c index 31db6b61a39e..7b2511ca0a61 100644 --- a/arch/mips/vr41xx/nec-cmbvr4133/irq.c +++ b/arch/mips/vr41xx/nec-cmbvr4133/irq.c | |||
@@ -104,7 +104,7 @@ void __init rockhopper_init_irq(void) | |||
104 | } | 104 | } |
105 | 105 | ||
106 | for (i = I8259_IRQ_BASE; i <= I8259_IRQ_LAST; i++) | 106 | for (i = I8259_IRQ_BASE; i <= I8259_IRQ_LAST; i++) |
107 | irq_desc[i].handler = &i8259_irq_type; | 107 | irq_desc[i].chip = &i8259_irq_type; |
108 | 108 | ||
109 | setup_irq(I8259_SLAVE_IRQ, &i8259_slave_cascade); | 109 | setup_irq(I8259_SLAVE_IRQ, &i8259_slave_cascade); |
110 | 110 | ||
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 910fb3afc0b5..6dd0ea8f88e0 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig | |||
@@ -51,6 +51,10 @@ config GENERIC_HARDIRQS | |||
51 | config GENERIC_IRQ_PROBE | 51 | config GENERIC_IRQ_PROBE |
52 | def_bool y | 52 | def_bool y |
53 | 53 | ||
54 | config IRQ_PER_CPU | ||
55 | bool | ||
56 | default y | ||
57 | |||
54 | # unless you want to implement ACPI on PA-RISC ... ;-) | 58 | # unless you want to implement ACPI on PA-RISC ... ;-) |
55 | config PM | 59 | config PM |
56 | bool | 60 | bool |
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index c057ad7605ba..bc7c4a4e26a1 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c | |||
@@ -97,15 +97,17 @@ update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte) | |||
97 | void | 97 | void |
98 | show_cache_info(struct seq_file *m) | 98 | show_cache_info(struct seq_file *m) |
99 | { | 99 | { |
100 | char buf[32]; | ||
101 | |||
100 | seq_printf(m, "I-cache\t\t: %ld KB\n", | 102 | seq_printf(m, "I-cache\t\t: %ld KB\n", |
101 | cache_info.ic_size/1024 ); | 103 | cache_info.ic_size/1024 ); |
102 | seq_printf(m, "D-cache\t\t: %ld KB (%s%s, %d-way associative)\n", | 104 | if (cache_info.dc_loop == 1) |
105 | snprintf(buf, 32, "%lu-way associative", cache_info.dc_loop); | ||
106 | seq_printf(m, "D-cache\t\t: %ld KB (%s%s, %s)\n", | ||
103 | cache_info.dc_size/1024, | 107 | cache_info.dc_size/1024, |
104 | (cache_info.dc_conf.cc_wt ? "WT":"WB"), | 108 | (cache_info.dc_conf.cc_wt ? "WT":"WB"), |
105 | (cache_info.dc_conf.cc_sh ? ", shared I/D":""), | 109 | (cache_info.dc_conf.cc_sh ? ", shared I/D":""), |
106 | (cache_info.dc_conf.cc_assoc) | 110 | ((cache_info.dc_loop == 1) ? "direct mapped" : buf)); |
107 | ); | ||
108 | |||
109 | seq_printf(m, "ITLB entries\t: %ld\n" "DTLB entries\t: %ld%s\n", | 111 | seq_printf(m, "ITLB entries\t: %ld\n" "DTLB entries\t: %ld%s\n", |
110 | cache_info.it_size, | 112 | cache_info.it_size, |
111 | cache_info.dt_size, | 113 | cache_info.dt_size, |
@@ -158,11 +160,11 @@ parisc_cache_init(void) | |||
158 | cache_info.dc_conf.cc_block, | 160 | cache_info.dc_conf.cc_block, |
159 | cache_info.dc_conf.cc_line, | 161 | cache_info.dc_conf.cc_line, |
160 | cache_info.dc_conf.cc_shift); | 162 | cache_info.dc_conf.cc_shift); |
161 | printk(" wt %d sh %d cst %d assoc %d\n", | 163 | printk(" wt %d sh %d cst %d hv %d\n", |
162 | cache_info.dc_conf.cc_wt, | 164 | cache_info.dc_conf.cc_wt, |
163 | cache_info.dc_conf.cc_sh, | 165 | cache_info.dc_conf.cc_sh, |
164 | cache_info.dc_conf.cc_cst, | 166 | cache_info.dc_conf.cc_cst, |
165 | cache_info.dc_conf.cc_assoc); | 167 | cache_info.dc_conf.cc_hv); |
166 | 168 | ||
167 | printk("IC base 0x%lx stride 0x%lx count 0x%lx loop 0x%lx\n", | 169 | printk("IC base 0x%lx stride 0x%lx count 0x%lx loop 0x%lx\n", |
168 | cache_info.ic_base, | 170 | cache_info.ic_base, |
@@ -176,11 +178,11 @@ parisc_cache_init(void) | |||
176 | cache_info.ic_conf.cc_block, | 178 | cache_info.ic_conf.cc_block, |
177 | cache_info.ic_conf.cc_line, | 179 | cache_info.ic_conf.cc_line, |
178 | cache_info.ic_conf.cc_shift); | 180 | cache_info.ic_conf.cc_shift); |
179 | printk(" wt %d sh %d cst %d assoc %d\n", | 181 | printk(" wt %d sh %d cst %d hv %d\n", |
180 | cache_info.ic_conf.cc_wt, | 182 | cache_info.ic_conf.cc_wt, |
181 | cache_info.ic_conf.cc_sh, | 183 | cache_info.ic_conf.cc_sh, |
182 | cache_info.ic_conf.cc_cst, | 184 | cache_info.ic_conf.cc_cst, |
183 | cache_info.ic_conf.cc_assoc); | 185 | cache_info.ic_conf.cc_hv); |
184 | 186 | ||
185 | printk("D-TLB conf: sh %d page %d cst %d aid %d pad1 %d \n", | 187 | printk("D-TLB conf: sh %d page %d cst %d aid %d pad1 %d \n", |
186 | cache_info.dt_conf.tc_sh, | 188 | cache_info.dt_conf.tc_sh, |
@@ -234,7 +236,8 @@ parisc_cache_init(void) | |||
234 | 236 | ||
235 | void disable_sr_hashing(void) | 237 | void disable_sr_hashing(void) |
236 | { | 238 | { |
237 | int srhash_type; | 239 | int srhash_type, retval; |
240 | unsigned long space_bits; | ||
238 | 241 | ||
239 | switch (boot_cpu_data.cpu_type) { | 242 | switch (boot_cpu_data.cpu_type) { |
240 | case pcx: /* We shouldn't get this far. setup.c should prevent it. */ | 243 | case pcx: /* We shouldn't get this far. setup.c should prevent it. */ |
@@ -260,6 +263,13 @@ void disable_sr_hashing(void) | |||
260 | } | 263 | } |
261 | 264 | ||
262 | disable_sr_hashing_asm(srhash_type); | 265 | disable_sr_hashing_asm(srhash_type); |
266 | |||
267 | retval = pdc_spaceid_bits(&space_bits); | ||
268 | /* If this procedure isn't implemented, don't panic. */ | ||
269 | if (retval < 0 && retval != PDC_BAD_OPTION) | ||
270 | panic("pdc_spaceid_bits call failed.\n"); | ||
271 | if (space_bits != 0) | ||
272 | panic("SpaceID hashing is still on!\n"); | ||
263 | } | 273 | } |
264 | 274 | ||
265 | void flush_dcache_page(struct page *page) | 275 | void flush_dcache_page(struct page *page) |
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index d9e53cf0372b..630730c32a5a 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S | |||
@@ -1638,7 +1638,7 @@ dbit_trap_20w: | |||
1638 | load32 PA(pa_dbit_lock),t0 | 1638 | load32 PA(pa_dbit_lock),t0 |
1639 | 1639 | ||
1640 | dbit_spin_20w: | 1640 | dbit_spin_20w: |
1641 | ldcw 0(t0),t1 | 1641 | LDCW 0(t0),t1 |
1642 | cmpib,= 0,t1,dbit_spin_20w | 1642 | cmpib,= 0,t1,dbit_spin_20w |
1643 | nop | 1643 | nop |
1644 | 1644 | ||
@@ -1674,7 +1674,7 @@ dbit_trap_11: | |||
1674 | load32 PA(pa_dbit_lock),t0 | 1674 | load32 PA(pa_dbit_lock),t0 |
1675 | 1675 | ||
1676 | dbit_spin_11: | 1676 | dbit_spin_11: |
1677 | ldcw 0(t0),t1 | 1677 | LDCW 0(t0),t1 |
1678 | cmpib,= 0,t1,dbit_spin_11 | 1678 | cmpib,= 0,t1,dbit_spin_11 |
1679 | nop | 1679 | nop |
1680 | 1680 | ||
@@ -1714,7 +1714,7 @@ dbit_trap_20: | |||
1714 | load32 PA(pa_dbit_lock),t0 | 1714 | load32 PA(pa_dbit_lock),t0 |
1715 | 1715 | ||
1716 | dbit_spin_20: | 1716 | dbit_spin_20: |
1717 | ldcw 0(t0),t1 | 1717 | LDCW 0(t0),t1 |
1718 | cmpib,= 0,t1,dbit_spin_20 | 1718 | cmpib,= 0,t1,dbit_spin_20 |
1719 | nop | 1719 | nop |
1720 | 1720 | ||
diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c index 2dc06b8e1817..4398d2a95789 100644 --- a/arch/parisc/kernel/firmware.c +++ b/arch/parisc/kernel/firmware.c | |||
@@ -11,7 +11,7 @@ | |||
11 | * Copyright 1999 The Puffin Group, (Alex deVries, David Kennedy) | 11 | * Copyright 1999 The Puffin Group, (Alex deVries, David Kennedy) |
12 | * Copyright 2003 Grant Grundler <grundler parisc-linux org> | 12 | * Copyright 2003 Grant Grundler <grundler parisc-linux org> |
13 | * Copyright 2003,2004 Ryan Bradetich <rbrad@parisc-linux.org> | 13 | * Copyright 2003,2004 Ryan Bradetich <rbrad@parisc-linux.org> |
14 | * Copyright 2004 Thibaut VARENE <varenet@parisc-linux.org> | 14 | * Copyright 2004,2006 Thibaut VARENE <varenet@parisc-linux.org> |
15 | * | 15 | * |
16 | * This program is free software; you can redistribute it and/or modify | 16 | * This program is free software; you can redistribute it and/or modify |
17 | * it under the terms of the GNU General Public License as published by | 17 | * it under the terms of the GNU General Public License as published by |
@@ -252,10 +252,8 @@ int pdc_pat_chassis_send_log(unsigned long state, unsigned long data) | |||
252 | #endif | 252 | #endif |
253 | 253 | ||
254 | /** | 254 | /** |
255 | * pdc_chassis_disp - Updates display | 255 | * pdc_chassis_disp - Updates chassis code |
256 | * @retval: -1 on error, 0 on success | 256 | * @retval: -1 on error, 0 on success |
257 | * | ||
258 | * Works on old PDC only (E class, others?) | ||
259 | */ | 257 | */ |
260 | int pdc_chassis_disp(unsigned long disp) | 258 | int pdc_chassis_disp(unsigned long disp) |
261 | { | 259 | { |
@@ -269,6 +267,22 @@ int pdc_chassis_disp(unsigned long disp) | |||
269 | } | 267 | } |
270 | 268 | ||
271 | /** | 269 | /** |
270 | * pdc_chassis_warn - Fetches chassis warnings | ||
271 | * @retval: -1 on error, 0 on success | ||
272 | */ | ||
273 | int pdc_chassis_warn(unsigned long *warn) | ||
274 | { | ||
275 | int retval = 0; | ||
276 | |||
277 | spin_lock_irq(&pdc_lock); | ||
278 | retval = mem_pdc_call(PDC_CHASSIS, PDC_CHASSIS_WARN, __pa(pdc_result)); | ||
279 | *warn = pdc_result[0]; | ||
280 | spin_unlock_irq(&pdc_lock); | ||
281 | |||
282 | return retval; | ||
283 | } | ||
284 | |||
285 | /** | ||
272 | * pdc_coproc_cfg - To identify coprocessors attached to the processor. | 286 | * pdc_coproc_cfg - To identify coprocessors attached to the processor. |
273 | * @pdc_coproc_info: Return buffer address. | 287 | * @pdc_coproc_info: Return buffer address. |
274 | * | 288 | * |
@@ -393,7 +407,9 @@ int pdc_model_info(struct pdc_model *model) | |||
393 | * pdc_model_sysmodel - Get the system model name. | 407 | * pdc_model_sysmodel - Get the system model name. |
394 | * @name: A char array of at least 81 characters. | 408 | * @name: A char array of at least 81 characters. |
395 | * | 409 | * |
396 | * Get system model name from PDC ROM (e.g. 9000/715 or 9000/778/B160L) | 410 | * Get system model name from PDC ROM (e.g. 9000/715 or 9000/778/B160L). |
411 | * Using OS_ID_HPUX will return the equivalent of the 'modelname' command | ||
412 | * on HP/UX. | ||
397 | */ | 413 | */ |
398 | int pdc_model_sysmodel(char *name) | 414 | int pdc_model_sysmodel(char *name) |
399 | { | 415 | { |
@@ -498,6 +514,26 @@ int pdc_cache_info(struct pdc_cache_info *cache_info) | |||
498 | return retval; | 514 | return retval; |
499 | } | 515 | } |
500 | 516 | ||
517 | /** | ||
518 | * pdc_spaceid_bits - Return whether Space ID hashing is turned on. | ||
519 | * @space_bits: Should be 0, if not, bad mojo! | ||
520 | * | ||
521 | * Returns information about Space ID hashing. | ||
522 | */ | ||
523 | int pdc_spaceid_bits(unsigned long *space_bits) | ||
524 | { | ||
525 | int retval; | ||
526 | |||
527 | spin_lock_irq(&pdc_lock); | ||
528 | pdc_result[0] = 0; | ||
529 | retval = mem_pdc_call(PDC_CACHE, PDC_CACHE_RET_SPID, __pa(pdc_result), 0); | ||
530 | convert_to_wide(pdc_result); | ||
531 | *space_bits = pdc_result[0]; | ||
532 | spin_unlock_irq(&pdc_lock); | ||
533 | |||
534 | return retval; | ||
535 | } | ||
536 | |||
501 | #ifndef CONFIG_PA20 | 537 | #ifndef CONFIG_PA20 |
502 | /** | 538 | /** |
503 | * pdc_btlb_info - Return block TLB information. | 539 | * pdc_btlb_info - Return block TLB information. |
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index 197936d9359a..82fe6ba29727 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c | |||
@@ -94,7 +94,7 @@ int cpu_check_affinity(unsigned int irq, cpumask_t *dest) | |||
94 | if (irq == TIMER_IRQ || irq == IPI_IRQ) { | 94 | if (irq == TIMER_IRQ || irq == IPI_IRQ) { |
95 | /* Bad linux design decision. The mask has already | 95 | /* Bad linux design decision. The mask has already |
96 | * been set; we must reset it */ | 96 | * been set; we must reset it */ |
97 | irq_affinity[irq] = CPU_MASK_ALL; | 97 | irq_desc[irq].affinity = CPU_MASK_ALL; |
98 | return -EINVAL; | 98 | return -EINVAL; |
99 | } | 99 | } |
100 | 100 | ||
@@ -110,7 +110,7 @@ static void cpu_set_affinity_irq(unsigned int irq, cpumask_t dest) | |||
110 | if (cpu_check_affinity(irq, &dest)) | 110 | if (cpu_check_affinity(irq, &dest)) |
111 | return; | 111 | return; |
112 | 112 | ||
113 | irq_affinity[irq] = dest; | 113 | irq_desc[irq].affinity = dest; |
114 | } | 114 | } |
115 | #endif | 115 | #endif |
116 | 116 | ||
@@ -125,6 +125,10 @@ static struct hw_interrupt_type cpu_interrupt_type = { | |||
125 | #ifdef CONFIG_SMP | 125 | #ifdef CONFIG_SMP |
126 | .set_affinity = cpu_set_affinity_irq, | 126 | .set_affinity = cpu_set_affinity_irq, |
127 | #endif | 127 | #endif |
128 | /* XXX: Needs to be written. We managed without it so far, but | ||
129 | * we really ought to write it. | ||
130 | */ | ||
131 | .retrigger = NULL, | ||
128 | }; | 132 | }; |
129 | 133 | ||
130 | int show_interrupts(struct seq_file *p, void *v) | 134 | int show_interrupts(struct seq_file *p, void *v) |
@@ -158,7 +162,7 @@ int show_interrupts(struct seq_file *p, void *v) | |||
158 | seq_printf(p, "%10u ", kstat_irqs(i)); | 162 | seq_printf(p, "%10u ", kstat_irqs(i)); |
159 | #endif | 163 | #endif |
160 | 164 | ||
161 | seq_printf(p, " %14s", irq_desc[i].handler->typename); | 165 | seq_printf(p, " %14s", irq_desc[i].chip->typename); |
162 | #ifndef PARISC_IRQ_CR16_COUNTS | 166 | #ifndef PARISC_IRQ_CR16_COUNTS |
163 | seq_printf(p, " %s", action->name); | 167 | seq_printf(p, " %s", action->name); |
164 | 168 | ||
@@ -210,12 +214,12 @@ int cpu_claim_irq(unsigned int irq, struct hw_interrupt_type *type, void *data) | |||
210 | { | 214 | { |
211 | if (irq_desc[irq].action) | 215 | if (irq_desc[irq].action) |
212 | return -EBUSY; | 216 | return -EBUSY; |
213 | if (irq_desc[irq].handler != &cpu_interrupt_type) | 217 | if (irq_desc[irq].chip != &cpu_interrupt_type) |
214 | return -EBUSY; | 218 | return -EBUSY; |
215 | 219 | ||
216 | if (type) { | 220 | if (type) { |
217 | irq_desc[irq].handler = type; | 221 | irq_desc[irq].chip = type; |
218 | irq_desc[irq].handler_data = data; | 222 | irq_desc[irq].chip_data = data; |
219 | cpu_interrupt_type.enable(irq); | 223 | cpu_interrupt_type.enable(irq); |
220 | } | 224 | } |
221 | return 0; | 225 | return 0; |
@@ -265,7 +269,7 @@ int txn_alloc_irq(unsigned int bits_wide) | |||
265 | unsigned long txn_affinity_addr(unsigned int irq, int cpu) | 269 | unsigned long txn_affinity_addr(unsigned int irq, int cpu) |
266 | { | 270 | { |
267 | #ifdef CONFIG_SMP | 271 | #ifdef CONFIG_SMP |
268 | irq_affinity[irq] = cpumask_of_cpu(cpu); | 272 | irq_desc[irq].affinity = cpumask_of_cpu(cpu); |
269 | #endif | 273 | #endif |
270 | 274 | ||
271 | return cpu_data[cpu].txn_addr; | 275 | return cpu_data[cpu].txn_addr; |
@@ -326,7 +330,7 @@ void do_cpu_irq_mask(struct pt_regs *regs) | |||
326 | /* Work our way from MSb to LSb...same order we alloc EIRs */ | 330 | /* Work our way from MSb to LSb...same order we alloc EIRs */ |
327 | for (irq = TIMER_IRQ; eirr_val && bit; bit>>=1, irq++) { | 331 | for (irq = TIMER_IRQ; eirr_val && bit; bit>>=1, irq++) { |
328 | #ifdef CONFIG_SMP | 332 | #ifdef CONFIG_SMP |
329 | cpumask_t dest = irq_affinity[irq]; | 333 | cpumask_t dest = irq_desc[irq].affinity; |
330 | #endif | 334 | #endif |
331 | if (!(bit & eirr_val)) | 335 | if (!(bit & eirr_val)) |
332 | continue; | 336 | continue; |
@@ -378,7 +382,7 @@ static void claim_cpu_irqs(void) | |||
378 | { | 382 | { |
379 | int i; | 383 | int i; |
380 | for (i = CPU_IRQ_BASE; i <= CPU_IRQ_MAX; i++) { | 384 | for (i = CPU_IRQ_BASE; i <= CPU_IRQ_MAX; i++) { |
381 | irq_desc[i].handler = &cpu_interrupt_type; | 385 | irq_desc[i].chip = &cpu_interrupt_type; |
382 | } | 386 | } |
383 | 387 | ||
384 | irq_desc[TIMER_IRQ].action = &timer_action; | 388 | irq_desc[TIMER_IRQ].action = &timer_action; |
@@ -404,13 +408,6 @@ void __init init_IRQ(void) | |||
404 | 408 | ||
405 | } | 409 | } |
406 | 410 | ||
407 | void hw_resend_irq(struct hw_interrupt_type *type, unsigned int irq) | ||
408 | { | ||
409 | /* XXX: Needs to be written. We managed without it so far, but | ||
410 | * we really ought to write it. | ||
411 | */ | ||
412 | } | ||
413 | |||
414 | void ack_bad_irq(unsigned int irq) | 411 | void ack_bad_irq(unsigned int irq) |
415 | { | 412 | { |
416 | printk("unexpected IRQ %d\n", irq); | 413 | printk("unexpected IRQ %d\n", irq); |
diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index f27cfe4771b8..aee311884f3f 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c | |||
@@ -89,6 +89,12 @@ static inline int is_local(struct module *me, void *loc) | |||
89 | return is_init(me, loc) || is_core(me, loc); | 89 | return is_init(me, loc) || is_core(me, loc); |
90 | } | 90 | } |
91 | 91 | ||
92 | static inline int is_local_section(struct module *me, void *loc, void *dot) | ||
93 | { | ||
94 | return (is_init(me, loc) && is_init(me, dot)) || | ||
95 | (is_core(me, loc) && is_core(me, dot)); | ||
96 | } | ||
97 | |||
92 | 98 | ||
93 | #ifndef __LP64__ | 99 | #ifndef __LP64__ |
94 | struct got_entry { | 100 | struct got_entry { |
@@ -364,8 +370,14 @@ static Elf_Addr get_fdesc(struct module *me, unsigned long value) | |||
364 | } | 370 | } |
365 | #endif /* __LP64__ */ | 371 | #endif /* __LP64__ */ |
366 | 372 | ||
373 | enum elf_stub_type { | ||
374 | ELF_STUB_GOT, | ||
375 | ELF_STUB_MILLI, | ||
376 | ELF_STUB_DIRECT, | ||
377 | }; | ||
378 | |||
367 | static Elf_Addr get_stub(struct module *me, unsigned long value, long addend, | 379 | static Elf_Addr get_stub(struct module *me, unsigned long value, long addend, |
368 | int millicode, int init_section) | 380 | enum elf_stub_type stub_type, int init_section) |
369 | { | 381 | { |
370 | unsigned long i; | 382 | unsigned long i; |
371 | struct stub_entry *stub; | 383 | struct stub_entry *stub; |
@@ -396,7 +408,7 @@ static Elf_Addr get_stub(struct module *me, unsigned long value, long addend, | |||
396 | stub->insns[1] |= reassemble_17(rrsel(value, addend) / 4); | 408 | stub->insns[1] |= reassemble_17(rrsel(value, addend) / 4); |
397 | 409 | ||
398 | #else | 410 | #else |
399 | /* for 64-bit we have two kinds of stubs: | 411 | /* for 64-bit we have three kinds of stubs: |
400 | * for normal function calls: | 412 | * for normal function calls: |
401 | * ldd 0(%dp),%dp | 413 | * ldd 0(%dp),%dp |
402 | * ldd 10(%dp), %r1 | 414 | * ldd 10(%dp), %r1 |
@@ -408,18 +420,23 @@ static Elf_Addr get_stub(struct module *me, unsigned long value, long addend, | |||
408 | * ldo 0(%r1), %r1 | 420 | * ldo 0(%r1), %r1 |
409 | * ldd 10(%r1), %r1 | 421 | * ldd 10(%r1), %r1 |
410 | * bve,n (%r1) | 422 | * bve,n (%r1) |
423 | * | ||
424 | * for direct branches (jumps between different section of the | ||
425 | * same module): | ||
426 | * ldil 0, %r1 | ||
427 | * ldo 0(%r1), %r1 | ||
428 | * bve,n (%r1) | ||
411 | */ | 429 | */ |
412 | if (!millicode) | 430 | switch (stub_type) { |
413 | { | 431 | case ELF_STUB_GOT: |
414 | stub->insns[0] = 0x537b0000; /* ldd 0(%dp),%dp */ | 432 | stub->insns[0] = 0x537b0000; /* ldd 0(%dp),%dp */ |
415 | stub->insns[1] = 0x53610020; /* ldd 10(%dp),%r1 */ | 433 | stub->insns[1] = 0x53610020; /* ldd 10(%dp),%r1 */ |
416 | stub->insns[2] = 0xe820d000; /* bve (%r1) */ | 434 | stub->insns[2] = 0xe820d000; /* bve (%r1) */ |
417 | stub->insns[3] = 0x537b0030; /* ldd 18(%dp),%dp */ | 435 | stub->insns[3] = 0x537b0030; /* ldd 18(%dp),%dp */ |
418 | 436 | ||
419 | stub->insns[0] |= reassemble_14(get_got(me, value, addend) & 0x3fff); | 437 | stub->insns[0] |= reassemble_14(get_got(me, value, addend) & 0x3fff); |
420 | } | 438 | break; |
421 | else | 439 | case ELF_STUB_MILLI: |
422 | { | ||
423 | stub->insns[0] = 0x20200000; /* ldil 0,%r1 */ | 440 | stub->insns[0] = 0x20200000; /* ldil 0,%r1 */ |
424 | stub->insns[1] = 0x34210000; /* ldo 0(%r1), %r1 */ | 441 | stub->insns[1] = 0x34210000; /* ldo 0(%r1), %r1 */ |
425 | stub->insns[2] = 0x50210020; /* ldd 10(%r1),%r1 */ | 442 | stub->insns[2] = 0x50210020; /* ldd 10(%r1),%r1 */ |
@@ -427,7 +444,17 @@ static Elf_Addr get_stub(struct module *me, unsigned long value, long addend, | |||
427 | 444 | ||
428 | stub->insns[0] |= reassemble_21(lrsel(value, addend)); | 445 | stub->insns[0] |= reassemble_21(lrsel(value, addend)); |
429 | stub->insns[1] |= reassemble_14(rrsel(value, addend)); | 446 | stub->insns[1] |= reassemble_14(rrsel(value, addend)); |
447 | break; | ||
448 | case ELF_STUB_DIRECT: | ||
449 | stub->insns[0] = 0x20200000; /* ldil 0,%r1 */ | ||
450 | stub->insns[1] = 0x34210000; /* ldo 0(%r1), %r1 */ | ||
451 | stub->insns[2] = 0xe820d002; /* bve,n (%r1) */ | ||
452 | |||
453 | stub->insns[0] |= reassemble_21(lrsel(value, addend)); | ||
454 | stub->insns[1] |= reassemble_14(rrsel(value, addend)); | ||
455 | break; | ||
430 | } | 456 | } |
457 | |||
431 | #endif | 458 | #endif |
432 | 459 | ||
433 | return (Elf_Addr)stub; | 460 | return (Elf_Addr)stub; |
@@ -539,14 +566,14 @@ int apply_relocate_add(Elf_Shdr *sechdrs, | |||
539 | break; | 566 | break; |
540 | case R_PARISC_PCREL17F: | 567 | case R_PARISC_PCREL17F: |
541 | /* 17-bit PC relative address */ | 568 | /* 17-bit PC relative address */ |
542 | val = get_stub(me, val, addend, 0, is_init(me, loc)); | 569 | val = get_stub(me, val, addend, ELF_STUB_GOT, is_init(me, loc)); |
543 | val = (val - dot - 8)/4; | 570 | val = (val - dot - 8)/4; |
544 | CHECK_RELOC(val, 17) | 571 | CHECK_RELOC(val, 17) |
545 | *loc = (*loc & ~0x1f1ffd) | reassemble_17(val); | 572 | *loc = (*loc & ~0x1f1ffd) | reassemble_17(val); |
546 | break; | 573 | break; |
547 | case R_PARISC_PCREL22F: | 574 | case R_PARISC_PCREL22F: |
548 | /* 22-bit PC relative address; only defined for pa20 */ | 575 | /* 22-bit PC relative address; only defined for pa20 */ |
549 | val = get_stub(me, val, addend, 0, is_init(me, loc)); | 576 | val = get_stub(me, val, addend, ELF_STUB_GOT, is_init(me, loc)); |
550 | DEBUGP("STUB FOR %s loc %lx+%lx at %lx\n", | 577 | DEBUGP("STUB FOR %s loc %lx+%lx at %lx\n", |
551 | strtab + sym->st_name, (unsigned long)loc, addend, | 578 | strtab + sym->st_name, (unsigned long)loc, addend, |
552 | val) | 579 | val) |
@@ -643,13 +670,23 @@ int apply_relocate_add(Elf_Shdr *sechdrs, | |||
643 | strtab + sym->st_name, | 670 | strtab + sym->st_name, |
644 | loc, val); | 671 | loc, val); |
645 | /* can we reach it locally? */ | 672 | /* can we reach it locally? */ |
646 | if(!is_local(me, (void *)val)) { | 673 | if(!is_local_section(me, (void *)val, (void *)dot)) { |
647 | if (strncmp(strtab + sym->st_name, "$$", 2) | 674 | |
675 | if (is_local(me, (void *)val)) | ||
676 | /* this is the case where the | ||
677 | * symbol is local to the | ||
678 | * module, but in a different | ||
679 | * section, so stub the jump | ||
680 | * in case it's more than 22 | ||
681 | * bits away */ | ||
682 | val = get_stub(me, val, addend, ELF_STUB_DIRECT, | ||
683 | is_init(me, loc)); | ||
684 | else if (strncmp(strtab + sym->st_name, "$$", 2) | ||
648 | == 0) | 685 | == 0) |
649 | val = get_stub(me, val, addend, 1, | 686 | val = get_stub(me, val, addend, ELF_STUB_MILLI, |
650 | is_init(me, loc)); | 687 | is_init(me, loc)); |
651 | else | 688 | else |
652 | val = get_stub(me, val, addend, 0, | 689 | val = get_stub(me, val, addend, ELF_STUB_GOT, |
653 | is_init(me, loc)); | 690 | is_init(me, loc)); |
654 | } | 691 | } |
655 | DEBUGP("STUB FOR %s loc %lx, val %lx+%lx at %lx\n", | 692 | DEBUGP("STUB FOR %s loc %lx, val %lx+%lx at %lx\n", |
diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c index 79c7db2705fd..7d6967ee367c 100644 --- a/arch/parisc/kernel/pci.c +++ b/arch/parisc/kernel/pci.c | |||
@@ -289,7 +289,7 @@ EXPORT_SYMBOL(pcibios_bus_to_resource); | |||
289 | * than res->start. | 289 | * than res->start. |
290 | */ | 290 | */ |
291 | void pcibios_align_resource(void *data, struct resource *res, | 291 | void pcibios_align_resource(void *data, struct resource *res, |
292 | unsigned long size, unsigned long alignment) | 292 | resource_size_t size, resource_size_t alignment) |
293 | { | 293 | { |
294 | unsigned long mask, align; | 294 | unsigned long mask, align; |
295 | 295 | ||
diff --git a/arch/parisc/kernel/pdc_chassis.c b/arch/parisc/kernel/pdc_chassis.c index a45e2e2ffd9f..d47ba1aa8253 100644 --- a/arch/parisc/kernel/pdc_chassis.c +++ b/arch/parisc/kernel/pdc_chassis.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * interfaces to log Chassis Codes via PDC (firmware) | 2 | * interfaces to Chassis Codes via PDC (firmware) |
3 | * | 3 | * |
4 | * Copyright (C) 2002 Laurent Canet <canetl@esiee.fr> | 4 | * Copyright (C) 2002 Laurent Canet <canetl@esiee.fr> |
5 | * Copyright (C) 2002-2004 Thibaut VARENE <varenet@parisc-linux.org> | 5 | * Copyright (C) 2002-2006 Thibaut VARENE <varenet@parisc-linux.org> |
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 |
@@ -16,6 +16,10 @@ | |||
16 | * You should have received a copy of the GNU General Public License | 16 | * You should have received a copy of the GNU General Public License |
17 | * along with this program; if not, write to the Free Software | 17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | * | ||
20 | * TODO: poll chassis warns, trigger (configurable) machine shutdown when | ||
21 | * needed. | ||
22 | * Find out how to get Chassis warnings out of PAT boxes? | ||
19 | */ | 23 | */ |
20 | 24 | ||
21 | #undef PDC_CHASSIS_DEBUG | 25 | #undef PDC_CHASSIS_DEBUG |
@@ -30,15 +34,16 @@ | |||
30 | #include <linux/reboot.h> | 34 | #include <linux/reboot.h> |
31 | #include <linux/notifier.h> | 35 | #include <linux/notifier.h> |
32 | #include <linux/cache.h> | 36 | #include <linux/cache.h> |
37 | #include <linux/proc_fs.h> | ||
33 | 38 | ||
34 | #include <asm/pdc_chassis.h> | 39 | #include <asm/pdc_chassis.h> |
35 | #include <asm/processor.h> | 40 | #include <asm/processor.h> |
36 | #include <asm/pdc.h> | 41 | #include <asm/pdc.h> |
37 | #include <asm/pdcpat.h> | 42 | #include <asm/pdcpat.h> |
38 | 43 | ||
44 | #define PDC_CHASSIS_VER "0.05" | ||
39 | 45 | ||
40 | #ifdef CONFIG_PDC_CHASSIS | 46 | #ifdef CONFIG_PDC_CHASSIS |
41 | static int pdc_chassis_old __read_mostly = 0; | ||
42 | static unsigned int pdc_chassis_enabled __read_mostly = 1; | 47 | static unsigned int pdc_chassis_enabled __read_mostly = 1; |
43 | 48 | ||
44 | 49 | ||
@@ -64,7 +69,7 @@ __setup("pdcchassis=", pdc_chassis_setup); | |||
64 | * Currently, only E class and A180 are known to work with this. | 69 | * Currently, only E class and A180 are known to work with this. |
65 | * Inspired by Christoph Plattner | 70 | * Inspired by Christoph Plattner |
66 | */ | 71 | */ |
67 | 72 | #if 0 | |
68 | static void __init pdc_chassis_checkold(void) | 73 | static void __init pdc_chassis_checkold(void) |
69 | { | 74 | { |
70 | switch(CPU_HVERSION) { | 75 | switch(CPU_HVERSION) { |
@@ -73,7 +78,6 @@ static void __init pdc_chassis_checkold(void) | |||
73 | case 0x482: /* E45 */ | 78 | case 0x482: /* E45 */ |
74 | case 0x483: /* E55 */ | 79 | case 0x483: /* E55 */ |
75 | case 0x516: /* A180 */ | 80 | case 0x516: /* A180 */ |
76 | pdc_chassis_old = 1; | ||
77 | break; | 81 | break; |
78 | 82 | ||
79 | default: | 83 | default: |
@@ -81,7 +85,7 @@ static void __init pdc_chassis_checkold(void) | |||
81 | } | 85 | } |
82 | DPRINTK(KERN_DEBUG "%s: pdc_chassis_checkold(); pdc_chassis_old = %d\n", __FILE__, pdc_chassis_old); | 86 | DPRINTK(KERN_DEBUG "%s: pdc_chassis_checkold(); pdc_chassis_old = %d\n", __FILE__, pdc_chassis_old); |
83 | } | 87 | } |
84 | 88 | #endif | |
85 | 89 | ||
86 | /** | 90 | /** |
87 | * pdc_chassis_panic_event() - Called by the panic handler. | 91 | * pdc_chassis_panic_event() - Called by the panic handler. |
@@ -131,30 +135,20 @@ static struct notifier_block pdc_chassis_reboot_block = { | |||
131 | void __init parisc_pdc_chassis_init(void) | 135 | void __init parisc_pdc_chassis_init(void) |
132 | { | 136 | { |
133 | #ifdef CONFIG_PDC_CHASSIS | 137 | #ifdef CONFIG_PDC_CHASSIS |
134 | int handle = 0; | ||
135 | if (likely(pdc_chassis_enabled)) { | 138 | if (likely(pdc_chassis_enabled)) { |
136 | DPRINTK(KERN_DEBUG "%s: parisc_pdc_chassis_init()\n", __FILE__); | 139 | DPRINTK(KERN_DEBUG "%s: parisc_pdc_chassis_init()\n", __FILE__); |
137 | 140 | ||
138 | /* Let see if we have something to handle... */ | 141 | /* Let see if we have something to handle... */ |
139 | /* Check for PDC_PAT or old LED Panel */ | 142 | printk(KERN_INFO "Enabling %s chassis codes support v%s\n", |
140 | pdc_chassis_checkold(); | 143 | is_pdc_pat() ? "PDC_PAT" : "regular", |
141 | if (is_pdc_pat()) { | 144 | PDC_CHASSIS_VER); |
142 | printk(KERN_INFO "Enabling PDC_PAT chassis codes support.\n"); | 145 | |
143 | handle = 1; | 146 | /* initialize panic notifier chain */ |
144 | } | 147 | atomic_notifier_chain_register(&panic_notifier_list, |
145 | else if (unlikely(pdc_chassis_old)) { | 148 | &pdc_chassis_panic_block); |
146 | printk(KERN_INFO "Enabling old style chassis LED panel support.\n"); | 149 | |
147 | handle = 1; | 150 | /* initialize reboot notifier chain */ |
148 | } | 151 | register_reboot_notifier(&pdc_chassis_reboot_block); |
149 | |||
150 | if (handle) { | ||
151 | /* initialize panic notifier chain */ | ||
152 | atomic_notifier_chain_register(&panic_notifier_list, | ||
153 | &pdc_chassis_panic_block); | ||
154 | |||
155 | /* initialize reboot notifier chain */ | ||
156 | register_reboot_notifier(&pdc_chassis_reboot_block); | ||
157 | } | ||
158 | } | 152 | } |
159 | #endif /* CONFIG_PDC_CHASSIS */ | 153 | #endif /* CONFIG_PDC_CHASSIS */ |
160 | } | 154 | } |
@@ -215,9 +209,12 @@ int pdc_chassis_send_status(int message) | |||
215 | } | 209 | } |
216 | } else retval = -1; | 210 | } else retval = -1; |
217 | #else | 211 | #else |
218 | if (unlikely(pdc_chassis_old)) { | 212 | if (1) { |
219 | switch (message) { | 213 | switch (message) { |
220 | case PDC_CHASSIS_DIRECT_BSTART: | 214 | case PDC_CHASSIS_DIRECT_BSTART: |
215 | retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_INIT)); | ||
216 | break; | ||
217 | |||
221 | case PDC_CHASSIS_DIRECT_BCOMPLETE: | 218 | case PDC_CHASSIS_DIRECT_BCOMPLETE: |
222 | retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_RUN)); | 219 | retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_RUN)); |
223 | break; | 220 | break; |
@@ -244,3 +241,61 @@ int pdc_chassis_send_status(int message) | |||
244 | #endif /* CONFIG_PDC_CHASSIS */ | 241 | #endif /* CONFIG_PDC_CHASSIS */ |
245 | return retval; | 242 | return retval; |
246 | } | 243 | } |
244 | |||
245 | #ifdef CONFIG_PDC_CHASSIS_WARN | ||
246 | #ifdef CONFIG_PROC_FS | ||
247 | static int pdc_chassis_warn_pread(char *page, char **start, off_t off, | ||
248 | int count, int *eof, void *data) | ||
249 | { | ||
250 | char *out = page; | ||
251 | int len, ret; | ||
252 | unsigned long warn; | ||
253 | u32 warnreg; | ||
254 | |||
255 | ret = pdc_chassis_warn(&warn); | ||
256 | if (ret != PDC_OK) | ||
257 | return -EIO; | ||
258 | |||
259 | warnreg = (warn & 0xFFFFFFFF); | ||
260 | |||
261 | if ((warnreg >> 24) & 0xFF) | ||
262 | out += sprintf(out, "Chassis component failure! (eg fan or PSU): 0x%.2x\n", ((warnreg >> 24) & 0xFF)); | ||
263 | |||
264 | out += sprintf(out, "Battery: %s\n", (warnreg & 0x04) ? "Low!" : "OK"); | ||
265 | out += sprintf(out, "Temp low: %s\n", (warnreg & 0x02) ? "Exceeded!" : "OK"); | ||
266 | out += sprintf(out, "Temp mid: %s\n", (warnreg & 0x01) ? "Exceeded!" : "OK"); | ||
267 | |||
268 | len = out - page - off; | ||
269 | if (len < count) { | ||
270 | *eof = 1; | ||
271 | if (len <= 0) return 0; | ||
272 | } else { | ||
273 | len = count; | ||
274 | } | ||
275 | *start = page + off; | ||
276 | return len; | ||
277 | } | ||
278 | |||
279 | static int __init pdc_chassis_create_procfs(void) | ||
280 | { | ||
281 | unsigned long test; | ||
282 | int ret; | ||
283 | |||
284 | ret = pdc_chassis_warn(&test); | ||
285 | if ((ret == PDC_BAD_PROC) || (ret == PDC_BAD_OPTION)) { | ||
286 | /* seems that some boxes (eg L1000) do not implement this */ | ||
287 | printk(KERN_INFO "Chassis warnings not supported.\n"); | ||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | printk(KERN_INFO "Enabling PDC chassis warnings support v%s\n", | ||
292 | PDC_CHASSIS_VER); | ||
293 | create_proc_read_entry("chassis", 0400, NULL, pdc_chassis_warn_pread, | ||
294 | NULL); | ||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | __initcall(pdc_chassis_create_procfs); | ||
299 | |||
300 | #endif /* CONFIG_PROC_FS */ | ||
301 | #endif /* CONFIG_PDC_CHASSIS_WARN */ | ||
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c index 413292f1a4a3..3f28de974556 100644 --- a/arch/parisc/kernel/ptrace.c +++ b/arch/parisc/kernel/ptrace.c | |||
@@ -91,7 +91,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
91 | int copied; | 91 | int copied; |
92 | 92 | ||
93 | #ifdef __LP64__ | 93 | #ifdef __LP64__ |
94 | if (personality(child->personality) == PER_LINUX32) { | 94 | if (__is_compat_task(child)) { |
95 | unsigned int tmp; | 95 | unsigned int tmp; |
96 | 96 | ||
97 | addr &= 0xffffffffL; | 97 | addr &= 0xffffffffL; |
@@ -123,7 +123,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
123 | case PTRACE_POKEDATA: | 123 | case PTRACE_POKEDATA: |
124 | ret = 0; | 124 | ret = 0; |
125 | #ifdef __LP64__ | 125 | #ifdef __LP64__ |
126 | if (personality(child->personality) == PER_LINUX32) { | 126 | if (__is_compat_task(child)) { |
127 | unsigned int tmp = (unsigned int)data; | 127 | unsigned int tmp = (unsigned int)data; |
128 | DBG("sys_ptrace(POKE%s, %d, %lx, %lx)\n", | 128 | DBG("sys_ptrace(POKE%s, %d, %lx, %lx)\n", |
129 | request == PTRACE_POKETEXT ? "TEXT" : "DATA", | 129 | request == PTRACE_POKETEXT ? "TEXT" : "DATA", |
@@ -146,7 +146,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
146 | case PTRACE_PEEKUSR: { | 146 | case PTRACE_PEEKUSR: { |
147 | ret = -EIO; | 147 | ret = -EIO; |
148 | #ifdef __LP64__ | 148 | #ifdef __LP64__ |
149 | if (personality(child->personality) == PER_LINUX32) { | 149 | if (__is_compat_task(child)) { |
150 | unsigned int tmp; | 150 | unsigned int tmp; |
151 | 151 | ||
152 | if (addr & (sizeof(int)-1)) | 152 | if (addr & (sizeof(int)-1)) |
@@ -205,7 +205,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
205 | goto out_tsk; | 205 | goto out_tsk; |
206 | } | 206 | } |
207 | #ifdef __LP64__ | 207 | #ifdef __LP64__ |
208 | if (personality(child->personality) == PER_LINUX32) { | 208 | if (__is_compat_task(child)) { |
209 | if (addr & (sizeof(int)-1)) | 209 | if (addr & (sizeof(int)-1)) |
210 | goto out_tsk; | 210 | goto out_tsk; |
211 | if ((addr = translate_usr_offset(addr)) < 0) | 211 | if ((addr = translate_usr_offset(addr)) < 0) |
diff --git a/arch/parisc/kernel/real2.S b/arch/parisc/kernel/real2.S index 8c2859cca77e..453d01a9f971 100644 --- a/arch/parisc/kernel/real2.S +++ b/arch/parisc/kernel/real2.S | |||
@@ -276,15 +276,6 @@ r64_ret: | |||
276 | 276 | ||
277 | #endif | 277 | #endif |
278 | 278 | ||
279 | .export pc_in_user_space | ||
280 | .text | ||
281 | /* Doesn't belong here but I couldn't find a nicer spot. */ | ||
282 | /* Should never get called, only used by profile stuff in time.c */ | ||
283 | pc_in_user_space: | ||
284 | bv,n 0(%rp) | ||
285 | nop | ||
286 | |||
287 | |||
288 | .export __canonicalize_funcptr_for_compare | 279 | .export __canonicalize_funcptr_for_compare |
289 | .text | 280 | .text |
290 | /* http://lists.parisc-linux.org/hypermail/parisc-linux/10916.html | 281 | /* http://lists.parisc-linux.org/hypermail/parisc-linux/10916.html |
diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c index 4a36ec3f6ac1..278f4b9f6a38 100644 --- a/arch/parisc/kernel/setup.c +++ b/arch/parisc/kernel/setup.c | |||
@@ -303,6 +303,8 @@ extern void eisa_init(void); | |||
303 | 303 | ||
304 | static int __init parisc_init(void) | 304 | static int __init parisc_init(void) |
305 | { | 305 | { |
306 | u32 osid = (OS_ID_LINUX << 16); | ||
307 | |||
306 | parisc_proc_mkdir(); | 308 | parisc_proc_mkdir(); |
307 | parisc_init_resources(); | 309 | parisc_init_resources(); |
308 | do_device_inventory(); /* probe for hardware */ | 310 | do_device_inventory(); /* probe for hardware */ |
@@ -311,6 +313,9 @@ static int __init parisc_init(void) | |||
311 | 313 | ||
312 | /* set up a new led state on systems shipped LED State panel */ | 314 | /* set up a new led state on systems shipped LED State panel */ |
313 | pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BSTART); | 315 | pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BSTART); |
316 | |||
317 | /* tell PDC we're Linux. Nevermind failure. */ | ||
318 | pdc_stable_write(0x40, &osid, sizeof(osid)); | ||
314 | 319 | ||
315 | processor_init(); | 320 | processor_init(); |
316 | printk(KERN_INFO "CPU(s): %d x %s at %d.%06d MHz\n", | 321 | printk(KERN_INFO "CPU(s): %d x %s at %d.%06d MHz\n", |
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c index cc38edfd90c5..bb83880c5ee3 100644 --- a/arch/parisc/kernel/signal.c +++ b/arch/parisc/kernel/signal.c | |||
@@ -76,7 +76,7 @@ sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs *r | |||
76 | #ifdef __LP64__ | 76 | #ifdef __LP64__ |
77 | compat_sigset_t newset32; | 77 | compat_sigset_t newset32; |
78 | 78 | ||
79 | if(personality(current->personality) == PER_LINUX32){ | 79 | if (is_compat_task()) { |
80 | /* XXX: Don't preclude handling different sized sigset_t's. */ | 80 | /* XXX: Don't preclude handling different sized sigset_t's. */ |
81 | if (sigsetsize != sizeof(compat_sigset_t)) | 81 | if (sigsetsize != sizeof(compat_sigset_t)) |
82 | return -EINVAL; | 82 | return -EINVAL; |
@@ -153,7 +153,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall) | |||
153 | compat_sigset_t compat_set; | 153 | compat_sigset_t compat_set; |
154 | struct compat_rt_sigframe __user * compat_frame; | 154 | struct compat_rt_sigframe __user * compat_frame; |
155 | 155 | ||
156 | if(personality(current->personality) == PER_LINUX32) | 156 | if (is_compat_task()) |
157 | sigframe_size = PARISC_RT_SIGFRAME_SIZE32; | 157 | sigframe_size = PARISC_RT_SIGFRAME_SIZE32; |
158 | #endif | 158 | #endif |
159 | 159 | ||
@@ -166,7 +166,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall) | |||
166 | #ifdef __LP64__ | 166 | #ifdef __LP64__ |
167 | compat_frame = (struct compat_rt_sigframe __user *)frame; | 167 | compat_frame = (struct compat_rt_sigframe __user *)frame; |
168 | 168 | ||
169 | if(personality(current->personality) == PER_LINUX32){ | 169 | if (is_compat_task()) { |
170 | DBG(2,"sys_rt_sigreturn: ELF32 process.\n"); | 170 | DBG(2,"sys_rt_sigreturn: ELF32 process.\n"); |
171 | if (__copy_from_user(&compat_set, &compat_frame->uc.uc_sigmask, sizeof(compat_set))) | 171 | if (__copy_from_user(&compat_set, &compat_frame->uc.uc_sigmask, sizeof(compat_set))) |
172 | goto give_sigsegv; | 172 | goto give_sigsegv; |
@@ -186,7 +186,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall) | |||
186 | 186 | ||
187 | /* Good thing we saved the old gr[30], eh? */ | 187 | /* Good thing we saved the old gr[30], eh? */ |
188 | #ifdef __LP64__ | 188 | #ifdef __LP64__ |
189 | if(personality(current->personality) == PER_LINUX32){ | 189 | if (is_compat_task()) { |
190 | DBG(1,"sys_rt_sigreturn: compat_frame->uc.uc_mcontext 0x%p\n", | 190 | DBG(1,"sys_rt_sigreturn: compat_frame->uc.uc_mcontext 0x%p\n", |
191 | &compat_frame->uc.uc_mcontext); | 191 | &compat_frame->uc.uc_mcontext); |
192 | // FIXME: Load upper half from register file | 192 | // FIXME: Load upper half from register file |
@@ -315,7 +315,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
315 | 315 | ||
316 | compat_frame = (struct compat_rt_sigframe __user *)frame; | 316 | compat_frame = (struct compat_rt_sigframe __user *)frame; |
317 | 317 | ||
318 | if(personality(current->personality) == PER_LINUX32) { | 318 | if (is_compat_task()) { |
319 | DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info); | 319 | DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info); |
320 | err |= copy_siginfo_to_user32(&compat_frame->info, info); | 320 | err |= copy_siginfo_to_user32(&compat_frame->info, info); |
321 | DBG(1,"SETUP_RT_FRAME: 1\n"); | 321 | DBG(1,"SETUP_RT_FRAME: 1\n"); |
@@ -392,7 +392,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
392 | haddr = A(ka->sa.sa_handler); | 392 | haddr = A(ka->sa.sa_handler); |
393 | /* The sa_handler may be a pointer to a function descriptor */ | 393 | /* The sa_handler may be a pointer to a function descriptor */ |
394 | #ifdef __LP64__ | 394 | #ifdef __LP64__ |
395 | if(personality(current->personality) == PER_LINUX32) { | 395 | if (is_compat_task()) { |
396 | #endif | 396 | #endif |
397 | if (haddr & PA_PLABEL_FDESC) { | 397 | if (haddr & PA_PLABEL_FDESC) { |
398 | Elf32_Fdesc fdesc; | 398 | Elf32_Fdesc fdesc; |
@@ -427,19 +427,19 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
427 | */ | 427 | */ |
428 | sigframe_size = PARISC_RT_SIGFRAME_SIZE; | 428 | sigframe_size = PARISC_RT_SIGFRAME_SIZE; |
429 | #ifdef __LP64__ | 429 | #ifdef __LP64__ |
430 | if(personality(current->personality) == PER_LINUX32) | 430 | if (is_compat_task()) |
431 | sigframe_size = PARISC_RT_SIGFRAME_SIZE32; | 431 | sigframe_size = PARISC_RT_SIGFRAME_SIZE32; |
432 | #endif | 432 | #endif |
433 | if (in_syscall) { | 433 | if (in_syscall) { |
434 | regs->gr[31] = haddr; | 434 | regs->gr[31] = haddr; |
435 | #ifdef __LP64__ | 435 | #ifdef __LP64__ |
436 | if(personality(current->personality) == PER_LINUX) | 436 | if (personality(current->personality) == PER_LINUX) |
437 | sigframe_size |= 1; | 437 | sigframe_size |= 1; |
438 | #endif | 438 | #endif |
439 | } else { | 439 | } else { |
440 | unsigned long psw = USER_PSW; | 440 | unsigned long psw = USER_PSW; |
441 | #ifdef __LP64__ | 441 | #ifdef __LP64__ |
442 | if(personality(current->personality) == PER_LINUX) | 442 | if (personality(current->personality) == PER_LINUX) |
443 | psw |= PSW_W; | 443 | psw |= PSW_W; |
444 | #endif | 444 | #endif |
445 | 445 | ||
@@ -464,7 +464,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
464 | regs->gr[26] = sig; /* signal number */ | 464 | regs->gr[26] = sig; /* signal number */ |
465 | 465 | ||
466 | #ifdef __LP64__ | 466 | #ifdef __LP64__ |
467 | if(personality(current->personality) == PER_LINUX32){ | 467 | if (is_compat_task()) { |
468 | regs->gr[25] = A(&compat_frame->info); /* siginfo pointer */ | 468 | regs->gr[25] = A(&compat_frame->info); /* siginfo pointer */ |
469 | regs->gr[24] = A(&compat_frame->uc); /* ucontext pointer */ | 469 | regs->gr[24] = A(&compat_frame->uc); /* ucontext pointer */ |
470 | } else | 470 | } else |
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index 479d9a017cd1..9670a89c77fe 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S | |||
@@ -29,18 +29,6 @@ | |||
29 | .level 1.1 | 29 | .level 1.1 |
30 | #endif | 30 | #endif |
31 | 31 | ||
32 | #ifndef CONFIG_64BIT | ||
33 | .macro fixup_branch,lbl | ||
34 | b \lbl | ||
35 | .endm | ||
36 | #else | ||
37 | .macro fixup_branch,lbl | ||
38 | ldil L%\lbl, %r1 | ||
39 | ldo R%\lbl(%r1), %r1 | ||
40 | bv,n %r0(%r1) | ||
41 | .endm | ||
42 | #endif | ||
43 | |||
44 | .text | 32 | .text |
45 | 33 | ||
46 | .import syscall_exit,code | 34 | .import syscall_exit,code |
@@ -541,7 +529,7 @@ cas_nocontend: | |||
541 | # endif | 529 | # endif |
542 | /* ENABLE_LWS_DEBUG */ | 530 | /* ENABLE_LWS_DEBUG */ |
543 | 531 | ||
544 | ldcw 0(%sr2,%r20), %r28 /* Try to acquire the lock */ | 532 | LDCW 0(%sr2,%r20), %r28 /* Try to acquire the lock */ |
545 | cmpb,<>,n %r0, %r28, cas_action /* Did we get it? */ | 533 | cmpb,<>,n %r0, %r28, cas_action /* Did we get it? */ |
546 | cas_wouldblock: | 534 | cas_wouldblock: |
547 | ldo 2(%r0), %r28 /* 2nd case */ | 535 | ldo 2(%r0), %r28 /* 2nd case */ |
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index 594930bc4bcf..eb35e1c0bb53 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c | |||
@@ -157,8 +157,22 @@ do_gettimeofday (struct timeval *tv) | |||
157 | usec += (xtime.tv_nsec / 1000); | 157 | usec += (xtime.tv_nsec / 1000); |
158 | } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); | 158 | } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); |
159 | 159 | ||
160 | while (usec >= 1000000) { | 160 | if (unlikely(usec > LONG_MAX)) { |
161 | usec -= 1000000; | 161 | /* This can happen if the gettimeoffset adjustment is |
162 | * negative and xtime.tv_nsec is smaller than the | ||
163 | * adjustment */ | ||
164 | printk(KERN_ERR "do_gettimeofday() spurious xtime.tv_nsec of %ld\n", usec); | ||
165 | usec += USEC_PER_SEC; | ||
166 | --sec; | ||
167 | /* This should never happen, it means the negative | ||
168 | * time adjustment was more than a second, so there's | ||
169 | * something seriously wrong */ | ||
170 | BUG_ON(usec > LONG_MAX); | ||
171 | } | ||
172 | |||
173 | |||
174 | while (usec >= USEC_PER_SEC) { | ||
175 | usec -= USEC_PER_SEC; | ||
162 | ++sec; | 176 | ++sec; |
163 | } | 177 | } |
164 | 178 | ||
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index ff200608c851..348344a84bf7 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c | |||
@@ -66,57 +66,42 @@ int printbinary(char *buf, unsigned long x, int nbits) | |||
66 | #else | 66 | #else |
67 | #define RFMT "%08lx" | 67 | #define RFMT "%08lx" |
68 | #endif | 68 | #endif |
69 | #define FFMT "%016llx" /* fpregs are 64-bit always */ | ||
69 | 70 | ||
70 | void show_regs(struct pt_regs *regs) | 71 | #define PRINTREGS(lvl,r,f,fmt,x) \ |
72 | printk("%s%s%02d-%02d " fmt " " fmt " " fmt " " fmt "\n", \ | ||
73 | lvl, f, (x), (x+3), (r)[(x)+0], (r)[(x)+1], \ | ||
74 | (r)[(x)+2], (r)[(x)+3]) | ||
75 | |||
76 | static void print_gr(char *level, struct pt_regs *regs) | ||
71 | { | 77 | { |
72 | int i; | 78 | int i; |
73 | char buf[128], *p; | 79 | char buf[64]; |
74 | char *level; | ||
75 | unsigned long cr30; | ||
76 | unsigned long cr31; | ||
77 | /* carlos says that gcc understands better memory in a struct, | ||
78 | * and it makes our life easier with fpregs -- T-Bone */ | ||
79 | struct { u32 sw[2]; } s; | ||
80 | |||
81 | level = user_mode(regs) ? KERN_DEBUG : KERN_CRIT; | ||
82 | |||
83 | printk("%s\n", level); /* don't want to have that pretty register dump messed up */ | ||
84 | 80 | ||
81 | printk("%s\n", level); | ||
85 | printk("%s YZrvWESTHLNXBCVMcbcbcbcbOGFRQPDI\n", level); | 82 | printk("%s YZrvWESTHLNXBCVMcbcbcbcbOGFRQPDI\n", level); |
86 | printbinary(buf, regs->gr[0], 32); | 83 | printbinary(buf, regs->gr[0], 32); |
87 | printk("%sPSW: %s %s\n", level, buf, print_tainted()); | 84 | printk("%sPSW: %s %s\n", level, buf, print_tainted()); |
88 | 85 | ||
89 | for (i = 0; i < 32; i += 4) { | 86 | for (i = 0; i < 32; i += 4) |
90 | int j; | 87 | PRINTREGS(level, regs->gr, "r", RFMT, i); |
91 | p = buf; | 88 | } |
92 | p += sprintf(p, "%sr%02d-%02d ", level, i, i + 3); | ||
93 | for (j = 0; j < 4; j++) { | ||
94 | p += sprintf(p, " " RFMT, (i+j) == 0 ? 0 : regs->gr[i + j]); | ||
95 | } | ||
96 | printk("%s\n", buf); | ||
97 | } | ||
98 | 89 | ||
99 | for (i = 0; i < 8; i += 4) { | 90 | static void print_fr(char *level, struct pt_regs *regs) |
100 | int j; | 91 | { |
101 | p = buf; | 92 | int i; |
102 | p += sprintf(p, "%ssr%d-%d ", level, i, i + 3); | 93 | char buf[64]; |
103 | for (j = 0; j < 4; j++) { | 94 | struct { u32 sw[2]; } s; |
104 | p += sprintf(p, " " RFMT, regs->sr[i + j]); | ||
105 | } | ||
106 | printk("%s\n", buf); | ||
107 | } | ||
108 | 95 | ||
109 | /* FR are 64bit everywhere. Need to use asm to get the content | 96 | /* FR are 64bit everywhere. Need to use asm to get the content |
110 | * of fpsr/fper1, and we assume that we won't have a FP Identify | 97 | * of fpsr/fper1, and we assume that we won't have a FP Identify |
111 | * in our way, otherwise we're screwed. | 98 | * in our way, otherwise we're screwed. |
112 | * The fldd is used to restore the T-bit if there was one, as the | 99 | * The fldd is used to restore the T-bit if there was one, as the |
113 | * store clears it anyway. | 100 | * store clears it anyway. |
114 | * BTW, PA2.0 book says "thou shall not use fstw on FPSR/FPERs". */ | 101 | * PA2.0 book says "thou shall not use fstw on FPSR/FPERs" - T-Bone */ |
115 | __asm__ ( | 102 | asm volatile ("fstd %%fr0,0(%1) \n\t" |
116 | "fstd %%fr0,0(%1) \n\t" | 103 | "fldd 0(%1),%%fr0 \n\t" |
117 | "fldd 0(%1),%%fr0 \n\t" | 104 | : "=m" (s) : "r" (&s) : "r0"); |
118 | : "=m" (s) : "r" (&s) : "%r0" | ||
119 | ); | ||
120 | 105 | ||
121 | printk("%s\n", level); | 106 | printk("%s\n", level); |
122 | printk("%s VZOUICununcqcqcqcqcqcrmunTDVZOUI\n", level); | 107 | printk("%s VZOUICununcqcqcqcqcqcrmunTDVZOUI\n", level); |
@@ -125,14 +110,25 @@ void show_regs(struct pt_regs *regs) | |||
125 | printk("%sFPER1: %08x\n", level, s.sw[1]); | 110 | printk("%sFPER1: %08x\n", level, s.sw[1]); |
126 | 111 | ||
127 | /* here we'll print fr0 again, tho it'll be meaningless */ | 112 | /* here we'll print fr0 again, tho it'll be meaningless */ |
128 | for (i = 0; i < 32; i += 4) { | 113 | for (i = 0; i < 32; i += 4) |
129 | int j; | 114 | PRINTREGS(level, regs->fr, "fr", FFMT, i); |
130 | p = buf; | 115 | } |
131 | p += sprintf(p, "%sfr%02d-%02d ", level, i, i + 3); | 116 | |
132 | for (j = 0; j < 4; j++) | 117 | void show_regs(struct pt_regs *regs) |
133 | p += sprintf(p, " %016llx", (i+j) == 0 ? 0 : regs->fr[i+j]); | 118 | { |
134 | printk("%s\n", buf); | 119 | int i; |
135 | } | 120 | char *level; |
121 | unsigned long cr30, cr31; | ||
122 | |||
123 | level = user_mode(regs) ? KERN_DEBUG : KERN_CRIT; | ||
124 | |||
125 | print_gr(level, regs); | ||
126 | |||
127 | for (i = 0; i < 8; i += 4) | ||
128 | PRINTREGS(level, regs->sr, "sr", RFMT, i); | ||
129 | |||
130 | if (user_mode(regs)) | ||
131 | print_fr(level, regs); | ||
136 | 132 | ||
137 | cr30 = mfctl(30); | 133 | cr30 = mfctl(30); |
138 | cr31 = mfctl(31); | 134 | cr31 = mfctl(31); |
diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c index de0a1b21cb40..92328fbddb3e 100644 --- a/arch/parisc/kernel/unaligned.c +++ b/arch/parisc/kernel/unaligned.c | |||
@@ -43,6 +43,8 @@ | |||
43 | "\tldil L%%" #lbl ", %%r1\n" \ | 43 | "\tldil L%%" #lbl ", %%r1\n" \ |
44 | "\tldo R%%" #lbl "(%%r1), %%r1\n" \ | 44 | "\tldo R%%" #lbl "(%%r1), %%r1\n" \ |
45 | "\tbv,n %%r0(%%r1)\n" | 45 | "\tbv,n %%r0(%%r1)\n" |
46 | /* If you use FIXUP_BRANCH, then you must list this clobber */ | ||
47 | #define FIXUP_BRANCH_CLOBBER "r1" | ||
46 | 48 | ||
47 | /* 1111 1100 0000 0000 0001 0011 1100 0000 */ | 49 | /* 1111 1100 0000 0000 0001 0011 1100 0000 */ |
48 | #define OPCODE1(a,b,c) ((a)<<26|(b)<<12|(c)<<6) | 50 | #define OPCODE1(a,b,c) ((a)<<26|(b)<<12|(c)<<6) |
@@ -157,7 +159,7 @@ static int emulate_ldh(struct pt_regs *regs, int toreg) | |||
157 | " .previous\n" | 159 | " .previous\n" |
158 | : "=r" (val), "=r" (ret) | 160 | : "=r" (val), "=r" (ret) |
159 | : "0" (val), "r" (saddr), "r" (regs->isr) | 161 | : "0" (val), "r" (saddr), "r" (regs->isr) |
160 | : "r20" ); | 162 | : "r20", FIXUP_BRANCH_CLOBBER ); |
161 | 163 | ||
162 | DPRINTF("val = 0x" RFMT "\n", val); | 164 | DPRINTF("val = 0x" RFMT "\n", val); |
163 | 165 | ||
@@ -202,7 +204,7 @@ static int emulate_ldw(struct pt_regs *regs, int toreg, int flop) | |||
202 | " .previous\n" | 204 | " .previous\n" |
203 | : "=r" (val), "=r" (ret) | 205 | : "=r" (val), "=r" (ret) |
204 | : "0" (val), "r" (saddr), "r" (regs->isr) | 206 | : "0" (val), "r" (saddr), "r" (regs->isr) |
205 | : "r19", "r20" ); | 207 | : "r19", "r20", FIXUP_BRANCH_CLOBBER ); |
206 | 208 | ||
207 | DPRINTF("val = 0x" RFMT "\n", val); | 209 | DPRINTF("val = 0x" RFMT "\n", val); |
208 | 210 | ||
@@ -253,7 +255,7 @@ static int emulate_ldd(struct pt_regs *regs, int toreg, int flop) | |||
253 | " .previous\n" | 255 | " .previous\n" |
254 | : "=r" (val), "=r" (ret) | 256 | : "=r" (val), "=r" (ret) |
255 | : "0" (val), "r" (saddr), "r" (regs->isr) | 257 | : "0" (val), "r" (saddr), "r" (regs->isr) |
256 | : "r19", "r20" ); | 258 | : "r19", "r20", FIXUP_BRANCH_CLOBBER ); |
257 | #else | 259 | #else |
258 | { | 260 | { |
259 | unsigned long valh=0,vall=0; | 261 | unsigned long valh=0,vall=0; |
@@ -287,7 +289,7 @@ static int emulate_ldd(struct pt_regs *regs, int toreg, int flop) | |||
287 | " .previous\n" | 289 | " .previous\n" |
288 | : "=r" (valh), "=r" (vall), "=r" (ret) | 290 | : "=r" (valh), "=r" (vall), "=r" (ret) |
289 | : "0" (valh), "1" (vall), "r" (saddr), "r" (regs->isr) | 291 | : "0" (valh), "1" (vall), "r" (saddr), "r" (regs->isr) |
290 | : "r19", "r20" ); | 292 | : "r19", "r20", FIXUP_BRANCH_CLOBBER ); |
291 | val=((__u64)valh<<32)|(__u64)vall; | 293 | val=((__u64)valh<<32)|(__u64)vall; |
292 | } | 294 | } |
293 | #endif | 295 | #endif |
@@ -335,7 +337,7 @@ static int emulate_sth(struct pt_regs *regs, int frreg) | |||
335 | " .previous\n" | 337 | " .previous\n" |
336 | : "=r" (ret) | 338 | : "=r" (ret) |
337 | : "r" (val), "r" (regs->ior), "r" (regs->isr) | 339 | : "r" (val), "r" (regs->ior), "r" (regs->isr) |
338 | : "r19" ); | 340 | : "r19", FIXUP_BRANCH_CLOBBER ); |
339 | 341 | ||
340 | return ret; | 342 | return ret; |
341 | } | 343 | } |
@@ -389,7 +391,7 @@ static int emulate_stw(struct pt_regs *regs, int frreg, int flop) | |||
389 | " .previous\n" | 391 | " .previous\n" |
390 | : "=r" (ret) | 392 | : "=r" (ret) |
391 | : "r" (val), "r" (regs->ior), "r" (regs->isr) | 393 | : "r" (val), "r" (regs->ior), "r" (regs->isr) |
392 | : "r19", "r20", "r21", "r22", "r1" ); | 394 | : "r19", "r20", "r21", "r22", "r1", FIXUP_BRANCH_CLOBBER ); |
393 | 395 | ||
394 | return 0; | 396 | return 0; |
395 | } | 397 | } |
@@ -450,7 +452,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop) | |||
450 | " .previous\n" | 452 | " .previous\n" |
451 | : "=r" (ret) | 453 | : "=r" (ret) |
452 | : "r" (val), "r" (regs->ior), "r" (regs->isr) | 454 | : "r" (val), "r" (regs->ior), "r" (regs->isr) |
453 | : "r19", "r20", "r21", "r22", "r1" ); | 455 | : "r19", "r20", "r21", "r22", "r1", FIXUP_BRANCH_CLOBBER ); |
454 | #else | 456 | #else |
455 | { | 457 | { |
456 | unsigned long valh=(val>>32),vall=(val&0xffffffffl); | 458 | unsigned long valh=(val>>32),vall=(val&0xffffffffl); |
@@ -495,7 +497,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop) | |||
495 | " .previous\n" | 497 | " .previous\n" |
496 | : "=r" (ret) | 498 | : "=r" (ret) |
497 | : "r" (valh), "r" (vall), "r" (regs->ior), "r" (regs->isr) | 499 | : "r" (valh), "r" (vall), "r" (regs->ior), "r" (regs->isr) |
498 | : "r19", "r20", "r21", "r1" ); | 500 | : "r19", "r20", "r21", "r1", FIXUP_BRANCH_CLOBBER ); |
499 | } | 501 | } |
500 | #endif | 502 | #endif |
501 | 503 | ||
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index e922a88b2bad..2643dbc3f289 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -30,6 +30,10 @@ config GENERIC_HARDIRQS | |||
30 | bool | 30 | bool |
31 | default y | 31 | default y |
32 | 32 | ||
33 | config IRQ_PER_CPU | ||
34 | bool | ||
35 | default y | ||
36 | |||
33 | config RWSEM_GENERIC_SPINLOCK | 37 | config RWSEM_GENERIC_SPINLOCK |
34 | bool | 38 | bool |
35 | 39 | ||
@@ -336,7 +340,7 @@ config PPC_ISERIES | |||
336 | 340 | ||
337 | config EMBEDDED6xx | 341 | config EMBEDDED6xx |
338 | bool "Embedded 6xx/7xx/7xxx-based board" | 342 | bool "Embedded 6xx/7xx/7xxx-based board" |
339 | depends on PPC32 && BROKEN | 343 | depends on PPC32 && (BROKEN||BROKEN_ON_SMP) |
340 | 344 | ||
341 | config APUS | 345 | config APUS |
342 | bool "Amiga-APUS" | 346 | bool "Amiga-APUS" |
@@ -413,12 +417,17 @@ config PPC_CELL_NATIVE | |||
413 | default n | 417 | default n |
414 | 418 | ||
415 | config PPC_IBM_CELL_BLADE | 419 | config PPC_IBM_CELL_BLADE |
416 | bool " IBM Cell Blade" | 420 | bool "IBM Cell Blade" |
417 | depends on PPC_MULTIPLATFORM && PPC64 | 421 | depends on PPC_MULTIPLATFORM && PPC64 |
418 | select PPC_CELL_NATIVE | 422 | select PPC_CELL_NATIVE |
419 | select PPC_RTAS | 423 | select PPC_RTAS |
420 | select MMIO_NVRAM | 424 | select MMIO_NVRAM |
421 | select PPC_UDBG_16550 | 425 | select PPC_UDBG_16550 |
426 | select UDBG_RTAS_CONSOLE | ||
427 | |||
428 | config UDBG_RTAS_CONSOLE | ||
429 | bool | ||
430 | default n | ||
422 | 431 | ||
423 | config XICS | 432 | config XICS |
424 | depends on PPC_PSERIES | 433 | depends on PPC_PSERIES |
@@ -431,7 +440,8 @@ config U3_DART | |||
431 | default n | 440 | default n |
432 | 441 | ||
433 | config MPIC | 442 | config MPIC |
434 | depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE || PPC_CHRP | 443 | depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE || PPC_CHRP \ |
444 | || MPC7448HPC2 | ||
435 | bool | 445 | bool |
436 | default y | 446 | default y |
437 | 447 | ||
@@ -557,6 +567,13 @@ config TAU_AVERAGE | |||
557 | /proc/cpuinfo. | 567 | /proc/cpuinfo. |
558 | 568 | ||
559 | If in doubt, say N here. | 569 | If in doubt, say N here. |
570 | |||
571 | config PPC_TODC | ||
572 | depends on EMBEDDED6xx | ||
573 | bool "Generic Time-of-day Clock (TODC) support" | ||
574 | ---help--- | ||
575 | This adds support for many TODC/RTC chips. | ||
576 | |||
560 | endmenu | 577 | endmenu |
561 | 578 | ||
562 | source arch/powerpc/platforms/embedded6xx/Kconfig | 579 | source arch/powerpc/platforms/embedded6xx/Kconfig |
@@ -618,16 +635,19 @@ config HOTPLUG_CPU | |||
618 | 635 | ||
619 | Say N if you are unsure. | 636 | Say N if you are unsure. |
620 | 637 | ||
638 | config ARCH_ENABLE_MEMORY_HOTPLUG | ||
639 | def_bool y | ||
640 | |||
621 | config KEXEC | 641 | config KEXEC |
622 | bool "kexec system call (EXPERIMENTAL)" | 642 | bool "kexec system call (EXPERIMENTAL)" |
623 | depends on PPC_MULTIPLATFORM && EXPERIMENTAL | 643 | depends on PPC_MULTIPLATFORM && EXPERIMENTAL |
624 | help | 644 | help |
625 | kexec is a system call that implements the ability to shutdown your | 645 | kexec is a system call that implements the ability to shutdown your |
626 | current kernel, and to start another kernel. It is like a reboot | 646 | current kernel, and to start another kernel. It is like a reboot |
627 | but it is indepedent of the system firmware. And like a reboot | 647 | but it is independent of the system firmware. And like a reboot |
628 | you can start any kernel with it, not just Linux. | 648 | you can start any kernel with it, not just Linux. |
629 | 649 | ||
630 | The name comes from the similiarity to the exec system call. | 650 | The name comes from the similarity to the exec system call. |
631 | 651 | ||
632 | It is an ongoing process to be certain the hardware in a machine | 652 | It is an ongoing process to be certain the hardware in a machine |
633 | is properly shutdown, so do not be surprised if this code does not | 653 | is properly shutdown, so do not be surprised if this code does not |
@@ -794,7 +814,6 @@ config GENERIC_ISA_DMA | |||
794 | 814 | ||
795 | config PPC_I8259 | 815 | config PPC_I8259 |
796 | bool | 816 | bool |
797 | default y if MPC8641_HPCN | ||
798 | default n | 817 | default n |
799 | 818 | ||
800 | config PPC_INDIRECT_PCI | 819 | config PPC_INDIRECT_PCI |
@@ -817,7 +836,8 @@ config MCA | |||
817 | bool | 836 | bool |
818 | 837 | ||
819 | config PCI | 838 | config PCI |
820 | bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_86xx || PPC_MPC52xx || (EMBEDDED && PPC_ISERIES) | 839 | bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_MPC52xx || (EMBEDDED && PPC_ISERIES) \ |
840 | || MPC7448HPC2 | ||
821 | default y if !40x && !CPM2 && !8xx && !APUS && !PPC_83xx && !PPC_85xx && !PPC_86xx | 841 | default y if !40x && !CPM2 && !8xx && !APUS && !PPC_83xx && !PPC_85xx && !PPC_86xx |
822 | default PCI_PERMEDIA if !4xx && !CPM2 && !8xx && APUS | 842 | default PCI_PERMEDIA if !4xx && !CPM2 && !8xx && APUS |
823 | default PCI_QSPAN if !4xx && !CPM2 && 8xx | 843 | default PCI_QSPAN if !4xx && !CPM2 && 8xx |
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug index c69006ae8246..e29ef77d3b00 100644 --- a/arch/powerpc/Kconfig.debug +++ b/arch/powerpc/Kconfig.debug | |||
@@ -134,12 +134,19 @@ config PPC_EARLY_DEBUG_G5 | |||
134 | help | 134 | help |
135 | Select this to enable early debugging for Apple G5 machines. | 135 | Select this to enable early debugging for Apple G5 machines. |
136 | 136 | ||
137 | config PPC_EARLY_DEBUG_RTAS | 137 | config PPC_EARLY_DEBUG_RTAS_PANEL |
138 | bool "RTAS Panel" | 138 | bool "RTAS Panel" |
139 | depends on PPC_RTAS | 139 | depends on PPC_RTAS |
140 | help | 140 | help |
141 | Select this to enable early debugging via the RTAS panel. | 141 | Select this to enable early debugging via the RTAS panel. |
142 | 142 | ||
143 | config PPC_EARLY_DEBUG_RTAS_CONSOLE | ||
144 | bool "RTAS Console" | ||
145 | depends on PPC_RTAS | ||
146 | select UDBG_RTAS_CONSOLE | ||
147 | help | ||
148 | Select this to enable early debugging via the RTAS console. | ||
149 | |||
143 | config PPC_EARLY_DEBUG_MAPLE | 150 | config PPC_EARLY_DEBUG_MAPLE |
144 | bool "Maple real mode" | 151 | bool "Maple real mode" |
145 | depends on PPC_MAPLE | 152 | depends on PPC_MAPLE |
diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig index b8b8d4675dc0..e028a2ecb8a3 100644 --- a/arch/powerpc/configs/cell_defconfig +++ b/arch/powerpc/configs/cell_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.17 | 3 | # Linux kernel version: 2.6.17-rc6 |
4 | # Mon Jun 19 17:23:03 2006 | 4 | # Thu Jun 22 15:28:36 2006 |
5 | # | 5 | # |
6 | CONFIG_PPC64=y | 6 | CONFIG_PPC64=y |
7 | CONFIG_64BIT=y | 7 | CONFIG_64BIT=y |
@@ -1063,7 +1063,8 @@ CONFIG_DEBUG_FS=y | |||
1063 | # CONFIG_DEBUG_STACKOVERFLOW is not set | 1063 | # CONFIG_DEBUG_STACKOVERFLOW is not set |
1064 | # CONFIG_DEBUG_STACK_USAGE is not set | 1064 | # CONFIG_DEBUG_STACK_USAGE is not set |
1065 | CONFIG_DEBUGGER=y | 1065 | CONFIG_DEBUGGER=y |
1066 | # CONFIG_XMON is not set | 1066 | CONFIG_XMON=y |
1067 | CONFIG_XMON_DEFAULT=y | ||
1067 | CONFIG_IRQSTACKS=y | 1068 | CONFIG_IRQSTACKS=y |
1068 | # CONFIG_BOOTX_TEXT is not set | 1069 | # CONFIG_BOOTX_TEXT is not set |
1069 | # CONFIG_PPC_EARLY_DEBUG is not set | 1070 | # CONFIG_PPC_EARLY_DEBUG is not set |
diff --git a/arch/powerpc/configs/mpc7448_hpc2_defconfig b/arch/powerpc/configs/mpc7448_hpc2_defconfig new file mode 100644 index 000000000000..15a50f4ceb1f --- /dev/null +++ b/arch/powerpc/configs/mpc7448_hpc2_defconfig | |||
@@ -0,0 +1,923 @@ | |||
1 | # | ||
2 | # Automatically generated make config: don't edit | ||
3 | # Linux kernel version: 2.6.17-rc4 | ||
4 | # Sat May 27 18:45:55 2006 | ||
5 | # | ||
6 | # CONFIG_PPC64 is not set | ||
7 | CONFIG_PPC32=y | ||
8 | CONFIG_PPC_MERGE=y | ||
9 | CONFIG_MMU=y | ||
10 | CONFIG_GENERIC_HARDIRQS=y | ||
11 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y | ||
12 | CONFIG_GENERIC_HWEIGHT=y | ||
13 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
14 | CONFIG_PPC=y | ||
15 | CONFIG_EARLY_PRINTK=y | ||
16 | CONFIG_GENERIC_NVRAM=y | ||
17 | CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y | ||
18 | CONFIG_ARCH_MAY_HAVE_PC_FDC=y | ||
19 | CONFIG_PPC_OF=y | ||
20 | CONFIG_PPC_UDBG_16550=y | ||
21 | # CONFIG_GENERIC_TBSYNC is not set | ||
22 | CONFIG_DEFAULT_UIMAGE=y | ||
23 | |||
24 | # | ||
25 | # Processor support | ||
26 | # | ||
27 | CONFIG_CLASSIC32=y | ||
28 | # CONFIG_PPC_52xx is not set | ||
29 | # CONFIG_PPC_82xx is not set | ||
30 | # CONFIG_PPC_83xx is not set | ||
31 | # CONFIG_PPC_85xx is not set | ||
32 | # CONFIG_40x is not set | ||
33 | # CONFIG_44x is not set | ||
34 | # CONFIG_8xx is not set | ||
35 | # CONFIG_E200 is not set | ||
36 | CONFIG_6xx=y | ||
37 | CONFIG_PPC_FPU=y | ||
38 | # CONFIG_ALTIVEC is not set | ||
39 | CONFIG_PPC_STD_MMU=y | ||
40 | CONFIG_PPC_STD_MMU_32=y | ||
41 | # CONFIG_SMP is not set | ||
42 | |||
43 | # | ||
44 | # Code maturity level options | ||
45 | # | ||
46 | CONFIG_EXPERIMENTAL=y | ||
47 | CONFIG_BROKEN_ON_SMP=y | ||
48 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
49 | |||
50 | # | ||
51 | # General setup | ||
52 | # | ||
53 | CONFIG_LOCALVERSION="" | ||
54 | CONFIG_LOCALVERSION_AUTO=y | ||
55 | CONFIG_SWAP=y | ||
56 | CONFIG_SYSVIPC=y | ||
57 | # CONFIG_POSIX_MQUEUE is not set | ||
58 | # CONFIG_BSD_PROCESS_ACCT is not set | ||
59 | CONFIG_SYSCTL=y | ||
60 | # CONFIG_AUDIT is not set | ||
61 | # CONFIG_IKCONFIG is not set | ||
62 | # CONFIG_RELAY is not set | ||
63 | CONFIG_INITRAMFS_SOURCE="" | ||
64 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
65 | CONFIG_EMBEDDED=y | ||
66 | CONFIG_KALLSYMS=y | ||
67 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | ||
68 | CONFIG_HOTPLUG=y | ||
69 | CONFIG_PRINTK=y | ||
70 | CONFIG_BUG=y | ||
71 | CONFIG_ELF_CORE=y | ||
72 | CONFIG_BASE_FULL=y | ||
73 | CONFIG_FUTEX=y | ||
74 | CONFIG_EPOLL=y | ||
75 | CONFIG_SHMEM=y | ||
76 | CONFIG_SLAB=y | ||
77 | # CONFIG_TINY_SHMEM is not set | ||
78 | CONFIG_BASE_SMALL=0 | ||
79 | # CONFIG_SLOB is not set | ||
80 | |||
81 | # | ||
82 | # Loadable module support | ||
83 | # | ||
84 | # CONFIG_MODULES is not set | ||
85 | |||
86 | # | ||
87 | # Block layer | ||
88 | # | ||
89 | CONFIG_LBD=y | ||
90 | # CONFIG_BLK_DEV_IO_TRACE is not set | ||
91 | # CONFIG_LSF is not set | ||
92 | |||
93 | # | ||
94 | # IO Schedulers | ||
95 | # | ||
96 | CONFIG_IOSCHED_NOOP=y | ||
97 | CONFIG_IOSCHED_AS=y | ||
98 | CONFIG_IOSCHED_DEADLINE=y | ||
99 | CONFIG_IOSCHED_CFQ=y | ||
100 | CONFIG_DEFAULT_AS=y | ||
101 | # CONFIG_DEFAULT_DEADLINE is not set | ||
102 | # CONFIG_DEFAULT_CFQ is not set | ||
103 | # CONFIG_DEFAULT_NOOP is not set | ||
104 | CONFIG_DEFAULT_IOSCHED="anticipatory" | ||
105 | |||
106 | # | ||
107 | # Platform support | ||
108 | # | ||
109 | # CONFIG_PPC_MULTIPLATFORM is not set | ||
110 | # CONFIG_PPC_ISERIES is not set | ||
111 | CONFIG_EMBEDDED6xx=y | ||
112 | # CONFIG_APUS is not set | ||
113 | CONFIG_MPIC=y | ||
114 | # CONFIG_PPC_RTAS is not set | ||
115 | # CONFIG_MMIO_NVRAM is not set | ||
116 | # CONFIG_PPC_MPC106 is not set | ||
117 | # CONFIG_PPC_970_NAP is not set | ||
118 | # CONFIG_CPU_FREQ is not set | ||
119 | # CONFIG_TAU is not set | ||
120 | # CONFIG_KATANA is not set | ||
121 | # CONFIG_WILLOW is not set | ||
122 | # CONFIG_CPCI690 is not set | ||
123 | # CONFIG_POWERPMC250 is not set | ||
124 | # CONFIG_CHESTNUT is not set | ||
125 | # CONFIG_SPRUCE is not set | ||
126 | # CONFIG_HDPU is not set | ||
127 | # CONFIG_EV64260 is not set | ||
128 | # CONFIG_LOPEC is not set | ||
129 | # CONFIG_MVME5100 is not set | ||
130 | # CONFIG_PPLUS is not set | ||
131 | # CONFIG_PRPMC750 is not set | ||
132 | # CONFIG_PRPMC800 is not set | ||
133 | # CONFIG_SANDPOINT is not set | ||
134 | CONFIG_MPC7448HPC2=y | ||
135 | # CONFIG_RADSTONE_PPC7D is not set | ||
136 | # CONFIG_PAL4 is not set | ||
137 | # CONFIG_GEMINI is not set | ||
138 | # CONFIG_EST8260 is not set | ||
139 | # CONFIG_SBC82xx is not set | ||
140 | # CONFIG_SBS8260 is not set | ||
141 | # CONFIG_RPX8260 is not set | ||
142 | # CONFIG_TQM8260 is not set | ||
143 | # CONFIG_ADS8272 is not set | ||
144 | # CONFIG_PQ2FADS is not set | ||
145 | # CONFIG_LITE5200 is not set | ||
146 | # CONFIG_EV64360 is not set | ||
147 | CONFIG_TSI108_BRIDGE=y | ||
148 | # CONFIG_WANT_EARLY_SERIAL is not set | ||
149 | |||
150 | # | ||
151 | # Kernel options | ||
152 | # | ||
153 | # CONFIG_HIGHMEM is not set | ||
154 | # CONFIG_HZ_100 is not set | ||
155 | CONFIG_HZ_250=y | ||
156 | # CONFIG_HZ_1000 is not set | ||
157 | CONFIG_HZ=250 | ||
158 | CONFIG_PREEMPT_NONE=y | ||
159 | # CONFIG_PREEMPT_VOLUNTARY is not set | ||
160 | # CONFIG_PREEMPT is not set | ||
161 | CONFIG_BINFMT_ELF=y | ||
162 | CONFIG_BINFMT_MISC=y | ||
163 | CONFIG_ARCH_FLATMEM_ENABLE=y | ||
164 | CONFIG_SELECT_MEMORY_MODEL=y | ||
165 | CONFIG_FLATMEM_MANUAL=y | ||
166 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
167 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
168 | CONFIG_FLATMEM=y | ||
169 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
170 | # CONFIG_SPARSEMEM_STATIC is not set | ||
171 | CONFIG_SPLIT_PTLOCK_CPUS=4 | ||
172 | CONFIG_PROC_DEVICETREE=y | ||
173 | # CONFIG_CMDLINE_BOOL is not set | ||
174 | # CONFIG_PM is not set | ||
175 | # CONFIG_SOFTWARE_SUSPEND is not set | ||
176 | # CONFIG_SECCOMP is not set | ||
177 | CONFIG_ISA_DMA_API=y | ||
178 | |||
179 | # | ||
180 | # Bus options | ||
181 | # | ||
182 | CONFIG_GENERIC_ISA_DMA=y | ||
183 | # CONFIG_PPC_I8259 is not set | ||
184 | # CONFIG_PPC_INDIRECT_PCI is not set | ||
185 | CONFIG_PCI=y | ||
186 | CONFIG_PCI_DOMAINS=y | ||
187 | |||
188 | # | ||
189 | # PCCARD (PCMCIA/CardBus) support | ||
190 | # | ||
191 | # CONFIG_PCCARD is not set | ||
192 | |||
193 | # | ||
194 | # PCI Hotplug Support | ||
195 | # | ||
196 | # CONFIG_HOTPLUG_PCI is not set | ||
197 | |||
198 | # | ||
199 | # Advanced setup | ||
200 | # | ||
201 | # CONFIG_ADVANCED_OPTIONS is not set | ||
202 | |||
203 | # | ||
204 | # Default settings for advanced configuration options are used | ||
205 | # | ||
206 | CONFIG_HIGHMEM_START=0xfe000000 | ||
207 | CONFIG_LOWMEM_SIZE=0x30000000 | ||
208 | CONFIG_KERNEL_START=0xc0000000 | ||
209 | CONFIG_TASK_SIZE=0x80000000 | ||
210 | CONFIG_BOOT_LOAD=0x00800000 | ||
211 | |||
212 | # | ||
213 | # Networking | ||
214 | # | ||
215 | CONFIG_NET=y | ||
216 | |||
217 | # | ||
218 | # Networking options | ||
219 | # | ||
220 | # CONFIG_NETDEBUG is not set | ||
221 | CONFIG_PACKET=y | ||
222 | # CONFIG_PACKET_MMAP is not set | ||
223 | CONFIG_UNIX=y | ||
224 | # CONFIG_NET_KEY is not set | ||
225 | CONFIG_INET=y | ||
226 | CONFIG_IP_MULTICAST=y | ||
227 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
228 | CONFIG_IP_FIB_HASH=y | ||
229 | CONFIG_IP_PNP=y | ||
230 | CONFIG_IP_PNP_DHCP=y | ||
231 | CONFIG_IP_PNP_BOOTP=y | ||
232 | # CONFIG_IP_PNP_RARP is not set | ||
233 | # CONFIG_NET_IPIP is not set | ||
234 | # CONFIG_NET_IPGRE is not set | ||
235 | # CONFIG_IP_MROUTE is not set | ||
236 | # CONFIG_ARPD is not set | ||
237 | CONFIG_SYN_COOKIES=y | ||
238 | # CONFIG_INET_AH is not set | ||
239 | # CONFIG_INET_ESP is not set | ||
240 | # CONFIG_INET_IPCOMP is not set | ||
241 | # CONFIG_INET_XFRM_TUNNEL is not set | ||
242 | # CONFIG_INET_TUNNEL is not set | ||
243 | CONFIG_INET_DIAG=y | ||
244 | CONFIG_INET_TCP_DIAG=y | ||
245 | # CONFIG_TCP_CONG_ADVANCED is not set | ||
246 | CONFIG_TCP_CONG_BIC=y | ||
247 | # CONFIG_IPV6 is not set | ||
248 | # CONFIG_INET6_XFRM_TUNNEL is not set | ||
249 | # CONFIG_INET6_TUNNEL is not set | ||
250 | # CONFIG_NETFILTER is not set | ||
251 | |||
252 | # | ||
253 | # DCCP Configuration (EXPERIMENTAL) | ||
254 | # | ||
255 | # CONFIG_IP_DCCP is not set | ||
256 | |||
257 | # | ||
258 | # SCTP Configuration (EXPERIMENTAL) | ||
259 | # | ||
260 | # CONFIG_IP_SCTP is not set | ||
261 | |||
262 | # | ||
263 | # TIPC Configuration (EXPERIMENTAL) | ||
264 | # | ||
265 | # CONFIG_TIPC is not set | ||
266 | # CONFIG_ATM is not set | ||
267 | # CONFIG_BRIDGE is not set | ||
268 | # CONFIG_VLAN_8021Q is not set | ||
269 | # CONFIG_DECNET is not set | ||
270 | # CONFIG_LLC2 is not set | ||
271 | # CONFIG_IPX is not set | ||
272 | # CONFIG_ATALK is not set | ||
273 | # CONFIG_X25 is not set | ||
274 | # CONFIG_LAPB is not set | ||
275 | # CONFIG_NET_DIVERT is not set | ||
276 | # CONFIG_ECONET is not set | ||
277 | # CONFIG_WAN_ROUTER is not set | ||
278 | |||
279 | # | ||
280 | # QoS and/or fair queueing | ||
281 | # | ||
282 | # CONFIG_NET_SCHED is not set | ||
283 | |||
284 | # | ||
285 | # Network testing | ||
286 | # | ||
287 | # CONFIG_NET_PKTGEN is not set | ||
288 | # CONFIG_HAMRADIO is not set | ||
289 | # CONFIG_IRDA is not set | ||
290 | # CONFIG_BT is not set | ||
291 | # CONFIG_IEEE80211 is not set | ||
292 | |||
293 | # | ||
294 | # Device Drivers | ||
295 | # | ||
296 | |||
297 | # | ||
298 | # Generic Driver Options | ||
299 | # | ||
300 | CONFIG_STANDALONE=y | ||
301 | CONFIG_PREVENT_FIRMWARE_BUILD=y | ||
302 | # CONFIG_FW_LOADER is not set | ||
303 | |||
304 | # | ||
305 | # Connector - unified userspace <-> kernelspace linker | ||
306 | # | ||
307 | # CONFIG_CONNECTOR is not set | ||
308 | |||
309 | # | ||
310 | # Memory Technology Devices (MTD) | ||
311 | # | ||
312 | # CONFIG_MTD is not set | ||
313 | |||
314 | # | ||
315 | # Parallel port support | ||
316 | # | ||
317 | # CONFIG_PARPORT is not set | ||
318 | |||
319 | # | ||
320 | # Plug and Play support | ||
321 | # | ||
322 | |||
323 | # | ||
324 | # Block devices | ||
325 | # | ||
326 | # CONFIG_BLK_DEV_FD is not set | ||
327 | # CONFIG_BLK_CPQ_DA is not set | ||
328 | # CONFIG_BLK_CPQ_CISS_DA is not set | ||
329 | # CONFIG_BLK_DEV_DAC960 is not set | ||
330 | # CONFIG_BLK_DEV_UMEM is not set | ||
331 | # CONFIG_BLK_DEV_COW_COMMON is not set | ||
332 | CONFIG_BLK_DEV_LOOP=y | ||
333 | # CONFIG_BLK_DEV_CRYPTOLOOP is not set | ||
334 | # CONFIG_BLK_DEV_NBD is not set | ||
335 | # CONFIG_BLK_DEV_SX8 is not set | ||
336 | CONFIG_BLK_DEV_RAM=y | ||
337 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
338 | CONFIG_BLK_DEV_RAM_SIZE=131072 | ||
339 | CONFIG_BLK_DEV_INITRD=y | ||
340 | # CONFIG_CDROM_PKTCDVD is not set | ||
341 | # CONFIG_ATA_OVER_ETH is not set | ||
342 | |||
343 | # | ||
344 | # ATA/ATAPI/MFM/RLL support | ||
345 | # | ||
346 | # CONFIG_IDE is not set | ||
347 | |||
348 | # | ||
349 | # SCSI device support | ||
350 | # | ||
351 | # CONFIG_RAID_ATTRS is not set | ||
352 | CONFIG_SCSI=y | ||
353 | CONFIG_SCSI_PROC_FS=y | ||
354 | |||
355 | # | ||
356 | # SCSI support type (disk, tape, CD-ROM) | ||
357 | # | ||
358 | CONFIG_BLK_DEV_SD=y | ||
359 | # CONFIG_CHR_DEV_ST is not set | ||
360 | # CONFIG_CHR_DEV_OSST is not set | ||
361 | # CONFIG_BLK_DEV_SR is not set | ||
362 | # CONFIG_CHR_DEV_SG is not set | ||
363 | # CONFIG_CHR_DEV_SCH is not set | ||
364 | |||
365 | # | ||
366 | # Some SCSI devices (e.g. CD jukebox) support multiple LUNs | ||
367 | # | ||
368 | # CONFIG_SCSI_MULTI_LUN is not set | ||
369 | # CONFIG_SCSI_CONSTANTS is not set | ||
370 | # CONFIG_SCSI_LOGGING is not set | ||
371 | |||
372 | # | ||
373 | # SCSI Transport Attributes | ||
374 | # | ||
375 | # CONFIG_SCSI_SPI_ATTRS is not set | ||
376 | # CONFIG_SCSI_FC_ATTRS is not set | ||
377 | # CONFIG_SCSI_ISCSI_ATTRS is not set | ||
378 | # CONFIG_SCSI_SAS_ATTRS is not set | ||
379 | |||
380 | # | ||
381 | # SCSI low-level drivers | ||
382 | # | ||
383 | # CONFIG_ISCSI_TCP is not set | ||
384 | # CONFIG_BLK_DEV_3W_XXXX_RAID is not set | ||
385 | # CONFIG_SCSI_3W_9XXX is not set | ||
386 | # CONFIG_SCSI_ACARD is not set | ||
387 | # CONFIG_SCSI_AACRAID is not set | ||
388 | # CONFIG_SCSI_AIC7XXX is not set | ||
389 | # CONFIG_SCSI_AIC7XXX_OLD is not set | ||
390 | # CONFIG_SCSI_AIC79XX is not set | ||
391 | # CONFIG_SCSI_DPT_I2O is not set | ||
392 | # CONFIG_MEGARAID_NEWGEN is not set | ||
393 | # CONFIG_MEGARAID_LEGACY is not set | ||
394 | # CONFIG_MEGARAID_SAS is not set | ||
395 | CONFIG_SCSI_SATA=y | ||
396 | # CONFIG_SCSI_SATA_AHCI is not set | ||
397 | # CONFIG_SCSI_SATA_SVW is not set | ||
398 | # CONFIG_SCSI_ATA_PIIX is not set | ||
399 | CONFIG_SCSI_SATA_MV=y | ||
400 | # CONFIG_SCSI_SATA_NV is not set | ||
401 | # CONFIG_SCSI_PDC_ADMA is not set | ||
402 | # CONFIG_SCSI_SATA_QSTOR is not set | ||
403 | # CONFIG_SCSI_SATA_PROMISE is not set | ||
404 | # CONFIG_SCSI_SATA_SX4 is not set | ||
405 | # CONFIG_SCSI_SATA_SIL is not set | ||
406 | # CONFIG_SCSI_SATA_SIL24 is not set | ||
407 | # CONFIG_SCSI_SATA_SIS is not set | ||
408 | # CONFIG_SCSI_SATA_ULI is not set | ||
409 | # CONFIG_SCSI_SATA_VIA is not set | ||
410 | # CONFIG_SCSI_SATA_VITESSE is not set | ||
411 | # CONFIG_SCSI_BUSLOGIC is not set | ||
412 | # CONFIG_SCSI_DMX3191D is not set | ||
413 | # CONFIG_SCSI_EATA is not set | ||
414 | # CONFIG_SCSI_FUTURE_DOMAIN is not set | ||
415 | # CONFIG_SCSI_GDTH is not set | ||
416 | # CONFIG_SCSI_IPS is not set | ||
417 | # CONFIG_SCSI_INITIO is not set | ||
418 | # CONFIG_SCSI_INIA100 is not set | ||
419 | # CONFIG_SCSI_SYM53C8XX_2 is not set | ||
420 | # CONFIG_SCSI_IPR is not set | ||
421 | # CONFIG_SCSI_QLOGIC_1280 is not set | ||
422 | # CONFIG_SCSI_QLA_FC is not set | ||
423 | # CONFIG_SCSI_LPFC is not set | ||
424 | # CONFIG_SCSI_DC395x is not set | ||
425 | # CONFIG_SCSI_DC390T is not set | ||
426 | # CONFIG_SCSI_NSP32 is not set | ||
427 | # CONFIG_SCSI_DEBUG is not set | ||
428 | |||
429 | # | ||
430 | # Multi-device support (RAID and LVM) | ||
431 | # | ||
432 | # CONFIG_MD is not set | ||
433 | |||
434 | # | ||
435 | # Fusion MPT device support | ||
436 | # | ||
437 | # CONFIG_FUSION is not set | ||
438 | # CONFIG_FUSION_SPI is not set | ||
439 | # CONFIG_FUSION_FC is not set | ||
440 | # CONFIG_FUSION_SAS is not set | ||
441 | |||
442 | # | ||
443 | # IEEE 1394 (FireWire) support | ||
444 | # | ||
445 | # CONFIG_IEEE1394 is not set | ||
446 | |||
447 | # | ||
448 | # I2O device support | ||
449 | # | ||
450 | # CONFIG_I2O is not set | ||
451 | |||
452 | # | ||
453 | # Macintosh device drivers | ||
454 | # | ||
455 | # CONFIG_WINDFARM is not set | ||
456 | |||
457 | # | ||
458 | # Network device support | ||
459 | # | ||
460 | CONFIG_NETDEVICES=y | ||
461 | # CONFIG_DUMMY is not set | ||
462 | # CONFIG_BONDING is not set | ||
463 | # CONFIG_EQUALIZER is not set | ||
464 | # CONFIG_TUN is not set | ||
465 | |||
466 | # | ||
467 | # ARCnet devices | ||
468 | # | ||
469 | # CONFIG_ARCNET is not set | ||
470 | |||
471 | # | ||
472 | # PHY device support | ||
473 | # | ||
474 | CONFIG_PHYLIB=y | ||
475 | |||
476 | # | ||
477 | # MII PHY device drivers | ||
478 | # | ||
479 | # CONFIG_MARVELL_PHY is not set | ||
480 | # CONFIG_DAVICOM_PHY is not set | ||
481 | # CONFIG_QSEMI_PHY is not set | ||
482 | # CONFIG_LXT_PHY is not set | ||
483 | # CONFIG_CICADA_PHY is not set | ||
484 | |||
485 | # | ||
486 | # Ethernet (10 or 100Mbit) | ||
487 | # | ||
488 | CONFIG_NET_ETHERNET=y | ||
489 | CONFIG_MII=y | ||
490 | # CONFIG_HAPPYMEAL is not set | ||
491 | # CONFIG_SUNGEM is not set | ||
492 | # CONFIG_CASSINI is not set | ||
493 | # CONFIG_NET_VENDOR_3COM is not set | ||
494 | |||
495 | # | ||
496 | # Tulip family network device support | ||
497 | # | ||
498 | # CONFIG_NET_TULIP is not set | ||
499 | # CONFIG_HP100 is not set | ||
500 | CONFIG_NET_PCI=y | ||
501 | # CONFIG_PCNET32 is not set | ||
502 | # CONFIG_AMD8111_ETH is not set | ||
503 | # CONFIG_ADAPTEC_STARFIRE is not set | ||
504 | # CONFIG_B44 is not set | ||
505 | # CONFIG_FORCEDETH is not set | ||
506 | # CONFIG_DGRS is not set | ||
507 | # CONFIG_EEPRO100 is not set | ||
508 | CONFIG_E100=y | ||
509 | # CONFIG_FEALNX is not set | ||
510 | # CONFIG_NATSEMI is not set | ||
511 | # CONFIG_NE2K_PCI is not set | ||
512 | # CONFIG_8139CP is not set | ||
513 | CONFIG_8139TOO=y | ||
514 | # CONFIG_8139TOO_PIO is not set | ||
515 | # CONFIG_8139TOO_TUNE_TWISTER is not set | ||
516 | # CONFIG_8139TOO_8129 is not set | ||
517 | # CONFIG_8139_OLD_RX_RESET is not set | ||
518 | # CONFIG_SIS900 is not set | ||
519 | # CONFIG_EPIC100 is not set | ||
520 | # CONFIG_SUNDANCE is not set | ||
521 | # CONFIG_TLAN is not set | ||
522 | # CONFIG_VIA_RHINE is not set | ||
523 | |||
524 | # | ||
525 | # Ethernet (1000 Mbit) | ||
526 | # | ||
527 | # CONFIG_ACENIC is not set | ||
528 | # CONFIG_DL2K is not set | ||
529 | # CONFIG_E1000 is not set | ||
530 | # CONFIG_NS83820 is not set | ||
531 | # CONFIG_HAMACHI is not set | ||
532 | # CONFIG_YELLOWFIN is not set | ||
533 | # CONFIG_R8169 is not set | ||
534 | # CONFIG_SIS190 is not set | ||
535 | # CONFIG_SKGE is not set | ||
536 | # CONFIG_SKY2 is not set | ||
537 | # CONFIG_SK98LIN is not set | ||
538 | # CONFIG_VIA_VELOCITY is not set | ||
539 | # CONFIG_TIGON3 is not set | ||
540 | # CONFIG_BNX2 is not set | ||
541 | CONFIG_TSI108_ETH=y | ||
542 | |||
543 | # | ||
544 | # Ethernet (10000 Mbit) | ||
545 | # | ||
546 | # CONFIG_CHELSIO_T1 is not set | ||
547 | # CONFIG_IXGB is not set | ||
548 | # CONFIG_S2IO is not set | ||
549 | |||
550 | # | ||
551 | # Token Ring devices | ||
552 | # | ||
553 | # CONFIG_TR is not set | ||
554 | |||
555 | # | ||
556 | # Wireless LAN (non-hamradio) | ||
557 | # | ||
558 | # CONFIG_NET_RADIO is not set | ||
559 | |||
560 | # | ||
561 | # Wan interfaces | ||
562 | # | ||
563 | # CONFIG_WAN is not set | ||
564 | # CONFIG_FDDI is not set | ||
565 | # CONFIG_HIPPI is not set | ||
566 | # CONFIG_PPP is not set | ||
567 | # CONFIG_SLIP is not set | ||
568 | # CONFIG_NET_FC is not set | ||
569 | # CONFIG_SHAPER is not set | ||
570 | # CONFIG_NETCONSOLE is not set | ||
571 | # CONFIG_NETPOLL is not set | ||
572 | # CONFIG_NET_POLL_CONTROLLER is not set | ||
573 | |||
574 | # | ||
575 | # ISDN subsystem | ||
576 | # | ||
577 | # CONFIG_ISDN is not set | ||
578 | |||
579 | # | ||
580 | # Telephony Support | ||
581 | # | ||
582 | # CONFIG_PHONE is not set | ||
583 | |||
584 | # | ||
585 | # Input device support | ||
586 | # | ||
587 | CONFIG_INPUT=y | ||
588 | |||
589 | # | ||
590 | # Userland interfaces | ||
591 | # | ||
592 | # CONFIG_INPUT_MOUSEDEV is not set | ||
593 | # CONFIG_INPUT_JOYDEV is not set | ||
594 | # CONFIG_INPUT_TSDEV is not set | ||
595 | # CONFIG_INPUT_EVDEV is not set | ||
596 | # CONFIG_INPUT_EVBUG is not set | ||
597 | |||
598 | # | ||
599 | # Input Device Drivers | ||
600 | # | ||
601 | # CONFIG_INPUT_KEYBOARD is not set | ||
602 | # CONFIG_INPUT_MOUSE is not set | ||
603 | # CONFIG_INPUT_JOYSTICK is not set | ||
604 | # CONFIG_INPUT_TOUCHSCREEN is not set | ||
605 | # CONFIG_INPUT_MISC is not set | ||
606 | |||
607 | # | ||
608 | # Hardware I/O ports | ||
609 | # | ||
610 | # CONFIG_SERIO is not set | ||
611 | # CONFIG_GAMEPORT is not set | ||
612 | |||
613 | # | ||
614 | # Character devices | ||
615 | # | ||
616 | # CONFIG_VT is not set | ||
617 | # CONFIG_SERIAL_NONSTANDARD is not set | ||
618 | |||
619 | # | ||
620 | # Serial drivers | ||
621 | # | ||
622 | CONFIG_SERIAL_8250=y | ||
623 | CONFIG_SERIAL_8250_CONSOLE=y | ||
624 | CONFIG_SERIAL_8250_PCI=y | ||
625 | CONFIG_SERIAL_8250_NR_UARTS=4 | ||
626 | CONFIG_SERIAL_8250_RUNTIME_UARTS=4 | ||
627 | # CONFIG_SERIAL_8250_EXTENDED is not set | ||
628 | |||
629 | # | ||
630 | # Non-8250 serial port support | ||
631 | # | ||
632 | CONFIG_SERIAL_CORE=y | ||
633 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
634 | # CONFIG_SERIAL_JSM is not set | ||
635 | CONFIG_UNIX98_PTYS=y | ||
636 | CONFIG_LEGACY_PTYS=y | ||
637 | CONFIG_LEGACY_PTY_COUNT=256 | ||
638 | |||
639 | # | ||
640 | # IPMI | ||
641 | # | ||
642 | # CONFIG_IPMI_HANDLER is not set | ||
643 | |||
644 | # | ||
645 | # Watchdog Cards | ||
646 | # | ||
647 | # CONFIG_WATCHDOG is not set | ||
648 | # CONFIG_NVRAM is not set | ||
649 | CONFIG_GEN_RTC=y | ||
650 | # CONFIG_GEN_RTC_X is not set | ||
651 | # CONFIG_DTLK is not set | ||
652 | # CONFIG_R3964 is not set | ||
653 | # CONFIG_APPLICOM is not set | ||
654 | |||
655 | # | ||
656 | # Ftape, the floppy tape device driver | ||
657 | # | ||
658 | # CONFIG_AGP is not set | ||
659 | # CONFIG_DRM is not set | ||
660 | # CONFIG_RAW_DRIVER is not set | ||
661 | |||
662 | # | ||
663 | # TPM devices | ||
664 | # | ||
665 | # CONFIG_TCG_TPM is not set | ||
666 | # CONFIG_TELCLOCK is not set | ||
667 | |||
668 | # | ||
669 | # I2C support | ||
670 | # | ||
671 | # CONFIG_I2C is not set | ||
672 | |||
673 | # | ||
674 | # SPI support | ||
675 | # | ||
676 | # CONFIG_SPI is not set | ||
677 | # CONFIG_SPI_MASTER is not set | ||
678 | |||
679 | # | ||
680 | # Dallas's 1-wire bus | ||
681 | # | ||
682 | # CONFIG_W1 is not set | ||
683 | |||
684 | # | ||
685 | # Hardware Monitoring support | ||
686 | # | ||
687 | CONFIG_HWMON=y | ||
688 | # CONFIG_HWMON_VID is not set | ||
689 | # CONFIG_SENSORS_F71805F is not set | ||
690 | # CONFIG_HWMON_DEBUG_CHIP is not set | ||
691 | |||
692 | # | ||
693 | # Misc devices | ||
694 | # | ||
695 | |||
696 | # | ||
697 | # Multimedia devices | ||
698 | # | ||
699 | # CONFIG_VIDEO_DEV is not set | ||
700 | |||
701 | # | ||
702 | # Digital Video Broadcasting Devices | ||
703 | # | ||
704 | # CONFIG_DVB is not set | ||
705 | |||
706 | # | ||
707 | # Graphics support | ||
708 | # | ||
709 | # CONFIG_FB is not set | ||
710 | |||
711 | # | ||
712 | # Sound | ||
713 | # | ||
714 | # CONFIG_SOUND is not set | ||
715 | |||
716 | # | ||
717 | # USB support | ||
718 | # | ||
719 | CONFIG_USB_ARCH_HAS_HCD=y | ||
720 | CONFIG_USB_ARCH_HAS_OHCI=y | ||
721 | CONFIG_USB_ARCH_HAS_EHCI=y | ||
722 | # CONFIG_USB is not set | ||
723 | |||
724 | # | ||
725 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' | ||
726 | # | ||
727 | |||
728 | # | ||
729 | # USB Gadget Support | ||
730 | # | ||
731 | # CONFIG_USB_GADGET is not set | ||
732 | |||
733 | # | ||
734 | # MMC/SD Card support | ||
735 | # | ||
736 | # CONFIG_MMC is not set | ||
737 | |||
738 | # | ||
739 | # LED devices | ||
740 | # | ||
741 | # CONFIG_NEW_LEDS is not set | ||
742 | |||
743 | # | ||
744 | # LED drivers | ||
745 | # | ||
746 | |||
747 | # | ||
748 | # LED Triggers | ||
749 | # | ||
750 | |||
751 | # | ||
752 | # InfiniBand support | ||
753 | # | ||
754 | # CONFIG_INFINIBAND is not set | ||
755 | |||
756 | # | ||
757 | # EDAC - error detection and reporting (RAS) (EXPERIMENTAL) | ||
758 | # | ||
759 | |||
760 | # | ||
761 | # Real Time Clock | ||
762 | # | ||
763 | # CONFIG_RTC_CLASS is not set | ||
764 | |||
765 | # | ||
766 | # File systems | ||
767 | # | ||
768 | CONFIG_EXT2_FS=y | ||
769 | # CONFIG_EXT2_FS_XATTR is not set | ||
770 | # CONFIG_EXT2_FS_XIP is not set | ||
771 | CONFIG_EXT3_FS=y | ||
772 | CONFIG_EXT3_FS_XATTR=y | ||
773 | # CONFIG_EXT3_FS_POSIX_ACL is not set | ||
774 | # CONFIG_EXT3_FS_SECURITY is not set | ||
775 | CONFIG_JBD=y | ||
776 | # CONFIG_JBD_DEBUG is not set | ||
777 | CONFIG_FS_MBCACHE=y | ||
778 | # CONFIG_REISERFS_FS is not set | ||
779 | # CONFIG_JFS_FS is not set | ||
780 | # CONFIG_FS_POSIX_ACL is not set | ||
781 | # CONFIG_XFS_FS is not set | ||
782 | # CONFIG_OCFS2_FS is not set | ||
783 | # CONFIG_MINIX_FS is not set | ||
784 | # CONFIG_ROMFS_FS is not set | ||
785 | CONFIG_INOTIFY=y | ||
786 | # CONFIG_QUOTA is not set | ||
787 | CONFIG_DNOTIFY=y | ||
788 | # CONFIG_AUTOFS_FS is not set | ||
789 | # CONFIG_AUTOFS4_FS is not set | ||
790 | # CONFIG_FUSE_FS is not set | ||
791 | |||
792 | # | ||
793 | # CD-ROM/DVD Filesystems | ||
794 | # | ||
795 | # CONFIG_ISO9660_FS is not set | ||
796 | # CONFIG_UDF_FS is not set | ||
797 | |||
798 | # | ||
799 | # DOS/FAT/NT Filesystems | ||
800 | # | ||
801 | # CONFIG_MSDOS_FS is not set | ||
802 | # CONFIG_VFAT_FS is not set | ||
803 | # CONFIG_NTFS_FS is not set | ||
804 | |||
805 | # | ||
806 | # Pseudo filesystems | ||
807 | # | ||
808 | CONFIG_PROC_FS=y | ||
809 | CONFIG_PROC_KCORE=y | ||
810 | CONFIG_SYSFS=y | ||
811 | CONFIG_TMPFS=y | ||
812 | # CONFIG_HUGETLB_PAGE is not set | ||
813 | CONFIG_RAMFS=y | ||
814 | # CONFIG_CONFIGFS_FS is not set | ||
815 | |||
816 | # | ||
817 | # Miscellaneous filesystems | ||
818 | # | ||
819 | # CONFIG_ADFS_FS is not set | ||
820 | # CONFIG_AFFS_FS is not set | ||
821 | # CONFIG_HFS_FS is not set | ||
822 | # CONFIG_HFSPLUS_FS is not set | ||
823 | # CONFIG_BEFS_FS is not set | ||
824 | # CONFIG_BFS_FS is not set | ||
825 | # CONFIG_EFS_FS is not set | ||
826 | # CONFIG_CRAMFS is not set | ||
827 | # CONFIG_VXFS_FS is not set | ||
828 | # CONFIG_HPFS_FS is not set | ||
829 | # CONFIG_QNX4FS_FS is not set | ||
830 | # CONFIG_SYSV_FS is not set | ||
831 | # CONFIG_UFS_FS is not set | ||
832 | |||
833 | # | ||
834 | # Network File Systems | ||
835 | # | ||
836 | CONFIG_NFS_FS=y | ||
837 | # CONFIG_NFS_V3 is not set | ||
838 | # CONFIG_NFS_V4 is not set | ||
839 | # CONFIG_NFS_DIRECTIO is not set | ||
840 | # CONFIG_NFSD is not set | ||
841 | CONFIG_ROOT_NFS=y | ||
842 | CONFIG_LOCKD=y | ||
843 | CONFIG_NFS_COMMON=y | ||
844 | CONFIG_SUNRPC=y | ||
845 | # CONFIG_RPCSEC_GSS_KRB5 is not set | ||
846 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | ||
847 | # CONFIG_SMB_FS is not set | ||
848 | # CONFIG_CIFS is not set | ||
849 | # CONFIG_NCP_FS is not set | ||
850 | # CONFIG_CODA_FS is not set | ||
851 | # CONFIG_AFS_FS is not set | ||
852 | # CONFIG_9P_FS is not set | ||
853 | |||
854 | # | ||
855 | # Partition Types | ||
856 | # | ||
857 | CONFIG_PARTITION_ADVANCED=y | ||
858 | # CONFIG_ACORN_PARTITION is not set | ||
859 | # CONFIG_OSF_PARTITION is not set | ||
860 | # CONFIG_AMIGA_PARTITION is not set | ||
861 | # CONFIG_ATARI_PARTITION is not set | ||
862 | # CONFIG_MAC_PARTITION is not set | ||
863 | CONFIG_MSDOS_PARTITION=y | ||
864 | # CONFIG_BSD_DISKLABEL is not set | ||
865 | # CONFIG_MINIX_SUBPARTITION is not set | ||
866 | # CONFIG_SOLARIS_X86_PARTITION is not set | ||
867 | # CONFIG_UNIXWARE_DISKLABEL is not set | ||
868 | # CONFIG_LDM_PARTITION is not set | ||
869 | # CONFIG_SGI_PARTITION is not set | ||
870 | # CONFIG_ULTRIX_PARTITION is not set | ||
871 | # CONFIG_SUN_PARTITION is not set | ||
872 | # CONFIG_KARMA_PARTITION is not set | ||
873 | # CONFIG_EFI_PARTITION is not set | ||
874 | |||
875 | # | ||
876 | # Native Language Support | ||
877 | # | ||
878 | # CONFIG_NLS is not set | ||
879 | |||
880 | # | ||
881 | # Library routines | ||
882 | # | ||
883 | # CONFIG_CRC_CCITT is not set | ||
884 | # CONFIG_CRC16 is not set | ||
885 | CONFIG_CRC32=y | ||
886 | # CONFIG_LIBCRC32C is not set | ||
887 | |||
888 | # | ||
889 | # Instrumentation Support | ||
890 | # | ||
891 | # CONFIG_PROFILING is not set | ||
892 | |||
893 | # | ||
894 | # Kernel hacking | ||
895 | # | ||
896 | # CONFIG_PRINTK_TIME is not set | ||
897 | # CONFIG_MAGIC_SYSRQ is not set | ||
898 | # CONFIG_DEBUG_KERNEL is not set | ||
899 | CONFIG_LOG_BUF_SHIFT=14 | ||
900 | # CONFIG_DEBUG_FS is not set | ||
901 | # CONFIG_UNWIND_INFO is not set | ||
902 | # CONFIG_BOOTX_TEXT is not set | ||
903 | # CONFIG_SERIAL_TEXT_DEBUG is not set | ||
904 | # CONFIG_PPC_EARLY_DEBUG_LPAR is not set | ||
905 | # CONFIG_PPC_EARLY_DEBUG_G5 is not set | ||
906 | # CONFIG_PPC_EARLY_DEBUG_RTAS is not set | ||
907 | # CONFIG_PPC_EARLY_DEBUG_MAPLE is not set | ||
908 | # CONFIG_PPC_EARLY_DEBUG_ISERIES is not set | ||
909 | |||
910 | # | ||
911 | # Security options | ||
912 | # | ||
913 | # CONFIG_KEYS is not set | ||
914 | # CONFIG_SECURITY is not set | ||
915 | |||
916 | # | ||
917 | # Cryptographic options | ||
918 | # | ||
919 | # CONFIG_CRYPTO is not set | ||
920 | |||
921 | # | ||
922 | # Hardware crypto devices | ||
923 | # | ||
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 803858e86160..814f242aeb8c 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
@@ -50,7 +50,8 @@ extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o | |||
50 | extra-$(CONFIG_8xx) := head_8xx.o | 50 | extra-$(CONFIG_8xx) := head_8xx.o |
51 | extra-y += vmlinux.lds | 51 | extra-y += vmlinux.lds |
52 | 52 | ||
53 | obj-y += time.o prom.o traps.o setup-common.o udbg.o | 53 | obj-y += time.o prom.o traps.o setup-common.o \ |
54 | udbg.o misc.o | ||
54 | obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o | 55 | obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o |
55 | obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o | 56 | obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o |
56 | obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o | 57 | obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o |
diff --git a/arch/powerpc/kernel/cpu_setup_power4.S b/arch/powerpc/kernel/cpu_setup_power4.S index 271418308d53..1fc863261003 100644 --- a/arch/powerpc/kernel/cpu_setup_power4.S +++ b/arch/powerpc/kernel/cpu_setup_power4.S | |||
@@ -125,7 +125,12 @@ _GLOBAL(__save_cpu_setup) | |||
125 | cmpwi r0,0x44 | 125 | cmpwi r0,0x44 |
126 | bne 2f | 126 | bne 2f |
127 | 127 | ||
128 | 1: /* Save HID0,1,4 and 5 */ | 128 | 1: /* skip if not running in HV mode */ |
129 | mfmsr r0 | ||
130 | rldicl. r0,r0,4,63 | ||
131 | beq 2f | ||
132 | |||
133 | /* Save HID0,1,4 and 5 */ | ||
129 | mfspr r3,SPRN_HID0 | 134 | mfspr r3,SPRN_HID0 |
130 | std r3,CS_HID0(r5) | 135 | std r3,CS_HID0(r5) |
131 | mfspr r3,SPRN_HID1 | 136 | mfspr r3,SPRN_HID1 |
@@ -159,7 +164,12 @@ _GLOBAL(__restore_cpu_setup) | |||
159 | cmpwi r0,0x44 | 164 | cmpwi r0,0x44 |
160 | bnelr | 165 | bnelr |
161 | 166 | ||
162 | 1: /* Before accessing memory, we make sure rm_ci is clear */ | 167 | 1: /* skip if not running in HV mode */ |
168 | mfmsr r0 | ||
169 | rldicl. r0,r0,4,63 | ||
170 | beqlr | ||
171 | |||
172 | /* Before accessing memory, we make sure rm_ci is clear */ | ||
163 | li r0,0 | 173 | li r0,0 |
164 | mfspr r3,SPRN_HID4 | 174 | mfspr r3,SPRN_HID4 |
165 | rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */ | 175 | rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */ |
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 1c114880dc05..abf7d42a8b07 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c | |||
@@ -722,18 +722,6 @@ struct cpu_spec cpu_specs[] = { | |||
722 | .oprofile_type = PPC_OPROFILE_G4, | 722 | .oprofile_type = PPC_OPROFILE_G4, |
723 | .platform = "ppc7450", | 723 | .platform = "ppc7450", |
724 | }, | 724 | }, |
725 | { /* 8641 */ | ||
726 | .pvr_mask = 0xffffffff, | ||
727 | .pvr_value = 0x80040010, | ||
728 | .cpu_name = "8641", | ||
729 | .cpu_features = CPU_FTRS_7447A, | ||
730 | .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, | ||
731 | .icache_bsize = 32, | ||
732 | .dcache_bsize = 32, | ||
733 | .num_pmcs = 6, | ||
734 | .cpu_setup = __setup_cpu_745x | ||
735 | }, | ||
736 | |||
737 | { /* 82xx (8240, 8245, 8260 are all 603e cores) */ | 725 | { /* 82xx (8240, 8245, 8260 are all 603e cores) */ |
738 | .pvr_mask = 0x7fff0000, | 726 | .pvr_mask = 0x7fff0000, |
739 | .pvr_value = 0x00810000, | 727 | .pvr_value = 0x00810000, |
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c index e253a45dcf10..358cecdc6aef 100644 --- a/arch/powerpc/kernel/crash.c +++ b/arch/powerpc/kernel/crash.c | |||
@@ -24,9 +24,11 @@ | |||
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <linux/irq.h> | 25 | #include <linux/irq.h> |
26 | #include <linux/types.h> | 26 | #include <linux/types.h> |
27 | #include <linux/irq.h> | ||
27 | 28 | ||
28 | #include <asm/processor.h> | 29 | #include <asm/processor.h> |
29 | #include <asm/machdep.h> | 30 | #include <asm/machdep.h> |
31 | #include <asm/kexec.h> | ||
30 | #include <asm/kdump.h> | 32 | #include <asm/kdump.h> |
31 | #include <asm/lmb.h> | 33 | #include <asm/lmb.h> |
32 | #include <asm/firmware.h> | 34 | #include <asm/firmware.h> |
@@ -41,6 +43,7 @@ | |||
41 | 43 | ||
42 | /* This keeps a track of which one is crashing cpu. */ | 44 | /* This keeps a track of which one is crashing cpu. */ |
43 | int crashing_cpu = -1; | 45 | int crashing_cpu = -1; |
46 | static cpumask_t cpus_in_crash = CPU_MASK_NONE; | ||
44 | 47 | ||
45 | static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data, | 48 | static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data, |
46 | size_t data_len) | 49 | size_t data_len) |
@@ -98,34 +101,66 @@ static void crash_save_this_cpu(struct pt_regs *regs, int cpu) | |||
98 | } | 101 | } |
99 | 102 | ||
100 | #ifdef CONFIG_SMP | 103 | #ifdef CONFIG_SMP |
101 | static atomic_t waiting_for_crash_ipi; | 104 | static atomic_t enter_on_soft_reset = ATOMIC_INIT(0); |
102 | 105 | ||
103 | void crash_ipi_callback(struct pt_regs *regs) | 106 | void crash_ipi_callback(struct pt_regs *regs) |
104 | { | 107 | { |
105 | int cpu = smp_processor_id(); | 108 | int cpu = smp_processor_id(); |
106 | 109 | ||
107 | if (cpu == crashing_cpu) | ||
108 | return; | ||
109 | |||
110 | if (!cpu_online(cpu)) | 110 | if (!cpu_online(cpu)) |
111 | return; | 111 | return; |
112 | 112 | ||
113 | if (ppc_md.kexec_cpu_down) | ||
114 | ppc_md.kexec_cpu_down(1, 1); | ||
115 | |||
116 | local_irq_disable(); | 113 | local_irq_disable(); |
114 | if (!cpu_isset(cpu, cpus_in_crash)) | ||
115 | crash_save_this_cpu(regs, cpu); | ||
116 | cpu_set(cpu, cpus_in_crash); | ||
117 | 117 | ||
118 | crash_save_this_cpu(regs, cpu); | 118 | /* |
119 | atomic_dec(&waiting_for_crash_ipi); | 119 | * Entered via soft-reset - could be the kdump |
120 | * process is invoked using soft-reset or user activated | ||
121 | * it if some CPU did not respond to an IPI. | ||
122 | * For soft-reset, the secondary CPU can enter this func | ||
123 | * twice. 1 - using IPI, and 2. soft-reset. | ||
124 | * Tell the kexec CPU that entered via soft-reset and ready | ||
125 | * to go down. | ||
126 | */ | ||
127 | if (cpu_isset(cpu, cpus_in_sr)) { | ||
128 | cpu_clear(cpu, cpus_in_sr); | ||
129 | atomic_inc(&enter_on_soft_reset); | ||
130 | } | ||
131 | |||
132 | /* | ||
133 | * Starting the kdump boot. | ||
134 | * This barrier is needed to make sure that all CPUs are stopped. | ||
135 | * If not, soft-reset will be invoked to bring other CPUs. | ||
136 | */ | ||
137 | while (!cpu_isset(crashing_cpu, cpus_in_crash)) | ||
138 | cpu_relax(); | ||
139 | |||
140 | if (ppc_md.kexec_cpu_down) | ||
141 | ppc_md.kexec_cpu_down(1, 1); | ||
120 | kexec_smp_wait(); | 142 | kexec_smp_wait(); |
121 | /* NOTREACHED */ | 143 | /* NOTREACHED */ |
122 | } | 144 | } |
123 | 145 | ||
124 | static void crash_kexec_prepare_cpus(void) | 146 | /* |
147 | * Wait until all CPUs are entered via soft-reset. | ||
148 | */ | ||
149 | static void crash_soft_reset_check(int cpu) | ||
150 | { | ||
151 | unsigned int ncpus = num_online_cpus() - 1;/* Excluding the panic cpu */ | ||
152 | |||
153 | cpu_clear(cpu, cpus_in_sr); | ||
154 | while (atomic_read(&enter_on_soft_reset) != ncpus) | ||
155 | cpu_relax(); | ||
156 | } | ||
157 | |||
158 | |||
159 | static void crash_kexec_prepare_cpus(int cpu) | ||
125 | { | 160 | { |
126 | unsigned int msecs; | 161 | unsigned int msecs; |
127 | 162 | ||
128 | atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); | 163 | unsigned int ncpus = num_online_cpus() - 1;/* Excluding the panic cpu */ |
129 | 164 | ||
130 | crash_send_ipi(crash_ipi_callback); | 165 | crash_send_ipi(crash_ipi_callback); |
131 | smp_wmb(); | 166 | smp_wmb(); |
@@ -133,14 +168,13 @@ static void crash_kexec_prepare_cpus(void) | |||
133 | /* | 168 | /* |
134 | * FIXME: Until we will have the way to stop other CPUSs reliabally, | 169 | * FIXME: Until we will have the way to stop other CPUSs reliabally, |
135 | * the crash CPU will send an IPI and wait for other CPUs to | 170 | * the crash CPU will send an IPI and wait for other CPUs to |
136 | * respond. If not, proceed the kexec boot even though we failed to | 171 | * respond. |
137 | * capture other CPU states. | ||
138 | * Delay of at least 10 seconds. | 172 | * Delay of at least 10 seconds. |
139 | */ | 173 | */ |
140 | printk(KERN_ALERT "Sending IPI to other cpus...\n"); | 174 | printk(KERN_EMERG "Sending IPI to other cpus...\n"); |
141 | msecs = 10000; | 175 | msecs = 10000; |
142 | while ((atomic_read(&waiting_for_crash_ipi) > 0) && (--msecs > 0)) { | 176 | while ((cpus_weight(cpus_in_crash) < ncpus) && (--msecs > 0)) { |
143 | barrier(); | 177 | cpu_relax(); |
144 | mdelay(1); | 178 | mdelay(1); |
145 | } | 179 | } |
146 | 180 | ||
@@ -149,18 +183,71 @@ static void crash_kexec_prepare_cpus(void) | |||
149 | /* | 183 | /* |
150 | * FIXME: In case if we do not get all CPUs, one possibility: ask the | 184 | * FIXME: In case if we do not get all CPUs, one possibility: ask the |
151 | * user to do soft reset such that we get all. | 185 | * user to do soft reset such that we get all. |
152 | * IPI handler is already set by the panic cpu initially. Therefore, | 186 | * Soft-reset will be used until better mechanism is implemented. |
153 | * all cpus could invoke this handler from die() and the panic CPU | 187 | */ |
154 | * will call machine_kexec() directly from this handler to do | 188 | if (cpus_weight(cpus_in_crash) < ncpus) { |
155 | * kexec boot. | 189 | printk(KERN_EMERG "done waiting: %d cpu(s) not responding\n", |
190 | ncpus - cpus_weight(cpus_in_crash)); | ||
191 | printk(KERN_EMERG "Activate soft-reset to stop other cpu(s)\n"); | ||
192 | cpus_in_sr = CPU_MASK_NONE; | ||
193 | atomic_set(&enter_on_soft_reset, 0); | ||
194 | while (cpus_weight(cpus_in_crash) < ncpus) | ||
195 | cpu_relax(); | ||
196 | } | ||
197 | /* | ||
198 | * Make sure all CPUs are entered via soft-reset if the kdump is | ||
199 | * invoked using soft-reset. | ||
156 | */ | 200 | */ |
157 | if (atomic_read(&waiting_for_crash_ipi)) | 201 | if (cpu_isset(cpu, cpus_in_sr)) |
158 | printk(KERN_ALERT "done waiting: %d cpus not responding\n", | 202 | crash_soft_reset_check(cpu); |
159 | atomic_read(&waiting_for_crash_ipi)); | ||
160 | /* Leave the IPI callback set */ | 203 | /* Leave the IPI callback set */ |
161 | } | 204 | } |
205 | |||
206 | /* | ||
207 | * This function will be called by secondary cpus or by kexec cpu | ||
208 | * if soft-reset is activated to stop some CPUs. | ||
209 | */ | ||
210 | void crash_kexec_secondary(struct pt_regs *regs) | ||
211 | { | ||
212 | int cpu = smp_processor_id(); | ||
213 | unsigned long flags; | ||
214 | int msecs = 5; | ||
215 | |||
216 | local_irq_save(flags); | ||
217 | /* Wait 5ms if the kexec CPU is not entered yet. */ | ||
218 | while (crashing_cpu < 0) { | ||
219 | if (--msecs < 0) { | ||
220 | /* | ||
221 | * Either kdump image is not loaded or | ||
222 | * kdump process is not started - Probably xmon | ||
223 | * exited using 'x'(exit and recover) or | ||
224 | * kexec_should_crash() failed for all running tasks. | ||
225 | */ | ||
226 | cpu_clear(cpu, cpus_in_sr); | ||
227 | local_irq_restore(flags); | ||
228 | return; | ||
229 | } | ||
230 | mdelay(1); | ||
231 | cpu_relax(); | ||
232 | } | ||
233 | if (cpu == crashing_cpu) { | ||
234 | /* | ||
235 | * Panic CPU will enter this func only via soft-reset. | ||
236 | * Wait until all secondary CPUs entered and | ||
237 | * then start kexec boot. | ||
238 | */ | ||
239 | crash_soft_reset_check(cpu); | ||
240 | cpu_set(crashing_cpu, cpus_in_crash); | ||
241 | if (ppc_md.kexec_cpu_down) | ||
242 | ppc_md.kexec_cpu_down(1, 0); | ||
243 | machine_kexec(kexec_crash_image); | ||
244 | /* NOTREACHED */ | ||
245 | } | ||
246 | crash_ipi_callback(regs); | ||
247 | } | ||
248 | |||
162 | #else | 249 | #else |
163 | static void crash_kexec_prepare_cpus(void) | 250 | static void crash_kexec_prepare_cpus(int cpu) |
164 | { | 251 | { |
165 | /* | 252 | /* |
166 | * move the secondarys to us so that we can copy | 253 | * move the secondarys to us so that we can copy |
@@ -171,6 +258,10 @@ static void crash_kexec_prepare_cpus(void) | |||
171 | smp_release_cpus(); | 258 | smp_release_cpus(); |
172 | } | 259 | } |
173 | 260 | ||
261 | void crash_kexec_secondary(struct pt_regs *regs) | ||
262 | { | ||
263 | cpus_in_sr = CPU_MASK_NONE; | ||
264 | } | ||
174 | #endif | 265 | #endif |
175 | 266 | ||
176 | void default_machine_crash_shutdown(struct pt_regs *regs) | 267 | void default_machine_crash_shutdown(struct pt_regs *regs) |
@@ -190,23 +281,23 @@ void default_machine_crash_shutdown(struct pt_regs *regs) | |||
190 | local_irq_disable(); | 281 | local_irq_disable(); |
191 | 282 | ||
192 | for_each_irq(irq) { | 283 | for_each_irq(irq) { |
193 | struct irq_desc *desc = irq_descp(irq); | 284 | struct irq_desc *desc = irq_desc + irq; |
194 | 285 | ||
195 | if (desc->status & IRQ_INPROGRESS) | 286 | if (desc->status & IRQ_INPROGRESS) |
196 | desc->handler->end(irq); | 287 | desc->chip->end(irq); |
197 | 288 | ||
198 | if (!(desc->status & IRQ_DISABLED)) | 289 | if (!(desc->status & IRQ_DISABLED)) |
199 | desc->handler->disable(irq); | 290 | desc->chip->disable(irq); |
200 | } | 291 | } |
201 | 292 | ||
202 | if (ppc_md.kexec_cpu_down) | ||
203 | ppc_md.kexec_cpu_down(1, 0); | ||
204 | |||
205 | /* | 293 | /* |
206 | * Make a note of crashing cpu. Will be used in machine_kexec | 294 | * Make a note of crashing cpu. Will be used in machine_kexec |
207 | * such that another IPI will not be sent. | 295 | * such that another IPI will not be sent. |
208 | */ | 296 | */ |
209 | crashing_cpu = smp_processor_id(); | 297 | crashing_cpu = smp_processor_id(); |
210 | crash_kexec_prepare_cpus(); | ||
211 | crash_save_this_cpu(regs, crashing_cpu); | 298 | crash_save_this_cpu(regs, crashing_cpu); |
299 | crash_kexec_prepare_cpus(crashing_cpu); | ||
300 | cpu_set(crashing_cpu, cpus_in_crash); | ||
301 | if (ppc_md.kexec_cpu_down) | ||
302 | ppc_md.kexec_cpu_down(1, 0); | ||
212 | } | 303 | } |
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 831acbdf2592..8cfd040d1f50 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S | |||
@@ -85,34 +85,6 @@ END_FTR_SECTION(0, 1) | |||
85 | /* Catch branch to 0 in real mode */ | 85 | /* Catch branch to 0 in real mode */ |
86 | trap | 86 | trap |
87 | 87 | ||
88 | #ifdef CONFIG_PPC_ISERIES | ||
89 | /* | ||
90 | * At offset 0x20, there is a pointer to iSeries LPAR data. | ||
91 | * This is required by the hypervisor | ||
92 | */ | ||
93 | . = 0x20 | ||
94 | .llong hvReleaseData-KERNELBASE | ||
95 | |||
96 | /* | ||
97 | * At offset 0x28 and 0x30 are offsets to the mschunks_map | ||
98 | * array (used by the iSeries LPAR debugger to do translation | ||
99 | * between physical addresses and absolute addresses) and | ||
100 | * to the pidhash table (also used by the debugger) | ||
101 | */ | ||
102 | .llong mschunks_map-KERNELBASE | ||
103 | .llong 0 /* pidhash-KERNELBASE SFRXXX */ | ||
104 | |||
105 | /* Offset 0x38 - Pointer to start of embedded System.map */ | ||
106 | .globl embedded_sysmap_start | ||
107 | embedded_sysmap_start: | ||
108 | .llong 0 | ||
109 | /* Offset 0x40 - Pointer to end of embedded System.map */ | ||
110 | .globl embedded_sysmap_end | ||
111 | embedded_sysmap_end: | ||
112 | .llong 0 | ||
113 | |||
114 | #endif /* CONFIG_PPC_ISERIES */ | ||
115 | |||
116 | /* Secondary processors spin on this value until it goes to 1. */ | 88 | /* Secondary processors spin on this value until it goes to 1. */ |
117 | .globl __secondary_hold_spinloop | 89 | .globl __secondary_hold_spinloop |
118 | __secondary_hold_spinloop: | 90 | __secondary_hold_spinloop: |
@@ -124,6 +96,15 @@ __secondary_hold_spinloop: | |||
124 | __secondary_hold_acknowledge: | 96 | __secondary_hold_acknowledge: |
125 | .llong 0x0 | 97 | .llong 0x0 |
126 | 98 | ||
99 | #ifdef CONFIG_PPC_ISERIES | ||
100 | /* | ||
101 | * At offset 0x20, there is a pointer to iSeries LPAR data. | ||
102 | * This is required by the hypervisor | ||
103 | */ | ||
104 | . = 0x20 | ||
105 | .llong hvReleaseData-KERNELBASE | ||
106 | #endif /* CONFIG_PPC_ISERIES */ | ||
107 | |||
127 | . = 0x60 | 108 | . = 0x60 |
128 | /* | 109 | /* |
129 | * The following code is used on pSeries to hold secondary processors | 110 | * The following code is used on pSeries to hold secondary processors |
@@ -1602,9 +1583,6 @@ _GLOBAL(__start_initialization_multiplatform) | |||
1602 | /* Setup some critical 970 SPRs before switching MMU off */ | 1583 | /* Setup some critical 970 SPRs before switching MMU off */ |
1603 | bl .__970_cpu_preinit | 1584 | bl .__970_cpu_preinit |
1604 | 1585 | ||
1605 | /* cpu # */ | ||
1606 | li r24,0 | ||
1607 | |||
1608 | /* Switch off MMU if not already */ | 1586 | /* Switch off MMU if not already */ |
1609 | LOAD_REG_IMMEDIATE(r4, .__after_prom_start - KERNELBASE) | 1587 | LOAD_REG_IMMEDIATE(r4, .__after_prom_start - KERNELBASE) |
1610 | add r4,r4,r30 | 1588 | add r4,r4,r30 |
@@ -1683,6 +1661,9 @@ _STATIC(__after_prom_start) | |||
1683 | /* i.e. where we are running */ | 1661 | /* i.e. where we are running */ |
1684 | /* the source addr */ | 1662 | /* the source addr */ |
1685 | 1663 | ||
1664 | cmpdi r4,0 /* In some cases the loader may */ | ||
1665 | beq .start_here_multiplatform /* have already put us at zero */ | ||
1666 | /* so we can skip the copy. */ | ||
1686 | LOAD_REG_IMMEDIATE(r5,copy_to_here) /* # bytes of memory to copy */ | 1667 | LOAD_REG_IMMEDIATE(r5,copy_to_here) /* # bytes of memory to copy */ |
1687 | sub r5,r5,r27 | 1668 | sub r5,r5,r27 |
1688 | 1669 | ||
@@ -1962,14 +1943,6 @@ _STATIC(start_here_common) | |||
1962 | li r3,0 | 1943 | li r3,0 |
1963 | bl .do_cpu_ftr_fixups | 1944 | bl .do_cpu_ftr_fixups |
1964 | 1945 | ||
1965 | LOAD_REG_IMMEDIATE(r26, boot_cpuid) | ||
1966 | lwz r26,0(r26) | ||
1967 | |||
1968 | LOAD_REG_IMMEDIATE(r24, paca) /* Get base vaddr of paca array */ | ||
1969 | mulli r13,r26,PACA_SIZE /* Calculate vaddr of right paca */ | ||
1970 | add r13,r13,r24 /* for this processor. */ | ||
1971 | mtspr SPRN_SPRG3,r13 | ||
1972 | |||
1973 | /* ptr to current */ | 1946 | /* ptr to current */ |
1974 | LOAD_REG_IMMEDIATE(r4, init_task) | 1947 | LOAD_REG_IMMEDIATE(r4, init_task) |
1975 | std r4,PACACURRENT(r13) | 1948 | std r4,PACACURRENT(r13) |
@@ -1995,17 +1968,6 @@ _STATIC(start_here_common) | |||
1995 | /* Not reached */ | 1968 | /* Not reached */ |
1996 | BUG_OPCODE | 1969 | BUG_OPCODE |
1997 | 1970 | ||
1998 | /* Put the paca pointer into r13 and SPRG3 */ | ||
1999 | _GLOBAL(setup_boot_paca) | ||
2000 | LOAD_REG_IMMEDIATE(r3, boot_cpuid) | ||
2001 | lwz r3,0(r3) | ||
2002 | LOAD_REG_IMMEDIATE(r4, paca) /* Get base vaddr of paca array */ | ||
2003 | mulli r3,r3,PACA_SIZE /* Calculate vaddr of right paca */ | ||
2004 | add r13,r3,r4 /* for this processor. */ | ||
2005 | mtspr SPRN_SPRG3,r13 | ||
2006 | |||
2007 | blr | ||
2008 | |||
2009 | /* | 1971 | /* |
2010 | * We put a few things here that have to be page-aligned. | 1972 | * We put a few things here that have to be page-aligned. |
2011 | * This stuff goes at the beginning of the bss, which is page-aligned. | 1973 | * This stuff goes at the beginning of the bss, which is page-aligned. |
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 7cb77c20fc5d..3d677ac99659 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <asm/iommu.h> | 38 | #include <asm/iommu.h> |
39 | #include <asm/pci-bridge.h> | 39 | #include <asm/pci-bridge.h> |
40 | #include <asm/machdep.h> | 40 | #include <asm/machdep.h> |
41 | #include <asm/kdump.h> | ||
41 | 42 | ||
42 | #define DBG(...) | 43 | #define DBG(...) |
43 | 44 | ||
@@ -440,8 +441,37 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid) | |||
440 | tbl->it_largehint = tbl->it_halfpoint; | 441 | tbl->it_largehint = tbl->it_halfpoint; |
441 | spin_lock_init(&tbl->it_lock); | 442 | spin_lock_init(&tbl->it_lock); |
442 | 443 | ||
444 | #ifdef CONFIG_CRASH_DUMP | ||
445 | if (ppc_md.tce_get) { | ||
446 | unsigned long index, tceval; | ||
447 | unsigned long tcecount = 0; | ||
448 | |||
449 | /* | ||
450 | * Reserve the existing mappings left by the first kernel. | ||
451 | */ | ||
452 | for (index = 0; index < tbl->it_size; index++) { | ||
453 | tceval = ppc_md.tce_get(tbl, index + tbl->it_offset); | ||
454 | /* | ||
455 | * Freed TCE entry contains 0x7fffffffffffffff on JS20 | ||
456 | */ | ||
457 | if (tceval && (tceval != 0x7fffffffffffffffUL)) { | ||
458 | __set_bit(index, tbl->it_map); | ||
459 | tcecount++; | ||
460 | } | ||
461 | } | ||
462 | if ((tbl->it_size - tcecount) < KDUMP_MIN_TCE_ENTRIES) { | ||
463 | printk(KERN_WARNING "TCE table is full; "); | ||
464 | printk(KERN_WARNING "freeing %d entries for the kdump boot\n", | ||
465 | KDUMP_MIN_TCE_ENTRIES); | ||
466 | for (index = tbl->it_size - KDUMP_MIN_TCE_ENTRIES; | ||
467 | index < tbl->it_size; index++) | ||
468 | __clear_bit(index, tbl->it_map); | ||
469 | } | ||
470 | } | ||
471 | #else | ||
443 | /* Clear the hardware table in case firmware left allocations in it */ | 472 | /* Clear the hardware table in case firmware left allocations in it */ |
444 | ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size); | 473 | ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size); |
474 | #endif | ||
445 | 475 | ||
446 | if (!welcomed) { | 476 | if (!welcomed) { |
447 | printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n", | 477 | printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n", |
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 40d4c14fde8f..24f6050aa4ab 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
@@ -120,8 +120,8 @@ int show_interrupts(struct seq_file *p, void *v) | |||
120 | #else | 120 | #else |
121 | seq_printf(p, "%10u ", kstat_irqs(i)); | 121 | seq_printf(p, "%10u ", kstat_irqs(i)); |
122 | #endif /* CONFIG_SMP */ | 122 | #endif /* CONFIG_SMP */ |
123 | if (desc->handler) | 123 | if (desc->chip) |
124 | seq_printf(p, " %s ", desc->handler->typename); | 124 | seq_printf(p, " %s ", desc->chip->typename); |
125 | else | 125 | else |
126 | seq_puts(p, " None "); | 126 | seq_puts(p, " None "); |
127 | seq_printf(p, "%s", (desc->status & IRQ_LEVEL) ? "Level " : "Edge "); | 127 | seq_printf(p, "%s", (desc->status & IRQ_LEVEL) ? "Level " : "Edge "); |
@@ -164,13 +164,13 @@ void fixup_irqs(cpumask_t map) | |||
164 | if (irq_desc[irq].status & IRQ_PER_CPU) | 164 | if (irq_desc[irq].status & IRQ_PER_CPU) |
165 | continue; | 165 | continue; |
166 | 166 | ||
167 | cpus_and(mask, irq_affinity[irq], map); | 167 | cpus_and(mask, irq_desc[irq].affinity, map); |
168 | if (any_online_cpu(mask) == NR_CPUS) { | 168 | if (any_online_cpu(mask) == NR_CPUS) { |
169 | printk("Breaking affinity for irq %i\n", irq); | 169 | printk("Breaking affinity for irq %i\n", irq); |
170 | mask = map; | 170 | mask = map; |
171 | } | 171 | } |
172 | if (irq_desc[irq].handler->set_affinity) | 172 | if (irq_desc[irq].chip->set_affinity) |
173 | irq_desc[irq].handler->set_affinity(irq, mask); | 173 | irq_desc[irq].chip->set_affinity(irq, mask); |
174 | else if (irq_desc[irq].action && !(warned++)) | 174 | else if (irq_desc[irq].action && !(warned++)) |
175 | printk("Cannot set affinity for irq %i\n", irq); | 175 | printk("Cannot set affinity for irq %i\n", irq); |
176 | } | 176 | } |
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c index 6e67b5b49ba1..3a9b78d03542 100644 --- a/arch/powerpc/kernel/legacy_serial.c +++ b/arch/powerpc/kernel/legacy_serial.c | |||
@@ -302,6 +302,17 @@ void __init find_legacy_serial_ports(void) | |||
302 | of_node_put(isa); | 302 | of_node_put(isa); |
303 | } | 303 | } |
304 | 304 | ||
305 | /* First fill our array with tsi-bridge ports */ | ||
306 | for (np = NULL; (np = of_find_compatible_node(np, "serial", "ns16550")) != NULL;) { | ||
307 | struct device_node *tsi = of_get_parent(np); | ||
308 | if (tsi && !strcmp(tsi->type, "tsi-bridge")) { | ||
309 | index = add_legacy_soc_port(np, np); | ||
310 | if (index >= 0 && np == stdout) | ||
311 | legacy_serial_console = index; | ||
312 | } | ||
313 | of_node_put(tsi); | ||
314 | } | ||
315 | |||
305 | #ifdef CONFIG_PCI | 316 | #ifdef CONFIG_PCI |
306 | /* Next, try to locate PCI ports */ | 317 | /* Next, try to locate PCI ports */ |
307 | for (np = NULL; (np = of_find_all_nodes(np));) { | 318 | for (np = NULL; (np = of_find_all_nodes(np));) { |
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c index c02deaab26c7..73edc3c16137 100644 --- a/arch/powerpc/kernel/lparcfg.c +++ b/arch/powerpc/kernel/lparcfg.c | |||
@@ -45,11 +45,9 @@ | |||
45 | static struct proc_dir_entry *proc_ppc64_lparcfg; | 45 | static struct proc_dir_entry *proc_ppc64_lparcfg; |
46 | #define LPARCFG_BUFF_SIZE 4096 | 46 | #define LPARCFG_BUFF_SIZE 4096 |
47 | 47 | ||
48 | #ifdef CONFIG_PPC_ISERIES | ||
49 | |||
50 | /* | 48 | /* |
51 | * For iSeries legacy systems, the PPA purr function is available from the | 49 | * Track sum of all purrs across all processors. This is used to further |
52 | * emulated_time_base field in the paca. | 50 | * calculate usage values by different applications |
53 | */ | 51 | */ |
54 | static unsigned long get_purr(void) | 52 | static unsigned long get_purr(void) |
55 | { | 53 | { |
@@ -57,48 +55,31 @@ static unsigned long get_purr(void) | |||
57 | int cpu; | 55 | int cpu; |
58 | 56 | ||
59 | for_each_possible_cpu(cpu) { | 57 | for_each_possible_cpu(cpu) { |
60 | sum_purr += lppaca[cpu].emulated_time_base; | 58 | if (firmware_has_feature(FW_FEATURE_ISERIES)) |
59 | sum_purr += lppaca[cpu].emulated_time_base; | ||
60 | else { | ||
61 | struct cpu_usage *cu; | ||
61 | 62 | ||
62 | #ifdef PURR_DEBUG | 63 | cu = &per_cpu(cpu_usage_array, cpu); |
63 | printk(KERN_INFO "get_purr for cpu (%d) has value (%ld) \n", | 64 | sum_purr += cu->current_tb; |
64 | cpu, lppaca[cpu].emulated_time_base); | 65 | } |
65 | #endif | ||
66 | } | 66 | } |
67 | return sum_purr; | 67 | return sum_purr; |
68 | } | 68 | } |
69 | 69 | ||
70 | #define lparcfg_write NULL | 70 | #ifdef CONFIG_PPC_ISERIES |
71 | 71 | ||
72 | /* | 72 | /* |
73 | * Methods used to fetch LPAR data when running on an iSeries platform. | 73 | * Methods used to fetch LPAR data when running on an iSeries platform. |
74 | */ | 74 | */ |
75 | static int lparcfg_data(struct seq_file *m, void *v) | 75 | static int iseries_lparcfg_data(struct seq_file *m, void *v) |
76 | { | 76 | { |
77 | unsigned long pool_id, lp_index; | 77 | unsigned long pool_id; |
78 | int shared, entitled_capacity, max_entitled_capacity; | 78 | int shared, entitled_capacity, max_entitled_capacity; |
79 | int processors, max_processors; | 79 | int processors, max_processors; |
80 | unsigned long purr = get_purr(); | 80 | unsigned long purr = get_purr(); |
81 | 81 | ||
82 | seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS); | ||
83 | |||
84 | shared = (int)(get_lppaca()->shared_proc); | 82 | shared = (int)(get_lppaca()->shared_proc); |
85 | seq_printf(m, "serial_number=%c%c%c%c%c%c%c\n", | ||
86 | e2a(xItExtVpdPanel.mfgID[2]), | ||
87 | e2a(xItExtVpdPanel.mfgID[3]), | ||
88 | e2a(xItExtVpdPanel.systemSerial[1]), | ||
89 | e2a(xItExtVpdPanel.systemSerial[2]), | ||
90 | e2a(xItExtVpdPanel.systemSerial[3]), | ||
91 | e2a(xItExtVpdPanel.systemSerial[4]), | ||
92 | e2a(xItExtVpdPanel.systemSerial[5])); | ||
93 | |||
94 | seq_printf(m, "system_type=%c%c%c%c\n", | ||
95 | e2a(xItExtVpdPanel.machineType[0]), | ||
96 | e2a(xItExtVpdPanel.machineType[1]), | ||
97 | e2a(xItExtVpdPanel.machineType[2]), | ||
98 | e2a(xItExtVpdPanel.machineType[3])); | ||
99 | |||
100 | lp_index = HvLpConfig_getLpIndex(); | ||
101 | seq_printf(m, "partition_id=%d\n", (int)lp_index); | ||
102 | 83 | ||
103 | seq_printf(m, "system_active_processors=%d\n", | 84 | seq_printf(m, "system_active_processors=%d\n", |
104 | (int)HvLpConfig_getSystemPhysicalProcessors()); | 85 | (int)HvLpConfig_getSystemPhysicalProcessors()); |
@@ -137,6 +118,14 @@ static int lparcfg_data(struct seq_file *m, void *v) | |||
137 | 118 | ||
138 | return 0; | 119 | return 0; |
139 | } | 120 | } |
121 | |||
122 | #else /* CONFIG_PPC_ISERIES */ | ||
123 | |||
124 | static int iseries_lparcfg_data(struct seq_file *m, void *v) | ||
125 | { | ||
126 | return 0; | ||
127 | } | ||
128 | |||
140 | #endif /* CONFIG_PPC_ISERIES */ | 129 | #endif /* CONFIG_PPC_ISERIES */ |
141 | 130 | ||
142 | #ifdef CONFIG_PPC_PSERIES | 131 | #ifdef CONFIG_PPC_PSERIES |
@@ -213,22 +202,6 @@ static void h_pic(unsigned long *pool_idle_time, unsigned long *num_procs) | |||
213 | log_plpar_hcall_return(rc, "H_PIC"); | 202 | log_plpar_hcall_return(rc, "H_PIC"); |
214 | } | 203 | } |
215 | 204 | ||
216 | /* Track sum of all purrs across all processors. This is used to further */ | ||
217 | /* calculate usage values by different applications */ | ||
218 | |||
219 | static unsigned long get_purr(void) | ||
220 | { | ||
221 | unsigned long sum_purr = 0; | ||
222 | int cpu; | ||
223 | struct cpu_usage *cu; | ||
224 | |||
225 | for_each_possible_cpu(cpu) { | ||
226 | cu = &per_cpu(cpu_usage_array, cpu); | ||
227 | sum_purr += cu->current_tb; | ||
228 | } | ||
229 | return sum_purr; | ||
230 | } | ||
231 | |||
232 | #define SPLPAR_CHARACTERISTICS_TOKEN 20 | 205 | #define SPLPAR_CHARACTERISTICS_TOKEN 20 |
233 | #define SPLPAR_MAXLENGTH 1026*(sizeof(char)) | 206 | #define SPLPAR_MAXLENGTH 1026*(sizeof(char)) |
234 | 207 | ||
@@ -333,35 +306,13 @@ static int lparcfg_count_active_processors(void) | |||
333 | return count; | 306 | return count; |
334 | } | 307 | } |
335 | 308 | ||
336 | static int lparcfg_data(struct seq_file *m, void *v) | 309 | static int pseries_lparcfg_data(struct seq_file *m, void *v) |
337 | { | 310 | { |
338 | int partition_potential_processors; | 311 | int partition_potential_processors; |
339 | int partition_active_processors; | 312 | int partition_active_processors; |
340 | struct device_node *rootdn; | ||
341 | const char *model = ""; | ||
342 | const char *system_id = ""; | ||
343 | unsigned int *lp_index_ptr, lp_index = 0; | ||
344 | struct device_node *rtas_node; | 313 | struct device_node *rtas_node; |
345 | int *lrdrp = NULL; | 314 | int *lrdrp = NULL; |
346 | 315 | ||
347 | rootdn = find_path_device("/"); | ||
348 | if (rootdn) { | ||
349 | model = get_property(rootdn, "model", NULL); | ||
350 | system_id = get_property(rootdn, "system-id", NULL); | ||
351 | lp_index_ptr = (unsigned int *) | ||
352 | get_property(rootdn, "ibm,partition-no", NULL); | ||
353 | if (lp_index_ptr) | ||
354 | lp_index = *lp_index_ptr; | ||
355 | } | ||
356 | |||
357 | seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS); | ||
358 | |||
359 | seq_printf(m, "serial_number=%s\n", system_id); | ||
360 | |||
361 | seq_printf(m, "system_type=%s\n", model); | ||
362 | |||
363 | seq_printf(m, "partition_id=%d\n", (int)lp_index); | ||
364 | |||
365 | rtas_node = find_path_device("/rtas"); | 316 | rtas_node = find_path_device("/rtas"); |
366 | if (rtas_node) | 317 | if (rtas_node) |
367 | lrdrp = (int *)get_property(rtas_node, "ibm,lrdr-capacity", | 318 | lrdrp = (int *)get_property(rtas_node, "ibm,lrdr-capacity", |
@@ -549,8 +500,61 @@ out: | |||
549 | return retval; | 500 | return retval; |
550 | } | 501 | } |
551 | 502 | ||
503 | #else /* CONFIG_PPC_PSERIES */ | ||
504 | |||
505 | static int pseries_lparcfg_data(struct seq_file *m, void *v) | ||
506 | { | ||
507 | return 0; | ||
508 | } | ||
509 | |||
510 | static ssize_t lparcfg_write(struct file *file, const char __user * buf, | ||
511 | size_t count, loff_t * off) | ||
512 | { | ||
513 | return count; | ||
514 | } | ||
515 | |||
552 | #endif /* CONFIG_PPC_PSERIES */ | 516 | #endif /* CONFIG_PPC_PSERIES */ |
553 | 517 | ||
518 | static int lparcfg_data(struct seq_file *m, void *v) | ||
519 | { | ||
520 | struct device_node *rootdn; | ||
521 | const char *model = ""; | ||
522 | const char *system_id = ""; | ||
523 | const char *tmp; | ||
524 | unsigned int *lp_index_ptr, lp_index = 0; | ||
525 | |||
526 | seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS); | ||
527 | |||
528 | rootdn = find_path_device("/"); | ||
529 | if (rootdn) { | ||
530 | tmp = get_property(rootdn, "model", NULL); | ||
531 | if (tmp) { | ||
532 | model = tmp; | ||
533 | /* Skip "IBM," - see platforms/iseries/dt.c */ | ||
534 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | ||
535 | model += 4; | ||
536 | } | ||
537 | tmp = get_property(rootdn, "system-id", NULL); | ||
538 | if (tmp) { | ||
539 | system_id = tmp; | ||
540 | /* Skip "IBM," - see platforms/iseries/dt.c */ | ||
541 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | ||
542 | system_id += 4; | ||
543 | } | ||
544 | lp_index_ptr = (unsigned int *) | ||
545 | get_property(rootdn, "ibm,partition-no", NULL); | ||
546 | if (lp_index_ptr) | ||
547 | lp_index = *lp_index_ptr; | ||
548 | } | ||
549 | seq_printf(m, "serial_number=%s\n", system_id); | ||
550 | seq_printf(m, "system_type=%s\n", model); | ||
551 | seq_printf(m, "partition_id=%d\n", (int)lp_index); | ||
552 | |||
553 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | ||
554 | return iseries_lparcfg_data(m, v); | ||
555 | return pseries_lparcfg_data(m, v); | ||
556 | } | ||
557 | |||
554 | static int lparcfg_open(struct inode *inode, struct file *file) | 558 | static int lparcfg_open(struct inode *inode, struct file *file) |
555 | { | 559 | { |
556 | return single_open(file, lparcfg_data, NULL); | 560 | return single_open(file, lparcfg_data, NULL); |
@@ -569,7 +573,8 @@ int __init lparcfg_init(void) | |||
569 | mode_t mode = S_IRUSR | S_IRGRP | S_IROTH; | 573 | mode_t mode = S_IRUSR | S_IRGRP | S_IROTH; |
570 | 574 | ||
571 | /* Allow writing if we have FW_FEATURE_SPLPAR */ | 575 | /* Allow writing if we have FW_FEATURE_SPLPAR */ |
572 | if (firmware_has_feature(FW_FEATURE_SPLPAR)) { | 576 | if (firmware_has_feature(FW_FEATURE_SPLPAR) && |
577 | !firmware_has_feature(FW_FEATURE_ISERIES)) { | ||
573 | lparcfg_fops.write = lparcfg_write; | 578 | lparcfg_fops.write = lparcfg_write; |
574 | mode |= S_IWUSR; | 579 | mode |= S_IWUSR; |
575 | } | 580 | } |
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c index a8fa04ef27cd..b438d45a068c 100644 --- a/arch/powerpc/kernel/machine_kexec_64.c +++ b/arch/powerpc/kernel/machine_kexec_64.c | |||
@@ -378,11 +378,13 @@ static void __init export_crashk_values(void) | |||
378 | of_node_put(node); | 378 | of_node_put(node); |
379 | } | 379 | } |
380 | 380 | ||
381 | void __init kexec_setup(void) | 381 | static int __init kexec_setup(void) |
382 | { | 382 | { |
383 | export_htab_values(); | 383 | export_htab_values(); |
384 | export_crashk_values(); | 384 | export_crashk_values(); |
385 | return 0; | ||
385 | } | 386 | } |
387 | __initcall(kexec_setup); | ||
386 | 388 | ||
387 | static int __init early_parse_crashk(char *p) | 389 | static int __init early_parse_crashk(char *p) |
388 | { | 390 | { |
diff --git a/arch/powerpc/kernel/misc.S b/arch/powerpc/kernel/misc.S new file mode 100644 index 000000000000..fc23040d5a26 --- /dev/null +++ b/arch/powerpc/kernel/misc.S | |||
@@ -0,0 +1,203 @@ | |||
1 | /* | ||
2 | * This file contains miscellaneous low-level functions. | ||
3 | * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) | ||
4 | * | ||
5 | * Largely rewritten by Cort Dougan (cort@cs.nmt.edu) | ||
6 | * and Paul Mackerras. | ||
7 | * | ||
8 | * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com) | ||
9 | * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com) | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License | ||
13 | * as published by the Free Software Foundation; either version | ||
14 | * 2 of the License, or (at your option) any later version. | ||
15 | */ | ||
16 | #include <asm/ppc_asm.h> | ||
17 | |||
18 | .text | ||
19 | |||
20 | #ifdef CONFIG_PPC64 | ||
21 | #define IN_SYNC twi 0,r5,0; isync | ||
22 | #define EIEIO_32 | ||
23 | #define SYNC_64 sync | ||
24 | #else /* CONFIG_PPC32 */ | ||
25 | #define IN_SYNC | ||
26 | #define EIEIO_32 eieio | ||
27 | #define SYNC_64 | ||
28 | #endif | ||
29 | /* | ||
30 | * Returns (address we are running at) - (address we were linked at) | ||
31 | * for use before the text and data are mapped to KERNELBASE. | ||
32 | */ | ||
33 | |||
34 | _GLOBAL(reloc_offset) | ||
35 | mflr r0 | ||
36 | bl 1f | ||
37 | 1: mflr r3 | ||
38 | LOAD_REG_IMMEDIATE(r4,1b) | ||
39 | subf r3,r4,r3 | ||
40 | mtlr r0 | ||
41 | blr | ||
42 | |||
43 | /* | ||
44 | * add_reloc_offset(x) returns x + reloc_offset(). | ||
45 | */ | ||
46 | _GLOBAL(add_reloc_offset) | ||
47 | mflr r0 | ||
48 | bl 1f | ||
49 | 1: mflr r5 | ||
50 | LOAD_REG_IMMEDIATE(r4,1b) | ||
51 | subf r5,r4,r5 | ||
52 | add r3,r3,r5 | ||
53 | mtlr r0 | ||
54 | blr | ||
55 | |||
56 | /* | ||
57 | * I/O string operations | ||
58 | * | ||
59 | * insb(port, buf, len) | ||
60 | * outsb(port, buf, len) | ||
61 | * insw(port, buf, len) | ||
62 | * outsw(port, buf, len) | ||
63 | * insl(port, buf, len) | ||
64 | * outsl(port, buf, len) | ||
65 | * insw_ns(port, buf, len) | ||
66 | * outsw_ns(port, buf, len) | ||
67 | * insl_ns(port, buf, len) | ||
68 | * outsl_ns(port, buf, len) | ||
69 | * | ||
70 | * The *_ns versions don't do byte-swapping. | ||
71 | */ | ||
72 | _GLOBAL(_insb) | ||
73 | cmpwi 0,r5,0 | ||
74 | mtctr r5 | ||
75 | subi r4,r4,1 | ||
76 | blelr- | ||
77 | 00: lbz r5,0(r3) | ||
78 | eieio | ||
79 | stbu r5,1(r4) | ||
80 | bdnz 00b | ||
81 | IN_SYNC | ||
82 | blr | ||
83 | |||
84 | _GLOBAL(_outsb) | ||
85 | cmpwi 0,r5,0 | ||
86 | mtctr r5 | ||
87 | subi r4,r4,1 | ||
88 | blelr- | ||
89 | 00: lbzu r5,1(r4) | ||
90 | stb r5,0(r3) | ||
91 | EIEIO_32 | ||
92 | bdnz 00b | ||
93 | SYNC_64 | ||
94 | blr | ||
95 | |||
96 | _GLOBAL(_insw) | ||
97 | cmpwi 0,r5,0 | ||
98 | mtctr r5 | ||
99 | subi r4,r4,2 | ||
100 | blelr- | ||
101 | 00: lhbrx r5,0,r3 | ||
102 | eieio | ||
103 | sthu r5,2(r4) | ||
104 | bdnz 00b | ||
105 | IN_SYNC | ||
106 | blr | ||
107 | |||
108 | _GLOBAL(_outsw) | ||
109 | cmpwi 0,r5,0 | ||
110 | mtctr r5 | ||
111 | subi r4,r4,2 | ||
112 | blelr- | ||
113 | 00: lhzu r5,2(r4) | ||
114 | EIEIO_32 | ||
115 | sthbrx r5,0,r3 | ||
116 | bdnz 00b | ||
117 | SYNC_64 | ||
118 | blr | ||
119 | |||
120 | _GLOBAL(_insl) | ||
121 | cmpwi 0,r5,0 | ||
122 | mtctr r5 | ||
123 | subi r4,r4,4 | ||
124 | blelr- | ||
125 | 00: lwbrx r5,0,r3 | ||
126 | eieio | ||
127 | stwu r5,4(r4) | ||
128 | bdnz 00b | ||
129 | IN_SYNC | ||
130 | blr | ||
131 | |||
132 | _GLOBAL(_outsl) | ||
133 | cmpwi 0,r5,0 | ||
134 | mtctr r5 | ||
135 | subi r4,r4,4 | ||
136 | blelr- | ||
137 | 00: lwzu r5,4(r4) | ||
138 | stwbrx r5,0,r3 | ||
139 | EIEIO_32 | ||
140 | bdnz 00b | ||
141 | SYNC_64 | ||
142 | blr | ||
143 | |||
144 | #ifdef CONFIG_PPC32 | ||
145 | _GLOBAL(__ide_mm_insw) | ||
146 | #endif | ||
147 | _GLOBAL(_insw_ns) | ||
148 | cmpwi 0,r5,0 | ||
149 | mtctr r5 | ||
150 | subi r4,r4,2 | ||
151 | blelr- | ||
152 | 00: lhz r5,0(r3) | ||
153 | eieio | ||
154 | sthu r5,2(r4) | ||
155 | bdnz 00b | ||
156 | IN_SYNC | ||
157 | blr | ||
158 | |||
159 | #ifdef CONFIG_PPC32 | ||
160 | _GLOBAL(__ide_mm_outsw) | ||
161 | #endif | ||
162 | _GLOBAL(_outsw_ns) | ||
163 | cmpwi 0,r5,0 | ||
164 | mtctr r5 | ||
165 | subi r4,r4,2 | ||
166 | blelr- | ||
167 | 00: lhzu r5,2(r4) | ||
168 | sth r5,0(r3) | ||
169 | EIEIO_32 | ||
170 | bdnz 00b | ||
171 | SYNC_64 | ||
172 | blr | ||
173 | |||
174 | #ifdef CONFIG_PPC32 | ||
175 | _GLOBAL(__ide_mm_insl) | ||
176 | #endif | ||
177 | _GLOBAL(_insl_ns) | ||
178 | cmpwi 0,r5,0 | ||
179 | mtctr r5 | ||
180 | subi r4,r4,4 | ||
181 | blelr- | ||
182 | 00: lwz r5,0(r3) | ||
183 | eieio | ||
184 | stwu r5,4(r4) | ||
185 | bdnz 00b | ||
186 | IN_SYNC | ||
187 | blr | ||
188 | |||
189 | #ifdef CONFIG_PPC32 | ||
190 | _GLOBAL(__ide_mm_outsl) | ||
191 | #endif | ||
192 | _GLOBAL(_outsl_ns) | ||
193 | cmpwi 0,r5,0 | ||
194 | mtctr r5 | ||
195 | subi r4,r4,4 | ||
196 | blelr- | ||
197 | 00: lwzu r5,4(r4) | ||
198 | stw r5,0(r3) | ||
199 | EIEIO_32 | ||
200 | bdnz 00b | ||
201 | SYNC_64 | ||
202 | blr | ||
203 | |||
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 01d3916c4cb1..c74774e2175d 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S | |||
@@ -61,32 +61,6 @@ _GLOBAL(mulhdu) | |||
61 | blr | 61 | blr |
62 | 62 | ||
63 | /* | 63 | /* |
64 | * Returns (address we're running at) - (address we were linked at) | ||
65 | * for use before the text and data are mapped to KERNELBASE. | ||
66 | */ | ||
67 | _GLOBAL(reloc_offset) | ||
68 | mflr r0 | ||
69 | bl 1f | ||
70 | 1: mflr r3 | ||
71 | LOAD_REG_IMMEDIATE(r4,1b) | ||
72 | subf r3,r4,r3 | ||
73 | mtlr r0 | ||
74 | blr | ||
75 | |||
76 | /* | ||
77 | * add_reloc_offset(x) returns x + reloc_offset(). | ||
78 | */ | ||
79 | _GLOBAL(add_reloc_offset) | ||
80 | mflr r0 | ||
81 | bl 1f | ||
82 | 1: mflr r5 | ||
83 | LOAD_REG_IMMEDIATE(r4,1b) | ||
84 | subf r5,r4,r5 | ||
85 | add r3,r3,r5 | ||
86 | mtlr r0 | ||
87 | blr | ||
88 | |||
89 | /* | ||
90 | * sub_reloc_offset(x) returns x - reloc_offset(). | 64 | * sub_reloc_offset(x) returns x - reloc_offset(). |
91 | */ | 65 | */ |
92 | _GLOBAL(sub_reloc_offset) | 66 | _GLOBAL(sub_reloc_offset) |
@@ -781,136 +755,6 @@ _GLOBAL(atomic_set_mask) | |||
781 | blr | 755 | blr |
782 | 756 | ||
783 | /* | 757 | /* |
784 | * I/O string operations | ||
785 | * | ||
786 | * insb(port, buf, len) | ||
787 | * outsb(port, buf, len) | ||
788 | * insw(port, buf, len) | ||
789 | * outsw(port, buf, len) | ||
790 | * insl(port, buf, len) | ||
791 | * outsl(port, buf, len) | ||
792 | * insw_ns(port, buf, len) | ||
793 | * outsw_ns(port, buf, len) | ||
794 | * insl_ns(port, buf, len) | ||
795 | * outsl_ns(port, buf, len) | ||
796 | * | ||
797 | * The *_ns versions don't do byte-swapping. | ||
798 | */ | ||
799 | _GLOBAL(_insb) | ||
800 | cmpwi 0,r5,0 | ||
801 | mtctr r5 | ||
802 | subi r4,r4,1 | ||
803 | blelr- | ||
804 | 00: lbz r5,0(r3) | ||
805 | eieio | ||
806 | stbu r5,1(r4) | ||
807 | bdnz 00b | ||
808 | blr | ||
809 | |||
810 | _GLOBAL(_outsb) | ||
811 | cmpwi 0,r5,0 | ||
812 | mtctr r5 | ||
813 | subi r4,r4,1 | ||
814 | blelr- | ||
815 | 00: lbzu r5,1(r4) | ||
816 | stb r5,0(r3) | ||
817 | eieio | ||
818 | bdnz 00b | ||
819 | blr | ||
820 | |||
821 | _GLOBAL(_insw) | ||
822 | cmpwi 0,r5,0 | ||
823 | mtctr r5 | ||
824 | subi r4,r4,2 | ||
825 | blelr- | ||
826 | 00: lhbrx r5,0,r3 | ||
827 | eieio | ||
828 | sthu r5,2(r4) | ||
829 | bdnz 00b | ||
830 | blr | ||
831 | |||
832 | _GLOBAL(_outsw) | ||
833 | cmpwi 0,r5,0 | ||
834 | mtctr r5 | ||
835 | subi r4,r4,2 | ||
836 | blelr- | ||
837 | 00: lhzu r5,2(r4) | ||
838 | eieio | ||
839 | sthbrx r5,0,r3 | ||
840 | bdnz 00b | ||
841 | blr | ||
842 | |||
843 | _GLOBAL(_insl) | ||
844 | cmpwi 0,r5,0 | ||
845 | mtctr r5 | ||
846 | subi r4,r4,4 | ||
847 | blelr- | ||
848 | 00: lwbrx r5,0,r3 | ||
849 | eieio | ||
850 | stwu r5,4(r4) | ||
851 | bdnz 00b | ||
852 | blr | ||
853 | |||
854 | _GLOBAL(_outsl) | ||
855 | cmpwi 0,r5,0 | ||
856 | mtctr r5 | ||
857 | subi r4,r4,4 | ||
858 | blelr- | ||
859 | 00: lwzu r5,4(r4) | ||
860 | stwbrx r5,0,r3 | ||
861 | eieio | ||
862 | bdnz 00b | ||
863 | blr | ||
864 | |||
865 | _GLOBAL(__ide_mm_insw) | ||
866 | _GLOBAL(_insw_ns) | ||
867 | cmpwi 0,r5,0 | ||
868 | mtctr r5 | ||
869 | subi r4,r4,2 | ||
870 | blelr- | ||
871 | 00: lhz r5,0(r3) | ||
872 | eieio | ||
873 | sthu r5,2(r4) | ||
874 | bdnz 00b | ||
875 | blr | ||
876 | |||
877 | _GLOBAL(__ide_mm_outsw) | ||
878 | _GLOBAL(_outsw_ns) | ||
879 | cmpwi 0,r5,0 | ||
880 | mtctr r5 | ||
881 | subi r4,r4,2 | ||
882 | blelr- | ||
883 | 00: lhzu r5,2(r4) | ||
884 | sth r5,0(r3) | ||
885 | eieio | ||
886 | bdnz 00b | ||
887 | blr | ||
888 | |||
889 | _GLOBAL(__ide_mm_insl) | ||
890 | _GLOBAL(_insl_ns) | ||
891 | cmpwi 0,r5,0 | ||
892 | mtctr r5 | ||
893 | subi r4,r4,4 | ||
894 | blelr- | ||
895 | 00: lwz r5,0(r3) | ||
896 | eieio | ||
897 | stwu r5,4(r4) | ||
898 | bdnz 00b | ||
899 | blr | ||
900 | |||
901 | _GLOBAL(__ide_mm_outsl) | ||
902 | _GLOBAL(_outsl_ns) | ||
903 | cmpwi 0,r5,0 | ||
904 | mtctr r5 | ||
905 | subi r4,r4,4 | ||
906 | blelr- | ||
907 | 00: lwzu r5,4(r4) | ||
908 | stw r5,0(r3) | ||
909 | eieio | ||
910 | bdnz 00b | ||
911 | blr | ||
912 | |||
913 | /* | ||
914 | * Extended precision shifts. | 758 | * Extended precision shifts. |
915 | * | 759 | * |
916 | * Updated to be valid for shift counts from 0 to 63 inclusive. | 760 | * Updated to be valid for shift counts from 0 to 63 inclusive. |
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index e8883d42c43c..580891cb8ccb 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S | |||
@@ -1,14 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * arch/powerpc/kernel/misc64.S | ||
3 | * | ||
4 | * This file contains miscellaneous low-level functions. | 2 | * This file contains miscellaneous low-level functions. |
5 | * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) | 3 | * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) |
6 | * | 4 | * |
7 | * Largely rewritten by Cort Dougan (cort@cs.nmt.edu) | 5 | * Largely rewritten by Cort Dougan (cort@cs.nmt.edu) |
8 | * and Paul Mackerras. | 6 | * and Paul Mackerras. |
9 | * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com) | 7 | * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com) |
10 | * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com) | 8 | * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com) |
11 | * | 9 | * |
12 | * This program is free software; you can redistribute it and/or | 10 | * This program is free software; you can redistribute it and/or |
13 | * modify it under the terms of the GNU General Public License | 11 | * modify it under the terms of the GNU General Public License |
14 | * as published by the Free Software Foundation; either version | 12 | * as published by the Free Software Foundation; either version |
@@ -30,41 +28,10 @@ | |||
30 | 28 | ||
31 | .text | 29 | .text |
32 | 30 | ||
33 | /* | ||
34 | * Returns (address we are running at) - (address we were linked at) | ||
35 | * for use before the text and data are mapped to KERNELBASE. | ||
36 | */ | ||
37 | |||
38 | _GLOBAL(reloc_offset) | ||
39 | mflr r0 | ||
40 | bl 1f | ||
41 | 1: mflr r3 | ||
42 | LOAD_REG_IMMEDIATE(r4,1b) | ||
43 | subf r3,r4,r3 | ||
44 | mtlr r0 | ||
45 | blr | ||
46 | |||
47 | /* | ||
48 | * add_reloc_offset(x) returns x + reloc_offset(). | ||
49 | */ | ||
50 | _GLOBAL(add_reloc_offset) | ||
51 | mflr r0 | ||
52 | bl 1f | ||
53 | 1: mflr r5 | ||
54 | LOAD_REG_IMMEDIATE(r4,1b) | ||
55 | subf r5,r4,r5 | ||
56 | add r3,r3,r5 | ||
57 | mtlr r0 | ||
58 | blr | ||
59 | |||
60 | _GLOBAL(get_msr) | 31 | _GLOBAL(get_msr) |
61 | mfmsr r3 | 32 | mfmsr r3 |
62 | blr | 33 | blr |
63 | 34 | ||
64 | _GLOBAL(get_dar) | ||
65 | mfdar r3 | ||
66 | blr | ||
67 | |||
68 | _GLOBAL(get_srr0) | 35 | _GLOBAL(get_srr0) |
69 | mfsrr0 r3 | 36 | mfsrr0 r3 |
70 | blr | 37 | blr |
@@ -72,10 +39,6 @@ _GLOBAL(get_srr0) | |||
72 | _GLOBAL(get_srr1) | 39 | _GLOBAL(get_srr1) |
73 | mfsrr1 r3 | 40 | mfsrr1 r3 |
74 | blr | 41 | blr |
75 | |||
76 | _GLOBAL(get_sp) | ||
77 | mr r3,r1 | ||
78 | blr | ||
79 | 42 | ||
80 | #ifdef CONFIG_IRQSTACKS | 43 | #ifdef CONFIG_IRQSTACKS |
81 | _GLOBAL(call_do_softirq) | 44 | _GLOBAL(call_do_softirq) |
@@ -101,48 +64,6 @@ _GLOBAL(call___do_IRQ) | |||
101 | blr | 64 | blr |
102 | #endif /* CONFIG_IRQSTACKS */ | 65 | #endif /* CONFIG_IRQSTACKS */ |
103 | 66 | ||
104 | /* | ||
105 | * To be called by C code which needs to do some operations with MMU | ||
106 | * disabled. Note that interrupts have to be disabled by the caller | ||
107 | * prior to calling us. The code called _MUST_ be in the RMO of course | ||
108 | * and part of the linear mapping as we don't attempt to translate the | ||
109 | * stack pointer at all. The function is called with the stack switched | ||
110 | * to this CPU emergency stack | ||
111 | * | ||
112 | * prototype is void *call_with_mmu_off(void *func, void *data); | ||
113 | * | ||
114 | * the called function is expected to be of the form | ||
115 | * | ||
116 | * void *called(void *data); | ||
117 | */ | ||
118 | _GLOBAL(call_with_mmu_off) | ||
119 | mflr r0 /* get link, save it on stackframe */ | ||
120 | std r0,16(r1) | ||
121 | mr r1,r5 /* save old stack ptr */ | ||
122 | ld r1,PACAEMERGSP(r13) /* get emerg. stack */ | ||
123 | subi r1,r1,STACK_FRAME_OVERHEAD | ||
124 | std r0,16(r1) /* save link on emerg. stack */ | ||
125 | std r5,0(r1) /* save old stack ptr in backchain */ | ||
126 | ld r3,0(r3) /* get to real function ptr (assume same TOC) */ | ||
127 | bl 2f /* we need LR to return, continue at label 2 */ | ||
128 | |||
129 | ld r0,16(r1) /* we return here from the call, get LR and */ | ||
130 | ld r1,0(r1) /* .. old stack ptr */ | ||
131 | mtspr SPRN_SRR0,r0 /* and get back to virtual mode with these */ | ||
132 | mfmsr r4 | ||
133 | ori r4,r4,MSR_IR|MSR_DR | ||
134 | mtspr SPRN_SRR1,r4 | ||
135 | rfid | ||
136 | |||
137 | 2: mtspr SPRN_SRR0,r3 /* coming from above, enter real mode */ | ||
138 | mr r3,r4 /* get parameter */ | ||
139 | mfmsr r0 | ||
140 | ori r0,r0,MSR_IR|MSR_DR | ||
141 | xori r0,r0,MSR_IR|MSR_DR | ||
142 | mtspr SPRN_SRR1,r0 | ||
143 | rfid | ||
144 | |||
145 | |||
146 | .section ".toc","aw" | 67 | .section ".toc","aw" |
147 | PPC64_CACHES: | 68 | PPC64_CACHES: |
148 | .tc ppc64_caches[TC],ppc64_caches | 69 | .tc ppc64_caches[TC],ppc64_caches |
@@ -323,144 +244,6 @@ _GLOBAL(__flush_dcache_icache) | |||
323 | bdnz 1b | 244 | bdnz 1b |
324 | isync | 245 | isync |
325 | blr | 246 | blr |
326 | |||
327 | /* | ||
328 | * I/O string operations | ||
329 | * | ||
330 | * insb(port, buf, len) | ||
331 | * outsb(port, buf, len) | ||
332 | * insw(port, buf, len) | ||
333 | * outsw(port, buf, len) | ||
334 | * insl(port, buf, len) | ||
335 | * outsl(port, buf, len) | ||
336 | * insw_ns(port, buf, len) | ||
337 | * outsw_ns(port, buf, len) | ||
338 | * insl_ns(port, buf, len) | ||
339 | * outsl_ns(port, buf, len) | ||
340 | * | ||
341 | * The *_ns versions don't do byte-swapping. | ||
342 | */ | ||
343 | _GLOBAL(_insb) | ||
344 | cmpwi 0,r5,0 | ||
345 | mtctr r5 | ||
346 | subi r4,r4,1 | ||
347 | blelr- | ||
348 | 00: lbz r5,0(r3) | ||
349 | eieio | ||
350 | stbu r5,1(r4) | ||
351 | bdnz 00b | ||
352 | twi 0,r5,0 | ||
353 | isync | ||
354 | blr | ||
355 | |||
356 | _GLOBAL(_outsb) | ||
357 | cmpwi 0,r5,0 | ||
358 | mtctr r5 | ||
359 | subi r4,r4,1 | ||
360 | blelr- | ||
361 | 00: lbzu r5,1(r4) | ||
362 | stb r5,0(r3) | ||
363 | bdnz 00b | ||
364 | sync | ||
365 | blr | ||
366 | |||
367 | _GLOBAL(_insw) | ||
368 | cmpwi 0,r5,0 | ||
369 | mtctr r5 | ||
370 | subi r4,r4,2 | ||
371 | blelr- | ||
372 | 00: lhbrx r5,0,r3 | ||
373 | eieio | ||
374 | sthu r5,2(r4) | ||
375 | bdnz 00b | ||
376 | twi 0,r5,0 | ||
377 | isync | ||
378 | blr | ||
379 | |||
380 | _GLOBAL(_outsw) | ||
381 | cmpwi 0,r5,0 | ||
382 | mtctr r5 | ||
383 | subi r4,r4,2 | ||
384 | blelr- | ||
385 | 00: lhzu r5,2(r4) | ||
386 | sthbrx r5,0,r3 | ||
387 | bdnz 00b | ||
388 | sync | ||
389 | blr | ||
390 | |||
391 | _GLOBAL(_insl) | ||
392 | cmpwi 0,r5,0 | ||
393 | mtctr r5 | ||
394 | subi r4,r4,4 | ||
395 | blelr- | ||
396 | 00: lwbrx r5,0,r3 | ||
397 | eieio | ||
398 | stwu r5,4(r4) | ||
399 | bdnz 00b | ||
400 | twi 0,r5,0 | ||
401 | isync | ||
402 | blr | ||
403 | |||
404 | _GLOBAL(_outsl) | ||
405 | cmpwi 0,r5,0 | ||
406 | mtctr r5 | ||
407 | subi r4,r4,4 | ||
408 | blelr- | ||
409 | 00: lwzu r5,4(r4) | ||
410 | stwbrx r5,0,r3 | ||
411 | bdnz 00b | ||
412 | sync | ||
413 | blr | ||
414 | |||
415 | /* _GLOBAL(ide_insw) now in drivers/ide/ide-iops.c */ | ||
416 | _GLOBAL(_insw_ns) | ||
417 | cmpwi 0,r5,0 | ||
418 | mtctr r5 | ||
419 | subi r4,r4,2 | ||
420 | blelr- | ||
421 | 00: lhz r5,0(r3) | ||
422 | eieio | ||
423 | sthu r5,2(r4) | ||
424 | bdnz 00b | ||
425 | twi 0,r5,0 | ||
426 | isync | ||
427 | blr | ||
428 | |||
429 | /* _GLOBAL(ide_outsw) now in drivers/ide/ide-iops.c */ | ||
430 | _GLOBAL(_outsw_ns) | ||
431 | cmpwi 0,r5,0 | ||
432 | mtctr r5 | ||
433 | subi r4,r4,2 | ||
434 | blelr- | ||
435 | 00: lhzu r5,2(r4) | ||
436 | sth r5,0(r3) | ||
437 | bdnz 00b | ||
438 | sync | ||
439 | blr | ||
440 | |||
441 | _GLOBAL(_insl_ns) | ||
442 | cmpwi 0,r5,0 | ||
443 | mtctr r5 | ||
444 | subi r4,r4,4 | ||
445 | blelr- | ||
446 | 00: lwz r5,0(r3) | ||
447 | eieio | ||
448 | stwu r5,4(r4) | ||
449 | bdnz 00b | ||
450 | twi 0,r5,0 | ||
451 | isync | ||
452 | blr | ||
453 | |||
454 | _GLOBAL(_outsl_ns) | ||
455 | cmpwi 0,r5,0 | ||
456 | mtctr r5 | ||
457 | subi r4,r4,4 | ||
458 | blelr- | ||
459 | 00: lwzu r5,4(r4) | ||
460 | stw r5,0(r3) | ||
461 | bdnz 00b | ||
462 | sync | ||
463 | blr | ||
464 | 247 | ||
465 | /* | 248 | /* |
466 | * identify_cpu and calls setup_cpu | 249 | * identify_cpu and calls setup_cpu |
@@ -605,6 +388,7 @@ _GLOBAL(real_writeb) | |||
605 | blr | 388 | blr |
606 | #endif /* defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) */ | 389 | #endif /* defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) */ |
607 | 390 | ||
391 | #ifdef CONFIG_CPU_FREQ_PMAC64 | ||
608 | /* | 392 | /* |
609 | * SCOM access functions for 970 (FX only for now) | 393 | * SCOM access functions for 970 (FX only for now) |
610 | * | 394 | * |
@@ -673,6 +457,7 @@ _GLOBAL(scom970_write) | |||
673 | /* restore interrupts */ | 457 | /* restore interrupts */ |
674 | mtmsrd r5,1 | 458 | mtmsrd r5,1 |
675 | blr | 459 | blr |
460 | #endif /* CONFIG_CPU_FREQ_PMAC64 */ | ||
676 | 461 | ||
677 | 462 | ||
678 | /* | 463 | /* |
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c index f505a8827e3e..a0bb354c1c08 100644 --- a/arch/powerpc/kernel/paca.c +++ b/arch/powerpc/kernel/paca.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <asm/ptrace.h> | 16 | #include <asm/ptrace.h> |
17 | #include <asm/page.h> | 17 | #include <asm/page.h> |
18 | #include <asm/lppaca.h> | 18 | #include <asm/lppaca.h> |
19 | #include <asm/iseries/it_lp_queue.h> | ||
20 | #include <asm/iseries/it_lp_reg_save.h> | 19 | #include <asm/iseries/it_lp_reg_save.h> |
21 | #include <asm/paca.h> | 20 | #include <asm/paca.h> |
22 | 21 | ||
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index b5431ccf1147..8474355a1a4f 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c | |||
@@ -99,7 +99,7 @@ pcibios_fixup_resources(struct pci_dev *dev) | |||
99 | if (!res->flags) | 99 | if (!res->flags) |
100 | continue; | 100 | continue; |
101 | if (res->end == 0xffffffff) { | 101 | if (res->end == 0xffffffff) { |
102 | DBG("PCI:%s Resource %d [%08lx-%08lx] is unassigned\n", | 102 | DBG("PCI:%s Resource %d [%016llx-%016llx] is unassigned\n", |
103 | pci_name(dev), i, res->start, res->end); | 103 | pci_name(dev), i, res->start, res->end); |
104 | res->end -= res->start; | 104 | res->end -= res->start; |
105 | res->start = 0; | 105 | res->start = 0; |
@@ -117,7 +117,7 @@ pcibios_fixup_resources(struct pci_dev *dev) | |||
117 | res->start += offset; | 117 | res->start += offset; |
118 | res->end += offset; | 118 | res->end += offset; |
119 | #ifdef DEBUG | 119 | #ifdef DEBUG |
120 | printk("Fixup res %d (%lx) of dev %s: %lx -> %lx\n", | 120 | printk("Fixup res %d (%lx) of dev %s: %llx -> %llx\n", |
121 | i, res->flags, pci_name(dev), | 121 | i, res->flags, pci_name(dev), |
122 | res->start - offset, res->start); | 122 | res->start - offset, res->start); |
123 | #endif | 123 | #endif |
@@ -173,18 +173,18 @@ EXPORT_SYMBOL(pcibios_bus_to_resource); | |||
173 | * but we want to try to avoid allocating at 0x2900-0x2bff | 173 | * but we want to try to avoid allocating at 0x2900-0x2bff |
174 | * which might have be mirrored at 0x0100-0x03ff.. | 174 | * which might have be mirrored at 0x0100-0x03ff.. |
175 | */ | 175 | */ |
176 | void pcibios_align_resource(void *data, struct resource *res, unsigned long size, | 176 | void pcibios_align_resource(void *data, struct resource *res, |
177 | unsigned long align) | 177 | resource_size_t size, resource_size_t align) |
178 | { | 178 | { |
179 | struct pci_dev *dev = data; | 179 | struct pci_dev *dev = data; |
180 | 180 | ||
181 | if (res->flags & IORESOURCE_IO) { | 181 | if (res->flags & IORESOURCE_IO) { |
182 | unsigned long start = res->start; | 182 | resource_size_t start = res->start; |
183 | 183 | ||
184 | if (size > 0x100) { | 184 | if (size > 0x100) { |
185 | printk(KERN_ERR "PCI: I/O Region %s/%d too large" | 185 | printk(KERN_ERR "PCI: I/O Region %s/%d too large" |
186 | " (%ld bytes)\n", pci_name(dev), | 186 | " (%lld bytes)\n", pci_name(dev), |
187 | dev->resource - res, size); | 187 | dev->resource - res, (unsigned long long)size); |
188 | } | 188 | } |
189 | 189 | ||
190 | if (start & 0x300) { | 190 | if (start & 0x300) { |
@@ -255,8 +255,8 @@ pcibios_allocate_bus_resources(struct list_head *bus_list) | |||
255 | } | 255 | } |
256 | } | 256 | } |
257 | 257 | ||
258 | DBG("PCI: bridge rsrc %lx..%lx (%lx), parent %p\n", | 258 | DBG("PCI: bridge rsrc %llx..%llx (%lx), parent %p\n", |
259 | res->start, res->end, res->flags, pr); | 259 | res->start, res->end, res->flags, pr); |
260 | if (pr) { | 260 | if (pr) { |
261 | if (request_resource(pr, res) == 0) | 261 | if (request_resource(pr, res) == 0) |
262 | continue; | 262 | continue; |
@@ -306,7 +306,7 @@ reparent_resources(struct resource *parent, struct resource *res) | |||
306 | *pp = NULL; | 306 | *pp = NULL; |
307 | for (p = res->child; p != NULL; p = p->sibling) { | 307 | for (p = res->child; p != NULL; p = p->sibling) { |
308 | p->parent = res; | 308 | p->parent = res; |
309 | DBG(KERN_INFO "PCI: reparented %s [%lx..%lx] under %s\n", | 309 | DBG(KERN_INFO "PCI: reparented %s [%llx..%llx] under %s\n", |
310 | p->name, p->start, p->end, res->name); | 310 | p->name, p->start, p->end, res->name); |
311 | } | 311 | } |
312 | return 0; | 312 | return 0; |
@@ -362,13 +362,14 @@ pci_relocate_bridge_resource(struct pci_bus *bus, int i) | |||
362 | try = conflict->start - 1; | 362 | try = conflict->start - 1; |
363 | } | 363 | } |
364 | if (request_resource(pr, res)) { | 364 | if (request_resource(pr, res)) { |
365 | DBG(KERN_ERR "PCI: huh? couldn't move to %lx..%lx\n", | 365 | DBG(KERN_ERR "PCI: huh? couldn't move to %llx..%llx\n", |
366 | res->start, res->end); | 366 | res->start, res->end); |
367 | return -1; /* "can't happen" */ | 367 | return -1; /* "can't happen" */ |
368 | } | 368 | } |
369 | update_bridge_base(bus, i); | 369 | update_bridge_base(bus, i); |
370 | printk(KERN_INFO "PCI: bridge %d resource %d moved to %lx..%lx\n", | 370 | printk(KERN_INFO "PCI: bridge %d resource %d moved to %llx..%llx\n", |
371 | bus->number, i, res->start, res->end); | 371 | bus->number, i, (unsigned long long)res->start, |
372 | (unsigned long long)res->end); | ||
372 | return 0; | 373 | return 0; |
373 | } | 374 | } |
374 | 375 | ||
@@ -479,14 +480,14 @@ static inline void alloc_resource(struct pci_dev *dev, int idx) | |||
479 | { | 480 | { |
480 | struct resource *pr, *r = &dev->resource[idx]; | 481 | struct resource *pr, *r = &dev->resource[idx]; |
481 | 482 | ||
482 | DBG("PCI:%s: Resource %d: %08lx-%08lx (f=%lx)\n", | 483 | DBG("PCI:%s: Resource %d: %016llx-%016llx (f=%lx)\n", |
483 | pci_name(dev), idx, r->start, r->end, r->flags); | 484 | pci_name(dev), idx, r->start, r->end, r->flags); |
484 | pr = pci_find_parent_resource(dev, r); | 485 | pr = pci_find_parent_resource(dev, r); |
485 | if (!pr || request_resource(pr, r) < 0) { | 486 | if (!pr || request_resource(pr, r) < 0) { |
486 | printk(KERN_ERR "PCI: Cannot allocate resource region %d" | 487 | printk(KERN_ERR "PCI: Cannot allocate resource region %d" |
487 | " of device %s\n", idx, pci_name(dev)); | 488 | " of device %s\n", idx, pci_name(dev)); |
488 | if (pr) | 489 | if (pr) |
489 | DBG("PCI: parent is %p: %08lx-%08lx (f=%lx)\n", | 490 | DBG("PCI: parent is %p: %016llx-%016llx (f=%lx)\n", |
490 | pr, pr->start, pr->end, pr->flags); | 491 | pr, pr->start, pr->end, pr->flags); |
491 | /* We'll assign a new address later */ | 492 | /* We'll assign a new address later */ |
492 | r->flags |= IORESOURCE_UNSET; | 493 | r->flags |= IORESOURCE_UNSET; |
@@ -956,7 +957,7 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose, | |||
956 | res = &hose->io_resource; | 957 | res = &hose->io_resource; |
957 | res->flags = IORESOURCE_IO; | 958 | res->flags = IORESOURCE_IO; |
958 | res->start = ranges[2]; | 959 | res->start = ranges[2]; |
959 | DBG("PCI: IO 0x%lx -> 0x%lx\n", | 960 | DBG("PCI: IO 0x%llx -> 0x%llx\n", |
960 | res->start, res->start + size - 1); | 961 | res->start, res->start + size - 1); |
961 | break; | 962 | break; |
962 | case 2: /* memory space */ | 963 | case 2: /* memory space */ |
@@ -978,7 +979,7 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose, | |||
978 | if(ranges[0] & 0x40000000) | 979 | if(ranges[0] & 0x40000000) |
979 | res->flags |= IORESOURCE_PREFETCH; | 980 | res->flags |= IORESOURCE_PREFETCH; |
980 | res->start = ranges[na+2]; | 981 | res->start = ranges[na+2]; |
981 | DBG("PCI: MEM[%d] 0x%lx -> 0x%lx\n", memno, | 982 | DBG("PCI: MEM[%d] 0x%llx -> 0x%llx\n", memno, |
982 | res->start, res->start + size - 1); | 983 | res->start, res->start + size - 1); |
983 | } | 984 | } |
984 | break; | 985 | break; |
@@ -1074,7 +1075,7 @@ do_update_p2p_io_resource(struct pci_bus *bus, int enable_vga) | |||
1074 | DBG("Remapping Bus %d, bridge: %s\n", bus->number, pci_name(bridge)); | 1075 | DBG("Remapping Bus %d, bridge: %s\n", bus->number, pci_name(bridge)); |
1075 | res.start -= ((unsigned long) hose->io_base_virt - isa_io_base); | 1076 | res.start -= ((unsigned long) hose->io_base_virt - isa_io_base); |
1076 | res.end -= ((unsigned long) hose->io_base_virt - isa_io_base); | 1077 | res.end -= ((unsigned long) hose->io_base_virt - isa_io_base); |
1077 | DBG(" IO window: %08lx-%08lx\n", res.start, res.end); | 1078 | DBG(" IO window: %016llx-%016llx\n", res.start, res.end); |
1078 | 1079 | ||
1079 | /* Set up the top and bottom of the PCI I/O segment for this bus. */ | 1080 | /* Set up the top and bottom of the PCI I/O segment for this bus. */ |
1080 | pci_read_config_dword(bridge, PCI_IO_BASE, &l); | 1081 | pci_read_config_dword(bridge, PCI_IO_BASE, &l); |
@@ -1223,8 +1224,8 @@ do_fixup_p2p_level(struct pci_bus *bus) | |||
1223 | continue; | 1224 | continue; |
1224 | if ((r->flags & IORESOURCE_IO) == 0) | 1225 | if ((r->flags & IORESOURCE_IO) == 0) |
1225 | continue; | 1226 | continue; |
1226 | DBG("Trying to allocate from %08lx, size %08lx from parent" | 1227 | DBG("Trying to allocate from %016llx, size %016llx from parent" |
1227 | " res %d: %08lx -> %08lx\n", | 1228 | " res %d: %016llx -> %016llx\n", |
1228 | res->start, res->end, i, r->start, r->end); | 1229 | res->start, res->end, i, r->start, r->end); |
1229 | 1230 | ||
1230 | if (allocate_resource(r, res, res->end + 1, res->start, max, | 1231 | if (allocate_resource(r, res, res->end + 1, res->start, max, |
@@ -1574,8 +1575,8 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, | |||
1574 | else | 1575 | else |
1575 | prot |= _PAGE_GUARDED; | 1576 | prot |= _PAGE_GUARDED; |
1576 | 1577 | ||
1577 | printk("PCI map for %s:%lx, prot: %lx\n", pci_name(dev), rp->start, | 1578 | printk("PCI map for %s:%llx, prot: %lx\n", pci_name(dev), |
1578 | prot); | 1579 | (unsigned long long)rp->start, prot); |
1579 | 1580 | ||
1580 | return __pgprot(prot); | 1581 | return __pgprot(prot); |
1581 | } | 1582 | } |
@@ -1755,7 +1756,7 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn) | |||
1755 | 1756 | ||
1756 | void pci_resource_to_user(const struct pci_dev *dev, int bar, | 1757 | void pci_resource_to_user(const struct pci_dev *dev, int bar, |
1757 | const struct resource *rsrc, | 1758 | const struct resource *rsrc, |
1758 | u64 *start, u64 *end) | 1759 | resource_size_t *start, resource_size_t *end) |
1759 | { | 1760 | { |
1760 | struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); | 1761 | struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); |
1761 | unsigned long offset = 0; | 1762 | unsigned long offset = 0; |
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 247937dd8b73..286aa52aae33 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c | |||
@@ -138,11 +138,11 @@ EXPORT_SYMBOL(pcibios_bus_to_resource); | |||
138 | * which might have be mirrored at 0x0100-0x03ff.. | 138 | * which might have be mirrored at 0x0100-0x03ff.. |
139 | */ | 139 | */ |
140 | void pcibios_align_resource(void *data, struct resource *res, | 140 | void pcibios_align_resource(void *data, struct resource *res, |
141 | unsigned long size, unsigned long align) | 141 | resource_size_t size, resource_size_t align) |
142 | { | 142 | { |
143 | struct pci_dev *dev = data; | 143 | struct pci_dev *dev = data; |
144 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | 144 | struct pci_controller *hose = pci_bus_to_host(dev->bus); |
145 | unsigned long start = res->start; | 145 | resource_size_t start = res->start; |
146 | unsigned long alignto; | 146 | unsigned long alignto; |
147 | 147 | ||
148 | if (res->flags & IORESOURCE_IO) { | 148 | if (res->flags & IORESOURCE_IO) { |
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 483455c5bb02..320c913435cd 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/bitops.h> | 30 | #include <linux/bitops.h> |
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/kexec.h> | 32 | #include <linux/kexec.h> |
33 | #include <linux/debugfs.h> | ||
33 | 34 | ||
34 | #include <asm/prom.h> | 35 | #include <asm/prom.h> |
35 | #include <asm/rtas.h> | 36 | #include <asm/rtas.h> |
@@ -952,6 +953,7 @@ static struct ibm_pa_feature { | |||
952 | /* put this back once we know how to test if firmware does 64k IO */ | 953 | /* put this back once we know how to test if firmware does 64k IO */ |
953 | {CPU_FTR_CI_LARGE_PAGE, 0, 1, 2, 0}, | 954 | {CPU_FTR_CI_LARGE_PAGE, 0, 1, 2, 0}, |
954 | #endif | 955 | #endif |
956 | {CPU_FTR_REAL_LE, PPC_FEATURE_TRUE_LE, 5, 0, 0}, | ||
955 | }; | 957 | }; |
956 | 958 | ||
957 | static void __init check_cpu_pa_features(unsigned long node) | 959 | static void __init check_cpu_pa_features(unsigned long node) |
@@ -1124,24 +1126,6 @@ static int __init early_init_dt_scan_chosen(unsigned long node, | |||
1124 | tce_alloc_end = *lprop; | 1126 | tce_alloc_end = *lprop; |
1125 | #endif | 1127 | #endif |
1126 | 1128 | ||
1127 | #ifdef CONFIG_PPC_RTAS | ||
1128 | /* To help early debugging via the front panel, we retrieve a minimal | ||
1129 | * set of RTAS infos now if available | ||
1130 | */ | ||
1131 | { | ||
1132 | u64 *basep, *entryp, *sizep; | ||
1133 | |||
1134 | basep = of_get_flat_dt_prop(node, "linux,rtas-base", NULL); | ||
1135 | entryp = of_get_flat_dt_prop(node, "linux,rtas-entry", NULL); | ||
1136 | sizep = of_get_flat_dt_prop(node, "linux,rtas-size", NULL); | ||
1137 | if (basep && entryp && sizep) { | ||
1138 | rtas.base = *basep; | ||
1139 | rtas.entry = *entryp; | ||
1140 | rtas.size = *sizep; | ||
1141 | } | ||
1142 | } | ||
1143 | #endif /* CONFIG_PPC_RTAS */ | ||
1144 | |||
1145 | #ifdef CONFIG_KEXEC | 1129 | #ifdef CONFIG_KEXEC |
1146 | lprop = (u64*)of_get_flat_dt_prop(node, "linux,crashkernel-base", NULL); | 1130 | lprop = (u64*)of_get_flat_dt_prop(node, "linux,crashkernel-base", NULL); |
1147 | if (lprop) | 1131 | if (lprop) |
@@ -1326,6 +1310,11 @@ void __init early_init_devtree(void *params) | |||
1326 | /* Setup flat device-tree pointer */ | 1310 | /* Setup flat device-tree pointer */ |
1327 | initial_boot_params = params; | 1311 | initial_boot_params = params; |
1328 | 1312 | ||
1313 | #ifdef CONFIG_PPC_RTAS | ||
1314 | /* Some machines might need RTAS info for debugging, grab it now. */ | ||
1315 | of_scan_flat_dt(early_init_dt_scan_rtas, NULL); | ||
1316 | #endif | ||
1317 | |||
1329 | /* Retrieve various informations from the /chosen node of the | 1318 | /* Retrieve various informations from the /chosen node of the |
1330 | * device-tree, including the platform type, initrd location and | 1319 | * device-tree, including the platform type, initrd location and |
1331 | * size, TCE reserve, and more ... | 1320 | * size, TCE reserve, and more ... |
@@ -2148,3 +2137,27 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) | |||
2148 | } | 2137 | } |
2149 | return NULL; | 2138 | return NULL; |
2150 | } | 2139 | } |
2140 | |||
2141 | #ifdef DEBUG | ||
2142 | static struct debugfs_blob_wrapper flat_dt_blob; | ||
2143 | |||
2144 | static int __init export_flat_device_tree(void) | ||
2145 | { | ||
2146 | struct dentry *d; | ||
2147 | |||
2148 | d = debugfs_create_dir("powerpc", NULL); | ||
2149 | if (!d) | ||
2150 | return 1; | ||
2151 | |||
2152 | flat_dt_blob.data = initial_boot_params; | ||
2153 | flat_dt_blob.size = initial_boot_params->totalsize; | ||
2154 | |||
2155 | d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR, | ||
2156 | d, &flat_dt_blob); | ||
2157 | if (!d) | ||
2158 | return 1; | ||
2159 | |||
2160 | return 0; | ||
2161 | } | ||
2162 | __initcall(export_flat_device_tree); | ||
2163 | #endif | ||
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 17dc79198515..4a4cb5598402 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c | |||
@@ -38,16 +38,19 @@ | |||
38 | struct rtas_t rtas = { | 38 | struct rtas_t rtas = { |
39 | .lock = SPIN_LOCK_UNLOCKED | 39 | .lock = SPIN_LOCK_UNLOCKED |
40 | }; | 40 | }; |
41 | EXPORT_SYMBOL(rtas); | ||
41 | 42 | ||
42 | struct rtas_suspend_me_data { | 43 | struct rtas_suspend_me_data { |
43 | long waiting; | 44 | long waiting; |
44 | struct rtas_args *args; | 45 | struct rtas_args *args; |
45 | }; | 46 | }; |
46 | 47 | ||
47 | EXPORT_SYMBOL(rtas); | ||
48 | |||
49 | DEFINE_SPINLOCK(rtas_data_buf_lock); | 48 | DEFINE_SPINLOCK(rtas_data_buf_lock); |
49 | EXPORT_SYMBOL(rtas_data_buf_lock); | ||
50 | |||
50 | char rtas_data_buf[RTAS_DATA_BUF_SIZE] __cacheline_aligned; | 51 | char rtas_data_buf[RTAS_DATA_BUF_SIZE] __cacheline_aligned; |
52 | EXPORT_SYMBOL(rtas_data_buf); | ||
53 | |||
51 | unsigned long rtas_rmo_buf; | 54 | unsigned long rtas_rmo_buf; |
52 | 55 | ||
53 | /* | 56 | /* |
@@ -106,11 +109,71 @@ static void call_rtas_display_status_delay(char c) | |||
106 | } | 109 | } |
107 | } | 110 | } |
108 | 111 | ||
109 | void __init udbg_init_rtas(void) | 112 | void __init udbg_init_rtas_panel(void) |
110 | { | 113 | { |
111 | udbg_putc = call_rtas_display_status_delay; | 114 | udbg_putc = call_rtas_display_status_delay; |
112 | } | 115 | } |
113 | 116 | ||
117 | #ifdef CONFIG_UDBG_RTAS_CONSOLE | ||
118 | |||
119 | /* If you think you're dying before early_init_dt_scan_rtas() does its | ||
120 | * work, you can hard code the token values for your firmware here and | ||
121 | * hardcode rtas.base/entry etc. | ||
122 | */ | ||
123 | static unsigned int rtas_putchar_token = RTAS_UNKNOWN_SERVICE; | ||
124 | static unsigned int rtas_getchar_token = RTAS_UNKNOWN_SERVICE; | ||
125 | |||
126 | static void udbg_rtascon_putc(char c) | ||
127 | { | ||
128 | int tries; | ||
129 | |||
130 | if (!rtas.base) | ||
131 | return; | ||
132 | |||
133 | /* Add CRs before LFs */ | ||
134 | if (c == '\n') | ||
135 | udbg_rtascon_putc('\r'); | ||
136 | |||
137 | /* if there is more than one character to be displayed, wait a bit */ | ||
138 | for (tries = 0; tries < 16; tries++) { | ||
139 | if (rtas_call(rtas_putchar_token, 1, 1, NULL, c) == 0) | ||
140 | break; | ||
141 | udelay(1000); | ||
142 | } | ||
143 | } | ||
144 | |||
145 | static int udbg_rtascon_getc_poll(void) | ||
146 | { | ||
147 | int c; | ||
148 | |||
149 | if (!rtas.base) | ||
150 | return -1; | ||
151 | |||
152 | if (rtas_call(rtas_getchar_token, 0, 2, &c)) | ||
153 | return -1; | ||
154 | |||
155 | return c; | ||
156 | } | ||
157 | |||
158 | static int udbg_rtascon_getc(void) | ||
159 | { | ||
160 | int c; | ||
161 | |||
162 | while ((c = udbg_rtascon_getc_poll()) == -1) | ||
163 | ; | ||
164 | |||
165 | return c; | ||
166 | } | ||
167 | |||
168 | |||
169 | void __init udbg_init_rtas_console(void) | ||
170 | { | ||
171 | udbg_putc = udbg_rtascon_putc; | ||
172 | udbg_getc = udbg_rtascon_getc; | ||
173 | udbg_getc_poll = udbg_rtascon_getc_poll; | ||
174 | } | ||
175 | #endif /* CONFIG_UDBG_RTAS_CONSOLE */ | ||
176 | |||
114 | void rtas_progress(char *s, unsigned short hex) | 177 | void rtas_progress(char *s, unsigned short hex) |
115 | { | 178 | { |
116 | struct device_node *root; | 179 | struct device_node *root; |
@@ -236,6 +299,7 @@ int rtas_token(const char *service) | |||
236 | tokp = (int *) get_property(rtas.dev, service, NULL); | 299 | tokp = (int *) get_property(rtas.dev, service, NULL); |
237 | return tokp ? *tokp : RTAS_UNKNOWN_SERVICE; | 300 | return tokp ? *tokp : RTAS_UNKNOWN_SERVICE; |
238 | } | 301 | } |
302 | EXPORT_SYMBOL(rtas_token); | ||
239 | 303 | ||
240 | #ifdef CONFIG_RTAS_ERROR_LOGGING | 304 | #ifdef CONFIG_RTAS_ERROR_LOGGING |
241 | /* | 305 | /* |
@@ -328,7 +392,7 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...) | |||
328 | char *buff_copy = NULL; | 392 | char *buff_copy = NULL; |
329 | int ret; | 393 | int ret; |
330 | 394 | ||
331 | if (token == RTAS_UNKNOWN_SERVICE) | 395 | if (!rtas.entry || token == RTAS_UNKNOWN_SERVICE) |
332 | return -1; | 396 | return -1; |
333 | 397 | ||
334 | /* Gotta do something different here, use global lock for now... */ | 398 | /* Gotta do something different here, use global lock for now... */ |
@@ -369,6 +433,7 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...) | |||
369 | } | 433 | } |
370 | return ret; | 434 | return ret; |
371 | } | 435 | } |
436 | EXPORT_SYMBOL(rtas_call); | ||
372 | 437 | ||
373 | /* For RTAS_BUSY (-2), delay for 1 millisecond. For an extended busy status | 438 | /* For RTAS_BUSY (-2), delay for 1 millisecond. For an extended busy status |
374 | * code of 990n, perform the hinted delay of 10^n (last digit) milliseconds. | 439 | * code of 990n, perform the hinted delay of 10^n (last digit) milliseconds. |
@@ -388,6 +453,7 @@ unsigned int rtas_busy_delay_time(int status) | |||
388 | 453 | ||
389 | return ms; | 454 | return ms; |
390 | } | 455 | } |
456 | EXPORT_SYMBOL(rtas_busy_delay_time); | ||
391 | 457 | ||
392 | /* For an RTAS busy status code, perform the hinted delay. */ | 458 | /* For an RTAS busy status code, perform the hinted delay. */ |
393 | unsigned int rtas_busy_delay(int status) | 459 | unsigned int rtas_busy_delay(int status) |
@@ -401,6 +467,7 @@ unsigned int rtas_busy_delay(int status) | |||
401 | 467 | ||
402 | return ms; | 468 | return ms; |
403 | } | 469 | } |
470 | EXPORT_SYMBOL(rtas_busy_delay); | ||
404 | 471 | ||
405 | int rtas_error_rc(int rtas_rc) | 472 | int rtas_error_rc(int rtas_rc) |
406 | { | 473 | { |
@@ -446,6 +513,7 @@ int rtas_get_power_level(int powerdomain, int *level) | |||
446 | return rtas_error_rc(rc); | 513 | return rtas_error_rc(rc); |
447 | return rc; | 514 | return rc; |
448 | } | 515 | } |
516 | EXPORT_SYMBOL(rtas_get_power_level); | ||
449 | 517 | ||
450 | int rtas_set_power_level(int powerdomain, int level, int *setlevel) | 518 | int rtas_set_power_level(int powerdomain, int level, int *setlevel) |
451 | { | 519 | { |
@@ -463,6 +531,7 @@ int rtas_set_power_level(int powerdomain, int level, int *setlevel) | |||
463 | return rtas_error_rc(rc); | 531 | return rtas_error_rc(rc); |
464 | return rc; | 532 | return rc; |
465 | } | 533 | } |
534 | EXPORT_SYMBOL(rtas_set_power_level); | ||
466 | 535 | ||
467 | int rtas_get_sensor(int sensor, int index, int *state) | 536 | int rtas_get_sensor(int sensor, int index, int *state) |
468 | { | 537 | { |
@@ -480,6 +549,7 @@ int rtas_get_sensor(int sensor, int index, int *state) | |||
480 | return rtas_error_rc(rc); | 549 | return rtas_error_rc(rc); |
481 | return rc; | 550 | return rc; |
482 | } | 551 | } |
552 | EXPORT_SYMBOL(rtas_get_sensor); | ||
483 | 553 | ||
484 | int rtas_set_indicator(int indicator, int index, int new_value) | 554 | int rtas_set_indicator(int indicator, int index, int new_value) |
485 | { | 555 | { |
@@ -497,6 +567,7 @@ int rtas_set_indicator(int indicator, int index, int new_value) | |||
497 | return rtas_error_rc(rc); | 567 | return rtas_error_rc(rc); |
498 | return rc; | 568 | return rc; |
499 | } | 569 | } |
570 | EXPORT_SYMBOL(rtas_set_indicator); | ||
500 | 571 | ||
501 | void rtas_restart(char *cmd) | 572 | void rtas_restart(char *cmd) |
502 | { | 573 | { |
@@ -791,14 +862,34 @@ void __init rtas_initialize(void) | |||
791 | #endif | 862 | #endif |
792 | } | 863 | } |
793 | 864 | ||
865 | int __init early_init_dt_scan_rtas(unsigned long node, | ||
866 | const char *uname, int depth, void *data) | ||
867 | { | ||
868 | u32 *basep, *entryp, *sizep; | ||
794 | 869 | ||
795 | EXPORT_SYMBOL(rtas_token); | 870 | if (depth != 1 || strcmp(uname, "rtas") != 0) |
796 | EXPORT_SYMBOL(rtas_call); | 871 | return 0; |
797 | EXPORT_SYMBOL(rtas_data_buf); | 872 | |
798 | EXPORT_SYMBOL(rtas_data_buf_lock); | 873 | basep = of_get_flat_dt_prop(node, "linux,rtas-base", NULL); |
799 | EXPORT_SYMBOL(rtas_busy_delay_time); | 874 | entryp = of_get_flat_dt_prop(node, "linux,rtas-entry", NULL); |
800 | EXPORT_SYMBOL(rtas_busy_delay); | 875 | sizep = of_get_flat_dt_prop(node, "rtas-size", NULL); |
801 | EXPORT_SYMBOL(rtas_get_sensor); | 876 | |
802 | EXPORT_SYMBOL(rtas_get_power_level); | 877 | if (basep && entryp && sizep) { |
803 | EXPORT_SYMBOL(rtas_set_power_level); | 878 | rtas.base = *basep; |
804 | EXPORT_SYMBOL(rtas_set_indicator); | 879 | rtas.entry = *entryp; |
880 | rtas.size = *sizep; | ||
881 | } | ||
882 | |||
883 | #ifdef CONFIG_UDBG_RTAS_CONSOLE | ||
884 | basep = of_get_flat_dt_prop(node, "put-term-char", NULL); | ||
885 | if (basep) | ||
886 | rtas_putchar_token = *basep; | ||
887 | |||
888 | basep = of_get_flat_dt_prop(node, "get-term-char", NULL); | ||
889 | if (basep) | ||
890 | rtas_getchar_token = *basep; | ||
891 | #endif | ||
892 | |||
893 | /* break now */ | ||
894 | return 1; | ||
895 | } | ||
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 78f3a5fd43f6..175539c9afa0 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
@@ -149,6 +149,13 @@ early_param("smt-enabled", early_smt_enabled); | |||
149 | #define check_smt_enabled() | 149 | #define check_smt_enabled() |
150 | #endif /* CONFIG_SMP */ | 150 | #endif /* CONFIG_SMP */ |
151 | 151 | ||
152 | /* Put the paca pointer into r13 and SPRG3 */ | ||
153 | void __init setup_paca(int cpu) | ||
154 | { | ||
155 | local_paca = &paca[cpu]; | ||
156 | mtspr(SPRN_SPRG3, local_paca); | ||
157 | } | ||
158 | |||
152 | /* | 159 | /* |
153 | * Early initialization entry point. This is called by head.S | 160 | * Early initialization entry point. This is called by head.S |
154 | * with MMU translation disabled. We rely on the "feature" of | 161 | * with MMU translation disabled. We rely on the "feature" of |
@@ -170,6 +177,9 @@ early_param("smt-enabled", early_smt_enabled); | |||
170 | 177 | ||
171 | void __init early_setup(unsigned long dt_ptr) | 178 | void __init early_setup(unsigned long dt_ptr) |
172 | { | 179 | { |
180 | /* Assume we're on cpu 0 for now. Don't write to the paca yet! */ | ||
181 | setup_paca(0); | ||
182 | |||
173 | /* Enable early debugging if any specified (see udbg.h) */ | 183 | /* Enable early debugging if any specified (see udbg.h) */ |
174 | udbg_early_init(); | 184 | udbg_early_init(); |
175 | 185 | ||
@@ -183,7 +193,7 @@ void __init early_setup(unsigned long dt_ptr) | |||
183 | early_init_devtree(__va(dt_ptr)); | 193 | early_init_devtree(__va(dt_ptr)); |
184 | 194 | ||
185 | /* Now we know the logical id of our boot cpu, setup the paca. */ | 195 | /* Now we know the logical id of our boot cpu, setup the paca. */ |
186 | setup_boot_paca(); | 196 | setup_paca(boot_cpuid); |
187 | 197 | ||
188 | /* Fix up paca fields required for the boot cpu */ | 198 | /* Fix up paca fields required for the boot cpu */ |
189 | get_paca()->cpu_start = 1; | 199 | get_paca()->cpu_start = 1; |
@@ -350,19 +360,11 @@ void __init setup_system(void) | |||
350 | */ | 360 | */ |
351 | unflatten_device_tree(); | 361 | unflatten_device_tree(); |
352 | 362 | ||
353 | #ifdef CONFIG_KEXEC | ||
354 | kexec_setup(); /* requires unflattened device tree. */ | ||
355 | #endif | ||
356 | |||
357 | /* | 363 | /* |
358 | * Fill the ppc64_caches & systemcfg structures with informations | 364 | * Fill the ppc64_caches & systemcfg structures with informations |
359 | * retrieved from the device-tree. Need to be called before | 365 | * retrieved from the device-tree. Need to be called before |
360 | * finish_device_tree() since the later requires some of the | 366 | * finish_device_tree() since the later requires some of the |
361 | * informations filled up here to properly parse the interrupt | 367 | * informations filled up here to properly parse the interrupt tree. |
362 | * tree. | ||
363 | * It also sets up the cache line sizes which allows to call | ||
364 | * routines like flush_icache_range (used by the hash init | ||
365 | * later on). | ||
366 | */ | 368 | */ |
367 | initialize_cache_info(); | 369 | initialize_cache_info(); |
368 | 370 | ||
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 52f5659534f4..fa6bd97b6b9d 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
@@ -52,9 +52,13 @@ | |||
52 | #include <asm/firmware.h> | 52 | #include <asm/firmware.h> |
53 | #include <asm/processor.h> | 53 | #include <asm/processor.h> |
54 | #endif | 54 | #endif |
55 | #include <asm/kexec.h> | ||
55 | 56 | ||
56 | #ifdef CONFIG_PPC64 /* XXX */ | 57 | #ifdef CONFIG_PPC64 /* XXX */ |
57 | #define _IO_BASE pci_io_base | 58 | #define _IO_BASE pci_io_base |
59 | #ifdef CONFIG_KEXEC | ||
60 | cpumask_t cpus_in_sr = CPU_MASK_NONE; | ||
61 | #endif | ||
58 | #endif | 62 | #endif |
59 | 63 | ||
60 | #ifdef CONFIG_DEBUGGER | 64 | #ifdef CONFIG_DEBUGGER |
@@ -97,7 +101,7 @@ static DEFINE_SPINLOCK(die_lock); | |||
97 | 101 | ||
98 | int die(const char *str, struct pt_regs *regs, long err) | 102 | int die(const char *str, struct pt_regs *regs, long err) |
99 | { | 103 | { |
100 | static int die_counter, crash_dump_start = 0; | 104 | static int die_counter; |
101 | 105 | ||
102 | if (debugger(regs)) | 106 | if (debugger(regs)) |
103 | return 1; | 107 | return 1; |
@@ -137,21 +141,12 @@ int die(const char *str, struct pt_regs *regs, long err) | |||
137 | print_modules(); | 141 | print_modules(); |
138 | show_regs(regs); | 142 | show_regs(regs); |
139 | bust_spinlocks(0); | 143 | bust_spinlocks(0); |
144 | spin_unlock_irq(&die_lock); | ||
140 | 145 | ||
141 | if (!crash_dump_start && kexec_should_crash(current)) { | 146 | if (kexec_should_crash(current) || |
142 | crash_dump_start = 1; | 147 | kexec_sr_activated(smp_processor_id())) |
143 | spin_unlock_irq(&die_lock); | ||
144 | crash_kexec(regs); | 148 | crash_kexec(regs); |
145 | /* NOTREACHED */ | 149 | crash_kexec_secondary(regs); |
146 | } | ||
147 | spin_unlock_irq(&die_lock); | ||
148 | if (crash_dump_start) | ||
149 | /* | ||
150 | * Only for soft-reset: Other CPUs will be responded to an IPI | ||
151 | * sent by first kexec CPU. | ||
152 | */ | ||
153 | for(;;) | ||
154 | ; | ||
155 | 150 | ||
156 | if (in_interrupt()) | 151 | if (in_interrupt()) |
157 | panic("Fatal exception in interrupt"); | 152 | panic("Fatal exception in interrupt"); |
@@ -215,6 +210,10 @@ void system_reset_exception(struct pt_regs *regs) | |||
215 | return; | 210 | return; |
216 | } | 211 | } |
217 | 212 | ||
213 | #ifdef CONFIG_KEXEC | ||
214 | cpu_set(smp_processor_id(), cpus_in_sr); | ||
215 | #endif | ||
216 | |||
218 | die("System Reset", regs, SIGABRT); | 217 | die("System Reset", regs, SIGABRT); |
219 | 218 | ||
220 | /* Must die if the interrupt is not recoverable */ | 219 | /* Must die if the interrupt is not recoverable */ |
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c index 67d9fd9ae2b5..759afd5e0d8a 100644 --- a/arch/powerpc/kernel/udbg.c +++ b/arch/powerpc/kernel/udbg.c | |||
@@ -34,9 +34,12 @@ void __init udbg_early_init(void) | |||
34 | #elif defined(CONFIG_PPC_EARLY_DEBUG_G5) | 34 | #elif defined(CONFIG_PPC_EARLY_DEBUG_G5) |
35 | /* For use on Apple G5 machines */ | 35 | /* For use on Apple G5 machines */ |
36 | udbg_init_pmac_realmode(); | 36 | udbg_init_pmac_realmode(); |
37 | #elif defined(CONFIG_PPC_EARLY_DEBUG_RTAS) | 37 | #elif defined(CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL) |
38 | /* RTAS panel debug */ | 38 | /* RTAS panel debug */ |
39 | udbg_init_rtas(); | 39 | udbg_init_rtas_panel(); |
40 | #elif defined(CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE) | ||
41 | /* RTAS console debug */ | ||
42 | udbg_init_rtas_console(); | ||
40 | #elif defined(CONFIG_PPC_EARLY_DEBUG_MAPLE) | 43 | #elif defined(CONFIG_PPC_EARLY_DEBUG_MAPLE) |
41 | /* Maple real mode debug */ | 44 | /* Maple real mode debug */ |
42 | udbg_init_maple_realmode(); | 45 | udbg_init_maple_realmode(); |
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c index a0f3cbd00d39..c90f124f3c71 100644 --- a/arch/powerpc/mm/hash_native_64.c +++ b/arch/powerpc/mm/hash_native_64.c | |||
@@ -520,7 +520,7 @@ static inline int tlb_batching_enabled(void) | |||
520 | } | 520 | } |
521 | #endif | 521 | #endif |
522 | 522 | ||
523 | void hpte_init_native(void) | 523 | void __init hpte_init_native(void) |
524 | { | 524 | { |
525 | ppc_md.hpte_invalidate = native_hpte_invalidate; | 525 | ppc_md.hpte_invalidate = native_hpte_invalidate; |
526 | ppc_md.hpte_updatepp = native_hpte_updatepp; | 526 | ppc_md.hpte_updatepp = native_hpte_updatepp; |
@@ -530,5 +530,4 @@ void hpte_init_native(void) | |||
530 | ppc_md.hpte_clear_all = native_hpte_clear; | 530 | ppc_md.hpte_clear_all = native_hpte_clear; |
531 | if (tlb_batching_enabled()) | 531 | if (tlb_batching_enabled()) |
532 | ppc_md.flush_hash_range = native_flush_hash_range; | 532 | ppc_md.flush_hash_range = native_flush_hash_range; |
533 | htab_finish_init(); | ||
534 | } | 533 | } |
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index d03fd2b4445e..3cc6d68f7117 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c | |||
@@ -167,34 +167,12 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend, | |||
167 | hash = hpt_hash(va, shift); | 167 | hash = hpt_hash(va, shift); |
168 | hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); | 168 | hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); |
169 | 169 | ||
170 | /* The crap below can be cleaned once ppd_md.probe() can | 170 | DBG("htab_bolt_mapping: calling %p\n", ppc_md.hpte_insert); |
171 | * set up the hash callbacks, thus we can just used the | 171 | |
172 | * normal insert callback here. | 172 | BUG_ON(!ppc_md.hpte_insert); |
173 | */ | 173 | ret = ppc_md.hpte_insert(hpteg, va, paddr, |
174 | #ifdef CONFIG_PPC_ISERIES | 174 | tmp_mode, HPTE_V_BOLTED, psize); |
175 | if (machine_is(iseries)) | 175 | |
176 | ret = iSeries_hpte_insert(hpteg, va, | ||
177 | paddr, | ||
178 | tmp_mode, | ||
179 | HPTE_V_BOLTED, | ||
180 | psize); | ||
181 | else | ||
182 | #endif | ||
183 | #ifdef CONFIG_PPC_PSERIES | ||
184 | if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR)) | ||
185 | ret = pSeries_lpar_hpte_insert(hpteg, va, | ||
186 | paddr, | ||
187 | tmp_mode, | ||
188 | HPTE_V_BOLTED, | ||
189 | psize); | ||
190 | else | ||
191 | #endif | ||
192 | #ifdef CONFIG_PPC_MULTIPLATFORM | ||
193 | ret = native_hpte_insert(hpteg, va, | ||
194 | paddr, | ||
195 | tmp_mode, HPTE_V_BOLTED, | ||
196 | psize); | ||
197 | #endif | ||
198 | if (ret < 0) | 176 | if (ret < 0) |
199 | break; | 177 | break; |
200 | } | 178 | } |
@@ -413,6 +391,41 @@ void create_section_mapping(unsigned long start, unsigned long end) | |||
413 | } | 391 | } |
414 | #endif /* CONFIG_MEMORY_HOTPLUG */ | 392 | #endif /* CONFIG_MEMORY_HOTPLUG */ |
415 | 393 | ||
394 | static inline void make_bl(unsigned int *insn_addr, void *func) | ||
395 | { | ||
396 | unsigned long funcp = *((unsigned long *)func); | ||
397 | int offset = funcp - (unsigned long)insn_addr; | ||
398 | |||
399 | *insn_addr = (unsigned int)(0x48000001 | (offset & 0x03fffffc)); | ||
400 | flush_icache_range((unsigned long)insn_addr, 4+ | ||
401 | (unsigned long)insn_addr); | ||
402 | } | ||
403 | |||
404 | static void __init htab_finish_init(void) | ||
405 | { | ||
406 | extern unsigned int *htab_call_hpte_insert1; | ||
407 | extern unsigned int *htab_call_hpte_insert2; | ||
408 | extern unsigned int *htab_call_hpte_remove; | ||
409 | extern unsigned int *htab_call_hpte_updatepp; | ||
410 | |||
411 | #ifdef CONFIG_PPC_64K_PAGES | ||
412 | extern unsigned int *ht64_call_hpte_insert1; | ||
413 | extern unsigned int *ht64_call_hpte_insert2; | ||
414 | extern unsigned int *ht64_call_hpte_remove; | ||
415 | extern unsigned int *ht64_call_hpte_updatepp; | ||
416 | |||
417 | make_bl(ht64_call_hpte_insert1, ppc_md.hpte_insert); | ||
418 | make_bl(ht64_call_hpte_insert2, ppc_md.hpte_insert); | ||
419 | make_bl(ht64_call_hpte_remove, ppc_md.hpte_remove); | ||
420 | make_bl(ht64_call_hpte_updatepp, ppc_md.hpte_updatepp); | ||
421 | #endif /* CONFIG_PPC_64K_PAGES */ | ||
422 | |||
423 | make_bl(htab_call_hpte_insert1, ppc_md.hpte_insert); | ||
424 | make_bl(htab_call_hpte_insert2, ppc_md.hpte_insert); | ||
425 | make_bl(htab_call_hpte_remove, ppc_md.hpte_remove); | ||
426 | make_bl(htab_call_hpte_updatepp, ppc_md.hpte_updatepp); | ||
427 | } | ||
428 | |||
416 | void __init htab_initialize(void) | 429 | void __init htab_initialize(void) |
417 | { | 430 | { |
418 | unsigned long table; | 431 | unsigned long table; |
@@ -525,6 +538,8 @@ void __init htab_initialize(void) | |||
525 | mmu_linear_psize)); | 538 | mmu_linear_psize)); |
526 | } | 539 | } |
527 | 540 | ||
541 | htab_finish_init(); | ||
542 | |||
528 | DBG(" <- htab_initialize()\n"); | 543 | DBG(" <- htab_initialize()\n"); |
529 | } | 544 | } |
530 | #undef KB | 545 | #undef KB |
@@ -787,16 +802,6 @@ void flush_hash_range(unsigned long number, int local) | |||
787 | } | 802 | } |
788 | } | 803 | } |
789 | 804 | ||
790 | static inline void make_bl(unsigned int *insn_addr, void *func) | ||
791 | { | ||
792 | unsigned long funcp = *((unsigned long *)func); | ||
793 | int offset = funcp - (unsigned long)insn_addr; | ||
794 | |||
795 | *insn_addr = (unsigned int)(0x48000001 | (offset & 0x03fffffc)); | ||
796 | flush_icache_range((unsigned long)insn_addr, 4+ | ||
797 | (unsigned long)insn_addr); | ||
798 | } | ||
799 | |||
800 | /* | 805 | /* |
801 | * low_hash_fault is called when we the low level hash code failed | 806 | * low_hash_fault is called when we the low level hash code failed |
802 | * to instert a PTE due to an hypervisor error | 807 | * to instert a PTE due to an hypervisor error |
@@ -815,28 +820,3 @@ void low_hash_fault(struct pt_regs *regs, unsigned long address) | |||
815 | } | 820 | } |
816 | bad_page_fault(regs, address, SIGBUS); | 821 | bad_page_fault(regs, address, SIGBUS); |
817 | } | 822 | } |
818 | |||
819 | void __init htab_finish_init(void) | ||
820 | { | ||
821 | extern unsigned int *htab_call_hpte_insert1; | ||
822 | extern unsigned int *htab_call_hpte_insert2; | ||
823 | extern unsigned int *htab_call_hpte_remove; | ||
824 | extern unsigned int *htab_call_hpte_updatepp; | ||
825 | |||
826 | #ifdef CONFIG_PPC_64K_PAGES | ||
827 | extern unsigned int *ht64_call_hpte_insert1; | ||
828 | extern unsigned int *ht64_call_hpte_insert2; | ||
829 | extern unsigned int *ht64_call_hpte_remove; | ||
830 | extern unsigned int *ht64_call_hpte_updatepp; | ||
831 | |||
832 | make_bl(ht64_call_hpte_insert1, ppc_md.hpte_insert); | ||
833 | make_bl(ht64_call_hpte_insert2, ppc_md.hpte_insert); | ||
834 | make_bl(ht64_call_hpte_remove, ppc_md.hpte_remove); | ||
835 | make_bl(ht64_call_hpte_updatepp, ppc_md.hpte_updatepp); | ||
836 | #endif /* CONFIG_PPC_64K_PAGES */ | ||
837 | |||
838 | make_bl(htab_call_hpte_insert1, ppc_md.hpte_insert); | ||
839 | make_bl(htab_call_hpte_insert2, ppc_md.hpte_insert); | ||
840 | make_bl(htab_call_hpte_remove, ppc_md.hpte_remove); | ||
841 | make_bl(htab_call_hpte_updatepp, ppc_md.hpte_updatepp); | ||
842 | } | ||
diff --git a/arch/powerpc/mm/mmu_context_64.c b/arch/powerpc/mm/mmu_context_64.c index 65d18dca266f..e2051efa09c5 100644 --- a/arch/powerpc/mm/mmu_context_64.c +++ b/arch/powerpc/mm/mmu_context_64.c | |||
@@ -44,7 +44,9 @@ again: | |||
44 | return err; | 44 | return err; |
45 | 45 | ||
46 | if (index > MAX_CONTEXT) { | 46 | if (index > MAX_CONTEXT) { |
47 | spin_lock(&mmu_context_lock); | ||
47 | idr_remove(&mmu_context_idr, index); | 48 | idr_remove(&mmu_context_idr, index); |
49 | spin_unlock(&mmu_context_lock); | ||
48 | return -ENOMEM; | 50 | return -ENOMEM; |
49 | } | 51 | } |
50 | 52 | ||
diff --git a/arch/powerpc/platforms/83xx/pci.c b/arch/powerpc/platforms/83xx/pci.c index 16f7d3b30e1d..3baceb00fefa 100644 --- a/arch/powerpc/platforms/83xx/pci.c +++ b/arch/powerpc/platforms/83xx/pci.c | |||
@@ -91,9 +91,10 @@ int __init add_bridge(struct device_node *dev) | |||
91 | mpc83xx_pci2_busno = hose->first_busno; | 91 | mpc83xx_pci2_busno = hose->first_busno; |
92 | } | 92 | } |
93 | 93 | ||
94 | printk(KERN_INFO "Found MPC83xx PCI host bridge at 0x%08lx. " | 94 | printk(KERN_INFO "Found MPC83xx PCI host bridge at 0x%016llx. " |
95 | "Firmware bus number: %d->%d\n", | 95 | "Firmware bus number: %d->%d\n", |
96 | rsrc.start, hose->first_busno, hose->last_busno); | 96 | (unsigned long long)rsrc.start, hose->first_busno, |
97 | hose->last_busno); | ||
97 | 98 | ||
98 | DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", | 99 | DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", |
99 | hose, hose->cfg_addr, hose->cfg_data); | 100 | hose, hose->cfg_addr, hose->cfg_data); |
diff --git a/arch/powerpc/platforms/85xx/pci.c b/arch/powerpc/platforms/85xx/pci.c index bad290110ed1..48c8849c07ca 100644 --- a/arch/powerpc/platforms/85xx/pci.c +++ b/arch/powerpc/platforms/85xx/pci.c | |||
@@ -79,9 +79,10 @@ int __init add_bridge(struct device_node *dev) | |||
79 | mpc85xx_pci2_busno = hose->first_busno; | 79 | mpc85xx_pci2_busno = hose->first_busno; |
80 | } | 80 | } |
81 | 81 | ||
82 | printk(KERN_INFO "Found MPC85xx PCI host bridge at 0x%08lx. " | 82 | printk(KERN_INFO "Found MPC85xx PCI host bridge at 0x%016llx. " |
83 | "Firmware bus number: %d->%d\n", | 83 | "Firmware bus number: %d->%d\n", |
84 | rsrc.start, hose->first_busno, hose->last_busno); | 84 | (unsigned long long)rsrc.start, hose->first_busno, |
85 | hose->last_busno); | ||
85 | 86 | ||
86 | DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", | 87 | DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", |
87 | hose, hose->cfg_addr, hose->cfg_data); | 88 | hose, hose->cfg_addr, hose->cfg_data); |
diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig index 3a87863d2876..d1ecc0f9ab58 100644 --- a/arch/powerpc/platforms/86xx/Kconfig +++ b/arch/powerpc/platforms/86xx/Kconfig | |||
@@ -7,6 +7,7 @@ choice | |||
7 | 7 | ||
8 | config MPC8641_HPCN | 8 | config MPC8641_HPCN |
9 | bool "Freescale MPC8641 HPCN" | 9 | bool "Freescale MPC8641 HPCN" |
10 | select PPC_I8259 | ||
10 | help | 11 | help |
11 | This option enables support for the MPC8641 HPCN board. | 12 | This option enables support for the MPC8641 HPCN board. |
12 | 13 | ||
@@ -28,9 +29,4 @@ config PPC_INDIRECT_PCI_BE | |||
28 | depends on PPC_86xx | 29 | depends on PPC_86xx |
29 | default y | 30 | default y |
30 | 31 | ||
31 | config PPC_STD_MMU | ||
32 | bool | ||
33 | depends on PPC_86xx | ||
34 | default y | ||
35 | |||
36 | endmenu | 32 | endmenu |
diff --git a/arch/powerpc/platforms/86xx/Makefile b/arch/powerpc/platforms/86xx/Makefile index 7be796c5d5c9..476a6eeee710 100644 --- a/arch/powerpc/platforms/86xx/Makefile +++ b/arch/powerpc/platforms/86xx/Makefile | |||
@@ -2,9 +2,6 @@ | |||
2 | # Makefile for the PowerPC 86xx linux kernel. | 2 | # Makefile for the PowerPC 86xx linux kernel. |
3 | # | 3 | # |
4 | 4 | ||
5 | |||
6 | ifeq ($(CONFIG_PPC_86xx),y) | ||
7 | obj-$(CONFIG_SMP) += mpc86xx_smp.o | 5 | obj-$(CONFIG_SMP) += mpc86xx_smp.o |
8 | endif | ||
9 | obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o | 6 | obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o |
10 | obj-$(CONFIG_PCI) += pci.o mpc86xx_pcie.o | 7 | obj-$(CONFIG_PCI) += pci.o mpc86xx_pcie.o |
diff --git a/arch/powerpc/platforms/86xx/mpc8641_hpcn.h b/arch/powerpc/platforms/86xx/mpc8641_hpcn.h index 5042253758b7..5d2bcf78cef7 100644 --- a/arch/powerpc/platforms/86xx/mpc8641_hpcn.h +++ b/arch/powerpc/platforms/86xx/mpc8641_hpcn.h | |||
@@ -14,7 +14,6 @@ | |||
14 | #ifndef __MPC8641_HPCN_H__ | 14 | #ifndef __MPC8641_HPCN_H__ |
15 | #define __MPC8641_HPCN_H__ | 15 | #define __MPC8641_HPCN_H__ |
16 | 16 | ||
17 | #include <linux/config.h> | ||
18 | #include <linux/init.h> | 17 | #include <linux/init.h> |
19 | 18 | ||
20 | /* PCI interrupt controller */ | 19 | /* PCI interrupt controller */ |
diff --git a/arch/powerpc/platforms/86xx/mpc86xx.h b/arch/powerpc/platforms/86xx/mpc86xx.h index e3c9e4f417d3..2834462590b8 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx.h +++ b/arch/powerpc/platforms/86xx/mpc86xx.h | |||
@@ -15,11 +15,13 @@ | |||
15 | * mpc86xx_* files. Mostly for use by mpc86xx_setup(). | 15 | * mpc86xx_* files. Mostly for use by mpc86xx_setup(). |
16 | */ | 16 | */ |
17 | 17 | ||
18 | extern int __init add_bridge(struct device_node *dev); | 18 | extern int add_bridge(struct device_node *dev); |
19 | 19 | ||
20 | extern void __init setup_indirect_pcie(struct pci_controller *hose, | 20 | extern int mpc86xx_exclude_device(u_char bus, u_char devfn); |
21 | |||
22 | extern void setup_indirect_pcie(struct pci_controller *hose, | ||
21 | u32 cfg_addr, u32 cfg_data); | 23 | u32 cfg_addr, u32 cfg_data); |
22 | extern void __init setup_indirect_pcie_nomap(struct pci_controller *hose, | 24 | extern void setup_indirect_pcie_nomap(struct pci_controller *hose, |
23 | void __iomem *cfg_addr, | 25 | void __iomem *cfg_addr, |
24 | void __iomem *cfg_data); | 26 | void __iomem *cfg_data); |
25 | 27 | ||
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c index 483c21df181e..ebae73eb0063 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c +++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c | |||
@@ -12,7 +12,6 @@ | |||
12 | * option) any later version. | 12 | * option) any later version. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/config.h> | ||
16 | #include <linux/stddef.h> | 15 | #include <linux/stddef.h> |
17 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
18 | #include <linux/pci.h> | 17 | #include <linux/pci.h> |
@@ -36,6 +35,7 @@ | |||
36 | #include <sysdev/fsl_soc.h> | 35 | #include <sysdev/fsl_soc.h> |
37 | 36 | ||
38 | #include "mpc86xx.h" | 37 | #include "mpc86xx.h" |
38 | #include "mpc8641_hpcn.h" | ||
39 | 39 | ||
40 | #ifndef CONFIG_PCI | 40 | #ifndef CONFIG_PCI |
41 | unsigned long isa_io_base = 0; | 41 | unsigned long isa_io_base = 0; |
@@ -186,17 +186,130 @@ mpc86xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) | |||
186 | return PCI_IRQ_TABLE_LOOKUP + I8259_OFFSET; | 186 | return PCI_IRQ_TABLE_LOOKUP + I8259_OFFSET; |
187 | } | 187 | } |
188 | 188 | ||
189 | static void __devinit quirk_ali1575(struct pci_dev *dev) | ||
190 | { | ||
191 | unsigned short temp; | ||
192 | |||
193 | /* | ||
194 | * ALI1575 interrupts route table setup: | ||
195 | * | ||
196 | * IRQ pin IRQ# | ||
197 | * PIRQA ---- 3 | ||
198 | * PIRQB ---- 4 | ||
199 | * PIRQC ---- 5 | ||
200 | * PIRQD ---- 6 | ||
201 | * PIRQE ---- 9 | ||
202 | * PIRQF ---- 10 | ||
203 | * PIRQG ---- 11 | ||
204 | * PIRQH ---- 12 | ||
205 | * | ||
206 | * interrupts for PCI slot0 -- PIRQA / PIRQB / PIRQC / PIRQD | ||
207 | * PCI slot1 -- PIRQB / PIRQC / PIRQD / PIRQA | ||
208 | */ | ||
209 | pci_write_config_dword(dev, 0x48, 0xb9317542); | ||
210 | |||
211 | /* USB 1.1 OHCI controller 1, interrupt: PIRQE */ | ||
212 | pci_write_config_byte(dev, 0x86, 0x0c); | ||
213 | |||
214 | /* USB 1.1 OHCI controller 2, interrupt: PIRQF */ | ||
215 | pci_write_config_byte(dev, 0x87, 0x0d); | ||
216 | |||
217 | /* USB 1.1 OHCI controller 3, interrupt: PIRQH */ | ||
218 | pci_write_config_byte(dev, 0x88, 0x0f); | ||
219 | |||
220 | /* USB 2.0 controller, interrupt: PIRQ7 */ | ||
221 | pci_write_config_byte(dev, 0x74, 0x06); | ||
222 | |||
223 | /* Audio controller, interrupt: PIRQE */ | ||
224 | pci_write_config_byte(dev, 0x8a, 0x0c); | ||
225 | |||
226 | /* Modem controller, interrupt: PIRQF */ | ||
227 | pci_write_config_byte(dev, 0x8b, 0x0d); | ||
228 | |||
229 | /* HD audio controller, interrupt: PIRQG */ | ||
230 | pci_write_config_byte(dev, 0x8c, 0x0e); | ||
231 | |||
232 | /* Serial ATA interrupt: PIRQD */ | ||
233 | pci_write_config_byte(dev, 0x8d, 0x0b); | ||
234 | |||
235 | /* SMB interrupt: PIRQH */ | ||
236 | pci_write_config_byte(dev, 0x8e, 0x0f); | ||
237 | |||
238 | /* PMU ACPI SCI interrupt: PIRQH */ | ||
239 | pci_write_config_byte(dev, 0x8f, 0x0f); | ||
240 | |||
241 | /* Primary PATA IDE IRQ: 14 | ||
242 | * Secondary PATA IDE IRQ: 15 | ||
243 | */ | ||
244 | pci_write_config_byte(dev, 0x44, 0x3d); | ||
245 | pci_write_config_byte(dev, 0x75, 0x0f); | ||
246 | |||
247 | /* Set IRQ14 and IRQ15 to legacy IRQs */ | ||
248 | pci_read_config_word(dev, 0x46, &temp); | ||
249 | temp |= 0xc000; | ||
250 | pci_write_config_word(dev, 0x46, temp); | ||
251 | |||
252 | /* Set i8259 interrupt trigger | ||
253 | * IRQ 3: Level | ||
254 | * IRQ 4: Level | ||
255 | * IRQ 5: Level | ||
256 | * IRQ 6: Level | ||
257 | * IRQ 7: Level | ||
258 | * IRQ 9: Level | ||
259 | * IRQ 10: Level | ||
260 | * IRQ 11: Level | ||
261 | * IRQ 12: Level | ||
262 | * IRQ 14: Edge | ||
263 | * IRQ 15: Edge | ||
264 | */ | ||
265 | outb(0xfa, 0x4d0); | ||
266 | outb(0x1e, 0x4d1); | ||
267 | } | ||
189 | 268 | ||
190 | int | 269 | static void __devinit quirk_uli5288(struct pci_dev *dev) |
191 | mpc86xx_exclude_device(u_char bus, u_char devfn) | ||
192 | { | 270 | { |
193 | #if !defined(CONFIG_PCI) | 271 | unsigned char c; |
194 | if (bus == 0 && PCI_SLOT(devfn) == 0) | 272 | |
195 | return PCIBIOS_DEVICE_NOT_FOUND; | 273 | pci_read_config_byte(dev,0x83,&c); |
196 | #endif | 274 | c |= 0x80; |
275 | pci_write_config_byte(dev, 0x83, c); | ||
276 | |||
277 | pci_write_config_byte(dev, 0x09, 0x01); | ||
278 | pci_write_config_byte(dev, 0x0a, 0x06); | ||
279 | |||
280 | pci_read_config_byte(dev,0x83,&c); | ||
281 | c &= 0x7f; | ||
282 | pci_write_config_byte(dev, 0x83, c); | ||
197 | 283 | ||
198 | return PCIBIOS_SUCCESSFUL; | 284 | pci_read_config_byte(dev,0x84,&c); |
285 | c |= 0x01; | ||
286 | pci_write_config_byte(dev, 0x84, c); | ||
199 | } | 287 | } |
288 | |||
289 | static void __devinit quirk_uli5229(struct pci_dev *dev) | ||
290 | { | ||
291 | unsigned short temp; | ||
292 | pci_write_config_word(dev, 0x04, 0x0405); | ||
293 | pci_read_config_word(dev, 0x4a, &temp); | ||
294 | temp |= 0x1000; | ||
295 | pci_write_config_word(dev, 0x4a, temp); | ||
296 | } | ||
297 | |||
298 | static void __devinit early_uli5249(struct pci_dev *dev) | ||
299 | { | ||
300 | unsigned char temp; | ||
301 | pci_write_config_word(dev, 0x04, 0x0007); | ||
302 | pci_read_config_byte(dev, 0x7c, &temp); | ||
303 | pci_write_config_byte(dev, 0x7c, 0x80); | ||
304 | pci_write_config_byte(dev, 0x09, 0x01); | ||
305 | pci_write_config_byte(dev, 0x7c, temp); | ||
306 | dev->class |= 0x1; | ||
307 | } | ||
308 | |||
309 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_ali1575); | ||
310 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288); | ||
311 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229); | ||
312 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, 0x5249, early_uli5249); | ||
200 | #endif /* CONFIG_PCI */ | 313 | #endif /* CONFIG_PCI */ |
201 | 314 | ||
202 | 315 | ||
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_smp.c b/arch/powerpc/platforms/86xx/mpc86xx_smp.c index 944ec4b71416..bb7fb41933ad 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx_smp.c +++ b/arch/powerpc/platforms/86xx/mpc86xx_smp.c | |||
@@ -10,7 +10,6 @@ | |||
10 | * option) any later version. | 10 | * option) any later version. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/config.h> | ||
14 | #include <linux/stddef.h> | 13 | #include <linux/stddef.h> |
15 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
16 | #include <linux/init.h> | 15 | #include <linux/init.h> |
@@ -34,8 +33,8 @@ extern unsigned long __secondary_hold_acknowledge; | |||
34 | static void __init | 33 | static void __init |
35 | smp_86xx_release_core(int nr) | 34 | smp_86xx_release_core(int nr) |
36 | { | 35 | { |
37 | void *mcm_vaddr; | 36 | __be32 __iomem *mcm_vaddr; |
38 | unsigned long vaddr, pcr; | 37 | unsigned long pcr; |
39 | 38 | ||
40 | if (nr < 0 || nr >= NR_CPUS) | 39 | if (nr < 0 || nr >= NR_CPUS) |
41 | return; | 40 | return; |
@@ -45,10 +44,9 @@ smp_86xx_release_core(int nr) | |||
45 | */ | 44 | */ |
46 | mcm_vaddr = ioremap(get_immrbase() + MPC86xx_MCM_OFFSET, | 45 | mcm_vaddr = ioremap(get_immrbase() + MPC86xx_MCM_OFFSET, |
47 | MPC86xx_MCM_SIZE); | 46 | MPC86xx_MCM_SIZE); |
48 | vaddr = (unsigned long)mcm_vaddr + MCM_PORT_CONFIG_OFFSET; | 47 | pcr = in_be32(mcm_vaddr + (MCM_PORT_CONFIG_OFFSET >> 2)); |
49 | pcr = in_be32((volatile unsigned *)vaddr); | ||
50 | pcr |= 1 << (nr + 24); | 48 | pcr |= 1 << (nr + 24); |
51 | out_be32((volatile unsigned *)vaddr, pcr); | 49 | out_be32(mcm_vaddr + (MCM_PORT_CONFIG_OFFSET >> 2), pcr); |
52 | } | 50 | } |
53 | 51 | ||
54 | 52 | ||
diff --git a/arch/powerpc/platforms/86xx/pci.c b/arch/powerpc/platforms/86xx/pci.c index 5180df7c75bc..bc5139043112 100644 --- a/arch/powerpc/platforms/86xx/pci.c +++ b/arch/powerpc/platforms/86xx/pci.c | |||
@@ -12,7 +12,6 @@ | |||
12 | * option) any later version. | 12 | * option) any later version. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/config.h> | ||
16 | #include <linux/types.h> | 15 | #include <linux/types.h> |
17 | #include <linux/module.h> | 16 | #include <linux/module.h> |
18 | #include <linux/init.h> | 17 | #include <linux/init.h> |
@@ -122,15 +121,12 @@ static void __init setup_pcie_atmu(struct pci_controller *hose, struct resource | |||
122 | static void __init | 121 | static void __init |
123 | mpc86xx_setup_pcie(struct pci_controller *hose, u32 pcie_offset, u32 pcie_size) | 122 | mpc86xx_setup_pcie(struct pci_controller *hose, u32 pcie_offset, u32 pcie_size) |
124 | { | 123 | { |
125 | volatile struct ccsr_pex *pcie; | ||
126 | u16 cmd; | 124 | u16 cmd; |
127 | unsigned int temps; | 125 | unsigned int temps; |
128 | 126 | ||
129 | DBG("PCIE host controller register offset 0x%08x, size 0x%08x.\n", | 127 | DBG("PCIE host controller register offset 0x%08x, size 0x%08x.\n", |
130 | pcie_offset, pcie_size); | 128 | pcie_offset, pcie_size); |
131 | 129 | ||
132 | pcie = ioremap(pcie_offset, pcie_size); | ||
133 | |||
134 | early_read_config_word(hose, 0, 0, PCI_COMMAND, &cmd); | 130 | early_read_config_word(hose, 0, 0, PCI_COMMAND, &cmd); |
135 | cmd |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | 131 | cmd |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY |
136 | | PCI_COMMAND_IO; | 132 | | PCI_COMMAND_IO; |
@@ -144,6 +140,14 @@ mpc86xx_setup_pcie(struct pci_controller *hose, u32 pcie_offset, u32 pcie_size) | |||
144 | early_write_config_dword(hose, 0, 0, PCI_PRIMARY_BUS, temps); | 140 | early_write_config_dword(hose, 0, 0, PCI_PRIMARY_BUS, temps); |
145 | } | 141 | } |
146 | 142 | ||
143 | int mpc86xx_exclude_device(u_char bus, u_char devfn) | ||
144 | { | ||
145 | if (bus == 0 && PCI_SLOT(devfn) == 0) | ||
146 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
147 | |||
148 | return PCIBIOS_SUCCESSFUL; | ||
149 | } | ||
150 | |||
147 | int __init add_bridge(struct device_node *dev) | 151 | int __init add_bridge(struct device_node *dev) |
148 | { | 152 | { |
149 | int len; | 153 | int len; |
@@ -198,128 +202,3 @@ int __init add_bridge(struct device_node *dev) | |||
198 | 202 | ||
199 | return 0; | 203 | return 0; |
200 | } | 204 | } |
201 | |||
202 | static void __devinit quirk_ali1575(struct pci_dev *dev) | ||
203 | { | ||
204 | unsigned short temp; | ||
205 | |||
206 | /* | ||
207 | * ALI1575 interrupts route table setup: | ||
208 | * | ||
209 | * IRQ pin IRQ# | ||
210 | * PIRQA ---- 3 | ||
211 | * PIRQB ---- 4 | ||
212 | * PIRQC ---- 5 | ||
213 | * PIRQD ---- 6 | ||
214 | * PIRQE ---- 9 | ||
215 | * PIRQF ---- 10 | ||
216 | * PIRQG ---- 11 | ||
217 | * PIRQH ---- 12 | ||
218 | * | ||
219 | * interrupts for PCI slot0 -- PIRQA / PIRQB / PIRQC / PIRQD | ||
220 | * PCI slot1 -- PIRQB / PIRQC / PIRQD / PIRQA | ||
221 | */ | ||
222 | pci_write_config_dword(dev, 0x48, 0xb9317542); | ||
223 | |||
224 | /* USB 1.1 OHCI controller 1, interrupt: PIRQE */ | ||
225 | pci_write_config_byte(dev, 0x86, 0x0c); | ||
226 | |||
227 | /* USB 1.1 OHCI controller 2, interrupt: PIRQF */ | ||
228 | pci_write_config_byte(dev, 0x87, 0x0d); | ||
229 | |||
230 | /* USB 1.1 OHCI controller 3, interrupt: PIRQH */ | ||
231 | pci_write_config_byte(dev, 0x88, 0x0f); | ||
232 | |||
233 | /* USB 2.0 controller, interrupt: PIRQ7 */ | ||
234 | pci_write_config_byte(dev, 0x74, 0x06); | ||
235 | |||
236 | /* Audio controller, interrupt: PIRQE */ | ||
237 | pci_write_config_byte(dev, 0x8a, 0x0c); | ||
238 | |||
239 | /* Modem controller, interrupt: PIRQF */ | ||
240 | pci_write_config_byte(dev, 0x8b, 0x0d); | ||
241 | |||
242 | /* HD audio controller, interrupt: PIRQG */ | ||
243 | pci_write_config_byte(dev, 0x8c, 0x0e); | ||
244 | |||
245 | /* Serial ATA interrupt: PIRQD */ | ||
246 | pci_write_config_byte(dev, 0x8d, 0x0b); | ||
247 | |||
248 | /* SMB interrupt: PIRQH */ | ||
249 | pci_write_config_byte(dev, 0x8e, 0x0f); | ||
250 | |||
251 | /* PMU ACPI SCI interrupt: PIRQH */ | ||
252 | pci_write_config_byte(dev, 0x8f, 0x0f); | ||
253 | |||
254 | /* Primary PATA IDE IRQ: 14 | ||
255 | * Secondary PATA IDE IRQ: 15 | ||
256 | */ | ||
257 | pci_write_config_byte(dev, 0x44, 0x3d); | ||
258 | pci_write_config_byte(dev, 0x75, 0x0f); | ||
259 | |||
260 | /* Set IRQ14 and IRQ15 to legacy IRQs */ | ||
261 | pci_read_config_word(dev, 0x46, &temp); | ||
262 | temp |= 0xc000; | ||
263 | pci_write_config_word(dev, 0x46, temp); | ||
264 | |||
265 | /* Set i8259 interrupt trigger | ||
266 | * IRQ 3: Level | ||
267 | * IRQ 4: Level | ||
268 | * IRQ 5: Level | ||
269 | * IRQ 6: Level | ||
270 | * IRQ 7: Level | ||
271 | * IRQ 9: Level | ||
272 | * IRQ 10: Level | ||
273 | * IRQ 11: Level | ||
274 | * IRQ 12: Level | ||
275 | * IRQ 14: Edge | ||
276 | * IRQ 15: Edge | ||
277 | */ | ||
278 | outb(0xfa, 0x4d0); | ||
279 | outb(0x1e, 0x4d1); | ||
280 | } | ||
281 | |||
282 | static void __devinit quirk_uli5288(struct pci_dev *dev) | ||
283 | { | ||
284 | unsigned char c; | ||
285 | |||
286 | pci_read_config_byte(dev,0x83,&c); | ||
287 | c |= 0x80; | ||
288 | pci_write_config_byte(dev, 0x83, c); | ||
289 | |||
290 | pci_write_config_byte(dev, 0x09, 0x01); | ||
291 | pci_write_config_byte(dev, 0x0a, 0x06); | ||
292 | |||
293 | pci_read_config_byte(dev,0x83,&c); | ||
294 | c &= 0x7f; | ||
295 | pci_write_config_byte(dev, 0x83, c); | ||
296 | |||
297 | pci_read_config_byte(dev,0x84,&c); | ||
298 | c |= 0x01; | ||
299 | pci_write_config_byte(dev, 0x84, c); | ||
300 | } | ||
301 | |||
302 | static void __devinit quirk_uli5229(struct pci_dev *dev) | ||
303 | { | ||
304 | unsigned short temp; | ||
305 | pci_write_config_word(dev, 0x04, 0x0405); | ||
306 | pci_read_config_word(dev, 0x4a, &temp); | ||
307 | temp |= 0x1000; | ||
308 | pci_write_config_word(dev, 0x4a, temp); | ||
309 | } | ||
310 | |||
311 | static void __devinit early_uli5249(struct pci_dev *dev) | ||
312 | { | ||
313 | unsigned char temp; | ||
314 | pci_write_config_word(dev, 0x04, 0x0007); | ||
315 | pci_read_config_byte(dev, 0x7c, &temp); | ||
316 | pci_write_config_byte(dev, 0x7c, 0x80); | ||
317 | pci_write_config_byte(dev, 0x09, 0x01); | ||
318 | pci_write_config_byte(dev, 0x7c, temp); | ||
319 | dev->class |= 0x1; | ||
320 | } | ||
321 | |||
322 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_ali1575); | ||
323 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288); | ||
324 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229); | ||
325 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, 0x5249, early_uli5249); | ||
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile index 292863694562..5cf46dc57895 100644 --- a/arch/powerpc/platforms/Makefile +++ b/arch/powerpc/platforms/Makefile | |||
@@ -14,3 +14,4 @@ obj-$(CONFIG_PPC_PSERIES) += pseries/ | |||
14 | obj-$(CONFIG_PPC_ISERIES) += iseries/ | 14 | obj-$(CONFIG_PPC_ISERIES) += iseries/ |
15 | obj-$(CONFIG_PPC_MAPLE) += maple/ | 15 | obj-$(CONFIG_PPC_MAPLE) += maple/ |
16 | obj-$(CONFIG_PPC_CELL) += cell/ | 16 | obj-$(CONFIG_PPC_CELL) += cell/ |
17 | obj-$(CONFIG_EMBEDDED6xx) += embedded6xx/ | ||
diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig index 352bbbacde9a..0c8c7b6ab897 100644 --- a/arch/powerpc/platforms/cell/Kconfig +++ b/arch/powerpc/platforms/cell/Kconfig | |||
@@ -6,6 +6,7 @@ config SPU_FS | |||
6 | default m | 6 | default m |
7 | depends on PPC_CELL | 7 | depends on PPC_CELL |
8 | select SPU_BASE | 8 | select SPU_BASE |
9 | select MEMORY_HOTPLUG | ||
9 | help | 10 | help |
10 | The SPU file system is used to access Synergistic Processing | 11 | The SPU file system is used to access Synergistic Processing |
11 | Units on machines implementing the Broadband Processor | 12 | Units on machines implementing the Broadband Processor |
@@ -18,7 +19,6 @@ config SPU_BASE | |||
18 | config SPUFS_MMAP | 19 | config SPUFS_MMAP |
19 | bool | 20 | bool |
20 | depends on SPU_FS && SPARSEMEM | 21 | depends on SPU_FS && SPARSEMEM |
21 | select MEMORY_HOTPLUG | ||
22 | default y | 22 | default y |
23 | 23 | ||
24 | config CBE_RAS | 24 | config CBE_RAS |
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c index 1bbf822b4efc..7bff3cbc5723 100644 --- a/arch/powerpc/platforms/cell/interrupt.c +++ b/arch/powerpc/platforms/cell/interrupt.c | |||
@@ -307,7 +307,7 @@ static void iic_request_ipi(int ipi, const char *name) | |||
307 | irq = iic_ipi_to_irq(ipi); | 307 | irq = iic_ipi_to_irq(ipi); |
308 | /* IPIs are marked SA_INTERRUPT as they must run with irqs | 308 | /* IPIs are marked SA_INTERRUPT as they must run with irqs |
309 | * disabled */ | 309 | * disabled */ |
310 | get_irq_desc(irq)->handler = &iic_pic; | 310 | get_irq_desc(irq)->chip = &iic_pic; |
311 | get_irq_desc(irq)->status |= IRQ_PER_CPU; | 311 | get_irq_desc(irq)->status |= IRQ_PER_CPU; |
312 | request_irq(irq, iic_ipi_action, SA_INTERRUPT, name, NULL); | 312 | request_irq(irq, iic_ipi_action, SA_INTERRUPT, name, NULL); |
313 | } | 313 | } |
@@ -330,7 +330,7 @@ static void iic_setup_spe_handlers(void) | |||
330 | for (be=0; be < num_present_cpus() / 2; be++) { | 330 | for (be=0; be < num_present_cpus() / 2; be++) { |
331 | for (isrc = 0; isrc < IIC_CLASS_STRIDE * 3; isrc++) { | 331 | for (isrc = 0; isrc < IIC_CLASS_STRIDE * 3; isrc++) { |
332 | int irq = IIC_NODE_STRIDE * be + IIC_SPE_OFFSET + isrc; | 332 | int irq = IIC_NODE_STRIDE * be + IIC_SPE_OFFSET + isrc; |
333 | get_irq_desc(irq)->handler = &iic_pic; | 333 | get_irq_desc(irq)->chip = &iic_pic; |
334 | } | 334 | } |
335 | } | 335 | } |
336 | } | 336 | } |
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c index 3d1831d331e5..00d112f92272 100644 --- a/arch/powerpc/platforms/cell/setup.c +++ b/arch/powerpc/platforms/cell/setup.c | |||
@@ -125,8 +125,6 @@ static void __init cell_init_early(void) | |||
125 | { | 125 | { |
126 | DBG(" -> cell_init_early()\n"); | 126 | DBG(" -> cell_init_early()\n"); |
127 | 127 | ||
128 | hpte_init_native(); | ||
129 | |||
130 | cell_init_iommu(); | 128 | cell_init_iommu(); |
131 | 129 | ||
132 | ppc64_interrupt_controller = IC_CELL_PIC; | 130 | ppc64_interrupt_controller = IC_CELL_PIC; |
@@ -139,11 +137,17 @@ static int __init cell_probe(void) | |||
139 | { | 137 | { |
140 | unsigned long root = of_get_flat_dt_root(); | 138 | unsigned long root = of_get_flat_dt_root(); |
141 | 139 | ||
142 | if (of_flat_dt_is_compatible(root, "IBM,CBEA") || | 140 | if (!of_flat_dt_is_compatible(root, "IBM,CBEA") && |
143 | of_flat_dt_is_compatible(root, "IBM,CPBW-1.0")) | 141 | !of_flat_dt_is_compatible(root, "IBM,CPBW-1.0")) |
144 | return 1; | 142 | return 0; |
143 | |||
144 | #ifdef CONFIG_UDBG_RTAS_CONSOLE | ||
145 | udbg_init_rtas_console(); | ||
146 | #endif | ||
147 | |||
148 | hpte_init_native(); | ||
145 | 149 | ||
146 | return 0; | 150 | return 1; |
147 | } | 151 | } |
148 | 152 | ||
149 | /* | 153 | /* |
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c index 55cbdd77a62d..7c3a0b6d34fd 100644 --- a/arch/powerpc/platforms/cell/spider-pic.c +++ b/arch/powerpc/platforms/cell/spider-pic.c | |||
@@ -162,7 +162,7 @@ void spider_init_IRQ_hardcoded(void) | |||
162 | spider_pics[node] = ioremap(spiderpic, 0x800); | 162 | spider_pics[node] = ioremap(spiderpic, 0x800); |
163 | for (n = 0; n < IIC_NUM_EXT; n++) { | 163 | for (n = 0; n < IIC_NUM_EXT; n++) { |
164 | int irq = n + IIC_EXT_OFFSET + node * IIC_NODE_STRIDE; | 164 | int irq = n + IIC_EXT_OFFSET + node * IIC_NODE_STRIDE; |
165 | get_irq_desc(irq)->handler = &spider_pic; | 165 | get_irq_desc(irq)->chip = &spider_pic; |
166 | } | 166 | } |
167 | 167 | ||
168 | /* do not mask any interrupts because of level */ | 168 | /* do not mask any interrupts because of level */ |
@@ -217,7 +217,7 @@ void spider_init_IRQ(void) | |||
217 | 217 | ||
218 | for (n = 0; n < IIC_NUM_EXT; n++) { | 218 | for (n = 0; n < IIC_NUM_EXT; n++) { |
219 | int irq = n + IIC_EXT_OFFSET + node * IIC_NODE_STRIDE; | 219 | int irq = n + IIC_EXT_OFFSET + node * IIC_NODE_STRIDE; |
220 | get_irq_desc(irq)->handler = &spider_pic; | 220 | get_irq_desc(irq)->chip = &spider_pic; |
221 | } | 221 | } |
222 | 222 | ||
223 | /* do not mask any interrupts because of level */ | 223 | /* do not mask any interrupts because of level */ |
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index db82f503ba2c..b306723abb87 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c | |||
@@ -168,12 +168,12 @@ spu_irq_class_0_bottom(struct spu *spu) | |||
168 | 168 | ||
169 | stat &= mask; | 169 | stat &= mask; |
170 | 170 | ||
171 | if (stat & 1) /* invalid MFC DMA */ | 171 | if (stat & 1) /* invalid DMA alignment */ |
172 | __spu_trap_invalid_dma(spu); | ||
173 | |||
174 | if (stat & 2) /* invalid DMA alignment */ | ||
175 | __spu_trap_dma_align(spu); | 172 | __spu_trap_dma_align(spu); |
176 | 173 | ||
174 | if (stat & 2) /* invalid MFC DMA */ | ||
175 | __spu_trap_invalid_dma(spu); | ||
176 | |||
177 | if (stat & 4) /* error on SPU */ | 177 | if (stat & 4) /* error on SPU */ |
178 | __spu_trap_error(spu); | 178 | __spu_trap_error(spu); |
179 | 179 | ||
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 7854a380dce2..58e794f9da1b 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c | |||
@@ -204,7 +204,7 @@ static int spufs_cntl_mmap(struct file *file, struct vm_area_struct *vma) | |||
204 | 204 | ||
205 | vma->vm_flags |= VM_RESERVED; | 205 | vma->vm_flags |= VM_RESERVED; |
206 | vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) | 206 | vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) |
207 | | _PAGE_NO_CACHE); | 207 | | _PAGE_NO_CACHE | _PAGE_GUARDED); |
208 | 208 | ||
209 | vma->vm_ops = &spufs_cntl_mmap_vmops; | 209 | vma->vm_ops = &spufs_cntl_mmap_vmops; |
210 | return 0; | 210 | return 0; |
@@ -675,7 +675,7 @@ static int spufs_signal1_mmap(struct file *file, struct vm_area_struct *vma) | |||
675 | 675 | ||
676 | vma->vm_flags |= VM_RESERVED; | 676 | vma->vm_flags |= VM_RESERVED; |
677 | vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) | 677 | vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) |
678 | | _PAGE_NO_CACHE); | 678 | | _PAGE_NO_CACHE | _PAGE_GUARDED); |
679 | 679 | ||
680 | vma->vm_ops = &spufs_signal1_mmap_vmops; | 680 | vma->vm_ops = &spufs_signal1_mmap_vmops; |
681 | return 0; | 681 | return 0; |
@@ -762,7 +762,7 @@ static int spufs_signal2_mmap(struct file *file, struct vm_area_struct *vma) | |||
762 | /* FIXME: */ | 762 | /* FIXME: */ |
763 | vma->vm_flags |= VM_RESERVED; | 763 | vma->vm_flags |= VM_RESERVED; |
764 | vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) | 764 | vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) |
765 | | _PAGE_NO_CACHE); | 765 | | _PAGE_NO_CACHE | _PAGE_GUARDED); |
766 | 766 | ||
767 | vma->vm_ops = &spufs_signal2_mmap_vmops; | 767 | vma->vm_ops = &spufs_signal2_mmap_vmops; |
768 | return 0; | 768 | return 0; |
@@ -850,7 +850,7 @@ static int spufs_mss_mmap(struct file *file, struct vm_area_struct *vma) | |||
850 | 850 | ||
851 | vma->vm_flags |= VM_RESERVED; | 851 | vma->vm_flags |= VM_RESERVED; |
852 | vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) | 852 | vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) |
853 | | _PAGE_NO_CACHE); | 853 | | _PAGE_NO_CACHE | _PAGE_GUARDED); |
854 | 854 | ||
855 | vma->vm_ops = &spufs_mss_mmap_vmops; | 855 | vma->vm_ops = &spufs_mss_mmap_vmops; |
856 | return 0; | 856 | return 0; |
@@ -899,7 +899,7 @@ static int spufs_mfc_mmap(struct file *file, struct vm_area_struct *vma) | |||
899 | 899 | ||
900 | vma->vm_flags |= VM_RESERVED; | 900 | vma->vm_flags |= VM_RESERVED; |
901 | vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) | 901 | vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) |
902 | | _PAGE_NO_CACHE); | 902 | | _PAGE_NO_CACHE | _PAGE_GUARDED); |
903 | 903 | ||
904 | vma->vm_ops = &spufs_mfc_mmap_vmops; | 904 | vma->vm_ops = &spufs_mfc_mmap_vmops; |
905 | return 0; | 905 | return 0; |
diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c index a656d810a44a..c7fea2cca534 100644 --- a/arch/powerpc/platforms/cell/spufs/switch.c +++ b/arch/powerpc/platforms/cell/spufs/switch.c | |||
@@ -464,7 +464,8 @@ static inline void wait_purge_complete(struct spu_state *csa, struct spu *spu) | |||
464 | * Poll MFC_CNTL[Ps] until value '11' is read | 464 | * Poll MFC_CNTL[Ps] until value '11' is read |
465 | * (purge complete). | 465 | * (purge complete). |
466 | */ | 466 | */ |
467 | POLL_WHILE_FALSE(in_be64(&priv2->mfc_control_RW) & | 467 | POLL_WHILE_FALSE((in_be64(&priv2->mfc_control_RW) & |
468 | MFC_CNTL_PURGE_DMA_STATUS_MASK) == | ||
468 | MFC_CNTL_PURGE_DMA_COMPLETE); | 469 | MFC_CNTL_PURGE_DMA_COMPLETE); |
469 | } | 470 | } |
470 | 471 | ||
@@ -1028,7 +1029,8 @@ static inline void wait_suspend_mfc_complete(struct spu_state *csa, | |||
1028 | * Restore, Step 47. | 1029 | * Restore, Step 47. |
1029 | * Poll MFC_CNTL[Ss] until 11 is returned. | 1030 | * Poll MFC_CNTL[Ss] until 11 is returned. |
1030 | */ | 1031 | */ |
1031 | POLL_WHILE_FALSE(in_be64(&priv2->mfc_control_RW) & | 1032 | POLL_WHILE_FALSE((in_be64(&priv2->mfc_control_RW) & |
1033 | MFC_CNTL_SUSPEND_DMA_STATUS_MASK) == | ||
1032 | MFC_CNTL_SUSPEND_COMPLETE); | 1034 | MFC_CNTL_SUSPEND_COMPLETE); |
1033 | } | 1035 | } |
1034 | 1036 | ||
diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c index ac224876ce59..53515daf01b1 100644 --- a/arch/powerpc/platforms/chrp/pci.c +++ b/arch/powerpc/platforms/chrp/pci.c | |||
@@ -143,7 +143,7 @@ hydra_init(void) | |||
143 | if (np == NULL || of_address_to_resource(np, 0, &r)) | 143 | if (np == NULL || of_address_to_resource(np, 0, &r)) |
144 | return 0; | 144 | return 0; |
145 | Hydra = ioremap(r.start, r.end-r.start); | 145 | Hydra = ioremap(r.start, r.end-r.start); |
146 | printk("Hydra Mac I/O at %lx\n", r.start); | 146 | printk("Hydra Mac I/O at %llx\n", (unsigned long long)r.start); |
147 | printk("Hydra Feature_Control was %x", | 147 | printk("Hydra Feature_Control was %x", |
148 | in_le32(&Hydra->Feature_Control)); | 148 | in_le32(&Hydra->Feature_Control)); |
149 | out_le32(&Hydra->Feature_Control, (HYDRA_FC_SCC_CELL_EN | | 149 | out_le32(&Hydra->Feature_Control, (HYDRA_FC_SCC_CELL_EN | |
@@ -267,7 +267,7 @@ chrp_find_bridges(void) | |||
267 | bus_range[0], bus_range[1]); | 267 | bus_range[0], bus_range[1]); |
268 | printk(" controlled by %s", dev->type); | 268 | printk(" controlled by %s", dev->type); |
269 | if (!is_longtrail) | 269 | if (!is_longtrail) |
270 | printk(" at %lx", r.start); | 270 | printk(" at %llx", (unsigned long long)r.start); |
271 | printk("\n"); | 271 | printk("\n"); |
272 | 272 | ||
273 | hose = pcibios_alloc_controller(); | 273 | hose = pcibios_alloc_controller(); |
diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig index 4fdbc9ae876b..ba07a9a7c039 100644 --- a/arch/powerpc/platforms/embedded6xx/Kconfig +++ b/arch/powerpc/platforms/embedded6xx/Kconfig | |||
@@ -74,6 +74,16 @@ config SANDPOINT | |||
74 | Select SANDPOINT if configuring for a Motorola Sandpoint X3 | 74 | Select SANDPOINT if configuring for a Motorola Sandpoint X3 |
75 | (any flavor). | 75 | (any flavor). |
76 | 76 | ||
77 | config MPC7448HPC2 | ||
78 | bool "Freescale MPC7448HPC2(Taiga)" | ||
79 | select TSI108_BRIDGE | ||
80 | select DEFAULT_UIMAGE | ||
81 | select PPC_UDBG_16550 | ||
82 | select MPIC | ||
83 | help | ||
84 | Select MPC7448HPC2 if configuring for Freescale MPC7448HPC2 (Taiga) | ||
85 | platform | ||
86 | |||
77 | config RADSTONE_PPC7D | 87 | config RADSTONE_PPC7D |
78 | bool "Radstone Technology PPC7D board" | 88 | bool "Radstone Technology PPC7D board" |
79 | select PPC_I8259 | 89 | select PPC_I8259 |
@@ -221,6 +231,11 @@ config MV64X60 | |||
221 | select PPC_INDIRECT_PCI | 231 | select PPC_INDIRECT_PCI |
222 | default y | 232 | default y |
223 | 233 | ||
234 | config TSI108_BRIDGE | ||
235 | bool | ||
236 | depends on MPC7448HPC2 | ||
237 | default y | ||
238 | |||
224 | menu "Set bridge options" | 239 | menu "Set bridge options" |
225 | depends on MV64X60 | 240 | depends on MV64X60 |
226 | 241 | ||
diff --git a/arch/powerpc/platforms/embedded6xx/Makefile b/arch/powerpc/platforms/embedded6xx/Makefile new file mode 100644 index 000000000000..fa499fe59291 --- /dev/null +++ b/arch/powerpc/platforms/embedded6xx/Makefile | |||
@@ -0,0 +1,4 @@ | |||
1 | # | ||
2 | # Makefile for the 6xx/7xx/7xxxx linux kernel. | ||
3 | # | ||
4 | obj-$(CONFIG_MPC7448HPC2) += mpc7448_hpc2.o | ||
diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c new file mode 100644 index 000000000000..d7a4fc7ca238 --- /dev/null +++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c | |||
@@ -0,0 +1,335 @@ | |||
1 | /* | ||
2 | * mpc7448_hpc2.c | ||
3 | * | ||
4 | * Board setup routines for the Freescale Taiga platform | ||
5 | * | ||
6 | * Author: Jacob Pan | ||
7 | * jacob.pan@freescale.com | ||
8 | * Author: Xianghua Xiao | ||
9 | * x.xiao@freescale.com | ||
10 | * Maintainer: Roy Zang <tie-fei.zang@freescale.com> | ||
11 | * Add Flat Device Tree support fot mpc7448hpc2 board | ||
12 | * | ||
13 | * Copyright 2004-2006 Freescale Semiconductor, Inc. | ||
14 | * | ||
15 | * This file is licensed under | ||
16 | * the terms of the GNU General Public License version 2. This program | ||
17 | * is licensed "as is" without any warranty of any kind, whether express | ||
18 | * or implied. | ||
19 | */ | ||
20 | |||
21 | #include <linux/config.h> | ||
22 | #include <linux/stddef.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/pci.h> | ||
25 | #include <linux/kdev_t.h> | ||
26 | #include <linux/console.h> | ||
27 | #include <linux/delay.h> | ||
28 | #include <linux/irq.h> | ||
29 | #include <linux/ide.h> | ||
30 | #include <linux/seq_file.h> | ||
31 | #include <linux/root_dev.h> | ||
32 | #include <linux/serial.h> | ||
33 | #include <linux/tty.h> | ||
34 | #include <linux/serial_core.h> | ||
35 | |||
36 | #include <asm/system.h> | ||
37 | #include <asm/time.h> | ||
38 | #include <asm/machdep.h> | ||
39 | #include <asm/prom.h> | ||
40 | #include <asm/udbg.h> | ||
41 | #include <asm/tsi108.h> | ||
42 | #include <asm/pci-bridge.h> | ||
43 | #include <asm/reg.h> | ||
44 | #include <mm/mmu_decl.h> | ||
45 | #include "mpc7448_hpc2.h" | ||
46 | #include <asm/tsi108_irq.h> | ||
47 | #include <asm/mpic.h> | ||
48 | |||
49 | #undef DEBUG | ||
50 | #ifdef DEBUG | ||
51 | #define DBG(fmt...) do { printk(fmt); } while(0) | ||
52 | #else | ||
53 | #define DBG(fmt...) do { } while(0) | ||
54 | #endif | ||
55 | |||
56 | #ifndef CONFIG_PCI | ||
57 | isa_io_base = MPC7448_HPC2_ISA_IO_BASE; | ||
58 | isa_mem_base = MPC7448_HPC2_ISA_MEM_BASE; | ||
59 | pci_dram_offset = MPC7448_HPC2_PCI_MEM_OFFSET; | ||
60 | #endif | ||
61 | |||
62 | extern int tsi108_setup_pci(struct device_node *dev); | ||
63 | extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val); | ||
64 | extern void tsi108_pci_int_init(void); | ||
65 | extern int tsi108_irq_cascade(struct pt_regs *regs, void *unused); | ||
66 | |||
67 | /* | ||
68 | * Define all of the IRQ senses and polarities. Taken from the | ||
69 | * mpc7448hpc manual. | ||
70 | * Note: Likely, this table and the following function should be | ||
71 | * obtained and derived from the OF Device Tree. | ||
72 | */ | ||
73 | |||
74 | static u_char mpc7448_hpc2_pic_initsenses[] __initdata = { | ||
75 | /* External on-board sources */ | ||
76 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[0] XINT0 from FPGA */ | ||
77 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[1] XINT1 from FPGA */ | ||
78 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[2] PHY_INT from both GIGE */ | ||
79 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[3] RESERVED */ | ||
80 | /* Internal Tsi108/109 interrupt sources */ | ||
81 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */ | ||
82 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */ | ||
83 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */ | ||
84 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */ | ||
85 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA0 */ | ||
86 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA1 */ | ||
87 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA2 */ | ||
88 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA3 */ | ||
89 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* UART0 */ | ||
90 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* UART1 */ | ||
91 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* I2C */ | ||
92 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* GPIO */ | ||
93 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* GIGE0 */ | ||
94 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* GIGE1 */ | ||
95 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */ | ||
96 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* HLP */ | ||
97 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* SDC */ | ||
98 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Processor IF */ | ||
99 | (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */ | ||
100 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* PCI/X block */ | ||
101 | }; | ||
102 | |||
103 | int mpc7448_hpc2_exclude_device(u_char bus, u_char devfn) | ||
104 | { | ||
105 | if (bus == 0 && PCI_SLOT(devfn) == 0) | ||
106 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
107 | else | ||
108 | return PCIBIOS_SUCCESSFUL; | ||
109 | } | ||
110 | |||
111 | /* | ||
112 | * find pci slot by devfn in interrupt map of OF tree | ||
113 | */ | ||
114 | u8 find_slot_by_devfn(unsigned int *interrupt_map, unsigned int devfn) | ||
115 | { | ||
116 | int i; | ||
117 | unsigned int tmp; | ||
118 | for (i = 0; i < 4; i++){ | ||
119 | tmp = interrupt_map[i*4*7]; | ||
120 | if ((tmp >> 11) == (devfn >> 3)) | ||
121 | return i; | ||
122 | } | ||
123 | return i; | ||
124 | } | ||
125 | |||
126 | /* | ||
127 | * Scans the interrupt map for pci device | ||
128 | */ | ||
129 | void mpc7448_hpc2_fixup_irq(struct pci_dev *dev) | ||
130 | { | ||
131 | struct pci_controller *hose; | ||
132 | struct device_node *node; | ||
133 | unsigned int *interrupt; | ||
134 | int busnr; | ||
135 | int len; | ||
136 | u8 slot; | ||
137 | u8 pin; | ||
138 | |||
139 | /* Lookup the hose */ | ||
140 | busnr = dev->bus->number; | ||
141 | hose = pci_bus_to_hose(busnr); | ||
142 | if (!hose) | ||
143 | printk(KERN_ERR "No pci hose found\n"); | ||
144 | |||
145 | /* Check it has an OF node associated */ | ||
146 | node = (struct device_node *) hose->arch_data; | ||
147 | if (!node) | ||
148 | printk(KERN_ERR "No pci node found\n"); | ||
149 | |||
150 | interrupt = (unsigned int *) get_property(node, "interrupt-map", &len); | ||
151 | slot = find_slot_by_devfn(interrupt, dev->devfn); | ||
152 | pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); | ||
153 | if (pin == 0 || pin > 4) | ||
154 | pin = 1; | ||
155 | pin--; | ||
156 | dev->irq = interrupt[slot*4*7 + pin*7 + 5]; | ||
157 | DBG("TSI_PCI: dev->irq = 0x%x\n", dev->irq); | ||
158 | } | ||
159 | /* temporary pci irq map fixup*/ | ||
160 | |||
161 | void __init mpc7448_hpc2_pcibios_fixup(void) | ||
162 | { | ||
163 | struct pci_dev *dev = NULL; | ||
164 | for_each_pci_dev(dev) { | ||
165 | mpc7448_hpc2_fixup_irq(dev); | ||
166 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); | ||
167 | } | ||
168 | } | ||
169 | |||
170 | static void __init mpc7448_hpc2_setup_arch(void) | ||
171 | { | ||
172 | struct device_node *cpu; | ||
173 | struct device_node *np; | ||
174 | if (ppc_md.progress) | ||
175 | ppc_md.progress("mpc7448_hpc2_setup_arch():set_bridge", 0); | ||
176 | |||
177 | cpu = of_find_node_by_type(NULL, "cpu"); | ||
178 | if (cpu != 0) { | ||
179 | unsigned int *fp; | ||
180 | |||
181 | fp = (int *)get_property(cpu, "clock-frequency", NULL); | ||
182 | if (fp != 0) | ||
183 | loops_per_jiffy = *fp / HZ; | ||
184 | else | ||
185 | loops_per_jiffy = 50000000 / HZ; | ||
186 | of_node_put(cpu); | ||
187 | } | ||
188 | tsi108_csr_vir_base = get_vir_csrbase(); | ||
189 | |||
190 | #ifdef CONFIG_ROOT_NFS | ||
191 | ROOT_DEV = Root_NFS; | ||
192 | #else | ||
193 | ROOT_DEV = Root_HDA1; | ||
194 | #endif | ||
195 | |||
196 | #ifdef CONFIG_BLK_DEV_INITRD | ||
197 | ROOT_DEV = Root_RAM0; | ||
198 | #endif | ||
199 | |||
200 | /* setup PCI host bridge */ | ||
201 | #ifdef CONFIG_PCI | ||
202 | for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) | ||
203 | tsi108_setup_pci(np); | ||
204 | |||
205 | ppc_md.pci_exclude_device = mpc7448_hpc2_exclude_device; | ||
206 | if (ppc_md.progress) | ||
207 | ppc_md.progress("tsi108: resources set", 0x100); | ||
208 | #endif | ||
209 | |||
210 | printk(KERN_INFO "MPC7448HPC2 (TAIGA) Platform\n"); | ||
211 | printk(KERN_INFO | ||
212 | "Jointly ported by Freescale and Tundra Semiconductor\n"); | ||
213 | printk(KERN_INFO | ||
214 | "Enabling L2 cache then enabling the HID0 prefetch engine.\n"); | ||
215 | } | ||
216 | |||
217 | /* | ||
218 | * Interrupt setup and service. Interrrupts on the mpc7448_hpc2 come | ||
219 | * from the four external INT pins, PCI interrupts are routed via | ||
220 | * PCI interrupt control registers, it generates internal IRQ23 | ||
221 | * | ||
222 | * Interrupt routing on the Taiga Board: | ||
223 | * TSI108:PB_INT[0] -> CPU0:INT# | ||
224 | * TSI108:PB_INT[1] -> CPU0:MCP# | ||
225 | * TSI108:PB_INT[2] -> N/C | ||
226 | * TSI108:PB_INT[3] -> N/C | ||
227 | */ | ||
228 | static void __init mpc7448_hpc2_init_IRQ(void) | ||
229 | { | ||
230 | struct mpic *mpic; | ||
231 | phys_addr_t mpic_paddr = 0; | ||
232 | struct device_node *tsi_pic; | ||
233 | |||
234 | tsi_pic = of_find_node_by_type(NULL, "open-pic"); | ||
235 | if (tsi_pic) { | ||
236 | unsigned int size; | ||
237 | void *prop = get_property(tsi_pic, "reg", &size); | ||
238 | mpic_paddr = of_translate_address(tsi_pic, prop); | ||
239 | } | ||
240 | |||
241 | if (mpic_paddr == 0) { | ||
242 | printk("%s: No tsi108 PIC found !\n", __FUNCTION__); | ||
243 | return; | ||
244 | } | ||
245 | |||
246 | DBG("%s: tsi108pic phys_addr = 0x%x\n", __FUNCTION__, | ||
247 | (u32) mpic_paddr); | ||
248 | |||
249 | mpic = mpic_alloc(mpic_paddr, | ||
250 | MPIC_PRIMARY | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET | | ||
251 | MPIC_SPV_EOI | MPIC_MOD_ID(MPIC_ID_TSI108), | ||
252 | 0, /* num_sources used */ | ||
253 | TSI108_IRQ_BASE, | ||
254 | 0, /* num_sources used */ | ||
255 | NR_IRQS - 4 /* XXXX */, | ||
256 | mpc7448_hpc2_pic_initsenses, | ||
257 | sizeof(mpc7448_hpc2_pic_initsenses), "Tsi108_PIC"); | ||
258 | |||
259 | BUG_ON(mpic == NULL); /* XXXX */ | ||
260 | |||
261 | mpic_init(mpic); | ||
262 | mpic_setup_cascade(IRQ_TSI108_PCI, tsi108_irq_cascade, mpic); | ||
263 | tsi108_pci_int_init(); | ||
264 | |||
265 | /* Configure MPIC outputs to CPU0 */ | ||
266 | tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0); | ||
267 | } | ||
268 | |||
269 | void mpc7448_hpc2_show_cpuinfo(struct seq_file *m) | ||
270 | { | ||
271 | seq_printf(m, "vendor\t\t: Freescale Semiconductor\n"); | ||
272 | seq_printf(m, "machine\t\t: MPC7448hpc2\n"); | ||
273 | } | ||
274 | |||
275 | void mpc7448_hpc2_restart(char *cmd) | ||
276 | { | ||
277 | local_irq_disable(); | ||
278 | |||
279 | /* Set exception prefix high - to the firmware */ | ||
280 | _nmask_and_or_msr(0, MSR_IP); | ||
281 | |||
282 | for (;;) ; /* Spin until reset happens */ | ||
283 | } | ||
284 | |||
285 | void mpc7448_hpc2_power_off(void) | ||
286 | { | ||
287 | local_irq_disable(); | ||
288 | for (;;) ; /* No way to shut power off with software */ | ||
289 | } | ||
290 | |||
291 | void mpc7448_hpc2_halt(void) | ||
292 | { | ||
293 | mpc7448_hpc2_power_off(); | ||
294 | } | ||
295 | |||
296 | /* | ||
297 | * Called very early, device-tree isn't unflattened | ||
298 | */ | ||
299 | static int __init mpc7448_hpc2_probe(void) | ||
300 | { | ||
301 | unsigned long root = of_get_flat_dt_root(); | ||
302 | |||
303 | if (!of_flat_dt_is_compatible(root, "mpc74xx")) | ||
304 | return 0; | ||
305 | return 1; | ||
306 | } | ||
307 | |||
308 | static int mpc7448_machine_check_exception(struct pt_regs *regs) | ||
309 | { | ||
310 | extern void tsi108_clear_pci_cfg_error(void); | ||
311 | const struct exception_table_entry *entry; | ||
312 | |||
313 | /* Are we prepared to handle this fault */ | ||
314 | if ((entry = search_exception_tables(regs->nip)) != NULL) { | ||
315 | tsi108_clear_pci_cfg_error(); | ||
316 | regs->msr |= MSR_RI; | ||
317 | regs->nip = entry->fixup; | ||
318 | return 1; | ||
319 | } | ||
320 | return 0; | ||
321 | |||
322 | } | ||
323 | define_machine(mpc7448_hpc2){ | ||
324 | .name = "MPC7448 HPC2", | ||
325 | .probe = mpc7448_hpc2_probe, | ||
326 | .setup_arch = mpc7448_hpc2_setup_arch, | ||
327 | .init_IRQ = mpc7448_hpc2_init_IRQ, | ||
328 | .show_cpuinfo = mpc7448_hpc2_show_cpuinfo, | ||
329 | .get_irq = mpic_get_irq, | ||
330 | .pcibios_fixup = mpc7448_hpc2_pcibios_fixup, | ||
331 | .restart = mpc7448_hpc2_restart, | ||
332 | .calibrate_decr = generic_calibrate_decr, | ||
333 | .machine_check_exception= mpc7448_machine_check_exception, | ||
334 | .progress = udbg_progress, | ||
335 | }; | ||
diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.h b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.h new file mode 100644 index 000000000000..a543a5242e34 --- /dev/null +++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.h | |||
@@ -0,0 +1,26 @@ | |||
1 | /* | ||
2 | * mpc7448_hpc2.h | ||
3 | * | ||
4 | * Definitions for Freescale MPC7448_HPC2 platform | ||
5 | * | ||
6 | * Author: Jacob Pan | ||
7 | * jacob.pan@freescale.com | ||
8 | * Maintainer: Roy Zang <roy.zang@freescale.com> | ||
9 | * | ||
10 | * 2006 (c) Freescale Semiconductor, Inc. This file is licensed under | ||
11 | * the terms of the GNU General Public License version 2. This program | ||
12 | * is licensed "as is" without any warranty of any kind, whether express | ||
13 | * or implied. | ||
14 | */ | ||
15 | |||
16 | #ifndef __PPC_PLATFORMS_MPC7448_HPC2_H | ||
17 | #define __PPC_PLATFORMS_MPC7448_HPC2_H | ||
18 | |||
19 | #include <asm/ppcboot.h> | ||
20 | |||
21 | /* Base Addresses for the PCI bus | ||
22 | */ | ||
23 | #define MPC7448_HPC2_PCI_MEM_OFFSET (0x00000000) | ||
24 | #define MPC7448_HPC2_ISA_IO_BASE (0x00000000) | ||
25 | #define MPC7448_HPC2_ISA_MEM_BASE (0x00000000) | ||
26 | #endif /* __PPC_PLATFORMS_MPC7448_HPC2_H */ | ||
diff --git a/arch/powerpc/platforms/iseries/dt.c b/arch/powerpc/platforms/iseries/dt.c index d3444aabe76e..d194140c1ebf 100644 --- a/arch/powerpc/platforms/iseries/dt.c +++ b/arch/powerpc/platforms/iseries/dt.c | |||
@@ -252,6 +252,7 @@ static void __init dt_model(struct iseries_flat_dt *dt) | |||
252 | { | 252 | { |
253 | char buf[16] = "IBM,"; | 253 | char buf[16] = "IBM,"; |
254 | 254 | ||
255 | /* N.B. lparcfg.c knows about the "IBM," prefixes ... */ | ||
255 | /* "IBM," + mfgId[2:3] + systemSerial[1:5] */ | 256 | /* "IBM," + mfgId[2:3] + systemSerial[1:5] */ |
256 | strne2a(buf + 4, xItExtVpdPanel.mfgID + 2, 2); | 257 | strne2a(buf + 4, xItExtVpdPanel.mfgID + 2, 2); |
257 | strne2a(buf + 6, xItExtVpdPanel.systemSerial + 1, 5); | 258 | strne2a(buf + 6, xItExtVpdPanel.systemSerial + 1, 5); |
@@ -264,6 +265,7 @@ static void __init dt_model(struct iseries_flat_dt *dt) | |||
264 | dt_prop_str(dt, "model", buf); | 265 | dt_prop_str(dt, "model", buf); |
265 | 266 | ||
266 | dt_prop_str(dt, "compatible", "IBM,iSeries"); | 267 | dt_prop_str(dt, "compatible", "IBM,iSeries"); |
268 | dt_prop_u32(dt, "ibm,partition-no", HvLpConfig_getLpIndex()); | ||
267 | } | 269 | } |
268 | 270 | ||
269 | static void __init dt_do_vdevice(struct iseries_flat_dt *dt, | 271 | static void __init dt_do_vdevice(struct iseries_flat_dt *dt, |
diff --git a/arch/powerpc/platforms/iseries/htab.c b/arch/powerpc/platforms/iseries/htab.c index 30bdcf3925d9..ed44dfceaa45 100644 --- a/arch/powerpc/platforms/iseries/htab.c +++ b/arch/powerpc/platforms/iseries/htab.c | |||
@@ -242,13 +242,11 @@ static void iSeries_hpte_invalidate(unsigned long slot, unsigned long va, | |||
242 | local_irq_restore(flags); | 242 | local_irq_restore(flags); |
243 | } | 243 | } |
244 | 244 | ||
245 | void hpte_init_iSeries(void) | 245 | void __init hpte_init_iSeries(void) |
246 | { | 246 | { |
247 | ppc_md.hpte_invalidate = iSeries_hpte_invalidate; | 247 | ppc_md.hpte_invalidate = iSeries_hpte_invalidate; |
248 | ppc_md.hpte_updatepp = iSeries_hpte_updatepp; | 248 | ppc_md.hpte_updatepp = iSeries_hpte_updatepp; |
249 | ppc_md.hpte_updateboltedpp = iSeries_hpte_updateboltedpp; | 249 | ppc_md.hpte_updateboltedpp = iSeries_hpte_updateboltedpp; |
250 | ppc_md.hpte_insert = iSeries_hpte_insert; | 250 | ppc_md.hpte_insert = iSeries_hpte_insert; |
251 | ppc_md.hpte_remove = iSeries_hpte_remove; | 251 | ppc_md.hpte_remove = iSeries_hpte_remove; |
252 | |||
253 | htab_finish_init(); | ||
254 | } | 252 | } |
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c index 62bbbcf5ded3..33bb4aa0e1e8 100644 --- a/arch/powerpc/platforms/iseries/irq.c +++ b/arch/powerpc/platforms/iseries/irq.c | |||
@@ -242,9 +242,9 @@ void __init iSeries_activate_IRQs() | |||
242 | for_each_irq (irq) { | 242 | for_each_irq (irq) { |
243 | irq_desc_t *desc = get_irq_desc(irq); | 243 | irq_desc_t *desc = get_irq_desc(irq); |
244 | 244 | ||
245 | if (desc && desc->handler && desc->handler->startup) { | 245 | if (desc && desc->chip && desc->chip->startup) { |
246 | spin_lock_irqsave(&desc->lock, flags); | 246 | spin_lock_irqsave(&desc->lock, flags); |
247 | desc->handler->startup(irq); | 247 | desc->chip->startup(irq); |
248 | spin_unlock_irqrestore(&desc->lock, flags); | 248 | spin_unlock_irqrestore(&desc->lock, flags); |
249 | } | 249 | } |
250 | } | 250 | } |
@@ -324,7 +324,7 @@ int __init iSeries_allocate_IRQ(HvBusNumber bus, | |||
324 | + function; | 324 | + function; |
325 | virtirq = virt_irq_create_mapping(realirq); | 325 | virtirq = virt_irq_create_mapping(realirq); |
326 | 326 | ||
327 | irq_desc[virtirq].handler = &iSeries_IRQ_handler; | 327 | irq_desc[virtirq].chip = &iSeries_IRQ_handler; |
328 | return virtirq; | 328 | return virtirq; |
329 | } | 329 | } |
330 | 330 | ||
diff --git a/arch/powerpc/platforms/iseries/lpevents.c b/arch/powerpc/platforms/iseries/lpevents.c index 8ca7b9396355..2a9f81ea27d6 100644 --- a/arch/powerpc/platforms/iseries/lpevents.c +++ b/arch/powerpc/platforms/iseries/lpevents.c | |||
@@ -51,20 +51,21 @@ static unsigned lpEventHandlerPaths[HvLpEvent_Type_NumTypes]; | |||
51 | static struct HvLpEvent * get_next_hvlpevent(void) | 51 | static struct HvLpEvent * get_next_hvlpevent(void) |
52 | { | 52 | { |
53 | struct HvLpEvent * event; | 53 | struct HvLpEvent * event; |
54 | event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; | 54 | event = (struct HvLpEvent *)hvlpevent_queue.hq_current_event; |
55 | 55 | ||
56 | if (hvlpevent_is_valid(event)) { | 56 | if (hvlpevent_is_valid(event)) { |
57 | /* rmb() needed only for weakly consistent machines (regatta) */ | 57 | /* rmb() needed only for weakly consistent machines (regatta) */ |
58 | rmb(); | 58 | rmb(); |
59 | /* Set pointer to next potential event */ | 59 | /* Set pointer to next potential event */ |
60 | hvlpevent_queue.xSlicCurEventPtr += ((event->xSizeMinus1 + | 60 | hvlpevent_queue.hq_current_event += ((event->xSizeMinus1 + |
61 | LpEventAlign) / LpEventAlign) * LpEventAlign; | 61 | IT_LP_EVENT_ALIGN) / IT_LP_EVENT_ALIGN) * |
62 | IT_LP_EVENT_ALIGN; | ||
62 | 63 | ||
63 | /* Wrap to beginning if no room at end */ | 64 | /* Wrap to beginning if no room at end */ |
64 | if (hvlpevent_queue.xSlicCurEventPtr > | 65 | if (hvlpevent_queue.hq_current_event > |
65 | hvlpevent_queue.xSlicLastValidEventPtr) { | 66 | hvlpevent_queue.hq_last_event) { |
66 | hvlpevent_queue.xSlicCurEventPtr = | 67 | hvlpevent_queue.hq_current_event = |
67 | hvlpevent_queue.xSlicEventStackPtr; | 68 | hvlpevent_queue.hq_event_stack; |
68 | } | 69 | } |
69 | } else { | 70 | } else { |
70 | event = NULL; | 71 | event = NULL; |
@@ -82,10 +83,10 @@ int hvlpevent_is_pending(void) | |||
82 | if (smp_processor_id() >= spread_lpevents) | 83 | if (smp_processor_id() >= spread_lpevents) |
83 | return 0; | 84 | return 0; |
84 | 85 | ||
85 | next_event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; | 86 | next_event = (struct HvLpEvent *)hvlpevent_queue.hq_current_event; |
86 | 87 | ||
87 | return hvlpevent_is_valid(next_event) || | 88 | return hvlpevent_is_valid(next_event) || |
88 | hvlpevent_queue.xPlicOverflowIntPending; | 89 | hvlpevent_queue.hq_overflow_pending; |
89 | } | 90 | } |
90 | 91 | ||
91 | static void hvlpevent_clear_valid(struct HvLpEvent * event) | 92 | static void hvlpevent_clear_valid(struct HvLpEvent * event) |
@@ -95,18 +96,18 @@ static void hvlpevent_clear_valid(struct HvLpEvent * event) | |||
95 | * ie. on 64-byte boundaries. | 96 | * ie. on 64-byte boundaries. |
96 | */ | 97 | */ |
97 | struct HvLpEvent *tmp; | 98 | struct HvLpEvent *tmp; |
98 | unsigned extra = ((event->xSizeMinus1 + LpEventAlign) / | 99 | unsigned extra = ((event->xSizeMinus1 + IT_LP_EVENT_ALIGN) / |
99 | LpEventAlign) - 1; | 100 | IT_LP_EVENT_ALIGN) - 1; |
100 | 101 | ||
101 | switch (extra) { | 102 | switch (extra) { |
102 | case 3: | 103 | case 3: |
103 | tmp = (struct HvLpEvent*)((char*)event + 3 * LpEventAlign); | 104 | tmp = (struct HvLpEvent*)((char*)event + 3 * IT_LP_EVENT_ALIGN); |
104 | hvlpevent_invalidate(tmp); | 105 | hvlpevent_invalidate(tmp); |
105 | case 2: | 106 | case 2: |
106 | tmp = (struct HvLpEvent*)((char*)event + 2 * LpEventAlign); | 107 | tmp = (struct HvLpEvent*)((char*)event + 2 * IT_LP_EVENT_ALIGN); |
107 | hvlpevent_invalidate(tmp); | 108 | hvlpevent_invalidate(tmp); |
108 | case 1: | 109 | case 1: |
109 | tmp = (struct HvLpEvent*)((char*)event + 1 * LpEventAlign); | 110 | tmp = (struct HvLpEvent*)((char*)event + 1 * IT_LP_EVENT_ALIGN); |
110 | hvlpevent_invalidate(tmp); | 111 | hvlpevent_invalidate(tmp); |
111 | } | 112 | } |
112 | 113 | ||
@@ -120,7 +121,7 @@ void process_hvlpevents(struct pt_regs *regs) | |||
120 | struct HvLpEvent * event; | 121 | struct HvLpEvent * event; |
121 | 122 | ||
122 | /* If we have recursed, just return */ | 123 | /* If we have recursed, just return */ |
123 | if (!spin_trylock(&hvlpevent_queue.lock)) | 124 | if (!spin_trylock(&hvlpevent_queue.hq_lock)) |
124 | return; | 125 | return; |
125 | 126 | ||
126 | for (;;) { | 127 | for (;;) { |
@@ -148,17 +149,17 @@ void process_hvlpevents(struct pt_regs *regs) | |||
148 | printk(KERN_INFO "Unexpected Lp Event type=%d\n", event->xType ); | 149 | printk(KERN_INFO "Unexpected Lp Event type=%d\n", event->xType ); |
149 | 150 | ||
150 | hvlpevent_clear_valid(event); | 151 | hvlpevent_clear_valid(event); |
151 | } else if (hvlpevent_queue.xPlicOverflowIntPending) | 152 | } else if (hvlpevent_queue.hq_overflow_pending) |
152 | /* | 153 | /* |
153 | * No more valid events. If overflow events are | 154 | * No more valid events. If overflow events are |
154 | * pending process them | 155 | * pending process them |
155 | */ | 156 | */ |
156 | HvCallEvent_getOverflowLpEvents(hvlpevent_queue.xIndex); | 157 | HvCallEvent_getOverflowLpEvents(hvlpevent_queue.hq_index); |
157 | else | 158 | else |
158 | break; | 159 | break; |
159 | } | 160 | } |
160 | 161 | ||
161 | spin_unlock(&hvlpevent_queue.lock); | 162 | spin_unlock(&hvlpevent_queue.hq_lock); |
162 | } | 163 | } |
163 | 164 | ||
164 | static int set_spread_lpevents(char *str) | 165 | static int set_spread_lpevents(char *str) |
@@ -184,20 +185,20 @@ void setup_hvlpevent_queue(void) | |||
184 | { | 185 | { |
185 | void *eventStack; | 186 | void *eventStack; |
186 | 187 | ||
187 | spin_lock_init(&hvlpevent_queue.lock); | 188 | spin_lock_init(&hvlpevent_queue.hq_lock); |
188 | 189 | ||
189 | /* Allocate a page for the Event Stack. */ | 190 | /* Allocate a page for the Event Stack. */ |
190 | eventStack = alloc_bootmem_pages(LpEventStackSize); | 191 | eventStack = alloc_bootmem_pages(IT_LP_EVENT_STACK_SIZE); |
191 | memset(eventStack, 0, LpEventStackSize); | 192 | memset(eventStack, 0, IT_LP_EVENT_STACK_SIZE); |
192 | 193 | ||
193 | /* Invoke the hypervisor to initialize the event stack */ | 194 | /* Invoke the hypervisor to initialize the event stack */ |
194 | HvCallEvent_setLpEventStack(0, eventStack, LpEventStackSize); | 195 | HvCallEvent_setLpEventStack(0, eventStack, IT_LP_EVENT_STACK_SIZE); |
195 | 196 | ||
196 | hvlpevent_queue.xSlicEventStackPtr = (char *)eventStack; | 197 | hvlpevent_queue.hq_event_stack = eventStack; |
197 | hvlpevent_queue.xSlicCurEventPtr = (char *)eventStack; | 198 | hvlpevent_queue.hq_current_event = eventStack; |
198 | hvlpevent_queue.xSlicLastValidEventPtr = (char *)eventStack + | 199 | hvlpevent_queue.hq_last_event = (char *)eventStack + |
199 | (LpEventStackSize - LpEventMaxSize); | 200 | (IT_LP_EVENT_STACK_SIZE - IT_LP_EVENT_MAX_SIZE); |
200 | hvlpevent_queue.xIndex = 0; | 201 | hvlpevent_queue.hq_index = 0; |
201 | } | 202 | } |
202 | 203 | ||
203 | /* Register a handler for an LpEvent type */ | 204 | /* Register a handler for an LpEvent type */ |
diff --git a/arch/powerpc/platforms/iseries/proc.c b/arch/powerpc/platforms/iseries/proc.c index e68b6b5fa89f..c241413629ac 100644 --- a/arch/powerpc/platforms/iseries/proc.c +++ b/arch/powerpc/platforms/iseries/proc.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <asm/processor.h> | 24 | #include <asm/processor.h> |
25 | #include <asm/time.h> | 25 | #include <asm/time.h> |
26 | #include <asm/lppaca.h> | 26 | #include <asm/lppaca.h> |
27 | #include <asm/iseries/it_lp_queue.h> | ||
28 | #include <asm/iseries/hv_call_xm.h> | 27 | #include <asm/iseries/hv_call_xm.h> |
29 | 28 | ||
30 | #include "processor_vpd.h" | 29 | #include "processor_vpd.h" |
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c index 617c724c4590..66c77e4f8ec2 100644 --- a/arch/powerpc/platforms/iseries/setup.c +++ b/arch/powerpc/platforms/iseries/setup.c | |||
@@ -81,8 +81,6 @@ static void iSeries_pci_final_fixup(void) { } | |||
81 | #endif | 81 | #endif |
82 | 82 | ||
83 | extern int rd_size; /* Defined in drivers/block/rd.c */ | 83 | extern int rd_size; /* Defined in drivers/block/rd.c */ |
84 | extern unsigned long embedded_sysmap_start; | ||
85 | extern unsigned long embedded_sysmap_end; | ||
86 | 84 | ||
87 | extern unsigned long iSeries_recal_tb; | 85 | extern unsigned long iSeries_recal_tb; |
88 | extern unsigned long iSeries_recal_titan; | 86 | extern unsigned long iSeries_recal_titan; |
@@ -321,11 +319,6 @@ static void __init iSeries_init_early(void) | |||
321 | iSeries_recal_titan = HvCallXm_loadTod(); | 319 | iSeries_recal_titan = HvCallXm_loadTod(); |
322 | 320 | ||
323 | /* | 321 | /* |
324 | * Initialize the hash table management pointers | ||
325 | */ | ||
326 | hpte_init_iSeries(); | ||
327 | |||
328 | /* | ||
329 | * Initialize the DMA/TCE management | 322 | * Initialize the DMA/TCE management |
330 | */ | 323 | */ |
331 | iommu_init_early_iSeries(); | 324 | iommu_init_early_iSeries(); |
@@ -563,16 +556,6 @@ static void __init iSeries_fixup_klimit(void) | |||
563 | if (naca.xRamDisk) | 556 | if (naca.xRamDisk) |
564 | klimit = KERNELBASE + (u64)naca.xRamDisk + | 557 | klimit = KERNELBASE + (u64)naca.xRamDisk + |
565 | (naca.xRamDiskSize * HW_PAGE_SIZE); | 558 | (naca.xRamDiskSize * HW_PAGE_SIZE); |
566 | else { | ||
567 | /* | ||
568 | * No ram disk was included - check and see if there | ||
569 | * was an embedded system map. Change klimit to take | ||
570 | * into account any embedded system map | ||
571 | */ | ||
572 | if (embedded_sysmap_end) | ||
573 | klimit = KERNELBASE + ((embedded_sysmap_end + 4095) & | ||
574 | 0xfffffffffffff000); | ||
575 | } | ||
576 | } | 559 | } |
577 | 560 | ||
578 | static int __init iSeries_src_init(void) | 561 | static int __init iSeries_src_init(void) |
@@ -683,6 +666,8 @@ static int __init iseries_probe(void) | |||
683 | */ | 666 | */ |
684 | virt_irq_max = 255; | 667 | virt_irq_max = 255; |
685 | 668 | ||
669 | hpte_init_iSeries(); | ||
670 | |||
686 | return 1; | 671 | return 1; |
687 | } | 672 | } |
688 | 673 | ||
diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c index 9a4efc0c3b29..f7170ff86dab 100644 --- a/arch/powerpc/platforms/maple/pci.c +++ b/arch/powerpc/platforms/maple/pci.c | |||
@@ -376,9 +376,10 @@ static void __init maple_fixup_phb_resources(void) | |||
376 | unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base; | 376 | unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base; |
377 | hose->io_resource.start += offset; | 377 | hose->io_resource.start += offset; |
378 | hose->io_resource.end += offset; | 378 | hose->io_resource.end += offset; |
379 | printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n", | 379 | printk(KERN_INFO "PCI Host %d, io start: %llx; io end: %llx\n", |
380 | hose->global_number, | 380 | hose->global_number, |
381 | hose->io_resource.start, hose->io_resource.end); | 381 | (unsigned long long)hose->io_resource.start, |
382 | (unsigned long long)hose->io_resource.end); | ||
382 | } | 383 | } |
383 | } | 384 | } |
384 | 385 | ||
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c index a0505ea48a86..4e32a5417fd1 100644 --- a/arch/powerpc/platforms/maple/setup.c +++ b/arch/powerpc/platforms/maple/setup.c | |||
@@ -199,11 +199,6 @@ static void __init maple_init_early(void) | |||
199 | { | 199 | { |
200 | DBG(" -> maple_init_early\n"); | 200 | DBG(" -> maple_init_early\n"); |
201 | 201 | ||
202 | /* Initialize hash table, from now on, we can take hash faults | ||
203 | * and call ioremap | ||
204 | */ | ||
205 | hpte_init_native(); | ||
206 | |||
207 | /* Setup interrupt mapping options */ | 202 | /* Setup interrupt mapping options */ |
208 | ppc64_interrupt_controller = IC_OPEN_PIC; | 203 | ppc64_interrupt_controller = IC_OPEN_PIC; |
209 | 204 | ||
@@ -272,6 +267,8 @@ static int __init maple_probe(void) | |||
272 | */ | 267 | */ |
273 | alloc_dart_table(); | 268 | alloc_dart_table(); |
274 | 269 | ||
270 | hpte_init_native(); | ||
271 | |||
275 | return 1; | 272 | return 1; |
276 | } | 273 | } |
277 | 274 | ||
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index 80035853467b..d524a915aa86 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c | |||
@@ -939,9 +939,10 @@ static int __init add_bridge(struct device_node *dev) | |||
939 | disp_name = "Chaos"; | 939 | disp_name = "Chaos"; |
940 | primary = 0; | 940 | primary = 0; |
941 | } | 941 | } |
942 | printk(KERN_INFO "Found %s PCI host bridge at 0x%08lx. " | 942 | printk(KERN_INFO "Found %s PCI host bridge at 0x%016llx. " |
943 | "Firmware bus number: %d->%d\n", | 943 | "Firmware bus number: %d->%d\n", |
944 | disp_name, rsrc.start, hose->first_busno, hose->last_busno); | 944 | disp_name, (unsigned long long)rsrc.start, hose->first_busno, |
945 | hose->last_busno); | ||
945 | #endif /* CONFIG_PPC32 */ | 946 | #endif /* CONFIG_PPC32 */ |
946 | 947 | ||
947 | DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", | 948 | DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", |
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index 18bf3011d1e3..9f6189af6dd6 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c | |||
@@ -446,7 +446,7 @@ static void __init pmac_pic_probe_oldstyle(void) | |||
446 | 446 | ||
447 | /* Set the handler for the main PIC */ | 447 | /* Set the handler for the main PIC */ |
448 | for ( i = 0; i < max_real_irqs ; i++ ) | 448 | for ( i = 0; i < max_real_irqs ; i++ ) |
449 | irq_desc[i].handler = &pmac_pic; | 449 | irq_desc[i].chip = &pmac_pic; |
450 | 450 | ||
451 | /* Get addresses of first controller if we have a node for it */ | 451 | /* Get addresses of first controller if we have a node for it */ |
452 | BUG_ON(of_address_to_resource(master, 0, &r)); | 452 | BUG_ON(of_address_to_resource(master, 0, &r)); |
@@ -493,7 +493,7 @@ static void __init pmac_pic_probe_oldstyle(void) | |||
493 | /* Setup handlers for secondary controller and hook cascade irq*/ | 493 | /* Setup handlers for secondary controller and hook cascade irq*/ |
494 | if (slave) { | 494 | if (slave) { |
495 | for ( i = max_real_irqs ; i < max_irqs ; i++ ) | 495 | for ( i = max_real_irqs ; i < max_irqs ; i++ ) |
496 | irq_desc[i].handler = &gatwick_pic; | 496 | irq_desc[i].chip = &gatwick_pic; |
497 | setup_irq(irq_cascade, &gatwick_cascade_action); | 497 | setup_irq(irq_cascade, &gatwick_cascade_action); |
498 | } | 498 | } |
499 | printk(KERN_INFO "irq: System has %d possible interrupts\n", max_irqs); | 499 | printk(KERN_INFO "irq: System has %d possible interrupts\n", max_irqs); |
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 9cc7db7a8bdc..89c5775f83be 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c | |||
@@ -600,13 +600,6 @@ pmac_halt(void) | |||
600 | */ | 600 | */ |
601 | static void __init pmac_init_early(void) | 601 | static void __init pmac_init_early(void) |
602 | { | 602 | { |
603 | #ifdef CONFIG_PPC64 | ||
604 | /* Initialize hash table, from now on, we can take hash faults | ||
605 | * and call ioremap | ||
606 | */ | ||
607 | hpte_init_native(); | ||
608 | #endif | ||
609 | |||
610 | /* Enable early btext debug if requested */ | 603 | /* Enable early btext debug if requested */ |
611 | if (strstr(cmd_line, "btextdbg")) { | 604 | if (strstr(cmd_line, "btextdbg")) { |
612 | udbg_adb_init_early(); | 605 | udbg_adb_init_early(); |
@@ -683,6 +676,8 @@ static int __init pmac_probe(void) | |||
683 | * part of the cacheable linar mapping | 676 | * part of the cacheable linar mapping |
684 | */ | 677 | */ |
685 | alloc_dart_table(); | 678 | alloc_dart_table(); |
679 | |||
680 | hpte_init_native(); | ||
686 | #endif | 681 | #endif |
687 | 682 | ||
688 | #ifdef CONFIG_PPC32 | 683 | #ifdef CONFIG_PPC32 |
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index d03a8b078f9d..8cfb5706790e 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c | |||
@@ -92,6 +92,15 @@ static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages) | |||
92 | *(tcep++) = 0; | 92 | *(tcep++) = 0; |
93 | } | 93 | } |
94 | 94 | ||
95 | static unsigned long tce_get_pseries(struct iommu_table *tbl, long index) | ||
96 | { | ||
97 | u64 *tcep; | ||
98 | |||
99 | index <<= TCE_PAGE_FACTOR; | ||
100 | tcep = ((u64 *)tbl->it_base) + index; | ||
101 | |||
102 | return *tcep; | ||
103 | } | ||
95 | 104 | ||
96 | static void tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum, | 105 | static void tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum, |
97 | long npages, unsigned long uaddr, | 106 | long npages, unsigned long uaddr, |
@@ -235,6 +244,25 @@ static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long n | |||
235 | } | 244 | } |
236 | } | 245 | } |
237 | 246 | ||
247 | static unsigned long tce_get_pSeriesLP(struct iommu_table *tbl, long tcenum) | ||
248 | { | ||
249 | u64 rc; | ||
250 | unsigned long tce_ret; | ||
251 | |||
252 | tcenum <<= TCE_PAGE_FACTOR; | ||
253 | rc = plpar_tce_get((u64)tbl->it_index, (u64)tcenum << 12, &tce_ret); | ||
254 | |||
255 | if (rc && printk_ratelimit()) { | ||
256 | printk("tce_get_pSeriesLP: plpar_tce_get failed. rc=%ld\n", | ||
257 | rc); | ||
258 | printk("\tindex = 0x%lx\n", (u64)tbl->it_index); | ||
259 | printk("\ttcenum = 0x%lx\n", (u64)tcenum); | ||
260 | show_stack(current, (unsigned long *)__get_SP()); | ||
261 | } | ||
262 | |||
263 | return tce_ret; | ||
264 | } | ||
265 | |||
238 | static void iommu_table_setparms(struct pci_controller *phb, | 266 | static void iommu_table_setparms(struct pci_controller *phb, |
239 | struct device_node *dn, | 267 | struct device_node *dn, |
240 | struct iommu_table *tbl) | 268 | struct iommu_table *tbl) |
@@ -254,7 +282,10 @@ static void iommu_table_setparms(struct pci_controller *phb, | |||
254 | } | 282 | } |
255 | 283 | ||
256 | tbl->it_base = (unsigned long)__va(*basep); | 284 | tbl->it_base = (unsigned long)__va(*basep); |
285 | |||
286 | #ifndef CONFIG_CRASH_DUMP | ||
257 | memset((void *)tbl->it_base, 0, *sizep); | 287 | memset((void *)tbl->it_base, 0, *sizep); |
288 | #endif | ||
258 | 289 | ||
259 | tbl->it_busno = phb->bus->number; | 290 | tbl->it_busno = phb->bus->number; |
260 | 291 | ||
@@ -560,11 +591,13 @@ void iommu_init_early_pSeries(void) | |||
560 | ppc_md.tce_build = tce_build_pSeriesLP; | 591 | ppc_md.tce_build = tce_build_pSeriesLP; |
561 | ppc_md.tce_free = tce_free_pSeriesLP; | 592 | ppc_md.tce_free = tce_free_pSeriesLP; |
562 | } | 593 | } |
594 | ppc_md.tce_get = tce_get_pSeriesLP; | ||
563 | ppc_md.iommu_bus_setup = iommu_bus_setup_pSeriesLP; | 595 | ppc_md.iommu_bus_setup = iommu_bus_setup_pSeriesLP; |
564 | ppc_md.iommu_dev_setup = iommu_dev_setup_pSeriesLP; | 596 | ppc_md.iommu_dev_setup = iommu_dev_setup_pSeriesLP; |
565 | } else { | 597 | } else { |
566 | ppc_md.tce_build = tce_build_pSeries; | 598 | ppc_md.tce_build = tce_build_pSeries; |
567 | ppc_md.tce_free = tce_free_pSeries; | 599 | ppc_md.tce_free = tce_free_pSeries; |
600 | ppc_md.tce_get = tce_get_pseries; | ||
568 | ppc_md.iommu_bus_setup = iommu_bus_setup_pSeries; | 601 | ppc_md.iommu_bus_setup = iommu_bus_setup_pSeries; |
569 | ppc_md.iommu_dev_setup = iommu_dev_setup_pSeries; | 602 | ppc_md.iommu_dev_setup = iommu_dev_setup_pSeries; |
570 | } | 603 | } |
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 634b7d06d3cc..27480705996f 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c | |||
@@ -513,7 +513,7 @@ void pSeries_lpar_flush_hash_range(unsigned long number, int local) | |||
513 | spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags); | 513 | spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags); |
514 | } | 514 | } |
515 | 515 | ||
516 | void hpte_init_lpar(void) | 516 | void __init hpte_init_lpar(void) |
517 | { | 517 | { |
518 | ppc_md.hpte_invalidate = pSeries_lpar_hpte_invalidate; | 518 | ppc_md.hpte_invalidate = pSeries_lpar_hpte_invalidate; |
519 | ppc_md.hpte_updatepp = pSeries_lpar_hpte_updatepp; | 519 | ppc_md.hpte_updatepp = pSeries_lpar_hpte_updatepp; |
@@ -522,6 +522,4 @@ void hpte_init_lpar(void) | |||
522 | ppc_md.hpte_remove = pSeries_lpar_hpte_remove; | 522 | ppc_md.hpte_remove = pSeries_lpar_hpte_remove; |
523 | ppc_md.flush_hash_range = pSeries_lpar_flush_hash_range; | 523 | ppc_md.flush_hash_range = pSeries_lpar_flush_hash_range; |
524 | ppc_md.hpte_clear_all = pSeries_lpar_hptab_clear; | 524 | ppc_md.hpte_clear_all = pSeries_lpar_hptab_clear; |
525 | |||
526 | htab_finish_init(); | ||
527 | } | 525 | } |
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 1e28518c6121..b3197ff156c6 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c | |||
@@ -322,11 +322,6 @@ static void __init pSeries_init_early(void) | |||
322 | DBG(" -> pSeries_init_early()\n"); | 322 | DBG(" -> pSeries_init_early()\n"); |
323 | 323 | ||
324 | fw_feature_init(); | 324 | fw_feature_init(); |
325 | |||
326 | if (firmware_has_feature(FW_FEATURE_LPAR)) | ||
327 | hpte_init_lpar(); | ||
328 | else | ||
329 | hpte_init_native(); | ||
330 | 325 | ||
331 | if (firmware_has_feature(FW_FEATURE_LPAR)) | 326 | if (firmware_has_feature(FW_FEATURE_LPAR)) |
332 | find_udbg_vterm(); | 327 | find_udbg_vterm(); |
@@ -384,6 +379,11 @@ static int __init pSeries_probe_hypertas(unsigned long node, | |||
384 | if (of_get_flat_dt_prop(node, "ibm,hypertas-functions", NULL) != NULL) | 379 | if (of_get_flat_dt_prop(node, "ibm,hypertas-functions", NULL) != NULL) |
385 | powerpc_firmware_features |= FW_FEATURE_LPAR; | 380 | powerpc_firmware_features |= FW_FEATURE_LPAR; |
386 | 381 | ||
382 | if (firmware_has_feature(FW_FEATURE_LPAR)) | ||
383 | hpte_init_lpar(); | ||
384 | else | ||
385 | hpte_init_native(); | ||
386 | |||
387 | return 1; | 387 | return 1; |
388 | } | 388 | } |
389 | 389 | ||
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c index b14f9b5c114e..19c03dd43000 100644 --- a/arch/powerpc/platforms/pseries/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c | |||
@@ -238,7 +238,7 @@ static int get_irq_server(unsigned int irq) | |||
238 | { | 238 | { |
239 | unsigned int server; | 239 | unsigned int server; |
240 | /* For the moment only implement delivery to all cpus or one cpu */ | 240 | /* For the moment only implement delivery to all cpus or one cpu */ |
241 | cpumask_t cpumask = irq_affinity[irq]; | 241 | cpumask_t cpumask = irq_desc[irq].affinity; |
242 | cpumask_t tmp = CPU_MASK_NONE; | 242 | cpumask_t tmp = CPU_MASK_NONE; |
243 | 243 | ||
244 | if (!distribute_irqs) | 244 | if (!distribute_irqs) |
@@ -558,7 +558,7 @@ nextnode: | |||
558 | } | 558 | } |
559 | 559 | ||
560 | for (i = irq_offset_value(); i < NR_IRQS; ++i) | 560 | for (i = irq_offset_value(); i < NR_IRQS; ++i) |
561 | get_irq_desc(i)->handler = &xics_pic; | 561 | get_irq_desc(i)->chip = &xics_pic; |
562 | 562 | ||
563 | xics_setup_cpu(); | 563 | xics_setup_cpu(); |
564 | 564 | ||
@@ -701,9 +701,9 @@ void xics_migrate_irqs_away(void) | |||
701 | continue; | 701 | continue; |
702 | 702 | ||
703 | /* We only need to migrate enabled IRQS */ | 703 | /* We only need to migrate enabled IRQS */ |
704 | if (desc == NULL || desc->handler == NULL | 704 | if (desc == NULL || desc->chip == NULL |
705 | || desc->action == NULL | 705 | || desc->action == NULL |
706 | || desc->handler->set_affinity == NULL) | 706 | || desc->chip->set_affinity == NULL) |
707 | continue; | 707 | continue; |
708 | 708 | ||
709 | spin_lock_irqsave(&desc->lock, flags); | 709 | spin_lock_irqsave(&desc->lock, flags); |
@@ -728,8 +728,8 @@ void xics_migrate_irqs_away(void) | |||
728 | virq, cpu); | 728 | virq, cpu); |
729 | 729 | ||
730 | /* Reset affinity to all cpus */ | 730 | /* Reset affinity to all cpus */ |
731 | desc->handler->set_affinity(virq, CPU_MASK_ALL); | 731 | desc->chip->set_affinity(virq, CPU_MASK_ALL); |
732 | irq_affinity[virq] = CPU_MASK_ALL; | 732 | irq_desc[irq].affinity = CPU_MASK_ALL; |
733 | unlock: | 733 | unlock: |
734 | spin_unlock_irqrestore(&desc->lock, flags); | 734 | spin_unlock_irqrestore(&desc->lock, flags); |
735 | } | 735 | } |
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index cef95b023730..054bd8b41ef5 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile | |||
@@ -12,3 +12,5 @@ obj-$(CONFIG_U3_DART) += dart_iommu.o | |||
12 | obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o | 12 | obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o |
13 | obj-$(CONFIG_PPC_83xx) += ipic.o | 13 | obj-$(CONFIG_PPC_83xx) += ipic.o |
14 | obj-$(CONFIG_FSL_SOC) += fsl_soc.o | 14 | obj-$(CONFIG_FSL_SOC) += fsl_soc.o |
15 | obj-$(CONFIG_PPC_TODC) += todc.o | ||
16 | obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o | ||
diff --git a/arch/powerpc/sysdev/dart.h b/arch/powerpc/sysdev/dart.h index c2d05763ccbe..1c8817c4835e 100644 --- a/arch/powerpc/sysdev/dart.h +++ b/arch/powerpc/sysdev/dart.h | |||
@@ -47,8 +47,12 @@ | |||
47 | /* U4 registers */ | 47 | /* U4 registers */ |
48 | #define DART_BASE_U4_BASE_MASK 0xffffff | 48 | #define DART_BASE_U4_BASE_MASK 0xffffff |
49 | #define DART_BASE_U4_BASE_SHIFT 0 | 49 | #define DART_BASE_U4_BASE_SHIFT 0 |
50 | #define DART_CNTL_U4_FLUSHTLB 0x20000000 | ||
51 | #define DART_CNTL_U4_ENABLE 0x80000000 | 50 | #define DART_CNTL_U4_ENABLE 0x80000000 |
51 | #define DART_CNTL_U4_IONE 0x40000000 | ||
52 | #define DART_CNTL_U4_FLUSHTLB 0x20000000 | ||
53 | #define DART_CNTL_U4_IDLE 0x10000000 | ||
54 | #define DART_CNTL_U4_PAR_EN 0x08000000 | ||
55 | #define DART_CNTL_U4_IONE_MASK 0x07ffffff | ||
52 | #define DART_SIZE_U4_SIZE_MASK 0x1fff | 56 | #define DART_SIZE_U4_SIZE_MASK 0x1fff |
53 | #define DART_SIZE_U4_SIZE_SHIFT 0 | 57 | #define DART_SIZE_U4_SIZE_SHIFT 0 |
54 | 58 | ||
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c index 6232091cc72b..7c7f34ce4986 100644 --- a/arch/powerpc/sysdev/dart_iommu.c +++ b/arch/powerpc/sysdev/dart_iommu.c | |||
@@ -101,8 +101,8 @@ retry: | |||
101 | if (l == (1L << limit)) { | 101 | if (l == (1L << limit)) { |
102 | if (limit < 4) { | 102 | if (limit < 4) { |
103 | limit++; | 103 | limit++; |
104 | reg = DART_IN(DART_CNTL); | 104 | reg = DART_IN(DART_CNTL); |
105 | reg &= ~inv_bit; | 105 | reg &= ~inv_bit; |
106 | DART_OUT(DART_CNTL, reg); | 106 | DART_OUT(DART_CNTL, reg); |
107 | goto retry; | 107 | goto retry; |
108 | } else | 108 | } else |
@@ -111,11 +111,39 @@ retry: | |||
111 | } | 111 | } |
112 | } | 112 | } |
113 | 113 | ||
114 | static inline void dart_tlb_invalidate_one(unsigned long bus_rpn) | ||
115 | { | ||
116 | unsigned int reg; | ||
117 | unsigned int l, limit; | ||
118 | |||
119 | reg = DART_CNTL_U4_ENABLE | DART_CNTL_U4_IONE | | ||
120 | (bus_rpn & DART_CNTL_U4_IONE_MASK); | ||
121 | DART_OUT(DART_CNTL, reg); | ||
122 | |||
123 | limit = 0; | ||
124 | wait_more: | ||
125 | l = 0; | ||
126 | while ((DART_IN(DART_CNTL) & DART_CNTL_U4_IONE) && l < (1L << limit)) { | ||
127 | rmb(); | ||
128 | l++; | ||
129 | } | ||
130 | |||
131 | if (l == (1L << limit)) { | ||
132 | if (limit < 4) { | ||
133 | limit++; | ||
134 | goto wait_more; | ||
135 | } else | ||
136 | panic("DART: TLB did not flush after waiting a long " | ||
137 | "time. Buggy U4 ?"); | ||
138 | } | ||
139 | } | ||
140 | |||
114 | static void dart_flush(struct iommu_table *tbl) | 141 | static void dart_flush(struct iommu_table *tbl) |
115 | { | 142 | { |
116 | if (dart_dirty) | 143 | if (dart_dirty) { |
117 | dart_tlb_invalidate_all(); | 144 | dart_tlb_invalidate_all(); |
118 | dart_dirty = 0; | 145 | dart_dirty = 0; |
146 | } | ||
119 | } | 147 | } |
120 | 148 | ||
121 | static void dart_build(struct iommu_table *tbl, long index, | 149 | static void dart_build(struct iommu_table *tbl, long index, |
@@ -124,6 +152,7 @@ static void dart_build(struct iommu_table *tbl, long index, | |||
124 | { | 152 | { |
125 | unsigned int *dp; | 153 | unsigned int *dp; |
126 | unsigned int rpn; | 154 | unsigned int rpn; |
155 | long l; | ||
127 | 156 | ||
128 | DBG("dart: build at: %lx, %lx, addr: %x\n", index, npages, uaddr); | 157 | DBG("dart: build at: %lx, %lx, addr: %x\n", index, npages, uaddr); |
129 | 158 | ||
@@ -135,7 +164,8 @@ static void dart_build(struct iommu_table *tbl, long index, | |||
135 | /* On U3, all memory is contigous, so we can move this | 164 | /* On U3, all memory is contigous, so we can move this |
136 | * out of the loop. | 165 | * out of the loop. |
137 | */ | 166 | */ |
138 | while (npages--) { | 167 | l = npages; |
168 | while (l--) { | ||
139 | rpn = virt_to_abs(uaddr) >> DART_PAGE_SHIFT; | 169 | rpn = virt_to_abs(uaddr) >> DART_PAGE_SHIFT; |
140 | 170 | ||
141 | *(dp++) = DARTMAP_VALID | (rpn & DARTMAP_RPNMASK); | 171 | *(dp++) = DARTMAP_VALID | (rpn & DARTMAP_RPNMASK); |
@@ -143,7 +173,14 @@ static void dart_build(struct iommu_table *tbl, long index, | |||
143 | uaddr += DART_PAGE_SIZE; | 173 | uaddr += DART_PAGE_SIZE; |
144 | } | 174 | } |
145 | 175 | ||
146 | dart_dirty = 1; | 176 | if (dart_is_u4) { |
177 | rpn = index; | ||
178 | mb(); /* make sure all updates have reached memory */ | ||
179 | while (npages--) | ||
180 | dart_tlb_invalidate_one(rpn++); | ||
181 | } else { | ||
182 | dart_dirty = 1; | ||
183 | } | ||
147 | } | 184 | } |
148 | 185 | ||
149 | 186 | ||
diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c index b7ac32fdd776..2bff30f6d635 100644 --- a/arch/powerpc/sysdev/i8259.c +++ b/arch/powerpc/sysdev/i8259.c | |||
@@ -208,7 +208,7 @@ void __init i8259_init(unsigned long intack_addr, int offset) | |||
208 | spin_unlock_irqrestore(&i8259_lock, flags); | 208 | spin_unlock_irqrestore(&i8259_lock, flags); |
209 | 209 | ||
210 | for (i = 0; i < NUM_ISA_INTERRUPTS; ++i) | 210 | for (i = 0; i < NUM_ISA_INTERRUPTS; ++i) |
211 | irq_desc[offset + i].handler = &i8259_pic; | 211 | irq_desc[offset + i].chip = &i8259_pic; |
212 | 212 | ||
213 | /* reserve our resources */ | 213 | /* reserve our resources */ |
214 | setup_irq(offset + 2, &i8259_irqaction); | 214 | setup_irq(offset + 2, &i8259_irqaction); |
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c index 8f01e0f1d847..46801f5ec03f 100644 --- a/arch/powerpc/sysdev/ipic.c +++ b/arch/powerpc/sysdev/ipic.c | |||
@@ -472,7 +472,7 @@ void __init ipic_init(phys_addr_t phys_addr, | |||
472 | ipic_write(primary_ipic->regs, IPIC_SEMSR, temp); | 472 | ipic_write(primary_ipic->regs, IPIC_SEMSR, temp); |
473 | 473 | ||
474 | for (i = 0 ; i < NR_IPIC_INTS ; i++) { | 474 | for (i = 0 ; i < NR_IPIC_INTS ; i++) { |
475 | irq_desc[i+irq_offset].handler = &ipic; | 475 | irq_desc[i+irq_offset].chip = &ipic; |
476 | irq_desc[i+irq_offset].status = IRQ_LEVEL; | 476 | irq_desc[i+irq_offset].status = IRQ_LEVEL; |
477 | } | 477 | } |
478 | 478 | ||
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index bffe50d02c99..28df9c827ca6 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c | |||
@@ -379,14 +379,14 @@ static inline u32 mpic_physmask(u32 cpumask) | |||
379 | /* Get the mpic structure from the IPI number */ | 379 | /* Get the mpic structure from the IPI number */ |
380 | static inline struct mpic * mpic_from_ipi(unsigned int ipi) | 380 | static inline struct mpic * mpic_from_ipi(unsigned int ipi) |
381 | { | 381 | { |
382 | return container_of(irq_desc[ipi].handler, struct mpic, hc_ipi); | 382 | return container_of(irq_desc[ipi].chip, struct mpic, hc_ipi); |
383 | } | 383 | } |
384 | #endif | 384 | #endif |
385 | 385 | ||
386 | /* Get the mpic structure from the irq number */ | 386 | /* Get the mpic structure from the irq number */ |
387 | static inline struct mpic * mpic_from_irq(unsigned int irq) | 387 | static inline struct mpic * mpic_from_irq(unsigned int irq) |
388 | { | 388 | { |
389 | return container_of(irq_desc[irq].handler, struct mpic, hc_irq); | 389 | return container_of(irq_desc[irq].chip, struct mpic, hc_irq); |
390 | } | 390 | } |
391 | 391 | ||
392 | /* Send an EOI */ | 392 | /* Send an EOI */ |
@@ -752,7 +752,7 @@ void __init mpic_init(struct mpic *mpic) | |||
752 | if (!(mpic->flags & MPIC_PRIMARY)) | 752 | if (!(mpic->flags & MPIC_PRIMARY)) |
753 | continue; | 753 | continue; |
754 | irq_desc[mpic->ipi_offset+i].status |= IRQ_PER_CPU; | 754 | irq_desc[mpic->ipi_offset+i].status |= IRQ_PER_CPU; |
755 | irq_desc[mpic->ipi_offset+i].handler = &mpic->hc_ipi; | 755 | irq_desc[mpic->ipi_offset+i].chip = &mpic->hc_ipi; |
756 | #endif /* CONFIG_SMP */ | 756 | #endif /* CONFIG_SMP */ |
757 | } | 757 | } |
758 | 758 | ||
@@ -813,7 +813,7 @@ void __init mpic_init(struct mpic *mpic) | |||
813 | /* init linux descriptors */ | 813 | /* init linux descriptors */ |
814 | if (i < mpic->irq_count) { | 814 | if (i < mpic->irq_count) { |
815 | irq_desc[mpic->irq_offset+i].status = level ? IRQ_LEVEL : 0; | 815 | irq_desc[mpic->irq_offset+i].status = level ? IRQ_LEVEL : 0; |
816 | irq_desc[mpic->irq_offset+i].handler = &mpic->hc_irq; | 816 | irq_desc[mpic->irq_offset+i].chip = &mpic->hc_irq; |
817 | } | 817 | } |
818 | } | 818 | } |
819 | 819 | ||
@@ -906,7 +906,7 @@ void mpic_setup_this_cpu(void) | |||
906 | /* let the mpic know we want intrs. default affinity is 0xffffffff | 906 | /* let the mpic know we want intrs. default affinity is 0xffffffff |
907 | * until changed via /proc. That's how it's done on x86. If we want | 907 | * until changed via /proc. That's how it's done on x86. If we want |
908 | * it differently, then we should make sure we also change the default | 908 | * it differently, then we should make sure we also change the default |
909 | * values of irq_affinity in irq.c. | 909 | * values of irq_desc[].affinity in irq.c. |
910 | */ | 910 | */ |
911 | if (distribute_irqs) { | 911 | if (distribute_irqs) { |
912 | for (i = 0; i < mpic->num_sources ; i++) | 912 | for (i = 0; i < mpic->num_sources ; i++) |
diff --git a/arch/powerpc/sysdev/todc.c b/arch/powerpc/sysdev/todc.c new file mode 100644 index 000000000000..0a65980efb50 --- /dev/null +++ b/arch/powerpc/sysdev/todc.c | |||
@@ -0,0 +1,392 @@ | |||
1 | /* | ||
2 | * Time of Day Clock support for the M48T35, M48T37, M48T59, and MC146818 | ||
3 | * Real Time Clocks/Timekeepers. | ||
4 | * | ||
5 | * Author: Mark A. Greer <mgreer@mvista.com> | ||
6 | * | ||
7 | * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under | ||
8 | * the terms of the GNU General Public License version 2. This program | ||
9 | * is licensed "as is" without any warranty of any kind, whether express | ||
10 | * or implied. | ||
11 | */ | ||
12 | #include <linux/errno.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/time.h> | ||
16 | #include <linux/timex.h> | ||
17 | #include <linux/bcd.h> | ||
18 | #include <linux/mc146818rtc.h> | ||
19 | |||
20 | #include <asm/machdep.h> | ||
21 | #include <asm/io.h> | ||
22 | #include <asm/time.h> | ||
23 | #include <asm/todc.h> | ||
24 | |||
25 | /* | ||
26 | * Depending on the hardware on your board and your board design, the | ||
27 | * RTC/NVRAM may be accessed either directly (like normal memory) or via | ||
28 | * address/data registers. If your board uses the direct method, set | ||
29 | * 'nvram_data' to the base address of your nvram and leave 'nvram_as0' and | ||
30 | * 'nvram_as1' NULL. If your board uses address/data regs to access nvram, | ||
31 | * set 'nvram_as0' to the address of the lower byte, set 'nvram_as1' to the | ||
32 | * address of the upper byte (leave NULL if using mc146818), and set | ||
33 | * 'nvram_data' to the address of the 8-bit data register. | ||
34 | * | ||
35 | * Note: Even though the documentation for the various RTC chips say that it | ||
36 | * take up to a second before it starts updating once the 'R' bit is | ||
37 | * cleared, they always seem to update even though we bang on it many | ||
38 | * times a second. This is true, except for the Dallas Semi 1746/1747 | ||
39 | * (possibly others). Those chips seem to have a real problem whenever | ||
40 | * we set the 'R' bit before reading them, they basically stop counting. | ||
41 | * --MAG | ||
42 | */ | ||
43 | |||
44 | /* | ||
45 | * 'todc_info' should be initialized in your *_setup.c file to | ||
46 | * point to a fully initialized 'todc_info_t' structure. | ||
47 | * This structure holds all the register offsets for your particular | ||
48 | * TODC/RTC chip. | ||
49 | * TODC_ALLOC()/TODC_INIT() will allocate and initialize this table for you. | ||
50 | */ | ||
51 | |||
52 | #ifdef RTC_FREQ_SELECT | ||
53 | #undef RTC_FREQ_SELECT | ||
54 | #define RTC_FREQ_SELECT control_b /* Register A */ | ||
55 | #endif | ||
56 | |||
57 | #ifdef RTC_CONTROL | ||
58 | #undef RTC_CONTROL | ||
59 | #define RTC_CONTROL control_a /* Register B */ | ||
60 | #endif | ||
61 | |||
62 | #ifdef RTC_INTR_FLAGS | ||
63 | #undef RTC_INTR_FLAGS | ||
64 | #define RTC_INTR_FLAGS watchdog /* Register C */ | ||
65 | #endif | ||
66 | |||
67 | #ifdef RTC_VALID | ||
68 | #undef RTC_VALID | ||
69 | #define RTC_VALID interrupts /* Register D */ | ||
70 | #endif | ||
71 | |||
72 | /* Access routines when RTC accessed directly (like normal memory) */ | ||
73 | u_char | ||
74 | todc_direct_read_val(int addr) | ||
75 | { | ||
76 | return readb((void __iomem *)(todc_info->nvram_data + addr)); | ||
77 | } | ||
78 | |||
79 | void | ||
80 | todc_direct_write_val(int addr, unsigned char val) | ||
81 | { | ||
82 | writeb(val, (void __iomem *)(todc_info->nvram_data + addr)); | ||
83 | return; | ||
84 | } | ||
85 | |||
86 | /* Access routines for accessing m48txx type chips via addr/data regs */ | ||
87 | u_char | ||
88 | todc_m48txx_read_val(int addr) | ||
89 | { | ||
90 | outb(addr, todc_info->nvram_as0); | ||
91 | outb(addr>>todc_info->as0_bits, todc_info->nvram_as1); | ||
92 | return inb(todc_info->nvram_data); | ||
93 | } | ||
94 | |||
95 | void | ||
96 | todc_m48txx_write_val(int addr, unsigned char val) | ||
97 | { | ||
98 | outb(addr, todc_info->nvram_as0); | ||
99 | outb(addr>>todc_info->as0_bits, todc_info->nvram_as1); | ||
100 | outb(val, todc_info->nvram_data); | ||
101 | return; | ||
102 | } | ||
103 | |||
104 | /* Access routines for accessing mc146818 type chips via addr/data regs */ | ||
105 | u_char | ||
106 | todc_mc146818_read_val(int addr) | ||
107 | { | ||
108 | outb_p(addr, todc_info->nvram_as0); | ||
109 | return inb_p(todc_info->nvram_data); | ||
110 | } | ||
111 | |||
112 | void | ||
113 | todc_mc146818_write_val(int addr, unsigned char val) | ||
114 | { | ||
115 | outb_p(addr, todc_info->nvram_as0); | ||
116 | outb_p(val, todc_info->nvram_data); | ||
117 | } | ||
118 | |||
119 | |||
120 | /* | ||
121 | * Routines to make RTC chips with NVRAM buried behind an addr/data pair | ||
122 | * have the NVRAM and clock regs appear at the same level. | ||
123 | * The NVRAM will appear to start at addr 0 and the clock regs will appear | ||
124 | * to start immediately after the NVRAM (actually, start at offset | ||
125 | * todc_info->nvram_size). | ||
126 | */ | ||
127 | static inline u_char | ||
128 | todc_read_val(int addr) | ||
129 | { | ||
130 | u_char val; | ||
131 | |||
132 | if (todc_info->sw_flags & TODC_FLAG_2_LEVEL_NVRAM) { | ||
133 | if (addr < todc_info->nvram_size) { /* NVRAM */ | ||
134 | ppc_md.rtc_write_val(todc_info->nvram_addr_reg, addr); | ||
135 | val = ppc_md.rtc_read_val(todc_info->nvram_data_reg); | ||
136 | } else { /* Clock Reg */ | ||
137 | addr -= todc_info->nvram_size; | ||
138 | val = ppc_md.rtc_read_val(addr); | ||
139 | } | ||
140 | } else | ||
141 | val = ppc_md.rtc_read_val(addr); | ||
142 | |||
143 | return val; | ||
144 | } | ||
145 | |||
146 | static inline void | ||
147 | todc_write_val(int addr, u_char val) | ||
148 | { | ||
149 | if (todc_info->sw_flags & TODC_FLAG_2_LEVEL_NVRAM) { | ||
150 | if (addr < todc_info->nvram_size) { /* NVRAM */ | ||
151 | ppc_md.rtc_write_val(todc_info->nvram_addr_reg, addr); | ||
152 | ppc_md.rtc_write_val(todc_info->nvram_data_reg, val); | ||
153 | } else { /* Clock Reg */ | ||
154 | addr -= todc_info->nvram_size; | ||
155 | ppc_md.rtc_write_val(addr, val); | ||
156 | } | ||
157 | } else | ||
158 | ppc_md.rtc_write_val(addr, val); | ||
159 | } | ||
160 | |||
161 | /* | ||
162 | * TODC routines | ||
163 | * | ||
164 | * There is some ugly stuff in that there are assumptions for the mc146818. | ||
165 | * | ||
166 | * Assumptions: | ||
167 | * - todc_info->control_a has the offset as mc146818 Register B reg | ||
168 | * - todc_info->control_b has the offset as mc146818 Register A reg | ||
169 | * - m48txx control reg's write enable or 'W' bit is same as | ||
170 | * mc146818 Register B 'SET' bit (i.e., 0x80) | ||
171 | * | ||
172 | * These assumptions were made to make the code simpler. | ||
173 | */ | ||
174 | long __init | ||
175 | todc_time_init(void) | ||
176 | { | ||
177 | u_char cntl_b; | ||
178 | |||
179 | if (!ppc_md.rtc_read_val) | ||
180 | ppc_md.rtc_read_val = ppc_md.nvram_read_val; | ||
181 | if (!ppc_md.rtc_write_val) | ||
182 | ppc_md.rtc_write_val = ppc_md.nvram_write_val; | ||
183 | |||
184 | cntl_b = todc_read_val(todc_info->control_b); | ||
185 | |||
186 | if (todc_info->rtc_type == TODC_TYPE_MC146818) { | ||
187 | if ((cntl_b & 0x70) != 0x20) { | ||
188 | printk(KERN_INFO "TODC real-time-clock was stopped." | ||
189 | " Now starting..."); | ||
190 | cntl_b &= ~0x70; | ||
191 | cntl_b |= 0x20; | ||
192 | } | ||
193 | |||
194 | todc_write_val(todc_info->control_b, cntl_b); | ||
195 | } else if (todc_info->rtc_type == TODC_TYPE_DS17285) { | ||
196 | u_char mode; | ||
197 | |||
198 | mode = todc_read_val(TODC_TYPE_DS17285_CNTL_A); | ||
199 | /* Make sure countdown clear is not set */ | ||
200 | mode &= ~0x40; | ||
201 | /* Enable oscillator, extended register set */ | ||
202 | mode |= 0x30; | ||
203 | todc_write_val(TODC_TYPE_DS17285_CNTL_A, mode); | ||
204 | |||
205 | } else if (todc_info->rtc_type == TODC_TYPE_DS1501) { | ||
206 | u_char month; | ||
207 | |||
208 | todc_info->enable_read = TODC_DS1501_CNTL_B_TE; | ||
209 | todc_info->enable_write = TODC_DS1501_CNTL_B_TE; | ||
210 | |||
211 | month = todc_read_val(todc_info->month); | ||
212 | |||
213 | if ((month & 0x80) == 0x80) { | ||
214 | printk(KERN_INFO "TODC %s %s\n", | ||
215 | "real-time-clock was stopped.", | ||
216 | "Now starting..."); | ||
217 | month &= ~0x80; | ||
218 | todc_write_val(todc_info->month, month); | ||
219 | } | ||
220 | |||
221 | cntl_b &= ~TODC_DS1501_CNTL_B_TE; | ||
222 | todc_write_val(todc_info->control_b, cntl_b); | ||
223 | } else { /* must be a m48txx type */ | ||
224 | u_char cntl_a; | ||
225 | |||
226 | todc_info->enable_read = TODC_MK48TXX_CNTL_A_R; | ||
227 | todc_info->enable_write = TODC_MK48TXX_CNTL_A_W; | ||
228 | |||
229 | cntl_a = todc_read_val(todc_info->control_a); | ||
230 | |||
231 | /* Check & clear STOP bit in control B register */ | ||
232 | if (cntl_b & TODC_MK48TXX_DAY_CB) { | ||
233 | printk(KERN_INFO "TODC %s %s\n", | ||
234 | "real-time-clock was stopped.", | ||
235 | "Now starting..."); | ||
236 | |||
237 | cntl_a |= todc_info->enable_write; | ||
238 | cntl_b &= ~TODC_MK48TXX_DAY_CB;/* Start Oscil */ | ||
239 | |||
240 | todc_write_val(todc_info->control_a, cntl_a); | ||
241 | todc_write_val(todc_info->control_b, cntl_b); | ||
242 | } | ||
243 | |||
244 | /* Make sure READ & WRITE bits are cleared. */ | ||
245 | cntl_a &= ~(todc_info->enable_write | todc_info->enable_read); | ||
246 | todc_write_val(todc_info->control_a, cntl_a); | ||
247 | } | ||
248 | |||
249 | return 0; | ||
250 | } | ||
251 | |||
252 | /* | ||
253 | * There is some ugly stuff in that there are assumptions that for a mc146818, | ||
254 | * the todc_info->control_a has the offset of the mc146818 Register B reg and | ||
255 | * that the register'ss 'SET' bit is the same as the m48txx's write enable | ||
256 | * bit in the control register of the m48txx (i.e., 0x80). | ||
257 | * | ||
258 | * It was done to make the code look simpler. | ||
259 | */ | ||
260 | void | ||
261 | todc_get_rtc_time(struct rtc_time *tm) | ||
262 | { | ||
263 | uint year = 0, mon = 0, mday = 0, hour = 0, min = 0, sec = 0; | ||
264 | uint limit, i; | ||
265 | u_char save_control, uip = 0; | ||
266 | extern void GregorianDay(struct rtc_time *); | ||
267 | |||
268 | spin_lock(&rtc_lock); | ||
269 | save_control = todc_read_val(todc_info->control_a); | ||
270 | |||
271 | if (todc_info->rtc_type != TODC_TYPE_MC146818) { | ||
272 | limit = 1; | ||
273 | |||
274 | switch (todc_info->rtc_type) { | ||
275 | case TODC_TYPE_DS1553: | ||
276 | case TODC_TYPE_DS1557: | ||
277 | case TODC_TYPE_DS1743: | ||
278 | case TODC_TYPE_DS1746: /* XXXX BAD HACK -> FIX */ | ||
279 | case TODC_TYPE_DS1747: | ||
280 | case TODC_TYPE_DS17285: | ||
281 | break; | ||
282 | default: | ||
283 | todc_write_val(todc_info->control_a, | ||
284 | (save_control | todc_info->enable_read)); | ||
285 | } | ||
286 | } else | ||
287 | limit = 100000000; | ||
288 | |||
289 | for (i=0; i<limit; i++) { | ||
290 | if (todc_info->rtc_type == TODC_TYPE_MC146818) | ||
291 | uip = todc_read_val(todc_info->RTC_FREQ_SELECT); | ||
292 | |||
293 | sec = todc_read_val(todc_info->seconds) & 0x7f; | ||
294 | min = todc_read_val(todc_info->minutes) & 0x7f; | ||
295 | hour = todc_read_val(todc_info->hours) & 0x3f; | ||
296 | mday = todc_read_val(todc_info->day_of_month) & 0x3f; | ||
297 | mon = todc_read_val(todc_info->month) & 0x1f; | ||
298 | year = todc_read_val(todc_info->year) & 0xff; | ||
299 | |||
300 | if (todc_info->rtc_type == TODC_TYPE_MC146818) { | ||
301 | uip |= todc_read_val(todc_info->RTC_FREQ_SELECT); | ||
302 | if ((uip & RTC_UIP) == 0) | ||
303 | break; | ||
304 | } | ||
305 | } | ||
306 | |||
307 | if (todc_info->rtc_type != TODC_TYPE_MC146818) { | ||
308 | switch (todc_info->rtc_type) { | ||
309 | case TODC_TYPE_DS1553: | ||
310 | case TODC_TYPE_DS1557: | ||
311 | case TODC_TYPE_DS1743: | ||
312 | case TODC_TYPE_DS1746: /* XXXX BAD HACK -> FIX */ | ||
313 | case TODC_TYPE_DS1747: | ||
314 | case TODC_TYPE_DS17285: | ||
315 | break; | ||
316 | default: | ||
317 | save_control &= ~(todc_info->enable_read); | ||
318 | todc_write_val(todc_info->control_a, save_control); | ||
319 | } | ||
320 | } | ||
321 | spin_unlock(&rtc_lock); | ||
322 | |||
323 | if ((todc_info->rtc_type != TODC_TYPE_MC146818) | ||
324 | || ((save_control & RTC_DM_BINARY) == 0) | ||
325 | || RTC_ALWAYS_BCD) { | ||
326 | BCD_TO_BIN(sec); | ||
327 | BCD_TO_BIN(min); | ||
328 | BCD_TO_BIN(hour); | ||
329 | BCD_TO_BIN(mday); | ||
330 | BCD_TO_BIN(mon); | ||
331 | BCD_TO_BIN(year); | ||
332 | } | ||
333 | |||
334 | if ((year + 1900) < 1970) { | ||
335 | year += 100; | ||
336 | } | ||
337 | |||
338 | tm->tm_sec = sec; | ||
339 | tm->tm_min = min; | ||
340 | tm->tm_hour = hour; | ||
341 | tm->tm_mday = mday; | ||
342 | tm->tm_mon = mon; | ||
343 | tm->tm_year = year; | ||
344 | |||
345 | GregorianDay(tm); | ||
346 | } | ||
347 | |||
348 | int | ||
349 | todc_set_rtc_time(struct rtc_time *tm) | ||
350 | { | ||
351 | u_char save_control, save_freq_select = 0; | ||
352 | |||
353 | spin_lock(&rtc_lock); | ||
354 | save_control = todc_read_val(todc_info->control_a); | ||
355 | |||
356 | /* Assuming MK48T59_RTC_CA_WRITE & RTC_SET are equal */ | ||
357 | todc_write_val(todc_info->control_a, | ||
358 | (save_control | todc_info->enable_write)); | ||
359 | save_control &= ~(todc_info->enable_write); /* in case it was set */ | ||
360 | |||
361 | if (todc_info->rtc_type == TODC_TYPE_MC146818) { | ||
362 | save_freq_select = todc_read_val(todc_info->RTC_FREQ_SELECT); | ||
363 | todc_write_val(todc_info->RTC_FREQ_SELECT, | ||
364 | save_freq_select | RTC_DIV_RESET2); | ||
365 | } | ||
366 | |||
367 | if ((todc_info->rtc_type != TODC_TYPE_MC146818) | ||
368 | || ((save_control & RTC_DM_BINARY) == 0) | ||
369 | || RTC_ALWAYS_BCD) { | ||
370 | BIN_TO_BCD(tm->tm_sec); | ||
371 | BIN_TO_BCD(tm->tm_min); | ||
372 | BIN_TO_BCD(tm->tm_hour); | ||
373 | BIN_TO_BCD(tm->tm_mon); | ||
374 | BIN_TO_BCD(tm->tm_mday); | ||
375 | BIN_TO_BCD(tm->tm_year); | ||
376 | } | ||
377 | |||
378 | todc_write_val(todc_info->seconds, tm->tm_sec); | ||
379 | todc_write_val(todc_info->minutes, tm->tm_min); | ||
380 | todc_write_val(todc_info->hours, tm->tm_hour); | ||
381 | todc_write_val(todc_info->month, tm->tm_mon); | ||
382 | todc_write_val(todc_info->day_of_month, tm->tm_mday); | ||
383 | todc_write_val(todc_info->year, tm->tm_year); | ||
384 | |||
385 | todc_write_val(todc_info->control_a, save_control); | ||
386 | |||
387 | if (todc_info->rtc_type == TODC_TYPE_MC146818) | ||
388 | todc_write_val(todc_info->RTC_FREQ_SELECT, save_freq_select); | ||
389 | |||
390 | spin_unlock(&rtc_lock); | ||
391 | return 0; | ||
392 | } | ||
diff --git a/arch/powerpc/sysdev/tsi108_dev.c b/arch/powerpc/sysdev/tsi108_dev.c new file mode 100644 index 000000000000..26a0cc820cde --- /dev/null +++ b/arch/powerpc/sysdev/tsi108_dev.c | |||
@@ -0,0 +1,145 @@ | |||
1 | /* | ||
2 | * tsi108/109 device setup code | ||
3 | * | ||
4 | * Maintained by Roy Zang < tie-fei.zang@freescale.com > | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/config.h> | ||
13 | #include <linux/stddef.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/errno.h> | ||
17 | #include <linux/major.h> | ||
18 | #include <linux/delay.h> | ||
19 | #include <linux/irq.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/device.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <asm/tsi108.h> | ||
24 | |||
25 | #include <asm/system.h> | ||
26 | #include <asm/atomic.h> | ||
27 | #include <asm/io.h> | ||
28 | #include <asm/irq.h> | ||
29 | #include <asm/prom.h> | ||
30 | #include <mm/mmu_decl.h> | ||
31 | |||
32 | #undef DEBUG | ||
33 | |||
34 | #ifdef DEBUG | ||
35 | #define DBG(fmt...) do { printk(fmt); } while(0) | ||
36 | #else | ||
37 | #define DBG(fmt...) do { } while(0) | ||
38 | #endif | ||
39 | |||
40 | static phys_addr_t tsi108_csr_base = -1; | ||
41 | |||
42 | phys_addr_t get_csrbase(void) | ||
43 | { | ||
44 | struct device_node *tsi; | ||
45 | |||
46 | if (tsi108_csr_base != -1) | ||
47 | return tsi108_csr_base; | ||
48 | |||
49 | tsi = of_find_node_by_type(NULL, "tsi-bridge"); | ||
50 | if (tsi) { | ||
51 | unsigned int size; | ||
52 | void *prop = get_property(tsi, "reg", &size); | ||
53 | tsi108_csr_base = of_translate_address(tsi, prop); | ||
54 | of_node_put(tsi); | ||
55 | }; | ||
56 | return tsi108_csr_base; | ||
57 | } | ||
58 | |||
59 | u32 get_vir_csrbase(void) | ||
60 | { | ||
61 | return (u32) (ioremap(get_csrbase(), 0x10000)); | ||
62 | } | ||
63 | |||
64 | EXPORT_SYMBOL(get_csrbase); | ||
65 | EXPORT_SYMBOL(get_vir_csrbase); | ||
66 | |||
67 | static int __init tsi108_eth_of_init(void) | ||
68 | { | ||
69 | struct device_node *np; | ||
70 | unsigned int i; | ||
71 | struct platform_device *tsi_eth_dev; | ||
72 | struct resource res; | ||
73 | int ret; | ||
74 | |||
75 | for (np = NULL, i = 0; | ||
76 | (np = of_find_compatible_node(np, "network", "tsi-ethernet")) != NULL; | ||
77 | i++) { | ||
78 | struct resource r[2]; | ||
79 | struct device_node *phy; | ||
80 | hw_info tsi_eth_data; | ||
81 | unsigned int *id; | ||
82 | unsigned int *phy_id; | ||
83 | void *mac_addr; | ||
84 | phandle *ph; | ||
85 | |||
86 | memset(r, 0, sizeof(r)); | ||
87 | memset(&tsi_eth_data, 0, sizeof(tsi_eth_data)); | ||
88 | |||
89 | ret = of_address_to_resource(np, 0, &r[0]); | ||
90 | DBG("%s: name:start->end = %s:0x%lx-> 0x%lx\n", | ||
91 | __FUNCTION__,r[0].name, r[0].start, r[0].end); | ||
92 | if (ret) | ||
93 | goto err; | ||
94 | |||
95 | r[1].name = "tx"; | ||
96 | r[1].start = np->intrs[0].line; | ||
97 | r[1].end = np->intrs[0].line; | ||
98 | r[1].flags = IORESOURCE_IRQ; | ||
99 | |||
100 | tsi_eth_dev = | ||
101 | platform_device_register_simple("tsi-ethernet", i, &r[0], | ||
102 | np->n_intrs + 1); | ||
103 | |||
104 | if (IS_ERR(tsi_eth_dev)) { | ||
105 | ret = PTR_ERR(tsi_eth_dev); | ||
106 | goto err; | ||
107 | } | ||
108 | |||
109 | mac_addr = get_property(np, "address", NULL); | ||
110 | memcpy(tsi_eth_data.mac_addr, mac_addr, 6); | ||
111 | |||
112 | ph = (phandle *) get_property(np, "phy-handle", NULL); | ||
113 | phy = of_find_node_by_phandle(*ph); | ||
114 | |||
115 | if (phy == NULL) { | ||
116 | ret = -ENODEV; | ||
117 | goto unreg; | ||
118 | } | ||
119 | |||
120 | id = (u32 *) get_property(phy, "reg", NULL); | ||
121 | phy_id = (u32 *) get_property(phy, "phy-id", NULL); | ||
122 | ret = of_address_to_resource(phy, 0, &res); | ||
123 | if (ret) { | ||
124 | of_node_put(phy); | ||
125 | goto unreg; | ||
126 | } | ||
127 | tsi_eth_data.regs = r[0].start; | ||
128 | tsi_eth_data.phyregs = res.start; | ||
129 | tsi_eth_data.phy = *phy_id; | ||
130 | tsi_eth_data.irq_num = np->intrs[0].line; | ||
131 | of_node_put(phy); | ||
132 | ret = | ||
133 | platform_device_add_data(tsi_eth_dev, &tsi_eth_data, | ||
134 | sizeof(hw_info)); | ||
135 | if (ret) | ||
136 | goto unreg; | ||
137 | } | ||
138 | return 0; | ||
139 | unreg: | ||
140 | platform_device_unregister(tsi_eth_dev); | ||
141 | err: | ||
142 | return ret; | ||
143 | } | ||
144 | |||
145 | arch_initcall(tsi108_eth_of_init); | ||
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c new file mode 100644 index 000000000000..3265d54c82ed --- /dev/null +++ b/arch/powerpc/sysdev/tsi108_pci.c | |||
@@ -0,0 +1,412 @@ | |||
1 | /* | ||
2 | * Common routines for Tundra Semiconductor TSI108 host bridge. | ||
3 | * | ||
4 | * 2004-2005 (c) Tundra Semiconductor Corp. | ||
5 | * Author: Alex Bounine (alexandreb@tundra.com) | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the Free | ||
9 | * Software Foundation; either version 2 of the License, or (at your option) | ||
10 | * any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
15 | * more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along with | ||
18 | * this program; if not, write to the Free Software Foundation, Inc., 59 | ||
19 | * Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/pci.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <linux/irq.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | |||
29 | |||
30 | #include <asm/byteorder.h> | ||
31 | #include <asm/io.h> | ||
32 | #include <asm/irq.h> | ||
33 | #include <asm/uaccess.h> | ||
34 | #include <asm/machdep.h> | ||
35 | #include <asm/pci-bridge.h> | ||
36 | #include <asm/tsi108.h> | ||
37 | #include <asm/tsi108_irq.h> | ||
38 | #include <asm/prom.h> | ||
39 | |||
40 | #undef DEBUG | ||
41 | #ifdef DEBUG | ||
42 | #define DBG(x...) printk(x) | ||
43 | #else | ||
44 | #define DBG(x...) | ||
45 | #endif | ||
46 | |||
47 | #define tsi_mk_config_addr(bus, devfunc, offset) \ | ||
48 | ((((bus)<<16) | ((devfunc)<<8) | (offset & 0xfc)) + tsi108_pci_cfg_base) | ||
49 | |||
50 | u32 tsi108_pci_cfg_base; | ||
51 | u32 tsi108_csr_vir_base; | ||
52 | |||
53 | extern u32 get_vir_csrbase(void); | ||
54 | extern u32 tsi108_read_reg(u32 reg_offset); | ||
55 | extern void tsi108_write_reg(u32 reg_offset, u32 val); | ||
56 | |||
57 | int | ||
58 | tsi108_direct_write_config(struct pci_bus *bus, unsigned int devfunc, | ||
59 | int offset, int len, u32 val) | ||
60 | { | ||
61 | volatile unsigned char *cfg_addr; | ||
62 | |||
63 | if (ppc_md.pci_exclude_device) | ||
64 | if (ppc_md.pci_exclude_device(bus->number, devfunc)) | ||
65 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
66 | |||
67 | cfg_addr = (unsigned char *)(tsi_mk_config_addr(bus->number, | ||
68 | devfunc, offset) | | ||
69 | (offset & 0x03)); | ||
70 | |||
71 | #ifdef DEBUG | ||
72 | printk("PCI CFG write : "); | ||
73 | printk("%d:0x%x:0x%x ", bus->number, devfunc, offset); | ||
74 | printk("%d ADDR=0x%08x ", len, (uint) cfg_addr); | ||
75 | printk("data = 0x%08x\n", val); | ||
76 | #endif | ||
77 | |||
78 | switch (len) { | ||
79 | case 1: | ||
80 | out_8((u8 *) cfg_addr, val); | ||
81 | break; | ||
82 | case 2: | ||
83 | out_le16((u16 *) cfg_addr, val); | ||
84 | break; | ||
85 | default: | ||
86 | out_le32((u32 *) cfg_addr, val); | ||
87 | break; | ||
88 | } | ||
89 | |||
90 | return PCIBIOS_SUCCESSFUL; | ||
91 | } | ||
92 | |||
93 | void tsi108_clear_pci_error(u32 pci_cfg_base) | ||
94 | { | ||
95 | u32 err_stat, err_addr, pci_stat; | ||
96 | |||
97 | /* | ||
98 | * Quietly clear PB and PCI error flags set as result | ||
99 | * of PCI/X configuration read requests. | ||
100 | */ | ||
101 | |||
102 | /* Read PB Error Log Registers */ | ||
103 | |||
104 | err_stat = tsi108_read_reg(TSI108_PB_OFFSET + TSI108_PB_ERRCS); | ||
105 | err_addr = tsi108_read_reg(TSI108_PB_OFFSET + TSI108_PB_AERR); | ||
106 | |||
107 | if (err_stat & TSI108_PB_ERRCS_ES) { | ||
108 | /* Clear error flag */ | ||
109 | tsi108_write_reg(TSI108_PB_OFFSET + TSI108_PB_ERRCS, | ||
110 | TSI108_PB_ERRCS_ES); | ||
111 | |||
112 | /* Clear read error reported in PB_ISR */ | ||
113 | tsi108_write_reg(TSI108_PB_OFFSET + TSI108_PB_ISR, | ||
114 | TSI108_PB_ISR_PBS_RD_ERR); | ||
115 | |||
116 | /* Clear PCI/X bus cfg errors if applicable */ | ||
117 | if ((err_addr & 0xFF000000) == pci_cfg_base) { | ||
118 | pci_stat = | ||
119 | tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_CSR); | ||
120 | tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_CSR, | ||
121 | pci_stat); | ||
122 | } | ||
123 | } | ||
124 | |||
125 | return; | ||
126 | } | ||
127 | |||
128 | #define __tsi108_read_pci_config(x, addr, op) \ | ||
129 | __asm__ __volatile__( \ | ||
130 | " "op" %0,0,%1\n" \ | ||
131 | "1: eieio\n" \ | ||
132 | "2:\n" \ | ||
133 | ".section .fixup,\"ax\"\n" \ | ||
134 | "3: li %0,-1\n" \ | ||
135 | " b 2b\n" \ | ||
136 | ".section __ex_table,\"a\"\n" \ | ||
137 | " .align 2\n" \ | ||
138 | " .long 1b,3b\n" \ | ||
139 | ".text" \ | ||
140 | : "=r"(x) : "r"(addr)) | ||
141 | |||
142 | int | ||
143 | tsi108_direct_read_config(struct pci_bus *bus, unsigned int devfn, int offset, | ||
144 | int len, u32 * val) | ||
145 | { | ||
146 | volatile unsigned char *cfg_addr; | ||
147 | u32 temp; | ||
148 | |||
149 | if (ppc_md.pci_exclude_device) | ||
150 | if (ppc_md.pci_exclude_device(bus->number, devfn)) | ||
151 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
152 | |||
153 | cfg_addr = (unsigned char *)(tsi_mk_config_addr(bus->number, | ||
154 | devfn, | ||
155 | offset) | (offset & | ||
156 | 0x03)); | ||
157 | |||
158 | switch (len) { | ||
159 | case 1: | ||
160 | __tsi108_read_pci_config(temp, cfg_addr, "lbzx"); | ||
161 | break; | ||
162 | case 2: | ||
163 | __tsi108_read_pci_config(temp, cfg_addr, "lhbrx"); | ||
164 | break; | ||
165 | default: | ||
166 | __tsi108_read_pci_config(temp, cfg_addr, "lwbrx"); | ||
167 | break; | ||
168 | } | ||
169 | |||
170 | *val = temp; | ||
171 | |||
172 | #ifdef DEBUG | ||
173 | if ((0xFFFFFFFF != temp) && (0xFFFF != temp) && (0xFF != temp)) { | ||
174 | printk("PCI CFG read : "); | ||
175 | printk("%d:0x%x:0x%x ", bus->number, devfn, offset); | ||
176 | printk("%d ADDR=0x%08x ", len, (uint) cfg_addr); | ||
177 | printk("data = 0x%x\n", *val); | ||
178 | } | ||
179 | #endif | ||
180 | return PCIBIOS_SUCCESSFUL; | ||
181 | } | ||
182 | |||
183 | void tsi108_clear_pci_cfg_error(void) | ||
184 | { | ||
185 | tsi108_clear_pci_error(TSI108_PCI_CFG_BASE_PHYS); | ||
186 | } | ||
187 | |||
188 | static struct pci_ops tsi108_direct_pci_ops = { | ||
189 | tsi108_direct_read_config, | ||
190 | tsi108_direct_write_config | ||
191 | }; | ||
192 | |||
193 | int __init tsi108_setup_pci(struct device_node *dev) | ||
194 | { | ||
195 | int len; | ||
196 | struct pci_controller *hose; | ||
197 | struct resource rsrc; | ||
198 | int *bus_range; | ||
199 | int primary = 0, has_address = 0; | ||
200 | |||
201 | /* PCI Config mapping */ | ||
202 | tsi108_pci_cfg_base = (u32)ioremap(TSI108_PCI_CFG_BASE_PHYS, | ||
203 | TSI108_PCI_CFG_SIZE); | ||
204 | DBG("TSI_PCI: %s tsi108_pci_cfg_base=0x%x\n", __FUNCTION__, | ||
205 | tsi108_pci_cfg_base); | ||
206 | |||
207 | /* Fetch host bridge registers address */ | ||
208 | has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); | ||
209 | |||
210 | /* Get bus range if any */ | ||
211 | bus_range = (int *)get_property(dev, "bus-range", &len); | ||
212 | if (bus_range == NULL || len < 2 * sizeof(int)) { | ||
213 | printk(KERN_WARNING "Can't get bus-range for %s, assume" | ||
214 | " bus 0\n", dev->full_name); | ||
215 | } | ||
216 | |||
217 | hose = pcibios_alloc_controller(); | ||
218 | |||
219 | if (!hose) { | ||
220 | printk("PCI Host bridge init failed\n"); | ||
221 | return -ENOMEM; | ||
222 | } | ||
223 | hose->arch_data = dev; | ||
224 | hose->set_cfg_type = 1; | ||
225 | |||
226 | hose->first_busno = bus_range ? bus_range[0] : 0; | ||
227 | hose->last_busno = bus_range ? bus_range[1] : 0xff; | ||
228 | |||
229 | (hose)->ops = &tsi108_direct_pci_ops; | ||
230 | |||
231 | printk(KERN_INFO "Found tsi108 PCI host bridge at 0x%08lx. " | ||
232 | "Firmware bus number: %d->%d\n", | ||
233 | rsrc.start, hose->first_busno, hose->last_busno); | ||
234 | |||
235 | /* Interpret the "ranges" property */ | ||
236 | /* This also maps the I/O region and sets isa_io/mem_base */ | ||
237 | pci_process_bridge_OF_ranges(hose, dev, primary); | ||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | /* | ||
242 | * Low level utility functions | ||
243 | */ | ||
244 | |||
245 | static void tsi108_pci_int_mask(u_int irq) | ||
246 | { | ||
247 | u_int irp_cfg; | ||
248 | int int_line = (irq - IRQ_PCI_INTAD_BASE); | ||
249 | |||
250 | irp_cfg = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL); | ||
251 | mb(); | ||
252 | irp_cfg |= (1 << int_line); /* INTx_DIR = output */ | ||
253 | irp_cfg &= ~(3 << (8 + (int_line * 2))); /* INTx_TYPE = unused */ | ||
254 | tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL, irp_cfg); | ||
255 | mb(); | ||
256 | irp_cfg = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL); | ||
257 | } | ||
258 | |||
259 | static void tsi108_pci_int_unmask(u_int irq) | ||
260 | { | ||
261 | u_int irp_cfg; | ||
262 | int int_line = (irq - IRQ_PCI_INTAD_BASE); | ||
263 | |||
264 | irp_cfg = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL); | ||
265 | mb(); | ||
266 | irp_cfg &= ~(1 << int_line); | ||
267 | irp_cfg |= (3 << (8 + (int_line * 2))); | ||
268 | tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL, irp_cfg); | ||
269 | mb(); | ||
270 | } | ||
271 | |||
272 | static void init_pci_source(void) | ||
273 | { | ||
274 | tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL, | ||
275 | 0x0000ff00); | ||
276 | tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE, | ||
277 | TSI108_PCI_IRP_ENABLE_P_INT); | ||
278 | mb(); | ||
279 | } | ||
280 | |||
281 | static inline int get_pci_source(void) | ||
282 | { | ||
283 | u_int temp = 0; | ||
284 | int irq = -1; | ||
285 | int i; | ||
286 | u_int pci_irp_stat; | ||
287 | static int mask = 0; | ||
288 | |||
289 | /* Read PCI/X block interrupt status register */ | ||
290 | pci_irp_stat = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_STAT); | ||
291 | mb(); | ||
292 | |||
293 | if (pci_irp_stat & TSI108_PCI_IRP_STAT_P_INT) { | ||
294 | /* Process Interrupt from PCI bus INTA# - INTD# lines */ | ||
295 | temp = | ||
296 | tsi108_read_reg(TSI108_PCI_OFFSET + | ||
297 | TSI108_PCI_IRP_INTAD) & 0xf; | ||
298 | mb(); | ||
299 | for (i = 0; i < 4; i++, mask++) { | ||
300 | if (temp & (1 << mask % 4)) { | ||
301 | irq = IRQ_PCI_INTA + mask % 4; | ||
302 | mask++; | ||
303 | break; | ||
304 | } | ||
305 | } | ||
306 | |||
307 | /* Disable interrupts from PCI block */ | ||
308 | temp = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE); | ||
309 | tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE, | ||
310 | temp & ~TSI108_PCI_IRP_ENABLE_P_INT); | ||
311 | mb(); | ||
312 | (void)tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE); | ||
313 | mb(); | ||
314 | } | ||
315 | #ifdef DEBUG | ||
316 | else { | ||
317 | printk("TSI108_PIC: error in TSI108_PCI_IRP_STAT\n"); | ||
318 | pci_irp_stat = | ||
319 | tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_STAT); | ||
320 | temp = | ||
321 | tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_INTAD); | ||
322 | mb(); | ||
323 | printk(">> stat=0x%08x intad=0x%08x ", pci_irp_stat, temp); | ||
324 | temp = | ||
325 | tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL); | ||
326 | mb(); | ||
327 | printk("cfg_ctl=0x%08x ", temp); | ||
328 | temp = | ||
329 | tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE); | ||
330 | mb(); | ||
331 | printk("irp_enable=0x%08x\n", temp); | ||
332 | } | ||
333 | #endif /* end of DEBUG */ | ||
334 | |||
335 | return irq; | ||
336 | } | ||
337 | |||
338 | |||
339 | /* | ||
340 | * Linux descriptor level callbacks | ||
341 | */ | ||
342 | |||
343 | static void tsi108_pci_irq_enable(u_int irq) | ||
344 | { | ||
345 | tsi108_pci_int_unmask(irq); | ||
346 | } | ||
347 | |||
348 | static void tsi108_pci_irq_disable(u_int irq) | ||
349 | { | ||
350 | tsi108_pci_int_mask(irq); | ||
351 | } | ||
352 | |||
353 | static void tsi108_pci_irq_ack(u_int irq) | ||
354 | { | ||
355 | tsi108_pci_int_mask(irq); | ||
356 | } | ||
357 | |||
358 | static void tsi108_pci_irq_end(u_int irq) | ||
359 | { | ||
360 | tsi108_pci_int_unmask(irq); | ||
361 | |||
362 | /* Enable interrupts from PCI block */ | ||
363 | tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE, | ||
364 | tsi108_read_reg(TSI108_PCI_OFFSET + | ||
365 | TSI108_PCI_IRP_ENABLE) | | ||
366 | TSI108_PCI_IRP_ENABLE_P_INT); | ||
367 | mb(); | ||
368 | } | ||
369 | |||
370 | /* | ||
371 | * Interrupt controller descriptor for cascaded PCI interrupt controller. | ||
372 | */ | ||
373 | |||
374 | struct hw_interrupt_type tsi108_pci_irq = { | ||
375 | .typename = "tsi108_PCI_int", | ||
376 | .enable = tsi108_pci_irq_enable, | ||
377 | .disable = tsi108_pci_irq_disable, | ||
378 | .ack = tsi108_pci_irq_ack, | ||
379 | .end = tsi108_pci_irq_end, | ||
380 | }; | ||
381 | |||
382 | /* | ||
383 | * Exported functions | ||
384 | */ | ||
385 | |||
386 | /* | ||
387 | * The Tsi108 PCI interrupts initialization routine. | ||
388 | * | ||
389 | * The INTA# - INTD# interrupts on the PCI bus are reported by the PCI block | ||
390 | * to the MPIC using single interrupt source (IRQ_TSI108_PCI). Therefore the | ||
391 | * PCI block has to be treated as a cascaded interrupt controller connected | ||
392 | * to the MPIC. | ||
393 | */ | ||
394 | |||
395 | void __init tsi108_pci_int_init(void) | ||
396 | { | ||
397 | u_int i; | ||
398 | |||
399 | DBG("Tsi108_pci_int_init: initializing PCI interrupts\n"); | ||
400 | |||
401 | for (i = 0; i < NUM_PCI_IRQS; i++) { | ||
402 | irq_desc[i + IRQ_PCI_INTAD_BASE].handler = &tsi108_pci_irq; | ||
403 | irq_desc[i + IRQ_PCI_INTAD_BASE].status |= IRQ_LEVEL; | ||
404 | } | ||
405 | |||
406 | init_pci_source(); | ||
407 | } | ||
408 | |||
409 | int tsi108_irq_cascade(struct pt_regs *regs, void *unused) | ||
410 | { | ||
411 | return get_pci_source(); | ||
412 | } | ||
diff --git a/arch/ppc/8xx_io/commproc.c b/arch/ppc/8xx_io/commproc.c index 12b84ca51327..9b3ace26280c 100644 --- a/arch/ppc/8xx_io/commproc.c +++ b/arch/ppc/8xx_io/commproc.c | |||
@@ -187,7 +187,7 @@ cpm_interrupt_init(void) | |||
187 | * interrupt vectors | 187 | * interrupt vectors |
188 | */ | 188 | */ |
189 | for ( i = CPM_IRQ_OFFSET ; i < CPM_IRQ_OFFSET + NR_CPM_INTS ; i++ ) | 189 | for ( i = CPM_IRQ_OFFSET ; i < CPM_IRQ_OFFSET + NR_CPM_INTS ; i++ ) |
190 | irq_desc[i].handler = &cpm_pic; | 190 | irq_desc[i].chip = &cpm_pic; |
191 | 191 | ||
192 | /* Set our interrupt handler with the core CPU. */ | 192 | /* Set our interrupt handler with the core CPU. */ |
193 | if (setup_irq(CPM_INTERRUPT, &cpm_interrupt_irqaction)) | 193 | if (setup_irq(CPM_INTERRUPT, &cpm_interrupt_irqaction)) |
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index b55de4f42aec..a04cdf01596b 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig | |||
@@ -219,10 +219,10 @@ config KEXEC | |||
219 | help | 219 | help |
220 | kexec is a system call that implements the ability to shutdown your | 220 | kexec is a system call that implements the ability to shutdown your |
221 | current kernel, and to start another kernel. It is like a reboot | 221 | current kernel, and to start another kernel. It is like a reboot |
222 | but it is indepedent of the system firmware. And like a reboot | 222 | but it is independent of the system firmware. And like a reboot |
223 | you can start any kernel with it, not just Linux. | 223 | you can start any kernel with it, not just Linux. |
224 | 224 | ||
225 | The name comes from the similiarity to the exec system call. | 225 | The name comes from the similarity to the exec system call. |
226 | 226 | ||
227 | It is an ongoing process to be certain the hardware in a machine | 227 | It is an ongoing process to be certain the hardware in a machine |
228 | is properly shutdown, so do not be surprised if this code does not | 228 | is properly shutdown, so do not be surprised if this code does not |
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c index d20accf9650d..242bb052be67 100644 --- a/arch/ppc/kernel/pci.c +++ b/arch/ppc/kernel/pci.c | |||
@@ -95,8 +95,10 @@ pcibios_fixup_resources(struct pci_dev *dev) | |||
95 | if (!res->flags) | 95 | if (!res->flags) |
96 | continue; | 96 | continue; |
97 | if (res->end == 0xffffffff) { | 97 | if (res->end == 0xffffffff) { |
98 | DBG("PCI:%s Resource %d [%08lx-%08lx] is unassigned\n", | 98 | DBG("PCI:%s Resource %d [%016llx-%016llx] is unassigned\n", |
99 | pci_name(dev), i, res->start, res->end); | 99 | pci_name(dev), i, |
100 | (unsigned long long)res->start, | ||
101 | (unsigned long long)res->end); | ||
100 | res->end -= res->start; | 102 | res->end -= res->start; |
101 | res->start = 0; | 103 | res->start = 0; |
102 | res->flags |= IORESOURCE_UNSET; | 104 | res->flags |= IORESOURCE_UNSET; |
@@ -169,18 +171,18 @@ EXPORT_SYMBOL(pcibios_bus_to_resource); | |||
169 | * but we want to try to avoid allocating at 0x2900-0x2bff | 171 | * but we want to try to avoid allocating at 0x2900-0x2bff |
170 | * which might have be mirrored at 0x0100-0x03ff.. | 172 | * which might have be mirrored at 0x0100-0x03ff.. |
171 | */ | 173 | */ |
172 | void pcibios_align_resource(void *data, struct resource *res, unsigned long size, | 174 | void pcibios_align_resource(void *data, struct resource *res, |
173 | unsigned long align) | 175 | resource_size_t size, resource_size_t align) |
174 | { | 176 | { |
175 | struct pci_dev *dev = data; | 177 | struct pci_dev *dev = data; |
176 | 178 | ||
177 | if (res->flags & IORESOURCE_IO) { | 179 | if (res->flags & IORESOURCE_IO) { |
178 | unsigned long start = res->start; | 180 | resource_size_t start = res->start; |
179 | 181 | ||
180 | if (size > 0x100) { | 182 | if (size > 0x100) { |
181 | printk(KERN_ERR "PCI: I/O Region %s/%d too large" | 183 | printk(KERN_ERR "PCI: I/O Region %s/%d too large" |
182 | " (%ld bytes)\n", pci_name(dev), | 184 | " (%lld bytes)\n", pci_name(dev), |
183 | dev->resource - res, size); | 185 | dev->resource - res, (unsigned long long)size); |
184 | } | 186 | } |
185 | 187 | ||
186 | if (start & 0x300) { | 188 | if (start & 0x300) { |
@@ -251,8 +253,9 @@ pcibios_allocate_bus_resources(struct list_head *bus_list) | |||
251 | } | 253 | } |
252 | } | 254 | } |
253 | 255 | ||
254 | DBG("PCI: bridge rsrc %lx..%lx (%lx), parent %p\n", | 256 | DBG("PCI: bridge rsrc %llx..%llx (%lx), parent %p\n", |
255 | res->start, res->end, res->flags, pr); | 257 | (unsigned long long)res->start, |
258 | (unsigned long long)res->end, res->flags, pr); | ||
256 | if (pr) { | 259 | if (pr) { |
257 | if (request_resource(pr, res) == 0) | 260 | if (request_resource(pr, res) == 0) |
258 | continue; | 261 | continue; |
@@ -302,8 +305,9 @@ reparent_resources(struct resource *parent, struct resource *res) | |||
302 | *pp = NULL; | 305 | *pp = NULL; |
303 | for (p = res->child; p != NULL; p = p->sibling) { | 306 | for (p = res->child; p != NULL; p = p->sibling) { |
304 | p->parent = res; | 307 | p->parent = res; |
305 | DBG(KERN_INFO "PCI: reparented %s [%lx..%lx] under %s\n", | 308 | DBG(KERN_INFO "PCI: reparented %s [%llx..%llx] under %s\n", |
306 | p->name, p->start, p->end, res->name); | 309 | p->name, (unsigned long long)p->start, |
310 | (unsigned long long)p->end, res->name); | ||
307 | } | 311 | } |
308 | return 0; | 312 | return 0; |
309 | } | 313 | } |
@@ -358,13 +362,15 @@ pci_relocate_bridge_resource(struct pci_bus *bus, int i) | |||
358 | try = conflict->start - 1; | 362 | try = conflict->start - 1; |
359 | } | 363 | } |
360 | if (request_resource(pr, res)) { | 364 | if (request_resource(pr, res)) { |
361 | DBG(KERN_ERR "PCI: huh? couldn't move to %lx..%lx\n", | 365 | DBG(KERN_ERR "PCI: huh? couldn't move to %llx..%llx\n", |
362 | res->start, res->end); | 366 | (unsigned long long)res->start, |
367 | (unsigned long long)res->end); | ||
363 | return -1; /* "can't happen" */ | 368 | return -1; /* "can't happen" */ |
364 | } | 369 | } |
365 | update_bridge_base(bus, i); | 370 | update_bridge_base(bus, i); |
366 | printk(KERN_INFO "PCI: bridge %d resource %d moved to %lx..%lx\n", | 371 | printk(KERN_INFO "PCI: bridge %d resource %d moved to %llx..%llx\n", |
367 | bus->number, i, res->start, res->end); | 372 | bus->number, i, (unsigned long long)res->start, |
373 | (unsigned long long)res->end); | ||
368 | return 0; | 374 | return 0; |
369 | } | 375 | } |
370 | 376 | ||
@@ -475,15 +481,17 @@ static inline void alloc_resource(struct pci_dev *dev, int idx) | |||
475 | { | 481 | { |
476 | struct resource *pr, *r = &dev->resource[idx]; | 482 | struct resource *pr, *r = &dev->resource[idx]; |
477 | 483 | ||
478 | DBG("PCI:%s: Resource %d: %08lx-%08lx (f=%lx)\n", | 484 | DBG("PCI:%s: Resource %d: %016llx-%016llx (f=%lx)\n", |
479 | pci_name(dev), idx, r->start, r->end, r->flags); | 485 | pci_name(dev), idx, (unsigned long long)r->start, |
486 | (unsigned long long)r->end, r->flags); | ||
480 | pr = pci_find_parent_resource(dev, r); | 487 | pr = pci_find_parent_resource(dev, r); |
481 | if (!pr || request_resource(pr, r) < 0) { | 488 | if (!pr || request_resource(pr, r) < 0) { |
482 | printk(KERN_ERR "PCI: Cannot allocate resource region %d" | 489 | printk(KERN_ERR "PCI: Cannot allocate resource region %d" |
483 | " of device %s\n", idx, pci_name(dev)); | 490 | " of device %s\n", idx, pci_name(dev)); |
484 | if (pr) | 491 | if (pr) |
485 | DBG("PCI: parent is %p: %08lx-%08lx (f=%lx)\n", | 492 | DBG("PCI: parent is %p: %016llx-%016llx (f=%lx)\n", |
486 | pr, pr->start, pr->end, pr->flags); | 493 | pr, (unsigned long long)pr->start, |
494 | (unsigned long long)pr->end, pr->flags); | ||
487 | /* We'll assign a new address later */ | 495 | /* We'll assign a new address later */ |
488 | r->flags |= IORESOURCE_UNSET; | 496 | r->flags |= IORESOURCE_UNSET; |
489 | r->end -= r->start; | 497 | r->end -= r->start; |
@@ -952,8 +960,8 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, | |||
952 | else | 960 | else |
953 | prot |= _PAGE_GUARDED; | 961 | prot |= _PAGE_GUARDED; |
954 | 962 | ||
955 | printk("PCI map for %s:%lx, prot: %lx\n", pci_name(dev), rp->start, | 963 | printk("PCI map for %s:%llx, prot: %lx\n", pci_name(dev), |
956 | prot); | 964 | (unsigned long long)rp->start, prot); |
957 | 965 | ||
958 | return __pgprot(prot); | 966 | return __pgprot(prot); |
959 | } | 967 | } |
@@ -1122,7 +1130,7 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn) | |||
1122 | 1130 | ||
1123 | void pci_resource_to_user(const struct pci_dev *dev, int bar, | 1131 | void pci_resource_to_user(const struct pci_dev *dev, int bar, |
1124 | const struct resource *rsrc, | 1132 | const struct resource *rsrc, |
1125 | u64 *start, u64 *end) | 1133 | resource_size_t *start, resource_size_t *end) |
1126 | { | 1134 | { |
1127 | struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); | 1135 | struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); |
1128 | unsigned long offset = 0; | 1136 | unsigned long offset = 0; |
diff --git a/arch/ppc/platforms/apus_setup.c b/arch/ppc/platforms/apus_setup.c index fe0cdc04d436..5c4118a459f3 100644 --- a/arch/ppc/platforms/apus_setup.c +++ b/arch/ppc/platforms/apus_setup.c | |||
@@ -734,9 +734,9 @@ void apus_init_IRQ(void) | |||
734 | for ( i = 0 ; i < AMI_IRQS; i++ ) { | 734 | for ( i = 0 ; i < AMI_IRQS; i++ ) { |
735 | irq_desc[i].status = IRQ_LEVEL; | 735 | irq_desc[i].status = IRQ_LEVEL; |
736 | if (i < IRQ_AMIGA_AUTO) { | 736 | if (i < IRQ_AMIGA_AUTO) { |
737 | irq_desc[i].handler = &amiga_irqctrl; | 737 | irq_desc[i].chip = &amiga_irqctrl; |
738 | } else { | 738 | } else { |
739 | irq_desc[i].handler = &amiga_sys_irqctrl; | 739 | irq_desc[i].chip = &amiga_sys_irqctrl; |
740 | action = &amiga_sys_irqaction[i-IRQ_AMIGA_AUTO]; | 740 | action = &amiga_sys_irqaction[i-IRQ_AMIGA_AUTO]; |
741 | if (action->name) | 741 | if (action->name) |
742 | setup_irq(i, action); | 742 | setup_irq(i, action); |
diff --git a/arch/ppc/platforms/sbc82xx.c b/arch/ppc/platforms/sbc82xx.c index 866807b4ad0b..41006d2b4b38 100644 --- a/arch/ppc/platforms/sbc82xx.c +++ b/arch/ppc/platforms/sbc82xx.c | |||
@@ -172,7 +172,7 @@ void __init sbc82xx_init_IRQ(void) | |||
172 | 172 | ||
173 | /* Set up the interrupt handlers for the i8259 IRQs */ | 173 | /* Set up the interrupt handlers for the i8259 IRQs */ |
174 | for (i = NR_SIU_INTS; i < NR_SIU_INTS + 8; i++) { | 174 | for (i = NR_SIU_INTS; i < NR_SIU_INTS + 8; i++) { |
175 | irq_desc[i].handler = &sbc82xx_i8259_ic; | 175 | irq_desc[i].chip = &sbc82xx_i8259_ic; |
176 | irq_desc[i].status |= IRQ_LEVEL; | 176 | irq_desc[i].status |= IRQ_LEVEL; |
177 | } | 177 | } |
178 | 178 | ||
diff --git a/arch/ppc/syslib/cpc700_pic.c b/arch/ppc/syslib/cpc700_pic.c index 5add0a919ef6..172aa215fdb0 100644 --- a/arch/ppc/syslib/cpc700_pic.c +++ b/arch/ppc/syslib/cpc700_pic.c | |||
@@ -140,12 +140,12 @@ cpc700_init_IRQ(void) | |||
140 | /* IRQ 0 is highest */ | 140 | /* IRQ 0 is highest */ |
141 | 141 | ||
142 | for (i = 0; i < 17; i++) { | 142 | for (i = 0; i < 17; i++) { |
143 | irq_desc[i].handler = &cpc700_pic; | 143 | irq_desc[i].chip = &cpc700_pic; |
144 | cpc700_pic_init_irq(i); | 144 | cpc700_pic_init_irq(i); |
145 | } | 145 | } |
146 | 146 | ||
147 | for (i = 20; i < 32; i++) { | 147 | for (i = 20; i < 32; i++) { |
148 | irq_desc[i].handler = &cpc700_pic; | 148 | irq_desc[i].chip = &cpc700_pic; |
149 | cpc700_pic_init_irq(i); | 149 | cpc700_pic_init_irq(i); |
150 | } | 150 | } |
151 | 151 | ||
diff --git a/arch/ppc/syslib/cpm2_pic.c b/arch/ppc/syslib/cpm2_pic.c index 29d95d415ceb..c0fee0beb815 100644 --- a/arch/ppc/syslib/cpm2_pic.c +++ b/arch/ppc/syslib/cpm2_pic.c | |||
@@ -171,7 +171,7 @@ void cpm2_init_IRQ(void) | |||
171 | /* Enable chaining to OpenPIC, and make everything level | 171 | /* Enable chaining to OpenPIC, and make everything level |
172 | */ | 172 | */ |
173 | for (i = 0; i < NR_CPM_INTS; i++) { | 173 | for (i = 0; i < NR_CPM_INTS; i++) { |
174 | irq_desc[i+CPM_IRQ_OFFSET].handler = &cpm2_pic; | 174 | irq_desc[i+CPM_IRQ_OFFSET].chip = &cpm2_pic; |
175 | irq_desc[i+CPM_IRQ_OFFSET].status |= IRQ_LEVEL; | 175 | irq_desc[i+CPM_IRQ_OFFSET].status |= IRQ_LEVEL; |
176 | } | 176 | } |
177 | } | 177 | } |
diff --git a/arch/ppc/syslib/gt64260_pic.c b/arch/ppc/syslib/gt64260_pic.c index dc3bd9ecbbf6..91096b38ae70 100644 --- a/arch/ppc/syslib/gt64260_pic.c +++ b/arch/ppc/syslib/gt64260_pic.c | |||
@@ -98,7 +98,7 @@ gt64260_init_irq(void) | |||
98 | 98 | ||
99 | /* use the gt64260 for all (possible) interrupt sources */ | 99 | /* use the gt64260 for all (possible) interrupt sources */ |
100 | for (i = gt64260_irq_base; i < (gt64260_irq_base + 96); i++) | 100 | for (i = gt64260_irq_base; i < (gt64260_irq_base + 96); i++) |
101 | irq_desc[i].handler = >64260_pic; | 101 | irq_desc[i].chip = >64260_pic; |
102 | 102 | ||
103 | if (ppc_md.progress) | 103 | if (ppc_md.progress) |
104 | ppc_md.progress("gt64260_init_irq: exit", 0x0); | 104 | ppc_md.progress("gt64260_init_irq: exit", 0x0); |
diff --git a/arch/ppc/syslib/m82xx_pci.c b/arch/ppc/syslib/m82xx_pci.c index 1941a8c7ca9a..63fa5b313396 100644 --- a/arch/ppc/syslib/m82xx_pci.c +++ b/arch/ppc/syslib/m82xx_pci.c | |||
@@ -159,7 +159,7 @@ pq2pci_init_irq(void) | |||
159 | immap->im_memctl.memc_or8 = 0xffff8010; | 159 | immap->im_memctl.memc_or8 = 0xffff8010; |
160 | #endif | 160 | #endif |
161 | for (irq = NR_CPM_INTS; irq < NR_CPM_INTS + 4; irq++) | 161 | for (irq = NR_CPM_INTS; irq < NR_CPM_INTS + 4; irq++) |
162 | irq_desc[irq].handler = &pq2pci_ic; | 162 | irq_desc[irq].chip = &pq2pci_ic; |
163 | 163 | ||
164 | /* make PCI IRQ level sensitive */ | 164 | /* make PCI IRQ level sensitive */ |
165 | immap->im_intctl.ic_siexr &= | 165 | immap->im_intctl.ic_siexr &= |
diff --git a/arch/ppc/syslib/m8xx_setup.c b/arch/ppc/syslib/m8xx_setup.c index dae9af78bde1..0c4c0de7c59f 100644 --- a/arch/ppc/syslib/m8xx_setup.c +++ b/arch/ppc/syslib/m8xx_setup.c | |||
@@ -347,13 +347,13 @@ m8xx_init_IRQ(void) | |||
347 | int i; | 347 | int i; |
348 | 348 | ||
349 | for (i = SIU_IRQ_OFFSET ; i < SIU_IRQ_OFFSET + NR_SIU_INTS ; i++) | 349 | for (i = SIU_IRQ_OFFSET ; i < SIU_IRQ_OFFSET + NR_SIU_INTS ; i++) |
350 | irq_desc[i].handler = &ppc8xx_pic; | 350 | irq_desc[i].chip = &ppc8xx_pic; |
351 | 351 | ||
352 | cpm_interrupt_init(); | 352 | cpm_interrupt_init(); |
353 | 353 | ||
354 | #if defined(CONFIG_PCI) | 354 | #if defined(CONFIG_PCI) |
355 | for (i = I8259_IRQ_OFFSET ; i < I8259_IRQ_OFFSET + NR_8259_INTS ; i++) | 355 | for (i = I8259_IRQ_OFFSET ; i < I8259_IRQ_OFFSET + NR_8259_INTS ; i++) |
356 | irq_desc[i].handler = &i8259_pic; | 356 | irq_desc[i].chip = &i8259_pic; |
357 | 357 | ||
358 | i8259_pic_irq_offset = I8259_IRQ_OFFSET; | 358 | i8259_pic_irq_offset = I8259_IRQ_OFFSET; |
359 | i8259_init(0); | 359 | i8259_init(0); |
diff --git a/arch/ppc/syslib/mpc52xx_pic.c b/arch/ppc/syslib/mpc52xx_pic.c index c4406f9dc6a3..6425b5cee7db 100644 --- a/arch/ppc/syslib/mpc52xx_pic.c +++ b/arch/ppc/syslib/mpc52xx_pic.c | |||
@@ -204,9 +204,9 @@ mpc52xx_init_irq(void) | |||
204 | out_be32(&intr->main_pri1, 0); | 204 | out_be32(&intr->main_pri1, 0); |
205 | out_be32(&intr->main_pri2, 0); | 205 | out_be32(&intr->main_pri2, 0); |
206 | 206 | ||
207 | /* Initialize irq_desc[i].handler's with mpc52xx_ic. */ | 207 | /* Initialize irq_desc[i].chip's with mpc52xx_ic. */ |
208 | for (i = 0; i < NR_IRQS; i++) { | 208 | for (i = 0; i < NR_IRQS; i++) { |
209 | irq_desc[i].handler = &mpc52xx_ic; | 209 | irq_desc[i].chip = &mpc52xx_ic; |
210 | irq_desc[i].status = IRQ_LEVEL; | 210 | irq_desc[i].status = IRQ_LEVEL; |
211 | } | 211 | } |
212 | 212 | ||
diff --git a/arch/ppc/syslib/mv64360_pic.c b/arch/ppc/syslib/mv64360_pic.c index 5a19697060f0..a4244d468381 100644 --- a/arch/ppc/syslib/mv64360_pic.c +++ b/arch/ppc/syslib/mv64360_pic.c | |||
@@ -119,7 +119,7 @@ mv64360_init_irq(void) | |||
119 | /* All interrupts are level interrupts */ | 119 | /* All interrupts are level interrupts */ |
120 | for (i = mv64360_irq_base; i < (mv64360_irq_base + 96); i++) { | 120 | for (i = mv64360_irq_base; i < (mv64360_irq_base + 96); i++) { |
121 | irq_desc[i].status |= IRQ_LEVEL; | 121 | irq_desc[i].status |= IRQ_LEVEL; |
122 | irq_desc[i].handler = &mv64360_pic; | 122 | irq_desc[i].chip = &mv64360_pic; |
123 | } | 123 | } |
124 | 124 | ||
125 | if (ppc_md.progress) | 125 | if (ppc_md.progress) |
diff --git a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c index 70456c8f998c..767a0bc95817 100644 --- a/arch/ppc/syslib/open_pic.c +++ b/arch/ppc/syslib/open_pic.c | |||
@@ -373,7 +373,7 @@ void __init openpic_init(int offset) | |||
373 | OPENPIC_VEC_IPI+i+offset); | 373 | OPENPIC_VEC_IPI+i+offset); |
374 | /* IPIs are per-CPU */ | 374 | /* IPIs are per-CPU */ |
375 | irq_desc[OPENPIC_VEC_IPI+i+offset].status |= IRQ_PER_CPU; | 375 | irq_desc[OPENPIC_VEC_IPI+i+offset].status |= IRQ_PER_CPU; |
376 | irq_desc[OPENPIC_VEC_IPI+i+offset].handler = &open_pic_ipi; | 376 | irq_desc[OPENPIC_VEC_IPI+i+offset].chip = &open_pic_ipi; |
377 | } | 377 | } |
378 | #endif | 378 | #endif |
379 | 379 | ||
@@ -408,7 +408,7 @@ void __init openpic_init(int offset) | |||
408 | 408 | ||
409 | /* Init descriptors */ | 409 | /* Init descriptors */ |
410 | for (i = offset; i < NumSources + offset; i++) | 410 | for (i = offset; i < NumSources + offset; i++) |
411 | irq_desc[i].handler = &open_pic; | 411 | irq_desc[i].chip = &open_pic; |
412 | 412 | ||
413 | /* Initialize the spurious interrupt */ | 413 | /* Initialize the spurious interrupt */ |
414 | if (ppc_md.progress) ppc_md.progress("openpic: spurious",0x3bd); | 414 | if (ppc_md.progress) ppc_md.progress("openpic: spurious",0x3bd); |
@@ -615,8 +615,8 @@ void __devinit do_openpic_setup_cpu(void) | |||
615 | /* let the openpic know we want intrs. default affinity | 615 | /* let the openpic know we want intrs. default affinity |
616 | * is 0xffffffff until changed via /proc | 616 | * is 0xffffffff until changed via /proc |
617 | * That's how it's done on x86. If we want it differently, then | 617 | * That's how it's done on x86. If we want it differently, then |
618 | * we should make sure we also change the default values of irq_affinity | 618 | * we should make sure we also change the default values of |
619 | * in irq.c. | 619 | * irq_desc[].affinity in irq.c. |
620 | */ | 620 | */ |
621 | for (i = 0; i < NumSources; i++) | 621 | for (i = 0; i < NumSources; i++) |
622 | openpic_mapirq(i, msk, CPU_MASK_ALL); | 622 | openpic_mapirq(i, msk, CPU_MASK_ALL); |
diff --git a/arch/ppc/syslib/open_pic2.c b/arch/ppc/syslib/open_pic2.c index bcbe40de26fe..b8154efff6ed 100644 --- a/arch/ppc/syslib/open_pic2.c +++ b/arch/ppc/syslib/open_pic2.c | |||
@@ -290,7 +290,7 @@ void __init openpic2_init(int offset) | |||
290 | 290 | ||
291 | /* Init descriptors */ | 291 | /* Init descriptors */ |
292 | for (i = offset; i < NumSources + offset; i++) | 292 | for (i = offset; i < NumSources + offset; i++) |
293 | irq_desc[i].handler = &open_pic2; | 293 | irq_desc[i].chip = &open_pic2; |
294 | 294 | ||
295 | /* Initialize the spurious interrupt */ | 295 | /* Initialize the spurious interrupt */ |
296 | if (ppc_md.progress) ppc_md.progress("openpic2: spurious",0x3bd); | 296 | if (ppc_md.progress) ppc_md.progress("openpic2: spurious",0x3bd); |
diff --git a/arch/ppc/syslib/ppc403_pic.c b/arch/ppc/syslib/ppc403_pic.c index c46043c47225..1584c8b1229f 100644 --- a/arch/ppc/syslib/ppc403_pic.c +++ b/arch/ppc/syslib/ppc403_pic.c | |||
@@ -121,5 +121,5 @@ ppc4xx_pic_init(void) | |||
121 | ppc_md.get_irq = ppc403_pic_get_irq; | 121 | ppc_md.get_irq = ppc403_pic_get_irq; |
122 | 122 | ||
123 | for (i = 0; i < NR_IRQS; i++) | 123 | for (i = 0; i < NR_IRQS; i++) |
124 | irq_desc[i].handler = &ppc403_aic; | 124 | irq_desc[i].chip = &ppc403_aic; |
125 | } | 125 | } |
diff --git a/arch/ppc/syslib/ppc4xx_pic.c b/arch/ppc/syslib/ppc4xx_pic.c index fd9af0fc0e9f..e669c1335d47 100644 --- a/arch/ppc/syslib/ppc4xx_pic.c +++ b/arch/ppc/syslib/ppc4xx_pic.c | |||
@@ -276,7 +276,7 @@ void __init ppc4xx_pic_init(void) | |||
276 | 276 | ||
277 | /* Attach low-level handlers */ | 277 | /* Attach low-level handlers */ |
278 | for (i = 0; i < (NR_UICS << 5); ++i) { | 278 | for (i = 0; i < (NR_UICS << 5); ++i) { |
279 | irq_desc[i].handler = &__uic[i >> 5].decl; | 279 | irq_desc[i].chip = &__uic[i >> 5].decl; |
280 | if (is_level_sensitive(i)) | 280 | if (is_level_sensitive(i)) |
281 | irq_desc[i].status |= IRQ_LEVEL; | 281 | irq_desc[i].status |= IRQ_LEVEL; |
282 | } | 282 | } |
diff --git a/arch/ppc/syslib/xilinx_pic.c b/arch/ppc/syslib/xilinx_pic.c index e672b600f315..39a93dc6375b 100644 --- a/arch/ppc/syslib/xilinx_pic.c +++ b/arch/ppc/syslib/xilinx_pic.c | |||
@@ -143,7 +143,7 @@ ppc4xx_pic_init(void) | |||
143 | ppc_md.get_irq = xilinx_pic_get_irq; | 143 | ppc_md.get_irq = xilinx_pic_get_irq; |
144 | 144 | ||
145 | for (i = 0; i < NR_IRQS; ++i) { | 145 | for (i = 0; i < NR_IRQS; ++i) { |
146 | irq_desc[i].handler = &xilinx_intc; | 146 | irq_desc[i].chip = &xilinx_intc; |
147 | 147 | ||
148 | if (XPAR_INTC_0_KIND_OF_INTR & (0x00000001 << i)) | 148 | if (XPAR_INTC_0_KIND_OF_INTR & (0x00000001 << i)) |
149 | irq_desc[i].status &= ~IRQ_LEVEL; | 149 | irq_desc[i].status &= ~IRQ_LEVEL; |
diff --git a/arch/s390/appldata/appldata.h b/arch/s390/appldata/appldata.h index e806a8922bbb..71d65eb30650 100644 --- a/arch/s390/appldata/appldata.h +++ b/arch/s390/appldata/appldata.h | |||
@@ -3,9 +3,9 @@ | |||
3 | * | 3 | * |
4 | * Definitions and interface for Linux - z/VM Monitor Stream. | 4 | * Definitions and interface for Linux - z/VM Monitor Stream. |
5 | * | 5 | * |
6 | * Copyright (C) 2003 IBM Corporation, IBM Deutschland Entwicklung GmbH. | 6 | * Copyright (C) 2003,2006 IBM Corporation, IBM Deutschland Entwicklung GmbH. |
7 | * | 7 | * |
8 | * Author: Gerald Schaefer <geraldsc@de.ibm.com> | 8 | * Author: Gerald Schaefer <gerald.schaefer@de.ibm.com> |
9 | */ | 9 | */ |
10 | 10 | ||
11 | //#define APPLDATA_DEBUG /* Debug messages on/off */ | 11 | //#define APPLDATA_DEBUG /* Debug messages on/off */ |
@@ -29,6 +29,22 @@ | |||
29 | #define CTL_APPLDATA_NET_SUM 2125 | 29 | #define CTL_APPLDATA_NET_SUM 2125 |
30 | #define CTL_APPLDATA_PROC 2126 | 30 | #define CTL_APPLDATA_PROC 2126 |
31 | 31 | ||
32 | #ifndef CONFIG_64BIT | ||
33 | |||
34 | #define APPLDATA_START_INTERVAL_REC 0x00 /* Function codes for */ | ||
35 | #define APPLDATA_STOP_REC 0x01 /* DIAG 0xDC */ | ||
36 | #define APPLDATA_GEN_EVENT_RECORD 0x02 | ||
37 | #define APPLDATA_START_CONFIG_REC 0x03 | ||
38 | |||
39 | #else | ||
40 | |||
41 | #define APPLDATA_START_INTERVAL_REC 0x80 | ||
42 | #define APPLDATA_STOP_REC 0x81 | ||
43 | #define APPLDATA_GEN_EVENT_RECORD 0x82 | ||
44 | #define APPLDATA_START_CONFIG_REC 0x83 | ||
45 | |||
46 | #endif /* CONFIG_64BIT */ | ||
47 | |||
32 | #define P_INFO(x...) printk(KERN_INFO MY_PRINT_NAME " info: " x) | 48 | #define P_INFO(x...) printk(KERN_INFO MY_PRINT_NAME " info: " x) |
33 | #define P_ERROR(x...) printk(KERN_ERR MY_PRINT_NAME " error: " x) | 49 | #define P_ERROR(x...) printk(KERN_ERR MY_PRINT_NAME " error: " x) |
34 | #define P_WARNING(x...) printk(KERN_WARNING MY_PRINT_NAME " status: " x) | 50 | #define P_WARNING(x...) printk(KERN_WARNING MY_PRINT_NAME " status: " x) |
@@ -53,7 +69,11 @@ struct appldata_ops { | |||
53 | void *data; /* record data */ | 69 | void *data; /* record data */ |
54 | unsigned int size; /* size of record */ | 70 | unsigned int size; /* size of record */ |
55 | struct module *owner; /* THIS_MODULE */ | 71 | struct module *owner; /* THIS_MODULE */ |
72 | char mod_lvl[2]; /* modification level, EBCDIC */ | ||
56 | }; | 73 | }; |
57 | 74 | ||
58 | extern int appldata_register_ops(struct appldata_ops *ops); | 75 | extern int appldata_register_ops(struct appldata_ops *ops); |
59 | extern void appldata_unregister_ops(struct appldata_ops *ops); | 76 | extern void appldata_unregister_ops(struct appldata_ops *ops); |
77 | extern int appldata_diag(char record_nr, u16 function, unsigned long buffer, | ||
78 | u16 length, char *mod_lvl); | ||
79 | |||
diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index 54d35c130907..61bc44626c04 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c | |||
@@ -5,9 +5,9 @@ | |||
5 | * Exports appldata_register_ops() and appldata_unregister_ops() for the | 5 | * Exports appldata_register_ops() and appldata_unregister_ops() for the |
6 | * data gathering modules. | 6 | * data gathering modules. |
7 | * | 7 | * |
8 | * Copyright (C) 2003 IBM Corporation, IBM Deutschland Entwicklung GmbH. | 8 | * Copyright (C) 2003,2006 IBM Corporation, IBM Deutschland Entwicklung GmbH. |
9 | * | 9 | * |
10 | * Author: Gerald Schaefer <geraldsc@de.ibm.com> | 10 | * Author: Gerald Schaefer <gerald.schaefer@de.ibm.com> |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/config.h> | 13 | #include <linux/config.h> |
@@ -40,22 +40,6 @@ | |||
40 | 40 | ||
41 | #define TOD_MICRO 0x01000 /* nr. of TOD clock units | 41 | #define TOD_MICRO 0x01000 /* nr. of TOD clock units |
42 | for 1 microsecond */ | 42 | for 1 microsecond */ |
43 | #ifndef CONFIG_64BIT | ||
44 | |||
45 | #define APPLDATA_START_INTERVAL_REC 0x00 /* Function codes for */ | ||
46 | #define APPLDATA_STOP_REC 0x01 /* DIAG 0xDC */ | ||
47 | #define APPLDATA_GEN_EVENT_RECORD 0x02 | ||
48 | #define APPLDATA_START_CONFIG_REC 0x03 | ||
49 | |||
50 | #else | ||
51 | |||
52 | #define APPLDATA_START_INTERVAL_REC 0x80 | ||
53 | #define APPLDATA_STOP_REC 0x81 | ||
54 | #define APPLDATA_GEN_EVENT_RECORD 0x82 | ||
55 | #define APPLDATA_START_CONFIG_REC 0x83 | ||
56 | |||
57 | #endif /* CONFIG_64BIT */ | ||
58 | |||
59 | 43 | ||
60 | /* | 44 | /* |
61 | * Parameter list for DIAGNOSE X'DC' | 45 | * Parameter list for DIAGNOSE X'DC' |
@@ -195,8 +179,8 @@ static void appldata_work_fn(void *data) | |||
195 | * | 179 | * |
196 | * prepare parameter list, issue DIAG 0xDC | 180 | * prepare parameter list, issue DIAG 0xDC |
197 | */ | 181 | */ |
198 | static int appldata_diag(char record_nr, u16 function, unsigned long buffer, | 182 | int appldata_diag(char record_nr, u16 function, unsigned long buffer, |
199 | u16 length) | 183 | u16 length, char *mod_lvl) |
200 | { | 184 | { |
201 | unsigned long ry; | 185 | unsigned long ry; |
202 | struct appldata_product_id { | 186 | struct appldata_product_id { |
@@ -214,7 +198,7 @@ static int appldata_diag(char record_nr, u16 function, unsigned long buffer, | |||
214 | .record_nr = record_nr, | 198 | .record_nr = record_nr, |
215 | .version_nr = {0xF2, 0xF6}, /* "26" */ | 199 | .version_nr = {0xF2, 0xF6}, /* "26" */ |
216 | .release_nr = {0xF0, 0xF1}, /* "01" */ | 200 | .release_nr = {0xF0, 0xF1}, /* "01" */ |
217 | .mod_lvl = {0xF0, 0xF0}, /* "00" */ | 201 | .mod_lvl = {mod_lvl[0], mod_lvl[1]}, |
218 | }; | 202 | }; |
219 | struct appldata_parameter_list appldata_parameter_list = { | 203 | struct appldata_parameter_list appldata_parameter_list = { |
220 | .diag = 0xDC, | 204 | .diag = 0xDC, |
@@ -467,24 +451,25 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp, | |||
467 | module_put(ops->owner); | 451 | module_put(ops->owner); |
468 | return -ENODEV; | 452 | return -ENODEV; |
469 | } | 453 | } |
470 | ops->active = 1; | ||
471 | ops->callback(ops->data); // init record | 454 | ops->callback(ops->data); // init record |
472 | rc = appldata_diag(ops->record_nr, | 455 | rc = appldata_diag(ops->record_nr, |
473 | APPLDATA_START_INTERVAL_REC, | 456 | APPLDATA_START_INTERVAL_REC, |
474 | (unsigned long) ops->data, ops->size); | 457 | (unsigned long) ops->data, ops->size, |
458 | ops->mod_lvl); | ||
475 | if (rc != 0) { | 459 | if (rc != 0) { |
476 | P_ERROR("START DIAG 0xDC for %s failed, " | 460 | P_ERROR("START DIAG 0xDC for %s failed, " |
477 | "return code: %d\n", ops->name, rc); | 461 | "return code: %d\n", ops->name, rc); |
478 | module_put(ops->owner); | 462 | module_put(ops->owner); |
479 | ops->active = 0; | ||
480 | } else { | 463 | } else { |
481 | P_INFO("Monitoring %s data enabled, " | 464 | P_INFO("Monitoring %s data enabled, " |
482 | "DIAG 0xDC started.\n", ops->name); | 465 | "DIAG 0xDC started.\n", ops->name); |
466 | ops->active = 1; | ||
483 | } | 467 | } |
484 | } else if ((buf[0] == '0') && (ops->active == 1)) { | 468 | } else if ((buf[0] == '0') && (ops->active == 1)) { |
485 | ops->active = 0; | 469 | ops->active = 0; |
486 | rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC, | 470 | rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC, |
487 | (unsigned long) ops->data, ops->size); | 471 | (unsigned long) ops->data, ops->size, |
472 | ops->mod_lvl); | ||
488 | if (rc != 0) { | 473 | if (rc != 0) { |
489 | P_ERROR("STOP DIAG 0xDC for %s failed, " | 474 | P_ERROR("STOP DIAG 0xDC for %s failed, " |
490 | "return code: %d\n", ops->name, rc); | 475 | "return code: %d\n", ops->name, rc); |
@@ -633,7 +618,7 @@ appldata_offline_cpu(int cpu) | |||
633 | spin_unlock(&appldata_timer_lock); | 618 | spin_unlock(&appldata_timer_lock); |
634 | } | 619 | } |
635 | 620 | ||
636 | static int | 621 | static int __cpuinit |
637 | appldata_cpu_notify(struct notifier_block *self, | 622 | appldata_cpu_notify(struct notifier_block *self, |
638 | unsigned long action, void *hcpu) | 623 | unsigned long action, void *hcpu) |
639 | { | 624 | { |
@@ -710,7 +695,8 @@ static void __exit appldata_exit(void) | |||
710 | list_for_each(lh, &appldata_ops_list) { | 695 | list_for_each(lh, &appldata_ops_list) { |
711 | ops = list_entry(lh, struct appldata_ops, list); | 696 | ops = list_entry(lh, struct appldata_ops, list); |
712 | rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC, | 697 | rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC, |
713 | (unsigned long) ops->data, ops->size); | 698 | (unsigned long) ops->data, ops->size, |
699 | ops->mod_lvl); | ||
714 | if (rc != 0) { | 700 | if (rc != 0) { |
715 | P_ERROR("STOP DIAG 0xDC for %s failed, " | 701 | P_ERROR("STOP DIAG 0xDC for %s failed, " |
716 | "return code: %d\n", ops->name, rc); | 702 | "return code: %d\n", ops->name, rc); |
@@ -739,6 +725,7 @@ MODULE_DESCRIPTION("Linux-VM Monitor Stream, base infrastructure"); | |||
739 | 725 | ||
740 | EXPORT_SYMBOL_GPL(appldata_register_ops); | 726 | EXPORT_SYMBOL_GPL(appldata_register_ops); |
741 | EXPORT_SYMBOL_GPL(appldata_unregister_ops); | 727 | EXPORT_SYMBOL_GPL(appldata_unregister_ops); |
728 | EXPORT_SYMBOL_GPL(appldata_diag); | ||
742 | 729 | ||
743 | #ifdef MODULE | 730 | #ifdef MODULE |
744 | /* | 731 | /* |
@@ -779,7 +766,6 @@ unsigned long nr_iowait(void) | |||
779 | #endif /* MODULE */ | 766 | #endif /* MODULE */ |
780 | EXPORT_SYMBOL_GPL(si_swapinfo); | 767 | EXPORT_SYMBOL_GPL(si_swapinfo); |
781 | EXPORT_SYMBOL_GPL(nr_threads); | 768 | EXPORT_SYMBOL_GPL(nr_threads); |
782 | EXPORT_SYMBOL_GPL(avenrun); | ||
783 | EXPORT_SYMBOL_GPL(get_full_page_state); | 769 | EXPORT_SYMBOL_GPL(get_full_page_state); |
784 | EXPORT_SYMBOL_GPL(nr_running); | 770 | EXPORT_SYMBOL_GPL(nr_running); |
785 | EXPORT_SYMBOL_GPL(nr_iowait); | 771 | EXPORT_SYMBOL_GPL(nr_iowait); |
diff --git a/arch/s390/appldata/appldata_mem.c b/arch/s390/appldata/appldata_mem.c index f0e2fbed3d4c..7915a197d96d 100644 --- a/arch/s390/appldata/appldata_mem.c +++ b/arch/s390/appldata/appldata_mem.c | |||
@@ -4,9 +4,9 @@ | |||
4 | * Data gathering module for Linux-VM Monitor Stream, Stage 1. | 4 | * Data gathering module for Linux-VM Monitor Stream, Stage 1. |
5 | * Collects data related to memory management. | 5 | * Collects data related to memory management. |
6 | * | 6 | * |
7 | * Copyright (C) 2003 IBM Corporation, IBM Deutschland Entwicklung GmbH. | 7 | * Copyright (C) 2003,2006 IBM Corporation, IBM Deutschland Entwicklung GmbH. |
8 | * | 8 | * |
9 | * Author: Gerald Schaefer <geraldsc@de.ibm.com> | 9 | * Author: Gerald Schaefer <gerald.schaefer@de.ibm.com> |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/config.h> | 12 | #include <linux/config.h> |
@@ -152,6 +152,7 @@ static struct appldata_ops ops = { | |||
152 | .callback = &appldata_get_mem_data, | 152 | .callback = &appldata_get_mem_data, |
153 | .data = &appldata_mem_data, | 153 | .data = &appldata_mem_data, |
154 | .owner = THIS_MODULE, | 154 | .owner = THIS_MODULE, |
155 | .mod_lvl = {0xF0, 0xF0}, /* EBCDIC "00" */ | ||
155 | }; | 156 | }; |
156 | 157 | ||
157 | 158 | ||
diff --git a/arch/s390/appldata/appldata_net_sum.c b/arch/s390/appldata/appldata_net_sum.c index 2a4c7432db4a..39b7bdecbf05 100644 --- a/arch/s390/appldata/appldata_net_sum.c +++ b/arch/s390/appldata/appldata_net_sum.c | |||
@@ -5,9 +5,9 @@ | |||
5 | * Collects accumulated network statistics (Packets received/transmitted, | 5 | * Collects accumulated network statistics (Packets received/transmitted, |
6 | * dropped, errors, ...). | 6 | * dropped, errors, ...). |
7 | * | 7 | * |
8 | * Copyright (C) 2003 IBM Corporation, IBM Deutschland Entwicklung GmbH. | 8 | * Copyright (C) 2003,2006 IBM Corporation, IBM Deutschland Entwicklung GmbH. |
9 | * | 9 | * |
10 | * Author: Gerald Schaefer <geraldsc@de.ibm.com> | 10 | * Author: Gerald Schaefer <gerald.schaefer@de.ibm.com> |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/config.h> | 13 | #include <linux/config.h> |
@@ -152,6 +152,7 @@ static struct appldata_ops ops = { | |||
152 | .callback = &appldata_get_net_sum_data, | 152 | .callback = &appldata_get_net_sum_data, |
153 | .data = &appldata_net_sum_data, | 153 | .data = &appldata_net_sum_data, |
154 | .owner = THIS_MODULE, | 154 | .owner = THIS_MODULE, |
155 | .mod_lvl = {0xF0, 0xF0}, /* EBCDIC "00" */ | ||
155 | }; | 156 | }; |
156 | 157 | ||
157 | 158 | ||
diff --git a/arch/s390/appldata/appldata_os.c b/arch/s390/appldata/appldata_os.c index 99ddd3bf2fba..f2b44a2f1dec 100644 --- a/arch/s390/appldata/appldata_os.c +++ b/arch/s390/appldata/appldata_os.c | |||
@@ -4,9 +4,9 @@ | |||
4 | * Data gathering module for Linux-VM Monitor Stream, Stage 1. | 4 | * Data gathering module for Linux-VM Monitor Stream, Stage 1. |
5 | * Collects misc. OS related data (CPU utilization, running processes). | 5 | * Collects misc. OS related data (CPU utilization, running processes). |
6 | * | 6 | * |
7 | * Copyright (C) 2003 IBM Corporation, IBM Deutschland Entwicklung GmbH. | 7 | * Copyright (C) 2003,2006 IBM Corporation, IBM Deutschland Entwicklung GmbH. |
8 | * | 8 | * |
9 | * Author: Gerald Schaefer <geraldsc@de.ibm.com> | 9 | * Author: Gerald Schaefer <gerald.schaefer@de.ibm.com> |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/config.h> | 12 | #include <linux/config.h> |
@@ -44,11 +44,14 @@ struct appldata_os_per_cpu { | |||
44 | u32 per_cpu_system; /* ... spent in kernel mode */ | 44 | u32 per_cpu_system; /* ... spent in kernel mode */ |
45 | u32 per_cpu_idle; /* ... spent in idle mode */ | 45 | u32 per_cpu_idle; /* ... spent in idle mode */ |
46 | 46 | ||
47 | // New in 2.6 --> | 47 | /* New in 2.6 */ |
48 | u32 per_cpu_irq; /* ... spent in interrupts */ | 48 | u32 per_cpu_irq; /* ... spent in interrupts */ |
49 | u32 per_cpu_softirq; /* ... spent in softirqs */ | 49 | u32 per_cpu_softirq; /* ... spent in softirqs */ |
50 | u32 per_cpu_iowait; /* ... spent while waiting for I/O */ | 50 | u32 per_cpu_iowait; /* ... spent while waiting for I/O */ |
51 | // <-- New in 2.6 | 51 | |
52 | /* New in modification level 01 */ | ||
53 | u32 per_cpu_steal; /* ... stolen by hypervisor */ | ||
54 | u32 cpu_id; /* number of this CPU */ | ||
52 | } __attribute__((packed)); | 55 | } __attribute__((packed)); |
53 | 56 | ||
54 | struct appldata_os_data { | 57 | struct appldata_os_data { |
@@ -68,10 +71,9 @@ struct appldata_os_data { | |||
68 | u32 avenrun[3]; /* average nr. of running processes during */ | 71 | u32 avenrun[3]; /* average nr. of running processes during */ |
69 | /* the last 1, 5 and 15 minutes */ | 72 | /* the last 1, 5 and 15 minutes */ |
70 | 73 | ||
71 | // New in 2.6 --> | 74 | /* New in 2.6 */ |
72 | u32 nr_iowait; /* number of blocked threads | 75 | u32 nr_iowait; /* number of blocked threads |
73 | (waiting for I/O) */ | 76 | (waiting for I/O) */ |
74 | // <-- New in 2.6 | ||
75 | 77 | ||
76 | /* per cpu data */ | 78 | /* per cpu data */ |
77 | struct appldata_os_per_cpu os_cpu[0]; | 79 | struct appldata_os_per_cpu os_cpu[0]; |
@@ -79,6 +81,14 @@ struct appldata_os_data { | |||
79 | 81 | ||
80 | static struct appldata_os_data *appldata_os_data; | 82 | static struct appldata_os_data *appldata_os_data; |
81 | 83 | ||
84 | static struct appldata_ops ops = { | ||
85 | .ctl_nr = CTL_APPLDATA_OS, | ||
86 | .name = "os", | ||
87 | .record_nr = APPLDATA_RECORD_OS_ID, | ||
88 | .owner = THIS_MODULE, | ||
89 | .mod_lvl = {0xF0, 0xF1}, /* EBCDIC "01" */ | ||
90 | }; | ||
91 | |||
82 | 92 | ||
83 | static inline void appldata_print_debug(struct appldata_os_data *os_data) | 93 | static inline void appldata_print_debug(struct appldata_os_data *os_data) |
84 | { | 94 | { |
@@ -100,15 +110,17 @@ static inline void appldata_print_debug(struct appldata_os_data *os_data) | |||
100 | P_DEBUG("nr_cpus = %u\n", os_data->nr_cpus); | 110 | P_DEBUG("nr_cpus = %u\n", os_data->nr_cpus); |
101 | for (i = 0; i < os_data->nr_cpus; i++) { | 111 | for (i = 0; i < os_data->nr_cpus; i++) { |
102 | P_DEBUG("cpu%u : user = %u, nice = %u, system = %u, " | 112 | P_DEBUG("cpu%u : user = %u, nice = %u, system = %u, " |
103 | "idle = %u, irq = %u, softirq = %u, iowait = %u\n", | 113 | "idle = %u, irq = %u, softirq = %u, iowait = %u, " |
104 | i, | 114 | "steal = %u\n", |
115 | os_data->os_cpu[i].cpu_id, | ||
105 | os_data->os_cpu[i].per_cpu_user, | 116 | os_data->os_cpu[i].per_cpu_user, |
106 | os_data->os_cpu[i].per_cpu_nice, | 117 | os_data->os_cpu[i].per_cpu_nice, |
107 | os_data->os_cpu[i].per_cpu_system, | 118 | os_data->os_cpu[i].per_cpu_system, |
108 | os_data->os_cpu[i].per_cpu_idle, | 119 | os_data->os_cpu[i].per_cpu_idle, |
109 | os_data->os_cpu[i].per_cpu_irq, | 120 | os_data->os_cpu[i].per_cpu_irq, |
110 | os_data->os_cpu[i].per_cpu_softirq, | 121 | os_data->os_cpu[i].per_cpu_softirq, |
111 | os_data->os_cpu[i].per_cpu_iowait); | 122 | os_data->os_cpu[i].per_cpu_iowait, |
123 | os_data->os_cpu[i].per_cpu_steal); | ||
112 | } | 124 | } |
113 | 125 | ||
114 | P_DEBUG("sync_count_1 = %u\n", os_data->sync_count_1); | 126 | P_DEBUG("sync_count_1 = %u\n", os_data->sync_count_1); |
@@ -123,14 +135,13 @@ static inline void appldata_print_debug(struct appldata_os_data *os_data) | |||
123 | */ | 135 | */ |
124 | static void appldata_get_os_data(void *data) | 136 | static void appldata_get_os_data(void *data) |
125 | { | 137 | { |
126 | int i, j; | 138 | int i, j, rc; |
127 | struct appldata_os_data *os_data; | 139 | struct appldata_os_data *os_data; |
140 | unsigned int new_size; | ||
128 | 141 | ||
129 | os_data = data; | 142 | os_data = data; |
130 | os_data->sync_count_1++; | 143 | os_data->sync_count_1++; |
131 | 144 | ||
132 | os_data->nr_cpus = num_online_cpus(); | ||
133 | |||
134 | os_data->nr_threads = nr_threads; | 145 | os_data->nr_threads = nr_threads; |
135 | os_data->nr_running = nr_running(); | 146 | os_data->nr_running = nr_running(); |
136 | os_data->nr_iowait = nr_iowait(); | 147 | os_data->nr_iowait = nr_iowait(); |
@@ -154,9 +165,44 @@ static void appldata_get_os_data(void *data) | |||
154 | cputime_to_jiffies(kstat_cpu(i).cpustat.softirq); | 165 | cputime_to_jiffies(kstat_cpu(i).cpustat.softirq); |
155 | os_data->os_cpu[j].per_cpu_iowait = | 166 | os_data->os_cpu[j].per_cpu_iowait = |
156 | cputime_to_jiffies(kstat_cpu(i).cpustat.iowait); | 167 | cputime_to_jiffies(kstat_cpu(i).cpustat.iowait); |
168 | os_data->os_cpu[j].per_cpu_steal = | ||
169 | cputime_to_jiffies(kstat_cpu(i).cpustat.steal); | ||
170 | os_data->os_cpu[j].cpu_id = i; | ||
157 | j++; | 171 | j++; |
158 | } | 172 | } |
159 | 173 | ||
174 | os_data->nr_cpus = j; | ||
175 | |||
176 | new_size = sizeof(struct appldata_os_data) + | ||
177 | (os_data->nr_cpus * sizeof(struct appldata_os_per_cpu)); | ||
178 | if (ops.size != new_size) { | ||
179 | if (ops.active) { | ||
180 | rc = appldata_diag(APPLDATA_RECORD_OS_ID, | ||
181 | APPLDATA_START_INTERVAL_REC, | ||
182 | (unsigned long) ops.data, new_size, | ||
183 | ops.mod_lvl); | ||
184 | if (rc != 0) { | ||
185 | P_ERROR("os: START NEW DIAG 0xDC failed, " | ||
186 | "return code: %d, new size = %i\n", rc, | ||
187 | new_size); | ||
188 | P_INFO("os: stopping old record now\n"); | ||
189 | } else | ||
190 | P_INFO("os: new record size = %i\n", new_size); | ||
191 | |||
192 | rc = appldata_diag(APPLDATA_RECORD_OS_ID, | ||
193 | APPLDATA_STOP_REC, | ||
194 | (unsigned long) ops.data, ops.size, | ||
195 | ops.mod_lvl); | ||
196 | if (rc != 0) | ||
197 | P_ERROR("os: STOP OLD DIAG 0xDC failed, " | ||
198 | "return code: %d, old size = %i\n", rc, | ||
199 | ops.size); | ||
200 | else | ||
201 | P_INFO("os: old record size = %i stopped\n", | ||
202 | ops.size); | ||
203 | } | ||
204 | ops.size = new_size; | ||
205 | } | ||
160 | os_data->timestamp = get_clock(); | 206 | os_data->timestamp = get_clock(); |
161 | os_data->sync_count_2++; | 207 | os_data->sync_count_2++; |
162 | #ifdef APPLDATA_DEBUG | 208 | #ifdef APPLDATA_DEBUG |
@@ -165,15 +211,6 @@ static void appldata_get_os_data(void *data) | |||
165 | } | 211 | } |
166 | 212 | ||
167 | 213 | ||
168 | static struct appldata_ops ops = { | ||
169 | .ctl_nr = CTL_APPLDATA_OS, | ||
170 | .name = "os", | ||
171 | .record_nr = APPLDATA_RECORD_OS_ID, | ||
172 | .callback = &appldata_get_os_data, | ||
173 | .owner = THIS_MODULE, | ||
174 | }; | ||
175 | |||
176 | |||
177 | /* | 214 | /* |
178 | * appldata_os_init() | 215 | * appldata_os_init() |
179 | * | 216 | * |
@@ -181,26 +218,25 @@ static struct appldata_ops ops = { | |||
181 | */ | 218 | */ |
182 | static int __init appldata_os_init(void) | 219 | static int __init appldata_os_init(void) |
183 | { | 220 | { |
184 | int rc, size; | 221 | int rc, max_size; |
185 | 222 | ||
186 | size = sizeof(struct appldata_os_data) + | 223 | max_size = sizeof(struct appldata_os_data) + |
187 | (NR_CPUS * sizeof(struct appldata_os_per_cpu)); | 224 | (NR_CPUS * sizeof(struct appldata_os_per_cpu)); |
188 | if (size > APPLDATA_MAX_REC_SIZE) { | 225 | if (max_size > APPLDATA_MAX_REC_SIZE) { |
189 | P_ERROR("Size of record = %i, bigger than maximum (%i)!\n", | 226 | P_ERROR("Max. size of OS record = %i, bigger than maximum " |
190 | size, APPLDATA_MAX_REC_SIZE); | 227 | "record size (%i)\n", max_size, APPLDATA_MAX_REC_SIZE); |
191 | rc = -ENOMEM; | 228 | rc = -ENOMEM; |
192 | goto out; | 229 | goto out; |
193 | } | 230 | } |
194 | P_DEBUG("sizeof(os) = %i, sizeof(os_cpu) = %lu\n", size, | 231 | P_DEBUG("max. sizeof(os) = %i, sizeof(os_cpu) = %lu\n", max_size, |
195 | sizeof(struct appldata_os_per_cpu)); | 232 | sizeof(struct appldata_os_per_cpu)); |
196 | 233 | ||
197 | appldata_os_data = kmalloc(size, GFP_DMA); | 234 | appldata_os_data = kzalloc(max_size, GFP_DMA); |
198 | if (appldata_os_data == NULL) { | 235 | if (appldata_os_data == NULL) { |
199 | P_ERROR("No memory for %s!\n", ops.name); | 236 | P_ERROR("No memory for %s!\n", ops.name); |
200 | rc = -ENOMEM; | 237 | rc = -ENOMEM; |
201 | goto out; | 238 | goto out; |
202 | } | 239 | } |
203 | memset(appldata_os_data, 0, size); | ||
204 | 240 | ||
205 | appldata_os_data->per_cpu_size = sizeof(struct appldata_os_per_cpu); | 241 | appldata_os_data->per_cpu_size = sizeof(struct appldata_os_per_cpu); |
206 | appldata_os_data->cpu_offset = offsetof(struct appldata_os_data, | 242 | appldata_os_data->cpu_offset = offsetof(struct appldata_os_data, |
@@ -208,7 +244,7 @@ static int __init appldata_os_init(void) | |||
208 | P_DEBUG("cpu offset = %u\n", appldata_os_data->cpu_offset); | 244 | P_DEBUG("cpu offset = %u\n", appldata_os_data->cpu_offset); |
209 | 245 | ||
210 | ops.data = appldata_os_data; | 246 | ops.data = appldata_os_data; |
211 | ops.size = size; | 247 | ops.callback = &appldata_get_os_data; |
212 | rc = appldata_register_ops(&ops); | 248 | rc = appldata_register_ops(&ops); |
213 | if (rc != 0) { | 249 | if (rc != 0) { |
214 | P_ERROR("Error registering ops, rc = %i\n", rc); | 250 | P_ERROR("Error registering ops, rc = %i\n", rc); |
diff --git a/arch/s390/kernel/binfmt_elf32.c b/arch/s390/kernel/binfmt_elf32.c index 1f451c2cb071..12a6311e9838 100644 --- a/arch/s390/kernel/binfmt_elf32.c +++ b/arch/s390/kernel/binfmt_elf32.c | |||
@@ -177,11 +177,6 @@ struct elf_prpsinfo32 | |||
177 | 177 | ||
178 | #include <linux/highuid.h> | 178 | #include <linux/highuid.h> |
179 | 179 | ||
180 | #undef NEW_TO_OLD_UID | ||
181 | #undef NEW_TO_OLD_GID | ||
182 | #define NEW_TO_OLD_UID(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid) | ||
183 | #define NEW_TO_OLD_GID(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid) | ||
184 | |||
185 | #define elf_addr_t u32 | 180 | #define elf_addr_t u32 |
186 | /* | 181 | /* |
187 | #define init_elf_binfmt init_elf32_binfmt | 182 | #define init_elf_binfmt init_elf32_binfmt |
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index b2448487854c..aa8b52c2140f 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
@@ -93,13 +93,22 @@ STACK_SIZE = 1 << STACK_SHIFT | |||
93 | l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13 | 93 | l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13 |
94 | .endm | 94 | .endm |
95 | 95 | ||
96 | .macro SAVE_ALL psworg,savearea,sync | 96 | .macro SAVE_ALL_SYNC psworg,savearea |
97 | la %r12,\psworg | 97 | la %r12,\psworg |
98 | .if \sync | ||
99 | tm \psworg+1,0x01 # test problem state bit | 98 | tm \psworg+1,0x01 # test problem state bit |
100 | bz BASED(2f) # skip stack setup save | 99 | bz BASED(2f) # skip stack setup save |
101 | l %r15,__LC_KERNEL_STACK # problem state -> load ksp | 100 | l %r15,__LC_KERNEL_STACK # problem state -> load ksp |
102 | .else | 101 | #ifdef CONFIG_CHECK_STACK |
102 | b BASED(3f) | ||
103 | 2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD | ||
104 | bz BASED(stack_overflow) | ||
105 | 3: | ||
106 | #endif | ||
107 | 2: | ||
108 | .endm | ||
109 | |||
110 | .macro SAVE_ALL_ASYNC psworg,savearea | ||
111 | la %r12,\psworg | ||
103 | tm \psworg+1,0x01 # test problem state bit | 112 | tm \psworg+1,0x01 # test problem state bit |
104 | bnz BASED(1f) # from user -> load async stack | 113 | bnz BASED(1f) # from user -> load async stack |
105 | clc \psworg+4(4),BASED(.Lcritical_end) | 114 | clc \psworg+4(4),BASED(.Lcritical_end) |
@@ -115,7 +124,6 @@ STACK_SIZE = 1 << STACK_SHIFT | |||
115 | sra %r14,STACK_SHIFT | 124 | sra %r14,STACK_SHIFT |
116 | be BASED(2f) | 125 | be BASED(2f) |
117 | 1: l %r15,__LC_ASYNC_STACK | 126 | 1: l %r15,__LC_ASYNC_STACK |
118 | .endif | ||
119 | #ifdef CONFIG_CHECK_STACK | 127 | #ifdef CONFIG_CHECK_STACK |
120 | b BASED(3f) | 128 | b BASED(3f) |
121 | 2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD | 129 | 2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD |
@@ -196,7 +204,7 @@ system_call: | |||
196 | STORE_TIMER __LC_SYNC_ENTER_TIMER | 204 | STORE_TIMER __LC_SYNC_ENTER_TIMER |
197 | sysc_saveall: | 205 | sysc_saveall: |
198 | SAVE_ALL_BASE __LC_SAVE_AREA | 206 | SAVE_ALL_BASE __LC_SAVE_AREA |
199 | SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 | 207 | SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA |
200 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA | 208 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA |
201 | lh %r7,0x8a # get svc number from lowcore | 209 | lh %r7,0x8a # get svc number from lowcore |
202 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 210 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
@@ -425,7 +433,7 @@ pgm_check_handler: | |||
425 | SAVE_ALL_BASE __LC_SAVE_AREA | 433 | SAVE_ALL_BASE __LC_SAVE_AREA |
426 | tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception | 434 | tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception |
427 | bnz BASED(pgm_per) # got per exception -> special case | 435 | bnz BASED(pgm_per) # got per exception -> special case |
428 | SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 | 436 | SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA |
429 | CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA | 437 | CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA |
430 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 438 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
431 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 439 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
@@ -464,7 +472,7 @@ pgm_per: | |||
464 | # Normal per exception | 472 | # Normal per exception |
465 | # | 473 | # |
466 | pgm_per_std: | 474 | pgm_per_std: |
467 | SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 | 475 | SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA |
468 | CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA | 476 | CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA |
469 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 477 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
470 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 478 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
@@ -490,7 +498,7 @@ pgm_no_vtime2: | |||
490 | # it was a single stepped SVC that is causing all the trouble | 498 | # it was a single stepped SVC that is causing all the trouble |
491 | # | 499 | # |
492 | pgm_svcper: | 500 | pgm_svcper: |
493 | SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 | 501 | SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA |
494 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA | 502 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA |
495 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 503 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
496 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 504 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
@@ -519,7 +527,7 @@ io_int_handler: | |||
519 | STORE_TIMER __LC_ASYNC_ENTER_TIMER | 527 | STORE_TIMER __LC_ASYNC_ENTER_TIMER |
520 | stck __LC_INT_CLOCK | 528 | stck __LC_INT_CLOCK |
521 | SAVE_ALL_BASE __LC_SAVE_AREA+16 | 529 | SAVE_ALL_BASE __LC_SAVE_AREA+16 |
522 | SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+16,0 | 530 | SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+16 |
523 | CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+16 | 531 | CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+16 |
524 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 532 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
525 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 533 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
@@ -631,7 +639,7 @@ ext_int_handler: | |||
631 | STORE_TIMER __LC_ASYNC_ENTER_TIMER | 639 | STORE_TIMER __LC_ASYNC_ENTER_TIMER |
632 | stck __LC_INT_CLOCK | 640 | stck __LC_INT_CLOCK |
633 | SAVE_ALL_BASE __LC_SAVE_AREA+16 | 641 | SAVE_ALL_BASE __LC_SAVE_AREA+16 |
634 | SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16,0 | 642 | SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16 |
635 | CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16 | 643 | CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16 |
636 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 644 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
637 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 645 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
@@ -657,21 +665,31 @@ __critical_end: | |||
657 | .globl mcck_int_handler | 665 | .globl mcck_int_handler |
658 | mcck_int_handler: | 666 | mcck_int_handler: |
659 | spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer | 667 | spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer |
660 | mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA | ||
661 | lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs | 668 | lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs |
662 | SAVE_ALL_BASE __LC_SAVE_AREA+32 | 669 | SAVE_ALL_BASE __LC_SAVE_AREA+32 |
663 | la %r12,__LC_MCK_OLD_PSW | 670 | la %r12,__LC_MCK_OLD_PSW |
664 | tm __LC_MCCK_CODE,0x80 # system damage? | 671 | tm __LC_MCCK_CODE,0x80 # system damage? |
665 | bo BASED(mcck_int_main) # yes -> rest of mcck code invalid | 672 | bo BASED(mcck_int_main) # yes -> rest of mcck code invalid |
666 | tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? | ||
667 | bo BASED(0f) | ||
668 | spt __LC_LAST_UPDATE_TIMER # revalidate cpu timer | ||
669 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 673 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
670 | mvc __LC_ASYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER | 674 | mvc __LC_SAVE_AREA+52(8),__LC_ASYNC_ENTER_TIMER |
671 | mvc __LC_SYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER | 675 | mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA |
672 | mvc __LC_EXIT_TIMER(8),__LC_LAST_UPDATE_TIMER | 676 | tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? |
677 | bo BASED(1f) | ||
678 | la %r14,__LC_SYNC_ENTER_TIMER | ||
679 | clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER | ||
680 | bl BASED(0f) | ||
681 | la %r14,__LC_ASYNC_ENTER_TIMER | ||
682 | 0: clc 0(8,%r14),__LC_EXIT_TIMER | ||
683 | bl BASED(0f) | ||
684 | la %r14,__LC_EXIT_TIMER | ||
685 | 0: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER | ||
686 | bl BASED(0f) | ||
687 | la %r14,__LC_LAST_UPDATE_TIMER | ||
688 | 0: spt 0(%r14) | ||
689 | mvc __LC_ASYNC_ENTER_TIMER(8),0(%r14) | ||
690 | 1: | ||
673 | #endif | 691 | #endif |
674 | 0: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? | 692 | tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? |
675 | bno BASED(mcck_int_main) # no -> skip cleanup critical | 693 | bno BASED(mcck_int_main) # no -> skip cleanup critical |
676 | tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit | 694 | tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit |
677 | bnz BASED(mcck_int_main) # from user -> load async stack | 695 | bnz BASED(mcck_int_main) # from user -> load async stack |
@@ -691,7 +709,7 @@ mcck_int_main: | |||
691 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 709 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
692 | tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? | 710 | tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? |
693 | bno BASED(mcck_no_vtime) # no -> skip cleanup critical | 711 | bno BASED(mcck_no_vtime) # no -> skip cleanup critical |
694 | tm __LC_MCK_OLD_PSW+1,0x01 # interrupting from user ? | 712 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
695 | bz BASED(mcck_no_vtime) | 713 | bz BASED(mcck_no_vtime) |
696 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER | 714 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER |
697 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | 715 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER |
@@ -715,6 +733,20 @@ mcck_no_vtime: | |||
715 | l %r1,BASED(.Ls390_handle_mcck) | 733 | l %r1,BASED(.Ls390_handle_mcck) |
716 | basr %r14,%r1 # call machine check handler | 734 | basr %r14,%r1 # call machine check handler |
717 | mcck_return: | 735 | mcck_return: |
736 | mvc __LC_RETURN_MCCK_PSW(8),SP_PSW(%r15) # move return PSW | ||
737 | ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit | ||
738 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | ||
739 | mvc __LC_ASYNC_ENTER_TIMER(8),__LC_SAVE_AREA+52 | ||
740 | tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? | ||
741 | bno BASED(0f) | ||
742 | lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 | ||
743 | stpt __LC_EXIT_TIMER | ||
744 | lpsw __LC_RETURN_MCCK_PSW # back to caller | ||
745 | 0: | ||
746 | #endif | ||
747 | lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 | ||
748 | lpsw __LC_RETURN_MCCK_PSW # back to caller | ||
749 | |||
718 | RESTORE_ALL __LC_RETURN_MCCK_PSW,0 | 750 | RESTORE_ALL __LC_RETURN_MCCK_PSW,0 |
719 | 751 | ||
720 | #ifdef CONFIG_SMP | 752 | #ifdef CONFIG_SMP |
@@ -781,6 +813,8 @@ cleanup_table_sysc_leave: | |||
781 | .long sysc_leave + 0x80000000, sysc_work_loop + 0x80000000 | 813 | .long sysc_leave + 0x80000000, sysc_work_loop + 0x80000000 |
782 | cleanup_table_sysc_work_loop: | 814 | cleanup_table_sysc_work_loop: |
783 | .long sysc_work_loop + 0x80000000, sysc_reschedule + 0x80000000 | 815 | .long sysc_work_loop + 0x80000000, sysc_reschedule + 0x80000000 |
816 | cleanup_table_io_return: | ||
817 | .long io_return + 0x80000000, io_leave + 0x80000000 | ||
784 | cleanup_table_io_leave: | 818 | cleanup_table_io_leave: |
785 | .long io_leave + 0x80000000, io_done + 0x80000000 | 819 | .long io_leave + 0x80000000, io_done + 0x80000000 |
786 | cleanup_table_io_work_loop: | 820 | cleanup_table_io_work_loop: |
@@ -807,6 +841,11 @@ cleanup_critical: | |||
807 | clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop+4) | 841 | clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop+4) |
808 | bl BASED(cleanup_sysc_return) | 842 | bl BASED(cleanup_sysc_return) |
809 | 0: | 843 | 0: |
844 | clc 4(4,%r12),BASED(cleanup_table_io_return) | ||
845 | bl BASED(0f) | ||
846 | clc 4(4,%r12),BASED(cleanup_table_io_return+4) | ||
847 | bl BASED(cleanup_io_return) | ||
848 | 0: | ||
810 | clc 4(4,%r12),BASED(cleanup_table_io_leave) | 849 | clc 4(4,%r12),BASED(cleanup_table_io_leave) |
811 | bl BASED(0f) | 850 | bl BASED(0f) |
812 | clc 4(4,%r12),BASED(cleanup_table_io_leave+4) | 851 | clc 4(4,%r12),BASED(cleanup_table_io_leave+4) |
@@ -839,7 +878,7 @@ cleanup_system_call: | |||
839 | mvc __LC_SAVE_AREA(16),0(%r12) | 878 | mvc __LC_SAVE_AREA(16),0(%r12) |
840 | 0: st %r13,4(%r12) | 879 | 0: st %r13,4(%r12) |
841 | st %r12,__LC_SAVE_AREA+48 # argh | 880 | st %r12,__LC_SAVE_AREA+48 # argh |
842 | SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 | 881 | SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA |
843 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA | 882 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA |
844 | l %r12,__LC_SAVE_AREA+48 # argh | 883 | l %r12,__LC_SAVE_AREA+48 # argh |
845 | st %r15,12(%r12) | 884 | st %r15,12(%r12) |
@@ -980,7 +1019,6 @@ cleanup_io_leave_insn: | |||
980 | .long cleanup_critical | 1019 | .long cleanup_critical |
981 | 1020 | ||
982 | #define SYSCALL(esa,esame,emu) .long esa | 1021 | #define SYSCALL(esa,esame,emu) .long esa |
983 | .globl sys_call_table | ||
984 | sys_call_table: | 1022 | sys_call_table: |
985 | #include "syscalls.S" | 1023 | #include "syscalls.S" |
986 | #undef SYSCALL | 1024 | #undef SYSCALL |
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 2ac095bc0e25..f3222a1b2861 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S | |||
@@ -87,13 +87,22 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \ | |||
87 | larl %r13,system_call | 87 | larl %r13,system_call |
88 | .endm | 88 | .endm |
89 | 89 | ||
90 | .macro SAVE_ALL psworg,savearea,sync | 90 | .macro SAVE_ALL_SYNC psworg,savearea |
91 | la %r12,\psworg | 91 | la %r12,\psworg |
92 | .if \sync | ||
93 | tm \psworg+1,0x01 # test problem state bit | 92 | tm \psworg+1,0x01 # test problem state bit |
94 | jz 2f # skip stack setup save | 93 | jz 2f # skip stack setup save |
95 | lg %r15,__LC_KERNEL_STACK # problem state -> load ksp | 94 | lg %r15,__LC_KERNEL_STACK # problem state -> load ksp |
96 | .else | 95 | #ifdef CONFIG_CHECK_STACK |
96 | j 3f | ||
97 | 2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD | ||
98 | jz stack_overflow | ||
99 | 3: | ||
100 | #endif | ||
101 | 2: | ||
102 | .endm | ||
103 | |||
104 | .macro SAVE_ALL_ASYNC psworg,savearea | ||
105 | la %r12,\psworg | ||
97 | tm \psworg+1,0x01 # test problem state bit | 106 | tm \psworg+1,0x01 # test problem state bit |
98 | jnz 1f # from user -> load kernel stack | 107 | jnz 1f # from user -> load kernel stack |
99 | clc \psworg+8(8),BASED(.Lcritical_end) | 108 | clc \psworg+8(8),BASED(.Lcritical_end) |
@@ -108,7 +117,6 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \ | |||
108 | srag %r14,%r14,STACK_SHIFT | 117 | srag %r14,%r14,STACK_SHIFT |
109 | jz 2f | 118 | jz 2f |
110 | 1: lg %r15,__LC_ASYNC_STACK # load async stack | 119 | 1: lg %r15,__LC_ASYNC_STACK # load async stack |
111 | .endif | ||
112 | #ifdef CONFIG_CHECK_STACK | 120 | #ifdef CONFIG_CHECK_STACK |
113 | j 3f | 121 | j 3f |
114 | 2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD | 122 | 2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD |
@@ -187,7 +195,7 @@ system_call: | |||
187 | STORE_TIMER __LC_SYNC_ENTER_TIMER | 195 | STORE_TIMER __LC_SYNC_ENTER_TIMER |
188 | sysc_saveall: | 196 | sysc_saveall: |
189 | SAVE_ALL_BASE __LC_SAVE_AREA | 197 | SAVE_ALL_BASE __LC_SAVE_AREA |
190 | SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 | 198 | SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA |
191 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA | 199 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA |
192 | llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore | 200 | llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore |
193 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 201 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
@@ -446,7 +454,7 @@ pgm_check_handler: | |||
446 | SAVE_ALL_BASE __LC_SAVE_AREA | 454 | SAVE_ALL_BASE __LC_SAVE_AREA |
447 | tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception | 455 | tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception |
448 | jnz pgm_per # got per exception -> special case | 456 | jnz pgm_per # got per exception -> special case |
449 | SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 | 457 | SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA |
450 | CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA | 458 | CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA |
451 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 459 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
452 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 460 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
@@ -485,7 +493,7 @@ pgm_per: | |||
485 | # Normal per exception | 493 | # Normal per exception |
486 | # | 494 | # |
487 | pgm_per_std: | 495 | pgm_per_std: |
488 | SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 | 496 | SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA |
489 | CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA | 497 | CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA |
490 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 498 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
491 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 499 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
@@ -511,7 +519,7 @@ pgm_no_vtime2: | |||
511 | # it was a single stepped SVC that is causing all the trouble | 519 | # it was a single stepped SVC that is causing all the trouble |
512 | # | 520 | # |
513 | pgm_svcper: | 521 | pgm_svcper: |
514 | SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 | 522 | SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA |
515 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA | 523 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA |
516 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 524 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
517 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 525 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
@@ -539,7 +547,7 @@ io_int_handler: | |||
539 | STORE_TIMER __LC_ASYNC_ENTER_TIMER | 547 | STORE_TIMER __LC_ASYNC_ENTER_TIMER |
540 | stck __LC_INT_CLOCK | 548 | stck __LC_INT_CLOCK |
541 | SAVE_ALL_BASE __LC_SAVE_AREA+32 | 549 | SAVE_ALL_BASE __LC_SAVE_AREA+32 |
542 | SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+32,0 | 550 | SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+32 |
543 | CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+32 | 551 | CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+32 |
544 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 552 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
545 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 553 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
@@ -647,7 +655,7 @@ ext_int_handler: | |||
647 | STORE_TIMER __LC_ASYNC_ENTER_TIMER | 655 | STORE_TIMER __LC_ASYNC_ENTER_TIMER |
648 | stck __LC_INT_CLOCK | 656 | stck __LC_INT_CLOCK |
649 | SAVE_ALL_BASE __LC_SAVE_AREA+32 | 657 | SAVE_ALL_BASE __LC_SAVE_AREA+32 |
650 | SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32,0 | 658 | SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32 |
651 | CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32 | 659 | CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32 |
652 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 660 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
653 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 661 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
@@ -672,21 +680,32 @@ __critical_end: | |||
672 | mcck_int_handler: | 680 | mcck_int_handler: |
673 | la %r1,4095 # revalidate r1 | 681 | la %r1,4095 # revalidate r1 |
674 | spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer | 682 | spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer |
675 | mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA-4095(%r1) | ||
676 | lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs | 683 | lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs |
677 | SAVE_ALL_BASE __LC_SAVE_AREA+64 | 684 | SAVE_ALL_BASE __LC_SAVE_AREA+64 |
678 | la %r12,__LC_MCK_OLD_PSW | 685 | la %r12,__LC_MCK_OLD_PSW |
679 | tm __LC_MCCK_CODE,0x80 # system damage? | 686 | tm __LC_MCCK_CODE,0x80 # system damage? |
680 | jo mcck_int_main # yes -> rest of mcck code invalid | 687 | jo mcck_int_main # yes -> rest of mcck code invalid |
681 | tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? | ||
682 | jo 0f | ||
683 | spt __LC_LAST_UPDATE_TIMER | ||
684 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 688 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
685 | mvc __LC_ASYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER | 689 | la %r14,4095 |
686 | mvc __LC_SYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER | 690 | mvc __LC_SAVE_AREA+104(8),__LC_ASYNC_ENTER_TIMER |
687 | mvc __LC_EXIT_TIMER(8),__LC_LAST_UPDATE_TIMER | 691 | mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA-4095(%r14) |
692 | tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? | ||
693 | jo 1f | ||
694 | la %r14,__LC_SYNC_ENTER_TIMER | ||
695 | clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER | ||
696 | jl 0f | ||
697 | la %r14,__LC_ASYNC_ENTER_TIMER | ||
698 | 0: clc 0(8,%r14),__LC_EXIT_TIMER | ||
699 | jl 0f | ||
700 | la %r14,__LC_EXIT_TIMER | ||
701 | 0: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER | ||
702 | jl 0f | ||
703 | la %r14,__LC_LAST_UPDATE_TIMER | ||
704 | 0: spt 0(%r14) | ||
705 | mvc __LC_ASYNC_ENTER_TIMER(8),0(%r14) | ||
706 | 1: | ||
688 | #endif | 707 | #endif |
689 | 0: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? | 708 | tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? |
690 | jno mcck_int_main # no -> skip cleanup critical | 709 | jno mcck_int_main # no -> skip cleanup critical |
691 | tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit | 710 | tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit |
692 | jnz mcck_int_main # from user -> load kernel stack | 711 | jnz mcck_int_main # from user -> load kernel stack |
@@ -705,7 +724,7 @@ mcck_int_main: | |||
705 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 724 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
706 | tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? | 725 | tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? |
707 | jno mcck_no_vtime # no -> no timer update | 726 | jno mcck_no_vtime # no -> no timer update |
708 | tm __LC_MCK_OLD_PSW+1,0x01 # interrupting from user ? | 727 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
709 | jz mcck_no_vtime | 728 | jz mcck_no_vtime |
710 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER | 729 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER |
711 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | 730 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER |
@@ -727,7 +746,17 @@ mcck_no_vtime: | |||
727 | jno mcck_return | 746 | jno mcck_return |
728 | brasl %r14,s390_handle_mcck | 747 | brasl %r14,s390_handle_mcck |
729 | mcck_return: | 748 | mcck_return: |
730 | RESTORE_ALL __LC_RETURN_MCCK_PSW,0 | 749 | mvc __LC_RETURN_MCCK_PSW(16),SP_PSW(%r15) # move return PSW |
750 | ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit | ||
751 | lmg %r0,%r15,SP_R0(%r15) # load gprs 0-15 | ||
752 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | ||
753 | mvc __LC_ASYNC_ENTER_TIMER(8),__LC_SAVE_AREA+104 | ||
754 | tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? | ||
755 | jno 0f | ||
756 | stpt __LC_EXIT_TIMER | ||
757 | 0: | ||
758 | #endif | ||
759 | lpswe __LC_RETURN_MCCK_PSW # back to caller | ||
731 | 760 | ||
732 | #ifdef CONFIG_SMP | 761 | #ifdef CONFIG_SMP |
733 | /* | 762 | /* |
@@ -789,6 +818,8 @@ cleanup_table_sysc_leave: | |||
789 | .quad sysc_leave, sysc_work_loop | 818 | .quad sysc_leave, sysc_work_loop |
790 | cleanup_table_sysc_work_loop: | 819 | cleanup_table_sysc_work_loop: |
791 | .quad sysc_work_loop, sysc_reschedule | 820 | .quad sysc_work_loop, sysc_reschedule |
821 | cleanup_table_io_return: | ||
822 | .quad io_return, io_leave | ||
792 | cleanup_table_io_leave: | 823 | cleanup_table_io_leave: |
793 | .quad io_leave, io_done | 824 | .quad io_leave, io_done |
794 | cleanup_table_io_work_loop: | 825 | cleanup_table_io_work_loop: |
@@ -815,6 +846,11 @@ cleanup_critical: | |||
815 | clc 8(8,%r12),BASED(cleanup_table_sysc_work_loop+8) | 846 | clc 8(8,%r12),BASED(cleanup_table_sysc_work_loop+8) |
816 | jl cleanup_sysc_return | 847 | jl cleanup_sysc_return |
817 | 0: | 848 | 0: |
849 | clc 8(8,%r12),BASED(cleanup_table_io_return) | ||
850 | jl 0f | ||
851 | clc 8(8,%r12),BASED(cleanup_table_io_return+8) | ||
852 | jl cleanup_io_return | ||
853 | 0: | ||
818 | clc 8(8,%r12),BASED(cleanup_table_io_leave) | 854 | clc 8(8,%r12),BASED(cleanup_table_io_leave) |
819 | jl 0f | 855 | jl 0f |
820 | clc 8(8,%r12),BASED(cleanup_table_io_leave+8) | 856 | clc 8(8,%r12),BASED(cleanup_table_io_leave+8) |
@@ -847,7 +883,7 @@ cleanup_system_call: | |||
847 | mvc __LC_SAVE_AREA(32),0(%r12) | 883 | mvc __LC_SAVE_AREA(32),0(%r12) |
848 | 0: stg %r13,8(%r12) | 884 | 0: stg %r13,8(%r12) |
849 | stg %r12,__LC_SAVE_AREA+96 # argh | 885 | stg %r12,__LC_SAVE_AREA+96 # argh |
850 | SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 | 886 | SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA |
851 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA | 887 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA |
852 | lg %r12,__LC_SAVE_AREA+96 # argh | 888 | lg %r12,__LC_SAVE_AREA+96 # argh |
853 | stg %r15,24(%r12) | 889 | stg %r15,24(%r12) |
@@ -957,7 +993,6 @@ cleanup_io_leave_insn: | |||
957 | .quad __critical_end | 993 | .quad __critical_end |
958 | 994 | ||
959 | #define SYSCALL(esa,esame,emu) .long esame | 995 | #define SYSCALL(esa,esame,emu) .long esame |
960 | .globl sys_call_table | ||
961 | sys_call_table: | 996 | sys_call_table: |
962 | #include "syscalls.S" | 997 | #include "syscalls.S" |
963 | #undef SYSCALL | 998 | #undef SYSCALL |
@@ -965,7 +1000,6 @@ sys_call_table: | |||
965 | #ifdef CONFIG_COMPAT | 1000 | #ifdef CONFIG_COMPAT |
966 | 1001 | ||
967 | #define SYSCALL(esa,esame,emu) .long emu | 1002 | #define SYSCALL(esa,esame,emu) .long emu |
968 | .globl sys_call_table_emu | ||
969 | sys_call_table_emu: | 1003 | sys_call_table_emu: |
970 | #include "syscalls.S" | 1004 | #include "syscalls.S" |
971 | #undef SYSCALL | 1005 | #undef SYSCALL |
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S index ea88d066bf04..538c82da49b1 100644 --- a/arch/s390/kernel/head.S +++ b/arch/s390/kernel/head.S | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * arch/s390/kernel/head.S | 2 | * arch/s390/kernel/head.S |
3 | * | 3 | * |
4 | * (C) Copyright IBM Corp. 1999, 2005 | 4 | * Copyright (C) IBM Corp. 1999,2006 |
5 | * | 5 | * |
6 | * Author(s): Hartmut Penner <hp@de.ibm.com> | 6 | * Author(s): Hartmut Penner <hp@de.ibm.com> |
7 | * Martin Schwidefsky <schwidefsky@de.ibm.com> | 7 | * Martin Schwidefsky <schwidefsky@de.ibm.com> |
@@ -482,24 +482,23 @@ start: | |||
482 | 482 | ||
483 | .macro GET_IPL_DEVICE | 483 | .macro GET_IPL_DEVICE |
484 | .Lget_ipl_device: | 484 | .Lget_ipl_device: |
485 | basr %r12,0 | 485 | l %r1,0xb8 # get sid |
486 | .LGID: l %r1,0xb8 # get sid | ||
487 | sll %r1,15 # test if subchannel is enabled | 486 | sll %r1,15 # test if subchannel is enabled |
488 | srl %r1,31 | 487 | srl %r1,31 |
489 | ltr %r1,%r1 | 488 | ltr %r1,%r1 |
490 | bz 0(%r14) # subchannel disabled | 489 | bz 2f-.LPG1(%r13) # subchannel disabled |
491 | l %r1,0xb8 | 490 | l %r1,0xb8 |
492 | la %r5,.Lipl_schib-.LGID(%r12) | 491 | la %r5,.Lipl_schib-.LPG1(%r13) |
493 | stsch 0(%r5) # get schib of subchannel | 492 | stsch 0(%r5) # get schib of subchannel |
494 | bnz 0(%r14) # schib not available | 493 | bnz 2f-.LPG1(%r13) # schib not available |
495 | tm 5(%r5),0x01 # devno valid? | 494 | tm 5(%r5),0x01 # devno valid? |
496 | bno 0(%r14) | 495 | bno 2f-.LPG1(%r13) |
497 | la %r6,ipl_parameter_flags-.LGID(%r12) | 496 | la %r6,ipl_parameter_flags-.LPG1(%r13) |
498 | oi 3(%r6),0x01 # set flag | 497 | oi 3(%r6),0x01 # set flag |
499 | la %r2,ipl_devno-.LGID(%r12) | 498 | la %r2,ipl_devno-.LPG1(%r13) |
500 | mvc 0(2,%r2),6(%r5) # store devno | 499 | mvc 0(2,%r2),6(%r5) # store devno |
501 | tm 4(%r5),0x80 # qdio capable device? | 500 | tm 4(%r5),0x80 # qdio capable device? |
502 | bno 0(%r14) | 501 | bno 2f-.LPG1(%r13) |
503 | oi 3(%r6),0x02 # set flag | 502 | oi 3(%r6),0x02 # set flag |
504 | 503 | ||
505 | # copy ipl parameters | 504 | # copy ipl parameters |
@@ -523,7 +522,7 @@ start: | |||
523 | ar %r2,%r1 | 522 | ar %r2,%r1 |
524 | sr %r0,%r4 | 523 | sr %r0,%r4 |
525 | jne 1b | 524 | jne 1b |
526 | b 0(%r14) | 525 | b 2f-.LPG1(%r13) |
527 | 526 | ||
528 | .align 4 | 527 | .align 4 |
529 | .Lipl_schib: | 528 | .Lipl_schib: |
@@ -537,6 +536,7 @@ ipl_parameter_flags: | |||
537 | .globl ipl_devno | 536 | .globl ipl_devno |
538 | ipl_devno: | 537 | ipl_devno: |
539 | .word 0 | 538 | .word 0 |
539 | 2: | ||
540 | .endm | 540 | .endm |
541 | 541 | ||
542 | #ifdef CONFIG_64BIT | 542 | #ifdef CONFIG_64BIT |
diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S index 2d3b089bfb83..d00de17b3778 100644 --- a/arch/s390/kernel/head31.S +++ b/arch/s390/kernel/head31.S | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * arch/s390/kernel/head31.S | 2 | * arch/s390/kernel/head31.S |
3 | * | 3 | * |
4 | * (C) Copyright IBM Corp. 2005 | 4 | * Copyright (C) IBM Corp. 2005,2006 |
5 | * | 5 | * |
6 | * Author(s): Hartmut Penner <hp@de.ibm.com> | 6 | * Author(s): Hartmut Penner <hp@de.ibm.com> |
7 | * Martin Schwidefsky <schwidefsky@de.ibm.com> | 7 | * Martin Schwidefsky <schwidefsky@de.ibm.com> |
@@ -16,12 +16,31 @@ | |||
16 | # or linload or SALIPL | 16 | # or linload or SALIPL |
17 | # | 17 | # |
18 | .org 0x10000 | 18 | .org 0x10000 |
19 | startup:basr %r13,0 # get base | 19 | startup:basr %r13,0 # get base |
20 | .LPG1: l %r1, .Lget_ipl_device_addr-.LPG1(%r13) | 20 | .LPG0: l %r13,0f-.LPG0(%r13) |
21 | basr %r14, %r1 | 21 | b 0(%r13) |
22 | 0: .long startup_continue | ||
23 | |||
24 | # | ||
25 | # params at 10400 (setup.h) | ||
26 | # | ||
27 | .org PARMAREA | ||
28 | .long 0,0 # IPL_DEVICE | ||
29 | .long 0,RAMDISK_ORIGIN # INITRD_START | ||
30 | .long 0,RAMDISK_SIZE # INITRD_SIZE | ||
31 | |||
32 | .org COMMAND_LINE | ||
33 | .byte "root=/dev/ram0 ro" | ||
34 | .byte 0 | ||
35 | |||
36 | .org 0x11000 | ||
37 | |||
38 | startup_continue: | ||
39 | basr %r13,0 # get base | ||
40 | .LPG1: GET_IPL_DEVICE | ||
22 | lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers | 41 | lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers |
23 | la %r12,_pstart-.LPG1(%r13) # pointer to parameter area | 42 | l %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area |
24 | # move IPL device to lowcore | 43 | # move IPL device to lowcore |
25 | mvc __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12) | 44 | mvc __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12) |
26 | 45 | ||
27 | # | 46 | # |
@@ -51,8 +70,8 @@ startup:basr %r13,0 # get base | |||
51 | a %r1,__LC_EXT_NEW_PSW+4 # set handler | 70 | a %r1,__LC_EXT_NEW_PSW+4 # set handler |
52 | st %r1,__LC_EXT_NEW_PSW+4 | 71 | st %r1,__LC_EXT_NEW_PSW+4 |
53 | 72 | ||
54 | la %r4,_pstart-.LPG1(%r13) # %r4 is our index for sccb stuff | 73 | l %r4,.Lsccbaddr-.LPG1(%r13) # %r4 is our index for sccb stuff |
55 | la %r1, .Lsccb-PARMAREA(%r4) # our sccb | 74 | lr %r1,%r4 # our sccb |
56 | .insn rre,0xb2200000,%r2,%r1 # service call | 75 | .insn rre,0xb2200000,%r2,%r1 # service call |
57 | ipm %r1 | 76 | ipm %r1 |
58 | srl %r1,28 # get cc code | 77 | srl %r1,28 # get cc code |
@@ -63,7 +82,7 @@ startup:basr %r13,0 # get base | |||
63 | be .Lservicecall-.LPG1(%r13) | 82 | be .Lservicecall-.LPG1(%r13) |
64 | lpsw .Lwaitsclp-.LPG1(%r13) | 83 | lpsw .Lwaitsclp-.LPG1(%r13) |
65 | .Lsclph: | 84 | .Lsclph: |
66 | lh %r1,.Lsccbr-PARMAREA(%r4) | 85 | lh %r1,.Lsccbr-.Lsccb(%r4) |
67 | chi %r1,0x10 # 0x0010 is the sucess code | 86 | chi %r1,0x10 # 0x0010 is the sucess code |
68 | je .Lprocsccb # let's process the sccb | 87 | je .Lprocsccb # let's process the sccb |
69 | chi %r1,0x1f0 | 88 | chi %r1,0x1f0 |
@@ -74,7 +93,7 @@ startup:basr %r13,0 # get base | |||
74 | b .Lservicecall-.LPG1(%r13) | 93 | b .Lservicecall-.LPG1(%r13) |
75 | .Lprocsccb: | 94 | .Lprocsccb: |
76 | lhi %r1,0 | 95 | lhi %r1,0 |
77 | icm %r1,3,.Lscpincr1-PARMAREA(%r4) # use this one if != 0 | 96 | icm %r1,3,.Lscpincr1-.Lsccb(%r4) # use this one if != 0 |
78 | jnz .Lscnd | 97 | jnz .Lscnd |
79 | lhi %r1,0x800 # otherwise report 2GB | 98 | lhi %r1,0x800 # otherwise report 2GB |
80 | .Lscnd: | 99 | .Lscnd: |
@@ -84,10 +103,10 @@ startup:basr %r13,0 # get base | |||
84 | lr %r1,%r3 | 103 | lr %r1,%r3 |
85 | .Lno2gb: | 104 | .Lno2gb: |
86 | xr %r3,%r3 # same logic | 105 | xr %r3,%r3 # same logic |
87 | ic %r3,.Lscpa1-PARMAREA(%r4) | 106 | ic %r3,.Lscpa1-.Lsccb(%r4) |
88 | chi %r3,0x00 | 107 | chi %r3,0x00 |
89 | jne .Lcompmem | 108 | jne .Lcompmem |
90 | l %r3,.Lscpa2-PARMAREA(%r13) | 109 | l %r3,.Lscpa2-.Lsccb(%r4) |
91 | .Lcompmem: | 110 | .Lcompmem: |
92 | mr %r2,%r1 # mem in MB on 128-bit | 111 | mr %r2,%r1 # mem in MB on 128-bit |
93 | l %r1,.Lonemb-.LPG1(%r13) | 112 | l %r1,.Lonemb-.LPG1(%r13) |
@@ -95,8 +114,6 @@ startup:basr %r13,0 # get base | |||
95 | b .Lfchunk-.LPG1(%r13) | 114 | b .Lfchunk-.LPG1(%r13) |
96 | 115 | ||
97 | .align 4 | 116 | .align 4 |
98 | .Lget_ipl_device_addr: | ||
99 | .long .Lget_ipl_device | ||
100 | .Lpmask: | 117 | .Lpmask: |
101 | .byte 0 | 118 | .byte 0 |
102 | .align 8 | 119 | .align 8 |
@@ -242,6 +259,8 @@ startup:basr %r13,0 # get base | |||
242 | .long 0 # cr13: home space segment table | 259 | .long 0 # cr13: home space segment table |
243 | .long 0xc0000000 # cr14: machine check handling off | 260 | .long 0xc0000000 # cr14: machine check handling off |
244 | .long 0 # cr15: linkage stack operations | 261 | .long 0 # cr15: linkage stack operations |
262 | .Lduct: .long 0,0,0,0,0,0,0,0 | ||
263 | .long 0,0,0,0,0,0,0,0 | ||
245 | .Lpcmem:.long 0x00080000,0x80000000 + .Lchkmem | 264 | .Lpcmem:.long 0x00080000,0x80000000 + .Lchkmem |
246 | .Lpcfpu:.long 0x00080000,0x80000000 + .Lchkfpu | 265 | .Lpcfpu:.long 0x00080000,0x80000000 + .Lchkfpu |
247 | .Lpccsp:.long 0x00080000,0x80000000 + .Lchkcsp | 266 | .Lpccsp:.long 0x00080000,0x80000000 + .Lchkcsp |
@@ -252,25 +271,9 @@ startup:basr %r13,0 # get base | |||
252 | .Lmflags:.long machine_flags | 271 | .Lmflags:.long machine_flags |
253 | .Lbss_bgn: .long __bss_start | 272 | .Lbss_bgn: .long __bss_start |
254 | .Lbss_end: .long _end | 273 | .Lbss_end: .long _end |
255 | 274 | .Lparmaddr: .long PARMAREA | |
256 | .org PARMAREA-64 | 275 | .Lsccbaddr: .long .Lsccb |
257 | .Lduct: .long 0,0,0,0,0,0,0,0 | 276 | .align 4096 |
258 | .long 0,0,0,0,0,0,0,0 | ||
259 | |||
260 | # | ||
261 | # params at 10400 (setup.h) | ||
262 | # | ||
263 | .org PARMAREA | ||
264 | .global _pstart | ||
265 | _pstart: | ||
266 | .long 0,0 # IPL_DEVICE | ||
267 | .long 0,RAMDISK_ORIGIN # INITRD_START | ||
268 | .long 0,RAMDISK_SIZE # INITRD_SIZE | ||
269 | |||
270 | .org COMMAND_LINE | ||
271 | .byte "root=/dev/ram0 ro" | ||
272 | .byte 0 | ||
273 | .org 0x11000 | ||
274 | .Lsccb: | 277 | .Lsccb: |
275 | .hword 0x1000 # length, one page | 278 | .hword 0x1000 # length, one page |
276 | .byte 0x00,0x00,0x00 | 279 | .byte 0x00,0x00,0x00 |
@@ -287,18 +290,14 @@ _pstart: | |||
287 | .Lscpincr2: | 290 | .Lscpincr2: |
288 | .quad 0x00 | 291 | .quad 0x00 |
289 | .fill 3984,1,0 | 292 | .fill 3984,1,0 |
290 | .org 0x12000 | 293 | .align 4096 |
291 | .global _pend | ||
292 | _pend: | ||
293 | |||
294 | GET_IPL_DEVICE | ||
295 | 294 | ||
296 | #ifdef CONFIG_SHARED_KERNEL | 295 | #ifdef CONFIG_SHARED_KERNEL |
297 | .org 0x100000 | 296 | .org 0x100000 |
298 | #endif | 297 | #endif |
299 | 298 | ||
300 | # | 299 | # |
301 | # startup-code, running in virtual mode | 300 | # startup-code, running in absolute addressing mode |
302 | # | 301 | # |
303 | .globl _stext | 302 | .globl _stext |
304 | _stext: basr %r13,0 # get base | 303 | _stext: basr %r13,0 # get base |
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index f08c06f45d5c..47744fcca930 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * arch/s390/kernel/head64.S | 2 | * arch/s390/kernel/head64.S |
3 | * | 3 | * |
4 | * (C) Copyright IBM Corp. 1999,2005 | 4 | * Copyright (C) IBM Corp. 1999,2006 |
5 | * | 5 | * |
6 | * Author(s): Hartmut Penner <hp@de.ibm.com> | 6 | * Author(s): Hartmut Penner <hp@de.ibm.com> |
7 | * Martin Schwidefsky <schwidefsky@de.ibm.com> | 7 | * Martin Schwidefsky <schwidefsky@de.ibm.com> |
@@ -15,18 +15,37 @@ | |||
15 | # this is called either by the ipl loader or directly by PSW restart | 15 | # this is called either by the ipl loader or directly by PSW restart |
16 | # or linload or SALIPL | 16 | # or linload or SALIPL |
17 | # | 17 | # |
18 | .org 0x10000 | 18 | .org 0x10000 |
19 | startup:basr %r13,0 # get base | 19 | startup:basr %r13,0 # get base |
20 | .LPG0: l %r13,0f-.LPG0(%r13) | ||
21 | b 0(%r13) | ||
22 | 0: .long startup_continue | ||
23 | |||
24 | # | ||
25 | # params at 10400 (setup.h) | ||
26 | # | ||
27 | .org PARMAREA | ||
28 | .quad 0 # IPL_DEVICE | ||
29 | .quad RAMDISK_ORIGIN # INITRD_START | ||
30 | .quad RAMDISK_SIZE # INITRD_SIZE | ||
31 | |||
32 | .org COMMAND_LINE | ||
33 | .byte "root=/dev/ram0 ro" | ||
34 | .byte 0 | ||
35 | |||
36 | .org 0x11000 | ||
37 | |||
38 | startup_continue: | ||
39 | basr %r13,0 # get base | ||
20 | .LPG1: sll %r13,1 # remove high order bit | 40 | .LPG1: sll %r13,1 # remove high order bit |
21 | srl %r13,1 | 41 | srl %r13,1 |
22 | l %r1,.Lget_ipl_device_addr-.LPG1(%r13) | 42 | GET_IPL_DEVICE |
23 | basr %r14,%r1 | ||
24 | lhi %r1,1 # mode 1 = esame | 43 | lhi %r1,1 # mode 1 = esame |
25 | slr %r0,%r0 # set cpuid to zero | 44 | slr %r0,%r0 # set cpuid to zero |
26 | sigp %r1,%r0,0x12 # switch to esame mode | 45 | sigp %r1,%r0,0x12 # switch to esame mode |
27 | sam64 # switch to 64 bit mode | 46 | sam64 # switch to 64 bit mode |
28 | lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers | 47 | lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers |
29 | larl %r12,_pstart # pointer to parameter area | 48 | lg %r12,.Lparmaddr-.LPG1(%r13)# pointer to parameter area |
30 | # move IPL device to lowcore | 49 | # move IPL device to lowcore |
31 | mvc __LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12) | 50 | mvc __LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12) |
32 | 51 | ||
@@ -55,8 +74,8 @@ startup:basr %r13,0 # get base | |||
55 | larl %r1,.Lsclph | 74 | larl %r1,.Lsclph |
56 | stg %r1,__LC_EXT_NEW_PSW+8 # set handler | 75 | stg %r1,__LC_EXT_NEW_PSW+8 # set handler |
57 | 76 | ||
58 | larl %r4,_pstart # %r4 is our index for sccb stuff | 77 | larl %r4,.Lsccb # %r4 is our index for sccb stuff |
59 | la %r1,.Lsccb-PARMAREA(%r4) # our sccb | 78 | lgr %r1,%r4 # our sccb |
60 | .insn rre,0xb2200000,%r2,%r1 # service call | 79 | .insn rre,0xb2200000,%r2,%r1 # service call |
61 | ipm %r1 | 80 | ipm %r1 |
62 | srl %r1,28 # get cc code | 81 | srl %r1,28 # get cc code |
@@ -67,7 +86,7 @@ startup:basr %r13,0 # get base | |||
67 | be .Lservicecall-.LPG1(%r13) | 86 | be .Lservicecall-.LPG1(%r13) |
68 | lpswe .Lwaitsclp-.LPG1(%r13) | 87 | lpswe .Lwaitsclp-.LPG1(%r13) |
69 | .Lsclph: | 88 | .Lsclph: |
70 | lh %r1,.Lsccbr-PARMAREA(%r4) | 89 | lh %r1,.Lsccbr-.Lsccb(%r4) |
71 | chi %r1,0x10 # 0x0010 is the sucess code | 90 | chi %r1,0x10 # 0x0010 is the sucess code |
72 | je .Lprocsccb # let's process the sccb | 91 | je .Lprocsccb # let's process the sccb |
73 | chi %r1,0x1f0 | 92 | chi %r1,0x1f0 |
@@ -78,15 +97,15 @@ startup:basr %r13,0 # get base | |||
78 | b .Lservicecall-.LPG1(%r13) | 97 | b .Lservicecall-.LPG1(%r13) |
79 | .Lprocsccb: | 98 | .Lprocsccb: |
80 | lghi %r1,0 | 99 | lghi %r1,0 |
81 | icm %r1,3,.Lscpincr1-PARMAREA(%r4) # use this one if != 0 | 100 | icm %r1,3,.Lscpincr1-.Lsccb(%r4) # use this one if != 0 |
82 | jnz .Lscnd | 101 | jnz .Lscnd |
83 | lg %r1,.Lscpincr2-PARMAREA(%r4) # otherwise use this one | 102 | lg %r1,.Lscpincr2-.Lsccb(%r4) # otherwise use this one |
84 | .Lscnd: | 103 | .Lscnd: |
85 | xr %r3,%r3 # same logic | 104 | xr %r3,%r3 # same logic |
86 | ic %r3,.Lscpa1-PARMAREA(%r4) | 105 | ic %r3,.Lscpa1-.Lsccb(%r4) |
87 | chi %r3,0x00 | 106 | chi %r3,0x00 |
88 | jne .Lcompmem | 107 | jne .Lcompmem |
89 | l %r3,.Lscpa2-PARMAREA(%r13) | 108 | l %r3,.Lscpa2-.Lsccb(%r4) |
90 | .Lcompmem: | 109 | .Lcompmem: |
91 | mlgr %r2,%r1 # mem in MB on 128-bit | 110 | mlgr %r2,%r1 # mem in MB on 128-bit |
92 | l %r1,.Lonemb-.LPG1(%r13) | 111 | l %r1,.Lonemb-.LPG1(%r13) |
@@ -94,8 +113,6 @@ startup:basr %r13,0 # get base | |||
94 | b .Lfchunk-.LPG1(%r13) | 113 | b .Lfchunk-.LPG1(%r13) |
95 | 114 | ||
96 | .align 4 | 115 | .align 4 |
97 | .Lget_ipl_device_addr: | ||
98 | .long .Lget_ipl_device | ||
99 | .Lpmask: | 116 | .Lpmask: |
100 | .byte 0 | 117 | .byte 0 |
101 | .align 8 | 118 | .align 8 |
@@ -242,29 +259,16 @@ startup:basr %r13,0 # get base | |||
242 | .quad 0 # cr13: home space segment table | 259 | .quad 0 # cr13: home space segment table |
243 | .quad 0xc0000000 # cr14: machine check handling off | 260 | .quad 0xc0000000 # cr14: machine check handling off |
244 | .quad 0 # cr15: linkage stack operations | 261 | .quad 0 # cr15: linkage stack operations |
262 | .Lduct: .long 0,0,0,0,0,0,0,0 | ||
263 | .long 0,0,0,0,0,0,0,0 | ||
245 | .Lpcmsk:.quad 0x0000000180000000 | 264 | .Lpcmsk:.quad 0x0000000180000000 |
246 | .L4malign:.quad 0xffffffffffc00000 | 265 | .L4malign:.quad 0xffffffffffc00000 |
247 | .Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8 | 266 | .Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8 |
248 | .Lnop: .long 0x07000700 | 267 | .Lnop: .long 0x07000700 |
268 | .Lparmaddr: | ||
269 | .quad PARMAREA | ||
249 | 270 | ||
250 | .org PARMAREA-64 | 271 | .align 4096 |
251 | .Lduct: .long 0,0,0,0,0,0,0,0 | ||
252 | .long 0,0,0,0,0,0,0,0 | ||
253 | |||
254 | # | ||
255 | # params at 10400 (setup.h) | ||
256 | # | ||
257 | .org PARMAREA | ||
258 | .global _pstart | ||
259 | _pstart: | ||
260 | .quad 0 # IPL_DEVICE | ||
261 | .quad RAMDISK_ORIGIN # INITRD_START | ||
262 | .quad RAMDISK_SIZE # INITRD_SIZE | ||
263 | |||
264 | .org COMMAND_LINE | ||
265 | .byte "root=/dev/ram0 ro" | ||
266 | .byte 0 | ||
267 | .org 0x11000 | ||
268 | .Lsccb: | 272 | .Lsccb: |
269 | .hword 0x1000 # length, one page | 273 | .hword 0x1000 # length, one page |
270 | .byte 0x00,0x00,0x00 | 274 | .byte 0x00,0x00,0x00 |
@@ -281,18 +285,14 @@ _pstart: | |||
281 | .Lscpincr2: | 285 | .Lscpincr2: |
282 | .quad 0x00 | 286 | .quad 0x00 |
283 | .fill 3984,1,0 | 287 | .fill 3984,1,0 |
284 | .org 0x12000 | 288 | .align 4096 |
285 | .global _pend | ||
286 | _pend: | ||
287 | |||
288 | GET_IPL_DEVICE | ||
289 | 289 | ||
290 | #ifdef CONFIG_SHARED_KERNEL | 290 | #ifdef CONFIG_SHARED_KERNEL |
291 | .org 0x100000 | 291 | .org 0x100000 |
292 | #endif | 292 | #endif |
293 | 293 | ||
294 | # | 294 | # |
295 | # startup-code, running in virtual mode | 295 | # startup-code, running in absolute addressing mode |
296 | # | 296 | # |
297 | .globl _stext | 297 | .globl _stext |
298 | _stext: basr %r13,0 # get base | 298 | _stext: basr %r13,0 # get base |
@@ -326,4 +326,3 @@ _stext: basr %r13,0 # get base | |||
326 | .align 8 | 326 | .align 8 |
327 | .Ldw: .quad 0x0002000180000000,0x0000000000000000 | 327 | .Ldw: .quad 0x0002000180000000,0x0000000000000000 |
328 | .Laregs: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | 328 | .Laregs: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
329 | |||
diff --git a/arch/s390/kernel/s390_ksyms.c b/arch/s390/kernel/s390_ksyms.c index 4176c77670c4..0886e739d122 100644 --- a/arch/s390/kernel/s390_ksyms.c +++ b/arch/s390/kernel/s390_ksyms.c | |||
@@ -46,8 +46,6 @@ EXPORT_SYMBOL(__down_interruptible); | |||
46 | */ | 46 | */ |
47 | extern int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs); | 47 | extern int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs); |
48 | EXPORT_SYMBOL(dump_fpu); | 48 | EXPORT_SYMBOL(dump_fpu); |
49 | EXPORT_SYMBOL(overflowuid); | ||
50 | EXPORT_SYMBOL(overflowgid); | ||
51 | EXPORT_SYMBOL(empty_zero_page); | 49 | EXPORT_SYMBOL(empty_zero_page); |
52 | 50 | ||
53 | /* | 51 | /* |
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index b282034452a4..2b2551e3510b 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/seq_file.h> | 37 | #include <linux/seq_file.h> |
38 | #include <linux/kernel_stat.h> | 38 | #include <linux/kernel_stat.h> |
39 | #include <linux/device.h> | 39 | #include <linux/device.h> |
40 | #include <linux/notifier.h> | ||
40 | 41 | ||
41 | #include <asm/uaccess.h> | 42 | #include <asm/uaccess.h> |
42 | #include <asm/system.h> | 43 | #include <asm/system.h> |
@@ -115,6 +116,7 @@ void __devinit cpu_init (void) | |||
115 | */ | 116 | */ |
116 | char vmhalt_cmd[128] = ""; | 117 | char vmhalt_cmd[128] = ""; |
117 | char vmpoff_cmd[128] = ""; | 118 | char vmpoff_cmd[128] = ""; |
119 | char vmpanic_cmd[128] = ""; | ||
118 | 120 | ||
119 | static inline void strncpy_skip_quote(char *dst, char *src, int n) | 121 | static inline void strncpy_skip_quote(char *dst, char *src, int n) |
120 | { | 122 | { |
@@ -146,6 +148,38 @@ static int __init vmpoff_setup(char *str) | |||
146 | 148 | ||
147 | __setup("vmpoff=", vmpoff_setup); | 149 | __setup("vmpoff=", vmpoff_setup); |
148 | 150 | ||
151 | static int vmpanic_notify(struct notifier_block *self, unsigned long event, | ||
152 | void *data) | ||
153 | { | ||
154 | if (MACHINE_IS_VM && strlen(vmpanic_cmd) > 0) | ||
155 | cpcmd(vmpanic_cmd, NULL, 0, NULL); | ||
156 | |||
157 | return NOTIFY_OK; | ||
158 | } | ||
159 | |||
160 | #define PANIC_PRI_VMPANIC 0 | ||
161 | |||
162 | static struct notifier_block vmpanic_nb = { | ||
163 | .notifier_call = vmpanic_notify, | ||
164 | .priority = PANIC_PRI_VMPANIC | ||
165 | }; | ||
166 | |||
167 | static int __init vmpanic_setup(char *str) | ||
168 | { | ||
169 | static int register_done __initdata = 0; | ||
170 | |||
171 | strncpy_skip_quote(vmpanic_cmd, str, 127); | ||
172 | vmpanic_cmd[127] = 0; | ||
173 | if (!register_done) { | ||
174 | register_done = 1; | ||
175 | atomic_notifier_chain_register(&panic_notifier_list, | ||
176 | &vmpanic_nb); | ||
177 | } | ||
178 | return 1; | ||
179 | } | ||
180 | |||
181 | __setup("vmpanic=", vmpanic_setup); | ||
182 | |||
149 | /* | 183 | /* |
150 | * condev= and conmode= setup parameter. | 184 | * condev= and conmode= setup parameter. |
151 | */ | 185 | */ |
@@ -289,19 +323,34 @@ void (*_machine_power_off)(void) = do_machine_power_off_nonsmp; | |||
289 | 323 | ||
290 | void machine_restart(char *command) | 324 | void machine_restart(char *command) |
291 | { | 325 | { |
292 | console_unblank(); | 326 | if (!in_interrupt() || oops_in_progress) |
327 | /* | ||
328 | * Only unblank the console if we are called in enabled | ||
329 | * context or a bust_spinlocks cleared the way for us. | ||
330 | */ | ||
331 | console_unblank(); | ||
293 | _machine_restart(command); | 332 | _machine_restart(command); |
294 | } | 333 | } |
295 | 334 | ||
296 | void machine_halt(void) | 335 | void machine_halt(void) |
297 | { | 336 | { |
298 | console_unblank(); | 337 | if (!in_interrupt() || oops_in_progress) |
338 | /* | ||
339 | * Only unblank the console if we are called in enabled | ||
340 | * context or a bust_spinlocks cleared the way for us. | ||
341 | */ | ||
342 | console_unblank(); | ||
299 | _machine_halt(); | 343 | _machine_halt(); |
300 | } | 344 | } |
301 | 345 | ||
302 | void machine_power_off(void) | 346 | void machine_power_off(void) |
303 | { | 347 | { |
304 | console_unblank(); | 348 | if (!in_interrupt() || oops_in_progress) |
349 | /* | ||
350 | * Only unblank the console if we are called in enabled | ||
351 | * context or a bust_spinlocks cleared the way for us. | ||
352 | */ | ||
353 | console_unblank(); | ||
305 | _machine_power_off(); | 354 | _machine_power_off(); |
306 | } | 355 | } |
307 | 356 | ||
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index a46793beeddd..b7630436f693 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c | |||
@@ -150,13 +150,11 @@ void show_stack(struct task_struct *task, unsigned long *sp) | |||
150 | unsigned long *stack; | 150 | unsigned long *stack; |
151 | int i; | 151 | int i; |
152 | 152 | ||
153 | // debugging aid: "show_stack(NULL);" prints the | ||
154 | // back trace for this cpu. | ||
155 | |||
156 | if (!sp) | 153 | if (!sp) |
157 | sp = task ? (unsigned long *) task->thread.ksp : __r15; | 154 | stack = task ? (unsigned long *) task->thread.ksp : __r15; |
155 | else | ||
156 | stack = sp; | ||
158 | 157 | ||
159 | stack = sp; | ||
160 | for (i = 0; i < kstack_depth_to_print; i++) { | 158 | for (i = 0; i < kstack_depth_to_print; i++) { |
161 | if (((addr_t) stack & (THREAD_SIZE-1)) == 0) | 159 | if (((addr_t) stack & (THREAD_SIZE-1)) == 0) |
162 | break; | 160 | break; |
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 2bcecf422573..1a0db1d4c952 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig | |||
@@ -465,10 +465,10 @@ config KEXEC | |||
465 | help | 465 | help |
466 | kexec is a system call that implements the ability to shutdown your | 466 | kexec is a system call that implements the ability to shutdown your |
467 | current kernel, and to start another kernel. It is like a reboot | 467 | current kernel, and to start another kernel. It is like a reboot |
468 | but it is indepedent of the system firmware. And like a reboot | 468 | but it is independent of the system firmware. And like a reboot |
469 | you can start any kernel with it, not just Linux. | 469 | you can start any kernel with it, not just Linux. |
470 | 470 | ||
471 | The name comes from the similiarity to the exec system call. | 471 | The name comes from the similarity to the exec system call. |
472 | 472 | ||
473 | It is an ongoing process to be certain the hardware in a machine | 473 | It is an ongoing process to be certain the hardware in a machine |
474 | is properly shutdown, so do not be surprised if this code does not | 474 | is properly shutdown, so do not be surprised if this code does not |
diff --git a/arch/sh/boards/adx/irq_maskreg.c b/arch/sh/boards/adx/irq_maskreg.c index c0973f8d57ba..357fab1bac2b 100644 --- a/arch/sh/boards/adx/irq_maskreg.c +++ b/arch/sh/boards/adx/irq_maskreg.c | |||
@@ -102,6 +102,6 @@ static void end_maskreg_irq(unsigned int irq) | |||
102 | void make_maskreg_irq(unsigned int irq) | 102 | void make_maskreg_irq(unsigned int irq) |
103 | { | 103 | { |
104 | disable_irq_nosync(irq); | 104 | disable_irq_nosync(irq); |
105 | irq_desc[irq].handler = &maskreg_irq_type; | 105 | irq_desc[irq].chip = &maskreg_irq_type; |
106 | disable_maskreg_irq(irq); | 106 | disable_maskreg_irq(irq); |
107 | } | 107 | } |
diff --git a/arch/sh/boards/bigsur/irq.c b/arch/sh/boards/bigsur/irq.c index 6ddbcc77244d..1d32425782c0 100644 --- a/arch/sh/boards/bigsur/irq.c +++ b/arch/sh/boards/bigsur/irq.c | |||
@@ -253,7 +253,7 @@ static void make_bigsur_l1isr(unsigned int irq) { | |||
253 | /* sanity check first */ | 253 | /* sanity check first */ |
254 | if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) { | 254 | if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) { |
255 | /* save the handler in the main description table */ | 255 | /* save the handler in the main description table */ |
256 | irq_desc[irq].handler = &bigsur_l1irq_type; | 256 | irq_desc[irq].chip = &bigsur_l1irq_type; |
257 | irq_desc[irq].status = IRQ_DISABLED; | 257 | irq_desc[irq].status = IRQ_DISABLED; |
258 | irq_desc[irq].action = 0; | 258 | irq_desc[irq].action = 0; |
259 | irq_desc[irq].depth = 1; | 259 | irq_desc[irq].depth = 1; |
@@ -270,7 +270,7 @@ static void make_bigsur_l2isr(unsigned int irq) { | |||
270 | /* sanity check first */ | 270 | /* sanity check first */ |
271 | if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) { | 271 | if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) { |
272 | /* save the handler in the main description table */ | 272 | /* save the handler in the main description table */ |
273 | irq_desc[irq].handler = &bigsur_l2irq_type; | 273 | irq_desc[irq].chip = &bigsur_l2irq_type; |
274 | irq_desc[irq].status = IRQ_DISABLED; | 274 | irq_desc[irq].status = IRQ_DISABLED; |
275 | irq_desc[irq].action = 0; | 275 | irq_desc[irq].action = 0; |
276 | irq_desc[irq].depth = 1; | 276 | irq_desc[irq].depth = 1; |
diff --git a/arch/sh/boards/cqreek/irq.c b/arch/sh/boards/cqreek/irq.c index d1da0d844567..2955adc52310 100644 --- a/arch/sh/boards/cqreek/irq.c +++ b/arch/sh/boards/cqreek/irq.c | |||
@@ -103,7 +103,7 @@ void __init init_cqreek_IRQ(void) | |||
103 | cqreek_irq_data[14].stat_port = BRIDGE_IDE_INTR_STAT; | 103 | cqreek_irq_data[14].stat_port = BRIDGE_IDE_INTR_STAT; |
104 | cqreek_irq_data[14].bit = 1; | 104 | cqreek_irq_data[14].bit = 1; |
105 | 105 | ||
106 | irq_desc[14].handler = &cqreek_irq_type; | 106 | irq_desc[14].chip = &cqreek_irq_type; |
107 | irq_desc[14].status = IRQ_DISABLED; | 107 | irq_desc[14].status = IRQ_DISABLED; |
108 | irq_desc[14].action = 0; | 108 | irq_desc[14].action = 0; |
109 | irq_desc[14].depth = 1; | 109 | irq_desc[14].depth = 1; |
@@ -117,7 +117,7 @@ void __init init_cqreek_IRQ(void) | |||
117 | cqreek_irq_data[10].bit = (1 << 10); | 117 | cqreek_irq_data[10].bit = (1 << 10); |
118 | 118 | ||
119 | /* XXX: Err... we may need demultiplexer for ISA irq... */ | 119 | /* XXX: Err... we may need demultiplexer for ISA irq... */ |
120 | irq_desc[10].handler = &cqreek_irq_type; | 120 | irq_desc[10].chip = &cqreek_irq_type; |
121 | irq_desc[10].status = IRQ_DISABLED; | 121 | irq_desc[10].status = IRQ_DISABLED; |
122 | irq_desc[10].action = 0; | 122 | irq_desc[10].action = 0; |
123 | irq_desc[10].depth = 1; | 123 | irq_desc[10].depth = 1; |
diff --git a/arch/sh/boards/dreamcast/setup.c b/arch/sh/boards/dreamcast/setup.c index 55dece35cde5..0027b80a2343 100644 --- a/arch/sh/boards/dreamcast/setup.c +++ b/arch/sh/boards/dreamcast/setup.c | |||
@@ -70,7 +70,7 @@ int __init platform_setup(void) | |||
70 | 70 | ||
71 | /* Assign all virtual IRQs to the System ASIC int. handler */ | 71 | /* Assign all virtual IRQs to the System ASIC int. handler */ |
72 | for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++) | 72 | for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++) |
73 | irq_desc[i].handler = &systemasic_int; | 73 | irq_desc[i].chip = &systemasic_int; |
74 | 74 | ||
75 | board_time_init = aica_time_init; | 75 | board_time_init = aica_time_init; |
76 | 76 | ||
diff --git a/arch/sh/boards/ec3104/setup.c b/arch/sh/boards/ec3104/setup.c index 5130ba2b6ff1..4b3ef16a0e96 100644 --- a/arch/sh/boards/ec3104/setup.c +++ b/arch/sh/boards/ec3104/setup.c | |||
@@ -63,7 +63,7 @@ int __init platform_setup(void) | |||
63 | str[i] = ctrl_readb(EC3104_BASE + i); | 63 | str[i] = ctrl_readb(EC3104_BASE + i); |
64 | 64 | ||
65 | for (i = EC3104_IRQBASE; i < EC3104_IRQBASE + 32; i++) | 65 | for (i = EC3104_IRQBASE; i < EC3104_IRQBASE + 32; i++) |
66 | irq_desc[i].handler = &ec3104_int; | 66 | irq_desc[i].chip = &ec3104_int; |
67 | 67 | ||
68 | printk("initializing EC3104 \"%.8s\" at %08x, IRQ %d, IRQ base %d\n", | 68 | printk("initializing EC3104 \"%.8s\" at %08x, IRQ %d, IRQ base %d\n", |
69 | str, EC3104_BASE, EC3104_IRQ, EC3104_IRQBASE); | 69 | str, EC3104_BASE, EC3104_IRQ, EC3104_IRQBASE); |
diff --git a/arch/sh/boards/harp/irq.c b/arch/sh/boards/harp/irq.c index 52d0ba39031b..701fa55d5297 100644 --- a/arch/sh/boards/harp/irq.c +++ b/arch/sh/boards/harp/irq.c | |||
@@ -114,7 +114,7 @@ static void enable_harp_irq(unsigned int irq) | |||
114 | static void __init make_harp_irq(unsigned int irq) | 114 | static void __init make_harp_irq(unsigned int irq) |
115 | { | 115 | { |
116 | disable_irq_nosync(irq); | 116 | disable_irq_nosync(irq); |
117 | irq_desc[irq].handler = &harp_irq_type; | 117 | irq_desc[irq].chip = &harp_irq_type; |
118 | disable_harp_irq(irq); | 118 | disable_harp_irq(irq); |
119 | } | 119 | } |
120 | 120 | ||
diff --git a/arch/sh/boards/mpc1211/pci.c b/arch/sh/boards/mpc1211/pci.c index ba3a65439752..9f7ccd33ffb6 100644 --- a/arch/sh/boards/mpc1211/pci.c +++ b/arch/sh/boards/mpc1211/pci.c | |||
@@ -273,9 +273,9 @@ void __init pcibios_fixup_irqs(void) | |||
273 | } | 273 | } |
274 | 274 | ||
275 | void pcibios_align_resource(void *data, struct resource *res, | 275 | void pcibios_align_resource(void *data, struct resource *res, |
276 | unsigned long size, unsigned long align) | 276 | resource_size_t size, resource_size_t align) |
277 | { | 277 | { |
278 | unsigned long start = res->start; | 278 | resource_size_t start = res->start; |
279 | 279 | ||
280 | if (res->flags & IORESOURCE_IO) { | 280 | if (res->flags & IORESOURCE_IO) { |
281 | if (start >= 0x10000UL) { | 281 | if (start >= 0x10000UL) { |
diff --git a/arch/sh/boards/mpc1211/setup.c b/arch/sh/boards/mpc1211/setup.c index 2bb581b91683..b72f009c52c2 100644 --- a/arch/sh/boards/mpc1211/setup.c +++ b/arch/sh/boards/mpc1211/setup.c | |||
@@ -194,7 +194,7 @@ static struct hw_interrupt_type mpc1211_irq_type = { | |||
194 | 194 | ||
195 | static void make_mpc1211_irq(unsigned int irq) | 195 | static void make_mpc1211_irq(unsigned int irq) |
196 | { | 196 | { |
197 | irq_desc[irq].handler = &mpc1211_irq_type; | 197 | irq_desc[irq].chip = &mpc1211_irq_type; |
198 | irq_desc[irq].status = IRQ_DISABLED; | 198 | irq_desc[irq].status = IRQ_DISABLED; |
199 | irq_desc[irq].action = 0; | 199 | irq_desc[irq].action = 0; |
200 | irq_desc[irq].depth = 1; | 200 | irq_desc[irq].depth = 1; |
diff --git a/arch/sh/boards/overdrive/galileo.c b/arch/sh/boards/overdrive/galileo.c index 276fa11ee4ce..b055809d2ac1 100644 --- a/arch/sh/boards/overdrive/galileo.c +++ b/arch/sh/boards/overdrive/galileo.c | |||
@@ -536,7 +536,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus) | |||
536 | } | 536 | } |
537 | 537 | ||
538 | void pcibios_align_resource(void *data, struct resource *res, | 538 | void pcibios_align_resource(void *data, struct resource *res, |
539 | unsigned long size) | 539 | resource_size_t size) |
540 | { | 540 | { |
541 | } | 541 | } |
542 | 542 | ||
diff --git a/arch/sh/boards/overdrive/irq.c b/arch/sh/boards/overdrive/irq.c index 715e8feb3a68..2c13a7de6b22 100644 --- a/arch/sh/boards/overdrive/irq.c +++ b/arch/sh/boards/overdrive/irq.c | |||
@@ -150,7 +150,7 @@ static void enable_od_irq(unsigned int irq) | |||
150 | static void __init make_od_irq(unsigned int irq) | 150 | static void __init make_od_irq(unsigned int irq) |
151 | { | 151 | { |
152 | disable_irq_nosync(irq); | 152 | disable_irq_nosync(irq); |
153 | irq_desc[irq].handler = &od_irq_type; | 153 | irq_desc[irq].chip = &od_irq_type; |
154 | disable_od_irq(irq); | 154 | disable_od_irq(irq); |
155 | } | 155 | } |
156 | 156 | ||
diff --git a/arch/sh/boards/renesas/hs7751rvoip/irq.c b/arch/sh/boards/renesas/hs7751rvoip/irq.c index ed4c5b50ea45..52a98b524e1f 100644 --- a/arch/sh/boards/renesas/hs7751rvoip/irq.c +++ b/arch/sh/boards/renesas/hs7751rvoip/irq.c | |||
@@ -86,7 +86,7 @@ static struct hw_interrupt_type hs7751rvoip_irq_type = { | |||
86 | static void make_hs7751rvoip_irq(unsigned int irq) | 86 | static void make_hs7751rvoip_irq(unsigned int irq) |
87 | { | 87 | { |
88 | disable_irq_nosync(irq); | 88 | disable_irq_nosync(irq); |
89 | irq_desc[irq].handler = &hs7751rvoip_irq_type; | 89 | irq_desc[irq].chip = &hs7751rvoip_irq_type; |
90 | disable_hs7751rvoip_irq(irq); | 90 | disable_hs7751rvoip_irq(irq); |
91 | } | 91 | } |
92 | 92 | ||
diff --git a/arch/sh/boards/renesas/rts7751r2d/irq.c b/arch/sh/boards/renesas/rts7751r2d/irq.c index d36c9374aed1..e16915d9cda4 100644 --- a/arch/sh/boards/renesas/rts7751r2d/irq.c +++ b/arch/sh/boards/renesas/rts7751r2d/irq.c | |||
@@ -100,7 +100,7 @@ static struct hw_interrupt_type rts7751r2d_irq_type = { | |||
100 | static void make_rts7751r2d_irq(unsigned int irq) | 100 | static void make_rts7751r2d_irq(unsigned int irq) |
101 | { | 101 | { |
102 | disable_irq_nosync(irq); | 102 | disable_irq_nosync(irq); |
103 | irq_desc[irq].handler = &rts7751r2d_irq_type; | 103 | irq_desc[irq].chip = &rts7751r2d_irq_type; |
104 | disable_rts7751r2d_irq(irq); | 104 | disable_rts7751r2d_irq(irq); |
105 | } | 105 | } |
106 | 106 | ||
diff --git a/arch/sh/boards/renesas/systemh/irq.c b/arch/sh/boards/renesas/systemh/irq.c index 7a2eb10edb56..845979181059 100644 --- a/arch/sh/boards/renesas/systemh/irq.c +++ b/arch/sh/boards/renesas/systemh/irq.c | |||
@@ -105,7 +105,7 @@ static void end_systemh_irq(unsigned int irq) | |||
105 | void make_systemh_irq(unsigned int irq) | 105 | void make_systemh_irq(unsigned int irq) |
106 | { | 106 | { |
107 | disable_irq_nosync(irq); | 107 | disable_irq_nosync(irq); |
108 | irq_desc[irq].handler = &systemh_irq_type; | 108 | irq_desc[irq].chip = &systemh_irq_type; |
109 | disable_systemh_irq(irq); | 109 | disable_systemh_irq(irq); |
110 | } | 110 | } |
111 | 111 | ||
diff --git a/arch/sh/boards/se/73180/irq.c b/arch/sh/boards/se/73180/irq.c index 70f04caad9a4..402735c7c898 100644 --- a/arch/sh/boards/se/73180/irq.c +++ b/arch/sh/boards/se/73180/irq.c | |||
@@ -85,7 +85,7 @@ void | |||
85 | make_intreq_irq(unsigned int irq) | 85 | make_intreq_irq(unsigned int irq) |
86 | { | 86 | { |
87 | disable_irq_nosync(irq); | 87 | disable_irq_nosync(irq); |
88 | irq_desc[irq].handler = &intreq_irq_type; | 88 | irq_desc[irq].chip = &intreq_irq_type; |
89 | disable_intreq_irq(irq); | 89 | disable_intreq_irq(irq); |
90 | } | 90 | } |
91 | 91 | ||
diff --git a/arch/sh/boards/superh/microdev/irq.c b/arch/sh/boards/superh/microdev/irq.c index efcbd86b7cd2..cb5999425d16 100644 --- a/arch/sh/boards/superh/microdev/irq.c +++ b/arch/sh/boards/superh/microdev/irq.c | |||
@@ -147,7 +147,7 @@ static void enable_microdev_irq(unsigned int irq) | |||
147 | static void __init make_microdev_irq(unsigned int irq) | 147 | static void __init make_microdev_irq(unsigned int irq) |
148 | { | 148 | { |
149 | disable_irq_nosync(irq); | 149 | disable_irq_nosync(irq); |
150 | irq_desc[irq].handler = µdev_irq_type; | 150 | irq_desc[irq].chip = µdev_irq_type; |
151 | disable_microdev_irq(irq); | 151 | disable_microdev_irq(irq); |
152 | } | 152 | } |
153 | 153 | ||
diff --git a/arch/sh/cchips/hd6446x/hd64461/setup.c b/arch/sh/cchips/hd6446x/hd64461/setup.c index f014b9bf6922..724db04cb392 100644 --- a/arch/sh/cchips/hd6446x/hd64461/setup.c +++ b/arch/sh/cchips/hd6446x/hd64461/setup.c | |||
@@ -154,7 +154,7 @@ int __init setup_hd64461(void) | |||
154 | outw(0xffff, HD64461_NIMR); | 154 | outw(0xffff, HD64461_NIMR); |
155 | 155 | ||
156 | for (i = HD64461_IRQBASE; i < HD64461_IRQBASE + 16; i++) { | 156 | for (i = HD64461_IRQBASE; i < HD64461_IRQBASE + 16; i++) { |
157 | irq_desc[i].handler = &hd64461_irq_type; | 157 | irq_desc[i].chip = &hd64461_irq_type; |
158 | } | 158 | } |
159 | 159 | ||
160 | setup_irq(CONFIG_HD64461_IRQ, &irq0); | 160 | setup_irq(CONFIG_HD64461_IRQ, &irq0); |
diff --git a/arch/sh/cchips/hd6446x/hd64465/setup.c b/arch/sh/cchips/hd6446x/hd64465/setup.c index 68e4c4e4283d..cf9142c620b7 100644 --- a/arch/sh/cchips/hd6446x/hd64465/setup.c +++ b/arch/sh/cchips/hd6446x/hd64465/setup.c | |||
@@ -182,7 +182,7 @@ static int __init setup_hd64465(void) | |||
182 | outw(0xffff, HD64465_REG_NIMR); /* mask all interrupts */ | 182 | outw(0xffff, HD64465_REG_NIMR); /* mask all interrupts */ |
183 | 183 | ||
184 | for (i = 0; i < HD64465_IRQ_NUM ; i++) { | 184 | for (i = 0; i < HD64465_IRQ_NUM ; i++) { |
185 | irq_desc[HD64465_IRQ_BASE + i].handler = &hd64465_irq_type; | 185 | irq_desc[HD64465_IRQ_BASE + i].chip = &hd64465_irq_type; |
186 | } | 186 | } |
187 | 187 | ||
188 | setup_irq(CONFIG_HD64465_IRQ, &irq0); | 188 | setup_irq(CONFIG_HD64465_IRQ, &irq0); |
diff --git a/arch/sh/cchips/voyagergx/irq.c b/arch/sh/cchips/voyagergx/irq.c index 2ee330b3c38f..892214bade19 100644 --- a/arch/sh/cchips/voyagergx/irq.c +++ b/arch/sh/cchips/voyagergx/irq.c | |||
@@ -191,7 +191,7 @@ void __init setup_voyagergx_irq(void) | |||
191 | flag = 1; | 191 | flag = 1; |
192 | } | 192 | } |
193 | if (flag == 1) | 193 | if (flag == 1) |
194 | irq_desc[VOYAGER_IRQ_BASE + i].handler = &voyagergx_irq_type; | 194 | irq_desc[VOYAGER_IRQ_BASE + i].chip = &voyagergx_irq_type; |
195 | } | 195 | } |
196 | 196 | ||
197 | setup_irq(IRQ_VOYAGER, &irq0); | 197 | setup_irq(IRQ_VOYAGER, &irq0); |
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index c1669905abe4..3d546ba329cf 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c | |||
@@ -75,7 +75,7 @@ pcibios_update_resource(struct pci_dev *dev, struct resource *root, | |||
75 | } | 75 | } |
76 | 76 | ||
77 | void pcibios_align_resource(void *data, struct resource *res, | 77 | void pcibios_align_resource(void *data, struct resource *res, |
78 | unsigned long size, unsigned long align) | 78 | resource_size_t size, resource_size_t align) |
79 | __attribute__ ((weak)); | 79 | __attribute__ ((weak)); |
80 | 80 | ||
81 | /* | 81 | /* |
@@ -85,10 +85,10 @@ void pcibios_align_resource(void *data, struct resource *res, | |||
85 | * modulo 0x400. | 85 | * modulo 0x400. |
86 | */ | 86 | */ |
87 | void pcibios_align_resource(void *data, struct resource *res, | 87 | void pcibios_align_resource(void *data, struct resource *res, |
88 | unsigned long size, unsigned long align) | 88 | resource_size_t size, resource_size_t align) |
89 | { | 89 | { |
90 | if (res->flags & IORESOURCE_IO) { | 90 | if (res->flags & IORESOURCE_IO) { |
91 | unsigned long start = res->start; | 91 | resource_size_t start = res->start; |
92 | 92 | ||
93 | if (start & 0x300) { | 93 | if (start & 0x300) { |
94 | start = (start + 0x3ff) & ~0x3ff; | 94 | start = (start + 0x3ff) & ~0x3ff; |
diff --git a/arch/sh/kernel/cpu/irq/imask.c b/arch/sh/kernel/cpu/irq/imask.c index baed9a550d39..a33ae3e0a5a5 100644 --- a/arch/sh/kernel/cpu/irq/imask.c +++ b/arch/sh/kernel/cpu/irq/imask.c | |||
@@ -105,6 +105,6 @@ static void shutdown_imask_irq(unsigned int irq) | |||
105 | void make_imask_irq(unsigned int irq) | 105 | void make_imask_irq(unsigned int irq) |
106 | { | 106 | { |
107 | disable_irq_nosync(irq); | 107 | disable_irq_nosync(irq); |
108 | irq_desc[irq].handler = &imask_irq_type; | 108 | irq_desc[irq].chip = &imask_irq_type; |
109 | enable_irq(irq); | 109 | enable_irq(irq); |
110 | } | 110 | } |
diff --git a/arch/sh/kernel/cpu/irq/intc2.c b/arch/sh/kernel/cpu/irq/intc2.c index 06e8afab32e4..30064bf6e154 100644 --- a/arch/sh/kernel/cpu/irq/intc2.c +++ b/arch/sh/kernel/cpu/irq/intc2.c | |||
@@ -137,7 +137,7 @@ void make_intc2_irq(unsigned int irq, | |||
137 | 137 | ||
138 | local_irq_restore(flags); | 138 | local_irq_restore(flags); |
139 | 139 | ||
140 | irq_desc[irq].handler = &intc2_irq_type; | 140 | irq_desc[irq].chip = &intc2_irq_type; |
141 | 141 | ||
142 | disable_intc2_irq(irq); | 142 | disable_intc2_irq(irq); |
143 | } | 143 | } |
diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c index e55150ed0856..0373b65c77f9 100644 --- a/arch/sh/kernel/cpu/irq/ipr.c +++ b/arch/sh/kernel/cpu/irq/ipr.c | |||
@@ -115,7 +115,7 @@ void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority) | |||
115 | ipr_data[irq].shift = pos*4; /* POSition (0-3) x 4 means shift */ | 115 | ipr_data[irq].shift = pos*4; /* POSition (0-3) x 4 means shift */ |
116 | ipr_data[irq].priority = priority; | 116 | ipr_data[irq].priority = priority; |
117 | 117 | ||
118 | irq_desc[irq].handler = &ipr_irq_type; | 118 | irq_desc[irq].chip = &ipr_irq_type; |
119 | disable_ipr_irq(irq); | 119 | disable_ipr_irq(irq); |
120 | } | 120 | } |
121 | 121 | ||
diff --git a/arch/sh/kernel/cpu/irq/pint.c b/arch/sh/kernel/cpu/irq/pint.c index 95d6024fe1ae..714963a25bba 100644 --- a/arch/sh/kernel/cpu/irq/pint.c +++ b/arch/sh/kernel/cpu/irq/pint.c | |||
@@ -85,7 +85,7 @@ static void end_pint_irq(unsigned int irq) | |||
85 | void make_pint_irq(unsigned int irq) | 85 | void make_pint_irq(unsigned int irq) |
86 | { | 86 | { |
87 | disable_irq_nosync(irq); | 87 | disable_irq_nosync(irq); |
88 | irq_desc[irq].handler = &pint_irq_type; | 88 | irq_desc[irq].chip = &pint_irq_type; |
89 | disable_pint_irq(irq); | 89 | disable_pint_irq(irq); |
90 | } | 90 | } |
91 | 91 | ||
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index b56e79632f24..c2e07f7f3496 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c | |||
@@ -47,7 +47,7 @@ int show_interrupts(struct seq_file *p, void *v) | |||
47 | goto unlock; | 47 | goto unlock; |
48 | seq_printf(p, "%3d: ",i); | 48 | seq_printf(p, "%3d: ",i); |
49 | seq_printf(p, "%10u ", kstat_irqs(i)); | 49 | seq_printf(p, "%10u ", kstat_irqs(i)); |
50 | seq_printf(p, " %14s", irq_desc[i].handler->typename); | 50 | seq_printf(p, " %14s", irq_desc[i].chip->typename); |
51 | seq_printf(p, " %s", action->name); | 51 | seq_printf(p, " %s", action->name); |
52 | 52 | ||
53 | for (action=action->next; action; action = action->next) | 53 | for (action=action->next; action; action = action->next) |
diff --git a/arch/sh64/kernel/irq.c b/arch/sh64/kernel/irq.c index d69879c0e063..675776a5477e 100644 --- a/arch/sh64/kernel/irq.c +++ b/arch/sh64/kernel/irq.c | |||
@@ -65,7 +65,7 @@ int show_interrupts(struct seq_file *p, void *v) | |||
65 | goto unlock; | 65 | goto unlock; |
66 | seq_printf(p, "%3d: ",i); | 66 | seq_printf(p, "%3d: ",i); |
67 | seq_printf(p, "%10u ", kstat_irqs(i)); | 67 | seq_printf(p, "%10u ", kstat_irqs(i)); |
68 | seq_printf(p, " %14s", irq_desc[i].handler->typename); | 68 | seq_printf(p, " %14s", irq_desc[i].chip->typename); |
69 | seq_printf(p, " %s", action->name); | 69 | seq_printf(p, " %s", action->name); |
70 | 70 | ||
71 | for (action=action->next; action; action = action->next) | 71 | for (action=action->next; action; action = action->next) |
diff --git a/arch/sh64/kernel/irq_intc.c b/arch/sh64/kernel/irq_intc.c index fc99bf4e362c..fa730f5fe2e6 100644 --- a/arch/sh64/kernel/irq_intc.c +++ b/arch/sh64/kernel/irq_intc.c | |||
@@ -178,7 +178,7 @@ static void end_intc_irq(unsigned int irq) | |||
178 | void make_intc_irq(unsigned int irq) | 178 | void make_intc_irq(unsigned int irq) |
179 | { | 179 | { |
180 | disable_irq_nosync(irq); | 180 | disable_irq_nosync(irq); |
181 | irq_desc[irq].handler = &intc_irq_type; | 181 | irq_desc[irq].chip = &intc_irq_type; |
182 | disable_intc_irq(irq); | 182 | disable_intc_irq(irq); |
183 | } | 183 | } |
184 | 184 | ||
@@ -208,7 +208,7 @@ void __init init_IRQ(void) | |||
208 | /* Set default: per-line enable/disable, priority driven ack/eoi */ | 208 | /* Set default: per-line enable/disable, priority driven ack/eoi */ |
209 | for (i = 0; i < NR_INTC_IRQS; i++) { | 209 | for (i = 0; i < NR_INTC_IRQS; i++) { |
210 | if (platform_int_priority[i] != NO_PRIORITY) { | 210 | if (platform_int_priority[i] != NO_PRIORITY) { |
211 | irq_desc[i].handler = &intc_irq_type; | 211 | irq_desc[i].chip = &intc_irq_type; |
212 | } | 212 | } |
213 | } | 213 | } |
214 | 214 | ||
diff --git a/arch/sh64/kernel/pcibios.c b/arch/sh64/kernel/pcibios.c index 50c61dcb9fae..945920bc24db 100644 --- a/arch/sh64/kernel/pcibios.c +++ b/arch/sh64/kernel/pcibios.c | |||
@@ -69,10 +69,10 @@ pcibios_update_resource(struct pci_dev *dev, struct resource *root, | |||
69 | * modulo 0x400. | 69 | * modulo 0x400. |
70 | */ | 70 | */ |
71 | void pcibios_align_resource(void *data, struct resource *res, | 71 | void pcibios_align_resource(void *data, struct resource *res, |
72 | unsigned long size, unsigned long align) | 72 | resource_size_t size, resource_size_t align) |
73 | { | 73 | { |
74 | if (res->flags & IORESOURCE_IO) { | 74 | if (res->flags & IORESOURCE_IO) { |
75 | unsigned long start = res->start; | 75 | resource_size_t start = res->start; |
76 | 76 | ||
77 | if (start & 0x300) { | 77 | if (start & 0x300) { |
78 | start = (start + 0x3ff) & ~0x3ff; | 78 | start = (start + 0x3ff) & ~0x3ff; |
diff --git a/arch/sh64/mach-cayman/irq.c b/arch/sh64/mach-cayman/irq.c index f797c84bfdd1..05eb7cdc26f0 100644 --- a/arch/sh64/mach-cayman/irq.c +++ b/arch/sh64/mach-cayman/irq.c | |||
@@ -187,7 +187,7 @@ void init_cayman_irq(void) | |||
187 | } | 187 | } |
188 | 188 | ||
189 | for (i=0; i<NR_EXT_IRQS; i++) { | 189 | for (i=0; i<NR_EXT_IRQS; i++) { |
190 | irq_desc[START_EXT_IRQS + i].handler = &cayman_irq_type; | 190 | irq_desc[START_EXT_IRQS + i].chip = &cayman_irq_type; |
191 | } | 191 | } |
192 | 192 | ||
193 | /* Setup the SMSC interrupt */ | 193 | /* Setup the SMSC interrupt */ |
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index ae4c667c906f..79d177149fdb 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c | |||
@@ -208,7 +208,7 @@ _sparc_ioremap(struct resource *res, u32 bus, u32 pa, int sz) | |||
208 | pa &= PAGE_MASK; | 208 | pa &= PAGE_MASK; |
209 | sparc_mapiorange(bus, pa, res->start, res->end - res->start + 1); | 209 | sparc_mapiorange(bus, pa, res->start, res->end - res->start + 1); |
210 | 210 | ||
211 | return (void __iomem *) (res->start + offset); | 211 | return (void __iomem *)(unsigned long)(res->start + offset); |
212 | } | 212 | } |
213 | 213 | ||
214 | /* | 214 | /* |
@@ -325,7 +325,7 @@ void *sbus_alloc_consistent(struct sbus_dev *sdev, long len, u32 *dma_addrp) | |||
325 | res->name = sdev->prom_name; | 325 | res->name = sdev->prom_name; |
326 | } | 326 | } |
327 | 327 | ||
328 | return (void *)res->start; | 328 | return (void *)(unsigned long)res->start; |
329 | 329 | ||
330 | err_noiommu: | 330 | err_noiommu: |
331 | release_resource(res); | 331 | release_resource(res); |
@@ -819,7 +819,9 @@ _sparc_io_get_info(char *buf, char **start, off_t fpos, int length, int *eof, | |||
819 | if (p + 32 >= e) /* Better than nothing */ | 819 | if (p + 32 >= e) /* Better than nothing */ |
820 | break; | 820 | break; |
821 | if ((nm = r->name) == 0) nm = "???"; | 821 | if ((nm = r->name) == 0) nm = "???"; |
822 | p += sprintf(p, "%08lx-%08lx: %s\n", r->start, r->end, nm); | 822 | p += sprintf(p, "%016llx-%016llx: %s\n", |
823 | (unsigned long long)r->start, | ||
824 | (unsigned long long)r->end, nm); | ||
823 | } | 825 | } |
824 | 826 | ||
825 | return p-buf; | 827 | return p-buf; |
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index bcfdddd0418a..5df3ebdc0ab1 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c | |||
@@ -860,7 +860,7 @@ char * __init pcibios_setup(char *str) | |||
860 | } | 860 | } |
861 | 861 | ||
862 | void pcibios_align_resource(void *data, struct resource *res, | 862 | void pcibios_align_resource(void *data, struct resource *res, |
863 | unsigned long size, unsigned long align) | 863 | resource_size_t size, resource_size_t align) |
864 | { | 864 | { |
865 | } | 865 | } |
866 | 866 | ||
diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c index a893a9cc9534..2e5d08ce217b 100644 --- a/arch/sparc/kernel/setup.c +++ b/arch/sparc/kernel/setup.c | |||
@@ -496,7 +496,7 @@ static int __init topology_init(void) | |||
496 | if (!p) | 496 | if (!p) |
497 | err = -ENOMEM; | 497 | err = -ENOMEM; |
498 | else | 498 | else |
499 | register_cpu(p, i, NULL); | 499 | register_cpu(p, i); |
500 | } | 500 | } |
501 | 501 | ||
502 | return err; | 502 | return err; |
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index cc89b06d0178..ab9e640df228 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c | |||
@@ -151,7 +151,7 @@ int show_interrupts(struct seq_file *p, void *v) | |||
151 | for_each_online_cpu(j) | 151 | for_each_online_cpu(j) |
152 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); | 152 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); |
153 | #endif | 153 | #endif |
154 | seq_printf(p, " %9s", irq_desc[i].handler->typename); | 154 | seq_printf(p, " %9s", irq_desc[i].chip->typename); |
155 | seq_printf(p, " %s", action->name); | 155 | seq_printf(p, " %s", action->name); |
156 | 156 | ||
157 | for (action=action->next; action; action = action->next) | 157 | for (action=action->next; action; action = action->next) |
@@ -224,7 +224,7 @@ static inline struct ino_bucket *virt_irq_to_bucket(unsigned int virt_irq) | |||
224 | #ifdef CONFIG_SMP | 224 | #ifdef CONFIG_SMP |
225 | static int irq_choose_cpu(unsigned int virt_irq) | 225 | static int irq_choose_cpu(unsigned int virt_irq) |
226 | { | 226 | { |
227 | cpumask_t mask = irq_affinity[virt_irq]; | 227 | cpumask_t mask = irq_desc[virt_irq].affinity; |
228 | int cpuid; | 228 | int cpuid; |
229 | 229 | ||
230 | if (cpus_equal(mask, CPU_MASK_ALL)) { | 230 | if (cpus_equal(mask, CPU_MASK_ALL)) { |
@@ -414,8 +414,8 @@ void irq_install_pre_handler(int virt_irq, | |||
414 | data->pre_handler_arg1 = arg1; | 414 | data->pre_handler_arg1 = arg1; |
415 | data->pre_handler_arg2 = arg2; | 415 | data->pre_handler_arg2 = arg2; |
416 | 416 | ||
417 | desc->handler = (desc->handler == &sun4u_irq ? | 417 | desc->chip = (desc->chip == &sun4u_irq ? |
418 | &sun4u_irq_ack : &sun4v_irq_ack); | 418 | &sun4u_irq_ack : &sun4v_irq_ack); |
419 | } | 419 | } |
420 | 420 | ||
421 | unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) | 421 | unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) |
@@ -431,7 +431,7 @@ unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) | |||
431 | bucket = &ivector_table[ino]; | 431 | bucket = &ivector_table[ino]; |
432 | if (!bucket->virt_irq) { | 432 | if (!bucket->virt_irq) { |
433 | bucket->virt_irq = virt_irq_alloc(__irq(bucket)); | 433 | bucket->virt_irq = virt_irq_alloc(__irq(bucket)); |
434 | irq_desc[bucket->virt_irq].handler = &sun4u_irq; | 434 | irq_desc[bucket->virt_irq].chip = &sun4u_irq; |
435 | } | 435 | } |
436 | 436 | ||
437 | desc = irq_desc + bucket->virt_irq; | 437 | desc = irq_desc + bucket->virt_irq; |
@@ -465,7 +465,7 @@ unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino) | |||
465 | bucket = &ivector_table[sysino]; | 465 | bucket = &ivector_table[sysino]; |
466 | if (!bucket->virt_irq) { | 466 | if (!bucket->virt_irq) { |
467 | bucket->virt_irq = virt_irq_alloc(__irq(bucket)); | 467 | bucket->virt_irq = virt_irq_alloc(__irq(bucket)); |
468 | irq_desc[bucket->virt_irq].handler = &sun4v_irq; | 468 | irq_desc[bucket->virt_irq].chip = &sun4v_irq; |
469 | } | 469 | } |
470 | 470 | ||
471 | desc = irq_desc + bucket->virt_irq; | 471 | desc = irq_desc + bucket->virt_irq; |
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 6c9e3e94abaa..20ca9ec8fd3b 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c | |||
@@ -357,7 +357,7 @@ void pcibios_update_irq(struct pci_dev *pdev, int irq) | |||
357 | } | 357 | } |
358 | 358 | ||
359 | void pcibios_align_resource(void *data, struct resource *res, | 359 | void pcibios_align_resource(void *data, struct resource *res, |
360 | unsigned long size, unsigned long align) | 360 | resource_size_t size, resource_size_t align) |
361 | { | 361 | { |
362 | } | 362 | } |
363 | 363 | ||
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index 2ffda012385e..fae43a3054a0 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c | |||
@@ -63,7 +63,7 @@ int show_interrupts(struct seq_file *p, void *v) | |||
63 | for_each_online_cpu(j) | 63 | for_each_online_cpu(j) |
64 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); | 64 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); |
65 | #endif | 65 | #endif |
66 | seq_printf(p, " %14s", irq_desc[i].handler->typename); | 66 | seq_printf(p, " %14s", irq_desc[i].chip->typename); |
67 | seq_printf(p, " %s", action->name); | 67 | seq_printf(p, " %s", action->name); |
68 | 68 | ||
69 | for (action=action->next; action; action = action->next) | 69 | for (action=action->next; action; action = action->next) |
@@ -451,13 +451,13 @@ void __init init_IRQ(void) | |||
451 | irq_desc[TIMER_IRQ].status = IRQ_DISABLED; | 451 | irq_desc[TIMER_IRQ].status = IRQ_DISABLED; |
452 | irq_desc[TIMER_IRQ].action = NULL; | 452 | irq_desc[TIMER_IRQ].action = NULL; |
453 | irq_desc[TIMER_IRQ].depth = 1; | 453 | irq_desc[TIMER_IRQ].depth = 1; |
454 | irq_desc[TIMER_IRQ].handler = &SIGVTALRM_irq_type; | 454 | irq_desc[TIMER_IRQ].chip = &SIGVTALRM_irq_type; |
455 | enable_irq(TIMER_IRQ); | 455 | enable_irq(TIMER_IRQ); |
456 | for (i = 1; i < NR_IRQS; i++) { | 456 | for (i = 1; i < NR_IRQS; i++) { |
457 | irq_desc[i].status = IRQ_DISABLED; | 457 | irq_desc[i].status = IRQ_DISABLED; |
458 | irq_desc[i].action = NULL; | 458 | irq_desc[i].action = NULL; |
459 | irq_desc[i].depth = 1; | 459 | irq_desc[i].depth = 1; |
460 | irq_desc[i].handler = &normal_irq_type; | 460 | irq_desc[i].chip = &normal_irq_type; |
461 | enable_irq(i); | 461 | enable_irq(i); |
462 | } | 462 | } |
463 | } | 463 | } |
diff --git a/arch/v850/kernel/irq.c b/arch/v850/kernel/irq.c index 7a151c26f82e..858c45819aab 100644 --- a/arch/v850/kernel/irq.c +++ b/arch/v850/kernel/irq.c | |||
@@ -65,10 +65,10 @@ int show_interrupts(struct seq_file *p, void *v) | |||
65 | int j; | 65 | int j; |
66 | int count = 0; | 66 | int count = 0; |
67 | int num = -1; | 67 | int num = -1; |
68 | const char *type_name = irq_desc[irq].handler->typename; | 68 | const char *type_name = irq_desc[irq].chip->typename; |
69 | 69 | ||
70 | for (j = 0; j < NR_IRQS; j++) | 70 | for (j = 0; j < NR_IRQS; j++) |
71 | if (irq_desc[j].handler->typename == type_name){ | 71 | if (irq_desc[j].chip->typename == type_name){ |
72 | if (irq == j) | 72 | if (irq == j) |
73 | num = count; | 73 | num = count; |
74 | count++; | 74 | count++; |
@@ -117,7 +117,7 @@ init_irq_handlers (int base_irq, int num, int interval, | |||
117 | irq_desc[base_irq].status = IRQ_DISABLED; | 117 | irq_desc[base_irq].status = IRQ_DISABLED; |
118 | irq_desc[base_irq].action = NULL; | 118 | irq_desc[base_irq].action = NULL; |
119 | irq_desc[base_irq].depth = 1; | 119 | irq_desc[base_irq].depth = 1; |
120 | irq_desc[base_irq].handler = irq_type; | 120 | irq_desc[base_irq].chip = irq_type; |
121 | base_irq += interval; | 121 | base_irq += interval; |
122 | } | 122 | } |
123 | } | 123 | } |
diff --git a/arch/v850/kernel/rte_mb_a_pci.c b/arch/v850/kernel/rte_mb_a_pci.c index ffbb6d073bf2..3a7c5c9c3ac6 100644 --- a/arch/v850/kernel/rte_mb_a_pci.c +++ b/arch/v850/kernel/rte_mb_a_pci.c | |||
@@ -329,7 +329,7 @@ void pcibios_fixup_bus(struct pci_bus *b) | |||
329 | 329 | ||
330 | void | 330 | void |
331 | pcibios_align_resource (void *data, struct resource *res, | 331 | pcibios_align_resource (void *data, struct resource *res, |
332 | unsigned long size, unsigned long align) | 332 | resource_size_t size, resource_size_t align) |
333 | { | 333 | { |
334 | } | 334 | } |
335 | 335 | ||
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index ccc4a7fb97a3..e856804c447f 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig | |||
@@ -370,6 +370,8 @@ config HOTPLUG_CPU | |||
370 | can be controlled through /sys/devices/system/cpu/cpu#. | 370 | can be controlled through /sys/devices/system/cpu/cpu#. |
371 | Say N if you want to disable CPU hotplug. | 371 | Say N if you want to disable CPU hotplug. |
372 | 372 | ||
373 | config ARCH_ENABLE_MEMORY_HOTPLUG | ||
374 | def_bool y | ||
373 | 375 | ||
374 | config HPET_TIMER | 376 | config HPET_TIMER |
375 | bool | 377 | bool |
@@ -459,10 +461,10 @@ config KEXEC | |||
459 | help | 461 | help |
460 | kexec is a system call that implements the ability to shutdown your | 462 | kexec is a system call that implements the ability to shutdown your |
461 | current kernel, and to start another kernel. It is like a reboot | 463 | current kernel, and to start another kernel. It is like a reboot |
462 | but it is indepedent of the system firmware. And like a reboot | 464 | but it is independent of the system firmware. And like a reboot |
463 | you can start any kernel with it, not just Linux. | 465 | you can start any kernel with it, not just Linux. |
464 | 466 | ||
465 | The name comes from the similiarity to the exec system call. | 467 | The name comes from the similarity to the exec system call. |
466 | 468 | ||
467 | It is an ongoing process to be certain the hardware in a machine | 469 | It is an ongoing process to be certain the hardware in a machine |
468 | is properly shutdown, so do not be surprised if this code does not | 470 | is properly shutdown, so do not be surprised if this code does not |
diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c index 86b2c1e197aa..3dd1659427dc 100644 --- a/arch/x86_64/kernel/i8259.c +++ b/arch/x86_64/kernel/i8259.c | |||
@@ -235,7 +235,7 @@ void make_8259A_irq(unsigned int irq) | |||
235 | { | 235 | { |
236 | disable_irq_nosync(irq); | 236 | disable_irq_nosync(irq); |
237 | io_apic_irqs &= ~(1<<irq); | 237 | io_apic_irqs &= ~(1<<irq); |
238 | irq_desc[irq].handler = &i8259A_irq_type; | 238 | irq_desc[irq].chip = &i8259A_irq_type; |
239 | enable_irq(irq); | 239 | enable_irq(irq); |
240 | } | 240 | } |
241 | 241 | ||
@@ -468,12 +468,12 @@ void __init init_ISA_irqs (void) | |||
468 | /* | 468 | /* |
469 | * 16 old-style INTA-cycle interrupts: | 469 | * 16 old-style INTA-cycle interrupts: |
470 | */ | 470 | */ |
471 | irq_desc[i].handler = &i8259A_irq_type; | 471 | irq_desc[i].chip = &i8259A_irq_type; |
472 | } else { | 472 | } else { |
473 | /* | 473 | /* |
474 | * 'high' PCI IRQs filled in on demand | 474 | * 'high' PCI IRQs filled in on demand |
475 | */ | 475 | */ |
476 | irq_desc[i].handler = &no_irq_type; | 476 | irq_desc[i].chip = &no_irq_type; |
477 | } | 477 | } |
478 | } | 478 | } |
479 | } | 479 | } |
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index c768d8a036d0..401b687fef21 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c | |||
@@ -876,15 +876,17 @@ static struct hw_interrupt_type ioapic_edge_type; | |||
876 | #define IOAPIC_EDGE 0 | 876 | #define IOAPIC_EDGE 0 |
877 | #define IOAPIC_LEVEL 1 | 877 | #define IOAPIC_LEVEL 1 |
878 | 878 | ||
879 | static inline void ioapic_register_intr(int irq, int vector, unsigned long trigger) | 879 | static void ioapic_register_intr(int irq, int vector, unsigned long trigger) |
880 | { | 880 | { |
881 | unsigned idx = use_pci_vector() && !platform_legacy_irq(irq) ? vector : irq; | 881 | unsigned idx; |
882 | |||
883 | idx = use_pci_vector() && !platform_legacy_irq(irq) ? vector : irq; | ||
882 | 884 | ||
883 | if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || | 885 | if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || |
884 | trigger == IOAPIC_LEVEL) | 886 | trigger == IOAPIC_LEVEL) |
885 | irq_desc[idx].handler = &ioapic_level_type; | 887 | irq_desc[idx].chip = &ioapic_level_type; |
886 | else | 888 | else |
887 | irq_desc[idx].handler = &ioapic_edge_type; | 889 | irq_desc[idx].chip = &ioapic_edge_type; |
888 | set_intr_gate(vector, interrupt[idx]); | 890 | set_intr_gate(vector, interrupt[idx]); |
889 | } | 891 | } |
890 | 892 | ||
@@ -986,7 +988,7 @@ static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, in | |||
986 | * The timer IRQ doesn't have to know that behind the | 988 | * The timer IRQ doesn't have to know that behind the |
987 | * scene we have a 8259A-master in AEOI mode ... | 989 | * scene we have a 8259A-master in AEOI mode ... |
988 | */ | 990 | */ |
989 | irq_desc[0].handler = &ioapic_edge_type; | 991 | irq_desc[0].chip = &ioapic_edge_type; |
990 | 992 | ||
991 | /* | 993 | /* |
992 | * Add it to the IO-APIC irq-routing table: | 994 | * Add it to the IO-APIC irq-routing table: |
@@ -1616,6 +1618,13 @@ static void set_ioapic_affinity_vector (unsigned int vector, | |||
1616 | #endif // CONFIG_SMP | 1618 | #endif // CONFIG_SMP |
1617 | #endif // CONFIG_PCI_MSI | 1619 | #endif // CONFIG_PCI_MSI |
1618 | 1620 | ||
1621 | static int ioapic_retrigger(unsigned int irq) | ||
1622 | { | ||
1623 | send_IPI_self(IO_APIC_VECTOR(irq)); | ||
1624 | |||
1625 | return 1; | ||
1626 | } | ||
1627 | |||
1619 | /* | 1628 | /* |
1620 | * Level and edge triggered IO-APIC interrupts need different handling, | 1629 | * Level and edge triggered IO-APIC interrupts need different handling, |
1621 | * so we use two separate IRQ descriptors. Edge triggered IRQs can be | 1630 | * so we use two separate IRQ descriptors. Edge triggered IRQs can be |
@@ -1636,6 +1645,7 @@ static struct hw_interrupt_type ioapic_edge_type __read_mostly = { | |||
1636 | #ifdef CONFIG_SMP | 1645 | #ifdef CONFIG_SMP |
1637 | .set_affinity = set_ioapic_affinity, | 1646 | .set_affinity = set_ioapic_affinity, |
1638 | #endif | 1647 | #endif |
1648 | .retrigger = ioapic_retrigger, | ||
1639 | }; | 1649 | }; |
1640 | 1650 | ||
1641 | static struct hw_interrupt_type ioapic_level_type __read_mostly = { | 1651 | static struct hw_interrupt_type ioapic_level_type __read_mostly = { |
@@ -1649,6 +1659,7 @@ static struct hw_interrupt_type ioapic_level_type __read_mostly = { | |||
1649 | #ifdef CONFIG_SMP | 1659 | #ifdef CONFIG_SMP |
1650 | .set_affinity = set_ioapic_affinity, | 1660 | .set_affinity = set_ioapic_affinity, |
1651 | #endif | 1661 | #endif |
1662 | .retrigger = ioapic_retrigger, | ||
1652 | }; | 1663 | }; |
1653 | 1664 | ||
1654 | static inline void init_IO_APIC_traps(void) | 1665 | static inline void init_IO_APIC_traps(void) |
@@ -1683,7 +1694,7 @@ static inline void init_IO_APIC_traps(void) | |||
1683 | make_8259A_irq(irq); | 1694 | make_8259A_irq(irq); |
1684 | else | 1695 | else |
1685 | /* Strange. Oh, well.. */ | 1696 | /* Strange. Oh, well.. */ |
1686 | irq_desc[irq].handler = &no_irq_type; | 1697 | irq_desc[irq].chip = &no_irq_type; |
1687 | } | 1698 | } |
1688 | } | 1699 | } |
1689 | } | 1700 | } |
@@ -1900,7 +1911,7 @@ static inline void check_timer(void) | |||
1900 | apic_printk(APIC_VERBOSE, KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); | 1911 | apic_printk(APIC_VERBOSE, KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); |
1901 | 1912 | ||
1902 | disable_8259A_irq(0); | 1913 | disable_8259A_irq(0); |
1903 | irq_desc[0].handler = &lapic_irq_type; | 1914 | irq_desc[0].chip = &lapic_irq_type; |
1904 | apic_write(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */ | 1915 | apic_write(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */ |
1905 | enable_8259A_irq(0); | 1916 | enable_8259A_irq(0); |
1906 | 1917 | ||
diff --git a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c index bfa82f52a5cc..a1f1df5f7bfc 100644 --- a/arch/x86_64/kernel/irq.c +++ b/arch/x86_64/kernel/irq.c | |||
@@ -79,7 +79,7 @@ int show_interrupts(struct seq_file *p, void *v) | |||
79 | for_each_online_cpu(j) | 79 | for_each_online_cpu(j) |
80 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); | 80 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); |
81 | #endif | 81 | #endif |
82 | seq_printf(p, " %14s", irq_desc[i].handler->typename); | 82 | seq_printf(p, " %14s", irq_desc[i].chip->typename); |
83 | 83 | ||
84 | seq_printf(p, " %s", action->name); | 84 | seq_printf(p, " %s", action->name); |
85 | for (action=action->next; action; action = action->next) | 85 | for (action=action->next; action; action = action->next) |
@@ -146,13 +146,13 @@ void fixup_irqs(cpumask_t map) | |||
146 | if (irq == 2) | 146 | if (irq == 2) |
147 | continue; | 147 | continue; |
148 | 148 | ||
149 | cpus_and(mask, irq_affinity[irq], map); | 149 | cpus_and(mask, irq_desc[irq].affinity, map); |
150 | if (any_online_cpu(mask) == NR_CPUS) { | 150 | if (any_online_cpu(mask) == NR_CPUS) { |
151 | printk("Breaking affinity for irq %i\n", irq); | 151 | printk("Breaking affinity for irq %i\n", irq); |
152 | mask = map; | 152 | mask = map; |
153 | } | 153 | } |
154 | if (irq_desc[irq].handler->set_affinity) | 154 | if (irq_desc[irq].chip->set_affinity) |
155 | irq_desc[irq].handler->set_affinity(irq, mask); | 155 | irq_desc[irq].chip->set_affinity(irq, mask); |
156 | else if (irq_desc[irq].action && !(warned++)) | 156 | else if (irq_desc[irq].action && !(warned++)) |
157 | printk("Cannot set affinity for irq %i\n", irq); | 157 | printk("Cannot set affinity for irq %i\n", irq); |
158 | } | 158 | } |
diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c index 51f9bed455fa..1cf744ee0959 100644 --- a/arch/xtensa/kernel/irq.c +++ b/arch/xtensa/kernel/irq.c | |||
@@ -100,7 +100,7 @@ int show_interrupts(struct seq_file *p, void *v) | |||
100 | for_each_online_cpu(j) | 100 | for_each_online_cpu(j) |
101 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); | 101 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); |
102 | #endif | 102 | #endif |
103 | seq_printf(p, " %14s", irq_desc[i].handler->typename); | 103 | seq_printf(p, " %14s", irq_desc[i].chip->typename); |
104 | seq_printf(p, " %s", action->name); | 104 | seq_printf(p, " %s", action->name); |
105 | 105 | ||
106 | for (action=action->next; action; action = action->next) | 106 | for (action=action->next; action; action = action->next) |
@@ -181,7 +181,7 @@ void __init init_IRQ(void) | |||
181 | int i; | 181 | int i; |
182 | 182 | ||
183 | for (i=0; i < XTENSA_NR_IRQS; i++) | 183 | for (i=0; i < XTENSA_NR_IRQS; i++) |
184 | irq_desc[i].handler = &xtensa_irq_type; | 184 | irq_desc[i].chip = &xtensa_irq_type; |
185 | 185 | ||
186 | cached_irq_mask = 0; | 186 | cached_irq_mask = 0; |
187 | 187 | ||
diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c index c6f471b9eaa0..eda029fc8972 100644 --- a/arch/xtensa/kernel/pci.c +++ b/arch/xtensa/kernel/pci.c | |||
@@ -71,13 +71,13 @@ static int pci_bus_count; | |||
71 | * which might have be mirrored at 0x0100-0x03ff.. | 71 | * which might have be mirrored at 0x0100-0x03ff.. |
72 | */ | 72 | */ |
73 | void | 73 | void |
74 | pcibios_align_resource(void *data, struct resource *res, unsigned long size, | 74 | pcibios_align_resource(void *data, struct resource *res, resource_size_t size, |
75 | unsigned long align) | 75 | resource_size_t align) |
76 | { | 76 | { |
77 | struct pci_dev *dev = data; | 77 | struct pci_dev *dev = data; |
78 | 78 | ||
79 | if (res->flags & IORESOURCE_IO) { | 79 | if (res->flags & IORESOURCE_IO) { |
80 | unsigned long start = res->start; | 80 | resource_size_t start = res->start; |
81 | 81 | ||
82 | if (size > 0x100) { | 82 | if (size > 0x100) { |
83 | printk(KERN_ERR "PCI: I/O Region %s/%d too large" | 83 | printk(KERN_ERR "PCI: I/O Region %s/%d too large" |
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index 889855d8d9f9..9e3e2a69c03a 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c | |||
@@ -180,8 +180,9 @@ static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) | |||
180 | amba_attr(id, "%08x\n", dev->periphid); | 180 | amba_attr(id, "%08x\n", dev->periphid); |
181 | amba_attr(irq0, "%u\n", dev->irq[0]); | 181 | amba_attr(irq0, "%u\n", dev->irq[0]); |
182 | amba_attr(irq1, "%u\n", dev->irq[1]); | 182 | amba_attr(irq1, "%u\n", dev->irq[1]); |
183 | amba_attr(resource, "\t%08lx\t%08lx\t%08lx\n", | 183 | amba_attr(resource, "\t%016llx\t%016llx\t%016lx\n", |
184 | dev->res.start, dev->res.end, dev->res.flags); | 184 | (unsigned long long)dev->res.start, (unsigned long long)dev->res.end, |
185 | dev->res.flags); | ||
185 | 186 | ||
186 | /** | 187 | /** |
187 | * amba_device_register - register an AMBA device | 188 | * amba_device_register - register an AMBA device |
diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c index 4b6bf19c39c0..4048681f36d5 100644 --- a/drivers/atm/ambassador.c +++ b/drivers/atm/ambassador.c | |||
@@ -2257,7 +2257,8 @@ static int __devinit amb_probe(struct pci_dev *pci_dev, const struct pci_device_ | |||
2257 | } | 2257 | } |
2258 | 2258 | ||
2259 | PRINTD (DBG_INFO, "found Madge ATM adapter (amb) at" | 2259 | PRINTD (DBG_INFO, "found Madge ATM adapter (amb) at" |
2260 | " IO %lx, IRQ %u, MEM %p", pci_resource_start(pci_dev, 1), | 2260 | " IO %llx, IRQ %u, MEM %p", |
2261 | (unsigned long long)pci_resource_start(pci_dev, 1), | ||
2261 | irq, bus_to_virt(pci_resource_start(pci_dev, 0))); | 2262 | irq, bus_to_virt(pci_resource_start(pci_dev, 0))); |
2262 | 2263 | ||
2263 | // check IO region | 2264 | // check IO region |
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c index 1bca86edf570..d40605c1af73 100644 --- a/drivers/atm/firestream.c +++ b/drivers/atm/firestream.c | |||
@@ -1658,9 +1658,10 @@ static int __devinit fs_init (struct fs_dev *dev) | |||
1658 | func_enter (); | 1658 | func_enter (); |
1659 | pci_dev = dev->pci_dev; | 1659 | pci_dev = dev->pci_dev; |
1660 | 1660 | ||
1661 | printk (KERN_INFO "found a FireStream %d card, base %08lx, irq%d.\n", | 1661 | printk (KERN_INFO "found a FireStream %d card, base %16llx, irq%d.\n", |
1662 | IS_FS50(dev)?50:155, | 1662 | IS_FS50(dev)?50:155, |
1663 | pci_resource_start(pci_dev, 0), dev->pci_dev->irq); | 1663 | (unsigned long long)pci_resource_start(pci_dev, 0), |
1664 | dev->pci_dev->irq); | ||
1664 | 1665 | ||
1665 | if (fs_debug & FS_DEBUG_INIT) | 1666 | if (fs_debug & FS_DEBUG_INIT) |
1666 | my_hd ((unsigned char *) dev, sizeof (*dev)); | 1667 | my_hd ((unsigned char *) dev, sizeof (*dev)); |
diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c index 852b564e903a..1a9dee19efcf 100644 --- a/drivers/block/paride/pf.c +++ b/drivers/block/paride/pf.c | |||
@@ -707,7 +707,7 @@ static int pf_detect(void) | |||
707 | if (pi_init(pf->pi, 0, conf[D_PRT], conf[D_MOD], | 707 | if (pi_init(pf->pi, 0, conf[D_PRT], conf[D_MOD], |
708 | conf[D_UNI], conf[D_PRO], conf[D_DLY], | 708 | conf[D_UNI], conf[D_PRO], conf[D_DLY], |
709 | pf_scratch, PI_PF, verbose, pf->name)) { | 709 | pf_scratch, PI_PF, verbose, pf->name)) { |
710 | if (!pf_probe(pf) && pf->disk) { | 710 | if (pf->disk && !pf_probe(pf)) { |
711 | pf->present = 1; | 711 | pf->present = 1; |
712 | k++; | 712 | k++; |
713 | } else | 713 | } else |
diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c index 2ae08b343b93..8144ce9f4df0 100644 --- a/drivers/block/sx8.c +++ b/drivers/block/sx8.c | |||
@@ -1694,9 +1694,10 @@ static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1694 | DPRINTK("waiting for probe_comp\n"); | 1694 | DPRINTK("waiting for probe_comp\n"); |
1695 | wait_for_completion(&host->probe_comp); | 1695 | wait_for_completion(&host->probe_comp); |
1696 | 1696 | ||
1697 | printk(KERN_INFO "%s: pci %s, ports %d, io %lx, irq %u, major %d\n", | 1697 | printk(KERN_INFO "%s: pci %s, ports %d, io %llx, irq %u, major %d\n", |
1698 | host->name, pci_name(pdev), (int) CARM_MAX_PORTS, | 1698 | host->name, pci_name(pdev), (int) CARM_MAX_PORTS, |
1699 | pci_resource_start(pdev, 0), pdev->irq, host->major); | 1699 | (unsigned long long)pci_resource_start(pdev, 0), |
1700 | pdev->irq, host->major); | ||
1700 | 1701 | ||
1701 | carm_host_id++; | 1702 | carm_host_id++; |
1702 | pci_set_drvdata(pdev, host); | 1703 | pci_set_drvdata(pdev, host); |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 410d70cb76fb..c40e487d9f5c 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -961,6 +961,7 @@ config PC8736x_GPIO | |||
961 | 961 | ||
962 | config NSC_GPIO | 962 | config NSC_GPIO |
963 | tristate "NatSemi Base GPIO Support" | 963 | tristate "NatSemi Base GPIO Support" |
964 | depends on X86_32 | ||
964 | # selected by SCx200_GPIO and PC8736x_GPIO | 965 | # selected by SCx200_GPIO and PC8736x_GPIO |
965 | # what about 2 selectors differing: m != y | 966 | # what about 2 selectors differing: m != y |
966 | help | 967 | help |
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c index 9275d5e52e6d..72fb60765c45 100644 --- a/drivers/char/applicom.c +++ b/drivers/char/applicom.c | |||
@@ -209,13 +209,16 @@ static int __init applicom_init(void) | |||
209 | RamIO = ioremap(dev->resource[0].start, LEN_RAM_IO); | 209 | RamIO = ioremap(dev->resource[0].start, LEN_RAM_IO); |
210 | 210 | ||
211 | if (!RamIO) { | 211 | if (!RamIO) { |
212 | printk(KERN_INFO "ac.o: Failed to ioremap PCI memory space at 0x%lx\n", dev->resource[0].start); | 212 | printk(KERN_INFO "ac.o: Failed to ioremap PCI memory " |
213 | "space at 0x%llx\n", | ||
214 | (unsigned long long)dev->resource[0].start); | ||
213 | pci_disable_device(dev); | 215 | pci_disable_device(dev); |
214 | return -EIO; | 216 | return -EIO; |
215 | } | 217 | } |
216 | 218 | ||
217 | printk(KERN_INFO "Applicom %s found at mem 0x%lx, irq %d\n", | 219 | printk(KERN_INFO "Applicom %s found at mem 0x%llx, irq %d\n", |
218 | applicom_pci_devnames[dev->device-1], dev->resource[0].start, | 220 | applicom_pci_devnames[dev->device-1], |
221 | (unsigned long long)dev->resource[0].start, | ||
219 | dev->irq); | 222 | dev->irq); |
220 | 223 | ||
221 | boardno = ac_register_board(dev->resource[0].start, RamIO,0); | 224 | boardno = ac_register_board(dev->resource[0].start, RamIO,0); |
diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c index 05e6e814d86f..073da48c092e 100644 --- a/drivers/char/vr41xx_giu.c +++ b/drivers/char/vr41xx_giu.c | |||
@@ -689,9 +689,9 @@ static int __devinit giu_probe(struct platform_device *dev) | |||
689 | 689 | ||
690 | for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) { | 690 | for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) { |
691 | if (i < GIU_IRQ(GIUINT_HIGH_OFFSET)) | 691 | if (i < GIU_IRQ(GIUINT_HIGH_OFFSET)) |
692 | irq_desc[i].handler = &giuint_low_irq_type; | 692 | irq_desc[i].chip = &giuint_low_irq_type; |
693 | else | 693 | else |
694 | irq_desc[i].handler = &giuint_high_irq_type; | 694 | irq_desc[i].chip = &giuint_high_irq_type; |
695 | } | 695 | } |
696 | 696 | ||
697 | return cascade_irq(GIUINT_IRQ, giu_get_irq); | 697 | return cascade_irq(GIUINT_IRQ, giu_get_irq); |
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index d633081fa4c5..d1266fe2d1ab 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig | |||
@@ -774,11 +774,18 @@ config BLK_DEV_IDEDMA_PMAC | |||
774 | performance. | 774 | performance. |
775 | 775 | ||
776 | config BLK_DEV_IDE_PMAC_BLINK | 776 | config BLK_DEV_IDE_PMAC_BLINK |
777 | bool "Blink laptop LED on drive activity" | 777 | bool "Blink laptop LED on drive activity (DEPRECATED)" |
778 | depends on BLK_DEV_IDE_PMAC && ADB_PMU | 778 | depends on BLK_DEV_IDE_PMAC && ADB_PMU |
779 | select ADB_PMU_LED | ||
780 | select LEDS_TRIGGERS | ||
781 | select LEDS_TRIGGER_IDE_DISK | ||
779 | help | 782 | help |
780 | This option enables the use of the sleep LED as a hard drive | 783 | This option enables the use of the sleep LED as a hard drive |
781 | activity LED. | 784 | activity LED. |
785 | This option is deprecated, it only selects ADB_PMU_LED and | ||
786 | LEDS_TRIGGER_IDE_DISK and changes the code in the new led class | ||
787 | device to default to the ide-disk trigger (which should be set | ||
788 | from userspace via sysfs). | ||
782 | 789 | ||
783 | config BLK_DEV_IDE_SWARM | 790 | config BLK_DEV_IDE_SWARM |
784 | tristate "IDE for Sibyte evaluation boards" | 791 | tristate "IDE for Sibyte evaluation boards" |
diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c index ff0cdc142f17..3edd7060510f 100644 --- a/drivers/ide/pci/aec62xx.c +++ b/drivers/ide/pci/aec62xx.c | |||
@@ -254,7 +254,8 @@ static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const ch | |||
254 | 254 | ||
255 | if (dev->resource[PCI_ROM_RESOURCE].start) { | 255 | if (dev->resource[PCI_ROM_RESOURCE].start) { |
256 | pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); | 256 | pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); |
257 | printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start); | 257 | printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, |
258 | (unsigned long)dev->resource[PCI_ROM_RESOURCE].start); | ||
258 | } | 259 | } |
259 | 260 | ||
260 | if (bus_speed <= 33) | 261 | if (bus_speed <= 33) |
diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c index be334da7a754..7da550281cf2 100644 --- a/drivers/ide/pci/hpt34x.c +++ b/drivers/ide/pci/hpt34x.c | |||
@@ -176,7 +176,7 @@ static unsigned int __devinit init_chipset_hpt34x(struct pci_dev *dev, const cha | |||
176 | pci_write_config_dword(dev, PCI_ROM_ADDRESS, | 176 | pci_write_config_dword(dev, PCI_ROM_ADDRESS, |
177 | dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); | 177 | dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); |
178 | printk(KERN_INFO "HPT345: ROM enabled at 0x%08lx\n", | 178 | printk(KERN_INFO "HPT345: ROM enabled at 0x%08lx\n", |
179 | dev->resource[PCI_ROM_RESOURCE].start); | 179 | (unsigned long)dev->resource[PCI_ROM_RESOURCE].start); |
180 | } | 180 | } |
181 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF0); | 181 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF0); |
182 | } else { | 182 | } else { |
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c index 2c9e938dd1cd..5a8334d134fb 100644 --- a/drivers/ide/pci/pdc202xx_new.c +++ b/drivers/ide/pci/pdc202xx_new.c | |||
@@ -313,8 +313,8 @@ static unsigned int __devinit init_chipset_pdcnew(struct pci_dev *dev, const cha | |||
313 | if (dev->resource[PCI_ROM_RESOURCE].start) { | 313 | if (dev->resource[PCI_ROM_RESOURCE].start) { |
314 | pci_write_config_dword(dev, PCI_ROM_ADDRESS, | 314 | pci_write_config_dword(dev, PCI_ROM_ADDRESS, |
315 | dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); | 315 | dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); |
316 | printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", | 316 | printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, |
317 | name, dev->resource[PCI_ROM_RESOURCE].start); | 317 | (unsigned long)dev->resource[PCI_ROM_RESOURCE].start); |
318 | } | 318 | } |
319 | 319 | ||
320 | #ifdef CONFIG_PPC_PMAC | 320 | #ifdef CONFIG_PPC_PMAC |
diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c index 26bc688a1821..1e209d8f9437 100644 --- a/drivers/ide/pci/pdc202xx_old.c +++ b/drivers/ide/pci/pdc202xx_old.c | |||
@@ -490,8 +490,8 @@ static unsigned int __devinit init_chipset_pdc202xx(struct pci_dev *dev, | |||
490 | if (dev->resource[PCI_ROM_RESOURCE].start) { | 490 | if (dev->resource[PCI_ROM_RESOURCE].start) { |
491 | pci_write_config_dword(dev, PCI_ROM_ADDRESS, | 491 | pci_write_config_dword(dev, PCI_ROM_ADDRESS, |
492 | dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); | 492 | dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); |
493 | printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", | 493 | printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, |
494 | name, dev->resource[PCI_ROM_RESOURCE].start); | 494 | (unsigned long)dev->resource[PCI_ROM_RESOURCE].start); |
495 | } | 495 | } |
496 | 496 | ||
497 | return dev->irq; | 497 | return dev->irq; |
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index ffca8b63ee79..e8ef3455ec35 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c | |||
@@ -421,107 +421,6 @@ static void pmac_ide_kauai_selectproc(ide_drive_t *drive); | |||
421 | #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ | 421 | #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ |
422 | 422 | ||
423 | /* | 423 | /* |
424 | * Below is the code for blinking the laptop LED along with hard | ||
425 | * disk activity. | ||
426 | */ | ||
427 | |||
428 | #ifdef CONFIG_BLK_DEV_IDE_PMAC_BLINK | ||
429 | |||
430 | /* Set to 50ms minimum led-on time (also used to limit frequency | ||
431 | * of requests sent to the PMU | ||
432 | */ | ||
433 | #define PMU_HD_BLINK_TIME (HZ/50) | ||
434 | |||
435 | static struct adb_request pmu_blink_on, pmu_blink_off; | ||
436 | static spinlock_t pmu_blink_lock; | ||
437 | static unsigned long pmu_blink_stoptime; | ||
438 | static int pmu_blink_ledstate; | ||
439 | static struct timer_list pmu_blink_timer; | ||
440 | static int pmu_ide_blink_enabled; | ||
441 | |||
442 | |||
443 | static void | ||
444 | pmu_hd_blink_timeout(unsigned long data) | ||
445 | { | ||
446 | unsigned long flags; | ||
447 | |||
448 | spin_lock_irqsave(&pmu_blink_lock, flags); | ||
449 | |||
450 | /* We may have been triggered again in a racy way, check | ||
451 | * that we really want to switch it off | ||
452 | */ | ||
453 | if (time_after(pmu_blink_stoptime, jiffies)) | ||
454 | goto done; | ||
455 | |||
456 | /* Previous req. not complete, try 100ms more */ | ||
457 | if (pmu_blink_off.complete == 0) | ||
458 | mod_timer(&pmu_blink_timer, jiffies + PMU_HD_BLINK_TIME); | ||
459 | else if (pmu_blink_ledstate) { | ||
460 | pmu_request(&pmu_blink_off, NULL, 4, 0xee, 4, 0, 0); | ||
461 | pmu_blink_ledstate = 0; | ||
462 | } | ||
463 | done: | ||
464 | spin_unlock_irqrestore(&pmu_blink_lock, flags); | ||
465 | } | ||
466 | |||
467 | static void | ||
468 | pmu_hd_kick_blink(void *data, int rw) | ||
469 | { | ||
470 | unsigned long flags; | ||
471 | |||
472 | pmu_blink_stoptime = jiffies + PMU_HD_BLINK_TIME; | ||
473 | wmb(); | ||
474 | mod_timer(&pmu_blink_timer, pmu_blink_stoptime); | ||
475 | /* Fast path when LED is already ON */ | ||
476 | if (pmu_blink_ledstate == 1) | ||
477 | return; | ||
478 | spin_lock_irqsave(&pmu_blink_lock, flags); | ||
479 | if (pmu_blink_on.complete && !pmu_blink_ledstate) { | ||
480 | pmu_request(&pmu_blink_on, NULL, 4, 0xee, 4, 0, 1); | ||
481 | pmu_blink_ledstate = 1; | ||
482 | } | ||
483 | spin_unlock_irqrestore(&pmu_blink_lock, flags); | ||
484 | } | ||
485 | |||
486 | static int | ||
487 | pmu_hd_blink_init(void) | ||
488 | { | ||
489 | struct device_node *dt; | ||
490 | const char *model; | ||
491 | |||
492 | /* Currently, I only enable this feature on KeyLargo based laptops, | ||
493 | * older laptops may support it (at least heathrow/paddington) but | ||
494 | * I don't feel like loading those venerable old machines with so | ||
495 | * much additional interrupt & PMU activity... | ||
496 | */ | ||
497 | if (pmu_get_model() != PMU_KEYLARGO_BASED) | ||
498 | return 0; | ||
499 | |||
500 | dt = of_find_node_by_path("/"); | ||
501 | if (dt == NULL) | ||
502 | return 0; | ||
503 | model = (const char *)get_property(dt, "model", NULL); | ||
504 | if (model == NULL) | ||
505 | return 0; | ||
506 | if (strncmp(model, "PowerBook", strlen("PowerBook")) != 0 && | ||
507 | strncmp(model, "iBook", strlen("iBook")) != 0) { | ||
508 | of_node_put(dt); | ||
509 | return 0; | ||
510 | } | ||
511 | of_node_put(dt); | ||
512 | |||
513 | pmu_blink_on.complete = 1; | ||
514 | pmu_blink_off.complete = 1; | ||
515 | spin_lock_init(&pmu_blink_lock); | ||
516 | init_timer(&pmu_blink_timer); | ||
517 | pmu_blink_timer.function = pmu_hd_blink_timeout; | ||
518 | |||
519 | return 1; | ||
520 | } | ||
521 | |||
522 | #endif /* CONFIG_BLK_DEV_IDE_PMAC_BLINK */ | ||
523 | |||
524 | /* | ||
525 | * N.B. this can't be an initfunc, because the media-bay task can | 424 | * N.B. this can't be an initfunc, because the media-bay task can |
526 | * call ide_[un]register at any time. | 425 | * call ide_[un]register at any time. |
527 | */ | 426 | */ |
@@ -1192,23 +1091,6 @@ pmac_ide_do_suspend(ide_hwif_t *hwif) | |||
1192 | pmif->timings[0] = 0; | 1091 | pmif->timings[0] = 0; |
1193 | pmif->timings[1] = 0; | 1092 | pmif->timings[1] = 0; |
1194 | 1093 | ||
1195 | #ifdef CONFIG_BLK_DEV_IDE_PMAC_BLINK | ||
1196 | /* Note: This code will be called for every hwif, thus we'll | ||
1197 | * try several time to stop the LED blinker timer, but that | ||
1198 | * should be harmless | ||
1199 | */ | ||
1200 | if (pmu_ide_blink_enabled) { | ||
1201 | unsigned long flags; | ||
1202 | |||
1203 | /* Make sure we don't hit the PMU blink */ | ||
1204 | spin_lock_irqsave(&pmu_blink_lock, flags); | ||
1205 | if (pmu_blink_ledstate) | ||
1206 | del_timer(&pmu_blink_timer); | ||
1207 | pmu_blink_ledstate = 0; | ||
1208 | spin_unlock_irqrestore(&pmu_blink_lock, flags); | ||
1209 | } | ||
1210 | #endif /* CONFIG_BLK_DEV_IDE_PMAC_BLINK */ | ||
1211 | |||
1212 | disable_irq(pmif->irq); | 1094 | disable_irq(pmif->irq); |
1213 | 1095 | ||
1214 | /* The media bay will handle itself just fine */ | 1096 | /* The media bay will handle itself just fine */ |
@@ -1376,13 +1258,6 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) | |||
1376 | hwif->selectproc = pmac_ide_selectproc; | 1258 | hwif->selectproc = pmac_ide_selectproc; |
1377 | hwif->speedproc = pmac_ide_tune_chipset; | 1259 | hwif->speedproc = pmac_ide_tune_chipset; |
1378 | 1260 | ||
1379 | #ifdef CONFIG_BLK_DEV_IDE_PMAC_BLINK | ||
1380 | pmu_ide_blink_enabled = pmu_hd_blink_init(); | ||
1381 | |||
1382 | if (pmu_ide_blink_enabled) | ||
1383 | hwif->led_act = pmu_hd_kick_blink; | ||
1384 | #endif | ||
1385 | |||
1386 | printk(KERN_INFO "ide%d: Found Apple %s controller, bus ID %d%s, irq %d\n", | 1261 | printk(KERN_INFO "ide%d: Found Apple %s controller, bus ID %d%s, irq %d\n", |
1387 | hwif->index, model_name[pmif->kind], pmif->aapl_bus_id, | 1262 | hwif->index, model_name[pmif->kind], pmif->aapl_bus_id, |
1388 | pmif->mediabay ? " (mediabay)" : "", hwif->irq); | 1263 | pmif->mediabay ? " (mediabay)" : "", hwif->irq); |
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c index 3d278412e1ca..800c8d518430 100644 --- a/drivers/ieee1394/ohci1394.c +++ b/drivers/ieee1394/ohci1394.c | |||
@@ -590,11 +590,11 @@ static void ohci_initialize(struct ti_ohci *ohci) | |||
590 | buf = reg_read(ohci, OHCI1394_Version); | 590 | buf = reg_read(ohci, OHCI1394_Version); |
591 | sprintf (irq_buf, "%d", ohci->dev->irq); | 591 | sprintf (irq_buf, "%d", ohci->dev->irq); |
592 | PRINT(KERN_INFO, "OHCI-1394 %d.%d (PCI): IRQ=[%s] " | 592 | PRINT(KERN_INFO, "OHCI-1394 %d.%d (PCI): IRQ=[%s] " |
593 | "MMIO=[%lx-%lx] Max Packet=[%d] IR/IT contexts=[%d/%d]", | 593 | "MMIO=[%llx-%llx] Max Packet=[%d] IR/IT contexts=[%d/%d]", |
594 | ((((buf) >> 16) & 0xf) + (((buf) >> 20) & 0xf) * 10), | 594 | ((((buf) >> 16) & 0xf) + (((buf) >> 20) & 0xf) * 10), |
595 | ((((buf) >> 4) & 0xf) + ((buf) & 0xf) * 10), irq_buf, | 595 | ((((buf) >> 4) & 0xf) + ((buf) & 0xf) * 10), irq_buf, |
596 | pci_resource_start(ohci->dev, 0), | 596 | (unsigned long long)pci_resource_start(ohci->dev, 0), |
597 | pci_resource_start(ohci->dev, 0) + OHCI1394_REGISTER_SIZE - 1, | 597 | (unsigned long long)pci_resource_start(ohci->dev, 0) + OHCI1394_REGISTER_SIZE - 1, |
598 | ohci->max_packet_size, | 598 | ohci->max_packet_size, |
599 | ohci->nb_iso_rcv_ctx, ohci->nb_iso_xmit_ctx); | 599 | ohci->nb_iso_rcv_ctx, ohci->nb_iso_xmit_ctx); |
600 | 600 | ||
@@ -3217,7 +3217,7 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev, | |||
3217 | { | 3217 | { |
3218 | struct hpsb_host *host; | 3218 | struct hpsb_host *host; |
3219 | struct ti_ohci *ohci; /* shortcut to currently handled device */ | 3219 | struct ti_ohci *ohci; /* shortcut to currently handled device */ |
3220 | unsigned long ohci_base; | 3220 | resource_size_t ohci_base; |
3221 | 3221 | ||
3222 | if (pci_enable_device(dev)) | 3222 | if (pci_enable_device(dev)) |
3223 | FAIL(-ENXIO, "Failed to enable OHCI hardware"); | 3223 | FAIL(-ENXIO, "Failed to enable OHCI hardware"); |
@@ -3270,15 +3270,16 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev, | |||
3270 | * clearly says it's 2kb, so this shouldn't be a problem. */ | 3270 | * clearly says it's 2kb, so this shouldn't be a problem. */ |
3271 | ohci_base = pci_resource_start(dev, 0); | 3271 | ohci_base = pci_resource_start(dev, 0); |
3272 | if (pci_resource_len(dev, 0) < OHCI1394_REGISTER_SIZE) | 3272 | if (pci_resource_len(dev, 0) < OHCI1394_REGISTER_SIZE) |
3273 | PRINT(KERN_WARNING, "PCI resource length of %lx too small!", | 3273 | PRINT(KERN_WARNING, "PCI resource length of 0x%llx too small!", |
3274 | pci_resource_len(dev, 0)); | 3274 | (unsigned long long)pci_resource_len(dev, 0)); |
3275 | 3275 | ||
3276 | /* Seems PCMCIA handles this internally. Not sure why. Seems | 3276 | /* Seems PCMCIA handles this internally. Not sure why. Seems |
3277 | * pretty bogus to force a driver to special case this. */ | 3277 | * pretty bogus to force a driver to special case this. */ |
3278 | #ifndef PCMCIA | 3278 | #ifndef PCMCIA |
3279 | if (!request_mem_region (ohci_base, OHCI1394_REGISTER_SIZE, OHCI1394_DRIVER_NAME)) | 3279 | if (!request_mem_region (ohci_base, OHCI1394_REGISTER_SIZE, OHCI1394_DRIVER_NAME)) |
3280 | FAIL(-ENOMEM, "MMIO resource (0x%lx - 0x%lx) unavailable", | 3280 | FAIL(-ENOMEM, "MMIO resource (0x%llx - 0x%llx) unavailable", |
3281 | ohci_base, ohci_base + OHCI1394_REGISTER_SIZE); | 3281 | (unsigned long long)ohci_base, |
3282 | (unsigned long long)ohci_base + OHCI1394_REGISTER_SIZE); | ||
3282 | #endif | 3283 | #endif |
3283 | ohci->init_state = OHCI_INIT_HAVE_MEM_REGION; | 3284 | ohci->init_state = OHCI_INIT_HAVE_MEM_REGION; |
3284 | 3285 | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c index dddcdae736ac..e4b897fa569a 100644 --- a/drivers/infiniband/hw/ipath/ipath_driver.c +++ b/drivers/infiniband/hw/ipath/ipath_driver.c | |||
@@ -460,10 +460,10 @@ static int __devinit ipath_init_one(struct pci_dev *pdev, | |||
460 | for (j = 0; j < 6; j++) { | 460 | for (j = 0; j < 6; j++) { |
461 | if (!pdev->resource[j].start) | 461 | if (!pdev->resource[j].start) |
462 | continue; | 462 | continue; |
463 | ipath_cdbg(VERBOSE, "BAR %d start %lx, end %lx, len %lx\n", | 463 | ipath_cdbg(VERBOSE, "BAR %d start %llx, end %llx, len %llx\n", |
464 | j, pdev->resource[j].start, | 464 | j, (unsigned long long)pdev->resource[j].start, |
465 | pdev->resource[j].end, | 465 | (unsigned long long)pdev->resource[j].end, |
466 | pci_resource_len(pdev, j)); | 466 | (unsigned long long)pci_resource_len(pdev, j)); |
467 | } | 467 | } |
468 | 468 | ||
469 | if (!addr) { | 469 | if (!addr) { |
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c index 9b9ff7bff357..465fd220569c 100644 --- a/drivers/infiniband/hw/mthca/mthca_main.c +++ b/drivers/infiniband/hw/mthca/mthca_main.c | |||
@@ -172,8 +172,9 @@ static int __devinit mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim | |||
172 | 172 | ||
173 | if (dev_lim->uar_size > pci_resource_len(mdev->pdev, 2)) { | 173 | if (dev_lim->uar_size > pci_resource_len(mdev->pdev, 2)) { |
174 | mthca_err(mdev, "HCA reported UAR size of 0x%x bigger than " | 174 | mthca_err(mdev, "HCA reported UAR size of 0x%x bigger than " |
175 | "PCI resource 2 size of 0x%lx, aborting.\n", | 175 | "PCI resource 2 size of 0x%llx, aborting.\n", |
176 | dev_lim->uar_size, pci_resource_len(mdev->pdev, 2)); | 176 | dev_lim->uar_size, |
177 | (unsigned long long)pci_resource_len(mdev->pdev, 2)); | ||
177 | return -ENODEV; | 178 | return -ENODEV; |
178 | } | 179 | } |
179 | 180 | ||
diff --git a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c index 096b6a0b5cca..1ac739ef2ffa 100644 --- a/drivers/input/serio/ct82c710.c +++ b/drivers/input/serio/ct82c710.c | |||
@@ -189,7 +189,7 @@ static int __devinit ct82c710_probe(struct platform_device *dev) | |||
189 | strlcpy(ct82c710_port->name, "C&T 82c710 mouse port", | 189 | strlcpy(ct82c710_port->name, "C&T 82c710 mouse port", |
190 | sizeof(ct82c710_port->name)); | 190 | sizeof(ct82c710_port->name)); |
191 | snprintf(ct82c710_port->phys, sizeof(ct82c710_port->phys), | 191 | snprintf(ct82c710_port->phys, sizeof(ct82c710_port->phys), |
192 | "isa%04lx/serio0", CT82C710_DATA); | 192 | "isa%16llx/serio0", (unsigned long long)CT82C710_DATA); |
193 | 193 | ||
194 | serio_register_port(ct82c710_port); | 194 | serio_register_port(ct82c710_port); |
195 | 195 | ||
@@ -241,8 +241,8 @@ static int __init ct82c710_init(void) | |||
241 | 241 | ||
242 | serio_register_port(ct82c710_port); | 242 | serio_register_port(ct82c710_port); |
243 | 243 | ||
244 | printk(KERN_INFO "serio: C&T 82c710 mouse port at %#lx irq %d\n", | 244 | printk(KERN_INFO "serio: C&T 82c710 mouse port at %#llx irq %d\n", |
245 | CT82C710_DATA, CT82C710_IRQ); | 245 | (unsigned long long)CT82C710_DATA, CT82C710_IRQ); |
246 | 246 | ||
247 | return 0; | 247 | return 0; |
248 | 248 | ||
diff --git a/drivers/isdn/hardware/avm/b1pcmcia.c b/drivers/isdn/hardware/avm/b1pcmcia.c index 9746cc5ffff8..ad5025155b4e 100644 --- a/drivers/isdn/hardware/avm/b1pcmcia.c +++ b/drivers/isdn/hardware/avm/b1pcmcia.c | |||
@@ -82,7 +82,7 @@ static int b1pcmcia_add_card(unsigned int port, unsigned irq, | |||
82 | card->irq = irq; | 82 | card->irq = irq; |
83 | card->cardtype = cardtype; | 83 | card->cardtype = cardtype; |
84 | 84 | ||
85 | retval = request_irq(card->irq, b1_interrupt, 0, card->name, card); | 85 | retval = request_irq(card->irq, b1_interrupt, SA_SHIRQ, card->name, card); |
86 | if (retval) { | 86 | if (retval) { |
87 | printk(KERN_ERR "b1pcmcia: unable to get IRQ %d.\n", | 87 | printk(KERN_ERR "b1pcmcia: unable to get IRQ %d.\n", |
88 | card->irq); | 88 | card->irq); |
diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c index 91d25acb5ede..3622720f0505 100644 --- a/drivers/isdn/hisax/hfc_pci.c +++ b/drivers/isdn/hisax/hfc_pci.c | |||
@@ -1688,7 +1688,7 @@ setup_hfcpci(struct IsdnCard *card) | |||
1688 | printk(KERN_WARNING "HFC-PCI: No IRQ for PCI card found\n"); | 1688 | printk(KERN_WARNING "HFC-PCI: No IRQ for PCI card found\n"); |
1689 | return (0); | 1689 | return (0); |
1690 | } | 1690 | } |
1691 | cs->hw.hfcpci.pci_io = (char *) dev_hfcpci->resource[ 1].start; | 1691 | cs->hw.hfcpci.pci_io = (char *)(unsigned long)dev_hfcpci->resource[1].start; |
1692 | printk(KERN_INFO "HiSax: HFC-PCI card manufacturer: %s card name: %s\n", id_list[i].vendor_name, id_list[i].card_name); | 1692 | printk(KERN_INFO "HiSax: HFC-PCI card manufacturer: %s card name: %s\n", id_list[i].vendor_name, id_list[i].card_name); |
1693 | } else { | 1693 | } else { |
1694 | printk(KERN_WARNING "HFC-PCI: No PCI card found\n"); | 1694 | printk(KERN_WARNING "HFC-PCI: No PCI card found\n"); |
diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c index 9bb18f3f7829..f9c14a2970bc 100644 --- a/drivers/isdn/hisax/sedlbauer_cs.c +++ b/drivers/isdn/hisax/sedlbauer_cs.c | |||
@@ -164,7 +164,7 @@ static int sedlbauer_probe(struct pcmcia_device *link) | |||
164 | link->priv = local; | 164 | link->priv = local; |
165 | 165 | ||
166 | /* Interrupt setup */ | 166 | /* Interrupt setup */ |
167 | link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; | 167 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; |
168 | link->irq.IRQInfo1 = IRQ_LEVEL_ID; | 168 | link->irq.IRQInfo1 = IRQ_LEVEL_ID; |
169 | link->irq.Handler = NULL; | 169 | link->irq.Handler = NULL; |
170 | 170 | ||
diff --git a/drivers/isdn/hisax/teles3.c b/drivers/isdn/hisax/teles3.c index a3eaf4d65707..090abd16b4bc 100644 --- a/drivers/isdn/hisax/teles3.c +++ b/drivers/isdn/hisax/teles3.c | |||
@@ -369,6 +369,7 @@ setup_teles3(struct IsdnCard *card) | |||
369 | cs->hw.teles3.hscx[1] + 96); | 369 | cs->hw.teles3.hscx[1] + 96); |
370 | return (0); | 370 | return (0); |
371 | } | 371 | } |
372 | cs->irq_flags |= SA_SHIRQ; /* cardbus can share */ | ||
372 | } else { | 373 | } else { |
373 | if (cs->hw.teles3.cfg_reg) { | 374 | if (cs->hw.teles3.cfg_reg) { |
374 | if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) { | 375 | if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) { |
diff --git a/drivers/isdn/hisax/telespci.c b/drivers/isdn/hisax/telespci.c index e2bb4fd8e25e..e82ab2251b82 100644 --- a/drivers/isdn/hisax/telespci.c +++ b/drivers/isdn/hisax/telespci.c | |||
@@ -311,8 +311,9 @@ setup_telespci(struct IsdnCard *card) | |||
311 | } | 311 | } |
312 | cs->hw.teles0.membase = ioremap(pci_resource_start(dev_tel, 0), | 312 | cs->hw.teles0.membase = ioremap(pci_resource_start(dev_tel, 0), |
313 | PAGE_SIZE); | 313 | PAGE_SIZE); |
314 | printk(KERN_INFO "Found: Zoran, base-address: 0x%lx, irq: 0x%x\n", | 314 | printk(KERN_INFO "Found: Zoran, base-address: 0x%llx, irq: 0x%x\n", |
315 | pci_resource_start(dev_tel, 0), dev_tel->irq); | 315 | (unsigned long long)pci_resource_start(dev_tel, 0), |
316 | dev_tel->irq); | ||
316 | } else { | 317 | } else { |
317 | printk(KERN_WARNING "TelesPCI: No PCI card found\n"); | 318 | printk(KERN_WARNING "TelesPCI: No PCI card found\n"); |
318 | return(0); | 319 | return(0); |
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c index b26e509ec759..eb21063e6f63 100644 --- a/drivers/isdn/i4l/isdn_common.c +++ b/drivers/isdn/i4l/isdn_common.c | |||
@@ -340,6 +340,16 @@ isdn_command(isdn_ctrl *cmd) | |||
340 | printk(KERN_WARNING "isdn_command command(%x) driver -1\n", cmd->command); | 340 | printk(KERN_WARNING "isdn_command command(%x) driver -1\n", cmd->command); |
341 | return(1); | 341 | return(1); |
342 | } | 342 | } |
343 | if (!dev->drv[cmd->driver]) { | ||
344 | printk(KERN_WARNING "isdn_command command(%x) dev->drv[%d] NULL\n", | ||
345 | cmd->command, cmd->driver); | ||
346 | return(1); | ||
347 | } | ||
348 | if (!dev->drv[cmd->driver]->interface) { | ||
349 | printk(KERN_WARNING "isdn_command command(%x) dev->drv[%d]->interface NULL\n", | ||
350 | cmd->command, cmd->driver); | ||
351 | return(1); | ||
352 | } | ||
343 | if (cmd->command == ISDN_CMD_SETL2) { | 353 | if (cmd->command == ISDN_CMD_SETL2) { |
344 | int idx = isdn_dc2minor(cmd->driver, cmd->arg & 255); | 354 | int idx = isdn_dc2minor(cmd->driver, cmd->arg & 255); |
345 | unsigned long l2prot = (cmd->arg >> 8) & 255; | 355 | unsigned long l2prot = (cmd->arg >> 8) & 255; |
@@ -1903,6 +1913,11 @@ isdn_free_channel(int di, int ch, int usage) | |||
1903 | { | 1913 | { |
1904 | int i; | 1914 | int i; |
1905 | 1915 | ||
1916 | if ((di < 0) || (ch < 0)) { | ||
1917 | printk(KERN_WARNING "%s: called with invalid drv(%d) or channel(%d)\n", | ||
1918 | __FUNCTION__, di, ch); | ||
1919 | return; | ||
1920 | } | ||
1906 | for (i = 0; i < ISDN_MAX_CHANNELS; i++) | 1921 | for (i = 0; i < ISDN_MAX_CHANNELS; i++) |
1907 | if (((!usage) || ((dev->usage[i] & ISDN_USAGE_MASK) == usage)) && | 1922 | if (((!usage) || ((dev->usage[i] & ISDN_USAGE_MASK) == usage)) && |
1908 | (dev->drvmap[i] == di) && | 1923 | (dev->drvmap[i] == di) && |
@@ -1918,7 +1933,8 @@ isdn_free_channel(int di, int ch, int usage) | |||
1918 | dev->v110[i] = NULL; | 1933 | dev->v110[i] = NULL; |
1919 | // 20.10.99 JIM, try to reinitialize v110 ! | 1934 | // 20.10.99 JIM, try to reinitialize v110 ! |
1920 | isdn_info_update(); | 1935 | isdn_info_update(); |
1921 | skb_queue_purge(&dev->drv[di]->rpqueue[ch]); | 1936 | if (dev->drv[di]) |
1937 | skb_queue_purge(&dev->drv[di]->rpqueue[ch]); | ||
1922 | } | 1938 | } |
1923 | } | 1939 | } |
1924 | 1940 | ||
diff --git a/drivers/isdn/i4l/isdn_x25iface.c b/drivers/isdn/i4l/isdn_x25iface.c index 743ac4077f35..8b3efc243161 100644 --- a/drivers/isdn/i4l/isdn_x25iface.c +++ b/drivers/isdn/i4l/isdn_x25iface.c | |||
@@ -208,7 +208,7 @@ static int isdn_x25iface_receive(struct concap_proto *cprot, struct sk_buff *skb | |||
208 | */ | 208 | */ |
209 | static int isdn_x25iface_connect_ind(struct concap_proto *cprot) | 209 | static int isdn_x25iface_connect_ind(struct concap_proto *cprot) |
210 | { | 210 | { |
211 | struct sk_buff * skb = dev_alloc_skb(1); | 211 | struct sk_buff * skb; |
212 | enum wan_states *state_p | 212 | enum wan_states *state_p |
213 | = &( ( (ix25_pdata_t*) (cprot->proto_data) ) -> state); | 213 | = &( ( (ix25_pdata_t*) (cprot->proto_data) ) -> state); |
214 | IX25DEBUG( "isdn_x25iface_connect_ind %s \n" | 214 | IX25DEBUG( "isdn_x25iface_connect_ind %s \n" |
@@ -220,6 +220,8 @@ static int isdn_x25iface_connect_ind(struct concap_proto *cprot) | |||
220 | return -1; | 220 | return -1; |
221 | } | 221 | } |
222 | *state_p = WAN_CONNECTED; | 222 | *state_p = WAN_CONNECTED; |
223 | |||
224 | skb = dev_alloc_skb(1); | ||
223 | if( skb ){ | 225 | if( skb ){ |
224 | *( skb_put(skb, 1) ) = 0x01; | 226 | *( skb_put(skb, 1) ) = 0x01; |
225 | skb->protocol = x25_type_trans(skb, cprot->net_dev); | 227 | skb->protocol = x25_type_trans(skb, cprot->net_dev); |
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig index 37cd6ee4586b..54f3f6b94efc 100644 --- a/drivers/macintosh/Kconfig +++ b/drivers/macintosh/Kconfig | |||
@@ -78,6 +78,18 @@ config ADB_PMU | |||
78 | this device; you should do so if your machine is one of those | 78 | this device; you should do so if your machine is one of those |
79 | mentioned above. | 79 | mentioned above. |
80 | 80 | ||
81 | config ADB_PMU_LED | ||
82 | bool "Support for the Power/iBook front LED" | ||
83 | depends on ADB_PMU | ||
84 | select NEW_LEDS | ||
85 | select LEDS_CLASS | ||
86 | help | ||
87 | Support the front LED on Power/iBooks as a generic LED that can | ||
88 | be triggered by any of the supported triggers. To get the | ||
89 | behaviour of the old CONFIG_BLK_DEV_IDE_PMAC_BLINK, select this | ||
90 | and the ide-disk LED trigger and configure appropriately through | ||
91 | sysfs. | ||
92 | |||
81 | config PMAC_SMU | 93 | config PMAC_SMU |
82 | bool "Support for SMU based PowerMacs" | 94 | bool "Support for SMU based PowerMacs" |
83 | depends on PPC_PMAC64 | 95 | depends on PPC_PMAC64 |
diff --git a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile index 45a268f8047e..b53d45f87b0b 100644 --- a/drivers/macintosh/Makefile +++ b/drivers/macintosh/Makefile | |||
@@ -12,6 +12,7 @@ obj-$(CONFIG_INPUT_ADBHID) += adbhid.o | |||
12 | obj-$(CONFIG_ANSLCD) += ans-lcd.o | 12 | obj-$(CONFIG_ANSLCD) += ans-lcd.o |
13 | 13 | ||
14 | obj-$(CONFIG_ADB_PMU) += via-pmu.o via-pmu-event.o | 14 | obj-$(CONFIG_ADB_PMU) += via-pmu.o via-pmu-event.o |
15 | obj-$(CONFIG_ADB_PMU_LED) += via-pmu-led.o | ||
15 | obj-$(CONFIG_PMAC_BACKLIGHT) += via-pmu-backlight.o | 16 | obj-$(CONFIG_PMAC_BACKLIGHT) += via-pmu-backlight.o |
16 | obj-$(CONFIG_ADB_CUDA) += via-cuda.o | 17 | obj-$(CONFIG_ADB_CUDA) += via-cuda.o |
17 | obj-$(CONFIG_PMAC_APM_EMU) += apm_emu.o | 18 | obj-$(CONFIG_PMAC_APM_EMU) += apm_emu.o |
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index 431bd37225a1..c687ac703941 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c | |||
@@ -428,10 +428,10 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip, | |||
428 | 428 | ||
429 | /* MacIO itself has a different reg, we use it's PCI base */ | 429 | /* MacIO itself has a different reg, we use it's PCI base */ |
430 | if (np == chip->of_node) { | 430 | if (np == chip->of_node) { |
431 | sprintf(dev->ofdev.dev.bus_id, "%1d.%08lx:%.*s", | 431 | sprintf(dev->ofdev.dev.bus_id, "%1d.%016llx:%.*s", |
432 | chip->lbus.index, | 432 | chip->lbus.index, |
433 | #ifdef CONFIG_PCI | 433 | #ifdef CONFIG_PCI |
434 | pci_resource_start(chip->lbus.pdev, 0), | 434 | (unsigned long long)pci_resource_start(chip->lbus.pdev, 0), |
435 | #else | 435 | #else |
436 | 0, /* NuBus may want to do something better here */ | 436 | 0, /* NuBus may want to do something better here */ |
437 | #endif | 437 | #endif |
diff --git a/drivers/macintosh/via-pmu-led.c b/drivers/macintosh/via-pmu-led.c new file mode 100644 index 000000000000..af8375ed0f5e --- /dev/null +++ b/drivers/macintosh/via-pmu-led.c | |||
@@ -0,0 +1,144 @@ | |||
1 | /* | ||
2 | * via-pmu LED class device | ||
3 | * | ||
4 | * Copyright 2006 Johannes Berg <johannes@sipsolutions.net> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
14 | * NON INFRINGEMENT. See the GNU General Public License for more | ||
15 | * details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
20 | * | ||
21 | */ | ||
22 | #include <linux/types.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/device.h> | ||
25 | #include <linux/leds.h> | ||
26 | #include <linux/adb.h> | ||
27 | #include <linux/pmu.h> | ||
28 | #include <asm/prom.h> | ||
29 | |||
30 | static spinlock_t pmu_blink_lock; | ||
31 | static struct adb_request pmu_blink_req; | ||
32 | /* -1: no change, 0: request off, 1: request on */ | ||
33 | static int requested_change; | ||
34 | static int sleeping; | ||
35 | |||
36 | static void pmu_req_done(struct adb_request * req) | ||
37 | { | ||
38 | unsigned long flags; | ||
39 | |||
40 | spin_lock_irqsave(&pmu_blink_lock, flags); | ||
41 | /* if someone requested a change in the meantime | ||
42 | * (we only see the last one which is fine) | ||
43 | * then apply it now */ | ||
44 | if (requested_change != -1 && !sleeping) | ||
45 | pmu_request(&pmu_blink_req, NULL, 4, 0xee, 4, 0, requested_change); | ||
46 | /* reset requested change */ | ||
47 | requested_change = -1; | ||
48 | spin_unlock_irqrestore(&pmu_blink_lock, flags); | ||
49 | } | ||
50 | |||
51 | static void pmu_led_set(struct led_classdev *led_cdev, | ||
52 | enum led_brightness brightness) | ||
53 | { | ||
54 | unsigned long flags; | ||
55 | |||
56 | spin_lock_irqsave(&pmu_blink_lock, flags); | ||
57 | switch (brightness) { | ||
58 | case LED_OFF: | ||
59 | requested_change = 0; | ||
60 | break; | ||
61 | case LED_FULL: | ||
62 | requested_change = 1; | ||
63 | break; | ||
64 | default: | ||
65 | goto out; | ||
66 | break; | ||
67 | } | ||
68 | /* if request isn't done, then don't do anything */ | ||
69 | if (pmu_blink_req.complete && !sleeping) | ||
70 | pmu_request(&pmu_blink_req, NULL, 4, 0xee, 4, 0, requested_change); | ||
71 | out: | ||
72 | spin_unlock_irqrestore(&pmu_blink_lock, flags); | ||
73 | } | ||
74 | |||
75 | static struct led_classdev pmu_led = { | ||
76 | .name = "pmu-front-led", | ||
77 | #ifdef CONFIG_BLK_DEV_IDE_PMAC_BLINK | ||
78 | .default_trigger = "ide-disk", | ||
79 | #endif | ||
80 | .brightness_set = pmu_led_set, | ||
81 | }; | ||
82 | |||
83 | #ifdef CONFIG_PM | ||
84 | static int pmu_led_sleep_call(struct pmu_sleep_notifier *self, int when) | ||
85 | { | ||
86 | unsigned long flags; | ||
87 | |||
88 | spin_lock_irqsave(&pmu_blink_lock, flags); | ||
89 | |||
90 | switch (when) { | ||
91 | case PBOOK_SLEEP_REQUEST: | ||
92 | sleeping = 1; | ||
93 | break; | ||
94 | case PBOOK_WAKE: | ||
95 | sleeping = 0; | ||
96 | break; | ||
97 | default: | ||
98 | /* do nothing */ | ||
99 | break; | ||
100 | } | ||
101 | spin_unlock_irqrestore(&pmu_blink_lock, flags); | ||
102 | |||
103 | return PBOOK_SLEEP_OK; | ||
104 | } | ||
105 | |||
106 | static struct pmu_sleep_notifier via_pmu_led_sleep_notif = { | ||
107 | .notifier_call = pmu_led_sleep_call, | ||
108 | }; | ||
109 | #endif | ||
110 | |||
111 | static int __init via_pmu_led_init(void) | ||
112 | { | ||
113 | struct device_node *dt; | ||
114 | const char *model; | ||
115 | |||
116 | /* only do this on keylargo based models */ | ||
117 | if (pmu_get_model() != PMU_KEYLARGO_BASED) | ||
118 | return -ENODEV; | ||
119 | |||
120 | dt = of_find_node_by_path("/"); | ||
121 | if (dt == NULL) | ||
122 | return -ENODEV; | ||
123 | model = (const char *)get_property(dt, "model", NULL); | ||
124 | if (model == NULL) | ||
125 | return -ENODEV; | ||
126 | if (strncmp(model, "PowerBook", strlen("PowerBook")) != 0 && | ||
127 | strncmp(model, "iBook", strlen("iBook")) != 0) { | ||
128 | of_node_put(dt); | ||
129 | /* ignore */ | ||
130 | return -ENODEV; | ||
131 | } | ||
132 | of_node_put(dt); | ||
133 | |||
134 | spin_lock_init(&pmu_blink_lock); | ||
135 | /* no outstanding req */ | ||
136 | pmu_blink_req.complete = 1; | ||
137 | pmu_blink_req.done = pmu_req_done; | ||
138 | #ifdef CONFIG_PM | ||
139 | pmu_register_sleep_notifier(&via_pmu_led_sleep_notif); | ||
140 | #endif | ||
141 | return led_classdev_register(NULL, &pmu_led); | ||
142 | } | ||
143 | |||
144 | late_initcall(via_pmu_led_init); | ||
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index f920e50ea124..837ec4eb3d60 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -2827,7 +2827,6 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski | |||
2827 | struct stripe_head *sh; | 2827 | struct stripe_head *sh; |
2828 | int pd_idx; | 2828 | int pd_idx; |
2829 | int raid_disks = conf->raid_disks; | 2829 | int raid_disks = conf->raid_disks; |
2830 | int data_disks = raid_disks - conf->max_degraded; | ||
2831 | sector_t max_sector = mddev->size << 1; | 2830 | sector_t max_sector = mddev->size << 1; |
2832 | int sync_blocks; | 2831 | int sync_blocks; |
2833 | int still_degraded = 0; | 2832 | int still_degraded = 0; |
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index 423e954948be..aa3203ae670c 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c | |||
@@ -4019,8 +4019,9 @@ static int __devinit bttv_probe(struct pci_dev *dev, | |||
4019 | if (!request_mem_region(pci_resource_start(dev,0), | 4019 | if (!request_mem_region(pci_resource_start(dev,0), |
4020 | pci_resource_len(dev,0), | 4020 | pci_resource_len(dev,0), |
4021 | btv->c.name)) { | 4021 | btv->c.name)) { |
4022 | printk(KERN_WARNING "bttv%d: can't request iomem (0x%lx).\n", | 4022 | printk(KERN_WARNING "bttv%d: can't request iomem (0x%llx).\n", |
4023 | btv->c.nr, pci_resource_start(dev,0)); | 4023 | btv->c.nr, |
4024 | (unsigned long long)pci_resource_start(dev,0)); | ||
4024 | return -EBUSY; | 4025 | return -EBUSY; |
4025 | } | 4026 | } |
4026 | pci_set_master(dev); | 4027 | pci_set_master(dev); |
@@ -4031,8 +4032,9 @@ static int __devinit bttv_probe(struct pci_dev *dev, | |||
4031 | pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); | 4032 | pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); |
4032 | printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %s, ", | 4033 | printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %s, ", |
4033 | bttv_num,btv->id, btv->revision, pci_name(dev)); | 4034 | bttv_num,btv->id, btv->revision, pci_name(dev)); |
4034 | printk("irq: %d, latency: %d, mmio: 0x%lx\n", | 4035 | printk("irq: %d, latency: %d, mmio: 0x%llx\n", |
4035 | btv->c.pci->irq, lat, pci_resource_start(dev,0)); | 4036 | btv->c.pci->irq, lat, |
4037 | (unsigned long long)pci_resource_start(dev,0)); | ||
4036 | schedule(); | 4038 | schedule(); |
4037 | 4039 | ||
4038 | btv->bt848_mmio=ioremap(pci_resource_start(dev,0), 0x1000); | 4040 | btv->bt848_mmio=ioremap(pci_resource_start(dev,0), 0x1000); |
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c index 2194cbeca33b..292a5e81eb75 100644 --- a/drivers/media/video/cx88/cx88-alsa.c +++ b/drivers/media/video/cx88/cx88-alsa.c | |||
@@ -712,9 +712,9 @@ static int __devinit snd_cx88_create(struct snd_card *card, | |||
712 | pci_read_config_byte(pci, PCI_LATENCY_TIMER, &chip->pci_lat); | 712 | pci_read_config_byte(pci, PCI_LATENCY_TIMER, &chip->pci_lat); |
713 | 713 | ||
714 | dprintk(1,"ALSA %s/%i: found at %s, rev: %d, irq: %d, " | 714 | dprintk(1,"ALSA %s/%i: found at %s, rev: %d, irq: %d, " |
715 | "latency: %d, mmio: 0x%lx\n", core->name, devno, | 715 | "latency: %d, mmio: 0x%llx\n", core->name, devno, |
716 | pci_name(pci), chip->pci_rev, pci->irq, | 716 | pci_name(pci), chip->pci_rev, pci->irq, |
717 | chip->pci_lat,pci_resource_start(pci,0)); | 717 | chip->pci_lat,(unsigned long long)pci_resource_start(pci,0)); |
718 | 718 | ||
719 | chip->irq = pci->irq; | 719 | chip->irq = pci->irq; |
720 | synchronize_irq(chip->irq); | 720 | synchronize_irq(chip->irq); |
@@ -766,8 +766,8 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci, | |||
766 | 766 | ||
767 | strcpy (card->driver, "CX88x"); | 767 | strcpy (card->driver, "CX88x"); |
768 | sprintf(card->shortname, "Conexant CX%x", pci->device); | 768 | sprintf(card->shortname, "Conexant CX%x", pci->device); |
769 | sprintf(card->longname, "%s at %#lx", | 769 | sprintf(card->longname, "%s at %#llx", |
770 | card->shortname, pci_resource_start(pci, 0)); | 770 | card->shortname,(unsigned long long)pci_resource_start(pci, 0)); |
771 | strcpy (card->mixername, "CX88"); | 771 | strcpy (card->mixername, "CX88"); |
772 | 772 | ||
773 | dprintk (0, "%s/%i: ALSA support for cx2388x boards\n", | 773 | dprintk (0, "%s/%i: ALSA support for cx2388x boards\n", |
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c index 26f4c0fb8c36..973d3f39b2d5 100644 --- a/drivers/media/video/cx88/cx88-core.c +++ b/drivers/media/video/cx88/cx88-core.c | |||
@@ -1031,8 +1031,8 @@ static int get_ressources(struct cx88_core *core, struct pci_dev *pci) | |||
1031 | pci_resource_len(pci,0), | 1031 | pci_resource_len(pci,0), |
1032 | core->name)) | 1032 | core->name)) |
1033 | return 0; | 1033 | return 0; |
1034 | printk(KERN_ERR "%s: can't get MMIO memory @ 0x%lx\n", | 1034 | printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n", |
1035 | core->name,pci_resource_start(pci,0)); | 1035 | core->name,(unsigned long long)pci_resource_start(pci,0)); |
1036 | return -EBUSY; | 1036 | return -EBUSY; |
1037 | } | 1037 | } |
1038 | 1038 | ||
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c index a9d7795a8e14..2c12aca1b6a3 100644 --- a/drivers/media/video/cx88/cx88-mpeg.c +++ b/drivers/media/video/cx88/cx88-mpeg.c | |||
@@ -420,9 +420,9 @@ int cx8802_init_common(struct cx8802_dev *dev) | |||
420 | pci_read_config_byte(dev->pci, PCI_CLASS_REVISION, &dev->pci_rev); | 420 | pci_read_config_byte(dev->pci, PCI_CLASS_REVISION, &dev->pci_rev); |
421 | pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER, &dev->pci_lat); | 421 | pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER, &dev->pci_lat); |
422 | printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, " | 422 | printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, " |
423 | "latency: %d, mmio: 0x%lx\n", dev->core->name, | 423 | "latency: %d, mmio: 0x%llx\n", dev->core->name, |
424 | pci_name(dev->pci), dev->pci_rev, dev->pci->irq, | 424 | pci_name(dev->pci), dev->pci_rev, dev->pci->irq, |
425 | dev->pci_lat,pci_resource_start(dev->pci,0)); | 425 | dev->pci_lat,(unsigned long long)pci_resource_start(dev->pci,0)); |
426 | 426 | ||
427 | /* initialize driver struct */ | 427 | /* initialize driver struct */ |
428 | spin_lock_init(&dev->slock); | 428 | spin_lock_init(&dev->slock); |
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index dcda5291b990..8d5cf474b68e 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c | |||
@@ -1847,9 +1847,9 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, | |||
1847 | pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); | 1847 | pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); |
1848 | pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); | 1848 | pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); |
1849 | printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, " | 1849 | printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, " |
1850 | "latency: %d, mmio: 0x%lx\n", core->name, | 1850 | "latency: %d, mmio: 0x%llx\n", core->name, |
1851 | pci_name(pci_dev), dev->pci_rev, pci_dev->irq, | 1851 | pci_name(pci_dev), dev->pci_rev, pci_dev->irq, |
1852 | dev->pci_lat,pci_resource_start(pci_dev,0)); | 1852 | dev->pci_lat,(unsigned long long)pci_resource_start(pci_dev,0)); |
1853 | 1853 | ||
1854 | pci_set_master(pci_dev); | 1854 | pci_set_master(pci_dev); |
1855 | if (!pci_dma_supported(pci_dev,0xffffffff)) { | 1855 | if (!pci_dma_supported(pci_dev,0xffffffff)) { |
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index f0c2111f14ad..da3007d2f411 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c | |||
@@ -871,9 +871,9 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, | |||
871 | pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); | 871 | pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); |
872 | pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); | 872 | pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); |
873 | printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, " | 873 | printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, " |
874 | "latency: %d, mmio: 0x%lx\n", dev->name, | 874 | "latency: %d, mmio: 0x%llx\n", dev->name, |
875 | pci_name(pci_dev), dev->pci_rev, pci_dev->irq, | 875 | pci_name(pci_dev), dev->pci_rev, pci_dev->irq, |
876 | dev->pci_lat,pci_resource_start(pci_dev,0)); | 876 | dev->pci_lat,(unsigned long long)pci_resource_start(pci_dev,0)); |
877 | pci_set_master(pci_dev); | 877 | pci_set_master(pci_dev); |
878 | if (!pci_dma_supported(pci_dev, DMA_32BIT_MASK)) { | 878 | if (!pci_dma_supported(pci_dev, DMA_32BIT_MASK)) { |
879 | printk("%s: Oops: no 32bit PCI DMA ???\n",dev->name); | 879 | printk("%s: Oops: no 32bit PCI DMA ???\n",dev->name); |
@@ -905,8 +905,8 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, | |||
905 | pci_resource_len(pci_dev,0), | 905 | pci_resource_len(pci_dev,0), |
906 | dev->name)) { | 906 | dev->name)) { |
907 | err = -EBUSY; | 907 | err = -EBUSY; |
908 | printk(KERN_ERR "%s: can't get MMIO memory @ 0x%lx\n", | 908 | printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n", |
909 | dev->name,pci_resource_start(pci_dev,0)); | 909 | dev->name,(unsigned long long)pci_resource_start(pci_dev,0)); |
910 | goto fail1; | 910 | goto fail1; |
911 | } | 911 | } |
912 | dev->lmmio = ioremap(pci_resource_start(pci_dev,0), 0x1000); | 912 | dev->lmmio = ioremap(pci_resource_start(pci_dev,0), 0x1000); |
diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c index c74e5460f834..3305c12372a2 100644 --- a/drivers/message/i2o/iop.c +++ b/drivers/message/i2o/iop.c | |||
@@ -683,9 +683,10 @@ static int i2o_iop_systab_set(struct i2o_controller *c) | |||
683 | c->mem_alloc = 1; | 683 | c->mem_alloc = 1; |
684 | sb->current_mem_size = 1 + res->end - res->start; | 684 | sb->current_mem_size = 1 + res->end - res->start; |
685 | sb->current_mem_base = res->start; | 685 | sb->current_mem_base = res->start; |
686 | osm_info("%s: allocated %ld bytes of PCI memory at " | 686 | osm_info("%s: allocated %llu bytes of PCI memory at " |
687 | "0x%08lX.\n", c->name, | 687 | "0x%016llX.\n", c->name, |
688 | 1 + res->end - res->start, res->start); | 688 | (unsigned long long)(1 + res->end - res->start), |
689 | (unsigned long long)res->start); | ||
689 | } | 690 | } |
690 | } | 691 | } |
691 | 692 | ||
@@ -704,9 +705,10 @@ static int i2o_iop_systab_set(struct i2o_controller *c) | |||
704 | c->io_alloc = 1; | 705 | c->io_alloc = 1; |
705 | sb->current_io_size = 1 + res->end - res->start; | 706 | sb->current_io_size = 1 + res->end - res->start; |
706 | sb->current_mem_base = res->start; | 707 | sb->current_mem_base = res->start; |
707 | osm_info("%s: allocated %ld bytes of PCI I/O at 0x%08lX" | 708 | osm_info("%s: allocated %llu bytes of PCI I/O at " |
708 | ".\n", c->name, 1 + res->end - res->start, | 709 | "0x%016llX.\n", c->name, |
709 | res->start); | 710 | (unsigned long long)(1 + res->end - res->start), |
711 | (unsigned long long)res->start); | ||
710 | } | 712 | } |
711 | } | 713 | } |
712 | 714 | ||
diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c index da8e4d7339cc..8576a65ca1c3 100644 --- a/drivers/mmc/mmci.c +++ b/drivers/mmc/mmci.c | |||
@@ -546,9 +546,9 @@ static int mmci_probe(struct amba_device *dev, void *id) | |||
546 | 546 | ||
547 | mmc_add_host(mmc); | 547 | mmc_add_host(mmc); |
548 | 548 | ||
549 | printk(KERN_INFO "%s: MMCI rev %x cfg %02x at 0x%08lx irq %d,%d\n", | 549 | printk(KERN_INFO "%s: MMCI rev %x cfg %02x at 0x%016llx irq %d,%d\n", |
550 | mmc_hostname(mmc), amba_rev(dev), amba_config(dev), | 550 | mmc_hostname(mmc), amba_rev(dev), amba_config(dev), |
551 | dev->res.start, dev->irq[0], dev->irq[1]); | 551 | (unsigned long long)dev->res.start, dev->irq[0], dev->irq[1]); |
552 | 552 | ||
553 | init_timer(&host->timer); | 553 | init_timer(&host->timer); |
554 | host->timer.data = (unsigned long)host; | 554 | host->timer.data = (unsigned long)host; |
diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c index f620d74f1004..30f07b473ae2 100644 --- a/drivers/mtd/devices/pmc551.c +++ b/drivers/mtd/devices/pmc551.c | |||
@@ -551,11 +551,11 @@ static u32 fixup_pmc551 (struct pci_dev *dev) | |||
551 | /* | 551 | /* |
552 | * Some screen fun | 552 | * Some screen fun |
553 | */ | 553 | */ |
554 | printk(KERN_DEBUG "pmc551: %d%c (0x%x) of %sprefetchable memory at 0x%lx\n", | 554 | printk(KERN_DEBUG "pmc551: %d%c (0x%x) of %sprefetchable memory at 0x%llx\n", |
555 | (size<1024)?size:(size<1048576)?size>>10:size>>20, | 555 | (size<1024)?size:(size<1048576)?size>>10:size>>20, |
556 | (size<1024)?'B':(size<1048576)?'K':'M', | 556 | (size<1024)?'B':(size<1048576)?'K':'M', |
557 | size, ((dcmd&(0x1<<3)) == 0)?"non-":"", | 557 | size, ((dcmd&(0x1<<3)) == 0)?"non-":"", |
558 | (dev->resource[0].start)&PCI_BASE_ADDRESS_MEM_MASK ); | 558 | (unsigned long long)((dev->resource[0].start)&PCI_BASE_ADDRESS_MEM_MASK)); |
559 | 559 | ||
560 | /* | 560 | /* |
561 | * Check to see the state of the memory | 561 | * Check to see the state of the memory |
@@ -685,8 +685,8 @@ static int __init init_pmc551(void) | |||
685 | break; | 685 | break; |
686 | } | 686 | } |
687 | 687 | ||
688 | printk(KERN_NOTICE "pmc551: Found PCI V370PDC at 0x%lX\n", | 688 | printk(KERN_NOTICE "pmc551: Found PCI V370PDC at 0x%llx\n", |
689 | PCI_Device->resource[0].start); | 689 | (unsigned long long)PCI_Device->resource[0].start); |
690 | 690 | ||
691 | /* | 691 | /* |
692 | * The PMC551 device acts VERY weird if you don't init it | 692 | * The PMC551 device acts VERY weird if you don't init it |
diff --git a/drivers/mtd/maps/amd76xrom.c b/drivers/mtd/maps/amd76xrom.c index c350878d4592..a50587005263 100644 --- a/drivers/mtd/maps/amd76xrom.c +++ b/drivers/mtd/maps/amd76xrom.c | |||
@@ -123,9 +123,10 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev, | |||
123 | window->rsrc.parent = NULL; | 123 | window->rsrc.parent = NULL; |
124 | printk(KERN_ERR MOD_NAME | 124 | printk(KERN_ERR MOD_NAME |
125 | " %s(): Unable to register resource" | 125 | " %s(): Unable to register resource" |
126 | " 0x%.08lx-0x%.08lx - kernel bug?\n", | 126 | " 0x%.16llx-0x%.16llx - kernel bug?\n", |
127 | __func__, | 127 | __func__, |
128 | window->rsrc.start, window->rsrc.end); | 128 | (unsigned long long)window->rsrc.start, |
129 | (unsigned long long)window->rsrc.end); | ||
129 | } | 130 | } |
130 | 131 | ||
131 | #if 0 | 132 | #if 0 |
diff --git a/drivers/mtd/maps/ichxrom.c b/drivers/mtd/maps/ichxrom.c index ea5073781b3a..16732794edf3 100644 --- a/drivers/mtd/maps/ichxrom.c +++ b/drivers/mtd/maps/ichxrom.c | |||
@@ -177,9 +177,10 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev, | |||
177 | window->rsrc.parent = NULL; | 177 | window->rsrc.parent = NULL; |
178 | printk(KERN_DEBUG MOD_NAME | 178 | printk(KERN_DEBUG MOD_NAME |
179 | ": %s(): Unable to register resource" | 179 | ": %s(): Unable to register resource" |
180 | " 0x%.08lx-0x%.08lx - kernel bug?\n", | 180 | " 0x%.16llx-0x%.16llx - kernel bug?\n", |
181 | __func__, | 181 | __func__, |
182 | window->rsrc.start, window->rsrc.end); | 182 | (unsigned long long)window->rsrc.start, |
183 | (unsigned long long)window->rsrc.end); | ||
183 | } | 184 | } |
184 | 185 | ||
185 | /* Map the firmware hub into my address space. */ | 186 | /* Map the firmware hub into my address space. */ |
diff --git a/drivers/mtd/maps/scx200_docflash.c b/drivers/mtd/maps/scx200_docflash.c index 28b8a571a91a..331a15859d71 100644 --- a/drivers/mtd/maps/scx200_docflash.c +++ b/drivers/mtd/maps/scx200_docflash.c | |||
@@ -164,8 +164,9 @@ static int __init init_scx200_docflash(void) | |||
164 | outl(pmr, scx200_cb_base + SCx200_PMR); | 164 | outl(pmr, scx200_cb_base + SCx200_PMR); |
165 | } | 165 | } |
166 | 166 | ||
167 | printk(KERN_INFO NAME ": DOCCS mapped at 0x%lx-0x%lx, width %d\n", | 167 | printk(KERN_INFO NAME ": DOCCS mapped at 0x%llx-0x%llx, width %d\n", |
168 | docmem.start, docmem.end, width); | 168 | (unsigned long long)docmem.start, |
169 | (unsigned long long)docmem.end, width); | ||
169 | 170 | ||
170 | scx200_docflash_map.size = size; | 171 | scx200_docflash_map.size = size; |
171 | if (width == 8) | 172 | if (width == 8) |
diff --git a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c index 24a03152d196..4db2055cee31 100644 --- a/drivers/mtd/maps/sun_uflash.c +++ b/drivers/mtd/maps/sun_uflash.c | |||
@@ -62,9 +62,10 @@ int uflash_devinit(struct linux_ebus_device *edev, struct device_node *dp) | |||
62 | /* Non-CFI userflash device-- once I find one we | 62 | /* Non-CFI userflash device-- once I find one we |
63 | * can work on supporting it. | 63 | * can work on supporting it. |
64 | */ | 64 | */ |
65 | printk("%s: unsupported device at 0x%lx (%d regs): " \ | 65 | printk("%s: unsupported device at 0x%llx (%d regs): " \ |
66 | "email ebrower@usa.net\n", | 66 | "email ebrower@usa.net\n", |
67 | dp->full_name, res->start, edev->num_addrs); | 67 | dp->full_name, (unsigned long long)res->start, |
68 | edev->num_addrs); | ||
68 | 69 | ||
69 | return -ENODEV; | 70 | return -ENODEV; |
70 | } | 71 | } |
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index b467c383ae60..d2f808979a2b 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c | |||
@@ -1407,8 +1407,10 @@ static int __devinit vortex_probe1(struct device *gendev, | |||
1407 | } | 1407 | } |
1408 | 1408 | ||
1409 | if (print_info) { | 1409 | if (print_info) { |
1410 | printk(KERN_INFO "%s: CardBus functions mapped %8.8lx->%p\n", | 1410 | printk(KERN_INFO "%s: CardBus functions mapped " |
1411 | print_name, pci_resource_start(pdev, 2), | 1411 | "%16.16llx->%p\n", |
1412 | print_name, | ||
1413 | (unsigned long long)pci_resource_start(pdev, 2), | ||
1412 | vp->cb_fn_base); | 1414 | vp->cb_fn_base); |
1413 | } | 1415 | } |
1414 | EL3WINDOW(2); | 1416 | EL3WINDOW(2); |
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index 0cdc830449d8..d26dd6a7062d 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c | |||
@@ -1823,7 +1823,7 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1823 | struct cp_private *cp; | 1823 | struct cp_private *cp; |
1824 | int rc; | 1824 | int rc; |
1825 | void __iomem *regs; | 1825 | void __iomem *regs; |
1826 | long pciaddr; | 1826 | resource_size_t pciaddr; |
1827 | unsigned int addr_len, i, pci_using_dac; | 1827 | unsigned int addr_len, i, pci_using_dac; |
1828 | u8 pci_rev; | 1828 | u8 pci_rev; |
1829 | 1829 | ||
@@ -1883,8 +1883,8 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1883 | } | 1883 | } |
1884 | if (pci_resource_len(pdev, 1) < CP_REGS_SIZE) { | 1884 | if (pci_resource_len(pdev, 1) < CP_REGS_SIZE) { |
1885 | rc = -EIO; | 1885 | rc = -EIO; |
1886 | printk(KERN_ERR PFX "MMIO resource (%lx) too small on pci dev %s\n", | 1886 | printk(KERN_ERR PFX "MMIO resource (%llx) too small on pci dev %s\n", |
1887 | pci_resource_len(pdev, 1), pci_name(pdev)); | 1887 | (unsigned long long)pci_resource_len(pdev, 1), pci_name(pdev)); |
1888 | goto err_out_res; | 1888 | goto err_out_res; |
1889 | } | 1889 | } |
1890 | 1890 | ||
@@ -1916,8 +1916,9 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1916 | regs = ioremap(pciaddr, CP_REGS_SIZE); | 1916 | regs = ioremap(pciaddr, CP_REGS_SIZE); |
1917 | if (!regs) { | 1917 | if (!regs) { |
1918 | rc = -EIO; | 1918 | rc = -EIO; |
1919 | printk(KERN_ERR PFX "Cannot map PCI MMIO (%lx@%lx) on pci dev %s\n", | 1919 | printk(KERN_ERR PFX "Cannot map PCI MMIO (%llx@%llx) on pci dev %s\n", |
1920 | pci_resource_len(pdev, 1), pciaddr, pci_name(pdev)); | 1920 | (unsigned long long)pci_resource_len(pdev, 1), |
1921 | (unsigned long long)pciaddr, pci_name(pdev)); | ||
1921 | goto err_out_res; | 1922 | goto err_out_res; |
1922 | } | 1923 | } |
1923 | dev->base_addr = (unsigned long) regs; | 1924 | dev->base_addr = (unsigned long) regs; |
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index abd6261465f1..ed2e3c03bc88 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c | |||
@@ -1341,9 +1341,9 @@ static int rtl8139_open (struct net_device *dev) | |||
1341 | netif_start_queue (dev); | 1341 | netif_start_queue (dev); |
1342 | 1342 | ||
1343 | if (netif_msg_ifup(tp)) | 1343 | if (netif_msg_ifup(tp)) |
1344 | printk(KERN_DEBUG "%s: rtl8139_open() ioaddr %#lx IRQ %d" | 1344 | printk(KERN_DEBUG "%s: rtl8139_open() ioaddr %#llx IRQ %d" |
1345 | " GP Pins %2.2x %s-duplex.\n", | 1345 | " GP Pins %2.2x %s-duplex.\n", dev->name, |
1346 | dev->name, pci_resource_start (tp->pci_dev, 1), | 1346 | (unsigned long long)pci_resource_start (tp->pci_dev, 1), |
1347 | dev->irq, RTL_R8 (MediaStatus), | 1347 | dev->irq, RTL_R8 (MediaStatus), |
1348 | tp->mii.full_duplex ? "full" : "half"); | 1348 | tp->mii.full_duplex ? "full" : "half"); |
1349 | 1349 | ||
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index f37170cc1a37..93a286570923 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c | |||
@@ -2678,9 +2678,9 @@ static int __devinit e100_probe(struct pci_dev *pdev, | |||
2678 | goto err_out_free; | 2678 | goto err_out_free; |
2679 | } | 2679 | } |
2680 | 2680 | ||
2681 | DPRINTK(PROBE, INFO, "addr 0x%lx, irq %d, " | 2681 | DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, " |
2682 | "MAC addr %02X:%02X:%02X:%02X:%02X:%02X\n", | 2682 | "MAC addr %02X:%02X:%02X:%02X:%02X:%02X\n", |
2683 | pci_resource_start(pdev, 0), pdev->irq, | 2683 | (unsigned long long)pci_resource_start(pdev, 0), pdev->irq, |
2684 | netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2], | 2684 | netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2], |
2685 | netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]); | 2685 | netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]); |
2686 | 2686 | ||
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 19a4a16055dc..1608efab4e3d 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
@@ -3354,8 +3354,8 @@ static int __devinit skge_probe(struct pci_dev *pdev, | |||
3354 | if (err) | 3354 | if (err) |
3355 | goto err_out_free_irq; | 3355 | goto err_out_free_irq; |
3356 | 3356 | ||
3357 | printk(KERN_INFO PFX DRV_VERSION " addr 0x%lx irq %d chip %s rev %d\n", | 3357 | printk(KERN_INFO PFX DRV_VERSION " addr 0x%llx irq %d chip %s rev %d\n", |
3358 | pci_resource_start(pdev, 0), pdev->irq, | 3358 | (unsigned long long)pci_resource_start(pdev, 0), pdev->irq, |
3359 | skge_board_name(hw), hw->chip_rev); | 3359 | skge_board_name(hw), hw->chip_rev); |
3360 | 3360 | ||
3361 | if ((dev = skge_devinit(hw, 0, using_dac)) == NULL) | 3361 | if ((dev = skge_devinit(hw, 0, using_dac)) == NULL) |
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index d3577871be28..e122007e16da 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -3311,9 +3311,9 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
3311 | if (err) | 3311 | if (err) |
3312 | goto err_out_iounmap; | 3312 | goto err_out_iounmap; |
3313 | 3313 | ||
3314 | printk(KERN_INFO PFX "v%s addr 0x%lx irq %d Yukon-%s (0x%x) rev %d\n", | 3314 | printk(KERN_INFO PFX "v%s addr 0x%llx irq %d Yukon-%s (0x%x) rev %d\n", |
3315 | DRV_VERSION, pci_resource_start(pdev, 0), pdev->irq, | 3315 | DRV_VERSION, (unsigned long long)pci_resource_start(pdev, 0), |
3316 | yukon2_name[hw->chip_id - CHIP_ID_YUKON_XL], | 3316 | pdev->irq, yukon2_name[hw->chip_id - CHIP_ID_YUKON_XL], |
3317 | hw->chip_id, hw->chip_rev); | 3317 | hw->chip_id, hw->chip_rev); |
3318 | 3318 | ||
3319 | dev = sky2_init_netdev(hw, 0, using_dac); | 3319 | dev = sky2_init_netdev(hw, 0, using_dac); |
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index 5f743b972949..fc2468ecce0b 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c | |||
@@ -2007,8 +2007,8 @@ static int __init de_init_one (struct pci_dev *pdev, | |||
2007 | } | 2007 | } |
2008 | if (pci_resource_len(pdev, 1) < DE_REGS_SIZE) { | 2008 | if (pci_resource_len(pdev, 1) < DE_REGS_SIZE) { |
2009 | rc = -EIO; | 2009 | rc = -EIO; |
2010 | printk(KERN_ERR PFX "MMIO resource (%lx) too small on pci dev %s\n", | 2010 | printk(KERN_ERR PFX "MMIO resource (%llx) too small on pci dev %s\n", |
2011 | pci_resource_len(pdev, 1), pci_name(pdev)); | 2011 | (unsigned long long)pci_resource_len(pdev, 1), pci_name(pdev)); |
2012 | goto err_out_res; | 2012 | goto err_out_res; |
2013 | } | 2013 | } |
2014 | 2014 | ||
@@ -2016,8 +2016,9 @@ static int __init de_init_one (struct pci_dev *pdev, | |||
2016 | regs = ioremap_nocache(pciaddr, DE_REGS_SIZE); | 2016 | regs = ioremap_nocache(pciaddr, DE_REGS_SIZE); |
2017 | if (!regs) { | 2017 | if (!regs) { |
2018 | rc = -EIO; | 2018 | rc = -EIO; |
2019 | printk(KERN_ERR PFX "Cannot map PCI MMIO (%lx@%lx) on pci dev %s\n", | 2019 | printk(KERN_ERR PFX "Cannot map PCI MMIO (%llx@%lx) on pci dev %s\n", |
2020 | pci_resource_len(pdev, 1), pciaddr, pci_name(pdev)); | 2020 | (unsigned long long)pci_resource_len(pdev, 1), |
2021 | pciaddr, pci_name(pdev)); | ||
2021 | goto err_out_res; | 2022 | goto err_out_res; |
2022 | } | 2023 | } |
2023 | dev->base_addr = (unsigned long) regs; | 2024 | dev->base_addr = (unsigned long) regs; |
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index e0de66739a42..53fd9b56d0bd 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c | |||
@@ -1350,10 +1350,10 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, | |||
1350 | SET_MODULE_OWNER(dev); | 1350 | SET_MODULE_OWNER(dev); |
1351 | SET_NETDEV_DEV(dev, &pdev->dev); | 1351 | SET_NETDEV_DEV(dev, &pdev->dev); |
1352 | if (pci_resource_len (pdev, 0) < tulip_tbl[chip_idx].io_size) { | 1352 | if (pci_resource_len (pdev, 0) < tulip_tbl[chip_idx].io_size) { |
1353 | printk (KERN_ERR PFX "%s: I/O region (0x%lx@0x%lx) too small, " | 1353 | printk (KERN_ERR PFX "%s: I/O region (0x%llx@0x%llx) too small, " |
1354 | "aborting\n", pci_name(pdev), | 1354 | "aborting\n", pci_name(pdev), |
1355 | pci_resource_len (pdev, 0), | 1355 | (unsigned long long)pci_resource_len (pdev, 0), |
1356 | pci_resource_start (pdev, 0)); | 1356 | (unsigned long long)pci_resource_start (pdev, 0)); |
1357 | goto err_out_free_netdev; | 1357 | goto err_out_free_netdev; |
1358 | } | 1358 | } |
1359 | 1359 | ||
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index e49e8b520c28..e24d2dafcf6c 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c | |||
@@ -2568,9 +2568,10 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2568 | 2568 | ||
2569 | pci_set_drvdata(pdev, dev); | 2569 | pci_set_drvdata(pdev, dev); |
2570 | 2570 | ||
2571 | printk(KERN_INFO "%s: %s at %s 0x%lx, ", | 2571 | printk(KERN_INFO "%s: %s at %s 0x%llx, ", |
2572 | dev->name, typhoon_card_info[card_id].name, | 2572 | dev->name, typhoon_card_info[card_id].name, |
2573 | use_mmio ? "MMIO" : "IO", pci_resource_start(pdev, use_mmio)); | 2573 | use_mmio ? "MMIO" : "IO", |
2574 | (unsigned long long)pci_resource_start(pdev, use_mmio)); | ||
2574 | for(i = 0; i < 5; i++) | 2575 | for(i = 0; i < 5; i++) |
2575 | printk("%2.2x:", dev->dev_addr[i]); | 2576 | printk("%2.2x:", dev->dev_addr[i]); |
2576 | printk("%2.2x\n", dev->dev_addr[i]); | 2577 | printk("%2.2x\n", dev->dev_addr[i]); |
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c index 4505540e3c59..04a376ec0ed8 100644 --- a/drivers/net/wan/dscc4.c +++ b/drivers/net/wan/dscc4.c | |||
@@ -732,15 +732,15 @@ static int __devinit dscc4_init_one(struct pci_dev *pdev, | |||
732 | ioaddr = ioremap(pci_resource_start(pdev, 0), | 732 | ioaddr = ioremap(pci_resource_start(pdev, 0), |
733 | pci_resource_len(pdev, 0)); | 733 | pci_resource_len(pdev, 0)); |
734 | if (!ioaddr) { | 734 | if (!ioaddr) { |
735 | printk(KERN_ERR "%s: cannot remap MMIO region %lx @ %lx\n", | 735 | printk(KERN_ERR "%s: cannot remap MMIO region %llx @ %llx\n", |
736 | DRV_NAME, pci_resource_len(pdev, 0), | 736 | DRV_NAME, (unsigned long long)pci_resource_len(pdev, 0), |
737 | pci_resource_start(pdev, 0)); | 737 | (unsigned long long)pci_resource_start(pdev, 0)); |
738 | rc = -EIO; | 738 | rc = -EIO; |
739 | goto err_free_mmio_regions_2; | 739 | goto err_free_mmio_regions_2; |
740 | } | 740 | } |
741 | printk(KERN_DEBUG "Siemens DSCC4, MMIO at %#lx (regs), %#lx (lbi), IRQ %d\n", | 741 | printk(KERN_DEBUG "Siemens DSCC4, MMIO at %#llx (regs), %#llx (lbi), IRQ %d\n", |
742 | pci_resource_start(pdev, 0), | 742 | (unsigned long long)pci_resource_start(pdev, 0), |
743 | pci_resource_start(pdev, 1), pdev->irq); | 743 | (unsigned long long)pci_resource_start(pdev, 1), pdev->irq); |
744 | 744 | ||
745 | /* Cf errata DS5 p.2 */ | 745 | /* Cf errata DS5 p.2 */ |
746 | pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xf8); | 746 | pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xf8); |
diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c index a3e65d1bc19b..d7897ae89f90 100644 --- a/drivers/net/wan/pc300_drv.c +++ b/drivers/net/wan/pc300_drv.c | |||
@@ -3445,9 +3445,9 @@ cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3445 | 3445 | ||
3446 | card = (pc300_t *) kmalloc(sizeof(pc300_t), GFP_KERNEL); | 3446 | card = (pc300_t *) kmalloc(sizeof(pc300_t), GFP_KERNEL); |
3447 | if (card == NULL) { | 3447 | if (card == NULL) { |
3448 | printk("PC300 found at RAM 0x%08lx, " | 3448 | printk("PC300 found at RAM 0x%016llx, " |
3449 | "but could not allocate card structure.\n", | 3449 | "but could not allocate card structure.\n", |
3450 | pci_resource_start(pdev, 3)); | 3450 | (unsigned long long)pci_resource_start(pdev, 3)); |
3451 | err = -ENOMEM; | 3451 | err = -ENOMEM; |
3452 | goto err_disable_dev; | 3452 | goto err_disable_dev; |
3453 | } | 3453 | } |
diff --git a/drivers/parisc/Kconfig b/drivers/parisc/Kconfig index 3f5de867acd7..1d3b84b4af3f 100644 --- a/drivers/parisc/Kconfig +++ b/drivers/parisc/Kconfig | |||
@@ -140,18 +140,37 @@ config CHASSIS_LCD_LED | |||
140 | If unsure, say Y. | 140 | If unsure, say Y. |
141 | 141 | ||
142 | config PDC_CHASSIS | 142 | config PDC_CHASSIS |
143 | bool "PDC chassis State Panel support" | 143 | bool "PDC chassis state codes support" |
144 | default y | 144 | default y |
145 | help | 145 | help |
146 | Say Y here if you want to enable support for the LED State front | 146 | Say Y here if you want to enable support for Chassis codes. |
147 | panel as found on E class, and support for the GSP Virtual Front | 147 | That includes support for LED State front panel as found on E |
148 | Panel (LED State and message logging) as found on high end | 148 | class, and support for the GSP Virtual Front Panel (LED State and |
149 | servers such as A, L and N-class. | 149 | message logging) as found on high end servers such as A, L and |
150 | 150 | N-class. | |
151 | This has nothing to do with Chassis LCD and LED support. | 151 | This driver will also display progress messages on LCD display, |
152 | such as "INI", "RUN" and "FLT", and might thus clobber messages | ||
153 | shown by the LED/LCD driver. | ||
154 | This driver updates the state panel (LED and/or LCD) upon system | ||
155 | state change (eg: boot, shutdown or panic). | ||
152 | 156 | ||
153 | If unsure, say Y. | 157 | If unsure, say Y. |
154 | 158 | ||
159 | |||
160 | config PDC_CHASSIS_WARN | ||
161 | bool "PDC chassis warnings support" | ||
162 | depends on PROC_FS | ||
163 | default y | ||
164 | help | ||
165 | Say Y here if you want to enable support for Chassis warnings. | ||
166 | This will add a proc entry '/proc/chassis' giving some information | ||
167 | about the overall health state of the system. | ||
168 | This includes NVRAM battery level, overtemp or failures such as | ||
169 | fans or power units. | ||
170 | |||
171 | If unsure, say Y. | ||
172 | |||
173 | |||
155 | config PDC_STABLE | 174 | config PDC_STABLE |
156 | tristate "PDC Stable Storage support" | 175 | tristate "PDC Stable Storage support" |
157 | depends on SYSFS | 176 | depends on SYSFS |
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index 6e8ed0c81a6c..ce0a6ebcff15 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c | |||
@@ -299,7 +299,7 @@ struct pci_port_ops dino_port_ops = { | |||
299 | 299 | ||
300 | static void dino_disable_irq(unsigned int irq) | 300 | static void dino_disable_irq(unsigned int irq) |
301 | { | 301 | { |
302 | struct dino_device *dino_dev = irq_desc[irq].handler_data; | 302 | struct dino_device *dino_dev = irq_desc[irq].chip_data; |
303 | int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); | 303 | int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); |
304 | 304 | ||
305 | DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, dino_dev, irq); | 305 | DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, dino_dev, irq); |
@@ -311,7 +311,7 @@ static void dino_disable_irq(unsigned int irq) | |||
311 | 311 | ||
312 | static void dino_enable_irq(unsigned int irq) | 312 | static void dino_enable_irq(unsigned int irq) |
313 | { | 313 | { |
314 | struct dino_device *dino_dev = irq_desc[irq].handler_data; | 314 | struct dino_device *dino_dev = irq_desc[irq].chip_data; |
315 | int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); | 315 | int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); |
316 | u32 tmp; | 316 | u32 tmp; |
317 | 317 | ||
diff --git a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c index 9d3bd15bf53b..58f0ce8d78e0 100644 --- a/drivers/parisc/eisa.c +++ b/drivers/parisc/eisa.c | |||
@@ -350,7 +350,7 @@ static int __devinit eisa_probe(struct parisc_device *dev) | |||
350 | irq_desc[2].action = &irq2_action; | 350 | irq_desc[2].action = &irq2_action; |
351 | 351 | ||
352 | for (i = 0; i < 16; i++) { | 352 | for (i = 0; i < 16; i++) { |
353 | irq_desc[i].handler = &eisa_interrupt_type; | 353 | irq_desc[i].chip = &eisa_interrupt_type; |
354 | } | 354 | } |
355 | 355 | ||
356 | EISA_bus = 1; | 356 | EISA_bus = 1; |
diff --git a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c index 16d40f95978d..5476ba7709b3 100644 --- a/drivers/parisc/gsc.c +++ b/drivers/parisc/gsc.c | |||
@@ -109,7 +109,7 @@ int gsc_find_local_irq(unsigned int irq, int *global_irqs, int limit) | |||
109 | 109 | ||
110 | static void gsc_asic_disable_irq(unsigned int irq) | 110 | static void gsc_asic_disable_irq(unsigned int irq) |
111 | { | 111 | { |
112 | struct gsc_asic *irq_dev = irq_desc[irq].handler_data; | 112 | struct gsc_asic *irq_dev = irq_desc[irq].chip_data; |
113 | int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32); | 113 | int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32); |
114 | u32 imr; | 114 | u32 imr; |
115 | 115 | ||
@@ -124,7 +124,7 @@ static void gsc_asic_disable_irq(unsigned int irq) | |||
124 | 124 | ||
125 | static void gsc_asic_enable_irq(unsigned int irq) | 125 | static void gsc_asic_enable_irq(unsigned int irq) |
126 | { | 126 | { |
127 | struct gsc_asic *irq_dev = irq_desc[irq].handler_data; | 127 | struct gsc_asic *irq_dev = irq_desc[irq].chip_data; |
128 | int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32); | 128 | int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32); |
129 | u32 imr; | 129 | u32 imr; |
130 | 130 | ||
@@ -164,8 +164,8 @@ int gsc_assign_irq(struct hw_interrupt_type *type, void *data) | |||
164 | if (irq > GSC_IRQ_MAX) | 164 | if (irq > GSC_IRQ_MAX) |
165 | return NO_IRQ; | 165 | return NO_IRQ; |
166 | 166 | ||
167 | irq_desc[irq].handler = type; | 167 | irq_desc[irq].chip = type; |
168 | irq_desc[irq].handler_data = data; | 168 | irq_desc[irq].chip_data = data; |
169 | return irq++; | 169 | return irq++; |
170 | } | 170 | } |
171 | 171 | ||
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c index 7a458d5bc751..1fbda77cefc2 100644 --- a/drivers/parisc/iosapic.c +++ b/drivers/parisc/iosapic.c | |||
@@ -619,7 +619,7 @@ iosapic_set_irt_data( struct vector_info *vi, u32 *dp0, u32 *dp1) | |||
619 | 619 | ||
620 | static struct vector_info *iosapic_get_vector(unsigned int irq) | 620 | static struct vector_info *iosapic_get_vector(unsigned int irq) |
621 | { | 621 | { |
622 | return irq_desc[irq].handler_data; | 622 | return irq_desc[irq].chip_data; |
623 | } | 623 | } |
624 | 624 | ||
625 | static void iosapic_disable_irq(unsigned int irq) | 625 | static void iosapic_disable_irq(unsigned int irq) |
diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c index bbeabe3fc4c6..ea1b7a63598e 100644 --- a/drivers/parisc/pdc_stable.c +++ b/drivers/parisc/pdc_stable.c | |||
@@ -28,8 +28,15 @@ | |||
28 | * following code can deal with just 96 bytes of Stable Storage, and all | 28 | * following code can deal with just 96 bytes of Stable Storage, and all |
29 | * sizes between 96 and 192 bytes (provided they are multiple of struct | 29 | * sizes between 96 and 192 bytes (provided they are multiple of struct |
30 | * device_path size, eg: 128, 160 and 192) to provide full information. | 30 | * device_path size, eg: 128, 160 and 192) to provide full information. |
31 | * The code makes no use of data above 192 bytes. One last word: there's one | 31 | * One last word: there's one path we can always count on: the primary path. |
32 | * path we can always count on: the primary path. | 32 | * Anything above 224 bytes is used for 'osdep2' OS-dependent storage area. |
33 | * | ||
34 | * The first OS-dependent area should always be available. Obviously, this is | ||
35 | * not true for the other one. Also bear in mind that reading/writing from/to | ||
36 | * osdep2 is much more expensive than from/to osdep1. | ||
37 | * NOTE: We do not handle the 2 bytes OS-dep area at 0x5D, nor the first | ||
38 | * 2 bytes of storage available right after OSID. That's a total of 4 bytes | ||
39 | * sacrificed: -ETOOLAZY :P | ||
33 | * | 40 | * |
34 | * The current policy wrt file permissions is: | 41 | * The current policy wrt file permissions is: |
35 | * - write: root only | 42 | * - write: root only |
@@ -64,15 +71,18 @@ | |||
64 | #include <asm/uaccess.h> | 71 | #include <asm/uaccess.h> |
65 | #include <asm/hardware.h> | 72 | #include <asm/hardware.h> |
66 | 73 | ||
67 | #define PDCS_VERSION "0.22" | 74 | #define PDCS_VERSION "0.30" |
68 | #define PDCS_PREFIX "PDC Stable Storage" | 75 | #define PDCS_PREFIX "PDC Stable Storage" |
69 | 76 | ||
70 | #define PDCS_ADDR_PPRI 0x00 | 77 | #define PDCS_ADDR_PPRI 0x00 |
71 | #define PDCS_ADDR_OSID 0x40 | 78 | #define PDCS_ADDR_OSID 0x40 |
79 | #define PDCS_ADDR_OSD1 0x48 | ||
80 | #define PDCS_ADDR_DIAG 0x58 | ||
72 | #define PDCS_ADDR_FSIZ 0x5C | 81 | #define PDCS_ADDR_FSIZ 0x5C |
73 | #define PDCS_ADDR_PCON 0x60 | 82 | #define PDCS_ADDR_PCON 0x60 |
74 | #define PDCS_ADDR_PALT 0x80 | 83 | #define PDCS_ADDR_PALT 0x80 |
75 | #define PDCS_ADDR_PKBD 0xA0 | 84 | #define PDCS_ADDR_PKBD 0xA0 |
85 | #define PDCS_ADDR_OSD2 0xE0 | ||
76 | 86 | ||
77 | MODULE_AUTHOR("Thibaut VARENE <varenet@parisc-linux.org>"); | 87 | MODULE_AUTHOR("Thibaut VARENE <varenet@parisc-linux.org>"); |
78 | MODULE_DESCRIPTION("sysfs interface to HP PDC Stable Storage data"); | 88 | MODULE_DESCRIPTION("sysfs interface to HP PDC Stable Storage data"); |
@@ -82,6 +92,9 @@ MODULE_VERSION(PDCS_VERSION); | |||
82 | /* holds Stable Storage size. Initialized once and for all, no lock needed */ | 92 | /* holds Stable Storage size. Initialized once and for all, no lock needed */ |
83 | static unsigned long pdcs_size __read_mostly; | 93 | static unsigned long pdcs_size __read_mostly; |
84 | 94 | ||
95 | /* holds OS ID. Initialized once and for all, hopefully to 0x0006 */ | ||
96 | static u16 pdcs_osid __read_mostly; | ||
97 | |||
85 | /* This struct defines what we need to deal with a parisc pdc path entry */ | 98 | /* This struct defines what we need to deal with a parisc pdc path entry */ |
86 | struct pdcspath_entry { | 99 | struct pdcspath_entry { |
87 | rwlock_t rw_lock; /* to protect path entry access */ | 100 | rwlock_t rw_lock; /* to protect path entry access */ |
@@ -609,27 +622,64 @@ static ssize_t | |||
609 | pdcs_osid_read(struct subsystem *entry, char *buf) | 622 | pdcs_osid_read(struct subsystem *entry, char *buf) |
610 | { | 623 | { |
611 | char *out = buf; | 624 | char *out = buf; |
612 | __u32 result; | ||
613 | char *tmpstr = NULL; | ||
614 | 625 | ||
615 | if (!entry || !buf) | 626 | if (!entry || !buf) |
616 | return -EINVAL; | 627 | return -EINVAL; |
617 | 628 | ||
618 | /* get OSID */ | 629 | out += sprintf(out, "%s dependent data (0x%.4x)\n", |
619 | if (pdc_stable_read(PDCS_ADDR_OSID, &result, sizeof(result)) != PDC_OK) | 630 | os_id_to_string(pdcs_osid), pdcs_osid); |
631 | |||
632 | return out - buf; | ||
633 | } | ||
634 | |||
635 | /** | ||
636 | * pdcs_osdep1_read - Stable Storage OS-Dependent data area 1 output. | ||
637 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
638 | * @buf: The output buffer to write to. | ||
639 | * | ||
640 | * This can hold 16 bytes of OS-Dependent data. | ||
641 | */ | ||
642 | static ssize_t | ||
643 | pdcs_osdep1_read(struct subsystem *entry, char *buf) | ||
644 | { | ||
645 | char *out = buf; | ||
646 | u32 result[4]; | ||
647 | |||
648 | if (!entry || !buf) | ||
649 | return -EINVAL; | ||
650 | |||
651 | if (pdc_stable_read(PDCS_ADDR_OSD1, &result, sizeof(result)) != PDC_OK) | ||
620 | return -EIO; | 652 | return -EIO; |
621 | 653 | ||
622 | /* the actual result is 16 bits away */ | 654 | out += sprintf(out, "0x%.8x\n", result[0]); |
623 | switch (result >> 16) { | 655 | out += sprintf(out, "0x%.8x\n", result[1]); |
624 | case 0x0000: tmpstr = "No OS-dependent data"; break; | 656 | out += sprintf(out, "0x%.8x\n", result[2]); |
625 | case 0x0001: tmpstr = "HP-UX dependent data"; break; | 657 | out += sprintf(out, "0x%.8x\n", result[3]); |
626 | case 0x0002: tmpstr = "MPE-iX dependent data"; break; | 658 | |
627 | case 0x0003: tmpstr = "OSF dependent data"; break; | 659 | return out - buf; |
628 | case 0x0004: tmpstr = "HP-RT dependent data"; break; | 660 | } |
629 | case 0x0005: tmpstr = "Novell Netware dependent data"; break; | 661 | |
630 | default: tmpstr = "Unknown"; break; | 662 | /** |
631 | } | 663 | * pdcs_diagnostic_read - Stable Storage Diagnostic register output. |
632 | out += sprintf(out, "%s (0x%.4x)\n", tmpstr, (result >> 16)); | 664 | * @entry: An allocated and populated subsytem struct. We don't use it tho. |
665 | * @buf: The output buffer to write to. | ||
666 | * | ||
667 | * I have NFC how to interpret the content of that register ;-). | ||
668 | */ | ||
669 | static ssize_t | ||
670 | pdcs_diagnostic_read(struct subsystem *entry, char *buf) | ||
671 | { | ||
672 | char *out = buf; | ||
673 | u32 result; | ||
674 | |||
675 | if (!entry || !buf) | ||
676 | return -EINVAL; | ||
677 | |||
678 | /* get diagnostic */ | ||
679 | if (pdc_stable_read(PDCS_ADDR_DIAG, &result, sizeof(result)) != PDC_OK) | ||
680 | return -EIO; | ||
681 | |||
682 | out += sprintf(out, "0x%.4x\n", (result >> 16)); | ||
633 | 683 | ||
634 | return out - buf; | 684 | return out - buf; |
635 | } | 685 | } |
@@ -645,7 +695,7 @@ static ssize_t | |||
645 | pdcs_fastsize_read(struct subsystem *entry, char *buf) | 695 | pdcs_fastsize_read(struct subsystem *entry, char *buf) |
646 | { | 696 | { |
647 | char *out = buf; | 697 | char *out = buf; |
648 | __u32 result; | 698 | u32 result; |
649 | 699 | ||
650 | if (!entry || !buf) | 700 | if (!entry || !buf) |
651 | return -EINVAL; | 701 | return -EINVAL; |
@@ -664,6 +714,39 @@ pdcs_fastsize_read(struct subsystem *entry, char *buf) | |||
664 | } | 714 | } |
665 | 715 | ||
666 | /** | 716 | /** |
717 | * pdcs_osdep2_read - Stable Storage OS-Dependent data area 2 output. | ||
718 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
719 | * @buf: The output buffer to write to. | ||
720 | * | ||
721 | * This can hold pdcs_size - 224 bytes of OS-Dependent data, when available. | ||
722 | */ | ||
723 | static ssize_t | ||
724 | pdcs_osdep2_read(struct subsystem *entry, char *buf) | ||
725 | { | ||
726 | char *out = buf; | ||
727 | unsigned long size; | ||
728 | unsigned short i; | ||
729 | u32 result; | ||
730 | |||
731 | if (unlikely(pdcs_size <= 224)) | ||
732 | return -ENODATA; | ||
733 | |||
734 | size = pdcs_size - 224; | ||
735 | |||
736 | if (!entry || !buf) | ||
737 | return -EINVAL; | ||
738 | |||
739 | for (i=0; i<size; i+=4) { | ||
740 | if (unlikely(pdc_stable_read(PDCS_ADDR_OSD2 + i, &result, | ||
741 | sizeof(result)) != PDC_OK)) | ||
742 | return -EIO; | ||
743 | out += sprintf(out, "0x%.8x\n", result); | ||
744 | } | ||
745 | |||
746 | return out - buf; | ||
747 | } | ||
748 | |||
749 | /** | ||
667 | * pdcs_auto_write - This function handles autoboot/search flag modifying. | 750 | * pdcs_auto_write - This function handles autoboot/search flag modifying. |
668 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | 751 | * @entry: An allocated and populated subsytem struct. We don't use it tho. |
669 | * @buf: The input buffer to read from. | 752 | * @buf: The input buffer to read from. |
@@ -770,13 +853,100 @@ pdcs_autosearch_write(struct subsystem *entry, const char *buf, size_t count) | |||
770 | return pdcs_auto_write(entry, buf, count, PF_AUTOSEARCH); | 853 | return pdcs_auto_write(entry, buf, count, PF_AUTOSEARCH); |
771 | } | 854 | } |
772 | 855 | ||
856 | /** | ||
857 | * pdcs_osdep1_write - Stable Storage OS-Dependent data area 1 input. | ||
858 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
859 | * @buf: The input buffer to read from. | ||
860 | * @count: The number of bytes to be read. | ||
861 | * | ||
862 | * This can store 16 bytes of OS-Dependent data. We use a byte-by-byte | ||
863 | * write approach. It's up to userspace to deal with it when constructing | ||
864 | * its input buffer. | ||
865 | */ | ||
866 | static ssize_t | ||
867 | pdcs_osdep1_write(struct subsystem *entry, const char *buf, size_t count) | ||
868 | { | ||
869 | u8 in[16]; | ||
870 | |||
871 | if (!capable(CAP_SYS_ADMIN)) | ||
872 | return -EACCES; | ||
873 | |||
874 | if (!entry || !buf || !count) | ||
875 | return -EINVAL; | ||
876 | |||
877 | if (unlikely(pdcs_osid != OS_ID_LINUX)) | ||
878 | return -EPERM; | ||
879 | |||
880 | if (count > 16) | ||
881 | return -EMSGSIZE; | ||
882 | |||
883 | /* We'll use a local copy of buf */ | ||
884 | memset(in, 0, 16); | ||
885 | memcpy(in, buf, count); | ||
886 | |||
887 | if (pdc_stable_write(PDCS_ADDR_OSD1, &in, sizeof(in)) != PDC_OK) | ||
888 | return -EIO; | ||
889 | |||
890 | return count; | ||
891 | } | ||
892 | |||
893 | /** | ||
894 | * pdcs_osdep2_write - Stable Storage OS-Dependent data area 2 input. | ||
895 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
896 | * @buf: The input buffer to read from. | ||
897 | * @count: The number of bytes to be read. | ||
898 | * | ||
899 | * This can store pdcs_size - 224 bytes of OS-Dependent data. We use a | ||
900 | * byte-by-byte write approach. It's up to userspace to deal with it when | ||
901 | * constructing its input buffer. | ||
902 | */ | ||
903 | static ssize_t | ||
904 | pdcs_osdep2_write(struct subsystem *entry, const char *buf, size_t count) | ||
905 | { | ||
906 | unsigned long size; | ||
907 | unsigned short i; | ||
908 | u8 in[4]; | ||
909 | |||
910 | if (!capable(CAP_SYS_ADMIN)) | ||
911 | return -EACCES; | ||
912 | |||
913 | if (!entry || !buf || !count) | ||
914 | return -EINVAL; | ||
915 | |||
916 | if (unlikely(pdcs_size <= 224)) | ||
917 | return -ENOSYS; | ||
918 | |||
919 | if (unlikely(pdcs_osid != OS_ID_LINUX)) | ||
920 | return -EPERM; | ||
921 | |||
922 | size = pdcs_size - 224; | ||
923 | |||
924 | if (count > size) | ||
925 | return -EMSGSIZE; | ||
926 | |||
927 | /* We'll use a local copy of buf */ | ||
928 | |||
929 | for (i=0; i<count; i+=4) { | ||
930 | memset(in, 0, 4); | ||
931 | memcpy(in, buf+i, (count-i < 4) ? count-i : 4); | ||
932 | if (unlikely(pdc_stable_write(PDCS_ADDR_OSD2 + i, &in, | ||
933 | sizeof(in)) != PDC_OK)) | ||
934 | return -EIO; | ||
935 | } | ||
936 | |||
937 | return count; | ||
938 | } | ||
939 | |||
773 | /* The remaining attributes. */ | 940 | /* The remaining attributes. */ |
774 | static PDCS_ATTR(size, 0444, pdcs_size_read, NULL); | 941 | static PDCS_ATTR(size, 0444, pdcs_size_read, NULL); |
775 | static PDCS_ATTR(autoboot, 0644, pdcs_autoboot_read, pdcs_autoboot_write); | 942 | static PDCS_ATTR(autoboot, 0644, pdcs_autoboot_read, pdcs_autoboot_write); |
776 | static PDCS_ATTR(autosearch, 0644, pdcs_autosearch_read, pdcs_autosearch_write); | 943 | static PDCS_ATTR(autosearch, 0644, pdcs_autosearch_read, pdcs_autosearch_write); |
777 | static PDCS_ATTR(timer, 0444, pdcs_timer_read, NULL); | 944 | static PDCS_ATTR(timer, 0444, pdcs_timer_read, NULL); |
778 | static PDCS_ATTR(osid, 0400, pdcs_osid_read, NULL); | 945 | static PDCS_ATTR(osid, 0444, pdcs_osid_read, NULL); |
946 | static PDCS_ATTR(osdep1, 0600, pdcs_osdep1_read, pdcs_osdep1_write); | ||
947 | static PDCS_ATTR(diagnostic, 0400, pdcs_diagnostic_read, NULL); | ||
779 | static PDCS_ATTR(fastsize, 0400, pdcs_fastsize_read, NULL); | 948 | static PDCS_ATTR(fastsize, 0400, pdcs_fastsize_read, NULL); |
949 | static PDCS_ATTR(osdep2, 0600, pdcs_osdep2_read, pdcs_osdep2_write); | ||
780 | 950 | ||
781 | static struct subsys_attribute *pdcs_subsys_attrs[] = { | 951 | static struct subsys_attribute *pdcs_subsys_attrs[] = { |
782 | &pdcs_attr_size, | 952 | &pdcs_attr_size, |
@@ -784,7 +954,10 @@ static struct subsys_attribute *pdcs_subsys_attrs[] = { | |||
784 | &pdcs_attr_autosearch, | 954 | &pdcs_attr_autosearch, |
785 | &pdcs_attr_timer, | 955 | &pdcs_attr_timer, |
786 | &pdcs_attr_osid, | 956 | &pdcs_attr_osid, |
957 | &pdcs_attr_osdep1, | ||
958 | &pdcs_attr_diagnostic, | ||
787 | &pdcs_attr_fastsize, | 959 | &pdcs_attr_fastsize, |
960 | &pdcs_attr_osdep2, | ||
788 | NULL, | 961 | NULL, |
789 | }; | 962 | }; |
790 | 963 | ||
@@ -865,6 +1038,7 @@ pdc_stable_init(void) | |||
865 | { | 1038 | { |
866 | struct subsys_attribute *attr; | 1039 | struct subsys_attribute *attr; |
867 | int i, rc = 0, error = 0; | 1040 | int i, rc = 0, error = 0; |
1041 | u32 result; | ||
868 | 1042 | ||
869 | /* find the size of the stable storage */ | 1043 | /* find the size of the stable storage */ |
870 | if (pdc_stable_get_size(&pdcs_size) != PDC_OK) | 1044 | if (pdc_stable_get_size(&pdcs_size) != PDC_OK) |
@@ -876,6 +1050,13 @@ pdc_stable_init(void) | |||
876 | 1050 | ||
877 | printk(KERN_INFO PDCS_PREFIX " facility v%s\n", PDCS_VERSION); | 1051 | printk(KERN_INFO PDCS_PREFIX " facility v%s\n", PDCS_VERSION); |
878 | 1052 | ||
1053 | /* get OSID */ | ||
1054 | if (pdc_stable_read(PDCS_ADDR_OSID, &result, sizeof(result)) != PDC_OK) | ||
1055 | return -EIO; | ||
1056 | |||
1057 | /* the actual result is 16 bits away */ | ||
1058 | pdcs_osid = (u16)(result >> 16); | ||
1059 | |||
879 | /* For now we'll register the stable subsys within this driver */ | 1060 | /* For now we'll register the stable subsys within this driver */ |
880 | if ((rc = firmware_register(&stable_subsys))) | 1061 | if ((rc = firmware_register(&stable_subsys))) |
881 | goto fail_firmreg; | 1062 | goto fail_firmreg; |
@@ -887,7 +1068,7 @@ pdc_stable_init(void) | |||
887 | 1068 | ||
888 | /* register the paths subsys as a subsystem of stable subsys */ | 1069 | /* register the paths subsys as a subsystem of stable subsys */ |
889 | kset_set_kset_s(&paths_subsys, stable_subsys); | 1070 | kset_set_kset_s(&paths_subsys, stable_subsys); |
890 | if ((rc= subsystem_register(&paths_subsys))) | 1071 | if ((rc = subsystem_register(&paths_subsys))) |
891 | goto fail_subsysreg; | 1072 | goto fail_subsysreg; |
892 | 1073 | ||
893 | /* now we create all "files" for the paths subsys */ | 1074 | /* now we create all "files" for the paths subsys */ |
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index 278f325021ee..d09e39e39c60 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c | |||
@@ -316,10 +316,10 @@ static int reserve_sba_gart = 1; | |||
316 | ** | 316 | ** |
317 | ** Superdome (in particular, REO) allows only 64-bit CSR accesses. | 317 | ** Superdome (in particular, REO) allows only 64-bit CSR accesses. |
318 | */ | 318 | */ |
319 | #define READ_REG32(addr) le32_to_cpu(__raw_readl(addr)) | 319 | #define READ_REG32(addr) readl(addr) |
320 | #define READ_REG64(addr) le64_to_cpu(__raw_readq(addr)) | 320 | #define READ_REG64(addr) readq(addr) |
321 | #define WRITE_REG32(val, addr) __raw_writel(cpu_to_le32(val), addr) | 321 | #define WRITE_REG32(val, addr) writel((val), (addr)) |
322 | #define WRITE_REG64(val, addr) __raw_writeq(cpu_to_le64(val), addr) | 322 | #define WRITE_REG64(val, addr) writeq((val), (addr)) |
323 | 323 | ||
324 | #ifdef CONFIG_64BIT | 324 | #ifdef CONFIG_64BIT |
325 | #define READ_REG(addr) READ_REG64(addr) | 325 | #define READ_REG(addr) READ_REG64(addr) |
@@ -1427,7 +1427,7 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num) | |||
1427 | iov_order = get_order(iova_space_size >> (IOVP_SHIFT - PAGE_SHIFT)); | 1427 | iov_order = get_order(iova_space_size >> (IOVP_SHIFT - PAGE_SHIFT)); |
1428 | ioc->pdir_size = (iova_space_size / IOVP_SIZE) * sizeof(u64); | 1428 | ioc->pdir_size = (iova_space_size / IOVP_SIZE) * sizeof(u64); |
1429 | 1429 | ||
1430 | DBG_INIT("%s() hpa 0x%lx IOV %dMB (%d bits)\n", | 1430 | DBG_INIT("%s() hpa 0x%p IOV %dMB (%d bits)\n", |
1431 | __FUNCTION__, ioc->ioc_hpa, iova_space_size >> 20, | 1431 | __FUNCTION__, ioc->ioc_hpa, iova_space_size >> 20, |
1432 | iov_order + PAGE_SHIFT); | 1432 | iov_order + PAGE_SHIFT); |
1433 | 1433 | ||
@@ -1764,7 +1764,7 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa, | |||
1764 | 1764 | ||
1765 | sba_dev->num_ioc = num_ioc; | 1765 | sba_dev->num_ioc = num_ioc; |
1766 | for (i = 0; i < num_ioc; i++) { | 1766 | for (i = 0; i < num_ioc; i++) { |
1767 | unsigned long ioc_hpa = sba_dev->ioc[i].ioc_hpa; | 1767 | void __iomem *ioc_hpa = sba_dev->ioc[i].ioc_hpa; |
1768 | unsigned int j; | 1768 | unsigned int j; |
1769 | 1769 | ||
1770 | for (j=0; j < sizeof(u64) * ROPES_PER_IOC; j+=sizeof(u64)) { | 1770 | for (j=0; j < sizeof(u64) * ROPES_PER_IOC; j+=sizeof(u64)) { |
@@ -1776,7 +1776,8 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa, | |||
1776 | * Improves netperf UDP_STREAM by ~10% for bcm5701. | 1776 | * Improves netperf UDP_STREAM by ~10% for bcm5701. |
1777 | */ | 1777 | */ |
1778 | if (IS_PLUTO(sba_dev->iodc)) { | 1778 | if (IS_PLUTO(sba_dev->iodc)) { |
1779 | unsigned long rope_cfg, cfg_val; | 1779 | void __iomem *rope_cfg; |
1780 | unsigned long cfg_val; | ||
1780 | 1781 | ||
1781 | rope_cfg = ioc_hpa + IOC_ROPE0_CFG + j; | 1782 | rope_cfg = ioc_hpa + IOC_ROPE0_CFG + j; |
1782 | cfg_val = READ_REG(rope_cfg); | 1783 | cfg_val = READ_REG(rope_cfg); |
@@ -1902,7 +1903,7 @@ sba_common_init(struct sba_device *sba_dev) | |||
1902 | * (bit #61, big endian), we have to flush and sync every time | 1903 | * (bit #61, big endian), we have to flush and sync every time |
1903 | * IO-PDIR is changed in Ike/Astro. | 1904 | * IO-PDIR is changed in Ike/Astro. |
1904 | */ | 1905 | */ |
1905 | if (boot_cpu_data.pdc.capabilities & PDC_MODEL_IOPDIR_FDC) { | 1906 | if (ioc_needs_fdc) { |
1906 | printk(KERN_INFO MODULE_NAME " FDC/SYNC required.\n"); | 1907 | printk(KERN_INFO MODULE_NAME " FDC/SYNC required.\n"); |
1907 | } else { | 1908 | } else { |
1908 | printk(KERN_INFO MODULE_NAME " IOC has cache coherent PDIR.\n"); | 1909 | printk(KERN_INFO MODULE_NAME " IOC has cache coherent PDIR.\n"); |
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c index 828eb45062de..a988dc7a9abd 100644 --- a/drivers/parisc/superio.c +++ b/drivers/parisc/superio.c | |||
@@ -360,7 +360,7 @@ int superio_fixup_irq(struct pci_dev *pcidev) | |||
360 | #endif | 360 | #endif |
361 | 361 | ||
362 | for (i = 0; i < 16; i++) { | 362 | for (i = 0; i < 16; i++) { |
363 | irq_desc[i].handler = &superio_interrupt_type; | 363 | irq_desc[i].chip = &superio_interrupt_type; |
364 | } | 364 | } |
365 | 365 | ||
366 | /* | 366 | /* |
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 723092682023..5f7db9d2436e 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
@@ -34,11 +34,11 @@ | |||
34 | */ | 34 | */ |
35 | int | 35 | int |
36 | pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, | 36 | pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, |
37 | unsigned long size, unsigned long align, unsigned long min, | 37 | resource_size_t size, resource_size_t align, |
38 | unsigned int type_mask, | 38 | resource_size_t min, unsigned int type_mask, |
39 | void (*alignf)(void *, struct resource *, | 39 | void (*alignf)(void *, struct resource *, resource_size_t, |
40 | unsigned long, unsigned long), | 40 | resource_size_t), |
41 | void *alignf_data) | 41 | void *alignf_data) |
42 | { | 42 | { |
43 | int i, ret = -ENOMEM; | 43 | int i, ret = -ENOMEM; |
44 | 44 | ||
diff --git a/drivers/pci/hotplug/cpcihp_zt5550.c b/drivers/pci/hotplug/cpcihp_zt5550.c index f7cb00da38df..1ec165df8522 100644 --- a/drivers/pci/hotplug/cpcihp_zt5550.c +++ b/drivers/pci/hotplug/cpcihp_zt5550.c | |||
@@ -95,8 +95,8 @@ static int zt5550_hc_config(struct pci_dev *pdev) | |||
95 | 95 | ||
96 | hc_dev = pdev; | 96 | hc_dev = pdev; |
97 | dbg("hc_dev = %p", hc_dev); | 97 | dbg("hc_dev = %p", hc_dev); |
98 | dbg("pci resource start %lx", pci_resource_start(hc_dev, 1)); | 98 | dbg("pci resource start %llx", (unsigned long long)pci_resource_start(hc_dev, 1)); |
99 | dbg("pci resource len %lx", pci_resource_len(hc_dev, 1)); | 99 | dbg("pci resource len %llx", (unsigned long long)pci_resource_len(hc_dev, 1)); |
100 | 100 | ||
101 | if(!request_mem_region(pci_resource_start(hc_dev, 1), | 101 | if(!request_mem_region(pci_resource_start(hc_dev, 1), |
102 | pci_resource_len(hc_dev, 1), MY_NAME)) { | 102 | pci_resource_len(hc_dev, 1), MY_NAME)) { |
@@ -108,8 +108,9 @@ static int zt5550_hc_config(struct pci_dev *pdev) | |||
108 | hc_registers = | 108 | hc_registers = |
109 | ioremap(pci_resource_start(hc_dev, 1), pci_resource_len(hc_dev, 1)); | 109 | ioremap(pci_resource_start(hc_dev, 1), pci_resource_len(hc_dev, 1)); |
110 | if(!hc_registers) { | 110 | if(!hc_registers) { |
111 | err("cannot remap MMIO region %lx @ %lx", | 111 | err("cannot remap MMIO region %llx @ %llx", |
112 | pci_resource_len(hc_dev, 1), pci_resource_start(hc_dev, 1)); | 112 | (unsigned long long)pci_resource_len(hc_dev, 1), |
113 | (unsigned long long)pci_resource_start(hc_dev, 1)); | ||
113 | ret = -ENODEV; | 114 | ret = -ENODEV; |
114 | goto exit_release_region; | 115 | goto exit_release_region; |
115 | } | 116 | } |
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index 9bc1deb8df52..f8658d63f077 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c | |||
@@ -1089,8 +1089,8 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1089 | } | 1089 | } |
1090 | 1090 | ||
1091 | dbg("pdev = %p\n", pdev); | 1091 | dbg("pdev = %p\n", pdev); |
1092 | dbg("pci resource start %lx\n", pci_resource_start(pdev, 0)); | 1092 | dbg("pci resource start %llx\n", (unsigned long long)pci_resource_start(pdev, 0)); |
1093 | dbg("pci resource len %lx\n", pci_resource_len(pdev, 0)); | 1093 | dbg("pci resource len %llx\n", (unsigned long long)pci_resource_len(pdev, 0)); |
1094 | 1094 | ||
1095 | if (!request_mem_region(pci_resource_start(pdev, 0), | 1095 | if (!request_mem_region(pci_resource_start(pdev, 0), |
1096 | pci_resource_len(pdev, 0), MY_NAME)) { | 1096 | pci_resource_len(pdev, 0), MY_NAME)) { |
@@ -1102,9 +1102,9 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1102 | ctrl->hpc_reg = ioremap(pci_resource_start(pdev, 0), | 1102 | ctrl->hpc_reg = ioremap(pci_resource_start(pdev, 0), |
1103 | pci_resource_len(pdev, 0)); | 1103 | pci_resource_len(pdev, 0)); |
1104 | if (!ctrl->hpc_reg) { | 1104 | if (!ctrl->hpc_reg) { |
1105 | err("cannot remap MMIO region %lx @ %lx\n", | 1105 | err("cannot remap MMIO region %llx @ %llx\n", |
1106 | pci_resource_len(pdev, 0), | 1106 | (unsigned long long)pci_resource_len(pdev, 0), |
1107 | pci_resource_start(pdev, 0)); | 1107 | (unsigned long long)pci_resource_start(pdev, 0)); |
1108 | rc = -ENODEV; | 1108 | rc = -ENODEV; |
1109 | goto err_free_mem_region; | 1109 | goto err_free_mem_region; |
1110 | } | 1110 | } |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index d77138ecb098..11f7858f0064 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -1398,8 +1398,9 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) | |||
1398 | 1398 | ||
1399 | for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++) | 1399 | for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++) |
1400 | if (pci_resource_len(pdev, rc) > 0) | 1400 | if (pci_resource_len(pdev, rc) > 0) |
1401 | dbg("pci resource[%d] start=0x%lx(len=0x%lx)\n", rc, | 1401 | dbg("pci resource[%d] start=0x%llx(len=0x%llx)\n", rc, |
1402 | pci_resource_start(pdev, rc), pci_resource_len(pdev, rc)); | 1402 | (unsigned long long)pci_resource_start(pdev, rc), |
1403 | (unsigned long long)pci_resource_len(pdev, rc)); | ||
1403 | 1404 | ||
1404 | info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, | 1405 | info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, |
1405 | pdev->subsystem_vendor, pdev->subsystem_device); | 1406 | pdev->subsystem_vendor, pdev->subsystem_device); |
diff --git a/drivers/pci/hotplug/shpchp_sysfs.c b/drivers/pci/hotplug/shpchp_sysfs.c index f5cfbf2c047c..620e1139e607 100644 --- a/drivers/pci/hotplug/shpchp_sysfs.c +++ b/drivers/pci/hotplug/shpchp_sysfs.c | |||
@@ -51,8 +51,10 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha | |||
51 | res = bus->resource[index]; | 51 | res = bus->resource[index]; |
52 | if (res && (res->flags & IORESOURCE_MEM) && | 52 | if (res && (res->flags & IORESOURCE_MEM) && |
53 | !(res->flags & IORESOURCE_PREFETCH)) { | 53 | !(res->flags & IORESOURCE_PREFETCH)) { |
54 | out += sprintf(out, "start = %8.8lx, length = %8.8lx\n", | 54 | out += sprintf(out, "start = %8.8llx, " |
55 | res->start, (res->end - res->start)); | 55 | "length = %8.8llx\n", |
56 | (unsigned long long)res->start, | ||
57 | (unsigned long long)(res->end - res->start)); | ||
56 | } | 58 | } |
57 | } | 59 | } |
58 | out += sprintf(out, "Free resources: prefetchable memory\n"); | 60 | out += sprintf(out, "Free resources: prefetchable memory\n"); |
@@ -60,16 +62,20 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha | |||
60 | res = bus->resource[index]; | 62 | res = bus->resource[index]; |
61 | if (res && (res->flags & IORESOURCE_MEM) && | 63 | if (res && (res->flags & IORESOURCE_MEM) && |
62 | (res->flags & IORESOURCE_PREFETCH)) { | 64 | (res->flags & IORESOURCE_PREFETCH)) { |
63 | out += sprintf(out, "start = %8.8lx, length = %8.8lx\n", | 65 | out += sprintf(out, "start = %8.8llx, " |
64 | res->start, (res->end - res->start)); | 66 | "length = %8.8llx\n", |
67 | (unsigned long long)res->start, | ||
68 | (unsigned long long)(res->end - res->start)); | ||
65 | } | 69 | } |
66 | } | 70 | } |
67 | out += sprintf(out, "Free resources: IO\n"); | 71 | out += sprintf(out, "Free resources: IO\n"); |
68 | for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) { | 72 | for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) { |
69 | res = bus->resource[index]; | 73 | res = bus->resource[index]; |
70 | if (res && (res->flags & IORESOURCE_IO)) { | 74 | if (res && (res->flags & IORESOURCE_IO)) { |
71 | out += sprintf(out, "start = %8.8lx, length = %8.8lx\n", | 75 | out += sprintf(out, "start = %8.8llx, " |
72 | res->start, (res->end - res->start)); | 76 | "length = %8.8llx\n", |
77 | (unsigned long long)res->start, | ||
78 | (unsigned long long)(res->end - res->start)); | ||
73 | } | 79 | } |
74 | } | 80 | } |
75 | out += sprintf(out, "Free resources: bus numbers\n"); | 81 | out += sprintf(out, "Free resources: bus numbers\n"); |
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 7f8429284fab..76d023d8a33b 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -429,12 +429,12 @@ static void irq_handler_init(int cap_id, int pos, int mask) | |||
429 | 429 | ||
430 | spin_lock_irqsave(&irq_desc[pos].lock, flags); | 430 | spin_lock_irqsave(&irq_desc[pos].lock, flags); |
431 | if (cap_id == PCI_CAP_ID_MSIX) | 431 | if (cap_id == PCI_CAP_ID_MSIX) |
432 | irq_desc[pos].handler = &msix_irq_type; | 432 | irq_desc[pos].chip = &msix_irq_type; |
433 | else { | 433 | else { |
434 | if (!mask) | 434 | if (!mask) |
435 | irq_desc[pos].handler = &msi_irq_wo_maskbit_type; | 435 | irq_desc[pos].chip = &msi_irq_wo_maskbit_type; |
436 | else | 436 | else |
437 | irq_desc[pos].handler = &msi_irq_w_maskbit_type; | 437 | irq_desc[pos].chip = &msi_irq_w_maskbit_type; |
438 | } | 438 | } |
439 | spin_unlock_irqrestore(&irq_desc[pos].lock, flags); | 439 | spin_unlock_irqrestore(&irq_desc[pos].lock, flags); |
440 | } | 440 | } |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index bc405c035ce3..606f9b6f70eb 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -87,7 +87,7 @@ resource_show(struct device * dev, struct device_attribute *attr, char * buf) | |||
87 | char * str = buf; | 87 | char * str = buf; |
88 | int i; | 88 | int i; |
89 | int max = 7; | 89 | int max = 7; |
90 | u64 start, end; | 90 | resource_size_t start, end; |
91 | 91 | ||
92 | if (pci_dev->subordinate) | 92 | if (pci_dev->subordinate) |
93 | max = DEVICE_COUNT_RESOURCE; | 93 | max = DEVICE_COUNT_RESOURCE; |
@@ -365,7 +365,7 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, | |||
365 | struct device, kobj)); | 365 | struct device, kobj)); |
366 | struct resource *res = (struct resource *)attr->private; | 366 | struct resource *res = (struct resource *)attr->private; |
367 | enum pci_mmap_state mmap_type; | 367 | enum pci_mmap_state mmap_type; |
368 | u64 start, end; | 368 | resource_size_t start, end; |
369 | int i; | 369 | int i; |
370 | 370 | ||
371 | for (i = 0; i < PCI_ROM_RESOURCE; i++) | 371 | for (i = 0; i < PCI_ROM_RESOURCE; i++) |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 23d3b17c8cad..cf57d7de3765 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -691,10 +691,12 @@ int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name) | |||
691 | return 0; | 691 | return 0; |
692 | 692 | ||
693 | err_out: | 693 | err_out: |
694 | printk (KERN_WARNING "PCI: Unable to reserve %s region #%d:%lx@%lx for device %s\n", | 694 | printk (KERN_WARNING "PCI: Unable to reserve %s region #%d:%llx@%llx " |
695 | "for device %s\n", | ||
695 | pci_resource_flags(pdev, bar) & IORESOURCE_IO ? "I/O" : "mem", | 696 | pci_resource_flags(pdev, bar) & IORESOURCE_IO ? "I/O" : "mem", |
696 | bar + 1, /* PCI BAR # */ | 697 | bar + 1, /* PCI BAR # */ |
697 | pci_resource_len(pdev, bar), pci_resource_start(pdev, bar), | 698 | (unsigned long long)pci_resource_len(pdev, bar), |
699 | (unsigned long long)pci_resource_start(pdev, bar), | ||
698 | pci_name(pdev)); | 700 | pci_name(pdev)); |
699 | return -EBUSY; | 701 | return -EBUSY; |
700 | } | 702 | } |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 29bdeca031a8..9cc842b666eb 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -6,10 +6,10 @@ extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); | |||
6 | extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev); | 6 | extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev); |
7 | extern void pci_cleanup_rom(struct pci_dev *dev); | 7 | extern void pci_cleanup_rom(struct pci_dev *dev); |
8 | extern int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, | 8 | extern int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, |
9 | unsigned long size, unsigned long align, | 9 | resource_size_t size, resource_size_t align, |
10 | unsigned long min, unsigned int type_mask, | 10 | resource_size_t min, unsigned int type_mask, |
11 | void (*alignf)(void *, struct resource *, | 11 | void (*alignf)(void *, struct resource *, |
12 | unsigned long, unsigned long), | 12 | resource_size_t, resource_size_t), |
13 | void *alignf_data); | 13 | void *alignf_data); |
14 | /* Firmware callbacks */ | 14 | /* Firmware callbacks */ |
15 | extern int (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state); | 15 | extern int (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state); |
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 54b2ebc9c91a..99cf33379769 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c | |||
@@ -302,12 +302,6 @@ static struct file_operations proc_bus_pci_operations = { | |||
302 | #endif /* HAVE_PCI_MMAP */ | 302 | #endif /* HAVE_PCI_MMAP */ |
303 | }; | 303 | }; |
304 | 304 | ||
305 | #if BITS_PER_LONG == 32 | ||
306 | #define LONG_FORMAT "\t%08lx" | ||
307 | #else | ||
308 | #define LONG_FORMAT "\t%16lx" | ||
309 | #endif | ||
310 | |||
311 | /* iterator */ | 305 | /* iterator */ |
312 | static void *pci_seq_start(struct seq_file *m, loff_t *pos) | 306 | static void *pci_seq_start(struct seq_file *m, loff_t *pos) |
313 | { | 307 | { |
@@ -356,18 +350,18 @@ static int show_device(struct seq_file *m, void *v) | |||
356 | dev->irq); | 350 | dev->irq); |
357 | /* Here should be 7 and not PCI_NUM_RESOURCES as we need to preserve compatibility */ | 351 | /* Here should be 7 and not PCI_NUM_RESOURCES as we need to preserve compatibility */ |
358 | for (i=0; i<7; i++) { | 352 | for (i=0; i<7; i++) { |
359 | u64 start, end; | 353 | resource_size_t start, end; |
360 | pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); | 354 | pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); |
361 | seq_printf(m, LONG_FORMAT, | 355 | seq_printf(m, "\t%16llx", |
362 | ((unsigned long)start) | | 356 | (unsigned long long)(start | |
363 | (dev->resource[i].flags & PCI_REGION_FLAG_MASK)); | 357 | (dev->resource[i].flags & PCI_REGION_FLAG_MASK))); |
364 | } | 358 | } |
365 | for (i=0; i<7; i++) { | 359 | for (i=0; i<7; i++) { |
366 | u64 start, end; | 360 | resource_size_t start, end; |
367 | pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); | 361 | pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); |
368 | seq_printf(m, LONG_FORMAT, | 362 | seq_printf(m, "\t%16llx", |
369 | dev->resource[i].start < dev->resource[i].end ? | 363 | dev->resource[i].start < dev->resource[i].end ? |
370 | (unsigned long)(end - start) + 1 : 0); | 364 | (unsigned long long)(end - start) + 1 : 0); |
371 | } | 365 | } |
372 | seq_putc(m, '\t'); | 366 | seq_putc(m, '\t'); |
373 | if (drv) | 367 | if (drv) |
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index 598a115cd00e..cbb69cf41311 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c | |||
@@ -80,8 +80,8 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) | |||
80 | } else { | 80 | } else { |
81 | if (res->flags & IORESOURCE_ROM_COPY) { | 81 | if (res->flags & IORESOURCE_ROM_COPY) { |
82 | *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); | 82 | *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); |
83 | return (void __iomem *)pci_resource_start(pdev, | 83 | return (void __iomem *)(unsigned long) |
84 | PCI_ROM_RESOURCE); | 84 | pci_resource_start(pdev, PCI_ROM_RESOURCE); |
85 | } else { | 85 | } else { |
86 | /* assign the ROM an address if it doesn't have one */ | 86 | /* assign the ROM an address if it doesn't have one */ |
87 | if (res->parent == NULL && | 87 | if (res->parent == NULL && |
@@ -170,11 +170,11 @@ void __iomem *pci_map_rom_copy(struct pci_dev *pdev, size_t *size) | |||
170 | return rom; | 170 | return rom; |
171 | 171 | ||
172 | res->end = res->start + *size; | 172 | res->end = res->start + *size; |
173 | memcpy_fromio((void*)res->start, rom, *size); | 173 | memcpy_fromio((void*)(unsigned long)res->start, rom, *size); |
174 | pci_unmap_rom(pdev, rom); | 174 | pci_unmap_rom(pdev, rom); |
175 | res->flags |= IORESOURCE_ROM_COPY; | 175 | res->flags |= IORESOURCE_ROM_COPY; |
176 | 176 | ||
177 | return (void __iomem *)res->start; | 177 | return (void __iomem *)(unsigned long)res->start; |
178 | } | 178 | } |
179 | 179 | ||
180 | /** | 180 | /** |
@@ -227,7 +227,7 @@ void pci_cleanup_rom(struct pci_dev *pdev) | |||
227 | { | 227 | { |
228 | struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; | 228 | struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; |
229 | if (res->flags & IORESOURCE_ROM_COPY) { | 229 | if (res->flags & IORESOURCE_ROM_COPY) { |
230 | kfree((void*)res->start); | 230 | kfree((void*)(unsigned long)res->start); |
231 | res->flags &= ~IORESOURCE_ROM_COPY; | 231 | res->flags &= ~IORESOURCE_ROM_COPY; |
232 | res->start = 0; | 232 | res->start = 0; |
233 | res->end = 0; | 233 | res->end = 0; |
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 35086e80faa9..47c1071ad84e 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -357,8 +357,10 @@ pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type) | |||
357 | order = __ffs(align) - 20; | 357 | order = __ffs(align) - 20; |
358 | if (order > 11) { | 358 | if (order > 11) { |
359 | printk(KERN_WARNING "PCI: region %s/%d " | 359 | printk(KERN_WARNING "PCI: region %s/%d " |
360 | "too large: %lx-%lx\n", | 360 | "too large: %llx-%llx\n", |
361 | pci_name(dev), i, r->start, r->end); | 361 | pci_name(dev), i, |
362 | (unsigned long long)r->start, | ||
363 | (unsigned long long)r->end); | ||
362 | r->flags = 0; | 364 | r->flags = 0; |
363 | continue; | 365 | continue; |
364 | } | 366 | } |
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 577f4b55c46d..ab78e4bbdd83 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
@@ -40,8 +40,9 @@ pci_update_resource(struct pci_dev *dev, struct resource *res, int resno) | |||
40 | 40 | ||
41 | pcibios_resource_to_bus(dev, ®ion, res); | 41 | pcibios_resource_to_bus(dev, ®ion, res); |
42 | 42 | ||
43 | pr_debug(" got res [%lx:%lx] bus [%lx:%lx] flags %lx for " | 43 | pr_debug(" got res [%llx:%llx] bus [%lx:%lx] flags %lx for " |
44 | "BAR %d of %s\n", res->start, res->end, | 44 | "BAR %d of %s\n", (unsigned long long)res->start, |
45 | (unsigned long long)res->end, | ||
45 | region.start, region.end, res->flags, resno, pci_name(dev)); | 46 | region.start, region.end, res->flags, resno, pci_name(dev)); |
46 | 47 | ||
47 | new = region.start | (res->flags & PCI_REGION_FLAG_MASK); | 48 | new = region.start | (res->flags & PCI_REGION_FLAG_MASK); |
@@ -104,10 +105,12 @@ pci_claim_resource(struct pci_dev *dev, int resource) | |||
104 | err = insert_resource(root, res); | 105 | err = insert_resource(root, res); |
105 | 106 | ||
106 | if (err) { | 107 | if (err) { |
107 | printk(KERN_ERR "PCI: %s region %d of %s %s [%lx:%lx]\n", | 108 | printk(KERN_ERR "PCI: %s region %d of %s %s [%llx:%llx]\n", |
108 | root ? "Address space collision on" : | 109 | root ? "Address space collision on" : |
109 | "No parent found for", | 110 | "No parent found for", |
110 | resource, dtype, pci_name(dev), res->start, res->end); | 111 | resource, dtype, pci_name(dev), |
112 | (unsigned long long)res->start, | ||
113 | (unsigned long long)res->end); | ||
111 | } | 114 | } |
112 | 115 | ||
113 | return err; | 116 | return err; |
@@ -118,7 +121,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
118 | { | 121 | { |
119 | struct pci_bus *bus = dev->bus; | 122 | struct pci_bus *bus = dev->bus; |
120 | struct resource *res = dev->resource + resno; | 123 | struct resource *res = dev->resource + resno; |
121 | unsigned long size, min, align; | 124 | resource_size_t size, min, align; |
122 | int ret; | 125 | int ret; |
123 | 126 | ||
124 | size = res->end - res->start + 1; | 127 | size = res->end - res->start + 1; |
@@ -145,9 +148,11 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
145 | } | 148 | } |
146 | 149 | ||
147 | if (ret) { | 150 | if (ret) { |
148 | printk(KERN_ERR "PCI: Failed to allocate %s resource #%d:%lx@%lx for %s\n", | 151 | printk(KERN_ERR "PCI: Failed to allocate %s resource " |
149 | res->flags & IORESOURCE_IO ? "I/O" : "mem", | 152 | "#%d:%llx@%llx for %s\n", |
150 | resno, size, res->start, pci_name(dev)); | 153 | res->flags & IORESOURCE_IO ? "I/O" : "mem", |
154 | resno, (unsigned long long)size, | ||
155 | (unsigned long long)res->start, pci_name(dev)); | ||
151 | } else if (resno < PCI_BRIDGE_RESOURCES) { | 156 | } else if (resno < PCI_BRIDGE_RESOURCES) { |
152 | pci_update_resource(dev, res, resno); | 157 | pci_update_resource(dev, res, resno); |
153 | } | 158 | } |
@@ -204,7 +209,7 @@ pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) | |||
204 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | 209 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { |
205 | struct resource *r; | 210 | struct resource *r; |
206 | struct resource_list *list, *tmp; | 211 | struct resource_list *list, *tmp; |
207 | unsigned long r_align; | 212 | resource_size_t r_align; |
208 | 213 | ||
209 | r = &dev->resource[i]; | 214 | r = &dev->resource[i]; |
210 | r_align = r->end - r->start; | 215 | r_align = r->end - r->start; |
@@ -213,13 +218,14 @@ pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) | |||
213 | continue; | 218 | continue; |
214 | if (!r_align) { | 219 | if (!r_align) { |
215 | printk(KERN_WARNING "PCI: Ignore bogus resource %d " | 220 | printk(KERN_WARNING "PCI: Ignore bogus resource %d " |
216 | "[%lx:%lx] of %s\n", | 221 | "[%llx:%llx] of %s\n", |
217 | i, r->start, r->end, pci_name(dev)); | 222 | i, (unsigned long long)r->start, |
223 | (unsigned long long)r->end, pci_name(dev)); | ||
218 | continue; | 224 | continue; |
219 | } | 225 | } |
220 | r_align = (i < PCI_BRIDGE_RESOURCES) ? r_align + 1 : r->start; | 226 | r_align = (i < PCI_BRIDGE_RESOURCES) ? r_align + 1 : r->start; |
221 | for (list = head; ; list = list->next) { | 227 | for (list = head; ; list = list->next) { |
222 | unsigned long align = 0; | 228 | resource_size_t align = 0; |
223 | struct resource_list *ln = list->next; | 229 | struct resource_list *ln = list->next; |
224 | int idx; | 230 | int idx; |
225 | 231 | ||
diff --git a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c index b39435bbfaeb..c662e4f89d46 100644 --- a/drivers/pcmcia/hd64465_ss.c +++ b/drivers/pcmcia/hd64465_ss.c | |||
@@ -244,8 +244,8 @@ static void hs_map_irq(hs_socket_t *sp, unsigned int irq) | |||
244 | 244 | ||
245 | hs_mapped_irq[irq].sock = sp; | 245 | hs_mapped_irq[irq].sock = sp; |
246 | /* insert ourselves as the irq controller */ | 246 | /* insert ourselves as the irq controller */ |
247 | hs_mapped_irq[irq].old_handler = irq_desc[irq].handler; | 247 | hs_mapped_irq[irq].old_handler = irq_desc[irq].chip; |
248 | irq_desc[irq].handler = &hd64465_ss_irq_type; | 248 | irq_desc[irq].chip = &hd64465_ss_irq_type; |
249 | } | 249 | } |
250 | 250 | ||
251 | 251 | ||
@@ -260,7 +260,7 @@ static void hs_unmap_irq(hs_socket_t *sp, unsigned int irq) | |||
260 | return; | 260 | return; |
261 | 261 | ||
262 | /* restore the original irq controller */ | 262 | /* restore the original irq controller */ |
263 | irq_desc[irq].handler = hs_mapped_irq[irq].old_handler; | 263 | irq_desc[irq].chip = hs_mapped_irq[irq].old_handler; |
264 | } | 264 | } |
265 | 265 | ||
266 | /*============================================================*/ | 266 | /*============================================================*/ |
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c index a2f05f485156..ff51a65d9433 100644 --- a/drivers/pcmcia/i82365.c +++ b/drivers/pcmcia/i82365.c | |||
@@ -1084,9 +1084,10 @@ static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem) | |||
1084 | u_short base, i; | 1084 | u_short base, i; |
1085 | u_char map; | 1085 | u_char map; |
1086 | 1086 | ||
1087 | debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, %#lx-%#lx, " | 1087 | debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, %#llx-%#llx, " |
1088 | "%#x)\n", sock, mem->map, mem->flags, mem->speed, | 1088 | "%#x)\n", sock, mem->map, mem->flags, mem->speed, |
1089 | mem->res->start, mem->res->end, mem->card_start); | 1089 | (unsigned long long)mem->res->start, |
1090 | (unsigned long long)mem->res->end, mem->card_start); | ||
1090 | 1091 | ||
1091 | map = mem->map; | 1092 | map = mem->map; |
1092 | if ((map > 4) || (mem->card_start > 0x3ffffff) || | 1093 | if ((map > 4) || (mem->card_start > 0x3ffffff) || |
diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c index 247ab837f841..9ee26c1b8635 100644 --- a/drivers/pcmcia/pd6729.c +++ b/drivers/pcmcia/pd6729.c | |||
@@ -642,7 +642,8 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev, | |||
642 | goto err_out_free_mem; | 642 | goto err_out_free_mem; |
643 | 643 | ||
644 | printk(KERN_INFO "pd6729: Cirrus PD6729 PCI to PCMCIA Bridge " | 644 | printk(KERN_INFO "pd6729: Cirrus PD6729 PCI to PCMCIA Bridge " |
645 | "at 0x%lx on irq %d\n", pci_resource_start(dev, 0), dev->irq); | 645 | "at 0x%llx on irq %d\n", |
646 | (unsigned long long)pci_resource_start(dev, 0), dev->irq); | ||
646 | /* | 647 | /* |
647 | * Since we have no memory BARs some firmware may not | 648 | * Since we have no memory BARs some firmware may not |
648 | * have had PCI_COMMAND_MEMORY enabled, yet the device needs it. | 649 | * have had PCI_COMMAND_MEMORY enabled, yet the device needs it. |
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index 0f8b157c9717..c3176b16b7be 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c | |||
@@ -72,7 +72,7 @@ static DEFINE_MUTEX(rsrc_mutex); | |||
72 | ======================================================================*/ | 72 | ======================================================================*/ |
73 | 73 | ||
74 | static struct resource * | 74 | static struct resource * |
75 | make_resource(unsigned long b, unsigned long n, int flags, char *name) | 75 | make_resource(resource_size_t b, resource_size_t n, int flags, char *name) |
76 | { | 76 | { |
77 | struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); | 77 | struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); |
78 | 78 | ||
@@ -86,8 +86,8 @@ make_resource(unsigned long b, unsigned long n, int flags, char *name) | |||
86 | } | 86 | } |
87 | 87 | ||
88 | static struct resource * | 88 | static struct resource * |
89 | claim_region(struct pcmcia_socket *s, unsigned long base, unsigned long size, | 89 | claim_region(struct pcmcia_socket *s, resource_size_t base, |
90 | int type, char *name) | 90 | resource_size_t size, int type, char *name) |
91 | { | 91 | { |
92 | struct resource *res, *parent; | 92 | struct resource *res, *parent; |
93 | 93 | ||
@@ -519,10 +519,10 @@ struct pcmcia_align_data { | |||
519 | 519 | ||
520 | static void | 520 | static void |
521 | pcmcia_common_align(void *align_data, struct resource *res, | 521 | pcmcia_common_align(void *align_data, struct resource *res, |
522 | unsigned long size, unsigned long align) | 522 | resource_size_t size, resource_size_t align) |
523 | { | 523 | { |
524 | struct pcmcia_align_data *data = align_data; | 524 | struct pcmcia_align_data *data = align_data; |
525 | unsigned long start; | 525 | resource_size_t start; |
526 | /* | 526 | /* |
527 | * Ensure that we have the correct start address | 527 | * Ensure that we have the correct start address |
528 | */ | 528 | */ |
@@ -533,8 +533,8 @@ pcmcia_common_align(void *align_data, struct resource *res, | |||
533 | } | 533 | } |
534 | 534 | ||
535 | static void | 535 | static void |
536 | pcmcia_align(void *align_data, struct resource *res, | 536 | pcmcia_align(void *align_data, struct resource *res, resource_size_t size, |
537 | unsigned long size, unsigned long align) | 537 | resource_size_t align) |
538 | { | 538 | { |
539 | struct pcmcia_align_data *data = align_data; | 539 | struct pcmcia_align_data *data = align_data; |
540 | struct resource_map *m; | 540 | struct resource_map *m; |
@@ -808,8 +808,10 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s) | |||
808 | if (res->flags & IORESOURCE_IO) { | 808 | if (res->flags & IORESOURCE_IO) { |
809 | if (res == &ioport_resource) | 809 | if (res == &ioport_resource) |
810 | continue; | 810 | continue; |
811 | printk(KERN_INFO "pcmcia: parent PCI bridge I/O window: 0x%lx - 0x%lx\n", | 811 | printk(KERN_INFO "pcmcia: parent PCI bridge I/O " |
812 | res->start, res->end); | 812 | "window: 0x%llx - 0x%llx\n", |
813 | (unsigned long long)res->start, | ||
814 | (unsigned long long)res->end); | ||
813 | if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end)) | 815 | if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end)) |
814 | done |= IORESOURCE_IO; | 816 | done |= IORESOURCE_IO; |
815 | 817 | ||
@@ -818,8 +820,10 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s) | |||
818 | if (res->flags & IORESOURCE_MEM) { | 820 | if (res->flags & IORESOURCE_MEM) { |
819 | if (res == &iomem_resource) | 821 | if (res == &iomem_resource) |
820 | continue; | 822 | continue; |
821 | printk(KERN_INFO "pcmcia: parent PCI bridge Memory window: 0x%lx - 0x%lx\n", | 823 | printk(KERN_INFO "pcmcia: parent PCI bridge Memory " |
822 | res->start, res->end); | 824 | "window: 0x%llx - 0x%llx\n", |
825 | (unsigned long long)res->start, | ||
826 | (unsigned long long)res->end); | ||
823 | if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end)) | 827 | if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end)) |
824 | done |= IORESOURCE_MEM; | 828 | done |= IORESOURCE_MEM; |
825 | } | 829 | } |
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c index 73bad1d5cb23..65a60671659f 100644 --- a/drivers/pcmcia/tcic.c +++ b/drivers/pcmcia/tcic.c | |||
@@ -756,8 +756,9 @@ static int tcic_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *m | |||
756 | u_long base, len, mmap; | 756 | u_long base, len, mmap; |
757 | 757 | ||
758 | debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, " | 758 | debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, " |
759 | "%#lx-%#lx, %#x)\n", psock, mem->map, mem->flags, | 759 | "%#llx-%#llx, %#x)\n", psock, mem->map, mem->flags, |
760 | mem->speed, mem->res->start, mem->res->end, mem->card_start); | 760 | mem->speed, (unsigned long long)mem->res->start, |
761 | (unsigned long long)mem->res->end, mem->card_start); | ||
761 | if ((mem->map > 3) || (mem->card_start > 0x3ffffff) || | 762 | if ((mem->map > 3) || (mem->card_start > 0x3ffffff) || |
762 | (mem->res->start > 0xffffff) || (mem->res->end > 0xffffff) || | 763 | (mem->res->start > 0xffffff) || (mem->res->end > 0xffffff) || |
763 | (mem->res->start > mem->res->end) || (mem->speed > 1000)) | 764 | (mem->res->start > mem->res->end) || (mem->speed > 1000)) |
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index a2d8ce7fef9c..3163e3d73da1 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c | |||
@@ -264,7 +264,7 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, struct device_at | |||
264 | if (pnp_port_flags(dev, i) & IORESOURCE_DISABLED) | 264 | if (pnp_port_flags(dev, i) & IORESOURCE_DISABLED) |
265 | pnp_printf(buffer," disabled\n"); | 265 | pnp_printf(buffer," disabled\n"); |
266 | else | 266 | else |
267 | pnp_printf(buffer," 0x%lx-0x%lx\n", | 267 | pnp_printf(buffer," 0x%llx-0x%llx\n", |
268 | pnp_port_start(dev, i), | 268 | pnp_port_start(dev, i), |
269 | pnp_port_end(dev, i)); | 269 | pnp_port_end(dev, i)); |
270 | } | 270 | } |
@@ -275,7 +275,7 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, struct device_at | |||
275 | if (pnp_mem_flags(dev, i) & IORESOURCE_DISABLED) | 275 | if (pnp_mem_flags(dev, i) & IORESOURCE_DISABLED) |
276 | pnp_printf(buffer," disabled\n"); | 276 | pnp_printf(buffer," disabled\n"); |
277 | else | 277 | else |
278 | pnp_printf(buffer," 0x%lx-0x%lx\n", | 278 | pnp_printf(buffer," 0x%llx-0x%llx\n", |
279 | pnp_mem_start(dev, i), | 279 | pnp_mem_start(dev, i), |
280 | pnp_mem_end(dev, i)); | 280 | pnp_mem_end(dev, i)); |
281 | } | 281 | } |
@@ -286,7 +286,7 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, struct device_at | |||
286 | if (pnp_irq_flags(dev, i) & IORESOURCE_DISABLED) | 286 | if (pnp_irq_flags(dev, i) & IORESOURCE_DISABLED) |
287 | pnp_printf(buffer," disabled\n"); | 287 | pnp_printf(buffer," disabled\n"); |
288 | else | 288 | else |
289 | pnp_printf(buffer," %ld\n", | 289 | pnp_printf(buffer," %lld\n", |
290 | pnp_irq(dev, i)); | 290 | pnp_irq(dev, i)); |
291 | } | 291 | } |
292 | } | 292 | } |
@@ -296,7 +296,7 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, struct device_at | |||
296 | if (pnp_dma_flags(dev, i) & IORESOURCE_DISABLED) | 296 | if (pnp_dma_flags(dev, i) & IORESOURCE_DISABLED) |
297 | pnp_printf(buffer," disabled\n"); | 297 | pnp_printf(buffer," disabled\n"); |
298 | else | 298 | else |
299 | pnp_printf(buffer," %ld\n", | 299 | pnp_printf(buffer," %lld\n", |
300 | pnp_dma(dev, i)); | 300 | pnp_dma(dev, i)); |
301 | } | 301 | } |
302 | } | 302 | } |
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index 6fff109bdab6..1d7a5b87f4cb 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c | |||
@@ -20,7 +20,8 @@ DECLARE_MUTEX(pnp_res_mutex); | |||
20 | 20 | ||
21 | static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) | 21 | static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) |
22 | { | 22 | { |
23 | unsigned long *start, *end, *flags; | 23 | resource_size_t *start, *end; |
24 | unsigned long *flags; | ||
24 | 25 | ||
25 | if (!dev || !rule) | 26 | if (!dev || !rule) |
26 | return -EINVAL; | 27 | return -EINVAL; |
@@ -63,7 +64,8 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) | |||
63 | 64 | ||
64 | static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) | 65 | static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) |
65 | { | 66 | { |
66 | unsigned long *start, *end, *flags; | 67 | resource_size_t *start, *end; |
68 | unsigned long *flags; | ||
67 | 69 | ||
68 | if (!dev || !rule) | 70 | if (!dev || !rule) |
69 | return -EINVAL; | 71 | return -EINVAL; |
@@ -116,7 +118,8 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) | |||
116 | 118 | ||
117 | static int pnp_assign_irq(struct pnp_dev * dev, struct pnp_irq *rule, int idx) | 119 | static int pnp_assign_irq(struct pnp_dev * dev, struct pnp_irq *rule, int idx) |
118 | { | 120 | { |
119 | unsigned long *start, *end, *flags; | 121 | resource_size_t *start, *end; |
122 | unsigned long *flags; | ||
120 | int i; | 123 | int i; |
121 | 124 | ||
122 | /* IRQ priority: this table is good for i386 */ | 125 | /* IRQ priority: this table is good for i386 */ |
@@ -168,7 +171,8 @@ static int pnp_assign_irq(struct pnp_dev * dev, struct pnp_irq *rule, int idx) | |||
168 | 171 | ||
169 | static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) | 172 | static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) |
170 | { | 173 | { |
171 | unsigned long *start, *end, *flags; | 174 | resource_size_t *start, *end; |
175 | unsigned long *flags; | ||
172 | int i; | 176 | int i; |
173 | 177 | ||
174 | /* DMA priority: this table is good for i386 */ | 178 | /* DMA priority: this table is good for i386 */ |
@@ -582,7 +586,8 @@ int pnp_disable_dev(struct pnp_dev *dev) | |||
582 | * @size: size of region | 586 | * @size: size of region |
583 | * | 587 | * |
584 | */ | 588 | */ |
585 | void pnp_resource_change(struct resource *resource, unsigned long start, unsigned long size) | 589 | void pnp_resource_change(struct resource *resource, resource_size_t start, |
590 | resource_size_t size) | ||
586 | { | 591 | { |
587 | if (resource == NULL) | 592 | if (resource == NULL) |
588 | return; | 593 | return; |
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index 6ded527169f4..7bb892f58cc0 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c | |||
@@ -241,7 +241,7 @@ int pnp_check_port(struct pnp_dev * dev, int idx) | |||
241 | { | 241 | { |
242 | int tmp; | 242 | int tmp; |
243 | struct pnp_dev *tdev; | 243 | struct pnp_dev *tdev; |
244 | unsigned long *port, *end, *tport, *tend; | 244 | resource_size_t *port, *end, *tport, *tend; |
245 | port = &dev->res.port_resource[idx].start; | 245 | port = &dev->res.port_resource[idx].start; |
246 | end = &dev->res.port_resource[idx].end; | 246 | end = &dev->res.port_resource[idx].end; |
247 | 247 | ||
@@ -297,7 +297,7 @@ int pnp_check_mem(struct pnp_dev * dev, int idx) | |||
297 | { | 297 | { |
298 | int tmp; | 298 | int tmp; |
299 | struct pnp_dev *tdev; | 299 | struct pnp_dev *tdev; |
300 | unsigned long *addr, *end, *taddr, *tend; | 300 | resource_size_t *addr, *end, *taddr, *tend; |
301 | addr = &dev->res.mem_resource[idx].start; | 301 | addr = &dev->res.mem_resource[idx].start; |
302 | end = &dev->res.mem_resource[idx].end; | 302 | end = &dev->res.mem_resource[idx].end; |
303 | 303 | ||
@@ -358,7 +358,7 @@ int pnp_check_irq(struct pnp_dev * dev, int idx) | |||
358 | { | 358 | { |
359 | int tmp; | 359 | int tmp; |
360 | struct pnp_dev *tdev; | 360 | struct pnp_dev *tdev; |
361 | unsigned long * irq = &dev->res.irq_resource[idx].start; | 361 | resource_size_t * irq = &dev->res.irq_resource[idx].start; |
362 | 362 | ||
363 | /* if the resource doesn't exist, don't complain about it */ | 363 | /* if the resource doesn't exist, don't complain about it */ |
364 | if (cannot_compare(dev->res.irq_resource[idx].flags)) | 364 | if (cannot_compare(dev->res.irq_resource[idx].flags)) |
@@ -423,7 +423,7 @@ int pnp_check_dma(struct pnp_dev * dev, int idx) | |||
423 | #ifndef CONFIG_IA64 | 423 | #ifndef CONFIG_IA64 |
424 | int tmp; | 424 | int tmp; |
425 | struct pnp_dev *tdev; | 425 | struct pnp_dev *tdev; |
426 | unsigned long * dma = &dev->res.dma_resource[idx].start; | 426 | resource_size_t * dma = &dev->res.dma_resource[idx].start; |
427 | 427 | ||
428 | /* if the resource doesn't exist, don't complain about it */ | 428 | /* if the resource doesn't exist, don't complain about it */ |
429 | if (cannot_compare(dev->res.dma_resource[idx].flags)) | 429 | if (cannot_compare(dev->res.dma_resource[idx].flags)) |
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index cfb1fff3787c..bafcd2f20ae2 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -95,7 +95,7 @@ dasd_alloc_device(void) | |||
95 | spin_lock_init(&device->mem_lock); | 95 | spin_lock_init(&device->mem_lock); |
96 | spin_lock_init(&device->request_queue_lock); | 96 | spin_lock_init(&device->request_queue_lock); |
97 | atomic_set (&device->tasklet_scheduled, 0); | 97 | atomic_set (&device->tasklet_scheduled, 0); |
98 | tasklet_init(&device->tasklet, | 98 | tasklet_init(&device->tasklet, |
99 | (void (*)(unsigned long)) dasd_tasklet, | 99 | (void (*)(unsigned long)) dasd_tasklet, |
100 | (unsigned long) device); | 100 | (unsigned long) device); |
101 | INIT_LIST_HEAD(&device->ccw_queue); | 101 | INIT_LIST_HEAD(&device->ccw_queue); |
@@ -128,7 +128,7 @@ dasd_state_new_to_known(struct dasd_device *device) | |||
128 | int rc; | 128 | int rc; |
129 | 129 | ||
130 | /* | 130 | /* |
131 | * As long as the device is not in state DASD_STATE_NEW we want to | 131 | * As long as the device is not in state DASD_STATE_NEW we want to |
132 | * keep the reference count > 0. | 132 | * keep the reference count > 0. |
133 | */ | 133 | */ |
134 | dasd_get_device(device); | 134 | dasd_get_device(device); |
@@ -336,7 +336,7 @@ dasd_decrease_state(struct dasd_device *device) | |||
336 | if (device->state == DASD_STATE_ONLINE && | 336 | if (device->state == DASD_STATE_ONLINE && |
337 | device->target <= DASD_STATE_READY) | 337 | device->target <= DASD_STATE_READY) |
338 | dasd_state_online_to_ready(device); | 338 | dasd_state_online_to_ready(device); |
339 | 339 | ||
340 | if (device->state == DASD_STATE_READY && | 340 | if (device->state == DASD_STATE_READY && |
341 | device->target <= DASD_STATE_BASIC) | 341 | device->target <= DASD_STATE_BASIC) |
342 | dasd_state_ready_to_basic(device); | 342 | dasd_state_ready_to_basic(device); |
@@ -348,7 +348,7 @@ dasd_decrease_state(struct dasd_device *device) | |||
348 | if (device->state == DASD_STATE_BASIC && | 348 | if (device->state == DASD_STATE_BASIC && |
349 | device->target <= DASD_STATE_KNOWN) | 349 | device->target <= DASD_STATE_KNOWN) |
350 | dasd_state_basic_to_known(device); | 350 | dasd_state_basic_to_known(device); |
351 | 351 | ||
352 | if (device->state == DASD_STATE_KNOWN && | 352 | if (device->state == DASD_STATE_KNOWN && |
353 | device->target <= DASD_STATE_NEW) | 353 | device->target <= DASD_STATE_NEW) |
354 | dasd_state_known_to_new(device); | 354 | dasd_state_known_to_new(device); |
@@ -994,7 +994,7 @@ dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, | |||
994 | ((irb->scsw.cstat << 8) | irb->scsw.dstat), cqr); | 994 | ((irb->scsw.cstat << 8) | irb->scsw.dstat), cqr); |
995 | 995 | ||
996 | /* Find out the appropriate era_action. */ | 996 | /* Find out the appropriate era_action. */ |
997 | if (irb->scsw.fctl & SCSW_FCTL_HALT_FUNC) | 997 | if (irb->scsw.fctl & SCSW_FCTL_HALT_FUNC) |
998 | era = dasd_era_fatal; | 998 | era = dasd_era_fatal; |
999 | else if (irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) && | 999 | else if (irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) && |
1000 | irb->scsw.cstat == 0 && | 1000 | irb->scsw.cstat == 0 && |
@@ -1004,7 +1004,7 @@ dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, | |||
1004 | era = dasd_era_fatal; /* don't recover this request */ | 1004 | era = dasd_era_fatal; /* don't recover this request */ |
1005 | else if (irb->esw.esw0.erw.cons) | 1005 | else if (irb->esw.esw0.erw.cons) |
1006 | era = device->discipline->examine_error(cqr, irb); | 1006 | era = device->discipline->examine_error(cqr, irb); |
1007 | else | 1007 | else |
1008 | era = dasd_era_recover; | 1008 | era = dasd_era_recover; |
1009 | 1009 | ||
1010 | DBF_DEV_EVENT(DBF_DEBUG, device, "era_code %d", era); | 1010 | DBF_DEV_EVENT(DBF_DEBUG, device, "era_code %d", era); |
@@ -1287,7 +1287,7 @@ __dasd_start_head(struct dasd_device * device) | |||
1287 | } | 1287 | } |
1288 | 1288 | ||
1289 | /* | 1289 | /* |
1290 | * Remove requests from the ccw queue. | 1290 | * Remove requests from the ccw queue. |
1291 | */ | 1291 | */ |
1292 | static void | 1292 | static void |
1293 | dasd_flush_ccw_queue(struct dasd_device * device, int all) | 1293 | dasd_flush_ccw_queue(struct dasd_device * device, int all) |
@@ -1450,23 +1450,23 @@ dasd_sleep_on(struct dasd_ccw_req * cqr) | |||
1450 | wait_queue_head_t wait_q; | 1450 | wait_queue_head_t wait_q; |
1451 | struct dasd_device *device; | 1451 | struct dasd_device *device; |
1452 | int rc; | 1452 | int rc; |
1453 | 1453 | ||
1454 | device = cqr->device; | 1454 | device = cqr->device; |
1455 | spin_lock_irq(get_ccwdev_lock(device->cdev)); | 1455 | spin_lock_irq(get_ccwdev_lock(device->cdev)); |
1456 | 1456 | ||
1457 | init_waitqueue_head (&wait_q); | 1457 | init_waitqueue_head (&wait_q); |
1458 | cqr->callback = dasd_wakeup_cb; | 1458 | cqr->callback = dasd_wakeup_cb; |
1459 | cqr->callback_data = (void *) &wait_q; | 1459 | cqr->callback_data = (void *) &wait_q; |
1460 | cqr->status = DASD_CQR_QUEUED; | 1460 | cqr->status = DASD_CQR_QUEUED; |
1461 | list_add_tail(&cqr->list, &device->ccw_queue); | 1461 | list_add_tail(&cqr->list, &device->ccw_queue); |
1462 | 1462 | ||
1463 | /* let the bh start the request to keep them in order */ | 1463 | /* let the bh start the request to keep them in order */ |
1464 | dasd_schedule_bh(device); | 1464 | dasd_schedule_bh(device); |
1465 | 1465 | ||
1466 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); | 1466 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); |
1467 | 1467 | ||
1468 | wait_event(wait_q, _wait_for_wakeup(cqr)); | 1468 | wait_event(wait_q, _wait_for_wakeup(cqr)); |
1469 | 1469 | ||
1470 | /* Request status is either done or failed. */ | 1470 | /* Request status is either done or failed. */ |
1471 | rc = (cqr->status == DASD_CQR_FAILED) ? -EIO : 0; | 1471 | rc = (cqr->status == DASD_CQR_FAILED) ? -EIO : 0; |
1472 | return rc; | 1472 | return rc; |
@@ -1568,7 +1568,7 @@ dasd_sleep_on_immediatly(struct dasd_ccw_req * cqr) | |||
1568 | wait_queue_head_t wait_q; | 1568 | wait_queue_head_t wait_q; |
1569 | struct dasd_device *device; | 1569 | struct dasd_device *device; |
1570 | int rc; | 1570 | int rc; |
1571 | 1571 | ||
1572 | device = cqr->device; | 1572 | device = cqr->device; |
1573 | spin_lock_irq(get_ccwdev_lock(device->cdev)); | 1573 | spin_lock_irq(get_ccwdev_lock(device->cdev)); |
1574 | rc = _dasd_term_running_cqr(device); | 1574 | rc = _dasd_term_running_cqr(device); |
@@ -1576,20 +1576,20 @@ dasd_sleep_on_immediatly(struct dasd_ccw_req * cqr) | |||
1576 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); | 1576 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); |
1577 | return rc; | 1577 | return rc; |
1578 | } | 1578 | } |
1579 | 1579 | ||
1580 | init_waitqueue_head (&wait_q); | 1580 | init_waitqueue_head (&wait_q); |
1581 | cqr->callback = dasd_wakeup_cb; | 1581 | cqr->callback = dasd_wakeup_cb; |
1582 | cqr->callback_data = (void *) &wait_q; | 1582 | cqr->callback_data = (void *) &wait_q; |
1583 | cqr->status = DASD_CQR_QUEUED; | 1583 | cqr->status = DASD_CQR_QUEUED; |
1584 | list_add(&cqr->list, &device->ccw_queue); | 1584 | list_add(&cqr->list, &device->ccw_queue); |
1585 | 1585 | ||
1586 | /* let the bh start the request to keep them in order */ | 1586 | /* let the bh start the request to keep them in order */ |
1587 | dasd_schedule_bh(device); | 1587 | dasd_schedule_bh(device); |
1588 | 1588 | ||
1589 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); | 1589 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); |
1590 | 1590 | ||
1591 | wait_event(wait_q, _wait_for_wakeup(cqr)); | 1591 | wait_event(wait_q, _wait_for_wakeup(cqr)); |
1592 | 1592 | ||
1593 | /* Request status is either done or failed. */ | 1593 | /* Request status is either done or failed. */ |
1594 | rc = (cqr->status == DASD_CQR_FAILED) ? -EIO : 0; | 1594 | rc = (cqr->status == DASD_CQR_FAILED) ? -EIO : 0; |
1595 | return rc; | 1595 | return rc; |
@@ -1725,7 +1725,7 @@ dasd_flush_request_queue(struct dasd_device * device) | |||
1725 | 1725 | ||
1726 | if (!device->request_queue) | 1726 | if (!device->request_queue) |
1727 | return; | 1727 | return; |
1728 | 1728 | ||
1729 | spin_lock_irq(&device->request_queue_lock); | 1729 | spin_lock_irq(&device->request_queue_lock); |
1730 | while (!list_empty(&device->request_queue->queue_head)) { | 1730 | while (!list_empty(&device->request_queue->queue_head)) { |
1731 | req = elv_next_request(device->request_queue); | 1731 | req = elv_next_request(device->request_queue); |
@@ -1855,15 +1855,34 @@ dasd_generic_probe (struct ccw_device *cdev, | |||
1855 | { | 1855 | { |
1856 | int ret; | 1856 | int ret; |
1857 | 1857 | ||
1858 | ret = ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP); | ||
1859 | if (ret) { | ||
1860 | printk(KERN_WARNING | ||
1861 | "dasd_generic_probe: could not set ccw-device options " | ||
1862 | "for %s\n", cdev->dev.bus_id); | ||
1863 | return ret; | ||
1864 | } | ||
1858 | ret = dasd_add_sysfs_files(cdev); | 1865 | ret = dasd_add_sysfs_files(cdev); |
1859 | if (ret) { | 1866 | if (ret) { |
1860 | printk(KERN_WARNING | 1867 | printk(KERN_WARNING |
1861 | "dasd_generic_probe: could not add sysfs entries " | 1868 | "dasd_generic_probe: could not add sysfs entries " |
1862 | "for %s\n", cdev->dev.bus_id); | 1869 | "for %s\n", cdev->dev.bus_id); |
1863 | } else { | 1870 | return ret; |
1864 | cdev->handler = &dasd_int_handler; | ||
1865 | } | 1871 | } |
1872 | cdev->handler = &dasd_int_handler; | ||
1866 | 1873 | ||
1874 | /* | ||
1875 | * Automatically online either all dasd devices (dasd_autodetect) | ||
1876 | * or all devices specified with dasd= parameters during | ||
1877 | * initial probe. | ||
1878 | */ | ||
1879 | if ((dasd_get_feature(cdev, DASD_FEATURE_INITIAL_ONLINE) > 0 ) || | ||
1880 | (dasd_autodetect && dasd_busid_known(cdev->dev.bus_id) != 0)) | ||
1881 | ret = ccw_device_set_online(cdev); | ||
1882 | if (ret) | ||
1883 | printk(KERN_WARNING | ||
1884 | "dasd_generic_probe: could not initially online " | ||
1885 | "ccw-device %s\n", cdev->dev.bus_id); | ||
1867 | return ret; | 1886 | return ret; |
1868 | } | 1887 | } |
1869 | 1888 | ||
@@ -1911,6 +1930,8 @@ dasd_generic_set_online (struct ccw_device *cdev, | |||
1911 | struct dasd_device *device; | 1930 | struct dasd_device *device; |
1912 | int rc; | 1931 | int rc; |
1913 | 1932 | ||
1933 | /* first online clears initial online feature flag */ | ||
1934 | dasd_set_feature(cdev, DASD_FEATURE_INITIAL_ONLINE, 0); | ||
1914 | device = dasd_create_device(cdev); | 1935 | device = dasd_create_device(cdev); |
1915 | if (IS_ERR(device)) | 1936 | if (IS_ERR(device)) |
1916 | return PTR_ERR(device); | 1937 | return PTR_ERR(device); |
@@ -2065,31 +2086,6 @@ dasd_generic_notify(struct ccw_device *cdev, int event) | |||
2065 | return ret; | 2086 | return ret; |
2066 | } | 2087 | } |
2067 | 2088 | ||
2068 | /* | ||
2069 | * Automatically online either all dasd devices (dasd_autodetect) or | ||
2070 | * all devices specified with dasd= parameters. | ||
2071 | */ | ||
2072 | static int | ||
2073 | __dasd_auto_online(struct device *dev, void *data) | ||
2074 | { | ||
2075 | struct ccw_device *cdev; | ||
2076 | |||
2077 | cdev = to_ccwdev(dev); | ||
2078 | if (dasd_autodetect || dasd_busid_known(cdev->dev.bus_id) == 0) | ||
2079 | ccw_device_set_online(cdev); | ||
2080 | return 0; | ||
2081 | } | ||
2082 | |||
2083 | void | ||
2084 | dasd_generic_auto_online (struct ccw_driver *dasd_discipline_driver) | ||
2085 | { | ||
2086 | struct device_driver *drv; | ||
2087 | |||
2088 | drv = get_driver(&dasd_discipline_driver->driver); | ||
2089 | driver_for_each_device(drv, NULL, NULL, __dasd_auto_online); | ||
2090 | put_driver(drv); | ||
2091 | } | ||
2092 | |||
2093 | 2089 | ||
2094 | static int __init | 2090 | static int __init |
2095 | dasd_init(void) | 2091 | dasd_init(void) |
@@ -2170,23 +2166,4 @@ EXPORT_SYMBOL_GPL(dasd_generic_remove); | |||
2170 | EXPORT_SYMBOL_GPL(dasd_generic_notify); | 2166 | EXPORT_SYMBOL_GPL(dasd_generic_notify); |
2171 | EXPORT_SYMBOL_GPL(dasd_generic_set_online); | 2167 | EXPORT_SYMBOL_GPL(dasd_generic_set_online); |
2172 | EXPORT_SYMBOL_GPL(dasd_generic_set_offline); | 2168 | EXPORT_SYMBOL_GPL(dasd_generic_set_offline); |
2173 | EXPORT_SYMBOL_GPL(dasd_generic_auto_online); | ||
2174 | 2169 | ||
2175 | /* | ||
2176 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
2177 | * Emacs will notice this stuff at the end of the file and automatically | ||
2178 | * adjust the settings for this buffer only. This must remain at the end | ||
2179 | * of the file. | ||
2180 | * --------------------------------------------------------------------------- | ||
2181 | * Local variables: | ||
2182 | * c-indent-level: 4 | ||
2183 | * c-brace-imaginary-offset: 0 | ||
2184 | * c-brace-offset: -4 | ||
2185 | * c-argdecl-indent: 4 | ||
2186 | * c-label-offset: -4 | ||
2187 | * c-continued-statement-offset: 4 | ||
2188 | * c-continued-brace-offset: 0 | ||
2189 | * indent-tabs-mode: 1 | ||
2190 | * tab-width: 8 | ||
2191 | * End: | ||
2192 | */ | ||
diff --git a/drivers/s390/block/dasd_3370_erp.c b/drivers/s390/block/dasd_3370_erp.c index 1d11c2a9525d..1ddab8991d92 100644 --- a/drivers/s390/block/dasd_3370_erp.c +++ b/drivers/s390/block/dasd_3370_erp.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * File...........: linux/drivers/s390/block/dasd_3370_erp.c | 2 | * File...........: linux/drivers/s390/block/dasd_3370_erp.c |
3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> | 3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> |
4 | * Bugreports.to..: <Linux390@de.ibm.com> | 4 | * Bugreports.to..: <Linux390@de.ibm.com> |
@@ -12,10 +12,10 @@ | |||
12 | 12 | ||
13 | 13 | ||
14 | /* | 14 | /* |
15 | * DASD_3370_ERP_EXAMINE | 15 | * DASD_3370_ERP_EXAMINE |
16 | * | 16 | * |
17 | * DESCRIPTION | 17 | * DESCRIPTION |
18 | * Checks only for fatal/no/recover error. | 18 | * Checks only for fatal/no/recover error. |
19 | * A detailed examination of the sense data is done later outside | 19 | * A detailed examination of the sense data is done later outside |
20 | * the interrupt handler. | 20 | * the interrupt handler. |
21 | * | 21 | * |
@@ -23,7 +23,7 @@ | |||
23 | * 'Chapter 7. 3370 Sense Data'. | 23 | * 'Chapter 7. 3370 Sense Data'. |
24 | * | 24 | * |
25 | * RETURN VALUES | 25 | * RETURN VALUES |
26 | * dasd_era_none no error | 26 | * dasd_era_none no error |
27 | * dasd_era_fatal for all fatal (unrecoverable errors) | 27 | * dasd_era_fatal for all fatal (unrecoverable errors) |
28 | * dasd_era_recover for all others. | 28 | * dasd_era_recover for all others. |
29 | */ | 29 | */ |
@@ -82,22 +82,3 @@ dasd_3370_erp_examine(struct dasd_ccw_req * cqr, struct irb * irb) | |||
82 | return dasd_era_recover; | 82 | return dasd_era_recover; |
83 | 83 | ||
84 | } /* END dasd_3370_erp_examine */ | 84 | } /* END dasd_3370_erp_examine */ |
85 | |||
86 | /* | ||
87 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
88 | * Emacs will notice this stuff at the end of the file and automatically | ||
89 | * adjust the settings for this buffer only. This must remain at the end | ||
90 | * of the file. | ||
91 | * --------------------------------------------------------------------------- | ||
92 | * Local variables: | ||
93 | * c-indent-level: 4 | ||
94 | * c-brace-imaginary-offset: 0 | ||
95 | * c-brace-offset: -4 | ||
96 | * c-argdecl-indent: 4 | ||
97 | * c-label-offset: -4 | ||
98 | * c-continued-statement-offset: 4 | ||
99 | * c-continued-brace-offset: 0 | ||
100 | * indent-tabs-mode: 1 | ||
101 | * tab-width: 8 | ||
102 | * End: | ||
103 | */ | ||
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c index 2ed51562319e..669805d4402d 100644 --- a/drivers/s390/block/dasd_3990_erp.c +++ b/drivers/s390/block/dasd_3990_erp.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * File...........: linux/drivers/s390/block/dasd_3990_erp.c | 2 | * File...........: linux/drivers/s390/block/dasd_3990_erp.c |
3 | * Author(s)......: Horst Hummel <Horst.Hummel@de.ibm.com> | 3 | * Author(s)......: Horst Hummel <Horst.Hummel@de.ibm.com> |
4 | * Holger Smolinski <Holger.Smolinski@de.ibm.com> | 4 | * Holger Smolinski <Holger.Smolinski@de.ibm.com> |
5 | * Bugreports.to..: <Linux390@de.ibm.com> | 5 | * Bugreports.to..: <Linux390@de.ibm.com> |
6 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000, 2001 | 6 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000, 2001 |
@@ -25,23 +25,23 @@ struct DCTL_data { | |||
25 | } __attribute__ ((packed)); | 25 | } __attribute__ ((packed)); |
26 | 26 | ||
27 | /* | 27 | /* |
28 | ***************************************************************************** | 28 | ***************************************************************************** |
29 | * SECTION ERP EXAMINATION | 29 | * SECTION ERP EXAMINATION |
30 | ***************************************************************************** | 30 | ***************************************************************************** |
31 | */ | 31 | */ |
32 | 32 | ||
33 | /* | 33 | /* |
34 | * DASD_3990_ERP_EXAMINE_24 | 34 | * DASD_3990_ERP_EXAMINE_24 |
35 | * | 35 | * |
36 | * DESCRIPTION | 36 | * DESCRIPTION |
37 | * Checks only for fatal (unrecoverable) error. | 37 | * Checks only for fatal (unrecoverable) error. |
38 | * A detailed examination of the sense data is done later outside | 38 | * A detailed examination of the sense data is done later outside |
39 | * the interrupt handler. | 39 | * the interrupt handler. |
40 | * | 40 | * |
41 | * Each bit configuration leading to an action code 2 (Exit with | 41 | * Each bit configuration leading to an action code 2 (Exit with |
42 | * programming error or unusual condition indication) | 42 | * programming error or unusual condition indication) |
43 | * are handled as fatal error´s. | 43 | * are handled as fatal error´s. |
44 | * | 44 | * |
45 | * All other configurations are handled as recoverable errors. | 45 | * All other configurations are handled as recoverable errors. |
46 | * | 46 | * |
47 | * RETURN VALUES | 47 | * RETURN VALUES |
@@ -93,15 +93,15 @@ dasd_3990_erp_examine_24(struct dasd_ccw_req * cqr, char *sense) | |||
93 | } /* END dasd_3990_erp_examine_24 */ | 93 | } /* END dasd_3990_erp_examine_24 */ |
94 | 94 | ||
95 | /* | 95 | /* |
96 | * DASD_3990_ERP_EXAMINE_32 | 96 | * DASD_3990_ERP_EXAMINE_32 |
97 | * | 97 | * |
98 | * DESCRIPTION | 98 | * DESCRIPTION |
99 | * Checks only for fatal/no/recoverable error. | 99 | * Checks only for fatal/no/recoverable error. |
100 | * A detailed examination of the sense data is done later outside | 100 | * A detailed examination of the sense data is done later outside |
101 | * the interrupt handler. | 101 | * the interrupt handler. |
102 | * | 102 | * |
103 | * RETURN VALUES | 103 | * RETURN VALUES |
104 | * dasd_era_none no error | 104 | * dasd_era_none no error |
105 | * dasd_era_fatal for all fatal (unrecoverable errors) | 105 | * dasd_era_fatal for all fatal (unrecoverable errors) |
106 | * dasd_era_recover for recoverable others. | 106 | * dasd_era_recover for recoverable others. |
107 | */ | 107 | */ |
@@ -128,10 +128,10 @@ dasd_3990_erp_examine_32(struct dasd_ccw_req * cqr, char *sense) | |||
128 | } /* end dasd_3990_erp_examine_32 */ | 128 | } /* end dasd_3990_erp_examine_32 */ |
129 | 129 | ||
130 | /* | 130 | /* |
131 | * DASD_3990_ERP_EXAMINE | 131 | * DASD_3990_ERP_EXAMINE |
132 | * | 132 | * |
133 | * DESCRIPTION | 133 | * DESCRIPTION |
134 | * Checks only for fatal/no/recover error. | 134 | * Checks only for fatal/no/recover error. |
135 | * A detailed examination of the sense data is done later outside | 135 | * A detailed examination of the sense data is done later outside |
136 | * the interrupt handler. | 136 | * the interrupt handler. |
137 | * | 137 | * |
@@ -139,7 +139,7 @@ dasd_3990_erp_examine_32(struct dasd_ccw_req * cqr, char *sense) | |||
139 | * 'Chapter 7. Error Recovery Procedures'. | 139 | * 'Chapter 7. Error Recovery Procedures'. |
140 | * | 140 | * |
141 | * RETURN VALUES | 141 | * RETURN VALUES |
142 | * dasd_era_none no error | 142 | * dasd_era_none no error |
143 | * dasd_era_fatal for all fatal (unrecoverable errors) | 143 | * dasd_era_fatal for all fatal (unrecoverable errors) |
144 | * dasd_era_recover for all others. | 144 | * dasd_era_recover for all others. |
145 | */ | 145 | */ |
@@ -178,18 +178,18 @@ dasd_3990_erp_examine(struct dasd_ccw_req * cqr, struct irb * irb) | |||
178 | } /* END dasd_3990_erp_examine */ | 178 | } /* END dasd_3990_erp_examine */ |
179 | 179 | ||
180 | /* | 180 | /* |
181 | ***************************************************************************** | 181 | ***************************************************************************** |
182 | * SECTION ERP HANDLING | 182 | * SECTION ERP HANDLING |
183 | ***************************************************************************** | 183 | ***************************************************************************** |
184 | */ | 184 | */ |
185 | /* | 185 | /* |
186 | ***************************************************************************** | 186 | ***************************************************************************** |
187 | * 24 and 32 byte sense ERP functions | 187 | * 24 and 32 byte sense ERP functions |
188 | ***************************************************************************** | 188 | ***************************************************************************** |
189 | */ | 189 | */ |
190 | 190 | ||
191 | /* | 191 | /* |
192 | * DASD_3990_ERP_CLEANUP | 192 | * DASD_3990_ERP_CLEANUP |
193 | * | 193 | * |
194 | * DESCRIPTION | 194 | * DESCRIPTION |
195 | * Removes the already build but not necessary ERP request and sets | 195 | * Removes the already build but not necessary ERP request and sets |
@@ -197,10 +197,10 @@ dasd_3990_erp_examine(struct dasd_ccw_req * cqr, struct irb * irb) | |||
197 | * | 197 | * |
198 | * PARAMETER | 198 | * PARAMETER |
199 | * erp request to be blocked | 199 | * erp request to be blocked |
200 | * final_status either DASD_CQR_DONE or DASD_CQR_FAILED | 200 | * final_status either DASD_CQR_DONE or DASD_CQR_FAILED |
201 | * | 201 | * |
202 | * RETURN VALUES | 202 | * RETURN VALUES |
203 | * cqr original cqr | 203 | * cqr original cqr |
204 | */ | 204 | */ |
205 | static struct dasd_ccw_req * | 205 | static struct dasd_ccw_req * |
206 | dasd_3990_erp_cleanup(struct dasd_ccw_req * erp, char final_status) | 206 | dasd_3990_erp_cleanup(struct dasd_ccw_req * erp, char final_status) |
@@ -214,7 +214,7 @@ dasd_3990_erp_cleanup(struct dasd_ccw_req * erp, char final_status) | |||
214 | } /* end dasd_3990_erp_cleanup */ | 214 | } /* end dasd_3990_erp_cleanup */ |
215 | 215 | ||
216 | /* | 216 | /* |
217 | * DASD_3990_ERP_BLOCK_QUEUE | 217 | * DASD_3990_ERP_BLOCK_QUEUE |
218 | * | 218 | * |
219 | * DESCRIPTION | 219 | * DESCRIPTION |
220 | * Block the given device request queue to prevent from further | 220 | * Block the given device request queue to prevent from further |
@@ -237,7 +237,7 @@ dasd_3990_erp_block_queue(struct dasd_ccw_req * erp, int expires) | |||
237 | } | 237 | } |
238 | 238 | ||
239 | /* | 239 | /* |
240 | * DASD_3990_ERP_INT_REQ | 240 | * DASD_3990_ERP_INT_REQ |
241 | * | 241 | * |
242 | * DESCRIPTION | 242 | * DESCRIPTION |
243 | * Handles 'Intervention Required' error. | 243 | * Handles 'Intervention Required' error. |
@@ -277,7 +277,7 @@ dasd_3990_erp_int_req(struct dasd_ccw_req * erp) | |||
277 | } /* end dasd_3990_erp_int_req */ | 277 | } /* end dasd_3990_erp_int_req */ |
278 | 278 | ||
279 | /* | 279 | /* |
280 | * DASD_3990_ERP_ALTERNATE_PATH | 280 | * DASD_3990_ERP_ALTERNATE_PATH |
281 | * | 281 | * |
282 | * DESCRIPTION | 282 | * DESCRIPTION |
283 | * Repeat the operation on a different channel path. | 283 | * Repeat the operation on a different channel path. |
@@ -330,15 +330,15 @@ dasd_3990_erp_alternate_path(struct dasd_ccw_req * erp) | |||
330 | * DASD_3990_ERP_DCTL | 330 | * DASD_3990_ERP_DCTL |
331 | * | 331 | * |
332 | * DESCRIPTION | 332 | * DESCRIPTION |
333 | * Setup cqr to do the Diagnostic Control (DCTL) command with an | 333 | * Setup cqr to do the Diagnostic Control (DCTL) command with an |
334 | * Inhibit Write subcommand (0x20) and the given modifier. | 334 | * Inhibit Write subcommand (0x20) and the given modifier. |
335 | * | 335 | * |
336 | * PARAMETER | 336 | * PARAMETER |
337 | * erp pointer to the current (failed) ERP | 337 | * erp pointer to the current (failed) ERP |
338 | * modifier subcommand modifier | 338 | * modifier subcommand modifier |
339 | * | 339 | * |
340 | * RETURN VALUES | 340 | * RETURN VALUES |
341 | * dctl_cqr pointer to NEW dctl_cqr | 341 | * dctl_cqr pointer to NEW dctl_cqr |
342 | * | 342 | * |
343 | */ | 343 | */ |
344 | static struct dasd_ccw_req * | 344 | static struct dasd_ccw_req * |
@@ -386,7 +386,7 @@ dasd_3990_erp_DCTL(struct dasd_ccw_req * erp, char modifier) | |||
386 | } /* end dasd_3990_erp_DCTL */ | 386 | } /* end dasd_3990_erp_DCTL */ |
387 | 387 | ||
388 | /* | 388 | /* |
389 | * DASD_3990_ERP_ACTION_1 | 389 | * DASD_3990_ERP_ACTION_1 |
390 | * | 390 | * |
391 | * DESCRIPTION | 391 | * DESCRIPTION |
392 | * Setup ERP to do the ERP action 1 (see Reference manual). | 392 | * Setup ERP to do the ERP action 1 (see Reference manual). |
@@ -415,7 +415,7 @@ dasd_3990_erp_action_1(struct dasd_ccw_req * erp) | |||
415 | } /* end dasd_3990_erp_action_1 */ | 415 | } /* end dasd_3990_erp_action_1 */ |
416 | 416 | ||
417 | /* | 417 | /* |
418 | * DASD_3990_ERP_ACTION_4 | 418 | * DASD_3990_ERP_ACTION_4 |
419 | * | 419 | * |
420 | * DESCRIPTION | 420 | * DESCRIPTION |
421 | * Setup ERP to do the ERP action 4 (see Reference manual). | 421 | * Setup ERP to do the ERP action 4 (see Reference manual). |
@@ -453,11 +453,11 @@ dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense) | |||
453 | 453 | ||
454 | if (sense[25] == 0x1D) { /* state change pending */ | 454 | if (sense[25] == 0x1D) { /* state change pending */ |
455 | 455 | ||
456 | DEV_MESSAGE(KERN_INFO, device, | 456 | DEV_MESSAGE(KERN_INFO, device, |
457 | "waiting for state change pending " | 457 | "waiting for state change pending " |
458 | "interrupt, %d retries left", | 458 | "interrupt, %d retries left", |
459 | erp->retries); | 459 | erp->retries); |
460 | 460 | ||
461 | dasd_3990_erp_block_queue(erp, 30*HZ); | 461 | dasd_3990_erp_block_queue(erp, 30*HZ); |
462 | 462 | ||
463 | } else if (sense[25] == 0x1E) { /* busy */ | 463 | } else if (sense[25] == 0x1E) { /* busy */ |
@@ -469,9 +469,9 @@ dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense) | |||
469 | } else { | 469 | } else { |
470 | 470 | ||
471 | /* no state change pending - retry */ | 471 | /* no state change pending - retry */ |
472 | DEV_MESSAGE (KERN_INFO, device, | 472 | DEV_MESSAGE (KERN_INFO, device, |
473 | "redriving request immediately, " | 473 | "redriving request immediately, " |
474 | "%d retries left", | 474 | "%d retries left", |
475 | erp->retries); | 475 | erp->retries); |
476 | erp->status = DASD_CQR_QUEUED; | 476 | erp->status = DASD_CQR_QUEUED; |
477 | } | 477 | } |
@@ -482,13 +482,13 @@ dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense) | |||
482 | } /* end dasd_3990_erp_action_4 */ | 482 | } /* end dasd_3990_erp_action_4 */ |
483 | 483 | ||
484 | /* | 484 | /* |
485 | ***************************************************************************** | 485 | ***************************************************************************** |
486 | * 24 byte sense ERP functions (only) | 486 | * 24 byte sense ERP functions (only) |
487 | ***************************************************************************** | 487 | ***************************************************************************** |
488 | */ | 488 | */ |
489 | 489 | ||
490 | /* | 490 | /* |
491 | * DASD_3990_ERP_ACTION_5 | 491 | * DASD_3990_ERP_ACTION_5 |
492 | * | 492 | * |
493 | * DESCRIPTION | 493 | * DESCRIPTION |
494 | * Setup ERP to do the ERP action 5 (see Reference manual). | 494 | * Setup ERP to do the ERP action 5 (see Reference manual). |
@@ -523,7 +523,7 @@ dasd_3990_erp_action_5(struct dasd_ccw_req * erp) | |||
523 | * | 523 | * |
524 | * PARAMETER | 524 | * PARAMETER |
525 | * sense current sense data | 525 | * sense current sense data |
526 | * | 526 | * |
527 | * RETURN VALUES | 527 | * RETURN VALUES |
528 | * void | 528 | * void |
529 | */ | 529 | */ |
@@ -1150,9 +1150,9 @@ dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense) | |||
1150 | * PARAMETER | 1150 | * PARAMETER |
1151 | * erp current erp_head | 1151 | * erp current erp_head |
1152 | * sense current sense data | 1152 | * sense current sense data |
1153 | * | 1153 | * |
1154 | * RETURN VALUES | 1154 | * RETURN VALUES |
1155 | * erp 'new' erp_head - pointer to new ERP | 1155 | * erp 'new' erp_head - pointer to new ERP |
1156 | */ | 1156 | */ |
1157 | static struct dasd_ccw_req * | 1157 | static struct dasd_ccw_req * |
1158 | dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense) | 1158 | dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense) |
@@ -1185,7 +1185,7 @@ dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense) | |||
1185 | } /* end dasd_3990_erp_com_rej */ | 1185 | } /* end dasd_3990_erp_com_rej */ |
1186 | 1186 | ||
1187 | /* | 1187 | /* |
1188 | * DASD_3990_ERP_BUS_OUT | 1188 | * DASD_3990_ERP_BUS_OUT |
1189 | * | 1189 | * |
1190 | * DESCRIPTION | 1190 | * DESCRIPTION |
1191 | * Handles 24 byte 'Bus Out Parity Check' error. | 1191 | * Handles 24 byte 'Bus Out Parity Check' error. |
@@ -1483,7 +1483,7 @@ dasd_3990_erp_env_data(struct dasd_ccw_req * erp, char *sense) | |||
1483 | * | 1483 | * |
1484 | * PARAMETER | 1484 | * PARAMETER |
1485 | * erp already added default ERP | 1485 | * erp already added default ERP |
1486 | * | 1486 | * |
1487 | * RETURN VALUES | 1487 | * RETURN VALUES |
1488 | * erp new erp_head - pointer to new ERP | 1488 | * erp new erp_head - pointer to new ERP |
1489 | */ | 1489 | */ |
@@ -1527,11 +1527,11 @@ dasd_3990_erp_file_prot(struct dasd_ccw_req * erp) | |||
1527 | } /* end dasd_3990_erp_file_prot */ | 1527 | } /* end dasd_3990_erp_file_prot */ |
1528 | 1528 | ||
1529 | /* | 1529 | /* |
1530 | * DASD_3990_ERP_INSPECT_24 | 1530 | * DASD_3990_ERP_INSPECT_24 |
1531 | * | 1531 | * |
1532 | * DESCRIPTION | 1532 | * DESCRIPTION |
1533 | * Does a detailed inspection of the 24 byte sense data | 1533 | * Does a detailed inspection of the 24 byte sense data |
1534 | * and sets up a related error recovery action. | 1534 | * and sets up a related error recovery action. |
1535 | * | 1535 | * |
1536 | * PARAMETER | 1536 | * PARAMETER |
1537 | * sense sense data of the actual error | 1537 | * sense sense data of the actual error |
@@ -1602,13 +1602,13 @@ dasd_3990_erp_inspect_24(struct dasd_ccw_req * erp, char *sense) | |||
1602 | } /* END dasd_3990_erp_inspect_24 */ | 1602 | } /* END dasd_3990_erp_inspect_24 */ |
1603 | 1603 | ||
1604 | /* | 1604 | /* |
1605 | ***************************************************************************** | 1605 | ***************************************************************************** |
1606 | * 32 byte sense ERP functions (only) | 1606 | * 32 byte sense ERP functions (only) |
1607 | ***************************************************************************** | 1607 | ***************************************************************************** |
1608 | */ | 1608 | */ |
1609 | 1609 | ||
1610 | /* | 1610 | /* |
1611 | * DASD_3990_ERPACTION_10_32 | 1611 | * DASD_3990_ERPACTION_10_32 |
1612 | * | 1612 | * |
1613 | * DESCRIPTION | 1613 | * DESCRIPTION |
1614 | * Handles 32 byte 'Action 10' of Single Program Action Codes. | 1614 | * Handles 32 byte 'Action 10' of Single Program Action Codes. |
@@ -1616,7 +1616,7 @@ dasd_3990_erp_inspect_24(struct dasd_ccw_req * erp, char *sense) | |||
1616 | * | 1616 | * |
1617 | * PARAMETER | 1617 | * PARAMETER |
1618 | * erp current erp_head | 1618 | * erp current erp_head |
1619 | * sense current sense data | 1619 | * sense current sense data |
1620 | * RETURN VALUES | 1620 | * RETURN VALUES |
1621 | * erp modified erp_head | 1621 | * erp modified erp_head |
1622 | */ | 1622 | */ |
@@ -1640,18 +1640,18 @@ dasd_3990_erp_action_10_32(struct dasd_ccw_req * erp, char *sense) | |||
1640 | * | 1640 | * |
1641 | * DESCRIPTION | 1641 | * DESCRIPTION |
1642 | * Handles 32 byte 'Action 1B' of Single Program Action Codes. | 1642 | * Handles 32 byte 'Action 1B' of Single Program Action Codes. |
1643 | * A write operation could not be finished because of an unexpected | 1643 | * A write operation could not be finished because of an unexpected |
1644 | * condition. | 1644 | * condition. |
1645 | * The already created 'default erp' is used to get the link to | 1645 | * The already created 'default erp' is used to get the link to |
1646 | * the erp chain, but it can not be used for this recovery | 1646 | * the erp chain, but it can not be used for this recovery |
1647 | * action because it contains no DE/LO data space. | 1647 | * action because it contains no DE/LO data space. |
1648 | * | 1648 | * |
1649 | * PARAMETER | 1649 | * PARAMETER |
1650 | * default_erp already added default erp. | 1650 | * default_erp already added default erp. |
1651 | * sense current sense data | 1651 | * sense current sense data |
1652 | * | 1652 | * |
1653 | * RETURN VALUES | 1653 | * RETURN VALUES |
1654 | * erp new erp or | 1654 | * erp new erp or |
1655 | * default_erp in case of imprecise ending or error | 1655 | * default_erp in case of imprecise ending or error |
1656 | */ | 1656 | */ |
1657 | static struct dasd_ccw_req * | 1657 | static struct dasd_ccw_req * |
@@ -1789,16 +1789,16 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense) | |||
1789 | * DASD_3990_UPDATE_1B | 1789 | * DASD_3990_UPDATE_1B |
1790 | * | 1790 | * |
1791 | * DESCRIPTION | 1791 | * DESCRIPTION |
1792 | * Handles the update to the 32 byte 'Action 1B' of Single Program | 1792 | * Handles the update to the 32 byte 'Action 1B' of Single Program |
1793 | * Action Codes in case the first action was not successful. | 1793 | * Action Codes in case the first action was not successful. |
1794 | * The already created 'previous_erp' is the currently not successful | 1794 | * The already created 'previous_erp' is the currently not successful |
1795 | * ERP. | 1795 | * ERP. |
1796 | * | 1796 | * |
1797 | * PARAMETER | 1797 | * PARAMETER |
1798 | * previous_erp already created previous erp. | 1798 | * previous_erp already created previous erp. |
1799 | * sense current sense data | 1799 | * sense current sense data |
1800 | * RETURN VALUES | 1800 | * RETURN VALUES |
1801 | * erp modified erp | 1801 | * erp modified erp |
1802 | */ | 1802 | */ |
1803 | static struct dasd_ccw_req * | 1803 | static struct dasd_ccw_req * |
1804 | dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense) | 1804 | dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense) |
@@ -1897,7 +1897,7 @@ dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense) | |||
1897 | } /* end dasd_3990_update_1B */ | 1897 | } /* end dasd_3990_update_1B */ |
1898 | 1898 | ||
1899 | /* | 1899 | /* |
1900 | * DASD_3990_ERP_COMPOUND_RETRY | 1900 | * DASD_3990_ERP_COMPOUND_RETRY |
1901 | * | 1901 | * |
1902 | * DESCRIPTION | 1902 | * DESCRIPTION |
1903 | * Handles the compound ERP action retry code. | 1903 | * Handles the compound ERP action retry code. |
@@ -1943,7 +1943,7 @@ dasd_3990_erp_compound_retry(struct dasd_ccw_req * erp, char *sense) | |||
1943 | } /* end dasd_3990_erp_compound_retry */ | 1943 | } /* end dasd_3990_erp_compound_retry */ |
1944 | 1944 | ||
1945 | /* | 1945 | /* |
1946 | * DASD_3990_ERP_COMPOUND_PATH | 1946 | * DASD_3990_ERP_COMPOUND_PATH |
1947 | * | 1947 | * |
1948 | * DESCRIPTION | 1948 | * DESCRIPTION |
1949 | * Handles the compound ERP action for retry on alternate | 1949 | * Handles the compound ERP action for retry on alternate |
@@ -1965,7 +1965,7 @@ dasd_3990_erp_compound_path(struct dasd_ccw_req * erp, char *sense) | |||
1965 | dasd_3990_erp_alternate_path(erp); | 1965 | dasd_3990_erp_alternate_path(erp); |
1966 | 1966 | ||
1967 | if (erp->status == DASD_CQR_FAILED) { | 1967 | if (erp->status == DASD_CQR_FAILED) { |
1968 | /* reset the lpm and the status to be able to | 1968 | /* reset the lpm and the status to be able to |
1969 | * try further actions. */ | 1969 | * try further actions. */ |
1970 | 1970 | ||
1971 | erp->lpm = 0; | 1971 | erp->lpm = 0; |
@@ -1980,7 +1980,7 @@ dasd_3990_erp_compound_path(struct dasd_ccw_req * erp, char *sense) | |||
1980 | } /* end dasd_3990_erp_compound_path */ | 1980 | } /* end dasd_3990_erp_compound_path */ |
1981 | 1981 | ||
1982 | /* | 1982 | /* |
1983 | * DASD_3990_ERP_COMPOUND_CODE | 1983 | * DASD_3990_ERP_COMPOUND_CODE |
1984 | * | 1984 | * |
1985 | * DESCRIPTION | 1985 | * DESCRIPTION |
1986 | * Handles the compound ERP action for retry code. | 1986 | * Handles the compound ERP action for retry code. |
@@ -2001,18 +2001,18 @@ dasd_3990_erp_compound_code(struct dasd_ccw_req * erp, char *sense) | |||
2001 | 2001 | ||
2002 | switch (sense[28]) { | 2002 | switch (sense[28]) { |
2003 | case 0x17: | 2003 | case 0x17: |
2004 | /* issue a Diagnostic Control command with an | 2004 | /* issue a Diagnostic Control command with an |
2005 | * Inhibit Write subcommand and controler modifier */ | 2005 | * Inhibit Write subcommand and controler modifier */ |
2006 | erp = dasd_3990_erp_DCTL(erp, 0x20); | 2006 | erp = dasd_3990_erp_DCTL(erp, 0x20); |
2007 | break; | 2007 | break; |
2008 | 2008 | ||
2009 | case 0x25: | 2009 | case 0x25: |
2010 | /* wait for 5 seconds and retry again */ | 2010 | /* wait for 5 seconds and retry again */ |
2011 | erp->retries = 1; | 2011 | erp->retries = 1; |
2012 | 2012 | ||
2013 | dasd_3990_erp_block_queue (erp, 5*HZ); | 2013 | dasd_3990_erp_block_queue (erp, 5*HZ); |
2014 | break; | 2014 | break; |
2015 | 2015 | ||
2016 | default: | 2016 | default: |
2017 | /* should not happen - continue */ | 2017 | /* should not happen - continue */ |
2018 | break; | 2018 | break; |
@@ -2026,7 +2026,7 @@ dasd_3990_erp_compound_code(struct dasd_ccw_req * erp, char *sense) | |||
2026 | } /* end dasd_3990_erp_compound_code */ | 2026 | } /* end dasd_3990_erp_compound_code */ |
2027 | 2027 | ||
2028 | /* | 2028 | /* |
2029 | * DASD_3990_ERP_COMPOUND_CONFIG | 2029 | * DASD_3990_ERP_COMPOUND_CONFIG |
2030 | * | 2030 | * |
2031 | * DESCRIPTION | 2031 | * DESCRIPTION |
2032 | * Handles the compound ERP action for configruation | 2032 | * Handles the compound ERP action for configruation |
@@ -2063,10 +2063,10 @@ dasd_3990_erp_compound_config(struct dasd_ccw_req * erp, char *sense) | |||
2063 | } /* end dasd_3990_erp_compound_config */ | 2063 | } /* end dasd_3990_erp_compound_config */ |
2064 | 2064 | ||
2065 | /* | 2065 | /* |
2066 | * DASD_3990_ERP_COMPOUND | 2066 | * DASD_3990_ERP_COMPOUND |
2067 | * | 2067 | * |
2068 | * DESCRIPTION | 2068 | * DESCRIPTION |
2069 | * Does the further compound program action if | 2069 | * Does the further compound program action if |
2070 | * compound retry was not successful. | 2070 | * compound retry was not successful. |
2071 | * | 2071 | * |
2072 | * PARAMETER | 2072 | * PARAMETER |
@@ -2110,11 +2110,11 @@ dasd_3990_erp_compound(struct dasd_ccw_req * erp, char *sense) | |||
2110 | } /* end dasd_3990_erp_compound */ | 2110 | } /* end dasd_3990_erp_compound */ |
2111 | 2111 | ||
2112 | /* | 2112 | /* |
2113 | * DASD_3990_ERP_INSPECT_32 | 2113 | * DASD_3990_ERP_INSPECT_32 |
2114 | * | 2114 | * |
2115 | * DESCRIPTION | 2115 | * DESCRIPTION |
2116 | * Does a detailed inspection of the 32 byte sense data | 2116 | * Does a detailed inspection of the 32 byte sense data |
2117 | * and sets up a related error recovery action. | 2117 | * and sets up a related error recovery action. |
2118 | * | 2118 | * |
2119 | * PARAMETER | 2119 | * PARAMETER |
2120 | * sense sense data of the actual error | 2120 | * sense sense data of the actual error |
@@ -2228,9 +2228,9 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense) | |||
2228 | } /* end dasd_3990_erp_inspect_32 */ | 2228 | } /* end dasd_3990_erp_inspect_32 */ |
2229 | 2229 | ||
2230 | /* | 2230 | /* |
2231 | ***************************************************************************** | 2231 | ***************************************************************************** |
2232 | * main ERP control fuctions (24 and 32 byte sense) | 2232 | * main ERP control fuctions (24 and 32 byte sense) |
2233 | ***************************************************************************** | 2233 | ***************************************************************************** |
2234 | */ | 2234 | */ |
2235 | 2235 | ||
2236 | /* | 2236 | /* |
@@ -2243,7 +2243,7 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense) | |||
2243 | * PARAMETER | 2243 | * PARAMETER |
2244 | * erp pointer to the currently created default ERP | 2244 | * erp pointer to the currently created default ERP |
2245 | * RETURN VALUES | 2245 | * RETURN VALUES |
2246 | * erp_new contens was possibly modified | 2246 | * erp_new contens was possibly modified |
2247 | */ | 2247 | */ |
2248 | static struct dasd_ccw_req * | 2248 | static struct dasd_ccw_req * |
2249 | dasd_3990_erp_inspect(struct dasd_ccw_req * erp) | 2249 | dasd_3990_erp_inspect(struct dasd_ccw_req * erp) |
@@ -2272,14 +2272,14 @@ dasd_3990_erp_inspect(struct dasd_ccw_req * erp) | |||
2272 | 2272 | ||
2273 | /* | 2273 | /* |
2274 | * DASD_3990_ERP_ADD_ERP | 2274 | * DASD_3990_ERP_ADD_ERP |
2275 | * | 2275 | * |
2276 | * DESCRIPTION | 2276 | * DESCRIPTION |
2277 | * This funtion adds an additional request block (ERP) to the head of | 2277 | * This funtion adds an additional request block (ERP) to the head of |
2278 | * the given cqr (or erp). | 2278 | * the given cqr (or erp). |
2279 | * This erp is initialized as an default erp (retry TIC) | 2279 | * This erp is initialized as an default erp (retry TIC) |
2280 | * | 2280 | * |
2281 | * PARAMETER | 2281 | * PARAMETER |
2282 | * cqr head of the current ERP-chain (or single cqr if | 2282 | * cqr head of the current ERP-chain (or single cqr if |
2283 | * first error) | 2283 | * first error) |
2284 | * RETURN VALUES | 2284 | * RETURN VALUES |
2285 | * erp pointer to new ERP-chain head | 2285 | * erp pointer to new ERP-chain head |
@@ -2332,15 +2332,15 @@ dasd_3990_erp_add_erp(struct dasd_ccw_req * cqr) | |||
2332 | } | 2332 | } |
2333 | 2333 | ||
2334 | /* | 2334 | /* |
2335 | * DASD_3990_ERP_ADDITIONAL_ERP | 2335 | * DASD_3990_ERP_ADDITIONAL_ERP |
2336 | * | 2336 | * |
2337 | * DESCRIPTION | 2337 | * DESCRIPTION |
2338 | * An additional ERP is needed to handle the current error. | 2338 | * An additional ERP is needed to handle the current error. |
2339 | * Add ERP to the head of the ERP-chain containing the ERP processing | 2339 | * Add ERP to the head of the ERP-chain containing the ERP processing |
2340 | * determined based on the sense data. | 2340 | * determined based on the sense data. |
2341 | * | 2341 | * |
2342 | * PARAMETER | 2342 | * PARAMETER |
2343 | * cqr head of the current ERP-chain (or single cqr if | 2343 | * cqr head of the current ERP-chain (or single cqr if |
2344 | * first error) | 2344 | * first error) |
2345 | * | 2345 | * |
2346 | * RETURN VALUES | 2346 | * RETURN VALUES |
@@ -2376,7 +2376,7 @@ dasd_3990_erp_additional_erp(struct dasd_ccw_req * cqr) | |||
2376 | * 24 byte sense byte 25 and 27 is set as well. | 2376 | * 24 byte sense byte 25 and 27 is set as well. |
2377 | * | 2377 | * |
2378 | * PARAMETER | 2378 | * PARAMETER |
2379 | * cqr1 first cqr, which will be compared with the | 2379 | * cqr1 first cqr, which will be compared with the |
2380 | * cqr2 second cqr. | 2380 | * cqr2 second cqr. |
2381 | * | 2381 | * |
2382 | * RETURN VALUES | 2382 | * RETURN VALUES |
@@ -2415,7 +2415,7 @@ dasd_3990_erp_error_match(struct dasd_ccw_req *cqr1, struct dasd_ccw_req *cqr2) | |||
2415 | * cqr failed cqr (either original cqr or already an erp) | 2415 | * cqr failed cqr (either original cqr or already an erp) |
2416 | * | 2416 | * |
2417 | * RETURN VALUES | 2417 | * RETURN VALUES |
2418 | * erp erp-pointer to the already defined error | 2418 | * erp erp-pointer to the already defined error |
2419 | * recovery procedure OR | 2419 | * recovery procedure OR |
2420 | * NULL if a 'new' error occurred. | 2420 | * NULL if a 'new' error occurred. |
2421 | */ | 2421 | */ |
@@ -2451,10 +2451,10 @@ dasd_3990_erp_in_erp(struct dasd_ccw_req *cqr) | |||
2451 | * DASD_3990_ERP_FURTHER_ERP (24 & 32 byte sense) | 2451 | * DASD_3990_ERP_FURTHER_ERP (24 & 32 byte sense) |
2452 | * | 2452 | * |
2453 | * DESCRIPTION | 2453 | * DESCRIPTION |
2454 | * No retry is left for the current ERP. Check what has to be done | 2454 | * No retry is left for the current ERP. Check what has to be done |
2455 | * with the ERP. | 2455 | * with the ERP. |
2456 | * - do further defined ERP action or | 2456 | * - do further defined ERP action or |
2457 | * - wait for interrupt or | 2457 | * - wait for interrupt or |
2458 | * - exit with permanent error | 2458 | * - exit with permanent error |
2459 | * | 2459 | * |
2460 | * PARAMETER | 2460 | * PARAMETER |
@@ -2485,7 +2485,7 @@ dasd_3990_erp_further_erp(struct dasd_ccw_req *erp) | |||
2485 | 2485 | ||
2486 | if (!(sense[2] & DASD_SENSE_BIT_0)) { | 2486 | if (!(sense[2] & DASD_SENSE_BIT_0)) { |
2487 | 2487 | ||
2488 | /* issue a Diagnostic Control command with an | 2488 | /* issue a Diagnostic Control command with an |
2489 | * Inhibit Write subcommand */ | 2489 | * Inhibit Write subcommand */ |
2490 | 2490 | ||
2491 | switch (sense[25]) { | 2491 | switch (sense[25]) { |
@@ -2535,14 +2535,14 @@ dasd_3990_erp_further_erp(struct dasd_ccw_req *erp) | |||
2535 | } /* end dasd_3990_erp_further_erp */ | 2535 | } /* end dasd_3990_erp_further_erp */ |
2536 | 2536 | ||
2537 | /* | 2537 | /* |
2538 | * DASD_3990_ERP_HANDLE_MATCH_ERP | 2538 | * DASD_3990_ERP_HANDLE_MATCH_ERP |
2539 | * | 2539 | * |
2540 | * DESCRIPTION | 2540 | * DESCRIPTION |
2541 | * An error occurred again and an ERP has been detected which is already | 2541 | * An error occurred again and an ERP has been detected which is already |
2542 | * used to handle this error (e.g. retries). | 2542 | * used to handle this error (e.g. retries). |
2543 | * All prior ERP's are asumed to be successful and therefore removed | 2543 | * All prior ERP's are asumed to be successful and therefore removed |
2544 | * from queue. | 2544 | * from queue. |
2545 | * If retry counter of matching erp is already 0, it is checked if further | 2545 | * If retry counter of matching erp is already 0, it is checked if further |
2546 | * action is needed (besides retry) or if the ERP has failed. | 2546 | * action is needed (besides retry) or if the ERP has failed. |
2547 | * | 2547 | * |
2548 | * PARAMETER | 2548 | * PARAMETER |
@@ -2631,7 +2631,7 @@ dasd_3990_erp_handle_match_erp(struct dasd_ccw_req *erp_head, | |||
2631 | * erp erp-pointer to the head of the ERP action chain. | 2631 | * erp erp-pointer to the head of the ERP action chain. |
2632 | * This means: | 2632 | * This means: |
2633 | * - either a ptr to an additional ERP cqr or | 2633 | * - either a ptr to an additional ERP cqr or |
2634 | * - the original given cqr (which's status might | 2634 | * - the original given cqr (which's status might |
2635 | * be modified) | 2635 | * be modified) |
2636 | */ | 2636 | */ |
2637 | struct dasd_ccw_req * | 2637 | struct dasd_ccw_req * |
@@ -2723,22 +2723,3 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr) | |||
2723 | return erp; | 2723 | return erp; |
2724 | 2724 | ||
2725 | } /* end dasd_3990_erp_action */ | 2725 | } /* end dasd_3990_erp_action */ |
2726 | |||
2727 | /* | ||
2728 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
2729 | * Emacs will notice this stuff at the end of the file and automatically | ||
2730 | * adjust the settings for this buffer only. This must remain at the end | ||
2731 | * of the file. | ||
2732 | * --------------------------------------------------------------------------- | ||
2733 | * Local variables: | ||
2734 | * c-indent-level: 4 | ||
2735 | * c-brace-imaginary-offset: 0 | ||
2736 | * c-brace-offset: -4 | ||
2737 | * c-argdecl-indent: 4 | ||
2738 | * c-label-offset: -4 | ||
2739 | * c-continued-statement-offset: 4 | ||
2740 | * c-continued-brace-offset: 0 | ||
2741 | * indent-tabs-mode: 1 | ||
2742 | * tab-width: 8 | ||
2743 | * End: | ||
2744 | */ | ||
diff --git a/drivers/s390/block/dasd_9336_erp.c b/drivers/s390/block/dasd_9336_erp.c index dc861446d056..6e082688475a 100644 --- a/drivers/s390/block/dasd_9336_erp.c +++ b/drivers/s390/block/dasd_9336_erp.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * File...........: linux/drivers/s390/block/dasd_9336_erp.c | 2 | * File...........: linux/drivers/s390/block/dasd_9336_erp.c |
3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> | 3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> |
4 | * Bugreports.to..: <Linux390@de.ibm.com> | 4 | * Bugreports.to..: <Linux390@de.ibm.com> |
@@ -12,10 +12,10 @@ | |||
12 | 12 | ||
13 | 13 | ||
14 | /* | 14 | /* |
15 | * DASD_9336_ERP_EXAMINE | 15 | * DASD_9336_ERP_EXAMINE |
16 | * | 16 | * |
17 | * DESCRIPTION | 17 | * DESCRIPTION |
18 | * Checks only for fatal/no/recover error. | 18 | * Checks only for fatal/no/recover error. |
19 | * A detailed examination of the sense data is done later outside | 19 | * A detailed examination of the sense data is done later outside |
20 | * the interrupt handler. | 20 | * the interrupt handler. |
21 | * | 21 | * |
@@ -23,7 +23,7 @@ | |||
23 | * 'Chapter 7. 9336 Sense Data'. | 23 | * 'Chapter 7. 9336 Sense Data'. |
24 | * | 24 | * |
25 | * RETURN VALUES | 25 | * RETURN VALUES |
26 | * dasd_era_none no error | 26 | * dasd_era_none no error |
27 | * dasd_era_fatal for all fatal (unrecoverable errors) | 27 | * dasd_era_fatal for all fatal (unrecoverable errors) |
28 | * dasd_era_recover for all others. | 28 | * dasd_era_recover for all others. |
29 | */ | 29 | */ |
@@ -39,22 +39,3 @@ dasd_9336_erp_examine(struct dasd_ccw_req * cqr, struct irb * irb) | |||
39 | return dasd_era_recover; | 39 | return dasd_era_recover; |
40 | 40 | ||
41 | } /* END dasd_9336_erp_examine */ | 41 | } /* END dasd_9336_erp_examine */ |
42 | |||
43 | /* | ||
44 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
45 | * Emacs will notice this stuff at the end of the file and automatically | ||
46 | * adjust the settings for this buffer only. This must remain at the end | ||
47 | * of the file. | ||
48 | * --------------------------------------------------------------------------- | ||
49 | * Local variables: | ||
50 | * c-indent-level: 4 | ||
51 | * c-brace-imaginary-offset: 0 | ||
52 | * c-brace-offset: -4 | ||
53 | * c-argdecl-indent: 4 | ||
54 | * c-label-offset: -4 | ||
55 | * c-continued-statement-offset: 4 | ||
56 | * c-continued-brace-offset: 0 | ||
57 | * indent-tabs-mode: 1 | ||
58 | * tab-width: 8 | ||
59 | * End: | ||
60 | */ | ||
diff --git a/drivers/s390/block/dasd_9343_erp.c b/drivers/s390/block/dasd_9343_erp.c index 4a5b79569aaa..ddecb9808ed4 100644 --- a/drivers/s390/block/dasd_9343_erp.c +++ b/drivers/s390/block/dasd_9343_erp.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * File...........: linux/drivers/s390/block/dasd_9345_erp.c | 2 | * File...........: linux/drivers/s390/block/dasd_9345_erp.c |
3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> | 3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> |
4 | * Bugreports.to..: <Linux390@de.ibm.com> | 4 | * Bugreports.to..: <Linux390@de.ibm.com> |
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index 216bc4fba199..9e9ae7179602 100644 --- a/drivers/s390/block/dasd_devmap.c +++ b/drivers/s390/block/dasd_devmap.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include "dasd_int.h" | 27 | #include "dasd_int.h" |
28 | 28 | ||
29 | kmem_cache_t *dasd_page_cache; | 29 | kmem_cache_t *dasd_page_cache; |
30 | EXPORT_SYMBOL(dasd_page_cache); | 30 | EXPORT_SYMBOL_GPL(dasd_page_cache); |
31 | 31 | ||
32 | /* | 32 | /* |
33 | * dasd_devmap_t is used to store the features and the relation | 33 | * dasd_devmap_t is used to store the features and the relation |
@@ -49,6 +49,20 @@ struct dasd_devmap { | |||
49 | }; | 49 | }; |
50 | 50 | ||
51 | /* | 51 | /* |
52 | * dasd_servermap is used to store the server_id of all storage servers | ||
53 | * accessed by DASD device driver. | ||
54 | */ | ||
55 | struct dasd_servermap { | ||
56 | struct list_head list; | ||
57 | struct server_id { | ||
58 | char vendor[4]; | ||
59 | char serial[15]; | ||
60 | } sid; | ||
61 | }; | ||
62 | |||
63 | static struct list_head dasd_serverlist; | ||
64 | |||
65 | /* | ||
52 | * Parameter parsing functions for dasd= parameter. The syntax is: | 66 | * Parameter parsing functions for dasd= parameter. The syntax is: |
53 | * <devno> : (0x)?[0-9a-fA-F]+ | 67 | * <devno> : (0x)?[0-9a-fA-F]+ |
54 | * <busid> : [0-0a-f]\.[0-9a-f]\.(0x)?[0-9a-fA-F]+ | 68 | * <busid> : [0-0a-f]\.[0-9a-f]\.(0x)?[0-9a-fA-F]+ |
@@ -64,6 +78,8 @@ struct dasd_devmap { | |||
64 | 78 | ||
65 | int dasd_probeonly = 0; /* is true, when probeonly mode is active */ | 79 | int dasd_probeonly = 0; /* is true, when probeonly mode is active */ |
66 | int dasd_autodetect = 0; /* is true, when autodetection is active */ | 80 | int dasd_autodetect = 0; /* is true, when autodetection is active */ |
81 | int dasd_nopav = 0; /* is true, when PAV is disabled */ | ||
82 | EXPORT_SYMBOL_GPL(dasd_nopav); | ||
67 | 83 | ||
68 | /* | 84 | /* |
69 | * char *dasd[] is intended to hold the ranges supplied by the dasd= statement | 85 | * char *dasd[] is intended to hold the ranges supplied by the dasd= statement |
@@ -123,7 +139,7 @@ static inline int | |||
123 | dasd_busid(char **str, int *id0, int *id1, int *devno) | 139 | dasd_busid(char **str, int *id0, int *id1, int *devno) |
124 | { | 140 | { |
125 | int val, old_style; | 141 | int val, old_style; |
126 | 142 | ||
127 | /* check for leading '0x' */ | 143 | /* check for leading '0x' */ |
128 | old_style = 0; | 144 | old_style = 0; |
129 | if ((*str)[0] == '0' && (*str)[1] == 'x') { | 145 | if ((*str)[0] == '0' && (*str)[1] == 'x') { |
@@ -179,7 +195,7 @@ dasd_feature_list(char *str, char **endp) | |||
179 | features = 0; | 195 | features = 0; |
180 | 196 | ||
181 | while (1) { | 197 | while (1) { |
182 | for (len = 0; | 198 | for (len = 0; |
183 | str[len] && str[len] != ':' && str[len] != ')'; len++); | 199 | str[len] && str[len] != ':' && str[len] != ')'; len++); |
184 | if (len == 2 && !strncmp(str, "ro", 2)) | 200 | if (len == 2 && !strncmp(str, "ro", 2)) |
185 | features |= DASD_FEATURE_READONLY; | 201 | features |= DASD_FEATURE_READONLY; |
@@ -228,19 +244,24 @@ dasd_parse_keyword( char *parsestring ) { | |||
228 | length = strlen(parsestring); | 244 | length = strlen(parsestring); |
229 | residual_str = parsestring + length; | 245 | residual_str = parsestring + length; |
230 | } | 246 | } |
231 | if (strncmp ("autodetect", parsestring, length) == 0) { | 247 | if (strncmp("autodetect", parsestring, length) == 0) { |
232 | dasd_autodetect = 1; | 248 | dasd_autodetect = 1; |
233 | MESSAGE (KERN_INFO, "%s", | 249 | MESSAGE (KERN_INFO, "%s", |
234 | "turning to autodetection mode"); | 250 | "turning to autodetection mode"); |
235 | return residual_str; | 251 | return residual_str; |
236 | } | 252 | } |
237 | if (strncmp ("probeonly", parsestring, length) == 0) { | 253 | if (strncmp("probeonly", parsestring, length) == 0) { |
238 | dasd_probeonly = 1; | 254 | dasd_probeonly = 1; |
239 | MESSAGE(KERN_INFO, "%s", | 255 | MESSAGE(KERN_INFO, "%s", |
240 | "turning to probeonly mode"); | 256 | "turning to probeonly mode"); |
241 | return residual_str; | 257 | return residual_str; |
242 | } | 258 | } |
243 | if (strncmp ("fixedbuffers", parsestring, length) == 0) { | 259 | if (strncmp("nopav", parsestring, length) == 0) { |
260 | dasd_nopav = 1; | ||
261 | MESSAGE(KERN_INFO, "%s", "disable PAV mode"); | ||
262 | return residual_str; | ||
263 | } | ||
264 | if (strncmp("fixedbuffers", parsestring, length) == 0) { | ||
244 | if (dasd_page_cache) | 265 | if (dasd_page_cache) |
245 | return residual_str; | 266 | return residual_str; |
246 | dasd_page_cache = | 267 | dasd_page_cache = |
@@ -294,6 +315,8 @@ dasd_parse_range( char *parsestring ) { | |||
294 | features = dasd_feature_list(str, &str); | 315 | features = dasd_feature_list(str, &str); |
295 | if (features < 0) | 316 | if (features < 0) |
296 | return ERR_PTR(-EINVAL); | 317 | return ERR_PTR(-EINVAL); |
318 | /* each device in dasd= parameter should be set initially online */ | ||
319 | features |= DASD_FEATURE_INITIAL_ONLINE; | ||
297 | while (from <= to) { | 320 | while (from <= to) { |
298 | sprintf(bus_id, "%01x.%01x.%04x", | 321 | sprintf(bus_id, "%01x.%01x.%04x", |
299 | from_id0, from_id1, from++); | 322 | from_id0, from_id1, from++); |
@@ -359,7 +382,7 @@ dasd_parse(void) | |||
359 | * Add a devmap for the device specified by busid. It is possible that | 382 | * Add a devmap for the device specified by busid. It is possible that |
360 | * the devmap already exists (dasd= parameter). The order of the devices | 383 | * the devmap already exists (dasd= parameter). The order of the devices |
361 | * added through this function will define the kdevs for the individual | 384 | * added through this function will define the kdevs for the individual |
362 | * devices. | 385 | * devices. |
363 | */ | 386 | */ |
364 | static struct dasd_devmap * | 387 | static struct dasd_devmap * |
365 | dasd_add_busid(char *bus_id, int features) | 388 | dasd_add_busid(char *bus_id, int features) |
@@ -368,7 +391,7 @@ dasd_add_busid(char *bus_id, int features) | |||
368 | int hash; | 391 | int hash; |
369 | 392 | ||
370 | new = (struct dasd_devmap *) | 393 | new = (struct dasd_devmap *) |
371 | kmalloc(sizeof(struct dasd_devmap), GFP_KERNEL); | 394 | kzalloc(sizeof(struct dasd_devmap), GFP_KERNEL); |
372 | if (!new) | 395 | if (!new) |
373 | return ERR_PTR(-ENOMEM); | 396 | return ERR_PTR(-ENOMEM); |
374 | spin_lock(&dasd_devmap_lock); | 397 | spin_lock(&dasd_devmap_lock); |
@@ -630,7 +653,8 @@ dasd_ro_show(struct device *dev, struct device_attribute *attr, char *buf) | |||
630 | } | 653 | } |
631 | 654 | ||
632 | static ssize_t | 655 | static ssize_t |
633 | dasd_ro_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 656 | dasd_ro_store(struct device *dev, struct device_attribute *attr, |
657 | const char *buf, size_t count) | ||
634 | { | 658 | { |
635 | struct dasd_devmap *devmap; | 659 | struct dasd_devmap *devmap; |
636 | int ro_flag; | 660 | int ro_flag; |
@@ -658,7 +682,7 @@ static DEVICE_ATTR(readonly, 0644, dasd_ro_show, dasd_ro_store); | |||
658 | * use_diag controls whether the driver should use diag rather than ssch | 682 | * use_diag controls whether the driver should use diag rather than ssch |
659 | * to talk to the device | 683 | * to talk to the device |
660 | */ | 684 | */ |
661 | static ssize_t | 685 | static ssize_t |
662 | dasd_use_diag_show(struct device *dev, struct device_attribute *attr, char *buf) | 686 | dasd_use_diag_show(struct device *dev, struct device_attribute *attr, char *buf) |
663 | { | 687 | { |
664 | struct dasd_devmap *devmap; | 688 | struct dasd_devmap *devmap; |
@@ -673,7 +697,8 @@ dasd_use_diag_show(struct device *dev, struct device_attribute *attr, char *buf) | |||
673 | } | 697 | } |
674 | 698 | ||
675 | static ssize_t | 699 | static ssize_t |
676 | dasd_use_diag_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 700 | dasd_use_diag_store(struct device *dev, struct device_attribute *attr, |
701 | const char *buf, size_t count) | ||
677 | { | 702 | { |
678 | struct dasd_devmap *devmap; | 703 | struct dasd_devmap *devmap; |
679 | ssize_t rc; | 704 | ssize_t rc; |
@@ -697,11 +722,11 @@ dasd_use_diag_store(struct device *dev, struct device_attribute *attr, const cha | |||
697 | return rc; | 722 | return rc; |
698 | } | 723 | } |
699 | 724 | ||
700 | static | 725 | static DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store); |
701 | DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store); | ||
702 | 726 | ||
703 | static ssize_t | 727 | static ssize_t |
704 | dasd_discipline_show(struct device *dev, struct device_attribute *attr, char *buf) | 728 | dasd_discipline_show(struct device *dev, struct device_attribute *attr, |
729 | char *buf) | ||
705 | { | 730 | { |
706 | struct dasd_devmap *devmap; | 731 | struct dasd_devmap *devmap; |
707 | char *dname; | 732 | char *dname; |
@@ -834,6 +859,38 @@ static struct attribute_group dasd_attr_group = { | |||
834 | .attrs = dasd_attrs, | 859 | .attrs = dasd_attrs, |
835 | }; | 860 | }; |
836 | 861 | ||
862 | /* | ||
863 | * Check if the related storage server is already contained in the | ||
864 | * dasd_serverlist. If server is not contained, create new entry. | ||
865 | * Return 0 if server was already in serverlist, | ||
866 | * 1 if the server was added successfully | ||
867 | * <0 in case of error. | ||
868 | */ | ||
869 | static int | ||
870 | dasd_add_server(struct dasd_uid *uid) | ||
871 | { | ||
872 | struct dasd_servermap *new, *tmp; | ||
873 | |||
874 | /* check if server is already contained */ | ||
875 | list_for_each_entry(tmp, &dasd_serverlist, list) | ||
876 | // normale cmp? | ||
877 | if (strncmp(tmp->sid.vendor, uid->vendor, | ||
878 | sizeof(tmp->sid.vendor)) == 0 | ||
879 | && strncmp(tmp->sid.serial, uid->serial, | ||
880 | sizeof(tmp->sid.serial)) == 0) | ||
881 | return 0; | ||
882 | |||
883 | new = (struct dasd_servermap *) | ||
884 | kzalloc(sizeof(struct dasd_servermap), GFP_KERNEL); | ||
885 | if (!new) | ||
886 | return -ENOMEM; | ||
887 | |||
888 | strncpy(new->sid.vendor, uid->vendor, sizeof(new->sid.vendor)); | ||
889 | strncpy(new->sid.serial, uid->serial, sizeof(new->sid.serial)); | ||
890 | list_add(&new->list, &dasd_serverlist); | ||
891 | return 1; | ||
892 | } | ||
893 | |||
837 | 894 | ||
838 | /* | 895 | /* |
839 | * Return copy of the device unique identifier. | 896 | * Return copy of the device unique identifier. |
@@ -854,21 +911,26 @@ dasd_get_uid(struct ccw_device *cdev, struct dasd_uid *uid) | |||
854 | 911 | ||
855 | /* | 912 | /* |
856 | * Register the given device unique identifier into devmap struct. | 913 | * Register the given device unique identifier into devmap struct. |
914 | * Return 0 if server was already in serverlist, | ||
915 | * 1 if the server was added successful | ||
916 | * <0 in case of error. | ||
857 | */ | 917 | */ |
858 | int | 918 | int |
859 | dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid) | 919 | dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid) |
860 | { | 920 | { |
861 | struct dasd_devmap *devmap; | 921 | struct dasd_devmap *devmap; |
922 | int rc; | ||
862 | 923 | ||
863 | devmap = dasd_find_busid(cdev->dev.bus_id); | 924 | devmap = dasd_find_busid(cdev->dev.bus_id); |
864 | if (IS_ERR(devmap)) | 925 | if (IS_ERR(devmap)) |
865 | return PTR_ERR(devmap); | 926 | return PTR_ERR(devmap); |
866 | spin_lock(&dasd_devmap_lock); | 927 | spin_lock(&dasd_devmap_lock); |
867 | devmap->uid = *uid; | 928 | devmap->uid = *uid; |
929 | rc = dasd_add_server(uid); | ||
868 | spin_unlock(&dasd_devmap_lock); | 930 | spin_unlock(&dasd_devmap_lock); |
869 | return 0; | 931 | return rc; |
870 | } | 932 | } |
871 | EXPORT_SYMBOL(dasd_set_uid); | 933 | EXPORT_SYMBOL_GPL(dasd_set_uid); |
872 | 934 | ||
873 | /* | 935 | /* |
874 | * Return value of the specified feature. | 936 | * Return value of the specified feature. |
@@ -880,7 +942,7 @@ dasd_get_feature(struct ccw_device *cdev, int feature) | |||
880 | 942 | ||
881 | devmap = dasd_find_busid(cdev->dev.bus_id); | 943 | devmap = dasd_find_busid(cdev->dev.bus_id); |
882 | if (IS_ERR(devmap)) | 944 | if (IS_ERR(devmap)) |
883 | return (int) PTR_ERR(devmap); | 945 | return PTR_ERR(devmap); |
884 | 946 | ||
885 | return ((devmap->features & feature) != 0); | 947 | return ((devmap->features & feature) != 0); |
886 | } | 948 | } |
@@ -896,7 +958,7 @@ dasd_set_feature(struct ccw_device *cdev, int feature, int flag) | |||
896 | 958 | ||
897 | devmap = dasd_find_busid(cdev->dev.bus_id); | 959 | devmap = dasd_find_busid(cdev->dev.bus_id); |
898 | if (IS_ERR(devmap)) | 960 | if (IS_ERR(devmap)) |
899 | return (int) PTR_ERR(devmap); | 961 | return PTR_ERR(devmap); |
900 | 962 | ||
901 | spin_lock(&dasd_devmap_lock); | 963 | spin_lock(&dasd_devmap_lock); |
902 | if (flag) | 964 | if (flag) |
@@ -932,8 +994,10 @@ dasd_devmap_init(void) | |||
932 | dasd_max_devindex = 0; | 994 | dasd_max_devindex = 0; |
933 | for (i = 0; i < 256; i++) | 995 | for (i = 0; i < 256; i++) |
934 | INIT_LIST_HEAD(&dasd_hashlists[i]); | 996 | INIT_LIST_HEAD(&dasd_hashlists[i]); |
935 | return 0; | ||
936 | 997 | ||
998 | /* Initialize servermap structure. */ | ||
999 | INIT_LIST_HEAD(&dasd_serverlist); | ||
1000 | return 0; | ||
937 | } | 1001 | } |
938 | 1002 | ||
939 | void | 1003 | void |
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c index 3f9d704d2657..4002f6c1c1b3 100644 --- a/drivers/s390/block/dasd_diag.c +++ b/drivers/s390/block/dasd_diag.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * File...........: linux/drivers/s390/block/dasd_diag.c | 2 | * File...........: linux/drivers/s390/block/dasd_diag.c |
3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> | 3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> |
4 | * Based on.......: linux/drivers/s390/block/mdisk.c | 4 | * Based on.......: linux/drivers/s390/block/mdisk.c |
@@ -336,7 +336,7 @@ dasd_diag_check_device(struct dasd_device *device) | |||
336 | 336 | ||
337 | private = (struct dasd_diag_private *) device->private; | 337 | private = (struct dasd_diag_private *) device->private; |
338 | if (private == NULL) { | 338 | if (private == NULL) { |
339 | private = kmalloc(sizeof(struct dasd_diag_private),GFP_KERNEL); | 339 | private = kzalloc(sizeof(struct dasd_diag_private),GFP_KERNEL); |
340 | if (private == NULL) { | 340 | if (private == NULL) { |
341 | DEV_MESSAGE(KERN_WARNING, device, "%s", | 341 | DEV_MESSAGE(KERN_WARNING, device, "%s", |
342 | "memory allocation failed for private data"); | 342 | "memory allocation failed for private data"); |
@@ -527,7 +527,7 @@ dasd_diag_build_cp(struct dasd_device * device, struct request *req) | |||
527 | datasize, device); | 527 | datasize, device); |
528 | if (IS_ERR(cqr)) | 528 | if (IS_ERR(cqr)) |
529 | return cqr; | 529 | return cqr; |
530 | 530 | ||
531 | dreq = (struct dasd_diag_req *) cqr->data; | 531 | dreq = (struct dasd_diag_req *) cqr->data; |
532 | dreq->block_count = count; | 532 | dreq->block_count = count; |
533 | dbio = dreq->bio; | 533 | dbio = dreq->bio; |
diff --git a/drivers/s390/block/dasd_diag.h b/drivers/s390/block/dasd_diag.h index 38a4e55f8953..b8c78267ff3e 100644 --- a/drivers/s390/block/dasd_diag.h +++ b/drivers/s390/block/dasd_diag.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * File...........: linux/drivers/s390/block/dasd_diag.h | 2 | * File...........: linux/drivers/s390/block/dasd_diag.h |
3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> | 3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> |
4 | * Based on.......: linux/drivers/s390/block/mdisk.h | 4 | * Based on.......: linux/drivers/s390/block/mdisk.h |
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 7d5a6cee4bd8..0dfab30e8089 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * File...........: linux/drivers/s390/block/dasd_eckd.c | 2 | * File...........: linux/drivers/s390/block/dasd_eckd.c |
3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> | 3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> |
4 | * Horst Hummel <Horst.Hummel@de.ibm.com> | 4 | * Horst Hummel <Horst.Hummel@de.ibm.com> |
5 | * Carsten Otte <Cotte@de.ibm.com> | 5 | * Carsten Otte <Cotte@de.ibm.com> |
6 | * Martin Schwidefsky <schwidefsky@de.ibm.com> | 6 | * Martin Schwidefsky <schwidefsky@de.ibm.com> |
7 | * Bugreports.to..: <Linux390@de.ibm.com> | 7 | * Bugreports.to..: <Linux390@de.ibm.com> |
@@ -24,6 +24,7 @@ | |||
24 | #include <asm/io.h> | 24 | #include <asm/io.h> |
25 | #include <asm/todclk.h> | 25 | #include <asm/todclk.h> |
26 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
27 | #include <asm/cio.h> | ||
27 | #include <asm/ccwdev.h> | 28 | #include <asm/ccwdev.h> |
28 | 29 | ||
29 | #include "dasd_int.h" | 30 | #include "dasd_int.h" |
@@ -89,17 +90,22 @@ dasd_eckd_probe (struct ccw_device *cdev) | |||
89 | { | 90 | { |
90 | int ret; | 91 | int ret; |
91 | 92 | ||
92 | ret = dasd_generic_probe (cdev, &dasd_eckd_discipline); | 93 | /* set ECKD specific ccw-device options */ |
93 | if (ret) | 94 | ret = ccw_device_set_options(cdev, CCWDEV_ALLOW_FORCE); |
95 | if (ret) { | ||
96 | printk(KERN_WARNING | ||
97 | "dasd_eckd_probe: could not set ccw-device options " | ||
98 | "for %s\n", cdev->dev.bus_id); | ||
94 | return ret; | 99 | return ret; |
95 | ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP | CCWDEV_ALLOW_FORCE); | 100 | } |
96 | return 0; | 101 | ret = dasd_generic_probe(cdev, &dasd_eckd_discipline); |
102 | return ret; | ||
97 | } | 103 | } |
98 | 104 | ||
99 | static int | 105 | static int |
100 | dasd_eckd_set_online(struct ccw_device *cdev) | 106 | dasd_eckd_set_online(struct ccw_device *cdev) |
101 | { | 107 | { |
102 | return dasd_generic_set_online (cdev, &dasd_eckd_discipline); | 108 | return dasd_generic_set_online(cdev, &dasd_eckd_discipline); |
103 | } | 109 | } |
104 | 110 | ||
105 | static struct ccw_driver dasd_eckd_driver = { | 111 | static struct ccw_driver dasd_eckd_driver = { |
@@ -210,14 +216,14 @@ check_XRC (struct ccw1 *de_ccw, | |||
210 | 216 | ||
211 | /* switch on System Time Stamp - needed for XRC Support */ | 217 | /* switch on System Time Stamp - needed for XRC Support */ |
212 | if (private->rdc_data.facilities.XRC_supported) { | 218 | if (private->rdc_data.facilities.XRC_supported) { |
213 | 219 | ||
214 | data->ga_extended |= 0x08; /* switch on 'Time Stamp Valid' */ | 220 | data->ga_extended |= 0x08; /* switch on 'Time Stamp Valid' */ |
215 | data->ga_extended |= 0x02; /* switch on 'Extended Parameter' */ | 221 | data->ga_extended |= 0x02; /* switch on 'Extended Parameter' */ |
216 | 222 | ||
217 | data->ep_sys_time = get_clock (); | 223 | data->ep_sys_time = get_clock (); |
218 | 224 | ||
219 | de_ccw->count = sizeof (struct DE_eckd_data); | 225 | de_ccw->count = sizeof (struct DE_eckd_data); |
220 | de_ccw->flags |= CCW_FLAG_SLI; | 226 | de_ccw->flags |= CCW_FLAG_SLI; |
221 | } | 227 | } |
222 | 228 | ||
223 | return; | 229 | return; |
@@ -296,8 +302,8 @@ define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk, | |||
296 | /* check for sequential prestage - enhance cylinder range */ | 302 | /* check for sequential prestage - enhance cylinder range */ |
297 | if (data->attributes.operation == DASD_SEQ_PRESTAGE || | 303 | if (data->attributes.operation == DASD_SEQ_PRESTAGE || |
298 | data->attributes.operation == DASD_SEQ_ACCESS) { | 304 | data->attributes.operation == DASD_SEQ_ACCESS) { |
299 | 305 | ||
300 | if (end.cyl + private->attrib.nr_cyl < geo.cyl) | 306 | if (end.cyl + private->attrib.nr_cyl < geo.cyl) |
301 | end.cyl += private->attrib.nr_cyl; | 307 | end.cyl += private->attrib.nr_cyl; |
302 | else | 308 | else |
303 | end.cyl = (geo.cyl - 1); | 309 | end.cyl = (geo.cyl - 1); |
@@ -317,7 +323,7 @@ locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, int trk, | |||
317 | struct dasd_eckd_private *private; | 323 | struct dasd_eckd_private *private; |
318 | int sector; | 324 | int sector; |
319 | int dn, d; | 325 | int dn, d; |
320 | 326 | ||
321 | private = (struct dasd_eckd_private *) device->private; | 327 | private = (struct dasd_eckd_private *) device->private; |
322 | 328 | ||
323 | DBF_DEV_EVENT(DBF_INFO, device, | 329 | DBF_DEV_EVENT(DBF_INFO, device, |
@@ -541,6 +547,86 @@ dasd_eckd_read_conf(struct dasd_device *device) | |||
541 | } | 547 | } |
542 | 548 | ||
543 | /* | 549 | /* |
550 | * Build CP for Perform Subsystem Function - SSC. | ||
551 | */ | ||
552 | struct dasd_ccw_req * | ||
553 | dasd_eckd_build_psf_ssc(struct dasd_device *device) | ||
554 | { | ||
555 | struct dasd_ccw_req *cqr; | ||
556 | struct dasd_psf_ssc_data *psf_ssc_data; | ||
557 | struct ccw1 *ccw; | ||
558 | |||
559 | cqr = dasd_smalloc_request("ECKD", 1 /* PSF */ , | ||
560 | sizeof(struct dasd_psf_ssc_data), | ||
561 | device); | ||
562 | |||
563 | if (IS_ERR(cqr)) { | ||
564 | DEV_MESSAGE(KERN_WARNING, device, "%s", | ||
565 | "Could not allocate PSF-SSC request"); | ||
566 | return cqr; | ||
567 | } | ||
568 | psf_ssc_data = (struct dasd_psf_ssc_data *)cqr->data; | ||
569 | psf_ssc_data->order = PSF_ORDER_SSC; | ||
570 | psf_ssc_data->suborder = 0x08; | ||
571 | |||
572 | ccw = cqr->cpaddr; | ||
573 | ccw->cmd_code = DASD_ECKD_CCW_PSF; | ||
574 | ccw->cda = (__u32)(addr_t)psf_ssc_data; | ||
575 | ccw->count = 66; | ||
576 | |||
577 | cqr->device = device; | ||
578 | cqr->expires = 10*HZ; | ||
579 | cqr->buildclk = get_clock(); | ||
580 | cqr->status = DASD_CQR_FILLED; | ||
581 | return cqr; | ||
582 | } | ||
583 | |||
584 | /* | ||
585 | * Perform Subsystem Function. | ||
586 | * It is necessary to trigger CIO for channel revalidation since this | ||
587 | * call might change behaviour of DASD devices. | ||
588 | */ | ||
589 | static int | ||
590 | dasd_eckd_psf_ssc(struct dasd_device *device) | ||
591 | { | ||
592 | struct dasd_ccw_req *cqr; | ||
593 | int rc; | ||
594 | |||
595 | cqr = dasd_eckd_build_psf_ssc(device); | ||
596 | if (IS_ERR(cqr)) | ||
597 | return PTR_ERR(cqr); | ||
598 | |||
599 | rc = dasd_sleep_on(cqr); | ||
600 | if (!rc) | ||
601 | /* trigger CIO to reprobe devices */ | ||
602 | css_schedule_reprobe(); | ||
603 | dasd_sfree_request(cqr, cqr->device); | ||
604 | return rc; | ||
605 | } | ||
606 | |||
607 | /* | ||
608 | * Valide storage server of current device. | ||
609 | */ | ||
610 | static int | ||
611 | dasd_eckd_validate_server(struct dasd_device *device) | ||
612 | { | ||
613 | int rc; | ||
614 | |||
615 | /* Currently PAV is the only reason to 'validate' server on LPAR */ | ||
616 | if (dasd_nopav || MACHINE_IS_VM) | ||
617 | return 0; | ||
618 | |||
619 | rc = dasd_eckd_psf_ssc(device); | ||
620 | if (rc) | ||
621 | /* may be requested feature is not available on server, | ||
622 | * therefore just report error and go ahead */ | ||
623 | DEV_MESSAGE(KERN_INFO, device, | ||
624 | "Perform Subsystem Function returned rc=%d", rc); | ||
625 | /* RE-Read Configuration Data */ | ||
626 | return dasd_eckd_read_conf(device); | ||
627 | } | ||
628 | |||
629 | /* | ||
544 | * Check device characteristics. | 630 | * Check device characteristics. |
545 | * If the device is accessible using ECKD discipline, the device is enabled. | 631 | * If the device is accessible using ECKD discipline, the device is enabled. |
546 | */ | 632 | */ |
@@ -554,7 +640,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device) | |||
554 | 640 | ||
555 | private = (struct dasd_eckd_private *) device->private; | 641 | private = (struct dasd_eckd_private *) device->private; |
556 | if (private == NULL) { | 642 | if (private == NULL) { |
557 | private = kmalloc(sizeof(struct dasd_eckd_private), | 643 | private = kzalloc(sizeof(struct dasd_eckd_private), |
558 | GFP_KERNEL | GFP_DMA); | 644 | GFP_KERNEL | GFP_DMA); |
559 | if (private == NULL) { | 645 | if (private == NULL) { |
560 | DEV_MESSAGE(KERN_WARNING, device, "%s", | 646 | DEV_MESSAGE(KERN_WARNING, device, "%s", |
@@ -562,7 +648,6 @@ dasd_eckd_check_characteristics(struct dasd_device *device) | |||
562 | "data"); | 648 | "data"); |
563 | return -ENOMEM; | 649 | return -ENOMEM; |
564 | } | 650 | } |
565 | memset(private, 0, sizeof(struct dasd_eckd_private)); | ||
566 | device->private = (void *) private; | 651 | device->private = (void *) private; |
567 | } | 652 | } |
568 | /* Invalidate status of initial analysis. */ | 653 | /* Invalidate status of initial analysis. */ |
@@ -571,16 +656,29 @@ dasd_eckd_check_characteristics(struct dasd_device *device) | |||
571 | private->attrib.operation = DASD_NORMAL_CACHE; | 656 | private->attrib.operation = DASD_NORMAL_CACHE; |
572 | private->attrib.nr_cyl = 0; | 657 | private->attrib.nr_cyl = 0; |
573 | 658 | ||
659 | /* Read Configuration Data */ | ||
660 | rc = dasd_eckd_read_conf(device); | ||
661 | if (rc) | ||
662 | return rc; | ||
663 | |||
664 | /* Generate device unique id and register in devmap */ | ||
665 | rc = dasd_eckd_generate_uid(device, &uid); | ||
666 | if (rc) | ||
667 | return rc; | ||
668 | rc = dasd_set_uid(device->cdev, &uid); | ||
669 | if (rc == 1) /* new server found */ | ||
670 | rc = dasd_eckd_validate_server(device); | ||
671 | if (rc) | ||
672 | return rc; | ||
673 | |||
574 | /* Read Device Characteristics */ | 674 | /* Read Device Characteristics */ |
575 | rdc_data = (void *) &(private->rdc_data); | 675 | rdc_data = (void *) &(private->rdc_data); |
576 | memset(rdc_data, 0, sizeof(rdc_data)); | 676 | memset(rdc_data, 0, sizeof(rdc_data)); |
577 | rc = read_dev_chars(device->cdev, &rdc_data, 64); | 677 | rc = read_dev_chars(device->cdev, &rdc_data, 64); |
578 | if (rc) { | 678 | if (rc) |
579 | DEV_MESSAGE(KERN_WARNING, device, | 679 | DEV_MESSAGE(KERN_WARNING, device, |
580 | "Read device characteristics returned error %d", | 680 | "Read device characteristics returned " |
581 | rc); | 681 | "rc=%d", rc); |
582 | return rc; | ||
583 | } | ||
584 | 682 | ||
585 | DEV_MESSAGE(KERN_INFO, device, | 683 | DEV_MESSAGE(KERN_INFO, device, |
586 | "%04X/%02X(CU:%04X/%02X) Cyl:%d Head:%d Sec:%d", | 684 | "%04X/%02X(CU:%04X/%02X) Cyl:%d Head:%d Sec:%d", |
@@ -591,19 +689,6 @@ dasd_eckd_check_characteristics(struct dasd_device *device) | |||
591 | private->rdc_data.no_cyl, | 689 | private->rdc_data.no_cyl, |
592 | private->rdc_data.trk_per_cyl, | 690 | private->rdc_data.trk_per_cyl, |
593 | private->rdc_data.sec_per_trk); | 691 | private->rdc_data.sec_per_trk); |
594 | |||
595 | /* Read Configuration Data */ | ||
596 | rc = dasd_eckd_read_conf (device); | ||
597 | if (rc) | ||
598 | return rc; | ||
599 | |||
600 | /* Generate device unique id and register in devmap */ | ||
601 | rc = dasd_eckd_generate_uid(device, &uid); | ||
602 | if (rc) | ||
603 | return rc; | ||
604 | |||
605 | rc = dasd_set_uid(device->cdev, &uid); | ||
606 | |||
607 | return rc; | 692 | return rc; |
608 | } | 693 | } |
609 | 694 | ||
@@ -773,7 +858,7 @@ dasd_eckd_end_analysis(struct dasd_device *device) | |||
773 | ((private->rdc_data.no_cyl * | 858 | ((private->rdc_data.no_cyl * |
774 | private->rdc_data.trk_per_cyl * | 859 | private->rdc_data.trk_per_cyl * |
775 | blk_per_trk * (device->bp_block >> 9)) >> 1), | 860 | blk_per_trk * (device->bp_block >> 9)) >> 1), |
776 | ((blk_per_trk * device->bp_block) >> 10), | 861 | ((blk_per_trk * device->bp_block) >> 10), |
777 | private->uses_cdl ? | 862 | private->uses_cdl ? |
778 | "compatible disk layout" : "linux disk layout"); | 863 | "compatible disk layout" : "linux disk layout"); |
779 | 864 | ||
@@ -970,7 +1055,7 @@ dasd_eckd_format_device(struct dasd_device * device, | |||
970 | if (i < 3) { | 1055 | if (i < 3) { |
971 | ect->kl = 4; | 1056 | ect->kl = 4; |
972 | ect->dl = sizes_trk0[i] - 4; | 1057 | ect->dl = sizes_trk0[i] - 4; |
973 | } | 1058 | } |
974 | } | 1059 | } |
975 | if ((fdata->intensity & 0x08) && | 1060 | if ((fdata->intensity & 0x08) && |
976 | fdata->start_unit == 1) { | 1061 | fdata->start_unit == 1) { |
@@ -1270,7 +1355,7 @@ dasd_eckd_fill_info(struct dasd_device * device, | |||
1270 | 1355 | ||
1271 | /* | 1356 | /* |
1272 | * Release device ioctl. | 1357 | * Release device ioctl. |
1273 | * Buils a channel programm to releases a prior reserved | 1358 | * Buils a channel programm to releases a prior reserved |
1274 | * (see dasd_eckd_reserve) device. | 1359 | * (see dasd_eckd_reserve) device. |
1275 | */ | 1360 | */ |
1276 | static int | 1361 | static int |
@@ -1310,8 +1395,8 @@ dasd_eckd_release(struct dasd_device *device) | |||
1310 | /* | 1395 | /* |
1311 | * Reserve device ioctl. | 1396 | * Reserve device ioctl. |
1312 | * Options are set to 'synchronous wait for interrupt' and | 1397 | * Options are set to 'synchronous wait for interrupt' and |
1313 | * 'timeout the request'. This leads to a terminate IO if | 1398 | * 'timeout the request'. This leads to a terminate IO if |
1314 | * the interrupt is outstanding for a certain time. | 1399 | * the interrupt is outstanding for a certain time. |
1315 | */ | 1400 | */ |
1316 | static int | 1401 | static int |
1317 | dasd_eckd_reserve(struct dasd_device *device) | 1402 | dasd_eckd_reserve(struct dasd_device *device) |
@@ -1349,7 +1434,7 @@ dasd_eckd_reserve(struct dasd_device *device) | |||
1349 | 1434 | ||
1350 | /* | 1435 | /* |
1351 | * Steal lock ioctl - unconditional reserve device. | 1436 | * Steal lock ioctl - unconditional reserve device. |
1352 | * Buils a channel programm to break a device's reservation. | 1437 | * Buils a channel programm to break a device's reservation. |
1353 | * (unconditional reserve) | 1438 | * (unconditional reserve) |
1354 | */ | 1439 | */ |
1355 | static int | 1440 | static int |
@@ -1522,6 +1607,40 @@ dasd_eckd_ioctl(struct dasd_device *device, unsigned int cmd, void __user *argp) | |||
1522 | } | 1607 | } |
1523 | 1608 | ||
1524 | /* | 1609 | /* |
1610 | * Dump the range of CCWs into 'page' buffer | ||
1611 | * and return number of printed chars. | ||
1612 | */ | ||
1613 | static inline int | ||
1614 | dasd_eckd_dump_ccw_range(struct ccw1 *from, struct ccw1 *to, char *page) | ||
1615 | { | ||
1616 | int len, count; | ||
1617 | char *datap; | ||
1618 | |||
1619 | len = 0; | ||
1620 | while (from <= to) { | ||
1621 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER | ||
1622 | " CCW %p: %08X %08X DAT:", | ||
1623 | from, ((int *) from)[0], ((int *) from)[1]); | ||
1624 | |||
1625 | /* get pointer to data (consider IDALs) */ | ||
1626 | if (from->flags & CCW_FLAG_IDA) | ||
1627 | datap = (char *) *((addr_t *) (addr_t) from->cda); | ||
1628 | else | ||
1629 | datap = (char *) ((addr_t) from->cda); | ||
1630 | |||
1631 | /* dump data (max 32 bytes) */ | ||
1632 | for (count = 0; count < from->count && count < 32; count++) { | ||
1633 | if (count % 8 == 0) len += sprintf(page + len, " "); | ||
1634 | if (count % 4 == 0) len += sprintf(page + len, " "); | ||
1635 | len += sprintf(page + len, "%02x", datap[count]); | ||
1636 | } | ||
1637 | len += sprintf(page + len, "\n"); | ||
1638 | from++; | ||
1639 | } | ||
1640 | return len; | ||
1641 | } | ||
1642 | |||
1643 | /* | ||
1525 | * Print sense data and related channel program. | 1644 | * Print sense data and related channel program. |
1526 | * Parts are printed because printk buffer is only 1024 bytes. | 1645 | * Parts are printed because printk buffer is only 1024 bytes. |
1527 | */ | 1646 | */ |
@@ -1530,8 +1649,8 @@ dasd_eckd_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req, | |||
1530 | struct irb *irb) | 1649 | struct irb *irb) |
1531 | { | 1650 | { |
1532 | char *page; | 1651 | char *page; |
1533 | struct ccw1 *act, *end, *last; | 1652 | struct ccw1 *first, *last, *fail, *from, *to; |
1534 | int len, sl, sct, count; | 1653 | int len, sl, sct; |
1535 | 1654 | ||
1536 | page = (char *) get_zeroed_page(GFP_ATOMIC); | 1655 | page = (char *) get_zeroed_page(GFP_ATOMIC); |
1537 | if (page == NULL) { | 1656 | if (page == NULL) { |
@@ -1539,7 +1658,8 @@ dasd_eckd_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req, | |||
1539 | "No memory to dump sense data"); | 1658 | "No memory to dump sense data"); |
1540 | return; | 1659 | return; |
1541 | } | 1660 | } |
1542 | len = sprintf(page, KERN_ERR PRINTK_HEADER | 1661 | /* dump the sense data */ |
1662 | len = sprintf(page, KERN_ERR PRINTK_HEADER | ||
1543 | " I/O status report for device %s:\n", | 1663 | " I/O status report for device %s:\n", |
1544 | device->cdev->dev.bus_id); | 1664 | device->cdev->dev.bus_id); |
1545 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER | 1665 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER |
@@ -1564,87 +1684,55 @@ dasd_eckd_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req, | |||
1564 | 1684 | ||
1565 | if (irb->ecw[27] & DASD_SENSE_BIT_0) { | 1685 | if (irb->ecw[27] & DASD_SENSE_BIT_0) { |
1566 | /* 24 Byte Sense Data */ | 1686 | /* 24 Byte Sense Data */ |
1567 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER | 1687 | sprintf(page + len, KERN_ERR PRINTK_HEADER |
1568 | " 24 Byte: %x MSG %x, " | 1688 | " 24 Byte: %x MSG %x, " |
1569 | "%s MSGb to SYSOP\n", | 1689 | "%s MSGb to SYSOP\n", |
1570 | irb->ecw[7] >> 4, irb->ecw[7] & 0x0f, | 1690 | irb->ecw[7] >> 4, irb->ecw[7] & 0x0f, |
1571 | irb->ecw[1] & 0x10 ? "" : "no"); | 1691 | irb->ecw[1] & 0x10 ? "" : "no"); |
1572 | } else { | 1692 | } else { |
1573 | /* 32 Byte Sense Data */ | 1693 | /* 32 Byte Sense Data */ |
1574 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER | 1694 | sprintf(page + len, KERN_ERR PRINTK_HEADER |
1575 | " 32 Byte: Format: %x " | 1695 | " 32 Byte: Format: %x " |
1576 | "Exception class %x\n", | 1696 | "Exception class %x\n", |
1577 | irb->ecw[6] & 0x0f, irb->ecw[22] >> 4); | 1697 | irb->ecw[6] & 0x0f, irb->ecw[22] >> 4); |
1578 | } | 1698 | } |
1579 | } else { | 1699 | } else { |
1580 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER | 1700 | sprintf(page + len, KERN_ERR PRINTK_HEADER |
1581 | " SORRY - NO VALID SENSE AVAILABLE\n"); | 1701 | " SORRY - NO VALID SENSE AVAILABLE\n"); |
1582 | } | 1702 | } |
1583 | MESSAGE_LOG(KERN_ERR, "%s", | 1703 | printk("%s", page); |
1584 | page + sizeof(KERN_ERR PRINTK_HEADER)); | 1704 | |
1585 | 1705 | /* dump the Channel Program (max 140 Bytes per line) */ | |
1586 | /* dump the Channel Program */ | 1706 | /* Count CCW and print first CCWs (maximum 1024 % 140 = 7) */ |
1587 | /* print first CCWs (maximum 8) */ | 1707 | first = req->cpaddr; |
1588 | act = req->cpaddr; | 1708 | for (last = first; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++); |
1589 | for (last = act; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++); | 1709 | to = min(first + 6, last); |
1590 | end = min(act + 8, last); | 1710 | len = sprintf(page, KERN_ERR PRINTK_HEADER |
1591 | len = sprintf(page, KERN_ERR PRINTK_HEADER | ||
1592 | " Related CP in req: %p\n", req); | 1711 | " Related CP in req: %p\n", req); |
1593 | while (act <= end) { | 1712 | dasd_eckd_dump_ccw_range(first, to, page + len); |
1594 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER | 1713 | printk("%s", page); |
1595 | " CCW %p: %08X %08X DAT:", | ||
1596 | act, ((int *) act)[0], ((int *) act)[1]); | ||
1597 | for (count = 0; count < 32 && count < act->count; | ||
1598 | count += sizeof(int)) | ||
1599 | len += sprintf(page + len, " %08X", | ||
1600 | ((int *) (addr_t) act->cda) | ||
1601 | [(count>>2)]); | ||
1602 | len += sprintf(page + len, "\n"); | ||
1603 | act++; | ||
1604 | } | ||
1605 | MESSAGE_LOG(KERN_ERR, "%s", | ||
1606 | page + sizeof(KERN_ERR PRINTK_HEADER)); | ||
1607 | 1714 | ||
1608 | /* print failing CCW area */ | 1715 | /* print failing CCW area (maximum 4) */ |
1716 | /* scsw->cda is either valid or zero */ | ||
1609 | len = 0; | 1717 | len = 0; |
1610 | if (act < ((struct ccw1 *)(addr_t) irb->scsw.cpa) - 2) { | 1718 | from = ++to; |
1611 | act = ((struct ccw1 *)(addr_t) irb->scsw.cpa) - 2; | 1719 | fail = (struct ccw1 *)(addr_t) irb->scsw.cpa; /* failing CCW */ |
1612 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n"); | 1720 | if (from < fail - 2) { |
1613 | } | 1721 | from = fail - 2; /* there is a gap - print header */ |
1614 | end = min((struct ccw1 *)(addr_t) irb->scsw.cpa + 2, last); | 1722 | len += sprintf(page, KERN_ERR PRINTK_HEADER "......\n"); |
1615 | while (act <= end) { | ||
1616 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER | ||
1617 | " CCW %p: %08X %08X DAT:", | ||
1618 | act, ((int *) act)[0], ((int *) act)[1]); | ||
1619 | for (count = 0; count < 32 && count < act->count; | ||
1620 | count += sizeof(int)) | ||
1621 | len += sprintf(page + len, " %08X", | ||
1622 | ((int *) (addr_t) act->cda) | ||
1623 | [(count>>2)]); | ||
1624 | len += sprintf(page + len, "\n"); | ||
1625 | act++; | ||
1626 | } | 1723 | } |
1724 | to = min(fail + 1, last); | ||
1725 | len += dasd_eckd_dump_ccw_range(from, to, page + len); | ||
1627 | 1726 | ||
1628 | /* print last CCWs */ | 1727 | /* print last CCWs (maximum 2) */ |
1629 | if (act < last - 2) { | 1728 | from = max(from, ++to); |
1630 | act = last - 2; | 1729 | if (from < last - 1) { |
1730 | from = last - 1; /* there is a gap - print header */ | ||
1631 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n"); | 1731 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n"); |
1632 | } | 1732 | } |
1633 | while (act <= last) { | 1733 | len += dasd_eckd_dump_ccw_range(from, last, page + len); |
1634 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER | ||
1635 | " CCW %p: %08X %08X DAT:", | ||
1636 | act, ((int *) act)[0], ((int *) act)[1]); | ||
1637 | for (count = 0; count < 32 && count < act->count; | ||
1638 | count += sizeof(int)) | ||
1639 | len += sprintf(page + len, " %08X", | ||
1640 | ((int *) (addr_t) act->cda) | ||
1641 | [(count>>2)]); | ||
1642 | len += sprintf(page + len, "\n"); | ||
1643 | act++; | ||
1644 | } | ||
1645 | if (len > 0) | 1734 | if (len > 0) |
1646 | MESSAGE_LOG(KERN_ERR, "%s", | 1735 | printk("%s", page); |
1647 | page + sizeof(KERN_ERR PRINTK_HEADER)); | ||
1648 | free_page((unsigned long) page); | 1736 | free_page((unsigned long) page); |
1649 | } | 1737 | } |
1650 | 1738 | ||
@@ -1685,14 +1773,8 @@ static struct dasd_discipline dasd_eckd_discipline = { | |||
1685 | static int __init | 1773 | static int __init |
1686 | dasd_eckd_init(void) | 1774 | dasd_eckd_init(void) |
1687 | { | 1775 | { |
1688 | int ret; | ||
1689 | |||
1690 | ASCEBC(dasd_eckd_discipline.ebcname, 4); | 1776 | ASCEBC(dasd_eckd_discipline.ebcname, 4); |
1691 | 1777 | return ccw_driver_register(&dasd_eckd_driver); | |
1692 | ret = ccw_driver_register(&dasd_eckd_driver); | ||
1693 | if (!ret) | ||
1694 | dasd_generic_auto_online(&dasd_eckd_driver); | ||
1695 | return ret; | ||
1696 | } | 1778 | } |
1697 | 1779 | ||
1698 | static void __exit | 1780 | static void __exit |
@@ -1703,22 +1785,3 @@ dasd_eckd_cleanup(void) | |||
1703 | 1785 | ||
1704 | module_init(dasd_eckd_init); | 1786 | module_init(dasd_eckd_init); |
1705 | module_exit(dasd_eckd_cleanup); | 1787 | module_exit(dasd_eckd_cleanup); |
1706 | |||
1707 | /* | ||
1708 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
1709 | * Emacs will notice this stuff at the end of the file and automatically | ||
1710 | * adjust the settings for this buffer only. This must remain at the end | ||
1711 | * of the file. | ||
1712 | * --------------------------------------------------------------------------- | ||
1713 | * Local variables: | ||
1714 | * c-indent-level: 4 | ||
1715 | * c-brace-imaginary-offset: 0 | ||
1716 | * c-brace-offset: -4 | ||
1717 | * c-argdecl-indent: 4 | ||
1718 | * c-label-offset: -4 | ||
1719 | * c-continued-statement-offset: 4 | ||
1720 | * c-continued-brace-offset: 0 | ||
1721 | * indent-tabs-mode: 1 | ||
1722 | * tab-width: 8 | ||
1723 | * End: | ||
1724 | */ | ||
diff --git a/drivers/s390/block/dasd_eckd.h b/drivers/s390/block/dasd_eckd.h index d5734e976e1c..712ff1650134 100644 --- a/drivers/s390/block/dasd_eckd.h +++ b/drivers/s390/block/dasd_eckd.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * File...........: linux/drivers/s390/block/dasd_eckd.h | 2 | * File...........: linux/drivers/s390/block/dasd_eckd.h |
3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> | 3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> |
4 | * Horst Hummel <Horst.Hummel@de.ibm.com> | 4 | * Horst Hummel <Horst.Hummel@de.ibm.com> |
5 | * Bugreports.to..: <Linux390@de.ibm.com> | 5 | * Bugreports.to..: <Linux390@de.ibm.com> |
6 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 | 6 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 |
7 | * | 7 | * |
@@ -41,9 +41,10 @@ | |||
41 | #define DASD_ECKD_CCW_RESERVE 0xB4 | 41 | #define DASD_ECKD_CCW_RESERVE 0xB4 |
42 | 42 | ||
43 | /* | 43 | /* |
44 | *Perform Subsystem Function / Sub-Orders | 44 | * Perform Subsystem Function / Sub-Orders |
45 | */ | 45 | */ |
46 | #define PSF_ORDER_PRSSD 0x18 | 46 | #define PSF_ORDER_PRSSD 0x18 |
47 | #define PSF_ORDER_SSC 0x1D | ||
47 | 48 | ||
48 | /***************************************************************************** | 49 | /***************************************************************************** |
49 | * SECTION: Type Definitions | 50 | * SECTION: Type Definitions |
@@ -155,7 +156,7 @@ struct dasd_eckd_characteristics { | |||
155 | unsigned char reserved2:4; | 156 | unsigned char reserved2:4; |
156 | unsigned char reserved3:8; | 157 | unsigned char reserved3:8; |
157 | unsigned char defect_wr:1; | 158 | unsigned char defect_wr:1; |
158 | unsigned char XRC_supported:1; | 159 | unsigned char XRC_supported:1; |
159 | unsigned char reserved4:1; | 160 | unsigned char reserved4:1; |
160 | unsigned char striping:1; | 161 | unsigned char striping:1; |
161 | unsigned char reserved5:4; | 162 | unsigned char reserved5:4; |
@@ -343,7 +344,7 @@ struct dasd_eckd_path { | |||
343 | }; | 344 | }; |
344 | 345 | ||
345 | /* | 346 | /* |
346 | * Perform Subsystem Function - Prepare for Read Subsystem Data | 347 | * Perform Subsystem Function - Prepare for Read Subsystem Data |
347 | */ | 348 | */ |
348 | struct dasd_psf_prssd_data { | 349 | struct dasd_psf_prssd_data { |
349 | unsigned char order; | 350 | unsigned char order; |
@@ -353,4 +354,15 @@ struct dasd_psf_prssd_data { | |||
353 | unsigned char varies[9]; | 354 | unsigned char varies[9]; |
354 | } __attribute__ ((packed)); | 355 | } __attribute__ ((packed)); |
355 | 356 | ||
357 | /* | ||
358 | * Perform Subsystem Function - Set Subsystem Characteristics | ||
359 | */ | ||
360 | struct dasd_psf_ssc_data { | ||
361 | unsigned char order; | ||
362 | unsigned char flags; | ||
363 | unsigned char cu_type[4]; | ||
364 | unsigned char suborder; | ||
365 | unsigned char reserved[59]; | ||
366 | } __attribute__((packed)); | ||
367 | |||
356 | #endif /* DASD_ECKD_H */ | 368 | #endif /* DASD_ECKD_H */ |
diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c index 2d8af709947f..da65f1b032f5 100644 --- a/drivers/s390/block/dasd_eer.c +++ b/drivers/s390/block/dasd_eer.c | |||
@@ -276,7 +276,7 @@ struct dasd_eer_header { | |||
276 | __u64 tv_sec; | 276 | __u64 tv_sec; |
277 | __u64 tv_usec; | 277 | __u64 tv_usec; |
278 | char busid[DASD_EER_BUSID_SIZE]; | 278 | char busid[DASD_EER_BUSID_SIZE]; |
279 | }; | 279 | } __attribute__ ((packed)); |
280 | 280 | ||
281 | /* | 281 | /* |
282 | * The following function can be used for those triggers that have | 282 | * The following function can be used for those triggers that have |
@@ -521,6 +521,8 @@ static int dasd_eer_open(struct inode *inp, struct file *filp) | |||
521 | unsigned long flags; | 521 | unsigned long flags; |
522 | 522 | ||
523 | eerb = kzalloc(sizeof(struct eerbuffer), GFP_KERNEL); | 523 | eerb = kzalloc(sizeof(struct eerbuffer), GFP_KERNEL); |
524 | if (!eerb) | ||
525 | return -ENOMEM; | ||
524 | eerb->buffer_page_count = eer_pages; | 526 | eerb->buffer_page_count = eer_pages; |
525 | if (eerb->buffer_page_count < 1 || | 527 | if (eerb->buffer_page_count < 1 || |
526 | eerb->buffer_page_count > INT_MAX / PAGE_SIZE) { | 528 | eerb->buffer_page_count > INT_MAX / PAGE_SIZE) { |
diff --git a/drivers/s390/block/dasd_erp.c b/drivers/s390/block/dasd_erp.c index b842377cb0c6..4108d96f6a5a 100644 --- a/drivers/s390/block/dasd_erp.c +++ b/drivers/s390/block/dasd_erp.c | |||
@@ -90,7 +90,7 @@ dasd_default_erp_action(struct dasd_ccw_req * cqr) | |||
90 | 90 | ||
91 | /* just retry - there is nothing to save ... I got no sense data.... */ | 91 | /* just retry - there is nothing to save ... I got no sense data.... */ |
92 | if (cqr->retries > 0) { | 92 | if (cqr->retries > 0) { |
93 | DEV_MESSAGE (KERN_DEBUG, device, | 93 | DEV_MESSAGE (KERN_DEBUG, device, |
94 | "default ERP called (%i retries left)", | 94 | "default ERP called (%i retries left)", |
95 | cqr->retries); | 95 | cqr->retries); |
96 | cqr->lpm = LPM_ANYPATH; | 96 | cqr->lpm = LPM_ANYPATH; |
@@ -155,7 +155,7 @@ dasd_default_erp_postaction(struct dasd_ccw_req * cqr) | |||
155 | 155 | ||
156 | /* | 156 | /* |
157 | * Print the hex dump of the memory used by a request. This includes | 157 | * Print the hex dump of the memory used by a request. This includes |
158 | * all error recovery ccws that have been chained in from of the | 158 | * all error recovery ccws that have been chained in from of the |
159 | * real request. | 159 | * real request. |
160 | */ | 160 | */ |
161 | static inline void | 161 | static inline void |
@@ -227,12 +227,12 @@ dasd_log_ccw(struct dasd_ccw_req * cqr, int caller, __u32 cpa) | |||
227 | /* | 227 | /* |
228 | * Log bytes arround failed CCW but only if we did | 228 | * Log bytes arround failed CCW but only if we did |
229 | * not log the whole CP of the CCW is outside the | 229 | * not log the whole CP of the CCW is outside the |
230 | * logged CP. | 230 | * logged CP. |
231 | */ | 231 | */ |
232 | if (cplength > 40 || | 232 | if (cplength > 40 || |
233 | ((addr_t) cpa < (addr_t) lcqr->cpaddr && | 233 | ((addr_t) cpa < (addr_t) lcqr->cpaddr && |
234 | (addr_t) cpa > (addr_t) (lcqr->cpaddr + cplength + 4))) { | 234 | (addr_t) cpa > (addr_t) (lcqr->cpaddr + cplength + 4))) { |
235 | 235 | ||
236 | DEV_MESSAGE(KERN_ERR, device, | 236 | DEV_MESSAGE(KERN_ERR, device, |
237 | "Failed CCW (%p) (area):", | 237 | "Failed CCW (%p) (area):", |
238 | (void *) (long) cpa); | 238 | (void *) (long) cpa); |
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c index 91145698f8e9..bb7755b9b19d 100644 --- a/drivers/s390/block/dasd_fba.c +++ b/drivers/s390/block/dasd_fba.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * File...........: linux/drivers/s390/block/dasd_fba.c | 2 | * File...........: linux/drivers/s390/block/dasd_fba.c |
3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> | 3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> |
4 | * Bugreports.to..: <Linux390@de.ibm.com> | 4 | * Bugreports.to..: <Linux390@de.ibm.com> |
@@ -56,19 +56,13 @@ static struct ccw_driver dasd_fba_driver; /* see below */ | |||
56 | static int | 56 | static int |
57 | dasd_fba_probe(struct ccw_device *cdev) | 57 | dasd_fba_probe(struct ccw_device *cdev) |
58 | { | 58 | { |
59 | int ret; | 59 | return dasd_generic_probe(cdev, &dasd_fba_discipline); |
60 | |||
61 | ret = dasd_generic_probe (cdev, &dasd_fba_discipline); | ||
62 | if (ret) | ||
63 | return ret; | ||
64 | ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP); | ||
65 | return 0; | ||
66 | } | 60 | } |
67 | 61 | ||
68 | static int | 62 | static int |
69 | dasd_fba_set_online(struct ccw_device *cdev) | 63 | dasd_fba_set_online(struct ccw_device *cdev) |
70 | { | 64 | { |
71 | return dasd_generic_set_online (cdev, &dasd_fba_discipline); | 65 | return dasd_generic_set_online(cdev, &dasd_fba_discipline); |
72 | } | 66 | } |
73 | 67 | ||
74 | static struct ccw_driver dasd_fba_driver = { | 68 | static struct ccw_driver dasd_fba_driver = { |
@@ -125,13 +119,13 @@ static int | |||
125 | dasd_fba_check_characteristics(struct dasd_device *device) | 119 | dasd_fba_check_characteristics(struct dasd_device *device) |
126 | { | 120 | { |
127 | struct dasd_fba_private *private; | 121 | struct dasd_fba_private *private; |
128 | struct ccw_device *cdev = device->cdev; | 122 | struct ccw_device *cdev = device->cdev; |
129 | void *rdc_data; | 123 | void *rdc_data; |
130 | int rc; | 124 | int rc; |
131 | 125 | ||
132 | private = (struct dasd_fba_private *) device->private; | 126 | private = (struct dasd_fba_private *) device->private; |
133 | if (private == NULL) { | 127 | if (private == NULL) { |
134 | private = kmalloc(sizeof(struct dasd_fba_private), GFP_KERNEL); | 128 | private = kzalloc(sizeof(struct dasd_fba_private), GFP_KERNEL); |
135 | if (private == NULL) { | 129 | if (private == NULL) { |
136 | DEV_MESSAGE(KERN_WARNING, device, "%s", | 130 | DEV_MESSAGE(KERN_WARNING, device, "%s", |
137 | "memory allocation failed for private " | 131 | "memory allocation failed for private " |
@@ -204,7 +198,7 @@ dasd_fba_examine_error(struct dasd_ccw_req * cqr, struct irb * irb) | |||
204 | if (irb->scsw.cstat == 0x00 && | 198 | if (irb->scsw.cstat == 0x00 && |
205 | irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END)) | 199 | irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END)) |
206 | return dasd_era_none; | 200 | return dasd_era_none; |
207 | 201 | ||
208 | cdev = device->cdev; | 202 | cdev = device->cdev; |
209 | switch (cdev->id.dev_type) { | 203 | switch (cdev->id.dev_type) { |
210 | case 0x3370: | 204 | case 0x3370: |
@@ -539,7 +533,7 @@ dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req, | |||
539 | * 8192 bytes (=2 pages). For 64 bit one dasd_mchunkt_t structure has | 533 | * 8192 bytes (=2 pages). For 64 bit one dasd_mchunkt_t structure has |
540 | * 24 bytes, the struct dasd_ccw_req has 136 bytes and each block can use | 534 | * 24 bytes, the struct dasd_ccw_req has 136 bytes and each block can use |
541 | * up to 16 bytes (8 for the ccw and 8 for the idal pointer). In | 535 | * up to 16 bytes (8 for the ccw and 8 for the idal pointer). In |
542 | * addition we have one define extent ccw + 16 bytes of data and a | 536 | * addition we have one define extent ccw + 16 bytes of data and a |
543 | * locate record ccw for each block (stupid devices!) + 16 bytes of data. | 537 | * locate record ccw for each block (stupid devices!) + 16 bytes of data. |
544 | * That makes: | 538 | * That makes: |
545 | * (8192 - 24 - 136 - 8 - 16) / 40 = 200.2 blocks at maximum. | 539 | * (8192 - 24 - 136 - 8 - 16) / 40 = 200.2 blocks at maximum. |
@@ -569,16 +563,8 @@ static struct dasd_discipline dasd_fba_discipline = { | |||
569 | static int __init | 563 | static int __init |
570 | dasd_fba_init(void) | 564 | dasd_fba_init(void) |
571 | { | 565 | { |
572 | int ret; | ||
573 | |||
574 | ASCEBC(dasd_fba_discipline.ebcname, 4); | 566 | ASCEBC(dasd_fba_discipline.ebcname, 4); |
575 | 567 | return ccw_driver_register(&dasd_fba_driver); | |
576 | ret = ccw_driver_register(&dasd_fba_driver); | ||
577 | if (ret) | ||
578 | return ret; | ||
579 | |||
580 | dasd_generic_auto_online(&dasd_fba_driver); | ||
581 | return 0; | ||
582 | } | 568 | } |
583 | 569 | ||
584 | static void __exit | 570 | static void __exit |
@@ -589,22 +575,3 @@ dasd_fba_cleanup(void) | |||
589 | 575 | ||
590 | module_init(dasd_fba_init); | 576 | module_init(dasd_fba_init); |
591 | module_exit(dasd_fba_cleanup); | 577 | module_exit(dasd_fba_cleanup); |
592 | |||
593 | /* | ||
594 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
595 | * Emacs will notice this stuff at the end of the file and automatically | ||
596 | * adjust the settings for this buffer only. This must remain at the end | ||
597 | * of the file. | ||
598 | * --------------------------------------------------------------------------- | ||
599 | * Local variables: | ||
600 | * c-indent-level: 4 | ||
601 | * c-brace-imaginary-offset: 0 | ||
602 | * c-brace-offset: -4 | ||
603 | * c-argdecl-indent: 4 | ||
604 | * c-label-offset: -4 | ||
605 | * c-continued-statement-offset: 4 | ||
606 | * c-continued-brace-offset: 0 | ||
607 | * indent-tabs-mode: 1 | ||
608 | * tab-width: 8 | ||
609 | * End: | ||
610 | */ | ||
diff --git a/drivers/s390/block/dasd_fba.h b/drivers/s390/block/dasd_fba.h index da1fa91fc01d..14c910baa5fe 100644 --- a/drivers/s390/block/dasd_fba.h +++ b/drivers/s390/block/dasd_fba.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * File...........: linux/drivers/s390/block/dasd_fba.h | 2 | * File...........: linux/drivers/s390/block/dasd_fba.h |
3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> | 3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> |
4 | * Bugreports.to..: <Linux390@de.ibm.com> | 4 | * Bugreports.to..: <Linux390@de.ibm.com> |
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index d4b13e300a76..03a83efc34c4 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * File...........: linux/drivers/s390/block/dasd_int.h | 2 | * File...........: linux/drivers/s390/block/dasd_int.h |
3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> | 3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> |
4 | * Horst Hummel <Horst.Hummel@de.ibm.com> | 4 | * Horst Hummel <Horst.Hummel@de.ibm.com> |
5 | * Martin Schwidefsky <schwidefsky@de.ibm.com> | 5 | * Martin Schwidefsky <schwidefsky@de.ibm.com> |
6 | * Bugreports.to..: <Linux390@de.ibm.com> | 6 | * Bugreports.to..: <Linux390@de.ibm.com> |
7 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 | 7 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 |
@@ -186,7 +186,7 @@ struct dasd_ccw_req { | |||
186 | void *callback_data; | 186 | void *callback_data; |
187 | }; | 187 | }; |
188 | 188 | ||
189 | /* | 189 | /* |
190 | * dasd_ccw_req -> status can be: | 190 | * dasd_ccw_req -> status can be: |
191 | */ | 191 | */ |
192 | #define DASD_CQR_FILLED 0x00 /* request is ready to be processed */ | 192 | #define DASD_CQR_FILLED 0x00 /* request is ready to be processed */ |
@@ -248,7 +248,7 @@ struct dasd_discipline { | |||
248 | /* | 248 | /* |
249 | * Error recovery functions. examine_error() returns a value that | 249 | * Error recovery functions. examine_error() returns a value that |
250 | * indicates what to do for an error condition. If examine_error() | 250 | * indicates what to do for an error condition. If examine_error() |
251 | * returns 'dasd_era_recover' erp_action() is called to create a | 251 | * returns 'dasd_era_recover' erp_action() is called to create a |
252 | * special error recovery ccw. erp_postaction() is called after | 252 | * special error recovery ccw. erp_postaction() is called after |
253 | * an error recovery ccw has finished its execution. dump_sense | 253 | * an error recovery ccw has finished its execution. dump_sense |
254 | * is called for every error condition to print the sense data | 254 | * is called for every error condition to print the sense data |
@@ -302,11 +302,11 @@ struct dasd_device { | |||
302 | spinlock_t request_queue_lock; | 302 | spinlock_t request_queue_lock; |
303 | struct block_device *bdev; | 303 | struct block_device *bdev; |
304 | unsigned int devindex; | 304 | unsigned int devindex; |
305 | unsigned long blocks; /* size of volume in blocks */ | 305 | unsigned long blocks; /* size of volume in blocks */ |
306 | unsigned int bp_block; /* bytes per block */ | 306 | unsigned int bp_block; /* bytes per block */ |
307 | unsigned int s2b_shift; /* log2 (bp_block/512) */ | 307 | unsigned int s2b_shift; /* log2 (bp_block/512) */ |
308 | unsigned long flags; /* per device flags */ | 308 | unsigned long flags; /* per device flags */ |
309 | unsigned short features; /* copy of devmap-features (read-only!) */ | 309 | unsigned short features; /* copy of devmap-features (read-only!) */ |
310 | 310 | ||
311 | /* extended error reporting stuff (eer) */ | 311 | /* extended error reporting stuff (eer) */ |
312 | struct dasd_ccw_req *eer_cqr; | 312 | struct dasd_ccw_req *eer_cqr; |
@@ -513,12 +513,12 @@ void dasd_generic_remove (struct ccw_device *cdev); | |||
513 | int dasd_generic_set_online(struct ccw_device *, struct dasd_discipline *); | 513 | int dasd_generic_set_online(struct ccw_device *, struct dasd_discipline *); |
514 | int dasd_generic_set_offline (struct ccw_device *cdev); | 514 | int dasd_generic_set_offline (struct ccw_device *cdev); |
515 | int dasd_generic_notify(struct ccw_device *, int); | 515 | int dasd_generic_notify(struct ccw_device *, int); |
516 | void dasd_generic_auto_online (struct ccw_driver *); | ||
517 | 516 | ||
518 | /* externals in dasd_devmap.c */ | 517 | /* externals in dasd_devmap.c */ |
519 | extern int dasd_max_devindex; | 518 | extern int dasd_max_devindex; |
520 | extern int dasd_probeonly; | 519 | extern int dasd_probeonly; |
521 | extern int dasd_autodetect; | 520 | extern int dasd_autodetect; |
521 | extern int dasd_nopav; | ||
522 | 522 | ||
523 | int dasd_devmap_init(void); | 523 | int dasd_devmap_init(void); |
524 | void dasd_devmap_exit(void); | 524 | void dasd_devmap_exit(void); |
@@ -606,22 +606,3 @@ static inline int dasd_eer_enabled(struct dasd_device *device) | |||
606 | #endif /* __KERNEL__ */ | 606 | #endif /* __KERNEL__ */ |
607 | 607 | ||
608 | #endif /* DASD_H */ | 608 | #endif /* DASD_H */ |
609 | |||
610 | /* | ||
611 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
612 | * Emacs will notice this stuff at the end of the file and automatically | ||
613 | * adjust the settings for this buffer only. This must remain at the end | ||
614 | * of the file. | ||
615 | * --------------------------------------------------------------------------- | ||
616 | * Local variables: | ||
617 | * c-indent-level: 4 | ||
618 | * c-brace-imaginary-offset: 0 | ||
619 | * c-brace-offset: -4 | ||
620 | * c-argdecl-indent: 4 | ||
621 | * c-label-offset: -4 | ||
622 | * c-continued-statement-offset: 4 | ||
623 | * c-continued-brace-offset: 0 | ||
624 | * indent-tabs-mode: 1 | ||
625 | * tab-width: 8 | ||
626 | * End: | ||
627 | */ | ||
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index b8c80d28df41..302bcd0f28be 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c | |||
@@ -90,10 +90,10 @@ static int | |||
90 | dasd_ioctl_quiesce(struct dasd_device *device) | 90 | dasd_ioctl_quiesce(struct dasd_device *device) |
91 | { | 91 | { |
92 | unsigned long flags; | 92 | unsigned long flags; |
93 | 93 | ||
94 | if (!capable (CAP_SYS_ADMIN)) | 94 | if (!capable (CAP_SYS_ADMIN)) |
95 | return -EACCES; | 95 | return -EACCES; |
96 | 96 | ||
97 | DEV_MESSAGE (KERN_DEBUG, device, "%s", | 97 | DEV_MESSAGE (KERN_DEBUG, device, "%s", |
98 | "Quiesce IO on device"); | 98 | "Quiesce IO on device"); |
99 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | 99 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); |
@@ -110,13 +110,13 @@ static int | |||
110 | dasd_ioctl_resume(struct dasd_device *device) | 110 | dasd_ioctl_resume(struct dasd_device *device) |
111 | { | 111 | { |
112 | unsigned long flags; | 112 | unsigned long flags; |
113 | 113 | ||
114 | if (!capable (CAP_SYS_ADMIN)) | 114 | if (!capable (CAP_SYS_ADMIN)) |
115 | return -EACCES; | 115 | return -EACCES; |
116 | 116 | ||
117 | DEV_MESSAGE (KERN_DEBUG, device, "%s", | 117 | DEV_MESSAGE (KERN_DEBUG, device, "%s", |
118 | "resume IO on device"); | 118 | "resume IO on device"); |
119 | 119 | ||
120 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | 120 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); |
121 | device->stopped &= ~DASD_STOPPED_QUIESCE; | 121 | device->stopped &= ~DASD_STOPPED_QUIESCE; |
122 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); | 122 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); |
@@ -287,7 +287,7 @@ dasd_ioctl_information(struct dasd_device *device, | |||
287 | dasd_info->open_count = atomic_read(&device->open_count); | 287 | dasd_info->open_count = atomic_read(&device->open_count); |
288 | if (!device->bdev) | 288 | if (!device->bdev) |
289 | dasd_info->open_count++; | 289 | dasd_info->open_count++; |
290 | 290 | ||
291 | /* | 291 | /* |
292 | * check if device is really formatted | 292 | * check if device is really formatted |
293 | * LDL / CDL was returned by 'fill_info' | 293 | * LDL / CDL was returned by 'fill_info' |
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index eecb2afad5c2..3c1314b7391b 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c | |||
@@ -50,6 +50,9 @@ struct raw3270 { | |||
50 | unsigned char *ascebc; /* ascii -> ebcdic table */ | 50 | unsigned char *ascebc; /* ascii -> ebcdic table */ |
51 | struct class_device *clttydev; /* 3270-class tty device ptr */ | 51 | struct class_device *clttydev; /* 3270-class tty device ptr */ |
52 | struct class_device *cltubdev; /* 3270-class tub device ptr */ | 52 | struct class_device *cltubdev; /* 3270-class tub device ptr */ |
53 | |||
54 | struct raw3270_request init_request; | ||
55 | unsigned char init_data[256]; | ||
53 | }; | 56 | }; |
54 | 57 | ||
55 | /* raw3270->flags */ | 58 | /* raw3270->flags */ |
@@ -484,8 +487,6 @@ struct raw3270_ua { /* Query Reply structure for Usable Area */ | |||
484 | } __attribute__ ((packed)) aua; | 487 | } __attribute__ ((packed)) aua; |
485 | } __attribute__ ((packed)); | 488 | } __attribute__ ((packed)); |
486 | 489 | ||
487 | static unsigned char raw3270_init_data[256]; | ||
488 | static struct raw3270_request raw3270_init_request; | ||
489 | static struct diag210 raw3270_init_diag210; | 490 | static struct diag210 raw3270_init_diag210; |
490 | static DECLARE_MUTEX(raw3270_init_sem); | 491 | static DECLARE_MUTEX(raw3270_init_sem); |
491 | 492 | ||
@@ -644,17 +645,17 @@ __raw3270_size_device(struct raw3270 *rp) | |||
644 | * required (3270 device switched to 'stand-by') and command | 645 | * required (3270 device switched to 'stand-by') and command |
645 | * rejects (old devices that can't do 'read partition'). | 646 | * rejects (old devices that can't do 'read partition'). |
646 | */ | 647 | */ |
647 | memset(&raw3270_init_request, 0, sizeof(raw3270_init_request)); | 648 | memset(&rp->init_request, 0, sizeof(rp->init_request)); |
648 | memset(raw3270_init_data, 0, sizeof(raw3270_init_data)); | 649 | memset(&rp->init_data, 0, 256); |
649 | /* Store 'read partition' data stream to raw3270_init_data */ | 650 | /* Store 'read partition' data stream to init_data */ |
650 | memcpy(raw3270_init_data, wbuf, sizeof(wbuf)); | 651 | memcpy(&rp->init_data, wbuf, sizeof(wbuf)); |
651 | INIT_LIST_HEAD(&raw3270_init_request.list); | 652 | INIT_LIST_HEAD(&rp->init_request.list); |
652 | raw3270_init_request.ccw.cmd_code = TC_WRITESF; | 653 | rp->init_request.ccw.cmd_code = TC_WRITESF; |
653 | raw3270_init_request.ccw.flags = CCW_FLAG_SLI; | 654 | rp->init_request.ccw.flags = CCW_FLAG_SLI; |
654 | raw3270_init_request.ccw.count = sizeof(wbuf); | 655 | rp->init_request.ccw.count = sizeof(wbuf); |
655 | raw3270_init_request.ccw.cda = (__u32) __pa(raw3270_init_data); | 656 | rp->init_request.ccw.cda = (__u32) __pa(&rp->init_data); |
656 | 657 | ||
657 | rc = raw3270_start_init(rp, &raw3270_init_view, &raw3270_init_request); | 658 | rc = raw3270_start_init(rp, &raw3270_init_view, &rp->init_request); |
658 | if (rc) | 659 | if (rc) |
659 | /* Check error cases: -ERESTARTSYS, -EIO and -EOPNOTSUPP */ | 660 | /* Check error cases: -ERESTARTSYS, -EIO and -EOPNOTSUPP */ |
660 | return rc; | 661 | return rc; |
@@ -679,18 +680,18 @@ __raw3270_size_device(struct raw3270 *rp) | |||
679 | * The device accepted the 'read partition' command. Now | 680 | * The device accepted the 'read partition' command. Now |
680 | * set up a read ccw and issue it. | 681 | * set up a read ccw and issue it. |
681 | */ | 682 | */ |
682 | raw3270_init_request.ccw.cmd_code = TC_READMOD; | 683 | rp->init_request.ccw.cmd_code = TC_READMOD; |
683 | raw3270_init_request.ccw.flags = CCW_FLAG_SLI; | 684 | rp->init_request.ccw.flags = CCW_FLAG_SLI; |
684 | raw3270_init_request.ccw.count = sizeof(raw3270_init_data); | 685 | rp->init_request.ccw.count = sizeof(rp->init_data); |
685 | raw3270_init_request.ccw.cda = (__u32) __pa(raw3270_init_data); | 686 | rp->init_request.ccw.cda = (__u32) __pa(rp->init_data); |
686 | rc = raw3270_start_init(rp, &raw3270_init_view, &raw3270_init_request); | 687 | rc = raw3270_start_init(rp, &raw3270_init_view, &rp->init_request); |
687 | if (rc) | 688 | if (rc) |
688 | return rc; | 689 | return rc; |
689 | /* Got a Query Reply */ | 690 | /* Got a Query Reply */ |
690 | count = sizeof(raw3270_init_data) - raw3270_init_request.rescnt; | 691 | count = sizeof(rp->init_data) - rp->init_request.rescnt; |
691 | uap = (struct raw3270_ua *) (raw3270_init_data + 1); | 692 | uap = (struct raw3270_ua *) (rp->init_data + 1); |
692 | /* Paranoia check. */ | 693 | /* Paranoia check. */ |
693 | if (raw3270_init_data[0] != 0x88 || uap->uab.qcode != 0x81) | 694 | if (rp->init_data[0] != 0x88 || uap->uab.qcode != 0x81) |
694 | return -EOPNOTSUPP; | 695 | return -EOPNOTSUPP; |
695 | /* Copy rows/columns of default Usable Area */ | 696 | /* Copy rows/columns of default Usable Area */ |
696 | rp->rows = uap->uab.h; | 697 | rp->rows = uap->uab.h; |
@@ -749,18 +750,18 @@ raw3270_reset_device(struct raw3270 *rp) | |||
749 | int rc; | 750 | int rc; |
750 | 751 | ||
751 | down(&raw3270_init_sem); | 752 | down(&raw3270_init_sem); |
752 | memset(&raw3270_init_request, 0, sizeof(raw3270_init_request)); | 753 | memset(&rp->init_request, 0, sizeof(rp->init_request)); |
753 | memset(raw3270_init_data, 0, sizeof(raw3270_init_data)); | 754 | memset(&rp->init_data, 0, sizeof(rp->init_data)); |
754 | /* Store reset data stream to raw3270_init_data/raw3270_init_request */ | 755 | /* Store reset data stream to init_data/init_request */ |
755 | raw3270_init_data[0] = TW_KR; | 756 | rp->init_data[0] = TW_KR; |
756 | INIT_LIST_HEAD(&raw3270_init_request.list); | 757 | INIT_LIST_HEAD(&rp->init_request.list); |
757 | raw3270_init_request.ccw.cmd_code = TC_EWRITEA; | 758 | rp->init_request.ccw.cmd_code = TC_EWRITEA; |
758 | raw3270_init_request.ccw.flags = CCW_FLAG_SLI; | 759 | rp->init_request.ccw.flags = CCW_FLAG_SLI; |
759 | raw3270_init_request.ccw.count = 1; | 760 | rp->init_request.ccw.count = 1; |
760 | raw3270_init_request.ccw.cda = (__u32) __pa(raw3270_init_data); | 761 | rp->init_request.ccw.cda = (__u32) __pa(rp->init_data); |
761 | rp->view = &raw3270_init_view; | 762 | rp->view = &raw3270_init_view; |
762 | raw3270_init_view.dev = rp; | 763 | raw3270_init_view.dev = rp; |
763 | rc = raw3270_start_init(rp, &raw3270_init_view, &raw3270_init_request); | 764 | rc = raw3270_start_init(rp, &raw3270_init_view, &rp->init_request); |
764 | raw3270_init_view.dev = 0; | 765 | raw3270_init_view.dev = 0; |
765 | rp->view = 0; | 766 | rp->view = 0; |
766 | up(&raw3270_init_sem); | 767 | up(&raw3270_init_sem); |
@@ -854,7 +855,7 @@ raw3270_setup_console(struct ccw_device *cdev) | |||
854 | char *ascebc; | 855 | char *ascebc; |
855 | int rc; | 856 | int rc; |
856 | 857 | ||
857 | rp = (struct raw3270 *) alloc_bootmem(sizeof(struct raw3270)); | 858 | rp = (struct raw3270 *) alloc_bootmem_low(sizeof(struct raw3270)); |
858 | ascebc = (char *) alloc_bootmem(256); | 859 | ascebc = (char *) alloc_bootmem(256); |
859 | rc = raw3270_setup_device(cdev, rp, ascebc); | 860 | rc = raw3270_setup_device(cdev, rp, ascebc); |
860 | if (rc) | 861 | if (rc) |
@@ -895,7 +896,7 @@ raw3270_create_device(struct ccw_device *cdev) | |||
895 | char *ascebc; | 896 | char *ascebc; |
896 | int rc; | 897 | int rc; |
897 | 898 | ||
898 | rp = kmalloc(sizeof(struct raw3270), GFP_KERNEL); | 899 | rp = kmalloc(sizeof(struct raw3270), GFP_KERNEL | GFP_DMA); |
899 | if (!rp) | 900 | if (!rp) |
900 | return ERR_PTR(-ENOMEM); | 901 | return ERR_PTR(-ENOMEM); |
901 | ascebc = kmalloc(256, GFP_KERNEL); | 902 | ascebc = kmalloc(256, GFP_KERNEL); |
diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c index 0960bef7b199..15b895496a45 100644 --- a/drivers/s390/cio/blacklist.c +++ b/drivers/s390/cio/blacklist.c | |||
@@ -224,39 +224,6 @@ is_blacklisted (int ssid, int devno) | |||
224 | } | 224 | } |
225 | 225 | ||
226 | #ifdef CONFIG_PROC_FS | 226 | #ifdef CONFIG_PROC_FS |
227 | static int | ||
228 | __s390_redo_validation(struct subchannel_id schid, void *data) | ||
229 | { | ||
230 | int ret; | ||
231 | struct subchannel *sch; | ||
232 | |||
233 | sch = get_subchannel_by_schid(schid); | ||
234 | if (sch) { | ||
235 | /* Already known. */ | ||
236 | put_device(&sch->dev); | ||
237 | return 0; | ||
238 | } | ||
239 | ret = css_probe_device(schid); | ||
240 | if (ret == -ENXIO) | ||
241 | return ret; /* We're through. */ | ||
242 | if (ret == -ENOMEM) | ||
243 | /* Stop validation for now. Bad, but no need for a panic. */ | ||
244 | return ret; | ||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | /* | ||
249 | * Function: s390_redo_validation | ||
250 | * Look for no longer blacklisted devices | ||
251 | * FIXME: there must be a better way to do this */ | ||
252 | static inline void | ||
253 | s390_redo_validation (void) | ||
254 | { | ||
255 | CIO_TRACE_EVENT (0, "redoval"); | ||
256 | |||
257 | for_each_subchannel(__s390_redo_validation, NULL); | ||
258 | } | ||
259 | |||
260 | /* | 227 | /* |
261 | * Function: blacklist_parse_proc_parameters | 228 | * Function: blacklist_parse_proc_parameters |
262 | * parse the stuff which is piped to /proc/cio_ignore | 229 | * parse the stuff which is piped to /proc/cio_ignore |
@@ -281,7 +248,7 @@ blacklist_parse_proc_parameters (char *buf) | |||
281 | return; | 248 | return; |
282 | } | 249 | } |
283 | 250 | ||
284 | s390_redo_validation (); | 251 | css_schedule_reprobe(); |
285 | } | 252 | } |
286 | 253 | ||
287 | /* Iterator struct for all devices. */ | 254 | /* Iterator struct for all devices. */ |
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index bdfee7fbaa2e..c7319a07ba35 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c | |||
@@ -404,21 +404,24 @@ ccwgroup_driver_register (struct ccwgroup_driver *cdriver) | |||
404 | } | 404 | } |
405 | 405 | ||
406 | static int | 406 | static int |
407 | __ccwgroup_driver_unregister_device(struct device *dev, void *data) | 407 | __ccwgroup_match_all(struct device *dev, void *data) |
408 | { | 408 | { |
409 | __ccwgroup_remove_symlinks(to_ccwgroupdev(dev)); | 409 | return 1; |
410 | device_unregister(dev); | ||
411 | put_device(dev); | ||
412 | return 0; | ||
413 | } | 410 | } |
414 | 411 | ||
415 | void | 412 | void |
416 | ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver) | 413 | ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver) |
417 | { | 414 | { |
415 | struct device *dev; | ||
416 | |||
418 | /* We don't want ccwgroup devices to live longer than their driver. */ | 417 | /* We don't want ccwgroup devices to live longer than their driver. */ |
419 | get_driver(&cdriver->driver); | 418 | get_driver(&cdriver->driver); |
420 | driver_for_each_device(&cdriver->driver, NULL, NULL, | 419 | while ((dev = driver_find_device(&cdriver->driver, NULL, NULL, |
421 | __ccwgroup_driver_unregister_device); | 420 | __ccwgroup_match_all))) { |
421 | __ccwgroup_remove_symlinks(to_ccwgroupdev(dev)); | ||
422 | device_unregister(dev); | ||
423 | put_device(dev); | ||
424 | } | ||
422 | put_driver(&cdriver->driver); | 425 | put_driver(&cdriver->driver); |
423 | driver_unregister(&cdriver->driver); | 426 | driver_unregister(&cdriver->driver); |
424 | } | 427 | } |
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 72187e54dcac..b00f3ed051a0 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c | |||
@@ -244,8 +244,7 @@ s390_subchannel_remove_chpid(struct device *dev, void *data) | |||
244 | 244 | ||
245 | if ((sch->schib.scsw.actl & SCSW_ACTL_DEVACT) && | 245 | if ((sch->schib.scsw.actl & SCSW_ACTL_DEVACT) && |
246 | (sch->schib.scsw.actl & SCSW_ACTL_SCHACT) && | 246 | (sch->schib.scsw.actl & SCSW_ACTL_SCHACT) && |
247 | (sch->schib.pmcw.lpum == mask) && | 247 | (sch->schib.pmcw.lpum == mask)) { |
248 | (sch->vpm == 0)) { | ||
249 | int cc; | 248 | int cc; |
250 | 249 | ||
251 | cc = cio_clear(sch); | 250 | cc = cio_clear(sch); |
@@ -918,12 +917,13 @@ chp_measurement_read(struct kobject *kobj, char *buf, loff_t off, size_t count) | |||
918 | chp = to_channelpath(container_of(kobj, struct device, kobj)); | 917 | chp = to_channelpath(container_of(kobj, struct device, kobj)); |
919 | css = to_css(chp->dev.parent); | 918 | css = to_css(chp->dev.parent); |
920 | 919 | ||
921 | size = sizeof(struct cmg_chars); | 920 | size = sizeof(struct cmg_entry); |
922 | 921 | ||
923 | /* Only allow single reads. */ | 922 | /* Only allow single reads. */ |
924 | if (off || count < size) | 923 | if (off || count < size) |
925 | return 0; | 924 | return 0; |
926 | chp_measurement_copy_block((struct cmg_entry *)buf, css, chp->id); | 925 | chp_measurement_copy_block((struct cmg_entry *)buf, css, chp->id); |
926 | count = size; | ||
927 | return count; | 927 | return count; |
928 | } | 928 | } |
929 | 929 | ||
diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c index 07ef3f640f4a..1c3e8e9012b0 100644 --- a/drivers/s390/cio/cmf.c +++ b/drivers/s390/cio/cmf.c | |||
@@ -3,9 +3,10 @@ | |||
3 | * | 3 | * |
4 | * Linux on zSeries Channel Measurement Facility support | 4 | * Linux on zSeries Channel Measurement Facility support |
5 | * | 5 | * |
6 | * Copyright 2000,2003 IBM Corporation | 6 | * Copyright 2000,2006 IBM Corporation |
7 | * | 7 | * |
8 | * Author: Arnd Bergmann <arndb@de.ibm.com> | 8 | * Authors: Arnd Bergmann <arndb@de.ibm.com> |
9 | * Cornelia Huck <cornelia.huck@de.ibm.com> | ||
9 | * | 10 | * |
10 | * original idea from Natarajan Krishnaswami <nkrishna@us.ibm.com> | 11 | * original idea from Natarajan Krishnaswami <nkrishna@us.ibm.com> |
11 | * | 12 | * |
@@ -96,9 +97,9 @@ module_param(format, bool, 0444); | |||
96 | /** | 97 | /** |
97 | * struct cmb_operations - functions to use depending on cmb_format | 98 | * struct cmb_operations - functions to use depending on cmb_format |
98 | * | 99 | * |
99 | * all these functions operate on a struct cmf_device. There is only | 100 | * Most of these functions operate on a struct ccw_device. There is only |
100 | * one instance of struct cmb_operations because all cmf_device | 101 | * one instance of struct cmb_operations because the format of the measurement |
101 | * objects are guaranteed to be of the same type. | 102 | * data is guaranteed to be the same for every ccw_device. |
102 | * | 103 | * |
103 | * @alloc: allocate memory for a channel measurement block, | 104 | * @alloc: allocate memory for a channel measurement block, |
104 | * either with the help of a special pool or with kmalloc | 105 | * either with the help of a special pool or with kmalloc |
@@ -107,6 +108,7 @@ module_param(format, bool, 0444); | |||
107 | * @readall: read a measurement block in a common format | 108 | * @readall: read a measurement block in a common format |
108 | * @reset: clear the data in the associated measurement block and | 109 | * @reset: clear the data in the associated measurement block and |
109 | * reset its time stamp | 110 | * reset its time stamp |
111 | * @align: align an allocated block so that the hardware can use it | ||
110 | */ | 112 | */ |
111 | struct cmb_operations { | 113 | struct cmb_operations { |
112 | int (*alloc) (struct ccw_device*); | 114 | int (*alloc) (struct ccw_device*); |
@@ -115,11 +117,19 @@ struct cmb_operations { | |||
115 | u64 (*read) (struct ccw_device*, int); | 117 | u64 (*read) (struct ccw_device*, int); |
116 | int (*readall)(struct ccw_device*, struct cmbdata *); | 118 | int (*readall)(struct ccw_device*, struct cmbdata *); |
117 | void (*reset) (struct ccw_device*); | 119 | void (*reset) (struct ccw_device*); |
120 | void * (*align) (void *); | ||
118 | 121 | ||
119 | struct attribute_group *attr_group; | 122 | struct attribute_group *attr_group; |
120 | }; | 123 | }; |
121 | static struct cmb_operations *cmbops; | 124 | static struct cmb_operations *cmbops; |
122 | 125 | ||
126 | struct cmb_data { | ||
127 | void *hw_block; /* Pointer to block updated by hardware */ | ||
128 | void *last_block; /* Last changed block copied from hardware block */ | ||
129 | int size; /* Size of hw_block and last_block */ | ||
130 | unsigned long long last_update; /* when last_block was updated */ | ||
131 | }; | ||
132 | |||
123 | /* our user interface is designed in terms of nanoseconds, | 133 | /* our user interface is designed in terms of nanoseconds, |
124 | * while the hardware measures total times in its own | 134 | * while the hardware measures total times in its own |
125 | * unit.*/ | 135 | * unit.*/ |
@@ -226,63 +236,229 @@ struct set_schib_struct { | |||
226 | unsigned long address; | 236 | unsigned long address; |
227 | wait_queue_head_t wait; | 237 | wait_queue_head_t wait; |
228 | int ret; | 238 | int ret; |
239 | struct kref kref; | ||
229 | }; | 240 | }; |
230 | 241 | ||
242 | static void cmf_set_schib_release(struct kref *kref) | ||
243 | { | ||
244 | struct set_schib_struct *set_data; | ||
245 | |||
246 | set_data = container_of(kref, struct set_schib_struct, kref); | ||
247 | kfree(set_data); | ||
248 | } | ||
249 | |||
250 | #define CMF_PENDING 1 | ||
251 | |||
231 | static int set_schib_wait(struct ccw_device *cdev, u32 mme, | 252 | static int set_schib_wait(struct ccw_device *cdev, u32 mme, |
232 | int mbfc, unsigned long address) | 253 | int mbfc, unsigned long address) |
233 | { | 254 | { |
234 | struct set_schib_struct s = { | 255 | struct set_schib_struct *set_data; |
235 | .mme = mme, | 256 | int ret; |
236 | .mbfc = mbfc, | ||
237 | .address = address, | ||
238 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER(s.wait), | ||
239 | }; | ||
240 | 257 | ||
241 | spin_lock_irq(cdev->ccwlock); | 258 | spin_lock_irq(cdev->ccwlock); |
242 | s.ret = set_schib(cdev, mme, mbfc, address); | 259 | if (!cdev->private->cmb) { |
243 | if (s.ret != -EBUSY) { | 260 | ret = -ENODEV; |
244 | goto out_nowait; | 261 | goto out; |
245 | } | 262 | } |
263 | set_data = kzalloc(sizeof(struct set_schib_struct), GFP_ATOMIC); | ||
264 | if (!set_data) { | ||
265 | ret = -ENOMEM; | ||
266 | goto out; | ||
267 | } | ||
268 | init_waitqueue_head(&set_data->wait); | ||
269 | kref_init(&set_data->kref); | ||
270 | set_data->mme = mme; | ||
271 | set_data->mbfc = mbfc; | ||
272 | set_data->address = address; | ||
273 | |||
274 | ret = set_schib(cdev, mme, mbfc, address); | ||
275 | if (ret != -EBUSY) | ||
276 | goto out_put; | ||
246 | 277 | ||
247 | if (cdev->private->state != DEV_STATE_ONLINE) { | 278 | if (cdev->private->state != DEV_STATE_ONLINE) { |
248 | s.ret = -EBUSY; | ||
249 | /* if the device is not online, don't even try again */ | 279 | /* if the device is not online, don't even try again */ |
250 | goto out_nowait; | 280 | ret = -EBUSY; |
281 | goto out_put; | ||
251 | } | 282 | } |
283 | |||
252 | cdev->private->state = DEV_STATE_CMFCHANGE; | 284 | cdev->private->state = DEV_STATE_CMFCHANGE; |
253 | cdev->private->cmb_wait = &s; | 285 | set_data->ret = CMF_PENDING; |
254 | s.ret = 1; | 286 | cdev->private->cmb_wait = set_data; |
255 | 287 | ||
256 | spin_unlock_irq(cdev->ccwlock); | 288 | spin_unlock_irq(cdev->ccwlock); |
257 | if (wait_event_interruptible(s.wait, s.ret != 1)) { | 289 | if (wait_event_interruptible(set_data->wait, |
290 | set_data->ret != CMF_PENDING)) { | ||
258 | spin_lock_irq(cdev->ccwlock); | 291 | spin_lock_irq(cdev->ccwlock); |
259 | if (s.ret == 1) { | 292 | if (set_data->ret == CMF_PENDING) { |
260 | s.ret = -ERESTARTSYS; | 293 | set_data->ret = -ERESTARTSYS; |
261 | cdev->private->cmb_wait = 0; | ||
262 | if (cdev->private->state == DEV_STATE_CMFCHANGE) | 294 | if (cdev->private->state == DEV_STATE_CMFCHANGE) |
263 | cdev->private->state = DEV_STATE_ONLINE; | 295 | cdev->private->state = DEV_STATE_ONLINE; |
264 | } | 296 | } |
265 | spin_unlock_irq(cdev->ccwlock); | 297 | spin_unlock_irq(cdev->ccwlock); |
266 | } | 298 | } |
267 | return s.ret; | 299 | spin_lock_irq(cdev->ccwlock); |
268 | 300 | cdev->private->cmb_wait = NULL; | |
269 | out_nowait: | 301 | ret = set_data->ret; |
302 | out_put: | ||
303 | kref_put(&set_data->kref, cmf_set_schib_release); | ||
304 | out: | ||
270 | spin_unlock_irq(cdev->ccwlock); | 305 | spin_unlock_irq(cdev->ccwlock); |
271 | return s.ret; | 306 | return ret; |
272 | } | 307 | } |
273 | 308 | ||
274 | void retry_set_schib(struct ccw_device *cdev) | 309 | void retry_set_schib(struct ccw_device *cdev) |
275 | { | 310 | { |
276 | struct set_schib_struct *s; | 311 | struct set_schib_struct *set_data; |
312 | |||
313 | set_data = cdev->private->cmb_wait; | ||
314 | if (!set_data) { | ||
315 | WARN_ON(1); | ||
316 | return; | ||
317 | } | ||
318 | kref_get(&set_data->kref); | ||
319 | set_data->ret = set_schib(cdev, set_data->mme, set_data->mbfc, | ||
320 | set_data->address); | ||
321 | wake_up(&set_data->wait); | ||
322 | kref_put(&set_data->kref, cmf_set_schib_release); | ||
323 | } | ||
324 | |||
325 | static int cmf_copy_block(struct ccw_device *cdev) | ||
326 | { | ||
327 | struct subchannel *sch; | ||
328 | void *reference_buf; | ||
329 | void *hw_block; | ||
330 | struct cmb_data *cmb_data; | ||
331 | |||
332 | sch = to_subchannel(cdev->dev.parent); | ||
333 | |||
334 | if (stsch(sch->schid, &sch->schib)) | ||
335 | return -ENODEV; | ||
336 | |||
337 | if (sch->schib.scsw.fctl & SCSW_FCTL_START_FUNC) { | ||
338 | /* Don't copy if a start function is in progress. */ | ||
339 | if ((!sch->schib.scsw.actl & SCSW_ACTL_SUSPENDED) && | ||
340 | (sch->schib.scsw.actl & | ||
341 | (SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT)) && | ||
342 | (!sch->schib.scsw.stctl & SCSW_STCTL_SEC_STATUS)) | ||
343 | return -EBUSY; | ||
344 | } | ||
345 | cmb_data = cdev->private->cmb; | ||
346 | hw_block = cmbops->align(cmb_data->hw_block); | ||
347 | if (!memcmp(cmb_data->last_block, hw_block, cmb_data->size)) | ||
348 | /* No need to copy. */ | ||
349 | return 0; | ||
350 | reference_buf = kzalloc(cmb_data->size, GFP_ATOMIC); | ||
351 | if (!reference_buf) | ||
352 | return -ENOMEM; | ||
353 | /* Ensure consistency of block copied from hardware. */ | ||
354 | do { | ||
355 | memcpy(cmb_data->last_block, hw_block, cmb_data->size); | ||
356 | memcpy(reference_buf, hw_block, cmb_data->size); | ||
357 | } while (memcmp(cmb_data->last_block, reference_buf, cmb_data->size)); | ||
358 | cmb_data->last_update = get_clock(); | ||
359 | kfree(reference_buf); | ||
360 | return 0; | ||
361 | } | ||
362 | |||
363 | struct copy_block_struct { | ||
364 | wait_queue_head_t wait; | ||
365 | int ret; | ||
366 | struct kref kref; | ||
367 | }; | ||
368 | |||
369 | static void cmf_copy_block_release(struct kref *kref) | ||
370 | { | ||
371 | struct copy_block_struct *copy_block; | ||
372 | |||
373 | copy_block = container_of(kref, struct copy_block_struct, kref); | ||
374 | kfree(copy_block); | ||
375 | } | ||
376 | |||
377 | static int cmf_cmb_copy_wait(struct ccw_device *cdev) | ||
378 | { | ||
379 | struct copy_block_struct *copy_block; | ||
380 | int ret; | ||
381 | unsigned long flags; | ||
382 | |||
383 | spin_lock_irqsave(cdev->ccwlock, flags); | ||
384 | if (!cdev->private->cmb) { | ||
385 | ret = -ENODEV; | ||
386 | goto out; | ||
387 | } | ||
388 | copy_block = kzalloc(sizeof(struct copy_block_struct), GFP_ATOMIC); | ||
389 | if (!copy_block) { | ||
390 | ret = -ENOMEM; | ||
391 | goto out; | ||
392 | } | ||
393 | init_waitqueue_head(©_block->wait); | ||
394 | kref_init(©_block->kref); | ||
395 | |||
396 | ret = cmf_copy_block(cdev); | ||
397 | if (ret != -EBUSY) | ||
398 | goto out_put; | ||
399 | |||
400 | if (cdev->private->state != DEV_STATE_ONLINE) { | ||
401 | ret = -EBUSY; | ||
402 | goto out_put; | ||
403 | } | ||
404 | |||
405 | cdev->private->state = DEV_STATE_CMFUPDATE; | ||
406 | copy_block->ret = CMF_PENDING; | ||
407 | cdev->private->cmb_wait = copy_block; | ||
408 | |||
409 | spin_unlock_irqrestore(cdev->ccwlock, flags); | ||
410 | if (wait_event_interruptible(copy_block->wait, | ||
411 | copy_block->ret != CMF_PENDING)) { | ||
412 | spin_lock_irqsave(cdev->ccwlock, flags); | ||
413 | if (copy_block->ret == CMF_PENDING) { | ||
414 | copy_block->ret = -ERESTARTSYS; | ||
415 | if (cdev->private->state == DEV_STATE_CMFUPDATE) | ||
416 | cdev->private->state = DEV_STATE_ONLINE; | ||
417 | } | ||
418 | spin_unlock_irqrestore(cdev->ccwlock, flags); | ||
419 | } | ||
420 | spin_lock_irqsave(cdev->ccwlock, flags); | ||
421 | cdev->private->cmb_wait = NULL; | ||
422 | ret = copy_block->ret; | ||
423 | out_put: | ||
424 | kref_put(©_block->kref, cmf_copy_block_release); | ||
425 | out: | ||
426 | spin_unlock_irqrestore(cdev->ccwlock, flags); | ||
427 | return ret; | ||
428 | } | ||
429 | |||
430 | void cmf_retry_copy_block(struct ccw_device *cdev) | ||
431 | { | ||
432 | struct copy_block_struct *copy_block; | ||
277 | 433 | ||
278 | s = cdev->private->cmb_wait; | 434 | copy_block = cdev->private->cmb_wait; |
279 | cdev->private->cmb_wait = 0; | 435 | if (!copy_block) { |
280 | if (!s) { | ||
281 | WARN_ON(1); | 436 | WARN_ON(1); |
282 | return; | 437 | return; |
283 | } | 438 | } |
284 | s->ret = set_schib(cdev, s->mme, s->mbfc, s->address); | 439 | kref_get(©_block->kref); |
285 | wake_up(&s->wait); | 440 | copy_block->ret = cmf_copy_block(cdev); |
441 | wake_up(©_block->wait); | ||
442 | kref_put(©_block->kref, cmf_copy_block_release); | ||
443 | } | ||
444 | |||
445 | static void cmf_generic_reset(struct ccw_device *cdev) | ||
446 | { | ||
447 | struct cmb_data *cmb_data; | ||
448 | |||
449 | spin_lock_irq(cdev->ccwlock); | ||
450 | cmb_data = cdev->private->cmb; | ||
451 | if (cmb_data) { | ||
452 | memset(cmb_data->last_block, 0, cmb_data->size); | ||
453 | /* | ||
454 | * Need to reset hw block as well to make the hardware start | ||
455 | * from 0 again. | ||
456 | */ | ||
457 | memset(cmbops->align(cmb_data->hw_block), 0, cmb_data->size); | ||
458 | cmb_data->last_update = 0; | ||
459 | } | ||
460 | cdev->private->cmb_start_time = get_clock(); | ||
461 | spin_unlock_irq(cdev->ccwlock); | ||
286 | } | 462 | } |
287 | 463 | ||
288 | /** | 464 | /** |
@@ -343,8 +519,8 @@ struct cmb { | |||
343 | /* insert a single device into the cmb_area list | 519 | /* insert a single device into the cmb_area list |
344 | * called with cmb_area.lock held from alloc_cmb | 520 | * called with cmb_area.lock held from alloc_cmb |
345 | */ | 521 | */ |
346 | static inline int | 522 | static inline int alloc_cmb_single (struct ccw_device *cdev, |
347 | alloc_cmb_single (struct ccw_device *cdev) | 523 | struct cmb_data *cmb_data) |
348 | { | 524 | { |
349 | struct cmb *cmb; | 525 | struct cmb *cmb; |
350 | struct ccw_device_private *node; | 526 | struct ccw_device_private *node; |
@@ -358,10 +534,12 @@ alloc_cmb_single (struct ccw_device *cdev) | |||
358 | 534 | ||
359 | /* find first unused cmb in cmb_area.mem. | 535 | /* find first unused cmb in cmb_area.mem. |
360 | * this is a little tricky: cmb_area.list | 536 | * this is a little tricky: cmb_area.list |
361 | * remains sorted by ->cmb pointers */ | 537 | * remains sorted by ->cmb->hw_data pointers */ |
362 | cmb = cmb_area.mem; | 538 | cmb = cmb_area.mem; |
363 | list_for_each_entry(node, &cmb_area.list, cmb_list) { | 539 | list_for_each_entry(node, &cmb_area.list, cmb_list) { |
364 | if ((struct cmb*)node->cmb > cmb) | 540 | struct cmb_data *data; |
541 | data = node->cmb; | ||
542 | if ((struct cmb*)data->hw_block > cmb) | ||
365 | break; | 543 | break; |
366 | cmb++; | 544 | cmb++; |
367 | } | 545 | } |
@@ -372,7 +550,8 @@ alloc_cmb_single (struct ccw_device *cdev) | |||
372 | 550 | ||
373 | /* insert new cmb */ | 551 | /* insert new cmb */ |
374 | list_add_tail(&cdev->private->cmb_list, &node->cmb_list); | 552 | list_add_tail(&cdev->private->cmb_list, &node->cmb_list); |
375 | cdev->private->cmb = cmb; | 553 | cmb_data->hw_block = cmb; |
554 | cdev->private->cmb = cmb_data; | ||
376 | ret = 0; | 555 | ret = 0; |
377 | out: | 556 | out: |
378 | spin_unlock_irq(cdev->ccwlock); | 557 | spin_unlock_irq(cdev->ccwlock); |
@@ -385,7 +564,19 @@ alloc_cmb (struct ccw_device *cdev) | |||
385 | int ret; | 564 | int ret; |
386 | struct cmb *mem; | 565 | struct cmb *mem; |
387 | ssize_t size; | 566 | ssize_t size; |
567 | struct cmb_data *cmb_data; | ||
568 | |||
569 | /* Allocate private cmb_data. */ | ||
570 | cmb_data = kzalloc(sizeof(struct cmb_data), GFP_KERNEL); | ||
571 | if (!cmb_data) | ||
572 | return -ENOMEM; | ||
388 | 573 | ||
574 | cmb_data->last_block = kzalloc(sizeof(struct cmb), GFP_KERNEL); | ||
575 | if (!cmb_data->last_block) { | ||
576 | kfree(cmb_data); | ||
577 | return -ENOMEM; | ||
578 | } | ||
579 | cmb_data->size = sizeof(struct cmb); | ||
389 | spin_lock(&cmb_area.lock); | 580 | spin_lock(&cmb_area.lock); |
390 | 581 | ||
391 | if (!cmb_area.mem) { | 582 | if (!cmb_area.mem) { |
@@ -414,29 +605,36 @@ alloc_cmb (struct ccw_device *cdev) | |||
414 | } | 605 | } |
415 | 606 | ||
416 | /* do the actual allocation */ | 607 | /* do the actual allocation */ |
417 | ret = alloc_cmb_single(cdev); | 608 | ret = alloc_cmb_single(cdev, cmb_data); |
418 | out: | 609 | out: |
419 | spin_unlock(&cmb_area.lock); | 610 | spin_unlock(&cmb_area.lock); |
420 | 611 | if (ret) { | |
612 | kfree(cmb_data->last_block); | ||
613 | kfree(cmb_data); | ||
614 | } | ||
421 | return ret; | 615 | return ret; |
422 | } | 616 | } |
423 | 617 | ||
424 | static void | 618 | static void free_cmb(struct ccw_device *cdev) |
425 | free_cmb(struct ccw_device *cdev) | ||
426 | { | 619 | { |
427 | struct ccw_device_private *priv; | 620 | struct ccw_device_private *priv; |
428 | 621 | struct cmb_data *cmb_data; | |
429 | priv = cdev->private; | ||
430 | 622 | ||
431 | spin_lock(&cmb_area.lock); | 623 | spin_lock(&cmb_area.lock); |
432 | spin_lock_irq(cdev->ccwlock); | 624 | spin_lock_irq(cdev->ccwlock); |
433 | 625 | ||
626 | priv = cdev->private; | ||
627 | |||
434 | if (list_empty(&priv->cmb_list)) { | 628 | if (list_empty(&priv->cmb_list)) { |
435 | /* already freed */ | 629 | /* already freed */ |
436 | goto out; | 630 | goto out; |
437 | } | 631 | } |
438 | 632 | ||
633 | cmb_data = priv->cmb; | ||
439 | priv->cmb = NULL; | 634 | priv->cmb = NULL; |
635 | if (cmb_data) | ||
636 | kfree(cmb_data->last_block); | ||
637 | kfree(cmb_data); | ||
440 | list_del_init(&priv->cmb_list); | 638 | list_del_init(&priv->cmb_list); |
441 | 639 | ||
442 | if (list_empty(&cmb_area.list)) { | 640 | if (list_empty(&cmb_area.list)) { |
@@ -451,83 +649,97 @@ out: | |||
451 | spin_unlock(&cmb_area.lock); | 649 | spin_unlock(&cmb_area.lock); |
452 | } | 650 | } |
453 | 651 | ||
454 | static int | 652 | static int set_cmb(struct ccw_device *cdev, u32 mme) |
455 | set_cmb(struct ccw_device *cdev, u32 mme) | ||
456 | { | 653 | { |
457 | u16 offset; | 654 | u16 offset; |
655 | struct cmb_data *cmb_data; | ||
656 | unsigned long flags; | ||
458 | 657 | ||
459 | if (!cdev->private->cmb) | 658 | spin_lock_irqsave(cdev->ccwlock, flags); |
659 | if (!cdev->private->cmb) { | ||
660 | spin_unlock_irqrestore(cdev->ccwlock, flags); | ||
460 | return -EINVAL; | 661 | return -EINVAL; |
461 | 662 | } | |
462 | offset = mme ? (struct cmb *)cdev->private->cmb - cmb_area.mem : 0; | 663 | cmb_data = cdev->private->cmb; |
664 | offset = mme ? (struct cmb *)cmb_data->hw_block - cmb_area.mem : 0; | ||
665 | spin_unlock_irqrestore(cdev->ccwlock, flags); | ||
463 | 666 | ||
464 | return set_schib_wait(cdev, mme, 0, offset); | 667 | return set_schib_wait(cdev, mme, 0, offset); |
465 | } | 668 | } |
466 | 669 | ||
467 | static u64 | 670 | static u64 read_cmb (struct ccw_device *cdev, int index) |
468 | read_cmb (struct ccw_device *cdev, int index) | ||
469 | { | 671 | { |
470 | /* yes, we have to put it on the stack | 672 | struct cmb *cmb; |
471 | * because the cmb must only be accessed | ||
472 | * atomically, e.g. with mvc */ | ||
473 | struct cmb cmb; | ||
474 | unsigned long flags; | ||
475 | u32 val; | 673 | u32 val; |
674 | int ret; | ||
675 | unsigned long flags; | ||
676 | |||
677 | ret = cmf_cmb_copy_wait(cdev); | ||
678 | if (ret < 0) | ||
679 | return 0; | ||
476 | 680 | ||
477 | spin_lock_irqsave(cdev->ccwlock, flags); | 681 | spin_lock_irqsave(cdev->ccwlock, flags); |
478 | if (!cdev->private->cmb) { | 682 | if (!cdev->private->cmb) { |
479 | spin_unlock_irqrestore(cdev->ccwlock, flags); | 683 | ret = 0; |
480 | return 0; | 684 | goto out; |
481 | } | 685 | } |
482 | 686 | cmb = ((struct cmb_data *)cdev->private->cmb)->last_block; | |
483 | cmb = *(struct cmb*)cdev->private->cmb; | ||
484 | spin_unlock_irqrestore(cdev->ccwlock, flags); | ||
485 | 687 | ||
486 | switch (index) { | 688 | switch (index) { |
487 | case cmb_ssch_rsch_count: | 689 | case cmb_ssch_rsch_count: |
488 | return cmb.ssch_rsch_count; | 690 | ret = cmb->ssch_rsch_count; |
691 | goto out; | ||
489 | case cmb_sample_count: | 692 | case cmb_sample_count: |
490 | return cmb.sample_count; | 693 | ret = cmb->sample_count; |
694 | goto out; | ||
491 | case cmb_device_connect_time: | 695 | case cmb_device_connect_time: |
492 | val = cmb.device_connect_time; | 696 | val = cmb->device_connect_time; |
493 | break; | 697 | break; |
494 | case cmb_function_pending_time: | 698 | case cmb_function_pending_time: |
495 | val = cmb.function_pending_time; | 699 | val = cmb->function_pending_time; |
496 | break; | 700 | break; |
497 | case cmb_device_disconnect_time: | 701 | case cmb_device_disconnect_time: |
498 | val = cmb.device_disconnect_time; | 702 | val = cmb->device_disconnect_time; |
499 | break; | 703 | break; |
500 | case cmb_control_unit_queuing_time: | 704 | case cmb_control_unit_queuing_time: |
501 | val = cmb.control_unit_queuing_time; | 705 | val = cmb->control_unit_queuing_time; |
502 | break; | 706 | break; |
503 | case cmb_device_active_only_time: | 707 | case cmb_device_active_only_time: |
504 | val = cmb.device_active_only_time; | 708 | val = cmb->device_active_only_time; |
505 | break; | 709 | break; |
506 | default: | 710 | default: |
507 | return 0; | 711 | ret = 0; |
712 | goto out; | ||
508 | } | 713 | } |
509 | return time_to_avg_nsec(val, cmb.sample_count); | 714 | ret = time_to_avg_nsec(val, cmb->sample_count); |
715 | out: | ||
716 | spin_unlock_irqrestore(cdev->ccwlock, flags); | ||
717 | return ret; | ||
510 | } | 718 | } |
511 | 719 | ||
512 | static int | 720 | static int readall_cmb (struct ccw_device *cdev, struct cmbdata *data) |
513 | readall_cmb (struct ccw_device *cdev, struct cmbdata *data) | ||
514 | { | 721 | { |
515 | /* yes, we have to put it on the stack | 722 | struct cmb *cmb; |
516 | * because the cmb must only be accessed | 723 | struct cmb_data *cmb_data; |
517 | * atomically, e.g. with mvc */ | ||
518 | struct cmb cmb; | ||
519 | unsigned long flags; | ||
520 | u64 time; | 724 | u64 time; |
725 | unsigned long flags; | ||
726 | int ret; | ||
521 | 727 | ||
728 | ret = cmf_cmb_copy_wait(cdev); | ||
729 | if (ret < 0) | ||
730 | return ret; | ||
522 | spin_lock_irqsave(cdev->ccwlock, flags); | 731 | spin_lock_irqsave(cdev->ccwlock, flags); |
523 | if (!cdev->private->cmb) { | 732 | cmb_data = cdev->private->cmb; |
524 | spin_unlock_irqrestore(cdev->ccwlock, flags); | 733 | if (!cmb_data) { |
525 | return -ENODEV; | 734 | ret = -ENODEV; |
735 | goto out; | ||
526 | } | 736 | } |
527 | 737 | if (cmb_data->last_update == 0) { | |
528 | cmb = *(struct cmb*)cdev->private->cmb; | 738 | ret = -EAGAIN; |
529 | time = get_clock() - cdev->private->cmb_start_time; | 739 | goto out; |
530 | spin_unlock_irqrestore(cdev->ccwlock, flags); | 740 | } |
741 | cmb = cmb_data->last_block; | ||
742 | time = cmb_data->last_update - cdev->private->cmb_start_time; | ||
531 | 743 | ||
532 | memset(data, 0, sizeof(struct cmbdata)); | 744 | memset(data, 0, sizeof(struct cmbdata)); |
533 | 745 | ||
@@ -538,31 +750,32 @@ readall_cmb (struct ccw_device *cdev, struct cmbdata *data) | |||
538 | data->elapsed_time = (time * 1000) >> 12; | 750 | data->elapsed_time = (time * 1000) >> 12; |
539 | 751 | ||
540 | /* copy data to new structure */ | 752 | /* copy data to new structure */ |
541 | data->ssch_rsch_count = cmb.ssch_rsch_count; | 753 | data->ssch_rsch_count = cmb->ssch_rsch_count; |
542 | data->sample_count = cmb.sample_count; | 754 | data->sample_count = cmb->sample_count; |
543 | 755 | ||
544 | /* time fields are converted to nanoseconds while copying */ | 756 | /* time fields are converted to nanoseconds while copying */ |
545 | data->device_connect_time = time_to_nsec(cmb.device_connect_time); | 757 | data->device_connect_time = time_to_nsec(cmb->device_connect_time); |
546 | data->function_pending_time = time_to_nsec(cmb.function_pending_time); | 758 | data->function_pending_time = time_to_nsec(cmb->function_pending_time); |
547 | data->device_disconnect_time = time_to_nsec(cmb.device_disconnect_time); | 759 | data->device_disconnect_time = |
760 | time_to_nsec(cmb->device_disconnect_time); | ||
548 | data->control_unit_queuing_time | 761 | data->control_unit_queuing_time |
549 | = time_to_nsec(cmb.control_unit_queuing_time); | 762 | = time_to_nsec(cmb->control_unit_queuing_time); |
550 | data->device_active_only_time | 763 | data->device_active_only_time |
551 | = time_to_nsec(cmb.device_active_only_time); | 764 | = time_to_nsec(cmb->device_active_only_time); |
765 | ret = 0; | ||
766 | out: | ||
767 | spin_unlock_irqrestore(cdev->ccwlock, flags); | ||
768 | return ret; | ||
769 | } | ||
552 | 770 | ||
553 | return 0; | 771 | static void reset_cmb(struct ccw_device *cdev) |
772 | { | ||
773 | cmf_generic_reset(cdev); | ||
554 | } | 774 | } |
555 | 775 | ||
556 | static void | 776 | static void * align_cmb(void *area) |
557 | reset_cmb(struct ccw_device *cdev) | ||
558 | { | 777 | { |
559 | struct cmb *cmb; | 778 | return area; |
560 | spin_lock_irq(cdev->ccwlock); | ||
561 | cmb = cdev->private->cmb; | ||
562 | if (cmb) | ||
563 | memset (cmb, 0, sizeof (*cmb)); | ||
564 | cdev->private->cmb_start_time = get_clock(); | ||
565 | spin_unlock_irq(cdev->ccwlock); | ||
566 | } | 779 | } |
567 | 780 | ||
568 | static struct attribute_group cmf_attr_group; | 781 | static struct attribute_group cmf_attr_group; |
@@ -574,6 +787,7 @@ static struct cmb_operations cmbops_basic = { | |||
574 | .read = read_cmb, | 787 | .read = read_cmb, |
575 | .readall = readall_cmb, | 788 | .readall = readall_cmb, |
576 | .reset = reset_cmb, | 789 | .reset = reset_cmb, |
790 | .align = align_cmb, | ||
577 | .attr_group = &cmf_attr_group, | 791 | .attr_group = &cmf_attr_group, |
578 | }; | 792 | }; |
579 | 793 | ||
@@ -610,22 +824,34 @@ static inline struct cmbe* cmbe_align(struct cmbe *c) | |||
610 | return (struct cmbe*)addr; | 824 | return (struct cmbe*)addr; |
611 | } | 825 | } |
612 | 826 | ||
613 | static int | 827 | static int alloc_cmbe (struct ccw_device *cdev) |
614 | alloc_cmbe (struct ccw_device *cdev) | ||
615 | { | 828 | { |
616 | struct cmbe *cmbe; | 829 | struct cmbe *cmbe; |
617 | cmbe = kmalloc (sizeof (*cmbe) * 2, GFP_KERNEL); | 830 | struct cmb_data *cmb_data; |
831 | int ret; | ||
832 | |||
833 | cmbe = kzalloc (sizeof (*cmbe) * 2, GFP_KERNEL); | ||
618 | if (!cmbe) | 834 | if (!cmbe) |
619 | return -ENOMEM; | 835 | return -ENOMEM; |
620 | 836 | cmb_data = kzalloc(sizeof(struct cmb_data), GFP_KERNEL); | |
837 | if (!cmb_data) { | ||
838 | ret = -ENOMEM; | ||
839 | goto out_free; | ||
840 | } | ||
841 | cmb_data->last_block = kzalloc(sizeof(struct cmbe), GFP_KERNEL); | ||
842 | if (!cmb_data->last_block) { | ||
843 | ret = -ENOMEM; | ||
844 | goto out_free; | ||
845 | } | ||
846 | cmb_data->size = sizeof(struct cmbe); | ||
621 | spin_lock_irq(cdev->ccwlock); | 847 | spin_lock_irq(cdev->ccwlock); |
622 | if (cdev->private->cmb) { | 848 | if (cdev->private->cmb) { |
623 | kfree(cmbe); | ||
624 | spin_unlock_irq(cdev->ccwlock); | 849 | spin_unlock_irq(cdev->ccwlock); |
625 | return -EBUSY; | 850 | ret = -EBUSY; |
851 | goto out_free; | ||
626 | } | 852 | } |
627 | 853 | cmb_data->hw_block = cmbe; | |
628 | cdev->private->cmb = cmbe; | 854 | cdev->private->cmb = cmb_data; |
629 | spin_unlock_irq(cdev->ccwlock); | 855 | spin_unlock_irq(cdev->ccwlock); |
630 | 856 | ||
631 | /* activate global measurement if this is the first channel */ | 857 | /* activate global measurement if this is the first channel */ |
@@ -636,14 +862,24 @@ alloc_cmbe (struct ccw_device *cdev) | |||
636 | spin_unlock(&cmb_area.lock); | 862 | spin_unlock(&cmb_area.lock); |
637 | 863 | ||
638 | return 0; | 864 | return 0; |
865 | out_free: | ||
866 | if (cmb_data) | ||
867 | kfree(cmb_data->last_block); | ||
868 | kfree(cmb_data); | ||
869 | kfree(cmbe); | ||
870 | return ret; | ||
639 | } | 871 | } |
640 | 872 | ||
641 | static void | 873 | static void free_cmbe (struct ccw_device *cdev) |
642 | free_cmbe (struct ccw_device *cdev) | ||
643 | { | 874 | { |
875 | struct cmb_data *cmb_data; | ||
876 | |||
644 | spin_lock_irq(cdev->ccwlock); | 877 | spin_lock_irq(cdev->ccwlock); |
645 | kfree(cdev->private->cmb); | 878 | cmb_data = cdev->private->cmb; |
646 | cdev->private->cmb = NULL; | 879 | cdev->private->cmb = NULL; |
880 | if (cmb_data) | ||
881 | kfree(cmb_data->last_block); | ||
882 | kfree(cmb_data); | ||
647 | spin_unlock_irq(cdev->ccwlock); | 883 | spin_unlock_irq(cdev->ccwlock); |
648 | 884 | ||
649 | /* deactivate global measurement if this is the last channel */ | 885 | /* deactivate global measurement if this is the last channel */ |
@@ -654,89 +890,105 @@ free_cmbe (struct ccw_device *cdev) | |||
654 | spin_unlock(&cmb_area.lock); | 890 | spin_unlock(&cmb_area.lock); |
655 | } | 891 | } |
656 | 892 | ||
657 | static int | 893 | static int set_cmbe(struct ccw_device *cdev, u32 mme) |
658 | set_cmbe(struct ccw_device *cdev, u32 mme) | ||
659 | { | 894 | { |
660 | unsigned long mba; | 895 | unsigned long mba; |
896 | struct cmb_data *cmb_data; | ||
897 | unsigned long flags; | ||
661 | 898 | ||
662 | if (!cdev->private->cmb) | 899 | spin_lock_irqsave(cdev->ccwlock, flags); |
900 | if (!cdev->private->cmb) { | ||
901 | spin_unlock_irqrestore(cdev->ccwlock, flags); | ||
663 | return -EINVAL; | 902 | return -EINVAL; |
664 | mba = mme ? (unsigned long) cmbe_align(cdev->private->cmb) : 0; | 903 | } |
904 | cmb_data = cdev->private->cmb; | ||
905 | mba = mme ? (unsigned long) cmbe_align(cmb_data->hw_block) : 0; | ||
906 | spin_unlock_irqrestore(cdev->ccwlock, flags); | ||
665 | 907 | ||
666 | return set_schib_wait(cdev, mme, 1, mba); | 908 | return set_schib_wait(cdev, mme, 1, mba); |
667 | } | 909 | } |
668 | 910 | ||
669 | 911 | ||
670 | u64 | 912 | static u64 read_cmbe (struct ccw_device *cdev, int index) |
671 | read_cmbe (struct ccw_device *cdev, int index) | ||
672 | { | 913 | { |
673 | /* yes, we have to put it on the stack | 914 | struct cmbe *cmb; |
674 | * because the cmb must only be accessed | 915 | struct cmb_data *cmb_data; |
675 | * atomically, e.g. with mvc */ | ||
676 | struct cmbe cmb; | ||
677 | unsigned long flags; | ||
678 | u32 val; | 916 | u32 val; |
917 | int ret; | ||
918 | unsigned long flags; | ||
679 | 919 | ||
680 | spin_lock_irqsave(cdev->ccwlock, flags); | 920 | ret = cmf_cmb_copy_wait(cdev); |
681 | if (!cdev->private->cmb) { | 921 | if (ret < 0) |
682 | spin_unlock_irqrestore(cdev->ccwlock, flags); | ||
683 | return 0; | 922 | return 0; |
684 | } | ||
685 | 923 | ||
686 | cmb = *cmbe_align(cdev->private->cmb); | 924 | spin_lock_irqsave(cdev->ccwlock, flags); |
687 | spin_unlock_irqrestore(cdev->ccwlock, flags); | 925 | cmb_data = cdev->private->cmb; |
926 | if (!cmb_data) { | ||
927 | ret = 0; | ||
928 | goto out; | ||
929 | } | ||
930 | cmb = cmb_data->last_block; | ||
688 | 931 | ||
689 | switch (index) { | 932 | switch (index) { |
690 | case cmb_ssch_rsch_count: | 933 | case cmb_ssch_rsch_count: |
691 | return cmb.ssch_rsch_count; | 934 | ret = cmb->ssch_rsch_count; |
935 | goto out; | ||
692 | case cmb_sample_count: | 936 | case cmb_sample_count: |
693 | return cmb.sample_count; | 937 | ret = cmb->sample_count; |
938 | goto out; | ||
694 | case cmb_device_connect_time: | 939 | case cmb_device_connect_time: |
695 | val = cmb.device_connect_time; | 940 | val = cmb->device_connect_time; |
696 | break; | 941 | break; |
697 | case cmb_function_pending_time: | 942 | case cmb_function_pending_time: |
698 | val = cmb.function_pending_time; | 943 | val = cmb->function_pending_time; |
699 | break; | 944 | break; |
700 | case cmb_device_disconnect_time: | 945 | case cmb_device_disconnect_time: |
701 | val = cmb.device_disconnect_time; | 946 | val = cmb->device_disconnect_time; |
702 | break; | 947 | break; |
703 | case cmb_control_unit_queuing_time: | 948 | case cmb_control_unit_queuing_time: |
704 | val = cmb.control_unit_queuing_time; | 949 | val = cmb->control_unit_queuing_time; |
705 | break; | 950 | break; |
706 | case cmb_device_active_only_time: | 951 | case cmb_device_active_only_time: |
707 | val = cmb.device_active_only_time; | 952 | val = cmb->device_active_only_time; |
708 | break; | 953 | break; |
709 | case cmb_device_busy_time: | 954 | case cmb_device_busy_time: |
710 | val = cmb.device_busy_time; | 955 | val = cmb->device_busy_time; |
711 | break; | 956 | break; |
712 | case cmb_initial_command_response_time: | 957 | case cmb_initial_command_response_time: |
713 | val = cmb.initial_command_response_time; | 958 | val = cmb->initial_command_response_time; |
714 | break; | 959 | break; |
715 | default: | 960 | default: |
716 | return 0; | 961 | ret = 0; |
962 | goto out; | ||
717 | } | 963 | } |
718 | return time_to_avg_nsec(val, cmb.sample_count); | 964 | ret = time_to_avg_nsec(val, cmb->sample_count); |
965 | out: | ||
966 | spin_unlock_irqrestore(cdev->ccwlock, flags); | ||
967 | return ret; | ||
719 | } | 968 | } |
720 | 969 | ||
721 | static int | 970 | static int readall_cmbe (struct ccw_device *cdev, struct cmbdata *data) |
722 | readall_cmbe (struct ccw_device *cdev, struct cmbdata *data) | ||
723 | { | 971 | { |
724 | /* yes, we have to put it on the stack | 972 | struct cmbe *cmb; |
725 | * because the cmb must only be accessed | 973 | struct cmb_data *cmb_data; |
726 | * atomically, e.g. with mvc */ | ||
727 | struct cmbe cmb; | ||
728 | unsigned long flags; | ||
729 | u64 time; | 974 | u64 time; |
975 | unsigned long flags; | ||
976 | int ret; | ||
730 | 977 | ||
978 | ret = cmf_cmb_copy_wait(cdev); | ||
979 | if (ret < 0) | ||
980 | return ret; | ||
731 | spin_lock_irqsave(cdev->ccwlock, flags); | 981 | spin_lock_irqsave(cdev->ccwlock, flags); |
732 | if (!cdev->private->cmb) { | 982 | cmb_data = cdev->private->cmb; |
733 | spin_unlock_irqrestore(cdev->ccwlock, flags); | 983 | if (!cmb_data) { |
734 | return -ENODEV; | 984 | ret = -ENODEV; |
985 | goto out; | ||
735 | } | 986 | } |
736 | 987 | if (cmb_data->last_update == 0) { | |
737 | cmb = *cmbe_align(cdev->private->cmb); | 988 | ret = -EAGAIN; |
738 | time = get_clock() - cdev->private->cmb_start_time; | 989 | goto out; |
739 | spin_unlock_irqrestore(cdev->ccwlock, flags); | 990 | } |
991 | time = cmb_data->last_update - cdev->private->cmb_start_time; | ||
740 | 992 | ||
741 | memset (data, 0, sizeof(struct cmbdata)); | 993 | memset (data, 0, sizeof(struct cmbdata)); |
742 | 994 | ||
@@ -746,35 +998,38 @@ readall_cmbe (struct ccw_device *cdev, struct cmbdata *data) | |||
746 | /* conver to nanoseconds */ | 998 | /* conver to nanoseconds */ |
747 | data->elapsed_time = (time * 1000) >> 12; | 999 | data->elapsed_time = (time * 1000) >> 12; |
748 | 1000 | ||
1001 | cmb = cmb_data->last_block; | ||
749 | /* copy data to new structure */ | 1002 | /* copy data to new structure */ |
750 | data->ssch_rsch_count = cmb.ssch_rsch_count; | 1003 | data->ssch_rsch_count = cmb->ssch_rsch_count; |
751 | data->sample_count = cmb.sample_count; | 1004 | data->sample_count = cmb->sample_count; |
752 | 1005 | ||
753 | /* time fields are converted to nanoseconds while copying */ | 1006 | /* time fields are converted to nanoseconds while copying */ |
754 | data->device_connect_time = time_to_nsec(cmb.device_connect_time); | 1007 | data->device_connect_time = time_to_nsec(cmb->device_connect_time); |
755 | data->function_pending_time = time_to_nsec(cmb.function_pending_time); | 1008 | data->function_pending_time = time_to_nsec(cmb->function_pending_time); |
756 | data->device_disconnect_time = time_to_nsec(cmb.device_disconnect_time); | 1009 | data->device_disconnect_time = |
1010 | time_to_nsec(cmb->device_disconnect_time); | ||
757 | data->control_unit_queuing_time | 1011 | data->control_unit_queuing_time |
758 | = time_to_nsec(cmb.control_unit_queuing_time); | 1012 | = time_to_nsec(cmb->control_unit_queuing_time); |
759 | data->device_active_only_time | 1013 | data->device_active_only_time |
760 | = time_to_nsec(cmb.device_active_only_time); | 1014 | = time_to_nsec(cmb->device_active_only_time); |
761 | data->device_busy_time = time_to_nsec(cmb.device_busy_time); | 1015 | data->device_busy_time = time_to_nsec(cmb->device_busy_time); |
762 | data->initial_command_response_time | 1016 | data->initial_command_response_time |
763 | = time_to_nsec(cmb.initial_command_response_time); | 1017 | = time_to_nsec(cmb->initial_command_response_time); |
764 | 1018 | ||
765 | return 0; | 1019 | ret = 0; |
1020 | out: | ||
1021 | spin_unlock_irqrestore(cdev->ccwlock, flags); | ||
1022 | return ret; | ||
766 | } | 1023 | } |
767 | 1024 | ||
768 | static void | 1025 | static void reset_cmbe(struct ccw_device *cdev) |
769 | reset_cmbe(struct ccw_device *cdev) | ||
770 | { | 1026 | { |
771 | struct cmbe *cmb; | 1027 | cmf_generic_reset(cdev); |
772 | spin_lock_irq(cdev->ccwlock); | 1028 | } |
773 | cmb = cmbe_align(cdev->private->cmb); | 1029 | |
774 | if (cmb) | 1030 | static void * align_cmbe(void *area) |
775 | memset (cmb, 0, sizeof (*cmb)); | 1031 | { |
776 | cdev->private->cmb_start_time = get_clock(); | 1032 | return cmbe_align(area); |
777 | spin_unlock_irq(cdev->ccwlock); | ||
778 | } | 1033 | } |
779 | 1034 | ||
780 | static struct attribute_group cmf_attr_group_ext; | 1035 | static struct attribute_group cmf_attr_group_ext; |
@@ -786,6 +1041,7 @@ static struct cmb_operations cmbops_extended = { | |||
786 | .read = read_cmbe, | 1041 | .read = read_cmbe, |
787 | .readall = readall_cmbe, | 1042 | .readall = readall_cmbe, |
788 | .reset = reset_cmbe, | 1043 | .reset = reset_cmbe, |
1044 | .align = align_cmbe, | ||
789 | .attr_group = &cmf_attr_group_ext, | 1045 | .attr_group = &cmf_attr_group_ext, |
790 | }; | 1046 | }; |
791 | 1047 | ||
@@ -803,14 +1059,19 @@ cmb_show_avg_sample_interval(struct device *dev, struct device_attribute *attr, | |||
803 | struct ccw_device *cdev; | 1059 | struct ccw_device *cdev; |
804 | long interval; | 1060 | long interval; |
805 | unsigned long count; | 1061 | unsigned long count; |
1062 | struct cmb_data *cmb_data; | ||
806 | 1063 | ||
807 | cdev = to_ccwdev(dev); | 1064 | cdev = to_ccwdev(dev); |
808 | interval = get_clock() - cdev->private->cmb_start_time; | ||
809 | count = cmf_read(cdev, cmb_sample_count); | 1065 | count = cmf_read(cdev, cmb_sample_count); |
810 | if (count) | 1066 | spin_lock_irq(cdev->ccwlock); |
1067 | cmb_data = cdev->private->cmb; | ||
1068 | if (count) { | ||
1069 | interval = cmb_data->last_update - | ||
1070 | cdev->private->cmb_start_time; | ||
811 | interval /= count; | 1071 | interval /= count; |
812 | else | 1072 | } else |
813 | interval = -1; | 1073 | interval = -1; |
1074 | spin_unlock_irq(cdev->ccwlock); | ||
814 | return sprintf(buf, "%ld\n", interval); | 1075 | return sprintf(buf, "%ld\n", interval); |
815 | } | 1076 | } |
816 | 1077 | ||
@@ -823,7 +1084,10 @@ cmb_show_avg_utilization(struct device *dev, struct device_attribute *attr, char | |||
823 | int ret; | 1084 | int ret; |
824 | 1085 | ||
825 | ret = cmf_readall(to_ccwdev(dev), &data); | 1086 | ret = cmf_readall(to_ccwdev(dev), &data); |
826 | if (ret) | 1087 | if (ret == -EAGAIN || ret == -ENODEV) |
1088 | /* No data (yet/currently) available to use for calculation. */ | ||
1089 | return sprintf(buf, "n/a\n"); | ||
1090 | else if (ret) | ||
827 | return ret; | 1091 | return ret; |
828 | 1092 | ||
829 | utilization = data.device_connect_time + | 1093 | utilization = data.device_connect_time + |
@@ -982,6 +1246,13 @@ cmf_readall(struct ccw_device *cdev, struct cmbdata *data) | |||
982 | return cmbops->readall(cdev, data); | 1246 | return cmbops->readall(cdev, data); |
983 | } | 1247 | } |
984 | 1248 | ||
1249 | /* Reenable cmf when a disconnected device becomes available again. */ | ||
1250 | int cmf_reenable(struct ccw_device *cdev) | ||
1251 | { | ||
1252 | cmbops->reset(cdev); | ||
1253 | return cmbops->set(cdev, 2); | ||
1254 | } | ||
1255 | |||
985 | static int __init | 1256 | static int __init |
986 | init_cmf(void) | 1257 | init_cmf(void) |
987 | { | 1258 | { |
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 74ea8aac4b7d..1d3be80797f8 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c | |||
@@ -19,9 +19,11 @@ | |||
19 | #include "cio_debug.h" | 19 | #include "cio_debug.h" |
20 | #include "ioasm.h" | 20 | #include "ioasm.h" |
21 | #include "chsc.h" | 21 | #include "chsc.h" |
22 | #include "device.h" | ||
22 | 23 | ||
23 | int need_rescan = 0; | 24 | int need_rescan = 0; |
24 | int css_init_done = 0; | 25 | int css_init_done = 0; |
26 | static int need_reprobe = 0; | ||
25 | static int max_ssid = 0; | 27 | static int max_ssid = 0; |
26 | 28 | ||
27 | struct channel_subsystem *css[__MAX_CSSID + 1]; | 29 | struct channel_subsystem *css[__MAX_CSSID + 1]; |
@@ -339,6 +341,67 @@ typedef void (*workfunc)(void *); | |||
339 | DECLARE_WORK(slow_path_work, (workfunc)css_trigger_slow_path, NULL); | 341 | DECLARE_WORK(slow_path_work, (workfunc)css_trigger_slow_path, NULL); |
340 | struct workqueue_struct *slow_path_wq; | 342 | struct workqueue_struct *slow_path_wq; |
341 | 343 | ||
344 | /* Reprobe subchannel if unregistered. */ | ||
345 | static int reprobe_subchannel(struct subchannel_id schid, void *data) | ||
346 | { | ||
347 | struct subchannel *sch; | ||
348 | int ret; | ||
349 | |||
350 | CIO_DEBUG(KERN_INFO, 6, "cio: reprobe 0.%x.%04x\n", | ||
351 | schid.ssid, schid.sch_no); | ||
352 | if (need_reprobe) | ||
353 | return -EAGAIN; | ||
354 | |||
355 | sch = get_subchannel_by_schid(schid); | ||
356 | if (sch) { | ||
357 | /* Already known. */ | ||
358 | put_device(&sch->dev); | ||
359 | return 0; | ||
360 | } | ||
361 | |||
362 | ret = css_probe_device(schid); | ||
363 | switch (ret) { | ||
364 | case 0: | ||
365 | break; | ||
366 | case -ENXIO: | ||
367 | case -ENOMEM: | ||
368 | /* These should abort looping */ | ||
369 | break; | ||
370 | default: | ||
371 | ret = 0; | ||
372 | } | ||
373 | |||
374 | return ret; | ||
375 | } | ||
376 | |||
377 | /* Work function used to reprobe all unregistered subchannels. */ | ||
378 | static void reprobe_all(void *data) | ||
379 | { | ||
380 | int ret; | ||
381 | |||
382 | CIO_MSG_EVENT(2, "reprobe start\n"); | ||
383 | |||
384 | need_reprobe = 0; | ||
385 | /* Make sure initial subchannel scan is done. */ | ||
386 | wait_event(ccw_device_init_wq, | ||
387 | atomic_read(&ccw_device_init_count) == 0); | ||
388 | ret = for_each_subchannel(reprobe_subchannel, NULL); | ||
389 | |||
390 | CIO_MSG_EVENT(2, "reprobe done (rc=%d, need_reprobe=%d)\n", ret, | ||
391 | need_reprobe); | ||
392 | } | ||
393 | |||
394 | DECLARE_WORK(css_reprobe_work, reprobe_all, NULL); | ||
395 | |||
396 | /* Schedule reprobing of all unregistered subchannels. */ | ||
397 | void css_schedule_reprobe(void) | ||
398 | { | ||
399 | need_reprobe = 1; | ||
400 | queue_work(ccw_device_work, &css_reprobe_work); | ||
401 | } | ||
402 | |||
403 | EXPORT_SYMBOL_GPL(css_schedule_reprobe); | ||
404 | |||
342 | /* | 405 | /* |
343 | * Rescan for new devices. FIXME: This is slow. | 406 | * Rescan for new devices. FIXME: This is slow. |
344 | * This function is called when we have lost CRWs due to overflows and we have | 407 | * This function is called when we have lost CRWs due to overflows and we have |
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 8e3053c2a451..eafde43e8410 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
@@ -133,8 +133,8 @@ struct css_driver io_subchannel_driver = { | |||
133 | 133 | ||
134 | struct workqueue_struct *ccw_device_work; | 134 | struct workqueue_struct *ccw_device_work; |
135 | struct workqueue_struct *ccw_device_notify_work; | 135 | struct workqueue_struct *ccw_device_notify_work; |
136 | static wait_queue_head_t ccw_device_init_wq; | 136 | wait_queue_head_t ccw_device_init_wq; |
137 | static atomic_t ccw_device_init_count; | 137 | atomic_t ccw_device_init_count; |
138 | 138 | ||
139 | static int __init | 139 | static int __init |
140 | init_ccw_bus_type (void) | 140 | init_ccw_bus_type (void) |
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h index 11587ebb7289..00be9a5b4acd 100644 --- a/drivers/s390/cio/device.h +++ b/drivers/s390/cio/device.h | |||
@@ -1,6 +1,10 @@ | |||
1 | #ifndef S390_DEVICE_H | 1 | #ifndef S390_DEVICE_H |
2 | #define S390_DEVICE_H | 2 | #define S390_DEVICE_H |
3 | 3 | ||
4 | #include <asm/ccwdev.h> | ||
5 | #include <asm/atomic.h> | ||
6 | #include <linux/wait.h> | ||
7 | |||
4 | /* | 8 | /* |
5 | * states of the device statemachine | 9 | * states of the device statemachine |
6 | */ | 10 | */ |
@@ -23,6 +27,7 @@ enum dev_state { | |||
23 | DEV_STATE_DISCONNECTED, | 27 | DEV_STATE_DISCONNECTED, |
24 | DEV_STATE_DISCONNECTED_SENSE_ID, | 28 | DEV_STATE_DISCONNECTED_SENSE_ID, |
25 | DEV_STATE_CMFCHANGE, | 29 | DEV_STATE_CMFCHANGE, |
30 | DEV_STATE_CMFUPDATE, | ||
26 | /* last element! */ | 31 | /* last element! */ |
27 | NR_DEV_STATES | 32 | NR_DEV_STATES |
28 | }; | 33 | }; |
@@ -67,6 +72,8 @@ dev_fsm_final_state(struct ccw_device *cdev) | |||
67 | 72 | ||
68 | extern struct workqueue_struct *ccw_device_work; | 73 | extern struct workqueue_struct *ccw_device_work; |
69 | extern struct workqueue_struct *ccw_device_notify_work; | 74 | extern struct workqueue_struct *ccw_device_notify_work; |
75 | extern wait_queue_head_t ccw_device_init_wq; | ||
76 | extern atomic_t ccw_device_init_count; | ||
70 | 77 | ||
71 | void io_subchannel_recog_done(struct ccw_device *cdev); | 78 | void io_subchannel_recog_done(struct ccw_device *cdev); |
72 | 79 | ||
@@ -112,5 +119,8 @@ int ccw_device_stlck(struct ccw_device *); | |||
112 | void ccw_device_set_timeout(struct ccw_device *, int); | 119 | void ccw_device_set_timeout(struct ccw_device *, int); |
113 | extern struct subchannel_id ccw_device_get_subchannel_id(struct ccw_device *); | 120 | extern struct subchannel_id ccw_device_get_subchannel_id(struct ccw_device *); |
114 | 121 | ||
122 | /* Channel measurement facility related */ | ||
115 | void retry_set_schib(struct ccw_device *cdev); | 123 | void retry_set_schib(struct ccw_device *cdev); |
124 | void cmf_retry_copy_block(struct ccw_device *); | ||
125 | int cmf_reenable(struct ccw_device *); | ||
116 | #endif | 126 | #endif |
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index 49ec562d7f60..7d0dd72635eb 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c | |||
@@ -336,8 +336,11 @@ ccw_device_oper_notify(void *data) | |||
336 | if (!ret) | 336 | if (!ret) |
337 | /* Driver doesn't want device back. */ | 337 | /* Driver doesn't want device back. */ |
338 | ccw_device_do_unreg_rereg((void *)cdev); | 338 | ccw_device_do_unreg_rereg((void *)cdev); |
339 | else | 339 | else { |
340 | /* Reenable channel measurements, if needed. */ | ||
341 | cmf_reenable(cdev); | ||
340 | wake_up(&cdev->private->wait_q); | 342 | wake_up(&cdev->private->wait_q); |
343 | } | ||
341 | } | 344 | } |
342 | 345 | ||
343 | /* | 346 | /* |
@@ -861,6 +864,8 @@ ccw_device_clear_verify(struct ccw_device *cdev, enum dev_event dev_event) | |||
861 | irb = (struct irb *) __LC_IRB; | 864 | irb = (struct irb *) __LC_IRB; |
862 | /* Accumulate status. We don't do basic sense. */ | 865 | /* Accumulate status. We don't do basic sense. */ |
863 | ccw_device_accumulate_irb(cdev, irb); | 866 | ccw_device_accumulate_irb(cdev, irb); |
867 | /* Remember to clear irb to avoid residuals. */ | ||
868 | memset(&cdev->private->irb, 0, sizeof(struct irb)); | ||
864 | /* Try to start delayed device verification. */ | 869 | /* Try to start delayed device verification. */ |
865 | ccw_device_online_verify(cdev, 0); | 870 | ccw_device_online_verify(cdev, 0); |
866 | /* Note: Don't call handler for cio initiated clear! */ | 871 | /* Note: Don't call handler for cio initiated clear! */ |
@@ -1093,6 +1098,13 @@ ccw_device_change_cmfstate(struct ccw_device *cdev, enum dev_event dev_event) | |||
1093 | dev_fsm_event(cdev, dev_event); | 1098 | dev_fsm_event(cdev, dev_event); |
1094 | } | 1099 | } |
1095 | 1100 | ||
1101 | static void ccw_device_update_cmfblock(struct ccw_device *cdev, | ||
1102 | enum dev_event dev_event) | ||
1103 | { | ||
1104 | cmf_retry_copy_block(cdev); | ||
1105 | cdev->private->state = DEV_STATE_ONLINE; | ||
1106 | dev_fsm_event(cdev, dev_event); | ||
1107 | } | ||
1096 | 1108 | ||
1097 | static void | 1109 | static void |
1098 | ccw_device_quiesce_done(struct ccw_device *cdev, enum dev_event dev_event) | 1110 | ccw_device_quiesce_done(struct ccw_device *cdev, enum dev_event dev_event) |
@@ -1247,6 +1259,12 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = { | |||
1247 | [DEV_EVENT_TIMEOUT] = ccw_device_change_cmfstate, | 1259 | [DEV_EVENT_TIMEOUT] = ccw_device_change_cmfstate, |
1248 | [DEV_EVENT_VERIFY] = ccw_device_change_cmfstate, | 1260 | [DEV_EVENT_VERIFY] = ccw_device_change_cmfstate, |
1249 | }, | 1261 | }, |
1262 | [DEV_STATE_CMFUPDATE] = { | ||
1263 | [DEV_EVENT_NOTOPER] = ccw_device_update_cmfblock, | ||
1264 | [DEV_EVENT_INTERRUPT] = ccw_device_update_cmfblock, | ||
1265 | [DEV_EVENT_TIMEOUT] = ccw_device_update_cmfblock, | ||
1266 | [DEV_EVENT_VERIFY] = ccw_device_update_cmfblock, | ||
1267 | }, | ||
1250 | }; | 1268 | }; |
1251 | 1269 | ||
1252 | /* | 1270 | /* |
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c index 795abb5a65ba..b266ad8e14ff 100644 --- a/drivers/s390/cio/device_ops.c +++ b/drivers/s390/cio/device_ops.c | |||
@@ -78,7 +78,8 @@ ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa, | |||
78 | return -ENODEV; | 78 | return -ENODEV; |
79 | if (cdev->private->state == DEV_STATE_NOT_OPER) | 79 | if (cdev->private->state == DEV_STATE_NOT_OPER) |
80 | return -ENODEV; | 80 | return -ENODEV; |
81 | if (cdev->private->state == DEV_STATE_VERIFY) { | 81 | if (cdev->private->state == DEV_STATE_VERIFY || |
82 | cdev->private->state == DEV_STATE_CLEAR_VERIFY) { | ||
82 | /* Remember to fake irb when finished. */ | 83 | /* Remember to fake irb when finished. */ |
83 | if (!cdev->private->flags.fake_irb) { | 84 | if (!cdev->private->flags.fake_irb) { |
84 | cdev->private->flags.fake_irb = 1; | 85 | cdev->private->flags.fake_irb = 1; |
@@ -270,7 +271,8 @@ ccw_device_wake_up(struct ccw_device *cdev, unsigned long ip, struct irb *irb) | |||
270 | * We didn't get channel end / device end. Check if path | 271 | * We didn't get channel end / device end. Check if path |
271 | * verification has been started; we can retry after it has | 272 | * verification has been started; we can retry after it has |
272 | * finished. We also retry unit checks except for command reject | 273 | * finished. We also retry unit checks except for command reject |
273 | * or intervention required. | 274 | * or intervention required. Also check for long busy |
275 | * conditions. | ||
274 | */ | 276 | */ |
275 | if (cdev->private->flags.doverify || | 277 | if (cdev->private->flags.doverify || |
276 | cdev->private->state == DEV_STATE_VERIFY) | 278 | cdev->private->state == DEV_STATE_VERIFY) |
@@ -279,6 +281,10 @@ ccw_device_wake_up(struct ccw_device *cdev, unsigned long ip, struct irb *irb) | |||
279 | !(irb->ecw[0] & | 281 | !(irb->ecw[0] & |
280 | (SNS0_CMD_REJECT | SNS0_INTERVENTION_REQ))) | 282 | (SNS0_CMD_REJECT | SNS0_INTERVENTION_REQ))) |
281 | cdev->private->intparm = -EAGAIN; | 283 | cdev->private->intparm = -EAGAIN; |
284 | else if ((irb->scsw.dstat & DEV_STAT_ATTENTION) && | ||
285 | (irb->scsw.dstat & DEV_STAT_DEV_END) && | ||
286 | (irb->scsw.dstat & DEV_STAT_UNIT_EXCEP)) | ||
287 | cdev->private->intparm = -EAGAIN; | ||
282 | else | 288 | else |
283 | cdev->private->intparm = -EIO; | 289 | cdev->private->intparm = -EIO; |
284 | 290 | ||
diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c index f99e55308b32..8dc75002acbe 100644 --- a/drivers/s390/s390mach.c +++ b/drivers/s390/s390mach.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
15 | #include <linux/workqueue.h> | 15 | #include <linux/workqueue.h> |
16 | #include <linux/time.h> | 16 | #include <linux/time.h> |
17 | #include <linux/kthread.h> | ||
17 | 18 | ||
18 | #include <asm/lowcore.h> | 19 | #include <asm/lowcore.h> |
19 | 20 | ||
@@ -56,8 +57,6 @@ s390_collect_crw_info(void *param) | |||
56 | unsigned int chain; | 57 | unsigned int chain; |
57 | 58 | ||
58 | sem = (struct semaphore *)param; | 59 | sem = (struct semaphore *)param; |
59 | /* Set a nice name. */ | ||
60 | daemonize("kmcheck"); | ||
61 | repeat: | 60 | repeat: |
62 | down_interruptible(sem); | 61 | down_interruptible(sem); |
63 | slow = 0; | 62 | slow = 0; |
@@ -516,7 +515,7 @@ arch_initcall(machine_check_init); | |||
516 | static int __init | 515 | static int __init |
517 | machine_check_crw_init (void) | 516 | machine_check_crw_init (void) |
518 | { | 517 | { |
519 | kernel_thread(s390_collect_crw_info, &m_sem, CLONE_FS|CLONE_FILES); | 518 | kthread_run(s390_collect_crw_info, &m_sem, "kmcheck"); |
520 | ctl_set_bit(14, 28); /* enable channel report MCH */ | 519 | ctl_set_bit(14, 28); /* enable channel report MCH */ |
521 | return 0; | 520 | return 0; |
522 | } | 521 | } |
diff --git a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c index 67c3d2999775..501ce1791782 100644 --- a/drivers/scsi/sata_via.c +++ b/drivers/scsi/sata_via.c | |||
@@ -335,10 +335,10 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
335 | if ((pci_resource_start(pdev, i) == 0) || | 335 | if ((pci_resource_start(pdev, i) == 0) || |
336 | (pci_resource_len(pdev, i) < bar_sizes[i])) { | 336 | (pci_resource_len(pdev, i) < bar_sizes[i])) { |
337 | dev_printk(KERN_ERR, &pdev->dev, | 337 | dev_printk(KERN_ERR, &pdev->dev, |
338 | "invalid PCI BAR %u (sz 0x%lx, val 0x%lx)\n", | 338 | "invalid PCI BAR %u (sz 0x%llx, val 0x%llx)\n", |
339 | i, | 339 | i, |
340 | pci_resource_start(pdev, i), | 340 | (unsigned long long)pci_resource_start(pdev, i), |
341 | pci_resource_len(pdev, i)); | 341 | (unsigned long long)pci_resource_len(pdev, i)); |
342 | rc = -ENODEV; | 342 | rc = -ENODEV; |
343 | goto err_out_regions; | 343 | goto err_out_regions; |
344 | } | 344 | } |
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index 94886c000d2a..864ef859be56 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c | |||
@@ -594,8 +594,8 @@ pci_default_setup(struct serial_private *priv, struct pciserial_board *board, | |||
594 | else | 594 | else |
595 | offset += idx * board->uart_offset; | 595 | offset += idx * board->uart_offset; |
596 | 596 | ||
597 | maxnr = (pci_resource_len(priv->dev, bar) - board->first_offset) / | 597 | maxnr = (pci_resource_len(priv->dev, bar) - board->first_offset) >> |
598 | (8 << board->reg_shift); | 598 | (board->reg_shift + 3); |
599 | 599 | ||
600 | if (board->flags & FL_REGION_SZ_CAP && idx >= maxnr) | 600 | if (board->flags & FL_REGION_SZ_CAP && idx >= maxnr) |
601 | return 1; | 601 | return 1; |
diff --git a/drivers/sn/ioc4.c b/drivers/sn/ioc4.c index 8256a97eb508..8562821e6498 100644 --- a/drivers/sn/ioc4.c +++ b/drivers/sn/ioc4.c | |||
@@ -438,7 +438,7 @@ static struct pci_device_id ioc4_id_table[] = { | |||
438 | {0} | 438 | {0} |
439 | }; | 439 | }; |
440 | 440 | ||
441 | static struct pci_driver __devinitdata ioc4_driver = { | 441 | static struct pci_driver ioc4_driver = { |
442 | .name = "IOC4", | 442 | .name = "IOC4", |
443 | .id_table = ioc4_id_table, | 443 | .id_table = ioc4_id_table, |
444 | .probe = ioc4_probe, | 444 | .probe = ioc4_probe, |
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index 6b4bc3f2bd86..89bcda5a3298 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c | |||
@@ -1684,9 +1684,13 @@ sl811h_probe(struct platform_device *dev) | |||
1684 | if (!addr || !data) | 1684 | if (!addr || !data) |
1685 | return -ENODEV; | 1685 | return -ENODEV; |
1686 | ioaddr = 1; | 1686 | ioaddr = 1; |
1687 | 1687 | /* | |
1688 | addr_reg = (void __iomem *) addr->start; | 1688 | * NOTE: 64-bit resource->start is getting truncated |
1689 | data_reg = (void __iomem *) data->start; | 1689 | * to avoid compiler warning, assuming that ->start |
1690 | * is always 32-bit for this case | ||
1691 | */ | ||
1692 | addr_reg = (void __iomem *) (unsigned long) addr->start; | ||
1693 | data_reg = (void __iomem *) (unsigned long) data->start; | ||
1690 | } else { | 1694 | } else { |
1691 | addr_reg = ioremap(addr->start, 1); | 1695 | addr_reg = ioremap(addr->start, 1); |
1692 | if (addr_reg == NULL) { | 1696 | if (addr_reg == NULL) { |
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index f32b590730f2..01401cd63ac0 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c | |||
@@ -390,7 +390,7 @@ static const char *vgacon_startup(void) | |||
390 | vga_video_port_val = VGA_CRT_DM; | 390 | vga_video_port_val = VGA_CRT_DM; |
391 | if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) { | 391 | if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) { |
392 | static struct resource ega_console_resource = | 392 | static struct resource ega_console_resource = |
393 | { "ega", 0x3B0, 0x3BF }; | 393 | { .name = "ega", .start = 0x3B0, .end = 0x3BF }; |
394 | vga_video_type = VIDEO_TYPE_EGAM; | 394 | vga_video_type = VIDEO_TYPE_EGAM; |
395 | vga_vram_size = 0x8000; | 395 | vga_vram_size = 0x8000; |
396 | display_desc = "EGA+"; | 396 | display_desc = "EGA+"; |
@@ -398,9 +398,9 @@ static const char *vgacon_startup(void) | |||
398 | &ega_console_resource); | 398 | &ega_console_resource); |
399 | } else { | 399 | } else { |
400 | static struct resource mda1_console_resource = | 400 | static struct resource mda1_console_resource = |
401 | { "mda", 0x3B0, 0x3BB }; | 401 | { .name = "mda", .start = 0x3B0, .end = 0x3BB }; |
402 | static struct resource mda2_console_resource = | 402 | static struct resource mda2_console_resource = |
403 | { "mda", 0x3BF, 0x3BF }; | 403 | { .name = "mda", .start = 0x3BF, .end = 0x3BF }; |
404 | vga_video_type = VIDEO_TYPE_MDA; | 404 | vga_video_type = VIDEO_TYPE_MDA; |
405 | vga_vram_size = 0x2000; | 405 | vga_vram_size = 0x2000; |
406 | display_desc = "*MDA"; | 406 | display_desc = "*MDA"; |
@@ -423,14 +423,14 @@ static const char *vgacon_startup(void) | |||
423 | 423 | ||
424 | if (!ORIG_VIDEO_ISVGA) { | 424 | if (!ORIG_VIDEO_ISVGA) { |
425 | static struct resource ega_console_resource | 425 | static struct resource ega_console_resource |
426 | = { "ega", 0x3C0, 0x3DF }; | 426 | = { .name = "ega", .start = 0x3C0, .end = 0x3DF }; |
427 | vga_video_type = VIDEO_TYPE_EGAC; | 427 | vga_video_type = VIDEO_TYPE_EGAC; |
428 | display_desc = "EGA"; | 428 | display_desc = "EGA"; |
429 | request_resource(&ioport_resource, | 429 | request_resource(&ioport_resource, |
430 | &ega_console_resource); | 430 | &ega_console_resource); |
431 | } else { | 431 | } else { |
432 | static struct resource vga_console_resource | 432 | static struct resource vga_console_resource |
433 | = { "vga+", 0x3C0, 0x3DF }; | 433 | = { .name = "vga+", .start = 0x3C0, .end = 0x3DF }; |
434 | vga_video_type = VIDEO_TYPE_VGAC; | 434 | vga_video_type = VIDEO_TYPE_VGAC; |
435 | display_desc = "VGA+"; | 435 | display_desc = "VGA+"; |
436 | request_resource(&ioport_resource, | 436 | request_resource(&ioport_resource, |
@@ -474,7 +474,7 @@ static const char *vgacon_startup(void) | |||
474 | } | 474 | } |
475 | } else { | 475 | } else { |
476 | static struct resource cga_console_resource = | 476 | static struct resource cga_console_resource = |
477 | { "cga", 0x3D4, 0x3D5 }; | 477 | { .name = "cga", .start = 0x3D4, .end = 0x3D5 }; |
478 | vga_video_type = VIDEO_TYPE_CGA; | 478 | vga_video_type = VIDEO_TYPE_CGA; |
479 | vga_vram_size = 0x2000; | 479 | vga_vram_size = 0x2000; |
480 | display_desc = "*CGA"; | 480 | display_desc = "*CGA"; |
diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c index 2e6df1fcb2b9..c0cc5e3ba7b5 100644 --- a/drivers/video/sgivwfb.c +++ b/drivers/video/sgivwfb.c | |||
@@ -23,6 +23,8 @@ | |||
23 | #include <asm/io.h> | 23 | #include <asm/io.h> |
24 | #include <asm/mtrr.h> | 24 | #include <asm/mtrr.h> |
25 | 25 | ||
26 | #include <setup_arch.h> | ||
27 | |||
26 | #define INCLUDE_TIMING_TABLE_DATA | 28 | #define INCLUDE_TIMING_TABLE_DATA |
27 | #define DBE_REG_BASE par->regs | 29 | #define DBE_REG_BASE par->regs |
28 | #include <video/sgivw.h> | 30 | #include <video/sgivw.h> |
@@ -42,10 +44,6 @@ struct sgivw_par { | |||
42 | * The default can be overridden if the driver is compiled as a module | 44 | * The default can be overridden if the driver is compiled as a module |
43 | */ | 45 | */ |
44 | 46 | ||
45 | /* set by arch/i386/kernel/setup.c */ | ||
46 | extern unsigned long sgivwfb_mem_phys; | ||
47 | extern unsigned long sgivwfb_mem_size; | ||
48 | |||
49 | static int ypan = 0; | 47 | static int ypan = 0; |
50 | static int ywrap = 0; | 48 | static int ywrap = 0; |
51 | 49 | ||
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index 8e1f90e42040..488b5ff48afb 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c | |||
@@ -98,7 +98,9 @@ static u64 ufs_frag_map(struct inode *inode, sector_t frag) | |||
98 | u64 temp = 0L; | 98 | u64 temp = 0L; |
99 | 99 | ||
100 | UFSD(": frag = %llu depth = %d\n", (unsigned long long)frag, depth); | 100 | UFSD(": frag = %llu depth = %d\n", (unsigned long long)frag, depth); |
101 | UFSD(": uspi->s_fpbshift = %d ,uspi->s_apbmask = %x, mask=%llx\n",uspi->s_fpbshift,uspi->s_apbmask,mask); | 101 | UFSD(": uspi->s_fpbshift = %d ,uspi->s_apbmask = %x, mask=%llx\n", |
102 | uspi->s_fpbshift, uspi->s_apbmask, | ||
103 | (unsigned long long)mask); | ||
102 | 104 | ||
103 | if (depth == 0) | 105 | if (depth == 0) |
104 | return 0; | 106 | return 0; |
@@ -429,7 +431,7 @@ int ufs_getfrag_block(struct inode *inode, sector_t fragment, struct buffer_head | |||
429 | 431 | ||
430 | if (!create) { | 432 | if (!create) { |
431 | phys64 = ufs_frag_map(inode, fragment); | 433 | phys64 = ufs_frag_map(inode, fragment); |
432 | UFSD("phys64 = %llu \n",phys64); | 434 | UFSD("phys64 = %llu\n", (unsigned long long)phys64); |
433 | if (phys64) | 435 | if (phys64) |
434 | map_bh(bh_result, sb, phys64); | 436 | map_bh(bh_result, sb, phys64); |
435 | return 0; | 437 | return 0; |
diff --git a/include/asm-alpha/hw_irq.h b/include/asm-alpha/hw_irq.h index ca9d43b63502..a37db0f95092 100644 --- a/include/asm-alpha/hw_irq.h +++ b/include/asm-alpha/hw_irq.h | |||
@@ -2,8 +2,6 @@ | |||
2 | #define _ALPHA_HW_IRQ_H | 2 | #define _ALPHA_HW_IRQ_H |
3 | 3 | ||
4 | 4 | ||
5 | static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {} | ||
6 | |||
7 | extern volatile unsigned long irq_err_count; | 5 | extern volatile unsigned long irq_err_count; |
8 | 6 | ||
9 | #ifdef CONFIG_ALPHA_GENERIC | 7 | #ifdef CONFIG_ALPHA_GENERIC |
diff --git a/include/asm-arm/mach/pci.h b/include/asm-arm/mach/pci.h index 25d540ed0079..923e0ca66200 100644 --- a/include/asm-arm/mach/pci.h +++ b/include/asm-arm/mach/pci.h | |||
@@ -28,7 +28,7 @@ struct hw_pci { | |||
28 | struct pci_sys_data { | 28 | struct pci_sys_data { |
29 | struct list_head node; | 29 | struct list_head node; |
30 | int busnr; /* primary bus number */ | 30 | int busnr; /* primary bus number */ |
31 | unsigned long mem_offset; /* bus->cpu memory mapping offset */ | 31 | u64 mem_offset; /* bus->cpu memory mapping offset */ |
32 | unsigned long io_offset; /* bus->cpu IO mapping offset */ | 32 | unsigned long io_offset; /* bus->cpu IO mapping offset */ |
33 | struct pci_bus *bus; /* PCI bus */ | 33 | struct pci_bus *bus; /* PCI bus */ |
34 | struct resource *resource[3]; /* Primary PCI bus resources */ | 34 | struct resource *resource[3]; /* Primary PCI bus resources */ |
diff --git a/include/asm-cris/hw_irq.h b/include/asm-cris/hw_irq.h index 341536a234e9..298066020af2 100644 --- a/include/asm-cris/hw_irq.h +++ b/include/asm-cris/hw_irq.h | |||
@@ -1,7 +1,5 @@ | |||
1 | #ifndef _ASM_HW_IRQ_H | 1 | #ifndef _ASM_HW_IRQ_H |
2 | #define _ASM_HW_IRQ_H | 2 | #define _ASM_HW_IRQ_H |
3 | 3 | ||
4 | static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {} | ||
5 | |||
6 | #endif | 4 | #endif |
7 | 5 | ||
diff --git a/include/asm-cris/irq.h b/include/asm-cris/irq.h index 4b338792218b..998cce9f3200 100644 --- a/include/asm-cris/irq.h +++ b/include/asm-cris/irq.h | |||
@@ -1,11 +1,6 @@ | |||
1 | #ifndef _ASM_IRQ_H | 1 | #ifndef _ASM_IRQ_H |
2 | #define _ASM_IRQ_H | 2 | #define _ASM_IRQ_H |
3 | 3 | ||
4 | /* | ||
5 | * IRQ line status macro IRQ_PER_CPU is used | ||
6 | */ | ||
7 | #define ARCH_HAS_IRQ_PER_CPU | ||
8 | |||
9 | #include <asm/arch/irq.h> | 4 | #include <asm/arch/irq.h> |
10 | 5 | ||
11 | static inline int irq_canonicalize(int irq) | 6 | static inline int irq_canonicalize(int irq) |
diff --git a/include/asm-i386/hw_irq.h b/include/asm-i386/hw_irq.h index a4c0a5a9ffd8..87e5a351d881 100644 --- a/include/asm-i386/hw_irq.h +++ b/include/asm-i386/hw_irq.h | |||
@@ -69,14 +69,4 @@ extern atomic_t irq_mis_count; | |||
69 | 69 | ||
70 | #define IO_APIC_IRQ(x) (((x) >= 16) || ((1<<(x)) & io_apic_irqs)) | 70 | #define IO_APIC_IRQ(x) (((x) >= 16) || ((1<<(x)) & io_apic_irqs)) |
71 | 71 | ||
72 | #if defined(CONFIG_X86_IO_APIC) | ||
73 | static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) | ||
74 | { | ||
75 | if (IO_APIC_IRQ(i)) | ||
76 | send_IPI_self(IO_APIC_VECTOR(i)); | ||
77 | } | ||
78 | #else | ||
79 | static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {} | ||
80 | #endif | ||
81 | |||
82 | #endif /* _ASM_HW_IRQ_H */ | 72 | #endif /* _ASM_HW_IRQ_H */ |
diff --git a/include/asm-i386/mach-visws/setup_arch.h b/include/asm-i386/mach-visws/setup_arch.h index b92d6d9a4d3c..33f700ef6831 100644 --- a/include/asm-i386/mach-visws/setup_arch.h +++ b/include/asm-i386/mach-visws/setup_arch.h | |||
@@ -1,5 +1,8 @@ | |||
1 | /* Hook to call BIOS initialisation function */ | 1 | /* Hook to call BIOS initialisation function */ |
2 | 2 | ||
3 | extern unsigned long sgivwfb_mem_phys; | ||
4 | extern unsigned long sgivwfb_mem_size; | ||
5 | |||
3 | /* no action for visws */ | 6 | /* no action for visws */ |
4 | 7 | ||
5 | #define ARCH_SETUP | 8 | #define ARCH_SETUP |
diff --git a/include/asm-ia64/hw_irq.h b/include/asm-ia64/hw_irq.h index ea8b8c407ab4..27f9df6b9145 100644 --- a/include/asm-ia64/hw_irq.h +++ b/include/asm-ia64/hw_irq.h | |||
@@ -97,8 +97,7 @@ extern int reserve_irq_vector (int vector); | |||
97 | extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect); | 97 | extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect); |
98 | extern void register_percpu_irq (ia64_vector vec, struct irqaction *action); | 98 | extern void register_percpu_irq (ia64_vector vec, struct irqaction *action); |
99 | 99 | ||
100 | static inline void | 100 | static inline void ia64_resend_irq(unsigned int vector) |
101 | hw_resend_irq (struct hw_interrupt_type *h, unsigned int vector) | ||
102 | { | 101 | { |
103 | platform_send_ipi(smp_processor_id(), vector, IA64_IPI_DM_INT, 0); | 102 | platform_send_ipi(smp_processor_id(), vector, IA64_IPI_DM_INT, 0); |
104 | } | 103 | } |
diff --git a/include/asm-ia64/irq.h b/include/asm-ia64/irq.h index dbe86c0bbce5..79479e2c6966 100644 --- a/include/asm-ia64/irq.h +++ b/include/asm-ia64/irq.h | |||
@@ -14,11 +14,6 @@ | |||
14 | #define NR_IRQS 256 | 14 | #define NR_IRQS 256 |
15 | #define NR_IRQ_VECTORS NR_IRQS | 15 | #define NR_IRQ_VECTORS NR_IRQS |
16 | 16 | ||
17 | /* | ||
18 | * IRQ line status macro IRQ_PER_CPU is used | ||
19 | */ | ||
20 | #define ARCH_HAS_IRQ_PER_CPU | ||
21 | |||
22 | static __inline__ int | 17 | static __inline__ int |
23 | irq_canonicalize (int irq) | 18 | irq_canonicalize (int irq) |
24 | { | 19 | { |
diff --git a/include/asm-m32r/hw_irq.h b/include/asm-m32r/hw_irq.h index 8d7e9d0e09e8..7138537cda03 100644 --- a/include/asm-m32r/hw_irq.h +++ b/include/asm-m32r/hw_irq.h | |||
@@ -1,9 +1,4 @@ | |||
1 | #ifndef _ASM_M32R_HW_IRQ_H | 1 | #ifndef _ASM_M32R_HW_IRQ_H |
2 | #define _ASM_M32R_HW_IRQ_H | 2 | #define _ASM_M32R_HW_IRQ_H |
3 | 3 | ||
4 | static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) | ||
5 | { | ||
6 | /* Nothing to do */ | ||
7 | } | ||
8 | |||
9 | #endif /* _ASM_M32R_HW_IRQ_H */ | 4 | #endif /* _ASM_M32R_HW_IRQ_H */ |
diff --git a/include/asm-mips/hw_irq.h b/include/asm-mips/hw_irq.h index c854d017c0e5..458d9fdc76bf 100644 --- a/include/asm-mips/hw_irq.h +++ b/include/asm-mips/hw_irq.h | |||
@@ -19,9 +19,9 @@ extern void init_8259A(int aeoi); | |||
19 | 19 | ||
20 | extern atomic_t irq_err_count; | 20 | extern atomic_t irq_err_count; |
21 | 21 | ||
22 | /* This may not be apropriate for all machines, we'll see ... */ | 22 | /* |
23 | static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) | 23 | * interrupt-retrigger: NOP for now. This may not be apropriate for all |
24 | { | 24 | * machines, we'll see ... |
25 | } | 25 | */ |
26 | 26 | ||
27 | #endif /* __ASM_HW_IRQ_H */ | 27 | #endif /* __ASM_HW_IRQ_H */ |
diff --git a/include/asm-parisc/assembly.h b/include/asm-parisc/assembly.h index 3ce3440d1b0c..1a7bfe699e0c 100644 --- a/include/asm-parisc/assembly.h +++ b/include/asm-parisc/assembly.h | |||
@@ -48,6 +48,7 @@ | |||
48 | #define CALLEE_SAVE_FRAME_SIZE (CALLEE_REG_FRAME_SIZE + CALLEE_FLOAT_FRAME_SIZE) | 48 | #define CALLEE_SAVE_FRAME_SIZE (CALLEE_REG_FRAME_SIZE + CALLEE_FLOAT_FRAME_SIZE) |
49 | 49 | ||
50 | #ifdef CONFIG_PA20 | 50 | #ifdef CONFIG_PA20 |
51 | #define LDCW ldcw,co | ||
51 | #define BL b,l | 52 | #define BL b,l |
52 | # ifdef CONFIG_64BIT | 53 | # ifdef CONFIG_64BIT |
53 | # define LEVEL 2.0w | 54 | # define LEVEL 2.0w |
@@ -55,6 +56,7 @@ | |||
55 | # define LEVEL 2.0 | 56 | # define LEVEL 2.0 |
56 | # endif | 57 | # endif |
57 | #else | 58 | #else |
59 | #define LDCW ldcw | ||
58 | #define BL bl | 60 | #define BL bl |
59 | #define LEVEL 1.1 | 61 | #define LEVEL 1.1 |
60 | #endif | 62 | #endif |
diff --git a/include/asm-parisc/compat.h b/include/asm-parisc/compat.h index 289624d8b2d4..71b4eeea205a 100644 --- a/include/asm-parisc/compat.h +++ b/include/asm-parisc/compat.h | |||
@@ -5,6 +5,7 @@ | |||
5 | */ | 5 | */ |
6 | #include <linux/types.h> | 6 | #include <linux/types.h> |
7 | #include <linux/sched.h> | 7 | #include <linux/sched.h> |
8 | #include <linux/personality.h> | ||
8 | 9 | ||
9 | #define COMPAT_USER_HZ 100 | 10 | #define COMPAT_USER_HZ 100 |
10 | 11 | ||
@@ -149,4 +150,14 @@ static __inline__ void __user *compat_alloc_user_space(long len) | |||
149 | return (void __user *)regs->gr[30]; | 150 | return (void __user *)regs->gr[30]; |
150 | } | 151 | } |
151 | 152 | ||
153 | static inline int __is_compat_task(struct task_struct *t) | ||
154 | { | ||
155 | return personality(t->personality) == PER_LINUX32; | ||
156 | } | ||
157 | |||
158 | static inline int is_compat_task(void) | ||
159 | { | ||
160 | return __is_compat_task(current); | ||
161 | } | ||
162 | |||
152 | #endif /* _ASM_PARISC_COMPAT_H */ | 163 | #endif /* _ASM_PARISC_COMPAT_H */ |
diff --git a/include/asm-parisc/hw_irq.h b/include/asm-parisc/hw_irq.h index 151426e27521..6707f7df3921 100644 --- a/include/asm-parisc/hw_irq.h +++ b/include/asm-parisc/hw_irq.h | |||
@@ -3,15 +3,6 @@ | |||
3 | 3 | ||
4 | /* | 4 | /* |
5 | * linux/include/asm/hw_irq.h | 5 | * linux/include/asm/hw_irq.h |
6 | * | ||
7 | * (C) 1992, 1993 Linus Torvalds, (C) 1997 Ingo Molnar | ||
8 | * | ||
9 | * moved some of the old arch/i386/kernel/irq.h to here. VY | ||
10 | * | ||
11 | * IRQ/IPI changes taken from work by Thomas Radke | ||
12 | * <tomsoft@informatik.tu-chemnitz.de> | ||
13 | */ | 6 | */ |
14 | 7 | ||
15 | extern void hw_resend_irq(struct hw_interrupt_type *, unsigned int); | ||
16 | |||
17 | #endif | 8 | #endif |
diff --git a/include/asm-parisc/irq.h b/include/asm-parisc/irq.h index 377ba90c7d02..5cae260615a2 100644 --- a/include/asm-parisc/irq.h +++ b/include/asm-parisc/irq.h | |||
@@ -26,11 +26,6 @@ | |||
26 | 26 | ||
27 | #define NR_IRQS (CPU_IRQ_MAX + 1) | 27 | #define NR_IRQS (CPU_IRQ_MAX + 1) |
28 | 28 | ||
29 | /* | ||
30 | * IRQ line status macro IRQ_PER_CPU is used | ||
31 | */ | ||
32 | #define ARCH_HAS_IRQ_PER_CPU | ||
33 | |||
34 | static __inline__ int irq_canonicalize(int irq) | 29 | static __inline__ int irq_canonicalize(int irq) |
35 | { | 30 | { |
36 | return (irq == 2) ? 9 : irq; | 31 | return (irq == 2) ? 9 : irq; |
diff --git a/include/asm-parisc/pdc.h b/include/asm-parisc/pdc.h index 08364f957e7a..c9b2e35326ee 100644 --- a/include/asm-parisc/pdc.h +++ b/include/asm-parisc/pdc.h | |||
@@ -278,12 +278,11 @@ typedef struct { | |||
278 | /* constants for OS (NVM...) */ | 278 | /* constants for OS (NVM...) */ |
279 | #define OS_ID_NONE 0 /* Undefined OS ID */ | 279 | #define OS_ID_NONE 0 /* Undefined OS ID */ |
280 | #define OS_ID_HPUX 1 /* HP-UX OS */ | 280 | #define OS_ID_HPUX 1 /* HP-UX OS */ |
281 | #define OS_ID_LINUX OS_ID_HPUX /* just use the same value as hpux */ | ||
282 | #define OS_ID_MPEXL 2 /* MPE XL OS */ | 281 | #define OS_ID_MPEXL 2 /* MPE XL OS */ |
283 | #define OS_ID_OSF 3 /* OSF OS */ | 282 | #define OS_ID_OSF 3 /* OSF OS */ |
284 | #define OS_ID_HPRT 4 /* HP-RT OS */ | 283 | #define OS_ID_HPRT 4 /* HP-RT OS */ |
285 | #define OS_ID_NOVEL 5 /* NOVELL OS */ | 284 | #define OS_ID_NOVEL 5 /* NOVELL OS */ |
286 | #define OS_ID_NT 6 /* NT OS */ | 285 | #define OS_ID_LINUX 6 /* Linux */ |
287 | 286 | ||
288 | 287 | ||
289 | /* constants for PDC_CHASSIS */ | 288 | /* constants for PDC_CHASSIS */ |
@@ -352,8 +351,8 @@ struct pdc_cache_cf { /* for PDC_CACHE (I/D-caches) */ | |||
352 | cc_wt : 1, /* 0 = WT-Dcache, 1 = WB-Dcache */ | 351 | cc_wt : 1, /* 0 = WT-Dcache, 1 = WB-Dcache */ |
353 | cc_sh : 2, /* 0 = separate I/D-cache, else shared I/D-cache */ | 352 | cc_sh : 2, /* 0 = separate I/D-cache, else shared I/D-cache */ |
354 | cc_cst : 3, /* 0 = incoherent D-cache, 1=coherent D-cache */ | 353 | cc_cst : 3, /* 0 = incoherent D-cache, 1=coherent D-cache */ |
355 | cc_pad1 : 5, /* reserved */ | 354 | cc_pad1 : 10, /* reserved */ |
356 | cc_assoc: 8; /* associativity of I/D-cache */ | 355 | cc_hv : 3; /* hversion dependent */ |
357 | }; | 356 | }; |
358 | 357 | ||
359 | struct pdc_tlb_cf { /* for PDC_CACHE (I/D-TLB's) */ | 358 | struct pdc_tlb_cf { /* for PDC_CACHE (I/D-TLB's) */ |
@@ -719,6 +718,7 @@ void setup_pdc(void); /* in inventory.c */ | |||
719 | int pdc_add_valid(unsigned long address); | 718 | int pdc_add_valid(unsigned long address); |
720 | int pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len); | 719 | int pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len); |
721 | int pdc_chassis_disp(unsigned long disp); | 720 | int pdc_chassis_disp(unsigned long disp); |
721 | int pdc_chassis_warn(unsigned long *warn); | ||
722 | int pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info); | 722 | int pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info); |
723 | int pdc_iodc_read(unsigned long *actcnt, unsigned long hpa, unsigned int index, | 723 | int pdc_iodc_read(unsigned long *actcnt, unsigned long hpa, unsigned int index, |
724 | void *iodc_data, unsigned int iodc_data_size); | 724 | void *iodc_data, unsigned int iodc_data_size); |
@@ -732,6 +732,7 @@ int pdc_model_cpuid(unsigned long *cpu_id); | |||
732 | int pdc_model_versions(unsigned long *versions, int id); | 732 | int pdc_model_versions(unsigned long *versions, int id); |
733 | int pdc_model_capabilities(unsigned long *capabilities); | 733 | int pdc_model_capabilities(unsigned long *capabilities); |
734 | int pdc_cache_info(struct pdc_cache_info *cache); | 734 | int pdc_cache_info(struct pdc_cache_info *cache); |
735 | int pdc_spaceid_bits(unsigned long *space_bits); | ||
735 | #ifndef CONFIG_PA20 | 736 | #ifndef CONFIG_PA20 |
736 | int pdc_btlb_info(struct pdc_btlb_info *btlb); | 737 | int pdc_btlb_info(struct pdc_btlb_info *btlb); |
737 | int pdc_mem_map_hpa(struct pdc_memory_map *r_addr, struct pdc_module_path *mod_path); | 738 | int pdc_mem_map_hpa(struct pdc_memory_map *r_addr, struct pdc_module_path *mod_path); |
@@ -775,6 +776,18 @@ int pdc_sti_call(unsigned long func, unsigned long flags, | |||
775 | 776 | ||
776 | extern void pdc_init(void); | 777 | extern void pdc_init(void); |
777 | 778 | ||
779 | static inline char * os_id_to_string(u16 os_id) { | ||
780 | switch(os_id) { | ||
781 | case OS_ID_NONE: return "No OS"; | ||
782 | case OS_ID_HPUX: return "HP-UX"; | ||
783 | case OS_ID_MPEXL: return "MPE-iX"; | ||
784 | case OS_ID_OSF: return "OSF"; | ||
785 | case OS_ID_HPRT: return "HP-RT"; | ||
786 | case OS_ID_NOVEL: return "Novell Netware"; | ||
787 | case OS_ID_LINUX: return "Linux"; | ||
788 | default: return "Unknown"; | ||
789 | } | ||
790 | } | ||
778 | #endif /* __ASSEMBLY__ */ | 791 | #endif /* __ASSEMBLY__ */ |
779 | 792 | ||
780 | #endif /* _PARISC_PDC_H */ | 793 | #endif /* _PARISC_PDC_H */ |
diff --git a/include/asm-parisc/pgtable.h b/include/asm-parisc/pgtable.h index b6bcc672ba80..5066c54dae0a 100644 --- a/include/asm-parisc/pgtable.h +++ b/include/asm-parisc/pgtable.h | |||
@@ -506,13 +506,13 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, | |||
506 | 506 | ||
507 | /* TLB page size encoding - see table 3-1 in parisc20.pdf */ | 507 | /* TLB page size encoding - see table 3-1 in parisc20.pdf */ |
508 | #define _PAGE_SIZE_ENCODING_4K 0 | 508 | #define _PAGE_SIZE_ENCODING_4K 0 |
509 | #define _PAGE_SIZE_ENCODING_16K 1 | 509 | #define _PAGE_SIZE_ENCODING_16K 1 |
510 | #define _PAGE_SIZE_ENCODING_64K 2 | 510 | #define _PAGE_SIZE_ENCODING_64K 2 |
511 | #define _PAGE_SIZE_ENCODING_256K 3 | 511 | #define _PAGE_SIZE_ENCODING_256K 3 |
512 | #define _PAGE_SIZE_ENCODING_1M 4 | 512 | #define _PAGE_SIZE_ENCODING_1M 4 |
513 | #define _PAGE_SIZE_ENCODING_4M 5 | 513 | #define _PAGE_SIZE_ENCODING_4M 5 |
514 | #define _PAGE_SIZE_ENCODING_16M 6 | 514 | #define _PAGE_SIZE_ENCODING_16M 6 |
515 | #define _PAGE_SIZE_ENCODING_64M 7 | 515 | #define _PAGE_SIZE_ENCODING_64M 7 |
516 | 516 | ||
517 | #if defined(CONFIG_PARISC_PAGE_SIZE_4KB) | 517 | #if defined(CONFIG_PARISC_PAGE_SIZE_4KB) |
518 | # define _PAGE_SIZE_ENCODING_DEFAULT _PAGE_SIZE_ENCODING_4K | 518 | # define _PAGE_SIZE_ENCODING_DEFAULT _PAGE_SIZE_ENCODING_4K |
diff --git a/include/asm-parisc/processor.h b/include/asm-parisc/processor.h index ca49dc91f4fc..b73626f040da 100644 --- a/include/asm-parisc/processor.h +++ b/include/asm-parisc/processor.h | |||
@@ -26,14 +26,12 @@ | |||
26 | * Default implementation of macro that returns current | 26 | * Default implementation of macro that returns current |
27 | * instruction pointer ("program counter"). | 27 | * instruction pointer ("program counter"). |
28 | */ | 28 | */ |
29 | 29 | #ifdef CONFIG_PA20 | |
30 | /* We cannot use MFIA as it was added for PA2.0 - prumpf | 30 | #define current_ia(x) __asm__("mfia %0" : "=r"(x)) |
31 | 31 | #else /* mfia added in pa2.0 */ | |
32 | At one point there were no "0f/0b" type local symbols in gas for | 32 | #define current_ia(x) __asm__("blr 0,%0\n\tnop" : "=r"(x)) |
33 | PA-RISC. This is no longer true, but this still seems like the | 33 | #endif |
34 | nicest way to implement this. */ | 34 | #define current_text_addr() ({ void *pc; current_ia(pc); pc; }) |
35 | |||
36 | #define current_text_addr() ({ void *pc; __asm__("\n\tblr 0,%0\n\tnop":"=r" (pc)); pc; }) | ||
37 | 35 | ||
38 | #define TASK_SIZE (current->thread.task_size) | 36 | #define TASK_SIZE (current->thread.task_size) |
39 | #define TASK_UNMAPPED_BASE (current->thread.map_base) | 37 | #define TASK_UNMAPPED_BASE (current->thread.map_base) |
diff --git a/include/asm-parisc/system.h b/include/asm-parisc/system.h index 863876134b2c..5fe2d2329ab5 100644 --- a/include/asm-parisc/system.h +++ b/include/asm-parisc/system.h | |||
@@ -155,13 +155,14 @@ static inline void set_eiem(unsigned long val) | |||
155 | type and dynamically select the 16-byte aligned int from the array | 155 | type and dynamically select the 16-byte aligned int from the array |
156 | for the semaphore. */ | 156 | for the semaphore. */ |
157 | 157 | ||
158 | #define __PA_LDCW_ALIGNMENT 16 | 158 | #define __PA_LDCW_ALIGNMENT 16 |
159 | #define __ldcw_align(a) ({ \ | 159 | #define __ldcw_align(a) ({ \ |
160 | unsigned long __ret = (unsigned long) &(a)->lock[0]; \ | 160 | unsigned long __ret = (unsigned long) &(a)->lock[0]; \ |
161 | __ret = (__ret + __PA_LDCW_ALIGNMENT - 1) & ~(__PA_LDCW_ALIGNMENT - 1); \ | 161 | __ret = (__ret + __PA_LDCW_ALIGNMENT - 1) \ |
162 | (volatile unsigned int *) __ret; \ | 162 | & ~(__PA_LDCW_ALIGNMENT - 1); \ |
163 | (volatile unsigned int *) __ret; \ | ||
163 | }) | 164 | }) |
164 | #define LDCW "ldcw" | 165 | #define __LDCW "ldcw" |
165 | 166 | ||
166 | #else /*CONFIG_PA20*/ | 167 | #else /*CONFIG_PA20*/ |
167 | /* From: "Jim Hull" <jim.hull of hp.com> | 168 | /* From: "Jim Hull" <jim.hull of hp.com> |
@@ -171,17 +172,18 @@ static inline void set_eiem(unsigned long val) | |||
171 | they only require "natural" alignment (4-byte for ldcw, 8-byte for | 172 | they only require "natural" alignment (4-byte for ldcw, 8-byte for |
172 | ldcd). */ | 173 | ldcd). */ |
173 | 174 | ||
174 | #define __PA_LDCW_ALIGNMENT 4 | 175 | #define __PA_LDCW_ALIGNMENT 4 |
175 | #define __ldcw_align(a) ((volatile unsigned int *)a) | 176 | #define __ldcw_align(a) ((volatile unsigned int *)a) |
176 | #define LDCW "ldcw,co" | 177 | #define __LDCW "ldcw,co" |
177 | 178 | ||
178 | #endif /*!CONFIG_PA20*/ | 179 | #endif /*!CONFIG_PA20*/ |
179 | 180 | ||
180 | /* LDCW, the only atomic read-write operation PA-RISC has. *sigh*. */ | 181 | /* LDCW, the only atomic read-write operation PA-RISC has. *sigh*. */ |
181 | #define __ldcw(a) ({ \ | 182 | #define __ldcw(a) ({ \ |
182 | unsigned __ret; \ | 183 | unsigned __ret; \ |
183 | __asm__ __volatile__(LDCW " 0(%1),%0" : "=r" (__ret) : "r" (a)); \ | 184 | __asm__ __volatile__(__LDCW " 0(%1),%0" \ |
184 | __ret; \ | 185 | : "=r" (__ret) : "r" (a)); \ |
186 | __ret; \ | ||
185 | }) | 187 | }) |
186 | 188 | ||
187 | #ifdef CONFIG_SMP | 189 | #ifdef CONFIG_SMP |
diff --git a/include/asm-parisc/uaccess.h b/include/asm-parisc/uaccess.h index f6c417c8c484..d973e8b3466c 100644 --- a/include/asm-parisc/uaccess.h +++ b/include/asm-parisc/uaccess.h | |||
@@ -172,7 +172,11 @@ struct exception_data { | |||
172 | /* | 172 | /* |
173 | * The "__put_user/kernel_asm()" macros tell gcc they read from memory | 173 | * The "__put_user/kernel_asm()" macros tell gcc they read from memory |
174 | * instead of writing. This is because they do not write to any memory | 174 | * instead of writing. This is because they do not write to any memory |
175 | * gcc knows about, so there are no aliasing issues. | 175 | * gcc knows about, so there are no aliasing issues. These macros must |
176 | * also be aware that "fixup_put_user_skip_[12]" are executed in the | ||
177 | * context of the fault, and any registers used there must be listed | ||
178 | * as clobbers. In this case only "r1" is used by the current routines. | ||
179 | * r8/r9 are already listed as err/val. | ||
176 | */ | 180 | */ |
177 | 181 | ||
178 | #ifdef __LP64__ | 182 | #ifdef __LP64__ |
@@ -183,7 +187,8 @@ struct exception_data { | |||
183 | "\t.dword\t1b,fixup_put_user_skip_1\n" \ | 187 | "\t.dword\t1b,fixup_put_user_skip_1\n" \ |
184 | "\t.previous" \ | 188 | "\t.previous" \ |
185 | : "=r"(__pu_err) \ | 189 | : "=r"(__pu_err) \ |
186 | : "r"(ptr), "r"(x), "0"(__pu_err)) | 190 | : "r"(ptr), "r"(x), "0"(__pu_err) \ |
191 | : "r1") | ||
187 | 192 | ||
188 | #define __put_user_asm(stx,x,ptr) \ | 193 | #define __put_user_asm(stx,x,ptr) \ |
189 | __asm__ __volatile__ ( \ | 194 | __asm__ __volatile__ ( \ |
diff --git a/include/asm-parisc/unistd.h b/include/asm-parisc/unistd.h index 12b867238a47..27bcfad1c3e3 100644 --- a/include/asm-parisc/unistd.h +++ b/include/asm-parisc/unistd.h | |||
@@ -797,11 +797,6 @@ | |||
797 | 797 | ||
798 | #define SYS_ify(syscall_name) __NR_##syscall_name | 798 | #define SYS_ify(syscall_name) __NR_##syscall_name |
799 | 799 | ||
800 | /* Assume all syscalls are done from PIC code just to be | ||
801 | * safe. The worst case scenario is that you lose a register | ||
802 | * and save/restore r19 across the syscall. */ | ||
803 | #define PIC | ||
804 | |||
805 | #ifndef ASM_LINE_SEP | 800 | #ifndef ASM_LINE_SEP |
806 | # define ASM_LINE_SEP ; | 801 | # define ASM_LINE_SEP ; |
807 | #endif | 802 | #endif |
diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h index fab41c280aa1..1ba3c9983614 100644 --- a/include/asm-powerpc/cputable.h +++ b/include/asm-powerpc/cputable.h | |||
@@ -117,38 +117,30 @@ extern void do_cpu_ftr_fixups(unsigned long offset); | |||
117 | #define CPU_FTR_PPC_LE ASM_CONST(0x0000000000200000) | 117 | #define CPU_FTR_PPC_LE ASM_CONST(0x0000000000200000) |
118 | #define CPU_FTR_REAL_LE ASM_CONST(0x0000000000400000) | 118 | #define CPU_FTR_REAL_LE ASM_CONST(0x0000000000400000) |
119 | 119 | ||
120 | /* | ||
121 | * Add the 64-bit processor unique features in the top half of the word; | ||
122 | * on 32-bit, make the names available but defined to be 0. | ||
123 | */ | ||
120 | #ifdef __powerpc64__ | 124 | #ifdef __powerpc64__ |
121 | /* Add the 64b processor unique features in the top half of the word */ | 125 | #define LONG_ASM_CONST(x) ASM_CONST(x) |
122 | #define CPU_FTR_SLB ASM_CONST(0x0000000100000000) | ||
123 | #define CPU_FTR_16M_PAGE ASM_CONST(0x0000000200000000) | ||
124 | #define CPU_FTR_TLBIEL ASM_CONST(0x0000000400000000) | ||
125 | #define CPU_FTR_NOEXECUTE ASM_CONST(0x0000000800000000) | ||
126 | #define CPU_FTR_IABR ASM_CONST(0x0000002000000000) | ||
127 | #define CPU_FTR_MMCRA ASM_CONST(0x0000004000000000) | ||
128 | #define CPU_FTR_CTRL ASM_CONST(0x0000008000000000) | ||
129 | #define CPU_FTR_SMT ASM_CONST(0x0000010000000000) | ||
130 | #define CPU_FTR_COHERENT_ICACHE ASM_CONST(0x0000020000000000) | ||
131 | #define CPU_FTR_LOCKLESS_TLBIE ASM_CONST(0x0000040000000000) | ||
132 | #define CPU_FTR_CI_LARGE_PAGE ASM_CONST(0x0000100000000000) | ||
133 | #define CPU_FTR_PAUSE_ZERO ASM_CONST(0x0000200000000000) | ||
134 | #define CPU_FTR_PURR ASM_CONST(0x0000400000000000) | ||
135 | #else | 126 | #else |
136 | /* ensure on 32b processors the flags are available for compiling but | 127 | #define LONG_ASM_CONST(x) 0 |
137 | * don't do anything */ | ||
138 | #define CPU_FTR_SLB ASM_CONST(0x0) | ||
139 | #define CPU_FTR_16M_PAGE ASM_CONST(0x0) | ||
140 | #define CPU_FTR_TLBIEL ASM_CONST(0x0) | ||
141 | #define CPU_FTR_NOEXECUTE ASM_CONST(0x0) | ||
142 | #define CPU_FTR_IABR ASM_CONST(0x0) | ||
143 | #define CPU_FTR_MMCRA ASM_CONST(0x0) | ||
144 | #define CPU_FTR_CTRL ASM_CONST(0x0) | ||
145 | #define CPU_FTR_SMT ASM_CONST(0x0) | ||
146 | #define CPU_FTR_COHERENT_ICACHE ASM_CONST(0x0) | ||
147 | #define CPU_FTR_LOCKLESS_TLBIE ASM_CONST(0x0) | ||
148 | #define CPU_FTR_CI_LARGE_PAGE ASM_CONST(0x0) | ||
149 | #define CPU_FTR_PURR ASM_CONST(0x0) | ||
150 | #endif | 128 | #endif |
151 | 129 | ||
130 | #define CPU_FTR_SLB LONG_ASM_CONST(0x0000000100000000) | ||
131 | #define CPU_FTR_16M_PAGE LONG_ASM_CONST(0x0000000200000000) | ||
132 | #define CPU_FTR_TLBIEL LONG_ASM_CONST(0x0000000400000000) | ||
133 | #define CPU_FTR_NOEXECUTE LONG_ASM_CONST(0x0000000800000000) | ||
134 | #define CPU_FTR_IABR LONG_ASM_CONST(0x0000002000000000) | ||
135 | #define CPU_FTR_MMCRA LONG_ASM_CONST(0x0000004000000000) | ||
136 | #define CPU_FTR_CTRL LONG_ASM_CONST(0x0000008000000000) | ||
137 | #define CPU_FTR_SMT LONG_ASM_CONST(0x0000010000000000) | ||
138 | #define CPU_FTR_COHERENT_ICACHE LONG_ASM_CONST(0x0000020000000000) | ||
139 | #define CPU_FTR_LOCKLESS_TLBIE LONG_ASM_CONST(0x0000040000000000) | ||
140 | #define CPU_FTR_CI_LARGE_PAGE LONG_ASM_CONST(0x0000100000000000) | ||
141 | #define CPU_FTR_PAUSE_ZERO LONG_ASM_CONST(0x0000200000000000) | ||
142 | #define CPU_FTR_PURR LONG_ASM_CONST(0x0000400000000000) | ||
143 | |||
152 | #ifndef __ASSEMBLY__ | 144 | #ifndef __ASSEMBLY__ |
153 | 145 | ||
154 | #define CPU_FTR_PPCAS_ARCH_V2_BASE (CPU_FTR_SLB | \ | 146 | #define CPU_FTR_PPCAS_ARCH_V2_BASE (CPU_FTR_SLB | \ |
diff --git a/include/asm-powerpc/hw_irq.h b/include/asm-powerpc/hw_irq.h index ce0f7db63c16..d40359204aba 100644 --- a/include/asm-powerpc/hw_irq.h +++ b/include/asm-powerpc/hw_irq.h | |||
@@ -86,27 +86,27 @@ static inline void local_irq_save_ptr(unsigned long *flags) | |||
86 | #define mask_irq(irq) \ | 86 | #define mask_irq(irq) \ |
87 | ({ \ | 87 | ({ \ |
88 | irq_desc_t *desc = get_irq_desc(irq); \ | 88 | irq_desc_t *desc = get_irq_desc(irq); \ |
89 | if (desc->handler && desc->handler->disable) \ | 89 | if (desc->chip && desc->chip->disable) \ |
90 | desc->handler->disable(irq); \ | 90 | desc->chip->disable(irq); \ |
91 | }) | 91 | }) |
92 | #define unmask_irq(irq) \ | 92 | #define unmask_irq(irq) \ |
93 | ({ \ | 93 | ({ \ |
94 | irq_desc_t *desc = get_irq_desc(irq); \ | 94 | irq_desc_t *desc = get_irq_desc(irq); \ |
95 | if (desc->handler && desc->handler->enable) \ | 95 | if (desc->chip && desc->chip->enable) \ |
96 | desc->handler->enable(irq); \ | 96 | desc->chip->enable(irq); \ |
97 | }) | 97 | }) |
98 | #define ack_irq(irq) \ | 98 | #define ack_irq(irq) \ |
99 | ({ \ | 99 | ({ \ |
100 | irq_desc_t *desc = get_irq_desc(irq); \ | 100 | irq_desc_t *desc = get_irq_desc(irq); \ |
101 | if (desc->handler && desc->handler->ack) \ | 101 | if (desc->chip && desc->chip->ack) \ |
102 | desc->handler->ack(irq); \ | 102 | desc->chip->ack(irq); \ |
103 | }) | 103 | }) |
104 | 104 | ||
105 | /* Should we handle this via lost interrupts and IPIs or should we don't care like | 105 | /* |
106 | * we do now ? --BenH. | 106 | * interrupt-retrigger: should we handle this via lost interrupts and IPIs |
107 | * or should we not care like we do now ? --BenH. | ||
107 | */ | 108 | */ |
108 | struct hw_interrupt_type; | 109 | struct hw_interrupt_type; |
109 | static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {} | ||
110 | 110 | ||
111 | #endif /* __KERNEL__ */ | 111 | #endif /* __KERNEL__ */ |
112 | #endif /* _ASM_POWERPC_HW_IRQ_H */ | 112 | #endif /* _ASM_POWERPC_HW_IRQ_H */ |
diff --git a/include/asm-powerpc/irq.h b/include/asm-powerpc/irq.h index a10feec29d4d..eb5f33e1977a 100644 --- a/include/asm-powerpc/irq.h +++ b/include/asm-powerpc/irq.h | |||
@@ -30,11 +30,6 @@ | |||
30 | #define IRQ_POLARITY_POSITIVE 0x2 /* high level or low->high edge */ | 30 | #define IRQ_POLARITY_POSITIVE 0x2 /* high level or low->high edge */ |
31 | #define IRQ_POLARITY_NEGATIVE 0x0 /* low level or high->low edge */ | 31 | #define IRQ_POLARITY_NEGATIVE 0x0 /* low level or high->low edge */ |
32 | 32 | ||
33 | /* | ||
34 | * IRQ line status macro IRQ_PER_CPU is used | ||
35 | */ | ||
36 | #define ARCH_HAS_IRQ_PER_CPU | ||
37 | |||
38 | #define get_irq_desc(irq) (&irq_desc[(irq)]) | 33 | #define get_irq_desc(irq) (&irq_desc[(irq)]) |
39 | 34 | ||
40 | /* Define a way to iterate across irqs. */ | 35 | /* Define a way to iterate across irqs. */ |
diff --git a/include/asm-powerpc/iseries/it_lp_queue.h b/include/asm-powerpc/iseries/it_lp_queue.h index b7c6fc12cce2..284c5a7db3ac 100644 --- a/include/asm-powerpc/iseries/it_lp_queue.h +++ b/include/asm-powerpc/iseries/it_lp_queue.h | |||
@@ -29,20 +29,20 @@ | |||
29 | 29 | ||
30 | struct HvLpEvent; | 30 | struct HvLpEvent; |
31 | 31 | ||
32 | #define ITMaxLpQueues 8 | 32 | #define IT_LP_MAX_QUEUES 8 |
33 | 33 | ||
34 | #define NotUsed 0 // Queue will not be used by PLIC | 34 | #define IT_LP_NOT_USED 0 /* Queue will not be used by PLIC */ |
35 | #define DedicatedIo 1 // Queue dedicated to IO processor specified | 35 | #define IT_LP_DEDICATED_IO 1 /* Queue dedicated to IO processor specified */ |
36 | #define DedicatedLp 2 // Queue dedicated to LP specified | 36 | #define IT_LP_DEDICATED_LP 2 /* Queue dedicated to LP specified */ |
37 | #define Shared 3 // Queue shared for both IO and LP | 37 | #define IT_LP_SHARED 3 /* Queue shared for both IO and LP */ |
38 | 38 | ||
39 | #define LpEventStackSize 4096 | 39 | #define IT_LP_EVENT_STACK_SIZE 4096 |
40 | #define LpEventMaxSize 256 | 40 | #define IT_LP_EVENT_MAX_SIZE 256 |
41 | #define LpEventAlign 64 | 41 | #define IT_LP_EVENT_ALIGN 64 |
42 | 42 | ||
43 | struct hvlpevent_queue { | 43 | struct hvlpevent_queue { |
44 | /* | 44 | /* |
45 | * The xSlicCurEventPtr is the pointer to the next event stack entry | 45 | * The hq_current_event is the pointer to the next event stack entry |
46 | * that will become valid. The OS must peek at this entry to determine | 46 | * that will become valid. The OS must peek at this entry to determine |
47 | * if it is valid. PLIC will set the valid indicator as the very last | 47 | * if it is valid. PLIC will set the valid indicator as the very last |
48 | * store into that entry. | 48 | * store into that entry. |
@@ -52,23 +52,23 @@ struct hvlpevent_queue { | |||
52 | * location again. | 52 | * location again. |
53 | * | 53 | * |
54 | * If the event stack fills and there are overflow events, then PLIC | 54 | * If the event stack fills and there are overflow events, then PLIC |
55 | * will set the xPlicOverflowIntPending flag in which case the OS will | 55 | * will set the hq_overflow_pending flag in which case the OS will |
56 | * have to fetch the additional LP events once they have drained the | 56 | * have to fetch the additional LP events once they have drained the |
57 | * event stack. | 57 | * event stack. |
58 | * | 58 | * |
59 | * The first 16-bytes are known by both the OS and PLIC. The remainder | 59 | * The first 16-bytes are known by both the OS and PLIC. The remainder |
60 | * of the cache line is for use by the OS. | 60 | * of the cache line is for use by the OS. |
61 | */ | 61 | */ |
62 | u8 xPlicOverflowIntPending;// 0x00 Overflow events are pending | 62 | u8 hq_overflow_pending; /* 0x00 Overflow events are pending */ |
63 | u8 xPlicStatus; // 0x01 DedicatedIo or DedicatedLp or NotUsed | 63 | u8 hq_status; /* 0x01 DedicatedIo or DedicatedLp or NotUsed */ |
64 | u16 xSlicLogicalProcIndex; // 0x02 Logical Proc Index for correlation | 64 | u16 hq_proc_index; /* 0x02 Logical Proc Index for correlation */ |
65 | u8 xPlicRsvd[12]; // 0x04 | 65 | u8 hq_reserved1[12]; /* 0x04 */ |
66 | char *xSlicCurEventPtr; // 0x10 | 66 | char *hq_current_event; /* 0x10 */ |
67 | char *xSlicLastValidEventPtr; // 0x18 | 67 | char *hq_last_event; /* 0x18 */ |
68 | char *xSlicEventStackPtr; // 0x20 | 68 | char *hq_event_stack; /* 0x20 */ |
69 | u8 xIndex; // 0x28 unique sequential index. | 69 | u8 hq_index; /* 0x28 unique sequential index. */ |
70 | u8 xSlicRsvd[3]; // 0x29-2b | 70 | u8 hq_reserved2[3]; /* 0x29-2b */ |
71 | spinlock_t lock; | 71 | spinlock_t hq_lock; |
72 | }; | 72 | }; |
73 | 73 | ||
74 | extern struct hvlpevent_queue hvlpevent_queue; | 74 | extern struct hvlpevent_queue hvlpevent_queue; |
diff --git a/include/asm-powerpc/kdump.h b/include/asm-powerpc/kdump.h index 5a5c3b5ab1e0..dc1574c945f8 100644 --- a/include/asm-powerpc/kdump.h +++ b/include/asm-powerpc/kdump.h | |||
@@ -15,6 +15,8 @@ | |||
15 | #define KDUMP_TRAMPOLINE_START 0x0100 | 15 | #define KDUMP_TRAMPOLINE_START 0x0100 |
16 | #define KDUMP_TRAMPOLINE_END 0x3000 | 16 | #define KDUMP_TRAMPOLINE_END 0x3000 |
17 | 17 | ||
18 | #define KDUMP_MIN_TCE_ENTRIES 2048 | ||
19 | |||
18 | #else /* !CONFIG_CRASH_DUMP */ | 20 | #else /* !CONFIG_CRASH_DUMP */ |
19 | 21 | ||
20 | #define PHYSICAL_START 0x0 | 22 | #define PHYSICAL_START 0x0 |
diff --git a/include/asm-powerpc/kexec.h b/include/asm-powerpc/kexec.h index efe8872ec583..8f7fd5cfec34 100644 --- a/include/asm-powerpc/kexec.h +++ b/include/asm-powerpc/kexec.h | |||
@@ -112,9 +112,13 @@ static inline void crash_setup_regs(struct pt_regs *newregs, | |||
112 | #ifdef __powerpc64__ | 112 | #ifdef __powerpc64__ |
113 | extern void kexec_smp_wait(void); /* get and clear naca physid, wait for | 113 | extern void kexec_smp_wait(void); /* get and clear naca physid, wait for |
114 | master to copy new code to 0 */ | 114 | master to copy new code to 0 */ |
115 | extern void __init kexec_setup(void); | ||
116 | extern int crashing_cpu; | 115 | extern int crashing_cpu; |
117 | extern void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *)); | 116 | extern void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *)); |
117 | extern cpumask_t cpus_in_sr; | ||
118 | static inline int kexec_sr_activated(int cpu) | ||
119 | { | ||
120 | return cpu_isset(cpu,cpus_in_sr); | ||
121 | } | ||
118 | #endif /* __powerpc64 __ */ | 122 | #endif /* __powerpc64 __ */ |
119 | 123 | ||
120 | struct kimage; | 124 | struct kimage; |
@@ -124,10 +128,13 @@ extern int default_machine_kexec_prepare(struct kimage *image); | |||
124 | extern void default_machine_crash_shutdown(struct pt_regs *regs); | 128 | extern void default_machine_crash_shutdown(struct pt_regs *regs); |
125 | 129 | ||
126 | extern void machine_kexec_simple(struct kimage *image); | 130 | extern void machine_kexec_simple(struct kimage *image); |
131 | extern void crash_kexec_secondary(struct pt_regs *regs); | ||
127 | extern int overlaps_crashkernel(unsigned long start, unsigned long size); | 132 | extern int overlaps_crashkernel(unsigned long start, unsigned long size); |
128 | extern void reserve_crashkernel(void); | 133 | extern void reserve_crashkernel(void); |
129 | 134 | ||
130 | #else /* !CONFIG_KEXEC */ | 135 | #else /* !CONFIG_KEXEC */ |
136 | static inline int kexec_sr_activated(int cpu) { return 0; } | ||
137 | static inline void crash_kexec_secondary(struct pt_regs *regs) { } | ||
131 | 138 | ||
132 | static inline int overlaps_crashkernel(unsigned long start, unsigned long size) | 139 | static inline int overlaps_crashkernel(unsigned long start, unsigned long size) |
133 | { | 140 | { |
diff --git a/include/asm-powerpc/machdep.h b/include/asm-powerpc/machdep.h index 73db1f71329d..eba133d149a7 100644 --- a/include/asm-powerpc/machdep.h +++ b/include/asm-powerpc/machdep.h | |||
@@ -81,6 +81,8 @@ struct machdep_calls { | |||
81 | void (*tce_free)(struct iommu_table *tbl, | 81 | void (*tce_free)(struct iommu_table *tbl, |
82 | long index, | 82 | long index, |
83 | long npages); | 83 | long npages); |
84 | unsigned long (*tce_get)(struct iommu_table *tbl, | ||
85 | long index); | ||
84 | void (*tce_flush)(struct iommu_table *tbl); | 86 | void (*tce_flush)(struct iommu_table *tbl); |
85 | void (*iommu_dev_setup)(struct pci_dev *dev); | 87 | void (*iommu_dev_setup)(struct pci_dev *dev); |
86 | void (*iommu_bus_setup)(struct pci_bus *bus); | 88 | void (*iommu_bus_setup)(struct pci_bus *bus); |
diff --git a/include/asm-powerpc/mmu.h b/include/asm-powerpc/mmu.h index 3a5ebe229af5..c3fc7a28e3cd 100644 --- a/include/asm-powerpc/mmu.h +++ b/include/asm-powerpc/mmu.h | |||
@@ -238,7 +238,6 @@ extern int hash_huge_page(struct mm_struct *mm, unsigned long access, | |||
238 | unsigned long ea, unsigned long vsid, int local, | 238 | unsigned long ea, unsigned long vsid, int local, |
239 | unsigned long trap); | 239 | unsigned long trap); |
240 | 240 | ||
241 | extern void htab_finish_init(void); | ||
242 | extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend, | 241 | extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend, |
243 | unsigned long pstart, unsigned long mode, | 242 | unsigned long pstart, unsigned long mode, |
244 | int psize); | 243 | int psize); |
diff --git a/include/asm-powerpc/mmu_context.h b/include/asm-powerpc/mmu_context.h index 8c6b1a6d944f..083ac917bd29 100644 --- a/include/asm-powerpc/mmu_context.h +++ b/include/asm-powerpc/mmu_context.h | |||
@@ -25,8 +25,13 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, | |||
25 | { | 25 | { |
26 | } | 26 | } |
27 | 27 | ||
28 | /* | ||
29 | * The proto-VSID space has 2^35 - 1 segments available for user mappings. | ||
30 | * Each segment contains 2^28 bytes. Each context maps 2^44 bytes, | ||
31 | * so we can support 2^19-1 contexts (19 == 35 + 28 - 44). | ||
32 | */ | ||
28 | #define NO_CONTEXT 0 | 33 | #define NO_CONTEXT 0 |
29 | #define MAX_CONTEXT (0x100000-1) | 34 | #define MAX_CONTEXT ((1UL << 19) - 1) |
30 | 35 | ||
31 | extern int init_new_context(struct task_struct *tsk, struct mm_struct *mm); | 36 | extern int init_new_context(struct task_struct *tsk, struct mm_struct *mm); |
32 | extern void destroy_context(struct mm_struct *mm); | 37 | extern void destroy_context(struct mm_struct *mm); |
diff --git a/include/asm-powerpc/mpc86xx.h b/include/asm-powerpc/mpc86xx.h index d0a6718d188b..f260382739fa 100644 --- a/include/asm-powerpc/mpc86xx.h +++ b/include/asm-powerpc/mpc86xx.h | |||
@@ -15,15 +15,10 @@ | |||
15 | #ifndef __ASM_POWERPC_MPC86xx_H__ | 15 | #ifndef __ASM_POWERPC_MPC86xx_H__ |
16 | #define __ASM_POWERPC_MPC86xx_H__ | 16 | #define __ASM_POWERPC_MPC86xx_H__ |
17 | 17 | ||
18 | #include <linux/config.h> | ||
19 | #include <asm/mmu.h> | 18 | #include <asm/mmu.h> |
20 | 19 | ||
21 | #ifdef CONFIG_PPC_86xx | 20 | #ifdef CONFIG_PPC_86xx |
22 | 21 | ||
23 | #ifdef CONFIG_MPC8641_HPCN | ||
24 | #include <platforms/86xx/mpc8641_hpcn.h> | ||
25 | #endif | ||
26 | |||
27 | #define _IO_BASE isa_io_base | 22 | #define _IO_BASE isa_io_base |
28 | #define _ISA_MEM_BASE isa_mem_base | 23 | #define _ISA_MEM_BASE isa_mem_base |
29 | #ifdef CONFIG_PCI | 24 | #ifdef CONFIG_PCI |
diff --git a/include/asm-powerpc/pci.h b/include/asm-powerpc/pci.h index 5d2c9e6c4be2..46afd29b904e 100644 --- a/include/asm-powerpc/pci.h +++ b/include/asm-powerpc/pci.h | |||
@@ -242,7 +242,7 @@ extern pgprot_t pci_phys_mem_access_prot(struct file *file, | |||
242 | #define HAVE_ARCH_PCI_RESOURCE_TO_USER | 242 | #define HAVE_ARCH_PCI_RESOURCE_TO_USER |
243 | extern void pci_resource_to_user(const struct pci_dev *dev, int bar, | 243 | extern void pci_resource_to_user(const struct pci_dev *dev, int bar, |
244 | const struct resource *rsrc, | 244 | const struct resource *rsrc, |
245 | u64 *start, u64 *end); | 245 | resource_size_t *start, resource_size_t *end); |
246 | #endif /* CONFIG_PPC_MULTIPLATFORM || CONFIG_PPC32 */ | 246 | #endif /* CONFIG_PPC_MULTIPLATFORM || CONFIG_PPC32 */ |
247 | 247 | ||
248 | #endif /* __KERNEL__ */ | 248 | #endif /* __KERNEL__ */ |
diff --git a/include/asm-powerpc/rtas.h b/include/asm-powerpc/rtas.h index 02e213e3d69f..a33c6acffa61 100644 --- a/include/asm-powerpc/rtas.h +++ b/include/asm-powerpc/rtas.h | |||
@@ -181,6 +181,9 @@ extern int rtas_set_rtc_time(struct rtc_time *rtc_time); | |||
181 | extern unsigned int rtas_busy_delay_time(int status); | 181 | extern unsigned int rtas_busy_delay_time(int status); |
182 | extern unsigned int rtas_busy_delay(int status); | 182 | extern unsigned int rtas_busy_delay(int status); |
183 | 183 | ||
184 | extern int early_init_dt_scan_rtas(unsigned long node, | ||
185 | const char *uname, int depth, void *data); | ||
186 | |||
184 | extern void pSeries_log_error(char *buf, unsigned int err_type, int fatal); | 187 | extern void pSeries_log_error(char *buf, unsigned int err_type, int fatal); |
185 | 188 | ||
186 | /* Error types logged. */ | 189 | /* Error types logged. */ |
diff --git a/include/asm-powerpc/time.h b/include/asm-powerpc/time.h index 4463148c659f..dcde4410348d 100644 --- a/include/asm-powerpc/time.h +++ b/include/asm-powerpc/time.h | |||
@@ -18,8 +18,9 @@ | |||
18 | #include <linux/percpu.h> | 18 | #include <linux/percpu.h> |
19 | 19 | ||
20 | #include <asm/processor.h> | 20 | #include <asm/processor.h> |
21 | #ifdef CONFIG_PPC64 | 21 | #ifdef CONFIG_PPC_ISERIES |
22 | #include <asm/paca.h> | 22 | #include <asm/paca.h> |
23 | #include <asm/firmware.h> | ||
23 | #include <asm/iseries/hv_call.h> | 24 | #include <asm/iseries/hv_call.h> |
24 | #endif | 25 | #endif |
25 | 26 | ||
@@ -177,7 +178,8 @@ static inline void set_dec(int val) | |||
177 | #ifdef CONFIG_PPC_ISERIES | 178 | #ifdef CONFIG_PPC_ISERIES |
178 | int cur_dec; | 179 | int cur_dec; |
179 | 180 | ||
180 | if (get_lppaca()->shared_proc) { | 181 | if (firmware_has_feature(FW_FEATURE_ISERIES) && |
182 | get_lppaca()->shared_proc) { | ||
181 | get_lppaca()->virtual_decr = val; | 183 | get_lppaca()->virtual_decr = val; |
182 | cur_dec = get_dec(); | 184 | cur_dec = get_dec(); |
183 | if (cur_dec > val) | 185 | if (cur_dec > val) |
diff --git a/include/asm-powerpc/todc.h b/include/asm-powerpc/todc.h new file mode 100644 index 000000000000..60a8c39b8c11 --- /dev/null +++ b/include/asm-powerpc/todc.h | |||
@@ -0,0 +1,487 @@ | |||
1 | /* | ||
2 | * Definitions for the M48Txx and mc146818 series of Time of day/Real Time | ||
3 | * Clock chips. | ||
4 | * | ||
5 | * Author: Mark A. Greer <mgreer@mvista.com> | ||
6 | * | ||
7 | * 2001 (c) MontaVista, Software, Inc. This file is licensed under | ||
8 | * the terms of the GNU General Public License version 2. This program | ||
9 | * is licensed "as is" without any warranty of any kind, whether express | ||
10 | * or implied. | ||
11 | */ | ||
12 | |||
13 | /* | ||
14 | * Support for the M48T37/M48T59/.../mc146818 Real Time Clock chips. | ||
15 | * Purpose is to make one generic file that handles all of these chips instead | ||
16 | * of every platform implementing the same code over & over again. | ||
17 | */ | ||
18 | |||
19 | #ifndef __PPC_KERNEL_TODC_H | ||
20 | #define __PPC_KERNEL_TODC_H | ||
21 | |||
22 | typedef struct { | ||
23 | uint rtc_type; /* your particular chip */ | ||
24 | |||
25 | /* | ||
26 | * Following are the addresses of the AS0, AS1, and DATA registers | ||
27 | * of these chips. Note that these are board-specific. | ||
28 | */ | ||
29 | unsigned int nvram_as0; | ||
30 | unsigned int nvram_as1; | ||
31 | unsigned int nvram_data; | ||
32 | |||
33 | /* | ||
34 | * Define bits to stop external set of regs from changing so | ||
35 | * the chip can be read/written reliably. | ||
36 | */ | ||
37 | unsigned char enable_read; | ||
38 | unsigned char enable_write; | ||
39 | |||
40 | /* | ||
41 | * Following is the number of AS0 address bits. This is normally | ||
42 | * 8 but some bad hardware routes address lines incorrectly. | ||
43 | */ | ||
44 | int as0_bits; | ||
45 | |||
46 | int nvram_size; /* Size of NVRAM on chip */ | ||
47 | int sw_flags; /* Software control flags */ | ||
48 | |||
49 | /* Following are the register offsets for the particular chip */ | ||
50 | int year; | ||
51 | int month; | ||
52 | int day_of_month; | ||
53 | int day_of_week; | ||
54 | int hours; | ||
55 | int minutes; | ||
56 | int seconds; | ||
57 | int control_b; | ||
58 | int control_a; | ||
59 | int watchdog; | ||
60 | int interrupts; | ||
61 | int alarm_date; | ||
62 | int alarm_hour; | ||
63 | int alarm_minutes; | ||
64 | int alarm_seconds; | ||
65 | int century; | ||
66 | int flags; | ||
67 | |||
68 | /* | ||
69 | * Some RTC chips have their NVRAM buried behind a addr/data pair of | ||
70 | * regs on the first level/clock registers. The following fields | ||
71 | * are the addresses for those addr/data regs. | ||
72 | */ | ||
73 | int nvram_addr_reg; | ||
74 | int nvram_data_reg; | ||
75 | } todc_info_t; | ||
76 | |||
77 | /* | ||
78 | * Define the types of TODC/RTC variants that are supported in | ||
79 | * arch/ppc/kernel/todc_time.c | ||
80 | * Make a new one of these for any chip somehow differs from what's already | ||
81 | * defined. That way, if you ever need to put in code to touch those | ||
82 | * bits/registers in todc_time.c, you can put it inside an | ||
83 | * 'if (todc_info->rtc_type == TODC_TYPE_XXX)' so you won't break | ||
84 | * anyone else. | ||
85 | */ | ||
86 | #define TODC_TYPE_MK48T35 1 | ||
87 | #define TODC_TYPE_MK48T37 2 | ||
88 | #define TODC_TYPE_MK48T59 3 | ||
89 | #define TODC_TYPE_DS1693 4 /* Dallas DS1693 RTC */ | ||
90 | #define TODC_TYPE_DS1743 5 /* Dallas DS1743 RTC */ | ||
91 | #define TODC_TYPE_DS1746 6 /* Dallas DS1746 RTC */ | ||
92 | #define TODC_TYPE_DS1747 7 /* Dallas DS1747 RTC */ | ||
93 | #define TODC_TYPE_DS1501 8 /* Dallas DS1501 RTC */ | ||
94 | #define TODC_TYPE_DS1643 9 /* Dallas DS1643 RTC */ | ||
95 | #define TODC_TYPE_PC97307 10 /* PC97307 internal RTC */ | ||
96 | #define TODC_TYPE_DS1557 11 /* Dallas DS1557 RTC */ | ||
97 | #define TODC_TYPE_DS17285 12 /* Dallas DS17285 RTC */ | ||
98 | #define TODC_TYPE_DS1553 13 /* Dallas DS1553 RTC */ | ||
99 | #define TODC_TYPE_MC146818 100 /* Leave room for m48txx's */ | ||
100 | |||
101 | /* | ||
102 | * Bit to clear/set to enable reads/writes to the chip | ||
103 | */ | ||
104 | #define TODC_MK48TXX_CNTL_A_R 0x40 | ||
105 | #define TODC_MK48TXX_CNTL_A_W 0x80 | ||
106 | #define TODC_MK48TXX_DAY_CB 0x80 | ||
107 | |||
108 | #define TODC_DS1501_CNTL_B_TE 0x80 | ||
109 | |||
110 | /* | ||
111 | * Define flag bits used by todc routines. | ||
112 | */ | ||
113 | #define TODC_FLAG_2_LEVEL_NVRAM 0x00000001 | ||
114 | |||
115 | /* | ||
116 | * Define the values for the various RTC's that should to into the todc_info | ||
117 | * table. | ||
118 | * Note: The XXX_NVRAM_SIZE, XXX_NVRAM_ADDR_REG, and XXX_NVRAM_DATA_REG only | ||
119 | * matter if XXX_SW_FLAGS has TODC_FLAG_2_LEVEL_NVRAM set. | ||
120 | */ | ||
121 | #define TODC_TYPE_MK48T35_NVRAM_SIZE 0x7ff8 | ||
122 | #define TODC_TYPE_MK48T35_SW_FLAGS 0 | ||
123 | #define TODC_TYPE_MK48T35_YEAR 0x7fff | ||
124 | #define TODC_TYPE_MK48T35_MONTH 0x7ffe | ||
125 | #define TODC_TYPE_MK48T35_DOM 0x7ffd /* Day of Month */ | ||
126 | #define TODC_TYPE_MK48T35_DOW 0x7ffc /* Day of Week */ | ||
127 | #define TODC_TYPE_MK48T35_HOURS 0x7ffb | ||
128 | #define TODC_TYPE_MK48T35_MINUTES 0x7ffa | ||
129 | #define TODC_TYPE_MK48T35_SECONDS 0x7ff9 | ||
130 | #define TODC_TYPE_MK48T35_CNTL_B 0x7ff9 | ||
131 | #define TODC_TYPE_MK48T35_CNTL_A 0x7ff8 | ||
132 | #define TODC_TYPE_MK48T35_WATCHDOG 0x0000 | ||
133 | #define TODC_TYPE_MK48T35_INTERRUPTS 0x0000 | ||
134 | #define TODC_TYPE_MK48T35_ALARM_DATE 0x0000 | ||
135 | #define TODC_TYPE_MK48T35_ALARM_HOUR 0x0000 | ||
136 | #define TODC_TYPE_MK48T35_ALARM_MINUTES 0x0000 | ||
137 | #define TODC_TYPE_MK48T35_ALARM_SECONDS 0x0000 | ||
138 | #define TODC_TYPE_MK48T35_CENTURY 0x0000 | ||
139 | #define TODC_TYPE_MK48T35_FLAGS 0x0000 | ||
140 | #define TODC_TYPE_MK48T35_NVRAM_ADDR_REG 0 | ||
141 | #define TODC_TYPE_MK48T35_NVRAM_DATA_REG 0 | ||
142 | |||
143 | #define TODC_TYPE_MK48T37_NVRAM_SIZE 0x7ff0 | ||
144 | #define TODC_TYPE_MK48T37_SW_FLAGS 0 | ||
145 | #define TODC_TYPE_MK48T37_YEAR 0x7fff | ||
146 | #define TODC_TYPE_MK48T37_MONTH 0x7ffe | ||
147 | #define TODC_TYPE_MK48T37_DOM 0x7ffd /* Day of Month */ | ||
148 | #define TODC_TYPE_MK48T37_DOW 0x7ffc /* Day of Week */ | ||
149 | #define TODC_TYPE_MK48T37_HOURS 0x7ffb | ||
150 | #define TODC_TYPE_MK48T37_MINUTES 0x7ffa | ||
151 | #define TODC_TYPE_MK48T37_SECONDS 0x7ff9 | ||
152 | #define TODC_TYPE_MK48T37_CNTL_B 0x7ff9 | ||
153 | #define TODC_TYPE_MK48T37_CNTL_A 0x7ff8 | ||
154 | #define TODC_TYPE_MK48T37_WATCHDOG 0x7ff7 | ||
155 | #define TODC_TYPE_MK48T37_INTERRUPTS 0x7ff6 | ||
156 | #define TODC_TYPE_MK48T37_ALARM_DATE 0x7ff5 | ||
157 | #define TODC_TYPE_MK48T37_ALARM_HOUR 0x7ff4 | ||
158 | #define TODC_TYPE_MK48T37_ALARM_MINUTES 0x7ff3 | ||
159 | #define TODC_TYPE_MK48T37_ALARM_SECONDS 0x7ff2 | ||
160 | #define TODC_TYPE_MK48T37_CENTURY 0x7ff1 | ||
161 | #define TODC_TYPE_MK48T37_FLAGS 0x7ff0 | ||
162 | #define TODC_TYPE_MK48T37_NVRAM_ADDR_REG 0 | ||
163 | #define TODC_TYPE_MK48T37_NVRAM_DATA_REG 0 | ||
164 | |||
165 | #define TODC_TYPE_MK48T59_NVRAM_SIZE 0x1ff0 | ||
166 | #define TODC_TYPE_MK48T59_SW_FLAGS 0 | ||
167 | #define TODC_TYPE_MK48T59_YEAR 0x1fff | ||
168 | #define TODC_TYPE_MK48T59_MONTH 0x1ffe | ||
169 | #define TODC_TYPE_MK48T59_DOM 0x1ffd /* Day of Month */ | ||
170 | #define TODC_TYPE_MK48T59_DOW 0x1ffc /* Day of Week */ | ||
171 | #define TODC_TYPE_MK48T59_HOURS 0x1ffb | ||
172 | #define TODC_TYPE_MK48T59_MINUTES 0x1ffa | ||
173 | #define TODC_TYPE_MK48T59_SECONDS 0x1ff9 | ||
174 | #define TODC_TYPE_MK48T59_CNTL_B 0x1ff9 | ||
175 | #define TODC_TYPE_MK48T59_CNTL_A 0x1ff8 | ||
176 | #define TODC_TYPE_MK48T59_WATCHDOG 0x1fff | ||
177 | #define TODC_TYPE_MK48T59_INTERRUPTS 0x1fff | ||
178 | #define TODC_TYPE_MK48T59_ALARM_DATE 0x1fff | ||
179 | #define TODC_TYPE_MK48T59_ALARM_HOUR 0x1fff | ||
180 | #define TODC_TYPE_MK48T59_ALARM_MINUTES 0x1fff | ||
181 | #define TODC_TYPE_MK48T59_ALARM_SECONDS 0x1fff | ||
182 | #define TODC_TYPE_MK48T59_CENTURY 0x1fff | ||
183 | #define TODC_TYPE_MK48T59_FLAGS 0x1fff | ||
184 | #define TODC_TYPE_MK48T59_NVRAM_ADDR_REG 0 | ||
185 | #define TODC_TYPE_MK48T59_NVRAM_DATA_REG 0 | ||
186 | |||
187 | #define TODC_TYPE_DS1501_NVRAM_SIZE 0x100 | ||
188 | #define TODC_TYPE_DS1501_SW_FLAGS TODC_FLAG_2_LEVEL_NVRAM | ||
189 | #define TODC_TYPE_DS1501_YEAR (TODC_TYPE_DS1501_NVRAM_SIZE + 0x06) | ||
190 | #define TODC_TYPE_DS1501_MONTH (TODC_TYPE_DS1501_NVRAM_SIZE + 0x05) | ||
191 | #define TODC_TYPE_DS1501_DOM (TODC_TYPE_DS1501_NVRAM_SIZE + 0x04) | ||
192 | #define TODC_TYPE_DS1501_DOW (TODC_TYPE_DS1501_NVRAM_SIZE + 0x03) | ||
193 | #define TODC_TYPE_DS1501_HOURS (TODC_TYPE_DS1501_NVRAM_SIZE + 0x02) | ||
194 | #define TODC_TYPE_DS1501_MINUTES (TODC_TYPE_DS1501_NVRAM_SIZE + 0x01) | ||
195 | #define TODC_TYPE_DS1501_SECONDS (TODC_TYPE_DS1501_NVRAM_SIZE + 0x00) | ||
196 | #define TODC_TYPE_DS1501_CNTL_B (TODC_TYPE_DS1501_NVRAM_SIZE + 0x0f) | ||
197 | #define TODC_TYPE_DS1501_CNTL_A (TODC_TYPE_DS1501_NVRAM_SIZE + 0x0f) | ||
198 | #define TODC_TYPE_DS1501_WATCHDOG (TODC_TYPE_DS1501_NVRAM_SIZE + 0xff) | ||
199 | #define TODC_TYPE_DS1501_INTERRUPTS (TODC_TYPE_DS1501_NVRAM_SIZE + 0xff) | ||
200 | #define TODC_TYPE_DS1501_ALARM_DATE (TODC_TYPE_DS1501_NVRAM_SIZE + 0x0b) | ||
201 | #define TODC_TYPE_DS1501_ALARM_HOUR (TODC_TYPE_DS1501_NVRAM_SIZE + 0x0a) | ||
202 | #define TODC_TYPE_DS1501_ALARM_MINUTES (TODC_TYPE_DS1501_NVRAM_SIZE + 0x09) | ||
203 | #define TODC_TYPE_DS1501_ALARM_SECONDS (TODC_TYPE_DS1501_NVRAM_SIZE + 0x08) | ||
204 | #define TODC_TYPE_DS1501_CENTURY (TODC_TYPE_DS1501_NVRAM_SIZE + 0x07) | ||
205 | #define TODC_TYPE_DS1501_FLAGS (TODC_TYPE_DS1501_NVRAM_SIZE + 0xff) | ||
206 | #define TODC_TYPE_DS1501_NVRAM_ADDR_REG 0x10 | ||
207 | #define TODC_TYPE_DS1501_NVRAM_DATA_REG 0x13 | ||
208 | |||
209 | #define TODC_TYPE_DS1553_NVRAM_SIZE 0x1ff0 | ||
210 | #define TODC_TYPE_DS1553_SW_FLAGS 0 | ||
211 | #define TODC_TYPE_DS1553_YEAR 0x1fff | ||
212 | #define TODC_TYPE_DS1553_MONTH 0x1ffe | ||
213 | #define TODC_TYPE_DS1553_DOM 0x1ffd /* Day of Month */ | ||
214 | #define TODC_TYPE_DS1553_DOW 0x1ffc /* Day of Week */ | ||
215 | #define TODC_TYPE_DS1553_HOURS 0x1ffb | ||
216 | #define TODC_TYPE_DS1553_MINUTES 0x1ffa | ||
217 | #define TODC_TYPE_DS1553_SECONDS 0x1ff9 | ||
218 | #define TODC_TYPE_DS1553_CNTL_B 0x1ff9 | ||
219 | #define TODC_TYPE_DS1553_CNTL_A 0x1ff8 /* control_a R/W regs */ | ||
220 | #define TODC_TYPE_DS1553_WATCHDOG 0x1ff7 | ||
221 | #define TODC_TYPE_DS1553_INTERRUPTS 0x1ff6 | ||
222 | #define TODC_TYPE_DS1553_ALARM_DATE 0x1ff5 | ||
223 | #define TODC_TYPE_DS1553_ALARM_HOUR 0x1ff4 | ||
224 | #define TODC_TYPE_DS1553_ALARM_MINUTES 0x1ff3 | ||
225 | #define TODC_TYPE_DS1553_ALARM_SECONDS 0x1ff2 | ||
226 | #define TODC_TYPE_DS1553_CENTURY 0x1ff8 | ||
227 | #define TODC_TYPE_DS1553_FLAGS 0x1ff0 | ||
228 | #define TODC_TYPE_DS1553_NVRAM_ADDR_REG 0 | ||
229 | #define TODC_TYPE_DS1553_NVRAM_DATA_REG 0 | ||
230 | |||
231 | #define TODC_TYPE_DS1557_NVRAM_SIZE 0x7fff0 | ||
232 | #define TODC_TYPE_DS1557_SW_FLAGS 0 | ||
233 | #define TODC_TYPE_DS1557_YEAR 0x7ffff | ||
234 | #define TODC_TYPE_DS1557_MONTH 0x7fffe | ||
235 | #define TODC_TYPE_DS1557_DOM 0x7fffd /* Day of Month */ | ||
236 | #define TODC_TYPE_DS1557_DOW 0x7fffc /* Day of Week */ | ||
237 | #define TODC_TYPE_DS1557_HOURS 0x7fffb | ||
238 | #define TODC_TYPE_DS1557_MINUTES 0x7fffa | ||
239 | #define TODC_TYPE_DS1557_SECONDS 0x7fff9 | ||
240 | #define TODC_TYPE_DS1557_CNTL_B 0x7fff9 | ||
241 | #define TODC_TYPE_DS1557_CNTL_A 0x7fff8 /* control_a R/W regs */ | ||
242 | #define TODC_TYPE_DS1557_WATCHDOG 0x7fff7 | ||
243 | #define TODC_TYPE_DS1557_INTERRUPTS 0x7fff6 | ||
244 | #define TODC_TYPE_DS1557_ALARM_DATE 0x7fff5 | ||
245 | #define TODC_TYPE_DS1557_ALARM_HOUR 0x7fff4 | ||
246 | #define TODC_TYPE_DS1557_ALARM_MINUTES 0x7fff3 | ||
247 | #define TODC_TYPE_DS1557_ALARM_SECONDS 0x7fff2 | ||
248 | #define TODC_TYPE_DS1557_CENTURY 0x7fff8 | ||
249 | #define TODC_TYPE_DS1557_FLAGS 0x7fff0 | ||
250 | #define TODC_TYPE_DS1557_NVRAM_ADDR_REG 0 | ||
251 | #define TODC_TYPE_DS1557_NVRAM_DATA_REG 0 | ||
252 | |||
253 | #define TODC_TYPE_DS1643_NVRAM_SIZE 0x1ff8 | ||
254 | #define TODC_TYPE_DS1643_SW_FLAGS 0 | ||
255 | #define TODC_TYPE_DS1643_YEAR 0x1fff | ||
256 | #define TODC_TYPE_DS1643_MONTH 0x1ffe | ||
257 | #define TODC_TYPE_DS1643_DOM 0x1ffd /* Day of Month */ | ||
258 | #define TODC_TYPE_DS1643_DOW 0x1ffc /* Day of Week */ | ||
259 | #define TODC_TYPE_DS1643_HOURS 0x1ffb | ||
260 | #define TODC_TYPE_DS1643_MINUTES 0x1ffa | ||
261 | #define TODC_TYPE_DS1643_SECONDS 0x1ff9 | ||
262 | #define TODC_TYPE_DS1643_CNTL_B 0x1ff9 | ||
263 | #define TODC_TYPE_DS1643_CNTL_A 0x1ff8 /* control_a R/W regs */ | ||
264 | #define TODC_TYPE_DS1643_WATCHDOG 0x1fff | ||
265 | #define TODC_TYPE_DS1643_INTERRUPTS 0x1fff | ||
266 | #define TODC_TYPE_DS1643_ALARM_DATE 0x1fff | ||
267 | #define TODC_TYPE_DS1643_ALARM_HOUR 0x1fff | ||
268 | #define TODC_TYPE_DS1643_ALARM_MINUTES 0x1fff | ||
269 | #define TODC_TYPE_DS1643_ALARM_SECONDS 0x1fff | ||
270 | #define TODC_TYPE_DS1643_CENTURY 0x1ff8 | ||
271 | #define TODC_TYPE_DS1643_FLAGS 0x1fff | ||
272 | #define TODC_TYPE_DS1643_NVRAM_ADDR_REG 0 | ||
273 | #define TODC_TYPE_DS1643_NVRAM_DATA_REG 0 | ||
274 | |||
275 | #define TODC_TYPE_DS1693_NVRAM_SIZE 0 /* Not handled yet */ | ||
276 | #define TODC_TYPE_DS1693_SW_FLAGS 0 | ||
277 | #define TODC_TYPE_DS1693_YEAR 0x09 | ||
278 | #define TODC_TYPE_DS1693_MONTH 0x08 | ||
279 | #define TODC_TYPE_DS1693_DOM 0x07 /* Day of Month */ | ||
280 | #define TODC_TYPE_DS1693_DOW 0x06 /* Day of Week */ | ||
281 | #define TODC_TYPE_DS1693_HOURS 0x04 | ||
282 | #define TODC_TYPE_DS1693_MINUTES 0x02 | ||
283 | #define TODC_TYPE_DS1693_SECONDS 0x00 | ||
284 | #define TODC_TYPE_DS1693_CNTL_B 0x0b | ||
285 | #define TODC_TYPE_DS1693_CNTL_A 0x0a | ||
286 | #define TODC_TYPE_DS1693_WATCHDOG 0xff | ||
287 | #define TODC_TYPE_DS1693_INTERRUPTS 0xff | ||
288 | #define TODC_TYPE_DS1693_ALARM_DATE 0x49 | ||
289 | #define TODC_TYPE_DS1693_ALARM_HOUR 0x05 | ||
290 | #define TODC_TYPE_DS1693_ALARM_MINUTES 0x03 | ||
291 | #define TODC_TYPE_DS1693_ALARM_SECONDS 0x01 | ||
292 | #define TODC_TYPE_DS1693_CENTURY 0x48 | ||
293 | #define TODC_TYPE_DS1693_FLAGS 0xff | ||
294 | #define TODC_TYPE_DS1693_NVRAM_ADDR_REG 0 | ||
295 | #define TODC_TYPE_DS1693_NVRAM_DATA_REG 0 | ||
296 | |||
297 | #define TODC_TYPE_DS1743_NVRAM_SIZE 0x1ff8 | ||
298 | #define TODC_TYPE_DS1743_SW_FLAGS 0 | ||
299 | #define TODC_TYPE_DS1743_YEAR 0x1fff | ||
300 | #define TODC_TYPE_DS1743_MONTH 0x1ffe | ||
301 | #define TODC_TYPE_DS1743_DOM 0x1ffd /* Day of Month */ | ||
302 | #define TODC_TYPE_DS1743_DOW 0x1ffc /* Day of Week */ | ||
303 | #define TODC_TYPE_DS1743_HOURS 0x1ffb | ||
304 | #define TODC_TYPE_DS1743_MINUTES 0x1ffa | ||
305 | #define TODC_TYPE_DS1743_SECONDS 0x1ff9 | ||
306 | #define TODC_TYPE_DS1743_CNTL_B 0x1ff9 | ||
307 | #define TODC_TYPE_DS1743_CNTL_A 0x1ff8 /* control_a R/W regs */ | ||
308 | #define TODC_TYPE_DS1743_WATCHDOG 0x1fff | ||
309 | #define TODC_TYPE_DS1743_INTERRUPTS 0x1fff | ||
310 | #define TODC_TYPE_DS1743_ALARM_DATE 0x1fff | ||
311 | #define TODC_TYPE_DS1743_ALARM_HOUR 0x1fff | ||
312 | #define TODC_TYPE_DS1743_ALARM_MINUTES 0x1fff | ||
313 | #define TODC_TYPE_DS1743_ALARM_SECONDS 0x1fff | ||
314 | #define TODC_TYPE_DS1743_CENTURY 0x1ff8 | ||
315 | #define TODC_TYPE_DS1743_FLAGS 0x1fff | ||
316 | #define TODC_TYPE_DS1743_NVRAM_ADDR_REG 0 | ||
317 | #define TODC_TYPE_DS1743_NVRAM_DATA_REG 0 | ||
318 | |||
319 | #define TODC_TYPE_DS1746_NVRAM_SIZE 0x1fff8 | ||
320 | #define TODC_TYPE_DS1746_SW_FLAGS 0 | ||
321 | #define TODC_TYPE_DS1746_YEAR 0x1ffff | ||
322 | #define TODC_TYPE_DS1746_MONTH 0x1fffe | ||
323 | #define TODC_TYPE_DS1746_DOM 0x1fffd /* Day of Month */ | ||
324 | #define TODC_TYPE_DS1746_DOW 0x1fffc /* Day of Week */ | ||
325 | #define TODC_TYPE_DS1746_HOURS 0x1fffb | ||
326 | #define TODC_TYPE_DS1746_MINUTES 0x1fffa | ||
327 | #define TODC_TYPE_DS1746_SECONDS 0x1fff9 | ||
328 | #define TODC_TYPE_DS1746_CNTL_B 0x1fff9 | ||
329 | #define TODC_TYPE_DS1746_CNTL_A 0x1fff8 /* control_a R/W regs */ | ||
330 | #define TODC_TYPE_DS1746_WATCHDOG 0x00000 | ||
331 | #define TODC_TYPE_DS1746_INTERRUPTS 0x00000 | ||
332 | #define TODC_TYPE_DS1746_ALARM_DATE 0x00000 | ||
333 | #define TODC_TYPE_DS1746_ALARM_HOUR 0x00000 | ||
334 | #define TODC_TYPE_DS1746_ALARM_MINUTES 0x00000 | ||
335 | #define TODC_TYPE_DS1746_ALARM_SECONDS 0x00000 | ||
336 | #define TODC_TYPE_DS1746_CENTURY 0x00000 | ||
337 | #define TODC_TYPE_DS1746_FLAGS 0x00000 | ||
338 | #define TODC_TYPE_DS1746_NVRAM_ADDR_REG 0 | ||
339 | #define TODC_TYPE_DS1746_NVRAM_DATA_REG 0 | ||
340 | |||
341 | #define TODC_TYPE_DS1747_NVRAM_SIZE 0x7fff8 | ||
342 | #define TODC_TYPE_DS1747_SW_FLAGS 0 | ||
343 | #define TODC_TYPE_DS1747_YEAR 0x7ffff | ||
344 | #define TODC_TYPE_DS1747_MONTH 0x7fffe | ||
345 | #define TODC_TYPE_DS1747_DOM 0x7fffd /* Day of Month */ | ||
346 | #define TODC_TYPE_DS1747_DOW 0x7fffc /* Day of Week */ | ||
347 | #define TODC_TYPE_DS1747_HOURS 0x7fffb | ||
348 | #define TODC_TYPE_DS1747_MINUTES 0x7fffa | ||
349 | #define TODC_TYPE_DS1747_SECONDS 0x7fff9 | ||
350 | #define TODC_TYPE_DS1747_CNTL_B 0x7fff9 | ||
351 | #define TODC_TYPE_DS1747_CNTL_A 0x7fff8 /* control_a R/W regs */ | ||
352 | #define TODC_TYPE_DS1747_WATCHDOG 0x00000 | ||
353 | #define TODC_TYPE_DS1747_INTERRUPTS 0x00000 | ||
354 | #define TODC_TYPE_DS1747_ALARM_DATE 0x00000 | ||
355 | #define TODC_TYPE_DS1747_ALARM_HOUR 0x00000 | ||
356 | #define TODC_TYPE_DS1747_ALARM_MINUTES 0x00000 | ||
357 | #define TODC_TYPE_DS1747_ALARM_SECONDS 0x00000 | ||
358 | #define TODC_TYPE_DS1747_CENTURY 0x00000 | ||
359 | #define TODC_TYPE_DS1747_FLAGS 0x00000 | ||
360 | #define TODC_TYPE_DS1747_NVRAM_ADDR_REG 0 | ||
361 | #define TODC_TYPE_DS1747_NVRAM_DATA_REG 0 | ||
362 | |||
363 | #define TODC_TYPE_DS17285_NVRAM_SIZE (0x1000-0x80) /* 4Kx8 NVRAM (minus RTC regs) */ | ||
364 | #define TODC_TYPE_DS17285_SW_FLAGS TODC_FLAG_2_LEVEL_NVRAM | ||
365 | #define TODC_TYPE_DS17285_SECONDS (TODC_TYPE_DS17285_NVRAM_SIZE + 0x00) | ||
366 | #define TODC_TYPE_DS17285_ALARM_SECONDS (TODC_TYPE_DS17285_NVRAM_SIZE + 0x01) | ||
367 | #define TODC_TYPE_DS17285_MINUTES (TODC_TYPE_DS17285_NVRAM_SIZE + 0x02) | ||
368 | #define TODC_TYPE_DS17285_ALARM_MINUTES (TODC_TYPE_DS17285_NVRAM_SIZE + 0x03) | ||
369 | #define TODC_TYPE_DS17285_HOURS (TODC_TYPE_DS17285_NVRAM_SIZE + 0x04) | ||
370 | #define TODC_TYPE_DS17285_ALARM_HOUR (TODC_TYPE_DS17285_NVRAM_SIZE + 0x05) | ||
371 | #define TODC_TYPE_DS17285_DOW (TODC_TYPE_DS17285_NVRAM_SIZE + 0x06) | ||
372 | #define TODC_TYPE_DS17285_DOM (TODC_TYPE_DS17285_NVRAM_SIZE + 0x07) | ||
373 | #define TODC_TYPE_DS17285_MONTH (TODC_TYPE_DS17285_NVRAM_SIZE + 0x08) | ||
374 | #define TODC_TYPE_DS17285_YEAR (TODC_TYPE_DS17285_NVRAM_SIZE + 0x09) | ||
375 | #define TODC_TYPE_DS17285_CNTL_A (TODC_TYPE_DS17285_NVRAM_SIZE + 0x0A) | ||
376 | #define TODC_TYPE_DS17285_CNTL_B (TODC_TYPE_DS17285_NVRAM_SIZE + 0x0B) | ||
377 | #define TODC_TYPE_DS17285_CNTL_C (TODC_TYPE_DS17285_NVRAM_SIZE + 0x0C) | ||
378 | #define TODC_TYPE_DS17285_CNTL_D (TODC_TYPE_DS17285_NVRAM_SIZE + 0x0D) | ||
379 | #define TODC_TYPE_DS17285_WATCHDOG 0 | ||
380 | #define TODC_TYPE_DS17285_INTERRUPTS 0 | ||
381 | #define TODC_TYPE_DS17285_ALARM_DATE 0 | ||
382 | #define TODC_TYPE_DS17285_CENTURY 0 | ||
383 | #define TODC_TYPE_DS17285_FLAGS 0 | ||
384 | #define TODC_TYPE_DS17285_NVRAM_ADDR_REG 0x50 | ||
385 | #define TODC_TYPE_DS17285_NVRAM_DATA_REG 0x53 | ||
386 | |||
387 | #define TODC_TYPE_MC146818_NVRAM_SIZE 0 /* XXXX */ | ||
388 | #define TODC_TYPE_MC146818_SW_FLAGS 0 | ||
389 | #define TODC_TYPE_MC146818_YEAR 0x09 | ||
390 | #define TODC_TYPE_MC146818_MONTH 0x08 | ||
391 | #define TODC_TYPE_MC146818_DOM 0x07 /* Day of Month */ | ||
392 | #define TODC_TYPE_MC146818_DOW 0x06 /* Day of Week */ | ||
393 | #define TODC_TYPE_MC146818_HOURS 0x04 | ||
394 | #define TODC_TYPE_MC146818_MINUTES 0x02 | ||
395 | #define TODC_TYPE_MC146818_SECONDS 0x00 | ||
396 | #define TODC_TYPE_MC146818_CNTL_B 0x0a | ||
397 | #define TODC_TYPE_MC146818_CNTL_A 0x0b /* control_a R/W regs */ | ||
398 | #define TODC_TYPE_MC146818_WATCHDOG 0 | ||
399 | #define TODC_TYPE_MC146818_INTERRUPTS 0x0c | ||
400 | #define TODC_TYPE_MC146818_ALARM_DATE 0xff | ||
401 | #define TODC_TYPE_MC146818_ALARM_HOUR 0x05 | ||
402 | #define TODC_TYPE_MC146818_ALARM_MINUTES 0x03 | ||
403 | #define TODC_TYPE_MC146818_ALARM_SECONDS 0x01 | ||
404 | #define TODC_TYPE_MC146818_CENTURY 0xff | ||
405 | #define TODC_TYPE_MC146818_FLAGS 0xff | ||
406 | #define TODC_TYPE_MC146818_NVRAM_ADDR_REG 0 | ||
407 | #define TODC_TYPE_MC146818_NVRAM_DATA_REG 0 | ||
408 | |||
409 | #define TODC_TYPE_PC97307_NVRAM_SIZE 0 /* No NVRAM? */ | ||
410 | #define TODC_TYPE_PC97307_SW_FLAGS 0 | ||
411 | #define TODC_TYPE_PC97307_YEAR 0x09 | ||
412 | #define TODC_TYPE_PC97307_MONTH 0x08 | ||
413 | #define TODC_TYPE_PC97307_DOM 0x07 /* Day of Month */ | ||
414 | #define TODC_TYPE_PC97307_DOW 0x06 /* Day of Week */ | ||
415 | #define TODC_TYPE_PC97307_HOURS 0x04 | ||
416 | #define TODC_TYPE_PC97307_MINUTES 0x02 | ||
417 | #define TODC_TYPE_PC97307_SECONDS 0x00 | ||
418 | #define TODC_TYPE_PC97307_CNTL_B 0x0a | ||
419 | #define TODC_TYPE_PC97307_CNTL_A 0x0b /* control_a R/W regs */ | ||
420 | #define TODC_TYPE_PC97307_WATCHDOG 0x0c | ||
421 | #define TODC_TYPE_PC97307_INTERRUPTS 0x0d | ||
422 | #define TODC_TYPE_PC97307_ALARM_DATE 0xff | ||
423 | #define TODC_TYPE_PC97307_ALARM_HOUR 0x05 | ||
424 | #define TODC_TYPE_PC97307_ALARM_MINUTES 0x03 | ||
425 | #define TODC_TYPE_PC97307_ALARM_SECONDS 0x01 | ||
426 | #define TODC_TYPE_PC97307_CENTURY 0xff | ||
427 | #define TODC_TYPE_PC97307_FLAGS 0xff | ||
428 | #define TODC_TYPE_PC97307_NVRAM_ADDR_REG 0 | ||
429 | #define TODC_TYPE_PC97307_NVRAM_DATA_REG 0 | ||
430 | |||
431 | /* | ||
432 | * Define macros to allocate and init the todc_info_t table that will | ||
433 | * be used by the todc_time.c routines. | ||
434 | */ | ||
435 | #define TODC_ALLOC() \ | ||
436 | static todc_info_t todc_info_alloc; \ | ||
437 | todc_info_t *todc_info = &todc_info_alloc; | ||
438 | |||
439 | #define TODC_INIT(clock_type, as0, as1, data, bits) { \ | ||
440 | todc_info->rtc_type = clock_type; \ | ||
441 | \ | ||
442 | todc_info->nvram_as0 = (unsigned int)(as0); \ | ||
443 | todc_info->nvram_as1 = (unsigned int)(as1); \ | ||
444 | todc_info->nvram_data = (unsigned int)(data); \ | ||
445 | \ | ||
446 | todc_info->as0_bits = (bits); \ | ||
447 | \ | ||
448 | todc_info->nvram_size = clock_type ##_NVRAM_SIZE; \ | ||
449 | todc_info->sw_flags = clock_type ##_SW_FLAGS; \ | ||
450 | \ | ||
451 | todc_info->year = clock_type ##_YEAR; \ | ||
452 | todc_info->month = clock_type ##_MONTH; \ | ||
453 | todc_info->day_of_month = clock_type ##_DOM; \ | ||
454 | todc_info->day_of_week = clock_type ##_DOW; \ | ||
455 | todc_info->hours = clock_type ##_HOURS; \ | ||
456 | todc_info->minutes = clock_type ##_MINUTES; \ | ||
457 | todc_info->seconds = clock_type ##_SECONDS; \ | ||
458 | todc_info->control_b = clock_type ##_CNTL_B; \ | ||
459 | todc_info->control_a = clock_type ##_CNTL_A; \ | ||
460 | todc_info->watchdog = clock_type ##_WATCHDOG; \ | ||
461 | todc_info->interrupts = clock_type ##_INTERRUPTS; \ | ||
462 | todc_info->alarm_date = clock_type ##_ALARM_DATE; \ | ||
463 | todc_info->alarm_hour = clock_type ##_ALARM_HOUR; \ | ||
464 | todc_info->alarm_minutes = clock_type ##_ALARM_MINUTES; \ | ||
465 | todc_info->alarm_seconds = clock_type ##_ALARM_SECONDS; \ | ||
466 | todc_info->century = clock_type ##_CENTURY; \ | ||
467 | todc_info->flags = clock_type ##_FLAGS; \ | ||
468 | \ | ||
469 | todc_info->nvram_addr_reg = clock_type ##_NVRAM_ADDR_REG; \ | ||
470 | todc_info->nvram_data_reg = clock_type ##_NVRAM_DATA_REG; \ | ||
471 | } | ||
472 | |||
473 | extern todc_info_t *todc_info; | ||
474 | |||
475 | unsigned char todc_direct_read_val(int addr); | ||
476 | void todc_direct_write_val(int addr, unsigned char val); | ||
477 | unsigned char todc_m48txx_read_val(int addr); | ||
478 | void todc_m48txx_write_val(int addr, unsigned char val); | ||
479 | unsigned char todc_mc146818_read_val(int addr); | ||
480 | void todc_mc146818_write_val(int addr, unsigned char val); | ||
481 | |||
482 | long todc_time_init(void); | ||
483 | void todc_get_rtc_time(struct rtc_time *); | ||
484 | int todc_set_rtc_time(struct rtc_time *); | ||
485 | void todc_calibrate_decr(void); | ||
486 | |||
487 | #endif /* __PPC_KERNEL_TODC_H */ | ||
diff --git a/include/asm-powerpc/tsi108.h b/include/asm-powerpc/tsi108.h new file mode 100644 index 000000000000..c4c278d72f71 --- /dev/null +++ b/include/asm-powerpc/tsi108.h | |||
@@ -0,0 +1,109 @@ | |||
1 | /* | ||
2 | * include/asm-ppc/tsi108.h | ||
3 | * | ||
4 | * common routine and memory layout for Tundra TSI108(Grendel) host bridge | ||
5 | * memory controller. | ||
6 | * | ||
7 | * Author: Jacob Pan (jacob.pan@freescale.com) | ||
8 | * Alex Bounine (alexandreb@tundra.com) | ||
9 | * 2004 (c) Freescale Semiconductor Inc. This file is licensed under | ||
10 | * the terms of the GNU General Public License version 2. This program | ||
11 | * is licensed "as is" without any warranty of any kind, whether express | ||
12 | * or implied. | ||
13 | */ | ||
14 | #ifndef __PPC_KERNEL_TSI108_H | ||
15 | #define __PPC_KERNEL_TSI108_H | ||
16 | |||
17 | #include <asm/pci-bridge.h> | ||
18 | |||
19 | /* Size of entire register space */ | ||
20 | #define TSI108_REG_SIZE (0x10000) | ||
21 | |||
22 | /* Sizes of register spaces for individual blocks */ | ||
23 | #define TSI108_HLP_SIZE 0x1000 | ||
24 | #define TSI108_PCI_SIZE 0x1000 | ||
25 | #define TSI108_CLK_SIZE 0x1000 | ||
26 | #define TSI108_PB_SIZE 0x1000 | ||
27 | #define TSI108_SD_SIZE 0x1000 | ||
28 | #define TSI108_DMA_SIZE 0x1000 | ||
29 | #define TSI108_ETH_SIZE 0x1000 | ||
30 | #define TSI108_I2C_SIZE 0x400 | ||
31 | #define TSI108_MPIC_SIZE 0x400 | ||
32 | #define TSI108_UART0_SIZE 0x200 | ||
33 | #define TSI108_GPIO_SIZE 0x200 | ||
34 | #define TSI108_UART1_SIZE 0x200 | ||
35 | |||
36 | /* Offsets within Tsi108(A) CSR space for individual blocks */ | ||
37 | #define TSI108_HLP_OFFSET 0x0000 | ||
38 | #define TSI108_PCI_OFFSET 0x1000 | ||
39 | #define TSI108_CLK_OFFSET 0x2000 | ||
40 | #define TSI108_PB_OFFSET 0x3000 | ||
41 | #define TSI108_SD_OFFSET 0x4000 | ||
42 | #define TSI108_DMA_OFFSET 0x5000 | ||
43 | #define TSI108_ETH_OFFSET 0x6000 | ||
44 | #define TSI108_I2C_OFFSET 0x7000 | ||
45 | #define TSI108_MPIC_OFFSET 0x7400 | ||
46 | #define TSI108_UART0_OFFSET 0x7800 | ||
47 | #define TSI108_GPIO_OFFSET 0x7A00 | ||
48 | #define TSI108_UART1_OFFSET 0x7C00 | ||
49 | |||
50 | /* Tsi108 registers used by common code components */ | ||
51 | #define TSI108_PCI_CSR (0x004) | ||
52 | #define TSI108_PCI_IRP_CFG_CTL (0x180) | ||
53 | #define TSI108_PCI_IRP_STAT (0x184) | ||
54 | #define TSI108_PCI_IRP_ENABLE (0x188) | ||
55 | #define TSI108_PCI_IRP_INTAD (0x18C) | ||
56 | |||
57 | #define TSI108_PCI_IRP_STAT_P_INT (0x00400000) | ||
58 | #define TSI108_PCI_IRP_ENABLE_P_INT (0x00400000) | ||
59 | |||
60 | #define TSI108_CG_PWRUP_STATUS (0x234) | ||
61 | |||
62 | #define TSI108_PB_ISR (0x00C) | ||
63 | #define TSI108_PB_ERRCS (0x404) | ||
64 | #define TSI108_PB_AERR (0x408) | ||
65 | |||
66 | #define TSI108_PB_ERRCS_ES (1 << 1) | ||
67 | #define TSI108_PB_ISR_PBS_RD_ERR (1 << 8) | ||
68 | |||
69 | #define TSI108_PCI_CFG_BASE_PHYS (0xfb000000) | ||
70 | #define TSI108_PCI_CFG_SIZE (0x01000000) | ||
71 | /* Global variables */ | ||
72 | |||
73 | extern u32 tsi108_pci_cfg_base; | ||
74 | /* Exported functions */ | ||
75 | |||
76 | extern int tsi108_bridge_init(struct pci_controller *hose, uint phys_csr_base); | ||
77 | extern unsigned long tsi108_get_mem_size(void); | ||
78 | extern unsigned long tsi108_get_cpu_clk(void); | ||
79 | extern unsigned long tsi108_get_sdc_clk(void); | ||
80 | extern int tsi108_direct_write_config(struct pci_bus *bus, unsigned int devfn, | ||
81 | int offset, int len, u32 val); | ||
82 | extern int tsi108_direct_read_config(struct pci_bus *bus, unsigned int devfn, | ||
83 | int offset, int len, u32 * val); | ||
84 | extern void tsi108_clear_pci_error(u32 pci_cfg_base); | ||
85 | |||
86 | extern phys_addr_t get_csrbase(void); | ||
87 | |||
88 | typedef struct { | ||
89 | u32 regs; /* hw registers base address */ | ||
90 | u32 phyregs; /* phy registers base address */ | ||
91 | u16 phy; /* phy address */ | ||
92 | u16 irq_num; /* irq number */ | ||
93 | u8 mac_addr[6]; /* phy mac address */ | ||
94 | } hw_info; | ||
95 | |||
96 | extern u32 get_vir_csrbase(void); | ||
97 | extern u32 tsi108_csr_vir_base; | ||
98 | |||
99 | extern inline u32 tsi108_read_reg(u32 reg_offset) | ||
100 | { | ||
101 | return in_be32((volatile u32 *)(tsi108_csr_vir_base + reg_offset)); | ||
102 | } | ||
103 | |||
104 | extern inline void tsi108_write_reg(u32 reg_offset, u32 val) | ||
105 | { | ||
106 | out_be32((volatile u32 *)(tsi108_csr_vir_base + reg_offset), val); | ||
107 | } | ||
108 | |||
109 | #endif /* __PPC_KERNEL_TSI108_H */ | ||
diff --git a/include/asm-powerpc/udbg.h b/include/asm-powerpc/udbg.h index 19a1517ac43b..55e57844fa78 100644 --- a/include/asm-powerpc/udbg.h +++ b/include/asm-powerpc/udbg.h | |||
@@ -42,7 +42,8 @@ extern void __init udbg_init_debug_lpar(void); | |||
42 | extern void __init udbg_init_pmac_realmode(void); | 42 | extern void __init udbg_init_pmac_realmode(void); |
43 | extern void __init udbg_init_maple_realmode(void); | 43 | extern void __init udbg_init_maple_realmode(void); |
44 | extern void __init udbg_init_iseries(void); | 44 | extern void __init udbg_init_iseries(void); |
45 | extern void __init udbg_init_rtas(void); | 45 | extern void __init udbg_init_rtas_panel(void); |
46 | extern void __init udbg_init_rtas_console(void); | ||
46 | 47 | ||
47 | #endif /* __KERNEL__ */ | 48 | #endif /* __KERNEL__ */ |
48 | #endif /* _ASM_POWERPC_UDBG_H */ | 49 | #endif /* _ASM_POWERPC_UDBG_H */ |
diff --git a/include/asm-ppc/pci.h b/include/asm-ppc/pci.h index 61434edbad7b..11ffaaa5da16 100644 --- a/include/asm-ppc/pci.h +++ b/include/asm-ppc/pci.h | |||
@@ -133,7 +133,7 @@ extern pgprot_t pci_phys_mem_access_prot(struct file *file, | |||
133 | #define HAVE_ARCH_PCI_RESOURCE_TO_USER | 133 | #define HAVE_ARCH_PCI_RESOURCE_TO_USER |
134 | extern void pci_resource_to_user(const struct pci_dev *dev, int bar, | 134 | extern void pci_resource_to_user(const struct pci_dev *dev, int bar, |
135 | const struct resource *rsrc, | 135 | const struct resource *rsrc, |
136 | u64 *start, u64 *end); | 136 | resource_size_t *start, resource_size_t *end); |
137 | 137 | ||
138 | 138 | ||
139 | #endif /* __KERNEL__ */ | 139 | #endif /* __KERNEL__ */ |
diff --git a/include/asm-s390/bitops.h b/include/asm-s390/bitops.h index 4d2b126ba159..0ddcdba79e4a 100644 --- a/include/asm-s390/bitops.h +++ b/include/asm-s390/bitops.h | |||
@@ -12,6 +12,9 @@ | |||
12 | * Copyright (C) 1992, Linus Torvalds | 12 | * Copyright (C) 1992, Linus Torvalds |
13 | * | 13 | * |
14 | */ | 14 | */ |
15 | |||
16 | #ifdef __KERNEL__ | ||
17 | |||
15 | #include <linux/compiler.h> | 18 | #include <linux/compiler.h> |
16 | 19 | ||
17 | /* | 20 | /* |
@@ -50,19 +53,6 @@ | |||
50 | * with operation of the form "set_bit(bitnr, flags)". | 53 | * with operation of the form "set_bit(bitnr, flags)". |
51 | */ | 54 | */ |
52 | 55 | ||
53 | /* set ALIGN_CS to 1 if the SMP safe bit operations should | ||
54 | * align the address to 4 byte boundary. It seems to work | ||
55 | * without the alignment. | ||
56 | */ | ||
57 | #ifdef __KERNEL__ | ||
58 | #define ALIGN_CS 0 | ||
59 | #else | ||
60 | #define ALIGN_CS 1 | ||
61 | #ifndef CONFIG_SMP | ||
62 | #error "bitops won't work without CONFIG_SMP" | ||
63 | #endif | ||
64 | #endif | ||
65 | |||
66 | /* bitmap tables from arch/S390/kernel/bitmap.S */ | 56 | /* bitmap tables from arch/S390/kernel/bitmap.S */ |
67 | extern const char _oi_bitmap[]; | 57 | extern const char _oi_bitmap[]; |
68 | extern const char _ni_bitmap[]; | 58 | extern const char _ni_bitmap[]; |
@@ -121,10 +111,6 @@ static inline void set_bit_cs(unsigned long nr, volatile unsigned long *ptr) | |||
121 | unsigned long addr, old, new, mask; | 111 | unsigned long addr, old, new, mask; |
122 | 112 | ||
123 | addr = (unsigned long) ptr; | 113 | addr = (unsigned long) ptr; |
124 | #if ALIGN_CS == 1 | ||
125 | nr += (addr & __BITOPS_ALIGN) << 3; /* add alignment to bit number */ | ||
126 | addr ^= addr & __BITOPS_ALIGN; /* align address to 8 */ | ||
127 | #endif | ||
128 | /* calculate address for CS */ | 114 | /* calculate address for CS */ |
129 | addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; | 115 | addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; |
130 | /* make OR mask */ | 116 | /* make OR mask */ |
@@ -141,10 +127,6 @@ static inline void clear_bit_cs(unsigned long nr, volatile unsigned long *ptr) | |||
141 | unsigned long addr, old, new, mask; | 127 | unsigned long addr, old, new, mask; |
142 | 128 | ||
143 | addr = (unsigned long) ptr; | 129 | addr = (unsigned long) ptr; |
144 | #if ALIGN_CS == 1 | ||
145 | nr += (addr & __BITOPS_ALIGN) << 3; /* add alignment to bit number */ | ||
146 | addr ^= addr & __BITOPS_ALIGN; /* align address to 8 */ | ||
147 | #endif | ||
148 | /* calculate address for CS */ | 130 | /* calculate address for CS */ |
149 | addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; | 131 | addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; |
150 | /* make AND mask */ | 132 | /* make AND mask */ |
@@ -161,10 +143,6 @@ static inline void change_bit_cs(unsigned long nr, volatile unsigned long *ptr) | |||
161 | unsigned long addr, old, new, mask; | 143 | unsigned long addr, old, new, mask; |
162 | 144 | ||
163 | addr = (unsigned long) ptr; | 145 | addr = (unsigned long) ptr; |
164 | #if ALIGN_CS == 1 | ||
165 | nr += (addr & __BITOPS_ALIGN) << 3; /* add alignment to bit number */ | ||
166 | addr ^= addr & __BITOPS_ALIGN; /* align address to 8 */ | ||
167 | #endif | ||
168 | /* calculate address for CS */ | 146 | /* calculate address for CS */ |
169 | addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; | 147 | addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; |
170 | /* make XOR mask */ | 148 | /* make XOR mask */ |
@@ -182,10 +160,6 @@ test_and_set_bit_cs(unsigned long nr, volatile unsigned long *ptr) | |||
182 | unsigned long addr, old, new, mask; | 160 | unsigned long addr, old, new, mask; |
183 | 161 | ||
184 | addr = (unsigned long) ptr; | 162 | addr = (unsigned long) ptr; |
185 | #if ALIGN_CS == 1 | ||
186 | nr += (addr & __BITOPS_ALIGN) << 3; /* add alignment to bit number */ | ||
187 | addr ^= addr & __BITOPS_ALIGN; /* align address to 8 */ | ||
188 | #endif | ||
189 | /* calculate address for CS */ | 163 | /* calculate address for CS */ |
190 | addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; | 164 | addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; |
191 | /* make OR/test mask */ | 165 | /* make OR/test mask */ |
@@ -205,10 +179,6 @@ test_and_clear_bit_cs(unsigned long nr, volatile unsigned long *ptr) | |||
205 | unsigned long addr, old, new, mask; | 179 | unsigned long addr, old, new, mask; |
206 | 180 | ||
207 | addr = (unsigned long) ptr; | 181 | addr = (unsigned long) ptr; |
208 | #if ALIGN_CS == 1 | ||
209 | nr += (addr & __BITOPS_ALIGN) << 3; /* add alignment to bit number */ | ||
210 | addr ^= addr & __BITOPS_ALIGN; /* align address to 8 */ | ||
211 | #endif | ||
212 | /* calculate address for CS */ | 182 | /* calculate address for CS */ |
213 | addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; | 183 | addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; |
214 | /* make AND/test mask */ | 184 | /* make AND/test mask */ |
@@ -228,10 +198,6 @@ test_and_change_bit_cs(unsigned long nr, volatile unsigned long *ptr) | |||
228 | unsigned long addr, old, new, mask; | 198 | unsigned long addr, old, new, mask; |
229 | 199 | ||
230 | addr = (unsigned long) ptr; | 200 | addr = (unsigned long) ptr; |
231 | #if ALIGN_CS == 1 | ||
232 | nr += (addr & __BITOPS_ALIGN) << 3; /* add alignment to bit number */ | ||
233 | addr ^= addr & __BITOPS_ALIGN; /* align address to 8 */ | ||
234 | #endif | ||
235 | /* calculate address for CS */ | 201 | /* calculate address for CS */ |
236 | addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; | 202 | addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; |
237 | /* make XOR/test mask */ | 203 | /* make XOR/test mask */ |
@@ -834,8 +800,6 @@ static inline int sched_find_first_bit(unsigned long *b) | |||
834 | 800 | ||
835 | #include <asm-generic/bitops/hweight.h> | 801 | #include <asm-generic/bitops/hweight.h> |
836 | 802 | ||
837 | #ifdef __KERNEL__ | ||
838 | |||
839 | /* | 803 | /* |
840 | * ATTENTION: intel byte ordering convention for ext2 and minix !! | 804 | * ATTENTION: intel byte ordering convention for ext2 and minix !! |
841 | * bit 0 is the LSB of addr; bit 31 is the MSB of addr; | 805 | * bit 0 is the LSB of addr; bit 31 is the MSB of addr; |
diff --git a/include/asm-s390/cio.h b/include/asm-s390/cio.h index 089cf567c317..2b1619306351 100644 --- a/include/asm-s390/cio.h +++ b/include/asm-s390/cio.h | |||
@@ -276,6 +276,8 @@ extern void wait_cons_dev(void); | |||
276 | 276 | ||
277 | extern void clear_all_subchannels(void); | 277 | extern void clear_all_subchannels(void); |
278 | 278 | ||
279 | extern void css_schedule_reprobe(void); | ||
280 | |||
279 | #endif | 281 | #endif |
280 | 282 | ||
281 | #endif | 283 | #endif |
diff --git a/include/asm-s390/cmb.h b/include/asm-s390/cmb.h index 2d09950a9c11..241756f80df3 100644 --- a/include/asm-s390/cmb.h +++ b/include/asm-s390/cmb.h | |||
@@ -44,10 +44,6 @@ struct cmbdata { | |||
44 | #define BIODASDCMFENABLE _IO(DASD_IOCTL_LETTER,32) | 44 | #define BIODASDCMFENABLE _IO(DASD_IOCTL_LETTER,32) |
45 | /* enable channel measurement */ | 45 | /* enable channel measurement */ |
46 | #define BIODASDCMFDISABLE _IO(DASD_IOCTL_LETTER,33) | 46 | #define BIODASDCMFDISABLE _IO(DASD_IOCTL_LETTER,33) |
47 | /* reset channel measurement block */ | ||
48 | #define BIODASDRESETCMB _IO(DASD_IOCTL_LETTER,34) | ||
49 | /* read channel measurement data */ | ||
50 | #define BIODASDREADCMB _IOWR(DASD_IOCTL_LETTER,32,__u64) | ||
51 | /* read channel measurement data */ | 47 | /* read channel measurement data */ |
52 | #define BIODASDREADALLCMB _IOWR(DASD_IOCTL_LETTER,33,struct cmbdata) | 48 | #define BIODASDREADALLCMB _IOWR(DASD_IOCTL_LETTER,33,struct cmbdata) |
53 | 49 | ||
diff --git a/include/asm-s390/dasd.h b/include/asm-s390/dasd.h index 1630c26e8f45..c042f9578081 100644 --- a/include/asm-s390/dasd.h +++ b/include/asm-s390/dasd.h | |||
@@ -68,10 +68,12 @@ typedef struct dasd_information2_t { | |||
68 | * 0x00: default features | 68 | * 0x00: default features |
69 | * 0x01: readonly (ro) | 69 | * 0x01: readonly (ro) |
70 | * 0x02: use diag discipline (diag) | 70 | * 0x02: use diag discipline (diag) |
71 | * 0x04: set the device initially online (internal use only) | ||
71 | */ | 72 | */ |
72 | #define DASD_FEATURE_DEFAULT 0 | 73 | #define DASD_FEATURE_DEFAULT 0x00 |
73 | #define DASD_FEATURE_READONLY 1 | 74 | #define DASD_FEATURE_READONLY 0x01 |
74 | #define DASD_FEATURE_USEDIAG 2 | 75 | #define DASD_FEATURE_USEDIAG 0x02 |
76 | #define DASD_FEATURE_INITIAL_ONLINE 0x04 | ||
75 | 77 | ||
76 | #define DASD_PARTN_BITS 2 | 78 | #define DASD_PARTN_BITS 2 |
77 | 79 | ||
diff --git a/include/asm-s390/thread_info.h b/include/asm-s390/thread_info.h index 8e0c7ed73d03..0a518915bf90 100644 --- a/include/asm-s390/thread_info.h +++ b/include/asm-s390/thread_info.h | |||
@@ -63,6 +63,7 @@ struct thread_info { | |||
63 | .exec_domain = &default_exec_domain, \ | 63 | .exec_domain = &default_exec_domain, \ |
64 | .flags = 0, \ | 64 | .flags = 0, \ |
65 | .cpu = 0, \ | 65 | .cpu = 0, \ |
66 | .preempt_count = 1, \ | ||
66 | .restart_block = { \ | 67 | .restart_block = { \ |
67 | .fn = do_no_restart_syscall, \ | 68 | .fn = do_no_restart_syscall, \ |
68 | }, \ | 69 | }, \ |
diff --git a/include/asm-s390/unistd.h b/include/asm-s390/unistd.h index e21443d3ea1d..aa7a243862e1 100644 --- a/include/asm-s390/unistd.h +++ b/include/asm-s390/unistd.h | |||
@@ -394,11 +394,9 @@ | |||
394 | 394 | ||
395 | #ifdef __KERNEL__ | 395 | #ifdef __KERNEL__ |
396 | 396 | ||
397 | /* user-visible error numbers are in the range -1 - -122: see <asm-s390/errno.h> */ | ||
398 | |||
399 | #define __syscall_return(type, res) \ | 397 | #define __syscall_return(type, res) \ |
400 | do { \ | 398 | do { \ |
401 | if ((unsigned long)(res) >= (unsigned long)(-125)) { \ | 399 | if ((unsigned long)(res) >= (unsigned long)(-4095)) {\ |
402 | errno = -(res); \ | 400 | errno = -(res); \ |
403 | res = -1; \ | 401 | res = -1; \ |
404 | } \ | 402 | } \ |
diff --git a/include/asm-sh/hw_irq.h b/include/asm-sh/hw_irq.h index 1d934fb2c581..fed26616967a 100644 --- a/include/asm-sh/hw_irq.h +++ b/include/asm-sh/hw_irq.h | |||
@@ -1,9 +1,4 @@ | |||
1 | #ifndef __ASM_SH_HW_IRQ_H | 1 | #ifndef __ASM_SH_HW_IRQ_H |
2 | #define __ASM_SH_HW_IRQ_H | 2 | #define __ASM_SH_HW_IRQ_H |
3 | 3 | ||
4 | static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) | ||
5 | { | ||
6 | /* Nothing to do */ | ||
7 | } | ||
8 | |||
9 | #endif /* __ASM_SH_HW_IRQ_H */ | 4 | #endif /* __ASM_SH_HW_IRQ_H */ |
diff --git a/include/asm-sh64/hw_irq.h b/include/asm-sh64/hw_irq.h index ae718d1f2d6c..ebb39089b0ac 100644 --- a/include/asm-sh64/hw_irq.h +++ b/include/asm-sh64/hw_irq.h | |||
@@ -11,6 +11,5 @@ | |||
11 | * Copyright (C) 2000, 2001 Paolo Alberelli | 11 | * Copyright (C) 2000, 2001 Paolo Alberelli |
12 | * | 12 | * |
13 | */ | 13 | */ |
14 | static __inline__ void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) { /* Nothing to do */ } | ||
15 | 14 | ||
16 | #endif /* __ASM_SH64_HW_IRQ_H */ | 15 | #endif /* __ASM_SH64_HW_IRQ_H */ |
diff --git a/include/asm-um/hw_irq.h b/include/asm-um/hw_irq.h index 4ee38c0b6a64..1cf84cf5f21a 100644 --- a/include/asm-um/hw_irq.h +++ b/include/asm-um/hw_irq.h | |||
@@ -4,7 +4,4 @@ | |||
4 | #include "asm/irq.h" | 4 | #include "asm/irq.h" |
5 | #include "asm/archparam.h" | 5 | #include "asm/archparam.h" |
6 | 6 | ||
7 | static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) | ||
8 | {} | ||
9 | |||
10 | #endif | 7 | #endif |
diff --git a/include/asm-v850/hw_irq.h b/include/asm-v850/hw_irq.h index a8aab4342712..043e94bb6bd8 100644 --- a/include/asm-v850/hw_irq.h +++ b/include/asm-v850/hw_irq.h | |||
@@ -1,8 +1,4 @@ | |||
1 | #ifndef __V850_HW_IRQ_H__ | 1 | #ifndef __V850_HW_IRQ_H__ |
2 | #define __V850_HW_IRQ_H__ | 2 | #define __V850_HW_IRQ_H__ |
3 | 3 | ||
4 | static inline void hw_resend_irq (struct hw_interrupt_type *h, unsigned int i) | ||
5 | { | ||
6 | } | ||
7 | |||
8 | #endif /* __V850_HW_IRQ_H__ */ | 4 | #endif /* __V850_HW_IRQ_H__ */ |
diff --git a/include/asm-x86_64/hw_irq.h b/include/asm-x86_64/hw_irq.h index 931877462788..48a4a5364e85 100644 --- a/include/asm-x86_64/hw_irq.h +++ b/include/asm-x86_64/hw_irq.h | |||
@@ -127,15 +127,6 @@ __asm__( \ | |||
127 | "push $~(" #nr ") ; " \ | 127 | "push $~(" #nr ") ; " \ |
128 | "jmp common_interrupt"); | 128 | "jmp common_interrupt"); |
129 | 129 | ||
130 | #if defined(CONFIG_X86_IO_APIC) | ||
131 | static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) { | ||
132 | if (IO_APIC_IRQ(i)) | ||
133 | send_IPI_self(IO_APIC_VECTOR(i)); | ||
134 | } | ||
135 | #else | ||
136 | static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {} | ||
137 | #endif | ||
138 | |||
139 | #define platform_legacy_irq(irq) ((irq) < 16) | 130 | #define platform_legacy_irq(irq) ((irq) < 16) |
140 | 131 | ||
141 | #endif | 132 | #endif |
diff --git a/include/asm-xtensa/hw_irq.h b/include/asm-xtensa/hw_irq.h index ccf436249eaa..3ddbea759b2b 100644 --- a/include/asm-xtensa/hw_irq.h +++ b/include/asm-xtensa/hw_irq.h | |||
@@ -11,8 +11,4 @@ | |||
11 | #ifndef _XTENSA_HW_IRQ_H | 11 | #ifndef _XTENSA_HW_IRQ_H |
12 | #define _XTENSA_HW_IRQ_H | 12 | #define _XTENSA_HW_IRQ_H |
13 | 13 | ||
14 | static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) | ||
15 | { | ||
16 | } | ||
17 | |||
18 | #endif | 14 | #endif |
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 70741e170114..db2a63a11633 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h | |||
@@ -36,6 +36,20 @@ extern void free_irq(unsigned int, void *); | |||
36 | extern void disable_irq_nosync(unsigned int irq); | 36 | extern void disable_irq_nosync(unsigned int irq); |
37 | extern void disable_irq(unsigned int irq); | 37 | extern void disable_irq(unsigned int irq); |
38 | extern void enable_irq(unsigned int irq); | 38 | extern void enable_irq(unsigned int irq); |
39 | |||
40 | /* IRQ wakeup (PM) control: */ | ||
41 | extern int set_irq_wake(unsigned int irq, unsigned int on); | ||
42 | |||
43 | static inline int enable_irq_wake(unsigned int irq) | ||
44 | { | ||
45 | return set_irq_wake(irq, 1); | ||
46 | } | ||
47 | |||
48 | static inline int disable_irq_wake(unsigned int irq) | ||
49 | { | ||
50 | return set_irq_wake(irq, 0); | ||
51 | } | ||
52 | |||
39 | #endif | 53 | #endif |
40 | 54 | ||
41 | #ifndef __ARCH_SET_SOFTIRQ_PENDING | 55 | #ifndef __ARCH_SET_SOFTIRQ_PENDING |
diff --git a/include/linux/ioport.h b/include/linux/ioport.h index edfc733b1575..87a9fc039b47 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h | |||
@@ -9,13 +9,15 @@ | |||
9 | #define _LINUX_IOPORT_H | 9 | #define _LINUX_IOPORT_H |
10 | 10 | ||
11 | #include <linux/compiler.h> | 11 | #include <linux/compiler.h> |
12 | #include <linux/types.h> | ||
12 | /* | 13 | /* |
13 | * Resources are tree-like, allowing | 14 | * Resources are tree-like, allowing |
14 | * nesting etc.. | 15 | * nesting etc.. |
15 | */ | 16 | */ |
16 | struct resource { | 17 | struct resource { |
18 | resource_size_t start; | ||
19 | resource_size_t end; | ||
17 | const char *name; | 20 | const char *name; |
18 | unsigned long start, end; | ||
19 | unsigned long flags; | 21 | unsigned long flags; |
20 | struct resource *parent, *sibling, *child; | 22 | struct resource *parent, *sibling, *child; |
21 | }; | 23 | }; |
@@ -96,14 +98,13 @@ extern struct resource * ____request_resource(struct resource *root, struct reso | |||
96 | extern int release_resource(struct resource *new); | 98 | extern int release_resource(struct resource *new); |
97 | extern __deprecated_for_modules int insert_resource(struct resource *parent, struct resource *new); | 99 | extern __deprecated_for_modules int insert_resource(struct resource *parent, struct resource *new); |
98 | extern int allocate_resource(struct resource *root, struct resource *new, | 100 | extern int allocate_resource(struct resource *root, struct resource *new, |
99 | unsigned long size, | 101 | resource_size_t size, resource_size_t min, |
100 | unsigned long min, unsigned long max, | 102 | resource_size_t max, resource_size_t align, |
101 | unsigned long align, | ||
102 | void (*alignf)(void *, struct resource *, | 103 | void (*alignf)(void *, struct resource *, |
103 | unsigned long, unsigned long), | 104 | resource_size_t, resource_size_t), |
104 | void *alignf_data); | 105 | void *alignf_data); |
105 | int adjust_resource(struct resource *res, unsigned long start, | 106 | int adjust_resource(struct resource *res, resource_size_t start, |
106 | unsigned long size); | 107 | resource_size_t size); |
107 | 108 | ||
108 | /* get registered SYSTEM_RAM resources in specified area */ | 109 | /* get registered SYSTEM_RAM resources in specified area */ |
109 | extern int find_next_system_ram(struct resource *res); | 110 | extern int find_next_system_ram(struct resource *res); |
@@ -113,17 +114,21 @@ extern int find_next_system_ram(struct resource *res); | |||
113 | #define request_mem_region(start,n,name) __request_region(&iomem_resource, (start), (n), (name)) | 114 | #define request_mem_region(start,n,name) __request_region(&iomem_resource, (start), (n), (name)) |
114 | #define rename_region(region, newname) do { (region)->name = (newname); } while (0) | 115 | #define rename_region(region, newname) do { (region)->name = (newname); } while (0) |
115 | 116 | ||
116 | extern struct resource * __request_region(struct resource *, unsigned long start, unsigned long n, const char *name); | 117 | extern struct resource * __request_region(struct resource *, |
118 | resource_size_t start, | ||
119 | resource_size_t n, const char *name); | ||
117 | 120 | ||
118 | /* Compatibility cruft */ | 121 | /* Compatibility cruft */ |
119 | #define release_region(start,n) __release_region(&ioport_resource, (start), (n)) | 122 | #define release_region(start,n) __release_region(&ioport_resource, (start), (n)) |
120 | #define check_mem_region(start,n) __check_region(&iomem_resource, (start), (n)) | 123 | #define check_mem_region(start,n) __check_region(&iomem_resource, (start), (n)) |
121 | #define release_mem_region(start,n) __release_region(&iomem_resource, (start), (n)) | 124 | #define release_mem_region(start,n) __release_region(&iomem_resource, (start), (n)) |
122 | 125 | ||
123 | extern int __check_region(struct resource *, unsigned long, unsigned long); | 126 | extern int __check_region(struct resource *, resource_size_t, resource_size_t); |
124 | extern void __release_region(struct resource *, unsigned long, unsigned long); | 127 | extern void __release_region(struct resource *, resource_size_t, |
128 | resource_size_t); | ||
125 | 129 | ||
126 | static inline int __deprecated check_region(unsigned long s, unsigned long n) | 130 | static inline int __deprecated check_region(resource_size_t s, |
131 | resource_size_t n) | ||
127 | { | 132 | { |
128 | return __check_region(&ioport_resource, s, n); | 133 | return __check_region(&ioport_resource, s, n); |
129 | } | 134 | } |
diff --git a/include/linux/irq.h b/include/linux/irq.h index 676e00dfb21a..0832149cdb18 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h | |||
@@ -1,5 +1,5 @@ | |||
1 | #ifndef __irq_h | 1 | #ifndef _LINUX_IRQ_H |
2 | #define __irq_h | 2 | #define _LINUX_IRQ_H |
3 | 3 | ||
4 | /* | 4 | /* |
5 | * Please do not include this file in generic code. There is currently | 5 | * Please do not include this file in generic code. There is currently |
@@ -11,7 +11,7 @@ | |||
11 | 11 | ||
12 | #include <linux/smp.h> | 12 | #include <linux/smp.h> |
13 | 13 | ||
14 | #if !defined(CONFIG_S390) | 14 | #ifndef CONFIG_S390 |
15 | 15 | ||
16 | #include <linux/linkage.h> | 16 | #include <linux/linkage.h> |
17 | #include <linux/cache.h> | 17 | #include <linux/cache.h> |
@@ -33,75 +33,160 @@ | |||
33 | #define IRQ_WAITING 32 /* IRQ not yet seen - for autodetection */ | 33 | #define IRQ_WAITING 32 /* IRQ not yet seen - for autodetection */ |
34 | #define IRQ_LEVEL 64 /* IRQ level triggered */ | 34 | #define IRQ_LEVEL 64 /* IRQ level triggered */ |
35 | #define IRQ_MASKED 128 /* IRQ masked - shouldn't be seen again */ | 35 | #define IRQ_MASKED 128 /* IRQ masked - shouldn't be seen again */ |
36 | #if defined(ARCH_HAS_IRQ_PER_CPU) | 36 | #ifdef CONFIG_IRQ_PER_CPU |
37 | # define IRQ_PER_CPU 256 /* IRQ is per CPU */ | 37 | # define IRQ_PER_CPU 256 /* IRQ is per CPU */ |
38 | # define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU) | 38 | # define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU) |
39 | #else | 39 | #else |
40 | # define CHECK_IRQ_PER_CPU(var) 0 | 40 | # define CHECK_IRQ_PER_CPU(var) 0 |
41 | #endif | 41 | #endif |
42 | 42 | ||
43 | #define IRQ_NOPROBE 512 /* IRQ is not valid for probing */ | ||
44 | #define IRQ_NOREQUEST 1024 /* IRQ cannot be requested */ | ||
45 | #define IRQ_NOAUTOEN 2048 /* IRQ will not be enabled on request irq */ | ||
46 | #define IRQ_DELAYED_DISABLE \ | ||
47 | 4096 /* IRQ disable (masking) happens delayed. */ | ||
48 | |||
43 | /* | 49 | /* |
44 | * Interrupt controller descriptor. This is all we need | 50 | * IRQ types, see also include/linux/interrupt.h |
45 | * to describe about the low-level hardware. | ||
46 | */ | 51 | */ |
47 | struct hw_interrupt_type { | 52 | #define IRQ_TYPE_NONE 0x0000 /* Default, unspecified type */ |
48 | const char * typename; | 53 | #define IRQ_TYPE_EDGE_RISING 0x0001 /* Edge rising type */ |
49 | unsigned int (*startup)(unsigned int irq); | 54 | #define IRQ_TYPE_EDGE_FALLING 0x0002 /* Edge falling type */ |
50 | void (*shutdown)(unsigned int irq); | 55 | #define IRQ_TYPE_EDGE_BOTH (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING) |
51 | void (*enable)(unsigned int irq); | 56 | #define IRQ_TYPE_LEVEL_HIGH 0x0004 /* Level high type */ |
52 | void (*disable)(unsigned int irq); | 57 | #define IRQ_TYPE_LEVEL_LOW 0x0008 /* Level low type */ |
53 | void (*ack)(unsigned int irq); | 58 | #define IRQ_TYPE_SENSE_MASK 0x000f /* Mask of the above */ |
54 | void (*end)(unsigned int irq); | 59 | #define IRQ_TYPE_SIMPLE 0x0010 /* Simple type */ |
55 | void (*set_affinity)(unsigned int irq, cpumask_t dest); | 60 | #define IRQ_TYPE_PERCPU 0x0020 /* Per CPU type */ |
61 | #define IRQ_TYPE_PROBE 0x0040 /* Probing in progress */ | ||
62 | |||
63 | struct proc_dir_entry; | ||
64 | |||
65 | /** | ||
66 | * struct irq_chip - hardware interrupt chip descriptor | ||
67 | * | ||
68 | * @name: name for /proc/interrupts | ||
69 | * @startup: start up the interrupt (defaults to ->enable if NULL) | ||
70 | * @shutdown: shut down the interrupt (defaults to ->disable if NULL) | ||
71 | * @enable: enable the interrupt (defaults to chip->unmask if NULL) | ||
72 | * @disable: disable the interrupt (defaults to chip->mask if NULL) | ||
73 | * @ack: start of a new interrupt | ||
74 | * @mask: mask an interrupt source | ||
75 | * @mask_ack: ack and mask an interrupt source | ||
76 | * @unmask: unmask an interrupt source | ||
77 | * @eoi: end of interrupt - chip level | ||
78 | * @end: end of interrupt - flow level | ||
79 | * @set_affinity: set the CPU affinity on SMP machines | ||
80 | * @retrigger: resend an IRQ to the CPU | ||
81 | * @set_type: set the flow type (IRQ_TYPE_LEVEL/etc.) of an IRQ | ||
82 | * @set_wake: enable/disable power-management wake-on of an IRQ | ||
83 | * | ||
84 | * @release: release function solely used by UML | ||
85 | * @typename: obsoleted by name, kept as migration helper | ||
86 | */ | ||
87 | struct irq_chip { | ||
88 | const char *name; | ||
89 | unsigned int (*startup)(unsigned int irq); | ||
90 | void (*shutdown)(unsigned int irq); | ||
91 | void (*enable)(unsigned int irq); | ||
92 | void (*disable)(unsigned int irq); | ||
93 | |||
94 | void (*ack)(unsigned int irq); | ||
95 | void (*mask)(unsigned int irq); | ||
96 | void (*mask_ack)(unsigned int irq); | ||
97 | void (*unmask)(unsigned int irq); | ||
98 | void (*eoi)(unsigned int irq); | ||
99 | |||
100 | void (*end)(unsigned int irq); | ||
101 | void (*set_affinity)(unsigned int irq, cpumask_t dest); | ||
102 | int (*retrigger)(unsigned int irq); | ||
103 | int (*set_type)(unsigned int irq, unsigned int flow_type); | ||
104 | int (*set_wake)(unsigned int irq, unsigned int on); | ||
105 | |||
56 | /* Currently used only by UML, might disappear one day.*/ | 106 | /* Currently used only by UML, might disappear one day.*/ |
57 | #ifdef CONFIG_IRQ_RELEASE_METHOD | 107 | #ifdef CONFIG_IRQ_RELEASE_METHOD |
58 | void (*release)(unsigned int irq, void *dev_id); | 108 | void (*release)(unsigned int irq, void *dev_id); |
59 | #endif | 109 | #endif |
110 | /* | ||
111 | * For compatibility, ->typename is copied into ->name. | ||
112 | * Will disappear. | ||
113 | */ | ||
114 | const char *typename; | ||
60 | }; | 115 | }; |
61 | 116 | ||
62 | typedef struct hw_interrupt_type hw_irq_controller; | 117 | /** |
63 | 118 | * struct irq_desc - interrupt descriptor | |
64 | /* | 119 | * |
65 | * This is the "IRQ descriptor", which contains various information | 120 | * @handle_irq: highlevel irq-events handler [if NULL, __do_IRQ()] |
66 | * about the irq, including what kind of hardware handling it has, | 121 | * @chip: low level interrupt hardware access |
67 | * whether it is disabled etc etc. | 122 | * @handler_data: per-IRQ data for the irq_chip methods |
123 | * @chip_data: platform-specific per-chip private data for the chip | ||
124 | * methods, to allow shared chip implementations | ||
125 | * @action: the irq action chain | ||
126 | * @status: status information | ||
127 | * @depth: disable-depth, for nested irq_disable() calls | ||
128 | * @irq_count: stats field to detect stalled irqs | ||
129 | * @irqs_unhandled: stats field for spurious unhandled interrupts | ||
130 | * @lock: locking for SMP | ||
131 | * @affinity: IRQ affinity on SMP | ||
132 | * @cpu: cpu index useful for balancing | ||
133 | * @pending_mask: pending rebalanced interrupts | ||
134 | * @move_irq: need to re-target IRQ destination | ||
135 | * @dir: /proc/irq/ procfs entry | ||
136 | * @affinity_entry: /proc/irq/smp_affinity procfs entry on SMP | ||
68 | * | 137 | * |
69 | * Pad this out to 32 bytes for cache and indexing reasons. | 138 | * Pad this out to 32 bytes for cache and indexing reasons. |
70 | */ | 139 | */ |
71 | typedef struct irq_desc { | 140 | struct irq_desc { |
72 | hw_irq_controller *handler; | 141 | void fastcall (*handle_irq)(unsigned int irq, |
73 | void *handler_data; | 142 | struct irq_desc *desc, |
74 | struct irqaction *action; /* IRQ action list */ | 143 | struct pt_regs *regs); |
75 | unsigned int status; /* IRQ status */ | 144 | struct irq_chip *chip; |
76 | unsigned int depth; /* nested irq disables */ | 145 | void *handler_data; |
77 | unsigned int irq_count; /* For detecting broken interrupts */ | 146 | void *chip_data; |
78 | unsigned int irqs_unhandled; | 147 | struct irqaction *action; /* IRQ action list */ |
79 | spinlock_t lock; | 148 | unsigned int status; /* IRQ status */ |
80 | #if defined (CONFIG_GENERIC_PENDING_IRQ) || defined (CONFIG_IRQBALANCE) | 149 | |
81 | unsigned int move_irq; /* Flag need to re-target intr dest*/ | 150 | unsigned int depth; /* nested irq disables */ |
151 | unsigned int irq_count; /* For detecting broken IRQs */ | ||
152 | unsigned int irqs_unhandled; | ||
153 | spinlock_t lock; | ||
154 | #ifdef CONFIG_SMP | ||
155 | cpumask_t affinity; | ||
156 | unsigned int cpu; | ||
157 | #endif | ||
158 | #if defined(CONFIG_GENERIC_PENDING_IRQ) || defined(CONFIG_IRQBALANCE) | ||
159 | cpumask_t pending_mask; | ||
160 | unsigned int move_irq; /* need to re-target IRQ dest */ | ||
82 | #endif | 161 | #endif |
83 | } ____cacheline_aligned irq_desc_t; | 162 | #ifdef CONFIG_PROC_FS |
163 | struct proc_dir_entry *dir; | ||
164 | #endif | ||
165 | } ____cacheline_aligned; | ||
84 | 166 | ||
85 | extern irq_desc_t irq_desc [NR_IRQS]; | 167 | extern struct irq_desc irq_desc[NR_IRQS]; |
86 | 168 | ||
87 | /* Return a pointer to the irq descriptor for IRQ. */ | 169 | /* |
88 | static inline irq_desc_t * | 170 | * Migration helpers for obsolete names, they will go away: |
89 | irq_descp (int irq) | 171 | */ |
90 | { | 172 | #define hw_interrupt_type irq_chip |
91 | return irq_desc + irq; | 173 | typedef struct irq_chip hw_irq_controller; |
92 | } | 174 | #define no_irq_type no_irq_chip |
175 | typedef struct irq_desc irq_desc_t; | ||
93 | 176 | ||
94 | #include <asm/hw_irq.h> /* the arch dependent stuff */ | 177 | /* |
178 | * Pick up the arch-dependent methods: | ||
179 | */ | ||
180 | #include <asm/hw_irq.h> | ||
95 | 181 | ||
96 | extern int setup_irq(unsigned int irq, struct irqaction * new); | 182 | extern int setup_irq(unsigned int irq, struct irqaction *new); |
97 | 183 | ||
98 | #ifdef CONFIG_GENERIC_HARDIRQS | 184 | #ifdef CONFIG_GENERIC_HARDIRQS |
99 | extern cpumask_t irq_affinity[NR_IRQS]; | ||
100 | 185 | ||
101 | #ifdef CONFIG_SMP | 186 | #ifdef CONFIG_SMP |
102 | static inline void set_native_irq_info(int irq, cpumask_t mask) | 187 | static inline void set_native_irq_info(int irq, cpumask_t mask) |
103 | { | 188 | { |
104 | irq_affinity[irq] = mask; | 189 | irq_desc[irq].affinity = mask; |
105 | } | 190 | } |
106 | #else | 191 | #else |
107 | static inline void set_native_irq_info(int irq, cpumask_t mask) | 192 | static inline void set_native_irq_info(int irq, cpumask_t mask) |
@@ -111,8 +196,7 @@ static inline void set_native_irq_info(int irq, cpumask_t mask) | |||
111 | 196 | ||
112 | #ifdef CONFIG_SMP | 197 | #ifdef CONFIG_SMP |
113 | 198 | ||
114 | #if defined (CONFIG_GENERIC_PENDING_IRQ) || defined (CONFIG_IRQBALANCE) | 199 | #if defined(CONFIG_GENERIC_PENDING_IRQ) || defined(CONFIG_IRQBALANCE) |
115 | extern cpumask_t pending_irq_cpumask[NR_IRQS]; | ||
116 | 200 | ||
117 | void set_pending_irq(unsigned int irq, cpumask_t mask); | 201 | void set_pending_irq(unsigned int irq, cpumask_t mask); |
118 | void move_native_irq(int irq); | 202 | void move_native_irq(int irq); |
@@ -133,7 +217,7 @@ static inline void set_irq_info(int irq, cpumask_t mask) | |||
133 | { | 217 | { |
134 | } | 218 | } |
135 | 219 | ||
136 | #else // CONFIG_PCI_MSI | 220 | #else /* CONFIG_PCI_MSI */ |
137 | 221 | ||
138 | static inline void move_irq(int irq) | 222 | static inline void move_irq(int irq) |
139 | { | 223 | { |
@@ -144,26 +228,36 @@ static inline void set_irq_info(int irq, cpumask_t mask) | |||
144 | { | 228 | { |
145 | set_native_irq_info(irq, mask); | 229 | set_native_irq_info(irq, mask); |
146 | } | 230 | } |
147 | #endif // CONFIG_PCI_MSI | ||
148 | 231 | ||
149 | #else // CONFIG_GENERIC_PENDING_IRQ || CONFIG_IRQBALANCE | 232 | #endif /* CONFIG_PCI_MSI */ |
233 | |||
234 | #else /* CONFIG_GENERIC_PENDING_IRQ || CONFIG_IRQBALANCE */ | ||
235 | |||
236 | static inline void move_irq(int irq) | ||
237 | { | ||
238 | } | ||
239 | |||
240 | static inline void move_native_irq(int irq) | ||
241 | { | ||
242 | } | ||
243 | |||
244 | static inline void set_pending_irq(unsigned int irq, cpumask_t mask) | ||
245 | { | ||
246 | } | ||
150 | 247 | ||
151 | #define move_irq(x) | ||
152 | #define move_native_irq(x) | ||
153 | #define set_pending_irq(x,y) | ||
154 | static inline void set_irq_info(int irq, cpumask_t mask) | 248 | static inline void set_irq_info(int irq, cpumask_t mask) |
155 | { | 249 | { |
156 | set_native_irq_info(irq, mask); | 250 | set_native_irq_info(irq, mask); |
157 | } | 251 | } |
158 | 252 | ||
159 | #endif // CONFIG_GENERIC_PENDING_IRQ | 253 | #endif /* CONFIG_GENERIC_PENDING_IRQ */ |
160 | 254 | ||
161 | #else // CONFIG_SMP | 255 | #else /* CONFIG_SMP */ |
162 | 256 | ||
163 | #define move_irq(x) | 257 | #define move_irq(x) |
164 | #define move_native_irq(x) | 258 | #define move_native_irq(x) |
165 | 259 | ||
166 | #endif // CONFIG_SMP | 260 | #endif /* CONFIG_SMP */ |
167 | 261 | ||
168 | #ifdef CONFIG_IRQBALANCE | 262 | #ifdef CONFIG_IRQBALANCE |
169 | extern void set_balance_irq_affinity(unsigned int irq, cpumask_t mask); | 263 | extern void set_balance_irq_affinity(unsigned int irq, cpumask_t mask); |
@@ -173,32 +267,138 @@ static inline void set_balance_irq_affinity(unsigned int irq, cpumask_t mask) | |||
173 | } | 267 | } |
174 | #endif | 268 | #endif |
175 | 269 | ||
270 | #ifdef CONFIG_AUTO_IRQ_AFFINITY | ||
271 | extern int select_smp_affinity(unsigned int irq); | ||
272 | #else | ||
273 | static inline int select_smp_affinity(unsigned int irq) | ||
274 | { | ||
275 | return 1; | ||
276 | } | ||
277 | #endif | ||
278 | |||
176 | extern int no_irq_affinity; | 279 | extern int no_irq_affinity; |
177 | extern int noirqdebug_setup(char *str); | ||
178 | 280 | ||
179 | extern fastcall irqreturn_t handle_IRQ_event(unsigned int irq, struct pt_regs *regs, | 281 | /* Handle irq action chains: */ |
180 | struct irqaction *action); | 282 | extern int handle_IRQ_event(unsigned int irq, struct pt_regs *regs, |
283 | struct irqaction *action); | ||
284 | |||
285 | /* | ||
286 | * Built-in IRQ handlers for various IRQ types, | ||
287 | * callable via desc->chip->handle_irq() | ||
288 | */ | ||
289 | extern void fastcall | ||
290 | handle_level_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs); | ||
291 | extern void fastcall | ||
292 | handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc, | ||
293 | struct pt_regs *regs); | ||
294 | extern void fastcall | ||
295 | handle_edge_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs); | ||
296 | extern void fastcall | ||
297 | handle_simple_irq(unsigned int irq, struct irq_desc *desc, | ||
298 | struct pt_regs *regs); | ||
299 | extern void fastcall | ||
300 | handle_percpu_irq(unsigned int irq, struct irq_desc *desc, | ||
301 | struct pt_regs *regs); | ||
302 | extern void fastcall | ||
303 | handle_bad_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs); | ||
304 | |||
305 | /* | ||
306 | * Get a descriptive string for the highlevel handler, for | ||
307 | * /proc/interrupts output: | ||
308 | */ | ||
309 | extern const char * | ||
310 | handle_irq_name(void fastcall (*handle)(unsigned int, struct irq_desc *, | ||
311 | struct pt_regs *)); | ||
312 | |||
313 | /* | ||
314 | * Monolithic do_IRQ implementation. | ||
315 | * (is an explicit fastcall, because i386 4KSTACKS calls it from assembly) | ||
316 | */ | ||
181 | extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs); | 317 | extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs); |
182 | extern void note_interrupt(unsigned int irq, irq_desc_t *desc, | ||
183 | int action_ret, struct pt_regs *regs); | ||
184 | extern int can_request_irq(unsigned int irq, unsigned long irqflags); | ||
185 | 318 | ||
319 | /* | ||
320 | * Architectures call this to let the generic IRQ layer | ||
321 | * handle an interrupt. If the descriptor is attached to an | ||
322 | * irqchip-style controller then we call the ->handle_irq() handler, | ||
323 | * and it calls __do_IRQ() if it's attached to an irqtype-style controller. | ||
324 | */ | ||
325 | static inline void generic_handle_irq(unsigned int irq, struct pt_regs *regs) | ||
326 | { | ||
327 | struct irq_desc *desc = irq_desc + irq; | ||
328 | |||
329 | if (likely(desc->handle_irq)) | ||
330 | desc->handle_irq(irq, desc, regs); | ||
331 | else | ||
332 | __do_IRQ(irq, regs); | ||
333 | } | ||
334 | |||
335 | /* Handling of unhandled and spurious interrupts: */ | ||
336 | extern void note_interrupt(unsigned int irq, struct irq_desc *desc, | ||
337 | int action_ret, struct pt_regs *regs); | ||
338 | |||
339 | /* Resending of interrupts :*/ | ||
340 | void check_irq_resend(struct irq_desc *desc, unsigned int irq); | ||
341 | |||
342 | /* Initialize /proc/irq/ */ | ||
186 | extern void init_irq_proc(void); | 343 | extern void init_irq_proc(void); |
187 | 344 | ||
188 | #ifdef CONFIG_AUTO_IRQ_AFFINITY | 345 | /* Enable/disable irq debugging output: */ |
189 | extern int select_smp_affinity(unsigned int irq); | 346 | extern int noirqdebug_setup(char *str); |
190 | #else | 347 | |
191 | static inline int | 348 | /* Checks whether the interrupt can be requested by request_irq(): */ |
192 | select_smp_affinity(unsigned int irq) | 349 | extern int can_request_irq(unsigned int irq, unsigned long irqflags); |
350 | |||
351 | /* Dummy irq-chip implementation: */ | ||
352 | extern struct irq_chip no_irq_chip; | ||
353 | |||
354 | extern void | ||
355 | set_irq_chip_and_handler(unsigned int irq, struct irq_chip *chip, | ||
356 | void fastcall (*handle)(unsigned int, | ||
357 | struct irq_desc *, | ||
358 | struct pt_regs *)); | ||
359 | extern void | ||
360 | __set_irq_handler(unsigned int irq, | ||
361 | void fastcall (*handle)(unsigned int, struct irq_desc *, | ||
362 | struct pt_regs *), | ||
363 | int is_chained); | ||
364 | |||
365 | /* | ||
366 | * Set a highlevel flow handler for a given IRQ: | ||
367 | */ | ||
368 | static inline void | ||
369 | set_irq_handler(unsigned int irq, | ||
370 | void fastcall (*handle)(unsigned int, struct irq_desc *, | ||
371 | struct pt_regs *)) | ||
193 | { | 372 | { |
194 | return 1; | 373 | __set_irq_handler(irq, handle, 0); |
195 | } | 374 | } |
196 | #endif | ||
197 | 375 | ||
198 | #endif | 376 | /* |
377 | * Set a highlevel chained flow handler for a given IRQ. | ||
378 | * (a chained handler is automatically enabled and set to | ||
379 | * IRQ_NOREQUEST and IRQ_NOPROBE) | ||
380 | */ | ||
381 | static inline void | ||
382 | set_irq_chained_handler(unsigned int irq, | ||
383 | void fastcall (*handle)(unsigned int, struct irq_desc *, | ||
384 | struct pt_regs *)) | ||
385 | { | ||
386 | __set_irq_handler(irq, handle, 1); | ||
387 | } | ||
199 | 388 | ||
200 | extern hw_irq_controller no_irq_type; /* needed in every arch ? */ | 389 | /* Set/get chip/data for an IRQ: */ |
201 | 390 | ||
202 | #endif | 391 | extern int set_irq_chip(unsigned int irq, struct irq_chip *chip); |
392 | extern int set_irq_data(unsigned int irq, void *data); | ||
393 | extern int set_irq_chip_data(unsigned int irq, void *data); | ||
394 | extern int set_irq_type(unsigned int irq, unsigned int type); | ||
395 | |||
396 | #define get_irq_chip(irq) (irq_desc[irq].chip) | ||
397 | #define get_irq_chip_data(irq) (irq_desc[irq].chip_data) | ||
398 | #define get_irq_data(irq) (irq_desc[irq].handler_data) | ||
399 | |||
400 | #endif /* CONFIG_GENERIC_HARDIRQS */ | ||
401 | |||
402 | #endif /* !CONFIG_S390 */ | ||
203 | 403 | ||
204 | #endif /* __irq_h */ | 404 | #endif /* _LINUX_IRQ_H */ |
diff --git a/include/linux/isdn/tpam.h b/include/linux/isdn/tpam.h deleted file mode 100644 index d18dd0dc570d..000000000000 --- a/include/linux/isdn/tpam.h +++ /dev/null | |||
@@ -1,55 +0,0 @@ | |||
1 | /* $Id: tpam.h,v 1.1.2.1 2001/06/08 08:23:46 kai Exp $ | ||
2 | * | ||
3 | * Turbo PAM ISDN driver for Linux. (Kernel Driver) | ||
4 | * | ||
5 | * Copyright 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcôve | ||
6 | * | ||
7 | * For all support questions please contact: <support@auvertech.fr> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2, or (at your option) | ||
12 | * any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | #ifndef _TPAM_H_ | ||
26 | #define _TPAM_H_ | ||
27 | |||
28 | #include <linux/types.h> | ||
29 | |||
30 | /* IOCTL commands */ | ||
31 | #define TPAM_CMD_DSPLOAD 0x0001 | ||
32 | #define TPAM_CMD_DSPSAVE 0x0002 | ||
33 | #define TPAM_CMD_DSPRUN 0x0003 | ||
34 | #define TPAM_CMD_LOOPMODEON 0x0004 | ||
35 | #define TPAM_CMD_LOOPMODEOFF 0x0005 | ||
36 | |||
37 | /* addresses of debug information zones on board */ | ||
38 | #define TPAM_TRAPAUDIT_REGISTER 0x005493e4 | ||
39 | #define TPAM_NCOAUDIT_REGISTER 0x00500000 | ||
40 | #define TPAM_MSGAUDIT_REGISTER 0x008E30F0 | ||
41 | |||
42 | /* length of debug information zones on board */ | ||
43 | #define TPAM_TRAPAUDIT_LENGTH 10000 | ||
44 | #define TPAM_NCOAUDIT_LENGTH 300000 | ||
45 | #define TPAM_NCOAUDIT_COUNT 30 | ||
46 | #define TPAM_MSGAUDIT_LENGTH 60000 | ||
47 | |||
48 | /* IOCTL load/save parameter */ | ||
49 | typedef struct tpam_dsp_ioctl { | ||
50 | __u32 address; /* address to load/save data */ | ||
51 | __u32 data_len; /* size of data to be loaded/saved */ | ||
52 | __u8 data[0]; /* data */ | ||
53 | } tpam_dsp_ioctl; | ||
54 | |||
55 | #endif /* _TPAM_H_ */ | ||
diff --git a/include/linux/key.h b/include/linux/key.h index e693e729bc92..169f05e4863e 100644 --- a/include/linux/key.h +++ b/include/linux/key.h | |||
@@ -177,7 +177,8 @@ struct key { | |||
177 | /* | 177 | /* |
178 | * kernel managed key type definition | 178 | * kernel managed key type definition |
179 | */ | 179 | */ |
180 | typedef int (*request_key_actor_t)(struct key *key, struct key *authkey, const char *op); | 180 | typedef int (*request_key_actor_t)(struct key *key, struct key *authkey, |
181 | const char *op, void *aux); | ||
181 | 182 | ||
182 | struct key_type { | 183 | struct key_type { |
183 | /* name of the type */ | 184 | /* name of the type */ |
@@ -285,6 +286,11 @@ extern struct key *request_key(struct key_type *type, | |||
285 | const char *description, | 286 | const char *description, |
286 | const char *callout_info); | 287 | const char *callout_info); |
287 | 288 | ||
289 | extern struct key *request_key_with_auxdata(struct key_type *type, | ||
290 | const char *description, | ||
291 | const char *callout_info, | ||
292 | void *aux); | ||
293 | |||
288 | extern int key_validate(struct key *key); | 294 | extern int key_validate(struct key *key); |
289 | 295 | ||
290 | extern key_ref_t key_create_or_update(key_ref_t keyring, | 296 | extern key_ref_t key_create_or_update(key_ref_t keyring, |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 62a8c22f5f60..983fca251b25 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -404,8 +404,8 @@ int pcibios_enable_device(struct pci_dev *, int mask); | |||
404 | char *pcibios_setup (char *str); | 404 | char *pcibios_setup (char *str); |
405 | 405 | ||
406 | /* Used only when drivers/pci/setup.c is used */ | 406 | /* Used only when drivers/pci/setup.c is used */ |
407 | void pcibios_align_resource(void *, struct resource *, | 407 | void pcibios_align_resource(void *, struct resource *, resource_size_t, |
408 | unsigned long, unsigned long); | 408 | resource_size_t); |
409 | void pcibios_update_irq(struct pci_dev *, int irq); | 409 | void pcibios_update_irq(struct pci_dev *, int irq); |
410 | 410 | ||
411 | /* Generic PCI functions used internally */ | 411 | /* Generic PCI functions used internally */ |
@@ -532,10 +532,10 @@ void pci_release_region(struct pci_dev *, int); | |||
532 | 532 | ||
533 | /* drivers/pci/bus.c */ | 533 | /* drivers/pci/bus.c */ |
534 | int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, | 534 | int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, |
535 | unsigned long size, unsigned long align, | 535 | resource_size_t size, resource_size_t align, |
536 | unsigned long min, unsigned int type_mask, | 536 | resource_size_t min, unsigned int type_mask, |
537 | void (*alignf)(void *, struct resource *, | 537 | void (*alignf)(void *, struct resource *, |
538 | unsigned long, unsigned long), | 538 | resource_size_t, resource_size_t), |
539 | void *alignf_data); | 539 | void *alignf_data); |
540 | void pci_enable_bridges(struct pci_bus *bus); | 540 | void pci_enable_bridges(struct pci_bus *bus); |
541 | 541 | ||
@@ -730,7 +730,8 @@ static inline char *pci_name(struct pci_dev *pdev) | |||
730 | */ | 730 | */ |
731 | #ifndef HAVE_ARCH_PCI_RESOURCE_TO_USER | 731 | #ifndef HAVE_ARCH_PCI_RESOURCE_TO_USER |
732 | static inline void pci_resource_to_user(const struct pci_dev *dev, int bar, | 732 | static inline void pci_resource_to_user(const struct pci_dev *dev, int bar, |
733 | const struct resource *rsrc, u64 *start, u64 *end) | 733 | const struct resource *rsrc, resource_size_t *start, |
734 | resource_size_t *end) | ||
734 | { | 735 | { |
735 | *start = rsrc->start; | 736 | *start = rsrc->start; |
736 | *end = rsrc->end; | 737 | *end = rsrc->end; |
diff --git a/include/linux/pnp.h b/include/linux/pnp.h index 93b0959eb40f..ab8a8dd8d64c 100644 --- a/include/linux/pnp.h +++ b/include/linux/pnp.h | |||
@@ -389,7 +389,8 @@ int pnp_start_dev(struct pnp_dev *dev); | |||
389 | int pnp_stop_dev(struct pnp_dev *dev); | 389 | int pnp_stop_dev(struct pnp_dev *dev); |
390 | int pnp_activate_dev(struct pnp_dev *dev); | 390 | int pnp_activate_dev(struct pnp_dev *dev); |
391 | int pnp_disable_dev(struct pnp_dev *dev); | 391 | int pnp_disable_dev(struct pnp_dev *dev); |
392 | void pnp_resource_change(struct resource *resource, unsigned long start, unsigned long size); | 392 | void pnp_resource_change(struct resource *resource, resource_size_t start, |
393 | resource_size_t size); | ||
393 | 394 | ||
394 | /* protocol helpers */ | 395 | /* protocol helpers */ |
395 | int pnp_is_active(struct pnp_dev * dev); | 396 | int pnp_is_active(struct pnp_dev * dev); |
@@ -434,7 +435,9 @@ static inline int pnp_start_dev(struct pnp_dev *dev) { return -ENODEV; } | |||
434 | static inline int pnp_stop_dev(struct pnp_dev *dev) { return -ENODEV; } | 435 | static inline int pnp_stop_dev(struct pnp_dev *dev) { return -ENODEV; } |
435 | static inline int pnp_activate_dev(struct pnp_dev *dev) { return -ENODEV; } | 436 | static inline int pnp_activate_dev(struct pnp_dev *dev) { return -ENODEV; } |
436 | static inline int pnp_disable_dev(struct pnp_dev *dev) { return -ENODEV; } | 437 | static inline int pnp_disable_dev(struct pnp_dev *dev) { return -ENODEV; } |
437 | static inline void pnp_resource_change(struct resource *resource, unsigned long start, unsigned long size) { } | 438 | static inline void pnp_resource_change(struct resource *resource, |
439 | resource_size_t start, | ||
440 | resource_size_t size) { } | ||
438 | 441 | ||
439 | /* protocol helpers */ | 442 | /* protocol helpers */ |
440 | static inline int pnp_is_active(struct pnp_dev * dev) { return 0; } | 443 | static inline int pnp_is_active(struct pnp_dev * dev) { return 0; } |
diff --git a/include/linux/types.h b/include/linux/types.h index a5e46e783ffa..3f235660a3cd 100644 --- a/include/linux/types.h +++ b/include/linux/types.h | |||
@@ -177,8 +177,15 @@ typedef __u64 __bitwise __be64; | |||
177 | 177 | ||
178 | #ifdef __KERNEL__ | 178 | #ifdef __KERNEL__ |
179 | typedef unsigned __bitwise__ gfp_t; | 179 | typedef unsigned __bitwise__ gfp_t; |
180 | |||
181 | #ifdef CONFIG_RESOURCES_64BIT | ||
182 | typedef u64 resource_size_t; | ||
183 | #else | ||
184 | typedef u32 resource_size_t; | ||
180 | #endif | 185 | #endif |
181 | 186 | ||
187 | #endif /* __KERNEL__ */ | ||
188 | |||
182 | struct ustat { | 189 | struct ustat { |
183 | __kernel_daddr_t f_tfree; | 190 | __kernel_daddr_t f_tfree; |
184 | __kernel_ino_t f_tinode; | 191 | __kernel_ino_t f_tinode; |
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h index 446afc3ea27f..758f8bf133c7 100644 --- a/include/sound/ac97_codec.h +++ b/include/sound/ac97_codec.h | |||
@@ -265,6 +265,7 @@ | |||
265 | 265 | ||
266 | /* specific - Analog Devices */ | 266 | /* specific - Analog Devices */ |
267 | #define AC97_AD_TEST 0x5a /* test register */ | 267 | #define AC97_AD_TEST 0x5a /* test register */ |
268 | #define AC97_AD_TEST2 0x5c /* undocumented test register 2 */ | ||
268 | #define AC97_AD_CODEC_CFG 0x70 /* codec configuration */ | 269 | #define AC97_AD_CODEC_CFG 0x70 /* codec configuration */ |
269 | #define AC97_AD_JACK_SPDIF 0x72 /* Jack Sense & S/PDIF */ | 270 | #define AC97_AD_JACK_SPDIF 0x72 /* Jack Sense & S/PDIF */ |
270 | #define AC97_AD_SERIAL_CFG 0x74 /* Serial Configuration */ | 271 | #define AC97_AD_SERIAL_CFG 0x74 /* Serial Configuration */ |
diff --git a/include/sound/ak4xxx-adda.h b/include/sound/ak4xxx-adda.h index 3bf5911fe827..3d9888492026 100644 --- a/include/sound/ak4xxx-adda.h +++ b/include/sound/ak4xxx-adda.h | |||
@@ -32,8 +32,8 @@ struct snd_akm4xxx; | |||
32 | struct snd_ak4xxx_ops { | 32 | struct snd_ak4xxx_ops { |
33 | void (*lock)(struct snd_akm4xxx *ak, int chip); | 33 | void (*lock)(struct snd_akm4xxx *ak, int chip); |
34 | void (*unlock)(struct snd_akm4xxx *ak, int chip); | 34 | void (*unlock)(struct snd_akm4xxx *ak, int chip); |
35 | void (*write)(struct snd_akm4xxx *ak, int chip, unsigned char reg, unsigned char val); | 35 | void (*write)(struct snd_akm4xxx *ak, int chip, unsigned char reg, |
36 | // unsigned char (*read)(struct snd_akm4xxx *ak, int chip, unsigned char reg); | 36 | unsigned char val); |
37 | void (*set_rate_val)(struct snd_akm4xxx *ak, unsigned int rate); | 37 | void (*set_rate_val)(struct snd_akm4xxx *ak, unsigned int rate); |
38 | }; | 38 | }; |
39 | 39 | ||
@@ -41,29 +41,40 @@ struct snd_ak4xxx_ops { | |||
41 | 41 | ||
42 | struct snd_akm4xxx { | 42 | struct snd_akm4xxx { |
43 | struct snd_card *card; | 43 | struct snd_card *card; |
44 | unsigned int num_adcs; /* AK4524 or AK4528 ADCs */ | 44 | unsigned int num_adcs; /* AK4524 or AK4528 ADCs */ |
45 | unsigned int num_dacs; /* AK4524 or AK4528 DACs */ | 45 | unsigned int num_dacs; /* AK4524 or AK4528 DACs */ |
46 | unsigned char images[AK4XXX_IMAGE_SIZE]; /* saved register image */ | 46 | unsigned char images[AK4XXX_IMAGE_SIZE]; /* saved register image */ |
47 | unsigned char ipga_gain[AK4XXX_MAX_CHIPS][2]; /* saved register image for IPGA (AK4528) */ | 47 | unsigned char ipga_gain[AK4XXX_MAX_CHIPS][2]; /* saved register image |
48 | * for IPGA (AK4528) | ||
49 | */ | ||
48 | unsigned long private_value[AK4XXX_MAX_CHIPS]; /* helper for driver */ | 50 | unsigned long private_value[AK4XXX_MAX_CHIPS]; /* helper for driver */ |
49 | void *private_data[AK4XXX_MAX_CHIPS]; /* helper for driver */ | 51 | void *private_data[AK4XXX_MAX_CHIPS]; /* helper for driver */ |
50 | /* template should fill the following fields */ | 52 | /* template should fill the following fields */ |
51 | unsigned int idx_offset; /* control index offset */ | 53 | unsigned int idx_offset; /* control index offset */ |
52 | enum { | 54 | enum { |
53 | SND_AK4524, SND_AK4528, SND_AK4529, | 55 | SND_AK4524, SND_AK4528, SND_AK4529, |
54 | SND_AK4355, SND_AK4358, SND_AK4381 | 56 | SND_AK4355, SND_AK4358, SND_AK4381 |
55 | } type; | 57 | } type; |
58 | unsigned int *num_stereo; /* array of combined counts | ||
59 | * for the mixer | ||
60 | */ | ||
61 | char **channel_names; /* array of mixer channel names */ | ||
56 | struct snd_ak4xxx_ops ops; | 62 | struct snd_ak4xxx_ops ops; |
57 | }; | 63 | }; |
58 | 64 | ||
59 | void snd_akm4xxx_write(struct snd_akm4xxx *ak, int chip, unsigned char reg, unsigned char val); | 65 | void snd_akm4xxx_write(struct snd_akm4xxx *ak, int chip, unsigned char reg, |
66 | unsigned char val); | ||
60 | void snd_akm4xxx_reset(struct snd_akm4xxx *ak, int state); | 67 | void snd_akm4xxx_reset(struct snd_akm4xxx *ak, int state); |
61 | void snd_akm4xxx_init(struct snd_akm4xxx *ak); | 68 | void snd_akm4xxx_init(struct snd_akm4xxx *ak); |
62 | int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak); | 69 | int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak); |
63 | 70 | ||
64 | #define snd_akm4xxx_get(ak,chip,reg) (ak)->images[(chip) * 16 + (reg)] | 71 | #define snd_akm4xxx_get(ak,chip,reg) \ |
65 | #define snd_akm4xxx_set(ak,chip,reg,val) ((ak)->images[(chip) * 16 + (reg)] = (val)) | 72 | (ak)->images[(chip) * 16 + (reg)] |
66 | #define snd_akm4xxx_get_ipga(ak,chip,reg) (ak)->ipga_gain[chip][(reg)-4] | 73 | #define snd_akm4xxx_set(ak,chip,reg,val) \ |
67 | #define snd_akm4xxx_set_ipga(ak,chip,reg,val) ((ak)->ipga_gain[chip][(reg)-4] = (val)) | 74 | ((ak)->images[(chip) * 16 + (reg)] = (val)) |
75 | #define snd_akm4xxx_get_ipga(ak,chip,reg) \ | ||
76 | (ak)->ipga_gain[chip][(reg)-4] | ||
77 | #define snd_akm4xxx_set_ipga(ak,chip,reg,val) \ | ||
78 | ((ak)->ipga_gain[chip][(reg)-4] = (val)) | ||
68 | 79 | ||
69 | #endif /* __SOUND_AK4XXX_ADDA_H */ | 80 | #endif /* __SOUND_AK4XXX_ADDA_H */ |
diff --git a/include/sound/initval.h b/include/sound/initval.h index d29e3d31d149..d45170b9e0b7 100644 --- a/include/sound/initval.h +++ b/include/sound/initval.h | |||
@@ -62,7 +62,8 @@ static int snd_legacy_find_free_irq(int *irq_table) | |||
62 | { | 62 | { |
63 | while (*irq_table != -1) { | 63 | while (*irq_table != -1) { |
64 | if (!request_irq(*irq_table, snd_legacy_empty_irq_handler, | 64 | if (!request_irq(*irq_table, snd_legacy_empty_irq_handler, |
65 | SA_INTERRUPT, "ALSA Test IRQ", (void *) irq_table)) { | 65 | SA_INTERRUPT | SA_PROBEIRQ, "ALSA Test IRQ", |
66 | (void *) irq_table)) { | ||
66 | free_irq(*irq_table, (void *) irq_table); | 67 | free_irq(*irq_table, (void *) irq_table); |
67 | return *irq_table; | 68 | return *irq_table; |
68 | } | 69 | } |
diff --git a/kernel/irq/Makefile b/kernel/irq/Makefile index 9f77f50d8143..1dab0ac3f797 100644 --- a/kernel/irq/Makefile +++ b/kernel/irq/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | 1 | ||
2 | obj-y := handle.o manage.o spurious.o | 2 | obj-y := handle.o manage.o spurious.o resend.o chip.o |
3 | obj-$(CONFIG_GENERIC_IRQ_PROBE) += autoprobe.o | 3 | obj-$(CONFIG_GENERIC_IRQ_PROBE) += autoprobe.o |
4 | obj-$(CONFIG_PROC_FS) += proc.o | 4 | obj-$(CONFIG_PROC_FS) += proc.o |
5 | obj-$(CONFIG_GENERIC_PENDING_IRQ) += migration.o | 5 | obj-$(CONFIG_GENERIC_PENDING_IRQ) += migration.o |
diff --git a/kernel/irq/autoprobe.c b/kernel/irq/autoprobe.c index 3467097ca61a..533068cfb607 100644 --- a/kernel/irq/autoprobe.c +++ b/kernel/irq/autoprobe.c | |||
@@ -11,12 +11,14 @@ | |||
11 | #include <linux/interrupt.h> | 11 | #include <linux/interrupt.h> |
12 | #include <linux/delay.h> | 12 | #include <linux/delay.h> |
13 | 13 | ||
14 | #include "internals.h" | ||
15 | |||
14 | /* | 16 | /* |
15 | * Autodetection depends on the fact that any interrupt that | 17 | * Autodetection depends on the fact that any interrupt that |
16 | * comes in on to an unassigned handler will get stuck with | 18 | * comes in on to an unassigned handler will get stuck with |
17 | * "IRQ_WAITING" cleared and the interrupt disabled. | 19 | * "IRQ_WAITING" cleared and the interrupt disabled. |
18 | */ | 20 | */ |
19 | static DECLARE_MUTEX(probe_sem); | 21 | static DEFINE_MUTEX(probing_active); |
20 | 22 | ||
21 | /** | 23 | /** |
22 | * probe_irq_on - begin an interrupt autodetect | 24 | * probe_irq_on - begin an interrupt autodetect |
@@ -27,11 +29,11 @@ static DECLARE_MUTEX(probe_sem); | |||
27 | */ | 29 | */ |
28 | unsigned long probe_irq_on(void) | 30 | unsigned long probe_irq_on(void) |
29 | { | 31 | { |
30 | unsigned long val; | 32 | struct irq_desc *desc; |
31 | irq_desc_t *desc; | 33 | unsigned long mask; |
32 | unsigned int i; | 34 | unsigned int i; |
33 | 35 | ||
34 | down(&probe_sem); | 36 | mutex_lock(&probing_active); |
35 | /* | 37 | /* |
36 | * something may have generated an irq long ago and we want to | 38 | * something may have generated an irq long ago and we want to |
37 | * flush such a longstanding irq before considering it as spurious. | 39 | * flush such a longstanding irq before considering it as spurious. |
@@ -40,8 +42,21 @@ unsigned long probe_irq_on(void) | |||
40 | desc = irq_desc + i; | 42 | desc = irq_desc + i; |
41 | 43 | ||
42 | spin_lock_irq(&desc->lock); | 44 | spin_lock_irq(&desc->lock); |
43 | if (!irq_desc[i].action) | 45 | if (!desc->action && !(desc->status & IRQ_NOPROBE)) { |
44 | irq_desc[i].handler->startup(i); | 46 | /* |
47 | * An old-style architecture might still have | ||
48 | * the handle_bad_irq handler there: | ||
49 | */ | ||
50 | compat_irq_chip_set_default_handler(desc); | ||
51 | |||
52 | /* | ||
53 | * Some chips need to know about probing in | ||
54 | * progress: | ||
55 | */ | ||
56 | if (desc->chip->set_type) | ||
57 | desc->chip->set_type(i, IRQ_TYPE_PROBE); | ||
58 | desc->chip->startup(i); | ||
59 | } | ||
45 | spin_unlock_irq(&desc->lock); | 60 | spin_unlock_irq(&desc->lock); |
46 | } | 61 | } |
47 | 62 | ||
@@ -57,9 +72,9 @@ unsigned long probe_irq_on(void) | |||
57 | desc = irq_desc + i; | 72 | desc = irq_desc + i; |
58 | 73 | ||
59 | spin_lock_irq(&desc->lock); | 74 | spin_lock_irq(&desc->lock); |
60 | if (!desc->action) { | 75 | if (!desc->action && !(desc->status & IRQ_NOPROBE)) { |
61 | desc->status |= IRQ_AUTODETECT | IRQ_WAITING; | 76 | desc->status |= IRQ_AUTODETECT | IRQ_WAITING; |
62 | if (desc->handler->startup(i)) | 77 | if (desc->chip->startup(i)) |
63 | desc->status |= IRQ_PENDING; | 78 | desc->status |= IRQ_PENDING; |
64 | } | 79 | } |
65 | spin_unlock_irq(&desc->lock); | 80 | spin_unlock_irq(&desc->lock); |
@@ -73,11 +88,11 @@ unsigned long probe_irq_on(void) | |||
73 | /* | 88 | /* |
74 | * Now filter out any obviously spurious interrupts | 89 | * Now filter out any obviously spurious interrupts |
75 | */ | 90 | */ |
76 | val = 0; | 91 | mask = 0; |
77 | for (i = 0; i < NR_IRQS; i++) { | 92 | for (i = 0; i < NR_IRQS; i++) { |
78 | irq_desc_t *desc = irq_desc + i; | ||
79 | unsigned int status; | 93 | unsigned int status; |
80 | 94 | ||
95 | desc = irq_desc + i; | ||
81 | spin_lock_irq(&desc->lock); | 96 | spin_lock_irq(&desc->lock); |
82 | status = desc->status; | 97 | status = desc->status; |
83 | 98 | ||
@@ -85,17 +100,16 @@ unsigned long probe_irq_on(void) | |||
85 | /* It triggered already - consider it spurious. */ | 100 | /* It triggered already - consider it spurious. */ |
86 | if (!(status & IRQ_WAITING)) { | 101 | if (!(status & IRQ_WAITING)) { |
87 | desc->status = status & ~IRQ_AUTODETECT; | 102 | desc->status = status & ~IRQ_AUTODETECT; |
88 | desc->handler->shutdown(i); | 103 | desc->chip->shutdown(i); |
89 | } else | 104 | } else |
90 | if (i < 32) | 105 | if (i < 32) |
91 | val |= 1 << i; | 106 | mask |= 1 << i; |
92 | } | 107 | } |
93 | spin_unlock_irq(&desc->lock); | 108 | spin_unlock_irq(&desc->lock); |
94 | } | 109 | } |
95 | 110 | ||
96 | return val; | 111 | return mask; |
97 | } | 112 | } |
98 | |||
99 | EXPORT_SYMBOL(probe_irq_on); | 113 | EXPORT_SYMBOL(probe_irq_on); |
100 | 114 | ||
101 | /** | 115 | /** |
@@ -117,7 +131,7 @@ unsigned int probe_irq_mask(unsigned long val) | |||
117 | 131 | ||
118 | mask = 0; | 132 | mask = 0; |
119 | for (i = 0; i < NR_IRQS; i++) { | 133 | for (i = 0; i < NR_IRQS; i++) { |
120 | irq_desc_t *desc = irq_desc + i; | 134 | struct irq_desc *desc = irq_desc + i; |
121 | unsigned int status; | 135 | unsigned int status; |
122 | 136 | ||
123 | spin_lock_irq(&desc->lock); | 137 | spin_lock_irq(&desc->lock); |
@@ -128,11 +142,11 @@ unsigned int probe_irq_mask(unsigned long val) | |||
128 | mask |= 1 << i; | 142 | mask |= 1 << i; |
129 | 143 | ||
130 | desc->status = status & ~IRQ_AUTODETECT; | 144 | desc->status = status & ~IRQ_AUTODETECT; |
131 | desc->handler->shutdown(i); | 145 | desc->chip->shutdown(i); |
132 | } | 146 | } |
133 | spin_unlock_irq(&desc->lock); | 147 | spin_unlock_irq(&desc->lock); |
134 | } | 148 | } |
135 | up(&probe_sem); | 149 | mutex_unlock(&probing_active); |
136 | 150 | ||
137 | return mask & val; | 151 | return mask & val; |
138 | } | 152 | } |
@@ -160,7 +174,7 @@ int probe_irq_off(unsigned long val) | |||
160 | int i, irq_found = 0, nr_irqs = 0; | 174 | int i, irq_found = 0, nr_irqs = 0; |
161 | 175 | ||
162 | for (i = 0; i < NR_IRQS; i++) { | 176 | for (i = 0; i < NR_IRQS; i++) { |
163 | irq_desc_t *desc = irq_desc + i; | 177 | struct irq_desc *desc = irq_desc + i; |
164 | unsigned int status; | 178 | unsigned int status; |
165 | 179 | ||
166 | spin_lock_irq(&desc->lock); | 180 | spin_lock_irq(&desc->lock); |
@@ -173,16 +187,16 @@ int probe_irq_off(unsigned long val) | |||
173 | nr_irqs++; | 187 | nr_irqs++; |
174 | } | 188 | } |
175 | desc->status = status & ~IRQ_AUTODETECT; | 189 | desc->status = status & ~IRQ_AUTODETECT; |
176 | desc->handler->shutdown(i); | 190 | desc->chip->shutdown(i); |
177 | } | 191 | } |
178 | spin_unlock_irq(&desc->lock); | 192 | spin_unlock_irq(&desc->lock); |
179 | } | 193 | } |
180 | up(&probe_sem); | 194 | mutex_unlock(&probing_active); |
181 | 195 | ||
182 | if (nr_irqs > 1) | 196 | if (nr_irqs > 1) |
183 | irq_found = -irq_found; | 197 | irq_found = -irq_found; |
198 | |||
184 | return irq_found; | 199 | return irq_found; |
185 | } | 200 | } |
186 | |||
187 | EXPORT_SYMBOL(probe_irq_off); | 201 | EXPORT_SYMBOL(probe_irq_off); |
188 | 202 | ||
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c new file mode 100644 index 000000000000..4a0952d9458b --- /dev/null +++ b/kernel/irq/chip.c | |||
@@ -0,0 +1,525 @@ | |||
1 | /* | ||
2 | * linux/kernel/irq/chip.c | ||
3 | * | ||
4 | * Copyright (C) 1992, 1998-2006 Linus Torvalds, Ingo Molnar | ||
5 | * Copyright (C) 2005-2006, Thomas Gleixner, Russell King | ||
6 | * | ||
7 | * This file contains the core interrupt handling code, for irq-chip | ||
8 | * based architectures. | ||
9 | * | ||
10 | * Detailed information is available in Documentation/DocBook/genericirq | ||
11 | */ | ||
12 | |||
13 | #include <linux/irq.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/kernel_stat.h> | ||
17 | |||
18 | #include "internals.h" | ||
19 | |||
20 | /** | ||
21 | * set_irq_chip - set the irq chip for an irq | ||
22 | * @irq: irq number | ||
23 | * @chip: pointer to irq chip description structure | ||
24 | */ | ||
25 | int set_irq_chip(unsigned int irq, struct irq_chip *chip) | ||
26 | { | ||
27 | struct irq_desc *desc; | ||
28 | unsigned long flags; | ||
29 | |||
30 | if (irq >= NR_IRQS) { | ||
31 | printk(KERN_ERR "Trying to install chip for IRQ%d\n", irq); | ||
32 | WARN_ON(1); | ||
33 | return -EINVAL; | ||
34 | } | ||
35 | |||
36 | if (!chip) | ||
37 | chip = &no_irq_chip; | ||
38 | |||
39 | desc = irq_desc + irq; | ||
40 | spin_lock_irqsave(&desc->lock, flags); | ||
41 | irq_chip_set_defaults(chip); | ||
42 | desc->chip = chip; | ||
43 | /* | ||
44 | * For compatibility only: | ||
45 | */ | ||
46 | desc->chip = chip; | ||
47 | spin_unlock_irqrestore(&desc->lock, flags); | ||
48 | |||
49 | return 0; | ||
50 | } | ||
51 | EXPORT_SYMBOL(set_irq_chip); | ||
52 | |||
53 | /** | ||
54 | * set_irq_type - set the irq type for an irq | ||
55 | * @irq: irq number | ||
56 | * @type: interrupt type - see include/linux/interrupt.h | ||
57 | */ | ||
58 | int set_irq_type(unsigned int irq, unsigned int type) | ||
59 | { | ||
60 | struct irq_desc *desc; | ||
61 | unsigned long flags; | ||
62 | int ret = -ENXIO; | ||
63 | |||
64 | if (irq >= NR_IRQS) { | ||
65 | printk(KERN_ERR "Trying to set irq type for IRQ%d\n", irq); | ||
66 | return -ENODEV; | ||
67 | } | ||
68 | |||
69 | desc = irq_desc + irq; | ||
70 | if (desc->chip->set_type) { | ||
71 | spin_lock_irqsave(&desc->lock, flags); | ||
72 | ret = desc->chip->set_type(irq, type); | ||
73 | spin_unlock_irqrestore(&desc->lock, flags); | ||
74 | } | ||
75 | return ret; | ||
76 | } | ||
77 | EXPORT_SYMBOL(set_irq_type); | ||
78 | |||
79 | /** | ||
80 | * set_irq_data - set irq type data for an irq | ||
81 | * @irq: Interrupt number | ||
82 | * @data: Pointer to interrupt specific data | ||
83 | * | ||
84 | * Set the hardware irq controller data for an irq | ||
85 | */ | ||
86 | int set_irq_data(unsigned int irq, void *data) | ||
87 | { | ||
88 | struct irq_desc *desc; | ||
89 | unsigned long flags; | ||
90 | |||
91 | if (irq >= NR_IRQS) { | ||
92 | printk(KERN_ERR | ||
93 | "Trying to install controller data for IRQ%d\n", irq); | ||
94 | return -EINVAL; | ||
95 | } | ||
96 | |||
97 | desc = irq_desc + irq; | ||
98 | spin_lock_irqsave(&desc->lock, flags); | ||
99 | desc->handler_data = data; | ||
100 | spin_unlock_irqrestore(&desc->lock, flags); | ||
101 | return 0; | ||
102 | } | ||
103 | EXPORT_SYMBOL(set_irq_data); | ||
104 | |||
105 | /** | ||
106 | * set_irq_chip_data - set irq chip data for an irq | ||
107 | * @irq: Interrupt number | ||
108 | * @data: Pointer to chip specific data | ||
109 | * | ||
110 | * Set the hardware irq chip data for an irq | ||
111 | */ | ||
112 | int set_irq_chip_data(unsigned int irq, void *data) | ||
113 | { | ||
114 | struct irq_desc *desc = irq_desc + irq; | ||
115 | unsigned long flags; | ||
116 | |||
117 | if (irq >= NR_IRQS || !desc->chip) { | ||
118 | printk(KERN_ERR "BUG: bad set_irq_chip_data(IRQ#%d)\n", irq); | ||
119 | return -EINVAL; | ||
120 | } | ||
121 | |||
122 | spin_lock_irqsave(&desc->lock, flags); | ||
123 | desc->chip_data = data; | ||
124 | spin_unlock_irqrestore(&desc->lock, flags); | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | EXPORT_SYMBOL(set_irq_chip_data); | ||
129 | |||
130 | /* | ||
131 | * default enable function | ||
132 | */ | ||
133 | static void default_enable(unsigned int irq) | ||
134 | { | ||
135 | struct irq_desc *desc = irq_desc + irq; | ||
136 | |||
137 | desc->chip->unmask(irq); | ||
138 | desc->status &= ~IRQ_MASKED; | ||
139 | } | ||
140 | |||
141 | /* | ||
142 | * default disable function | ||
143 | */ | ||
144 | static void default_disable(unsigned int irq) | ||
145 | { | ||
146 | struct irq_desc *desc = irq_desc + irq; | ||
147 | |||
148 | if (!(desc->status & IRQ_DELAYED_DISABLE)) | ||
149 | irq_desc[irq].chip->mask(irq); | ||
150 | } | ||
151 | |||
152 | /* | ||
153 | * default startup function | ||
154 | */ | ||
155 | static unsigned int default_startup(unsigned int irq) | ||
156 | { | ||
157 | irq_desc[irq].chip->enable(irq); | ||
158 | |||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | /* | ||
163 | * Fixup enable/disable function pointers | ||
164 | */ | ||
165 | void irq_chip_set_defaults(struct irq_chip *chip) | ||
166 | { | ||
167 | if (!chip->enable) | ||
168 | chip->enable = default_enable; | ||
169 | if (!chip->disable) | ||
170 | chip->disable = default_disable; | ||
171 | if (!chip->startup) | ||
172 | chip->startup = default_startup; | ||
173 | if (!chip->shutdown) | ||
174 | chip->shutdown = chip->disable; | ||
175 | if (!chip->name) | ||
176 | chip->name = chip->typename; | ||
177 | } | ||
178 | |||
179 | static inline void mask_ack_irq(struct irq_desc *desc, int irq) | ||
180 | { | ||
181 | if (desc->chip->mask_ack) | ||
182 | desc->chip->mask_ack(irq); | ||
183 | else { | ||
184 | desc->chip->mask(irq); | ||
185 | desc->chip->ack(irq); | ||
186 | } | ||
187 | } | ||
188 | |||
189 | /** | ||
190 | * handle_simple_irq - Simple and software-decoded IRQs. | ||
191 | * @irq: the interrupt number | ||
192 | * @desc: the interrupt description structure for this irq | ||
193 | * @regs: pointer to a register structure | ||
194 | * | ||
195 | * Simple interrupts are either sent from a demultiplexing interrupt | ||
196 | * handler or come from hardware, where no interrupt hardware control | ||
197 | * is necessary. | ||
198 | * | ||
199 | * Note: The caller is expected to handle the ack, clear, mask and | ||
200 | * unmask issues if necessary. | ||
201 | */ | ||
202 | void fastcall | ||
203 | handle_simple_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs) | ||
204 | { | ||
205 | struct irqaction *action; | ||
206 | irqreturn_t action_ret; | ||
207 | const unsigned int cpu = smp_processor_id(); | ||
208 | |||
209 | spin_lock(&desc->lock); | ||
210 | |||
211 | if (unlikely(desc->status & IRQ_INPROGRESS)) | ||
212 | goto out_unlock; | ||
213 | desc->status &= ~(IRQ_REPLAY | IRQ_WAITING); | ||
214 | kstat_cpu(cpu).irqs[irq]++; | ||
215 | |||
216 | action = desc->action; | ||
217 | if (unlikely(!action || (desc->status & IRQ_DISABLED))) | ||
218 | goto out_unlock; | ||
219 | |||
220 | desc->status |= IRQ_INPROGRESS; | ||
221 | spin_unlock(&desc->lock); | ||
222 | |||
223 | action_ret = handle_IRQ_event(irq, regs, action); | ||
224 | if (!noirqdebug) | ||
225 | note_interrupt(irq, desc, action_ret, regs); | ||
226 | |||
227 | spin_lock(&desc->lock); | ||
228 | desc->status &= ~IRQ_INPROGRESS; | ||
229 | out_unlock: | ||
230 | spin_unlock(&desc->lock); | ||
231 | } | ||
232 | |||
233 | /** | ||
234 | * handle_level_irq - Level type irq handler | ||
235 | * @irq: the interrupt number | ||
236 | * @desc: the interrupt description structure for this irq | ||
237 | * @regs: pointer to a register structure | ||
238 | * | ||
239 | * Level type interrupts are active as long as the hardware line has | ||
240 | * the active level. This may require to mask the interrupt and unmask | ||
241 | * it after the associated handler has acknowledged the device, so the | ||
242 | * interrupt line is back to inactive. | ||
243 | */ | ||
244 | void fastcall | ||
245 | handle_level_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs) | ||
246 | { | ||
247 | unsigned int cpu = smp_processor_id(); | ||
248 | struct irqaction *action; | ||
249 | irqreturn_t action_ret; | ||
250 | |||
251 | spin_lock(&desc->lock); | ||
252 | mask_ack_irq(desc, irq); | ||
253 | |||
254 | if (unlikely(desc->status & IRQ_INPROGRESS)) | ||
255 | goto out; | ||
256 | desc->status &= ~(IRQ_REPLAY | IRQ_WAITING); | ||
257 | kstat_cpu(cpu).irqs[irq]++; | ||
258 | |||
259 | /* | ||
260 | * If its disabled or no action available | ||
261 | * keep it masked and get out of here | ||
262 | */ | ||
263 | action = desc->action; | ||
264 | if (unlikely(!action || (desc->status & IRQ_DISABLED))) | ||
265 | goto out; | ||
266 | |||
267 | desc->status |= IRQ_INPROGRESS; | ||
268 | spin_unlock(&desc->lock); | ||
269 | |||
270 | action_ret = handle_IRQ_event(irq, regs, action); | ||
271 | if (!noirqdebug) | ||
272 | note_interrupt(irq, desc, action_ret, regs); | ||
273 | |||
274 | spin_lock(&desc->lock); | ||
275 | desc->status &= ~IRQ_INPROGRESS; | ||
276 | out: | ||
277 | if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask) | ||
278 | desc->chip->unmask(irq); | ||
279 | spin_unlock(&desc->lock); | ||
280 | } | ||
281 | |||
282 | /** | ||
283 | * handle_fasteoi_irq - irq handler for transparent controllers | ||
284 | * @irq: the interrupt number | ||
285 | * @desc: the interrupt description structure for this irq | ||
286 | * @regs: pointer to a register structure | ||
287 | * | ||
288 | * Only a single callback will be issued to the chip: an ->eoi() | ||
289 | * call when the interrupt has been serviced. This enables support | ||
290 | * for modern forms of interrupt handlers, which handle the flow | ||
291 | * details in hardware, transparently. | ||
292 | */ | ||
293 | void fastcall | ||
294 | handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc, | ||
295 | struct pt_regs *regs) | ||
296 | { | ||
297 | unsigned int cpu = smp_processor_id(); | ||
298 | struct irqaction *action; | ||
299 | irqreturn_t action_ret; | ||
300 | |||
301 | spin_lock(&desc->lock); | ||
302 | |||
303 | if (unlikely(desc->status & IRQ_INPROGRESS)) | ||
304 | goto out; | ||
305 | |||
306 | desc->status &= ~(IRQ_REPLAY | IRQ_WAITING); | ||
307 | kstat_cpu(cpu).irqs[irq]++; | ||
308 | |||
309 | /* | ||
310 | * If its disabled or no action available | ||
311 | * keep it masked and get out of here | ||
312 | */ | ||
313 | action = desc->action; | ||
314 | if (unlikely(!action || (desc->status & IRQ_DISABLED))) { | ||
315 | desc->status |= IRQ_PENDING; | ||
316 | goto out; | ||
317 | } | ||
318 | |||
319 | desc->status |= IRQ_INPROGRESS; | ||
320 | desc->status &= ~IRQ_PENDING; | ||
321 | spin_unlock(&desc->lock); | ||
322 | |||
323 | action_ret = handle_IRQ_event(irq, regs, action); | ||
324 | if (!noirqdebug) | ||
325 | note_interrupt(irq, desc, action_ret, regs); | ||
326 | |||
327 | spin_lock(&desc->lock); | ||
328 | desc->status &= ~IRQ_INPROGRESS; | ||
329 | out: | ||
330 | desc->chip->eoi(irq); | ||
331 | |||
332 | spin_unlock(&desc->lock); | ||
333 | } | ||
334 | |||
335 | /** | ||
336 | * handle_edge_irq - edge type IRQ handler | ||
337 | * @irq: the interrupt number | ||
338 | * @desc: the interrupt description structure for this irq | ||
339 | * @regs: pointer to a register structure | ||
340 | * | ||
341 | * Interrupt occures on the falling and/or rising edge of a hardware | ||
342 | * signal. The occurence is latched into the irq controller hardware | ||
343 | * and must be acked in order to be reenabled. After the ack another | ||
344 | * interrupt can happen on the same source even before the first one | ||
345 | * is handled by the assosiacted event handler. If this happens it | ||
346 | * might be necessary to disable (mask) the interrupt depending on the | ||
347 | * controller hardware. This requires to reenable the interrupt inside | ||
348 | * of the loop which handles the interrupts which have arrived while | ||
349 | * the handler was running. If all pending interrupts are handled, the | ||
350 | * loop is left. | ||
351 | */ | ||
352 | void fastcall | ||
353 | handle_edge_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs) | ||
354 | { | ||
355 | const unsigned int cpu = smp_processor_id(); | ||
356 | |||
357 | spin_lock(&desc->lock); | ||
358 | |||
359 | desc->status &= ~(IRQ_REPLAY | IRQ_WAITING); | ||
360 | |||
361 | /* | ||
362 | * If we're currently running this IRQ, or its disabled, | ||
363 | * we shouldn't process the IRQ. Mark it pending, handle | ||
364 | * the necessary masking and go out | ||
365 | */ | ||
366 | if (unlikely((desc->status & (IRQ_INPROGRESS | IRQ_DISABLED)) || | ||
367 | !desc->action)) { | ||
368 | desc->status |= (IRQ_PENDING | IRQ_MASKED); | ||
369 | mask_ack_irq(desc, irq); | ||
370 | goto out_unlock; | ||
371 | } | ||
372 | |||
373 | kstat_cpu(cpu).irqs[irq]++; | ||
374 | |||
375 | /* Start handling the irq */ | ||
376 | desc->chip->ack(irq); | ||
377 | |||
378 | /* Mark the IRQ currently in progress.*/ | ||
379 | desc->status |= IRQ_INPROGRESS; | ||
380 | |||
381 | do { | ||
382 | struct irqaction *action = desc->action; | ||
383 | irqreturn_t action_ret; | ||
384 | |||
385 | if (unlikely(!action)) { | ||
386 | desc->chip->mask(irq); | ||
387 | goto out_unlock; | ||
388 | } | ||
389 | |||
390 | /* | ||
391 | * When another irq arrived while we were handling | ||
392 | * one, we could have masked the irq. | ||
393 | * Renable it, if it was not disabled in meantime. | ||
394 | */ | ||
395 | if (unlikely((desc->status & | ||
396 | (IRQ_PENDING | IRQ_MASKED | IRQ_DISABLED)) == | ||
397 | (IRQ_PENDING | IRQ_MASKED))) { | ||
398 | desc->chip->unmask(irq); | ||
399 | desc->status &= ~IRQ_MASKED; | ||
400 | } | ||
401 | |||
402 | desc->status &= ~IRQ_PENDING; | ||
403 | spin_unlock(&desc->lock); | ||
404 | action_ret = handle_IRQ_event(irq, regs, action); | ||
405 | if (!noirqdebug) | ||
406 | note_interrupt(irq, desc, action_ret, regs); | ||
407 | spin_lock(&desc->lock); | ||
408 | |||
409 | } while ((desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING); | ||
410 | |||
411 | desc->status &= ~IRQ_INPROGRESS; | ||
412 | out_unlock: | ||
413 | spin_unlock(&desc->lock); | ||
414 | } | ||
415 | |||
416 | #ifdef CONFIG_SMP | ||
417 | /** | ||
418 | * handle_percpu_IRQ - Per CPU local irq handler | ||
419 | * @irq: the interrupt number | ||
420 | * @desc: the interrupt description structure for this irq | ||
421 | * @regs: pointer to a register structure | ||
422 | * | ||
423 | * Per CPU interrupts on SMP machines without locking requirements | ||
424 | */ | ||
425 | void fastcall | ||
426 | handle_percpu_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs) | ||
427 | { | ||
428 | irqreturn_t action_ret; | ||
429 | |||
430 | kstat_this_cpu.irqs[irq]++; | ||
431 | |||
432 | if (desc->chip->ack) | ||
433 | desc->chip->ack(irq); | ||
434 | |||
435 | action_ret = handle_IRQ_event(irq, regs, desc->action); | ||
436 | if (!noirqdebug) | ||
437 | note_interrupt(irq, desc, action_ret, regs); | ||
438 | |||
439 | if (desc->chip->eoi) | ||
440 | desc->chip->eoi(irq); | ||
441 | } | ||
442 | |||
443 | #endif /* CONFIG_SMP */ | ||
444 | |||
445 | void | ||
446 | __set_irq_handler(unsigned int irq, | ||
447 | void fastcall (*handle)(unsigned int, irq_desc_t *, | ||
448 | struct pt_regs *), | ||
449 | int is_chained) | ||
450 | { | ||
451 | struct irq_desc *desc; | ||
452 | unsigned long flags; | ||
453 | |||
454 | if (irq >= NR_IRQS) { | ||
455 | printk(KERN_ERR | ||
456 | "Trying to install type control for IRQ%d\n", irq); | ||
457 | return; | ||
458 | } | ||
459 | |||
460 | desc = irq_desc + irq; | ||
461 | |||
462 | if (!handle) | ||
463 | handle = handle_bad_irq; | ||
464 | |||
465 | if (is_chained && desc->chip == &no_irq_chip) | ||
466 | printk(KERN_WARNING "Trying to install " | ||
467 | "chained interrupt type for IRQ%d\n", irq); | ||
468 | |||
469 | spin_lock_irqsave(&desc->lock, flags); | ||
470 | |||
471 | /* Uninstall? */ | ||
472 | if (handle == handle_bad_irq) { | ||
473 | if (desc->chip != &no_irq_chip) { | ||
474 | desc->chip->mask(irq); | ||
475 | desc->chip->ack(irq); | ||
476 | } | ||
477 | desc->status |= IRQ_DISABLED; | ||
478 | desc->depth = 1; | ||
479 | } | ||
480 | desc->handle_irq = handle; | ||
481 | |||
482 | if (handle != handle_bad_irq && is_chained) { | ||
483 | desc->status &= ~IRQ_DISABLED; | ||
484 | desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE; | ||
485 | desc->depth = 0; | ||
486 | desc->chip->unmask(irq); | ||
487 | } | ||
488 | spin_unlock_irqrestore(&desc->lock, flags); | ||
489 | } | ||
490 | |||
491 | void | ||
492 | set_irq_chip_and_handler(unsigned int irq, struct irq_chip *chip, | ||
493 | void fastcall (*handle)(unsigned int, | ||
494 | struct irq_desc *, | ||
495 | struct pt_regs *)) | ||
496 | { | ||
497 | set_irq_chip(irq, chip); | ||
498 | __set_irq_handler(irq, handle, 0); | ||
499 | } | ||
500 | |||
501 | /* | ||
502 | * Get a descriptive string for the highlevel handler, for | ||
503 | * /proc/interrupts output: | ||
504 | */ | ||
505 | const char * | ||
506 | handle_irq_name(void fastcall (*handle)(unsigned int, struct irq_desc *, | ||
507 | struct pt_regs *)) | ||
508 | { | ||
509 | if (handle == handle_level_irq) | ||
510 | return "level "; | ||
511 | if (handle == handle_fasteoi_irq) | ||
512 | return "fasteoi"; | ||
513 | if (handle == handle_edge_irq) | ||
514 | return "edge "; | ||
515 | if (handle == handle_simple_irq) | ||
516 | return "simple "; | ||
517 | #ifdef CONFIG_SMP | ||
518 | if (handle == handle_percpu_irq) | ||
519 | return "percpu "; | ||
520 | #endif | ||
521 | if (handle == handle_bad_irq) | ||
522 | return "bad "; | ||
523 | |||
524 | return NULL; | ||
525 | } | ||
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c index 0f6530117105..5a360dd4331b 100644 --- a/kernel/irq/handle.c +++ b/kernel/irq/handle.c | |||
@@ -1,9 +1,13 @@ | |||
1 | /* | 1 | /* |
2 | * linux/kernel/irq/handle.c | 2 | * linux/kernel/irq/handle.c |
3 | * | 3 | * |
4 | * Copyright (C) 1992, 1998-2004 Linus Torvalds, Ingo Molnar | 4 | * Copyright (C) 1992, 1998-2006 Linus Torvalds, Ingo Molnar |
5 | * Copyright (C) 2005-2006, Thomas Gleixner, Russell King | ||
5 | * | 6 | * |
6 | * This file contains the core interrupt handling code. | 7 | * This file contains the core interrupt handling code. |
8 | * | ||
9 | * Detailed information is available in Documentation/DocBook/genericirq | ||
10 | * | ||
7 | */ | 11 | */ |
8 | 12 | ||
9 | #include <linux/irq.h> | 13 | #include <linux/irq.h> |
@@ -14,11 +18,22 @@ | |||
14 | 18 | ||
15 | #include "internals.h" | 19 | #include "internals.h" |
16 | 20 | ||
21 | /** | ||
22 | * handle_bad_irq - handle spurious and unhandled irqs | ||
23 | */ | ||
24 | void fastcall | ||
25 | handle_bad_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs) | ||
26 | { | ||
27 | print_irq_desc(irq, desc); | ||
28 | kstat_this_cpu.irqs[irq]++; | ||
29 | ack_bad_irq(irq); | ||
30 | } | ||
31 | |||
17 | /* | 32 | /* |
18 | * Linux has a controller-independent interrupt architecture. | 33 | * Linux has a controller-independent interrupt architecture. |
19 | * Every controller has a 'controller-template', that is used | 34 | * Every controller has a 'controller-template', that is used |
20 | * by the main code to do the right thing. Each driver-visible | 35 | * by the main code to do the right thing. Each driver-visible |
21 | * interrupt source is transparently wired to the apropriate | 36 | * interrupt source is transparently wired to the appropriate |
22 | * controller. Thus drivers need not be aware of the | 37 | * controller. Thus drivers need not be aware of the |
23 | * interrupt-controller. | 38 | * interrupt-controller. |
24 | * | 39 | * |
@@ -28,41 +43,52 @@ | |||
28 | * | 43 | * |
29 | * Controller mappings for all interrupt sources: | 44 | * Controller mappings for all interrupt sources: |
30 | */ | 45 | */ |
31 | irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = { | 46 | struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned = { |
32 | [0 ... NR_IRQS-1] = { | 47 | [0 ... NR_IRQS-1] = { |
33 | .status = IRQ_DISABLED, | 48 | .status = IRQ_DISABLED, |
34 | .handler = &no_irq_type, | 49 | .chip = &no_irq_chip, |
35 | .lock = SPIN_LOCK_UNLOCKED | 50 | .handle_irq = handle_bad_irq, |
51 | .depth = 1, | ||
52 | .lock = SPIN_LOCK_UNLOCKED, | ||
53 | #ifdef CONFIG_SMP | ||
54 | .affinity = CPU_MASK_ALL | ||
55 | #endif | ||
36 | } | 56 | } |
37 | }; | 57 | }; |
38 | 58 | ||
39 | /* | 59 | /* |
40 | * Generic 'no controller' code | 60 | * What should we do if we get a hw irq event on an illegal vector? |
61 | * Each architecture has to answer this themself. | ||
41 | */ | 62 | */ |
42 | static void end_none(unsigned int irq) { } | 63 | static void ack_bad(unsigned int irq) |
43 | static void enable_none(unsigned int irq) { } | ||
44 | static void disable_none(unsigned int irq) { } | ||
45 | static void shutdown_none(unsigned int irq) { } | ||
46 | static unsigned int startup_none(unsigned int irq) { return 0; } | ||
47 | |||
48 | static void ack_none(unsigned int irq) | ||
49 | { | 64 | { |
50 | /* | 65 | print_irq_desc(irq, irq_desc + irq); |
51 | * 'what should we do if we get a hw irq event on an illegal vector'. | ||
52 | * each architecture has to answer this themself. | ||
53 | */ | ||
54 | ack_bad_irq(irq); | 66 | ack_bad_irq(irq); |
55 | } | 67 | } |
56 | 68 | ||
57 | struct hw_interrupt_type no_irq_type = { | 69 | /* |
58 | .typename = "none", | 70 | * NOP functions |
59 | .startup = startup_none, | 71 | */ |
60 | .shutdown = shutdown_none, | 72 | static void noop(unsigned int irq) |
61 | .enable = enable_none, | 73 | { |
62 | .disable = disable_none, | 74 | } |
63 | .ack = ack_none, | 75 | |
64 | .end = end_none, | 76 | static unsigned int noop_ret(unsigned int irq) |
65 | .set_affinity = NULL | 77 | { |
78 | return 0; | ||
79 | } | ||
80 | |||
81 | /* | ||
82 | * Generic no controller implementation | ||
83 | */ | ||
84 | struct irq_chip no_irq_chip = { | ||
85 | .name = "none", | ||
86 | .startup = noop_ret, | ||
87 | .shutdown = noop, | ||
88 | .enable = noop, | ||
89 | .disable = noop, | ||
90 | .ack = ack_bad, | ||
91 | .end = noop, | ||
66 | }; | 92 | }; |
67 | 93 | ||
68 | /* | 94 | /* |
@@ -73,11 +99,16 @@ irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs) | |||
73 | return IRQ_NONE; | 99 | return IRQ_NONE; |
74 | } | 100 | } |
75 | 101 | ||
76 | /* | 102 | /** |
77 | * Have got an event to handle: | 103 | * handle_IRQ_event - irq action chain handler |
104 | * @irq: the interrupt number | ||
105 | * @regs: pointer to a register structure | ||
106 | * @action: the interrupt action chain for this irq | ||
107 | * | ||
108 | * Handles the action chain of an irq event | ||
78 | */ | 109 | */ |
79 | fastcall irqreturn_t handle_IRQ_event(unsigned int irq, struct pt_regs *regs, | 110 | irqreturn_t handle_IRQ_event(unsigned int irq, struct pt_regs *regs, |
80 | struct irqaction *action) | 111 | struct irqaction *action) |
81 | { | 112 | { |
82 | irqreturn_t ret, retval = IRQ_NONE; | 113 | irqreturn_t ret, retval = IRQ_NONE; |
83 | unsigned int status = 0; | 114 | unsigned int status = 0; |
@@ -100,15 +131,22 @@ fastcall irqreturn_t handle_IRQ_event(unsigned int irq, struct pt_regs *regs, | |||
100 | return retval; | 131 | return retval; |
101 | } | 132 | } |
102 | 133 | ||
103 | /* | 134 | /** |
104 | * do_IRQ handles all normal device IRQ's (the special | 135 | * __do_IRQ - original all in one highlevel IRQ handler |
136 | * @irq: the interrupt number | ||
137 | * @regs: pointer to a register structure | ||
138 | * | ||
139 | * __do_IRQ handles all normal device IRQ's (the special | ||
105 | * SMP cross-CPU interrupts have their own specific | 140 | * SMP cross-CPU interrupts have their own specific |
106 | * handlers). | 141 | * handlers). |
142 | * | ||
143 | * This is the original x86 implementation which is used for every | ||
144 | * interrupt type. | ||
107 | */ | 145 | */ |
108 | fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs) | 146 | fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs) |
109 | { | 147 | { |
110 | irq_desc_t *desc = irq_desc + irq; | 148 | struct irq_desc *desc = irq_desc + irq; |
111 | struct irqaction * action; | 149 | struct irqaction *action; |
112 | unsigned int status; | 150 | unsigned int status; |
113 | 151 | ||
114 | kstat_this_cpu.irqs[irq]++; | 152 | kstat_this_cpu.irqs[irq]++; |
@@ -118,16 +156,16 @@ fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs) | |||
118 | /* | 156 | /* |
119 | * No locking required for CPU-local interrupts: | 157 | * No locking required for CPU-local interrupts: |
120 | */ | 158 | */ |
121 | if (desc->handler->ack) | 159 | if (desc->chip->ack) |
122 | desc->handler->ack(irq); | 160 | desc->chip->ack(irq); |
123 | action_ret = handle_IRQ_event(irq, regs, desc->action); | 161 | action_ret = handle_IRQ_event(irq, regs, desc->action); |
124 | desc->handler->end(irq); | 162 | desc->chip->end(irq); |
125 | return 1; | 163 | return 1; |
126 | } | 164 | } |
127 | 165 | ||
128 | spin_lock(&desc->lock); | 166 | spin_lock(&desc->lock); |
129 | if (desc->handler->ack) | 167 | if (desc->chip->ack) |
130 | desc->handler->ack(irq); | 168 | desc->chip->ack(irq); |
131 | /* | 169 | /* |
132 | * REPLAY is when Linux resends an IRQ that was dropped earlier | 170 | * REPLAY is when Linux resends an IRQ that was dropped earlier |
133 | * WAITING is used by probe to mark irqs that are being tested | 171 | * WAITING is used by probe to mark irqs that are being tested |
@@ -187,7 +225,7 @@ out: | |||
187 | * The ->end() handler has to deal with interrupts which got | 225 | * The ->end() handler has to deal with interrupts which got |
188 | * disabled while the handler was running. | 226 | * disabled while the handler was running. |
189 | */ | 227 | */ |
190 | desc->handler->end(irq); | 228 | desc->chip->end(irq); |
191 | spin_unlock(&desc->lock); | 229 | spin_unlock(&desc->lock); |
192 | 230 | ||
193 | return 1; | 231 | return 1; |
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h index 46feba630266..08a849a22447 100644 --- a/kernel/irq/internals.h +++ b/kernel/irq/internals.h | |||
@@ -4,6 +4,12 @@ | |||
4 | 4 | ||
5 | extern int noirqdebug; | 5 | extern int noirqdebug; |
6 | 6 | ||
7 | /* Set default functions for irq_chip structures: */ | ||
8 | extern void irq_chip_set_defaults(struct irq_chip *chip); | ||
9 | |||
10 | /* Set default handler: */ | ||
11 | extern void compat_irq_chip_set_default_handler(struct irq_desc *desc); | ||
12 | |||
7 | #ifdef CONFIG_PROC_FS | 13 | #ifdef CONFIG_PROC_FS |
8 | extern void register_irq_proc(unsigned int irq); | 14 | extern void register_irq_proc(unsigned int irq); |
9 | extern void register_handler_proc(unsigned int irq, struct irqaction *action); | 15 | extern void register_handler_proc(unsigned int irq, struct irqaction *action); |
@@ -16,3 +22,43 @@ static inline void unregister_handler_proc(unsigned int irq, | |||
16 | struct irqaction *action) { } | 22 | struct irqaction *action) { } |
17 | #endif | 23 | #endif |
18 | 24 | ||
25 | /* | ||
26 | * Debugging printout: | ||
27 | */ | ||
28 | |||
29 | #include <linux/kallsyms.h> | ||
30 | |||
31 | #define P(f) if (desc->status & f) printk("%14s set\n", #f) | ||
32 | |||
33 | static inline void print_irq_desc(unsigned int irq, struct irq_desc *desc) | ||
34 | { | ||
35 | printk("irq %d, desc: %p, depth: %d, count: %d, unhandled: %d\n", | ||
36 | irq, desc, desc->depth, desc->irq_count, desc->irqs_unhandled); | ||
37 | printk("->handle_irq(): %p, ", desc->handle_irq); | ||
38 | print_symbol("%s\n", (unsigned long)desc->handle_irq); | ||
39 | printk("->chip(): %p, ", desc->chip); | ||
40 | print_symbol("%s\n", (unsigned long)desc->chip); | ||
41 | printk("->action(): %p\n", desc->action); | ||
42 | if (desc->action) { | ||
43 | printk("->action->handler(): %p, ", desc->action->handler); | ||
44 | print_symbol("%s\n", (unsigned long)desc->action->handler); | ||
45 | } | ||
46 | |||
47 | P(IRQ_INPROGRESS); | ||
48 | P(IRQ_DISABLED); | ||
49 | P(IRQ_PENDING); | ||
50 | P(IRQ_REPLAY); | ||
51 | P(IRQ_AUTODETECT); | ||
52 | P(IRQ_WAITING); | ||
53 | P(IRQ_LEVEL); | ||
54 | P(IRQ_MASKED); | ||
55 | #ifdef CONFIG_IRQ_PER_CPU | ||
56 | P(IRQ_PER_CPU); | ||
57 | #endif | ||
58 | P(IRQ_NOPROBE); | ||
59 | P(IRQ_NOREQUEST); | ||
60 | P(IRQ_NOAUTOEN); | ||
61 | } | ||
62 | |||
63 | #undef P | ||
64 | |||
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 1279e3499534..9eb1d518ee1c 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
@@ -1,7 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * linux/kernel/irq/manage.c | 2 | * linux/kernel/irq/manage.c |
3 | * | 3 | * |
4 | * Copyright (C) 1992, 1998-2004 Linus Torvalds, Ingo Molnar | 4 | * Copyright (C) 1992, 1998-2006 Linus Torvalds, Ingo Molnar |
5 | * Copyright (C) 2005-2006 Thomas Gleixner | ||
5 | * | 6 | * |
6 | * This file contains driver APIs to the irq subsystem. | 7 | * This file contains driver APIs to the irq subsystem. |
7 | */ | 8 | */ |
@@ -16,12 +17,6 @@ | |||
16 | 17 | ||
17 | #ifdef CONFIG_SMP | 18 | #ifdef CONFIG_SMP |
18 | 19 | ||
19 | cpumask_t irq_affinity[NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL }; | ||
20 | |||
21 | #if defined (CONFIG_GENERIC_PENDING_IRQ) || defined (CONFIG_IRQBALANCE) | ||
22 | cpumask_t __cacheline_aligned pending_irq_cpumask[NR_IRQS]; | ||
23 | #endif | ||
24 | |||
25 | /** | 20 | /** |
26 | * synchronize_irq - wait for pending IRQ handlers (on other CPUs) | 21 | * synchronize_irq - wait for pending IRQ handlers (on other CPUs) |
27 | * @irq: interrupt number to wait for | 22 | * @irq: interrupt number to wait for |
@@ -42,7 +37,6 @@ void synchronize_irq(unsigned int irq) | |||
42 | while (desc->status & IRQ_INPROGRESS) | 37 | while (desc->status & IRQ_INPROGRESS) |
43 | cpu_relax(); | 38 | cpu_relax(); |
44 | } | 39 | } |
45 | |||
46 | EXPORT_SYMBOL(synchronize_irq); | 40 | EXPORT_SYMBOL(synchronize_irq); |
47 | 41 | ||
48 | #endif | 42 | #endif |
@@ -60,7 +54,7 @@ EXPORT_SYMBOL(synchronize_irq); | |||
60 | */ | 54 | */ |
61 | void disable_irq_nosync(unsigned int irq) | 55 | void disable_irq_nosync(unsigned int irq) |
62 | { | 56 | { |
63 | irq_desc_t *desc = irq_desc + irq; | 57 | struct irq_desc *desc = irq_desc + irq; |
64 | unsigned long flags; | 58 | unsigned long flags; |
65 | 59 | ||
66 | if (irq >= NR_IRQS) | 60 | if (irq >= NR_IRQS) |
@@ -69,11 +63,10 @@ void disable_irq_nosync(unsigned int irq) | |||
69 | spin_lock_irqsave(&desc->lock, flags); | 63 | spin_lock_irqsave(&desc->lock, flags); |
70 | if (!desc->depth++) { | 64 | if (!desc->depth++) { |
71 | desc->status |= IRQ_DISABLED; | 65 | desc->status |= IRQ_DISABLED; |
72 | desc->handler->disable(irq); | 66 | desc->chip->disable(irq); |
73 | } | 67 | } |
74 | spin_unlock_irqrestore(&desc->lock, flags); | 68 | spin_unlock_irqrestore(&desc->lock, flags); |
75 | } | 69 | } |
76 | |||
77 | EXPORT_SYMBOL(disable_irq_nosync); | 70 | EXPORT_SYMBOL(disable_irq_nosync); |
78 | 71 | ||
79 | /** | 72 | /** |
@@ -90,7 +83,7 @@ EXPORT_SYMBOL(disable_irq_nosync); | |||
90 | */ | 83 | */ |
91 | void disable_irq(unsigned int irq) | 84 | void disable_irq(unsigned int irq) |
92 | { | 85 | { |
93 | irq_desc_t *desc = irq_desc + irq; | 86 | struct irq_desc *desc = irq_desc + irq; |
94 | 87 | ||
95 | if (irq >= NR_IRQS) | 88 | if (irq >= NR_IRQS) |
96 | return; | 89 | return; |
@@ -99,7 +92,6 @@ void disable_irq(unsigned int irq) | |||
99 | if (desc->action) | 92 | if (desc->action) |
100 | synchronize_irq(irq); | 93 | synchronize_irq(irq); |
101 | } | 94 | } |
102 | |||
103 | EXPORT_SYMBOL(disable_irq); | 95 | EXPORT_SYMBOL(disable_irq); |
104 | 96 | ||
105 | /** | 97 | /** |
@@ -114,7 +106,7 @@ EXPORT_SYMBOL(disable_irq); | |||
114 | */ | 106 | */ |
115 | void enable_irq(unsigned int irq) | 107 | void enable_irq(unsigned int irq) |
116 | { | 108 | { |
117 | irq_desc_t *desc = irq_desc + irq; | 109 | struct irq_desc *desc = irq_desc + irq; |
118 | unsigned long flags; | 110 | unsigned long flags; |
119 | 111 | ||
120 | if (irq >= NR_IRQS) | 112 | if (irq >= NR_IRQS) |
@@ -123,17 +115,15 @@ void enable_irq(unsigned int irq) | |||
123 | spin_lock_irqsave(&desc->lock, flags); | 115 | spin_lock_irqsave(&desc->lock, flags); |
124 | switch (desc->depth) { | 116 | switch (desc->depth) { |
125 | case 0: | 117 | case 0: |
118 | printk(KERN_WARNING "Unablanced enable_irq(%d)\n", irq); | ||
126 | WARN_ON(1); | 119 | WARN_ON(1); |
127 | break; | 120 | break; |
128 | case 1: { | 121 | case 1: { |
129 | unsigned int status = desc->status & ~IRQ_DISABLED; | 122 | unsigned int status = desc->status & ~IRQ_DISABLED; |
130 | 123 | ||
131 | desc->status = status; | 124 | /* Prevent probing on this irq: */ |
132 | if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) { | 125 | desc->status = status | IRQ_NOPROBE; |
133 | desc->status = status | IRQ_REPLAY; | 126 | check_irq_resend(desc, irq); |
134 | hw_resend_irq(desc->handler,irq); | ||
135 | } | ||
136 | desc->handler->enable(irq); | ||
137 | /* fall-through */ | 127 | /* fall-through */ |
138 | } | 128 | } |
139 | default: | 129 | default: |
@@ -141,9 +131,29 @@ void enable_irq(unsigned int irq) | |||
141 | } | 131 | } |
142 | spin_unlock_irqrestore(&desc->lock, flags); | 132 | spin_unlock_irqrestore(&desc->lock, flags); |
143 | } | 133 | } |
144 | |||
145 | EXPORT_SYMBOL(enable_irq); | 134 | EXPORT_SYMBOL(enable_irq); |
146 | 135 | ||
136 | /** | ||
137 | * set_irq_wake - control irq power management wakeup | ||
138 | * @irq: interrupt to control | ||
139 | * @on: enable/disable power management wakeup | ||
140 | * | ||
141 | * Enable/disable power management wakeup mode | ||
142 | */ | ||
143 | int set_irq_wake(unsigned int irq, unsigned int on) | ||
144 | { | ||
145 | struct irq_desc *desc = irq_desc + irq; | ||
146 | unsigned long flags; | ||
147 | int ret = -ENXIO; | ||
148 | |||
149 | spin_lock_irqsave(&desc->lock, flags); | ||
150 | if (desc->chip->set_wake) | ||
151 | ret = desc->chip->set_wake(irq, on); | ||
152 | spin_unlock_irqrestore(&desc->lock, flags); | ||
153 | return ret; | ||
154 | } | ||
155 | EXPORT_SYMBOL(set_irq_wake); | ||
156 | |||
147 | /* | 157 | /* |
148 | * Internal function that tells the architecture code whether a | 158 | * Internal function that tells the architecture code whether a |
149 | * particular irq has been exclusively allocated or is available | 159 | * particular irq has been exclusively allocated or is available |
@@ -153,7 +163,7 @@ int can_request_irq(unsigned int irq, unsigned long irqflags) | |||
153 | { | 163 | { |
154 | struct irqaction *action; | 164 | struct irqaction *action; |
155 | 165 | ||
156 | if (irq >= NR_IRQS) | 166 | if (irq >= NR_IRQS || irq_desc[irq].status & IRQ_NOREQUEST) |
157 | return 0; | 167 | return 0; |
158 | 168 | ||
159 | action = irq_desc[irq].action; | 169 | action = irq_desc[irq].action; |
@@ -164,11 +174,22 @@ int can_request_irq(unsigned int irq, unsigned long irqflags) | |||
164 | return !action; | 174 | return !action; |
165 | } | 175 | } |
166 | 176 | ||
177 | void compat_irq_chip_set_default_handler(struct irq_desc *desc) | ||
178 | { | ||
179 | /* | ||
180 | * If the architecture still has not overriden | ||
181 | * the flow handler then zap the default. This | ||
182 | * should catch incorrect flow-type setting. | ||
183 | */ | ||
184 | if (desc->handle_irq == &handle_bad_irq) | ||
185 | desc->handle_irq = NULL; | ||
186 | } | ||
187 | |||
167 | /* | 188 | /* |
168 | * Internal function to register an irqaction - typically used to | 189 | * Internal function to register an irqaction - typically used to |
169 | * allocate special interrupts that are part of the architecture. | 190 | * allocate special interrupts that are part of the architecture. |
170 | */ | 191 | */ |
171 | int setup_irq(unsigned int irq, struct irqaction * new) | 192 | int setup_irq(unsigned int irq, struct irqaction *new) |
172 | { | 193 | { |
173 | struct irq_desc *desc = irq_desc + irq; | 194 | struct irq_desc *desc = irq_desc + irq; |
174 | struct irqaction *old, **p; | 195 | struct irqaction *old, **p; |
@@ -178,7 +199,7 @@ int setup_irq(unsigned int irq, struct irqaction * new) | |||
178 | if (irq >= NR_IRQS) | 199 | if (irq >= NR_IRQS) |
179 | return -EINVAL; | 200 | return -EINVAL; |
180 | 201 | ||
181 | if (desc->handler == &no_irq_type) | 202 | if (desc->chip == &no_irq_chip) |
182 | return -ENOSYS; | 203 | return -ENOSYS; |
183 | /* | 204 | /* |
184 | * Some drivers like serial.c use request_irq() heavily, | 205 | * Some drivers like serial.c use request_irq() heavily, |
@@ -200,14 +221,21 @@ int setup_irq(unsigned int irq, struct irqaction * new) | |||
200 | /* | 221 | /* |
201 | * The following block of code has to be executed atomically | 222 | * The following block of code has to be executed atomically |
202 | */ | 223 | */ |
203 | spin_lock_irqsave(&desc->lock,flags); | 224 | spin_lock_irqsave(&desc->lock, flags); |
204 | p = &desc->action; | 225 | p = &desc->action; |
205 | if ((old = *p) != NULL) { | 226 | old = *p; |
206 | /* Can't share interrupts unless both agree to */ | 227 | if (old) { |
207 | if (!(old->flags & new->flags & SA_SHIRQ)) | 228 | /* |
229 | * Can't share interrupts unless both agree to and are | ||
230 | * the same type (level, edge, polarity). So both flag | ||
231 | * fields must have SA_SHIRQ set and the bits which | ||
232 | * set the trigger type must match. | ||
233 | */ | ||
234 | if (!((old->flags & new->flags) & SA_SHIRQ) || | ||
235 | ((old->flags ^ new->flags) & SA_TRIGGER_MASK)) | ||
208 | goto mismatch; | 236 | goto mismatch; |
209 | 237 | ||
210 | #if defined(ARCH_HAS_IRQ_PER_CPU) && defined(SA_PERCPU_IRQ) | 238 | #if defined(CONFIG_IRQ_PER_CPU) && defined(SA_PERCPU_IRQ) |
211 | /* All handlers must agree on per-cpuness */ | 239 | /* All handlers must agree on per-cpuness */ |
212 | if ((old->flags & IRQ_PER_CPU) != (new->flags & IRQ_PER_CPU)) | 240 | if ((old->flags & IRQ_PER_CPU) != (new->flags & IRQ_PER_CPU)) |
213 | goto mismatch; | 241 | goto mismatch; |
@@ -222,20 +250,44 @@ int setup_irq(unsigned int irq, struct irqaction * new) | |||
222 | } | 250 | } |
223 | 251 | ||
224 | *p = new; | 252 | *p = new; |
225 | #if defined(ARCH_HAS_IRQ_PER_CPU) && defined(SA_PERCPU_IRQ) | 253 | #if defined(CONFIG_IRQ_PER_CPU) && defined(SA_PERCPU_IRQ) |
226 | if (new->flags & SA_PERCPU_IRQ) | 254 | if (new->flags & SA_PERCPU_IRQ) |
227 | desc->status |= IRQ_PER_CPU; | 255 | desc->status |= IRQ_PER_CPU; |
228 | #endif | 256 | #endif |
229 | if (!shared) { | 257 | if (!shared) { |
230 | desc->depth = 0; | 258 | irq_chip_set_defaults(desc->chip); |
231 | desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | | 259 | |
232 | IRQ_WAITING | IRQ_INPROGRESS); | 260 | /* Setup the type (level, edge polarity) if configured: */ |
233 | if (desc->handler->startup) | 261 | if (new->flags & SA_TRIGGER_MASK) { |
234 | desc->handler->startup(irq); | 262 | if (desc->chip && desc->chip->set_type) |
235 | else | 263 | desc->chip->set_type(irq, |
236 | desc->handler->enable(irq); | 264 | new->flags & SA_TRIGGER_MASK); |
265 | else | ||
266 | /* | ||
267 | * SA_TRIGGER_* but the PIC does not support | ||
268 | * multiple flow-types? | ||
269 | */ | ||
270 | printk(KERN_WARNING "setup_irq(%d) SA_TRIGGER" | ||
271 | "set. No set_type function available\n", | ||
272 | irq); | ||
273 | } else | ||
274 | compat_irq_chip_set_default_handler(desc); | ||
275 | |||
276 | desc->status &= ~(IRQ_AUTODETECT | IRQ_WAITING | | ||
277 | IRQ_INPROGRESS); | ||
278 | |||
279 | if (!(desc->status & IRQ_NOAUTOEN)) { | ||
280 | desc->depth = 0; | ||
281 | desc->status &= ~IRQ_DISABLED; | ||
282 | if (desc->chip->startup) | ||
283 | desc->chip->startup(irq); | ||
284 | else | ||
285 | desc->chip->enable(irq); | ||
286 | } else | ||
287 | /* Undo nested disables: */ | ||
288 | desc->depth = 1; | ||
237 | } | 289 | } |
238 | spin_unlock_irqrestore(&desc->lock,flags); | 290 | spin_unlock_irqrestore(&desc->lock, flags); |
239 | 291 | ||
240 | new->irq = irq; | 292 | new->irq = irq; |
241 | register_irq_proc(irq); | 293 | register_irq_proc(irq); |
@@ -278,10 +330,10 @@ void free_irq(unsigned int irq, void *dev_id) | |||
278 | return; | 330 | return; |
279 | 331 | ||
280 | desc = irq_desc + irq; | 332 | desc = irq_desc + irq; |
281 | spin_lock_irqsave(&desc->lock,flags); | 333 | spin_lock_irqsave(&desc->lock, flags); |
282 | p = &desc->action; | 334 | p = &desc->action; |
283 | for (;;) { | 335 | for (;;) { |
284 | struct irqaction * action = *p; | 336 | struct irqaction *action = *p; |
285 | 337 | ||
286 | if (action) { | 338 | if (action) { |
287 | struct irqaction **pp = p; | 339 | struct irqaction **pp = p; |
@@ -295,18 +347,18 @@ void free_irq(unsigned int irq, void *dev_id) | |||
295 | 347 | ||
296 | /* Currently used only by UML, might disappear one day.*/ | 348 | /* Currently used only by UML, might disappear one day.*/ |
297 | #ifdef CONFIG_IRQ_RELEASE_METHOD | 349 | #ifdef CONFIG_IRQ_RELEASE_METHOD |
298 | if (desc->handler->release) | 350 | if (desc->chip->release) |
299 | desc->handler->release(irq, dev_id); | 351 | desc->chip->release(irq, dev_id); |
300 | #endif | 352 | #endif |
301 | 353 | ||
302 | if (!desc->action) { | 354 | if (!desc->action) { |
303 | desc->status |= IRQ_DISABLED; | 355 | desc->status |= IRQ_DISABLED; |
304 | if (desc->handler->shutdown) | 356 | if (desc->chip->shutdown) |
305 | desc->handler->shutdown(irq); | 357 | desc->chip->shutdown(irq); |
306 | else | 358 | else |
307 | desc->handler->disable(irq); | 359 | desc->chip->disable(irq); |
308 | } | 360 | } |
309 | spin_unlock_irqrestore(&desc->lock,flags); | 361 | spin_unlock_irqrestore(&desc->lock, flags); |
310 | unregister_handler_proc(irq, action); | 362 | unregister_handler_proc(irq, action); |
311 | 363 | ||
312 | /* Make sure it's not being used on another CPU */ | 364 | /* Make sure it's not being used on another CPU */ |
@@ -314,12 +366,11 @@ void free_irq(unsigned int irq, void *dev_id) | |||
314 | kfree(action); | 366 | kfree(action); |
315 | return; | 367 | return; |
316 | } | 368 | } |
317 | printk(KERN_ERR "Trying to free free IRQ%d\n",irq); | 369 | printk(KERN_ERR "Trying to free free IRQ%d\n", irq); |
318 | spin_unlock_irqrestore(&desc->lock,flags); | 370 | spin_unlock_irqrestore(&desc->lock, flags); |
319 | return; | 371 | return; |
320 | } | 372 | } |
321 | } | 373 | } |
322 | |||
323 | EXPORT_SYMBOL(free_irq); | 374 | EXPORT_SYMBOL(free_irq); |
324 | 375 | ||
325 | /** | 376 | /** |
@@ -353,9 +404,9 @@ EXPORT_SYMBOL(free_irq); | |||
353 | */ | 404 | */ |
354 | int request_irq(unsigned int irq, | 405 | int request_irq(unsigned int irq, |
355 | irqreturn_t (*handler)(int, void *, struct pt_regs *), | 406 | irqreturn_t (*handler)(int, void *, struct pt_regs *), |
356 | unsigned long irqflags, const char * devname, void *dev_id) | 407 | unsigned long irqflags, const char *devname, void *dev_id) |
357 | { | 408 | { |
358 | struct irqaction * action; | 409 | struct irqaction *action; |
359 | int retval; | 410 | int retval; |
360 | 411 | ||
361 | /* | 412 | /* |
@@ -368,6 +419,8 @@ int request_irq(unsigned int irq, | |||
368 | return -EINVAL; | 419 | return -EINVAL; |
369 | if (irq >= NR_IRQS) | 420 | if (irq >= NR_IRQS) |
370 | return -EINVAL; | 421 | return -EINVAL; |
422 | if (irq_desc[irq].status & IRQ_NOREQUEST) | ||
423 | return -EINVAL; | ||
371 | if (!handler) | 424 | if (!handler) |
372 | return -EINVAL; | 425 | return -EINVAL; |
373 | 426 | ||
@@ -390,6 +443,5 @@ int request_irq(unsigned int irq, | |||
390 | 443 | ||
391 | return retval; | 444 | return retval; |
392 | } | 445 | } |
393 | |||
394 | EXPORT_SYMBOL(request_irq); | 446 | EXPORT_SYMBOL(request_irq); |
395 | 447 | ||
diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c index a12d00eb5e7c..a57ebe9fa6f6 100644 --- a/kernel/irq/migration.c +++ b/kernel/irq/migration.c | |||
@@ -3,19 +3,19 @@ | |||
3 | 3 | ||
4 | void set_pending_irq(unsigned int irq, cpumask_t mask) | 4 | void set_pending_irq(unsigned int irq, cpumask_t mask) |
5 | { | 5 | { |
6 | irq_desc_t *desc = irq_desc + irq; | 6 | struct irq_desc *desc = irq_desc + irq; |
7 | unsigned long flags; | 7 | unsigned long flags; |
8 | 8 | ||
9 | spin_lock_irqsave(&desc->lock, flags); | 9 | spin_lock_irqsave(&desc->lock, flags); |
10 | desc->move_irq = 1; | 10 | desc->move_irq = 1; |
11 | pending_irq_cpumask[irq] = mask; | 11 | irq_desc[irq].pending_mask = mask; |
12 | spin_unlock_irqrestore(&desc->lock, flags); | 12 | spin_unlock_irqrestore(&desc->lock, flags); |
13 | } | 13 | } |
14 | 14 | ||
15 | void move_native_irq(int irq) | 15 | void move_native_irq(int irq) |
16 | { | 16 | { |
17 | struct irq_desc *desc = irq_desc + irq; | ||
17 | cpumask_t tmp; | 18 | cpumask_t tmp; |
18 | irq_desc_t *desc = irq_descp(irq); | ||
19 | 19 | ||
20 | if (likely(!desc->move_irq)) | 20 | if (likely(!desc->move_irq)) |
21 | return; | 21 | return; |
@@ -30,15 +30,15 @@ void move_native_irq(int irq) | |||
30 | 30 | ||
31 | desc->move_irq = 0; | 31 | desc->move_irq = 0; |
32 | 32 | ||
33 | if (unlikely(cpus_empty(pending_irq_cpumask[irq]))) | 33 | if (unlikely(cpus_empty(irq_desc[irq].pending_mask))) |
34 | return; | 34 | return; |
35 | 35 | ||
36 | if (!desc->handler->set_affinity) | 36 | if (!desc->chip->set_affinity) |
37 | return; | 37 | return; |
38 | 38 | ||
39 | assert_spin_locked(&desc->lock); | 39 | assert_spin_locked(&desc->lock); |
40 | 40 | ||
41 | cpus_and(tmp, pending_irq_cpumask[irq], cpu_online_map); | 41 | cpus_and(tmp, irq_desc[irq].pending_mask, cpu_online_map); |
42 | 42 | ||
43 | /* | 43 | /* |
44 | * If there was a valid mask to work with, please | 44 | * If there was a valid mask to work with, please |
@@ -51,12 +51,12 @@ void move_native_irq(int irq) | |||
51 | */ | 51 | */ |
52 | if (likely(!cpus_empty(tmp))) { | 52 | if (likely(!cpus_empty(tmp))) { |
53 | if (likely(!(desc->status & IRQ_DISABLED))) | 53 | if (likely(!(desc->status & IRQ_DISABLED))) |
54 | desc->handler->disable(irq); | 54 | desc->chip->disable(irq); |
55 | 55 | ||
56 | desc->handler->set_affinity(irq,tmp); | 56 | desc->chip->set_affinity(irq,tmp); |
57 | 57 | ||
58 | if (likely(!(desc->status & IRQ_DISABLED))) | 58 | if (likely(!(desc->status & IRQ_DISABLED))) |
59 | desc->handler->enable(irq); | 59 | desc->chip->enable(irq); |
60 | } | 60 | } |
61 | cpus_clear(pending_irq_cpumask[irq]); | 61 | cpus_clear(irq_desc[irq].pending_mask); |
62 | } | 62 | } |
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c index afacd6f585fa..607c7809ad01 100644 --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c | |||
@@ -12,15 +12,10 @@ | |||
12 | 12 | ||
13 | #include "internals.h" | 13 | #include "internals.h" |
14 | 14 | ||
15 | static struct proc_dir_entry *root_irq_dir, *irq_dir[NR_IRQS]; | 15 | static struct proc_dir_entry *root_irq_dir; |
16 | 16 | ||
17 | #ifdef CONFIG_SMP | 17 | #ifdef CONFIG_SMP |
18 | 18 | ||
19 | /* | ||
20 | * The /proc/irq/<irq>/smp_affinity values: | ||
21 | */ | ||
22 | static struct proc_dir_entry *smp_affinity_entry[NR_IRQS]; | ||
23 | |||
24 | #ifdef CONFIG_GENERIC_PENDING_IRQ | 19 | #ifdef CONFIG_GENERIC_PENDING_IRQ |
25 | void proc_set_irq_affinity(unsigned int irq, cpumask_t mask_val) | 20 | void proc_set_irq_affinity(unsigned int irq, cpumask_t mask_val) |
26 | { | 21 | { |
@@ -36,15 +31,15 @@ void proc_set_irq_affinity(unsigned int irq, cpumask_t mask_val) | |||
36 | void proc_set_irq_affinity(unsigned int irq, cpumask_t mask_val) | 31 | void proc_set_irq_affinity(unsigned int irq, cpumask_t mask_val) |
37 | { | 32 | { |
38 | set_balance_irq_affinity(irq, mask_val); | 33 | set_balance_irq_affinity(irq, mask_val); |
39 | irq_affinity[irq] = mask_val; | 34 | irq_desc[irq].affinity = mask_val; |
40 | irq_desc[irq].handler->set_affinity(irq, mask_val); | 35 | irq_desc[irq].chip->set_affinity(irq, mask_val); |
41 | } | 36 | } |
42 | #endif | 37 | #endif |
43 | 38 | ||
44 | static int irq_affinity_read_proc(char *page, char **start, off_t off, | 39 | static int irq_affinity_read_proc(char *page, char **start, off_t off, |
45 | int count, int *eof, void *data) | 40 | int count, int *eof, void *data) |
46 | { | 41 | { |
47 | int len = cpumask_scnprintf(page, count, irq_affinity[(long)data]); | 42 | int len = cpumask_scnprintf(page, count, irq_desc[(long)data].affinity); |
48 | 43 | ||
49 | if (count - len < 2) | 44 | if (count - len < 2) |
50 | return -EINVAL; | 45 | return -EINVAL; |
@@ -59,7 +54,7 @@ static int irq_affinity_write_proc(struct file *file, const char __user *buffer, | |||
59 | unsigned int irq = (int)(long)data, full_count = count, err; | 54 | unsigned int irq = (int)(long)data, full_count = count, err; |
60 | cpumask_t new_value, tmp; | 55 | cpumask_t new_value, tmp; |
61 | 56 | ||
62 | if (!irq_desc[irq].handler->set_affinity || no_irq_affinity) | 57 | if (!irq_desc[irq].chip->set_affinity || no_irq_affinity) |
63 | return -EIO; | 58 | return -EIO; |
64 | 59 | ||
65 | err = cpumask_parse(buffer, count, new_value); | 60 | err = cpumask_parse(buffer, count, new_value); |
@@ -102,7 +97,7 @@ void register_handler_proc(unsigned int irq, struct irqaction *action) | |||
102 | { | 97 | { |
103 | char name [MAX_NAMELEN]; | 98 | char name [MAX_NAMELEN]; |
104 | 99 | ||
105 | if (!irq_dir[irq] || action->dir || !action->name || | 100 | if (!irq_desc[irq].dir || action->dir || !action->name || |
106 | !name_unique(irq, action)) | 101 | !name_unique(irq, action)) |
107 | return; | 102 | return; |
108 | 103 | ||
@@ -110,7 +105,7 @@ void register_handler_proc(unsigned int irq, struct irqaction *action) | |||
110 | snprintf(name, MAX_NAMELEN, "%s", action->name); | 105 | snprintf(name, MAX_NAMELEN, "%s", action->name); |
111 | 106 | ||
112 | /* create /proc/irq/1234/handler/ */ | 107 | /* create /proc/irq/1234/handler/ */ |
113 | action->dir = proc_mkdir(name, irq_dir[irq]); | 108 | action->dir = proc_mkdir(name, irq_desc[irq].dir); |
114 | } | 109 | } |
115 | 110 | ||
116 | #undef MAX_NAMELEN | 111 | #undef MAX_NAMELEN |
@@ -122,22 +117,22 @@ void register_irq_proc(unsigned int irq) | |||
122 | char name [MAX_NAMELEN]; | 117 | char name [MAX_NAMELEN]; |
123 | 118 | ||
124 | if (!root_irq_dir || | 119 | if (!root_irq_dir || |
125 | (irq_desc[irq].handler == &no_irq_type) || | 120 | (irq_desc[irq].chip == &no_irq_chip) || |
126 | irq_dir[irq]) | 121 | irq_desc[irq].dir) |
127 | return; | 122 | return; |
128 | 123 | ||
129 | memset(name, 0, MAX_NAMELEN); | 124 | memset(name, 0, MAX_NAMELEN); |
130 | sprintf(name, "%d", irq); | 125 | sprintf(name, "%d", irq); |
131 | 126 | ||
132 | /* create /proc/irq/1234 */ | 127 | /* create /proc/irq/1234 */ |
133 | irq_dir[irq] = proc_mkdir(name, root_irq_dir); | 128 | irq_desc[irq].dir = proc_mkdir(name, root_irq_dir); |
134 | 129 | ||
135 | #ifdef CONFIG_SMP | 130 | #ifdef CONFIG_SMP |
136 | { | 131 | { |
137 | struct proc_dir_entry *entry; | 132 | struct proc_dir_entry *entry; |
138 | 133 | ||
139 | /* create /proc/irq/<irq>/smp_affinity */ | 134 | /* create /proc/irq/<irq>/smp_affinity */ |
140 | entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]); | 135 | entry = create_proc_entry("smp_affinity", 0600, irq_desc[irq].dir); |
141 | 136 | ||
142 | if (entry) { | 137 | if (entry) { |
143 | entry->nlink = 1; | 138 | entry->nlink = 1; |
@@ -145,7 +140,6 @@ void register_irq_proc(unsigned int irq) | |||
145 | entry->read_proc = irq_affinity_read_proc; | 140 | entry->read_proc = irq_affinity_read_proc; |
146 | entry->write_proc = irq_affinity_write_proc; | 141 | entry->write_proc = irq_affinity_write_proc; |
147 | } | 142 | } |
148 | smp_affinity_entry[irq] = entry; | ||
149 | } | 143 | } |
150 | #endif | 144 | #endif |
151 | } | 145 | } |
@@ -155,7 +149,7 @@ void register_irq_proc(unsigned int irq) | |||
155 | void unregister_handler_proc(unsigned int irq, struct irqaction *action) | 149 | void unregister_handler_proc(unsigned int irq, struct irqaction *action) |
156 | { | 150 | { |
157 | if (action->dir) | 151 | if (action->dir) |
158 | remove_proc_entry(action->dir->name, irq_dir[irq]); | 152 | remove_proc_entry(action->dir->name, irq_desc[irq].dir); |
159 | } | 153 | } |
160 | 154 | ||
161 | void init_irq_proc(void) | 155 | void init_irq_proc(void) |
diff --git a/kernel/irq/resend.c b/kernel/irq/resend.c new file mode 100644 index 000000000000..872f91ba2ce8 --- /dev/null +++ b/kernel/irq/resend.c | |||
@@ -0,0 +1,78 @@ | |||
1 | /* | ||
2 | * linux/kernel/irq/resend.c | ||
3 | * | ||
4 | * Copyright (C) 1992, 1998-2006 Linus Torvalds, Ingo Molnar | ||
5 | * Copyright (C) 2005-2006, Thomas Gleixner | ||
6 | * | ||
7 | * This file contains the IRQ-resend code | ||
8 | * | ||
9 | * If the interrupt is waiting to be processed, we try to re-run it. | ||
10 | * We can't directly run it from here since the caller might be in an | ||
11 | * interrupt-protected region. Not all irq controller chips can | ||
12 | * retrigger interrupts at the hardware level, so in those cases | ||
13 | * we allow the resending of IRQs via a tasklet. | ||
14 | */ | ||
15 | |||
16 | #include <linux/irq.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/random.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | |||
21 | #include "internals.h" | ||
22 | |||
23 | #ifdef CONFIG_HARDIRQS_SW_RESEND | ||
24 | |||
25 | /* Bitmap to handle software resend of interrupts: */ | ||
26 | static DECLARE_BITMAP(irqs_resend, NR_IRQS); | ||
27 | |||
28 | /* | ||
29 | * Run software resends of IRQ's | ||
30 | */ | ||
31 | static void resend_irqs(unsigned long arg) | ||
32 | { | ||
33 | struct irq_desc *desc; | ||
34 | int irq; | ||
35 | |||
36 | while (!bitmap_empty(irqs_resend, NR_IRQS)) { | ||
37 | irq = find_first_bit(irqs_resend, NR_IRQS); | ||
38 | clear_bit(irq, irqs_resend); | ||
39 | desc = irq_desc + irq; | ||
40 | local_irq_disable(); | ||
41 | desc->handle_irq(irq, desc, NULL); | ||
42 | local_irq_enable(); | ||
43 | } | ||
44 | } | ||
45 | |||
46 | /* Tasklet to handle resend: */ | ||
47 | static DECLARE_TASKLET(resend_tasklet, resend_irqs, 0); | ||
48 | |||
49 | #endif | ||
50 | |||
51 | /* | ||
52 | * IRQ resend | ||
53 | * | ||
54 | * Is called with interrupts disabled and desc->lock held. | ||
55 | */ | ||
56 | void check_irq_resend(struct irq_desc *desc, unsigned int irq) | ||
57 | { | ||
58 | unsigned int status = desc->status; | ||
59 | |||
60 | /* | ||
61 | * Make sure the interrupt is enabled, before resending it: | ||
62 | */ | ||
63 | desc->chip->enable(irq); | ||
64 | |||
65 | if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) { | ||
66 | desc->status &= ~IRQ_PENDING; | ||
67 | desc->status = status | IRQ_REPLAY; | ||
68 | |||
69 | if (!desc->chip || !desc->chip->retrigger || | ||
70 | !desc->chip->retrigger(irq)) { | ||
71 | #ifdef CONFIG_HARDIRQS_SW_RESEND | ||
72 | /* Set it pending and activate the softirq: */ | ||
73 | set_bit(irq, irqs_resend); | ||
74 | tasklet_schedule(&resend_tasklet); | ||
75 | #endif | ||
76 | } | ||
77 | } | ||
78 | } | ||
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c index b2fb3c18d06b..b483deed311c 100644 --- a/kernel/irq/spurious.c +++ b/kernel/irq/spurious.c | |||
@@ -16,22 +16,20 @@ static int irqfixup __read_mostly; | |||
16 | /* | 16 | /* |
17 | * Recovery handler for misrouted interrupts. | 17 | * Recovery handler for misrouted interrupts. |
18 | */ | 18 | */ |
19 | |||
20 | static int misrouted_irq(int irq, struct pt_regs *regs) | 19 | static int misrouted_irq(int irq, struct pt_regs *regs) |
21 | { | 20 | { |
22 | int i; | 21 | int i; |
23 | irq_desc_t *desc; | ||
24 | int ok = 0; | 22 | int ok = 0; |
25 | int work = 0; /* Did we do work for a real IRQ */ | 23 | int work = 0; /* Did we do work for a real IRQ */ |
26 | 24 | ||
27 | for(i = 1; i < NR_IRQS; i++) { | 25 | for (i = 1; i < NR_IRQS; i++) { |
26 | struct irq_desc *desc = irq_desc + i; | ||
28 | struct irqaction *action; | 27 | struct irqaction *action; |
29 | 28 | ||
30 | if (i == irq) /* Already tried */ | 29 | if (i == irq) /* Already tried */ |
31 | continue; | 30 | continue; |
32 | desc = &irq_desc[i]; | 31 | |
33 | spin_lock(&desc->lock); | 32 | spin_lock(&desc->lock); |
34 | action = desc->action; | ||
35 | /* Already running on another processor */ | 33 | /* Already running on another processor */ |
36 | if (desc->status & IRQ_INPROGRESS) { | 34 | if (desc->status & IRQ_INPROGRESS) { |
37 | /* | 35 | /* |
@@ -45,7 +43,9 @@ static int misrouted_irq(int irq, struct pt_regs *regs) | |||
45 | } | 43 | } |
46 | /* Honour the normal IRQ locking */ | 44 | /* Honour the normal IRQ locking */ |
47 | desc->status |= IRQ_INPROGRESS; | 45 | desc->status |= IRQ_INPROGRESS; |
46 | action = desc->action; | ||
48 | spin_unlock(&desc->lock); | 47 | spin_unlock(&desc->lock); |
48 | |||
49 | while (action) { | 49 | while (action) { |
50 | /* Only shared IRQ handlers are safe to call */ | 50 | /* Only shared IRQ handlers are safe to call */ |
51 | if (action->flags & SA_SHIRQ) { | 51 | if (action->flags & SA_SHIRQ) { |
@@ -62,9 +62,8 @@ static int misrouted_irq(int irq, struct pt_regs *regs) | |||
62 | 62 | ||
63 | /* | 63 | /* |
64 | * While we were looking for a fixup someone queued a real | 64 | * While we were looking for a fixup someone queued a real |
65 | * IRQ clashing with our walk | 65 | * IRQ clashing with our walk: |
66 | */ | 66 | */ |
67 | |||
68 | while ((desc->status & IRQ_PENDING) && action) { | 67 | while ((desc->status & IRQ_PENDING) && action) { |
69 | /* | 68 | /* |
70 | * Perform real IRQ processing for the IRQ we deferred | 69 | * Perform real IRQ processing for the IRQ we deferred |
@@ -80,8 +79,8 @@ static int misrouted_irq(int irq, struct pt_regs *regs) | |||
80 | * If we did actual work for the real IRQ line we must let the | 79 | * If we did actual work for the real IRQ line we must let the |
81 | * IRQ controller clean up too | 80 | * IRQ controller clean up too |
82 | */ | 81 | */ |
83 | if(work) | 82 | if (work && desc->chip && desc->chip->end) |
84 | desc->handler->end(i); | 83 | desc->chip->end(i); |
85 | spin_unlock(&desc->lock); | 84 | spin_unlock(&desc->lock); |
86 | } | 85 | } |
87 | /* So the caller can adjust the irq error counts */ | 86 | /* So the caller can adjust the irq error counts */ |
@@ -100,7 +99,8 @@ static int misrouted_irq(int irq, struct pt_regs *regs) | |||
100 | */ | 99 | */ |
101 | 100 | ||
102 | static void | 101 | static void |
103 | __report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret) | 102 | __report_bad_irq(unsigned int irq, struct irq_desc *desc, |
103 | irqreturn_t action_ret) | ||
104 | { | 104 | { |
105 | struct irqaction *action; | 105 | struct irqaction *action; |
106 | 106 | ||
@@ -113,6 +113,7 @@ __report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret) | |||
113 | } | 113 | } |
114 | dump_stack(); | 114 | dump_stack(); |
115 | printk(KERN_ERR "handlers:\n"); | 115 | printk(KERN_ERR "handlers:\n"); |
116 | |||
116 | action = desc->action; | 117 | action = desc->action; |
117 | while (action) { | 118 | while (action) { |
118 | printk(KERN_ERR "[<%p>]", action->handler); | 119 | printk(KERN_ERR "[<%p>]", action->handler); |
@@ -123,7 +124,8 @@ __report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret) | |||
123 | } | 124 | } |
124 | } | 125 | } |
125 | 126 | ||
126 | static void report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret) | 127 | static void |
128 | report_bad_irq(unsigned int irq, struct irq_desc *desc, irqreturn_t action_ret) | ||
127 | { | 129 | { |
128 | static int count = 100; | 130 | static int count = 100; |
129 | 131 | ||
@@ -133,8 +135,8 @@ static void report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t actio | |||
133 | } | 135 | } |
134 | } | 136 | } |
135 | 137 | ||
136 | void note_interrupt(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret, | 138 | void note_interrupt(unsigned int irq, struct irq_desc *desc, |
137 | struct pt_regs *regs) | 139 | irqreturn_t action_ret, struct pt_regs *regs) |
138 | { | 140 | { |
139 | if (unlikely(action_ret != IRQ_HANDLED)) { | 141 | if (unlikely(action_ret != IRQ_HANDLED)) { |
140 | desc->irqs_unhandled++; | 142 | desc->irqs_unhandled++; |
@@ -166,7 +168,8 @@ void note_interrupt(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret, | |||
166 | */ | 168 | */ |
167 | printk(KERN_EMERG "Disabling IRQ #%d\n", irq); | 169 | printk(KERN_EMERG "Disabling IRQ #%d\n", irq); |
168 | desc->status |= IRQ_DISABLED; | 170 | desc->status |= IRQ_DISABLED; |
169 | desc->handler->disable(irq); | 171 | desc->depth = 1; |
172 | desc->chip->disable(irq); | ||
170 | } | 173 | } |
171 | desc->irqs_unhandled = 0; | 174 | desc->irqs_unhandled = 0; |
172 | } | 175 | } |
@@ -177,6 +180,7 @@ int __init noirqdebug_setup(char *str) | |||
177 | { | 180 | { |
178 | noirqdebug = 1; | 181 | noirqdebug = 1; |
179 | printk(KERN_INFO "IRQ lockup detection disabled\n"); | 182 | printk(KERN_INFO "IRQ lockup detection disabled\n"); |
183 | |||
180 | return 1; | 184 | return 1; |
181 | } | 185 | } |
182 | 186 | ||
@@ -187,6 +191,7 @@ static int __init irqfixup_setup(char *str) | |||
187 | irqfixup = 1; | 191 | irqfixup = 1; |
188 | printk(KERN_WARNING "Misrouted IRQ fixup support enabled.\n"); | 192 | printk(KERN_WARNING "Misrouted IRQ fixup support enabled.\n"); |
189 | printk(KERN_WARNING "This may impact system performance.\n"); | 193 | printk(KERN_WARNING "This may impact system performance.\n"); |
194 | |||
190 | return 1; | 195 | return 1; |
191 | } | 196 | } |
192 | 197 | ||
diff --git a/kernel/kexec.c b/kernel/kexec.c index 58f0f382597c..50087ecf337e 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c | |||
@@ -1042,7 +1042,6 @@ asmlinkage long compat_sys_kexec_load(unsigned long entry, | |||
1042 | 1042 | ||
1043 | void crash_kexec(struct pt_regs *regs) | 1043 | void crash_kexec(struct pt_regs *regs) |
1044 | { | 1044 | { |
1045 | struct kimage *image; | ||
1046 | int locked; | 1045 | int locked; |
1047 | 1046 | ||
1048 | 1047 | ||
@@ -1056,12 +1055,11 @@ void crash_kexec(struct pt_regs *regs) | |||
1056 | */ | 1055 | */ |
1057 | locked = xchg(&kexec_lock, 1); | 1056 | locked = xchg(&kexec_lock, 1); |
1058 | if (!locked) { | 1057 | if (!locked) { |
1059 | image = xchg(&kexec_crash_image, NULL); | 1058 | if (kexec_crash_image) { |
1060 | if (image) { | ||
1061 | struct pt_regs fixed_regs; | 1059 | struct pt_regs fixed_regs; |
1062 | crash_setup_regs(&fixed_regs, regs); | 1060 | crash_setup_regs(&fixed_regs, regs); |
1063 | machine_crash_shutdown(&fixed_regs); | 1061 | machine_crash_shutdown(&fixed_regs); |
1064 | machine_kexec(image); | 1062 | machine_kexec(kexec_crash_image); |
1065 | } | 1063 | } |
1066 | xchg(&kexec_lock, 0); | 1064 | xchg(&kexec_lock, 0); |
1067 | } | 1065 | } |
diff --git a/kernel/resource.c b/kernel/resource.c index 2404f9b0bc47..bf1130d81b7f 100644 --- a/kernel/resource.c +++ b/kernel/resource.c | |||
@@ -23,20 +23,18 @@ | |||
23 | 23 | ||
24 | struct resource ioport_resource = { | 24 | struct resource ioport_resource = { |
25 | .name = "PCI IO", | 25 | .name = "PCI IO", |
26 | .start = 0x0000, | 26 | .start = 0, |
27 | .end = IO_SPACE_LIMIT, | 27 | .end = IO_SPACE_LIMIT, |
28 | .flags = IORESOURCE_IO, | 28 | .flags = IORESOURCE_IO, |
29 | }; | 29 | }; |
30 | |||
31 | EXPORT_SYMBOL(ioport_resource); | 30 | EXPORT_SYMBOL(ioport_resource); |
32 | 31 | ||
33 | struct resource iomem_resource = { | 32 | struct resource iomem_resource = { |
34 | .name = "PCI mem", | 33 | .name = "PCI mem", |
35 | .start = 0UL, | 34 | .start = 0, |
36 | .end = ~0UL, | 35 | .end = -1, |
37 | .flags = IORESOURCE_MEM, | 36 | .flags = IORESOURCE_MEM, |
38 | }; | 37 | }; |
39 | |||
40 | EXPORT_SYMBOL(iomem_resource); | 38 | EXPORT_SYMBOL(iomem_resource); |
41 | 39 | ||
42 | static DEFINE_RWLOCK(resource_lock); | 40 | static DEFINE_RWLOCK(resource_lock); |
@@ -83,10 +81,10 @@ static int r_show(struct seq_file *m, void *v) | |||
83 | for (depth = 0, p = r; depth < MAX_IORES_LEVEL; depth++, p = p->parent) | 81 | for (depth = 0, p = r; depth < MAX_IORES_LEVEL; depth++, p = p->parent) |
84 | if (p->parent == root) | 82 | if (p->parent == root) |
85 | break; | 83 | break; |
86 | seq_printf(m, "%*s%0*lx-%0*lx : %s\n", | 84 | seq_printf(m, "%*s%0*llx-%0*llx : %s\n", |
87 | depth * 2, "", | 85 | depth * 2, "", |
88 | width, r->start, | 86 | width, (unsigned long long) r->start, |
89 | width, r->end, | 87 | width, (unsigned long long) r->end, |
90 | r->name ? r->name : "<BAD>"); | 88 | r->name ? r->name : "<BAD>"); |
91 | return 0; | 89 | return 0; |
92 | } | 90 | } |
@@ -151,8 +149,8 @@ __initcall(ioresources_init); | |||
151 | /* Return the conflict entry if you can't request it */ | 149 | /* Return the conflict entry if you can't request it */ |
152 | static struct resource * __request_resource(struct resource *root, struct resource *new) | 150 | static struct resource * __request_resource(struct resource *root, struct resource *new) |
153 | { | 151 | { |
154 | unsigned long start = new->start; | 152 | resource_size_t start = new->start; |
155 | unsigned long end = new->end; | 153 | resource_size_t end = new->end; |
156 | struct resource *tmp, **p; | 154 | struct resource *tmp, **p; |
157 | 155 | ||
158 | if (end < start) | 156 | if (end < start) |
@@ -274,11 +272,10 @@ int find_next_system_ram(struct resource *res) | |||
274 | * Find empty slot in the resource tree given range and alignment. | 272 | * Find empty slot in the resource tree given range and alignment. |
275 | */ | 273 | */ |
276 | static int find_resource(struct resource *root, struct resource *new, | 274 | static int find_resource(struct resource *root, struct resource *new, |
277 | unsigned long size, | 275 | resource_size_t size, resource_size_t min, |
278 | unsigned long min, unsigned long max, | 276 | resource_size_t max, resource_size_t align, |
279 | unsigned long align, | ||
280 | void (*alignf)(void *, struct resource *, | 277 | void (*alignf)(void *, struct resource *, |
281 | unsigned long, unsigned long), | 278 | resource_size_t, resource_size_t), |
282 | void *alignf_data) | 279 | void *alignf_data) |
283 | { | 280 | { |
284 | struct resource *this = root->child; | 281 | struct resource *this = root->child; |
@@ -320,11 +317,10 @@ static int find_resource(struct resource *root, struct resource *new, | |||
320 | * Allocate empty slot in the resource tree given range and alignment. | 317 | * Allocate empty slot in the resource tree given range and alignment. |
321 | */ | 318 | */ |
322 | int allocate_resource(struct resource *root, struct resource *new, | 319 | int allocate_resource(struct resource *root, struct resource *new, |
323 | unsigned long size, | 320 | resource_size_t size, resource_size_t min, |
324 | unsigned long min, unsigned long max, | 321 | resource_size_t max, resource_size_t align, |
325 | unsigned long align, | ||
326 | void (*alignf)(void *, struct resource *, | 322 | void (*alignf)(void *, struct resource *, |
327 | unsigned long, unsigned long), | 323 | resource_size_t, resource_size_t), |
328 | void *alignf_data) | 324 | void *alignf_data) |
329 | { | 325 | { |
330 | int err; | 326 | int err; |
@@ -416,10 +412,10 @@ EXPORT_SYMBOL(insert_resource); | |||
416 | * arguments. Returns -EBUSY if it can't fit. Existing children of | 412 | * arguments. Returns -EBUSY if it can't fit. Existing children of |
417 | * the resource are assumed to be immutable. | 413 | * the resource are assumed to be immutable. |
418 | */ | 414 | */ |
419 | int adjust_resource(struct resource *res, unsigned long start, unsigned long size) | 415 | int adjust_resource(struct resource *res, resource_size_t start, resource_size_t size) |
420 | { | 416 | { |
421 | struct resource *tmp, *parent = res->parent; | 417 | struct resource *tmp, *parent = res->parent; |
422 | unsigned long end = start + size - 1; | 418 | resource_size_t end = start + size - 1; |
423 | int result = -EBUSY; | 419 | int result = -EBUSY; |
424 | 420 | ||
425 | write_lock(&resource_lock); | 421 | write_lock(&resource_lock); |
@@ -466,7 +462,9 @@ EXPORT_SYMBOL(adjust_resource); | |||
466 | * | 462 | * |
467 | * Release-region releases a matching busy region. | 463 | * Release-region releases a matching busy region. |
468 | */ | 464 | */ |
469 | struct resource * __request_region(struct resource *parent, unsigned long start, unsigned long n, const char *name) | 465 | struct resource * __request_region(struct resource *parent, |
466 | resource_size_t start, resource_size_t n, | ||
467 | const char *name) | ||
470 | { | 468 | { |
471 | struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); | 469 | struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); |
472 | 470 | ||
@@ -502,7 +500,8 @@ struct resource * __request_region(struct resource *parent, unsigned long start, | |||
502 | 500 | ||
503 | EXPORT_SYMBOL(__request_region); | 501 | EXPORT_SYMBOL(__request_region); |
504 | 502 | ||
505 | int __check_region(struct resource *parent, unsigned long start, unsigned long n) | 503 | int __check_region(struct resource *parent, resource_size_t start, |
504 | resource_size_t n) | ||
506 | { | 505 | { |
507 | struct resource * res; | 506 | struct resource * res; |
508 | 507 | ||
@@ -517,10 +516,11 @@ int __check_region(struct resource *parent, unsigned long start, unsigned long n | |||
517 | 516 | ||
518 | EXPORT_SYMBOL(__check_region); | 517 | EXPORT_SYMBOL(__check_region); |
519 | 518 | ||
520 | void __release_region(struct resource *parent, unsigned long start, unsigned long n) | 519 | void __release_region(struct resource *parent, resource_size_t start, |
520 | resource_size_t n) | ||
521 | { | 521 | { |
522 | struct resource **p; | 522 | struct resource **p; |
523 | unsigned long end; | 523 | resource_size_t end; |
524 | 524 | ||
525 | p = &parent->child; | 525 | p = &parent->child; |
526 | end = start + n - 1; | 526 | end = start + n - 1; |
@@ -549,7 +549,9 @@ void __release_region(struct resource *parent, unsigned long start, unsigned lon | |||
549 | 549 | ||
550 | write_unlock(&resource_lock); | 550 | write_unlock(&resource_lock); |
551 | 551 | ||
552 | printk(KERN_WARNING "Trying to free nonexistent resource <%08lx-%08lx>\n", start, end); | 552 | printk(KERN_WARNING "Trying to free nonexistent resource " |
553 | "<%016llx-%016llx>\n", (unsigned long long)start, | ||
554 | (unsigned long long)end); | ||
553 | } | 555 | } |
554 | 556 | ||
555 | EXPORT_SYMBOL(__release_region); | 557 | EXPORT_SYMBOL(__release_region); |
diff --git a/mm/Kconfig b/mm/Kconfig index e76c023eb0bb..8f5b45615f7b 100644 --- a/mm/Kconfig +++ b/mm/Kconfig | |||
@@ -115,7 +115,7 @@ config SPARSEMEM_EXTREME | |||
115 | # eventually, we can have this option just 'select SPARSEMEM' | 115 | # eventually, we can have this option just 'select SPARSEMEM' |
116 | config MEMORY_HOTPLUG | 116 | config MEMORY_HOTPLUG |
117 | bool "Allow for memory hot-add" | 117 | bool "Allow for memory hot-add" |
118 | depends on SPARSEMEM && HOTPLUG && !SOFTWARE_SUSPEND | 118 | depends on SPARSEMEM && HOTPLUG && !SOFTWARE_SUSPEND && ARCH_ENABLE_MEMORY_HOTPLUG |
119 | depends on (IA64 || X86 || PPC64) | 119 | depends on (IA64 || X86 || PPC64) |
120 | 120 | ||
121 | comment "Memory hotplug is currently incompatible with Software Suspend" | 121 | comment "Memory hotplug is currently incompatible with Software Suspend" |
@@ -146,3 +146,9 @@ config MIGRATION | |||
146 | while the virtual addresses are not changed. This is useful for | 146 | while the virtual addresses are not changed. This is useful for |
147 | example on NUMA systems to put pages nearer to the processors accessing | 147 | example on NUMA systems to put pages nearer to the processors accessing |
148 | the page. | 148 | the page. |
149 | |||
150 | config RESOURCES_64BIT | ||
151 | bool "64 bit Memory and IO resources (EXPERIMENTAL)" if (!64BIT && EXPERIMENTAL) | ||
152 | default 64BIT | ||
153 | help | ||
154 | This option allows memory and IO resources to be 64 bit. | ||
diff --git a/mm/filemap.c b/mm/filemap.c index 4082b3b3cea7..648f2c0c8e18 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -2125,6 +2125,12 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov, | |||
2125 | break; | 2125 | break; |
2126 | } | 2126 | } |
2127 | 2127 | ||
2128 | if (unlikely(bytes == 0)) { | ||
2129 | status = 0; | ||
2130 | copied = 0; | ||
2131 | goto zero_length_segment; | ||
2132 | } | ||
2133 | |||
2128 | status = a_ops->prepare_write(file, page, offset, offset+bytes); | 2134 | status = a_ops->prepare_write(file, page, offset, offset+bytes); |
2129 | if (unlikely(status)) { | 2135 | if (unlikely(status)) { |
2130 | loff_t isize = i_size_read(inode); | 2136 | loff_t isize = i_size_read(inode); |
@@ -2154,7 +2160,8 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov, | |||
2154 | page_cache_release(page); | 2160 | page_cache_release(page); |
2155 | continue; | 2161 | continue; |
2156 | } | 2162 | } |
2157 | if (likely(copied > 0)) { | 2163 | zero_length_segment: |
2164 | if (likely(copied >= 0)) { | ||
2158 | if (!status) | 2165 | if (!status) |
2159 | status = copied; | 2166 | status = copied; |
2160 | 2167 | ||
diff --git a/mm/filemap.h b/mm/filemap.h index 536979fb4ba7..3f2a343c6015 100644 --- a/mm/filemap.h +++ b/mm/filemap.h | |||
@@ -88,7 +88,7 @@ filemap_set_next_iovec(const struct iovec **iovp, size_t *basep, size_t bytes) | |||
88 | const struct iovec *iov = *iovp; | 88 | const struct iovec *iov = *iovp; |
89 | size_t base = *basep; | 89 | size_t base = *basep; |
90 | 90 | ||
91 | while (bytes) { | 91 | do { |
92 | int copy = min(bytes, iov->iov_len - base); | 92 | int copy = min(bytes, iov->iov_len - base); |
93 | 93 | ||
94 | bytes -= copy; | 94 | bytes -= copy; |
@@ -97,7 +97,7 @@ filemap_set_next_iovec(const struct iovec **iovp, size_t *basep, size_t bytes) | |||
97 | iov++; | 97 | iov++; |
98 | base = 0; | 98 | base = 0; |
99 | } | 99 | } |
100 | } | 100 | } while (bytes); |
101 | *iovp = iov; | 101 | *iovp = iov; |
102 | *basep = base; | 102 | *basep = base; |
103 | } | 103 | } |
diff --git a/security/keys/internal.h b/security/keys/internal.h index 3c2877f0663e..1bb416f4bbce 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h | |||
@@ -99,6 +99,7 @@ extern int install_process_keyring(struct task_struct *tsk); | |||
99 | extern struct key *request_key_and_link(struct key_type *type, | 99 | extern struct key *request_key_and_link(struct key_type *type, |
100 | const char *description, | 100 | const char *description, |
101 | const char *callout_info, | 101 | const char *callout_info, |
102 | void *aux, | ||
102 | struct key *dest_keyring, | 103 | struct key *dest_keyring, |
103 | unsigned long flags); | 104 | unsigned long flags); |
104 | 105 | ||
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 329411cf8768..d9ca15c109cc 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c | |||
@@ -183,7 +183,7 @@ asmlinkage long sys_request_key(const char __user *_type, | |||
183 | } | 183 | } |
184 | 184 | ||
185 | /* do the search */ | 185 | /* do the search */ |
186 | key = request_key_and_link(ktype, description, callout_info, | 186 | key = request_key_and_link(ktype, description, callout_info, NULL, |
187 | key_ref_to_ptr(dest_ref), | 187 | key_ref_to_ptr(dest_ref), |
188 | KEY_ALLOC_IN_QUOTA); | 188 | KEY_ALLOC_IN_QUOTA); |
189 | if (IS_ERR(key)) { | 189 | if (IS_ERR(key)) { |
diff --git a/security/keys/request_key.c b/security/keys/request_key.c index 58d1efd4fc2c..f573ac189a0a 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* request_key.c: request a key from userspace | 1 | /* request_key.c: request a key from userspace |
2 | * | 2 | * |
3 | * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved. | 3 | * Copyright (C) 2004-6 Red Hat, Inc. All Rights Reserved. |
4 | * Written by David Howells (dhowells@redhat.com) | 4 | * Written by David Howells (dhowells@redhat.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 |
@@ -33,7 +33,8 @@ DECLARE_WAIT_QUEUE_HEAD(request_key_conswq); | |||
33 | */ | 33 | */ |
34 | static int call_sbin_request_key(struct key *key, | 34 | static int call_sbin_request_key(struct key *key, |
35 | struct key *authkey, | 35 | struct key *authkey, |
36 | const char *op) | 36 | const char *op, |
37 | void *aux) | ||
37 | { | 38 | { |
38 | struct task_struct *tsk = current; | 39 | struct task_struct *tsk = current; |
39 | key_serial_t prkey, sskey; | 40 | key_serial_t prkey, sskey; |
@@ -127,6 +128,7 @@ error_alloc: | |||
127 | static struct key *__request_key_construction(struct key_type *type, | 128 | static struct key *__request_key_construction(struct key_type *type, |
128 | const char *description, | 129 | const char *description, |
129 | const char *callout_info, | 130 | const char *callout_info, |
131 | void *aux, | ||
130 | unsigned long flags) | 132 | unsigned long flags) |
131 | { | 133 | { |
132 | request_key_actor_t actor; | 134 | request_key_actor_t actor; |
@@ -164,7 +166,7 @@ static struct key *__request_key_construction(struct key_type *type, | |||
164 | actor = call_sbin_request_key; | 166 | actor = call_sbin_request_key; |
165 | if (type->request_key) | 167 | if (type->request_key) |
166 | actor = type->request_key; | 168 | actor = type->request_key; |
167 | ret = actor(key, authkey, "create"); | 169 | ret = actor(key, authkey, "create", aux); |
168 | if (ret < 0) | 170 | if (ret < 0) |
169 | goto request_failed; | 171 | goto request_failed; |
170 | 172 | ||
@@ -258,8 +260,9 @@ alloc_failed: | |||
258 | */ | 260 | */ |
259 | static struct key *request_key_construction(struct key_type *type, | 261 | static struct key *request_key_construction(struct key_type *type, |
260 | const char *description, | 262 | const char *description, |
261 | struct key_user *user, | ||
262 | const char *callout_info, | 263 | const char *callout_info, |
264 | void *aux, | ||
265 | struct key_user *user, | ||
263 | unsigned long flags) | 266 | unsigned long flags) |
264 | { | 267 | { |
265 | struct key_construction *pcons; | 268 | struct key_construction *pcons; |
@@ -284,7 +287,7 @@ static struct key *request_key_construction(struct key_type *type, | |||
284 | } | 287 | } |
285 | 288 | ||
286 | /* see about getting userspace to construct the key */ | 289 | /* see about getting userspace to construct the key */ |
287 | key = __request_key_construction(type, description, callout_info, | 290 | key = __request_key_construction(type, description, callout_info, aux, |
288 | flags); | 291 | flags); |
289 | error: | 292 | error: |
290 | kleave(" = %p", key); | 293 | kleave(" = %p", key); |
@@ -392,6 +395,7 @@ static void request_key_link(struct key *key, struct key *dest_keyring) | |||
392 | struct key *request_key_and_link(struct key_type *type, | 395 | struct key *request_key_and_link(struct key_type *type, |
393 | const char *description, | 396 | const char *description, |
394 | const char *callout_info, | 397 | const char *callout_info, |
398 | void *aux, | ||
395 | struct key *dest_keyring, | 399 | struct key *dest_keyring, |
396 | unsigned long flags) | 400 | unsigned long flags) |
397 | { | 401 | { |
@@ -399,8 +403,9 @@ struct key *request_key_and_link(struct key_type *type, | |||
399 | struct key *key; | 403 | struct key *key; |
400 | key_ref_t key_ref; | 404 | key_ref_t key_ref; |
401 | 405 | ||
402 | kenter("%s,%s,%s,%p,%lx", | 406 | kenter("%s,%s,%s,%p,%p,%lx", |
403 | type->name, description, callout_info, dest_keyring, flags); | 407 | type->name, description, callout_info, aux, |
408 | dest_keyring, flags); | ||
404 | 409 | ||
405 | /* search all the process keyrings for a key */ | 410 | /* search all the process keyrings for a key */ |
406 | key_ref = search_process_keyrings(type, description, type->match, | 411 | key_ref = search_process_keyrings(type, description, type->match, |
@@ -433,8 +438,8 @@ struct key *request_key_and_link(struct key_type *type, | |||
433 | /* ask userspace (returns NULL if it waited on a key | 438 | /* ask userspace (returns NULL if it waited on a key |
434 | * being constructed) */ | 439 | * being constructed) */ |
435 | key = request_key_construction(type, description, | 440 | key = request_key_construction(type, description, |
436 | user, callout_info, | 441 | callout_info, aux, |
437 | flags); | 442 | user, flags); |
438 | if (key) | 443 | if (key) |
439 | break; | 444 | break; |
440 | 445 | ||
@@ -491,8 +496,27 @@ struct key *request_key(struct key_type *type, | |||
491 | const char *callout_info) | 496 | const char *callout_info) |
492 | { | 497 | { |
493 | return request_key_and_link(type, description, callout_info, NULL, | 498 | return request_key_and_link(type, description, callout_info, NULL, |
494 | KEY_ALLOC_IN_QUOTA); | 499 | NULL, KEY_ALLOC_IN_QUOTA); |
495 | 500 | ||
496 | } /* end request_key() */ | 501 | } /* end request_key() */ |
497 | 502 | ||
498 | EXPORT_SYMBOL(request_key); | 503 | EXPORT_SYMBOL(request_key); |
504 | |||
505 | /*****************************************************************************/ | ||
506 | /* | ||
507 | * request a key with auxiliary data for the upcaller | ||
508 | * - search the process's keyrings | ||
509 | * - check the list of keys being created or updated | ||
510 | * - call out to userspace for a key if supplementary info was provided | ||
511 | */ | ||
512 | struct key *request_key_with_auxdata(struct key_type *type, | ||
513 | const char *description, | ||
514 | const char *callout_info, | ||
515 | void *aux) | ||
516 | { | ||
517 | return request_key_and_link(type, description, callout_info, aux, | ||
518 | NULL, KEY_ALLOC_IN_QUOTA); | ||
519 | |||
520 | } /* end request_key_with_auxdata() */ | ||
521 | |||
522 | EXPORT_SYMBOL(request_key_with_auxdata); | ||
diff --git a/sound/Makefile b/sound/Makefile index a682ea30f0c9..1f60797afa8a 100644 --- a/sound/Makefile +++ b/sound/Makefile | |||
@@ -4,7 +4,8 @@ | |||
4 | obj-$(CONFIG_SOUND) += soundcore.o | 4 | obj-$(CONFIG_SOUND) += soundcore.o |
5 | obj-$(CONFIG_SOUND_PRIME) += oss/ | 5 | obj-$(CONFIG_SOUND_PRIME) += oss/ |
6 | obj-$(CONFIG_DMASOUND) += oss/ | 6 | obj-$(CONFIG_DMASOUND) += oss/ |
7 | obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/ usb/ sparc/ parisc/ pcmcia/ mips/ aoa/ | 7 | obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/ usb/ sparc/ parisc/ pcmcia/ mips/ |
8 | obj-$(CONFIG_SND_AOA) += aoa/ | ||
8 | 9 | ||
9 | ifeq ($(CONFIG_SND),y) | 10 | ifeq ($(CONFIG_SND),y) |
10 | obj-y += last.o | 11 | obj-y += last.o |
diff --git a/sound/aoa/Kconfig b/sound/aoa/Kconfig index a85194fe0b06..2f4334d19ccd 100644 --- a/sound/aoa/Kconfig +++ b/sound/aoa/Kconfig | |||
@@ -3,7 +3,8 @@ menu "Apple Onboard Audio driver" | |||
3 | 3 | ||
4 | config SND_AOA | 4 | config SND_AOA |
5 | tristate "Apple Onboard Audio driver" | 5 | tristate "Apple Onboard Audio driver" |
6 | depends on SOUND && SND_PCM | 6 | depends on SND |
7 | select SND_PCM | ||
7 | ---help--- | 8 | ---help--- |
8 | This option enables the new driver for the various | 9 | This option enables the new driver for the various |
9 | Apple Onboard Audio components. | 10 | Apple Onboard Audio components. |
diff --git a/sound/aoa/core/snd-aoa-gpio-feature.c b/sound/aoa/core/snd-aoa-gpio-feature.c index 2c6eb7784cc9..bab97547a052 100644 --- a/sound/aoa/core/snd-aoa-gpio-feature.c +++ b/sound/aoa/core/snd-aoa-gpio-feature.c | |||
@@ -207,6 +207,17 @@ static void ftr_handle_notify(void *data) | |||
207 | mutex_unlock(¬if->mutex); | 207 | mutex_unlock(¬if->mutex); |
208 | } | 208 | } |
209 | 209 | ||
210 | static void gpio_enable_dual_edge(int gpio) | ||
211 | { | ||
212 | int v; | ||
213 | |||
214 | if (gpio == -1) | ||
215 | return; | ||
216 | v = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, gpio, 0); | ||
217 | v |= 0x80; /* enable dual edge */ | ||
218 | pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, gpio, v); | ||
219 | } | ||
220 | |||
210 | static void ftr_gpio_init(struct gpio_runtime *rt) | 221 | static void ftr_gpio_init(struct gpio_runtime *rt) |
211 | { | 222 | { |
212 | get_gpio("headphone-mute", NULL, | 223 | get_gpio("headphone-mute", NULL, |
@@ -234,6 +245,10 @@ static void ftr_gpio_init(struct gpio_runtime *rt) | |||
234 | &linein_detect_gpio, | 245 | &linein_detect_gpio, |
235 | &linein_detect_gpio_activestate); | 246 | &linein_detect_gpio_activestate); |
236 | 247 | ||
248 | gpio_enable_dual_edge(headphone_detect_gpio); | ||
249 | gpio_enable_dual_edge(lineout_detect_gpio); | ||
250 | gpio_enable_dual_edge(linein_detect_gpio); | ||
251 | |||
237 | get_irq(headphone_detect_node, &headphone_detect_irq); | 252 | get_irq(headphone_detect_node, &headphone_detect_irq); |
238 | get_irq(lineout_detect_node, &lineout_detect_irq); | 253 | get_irq(lineout_detect_node, &lineout_detect_irq); |
239 | get_irq(linein_detect_node, &linein_detect_irq); | 254 | get_irq(linein_detect_node, &linein_detect_irq); |
diff --git a/sound/aoa/fabrics/snd-aoa-fabric-layout.c b/sound/aoa/fabrics/snd-aoa-fabric-layout.c index 04a7238e9494..cbc8a3b5cea4 100644 --- a/sound/aoa/fabrics/snd-aoa-fabric-layout.c +++ b/sound/aoa/fabrics/snd-aoa-fabric-layout.c | |||
@@ -94,6 +94,7 @@ MODULE_ALIAS("sound-layout-82"); | |||
94 | MODULE_ALIAS("sound-layout-84"); | 94 | MODULE_ALIAS("sound-layout-84"); |
95 | MODULE_ALIAS("sound-layout-86"); | 95 | MODULE_ALIAS("sound-layout-86"); |
96 | MODULE_ALIAS("sound-layout-92"); | 96 | MODULE_ALIAS("sound-layout-92"); |
97 | MODULE_ALIAS("sound-layout-96"); | ||
97 | 98 | ||
98 | /* onyx with all but microphone connected */ | 99 | /* onyx with all but microphone connected */ |
99 | static struct codec_connection onyx_connections_nomic[] = { | 100 | static struct codec_connection onyx_connections_nomic[] = { |
@@ -381,6 +382,13 @@ static struct layout layouts[] = { | |||
381 | .connections = toonie_connections, | 382 | .connections = toonie_connections, |
382 | }, | 383 | }, |
383 | }, | 384 | }, |
385 | { | ||
386 | .layout_id = 96, | ||
387 | .codecs[0] = { | ||
388 | .name = "onyx", | ||
389 | .connections = onyx_connections_noheadphones, | ||
390 | }, | ||
391 | }, | ||
384 | /* unknown, untested, but this comes from Apple */ | 392 | /* unknown, untested, but this comes from Apple */ |
385 | { .layout_id = 41, | 393 | { .layout_id = 41, |
386 | .codecs[0] = { | 394 | .codecs[0] = { |
@@ -479,12 +487,6 @@ static struct layout layouts[] = { | |||
479 | .connections = onyx_connections_noheadphones, | 487 | .connections = onyx_connections_noheadphones, |
480 | }, | 488 | }, |
481 | }, | 489 | }, |
482 | { .layout_id = 96, | ||
483 | .codecs[0] = { | ||
484 | .name = "onyx", | ||
485 | .connections = onyx_connections_noheadphones, | ||
486 | }, | ||
487 | }, | ||
488 | { .layout_id = 98, | 490 | { .layout_id = 98, |
489 | .codecs[0] = { | 491 | .codecs[0] = { |
490 | .name = "toonie", | 492 | .name = "toonie", |
diff --git a/sound/aoa/soundbus/Kconfig b/sound/aoa/soundbus/Kconfig index d532d27a9f54..7368b7ddfe0d 100644 --- a/sound/aoa/soundbus/Kconfig +++ b/sound/aoa/soundbus/Kconfig | |||
@@ -1,6 +1,7 @@ | |||
1 | config SND_AOA_SOUNDBUS | 1 | config SND_AOA_SOUNDBUS |
2 | tristate "Apple Soundbus support" | 2 | tristate "Apple Soundbus support" |
3 | depends on SOUND && SND_PCM && EXPERIMENTAL | 3 | depends on SOUND |
4 | select SND_PCM | ||
4 | ---help--- | 5 | ---help--- |
5 | This option enables the generic driver for the soundbus | 6 | This option enables the generic driver for the soundbus |
6 | support on Apple machines. | 7 | support on Apple machines. |
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index 5f22d70fefc0..6b18225672c7 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c | |||
@@ -779,8 +779,9 @@ static struct aaci * __devinit aaci_init_card(struct amba_device *dev) | |||
779 | strlcpy(card->driver, DRIVER_NAME, sizeof(card->driver)); | 779 | strlcpy(card->driver, DRIVER_NAME, sizeof(card->driver)); |
780 | strlcpy(card->shortname, "ARM AC'97 Interface", sizeof(card->shortname)); | 780 | strlcpy(card->shortname, "ARM AC'97 Interface", sizeof(card->shortname)); |
781 | snprintf(card->longname, sizeof(card->longname), | 781 | snprintf(card->longname, sizeof(card->longname), |
782 | "%s at 0x%08lx, irq %d", | 782 | "%s at 0x%016llx, irq %d", |
783 | card->shortname, dev->res.start, dev->irq[0]); | 783 | card->shortname, (unsigned long long)dev->res.start, |
784 | dev->irq[0]); | ||
784 | 785 | ||
785 | aaci = card->private_data; | 786 | aaci = card->private_data; |
786 | mutex_init(&aaci->ac97_sem); | 787 | mutex_init(&aaci->ac97_sem); |
diff --git a/sound/core/Kconfig b/sound/core/Kconfig index 4262a1c87731..b2927523d79d 100644 --- a/sound/core/Kconfig +++ b/sound/core/Kconfig | |||
@@ -122,8 +122,8 @@ config SND_SEQ_RTCTIMER_DEFAULT | |||
122 | If in doubt, say Y. | 122 | If in doubt, say Y. |
123 | 123 | ||
124 | config SND_DYNAMIC_MINORS | 124 | config SND_DYNAMIC_MINORS |
125 | bool "Dynamic device file minor numbers (EXPERIMENTAL)" | 125 | bool "Dynamic device file minor numbers" |
126 | depends on SND && EXPERIMENTAL | 126 | depends on SND |
127 | help | 127 | help |
128 | If you say Y here, the minor numbers of ALSA device files in | 128 | If you say Y here, the minor numbers of ALSA device files in |
129 | /dev/snd/ are allocated dynamically. This allows you to have | 129 | /dev/snd/ are allocated dynamically. This allows you to have |
diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c index 334579a9f268..d467b4f0ff2b 100644 --- a/sound/core/seq/seq_ports.c +++ b/sound/core/seq/seq_ports.c | |||
@@ -322,10 +322,8 @@ int snd_seq_delete_all_ports(struct snd_seq_client *client) | |||
322 | mutex_lock(&client->ports_mutex); | 322 | mutex_lock(&client->ports_mutex); |
323 | write_lock_irqsave(&client->ports_lock, flags); | 323 | write_lock_irqsave(&client->ports_lock, flags); |
324 | if (! list_empty(&client->ports_list_head)) { | 324 | if (! list_empty(&client->ports_list_head)) { |
325 | __list_add(&deleted_list, | 325 | list_add(&deleted_list, &client->ports_list_head); |
326 | client->ports_list_head.prev, | 326 | list_del_init(&client->ports_list_head); |
327 | client->ports_list_head.next); | ||
328 | INIT_LIST_HEAD(&client->ports_list_head); | ||
329 | } else { | 327 | } else { |
330 | INIT_LIST_HEAD(&deleted_list); | 328 | INIT_LIST_HEAD(&deleted_list); |
331 | } | 329 | } |
diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c index d3cbbb047582..8b80024968be 100644 --- a/sound/drivers/mpu401/mpu401.c +++ b/sound/drivers/mpu401/mpu401.c | |||
@@ -160,8 +160,9 @@ static int __devinit snd_mpu401_pnp(int dev, struct pnp_dev *device, | |||
160 | return -ENODEV; | 160 | return -ENODEV; |
161 | } | 161 | } |
162 | if (pnp_port_len(device, 0) < IO_EXTENT) { | 162 | if (pnp_port_len(device, 0) < IO_EXTENT) { |
163 | snd_printk(KERN_ERR "PnP port length is %ld, expected %d\n", | 163 | snd_printk(KERN_ERR "PnP port length is %llu, expected %d\n", |
164 | pnp_port_len(device, 0), IO_EXTENT); | 164 | (unsigned long long)pnp_port_len(device, 0), |
165 | IO_EXTENT); | ||
165 | return -ENODEV; | 166 | return -ENODEV; |
166 | } | 167 | } |
167 | port[dev] = pnp_port_start(device, 0); | 168 | port[dev] = pnp_port_start(device, 0); |
diff --git a/sound/i2c/other/ak4xxx-adda.c b/sound/i2c/other/ak4xxx-adda.c index 045e32a311e0..dc7cc2001b74 100644 --- a/sound/i2c/other/ak4xxx-adda.c +++ b/sound/i2c/other/ak4xxx-adda.c | |||
@@ -34,7 +34,8 @@ MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Takashi Iwai <tiwai@suse.de>"); | |||
34 | MODULE_DESCRIPTION("Routines for control of AK452x / AK43xx AD/DA converters"); | 34 | MODULE_DESCRIPTION("Routines for control of AK452x / AK43xx AD/DA converters"); |
35 | MODULE_LICENSE("GPL"); | 35 | MODULE_LICENSE("GPL"); |
36 | 36 | ||
37 | void snd_akm4xxx_write(struct snd_akm4xxx *ak, int chip, unsigned char reg, unsigned char val) | 37 | void snd_akm4xxx_write(struct snd_akm4xxx *ak, int chip, unsigned char reg, |
38 | unsigned char val) | ||
38 | { | 39 | { |
39 | ak->ops.lock(ak, chip); | 40 | ak->ops.lock(ak, chip); |
40 | ak->ops.write(ak, chip, reg, val); | 41 | ak->ops.write(ak, chip, reg, val); |
@@ -52,6 +53,67 @@ void snd_akm4xxx_write(struct snd_akm4xxx *ak, int chip, unsigned char reg, unsi | |||
52 | ak->ops.unlock(ak, chip); | 53 | ak->ops.unlock(ak, chip); |
53 | } | 54 | } |
54 | 55 | ||
56 | EXPORT_SYMBOL(snd_akm4xxx_write); | ||
57 | |||
58 | /* reset procedure for AK4524 and AK4528 */ | ||
59 | static void ak4524_reset(struct snd_akm4xxx *ak, int state) | ||
60 | { | ||
61 | unsigned int chip; | ||
62 | unsigned char reg, maxreg; | ||
63 | |||
64 | if (ak->type == SND_AK4528) | ||
65 | maxreg = 0x06; | ||
66 | else | ||
67 | maxreg = 0x08; | ||
68 | for (chip = 0; chip < ak->num_dacs/2; chip++) { | ||
69 | snd_akm4xxx_write(ak, chip, 0x01, state ? 0x00 : 0x03); | ||
70 | if (state) | ||
71 | continue; | ||
72 | /* DAC volumes */ | ||
73 | for (reg = 0x04; reg < maxreg; reg++) | ||
74 | snd_akm4xxx_write(ak, chip, reg, | ||
75 | snd_akm4xxx_get(ak, chip, reg)); | ||
76 | if (ak->type == SND_AK4528) | ||
77 | continue; | ||
78 | /* IPGA */ | ||
79 | for (reg = 0x04; reg < 0x06; reg++) | ||
80 | snd_akm4xxx_write(ak, chip, reg, | ||
81 | snd_akm4xxx_get_ipga(ak, chip, reg)); | ||
82 | } | ||
83 | } | ||
84 | |||
85 | /* reset procedure for AK4355 and AK4358 */ | ||
86 | static void ak4355_reset(struct snd_akm4xxx *ak, int state) | ||
87 | { | ||
88 | unsigned char reg; | ||
89 | |||
90 | if (state) { | ||
91 | snd_akm4xxx_write(ak, 0, 0x01, 0x02); /* reset and soft-mute */ | ||
92 | return; | ||
93 | } | ||
94 | for (reg = 0x00; reg < 0x0b; reg++) | ||
95 | if (reg != 0x01) | ||
96 | snd_akm4xxx_write(ak, 0, reg, | ||
97 | snd_akm4xxx_get(ak, 0, reg)); | ||
98 | snd_akm4xxx_write(ak, 0, 0x01, 0x01); /* un-reset, unmute */ | ||
99 | } | ||
100 | |||
101 | /* reset procedure for AK4381 */ | ||
102 | static void ak4381_reset(struct snd_akm4xxx *ak, int state) | ||
103 | { | ||
104 | unsigned int chip; | ||
105 | unsigned char reg; | ||
106 | |||
107 | for (chip = 0; chip < ak->num_dacs/2; chip++) { | ||
108 | snd_akm4xxx_write(ak, chip, 0x00, state ? 0x0c : 0x0f); | ||
109 | if (state) | ||
110 | continue; | ||
111 | for (reg = 0x01; reg < 0x05; reg++) | ||
112 | snd_akm4xxx_write(ak, chip, reg, | ||
113 | snd_akm4xxx_get(ak, chip, reg)); | ||
114 | } | ||
115 | } | ||
116 | |||
55 | /* | 117 | /* |
56 | * reset the AKM codecs | 118 | * reset the AKM codecs |
57 | * @state: 1 = reset codec, 0 = restore the registers | 119 | * @state: 1 = reset codec, 0 = restore the registers |
@@ -60,52 +122,26 @@ void snd_akm4xxx_write(struct snd_akm4xxx *ak, int chip, unsigned char reg, unsi | |||
60 | */ | 122 | */ |
61 | void snd_akm4xxx_reset(struct snd_akm4xxx *ak, int state) | 123 | void snd_akm4xxx_reset(struct snd_akm4xxx *ak, int state) |
62 | { | 124 | { |
63 | unsigned int chip; | ||
64 | unsigned char reg; | ||
65 | |||
66 | switch (ak->type) { | 125 | switch (ak->type) { |
67 | case SND_AK4524: | 126 | case SND_AK4524: |
68 | case SND_AK4528: | 127 | case SND_AK4528: |
69 | for (chip = 0; chip < ak->num_dacs/2; chip++) { | 128 | ak4524_reset(ak, state); |
70 | snd_akm4xxx_write(ak, chip, 0x01, state ? 0x00 : 0x03); | ||
71 | if (state) | ||
72 | continue; | ||
73 | /* DAC volumes */ | ||
74 | for (reg = 0x04; reg < (ak->type == SND_AK4528 ? 0x06 : 0x08); reg++) | ||
75 | snd_akm4xxx_write(ak, chip, reg, snd_akm4xxx_get(ak, chip, reg)); | ||
76 | if (ak->type == SND_AK4528) | ||
77 | continue; | ||
78 | /* IPGA */ | ||
79 | for (reg = 0x04; reg < 0x06; reg++) | ||
80 | snd_akm4xxx_write(ak, chip, reg, snd_akm4xxx_get_ipga(ak, chip, reg)); | ||
81 | } | ||
82 | break; | 129 | break; |
83 | case SND_AK4529: | 130 | case SND_AK4529: |
84 | /* FIXME: needed for ak4529? */ | 131 | /* FIXME: needed for ak4529? */ |
85 | break; | 132 | break; |
86 | case SND_AK4355: | 133 | case SND_AK4355: |
87 | case SND_AK4358: | 134 | case SND_AK4358: |
88 | if (state) { | 135 | ak4355_reset(ak, state); |
89 | snd_akm4xxx_write(ak, 0, 0x01, 0x02); /* reset and soft-mute */ | ||
90 | return; | ||
91 | } | ||
92 | for (reg = 0x00; reg < 0x0b; reg++) | ||
93 | if (reg != 0x01) | ||
94 | snd_akm4xxx_write(ak, 0, reg, snd_akm4xxx_get(ak, 0, reg)); | ||
95 | snd_akm4xxx_write(ak, 0, 0x01, 0x01); /* un-reset, unmute */ | ||
96 | break; | 136 | break; |
97 | case SND_AK4381: | 137 | case SND_AK4381: |
98 | for (chip = 0; chip < ak->num_dacs/2; chip++) { | 138 | ak4381_reset(ak, state); |
99 | snd_akm4xxx_write(ak, chip, 0x00, state ? 0x0c : 0x0f); | ||
100 | if (state) | ||
101 | continue; | ||
102 | for (reg = 0x01; reg < 0x05; reg++) | ||
103 | snd_akm4xxx_write(ak, chip, reg, snd_akm4xxx_get(ak, chip, reg)); | ||
104 | } | ||
105 | break; | 139 | break; |
106 | } | 140 | } |
107 | } | 141 | } |
108 | 142 | ||
143 | EXPORT_SYMBOL(snd_akm4xxx_reset); | ||
144 | |||
109 | /* | 145 | /* |
110 | * initialize all the ak4xxx chips | 146 | * initialize all the ak4xxx chips |
111 | */ | 147 | */ |
@@ -153,7 +189,8 @@ void snd_akm4xxx_init(struct snd_akm4xxx *ak) | |||
153 | }; | 189 | }; |
154 | static unsigned char inits_ak4355[] = { | 190 | static unsigned char inits_ak4355[] = { |
155 | 0x01, 0x02, /* 1: reset and soft-mute */ | 191 | 0x01, 0x02, /* 1: reset and soft-mute */ |
156 | 0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect, disable DZF, sharp roll-off, RSTN#=0 */ | 192 | 0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect, |
193 | * disable DZF, sharp roll-off, RSTN#=0 */ | ||
157 | 0x02, 0x0e, /* 2: DA's power up, normal speed, RSTN#=0 */ | 194 | 0x02, 0x0e, /* 2: DA's power up, normal speed, RSTN#=0 */ |
158 | // 0x02, 0x2e, /* quad speed */ | 195 | // 0x02, 0x2e, /* quad speed */ |
159 | 0x03, 0x01, /* 3: de-emphasis off */ | 196 | 0x03, 0x01, /* 3: de-emphasis off */ |
@@ -169,7 +206,8 @@ void snd_akm4xxx_init(struct snd_akm4xxx *ak) | |||
169 | }; | 206 | }; |
170 | static unsigned char inits_ak4358[] = { | 207 | static unsigned char inits_ak4358[] = { |
171 | 0x01, 0x02, /* 1: reset and soft-mute */ | 208 | 0x01, 0x02, /* 1: reset and soft-mute */ |
172 | 0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect, disable DZF, sharp roll-off, RSTN#=0 */ | 209 | 0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect, |
210 | * disable DZF, sharp roll-off, RSTN#=0 */ | ||
173 | 0x02, 0x0e, /* 2: DA's power up, normal speed, RSTN#=0 */ | 211 | 0x02, 0x0e, /* 2: DA's power up, normal speed, RSTN#=0 */ |
174 | // 0x02, 0x2e, /* quad speed */ | 212 | // 0x02, 0x2e, /* quad speed */ |
175 | 0x03, 0x01, /* 3: de-emphasis off */ | 213 | 0x03, 0x01, /* 3: de-emphasis off */ |
@@ -187,7 +225,8 @@ void snd_akm4xxx_init(struct snd_akm4xxx *ak) | |||
187 | }; | 225 | }; |
188 | static unsigned char inits_ak4381[] = { | 226 | static unsigned char inits_ak4381[] = { |
189 | 0x00, 0x0c, /* 0: mode3(i2s), disable auto-clock detect */ | 227 | 0x00, 0x0c, /* 0: mode3(i2s), disable auto-clock detect */ |
190 | 0x01, 0x02, /* 1: de-emphasis off, normal speed, sharp roll-off, DZF off */ | 228 | 0x01, 0x02, /* 1: de-emphasis off, normal speed, |
229 | * sharp roll-off, DZF off */ | ||
191 | // 0x01, 0x12, /* quad speed */ | 230 | // 0x01, 0x12, /* quad speed */ |
192 | 0x02, 0x00, /* 2: DZF disabled */ | 231 | 0x02, 0x00, /* 2: DZF disabled */ |
193 | 0x03, 0x00, /* 3: LATT 0 */ | 232 | 0x03, 0x00, /* 3: LATT 0 */ |
@@ -239,12 +278,15 @@ void snd_akm4xxx_init(struct snd_akm4xxx *ak) | |||
239 | } | 278 | } |
240 | } | 279 | } |
241 | 280 | ||
281 | EXPORT_SYMBOL(snd_akm4xxx_init); | ||
282 | |||
242 | #define AK_GET_CHIP(val) (((val) >> 8) & 0xff) | 283 | #define AK_GET_CHIP(val) (((val) >> 8) & 0xff) |
243 | #define AK_GET_ADDR(val) ((val) & 0xff) | 284 | #define AK_GET_ADDR(val) ((val) & 0xff) |
244 | #define AK_GET_SHIFT(val) (((val) >> 16) & 0x7f) | 285 | #define AK_GET_SHIFT(val) (((val) >> 16) & 0x7f) |
245 | #define AK_GET_INVERT(val) (((val) >> 23) & 1) | 286 | #define AK_GET_INVERT(val) (((val) >> 23) & 1) |
246 | #define AK_GET_MASK(val) (((val) >> 24) & 0xff) | 287 | #define AK_GET_MASK(val) (((val) >> 24) & 0xff) |
247 | #define AK_COMPOSE(chip,addr,shift,mask) (((chip) << 8) | (addr) | ((shift) << 16) | ((mask) << 24)) | 288 | #define AK_COMPOSE(chip,addr,shift,mask) \ |
289 | (((chip) << 8) | (addr) | ((shift) << 16) | ((mask) << 24)) | ||
248 | #define AK_INVERT (1<<23) | 290 | #define AK_INVERT (1<<23) |
249 | 291 | ||
250 | static int snd_akm4xxx_volume_info(struct snd_kcontrol *kcontrol, | 292 | static int snd_akm4xxx_volume_info(struct snd_kcontrol *kcontrol, |
@@ -292,6 +334,64 @@ static int snd_akm4xxx_volume_put(struct snd_kcontrol *kcontrol, | |||
292 | return change; | 334 | return change; |
293 | } | 335 | } |
294 | 336 | ||
337 | static int snd_akm4xxx_stereo_volume_info(struct snd_kcontrol *kcontrol, | ||
338 | struct snd_ctl_elem_info *uinfo) | ||
339 | { | ||
340 | unsigned int mask = AK_GET_MASK(kcontrol->private_value); | ||
341 | |||
342 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
343 | uinfo->count = 2; | ||
344 | uinfo->value.integer.min = 0; | ||
345 | uinfo->value.integer.max = mask; | ||
346 | return 0; | ||
347 | } | ||
348 | |||
349 | static int snd_akm4xxx_stereo_volume_get(struct snd_kcontrol *kcontrol, | ||
350 | struct snd_ctl_elem_value *ucontrol) | ||
351 | { | ||
352 | struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); | ||
353 | int chip = AK_GET_CHIP(kcontrol->private_value); | ||
354 | int addr = AK_GET_ADDR(kcontrol->private_value); | ||
355 | int invert = AK_GET_INVERT(kcontrol->private_value); | ||
356 | unsigned int mask = AK_GET_MASK(kcontrol->private_value); | ||
357 | unsigned char val = snd_akm4xxx_get(ak, chip, addr); | ||
358 | |||
359 | ucontrol->value.integer.value[0] = invert ? mask - val : val; | ||
360 | |||
361 | val = snd_akm4xxx_get(ak, chip, addr+1); | ||
362 | ucontrol->value.integer.value[1] = invert ? mask - val : val; | ||
363 | |||
364 | return 0; | ||
365 | } | ||
366 | |||
367 | static int snd_akm4xxx_stereo_volume_put(struct snd_kcontrol *kcontrol, | ||
368 | struct snd_ctl_elem_value *ucontrol) | ||
369 | { | ||
370 | struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); | ||
371 | int chip = AK_GET_CHIP(kcontrol->private_value); | ||
372 | int addr = AK_GET_ADDR(kcontrol->private_value); | ||
373 | int invert = AK_GET_INVERT(kcontrol->private_value); | ||
374 | unsigned int mask = AK_GET_MASK(kcontrol->private_value); | ||
375 | unsigned char nval = ucontrol->value.integer.value[0] % (mask+1); | ||
376 | int change0, change1; | ||
377 | |||
378 | if (invert) | ||
379 | nval = mask - nval; | ||
380 | change0 = snd_akm4xxx_get(ak, chip, addr) != nval; | ||
381 | if (change0) | ||
382 | snd_akm4xxx_write(ak, chip, addr, nval); | ||
383 | |||
384 | nval = ucontrol->value.integer.value[1] % (mask+1); | ||
385 | if (invert) | ||
386 | nval = mask - nval; | ||
387 | change1 = snd_akm4xxx_get(ak, chip, addr+1) != nval; | ||
388 | if (change1) | ||
389 | snd_akm4xxx_write(ak, chip, addr+1, nval); | ||
390 | |||
391 | |||
392 | return change0 || change1; | ||
393 | } | ||
394 | |||
295 | static int snd_akm4xxx_ipga_gain_info(struct snd_kcontrol *kcontrol, | 395 | static int snd_akm4xxx_ipga_gain_info(struct snd_kcontrol *kcontrol, |
296 | struct snd_ctl_elem_info *uinfo) | 396 | struct snd_ctl_elem_info *uinfo) |
297 | { | 397 | { |
@@ -308,7 +408,8 @@ static int snd_akm4xxx_ipga_gain_get(struct snd_kcontrol *kcontrol, | |||
308 | struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); | 408 | struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); |
309 | int chip = AK_GET_CHIP(kcontrol->private_value); | 409 | int chip = AK_GET_CHIP(kcontrol->private_value); |
310 | int addr = AK_GET_ADDR(kcontrol->private_value); | 410 | int addr = AK_GET_ADDR(kcontrol->private_value); |
311 | ucontrol->value.integer.value[0] = snd_akm4xxx_get_ipga(ak, chip, addr) & 0x7f; | 411 | ucontrol->value.integer.value[0] = |
412 | snd_akm4xxx_get_ipga(ak, chip, addr) & 0x7f; | ||
312 | return 0; | 413 | return 0; |
313 | } | 414 | } |
314 | 415 | ||
@@ -336,7 +437,8 @@ static int snd_akm4xxx_deemphasis_info(struct snd_kcontrol *kcontrol, | |||
336 | uinfo->value.enumerated.items = 4; | 437 | uinfo->value.enumerated.items = 4; |
337 | if (uinfo->value.enumerated.item >= 4) | 438 | if (uinfo->value.enumerated.item >= 4) |
338 | uinfo->value.enumerated.item = 3; | 439 | uinfo->value.enumerated.item = 3; |
339 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | 440 | strcpy(uinfo->value.enumerated.name, |
441 | texts[uinfo->value.enumerated.item]); | ||
340 | return 0; | 442 | return 0; |
341 | } | 443 | } |
342 | 444 | ||
@@ -347,7 +449,8 @@ static int snd_akm4xxx_deemphasis_get(struct snd_kcontrol *kcontrol, | |||
347 | int chip = AK_GET_CHIP(kcontrol->private_value); | 449 | int chip = AK_GET_CHIP(kcontrol->private_value); |
348 | int addr = AK_GET_ADDR(kcontrol->private_value); | 450 | int addr = AK_GET_ADDR(kcontrol->private_value); |
349 | int shift = AK_GET_SHIFT(kcontrol->private_value); | 451 | int shift = AK_GET_SHIFT(kcontrol->private_value); |
350 | ucontrol->value.enumerated.item[0] = (snd_akm4xxx_get(ak, chip, addr) >> shift) & 3; | 452 | ucontrol->value.enumerated.item[0] = |
453 | (snd_akm4xxx_get(ak, chip, addr) >> shift) & 3; | ||
351 | return 0; | 454 | return 0; |
352 | } | 455 | } |
353 | 456 | ||
@@ -361,7 +464,8 @@ static int snd_akm4xxx_deemphasis_put(struct snd_kcontrol *kcontrol, | |||
361 | unsigned char nval = ucontrol->value.enumerated.item[0] & 3; | 464 | unsigned char nval = ucontrol->value.enumerated.item[0] & 3; |
362 | int change; | 465 | int change; |
363 | 466 | ||
364 | nval = (nval << shift) | (snd_akm4xxx_get(ak, chip, addr) & ~(3 << shift)); | 467 | nval = (nval << shift) | |
468 | (snd_akm4xxx_get(ak, chip, addr) & ~(3 << shift)); | ||
365 | change = snd_akm4xxx_get(ak, chip, addr) != nval; | 469 | change = snd_akm4xxx_get(ak, chip, addr) != nval; |
366 | if (change) | 470 | if (change) |
367 | snd_akm4xxx_write(ak, chip, addr, nval); | 471 | snd_akm4xxx_write(ak, chip, addr, nval); |
@@ -377,51 +481,86 @@ int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak) | |||
377 | unsigned int idx, num_emphs; | 481 | unsigned int idx, num_emphs; |
378 | struct snd_kcontrol *ctl; | 482 | struct snd_kcontrol *ctl; |
379 | int err; | 483 | int err; |
484 | int mixer_ch = 0; | ||
485 | int num_stereo; | ||
380 | 486 | ||
381 | ctl = kmalloc(sizeof(*ctl), GFP_KERNEL); | 487 | ctl = kmalloc(sizeof(*ctl), GFP_KERNEL); |
382 | if (! ctl) | 488 | if (! ctl) |
383 | return -ENOMEM; | 489 | return -ENOMEM; |
384 | 490 | ||
385 | for (idx = 0; idx < ak->num_dacs; ++idx) { | 491 | for (idx = 0; idx < ak->num_dacs; ) { |
386 | memset(ctl, 0, sizeof(*ctl)); | 492 | memset(ctl, 0, sizeof(*ctl)); |
387 | strcpy(ctl->id.name, "DAC Volume"); | 493 | if (ak->channel_names == NULL) { |
388 | ctl->id.index = idx + ak->idx_offset * 2; | 494 | strcpy(ctl->id.name, "DAC Volume"); |
495 | num_stereo = 1; | ||
496 | ctl->id.index = mixer_ch + ak->idx_offset * 2; | ||
497 | } else { | ||
498 | strcpy(ctl->id.name, ak->channel_names[mixer_ch]); | ||
499 | num_stereo = ak->num_stereo[mixer_ch]; | ||
500 | ctl->id.index = 0; | ||
501 | } | ||
389 | ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | 502 | ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; |
390 | ctl->count = 1; | 503 | ctl->count = 1; |
391 | ctl->info = snd_akm4xxx_volume_info; | 504 | if (num_stereo == 2) { |
392 | ctl->get = snd_akm4xxx_volume_get; | 505 | ctl->info = snd_akm4xxx_stereo_volume_info; |
393 | ctl->put = snd_akm4xxx_volume_put; | 506 | ctl->get = snd_akm4xxx_stereo_volume_get; |
507 | ctl->put = snd_akm4xxx_stereo_volume_put; | ||
508 | } else { | ||
509 | ctl->info = snd_akm4xxx_volume_info; | ||
510 | ctl->get = snd_akm4xxx_volume_get; | ||
511 | ctl->put = snd_akm4xxx_volume_put; | ||
512 | } | ||
394 | switch (ak->type) { | 513 | switch (ak->type) { |
395 | case SND_AK4524: | 514 | case SND_AK4524: |
396 | ctl->private_value = AK_COMPOSE(idx/2, (idx%2) + 6, 0, 127); /* register 6 & 7 */ | 515 | /* register 6 & 7 */ |
516 | ctl->private_value = | ||
517 | AK_COMPOSE(idx/2, (idx%2) + 6, 0, 127); | ||
397 | break; | 518 | break; |
398 | case SND_AK4528: | 519 | case SND_AK4528: |
399 | ctl->private_value = AK_COMPOSE(idx/2, (idx%2) + 4, 0, 127); /* register 4 & 5 */ | 520 | /* register 4 & 5 */ |
521 | ctl->private_value = | ||
522 | AK_COMPOSE(idx/2, (idx%2) + 4, 0, 127); | ||
400 | break; | 523 | break; |
401 | case SND_AK4529: { | 524 | case SND_AK4529: { |
402 | int val = idx < 6 ? idx + 2 : (idx - 6) + 0xb; /* registers 2-7 and b,c */ | 525 | /* registers 2-7 and b,c */ |
403 | ctl->private_value = AK_COMPOSE(0, val, 0, 255) | AK_INVERT; | 526 | int val = idx < 6 ? idx + 2 : (idx - 6) + 0xb; |
527 | ctl->private_value = | ||
528 | AK_COMPOSE(0, val, 0, 255) | AK_INVERT; | ||
404 | break; | 529 | break; |
405 | } | 530 | } |
406 | case SND_AK4355: | 531 | case SND_AK4355: |
407 | ctl->private_value = AK_COMPOSE(0, idx + 4, 0, 255); /* register 4-9, chip #0 only */ | 532 | /* register 4-9, chip #0 only */ |
533 | ctl->private_value = AK_COMPOSE(0, idx + 4, 0, 255); | ||
408 | break; | 534 | break; |
409 | case SND_AK4358: | 535 | case SND_AK4358: |
410 | if (idx >= 6) | 536 | if (idx >= 6) |
411 | ctl->private_value = AK_COMPOSE(0, idx + 5, 0, 255); /* register 4-9, chip #0 only */ | 537 | /* register 4-9, chip #0 only */ |
538 | ctl->private_value = | ||
539 | AK_COMPOSE(0, idx + 5, 0, 255); | ||
412 | else | 540 | else |
413 | ctl->private_value = AK_COMPOSE(0, idx + 4, 0, 255); /* register 4-9, chip #0 only */ | 541 | /* register 4-9, chip #0 only */ |
542 | ctl->private_value = | ||
543 | AK_COMPOSE(0, idx + 4, 0, 255); | ||
414 | break; | 544 | break; |
415 | case SND_AK4381: | 545 | case SND_AK4381: |
416 | ctl->private_value = AK_COMPOSE(idx/2, (idx%2) + 3, 0, 255); /* register 3 & 4 */ | 546 | /* register 3 & 4 */ |
547 | ctl->private_value = | ||
548 | AK_COMPOSE(idx/2, (idx%2) + 3, 0, 255); | ||
417 | break; | 549 | break; |
418 | default: | 550 | default: |
419 | err = -EINVAL; | 551 | err = -EINVAL; |
420 | goto __error; | 552 | goto __error; |
421 | } | 553 | } |
554 | |||
422 | ctl->private_data = ak; | 555 | ctl->private_data = ak; |
423 | if ((err = snd_ctl_add(ak->card, snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE))) < 0) | 556 | err = snd_ctl_add(ak->card, |
557 | snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ| | ||
558 | SNDRV_CTL_ELEM_ACCESS_WRITE)); | ||
559 | if (err < 0) | ||
424 | goto __error; | 560 | goto __error; |
561 | |||
562 | idx += num_stereo; | ||
563 | mixer_ch++; | ||
425 | } | 564 | } |
426 | for (idx = 0; idx < ak->num_adcs && ak->type == SND_AK4524; ++idx) { | 565 | for (idx = 0; idx < ak->num_adcs && ak->type == SND_AK4524; ++idx) { |
427 | memset(ctl, 0, sizeof(*ctl)); | 566 | memset(ctl, 0, sizeof(*ctl)); |
@@ -432,9 +571,14 @@ int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak) | |||
432 | ctl->info = snd_akm4xxx_volume_info; | 571 | ctl->info = snd_akm4xxx_volume_info; |
433 | ctl->get = snd_akm4xxx_volume_get; | 572 | ctl->get = snd_akm4xxx_volume_get; |
434 | ctl->put = snd_akm4xxx_volume_put; | 573 | ctl->put = snd_akm4xxx_volume_put; |
435 | ctl->private_value = AK_COMPOSE(idx/2, (idx%2) + 4, 0, 127); /* register 4 & 5 */ | 574 | /* register 4 & 5 */ |
575 | ctl->private_value = | ||
576 | AK_COMPOSE(idx/2, (idx%2) + 4, 0, 127); | ||
436 | ctl->private_data = ak; | 577 | ctl->private_data = ak; |
437 | if ((err = snd_ctl_add(ak->card, snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE))) < 0) | 578 | err = snd_ctl_add(ak->card, |
579 | snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ| | ||
580 | SNDRV_CTL_ELEM_ACCESS_WRITE)); | ||
581 | if (err < 0) | ||
438 | goto __error; | 582 | goto __error; |
439 | 583 | ||
440 | memset(ctl, 0, sizeof(*ctl)); | 584 | memset(ctl, 0, sizeof(*ctl)); |
@@ -445,9 +589,13 @@ int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak) | |||
445 | ctl->info = snd_akm4xxx_ipga_gain_info; | 589 | ctl->info = snd_akm4xxx_ipga_gain_info; |
446 | ctl->get = snd_akm4xxx_ipga_gain_get; | 590 | ctl->get = snd_akm4xxx_ipga_gain_get; |
447 | ctl->put = snd_akm4xxx_ipga_gain_put; | 591 | ctl->put = snd_akm4xxx_ipga_gain_put; |
448 | ctl->private_value = AK_COMPOSE(idx/2, (idx%2) + 4, 0, 0); /* register 4 & 5 */ | 592 | /* register 4 & 5 */ |
593 | ctl->private_value = AK_COMPOSE(idx/2, (idx%2) + 4, 0, 0); | ||
449 | ctl->private_data = ak; | 594 | ctl->private_data = ak; |
450 | if ((err = snd_ctl_add(ak->card, snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE))) < 0) | 595 | err = snd_ctl_add(ak->card, |
596 | snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ| | ||
597 | SNDRV_CTL_ELEM_ACCESS_WRITE)); | ||
598 | if (err < 0) | ||
451 | goto __error; | 599 | goto __error; |
452 | } | 600 | } |
453 | if (ak->type == SND_AK4355 || ak->type == SND_AK4358) | 601 | if (ak->type == SND_AK4355 || ak->type == SND_AK4358) |
@@ -466,11 +614,13 @@ int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak) | |||
466 | switch (ak->type) { | 614 | switch (ak->type) { |
467 | case SND_AK4524: | 615 | case SND_AK4524: |
468 | case SND_AK4528: | 616 | case SND_AK4528: |
469 | ctl->private_value = AK_COMPOSE(idx, 3, 0, 0); /* register 3 */ | 617 | /* register 3 */ |
618 | ctl->private_value = AK_COMPOSE(idx, 3, 0, 0); | ||
470 | break; | 619 | break; |
471 | case SND_AK4529: { | 620 | case SND_AK4529: { |
472 | int shift = idx == 3 ? 6 : (2 - idx) * 2; | 621 | int shift = idx == 3 ? 6 : (2 - idx) * 2; |
473 | ctl->private_value = AK_COMPOSE(0, 8, shift, 0); /* register 8 with shift */ | 622 | /* register 8 with shift */ |
623 | ctl->private_value = AK_COMPOSE(0, 8, shift, 0); | ||
474 | break; | 624 | break; |
475 | } | 625 | } |
476 | case SND_AK4355: | 626 | case SND_AK4355: |
@@ -482,7 +632,10 @@ int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak) | |||
482 | break; | 632 | break; |
483 | } | 633 | } |
484 | ctl->private_data = ak; | 634 | ctl->private_data = ak; |
485 | if ((err = snd_ctl_add(ak->card, snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE))) < 0) | 635 | err = snd_ctl_add(ak->card, |
636 | snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ| | ||
637 | SNDRV_CTL_ELEM_ACCESS_WRITE)); | ||
638 | if (err < 0) | ||
486 | goto __error; | 639 | goto __error; |
487 | } | 640 | } |
488 | err = 0; | 641 | err = 0; |
@@ -492,6 +645,8 @@ int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak) | |||
492 | return err; | 645 | return err; |
493 | } | 646 | } |
494 | 647 | ||
648 | EXPORT_SYMBOL(snd_akm4xxx_build_controls); | ||
649 | |||
495 | static int __init alsa_akm4xxx_module_init(void) | 650 | static int __init alsa_akm4xxx_module_init(void) |
496 | { | 651 | { |
497 | return 0; | 652 | return 0; |
@@ -503,8 +658,3 @@ static void __exit alsa_akm4xxx_module_exit(void) | |||
503 | 658 | ||
504 | module_init(alsa_akm4xxx_module_init) | 659 | module_init(alsa_akm4xxx_module_init) |
505 | module_exit(alsa_akm4xxx_module_exit) | 660 | module_exit(alsa_akm4xxx_module_exit) |
506 | |||
507 | EXPORT_SYMBOL(snd_akm4xxx_write); | ||
508 | EXPORT_SYMBOL(snd_akm4xxx_reset); | ||
509 | EXPORT_SYMBOL(snd_akm4xxx_init); | ||
510 | EXPORT_SYMBOL(snd_akm4xxx_build_controls); | ||
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c index e6945db8ed1b..af60b0bc8115 100644 --- a/sound/isa/es18xx.c +++ b/sound/isa/es18xx.c | |||
@@ -2088,7 +2088,8 @@ static int __devinit snd_audiodrive_pnp(int dev, struct snd_audiodrive *acard, | |||
2088 | kfree(cfg); | 2088 | kfree(cfg); |
2089 | return -EAGAIN; | 2089 | return -EAGAIN; |
2090 | } | 2090 | } |
2091 | snd_printdd("pnp: port=0x%lx\n", pnp_port_start(acard->devc, 0)); | 2091 | snd_printdd("pnp: port=0x%llx\n", |
2092 | (unsigned long long)pnp_port_start(acard->devc, 0)); | ||
2092 | /* PnP initialization */ | 2093 | /* PnP initialization */ |
2093 | pdev = acard->dev; | 2094 | pdev = acard->dev; |
2094 | pnp_init_resource_table(cfg); | 2095 | pnp_init_resource_table(cfg); |
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c index 866300f2acbb..c1c86e0fa56d 100644 --- a/sound/isa/gus/interwave.c +++ b/sound/isa/gus/interwave.c | |||
@@ -611,10 +611,10 @@ static int __devinit snd_interwave_pnp(int dev, struct snd_interwave *iwcard, | |||
611 | if (dma2[dev] >= 0) | 611 | if (dma2[dev] >= 0) |
612 | dma2[dev] = pnp_dma(pdev, 1); | 612 | dma2[dev] = pnp_dma(pdev, 1); |
613 | irq[dev] = pnp_irq(pdev, 0); | 613 | irq[dev] = pnp_irq(pdev, 0); |
614 | snd_printdd("isapnp IW: sb port=0x%lx, gf1 port=0x%lx, codec port=0x%lx\n", | 614 | snd_printdd("isapnp IW: sb port=0x%llx, gf1 port=0x%llx, codec port=0x%llx\n", |
615 | pnp_port_start(pdev, 0), | 615 | (unsigned long long)pnp_port_start(pdev, 0), |
616 | pnp_port_start(pdev, 1), | 616 | (unsigned long long)pnp_port_start(pdev, 1), |
617 | pnp_port_start(pdev, 2)); | 617 | (unsigned long long)pnp_port_start(pdev, 2)); |
618 | snd_printdd("isapnp IW: dma1=%i, dma2=%i, irq=%i\n", dma1[dev], dma2[dev], irq[dev]); | 618 | snd_printdd("isapnp IW: dma1=%i, dma2=%i, irq=%i\n", dma1[dev], dma2[dev], irq[dev]); |
619 | #ifdef SNDRV_STB | 619 | #ifdef SNDRV_STB |
620 | /* Tone Control initialization */ | 620 | /* Tone Control initialization */ |
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c index 7f7f05fa518a..d64e67f2bafa 100644 --- a/sound/isa/sb/sb16.c +++ b/sound/isa/sb/sb16.c | |||
@@ -327,7 +327,8 @@ static int __devinit snd_card_sb16_pnp(int dev, struct snd_card_sb16 *acard, | |||
327 | goto __wt_error; | 327 | goto __wt_error; |
328 | } | 328 | } |
329 | awe_port[dev] = pnp_port_start(pdev, 0); | 329 | awe_port[dev] = pnp_port_start(pdev, 0); |
330 | snd_printdd("pnp SB16: wavetable port=0x%lx\n", pnp_port_start(pdev, 0)); | 330 | snd_printdd("pnp SB16: wavetable port=0x%llx\n", |
331 | (unsigned long long)pnp_port_start(pdev, 0)); | ||
331 | } else { | 332 | } else { |
332 | __wt_error: | 333 | __wt_error: |
333 | if (pdev) { | 334 | if (pdev) { |
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig index 3b8cdbca2636..f4980ca5c05c 100644 --- a/sound/oss/Kconfig +++ b/sound/oss/Kconfig | |||
@@ -493,6 +493,19 @@ config SOUND_CS4232 | |||
493 | See <file:Documentation/sound/oss/CS4232> for more information on | 493 | See <file:Documentation/sound/oss/CS4232> for more information on |
494 | configuring this card. | 494 | configuring this card. |
495 | 495 | ||
496 | config SOUND_SSCAPE | ||
497 | tristate "Ensoniq SoundScape support" | ||
498 | depends on SOUND_OSS | ||
499 | help | ||
500 | Answer Y if you have a sound card based on the Ensoniq SoundScape | ||
501 | chipset. Such cards are being manufactured at least by Ensoniq, Spea | ||
502 | and Reveal (Reveal makes also other cards). | ||
503 | |||
504 | If you compile the driver into the kernel, you have to add | ||
505 | "sscape=<io>,<irq>,<dma>,<mpuio>,<mpuirq>" to the kernel command | ||
506 | line. | ||
507 | |||
508 | |||
496 | config SOUND_VMIDI | 509 | config SOUND_VMIDI |
497 | tristate "Loopback MIDI device support" | 510 | tristate "Loopback MIDI device support" |
498 | depends on SOUND_OSS | 511 | depends on SOUND_OSS |
diff --git a/sound/oss/forte.c b/sound/oss/forte.c index 0294eec8ad90..44e578098d76 100644 --- a/sound/oss/forte.c +++ b/sound/oss/forte.c | |||
@@ -2035,8 +2035,9 @@ forte_probe (struct pci_dev *pci_dev, const struct pci_device_id *pci_id) | |||
2035 | 2035 | ||
2036 | pci_set_drvdata (pci_dev, chip); | 2036 | pci_set_drvdata (pci_dev, chip); |
2037 | 2037 | ||
2038 | printk (KERN_INFO PFX "FM801 chip found at 0x%04lX-0x%04lX IRQ %u\n", | 2038 | printk (KERN_INFO PFX "FM801 chip found at 0x%04lX-0x%16llX IRQ %u\n", |
2039 | chip->iobase, pci_resource_end (pci_dev, 0), chip->irq); | 2039 | chip->iobase, (unsigned long long)pci_resource_end (pci_dev, 0), |
2040 | chip->irq); | ||
2040 | 2041 | ||
2041 | /* Power it up */ | 2042 | /* Power it up */ |
2042 | if ((ret = forte_chip_init (chip)) == 0) | 2043 | if ((ret = forte_chip_init (chip)) == 0) |
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index d37346b12dc0..23e54cedfd4a 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig | |||
@@ -233,6 +233,143 @@ config SND_CS5535AUDIO | |||
233 | To compile this driver as a module, choose M here: the module | 233 | To compile this driver as a module, choose M here: the module |
234 | will be called snd-cs5535audio. | 234 | will be called snd-cs5535audio. |
235 | 235 | ||
236 | config SND_DARLA20 | ||
237 | tristate "(Echoaudio) Darla20" | ||
238 | depends on SND | ||
239 | depends on FW_LOADER | ||
240 | select SND_PCM | ||
241 | help | ||
242 | Say 'Y' or 'M' to include support for Echoaudio Darla. | ||
243 | |||
244 | To compile this driver as a module, choose M here: the module | ||
245 | will be called snd-darla20 | ||
246 | |||
247 | config SND_GINA20 | ||
248 | tristate "(Echoaudio) Gina20" | ||
249 | depends on SND | ||
250 | depends on FW_LOADER | ||
251 | select SND_PCM | ||
252 | help | ||
253 | Say 'Y' or 'M' to include support for Echoaudio Gina. | ||
254 | |||
255 | To compile this driver as a module, choose M here: the module | ||
256 | will be called snd-gina20 | ||
257 | |||
258 | config SND_LAYLA20 | ||
259 | tristate "(Echoaudio) Layla20" | ||
260 | depends on SND | ||
261 | depends on FW_LOADER | ||
262 | select SND_RAWMIDI | ||
263 | select SND_PCM | ||
264 | help | ||
265 | Say 'Y' or 'M' to include support for Echoaudio Layla. | ||
266 | |||
267 | To compile this driver as a module, choose M here: the module | ||
268 | will be called snd-layla20 | ||
269 | |||
270 | config SND_DARLA24 | ||
271 | tristate "(Echoaudio) Darla24" | ||
272 | depends on SND | ||
273 | depends on FW_LOADER | ||
274 | select SND_PCM | ||
275 | help | ||
276 | Say 'Y' or 'M' to include support for Echoaudio Darla24. | ||
277 | |||
278 | To compile this driver as a module, choose M here: the module | ||
279 | will be called snd-darla24 | ||
280 | |||
281 | config SND_GINA24 | ||
282 | tristate "(Echoaudio) Gina24" | ||
283 | depends on SND | ||
284 | depends on FW_LOADER | ||
285 | select SND_PCM | ||
286 | help | ||
287 | Say 'Y' or 'M' to include support for Echoaudio Gina24. | ||
288 | |||
289 | To compile this driver as a module, choose M here: the module | ||
290 | will be called snd-gina24 | ||
291 | |||
292 | config SND_LAYLA24 | ||
293 | tristate "(Echoaudio) Layla24" | ||
294 | depends on SND | ||
295 | depends on FW_LOADER | ||
296 | select SND_RAWMIDI | ||
297 | select SND_PCM | ||
298 | help | ||
299 | Say 'Y' or 'M' to include support for Echoaudio Layla24. | ||
300 | |||
301 | To compile this driver as a module, choose M here: the module | ||
302 | will be called snd-layla24 | ||
303 | |||
304 | config SND_MONA | ||
305 | tristate "(Echoaudio) Mona" | ||
306 | depends on SND | ||
307 | depends on FW_LOADER | ||
308 | select SND_RAWMIDI | ||
309 | select SND_PCM | ||
310 | help | ||
311 | Say 'Y' or 'M' to include support for Echoaudio Mona. | ||
312 | |||
313 | To compile this driver as a module, choose M here: the module | ||
314 | will be called snd-mona | ||
315 | |||
316 | config SND_MIA | ||
317 | tristate "(Echoaudio) Mia" | ||
318 | depends on SND | ||
319 | depends on FW_LOADER | ||
320 | select SND_RAWMIDI | ||
321 | select SND_PCM | ||
322 | help | ||
323 | Say 'Y' or 'M' to include support for Echoaudio Mia and Mia-midi. | ||
324 | |||
325 | To compile this driver as a module, choose M here: the module | ||
326 | will be called snd-mia | ||
327 | |||
328 | config SND_ECHO3G | ||
329 | tristate "(Echoaudio) 3G cards" | ||
330 | depends on SND | ||
331 | depends on FW_LOADER | ||
332 | select SND_RAWMIDI | ||
333 | select SND_PCM | ||
334 | help | ||
335 | Say 'Y' or 'M' to include support for Echoaudio Gina3G and Layla3G. | ||
336 | |||
337 | To compile this driver as a module, choose M here: the module | ||
338 | will be called snd-echo3g | ||
339 | |||
340 | config SND_INDIGO | ||
341 | tristate "(Echoaudio) Indigo" | ||
342 | depends on SND | ||
343 | depends on FW_LOADER | ||
344 | select SND_PCM | ||
345 | help | ||
346 | Say 'Y' or 'M' to include support for Echoaudio Indigo. | ||
347 | |||
348 | To compile this driver as a module, choose M here: the module | ||
349 | will be called snd-indigo | ||
350 | |||
351 | config SND_INDIGOIO | ||
352 | tristate "(Echoaudio) Indigo IO" | ||
353 | depends on SND | ||
354 | depends on FW_LOADER | ||
355 | select SND_PCM | ||
356 | help | ||
357 | Say 'Y' or 'M' to include support for Echoaudio Indigo IO. | ||
358 | |||
359 | To compile this driver as a module, choose M here: the module | ||
360 | will be called snd-indigoio | ||
361 | |||
362 | config SND_INDIGODJ | ||
363 | tristate "(Echoaudio) Indigo DJ" | ||
364 | depends on SND | ||
365 | depends on FW_LOADER | ||
366 | select SND_PCM | ||
367 | help | ||
368 | Say 'Y' or 'M' to include support for Echoaudio Indigo DJ. | ||
369 | |||
370 | To compile this driver as a module, choose M here: the module | ||
371 | will be called snd-indigodj | ||
372 | |||
236 | config SND_EMU10K1 | 373 | config SND_EMU10K1 |
237 | tristate "Emu10k1 (SB Live!, Audigy, E-mu APS)" | 374 | tristate "Emu10k1 (SB Live!, Audigy, E-mu APS)" |
238 | depends on SND | 375 | depends on SND |
@@ -420,8 +557,8 @@ config SND_INTEL8X0 | |||
420 | will be called snd-intel8x0. | 557 | will be called snd-intel8x0. |
421 | 558 | ||
422 | config SND_INTEL8X0M | 559 | config SND_INTEL8X0M |
423 | tristate "Intel/SiS/nVidia/AMD MC97 Modem (EXPERIMENTAL)" | 560 | tristate "Intel/SiS/nVidia/AMD MC97 Modem" |
424 | depends on SND && EXPERIMENTAL | 561 | depends on SND |
425 | select SND_AC97_CODEC | 562 | select SND_AC97_CODEC |
426 | help | 563 | help |
427 | Say Y here to include support for the integrated MC97 modem on | 564 | Say Y here to include support for the integrated MC97 modem on |
diff --git a/sound/pci/Makefile b/sound/pci/Makefile index cba5105aafea..e06736da9ef1 100644 --- a/sound/pci/Makefile +++ b/sound/pci/Makefile | |||
@@ -57,6 +57,7 @@ obj-$(CONFIG_SND) += \ | |||
57 | ca0106/ \ | 57 | ca0106/ \ |
58 | cs46xx/ \ | 58 | cs46xx/ \ |
59 | cs5535audio/ \ | 59 | cs5535audio/ \ |
60 | echoaudio/ \ | ||
60 | emu10k1/ \ | 61 | emu10k1/ \ |
61 | hda/ \ | 62 | hda/ \ |
62 | ice1712/ \ | 63 | ice1712/ \ |
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index 7f197c780816..094cfc1f3a19 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c | |||
@@ -1824,6 +1824,8 @@ static const struct snd_kcontrol_new snd_ac97_ad1888_controls[] = { | |||
1824 | .get = snd_ac97_ad1888_lohpsel_get, | 1824 | .get = snd_ac97_ad1888_lohpsel_get, |
1825 | .put = snd_ac97_ad1888_lohpsel_put | 1825 | .put = snd_ac97_ad1888_lohpsel_put |
1826 | }, | 1826 | }, |
1827 | AC97_SINGLE("V_REFOUT Enable", AC97_AD_MISC, 2, 1, 1), | ||
1828 | AC97_SINGLE("High Pass Filter Enable", AC97_AD_TEST2, 12, 1, 1), | ||
1827 | AC97_SINGLE("Spread Front to Surround and Center/LFE", AC97_AD_MISC, 7, 1, 0), | 1829 | AC97_SINGLE("Spread Front to Surround and Center/LFE", AC97_AD_MISC, 7, 1, 0), |
1828 | { | 1830 | { |
1829 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1831 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index c33642d8d9a1..497ed6b20060 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c | |||
@@ -888,8 +888,9 @@ static int __devinit snd_bt87x_probe(struct pci_dev *pci, | |||
888 | 888 | ||
889 | strcpy(card->driver, "Bt87x"); | 889 | strcpy(card->driver, "Bt87x"); |
890 | sprintf(card->shortname, "Brooktree Bt%x", pci->device); | 890 | sprintf(card->shortname, "Brooktree Bt%x", pci->device); |
891 | sprintf(card->longname, "%s at %#lx, irq %i", | 891 | sprintf(card->longname, "%s at %#llx, irq %i", |
892 | card->shortname, pci_resource_start(pci, 0), chip->irq); | 892 | card->shortname, (unsigned long long)pci_resource_start(pci, 0), |
893 | chip->irq); | ||
893 | strcpy(card->mixername, "Bt87x"); | 894 | strcpy(card->mixername, "Bt87x"); |
894 | 895 | ||
895 | err = snd_card_register(card); | 896 | err = snd_card_register(card); |
diff --git a/sound/pci/echoaudio/Makefile b/sound/pci/echoaudio/Makefile new file mode 100644 index 000000000000..7b576aeb3f8d --- /dev/null +++ b/sound/pci/echoaudio/Makefile | |||
@@ -0,0 +1,30 @@ | |||
1 | # | ||
2 | # Makefile for ALSA Echoaudio soundcard drivers | ||
3 | # Copyright (c) 2003 by Giuliano Pochini <pochini@shiny.it> | ||
4 | # | ||
5 | |||
6 | snd-darla20-objs := darla20.o | ||
7 | snd-gina20-objs := gina20.o | ||
8 | snd-layla20-objs := layla20.o | ||
9 | snd-darla24-objs := darla24.o | ||
10 | snd-gina24-objs := gina24.o | ||
11 | snd-layla24-objs := layla24.o | ||
12 | snd-mona-objs := mona.o | ||
13 | snd-mia-objs := mia.o | ||
14 | snd-echo3g-objs := echo3g.o | ||
15 | snd-indigo-objs := indigo.o | ||
16 | snd-indigoio-objs := indigoio.o | ||
17 | snd-indigodj-objs := indigodj.o | ||
18 | |||
19 | obj-$(CONFIG_SND_DARLA20) += snd-darla20.o | ||
20 | obj-$(CONFIG_SND_GINA20) += snd-gina20.o | ||
21 | obj-$(CONFIG_SND_LAYLA20) += snd-layla20.o | ||
22 | obj-$(CONFIG_SND_DARLA24) += snd-darla24.o | ||
23 | obj-$(CONFIG_SND_GINA24) += snd-gina24.o | ||
24 | obj-$(CONFIG_SND_LAYLA24) += snd-layla24.o | ||
25 | obj-$(CONFIG_SND_MONA) += snd-mona.o | ||
26 | obj-$(CONFIG_SND_MIA) += snd-mia.o | ||
27 | obj-$(CONFIG_SND_ECHO3G) += snd-echo3g.o | ||
28 | obj-$(CONFIG_SND_INDIGO) += snd-indigo.o | ||
29 | obj-$(CONFIG_SND_INDIGOIO) += snd-indigoio.o | ||
30 | obj-$(CONFIG_SND_INDIGODJ) += snd-indigodj.o | ||
diff --git a/sound/pci/echoaudio/darla20.c b/sound/pci/echoaudio/darla20.c new file mode 100644 index 000000000000..b7108e29a668 --- /dev/null +++ b/sound/pci/echoaudio/darla20.c | |||
@@ -0,0 +1,99 @@ | |||
1 | /* | ||
2 | * ALSA driver for Echoaudio soundcards. | ||
3 | * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #define ECHOGALS_FAMILY | ||
20 | #define ECHOCARD_DARLA20 | ||
21 | #define ECHOCARD_NAME "Darla20" | ||
22 | #define ECHOCARD_HAS_MONITOR | ||
23 | |||
24 | /* Pipe indexes */ | ||
25 | #define PX_ANALOG_OUT 0 /* 8 */ | ||
26 | #define PX_DIGITAL_OUT 8 /* 0 */ | ||
27 | #define PX_ANALOG_IN 8 /* 2 */ | ||
28 | #define PX_DIGITAL_IN 10 /* 0 */ | ||
29 | #define PX_NUM 10 | ||
30 | |||
31 | /* Bus indexes */ | ||
32 | #define BX_ANALOG_OUT 0 /* 8 */ | ||
33 | #define BX_DIGITAL_OUT 8 /* 0 */ | ||
34 | #define BX_ANALOG_IN 8 /* 2 */ | ||
35 | #define BX_DIGITAL_IN 10 /* 0 */ | ||
36 | #define BX_NUM 10 | ||
37 | |||
38 | |||
39 | #include <sound/driver.h> | ||
40 | #include <linux/delay.h> | ||
41 | #include <linux/init.h> | ||
42 | #include <linux/interrupt.h> | ||
43 | #include <linux/pci.h> | ||
44 | #include <linux/slab.h> | ||
45 | #include <linux/moduleparam.h> | ||
46 | #include <linux/firmware.h> | ||
47 | #include <sound/core.h> | ||
48 | #include <sound/info.h> | ||
49 | #include <sound/control.h> | ||
50 | #include <sound/pcm.h> | ||
51 | #include <sound/pcm_params.h> | ||
52 | #include <sound/asoundef.h> | ||
53 | #include <sound/initval.h> | ||
54 | #include <asm/io.h> | ||
55 | #include <asm/atomic.h> | ||
56 | #include "echoaudio.h" | ||
57 | |||
58 | #define FW_DARLA20_DSP 0 | ||
59 | |||
60 | static const struct firmware card_fw[] = { | ||
61 | {0, "darla20_dsp.fw"} | ||
62 | }; | ||
63 | |||
64 | static struct pci_device_id snd_echo_ids[] = { | ||
65 | {0x1057, 0x1801, 0xECC0, 0x0010, 0, 0, 0}, /* DSP 56301 Darla20 rev.0 */ | ||
66 | {0,} | ||
67 | }; | ||
68 | |||
69 | static struct snd_pcm_hardware pcm_hardware_skel = { | ||
70 | .info = SNDRV_PCM_INFO_MMAP | | ||
71 | SNDRV_PCM_INFO_INTERLEAVED | | ||
72 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
73 | SNDRV_PCM_INFO_MMAP_VALID | | ||
74 | SNDRV_PCM_INFO_PAUSE | | ||
75 | SNDRV_PCM_INFO_SYNC_START, | ||
76 | .formats = SNDRV_PCM_FMTBIT_U8 | | ||
77 | SNDRV_PCM_FMTBIT_S16_LE | | ||
78 | SNDRV_PCM_FMTBIT_S24_3LE | | ||
79 | SNDRV_PCM_FMTBIT_S32_LE | | ||
80 | SNDRV_PCM_FMTBIT_S32_BE, | ||
81 | .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, | ||
82 | .rate_min = 44100, | ||
83 | .rate_max = 48000, | ||
84 | .channels_min = 1, | ||
85 | .channels_max = 2, | ||
86 | .buffer_bytes_max = 262144, | ||
87 | .period_bytes_min = 32, | ||
88 | .period_bytes_max = 131072, | ||
89 | .periods_min = 2, | ||
90 | .periods_max = 220, | ||
91 | /* One page (4k) contains 512 instructions. I don't know if the hw | ||
92 | supports lists longer than this. In this case periods_max=220 is a | ||
93 | safe limit to make sure the list never exceeds 512 instructions. */ | ||
94 | }; | ||
95 | |||
96 | |||
97 | #include "darla20_dsp.c" | ||
98 | #include "echoaudio_dsp.c" | ||
99 | #include "echoaudio.c" | ||
diff --git a/sound/pci/echoaudio/darla20_dsp.c b/sound/pci/echoaudio/darla20_dsp.c new file mode 100644 index 000000000000..4159e3bc186f --- /dev/null +++ b/sound/pci/echoaudio/darla20_dsp.c | |||
@@ -0,0 +1,125 @@ | |||
1 | /*************************************************************************** | ||
2 | |||
3 | Copyright Echo Digital Audio Corporation (c) 1998 - 2004 | ||
4 | All rights reserved | ||
5 | www.echoaudio.com | ||
6 | |||
7 | This file is part of Echo Digital Audio's generic driver library. | ||
8 | |||
9 | Echo Digital Audio's generic driver library is free software; | ||
10 | you can redistribute it and/or modify it under the terms of | ||
11 | the GNU General Public License as published by the Free Software | ||
12 | Foundation. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, | ||
22 | MA 02111-1307, USA. | ||
23 | |||
24 | ************************************************************************* | ||
25 | |||
26 | Translation from C++ and adaptation for use in ALSA-Driver | ||
27 | were made by Giuliano Pochini <pochini@shiny.it> | ||
28 | |||
29 | ****************************************************************************/ | ||
30 | |||
31 | |||
32 | static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | ||
33 | { | ||
34 | int err; | ||
35 | |||
36 | DE_INIT(("init_hw() - Darla20\n")); | ||
37 | snd_assert((subdevice_id & 0xfff0) == DARLA20, return -ENODEV); | ||
38 | |||
39 | if ((err = init_dsp_comm_page(chip))) { | ||
40 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | ||
41 | return err; | ||
42 | } | ||
43 | |||
44 | chip->device_id = device_id; | ||
45 | chip->subdevice_id = subdevice_id; | ||
46 | chip->bad_board = TRUE; | ||
47 | chip->dsp_code_to_load = &card_fw[FW_DARLA20_DSP]; | ||
48 | chip->spdif_status = GD_SPDIF_STATUS_UNDEF; | ||
49 | chip->clock_state = GD_CLOCK_UNDEF; | ||
50 | /* Since this card has no ASIC, mark it as loaded so everything | ||
51 | works OK */ | ||
52 | chip->asic_loaded = TRUE; | ||
53 | chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL; | ||
54 | |||
55 | if ((err = load_firmware(chip)) < 0) | ||
56 | return err; | ||
57 | chip->bad_board = FALSE; | ||
58 | |||
59 | if ((err = init_line_levels(chip)) < 0) | ||
60 | return err; | ||
61 | |||
62 | DE_INIT(("init_hw done\n")); | ||
63 | return err; | ||
64 | } | ||
65 | |||
66 | |||
67 | |||
68 | /* The Darla20 has no external clock sources */ | ||
69 | static u32 detect_input_clocks(const struct echoaudio *chip) | ||
70 | { | ||
71 | return ECHO_CLOCK_BIT_INTERNAL; | ||
72 | } | ||
73 | |||
74 | |||
75 | |||
76 | /* The Darla20 has no ASIC. Just do nothing */ | ||
77 | static int load_asic(struct echoaudio *chip) | ||
78 | { | ||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | |||
83 | |||
84 | static int set_sample_rate(struct echoaudio *chip, u32 rate) | ||
85 | { | ||
86 | u8 clock_state, spdif_status; | ||
87 | |||
88 | if (wait_handshake(chip)) | ||
89 | return -EIO; | ||
90 | |||
91 | switch (rate) { | ||
92 | case 44100: | ||
93 | clock_state = GD_CLOCK_44; | ||
94 | spdif_status = GD_SPDIF_STATUS_44; | ||
95 | break; | ||
96 | case 48000: | ||
97 | clock_state = GD_CLOCK_48; | ||
98 | spdif_status = GD_SPDIF_STATUS_48; | ||
99 | break; | ||
100 | default: | ||
101 | clock_state = GD_CLOCK_NOCHANGE; | ||
102 | spdif_status = GD_SPDIF_STATUS_NOCHANGE; | ||
103 | break; | ||
104 | } | ||
105 | |||
106 | if (chip->clock_state == clock_state) | ||
107 | clock_state = GD_CLOCK_NOCHANGE; | ||
108 | if (spdif_status == chip->spdif_status) | ||
109 | spdif_status = GD_SPDIF_STATUS_NOCHANGE; | ||
110 | |||
111 | chip->comm_page->sample_rate = cpu_to_le32(rate); | ||
112 | chip->comm_page->gd_clock_state = clock_state; | ||
113 | chip->comm_page->gd_spdif_status = spdif_status; | ||
114 | chip->comm_page->gd_resampler_state = 3; /* magic number - should always be 3 */ | ||
115 | |||
116 | /* Save the new audio state if it changed */ | ||
117 | if (clock_state != GD_CLOCK_NOCHANGE) | ||
118 | chip->clock_state = clock_state; | ||
119 | if (spdif_status != GD_SPDIF_STATUS_NOCHANGE) | ||
120 | chip->spdif_status = spdif_status; | ||
121 | chip->sample_rate = rate; | ||
122 | |||
123 | clear_handshake(chip); | ||
124 | return send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE); | ||
125 | } | ||
diff --git a/sound/pci/echoaudio/darla24.c b/sound/pci/echoaudio/darla24.c new file mode 100644 index 000000000000..e59a982ee361 --- /dev/null +++ b/sound/pci/echoaudio/darla24.c | |||
@@ -0,0 +1,106 @@ | |||
1 | /* | ||
2 | * ALSA driver for Echoaudio soundcards. | ||
3 | * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #define ECHOGALS_FAMILY | ||
20 | #define ECHOCARD_DARLA24 | ||
21 | #define ECHOCARD_NAME "Darla24" | ||
22 | #define ECHOCARD_HAS_MONITOR | ||
23 | #define ECHOCARD_HAS_INPUT_NOMINAL_LEVEL | ||
24 | #define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL | ||
25 | #define ECHOCARD_HAS_EXTERNAL_CLOCK | ||
26 | #define ECHOCARD_HAS_SUPER_INTERLEAVE | ||
27 | |||
28 | /* Pipe indexes */ | ||
29 | #define PX_ANALOG_OUT 0 /* 8 */ | ||
30 | #define PX_DIGITAL_OUT 8 /* 0 */ | ||
31 | #define PX_ANALOG_IN 8 /* 2 */ | ||
32 | #define PX_DIGITAL_IN 10 /* 0 */ | ||
33 | #define PX_NUM 10 | ||
34 | |||
35 | /* Bus indexes */ | ||
36 | #define BX_ANALOG_OUT 0 /* 8 */ | ||
37 | #define BX_DIGITAL_OUT 8 /* 0 */ | ||
38 | #define BX_ANALOG_IN 8 /* 2 */ | ||
39 | #define BX_DIGITAL_IN 10 /* 0 */ | ||
40 | #define BX_NUM 10 | ||
41 | |||
42 | |||
43 | #include <sound/driver.h> | ||
44 | #include <linux/delay.h> | ||
45 | #include <linux/init.h> | ||
46 | #include <linux/interrupt.h> | ||
47 | #include <linux/pci.h> | ||
48 | #include <linux/slab.h> | ||
49 | #include <linux/moduleparam.h> | ||
50 | #include <linux/firmware.h> | ||
51 | #include <sound/core.h> | ||
52 | #include <sound/info.h> | ||
53 | #include <sound/control.h> | ||
54 | #include <sound/pcm.h> | ||
55 | #include <sound/pcm_params.h> | ||
56 | #include <sound/asoundef.h> | ||
57 | #include <sound/initval.h> | ||
58 | #include <asm/io.h> | ||
59 | #include <asm/atomic.h> | ||
60 | #include "echoaudio.h" | ||
61 | |||
62 | #define FW_DARLA24_DSP 0 | ||
63 | |||
64 | static const struct firmware card_fw[] = { | ||
65 | {0, "darla24_dsp.fw"} | ||
66 | }; | ||
67 | |||
68 | static struct pci_device_id snd_echo_ids[] = { | ||
69 | {0x1057, 0x1801, 0xECC0, 0x0040, 0, 0, 0}, /* DSP 56301 Darla24 rev.0 */ | ||
70 | {0x1057, 0x1801, 0xECC0, 0x0041, 0, 0, 0}, /* DSP 56301 Darla24 rev.1 */ | ||
71 | {0,} | ||
72 | }; | ||
73 | |||
74 | static struct snd_pcm_hardware pcm_hardware_skel = { | ||
75 | .info = SNDRV_PCM_INFO_MMAP | | ||
76 | SNDRV_PCM_INFO_INTERLEAVED | | ||
77 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
78 | SNDRV_PCM_INFO_MMAP_VALID | | ||
79 | SNDRV_PCM_INFO_PAUSE | | ||
80 | SNDRV_PCM_INFO_SYNC_START, | ||
81 | .formats = SNDRV_PCM_FMTBIT_U8 | | ||
82 | SNDRV_PCM_FMTBIT_S16_LE | | ||
83 | SNDRV_PCM_FMTBIT_S24_3LE | | ||
84 | SNDRV_PCM_FMTBIT_S32_LE | | ||
85 | SNDRV_PCM_FMTBIT_S32_BE, | ||
86 | .rates = SNDRV_PCM_RATE_8000_48000 | | ||
87 | SNDRV_PCM_RATE_88200 | | ||
88 | SNDRV_PCM_RATE_96000, | ||
89 | .rate_min = 8000, | ||
90 | .rate_max = 96000, | ||
91 | .channels_min = 1, | ||
92 | .channels_max = 8, | ||
93 | .buffer_bytes_max = 262144, | ||
94 | .period_bytes_min = 32, | ||
95 | .period_bytes_max = 131072, | ||
96 | .periods_min = 2, | ||
97 | .periods_max = 220, | ||
98 | /* One page (4k) contains 512 instructions. I don't know if the hw | ||
99 | supports lists longer than this. In this case periods_max=220 is a | ||
100 | safe limit to make sure the list never exceeds 512 instructions. */ | ||
101 | }; | ||
102 | |||
103 | |||
104 | #include "darla24_dsp.c" | ||
105 | #include "echoaudio_dsp.c" | ||
106 | #include "echoaudio.c" | ||
diff --git a/sound/pci/echoaudio/darla24_dsp.c b/sound/pci/echoaudio/darla24_dsp.c new file mode 100644 index 000000000000..79938eed7e9c --- /dev/null +++ b/sound/pci/echoaudio/darla24_dsp.c | |||
@@ -0,0 +1,156 @@ | |||
1 | /*************************************************************************** | ||
2 | |||
3 | Copyright Echo Digital Audio Corporation (c) 1998 - 2004 | ||
4 | All rights reserved | ||
5 | www.echoaudio.com | ||
6 | |||
7 | This file is part of Echo Digital Audio's generic driver library. | ||
8 | |||
9 | Echo Digital Audio's generic driver library is free software; | ||
10 | you can redistribute it and/or modify it under the terms of | ||
11 | the GNU General Public License as published by the Free Software | ||
12 | Foundation. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, | ||
22 | MA 02111-1307, USA. | ||
23 | |||
24 | ************************************************************************* | ||
25 | |||
26 | Translation from C++ and adaptation for use in ALSA-Driver | ||
27 | were made by Giuliano Pochini <pochini@shiny.it> | ||
28 | |||
29 | ****************************************************************************/ | ||
30 | |||
31 | |||
32 | static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | ||
33 | { | ||
34 | int err; | ||
35 | |||
36 | DE_INIT(("init_hw() - Darla24\n")); | ||
37 | snd_assert((subdevice_id & 0xfff0) == DARLA24, return -ENODEV); | ||
38 | |||
39 | if ((err = init_dsp_comm_page(chip))) { | ||
40 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | ||
41 | return err; | ||
42 | } | ||
43 | |||
44 | chip->device_id = device_id; | ||
45 | chip->subdevice_id = subdevice_id; | ||
46 | chip->bad_board = TRUE; | ||
47 | chip->dsp_code_to_load = &card_fw[FW_DARLA24_DSP]; | ||
48 | /* Since this card has no ASIC, mark it as loaded so everything | ||
49 | works OK */ | ||
50 | chip->asic_loaded = TRUE; | ||
51 | chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL | | ||
52 | ECHO_CLOCK_BIT_ESYNC; | ||
53 | |||
54 | if ((err = load_firmware(chip)) < 0) | ||
55 | return err; | ||
56 | chip->bad_board = FALSE; | ||
57 | |||
58 | if ((err = init_line_levels(chip)) < 0) | ||
59 | return err; | ||
60 | |||
61 | DE_INIT(("init_hw done\n")); | ||
62 | return err; | ||
63 | } | ||
64 | |||
65 | |||
66 | |||
67 | static u32 detect_input_clocks(const struct echoaudio *chip) | ||
68 | { | ||
69 | u32 clocks_from_dsp, clock_bits; | ||
70 | |||
71 | /* Map the DSP clock detect bits to the generic driver clock | ||
72 | detect bits */ | ||
73 | clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); | ||
74 | |||
75 | clock_bits = ECHO_CLOCK_BIT_INTERNAL; | ||
76 | |||
77 | if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_ESYNC) | ||
78 | clock_bits |= ECHO_CLOCK_BIT_ESYNC; | ||
79 | |||
80 | return clock_bits; | ||
81 | } | ||
82 | |||
83 | |||
84 | |||
85 | /* The Darla24 has no ASIC. Just do nothing */ | ||
86 | static int load_asic(struct echoaudio *chip) | ||
87 | { | ||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | |||
92 | |||
93 | static int set_sample_rate(struct echoaudio *chip, u32 rate) | ||
94 | { | ||
95 | u8 clock; | ||
96 | |||
97 | switch (rate) { | ||
98 | case 96000: | ||
99 | clock = GD24_96000; | ||
100 | break; | ||
101 | case 88200: | ||
102 | clock = GD24_88200; | ||
103 | break; | ||
104 | case 48000: | ||
105 | clock = GD24_48000; | ||
106 | break; | ||
107 | case 44100: | ||
108 | clock = GD24_44100; | ||
109 | break; | ||
110 | case 32000: | ||
111 | clock = GD24_32000; | ||
112 | break; | ||
113 | case 22050: | ||
114 | clock = GD24_22050; | ||
115 | break; | ||
116 | case 16000: | ||
117 | clock = GD24_16000; | ||
118 | break; | ||
119 | case 11025: | ||
120 | clock = GD24_11025; | ||
121 | break; | ||
122 | case 8000: | ||
123 | clock = GD24_8000; | ||
124 | break; | ||
125 | default: | ||
126 | DE_ACT(("set_sample_rate: Error, invalid sample rate %d\n", | ||
127 | rate)); | ||
128 | return -EINVAL; | ||
129 | } | ||
130 | |||
131 | if (wait_handshake(chip)) | ||
132 | return -EIO; | ||
133 | |||
134 | DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock)); | ||
135 | chip->sample_rate = rate; | ||
136 | |||
137 | /* Override the sample rate if this card is set to Echo sync. */ | ||
138 | if (chip->input_clock == ECHO_CLOCK_ESYNC) | ||
139 | clock = GD24_EXT_SYNC; | ||
140 | |||
141 | chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP ? */ | ||
142 | chip->comm_page->gd_clock_state = clock; | ||
143 | clear_handshake(chip); | ||
144 | return send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE); | ||
145 | } | ||
146 | |||
147 | |||
148 | |||
149 | static int set_input_clock(struct echoaudio *chip, u16 clock) | ||
150 | { | ||
151 | snd_assert(clock == ECHO_CLOCK_INTERNAL || | ||
152 | clock == ECHO_CLOCK_ESYNC, return -EINVAL); | ||
153 | chip->input_clock = clock; | ||
154 | return set_sample_rate(chip, chip->sample_rate); | ||
155 | } | ||
156 | |||
diff --git a/sound/pci/echoaudio/echo3g.c b/sound/pci/echoaudio/echo3g.c new file mode 100644 index 000000000000..12099fe1547d --- /dev/null +++ b/sound/pci/echoaudio/echo3g.c | |||
@@ -0,0 +1,118 @@ | |||
1 | /* | ||
2 | * ALSA driver for Echoaudio soundcards. | ||
3 | * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #define ECHO3G_FAMILY | ||
20 | #define ECHOCARD_ECHO3G | ||
21 | #define ECHOCARD_NAME "Echo3G" | ||
22 | #define ECHOCARD_HAS_MONITOR | ||
23 | #define ECHOCARD_HAS_ASIC | ||
24 | #define ECHOCARD_HAS_INPUT_NOMINAL_LEVEL | ||
25 | #define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL | ||
26 | #define ECHOCARD_HAS_SUPER_INTERLEAVE | ||
27 | #define ECHOCARD_HAS_DIGITAL_IO | ||
28 | #define ECHOCARD_HAS_DIGITAL_MODE_SWITCH | ||
29 | #define ECHOCARD_HAS_ADAT 6 | ||
30 | #define ECHOCARD_HAS_EXTERNAL_CLOCK | ||
31 | #define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 | ||
32 | #define ECHOCARD_HAS_MIDI | ||
33 | #define ECHOCARD_HAS_PHANTOM_POWER | ||
34 | |||
35 | /* Pipe indexes */ | ||
36 | #define PX_ANALOG_OUT 0 | ||
37 | #define PX_DIGITAL_OUT chip->px_digital_out | ||
38 | #define PX_ANALOG_IN chip->px_analog_in | ||
39 | #define PX_DIGITAL_IN chip->px_digital_in | ||
40 | #define PX_NUM chip->px_num | ||
41 | |||
42 | /* Bus indexes */ | ||
43 | #define BX_ANALOG_OUT 0 | ||
44 | #define BX_DIGITAL_OUT chip->bx_digital_out | ||
45 | #define BX_ANALOG_IN chip->bx_analog_in | ||
46 | #define BX_DIGITAL_IN chip->bx_digital_in | ||
47 | #define BX_NUM chip->bx_num | ||
48 | |||
49 | |||
50 | #include <sound/driver.h> | ||
51 | #include <linux/delay.h> | ||
52 | #include <linux/init.h> | ||
53 | #include <linux/interrupt.h> | ||
54 | #include <linux/pci.h> | ||
55 | #include <linux/slab.h> | ||
56 | #include <linux/moduleparam.h> | ||
57 | #include <linux/firmware.h> | ||
58 | #include <sound/core.h> | ||
59 | #include <sound/info.h> | ||
60 | #include <sound/control.h> | ||
61 | #include <sound/pcm.h> | ||
62 | #include <sound/pcm_params.h> | ||
63 | #include <sound/asoundef.h> | ||
64 | #include <sound/initval.h> | ||
65 | #include <sound/rawmidi.h> | ||
66 | #include <asm/io.h> | ||
67 | #include <asm/atomic.h> | ||
68 | #include "echoaudio.h" | ||
69 | |||
70 | #define FW_361_LOADER 0 | ||
71 | #define FW_ECHO3G_DSP 1 | ||
72 | #define FW_3G_ASIC 2 | ||
73 | |||
74 | static const struct firmware card_fw[] = { | ||
75 | {0, "loader_dsp.fw"}, | ||
76 | {0, "echo3g_dsp.fw"}, | ||
77 | {0, "3g_asic.fw"} | ||
78 | }; | ||
79 | |||
80 | static struct pci_device_id snd_echo_ids[] = { | ||
81 | {0x1057, 0x3410, 0xECC0, 0x0100, 0, 0, 0}, /* Echo 3G */ | ||
82 | {0,} | ||
83 | }; | ||
84 | |||
85 | static struct snd_pcm_hardware pcm_hardware_skel = { | ||
86 | .info = SNDRV_PCM_INFO_MMAP | | ||
87 | SNDRV_PCM_INFO_INTERLEAVED | | ||
88 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
89 | SNDRV_PCM_INFO_MMAP_VALID | | ||
90 | SNDRV_PCM_INFO_PAUSE | | ||
91 | SNDRV_PCM_INFO_SYNC_START, | ||
92 | .formats = SNDRV_PCM_FMTBIT_U8 | | ||
93 | SNDRV_PCM_FMTBIT_S16_LE | | ||
94 | SNDRV_PCM_FMTBIT_S24_3LE | | ||
95 | SNDRV_PCM_FMTBIT_S32_LE | | ||
96 | SNDRV_PCM_FMTBIT_S32_BE, | ||
97 | .rates = SNDRV_PCM_RATE_32000 | | ||
98 | SNDRV_PCM_RATE_44100 | | ||
99 | SNDRV_PCM_RATE_48000 | | ||
100 | SNDRV_PCM_RATE_88200 | | ||
101 | SNDRV_PCM_RATE_96000 | | ||
102 | SNDRV_PCM_RATE_CONTINUOUS, | ||
103 | .rate_min = 32000, | ||
104 | .rate_max = 100000, | ||
105 | .channels_min = 1, | ||
106 | .channels_max = 8, | ||
107 | .buffer_bytes_max = 262144, | ||
108 | .period_bytes_min = 32, | ||
109 | .period_bytes_max = 131072, | ||
110 | .periods_min = 2, | ||
111 | .periods_max = 220, | ||
112 | }; | ||
113 | |||
114 | #include "echo3g_dsp.c" | ||
115 | #include "echoaudio_dsp.c" | ||
116 | #include "echoaudio_3g.c" | ||
117 | #include "echoaudio.c" | ||
118 | #include "midi.c" | ||
diff --git a/sound/pci/echoaudio/echo3g_dsp.c b/sound/pci/echoaudio/echo3g_dsp.c new file mode 100644 index 000000000000..d26a1d1f3ed1 --- /dev/null +++ b/sound/pci/echoaudio/echo3g_dsp.c | |||
@@ -0,0 +1,131 @@ | |||
1 | /**************************************************************************** | ||
2 | |||
3 | Copyright Echo Digital Audio Corporation (c) 1998 - 2004 | ||
4 | All rights reserved | ||
5 | www.echoaudio.com | ||
6 | |||
7 | This file is part of Echo Digital Audio's generic driver library. | ||
8 | |||
9 | Echo Digital Audio's generic driver library is free software; | ||
10 | you can redistribute it and/or modify it under the terms of | ||
11 | the GNU General Public License as published by the Free Software | ||
12 | Foundation. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, | ||
22 | MA 02111-1307, USA. | ||
23 | |||
24 | ************************************************************************* | ||
25 | |||
26 | Translation from C++ and adaptation for use in ALSA-Driver | ||
27 | were made by Giuliano Pochini <pochini@shiny.it> | ||
28 | |||
29 | ****************************************************************************/ | ||
30 | |||
31 | static int load_asic(struct echoaudio *chip); | ||
32 | static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode); | ||
33 | static int set_digital_mode(struct echoaudio *chip, u8 mode); | ||
34 | static int check_asic_status(struct echoaudio *chip); | ||
35 | static int set_sample_rate(struct echoaudio *chip, u32 rate); | ||
36 | static int set_input_clock(struct echoaudio *chip, u16 clock); | ||
37 | static int set_professional_spdif(struct echoaudio *chip, char prof); | ||
38 | static int set_phantom_power(struct echoaudio *chip, char on); | ||
39 | static int write_control_reg(struct echoaudio *chip, u32 ctl, u32 frq, | ||
40 | char force); | ||
41 | |||
42 | #include <linux/irq.h> | ||
43 | |||
44 | static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | ||
45 | { | ||
46 | int err; | ||
47 | |||
48 | local_irq_enable(); | ||
49 | DE_INIT(("init_hw() - Echo3G\n")); | ||
50 | snd_assert((subdevice_id & 0xfff0) == ECHO3G, return -ENODEV); | ||
51 | |||
52 | if ((err = init_dsp_comm_page(chip))) { | ||
53 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | ||
54 | return err; | ||
55 | } | ||
56 | |||
57 | chip->comm_page->e3g_frq_register = | ||
58 | __constant_cpu_to_le32((E3G_MAGIC_NUMBER / 48000) - 2); | ||
59 | chip->device_id = device_id; | ||
60 | chip->subdevice_id = subdevice_id; | ||
61 | chip->bad_board = TRUE; | ||
62 | chip->has_midi = TRUE; | ||
63 | chip->dsp_code_to_load = &card_fw[FW_ECHO3G_DSP]; | ||
64 | |||
65 | /* Load the DSP code and the ASIC on the PCI card and get | ||
66 | what type of external box is attached */ | ||
67 | err = load_firmware(chip); | ||
68 | |||
69 | if (err < 0) { | ||
70 | return err; | ||
71 | } else if (err == E3G_GINA3G_BOX_TYPE) { | ||
72 | chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL | | ||
73 | ECHO_CLOCK_BIT_SPDIF | | ||
74 | ECHO_CLOCK_BIT_ADAT; | ||
75 | chip->card_name = "Gina3G"; | ||
76 | chip->px_digital_out = chip->bx_digital_out = 6; | ||
77 | chip->px_analog_in = chip->bx_analog_in = 14; | ||
78 | chip->px_digital_in = chip->bx_digital_in = 16; | ||
79 | chip->px_num = chip->bx_num = 24; | ||
80 | chip->has_phantom_power = TRUE; | ||
81 | chip->hasnt_input_nominal_level = TRUE; | ||
82 | } else if (err == E3G_LAYLA3G_BOX_TYPE) { | ||
83 | chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL | | ||
84 | ECHO_CLOCK_BIT_SPDIF | | ||
85 | ECHO_CLOCK_BIT_ADAT | | ||
86 | ECHO_CLOCK_BIT_WORD; | ||
87 | chip->card_name = "Layla3G"; | ||
88 | chip->px_digital_out = chip->bx_digital_out = 8; | ||
89 | chip->px_analog_in = chip->bx_analog_in = 16; | ||
90 | chip->px_digital_in = chip->bx_digital_in = 24; | ||
91 | chip->px_num = chip->bx_num = 32; | ||
92 | } else { | ||
93 | return -ENODEV; | ||
94 | } | ||
95 | |||
96 | chip->digital_modes = ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | | ||
97 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | | ||
98 | ECHOCAPS_HAS_DIGITAL_MODE_ADAT; | ||
99 | chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; | ||
100 | chip->professional_spdif = FALSE; | ||
101 | chip->non_audio_spdif = FALSE; | ||
102 | chip->bad_board = FALSE; | ||
103 | |||
104 | if ((err = init_line_levels(chip)) < 0) | ||
105 | return err; | ||
106 | err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA); | ||
107 | snd_assert(err >= 0, return err); | ||
108 | err = set_phantom_power(chip, 0); | ||
109 | snd_assert(err >= 0, return err); | ||
110 | err = set_professional_spdif(chip, TRUE); | ||
111 | |||
112 | DE_INIT(("init_hw done\n")); | ||
113 | return err; | ||
114 | } | ||
115 | |||
116 | |||
117 | |||
118 | static int set_phantom_power(struct echoaudio *chip, char on) | ||
119 | { | ||
120 | u32 control_reg = le32_to_cpu(chip->comm_page->control_register); | ||
121 | |||
122 | if (on) | ||
123 | control_reg |= E3G_PHANTOM_POWER; | ||
124 | else | ||
125 | control_reg &= ~E3G_PHANTOM_POWER; | ||
126 | |||
127 | chip->phantom_power = on; | ||
128 | return write_control_reg(chip, control_reg, | ||
129 | le32_to_cpu(chip->comm_page->e3g_frq_register), | ||
130 | 0); | ||
131 | } | ||
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c new file mode 100644 index 000000000000..43b408ada1da --- /dev/null +++ b/sound/pci/echoaudio/echoaudio.c | |||
@@ -0,0 +1,2196 @@ | |||
1 | /* | ||
2 | * ALSA driver for Echoaudio soundcards. | ||
3 | * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | MODULE_AUTHOR("Giuliano Pochini <pochini@shiny.it>"); | ||
20 | MODULE_LICENSE("GPL v2"); | ||
21 | MODULE_DESCRIPTION("Echoaudio " ECHOCARD_NAME " soundcards driver"); | ||
22 | MODULE_SUPPORTED_DEVICE("{{Echoaudio," ECHOCARD_NAME "}}"); | ||
23 | MODULE_DEVICE_TABLE(pci, snd_echo_ids); | ||
24 | |||
25 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; | ||
26 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; | ||
27 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; | ||
28 | |||
29 | module_param_array(index, int, NULL, 0444); | ||
30 | MODULE_PARM_DESC(index, "Index value for " ECHOCARD_NAME " soundcard."); | ||
31 | module_param_array(id, charp, NULL, 0444); | ||
32 | MODULE_PARM_DESC(id, "ID string for " ECHOCARD_NAME " soundcard."); | ||
33 | module_param_array(enable, bool, NULL, 0444); | ||
34 | MODULE_PARM_DESC(enable, "Enable " ECHOCARD_NAME " soundcard."); | ||
35 | |||
36 | static unsigned int channels_list[10] = {1, 2, 4, 6, 8, 10, 12, 14, 16, 999999}; | ||
37 | |||
38 | static int get_firmware(const struct firmware **fw_entry, | ||
39 | const struct firmware *frm, struct echoaudio *chip) | ||
40 | { | ||
41 | int err; | ||
42 | char name[30]; | ||
43 | DE_ACT(("firmware requested: %s\n", frm->data)); | ||
44 | snprintf(name, sizeof(name), "ea/%s", frm->data); | ||
45 | if ((err = request_firmware(fw_entry, name, pci_device(chip))) < 0) | ||
46 | snd_printk(KERN_ERR "get_firmware(): Firmware not available (%d)\n", err); | ||
47 | return err; | ||
48 | } | ||
49 | |||
50 | static void free_firmware(const struct firmware *fw_entry) | ||
51 | { | ||
52 | release_firmware(fw_entry); | ||
53 | DE_ACT(("firmware released\n")); | ||
54 | } | ||
55 | |||
56 | |||
57 | |||
58 | /****************************************************************************** | ||
59 | PCM interface | ||
60 | ******************************************************************************/ | ||
61 | |||
62 | static void audiopipe_free(struct snd_pcm_runtime *runtime) | ||
63 | { | ||
64 | struct audiopipe *pipe = runtime->private_data; | ||
65 | |||
66 | if (pipe->sgpage.area) | ||
67 | snd_dma_free_pages(&pipe->sgpage); | ||
68 | kfree(pipe); | ||
69 | } | ||
70 | |||
71 | |||
72 | |||
73 | static int hw_rule_capture_format_by_channels(struct snd_pcm_hw_params *params, | ||
74 | struct snd_pcm_hw_rule *rule) | ||
75 | { | ||
76 | struct snd_interval *c = hw_param_interval(params, | ||
77 | SNDRV_PCM_HW_PARAM_CHANNELS); | ||
78 | struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); | ||
79 | struct snd_mask fmt; | ||
80 | |||
81 | snd_mask_any(&fmt); | ||
82 | |||
83 | #ifndef ECHOCARD_HAS_STEREO_BIG_ENDIAN32 | ||
84 | /* >=2 channels cannot be S32_BE */ | ||
85 | if (c->min == 2) { | ||
86 | fmt.bits[0] &= ~SNDRV_PCM_FMTBIT_S32_BE; | ||
87 | return snd_mask_refine(f, &fmt); | ||
88 | } | ||
89 | #endif | ||
90 | /* > 2 channels cannot be U8 and S32_BE */ | ||
91 | if (c->min > 2) { | ||
92 | fmt.bits[0] &= ~(SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_BE); | ||
93 | return snd_mask_refine(f, &fmt); | ||
94 | } | ||
95 | /* Mono is ok with any format */ | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | |||
100 | |||
101 | static int hw_rule_capture_channels_by_format(struct snd_pcm_hw_params *params, | ||
102 | struct snd_pcm_hw_rule *rule) | ||
103 | { | ||
104 | struct snd_interval *c = hw_param_interval(params, | ||
105 | SNDRV_PCM_HW_PARAM_CHANNELS); | ||
106 | struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); | ||
107 | struct snd_interval ch; | ||
108 | |||
109 | snd_interval_any(&ch); | ||
110 | |||
111 | /* S32_BE is mono (and stereo) only */ | ||
112 | if (f->bits[0] == SNDRV_PCM_FMTBIT_S32_BE) { | ||
113 | ch.min = 1; | ||
114 | #ifdef ECHOCARD_HAS_STEREO_BIG_ENDIAN32 | ||
115 | ch.max = 2; | ||
116 | #else | ||
117 | ch.max = 1; | ||
118 | #endif | ||
119 | ch.integer = 1; | ||
120 | return snd_interval_refine(c, &ch); | ||
121 | } | ||
122 | /* U8 can be only mono or stereo */ | ||
123 | if (f->bits[0] == SNDRV_PCM_FMTBIT_U8) { | ||
124 | ch.min = 1; | ||
125 | ch.max = 2; | ||
126 | ch.integer = 1; | ||
127 | return snd_interval_refine(c, &ch); | ||
128 | } | ||
129 | /* S16_LE, S24_3LE and S32_LE support any number of channels. */ | ||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | |||
134 | |||
135 | static int hw_rule_playback_format_by_channels(struct snd_pcm_hw_params *params, | ||
136 | struct snd_pcm_hw_rule *rule) | ||
137 | { | ||
138 | struct snd_interval *c = hw_param_interval(params, | ||
139 | SNDRV_PCM_HW_PARAM_CHANNELS); | ||
140 | struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); | ||
141 | struct snd_mask fmt; | ||
142 | u64 fmask; | ||
143 | snd_mask_any(&fmt); | ||
144 | |||
145 | fmask = fmt.bits[0] + ((u64)fmt.bits[1] << 32); | ||
146 | |||
147 | /* >2 channels must be S16_LE, S24_3LE or S32_LE */ | ||
148 | if (c->min > 2) { | ||
149 | fmask &= SNDRV_PCM_FMTBIT_S16_LE | | ||
150 | SNDRV_PCM_FMTBIT_S24_3LE | | ||
151 | SNDRV_PCM_FMTBIT_S32_LE; | ||
152 | /* 1 channel must be S32_BE or S32_LE */ | ||
153 | } else if (c->max == 1) | ||
154 | fmask &= SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE; | ||
155 | #ifndef ECHOCARD_HAS_STEREO_BIG_ENDIAN32 | ||
156 | /* 2 channels cannot be S32_BE */ | ||
157 | else if (c->min == 2 && c->max == 2) | ||
158 | fmask &= ~SNDRV_PCM_FMTBIT_S32_BE; | ||
159 | #endif | ||
160 | else | ||
161 | return 0; | ||
162 | |||
163 | fmt.bits[0] &= (u32)fmask; | ||
164 | fmt.bits[1] &= (u32)(fmask >> 32); | ||
165 | return snd_mask_refine(f, &fmt); | ||
166 | } | ||
167 | |||
168 | |||
169 | |||
170 | static int hw_rule_playback_channels_by_format(struct snd_pcm_hw_params *params, | ||
171 | struct snd_pcm_hw_rule *rule) | ||
172 | { | ||
173 | struct snd_interval *c = hw_param_interval(params, | ||
174 | SNDRV_PCM_HW_PARAM_CHANNELS); | ||
175 | struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); | ||
176 | struct snd_interval ch; | ||
177 | u64 fmask; | ||
178 | |||
179 | snd_interval_any(&ch); | ||
180 | ch.integer = 1; | ||
181 | fmask = f->bits[0] + ((u64)f->bits[1] << 32); | ||
182 | |||
183 | /* S32_BE is mono (and stereo) only */ | ||
184 | if (fmask == SNDRV_PCM_FMTBIT_S32_BE) { | ||
185 | ch.min = 1; | ||
186 | #ifdef ECHOCARD_HAS_STEREO_BIG_ENDIAN32 | ||
187 | ch.max = 2; | ||
188 | #else | ||
189 | ch.max = 1; | ||
190 | #endif | ||
191 | /* U8 is stereo only */ | ||
192 | } else if (fmask == SNDRV_PCM_FMTBIT_U8) | ||
193 | ch.min = ch.max = 2; | ||
194 | /* S16_LE and S24_3LE must be at least stereo */ | ||
195 | else if (!(fmask & ~(SNDRV_PCM_FMTBIT_S16_LE | | ||
196 | SNDRV_PCM_FMTBIT_S24_3LE))) | ||
197 | ch.min = 2; | ||
198 | else | ||
199 | return 0; | ||
200 | |||
201 | return snd_interval_refine(c, &ch); | ||
202 | } | ||
203 | |||
204 | |||
205 | |||
206 | /* Since the sample rate is a global setting, do allow the user to change the | ||
207 | sample rate only if there is only one pcm device open. */ | ||
208 | static int hw_rule_sample_rate(struct snd_pcm_hw_params *params, | ||
209 | struct snd_pcm_hw_rule *rule) | ||
210 | { | ||
211 | struct snd_interval *rate = hw_param_interval(params, | ||
212 | SNDRV_PCM_HW_PARAM_RATE); | ||
213 | struct echoaudio *chip = rule->private; | ||
214 | struct snd_interval fixed; | ||
215 | |||
216 | if (!chip->can_set_rate) { | ||
217 | snd_interval_any(&fixed); | ||
218 | fixed.min = fixed.max = chip->sample_rate; | ||
219 | return snd_interval_refine(rate, &fixed); | ||
220 | } | ||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | |||
225 | static int pcm_open(struct snd_pcm_substream *substream, | ||
226 | signed char max_channels) | ||
227 | { | ||
228 | struct echoaudio *chip; | ||
229 | struct snd_pcm_runtime *runtime; | ||
230 | struct audiopipe *pipe; | ||
231 | int err, i; | ||
232 | |||
233 | if (max_channels <= 0) | ||
234 | return -EAGAIN; | ||
235 | |||
236 | chip = snd_pcm_substream_chip(substream); | ||
237 | runtime = substream->runtime; | ||
238 | |||
239 | if (!(pipe = kmalloc(sizeof(struct audiopipe), GFP_KERNEL))) | ||
240 | return -ENOMEM; | ||
241 | memset(pipe, 0, sizeof(struct audiopipe)); | ||
242 | pipe->index = -1; /* Not configured yet */ | ||
243 | |||
244 | /* Set up hw capabilities and contraints */ | ||
245 | memcpy(&pipe->hw, &pcm_hardware_skel, sizeof(struct snd_pcm_hardware)); | ||
246 | DE_HWP(("max_channels=%d\n", max_channels)); | ||
247 | pipe->constr.list = channels_list; | ||
248 | pipe->constr.mask = 0; | ||
249 | for (i = 0; channels_list[i] <= max_channels; i++); | ||
250 | pipe->constr.count = i; | ||
251 | if (pipe->hw.channels_max > max_channels) | ||
252 | pipe->hw.channels_max = max_channels; | ||
253 | if (chip->digital_mode == DIGITAL_MODE_ADAT) { | ||
254 | pipe->hw.rate_max = 48000; | ||
255 | pipe->hw.rates &= SNDRV_PCM_RATE_8000_48000; | ||
256 | } | ||
257 | |||
258 | runtime->hw = pipe->hw; | ||
259 | runtime->private_data = pipe; | ||
260 | runtime->private_free = audiopipe_free; | ||
261 | snd_pcm_set_sync(substream); | ||
262 | |||
263 | /* Only mono and any even number of channels are allowed */ | ||
264 | if ((err = snd_pcm_hw_constraint_list(runtime, 0, | ||
265 | SNDRV_PCM_HW_PARAM_CHANNELS, | ||
266 | &pipe->constr)) < 0) | ||
267 | return err; | ||
268 | |||
269 | /* All periods should have the same size */ | ||
270 | if ((err = snd_pcm_hw_constraint_integer(runtime, | ||
271 | SNDRV_PCM_HW_PARAM_PERIODS)) < 0) | ||
272 | return err; | ||
273 | |||
274 | /* The hw accesses memory in chunks 32 frames long and they should be | ||
275 | 32-bytes-aligned. It's not a requirement, but it seems that IRQs are | ||
276 | generated with a resolution of 32 frames. Thus we need the following */ | ||
277 | if ((err = snd_pcm_hw_constraint_step(runtime, 0, | ||
278 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, | ||
279 | 32)) < 0) | ||
280 | return err; | ||
281 | if ((err = snd_pcm_hw_constraint_step(runtime, 0, | ||
282 | SNDRV_PCM_HW_PARAM_BUFFER_SIZE, | ||
283 | 32)) < 0) | ||
284 | return err; | ||
285 | |||
286 | if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, | ||
287 | SNDRV_PCM_HW_PARAM_RATE, | ||
288 | hw_rule_sample_rate, chip, | ||
289 | SNDRV_PCM_HW_PARAM_RATE, -1)) < 0) | ||
290 | return err; | ||
291 | |||
292 | /* Finally allocate a page for the scatter-gather list */ | ||
293 | if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, | ||
294 | snd_dma_pci_data(chip->pci), | ||
295 | PAGE_SIZE, &pipe->sgpage)) < 0) { | ||
296 | DE_HWP(("s-g list allocation failed\n")); | ||
297 | return err; | ||
298 | } | ||
299 | |||
300 | return 0; | ||
301 | } | ||
302 | |||
303 | |||
304 | |||
305 | static int pcm_analog_in_open(struct snd_pcm_substream *substream) | ||
306 | { | ||
307 | struct echoaudio *chip = snd_pcm_substream_chip(substream); | ||
308 | int err; | ||
309 | |||
310 | DE_ACT(("pcm_analog_in_open\n")); | ||
311 | if ((err = pcm_open(substream, num_analog_busses_in(chip) - | ||
312 | substream->number)) < 0) | ||
313 | return err; | ||
314 | if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, | ||
315 | SNDRV_PCM_HW_PARAM_CHANNELS, | ||
316 | hw_rule_capture_channels_by_format, NULL, | ||
317 | SNDRV_PCM_HW_PARAM_FORMAT, -1)) < 0) | ||
318 | return err; | ||
319 | if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, | ||
320 | SNDRV_PCM_HW_PARAM_FORMAT, | ||
321 | hw_rule_capture_format_by_channels, NULL, | ||
322 | SNDRV_PCM_HW_PARAM_CHANNELS, -1)) < 0) | ||
323 | return err; | ||
324 | atomic_inc(&chip->opencount); | ||
325 | if (atomic_read(&chip->opencount) > 1 && chip->rate_set) | ||
326 | chip->can_set_rate=0; | ||
327 | DE_HWP(("pcm_analog_in_open cs=%d oc=%d r=%d\n", | ||
328 | chip->can_set_rate, atomic_read(&chip->opencount), | ||
329 | chip->sample_rate)); | ||
330 | return 0; | ||
331 | } | ||
332 | |||
333 | |||
334 | |||
335 | static int pcm_analog_out_open(struct snd_pcm_substream *substream) | ||
336 | { | ||
337 | struct echoaudio *chip = snd_pcm_substream_chip(substream); | ||
338 | int max_channels, err; | ||
339 | |||
340 | #ifdef ECHOCARD_HAS_VMIXER | ||
341 | max_channels = num_pipes_out(chip); | ||
342 | #else | ||
343 | max_channels = num_analog_busses_out(chip); | ||
344 | #endif | ||
345 | DE_ACT(("pcm_analog_out_open\n")); | ||
346 | if ((err = pcm_open(substream, max_channels - substream->number)) < 0) | ||
347 | return err; | ||
348 | if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, | ||
349 | SNDRV_PCM_HW_PARAM_CHANNELS, | ||
350 | hw_rule_playback_channels_by_format, | ||
351 | NULL, | ||
352 | SNDRV_PCM_HW_PARAM_FORMAT, -1)) < 0) | ||
353 | return err; | ||
354 | if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, | ||
355 | SNDRV_PCM_HW_PARAM_FORMAT, | ||
356 | hw_rule_playback_format_by_channels, | ||
357 | NULL, | ||
358 | SNDRV_PCM_HW_PARAM_CHANNELS, -1)) < 0) | ||
359 | return err; | ||
360 | atomic_inc(&chip->opencount); | ||
361 | if (atomic_read(&chip->opencount) > 1 && chip->rate_set) | ||
362 | chip->can_set_rate=0; | ||
363 | DE_HWP(("pcm_analog_out_open cs=%d oc=%d r=%d\n", | ||
364 | chip->can_set_rate, atomic_read(&chip->opencount), | ||
365 | chip->sample_rate)); | ||
366 | return 0; | ||
367 | } | ||
368 | |||
369 | |||
370 | |||
371 | #ifdef ECHOCARD_HAS_DIGITAL_IO | ||
372 | |||
373 | static int pcm_digital_in_open(struct snd_pcm_substream *substream) | ||
374 | { | ||
375 | struct echoaudio *chip = snd_pcm_substream_chip(substream); | ||
376 | int err, max_channels; | ||
377 | |||
378 | DE_ACT(("pcm_digital_in_open\n")); | ||
379 | max_channels = num_digital_busses_in(chip) - substream->number; | ||
380 | down(&chip->mode_mutex); | ||
381 | if (chip->digital_mode == DIGITAL_MODE_ADAT) | ||
382 | err = pcm_open(substream, max_channels); | ||
383 | else /* If the card has ADAT, subtract the 6 channels | ||
384 | * that S/PDIF doesn't have | ||
385 | */ | ||
386 | err = pcm_open(substream, max_channels - ECHOCARD_HAS_ADAT); | ||
387 | |||
388 | if (err < 0) | ||
389 | goto din_exit; | ||
390 | |||
391 | if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, | ||
392 | SNDRV_PCM_HW_PARAM_CHANNELS, | ||
393 | hw_rule_capture_channels_by_format, NULL, | ||
394 | SNDRV_PCM_HW_PARAM_FORMAT, -1)) < 0) | ||
395 | goto din_exit; | ||
396 | if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, | ||
397 | SNDRV_PCM_HW_PARAM_FORMAT, | ||
398 | hw_rule_capture_format_by_channels, NULL, | ||
399 | SNDRV_PCM_HW_PARAM_CHANNELS, -1)) < 0) | ||
400 | goto din_exit; | ||
401 | |||
402 | atomic_inc(&chip->opencount); | ||
403 | if (atomic_read(&chip->opencount) > 1 && chip->rate_set) | ||
404 | chip->can_set_rate=0; | ||
405 | |||
406 | din_exit: | ||
407 | up(&chip->mode_mutex); | ||
408 | return err; | ||
409 | } | ||
410 | |||
411 | |||
412 | |||
413 | #ifndef ECHOCARD_HAS_VMIXER /* See the note in snd_echo_new_pcm() */ | ||
414 | |||
415 | static int pcm_digital_out_open(struct snd_pcm_substream *substream) | ||
416 | { | ||
417 | struct echoaudio *chip = snd_pcm_substream_chip(substream); | ||
418 | int err, max_channels; | ||
419 | |||
420 | DE_ACT(("pcm_digital_out_open\n")); | ||
421 | max_channels = num_digital_busses_out(chip) - substream->number; | ||
422 | down(&chip->mode_mutex); | ||
423 | if (chip->digital_mode == DIGITAL_MODE_ADAT) | ||
424 | err = pcm_open(substream, max_channels); | ||
425 | else /* If the card has ADAT, subtract the 6 channels | ||
426 | * that S/PDIF doesn't have | ||
427 | */ | ||
428 | err = pcm_open(substream, max_channels - ECHOCARD_HAS_ADAT); | ||
429 | |||
430 | if (err < 0) | ||
431 | goto dout_exit; | ||
432 | |||
433 | if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, | ||
434 | SNDRV_PCM_HW_PARAM_CHANNELS, | ||
435 | hw_rule_playback_channels_by_format, | ||
436 | NULL, SNDRV_PCM_HW_PARAM_FORMAT, | ||
437 | -1)) < 0) | ||
438 | goto dout_exit; | ||
439 | if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, | ||
440 | SNDRV_PCM_HW_PARAM_FORMAT, | ||
441 | hw_rule_playback_format_by_channels, | ||
442 | NULL, SNDRV_PCM_HW_PARAM_CHANNELS, | ||
443 | -1)) < 0) | ||
444 | goto dout_exit; | ||
445 | atomic_inc(&chip->opencount); | ||
446 | if (atomic_read(&chip->opencount) > 1 && chip->rate_set) | ||
447 | chip->can_set_rate=0; | ||
448 | dout_exit: | ||
449 | up(&chip->mode_mutex); | ||
450 | return err; | ||
451 | } | ||
452 | |||
453 | #endif /* !ECHOCARD_HAS_VMIXER */ | ||
454 | |||
455 | #endif /* ECHOCARD_HAS_DIGITAL_IO */ | ||
456 | |||
457 | |||
458 | |||
459 | static int pcm_close(struct snd_pcm_substream *substream) | ||
460 | { | ||
461 | struct echoaudio *chip = snd_pcm_substream_chip(substream); | ||
462 | int oc; | ||
463 | |||
464 | /* Nothing to do here. Audio is already off and pipe will be | ||
465 | * freed by its callback | ||
466 | */ | ||
467 | DE_ACT(("pcm_close\n")); | ||
468 | |||
469 | atomic_dec(&chip->opencount); | ||
470 | oc = atomic_read(&chip->opencount); | ||
471 | DE_ACT(("pcm_close oc=%d cs=%d rs=%d\n", oc, | ||
472 | chip->can_set_rate, chip->rate_set)); | ||
473 | if (oc < 2) | ||
474 | chip->can_set_rate = 1; | ||
475 | if (oc == 0) | ||
476 | chip->rate_set = 0; | ||
477 | DE_ACT(("pcm_close2 oc=%d cs=%d rs=%d\n", oc, | ||
478 | chip->can_set_rate,chip->rate_set)); | ||
479 | |||
480 | return 0; | ||
481 | } | ||
482 | |||
483 | |||
484 | |||
485 | /* Channel allocation and scatter-gather list setup */ | ||
486 | static int init_engine(struct snd_pcm_substream *substream, | ||
487 | struct snd_pcm_hw_params *hw_params, | ||
488 | int pipe_index, int interleave) | ||
489 | { | ||
490 | struct echoaudio *chip; | ||
491 | int err, per, rest, page, edge, offs; | ||
492 | struct snd_sg_buf *sgbuf; | ||
493 | struct audiopipe *pipe; | ||
494 | |||
495 | chip = snd_pcm_substream_chip(substream); | ||
496 | pipe = (struct audiopipe *) substream->runtime->private_data; | ||
497 | |||
498 | /* Sets up che hardware. If it's already initialized, reset and | ||
499 | * redo with the new parameters | ||
500 | */ | ||
501 | spin_lock_irq(&chip->lock); | ||
502 | if (pipe->index >= 0) { | ||
503 | DE_HWP(("hwp_ie free(%d)\n", pipe->index)); | ||
504 | err = free_pipes(chip, pipe); | ||
505 | snd_assert(!err); | ||
506 | chip->substream[pipe->index] = NULL; | ||
507 | } | ||
508 | |||
509 | err = allocate_pipes(chip, pipe, pipe_index, interleave); | ||
510 | if (err < 0) { | ||
511 | spin_unlock_irq(&chip->lock); | ||
512 | DE_ACT((KERN_NOTICE "allocate_pipes(%d) err=%d\n", | ||
513 | pipe_index, err)); | ||
514 | return err; | ||
515 | } | ||
516 | spin_unlock_irq(&chip->lock); | ||
517 | DE_ACT((KERN_NOTICE "allocate_pipes()=%d\n", pipe_index)); | ||
518 | |||
519 | DE_HWP(("pcm_hw_params (bufsize=%dB periods=%d persize=%dB)\n", | ||
520 | params_buffer_bytes(hw_params), params_periods(hw_params), | ||
521 | params_period_bytes(hw_params))); | ||
522 | err = snd_pcm_lib_malloc_pages(substream, | ||
523 | params_buffer_bytes(hw_params)); | ||
524 | if (err < 0) { | ||
525 | snd_printk(KERN_ERR "malloc_pages err=%d\n", err); | ||
526 | spin_lock_irq(&chip->lock); | ||
527 | free_pipes(chip, pipe); | ||
528 | spin_unlock_irq(&chip->lock); | ||
529 | pipe->index = -1; | ||
530 | return err; | ||
531 | } | ||
532 | |||
533 | sgbuf = snd_pcm_substream_sgbuf(substream); | ||
534 | |||
535 | DE_HWP(("pcm_hw_params table size=%d pages=%d\n", | ||
536 | sgbuf->size, sgbuf->pages)); | ||
537 | sglist_init(chip, pipe); | ||
538 | edge = PAGE_SIZE; | ||
539 | for (offs = page = per = 0; offs < params_buffer_bytes(hw_params); | ||
540 | per++) { | ||
541 | rest = params_period_bytes(hw_params); | ||
542 | if (offs + rest > params_buffer_bytes(hw_params)) | ||
543 | rest = params_buffer_bytes(hw_params) - offs; | ||
544 | while (rest) { | ||
545 | if (rest <= edge - offs) { | ||
546 | sglist_add_mapping(chip, pipe, | ||
547 | snd_sgbuf_get_addr(sgbuf, offs), | ||
548 | rest); | ||
549 | sglist_add_irq(chip, pipe); | ||
550 | offs += rest; | ||
551 | rest = 0; | ||
552 | } else { | ||
553 | sglist_add_mapping(chip, pipe, | ||
554 | snd_sgbuf_get_addr(sgbuf, offs), | ||
555 | edge - offs); | ||
556 | rest -= edge - offs; | ||
557 | offs = edge; | ||
558 | } | ||
559 | if (offs == edge) { | ||
560 | edge += PAGE_SIZE; | ||
561 | page++; | ||
562 | } | ||
563 | } | ||
564 | } | ||
565 | |||
566 | /* Close the ring buffer */ | ||
567 | sglist_wrap(chip, pipe); | ||
568 | |||
569 | /* This stuff is used by the irq handler, so it must be | ||
570 | * initialized before chip->substream | ||
571 | */ | ||
572 | chip->last_period[pipe_index] = 0; | ||
573 | pipe->last_counter = 0; | ||
574 | pipe->position = 0; | ||
575 | smp_wmb(); | ||
576 | chip->substream[pipe_index] = substream; | ||
577 | chip->rate_set = 1; | ||
578 | spin_lock_irq(&chip->lock); | ||
579 | set_sample_rate(chip, hw_params->rate_num / hw_params->rate_den); | ||
580 | spin_unlock_irq(&chip->lock); | ||
581 | DE_HWP(("pcm_hw_params ok\n")); | ||
582 | return 0; | ||
583 | } | ||
584 | |||
585 | |||
586 | |||
587 | static int pcm_analog_in_hw_params(struct snd_pcm_substream *substream, | ||
588 | struct snd_pcm_hw_params *hw_params) | ||
589 | { | ||
590 | struct echoaudio *chip = snd_pcm_substream_chip(substream); | ||
591 | |||
592 | return init_engine(substream, hw_params, px_analog_in(chip) + | ||
593 | substream->number, params_channels(hw_params)); | ||
594 | } | ||
595 | |||
596 | |||
597 | |||
598 | static int pcm_analog_out_hw_params(struct snd_pcm_substream *substream, | ||
599 | struct snd_pcm_hw_params *hw_params) | ||
600 | { | ||
601 | return init_engine(substream, hw_params, substream->number, | ||
602 | params_channels(hw_params)); | ||
603 | } | ||
604 | |||
605 | |||
606 | |||
607 | #ifdef ECHOCARD_HAS_DIGITAL_IO | ||
608 | |||
609 | static int pcm_digital_in_hw_params(struct snd_pcm_substream *substream, | ||
610 | struct snd_pcm_hw_params *hw_params) | ||
611 | { | ||
612 | struct echoaudio *chip = snd_pcm_substream_chip(substream); | ||
613 | |||
614 | return init_engine(substream, hw_params, px_digital_in(chip) + | ||
615 | substream->number, params_channels(hw_params)); | ||
616 | } | ||
617 | |||
618 | |||
619 | |||
620 | #ifndef ECHOCARD_HAS_VMIXER /* See the note in snd_echo_new_pcm() */ | ||
621 | static int pcm_digital_out_hw_params(struct snd_pcm_substream *substream, | ||
622 | struct snd_pcm_hw_params *hw_params) | ||
623 | { | ||
624 | struct echoaudio *chip = snd_pcm_substream_chip(substream); | ||
625 | |||
626 | return init_engine(substream, hw_params, px_digital_out(chip) + | ||
627 | substream->number, params_channels(hw_params)); | ||
628 | } | ||
629 | #endif /* !ECHOCARD_HAS_VMIXER */ | ||
630 | |||
631 | #endif /* ECHOCARD_HAS_DIGITAL_IO */ | ||
632 | |||
633 | |||
634 | |||
635 | static int pcm_hw_free(struct snd_pcm_substream *substream) | ||
636 | { | ||
637 | struct echoaudio *chip; | ||
638 | struct audiopipe *pipe; | ||
639 | |||
640 | chip = snd_pcm_substream_chip(substream); | ||
641 | pipe = (struct audiopipe *) substream->runtime->private_data; | ||
642 | |||
643 | spin_lock_irq(&chip->lock); | ||
644 | if (pipe->index >= 0) { | ||
645 | DE_HWP(("pcm_hw_free(%d)\n", pipe->index)); | ||
646 | free_pipes(chip, pipe); | ||
647 | chip->substream[pipe->index] = NULL; | ||
648 | pipe->index = -1; | ||
649 | } | ||
650 | spin_unlock_irq(&chip->lock); | ||
651 | |||
652 | DE_HWP(("pcm_hw_freed\n")); | ||
653 | snd_pcm_lib_free_pages(substream); | ||
654 | return 0; | ||
655 | } | ||
656 | |||
657 | |||
658 | |||
659 | static int pcm_prepare(struct snd_pcm_substream *substream) | ||
660 | { | ||
661 | struct echoaudio *chip = snd_pcm_substream_chip(substream); | ||
662 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
663 | struct audioformat format; | ||
664 | int pipe_index = ((struct audiopipe *)runtime->private_data)->index; | ||
665 | |||
666 | DE_HWP(("Prepare rate=%d format=%d channels=%d\n", | ||
667 | runtime->rate, runtime->format, runtime->channels)); | ||
668 | format.interleave = runtime->channels; | ||
669 | format.data_are_bigendian = 0; | ||
670 | format.mono_to_stereo = 0; | ||
671 | switch (runtime->format) { | ||
672 | case SNDRV_PCM_FORMAT_U8: | ||
673 | format.bits_per_sample = 8; | ||
674 | break; | ||
675 | case SNDRV_PCM_FORMAT_S16_LE: | ||
676 | format.bits_per_sample = 16; | ||
677 | break; | ||
678 | case SNDRV_PCM_FORMAT_S24_3LE: | ||
679 | format.bits_per_sample = 24; | ||
680 | break; | ||
681 | case SNDRV_PCM_FORMAT_S32_BE: | ||
682 | format.data_are_bigendian = 1; | ||
683 | case SNDRV_PCM_FORMAT_S32_LE: | ||
684 | format.bits_per_sample = 32; | ||
685 | break; | ||
686 | default: | ||
687 | DE_HWP(("Prepare error: unsupported format %d\n", | ||
688 | runtime->format)); | ||
689 | return -EINVAL; | ||
690 | } | ||
691 | |||
692 | snd_assert(pipe_index < px_num(chip), return -EINVAL); | ||
693 | snd_assert(is_pipe_allocated(chip, pipe_index), return -EINVAL); | ||
694 | set_audio_format(chip, pipe_index, &format); | ||
695 | return 0; | ||
696 | } | ||
697 | |||
698 | |||
699 | |||
700 | static int pcm_trigger(struct snd_pcm_substream *substream, int cmd) | ||
701 | { | ||
702 | struct echoaudio *chip = snd_pcm_substream_chip(substream); | ||
703 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
704 | struct audiopipe *pipe = runtime->private_data; | ||
705 | int i, err; | ||
706 | u32 channelmask = 0; | ||
707 | struct list_head *pos; | ||
708 | struct snd_pcm_substream *s; | ||
709 | |||
710 | snd_pcm_group_for_each(pos, substream) { | ||
711 | s = snd_pcm_group_substream_entry(pos); | ||
712 | for (i = 0; i < DSP_MAXPIPES; i++) { | ||
713 | if (s == chip->substream[i]) { | ||
714 | channelmask |= 1 << i; | ||
715 | snd_pcm_trigger_done(s, substream); | ||
716 | } | ||
717 | } | ||
718 | } | ||
719 | |||
720 | spin_lock(&chip->lock); | ||
721 | switch (cmd) { | ||
722 | case SNDRV_PCM_TRIGGER_START: | ||
723 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
724 | DE_ACT(("pcm_trigger start\n")); | ||
725 | for (i = 0; i < DSP_MAXPIPES; i++) { | ||
726 | if (channelmask & (1 << i)) { | ||
727 | pipe = chip->substream[i]->runtime->private_data; | ||
728 | switch (pipe->state) { | ||
729 | case PIPE_STATE_STOPPED: | ||
730 | chip->last_period[i] = 0; | ||
731 | pipe->last_counter = 0; | ||
732 | pipe->position = 0; | ||
733 | *pipe->dma_counter = 0; | ||
734 | case PIPE_STATE_PAUSED: | ||
735 | pipe->state = PIPE_STATE_STARTED; | ||
736 | break; | ||
737 | case PIPE_STATE_STARTED: | ||
738 | break; | ||
739 | } | ||
740 | } | ||
741 | } | ||
742 | err = start_transport(chip, channelmask, | ||
743 | chip->pipe_cyclic_mask); | ||
744 | break; | ||
745 | case SNDRV_PCM_TRIGGER_STOP: | ||
746 | DE_ACT(("pcm_trigger stop\n")); | ||
747 | for (i = 0; i < DSP_MAXPIPES; i++) { | ||
748 | if (channelmask & (1 << i)) { | ||
749 | pipe = chip->substream[i]->runtime->private_data; | ||
750 | pipe->state = PIPE_STATE_STOPPED; | ||
751 | } | ||
752 | } | ||
753 | err = stop_transport(chip, channelmask); | ||
754 | break; | ||
755 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
756 | DE_ACT(("pcm_trigger pause\n")); | ||
757 | for (i = 0; i < DSP_MAXPIPES; i++) { | ||
758 | if (channelmask & (1 << i)) { | ||
759 | pipe = chip->substream[i]->runtime->private_data; | ||
760 | pipe->state = PIPE_STATE_PAUSED; | ||
761 | } | ||
762 | } | ||
763 | err = pause_transport(chip, channelmask); | ||
764 | break; | ||
765 | default: | ||
766 | err = -EINVAL; | ||
767 | } | ||
768 | spin_unlock(&chip->lock); | ||
769 | return err; | ||
770 | } | ||
771 | |||
772 | |||
773 | |||
774 | static snd_pcm_uframes_t pcm_pointer(struct snd_pcm_substream *substream) | ||
775 | { | ||
776 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
777 | struct audiopipe *pipe = runtime->private_data; | ||
778 | size_t cnt, bufsize, pos; | ||
779 | |||
780 | cnt = le32_to_cpu(*pipe->dma_counter); | ||
781 | pipe->position += cnt - pipe->last_counter; | ||
782 | pipe->last_counter = cnt; | ||
783 | bufsize = substream->runtime->buffer_size; | ||
784 | pos = bytes_to_frames(substream->runtime, pipe->position); | ||
785 | |||
786 | while (pos >= bufsize) { | ||
787 | pipe->position -= frames_to_bytes(substream->runtime, bufsize); | ||
788 | pos -= bufsize; | ||
789 | } | ||
790 | return pos; | ||
791 | } | ||
792 | |||
793 | |||
794 | |||
795 | /* pcm *_ops structures */ | ||
796 | static struct snd_pcm_ops analog_playback_ops = { | ||
797 | .open = pcm_analog_out_open, | ||
798 | .close = pcm_close, | ||
799 | .ioctl = snd_pcm_lib_ioctl, | ||
800 | .hw_params = pcm_analog_out_hw_params, | ||
801 | .hw_free = pcm_hw_free, | ||
802 | .prepare = pcm_prepare, | ||
803 | .trigger = pcm_trigger, | ||
804 | .pointer = pcm_pointer, | ||
805 | .page = snd_pcm_sgbuf_ops_page, | ||
806 | }; | ||
807 | static struct snd_pcm_ops analog_capture_ops = { | ||
808 | .open = pcm_analog_in_open, | ||
809 | .close = pcm_close, | ||
810 | .ioctl = snd_pcm_lib_ioctl, | ||
811 | .hw_params = pcm_analog_in_hw_params, | ||
812 | .hw_free = pcm_hw_free, | ||
813 | .prepare = pcm_prepare, | ||
814 | .trigger = pcm_trigger, | ||
815 | .pointer = pcm_pointer, | ||
816 | .page = snd_pcm_sgbuf_ops_page, | ||
817 | }; | ||
818 | #ifdef ECHOCARD_HAS_DIGITAL_IO | ||
819 | #ifndef ECHOCARD_HAS_VMIXER | ||
820 | static struct snd_pcm_ops digital_playback_ops = { | ||
821 | .open = pcm_digital_out_open, | ||
822 | .close = pcm_close, | ||
823 | .ioctl = snd_pcm_lib_ioctl, | ||
824 | .hw_params = pcm_digital_out_hw_params, | ||
825 | .hw_free = pcm_hw_free, | ||
826 | .prepare = pcm_prepare, | ||
827 | .trigger = pcm_trigger, | ||
828 | .pointer = pcm_pointer, | ||
829 | .page = snd_pcm_sgbuf_ops_page, | ||
830 | }; | ||
831 | #endif /* !ECHOCARD_HAS_VMIXER */ | ||
832 | static struct snd_pcm_ops digital_capture_ops = { | ||
833 | .open = pcm_digital_in_open, | ||
834 | .close = pcm_close, | ||
835 | .ioctl = snd_pcm_lib_ioctl, | ||
836 | .hw_params = pcm_digital_in_hw_params, | ||
837 | .hw_free = pcm_hw_free, | ||
838 | .prepare = pcm_prepare, | ||
839 | .trigger = pcm_trigger, | ||
840 | .pointer = pcm_pointer, | ||
841 | .page = snd_pcm_sgbuf_ops_page, | ||
842 | }; | ||
843 | #endif /* ECHOCARD_HAS_DIGITAL_IO */ | ||
844 | |||
845 | |||
846 | |||
847 | /* Preallocate memory only for the first substream because it's the most | ||
848 | * used one | ||
849 | */ | ||
850 | static int snd_echo_preallocate_pages(struct snd_pcm *pcm, struct device *dev) | ||
851 | { | ||
852 | struct snd_pcm_substream *ss; | ||
853 | int stream, err; | ||
854 | |||
855 | for (stream = 0; stream < 2; stream++) | ||
856 | for (ss = pcm->streams[stream].substream; ss; ss = ss->next) { | ||
857 | err = snd_pcm_lib_preallocate_pages(ss, SNDRV_DMA_TYPE_DEV_SG, | ||
858 | dev, | ||
859 | ss->number ? 0 : 128<<10, | ||
860 | 256<<10); | ||
861 | if (err < 0) | ||
862 | return err; | ||
863 | } | ||
864 | return 0; | ||
865 | } | ||
866 | |||
867 | |||
868 | |||
869 | /*<--snd_echo_probe() */ | ||
870 | static int __devinit snd_echo_new_pcm(struct echoaudio *chip) | ||
871 | { | ||
872 | struct snd_pcm *pcm; | ||
873 | int err; | ||
874 | |||
875 | #ifdef ECHOCARD_HAS_VMIXER | ||
876 | /* This card has a Vmixer, that is there is no direct mapping from PCM | ||
877 | streams to physical outputs. The user can mix the streams as he wishes | ||
878 | via control interface and it's possible to send any stream to any | ||
879 | output, thus it makes no sense to keep analog and digital outputs | ||
880 | separated */ | ||
881 | |||
882 | /* PCM#0 Virtual outputs and analog inputs */ | ||
883 | if ((err = snd_pcm_new(chip->card, "PCM", 0, num_pipes_out(chip), | ||
884 | num_analog_busses_in(chip), &pcm)) < 0) | ||
885 | return err; | ||
886 | pcm->private_data = chip; | ||
887 | chip->analog_pcm = pcm; | ||
888 | strcpy(pcm->name, chip->card->shortname); | ||
889 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &analog_playback_ops); | ||
890 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &analog_capture_ops); | ||
891 | if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) | ||
892 | return err; | ||
893 | DE_INIT(("Analog PCM ok\n")); | ||
894 | |||
895 | #ifdef ECHOCARD_HAS_DIGITAL_IO | ||
896 | /* PCM#1 Digital inputs, no outputs */ | ||
897 | if ((err = snd_pcm_new(chip->card, "Digital PCM", 1, 0, | ||
898 | num_digital_busses_in(chip), &pcm)) < 0) | ||
899 | return err; | ||
900 | pcm->private_data = chip; | ||
901 | chip->digital_pcm = pcm; | ||
902 | strcpy(pcm->name, chip->card->shortname); | ||
903 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &digital_capture_ops); | ||
904 | if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) | ||
905 | return err; | ||
906 | DE_INIT(("Digital PCM ok\n")); | ||
907 | #endif /* ECHOCARD_HAS_DIGITAL_IO */ | ||
908 | |||
909 | #else /* ECHOCARD_HAS_VMIXER */ | ||
910 | |||
911 | /* The card can manage substreams formed by analog and digital channels | ||
912 | at the same time, but I prefer to keep analog and digital channels | ||
913 | separated, because that mixed thing is confusing and useless. So we | ||
914 | register two PCM devices: */ | ||
915 | |||
916 | /* PCM#0 Analog i/o */ | ||
917 | if ((err = snd_pcm_new(chip->card, "Analog PCM", 0, | ||
918 | num_analog_busses_out(chip), | ||
919 | num_analog_busses_in(chip), &pcm)) < 0) | ||
920 | return err; | ||
921 | pcm->private_data = chip; | ||
922 | chip->analog_pcm = pcm; | ||
923 | strcpy(pcm->name, chip->card->shortname); | ||
924 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &analog_playback_ops); | ||
925 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &analog_capture_ops); | ||
926 | if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) | ||
927 | return err; | ||
928 | DE_INIT(("Analog PCM ok\n")); | ||
929 | |||
930 | #ifdef ECHOCARD_HAS_DIGITAL_IO | ||
931 | /* PCM#1 Digital i/o */ | ||
932 | if ((err = snd_pcm_new(chip->card, "Digital PCM", 1, | ||
933 | num_digital_busses_out(chip), | ||
934 | num_digital_busses_in(chip), &pcm)) < 0) | ||
935 | return err; | ||
936 | pcm->private_data = chip; | ||
937 | chip->digital_pcm = pcm; | ||
938 | strcpy(pcm->name, chip->card->shortname); | ||
939 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &digital_playback_ops); | ||
940 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &digital_capture_ops); | ||
941 | if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) | ||
942 | return err; | ||
943 | DE_INIT(("Digital PCM ok\n")); | ||
944 | #endif /* ECHOCARD_HAS_DIGITAL_IO */ | ||
945 | |||
946 | #endif /* ECHOCARD_HAS_VMIXER */ | ||
947 | |||
948 | return 0; | ||
949 | } | ||
950 | |||
951 | |||
952 | |||
953 | |||
954 | /****************************************************************************** | ||
955 | Control interface | ||
956 | ******************************************************************************/ | ||
957 | |||
958 | /******************* PCM output volume *******************/ | ||
959 | static int snd_echo_output_gain_info(struct snd_kcontrol *kcontrol, | ||
960 | struct snd_ctl_elem_info *uinfo) | ||
961 | { | ||
962 | struct echoaudio *chip; | ||
963 | |||
964 | chip = snd_kcontrol_chip(kcontrol); | ||
965 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
966 | uinfo->count = num_busses_out(chip); | ||
967 | uinfo->value.integer.min = ECHOGAIN_MINOUT; | ||
968 | uinfo->value.integer.max = ECHOGAIN_MAXOUT; | ||
969 | return 0; | ||
970 | } | ||
971 | |||
972 | static int snd_echo_output_gain_get(struct snd_kcontrol *kcontrol, | ||
973 | struct snd_ctl_elem_value *ucontrol) | ||
974 | { | ||
975 | struct echoaudio *chip; | ||
976 | int c; | ||
977 | |||
978 | chip = snd_kcontrol_chip(kcontrol); | ||
979 | for (c = 0; c < num_busses_out(chip); c++) | ||
980 | ucontrol->value.integer.value[c] = chip->output_gain[c]; | ||
981 | return 0; | ||
982 | } | ||
983 | |||
984 | static int snd_echo_output_gain_put(struct snd_kcontrol *kcontrol, | ||
985 | struct snd_ctl_elem_value *ucontrol) | ||
986 | { | ||
987 | struct echoaudio *chip; | ||
988 | int c, changed, gain; | ||
989 | |||
990 | changed = 0; | ||
991 | chip = snd_kcontrol_chip(kcontrol); | ||
992 | spin_lock_irq(&chip->lock); | ||
993 | for (c = 0; c < num_busses_out(chip); c++) { | ||
994 | gain = ucontrol->value.integer.value[c]; | ||
995 | /* Ignore out of range values */ | ||
996 | if (gain < ECHOGAIN_MINOUT || gain > ECHOGAIN_MAXOUT) | ||
997 | continue; | ||
998 | if (chip->output_gain[c] != gain) { | ||
999 | set_output_gain(chip, c, gain); | ||
1000 | changed = 1; | ||
1001 | } | ||
1002 | } | ||
1003 | if (changed) | ||
1004 | update_output_line_level(chip); | ||
1005 | spin_unlock_irq(&chip->lock); | ||
1006 | return changed; | ||
1007 | } | ||
1008 | |||
1009 | #ifdef ECHOCARD_HAS_VMIXER | ||
1010 | /* On Vmixer cards this one controls the line-out volume */ | ||
1011 | static struct snd_kcontrol_new snd_echo_line_output_gain __devinitdata = { | ||
1012 | .name = "Line Playback Volume", | ||
1013 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1014 | .info = snd_echo_output_gain_info, | ||
1015 | .get = snd_echo_output_gain_get, | ||
1016 | .put = snd_echo_output_gain_put, | ||
1017 | }; | ||
1018 | #else | ||
1019 | static struct snd_kcontrol_new snd_echo_pcm_output_gain __devinitdata = { | ||
1020 | .name = "PCM Playback Volume", | ||
1021 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1022 | .info = snd_echo_output_gain_info, | ||
1023 | .get = snd_echo_output_gain_get, | ||
1024 | .put = snd_echo_output_gain_put, | ||
1025 | }; | ||
1026 | #endif | ||
1027 | |||
1028 | |||
1029 | |||
1030 | #ifdef ECHOCARD_HAS_INPUT_GAIN | ||
1031 | |||
1032 | /******************* Analog input volume *******************/ | ||
1033 | static int snd_echo_input_gain_info(struct snd_kcontrol *kcontrol, | ||
1034 | struct snd_ctl_elem_info *uinfo) | ||
1035 | { | ||
1036 | struct echoaudio *chip; | ||
1037 | |||
1038 | chip = snd_kcontrol_chip(kcontrol); | ||
1039 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
1040 | uinfo->count = num_analog_busses_in(chip); | ||
1041 | uinfo->value.integer.min = ECHOGAIN_MININP; | ||
1042 | uinfo->value.integer.max = ECHOGAIN_MAXINP; | ||
1043 | return 0; | ||
1044 | } | ||
1045 | |||
1046 | static int snd_echo_input_gain_get(struct snd_kcontrol *kcontrol, | ||
1047 | struct snd_ctl_elem_value *ucontrol) | ||
1048 | { | ||
1049 | struct echoaudio *chip; | ||
1050 | int c; | ||
1051 | |||
1052 | chip = snd_kcontrol_chip(kcontrol); | ||
1053 | for (c = 0; c < num_analog_busses_in(chip); c++) | ||
1054 | ucontrol->value.integer.value[c] = chip->input_gain[c]; | ||
1055 | return 0; | ||
1056 | } | ||
1057 | |||
1058 | static int snd_echo_input_gain_put(struct snd_kcontrol *kcontrol, | ||
1059 | struct snd_ctl_elem_value *ucontrol) | ||
1060 | { | ||
1061 | struct echoaudio *chip; | ||
1062 | int c, gain, changed; | ||
1063 | |||
1064 | changed = 0; | ||
1065 | chip = snd_kcontrol_chip(kcontrol); | ||
1066 | spin_lock_irq(&chip->lock); | ||
1067 | for (c = 0; c < num_analog_busses_in(chip); c++) { | ||
1068 | gain = ucontrol->value.integer.value[c]; | ||
1069 | /* Ignore out of range values */ | ||
1070 | if (gain < ECHOGAIN_MININP || gain > ECHOGAIN_MAXINP) | ||
1071 | continue; | ||
1072 | if (chip->input_gain[c] != gain) { | ||
1073 | set_input_gain(chip, c, gain); | ||
1074 | changed = 1; | ||
1075 | } | ||
1076 | } | ||
1077 | if (changed) | ||
1078 | update_input_line_level(chip); | ||
1079 | spin_unlock_irq(&chip->lock); | ||
1080 | return changed; | ||
1081 | } | ||
1082 | |||
1083 | static struct snd_kcontrol_new snd_echo_line_input_gain __devinitdata = { | ||
1084 | .name = "Line Capture Volume", | ||
1085 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1086 | .info = snd_echo_input_gain_info, | ||
1087 | .get = snd_echo_input_gain_get, | ||
1088 | .put = snd_echo_input_gain_put, | ||
1089 | }; | ||
1090 | |||
1091 | #endif /* ECHOCARD_HAS_INPUT_GAIN */ | ||
1092 | |||
1093 | |||
1094 | |||
1095 | #ifdef ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL | ||
1096 | |||
1097 | /************ Analog output nominal level (+4dBu / -10dBV) ***************/ | ||
1098 | static int snd_echo_output_nominal_info (struct snd_kcontrol *kcontrol, | ||
1099 | struct snd_ctl_elem_info *uinfo) | ||
1100 | { | ||
1101 | struct echoaudio *chip; | ||
1102 | |||
1103 | chip = snd_kcontrol_chip(kcontrol); | ||
1104 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
1105 | uinfo->count = num_analog_busses_out(chip); | ||
1106 | uinfo->value.integer.min = 0; | ||
1107 | uinfo->value.integer.max = 1; | ||
1108 | return 0; | ||
1109 | } | ||
1110 | |||
1111 | static int snd_echo_output_nominal_get(struct snd_kcontrol *kcontrol, | ||
1112 | struct snd_ctl_elem_value *ucontrol) | ||
1113 | { | ||
1114 | struct echoaudio *chip; | ||
1115 | int c; | ||
1116 | |||
1117 | chip = snd_kcontrol_chip(kcontrol); | ||
1118 | for (c = 0; c < num_analog_busses_out(chip); c++) | ||
1119 | ucontrol->value.integer.value[c] = chip->nominal_level[c]; | ||
1120 | return 0; | ||
1121 | } | ||
1122 | |||
1123 | static int snd_echo_output_nominal_put(struct snd_kcontrol *kcontrol, | ||
1124 | struct snd_ctl_elem_value *ucontrol) | ||
1125 | { | ||
1126 | struct echoaudio *chip; | ||
1127 | int c, changed; | ||
1128 | |||
1129 | changed = 0; | ||
1130 | chip = snd_kcontrol_chip(kcontrol); | ||
1131 | spin_lock_irq(&chip->lock); | ||
1132 | for (c = 0; c < num_analog_busses_out(chip); c++) { | ||
1133 | if (chip->nominal_level[c] != ucontrol->value.integer.value[c]) { | ||
1134 | set_nominal_level(chip, c, | ||
1135 | ucontrol->value.integer.value[c]); | ||
1136 | changed = 1; | ||
1137 | } | ||
1138 | } | ||
1139 | if (changed) | ||
1140 | update_output_line_level(chip); | ||
1141 | spin_unlock_irq(&chip->lock); | ||
1142 | return changed; | ||
1143 | } | ||
1144 | |||
1145 | static struct snd_kcontrol_new snd_echo_output_nominal_level __devinitdata = { | ||
1146 | .name = "Line Playback Switch (-10dBV)", | ||
1147 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1148 | .info = snd_echo_output_nominal_info, | ||
1149 | .get = snd_echo_output_nominal_get, | ||
1150 | .put = snd_echo_output_nominal_put, | ||
1151 | }; | ||
1152 | |||
1153 | #endif /* ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL */ | ||
1154 | |||
1155 | |||
1156 | |||
1157 | #ifdef ECHOCARD_HAS_INPUT_NOMINAL_LEVEL | ||
1158 | |||
1159 | /*************** Analog input nominal level (+4dBu / -10dBV) ***************/ | ||
1160 | static int snd_echo_input_nominal_info(struct snd_kcontrol *kcontrol, | ||
1161 | struct snd_ctl_elem_info *uinfo) | ||
1162 | { | ||
1163 | struct echoaudio *chip; | ||
1164 | |||
1165 | chip = snd_kcontrol_chip(kcontrol); | ||
1166 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
1167 | uinfo->count = num_analog_busses_in(chip); | ||
1168 | uinfo->value.integer.min = 0; | ||
1169 | uinfo->value.integer.max = 1; | ||
1170 | return 0; | ||
1171 | } | ||
1172 | |||
1173 | static int snd_echo_input_nominal_get(struct snd_kcontrol *kcontrol, | ||
1174 | struct snd_ctl_elem_value *ucontrol) | ||
1175 | { | ||
1176 | struct echoaudio *chip; | ||
1177 | int c; | ||
1178 | |||
1179 | chip = snd_kcontrol_chip(kcontrol); | ||
1180 | for (c = 0; c < num_analog_busses_in(chip); c++) | ||
1181 | ucontrol->value.integer.value[c] = | ||
1182 | chip->nominal_level[bx_analog_in(chip) + c]; | ||
1183 | return 0; | ||
1184 | } | ||
1185 | |||
1186 | static int snd_echo_input_nominal_put(struct snd_kcontrol *kcontrol, | ||
1187 | struct snd_ctl_elem_value *ucontrol) | ||
1188 | { | ||
1189 | struct echoaudio *chip; | ||
1190 | int c, changed; | ||
1191 | |||
1192 | changed = 0; | ||
1193 | chip = snd_kcontrol_chip(kcontrol); | ||
1194 | spin_lock_irq(&chip->lock); | ||
1195 | for (c = 0; c < num_analog_busses_in(chip); c++) { | ||
1196 | if (chip->nominal_level[bx_analog_in(chip) + c] != | ||
1197 | ucontrol->value.integer.value[c]) { | ||
1198 | set_nominal_level(chip, bx_analog_in(chip) + c, | ||
1199 | ucontrol->value.integer.value[c]); | ||
1200 | changed = 1; | ||
1201 | } | ||
1202 | } | ||
1203 | if (changed) | ||
1204 | update_output_line_level(chip); /* "Output" is not a mistake | ||
1205 | * here. | ||
1206 | */ | ||
1207 | spin_unlock_irq(&chip->lock); | ||
1208 | return changed; | ||
1209 | } | ||
1210 | |||
1211 | static struct snd_kcontrol_new snd_echo_intput_nominal_level __devinitdata = { | ||
1212 | .name = "Line Capture Switch (-10dBV)", | ||
1213 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1214 | .info = snd_echo_input_nominal_info, | ||
1215 | .get = snd_echo_input_nominal_get, | ||
1216 | .put = snd_echo_input_nominal_put, | ||
1217 | }; | ||
1218 | |||
1219 | #endif /* ECHOCARD_HAS_INPUT_NOMINAL_LEVEL */ | ||
1220 | |||
1221 | |||
1222 | |||
1223 | #ifdef ECHOCARD_HAS_MONITOR | ||
1224 | |||
1225 | /******************* Monitor mixer *******************/ | ||
1226 | static int snd_echo_mixer_info(struct snd_kcontrol *kcontrol, | ||
1227 | struct snd_ctl_elem_info *uinfo) | ||
1228 | { | ||
1229 | struct echoaudio *chip; | ||
1230 | |||
1231 | chip = snd_kcontrol_chip(kcontrol); | ||
1232 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
1233 | uinfo->count = 1; | ||
1234 | uinfo->value.integer.min = ECHOGAIN_MINOUT; | ||
1235 | uinfo->value.integer.max = ECHOGAIN_MAXOUT; | ||
1236 | uinfo->dimen.d[0] = num_busses_out(chip); | ||
1237 | uinfo->dimen.d[1] = num_busses_in(chip); | ||
1238 | return 0; | ||
1239 | } | ||
1240 | |||
1241 | static int snd_echo_mixer_get(struct snd_kcontrol *kcontrol, | ||
1242 | struct snd_ctl_elem_value *ucontrol) | ||
1243 | { | ||
1244 | struct echoaudio *chip; | ||
1245 | |||
1246 | chip = snd_kcontrol_chip(kcontrol); | ||
1247 | ucontrol->value.integer.value[0] = | ||
1248 | chip->monitor_gain[ucontrol->id.index / num_busses_in(chip)] | ||
1249 | [ucontrol->id.index % num_busses_in(chip)]; | ||
1250 | return 0; | ||
1251 | } | ||
1252 | |||
1253 | static int snd_echo_mixer_put(struct snd_kcontrol *kcontrol, | ||
1254 | struct snd_ctl_elem_value *ucontrol) | ||
1255 | { | ||
1256 | struct echoaudio *chip; | ||
1257 | int changed, gain; | ||
1258 | short out, in; | ||
1259 | |||
1260 | changed = 0; | ||
1261 | chip = snd_kcontrol_chip(kcontrol); | ||
1262 | out = ucontrol->id.index / num_busses_in(chip); | ||
1263 | in = ucontrol->id.index % num_busses_in(chip); | ||
1264 | gain = ucontrol->value.integer.value[0]; | ||
1265 | if (gain < ECHOGAIN_MINOUT || gain > ECHOGAIN_MAXOUT) | ||
1266 | return -EINVAL; | ||
1267 | if (chip->monitor_gain[out][in] != gain) { | ||
1268 | spin_lock_irq(&chip->lock); | ||
1269 | set_monitor_gain(chip, out, in, gain); | ||
1270 | update_output_line_level(chip); | ||
1271 | spin_unlock_irq(&chip->lock); | ||
1272 | changed = 1; | ||
1273 | } | ||
1274 | return changed; | ||
1275 | } | ||
1276 | |||
1277 | static struct snd_kcontrol_new snd_echo_monitor_mixer __devinitdata = { | ||
1278 | .name = "Monitor Mixer Volume", | ||
1279 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1280 | .info = snd_echo_mixer_info, | ||
1281 | .get = snd_echo_mixer_get, | ||
1282 | .put = snd_echo_mixer_put, | ||
1283 | }; | ||
1284 | |||
1285 | #endif /* ECHOCARD_HAS_MONITOR */ | ||
1286 | |||
1287 | |||
1288 | |||
1289 | #ifdef ECHOCARD_HAS_VMIXER | ||
1290 | |||
1291 | /******************* Vmixer *******************/ | ||
1292 | static int snd_echo_vmixer_info(struct snd_kcontrol *kcontrol, | ||
1293 | struct snd_ctl_elem_info *uinfo) | ||
1294 | { | ||
1295 | struct echoaudio *chip; | ||
1296 | |||
1297 | chip = snd_kcontrol_chip(kcontrol); | ||
1298 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
1299 | uinfo->count = 1; | ||
1300 | uinfo->value.integer.min = ECHOGAIN_MINOUT; | ||
1301 | uinfo->value.integer.max = ECHOGAIN_MAXOUT; | ||
1302 | uinfo->dimen.d[0] = num_busses_out(chip); | ||
1303 | uinfo->dimen.d[1] = num_pipes_out(chip); | ||
1304 | return 0; | ||
1305 | } | ||
1306 | |||
1307 | static int snd_echo_vmixer_get(struct snd_kcontrol *kcontrol, | ||
1308 | struct snd_ctl_elem_value *ucontrol) | ||
1309 | { | ||
1310 | struct echoaudio *chip; | ||
1311 | |||
1312 | chip = snd_kcontrol_chip(kcontrol); | ||
1313 | ucontrol->value.integer.value[0] = | ||
1314 | chip->vmixer_gain[ucontrol->id.index / num_pipes_out(chip)] | ||
1315 | [ucontrol->id.index % num_pipes_out(chip)]; | ||
1316 | return 0; | ||
1317 | } | ||
1318 | |||
1319 | static int snd_echo_vmixer_put(struct snd_kcontrol *kcontrol, | ||
1320 | struct snd_ctl_elem_value *ucontrol) | ||
1321 | { | ||
1322 | struct echoaudio *chip; | ||
1323 | int gain, changed; | ||
1324 | short vch, out; | ||
1325 | |||
1326 | changed = 0; | ||
1327 | chip = snd_kcontrol_chip(kcontrol); | ||
1328 | out = ucontrol->id.index / num_pipes_out(chip); | ||
1329 | vch = ucontrol->id.index % num_pipes_out(chip); | ||
1330 | gain = ucontrol->value.integer.value[0]; | ||
1331 | if (gain < ECHOGAIN_MINOUT || gain > ECHOGAIN_MAXOUT) | ||
1332 | return -EINVAL; | ||
1333 | if (chip->vmixer_gain[out][vch] != ucontrol->value.integer.value[0]) { | ||
1334 | spin_lock_irq(&chip->lock); | ||
1335 | set_vmixer_gain(chip, out, vch, ucontrol->value.integer.value[0]); | ||
1336 | update_vmixer_level(chip); | ||
1337 | spin_unlock_irq(&chip->lock); | ||
1338 | changed = 1; | ||
1339 | } | ||
1340 | return changed; | ||
1341 | } | ||
1342 | |||
1343 | static struct snd_kcontrol_new snd_echo_vmixer __devinitdata = { | ||
1344 | .name = "VMixer Volume", | ||
1345 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1346 | .info = snd_echo_vmixer_info, | ||
1347 | .get = snd_echo_vmixer_get, | ||
1348 | .put = snd_echo_vmixer_put, | ||
1349 | }; | ||
1350 | |||
1351 | #endif /* ECHOCARD_HAS_VMIXER */ | ||
1352 | |||
1353 | |||
1354 | |||
1355 | #ifdef ECHOCARD_HAS_DIGITAL_MODE_SWITCH | ||
1356 | |||
1357 | /******************* Digital mode switch *******************/ | ||
1358 | static int snd_echo_digital_mode_info(struct snd_kcontrol *kcontrol, | ||
1359 | struct snd_ctl_elem_info *uinfo) | ||
1360 | { | ||
1361 | static char *names[4] = { | ||
1362 | "S/PDIF Coaxial", "S/PDIF Optical", "ADAT Optical", | ||
1363 | "S/PDIF Cdrom" | ||
1364 | }; | ||
1365 | struct echoaudio *chip; | ||
1366 | |||
1367 | chip = snd_kcontrol_chip(kcontrol); | ||
1368 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
1369 | uinfo->value.enumerated.items = chip->num_digital_modes; | ||
1370 | uinfo->count = 1; | ||
1371 | if (uinfo->value.enumerated.item >= chip->num_digital_modes) | ||
1372 | uinfo->value.enumerated.item = chip->num_digital_modes - 1; | ||
1373 | strcpy(uinfo->value.enumerated.name, names[ | ||
1374 | chip->digital_mode_list[uinfo->value.enumerated.item]]); | ||
1375 | return 0; | ||
1376 | } | ||
1377 | |||
1378 | static int snd_echo_digital_mode_get(struct snd_kcontrol *kcontrol, | ||
1379 | struct snd_ctl_elem_value *ucontrol) | ||
1380 | { | ||
1381 | struct echoaudio *chip; | ||
1382 | int i, mode; | ||
1383 | |||
1384 | chip = snd_kcontrol_chip(kcontrol); | ||
1385 | mode = chip->digital_mode; | ||
1386 | for (i = chip->num_digital_modes - 1; i >= 0; i--) | ||
1387 | if (mode == chip->digital_mode_list[i]) { | ||
1388 | ucontrol->value.enumerated.item[0] = i; | ||
1389 | break; | ||
1390 | } | ||
1391 | return 0; | ||
1392 | } | ||
1393 | |||
1394 | static int snd_echo_digital_mode_put(struct snd_kcontrol *kcontrol, | ||
1395 | struct snd_ctl_elem_value *ucontrol) | ||
1396 | { | ||
1397 | struct echoaudio *chip; | ||
1398 | int changed; | ||
1399 | unsigned short emode, dmode; | ||
1400 | |||
1401 | changed = 0; | ||
1402 | chip = snd_kcontrol_chip(kcontrol); | ||
1403 | |||
1404 | emode = ucontrol->value.enumerated.item[0]; | ||
1405 | if (emode >= chip->num_digital_modes) | ||
1406 | return -EINVAL; | ||
1407 | dmode = chip->digital_mode_list[emode]; | ||
1408 | |||
1409 | if (dmode != chip->digital_mode) { | ||
1410 | /* mode_mutex is required to make this operation atomic wrt | ||
1411 | pcm_digital_*_open() and set_input_clock() functions. */ | ||
1412 | down(&chip->mode_mutex); | ||
1413 | |||
1414 | /* Do not allow the user to change the digital mode when a pcm | ||
1415 | device is open because it also changes the number of channels | ||
1416 | and the allowed sample rates */ | ||
1417 | if (atomic_read(&chip->opencount)) { | ||
1418 | changed = -EAGAIN; | ||
1419 | } else { | ||
1420 | changed = set_digital_mode(chip, dmode); | ||
1421 | /* If we had to change the clock source, report it */ | ||
1422 | if (changed > 0 && chip->clock_src_ctl) { | ||
1423 | snd_ctl_notify(chip->card, | ||
1424 | SNDRV_CTL_EVENT_MASK_VALUE, | ||
1425 | &chip->clock_src_ctl->id); | ||
1426 | DE_ACT(("SDM() =%d\n", changed)); | ||
1427 | } | ||
1428 | if (changed >= 0) | ||
1429 | changed = 1; /* No errors */ | ||
1430 | } | ||
1431 | up(&chip->mode_mutex); | ||
1432 | } | ||
1433 | return changed; | ||
1434 | } | ||
1435 | |||
1436 | static struct snd_kcontrol_new snd_echo_digital_mode_switch __devinitdata = { | ||
1437 | .name = "Digital mode Switch", | ||
1438 | .iface = SNDRV_CTL_ELEM_IFACE_CARD, | ||
1439 | .info = snd_echo_digital_mode_info, | ||
1440 | .get = snd_echo_digital_mode_get, | ||
1441 | .put = snd_echo_digital_mode_put, | ||
1442 | }; | ||
1443 | |||
1444 | #endif /* ECHOCARD_HAS_DIGITAL_MODE_SWITCH */ | ||
1445 | |||
1446 | |||
1447 | |||
1448 | #ifdef ECHOCARD_HAS_DIGITAL_IO | ||
1449 | |||
1450 | /******************* S/PDIF mode switch *******************/ | ||
1451 | static int snd_echo_spdif_mode_info(struct snd_kcontrol *kcontrol, | ||
1452 | struct snd_ctl_elem_info *uinfo) | ||
1453 | { | ||
1454 | static char *names[2] = {"Consumer", "Professional"}; | ||
1455 | |||
1456 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
1457 | uinfo->value.enumerated.items = 2; | ||
1458 | uinfo->count = 1; | ||
1459 | if (uinfo->value.enumerated.item) | ||
1460 | uinfo->value.enumerated.item = 1; | ||
1461 | strcpy(uinfo->value.enumerated.name, | ||
1462 | names[uinfo->value.enumerated.item]); | ||
1463 | return 0; | ||
1464 | } | ||
1465 | |||
1466 | static int snd_echo_spdif_mode_get(struct snd_kcontrol *kcontrol, | ||
1467 | struct snd_ctl_elem_value *ucontrol) | ||
1468 | { | ||
1469 | struct echoaudio *chip; | ||
1470 | |||
1471 | chip = snd_kcontrol_chip(kcontrol); | ||
1472 | ucontrol->value.enumerated.item[0] = !!chip->professional_spdif; | ||
1473 | return 0; | ||
1474 | } | ||
1475 | |||
1476 | static int snd_echo_spdif_mode_put(struct snd_kcontrol *kcontrol, | ||
1477 | struct snd_ctl_elem_value *ucontrol) | ||
1478 | { | ||
1479 | struct echoaudio *chip; | ||
1480 | int mode; | ||
1481 | |||
1482 | chip = snd_kcontrol_chip(kcontrol); | ||
1483 | mode = !!ucontrol->value.enumerated.item[0]; | ||
1484 | if (mode != chip->professional_spdif) { | ||
1485 | spin_lock_irq(&chip->lock); | ||
1486 | set_professional_spdif(chip, mode); | ||
1487 | spin_unlock_irq(&chip->lock); | ||
1488 | return 1; | ||
1489 | } | ||
1490 | return 0; | ||
1491 | } | ||
1492 | |||
1493 | static struct snd_kcontrol_new snd_echo_spdif_mode_switch __devinitdata = { | ||
1494 | .name = "S/PDIF mode Switch", | ||
1495 | .iface = SNDRV_CTL_ELEM_IFACE_CARD, | ||
1496 | .info = snd_echo_spdif_mode_info, | ||
1497 | .get = snd_echo_spdif_mode_get, | ||
1498 | .put = snd_echo_spdif_mode_put, | ||
1499 | }; | ||
1500 | |||
1501 | #endif /* ECHOCARD_HAS_DIGITAL_IO */ | ||
1502 | |||
1503 | |||
1504 | |||
1505 | #ifdef ECHOCARD_HAS_EXTERNAL_CLOCK | ||
1506 | |||
1507 | /******************* Select input clock source *******************/ | ||
1508 | static int snd_echo_clock_source_info(struct snd_kcontrol *kcontrol, | ||
1509 | struct snd_ctl_elem_info *uinfo) | ||
1510 | { | ||
1511 | static char *names[8] = { | ||
1512 | "Internal", "Word", "Super", "S/PDIF", "ADAT", "ESync", | ||
1513 | "ESync96", "MTC" | ||
1514 | }; | ||
1515 | struct echoaudio *chip; | ||
1516 | |||
1517 | chip = snd_kcontrol_chip(kcontrol); | ||
1518 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
1519 | uinfo->value.enumerated.items = chip->num_clock_sources; | ||
1520 | uinfo->count = 1; | ||
1521 | if (uinfo->value.enumerated.item >= chip->num_clock_sources) | ||
1522 | uinfo->value.enumerated.item = chip->num_clock_sources - 1; | ||
1523 | strcpy(uinfo->value.enumerated.name, names[ | ||
1524 | chip->clock_source_list[uinfo->value.enumerated.item]]); | ||
1525 | return 0; | ||
1526 | } | ||
1527 | |||
1528 | static int snd_echo_clock_source_get(struct snd_kcontrol *kcontrol, | ||
1529 | struct snd_ctl_elem_value *ucontrol) | ||
1530 | { | ||
1531 | struct echoaudio *chip; | ||
1532 | int i, clock; | ||
1533 | |||
1534 | chip = snd_kcontrol_chip(kcontrol); | ||
1535 | clock = chip->input_clock; | ||
1536 | |||
1537 | for (i = 0; i < chip->num_clock_sources; i++) | ||
1538 | if (clock == chip->clock_source_list[i]) | ||
1539 | ucontrol->value.enumerated.item[0] = i; | ||
1540 | |||
1541 | return 0; | ||
1542 | } | ||
1543 | |||
1544 | static int snd_echo_clock_source_put(struct snd_kcontrol *kcontrol, | ||
1545 | struct snd_ctl_elem_value *ucontrol) | ||
1546 | { | ||
1547 | struct echoaudio *chip; | ||
1548 | int changed; | ||
1549 | unsigned int eclock, dclock; | ||
1550 | |||
1551 | changed = 0; | ||
1552 | chip = snd_kcontrol_chip(kcontrol); | ||
1553 | eclock = ucontrol->value.enumerated.item[0]; | ||
1554 | if (eclock >= chip->input_clock_types) | ||
1555 | return -EINVAL; | ||
1556 | dclock = chip->clock_source_list[eclock]; | ||
1557 | if (chip->input_clock != dclock) { | ||
1558 | down(&chip->mode_mutex); | ||
1559 | spin_lock_irq(&chip->lock); | ||
1560 | if ((changed = set_input_clock(chip, dclock)) == 0) | ||
1561 | changed = 1; /* no errors */ | ||
1562 | spin_unlock_irq(&chip->lock); | ||
1563 | up(&chip->mode_mutex); | ||
1564 | } | ||
1565 | |||
1566 | if (changed < 0) | ||
1567 | DE_ACT(("seticlk val%d err 0x%x\n", dclock, changed)); | ||
1568 | |||
1569 | return changed; | ||
1570 | } | ||
1571 | |||
1572 | static struct snd_kcontrol_new snd_echo_clock_source_switch __devinitdata = { | ||
1573 | .name = "Sample Clock Source", | ||
1574 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | ||
1575 | .info = snd_echo_clock_source_info, | ||
1576 | .get = snd_echo_clock_source_get, | ||
1577 | .put = snd_echo_clock_source_put, | ||
1578 | }; | ||
1579 | |||
1580 | #endif /* ECHOCARD_HAS_EXTERNAL_CLOCK */ | ||
1581 | |||
1582 | |||
1583 | |||
1584 | #ifdef ECHOCARD_HAS_PHANTOM_POWER | ||
1585 | |||
1586 | /******************* Phantom power switch *******************/ | ||
1587 | static int snd_echo_phantom_power_info(struct snd_kcontrol *kcontrol, | ||
1588 | struct snd_ctl_elem_info *uinfo) | ||
1589 | { | ||
1590 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
1591 | uinfo->count = 1; | ||
1592 | uinfo->value.integer.min = 0; | ||
1593 | uinfo->value.integer.max = 1; | ||
1594 | return 0; | ||
1595 | } | ||
1596 | |||
1597 | static int snd_echo_phantom_power_get(struct snd_kcontrol *kcontrol, | ||
1598 | struct snd_ctl_elem_value *ucontrol) | ||
1599 | { | ||
1600 | struct echoaudio *chip = snd_kcontrol_chip(kcontrol); | ||
1601 | |||
1602 | ucontrol->value.integer.value[0] = chip->phantom_power; | ||
1603 | return 0; | ||
1604 | } | ||
1605 | |||
1606 | static int snd_echo_phantom_power_put(struct snd_kcontrol *kcontrol, | ||
1607 | struct snd_ctl_elem_value *ucontrol) | ||
1608 | { | ||
1609 | struct echoaudio *chip = snd_kcontrol_chip(kcontrol); | ||
1610 | int power, changed = 0; | ||
1611 | |||
1612 | power = !!ucontrol->value.integer.value[0]; | ||
1613 | if (chip->phantom_power != power) { | ||
1614 | spin_lock_irq(&chip->lock); | ||
1615 | changed = set_phantom_power(chip, power); | ||
1616 | spin_unlock_irq(&chip->lock); | ||
1617 | if (changed == 0) | ||
1618 | changed = 1; /* no errors */ | ||
1619 | } | ||
1620 | return changed; | ||
1621 | } | ||
1622 | |||
1623 | static struct snd_kcontrol_new snd_echo_phantom_power_switch __devinitdata = { | ||
1624 | .name = "Phantom power Switch", | ||
1625 | .iface = SNDRV_CTL_ELEM_IFACE_CARD, | ||
1626 | .info = snd_echo_phantom_power_info, | ||
1627 | .get = snd_echo_phantom_power_get, | ||
1628 | .put = snd_echo_phantom_power_put, | ||
1629 | }; | ||
1630 | |||
1631 | #endif /* ECHOCARD_HAS_PHANTOM_POWER */ | ||
1632 | |||
1633 | |||
1634 | |||
1635 | #ifdef ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE | ||
1636 | |||
1637 | /******************* Digital input automute switch *******************/ | ||
1638 | static int snd_echo_automute_info(struct snd_kcontrol *kcontrol, | ||
1639 | struct snd_ctl_elem_info *uinfo) | ||
1640 | { | ||
1641 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
1642 | uinfo->count = 1; | ||
1643 | uinfo->value.integer.min = 0; | ||
1644 | uinfo->value.integer.max = 1; | ||
1645 | return 0; | ||
1646 | } | ||
1647 | |||
1648 | static int snd_echo_automute_get(struct snd_kcontrol *kcontrol, | ||
1649 | struct snd_ctl_elem_value *ucontrol) | ||
1650 | { | ||
1651 | struct echoaudio *chip = snd_kcontrol_chip(kcontrol); | ||
1652 | |||
1653 | ucontrol->value.integer.value[0] = chip->digital_in_automute; | ||
1654 | return 0; | ||
1655 | } | ||
1656 | |||
1657 | static int snd_echo_automute_put(struct snd_kcontrol *kcontrol, | ||
1658 | struct snd_ctl_elem_value *ucontrol) | ||
1659 | { | ||
1660 | struct echoaudio *chip = snd_kcontrol_chip(kcontrol); | ||
1661 | int automute, changed = 0; | ||
1662 | |||
1663 | automute = !!ucontrol->value.integer.value[0]; | ||
1664 | if (chip->digital_in_automute != automute) { | ||
1665 | spin_lock_irq(&chip->lock); | ||
1666 | changed = set_input_auto_mute(chip, automute); | ||
1667 | spin_unlock_irq(&chip->lock); | ||
1668 | if (changed == 0) | ||
1669 | changed = 1; /* no errors */ | ||
1670 | } | ||
1671 | return changed; | ||
1672 | } | ||
1673 | |||
1674 | static struct snd_kcontrol_new snd_echo_automute_switch __devinitdata = { | ||
1675 | .name = "Digital Capture Switch (automute)", | ||
1676 | .iface = SNDRV_CTL_ELEM_IFACE_CARD, | ||
1677 | .info = snd_echo_automute_info, | ||
1678 | .get = snd_echo_automute_get, | ||
1679 | .put = snd_echo_automute_put, | ||
1680 | }; | ||
1681 | |||
1682 | #endif /* ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE */ | ||
1683 | |||
1684 | |||
1685 | |||
1686 | /******************* VU-meters switch *******************/ | ||
1687 | static int snd_echo_vumeters_switch_info(struct snd_kcontrol *kcontrol, | ||
1688 | struct snd_ctl_elem_info *uinfo) | ||
1689 | { | ||
1690 | struct echoaudio *chip; | ||
1691 | |||
1692 | chip = snd_kcontrol_chip(kcontrol); | ||
1693 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
1694 | uinfo->count = 1; | ||
1695 | uinfo->value.integer.min = 0; | ||
1696 | uinfo->value.integer.max = 1; | ||
1697 | return 0; | ||
1698 | } | ||
1699 | |||
1700 | static int snd_echo_vumeters_switch_put(struct snd_kcontrol *kcontrol, | ||
1701 | struct snd_ctl_elem_value *ucontrol) | ||
1702 | { | ||
1703 | struct echoaudio *chip; | ||
1704 | |||
1705 | chip = snd_kcontrol_chip(kcontrol); | ||
1706 | spin_lock_irq(&chip->lock); | ||
1707 | set_meters_on(chip, ucontrol->value.integer.value[0]); | ||
1708 | spin_unlock_irq(&chip->lock); | ||
1709 | return 1; | ||
1710 | } | ||
1711 | |||
1712 | static struct snd_kcontrol_new snd_echo_vumeters_switch __devinitdata = { | ||
1713 | .name = "VU-meters Switch", | ||
1714 | .iface = SNDRV_CTL_ELEM_IFACE_CARD, | ||
1715 | .access = SNDRV_CTL_ELEM_ACCESS_WRITE, | ||
1716 | .info = snd_echo_vumeters_switch_info, | ||
1717 | .put = snd_echo_vumeters_switch_put, | ||
1718 | }; | ||
1719 | |||
1720 | |||
1721 | |||
1722 | /***** Read VU-meters (input, output, analog and digital together) *****/ | ||
1723 | static int snd_echo_vumeters_info(struct snd_kcontrol *kcontrol, | ||
1724 | struct snd_ctl_elem_info *uinfo) | ||
1725 | { | ||
1726 | struct echoaudio *chip; | ||
1727 | |||
1728 | chip = snd_kcontrol_chip(kcontrol); | ||
1729 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
1730 | uinfo->count = 96; | ||
1731 | uinfo->value.integer.min = ECHOGAIN_MINOUT; | ||
1732 | uinfo->value.integer.max = 0; | ||
1733 | #ifdef ECHOCARD_HAS_VMIXER | ||
1734 | uinfo->dimen.d[0] = 3; /* Out, In, Virt */ | ||
1735 | #else | ||
1736 | uinfo->dimen.d[0] = 2; /* Out, In */ | ||
1737 | #endif | ||
1738 | uinfo->dimen.d[1] = 16; /* 16 channels */ | ||
1739 | uinfo->dimen.d[2] = 2; /* 0=level, 1=peak */ | ||
1740 | return 0; | ||
1741 | } | ||
1742 | |||
1743 | static int snd_echo_vumeters_get(struct snd_kcontrol *kcontrol, | ||
1744 | struct snd_ctl_elem_value *ucontrol) | ||
1745 | { | ||
1746 | struct echoaudio *chip; | ||
1747 | |||
1748 | chip = snd_kcontrol_chip(kcontrol); | ||
1749 | get_audio_meters(chip, ucontrol->value.integer.value); | ||
1750 | return 0; | ||
1751 | } | ||
1752 | |||
1753 | static struct snd_kcontrol_new snd_echo_vumeters __devinitdata = { | ||
1754 | .name = "VU-meters", | ||
1755 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1756 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | ||
1757 | .info = snd_echo_vumeters_info, | ||
1758 | .get = snd_echo_vumeters_get, | ||
1759 | }; | ||
1760 | |||
1761 | |||
1762 | |||
1763 | /*** Channels info - it exports informations about the number of channels ***/ | ||
1764 | static int snd_echo_channels_info_info(struct snd_kcontrol *kcontrol, | ||
1765 | struct snd_ctl_elem_info *uinfo) | ||
1766 | { | ||
1767 | struct echoaudio *chip; | ||
1768 | |||
1769 | chip = snd_kcontrol_chip(kcontrol); | ||
1770 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
1771 | uinfo->count = 6; | ||
1772 | uinfo->value.integer.min = 0; | ||
1773 | uinfo->value.integer.max = 1 << ECHO_CLOCK_NUMBER; | ||
1774 | return 0; | ||
1775 | } | ||
1776 | |||
1777 | static int snd_echo_channels_info_get(struct snd_kcontrol *kcontrol, | ||
1778 | struct snd_ctl_elem_value *ucontrol) | ||
1779 | { | ||
1780 | struct echoaudio *chip; | ||
1781 | int detected, clocks, bit, src; | ||
1782 | |||
1783 | chip = snd_kcontrol_chip(kcontrol); | ||
1784 | ucontrol->value.integer.value[0] = num_busses_in(chip); | ||
1785 | ucontrol->value.integer.value[1] = num_analog_busses_in(chip); | ||
1786 | ucontrol->value.integer.value[2] = num_busses_out(chip); | ||
1787 | ucontrol->value.integer.value[3] = num_analog_busses_out(chip); | ||
1788 | ucontrol->value.integer.value[4] = num_pipes_out(chip); | ||
1789 | |||
1790 | /* Compute the bitmask of the currently valid input clocks */ | ||
1791 | detected = detect_input_clocks(chip); | ||
1792 | clocks = 0; | ||
1793 | src = chip->num_clock_sources - 1; | ||
1794 | for (bit = ECHO_CLOCK_NUMBER - 1; bit >= 0; bit--) | ||
1795 | if (detected & (1 << bit)) | ||
1796 | for (; src >= 0; src--) | ||
1797 | if (bit == chip->clock_source_list[src]) { | ||
1798 | clocks |= 1 << src; | ||
1799 | break; | ||
1800 | } | ||
1801 | ucontrol->value.integer.value[5] = clocks; | ||
1802 | |||
1803 | return 0; | ||
1804 | } | ||
1805 | |||
1806 | static struct snd_kcontrol_new snd_echo_channels_info __devinitdata = { | ||
1807 | .name = "Channels info", | ||
1808 | .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, | ||
1809 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | ||
1810 | .info = snd_echo_channels_info_info, | ||
1811 | .get = snd_echo_channels_info_get, | ||
1812 | }; | ||
1813 | |||
1814 | |||
1815 | |||
1816 | |||
1817 | /****************************************************************************** | ||
1818 | IRQ Handler | ||
1819 | ******************************************************************************/ | ||
1820 | |||
1821 | static irqreturn_t snd_echo_interrupt(int irq, void *dev_id, | ||
1822 | struct pt_regs *regs) | ||
1823 | { | ||
1824 | struct echoaudio *chip = dev_id; | ||
1825 | struct snd_pcm_substream *substream; | ||
1826 | int period, ss, st; | ||
1827 | |||
1828 | spin_lock(&chip->lock); | ||
1829 | st = service_irq(chip); | ||
1830 | if (st < 0) { | ||
1831 | spin_unlock(&chip->lock); | ||
1832 | return IRQ_NONE; | ||
1833 | } | ||
1834 | /* The hardware doesn't tell us which substream caused the irq, | ||
1835 | thus we have to check all running substreams. */ | ||
1836 | for (ss = 0; ss < DSP_MAXPIPES; ss++) { | ||
1837 | if ((substream = chip->substream[ss])) { | ||
1838 | period = pcm_pointer(substream) / | ||
1839 | substream->runtime->period_size; | ||
1840 | if (period != chip->last_period[ss]) { | ||
1841 | chip->last_period[ss] = period; | ||
1842 | spin_unlock(&chip->lock); | ||
1843 | snd_pcm_period_elapsed(substream); | ||
1844 | spin_lock(&chip->lock); | ||
1845 | } | ||
1846 | } | ||
1847 | } | ||
1848 | spin_unlock(&chip->lock); | ||
1849 | |||
1850 | #ifdef ECHOCARD_HAS_MIDI | ||
1851 | if (st > 0 && chip->midi_in) { | ||
1852 | snd_rawmidi_receive(chip->midi_in, chip->midi_buffer, st); | ||
1853 | DE_MID(("rawmidi_iread=%d\n", st)); | ||
1854 | } | ||
1855 | #endif | ||
1856 | return IRQ_HANDLED; | ||
1857 | } | ||
1858 | |||
1859 | |||
1860 | |||
1861 | |||
1862 | /****************************************************************************** | ||
1863 | Module construction / destruction | ||
1864 | ******************************************************************************/ | ||
1865 | |||
1866 | static int snd_echo_free(struct echoaudio *chip) | ||
1867 | { | ||
1868 | DE_INIT(("Stop DSP...\n")); | ||
1869 | if (chip->comm_page) { | ||
1870 | rest_in_peace(chip); | ||
1871 | snd_dma_free_pages(&chip->commpage_dma_buf); | ||
1872 | } | ||
1873 | DE_INIT(("Stopped.\n")); | ||
1874 | |||
1875 | if (chip->irq >= 0) | ||
1876 | free_irq(chip->irq, (void *)chip); | ||
1877 | |||
1878 | if (chip->dsp_registers) | ||
1879 | iounmap(chip->dsp_registers); | ||
1880 | |||
1881 | if (chip->iores) | ||
1882 | release_and_free_resource(chip->iores); | ||
1883 | |||
1884 | DE_INIT(("MMIO freed.\n")); | ||
1885 | |||
1886 | pci_disable_device(chip->pci); | ||
1887 | |||
1888 | /* release chip data */ | ||
1889 | kfree(chip); | ||
1890 | DE_INIT(("Chip freed.\n")); | ||
1891 | return 0; | ||
1892 | } | ||
1893 | |||
1894 | |||
1895 | |||
1896 | static int snd_echo_dev_free(struct snd_device *device) | ||
1897 | { | ||
1898 | struct echoaudio *chip = device->device_data; | ||
1899 | |||
1900 | DE_INIT(("snd_echo_dev_free()...\n")); | ||
1901 | return snd_echo_free(chip); | ||
1902 | } | ||
1903 | |||
1904 | |||
1905 | |||
1906 | /* <--snd_echo_probe() */ | ||
1907 | static __devinit int snd_echo_create(struct snd_card *card, | ||
1908 | struct pci_dev *pci, | ||
1909 | struct echoaudio **rchip) | ||
1910 | { | ||
1911 | struct echoaudio *chip; | ||
1912 | int err; | ||
1913 | size_t sz; | ||
1914 | static struct snd_device_ops ops = { | ||
1915 | .dev_free = snd_echo_dev_free, | ||
1916 | }; | ||
1917 | |||
1918 | *rchip = NULL; | ||
1919 | |||
1920 | pci_write_config_byte(pci, PCI_LATENCY_TIMER, 0xC0); | ||
1921 | |||
1922 | if ((err = pci_enable_device(pci)) < 0) | ||
1923 | return err; | ||
1924 | pci_set_master(pci); | ||
1925 | |||
1926 | /* allocate a chip-specific data */ | ||
1927 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | ||
1928 | if (!chip) { | ||
1929 | pci_disable_device(pci); | ||
1930 | return -ENOMEM; | ||
1931 | } | ||
1932 | DE_INIT(("chip=%p\n", chip)); | ||
1933 | |||
1934 | spin_lock_init(&chip->lock); | ||
1935 | chip->card = card; | ||
1936 | chip->pci = pci; | ||
1937 | chip->irq = -1; | ||
1938 | |||
1939 | /* PCI resource allocation */ | ||
1940 | chip->dsp_registers_phys = pci_resource_start(pci, 0); | ||
1941 | sz = pci_resource_len(pci, 0); | ||
1942 | if (sz > PAGE_SIZE) | ||
1943 | sz = PAGE_SIZE; /* We map only the required part */ | ||
1944 | |||
1945 | if ((chip->iores = request_mem_region(chip->dsp_registers_phys, sz, | ||
1946 | ECHOCARD_NAME)) == NULL) { | ||
1947 | snd_echo_free(chip); | ||
1948 | snd_printk(KERN_ERR "cannot get memory region\n"); | ||
1949 | return -EBUSY; | ||
1950 | } | ||
1951 | chip->dsp_registers = (volatile u32 __iomem *) | ||
1952 | ioremap_nocache(chip->dsp_registers_phys, sz); | ||
1953 | |||
1954 | if (request_irq(pci->irq, snd_echo_interrupt, SA_INTERRUPT | SA_SHIRQ, | ||
1955 | ECHOCARD_NAME, (void *)chip)) { | ||
1956 | snd_echo_free(chip); | ||
1957 | snd_printk(KERN_ERR "cannot grab irq\n"); | ||
1958 | return -EBUSY; | ||
1959 | } | ||
1960 | chip->irq = pci->irq; | ||
1961 | DE_INIT(("pci=%p irq=%d subdev=%04x Init hardware...\n", | ||
1962 | chip->pci, chip->irq, chip->pci->subsystem_device)); | ||
1963 | |||
1964 | /* Create the DSP comm page - this is the area of memory used for most | ||
1965 | of the communication with the DSP, which accesses it via bus mastering */ | ||
1966 | if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), | ||
1967 | sizeof(struct comm_page), | ||
1968 | &chip->commpage_dma_buf) < 0) { | ||
1969 | snd_echo_free(chip); | ||
1970 | snd_printk(KERN_ERR "cannot allocate the comm page\n"); | ||
1971 | return -ENOMEM; | ||
1972 | } | ||
1973 | chip->comm_page_phys = chip->commpage_dma_buf.addr; | ||
1974 | chip->comm_page = (struct comm_page *)chip->commpage_dma_buf.area; | ||
1975 | |||
1976 | err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device); | ||
1977 | if (err) { | ||
1978 | DE_INIT(("init_hw err=%d\n", err)); | ||
1979 | snd_echo_free(chip); | ||
1980 | return err; | ||
1981 | } | ||
1982 | DE_INIT(("Card init OK\n")); | ||
1983 | |||
1984 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { | ||
1985 | snd_echo_free(chip); | ||
1986 | return err; | ||
1987 | } | ||
1988 | atomic_set(&chip->opencount, 0); | ||
1989 | init_MUTEX(&chip->mode_mutex); | ||
1990 | chip->can_set_rate = 1; | ||
1991 | *rchip = chip; | ||
1992 | /* Init done ! */ | ||
1993 | return 0; | ||
1994 | } | ||
1995 | |||
1996 | |||
1997 | |||
1998 | /* constructor */ | ||
1999 | static int __devinit snd_echo_probe(struct pci_dev *pci, | ||
2000 | const struct pci_device_id *pci_id) | ||
2001 | { | ||
2002 | static int dev; | ||
2003 | struct snd_card *card; | ||
2004 | struct echoaudio *chip; | ||
2005 | char *dsp; | ||
2006 | int i, err; | ||
2007 | |||
2008 | if (dev >= SNDRV_CARDS) | ||
2009 | return -ENODEV; | ||
2010 | if (!enable[dev]) { | ||
2011 | dev++; | ||
2012 | return -ENOENT; | ||
2013 | } | ||
2014 | |||
2015 | DE_INIT(("Echoaudio driver starting...\n")); | ||
2016 | i = 0; | ||
2017 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | ||
2018 | if (card == NULL) | ||
2019 | return -ENOMEM; | ||
2020 | |||
2021 | if ((err = snd_echo_create(card, pci, &chip)) < 0) { | ||
2022 | snd_card_free(card); | ||
2023 | return err; | ||
2024 | } | ||
2025 | |||
2026 | strcpy(card->driver, "Echo_" ECHOCARD_NAME); | ||
2027 | strcpy(card->shortname, chip->card_name); | ||
2028 | |||
2029 | dsp = "56301"; | ||
2030 | if (pci_id->device == 0x3410) | ||
2031 | dsp = "56361"; | ||
2032 | |||
2033 | sprintf(card->longname, "%s rev.%d (DSP%s) at 0x%lx irq %i", | ||
2034 | card->shortname, pci_id->subdevice & 0x000f, dsp, | ||
2035 | chip->dsp_registers_phys, chip->irq); | ||
2036 | |||
2037 | if ((err = snd_echo_new_pcm(chip)) < 0) { | ||
2038 | snd_printk(KERN_ERR "new pcm error %d\n", err); | ||
2039 | snd_card_free(card); | ||
2040 | return err; | ||
2041 | } | ||
2042 | |||
2043 | #ifdef ECHOCARD_HAS_MIDI | ||
2044 | if (chip->has_midi) { /* Some Mia's do not have midi */ | ||
2045 | if ((err = snd_echo_midi_create(card, chip)) < 0) { | ||
2046 | snd_printk(KERN_ERR "new midi error %d\n", err); | ||
2047 | snd_card_free(card); | ||
2048 | return err; | ||
2049 | } | ||
2050 | } | ||
2051 | #endif | ||
2052 | |||
2053 | #ifdef ECHOCARD_HAS_VMIXER | ||
2054 | snd_echo_vmixer.count = num_pipes_out(chip) * num_busses_out(chip); | ||
2055 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_line_output_gain, chip))) < 0) | ||
2056 | goto ctl_error; | ||
2057 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vmixer, chip))) < 0) | ||
2058 | goto ctl_error; | ||
2059 | #else | ||
2060 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_pcm_output_gain, chip))) < 0) | ||
2061 | goto ctl_error; | ||
2062 | #endif | ||
2063 | |||
2064 | #ifdef ECHOCARD_HAS_INPUT_GAIN | ||
2065 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_line_input_gain, chip))) < 0) | ||
2066 | goto ctl_error; | ||
2067 | #endif | ||
2068 | |||
2069 | #ifdef ECHOCARD_HAS_INPUT_NOMINAL_LEVEL | ||
2070 | if (!chip->hasnt_input_nominal_level) | ||
2071 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_intput_nominal_level, chip))) < 0) | ||
2072 | goto ctl_error; | ||
2073 | #endif | ||
2074 | |||
2075 | #ifdef ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL | ||
2076 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_output_nominal_level, chip))) < 0) | ||
2077 | goto ctl_error; | ||
2078 | #endif | ||
2079 | |||
2080 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vumeters_switch, chip))) < 0) | ||
2081 | goto ctl_error; | ||
2082 | |||
2083 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vumeters, chip))) < 0) | ||
2084 | goto ctl_error; | ||
2085 | |||
2086 | #ifdef ECHOCARD_HAS_MONITOR | ||
2087 | snd_echo_monitor_mixer.count = num_busses_in(chip) * num_busses_out(chip); | ||
2088 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_monitor_mixer, chip))) < 0) | ||
2089 | goto ctl_error; | ||
2090 | #endif | ||
2091 | |||
2092 | #ifdef ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE | ||
2093 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_automute_switch, chip))) < 0) | ||
2094 | goto ctl_error; | ||
2095 | #endif | ||
2096 | |||
2097 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_channels_info, chip))) < 0) | ||
2098 | goto ctl_error; | ||
2099 | |||
2100 | #ifdef ECHOCARD_HAS_DIGITAL_MODE_SWITCH | ||
2101 | /* Creates a list of available digital modes */ | ||
2102 | chip->num_digital_modes = 0; | ||
2103 | for (i = 0; i < 6; i++) | ||
2104 | if (chip->digital_modes & (1 << i)) | ||
2105 | chip->digital_mode_list[chip->num_digital_modes++] = i; | ||
2106 | |||
2107 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_digital_mode_switch, chip))) < 0) | ||
2108 | goto ctl_error; | ||
2109 | #endif /* ECHOCARD_HAS_DIGITAL_MODE_SWITCH */ | ||
2110 | |||
2111 | #ifdef ECHOCARD_HAS_EXTERNAL_CLOCK | ||
2112 | /* Creates a list of available clock sources */ | ||
2113 | chip->num_clock_sources = 0; | ||
2114 | for (i = 0; i < 10; i++) | ||
2115 | if (chip->input_clock_types & (1 << i)) | ||
2116 | chip->clock_source_list[chip->num_clock_sources++] = i; | ||
2117 | |||
2118 | if (chip->num_clock_sources > 1) { | ||
2119 | chip->clock_src_ctl = snd_ctl_new1(&snd_echo_clock_source_switch, chip); | ||
2120 | if ((err = snd_ctl_add(chip->card, chip->clock_src_ctl)) < 0) | ||
2121 | goto ctl_error; | ||
2122 | } | ||
2123 | #endif /* ECHOCARD_HAS_EXTERNAL_CLOCK */ | ||
2124 | |||
2125 | #ifdef ECHOCARD_HAS_DIGITAL_IO | ||
2126 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_spdif_mode_switch, chip))) < 0) | ||
2127 | goto ctl_error; | ||
2128 | #endif | ||
2129 | |||
2130 | #ifdef ECHOCARD_HAS_PHANTOM_POWER | ||
2131 | if (chip->has_phantom_power) | ||
2132 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_phantom_power_switch, chip))) < 0) | ||
2133 | goto ctl_error; | ||
2134 | #endif | ||
2135 | |||
2136 | if ((err = snd_card_register(card)) < 0) { | ||
2137 | snd_card_free(card); | ||
2138 | goto ctl_error; | ||
2139 | } | ||
2140 | snd_printk(KERN_INFO "Card registered: %s\n", card->longname); | ||
2141 | |||
2142 | pci_set_drvdata(pci, chip); | ||
2143 | dev++; | ||
2144 | return 0; | ||
2145 | |||
2146 | ctl_error: | ||
2147 | snd_printk(KERN_ERR "new control error %d\n", err); | ||
2148 | snd_card_free(card); | ||
2149 | return err; | ||
2150 | } | ||
2151 | |||
2152 | |||
2153 | |||
2154 | static void __devexit snd_echo_remove(struct pci_dev *pci) | ||
2155 | { | ||
2156 | struct echoaudio *chip; | ||
2157 | |||
2158 | chip = pci_get_drvdata(pci); | ||
2159 | if (chip) | ||
2160 | snd_card_free(chip->card); | ||
2161 | pci_set_drvdata(pci, NULL); | ||
2162 | } | ||
2163 | |||
2164 | |||
2165 | |||
2166 | /****************************************************************************** | ||
2167 | Everything starts and ends here | ||
2168 | ******************************************************************************/ | ||
2169 | |||
2170 | /* pci_driver definition */ | ||
2171 | static struct pci_driver driver = { | ||
2172 | .name = "Echoaudio " ECHOCARD_NAME, | ||
2173 | .id_table = snd_echo_ids, | ||
2174 | .probe = snd_echo_probe, | ||
2175 | .remove = __devexit_p(snd_echo_remove), | ||
2176 | }; | ||
2177 | |||
2178 | |||
2179 | |||
2180 | /* initialization of the module */ | ||
2181 | static int __init alsa_card_echo_init(void) | ||
2182 | { | ||
2183 | return pci_register_driver(&driver); | ||
2184 | } | ||
2185 | |||
2186 | |||
2187 | |||
2188 | /* clean up the module */ | ||
2189 | static void __exit alsa_card_echo_exit(void) | ||
2190 | { | ||
2191 | pci_unregister_driver(&driver); | ||
2192 | } | ||
2193 | |||
2194 | |||
2195 | module_init(alsa_card_echo_init) | ||
2196 | module_exit(alsa_card_echo_exit) | ||
diff --git a/sound/pci/echoaudio/echoaudio.h b/sound/pci/echoaudio/echoaudio.h new file mode 100644 index 000000000000..7e88c968e22f --- /dev/null +++ b/sound/pci/echoaudio/echoaudio.h | |||
@@ -0,0 +1,590 @@ | |||
1 | /**************************************************************************** | ||
2 | |||
3 | Copyright Echo Digital Audio Corporation (c) 1998 - 2004 | ||
4 | All rights reserved | ||
5 | www.echoaudio.com | ||
6 | |||
7 | This file is part of Echo Digital Audio's generic driver library. | ||
8 | |||
9 | Echo Digital Audio's generic driver library is free software; | ||
10 | you can redistribute it and/or modify it under the terms of | ||
11 | the GNU General Public License as published by the Free Software | ||
12 | Foundation. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, | ||
22 | MA 02111-1307, USA. | ||
23 | |||
24 | **************************************************************************** | ||
25 | |||
26 | Translation from C++ and adaptation for use in ALSA-Driver | ||
27 | were made by Giuliano Pochini <pochini@shiny.it> | ||
28 | |||
29 | **************************************************************************** | ||
30 | |||
31 | |||
32 | Here's a block diagram of how most of the cards work: | ||
33 | |||
34 | +-----------+ | ||
35 | record | |<-------------------- Inputs | ||
36 | <-------| | | | ||
37 | PCI | Transport | | | ||
38 | bus | engine | \|/ | ||
39 | ------->| | +-------+ | ||
40 | play | |--->|monitor|-------> Outputs | ||
41 | +-----------+ | mixer | | ||
42 | +-------+ | ||
43 | |||
44 | The lines going to and from the PCI bus represent "pipes". A pipe performs | ||
45 | audio transport - moving audio data to and from buffers on the host via | ||
46 | bus mastering. | ||
47 | |||
48 | The inputs and outputs on the right represent input and output "busses." | ||
49 | A bus is a physical, real connection to the outside world. An example | ||
50 | of a bus would be the 1/4" analog connectors on the back of Layla or | ||
51 | an RCA S/PDIF connector. | ||
52 | |||
53 | For most cards, there is a one-to-one correspondence between outputs | ||
54 | and busses; that is, each individual pipe is hard-wired to a single bus. | ||
55 | |||
56 | Cards that work this way are Darla20, Gina20, Layla20, Darla24, Gina24, | ||
57 | Layla24, Mona, and Indigo. | ||
58 | |||
59 | |||
60 | Mia has a feature called "virtual outputs." | ||
61 | |||
62 | |||
63 | +-----------+ | ||
64 | record | |<----------------------------- Inputs | ||
65 | <-------| | | | ||
66 | PCI | Transport | | | ||
67 | bus | engine | \|/ | ||
68 | ------->| | +------+ +-------+ | ||
69 | play | |-->|vmixer|-->|monitor|-------> Outputs | ||
70 | +-----------+ +------+ | mixer | | ||
71 | +-------+ | ||
72 | |||
73 | |||
74 | Obviously, the difference here is the box labeled "vmixer." Vmixer is | ||
75 | short for "virtual output mixer." For Mia, pipes are *not* hard-wired | ||
76 | to a single bus; the vmixer lets you mix any pipe to any bus in any | ||
77 | combination. | ||
78 | |||
79 | Note, however, that the left-hand side of the diagram is unchanged. | ||
80 | Transport works exactly the same way - the difference is in the mixer stage. | ||
81 | |||
82 | |||
83 | Pipes and busses are numbered starting at zero. | ||
84 | |||
85 | |||
86 | |||
87 | Pipe index | ||
88 | ========== | ||
89 | |||
90 | A number of calls in CEchoGals refer to a "pipe index". A pipe index is | ||
91 | a unique number for a pipe that unambiguously refers to a playback or record | ||
92 | pipe. Pipe indices are numbered starting with analog outputs, followed by | ||
93 | digital outputs, then analog inputs, then digital inputs. | ||
94 | |||
95 | Take Gina24 as an example: | ||
96 | |||
97 | Pipe index | ||
98 | |||
99 | 0-7 Analog outputs (0 .. FirstDigitalBusOut-1) | ||
100 | 8-15 Digital outputs (FirstDigitalBusOut .. NumBussesOut-1) | ||
101 | 16-17 Analog inputs | ||
102 | 18-25 Digital inputs | ||
103 | |||
104 | |||
105 | You get the pipe index by calling CEchoGals::OpenAudio; the other transport | ||
106 | functions take the pipe index as a parameter. If you need a pipe index for | ||
107 | some other reason, use the handy Makepipe_index method. | ||
108 | |||
109 | |||
110 | Some calls take a CChannelMask parameter; CChannelMask is a handy way to | ||
111 | group pipe indices. | ||
112 | |||
113 | |||
114 | |||
115 | Digital mode switch | ||
116 | =================== | ||
117 | |||
118 | Some cards (right now, Gina24, Layla24, and Mona) have a Digital Mode Switch | ||
119 | or DMS. Cards with a DMS can be set to one of three mutually exclusive | ||
120 | digital modes: S/PDIF RCA, S/PDIF optical, or ADAT optical. | ||
121 | |||
122 | This may create some confusion since ADAT optical is 8 channels wide and | ||
123 | S/PDIF is only two channels wide. Gina24, Layla24, and Mona handle this | ||
124 | by acting as if they always have 8 digital outs and ins. If you are in | ||
125 | either S/PDIF mode, the last 6 channels don't do anything - data sent | ||
126 | out these channels is thrown away and you will always record zeros. | ||
127 | |||
128 | Note that with Gina24, Layla24, and Mona, sample rates above 50 kHz are | ||
129 | only available if you have the card configured for S/PDIF optical or S/PDIF | ||
130 | RCA. | ||
131 | |||
132 | |||
133 | |||
134 | Double speed mode | ||
135 | ================= | ||
136 | |||
137 | Some of the cards support 88.2 kHz and 96 kHz sampling (Darla24, Gina24, | ||
138 | Layla24, Mona, Mia, and Indigo). For these cards, the driver sometimes has | ||
139 | to worry about "double speed mode"; double speed mode applies whenever the | ||
140 | sampling rate is above 50 kHz. | ||
141 | |||
142 | For instance, Mona and Layla24 support word clock sync. However, they | ||
143 | actually support two different word clock modes - single speed (below | ||
144 | 50 kHz) and double speed (above 50 kHz). The hardware detects if a single | ||
145 | or double speed word clock signal is present; the generic code uses that | ||
146 | information to determine which mode to use. | ||
147 | |||
148 | The generic code takes care of all this for you. | ||
149 | */ | ||
150 | |||
151 | |||
152 | #ifndef _ECHOAUDIO_H_ | ||
153 | #define _ECHOAUDIO_H_ | ||
154 | |||
155 | |||
156 | #define TRUE 1 | ||
157 | #define FALSE 0 | ||
158 | |||
159 | #include "echoaudio_dsp.h" | ||
160 | |||
161 | |||
162 | |||
163 | /*********************************************************************** | ||
164 | |||
165 | PCI configuration space | ||
166 | |||
167 | ***********************************************************************/ | ||
168 | |||
169 | /* | ||
170 | * PCI vendor ID and device IDs for the hardware | ||
171 | */ | ||
172 | #define VENDOR_ID 0x1057 | ||
173 | #define DEVICE_ID_56301 0x1801 | ||
174 | #define DEVICE_ID_56361 0x3410 | ||
175 | #define SUBVENDOR_ID 0xECC0 | ||
176 | |||
177 | |||
178 | /* | ||
179 | * Valid Echo PCI subsystem card IDs | ||
180 | */ | ||
181 | #define DARLA20 0x0010 | ||
182 | #define GINA20 0x0020 | ||
183 | #define LAYLA20 0x0030 | ||
184 | #define DARLA24 0x0040 | ||
185 | #define GINA24 0x0050 | ||
186 | #define LAYLA24 0x0060 | ||
187 | #define MONA 0x0070 | ||
188 | #define MIA 0x0080 | ||
189 | #define INDIGO 0x0090 | ||
190 | #define INDIGO_IO 0x00a0 | ||
191 | #define INDIGO_DJ 0x00b0 | ||
192 | #define ECHO3G 0x0100 | ||
193 | |||
194 | |||
195 | /************************************************************************ | ||
196 | |||
197 | Array sizes and so forth | ||
198 | |||
199 | ***********************************************************************/ | ||
200 | |||
201 | /* | ||
202 | * Sizes | ||
203 | */ | ||
204 | #define ECHO_MAXAUDIOINPUTS 32 /* Max audio input channels */ | ||
205 | #define ECHO_MAXAUDIOOUTPUTS 32 /* Max audio output channels */ | ||
206 | #define ECHO_MAXAUDIOPIPES 32 /* Max number of input and output | ||
207 | * pipes */ | ||
208 | #define E3G_MAX_OUTPUTS 16 | ||
209 | #define ECHO_MAXMIDIJACKS 1 /* Max MIDI ports */ | ||
210 | #define ECHO_MIDI_QUEUE_SZ 512 /* Max MIDI input queue entries */ | ||
211 | #define ECHO_MTC_QUEUE_SZ 32 /* Max MIDI time code input queue | ||
212 | * entries */ | ||
213 | |||
214 | /* | ||
215 | * MIDI activity indicator timeout | ||
216 | */ | ||
217 | #define MIDI_ACTIVITY_TIMEOUT_USEC 200000 | ||
218 | |||
219 | |||
220 | /**************************************************************************** | ||
221 | |||
222 | Clocks | ||
223 | |||
224 | *****************************************************************************/ | ||
225 | |||
226 | /* | ||
227 | * Clock numbers | ||
228 | */ | ||
229 | #define ECHO_CLOCK_INTERNAL 0 | ||
230 | #define ECHO_CLOCK_WORD 1 | ||
231 | #define ECHO_CLOCK_SUPER 2 | ||
232 | #define ECHO_CLOCK_SPDIF 3 | ||
233 | #define ECHO_CLOCK_ADAT 4 | ||
234 | #define ECHO_CLOCK_ESYNC 5 | ||
235 | #define ECHO_CLOCK_ESYNC96 6 | ||
236 | #define ECHO_CLOCK_MTC 7 | ||
237 | #define ECHO_CLOCK_NUMBER 8 | ||
238 | #define ECHO_CLOCKS 0xffff | ||
239 | |||
240 | /* | ||
241 | * Clock bit numbers - used to report capabilities and whatever clocks | ||
242 | * are being detected dynamically. | ||
243 | */ | ||
244 | #define ECHO_CLOCK_BIT_INTERNAL (1 << ECHO_CLOCK_INTERNAL) | ||
245 | #define ECHO_CLOCK_BIT_WORD (1 << ECHO_CLOCK_WORD) | ||
246 | #define ECHO_CLOCK_BIT_SUPER (1 << ECHO_CLOCK_SUPER) | ||
247 | #define ECHO_CLOCK_BIT_SPDIF (1 << ECHO_CLOCK_SPDIF) | ||
248 | #define ECHO_CLOCK_BIT_ADAT (1 << ECHO_CLOCK_ADAT) | ||
249 | #define ECHO_CLOCK_BIT_ESYNC (1 << ECHO_CLOCK_ESYNC) | ||
250 | #define ECHO_CLOCK_BIT_ESYNC96 (1 << ECHO_CLOCK_ESYNC96) | ||
251 | #define ECHO_CLOCK_BIT_MTC (1<<ECHO_CLOCK_MTC) | ||
252 | |||
253 | |||
254 | /*************************************************************************** | ||
255 | |||
256 | Digital modes | ||
257 | |||
258 | ****************************************************************************/ | ||
259 | |||
260 | /* | ||
261 | * Digital modes for Mona, Layla24, and Gina24 | ||
262 | */ | ||
263 | #define DIGITAL_MODE_NONE 0xFF | ||
264 | #define DIGITAL_MODE_SPDIF_RCA 0 | ||
265 | #define DIGITAL_MODE_SPDIF_OPTICAL 1 | ||
266 | #define DIGITAL_MODE_ADAT 2 | ||
267 | #define DIGITAL_MODE_SPDIF_CDROM 3 | ||
268 | #define DIGITAL_MODES 4 | ||
269 | |||
270 | /* | ||
271 | * Digital mode capability masks | ||
272 | */ | ||
273 | #define ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA (1 << DIGITAL_MODE_SPDIF_RCA) | ||
274 | #define ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL (1 << DIGITAL_MODE_SPDIF_OPTICAL) | ||
275 | #define ECHOCAPS_HAS_DIGITAL_MODE_ADAT (1 << DIGITAL_MODE_ADAT) | ||
276 | #define ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_CDROM (1 << DIGITAL_MODE_SPDIF_CDROM) | ||
277 | |||
278 | |||
279 | #define EXT_3GBOX_NC 0x01 /* 3G box not connected */ | ||
280 | #define EXT_3GBOX_NOT_SET 0x02 /* 3G box not detected yet */ | ||
281 | |||
282 | |||
283 | #define ECHOGAIN_MUTED (-128) /* Minimum possible gain */ | ||
284 | #define ECHOGAIN_MINOUT (-128) /* Min output gain (dB) */ | ||
285 | #define ECHOGAIN_MAXOUT (6) /* Max output gain (dB) */ | ||
286 | #define ECHOGAIN_MININP (-50) /* Min input gain (0.5 dB) */ | ||
287 | #define ECHOGAIN_MAXINP (50) /* Max input gain (0.5 dB) */ | ||
288 | |||
289 | #define PIPE_STATE_STOPPED 0 /* Pipe has been reset */ | ||
290 | #define PIPE_STATE_PAUSED 1 /* Pipe has been stopped */ | ||
291 | #define PIPE_STATE_STARTED 2 /* Pipe has been started */ | ||
292 | #define PIPE_STATE_PENDING 3 /* Pipe has pending start */ | ||
293 | |||
294 | |||
295 | /* Debug initialization */ | ||
296 | #ifdef CONFIG_SND_DEBUG | ||
297 | #define DE_INIT(x) snd_printk x | ||
298 | #else | ||
299 | #define DE_INIT(x) | ||
300 | #endif | ||
301 | |||
302 | /* Debug hw_params callbacks */ | ||
303 | #ifdef CONFIG_SND_DEBUG | ||
304 | #define DE_HWP(x) snd_printk x | ||
305 | #else | ||
306 | #define DE_HWP(x) | ||
307 | #endif | ||
308 | |||
309 | /* Debug normal activity (open, start, stop...) */ | ||
310 | #ifdef CONFIG_SND_DEBUG | ||
311 | #define DE_ACT(x) snd_printk x | ||
312 | #else | ||
313 | #define DE_ACT(x) | ||
314 | #endif | ||
315 | |||
316 | /* Debug midi activity */ | ||
317 | #ifdef CONFIG_SND_DEBUG | ||
318 | #define DE_MID(x) snd_printk x | ||
319 | #else | ||
320 | #define DE_MID(x) | ||
321 | #endif | ||
322 | |||
323 | |||
324 | struct audiopipe { | ||
325 | volatile u32 *dma_counter; /* Commpage register that contains | ||
326 | * the current dma position | ||
327 | * (lower 32 bits only) | ||
328 | */ | ||
329 | u32 last_counter; /* The last position, which is used | ||
330 | * to compute... | ||
331 | */ | ||
332 | u32 position; /* ...the number of bytes tranferred | ||
333 | * by the DMA engine, modulo the | ||
334 | * buffer size | ||
335 | */ | ||
336 | short index; /* Index of the first channel or <0 | ||
337 | * if hw is not configured yet | ||
338 | */ | ||
339 | short interleave; | ||
340 | struct snd_dma_buffer sgpage; /* Room for the scatter-gather list */ | ||
341 | struct snd_pcm_hardware hw; | ||
342 | struct snd_pcm_hw_constraint_list constr; | ||
343 | short sglist_head; | ||
344 | char state; /* pipe state */ | ||
345 | }; | ||
346 | |||
347 | |||
348 | struct audioformat { | ||
349 | u8 interleave; /* How the data is arranged in memory: | ||
350 | * mono = 1, stereo = 2, ... | ||
351 | */ | ||
352 | u8 bits_per_sample; /* 8, 16, 24, 32 (24 bits left aligned) */ | ||
353 | char mono_to_stereo; /* Only used if interleave is 1 and | ||
354 | * if this is an output pipe. | ||
355 | */ | ||
356 | char data_are_bigendian; /* 1 = big endian, 0 = little endian */ | ||
357 | }; | ||
358 | |||
359 | |||
360 | struct echoaudio { | ||
361 | spinlock_t lock; | ||
362 | struct snd_pcm_substream *substream[DSP_MAXPIPES]; | ||
363 | int last_period[DSP_MAXPIPES]; | ||
364 | struct semaphore mode_mutex; | ||
365 | u16 num_digital_modes, digital_mode_list[6]; | ||
366 | u16 num_clock_sources, clock_source_list[10]; | ||
367 | atomic_t opencount; | ||
368 | struct snd_kcontrol *clock_src_ctl; | ||
369 | struct snd_pcm *analog_pcm, *digital_pcm; | ||
370 | struct snd_card *card; | ||
371 | const char *card_name; | ||
372 | struct pci_dev *pci; | ||
373 | unsigned long dsp_registers_phys; | ||
374 | struct resource *iores; | ||
375 | struct snd_dma_buffer commpage_dma_buf; | ||
376 | int irq; | ||
377 | #ifdef ECHOCARD_HAS_MIDI | ||
378 | struct snd_rawmidi *rmidi; | ||
379 | struct snd_rawmidi_substream *midi_in, *midi_out; | ||
380 | #endif | ||
381 | struct timer_list timer; | ||
382 | char tinuse; /* Timer in use */ | ||
383 | char midi_full; /* MIDI output buffer is full */ | ||
384 | char can_set_rate; | ||
385 | char rate_set; | ||
386 | |||
387 | /* This stuff is used mainly by the lowlevel code */ | ||
388 | struct comm_page *comm_page; /* Virtual address of the memory | ||
389 | * seen by DSP | ||
390 | */ | ||
391 | u32 pipe_alloc_mask; /* Bitmask of allocated pipes */ | ||
392 | u32 pipe_cyclic_mask; /* Bitmask of pipes with cyclic | ||
393 | * buffers | ||
394 | */ | ||
395 | u32 sample_rate; /* Card sample rate in Hz */ | ||
396 | u8 digital_mode; /* Current digital mode | ||
397 | * (see DIGITAL_MODE_*) | ||
398 | */ | ||
399 | u8 spdif_status; /* Gina20, Darla20, Darla24 - only */ | ||
400 | u8 clock_state; /* Gina20, Darla20, Darla24 - only */ | ||
401 | u8 input_clock; /* Currently selected sample clock | ||
402 | * source | ||
403 | */ | ||
404 | u8 output_clock; /* Layla20 only */ | ||
405 | char meters_enabled; /* VU-meters status */ | ||
406 | char asic_loaded; /* Set TRUE when ASIC loaded */ | ||
407 | char bad_board; /* Set TRUE if DSP won't load */ | ||
408 | char professional_spdif; /* 0 = consumer; 1 = professional */ | ||
409 | char non_audio_spdif; /* 3G - only */ | ||
410 | char digital_in_automute; /* Gina24, Layla24, Mona - only */ | ||
411 | char has_phantom_power; | ||
412 | char hasnt_input_nominal_level; /* Gina3G */ | ||
413 | char phantom_power; /* Gina3G - only */ | ||
414 | char has_midi; | ||
415 | char midi_input_enabled; | ||
416 | |||
417 | #ifdef ECHOCARD_ECHO3G | ||
418 | /* External module -dependent pipe and bus indexes */ | ||
419 | char px_digital_out, px_analog_in, px_digital_in, px_num; | ||
420 | char bx_digital_out, bx_analog_in, bx_digital_in, bx_num; | ||
421 | #endif | ||
422 | |||
423 | char nominal_level[ECHO_MAXAUDIOPIPES]; /* True == -10dBV | ||
424 | * False == +4dBu */ | ||
425 | s8 input_gain[ECHO_MAXAUDIOINPUTS]; /* Input level -50..+50 | ||
426 | * unit is 0.5dB */ | ||
427 | s8 output_gain[ECHO_MAXAUDIOOUTPUTS]; /* Output level -128..+6 dB | ||
428 | * (-128=muted) */ | ||
429 | s8 monitor_gain[ECHO_MAXAUDIOOUTPUTS][ECHO_MAXAUDIOINPUTS]; | ||
430 | /* -128..+6 dB */ | ||
431 | s8 vmixer_gain[ECHO_MAXAUDIOOUTPUTS][ECHO_MAXAUDIOOUTPUTS]; | ||
432 | /* -128..+6 dB */ | ||
433 | |||
434 | u16 digital_modes; /* Bitmask of supported modes | ||
435 | * (see ECHOCAPS_HAS_DIGITAL_MODE_*) */ | ||
436 | u16 input_clock_types; /* Suppoted input clock types */ | ||
437 | u16 output_clock_types; /* Suppoted output clock types - | ||
438 | * Layla20 only */ | ||
439 | u16 device_id, subdevice_id; | ||
440 | u16 *dsp_code; /* Current DSP code loaded, | ||
441 | * NULL if nothing loaded */ | ||
442 | const struct firmware *dsp_code_to_load;/* DSP code to load */ | ||
443 | const struct firmware *asic_code; /* Current ASIC code */ | ||
444 | u32 comm_page_phys; /* Physical address of the | ||
445 | * memory seen by DSP */ | ||
446 | volatile u32 __iomem *dsp_registers; /* DSP's register base */ | ||
447 | u32 active_mask; /* Chs. active mask or | ||
448 | * punks out */ | ||
449 | |||
450 | #ifdef ECHOCARD_HAS_MIDI | ||
451 | u16 mtc_state; /* State for MIDI input parsing state machine */ | ||
452 | u8 midi_buffer[MIDI_IN_BUFFER_SIZE]; | ||
453 | #endif | ||
454 | }; | ||
455 | |||
456 | |||
457 | static int init_dsp_comm_page(struct echoaudio *chip); | ||
458 | static int init_line_levels(struct echoaudio *chip); | ||
459 | static int free_pipes(struct echoaudio *chip, struct audiopipe *pipe); | ||
460 | static int load_firmware(struct echoaudio *chip); | ||
461 | static int wait_handshake(struct echoaudio *chip); | ||
462 | static int send_vector(struct echoaudio *chip, u32 command); | ||
463 | static int get_firmware(const struct firmware **fw_entry, | ||
464 | const struct firmware *frm, struct echoaudio *chip); | ||
465 | static void free_firmware(const struct firmware *fw_entry); | ||
466 | |||
467 | #ifdef ECHOCARD_HAS_MIDI | ||
468 | static int enable_midi_input(struct echoaudio *chip, char enable); | ||
469 | static int midi_service_irq(struct echoaudio *chip); | ||
470 | static int __devinit snd_echo_midi_create(struct snd_card *card, | ||
471 | struct echoaudio *chip); | ||
472 | #endif | ||
473 | |||
474 | |||
475 | static inline void clear_handshake(struct echoaudio *chip) | ||
476 | { | ||
477 | chip->comm_page->handshake = 0; | ||
478 | } | ||
479 | |||
480 | static inline u32 get_dsp_register(struct echoaudio *chip, u32 index) | ||
481 | { | ||
482 | return readl(&chip->dsp_registers[index]); | ||
483 | } | ||
484 | |||
485 | static inline void set_dsp_register(struct echoaudio *chip, u32 index, | ||
486 | u32 value) | ||
487 | { | ||
488 | writel(value, &chip->dsp_registers[index]); | ||
489 | } | ||
490 | |||
491 | |||
492 | /* Pipe and bus indexes. PX_* and BX_* are defined as chip->px_* and chip->bx_* | ||
493 | for 3G cards because they depend on the external box. They are integer | ||
494 | constants for all other cards. | ||
495 | Never use those defines directly, use the following functions instead. */ | ||
496 | |||
497 | static inline int px_digital_out(const struct echoaudio *chip) | ||
498 | { | ||
499 | return PX_DIGITAL_OUT; | ||
500 | } | ||
501 | |||
502 | static inline int px_analog_in(const struct echoaudio *chip) | ||
503 | { | ||
504 | return PX_ANALOG_IN; | ||
505 | } | ||
506 | |||
507 | static inline int px_digital_in(const struct echoaudio *chip) | ||
508 | { | ||
509 | return PX_DIGITAL_IN; | ||
510 | } | ||
511 | |||
512 | static inline int px_num(const struct echoaudio *chip) | ||
513 | { | ||
514 | return PX_NUM; | ||
515 | } | ||
516 | |||
517 | static inline int bx_digital_out(const struct echoaudio *chip) | ||
518 | { | ||
519 | return BX_DIGITAL_OUT; | ||
520 | } | ||
521 | |||
522 | static inline int bx_analog_in(const struct echoaudio *chip) | ||
523 | { | ||
524 | return BX_ANALOG_IN; | ||
525 | } | ||
526 | |||
527 | static inline int bx_digital_in(const struct echoaudio *chip) | ||
528 | { | ||
529 | return BX_DIGITAL_IN; | ||
530 | } | ||
531 | |||
532 | static inline int bx_num(const struct echoaudio *chip) | ||
533 | { | ||
534 | return BX_NUM; | ||
535 | } | ||
536 | |||
537 | static inline int num_pipes_out(const struct echoaudio *chip) | ||
538 | { | ||
539 | return px_analog_in(chip); | ||
540 | } | ||
541 | |||
542 | static inline int num_pipes_in(const struct echoaudio *chip) | ||
543 | { | ||
544 | return px_num(chip) - px_analog_in(chip); | ||
545 | } | ||
546 | |||
547 | static inline int num_busses_out(const struct echoaudio *chip) | ||
548 | { | ||
549 | return bx_analog_in(chip); | ||
550 | } | ||
551 | |||
552 | static inline int num_busses_in(const struct echoaudio *chip) | ||
553 | { | ||
554 | return bx_num(chip) - bx_analog_in(chip); | ||
555 | } | ||
556 | |||
557 | static inline int num_analog_busses_out(const struct echoaudio *chip) | ||
558 | { | ||
559 | return bx_digital_out(chip); | ||
560 | } | ||
561 | |||
562 | static inline int num_analog_busses_in(const struct echoaudio *chip) | ||
563 | { | ||
564 | return bx_digital_in(chip) - bx_analog_in(chip); | ||
565 | } | ||
566 | |||
567 | static inline int num_digital_busses_out(const struct echoaudio *chip) | ||
568 | { | ||
569 | return num_busses_out(chip) - num_analog_busses_out(chip); | ||
570 | } | ||
571 | |||
572 | static inline int num_digital_busses_in(const struct echoaudio *chip) | ||
573 | { | ||
574 | return num_busses_in(chip) - num_analog_busses_in(chip); | ||
575 | } | ||
576 | |||
577 | /* The monitor array is a one-dimensional array; compute the offset | ||
578 | * into the array */ | ||
579 | static inline int monitor_index(const struct echoaudio *chip, int out, int in) | ||
580 | { | ||
581 | return out * num_busses_in(chip) + in; | ||
582 | } | ||
583 | |||
584 | |||
585 | #ifndef pci_device | ||
586 | #define pci_device(chip) (&chip->pci->dev) | ||
587 | #endif | ||
588 | |||
589 | |||
590 | #endif /* _ECHOAUDIO_H_ */ | ||
diff --git a/sound/pci/echoaudio/echoaudio_3g.c b/sound/pci/echoaudio/echoaudio_3g.c new file mode 100644 index 000000000000..9f439ea459f4 --- /dev/null +++ b/sound/pci/echoaudio/echoaudio_3g.c | |||
@@ -0,0 +1,431 @@ | |||
1 | /**************************************************************************** | ||
2 | |||
3 | Copyright Echo Digital Audio Corporation (c) 1998 - 2004 | ||
4 | All rights reserved | ||
5 | www.echoaudio.com | ||
6 | |||
7 | This file is part of Echo Digital Audio's generic driver library. | ||
8 | |||
9 | Echo Digital Audio's generic driver library is free software; | ||
10 | you can redistribute it and/or modify it under the terms of | ||
11 | the GNU General Public License as published by the Free Software | ||
12 | Foundation. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, | ||
22 | MA 02111-1307, USA. | ||
23 | |||
24 | ************************************************************************* | ||
25 | |||
26 | Translation from C++ and adaptation for use in ALSA-Driver | ||
27 | were made by Giuliano Pochini <pochini@shiny.it> | ||
28 | |||
29 | ****************************************************************************/ | ||
30 | |||
31 | |||
32 | |||
33 | /* These functions are common for all "3G" cards */ | ||
34 | |||
35 | |||
36 | static int check_asic_status(struct echoaudio *chip) | ||
37 | { | ||
38 | u32 box_status; | ||
39 | |||
40 | if (wait_handshake(chip)) | ||
41 | return -EIO; | ||
42 | |||
43 | chip->comm_page->ext_box_status = | ||
44 | __constant_cpu_to_le32(E3G_ASIC_NOT_LOADED); | ||
45 | chip->asic_loaded = FALSE; | ||
46 | clear_handshake(chip); | ||
47 | send_vector(chip, DSP_VC_TEST_ASIC); | ||
48 | |||
49 | if (wait_handshake(chip)) { | ||
50 | chip->dsp_code = NULL; | ||
51 | return -EIO; | ||
52 | } | ||
53 | |||
54 | box_status = le32_to_cpu(chip->comm_page->ext_box_status); | ||
55 | DE_INIT(("box_status=%x\n", box_status)); | ||
56 | if (box_status == E3G_ASIC_NOT_LOADED) | ||
57 | return -ENODEV; | ||
58 | |||
59 | chip->asic_loaded = TRUE; | ||
60 | return box_status & E3G_BOX_TYPE_MASK; | ||
61 | } | ||
62 | |||
63 | |||
64 | |||
65 | static inline u32 get_frq_reg(struct echoaudio *chip) | ||
66 | { | ||
67 | return le32_to_cpu(chip->comm_page->e3g_frq_register); | ||
68 | } | ||
69 | |||
70 | |||
71 | |||
72 | /* Most configuration of 3G cards is accomplished by writing the control | ||
73 | register. write_control_reg sends the new control register value to the DSP. */ | ||
74 | static int write_control_reg(struct echoaudio *chip, u32 ctl, u32 frq, | ||
75 | char force) | ||
76 | { | ||
77 | if (wait_handshake(chip)) | ||
78 | return -EIO; | ||
79 | |||
80 | DE_ACT(("WriteControlReg: Setting 0x%x, 0x%x\n", ctl, frq)); | ||
81 | |||
82 | ctl = cpu_to_le32(ctl); | ||
83 | frq = cpu_to_le32(frq); | ||
84 | |||
85 | if (ctl != chip->comm_page->control_register || | ||
86 | frq != chip->comm_page->e3g_frq_register || force) { | ||
87 | chip->comm_page->e3g_frq_register = frq; | ||
88 | chip->comm_page->control_register = ctl; | ||
89 | clear_handshake(chip); | ||
90 | return send_vector(chip, DSP_VC_WRITE_CONTROL_REG); | ||
91 | } | ||
92 | |||
93 | DE_ACT(("WriteControlReg: not written, no change\n")); | ||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | |||
98 | |||
99 | /* Set the digital mode - currently for Gina24, Layla24, Mona, 3G */ | ||
100 | static int set_digital_mode(struct echoaudio *chip, u8 mode) | ||
101 | { | ||
102 | u8 previous_mode; | ||
103 | int err, i, o; | ||
104 | |||
105 | /* All audio channels must be closed before changing the digital mode */ | ||
106 | snd_assert(!chip->pipe_alloc_mask, return -EAGAIN); | ||
107 | |||
108 | snd_assert(chip->digital_modes & (1 << mode), return -EINVAL); | ||
109 | |||
110 | previous_mode = chip->digital_mode; | ||
111 | err = dsp_set_digital_mode(chip, mode); | ||
112 | |||
113 | /* If we successfully changed the digital mode from or to ADAT, | ||
114 | * then make sure all output, input and monitor levels are | ||
115 | * updated by the DSP comm object. */ | ||
116 | if (err >= 0 && previous_mode != mode && | ||
117 | (previous_mode == DIGITAL_MODE_ADAT || mode == DIGITAL_MODE_ADAT)) { | ||
118 | spin_lock_irq(&chip->lock); | ||
119 | for (o = 0; o < num_busses_out(chip); o++) | ||
120 | for (i = 0; i < num_busses_in(chip); i++) | ||
121 | set_monitor_gain(chip, o, i, | ||
122 | chip->monitor_gain[o][i]); | ||
123 | |||
124 | #ifdef ECHOCARD_HAS_INPUT_GAIN | ||
125 | for (i = 0; i < num_busses_in(chip); i++) | ||
126 | set_input_gain(chip, i, chip->input_gain[i]); | ||
127 | update_input_line_level(chip); | ||
128 | #endif | ||
129 | |||
130 | for (o = 0; o < num_busses_out(chip); o++) | ||
131 | set_output_gain(chip, o, chip->output_gain[o]); | ||
132 | update_output_line_level(chip); | ||
133 | spin_unlock_irq(&chip->lock); | ||
134 | } | ||
135 | |||
136 | return err; | ||
137 | } | ||
138 | |||
139 | |||
140 | |||
141 | static u32 set_spdif_bits(struct echoaudio *chip, u32 control_reg, u32 rate) | ||
142 | { | ||
143 | control_reg &= E3G_SPDIF_FORMAT_CLEAR_MASK; | ||
144 | |||
145 | switch (rate) { | ||
146 | case 32000 : | ||
147 | control_reg |= E3G_SPDIF_SAMPLE_RATE0 | E3G_SPDIF_SAMPLE_RATE1; | ||
148 | break; | ||
149 | case 44100 : | ||
150 | if (chip->professional_spdif) | ||
151 | control_reg |= E3G_SPDIF_SAMPLE_RATE0; | ||
152 | break; | ||
153 | case 48000 : | ||
154 | control_reg |= E3G_SPDIF_SAMPLE_RATE1; | ||
155 | break; | ||
156 | } | ||
157 | |||
158 | if (chip->professional_spdif) | ||
159 | control_reg |= E3G_SPDIF_PRO_MODE; | ||
160 | |||
161 | if (chip->non_audio_spdif) | ||
162 | control_reg |= E3G_SPDIF_NOT_AUDIO; | ||
163 | |||
164 | control_reg |= E3G_SPDIF_24_BIT | E3G_SPDIF_TWO_CHANNEL | | ||
165 | E3G_SPDIF_COPY_PERMIT; | ||
166 | |||
167 | return control_reg; | ||
168 | } | ||
169 | |||
170 | |||
171 | |||
172 | /* Set the S/PDIF output format */ | ||
173 | static int set_professional_spdif(struct echoaudio *chip, char prof) | ||
174 | { | ||
175 | u32 control_reg; | ||
176 | |||
177 | control_reg = le32_to_cpu(chip->comm_page->control_register); | ||
178 | chip->professional_spdif = prof; | ||
179 | control_reg = set_spdif_bits(chip, control_reg, chip->sample_rate); | ||
180 | return write_control_reg(chip, control_reg, get_frq_reg(chip), 0); | ||
181 | } | ||
182 | |||
183 | |||
184 | |||
185 | /* detect_input_clocks() returns a bitmask consisting of all the input clocks | ||
186 | currently connected to the hardware; this changes as the user connects and | ||
187 | disconnects clock inputs. You should use this information to determine which | ||
188 | clocks the user is allowed to select. */ | ||
189 | static u32 detect_input_clocks(const struct echoaudio *chip) | ||
190 | { | ||
191 | u32 clocks_from_dsp, clock_bits; | ||
192 | |||
193 | /* Map the DSP clock detect bits to the generic driver clock | ||
194 | * detect bits */ | ||
195 | clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); | ||
196 | |||
197 | clock_bits = ECHO_CLOCK_BIT_INTERNAL; | ||
198 | |||
199 | if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_WORD) | ||
200 | clock_bits |= ECHO_CLOCK_BIT_WORD; | ||
201 | |||
202 | switch(chip->digital_mode) { | ||
203 | case DIGITAL_MODE_SPDIF_RCA: | ||
204 | case DIGITAL_MODE_SPDIF_OPTICAL: | ||
205 | if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_SPDIF) | ||
206 | clock_bits |= ECHO_CLOCK_BIT_SPDIF; | ||
207 | break; | ||
208 | case DIGITAL_MODE_ADAT: | ||
209 | if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_ADAT) | ||
210 | clock_bits |= ECHO_CLOCK_BIT_ADAT; | ||
211 | break; | ||
212 | } | ||
213 | |||
214 | return clock_bits; | ||
215 | } | ||
216 | |||
217 | |||
218 | |||
219 | static int load_asic(struct echoaudio *chip) | ||
220 | { | ||
221 | int box_type, err; | ||
222 | |||
223 | if (chip->asic_loaded) | ||
224 | return 0; | ||
225 | |||
226 | /* Give the DSP a few milliseconds to settle down */ | ||
227 | mdelay(2); | ||
228 | |||
229 | err = load_asic_generic(chip, DSP_FNC_LOAD_3G_ASIC, | ||
230 | &card_fw[FW_3G_ASIC]); | ||
231 | if (err < 0) | ||
232 | return err; | ||
233 | |||
234 | chip->asic_code = &card_fw[FW_3G_ASIC]; | ||
235 | |||
236 | /* Now give the new ASIC a little time to set up */ | ||
237 | mdelay(2); | ||
238 | /* See if it worked */ | ||
239 | box_type = check_asic_status(chip); | ||
240 | |||
241 | /* Set up the control register if the load succeeded - | ||
242 | * 48 kHz, internal clock, S/PDIF RCA mode */ | ||
243 | if (box_type >= 0) { | ||
244 | err = write_control_reg(chip, E3G_48KHZ, | ||
245 | E3G_FREQ_REG_DEFAULT, TRUE); | ||
246 | if (err < 0) | ||
247 | return err; | ||
248 | } | ||
249 | |||
250 | return box_type; | ||
251 | } | ||
252 | |||
253 | |||
254 | |||
255 | static int set_sample_rate(struct echoaudio *chip, u32 rate) | ||
256 | { | ||
257 | u32 control_reg, clock, base_rate, frq_reg; | ||
258 | |||
259 | /* Only set the clock for internal mode. */ | ||
260 | if (chip->input_clock != ECHO_CLOCK_INTERNAL) { | ||
261 | DE_ACT(("set_sample_rate: Cannot set sample rate - " | ||
262 | "clock not set to CLK_CLOCKININTERNAL\n")); | ||
263 | /* Save the rate anyhow */ | ||
264 | chip->comm_page->sample_rate = cpu_to_le32(rate); | ||
265 | chip->sample_rate = rate; | ||
266 | set_input_clock(chip, chip->input_clock); | ||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | snd_assert(rate < 50000 || chip->digital_mode != DIGITAL_MODE_ADAT, | ||
271 | return -EINVAL); | ||
272 | |||
273 | clock = 0; | ||
274 | control_reg = le32_to_cpu(chip->comm_page->control_register); | ||
275 | control_reg &= E3G_CLOCK_CLEAR_MASK; | ||
276 | |||
277 | switch (rate) { | ||
278 | case 96000: | ||
279 | clock = E3G_96KHZ; | ||
280 | break; | ||
281 | case 88200: | ||
282 | clock = E3G_88KHZ; | ||
283 | break; | ||
284 | case 48000: | ||
285 | clock = E3G_48KHZ; | ||
286 | break; | ||
287 | case 44100: | ||
288 | clock = E3G_44KHZ; | ||
289 | break; | ||
290 | case 32000: | ||
291 | clock = E3G_32KHZ; | ||
292 | break; | ||
293 | default: | ||
294 | clock = E3G_CONTINUOUS_CLOCK; | ||
295 | if (rate > 50000) | ||
296 | clock |= E3G_DOUBLE_SPEED_MODE; | ||
297 | break; | ||
298 | } | ||
299 | |||
300 | control_reg |= clock; | ||
301 | control_reg = set_spdif_bits(chip, control_reg, rate); | ||
302 | |||
303 | base_rate = rate; | ||
304 | if (base_rate > 50000) | ||
305 | base_rate /= 2; | ||
306 | if (base_rate < 32000) | ||
307 | base_rate = 32000; | ||
308 | |||
309 | frq_reg = E3G_MAGIC_NUMBER / base_rate - 2; | ||
310 | if (frq_reg > E3G_FREQ_REG_MAX) | ||
311 | frq_reg = E3G_FREQ_REG_MAX; | ||
312 | |||
313 | chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ | ||
314 | chip->sample_rate = rate; | ||
315 | DE_ACT(("SetSampleRate: %d clock %x\n", rate, control_reg)); | ||
316 | |||
317 | /* Tell the DSP about it - DSP reads both control reg & freq reg */ | ||
318 | return write_control_reg(chip, control_reg, frq_reg, 0); | ||
319 | } | ||
320 | |||
321 | |||
322 | |||
323 | /* Set the sample clock source to internal, S/PDIF, ADAT */ | ||
324 | static int set_input_clock(struct echoaudio *chip, u16 clock) | ||
325 | { | ||
326 | u32 control_reg, clocks_from_dsp; | ||
327 | |||
328 | DE_ACT(("set_input_clock:\n")); | ||
329 | |||
330 | /* Mask off the clock select bits */ | ||
331 | control_reg = le32_to_cpu(chip->comm_page->control_register) & | ||
332 | E3G_CLOCK_CLEAR_MASK; | ||
333 | clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); | ||
334 | |||
335 | switch (clock) { | ||
336 | case ECHO_CLOCK_INTERNAL: | ||
337 | DE_ACT(("Set Echo3G clock to INTERNAL\n")); | ||
338 | chip->input_clock = ECHO_CLOCK_INTERNAL; | ||
339 | return set_sample_rate(chip, chip->sample_rate); | ||
340 | case ECHO_CLOCK_SPDIF: | ||
341 | if (chip->digital_mode == DIGITAL_MODE_ADAT) | ||
342 | return -EAGAIN; | ||
343 | DE_ACT(("Set Echo3G clock to SPDIF\n")); | ||
344 | control_reg |= E3G_SPDIF_CLOCK; | ||
345 | if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_SPDIF96) | ||
346 | control_reg |= E3G_DOUBLE_SPEED_MODE; | ||
347 | else | ||
348 | control_reg &= ~E3G_DOUBLE_SPEED_MODE; | ||
349 | break; | ||
350 | case ECHO_CLOCK_ADAT: | ||
351 | if (chip->digital_mode != DIGITAL_MODE_ADAT) | ||
352 | return -EAGAIN; | ||
353 | DE_ACT(("Set Echo3G clock to ADAT\n")); | ||
354 | control_reg |= E3G_ADAT_CLOCK; | ||
355 | control_reg &= ~E3G_DOUBLE_SPEED_MODE; | ||
356 | break; | ||
357 | case ECHO_CLOCK_WORD: | ||
358 | DE_ACT(("Set Echo3G clock to WORD\n")); | ||
359 | control_reg |= E3G_WORD_CLOCK; | ||
360 | if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_WORD96) | ||
361 | control_reg |= E3G_DOUBLE_SPEED_MODE; | ||
362 | else | ||
363 | control_reg &= ~E3G_DOUBLE_SPEED_MODE; | ||
364 | break; | ||
365 | default: | ||
366 | DE_ACT(("Input clock 0x%x not supported for Echo3G\n", clock)); | ||
367 | return -EINVAL; | ||
368 | } | ||
369 | |||
370 | chip->input_clock = clock; | ||
371 | return write_control_reg(chip, control_reg, get_frq_reg(chip), 1); | ||
372 | } | ||
373 | |||
374 | |||
375 | |||
376 | static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) | ||
377 | { | ||
378 | u32 control_reg; | ||
379 | int err, incompatible_clock; | ||
380 | |||
381 | /* Set clock to "internal" if it's not compatible with the new mode */ | ||
382 | incompatible_clock = FALSE; | ||
383 | switch (mode) { | ||
384 | case DIGITAL_MODE_SPDIF_OPTICAL: | ||
385 | case DIGITAL_MODE_SPDIF_RCA: | ||
386 | if (chip->input_clock == ECHO_CLOCK_ADAT) | ||
387 | incompatible_clock = TRUE; | ||
388 | break; | ||
389 | case DIGITAL_MODE_ADAT: | ||
390 | if (chip->input_clock == ECHO_CLOCK_SPDIF) | ||
391 | incompatible_clock = TRUE; | ||
392 | break; | ||
393 | default: | ||
394 | DE_ACT(("Digital mode not supported: %d\n", mode)); | ||
395 | return -EINVAL; | ||
396 | } | ||
397 | |||
398 | spin_lock_irq(&chip->lock); | ||
399 | |||
400 | if (incompatible_clock) { | ||
401 | chip->sample_rate = 48000; | ||
402 | set_input_clock(chip, ECHO_CLOCK_INTERNAL); | ||
403 | } | ||
404 | |||
405 | /* Clear the current digital mode */ | ||
406 | control_reg = le32_to_cpu(chip->comm_page->control_register); | ||
407 | control_reg &= E3G_DIGITAL_MODE_CLEAR_MASK; | ||
408 | |||
409 | /* Tweak the control reg */ | ||
410 | switch (mode) { | ||
411 | case DIGITAL_MODE_SPDIF_OPTICAL: | ||
412 | control_reg |= E3G_SPDIF_OPTICAL_MODE; | ||
413 | break; | ||
414 | case DIGITAL_MODE_SPDIF_RCA: | ||
415 | /* E3G_SPDIF_OPTICAL_MODE bit cleared */ | ||
416 | break; | ||
417 | case DIGITAL_MODE_ADAT: | ||
418 | control_reg |= E3G_ADAT_MODE; | ||
419 | control_reg &= ~E3G_DOUBLE_SPEED_MODE; /* @@ useless */ | ||
420 | break; | ||
421 | } | ||
422 | |||
423 | err = write_control_reg(chip, control_reg, get_frq_reg(chip), 1); | ||
424 | spin_unlock_irq(&chip->lock); | ||
425 | if (err < 0) | ||
426 | return err; | ||
427 | chip->digital_mode = mode; | ||
428 | |||
429 | DE_ACT(("set_digital_mode(%d)\n", chip->digital_mode)); | ||
430 | return incompatible_clock; | ||
431 | } | ||
diff --git a/sound/pci/echoaudio/echoaudio_dsp.c b/sound/pci/echoaudio/echoaudio_dsp.c new file mode 100644 index 000000000000..42afa837d9b4 --- /dev/null +++ b/sound/pci/echoaudio/echoaudio_dsp.c | |||
@@ -0,0 +1,1125 @@ | |||
1 | /**************************************************************************** | ||
2 | |||
3 | Copyright Echo Digital Audio Corporation (c) 1998 - 2004 | ||
4 | All rights reserved | ||
5 | www.echoaudio.com | ||
6 | |||
7 | This file is part of Echo Digital Audio's generic driver library. | ||
8 | |||
9 | Echo Digital Audio's generic driver library is free software; | ||
10 | you can redistribute it and/or modify it under the terms of | ||
11 | the GNU General Public License as published by the Free Software | ||
12 | Foundation. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, | ||
22 | MA 02111-1307, USA. | ||
23 | |||
24 | ************************************************************************* | ||
25 | |||
26 | Translation from C++ and adaptation for use in ALSA-Driver | ||
27 | were made by Giuliano Pochini <pochini@shiny.it> | ||
28 | |||
29 | ****************************************************************************/ | ||
30 | |||
31 | #if PAGE_SIZE < 4096 | ||
32 | #error PAGE_SIZE is < 4k | ||
33 | #endif | ||
34 | |||
35 | static int restore_dsp_rettings(struct echoaudio *chip); | ||
36 | |||
37 | |||
38 | /* Some vector commands involve the DSP reading or writing data to and from the | ||
39 | comm page; if you send one of these commands to the DSP, it will complete the | ||
40 | command and then write a non-zero value to the Handshake field in the | ||
41 | comm page. This function waits for the handshake to show up. */ | ||
42 | static int wait_handshake(struct echoaudio *chip) | ||
43 | { | ||
44 | int i; | ||
45 | |||
46 | /* Wait up to 10ms for the handshake from the DSP */ | ||
47 | for (i = 0; i < HANDSHAKE_TIMEOUT; i++) { | ||
48 | /* Look for the handshake value */ | ||
49 | if (chip->comm_page->handshake) { | ||
50 | /*if (i) DE_ACT(("Handshake time: %d\n", i));*/ | ||
51 | return 0; | ||
52 | } | ||
53 | udelay(1); | ||
54 | } | ||
55 | |||
56 | snd_printk(KERN_ERR "wait_handshake(): Timeout waiting for DSP\n"); | ||
57 | return -EBUSY; | ||
58 | } | ||
59 | |||
60 | |||
61 | |||
62 | /* Much of the interaction between the DSP and the driver is done via vector | ||
63 | commands; send_vector writes a vector command to the DSP. Typically, this | ||
64 | causes the DSP to read or write fields in the comm page. | ||
65 | PCI posting is not required thanks to the handshake logic. */ | ||
66 | static int send_vector(struct echoaudio *chip, u32 command) | ||
67 | { | ||
68 | int i; | ||
69 | |||
70 | wmb(); /* Flush all pending writes before sending the command */ | ||
71 | |||
72 | /* Wait up to 100ms for the "vector busy" bit to be off */ | ||
73 | for (i = 0; i < VECTOR_BUSY_TIMEOUT; i++) { | ||
74 | if (!(get_dsp_register(chip, CHI32_VECTOR_REG) & | ||
75 | CHI32_VECTOR_BUSY)) { | ||
76 | set_dsp_register(chip, CHI32_VECTOR_REG, command); | ||
77 | /*if (i) DE_ACT(("send_vector time: %d\n", i));*/ | ||
78 | return 0; | ||
79 | } | ||
80 | udelay(1); | ||
81 | } | ||
82 | |||
83 | DE_ACT((KERN_ERR "timeout on send_vector\n")); | ||
84 | return -EBUSY; | ||
85 | } | ||
86 | |||
87 | |||
88 | |||
89 | /* write_dsp writes a 32-bit value to the DSP; this is used almost | ||
90 | exclusively for loading the DSP. */ | ||
91 | static int write_dsp(struct echoaudio *chip, u32 data) | ||
92 | { | ||
93 | u32 status, i; | ||
94 | |||
95 | for (i = 0; i < 10000000; i++) { /* timeout = 10s */ | ||
96 | status = get_dsp_register(chip, CHI32_STATUS_REG); | ||
97 | if ((status & CHI32_STATUS_HOST_WRITE_EMPTY) != 0) { | ||
98 | set_dsp_register(chip, CHI32_DATA_REG, data); | ||
99 | wmb(); /* write it immediately */ | ||
100 | return 0; | ||
101 | } | ||
102 | udelay(1); | ||
103 | cond_resched(); | ||
104 | } | ||
105 | |||
106 | chip->bad_board = TRUE; /* Set TRUE until DSP re-loaded */ | ||
107 | DE_ACT((KERN_ERR "write_dsp: Set bad_board to TRUE\n")); | ||
108 | return -EIO; | ||
109 | } | ||
110 | |||
111 | |||
112 | |||
113 | /* read_dsp reads a 32-bit value from the DSP; this is used almost | ||
114 | exclusively for loading the DSP and checking the status of the ASIC. */ | ||
115 | static int read_dsp(struct echoaudio *chip, u32 *data) | ||
116 | { | ||
117 | u32 status, i; | ||
118 | |||
119 | for (i = 0; i < READ_DSP_TIMEOUT; i++) { | ||
120 | status = get_dsp_register(chip, CHI32_STATUS_REG); | ||
121 | if ((status & CHI32_STATUS_HOST_READ_FULL) != 0) { | ||
122 | *data = get_dsp_register(chip, CHI32_DATA_REG); | ||
123 | return 0; | ||
124 | } | ||
125 | udelay(1); | ||
126 | cond_resched(); | ||
127 | } | ||
128 | |||
129 | chip->bad_board = TRUE; /* Set TRUE until DSP re-loaded */ | ||
130 | DE_INIT((KERN_ERR "read_dsp: Set bad_board to TRUE\n")); | ||
131 | return -EIO; | ||
132 | } | ||
133 | |||
134 | |||
135 | |||
136 | /**************************************************************************** | ||
137 | Firmware loading functions | ||
138 | ****************************************************************************/ | ||
139 | |||
140 | /* This function is used to read back the serial number from the DSP; | ||
141 | this is triggered by the SET_COMMPAGE_ADDR command. | ||
142 | Only some early Echogals products have serial numbers in the ROM; | ||
143 | the serial number is not used, but you still need to do this as | ||
144 | part of the DSP load process. */ | ||
145 | static int read_sn(struct echoaudio *chip) | ||
146 | { | ||
147 | int i; | ||
148 | u32 sn[6]; | ||
149 | |||
150 | for (i = 0; i < 5; i++) { | ||
151 | if (read_dsp(chip, &sn[i])) { | ||
152 | snd_printk(KERN_ERR "Failed to read serial number\n"); | ||
153 | return -EIO; | ||
154 | } | ||
155 | } | ||
156 | DE_INIT(("Read serial number %08x %08x %08x %08x %08x\n", | ||
157 | sn[0], sn[1], sn[2], sn[3], sn[4])); | ||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | |||
162 | |||
163 | #ifndef ECHOCARD_HAS_ASIC | ||
164 | /* This card has no ASIC, just return ok */ | ||
165 | static inline int check_asic_status(struct echoaudio *chip) | ||
166 | { | ||
167 | chip->asic_loaded = TRUE; | ||
168 | return 0; | ||
169 | } | ||
170 | |||
171 | #endif /* !ECHOCARD_HAS_ASIC */ | ||
172 | |||
173 | |||
174 | |||
175 | #ifdef ECHOCARD_HAS_ASIC | ||
176 | |||
177 | /* Load ASIC code - done after the DSP is loaded */ | ||
178 | static int load_asic_generic(struct echoaudio *chip, u32 cmd, | ||
179 | const struct firmware *asic) | ||
180 | { | ||
181 | const struct firmware *fw; | ||
182 | int err; | ||
183 | u32 i, size; | ||
184 | u8 *code; | ||
185 | |||
186 | if ((err = get_firmware(&fw, asic, chip)) < 0) { | ||
187 | snd_printk(KERN_WARNING "Firmware not found !\n"); | ||
188 | return err; | ||
189 | } | ||
190 | |||
191 | code = (u8 *)fw->data; | ||
192 | size = fw->size; | ||
193 | |||
194 | /* Send the "Here comes the ASIC" command */ | ||
195 | if (write_dsp(chip, cmd) < 0) | ||
196 | goto la_error; | ||
197 | |||
198 | /* Write length of ASIC file in bytes */ | ||
199 | if (write_dsp(chip, size) < 0) | ||
200 | goto la_error; | ||
201 | |||
202 | for (i = 0; i < size; i++) { | ||
203 | if (write_dsp(chip, code[i]) < 0) | ||
204 | goto la_error; | ||
205 | } | ||
206 | |||
207 | DE_INIT(("ASIC loaded\n")); | ||
208 | free_firmware(fw); | ||
209 | return 0; | ||
210 | |||
211 | la_error: | ||
212 | DE_INIT(("failed on write_dsp\n")); | ||
213 | free_firmware(fw); | ||
214 | return -EIO; | ||
215 | } | ||
216 | |||
217 | #endif /* ECHOCARD_HAS_ASIC */ | ||
218 | |||
219 | |||
220 | |||
221 | #ifdef DSP_56361 | ||
222 | |||
223 | /* Install the resident loader for 56361 DSPs; The resident loader is on | ||
224 | the EPROM on the board for 56301 DSP. The resident loader is a tiny little | ||
225 | program that is used to load the real DSP code. */ | ||
226 | static int install_resident_loader(struct echoaudio *chip) | ||
227 | { | ||
228 | u32 address; | ||
229 | int index, words, i; | ||
230 | u16 *code; | ||
231 | u32 status; | ||
232 | const struct firmware *fw; | ||
233 | |||
234 | /* 56361 cards only! This check is required by the old 56301-based | ||
235 | Mona and Gina24 */ | ||
236 | if (chip->device_id != DEVICE_ID_56361) | ||
237 | return 0; | ||
238 | |||
239 | /* Look to see if the resident loader is present. If the resident | ||
240 | loader is already installed, host flag 5 will be on. */ | ||
241 | status = get_dsp_register(chip, CHI32_STATUS_REG); | ||
242 | if (status & CHI32_STATUS_REG_HF5) { | ||
243 | DE_INIT(("Resident loader already installed; status is 0x%x\n", | ||
244 | status)); | ||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | if ((i = get_firmware(&fw, &card_fw[FW_361_LOADER], chip)) < 0) { | ||
249 | snd_printk(KERN_WARNING "Firmware not found !\n"); | ||
250 | return i; | ||
251 | } | ||
252 | |||
253 | /* The DSP code is an array of 16 bit words. The array is divided up | ||
254 | into sections. The first word of each section is the size in words, | ||
255 | followed by the section type. | ||
256 | Since DSP addresses and data are 24 bits wide, they each take up two | ||
257 | 16 bit words in the array. | ||
258 | This is a lot like the other loader loop, but it's not a loop, you | ||
259 | don't write the memory type, and you don't write a zero at the end. */ | ||
260 | |||
261 | /* Set DSP format bits for 24 bit mode */ | ||
262 | set_dsp_register(chip, CHI32_CONTROL_REG, | ||
263 | get_dsp_register(chip, CHI32_CONTROL_REG) | 0x900); | ||
264 | |||
265 | code = (u16 *)fw->data; | ||
266 | |||
267 | /* Skip the header section; the first word in the array is the size | ||
268 | of the first section, so the first real section of code is pointed | ||
269 | to by Code[0]. */ | ||
270 | index = code[0]; | ||
271 | |||
272 | /* Skip the section size, LRS block type, and DSP memory type */ | ||
273 | index += 3; | ||
274 | |||
275 | /* Get the number of DSP words to write */ | ||
276 | words = code[index++]; | ||
277 | |||
278 | /* Get the DSP address for this block; 24 bits, so build from two words */ | ||
279 | address = ((u32)code[index] << 16) + code[index + 1]; | ||
280 | index += 2; | ||
281 | |||
282 | /* Write the count to the DSP */ | ||
283 | if (write_dsp(chip, words)) { | ||
284 | DE_INIT(("install_resident_loader: Failed to write word count!\n")); | ||
285 | goto irl_error; | ||
286 | } | ||
287 | /* Write the DSP address */ | ||
288 | if (write_dsp(chip, address)) { | ||
289 | DE_INIT(("install_resident_loader: Failed to write DSP address!\n")); | ||
290 | goto irl_error; | ||
291 | } | ||
292 | /* Write out this block of code to the DSP */ | ||
293 | for (i = 0; i < words; i++) { | ||
294 | u32 data; | ||
295 | |||
296 | data = ((u32)code[index] << 16) + code[index + 1]; | ||
297 | if (write_dsp(chip, data)) { | ||
298 | DE_INIT(("install_resident_loader: Failed to write DSP code\n")); | ||
299 | goto irl_error; | ||
300 | } | ||
301 | index += 2; | ||
302 | } | ||
303 | |||
304 | /* Wait for flag 5 to come up */ | ||
305 | for (i = 0; i < 200; i++) { /* Timeout is 50us * 200 = 10ms */ | ||
306 | udelay(50); | ||
307 | status = get_dsp_register(chip, CHI32_STATUS_REG); | ||
308 | if (status & CHI32_STATUS_REG_HF5) | ||
309 | break; | ||
310 | } | ||
311 | |||
312 | if (i == 200) { | ||
313 | DE_INIT(("Resident loader failed to set HF5\n")); | ||
314 | goto irl_error; | ||
315 | } | ||
316 | |||
317 | DE_INIT(("Resident loader successfully installed\n")); | ||
318 | free_firmware(fw); | ||
319 | return 0; | ||
320 | |||
321 | irl_error: | ||
322 | free_firmware(fw); | ||
323 | return -EIO; | ||
324 | } | ||
325 | |||
326 | #endif /* DSP_56361 */ | ||
327 | |||
328 | |||
329 | static int load_dsp(struct echoaudio *chip, u16 *code) | ||
330 | { | ||
331 | u32 address, data; | ||
332 | int index, words, i; | ||
333 | |||
334 | if (chip->dsp_code == code) { | ||
335 | DE_INIT(("DSP is already loaded!\n")); | ||
336 | return 0; | ||
337 | } | ||
338 | chip->bad_board = TRUE; /* Set TRUE until DSP loaded */ | ||
339 | chip->dsp_code = NULL; /* Current DSP code not loaded */ | ||
340 | chip->asic_loaded = FALSE; /* Loading the DSP code will reset the ASIC */ | ||
341 | |||
342 | DE_INIT(("load_dsp: Set bad_board to TRUE\n")); | ||
343 | |||
344 | /* If this board requires a resident loader, install it. */ | ||
345 | #ifdef DSP_56361 | ||
346 | if ((i = install_resident_loader(chip)) < 0) | ||
347 | return i; | ||
348 | #endif | ||
349 | |||
350 | /* Send software reset command */ | ||
351 | if (send_vector(chip, DSP_VC_RESET) < 0) { | ||
352 | DE_INIT(("LoadDsp: send_vector DSP_VC_RESET failed, Critical Failure\n")); | ||
353 | return -EIO; | ||
354 | } | ||
355 | /* Delay 10us */ | ||
356 | udelay(10); | ||
357 | |||
358 | /* Wait 10ms for HF3 to indicate that software reset is complete */ | ||
359 | for (i = 0; i < 1000; i++) { /* Timeout is 10us * 1000 = 10ms */ | ||
360 | if (get_dsp_register(chip, CHI32_STATUS_REG) & | ||
361 | CHI32_STATUS_REG_HF3) | ||
362 | break; | ||
363 | udelay(10); | ||
364 | } | ||
365 | |||
366 | if (i == 1000) { | ||
367 | DE_INIT(("load_dsp: Timeout waiting for CHI32_STATUS_REG_HF3\n")); | ||
368 | return -EIO; | ||
369 | } | ||
370 | |||
371 | /* Set DSP format bits for 24 bit mode now that soft reset is done */ | ||
372 | set_dsp_register(chip, CHI32_CONTROL_REG, | ||
373 | get_dsp_register(chip, CHI32_CONTROL_REG) | 0x900); | ||
374 | |||
375 | /* Main loader loop */ | ||
376 | |||
377 | index = code[0]; | ||
378 | for (;;) { | ||
379 | int block_type, mem_type; | ||
380 | |||
381 | /* Total Block Size */ | ||
382 | index++; | ||
383 | |||
384 | /* Block Type */ | ||
385 | block_type = code[index]; | ||
386 | if (block_type == 4) /* We're finished */ | ||
387 | break; | ||
388 | |||
389 | index++; | ||
390 | |||
391 | /* Memory Type P=0,X=1,Y=2 */ | ||
392 | mem_type = code[index++]; | ||
393 | |||
394 | /* Block Code Size */ | ||
395 | words = code[index++]; | ||
396 | if (words == 0) /* We're finished */ | ||
397 | break; | ||
398 | |||
399 | /* Start Address */ | ||
400 | address = ((u32)code[index] << 16) + code[index + 1]; | ||
401 | index += 2; | ||
402 | |||
403 | if (write_dsp(chip, words) < 0) { | ||
404 | DE_INIT(("load_dsp: failed to write number of DSP words\n")); | ||
405 | return -EIO; | ||
406 | } | ||
407 | if (write_dsp(chip, address) < 0) { | ||
408 | DE_INIT(("load_dsp: failed to write DSP address\n")); | ||
409 | return -EIO; | ||
410 | } | ||
411 | if (write_dsp(chip, mem_type) < 0) { | ||
412 | DE_INIT(("load_dsp: failed to write DSP memory type\n")); | ||
413 | return -EIO; | ||
414 | } | ||
415 | /* Code */ | ||
416 | for (i = 0; i < words; i++, index+=2) { | ||
417 | data = ((u32)code[index] << 16) + code[index + 1]; | ||
418 | if (write_dsp(chip, data) < 0) { | ||
419 | DE_INIT(("load_dsp: failed to write DSP data\n")); | ||
420 | return -EIO; | ||
421 | } | ||
422 | } | ||
423 | } | ||
424 | |||
425 | if (write_dsp(chip, 0) < 0) { /* We're done!!! */ | ||
426 | DE_INIT(("load_dsp: Failed to write final zero\n")); | ||
427 | return -EIO; | ||
428 | } | ||
429 | udelay(10); | ||
430 | |||
431 | for (i = 0; i < 5000; i++) { /* Timeout is 100us * 5000 = 500ms */ | ||
432 | /* Wait for flag 4 - indicates that the DSP loaded OK */ | ||
433 | if (get_dsp_register(chip, CHI32_STATUS_REG) & | ||
434 | CHI32_STATUS_REG_HF4) { | ||
435 | set_dsp_register(chip, CHI32_CONTROL_REG, | ||
436 | get_dsp_register(chip, CHI32_CONTROL_REG) & ~0x1b00); | ||
437 | |||
438 | if (write_dsp(chip, DSP_FNC_SET_COMMPAGE_ADDR) < 0) { | ||
439 | DE_INIT(("load_dsp: Failed to write DSP_FNC_SET_COMMPAGE_ADDR\n")); | ||
440 | return -EIO; | ||
441 | } | ||
442 | |||
443 | if (write_dsp(chip, chip->comm_page_phys) < 0) { | ||
444 | DE_INIT(("load_dsp: Failed to write comm page address\n")); | ||
445 | return -EIO; | ||
446 | } | ||
447 | |||
448 | /* Get the serial number via slave mode. | ||
449 | This is triggered by the SET_COMMPAGE_ADDR command. | ||
450 | We don't actually use the serial number but we have to | ||
451 | get it as part of the DSP init voodoo. */ | ||
452 | if (read_sn(chip) < 0) { | ||
453 | DE_INIT(("load_dsp: Failed to read serial number\n")); | ||
454 | return -EIO; | ||
455 | } | ||
456 | |||
457 | chip->dsp_code = code; /* Show which DSP code loaded */ | ||
458 | chip->bad_board = FALSE; /* DSP OK */ | ||
459 | DE_INIT(("load_dsp: OK!\n")); | ||
460 | return 0; | ||
461 | } | ||
462 | udelay(100); | ||
463 | } | ||
464 | |||
465 | DE_INIT(("load_dsp: DSP load timed out waiting for HF4\n")); | ||
466 | return -EIO; | ||
467 | } | ||
468 | |||
469 | |||
470 | |||
471 | /* load_firmware takes care of loading the DSP and any ASIC code. */ | ||
472 | static int load_firmware(struct echoaudio *chip) | ||
473 | { | ||
474 | const struct firmware *fw; | ||
475 | int box_type, err; | ||
476 | |||
477 | snd_assert(chip->dsp_code_to_load && chip->comm_page, return -EPERM); | ||
478 | |||
479 | /* See if the ASIC is present and working - only if the DSP is already loaded */ | ||
480 | if (chip->dsp_code) { | ||
481 | if ((box_type = check_asic_status(chip)) >= 0) | ||
482 | return box_type; | ||
483 | /* ASIC check failed; force the DSP to reload */ | ||
484 | chip->dsp_code = NULL; | ||
485 | } | ||
486 | |||
487 | if ((err = get_firmware(&fw, chip->dsp_code_to_load, chip)) < 0) | ||
488 | return err; | ||
489 | err = load_dsp(chip, (u16 *)fw->data); | ||
490 | free_firmware(fw); | ||
491 | if (err < 0) | ||
492 | return err; | ||
493 | |||
494 | if ((box_type = load_asic(chip)) < 0) | ||
495 | return box_type; /* error */ | ||
496 | |||
497 | if ((err = restore_dsp_rettings(chip)) < 0) | ||
498 | return err; | ||
499 | |||
500 | return box_type; | ||
501 | } | ||
502 | |||
503 | |||
504 | |||
505 | /**************************************************************************** | ||
506 | Mixer functions | ||
507 | ****************************************************************************/ | ||
508 | |||
509 | #if defined(ECHOCARD_HAS_INPUT_NOMINAL_LEVEL) || \ | ||
510 | defined(ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL) | ||
511 | |||
512 | /* Set the nominal level for an input or output bus (true = -10dBV, false = +4dBu) */ | ||
513 | static int set_nominal_level(struct echoaudio *chip, u16 index, char consumer) | ||
514 | { | ||
515 | snd_assert(index < num_busses_out(chip) + num_busses_in(chip), | ||
516 | return -EINVAL); | ||
517 | |||
518 | /* Wait for the handshake (OK even if ASIC is not loaded) */ | ||
519 | if (wait_handshake(chip)) | ||
520 | return -EIO; | ||
521 | |||
522 | chip->nominal_level[index] = consumer; | ||
523 | |||
524 | if (consumer) | ||
525 | chip->comm_page->nominal_level_mask |= cpu_to_le32(1 << index); | ||
526 | else | ||
527 | chip->comm_page->nominal_level_mask &= ~cpu_to_le32(1 << index); | ||
528 | |||
529 | return 0; | ||
530 | } | ||
531 | |||
532 | #endif /* ECHOCARD_HAS_*_NOMINAL_LEVEL */ | ||
533 | |||
534 | |||
535 | |||
536 | /* Set the gain for a single physical output channel (dB). */ | ||
537 | static int set_output_gain(struct echoaudio *chip, u16 channel, s8 gain) | ||
538 | { | ||
539 | snd_assert(channel < num_busses_out(chip), return -EINVAL); | ||
540 | |||
541 | if (wait_handshake(chip)) | ||
542 | return -EIO; | ||
543 | |||
544 | /* Save the new value */ | ||
545 | chip->output_gain[channel] = gain; | ||
546 | chip->comm_page->line_out_level[channel] = gain; | ||
547 | return 0; | ||
548 | } | ||
549 | |||
550 | |||
551 | |||
552 | #ifdef ECHOCARD_HAS_MONITOR | ||
553 | /* Set the monitor level from an input bus to an output bus. */ | ||
554 | static int set_monitor_gain(struct echoaudio *chip, u16 output, u16 input, | ||
555 | s8 gain) | ||
556 | { | ||
557 | snd_assert(output < num_busses_out(chip) && | ||
558 | input < num_busses_in(chip), return -EINVAL); | ||
559 | |||
560 | if (wait_handshake(chip)) | ||
561 | return -EIO; | ||
562 | |||
563 | chip->monitor_gain[output][input] = gain; | ||
564 | chip->comm_page->monitors[monitor_index(chip, output, input)] = gain; | ||
565 | return 0; | ||
566 | } | ||
567 | #endif /* ECHOCARD_HAS_MONITOR */ | ||
568 | |||
569 | |||
570 | /* Tell the DSP to read and update output, nominal & monitor levels in comm page. */ | ||
571 | static int update_output_line_level(struct echoaudio *chip) | ||
572 | { | ||
573 | if (wait_handshake(chip)) | ||
574 | return -EIO; | ||
575 | clear_handshake(chip); | ||
576 | return send_vector(chip, DSP_VC_UPDATE_OUTVOL); | ||
577 | } | ||
578 | |||
579 | |||
580 | |||
581 | /* Tell the DSP to read and update input levels in comm page */ | ||
582 | static int update_input_line_level(struct echoaudio *chip) | ||
583 | { | ||
584 | if (wait_handshake(chip)) | ||
585 | return -EIO; | ||
586 | clear_handshake(chip); | ||
587 | return send_vector(chip, DSP_VC_UPDATE_INGAIN); | ||
588 | } | ||
589 | |||
590 | |||
591 | |||
592 | /* set_meters_on turns the meters on or off. If meters are turned on, the DSP | ||
593 | will write the meter and clock detect values to the comm page at about 30Hz */ | ||
594 | static void set_meters_on(struct echoaudio *chip, char on) | ||
595 | { | ||
596 | if (on && !chip->meters_enabled) { | ||
597 | send_vector(chip, DSP_VC_METERS_ON); | ||
598 | chip->meters_enabled = 1; | ||
599 | } else if (!on && chip->meters_enabled) { | ||
600 | send_vector(chip, DSP_VC_METERS_OFF); | ||
601 | chip->meters_enabled = 0; | ||
602 | memset((s8 *)chip->comm_page->vu_meter, ECHOGAIN_MUTED, | ||
603 | DSP_MAXPIPES); | ||
604 | memset((s8 *)chip->comm_page->peak_meter, ECHOGAIN_MUTED, | ||
605 | DSP_MAXPIPES); | ||
606 | } | ||
607 | } | ||
608 | |||
609 | |||
610 | |||
611 | /* Fill out an the given array using the current values in the comm page. | ||
612 | Meters are written in the comm page by the DSP in this order: | ||
613 | Output busses | ||
614 | Input busses | ||
615 | Output pipes (vmixer cards only) | ||
616 | |||
617 | This function assumes there are no more than 16 in/out busses or pipes | ||
618 | Meters is an array [3][16][2] of long. */ | ||
619 | static void get_audio_meters(struct echoaudio *chip, long *meters) | ||
620 | { | ||
621 | int i, m, n; | ||
622 | |||
623 | m = 0; | ||
624 | n = 0; | ||
625 | for (i = 0; i < num_busses_out(chip); i++, m++) { | ||
626 | meters[n++] = chip->comm_page->vu_meter[m]; | ||
627 | meters[n++] = chip->comm_page->peak_meter[m]; | ||
628 | } | ||
629 | for (; n < 32; n++) | ||
630 | meters[n] = 0; | ||
631 | |||
632 | #ifdef ECHOCARD_ECHO3G | ||
633 | m = E3G_MAX_OUTPUTS; /* Skip unused meters */ | ||
634 | #endif | ||
635 | |||
636 | for (i = 0; i < num_busses_in(chip); i++, m++) { | ||
637 | meters[n++] = chip->comm_page->vu_meter[m]; | ||
638 | meters[n++] = chip->comm_page->peak_meter[m]; | ||
639 | } | ||
640 | for (; n < 64; n++) | ||
641 | meters[n] = 0; | ||
642 | |||
643 | #ifdef ECHOCARD_HAS_VMIXER | ||
644 | for (i = 0; i < num_pipes_out(chip); i++, m++) { | ||
645 | meters[n++] = chip->comm_page->vu_meter[m]; | ||
646 | meters[n++] = chip->comm_page->peak_meter[m]; | ||
647 | } | ||
648 | #endif | ||
649 | for (; n < 96; n++) | ||
650 | meters[n] = 0; | ||
651 | } | ||
652 | |||
653 | |||
654 | |||
655 | static int restore_dsp_rettings(struct echoaudio *chip) | ||
656 | { | ||
657 | int err; | ||
658 | DE_INIT(("restore_dsp_settings\n")); | ||
659 | |||
660 | if ((err = check_asic_status(chip)) < 0) | ||
661 | return err; | ||
662 | |||
663 | /* @ Gina20/Darla20 only. Should be harmless for other cards. */ | ||
664 | chip->comm_page->gd_clock_state = GD_CLOCK_UNDEF; | ||
665 | chip->comm_page->gd_spdif_status = GD_SPDIF_STATUS_UNDEF; | ||
666 | chip->comm_page->handshake = 0xffffffff; | ||
667 | |||
668 | if ((err = set_sample_rate(chip, chip->sample_rate)) < 0) | ||
669 | return err; | ||
670 | |||
671 | if (chip->meters_enabled) | ||
672 | if (send_vector(chip, DSP_VC_METERS_ON) < 0) | ||
673 | return -EIO; | ||
674 | |||
675 | #ifdef ECHOCARD_HAS_EXTERNAL_CLOCK | ||
676 | if (set_input_clock(chip, chip->input_clock) < 0) | ||
677 | return -EIO; | ||
678 | #endif | ||
679 | |||
680 | #ifdef ECHOCARD_HAS_OUTPUT_CLOCK_SWITCH | ||
681 | if (set_output_clock(chip, chip->output_clock) < 0) | ||
682 | return -EIO; | ||
683 | #endif | ||
684 | |||
685 | if (update_output_line_level(chip) < 0) | ||
686 | return -EIO; | ||
687 | |||
688 | if (update_input_line_level(chip) < 0) | ||
689 | return -EIO; | ||
690 | |||
691 | #ifdef ECHOCARD_HAS_VMIXER | ||
692 | if (update_vmixer_level(chip) < 0) | ||
693 | return -EIO; | ||
694 | #endif | ||
695 | |||
696 | if (wait_handshake(chip) < 0) | ||
697 | return -EIO; | ||
698 | clear_handshake(chip); | ||
699 | |||
700 | DE_INIT(("restore_dsp_rettings done\n")); | ||
701 | return send_vector(chip, DSP_VC_UPDATE_FLAGS); | ||
702 | } | ||
703 | |||
704 | |||
705 | |||
706 | /**************************************************************************** | ||
707 | Transport functions | ||
708 | ****************************************************************************/ | ||
709 | |||
710 | /* set_audio_format() sets the format of the audio data in host memory for | ||
711 | this pipe. Note that _MS_ (mono-to-stereo) playback modes are not used by ALSA | ||
712 | but they are here because they are just mono while capturing */ | ||
713 | static void set_audio_format(struct echoaudio *chip, u16 pipe_index, | ||
714 | const struct audioformat *format) | ||
715 | { | ||
716 | u16 dsp_format; | ||
717 | |||
718 | dsp_format = DSP_AUDIOFORM_SS_16LE; | ||
719 | |||
720 | /* Look for super-interleave (no big-endian and 8 bits) */ | ||
721 | if (format->interleave > 2) { | ||
722 | switch (format->bits_per_sample) { | ||
723 | case 16: | ||
724 | dsp_format = DSP_AUDIOFORM_SUPER_INTERLEAVE_16LE; | ||
725 | break; | ||
726 | case 24: | ||
727 | dsp_format = DSP_AUDIOFORM_SUPER_INTERLEAVE_24LE; | ||
728 | break; | ||
729 | case 32: | ||
730 | dsp_format = DSP_AUDIOFORM_SUPER_INTERLEAVE_32LE; | ||
731 | break; | ||
732 | } | ||
733 | dsp_format |= format->interleave; | ||
734 | } else if (format->data_are_bigendian) { | ||
735 | /* For big-endian data, only 32 bit samples are supported */ | ||
736 | switch (format->interleave) { | ||
737 | case 1: | ||
738 | dsp_format = DSP_AUDIOFORM_MM_32BE; | ||
739 | break; | ||
740 | #ifdef ECHOCARD_HAS_STEREO_BIG_ENDIAN32 | ||
741 | case 2: | ||
742 | dsp_format = DSP_AUDIOFORM_SS_32BE; | ||
743 | break; | ||
744 | #endif | ||
745 | } | ||
746 | } else if (format->interleave == 1 && | ||
747 | format->bits_per_sample == 32 && !format->mono_to_stereo) { | ||
748 | /* 32 bit little-endian mono->mono case */ | ||
749 | dsp_format = DSP_AUDIOFORM_MM_32LE; | ||
750 | } else { | ||
751 | /* Handle the other little-endian formats */ | ||
752 | switch (format->bits_per_sample) { | ||
753 | case 8: | ||
754 | if (format->interleave == 2) | ||
755 | dsp_format = DSP_AUDIOFORM_SS_8; | ||
756 | else | ||
757 | dsp_format = DSP_AUDIOFORM_MS_8; | ||
758 | break; | ||
759 | default: | ||
760 | case 16: | ||
761 | if (format->interleave == 2) | ||
762 | dsp_format = DSP_AUDIOFORM_SS_16LE; | ||
763 | else | ||
764 | dsp_format = DSP_AUDIOFORM_MS_16LE; | ||
765 | break; | ||
766 | case 24: | ||
767 | if (format->interleave == 2) | ||
768 | dsp_format = DSP_AUDIOFORM_SS_24LE; | ||
769 | else | ||
770 | dsp_format = DSP_AUDIOFORM_MS_24LE; | ||
771 | break; | ||
772 | case 32: | ||
773 | if (format->interleave == 2) | ||
774 | dsp_format = DSP_AUDIOFORM_SS_32LE; | ||
775 | else | ||
776 | dsp_format = DSP_AUDIOFORM_MS_32LE; | ||
777 | break; | ||
778 | } | ||
779 | } | ||
780 | DE_ACT(("set_audio_format[%d] = %x\n", pipe_index, dsp_format)); | ||
781 | chip->comm_page->audio_format[pipe_index] = cpu_to_le16(dsp_format); | ||
782 | } | ||
783 | |||
784 | |||
785 | |||
786 | /* start_transport starts transport for a set of pipes. | ||
787 | The bits 1 in channel_mask specify what pipes to start. Only the bit of the | ||
788 | first channel must be set, regardless its interleave. | ||
789 | Same thing for pause_ and stop_ -trasport below. */ | ||
790 | static int start_transport(struct echoaudio *chip, u32 channel_mask, | ||
791 | u32 cyclic_mask) | ||
792 | { | ||
793 | DE_ACT(("start_transport %x\n", channel_mask)); | ||
794 | |||
795 | if (wait_handshake(chip)) | ||
796 | return -EIO; | ||
797 | |||
798 | chip->comm_page->cmd_start |= cpu_to_le32(channel_mask); | ||
799 | |||
800 | if (chip->comm_page->cmd_start) { | ||
801 | clear_handshake(chip); | ||
802 | send_vector(chip, DSP_VC_START_TRANSFER); | ||
803 | if (wait_handshake(chip)) | ||
804 | return -EIO; | ||
805 | /* Keep track of which pipes are transporting */ | ||
806 | chip->active_mask |= channel_mask; | ||
807 | chip->comm_page->cmd_start = 0; | ||
808 | return 0; | ||
809 | } | ||
810 | |||
811 | DE_ACT(("start_transport: No pipes to start!\n")); | ||
812 | return -EINVAL; | ||
813 | } | ||
814 | |||
815 | |||
816 | |||
817 | static int pause_transport(struct echoaudio *chip, u32 channel_mask) | ||
818 | { | ||
819 | DE_ACT(("pause_transport %x\n", channel_mask)); | ||
820 | |||
821 | if (wait_handshake(chip)) | ||
822 | return -EIO; | ||
823 | |||
824 | chip->comm_page->cmd_stop |= cpu_to_le32(channel_mask); | ||
825 | chip->comm_page->cmd_reset = 0; | ||
826 | if (chip->comm_page->cmd_stop) { | ||
827 | clear_handshake(chip); | ||
828 | send_vector(chip, DSP_VC_STOP_TRANSFER); | ||
829 | if (wait_handshake(chip)) | ||
830 | return -EIO; | ||
831 | /* Keep track of which pipes are transporting */ | ||
832 | chip->active_mask &= ~channel_mask; | ||
833 | chip->comm_page->cmd_stop = 0; | ||
834 | chip->comm_page->cmd_reset = 0; | ||
835 | return 0; | ||
836 | } | ||
837 | |||
838 | DE_ACT(("pause_transport: No pipes to stop!\n")); | ||
839 | return 0; | ||
840 | } | ||
841 | |||
842 | |||
843 | |||
844 | static int stop_transport(struct echoaudio *chip, u32 channel_mask) | ||
845 | { | ||
846 | DE_ACT(("stop_transport %x\n", channel_mask)); | ||
847 | |||
848 | if (wait_handshake(chip)) | ||
849 | return -EIO; | ||
850 | |||
851 | chip->comm_page->cmd_stop |= cpu_to_le32(channel_mask); | ||
852 | chip->comm_page->cmd_reset |= cpu_to_le32(channel_mask); | ||
853 | if (chip->comm_page->cmd_reset) { | ||
854 | clear_handshake(chip); | ||
855 | send_vector(chip, DSP_VC_STOP_TRANSFER); | ||
856 | if (wait_handshake(chip)) | ||
857 | return -EIO; | ||
858 | /* Keep track of which pipes are transporting */ | ||
859 | chip->active_mask &= ~channel_mask; | ||
860 | chip->comm_page->cmd_stop = 0; | ||
861 | chip->comm_page->cmd_reset = 0; | ||
862 | return 0; | ||
863 | } | ||
864 | |||
865 | DE_ACT(("stop_transport: No pipes to stop!\n")); | ||
866 | return 0; | ||
867 | } | ||
868 | |||
869 | |||
870 | |||
871 | static inline int is_pipe_allocated(struct echoaudio *chip, u16 pipe_index) | ||
872 | { | ||
873 | return (chip->pipe_alloc_mask & (1 << pipe_index)); | ||
874 | } | ||
875 | |||
876 | |||
877 | |||
878 | /* Stops everything and turns off the DSP. All pipes should be already | ||
879 | stopped and unallocated. */ | ||
880 | static int rest_in_peace(struct echoaudio *chip) | ||
881 | { | ||
882 | DE_ACT(("rest_in_peace() open=%x\n", chip->pipe_alloc_mask)); | ||
883 | |||
884 | /* Stops all active pipes (just to be sure) */ | ||
885 | stop_transport(chip, chip->active_mask); | ||
886 | |||
887 | set_meters_on(chip, FALSE); | ||
888 | |||
889 | #ifdef ECHOCARD_HAS_MIDI | ||
890 | enable_midi_input(chip, FALSE); | ||
891 | #endif | ||
892 | |||
893 | /* Go to sleep */ | ||
894 | if (chip->dsp_code) { | ||
895 | /* Make load_firmware do a complete reload */ | ||
896 | chip->dsp_code = NULL; | ||
897 | /* Put the DSP to sleep */ | ||
898 | return send_vector(chip, DSP_VC_GO_COMATOSE); | ||
899 | } | ||
900 | return 0; | ||
901 | } | ||
902 | |||
903 | |||
904 | |||
905 | /* Fills the comm page with default values */ | ||
906 | static int init_dsp_comm_page(struct echoaudio *chip) | ||
907 | { | ||
908 | /* Check if the compiler added extra padding inside the structure */ | ||
909 | if (offsetof(struct comm_page, midi_output) != 0xbe0) { | ||
910 | DE_INIT(("init_dsp_comm_page() - Invalid struct comm_page structure\n")); | ||
911 | return -EPERM; | ||
912 | } | ||
913 | |||
914 | /* Init all the basic stuff */ | ||
915 | chip->card_name = ECHOCARD_NAME; | ||
916 | chip->bad_board = TRUE; /* Set TRUE until DSP loaded */ | ||
917 | chip->dsp_code = NULL; /* Current DSP code not loaded */ | ||
918 | chip->digital_mode = DIGITAL_MODE_NONE; | ||
919 | chip->input_clock = ECHO_CLOCK_INTERNAL; | ||
920 | chip->output_clock = ECHO_CLOCK_WORD; | ||
921 | chip->asic_loaded = FALSE; | ||
922 | memset(chip->comm_page, 0, sizeof(struct comm_page)); | ||
923 | |||
924 | /* Init the comm page */ | ||
925 | chip->comm_page->comm_size = | ||
926 | __constant_cpu_to_le32(sizeof(struct comm_page)); | ||
927 | chip->comm_page->handshake = 0xffffffff; | ||
928 | chip->comm_page->midi_out_free_count = | ||
929 | __constant_cpu_to_le32(DSP_MIDI_OUT_FIFO_SIZE); | ||
930 | chip->comm_page->sample_rate = __constant_cpu_to_le32(44100); | ||
931 | chip->sample_rate = 44100; | ||
932 | |||
933 | /* Set line levels so we don't blast any inputs on startup */ | ||
934 | memset(chip->comm_page->monitors, ECHOGAIN_MUTED, MONITOR_ARRAY_SIZE); | ||
935 | memset(chip->comm_page->vmixer, ECHOGAIN_MUTED, VMIXER_ARRAY_SIZE); | ||
936 | |||
937 | return 0; | ||
938 | } | ||
939 | |||
940 | |||
941 | |||
942 | /* This function initializes the several volume controls for busses and pipes. | ||
943 | This MUST be called after the DSP is up and running ! */ | ||
944 | static int init_line_levels(struct echoaudio *chip) | ||
945 | { | ||
946 | int st, i, o; | ||
947 | |||
948 | DE_INIT(("init_line_levels\n")); | ||
949 | |||
950 | /* Mute output busses */ | ||
951 | for (i = 0; i < num_busses_out(chip); i++) | ||
952 | if ((st = set_output_gain(chip, i, ECHOGAIN_MUTED))) | ||
953 | return st; | ||
954 | if ((st = update_output_line_level(chip))) | ||
955 | return st; | ||
956 | |||
957 | #ifdef ECHOCARD_HAS_VMIXER | ||
958 | /* Mute the Vmixer */ | ||
959 | for (i = 0; i < num_pipes_out(chip); i++) | ||
960 | for (o = 0; o < num_busses_out(chip); o++) | ||
961 | if ((st = set_vmixer_gain(chip, o, i, ECHOGAIN_MUTED))) | ||
962 | return st; | ||
963 | if ((st = update_vmixer_level(chip))) | ||
964 | return st; | ||
965 | #endif /* ECHOCARD_HAS_VMIXER */ | ||
966 | |||
967 | #ifdef ECHOCARD_HAS_MONITOR | ||
968 | /* Mute the monitor mixer */ | ||
969 | for (o = 0; o < num_busses_out(chip); o++) | ||
970 | for (i = 0; i < num_busses_in(chip); i++) | ||
971 | if ((st = set_monitor_gain(chip, o, i, ECHOGAIN_MUTED))) | ||
972 | return st; | ||
973 | if ((st = update_output_line_level(chip))) | ||
974 | return st; | ||
975 | #endif /* ECHOCARD_HAS_MONITOR */ | ||
976 | |||
977 | #ifdef ECHOCARD_HAS_INPUT_GAIN | ||
978 | for (i = 0; i < num_busses_in(chip); i++) | ||
979 | if ((st = set_input_gain(chip, i, ECHOGAIN_MUTED))) | ||
980 | return st; | ||
981 | if ((st = update_input_line_level(chip))) | ||
982 | return st; | ||
983 | #endif /* ECHOCARD_HAS_INPUT_GAIN */ | ||
984 | |||
985 | return 0; | ||
986 | } | ||
987 | |||
988 | |||
989 | |||
990 | /* This is low level part of the interrupt handler. | ||
991 | It returns -1 if the IRQ is not ours, or N>=0 if it is, where N is the number | ||
992 | of midi data in the input queue. */ | ||
993 | static int service_irq(struct echoaudio *chip) | ||
994 | { | ||
995 | int st; | ||
996 | |||
997 | /* Read the DSP status register and see if this DSP generated this interrupt */ | ||
998 | if (get_dsp_register(chip, CHI32_STATUS_REG) & CHI32_STATUS_IRQ) { | ||
999 | st = 0; | ||
1000 | #ifdef ECHOCARD_HAS_MIDI | ||
1001 | /* Get and parse midi data if present */ | ||
1002 | if (chip->comm_page->midi_input[0]) /* The count is at index 0 */ | ||
1003 | st = midi_service_irq(chip); /* Returns how many midi bytes we received */ | ||
1004 | #endif | ||
1005 | /* Clear the hardware interrupt */ | ||
1006 | chip->comm_page->midi_input[0] = 0; | ||
1007 | send_vector(chip, DSP_VC_ACK_INT); | ||
1008 | return st; | ||
1009 | } | ||
1010 | return -1; | ||
1011 | } | ||
1012 | |||
1013 | |||
1014 | |||
1015 | |||
1016 | /****************************************************************************** | ||
1017 | Functions for opening and closing pipes | ||
1018 | ******************************************************************************/ | ||
1019 | |||
1020 | /* allocate_pipes is used to reserve audio pipes for your exclusive use. | ||
1021 | The call will fail if some pipes are already allocated. */ | ||
1022 | static int allocate_pipes(struct echoaudio *chip, struct audiopipe *pipe, | ||
1023 | int pipe_index, int interleave) | ||
1024 | { | ||
1025 | int i; | ||
1026 | u32 channel_mask; | ||
1027 | char is_cyclic; | ||
1028 | |||
1029 | DE_ACT(("allocate_pipes: ch=%d int=%d\n", pipe_index, interleave)); | ||
1030 | |||
1031 | if (chip->bad_board) | ||
1032 | return -EIO; | ||
1033 | |||
1034 | is_cyclic = 1; /* This driver uses cyclic buffers only */ | ||
1035 | |||
1036 | for (channel_mask = i = 0; i < interleave; i++) | ||
1037 | channel_mask |= 1 << (pipe_index + i); | ||
1038 | if (chip->pipe_alloc_mask & channel_mask) { | ||
1039 | DE_ACT(("allocate_pipes: channel already open\n")); | ||
1040 | return -EAGAIN; | ||
1041 | } | ||
1042 | |||
1043 | chip->comm_page->position[pipe_index] = 0; | ||
1044 | chip->pipe_alloc_mask |= channel_mask; | ||
1045 | if (is_cyclic) | ||
1046 | chip->pipe_cyclic_mask |= channel_mask; | ||
1047 | pipe->index = pipe_index; | ||
1048 | pipe->interleave = interleave; | ||
1049 | pipe->state = PIPE_STATE_STOPPED; | ||
1050 | |||
1051 | /* The counter register is where the DSP writes the 32 bit DMA | ||
1052 | position for a pipe. The DSP is constantly updating this value as | ||
1053 | it moves data. The DMA counter is in units of bytes, not samples. */ | ||
1054 | pipe->dma_counter = &chip->comm_page->position[pipe_index]; | ||
1055 | *pipe->dma_counter = 0; | ||
1056 | DE_ACT(("allocate_pipes: ok\n")); | ||
1057 | return pipe_index; | ||
1058 | } | ||
1059 | |||
1060 | |||
1061 | |||
1062 | static int free_pipes(struct echoaudio *chip, struct audiopipe *pipe) | ||
1063 | { | ||
1064 | u32 channel_mask; | ||
1065 | int i; | ||
1066 | |||
1067 | DE_ACT(("free_pipes: Pipe %d\n", pipe->index)); | ||
1068 | snd_assert(is_pipe_allocated(chip, pipe->index), return -EINVAL); | ||
1069 | snd_assert(pipe->state == PIPE_STATE_STOPPED, return -EINVAL); | ||
1070 | |||
1071 | for (channel_mask = i = 0; i < pipe->interleave; i++) | ||
1072 | channel_mask |= 1 << (pipe->index + i); | ||
1073 | |||
1074 | chip->pipe_alloc_mask &= ~channel_mask; | ||
1075 | chip->pipe_cyclic_mask &= ~channel_mask; | ||
1076 | return 0; | ||
1077 | } | ||
1078 | |||
1079 | |||
1080 | |||
1081 | /****************************************************************************** | ||
1082 | Functions for managing the scatter-gather list | ||
1083 | ******************************************************************************/ | ||
1084 | |||
1085 | static int sglist_init(struct echoaudio *chip, struct audiopipe *pipe) | ||
1086 | { | ||
1087 | pipe->sglist_head = 0; | ||
1088 | memset(pipe->sgpage.area, 0, PAGE_SIZE); | ||
1089 | chip->comm_page->sglist_addr[pipe->index].addr = | ||
1090 | cpu_to_le32(pipe->sgpage.addr); | ||
1091 | return 0; | ||
1092 | } | ||
1093 | |||
1094 | |||
1095 | |||
1096 | static int sglist_add_mapping(struct echoaudio *chip, struct audiopipe *pipe, | ||
1097 | dma_addr_t address, size_t length) | ||
1098 | { | ||
1099 | int head = pipe->sglist_head; | ||
1100 | struct sg_entry *list = (struct sg_entry *)pipe->sgpage.area; | ||
1101 | |||
1102 | if (head < MAX_SGLIST_ENTRIES - 1) { | ||
1103 | list[head].addr = cpu_to_le32(address); | ||
1104 | list[head].size = cpu_to_le32(length); | ||
1105 | pipe->sglist_head++; | ||
1106 | } else { | ||
1107 | DE_ACT(("SGlist: too many fragments\n")); | ||
1108 | return -ENOMEM; | ||
1109 | } | ||
1110 | return 0; | ||
1111 | } | ||
1112 | |||
1113 | |||
1114 | |||
1115 | static inline int sglist_add_irq(struct echoaudio *chip, struct audiopipe *pipe) | ||
1116 | { | ||
1117 | return sglist_add_mapping(chip, pipe, 0, 0); | ||
1118 | } | ||
1119 | |||
1120 | |||
1121 | |||
1122 | static inline int sglist_wrap(struct echoaudio *chip, struct audiopipe *pipe) | ||
1123 | { | ||
1124 | return sglist_add_mapping(chip, pipe, pipe->sgpage.addr, 0); | ||
1125 | } | ||
diff --git a/sound/pci/echoaudio/echoaudio_dsp.h b/sound/pci/echoaudio/echoaudio_dsp.h new file mode 100644 index 000000000000..e55ee00991ac --- /dev/null +++ b/sound/pci/echoaudio/echoaudio_dsp.h | |||
@@ -0,0 +1,694 @@ | |||
1 | /**************************************************************************** | ||
2 | |||
3 | Copyright Echo Digital Audio Corporation (c) 1998 - 2004 | ||
4 | All rights reserved | ||
5 | www.echoaudio.com | ||
6 | |||
7 | This file is part of Echo Digital Audio's generic driver library. | ||
8 | |||
9 | Echo Digital Audio's generic driver library is free software; | ||
10 | you can redistribute it and/or modify it under the terms of | ||
11 | the GNU General Public License as published by the Free Software | ||
12 | Foundation. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, | ||
22 | MA 02111-1307, USA. | ||
23 | |||
24 | ************************************************************************* | ||
25 | |||
26 | Translation from C++ and adaptation for use in ALSA-Driver | ||
27 | were made by Giuliano Pochini <pochini@shiny.it> | ||
28 | |||
29 | ****************************************************************************/ | ||
30 | |||
31 | #ifndef _ECHO_DSP_ | ||
32 | #define _ECHO_DSP_ | ||
33 | |||
34 | |||
35 | /**** Echogals: Darla20, Gina20, Layla20, and Darla24 ****/ | ||
36 | #if defined(ECHOGALS_FAMILY) | ||
37 | |||
38 | #define NUM_ASIC_TESTS 5 | ||
39 | #define READ_DSP_TIMEOUT 1000000L /* one second */ | ||
40 | |||
41 | /**** Echo24: Gina24, Layla24, Mona, Mia, Mia-midi ****/ | ||
42 | #elif defined(ECHO24_FAMILY) | ||
43 | |||
44 | #define DSP_56361 /* Some Echo24 cards use the 56361 DSP */ | ||
45 | #define READ_DSP_TIMEOUT 100000L /* .1 second */ | ||
46 | |||
47 | /**** 3G: Gina3G, Layla3G ****/ | ||
48 | #elif defined(ECHO3G_FAMILY) | ||
49 | |||
50 | #define DSP_56361 | ||
51 | #define READ_DSP_TIMEOUT 100000L /* .1 second */ | ||
52 | #define MIN_MTC_1X_RATE 32000 | ||
53 | |||
54 | /**** Indigo: Indigo, Indigo IO, Indigo DJ ****/ | ||
55 | #elif defined(INDIGO_FAMILY) | ||
56 | |||
57 | #define DSP_56361 | ||
58 | #define READ_DSP_TIMEOUT 100000L /* .1 second */ | ||
59 | |||
60 | #else | ||
61 | |||
62 | #error No family is defined | ||
63 | |||
64 | #endif | ||
65 | |||
66 | |||
67 | |||
68 | /* | ||
69 | * | ||
70 | * Max inputs and outputs | ||
71 | * | ||
72 | */ | ||
73 | |||
74 | #define DSP_MAXAUDIOINPUTS 16 /* Max audio input channels */ | ||
75 | #define DSP_MAXAUDIOOUTPUTS 16 /* Max audio output channels */ | ||
76 | #define DSP_MAXPIPES 32 /* Max total pipes (input + output) */ | ||
77 | |||
78 | |||
79 | /* | ||
80 | * | ||
81 | * These are the offsets for the memory-mapped DSP registers; the DSP base | ||
82 | * address is treated as the start of a u32 array. | ||
83 | */ | ||
84 | |||
85 | #define CHI32_CONTROL_REG 4 | ||
86 | #define CHI32_STATUS_REG 5 | ||
87 | #define CHI32_VECTOR_REG 6 | ||
88 | #define CHI32_DATA_REG 7 | ||
89 | |||
90 | |||
91 | /* | ||
92 | * | ||
93 | * Interesting bits within the DSP registers | ||
94 | * | ||
95 | */ | ||
96 | |||
97 | #define CHI32_VECTOR_BUSY 0x00000001 | ||
98 | #define CHI32_STATUS_REG_HF3 0x00000008 | ||
99 | #define CHI32_STATUS_REG_HF4 0x00000010 | ||
100 | #define CHI32_STATUS_REG_HF5 0x00000020 | ||
101 | #define CHI32_STATUS_HOST_READ_FULL 0x00000004 | ||
102 | #define CHI32_STATUS_HOST_WRITE_EMPTY 0x00000002 | ||
103 | #define CHI32_STATUS_IRQ 0x00000040 | ||
104 | |||
105 | |||
106 | /* | ||
107 | * | ||
108 | * DSP commands sent via slave mode; these are sent to the DSP by write_dsp() | ||
109 | * | ||
110 | */ | ||
111 | |||
112 | #define DSP_FNC_SET_COMMPAGE_ADDR 0x02 | ||
113 | #define DSP_FNC_LOAD_LAYLA_ASIC 0xa0 | ||
114 | #define DSP_FNC_LOAD_GINA24_ASIC 0xa0 | ||
115 | #define DSP_FNC_LOAD_MONA_PCI_CARD_ASIC 0xa0 | ||
116 | #define DSP_FNC_LOAD_LAYLA24_PCI_CARD_ASIC 0xa0 | ||
117 | #define DSP_FNC_LOAD_MONA_EXTERNAL_ASIC 0xa1 | ||
118 | #define DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC 0xa1 | ||
119 | #define DSP_FNC_LOAD_3G_ASIC 0xa0 | ||
120 | |||
121 | |||
122 | /* | ||
123 | * | ||
124 | * Defines to handle the MIDI input state engine; these are used to properly | ||
125 | * extract MIDI time code bytes and their timestamps from the MIDI input stream. | ||
126 | * | ||
127 | */ | ||
128 | |||
129 | #define MIDI_IN_STATE_NORMAL 0 | ||
130 | #define MIDI_IN_STATE_TS_HIGH 1 | ||
131 | #define MIDI_IN_STATE_TS_LOW 2 | ||
132 | #define MIDI_IN_STATE_F1_DATA 3 | ||
133 | #define MIDI_IN_SKIP_DATA (-1) | ||
134 | |||
135 | |||
136 | /*---------------------------------------------------------------------------- | ||
137 | |||
138 | Setting the sample rates on Layla24 is somewhat schizophrenic. | ||
139 | |||
140 | For standard rates, it works exactly like Mona and Gina24. That is, for | ||
141 | 8, 11.025, 16, 22.05, 32, 44.1, 48, 88.2, and 96 kHz, you just set the | ||
142 | appropriate bits in the control register and write the control register. | ||
143 | |||
144 | In order to support MIDI time code sync (and possibly SMPTE LTC sync in | ||
145 | the future), Layla24 also has "continuous sample rate mode". In this mode, | ||
146 | Layla24 can generate any sample rate between 25 and 50 kHz inclusive, or | ||
147 | 50 to 100 kHz inclusive for double speed mode. | ||
148 | |||
149 | To use continuous mode: | ||
150 | |||
151 | -Set the clock select bits in the control register to 0xe (see the #define | ||
152 | below) | ||
153 | |||
154 | -Set double-speed mode if you want to use sample rates above 50 kHz | ||
155 | |||
156 | -Write the control register as you would normally | ||
157 | |||
158 | -Now, you need to set the frequency register. First, you need to determine the | ||
159 | value for the frequency register. This is given by the following formula: | ||
160 | |||
161 | frequency_reg = (LAYLA24_MAGIC_NUMBER / sample_rate) - 2 | ||
162 | |||
163 | Note the #define below for the magic number | ||
164 | |||
165 | -Wait for the DSP handshake | ||
166 | -Write the frequency_reg value to the .SampleRate field of the comm page | ||
167 | -Send the vector command SET_LAYLA24_FREQUENCY_REG (see vmonkey.h) | ||
168 | |||
169 | Once you have set the control register up for continuous mode, you can just | ||
170 | write the frequency register to change the sample rate. This could be | ||
171 | used for MIDI time code sync. For MTC sync, the control register is set for | ||
172 | continuous mode. The driver then just keeps writing the | ||
173 | SET_LAYLA24_FREQUENCY_REG command. | ||
174 | |||
175 | -----------------------------------------------------------------------------*/ | ||
176 | |||
177 | #define LAYLA24_MAGIC_NUMBER 677376000 | ||
178 | #define LAYLA24_CONTINUOUS_CLOCK 0x000e | ||
179 | |||
180 | |||
181 | /* | ||
182 | * | ||
183 | * DSP vector commands | ||
184 | * | ||
185 | */ | ||
186 | |||
187 | #define DSP_VC_RESET 0x80ff | ||
188 | |||
189 | #ifndef DSP_56361 | ||
190 | |||
191 | #define DSP_VC_ACK_INT 0x8073 | ||
192 | #define DSP_VC_SET_VMIXER_GAIN 0x0000 /* Not used, only for compile */ | ||
193 | #define DSP_VC_START_TRANSFER 0x0075 /* Handshke rqd. */ | ||
194 | #define DSP_VC_METERS_ON 0x0079 | ||
195 | #define DSP_VC_METERS_OFF 0x007b | ||
196 | #define DSP_VC_UPDATE_OUTVOL 0x007d /* Handshke rqd. */ | ||
197 | #define DSP_VC_UPDATE_INGAIN 0x007f /* Handshke rqd. */ | ||
198 | #define DSP_VC_ADD_AUDIO_BUFFER 0x0081 /* Handshke rqd. */ | ||
199 | #define DSP_VC_TEST_ASIC 0x00eb | ||
200 | #define DSP_VC_UPDATE_CLOCKS 0x00ef /* Handshke rqd. */ | ||
201 | #define DSP_VC_SET_LAYLA_SAMPLE_RATE 0x00f1 /* Handshke rqd. */ | ||
202 | #define DSP_VC_SET_GD_AUDIO_STATE 0x00f1 /* Handshke rqd. */ | ||
203 | #define DSP_VC_WRITE_CONTROL_REG 0x00f1 /* Handshke rqd. */ | ||
204 | #define DSP_VC_MIDI_WRITE 0x00f5 /* Handshke rqd. */ | ||
205 | #define DSP_VC_STOP_TRANSFER 0x00f7 /* Handshke rqd. */ | ||
206 | #define DSP_VC_UPDATE_FLAGS 0x00fd /* Handshke rqd. */ | ||
207 | #define DSP_VC_GO_COMATOSE 0x00f9 | ||
208 | |||
209 | #else /* !DSP_56361 */ | ||
210 | |||
211 | /* Vector commands for families that use either the 56301 or 56361 */ | ||
212 | #define DSP_VC_ACK_INT 0x80F5 | ||
213 | #define DSP_VC_SET_VMIXER_GAIN 0x00DB /* Handshke rqd. */ | ||
214 | #define DSP_VC_START_TRANSFER 0x00DD /* Handshke rqd. */ | ||
215 | #define DSP_VC_METERS_ON 0x00EF | ||
216 | #define DSP_VC_METERS_OFF 0x00F1 | ||
217 | #define DSP_VC_UPDATE_OUTVOL 0x00E3 /* Handshke rqd. */ | ||
218 | #define DSP_VC_UPDATE_INGAIN 0x00E5 /* Handshke rqd. */ | ||
219 | #define DSP_VC_ADD_AUDIO_BUFFER 0x00E1 /* Handshke rqd. */ | ||
220 | #define DSP_VC_TEST_ASIC 0x00ED | ||
221 | #define DSP_VC_UPDATE_CLOCKS 0x00E9 /* Handshke rqd. */ | ||
222 | #define DSP_VC_SET_LAYLA24_FREQUENCY_REG 0x00E9 /* Handshke rqd. */ | ||
223 | #define DSP_VC_SET_LAYLA_SAMPLE_RATE 0x00EB /* Handshke rqd. */ | ||
224 | #define DSP_VC_SET_GD_AUDIO_STATE 0x00EB /* Handshke rqd. */ | ||
225 | #define DSP_VC_WRITE_CONTROL_REG 0x00EB /* Handshke rqd. */ | ||
226 | #define DSP_VC_MIDI_WRITE 0x00E7 /* Handshke rqd. */ | ||
227 | #define DSP_VC_STOP_TRANSFER 0x00DF /* Handshke rqd. */ | ||
228 | #define DSP_VC_UPDATE_FLAGS 0x00FB /* Handshke rqd. */ | ||
229 | #define DSP_VC_GO_COMATOSE 0x00d9 | ||
230 | |||
231 | #endif /* !DSP_56361 */ | ||
232 | |||
233 | |||
234 | /* | ||
235 | * | ||
236 | * Timeouts | ||
237 | * | ||
238 | */ | ||
239 | |||
240 | #define HANDSHAKE_TIMEOUT 20000 /* send_vector command timeout (20ms) */ | ||
241 | #define VECTOR_BUSY_TIMEOUT 100000 /* 100ms */ | ||
242 | #define MIDI_OUT_DELAY_USEC 2000 /* How long to wait after MIDI fills up */ | ||
243 | |||
244 | |||
245 | /* | ||
246 | * | ||
247 | * Flags for .Flags field in the comm page | ||
248 | * | ||
249 | */ | ||
250 | |||
251 | #define DSP_FLAG_MIDI_INPUT 0x0001 /* Enable MIDI input */ | ||
252 | #define DSP_FLAG_SPDIF_NONAUDIO 0x0002 /* Sets the "non-audio" bit | ||
253 | * in the S/PDIF out status | ||
254 | * bits. Clear this flag for | ||
255 | * audio data; | ||
256 | * set it for AC3 or WMA or | ||
257 | * some such */ | ||
258 | #define DSP_FLAG_PROFESSIONAL_SPDIF 0x0008 /* 1 Professional, 0 Consumer */ | ||
259 | |||
260 | |||
261 | /* | ||
262 | * | ||
263 | * Clock detect bits reported by the DSP for Gina20, Layla20, Darla24, and Mia | ||
264 | * | ||
265 | */ | ||
266 | |||
267 | #define GLDM_CLOCK_DETECT_BIT_WORD 0x0002 | ||
268 | #define GLDM_CLOCK_DETECT_BIT_SUPER 0x0004 | ||
269 | #define GLDM_CLOCK_DETECT_BIT_SPDIF 0x0008 | ||
270 | #define GLDM_CLOCK_DETECT_BIT_ESYNC 0x0010 | ||
271 | |||
272 | |||
273 | /* | ||
274 | * | ||
275 | * Clock detect bits reported by the DSP for Gina24, Mona, and Layla24 | ||
276 | * | ||
277 | */ | ||
278 | |||
279 | #define GML_CLOCK_DETECT_BIT_WORD96 0x0002 | ||
280 | #define GML_CLOCK_DETECT_BIT_WORD48 0x0004 | ||
281 | #define GML_CLOCK_DETECT_BIT_SPDIF48 0x0008 | ||
282 | #define GML_CLOCK_DETECT_BIT_SPDIF96 0x0010 | ||
283 | #define GML_CLOCK_DETECT_BIT_WORD (GML_CLOCK_DETECT_BIT_WORD96 | GML_CLOCK_DETECT_BIT_WORD48) | ||
284 | #define GML_CLOCK_DETECT_BIT_SPDIF (GML_CLOCK_DETECT_BIT_SPDIF48 | GML_CLOCK_DETECT_BIT_SPDIF96) | ||
285 | #define GML_CLOCK_DETECT_BIT_ESYNC 0x0020 | ||
286 | #define GML_CLOCK_DETECT_BIT_ADAT 0x0040 | ||
287 | |||
288 | |||
289 | /* | ||
290 | * | ||
291 | * Layla clock numbers to send to DSP | ||
292 | * | ||
293 | */ | ||
294 | |||
295 | #define LAYLA20_CLOCK_INTERNAL 0 | ||
296 | #define LAYLA20_CLOCK_SPDIF 1 | ||
297 | #define LAYLA20_CLOCK_WORD 2 | ||
298 | #define LAYLA20_CLOCK_SUPER 3 | ||
299 | |||
300 | |||
301 | /* | ||
302 | * | ||
303 | * Gina/Darla clock states | ||
304 | * | ||
305 | */ | ||
306 | |||
307 | #define GD_CLOCK_NOCHANGE 0 | ||
308 | #define GD_CLOCK_44 1 | ||
309 | #define GD_CLOCK_48 2 | ||
310 | #define GD_CLOCK_SPDIFIN 3 | ||
311 | #define GD_CLOCK_UNDEF 0xff | ||
312 | |||
313 | |||
314 | /* | ||
315 | * | ||
316 | * Gina/Darla S/PDIF status bits | ||
317 | * | ||
318 | */ | ||
319 | |||
320 | #define GD_SPDIF_STATUS_NOCHANGE 0 | ||
321 | #define GD_SPDIF_STATUS_44 1 | ||
322 | #define GD_SPDIF_STATUS_48 2 | ||
323 | #define GD_SPDIF_STATUS_UNDEF 0xff | ||
324 | |||
325 | |||
326 | /* | ||
327 | * | ||
328 | * Layla20 output clocks | ||
329 | * | ||
330 | */ | ||
331 | |||
332 | #define LAYLA20_OUTPUT_CLOCK_SUPER 0 | ||
333 | #define LAYLA20_OUTPUT_CLOCK_WORD 1 | ||
334 | |||
335 | |||
336 | /**************************************************************************** | ||
337 | |||
338 | Magic constants for the Darla24 hardware | ||
339 | |||
340 | ****************************************************************************/ | ||
341 | |||
342 | #define GD24_96000 0x0 | ||
343 | #define GD24_48000 0x1 | ||
344 | #define GD24_44100 0x2 | ||
345 | #define GD24_32000 0x3 | ||
346 | #define GD24_22050 0x4 | ||
347 | #define GD24_16000 0x5 | ||
348 | #define GD24_11025 0x6 | ||
349 | #define GD24_8000 0x7 | ||
350 | #define GD24_88200 0x8 | ||
351 | #define GD24_EXT_SYNC 0x9 | ||
352 | |||
353 | |||
354 | /* | ||
355 | * | ||
356 | * Return values from the DSP when ASIC is loaded | ||
357 | * | ||
358 | */ | ||
359 | |||
360 | #define ASIC_ALREADY_LOADED 0x1 | ||
361 | #define ASIC_NOT_LOADED 0x0 | ||
362 | |||
363 | |||
364 | /* | ||
365 | * | ||
366 | * DSP Audio formats | ||
367 | * | ||
368 | * These are the audio formats that the DSP can transfer | ||
369 | * via input and output pipes. LE means little-endian, | ||
370 | * BE means big-endian. | ||
371 | * | ||
372 | * DSP_AUDIOFORM_MS_8 | ||
373 | * | ||
374 | * 8-bit mono unsigned samples. For playback, | ||
375 | * mono data is duplicated out the left and right channels | ||
376 | * of the output bus. The "MS" part of the name | ||
377 | * means mono->stereo. | ||
378 | * | ||
379 | * DSP_AUDIOFORM_MS_16LE | ||
380 | * | ||
381 | * 16-bit signed little-endian mono samples. Playback works | ||
382 | * like the previous code. | ||
383 | * | ||
384 | * DSP_AUDIOFORM_MS_24LE | ||
385 | * | ||
386 | * 24-bit signed little-endian mono samples. Data is packed | ||
387 | * three bytes per sample; if you had two samples 0x112233 and 0x445566 | ||
388 | * they would be stored in memory like this: 33 22 11 66 55 44. | ||
389 | * | ||
390 | * DSP_AUDIOFORM_MS_32LE | ||
391 | * | ||
392 | * 24-bit signed little-endian mono samples in a 32-bit | ||
393 | * container. In other words, each sample is a 32-bit signed | ||
394 | * integer, where the actual audio data is left-justified | ||
395 | * in the 32 bits and only the 24 most significant bits are valid. | ||
396 | * | ||
397 | * DSP_AUDIOFORM_SS_8 | ||
398 | * DSP_AUDIOFORM_SS_16LE | ||
399 | * DSP_AUDIOFORM_SS_24LE | ||
400 | * DSP_AUDIOFORM_SS_32LE | ||
401 | * | ||
402 | * Like the previous ones, except now with stereo interleaved | ||
403 | * data. "SS" means stereo->stereo. | ||
404 | * | ||
405 | * DSP_AUDIOFORM_MM_32LE | ||
406 | * | ||
407 | * Similar to DSP_AUDIOFORM_MS_32LE, except that the mono | ||
408 | * data is not duplicated out both the left and right outputs. | ||
409 | * This mode is used by the ASIO driver. Here, "MM" means | ||
410 | * mono->mono. | ||
411 | * | ||
412 | * DSP_AUDIOFORM_MM_32BE | ||
413 | * | ||
414 | * Just like DSP_AUDIOFORM_MM_32LE, but now the data is | ||
415 | * in big-endian format. | ||
416 | * | ||
417 | */ | ||
418 | |||
419 | #define DSP_AUDIOFORM_MS_8 0 /* 8 bit mono */ | ||
420 | #define DSP_AUDIOFORM_MS_16LE 1 /* 16 bit mono */ | ||
421 | #define DSP_AUDIOFORM_MS_24LE 2 /* 24 bit mono */ | ||
422 | #define DSP_AUDIOFORM_MS_32LE 3 /* 32 bit mono */ | ||
423 | #define DSP_AUDIOFORM_SS_8 4 /* 8 bit stereo */ | ||
424 | #define DSP_AUDIOFORM_SS_16LE 5 /* 16 bit stereo */ | ||
425 | #define DSP_AUDIOFORM_SS_24LE 6 /* 24 bit stereo */ | ||
426 | #define DSP_AUDIOFORM_SS_32LE 7 /* 32 bit stereo */ | ||
427 | #define DSP_AUDIOFORM_MM_32LE 8 /* 32 bit mono->mono little-endian */ | ||
428 | #define DSP_AUDIOFORM_MM_32BE 9 /* 32 bit mono->mono big-endian */ | ||
429 | #define DSP_AUDIOFORM_SS_32BE 10 /* 32 bit stereo big endian */ | ||
430 | #define DSP_AUDIOFORM_INVALID 0xFF /* Invalid audio format */ | ||
431 | |||
432 | |||
433 | /* | ||
434 | * | ||
435 | * Super-interleave is defined as interleaving by 4 or more. Darla20 and Gina20 | ||
436 | * do not support super interleave. | ||
437 | * | ||
438 | * 16 bit, 24 bit, and 32 bit little endian samples are supported for super | ||
439 | * interleave. The interleave factor must be even. 16 - way interleave is the | ||
440 | * current maximum, so you can interleave by 4, 6, 8, 10, 12, 14, and 16. | ||
441 | * | ||
442 | * The actual format code is derived by taking the define below and or-ing with | ||
443 | * the interleave factor. So, 32 bit interleave by 6 is 0x86 and | ||
444 | * 16 bit interleave by 16 is (0x40 | 0x10) = 0x50. | ||
445 | * | ||
446 | */ | ||
447 | |||
448 | #define DSP_AUDIOFORM_SUPER_INTERLEAVE_16LE 0x40 | ||
449 | #define DSP_AUDIOFORM_SUPER_INTERLEAVE_24LE 0xc0 | ||
450 | #define DSP_AUDIOFORM_SUPER_INTERLEAVE_32LE 0x80 | ||
451 | |||
452 | |||
453 | /* | ||
454 | * | ||
455 | * Gina24, Mona, and Layla24 control register defines | ||
456 | * | ||
457 | */ | ||
458 | |||
459 | #define GML_CONVERTER_ENABLE 0x0010 | ||
460 | #define GML_SPDIF_PRO_MODE 0x0020 /* Professional S/PDIF == 1, | ||
461 | consumer == 0 */ | ||
462 | #define GML_SPDIF_SAMPLE_RATE0 0x0040 | ||
463 | #define GML_SPDIF_SAMPLE_RATE1 0x0080 | ||
464 | #define GML_SPDIF_TWO_CHANNEL 0x0100 /* 1 == two channels, | ||
465 | 0 == one channel */ | ||
466 | #define GML_SPDIF_NOT_AUDIO 0x0200 | ||
467 | #define GML_SPDIF_COPY_PERMIT 0x0400 | ||
468 | #define GML_SPDIF_24_BIT 0x0800 /* 1 == 24 bit, 0 == 20 bit */ | ||
469 | #define GML_ADAT_MODE 0x1000 /* 1 == ADAT mode, 0 == S/PDIF mode */ | ||
470 | #define GML_SPDIF_OPTICAL_MODE 0x2000 /* 1 == optical mode, 0 == RCA mode */ | ||
471 | #define GML_SPDIF_CDROM_MODE 0x3000 /* 1 == CDROM mode, | ||
472 | * 0 == RCA or optical mode */ | ||
473 | #define GML_DOUBLE_SPEED_MODE 0x4000 /* 1 == double speed, | ||
474 | 0 == single speed */ | ||
475 | |||
476 | #define GML_DIGITAL_IN_AUTO_MUTE 0x800000 | ||
477 | |||
478 | #define GML_96KHZ (0x0 | GML_DOUBLE_SPEED_MODE) | ||
479 | #define GML_88KHZ (0x1 | GML_DOUBLE_SPEED_MODE) | ||
480 | #define GML_48KHZ 0x2 | ||
481 | #define GML_44KHZ 0x3 | ||
482 | #define GML_32KHZ 0x4 | ||
483 | #define GML_22KHZ 0x5 | ||
484 | #define GML_16KHZ 0x6 | ||
485 | #define GML_11KHZ 0x7 | ||
486 | #define GML_8KHZ 0x8 | ||
487 | #define GML_SPDIF_CLOCK 0x9 | ||
488 | #define GML_ADAT_CLOCK 0xA | ||
489 | #define GML_WORD_CLOCK 0xB | ||
490 | #define GML_ESYNC_CLOCK 0xC | ||
491 | #define GML_ESYNCx2_CLOCK 0xD | ||
492 | |||
493 | #define GML_CLOCK_CLEAR_MASK 0xffffbff0 | ||
494 | #define GML_SPDIF_RATE_CLEAR_MASK (~(GML_SPDIF_SAMPLE_RATE0|GML_SPDIF_SAMPLE_RATE1)) | ||
495 | #define GML_DIGITAL_MODE_CLEAR_MASK 0xffffcfff | ||
496 | #define GML_SPDIF_FORMAT_CLEAR_MASK 0xfffff01f | ||
497 | |||
498 | |||
499 | /* | ||
500 | * | ||
501 | * Mia sample rate and clock setting constants | ||
502 | * | ||
503 | */ | ||
504 | |||
505 | #define MIA_32000 0x0040 | ||
506 | #define MIA_44100 0x0042 | ||
507 | #define MIA_48000 0x0041 | ||
508 | #define MIA_88200 0x0142 | ||
509 | #define MIA_96000 0x0141 | ||
510 | |||
511 | #define MIA_SPDIF 0x00000044 | ||
512 | #define MIA_SPDIF96 0x00000144 | ||
513 | |||
514 | #define MIA_MIDI_REV 1 /* Must be Mia rev 1 for MIDI support */ | ||
515 | |||
516 | |||
517 | /* | ||
518 | * | ||
519 | * 3G register bits | ||
520 | * | ||
521 | */ | ||
522 | |||
523 | #define E3G_CONVERTER_ENABLE 0x0010 | ||
524 | #define E3G_SPDIF_PRO_MODE 0x0020 /* Professional S/PDIF == 1, | ||
525 | consumer == 0 */ | ||
526 | #define E3G_SPDIF_SAMPLE_RATE0 0x0040 | ||
527 | #define E3G_SPDIF_SAMPLE_RATE1 0x0080 | ||
528 | #define E3G_SPDIF_TWO_CHANNEL 0x0100 /* 1 == two channels, | ||
529 | 0 == one channel */ | ||
530 | #define E3G_SPDIF_NOT_AUDIO 0x0200 | ||
531 | #define E3G_SPDIF_COPY_PERMIT 0x0400 | ||
532 | #define E3G_SPDIF_24_BIT 0x0800 /* 1 == 24 bit, 0 == 20 bit */ | ||
533 | #define E3G_DOUBLE_SPEED_MODE 0x4000 /* 1 == double speed, | ||
534 | 0 == single speed */ | ||
535 | #define E3G_PHANTOM_POWER 0x8000 /* 1 == phantom power on, | ||
536 | 0 == phantom power off */ | ||
537 | |||
538 | #define E3G_96KHZ (0x0 | E3G_DOUBLE_SPEED_MODE) | ||
539 | #define E3G_88KHZ (0x1 | E3G_DOUBLE_SPEED_MODE) | ||
540 | #define E3G_48KHZ 0x2 | ||
541 | #define E3G_44KHZ 0x3 | ||
542 | #define E3G_32KHZ 0x4 | ||
543 | #define E3G_22KHZ 0x5 | ||
544 | #define E3G_16KHZ 0x6 | ||
545 | #define E3G_11KHZ 0x7 | ||
546 | #define E3G_8KHZ 0x8 | ||
547 | #define E3G_SPDIF_CLOCK 0x9 | ||
548 | #define E3G_ADAT_CLOCK 0xA | ||
549 | #define E3G_WORD_CLOCK 0xB | ||
550 | #define E3G_CONTINUOUS_CLOCK 0xE | ||
551 | |||
552 | #define E3G_ADAT_MODE 0x1000 | ||
553 | #define E3G_SPDIF_OPTICAL_MODE 0x2000 | ||
554 | |||
555 | #define E3G_CLOCK_CLEAR_MASK 0xbfffbff0 | ||
556 | #define E3G_DIGITAL_MODE_CLEAR_MASK 0xffffcfff | ||
557 | #define E3G_SPDIF_FORMAT_CLEAR_MASK 0xfffff01f | ||
558 | |||
559 | /* Clock detect bits reported by the DSP */ | ||
560 | #define E3G_CLOCK_DETECT_BIT_WORD96 0x0001 | ||
561 | #define E3G_CLOCK_DETECT_BIT_WORD48 0x0002 | ||
562 | #define E3G_CLOCK_DETECT_BIT_SPDIF48 0x0004 | ||
563 | #define E3G_CLOCK_DETECT_BIT_ADAT 0x0004 | ||
564 | #define E3G_CLOCK_DETECT_BIT_SPDIF96 0x0008 | ||
565 | #define E3G_CLOCK_DETECT_BIT_WORD (E3G_CLOCK_DETECT_BIT_WORD96|E3G_CLOCK_DETECT_BIT_WORD48) | ||
566 | #define E3G_CLOCK_DETECT_BIT_SPDIF (E3G_CLOCK_DETECT_BIT_SPDIF48|E3G_CLOCK_DETECT_BIT_SPDIF96) | ||
567 | |||
568 | /* Frequency control register */ | ||
569 | #define E3G_MAGIC_NUMBER 677376000 | ||
570 | #define E3G_FREQ_REG_DEFAULT (E3G_MAGIC_NUMBER / 48000 - 2) | ||
571 | #define E3G_FREQ_REG_MAX 0xffff | ||
572 | |||
573 | /* 3G external box types */ | ||
574 | #define E3G_GINA3G_BOX_TYPE 0x00 | ||
575 | #define E3G_LAYLA3G_BOX_TYPE 0x10 | ||
576 | #define E3G_ASIC_NOT_LOADED 0xffff | ||
577 | #define E3G_BOX_TYPE_MASK 0xf0 | ||
578 | |||
579 | #define EXT_3GBOX_NC 0x01 | ||
580 | #define EXT_3GBOX_NOT_SET 0x02 | ||
581 | |||
582 | |||
583 | /* | ||
584 | * | ||
585 | * Gina20 & Layla20 have input gain controls for the analog inputs; | ||
586 | * this is the magic number for the hardware that gives you 0 dB at -10. | ||
587 | * | ||
588 | */ | ||
589 | |||
590 | #define GL20_INPUT_GAIN_MAGIC_NUMBER 0xC8 | ||
591 | |||
592 | |||
593 | /* | ||
594 | * | ||
595 | * Defines how much time must pass between DSP load attempts | ||
596 | * | ||
597 | */ | ||
598 | |||
599 | #define DSP_LOAD_ATTEMPT_PERIOD 1000000L /* One second */ | ||
600 | |||
601 | |||
602 | /* | ||
603 | * | ||
604 | * Size of arrays for the comm page. MAX_PLAY_TAPS and MAX_REC_TAPS are | ||
605 | * no longer used, but the sizes must still be right for the DSP to see | ||
606 | * the comm page correctly. | ||
607 | * | ||
608 | */ | ||
609 | |||
610 | #define MONITOR_ARRAY_SIZE 0x180 | ||
611 | #define VMIXER_ARRAY_SIZE 0x40 | ||
612 | #define MIDI_OUT_BUFFER_SIZE 32 | ||
613 | #define MIDI_IN_BUFFER_SIZE 256 | ||
614 | #define MAX_PLAY_TAPS 168 | ||
615 | #define MAX_REC_TAPS 192 | ||
616 | #define DSP_MIDI_OUT_FIFO_SIZE 64 | ||
617 | |||
618 | |||
619 | /* sg_entry is a single entry for the scatter-gather list. The array of struct | ||
620 | sg_entry struct is read by the DSP, so all values must be little-endian. */ | ||
621 | |||
622 | #define MAX_SGLIST_ENTRIES 512 | ||
623 | |||
624 | struct sg_entry { | ||
625 | u32 addr; | ||
626 | u32 size; | ||
627 | }; | ||
628 | |||
629 | |||
630 | /**************************************************************************** | ||
631 | |||
632 | The comm page. This structure is read and written by the DSP; the | ||
633 | DSP code is a firm believer in the byte offsets written in the comments | ||
634 | at the end of each line. This structure should not be changed. | ||
635 | |||
636 | Any reads from or writes to this structure should be in little-endian format. | ||
637 | |||
638 | ****************************************************************************/ | ||
639 | |||
640 | struct comm_page { /* Base Length*/ | ||
641 | u32 comm_size; /* size of this object 0x000 4 */ | ||
642 | u32 flags; /* See Appendix A below 0x004 4 */ | ||
643 | u32 unused; /* Unused entry 0x008 4 */ | ||
644 | u32 sample_rate; /* Card sample rate in Hz 0x00c 4 */ | ||
645 | volatile u32 handshake; /* DSP command handshake 0x010 4 */ | ||
646 | u32 cmd_start; /* Chs. to start mask 0x014 4 */ | ||
647 | u32 cmd_stop; /* Chs. to stop mask 0x018 4 */ | ||
648 | u32 cmd_reset; /* Chs. to reset mask 0x01c 4 */ | ||
649 | u16 audio_format[DSP_MAXPIPES]; /* Chs. audio format 0x020 32*2 */ | ||
650 | struct sg_entry sglist_addr[DSP_MAXPIPES]; | ||
651 | /* Chs. Physical sglist addrs 0x060 32*8 */ | ||
652 | volatile u32 position[DSP_MAXPIPES]; | ||
653 | /* Positions for ea. ch. 0x160 32*4 */ | ||
654 | volatile s8 vu_meter[DSP_MAXPIPES]; | ||
655 | /* VU meters 0x1e0 32*1 */ | ||
656 | volatile s8 peak_meter[DSP_MAXPIPES]; | ||
657 | /* Peak meters 0x200 32*1 */ | ||
658 | s8 line_out_level[DSP_MAXAUDIOOUTPUTS]; | ||
659 | /* Output gain 0x220 16*1 */ | ||
660 | s8 line_in_level[DSP_MAXAUDIOINPUTS]; | ||
661 | /* Input gain 0x230 16*1 */ | ||
662 | s8 monitors[MONITOR_ARRAY_SIZE]; | ||
663 | /* Monitor map 0x240 0x180 */ | ||
664 | u32 play_coeff[MAX_PLAY_TAPS]; | ||
665 | /* Gina/Darla play filters - obsolete 0x3c0 168*4 */ | ||
666 | u32 rec_coeff[MAX_REC_TAPS]; | ||
667 | /* Gina/Darla record filters - obsolete 0x660 192*4 */ | ||
668 | volatile u16 midi_input[MIDI_IN_BUFFER_SIZE]; | ||
669 | /* MIDI input data transfer buffer 0x960 256*2 */ | ||
670 | u8 gd_clock_state; /* Chg Gina/Darla clock state 0xb60 1 */ | ||
671 | u8 gd_spdif_status; /* Chg. Gina/Darla S/PDIF state 0xb61 1 */ | ||
672 | u8 gd_resampler_state; /* Should always be 3 0xb62 1 */ | ||
673 | u8 filler2; /* 0xb63 1 */ | ||
674 | u32 nominal_level_mask; /* -10 level enable mask 0xb64 4 */ | ||
675 | u16 input_clock; /* Chg. Input clock state 0xb68 2 */ | ||
676 | u16 output_clock; /* Chg. Output clock state 0xb6a 2 */ | ||
677 | volatile u32 status_clocks; | ||
678 | /* Current Input clock state 0xb6c 4 */ | ||
679 | u32 ext_box_status; /* External box status 0xb70 4 */ | ||
680 | u32 cmd_add_buffer; /* Pipes to add (obsolete) 0xb74 4 */ | ||
681 | volatile u32 midi_out_free_count; | ||
682 | /* # of bytes free in MIDI output FIFO 0xb78 4 */ | ||
683 | u32 unused2; /* Cyclic pipes 0xb7c 4 */ | ||
684 | u32 control_register; | ||
685 | /* Mona, Gina24, Layla24, 3G ctrl reg 0xb80 4 */ | ||
686 | u32 e3g_frq_register; /* 3G frequency register 0xb84 4 */ | ||
687 | u8 filler[24]; /* filler 0xb88 24*1 */ | ||
688 | s8 vmixer[VMIXER_ARRAY_SIZE]; | ||
689 | /* Vmixer levels 0xba0 64*1 */ | ||
690 | u8 midi_output[MIDI_OUT_BUFFER_SIZE]; | ||
691 | /* MIDI output data 0xbe0 32*1 */ | ||
692 | }; | ||
693 | |||
694 | #endif /* _ECHO_DSP_ */ | ||
diff --git a/sound/pci/echoaudio/echoaudio_gml.c b/sound/pci/echoaudio/echoaudio_gml.c new file mode 100644 index 000000000000..3aa37e76ebab --- /dev/null +++ b/sound/pci/echoaudio/echoaudio_gml.c | |||
@@ -0,0 +1,198 @@ | |||
1 | /**************************************************************************** | ||
2 | |||
3 | Copyright Echo Digital Audio Corporation (c) 1998 - 2004 | ||
4 | All rights reserved | ||
5 | www.echoaudio.com | ||
6 | |||
7 | This file is part of Echo Digital Audio's generic driver library. | ||
8 | |||
9 | Echo Digital Audio's generic driver library is free software; | ||
10 | you can redistribute it and/or modify it under the terms of | ||
11 | the GNU General Public License as published by the Free Software | ||
12 | Foundation. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, | ||
22 | MA 02111-1307, USA. | ||
23 | |||
24 | ************************************************************************* | ||
25 | |||
26 | Translation from C++ and adaptation for use in ALSA-Driver | ||
27 | were made by Giuliano Pochini <pochini@shiny.it> | ||
28 | |||
29 | ****************************************************************************/ | ||
30 | |||
31 | |||
32 | /* These functions are common for Gina24, Layla24 and Mona cards */ | ||
33 | |||
34 | |||
35 | /* ASIC status check - some cards have one or two ASICs that need to be | ||
36 | loaded. Once that load is complete, this function is called to see if | ||
37 | the load was successful. | ||
38 | If this load fails, it does not necessarily mean that the hardware is | ||
39 | defective - the external box may be disconnected or turned off. */ | ||
40 | static int check_asic_status(struct echoaudio *chip) | ||
41 | { | ||
42 | u32 asic_status; | ||
43 | |||
44 | send_vector(chip, DSP_VC_TEST_ASIC); | ||
45 | |||
46 | /* The DSP will return a value to indicate whether or not the | ||
47 | ASIC is currently loaded */ | ||
48 | if (read_dsp(chip, &asic_status) < 0) { | ||
49 | DE_INIT(("check_asic_status: failed on read_dsp\n")); | ||
50 | chip->asic_loaded = FALSE; | ||
51 | return -EIO; | ||
52 | } | ||
53 | |||
54 | chip->asic_loaded = (asic_status == ASIC_ALREADY_LOADED); | ||
55 | return chip->asic_loaded ? 0 : -EIO; | ||
56 | } | ||
57 | |||
58 | |||
59 | |||
60 | /* Most configuration of Gina24, Layla24, or Mona is accomplished by writing | ||
61 | the control register. write_control_reg sends the new control register | ||
62 | value to the DSP. */ | ||
63 | static int write_control_reg(struct echoaudio *chip, u32 value, char force) | ||
64 | { | ||
65 | /* Handle the digital input auto-mute */ | ||
66 | if (chip->digital_in_automute) | ||
67 | value |= GML_DIGITAL_IN_AUTO_MUTE; | ||
68 | else | ||
69 | value &= ~GML_DIGITAL_IN_AUTO_MUTE; | ||
70 | |||
71 | DE_ACT(("write_control_reg: 0x%x\n", value)); | ||
72 | |||
73 | /* Write the control register */ | ||
74 | value = cpu_to_le32(value); | ||
75 | if (value != chip->comm_page->control_register || force) { | ||
76 | if (wait_handshake(chip)) | ||
77 | return -EIO; | ||
78 | chip->comm_page->control_register = value; | ||
79 | clear_handshake(chip); | ||
80 | return send_vector(chip, DSP_VC_WRITE_CONTROL_REG); | ||
81 | } | ||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | |||
86 | |||
87 | /* Gina24, Layla24, and Mona support digital input auto-mute. If the digital | ||
88 | input auto-mute is enabled, the DSP will only enable the digital inputs if | ||
89 | the card is syncing to a valid clock on the ADAT or S/PDIF inputs. | ||
90 | If the auto-mute is disabled, the digital inputs are enabled regardless of | ||
91 | what the input clock is set or what is connected. */ | ||
92 | static int set_input_auto_mute(struct echoaudio *chip, int automute) | ||
93 | { | ||
94 | DE_ACT(("set_input_auto_mute %d\n", automute)); | ||
95 | |||
96 | chip->digital_in_automute = automute; | ||
97 | |||
98 | /* Re-set the input clock to the current value - indirectly causes | ||
99 | the auto-mute flag to be sent to the DSP */ | ||
100 | return set_input_clock(chip, chip->input_clock); | ||
101 | } | ||
102 | |||
103 | |||
104 | |||
105 | /* S/PDIF coax / S/PDIF optical / ADAT - switch */ | ||
106 | static int set_digital_mode(struct echoaudio *chip, u8 mode) | ||
107 | { | ||
108 | u8 previous_mode; | ||
109 | int err, i, o; | ||
110 | |||
111 | if (chip->bad_board) | ||
112 | return -EIO; | ||
113 | |||
114 | /* All audio channels must be closed before changing the digital mode */ | ||
115 | snd_assert(!chip->pipe_alloc_mask, return -EAGAIN); | ||
116 | |||
117 | snd_assert(chip->digital_modes & (1 << mode), return -EINVAL); | ||
118 | |||
119 | previous_mode = chip->digital_mode; | ||
120 | err = dsp_set_digital_mode(chip, mode); | ||
121 | |||
122 | /* If we successfully changed the digital mode from or to ADAT, | ||
123 | then make sure all output, input and monitor levels are | ||
124 | updated by the DSP comm object. */ | ||
125 | if (err >= 0 && previous_mode != mode && | ||
126 | (previous_mode == DIGITAL_MODE_ADAT || mode == DIGITAL_MODE_ADAT)) { | ||
127 | spin_lock_irq(&chip->lock); | ||
128 | for (o = 0; o < num_busses_out(chip); o++) | ||
129 | for (i = 0; i < num_busses_in(chip); i++) | ||
130 | set_monitor_gain(chip, o, i, | ||
131 | chip->monitor_gain[o][i]); | ||
132 | |||
133 | #ifdef ECHOCARD_HAS_INPUT_GAIN | ||
134 | for (i = 0; i < num_busses_in(chip); i++) | ||
135 | set_input_gain(chip, i, chip->input_gain[i]); | ||
136 | update_input_line_level(chip); | ||
137 | #endif | ||
138 | |||
139 | for (o = 0; o < num_busses_out(chip); o++) | ||
140 | set_output_gain(chip, o, chip->output_gain[o]); | ||
141 | update_output_line_level(chip); | ||
142 | spin_unlock_irq(&chip->lock); | ||
143 | } | ||
144 | |||
145 | return err; | ||
146 | } | ||
147 | |||
148 | |||
149 | |||
150 | /* Set the S/PDIF output format */ | ||
151 | static int set_professional_spdif(struct echoaudio *chip, char prof) | ||
152 | { | ||
153 | u32 control_reg; | ||
154 | int err; | ||
155 | |||
156 | /* Clear the current S/PDIF flags */ | ||
157 | control_reg = le32_to_cpu(chip->comm_page->control_register); | ||
158 | control_reg &= GML_SPDIF_FORMAT_CLEAR_MASK; | ||
159 | |||
160 | /* Set the new S/PDIF flags depending on the mode */ | ||
161 | control_reg |= GML_SPDIF_TWO_CHANNEL | GML_SPDIF_24_BIT | | ||
162 | GML_SPDIF_COPY_PERMIT; | ||
163 | if (prof) { | ||
164 | /* Professional mode */ | ||
165 | control_reg |= GML_SPDIF_PRO_MODE; | ||
166 | |||
167 | switch (chip->sample_rate) { | ||
168 | case 32000: | ||
169 | control_reg |= GML_SPDIF_SAMPLE_RATE0 | | ||
170 | GML_SPDIF_SAMPLE_RATE1; | ||
171 | break; | ||
172 | case 44100: | ||
173 | control_reg |= GML_SPDIF_SAMPLE_RATE0; | ||
174 | break; | ||
175 | case 48000: | ||
176 | control_reg |= GML_SPDIF_SAMPLE_RATE1; | ||
177 | break; | ||
178 | } | ||
179 | } else { | ||
180 | /* Consumer mode */ | ||
181 | switch (chip->sample_rate) { | ||
182 | case 32000: | ||
183 | control_reg |= GML_SPDIF_SAMPLE_RATE0 | | ||
184 | GML_SPDIF_SAMPLE_RATE1; | ||
185 | break; | ||
186 | case 48000: | ||
187 | control_reg |= GML_SPDIF_SAMPLE_RATE1; | ||
188 | break; | ||
189 | } | ||
190 | } | ||
191 | |||
192 | if ((err = write_control_reg(chip, control_reg, FALSE))) | ||
193 | return err; | ||
194 | chip->professional_spdif = prof; | ||
195 | DE_ACT(("set_professional_spdif to %s\n", | ||
196 | prof ? "Professional" : "Consumer")); | ||
197 | return 0; | ||
198 | } | ||
diff --git a/sound/pci/echoaudio/gina20.c b/sound/pci/echoaudio/gina20.c new file mode 100644 index 000000000000..29d6d12f80ca --- /dev/null +++ b/sound/pci/echoaudio/gina20.c | |||
@@ -0,0 +1,103 @@ | |||
1 | /* | ||
2 | * ALSA driver for Echoaudio soundcards. | ||
3 | * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #define ECHOGALS_FAMILY | ||
20 | #define ECHOCARD_GINA20 | ||
21 | #define ECHOCARD_NAME "Gina20" | ||
22 | #define ECHOCARD_HAS_MONITOR | ||
23 | #define ECHOCARD_HAS_INPUT_GAIN | ||
24 | #define ECHOCARD_HAS_DIGITAL_IO | ||
25 | #define ECHOCARD_HAS_EXTERNAL_CLOCK | ||
26 | #define ECHOCARD_HAS_ADAT FALSE | ||
27 | |||
28 | /* Pipe indexes */ | ||
29 | #define PX_ANALOG_OUT 0 /* 8 */ | ||
30 | #define PX_DIGITAL_OUT 8 /* 2 */ | ||
31 | #define PX_ANALOG_IN 10 /* 2 */ | ||
32 | #define PX_DIGITAL_IN 12 /* 2 */ | ||
33 | #define PX_NUM 14 | ||
34 | |||
35 | /* Bus indexes */ | ||
36 | #define BX_ANALOG_OUT 0 /* 8 */ | ||
37 | #define BX_DIGITAL_OUT 8 /* 2 */ | ||
38 | #define BX_ANALOG_IN 10 /* 2 */ | ||
39 | #define BX_DIGITAL_IN 12 /* 2 */ | ||
40 | #define BX_NUM 14 | ||
41 | |||
42 | |||
43 | #include <sound/driver.h> | ||
44 | #include <linux/delay.h> | ||
45 | #include <linux/init.h> | ||
46 | #include <linux/interrupt.h> | ||
47 | #include <linux/pci.h> | ||
48 | #include <linux/slab.h> | ||
49 | #include <linux/moduleparam.h> | ||
50 | #include <linux/firmware.h> | ||
51 | #include <sound/core.h> | ||
52 | #include <sound/info.h> | ||
53 | #include <sound/control.h> | ||
54 | #include <sound/pcm.h> | ||
55 | #include <sound/pcm_params.h> | ||
56 | #include <sound/asoundef.h> | ||
57 | #include <sound/initval.h> | ||
58 | #include <asm/io.h> | ||
59 | #include <asm/atomic.h> | ||
60 | #include "echoaudio.h" | ||
61 | |||
62 | #define FW_GINA20_DSP 0 | ||
63 | |||
64 | static const struct firmware card_fw[] = { | ||
65 | {0, "gina20_dsp.fw"} | ||
66 | }; | ||
67 | |||
68 | static struct pci_device_id snd_echo_ids[] = { | ||
69 | {0x1057, 0x1801, 0xECC0, 0x0020, 0, 0, 0}, /* DSP 56301 Gina20 rev.0 */ | ||
70 | {0,} | ||
71 | }; | ||
72 | |||
73 | static struct snd_pcm_hardware pcm_hardware_skel = { | ||
74 | .info = SNDRV_PCM_INFO_MMAP | | ||
75 | SNDRV_PCM_INFO_INTERLEAVED | | ||
76 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
77 | SNDRV_PCM_INFO_MMAP_VALID | | ||
78 | SNDRV_PCM_INFO_PAUSE | | ||
79 | SNDRV_PCM_INFO_SYNC_START, | ||
80 | .formats = SNDRV_PCM_FMTBIT_U8 | | ||
81 | SNDRV_PCM_FMTBIT_S16_LE | | ||
82 | SNDRV_PCM_FMTBIT_S24_3LE | | ||
83 | SNDRV_PCM_FMTBIT_S32_LE | | ||
84 | SNDRV_PCM_FMTBIT_S32_BE, | ||
85 | .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, | ||
86 | .rate_min = 44100, | ||
87 | .rate_max = 48000, | ||
88 | .channels_min = 1, | ||
89 | .channels_max = 2, | ||
90 | .buffer_bytes_max = 262144, | ||
91 | .period_bytes_min = 32, | ||
92 | .period_bytes_max = 131072, | ||
93 | .periods_min = 2, | ||
94 | .periods_max = 220, | ||
95 | /* One page (4k) contains 512 instructions. I don't know if the hw | ||
96 | supports lists longer than this. In this case periods_max=220 is a | ||
97 | safe limit to make sure the list never exceeds 512 instructions. */ | ||
98 | }; | ||
99 | |||
100 | |||
101 | #include "gina20_dsp.c" | ||
102 | #include "echoaudio_dsp.c" | ||
103 | #include "echoaudio.c" | ||
diff --git a/sound/pci/echoaudio/gina20_dsp.c b/sound/pci/echoaudio/gina20_dsp.c new file mode 100644 index 000000000000..2757c8960843 --- /dev/null +++ b/sound/pci/echoaudio/gina20_dsp.c | |||
@@ -0,0 +1,215 @@ | |||
1 | /**************************************************************************** | ||
2 | |||
3 | Copyright Echo Digital Audio Corporation (c) 1998 - 2004 | ||
4 | All rights reserved | ||
5 | www.echoaudio.com | ||
6 | |||
7 | This file is part of Echo Digital Audio's generic driver library. | ||
8 | |||
9 | Echo Digital Audio's generic driver library is free software; | ||
10 | you can redistribute it and/or modify it under the terms of | ||
11 | the GNU General Public License as published by the Free Software | ||
12 | Foundation. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, | ||
22 | MA 02111-1307, USA. | ||
23 | |||
24 | ************************************************************************* | ||
25 | |||
26 | Translation from C++ and adaptation for use in ALSA-Driver | ||
27 | were made by Giuliano Pochini <pochini@shiny.it> | ||
28 | |||
29 | ****************************************************************************/ | ||
30 | |||
31 | |||
32 | static int set_professional_spdif(struct echoaudio *chip, char prof); | ||
33 | static int update_flags(struct echoaudio *chip); | ||
34 | |||
35 | |||
36 | static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | ||
37 | { | ||
38 | int err; | ||
39 | |||
40 | DE_INIT(("init_hw() - Gina20\n")); | ||
41 | snd_assert((subdevice_id & 0xfff0) == GINA20, return -ENODEV); | ||
42 | |||
43 | if ((err = init_dsp_comm_page(chip))) { | ||
44 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | ||
45 | return err; | ||
46 | } | ||
47 | |||
48 | chip->device_id = device_id; | ||
49 | chip->subdevice_id = subdevice_id; | ||
50 | chip->bad_board = TRUE; | ||
51 | chip->dsp_code_to_load = &card_fw[FW_GINA20_DSP]; | ||
52 | chip->spdif_status = GD_SPDIF_STATUS_UNDEF; | ||
53 | chip->clock_state = GD_CLOCK_UNDEF; | ||
54 | /* Since this card has no ASIC, mark it as loaded so everything | ||
55 | works OK */ | ||
56 | chip->asic_loaded = TRUE; | ||
57 | chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL | | ||
58 | ECHO_CLOCK_BIT_SPDIF; | ||
59 | |||
60 | if ((err = load_firmware(chip)) < 0) | ||
61 | return err; | ||
62 | chip->bad_board = FALSE; | ||
63 | |||
64 | if ((err = init_line_levels(chip)) < 0) | ||
65 | return err; | ||
66 | |||
67 | err = set_professional_spdif(chip, TRUE); | ||
68 | |||
69 | DE_INIT(("init_hw done\n")); | ||
70 | return err; | ||
71 | } | ||
72 | |||
73 | |||
74 | |||
75 | static u32 detect_input_clocks(const struct echoaudio *chip) | ||
76 | { | ||
77 | u32 clocks_from_dsp, clock_bits; | ||
78 | |||
79 | /* Map the DSP clock detect bits to the generic driver clock | ||
80 | detect bits */ | ||
81 | clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); | ||
82 | |||
83 | clock_bits = ECHO_CLOCK_BIT_INTERNAL; | ||
84 | |||
85 | if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF) | ||
86 | clock_bits |= ECHO_CLOCK_BIT_SPDIF; | ||
87 | |||
88 | return clock_bits; | ||
89 | } | ||
90 | |||
91 | |||
92 | |||
93 | /* The Gina20 has no ASIC. Just do nothing */ | ||
94 | static int load_asic(struct echoaudio *chip) | ||
95 | { | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | |||
100 | |||
101 | static int set_sample_rate(struct echoaudio *chip, u32 rate) | ||
102 | { | ||
103 | u8 clock_state, spdif_status; | ||
104 | |||
105 | if (wait_handshake(chip)) | ||
106 | return -EIO; | ||
107 | |||
108 | switch (rate) { | ||
109 | case 44100: | ||
110 | clock_state = GD_CLOCK_44; | ||
111 | spdif_status = GD_SPDIF_STATUS_44; | ||
112 | break; | ||
113 | case 48000: | ||
114 | clock_state = GD_CLOCK_48; | ||
115 | spdif_status = GD_SPDIF_STATUS_48; | ||
116 | break; | ||
117 | default: | ||
118 | clock_state = GD_CLOCK_NOCHANGE; | ||
119 | spdif_status = GD_SPDIF_STATUS_NOCHANGE; | ||
120 | break; | ||
121 | } | ||
122 | |||
123 | if (chip->clock_state == clock_state) | ||
124 | clock_state = GD_CLOCK_NOCHANGE; | ||
125 | if (spdif_status == chip->spdif_status) | ||
126 | spdif_status = GD_SPDIF_STATUS_NOCHANGE; | ||
127 | |||
128 | chip->comm_page->sample_rate = cpu_to_le32(rate); | ||
129 | chip->comm_page->gd_clock_state = clock_state; | ||
130 | chip->comm_page->gd_spdif_status = spdif_status; | ||
131 | chip->comm_page->gd_resampler_state = 3; /* magic number - should always be 3 */ | ||
132 | |||
133 | /* Save the new audio state if it changed */ | ||
134 | if (clock_state != GD_CLOCK_NOCHANGE) | ||
135 | chip->clock_state = clock_state; | ||
136 | if (spdif_status != GD_SPDIF_STATUS_NOCHANGE) | ||
137 | chip->spdif_status = spdif_status; | ||
138 | chip->sample_rate = rate; | ||
139 | |||
140 | clear_handshake(chip); | ||
141 | return send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE); | ||
142 | } | ||
143 | |||
144 | |||
145 | |||
146 | static int set_input_clock(struct echoaudio *chip, u16 clock) | ||
147 | { | ||
148 | DE_ACT(("set_input_clock:\n")); | ||
149 | |||
150 | switch (clock) { | ||
151 | case ECHO_CLOCK_INTERNAL: | ||
152 | /* Reset the audio state to unknown (just in case) */ | ||
153 | chip->clock_state = GD_CLOCK_UNDEF; | ||
154 | chip->spdif_status = GD_SPDIF_STATUS_UNDEF; | ||
155 | set_sample_rate(chip, chip->sample_rate); | ||
156 | chip->input_clock = clock; | ||
157 | DE_ACT(("Set Gina clock to INTERNAL\n")); | ||
158 | break; | ||
159 | case ECHO_CLOCK_SPDIF: | ||
160 | chip->comm_page->gd_clock_state = GD_CLOCK_SPDIFIN; | ||
161 | chip->comm_page->gd_spdif_status = GD_SPDIF_STATUS_NOCHANGE; | ||
162 | clear_handshake(chip); | ||
163 | send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE); | ||
164 | chip->clock_state = GD_CLOCK_SPDIFIN; | ||
165 | DE_ACT(("Set Gina20 clock to SPDIF\n")); | ||
166 | chip->input_clock = clock; | ||
167 | break; | ||
168 | default: | ||
169 | return -EINVAL; | ||
170 | } | ||
171 | |||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | |||
176 | |||
177 | /* Set input bus gain (one unit is 0.5dB !) */ | ||
178 | static int set_input_gain(struct echoaudio *chip, u16 input, int gain) | ||
179 | { | ||
180 | snd_assert(input < num_busses_in(chip), return -EINVAL); | ||
181 | |||
182 | if (wait_handshake(chip)) | ||
183 | return -EIO; | ||
184 | |||
185 | chip->input_gain[input] = gain; | ||
186 | gain += GL20_INPUT_GAIN_MAGIC_NUMBER; | ||
187 | chip->comm_page->line_in_level[input] = gain; | ||
188 | return 0; | ||
189 | } | ||
190 | |||
191 | |||
192 | |||
193 | /* Tell the DSP to reread the flags from the comm page */ | ||
194 | static int update_flags(struct echoaudio *chip) | ||
195 | { | ||
196 | if (wait_handshake(chip)) | ||
197 | return -EIO; | ||
198 | clear_handshake(chip); | ||
199 | return send_vector(chip, DSP_VC_UPDATE_FLAGS); | ||
200 | } | ||
201 | |||
202 | |||
203 | |||
204 | static int set_professional_spdif(struct echoaudio *chip, char prof) | ||
205 | { | ||
206 | DE_ACT(("set_professional_spdif %d\n", prof)); | ||
207 | if (prof) | ||
208 | chip->comm_page->flags |= | ||
209 | __constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); | ||
210 | else | ||
211 | chip->comm_page->flags &= | ||
212 | ~__constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); | ||
213 | chip->professional_spdif = prof; | ||
214 | return update_flags(chip); | ||
215 | } | ||
diff --git a/sound/pci/echoaudio/gina24.c b/sound/pci/echoaudio/gina24.c new file mode 100644 index 000000000000..e464d720d0bd --- /dev/null +++ b/sound/pci/echoaudio/gina24.c | |||
@@ -0,0 +1,123 @@ | |||
1 | /* | ||
2 | * ALSA driver for Echoaudio soundcards. | ||
3 | * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #define ECHO24_FAMILY | ||
20 | #define ECHOCARD_GINA24 | ||
21 | #define ECHOCARD_NAME "Gina24" | ||
22 | #define ECHOCARD_HAS_MONITOR | ||
23 | #define ECHOCARD_HAS_ASIC | ||
24 | #define ECHOCARD_HAS_INPUT_NOMINAL_LEVEL | ||
25 | #define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL | ||
26 | #define ECHOCARD_HAS_SUPER_INTERLEAVE | ||
27 | #define ECHOCARD_HAS_DIGITAL_IO | ||
28 | #define ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE | ||
29 | #define ECHOCARD_HAS_DIGITAL_MODE_SWITCH | ||
30 | #define ECHOCARD_HAS_EXTERNAL_CLOCK | ||
31 | #define ECHOCARD_HAS_ADAT 6 | ||
32 | #define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 | ||
33 | |||
34 | /* Pipe indexes */ | ||
35 | #define PX_ANALOG_OUT 0 /* 8 */ | ||
36 | #define PX_DIGITAL_OUT 8 /* 8 */ | ||
37 | #define PX_ANALOG_IN 16 /* 2 */ | ||
38 | #define PX_DIGITAL_IN 18 /* 8 */ | ||
39 | #define PX_NUM 26 | ||
40 | |||
41 | /* Bus indexes */ | ||
42 | #define BX_ANALOG_OUT 0 /* 8 */ | ||
43 | #define BX_DIGITAL_OUT 8 /* 8 */ | ||
44 | #define BX_ANALOG_IN 16 /* 2 */ | ||
45 | #define BX_DIGITAL_IN 18 /* 8 */ | ||
46 | #define BX_NUM 26 | ||
47 | |||
48 | |||
49 | #include <sound/driver.h> | ||
50 | #include <linux/delay.h> | ||
51 | #include <linux/init.h> | ||
52 | #include <linux/interrupt.h> | ||
53 | #include <linux/pci.h> | ||
54 | #include <linux/slab.h> | ||
55 | #include <linux/moduleparam.h> | ||
56 | #include <linux/firmware.h> | ||
57 | #include <sound/core.h> | ||
58 | #include <sound/info.h> | ||
59 | #include <sound/control.h> | ||
60 | #include <sound/pcm.h> | ||
61 | #include <sound/pcm_params.h> | ||
62 | #include <sound/asoundef.h> | ||
63 | #include <sound/initval.h> | ||
64 | #include <asm/io.h> | ||
65 | #include <asm/atomic.h> | ||
66 | #include "echoaudio.h" | ||
67 | |||
68 | #define FW_361_LOADER 0 | ||
69 | #define FW_GINA24_301_DSP 1 | ||
70 | #define FW_GINA24_361_DSP 2 | ||
71 | #define FW_GINA24_301_ASIC 3 | ||
72 | #define FW_GINA24_361_ASIC 4 | ||
73 | |||
74 | static const struct firmware card_fw[] = { | ||
75 | {0, "loader_dsp.fw"}, | ||
76 | {0, "gina24_301_dsp.fw"}, | ||
77 | {0, "gina24_361_dsp.fw"}, | ||
78 | {0, "gina24_301_asic.fw"}, | ||
79 | {0, "gina24_361_asic.fw"} | ||
80 | }; | ||
81 | |||
82 | static struct pci_device_id snd_echo_ids[] = { | ||
83 | {0x1057, 0x1801, 0xECC0, 0x0050, 0, 0, 0}, /* DSP 56301 Gina24 rev.0 */ | ||
84 | {0x1057, 0x1801, 0xECC0, 0x0051, 0, 0, 0}, /* DSP 56301 Gina24 rev.1 */ | ||
85 | {0x1057, 0x3410, 0xECC0, 0x0050, 0, 0, 0}, /* DSP 56361 Gina24 rev.0 */ | ||
86 | {0x1057, 0x3410, 0xECC0, 0x0051, 0, 0, 0}, /* DSP 56361 Gina24 rev.1 */ | ||
87 | {0,} | ||
88 | }; | ||
89 | |||
90 | static struct snd_pcm_hardware pcm_hardware_skel = { | ||
91 | .info = SNDRV_PCM_INFO_MMAP | | ||
92 | SNDRV_PCM_INFO_INTERLEAVED | | ||
93 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
94 | SNDRV_PCM_INFO_MMAP_VALID | | ||
95 | SNDRV_PCM_INFO_PAUSE | | ||
96 | SNDRV_PCM_INFO_SYNC_START, | ||
97 | .formats = SNDRV_PCM_FMTBIT_U8 | | ||
98 | SNDRV_PCM_FMTBIT_S16_LE | | ||
99 | SNDRV_PCM_FMTBIT_S24_3LE | | ||
100 | SNDRV_PCM_FMTBIT_S32_LE | | ||
101 | SNDRV_PCM_FMTBIT_S32_BE, | ||
102 | .rates = SNDRV_PCM_RATE_8000_48000 | | ||
103 | SNDRV_PCM_RATE_88200 | | ||
104 | SNDRV_PCM_RATE_96000, | ||
105 | .rate_min = 8000, | ||
106 | .rate_max = 96000, | ||
107 | .channels_min = 1, | ||
108 | .channels_max = 8, | ||
109 | .buffer_bytes_max = 262144, | ||
110 | .period_bytes_min = 32, | ||
111 | .period_bytes_max = 131072, | ||
112 | .periods_min = 2, | ||
113 | .periods_max = 220, | ||
114 | /* One page (4k) contains 512 instructions. I don't know if the hw | ||
115 | supports lists longer than this. In this case periods_max=220 is a | ||
116 | safe limit to make sure the list never exceeds 512 instructions. | ||
117 | 220 ~= (512 - 1 - (BUFFER_BYTES_MAX / PAGE_SIZE)) / 2 */ | ||
118 | }; | ||
119 | |||
120 | #include "gina24_dsp.c" | ||
121 | #include "echoaudio_dsp.c" | ||
122 | #include "echoaudio_gml.c" | ||
123 | #include "echoaudio.c" | ||
diff --git a/sound/pci/echoaudio/gina24_dsp.c b/sound/pci/echoaudio/gina24_dsp.c new file mode 100644 index 000000000000..144fc567becf --- /dev/null +++ b/sound/pci/echoaudio/gina24_dsp.c | |||
@@ -0,0 +1,346 @@ | |||
1 | /**************************************************************************** | ||
2 | |||
3 | Copyright Echo Digital Audio Corporation (c) 1998 - 2004 | ||
4 | All rights reserved | ||
5 | www.echoaudio.com | ||
6 | |||
7 | This file is part of Echo Digital Audio's generic driver library. | ||
8 | |||
9 | Echo Digital Audio's generic driver library is free software; | ||
10 | you can redistribute it and/or modify it under the terms of | ||
11 | the GNU General Public License as published by the Free Software | ||
12 | Foundation. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, | ||
22 | MA 02111-1307, USA. | ||
23 | |||
24 | ************************************************************************* | ||
25 | |||
26 | Translation from C++ and adaptation for use in ALSA-Driver | ||
27 | were made by Giuliano Pochini <pochini@shiny.it> | ||
28 | |||
29 | ****************************************************************************/ | ||
30 | |||
31 | |||
32 | static int write_control_reg(struct echoaudio *chip, u32 value, char force); | ||
33 | static int set_input_clock(struct echoaudio *chip, u16 clock); | ||
34 | static int set_professional_spdif(struct echoaudio *chip, char prof); | ||
35 | static int set_digital_mode(struct echoaudio *chip, u8 mode); | ||
36 | static int load_asic_generic(struct echoaudio *chip, u32 cmd, | ||
37 | const struct firmware *asic); | ||
38 | static int check_asic_status(struct echoaudio *chip); | ||
39 | |||
40 | |||
41 | static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | ||
42 | { | ||
43 | int err; | ||
44 | |||
45 | DE_INIT(("init_hw() - Gina24\n")); | ||
46 | snd_assert((subdevice_id & 0xfff0) == GINA24, return -ENODEV); | ||
47 | |||
48 | if ((err = init_dsp_comm_page(chip))) { | ||
49 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | ||
50 | return err; | ||
51 | } | ||
52 | |||
53 | chip->device_id = device_id; | ||
54 | chip->subdevice_id = subdevice_id; | ||
55 | chip->bad_board = TRUE; | ||
56 | chip->input_clock_types = | ||
57 | ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF | | ||
58 | ECHO_CLOCK_BIT_ESYNC | ECHO_CLOCK_BIT_ESYNC96 | | ||
59 | ECHO_CLOCK_BIT_ADAT; | ||
60 | chip->professional_spdif = FALSE; | ||
61 | chip->digital_in_automute = TRUE; | ||
62 | chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; | ||
63 | |||
64 | /* Gina24 comes in both '301 and '361 flavors */ | ||
65 | if (chip->device_id == DEVICE_ID_56361) { | ||
66 | chip->dsp_code_to_load = &card_fw[FW_GINA24_361_DSP]; | ||
67 | chip->digital_modes = | ||
68 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | | ||
69 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | | ||
70 | ECHOCAPS_HAS_DIGITAL_MODE_ADAT; | ||
71 | } else { | ||
72 | chip->dsp_code_to_load = &card_fw[FW_GINA24_301_DSP]; | ||
73 | chip->digital_modes = | ||
74 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | | ||
75 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | | ||
76 | ECHOCAPS_HAS_DIGITAL_MODE_ADAT | | ||
77 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_CDROM; | ||
78 | } | ||
79 | |||
80 | if ((err = load_firmware(chip)) < 0) | ||
81 | return err; | ||
82 | chip->bad_board = FALSE; | ||
83 | |||
84 | if ((err = init_line_levels(chip)) < 0) | ||
85 | return err; | ||
86 | err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA); | ||
87 | snd_assert(err >= 0, return err); | ||
88 | err = set_professional_spdif(chip, TRUE); | ||
89 | |||
90 | DE_INIT(("init_hw done\n")); | ||
91 | return err; | ||
92 | } | ||
93 | |||
94 | |||
95 | |||
96 | static u32 detect_input_clocks(const struct echoaudio *chip) | ||
97 | { | ||
98 | u32 clocks_from_dsp, clock_bits; | ||
99 | |||
100 | /* Map the DSP clock detect bits to the generic driver clock | ||
101 | detect bits */ | ||
102 | clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); | ||
103 | |||
104 | clock_bits = ECHO_CLOCK_BIT_INTERNAL; | ||
105 | |||
106 | if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF) | ||
107 | clock_bits |= ECHO_CLOCK_BIT_SPDIF; | ||
108 | |||
109 | if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ADAT) | ||
110 | clock_bits |= ECHO_CLOCK_BIT_ADAT; | ||
111 | |||
112 | if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ESYNC) | ||
113 | clock_bits |= ECHO_CLOCK_BIT_ESYNC | ECHO_CLOCK_BIT_ESYNC96; | ||
114 | |||
115 | return clock_bits; | ||
116 | } | ||
117 | |||
118 | |||
119 | |||
120 | /* Gina24 has an ASIC on the PCI card which must be loaded for anything | ||
121 | interesting to happen. */ | ||
122 | static int load_asic(struct echoaudio *chip) | ||
123 | { | ||
124 | u32 control_reg; | ||
125 | int err; | ||
126 | const struct firmware *fw; | ||
127 | |||
128 | if (chip->asic_loaded) | ||
129 | return 1; | ||
130 | |||
131 | /* Give the DSP a few milliseconds to settle down */ | ||
132 | mdelay(10); | ||
133 | |||
134 | /* Pick the correct ASIC for '301 or '361 Gina24 */ | ||
135 | if (chip->device_id == DEVICE_ID_56361) | ||
136 | fw = &card_fw[FW_GINA24_361_ASIC]; | ||
137 | else | ||
138 | fw = &card_fw[FW_GINA24_301_ASIC]; | ||
139 | |||
140 | if ((err = load_asic_generic(chip, DSP_FNC_LOAD_GINA24_ASIC, fw)) < 0) | ||
141 | return err; | ||
142 | |||
143 | chip->asic_code = fw; | ||
144 | |||
145 | /* Now give the new ASIC a little time to set up */ | ||
146 | mdelay(10); | ||
147 | /* See if it worked */ | ||
148 | err = check_asic_status(chip); | ||
149 | |||
150 | /* Set up the control register if the load succeeded - | ||
151 | 48 kHz, internal clock, S/PDIF RCA mode */ | ||
152 | if (!err) { | ||
153 | control_reg = GML_CONVERTER_ENABLE | GML_48KHZ; | ||
154 | err = write_control_reg(chip, control_reg, TRUE); | ||
155 | } | ||
156 | DE_INIT(("load_asic() done\n")); | ||
157 | return err; | ||
158 | } | ||
159 | |||
160 | |||
161 | |||
162 | static int set_sample_rate(struct echoaudio *chip, u32 rate) | ||
163 | { | ||
164 | u32 control_reg, clock; | ||
165 | |||
166 | snd_assert(rate < 50000 || chip->digital_mode != DIGITAL_MODE_ADAT, | ||
167 | return -EINVAL); | ||
168 | |||
169 | /* Only set the clock for internal mode. */ | ||
170 | if (chip->input_clock != ECHO_CLOCK_INTERNAL) { | ||
171 | DE_ACT(("set_sample_rate: Cannot set sample rate - " | ||
172 | "clock not set to CLK_CLOCKININTERNAL\n")); | ||
173 | /* Save the rate anyhow */ | ||
174 | chip->comm_page->sample_rate = cpu_to_le32(rate); | ||
175 | chip->sample_rate = rate; | ||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | clock = 0; | ||
180 | |||
181 | control_reg = le32_to_cpu(chip->comm_page->control_register); | ||
182 | control_reg &= GML_CLOCK_CLEAR_MASK & GML_SPDIF_RATE_CLEAR_MASK; | ||
183 | |||
184 | switch (rate) { | ||
185 | case 96000: | ||
186 | clock = GML_96KHZ; | ||
187 | break; | ||
188 | case 88200: | ||
189 | clock = GML_88KHZ; | ||
190 | break; | ||
191 | case 48000: | ||
192 | clock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1; | ||
193 | break; | ||
194 | case 44100: | ||
195 | clock = GML_44KHZ; | ||
196 | /* Professional mode ? */ | ||
197 | if (control_reg & GML_SPDIF_PRO_MODE) | ||
198 | clock |= GML_SPDIF_SAMPLE_RATE0; | ||
199 | break; | ||
200 | case 32000: | ||
201 | clock = GML_32KHZ | GML_SPDIF_SAMPLE_RATE0 | | ||
202 | GML_SPDIF_SAMPLE_RATE1; | ||
203 | break; | ||
204 | case 22050: | ||
205 | clock = GML_22KHZ; | ||
206 | break; | ||
207 | case 16000: | ||
208 | clock = GML_16KHZ; | ||
209 | break; | ||
210 | case 11025: | ||
211 | clock = GML_11KHZ; | ||
212 | break; | ||
213 | case 8000: | ||
214 | clock = GML_8KHZ; | ||
215 | break; | ||
216 | default: | ||
217 | DE_ACT(("set_sample_rate: %d invalid!\n", rate)); | ||
218 | return -EINVAL; | ||
219 | } | ||
220 | |||
221 | control_reg |= clock; | ||
222 | |||
223 | chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ | ||
224 | chip->sample_rate = rate; | ||
225 | DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock)); | ||
226 | |||
227 | return write_control_reg(chip, control_reg, FALSE); | ||
228 | } | ||
229 | |||
230 | |||
231 | |||
232 | static int set_input_clock(struct echoaudio *chip, u16 clock) | ||
233 | { | ||
234 | u32 control_reg, clocks_from_dsp; | ||
235 | |||
236 | DE_ACT(("set_input_clock:\n")); | ||
237 | |||
238 | /* Mask off the clock select bits */ | ||
239 | control_reg = le32_to_cpu(chip->comm_page->control_register) & | ||
240 | GML_CLOCK_CLEAR_MASK; | ||
241 | clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); | ||
242 | |||
243 | switch (clock) { | ||
244 | case ECHO_CLOCK_INTERNAL: | ||
245 | DE_ACT(("Set Gina24 clock to INTERNAL\n")); | ||
246 | chip->input_clock = ECHO_CLOCK_INTERNAL; | ||
247 | return set_sample_rate(chip, chip->sample_rate); | ||
248 | case ECHO_CLOCK_SPDIF: | ||
249 | if (chip->digital_mode == DIGITAL_MODE_ADAT) | ||
250 | return -EAGAIN; | ||
251 | DE_ACT(("Set Gina24 clock to SPDIF\n")); | ||
252 | control_reg |= GML_SPDIF_CLOCK; | ||
253 | if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF96) | ||
254 | control_reg |= GML_DOUBLE_SPEED_MODE; | ||
255 | else | ||
256 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | ||
257 | break; | ||
258 | case ECHO_CLOCK_ADAT: | ||
259 | if (chip->digital_mode != DIGITAL_MODE_ADAT) | ||
260 | return -EAGAIN; | ||
261 | DE_ACT(("Set Gina24 clock to ADAT\n")); | ||
262 | control_reg |= GML_ADAT_CLOCK; | ||
263 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | ||
264 | break; | ||
265 | case ECHO_CLOCK_ESYNC: | ||
266 | DE_ACT(("Set Gina24 clock to ESYNC\n")); | ||
267 | control_reg |= GML_ESYNC_CLOCK; | ||
268 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | ||
269 | break; | ||
270 | case ECHO_CLOCK_ESYNC96: | ||
271 | DE_ACT(("Set Gina24 clock to ESYNC96\n")); | ||
272 | control_reg |= GML_ESYNC_CLOCK | GML_DOUBLE_SPEED_MODE; | ||
273 | break; | ||
274 | default: | ||
275 | DE_ACT(("Input clock 0x%x not supported for Gina24\n", clock)); | ||
276 | return -EINVAL; | ||
277 | } | ||
278 | |||
279 | chip->input_clock = clock; | ||
280 | return write_control_reg(chip, control_reg, TRUE); | ||
281 | } | ||
282 | |||
283 | |||
284 | |||
285 | static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) | ||
286 | { | ||
287 | u32 control_reg; | ||
288 | int err, incompatible_clock; | ||
289 | |||
290 | /* Set clock to "internal" if it's not compatible with the new mode */ | ||
291 | incompatible_clock = FALSE; | ||
292 | switch (mode) { | ||
293 | case DIGITAL_MODE_SPDIF_OPTICAL: | ||
294 | case DIGITAL_MODE_SPDIF_CDROM: | ||
295 | case DIGITAL_MODE_SPDIF_RCA: | ||
296 | if (chip->input_clock == ECHO_CLOCK_ADAT) | ||
297 | incompatible_clock = TRUE; | ||
298 | break; | ||
299 | case DIGITAL_MODE_ADAT: | ||
300 | if (chip->input_clock == ECHO_CLOCK_SPDIF) | ||
301 | incompatible_clock = TRUE; | ||
302 | break; | ||
303 | default: | ||
304 | DE_ACT(("Digital mode not supported: %d\n", mode)); | ||
305 | return -EINVAL; | ||
306 | } | ||
307 | |||
308 | spin_lock_irq(&chip->lock); | ||
309 | |||
310 | if (incompatible_clock) { /* Switch to 48KHz, internal */ | ||
311 | chip->sample_rate = 48000; | ||
312 | set_input_clock(chip, ECHO_CLOCK_INTERNAL); | ||
313 | } | ||
314 | |||
315 | /* Clear the current digital mode */ | ||
316 | control_reg = le32_to_cpu(chip->comm_page->control_register); | ||
317 | control_reg &= GML_DIGITAL_MODE_CLEAR_MASK; | ||
318 | |||
319 | /* Tweak the control reg */ | ||
320 | switch (mode) { | ||
321 | case DIGITAL_MODE_SPDIF_OPTICAL: | ||
322 | control_reg |= GML_SPDIF_OPTICAL_MODE; | ||
323 | break; | ||
324 | case DIGITAL_MODE_SPDIF_CDROM: | ||
325 | /* '361 Gina24 cards do not have the S/PDIF CD-ROM mode */ | ||
326 | if (chip->device_id == DEVICE_ID_56301) | ||
327 | control_reg |= GML_SPDIF_CDROM_MODE; | ||
328 | break; | ||
329 | case DIGITAL_MODE_SPDIF_RCA: | ||
330 | /* GML_SPDIF_OPTICAL_MODE bit cleared */ | ||
331 | break; | ||
332 | case DIGITAL_MODE_ADAT: | ||
333 | control_reg |= GML_ADAT_MODE; | ||
334 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | ||
335 | break; | ||
336 | } | ||
337 | |||
338 | err = write_control_reg(chip, control_reg, TRUE); | ||
339 | spin_unlock_irq(&chip->lock); | ||
340 | if (err < 0) | ||
341 | return err; | ||
342 | chip->digital_mode = mode; | ||
343 | |||
344 | DE_ACT(("set_digital_mode to %d\n", chip->digital_mode)); | ||
345 | return incompatible_clock; | ||
346 | } | ||
diff --git a/sound/pci/echoaudio/indigo.c b/sound/pci/echoaudio/indigo.c new file mode 100644 index 000000000000..bfd2467099ac --- /dev/null +++ b/sound/pci/echoaudio/indigo.c | |||
@@ -0,0 +1,104 @@ | |||
1 | /* | ||
2 | * ALSA driver for Echoaudio soundcards. | ||
3 | * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #define INDIGO_FAMILY | ||
20 | #define ECHOCARD_INDIGO | ||
21 | #define ECHOCARD_NAME "Indigo" | ||
22 | #define ECHOCARD_HAS_SUPER_INTERLEAVE | ||
23 | #define ECHOCARD_HAS_VMIXER | ||
24 | #define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 | ||
25 | |||
26 | /* Pipe indexes */ | ||
27 | #define PX_ANALOG_OUT 0 /* 8 */ | ||
28 | #define PX_DIGITAL_OUT 8 /* 0 */ | ||
29 | #define PX_ANALOG_IN 8 /* 0 */ | ||
30 | #define PX_DIGITAL_IN 8 /* 0 */ | ||
31 | #define PX_NUM 8 | ||
32 | |||
33 | /* Bus indexes */ | ||
34 | #define BX_ANALOG_OUT 0 /* 2 */ | ||
35 | #define BX_DIGITAL_OUT 2 /* 0 */ | ||
36 | #define BX_ANALOG_IN 2 /* 0 */ | ||
37 | #define BX_DIGITAL_IN 2 /* 0 */ | ||
38 | #define BX_NUM 2 | ||
39 | |||
40 | |||
41 | #include <sound/driver.h> | ||
42 | #include <linux/delay.h> | ||
43 | #include <linux/init.h> | ||
44 | #include <linux/interrupt.h> | ||
45 | #include <linux/pci.h> | ||
46 | #include <linux/slab.h> | ||
47 | #include <linux/moduleparam.h> | ||
48 | #include <linux/firmware.h> | ||
49 | #include <sound/core.h> | ||
50 | #include <sound/info.h> | ||
51 | #include <sound/control.h> | ||
52 | #include <sound/pcm.h> | ||
53 | #include <sound/pcm_params.h> | ||
54 | #include <sound/asoundef.h> | ||
55 | #include <sound/initval.h> | ||
56 | #include <asm/io.h> | ||
57 | #include <asm/atomic.h> | ||
58 | #include "echoaudio.h" | ||
59 | |||
60 | #define FW_361_LOADER 0 | ||
61 | #define FW_INDIGO_DSP 1 | ||
62 | |||
63 | static const struct firmware card_fw[] = { | ||
64 | {0, "loader_dsp.fw"}, | ||
65 | {0, "indigo_dsp.fw"} | ||
66 | }; | ||
67 | |||
68 | static struct pci_device_id snd_echo_ids[] = { | ||
69 | {0x1057, 0x3410, 0xECC0, 0x0090, 0, 0, 0}, /* Indigo */ | ||
70 | {0,} | ||
71 | }; | ||
72 | |||
73 | static struct snd_pcm_hardware pcm_hardware_skel = { | ||
74 | .info = SNDRV_PCM_INFO_MMAP | | ||
75 | SNDRV_PCM_INFO_INTERLEAVED | | ||
76 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
77 | SNDRV_PCM_INFO_MMAP_VALID | | ||
78 | SNDRV_PCM_INFO_PAUSE | | ||
79 | SNDRV_PCM_INFO_SYNC_START, | ||
80 | .formats = SNDRV_PCM_FMTBIT_U8 | | ||
81 | SNDRV_PCM_FMTBIT_S16_LE | | ||
82 | SNDRV_PCM_FMTBIT_S24_3LE | | ||
83 | SNDRV_PCM_FMTBIT_S32_LE | | ||
84 | SNDRV_PCM_FMTBIT_S32_BE, | ||
85 | .rates = SNDRV_PCM_RATE_32000 | | ||
86 | SNDRV_PCM_RATE_44100 | | ||
87 | SNDRV_PCM_RATE_48000 | | ||
88 | SNDRV_PCM_RATE_88200 | | ||
89 | SNDRV_PCM_RATE_96000, | ||
90 | .rate_min = 32000, | ||
91 | .rate_max = 96000, | ||
92 | .channels_min = 1, | ||
93 | .channels_max = 8, | ||
94 | .buffer_bytes_max = 262144, | ||
95 | .period_bytes_min = 32, | ||
96 | .period_bytes_max = 131072, | ||
97 | .periods_min = 2, | ||
98 | .periods_max = 220, | ||
99 | }; | ||
100 | |||
101 | #include "indigo_dsp.c" | ||
102 | #include "echoaudio_dsp.c" | ||
103 | #include "echoaudio.c" | ||
104 | |||
diff --git a/sound/pci/echoaudio/indigo_dsp.c b/sound/pci/echoaudio/indigo_dsp.c new file mode 100644 index 000000000000..d6ac7734609e --- /dev/null +++ b/sound/pci/echoaudio/indigo_dsp.c | |||
@@ -0,0 +1,170 @@ | |||
1 | /**************************************************************************** | ||
2 | |||
3 | Copyright Echo Digital Audio Corporation (c) 1998 - 2004 | ||
4 | All rights reserved | ||
5 | www.echoaudio.com | ||
6 | |||
7 | This file is part of Echo Digital Audio's generic driver library. | ||
8 | |||
9 | Echo Digital Audio's generic driver library is free software; | ||
10 | you can redistribute it and/or modify it under the terms of | ||
11 | the GNU General Public License as published by the Free Software | ||
12 | Foundation. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, | ||
22 | MA 02111-1307, USA. | ||
23 | |||
24 | ************************************************************************* | ||
25 | |||
26 | Translation from C++ and adaptation for use in ALSA-Driver | ||
27 | were made by Giuliano Pochini <pochini@shiny.it> | ||
28 | |||
29 | ****************************************************************************/ | ||
30 | |||
31 | |||
32 | static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, | ||
33 | int gain); | ||
34 | static int update_vmixer_level(struct echoaudio *chip); | ||
35 | |||
36 | |||
37 | static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | ||
38 | { | ||
39 | int err; | ||
40 | |||
41 | DE_INIT(("init_hw() - Indigo\n")); | ||
42 | snd_assert((subdevice_id & 0xfff0) == INDIGO, return -ENODEV); | ||
43 | |||
44 | if ((err = init_dsp_comm_page(chip))) { | ||
45 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | ||
46 | return err; | ||
47 | } | ||
48 | |||
49 | chip->device_id = device_id; | ||
50 | chip->subdevice_id = subdevice_id; | ||
51 | chip->bad_board = TRUE; | ||
52 | chip->dsp_code_to_load = &card_fw[FW_INDIGO_DSP]; | ||
53 | /* Since this card has no ASIC, mark it as loaded so everything | ||
54 | works OK */ | ||
55 | chip->asic_loaded = TRUE; | ||
56 | chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL; | ||
57 | |||
58 | if ((err = load_firmware(chip)) < 0) | ||
59 | return err; | ||
60 | chip->bad_board = FALSE; | ||
61 | |||
62 | if ((err = init_line_levels(chip)) < 0) | ||
63 | return err; | ||
64 | |||
65 | /* Default routing of the virtual channels: all vchannels are routed | ||
66 | to the stereo output */ | ||
67 | set_vmixer_gain(chip, 0, 0, 0); | ||
68 | set_vmixer_gain(chip, 1, 1, 0); | ||
69 | set_vmixer_gain(chip, 0, 2, 0); | ||
70 | set_vmixer_gain(chip, 1, 3, 0); | ||
71 | set_vmixer_gain(chip, 0, 4, 0); | ||
72 | set_vmixer_gain(chip, 1, 5, 0); | ||
73 | set_vmixer_gain(chip, 0, 6, 0); | ||
74 | set_vmixer_gain(chip, 1, 7, 0); | ||
75 | err = update_vmixer_level(chip); | ||
76 | |||
77 | DE_INIT(("init_hw done\n")); | ||
78 | return err; | ||
79 | } | ||
80 | |||
81 | |||
82 | |||
83 | static u32 detect_input_clocks(const struct echoaudio *chip) | ||
84 | { | ||
85 | return ECHO_CLOCK_BIT_INTERNAL; | ||
86 | } | ||
87 | |||
88 | |||
89 | |||
90 | /* The Indigo has no ASIC. Just do nothing */ | ||
91 | static int load_asic(struct echoaudio *chip) | ||
92 | { | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | |||
97 | |||
98 | static int set_sample_rate(struct echoaudio *chip, u32 rate) | ||
99 | { | ||
100 | u32 control_reg; | ||
101 | |||
102 | switch (rate) { | ||
103 | case 96000: | ||
104 | control_reg = MIA_96000; | ||
105 | break; | ||
106 | case 88200: | ||
107 | control_reg = MIA_88200; | ||
108 | break; | ||
109 | case 48000: | ||
110 | control_reg = MIA_48000; | ||
111 | break; | ||
112 | case 44100: | ||
113 | control_reg = MIA_44100; | ||
114 | break; | ||
115 | case 32000: | ||
116 | control_reg = MIA_32000; | ||
117 | break; | ||
118 | default: | ||
119 | DE_ACT(("set_sample_rate: %d invalid!\n", rate)); | ||
120 | return -EINVAL; | ||
121 | } | ||
122 | |||
123 | /* Set the control register if it has changed */ | ||
124 | if (control_reg != le32_to_cpu(chip->comm_page->control_register)) { | ||
125 | if (wait_handshake(chip)) | ||
126 | return -EIO; | ||
127 | |||
128 | chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ | ||
129 | chip->comm_page->control_register = cpu_to_le32(control_reg); | ||
130 | chip->sample_rate = rate; | ||
131 | |||
132 | clear_handshake(chip); | ||
133 | return send_vector(chip, DSP_VC_UPDATE_CLOCKS); | ||
134 | } | ||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | |||
139 | |||
140 | /* This function routes the sound from a virtual channel to a real output */ | ||
141 | static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, | ||
142 | int gain) | ||
143 | { | ||
144 | int index; | ||
145 | |||
146 | snd_assert(pipe < num_pipes_out(chip) && | ||
147 | output < num_busses_out(chip), return -EINVAL); | ||
148 | |||
149 | if (wait_handshake(chip)) | ||
150 | return -EIO; | ||
151 | |||
152 | chip->vmixer_gain[output][pipe] = gain; | ||
153 | index = output * num_pipes_out(chip) + pipe; | ||
154 | chip->comm_page->vmixer[index] = gain; | ||
155 | |||
156 | DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain)); | ||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | |||
161 | |||
162 | /* Tell the DSP to read and update virtual mixer levels in comm page. */ | ||
163 | static int update_vmixer_level(struct echoaudio *chip) | ||
164 | { | ||
165 | if (wait_handshake(chip)) | ||
166 | return -EIO; | ||
167 | clear_handshake(chip); | ||
168 | return send_vector(chip, DSP_VC_SET_VMIXER_GAIN); | ||
169 | } | ||
170 | |||
diff --git a/sound/pci/echoaudio/indigodj.c b/sound/pci/echoaudio/indigodj.c new file mode 100644 index 000000000000..8ed7ff1fd875 --- /dev/null +++ b/sound/pci/echoaudio/indigodj.c | |||
@@ -0,0 +1,104 @@ | |||
1 | /* | ||
2 | * ALSA driver for Echoaudio soundcards. | ||
3 | * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #define INDIGO_FAMILY | ||
20 | #define ECHOCARD_INDIGO_DJ | ||
21 | #define ECHOCARD_NAME "Indigo DJ" | ||
22 | #define ECHOCARD_HAS_SUPER_INTERLEAVE | ||
23 | #define ECHOCARD_HAS_VMIXER | ||
24 | #define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 | ||
25 | |||
26 | /* Pipe indexes */ | ||
27 | #define PX_ANALOG_OUT 0 /* 8 */ | ||
28 | #define PX_DIGITAL_OUT 8 /* 0 */ | ||
29 | #define PX_ANALOG_IN 8 /* 0 */ | ||
30 | #define PX_DIGITAL_IN 8 /* 0 */ | ||
31 | #define PX_NUM 8 | ||
32 | |||
33 | /* Bus indexes */ | ||
34 | #define BX_ANALOG_OUT 0 /* 4 */ | ||
35 | #define BX_DIGITAL_OUT 4 /* 0 */ | ||
36 | #define BX_ANALOG_IN 4 /* 0 */ | ||
37 | #define BX_DIGITAL_IN 4 /* 0 */ | ||
38 | #define BX_NUM 4 | ||
39 | |||
40 | |||
41 | #include <sound/driver.h> | ||
42 | #include <linux/delay.h> | ||
43 | #include <linux/init.h> | ||
44 | #include <linux/interrupt.h> | ||
45 | #include <linux/pci.h> | ||
46 | #include <linux/slab.h> | ||
47 | #include <linux/moduleparam.h> | ||
48 | #include <linux/firmware.h> | ||
49 | #include <sound/core.h> | ||
50 | #include <sound/info.h> | ||
51 | #include <sound/control.h> | ||
52 | #include <sound/pcm.h> | ||
53 | #include <sound/pcm_params.h> | ||
54 | #include <sound/asoundef.h> | ||
55 | #include <sound/initval.h> | ||
56 | #include <asm/io.h> | ||
57 | #include <asm/atomic.h> | ||
58 | #include "echoaudio.h" | ||
59 | |||
60 | #define FW_361_LOADER 0 | ||
61 | #define FW_INDIGO_DJ_DSP 1 | ||
62 | |||
63 | static const struct firmware card_fw[] = { | ||
64 | {0, "loader_dsp.fw"}, | ||
65 | {0, "indigo_dj_dsp.fw"} | ||
66 | }; | ||
67 | |||
68 | static struct pci_device_id snd_echo_ids[] = { | ||
69 | {0x1057, 0x3410, 0xECC0, 0x00B0, 0, 0, 0}, /* Indigo DJ*/ | ||
70 | {0,} | ||
71 | }; | ||
72 | |||
73 | static struct snd_pcm_hardware pcm_hardware_skel = { | ||
74 | .info = SNDRV_PCM_INFO_MMAP | | ||
75 | SNDRV_PCM_INFO_INTERLEAVED | | ||
76 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
77 | SNDRV_PCM_INFO_MMAP_VALID | | ||
78 | SNDRV_PCM_INFO_PAUSE | | ||
79 | SNDRV_PCM_INFO_SYNC_START, | ||
80 | .formats = SNDRV_PCM_FMTBIT_U8 | | ||
81 | SNDRV_PCM_FMTBIT_S16_LE | | ||
82 | SNDRV_PCM_FMTBIT_S24_3LE | | ||
83 | SNDRV_PCM_FMTBIT_S32_LE | | ||
84 | SNDRV_PCM_FMTBIT_S32_BE, | ||
85 | .rates = SNDRV_PCM_RATE_32000 | | ||
86 | SNDRV_PCM_RATE_44100 | | ||
87 | SNDRV_PCM_RATE_48000 | | ||
88 | SNDRV_PCM_RATE_88200 | | ||
89 | SNDRV_PCM_RATE_96000, | ||
90 | .rate_min = 32000, | ||
91 | .rate_max = 96000, | ||
92 | .channels_min = 1, | ||
93 | .channels_max = 4, | ||
94 | .buffer_bytes_max = 262144, | ||
95 | .period_bytes_min = 32, | ||
96 | .period_bytes_max = 131072, | ||
97 | .periods_min = 2, | ||
98 | .periods_max = 220, | ||
99 | }; | ||
100 | |||
101 | #include "indigodj_dsp.c" | ||
102 | #include "echoaudio_dsp.c" | ||
103 | #include "echoaudio.c" | ||
104 | |||
diff --git a/sound/pci/echoaudio/indigodj_dsp.c b/sound/pci/echoaudio/indigodj_dsp.c new file mode 100644 index 000000000000..500e150b49fc --- /dev/null +++ b/sound/pci/echoaudio/indigodj_dsp.c | |||
@@ -0,0 +1,170 @@ | |||
1 | /**************************************************************************** | ||
2 | |||
3 | Copyright Echo Digital Audio Corporation (c) 1998 - 2004 | ||
4 | All rights reserved | ||
5 | www.echoaudio.com | ||
6 | |||
7 | This file is part of Echo Digital Audio's generic driver library. | ||
8 | |||
9 | Echo Digital Audio's generic driver library is free software; | ||
10 | you can redistribute it and/or modify it under the terms of | ||
11 | the GNU General Public License as published by the Free Software | ||
12 | Foundation. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, | ||
22 | MA 02111-1307, USA. | ||
23 | |||
24 | ************************************************************************* | ||
25 | |||
26 | Translation from C++ and adaptation for use in ALSA-Driver | ||
27 | were made by Giuliano Pochini <pochini@shiny.it> | ||
28 | |||
29 | ****************************************************************************/ | ||
30 | |||
31 | |||
32 | static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, | ||
33 | int gain); | ||
34 | static int update_vmixer_level(struct echoaudio *chip); | ||
35 | |||
36 | |||
37 | static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | ||
38 | { | ||
39 | int err; | ||
40 | |||
41 | DE_INIT(("init_hw() - Indigo DJ\n")); | ||
42 | snd_assert((subdevice_id & 0xfff0) == INDIGO_DJ, return -ENODEV); | ||
43 | |||
44 | if ((err = init_dsp_comm_page(chip))) { | ||
45 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | ||
46 | return err; | ||
47 | } | ||
48 | |||
49 | chip->device_id = device_id; | ||
50 | chip->subdevice_id = subdevice_id; | ||
51 | chip->bad_board = TRUE; | ||
52 | chip->dsp_code_to_load = &card_fw[FW_INDIGO_DJ_DSP]; | ||
53 | /* Since this card has no ASIC, mark it as loaded so everything | ||
54 | works OK */ | ||
55 | chip->asic_loaded = TRUE; | ||
56 | chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL; | ||
57 | |||
58 | if ((err = load_firmware(chip)) < 0) | ||
59 | return err; | ||
60 | chip->bad_board = FALSE; | ||
61 | |||
62 | if ((err = init_line_levels(chip)) < 0) | ||
63 | return err; | ||
64 | |||
65 | /* Default routing of the virtual channels: vchannels 0-3 and | ||
66 | vchannels 4-7 are routed to real channels 0-4 */ | ||
67 | set_vmixer_gain(chip, 0, 0, 0); | ||
68 | set_vmixer_gain(chip, 1, 1, 0); | ||
69 | set_vmixer_gain(chip, 2, 2, 0); | ||
70 | set_vmixer_gain(chip, 3, 3, 0); | ||
71 | set_vmixer_gain(chip, 0, 4, 0); | ||
72 | set_vmixer_gain(chip, 1, 5, 0); | ||
73 | set_vmixer_gain(chip, 2, 6, 0); | ||
74 | set_vmixer_gain(chip, 3, 7, 0); | ||
75 | err = update_vmixer_level(chip); | ||
76 | |||
77 | DE_INIT(("init_hw done\n")); | ||
78 | return err; | ||
79 | } | ||
80 | |||
81 | |||
82 | |||
83 | static u32 detect_input_clocks(const struct echoaudio *chip) | ||
84 | { | ||
85 | return ECHO_CLOCK_BIT_INTERNAL; | ||
86 | } | ||
87 | |||
88 | |||
89 | |||
90 | /* The IndigoDJ has no ASIC. Just do nothing */ | ||
91 | static int load_asic(struct echoaudio *chip) | ||
92 | { | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | |||
97 | |||
98 | static int set_sample_rate(struct echoaudio *chip, u32 rate) | ||
99 | { | ||
100 | u32 control_reg; | ||
101 | |||
102 | switch (rate) { | ||
103 | case 96000: | ||
104 | control_reg = MIA_96000; | ||
105 | break; | ||
106 | case 88200: | ||
107 | control_reg = MIA_88200; | ||
108 | break; | ||
109 | case 48000: | ||
110 | control_reg = MIA_48000; | ||
111 | break; | ||
112 | case 44100: | ||
113 | control_reg = MIA_44100; | ||
114 | break; | ||
115 | case 32000: | ||
116 | control_reg = MIA_32000; | ||
117 | break; | ||
118 | default: | ||
119 | DE_ACT(("set_sample_rate: %d invalid!\n", rate)); | ||
120 | return -EINVAL; | ||
121 | } | ||
122 | |||
123 | /* Set the control register if it has changed */ | ||
124 | if (control_reg != le32_to_cpu(chip->comm_page->control_register)) { | ||
125 | if (wait_handshake(chip)) | ||
126 | return -EIO; | ||
127 | |||
128 | chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ | ||
129 | chip->comm_page->control_register = cpu_to_le32(control_reg); | ||
130 | chip->sample_rate = rate; | ||
131 | |||
132 | clear_handshake(chip); | ||
133 | return send_vector(chip, DSP_VC_UPDATE_CLOCKS); | ||
134 | } | ||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | |||
139 | |||
140 | /* This function routes the sound from a virtual channel to a real output */ | ||
141 | static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, | ||
142 | int gain) | ||
143 | { | ||
144 | int index; | ||
145 | |||
146 | snd_assert(pipe < num_pipes_out(chip) && | ||
147 | output < num_busses_out(chip), return -EINVAL); | ||
148 | |||
149 | if (wait_handshake(chip)) | ||
150 | return -EIO; | ||
151 | |||
152 | chip->vmixer_gain[output][pipe] = gain; | ||
153 | index = output * num_pipes_out(chip) + pipe; | ||
154 | chip->comm_page->vmixer[index] = gain; | ||
155 | |||
156 | DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain)); | ||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | |||
161 | |||
162 | /* Tell the DSP to read and update virtual mixer levels in comm page. */ | ||
163 | static int update_vmixer_level(struct echoaudio *chip) | ||
164 | { | ||
165 | if (wait_handshake(chip)) | ||
166 | return -EIO; | ||
167 | clear_handshake(chip); | ||
168 | return send_vector(chip, DSP_VC_SET_VMIXER_GAIN); | ||
169 | } | ||
170 | |||
diff --git a/sound/pci/echoaudio/indigoio.c b/sound/pci/echoaudio/indigoio.c new file mode 100644 index 000000000000..a8788e959171 --- /dev/null +++ b/sound/pci/echoaudio/indigoio.c | |||
@@ -0,0 +1,105 @@ | |||
1 | /* | ||
2 | * ALSA driver for Echoaudio soundcards. | ||
3 | * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #define INDIGO_FAMILY | ||
20 | #define ECHOCARD_INDIGO_IO | ||
21 | #define ECHOCARD_NAME "Indigo IO" | ||
22 | #define ECHOCARD_HAS_MONITOR | ||
23 | #define ECHOCARD_HAS_SUPER_INTERLEAVE | ||
24 | #define ECHOCARD_HAS_VMIXER | ||
25 | #define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 | ||
26 | |||
27 | /* Pipe indexes */ | ||
28 | #define PX_ANALOG_OUT 0 /* 8 */ | ||
29 | #define PX_DIGITAL_OUT 8 /* 0 */ | ||
30 | #define PX_ANALOG_IN 8 /* 2 */ | ||
31 | #define PX_DIGITAL_IN 10 /* 0 */ | ||
32 | #define PX_NUM 10 | ||
33 | |||
34 | /* Bus indexes */ | ||
35 | #define BX_ANALOG_OUT 0 /* 2 */ | ||
36 | #define BX_DIGITAL_OUT 2 /* 0 */ | ||
37 | #define BX_ANALOG_IN 2 /* 2 */ | ||
38 | #define BX_DIGITAL_IN 4 /* 0 */ | ||
39 | #define BX_NUM 4 | ||
40 | |||
41 | |||
42 | #include <sound/driver.h> | ||
43 | #include <linux/delay.h> | ||
44 | #include <linux/init.h> | ||
45 | #include <linux/interrupt.h> | ||
46 | #include <linux/pci.h> | ||
47 | #include <linux/slab.h> | ||
48 | #include <linux/moduleparam.h> | ||
49 | #include <linux/firmware.h> | ||
50 | #include <sound/core.h> | ||
51 | #include <sound/info.h> | ||
52 | #include <sound/control.h> | ||
53 | #include <sound/pcm.h> | ||
54 | #include <sound/pcm_params.h> | ||
55 | #include <sound/asoundef.h> | ||
56 | #include <sound/initval.h> | ||
57 | #include <asm/io.h> | ||
58 | #include <asm/atomic.h> | ||
59 | #include "echoaudio.h" | ||
60 | |||
61 | #define FW_361_LOADER 0 | ||
62 | #define FW_INDIGO_IO_DSP 1 | ||
63 | |||
64 | static const struct firmware card_fw[] = { | ||
65 | {0, "loader_dsp.fw"}, | ||
66 | {0, "indigo_io_dsp.fw"} | ||
67 | }; | ||
68 | |||
69 | static struct pci_device_id snd_echo_ids[] = { | ||
70 | {0x1057, 0x3410, 0xECC0, 0x00A0, 0, 0, 0}, /* Indigo IO*/ | ||
71 | {0,} | ||
72 | }; | ||
73 | |||
74 | static struct snd_pcm_hardware pcm_hardware_skel = { | ||
75 | .info = SNDRV_PCM_INFO_MMAP | | ||
76 | SNDRV_PCM_INFO_INTERLEAVED | | ||
77 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
78 | SNDRV_PCM_INFO_MMAP_VALID | | ||
79 | SNDRV_PCM_INFO_PAUSE | | ||
80 | SNDRV_PCM_INFO_SYNC_START, | ||
81 | .formats = SNDRV_PCM_FMTBIT_U8 | | ||
82 | SNDRV_PCM_FMTBIT_S16_LE | | ||
83 | SNDRV_PCM_FMTBIT_S24_3LE | | ||
84 | SNDRV_PCM_FMTBIT_S32_LE | | ||
85 | SNDRV_PCM_FMTBIT_S32_BE, | ||
86 | .rates = SNDRV_PCM_RATE_32000 | | ||
87 | SNDRV_PCM_RATE_44100 | | ||
88 | SNDRV_PCM_RATE_48000 | | ||
89 | SNDRV_PCM_RATE_88200 | | ||
90 | SNDRV_PCM_RATE_96000, | ||
91 | .rate_min = 32000, | ||
92 | .rate_max = 96000, | ||
93 | .channels_min = 1, | ||
94 | .channels_max = 8, | ||
95 | .buffer_bytes_max = 262144, | ||
96 | .period_bytes_min = 32, | ||
97 | .period_bytes_max = 131072, | ||
98 | .periods_min = 2, | ||
99 | .periods_max = 220, | ||
100 | }; | ||
101 | |||
102 | #include "indigoio_dsp.c" | ||
103 | #include "echoaudio_dsp.c" | ||
104 | #include "echoaudio.c" | ||
105 | |||
diff --git a/sound/pci/echoaudio/indigoio_dsp.c b/sound/pci/echoaudio/indigoio_dsp.c new file mode 100644 index 000000000000..f3ad13d06be0 --- /dev/null +++ b/sound/pci/echoaudio/indigoio_dsp.c | |||
@@ -0,0 +1,141 @@ | |||
1 | /**************************************************************************** | ||
2 | |||
3 | Copyright Echo Digital Audio Corporation (c) 1998 - 2004 | ||
4 | All rights reserved | ||
5 | www.echoaudio.com | ||
6 | |||
7 | This file is part of Echo Digital Audio's generic driver library. | ||
8 | |||
9 | Echo Digital Audio's generic driver library is free software; | ||
10 | you can redistribute it and/or modify it under the terms of | ||
11 | the GNU General Public License as published by the Free Software | ||
12 | Foundation. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, | ||
22 | MA 02111-1307, USA. | ||
23 | |||
24 | ************************************************************************* | ||
25 | |||
26 | Translation from C++ and adaptation for use in ALSA-Driver | ||
27 | were made by Giuliano Pochini <pochini@shiny.it> | ||
28 | |||
29 | ****************************************************************************/ | ||
30 | |||
31 | |||
32 | static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, | ||
33 | int gain); | ||
34 | static int update_vmixer_level(struct echoaudio *chip); | ||
35 | |||
36 | |||
37 | static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | ||
38 | { | ||
39 | int err; | ||
40 | |||
41 | DE_INIT(("init_hw() - Indigo IO\n")); | ||
42 | snd_assert((subdevice_id & 0xfff0) == INDIGO_IO, return -ENODEV); | ||
43 | |||
44 | if ((err = init_dsp_comm_page(chip))) { | ||
45 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | ||
46 | return err; | ||
47 | } | ||
48 | |||
49 | chip->device_id = device_id; | ||
50 | chip->subdevice_id = subdevice_id; | ||
51 | chip->bad_board = TRUE; | ||
52 | chip->dsp_code_to_load = &card_fw[FW_INDIGO_IO_DSP]; | ||
53 | /* Since this card has no ASIC, mark it as loaded so everything | ||
54 | works OK */ | ||
55 | chip->asic_loaded = TRUE; | ||
56 | chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL; | ||
57 | |||
58 | if ((err = load_firmware(chip)) < 0) | ||
59 | return err; | ||
60 | chip->bad_board = FALSE; | ||
61 | |||
62 | if ((err = init_line_levels(chip)) < 0) | ||
63 | return err; | ||
64 | |||
65 | /* Default routing of the virtual channels: all vchannels are routed | ||
66 | to the stereo output */ | ||
67 | set_vmixer_gain(chip, 0, 0, 0); | ||
68 | set_vmixer_gain(chip, 1, 1, 0); | ||
69 | set_vmixer_gain(chip, 0, 2, 0); | ||
70 | set_vmixer_gain(chip, 1, 3, 0); | ||
71 | set_vmixer_gain(chip, 0, 4, 0); | ||
72 | set_vmixer_gain(chip, 1, 5, 0); | ||
73 | set_vmixer_gain(chip, 0, 6, 0); | ||
74 | set_vmixer_gain(chip, 1, 7, 0); | ||
75 | err = update_vmixer_level(chip); | ||
76 | |||
77 | DE_INIT(("init_hw done\n")); | ||
78 | return err; | ||
79 | } | ||
80 | |||
81 | |||
82 | |||
83 | static u32 detect_input_clocks(const struct echoaudio *chip) | ||
84 | { | ||
85 | return ECHO_CLOCK_BIT_INTERNAL; | ||
86 | } | ||
87 | |||
88 | |||
89 | |||
90 | /* The IndigoIO has no ASIC. Just do nothing */ | ||
91 | static int load_asic(struct echoaudio *chip) | ||
92 | { | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | |||
97 | |||
98 | static int set_sample_rate(struct echoaudio *chip, u32 rate) | ||
99 | { | ||
100 | if (wait_handshake(chip)) | ||
101 | return -EIO; | ||
102 | |||
103 | chip->sample_rate = rate; | ||
104 | chip->comm_page->sample_rate = cpu_to_le32(rate); | ||
105 | clear_handshake(chip); | ||
106 | return send_vector(chip, DSP_VC_UPDATE_CLOCKS); | ||
107 | } | ||
108 | |||
109 | |||
110 | |||
111 | /* This function routes the sound from a virtual channel to a real output */ | ||
112 | static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, | ||
113 | int gain) | ||
114 | { | ||
115 | int index; | ||
116 | |||
117 | snd_assert(pipe < num_pipes_out(chip) && | ||
118 | output < num_busses_out(chip), return -EINVAL); | ||
119 | |||
120 | if (wait_handshake(chip)) | ||
121 | return -EIO; | ||
122 | |||
123 | chip->vmixer_gain[output][pipe] = gain; | ||
124 | index = output * num_pipes_out(chip) + pipe; | ||
125 | chip->comm_page->vmixer[index] = gain; | ||
126 | |||
127 | DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain)); | ||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | |||
132 | |||
133 | /* Tell the DSP to read and update virtual mixer levels in comm page. */ | ||
134 | static int update_vmixer_level(struct echoaudio *chip) | ||
135 | { | ||
136 | if (wait_handshake(chip)) | ||
137 | return -EIO; | ||
138 | clear_handshake(chip); | ||
139 | return send_vector(chip, DSP_VC_SET_VMIXER_GAIN); | ||
140 | } | ||
141 | |||
diff --git a/sound/pci/echoaudio/layla20.c b/sound/pci/echoaudio/layla20.c new file mode 100644 index 000000000000..e503d74b3ba9 --- /dev/null +++ b/sound/pci/echoaudio/layla20.c | |||
@@ -0,0 +1,112 @@ | |||
1 | /* | ||
2 | * ALSA driver for Echoaudio soundcards. | ||
3 | * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #define ECHOGALS_FAMILY | ||
20 | #define ECHOCARD_LAYLA20 | ||
21 | #define ECHOCARD_NAME "Layla20" | ||
22 | #define ECHOCARD_HAS_MONITOR | ||
23 | #define ECHOCARD_HAS_ASIC | ||
24 | #define ECHOCARD_HAS_INPUT_GAIN | ||
25 | #define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL | ||
26 | #define ECHOCARD_HAS_SUPER_INTERLEAVE | ||
27 | #define ECHOCARD_HAS_DIGITAL_IO | ||
28 | #define ECHOCARD_HAS_EXTERNAL_CLOCK | ||
29 | #define ECHOCARD_HAS_ADAT FALSE | ||
30 | #define ECHOCARD_HAS_OUTPUT_CLOCK_SWITCH | ||
31 | #define ECHOCARD_HAS_MIDI | ||
32 | |||
33 | /* Pipe indexes */ | ||
34 | #define PX_ANALOG_OUT 0 /* 10 */ | ||
35 | #define PX_DIGITAL_OUT 10 /* 2 */ | ||
36 | #define PX_ANALOG_IN 12 /* 8 */ | ||
37 | #define PX_DIGITAL_IN 20 /* 2 */ | ||
38 | #define PX_NUM 22 | ||
39 | |||
40 | /* Bus indexes */ | ||
41 | #define BX_ANALOG_OUT 0 /* 10 */ | ||
42 | #define BX_DIGITAL_OUT 10 /* 2 */ | ||
43 | #define BX_ANALOG_IN 12 /* 8 */ | ||
44 | #define BX_DIGITAL_IN 20 /* 2 */ | ||
45 | #define BX_NUM 22 | ||
46 | |||
47 | |||
48 | #include <sound/driver.h> | ||
49 | #include <linux/delay.h> | ||
50 | #include <linux/init.h> | ||
51 | #include <linux/interrupt.h> | ||
52 | #include <linux/pci.h> | ||
53 | #include <linux/slab.h> | ||
54 | #include <linux/moduleparam.h> | ||
55 | #include <linux/firmware.h> | ||
56 | #include <sound/core.h> | ||
57 | #include <sound/info.h> | ||
58 | #include <sound/control.h> | ||
59 | #include <sound/pcm.h> | ||
60 | #include <sound/pcm_params.h> | ||
61 | #include <sound/asoundef.h> | ||
62 | #include <sound/initval.h> | ||
63 | #include <sound/rawmidi.h> | ||
64 | #include <asm/io.h> | ||
65 | #include <asm/atomic.h> | ||
66 | #include "echoaudio.h" | ||
67 | |||
68 | #define FW_LAYLA20_DSP 0 | ||
69 | #define FW_LAYLA20_ASIC 1 | ||
70 | |||
71 | static const struct firmware card_fw[] = { | ||
72 | {0, "layla20_dsp.fw"}, | ||
73 | {0, "layla20_asic.fw"} | ||
74 | }; | ||
75 | |||
76 | static struct pci_device_id snd_echo_ids[] = { | ||
77 | {0x1057, 0x1801, 0xECC0, 0x0030, 0, 0, 0}, /* DSP 56301 Layla20 rev.0 */ | ||
78 | {0x1057, 0x1801, 0xECC0, 0x0031, 0, 0, 0}, /* DSP 56301 Layla20 rev.1 */ | ||
79 | {0,} | ||
80 | }; | ||
81 | |||
82 | static struct snd_pcm_hardware pcm_hardware_skel = { | ||
83 | .info = SNDRV_PCM_INFO_MMAP | | ||
84 | SNDRV_PCM_INFO_INTERLEAVED | | ||
85 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
86 | SNDRV_PCM_INFO_MMAP_VALID | | ||
87 | SNDRV_PCM_INFO_PAUSE | | ||
88 | SNDRV_PCM_INFO_SYNC_START, | ||
89 | .formats = SNDRV_PCM_FMTBIT_U8 | | ||
90 | SNDRV_PCM_FMTBIT_S16_LE | | ||
91 | SNDRV_PCM_FMTBIT_S24_3LE | | ||
92 | SNDRV_PCM_FMTBIT_S32_LE | | ||
93 | SNDRV_PCM_FMTBIT_S32_BE, | ||
94 | .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_CONTINUOUS, | ||
95 | .rate_min = 8000, | ||
96 | .rate_max = 50000, | ||
97 | .channels_min = 1, | ||
98 | .channels_max = 10, | ||
99 | .buffer_bytes_max = 262144, | ||
100 | .period_bytes_min = 32, | ||
101 | .period_bytes_max = 131072, | ||
102 | .periods_min = 2, | ||
103 | .periods_max = 220, | ||
104 | /* One page (4k) contains 512 instructions. I don't know if the hw | ||
105 | supports lists longer than this. In this case periods_max=220 is a | ||
106 | safe limit to make sure the list never exceeds 512 instructions. */ | ||
107 | }; | ||
108 | |||
109 | #include "layla20_dsp.c" | ||
110 | #include "echoaudio_dsp.c" | ||
111 | #include "echoaudio.c" | ||
112 | #include "midi.c" | ||
diff --git a/sound/pci/echoaudio/layla20_dsp.c b/sound/pci/echoaudio/layla20_dsp.c new file mode 100644 index 000000000000..990c9a60a0a8 --- /dev/null +++ b/sound/pci/echoaudio/layla20_dsp.c | |||
@@ -0,0 +1,290 @@ | |||
1 | /**************************************************************************** | ||
2 | |||
3 | Copyright Echo Digital Audio Corporation (c) 1998 - 2004 | ||
4 | All rights reserved | ||
5 | www.echoaudio.com | ||
6 | |||
7 | This file is part of Echo Digital Audio's generic driver library. | ||
8 | |||
9 | Echo Digital Audio's generic driver library is free software; | ||
10 | you can redistribute it and/or modify it under the terms of | ||
11 | the GNU General Public License as published by the Free Software | ||
12 | Foundation. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, | ||
22 | MA 02111-1307, USA. | ||
23 | |||
24 | ************************************************************************* | ||
25 | |||
26 | Translation from C++ and adaptation for use in ALSA-Driver | ||
27 | were made by Giuliano Pochini <pochini@shiny.it> | ||
28 | |||
29 | ****************************************************************************/ | ||
30 | |||
31 | |||
32 | static int read_dsp(struct echoaudio *chip, u32 *data); | ||
33 | static int set_professional_spdif(struct echoaudio *chip, char prof); | ||
34 | static int load_asic_generic(struct echoaudio *chip, u32 cmd, | ||
35 | const struct firmware *asic); | ||
36 | static int check_asic_status(struct echoaudio *chip); | ||
37 | static int update_flags(struct echoaudio *chip); | ||
38 | |||
39 | |||
40 | static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | ||
41 | { | ||
42 | int err; | ||
43 | |||
44 | DE_INIT(("init_hw() - Layla20\n")); | ||
45 | snd_assert((subdevice_id & 0xfff0) == LAYLA20, return -ENODEV); | ||
46 | |||
47 | if ((err = init_dsp_comm_page(chip))) { | ||
48 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | ||
49 | return err; | ||
50 | } | ||
51 | |||
52 | chip->device_id = device_id; | ||
53 | chip->subdevice_id = subdevice_id; | ||
54 | chip->bad_board = TRUE; | ||
55 | chip->has_midi = TRUE; | ||
56 | chip->dsp_code_to_load = &card_fw[FW_LAYLA20_DSP]; | ||
57 | chip->input_clock_types = | ||
58 | ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF | | ||
59 | ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER; | ||
60 | chip->output_clock_types = | ||
61 | ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER; | ||
62 | |||
63 | if ((err = load_firmware(chip)) < 0) | ||
64 | return err; | ||
65 | chip->bad_board = FALSE; | ||
66 | |||
67 | if ((err = init_line_levels(chip)) < 0) | ||
68 | return err; | ||
69 | |||
70 | err = set_professional_spdif(chip, TRUE); | ||
71 | |||
72 | DE_INIT(("init_hw done\n")); | ||
73 | return err; | ||
74 | } | ||
75 | |||
76 | |||
77 | |||
78 | static u32 detect_input_clocks(const struct echoaudio *chip) | ||
79 | { | ||
80 | u32 clocks_from_dsp, clock_bits; | ||
81 | |||
82 | /* Map the DSP clock detect bits to the generic driver clock detect bits */ | ||
83 | clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); | ||
84 | |||
85 | clock_bits = ECHO_CLOCK_BIT_INTERNAL; | ||
86 | |||
87 | if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF) | ||
88 | clock_bits |= ECHO_CLOCK_BIT_SPDIF; | ||
89 | |||
90 | if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_WORD) { | ||
91 | if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SUPER) | ||
92 | clock_bits |= ECHO_CLOCK_BIT_SUPER; | ||
93 | else | ||
94 | clock_bits |= ECHO_CLOCK_BIT_WORD; | ||
95 | } | ||
96 | |||
97 | return clock_bits; | ||
98 | } | ||
99 | |||
100 | |||
101 | |||
102 | /* ASIC status check - some cards have one or two ASICs that need to be | ||
103 | loaded. Once that load is complete, this function is called to see if | ||
104 | the load was successful. | ||
105 | If this load fails, it does not necessarily mean that the hardware is | ||
106 | defective - the external box may be disconnected or turned off. | ||
107 | This routine sometimes fails for Layla20; for Layla20, the loop runs | ||
108 | 5 times and succeeds if it wins on three of the loops. */ | ||
109 | static int check_asic_status(struct echoaudio *chip) | ||
110 | { | ||
111 | u32 asic_status; | ||
112 | int goodcnt, i; | ||
113 | |||
114 | chip->asic_loaded = FALSE; | ||
115 | for (i = goodcnt = 0; i < 5; i++) { | ||
116 | send_vector(chip, DSP_VC_TEST_ASIC); | ||
117 | |||
118 | /* The DSP will return a value to indicate whether or not | ||
119 | the ASIC is currently loaded */ | ||
120 | if (read_dsp(chip, &asic_status) < 0) { | ||
121 | DE_ACT(("check_asic_status: failed on read_dsp\n")); | ||
122 | return -EIO; | ||
123 | } | ||
124 | |||
125 | if (asic_status == ASIC_ALREADY_LOADED) { | ||
126 | if (++goodcnt == 3) { | ||
127 | chip->asic_loaded = TRUE; | ||
128 | return 0; | ||
129 | } | ||
130 | } | ||
131 | } | ||
132 | return -EIO; | ||
133 | } | ||
134 | |||
135 | |||
136 | |||
137 | /* Layla20 has an ASIC in the external box */ | ||
138 | static int load_asic(struct echoaudio *chip) | ||
139 | { | ||
140 | int err; | ||
141 | |||
142 | if (chip->asic_loaded) | ||
143 | return 0; | ||
144 | |||
145 | err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA_ASIC, | ||
146 | &card_fw[FW_LAYLA20_ASIC]); | ||
147 | if (err < 0) | ||
148 | return err; | ||
149 | |||
150 | /* Check if ASIC is alive and well. */ | ||
151 | return check_asic_status(chip); | ||
152 | } | ||
153 | |||
154 | |||
155 | |||
156 | static int set_sample_rate(struct echoaudio *chip, u32 rate) | ||
157 | { | ||
158 | snd_assert(rate >= 8000 && rate <= 50000, return -EINVAL); | ||
159 | |||
160 | /* Only set the clock for internal mode. Do not return failure, | ||
161 | simply treat it as a non-event. */ | ||
162 | if (chip->input_clock != ECHO_CLOCK_INTERNAL) { | ||
163 | DE_ACT(("set_sample_rate: Cannot set sample rate - " | ||
164 | "clock not set to CLK_CLOCKININTERNAL\n")); | ||
165 | chip->comm_page->sample_rate = cpu_to_le32(rate); | ||
166 | chip->sample_rate = rate; | ||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | if (wait_handshake(chip)) | ||
171 | return -EIO; | ||
172 | |||
173 | DE_ACT(("set_sample_rate(%d)\n", rate)); | ||
174 | chip->sample_rate = rate; | ||
175 | chip->comm_page->sample_rate = cpu_to_le32(rate); | ||
176 | clear_handshake(chip); | ||
177 | return send_vector(chip, DSP_VC_SET_LAYLA_SAMPLE_RATE); | ||
178 | } | ||
179 | |||
180 | |||
181 | |||
182 | static int set_input_clock(struct echoaudio *chip, u16 clock_source) | ||
183 | { | ||
184 | u16 clock; | ||
185 | u32 rate; | ||
186 | |||
187 | DE_ACT(("set_input_clock:\n")); | ||
188 | rate = 0; | ||
189 | switch (clock_source) { | ||
190 | case ECHO_CLOCK_INTERNAL: | ||
191 | DE_ACT(("Set Layla20 clock to INTERNAL\n")); | ||
192 | rate = chip->sample_rate; | ||
193 | clock = LAYLA20_CLOCK_INTERNAL; | ||
194 | break; | ||
195 | case ECHO_CLOCK_SPDIF: | ||
196 | DE_ACT(("Set Layla20 clock to SPDIF\n")); | ||
197 | clock = LAYLA20_CLOCK_SPDIF; | ||
198 | break; | ||
199 | case ECHO_CLOCK_WORD: | ||
200 | DE_ACT(("Set Layla20 clock to WORD\n")); | ||
201 | clock = LAYLA20_CLOCK_WORD; | ||
202 | break; | ||
203 | case ECHO_CLOCK_SUPER: | ||
204 | DE_ACT(("Set Layla20 clock to SUPER\n")); | ||
205 | clock = LAYLA20_CLOCK_SUPER; | ||
206 | break; | ||
207 | default: | ||
208 | DE_ACT(("Input clock 0x%x not supported for Layla24\n", | ||
209 | clock_source)); | ||
210 | return -EINVAL; | ||
211 | } | ||
212 | chip->input_clock = clock_source; | ||
213 | |||
214 | chip->comm_page->input_clock = cpu_to_le16(clock); | ||
215 | clear_handshake(chip); | ||
216 | send_vector(chip, DSP_VC_UPDATE_CLOCKS); | ||
217 | |||
218 | if (rate) | ||
219 | set_sample_rate(chip, rate); | ||
220 | |||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | |||
225 | |||
226 | static int set_output_clock(struct echoaudio *chip, u16 clock) | ||
227 | { | ||
228 | DE_ACT(("set_output_clock: %d\n", clock)); | ||
229 | switch (clock) { | ||
230 | case ECHO_CLOCK_SUPER: | ||
231 | clock = LAYLA20_OUTPUT_CLOCK_SUPER; | ||
232 | break; | ||
233 | case ECHO_CLOCK_WORD: | ||
234 | clock = LAYLA20_OUTPUT_CLOCK_WORD; | ||
235 | break; | ||
236 | default: | ||
237 | DE_ACT(("set_output_clock wrong clock\n")); | ||
238 | return -EINVAL; | ||
239 | } | ||
240 | |||
241 | if (wait_handshake(chip)) | ||
242 | return -EIO; | ||
243 | |||
244 | chip->comm_page->output_clock = cpu_to_le16(clock); | ||
245 | chip->output_clock = clock; | ||
246 | clear_handshake(chip); | ||
247 | return send_vector(chip, DSP_VC_UPDATE_CLOCKS); | ||
248 | } | ||
249 | |||
250 | |||
251 | |||
252 | /* Set input bus gain (one unit is 0.5dB !) */ | ||
253 | static int set_input_gain(struct echoaudio *chip, u16 input, int gain) | ||
254 | { | ||
255 | snd_assert(input < num_busses_in(chip), return -EINVAL); | ||
256 | |||
257 | if (wait_handshake(chip)) | ||
258 | return -EIO; | ||
259 | |||
260 | chip->input_gain[input] = gain; | ||
261 | gain += GL20_INPUT_GAIN_MAGIC_NUMBER; | ||
262 | chip->comm_page->line_in_level[input] = gain; | ||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | |||
267 | |||
268 | /* Tell the DSP to reread the flags from the comm page */ | ||
269 | static int update_flags(struct echoaudio *chip) | ||
270 | { | ||
271 | if (wait_handshake(chip)) | ||
272 | return -EIO; | ||
273 | clear_handshake(chip); | ||
274 | return send_vector(chip, DSP_VC_UPDATE_FLAGS); | ||
275 | } | ||
276 | |||
277 | |||
278 | |||
279 | static int set_professional_spdif(struct echoaudio *chip, char prof) | ||
280 | { | ||
281 | DE_ACT(("set_professional_spdif %d\n", prof)); | ||
282 | if (prof) | ||
283 | chip->comm_page->flags |= | ||
284 | __constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); | ||
285 | else | ||
286 | chip->comm_page->flags &= | ||
287 | ~__constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); | ||
288 | chip->professional_spdif = prof; | ||
289 | return update_flags(chip); | ||
290 | } | ||
diff --git a/sound/pci/echoaudio/layla24.c b/sound/pci/echoaudio/layla24.c new file mode 100644 index 000000000000..d4581fdc841c --- /dev/null +++ b/sound/pci/echoaudio/layla24.c | |||
@@ -0,0 +1,121 @@ | |||
1 | /* | ||
2 | * ALSA driver for Echoaudio soundcards. | ||
3 | * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #define ECHO24_FAMILY | ||
20 | #define ECHOCARD_LAYLA24 | ||
21 | #define ECHOCARD_NAME "Layla24" | ||
22 | #define ECHOCARD_HAS_MONITOR | ||
23 | #define ECHOCARD_HAS_ASIC | ||
24 | #define ECHOCARD_HAS_INPUT_NOMINAL_LEVEL | ||
25 | #define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL | ||
26 | #define ECHOCARD_HAS_SUPER_INTERLEAVE | ||
27 | #define ECHOCARD_HAS_DIGITAL_IO | ||
28 | #define ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE | ||
29 | #define ECHOCARD_HAS_DIGITAL_MODE_SWITCH | ||
30 | #define ECHOCARD_HAS_EXTERNAL_CLOCK | ||
31 | #define ECHOCARD_HAS_ADAT 6 | ||
32 | #define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 | ||
33 | #define ECHOCARD_HAS_MIDI | ||
34 | |||
35 | /* Pipe indexes */ | ||
36 | #define PX_ANALOG_OUT 0 /* 8 */ | ||
37 | #define PX_DIGITAL_OUT 8 /* 8 */ | ||
38 | #define PX_ANALOG_IN 16 /* 8 */ | ||
39 | #define PX_DIGITAL_IN 24 /* 8 */ | ||
40 | #define PX_NUM 32 | ||
41 | |||
42 | /* Bus indexes */ | ||
43 | #define BX_ANALOG_OUT 0 /* 8 */ | ||
44 | #define BX_DIGITAL_OUT 8 /* 8 */ | ||
45 | #define BX_ANALOG_IN 16 /* 8 */ | ||
46 | #define BX_DIGITAL_IN 24 /* 8 */ | ||
47 | #define BX_NUM 32 | ||
48 | |||
49 | |||
50 | #include <sound/driver.h> | ||
51 | #include <linux/delay.h> | ||
52 | #include <linux/init.h> | ||
53 | #include <linux/interrupt.h> | ||
54 | #include <linux/pci.h> | ||
55 | #include <linux/slab.h> | ||
56 | #include <linux/moduleparam.h> | ||
57 | #include <linux/firmware.h> | ||
58 | #include <sound/core.h> | ||
59 | #include <sound/info.h> | ||
60 | #include <sound/control.h> | ||
61 | #include <sound/pcm.h> | ||
62 | #include <sound/pcm_params.h> | ||
63 | #include <sound/asoundef.h> | ||
64 | #include <sound/initval.h> | ||
65 | #include <sound/rawmidi.h> | ||
66 | #include <asm/io.h> | ||
67 | #include <asm/atomic.h> | ||
68 | #include "echoaudio.h" | ||
69 | |||
70 | #define FW_361_LOADER 0 | ||
71 | #define FW_LAYLA24_DSP 1 | ||
72 | #define FW_LAYLA24_1_ASIC 2 | ||
73 | #define FW_LAYLA24_2A_ASIC 3 | ||
74 | #define FW_LAYLA24_2S_ASIC 4 | ||
75 | |||
76 | static const struct firmware card_fw[] = { | ||
77 | {0, "loader_dsp.fw"}, | ||
78 | {0, "layla24_dsp.fw"}, | ||
79 | {0, "layla24_1_asic.fw"}, | ||
80 | {0, "layla24_2A_asic.fw"}, | ||
81 | {0, "layla24_2S_asic.fw"} | ||
82 | }; | ||
83 | |||
84 | static struct pci_device_id snd_echo_ids[] = { | ||
85 | {0x1057, 0x3410, 0xECC0, 0x0060, 0, 0, 0}, /* DSP 56361 Layla24 rev.0 */ | ||
86 | {0,} | ||
87 | }; | ||
88 | |||
89 | static struct snd_pcm_hardware pcm_hardware_skel = { | ||
90 | .info = SNDRV_PCM_INFO_MMAP | | ||
91 | SNDRV_PCM_INFO_INTERLEAVED | | ||
92 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
93 | SNDRV_PCM_INFO_MMAP_VALID | | ||
94 | SNDRV_PCM_INFO_PAUSE | | ||
95 | SNDRV_PCM_INFO_SYNC_START, | ||
96 | .formats = SNDRV_PCM_FMTBIT_U8 | | ||
97 | SNDRV_PCM_FMTBIT_S16_LE | | ||
98 | SNDRV_PCM_FMTBIT_S24_3LE | | ||
99 | SNDRV_PCM_FMTBIT_S32_LE | | ||
100 | SNDRV_PCM_FMTBIT_S32_BE, | ||
101 | .rates = SNDRV_PCM_RATE_8000_96000, | ||
102 | .rate_min = 8000, | ||
103 | .rate_max = 100000, | ||
104 | .channels_min = 1, | ||
105 | .channels_max = 8, | ||
106 | .buffer_bytes_max = 262144, | ||
107 | .period_bytes_min = 32, | ||
108 | .period_bytes_max = 131072, | ||
109 | .periods_min = 2, | ||
110 | .periods_max = 220, | ||
111 | /* One page (4k) contains 512 instructions. I don't know if the hw | ||
112 | supports lists longer than this. In this case periods_max=220 is a | ||
113 | safe limit to make sure the list never exceeds 512 instructions. */ | ||
114 | }; | ||
115 | |||
116 | |||
117 | #include "layla24_dsp.c" | ||
118 | #include "echoaudio_dsp.c" | ||
119 | #include "echoaudio_gml.c" | ||
120 | #include "echoaudio.c" | ||
121 | #include "midi.c" | ||
diff --git a/sound/pci/echoaudio/layla24_dsp.c b/sound/pci/echoaudio/layla24_dsp.c new file mode 100644 index 000000000000..7ec5b63d0dce --- /dev/null +++ b/sound/pci/echoaudio/layla24_dsp.c | |||
@@ -0,0 +1,394 @@ | |||
1 | /**************************************************************************** | ||
2 | |||
3 | Copyright Echo Digital Audio Corporation (c) 1998 - 2004 | ||
4 | All rights reserved | ||
5 | www.echoaudio.com | ||
6 | |||
7 | This file is part of Echo Digital Audio's generic driver library. | ||
8 | |||
9 | Echo Digital Audio's generic driver library is free software; | ||
10 | you can redistribute it and/or modify it under the terms of | ||
11 | the GNU General Public License as published by the Free Software Foundation. | ||
12 | |||
13 | This program is distributed in the hope that it will be useful, | ||
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | GNU General Public License for more details. | ||
17 | |||
18 | You should have received a copy of the GNU General Public License | ||
19 | along with this program; if not, write to the Free Software | ||
20 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, | ||
21 | MA 02111-1307, USA. | ||
22 | |||
23 | ************************************************************************* | ||
24 | |||
25 | Translation from C++ and adaptation for use in ALSA-Driver | ||
26 | were made by Giuliano Pochini <pochini@shiny.it> | ||
27 | |||
28 | ****************************************************************************/ | ||
29 | |||
30 | |||
31 | static int write_control_reg(struct echoaudio *chip, u32 value, char force); | ||
32 | static int set_input_clock(struct echoaudio *chip, u16 clock); | ||
33 | static int set_professional_spdif(struct echoaudio *chip, char prof); | ||
34 | static int set_digital_mode(struct echoaudio *chip, u8 mode); | ||
35 | static int load_asic_generic(struct echoaudio *chip, u32 cmd, | ||
36 | const struct firmware *asic); | ||
37 | static int check_asic_status(struct echoaudio *chip); | ||
38 | |||
39 | |||
40 | static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | ||
41 | { | ||
42 | int err; | ||
43 | |||
44 | DE_INIT(("init_hw() - Layla24\n")); | ||
45 | snd_assert((subdevice_id & 0xfff0) == LAYLA24, return -ENODEV); | ||
46 | |||
47 | if ((err = init_dsp_comm_page(chip))) { | ||
48 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | ||
49 | return err; | ||
50 | } | ||
51 | |||
52 | chip->device_id = device_id; | ||
53 | chip->subdevice_id = subdevice_id; | ||
54 | chip->bad_board = TRUE; | ||
55 | chip->has_midi = TRUE; | ||
56 | chip->dsp_code_to_load = &card_fw[FW_LAYLA24_DSP]; | ||
57 | chip->input_clock_types = | ||
58 | ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF | | ||
59 | ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_ADAT; | ||
60 | chip->digital_modes = | ||
61 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | | ||
62 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | | ||
63 | ECHOCAPS_HAS_DIGITAL_MODE_ADAT; | ||
64 | chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; | ||
65 | chip->professional_spdif = FALSE; | ||
66 | chip->digital_in_automute = TRUE; | ||
67 | |||
68 | if ((err = load_firmware(chip)) < 0) | ||
69 | return err; | ||
70 | chip->bad_board = FALSE; | ||
71 | |||
72 | if ((err = init_line_levels(chip)) < 0) | ||
73 | return err; | ||
74 | |||
75 | err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA); | ||
76 | snd_assert(err >= 0, return err); | ||
77 | err = set_professional_spdif(chip, TRUE); | ||
78 | |||
79 | DE_INIT(("init_hw done\n")); | ||
80 | return err; | ||
81 | } | ||
82 | |||
83 | |||
84 | |||
85 | static u32 detect_input_clocks(const struct echoaudio *chip) | ||
86 | { | ||
87 | u32 clocks_from_dsp, clock_bits; | ||
88 | |||
89 | /* Map the DSP clock detect bits to the generic driver clock detect bits */ | ||
90 | clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); | ||
91 | |||
92 | clock_bits = ECHO_CLOCK_BIT_INTERNAL; | ||
93 | |||
94 | if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF) | ||
95 | clock_bits |= ECHO_CLOCK_BIT_SPDIF; | ||
96 | |||
97 | if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ADAT) | ||
98 | clock_bits |= ECHO_CLOCK_BIT_ADAT; | ||
99 | |||
100 | if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD) | ||
101 | clock_bits |= ECHO_CLOCK_BIT_WORD; | ||
102 | |||
103 | return clock_bits; | ||
104 | } | ||
105 | |||
106 | |||
107 | |||
108 | /* Layla24 has an ASIC on the PCI card and another ASIC in the external box; | ||
109 | both need to be loaded. */ | ||
110 | static int load_asic(struct echoaudio *chip) | ||
111 | { | ||
112 | int err; | ||
113 | |||
114 | if (chip->asic_loaded) | ||
115 | return 1; | ||
116 | |||
117 | DE_INIT(("load_asic\n")); | ||
118 | |||
119 | /* Give the DSP a few milliseconds to settle down */ | ||
120 | mdelay(10); | ||
121 | |||
122 | /* Load the ASIC for the PCI card */ | ||
123 | err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_PCI_CARD_ASIC, | ||
124 | &card_fw[FW_LAYLA24_1_ASIC]); | ||
125 | if (err < 0) | ||
126 | return err; | ||
127 | |||
128 | chip->asic_code = &card_fw[FW_LAYLA24_2S_ASIC]; | ||
129 | |||
130 | /* Now give the new ASIC a little time to set up */ | ||
131 | mdelay(10); | ||
132 | |||
133 | /* Do the external one */ | ||
134 | err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC, | ||
135 | &card_fw[FW_LAYLA24_2S_ASIC]); | ||
136 | if (err < 0) | ||
137 | return FALSE; | ||
138 | |||
139 | /* Now give the external ASIC a little time to set up */ | ||
140 | mdelay(10); | ||
141 | |||
142 | /* See if it worked */ | ||
143 | err = check_asic_status(chip); | ||
144 | |||
145 | /* Set up the control register if the load succeeded - | ||
146 | 48 kHz, internal clock, S/PDIF RCA mode */ | ||
147 | if (!err) | ||
148 | err = write_control_reg(chip, GML_CONVERTER_ENABLE | GML_48KHZ, | ||
149 | TRUE); | ||
150 | |||
151 | DE_INIT(("load_asic() done\n")); | ||
152 | return err; | ||
153 | } | ||
154 | |||
155 | |||
156 | |||
157 | static int set_sample_rate(struct echoaudio *chip, u32 rate) | ||
158 | { | ||
159 | u32 control_reg, clock, base_rate; | ||
160 | |||
161 | snd_assert(rate < 50000 || chip->digital_mode != DIGITAL_MODE_ADAT, | ||
162 | return -EINVAL); | ||
163 | |||
164 | /* Only set the clock for internal mode. */ | ||
165 | if (chip->input_clock != ECHO_CLOCK_INTERNAL) { | ||
166 | DE_ACT(("set_sample_rate: Cannot set sample rate - " | ||
167 | "clock not set to CLK_CLOCKININTERNAL\n")); | ||
168 | /* Save the rate anyhow */ | ||
169 | chip->comm_page->sample_rate = cpu_to_le32(rate); | ||
170 | chip->sample_rate = rate; | ||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | /* Get the control register & clear the appropriate bits */ | ||
175 | control_reg = le32_to_cpu(chip->comm_page->control_register); | ||
176 | control_reg &= GML_CLOCK_CLEAR_MASK & GML_SPDIF_RATE_CLEAR_MASK; | ||
177 | |||
178 | clock = 0; | ||
179 | |||
180 | switch (rate) { | ||
181 | case 96000: | ||
182 | clock = GML_96KHZ; | ||
183 | break; | ||
184 | case 88200: | ||
185 | clock = GML_88KHZ; | ||
186 | break; | ||
187 | case 48000: | ||
188 | clock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1; | ||
189 | break; | ||
190 | case 44100: | ||
191 | clock = GML_44KHZ; | ||
192 | /* Professional mode */ | ||
193 | if (control_reg & GML_SPDIF_PRO_MODE) | ||
194 | clock |= GML_SPDIF_SAMPLE_RATE0; | ||
195 | break; | ||
196 | case 32000: | ||
197 | clock = GML_32KHZ | GML_SPDIF_SAMPLE_RATE0 | | ||
198 | GML_SPDIF_SAMPLE_RATE1; | ||
199 | break; | ||
200 | case 22050: | ||
201 | clock = GML_22KHZ; | ||
202 | break; | ||
203 | case 16000: | ||
204 | clock = GML_16KHZ; | ||
205 | break; | ||
206 | case 11025: | ||
207 | clock = GML_11KHZ; | ||
208 | break; | ||
209 | case 8000: | ||
210 | clock = GML_8KHZ; | ||
211 | break; | ||
212 | default: | ||
213 | /* If this is a non-standard rate, then the driver needs to | ||
214 | use Layla24's special "continuous frequency" mode */ | ||
215 | clock = LAYLA24_CONTINUOUS_CLOCK; | ||
216 | if (rate > 50000) { | ||
217 | base_rate = rate >> 1; | ||
218 | control_reg |= GML_DOUBLE_SPEED_MODE; | ||
219 | } else { | ||
220 | base_rate = rate; | ||
221 | } | ||
222 | |||
223 | if (base_rate < 25000) | ||
224 | base_rate = 25000; | ||
225 | |||
226 | if (wait_handshake(chip)) | ||
227 | return -EIO; | ||
228 | |||
229 | chip->comm_page->sample_rate = | ||
230 | cpu_to_le32(LAYLA24_MAGIC_NUMBER / base_rate - 2); | ||
231 | |||
232 | clear_handshake(chip); | ||
233 | send_vector(chip, DSP_VC_SET_LAYLA24_FREQUENCY_REG); | ||
234 | } | ||
235 | |||
236 | control_reg |= clock; | ||
237 | |||
238 | chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP ? */ | ||
239 | chip->sample_rate = rate; | ||
240 | DE_ACT(("set_sample_rate: %d clock %d\n", rate, control_reg)); | ||
241 | |||
242 | return write_control_reg(chip, control_reg, FALSE); | ||
243 | } | ||
244 | |||
245 | |||
246 | |||
247 | static int set_input_clock(struct echoaudio *chip, u16 clock) | ||
248 | { | ||
249 | u32 control_reg, clocks_from_dsp; | ||
250 | |||
251 | /* Mask off the clock select bits */ | ||
252 | control_reg = le32_to_cpu(chip->comm_page->control_register) & | ||
253 | GML_CLOCK_CLEAR_MASK; | ||
254 | clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); | ||
255 | |||
256 | /* Pick the new clock */ | ||
257 | switch (clock) { | ||
258 | case ECHO_CLOCK_INTERNAL: | ||
259 | DE_ACT(("Set Layla24 clock to INTERNAL\n")); | ||
260 | chip->input_clock = ECHO_CLOCK_INTERNAL; | ||
261 | return set_sample_rate(chip, chip->sample_rate); | ||
262 | case ECHO_CLOCK_SPDIF: | ||
263 | if (chip->digital_mode == DIGITAL_MODE_ADAT) | ||
264 | return -EAGAIN; | ||
265 | control_reg |= GML_SPDIF_CLOCK; | ||
266 | /* Layla24 doesn't support 96KHz S/PDIF */ | ||
267 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | ||
268 | DE_ACT(("Set Layla24 clock to SPDIF\n")); | ||
269 | break; | ||
270 | case ECHO_CLOCK_WORD: | ||
271 | control_reg |= GML_WORD_CLOCK; | ||
272 | if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD96) | ||
273 | control_reg |= GML_DOUBLE_SPEED_MODE; | ||
274 | else | ||
275 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | ||
276 | DE_ACT(("Set Layla24 clock to WORD\n")); | ||
277 | break; | ||
278 | case ECHO_CLOCK_ADAT: | ||
279 | if (chip->digital_mode != DIGITAL_MODE_ADAT) | ||
280 | return -EAGAIN; | ||
281 | control_reg |= GML_ADAT_CLOCK; | ||
282 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | ||
283 | DE_ACT(("Set Layla24 clock to ADAT\n")); | ||
284 | break; | ||
285 | default: | ||
286 | DE_ACT(("Input clock 0x%x not supported for Layla24\n", clock)); | ||
287 | return -EINVAL; | ||
288 | } | ||
289 | |||
290 | chip->input_clock = clock; | ||
291 | return write_control_reg(chip, control_reg, TRUE); | ||
292 | } | ||
293 | |||
294 | |||
295 | |||
296 | /* Depending on what digital mode you want, Layla24 needs different ASICs | ||
297 | loaded. This function checks the ASIC needed for the new mode and sees | ||
298 | if it matches the one already loaded. */ | ||
299 | static int switch_asic(struct echoaudio *chip, const struct firmware *asic) | ||
300 | { | ||
301 | s8 *monitors; | ||
302 | |||
303 | /* Check to see if this is already loaded */ | ||
304 | if (asic != chip->asic_code) { | ||
305 | monitors = kmalloc(MONITOR_ARRAY_SIZE, GFP_KERNEL); | ||
306 | if (! monitors) | ||
307 | return -ENOMEM; | ||
308 | |||
309 | memcpy(monitors, chip->comm_page->monitors, MONITOR_ARRAY_SIZE); | ||
310 | memset(chip->comm_page->monitors, ECHOGAIN_MUTED, | ||
311 | MONITOR_ARRAY_SIZE); | ||
312 | |||
313 | /* Load the desired ASIC */ | ||
314 | if (load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC, | ||
315 | asic) < 0) { | ||
316 | memcpy(chip->comm_page->monitors, monitors, | ||
317 | MONITOR_ARRAY_SIZE); | ||
318 | kfree(monitors); | ||
319 | return -EIO; | ||
320 | } | ||
321 | chip->asic_code = asic; | ||
322 | memcpy(chip->comm_page->monitors, monitors, MONITOR_ARRAY_SIZE); | ||
323 | kfree(monitors); | ||
324 | } | ||
325 | |||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | |||
330 | |||
331 | static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) | ||
332 | { | ||
333 | u32 control_reg; | ||
334 | int err, incompatible_clock; | ||
335 | const struct firmware *asic; | ||
336 | |||
337 | /* Set clock to "internal" if it's not compatible with the new mode */ | ||
338 | incompatible_clock = FALSE; | ||
339 | switch (mode) { | ||
340 | case DIGITAL_MODE_SPDIF_OPTICAL: | ||
341 | case DIGITAL_MODE_SPDIF_RCA: | ||
342 | if (chip->input_clock == ECHO_CLOCK_ADAT) | ||
343 | incompatible_clock = TRUE; | ||
344 | asic = &card_fw[FW_LAYLA24_2S_ASIC]; | ||
345 | break; | ||
346 | case DIGITAL_MODE_ADAT: | ||
347 | if (chip->input_clock == ECHO_CLOCK_SPDIF) | ||
348 | incompatible_clock = TRUE; | ||
349 | asic = &card_fw[FW_LAYLA24_2A_ASIC]; | ||
350 | break; | ||
351 | default: | ||
352 | DE_ACT(("Digital mode not supported: %d\n", mode)); | ||
353 | return -EINVAL; | ||
354 | } | ||
355 | |||
356 | if (incompatible_clock) { /* Switch to 48KHz, internal */ | ||
357 | chip->sample_rate = 48000; | ||
358 | spin_lock_irq(&chip->lock); | ||
359 | set_input_clock(chip, ECHO_CLOCK_INTERNAL); | ||
360 | spin_unlock_irq(&chip->lock); | ||
361 | } | ||
362 | |||
363 | /* switch_asic() can sleep */ | ||
364 | if (switch_asic(chip, asic) < 0) | ||
365 | return -EIO; | ||
366 | |||
367 | spin_lock_irq(&chip->lock); | ||
368 | |||
369 | /* Tweak the control register */ | ||
370 | control_reg = le32_to_cpu(chip->comm_page->control_register); | ||
371 | control_reg &= GML_DIGITAL_MODE_CLEAR_MASK; | ||
372 | |||
373 | switch (mode) { | ||
374 | case DIGITAL_MODE_SPDIF_OPTICAL: | ||
375 | control_reg |= GML_SPDIF_OPTICAL_MODE; | ||
376 | break; | ||
377 | case DIGITAL_MODE_SPDIF_RCA: | ||
378 | /* GML_SPDIF_OPTICAL_MODE bit cleared */ | ||
379 | break; | ||
380 | case DIGITAL_MODE_ADAT: | ||
381 | control_reg |= GML_ADAT_MODE; | ||
382 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | ||
383 | break; | ||
384 | } | ||
385 | |||
386 | err = write_control_reg(chip, control_reg, TRUE); | ||
387 | spin_unlock_irq(&chip->lock); | ||
388 | if (err < 0) | ||
389 | return err; | ||
390 | chip->digital_mode = mode; | ||
391 | |||
392 | DE_ACT(("set_digital_mode to %d\n", mode)); | ||
393 | return incompatible_clock; | ||
394 | } | ||
diff --git a/sound/pci/echoaudio/mia.c b/sound/pci/echoaudio/mia.c new file mode 100644 index 000000000000..be40c64263d2 --- /dev/null +++ b/sound/pci/echoaudio/mia.c | |||
@@ -0,0 +1,117 @@ | |||
1 | /* | ||
2 | * ALSA driver for Echoaudio soundcards. | ||
3 | * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #define ECHO24_FAMILY | ||
20 | #define ECHOCARD_MIA | ||
21 | #define ECHOCARD_NAME "Mia" | ||
22 | #define ECHOCARD_HAS_MONITOR | ||
23 | #define ECHOCARD_HAS_INPUT_NOMINAL_LEVEL | ||
24 | #define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL | ||
25 | #define ECHOCARD_HAS_SUPER_INTERLEAVE | ||
26 | #define ECHOCARD_HAS_VMIXER | ||
27 | #define ECHOCARD_HAS_DIGITAL_IO | ||
28 | #define ECHOCARD_HAS_EXTERNAL_CLOCK | ||
29 | #define ECHOCARD_HAS_ADAT FALSE | ||
30 | #define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 | ||
31 | #define ECHOCARD_HAS_MIDI | ||
32 | |||
33 | /* Pipe indexes */ | ||
34 | #define PX_ANALOG_OUT 0 /* 8 */ | ||
35 | #define PX_DIGITAL_OUT 8 /* 0 */ | ||
36 | #define PX_ANALOG_IN 8 /* 2 */ | ||
37 | #define PX_DIGITAL_IN 10 /* 2 */ | ||
38 | #define PX_NUM 12 | ||
39 | |||
40 | /* Bus indexes */ | ||
41 | #define BX_ANALOG_OUT 0 /* 2 */ | ||
42 | #define BX_DIGITAL_OUT 2 /* 2 */ | ||
43 | #define BX_ANALOG_IN 4 /* 2 */ | ||
44 | #define BX_DIGITAL_IN 6 /* 2 */ | ||
45 | #define BX_NUM 8 | ||
46 | |||
47 | |||
48 | #include <sound/driver.h> | ||
49 | #include <linux/delay.h> | ||
50 | #include <linux/init.h> | ||
51 | #include <linux/interrupt.h> | ||
52 | #include <linux/pci.h> | ||
53 | #include <linux/slab.h> | ||
54 | #include <linux/moduleparam.h> | ||
55 | #include <linux/firmware.h> | ||
56 | #include <sound/core.h> | ||
57 | #include <sound/info.h> | ||
58 | #include <sound/control.h> | ||
59 | #include <sound/pcm.h> | ||
60 | #include <sound/pcm_params.h> | ||
61 | #include <sound/asoundef.h> | ||
62 | #include <sound/initval.h> | ||
63 | #include <sound/rawmidi.h> | ||
64 | #include <asm/io.h> | ||
65 | #include <asm/atomic.h> | ||
66 | #include "echoaudio.h" | ||
67 | |||
68 | #define FW_361_LOADER 0 | ||
69 | #define FW_MIA_DSP 1 | ||
70 | |||
71 | static const struct firmware card_fw[] = { | ||
72 | {0, "loader_dsp.fw"}, | ||
73 | {0, "mia_dsp.fw"} | ||
74 | }; | ||
75 | |||
76 | static struct pci_device_id snd_echo_ids[] = { | ||
77 | {0x1057, 0x3410, 0xECC0, 0x0080, 0, 0, 0}, /* DSP 56361 Mia rev.0 */ | ||
78 | {0x1057, 0x3410, 0xECC0, 0x0081, 0, 0, 0}, /* DSP 56361 Mia rev.1 */ | ||
79 | {0,} | ||
80 | }; | ||
81 | |||
82 | static struct snd_pcm_hardware pcm_hardware_skel = { | ||
83 | .info = SNDRV_PCM_INFO_MMAP | | ||
84 | SNDRV_PCM_INFO_INTERLEAVED | | ||
85 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
86 | SNDRV_PCM_INFO_MMAP_VALID | | ||
87 | SNDRV_PCM_INFO_PAUSE | | ||
88 | SNDRV_PCM_INFO_SYNC_START, | ||
89 | .formats = SNDRV_PCM_FMTBIT_U8 | | ||
90 | SNDRV_PCM_FMTBIT_S16_LE | | ||
91 | SNDRV_PCM_FMTBIT_S24_3LE | | ||
92 | SNDRV_PCM_FMTBIT_S32_LE | | ||
93 | SNDRV_PCM_FMTBIT_S32_BE, | ||
94 | .rates = SNDRV_PCM_RATE_32000 | | ||
95 | SNDRV_PCM_RATE_44100 | | ||
96 | SNDRV_PCM_RATE_48000 | | ||
97 | SNDRV_PCM_RATE_88200 | | ||
98 | SNDRV_PCM_RATE_96000, | ||
99 | .rate_min = 8000, | ||
100 | .rate_max = 96000, | ||
101 | .channels_min = 1, | ||
102 | .channels_max = 8, | ||
103 | .buffer_bytes_max = 262144, | ||
104 | .period_bytes_min = 32, | ||
105 | .period_bytes_max = 131072, | ||
106 | .periods_min = 2, | ||
107 | .periods_max = 220, | ||
108 | /* One page (4k) contains 512 instructions. I don't know if the hw | ||
109 | supports lists longer than this. In this case periods_max=220 is a | ||
110 | safe limit to make sure the list never exceeds 512 instructions. */ | ||
111 | }; | ||
112 | |||
113 | |||
114 | #include "mia_dsp.c" | ||
115 | #include "echoaudio_dsp.c" | ||
116 | #include "echoaudio.c" | ||
117 | #include "midi.c" | ||
diff --git a/sound/pci/echoaudio/mia_dsp.c b/sound/pci/echoaudio/mia_dsp.c new file mode 100644 index 000000000000..891c70519096 --- /dev/null +++ b/sound/pci/echoaudio/mia_dsp.c | |||
@@ -0,0 +1,229 @@ | |||
1 | /**************************************************************************** | ||
2 | |||
3 | Copyright Echo Digital Audio Corporation (c) 1998 - 2004 | ||
4 | All rights reserved | ||
5 | www.echoaudio.com | ||
6 | |||
7 | This file is part of Echo Digital Audio's generic driver library. | ||
8 | |||
9 | Echo Digital Audio's generic driver library is free software; | ||
10 | you can redistribute it and/or modify it under the terms of | ||
11 | the GNU General Public License as published by the Free Software | ||
12 | Foundation. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, | ||
22 | MA 02111-1307, USA. | ||
23 | |||
24 | ************************************************************************* | ||
25 | |||
26 | Translation from C++ and adaptation for use in ALSA-Driver | ||
27 | were made by Giuliano Pochini <pochini@shiny.it> | ||
28 | |||
29 | ****************************************************************************/ | ||
30 | |||
31 | |||
32 | static int set_input_clock(struct echoaudio *chip, u16 clock); | ||
33 | static int set_professional_spdif(struct echoaudio *chip, char prof); | ||
34 | static int update_flags(struct echoaudio *chip); | ||
35 | static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, | ||
36 | int gain); | ||
37 | static int update_vmixer_level(struct echoaudio *chip); | ||
38 | |||
39 | |||
40 | static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | ||
41 | { | ||
42 | int err; | ||
43 | |||
44 | DE_INIT(("init_hw() - Mia\n")); | ||
45 | snd_assert((subdevice_id & 0xfff0) == MIA, return -ENODEV); | ||
46 | |||
47 | if ((err = init_dsp_comm_page(chip))) { | ||
48 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | ||
49 | return err; | ||
50 | } | ||
51 | |||
52 | chip->device_id = device_id; | ||
53 | chip->subdevice_id = subdevice_id; | ||
54 | chip->bad_board = TRUE; | ||
55 | chip->dsp_code_to_load = &card_fw[FW_MIA_DSP]; | ||
56 | /* Since this card has no ASIC, mark it as loaded so everything | ||
57 | works OK */ | ||
58 | chip->asic_loaded = TRUE; | ||
59 | if ((subdevice_id & 0x0000f) == MIA_MIDI_REV) | ||
60 | chip->has_midi = TRUE; | ||
61 | chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL | | ||
62 | ECHO_CLOCK_BIT_SPDIF; | ||
63 | |||
64 | if ((err = load_firmware(chip)) < 0) | ||
65 | return err; | ||
66 | chip->bad_board = FALSE; | ||
67 | |||
68 | if ((err = init_line_levels(chip))) | ||
69 | return err; | ||
70 | |||
71 | /* Default routing of the virtual channels: vchannels 0-3 go to analog | ||
72 | outputs and vchannels 4-7 go to S/PDIF outputs */ | ||
73 | set_vmixer_gain(chip, 0, 0, 0); | ||
74 | set_vmixer_gain(chip, 1, 1, 0); | ||
75 | set_vmixer_gain(chip, 0, 2, 0); | ||
76 | set_vmixer_gain(chip, 1, 3, 0); | ||
77 | set_vmixer_gain(chip, 2, 4, 0); | ||
78 | set_vmixer_gain(chip, 3, 5, 0); | ||
79 | set_vmixer_gain(chip, 2, 6, 0); | ||
80 | set_vmixer_gain(chip, 3, 7, 0); | ||
81 | err = update_vmixer_level(chip); | ||
82 | |||
83 | DE_INIT(("init_hw done\n")); | ||
84 | return err; | ||
85 | } | ||
86 | |||
87 | |||
88 | |||
89 | static u32 detect_input_clocks(const struct echoaudio *chip) | ||
90 | { | ||
91 | u32 clocks_from_dsp, clock_bits; | ||
92 | |||
93 | /* Map the DSP clock detect bits to the generic driver clock | ||
94 | detect bits */ | ||
95 | clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); | ||
96 | |||
97 | clock_bits = ECHO_CLOCK_BIT_INTERNAL; | ||
98 | |||
99 | if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF) | ||
100 | clock_bits |= ECHO_CLOCK_BIT_SPDIF; | ||
101 | |||
102 | return clock_bits; | ||
103 | } | ||
104 | |||
105 | |||
106 | |||
107 | /* The Mia has no ASIC. Just do nothing */ | ||
108 | static int load_asic(struct echoaudio *chip) | ||
109 | { | ||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | |||
114 | |||
115 | static int set_sample_rate(struct echoaudio *chip, u32 rate) | ||
116 | { | ||
117 | u32 control_reg; | ||
118 | |||
119 | switch (rate) { | ||
120 | case 96000: | ||
121 | control_reg = MIA_96000; | ||
122 | break; | ||
123 | case 88200: | ||
124 | control_reg = MIA_88200; | ||
125 | break; | ||
126 | case 48000: | ||
127 | control_reg = MIA_48000; | ||
128 | break; | ||
129 | case 44100: | ||
130 | control_reg = MIA_44100; | ||
131 | break; | ||
132 | case 32000: | ||
133 | control_reg = MIA_32000; | ||
134 | break; | ||
135 | default: | ||
136 | DE_ACT(("set_sample_rate: %d invalid!\n", rate)); | ||
137 | return -EINVAL; | ||
138 | } | ||
139 | |||
140 | /* Override the clock setting if this Mia is set to S/PDIF clock */ | ||
141 | if (chip->input_clock == ECHO_CLOCK_SPDIF) | ||
142 | control_reg |= MIA_SPDIF; | ||
143 | |||
144 | /* Set the control register if it has changed */ | ||
145 | if (control_reg != le32_to_cpu(chip->comm_page->control_register)) { | ||
146 | if (wait_handshake(chip)) | ||
147 | return -EIO; | ||
148 | |||
149 | chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ | ||
150 | chip->comm_page->control_register = cpu_to_le32(control_reg); | ||
151 | chip->sample_rate = rate; | ||
152 | |||
153 | clear_handshake(chip); | ||
154 | return send_vector(chip, DSP_VC_UPDATE_CLOCKS); | ||
155 | } | ||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | |||
160 | |||
161 | static int set_input_clock(struct echoaudio *chip, u16 clock) | ||
162 | { | ||
163 | DE_ACT(("set_input_clock(%d)\n", clock)); | ||
164 | snd_assert(clock == ECHO_CLOCK_INTERNAL || clock == ECHO_CLOCK_SPDIF, | ||
165 | return -EINVAL); | ||
166 | |||
167 | chip->input_clock = clock; | ||
168 | return set_sample_rate(chip, chip->sample_rate); | ||
169 | } | ||
170 | |||
171 | |||
172 | |||
173 | /* This function routes the sound from a virtual channel to a real output */ | ||
174 | static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, | ||
175 | int gain) | ||
176 | { | ||
177 | int index; | ||
178 | |||
179 | snd_assert(pipe < num_pipes_out(chip) && | ||
180 | output < num_busses_out(chip), return -EINVAL); | ||
181 | |||
182 | if (wait_handshake(chip)) | ||
183 | return -EIO; | ||
184 | |||
185 | chip->vmixer_gain[output][pipe] = gain; | ||
186 | index = output * num_pipes_out(chip) + pipe; | ||
187 | chip->comm_page->vmixer[index] = gain; | ||
188 | |||
189 | DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain)); | ||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | |||
194 | |||
195 | /* Tell the DSP to read and update virtual mixer levels in comm page. */ | ||
196 | static int update_vmixer_level(struct echoaudio *chip) | ||
197 | { | ||
198 | if (wait_handshake(chip)) | ||
199 | return -EIO; | ||
200 | clear_handshake(chip); | ||
201 | return send_vector(chip, DSP_VC_SET_VMIXER_GAIN); | ||
202 | } | ||
203 | |||
204 | |||
205 | |||
206 | /* Tell the DSP to reread the flags from the comm page */ | ||
207 | static int update_flags(struct echoaudio *chip) | ||
208 | { | ||
209 | if (wait_handshake(chip)) | ||
210 | return -EIO; | ||
211 | clear_handshake(chip); | ||
212 | return send_vector(chip, DSP_VC_UPDATE_FLAGS); | ||
213 | } | ||
214 | |||
215 | |||
216 | |||
217 | static int set_professional_spdif(struct echoaudio *chip, char prof) | ||
218 | { | ||
219 | DE_ACT(("set_professional_spdif %d\n", prof)); | ||
220 | if (prof) | ||
221 | chip->comm_page->flags |= | ||
222 | __constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); | ||
223 | else | ||
224 | chip->comm_page->flags &= | ||
225 | ~__constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); | ||
226 | chip->professional_spdif = prof; | ||
227 | return update_flags(chip); | ||
228 | } | ||
229 | |||
diff --git a/sound/pci/echoaudio/midi.c b/sound/pci/echoaudio/midi.c new file mode 100644 index 000000000000..e31f0f11e3a8 --- /dev/null +++ b/sound/pci/echoaudio/midi.c | |||
@@ -0,0 +1,327 @@ | |||
1 | /**************************************************************************** | ||
2 | |||
3 | Copyright Echo Digital Audio Corporation (c) 1998 - 2004 | ||
4 | All rights reserved | ||
5 | www.echoaudio.com | ||
6 | |||
7 | This file is part of Echo Digital Audio's generic driver library. | ||
8 | |||
9 | Echo Digital Audio's generic driver library is free software; | ||
10 | you can redistribute it and/or modify it under the terms of | ||
11 | the GNU General Public License as published by the Free Software | ||
12 | Foundation. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, | ||
22 | MA 02111-1307, USA. | ||
23 | |||
24 | ************************************************************************* | ||
25 | |||
26 | Translation from C++ and adaptation for use in ALSA-Driver | ||
27 | were made by Giuliano Pochini <pochini@shiny.it> | ||
28 | |||
29 | ****************************************************************************/ | ||
30 | |||
31 | |||
32 | /****************************************************************************** | ||
33 | MIDI lowlevel code | ||
34 | ******************************************************************************/ | ||
35 | |||
36 | /* Start and stop Midi input */ | ||
37 | static int enable_midi_input(struct echoaudio *chip, char enable) | ||
38 | { | ||
39 | DE_MID(("enable_midi_input(%d)\n", enable)); | ||
40 | |||
41 | if (wait_handshake(chip)) | ||
42 | return -EIO; | ||
43 | |||
44 | if (enable) { | ||
45 | chip->mtc_state = MIDI_IN_STATE_NORMAL; | ||
46 | chip->comm_page->flags |= | ||
47 | __constant_cpu_to_le32(DSP_FLAG_MIDI_INPUT); | ||
48 | } else | ||
49 | chip->comm_page->flags &= | ||
50 | ~__constant_cpu_to_le32(DSP_FLAG_MIDI_INPUT); | ||
51 | |||
52 | clear_handshake(chip); | ||
53 | return send_vector(chip, DSP_VC_UPDATE_FLAGS); | ||
54 | } | ||
55 | |||
56 | |||
57 | |||
58 | /* Send a buffer full of MIDI data to the DSP | ||
59 | Returns how many actually written or < 0 on error */ | ||
60 | static int write_midi(struct echoaudio *chip, u8 *data, int bytes) | ||
61 | { | ||
62 | snd_assert(bytes > 0 && bytes < MIDI_OUT_BUFFER_SIZE, return -EINVAL); | ||
63 | |||
64 | if (wait_handshake(chip)) | ||
65 | return -EIO; | ||
66 | |||
67 | /* HF4 indicates that it is safe to write MIDI output data */ | ||
68 | if (! (get_dsp_register(chip, CHI32_STATUS_REG) & CHI32_STATUS_REG_HF4)) | ||
69 | return 0; | ||
70 | |||
71 | chip->comm_page->midi_output[0] = bytes; | ||
72 | memcpy(&chip->comm_page->midi_output[1], data, bytes); | ||
73 | chip->comm_page->midi_out_free_count = 0; | ||
74 | clear_handshake(chip); | ||
75 | send_vector(chip, DSP_VC_MIDI_WRITE); | ||
76 | DE_MID(("write_midi: %d\n", bytes)); | ||
77 | return bytes; | ||
78 | } | ||
79 | |||
80 | |||
81 | |||
82 | /* Run the state machine for MIDI input data | ||
83 | MIDI time code sync isn't supported by this code right now, but you still need | ||
84 | this state machine to parse the incoming MIDI data stream. Every time the DSP | ||
85 | sees a 0xF1 byte come in, it adds the DSP sample position to the MIDI data | ||
86 | stream. The DSP sample position is represented as a 32 bit unsigned value, | ||
87 | with the high 16 bits first, followed by the low 16 bits. Since these aren't | ||
88 | real MIDI bytes, the following logic is needed to skip them. */ | ||
89 | static inline int mtc_process_data(struct echoaudio *chip, short midi_byte) | ||
90 | { | ||
91 | switch (chip->mtc_state) { | ||
92 | case MIDI_IN_STATE_NORMAL: | ||
93 | if (midi_byte == 0xF1) | ||
94 | chip->mtc_state = MIDI_IN_STATE_TS_HIGH; | ||
95 | break; | ||
96 | case MIDI_IN_STATE_TS_HIGH: | ||
97 | chip->mtc_state = MIDI_IN_STATE_TS_LOW; | ||
98 | return MIDI_IN_SKIP_DATA; | ||
99 | break; | ||
100 | case MIDI_IN_STATE_TS_LOW: | ||
101 | chip->mtc_state = MIDI_IN_STATE_F1_DATA; | ||
102 | return MIDI_IN_SKIP_DATA; | ||
103 | break; | ||
104 | case MIDI_IN_STATE_F1_DATA: | ||
105 | chip->mtc_state = MIDI_IN_STATE_NORMAL; | ||
106 | break; | ||
107 | } | ||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | |||
112 | |||
113 | /* This function is called from the IRQ handler and it reads the midi data | ||
114 | from the DSP's buffer. It returns the number of bytes received. */ | ||
115 | static int midi_service_irq(struct echoaudio *chip) | ||
116 | { | ||
117 | short int count, midi_byte, i, received; | ||
118 | |||
119 | /* The count is at index 0, followed by actual data */ | ||
120 | count = le16_to_cpu(chip->comm_page->midi_input[0]); | ||
121 | |||
122 | snd_assert(count < MIDI_IN_BUFFER_SIZE, return 0); | ||
123 | |||
124 | /* Get the MIDI data from the comm page */ | ||
125 | i = 1; | ||
126 | received = 0; | ||
127 | for (i = 1; i <= count; i++) { | ||
128 | /* Get the MIDI byte */ | ||
129 | midi_byte = le16_to_cpu(chip->comm_page->midi_input[i]); | ||
130 | |||
131 | /* Parse the incoming MIDI stream. The incoming MIDI data | ||
132 | consists of MIDI bytes and timestamps for the MIDI time code | ||
133 | 0xF1 bytes. mtc_process_data() is a little state machine that | ||
134 | parses the stream. If you get MIDI_IN_SKIP_DATA back, then | ||
135 | this is a timestamp byte, not a MIDI byte, so don't store it | ||
136 | in the MIDI input buffer. */ | ||
137 | if (mtc_process_data(chip, midi_byte) == MIDI_IN_SKIP_DATA) | ||
138 | continue; | ||
139 | |||
140 | chip->midi_buffer[received++] = (u8)midi_byte; | ||
141 | } | ||
142 | |||
143 | return received; | ||
144 | } | ||
145 | |||
146 | |||
147 | |||
148 | |||
149 | /****************************************************************************** | ||
150 | MIDI interface | ||
151 | ******************************************************************************/ | ||
152 | |||
153 | static int snd_echo_midi_input_open(struct snd_rawmidi_substream *substream) | ||
154 | { | ||
155 | struct echoaudio *chip = substream->rmidi->private_data; | ||
156 | |||
157 | chip->midi_in = substream; | ||
158 | DE_MID(("rawmidi_iopen\n")); | ||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | |||
163 | |||
164 | static void snd_echo_midi_input_trigger(struct snd_rawmidi_substream *substream, | ||
165 | int up) | ||
166 | { | ||
167 | struct echoaudio *chip = substream->rmidi->private_data; | ||
168 | |||
169 | if (up != chip->midi_input_enabled) { | ||
170 | spin_lock_irq(&chip->lock); | ||
171 | enable_midi_input(chip, up); | ||
172 | spin_unlock_irq(&chip->lock); | ||
173 | chip->midi_input_enabled = up; | ||
174 | } | ||
175 | } | ||
176 | |||
177 | |||
178 | |||
179 | static int snd_echo_midi_input_close(struct snd_rawmidi_substream *substream) | ||
180 | { | ||
181 | struct echoaudio *chip = substream->rmidi->private_data; | ||
182 | |||
183 | chip->midi_in = NULL; | ||
184 | DE_MID(("rawmidi_iclose\n")); | ||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | |||
189 | |||
190 | static int snd_echo_midi_output_open(struct snd_rawmidi_substream *substream) | ||
191 | { | ||
192 | struct echoaudio *chip = substream->rmidi->private_data; | ||
193 | |||
194 | chip->tinuse = 0; | ||
195 | chip->midi_full = 0; | ||
196 | chip->midi_out = substream; | ||
197 | DE_MID(("rawmidi_oopen\n")); | ||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | |||
202 | |||
203 | static void snd_echo_midi_output_write(unsigned long data) | ||
204 | { | ||
205 | struct echoaudio *chip = (struct echoaudio *)data; | ||
206 | unsigned long flags; | ||
207 | int bytes, sent, time; | ||
208 | unsigned char buf[MIDI_OUT_BUFFER_SIZE - 1]; | ||
209 | |||
210 | DE_MID(("snd_echo_midi_output_write\n")); | ||
211 | /* No interrupts are involved: we have to check at regular intervals | ||
212 | if the card's output buffer has room for new data. */ | ||
213 | sent = bytes = 0; | ||
214 | spin_lock_irqsave(&chip->lock, flags); | ||
215 | chip->midi_full = 0; | ||
216 | if (chip->midi_out && !snd_rawmidi_transmit_empty(chip->midi_out)) { | ||
217 | bytes = snd_rawmidi_transmit_peek(chip->midi_out, buf, | ||
218 | MIDI_OUT_BUFFER_SIZE - 1); | ||
219 | DE_MID(("Try to send %d bytes...\n", bytes)); | ||
220 | sent = write_midi(chip, buf, bytes); | ||
221 | if (sent < 0) { | ||
222 | snd_printk(KERN_ERR "write_midi() error %d\n", sent); | ||
223 | /* retry later */ | ||
224 | sent = 9000; | ||
225 | chip->midi_full = 1; | ||
226 | } else if (sent > 0) { | ||
227 | DE_MID(("%d bytes sent\n", sent)); | ||
228 | snd_rawmidi_transmit_ack(chip->midi_out, sent); | ||
229 | } else { | ||
230 | /* Buffer is full. DSP's internal buffer is 64 (128 ?) | ||
231 | bytes long. Let's wait until half of them are sent */ | ||
232 | DE_MID(("Full\n")); | ||
233 | sent = 32; | ||
234 | chip->midi_full = 1; | ||
235 | } | ||
236 | } | ||
237 | |||
238 | /* We restart the timer only if there is some data left to send */ | ||
239 | if (!snd_rawmidi_transmit_empty(chip->midi_out) && chip->tinuse) { | ||
240 | /* The timer will expire slightly after the data has been | ||
241 | sent */ | ||
242 | time = (sent << 3) / 25 + 1; /* 8/25=0.32ms to send a byte */ | ||
243 | mod_timer(&chip->timer, jiffies + (time * HZ + 999) / 1000); | ||
244 | DE_MID(("Timer armed(%d)\n", ((time * HZ + 999) / 1000))); | ||
245 | } | ||
246 | spin_unlock_irqrestore(&chip->lock, flags); | ||
247 | } | ||
248 | |||
249 | |||
250 | |||
251 | static void snd_echo_midi_output_trigger(struct snd_rawmidi_substream *substream, | ||
252 | int up) | ||
253 | { | ||
254 | struct echoaudio *chip = substream->rmidi->private_data; | ||
255 | |||
256 | DE_MID(("snd_echo_midi_output_trigger(%d)\n", up)); | ||
257 | spin_lock_irq(&chip->lock); | ||
258 | if (up) { | ||
259 | if (!chip->tinuse) { | ||
260 | init_timer(&chip->timer); | ||
261 | chip->timer.function = snd_echo_midi_output_write; | ||
262 | chip->timer.data = (unsigned long)chip; | ||
263 | chip->tinuse = 1; | ||
264 | } | ||
265 | } else { | ||
266 | if (chip->tinuse) { | ||
267 | del_timer(&chip->timer); | ||
268 | chip->tinuse = 0; | ||
269 | DE_MID(("Timer removed\n")); | ||
270 | } | ||
271 | } | ||
272 | spin_unlock_irq(&chip->lock); | ||
273 | |||
274 | if (up && !chip->midi_full) | ||
275 | snd_echo_midi_output_write((unsigned long)chip); | ||
276 | } | ||
277 | |||
278 | |||
279 | |||
280 | static int snd_echo_midi_output_close(struct snd_rawmidi_substream *substream) | ||
281 | { | ||
282 | struct echoaudio *chip = substream->rmidi->private_data; | ||
283 | |||
284 | chip->midi_out = NULL; | ||
285 | DE_MID(("rawmidi_oclose\n")); | ||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | |||
290 | |||
291 | static struct snd_rawmidi_ops snd_echo_midi_input = { | ||
292 | .open = snd_echo_midi_input_open, | ||
293 | .close = snd_echo_midi_input_close, | ||
294 | .trigger = snd_echo_midi_input_trigger, | ||
295 | }; | ||
296 | |||
297 | static struct snd_rawmidi_ops snd_echo_midi_output = { | ||
298 | .open = snd_echo_midi_output_open, | ||
299 | .close = snd_echo_midi_output_close, | ||
300 | .trigger = snd_echo_midi_output_trigger, | ||
301 | }; | ||
302 | |||
303 | |||
304 | |||
305 | /* <--snd_echo_probe() */ | ||
306 | static int __devinit snd_echo_midi_create(struct snd_card *card, | ||
307 | struct echoaudio *chip) | ||
308 | { | ||
309 | int err; | ||
310 | |||
311 | if ((err = snd_rawmidi_new(card, card->shortname, 0, 1, 1, | ||
312 | &chip->rmidi)) < 0) | ||
313 | return err; | ||
314 | |||
315 | strcpy(chip->rmidi->name, card->shortname); | ||
316 | chip->rmidi->private_data = chip; | ||
317 | |||
318 | snd_rawmidi_set_ops(chip->rmidi, SNDRV_RAWMIDI_STREAM_INPUT, | ||
319 | &snd_echo_midi_input); | ||
320 | snd_rawmidi_set_ops(chip->rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, | ||
321 | &snd_echo_midi_output); | ||
322 | |||
323 | chip->rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | | ||
324 | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX; | ||
325 | DE_INIT(("MIDI ok\n")); | ||
326 | return 0; | ||
327 | } | ||
diff --git a/sound/pci/echoaudio/mona.c b/sound/pci/echoaudio/mona.c new file mode 100644 index 000000000000..5dc512add372 --- /dev/null +++ b/sound/pci/echoaudio/mona.c | |||
@@ -0,0 +1,129 @@ | |||
1 | /* | ||
2 | * ALSA driver for Echoaudio soundcards. | ||
3 | * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #define ECHO24_FAMILY | ||
20 | #define ECHOCARD_MONA | ||
21 | #define ECHOCARD_NAME "Mona" | ||
22 | #define ECHOCARD_HAS_MONITOR | ||
23 | #define ECHOCARD_HAS_ASIC | ||
24 | #define ECHOCARD_HAS_SUPER_INTERLEAVE | ||
25 | #define ECHOCARD_HAS_DIGITAL_IO | ||
26 | #define ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE | ||
27 | #define ECHOCARD_HAS_DIGITAL_MODE_SWITCH | ||
28 | #define ECHOCARD_HAS_EXTERNAL_CLOCK | ||
29 | #define ECHOCARD_HAS_ADAT 6 | ||
30 | #define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 | ||
31 | |||
32 | /* Pipe indexes */ | ||
33 | #define PX_ANALOG_OUT 0 /* 6 */ | ||
34 | #define PX_DIGITAL_OUT 6 /* 8 */ | ||
35 | #define PX_ANALOG_IN 14 /* 4 */ | ||
36 | #define PX_DIGITAL_IN 18 /* 8 */ | ||
37 | #define PX_NUM 26 | ||
38 | |||
39 | /* Bus indexes */ | ||
40 | #define BX_ANALOG_OUT 0 /* 6 */ | ||
41 | #define BX_DIGITAL_OUT 6 /* 8 */ | ||
42 | #define BX_ANALOG_IN 14 /* 4 */ | ||
43 | #define BX_DIGITAL_IN 18 /* 8 */ | ||
44 | #define BX_NUM 26 | ||
45 | |||
46 | |||
47 | #include <sound/driver.h> | ||
48 | #include <linux/delay.h> | ||
49 | #include <linux/init.h> | ||
50 | #include <linux/interrupt.h> | ||
51 | #include <linux/pci.h> | ||
52 | #include <linux/slab.h> | ||
53 | #include <linux/moduleparam.h> | ||
54 | #include <linux/firmware.h> | ||
55 | #include <sound/core.h> | ||
56 | #include <sound/info.h> | ||
57 | #include <sound/control.h> | ||
58 | #include <sound/pcm.h> | ||
59 | #include <sound/pcm_params.h> | ||
60 | #include <sound/asoundef.h> | ||
61 | #include <sound/initval.h> | ||
62 | #include <asm/io.h> | ||
63 | #include <asm/atomic.h> | ||
64 | #include "echoaudio.h" | ||
65 | |||
66 | #define FW_361_LOADER 0 | ||
67 | #define FW_MONA_301_DSP 1 | ||
68 | #define FW_MONA_361_DSP 2 | ||
69 | #define FW_MONA_301_1_ASIC48 3 | ||
70 | #define FW_MONA_301_1_ASIC96 4 | ||
71 | #define FW_MONA_361_1_ASIC48 5 | ||
72 | #define FW_MONA_361_1_ASIC96 6 | ||
73 | #define FW_MONA_2_ASIC 7 | ||
74 | |||
75 | static const struct firmware card_fw[] = { | ||
76 | {0, "loader_dsp.fw"}, | ||
77 | {0, "mona_301_dsp.fw"}, | ||
78 | {0, "mona_361_dsp.fw"}, | ||
79 | {0, "mona_301_1_asic_48.fw"}, | ||
80 | {0, "mona_301_1_asic_96.fw"}, | ||
81 | {0, "mona_361_1_asic_48.fw"}, | ||
82 | {0, "mona_361_1_asic_96.fw"}, | ||
83 | {0, "mona_2_asic.fw"} | ||
84 | }; | ||
85 | |||
86 | static struct pci_device_id snd_echo_ids[] = { | ||
87 | {0x1057, 0x1801, 0xECC0, 0x0070, 0, 0, 0}, /* DSP 56301 Mona rev.0 */ | ||
88 | {0x1057, 0x1801, 0xECC0, 0x0071, 0, 0, 0}, /* DSP 56301 Mona rev.1 */ | ||
89 | {0x1057, 0x1801, 0xECC0, 0x0072, 0, 0, 0}, /* DSP 56301 Mona rev.2 */ | ||
90 | {0x1057, 0x3410, 0xECC0, 0x0070, 0, 0, 0}, /* DSP 56361 Mona rev.0 */ | ||
91 | {0x1057, 0x3410, 0xECC0, 0x0071, 0, 0, 0}, /* DSP 56361 Mona rev.1 */ | ||
92 | {0x1057, 0x3410, 0xECC0, 0x0072, 0, 0, 0}, /* DSP 56361 Mona rev.2 */ | ||
93 | {0,} | ||
94 | }; | ||
95 | |||
96 | static struct snd_pcm_hardware pcm_hardware_skel = { | ||
97 | .info = SNDRV_PCM_INFO_MMAP | | ||
98 | SNDRV_PCM_INFO_INTERLEAVED | | ||
99 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
100 | SNDRV_PCM_INFO_MMAP_VALID | | ||
101 | SNDRV_PCM_INFO_PAUSE | | ||
102 | SNDRV_PCM_INFO_SYNC_START, | ||
103 | .formats = SNDRV_PCM_FMTBIT_U8 | | ||
104 | SNDRV_PCM_FMTBIT_S16_LE | | ||
105 | SNDRV_PCM_FMTBIT_S24_3LE | | ||
106 | SNDRV_PCM_FMTBIT_S32_LE | | ||
107 | SNDRV_PCM_FMTBIT_S32_BE, | ||
108 | .rates = SNDRV_PCM_RATE_8000_48000 | | ||
109 | SNDRV_PCM_RATE_88200 | | ||
110 | SNDRV_PCM_RATE_96000, | ||
111 | .rate_min = 8000, | ||
112 | .rate_max = 96000, | ||
113 | .channels_min = 1, | ||
114 | .channels_max = 8, | ||
115 | .buffer_bytes_max = 262144, | ||
116 | .period_bytes_min = 32, | ||
117 | .period_bytes_max = 131072, | ||
118 | .periods_min = 2, | ||
119 | .periods_max = 220, | ||
120 | /* One page (4k) contains 512 instructions. I don't know if the hw | ||
121 | supports lists longer than this. In this case periods_max=220 is a | ||
122 | safe limit to make sure the list never exceeds 512 instructions. */ | ||
123 | }; | ||
124 | |||
125 | |||
126 | #include "mona_dsp.c" | ||
127 | #include "echoaudio_dsp.c" | ||
128 | #include "echoaudio_gml.c" | ||
129 | #include "echoaudio.c" | ||
diff --git a/sound/pci/echoaudio/mona_dsp.c b/sound/pci/echoaudio/mona_dsp.c new file mode 100644 index 000000000000..c0b4bf0be7d1 --- /dev/null +++ b/sound/pci/echoaudio/mona_dsp.c | |||
@@ -0,0 +1,428 @@ | |||
1 | /**************************************************************************** | ||
2 | |||
3 | Copyright Echo Digital Audio Corporation (c) 1998 - 2004 | ||
4 | All rights reserved | ||
5 | www.echoaudio.com | ||
6 | |||
7 | This file is part of Echo Digital Audio's generic driver library. | ||
8 | |||
9 | Echo Digital Audio's generic driver library is free software; | ||
10 | you can redistribute it and/or modify it under the terms of | ||
11 | the GNU General Public License as published by the Free Software | ||
12 | Foundation. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, | ||
22 | MA 02111-1307, USA. | ||
23 | |||
24 | ************************************************************************* | ||
25 | |||
26 | Translation from C++ and adaptation for use in ALSA-Driver | ||
27 | were made by Giuliano Pochini <pochini@shiny.it> | ||
28 | |||
29 | ****************************************************************************/ | ||
30 | |||
31 | |||
32 | static int write_control_reg(struct echoaudio *chip, u32 value, char force); | ||
33 | static int set_input_clock(struct echoaudio *chip, u16 clock); | ||
34 | static int set_professional_spdif(struct echoaudio *chip, char prof); | ||
35 | static int set_digital_mode(struct echoaudio *chip, u8 mode); | ||
36 | static int load_asic_generic(struct echoaudio *chip, u32 cmd, | ||
37 | const struct firmware *asic); | ||
38 | static int check_asic_status(struct echoaudio *chip); | ||
39 | |||
40 | |||
41 | static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | ||
42 | { | ||
43 | int err; | ||
44 | |||
45 | DE_INIT(("init_hw() - Mona\n")); | ||
46 | snd_assert((subdevice_id & 0xfff0) == MONA, return -ENODEV); | ||
47 | |||
48 | if ((err = init_dsp_comm_page(chip))) { | ||
49 | DE_INIT(("init_hw - could not initialize DSP comm page\n")); | ||
50 | return err; | ||
51 | } | ||
52 | |||
53 | chip->device_id = device_id; | ||
54 | chip->subdevice_id = subdevice_id; | ||
55 | chip->bad_board = TRUE; | ||
56 | chip->input_clock_types = | ||
57 | ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF | | ||
58 | ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_ADAT; | ||
59 | chip->digital_modes = | ||
60 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | | ||
61 | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | | ||
62 | ECHOCAPS_HAS_DIGITAL_MODE_ADAT; | ||
63 | |||
64 | /* Mona comes in both '301 and '361 flavors */ | ||
65 | if (chip->device_id == DEVICE_ID_56361) | ||
66 | chip->dsp_code_to_load = &card_fw[FW_MONA_361_DSP]; | ||
67 | else | ||
68 | chip->dsp_code_to_load = &card_fw[FW_MONA_301_DSP]; | ||
69 | |||
70 | chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; | ||
71 | chip->professional_spdif = FALSE; | ||
72 | chip->digital_in_automute = TRUE; | ||
73 | |||
74 | if ((err = load_firmware(chip)) < 0) | ||
75 | return err; | ||
76 | chip->bad_board = FALSE; | ||
77 | |||
78 | if ((err = init_line_levels(chip)) < 0) | ||
79 | return err; | ||
80 | |||
81 | err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA); | ||
82 | snd_assert(err >= 0, return err); | ||
83 | err = set_professional_spdif(chip, TRUE); | ||
84 | |||
85 | DE_INIT(("init_hw done\n")); | ||
86 | return err; | ||
87 | } | ||
88 | |||
89 | |||
90 | |||
91 | static u32 detect_input_clocks(const struct echoaudio *chip) | ||
92 | { | ||
93 | u32 clocks_from_dsp, clock_bits; | ||
94 | |||
95 | /* Map the DSP clock detect bits to the generic driver clock | ||
96 | detect bits */ | ||
97 | clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); | ||
98 | |||
99 | clock_bits = ECHO_CLOCK_BIT_INTERNAL; | ||
100 | |||
101 | if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF) | ||
102 | clock_bits |= ECHO_CLOCK_BIT_SPDIF; | ||
103 | |||
104 | if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ADAT) | ||
105 | clock_bits |= ECHO_CLOCK_BIT_ADAT; | ||
106 | |||
107 | if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD) | ||
108 | clock_bits |= ECHO_CLOCK_BIT_WORD; | ||
109 | |||
110 | return clock_bits; | ||
111 | } | ||
112 | |||
113 | |||
114 | |||
115 | /* Mona has an ASIC on the PCI card and another ASIC in the external box; | ||
116 | both need to be loaded. */ | ||
117 | static int load_asic(struct echoaudio *chip) | ||
118 | { | ||
119 | u32 control_reg; | ||
120 | int err; | ||
121 | const struct firmware *asic; | ||
122 | |||
123 | if (chip->asic_loaded) | ||
124 | return 0; | ||
125 | |||
126 | mdelay(10); | ||
127 | |||
128 | if (chip->device_id == DEVICE_ID_56361) | ||
129 | asic = &card_fw[FW_MONA_361_1_ASIC48]; | ||
130 | else | ||
131 | asic = &card_fw[FW_MONA_301_1_ASIC48]; | ||
132 | |||
133 | err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC, asic); | ||
134 | if (err < 0) | ||
135 | return err; | ||
136 | |||
137 | chip->asic_code = asic; | ||
138 | mdelay(10); | ||
139 | |||
140 | /* Do the external one */ | ||
141 | err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_EXTERNAL_ASIC, | ||
142 | &card_fw[FW_MONA_2_ASIC]); | ||
143 | if (err < 0) | ||
144 | return err; | ||
145 | |||
146 | mdelay(10); | ||
147 | err = check_asic_status(chip); | ||
148 | |||
149 | /* Set up the control register if the load succeeded - | ||
150 | 48 kHz, internal clock, S/PDIF RCA mode */ | ||
151 | if (!err) { | ||
152 | control_reg = GML_CONVERTER_ENABLE | GML_48KHZ; | ||
153 | err = write_control_reg(chip, control_reg, TRUE); | ||
154 | } | ||
155 | |||
156 | return err; | ||
157 | } | ||
158 | |||
159 | |||
160 | |||
161 | /* Depending on what digital mode you want, Mona needs different ASICs | ||
162 | loaded. This function checks the ASIC needed for the new mode and sees | ||
163 | if it matches the one already loaded. */ | ||
164 | static int switch_asic(struct echoaudio *chip, char double_speed) | ||
165 | { | ||
166 | const struct firmware *asic; | ||
167 | int err; | ||
168 | |||
169 | /* Check the clock detect bits to see if this is | ||
170 | a single-speed clock or a double-speed clock; load | ||
171 | a new ASIC if necessary. */ | ||
172 | if (chip->device_id == DEVICE_ID_56361) { | ||
173 | if (double_speed) | ||
174 | asic = &card_fw[FW_MONA_361_1_ASIC96]; | ||
175 | else | ||
176 | asic = &card_fw[FW_MONA_361_1_ASIC48]; | ||
177 | } else { | ||
178 | if (double_speed) | ||
179 | asic = &card_fw[FW_MONA_301_1_ASIC96]; | ||
180 | else | ||
181 | asic = &card_fw[FW_MONA_301_1_ASIC48]; | ||
182 | } | ||
183 | |||
184 | if (asic != chip->asic_code) { | ||
185 | /* Load the desired ASIC */ | ||
186 | err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC, | ||
187 | asic); | ||
188 | if (err < 0) | ||
189 | return err; | ||
190 | chip->asic_code = asic; | ||
191 | } | ||
192 | |||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | |||
197 | |||
198 | static int set_sample_rate(struct echoaudio *chip, u32 rate) | ||
199 | { | ||
200 | u32 control_reg, clock; | ||
201 | const struct firmware *asic; | ||
202 | char force_write; | ||
203 | |||
204 | /* Only set the clock for internal mode. */ | ||
205 | if (chip->input_clock != ECHO_CLOCK_INTERNAL) { | ||
206 | DE_ACT(("set_sample_rate: Cannot set sample rate - " | ||
207 | "clock not set to CLK_CLOCKININTERNAL\n")); | ||
208 | /* Save the rate anyhow */ | ||
209 | chip->comm_page->sample_rate = cpu_to_le32(rate); | ||
210 | chip->sample_rate = rate; | ||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | /* Now, check to see if the required ASIC is loaded */ | ||
215 | if (rate >= 88200) { | ||
216 | if (chip->digital_mode == DIGITAL_MODE_ADAT) | ||
217 | return -EINVAL; | ||
218 | if (chip->device_id == DEVICE_ID_56361) | ||
219 | asic = &card_fw[FW_MONA_361_1_ASIC96]; | ||
220 | else | ||
221 | asic = &card_fw[FW_MONA_301_1_ASIC96]; | ||
222 | } else { | ||
223 | if (chip->device_id == DEVICE_ID_56361) | ||
224 | asic = &card_fw[FW_MONA_361_1_ASIC48]; | ||
225 | else | ||
226 | asic = &card_fw[FW_MONA_301_1_ASIC48]; | ||
227 | } | ||
228 | |||
229 | force_write = 0; | ||
230 | if (asic != chip->asic_code) { | ||
231 | int err; | ||
232 | /* Load the desired ASIC (load_asic_generic() can sleep) */ | ||
233 | spin_unlock_irq(&chip->lock); | ||
234 | err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC, | ||
235 | asic); | ||
236 | spin_lock_irq(&chip->lock); | ||
237 | |||
238 | if (err < 0) | ||
239 | return err; | ||
240 | chip->asic_code = asic; | ||
241 | force_write = 1; | ||
242 | } | ||
243 | |||
244 | /* Compute the new control register value */ | ||
245 | clock = 0; | ||
246 | control_reg = le32_to_cpu(chip->comm_page->control_register); | ||
247 | control_reg &= GML_CLOCK_CLEAR_MASK; | ||
248 | control_reg &= GML_SPDIF_RATE_CLEAR_MASK; | ||
249 | |||
250 | switch (rate) { | ||
251 | case 96000: | ||
252 | clock = GML_96KHZ; | ||
253 | break; | ||
254 | case 88200: | ||
255 | clock = GML_88KHZ; | ||
256 | break; | ||
257 | case 48000: | ||
258 | clock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1; | ||
259 | break; | ||
260 | case 44100: | ||
261 | clock = GML_44KHZ; | ||
262 | /* Professional mode */ | ||
263 | if (control_reg & GML_SPDIF_PRO_MODE) | ||
264 | clock |= GML_SPDIF_SAMPLE_RATE0; | ||
265 | break; | ||
266 | case 32000: | ||
267 | clock = GML_32KHZ | GML_SPDIF_SAMPLE_RATE0 | | ||
268 | GML_SPDIF_SAMPLE_RATE1; | ||
269 | break; | ||
270 | case 22050: | ||
271 | clock = GML_22KHZ; | ||
272 | break; | ||
273 | case 16000: | ||
274 | clock = GML_16KHZ; | ||
275 | break; | ||
276 | case 11025: | ||
277 | clock = GML_11KHZ; | ||
278 | break; | ||
279 | case 8000: | ||
280 | clock = GML_8KHZ; | ||
281 | break; | ||
282 | default: | ||
283 | DE_ACT(("set_sample_rate: %d invalid!\n", rate)); | ||
284 | return -EINVAL; | ||
285 | } | ||
286 | |||
287 | control_reg |= clock; | ||
288 | |||
289 | chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ | ||
290 | chip->sample_rate = rate; | ||
291 | DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock)); | ||
292 | |||
293 | return write_control_reg(chip, control_reg, force_write); | ||
294 | } | ||
295 | |||
296 | |||
297 | |||
298 | static int set_input_clock(struct echoaudio *chip, u16 clock) | ||
299 | { | ||
300 | u32 control_reg, clocks_from_dsp; | ||
301 | int err; | ||
302 | |||
303 | DE_ACT(("set_input_clock:\n")); | ||
304 | |||
305 | /* Prevent two simultaneous calls to switch_asic() */ | ||
306 | if (atomic_read(&chip->opencount)) | ||
307 | return -EAGAIN; | ||
308 | |||
309 | /* Mask off the clock select bits */ | ||
310 | control_reg = le32_to_cpu(chip->comm_page->control_register) & | ||
311 | GML_CLOCK_CLEAR_MASK; | ||
312 | clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); | ||
313 | |||
314 | switch (clock) { | ||
315 | case ECHO_CLOCK_INTERNAL: | ||
316 | DE_ACT(("Set Mona clock to INTERNAL\n")); | ||
317 | chip->input_clock = ECHO_CLOCK_INTERNAL; | ||
318 | return set_sample_rate(chip, chip->sample_rate); | ||
319 | case ECHO_CLOCK_SPDIF: | ||
320 | if (chip->digital_mode == DIGITAL_MODE_ADAT) | ||
321 | return -EAGAIN; | ||
322 | spin_unlock_irq(&chip->lock); | ||
323 | err = switch_asic(chip, clocks_from_dsp & | ||
324 | GML_CLOCK_DETECT_BIT_SPDIF96); | ||
325 | spin_lock_irq(&chip->lock); | ||
326 | if (err < 0) | ||
327 | return err; | ||
328 | DE_ACT(("Set Mona clock to SPDIF\n")); | ||
329 | control_reg |= GML_SPDIF_CLOCK; | ||
330 | if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF96) | ||
331 | control_reg |= GML_DOUBLE_SPEED_MODE; | ||
332 | else | ||
333 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | ||
334 | break; | ||
335 | case ECHO_CLOCK_WORD: | ||
336 | DE_ACT(("Set Mona clock to WORD\n")); | ||
337 | spin_unlock_irq(&chip->lock); | ||
338 | err = switch_asic(chip, clocks_from_dsp & | ||
339 | GML_CLOCK_DETECT_BIT_WORD96); | ||
340 | spin_lock_irq(&chip->lock); | ||
341 | if (err < 0) | ||
342 | return err; | ||
343 | control_reg |= GML_WORD_CLOCK; | ||
344 | if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD96) | ||
345 | control_reg |= GML_DOUBLE_SPEED_MODE; | ||
346 | else | ||
347 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | ||
348 | break; | ||
349 | case ECHO_CLOCK_ADAT: | ||
350 | DE_ACT(("Set Mona clock to ADAT\n")); | ||
351 | if (chip->digital_mode != DIGITAL_MODE_ADAT) | ||
352 | return -EAGAIN; | ||
353 | control_reg |= GML_ADAT_CLOCK; | ||
354 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | ||
355 | break; | ||
356 | default: | ||
357 | DE_ACT(("Input clock 0x%x not supported for Mona\n", clock)); | ||
358 | return -EINVAL; | ||
359 | } | ||
360 | |||
361 | chip->input_clock = clock; | ||
362 | return write_control_reg(chip, control_reg, TRUE); | ||
363 | } | ||
364 | |||
365 | |||
366 | |||
367 | static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) | ||
368 | { | ||
369 | u32 control_reg; | ||
370 | int err, incompatible_clock; | ||
371 | |||
372 | /* Set clock to "internal" if it's not compatible with the new mode */ | ||
373 | incompatible_clock = FALSE; | ||
374 | switch (mode) { | ||
375 | case DIGITAL_MODE_SPDIF_OPTICAL: | ||
376 | case DIGITAL_MODE_SPDIF_RCA: | ||
377 | if (chip->input_clock == ECHO_CLOCK_ADAT) | ||
378 | incompatible_clock = TRUE; | ||
379 | break; | ||
380 | case DIGITAL_MODE_ADAT: | ||
381 | if (chip->input_clock == ECHO_CLOCK_SPDIF) | ||
382 | incompatible_clock = TRUE; | ||
383 | break; | ||
384 | default: | ||
385 | DE_ACT(("Digital mode not supported: %d\n", mode)); | ||
386 | return -EINVAL; | ||
387 | } | ||
388 | |||
389 | spin_lock_irq(&chip->lock); | ||
390 | |||
391 | if (incompatible_clock) { /* Switch to 48KHz, internal */ | ||
392 | chip->sample_rate = 48000; | ||
393 | set_input_clock(chip, ECHO_CLOCK_INTERNAL); | ||
394 | } | ||
395 | |||
396 | /* Clear the current digital mode */ | ||
397 | control_reg = le32_to_cpu(chip->comm_page->control_register); | ||
398 | control_reg &= GML_DIGITAL_MODE_CLEAR_MASK; | ||
399 | |||
400 | /* Tweak the control reg */ | ||
401 | switch (mode) { | ||
402 | case DIGITAL_MODE_SPDIF_OPTICAL: | ||
403 | control_reg |= GML_SPDIF_OPTICAL_MODE; | ||
404 | break; | ||
405 | case DIGITAL_MODE_SPDIF_RCA: | ||
406 | /* GML_SPDIF_OPTICAL_MODE bit cleared */ | ||
407 | break; | ||
408 | case DIGITAL_MODE_ADAT: | ||
409 | /* If the current ASIC is the 96KHz ASIC, switch the ASIC | ||
410 | and set to 48 KHz */ | ||
411 | if (chip->asic_code == &card_fw[FW_MONA_361_1_ASIC96] || | ||
412 | chip->asic_code == &card_fw[FW_MONA_301_1_ASIC96]) { | ||
413 | set_sample_rate(chip, 48000); | ||
414 | } | ||
415 | control_reg |= GML_ADAT_MODE; | ||
416 | control_reg &= ~GML_DOUBLE_SPEED_MODE; | ||
417 | break; | ||
418 | } | ||
419 | |||
420 | err = write_control_reg(chip, control_reg, FALSE); | ||
421 | spin_unlock_irq(&chip->lock); | ||
422 | if (err < 0) | ||
423 | return err; | ||
424 | chip->digital_mode = mode; | ||
425 | |||
426 | DE_ACT(("set_digital_mode to %d\n", mode)); | ||
427 | return incompatible_clock; | ||
428 | } | ||
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 8c2a8174ece1..23201f3eeb12 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -408,7 +408,9 @@ static const struct hda_codec_preset *find_codec_preset(struct hda_codec *codec) | |||
408 | u32 mask = preset->mask; | 408 | u32 mask = preset->mask; |
409 | if (! mask) | 409 | if (! mask) |
410 | mask = ~0; | 410 | mask = ~0; |
411 | if (preset->id == (codec->vendor_id & mask)) | 411 | if (preset->id == (codec->vendor_id & mask) && |
412 | (! preset->rev || | ||
413 | preset->rev == codec->revision_id)) | ||
412 | return preset; | 414 | return preset; |
413 | } | 415 | } |
414 | } | 416 | } |
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index dd4e00a82b55..33b7d5806469 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -799,6 +799,8 @@ static struct hda_board_config ad1986a_cfg_tbl[] = { | |||
799 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x818f, | 799 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x818f, |
800 | .config = AD1986A_LAPTOP }, /* ASUS P5GV-MX */ | 800 | .config = AD1986A_LAPTOP }, /* ASUS P5GV-MX */ |
801 | { .modelname = "laptop-eapd", .config = AD1986A_LAPTOP_EAPD }, | 801 | { .modelname = "laptop-eapd", .config = AD1986A_LAPTOP_EAPD }, |
802 | { .pci_subvendor = 0x144d, .pci_subdevice = 0xc023, | ||
803 | .config = AD1986A_LAPTOP_EAPD }, /* Samsung X60 Chane */ | ||
802 | { .pci_subvendor = 0x144d, .pci_subdevice = 0xc024, | 804 | { .pci_subvendor = 0x144d, .pci_subdevice = 0xc024, |
803 | .config = AD1986A_LAPTOP_EAPD }, /* Samsung R65-T2300 Charis */ | 805 | .config = AD1986A_LAPTOP_EAPD }, /* Samsung R65-T2300 Charis */ |
804 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x1153, | 806 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x1153, |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 98b9f16c26ff..18d105263fea 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -78,6 +78,7 @@ enum { | |||
78 | enum { | 78 | enum { |
79 | ALC262_BASIC, | 79 | ALC262_BASIC, |
80 | ALC262_FUJITSU, | 80 | ALC262_FUJITSU, |
81 | ALC262_HP_BPC, | ||
81 | ALC262_AUTO, | 82 | ALC262_AUTO, |
82 | ALC262_MODEL_LAST /* last tag */ | 83 | ALC262_MODEL_LAST /* last tag */ |
83 | }; | 84 | }; |
@@ -85,6 +86,7 @@ enum { | |||
85 | /* ALC861 models */ | 86 | /* ALC861 models */ |
86 | enum { | 87 | enum { |
87 | ALC861_3ST, | 88 | ALC861_3ST, |
89 | ALC660_3ST, | ||
88 | ALC861_3ST_DIG, | 90 | ALC861_3ST_DIG, |
89 | ALC861_6ST_DIG, | 91 | ALC861_6ST_DIG, |
90 | ALC861_AUTO, | 92 | ALC861_AUTO, |
@@ -99,6 +101,17 @@ enum { | |||
99 | ALC882_MODEL_LAST, | 101 | ALC882_MODEL_LAST, |
100 | }; | 102 | }; |
101 | 103 | ||
104 | /* ALC883 models */ | ||
105 | enum { | ||
106 | ALC883_3ST_2ch_DIG, | ||
107 | ALC883_3ST_6ch_DIG, | ||
108 | ALC883_3ST_6ch, | ||
109 | ALC883_6ST_DIG, | ||
110 | ALC888_DEMO_BOARD, | ||
111 | ALC883_AUTO, | ||
112 | ALC883_MODEL_LAST, | ||
113 | }; | ||
114 | |||
102 | /* for GPIO Poll */ | 115 | /* for GPIO Poll */ |
103 | #define GPIO_MASK 0x03 | 116 | #define GPIO_MASK 0x03 |
104 | 117 | ||
@@ -108,7 +121,8 @@ struct alc_spec { | |||
108 | unsigned int num_mixers; | 121 | unsigned int num_mixers; |
109 | 122 | ||
110 | const struct hda_verb *init_verbs[5]; /* initialization verbs | 123 | const struct hda_verb *init_verbs[5]; /* initialization verbs |
111 | * don't forget NULL termination! | 124 | * don't forget NULL |
125 | * termination! | ||
112 | */ | 126 | */ |
113 | unsigned int num_init_verbs; | 127 | unsigned int num_init_verbs; |
114 | 128 | ||
@@ -163,7 +177,9 @@ struct alc_spec { | |||
163 | * configuration template - to be copied to the spec instance | 177 | * configuration template - to be copied to the spec instance |
164 | */ | 178 | */ |
165 | struct alc_config_preset { | 179 | struct alc_config_preset { |
166 | struct snd_kcontrol_new *mixers[5]; /* should be identical size with spec */ | 180 | struct snd_kcontrol_new *mixers[5]; /* should be identical size |
181 | * with spec | ||
182 | */ | ||
167 | const struct hda_verb *init_verbs[5]; | 183 | const struct hda_verb *init_verbs[5]; |
168 | unsigned int num_dacs; | 184 | unsigned int num_dacs; |
169 | hda_nid_t *dac_nids; | 185 | hda_nid_t *dac_nids; |
@@ -184,7 +200,8 @@ struct alc_config_preset { | |||
184 | /* | 200 | /* |
185 | * input MUX handling | 201 | * input MUX handling |
186 | */ | 202 | */ |
187 | static int alc_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 203 | static int alc_mux_enum_info(struct snd_kcontrol *kcontrol, |
204 | struct snd_ctl_elem_info *uinfo) | ||
188 | { | 205 | { |
189 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 206 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
190 | struct alc_spec *spec = codec->spec; | 207 | struct alc_spec *spec = codec->spec; |
@@ -194,7 +211,8 @@ static int alc_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ | |||
194 | return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo); | 211 | return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo); |
195 | } | 212 | } |
196 | 213 | ||
197 | static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 214 | static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, |
215 | struct snd_ctl_elem_value *ucontrol) | ||
198 | { | 216 | { |
199 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 217 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
200 | struct alc_spec *spec = codec->spec; | 218 | struct alc_spec *spec = codec->spec; |
@@ -204,21 +222,24 @@ static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v | |||
204 | return 0; | 222 | return 0; |
205 | } | 223 | } |
206 | 224 | ||
207 | static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 225 | static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, |
226 | struct snd_ctl_elem_value *ucontrol) | ||
208 | { | 227 | { |
209 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 228 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
210 | struct alc_spec *spec = codec->spec; | 229 | struct alc_spec *spec = codec->spec; |
211 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | 230 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); |
212 | unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; | 231 | unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; |
213 | return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol, | 232 | return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol, |
214 | spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]); | 233 | spec->adc_nids[adc_idx], |
234 | &spec->cur_mux[adc_idx]); | ||
215 | } | 235 | } |
216 | 236 | ||
217 | 237 | ||
218 | /* | 238 | /* |
219 | * channel mode setting | 239 | * channel mode setting |
220 | */ | 240 | */ |
221 | static int alc_ch_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 241 | static int alc_ch_mode_info(struct snd_kcontrol *kcontrol, |
242 | struct snd_ctl_elem_info *uinfo) | ||
222 | { | 243 | { |
223 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 244 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
224 | struct alc_spec *spec = codec->spec; | 245 | struct alc_spec *spec = codec->spec; |
@@ -226,20 +247,24 @@ static int alc_ch_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_i | |||
226 | spec->num_channel_mode); | 247 | spec->num_channel_mode); |
227 | } | 248 | } |
228 | 249 | ||
229 | static int alc_ch_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 250 | static int alc_ch_mode_get(struct snd_kcontrol *kcontrol, |
251 | struct snd_ctl_elem_value *ucontrol) | ||
230 | { | 252 | { |
231 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 253 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
232 | struct alc_spec *spec = codec->spec; | 254 | struct alc_spec *spec = codec->spec; |
233 | return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode, | 255 | return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode, |
234 | spec->num_channel_mode, spec->multiout.max_channels); | 256 | spec->num_channel_mode, |
257 | spec->multiout.max_channels); | ||
235 | } | 258 | } |
236 | 259 | ||
237 | static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 260 | static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, |
261 | struct snd_ctl_elem_value *ucontrol) | ||
238 | { | 262 | { |
239 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 263 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
240 | struct alc_spec *spec = codec->spec; | 264 | struct alc_spec *spec = codec->spec; |
241 | return snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, | 265 | return snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, |
242 | spec->num_channel_mode, &spec->multiout.max_channels); | 266 | spec->num_channel_mode, |
267 | &spec->multiout.max_channels); | ||
243 | } | 268 | } |
244 | 269 | ||
245 | /* | 270 | /* |
@@ -290,7 +315,8 @@ static signed char alc_pin_mode_dir_info[5][2] = { | |||
290 | #define alc_pin_mode_n_items(_dir) \ | 315 | #define alc_pin_mode_n_items(_dir) \ |
291 | (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1) | 316 | (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1) |
292 | 317 | ||
293 | static int alc_pin_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 318 | static int alc_pin_mode_info(struct snd_kcontrol *kcontrol, |
319 | struct snd_ctl_elem_info *uinfo) | ||
294 | { | 320 | { |
295 | unsigned int item_num = uinfo->value.enumerated.item; | 321 | unsigned int item_num = uinfo->value.enumerated.item; |
296 | unsigned char dir = (kcontrol->private_value >> 16) & 0xff; | 322 | unsigned char dir = (kcontrol->private_value >> 16) & 0xff; |
@@ -305,40 +331,46 @@ static int alc_pin_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ | |||
305 | return 0; | 331 | return 0; |
306 | } | 332 | } |
307 | 333 | ||
308 | static int alc_pin_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 334 | static int alc_pin_mode_get(struct snd_kcontrol *kcontrol, |
335 | struct snd_ctl_elem_value *ucontrol) | ||
309 | { | 336 | { |
310 | unsigned int i; | 337 | unsigned int i; |
311 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 338 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
312 | hda_nid_t nid = kcontrol->private_value & 0xffff; | 339 | hda_nid_t nid = kcontrol->private_value & 0xffff; |
313 | unsigned char dir = (kcontrol->private_value >> 16) & 0xff; | 340 | unsigned char dir = (kcontrol->private_value >> 16) & 0xff; |
314 | long *valp = ucontrol->value.integer.value; | 341 | long *valp = ucontrol->value.integer.value; |
315 | unsigned int pinctl = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_PIN_WIDGET_CONTROL,0x00); | 342 | unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, |
343 | AC_VERB_GET_PIN_WIDGET_CONTROL, | ||
344 | 0x00); | ||
316 | 345 | ||
317 | /* Find enumerated value for current pinctl setting */ | 346 | /* Find enumerated value for current pinctl setting */ |
318 | i = alc_pin_mode_min(dir); | 347 | i = alc_pin_mode_min(dir); |
319 | while (alc_pin_mode_values[i]!=pinctl && i<=alc_pin_mode_max(dir)) | 348 | while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir)) |
320 | i++; | 349 | i++; |
321 | *valp = i<=alc_pin_mode_max(dir)?i:alc_pin_mode_min(dir); | 350 | *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir); |
322 | return 0; | 351 | return 0; |
323 | } | 352 | } |
324 | 353 | ||
325 | static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 354 | static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, |
355 | struct snd_ctl_elem_value *ucontrol) | ||
326 | { | 356 | { |
327 | signed int change; | 357 | signed int change; |
328 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 358 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
329 | hda_nid_t nid = kcontrol->private_value & 0xffff; | 359 | hda_nid_t nid = kcontrol->private_value & 0xffff; |
330 | unsigned char dir = (kcontrol->private_value >> 16) & 0xff; | 360 | unsigned char dir = (kcontrol->private_value >> 16) & 0xff; |
331 | long val = *ucontrol->value.integer.value; | 361 | long val = *ucontrol->value.integer.value; |
332 | unsigned int pinctl = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_PIN_WIDGET_CONTROL,0x00); | 362 | unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, |
363 | AC_VERB_GET_PIN_WIDGET_CONTROL, | ||
364 | 0x00); | ||
333 | 365 | ||
334 | if (val<alc_pin_mode_min(dir) || val>alc_pin_mode_max(dir)) | 366 | if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir)) |
335 | val = alc_pin_mode_min(dir); | 367 | val = alc_pin_mode_min(dir); |
336 | 368 | ||
337 | change = pinctl != alc_pin_mode_values[val]; | 369 | change = pinctl != alc_pin_mode_values[val]; |
338 | if (change) { | 370 | if (change) { |
339 | /* Set pin mode to that requested */ | 371 | /* Set pin mode to that requested */ |
340 | snd_hda_codec_write(codec,nid,0,AC_VERB_SET_PIN_WIDGET_CONTROL, | 372 | snd_hda_codec_write(codec,nid,0,AC_VERB_SET_PIN_WIDGET_CONTROL, |
341 | alc_pin_mode_values[val]); | 373 | alc_pin_mode_values[val]); |
342 | 374 | ||
343 | /* Also enable the retasking pin's input/output as required | 375 | /* Also enable the retasking pin's input/output as required |
344 | * for the requested pin mode. Enum values of 2 or less are | 376 | * for the requested pin mode. Enum values of 2 or less are |
@@ -351,15 +383,19 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v | |||
351 | * this turns out to be necessary in the future. | 383 | * this turns out to be necessary in the future. |
352 | */ | 384 | */ |
353 | if (val <= 2) { | 385 | if (val <= 2) { |
354 | snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE, | 386 | snd_hda_codec_write(codec, nid, 0, |
355 | AMP_OUT_MUTE); | 387 | AC_VERB_SET_AMP_GAIN_MUTE, |
356 | snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE, | 388 | AMP_OUT_MUTE); |
357 | AMP_IN_UNMUTE(0)); | 389 | snd_hda_codec_write(codec, nid, 0, |
390 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
391 | AMP_IN_UNMUTE(0)); | ||
358 | } else { | 392 | } else { |
359 | snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE, | 393 | snd_hda_codec_write(codec, nid, 0, |
360 | AMP_IN_MUTE(0)); | 394 | AC_VERB_SET_AMP_GAIN_MUTE, |
361 | snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE, | 395 | AMP_IN_MUTE(0)); |
362 | AMP_OUT_UNMUTE); | 396 | snd_hda_codec_write(codec, nid, 0, |
397 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
398 | AMP_OUT_UNMUTE); | ||
363 | } | 399 | } |
364 | } | 400 | } |
365 | return change; | 401 | return change; |
@@ -378,7 +414,8 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v | |||
378 | * needed for any "production" models. | 414 | * needed for any "production" models. |
379 | */ | 415 | */ |
380 | #ifdef CONFIG_SND_DEBUG | 416 | #ifdef CONFIG_SND_DEBUG |
381 | static int alc_gpio_data_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 417 | static int alc_gpio_data_info(struct snd_kcontrol *kcontrol, |
418 | struct snd_ctl_elem_info *uinfo) | ||
382 | { | 419 | { |
383 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | 420 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; |
384 | uinfo->count = 1; | 421 | uinfo->count = 1; |
@@ -386,33 +423,38 @@ static int alc_gpio_data_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem | |||
386 | uinfo->value.integer.max = 1; | 423 | uinfo->value.integer.max = 1; |
387 | return 0; | 424 | return 0; |
388 | } | 425 | } |
389 | static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 426 | static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, |
427 | struct snd_ctl_elem_value *ucontrol) | ||
390 | { | 428 | { |
391 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 429 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
392 | hda_nid_t nid = kcontrol->private_value & 0xffff; | 430 | hda_nid_t nid = kcontrol->private_value & 0xffff; |
393 | unsigned char mask = (kcontrol->private_value >> 16) & 0xff; | 431 | unsigned char mask = (kcontrol->private_value >> 16) & 0xff; |
394 | long *valp = ucontrol->value.integer.value; | 432 | long *valp = ucontrol->value.integer.value; |
395 | unsigned int val = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_GPIO_DATA,0x00); | 433 | unsigned int val = snd_hda_codec_read(codec, nid, 0, |
434 | AC_VERB_GET_GPIO_DATA, 0x00); | ||
396 | 435 | ||
397 | *valp = (val & mask) != 0; | 436 | *valp = (val & mask) != 0; |
398 | return 0; | 437 | return 0; |
399 | } | 438 | } |
400 | static int alc_gpio_data_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 439 | static int alc_gpio_data_put(struct snd_kcontrol *kcontrol, |
440 | struct snd_ctl_elem_value *ucontrol) | ||
401 | { | 441 | { |
402 | signed int change; | 442 | signed int change; |
403 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 443 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
404 | hda_nid_t nid = kcontrol->private_value & 0xffff; | 444 | hda_nid_t nid = kcontrol->private_value & 0xffff; |
405 | unsigned char mask = (kcontrol->private_value >> 16) & 0xff; | 445 | unsigned char mask = (kcontrol->private_value >> 16) & 0xff; |
406 | long val = *ucontrol->value.integer.value; | 446 | long val = *ucontrol->value.integer.value; |
407 | unsigned int gpio_data = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_GPIO_DATA,0x00); | 447 | unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0, |
448 | AC_VERB_GET_GPIO_DATA, | ||
449 | 0x00); | ||
408 | 450 | ||
409 | /* Set/unset the masked GPIO bit(s) as needed */ | 451 | /* Set/unset the masked GPIO bit(s) as needed */ |
410 | change = (val==0?0:mask) != (gpio_data & mask); | 452 | change = (val == 0 ? 0 : mask) != (gpio_data & mask); |
411 | if (val==0) | 453 | if (val == 0) |
412 | gpio_data &= ~mask; | 454 | gpio_data &= ~mask; |
413 | else | 455 | else |
414 | gpio_data |= mask; | 456 | gpio_data |= mask; |
415 | snd_hda_codec_write(codec,nid,0,AC_VERB_SET_GPIO_DATA,gpio_data); | 457 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_GPIO_DATA, gpio_data); |
416 | 458 | ||
417 | return change; | 459 | return change; |
418 | } | 460 | } |
@@ -432,7 +474,8 @@ static int alc_gpio_data_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ | |||
432 | * necessary. | 474 | * necessary. |
433 | */ | 475 | */ |
434 | #ifdef CONFIG_SND_DEBUG | 476 | #ifdef CONFIG_SND_DEBUG |
435 | static int alc_spdif_ctrl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 477 | static int alc_spdif_ctrl_info(struct snd_kcontrol *kcontrol, |
478 | struct snd_ctl_elem_info *uinfo) | ||
436 | { | 479 | { |
437 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | 480 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; |
438 | uinfo->count = 1; | 481 | uinfo->count = 1; |
@@ -440,33 +483,39 @@ static int alc_spdif_ctrl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ele | |||
440 | uinfo->value.integer.max = 1; | 483 | uinfo->value.integer.max = 1; |
441 | return 0; | 484 | return 0; |
442 | } | 485 | } |
443 | static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 486 | static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol, |
487 | struct snd_ctl_elem_value *ucontrol) | ||
444 | { | 488 | { |
445 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 489 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
446 | hda_nid_t nid = kcontrol->private_value & 0xffff; | 490 | hda_nid_t nid = kcontrol->private_value & 0xffff; |
447 | unsigned char mask = (kcontrol->private_value >> 16) & 0xff; | 491 | unsigned char mask = (kcontrol->private_value >> 16) & 0xff; |
448 | long *valp = ucontrol->value.integer.value; | 492 | long *valp = ucontrol->value.integer.value; |
449 | unsigned int val = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_DIGI_CONVERT,0x00); | 493 | unsigned int val = snd_hda_codec_read(codec, nid, 0, |
494 | AC_VERB_GET_DIGI_CONVERT, 0x00); | ||
450 | 495 | ||
451 | *valp = (val & mask) != 0; | 496 | *valp = (val & mask) != 0; |
452 | return 0; | 497 | return 0; |
453 | } | 498 | } |
454 | static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 499 | static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol, |
500 | struct snd_ctl_elem_value *ucontrol) | ||
455 | { | 501 | { |
456 | signed int change; | 502 | signed int change; |
457 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 503 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
458 | hda_nid_t nid = kcontrol->private_value & 0xffff; | 504 | hda_nid_t nid = kcontrol->private_value & 0xffff; |
459 | unsigned char mask = (kcontrol->private_value >> 16) & 0xff; | 505 | unsigned char mask = (kcontrol->private_value >> 16) & 0xff; |
460 | long val = *ucontrol->value.integer.value; | 506 | long val = *ucontrol->value.integer.value; |
461 | unsigned int ctrl_data = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_DIGI_CONVERT,0x00); | 507 | unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0, |
508 | AC_VERB_GET_DIGI_CONVERT, | ||
509 | 0x00); | ||
462 | 510 | ||
463 | /* Set/unset the masked control bit(s) as needed */ | 511 | /* Set/unset the masked control bit(s) as needed */ |
464 | change = (val==0?0:mask) != (ctrl_data & mask); | 512 | change = (val == 0 ? 0 : mask) != (ctrl_data & mask); |
465 | if (val==0) | 513 | if (val==0) |
466 | ctrl_data &= ~mask; | 514 | ctrl_data &= ~mask; |
467 | else | 515 | else |
468 | ctrl_data |= mask; | 516 | ctrl_data |= mask; |
469 | snd_hda_codec_write(codec,nid,0,AC_VERB_SET_DIGI_CONVERT_1,ctrl_data); | 517 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, |
518 | ctrl_data); | ||
470 | 519 | ||
471 | return change; | 520 | return change; |
472 | } | 521 | } |
@@ -481,14 +530,17 @@ static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem | |||
481 | /* | 530 | /* |
482 | * set up from the preset table | 531 | * set up from the preset table |
483 | */ | 532 | */ |
484 | static void setup_preset(struct alc_spec *spec, const struct alc_config_preset *preset) | 533 | static void setup_preset(struct alc_spec *spec, |
534 | const struct alc_config_preset *preset) | ||
485 | { | 535 | { |
486 | int i; | 536 | int i; |
487 | 537 | ||
488 | for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++) | 538 | for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++) |
489 | spec->mixers[spec->num_mixers++] = preset->mixers[i]; | 539 | spec->mixers[spec->num_mixers++] = preset->mixers[i]; |
490 | for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i]; i++) | 540 | for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i]; |
491 | spec->init_verbs[spec->num_init_verbs++] = preset->init_verbs[i]; | 541 | i++) |
542 | spec->init_verbs[spec->num_init_verbs++] = | ||
543 | preset->init_verbs[i]; | ||
492 | 544 | ||
493 | spec->channel_mode = preset->channel_mode; | 545 | spec->channel_mode = preset->channel_mode; |
494 | spec->num_channel_mode = preset->num_channel_mode; | 546 | spec->num_channel_mode = preset->num_channel_mode; |
@@ -517,8 +569,8 @@ static void setup_preset(struct alc_spec *spec, const struct alc_config_preset * | |||
517 | * ALC880 3-stack model | 569 | * ALC880 3-stack model |
518 | * | 570 | * |
519 | * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e) | 571 | * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e) |
520 | * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18, F-Mic = 0x1b | 572 | * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18, |
521 | * HP = 0x19 | 573 | * F-Mic = 0x1b, HP = 0x19 |
522 | */ | 574 | */ |
523 | 575 | ||
524 | static hda_nid_t alc880_dac_nids[4] = { | 576 | static hda_nid_t alc880_dac_nids[4] = { |
@@ -662,7 +714,8 @@ static struct snd_kcontrol_new alc880_capture_alt_mixer[] = { | |||
662 | /* | 714 | /* |
663 | * ALC880 5-stack model | 715 | * ALC880 5-stack model |
664 | * | 716 | * |
665 | * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d), Side = 0x02 (0xd) | 717 | * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d), |
718 | * Side = 0x02 (0xd) | ||
666 | * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16 | 719 | * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16 |
667 | * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19 | 720 | * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19 |
668 | */ | 721 | */ |
@@ -700,7 +753,8 @@ static struct hda_channel_mode alc880_fivestack_modes[2] = { | |||
700 | /* | 753 | /* |
701 | * ALC880 6-stack model | 754 | * ALC880 6-stack model |
702 | * | 755 | * |
703 | * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e), Side = 0x05 (0x0f) | 756 | * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e), |
757 | * Side = 0x05 (0x0f) | ||
704 | * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17, | 758 | * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17, |
705 | * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b | 759 | * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b |
706 | */ | 760 | */ |
@@ -811,7 +865,8 @@ static struct snd_kcontrol_new alc880_w810_base_mixer[] = { | |||
811 | * Z710V model | 865 | * Z710V model |
812 | * | 866 | * |
813 | * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d) | 867 | * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d) |
814 | * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?), Line = 0x1a | 868 | * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?), |
869 | * Line = 0x1a | ||
815 | */ | 870 | */ |
816 | 871 | ||
817 | static hda_nid_t alc880_z71v_dac_nids[1] = { | 872 | static hda_nid_t alc880_z71v_dac_nids[1] = { |
@@ -966,7 +1021,8 @@ static int alc_build_controls(struct hda_codec *codec) | |||
966 | } | 1021 | } |
967 | 1022 | ||
968 | if (spec->multiout.dig_out_nid) { | 1023 | if (spec->multiout.dig_out_nid) { |
969 | err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); | 1024 | err = snd_hda_create_spdif_out_ctls(codec, |
1025 | spec->multiout.dig_out_nid); | ||
970 | if (err < 0) | 1026 | if (err < 0) |
971 | return err; | 1027 | return err; |
972 | } | 1028 | } |
@@ -999,8 +1055,8 @@ static struct hda_verb alc880_volume_init_verbs[] = { | |||
999 | 1055 | ||
1000 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback | 1056 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback |
1001 | * mixer widget | 1057 | * mixer widget |
1002 | * Note: PASD motherboards uses the Line In 2 as the input for front panel | 1058 | * Note: PASD motherboards uses the Line In 2 as the input for front |
1003 | * mic (mic 2) | 1059 | * panel mic (mic 2) |
1004 | */ | 1060 | */ |
1005 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ | 1061 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ |
1006 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 1062 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
@@ -1154,8 +1210,8 @@ static struct hda_verb alc880_pin_z71v_init_verbs[] = { | |||
1154 | 1210 | ||
1155 | /* | 1211 | /* |
1156 | * 6-stack pin configuration: | 1212 | * 6-stack pin configuration: |
1157 | * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18, f-mic = 0x19, | 1213 | * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18, |
1158 | * line = 0x1a, HP = 0x1b | 1214 | * f-mic = 0x19, line = 0x1a, HP = 0x1b |
1159 | */ | 1215 | */ |
1160 | static struct hda_verb alc880_pin_6stack_init_verbs[] = { | 1216 | static struct hda_verb alc880_pin_6stack_init_verbs[] = { |
1161 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ | 1217 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ |
@@ -1587,8 +1643,8 @@ static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
1587 | struct snd_pcm_substream *substream) | 1643 | struct snd_pcm_substream *substream) |
1588 | { | 1644 | { |
1589 | struct alc_spec *spec = codec->spec; | 1645 | struct alc_spec *spec = codec->spec; |
1590 | return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, | 1646 | return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, |
1591 | format, substream); | 1647 | stream_tag, format, substream); |
1592 | } | 1648 | } |
1593 | 1649 | ||
1594 | static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | 1650 | static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, |
@@ -1640,7 +1696,8 @@ static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
1640 | { | 1696 | { |
1641 | struct alc_spec *spec = codec->spec; | 1697 | struct alc_spec *spec = codec->spec; |
1642 | 1698 | ||
1643 | snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 0, 0, 0); | 1699 | snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], |
1700 | 0, 0, 0); | ||
1644 | return 0; | 1701 | return 0; |
1645 | } | 1702 | } |
1646 | 1703 | ||
@@ -1822,7 +1879,8 @@ static struct hda_channel_mode alc880_test_modes[4] = { | |||
1822 | { 8, NULL }, | 1879 | { 8, NULL }, |
1823 | }; | 1880 | }; |
1824 | 1881 | ||
1825 | static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1882 | static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol, |
1883 | struct snd_ctl_elem_info *uinfo) | ||
1826 | { | 1884 | { |
1827 | static char *texts[] = { | 1885 | static char *texts[] = { |
1828 | "N/A", "Line Out", "HP Out", | 1886 | "N/A", "Line Out", "HP Out", |
@@ -1837,7 +1895,8 @@ static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
1837 | return 0; | 1895 | return 0; |
1838 | } | 1896 | } |
1839 | 1897 | ||
1840 | static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1898 | static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol, |
1899 | struct snd_ctl_elem_value *ucontrol) | ||
1841 | { | 1900 | { |
1842 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 1901 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
1843 | hda_nid_t nid = (hda_nid_t)kcontrol->private_value; | 1902 | hda_nid_t nid = (hda_nid_t)kcontrol->private_value; |
@@ -1863,7 +1922,8 @@ static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_el | |||
1863 | return 0; | 1922 | return 0; |
1864 | } | 1923 | } |
1865 | 1924 | ||
1866 | static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1925 | static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol, |
1926 | struct snd_ctl_elem_value *ucontrol) | ||
1867 | { | 1927 | { |
1868 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 1928 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
1869 | hda_nid_t nid = (hda_nid_t)kcontrol->private_value; | 1929 | hda_nid_t nid = (hda_nid_t)kcontrol->private_value; |
@@ -1881,15 +1941,18 @@ static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el | |||
1881 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | 1941 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); |
1882 | new_ctl = ctls[ucontrol->value.enumerated.item[0]]; | 1942 | new_ctl = ctls[ucontrol->value.enumerated.item[0]]; |
1883 | if (old_ctl != new_ctl) { | 1943 | if (old_ctl != new_ctl) { |
1884 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, new_ctl); | 1944 | snd_hda_codec_write(codec, nid, 0, |
1945 | AC_VERB_SET_PIN_WIDGET_CONTROL, new_ctl); | ||
1885 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 1946 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, |
1886 | ucontrol->value.enumerated.item[0] >= 3 ? 0xb080 : 0xb000); | 1947 | (ucontrol->value.enumerated.item[0] >= 3 ? |
1948 | 0xb080 : 0xb000)); | ||
1887 | return 1; | 1949 | return 1; |
1888 | } | 1950 | } |
1889 | return 0; | 1951 | return 0; |
1890 | } | 1952 | } |
1891 | 1953 | ||
1892 | static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1954 | static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol, |
1955 | struct snd_ctl_elem_info *uinfo) | ||
1893 | { | 1956 | { |
1894 | static char *texts[] = { | 1957 | static char *texts[] = { |
1895 | "Front", "Surround", "CLFE", "Side" | 1958 | "Front", "Surround", "CLFE", "Side" |
@@ -1903,7 +1966,8 @@ static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
1903 | return 0; | 1966 | return 0; |
1904 | } | 1967 | } |
1905 | 1968 | ||
1906 | static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1969 | static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol, |
1970 | struct snd_ctl_elem_value *ucontrol) | ||
1907 | { | 1971 | { |
1908 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 1972 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
1909 | hda_nid_t nid = (hda_nid_t)kcontrol->private_value; | 1973 | hda_nid_t nid = (hda_nid_t)kcontrol->private_value; |
@@ -1914,7 +1978,8 @@ static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol, struct snd_ctl_el | |||
1914 | return 0; | 1978 | return 0; |
1915 | } | 1979 | } |
1916 | 1980 | ||
1917 | static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1981 | static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol, |
1982 | struct snd_ctl_elem_value *ucontrol) | ||
1918 | { | 1983 | { |
1919 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 1984 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
1920 | hda_nid_t nid = (hda_nid_t)kcontrol->private_value; | 1985 | hda_nid_t nid = (hda_nid_t)kcontrol->private_value; |
@@ -2739,7 +2804,8 @@ static int patch_alc880(struct hda_codec *codec) | |||
2739 | 2804 | ||
2740 | board_config = snd_hda_check_board_config(codec, alc880_cfg_tbl); | 2805 | board_config = snd_hda_check_board_config(codec, alc880_cfg_tbl); |
2741 | if (board_config < 0 || board_config >= ALC880_MODEL_LAST) { | 2806 | if (board_config < 0 || board_config >= ALC880_MODEL_LAST) { |
2742 | printk(KERN_INFO "hda_codec: Unknown model for ALC880, trying auto-probe from BIOS...\n"); | 2807 | printk(KERN_INFO "hda_codec: Unknown model for ALC880, " |
2808 | "trying auto-probe from BIOS...\n"); | ||
2743 | board_config = ALC880_AUTO; | 2809 | board_config = ALC880_AUTO; |
2744 | } | 2810 | } |
2745 | 2811 | ||
@@ -2750,7 +2816,9 @@ static int patch_alc880(struct hda_codec *codec) | |||
2750 | alc_free(codec); | 2816 | alc_free(codec); |
2751 | return err; | 2817 | return err; |
2752 | } else if (! err) { | 2818 | } else if (! err) { |
2753 | printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using 3-stack mode...\n"); | 2819 | printk(KERN_INFO |
2820 | "hda_codec: Cannot set up configuration " | ||
2821 | "from BIOS. Using 3-stack mode...\n"); | ||
2754 | board_config = ALC880_3ST; | 2822 | board_config = ALC880_3ST; |
2755 | } | 2823 | } |
2756 | } | 2824 | } |
@@ -3947,7 +4015,8 @@ static int patch_alc260(struct hda_codec *codec) | |||
3947 | 4015 | ||
3948 | board_config = snd_hda_check_board_config(codec, alc260_cfg_tbl); | 4016 | board_config = snd_hda_check_board_config(codec, alc260_cfg_tbl); |
3949 | if (board_config < 0 || board_config >= ALC260_MODEL_LAST) { | 4017 | if (board_config < 0 || board_config >= ALC260_MODEL_LAST) { |
3950 | snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260\n"); | 4018 | snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, " |
4019 | "trying auto-probe from BIOS...\n"); | ||
3951 | board_config = ALC260_AUTO; | 4020 | board_config = ALC260_AUTO; |
3952 | } | 4021 | } |
3953 | 4022 | ||
@@ -3958,7 +4027,9 @@ static int patch_alc260(struct hda_codec *codec) | |||
3958 | alc_free(codec); | 4027 | alc_free(codec); |
3959 | return err; | 4028 | return err; |
3960 | } else if (! err) { | 4029 | } else if (! err) { |
3961 | printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using base mode...\n"); | 4030 | printk(KERN_INFO |
4031 | "hda_codec: Cannot set up configuration " | ||
4032 | "from BIOS. Using base mode...\n"); | ||
3962 | board_config = ALC260_BASIC; | 4033 | board_config = ALC260_BASIC; |
3963 | } | 4034 | } |
3964 | } | 4035 | } |
@@ -4320,9 +4391,12 @@ static struct snd_kcontrol_new alc882_capture_mixer[] = { | |||
4320 | static struct hda_board_config alc882_cfg_tbl[] = { | 4391 | static struct hda_board_config alc882_cfg_tbl[] = { |
4321 | { .modelname = "3stack-dig", .config = ALC882_3ST_DIG }, | 4392 | { .modelname = "3stack-dig", .config = ALC882_3ST_DIG }, |
4322 | { .modelname = "6stack-dig", .config = ALC882_6ST_DIG }, | 4393 | { .modelname = "6stack-dig", .config = ALC882_6ST_DIG }, |
4323 | { .pci_subvendor = 0x1462, .pci_subdevice = 0x6668, .config = ALC882_6ST_DIG }, /* MSI */ | 4394 | { .pci_subvendor = 0x1462, .pci_subdevice = 0x6668, |
4324 | { .pci_subvendor = 0x105b, .pci_subdevice = 0x6668, .config = ALC882_6ST_DIG }, /* Foxconn */ | 4395 | .config = ALC882_6ST_DIG }, /* MSI */ |
4325 | { .pci_subvendor = 0x1019, .pci_subdevice = 0x6668, .config = ALC882_6ST_DIG }, /* ECS */ | 4396 | { .pci_subvendor = 0x105b, .pci_subdevice = 0x6668, |
4397 | .config = ALC882_6ST_DIG }, /* Foxconn */ | ||
4398 | { .pci_subvendor = 0x1019, .pci_subdevice = 0x6668, | ||
4399 | .config = ALC882_6ST_DIG }, /* ECS to Intel*/ | ||
4326 | { .modelname = "auto", .config = ALC882_AUTO }, | 4400 | { .modelname = "auto", .config = ALC882_AUTO }, |
4327 | {} | 4401 | {} |
4328 | }; | 4402 | }; |
@@ -4439,10 +4513,6 @@ static void alc882_auto_init(struct hda_codec *codec) | |||
4439 | alc882_auto_init_analog_input(codec); | 4513 | alc882_auto_init_analog_input(codec); |
4440 | } | 4514 | } |
4441 | 4515 | ||
4442 | /* | ||
4443 | * ALC882 Headphone poll in 3.5.1a or 3.5.2 | ||
4444 | */ | ||
4445 | |||
4446 | static int patch_alc882(struct hda_codec *codec) | 4516 | static int patch_alc882(struct hda_codec *codec) |
4447 | { | 4517 | { |
4448 | struct alc_spec *spec; | 4518 | struct alc_spec *spec; |
@@ -4457,7 +4527,8 @@ static int patch_alc882(struct hda_codec *codec) | |||
4457 | board_config = snd_hda_check_board_config(codec, alc882_cfg_tbl); | 4527 | board_config = snd_hda_check_board_config(codec, alc882_cfg_tbl); |
4458 | 4528 | ||
4459 | if (board_config < 0 || board_config >= ALC882_MODEL_LAST) { | 4529 | if (board_config < 0 || board_config >= ALC882_MODEL_LAST) { |
4460 | printk(KERN_INFO "hda_codec: Unknown model for ALC882, trying auto-probe from BIOS...\n"); | 4530 | printk(KERN_INFO "hda_codec: Unknown model for ALC882, " |
4531 | "trying auto-probe from BIOS...\n"); | ||
4461 | board_config = ALC882_AUTO; | 4532 | board_config = ALC882_AUTO; |
4462 | } | 4533 | } |
4463 | 4534 | ||
@@ -4468,7 +4539,9 @@ static int patch_alc882(struct hda_codec *codec) | |||
4468 | alc_free(codec); | 4539 | alc_free(codec); |
4469 | return err; | 4540 | return err; |
4470 | } else if (! err) { | 4541 | } else if (! err) { |
4471 | printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using base mode...\n"); | 4542 | printk(KERN_INFO |
4543 | "hda_codec: Cannot set up configuration " | ||
4544 | "from BIOS. Using base mode...\n"); | ||
4472 | board_config = ALC882_3ST_DIG; | 4545 | board_config = ALC882_3ST_DIG; |
4473 | } | 4546 | } |
4474 | } | 4547 | } |
@@ -4509,6 +4582,652 @@ static int patch_alc882(struct hda_codec *codec) | |||
4509 | } | 4582 | } |
4510 | 4583 | ||
4511 | /* | 4584 | /* |
4585 | * ALC883 support | ||
4586 | * | ||
4587 | * ALC883 is almost identical with ALC880 but has cleaner and more flexible | ||
4588 | * configuration. Each pin widget can choose any input DACs and a mixer. | ||
4589 | * Each ADC is connected from a mixer of all inputs. This makes possible | ||
4590 | * 6-channel independent captures. | ||
4591 | * | ||
4592 | * In addition, an independent DAC for the multi-playback (not used in this | ||
4593 | * driver yet). | ||
4594 | */ | ||
4595 | #define ALC883_DIGOUT_NID 0x06 | ||
4596 | #define ALC883_DIGIN_NID 0x0a | ||
4597 | |||
4598 | static hda_nid_t alc883_dac_nids[4] = { | ||
4599 | /* front, rear, clfe, rear_surr */ | ||
4600 | 0x02, 0x04, 0x03, 0x05 | ||
4601 | }; | ||
4602 | |||
4603 | static hda_nid_t alc883_adc_nids[2] = { | ||
4604 | /* ADC1-2 */ | ||
4605 | 0x08, 0x09, | ||
4606 | }; | ||
4607 | /* input MUX */ | ||
4608 | /* FIXME: should be a matrix-type input source selection */ | ||
4609 | |||
4610 | static struct hda_input_mux alc883_capture_source = { | ||
4611 | .num_items = 4, | ||
4612 | .items = { | ||
4613 | { "Mic", 0x0 }, | ||
4614 | { "Front Mic", 0x1 }, | ||
4615 | { "Line", 0x2 }, | ||
4616 | { "CD", 0x4 }, | ||
4617 | }, | ||
4618 | }; | ||
4619 | #define alc883_mux_enum_info alc_mux_enum_info | ||
4620 | #define alc883_mux_enum_get alc_mux_enum_get | ||
4621 | |||
4622 | static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol, | ||
4623 | struct snd_ctl_elem_value *ucontrol) | ||
4624 | { | ||
4625 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
4626 | struct alc_spec *spec = codec->spec; | ||
4627 | const struct hda_input_mux *imux = spec->input_mux; | ||
4628 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
4629 | static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 }; | ||
4630 | hda_nid_t nid = capture_mixers[adc_idx]; | ||
4631 | unsigned int *cur_val = &spec->cur_mux[adc_idx]; | ||
4632 | unsigned int i, idx; | ||
4633 | |||
4634 | idx = ucontrol->value.enumerated.item[0]; | ||
4635 | if (idx >= imux->num_items) | ||
4636 | idx = imux->num_items - 1; | ||
4637 | if (*cur_val == idx && ! codec->in_resume) | ||
4638 | return 0; | ||
4639 | for (i = 0; i < imux->num_items; i++) { | ||
4640 | unsigned int v = (i == idx) ? 0x7000 : 0x7080; | ||
4641 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
4642 | v | (imux->items[i].index << 8)); | ||
4643 | } | ||
4644 | *cur_val = idx; | ||
4645 | return 1; | ||
4646 | } | ||
4647 | /* | ||
4648 | * 2ch mode | ||
4649 | */ | ||
4650 | static struct hda_channel_mode alc883_3ST_2ch_modes[1] = { | ||
4651 | { 2, NULL } | ||
4652 | }; | ||
4653 | |||
4654 | /* | ||
4655 | * 2ch mode | ||
4656 | */ | ||
4657 | static struct hda_verb alc883_3ST_ch2_init[] = { | ||
4658 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | ||
4659 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
4660 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | ||
4661 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
4662 | { } /* end */ | ||
4663 | }; | ||
4664 | |||
4665 | /* | ||
4666 | * 6ch mode | ||
4667 | */ | ||
4668 | static struct hda_verb alc883_3ST_ch6_init[] = { | ||
4669 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
4670 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
4671 | { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, | ||
4672 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
4673 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
4674 | { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, | ||
4675 | { } /* end */ | ||
4676 | }; | ||
4677 | |||
4678 | static struct hda_channel_mode alc883_3ST_6ch_modes[2] = { | ||
4679 | { 2, alc883_3ST_ch2_init }, | ||
4680 | { 6, alc883_3ST_ch6_init }, | ||
4681 | }; | ||
4682 | |||
4683 | /* | ||
4684 | * 6ch mode | ||
4685 | */ | ||
4686 | static struct hda_verb alc883_sixstack_ch6_init[] = { | ||
4687 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, | ||
4688 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
4689 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
4690 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
4691 | { } /* end */ | ||
4692 | }; | ||
4693 | |||
4694 | /* | ||
4695 | * 8ch mode | ||
4696 | */ | ||
4697 | static struct hda_verb alc883_sixstack_ch8_init[] = { | ||
4698 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
4699 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
4700 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
4701 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
4702 | { } /* end */ | ||
4703 | }; | ||
4704 | |||
4705 | static struct hda_channel_mode alc883_sixstack_modes[2] = { | ||
4706 | { 6, alc883_sixstack_ch6_init }, | ||
4707 | { 8, alc883_sixstack_ch8_init }, | ||
4708 | }; | ||
4709 | |||
4710 | /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 | ||
4711 | * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b | ||
4712 | */ | ||
4713 | |||
4714 | static struct snd_kcontrol_new alc883_base_mixer[] = { | ||
4715 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
4716 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
4717 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
4718 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), | ||
4719 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | ||
4720 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | ||
4721 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | ||
4722 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | ||
4723 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), | ||
4724 | HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), | ||
4725 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
4726 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
4727 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
4728 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
4729 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
4730 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
4731 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
4732 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
4733 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
4734 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
4735 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
4736 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | ||
4737 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | ||
4738 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), | ||
4739 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), | ||
4740 | { | ||
4741 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
4742 | /* .name = "Capture Source", */ | ||
4743 | .name = "Input Source", | ||
4744 | .count = 2, | ||
4745 | .info = alc883_mux_enum_info, | ||
4746 | .get = alc883_mux_enum_get, | ||
4747 | .put = alc883_mux_enum_put, | ||
4748 | }, | ||
4749 | { } /* end */ | ||
4750 | }; | ||
4751 | |||
4752 | static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { | ||
4753 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
4754 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
4755 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
4756 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
4757 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
4758 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
4759 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
4760 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
4761 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
4762 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
4763 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
4764 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
4765 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
4766 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | ||
4767 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | ||
4768 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), | ||
4769 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), | ||
4770 | { | ||
4771 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
4772 | /* .name = "Capture Source", */ | ||
4773 | .name = "Input Source", | ||
4774 | .count = 2, | ||
4775 | .info = alc883_mux_enum_info, | ||
4776 | .get = alc883_mux_enum_get, | ||
4777 | .put = alc883_mux_enum_put, | ||
4778 | }, | ||
4779 | { } /* end */ | ||
4780 | }; | ||
4781 | |||
4782 | static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { | ||
4783 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
4784 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
4785 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
4786 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), | ||
4787 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | ||
4788 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | ||
4789 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | ||
4790 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | ||
4791 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
4792 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
4793 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
4794 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
4795 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
4796 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
4797 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
4798 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
4799 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
4800 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
4801 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
4802 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | ||
4803 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | ||
4804 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), | ||
4805 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), | ||
4806 | { | ||
4807 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
4808 | /* .name = "Capture Source", */ | ||
4809 | .name = "Input Source", | ||
4810 | .count = 2, | ||
4811 | .info = alc883_mux_enum_info, | ||
4812 | .get = alc883_mux_enum_get, | ||
4813 | .put = alc883_mux_enum_put, | ||
4814 | }, | ||
4815 | { } /* end */ | ||
4816 | }; | ||
4817 | |||
4818 | static struct snd_kcontrol_new alc883_chmode_mixer[] = { | ||
4819 | { | ||
4820 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
4821 | .name = "Channel Mode", | ||
4822 | .info = alc_ch_mode_info, | ||
4823 | .get = alc_ch_mode_get, | ||
4824 | .put = alc_ch_mode_put, | ||
4825 | }, | ||
4826 | { } /* end */ | ||
4827 | }; | ||
4828 | |||
4829 | static struct hda_verb alc883_init_verbs[] = { | ||
4830 | /* ADC1: mute amp left and right */ | ||
4831 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
4832 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
4833 | /* ADC2: mute amp left and right */ | ||
4834 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
4835 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
4836 | /* Front mixer: unmute input/output amp left and right (volume = 0) */ | ||
4837 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
4838 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
4839 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
4840 | /* Rear mixer */ | ||
4841 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
4842 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
4843 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
4844 | /* CLFE mixer */ | ||
4845 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
4846 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
4847 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
4848 | /* Side mixer */ | ||
4849 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
4850 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
4851 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
4852 | |||
4853 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
4854 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
4855 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
4856 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
4857 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
4858 | |||
4859 | /* Front Pin: output 0 (0x0c) */ | ||
4860 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
4861 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
4862 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
4863 | /* Rear Pin: output 1 (0x0d) */ | ||
4864 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
4865 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
4866 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
4867 | /* CLFE Pin: output 2 (0x0e) */ | ||
4868 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
4869 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
4870 | {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
4871 | /* Side Pin: output 3 (0x0f) */ | ||
4872 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
4873 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
4874 | {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, | ||
4875 | /* Mic (rear) pin: input vref at 80% */ | ||
4876 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
4877 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
4878 | /* Front Mic pin: input vref at 80% */ | ||
4879 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
4880 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
4881 | /* Line In pin: input */ | ||
4882 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
4883 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
4884 | /* Line-2 In: Headphone output (output 0 - 0x0c) */ | ||
4885 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
4886 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
4887 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
4888 | /* CD pin widget for input */ | ||
4889 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
4890 | |||
4891 | /* FIXME: use matrix-type input source selection */ | ||
4892 | /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ | ||
4893 | /* Input mixer2 */ | ||
4894 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
4895 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
4896 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
4897 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
4898 | /* Input mixer3 */ | ||
4899 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
4900 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
4901 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
4902 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
4903 | { } | ||
4904 | }; | ||
4905 | |||
4906 | /* | ||
4907 | * generic initialization of ADC, input mixers and output mixers | ||
4908 | */ | ||
4909 | static struct hda_verb alc883_auto_init_verbs[] = { | ||
4910 | /* | ||
4911 | * Unmute ADC0-2 and set the default input to mic-in | ||
4912 | */ | ||
4913 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
4914 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
4915 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
4916 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
4917 | |||
4918 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback | ||
4919 | * mixer widget | ||
4920 | * Note: PASD motherboards uses the Line In 2 as the input for front panel | ||
4921 | * mic (mic 2) | ||
4922 | */ | ||
4923 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ | ||
4924 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
4925 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
4926 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
4927 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
4928 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
4929 | |||
4930 | /* | ||
4931 | * Set up output mixers (0x0c - 0x0f) | ||
4932 | */ | ||
4933 | /* set vol=0 to output mixers */ | ||
4934 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
4935 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
4936 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
4937 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
4938 | /* set up input amps for analog loopback */ | ||
4939 | /* Amp Indices: DAC = 0, mixer = 1 */ | ||
4940 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
4941 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
4942 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
4943 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
4944 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
4945 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
4946 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
4947 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
4948 | {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
4949 | {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
4950 | |||
4951 | /* FIXME: use matrix-type input source selection */ | ||
4952 | /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ | ||
4953 | /* Input mixer1 */ | ||
4954 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
4955 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
4956 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
4957 | //{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
4958 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
4959 | /* Input mixer2 */ | ||
4960 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
4961 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
4962 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
4963 | //{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
4964 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
4965 | |||
4966 | { } | ||
4967 | }; | ||
4968 | |||
4969 | /* capture mixer elements */ | ||
4970 | static struct snd_kcontrol_new alc883_capture_mixer[] = { | ||
4971 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | ||
4972 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | ||
4973 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), | ||
4974 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), | ||
4975 | { | ||
4976 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
4977 | /* The multiple "Capture Source" controls confuse alsamixer | ||
4978 | * So call somewhat different.. | ||
4979 | * FIXME: the controls appear in the "playback" view! | ||
4980 | */ | ||
4981 | /* .name = "Capture Source", */ | ||
4982 | .name = "Input Source", | ||
4983 | .count = 2, | ||
4984 | .info = alc882_mux_enum_info, | ||
4985 | .get = alc882_mux_enum_get, | ||
4986 | .put = alc882_mux_enum_put, | ||
4987 | }, | ||
4988 | { } /* end */ | ||
4989 | }; | ||
4990 | |||
4991 | /* pcm configuration: identiacal with ALC880 */ | ||
4992 | #define alc883_pcm_analog_playback alc880_pcm_analog_playback | ||
4993 | #define alc883_pcm_analog_capture alc880_pcm_analog_capture | ||
4994 | #define alc883_pcm_digital_playback alc880_pcm_digital_playback | ||
4995 | #define alc883_pcm_digital_capture alc880_pcm_digital_capture | ||
4996 | |||
4997 | /* | ||
4998 | * configuration and preset | ||
4999 | */ | ||
5000 | static struct hda_board_config alc883_cfg_tbl[] = { | ||
5001 | { .modelname = "3stack-dig", .config = ALC883_3ST_2ch_DIG }, | ||
5002 | { .modelname = "6stack-dig", .config = ALC883_6ST_DIG }, | ||
5003 | { .modelname = "6stack-dig-demo", .config = ALC888_DEMO_BOARD }, | ||
5004 | { .pci_subvendor = 0x1462, .pci_subdevice = 0x6668, | ||
5005 | .config = ALC883_6ST_DIG }, /* MSI */ | ||
5006 | { .pci_subvendor = 0x105b, .pci_subdevice = 0x6668, | ||
5007 | .config = ALC883_6ST_DIG }, /* Foxconn */ | ||
5008 | { .pci_subvendor = 0x1019, .pci_subdevice = 0x6668, | ||
5009 | .config = ALC883_3ST_6ch_DIG }, /* ECS to Intel*/ | ||
5010 | { .pci_subvendor = 0x108e, .pci_subdevice = 0x534d, | ||
5011 | .config = ALC883_3ST_6ch }, | ||
5012 | { .modelname = "auto", .config = ALC883_AUTO }, | ||
5013 | {} | ||
5014 | }; | ||
5015 | |||
5016 | static struct alc_config_preset alc883_presets[] = { | ||
5017 | [ALC883_3ST_2ch_DIG] = { | ||
5018 | .mixers = { alc883_3ST_2ch_mixer }, | ||
5019 | .init_verbs = { alc883_init_verbs }, | ||
5020 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
5021 | .dac_nids = alc883_dac_nids, | ||
5022 | .dig_out_nid = ALC883_DIGOUT_NID, | ||
5023 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), | ||
5024 | .adc_nids = alc883_adc_nids, | ||
5025 | .dig_in_nid = ALC883_DIGIN_NID, | ||
5026 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | ||
5027 | .channel_mode = alc883_3ST_2ch_modes, | ||
5028 | .input_mux = &alc883_capture_source, | ||
5029 | }, | ||
5030 | [ALC883_3ST_6ch_DIG] = { | ||
5031 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, | ||
5032 | .init_verbs = { alc883_init_verbs }, | ||
5033 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
5034 | .dac_nids = alc883_dac_nids, | ||
5035 | .dig_out_nid = ALC883_DIGOUT_NID, | ||
5036 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), | ||
5037 | .adc_nids = alc883_adc_nids, | ||
5038 | .dig_in_nid = ALC883_DIGIN_NID, | ||
5039 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), | ||
5040 | .channel_mode = alc883_3ST_6ch_modes, | ||
5041 | .input_mux = &alc883_capture_source, | ||
5042 | }, | ||
5043 | [ALC883_3ST_6ch] = { | ||
5044 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, | ||
5045 | .init_verbs = { alc883_init_verbs }, | ||
5046 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
5047 | .dac_nids = alc883_dac_nids, | ||
5048 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), | ||
5049 | .adc_nids = alc883_adc_nids, | ||
5050 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), | ||
5051 | .channel_mode = alc883_3ST_6ch_modes, | ||
5052 | .input_mux = &alc883_capture_source, | ||
5053 | }, | ||
5054 | [ALC883_6ST_DIG] = { | ||
5055 | .mixers = { alc883_base_mixer, alc883_chmode_mixer }, | ||
5056 | .init_verbs = { alc883_init_verbs }, | ||
5057 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
5058 | .dac_nids = alc883_dac_nids, | ||
5059 | .dig_out_nid = ALC883_DIGOUT_NID, | ||
5060 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), | ||
5061 | .adc_nids = alc883_adc_nids, | ||
5062 | .dig_in_nid = ALC883_DIGIN_NID, | ||
5063 | .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), | ||
5064 | .channel_mode = alc883_sixstack_modes, | ||
5065 | .input_mux = &alc883_capture_source, | ||
5066 | }, | ||
5067 | [ALC888_DEMO_BOARD] = { | ||
5068 | .mixers = { alc883_base_mixer, alc883_chmode_mixer }, | ||
5069 | .init_verbs = { alc883_init_verbs }, | ||
5070 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
5071 | .dac_nids = alc883_dac_nids, | ||
5072 | .dig_out_nid = ALC883_DIGOUT_NID, | ||
5073 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), | ||
5074 | .adc_nids = alc883_adc_nids, | ||
5075 | .dig_in_nid = ALC883_DIGIN_NID, | ||
5076 | .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), | ||
5077 | .channel_mode = alc883_sixstack_modes, | ||
5078 | .input_mux = &alc883_capture_source, | ||
5079 | }, | ||
5080 | }; | ||
5081 | |||
5082 | |||
5083 | /* | ||
5084 | * BIOS auto configuration | ||
5085 | */ | ||
5086 | static void alc883_auto_set_output_and_unmute(struct hda_codec *codec, | ||
5087 | hda_nid_t nid, int pin_type, | ||
5088 | int dac_idx) | ||
5089 | { | ||
5090 | /* set as output */ | ||
5091 | struct alc_spec *spec = codec->spec; | ||
5092 | int idx; | ||
5093 | |||
5094 | if (spec->multiout.dac_nids[dac_idx] == 0x25) | ||
5095 | idx = 4; | ||
5096 | else | ||
5097 | idx = spec->multiout.dac_nids[dac_idx] - 2; | ||
5098 | |||
5099 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
5100 | pin_type); | ||
5101 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
5102 | AMP_OUT_UNMUTE); | ||
5103 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); | ||
5104 | |||
5105 | } | ||
5106 | |||
5107 | static void alc883_auto_init_multi_out(struct hda_codec *codec) | ||
5108 | { | ||
5109 | struct alc_spec *spec = codec->spec; | ||
5110 | int i; | ||
5111 | |||
5112 | for (i = 0; i <= HDA_SIDE; i++) { | ||
5113 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | ||
5114 | if (nid) | ||
5115 | alc883_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); | ||
5116 | } | ||
5117 | } | ||
5118 | |||
5119 | static void alc883_auto_init_hp_out(struct hda_codec *codec) | ||
5120 | { | ||
5121 | struct alc_spec *spec = codec->spec; | ||
5122 | hda_nid_t pin; | ||
5123 | |||
5124 | pin = spec->autocfg.hp_pin; | ||
5125 | if (pin) /* connect to front */ | ||
5126 | /* use dac 0 */ | ||
5127 | alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); | ||
5128 | } | ||
5129 | |||
5130 | #define alc883_is_input_pin(nid) alc880_is_input_pin(nid) | ||
5131 | #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID | ||
5132 | |||
5133 | static void alc883_auto_init_analog_input(struct hda_codec *codec) | ||
5134 | { | ||
5135 | struct alc_spec *spec = codec->spec; | ||
5136 | int i; | ||
5137 | |||
5138 | for (i = 0; i < AUTO_PIN_LAST; i++) { | ||
5139 | hda_nid_t nid = spec->autocfg.input_pins[i]; | ||
5140 | if (alc883_is_input_pin(nid)) { | ||
5141 | snd_hda_codec_write(codec, nid, 0, | ||
5142 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
5143 | (i <= AUTO_PIN_FRONT_MIC ? | ||
5144 | PIN_VREF80 : PIN_IN)); | ||
5145 | if (nid != ALC883_PIN_CD_NID) | ||
5146 | snd_hda_codec_write(codec, nid, 0, | ||
5147 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
5148 | AMP_OUT_MUTE); | ||
5149 | } | ||
5150 | } | ||
5151 | } | ||
5152 | |||
5153 | /* almost identical with ALC880 parser... */ | ||
5154 | static int alc883_parse_auto_config(struct hda_codec *codec) | ||
5155 | { | ||
5156 | struct alc_spec *spec = codec->spec; | ||
5157 | int err = alc880_parse_auto_config(codec); | ||
5158 | |||
5159 | if (err < 0) | ||
5160 | return err; | ||
5161 | else if (err > 0) | ||
5162 | /* hack - override the init verbs */ | ||
5163 | spec->init_verbs[0] = alc883_auto_init_verbs; | ||
5164 | spec->mixers[spec->num_mixers] = alc883_capture_mixer; | ||
5165 | spec->num_mixers++; | ||
5166 | return err; | ||
5167 | } | ||
5168 | |||
5169 | /* additional initialization for auto-configuration model */ | ||
5170 | static void alc883_auto_init(struct hda_codec *codec) | ||
5171 | { | ||
5172 | alc883_auto_init_multi_out(codec); | ||
5173 | alc883_auto_init_hp_out(codec); | ||
5174 | alc883_auto_init_analog_input(codec); | ||
5175 | } | ||
5176 | |||
5177 | static int patch_alc883(struct hda_codec *codec) | ||
5178 | { | ||
5179 | struct alc_spec *spec; | ||
5180 | int err, board_config; | ||
5181 | |||
5182 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
5183 | if (spec == NULL) | ||
5184 | return -ENOMEM; | ||
5185 | |||
5186 | codec->spec = spec; | ||
5187 | |||
5188 | board_config = snd_hda_check_board_config(codec, alc883_cfg_tbl); | ||
5189 | if (board_config < 0 || board_config >= ALC883_MODEL_LAST) { | ||
5190 | printk(KERN_INFO "hda_codec: Unknown model for ALC883, " | ||
5191 | "trying auto-probe from BIOS...\n"); | ||
5192 | board_config = ALC883_AUTO; | ||
5193 | } | ||
5194 | |||
5195 | if (board_config == ALC883_AUTO) { | ||
5196 | /* automatic parse from the BIOS config */ | ||
5197 | err = alc883_parse_auto_config(codec); | ||
5198 | if (err < 0) { | ||
5199 | alc_free(codec); | ||
5200 | return err; | ||
5201 | } else if (! err) { | ||
5202 | printk(KERN_INFO | ||
5203 | "hda_codec: Cannot set up configuration " | ||
5204 | "from BIOS. Using base mode...\n"); | ||
5205 | board_config = ALC883_3ST_2ch_DIG; | ||
5206 | } | ||
5207 | } | ||
5208 | |||
5209 | if (board_config != ALC883_AUTO) | ||
5210 | setup_preset(spec, &alc883_presets[board_config]); | ||
5211 | |||
5212 | spec->stream_name_analog = "ALC883 Analog"; | ||
5213 | spec->stream_analog_playback = &alc883_pcm_analog_playback; | ||
5214 | spec->stream_analog_capture = &alc883_pcm_analog_capture; | ||
5215 | |||
5216 | spec->stream_name_digital = "ALC883 Digital"; | ||
5217 | spec->stream_digital_playback = &alc883_pcm_digital_playback; | ||
5218 | spec->stream_digital_capture = &alc883_pcm_digital_capture; | ||
5219 | |||
5220 | spec->adc_nids = alc883_adc_nids; | ||
5221 | spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); | ||
5222 | |||
5223 | codec->patch_ops = alc_patch_ops; | ||
5224 | if (board_config == ALC883_AUTO) | ||
5225 | spec->init_hook = alc883_auto_init; | ||
5226 | |||
5227 | return 0; | ||
5228 | } | ||
5229 | |||
5230 | /* | ||
4512 | * ALC262 support | 5231 | * ALC262 support |
4513 | */ | 5232 | */ |
4514 | 5233 | ||
@@ -4542,6 +5261,28 @@ static struct snd_kcontrol_new alc262_base_mixer[] = { | |||
4542 | { } /* end */ | 5261 | { } /* end */ |
4543 | }; | 5262 | }; |
4544 | 5263 | ||
5264 | static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { | ||
5265 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
5266 | HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
5267 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
5268 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | ||
5269 | HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), | ||
5270 | |||
5271 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
5272 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
5273 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), | ||
5274 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), | ||
5275 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
5276 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
5277 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
5278 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
5279 | HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
5280 | HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
5281 | HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT), | ||
5282 | HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT), | ||
5283 | { } /* end */ | ||
5284 | }; | ||
5285 | |||
4545 | #define alc262_capture_mixer alc882_capture_mixer | 5286 | #define alc262_capture_mixer alc882_capture_mixer |
4546 | #define alc262_capture_alt_mixer alc882_capture_alt_mixer | 5287 | #define alc262_capture_alt_mixer alc882_capture_alt_mixer |
4547 | 5288 | ||
@@ -4645,6 +5386,17 @@ static struct hda_input_mux alc262_fujitsu_capture_source = { | |||
4645 | }, | 5386 | }, |
4646 | }; | 5387 | }; |
4647 | 5388 | ||
5389 | static struct hda_input_mux alc262_HP_capture_source = { | ||
5390 | .num_items = 5, | ||
5391 | .items = { | ||
5392 | { "Mic", 0x0 }, | ||
5393 | { "Front Mic", 0x3 }, | ||
5394 | { "Line", 0x2 }, | ||
5395 | { "CD", 0x4 }, | ||
5396 | { "AUX IN", 0x6 }, | ||
5397 | }, | ||
5398 | }; | ||
5399 | |||
4648 | /* mute/unmute internal speaker according to the hp jack and mute state */ | 5400 | /* mute/unmute internal speaker according to the hp jack and mute state */ |
4649 | static void alc262_fujitsu_automute(struct hda_codec *codec, int force) | 5401 | static void alc262_fujitsu_automute(struct hda_codec *codec, int force) |
4650 | { | 5402 | { |
@@ -4868,6 +5620,93 @@ static struct hda_verb alc262_volume_init_verbs[] = { | |||
4868 | { } | 5620 | { } |
4869 | }; | 5621 | }; |
4870 | 5622 | ||
5623 | static struct hda_verb alc262_HP_BPC_init_verbs[] = { | ||
5624 | /* | ||
5625 | * Unmute ADC0-2 and set the default input to mic-in | ||
5626 | */ | ||
5627 | {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
5628 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
5629 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
5630 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
5631 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
5632 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
5633 | |||
5634 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback | ||
5635 | * mixer widget | ||
5636 | * Note: PASD motherboards uses the Line In 2 as the input for front panel | ||
5637 | * mic (mic 2) | ||
5638 | */ | ||
5639 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ | ||
5640 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
5641 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
5642 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
5643 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
5644 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
5645 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, | ||
5646 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)}, | ||
5647 | |||
5648 | /* | ||
5649 | * Set up output mixers (0x0c - 0x0e) | ||
5650 | */ | ||
5651 | /* set vol=0 to output mixers */ | ||
5652 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
5653 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
5654 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
5655 | |||
5656 | /* set up input amps for analog loopback */ | ||
5657 | /* Amp Indices: DAC = 0, mixer = 1 */ | ||
5658 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
5659 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
5660 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
5661 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
5662 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
5663 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
5664 | |||
5665 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, | ||
5666 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
5667 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
5668 | |||
5669 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
5670 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
5671 | |||
5672 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
5673 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
5674 | |||
5675 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | ||
5676 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | ||
5677 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | ||
5678 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | ||
5679 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | ||
5680 | |||
5681 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, | ||
5682 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, | ||
5683 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, | ||
5684 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, | ||
5685 | {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, | ||
5686 | {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, | ||
5687 | |||
5688 | |||
5689 | /* FIXME: use matrix-type input source selection */ | ||
5690 | /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ | ||
5691 | /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ | ||
5692 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
5693 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, | ||
5694 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, | ||
5695 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, | ||
5696 | /* Input mixer2 */ | ||
5697 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
5698 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, | ||
5699 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, | ||
5700 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, | ||
5701 | /* Input mixer3 */ | ||
5702 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
5703 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, | ||
5704 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, | ||
5705 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, | ||
5706 | |||
5707 | { } | ||
5708 | }; | ||
5709 | |||
4871 | /* pcm configuration: identiacal with ALC880 */ | 5710 | /* pcm configuration: identiacal with ALC880 */ |
4872 | #define alc262_pcm_analog_playback alc880_pcm_analog_playback | 5711 | #define alc262_pcm_analog_playback alc880_pcm_analog_playback |
4873 | #define alc262_pcm_analog_capture alc880_pcm_analog_capture | 5712 | #define alc262_pcm_analog_capture alc880_pcm_analog_capture |
@@ -4928,7 +5767,16 @@ static void alc262_auto_init(struct hda_codec *codec) | |||
4928 | static struct hda_board_config alc262_cfg_tbl[] = { | 5767 | static struct hda_board_config alc262_cfg_tbl[] = { |
4929 | { .modelname = "basic", .config = ALC262_BASIC }, | 5768 | { .modelname = "basic", .config = ALC262_BASIC }, |
4930 | { .modelname = "fujitsu", .config = ALC262_FUJITSU }, | 5769 | { .modelname = "fujitsu", .config = ALC262_FUJITSU }, |
4931 | { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1397, .config = ALC262_FUJITSU }, | 5770 | { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1397, |
5771 | .config = ALC262_FUJITSU }, | ||
5772 | { .pci_subvendor = 0x103c, .pci_subdevice = 0x208c, | ||
5773 | .config = ALC262_HP_BPC }, /* xw4400 */ | ||
5774 | { .pci_subvendor = 0x103c, .pci_subdevice = 0x3014, | ||
5775 | .config = ALC262_HP_BPC }, /* xw6400 */ | ||
5776 | { .pci_subvendor = 0x103c, .pci_subdevice = 0x3015, | ||
5777 | .config = ALC262_HP_BPC }, /* xw8400 */ | ||
5778 | { .pci_subvendor = 0x103c, .pci_subdevice = 0x12fe, | ||
5779 | .config = ALC262_HP_BPC }, /* xw9400 */ | ||
4932 | { .modelname = "auto", .config = ALC262_AUTO }, | 5780 | { .modelname = "auto", .config = ALC262_AUTO }, |
4933 | {} | 5781 | {} |
4934 | }; | 5782 | }; |
@@ -4956,6 +5804,16 @@ static struct alc_config_preset alc262_presets[] = { | |||
4956 | .input_mux = &alc262_fujitsu_capture_source, | 5804 | .input_mux = &alc262_fujitsu_capture_source, |
4957 | .unsol_event = alc262_fujitsu_unsol_event, | 5805 | .unsol_event = alc262_fujitsu_unsol_event, |
4958 | }, | 5806 | }, |
5807 | [ALC262_HP_BPC] = { | ||
5808 | .mixers = { alc262_HP_BPC_mixer }, | ||
5809 | .init_verbs = { alc262_HP_BPC_init_verbs }, | ||
5810 | .num_dacs = ARRAY_SIZE(alc262_dac_nids), | ||
5811 | .dac_nids = alc262_dac_nids, | ||
5812 | .hp_nid = 0x03, | ||
5813 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | ||
5814 | .channel_mode = alc262_modes, | ||
5815 | .input_mux = &alc262_HP_capture_source, | ||
5816 | }, | ||
4959 | }; | 5817 | }; |
4960 | 5818 | ||
4961 | static int patch_alc262(struct hda_codec *codec) | 5819 | static int patch_alc262(struct hda_codec *codec) |
@@ -4981,8 +5839,10 @@ static int patch_alc262(struct hda_codec *codec) | |||
4981 | #endif | 5839 | #endif |
4982 | 5840 | ||
4983 | board_config = snd_hda_check_board_config(codec, alc262_cfg_tbl); | 5841 | board_config = snd_hda_check_board_config(codec, alc262_cfg_tbl); |
5842 | |||
4984 | if (board_config < 0 || board_config >= ALC262_MODEL_LAST) { | 5843 | if (board_config < 0 || board_config >= ALC262_MODEL_LAST) { |
4985 | printk(KERN_INFO "hda_codec: Unknown model for ALC262, trying auto-probe from BIOS...\n"); | 5844 | printk(KERN_INFO "hda_codec: Unknown model for ALC262, " |
5845 | "trying auto-probe from BIOS...\n"); | ||
4986 | board_config = ALC262_AUTO; | 5846 | board_config = ALC262_AUTO; |
4987 | } | 5847 | } |
4988 | 5848 | ||
@@ -4993,7 +5853,9 @@ static int patch_alc262(struct hda_codec *codec) | |||
4993 | alc_free(codec); | 5853 | alc_free(codec); |
4994 | return err; | 5854 | return err; |
4995 | } else if (! err) { | 5855 | } else if (! err) { |
4996 | printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using base mode...\n"); | 5856 | printk(KERN_INFO |
5857 | "hda_codec: Cannot set up configuration " | ||
5858 | "from BIOS. Using base mode...\n"); | ||
4997 | board_config = ALC262_BASIC; | 5859 | board_config = ALC262_BASIC; |
4998 | } | 5860 | } |
4999 | } | 5861 | } |
@@ -5034,7 +5896,6 @@ static int patch_alc262(struct hda_codec *codec) | |||
5034 | return 0; | 5896 | return 0; |
5035 | } | 5897 | } |
5036 | 5898 | ||
5037 | |||
5038 | /* | 5899 | /* |
5039 | * ALC861 channel source setting (2/6 channel selection for 3-stack) | 5900 | * ALC861 channel source setting (2/6 channel selection for 3-stack) |
5040 | */ | 5901 | */ |
@@ -5049,9 +5910,11 @@ static struct hda_verb alc861_threestack_ch2_init[] = { | |||
5049 | /* set pin widget 18h (mic1/2) for input, for mic also enable the vref */ | 5910 | /* set pin widget 18h (mic1/2) for input, for mic also enable the vref */ |
5050 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | 5911 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, |
5051 | 5912 | ||
5052 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, | 5913 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, |
5053 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, //mic | 5914 | #if 0 |
5054 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, //line in | 5915 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ |
5916 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ | ||
5917 | #endif | ||
5055 | { } /* end */ | 5918 | { } /* end */ |
5056 | }; | 5919 | }; |
5057 | /* | 5920 | /* |
@@ -5065,11 +5928,13 @@ static struct hda_verb alc861_threestack_ch6_init[] = { | |||
5065 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | 5928 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, |
5066 | 5929 | ||
5067 | { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, | 5930 | { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, |
5068 | { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, | 5931 | { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, |
5069 | 5932 | ||
5070 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, | 5933 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, |
5071 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, //mic | 5934 | #if 0 |
5072 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, //line in | 5935 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ |
5936 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ | ||
5937 | #endif | ||
5073 | { } /* end */ | 5938 | { } /* end */ |
5074 | }; | 5939 | }; |
5075 | 5940 | ||
@@ -5353,6 +6218,11 @@ static hda_nid_t alc861_dac_nids[4] = { | |||
5353 | 0x03, 0x06, 0x05, 0x04 | 6218 | 0x03, 0x06, 0x05, 0x04 |
5354 | }; | 6219 | }; |
5355 | 6220 | ||
6221 | static hda_nid_t alc660_dac_nids[3] = { | ||
6222 | /* front, clfe, surround */ | ||
6223 | 0x03, 0x05, 0x06 | ||
6224 | }; | ||
6225 | |||
5356 | static hda_nid_t alc861_adc_nids[1] = { | 6226 | static hda_nid_t alc861_adc_nids[1] = { |
5357 | /* ADC0-2 */ | 6227 | /* ADC0-2 */ |
5358 | 0x08, | 6228 | 0x08, |
@@ -5605,7 +6475,10 @@ static void alc861_auto_init(struct hda_codec *codec) | |||
5605 | */ | 6475 | */ |
5606 | static struct hda_board_config alc861_cfg_tbl[] = { | 6476 | static struct hda_board_config alc861_cfg_tbl[] = { |
5607 | { .modelname = "3stack", .config = ALC861_3ST }, | 6477 | { .modelname = "3stack", .config = ALC861_3ST }, |
5608 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xd600, .config = ALC861_3ST }, | 6478 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xd600, |
6479 | .config = ALC861_3ST }, | ||
6480 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x81e7, | ||
6481 | .config = ALC660_3ST }, | ||
5609 | { .modelname = "3stack-dig", .config = ALC861_3ST_DIG }, | 6482 | { .modelname = "3stack-dig", .config = ALC861_3ST_DIG }, |
5610 | { .modelname = "6stack-dig", .config = ALC861_6ST_DIG }, | 6483 | { .modelname = "6stack-dig", .config = ALC861_6ST_DIG }, |
5611 | { .modelname = "auto", .config = ALC861_AUTO }, | 6484 | { .modelname = "auto", .config = ALC861_AUTO }, |
@@ -5648,6 +6521,17 @@ static struct alc_config_preset alc861_presets[] = { | |||
5648 | .adc_nids = alc861_adc_nids, | 6521 | .adc_nids = alc861_adc_nids, |
5649 | .input_mux = &alc861_capture_source, | 6522 | .input_mux = &alc861_capture_source, |
5650 | }, | 6523 | }, |
6524 | [ALC660_3ST] = { | ||
6525 | .mixers = { alc861_3ST_mixer }, | ||
6526 | .init_verbs = { alc861_threestack_init_verbs }, | ||
6527 | .num_dacs = ARRAY_SIZE(alc660_dac_nids), | ||
6528 | .dac_nids = alc660_dac_nids, | ||
6529 | .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), | ||
6530 | .channel_mode = alc861_threestack_modes, | ||
6531 | .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), | ||
6532 | .adc_nids = alc861_adc_nids, | ||
6533 | .input_mux = &alc861_capture_source, | ||
6534 | }, | ||
5651 | }; | 6535 | }; |
5652 | 6536 | ||
5653 | 6537 | ||
@@ -5664,8 +6548,10 @@ static int patch_alc861(struct hda_codec *codec) | |||
5664 | codec->spec = spec; | 6548 | codec->spec = spec; |
5665 | 6549 | ||
5666 | board_config = snd_hda_check_board_config(codec, alc861_cfg_tbl); | 6550 | board_config = snd_hda_check_board_config(codec, alc861_cfg_tbl); |
6551 | |||
5667 | if (board_config < 0 || board_config >= ALC861_MODEL_LAST) { | 6552 | if (board_config < 0 || board_config >= ALC861_MODEL_LAST) { |
5668 | printk(KERN_INFO "hda_codec: Unknown model for ALC861, trying auto-probe from BIOS...\n"); | 6553 | printk(KERN_INFO "hda_codec: Unknown model for ALC861, " |
6554 | "trying auto-probe from BIOS...\n"); | ||
5669 | board_config = ALC861_AUTO; | 6555 | board_config = ALC861_AUTO; |
5670 | } | 6556 | } |
5671 | 6557 | ||
@@ -5676,7 +6562,9 @@ static int patch_alc861(struct hda_codec *codec) | |||
5676 | alc_free(codec); | 6562 | alc_free(codec); |
5677 | return err; | 6563 | return err; |
5678 | } else if (! err) { | 6564 | } else if (! err) { |
5679 | printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using base mode...\n"); | 6565 | printk(KERN_INFO |
6566 | "hda_codec: Cannot set up configuration " | ||
6567 | "from BIOS. Using base mode...\n"); | ||
5680 | board_config = ALC861_3ST_DIG; | 6568 | board_config = ALC861_3ST_DIG; |
5681 | } | 6569 | } |
5682 | } | 6570 | } |
@@ -5707,8 +6595,12 @@ struct hda_codec_preset snd_hda_preset_realtek[] = { | |||
5707 | { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, | 6595 | { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, |
5708 | { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, | 6596 | { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, |
5709 | { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, | 6597 | { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, |
5710 | { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, | 6598 | { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 }, |
5711 | { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, | 6599 | { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, |
5712 | { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, | 6600 | { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 }, |
6601 | { .id = 0x10ec0861, .rev = 0x100300, .name = "ALC861", | ||
6602 | .patch = patch_alc861 }, | ||
6603 | { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", | ||
6604 | .patch = patch_alc861 }, | ||
5713 | {} /* terminator */ | 6605 | {} /* terminator */ |
5714 | }; | 6606 | }; |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 36f199442fdc..fb4bed0759d1 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -42,6 +42,9 @@ | |||
42 | #define STAC_D945GTP3 1 | 42 | #define STAC_D945GTP3 1 |
43 | #define STAC_D945GTP5 2 | 43 | #define STAC_D945GTP5 2 |
44 | #define STAC_MACMINI 3 | 44 | #define STAC_MACMINI 3 |
45 | #define STAC_D965_2112 4 | ||
46 | #define STAC_D965_284B 5 | ||
47 | #define STAC_922X_MODELS 6 /* number of 922x models */ | ||
45 | 48 | ||
46 | struct sigmatel_spec { | 49 | struct sigmatel_spec { |
47 | struct snd_kcontrol_new *mixers[4]; | 50 | struct snd_kcontrol_new *mixers[4]; |
@@ -107,10 +110,24 @@ static hda_nid_t stac922x_adc_nids[2] = { | |||
107 | 0x06, 0x07, | 110 | 0x06, 0x07, |
108 | }; | 111 | }; |
109 | 112 | ||
113 | static hda_nid_t stac9227_adc_nids[2] = { | ||
114 | 0x07, 0x08, | ||
115 | }; | ||
116 | |||
117 | #if 0 | ||
118 | static hda_nid_t d965_2112_dac_nids[3] = { | ||
119 | 0x02, 0x03, 0x05, | ||
120 | }; | ||
121 | #endif | ||
122 | |||
110 | static hda_nid_t stac922x_mux_nids[2] = { | 123 | static hda_nid_t stac922x_mux_nids[2] = { |
111 | 0x12, 0x13, | 124 | 0x12, 0x13, |
112 | }; | 125 | }; |
113 | 126 | ||
127 | static hda_nid_t stac9227_mux_nids[2] = { | ||
128 | 0x15, 0x16, | ||
129 | }; | ||
130 | |||
114 | static hda_nid_t stac927x_adc_nids[3] = { | 131 | static hda_nid_t stac927x_adc_nids[3] = { |
115 | 0x07, 0x08, 0x09 | 132 | 0x07, 0x08, 0x09 |
116 | }; | 133 | }; |
@@ -173,6 +190,24 @@ static struct hda_verb stac922x_core_init[] = { | |||
173 | {} | 190 | {} |
174 | }; | 191 | }; |
175 | 192 | ||
193 | static struct hda_verb stac9227_core_init[] = { | ||
194 | /* set master volume and direct control */ | ||
195 | { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | ||
196 | /* unmute node 0x1b */ | ||
197 | { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | ||
198 | {} | ||
199 | }; | ||
200 | |||
201 | static struct hda_verb d965_2112_core_init[] = { | ||
202 | /* set master volume and direct control */ | ||
203 | { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | ||
204 | /* unmute node 0x1b */ | ||
205 | { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | ||
206 | /* select node 0x03 as DAC */ | ||
207 | { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
208 | {} | ||
209 | }; | ||
210 | |||
176 | static struct hda_verb stac927x_core_init[] = { | 211 | static struct hda_verb stac927x_core_init[] = { |
177 | /* set master volume and direct control */ | 212 | /* set master volume and direct control */ |
178 | { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 213 | { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
@@ -212,6 +247,21 @@ static struct snd_kcontrol_new stac922x_mixer[] = { | |||
212 | { } /* end */ | 247 | { } /* end */ |
213 | }; | 248 | }; |
214 | 249 | ||
250 | /* This needs to be generated dynamically based on sequence */ | ||
251 | static struct snd_kcontrol_new stac9227_mixer[] = { | ||
252 | { | ||
253 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
254 | .name = "Input Source", | ||
255 | .count = 1, | ||
256 | .info = stac92xx_mux_enum_info, | ||
257 | .get = stac92xx_mux_enum_get, | ||
258 | .put = stac92xx_mux_enum_put, | ||
259 | }, | ||
260 | HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), | ||
261 | HDA_CODEC_MUTE("Capture Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
262 | { } /* end */ | ||
263 | }; | ||
264 | |||
215 | static snd_kcontrol_new_t stac927x_mixer[] = { | 265 | static snd_kcontrol_new_t stac927x_mixer[] = { |
216 | { | 266 | { |
217 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 267 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
@@ -291,11 +341,17 @@ static unsigned int d945gtp5_pin_configs[10] = { | |||
291 | 0x02a19320, 0x40000100, | 341 | 0x02a19320, 0x40000100, |
292 | }; | 342 | }; |
293 | 343 | ||
294 | static unsigned int *stac922x_brd_tbl[] = { | 344 | static unsigned int d965_2112_pin_configs[10] = { |
295 | ref922x_pin_configs, | 345 | 0x0221401f, 0x40000100, 0x40000100, 0x01014011, |
296 | d945gtp3_pin_configs, | 346 | 0x01a19021, 0x01813024, 0x01452130, 0x40000100, |
297 | d945gtp5_pin_configs, | 347 | 0x02a19320, 0x40000100, |
298 | NULL, /* STAC_MACMINI */ | 348 | }; |
349 | |||
350 | static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { | ||
351 | [STAC_REF] = ref922x_pin_configs, | ||
352 | [STAC_D945GTP3] = d945gtp3_pin_configs, | ||
353 | [STAC_D945GTP5] = d945gtp5_pin_configs, | ||
354 | [STAC_D965_2112] = d965_2112_pin_configs, | ||
299 | }; | 355 | }; |
300 | 356 | ||
301 | static struct hda_board_config stac922x_cfg_tbl[] = { | 357 | static struct hda_board_config stac922x_cfg_tbl[] = { |
@@ -330,6 +386,12 @@ static struct hda_board_config stac922x_cfg_tbl[] = { | |||
330 | { .pci_subvendor = 0x8384, | 386 | { .pci_subvendor = 0x8384, |
331 | .pci_subdevice = 0x7680, | 387 | .pci_subdevice = 0x7680, |
332 | .config = STAC_MACMINI }, /* Apple Mac Mini (early 2006) */ | 388 | .config = STAC_MACMINI }, /* Apple Mac Mini (early 2006) */ |
389 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
390 | .pci_subdevice = 0x2112, | ||
391 | .config = STAC_D965_2112 }, | ||
392 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
393 | .pci_subdevice = 0x284b, | ||
394 | .config = STAC_D965_284B }, | ||
333 | {} /* terminator */ | 395 | {} /* terminator */ |
334 | }; | 396 | }; |
335 | 397 | ||
@@ -713,7 +775,8 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf | |||
713 | * A and B is not supported. | 775 | * A and B is not supported. |
714 | */ | 776 | */ |
715 | /* fill in the dac_nids table from the parsed pin configuration */ | 777 | /* fill in the dac_nids table from the parsed pin configuration */ |
716 | static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, const struct auto_pin_cfg *cfg) | 778 | static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, |
779 | const struct auto_pin_cfg *cfg) | ||
717 | { | 780 | { |
718 | struct sigmatel_spec *spec = codec->spec; | 781 | struct sigmatel_spec *spec = codec->spec; |
719 | hda_nid_t nid; | 782 | hda_nid_t nid; |
@@ -732,10 +795,13 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, const struct aut | |||
732 | } | 795 | } |
733 | 796 | ||
734 | /* add playback controls from the parsed DAC table */ | 797 | /* add playback controls from the parsed DAC table */ |
735 | static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec *spec, const struct auto_pin_cfg *cfg) | 798 | static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec *spec, |
799 | const struct auto_pin_cfg *cfg) | ||
736 | { | 800 | { |
737 | char name[32]; | 801 | char name[32]; |
738 | static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; | 802 | static const char *chname[4] = { |
803 | "Front", "Surround", NULL /*CLFE*/, "Side" | ||
804 | }; | ||
739 | hda_nid_t nid; | 805 | hda_nid_t nid; |
740 | int i, err; | 806 | int i, err; |
741 | 807 | ||
@@ -893,10 +959,12 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
893 | return err; | 959 | return err; |
894 | if (! spec->autocfg.line_outs) | 960 | if (! spec->autocfg.line_outs) |
895 | return 0; /* can't find valid pin config */ | 961 | return 0; /* can't find valid pin config */ |
962 | |||
896 | if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0) | 963 | if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0) |
897 | return err; | 964 | return err; |
898 | if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0) | 965 | if (spec->multiout.num_dacs == 0) |
899 | return err; | 966 | if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0) |
967 | return err; | ||
900 | 968 | ||
901 | if ((err = stac92xx_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || | 969 | if ((err = stac92xx_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || |
902 | (err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg)) < 0 || | 970 | (err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg)) < 0 || |
@@ -1194,7 +1262,8 @@ static int patch_stac922x(struct hda_codec *codec) | |||
1194 | codec->spec = spec; | 1262 | codec->spec = spec; |
1195 | spec->board_config = snd_hda_check_board_config(codec, stac922x_cfg_tbl); | 1263 | spec->board_config = snd_hda_check_board_config(codec, stac922x_cfg_tbl); |
1196 | if (spec->board_config < 0) | 1264 | if (spec->board_config < 0) |
1197 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, using BIOS defaults\n"); | 1265 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, " |
1266 | "using BIOS defaults\n"); | ||
1198 | else if (stac922x_brd_tbl[spec->board_config] != NULL) { | 1267 | else if (stac922x_brd_tbl[spec->board_config] != NULL) { |
1199 | spec->num_pins = 10; | 1268 | spec->num_pins = 10; |
1200 | spec->pin_nids = stac922x_pin_nids; | 1269 | spec->pin_nids = stac922x_pin_nids; |
@@ -1210,6 +1279,25 @@ static int patch_stac922x(struct hda_codec *codec) | |||
1210 | spec->mixer = stac922x_mixer; | 1279 | spec->mixer = stac922x_mixer; |
1211 | 1280 | ||
1212 | spec->multiout.dac_nids = spec->dac_nids; | 1281 | spec->multiout.dac_nids = spec->dac_nids; |
1282 | |||
1283 | switch (spec->board_config) { | ||
1284 | case STAC_D965_2112: | ||
1285 | spec->adc_nids = stac9227_adc_nids; | ||
1286 | spec->mux_nids = stac9227_mux_nids; | ||
1287 | #if 0 | ||
1288 | spec->multiout.dac_nids = d965_2112_dac_nids; | ||
1289 | spec->multiout.num_dacs = ARRAY_SIZE(d965_2112_dac_nids); | ||
1290 | #endif | ||
1291 | spec->init = d965_2112_core_init; | ||
1292 | spec->mixer = stac9227_mixer; | ||
1293 | break; | ||
1294 | case STAC_D965_284B: | ||
1295 | spec->adc_nids = stac9227_adc_nids; | ||
1296 | spec->mux_nids = stac9227_mux_nids; | ||
1297 | spec->init = stac9227_core_init; | ||
1298 | spec->mixer = stac9227_mixer; | ||
1299 | break; | ||
1300 | } | ||
1213 | 1301 | ||
1214 | err = stac92xx_parse_auto_config(codec, 0x08, 0x09); | 1302 | err = stac92xx_parse_auto_config(codec, 0x08, 0x09); |
1215 | if (err < 0) { | 1303 | if (err < 0) { |
diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c index b5754b32b802..fec9440cb310 100644 --- a/sound/pci/ice1712/revo.c +++ b/sound/pci/ice1712/revo.c | |||
@@ -87,12 +87,25 @@ static void revo_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) | |||
87 | * initialize the chips on M-Audio Revolution cards | 87 | * initialize the chips on M-Audio Revolution cards |
88 | */ | 88 | */ |
89 | 89 | ||
90 | static unsigned int revo71_num_stereo_front[] = {2}; | ||
91 | static char *revo71_channel_names_front[] = {"PCM Playback Volume"}; | ||
92 | |||
93 | static unsigned int revo71_num_stereo_surround[] = {1, 1, 2, 2}; | ||
94 | static char *revo71_channel_names_surround[] = {"PCM Center Playback Volume", "PCM LFE Playback Volume", | ||
95 | "PCM Side Playback Volume", "PCM Rear Playback Volume"}; | ||
96 | |||
97 | static unsigned int revo51_num_stereo[] = {2, 1, 1, 2}; | ||
98 | static char *revo51_channel_names[] = {"PCM Playback Volume", "PCM Center Playback Volume", | ||
99 | "PCM LFE Playback Volume", "PCM Rear Playback Volume"}; | ||
100 | |||
90 | static struct snd_akm4xxx akm_revo_front __devinitdata = { | 101 | static struct snd_akm4xxx akm_revo_front __devinitdata = { |
91 | .type = SND_AK4381, | 102 | .type = SND_AK4381, |
92 | .num_dacs = 2, | 103 | .num_dacs = 2, |
93 | .ops = { | 104 | .ops = { |
94 | .set_rate_val = revo_set_rate_val | 105 | .set_rate_val = revo_set_rate_val |
95 | } | 106 | }, |
107 | .num_stereo = revo71_num_stereo_front, | ||
108 | .channel_names = revo71_channel_names_front | ||
96 | }; | 109 | }; |
97 | 110 | ||
98 | static struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = { | 111 | static struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = { |
@@ -113,7 +126,9 @@ static struct snd_akm4xxx akm_revo_surround __devinitdata = { | |||
113 | .num_dacs = 6, | 126 | .num_dacs = 6, |
114 | .ops = { | 127 | .ops = { |
115 | .set_rate_val = revo_set_rate_val | 128 | .set_rate_val = revo_set_rate_val |
116 | } | 129 | }, |
130 | .num_stereo = revo71_num_stereo_surround, | ||
131 | .channel_names = revo71_channel_names_surround | ||
117 | }; | 132 | }; |
118 | 133 | ||
119 | static struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = { | 134 | static struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = { |
@@ -133,7 +148,9 @@ static struct snd_akm4xxx akm_revo51 __devinitdata = { | |||
133 | .num_dacs = 6, | 148 | .num_dacs = 6, |
134 | .ops = { | 149 | .ops = { |
135 | .set_rate_val = revo_set_rate_val | 150 | .set_rate_val = revo_set_rate_val |
136 | } | 151 | }, |
152 | .num_stereo = revo51_num_stereo, | ||
153 | .channel_names = revo51_channel_names | ||
137 | }; | 154 | }; |
138 | 155 | ||
139 | static struct snd_ak4xxx_private akm_revo51_priv __devinitdata = { | 156 | static struct snd_ak4xxx_private akm_revo51_priv __devinitdata = { |
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c index dcf402948347..e5511606af04 100644 --- a/sound/pci/sonicvibes.c +++ b/sound/pci/sonicvibes.c | |||
@@ -1441,10 +1441,10 @@ static int __devinit snd_sonic_probe(struct pci_dev *pci, | |||
1441 | 1441 | ||
1442 | strcpy(card->driver, "SonicVibes"); | 1442 | strcpy(card->driver, "SonicVibes"); |
1443 | strcpy(card->shortname, "S3 SonicVibes"); | 1443 | strcpy(card->shortname, "S3 SonicVibes"); |
1444 | sprintf(card->longname, "%s rev %i at 0x%lx, irq %i", | 1444 | sprintf(card->longname, "%s rev %i at 0x%llx, irq %i", |
1445 | card->shortname, | 1445 | card->shortname, |
1446 | sonic->revision, | 1446 | sonic->revision, |
1447 | pci_resource_start(pci, 1), | 1447 | (unsigned long long)pci_resource_start(pci, 1), |
1448 | sonic->irq); | 1448 | sonic->irq); |
1449 | 1449 | ||
1450 | if ((err = snd_sonicvibes_pcm(sonic, 0, NULL)) < 0) { | 1450 | if ((err = snd_sonicvibes_pcm(sonic, 0, NULL)) < 0) { |
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c index b678814975c9..be98f6377339 100644 --- a/sound/ppc/pmac.c +++ b/sound/ppc/pmac.c | |||
@@ -1170,9 +1170,10 @@ int __init snd_pmac_new(struct snd_card *card, struct snd_pmac **chip_return) | |||
1170 | chip->rsrc[i].start + 1, | 1170 | chip->rsrc[i].start + 1, |
1171 | rnames[i]) == NULL) { | 1171 | rnames[i]) == NULL) { |
1172 | printk(KERN_ERR "snd: can't request rsrc " | 1172 | printk(KERN_ERR "snd: can't request rsrc " |
1173 | " %d (%s: 0x%08lx:%08lx)\n", | 1173 | " %d (%s: 0x%016lx:%016lx)\n", |
1174 | i, rnames[i], chip->rsrc[i].start, | 1174 | i, rnames[i], |
1175 | chip->rsrc[i].end); | 1175 | (unsigned long long)chip->rsrc[i].start, |
1176 | (unsigned long long)chip->rsrc[i].end); | ||
1176 | err = -ENODEV; | 1177 | err = -ENODEV; |
1177 | goto __error; | 1178 | goto __error; |
1178 | } | 1179 | } |
@@ -1201,9 +1202,10 @@ int __init snd_pmac_new(struct snd_card *card, struct snd_pmac **chip_return) | |||
1201 | chip->rsrc[i].start + 1, | 1202 | chip->rsrc[i].start + 1, |
1202 | rnames[i]) == NULL) { | 1203 | rnames[i]) == NULL) { |
1203 | printk(KERN_ERR "snd: can't request rsrc " | 1204 | printk(KERN_ERR "snd: can't request rsrc " |
1204 | " %d (%s: 0x%08lx:%08lx)\n", | 1205 | " %d (%s: 0x%016llx:%016llx)\n", |
1205 | i, rnames[i], chip->rsrc[i].start, | 1206 | i, rnames[i], |
1206 | chip->rsrc[i].end); | 1207 | (unsigned long long)chip->rsrc[i].start, |
1208 | (unsigned long long)chip->rsrc[i].end); | ||
1207 | err = -ENODEV; | 1209 | err = -ENODEV; |
1208 | goto __error; | 1210 | goto __error; |
1209 | } | 1211 | } |
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index da54d04a3e3a..d9d14c2707db 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c | |||
@@ -2037,10 +2037,10 @@ static int __init cs4231_sbus_attach(struct sbus_dev *sdev) | |||
2037 | if (err) | 2037 | if (err) |
2038 | return err; | 2038 | return err; |
2039 | 2039 | ||
2040 | sprintf(card->longname, "%s at 0x%02lx:0x%08lx, irq %d", | 2040 | sprintf(card->longname, "%s at 0x%02lx:0x%016lx, irq %d", |
2041 | card->shortname, | 2041 | card->shortname, |
2042 | rp->flags & 0xffL, | 2042 | rp->flags & 0xffL, |
2043 | rp->start, | 2043 | (unsigned long long)rp->start, |
2044 | sdev->irqs[0]); | 2044 | sdev->irqs[0]); |
2045 | 2045 | ||
2046 | if ((err = snd_cs4231_sbus_create(card, sdev, dev, &cp)) < 0) { | 2046 | if ((err = snd_cs4231_sbus_create(card, sdev, dev, &cp)) < 0) { |
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c index 5eecdd09a79d..a7489a3dd75a 100644 --- a/sound/sparc/dbri.c +++ b/sound/sparc/dbri.c | |||
@@ -2645,9 +2645,9 @@ static int __init dbri_attach(int prom_node, struct sbus_dev *sdev) | |||
2645 | strcpy(card->driver, "DBRI"); | 2645 | strcpy(card->driver, "DBRI"); |
2646 | strcpy(card->shortname, "Sun DBRI"); | 2646 | strcpy(card->shortname, "Sun DBRI"); |
2647 | rp = &sdev->resource[0]; | 2647 | rp = &sdev->resource[0]; |
2648 | sprintf(card->longname, "%s at 0x%02lx:0x%08lx, irq %d", | 2648 | sprintf(card->longname, "%s at 0x%02lx:0x%016lx, irq %d", |
2649 | card->shortname, | 2649 | card->shortname, |
2650 | rp->flags & 0xffL, rp->start, irq.pri); | 2650 | rp->flags & 0xffL, (unsigned long long)rp->start, irq.pri); |
2651 | 2651 | ||
2652 | if ((err = snd_dbri_create(card, sdev, &irq, dev)) < 0) { | 2652 | if ((err = snd_dbri_create(card, sdev, &irq, dev)) < 0) { |
2653 | snd_card_free(card); | 2653 | snd_card_free(card); |
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 627de9525a32..d32d83d970cc 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c | |||
@@ -3096,6 +3096,32 @@ static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev) | |||
3096 | } | 3096 | } |
3097 | 3097 | ||
3098 | /* | 3098 | /* |
3099 | * C-Media CM106/CM106+ have four 16-bit internal registers that are nicely | ||
3100 | * documented in the device's data sheet. | ||
3101 | */ | ||
3102 | static int snd_usb_cm106_write_int_reg(struct usb_device *dev, int reg, u16 value) | ||
3103 | { | ||
3104 | u8 buf[4]; | ||
3105 | buf[0] = 0x20; | ||
3106 | buf[1] = value & 0xff; | ||
3107 | buf[2] = (value >> 8) & 0xff; | ||
3108 | buf[3] = reg; | ||
3109 | return snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_CONFIGURATION, | ||
3110 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT, | ||
3111 | 0, 0, &buf, 4, 1000); | ||
3112 | } | ||
3113 | |||
3114 | static int snd_usb_cm106_boot_quirk(struct usb_device *dev) | ||
3115 | { | ||
3116 | /* | ||
3117 | * Enable line-out driver mode, set headphone source to front | ||
3118 | * channels, enable stereo mic. | ||
3119 | */ | ||
3120 | return snd_usb_cm106_write_int_reg(dev, 2, 0x8004); | ||
3121 | } | ||
3122 | |||
3123 | |||
3124 | /* | ||
3099 | * Setup quirks | 3125 | * Setup quirks |
3100 | */ | 3126 | */ |
3101 | #define AUDIOPHILE_SET 0x01 /* if set, parse device_setup */ | 3127 | #define AUDIOPHILE_SET 0x01 /* if set, parse device_setup */ |
@@ -3365,6 +3391,12 @@ static void *snd_usb_audio_probe(struct usb_device *dev, | |||
3365 | goto __err_val; | 3391 | goto __err_val; |
3366 | } | 3392 | } |
3367 | 3393 | ||
3394 | /* C-Media CM106 / Turtle Beach Audio Advantage Roadie */ | ||
3395 | if (id == USB_ID(0x10f5, 0x0200)) { | ||
3396 | if (snd_usb_cm106_boot_quirk(dev) < 0) | ||
3397 | goto __err_val; | ||
3398 | } | ||
3399 | |||
3368 | /* | 3400 | /* |
3369 | * found a config. now register to ALSA | 3401 | * found a config. now register to ALSA |
3370 | */ | 3402 | */ |