diff options
431 files changed, 13847 insertions, 4808 deletions
diff --git a/Documentation/DocBook/kernel-locking.tmpl b/Documentation/DocBook/kernel-locking.tmpl index 0a441f73261a..01825ee7db64 100644 --- a/Documentation/DocBook/kernel-locking.tmpl +++ b/Documentation/DocBook/kernel-locking.tmpl | |||
@@ -219,7 +219,7 @@ | |||
219 | </para> | 219 | </para> |
220 | 220 | ||
221 | <sect1 id="lock-intro"> | 221 | <sect1 id="lock-intro"> |
222 | <title>Two Main Types of Kernel Locks: Spinlocks and Semaphores</title> | 222 | <title>Three Main Types of Kernel Locks: Spinlocks, Mutexes and Semaphores</title> |
223 | 223 | ||
224 | <para> | 224 | <para> |
225 | There are three main types of kernel locks. The fundamental type | 225 | There are three main types of kernel locks. The fundamental type |
diff --git a/Documentation/DocBook/libata.tmpl b/Documentation/DocBook/libata.tmpl index e2e24b4778d4..ba9975771503 100644 --- a/Documentation/DocBook/libata.tmpl +++ b/Documentation/DocBook/libata.tmpl | |||
@@ -456,8 +456,9 @@ void (*irq_clear) (struct ata_port *); | |||
456 | 456 | ||
457 | <sect2><title>SATA phy read/write</title> | 457 | <sect2><title>SATA phy read/write</title> |
458 | <programlisting> | 458 | <programlisting> |
459 | u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg); | 459 | int (*scr_read) (struct ata_port *ap, unsigned int sc_reg, |
460 | void (*scr_write) (struct ata_port *ap, unsigned int sc_reg, | 460 | u32 *val); |
461 | int (*scr_write) (struct ata_port *ap, unsigned int sc_reg, | ||
461 | u32 val); | 462 | u32 val); |
462 | </programlisting> | 463 | </programlisting> |
463 | 464 | ||
diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index 3f9a7912e69b..d6b45a9b29b4 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches | |||
@@ -122,7 +122,7 @@ then only post say 15 or so at a time and wait for review and integration. | |||
122 | 122 | ||
123 | Check your patch for basic style violations, details of which can be | 123 | Check your patch for basic style violations, details of which can be |
124 | found in Documentation/CodingStyle. Failure to do so simply wastes | 124 | found in Documentation/CodingStyle. Failure to do so simply wastes |
125 | the reviewers time and will get your patch rejected, probabally | 125 | the reviewers time and will get your patch rejected, probably |
126 | without even being read. | 126 | without even being read. |
127 | 127 | ||
128 | At a minimum you should check your patches with the patch style | 128 | At a minimum you should check your patches with the patch style |
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index a5cb7839a679..c175eedadb5f 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -180,24 +180,11 @@ Who: Adrian Bunk <bunk@stusta.de> | |||
180 | 180 | ||
181 | --------------------------- | 181 | --------------------------- |
182 | 182 | ||
183 | What: /sys/firmware/acpi/namespace | ||
184 | When: 2.6.21 | ||
185 | Why: The ACPI namespace is effectively the symbol list for | ||
186 | the BIOS. The device names are completely arbitrary | ||
187 | and have no place being exposed to user-space. | ||
188 | |||
189 | For those interested in the BIOS ACPI namespace, | ||
190 | the BIOS can be extracted and disassembled with acpidump | ||
191 | and iasl as documented in the pmtools package here: | ||
192 | http://ftp.kernel.org/pub/linux/kernel/people/lenb/acpi/utils | ||
193 | Who: Len Brown <len.brown@intel.com> | ||
194 | |||
195 | --------------------------- | ||
196 | |||
197 | What: ACPI procfs interface | 183 | What: ACPI procfs interface |
198 | When: July 2007 | 184 | When: July 2008 |
199 | Why: After ACPI sysfs conversion, ACPI attributes will be duplicated | 185 | Why: ACPI sysfs conversion should be finished by January 2008. |
200 | in sysfs and the ACPI procfs interface should be removed. | 186 | ACPI procfs interface will be removed in July 2008 so that |
187 | there is enough time for the user space to catch up. | ||
201 | Who: Zhang Rui <rui.zhang@intel.com> | 188 | Who: Zhang Rui <rui.zhang@intel.com> |
202 | 189 | ||
203 | --------------------------- | 190 | --------------------------- |
diff --git a/Documentation/thinkpad-acpi.txt b/Documentation/thinkpad-acpi.txt index 9e6b94face4b..6711fbcf4080 100644 --- a/Documentation/thinkpad-acpi.txt +++ b/Documentation/thinkpad-acpi.txt | |||
@@ -1,11 +1,11 @@ | |||
1 | ThinkPad ACPI Extras Driver | 1 | ThinkPad ACPI Extras Driver |
2 | 2 | ||
3 | Version 0.14 | 3 | Version 0.15 |
4 | April 21st, 2007 | 4 | July 1st, 2007 |
5 | 5 | ||
6 | Borislav Deianov <borislav@users.sf.net> | 6 | Borislav Deianov <borislav@users.sf.net> |
7 | Henrique de Moraes Holschuh <hmh@hmh.eng.br> | 7 | Henrique de Moraes Holschuh <hmh@hmh.eng.br> |
8 | http://ibm-acpi.sf.net/ | 8 | http://ibm-acpi.sf.net/ |
9 | 9 | ||
10 | 10 | ||
11 | This is a Linux driver for the IBM and Lenovo ThinkPad laptops. It | 11 | This is a Linux driver for the IBM and Lenovo ThinkPad laptops. It |
@@ -134,54 +134,68 @@ end of this document. Changes to the sysfs interface done by the kernel | |||
134 | subsystems are not documented here, nor are they tracked by this | 134 | subsystems are not documented here, nor are they tracked by this |
135 | attribute. | 135 | attribute. |
136 | 136 | ||
137 | Changes to the thinkpad-acpi sysfs interface are only considered | ||
138 | non-experimental when they are submitted to Linux mainline, at which | ||
139 | point the changes in this interface are documented and interface_version | ||
140 | may be updated. If you are using any thinkpad-acpi features not yet | ||
141 | sent to mainline for merging, you do so on your own risk: these features | ||
142 | may disappear, or be implemented in a different and incompatible way by | ||
143 | the time they are merged in Linux mainline. | ||
144 | |||
145 | Changes that are backwards-compatible by nature (e.g. the addition of | ||
146 | attributes that do not change the way the other attributes work) do not | ||
147 | always warrant an update of interface_version. Therefore, one must | ||
148 | expect that an attribute might not be there, and deal with it properly | ||
149 | (an attribute not being there *is* a valid way to make it clear that a | ||
150 | feature is not available in sysfs). | ||
151 | |||
137 | Hot keys | 152 | Hot keys |
138 | -------- | 153 | -------- |
139 | 154 | ||
140 | procfs: /proc/acpi/ibm/hotkey | 155 | procfs: /proc/acpi/ibm/hotkey |
141 | sysfs device attribute: hotkey_* | 156 | sysfs device attribute: hotkey_* |
142 | 157 | ||
143 | Without this driver, only the Fn-F4 key (sleep button) generates an | 158 | In a ThinkPad, the ACPI HKEY handler is responsible for comunicating |
144 | ACPI event. With the driver loaded, the hotkey feature enabled and the | 159 | some important events and also keyboard hot key presses to the operating |
145 | mask set (see below), the various hot keys generate ACPI events in the | 160 | system. Enabling the hotkey functionality of thinkpad-acpi signals the |
161 | firmware that such a driver is present, and modifies how the ThinkPad | ||
162 | firmware will behave in many situations. | ||
163 | |||
164 | When the hotkey feature is enabled and the hot key mask is set (see | ||
165 | below), the various hot keys either generate ACPI events in the | ||
146 | following format: | 166 | following format: |
147 | 167 | ||
148 | ibm/hotkey HKEY 00000080 0000xxxx | 168 | ibm/hotkey HKEY 00000080 0000xxxx |
149 | 169 | ||
150 | The last four digits vary depending on the key combination pressed. | 170 | or events over the input layer. The input layer support accepts the |
151 | All labeled Fn-Fx key combinations generate distinct events. In | 171 | standard IOCTLs to remap the keycodes assigned to each hotkey. |
152 | addition, the lid microswitch and some docking station buttons may | 172 | |
153 | also generate such events. | 173 | When the input device is open, the driver will suppress any ACPI hot key |
154 | 174 | events that get translated into a meaningful input layer event, in order | |
155 | The bit mask allows some control over which hot keys generate ACPI | 175 | to avoid sending duplicate events to userspace. Hot keys that are |
156 | events. Not all bits in the mask can be modified. Not all bits that | 176 | mapped to KEY_RESERVED in the keymap are not translated, and will always |
157 | can be modified do anything. Not all hot keys can be individually | 177 | generate an ACPI ibm/hotkey HKEY event, and no input layer events. |
158 | controlled by the mask. Most recent ThinkPad models honor the | 178 | |
159 | following bits (assuming the hot keys feature has been enabled): | 179 | The hot key bit mask allows some control over which hot keys generate |
160 | 180 | events. If a key is "masked" (bit set to 0 in the mask), the firmware | |
161 | key bit behavior when set behavior when unset | 181 | will handle it. If it is "unmasked", it signals the firmware that |
162 | 182 | thinkpad-acpi would prefer to handle it, if the firmware would be so | |
163 | Fn-F3 always generates ACPI event | 183 | kind to allow it (and it often doesn't!). |
164 | Fn-F4 always generates ACPI event | 184 | |
165 | Fn-F5 0010 generate ACPI event enable/disable Bluetooth | 185 | Not all bits in the mask can be modified. Not all bits that can be |
166 | Fn-F7 0040 generate ACPI event switch LCD and external display | 186 | modified do anything. Not all hot keys can be individually controlled |
167 | Fn-F8 0080 generate ACPI event expand screen or none | 187 | by the mask. Some models do not support the mask at all, and in those |
168 | Fn-F9 0100 generate ACPI event none | 188 | models, hot keys cannot be controlled individually. The behaviour of |
169 | Fn-F12 always generates ACPI event | 189 | the mask is, therefore, higly dependent on the ThinkPad model. |
170 | 190 | ||
171 | Some models do not support all of the above. For example, the T30 does | 191 | Note that unmasking some keys prevents their default behavior. For |
172 | not support Fn-F5 and Fn-F9. Other models do not support the mask at | 192 | example, if Fn+F5 is unmasked, that key will no longer enable/disable |
173 | all. On those models, hot keys cannot be controlled individually. | 193 | Bluetooth by itself. |
174 | 194 | ||
175 | Note that enabling ACPI events for some keys prevents their default | 195 | Note also that not all Fn key combinations are supported through ACPI. |
176 | behavior. For example, if events for Fn-F5 are enabled, that key will | 196 | For example, on the X40, the brightness, volume and "Access IBM" buttons |
177 | no longer enable/disable Bluetooth by itself. This can still be done | 197 | do not generate ACPI events even with this driver. They *can* be used |
178 | from an acpid handler for the ibm/hotkey event. | 198 | through the "ThinkPad Buttons" utility, see http://www.nongnu.org/tpb/ |
179 | |||
180 | Note also that not all Fn key combinations are supported through | ||
181 | ACPI. For example, on the X40, the brightness, volume and "Access IBM" | ||
182 | buttons do not generate ACPI events even with this driver. They *can* | ||
183 | be used through the "ThinkPad Buttons" utility, see | ||
184 | http://www.nongnu.org/tpb/ | ||
185 | 199 | ||
186 | procfs notes: | 200 | procfs notes: |
187 | 201 | ||
@@ -189,9 +203,9 @@ The following commands can be written to the /proc/acpi/ibm/hotkey file: | |||
189 | 203 | ||
190 | echo enable > /proc/acpi/ibm/hotkey -- enable the hot keys feature | 204 | echo enable > /proc/acpi/ibm/hotkey -- enable the hot keys feature |
191 | echo disable > /proc/acpi/ibm/hotkey -- disable the hot keys feature | 205 | echo disable > /proc/acpi/ibm/hotkey -- disable the hot keys feature |
192 | echo 0xffff > /proc/acpi/ibm/hotkey -- enable all possible hot keys | 206 | echo 0xffffffff > /proc/acpi/ibm/hotkey -- enable all hot keys |
193 | echo 0x0000 > /proc/acpi/ibm/hotkey -- disable all possible hot keys | 207 | echo 0 > /proc/acpi/ibm/hotkey -- disable all possible hot keys |
194 | ... any other 4-hex-digit mask ... | 208 | ... any other 8-hex-digit mask ... |
195 | echo reset > /proc/acpi/ibm/hotkey -- restore the original mask | 209 | echo reset > /proc/acpi/ibm/hotkey -- restore the original mask |
196 | 210 | ||
197 | sysfs notes: | 211 | sysfs notes: |
@@ -202,7 +216,7 @@ sysfs notes: | |||
202 | key feature status will be restored to this value. | 216 | key feature status will be restored to this value. |
203 | 217 | ||
204 | 0: hot keys were disabled | 218 | 0: hot keys were disabled |
205 | 1: hot keys were enabled | 219 | 1: hot keys were enabled (unusual) |
206 | 220 | ||
207 | hotkey_bios_mask: | 221 | hotkey_bios_mask: |
208 | Returns the hot keys mask when thinkpad-acpi was loaded. | 222 | Returns the hot keys mask when thinkpad-acpi was loaded. |
@@ -217,9 +231,182 @@ sysfs notes: | |||
217 | 1: enables the hot keys feature / feature enabled | 231 | 1: enables the hot keys feature / feature enabled |
218 | 232 | ||
219 | hotkey_mask: | 233 | hotkey_mask: |
220 | bit mask to enable ACPI event generation for each hot | 234 | bit mask to enable driver-handling and ACPI event |
221 | key (see above). Returns the current status of the hot | 235 | generation for each hot key (see above). Returns the |
222 | keys mask, and allows one to modify it. | 236 | current status of the hot keys mask, and allows one to |
237 | modify it. | ||
238 | |||
239 | hotkey_all_mask: | ||
240 | bit mask that should enable event reporting for all | ||
241 | supported hot keys, when echoed to hotkey_mask above. | ||
242 | Unless you know which events need to be handled | ||
243 | passively (because the firmware *will* handle them | ||
244 | anyway), do *not* use hotkey_all_mask. Use | ||
245 | hotkey_recommended_mask, instead. You have been warned. | ||
246 | |||
247 | hotkey_recommended_mask: | ||
248 | bit mask that should enable event reporting for all | ||
249 | supported hot keys, except those which are always | ||
250 | handled by the firmware anyway. Echo it to | ||
251 | hotkey_mask above, to use. | ||
252 | |||
253 | hotkey_radio_sw: | ||
254 | if the ThinkPad has a hardware radio switch, this | ||
255 | attribute will read 0 if the switch is in the "radios | ||
256 | disabled" postition, and 1 if the switch is in the | ||
257 | "radios enabled" position. | ||
258 | |||
259 | input layer notes: | ||
260 | |||
261 | A Hot key is mapped to a single input layer EV_KEY event, possibly | ||
262 | followed by an EV_MSC MSC_SCAN event that shall contain that key's scan | ||
263 | code. An EV_SYN event will always be generated to mark the end of the | ||
264 | event block. | ||
265 | |||
266 | Do not use the EV_MSC MSC_SCAN events to process keys. They are to be | ||
267 | used as a helper to remap keys, only. They are particularly useful when | ||
268 | remapping KEY_UNKNOWN keys. | ||
269 | |||
270 | The events are available in an input device, with the following id: | ||
271 | |||
272 | Bus: BUS_HOST | ||
273 | vendor: 0x1014 (PCI_VENDOR_ID_IBM) or | ||
274 | 0x17aa (PCI_VENDOR_ID_LENOVO) | ||
275 | product: 0x5054 ("TP") | ||
276 | version: 0x4101 | ||
277 | |||
278 | The version will have its LSB incremented if the keymap changes in a | ||
279 | backwards-compatible way. The MSB shall always be 0x41 for this input | ||
280 | device. If the MSB is not 0x41, do not use the device as described in | ||
281 | this section, as it is either something else (e.g. another input device | ||
282 | exported by a thinkpad driver, such as HDAPS) or its functionality has | ||
283 | been changed in a non-backwards compatible way. | ||
284 | |||
285 | Adding other event types for other functionalities shall be considered a | ||
286 | backwards-compatible change for this input device. | ||
287 | |||
288 | Thinkpad-acpi Hot Key event map (version 0x4101): | ||
289 | |||
290 | ACPI Scan | ||
291 | event code Key Notes | ||
292 | |||
293 | 0x1001 0x00 FN+F1 - | ||
294 | 0x1002 0x01 FN+F2 IBM: battery (rare) | ||
295 | Lenovo: Screen lock | ||
296 | |||
297 | 0x1003 0x02 FN+F3 Many IBM models always report | ||
298 | this hot key, even with hot keys | ||
299 | disabled or with Fn+F3 masked | ||
300 | off | ||
301 | IBM: screen lock | ||
302 | Lenovo: battery | ||
303 | |||
304 | 0x1004 0x03 FN+F4 Sleep button (ACPI sleep button | ||
305 | semanthics, i.e. sleep-to-RAM). | ||
306 | It is always generate some kind | ||
307 | of event, either the hot key | ||
308 | event or a ACPI sleep button | ||
309 | event. The firmware may | ||
310 | refuse to generate further FN+F4 | ||
311 | key presses until a S3 or S4 ACPI | ||
312 | sleep cycle is performed or some | ||
313 | time passes. | ||
314 | |||
315 | 0x1005 0x04 FN+F5 Radio. Enables/disables | ||
316 | the internal BlueTooth hardware | ||
317 | and W-WAN card if left in control | ||
318 | of the firmware. Does not affect | ||
319 | the WLAN card. | ||
320 | Should be used to turn on/off all | ||
321 | radios (bluetooth+W-WAN+WLAN), | ||
322 | really. | ||
323 | |||
324 | 0x1006 0x05 FN+F6 - | ||
325 | |||
326 | 0x1007 0x06 FN+F7 Video output cycle. | ||
327 | Do you feel lucky today? | ||
328 | |||
329 | 0x1008 0x07 FN+F8 IBM: toggle screen expand | ||
330 | Lenovo: configure ultranav | ||
331 | |||
332 | 0x1009 0x08 FN+F9 - | ||
333 | .. .. .. | ||
334 | 0x100B 0x0A FN+F11 - | ||
335 | |||
336 | 0x100C 0x0B FN+F12 Sleep to disk. You are always | ||
337 | supposed to handle it yourself, | ||
338 | either through the ACPI event, | ||
339 | or through a hotkey event. | ||
340 | The firmware may refuse to | ||
341 | generate further FN+F4 key | ||
342 | press events until a S3 or S4 | ||
343 | ACPI sleep cycle is performed, | ||
344 | or some time passes. | ||
345 | |||
346 | 0x100D 0x0C FN+BACKSPACE - | ||
347 | 0x100E 0x0D FN+INSERT - | ||
348 | 0x100F 0x0E FN+DELETE - | ||
349 | |||
350 | 0x1010 0x0F FN+HOME Brightness up. This key is | ||
351 | always handled by the firmware | ||
352 | in IBM ThinkPads, even when | ||
353 | unmasked. Just leave it alone. | ||
354 | For Lenovo ThinkPads with a new | ||
355 | BIOS, it has to be handled either | ||
356 | by the ACPI OSI, or by userspace. | ||
357 | 0x1011 0x10 FN+END Brightness down. See brightness | ||
358 | up for details. | ||
359 | |||
360 | 0x1012 0x11 FN+PGUP Thinklight toggle. This key is | ||
361 | always handled by the firmware, | ||
362 | even when unmasked. | ||
363 | |||
364 | 0x1013 0x12 FN+PGDOWN - | ||
365 | |||
366 | 0x1014 0x13 FN+SPACE Zoom key | ||
367 | |||
368 | 0x1015 0x14 VOLUME UP Internal mixer volume up. This | ||
369 | key is always handled by the | ||
370 | firmware, even when unmasked. | ||
371 | NOTE: Lenovo seems to be changing | ||
372 | this. | ||
373 | 0x1016 0x15 VOLUME DOWN Internal mixer volume up. This | ||
374 | key is always handled by the | ||
375 | firmware, even when unmasked. | ||
376 | NOTE: Lenovo seems to be changing | ||
377 | this. | ||
378 | 0x1017 0x16 MUTE Mute internal mixer. This | ||
379 | key is always handled by the | ||
380 | firmware, even when unmasked. | ||
381 | |||
382 | 0x1018 0x17 THINKPAD Thinkpad/Access IBM/Lenovo key | ||
383 | |||
384 | 0x1019 0x18 unknown | ||
385 | .. .. .. | ||
386 | 0x1020 0x1F unknown | ||
387 | |||
388 | The ThinkPad firmware does not allow one to differentiate when most hot | ||
389 | keys are pressed or released (either that, or we don't know how to, yet). | ||
390 | For these keys, the driver generates a set of events for a key press and | ||
391 | immediately issues the same set of events for a key release. It is | ||
392 | unknown by the driver if the ThinkPad firmware triggered these events on | ||
393 | hot key press or release, but the firmware will do it for either one, not | ||
394 | both. | ||
395 | |||
396 | If a key is mapped to KEY_RESERVED, it generates no input events at all, | ||
397 | and it may generate a legacy thinkpad-acpi ACPI hotkey event. | ||
398 | |||
399 | If a key is mapped to KEY_UNKNOWN, it generates an input event that | ||
400 | includes an scan code, and it may also generate a legacy thinkpad-acpi | ||
401 | ACPI hotkey event. | ||
402 | |||
403 | If a key is mapped to anything else, it will only generate legacy | ||
404 | thinkpad-acpi ACPI hotkey events if nobody has opened the input device. | ||
405 | |||
406 | Non hot-key ACPI HKEY event map: | ||
407 | 0x5001 Lid closed | ||
408 | 0x5002 Lid opened | ||
409 | 0x7000 Radio Switch may have changed state | ||
223 | 410 | ||
224 | 411 | ||
225 | Bluetooth | 412 | Bluetooth |
@@ -437,27 +624,34 @@ CMOS control | |||
437 | procfs: /proc/acpi/ibm/cmos | 624 | procfs: /proc/acpi/ibm/cmos |
438 | sysfs device attribute: cmos_command | 625 | sysfs device attribute: cmos_command |
439 | 626 | ||
440 | This feature is used internally by the ACPI firmware to control the | 627 | This feature is mostly used internally by the ACPI firmware to keep the legacy |
441 | ThinkLight on most newer ThinkPad models. It may also control LCD | 628 | CMOS NVRAM bits in sync with the current machine state, and to record this |
442 | brightness, sounds volume and more, but only on some models. | 629 | state so that the ThinkPad will retain such settings across reboots. |
630 | |||
631 | Some of these commands actually perform actions in some ThinkPad models, but | ||
632 | this is expected to disappear more and more in newer models. As an example, in | ||
633 | a T43 and in a X40, commands 12 and 13 still control the ThinkLight state for | ||
634 | real, but commands 0 to 2 don't control the mixer anymore (they have been | ||
635 | phased out) and just update the NVRAM. | ||
443 | 636 | ||
444 | The range of valid cmos command numbers is 0 to 21, but not all have an | 637 | The range of valid cmos command numbers is 0 to 21, but not all have an |
445 | effect and the behavior varies from model to model. Here is the behavior | 638 | effect and the behavior varies from model to model. Here is the behavior |
446 | on the X40 (tpb is the ThinkPad Buttons utility): | 639 | on the X40 (tpb is the ThinkPad Buttons utility): |
447 | 640 | ||
448 | 0 - no effect but tpb reports "Volume down" | 641 | 0 - Related to "Volume down" key press |
449 | 1 - no effect but tpb reports "Volume up" | 642 | 1 - Related to "Volume up" key press |
450 | 2 - no effect but tpb reports "Mute on" | 643 | 2 - Related to "Mute on" key press |
451 | 3 - simulate pressing the "Access IBM" button | 644 | 3 - Related to "Access IBM" key press |
452 | 4 - LCD brightness up | 645 | 4 - Related to "LCD brightness up" key pess |
453 | 5 - LCD brightness down | 646 | 5 - Related to "LCD brightness down" key press |
454 | 11 - toggle screen expansion | 647 | 11 - Related to "toggle screen expansion" key press/function |
455 | 12 - ThinkLight on | 648 | 12 - Related to "ThinkLight on" |
456 | 13 - ThinkLight off | 649 | 13 - Related to "ThinkLight off" |
457 | 14 - no effect but tpb reports ThinkLight status change | 650 | 14 - Related to "ThinkLight" key press (toggle thinklight) |
458 | 651 | ||
459 | The cmos command interface is prone to firmware split-brain problems, as | 652 | The cmos command interface is prone to firmware split-brain problems, as |
460 | in newer ThinkPads it is just a compatibility layer. | 653 | in newer ThinkPads it is just a compatibility layer. Do not use it, it is |
654 | exported just as a debug tool. | ||
461 | 655 | ||
462 | LED control -- /proc/acpi/ibm/led | 656 | LED control -- /proc/acpi/ibm/led |
463 | --------------------------------- | 657 | --------------------------------- |
@@ -516,23 +710,15 @@ Temperature sensors | |||
516 | procfs: /proc/acpi/ibm/thermal | 710 | procfs: /proc/acpi/ibm/thermal |
517 | sysfs device attributes: (hwmon) temp*_input | 711 | sysfs device attributes: (hwmon) temp*_input |
518 | 712 | ||
519 | Most ThinkPads include six or more separate temperature sensors but | 713 | Most ThinkPads include six or more separate temperature sensors but only |
520 | only expose the CPU temperature through the standard ACPI methods. | 714 | expose the CPU temperature through the standard ACPI methods. This |
521 | This feature shows readings from up to eight different sensors on older | 715 | feature shows readings from up to eight different sensors on older |
522 | ThinkPads, and it has experimental support for up to sixteen different | 716 | ThinkPads, and up to sixteen different sensors on newer ThinkPads. |
523 | sensors on newer ThinkPads. | ||
524 | |||
525 | EXPERIMENTAL: The 16-sensors feature is marked EXPERIMENTAL because the | ||
526 | implementation directly accesses hardware registers and may not work as | ||
527 | expected. USE WITH CAUTION! To use this feature, you need to supply the | ||
528 | experimental=1 parameter when loading the module. When EXPERIMENTAL | ||
529 | mode is enabled, reading the first 8 sensors on newer ThinkPads will | ||
530 | also use an new experimental thermal sensor access mode. | ||
531 | 717 | ||
532 | For example, on the X40, a typical output may be: | 718 | For example, on the X40, a typical output may be: |
533 | temperatures: 42 42 45 41 36 -128 33 -128 | 719 | temperatures: 42 42 45 41 36 -128 33 -128 |
534 | 720 | ||
535 | EXPERIMENTAL: On the T43/p, a typical output may be: | 721 | On the T43/p, a typical output may be: |
536 | temperatures: 48 48 36 52 38 -128 31 -128 48 52 48 -128 -128 -128 -128 -128 | 722 | temperatures: 48 48 36 52 38 -128 31 -128 48 52 48 -128 -128 -128 -128 -128 |
537 | 723 | ||
538 | The mapping of thermal sensors to physical locations varies depending on | 724 | The mapping of thermal sensors to physical locations varies depending on |
@@ -562,7 +748,8 @@ http://thinkwiki.org/wiki/Thermal_Sensors#ThinkPad_T43.2C_T43p | |||
562 | 2: System board, left side (near PCMCIA slot), reported as HDAPS temp | 748 | 2: System board, left side (near PCMCIA slot), reported as HDAPS temp |
563 | 3: PCMCIA slot | 749 | 3: PCMCIA slot |
564 | 9: MCH (northbridge) to DRAM Bus | 750 | 9: MCH (northbridge) to DRAM Bus |
565 | 10: ICH (southbridge), under Mini-PCI card, under touchpad | 751 | 10: Clock-generator, mini-pci card and ICH (southbridge), under Mini-PCI |
752 | card, under touchpad | ||
566 | 11: Power regulator, underside of system board, below F2 key | 753 | 11: Power regulator, underside of system board, below F2 key |
567 | 754 | ||
568 | The A31 has a very atypical layout for the thermal sensors | 755 | The A31 has a very atypical layout for the thermal sensors |
@@ -681,6 +868,12 @@ cannot be controlled. | |||
681 | The backlight control has eight levels, ranging from 0 to 7. Some of the | 868 | The backlight control has eight levels, ranging from 0 to 7. Some of the |
682 | levels may not be distinct. | 869 | levels may not be distinct. |
683 | 870 | ||
871 | There are two interfaces to the firmware for brightness control, EC and CMOS. | ||
872 | To select which one should be used, use the brightness_mode module parameter: | ||
873 | brightness_mode=1 selects EC mode, brightness_mode=2 selects CMOS mode, | ||
874 | brightness_mode=3 selects both EC and CMOS. The driver tries to autodetect | ||
875 | which interface to use. | ||
876 | |||
684 | Procfs notes: | 877 | Procfs notes: |
685 | 878 | ||
686 | The available commands are: | 879 | The available commands are: |
@@ -976,3 +1169,9 @@ Sysfs interface changelog: | |||
976 | 1169 | ||
977 | 0x000100: Initial sysfs support, as a single platform driver and | 1170 | 0x000100: Initial sysfs support, as a single platform driver and |
978 | device. | 1171 | device. |
1172 | 0x000200: Hot key support for 32 hot keys, and radio slider switch | ||
1173 | support. | ||
1174 | 0x010000: Hot keys are now handled by default over the input | ||
1175 | layer, the radio switch generates input event EV_RADIO, | ||
1176 | and the driver enables hot key handling by default in | ||
1177 | the firmware. | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 773c732b4177..01f222e51871 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -225,15 +225,15 @@ T: git kernel.org:/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git | |||
225 | S: Supported | 225 | S: Supported |
226 | 226 | ||
227 | ACPI BATTERY DRIVERS | 227 | ACPI BATTERY DRIVERS |
228 | P: Vladimir P. Lebedev | 228 | P: Alexey Starikovskiy |
229 | M: vladimir.p.lebedev@intel.com | 229 | M: astarikovskiy@suse.de |
230 | L: linux-acpi@vger.kernel.org | 230 | L: linux-acpi@vger.kernel.org |
231 | W: http://acpi.sourceforge.net/ | 231 | W: http://acpi.sourceforge.net/ |
232 | S: Supported | 232 | S: Supported |
233 | 233 | ||
234 | ACPI EC DRIVER | 234 | ACPI EC DRIVER |
235 | P: Alexey Starikovskiy | 235 | P: Alexey Starikovskiy |
236 | M: alexey.y.starikovskiy@linux.intel.com | 236 | M: astarikovskiy@suse.de |
237 | L: linux-acpi@vger.kernel.org | 237 | L: linux-acpi@vger.kernel.org |
238 | W: http://acpi.sourceforge.net/ | 238 | W: http://acpi.sourceforge.net/ |
239 | S: Supported | 239 | S: Supported |
@@ -463,7 +463,7 @@ S: Maintained | |||
463 | 463 | ||
464 | ARM/HP JORNADA 7XX MACHINE SUPPORT | 464 | ARM/HP JORNADA 7XX MACHINE SUPPORT |
465 | P: Kristoffer Ericson | 465 | P: Kristoffer Ericson |
466 | M: kristoffer_e1@hotmail.com | 466 | M: kristoffer.ericson@gmail.com |
467 | W: www.jlime.com | 467 | W: www.jlime.com |
468 | S: Maintained | 468 | S: Maintained |
469 | 469 | ||
@@ -1,7 +1,7 @@ | |||
1 | VERSION = 2 | 1 | VERSION = 2 |
2 | PATCHLEVEL = 6 | 2 | PATCHLEVEL = 6 |
3 | SUBLEVEL = 22 | 3 | SUBLEVEL = 23 |
4 | EXTRAVERSION = | 4 | EXTRAVERSION =-rc1 |
5 | NAME = Holy Dancing Manatees, Batman! | 5 | NAME = Holy Dancing Manatees, Batman! |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index a44c6da9bf83..85016313bd11 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -324,6 +324,12 @@ config ARCH_NS9XXX | |||
324 | 324 | ||
325 | <http://www.digi.com/products/microprocessors/index.jsp> | 325 | <http://www.digi.com/products/microprocessors/index.jsp> |
326 | 326 | ||
327 | config ARCH_MXC | ||
328 | bool "Freescale MXC/iMX-based" | ||
329 | select ARCH_MTD_XIP | ||
330 | help | ||
331 | Support for Freescale MXC/iMX-based family of processors | ||
332 | |||
327 | config ARCH_PNX4008 | 333 | config ARCH_PNX4008 |
328 | bool "Philips Nexperia PNX4008 Mobile" | 334 | bool "Philips Nexperia PNX4008 Mobile" |
329 | help | 335 | help |
@@ -432,6 +438,7 @@ source "arch/arm/mach-omap1/Kconfig" | |||
432 | source "arch/arm/mach-omap2/Kconfig" | 438 | source "arch/arm/mach-omap2/Kconfig" |
433 | 439 | ||
434 | source "arch/arm/plat-s3c24xx/Kconfig" | 440 | source "arch/arm/plat-s3c24xx/Kconfig" |
441 | source "arch/arm/plat-s3c/Kconfig" | ||
435 | 442 | ||
436 | if ARCH_S3C2410 | 443 | if ARCH_S3C2410 |
437 | source "arch/arm/mach-s3c2400/Kconfig" | 444 | source "arch/arm/mach-s3c2400/Kconfig" |
@@ -456,6 +463,8 @@ source "arch/arm/mach-realview/Kconfig" | |||
456 | 463 | ||
457 | source "arch/arm/mach-at91/Kconfig" | 464 | source "arch/arm/mach-at91/Kconfig" |
458 | 465 | ||
466 | source "arch/arm/plat-mxc/Kconfig" | ||
467 | |||
459 | source "arch/arm/mach-netx/Kconfig" | 468 | source "arch/arm/mach-netx/Kconfig" |
460 | 469 | ||
461 | source "arch/arm/mach-ns9xxx/Kconfig" | 470 | source "arch/arm/mach-ns9xxx/Kconfig" |
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 40c5eb1f55c7..18101f5f5f24 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug | |||
@@ -82,24 +82,24 @@ config DEBUG_CLPS711X_UART2 | |||
82 | output to the second serial port on these devices. Saying N will | 82 | output to the second serial port on these devices. Saying N will |
83 | cause the debug messages to appear on the first serial port. | 83 | cause the debug messages to appear on the first serial port. |
84 | 84 | ||
85 | config DEBUG_S3C2410_PORT | 85 | config DEBUG_S3C_PORT |
86 | depends on DEBUG_LL && ARCH_S3C2410 | 86 | depends on DEBUG_LL && PLAT_S3C |
87 | bool "Kernel low-level debugging messages via S3C2410 UART" | 87 | bool "Kernel low-level debugging messages via S3C UART" |
88 | help | 88 | help |
89 | Say Y here if you want debug print routines to go to one of the | 89 | Say Y here if you want debug print routines to go to one of the |
90 | S3C2410 internal UARTs. The chosen UART must have been configured | 90 | S3C internal UARTs. The chosen UART must have been configured |
91 | before it is used. | 91 | before it is used. |
92 | 92 | ||
93 | config DEBUG_S3C2410_UART | 93 | config DEBUG_S3C_UART |
94 | depends on ARCH_S3C2410 | 94 | depends on PLAT_S3C |
95 | int "S3C2410 UART to use for low-level debug" | 95 | int "S3C UART to use for low-level debug" |
96 | default "0" | 96 | default "0" |
97 | help | 97 | help |
98 | Choice for UART for kernel low-level using S3C2410 UARTS, | 98 | Choice for UART for kernel low-level using S3C UARTS, |
99 | should be between zero and two. The port must have been | 99 | should be between zero and two. The port must have been |
100 | initialised by the boot-loader before use. | 100 | initialised by the boot-loader before use. |
101 | 101 | ||
102 | The uncompressor code port configuration is now handled | 102 | The uncompressor code port configuration is now handled |
103 | by CONFIG_S3C2410_LOWLEVEL_UART_PORT. | 103 | by CONFIG_S3C_LOWLEVEL_UART_PORT. |
104 | 104 | ||
105 | endmenu | 105 | endmenu |
diff --git a/arch/arm/Makefile b/arch/arm/Makefile index cbd5010d3bc3..fa4ea9ff0797 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile | |||
@@ -137,6 +137,8 @@ endif | |||
137 | textofs-$(CONFIG_ARCH_NS9XXX) := 0x00108000 | 137 | textofs-$(CONFIG_ARCH_NS9XXX) := 0x00108000 |
138 | machine-$(CONFIG_ARCH_DAVINCI) := davinci | 138 | machine-$(CONFIG_ARCH_DAVINCI) := davinci |
139 | machine-$(CONFIG_ARCH_KS8695) := ks8695 | 139 | machine-$(CONFIG_ARCH_KS8695) := ks8695 |
140 | incdir-$(CONFIG_ARCH_MXC) := mxc | ||
141 | machine-$(CONFIG_ARCH_MX3) := mx3 | ||
140 | 142 | ||
141 | ifeq ($(CONFIG_ARCH_EBSA110),y) | 143 | ifeq ($(CONFIG_ARCH_EBSA110),y) |
142 | # This is what happens if you forget the IOCS16 line. | 144 | # This is what happens if you forget the IOCS16 line. |
@@ -183,6 +185,7 @@ core-$(CONFIG_VFP) += arch/arm/vfp/ | |||
183 | core-$(CONFIG_PLAT_IOP) += arch/arm/plat-iop/ | 185 | core-$(CONFIG_PLAT_IOP) += arch/arm/plat-iop/ |
184 | core-$(CONFIG_ARCH_OMAP) += arch/arm/plat-omap/ | 186 | core-$(CONFIG_ARCH_OMAP) += arch/arm/plat-omap/ |
185 | core-$(CONFIG_PLAT_S3C24XX) += arch/arm/plat-s3c24xx/ | 187 | core-$(CONFIG_PLAT_S3C24XX) += arch/arm/plat-s3c24xx/ |
188 | core-$(CONFIG_ARCH_MXC) += arch/arm/plat-mxc/ | ||
186 | 189 | ||
187 | drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/ | 190 | drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/ |
188 | drivers-$(CONFIG_ARCH_CLPS7500) += drivers/acorn/char/ | 191 | drivers-$(CONFIG_ARCH_CLPS7500) += drivers/acorn/char/ |
diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile index ec9c400c7f82..25f12303b106 100644 --- a/arch/arm/boot/Makefile +++ b/arch/arm/boot/Makefile | |||
@@ -91,4 +91,12 @@ zinstall: $(obj)/zImage | |||
91 | $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ | 91 | $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ |
92 | $(obj)/zImage System.map "$(INSTALL_PATH)" | 92 | $(obj)/zImage System.map "$(INSTALL_PATH)" |
93 | 93 | ||
94 | zi: | ||
95 | $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ | ||
96 | $(obj)/zImage System.map "$(INSTALL_PATH)" | ||
97 | |||
98 | i: | ||
99 | $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ | ||
100 | $(obj)/Image System.map "$(INSTALL_PATH)" | ||
101 | |||
94 | subdir- := bootp compressed | 102 | subdir- := bootp compressed |
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index a1f1691b67fe..6b8cbd69f249 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile | |||
@@ -73,7 +73,7 @@ SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/ | |||
73 | 73 | ||
74 | targets := vmlinux vmlinux.lds piggy.gz piggy.o font.o font.c \ | 74 | targets := vmlinux vmlinux.lds piggy.gz piggy.o font.o font.c \ |
75 | head.o misc.o $(OBJS) | 75 | head.o misc.o $(OBJS) |
76 | EXTRA_CFLAGS := -fpic | 76 | EXTRA_CFLAGS := -fpic -fno-builtin |
77 | EXTRA_AFLAGS := | 77 | EXTRA_AFLAGS := |
78 | 78 | ||
79 | # Supply ZRELADDR, INITRD_PHYS and PARAMS_PHYS to the decompressor via | 79 | # Supply ZRELADDR, INITRD_PHYS and PARAMS_PHYS to the decompressor via |
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index d7fb5ee1637e..b9b03eda70e5 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S | |||
@@ -55,7 +55,7 @@ | |||
55 | #elif defined(CONFIG_ARCH_S3C2410) | 55 | #elif defined(CONFIG_ARCH_S3C2410) |
56 | .macro loadsp, rb | 56 | .macro loadsp, rb |
57 | mov \rb, #0x50000000 | 57 | mov \rb, #0x50000000 |
58 | add \rb, \rb, #0x4000 * CONFIG_S3C2410_LOWLEVEL_UART_PORT | 58 | add \rb, \rb, #0x4000 * CONFIG_S3C_LOWLEVEL_UART_PORT |
59 | .endm | 59 | .endm |
60 | #else | 60 | #else |
61 | .macro loadsp, rb | 61 | .macro loadsp, rb |
diff --git a/arch/arm/configs/em_x270_defconfig b/arch/arm/configs/em_x270_defconfig new file mode 100644 index 000000000000..6bea0901bdf0 --- /dev/null +++ b/arch/arm/configs/em_x270_defconfig | |||
@@ -0,0 +1,1265 @@ | |||
1 | # | ||
2 | # Automatically generated make config: don't edit | ||
3 | # Linux kernel version: 2.6.22 | ||
4 | # Mon Jul 9 15:18:20 2007 | ||
5 | # | ||
6 | CONFIG_ARM=y | ||
7 | CONFIG_SYS_SUPPORTS_APM_EMULATION=y | ||
8 | CONFIG_GENERIC_GPIO=y | ||
9 | CONFIG_GENERIC_TIME=y | ||
10 | # CONFIG_GENERIC_CLOCKEVENTS is not set | ||
11 | CONFIG_MMU=y | ||
12 | # CONFIG_NO_IOPORT is not set | ||
13 | CONFIG_GENERIC_HARDIRQS=y | ||
14 | CONFIG_STACKTRACE_SUPPORT=y | ||
15 | CONFIG_LOCKDEP_SUPPORT=y | ||
16 | CONFIG_TRACE_IRQFLAGS_SUPPORT=y | ||
17 | CONFIG_HARDIRQS_SW_RESEND=y | ||
18 | CONFIG_GENERIC_IRQ_PROBE=y | ||
19 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
20 | # CONFIG_ARCH_HAS_ILOG2_U32 is not set | ||
21 | # CONFIG_ARCH_HAS_ILOG2_U64 is not set | ||
22 | CONFIG_GENERIC_HWEIGHT=y | ||
23 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
24 | CONFIG_ZONE_DMA=y | ||
25 | CONFIG_ARCH_MTD_XIP=y | ||
26 | CONFIG_VECTORS_BASE=0xffff0000 | ||
27 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | ||
28 | |||
29 | # | ||
30 | # Code maturity level options | ||
31 | # | ||
32 | CONFIG_EXPERIMENTAL=y | ||
33 | CONFIG_BROKEN_ON_SMP=y | ||
34 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
35 | |||
36 | # | ||
37 | # General setup | ||
38 | # | ||
39 | CONFIG_LOCALVERSION="-em-x270" | ||
40 | # CONFIG_LOCALVERSION_AUTO is not set | ||
41 | CONFIG_SWAP=y | ||
42 | CONFIG_SYSVIPC=y | ||
43 | # CONFIG_IPC_NS is not set | ||
44 | CONFIG_SYSVIPC_SYSCTL=y | ||
45 | # CONFIG_POSIX_MQUEUE is not set | ||
46 | # CONFIG_BSD_PROCESS_ACCT is not set | ||
47 | # CONFIG_TASKSTATS is not set | ||
48 | # CONFIG_UTS_NS is not set | ||
49 | # CONFIG_AUDIT is not set | ||
50 | CONFIG_IKCONFIG=y | ||
51 | CONFIG_IKCONFIG_PROC=y | ||
52 | CONFIG_LOG_BUF_SHIFT=17 | ||
53 | CONFIG_SYSFS_DEPRECATED=y | ||
54 | # CONFIG_RELAY is not set | ||
55 | CONFIG_BLK_DEV_INITRD=y | ||
56 | CONFIG_INITRAMFS_SOURCE="" | ||
57 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | ||
58 | CONFIG_SYSCTL=y | ||
59 | CONFIG_EMBEDDED=y | ||
60 | CONFIG_UID16=y | ||
61 | CONFIG_SYSCTL_SYSCALL=y | ||
62 | CONFIG_KALLSYMS=y | ||
63 | # CONFIG_KALLSYMS_ALL is not set | ||
64 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | ||
65 | CONFIG_HOTPLUG=y | ||
66 | CONFIG_PRINTK=y | ||
67 | CONFIG_BUG=y | ||
68 | CONFIG_ELF_CORE=y | ||
69 | CONFIG_BASE_FULL=y | ||
70 | CONFIG_FUTEX=y | ||
71 | CONFIG_ANON_INODES=y | ||
72 | CONFIG_EPOLL=y | ||
73 | CONFIG_SIGNALFD=y | ||
74 | CONFIG_TIMERFD=y | ||
75 | CONFIG_EVENTFD=y | ||
76 | CONFIG_SHMEM=y | ||
77 | CONFIG_VM_EVENT_COUNTERS=y | ||
78 | CONFIG_SLAB=y | ||
79 | # CONFIG_SLUB is not set | ||
80 | # CONFIG_SLOB is not set | ||
81 | CONFIG_RT_MUTEXES=y | ||
82 | # CONFIG_TINY_SHMEM is not set | ||
83 | CONFIG_BASE_SMALL=0 | ||
84 | |||
85 | # | ||
86 | # Loadable module support | ||
87 | # | ||
88 | CONFIG_MODULES=y | ||
89 | CONFIG_MODULE_UNLOAD=y | ||
90 | CONFIG_MODULE_FORCE_UNLOAD=y | ||
91 | # CONFIG_MODVERSIONS is not set | ||
92 | # CONFIG_MODULE_SRCVERSION_ALL is not set | ||
93 | CONFIG_KMOD=y | ||
94 | |||
95 | # | ||
96 | # Block layer | ||
97 | # | ||
98 | CONFIG_BLOCK=y | ||
99 | # CONFIG_LBD is not set | ||
100 | # CONFIG_BLK_DEV_IO_TRACE is not set | ||
101 | # CONFIG_LSF is not set | ||
102 | |||
103 | # | ||
104 | # IO Schedulers | ||
105 | # | ||
106 | CONFIG_IOSCHED_NOOP=y | ||
107 | CONFIG_IOSCHED_AS=y | ||
108 | CONFIG_IOSCHED_DEADLINE=y | ||
109 | CONFIG_IOSCHED_CFQ=y | ||
110 | CONFIG_DEFAULT_AS=y | ||
111 | # CONFIG_DEFAULT_DEADLINE is not set | ||
112 | # CONFIG_DEFAULT_CFQ is not set | ||
113 | # CONFIG_DEFAULT_NOOP is not set | ||
114 | CONFIG_DEFAULT_IOSCHED="anticipatory" | ||
115 | |||
116 | # | ||
117 | # System Type | ||
118 | # | ||
119 | # CONFIG_ARCH_AAEC2000 is not set | ||
120 | # CONFIG_ARCH_INTEGRATOR is not set | ||
121 | # CONFIG_ARCH_REALVIEW is not set | ||
122 | # CONFIG_ARCH_VERSATILE is not set | ||
123 | # CONFIG_ARCH_AT91 is not set | ||
124 | # CONFIG_ARCH_CLPS7500 is not set | ||
125 | # CONFIG_ARCH_CLPS711X is not set | ||
126 | # CONFIG_ARCH_CO285 is not set | ||
127 | # CONFIG_ARCH_EBSA110 is not set | ||
128 | # CONFIG_ARCH_EP93XX is not set | ||
129 | # CONFIG_ARCH_FOOTBRIDGE is not set | ||
130 | # CONFIG_ARCH_NETX is not set | ||
131 | # CONFIG_ARCH_H720X is not set | ||
132 | # CONFIG_ARCH_IMX is not set | ||
133 | # CONFIG_ARCH_IOP13XX is not set | ||
134 | # CONFIG_ARCH_IOP32X is not set | ||
135 | # CONFIG_ARCH_IOP33X is not set | ||
136 | # CONFIG_ARCH_IXP23XX is not set | ||
137 | # CONFIG_ARCH_IXP2000 is not set | ||
138 | # CONFIG_ARCH_IXP4XX is not set | ||
139 | # CONFIG_ARCH_L7200 is not set | ||
140 | # CONFIG_ARCH_KS8695 is not set | ||
141 | # CONFIG_ARCH_NS9XXX is not set | ||
142 | # CONFIG_ARCH_PNX4008 is not set | ||
143 | CONFIG_ARCH_PXA=y | ||
144 | # CONFIG_ARCH_RPC is not set | ||
145 | # CONFIG_ARCH_SA1100 is not set | ||
146 | # CONFIG_ARCH_S3C2410 is not set | ||
147 | # CONFIG_ARCH_SHARK is not set | ||
148 | # CONFIG_ARCH_LH7A40X is not set | ||
149 | # CONFIG_ARCH_DAVINCI is not set | ||
150 | # CONFIG_ARCH_OMAP is not set | ||
151 | |||
152 | # | ||
153 | # Intel PXA2xx Implementations | ||
154 | # | ||
155 | # CONFIG_ARCH_LUBBOCK is not set | ||
156 | # CONFIG_MACH_LOGICPD_PXA270 is not set | ||
157 | # CONFIG_MACH_MAINSTONE is not set | ||
158 | # CONFIG_ARCH_PXA_IDP is not set | ||
159 | # CONFIG_PXA_SHARPSL is not set | ||
160 | # CONFIG_MACH_TRIZEPS4 is not set | ||
161 | CONFIG_MACH_EM_X270=y | ||
162 | CONFIG_PXA27x=y | ||
163 | |||
164 | # | ||
165 | # Processor Type | ||
166 | # | ||
167 | CONFIG_CPU_32=y | ||
168 | CONFIG_CPU_XSCALE=y | ||
169 | CONFIG_CPU_32v5=y | ||
170 | CONFIG_CPU_ABRT_EV5T=y | ||
171 | CONFIG_CPU_CACHE_VIVT=y | ||
172 | CONFIG_CPU_TLB_V4WBI=y | ||
173 | CONFIG_CPU_CP15=y | ||
174 | CONFIG_CPU_CP15_MMU=y | ||
175 | |||
176 | # | ||
177 | # Processor Features | ||
178 | # | ||
179 | CONFIG_ARM_THUMB=y | ||
180 | # CONFIG_CPU_DCACHE_DISABLE is not set | ||
181 | # CONFIG_OUTER_CACHE is not set | ||
182 | CONFIG_IWMMXT=y | ||
183 | CONFIG_XSCALE_PMU=y | ||
184 | |||
185 | # | ||
186 | # Bus support | ||
187 | # | ||
188 | # CONFIG_ARCH_SUPPORTS_MSI is not set | ||
189 | |||
190 | # | ||
191 | # PCCARD (PCMCIA/CardBus) support | ||
192 | # | ||
193 | # CONFIG_PCCARD is not set | ||
194 | |||
195 | # | ||
196 | # Kernel Features | ||
197 | # | ||
198 | # CONFIG_TICK_ONESHOT is not set | ||
199 | # CONFIG_PREEMPT is not set | ||
200 | # CONFIG_NO_IDLE_HZ is not set | ||
201 | CONFIG_HZ=100 | ||
202 | CONFIG_AEABI=y | ||
203 | CONFIG_OABI_COMPAT=y | ||
204 | # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set | ||
205 | CONFIG_SELECT_MEMORY_MODEL=y | ||
206 | CONFIG_FLATMEM_MANUAL=y | ||
207 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
208 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
209 | CONFIG_FLATMEM=y | ||
210 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
211 | # CONFIG_SPARSEMEM_STATIC is not set | ||
212 | CONFIG_SPLIT_PTLOCK_CPUS=4096 | ||
213 | # CONFIG_RESOURCES_64BIT is not set | ||
214 | CONFIG_ZONE_DMA_FLAG=1 | ||
215 | CONFIG_ALIGNMENT_TRAP=y | ||
216 | |||
217 | # | ||
218 | # Boot options | ||
219 | # | ||
220 | CONFIG_ZBOOT_ROM_TEXT=0x0 | ||
221 | CONFIG_ZBOOT_ROM_BSS=0x0 | ||
222 | CONFIG_CMDLINE="" | ||
223 | # CONFIG_XIP_KERNEL is not set | ||
224 | # CONFIG_KEXEC is not set | ||
225 | |||
226 | # | ||
227 | # Floating point emulation | ||
228 | # | ||
229 | |||
230 | # | ||
231 | # At least one emulation must be selected | ||
232 | # | ||
233 | CONFIG_FPE_NWFPE=y | ||
234 | # CONFIG_FPE_NWFPE_XP is not set | ||
235 | # CONFIG_FPE_FASTFPE is not set | ||
236 | |||
237 | # | ||
238 | # Userspace binary formats | ||
239 | # | ||
240 | CONFIG_BINFMT_ELF=y | ||
241 | # CONFIG_BINFMT_AOUT is not set | ||
242 | # CONFIG_BINFMT_MISC is not set | ||
243 | |||
244 | # | ||
245 | # Power management options | ||
246 | # | ||
247 | CONFIG_PM=y | ||
248 | CONFIG_PM_LEGACY=y | ||
249 | # CONFIG_PM_DEBUG is not set | ||
250 | # CONFIG_PM_SYSFS_DEPRECATED is not set | ||
251 | CONFIG_APM_EMULATION=m | ||
252 | |||
253 | # | ||
254 | # Networking | ||
255 | # | ||
256 | CONFIG_NET=y | ||
257 | |||
258 | # | ||
259 | # Networking options | ||
260 | # | ||
261 | CONFIG_PACKET=y | ||
262 | # CONFIG_PACKET_MMAP is not set | ||
263 | CONFIG_UNIX=y | ||
264 | CONFIG_XFRM=y | ||
265 | # CONFIG_XFRM_USER is not set | ||
266 | # CONFIG_XFRM_SUB_POLICY is not set | ||
267 | # CONFIG_XFRM_MIGRATE is not set | ||
268 | # CONFIG_NET_KEY is not set | ||
269 | CONFIG_INET=y | ||
270 | # CONFIG_IP_MULTICAST is not set | ||
271 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
272 | CONFIG_IP_FIB_HASH=y | ||
273 | CONFIG_IP_PNP=y | ||
274 | CONFIG_IP_PNP_DHCP=y | ||
275 | CONFIG_IP_PNP_BOOTP=y | ||
276 | # CONFIG_IP_PNP_RARP is not set | ||
277 | # CONFIG_NET_IPIP is not set | ||
278 | # CONFIG_NET_IPGRE is not set | ||
279 | # CONFIG_ARPD is not set | ||
280 | # CONFIG_SYN_COOKIES is not set | ||
281 | # CONFIG_INET_AH is not set | ||
282 | # CONFIG_INET_ESP is not set | ||
283 | # CONFIG_INET_IPCOMP is not set | ||
284 | # CONFIG_INET_XFRM_TUNNEL is not set | ||
285 | # CONFIG_INET_TUNNEL is not set | ||
286 | CONFIG_INET_XFRM_MODE_TRANSPORT=y | ||
287 | CONFIG_INET_XFRM_MODE_TUNNEL=y | ||
288 | CONFIG_INET_XFRM_MODE_BEET=y | ||
289 | CONFIG_INET_DIAG=y | ||
290 | CONFIG_INET_TCP_DIAG=y | ||
291 | # CONFIG_TCP_CONG_ADVANCED is not set | ||
292 | CONFIG_TCP_CONG_CUBIC=y | ||
293 | CONFIG_DEFAULT_TCP_CONG="cubic" | ||
294 | # CONFIG_TCP_MD5SIG is not set | ||
295 | # CONFIG_IPV6 is not set | ||
296 | # CONFIG_INET6_XFRM_TUNNEL is not set | ||
297 | # CONFIG_INET6_TUNNEL is not set | ||
298 | # CONFIG_NETWORK_SECMARK is not set | ||
299 | # CONFIG_NETFILTER is not set | ||
300 | # CONFIG_IP_DCCP is not set | ||
301 | # CONFIG_IP_SCTP is not set | ||
302 | # CONFIG_TIPC is not set | ||
303 | # CONFIG_ATM is not set | ||
304 | # CONFIG_BRIDGE is not set | ||
305 | # CONFIG_VLAN_8021Q is not set | ||
306 | # CONFIG_DECNET is not set | ||
307 | # CONFIG_LLC2 is not set | ||
308 | # CONFIG_IPX is not set | ||
309 | # CONFIG_ATALK is not set | ||
310 | # CONFIG_X25 is not set | ||
311 | # CONFIG_LAPB is not set | ||
312 | # CONFIG_ECONET is not set | ||
313 | # CONFIG_WAN_ROUTER is not set | ||
314 | |||
315 | # | ||
316 | # QoS and/or fair queueing | ||
317 | # | ||
318 | # CONFIG_NET_SCHED is not set | ||
319 | |||
320 | # | ||
321 | # Network testing | ||
322 | # | ||
323 | # CONFIG_NET_PKTGEN is not set | ||
324 | # CONFIG_HAMRADIO is not set | ||
325 | # CONFIG_IRDA is not set | ||
326 | CONFIG_BT=m | ||
327 | CONFIG_BT_L2CAP=m | ||
328 | CONFIG_BT_SCO=m | ||
329 | CONFIG_BT_RFCOMM=m | ||
330 | # CONFIG_BT_RFCOMM_TTY is not set | ||
331 | CONFIG_BT_BNEP=m | ||
332 | # CONFIG_BT_BNEP_MC_FILTER is not set | ||
333 | # CONFIG_BT_BNEP_PROTO_FILTER is not set | ||
334 | CONFIG_BT_HIDP=m | ||
335 | |||
336 | # | ||
337 | # Bluetooth device drivers | ||
338 | # | ||
339 | CONFIG_BT_HCIUSB=m | ||
340 | # CONFIG_BT_HCIUSB_SCO is not set | ||
341 | CONFIG_BT_HCIUART=m | ||
342 | # CONFIG_BT_HCIUART_H4 is not set | ||
343 | # CONFIG_BT_HCIUART_BCSP is not set | ||
344 | CONFIG_BT_HCIBCM203X=m | ||
345 | CONFIG_BT_HCIBPA10X=m | ||
346 | CONFIG_BT_HCIBFUSB=m | ||
347 | # CONFIG_BT_HCIVHCI is not set | ||
348 | # CONFIG_AF_RXRPC is not set | ||
349 | |||
350 | # | ||
351 | # Wireless | ||
352 | # | ||
353 | # CONFIG_CFG80211 is not set | ||
354 | # CONFIG_WIRELESS_EXT is not set | ||
355 | # CONFIG_MAC80211 is not set | ||
356 | CONFIG_IEEE80211=m | ||
357 | # CONFIG_IEEE80211_DEBUG is not set | ||
358 | CONFIG_IEEE80211_CRYPT_WEP=m | ||
359 | CONFIG_IEEE80211_CRYPT_CCMP=m | ||
360 | # CONFIG_IEEE80211_CRYPT_TKIP is not set | ||
361 | # CONFIG_IEEE80211_SOFTMAC is not set | ||
362 | # CONFIG_RFKILL is not set | ||
363 | |||
364 | # | ||
365 | # Device Drivers | ||
366 | # | ||
367 | |||
368 | # | ||
369 | # Generic Driver Options | ||
370 | # | ||
371 | CONFIG_STANDALONE=y | ||
372 | CONFIG_PREVENT_FIRMWARE_BUILD=y | ||
373 | CONFIG_FW_LOADER=y | ||
374 | # CONFIG_DEBUG_DRIVER is not set | ||
375 | # CONFIG_DEBUG_DEVRES is not set | ||
376 | # CONFIG_SYS_HYPERVISOR is not set | ||
377 | |||
378 | # | ||
379 | # Connector - unified userspace <-> kernelspace linker | ||
380 | # | ||
381 | # CONFIG_CONNECTOR is not set | ||
382 | CONFIG_MTD=y | ||
383 | # CONFIG_MTD_DEBUG is not set | ||
384 | CONFIG_MTD_CONCAT=y | ||
385 | CONFIG_MTD_PARTITIONS=y | ||
386 | # CONFIG_MTD_REDBOOT_PARTS is not set | ||
387 | # CONFIG_MTD_CMDLINE_PARTS is not set | ||
388 | # CONFIG_MTD_AFS_PARTS is not set | ||
389 | |||
390 | # | ||
391 | # User Modules And Translation Layers | ||
392 | # | ||
393 | CONFIG_MTD_CHAR=y | ||
394 | CONFIG_MTD_BLKDEVS=y | ||
395 | CONFIG_MTD_BLOCK=y | ||
396 | # CONFIG_FTL is not set | ||
397 | # CONFIG_NFTL is not set | ||
398 | # CONFIG_INFTL is not set | ||
399 | # CONFIG_RFD_FTL is not set | ||
400 | # CONFIG_SSFDC is not set | ||
401 | |||
402 | # | ||
403 | # RAM/ROM/Flash chip drivers | ||
404 | # | ||
405 | # CONFIG_MTD_CFI is not set | ||
406 | # CONFIG_MTD_JEDECPROBE is not set | ||
407 | # CONFIG_MTD_CFI_NOSWAP is not set | ||
408 | # CONFIG_MTD_CFI_BE_BYTE_SWAP is not set | ||
409 | # CONFIG_MTD_CFI_LE_BYTE_SWAP is not set | ||
410 | CONFIG_MTD_MAP_BANK_WIDTH_1=y | ||
411 | CONFIG_MTD_MAP_BANK_WIDTH_2=y | ||
412 | CONFIG_MTD_MAP_BANK_WIDTH_4=y | ||
413 | # CONFIG_MTD_MAP_BANK_WIDTH_8 is not set | ||
414 | # CONFIG_MTD_MAP_BANK_WIDTH_16 is not set | ||
415 | # CONFIG_MTD_MAP_BANK_WIDTH_32 is not set | ||
416 | CONFIG_MTD_CFI_I1=y | ||
417 | CONFIG_MTD_CFI_I2=y | ||
418 | # CONFIG_MTD_CFI_I4 is not set | ||
419 | # CONFIG_MTD_CFI_I8 is not set | ||
420 | # CONFIG_MTD_RAM is not set | ||
421 | # CONFIG_MTD_ROM is not set | ||
422 | # CONFIG_MTD_ABSENT is not set | ||
423 | |||
424 | # | ||
425 | # Mapping drivers for chip access | ||
426 | # | ||
427 | # CONFIG_MTD_COMPLEX_MAPPINGS is not set | ||
428 | # CONFIG_MTD_SHARP_SL is not set | ||
429 | # CONFIG_MTD_PLATRAM is not set | ||
430 | |||
431 | # | ||
432 | # Self-contained MTD device drivers | ||
433 | # | ||
434 | # CONFIG_MTD_SLRAM is not set | ||
435 | # CONFIG_MTD_PHRAM is not set | ||
436 | # CONFIG_MTD_MTDRAM is not set | ||
437 | # CONFIG_MTD_BLOCK2MTD is not set | ||
438 | |||
439 | # | ||
440 | # Disk-On-Chip Device Drivers | ||
441 | # | ||
442 | # CONFIG_MTD_DOC2000 is not set | ||
443 | # CONFIG_MTD_DOC2001 is not set | ||
444 | # CONFIG_MTD_DOC2001PLUS is not set | ||
445 | CONFIG_MTD_NAND=y | ||
446 | # CONFIG_MTD_NAND_VERIFY_WRITE is not set | ||
447 | # CONFIG_MTD_NAND_ECC_SMC is not set | ||
448 | # CONFIG_MTD_NAND_MUSEUM_IDS is not set | ||
449 | # CONFIG_MTD_NAND_H1900 is not set | ||
450 | CONFIG_MTD_NAND_IDS=y | ||
451 | # CONFIG_MTD_NAND_DISKONCHIP is not set | ||
452 | # CONFIG_MTD_NAND_SHARPSL is not set | ||
453 | # CONFIG_MTD_NAND_NANDSIM is not set | ||
454 | CONFIG_MTD_NAND_PLATFORM=y | ||
455 | # CONFIG_MTD_ONENAND is not set | ||
456 | |||
457 | # | ||
458 | # UBI - Unsorted block images | ||
459 | # | ||
460 | # CONFIG_MTD_UBI is not set | ||
461 | |||
462 | # | ||
463 | # Parallel port support | ||
464 | # | ||
465 | # CONFIG_PARPORT is not set | ||
466 | |||
467 | # | ||
468 | # Plug and Play support | ||
469 | # | ||
470 | # CONFIG_PNPACPI is not set | ||
471 | |||
472 | # | ||
473 | # Block devices | ||
474 | # | ||
475 | # CONFIG_BLK_DEV_COW_COMMON is not set | ||
476 | CONFIG_BLK_DEV_LOOP=y | ||
477 | # CONFIG_BLK_DEV_CRYPTOLOOP is not set | ||
478 | # CONFIG_BLK_DEV_NBD is not set | ||
479 | # CONFIG_BLK_DEV_UB is not set | ||
480 | CONFIG_BLK_DEV_RAM=y | ||
481 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
482 | CONFIG_BLK_DEV_RAM_SIZE=12000 | ||
483 | CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 | ||
484 | # CONFIG_CDROM_PKTCDVD is not set | ||
485 | # CONFIG_ATA_OVER_ETH is not set | ||
486 | # CONFIG_IDE is not set | ||
487 | |||
488 | # | ||
489 | # SCSI device support | ||
490 | # | ||
491 | # CONFIG_RAID_ATTRS is not set | ||
492 | CONFIG_SCSI=y | ||
493 | # CONFIG_SCSI_TGT is not set | ||
494 | # CONFIG_SCSI_NETLINK is not set | ||
495 | # CONFIG_SCSI_PROC_FS is not set | ||
496 | |||
497 | # | ||
498 | # SCSI support type (disk, tape, CD-ROM) | ||
499 | # | ||
500 | CONFIG_BLK_DEV_SD=y | ||
501 | # CONFIG_CHR_DEV_ST is not set | ||
502 | # CONFIG_CHR_DEV_OSST is not set | ||
503 | # CONFIG_BLK_DEV_SR is not set | ||
504 | # CONFIG_CHR_DEV_SG is not set | ||
505 | # CONFIG_CHR_DEV_SCH is not set | ||
506 | |||
507 | # | ||
508 | # Some SCSI devices (e.g. CD jukebox) support multiple LUNs | ||
509 | # | ||
510 | # CONFIG_SCSI_MULTI_LUN is not set | ||
511 | # CONFIG_SCSI_CONSTANTS is not set | ||
512 | # CONFIG_SCSI_LOGGING is not set | ||
513 | # CONFIG_SCSI_SCAN_ASYNC is not set | ||
514 | CONFIG_SCSI_WAIT_SCAN=m | ||
515 | |||
516 | # | ||
517 | # SCSI Transports | ||
518 | # | ||
519 | # CONFIG_SCSI_SPI_ATTRS is not set | ||
520 | # CONFIG_SCSI_FC_ATTRS is not set | ||
521 | # CONFIG_SCSI_ISCSI_ATTRS is not set | ||
522 | # CONFIG_SCSI_SAS_ATTRS is not set | ||
523 | # CONFIG_SCSI_SAS_LIBSAS is not set | ||
524 | |||
525 | # | ||
526 | # SCSI low-level drivers | ||
527 | # | ||
528 | # CONFIG_ISCSI_TCP is not set | ||
529 | # CONFIG_SCSI_DEBUG is not set | ||
530 | # CONFIG_ATA is not set | ||
531 | |||
532 | # | ||
533 | # Multi-device support (RAID and LVM) | ||
534 | # | ||
535 | # CONFIG_MD is not set | ||
536 | |||
537 | # | ||
538 | # Network device support | ||
539 | # | ||
540 | CONFIG_NETDEVICES=y | ||
541 | # CONFIG_DUMMY is not set | ||
542 | # CONFIG_BONDING is not set | ||
543 | # CONFIG_EQUALIZER is not set | ||
544 | # CONFIG_TUN is not set | ||
545 | # CONFIG_PHYLIB is not set | ||
546 | |||
547 | # | ||
548 | # Ethernet (10 or 100Mbit) | ||
549 | # | ||
550 | CONFIG_NET_ETHERNET=y | ||
551 | CONFIG_MII=y | ||
552 | # CONFIG_SMC91X is not set | ||
553 | CONFIG_DM9000=y | ||
554 | # CONFIG_SMC911X is not set | ||
555 | # CONFIG_NETDEV_1000 is not set | ||
556 | # CONFIG_NETDEV_10000 is not set | ||
557 | |||
558 | # | ||
559 | # Wireless LAN | ||
560 | # | ||
561 | # CONFIG_WLAN_PRE80211 is not set | ||
562 | # CONFIG_WLAN_80211 is not set | ||
563 | |||
564 | # | ||
565 | # USB Network Adapters | ||
566 | # | ||
567 | # CONFIG_USB_CATC is not set | ||
568 | # CONFIG_USB_KAWETH is not set | ||
569 | # CONFIG_USB_PEGASUS is not set | ||
570 | # CONFIG_USB_RTL8150 is not set | ||
571 | # CONFIG_USB_USBNET_MII is not set | ||
572 | # CONFIG_USB_USBNET is not set | ||
573 | # CONFIG_WAN is not set | ||
574 | # CONFIG_PPP is not set | ||
575 | # CONFIG_SLIP is not set | ||
576 | # CONFIG_SHAPER is not set | ||
577 | # CONFIG_NETCONSOLE is not set | ||
578 | # CONFIG_NETPOLL is not set | ||
579 | # CONFIG_NET_POLL_CONTROLLER is not set | ||
580 | |||
581 | # | ||
582 | # ISDN subsystem | ||
583 | # | ||
584 | # CONFIG_ISDN is not set | ||
585 | |||
586 | # | ||
587 | # Input device support | ||
588 | # | ||
589 | CONFIG_INPUT=y | ||
590 | # CONFIG_INPUT_FF_MEMLESS is not set | ||
591 | # CONFIG_INPUT_POLLDEV is not set | ||
592 | |||
593 | # | ||
594 | # Userland interfaces | ||
595 | # | ||
596 | CONFIG_INPUT_MOUSEDEV=y | ||
597 | # CONFIG_INPUT_MOUSEDEV_PSAUX is not set | ||
598 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 | ||
599 | CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | ||
600 | # CONFIG_INPUT_JOYDEV is not set | ||
601 | # CONFIG_INPUT_TSDEV is not set | ||
602 | CONFIG_INPUT_EVDEV=y | ||
603 | # CONFIG_INPUT_EVBUG is not set | ||
604 | |||
605 | # | ||
606 | # Input Device Drivers | ||
607 | # | ||
608 | CONFIG_INPUT_KEYBOARD=y | ||
609 | # CONFIG_KEYBOARD_ATKBD is not set | ||
610 | # CONFIG_KEYBOARD_SUNKBD is not set | ||
611 | # CONFIG_KEYBOARD_LKKBD is not set | ||
612 | # CONFIG_KEYBOARD_XTKBD is not set | ||
613 | # CONFIG_KEYBOARD_NEWTON is not set | ||
614 | # CONFIG_KEYBOARD_STOWAWAY is not set | ||
615 | CONFIG_KEYBOARD_PXA27x=m | ||
616 | # CONFIG_KEYBOARD_GPIO is not set | ||
617 | # CONFIG_INPUT_MOUSE is not set | ||
618 | # CONFIG_INPUT_JOYSTICK is not set | ||
619 | # CONFIG_INPUT_TABLET is not set | ||
620 | CONFIG_INPUT_TOUCHSCREEN=y | ||
621 | # CONFIG_TOUCHSCREEN_GUNZE is not set | ||
622 | # CONFIG_TOUCHSCREEN_ELO is not set | ||
623 | # CONFIG_TOUCHSCREEN_MTOUCH is not set | ||
624 | # CONFIG_TOUCHSCREEN_MK712 is not set | ||
625 | # CONFIG_TOUCHSCREEN_PENMOUNT is not set | ||
626 | # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set | ||
627 | # CONFIG_TOUCHSCREEN_TOUCHWIN is not set | ||
628 | # CONFIG_TOUCHSCREEN_UCB1400 is not set | ||
629 | # CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set | ||
630 | # CONFIG_INPUT_MISC is not set | ||
631 | |||
632 | # | ||
633 | # Hardware I/O ports | ||
634 | # | ||
635 | CONFIG_SERIO=y | ||
636 | # CONFIG_SERIO_SERPORT is not set | ||
637 | CONFIG_SERIO_LIBPS2=y | ||
638 | # CONFIG_SERIO_RAW is not set | ||
639 | # CONFIG_GAMEPORT is not set | ||
640 | |||
641 | # | ||
642 | # Character devices | ||
643 | # | ||
644 | CONFIG_VT=y | ||
645 | CONFIG_VT_CONSOLE=y | ||
646 | CONFIG_HW_CONSOLE=y | ||
647 | # CONFIG_VT_HW_CONSOLE_BINDING is not set | ||
648 | # CONFIG_SERIAL_NONSTANDARD is not set | ||
649 | |||
650 | # | ||
651 | # Serial drivers | ||
652 | # | ||
653 | # CONFIG_SERIAL_8250 is not set | ||
654 | |||
655 | # | ||
656 | # Non-8250 serial port support | ||
657 | # | ||
658 | CONFIG_SERIAL_PXA=y | ||
659 | CONFIG_SERIAL_PXA_CONSOLE=y | ||
660 | CONFIG_SERIAL_CORE=y | ||
661 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
662 | CONFIG_UNIX98_PTYS=y | ||
663 | CONFIG_LEGACY_PTYS=y | ||
664 | CONFIG_LEGACY_PTY_COUNT=256 | ||
665 | |||
666 | # | ||
667 | # IPMI | ||
668 | # | ||
669 | # CONFIG_IPMI_HANDLER is not set | ||
670 | # CONFIG_WATCHDOG is not set | ||
671 | CONFIG_HW_RANDOM=m | ||
672 | # CONFIG_NVRAM is not set | ||
673 | # CONFIG_R3964 is not set | ||
674 | # CONFIG_RAW_DRIVER is not set | ||
675 | |||
676 | # | ||
677 | # TPM devices | ||
678 | # | ||
679 | # CONFIG_TCG_TPM is not set | ||
680 | # CONFIG_I2C is not set | ||
681 | |||
682 | # | ||
683 | # SPI support | ||
684 | # | ||
685 | # CONFIG_SPI is not set | ||
686 | # CONFIG_SPI_MASTER is not set | ||
687 | |||
688 | # | ||
689 | # Dallas's 1-wire bus | ||
690 | # | ||
691 | # CONFIG_W1 is not set | ||
692 | # CONFIG_HWMON is not set | ||
693 | |||
694 | # | ||
695 | # Misc devices | ||
696 | # | ||
697 | |||
698 | # | ||
699 | # Multifunction device drivers | ||
700 | # | ||
701 | # CONFIG_MFD_SM501 is not set | ||
702 | |||
703 | # | ||
704 | # LED devices | ||
705 | # | ||
706 | # CONFIG_NEW_LEDS is not set | ||
707 | |||
708 | # | ||
709 | # LED drivers | ||
710 | # | ||
711 | |||
712 | # | ||
713 | # LED Triggers | ||
714 | # | ||
715 | |||
716 | # | ||
717 | # Multimedia devices | ||
718 | # | ||
719 | # CONFIG_VIDEO_DEV is not set | ||
720 | # CONFIG_DVB_CORE is not set | ||
721 | # CONFIG_DAB is not set | ||
722 | |||
723 | # | ||
724 | # Graphics support | ||
725 | # | ||
726 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set | ||
727 | |||
728 | # | ||
729 | # Display device support | ||
730 | # | ||
731 | # CONFIG_DISPLAY_SUPPORT is not set | ||
732 | # CONFIG_VGASTATE is not set | ||
733 | CONFIG_FB=y | ||
734 | # CONFIG_FIRMWARE_EDID is not set | ||
735 | # CONFIG_FB_DDC is not set | ||
736 | CONFIG_FB_CFB_FILLRECT=y | ||
737 | CONFIG_FB_CFB_COPYAREA=y | ||
738 | CONFIG_FB_CFB_IMAGEBLIT=y | ||
739 | # CONFIG_FB_SYS_FILLRECT is not set | ||
740 | # CONFIG_FB_SYS_COPYAREA is not set | ||
741 | # CONFIG_FB_SYS_IMAGEBLIT is not set | ||
742 | # CONFIG_FB_SYS_FOPS is not set | ||
743 | CONFIG_FB_DEFERRED_IO=y | ||
744 | # CONFIG_FB_SVGALIB is not set | ||
745 | # CONFIG_FB_MACMODES is not set | ||
746 | # CONFIG_FB_BACKLIGHT is not set | ||
747 | # CONFIG_FB_MODE_HELPERS is not set | ||
748 | # CONFIG_FB_TILEBLITTING is not set | ||
749 | |||
750 | # | ||
751 | # Frame buffer hardware drivers | ||
752 | # | ||
753 | # CONFIG_FB_S1D13XXX is not set | ||
754 | CONFIG_FB_PXA=y | ||
755 | # CONFIG_FB_PXA_PARAMETERS is not set | ||
756 | # CONFIG_FB_MBX is not set | ||
757 | # CONFIG_FB_VIRTUAL is not set | ||
758 | |||
759 | # | ||
760 | # Console display driver support | ||
761 | # | ||
762 | # CONFIG_VGA_CONSOLE is not set | ||
763 | CONFIG_DUMMY_CONSOLE=y | ||
764 | CONFIG_FRAMEBUFFER_CONSOLE=y | ||
765 | # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set | ||
766 | # CONFIG_FONTS is not set | ||
767 | CONFIG_FONT_8x8=y | ||
768 | CONFIG_FONT_8x16=y | ||
769 | CONFIG_LOGO=y | ||
770 | CONFIG_LOGO_LINUX_MONO=y | ||
771 | CONFIG_LOGO_LINUX_VGA16=y | ||
772 | CONFIG_LOGO_LINUX_CLUT224=y | ||
773 | |||
774 | # | ||
775 | # Sound | ||
776 | # | ||
777 | CONFIG_SOUND=m | ||
778 | |||
779 | # | ||
780 | # Advanced Linux Sound Architecture | ||
781 | # | ||
782 | CONFIG_SND=m | ||
783 | CONFIG_SND_TIMER=m | ||
784 | CONFIG_SND_PCM=m | ||
785 | # CONFIG_SND_SEQUENCER is not set | ||
786 | CONFIG_SND_OSSEMUL=y | ||
787 | CONFIG_SND_MIXER_OSS=m | ||
788 | CONFIG_SND_PCM_OSS=m | ||
789 | CONFIG_SND_PCM_OSS_PLUGINS=y | ||
790 | # CONFIG_SND_DYNAMIC_MINORS is not set | ||
791 | CONFIG_SND_SUPPORT_OLD_API=y | ||
792 | CONFIG_SND_VERBOSE_PROCFS=y | ||
793 | # CONFIG_SND_VERBOSE_PRINTK is not set | ||
794 | # CONFIG_SND_DEBUG is not set | ||
795 | |||
796 | # | ||
797 | # Generic devices | ||
798 | # | ||
799 | CONFIG_SND_AC97_CODEC=m | ||
800 | # CONFIG_SND_DUMMY is not set | ||
801 | # CONFIG_SND_MTPAV is not set | ||
802 | # CONFIG_SND_SERIAL_U16550 is not set | ||
803 | # CONFIG_SND_MPU401 is not set | ||
804 | |||
805 | # | ||
806 | # ALSA ARM devices | ||
807 | # | ||
808 | CONFIG_SND_PXA2XX_PCM=m | ||
809 | CONFIG_SND_PXA2XX_AC97=m | ||
810 | |||
811 | # | ||
812 | # USB devices | ||
813 | # | ||
814 | # CONFIG_SND_USB_AUDIO is not set | ||
815 | # CONFIG_SND_USB_CAIAQ is not set | ||
816 | |||
817 | # | ||
818 | # System on Chip audio support | ||
819 | # | ||
820 | # CONFIG_SND_SOC is not set | ||
821 | |||
822 | # | ||
823 | # Open Sound System | ||
824 | # | ||
825 | # CONFIG_SOUND_PRIME is not set | ||
826 | CONFIG_AC97_BUS=m | ||
827 | |||
828 | # | ||
829 | # HID Devices | ||
830 | # | ||
831 | CONFIG_HID=y | ||
832 | # CONFIG_HID_DEBUG is not set | ||
833 | |||
834 | # | ||
835 | # USB Input Devices | ||
836 | # | ||
837 | CONFIG_USB_HID=y | ||
838 | # CONFIG_USB_HIDINPUT_POWERBOOK is not set | ||
839 | # CONFIG_HID_FF is not set | ||
840 | # CONFIG_USB_HIDDEV is not set | ||
841 | |||
842 | # | ||
843 | # USB support | ||
844 | # | ||
845 | CONFIG_USB_ARCH_HAS_HCD=y | ||
846 | CONFIG_USB_ARCH_HAS_OHCI=y | ||
847 | # CONFIG_USB_ARCH_HAS_EHCI is not set | ||
848 | CONFIG_USB=y | ||
849 | # CONFIG_USB_DEBUG is not set | ||
850 | |||
851 | # | ||
852 | # Miscellaneous USB options | ||
853 | # | ||
854 | CONFIG_USB_DEVICEFS=y | ||
855 | # CONFIG_USB_DEVICE_CLASS is not set | ||
856 | # CONFIG_USB_DYNAMIC_MINORS is not set | ||
857 | # CONFIG_USB_SUSPEND is not set | ||
858 | # CONFIG_USB_OTG is not set | ||
859 | |||
860 | # | ||
861 | # USB Host Controller Drivers | ||
862 | # | ||
863 | # CONFIG_USB_ISP116X_HCD is not set | ||
864 | CONFIG_USB_OHCI_HCD=y | ||
865 | # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set | ||
866 | # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set | ||
867 | CONFIG_USB_OHCI_LITTLE_ENDIAN=y | ||
868 | # CONFIG_USB_SL811_HCD is not set | ||
869 | |||
870 | # | ||
871 | # USB Device Class drivers | ||
872 | # | ||
873 | # CONFIG_USB_ACM is not set | ||
874 | # CONFIG_USB_PRINTER is not set | ||
875 | |||
876 | # | ||
877 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' | ||
878 | # | ||
879 | |||
880 | # | ||
881 | # may also be needed; see USB_STORAGE Help for more information | ||
882 | # | ||
883 | CONFIG_USB_STORAGE=y | ||
884 | # CONFIG_USB_STORAGE_DEBUG is not set | ||
885 | # CONFIG_USB_STORAGE_DATAFAB is not set | ||
886 | # CONFIG_USB_STORAGE_FREECOM is not set | ||
887 | # CONFIG_USB_STORAGE_DPCM is not set | ||
888 | # CONFIG_USB_STORAGE_USBAT is not set | ||
889 | # CONFIG_USB_STORAGE_SDDR09 is not set | ||
890 | # CONFIG_USB_STORAGE_SDDR55 is not set | ||
891 | # CONFIG_USB_STORAGE_JUMPSHOT is not set | ||
892 | # CONFIG_USB_STORAGE_ALAUDA is not set | ||
893 | # CONFIG_USB_STORAGE_KARMA is not set | ||
894 | # CONFIG_USB_LIBUSUAL is not set | ||
895 | |||
896 | # | ||
897 | # USB Imaging devices | ||
898 | # | ||
899 | # CONFIG_USB_MDC800 is not set | ||
900 | # CONFIG_USB_MICROTEK is not set | ||
901 | # CONFIG_USB_MON is not set | ||
902 | |||
903 | # | ||
904 | # USB port drivers | ||
905 | # | ||
906 | |||
907 | # | ||
908 | # USB Serial Converter support | ||
909 | # | ||
910 | # CONFIG_USB_SERIAL is not set | ||
911 | |||
912 | # | ||
913 | # USB Miscellaneous drivers | ||
914 | # | ||
915 | # CONFIG_USB_EMI62 is not set | ||
916 | # CONFIG_USB_EMI26 is not set | ||
917 | # CONFIG_USB_ADUTUX is not set | ||
918 | # CONFIG_USB_AUERSWALD is not set | ||
919 | # CONFIG_USB_RIO500 is not set | ||
920 | # CONFIG_USB_LEGOTOWER is not set | ||
921 | # CONFIG_USB_LCD is not set | ||
922 | # CONFIG_USB_BERRY_CHARGE is not set | ||
923 | # CONFIG_USB_LED is not set | ||
924 | # CONFIG_USB_CYPRESS_CY7C63 is not set | ||
925 | # CONFIG_USB_CYTHERM is not set | ||
926 | # CONFIG_USB_PHIDGET is not set | ||
927 | # CONFIG_USB_IDMOUSE is not set | ||
928 | # CONFIG_USB_FTDI_ELAN is not set | ||
929 | # CONFIG_USB_APPLEDISPLAY is not set | ||
930 | # CONFIG_USB_LD is not set | ||
931 | # CONFIG_USB_TRANCEVIBRATOR is not set | ||
932 | # CONFIG_USB_IOWARRIOR is not set | ||
933 | # CONFIG_USB_TEST is not set | ||
934 | |||
935 | # | ||
936 | # USB DSL modem support | ||
937 | # | ||
938 | |||
939 | # | ||
940 | # USB Gadget Support | ||
941 | # | ||
942 | # CONFIG_USB_GADGET is not set | ||
943 | CONFIG_MMC=m | ||
944 | # CONFIG_MMC_DEBUG is not set | ||
945 | # CONFIG_MMC_UNSAFE_RESUME is not set | ||
946 | |||
947 | # | ||
948 | # MMC/SD Card Drivers | ||
949 | # | ||
950 | CONFIG_MMC_BLOCK=m | ||
951 | |||
952 | # | ||
953 | # MMC/SD Host Controller Drivers | ||
954 | # | ||
955 | CONFIG_MMC_PXA=m | ||
956 | |||
957 | # | ||
958 | # Real Time Clock | ||
959 | # | ||
960 | CONFIG_RTC_LIB=y | ||
961 | CONFIG_RTC_CLASS=m | ||
962 | |||
963 | # | ||
964 | # RTC interfaces | ||
965 | # | ||
966 | CONFIG_RTC_INTF_SYSFS=y | ||
967 | CONFIG_RTC_INTF_PROC=y | ||
968 | CONFIG_RTC_INTF_DEV=y | ||
969 | # CONFIG_RTC_INTF_DEV_UIE_EMUL is not set | ||
970 | # CONFIG_RTC_DRV_TEST is not set | ||
971 | |||
972 | # | ||
973 | # I2C RTC drivers | ||
974 | # | ||
975 | |||
976 | # | ||
977 | # SPI RTC drivers | ||
978 | # | ||
979 | |||
980 | # | ||
981 | # Platform RTC drivers | ||
982 | # | ||
983 | # CONFIG_RTC_DRV_CMOS is not set | ||
984 | # CONFIG_RTC_DRV_DS1553 is not set | ||
985 | # CONFIG_RTC_DRV_DS1742 is not set | ||
986 | # CONFIG_RTC_DRV_M48T86 is not set | ||
987 | CONFIG_RTC_DRV_V3020=m | ||
988 | |||
989 | # | ||
990 | # on-CPU RTC drivers | ||
991 | # | ||
992 | CONFIG_RTC_DRV_SA1100=m | ||
993 | |||
994 | # | ||
995 | # File systems | ||
996 | # | ||
997 | CONFIG_EXT2_FS=y | ||
998 | # CONFIG_EXT2_FS_XATTR is not set | ||
999 | # CONFIG_EXT2_FS_XIP is not set | ||
1000 | CONFIG_EXT3_FS=y | ||
1001 | CONFIG_EXT3_FS_XATTR=y | ||
1002 | # CONFIG_EXT3_FS_POSIX_ACL is not set | ||
1003 | # CONFIG_EXT3_FS_SECURITY is not set | ||
1004 | # CONFIG_EXT4DEV_FS is not set | ||
1005 | CONFIG_JBD=y | ||
1006 | # CONFIG_JBD_DEBUG is not set | ||
1007 | CONFIG_FS_MBCACHE=y | ||
1008 | # CONFIG_REISERFS_FS is not set | ||
1009 | # CONFIG_JFS_FS is not set | ||
1010 | # CONFIG_FS_POSIX_ACL is not set | ||
1011 | # CONFIG_XFS_FS is not set | ||
1012 | # CONFIG_GFS2_FS is not set | ||
1013 | # CONFIG_OCFS2_FS is not set | ||
1014 | # CONFIG_MINIX_FS is not set | ||
1015 | # CONFIG_ROMFS_FS is not set | ||
1016 | CONFIG_INOTIFY=y | ||
1017 | CONFIG_INOTIFY_USER=y | ||
1018 | # CONFIG_QUOTA is not set | ||
1019 | CONFIG_DNOTIFY=y | ||
1020 | # CONFIG_AUTOFS_FS is not set | ||
1021 | # CONFIG_AUTOFS4_FS is not set | ||
1022 | # CONFIG_FUSE_FS is not set | ||
1023 | |||
1024 | # | ||
1025 | # CD-ROM/DVD Filesystems | ||
1026 | # | ||
1027 | # CONFIG_ISO9660_FS is not set | ||
1028 | # CONFIG_UDF_FS is not set | ||
1029 | |||
1030 | # | ||
1031 | # DOS/FAT/NT Filesystems | ||
1032 | # | ||
1033 | CONFIG_FAT_FS=y | ||
1034 | CONFIG_MSDOS_FS=y | ||
1035 | CONFIG_VFAT_FS=y | ||
1036 | CONFIG_FAT_DEFAULT_CODEPAGE=437 | ||
1037 | CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" | ||
1038 | # CONFIG_NTFS_FS is not set | ||
1039 | |||
1040 | # | ||
1041 | # Pseudo filesystems | ||
1042 | # | ||
1043 | CONFIG_PROC_FS=y | ||
1044 | CONFIG_PROC_SYSCTL=y | ||
1045 | CONFIG_SYSFS=y | ||
1046 | CONFIG_TMPFS=y | ||
1047 | # CONFIG_TMPFS_POSIX_ACL is not set | ||
1048 | # CONFIG_HUGETLB_PAGE is not set | ||
1049 | CONFIG_RAMFS=y | ||
1050 | # CONFIG_CONFIGFS_FS is not set | ||
1051 | |||
1052 | # | ||
1053 | # Miscellaneous filesystems | ||
1054 | # | ||
1055 | # CONFIG_ADFS_FS is not set | ||
1056 | # CONFIG_AFFS_FS is not set | ||
1057 | # CONFIG_HFS_FS is not set | ||
1058 | # CONFIG_HFSPLUS_FS is not set | ||
1059 | # CONFIG_BEFS_FS is not set | ||
1060 | # CONFIG_BFS_FS is not set | ||
1061 | # CONFIG_EFS_FS is not set | ||
1062 | CONFIG_JFFS2_FS=y | ||
1063 | CONFIG_JFFS2_FS_DEBUG=0 | ||
1064 | CONFIG_JFFS2_FS_WRITEBUFFER=y | ||
1065 | CONFIG_JFFS2_SUMMARY=y | ||
1066 | # CONFIG_JFFS2_FS_XATTR is not set | ||
1067 | # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set | ||
1068 | CONFIG_JFFS2_ZLIB=y | ||
1069 | CONFIG_JFFS2_RTIME=y | ||
1070 | # CONFIG_JFFS2_RUBIN is not set | ||
1071 | # CONFIG_CRAMFS is not set | ||
1072 | # CONFIG_VXFS_FS is not set | ||
1073 | # CONFIG_HPFS_FS is not set | ||
1074 | # CONFIG_QNX4FS_FS is not set | ||
1075 | # CONFIG_SYSV_FS is not set | ||
1076 | # CONFIG_UFS_FS is not set | ||
1077 | |||
1078 | # | ||
1079 | # Network File Systems | ||
1080 | # | ||
1081 | CONFIG_NFS_FS=y | ||
1082 | CONFIG_NFS_V3=y | ||
1083 | # CONFIG_NFS_V3_ACL is not set | ||
1084 | # CONFIG_NFS_V4 is not set | ||
1085 | # CONFIG_NFS_DIRECTIO is not set | ||
1086 | # CONFIG_NFSD is not set | ||
1087 | CONFIG_ROOT_NFS=y | ||
1088 | CONFIG_LOCKD=y | ||
1089 | CONFIG_LOCKD_V4=y | ||
1090 | CONFIG_NFS_COMMON=y | ||
1091 | CONFIG_SUNRPC=y | ||
1092 | # CONFIG_SUNRPC_BIND34 is not set | ||
1093 | # CONFIG_RPCSEC_GSS_KRB5 is not set | ||
1094 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | ||
1095 | CONFIG_SMB_FS=y | ||
1096 | # CONFIG_SMB_NLS_DEFAULT is not set | ||
1097 | # CONFIG_CIFS is not set | ||
1098 | # CONFIG_NCP_FS is not set | ||
1099 | # CONFIG_CODA_FS is not set | ||
1100 | # CONFIG_AFS_FS is not set | ||
1101 | # CONFIG_9P_FS is not set | ||
1102 | |||
1103 | # | ||
1104 | # Partition Types | ||
1105 | # | ||
1106 | # CONFIG_PARTITION_ADVANCED is not set | ||
1107 | CONFIG_MSDOS_PARTITION=y | ||
1108 | |||
1109 | # | ||
1110 | # Native Language Support | ||
1111 | # | ||
1112 | CONFIG_NLS=y | ||
1113 | CONFIG_NLS_DEFAULT="iso8859-1" | ||
1114 | CONFIG_NLS_CODEPAGE_437=y | ||
1115 | # CONFIG_NLS_CODEPAGE_737 is not set | ||
1116 | # CONFIG_NLS_CODEPAGE_775 is not set | ||
1117 | # CONFIG_NLS_CODEPAGE_850 is not set | ||
1118 | # CONFIG_NLS_CODEPAGE_852 is not set | ||
1119 | # CONFIG_NLS_CODEPAGE_855 is not set | ||
1120 | # CONFIG_NLS_CODEPAGE_857 is not set | ||
1121 | # CONFIG_NLS_CODEPAGE_860 is not set | ||
1122 | # CONFIG_NLS_CODEPAGE_861 is not set | ||
1123 | # CONFIG_NLS_CODEPAGE_862 is not set | ||
1124 | # CONFIG_NLS_CODEPAGE_863 is not set | ||
1125 | # CONFIG_NLS_CODEPAGE_864 is not set | ||
1126 | # CONFIG_NLS_CODEPAGE_865 is not set | ||
1127 | # CONFIG_NLS_CODEPAGE_866 is not set | ||
1128 | # CONFIG_NLS_CODEPAGE_869 is not set | ||
1129 | # CONFIG_NLS_CODEPAGE_936 is not set | ||
1130 | # CONFIG_NLS_CODEPAGE_950 is not set | ||
1131 | # CONFIG_NLS_CODEPAGE_932 is not set | ||
1132 | # CONFIG_NLS_CODEPAGE_949 is not set | ||
1133 | # CONFIG_NLS_CODEPAGE_874 is not set | ||
1134 | # CONFIG_NLS_ISO8859_8 is not set | ||
1135 | # CONFIG_NLS_CODEPAGE_1250 is not set | ||
1136 | # CONFIG_NLS_CODEPAGE_1251 is not set | ||
1137 | # CONFIG_NLS_ASCII is not set | ||
1138 | CONFIG_NLS_ISO8859_1=y | ||
1139 | # CONFIG_NLS_ISO8859_2 is not set | ||
1140 | # CONFIG_NLS_ISO8859_3 is not set | ||
1141 | # CONFIG_NLS_ISO8859_4 is not set | ||
1142 | # CONFIG_NLS_ISO8859_5 is not set | ||
1143 | # CONFIG_NLS_ISO8859_6 is not set | ||
1144 | # CONFIG_NLS_ISO8859_7 is not set | ||
1145 | # CONFIG_NLS_ISO8859_9 is not set | ||
1146 | # CONFIG_NLS_ISO8859_13 is not set | ||
1147 | # CONFIG_NLS_ISO8859_14 is not set | ||
1148 | # CONFIG_NLS_ISO8859_15 is not set | ||
1149 | # CONFIG_NLS_KOI8_R is not set | ||
1150 | # CONFIG_NLS_KOI8_U is not set | ||
1151 | CONFIG_NLS_UTF8=y | ||
1152 | |||
1153 | # | ||
1154 | # Distributed Lock Manager | ||
1155 | # | ||
1156 | # CONFIG_DLM is not set | ||
1157 | |||
1158 | # | ||
1159 | # Profiling support | ||
1160 | # | ||
1161 | # CONFIG_PROFILING is not set | ||
1162 | |||
1163 | # | ||
1164 | # Kernel hacking | ||
1165 | # | ||
1166 | # CONFIG_PRINTK_TIME is not set | ||
1167 | CONFIG_ENABLE_MUST_CHECK=y | ||
1168 | CONFIG_MAGIC_SYSRQ=y | ||
1169 | # CONFIG_UNUSED_SYMBOLS is not set | ||
1170 | # CONFIG_DEBUG_FS is not set | ||
1171 | # CONFIG_HEADERS_CHECK is not set | ||
1172 | CONFIG_DEBUG_KERNEL=y | ||
1173 | # CONFIG_DEBUG_SHIRQ is not set | ||
1174 | # CONFIG_DETECT_SOFTLOCKUP is not set | ||
1175 | # CONFIG_SCHEDSTATS is not set | ||
1176 | # CONFIG_TIMER_STATS is not set | ||
1177 | # CONFIG_DEBUG_SLAB is not set | ||
1178 | # CONFIG_DEBUG_RT_MUTEXES is not set | ||
1179 | # CONFIG_RT_MUTEX_TESTER is not set | ||
1180 | # CONFIG_DEBUG_SPINLOCK is not set | ||
1181 | # CONFIG_DEBUG_MUTEXES is not set | ||
1182 | # CONFIG_DEBUG_LOCK_ALLOC is not set | ||
1183 | # CONFIG_PROVE_LOCKING is not set | ||
1184 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | ||
1185 | # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set | ||
1186 | # CONFIG_DEBUG_KOBJECT is not set | ||
1187 | # CONFIG_DEBUG_BUGVERBOSE is not set | ||
1188 | CONFIG_DEBUG_INFO=y | ||
1189 | # CONFIG_DEBUG_VM is not set | ||
1190 | # CONFIG_DEBUG_LIST is not set | ||
1191 | CONFIG_FRAME_POINTER=y | ||
1192 | CONFIG_FORCED_INLINING=y | ||
1193 | # CONFIG_RCU_TORTURE_TEST is not set | ||
1194 | # CONFIG_FAULT_INJECTION is not set | ||
1195 | CONFIG_DEBUG_USER=y | ||
1196 | CONFIG_DEBUG_ERRORS=y | ||
1197 | CONFIG_DEBUG_LL=y | ||
1198 | # CONFIG_DEBUG_ICEDCC is not set | ||
1199 | |||
1200 | # | ||
1201 | # Security options | ||
1202 | # | ||
1203 | # CONFIG_KEYS is not set | ||
1204 | # CONFIG_SECURITY is not set | ||
1205 | |||
1206 | # | ||
1207 | # Cryptographic options | ||
1208 | # | ||
1209 | CONFIG_CRYPTO=y | ||
1210 | CONFIG_CRYPTO_ALGAPI=m | ||
1211 | CONFIG_CRYPTO_BLKCIPHER=m | ||
1212 | CONFIG_CRYPTO_MANAGER=m | ||
1213 | # CONFIG_CRYPTO_HMAC is not set | ||
1214 | # CONFIG_CRYPTO_XCBC is not set | ||
1215 | # CONFIG_CRYPTO_NULL is not set | ||
1216 | # CONFIG_CRYPTO_MD4 is not set | ||
1217 | # CONFIG_CRYPTO_MD5 is not set | ||
1218 | # CONFIG_CRYPTO_SHA1 is not set | ||
1219 | # CONFIG_CRYPTO_SHA256 is not set | ||
1220 | # CONFIG_CRYPTO_SHA512 is not set | ||
1221 | # CONFIG_CRYPTO_WP512 is not set | ||
1222 | # CONFIG_CRYPTO_TGR192 is not set | ||
1223 | # CONFIG_CRYPTO_GF128MUL is not set | ||
1224 | CONFIG_CRYPTO_ECB=m | ||
1225 | CONFIG_CRYPTO_CBC=m | ||
1226 | CONFIG_CRYPTO_PCBC=m | ||
1227 | # CONFIG_CRYPTO_LRW is not set | ||
1228 | # CONFIG_CRYPTO_CRYPTD is not set | ||
1229 | # CONFIG_CRYPTO_DES is not set | ||
1230 | # CONFIG_CRYPTO_FCRYPT is not set | ||
1231 | # CONFIG_CRYPTO_BLOWFISH is not set | ||
1232 | # CONFIG_CRYPTO_TWOFISH is not set | ||
1233 | # CONFIG_CRYPTO_SERPENT is not set | ||
1234 | CONFIG_CRYPTO_AES=m | ||
1235 | # CONFIG_CRYPTO_CAST5 is not set | ||
1236 | # CONFIG_CRYPTO_CAST6 is not set | ||
1237 | # CONFIG_CRYPTO_TEA is not set | ||
1238 | CONFIG_CRYPTO_ARC4=m | ||
1239 | # CONFIG_CRYPTO_KHAZAD is not set | ||
1240 | # CONFIG_CRYPTO_ANUBIS is not set | ||
1241 | # CONFIG_CRYPTO_DEFLATE is not set | ||
1242 | # CONFIG_CRYPTO_MICHAEL_MIC is not set | ||
1243 | # CONFIG_CRYPTO_CRC32C is not set | ||
1244 | # CONFIG_CRYPTO_CAMELLIA is not set | ||
1245 | # CONFIG_CRYPTO_TEST is not set | ||
1246 | |||
1247 | # | ||
1248 | # Hardware crypto devices | ||
1249 | # | ||
1250 | |||
1251 | # | ||
1252 | # Library routines | ||
1253 | # | ||
1254 | CONFIG_BITREVERSE=y | ||
1255 | # CONFIG_CRC_CCITT is not set | ||
1256 | # CONFIG_CRC16 is not set | ||
1257 | # CONFIG_CRC_ITU_T is not set | ||
1258 | CONFIG_CRC32=y | ||
1259 | # CONFIG_LIBCRC32C is not set | ||
1260 | CONFIG_ZLIB_INFLATE=y | ||
1261 | CONFIG_ZLIB_DEFLATE=y | ||
1262 | CONFIG_PLIST=y | ||
1263 | CONFIG_HAS_IOMEM=y | ||
1264 | CONFIG_HAS_IOPORT=y | ||
1265 | CONFIG_HAS_DMA=y | ||
diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig index 1d5150e4d6b3..f8a1645b3d4a 100644 --- a/arch/arm/configs/s3c2410_defconfig +++ b/arch/arm/configs/s3c2410_defconfig | |||
@@ -138,11 +138,11 @@ CONFIG_ARCH_S3C2410=y | |||
138 | CONFIG_PLAT_S3C24XX=y | 138 | CONFIG_PLAT_S3C24XX=y |
139 | CONFIG_CPU_S3C244X=y | 139 | CONFIG_CPU_S3C244X=y |
140 | CONFIG_PM_SIMTEC=y | 140 | CONFIG_PM_SIMTEC=y |
141 | # CONFIG_S3C2410_BOOT_WATCHDOG is not set | 141 | # CONFIG_S3C_BOOT_WATCHDOG is not set |
142 | # CONFIG_S3C2410_BOOT_ERROR_RESET is not set | 142 | # CONFIG_S3C_BOOT_ERROR_RESET is not set |
143 | # CONFIG_S3C2410_PM_DEBUG is not set | 143 | # CONFIG_S3C2410_PM_DEBUG is not set |
144 | # CONFIG_S3C2410_PM_CHECK is not set | 144 | # CONFIG_S3C2410_PM_CHECK is not set |
145 | CONFIG_S3C2410_LOWLEVEL_UART_PORT=0 | 145 | CONFIG_S3C_LOWLEVEL_UART_PORT=0 |
146 | CONFIG_S3C2410_DMA=y | 146 | CONFIG_S3C2410_DMA=y |
147 | # CONFIG_S3C2410_DMA_DEBUG is not set | 147 | # CONFIG_S3C2410_DMA_DEBUG is not set |
148 | CONFIG_MACH_SMDK=y | 148 | CONFIG_MACH_SMDK=y |
@@ -1392,8 +1392,8 @@ CONFIG_DEBUG_USER=y | |||
1392 | # CONFIG_DEBUG_ERRORS is not set | 1392 | # CONFIG_DEBUG_ERRORS is not set |
1393 | CONFIG_DEBUG_LL=y | 1393 | CONFIG_DEBUG_LL=y |
1394 | # CONFIG_DEBUG_ICEDCC is not set | 1394 | # CONFIG_DEBUG_ICEDCC is not set |
1395 | CONFIG_DEBUG_S3C2410_PORT=y | 1395 | CONFIG_DEBUG_S3C_PORT=y |
1396 | CONFIG_DEBUG_S3C2410_UART=0 | 1396 | CONFIG_DEBUG_S3C_UART=0 |
1397 | 1397 | ||
1398 | # | 1398 | # |
1399 | # Security options | 1399 | # Security options |
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c index 70599bcf451c..0417c165d50d 100644 --- a/arch/arm/mach-at91/at91rm9200_devices.c +++ b/arch/arm/mach-at91/at91rm9200_devices.c | |||
@@ -477,7 +477,7 @@ void __init at91_add_device_i2c(void) {} | |||
477 | * SPI | 477 | * SPI |
478 | * -------------------------------------------------------------------- */ | 478 | * -------------------------------------------------------------------- */ |
479 | 479 | ||
480 | #if defined(CONFIG_SPI_AT91) || defined(CONFIG_SPI_AT91_MODULE) || defined(CONFIG_AT91_SPI) || defined(CONFIG_AT91_SPI_MODULE) | 480 | #if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) |
481 | static u64 spi_dmamask = 0xffffffffUL; | 481 | static u64 spi_dmamask = 0xffffffffUL; |
482 | 482 | ||
483 | static struct resource spi_resources[] = { | 483 | static struct resource spi_resources[] = { |
@@ -494,7 +494,7 @@ static struct resource spi_resources[] = { | |||
494 | }; | 494 | }; |
495 | 495 | ||
496 | static struct platform_device at91rm9200_spi_device = { | 496 | static struct platform_device at91rm9200_spi_device = { |
497 | .name = "at91_spi", | 497 | .name = "atmel_spi", |
498 | .id = 0, | 498 | .id = 0, |
499 | .dev = { | 499 | .dev = { |
500 | .dma_mask = &spi_dmamask, | 500 | .dma_mask = &spi_dmamask, |
@@ -522,18 +522,14 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) | |||
522 | else | 522 | else |
523 | cs_pin = spi_standard_cs[devices[i].chip_select]; | 523 | cs_pin = spi_standard_cs[devices[i].chip_select]; |
524 | 524 | ||
525 | #ifdef CONFIG_SPI_AT91_MANUAL_CS | 525 | /* enable chip-select pin */ |
526 | at91_set_gpio_output(cs_pin, 1); | 526 | at91_set_gpio_output(cs_pin, 1); |
527 | #else | ||
528 | at91_set_A_periph(cs_pin, 0); | ||
529 | #endif | ||
530 | 527 | ||
531 | /* pass chip-select pin to driver */ | 528 | /* pass chip-select pin to driver */ |
532 | devices[i].controller_data = (void *) cs_pin; | 529 | devices[i].controller_data = (void *) cs_pin; |
533 | } | 530 | } |
534 | 531 | ||
535 | spi_register_board_info(devices, nr_devices); | 532 | spi_register_board_info(devices, nr_devices); |
536 | at91_clock_associate("spi_clk", &at91rm9200_spi_device.dev, "spi"); | ||
537 | platform_device_register(&at91rm9200_spi_device); | 533 | platform_device_register(&at91rm9200_spi_device); |
538 | } | 534 | } |
539 | #else | 535 | #else |
diff --git a/arch/arm/mach-iop32x/Kconfig b/arch/arm/mach-iop32x/Kconfig index 9bb02b6d7ae1..dbe07c9472ed 100644 --- a/arch/arm/mach-iop32x/Kconfig +++ b/arch/arm/mach-iop32x/Kconfig | |||
@@ -42,6 +42,13 @@ config IOP3XX_ATU | |||
42 | Say N if the IOP is an add in card, the host system owns the PCI | 42 | Say N if the IOP is an add in card, the host system owns the PCI |
43 | bus in this case. | 43 | bus in this case. |
44 | 44 | ||
45 | config MACH_EM7210 | ||
46 | bool "Enable support for the Lanner EM7210" | ||
47 | help | ||
48 | Say Y here if you want to run your kernel on the Lanner EM7210 | ||
49 | board. Say also Y here if you have a SS4000e Baxter Creek NAS | ||
50 | appliance." | ||
51 | |||
45 | endmenu | 52 | endmenu |
46 | 53 | ||
47 | endif | 54 | endif |
diff --git a/arch/arm/mach-iop32x/Makefile b/arch/arm/mach-iop32x/Makefile index 7b05b37e1f94..cfdf8a137c2b 100644 --- a/arch/arm/mach-iop32x/Makefile +++ b/arch/arm/mach-iop32x/Makefile | |||
@@ -11,3 +11,4 @@ obj-$(CONFIG_MACH_GLANTANK) += glantank.o | |||
11 | obj-$(CONFIG_ARCH_IQ80321) += iq80321.o | 11 | obj-$(CONFIG_ARCH_IQ80321) += iq80321.o |
12 | obj-$(CONFIG_ARCH_IQ31244) += iq31244.o | 12 | obj-$(CONFIG_ARCH_IQ31244) += iq31244.o |
13 | obj-$(CONFIG_MACH_N2100) += n2100.o | 13 | obj-$(CONFIG_MACH_N2100) += n2100.o |
14 | obj-$(CONFIG_MACH_EM7210) += em7210.o | ||
diff --git a/arch/arm/mach-iop32x/em7210.c b/arch/arm/mach-iop32x/em7210.c new file mode 100644 index 000000000000..c947152f9a3c --- /dev/null +++ b/arch/arm/mach-iop32x/em7210.c | |||
@@ -0,0 +1,215 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-iop32x/em7210.c | ||
3 | * | ||
4 | * Board support code for the Lanner EM7210 platforms. | ||
5 | * | ||
6 | * Based on arch/arm/mach-iop32x/iq31244.c file. | ||
7 | * | ||
8 | * Copyright (C) 2007 Arnaud Patard <arnaud.patard@rtp-net.org> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/mm.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/pci.h> | ||
20 | #include <linux/pm.h> | ||
21 | #include <linux/serial_core.h> | ||
22 | #include <linux/serial_8250.h> | ||
23 | #include <linux/mtd/physmap.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/i2c.h> | ||
26 | #include <asm/hardware.h> | ||
27 | #include <linux/io.h> | ||
28 | #include <linux/irq.h> | ||
29 | #include <asm/mach/arch.h> | ||
30 | #include <asm/mach/map.h> | ||
31 | #include <asm/mach/pci.h> | ||
32 | #include <asm/mach/time.h> | ||
33 | #include <asm/mach-types.h> | ||
34 | #include <asm/arch/time.h> | ||
35 | |||
36 | static void __init em7210_timer_init(void) | ||
37 | { | ||
38 | /* http://www.kwaak.net/fotos/fotos-nas/slide_24.html */ | ||
39 | /* 33.333 MHz crystal. */ | ||
40 | iop_init_time(200000000); | ||
41 | } | ||
42 | |||
43 | static struct sys_timer em7210_timer = { | ||
44 | .init = em7210_timer_init, | ||
45 | .offset = iop_gettimeoffset, | ||
46 | }; | ||
47 | |||
48 | /* | ||
49 | * EM7210 RTC | ||
50 | */ | ||
51 | static struct i2c_board_info __initdata em7210_i2c_devices[] = { | ||
52 | { | ||
53 | I2C_BOARD_INFO("rtc-rs5c372", 0x32), | ||
54 | .type = "rs5c372a", | ||
55 | }, | ||
56 | }; | ||
57 | |||
58 | /* | ||
59 | * EM7210 I/O | ||
60 | */ | ||
61 | static struct map_desc em7210_io_desc[] __initdata = { | ||
62 | { /* on-board devices */ | ||
63 | .virtual = IQ31244_UART, | ||
64 | .pfn = __phys_to_pfn(IQ31244_UART), | ||
65 | .length = 0x00100000, | ||
66 | .type = MT_DEVICE, | ||
67 | }, | ||
68 | }; | ||
69 | |||
70 | void __init em7210_map_io(void) | ||
71 | { | ||
72 | iop3xx_map_io(); | ||
73 | iotable_init(em7210_io_desc, ARRAY_SIZE(em7210_io_desc)); | ||
74 | } | ||
75 | |||
76 | |||
77 | /* | ||
78 | * EM7210 PCI | ||
79 | */ | ||
80 | #define INTA IRQ_IOP32X_XINT0 | ||
81 | #define INTB IRQ_IOP32X_XINT1 | ||
82 | #define INTC IRQ_IOP32X_XINT2 | ||
83 | #define INTD IRQ_IOP32X_XINT3 | ||
84 | |||
85 | static int __init | ||
86 | em7210_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | ||
87 | { | ||
88 | static int pci_irq_table[][4] = { | ||
89 | /* | ||
90 | * PCI IDSEL/INTPIN->INTLINE | ||
91 | * A B C D | ||
92 | */ | ||
93 | {INTB, INTB, INTB, INTB}, /* console / uart */ | ||
94 | {INTA, INTA, INTA, INTA}, /* 1st 82541 */ | ||
95 | {INTD, INTD, INTD, INTD}, /* 2nd 82541 */ | ||
96 | {INTC, INTC, INTC, INTC}, /* GD31244 */ | ||
97 | {INTD, INTA, INTA, INTA}, /* mini-PCI */ | ||
98 | {INTD, INTC, INTA, INTA}, /* NEC USB */ | ||
99 | }; | ||
100 | |||
101 | if (pin < 1 || pin > 4) | ||
102 | return -1; | ||
103 | |||
104 | return pci_irq_table[slot % 6][pin - 1]; | ||
105 | } | ||
106 | |||
107 | static struct hw_pci em7210_pci __initdata = { | ||
108 | .swizzle = pci_std_swizzle, | ||
109 | .nr_controllers = 1, | ||
110 | .setup = iop3xx_pci_setup, | ||
111 | .preinit = iop3xx_pci_preinit, | ||
112 | .scan = iop3xx_pci_scan_bus, | ||
113 | .map_irq = em7210_pci_map_irq, | ||
114 | }; | ||
115 | |||
116 | static int __init em7210_pci_init(void) | ||
117 | { | ||
118 | if (machine_is_em7210()) | ||
119 | pci_common_init(&em7210_pci); | ||
120 | |||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | subsys_initcall(em7210_pci_init); | ||
125 | |||
126 | |||
127 | /* | ||
128 | * EM7210 Flash | ||
129 | */ | ||
130 | static struct physmap_flash_data em7210_flash_data = { | ||
131 | .width = 2, | ||
132 | }; | ||
133 | |||
134 | static struct resource em7210_flash_resource = { | ||
135 | .start = 0xf0000000, | ||
136 | .end = 0xf1ffffff, | ||
137 | .flags = IORESOURCE_MEM, | ||
138 | }; | ||
139 | |||
140 | static struct platform_device em7210_flash_device = { | ||
141 | .name = "physmap-flash", | ||
142 | .id = 0, | ||
143 | .dev = { | ||
144 | .platform_data = &em7210_flash_data, | ||
145 | }, | ||
146 | .num_resources = 1, | ||
147 | .resource = &em7210_flash_resource, | ||
148 | }; | ||
149 | |||
150 | |||
151 | /* | ||
152 | * EM7210 UART | ||
153 | * The physical address of the serial port is 0xfe800000, | ||
154 | * so it can be used for physical and virtual address. | ||
155 | */ | ||
156 | static struct plat_serial8250_port em7210_serial_port[] = { | ||
157 | { | ||
158 | .mapbase = IQ31244_UART, | ||
159 | .membase = (char *)IQ31244_UART, | ||
160 | .irq = IRQ_IOP32X_XINT1, | ||
161 | .flags = UPF_SKIP_TEST, | ||
162 | .iotype = UPIO_MEM, | ||
163 | .regshift = 0, | ||
164 | .uartclk = 1843200, | ||
165 | }, | ||
166 | { }, | ||
167 | }; | ||
168 | |||
169 | static struct resource em7210_uart_resource = { | ||
170 | .start = IQ31244_UART, | ||
171 | .end = IQ31244_UART + 7, | ||
172 | .flags = IORESOURCE_MEM, | ||
173 | }; | ||
174 | |||
175 | static struct platform_device em7210_serial_device = { | ||
176 | .name = "serial8250", | ||
177 | .id = PLAT8250_DEV_PLATFORM, | ||
178 | .dev = { | ||
179 | .platform_data = em7210_serial_port, | ||
180 | }, | ||
181 | .num_resources = 1, | ||
182 | .resource = &em7210_uart_resource, | ||
183 | }; | ||
184 | |||
185 | void em7210_power_off(void) | ||
186 | { | ||
187 | *IOP3XX_GPOE &= 0xfe; | ||
188 | *IOP3XX_GPOD |= 0x01; | ||
189 | } | ||
190 | |||
191 | static void __init em7210_init_machine(void) | ||
192 | { | ||
193 | platform_device_register(&em7210_serial_device); | ||
194 | platform_device_register(&iop3xx_i2c0_device); | ||
195 | platform_device_register(&iop3xx_i2c1_device); | ||
196 | platform_device_register(&em7210_flash_device); | ||
197 | platform_device_register(&iop3xx_dma_0_channel); | ||
198 | platform_device_register(&iop3xx_dma_1_channel); | ||
199 | |||
200 | i2c_register_board_info(0, em7210_i2c_devices, | ||
201 | ARRAY_SIZE(em7210_i2c_devices)); | ||
202 | |||
203 | |||
204 | pm_power_off = em7210_power_off; | ||
205 | } | ||
206 | |||
207 | MACHINE_START(EM7210, "Lanner EM7210") | ||
208 | .phys_io = IQ31244_UART, | ||
209 | .io_pg_offst = ((IQ31244_UART) >> 18) & 0xfffc, | ||
210 | .boot_params = 0xa0000100, | ||
211 | .map_io = em7210_map_io, | ||
212 | .init_irq = iop32x_init_irq, | ||
213 | .timer = &em7210_timer, | ||
214 | .init_machine = em7210_init_machine, | ||
215 | MACHINE_END | ||
diff --git a/arch/arm/mach-iop32x/irq.c b/arch/arm/mach-iop32x/irq.c index c971171c2905..55cf0162e8c1 100644 --- a/arch/arm/mach-iop32x/irq.c +++ b/arch/arm/mach-iop32x/irq.c | |||
@@ -63,7 +63,8 @@ void __init iop32x_init_irq(void) | |||
63 | if (machine_is_glantank() || | 63 | if (machine_is_glantank() || |
64 | machine_is_iq80321() || | 64 | machine_is_iq80321() || |
65 | machine_is_iq31244() || | 65 | machine_is_iq31244() || |
66 | machine_is_n2100()) | 66 | machine_is_n2100() || |
67 | machine_is_em7210()) | ||
67 | *IOP3XX_PCIIRSR = 0x0f; | 68 | *IOP3XX_PCIIRSR = 0x0f; |
68 | 69 | ||
69 | for (i = 0; i < NR_IRQS; i++) { | 70 | for (i = 0; i < NR_IRQS; i++) { |
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index 23e7fba6d3e1..c1271c449246 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c | |||
@@ -188,7 +188,7 @@ static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type) | |||
188 | *int_reg |= (int_style << (line * IXP4XX_GPIO_STYLE_SIZE)); | 188 | *int_reg |= (int_style << (line * IXP4XX_GPIO_STYLE_SIZE)); |
189 | 189 | ||
190 | /* Configure the line as an input */ | 190 | /* Configure the line as an input */ |
191 | gpio_line_config(line, IXP4XX_GPIO_IN); | 191 | gpio_line_config(irq2gpio[irq], IXP4XX_GPIO_IN); |
192 | 192 | ||
193 | return 0; | 193 | return 0; |
194 | } | 194 | } |
diff --git a/arch/arm/mach-ks8695/irq.c b/arch/arm/mach-ks8695/irq.c index 2407bba00547..4c3ab43e1046 100644 --- a/arch/arm/mach-ks8695/irq.c +++ b/arch/arm/mach-ks8695/irq.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
25 | #include <linux/ioport.h> | 25 | #include <linux/ioport.h> |
26 | #include <linux/ptrace.h> | ||
27 | #include <linux/sysdev.h> | 26 | #include <linux/sysdev.h> |
28 | 27 | ||
29 | #include <asm/hardware.h> | 28 | #include <asm/hardware.h> |
diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig new file mode 100644 index 000000000000..5fe8606cac08 --- /dev/null +++ b/arch/arm/mach-mx3/Kconfig | |||
@@ -0,0 +1,12 @@ | |||
1 | menu "MX3 Options" | ||
2 | depends on ARCH_MX3 | ||
3 | |||
4 | config MACH_MX31ADS | ||
5 | bool "Support MX31ADS platforms" | ||
6 | default y | ||
7 | help | ||
8 | Include support for MX31ADS platform. This includes specific | ||
9 | configurations for the board and its peripherals. | ||
10 | |||
11 | endmenu | ||
12 | |||
diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile new file mode 100644 index 000000000000..cbec997f332a --- /dev/null +++ b/arch/arm/mach-mx3/Makefile | |||
@@ -0,0 +1,8 @@ | |||
1 | # | ||
2 | # Makefile for the linux kernel. | ||
3 | # | ||
4 | |||
5 | # Object file lists. | ||
6 | |||
7 | obj-y := mm.o time.o | ||
8 | obj-$(CONFIG_MACH_MX31ADS) += mx31ads.o | ||
diff --git a/arch/arm/mach-mx3/Makefile.boot b/arch/arm/mach-mx3/Makefile.boot new file mode 100644 index 000000000000..e1dd366f836b --- /dev/null +++ b/arch/arm/mach-mx3/Makefile.boot | |||
@@ -0,0 +1,3 @@ | |||
1 | zreladdr-y := 0x80008000 | ||
2 | params_phys-y := 0x80000100 | ||
3 | initrd_phys-y := 0x80800000 | ||
diff --git a/arch/arm/mach-mx3/mm.c b/arch/arm/mach-mx3/mm.c new file mode 100644 index 000000000000..41dad485ded9 --- /dev/null +++ b/arch/arm/mach-mx3/mm.c | |||
@@ -0,0 +1,64 @@ | |||
1 | /* | ||
2 | * Copyright (C) 1999,2000 Arm Limited | ||
3 | * Copyright (C) 2000 Deep Blue Solutions Ltd | ||
4 | * Copyright (C) 2002 Shane Nay (shane@minirl.com) | ||
5 | * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
6 | * - add MX31 specific definitions | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
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, MA 02111-1307 USA | ||
21 | */ | ||
22 | |||
23 | #include <linux/mm.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <asm/hardware.h> | ||
26 | #include <asm/pgtable.h> | ||
27 | #include <asm/mach/map.h> | ||
28 | #include <asm/arch/common.h> | ||
29 | |||
30 | /*! | ||
31 | * @file mm.c | ||
32 | * | ||
33 | * @brief This file creates static virtual to physical mappings, common to all MX3 boards. | ||
34 | * | ||
35 | * @ingroup Memory | ||
36 | */ | ||
37 | |||
38 | /*! | ||
39 | * This table defines static virtual address mappings for I/O regions. | ||
40 | * These are the mappings common across all MX3 boards. | ||
41 | */ | ||
42 | static struct map_desc mxc_io_desc[] __initdata = { | ||
43 | { | ||
44 | .virtual = X_MEMC_BASE_ADDR_VIRT, | ||
45 | .pfn = __phys_to_pfn(X_MEMC_BASE_ADDR), | ||
46 | .length = X_MEMC_SIZE, | ||
47 | .type = MT_DEVICE | ||
48 | }, { | ||
49 | .virtual = AVIC_BASE_ADDR_VIRT, | ||
50 | .pfn = __phys_to_pfn(AVIC_BASE_ADDR), | ||
51 | .length = AVIC_SIZE, | ||
52 | .type = MT_NONSHARED_DEVICE | ||
53 | }, | ||
54 | }; | ||
55 | |||
56 | /*! | ||
57 | * This function initializes the memory map. It is called during the | ||
58 | * system startup to create static physical to virtual memory mappings | ||
59 | * for the IO modules. | ||
60 | */ | ||
61 | void __init mxc_map_io(void) | ||
62 | { | ||
63 | iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc)); | ||
64 | } | ||
diff --git a/arch/arm/mach-mx3/mx31ads.c b/arch/arm/mach-mx3/mx31ads.c new file mode 100644 index 000000000000..7e89bdc23a9f --- /dev/null +++ b/arch/arm/mach-mx3/mx31ads.c | |||
@@ -0,0 +1,142 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000 Deep Blue Solutions Ltd | ||
3 | * Copyright (C) 2002 Shane Nay (shane@minirl.com) | ||
4 | * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
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, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
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 | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <linux/types.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/clk.h> | ||
24 | #include <linux/serial_8250.h> | ||
25 | |||
26 | #include <asm/hardware.h> | ||
27 | #include <asm/mach-types.h> | ||
28 | #include <asm/mach/arch.h> | ||
29 | #include <asm/memory.h> | ||
30 | #include <asm/mach/map.h> | ||
31 | #include <asm/arch/common.h> | ||
32 | |||
33 | /*! | ||
34 | * @file mx31ads.c | ||
35 | * | ||
36 | * @brief This file contains the board-specific initialization routines. | ||
37 | * | ||
38 | * @ingroup System | ||
39 | */ | ||
40 | |||
41 | #if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) | ||
42 | /*! | ||
43 | * The serial port definition structure. | ||
44 | */ | ||
45 | static struct plat_serial8250_port serial_platform_data[] = { | ||
46 | { | ||
47 | .membase = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTA), | ||
48 | .mapbase = (unsigned long)(CS4_BASE_ADDR + PBC_SC16C652_UARTA), | ||
49 | .irq = EXPIO_INT_XUART_INTA, | ||
50 | .uartclk = 14745600, | ||
51 | .regshift = 0, | ||
52 | .iotype = UPIO_MEM, | ||
53 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ, | ||
54 | }, { | ||
55 | .membase = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTB), | ||
56 | .mapbase = (unsigned long)(CS4_BASE_ADDR + PBC_SC16C652_UARTB), | ||
57 | .irq = EXPIO_INT_XUART_INTB, | ||
58 | .uartclk = 14745600, | ||
59 | .regshift = 0, | ||
60 | .iotype = UPIO_MEM, | ||
61 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ, | ||
62 | }, | ||
63 | {}, | ||
64 | }; | ||
65 | |||
66 | static struct platform_device serial_device = { | ||
67 | .name = "serial8250", | ||
68 | .id = 0, | ||
69 | .dev = { | ||
70 | .platform_data = serial_platform_data, | ||
71 | }, | ||
72 | }; | ||
73 | |||
74 | static int __init mxc_init_extuart(void) | ||
75 | { | ||
76 | return platform_device_register(&serial_device); | ||
77 | } | ||
78 | #else | ||
79 | static inline int mxc_init_extuart(void) | ||
80 | { | ||
81 | return 0; | ||
82 | } | ||
83 | #endif | ||
84 | |||
85 | /*! | ||
86 | * This structure defines static mappings for the i.MX31ADS board. | ||
87 | */ | ||
88 | static struct map_desc mx31ads_io_desc[] __initdata = { | ||
89 | { | ||
90 | .virtual = AIPS1_BASE_ADDR_VIRT, | ||
91 | .pfn = __phys_to_pfn(AIPS1_BASE_ADDR), | ||
92 | .length = AIPS1_SIZE, | ||
93 | .type = MT_NONSHARED_DEVICE | ||
94 | }, { | ||
95 | .virtual = SPBA0_BASE_ADDR_VIRT, | ||
96 | .pfn = __phys_to_pfn(SPBA0_BASE_ADDR), | ||
97 | .length = SPBA0_SIZE, | ||
98 | .type = MT_NONSHARED_DEVICE | ||
99 | }, { | ||
100 | .virtual = AIPS2_BASE_ADDR_VIRT, | ||
101 | .pfn = __phys_to_pfn(AIPS2_BASE_ADDR), | ||
102 | .length = AIPS2_SIZE, | ||
103 | .type = MT_NONSHARED_DEVICE | ||
104 | }, { | ||
105 | .virtual = CS4_BASE_ADDR_VIRT, | ||
106 | .pfn = __phys_to_pfn(CS4_BASE_ADDR), | ||
107 | .length = CS4_SIZE / 2, | ||
108 | .type = MT_DEVICE | ||
109 | }, | ||
110 | }; | ||
111 | |||
112 | /*! | ||
113 | * Set up static virtual mappings. | ||
114 | */ | ||
115 | void __init mx31ads_map_io(void) | ||
116 | { | ||
117 | mxc_map_io(); | ||
118 | iotable_init(mx31ads_io_desc, ARRAY_SIZE(mx31ads_io_desc)); | ||
119 | } | ||
120 | |||
121 | /*! | ||
122 | * Board specific initialization. | ||
123 | */ | ||
124 | static void __init mxc_board_init(void) | ||
125 | { | ||
126 | mxc_init_extuart(); | ||
127 | } | ||
128 | |||
129 | /* | ||
130 | * The following uses standard kernel macros defined in arch.h in order to | ||
131 | * initialize __mach_desc_MX31ADS data structure. | ||
132 | */ | ||
133 | MACHINE_START(MX31ADS, "Freescale MX31ADS") | ||
134 | /* Maintainer: Freescale Semiconductor, Inc. */ | ||
135 | .phys_io = AIPS1_BASE_ADDR, | ||
136 | .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, | ||
137 | .boot_params = PHYS_OFFSET + 0x100, | ||
138 | .map_io = mx31ads_map_io, | ||
139 | .init_irq = mxc_init_irq, | ||
140 | .init_machine = mxc_board_init, | ||
141 | .timer = &mxc_timer, | ||
142 | MACHINE_END | ||
diff --git a/arch/arm/mach-mx3/time.c b/arch/arm/mach-mx3/time.c new file mode 100644 index 000000000000..e81fb5c5d7c3 --- /dev/null +++ b/arch/arm/mach-mx3/time.c | |||
@@ -0,0 +1,152 @@ | |||
1 | /* | ||
2 | * System Timer Interrupt reconfigured to run in free-run mode. | ||
3 | * Author: Vitaly Wool | ||
4 | * Copyright 2004 MontaVista Software Inc. | ||
5 | * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
6 | */ | ||
7 | |||
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 version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | /*! | ||
15 | * @file time.c | ||
16 | * @brief This file contains OS tick and wdog timer implementations. | ||
17 | * | ||
18 | * This file contains OS tick and wdog timer implementations. | ||
19 | * | ||
20 | * @ingroup Timers | ||
21 | */ | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/irq.h> | ||
27 | #include <asm/hardware.h> | ||
28 | #include <asm/mach/time.h> | ||
29 | #include <asm/io.h> | ||
30 | #include <asm/arch/common.h> | ||
31 | |||
32 | /*! | ||
33 | * This is the timer interrupt service routine to do required tasks. | ||
34 | * It also services the WDOG timer at the frequency of twice per WDOG | ||
35 | * timeout value. For example, if the WDOG's timeout value is 4 (2 | ||
36 | * seconds since the WDOG runs at 0.5Hz), it will be serviced once | ||
37 | * every 2/2=1 second. | ||
38 | * | ||
39 | * @param irq GPT interrupt source number (not used) | ||
40 | * @param dev_id this parameter is not used | ||
41 | * @return always returns \b IRQ_HANDLED as defined in | ||
42 | * include/linux/interrupt.h. | ||
43 | */ | ||
44 | static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) | ||
45 | { | ||
46 | unsigned int next_match; | ||
47 | |||
48 | write_seqlock(&xtime_lock); | ||
49 | |||
50 | if (__raw_readl(MXC_GPT_GPTSR) & GPTSR_OF1) { | ||
51 | do { | ||
52 | timer_tick(); | ||
53 | next_match = __raw_readl(MXC_GPT_GPTOCR1) + LATCH; | ||
54 | __raw_writel(GPTSR_OF1, MXC_GPT_GPTSR); | ||
55 | __raw_writel(next_match, MXC_GPT_GPTOCR1); | ||
56 | } while ((signed long)(next_match - | ||
57 | __raw_readl(MXC_GPT_GPTCNT)) <= 0); | ||
58 | } | ||
59 | |||
60 | write_sequnlock(&xtime_lock); | ||
61 | |||
62 | return IRQ_HANDLED; | ||
63 | } | ||
64 | |||
65 | /*! | ||
66 | * This function is used to obtain the number of microseconds since the last | ||
67 | * timer interrupt. Note that interrupts is disabled by do_gettimeofday(). | ||
68 | * | ||
69 | * @return the number of microseconds since the last timer interrupt. | ||
70 | */ | ||
71 | static unsigned long mxc_gettimeoffset(void) | ||
72 | { | ||
73 | unsigned long ticks_to_match, elapsed, usec, tick_usec, i; | ||
74 | |||
75 | /* Get ticks before next timer match */ | ||
76 | ticks_to_match = | ||
77 | __raw_readl(MXC_GPT_GPTOCR1) - __raw_readl(MXC_GPT_GPTCNT); | ||
78 | |||
79 | /* We need elapsed ticks since last match */ | ||
80 | elapsed = LATCH - ticks_to_match; | ||
81 | |||
82 | /* Now convert them to usec */ | ||
83 | /* Insure no overflow when calculating the usec below */ | ||
84 | for (i = 1, tick_usec = tick_nsec / 1000;; i *= 2) { | ||
85 | tick_usec /= i; | ||
86 | if ((0xFFFFFFFF / tick_usec) > elapsed) | ||
87 | break; | ||
88 | } | ||
89 | usec = (unsigned long)(elapsed * tick_usec) / (LATCH / i); | ||
90 | |||
91 | return usec; | ||
92 | } | ||
93 | |||
94 | /*! | ||
95 | * The OS tick timer interrupt structure. | ||
96 | */ | ||
97 | static struct irqaction timer_irq = { | ||
98 | .name = "MXC Timer Tick", | ||
99 | .flags = IRQF_DISABLED | IRQF_TIMER, | ||
100 | .handler = mxc_timer_interrupt | ||
101 | }; | ||
102 | |||
103 | /*! | ||
104 | * This function is used to initialize the GPT to produce an interrupt | ||
105 | * based on HZ. It is called by start_kernel() during system startup. | ||
106 | */ | ||
107 | void __init mxc_init_time(void) | ||
108 | { | ||
109 | u32 reg, v; | ||
110 | reg = __raw_readl(MXC_GPT_GPTCR); | ||
111 | reg &= ~GPTCR_ENABLE; | ||
112 | __raw_writel(reg, MXC_GPT_GPTCR); | ||
113 | reg |= GPTCR_SWR; | ||
114 | __raw_writel(reg, MXC_GPT_GPTCR); | ||
115 | |||
116 | while ((__raw_readl(MXC_GPT_GPTCR) & GPTCR_SWR) != 0) | ||
117 | cpu_relax(); | ||
118 | |||
119 | reg = GPTCR_FRR | GPTCR_CLKSRC_HIGHFREQ; | ||
120 | __raw_writel(reg, MXC_GPT_GPTCR); | ||
121 | |||
122 | /* TODO: get timer rate from clk driver */ | ||
123 | v = 66500000; | ||
124 | |||
125 | __raw_writel((v / CLOCK_TICK_RATE) - 1, MXC_GPT_GPTPR); | ||
126 | |||
127 | if ((v % CLOCK_TICK_RATE) != 0) { | ||
128 | pr_info("\nWARNING: Can't generate CLOCK_TICK_RATE at %d Hz\n", | ||
129 | CLOCK_TICK_RATE); | ||
130 | } | ||
131 | pr_info("Actual CLOCK_TICK_RATE is %d Hz\n", | ||
132 | v / ((__raw_readl(MXC_GPT_GPTPR) & 0xFFF) + 1)); | ||
133 | |||
134 | reg = __raw_readl(MXC_GPT_GPTCNT); | ||
135 | reg += LATCH; | ||
136 | __raw_writel(reg, MXC_GPT_GPTOCR1); | ||
137 | |||
138 | setup_irq(MXC_INT_GPT, &timer_irq); | ||
139 | |||
140 | reg = __raw_readl(MXC_GPT_GPTCR); | ||
141 | reg = | ||
142 | GPTCR_FRR | GPTCR_CLKSRC_HIGHFREQ | GPTCR_STOPEN | GPTCR_DOZEN | | ||
143 | GPTCR_WAITEN | GPTCR_ENMOD | GPTCR_ENABLE; | ||
144 | __raw_writel(reg, MXC_GPT_GPTCR); | ||
145 | |||
146 | __raw_writel(GPTIR_OF1IE, MXC_GPT_GPTIR); | ||
147 | } | ||
148 | |||
149 | struct sys_timer mxc_timer = { | ||
150 | .init = mxc_init_time, | ||
151 | .offset = mxc_gettimeoffset, | ||
152 | }; | ||
diff --git a/arch/arm/mach-ns9xxx/Makefile b/arch/arm/mach-ns9xxx/Makefile index 53213a69f601..4476411b8140 100644 --- a/arch/arm/mach-ns9xxx/Makefile +++ b/arch/arm/mach-ns9xxx/Makefile | |||
@@ -1,6 +1,7 @@ | |||
1 | obj-y := irq.o time.o generic.o | 1 | obj-y := irq.o time.o generic.o |
2 | 2 | ||
3 | obj-$(CONFIG_MACH_CC9P9360DEV) += mach-cc9p9360dev.o | 3 | obj-$(CONFIG_MACH_CC9P9360DEV) += mach-cc9p9360dev.o |
4 | obj-$(CONFIG_MACH_CC9P9360JS) += mach-cc9p9360js.o | ||
4 | 5 | ||
5 | obj-$(CONFIG_BOARD_A9M9750DEV) += board-a9m9750dev.o | 6 | obj-$(CONFIG_BOARD_A9M9750DEV) += board-a9m9750dev.o |
6 | obj-$(CONFIG_BOARD_JSCC9P9360) += board-jscc9p9360.o | 7 | obj-$(CONFIG_BOARD_JSCC9P9360) += board-jscc9p9360.o |
diff --git a/arch/arm/mach-ns9xxx/board-a9m9750dev.c b/arch/arm/mach-ns9xxx/board-a9m9750dev.c index 25289884a607..925048e7adfe 100644 --- a/arch/arm/mach-ns9xxx/board-a9m9750dev.c +++ b/arch/arm/mach-ns9xxx/board-a9m9750dev.c | |||
@@ -77,7 +77,7 @@ static void a9m9750dev_fpga_demux_handler(unsigned int irq, | |||
77 | 77 | ||
78 | desc = irq_desc + FPGA_IRQ(irqno); | 78 | desc = irq_desc + FPGA_IRQ(irqno); |
79 | 79 | ||
80 | desc_handle_irq(irqno, desc); | 80 | desc_handle_irq(FPGA_IRQ(irqno), desc); |
81 | } | 81 | } |
82 | } | 82 | } |
83 | 83 | ||
@@ -91,7 +91,7 @@ void __init board_a9m9750dev_init_irq(void) | |||
91 | * use GPIO 11, because GPIO 32 is used for the LCD | 91 | * use GPIO 11, because GPIO 32 is used for the LCD |
92 | */ | 92 | */ |
93 | /* XXX: proper GPIO handling */ | 93 | /* XXX: proper GPIO handling */ |
94 | BBU_GC(2) &= ~0x2000; | 94 | BBU_GCONFb1(1) &= ~0x2000; |
95 | 95 | ||
96 | for (i = FPGA_IRQ(0); i <= FPGA_IRQ(7); ++i) { | 96 | for (i = FPGA_IRQ(0); i <= FPGA_IRQ(7); ++i) { |
97 | set_irq_chip(i, &a9m9750dev_fpga_chip); | 97 | set_irq_chip(i, &a9m9750dev_fpga_chip); |
@@ -178,7 +178,7 @@ void __init board_a9m9750dev_init_machine(void) | |||
178 | 178 | ||
179 | /* setup static CS0: memory configuration */ | 179 | /* setup static CS0: memory configuration */ |
180 | reg = MEM_SMC(0); | 180 | reg = MEM_SMC(0); |
181 | REGSET(reg, MEM_SMC, WSMC, OFF); | 181 | REGSET(reg, MEM_SMC, PSMC, OFF); |
182 | REGSET(reg, MEM_SMC, BSMC, OFF); | 182 | REGSET(reg, MEM_SMC, BSMC, OFF); |
183 | REGSET(reg, MEM_SMC, EW, OFF); | 183 | REGSET(reg, MEM_SMC, EW, OFF); |
184 | REGSET(reg, MEM_SMC, PB, 1); | 184 | REGSET(reg, MEM_SMC, PB, 1); |
@@ -196,4 +196,3 @@ void __init board_a9m9750dev_init_machine(void) | |||
196 | platform_add_devices(board_a9m9750dev_devices, | 196 | platform_add_devices(board_a9m9750dev_devices, |
197 | ARRAY_SIZE(board_a9m9750dev_devices)); | 197 | ARRAY_SIZE(board_a9m9750dev_devices)); |
198 | } | 198 | } |
199 | |||
diff --git a/arch/arm/mach-ns9xxx/generic.c b/arch/arm/mach-ns9xxx/generic.c index 83e2b6532b22..d742c921e34d 100644 --- a/arch/arm/mach-ns9xxx/generic.c +++ b/arch/arm/mach-ns9xxx/generic.c | |||
@@ -18,6 +18,8 @@ | |||
18 | #include <asm/arch-ns9xxx/regs-mem.h> | 18 | #include <asm/arch-ns9xxx/regs-mem.h> |
19 | #include <asm/arch-ns9xxx/board.h> | 19 | #include <asm/arch-ns9xxx/board.h> |
20 | 20 | ||
21 | #include "generic.h" | ||
22 | |||
21 | static struct map_desc standard_io_desc[] __initdata = { | 23 | static struct map_desc standard_io_desc[] __initdata = { |
22 | { /* BBus */ | 24 | { /* BBus */ |
23 | .virtual = io_p2v(0x90000000), | 25 | .virtual = io_p2v(0x90000000), |
diff --git a/arch/arm/mach-ns9xxx/irq.c b/arch/arm/mach-ns9xxx/irq.c index 83d92724a971..b8c7b00522e6 100644 --- a/arch/arm/mach-ns9xxx/irq.c +++ b/arch/arm/mach-ns9xxx/irq.c | |||
@@ -21,6 +21,15 @@ static void ns9xxx_ack_irq_timer(unsigned int irq) | |||
21 | { | 21 | { |
22 | u32 tc = SYS_TC(irq - IRQ_TIMER0); | 22 | u32 tc = SYS_TC(irq - IRQ_TIMER0); |
23 | 23 | ||
24 | /* | ||
25 | * If the timer is programmed to halt on terminal count, the | ||
26 | * timer must be disabled before clearing the interrupt. | ||
27 | */ | ||
28 | if (REGGET(tc, SYS_TCx, REN) == 0) { | ||
29 | REGSET(tc, SYS_TCx, TEN, DIS); | ||
30 | SYS_TC(irq - IRQ_TIMER0) = tc; | ||
31 | } | ||
32 | |||
24 | REGSET(tc, SYS_TCx, INTC, SET); | 33 | REGSET(tc, SYS_TCx, INTC, SET); |
25 | SYS_TC(irq - IRQ_TIMER0) = tc; | 34 | SYS_TC(irq - IRQ_TIMER0) = tc; |
26 | 35 | ||
@@ -28,7 +37,7 @@ static void ns9xxx_ack_irq_timer(unsigned int irq) | |||
28 | SYS_TC(irq - IRQ_TIMER0) = tc; | 37 | SYS_TC(irq - IRQ_TIMER0) = tc; |
29 | } | 38 | } |
30 | 39 | ||
31 | void (*ns9xxx_ack_irq_functions[NR_IRQS])(unsigned int) = { | 40 | static void (*ns9xxx_ack_irq_functions[NR_IRQS])(unsigned int) = { |
32 | [IRQ_TIMER0] = ns9xxx_ack_irq_timer, | 41 | [IRQ_TIMER0] = ns9xxx_ack_irq_timer, |
33 | [IRQ_TIMER1] = ns9xxx_ack_irq_timer, | 42 | [IRQ_TIMER1] = ns9xxx_ack_irq_timer, |
34 | [IRQ_TIMER2] = ns9xxx_ack_irq_timer, | 43 | [IRQ_TIMER2] = ns9xxx_ack_irq_timer, |
diff --git a/arch/arm/mach-ns9xxx/mach-cc9p9360js.c b/arch/arm/mach-ns9xxx/mach-cc9p9360js.c index d09d5fa5620a..85c8b41105c9 100644 --- a/arch/arm/mach-ns9xxx/mach-cc9p9360js.c +++ b/arch/arm/mach-ns9xxx/mach-cc9p9360js.c | |||
@@ -20,7 +20,7 @@ static void __init mach_cc9p9360js_init_machine(void) | |||
20 | board_jscc9p9360_init_machine(); | 20 | board_jscc9p9360_init_machine(); |
21 | } | 21 | } |
22 | 22 | ||
23 | MACHINE_START(CC9P9360DEV, "Digi ConnectCore 9P 9360 on an JSCC9P9360 Devboard") | 23 | MACHINE_START(CC9P9360JS, "Digi ConnectCore 9P 9360 on an JSCC9P9360 Devboard") |
24 | .map_io = ns9xxx_map_io, | 24 | .map_io = ns9xxx_map_io, |
25 | .init_irq = ns9xxx_init_irq, | 25 | .init_irq = ns9xxx_init_irq, |
26 | .init_machine = mach_cc9p9360js_init_machine, | 26 | .init_machine = mach_cc9p9360js_init_machine, |
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 5c0a10041cd1..5ebec6d88b51 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig | |||
@@ -37,6 +37,10 @@ config MACH_TRIZEPS4 | |||
37 | bool "Keith und Koep Trizeps4 DIMM-Module" | 37 | bool "Keith und Koep Trizeps4 DIMM-Module" |
38 | select PXA27x | 38 | select PXA27x |
39 | 39 | ||
40 | config MACH_EM_X270 | ||
41 | bool "CompuLab EM-x270 platform" | ||
42 | select PXA27x | ||
43 | |||
40 | endchoice | 44 | endchoice |
41 | 45 | ||
42 | if PXA_SHARPSL | 46 | if PXA_SHARPSL |
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index 9093eb1c94eb..7d6ab5c59ab9 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile | |||
@@ -18,6 +18,7 @@ obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o sp | |||
18 | obj-$(CONFIG_MACH_AKITA) += akita-ioexp.o | 18 | obj-$(CONFIG_MACH_AKITA) += akita-ioexp.o |
19 | obj-$(CONFIG_MACH_POODLE) += poodle.o corgi_ssp.o | 19 | obj-$(CONFIG_MACH_POODLE) += poodle.o corgi_ssp.o |
20 | obj-$(CONFIG_MACH_TOSA) += tosa.o | 20 | obj-$(CONFIG_MACH_TOSA) += tosa.o |
21 | obj-$(CONFIG_MACH_EM_X270) += em-x270.o | ||
21 | 22 | ||
22 | # Support for blinky lights | 23 | # Support for blinky lights |
23 | led-y := leds.o | 24 | led-y := leds.o |
diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h index 9a6faff8e5a7..636fdb1c049c 100644 --- a/arch/arm/mach-pxa/devices.h +++ b/arch/arm/mach-pxa/devices.h | |||
@@ -1,11 +1,11 @@ | |||
1 | extern struct platform_device pxamci_device; | 1 | extern struct platform_device pxa_device_mci; |
2 | extern struct platform_device pxaudc_device; | 2 | extern struct platform_device pxa_device_udc; |
3 | extern struct platform_device pxafb_device; | 3 | extern struct platform_device pxa_device_fb; |
4 | extern struct platform_device ffuart_device; | 4 | extern struct platform_device pxa_device_ffuart; |
5 | extern struct platform_device btuart_device; | 5 | extern struct platform_device pxa_device_btuart; |
6 | extern struct platform_device stuart_device; | 6 | extern struct platform_device pxa_device_stuart; |
7 | extern struct platform_device hwuart_device; | 7 | extern struct platform_device pxa_device_hwuart; |
8 | extern struct platform_device pxai2c_device; | 8 | extern struct platform_device pxa_device_i2c; |
9 | extern struct platform_device pxai2s_device; | 9 | extern struct platform_device pxa_device_i2s; |
10 | extern struct platform_device pxaficp_device; | 10 | extern struct platform_device pxa_device_ficp; |
11 | extern struct platform_device pxartc_device; | 11 | extern struct platform_device pxa_device_rtc; |
diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c new file mode 100644 index 000000000000..3d0ad5065ee5 --- /dev/null +++ b/arch/arm/mach-pxa/em-x270.c | |||
@@ -0,0 +1,354 @@ | |||
1 | /* | ||
2 | * Support for CompuLab EM-x270 platform | ||
3 | * | ||
4 | * Copyright (C) 2007 CompuLab, Ltd. | ||
5 | * Author: Mike Rapoport <mike@compulab.co.il> | ||
6 | * | ||
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 | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/irq.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | |||
15 | #include <linux/dm9000.h> | ||
16 | #include <linux/rtc-v3020.h> | ||
17 | |||
18 | #include <linux/mtd/nand.h> | ||
19 | #include <linux/mtd/partitions.h> | ||
20 | |||
21 | #include <asm/mach-types.h> | ||
22 | |||
23 | #include <asm/mach/arch.h> | ||
24 | |||
25 | #include <asm/arch/pxa-regs.h> | ||
26 | #include <asm/arch/pxafb.h> | ||
27 | #include <asm/arch/ohci.h> | ||
28 | #include <asm/arch/mmc.h> | ||
29 | #include <asm/arch/bitfield.h> | ||
30 | |||
31 | #include "generic.h" | ||
32 | |||
33 | /* GPIO IRQ usage */ | ||
34 | #define EM_X270_MMC_PD (105) | ||
35 | #define EM_X270_ETHIRQ IRQ_GPIO(41) | ||
36 | #define EM_X270_MMC_IRQ IRQ_GPIO(13) | ||
37 | |||
38 | static struct resource em_x270_dm9k_resource[] = { | ||
39 | [0] = { | ||
40 | .start = PXA_CS2_PHYS, | ||
41 | .end = PXA_CS2_PHYS + 3, | ||
42 | .flags = IORESOURCE_MEM, | ||
43 | }, | ||
44 | [1] = { | ||
45 | .start = PXA_CS2_PHYS + 8, | ||
46 | .end = PXA_CS2_PHYS + 8 + 0x3f, | ||
47 | .flags = IORESOURCE_MEM, | ||
48 | }, | ||
49 | [2] = { | ||
50 | .start = EM_X270_ETHIRQ, | ||
51 | .end = EM_X270_ETHIRQ, | ||
52 | .flags = IORESOURCE_IRQ, | ||
53 | } | ||
54 | }; | ||
55 | |||
56 | /* for the moment we limit ourselves to 32bit IO until some | ||
57 | * better IO routines can be written and tested | ||
58 | */ | ||
59 | static struct dm9000_plat_data em_x270_dm9k_platdata = { | ||
60 | .flags = DM9000_PLATF_32BITONLY, | ||
61 | }; | ||
62 | |||
63 | /* Ethernet device */ | ||
64 | static struct platform_device em_x270_dm9k = { | ||
65 | .name = "dm9000", | ||
66 | .id = 0, | ||
67 | .num_resources = ARRAY_SIZE(em_x270_dm9k_resource), | ||
68 | .resource = em_x270_dm9k_resource, | ||
69 | .dev = { | ||
70 | .platform_data = &em_x270_dm9k_platdata, | ||
71 | } | ||
72 | }; | ||
73 | |||
74 | /* audio device */ | ||
75 | static struct platform_device em_x270_audio = { | ||
76 | .name = "pxa2xx-ac97", | ||
77 | .id = -1, | ||
78 | }; | ||
79 | |||
80 | /* WM9712 touchscreen controller. Hopefully the driver will make it to | ||
81 | * the mainstream sometime */ | ||
82 | static struct platform_device em_x270_ts = { | ||
83 | .name = "wm97xx-ts", | ||
84 | .id = -1, | ||
85 | }; | ||
86 | |||
87 | /* RTC */ | ||
88 | static struct resource em_x270_v3020_resource[] = { | ||
89 | [0] = { | ||
90 | .start = PXA_CS4_PHYS, | ||
91 | .end = PXA_CS4_PHYS + 3, | ||
92 | .flags = IORESOURCE_MEM, | ||
93 | }, | ||
94 | }; | ||
95 | |||
96 | static struct v3020_platform_data em_x270_v3020_platdata = { | ||
97 | .leftshift = 0, | ||
98 | }; | ||
99 | |||
100 | static struct platform_device em_x270_rtc = { | ||
101 | .name = "v3020", | ||
102 | .num_resources = ARRAY_SIZE(em_x270_v3020_resource), | ||
103 | .resource = em_x270_v3020_resource, | ||
104 | .id = -1, | ||
105 | .dev = { | ||
106 | .platform_data = &em_x270_v3020_platdata, | ||
107 | } | ||
108 | }; | ||
109 | |||
110 | /* NAND flash */ | ||
111 | #define GPIO_NAND_CS (11) | ||
112 | #define GPIO_NAND_RB (56) | ||
113 | |||
114 | static inline void nand_cs_on(void) | ||
115 | { | ||
116 | GPCR(GPIO_NAND_CS) = GPIO_bit(GPIO_NAND_CS); | ||
117 | } | ||
118 | |||
119 | static void nand_cs_off(void) | ||
120 | { | ||
121 | dsb(); | ||
122 | |||
123 | GPSR(GPIO_NAND_CS) = GPIO_bit(GPIO_NAND_CS); | ||
124 | } | ||
125 | |||
126 | /* hardware specific access to control-lines */ | ||
127 | static void em_x270_nand_cmd_ctl(struct mtd_info *mtd, int dat, | ||
128 | unsigned int ctrl) | ||
129 | { | ||
130 | struct nand_chip *this = mtd->priv; | ||
131 | unsigned long nandaddr = (unsigned long)this->IO_ADDR_W; | ||
132 | |||
133 | dsb(); | ||
134 | |||
135 | if (ctrl & NAND_CTRL_CHANGE) { | ||
136 | if (ctrl & NAND_ALE) | ||
137 | nandaddr |= (1 << 3); | ||
138 | else | ||
139 | nandaddr &= ~(1 << 3); | ||
140 | if (ctrl & NAND_CLE) | ||
141 | nandaddr |= (1 << 2); | ||
142 | else | ||
143 | nandaddr &= ~(1 << 2); | ||
144 | if (ctrl & NAND_NCE) | ||
145 | nand_cs_on(); | ||
146 | else | ||
147 | nand_cs_off(); | ||
148 | } | ||
149 | |||
150 | dsb(); | ||
151 | this->IO_ADDR_W = (void __iomem *)nandaddr; | ||
152 | if (dat != NAND_CMD_NONE) | ||
153 | writel(dat, this->IO_ADDR_W); | ||
154 | |||
155 | dsb(); | ||
156 | } | ||
157 | |||
158 | /* read device ready pin */ | ||
159 | static int em_x270_nand_device_ready(struct mtd_info *mtd) | ||
160 | { | ||
161 | dsb(); | ||
162 | |||
163 | return GPLR(GPIO_NAND_RB) & GPIO_bit(GPIO_NAND_RB); | ||
164 | } | ||
165 | |||
166 | static struct mtd_partition em_x270_partition_info[] = { | ||
167 | [0] = { | ||
168 | .name = "em_x270-0", | ||
169 | .offset = 0, | ||
170 | .size = SZ_4M, | ||
171 | }, | ||
172 | [1] = { | ||
173 | .name = "em_x270-1", | ||
174 | .offset = MTDPART_OFS_APPEND, | ||
175 | .size = MTDPART_SIZ_FULL | ||
176 | }, | ||
177 | }; | ||
178 | |||
179 | static const char *em_x270_part_probes[] = { "cmdlinepart", NULL }; | ||
180 | |||
181 | struct platform_nand_data em_x270_nand_platdata = { | ||
182 | .chip = { | ||
183 | .nr_chips = 1, | ||
184 | .chip_offset = 0, | ||
185 | .nr_partitions = ARRAY_SIZE(em_x270_partition_info), | ||
186 | .partitions = em_x270_partition_info, | ||
187 | .chip_delay = 20, | ||
188 | .part_probe_types = em_x270_part_probes, | ||
189 | }, | ||
190 | .ctrl = { | ||
191 | .hwcontrol = 0, | ||
192 | .dev_ready = em_x270_nand_device_ready, | ||
193 | .select_chip = 0, | ||
194 | .cmd_ctrl = em_x270_nand_cmd_ctl, | ||
195 | }, | ||
196 | }; | ||
197 | |||
198 | static struct resource em_x270_nand_resource[] = { | ||
199 | [0] = { | ||
200 | .start = PXA_CS1_PHYS, | ||
201 | .end = PXA_CS1_PHYS + 12, | ||
202 | .flags = IORESOURCE_MEM, | ||
203 | }, | ||
204 | }; | ||
205 | |||
206 | static struct platform_device em_x270_nand = { | ||
207 | .name = "gen_nand", | ||
208 | .num_resources = ARRAY_SIZE(em_x270_nand_resource), | ||
209 | .resource = em_x270_nand_resource, | ||
210 | .id = -1, | ||
211 | .dev = { | ||
212 | .platform_data = &em_x270_nand_platdata, | ||
213 | } | ||
214 | }; | ||
215 | |||
216 | /* platform devices */ | ||
217 | static struct platform_device *platform_devices[] __initdata = { | ||
218 | &em_x270_dm9k, | ||
219 | &em_x270_audio, | ||
220 | &em_x270_ts, | ||
221 | &em_x270_rtc, | ||
222 | &em_x270_nand, | ||
223 | }; | ||
224 | |||
225 | |||
226 | /* PXA27x OHCI controller setup */ | ||
227 | static int em_x270_ohci_init(struct device *dev) | ||
228 | { | ||
229 | /* Set the Power Control Polarity Low */ | ||
230 | UHCHR = (UHCHR | UHCHR_PCPL) & | ||
231 | ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE); | ||
232 | |||
233 | /* enable port 2 transiever */ | ||
234 | UP2OCR = UP2OCR_HXS | UP2OCR_HXOE; | ||
235 | |||
236 | return 0; | ||
237 | } | ||
238 | |||
239 | static struct pxaohci_platform_data em_x270_ohci_platform_data = { | ||
240 | .port_mode = PMM_PERPORT_MODE, | ||
241 | .init = em_x270_ohci_init, | ||
242 | }; | ||
243 | |||
244 | |||
245 | static int em_x270_mci_init(struct device *dev, | ||
246 | irq_handler_t em_x270_detect_int, | ||
247 | void *data) | ||
248 | { | ||
249 | int err; | ||
250 | |||
251 | /* setup GPIO for PXA27x MMC controller */ | ||
252 | pxa_gpio_mode(GPIO32_MMCCLK_MD); | ||
253 | pxa_gpio_mode(GPIO112_MMCCMD_MD); | ||
254 | pxa_gpio_mode(GPIO92_MMCDAT0_MD); | ||
255 | pxa_gpio_mode(GPIO109_MMCDAT1_MD); | ||
256 | pxa_gpio_mode(GPIO110_MMCDAT2_MD); | ||
257 | pxa_gpio_mode(GPIO111_MMCDAT3_MD); | ||
258 | |||
259 | /* EM-X270 uses GPIO13 as SD power enable */ | ||
260 | pxa_gpio_mode(EM_X270_MMC_PD | GPIO_OUT); | ||
261 | |||
262 | err = request_irq(EM_X270_MMC_IRQ, em_x270_detect_int, | ||
263 | IRQF_DISABLED | IRQF_TRIGGER_FALLING, | ||
264 | "MMC card detect", data); | ||
265 | if (err) { | ||
266 | printk(KERN_ERR "%s: can't request MMC card detect IRQ: %d\n", | ||
267 | __FUNCTION__, err); | ||
268 | return err; | ||
269 | } | ||
270 | |||
271 | return 0; | ||
272 | } | ||
273 | |||
274 | static void em_x270_mci_setpower(struct device *dev, unsigned int vdd) | ||
275 | { | ||
276 | /* | ||
277 | FIXME: current hardware implementation does not allow to | ||
278 | enable/disable MMC power. This will be fixed in next HW releases, | ||
279 | and we'll need to add implmentation here. | ||
280 | */ | ||
281 | return; | ||
282 | } | ||
283 | |||
284 | static void em_x270_mci_exit(struct device *dev, void *data) | ||
285 | { | ||
286 | free_irq(EM_X270_MMC_IRQ, data); | ||
287 | } | ||
288 | |||
289 | static struct pxamci_platform_data em_x270_mci_platform_data = { | ||
290 | .ocr_mask = MMC_VDD_28_29|MMC_VDD_29_30|MMC_VDD_30_31, | ||
291 | .init = em_x270_mci_init, | ||
292 | .setpower = em_x270_mci_setpower, | ||
293 | .exit = em_x270_mci_exit, | ||
294 | }; | ||
295 | |||
296 | /* LCD 480x640 */ | ||
297 | static struct pxafb_mode_info em_x270_lcd_mode = { | ||
298 | .pixclock = 50000, | ||
299 | .bpp = 16, | ||
300 | .xres = 480, | ||
301 | .yres = 640, | ||
302 | .hsync_len = 8, | ||
303 | .vsync_len = 2, | ||
304 | .left_margin = 8, | ||
305 | .upper_margin = 0, | ||
306 | .right_margin = 24, | ||
307 | .lower_margin = 4, | ||
308 | .cmap_greyscale = 0, | ||
309 | }; | ||
310 | |||
311 | static struct pxafb_mach_info em_x270_lcd = { | ||
312 | .modes = &em_x270_lcd_mode, | ||
313 | .num_modes = 1, | ||
314 | .cmap_inverse = 0, | ||
315 | .cmap_static = 0, | ||
316 | .lccr0 = LCCR0_PAS, | ||
317 | .lccr3 = LCCR3_PixClkDiv(0x01) | LCCR3_Acb(0xff), | ||
318 | }; | ||
319 | |||
320 | static void __init em_x270_init(void) | ||
321 | { | ||
322 | /* setup LCD */ | ||
323 | set_pxa_fb_info(&em_x270_lcd); | ||
324 | |||
325 | /* register EM-X270 platform devices */ | ||
326 | platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); | ||
327 | |||
328 | /* set MCI and OHCI platform parameters */ | ||
329 | pxa_set_mci_info(&em_x270_mci_platform_data); | ||
330 | pxa_set_ohci_info(&em_x270_ohci_platform_data); | ||
331 | |||
332 | /* setup STUART GPIOs */ | ||
333 | pxa_gpio_mode(GPIO46_STRXD_MD); | ||
334 | pxa_gpio_mode(GPIO47_STTXD_MD); | ||
335 | |||
336 | /* setup BTUART GPIOs */ | ||
337 | pxa_gpio_mode(GPIO42_BTRXD_MD); | ||
338 | pxa_gpio_mode(GPIO43_BTTXD_MD); | ||
339 | pxa_gpio_mode(GPIO44_BTCTS_MD); | ||
340 | pxa_gpio_mode(GPIO45_BTRTS_MD); | ||
341 | |||
342 | /* Setup interrupt for dm9000 */ | ||
343 | set_irq_type(EM_X270_ETHIRQ, IRQT_RISING); | ||
344 | } | ||
345 | |||
346 | MACHINE_START(EM_X270, "Compulab EM-x270") | ||
347 | .boot_params = 0xa0000100, | ||
348 | .phys_io = 0x40000000, | ||
349 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, | ||
350 | .map_io = pxa_map_io, | ||
351 | .init_irq = pxa27x_init_irq, | ||
352 | .timer = &pxa_timer, | ||
353 | .init_machine = em_x270_init, | ||
354 | MACHINE_END | ||
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c index 296539b6359c..5510f6fdce55 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c | |||
@@ -243,7 +243,7 @@ static struct resource pxamci_resources[] = { | |||
243 | 243 | ||
244 | static u64 pxamci_dmamask = 0xffffffffUL; | 244 | static u64 pxamci_dmamask = 0xffffffffUL; |
245 | 245 | ||
246 | struct platform_device pxamci_device = { | 246 | struct platform_device pxa_device_mci = { |
247 | .name = "pxa2xx-mci", | 247 | .name = "pxa2xx-mci", |
248 | .id = -1, | 248 | .id = -1, |
249 | .dev = { | 249 | .dev = { |
@@ -256,7 +256,7 @@ struct platform_device pxamci_device = { | |||
256 | 256 | ||
257 | void __init pxa_set_mci_info(struct pxamci_platform_data *info) | 257 | void __init pxa_set_mci_info(struct pxamci_platform_data *info) |
258 | { | 258 | { |
259 | pxamci_device.dev.platform_data = info; | 259 | pxa_device_mci.dev.platform_data = info; |
260 | } | 260 | } |
261 | 261 | ||
262 | 262 | ||
@@ -282,7 +282,7 @@ static struct resource pxa2xx_udc_resources[] = { | |||
282 | 282 | ||
283 | static u64 udc_dma_mask = ~(u32)0; | 283 | static u64 udc_dma_mask = ~(u32)0; |
284 | 284 | ||
285 | struct platform_device pxaudc_device = { | 285 | struct platform_device pxa_device_udc = { |
286 | .name = "pxa2xx-udc", | 286 | .name = "pxa2xx-udc", |
287 | .id = -1, | 287 | .id = -1, |
288 | .resource = pxa2xx_udc_resources, | 288 | .resource = pxa2xx_udc_resources, |
@@ -308,7 +308,7 @@ static struct resource pxafb_resources[] = { | |||
308 | 308 | ||
309 | static u64 fb_dma_mask = ~(u64)0; | 309 | static u64 fb_dma_mask = ~(u64)0; |
310 | 310 | ||
311 | struct platform_device pxafb_device = { | 311 | struct platform_device pxa_device_fb = { |
312 | .name = "pxa2xx-fb", | 312 | .name = "pxa2xx-fb", |
313 | .id = -1, | 313 | .id = -1, |
314 | .dev = { | 314 | .dev = { |
@@ -321,27 +321,27 @@ struct platform_device pxafb_device = { | |||
321 | 321 | ||
322 | void __init set_pxa_fb_info(struct pxafb_mach_info *info) | 322 | void __init set_pxa_fb_info(struct pxafb_mach_info *info) |
323 | { | 323 | { |
324 | pxafb_device.dev.platform_data = info; | 324 | pxa_device_fb.dev.platform_data = info; |
325 | } | 325 | } |
326 | 326 | ||
327 | void __init set_pxa_fb_parent(struct device *parent_dev) | 327 | void __init set_pxa_fb_parent(struct device *parent_dev) |
328 | { | 328 | { |
329 | pxafb_device.dev.parent = parent_dev; | 329 | pxa_device_fb.dev.parent = parent_dev; |
330 | } | 330 | } |
331 | 331 | ||
332 | struct platform_device ffuart_device = { | 332 | struct platform_device pxa_device_ffuart= { |
333 | .name = "pxa2xx-uart", | 333 | .name = "pxa2xx-uart", |
334 | .id = 0, | 334 | .id = 0, |
335 | }; | 335 | }; |
336 | struct platform_device btuart_device = { | 336 | struct platform_device pxa_device_btuart = { |
337 | .name = "pxa2xx-uart", | 337 | .name = "pxa2xx-uart", |
338 | .id = 1, | 338 | .id = 1, |
339 | }; | 339 | }; |
340 | struct platform_device stuart_device = { | 340 | struct platform_device pxa_device_stuart = { |
341 | .name = "pxa2xx-uart", | 341 | .name = "pxa2xx-uart", |
342 | .id = 2, | 342 | .id = 2, |
343 | }; | 343 | }; |
344 | struct platform_device hwuart_device = { | 344 | struct platform_device pxa_device_hwuart = { |
345 | .name = "pxa2xx-uart", | 345 | .name = "pxa2xx-uart", |
346 | .id = 3, | 346 | .id = 3, |
347 | }; | 347 | }; |
@@ -358,7 +358,7 @@ static struct resource pxai2c_resources[] = { | |||
358 | }, | 358 | }, |
359 | }; | 359 | }; |
360 | 360 | ||
361 | struct platform_device pxai2c_device = { | 361 | struct platform_device pxa_device_i2c = { |
362 | .name = "pxa2xx-i2c", | 362 | .name = "pxa2xx-i2c", |
363 | .id = 0, | 363 | .id = 0, |
364 | .resource = pxai2c_resources, | 364 | .resource = pxai2c_resources, |
@@ -367,7 +367,7 @@ struct platform_device pxai2c_device = { | |||
367 | 367 | ||
368 | void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info) | 368 | void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info) |
369 | { | 369 | { |
370 | pxai2c_device.dev.platform_data = info; | 370 | pxa_device_i2c.dev.platform_data = info; |
371 | } | 371 | } |
372 | 372 | ||
373 | static struct resource pxai2s_resources[] = { | 373 | static struct resource pxai2s_resources[] = { |
@@ -382,7 +382,7 @@ static struct resource pxai2s_resources[] = { | |||
382 | }, | 382 | }, |
383 | }; | 383 | }; |
384 | 384 | ||
385 | struct platform_device pxai2s_device = { | 385 | struct platform_device pxa_device_i2s = { |
386 | .name = "pxa2xx-i2s", | 386 | .name = "pxa2xx-i2s", |
387 | .id = -1, | 387 | .id = -1, |
388 | .resource = pxai2s_resources, | 388 | .resource = pxai2s_resources, |
@@ -391,7 +391,7 @@ struct platform_device pxai2s_device = { | |||
391 | 391 | ||
392 | static u64 pxaficp_dmamask = ~(u32)0; | 392 | static u64 pxaficp_dmamask = ~(u32)0; |
393 | 393 | ||
394 | struct platform_device pxaficp_device = { | 394 | struct platform_device pxa_device_ficp = { |
395 | .name = "pxa2xx-ir", | 395 | .name = "pxa2xx-ir", |
396 | .id = -1, | 396 | .id = -1, |
397 | .dev = { | 397 | .dev = { |
@@ -402,10 +402,10 @@ struct platform_device pxaficp_device = { | |||
402 | 402 | ||
403 | void __init pxa_set_ficp_info(struct pxaficp_platform_data *info) | 403 | void __init pxa_set_ficp_info(struct pxaficp_platform_data *info) |
404 | { | 404 | { |
405 | pxaficp_device.dev.platform_data = info; | 405 | pxa_device_ficp.dev.platform_data = info; |
406 | } | 406 | } |
407 | 407 | ||
408 | struct platform_device pxartc_device = { | 408 | struct platform_device pxa_device_rtc = { |
409 | .name = "sa1100-rtc", | 409 | .name = "sa1100-rtc", |
410 | .id = -1, | 410 | .id = -1, |
411 | }; | 411 | }; |
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c index e66dbc26add1..b59a81a8e7d3 100644 --- a/arch/arm/mach-pxa/pm.c +++ b/arch/arm/mach-pxa/pm.c | |||
@@ -24,61 +24,13 @@ | |||
24 | #include <asm/arch/lubbock.h> | 24 | #include <asm/arch/lubbock.h> |
25 | #include <asm/mach/time.h> | 25 | #include <asm/mach/time.h> |
26 | 26 | ||
27 | 27 | struct pxa_cpu_pm_fns *pxa_cpu_pm_fns; | |
28 | /* | 28 | static unsigned long *sleep_save; |
29 | * Debug macros | ||
30 | */ | ||
31 | #undef DEBUG | ||
32 | |||
33 | #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x | ||
34 | #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] | ||
35 | |||
36 | #define RESTORE_GPLEVEL(n) do { \ | ||
37 | GPSR##n = sleep_save[SLEEP_SAVE_GPLR##n]; \ | ||
38 | GPCR##n = ~sleep_save[SLEEP_SAVE_GPLR##n]; \ | ||
39 | } while (0) | ||
40 | |||
41 | /* | ||
42 | * List of global PXA peripheral registers to preserve. | ||
43 | * More ones like CP and general purpose register values are preserved | ||
44 | * with the stack pointer in sleep.S. | ||
45 | */ | ||
46 | enum { SLEEP_SAVE_START = 0, | ||
47 | |||
48 | SLEEP_SAVE_GPLR0, SLEEP_SAVE_GPLR1, SLEEP_SAVE_GPLR2, SLEEP_SAVE_GPLR3, | ||
49 | SLEEP_SAVE_GPDR0, SLEEP_SAVE_GPDR1, SLEEP_SAVE_GPDR2, SLEEP_SAVE_GPDR3, | ||
50 | SLEEP_SAVE_GRER0, SLEEP_SAVE_GRER1, SLEEP_SAVE_GRER2, SLEEP_SAVE_GRER3, | ||
51 | SLEEP_SAVE_GFER0, SLEEP_SAVE_GFER1, SLEEP_SAVE_GFER2, SLEEP_SAVE_GFER3, | ||
52 | SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3, | ||
53 | |||
54 | SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, | ||
55 | SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR1_U, | ||
56 | SLEEP_SAVE_GAFR2_L, SLEEP_SAVE_GAFR2_U, | ||
57 | SLEEP_SAVE_GAFR3_L, SLEEP_SAVE_GAFR3_U, | ||
58 | |||
59 | SLEEP_SAVE_PSTR, | ||
60 | |||
61 | SLEEP_SAVE_ICMR, | ||
62 | SLEEP_SAVE_CKEN, | ||
63 | |||
64 | #ifdef CONFIG_PXA27x | ||
65 | SLEEP_SAVE_MDREFR, | ||
66 | SLEEP_SAVE_PWER, SLEEP_SAVE_PCFR, SLEEP_SAVE_PRER, | ||
67 | SLEEP_SAVE_PFER, SLEEP_SAVE_PKWR, | ||
68 | #endif | ||
69 | |||
70 | SLEEP_SAVE_CKSUM, | ||
71 | |||
72 | SLEEP_SAVE_SIZE | ||
73 | }; | ||
74 | |||
75 | 29 | ||
76 | int pxa_pm_enter(suspend_state_t state) | 30 | int pxa_pm_enter(suspend_state_t state) |
77 | { | 31 | { |
78 | unsigned long sleep_save[SLEEP_SAVE_SIZE]; | 32 | unsigned long sleep_save_checksum = 0, checksum = 0; |
79 | unsigned long checksum = 0; | ||
80 | int i; | 33 | int i; |
81 | extern void pxa_cpu_pm_enter(suspend_state_t state); | ||
82 | 34 | ||
83 | #ifdef CONFIG_IWMMXT | 35 | #ifdef CONFIG_IWMMXT |
84 | /* force any iWMMXt context to ram **/ | 36 | /* force any iWMMXt context to ram **/ |
@@ -86,100 +38,35 @@ int pxa_pm_enter(suspend_state_t state) | |||
86 | iwmmxt_task_disable(NULL); | 38 | iwmmxt_task_disable(NULL); |
87 | #endif | 39 | #endif |
88 | 40 | ||
89 | SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2); | 41 | pxa_cpu_pm_fns->save(sleep_save); |
90 | SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2); | ||
91 | SAVE(GRER0); SAVE(GRER1); SAVE(GRER2); | ||
92 | SAVE(GFER0); SAVE(GFER1); SAVE(GFER2); | ||
93 | SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); | ||
94 | |||
95 | SAVE(GAFR0_L); SAVE(GAFR0_U); | ||
96 | SAVE(GAFR1_L); SAVE(GAFR1_U); | ||
97 | SAVE(GAFR2_L); SAVE(GAFR2_U); | ||
98 | |||
99 | #ifdef CONFIG_PXA27x | ||
100 | SAVE(MDREFR); | ||
101 | SAVE(GPLR3); SAVE(GPDR3); SAVE(GRER3); SAVE(GFER3); SAVE(PGSR3); | ||
102 | SAVE(GAFR3_L); SAVE(GAFR3_U); | ||
103 | SAVE(PWER); SAVE(PCFR); SAVE(PRER); | ||
104 | SAVE(PFER); SAVE(PKWR); | ||
105 | #endif | ||
106 | |||
107 | SAVE(ICMR); | ||
108 | ICMR = 0; | ||
109 | |||
110 | SAVE(CKEN); | ||
111 | SAVE(PSTR); | ||
112 | |||
113 | /* Note: wake up source are set up in each machine specific files */ | ||
114 | |||
115 | /* clear GPIO transition detect bits */ | ||
116 | GEDR0 = GEDR0; GEDR1 = GEDR1; GEDR2 = GEDR2; | ||
117 | #ifdef CONFIG_PXA27x | ||
118 | GEDR3 = GEDR3; | ||
119 | #endif | ||
120 | 42 | ||
121 | /* Clear sleep reset status */ | 43 | /* Clear sleep reset status */ |
122 | RCSR = RCSR_SMR; | 44 | RCSR = RCSR_SMR; |
123 | 45 | ||
124 | /* before sleeping, calculate and save a checksum */ | 46 | /* before sleeping, calculate and save a checksum */ |
125 | for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++) | 47 | for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++) |
126 | checksum += sleep_save[i]; | 48 | sleep_save_checksum += sleep_save[i]; |
127 | sleep_save[SLEEP_SAVE_CKSUM] = checksum; | ||
128 | 49 | ||
129 | /* *** go zzz *** */ | 50 | /* *** go zzz *** */ |
130 | pxa_cpu_pm_enter(state); | 51 | pxa_cpu_pm_fns->enter(state); |
131 | |||
132 | cpu_init(); | 52 | cpu_init(); |
133 | 53 | ||
134 | /* after sleeping, validate the checksum */ | 54 | /* after sleeping, validate the checksum */ |
135 | checksum = 0; | 55 | for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++) |
136 | for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++) | ||
137 | checksum += sleep_save[i]; | 56 | checksum += sleep_save[i]; |
138 | 57 | ||
139 | /* if invalid, display message and wait for a hardware reset */ | 58 | /* if invalid, display message and wait for a hardware reset */ |
140 | if (checksum != sleep_save[SLEEP_SAVE_CKSUM]) { | 59 | if (checksum != sleep_save_checksum) { |
141 | #ifdef CONFIG_ARCH_LUBBOCK | 60 | #ifdef CONFIG_ARCH_LUBBOCK |
142 | LUB_HEXLED = 0xbadbadc5; | 61 | LUB_HEXLED = 0xbadbadc5; |
143 | #endif | 62 | #endif |
144 | while (1) | 63 | while (1) |
145 | pxa_cpu_pm_enter(state); | 64 | pxa_cpu_pm_fns->enter(state); |
146 | } | 65 | } |
147 | 66 | ||
148 | /* ensure not to come back here if it wasn't intended */ | 67 | pxa_cpu_pm_fns->restore(sleep_save); |
149 | PSPR = 0; | ||
150 | |||
151 | /* restore registers */ | ||
152 | RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); RESTORE_GPLEVEL(2); | ||
153 | RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2); | ||
154 | RESTORE(GAFR0_L); RESTORE(GAFR0_U); | ||
155 | RESTORE(GAFR1_L); RESTORE(GAFR1_U); | ||
156 | RESTORE(GAFR2_L); RESTORE(GAFR2_U); | ||
157 | RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2); | ||
158 | RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2); | ||
159 | RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); | ||
160 | |||
161 | #ifdef CONFIG_PXA27x | ||
162 | RESTORE(MDREFR); | ||
163 | RESTORE_GPLEVEL(3); RESTORE(GPDR3); | ||
164 | RESTORE(GAFR3_L); RESTORE(GAFR3_U); | ||
165 | RESTORE(GRER3); RESTORE(GFER3); RESTORE(PGSR3); | ||
166 | RESTORE(PWER); RESTORE(PCFR); RESTORE(PRER); | ||
167 | RESTORE(PFER); RESTORE(PKWR); | ||
168 | #endif | ||
169 | |||
170 | PSSR = PSSR_RDH | PSSR_PH; | ||
171 | |||
172 | RESTORE(CKEN); | ||
173 | |||
174 | ICLR = 0; | ||
175 | ICCR = 1; | ||
176 | RESTORE(ICMR); | ||
177 | 68 | ||
178 | RESTORE(PSTR); | 69 | pr_debug("*** made it back from resume\n"); |
179 | |||
180 | #ifdef DEBUG | ||
181 | printk(KERN_DEBUG "*** made it back from resume\n"); | ||
182 | #endif | ||
183 | 70 | ||
184 | return 0; | 71 | return 0; |
185 | } | 72 | } |
@@ -190,3 +77,35 @@ unsigned long sleep_phys_sp(void *sp) | |||
190 | { | 77 | { |
191 | return virt_to_phys(sp); | 78 | return virt_to_phys(sp); |
192 | } | 79 | } |
80 | |||
81 | static int pxa_pm_valid(suspend_state_t state) | ||
82 | { | ||
83 | if (pxa_cpu_pm_fns) | ||
84 | return pxa_cpu_pm_fns->valid(state); | ||
85 | |||
86 | return -EINVAL; | ||
87 | } | ||
88 | |||
89 | static struct pm_ops pxa_pm_ops = { | ||
90 | .valid = pxa_pm_valid, | ||
91 | .enter = pxa_pm_enter, | ||
92 | }; | ||
93 | |||
94 | static int __init pxa_pm_init(void) | ||
95 | { | ||
96 | if (!pxa_cpu_pm_fns) { | ||
97 | printk(KERN_ERR "no valid pxa_cpu_pm_fns defined\n"); | ||
98 | return -EINVAL; | ||
99 | } | ||
100 | |||
101 | sleep_save = kmalloc(pxa_cpu_pm_fns->save_size, GFP_KERNEL); | ||
102 | if (!sleep_save) { | ||
103 | printk(KERN_ERR "failed to alloc memory for pm save\n"); | ||
104 | return -ENOMEM; | ||
105 | } | ||
106 | |||
107 | pm_set_ops(&pxa_pm_ops); | ||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | device_initcall(pxa_pm_init); | ||
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index f36ca448338e..6dfcca72e90f 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c | |||
@@ -110,26 +110,99 @@ EXPORT_SYMBOL(get_lcdclk_frequency_10khz); | |||
110 | 110 | ||
111 | #ifdef CONFIG_PM | 111 | #ifdef CONFIG_PM |
112 | 112 | ||
113 | void pxa_cpu_pm_enter(suspend_state_t state) | 113 | #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x |
114 | #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] | ||
115 | |||
116 | #define RESTORE_GPLEVEL(n) do { \ | ||
117 | GPSR##n = sleep_save[SLEEP_SAVE_GPLR##n]; \ | ||
118 | GPCR##n = ~sleep_save[SLEEP_SAVE_GPLR##n]; \ | ||
119 | } while (0) | ||
120 | |||
121 | /* | ||
122 | * List of global PXA peripheral registers to preserve. | ||
123 | * More ones like CP and general purpose register values are preserved | ||
124 | * with the stack pointer in sleep.S. | ||
125 | */ | ||
126 | enum { SLEEP_SAVE_START = 0, | ||
127 | |||
128 | SLEEP_SAVE_GPLR0, SLEEP_SAVE_GPLR1, SLEEP_SAVE_GPLR2, | ||
129 | SLEEP_SAVE_GPDR0, SLEEP_SAVE_GPDR1, SLEEP_SAVE_GPDR2, | ||
130 | SLEEP_SAVE_GRER0, SLEEP_SAVE_GRER1, SLEEP_SAVE_GRER2, | ||
131 | SLEEP_SAVE_GFER0, SLEEP_SAVE_GFER1, SLEEP_SAVE_GFER2, | ||
132 | SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, | ||
133 | |||
134 | SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, | ||
135 | SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR1_U, | ||
136 | SLEEP_SAVE_GAFR2_L, SLEEP_SAVE_GAFR2_U, | ||
137 | |||
138 | SLEEP_SAVE_PSTR, | ||
139 | |||
140 | SLEEP_SAVE_ICMR, | ||
141 | SLEEP_SAVE_CKEN, | ||
142 | |||
143 | SLEEP_SAVE_SIZE | ||
144 | }; | ||
145 | |||
146 | |||
147 | static void pxa25x_cpu_pm_save(unsigned long *sleep_save) | ||
148 | { | ||
149 | SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2); | ||
150 | SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2); | ||
151 | SAVE(GRER0); SAVE(GRER1); SAVE(GRER2); | ||
152 | SAVE(GFER0); SAVE(GFER1); SAVE(GFER2); | ||
153 | SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); | ||
154 | |||
155 | SAVE(GAFR0_L); SAVE(GAFR0_U); | ||
156 | SAVE(GAFR1_L); SAVE(GAFR1_U); | ||
157 | SAVE(GAFR2_L); SAVE(GAFR2_U); | ||
158 | |||
159 | SAVE(ICMR); | ||
160 | SAVE(CKEN); | ||
161 | SAVE(PSTR); | ||
162 | } | ||
163 | |||
164 | static void pxa25x_cpu_pm_restore(unsigned long *sleep_save) | ||
114 | { | 165 | { |
115 | extern void pxa_cpu_suspend(unsigned int); | 166 | /* restore registers */ |
116 | extern void pxa_cpu_resume(void); | 167 | RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); RESTORE_GPLEVEL(2); |
168 | RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2); | ||
169 | RESTORE(GAFR0_L); RESTORE(GAFR0_U); | ||
170 | RESTORE(GAFR1_L); RESTORE(GAFR1_U); | ||
171 | RESTORE(GAFR2_L); RESTORE(GAFR2_U); | ||
172 | RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2); | ||
173 | RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2); | ||
174 | RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); | ||
175 | |||
176 | RESTORE(CKEN); | ||
177 | RESTORE(ICMR); | ||
178 | RESTORE(PSTR); | ||
179 | } | ||
117 | 180 | ||
181 | static void pxa25x_cpu_pm_enter(suspend_state_t state) | ||
182 | { | ||
118 | CKEN = 0; | 183 | CKEN = 0; |
119 | 184 | ||
120 | switch (state) { | 185 | switch (state) { |
121 | case PM_SUSPEND_MEM: | 186 | case PM_SUSPEND_MEM: |
122 | /* set resume return address */ | 187 | /* set resume return address */ |
123 | PSPR = virt_to_phys(pxa_cpu_resume); | 188 | PSPR = virt_to_phys(pxa_cpu_resume); |
124 | pxa_cpu_suspend(PWRMODE_SLEEP); | 189 | pxa25x_cpu_suspend(PWRMODE_SLEEP); |
125 | break; | 190 | break; |
126 | } | 191 | } |
127 | } | 192 | } |
128 | 193 | ||
129 | static struct pm_ops pxa25x_pm_ops = { | 194 | static struct pxa_cpu_pm_fns pxa25x_cpu_pm_fns = { |
130 | .enter = pxa_pm_enter, | 195 | .save_size = SLEEP_SAVE_SIZE, |
131 | .valid = pm_valid_only_mem, | 196 | .valid = pm_valid_only_mem, |
197 | .save = pxa25x_cpu_pm_save, | ||
198 | .restore = pxa25x_cpu_pm_restore, | ||
199 | .enter = pxa25x_cpu_pm_enter, | ||
132 | }; | 200 | }; |
201 | |||
202 | static void __init pxa25x_init_pm(void) | ||
203 | { | ||
204 | pxa_cpu_pm_fns = &pxa25x_cpu_pm_fns; | ||
205 | } | ||
133 | #endif | 206 | #endif |
134 | 207 | ||
135 | void __init pxa25x_init_irq(void) | 208 | void __init pxa25x_init_irq(void) |
@@ -139,16 +212,16 @@ void __init pxa25x_init_irq(void) | |||
139 | } | 212 | } |
140 | 213 | ||
141 | static struct platform_device *pxa25x_devices[] __initdata = { | 214 | static struct platform_device *pxa25x_devices[] __initdata = { |
142 | &pxamci_device, | 215 | &pxa_device_mci, |
143 | &pxaudc_device, | 216 | &pxa_device_udc, |
144 | &pxafb_device, | 217 | &pxa_device_fb, |
145 | &ffuart_device, | 218 | &pxa_device_ffuart, |
146 | &btuart_device, | 219 | &pxa_device_btuart, |
147 | &stuart_device, | 220 | &pxa_device_stuart, |
148 | &pxai2c_device, | 221 | &pxa_device_i2c, |
149 | &pxai2s_device, | 222 | &pxa_device_i2s, |
150 | &pxaficp_device, | 223 | &pxa_device_ficp, |
151 | &pxartc_device, | 224 | &pxa_device_rtc, |
152 | }; | 225 | }; |
153 | 226 | ||
154 | static int __init pxa25x_init(void) | 227 | static int __init pxa25x_init(void) |
@@ -159,14 +232,14 @@ static int __init pxa25x_init(void) | |||
159 | if ((ret = pxa_init_dma(16))) | 232 | if ((ret = pxa_init_dma(16))) |
160 | return ret; | 233 | return ret; |
161 | #ifdef CONFIG_PM | 234 | #ifdef CONFIG_PM |
162 | pm_set_ops(&pxa25x_pm_ops); | 235 | pxa25x_init_pm(); |
163 | #endif | 236 | #endif |
164 | ret = platform_add_devices(pxa25x_devices, | 237 | ret = platform_add_devices(pxa25x_devices, |
165 | ARRAY_SIZE(pxa25x_devices)); | 238 | ARRAY_SIZE(pxa25x_devices)); |
166 | } | 239 | } |
167 | /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */ | 240 | /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */ |
168 | if (cpu_is_pxa25x()) | 241 | if (cpu_is_pxa25x()) |
169 | ret = platform_device_register(&hwuart_device); | 242 | ret = platform_device_register(&pxa_device_hwuart); |
170 | 243 | ||
171 | return ret; | 244 | return ret; |
172 | } | 245 | } |
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index aa5bb02c897b..203371ab19db 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c | |||
@@ -126,14 +126,107 @@ EXPORT_SYMBOL(get_lcdclk_frequency_10khz); | |||
126 | 126 | ||
127 | #ifdef CONFIG_PM | 127 | #ifdef CONFIG_PM |
128 | 128 | ||
129 | void pxa_cpu_pm_enter(suspend_state_t state) | 129 | #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x |
130 | #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] | ||
131 | |||
132 | #define RESTORE_GPLEVEL(n) do { \ | ||
133 | GPSR##n = sleep_save[SLEEP_SAVE_GPLR##n]; \ | ||
134 | GPCR##n = ~sleep_save[SLEEP_SAVE_GPLR##n]; \ | ||
135 | } while (0) | ||
136 | |||
137 | /* | ||
138 | * List of global PXA peripheral registers to preserve. | ||
139 | * More ones like CP and general purpose register values are preserved | ||
140 | * with the stack pointer in sleep.S. | ||
141 | */ | ||
142 | enum { SLEEP_SAVE_START = 0, | ||
143 | |||
144 | SLEEP_SAVE_GPLR0, SLEEP_SAVE_GPLR1, SLEEP_SAVE_GPLR2, SLEEP_SAVE_GPLR3, | ||
145 | SLEEP_SAVE_GPDR0, SLEEP_SAVE_GPDR1, SLEEP_SAVE_GPDR2, SLEEP_SAVE_GPDR3, | ||
146 | SLEEP_SAVE_GRER0, SLEEP_SAVE_GRER1, SLEEP_SAVE_GRER2, SLEEP_SAVE_GRER3, | ||
147 | SLEEP_SAVE_GFER0, SLEEP_SAVE_GFER1, SLEEP_SAVE_GFER2, SLEEP_SAVE_GFER3, | ||
148 | SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3, | ||
149 | |||
150 | SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, | ||
151 | SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR1_U, | ||
152 | SLEEP_SAVE_GAFR2_L, SLEEP_SAVE_GAFR2_U, | ||
153 | SLEEP_SAVE_GAFR3_L, SLEEP_SAVE_GAFR3_U, | ||
154 | |||
155 | SLEEP_SAVE_PSTR, | ||
156 | |||
157 | SLEEP_SAVE_ICMR, | ||
158 | SLEEP_SAVE_CKEN, | ||
159 | |||
160 | SLEEP_SAVE_MDREFR, | ||
161 | SLEEP_SAVE_PWER, SLEEP_SAVE_PCFR, SLEEP_SAVE_PRER, | ||
162 | SLEEP_SAVE_PFER, SLEEP_SAVE_PKWR, | ||
163 | |||
164 | SLEEP_SAVE_SIZE | ||
165 | }; | ||
166 | |||
167 | void pxa27x_cpu_pm_save(unsigned long *sleep_save) | ||
168 | { | ||
169 | SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2); SAVE(GPLR3); | ||
170 | SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2); SAVE(GPDR3); | ||
171 | SAVE(GRER0); SAVE(GRER1); SAVE(GRER2); SAVE(GRER3); | ||
172 | SAVE(GFER0); SAVE(GFER1); SAVE(GFER2); SAVE(GFER3); | ||
173 | SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); SAVE(PGSR3); | ||
174 | |||
175 | SAVE(GAFR0_L); SAVE(GAFR0_U); | ||
176 | SAVE(GAFR1_L); SAVE(GAFR1_U); | ||
177 | SAVE(GAFR2_L); SAVE(GAFR2_U); | ||
178 | SAVE(GAFR3_L); SAVE(GAFR3_U); | ||
179 | |||
180 | SAVE(MDREFR); | ||
181 | SAVE(PWER); SAVE(PCFR); SAVE(PRER); | ||
182 | SAVE(PFER); SAVE(PKWR); | ||
183 | |||
184 | SAVE(ICMR); ICMR = 0; | ||
185 | SAVE(CKEN); | ||
186 | SAVE(PSTR); | ||
187 | |||
188 | /* Clear GPIO transition detect bits */ | ||
189 | GEDR0 = GEDR0; GEDR1 = GEDR1; GEDR2 = GEDR2; GEDR3 = GEDR3; | ||
190 | } | ||
191 | |||
192 | void pxa27x_cpu_pm_restore(unsigned long *sleep_save) | ||
193 | { | ||
194 | /* ensure not to come back here if it wasn't intended */ | ||
195 | PSPR = 0; | ||
196 | |||
197 | /* restore registers */ | ||
198 | RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); | ||
199 | RESTORE_GPLEVEL(2); RESTORE_GPLEVEL(3); | ||
200 | RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2); RESTORE(GPDR3); | ||
201 | RESTORE(GAFR0_L); RESTORE(GAFR0_U); | ||
202 | RESTORE(GAFR1_L); RESTORE(GAFR1_U); | ||
203 | RESTORE(GAFR2_L); RESTORE(GAFR2_U); | ||
204 | RESTORE(GAFR3_L); RESTORE(GAFR3_U); | ||
205 | RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2); RESTORE(GRER3); | ||
206 | RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2); RESTORE(GFER3); | ||
207 | RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); RESTORE(PGSR3); | ||
208 | |||
209 | RESTORE(MDREFR); | ||
210 | RESTORE(PWER); RESTORE(PCFR); RESTORE(PRER); | ||
211 | RESTORE(PFER); RESTORE(PKWR); | ||
212 | |||
213 | PSSR = PSSR_RDH | PSSR_PH; | ||
214 | |||
215 | RESTORE(CKEN); | ||
216 | |||
217 | ICLR = 0; | ||
218 | ICCR = 1; | ||
219 | RESTORE(ICMR); | ||
220 | RESTORE(PSTR); | ||
221 | } | ||
222 | |||
223 | void pxa27x_cpu_pm_enter(suspend_state_t state) | ||
130 | { | 224 | { |
131 | extern void pxa_cpu_standby(void); | 225 | extern void pxa_cpu_standby(void); |
132 | extern void pxa_cpu_suspend(unsigned int); | ||
133 | extern void pxa_cpu_resume(void); | ||
134 | 226 | ||
135 | if (state == PM_SUSPEND_STANDBY) | 227 | if (state == PM_SUSPEND_STANDBY) |
136 | CKEN = (1 << CKEN_MEMC) | (1 << CKEN_OSTIMER) | (1 << CKEN_LCD) | (1 << CKEN_PWM0); | 228 | CKEN = (1 << CKEN_MEMC) | (1 << CKEN_OSTIMER) | |
229 | (1 << CKEN_LCD) | (1 << CKEN_PWM0); | ||
137 | else | 230 | else |
138 | CKEN = (1 << CKEN_MEMC) | (1 << CKEN_OSTIMER); | 231 | CKEN = (1 << CKEN_MEMC) | (1 << CKEN_OSTIMER); |
139 | 232 | ||
@@ -150,20 +243,28 @@ void pxa_cpu_pm_enter(suspend_state_t state) | |||
150 | case PM_SUSPEND_MEM: | 243 | case PM_SUSPEND_MEM: |
151 | /* set resume return address */ | 244 | /* set resume return address */ |
152 | PSPR = virt_to_phys(pxa_cpu_resume); | 245 | PSPR = virt_to_phys(pxa_cpu_resume); |
153 | pxa_cpu_suspend(PWRMODE_SLEEP); | 246 | pxa27x_cpu_suspend(PWRMODE_SLEEP); |
154 | break; | 247 | break; |
155 | } | 248 | } |
156 | } | 249 | } |
157 | 250 | ||
158 | static int pxa27x_pm_valid(suspend_state_t state) | 251 | static int pxa27x_cpu_pm_valid(suspend_state_t state) |
159 | { | 252 | { |
160 | return state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY; | 253 | return state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY; |
161 | } | 254 | } |
162 | 255 | ||
163 | static struct pm_ops pxa27x_pm_ops = { | 256 | static struct pxa_cpu_pm_fns pxa27x_cpu_pm_fns = { |
164 | .enter = pxa_pm_enter, | 257 | .save_size = SLEEP_SAVE_SIZE, |
165 | .valid = pxa27x_pm_valid, | 258 | .save = pxa27x_cpu_pm_save, |
259 | .restore = pxa27x_cpu_pm_restore, | ||
260 | .valid = pxa27x_cpu_pm_valid, | ||
261 | .enter = pxa27x_cpu_pm_enter, | ||
166 | }; | 262 | }; |
263 | |||
264 | static void __init pxa27x_init_pm(void) | ||
265 | { | ||
266 | pxa_cpu_pm_fns = &pxa27x_cpu_pm_fns; | ||
267 | } | ||
167 | #endif | 268 | #endif |
168 | 269 | ||
169 | /* | 270 | /* |
@@ -185,7 +286,7 @@ static struct resource pxa27x_ohci_resources[] = { | |||
185 | }, | 286 | }, |
186 | }; | 287 | }; |
187 | 288 | ||
188 | static struct platform_device pxaohci_device = { | 289 | static struct platform_device pxa27x_device_ohci = { |
189 | .name = "pxa27x-ohci", | 290 | .name = "pxa27x-ohci", |
190 | .id = -1, | 291 | .id = -1, |
191 | .dev = { | 292 | .dev = { |
@@ -198,7 +299,7 @@ static struct platform_device pxaohci_device = { | |||
198 | 299 | ||
199 | void __init pxa_set_ohci_info(struct pxaohci_platform_data *info) | 300 | void __init pxa_set_ohci_info(struct pxaohci_platform_data *info) |
200 | { | 301 | { |
201 | pxaohci_device.dev.platform_data = info; | 302 | pxa27x_device_ohci.dev.platform_data = info; |
202 | } | 303 | } |
203 | 304 | ||
204 | static struct resource i2c_power_resources[] = { | 305 | static struct resource i2c_power_resources[] = { |
@@ -213,7 +314,7 @@ static struct resource i2c_power_resources[] = { | |||
213 | }, | 314 | }, |
214 | }; | 315 | }; |
215 | 316 | ||
216 | static struct platform_device pxai2c_power_device = { | 317 | static struct platform_device pxa27x_device_i2c_power = { |
217 | .name = "pxa2xx-i2c", | 318 | .name = "pxa2xx-i2c", |
218 | .id = 1, | 319 | .id = 1, |
219 | .resource = i2c_power_resources, | 320 | .resource = i2c_power_resources, |
@@ -221,18 +322,18 @@ static struct platform_device pxai2c_power_device = { | |||
221 | }; | 322 | }; |
222 | 323 | ||
223 | static struct platform_device *devices[] __initdata = { | 324 | static struct platform_device *devices[] __initdata = { |
224 | &pxamci_device, | 325 | &pxa_device_mci, |
225 | &pxaudc_device, | 326 | &pxa_device_udc, |
226 | &pxafb_device, | 327 | &pxa_device_fb, |
227 | &ffuart_device, | 328 | &pxa_device_ffuart, |
228 | &btuart_device, | 329 | &pxa_device_btuart, |
229 | &stuart_device, | 330 | &pxa_device_stuart, |
230 | &pxai2c_device, | 331 | &pxa_device_i2c, |
231 | &pxai2c_power_device, | 332 | &pxa_device_i2s, |
232 | &pxai2s_device, | 333 | &pxa_device_ficp, |
233 | &pxaficp_device, | 334 | &pxa_device_rtc, |
234 | &pxartc_device, | 335 | &pxa27x_device_i2c_power, |
235 | &pxaohci_device, | 336 | &pxa27x_device_ohci, |
236 | }; | 337 | }; |
237 | 338 | ||
238 | void __init pxa27x_init_irq(void) | 339 | void __init pxa27x_init_irq(void) |
@@ -249,7 +350,7 @@ static int __init pxa27x_init(void) | |||
249 | if ((ret = pxa_init_dma(32))) | 350 | if ((ret = pxa_init_dma(32))) |
250 | return ret; | 351 | return ret; |
251 | #ifdef CONFIG_PM | 352 | #ifdef CONFIG_PM |
252 | pm_set_ops(&pxa27x_pm_ops); | 353 | pxa27x_init_pm(); |
253 | #endif | 354 | #endif |
254 | ret = platform_add_devices(devices, ARRAY_SIZE(devices)); | 355 | ret = platform_add_devices(devices, ARRAY_SIZE(devices)); |
255 | } | 356 | } |
diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S index 15874b360e51..aff71fec618a 100644 --- a/arch/arm/mach-pxa/sleep.S +++ b/arch/arm/mach-pxa/sleep.S | |||
@@ -17,28 +17,12 @@ | |||
17 | 17 | ||
18 | #include <asm/arch/pxa-regs.h> | 18 | #include <asm/arch/pxa-regs.h> |
19 | 19 | ||
20 | #ifdef CONFIG_PXA27x // workaround for Errata 50 | ||
21 | #define MDREFR_KDIV 0x200a4000 // all banks | 20 | #define MDREFR_KDIV 0x200a4000 // all banks |
22 | #define CCCR_SLEEP 0x00000107 // L=7 2N=2 A=0 PPDIS=0 CPDIS=0 | 21 | #define CCCR_SLEEP 0x00000107 // L=7 2N=2 A=0 PPDIS=0 CPDIS=0 |
23 | #endif | ||
24 | 22 | ||
25 | .text | 23 | .text |
26 | 24 | ||
27 | /* | 25 | pxa_cpu_save_cp: |
28 | * pxa_cpu_suspend() | ||
29 | * | ||
30 | * Forces CPU into sleep state. | ||
31 | * | ||
32 | * r0 = value for PWRMODE M field for desired sleep state | ||
33 | */ | ||
34 | |||
35 | ENTRY(pxa_cpu_suspend) | ||
36 | |||
37 | #ifndef CONFIG_IWMMXT | ||
38 | mra r2, r3, acc0 | ||
39 | #endif | ||
40 | stmfd sp!, {r2 - r12, lr} @ save registers on stack | ||
41 | |||
42 | @ get coprocessor registers | 26 | @ get coprocessor registers |
43 | mrc p14, 0, r3, c6, c0, 0 @ clock configuration, for turbo mode | 27 | mrc p14, 0, r3, c6, c0, 0 @ clock configuration, for turbo mode |
44 | mrc p15, 0, r4, c15, c1, 0 @ CP access reg | 28 | mrc p15, 0, r4, c15, c1, 0 @ CP access reg |
@@ -54,12 +38,36 @@ ENTRY(pxa_cpu_suspend) | |||
54 | mov r10, sp | 38 | mov r10, sp |
55 | stmfd sp!, {r3 - r10} | 39 | stmfd sp!, {r3 - r10} |
56 | 40 | ||
57 | mov r5, r0 @ save sleep mode | 41 | mov pc, lr |
42 | |||
43 | pxa_cpu_save_sp: | ||
58 | @ preserve phys address of stack | 44 | @ preserve phys address of stack |
59 | mov r0, sp | 45 | mov r0, sp |
46 | mov r2, lr | ||
60 | bl sleep_phys_sp | 47 | bl sleep_phys_sp |
61 | ldr r1, =sleep_save_sp | 48 | ldr r1, =sleep_save_sp |
62 | str r0, [r1] | 49 | str r0, [r1] |
50 | mov pc, r2 | ||
51 | |||
52 | /* | ||
53 | * pxa27x_cpu_suspend() | ||
54 | * | ||
55 | * Forces CPU into sleep state. | ||
56 | * | ||
57 | * r0 = value for PWRMODE M field for desired sleep state | ||
58 | */ | ||
59 | |||
60 | ENTRY(pxa27x_cpu_suspend) | ||
61 | |||
62 | #ifndef CONFIG_IWMMXT | ||
63 | mra r2, r3, acc0 | ||
64 | #endif | ||
65 | stmfd sp!, {r2 - r12, lr} @ save registers on stack | ||
66 | |||
67 | bl pxa_cpu_save_cp | ||
68 | |||
69 | mov r5, r0 @ save sleep mode | ||
70 | bl pxa_cpu_save_sp | ||
63 | 71 | ||
64 | @ clean data cache | 72 | @ clean data cache |
65 | bl xscale_flush_kern_cache_all | 73 | bl xscale_flush_kern_cache_all |
@@ -80,13 +88,55 @@ ENTRY(pxa_cpu_suspend) | |||
80 | @ enable SDRAM self-refresh mode | 88 | @ enable SDRAM self-refresh mode |
81 | orr r5, r5, #MDREFR_SLFRSH | 89 | orr r5, r5, #MDREFR_SLFRSH |
82 | 90 | ||
83 | #ifdef CONFIG_PXA27x | ||
84 | @ set SDCLKx divide-by-2 bits (this is part of a workaround for Errata 50) | 91 | @ set SDCLKx divide-by-2 bits (this is part of a workaround for Errata 50) |
85 | ldr r6, =MDREFR_KDIV | 92 | ldr r6, =MDREFR_KDIV |
86 | orr r5, r5, r6 | 93 | orr r5, r5, r6 |
87 | #endif | ||
88 | 94 | ||
89 | #ifdef CONFIG_PXA25x | 95 | @ Intel PXA270 Specification Update notes problems sleeping |
96 | @ with core operating above 91 MHz | ||
97 | @ (see Errata 50, ...processor does not exit from sleep...) | ||
98 | |||
99 | ldr r6, =CCCR | ||
100 | ldr r8, [r6] @ keep original value for resume | ||
101 | |||
102 | ldr r7, =CCCR_SLEEP @ prepare CCCR sleep value | ||
103 | mov r0, #0x2 @ prepare value for CLKCFG | ||
104 | |||
105 | @ align execution to a cache line | ||
106 | b pxa_cpu_do_suspend | ||
107 | |||
108 | /* | ||
109 | * pxa27x_cpu_suspend() | ||
110 | * | ||
111 | * Forces CPU into sleep state. | ||
112 | * | ||
113 | * r0 = value for PWRMODE M field for desired sleep state | ||
114 | */ | ||
115 | |||
116 | ENTRY(pxa25x_cpu_suspend) | ||
117 | stmfd sp!, {r2 - r12, lr} @ save registers on stack | ||
118 | |||
119 | bl pxa_cpu_save_cp | ||
120 | |||
121 | mov r5, r0 @ save sleep mode | ||
122 | bl pxa_cpu_save_sp | ||
123 | |||
124 | @ clean data cache | ||
125 | bl xscale_flush_kern_cache_all | ||
126 | |||
127 | @ prepare value for sleep mode | ||
128 | mov r1, r5 @ sleep mode | ||
129 | |||
130 | @ prepare pointer to physical address 0 (virtual mapping in generic.c) | ||
131 | mov r2, #UNCACHED_PHYS_0 | ||
132 | |||
133 | @ prepare SDRAM refresh settings | ||
134 | ldr r4, =MDREFR | ||
135 | ldr r5, [r4] | ||
136 | |||
137 | @ enable SDRAM self-refresh mode | ||
138 | orr r5, r5, #MDREFR_SLFRSH | ||
139 | |||
90 | @ Intel PXA255 Specification Update notes problems | 140 | @ Intel PXA255 Specification Update notes problems |
91 | @ about suspending with PXBus operating above 133MHz | 141 | @ about suspending with PXBus operating above 133MHz |
92 | @ (see Errata 31, GPIO output signals, ... unpredictable in sleep | 142 | @ (see Errata 31, GPIO output signals, ... unpredictable in sleep |
@@ -118,30 +168,15 @@ ENTRY(pxa_cpu_suspend) | |||
118 | mov r0, #0 | 168 | mov r0, #0 |
119 | mcr p14, 0, r0, c6, c0, 0 | 169 | mcr p14, 0, r0, c6, c0, 0 |
120 | orr r0, r0, #2 @ initiate change bit | 170 | orr r0, r0, #2 @ initiate change bit |
121 | #endif | 171 | b pxa_cpu_do_suspend |
122 | #ifdef CONFIG_PXA27x | ||
123 | @ Intel PXA270 Specification Update notes problems sleeping | ||
124 | @ with core operating above 91 MHz | ||
125 | @ (see Errata 50, ...processor does not exit from sleep...) | ||
126 | |||
127 | ldr r6, =CCCR | ||
128 | ldr r8, [r6] @ keep original value for resume | ||
129 | |||
130 | ldr r7, =CCCR_SLEEP @ prepare CCCR sleep value | ||
131 | mov r0, #0x2 @ prepare value for CLKCFG | ||
132 | #endif | ||
133 | |||
134 | @ align execution to a cache line | ||
135 | b 1f | ||
136 | 172 | ||
137 | .ltorg | 173 | .ltorg |
138 | .align 5 | 174 | .align 5 |
139 | 1: | 175 | pxa_cpu_do_suspend: |
140 | 176 | ||
141 | @ All needed values are now in registers. | 177 | @ All needed values are now in registers. |
142 | @ These last instructions should be in cache | 178 | @ These last instructions should be in cache |
143 | 179 | ||
144 | #if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x) | ||
145 | @ initiate the frequency change... | 180 | @ initiate the frequency change... |
146 | str r7, [r6] | 181 | str r7, [r6] |
147 | mcr p14, 0, r0, c6, c0, 0 | 182 | mcr p14, 0, r0, c6, c0, 0 |
@@ -155,7 +190,6 @@ ENTRY(pxa_cpu_suspend) | |||
155 | mov r0, #42 | 190 | mov r0, #42 |
156 | 10: subs r0, r0, #1 | 191 | 10: subs r0, r0, #1 |
157 | bne 10b | 192 | bne 10b |
158 | #endif | ||
159 | 193 | ||
160 | @ Do not reorder... | 194 | @ Do not reorder... |
161 | @ Intel PXA270 Specification Update notes problems performing | 195 | @ Intel PXA270 Specification Update notes problems performing |
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c index 6f91fd2d061a..98d27e646b09 100644 --- a/arch/arm/mach-pxa/time.c +++ b/arch/arm/mach-pxa/time.c | |||
@@ -1,9 +1,11 @@ | |||
1 | /* | 1 | /* |
2 | * arch/arm/mach-pxa/time.c | 2 | * arch/arm/mach-pxa/time.c |
3 | * | 3 | * |
4 | * Author: Nicolas Pitre | 4 | * PXA clocksource, clockevents, and OST interrupt handlers. |
5 | * Created: Jun 15, 2001 | 5 | * Copyright (c) 2007 by Bill Gatliff <bgat@billgatliff.com>. |
6 | * Copyright: MontaVista Software Inc. | 6 | * |
7 | * Derived from Nicolas Pitre's PXA timer handler Copyright (c) 2001 | ||
8 | * by MontaVista Software, Inc. (Nico, your code rocks!) | ||
7 | * | 9 | * |
8 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 11 | * it under the terms of the GNU General Public License version 2 as |
@@ -12,164 +14,160 @@ | |||
12 | 14 | ||
13 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
14 | #include <linux/init.h> | 16 | #include <linux/init.h> |
15 | #include <linux/delay.h> | ||
16 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
17 | #include <linux/time.h> | 18 | #include <linux/clockchips.h> |
18 | #include <linux/signal.h> | 19 | |
19 | #include <linux/errno.h> | ||
20 | #include <linux/sched.h> | ||
21 | #include <linux/clocksource.h> | ||
22 | |||
23 | #include <asm/system.h> | ||
24 | #include <asm/hardware.h> | ||
25 | #include <asm/io.h> | ||
26 | #include <asm/leds.h> | ||
27 | #include <asm/irq.h> | ||
28 | #include <asm/mach/irq.h> | 20 | #include <asm/mach/irq.h> |
29 | #include <asm/mach/time.h> | 21 | #include <asm/mach/time.h> |
30 | #include <asm/arch/pxa-regs.h> | 22 | #include <asm/arch/pxa-regs.h> |
31 | 23 | ||
32 | |||
33 | static int pxa_set_rtc(void) | ||
34 | { | ||
35 | unsigned long current_time = xtime.tv_sec; | ||
36 | |||
37 | if (RTSR & RTSR_ALE) { | ||
38 | /* make sure not to forward the clock over an alarm */ | ||
39 | unsigned long alarm = RTAR; | ||
40 | if (current_time >= alarm && alarm >= RCNR) | ||
41 | return -ERESTARTSYS; | ||
42 | } | ||
43 | RCNR = current_time; | ||
44 | return 0; | ||
45 | } | ||
46 | |||
47 | #ifdef CONFIG_NO_IDLE_HZ | ||
48 | static unsigned long initial_match; | ||
49 | static int match_posponed; | ||
50 | #endif | ||
51 | |||
52 | static irqreturn_t | 24 | static irqreturn_t |
53 | pxa_timer_interrupt(int irq, void *dev_id) | 25 | pxa_ost0_interrupt(int irq, void *dev_id) |
54 | { | 26 | { |
55 | int next_match; | 27 | int next_match; |
56 | 28 | struct clock_event_device *c = dev_id; | |
57 | write_seqlock(&xtime_lock); | 29 | |
58 | 30 | if (c->mode == CLOCK_EVT_MODE_ONESHOT) { | |
59 | #ifdef CONFIG_NO_IDLE_HZ | 31 | /* Disarm the compare/match, signal the event. */ |
60 | if (match_posponed) { | 32 | OIER &= ~OIER_E0; |
61 | match_posponed = 0; | 33 | c->event_handler(c); |
62 | OSMR0 = initial_match; | 34 | } else if (c->mode == CLOCK_EVT_MODE_PERIODIC) { |
63 | } | 35 | /* Call the event handler as many times as necessary |
64 | #endif | 36 | * to recover missed events, if any (if we update |
65 | 37 | * OSMR0 and OSCR0 is still ahead of us, we've missed | |
66 | /* Loop until we get ahead of the free running timer. | 38 | * the event). As we're dealing with that, re-arm the |
67 | * This ensures an exact clock tick count and time accuracy. | 39 | * compare/match for the next event. |
68 | * Since IRQs are disabled at this point, coherence between | 40 | * |
69 | * lost_ticks(updated in do_timer()) and the match reg value is | 41 | * HACK ALERT: |
70 | * ensured, hence we can use do_gettimeofday() from interrupt | 42 | * |
71 | * handlers. | 43 | * There's a latency between the instruction that |
72 | * | 44 | * writes to OSMR0 and the actual commit to the |
73 | * HACK ALERT: it seems that the PXA timer regs aren't updated right | 45 | * physical hardware, because the CPU doesn't (have |
74 | * away in all cases when a write occurs. We therefore compare with | 46 | * to) run at bus speed, there's a write buffer |
75 | * 8 instead of 0 in the while() condition below to avoid missing a | 47 | * between the CPU and the bus, etc. etc. So if the |
76 | * match if OSCR has already reached the next OSMR value. | 48 | * target OSCR0 is "very close", to the OSMR0 load |
77 | * Experience has shown that up to 6 ticks are needed to work around | 49 | * value, the update to OSMR0 might not get to the |
78 | * this problem, but let's use 8 to be conservative. Note that this | 50 | * hardware in time and we'll miss that interrupt. |
79 | * affect things only when the timer IRQ has been delayed by nearly | 51 | * |
80 | * exactly one tick period which should be a pretty rare event. | 52 | * To be safe, if the new OSMR0 is "very close" to the |
53 | * target OSCR0 value, we call the event_handler as | ||
54 | * though the event actually happened. According to | ||
55 | * Nico's comment in the previous version of this | ||
56 | * code, experience has shown that 6 OSCR ticks is | ||
57 | * "very close" but he went with 8. We will use 16, | ||
58 | * based on the results of testing on PXA270. | ||
59 | * | ||
60 | * To be doubly sure, we also tell clkevt via | ||
61 | * clockevents_register_device() not to ask for | ||
62 | * anything that might put us "very close". | ||
81 | */ | 63 | */ |
64 | #define MIN_OSCR_DELTA 16 | ||
82 | do { | 65 | do { |
83 | timer_tick(); | 66 | OSSR = OSSR_M0; |
84 | OSSR = OSSR_M0; /* Clear match on timer 0 */ | ||
85 | next_match = (OSMR0 += LATCH); | 67 | next_match = (OSMR0 += LATCH); |
86 | } while( (signed long)(next_match - OSCR) <= 8 ); | 68 | c->event_handler(c); |
87 | 69 | } while (((signed long)(next_match - OSCR) <= MIN_OSCR_DELTA) | |
88 | write_sequnlock(&xtime_lock); | 70 | && (c->mode == CLOCK_EVT_MODE_PERIODIC)); |
71 | } | ||
89 | 72 | ||
90 | return IRQ_HANDLED; | 73 | return IRQ_HANDLED; |
91 | } | 74 | } |
92 | 75 | ||
93 | static struct irqaction pxa_timer_irq = { | 76 | static int |
94 | .name = "PXA Timer Tick", | 77 | pxa_osmr0_set_next_event(unsigned long delta, struct clock_event_device *dev) |
95 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, | 78 | { |
96 | .handler = pxa_timer_interrupt, | 79 | unsigned long irqflags; |
80 | |||
81 | raw_local_irq_save(irqflags); | ||
82 | OSMR0 = OSCR + delta; | ||
83 | OSSR = OSSR_M0; | ||
84 | OIER |= OIER_E0; | ||
85 | raw_local_irq_restore(irqflags); | ||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | static void | ||
90 | pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev) | ||
91 | { | ||
92 | unsigned long irqflags; | ||
93 | |||
94 | switch (mode) { | ||
95 | case CLOCK_EVT_MODE_PERIODIC: | ||
96 | raw_local_irq_save(irqflags); | ||
97 | OSMR0 = OSCR + LATCH; | ||
98 | OSSR = OSSR_M0; | ||
99 | OIER |= OIER_E0; | ||
100 | raw_local_irq_restore(irqflags); | ||
101 | break; | ||
102 | |||
103 | case CLOCK_EVT_MODE_ONESHOT: | ||
104 | raw_local_irq_save(irqflags); | ||
105 | OIER &= ~OIER_E0; | ||
106 | raw_local_irq_restore(irqflags); | ||
107 | break; | ||
108 | |||
109 | case CLOCK_EVT_MODE_UNUSED: | ||
110 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
111 | /* initializing, released, or preparing for suspend */ | ||
112 | raw_local_irq_save(irqflags); | ||
113 | OIER &= ~OIER_E0; | ||
114 | raw_local_irq_restore(irqflags); | ||
115 | break; | ||
116 | } | ||
117 | } | ||
118 | |||
119 | static struct clock_event_device ckevt_pxa_osmr0 = { | ||
120 | .name = "osmr0", | ||
121 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | ||
122 | .shift = 32, | ||
123 | .rating = 200, | ||
124 | .cpumask = CPU_MASK_CPU0, | ||
125 | .set_next_event = pxa_osmr0_set_next_event, | ||
126 | .set_mode = pxa_osmr0_set_mode, | ||
97 | }; | 127 | }; |
98 | 128 | ||
99 | static cycle_t pxa_get_cycles(void) | 129 | static cycle_t pxa_read_oscr(void) |
100 | { | 130 | { |
101 | return OSCR; | 131 | return OSCR; |
102 | } | 132 | } |
103 | 133 | ||
104 | static struct clocksource clocksource_pxa = { | 134 | static struct clocksource cksrc_pxa_oscr0 = { |
105 | .name = "pxa_timer", | 135 | .name = "oscr0", |
106 | .rating = 200, | 136 | .rating = 200, |
107 | .read = pxa_get_cycles, | 137 | .read = pxa_read_oscr, |
108 | .mask = CLOCKSOURCE_MASK(32), | 138 | .mask = CLOCKSOURCE_MASK(32), |
109 | .shift = 20, | 139 | .shift = 20, |
110 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 140 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
111 | }; | 141 | }; |
112 | 142 | ||
143 | static struct irqaction pxa_ost0_irq = { | ||
144 | .name = "ost0", | ||
145 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, | ||
146 | .handler = pxa_ost0_interrupt, | ||
147 | .dev_id = &ckevt_pxa_osmr0, | ||
148 | }; | ||
149 | |||
113 | static void __init pxa_timer_init(void) | 150 | static void __init pxa_timer_init(void) |
114 | { | 151 | { |
115 | struct timespec tv; | 152 | OIER = 0; |
116 | unsigned long flags; | 153 | OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3; |
117 | 154 | ||
118 | set_rtc = pxa_set_rtc; | 155 | ckevt_pxa_osmr0.mult = |
156 | div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, ckevt_pxa_osmr0.shift); | ||
157 | ckevt_pxa_osmr0.max_delta_ns = | ||
158 | clockevent_delta2ns(0x7fffffff, &ckevt_pxa_osmr0); | ||
159 | ckevt_pxa_osmr0.min_delta_ns = | ||
160 | clockevent_delta2ns(MIN_OSCR_DELTA, &ckevt_pxa_osmr0) + 1; | ||
119 | 161 | ||
120 | OIER = 0; /* disable any timer interrupts */ | 162 | cksrc_pxa_oscr0.mult = |
121 | OSSR = 0xf; /* clear status on all timers */ | 163 | clocksource_hz2mult(CLOCK_TICK_RATE, cksrc_pxa_oscr0.shift); |
122 | setup_irq(IRQ_OST0, &pxa_timer_irq); | ||
123 | local_irq_save(flags); | ||
124 | OIER = OIER_E0; /* enable match on timer 0 to cause interrupts */ | ||
125 | OSMR0 = OSCR + LATCH; /* set initial match */ | ||
126 | local_irq_restore(flags); | ||
127 | |||
128 | /* | ||
129 | * OSCR runs continuously on PXA and is not written to, | ||
130 | * so we can use it as clock source directly. | ||
131 | */ | ||
132 | clocksource_pxa.mult = | ||
133 | clocksource_hz2mult(CLOCK_TICK_RATE, clocksource_pxa.shift); | ||
134 | clocksource_register(&clocksource_pxa); | ||
135 | } | ||
136 | |||
137 | #ifdef CONFIG_NO_IDLE_HZ | ||
138 | static int pxa_dyn_tick_enable_disable(void) | ||
139 | { | ||
140 | /* nothing to do */ | ||
141 | return 0; | ||
142 | } | ||
143 | 164 | ||
144 | static void pxa_dyn_tick_reprogram(unsigned long ticks) | 165 | setup_irq(IRQ_OST0, &pxa_ost0_irq); |
145 | { | ||
146 | if (ticks > 1) { | ||
147 | initial_match = OSMR0; | ||
148 | OSMR0 = initial_match + ticks * LATCH; | ||
149 | match_posponed = 1; | ||
150 | } | ||
151 | } | ||
152 | 166 | ||
153 | static irqreturn_t | 167 | clocksource_register(&cksrc_pxa_oscr0); |
154 | pxa_dyn_tick_handler(int irq, void *dev_id) | 168 | clockevents_register_device(&ckevt_pxa_osmr0); |
155 | { | ||
156 | if (match_posponed) { | ||
157 | match_posponed = 0; | ||
158 | OSMR0 = initial_match; | ||
159 | if ( (signed long)(initial_match - OSCR) <= 8 ) | ||
160 | return pxa_timer_interrupt(irq, dev_id); | ||
161 | } | ||
162 | return IRQ_NONE; | ||
163 | } | 169 | } |
164 | 170 | ||
165 | static struct dyn_tick_timer pxa_dyn_tick = { | ||
166 | .enable = pxa_dyn_tick_enable_disable, | ||
167 | .disable = pxa_dyn_tick_enable_disable, | ||
168 | .reprogram = pxa_dyn_tick_reprogram, | ||
169 | .handler = pxa_dyn_tick_handler, | ||
170 | }; | ||
171 | #endif | ||
172 | |||
173 | #ifdef CONFIG_PM | 171 | #ifdef CONFIG_PM |
174 | static unsigned long osmr[4], oier; | 172 | static unsigned long osmr[4], oier; |
175 | 173 | ||
@@ -191,7 +189,10 @@ static void pxa_timer_resume(void) | |||
191 | OIER = oier; | 189 | OIER = oier; |
192 | 190 | ||
193 | /* | 191 | /* |
194 | * OSMR0 is the system timer: make sure OSCR is sufficiently behind | 192 | * OSCR0 is the system timer, which has to increase |
193 | * monotonically until it rolls over in hardware. The value | ||
194 | * (OSMR0 - LATCH) is OSCR0 at the most recent system tick, | ||
195 | * which is a handy value to restore to OSCR0. | ||
195 | */ | 196 | */ |
196 | OSCR = OSMR0 - LATCH; | 197 | OSCR = OSMR0 - LATCH; |
197 | } | 198 | } |
@@ -204,7 +205,4 @@ struct sys_timer pxa_timer = { | |||
204 | .init = pxa_timer_init, | 205 | .init = pxa_timer_init, |
205 | .suspend = pxa_timer_suspend, | 206 | .suspend = pxa_timer_suspend, |
206 | .resume = pxa_timer_resume, | 207 | .resume = pxa_timer_resume, |
207 | #ifdef CONFIG_NO_IDLE_HZ | ||
208 | .dyn_tick = &pxa_dyn_tick, | ||
209 | #endif | ||
210 | }; | 208 | }; |
diff --git a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c index 570cf937e73b..a454451c97c3 100644 --- a/arch/arm/mach-rpc/riscpc.c +++ b/arch/arm/mach-rpc/riscpc.c | |||
@@ -87,7 +87,7 @@ static void __init rpc_map_io(void) | |||
87 | /* | 87 | /* |
88 | * Turn off floppy. | 88 | * Turn off floppy. |
89 | */ | 89 | */ |
90 | outb(0xc, 0x3f2); | 90 | writeb(0xc, PCIO_BASE + (0x3f2 << 2)); |
91 | 91 | ||
92 | /* | 92 | /* |
93 | * RiscPC can't handle half-word loads and stores | 93 | * RiscPC can't handle half-word loads and stores |
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig index d4b013b283c3..e2079cf9266f 100644 --- a/arch/arm/mach-s3c2410/Kconfig +++ b/arch/arm/mach-s3c2410/Kconfig | |||
@@ -9,6 +9,7 @@ config CPU_S3C2410 | |||
9 | depends on ARCH_S3C2410 | 9 | depends on ARCH_S3C2410 |
10 | select S3C2410_CLOCK | 10 | select S3C2410_CLOCK |
11 | select S3C2410_GPIO | 11 | select S3C2410_GPIO |
12 | select CPU_LLSERIAL_S3C2410 | ||
12 | select S3C2410_PM if PM | 13 | select S3C2410_PM if PM |
13 | help | 14 | help |
14 | Support for S3C2410 and S3C2410A family from the S3C24XX line | 15 | Support for S3C2410 and S3C2410A family from the S3C24XX line |
diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c index 5b4831c4c1d8..cab9d6265e9e 100644 --- a/arch/arm/mach-s3c2410/clock.c +++ b/arch/arm/mach-s3c2410/clock.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include <asm/hardware.h> | 37 | #include <asm/hardware.h> |
38 | #include <asm/io.h> | 38 | #include <asm/io.h> |
39 | 39 | ||
40 | #include <asm/arch/regs-serial.h> | 40 | #include <asm/plat-s3c/regs-serial.h> |
41 | #include <asm/arch/regs-clock.h> | 41 | #include <asm/arch/regs-clock.h> |
42 | #include <asm/arch/regs-gpio.h> | 42 | #include <asm/arch/regs-gpio.h> |
43 | 43 | ||
diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c index 67d1ad363973..80d83739ab9f 100644 --- a/arch/arm/mach-s3c2410/dma.c +++ b/arch/arm/mach-s3c2410/dma.c | |||
@@ -23,14 +23,14 @@ | |||
23 | #include <asm/plat-s3c24xx/cpu.h> | 23 | #include <asm/plat-s3c24xx/cpu.h> |
24 | #include <asm/plat-s3c24xx/dma.h> | 24 | #include <asm/plat-s3c24xx/dma.h> |
25 | 25 | ||
26 | #include <asm/arch/regs-serial.h> | 26 | #include <asm/plat-s3c/regs-serial.h> |
27 | #include <asm/arch/regs-gpio.h> | 27 | #include <asm/arch/regs-gpio.h> |
28 | #include <asm/arch/regs-ac97.h> | 28 | #include <asm/plat-s3c/regs-ac97.h> |
29 | #include <asm/arch/regs-mem.h> | 29 | #include <asm/arch/regs-mem.h> |
30 | #include <asm/arch/regs-lcd.h> | 30 | #include <asm/arch/regs-lcd.h> |
31 | #include <asm/arch/regs-sdi.h> | 31 | #include <asm/arch/regs-sdi.h> |
32 | #include <asm/arch/regs-iis.h> | 32 | #include <asm/plat-s3c24xx/regs-iis.h> |
33 | #include <asm/arch/regs-spi.h> | 33 | #include <asm/plat-s3c24xx/regs-spi.h> |
34 | 34 | ||
35 | static struct s3c24xx_dma_map __initdata s3c2410_dma_mappings[] = { | 35 | static struct s3c24xx_dma_map __initdata s3c2410_dma_mappings[] = { |
36 | [DMACH_XD0] = { | 36 | [DMACH_XD0] = { |
diff --git a/arch/arm/mach-s3c2410/mach-amlm5900.c b/arch/arm/mach-s3c2410/mach-amlm5900.c index 435adcce6482..43bb5e106302 100644 --- a/arch/arm/mach-s3c2410/mach-amlm5900.c +++ b/arch/arm/mach-s3c2410/mach-amlm5900.c | |||
@@ -48,7 +48,7 @@ | |||
48 | #include <asm/mach-types.h> | 48 | #include <asm/mach-types.h> |
49 | #include <asm/arch/fb.h> | 49 | #include <asm/arch/fb.h> |
50 | 50 | ||
51 | #include <asm/arch/regs-serial.h> | 51 | #include <asm/plat-s3c/regs-serial.h> |
52 | #include <asm/arch/regs-lcd.h> | 52 | #include <asm/arch/regs-lcd.h> |
53 | #include <asm/arch/regs-gpio.h> | 53 | #include <asm/arch/regs-gpio.h> |
54 | 54 | ||
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index 8b52ea95d4f6..bc926992b4e4 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c | |||
@@ -36,13 +36,13 @@ | |||
36 | #include <asm/mach-types.h> | 36 | #include <asm/mach-types.h> |
37 | 37 | ||
38 | //#include <asm/debug-ll.h> | 38 | //#include <asm/debug-ll.h> |
39 | #include <asm/arch/regs-serial.h> | 39 | #include <asm/plat-s3c/regs-serial.h> |
40 | #include <asm/arch/regs-gpio.h> | 40 | #include <asm/arch/regs-gpio.h> |
41 | #include <asm/arch/regs-mem.h> | 41 | #include <asm/arch/regs-mem.h> |
42 | #include <asm/arch/regs-lcd.h> | 42 | #include <asm/arch/regs-lcd.h> |
43 | 43 | ||
44 | #include <asm/arch/nand.h> | 44 | #include <asm/plat-s3c/nand.h> |
45 | #include <asm/arch/iic.h> | 45 | #include <asm/plat-s3c/iic.h> |
46 | #include <asm/arch/fb.h> | 46 | #include <asm/arch/fb.h> |
47 | 47 | ||
48 | #include <linux/mtd/mtd.h> | 48 | #include <linux/mtd/mtd.h> |
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c index 5c9bcea74767..9a172b4ad720 100644 --- a/arch/arm/mach-s3c2410/mach-h1940.c +++ b/arch/arm/mach-s3c2410/mach-h1940.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include <asm/irq.h> | 30 | #include <asm/irq.h> |
31 | #include <asm/mach-types.h> | 31 | #include <asm/mach-types.h> |
32 | 32 | ||
33 | #include <asm/arch/regs-serial.h> | 33 | #include <asm/plat-s3c/regs-serial.h> |
34 | #include <asm/arch/regs-lcd.h> | 34 | #include <asm/arch/regs-lcd.h> |
35 | #include <asm/arch/regs-gpio.h> | 35 | #include <asm/arch/regs-gpio.h> |
36 | #include <asm/arch/regs-clock.h> | 36 | #include <asm/arch/regs-clock.h> |
@@ -38,7 +38,7 @@ | |||
38 | #include <asm/arch/h1940.h> | 38 | #include <asm/arch/h1940.h> |
39 | #include <asm/arch/h1940-latch.h> | 39 | #include <asm/arch/h1940-latch.h> |
40 | #include <asm/arch/fb.h> | 40 | #include <asm/arch/fb.h> |
41 | #include <asm/arch/udc.h> | 41 | #include <asm/plat-s3c24xx/udc.h> |
42 | 42 | ||
43 | #include <asm/plat-s3c24xx/clock.h> | 43 | #include <asm/plat-s3c24xx/clock.h> |
44 | #include <asm/plat-s3c24xx/devs.h> | 44 | #include <asm/plat-s3c24xx/devs.h> |
diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index 412e50c3d28a..621f548da610 100644 --- a/arch/arm/mach-s3c2410/mach-n30.c +++ b/arch/arm/mach-s3c2410/mach-n30.c | |||
@@ -33,9 +33,9 @@ | |||
33 | #include <asm/irq.h> | 33 | #include <asm/irq.h> |
34 | #include <asm/mach-types.h> | 34 | #include <asm/mach-types.h> |
35 | 35 | ||
36 | #include <asm/arch/regs-serial.h> | 36 | #include <asm/plat-s3c/regs-serial.h> |
37 | #include <asm/arch/regs-gpio.h> | 37 | #include <asm/arch/regs-gpio.h> |
38 | #include <asm/arch/iic.h> | 38 | #include <asm/plat-s3c/iic.h> |
39 | 39 | ||
40 | #include <asm/plat-s3c24xx/s3c2410.h> | 40 | #include <asm/plat-s3c24xx/s3c2410.h> |
41 | #include <asm/plat-s3c24xx/clock.h> | 41 | #include <asm/plat-s3c24xx/clock.h> |
diff --git a/arch/arm/mach-s3c2410/mach-otom.c b/arch/arm/mach-s3c2410/mach-otom.c index 1f899fa588df..717af40e4477 100644 --- a/arch/arm/mach-s3c2410/mach-otom.c +++ b/arch/arm/mach-s3c2410/mach-otom.c | |||
@@ -29,7 +29,7 @@ | |||
29 | #include <asm/irq.h> | 29 | #include <asm/irq.h> |
30 | #include <asm/mach-types.h> | 30 | #include <asm/mach-types.h> |
31 | 31 | ||
32 | #include <asm/arch/regs-serial.h> | 32 | #include <asm/plat-s3c/regs-serial.h> |
33 | #include <asm/arch/regs-gpio.h> | 33 | #include <asm/arch/regs-gpio.h> |
34 | 34 | ||
35 | #include <asm/plat-s3c24xx/s3c2410.h> | 35 | #include <asm/plat-s3c24xx/s3c2410.h> |
diff --git a/arch/arm/mach-s3c2410/mach-qt2410.c b/arch/arm/mach-s3c2410/mach-qt2410.c index d86e6f18bac9..e670b1e1631b 100644 --- a/arch/arm/mach-s3c2410/mach-qt2410.c +++ b/arch/arm/mach-s3c2410/mach-qt2410.c | |||
@@ -49,10 +49,10 @@ | |||
49 | 49 | ||
50 | #include <asm/arch/regs-gpio.h> | 50 | #include <asm/arch/regs-gpio.h> |
51 | #include <asm/arch/leds-gpio.h> | 51 | #include <asm/arch/leds-gpio.h> |
52 | #include <asm/arch/regs-serial.h> | 52 | #include <asm/plat-s3c/regs-serial.h> |
53 | #include <asm/arch/fb.h> | 53 | #include <asm/arch/fb.h> |
54 | #include <asm/arch/nand.h> | 54 | #include <asm/plat-s3c/nand.h> |
55 | #include <asm/arch/udc.h> | 55 | #include <asm/plat-s3c24xx/udc.h> |
56 | #include <asm/arch/spi.h> | 56 | #include <asm/arch/spi.h> |
57 | #include <asm/arch/spi-gpio.h> | 57 | #include <asm/arch/spi-gpio.h> |
58 | 58 | ||
diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c index 5852d300d52f..226550504c85 100644 --- a/arch/arm/mach-s3c2410/mach-smdk2410.c +++ b/arch/arm/mach-s3c2410/mach-smdk2410.c | |||
@@ -47,7 +47,7 @@ | |||
47 | #include <asm/irq.h> | 47 | #include <asm/irq.h> |
48 | #include <asm/mach-types.h> | 48 | #include <asm/mach-types.h> |
49 | 49 | ||
50 | #include <asm/arch/regs-serial.h> | 50 | #include <asm/plat-s3c/regs-serial.h> |
51 | 51 | ||
52 | #include <asm/plat-s3c24xx/devs.h> | 52 | #include <asm/plat-s3c24xx/devs.h> |
53 | #include <asm/plat-s3c24xx/cpu.h> | 53 | #include <asm/plat-s3c24xx/cpu.h> |
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c index 7b624bb00490..9f43f3f124f5 100644 --- a/arch/arm/mach-s3c2410/mach-vr1000.c +++ b/arch/arm/mach-s3c2410/mach-vr1000.c | |||
@@ -39,7 +39,7 @@ | |||
39 | #include <asm/irq.h> | 39 | #include <asm/irq.h> |
40 | #include <asm/mach-types.h> | 40 | #include <asm/mach-types.h> |
41 | 41 | ||
42 | #include <asm/arch/regs-serial.h> | 42 | #include <asm/plat-s3c/regs-serial.h> |
43 | #include <asm/arch/regs-gpio.h> | 43 | #include <asm/arch/regs-gpio.h> |
44 | #include <asm/arch/leds-gpio.h> | 44 | #include <asm/arch/leds-gpio.h> |
45 | 45 | ||
diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c index 1a86a9803753..e580303cb0ab 100644 --- a/arch/arm/mach-s3c2410/s3c2410.c +++ b/arch/arm/mach-s3c2410/s3c2410.c | |||
@@ -29,7 +29,7 @@ | |||
29 | #include <asm/irq.h> | 29 | #include <asm/irq.h> |
30 | 30 | ||
31 | #include <asm/arch/regs-clock.h> | 31 | #include <asm/arch/regs-clock.h> |
32 | #include <asm/arch/regs-serial.h> | 32 | #include <asm/plat-s3c/regs-serial.h> |
33 | 33 | ||
34 | #include <asm/plat-s3c24xx/s3c2410.h> | 34 | #include <asm/plat-s3c24xx/s3c2410.h> |
35 | #include <asm/plat-s3c24xx/cpu.h> | 35 | #include <asm/plat-s3c24xx/cpu.h> |
@@ -40,7 +40,6 @@ | |||
40 | 40 | ||
41 | static struct map_desc s3c2410_iodesc[] __initdata = { | 41 | static struct map_desc s3c2410_iodesc[] __initdata = { |
42 | IODESC_ENT(CLKPWR), | 42 | IODESC_ENT(CLKPWR), |
43 | IODESC_ENT(LCD), | ||
44 | IODESC_ENT(TIMER), | 43 | IODESC_ENT(TIMER), |
45 | IODESC_ENT(WATCHDOG), | 44 | IODESC_ENT(WATCHDOG), |
46 | }; | 45 | }; |
diff --git a/arch/arm/mach-s3c2410/sleep.S b/arch/arm/mach-s3c2410/sleep.S index d1eeed2ad47c..8a9c5a2bb252 100644 --- a/arch/arm/mach-s3c2410/sleep.S +++ b/arch/arm/mach-s3c2410/sleep.S | |||
@@ -32,7 +32,7 @@ | |||
32 | #include <asm/arch/regs-gpio.h> | 32 | #include <asm/arch/regs-gpio.h> |
33 | #include <asm/arch/regs-clock.h> | 33 | #include <asm/arch/regs-clock.h> |
34 | #include <asm/arch/regs-mem.h> | 34 | #include <asm/arch/regs-mem.h> |
35 | #include <asm/arch/regs-serial.h> | 35 | #include <asm/plat-s3c/regs-serial.h> |
36 | 36 | ||
37 | /* s3c2410_cpu_suspend | 37 | /* s3c2410_cpu_suspend |
38 | * | 38 | * |
diff --git a/arch/arm/mach-s3c2412/Kconfig b/arch/arm/mach-s3c2412/Kconfig index d5be5d053264..8e8fe48ea47f 100644 --- a/arch/arm/mach-s3c2412/Kconfig +++ b/arch/arm/mach-s3c2412/Kconfig | |||
@@ -7,6 +7,7 @@ | |||
7 | config CPU_S3C2412 | 7 | config CPU_S3C2412 |
8 | bool | 8 | bool |
9 | depends on ARCH_S3C2410 | 9 | depends on ARCH_S3C2410 |
10 | select CPU_LLSERIAL_S3C2440 | ||
10 | select S3C2412_PM if PM | 11 | select S3C2412_PM if PM |
11 | select S3C2412_DMA if S3C2410_DMA | 12 | select S3C2412_DMA if S3C2410_DMA |
12 | help | 13 | help |
diff --git a/arch/arm/mach-s3c2412/clock.c b/arch/arm/mach-s3c2412/clock.c index 6a8e4448770b..8543dd6df391 100644 --- a/arch/arm/mach-s3c2412/clock.c +++ b/arch/arm/mach-s3c2412/clock.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include <asm/hardware.h> | 37 | #include <asm/hardware.h> |
38 | #include <asm/io.h> | 38 | #include <asm/io.h> |
39 | 39 | ||
40 | #include <asm/arch/regs-serial.h> | 40 | #include <asm/plat-s3c/regs-serial.h> |
41 | #include <asm/arch/regs-clock.h> | 41 | #include <asm/arch/regs-clock.h> |
42 | #include <asm/arch/regs-gpio.h> | 42 | #include <asm/arch/regs-gpio.h> |
43 | 43 | ||
diff --git a/arch/arm/mach-s3c2412/dma.c b/arch/arm/mach-s3c2412/dma.c index 668cccefe7b0..4b9425c1bf72 100644 --- a/arch/arm/mach-s3c2412/dma.c +++ b/arch/arm/mach-s3c2412/dma.c | |||
@@ -24,14 +24,14 @@ | |||
24 | #include <asm/plat-s3c24xx/dma.h> | 24 | #include <asm/plat-s3c24xx/dma.h> |
25 | #include <asm/plat-s3c24xx/cpu.h> | 25 | #include <asm/plat-s3c24xx/cpu.h> |
26 | 26 | ||
27 | #include <asm/arch/regs-serial.h> | 27 | #include <asm/plat-s3c/regs-serial.h> |
28 | #include <asm/arch/regs-gpio.h> | 28 | #include <asm/arch/regs-gpio.h> |
29 | #include <asm/arch/regs-ac97.h> | 29 | #include <asm/plat-s3c/regs-ac97.h> |
30 | #include <asm/arch/regs-mem.h> | 30 | #include <asm/arch/regs-mem.h> |
31 | #include <asm/arch/regs-lcd.h> | 31 | #include <asm/arch/regs-lcd.h> |
32 | #include <asm/arch/regs-sdi.h> | 32 | #include <asm/arch/regs-sdi.h> |
33 | #include <asm/arch/regs-iis.h> | 33 | #include <asm/plat-s3c24xx/regs-iis.h> |
34 | #include <asm/arch/regs-spi.h> | 34 | #include <asm/plat-s3c24xx/regs-spi.h> |
35 | 35 | ||
36 | #define MAP(x) { (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID } | 36 | #define MAP(x) { (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID } |
37 | 37 | ||
diff --git a/arch/arm/mach-s3c2412/mach-smdk2413.c b/arch/arm/mach-s3c2412/mach-smdk2413.c index 063af09f899d..b126a530daa6 100644 --- a/arch/arm/mach-s3c2412/mach-smdk2413.c +++ b/arch/arm/mach-s3c2412/mach-smdk2413.c | |||
@@ -32,12 +32,12 @@ | |||
32 | #include <asm/mach-types.h> | 32 | #include <asm/mach-types.h> |
33 | 33 | ||
34 | //#include <asm/debug-ll.h> | 34 | //#include <asm/debug-ll.h> |
35 | #include <asm/arch/regs-serial.h> | 35 | #include <asm/plat-s3c/regs-serial.h> |
36 | #include <asm/arch/regs-gpio.h> | 36 | #include <asm/arch/regs-gpio.h> |
37 | #include <asm/arch/regs-lcd.h> | 37 | #include <asm/arch/regs-lcd.h> |
38 | 38 | ||
39 | #include <asm/arch/idle.h> | 39 | #include <asm/arch/idle.h> |
40 | #include <asm/arch/udc.h> | 40 | #include <asm/plat-s3c24xx/udc.h> |
41 | #include <asm/arch/fb.h> | 41 | #include <asm/arch/fb.h> |
42 | 42 | ||
43 | #include <asm/plat-s3c24xx/s3c2410.h> | 43 | #include <asm/plat-s3c24xx/s3c2410.h> |
diff --git a/arch/arm/mach-s3c2412/mach-vstms.c b/arch/arm/mach-s3c2412/mach-vstms.c index f2fbd65956ac..32982547cd63 100644 --- a/arch/arm/mach-s3c2412/mach-vstms.c +++ b/arch/arm/mach-s3c2412/mach-vstms.c | |||
@@ -33,14 +33,14 @@ | |||
33 | #include <asm/irq.h> | 33 | #include <asm/irq.h> |
34 | #include <asm/mach-types.h> | 34 | #include <asm/mach-types.h> |
35 | 35 | ||
36 | #include <asm/arch/regs-serial.h> | 36 | #include <asm/plat-s3c/regs-serial.h> |
37 | #include <asm/arch/regs-gpio.h> | 37 | #include <asm/arch/regs-gpio.h> |
38 | #include <asm/arch/regs-lcd.h> | 38 | #include <asm/arch/regs-lcd.h> |
39 | 39 | ||
40 | #include <asm/arch/idle.h> | 40 | #include <asm/arch/idle.h> |
41 | #include <asm/arch/fb.h> | 41 | #include <asm/arch/fb.h> |
42 | 42 | ||
43 | #include <asm/arch/nand.h> | 43 | #include <asm/plat-s3c/nand.h> |
44 | 44 | ||
45 | #include <asm/plat-s3c24xx/s3c2410.h> | 45 | #include <asm/plat-s3c24xx/s3c2410.h> |
46 | #include <asm/plat-s3c24xx/s3c2412.h> | 46 | #include <asm/plat-s3c24xx/s3c2412.h> |
diff --git a/arch/arm/mach-s3c2412/s3c2412.c b/arch/arm/mach-s3c2412/s3c2412.c index 782b5814ced2..e0ccb404623f 100644 --- a/arch/arm/mach-s3c2412/s3c2412.c +++ b/arch/arm/mach-s3c2412/s3c2412.c | |||
@@ -34,12 +34,12 @@ | |||
34 | #include <asm/arch/idle.h> | 34 | #include <asm/arch/idle.h> |
35 | 35 | ||
36 | #include <asm/arch/regs-clock.h> | 36 | #include <asm/arch/regs-clock.h> |
37 | #include <asm/arch/regs-serial.h> | 37 | #include <asm/plat-s3c/regs-serial.h> |
38 | #include <asm/arch/regs-power.h> | 38 | #include <asm/arch/regs-power.h> |
39 | #include <asm/arch/regs-gpio.h> | 39 | #include <asm/arch/regs-gpio.h> |
40 | #include <asm/arch/regs-gpioj.h> | 40 | #include <asm/arch/regs-gpioj.h> |
41 | #include <asm/arch/regs-dsc.h> | 41 | #include <asm/arch/regs-dsc.h> |
42 | #include <asm/arch/regs-spi.h> | 42 | #include <asm/plat-s3c24xx/regs-spi.h> |
43 | #include <asm/arch/regs-s3c2412.h> | 43 | #include <asm/arch/regs-s3c2412.h> |
44 | 44 | ||
45 | #include <asm/plat-s3c24xx/s3c2412.h> | 45 | #include <asm/plat-s3c24xx/s3c2412.h> |
@@ -63,7 +63,6 @@ static inline void s3c2412_init_gpio2(void) | |||
63 | 63 | ||
64 | static struct map_desc s3c2412_iodesc[] __initdata = { | 64 | static struct map_desc s3c2412_iodesc[] __initdata = { |
65 | IODESC_ENT(CLKPWR), | 65 | IODESC_ENT(CLKPWR), |
66 | IODESC_ENT(LCD), | ||
67 | IODESC_ENT(TIMER), | 66 | IODESC_ENT(TIMER), |
68 | IODESC_ENT(WATCHDOG), | 67 | IODESC_ENT(WATCHDOG), |
69 | }; | 68 | }; |
diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig index e3bfda098c0f..f1915bd61d15 100644 --- a/arch/arm/mach-s3c2440/Kconfig +++ b/arch/arm/mach-s3c2440/Kconfig | |||
@@ -12,6 +12,7 @@ config CPU_S3C2440 | |||
12 | select S3C2410_GPIO | 12 | select S3C2410_GPIO |
13 | select S3C2440_DMA if S3C2410_DMA | 13 | select S3C2440_DMA if S3C2410_DMA |
14 | select CPU_S3C244X | 14 | select CPU_S3C244X |
15 | select CPU_LLSERIAL_S3C2440 | ||
15 | help | 16 | help |
16 | Support for S3C2440 Samsung Mobile CPU based systems. | 17 | Support for S3C2440 Samsung Mobile CPU based systems. |
17 | 18 | ||
diff --git a/arch/arm/mach-s3c2440/dma.c b/arch/arm/mach-s3c2440/dma.c index cd035a3ec878..f509f062e749 100644 --- a/arch/arm/mach-s3c2440/dma.c +++ b/arch/arm/mach-s3c2440/dma.c | |||
@@ -23,14 +23,14 @@ | |||
23 | #include <asm/plat-s3c24xx/dma.h> | 23 | #include <asm/plat-s3c24xx/dma.h> |
24 | #include <asm/plat-s3c24xx/cpu.h> | 24 | #include <asm/plat-s3c24xx/cpu.h> |
25 | 25 | ||
26 | #include <asm/arch/regs-serial.h> | 26 | #include <asm/plat-s3c/regs-serial.h> |
27 | #include <asm/arch/regs-gpio.h> | 27 | #include <asm/arch/regs-gpio.h> |
28 | #include <asm/arch/regs-ac97.h> | 28 | #include <asm/plat-s3c/regs-ac97.h> |
29 | #include <asm/arch/regs-mem.h> | 29 | #include <asm/arch/regs-mem.h> |
30 | #include <asm/arch/regs-lcd.h> | 30 | #include <asm/arch/regs-lcd.h> |
31 | #include <asm/arch/regs-sdi.h> | 31 | #include <asm/arch/regs-sdi.h> |
32 | #include <asm/arch/regs-iis.h> | 32 | #include <asm/plat-s3c24xx/regs-iis.h> |
33 | #include <asm/arch/regs-spi.h> | 33 | #include <asm/plat-s3c24xx/regs-spi.h> |
34 | 34 | ||
35 | static struct s3c24xx_dma_map __initdata s3c2440_dma_mappings[] = { | 35 | static struct s3c24xx_dma_map __initdata s3c2440_dma_mappings[] = { |
36 | [DMACH_XD0] = { | 36 | [DMACH_XD0] = { |
diff --git a/arch/arm/mach-s3c2440/mach-anubis.c b/arch/arm/mach-s3c2440/mach-anubis.c index 29c163d300d4..3d3dfa95db8e 100644 --- a/arch/arm/mach-s3c2440/mach-anubis.c +++ b/arch/arm/mach-s3c2440/mach-anubis.c | |||
@@ -34,11 +34,11 @@ | |||
34 | #include <asm/irq.h> | 34 | #include <asm/irq.h> |
35 | #include <asm/mach-types.h> | 35 | #include <asm/mach-types.h> |
36 | 36 | ||
37 | #include <asm/arch/regs-serial.h> | 37 | #include <asm/plat-s3c/regs-serial.h> |
38 | #include <asm/arch/regs-gpio.h> | 38 | #include <asm/arch/regs-gpio.h> |
39 | #include <asm/arch/regs-mem.h> | 39 | #include <asm/arch/regs-mem.h> |
40 | #include <asm/arch/regs-lcd.h> | 40 | #include <asm/arch/regs-lcd.h> |
41 | #include <asm/arch/nand.h> | 41 | #include <asm/plat-s3c/nand.h> |
42 | 42 | ||
43 | #include <linux/mtd/mtd.h> | 43 | #include <linux/mtd/mtd.h> |
44 | #include <linux/mtd/nand.h> | 44 | #include <linux/mtd/nand.h> |
diff --git a/arch/arm/mach-s3c2440/mach-nexcoder.c b/arch/arm/mach-s3c2440/mach-nexcoder.c index 5e61f2166c76..afe0d7b7e389 100644 --- a/arch/arm/mach-s3c2440/mach-nexcoder.c +++ b/arch/arm/mach-s3c2440/mach-nexcoder.c | |||
@@ -36,7 +36,7 @@ | |||
36 | 36 | ||
37 | //#include <asm/debug-ll.h> | 37 | //#include <asm/debug-ll.h> |
38 | #include <asm/arch/regs-gpio.h> | 38 | #include <asm/arch/regs-gpio.h> |
39 | #include <asm/arch/regs-serial.h> | 39 | #include <asm/plat-s3c/regs-serial.h> |
40 | 40 | ||
41 | #include <asm/plat-s3c24xx/s3c2410.h> | 41 | #include <asm/plat-s3c24xx/s3c2410.h> |
42 | #include <asm/plat-s3c24xx/s3c2440.h> | 42 | #include <asm/plat-s3c24xx/s3c2440.h> |
diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c index 89f4c9c5777b..0ba7e9060c7b 100644 --- a/arch/arm/mach-s3c2440/mach-osiris.c +++ b/arch/arm/mach-s3c2440/mach-osiris.c | |||
@@ -31,11 +31,11 @@ | |||
31 | #include <asm/irq.h> | 31 | #include <asm/irq.h> |
32 | #include <asm/mach-types.h> | 32 | #include <asm/mach-types.h> |
33 | 33 | ||
34 | #include <asm/arch/regs-serial.h> | 34 | #include <asm/plat-s3c/regs-serial.h> |
35 | #include <asm/arch/regs-gpio.h> | 35 | #include <asm/arch/regs-gpio.h> |
36 | #include <asm/arch/regs-mem.h> | 36 | #include <asm/arch/regs-mem.h> |
37 | #include <asm/arch/regs-lcd.h> | 37 | #include <asm/arch/regs-lcd.h> |
38 | #include <asm/arch/nand.h> | 38 | #include <asm/plat-s3c/nand.h> |
39 | 39 | ||
40 | #include <linux/mtd/mtd.h> | 40 | #include <linux/mtd/mtd.h> |
41 | #include <linux/mtd/nand.h> | 41 | #include <linux/mtd/nand.h> |
diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c index 866ff71c01dd..b59e6d39f2f2 100644 --- a/arch/arm/mach-s3c2440/mach-rx3715.c +++ b/arch/arm/mach-s3c2440/mach-rx3715.c | |||
@@ -38,12 +38,12 @@ | |||
38 | #include <asm/irq.h> | 38 | #include <asm/irq.h> |
39 | #include <asm/mach-types.h> | 39 | #include <asm/mach-types.h> |
40 | 40 | ||
41 | #include <asm/arch/regs-serial.h> | 41 | #include <asm/plat-s3c/regs-serial.h> |
42 | #include <asm/arch/regs-gpio.h> | 42 | #include <asm/arch/regs-gpio.h> |
43 | #include <asm/arch/regs-lcd.h> | 43 | #include <asm/arch/regs-lcd.h> |
44 | 44 | ||
45 | #include <asm/arch/h1940.h> | 45 | #include <asm/arch/h1940.h> |
46 | #include <asm/arch/nand.h> | 46 | #include <asm/plat-s3c/nand.h> |
47 | #include <asm/arch/fb.h> | 47 | #include <asm/arch/fb.h> |
48 | 48 | ||
49 | #include <asm/plat-s3c24xx/clock.h> | 49 | #include <asm/plat-s3c24xx/clock.h> |
diff --git a/arch/arm/mach-s3c2440/mach-smdk2440.c b/arch/arm/mach-s3c2440/mach-smdk2440.c index e167254e232e..670115b8a12e 100644 --- a/arch/arm/mach-s3c2440/mach-smdk2440.c +++ b/arch/arm/mach-s3c2440/mach-smdk2440.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <asm/irq.h> | 31 | #include <asm/irq.h> |
32 | #include <asm/mach-types.h> | 32 | #include <asm/mach-types.h> |
33 | 33 | ||
34 | #include <asm/arch/regs-serial.h> | 34 | #include <asm/plat-s3c/regs-serial.h> |
35 | #include <asm/arch/regs-gpio.h> | 35 | #include <asm/arch/regs-gpio.h> |
36 | #include <asm/arch/regs-lcd.h> | 36 | #include <asm/arch/regs-lcd.h> |
37 | 37 | ||
diff --git a/arch/arm/mach-s3c2442/Kconfig b/arch/arm/mach-s3c2442/Kconfig index bf8d87abfab3..88d5fd34fe3b 100644 --- a/arch/arm/mach-s3c2442/Kconfig +++ b/arch/arm/mach-s3c2442/Kconfig | |||
@@ -11,6 +11,7 @@ config CPU_S3C2442 | |||
11 | select S3C2410_GPIO | 11 | select S3C2410_GPIO |
12 | select S3C2410_PM if PM | 12 | select S3C2410_PM if PM |
13 | select CPU_S3C244X | 13 | select CPU_S3C244X |
14 | select CPU_LLSERIAL_S3C2440 | ||
14 | help | 15 | help |
15 | Support for S3C2442 Samsung Mobile CPU based systems. | 16 | Support for S3C2442 Samsung Mobile CPU based systems. |
16 | 17 | ||
diff --git a/arch/arm/mach-s3c2443/Kconfig b/arch/arm/mach-s3c2443/Kconfig index c649bb2e7ce8..14252f573754 100644 --- a/arch/arm/mach-s3c2443/Kconfig +++ b/arch/arm/mach-s3c2443/Kconfig | |||
@@ -8,6 +8,7 @@ config CPU_S3C2443 | |||
8 | bool | 8 | bool |
9 | depends on ARCH_S3C2410 | 9 | depends on ARCH_S3C2410 |
10 | select S3C2443_DMA if S3C2410_DMA | 10 | select S3C2443_DMA if S3C2410_DMA |
11 | select CPU_LLSERIAL_S3C2440 | ||
11 | help | 12 | help |
12 | Support for the S3C2443 SoC from the S3C24XX line | 13 | Support for the S3C2443 SoC from the S3C24XX line |
13 | 14 | ||
diff --git a/arch/arm/mach-s3c2443/dma.c b/arch/arm/mach-s3c2443/dma.c index f70e8ccffc3d..fc3ede82af8f 100644 --- a/arch/arm/mach-s3c2443/dma.c +++ b/arch/arm/mach-s3c2443/dma.c | |||
@@ -24,14 +24,14 @@ | |||
24 | #include <asm/plat-s3c24xx/dma.h> | 24 | #include <asm/plat-s3c24xx/dma.h> |
25 | #include <asm/plat-s3c24xx/cpu.h> | 25 | #include <asm/plat-s3c24xx/cpu.h> |
26 | 26 | ||
27 | #include <asm/arch/regs-serial.h> | 27 | #include <asm/plat-s3c/regs-serial.h> |
28 | #include <asm/arch/regs-gpio.h> | 28 | #include <asm/arch/regs-gpio.h> |
29 | #include <asm/arch/regs-ac97.h> | 29 | #include <asm/plat-s3c/regs-ac97.h> |
30 | #include <asm/arch/regs-mem.h> | 30 | #include <asm/arch/regs-mem.h> |
31 | #include <asm/arch/regs-lcd.h> | 31 | #include <asm/arch/regs-lcd.h> |
32 | #include <asm/arch/regs-sdi.h> | 32 | #include <asm/arch/regs-sdi.h> |
33 | #include <asm/arch/regs-iis.h> | 33 | #include <asm/plat-s3c24xx/regs-iis.h> |
34 | #include <asm/arch/regs-spi.h> | 34 | #include <asm/plat-s3c24xx/regs-spi.h> |
35 | 35 | ||
36 | #define MAP(x) { \ | 36 | #define MAP(x) { \ |
37 | [0] = (x) | DMA_CH_VALID, \ | 37 | [0] = (x) | DMA_CH_VALID, \ |
diff --git a/arch/arm/mach-s3c2443/mach-smdk2443.c b/arch/arm/mach-s3c2443/mach-smdk2443.c index b1eb709ee65a..8cd93130ef36 100644 --- a/arch/arm/mach-s3c2443/mach-smdk2443.c +++ b/arch/arm/mach-s3c2443/mach-smdk2443.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <asm/irq.h> | 31 | #include <asm/irq.h> |
32 | #include <asm/mach-types.h> | 32 | #include <asm/mach-types.h> |
33 | 33 | ||
34 | #include <asm/arch/regs-serial.h> | 34 | #include <asm/plat-s3c/regs-serial.h> |
35 | #include <asm/arch/regs-gpio.h> | 35 | #include <asm/arch/regs-gpio.h> |
36 | #include <asm/arch/regs-lcd.h> | 36 | #include <asm/arch/regs-lcd.h> |
37 | 37 | ||
diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig index cd67ab1b217b..f99d9013905f 100644 --- a/arch/arm/mach-sa1100/Kconfig +++ b/arch/arm/mach-sa1100/Kconfig | |||
@@ -101,6 +101,16 @@ config SA1100_JORNADA720 | |||
101 | handheld computer. See <http://www.hp.com/jornada/products/720> | 101 | handheld computer. See <http://www.hp.com/jornada/products/720> |
102 | for details. | 102 | for details. |
103 | 103 | ||
104 | config SA1100_JORNADA720_SSP | ||
105 | bool "HP Jornada 720 Extended SSP driver" | ||
106 | select SA1100_SSP | ||
107 | depends on SA1100_JORNADA720 | ||
108 | help | ||
109 | Say Y here if you have a HP Jornada 7xx handheld computer and you | ||
110 | want to access devices connected to the MCU. Those include the | ||
111 | keyboard, touchscreen, backlight and battery. This driver also activates | ||
112 | the generic SSP which it extends. | ||
113 | |||
104 | config SA1100_HACKKIT | 114 | config SA1100_HACKKIT |
105 | bool "HackKit Core CPU Board" | 115 | bool "HackKit Core CPU Board" |
106 | help | 116 | help |
@@ -145,8 +155,7 @@ config SA1100_SSP | |||
145 | help | 155 | help |
146 | Say Y here to enable support for the generic PIO SSP driver. | 156 | Say Y here to enable support for the generic PIO SSP driver. |
147 | This isn't for audio support, but for attached sensors and | 157 | This isn't for audio support, but for attached sensors and |
148 | other devices, eg for BadgePAD 4 sensor support, or Jornada | 158 | other devices, eg for BadgePAD 4 sensor support. |
149 | 720 touchscreen support. | ||
150 | 159 | ||
151 | config H3600_SLEEVE | 160 | config H3600_SLEEVE |
152 | tristate "Compaq iPAQ Handheld sleeve support" | 161 | tristate "Compaq iPAQ Handheld sleeve support" |
diff --git a/arch/arm/mach-sa1100/Makefile b/arch/arm/mach-sa1100/Makefile index e27f15042a22..7a61e8d33ab7 100644 --- a/arch/arm/mach-sa1100/Makefile +++ b/arch/arm/mach-sa1100/Makefile | |||
@@ -31,6 +31,7 @@ obj-$(CONFIG_SA1100_HACKKIT) += hackkit.o | |||
31 | led-$(CONFIG_SA1100_HACKKIT) += leds-hackkit.o | 31 | led-$(CONFIG_SA1100_HACKKIT) += leds-hackkit.o |
32 | 32 | ||
33 | obj-$(CONFIG_SA1100_JORNADA720) += jornada720.o | 33 | obj-$(CONFIG_SA1100_JORNADA720) += jornada720.o |
34 | obj-$(CONFIG_SA1100_JORNADA720_SSP) += jornada720_ssp.o | ||
34 | 35 | ||
35 | obj-$(CONFIG_SA1100_LART) += lart.o | 36 | obj-$(CONFIG_SA1100_LART) += lart.o |
36 | led-$(CONFIG_SA1100_LART) += leds-lart.o | 37 | led-$(CONFIG_SA1100_LART) += leds-lart.o |
@@ -51,3 +52,4 @@ obj-$(CONFIG_LEDS) += $(led-y) | |||
51 | # Miscelaneous functions | 52 | # Miscelaneous functions |
52 | obj-$(CONFIG_PM) += pm.o sleep.o | 53 | obj-$(CONFIG_PM) += pm.o sleep.o |
53 | obj-$(CONFIG_SA1100_SSP) += ssp.o | 54 | obj-$(CONFIG_SA1100_SSP) += ssp.o |
55 | |||
diff --git a/arch/arm/mach-sa1100/jornada720_ssp.c b/arch/arm/mach-sa1100/jornada720_ssp.c new file mode 100644 index 000000000000..0a45e1ac8ad6 --- /dev/null +++ b/arch/arm/mach-sa1100/jornada720_ssp.c | |||
@@ -0,0 +1,201 @@ | |||
1 | /** | ||
2 | * arch/arm/mac-sa1100/jornada720_ssp.c | ||
3 | * | ||
4 | * Copyright (C) 2006/2007 Kristoffer Ericson <Kristoffer.Ericson@gmail.com> | ||
5 | * Copyright (C) 2006 Filip Zyzniewski <filip.zyzniewski@tefnet.pl> | ||
6 | * | ||
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 | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * SSP driver for the HP Jornada 710/720/728 | ||
12 | */ | ||
13 | |||
14 | #include <linux/delay.h> | ||
15 | #include <linux/errno.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/sched.h> | ||
21 | #include <linux/slab.h> | ||
22 | |||
23 | #include <asm/hardware.h> | ||
24 | #include <asm/hardware/ssp.h> | ||
25 | #include <asm/arch/jornada720.h> | ||
26 | |||
27 | static DEFINE_SPINLOCK(jornada_ssp_lock); | ||
28 | static unsigned long jornada_ssp_flags; | ||
29 | |||
30 | /** | ||
31 | * jornada_ssp_reverse - reverses input byte | ||
32 | * | ||
33 | * we need to reverse all data we recieve from the mcu due to its physical location | ||
34 | * returns : 01110111 -> 11101110 | ||
35 | */ | ||
36 | u8 inline jornada_ssp_reverse(u8 byte) | ||
37 | { | ||
38 | return | ||
39 | ((0x80 & byte) >> 7) | | ||
40 | ((0x40 & byte) >> 5) | | ||
41 | ((0x20 & byte) >> 3) | | ||
42 | ((0x10 & byte) >> 1) | | ||
43 | ((0x08 & byte) << 1) | | ||
44 | ((0x04 & byte) << 3) | | ||
45 | ((0x02 & byte) << 5) | | ||
46 | ((0x01 & byte) << 7); | ||
47 | }; | ||
48 | EXPORT_SYMBOL(jornada_ssp_reverse); | ||
49 | |||
50 | /** | ||
51 | * jornada_ssp_byte - waits for ready ssp bus and sends byte | ||
52 | * | ||
53 | * waits for fifo buffer to clear and then transmits, if it doesn't then we will | ||
54 | * timeout after <timeout> rounds. Needs mcu running before its called. | ||
55 | * | ||
56 | * returns : %mcu output on success | ||
57 | * : %-ETIMEOUT on timeout | ||
58 | */ | ||
59 | int jornada_ssp_byte(u8 byte) | ||
60 | { | ||
61 | int timeout = 400000; | ||
62 | u16 ret; | ||
63 | |||
64 | while ((GPLR & GPIO_GPIO10)) { | ||
65 | if (!--timeout) { | ||
66 | printk(KERN_WARNING "SSP: timeout while waiting for transmit\n"); | ||
67 | return -ETIMEDOUT; | ||
68 | } | ||
69 | cpu_relax(); | ||
70 | } | ||
71 | |||
72 | ret = jornada_ssp_reverse(byte) << 8; | ||
73 | |||
74 | ssp_write_word(ret); | ||
75 | ssp_read_word(&ret); | ||
76 | |||
77 | return jornada_ssp_reverse(ret); | ||
78 | }; | ||
79 | EXPORT_SYMBOL(jornada_ssp_byte); | ||
80 | |||
81 | /** | ||
82 | * jornada_ssp_inout - decide if input is command or trading byte | ||
83 | * | ||
84 | * returns : (jornada_ssp_byte(byte)) on success | ||
85 | * : %-ETIMEOUT on timeout failure | ||
86 | */ | ||
87 | int jornada_ssp_inout(u8 byte) | ||
88 | { | ||
89 | int ret, i; | ||
90 | |||
91 | /* true means command byte */ | ||
92 | if (byte != TXDUMMY) { | ||
93 | ret = jornada_ssp_byte(byte); | ||
94 | /* Proper return to commands is TxDummy */ | ||
95 | if (ret != TXDUMMY) { | ||
96 | for (i = 0; i < 256; i++)/* flushing bus */ | ||
97 | if (jornada_ssp_byte(TXDUMMY) == -1) | ||
98 | break; | ||
99 | return -ETIMEDOUT; | ||
100 | } | ||
101 | } else /* Exchange TxDummy for data */ | ||
102 | ret = jornada_ssp_byte(TXDUMMY); | ||
103 | |||
104 | return ret; | ||
105 | }; | ||
106 | EXPORT_SYMBOL(jornada_ssp_inout); | ||
107 | |||
108 | /** | ||
109 | * jornada_ssp_start - enable mcu | ||
110 | * | ||
111 | */ | ||
112 | int jornada_ssp_start() | ||
113 | { | ||
114 | spin_lock_irqsave(&jornada_ssp_lock, jornada_ssp_flags); | ||
115 | GPCR = GPIO_GPIO25; | ||
116 | udelay(50); | ||
117 | return 0; | ||
118 | }; | ||
119 | EXPORT_SYMBOL(jornada_ssp_start); | ||
120 | |||
121 | /** | ||
122 | * jornada_ssp_end - disable mcu and turn off lock | ||
123 | * | ||
124 | */ | ||
125 | int jornada_ssp_end() | ||
126 | { | ||
127 | GPSR = GPIO_GPIO25; | ||
128 | spin_unlock_irqrestore(&jornada_ssp_lock, jornada_ssp_flags); | ||
129 | return 0; | ||
130 | }; | ||
131 | EXPORT_SYMBOL(jornada_ssp_end); | ||
132 | |||
133 | static int __init jornada_ssp_probe(struct platform_device *dev) | ||
134 | { | ||
135 | int ret; | ||
136 | |||
137 | GPSR = GPIO_GPIO25; | ||
138 | |||
139 | ret = ssp_init(); | ||
140 | |||
141 | /* worked fine, lets not bother with anything else */ | ||
142 | if (!ret) { | ||
143 | printk(KERN_INFO "SSP: device initialized with irq\n"); | ||
144 | return ret; | ||
145 | } | ||
146 | |||
147 | printk(KERN_WARNING "SSP: initialization failed, trying non-irq solution \n"); | ||
148 | |||
149 | /* init of Serial 4 port */ | ||
150 | Ser4MCCR0 = 0; | ||
151 | Ser4SSCR0 = 0x0387; | ||
152 | Ser4SSCR1 = 0x18; | ||
153 | |||
154 | /* clear out any left over data */ | ||
155 | ssp_flush(); | ||
156 | |||
157 | /* enable MCU */ | ||
158 | jornada_ssp_start(); | ||
159 | |||
160 | /* see if return value makes sense */ | ||
161 | ret = jornada_ssp_inout(GETBRIGHTNESS); | ||
162 | |||
163 | /* seems like it worked, just feed it with TxDummy to get rid of data */ | ||
164 | if (ret == TxDummy) | ||
165 | jornada_ssp_inout(TXDUMMY); | ||
166 | |||
167 | jornada_ssp_end(); | ||
168 | |||
169 | /* failed, lets just kill everything */ | ||
170 | if (ret == -ETIMEDOUT) { | ||
171 | printk(KERN_WARNING "SSP: attempts failed, bailing\n"); | ||
172 | ssp_exit(); | ||
173 | return -ENODEV; | ||
174 | } | ||
175 | |||
176 | /* all fine */ | ||
177 | printk(KERN_INFO "SSP: device initialized\n"); | ||
178 | return 0; | ||
179 | }; | ||
180 | |||
181 | static int jornada_ssp_remove(struct platform_device *dev) | ||
182 | { | ||
183 | /* Note that this doesnt actually remove the driver, since theres nothing to remove | ||
184 | * It just makes sure everything is turned off */ | ||
185 | GPSR = GPIO_GPIO25; | ||
186 | ssp_exit(); | ||
187 | return 0; | ||
188 | }; | ||
189 | |||
190 | struct platform_driver jornadassp_driver = { | ||
191 | .probe = jornada_ssp_probe, | ||
192 | .remove = jornada_ssp_remove, | ||
193 | .driver = { | ||
194 | .name = "jornada_ssp", | ||
195 | }, | ||
196 | }; | ||
197 | |||
198 | static int __init jornada_ssp_init(void) | ||
199 | { | ||
200 | return platform_driver_register(&jornadassp_driver); | ||
201 | } | ||
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c index 3a0a1ee2542d..9f1ed1509301 100644 --- a/arch/arm/mach-sa1100/neponset.c +++ b/arch/arm/mach-sa1100/neponset.c | |||
@@ -292,6 +292,8 @@ static struct platform_device *devices[] __initdata = { | |||
292 | &smc91x_device, | 292 | &smc91x_device, |
293 | }; | 293 | }; |
294 | 294 | ||
295 | extern void sa1110_mb_disable(void); | ||
296 | |||
295 | static int __init neponset_init(void) | 297 | static int __init neponset_init(void) |
296 | { | 298 | { |
297 | platform_driver_register(&neponset_device_driver); | 299 | platform_driver_register(&neponset_device_driver); |
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index e7904bc92c73..12161ae445da 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig | |||
@@ -345,13 +345,14 @@ config CPU_XSC3 | |||
345 | # ARMv6 | 345 | # ARMv6 |
346 | config CPU_V6 | 346 | config CPU_V6 |
347 | bool "Support ARM V6 processor" | 347 | bool "Support ARM V6 processor" |
348 | depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP2 | 348 | depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP2 || ARCH_MX3 |
349 | default y if ARCH_MX3 | ||
349 | select CPU_32v6 | 350 | select CPU_32v6 |
350 | select CPU_ABRT_EV6 | 351 | select CPU_ABRT_EV6 |
351 | select CPU_CACHE_V6 | 352 | select CPU_CACHE_V6 |
352 | select CPU_CACHE_VIPT | 353 | select CPU_CACHE_VIPT |
353 | select CPU_CP15_MMU | 354 | select CPU_CP15_MMU |
354 | select CPU_HAS_ASID | 355 | select CPU_HAS_ASID if MMU |
355 | select CPU_COPY_V6 if MMU | 356 | select CPU_COPY_V6 if MMU |
356 | select CPU_TLB_V6 if MMU | 357 | select CPU_TLB_V6 if MMU |
357 | 358 | ||
@@ -359,7 +360,7 @@ config CPU_V6 | |||
359 | config CPU_32v6K | 360 | config CPU_32v6K |
360 | bool "Support ARM V6K processor extensions" if !SMP | 361 | bool "Support ARM V6K processor extensions" if !SMP |
361 | depends on CPU_V6 | 362 | depends on CPU_V6 |
362 | default y if SMP | 363 | default y if SMP && !ARCH_MX3 |
363 | help | 364 | help |
364 | Say Y here if your ARMv6 processor supports the 'K' extension. | 365 | Say Y here if your ARMv6 processor supports the 'K' extension. |
365 | This enables the kernel to use some instructions not present | 366 | This enables the kernel to use some instructions not present |
@@ -377,7 +378,7 @@ config CPU_V7 | |||
377 | select CPU_CACHE_V7 | 378 | select CPU_CACHE_V7 |
378 | select CPU_CACHE_VIPT | 379 | select CPU_CACHE_VIPT |
379 | select CPU_CP15_MMU | 380 | select CPU_CP15_MMU |
380 | select CPU_HAS_ASID | 381 | select CPU_HAS_ASID if MMU |
381 | select CPU_COPY_V6 if MMU | 382 | select CPU_COPY_V6 if MMU |
382 | select CPU_TLB_V7 if MMU | 383 | select CPU_TLB_V7 if MMU |
383 | 384 | ||
@@ -405,6 +406,7 @@ config CPU_32v5 | |||
405 | 406 | ||
406 | config CPU_32v6 | 407 | config CPU_32v6 |
407 | bool | 408 | bool |
409 | select TLS_REG_EMUL if !CPU_32v6K && !MMU | ||
408 | 410 | ||
409 | config CPU_32v7 | 411 | config CPU_32v7 |
410 | bool | 412 | bool |
@@ -598,7 +600,7 @@ config CPU_DCACHE_SIZE | |||
598 | 600 | ||
599 | config CPU_DCACHE_WRITETHROUGH | 601 | config CPU_DCACHE_WRITETHROUGH |
600 | bool "Force write through D-cache" | 602 | bool "Force write through D-cache" |
601 | depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_V6) && !CPU_DCACHE_DISABLE | 603 | depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020) && !CPU_DCACHE_DISABLE |
602 | default y if CPU_ARM925T | 604 | default y if CPU_ARM925T |
603 | help | 605 | help |
604 | Say Y here to use the data cache in writethrough mode. Unless you | 606 | Say Y here to use the data cache in writethrough mode. Unless you |
@@ -611,12 +613,6 @@ config CPU_CACHE_ROUND_ROBIN | |||
611 | Say Y here to use the predictable round-robin cache replacement | 613 | Say Y here to use the predictable round-robin cache replacement |
612 | policy. Unless you specifically require this or are unsure, say N. | 614 | policy. Unless you specifically require this or are unsure, say N. |
613 | 615 | ||
614 | config CPU_L2CACHE_DISABLE | ||
615 | bool "Disable level 2 cache" | ||
616 | depends on CPU_V7 | ||
617 | help | ||
618 | Say Y here to disable the level 2 cache. If unsure, say N. | ||
619 | |||
620 | config CPU_BPREDICT_DISABLE | 616 | config CPU_BPREDICT_DISABLE |
621 | bool "Disable branch prediction" | 617 | bool "Disable branch prediction" |
622 | depends on CPU_ARM1020 || CPU_V6 || CPU_XSC3 || CPU_V7 | 618 | depends on CPU_ARM1020 || CPU_V6 || CPU_XSC3 || CPU_V7 |
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index 08a36f1b35d2..b4e9b734e0bd 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c | |||
@@ -17,6 +17,7 @@ | |||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
18 | */ | 18 | */ |
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/spinlock.h> | ||
20 | 21 | ||
21 | #include <asm/cacheflush.h> | 22 | #include <asm/cacheflush.h> |
22 | #include <asm/io.h> | 23 | #include <asm/io.h> |
@@ -25,14 +26,19 @@ | |||
25 | #define CACHE_LINE_SIZE 32 | 26 | #define CACHE_LINE_SIZE 32 |
26 | 27 | ||
27 | static void __iomem *l2x0_base; | 28 | static void __iomem *l2x0_base; |
29 | static DEFINE_SPINLOCK(l2x0_lock); | ||
28 | 30 | ||
29 | static inline void sync_writel(unsigned long val, unsigned long reg, | 31 | static inline void sync_writel(unsigned long val, unsigned long reg, |
30 | unsigned long complete_mask) | 32 | unsigned long complete_mask) |
31 | { | 33 | { |
34 | unsigned long flags; | ||
35 | |||
36 | spin_lock_irqsave(&l2x0_lock, flags); | ||
32 | writel(val, l2x0_base + reg); | 37 | writel(val, l2x0_base + reg); |
33 | /* wait for the operation to complete */ | 38 | /* wait for the operation to complete */ |
34 | while (readl(l2x0_base + reg) & complete_mask) | 39 | while (readl(l2x0_base + reg) & complete_mask) |
35 | ; | 40 | ; |
41 | spin_unlock_irqrestore(&l2x0_lock, flags); | ||
36 | } | 42 | } |
37 | 43 | ||
38 | static inline void cache_sync(void) | 44 | static inline void cache_sync(void) |
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 3b5e47dc0c97..e5d61ee3d4a1 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c | |||
@@ -114,6 +114,10 @@ static void __init early_cachepolicy(char **p) | |||
114 | } | 114 | } |
115 | if (i == ARRAY_SIZE(cache_policies)) | 115 | if (i == ARRAY_SIZE(cache_policies)) |
116 | printk(KERN_ERR "ERROR: unknown or unsupported cache policy\n"); | 116 | printk(KERN_ERR "ERROR: unknown or unsupported cache policy\n"); |
117 | if (cpu_architecture() >= CPU_ARCH_ARMv6) { | ||
118 | printk(KERN_WARNING "Only cachepolicy=writeback supported on ARMv6 and later\n"); | ||
119 | cachepolicy = CPOLICY_WRITEBACK; | ||
120 | } | ||
117 | flush_cache_all(); | 121 | flush_cache_all(); |
118 | set_cr(cr_alignment); | 122 | set_cr(cr_alignment); |
119 | } | 123 | } |
@@ -252,13 +256,15 @@ static void __init build_mem_type_table(void) | |||
252 | int cpu_arch = cpu_architecture(); | 256 | int cpu_arch = cpu_architecture(); |
253 | int i; | 257 | int i; |
254 | 258 | ||
259 | if (cpu_arch < CPU_ARCH_ARMv6) { | ||
255 | #if defined(CONFIG_CPU_DCACHE_DISABLE) | 260 | #if defined(CONFIG_CPU_DCACHE_DISABLE) |
256 | if (cachepolicy > CPOLICY_BUFFERED) | 261 | if (cachepolicy > CPOLICY_BUFFERED) |
257 | cachepolicy = CPOLICY_BUFFERED; | 262 | cachepolicy = CPOLICY_BUFFERED; |
258 | #elif defined(CONFIG_CPU_DCACHE_WRITETHROUGH) | 263 | #elif defined(CONFIG_CPU_DCACHE_WRITETHROUGH) |
259 | if (cachepolicy > CPOLICY_WRITETHROUGH) | 264 | if (cachepolicy > CPOLICY_WRITETHROUGH) |
260 | cachepolicy = CPOLICY_WRITETHROUGH; | 265 | cachepolicy = CPOLICY_WRITETHROUGH; |
261 | #endif | 266 | #endif |
267 | } | ||
262 | if (cpu_arch < CPU_ARCH_ARMv5) { | 268 | if (cpu_arch < CPU_ARCH_ARMv5) { |
263 | if (cachepolicy >= CPOLICY_WRITEALLOC) | 269 | if (cachepolicy >= CPOLICY_WRITEALLOC) |
264 | cachepolicy = CPOLICY_WRITEBACK; | 270 | cachepolicy = CPOLICY_WRITEBACK; |
diff --git a/arch/arm/mm/proc-syms.c b/arch/arm/mm/proc-syms.c index 9f396b4fa0b7..2b5ba396e3a6 100644 --- a/arch/arm/mm/proc-syms.c +++ b/arch/arm/mm/proc-syms.c | |||
@@ -31,12 +31,14 @@ EXPORT_SYMBOL(__cpuc_coherent_kern_range); | |||
31 | EXPORT_SYMBOL(cpu_cache); | 31 | EXPORT_SYMBOL(cpu_cache); |
32 | #endif | 32 | #endif |
33 | 33 | ||
34 | #ifdef CONFIG_MMU | ||
34 | #ifndef MULTI_USER | 35 | #ifndef MULTI_USER |
35 | EXPORT_SYMBOL(__cpu_clear_user_page); | 36 | EXPORT_SYMBOL(__cpu_clear_user_page); |
36 | EXPORT_SYMBOL(__cpu_copy_user_page); | 37 | EXPORT_SYMBOL(__cpu_copy_user_page); |
37 | #else | 38 | #else |
38 | EXPORT_SYMBOL(cpu_user); | 39 | EXPORT_SYMBOL(cpu_user); |
39 | #endif | 40 | #endif |
41 | #endif | ||
40 | 42 | ||
41 | /* | 43 | /* |
42 | * No module should need to touch the TLB (and currently | 44 | * No module should need to touch the TLB (and currently |
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 718f4782ee8b..e0acc5ae6f6f 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S | |||
@@ -77,6 +77,7 @@ ENTRY(cpu_v7_dcache_clean_area) | |||
77 | * - we are not using split page tables | 77 | * - we are not using split page tables |
78 | */ | 78 | */ |
79 | ENTRY(cpu_v7_switch_mm) | 79 | ENTRY(cpu_v7_switch_mm) |
80 | #ifdef CONFIG_MMU | ||
80 | mov r2, #0 | 81 | mov r2, #0 |
81 | ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id | 82 | ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id |
82 | orr r0, r0, #TTB_RGN_OC_WB @ mark PTWs outer cacheable, WB | 83 | orr r0, r0, #TTB_RGN_OC_WB @ mark PTWs outer cacheable, WB |
@@ -86,6 +87,7 @@ ENTRY(cpu_v7_switch_mm) | |||
86 | isb | 87 | isb |
87 | mcr p15, 0, r1, c13, c0, 1 @ set context ID | 88 | mcr p15, 0, r1, c13, c0, 1 @ set context ID |
88 | isb | 89 | isb |
90 | #endif | ||
89 | mov pc, lr | 91 | mov pc, lr |
90 | 92 | ||
91 | /* | 93 | /* |
@@ -109,6 +111,7 @@ ENTRY(cpu_v7_switch_mm) | |||
109 | * 1111 0 1 1 r/w r/w | 111 | * 1111 0 1 1 r/w r/w |
110 | */ | 112 | */ |
111 | ENTRY(cpu_v7_set_pte_ext) | 113 | ENTRY(cpu_v7_set_pte_ext) |
114 | #ifdef CONFIG_MMU | ||
112 | str r1, [r0], #-2048 @ linux version | 115 | str r1, [r0], #-2048 @ linux version |
113 | 116 | ||
114 | bic r3, r1, #0x000003f0 | 117 | bic r3, r1, #0x000003f0 |
@@ -136,6 +139,7 @@ ENTRY(cpu_v7_set_pte_ext) | |||
136 | 139 | ||
137 | str r3, [r0] | 140 | str r3, [r0] |
138 | mcr p15, 0, r0, c7, c10, 1 @ flush_pte | 141 | mcr p15, 0, r0, c7, c10, 1 @ flush_pte |
142 | #endif | ||
139 | mov pc, lr | 143 | mov pc, lr |
140 | 144 | ||
141 | cpu_v7_name: | 145 | cpu_v7_name: |
@@ -169,6 +173,7 @@ __v7_setup: | |||
169 | mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate | 173 | mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate |
170 | #endif | 174 | #endif |
171 | dsb | 175 | dsb |
176 | #ifdef CONFIG_MMU | ||
172 | mcr p15, 0, r10, c8, c7, 0 @ invalidate I + D TLBs | 177 | mcr p15, 0, r10, c8, c7, 0 @ invalidate I + D TLBs |
173 | mcr p15, 0, r10, c2, c0, 2 @ TTB control register | 178 | mcr p15, 0, r10, c2, c0, 2 @ TTB control register |
174 | orr r4, r4, #TTB_RGN_OC_WB @ mark PTWs outer cacheable, WB | 179 | orr r4, r4, #TTB_RGN_OC_WB @ mark PTWs outer cacheable, WB |
@@ -176,21 +181,12 @@ __v7_setup: | |||
176 | mcr p15, 0, r4, c2, c0, 1 @ load TTB1 | 181 | mcr p15, 0, r4, c2, c0, 1 @ load TTB1 |
177 | mov r10, #0x1f @ domains 0, 1 = manager | 182 | mov r10, #0x1f @ domains 0, 1 = manager |
178 | mcr p15, 0, r10, c3, c0, 0 @ load domain access register | 183 | mcr p15, 0, r10, c3, c0, 0 @ load domain access register |
179 | #ifndef CONFIG_CPU_L2CACHE_DISABLE | ||
180 | @ L2 cache configuration in the L2 aux control register | ||
181 | mrc p15, 1, r10, c9, c0, 2 | ||
182 | bic r10, r10, #(1 << 16) @ L2 outer cache | ||
183 | mcr p15, 1, r10, c9, c0, 2 | ||
184 | @ L2 cache is enabled in the aux control register | ||
185 | mrc p15, 0, r10, c1, c0, 1 | ||
186 | orr r10, r10, #2 | ||
187 | mcr p15, 0, r10, c1, c0, 1 | ||
188 | #endif | 184 | #endif |
189 | mrc p15, 0, r0, c1, c0, 0 @ read control register | 185 | adr r5, v7_crval |
190 | ldr r10, cr1_clear @ get mask for bits to clear | 186 | ldmia r5, {r5, r6} |
191 | bic r0, r0, r10 @ clear bits them | 187 | mrc p15, 0, r0, c1, c0, 0 @ read control register |
192 | ldr r10, cr1_set @ get mask for bits to set | 188 | bic r0, r0, r5 @ clear bits them |
193 | orr r0, r0, r10 @ set them | 189 | orr r0, r0, r6 @ set them |
194 | mov pc, lr @ return to head.S:__ret | 190 | mov pc, lr @ return to head.S:__ret |
195 | 191 | ||
196 | /* | 192 | /* |
@@ -199,12 +195,9 @@ __v7_setup: | |||
199 | * rrrr rrrx xxx0 0101 xxxx xxxx x111 xxxx < forced | 195 | * rrrr rrrx xxx0 0101 xxxx xxxx x111 xxxx < forced |
200 | * 0 110 0011 1.00 .111 1101 < we want | 196 | * 0 110 0011 1.00 .111 1101 < we want |
201 | */ | 197 | */ |
202 | .type cr1_clear, #object | 198 | .type v7_crval, #object |
203 | .type cr1_set, #object | 199 | v7_crval: |
204 | cr1_clear: | 200 | crval clear=0x0120c302, mmuset=0x00c0387d, ucset=0x00c0187c |
205 | .word 0x0120c302 | ||
206 | cr1_set: | ||
207 | .word 0x00c0387d | ||
208 | 201 | ||
209 | __v7_setup_stack: | 202 | __v7_setup_stack: |
210 | .space 4 * 11 @ 11 registers | 203 | .space 4 * 11 @ 11 registers |
diff --git a/arch/arm/plat-iop/time.c b/arch/arm/plat-iop/time.c index 100d57ad98ed..ba3d21d8fba3 100644 --- a/arch/arm/plat-iop/time.c +++ b/arch/arm/plat-iop/time.c | |||
@@ -78,6 +78,13 @@ static struct irqaction iop_timer_irq = { | |||
78 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, | 78 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, |
79 | }; | 79 | }; |
80 | 80 | ||
81 | static unsigned long iop_tick_rate; | ||
82 | unsigned long get_iop_tick_rate(void) | ||
83 | { | ||
84 | return iop_tick_rate; | ||
85 | } | ||
86 | EXPORT_SYMBOL(get_iop_tick_rate); | ||
87 | |||
81 | void __init iop_init_time(unsigned long tick_rate) | 88 | void __init iop_init_time(unsigned long tick_rate) |
82 | { | 89 | { |
83 | u32 timer_ctl; | 90 | u32 timer_ctl; |
@@ -85,6 +92,7 @@ void __init iop_init_time(unsigned long tick_rate) | |||
85 | ticks_per_jiffy = (tick_rate + HZ/2) / HZ; | 92 | ticks_per_jiffy = (tick_rate + HZ/2) / HZ; |
86 | ticks_per_usec = tick_rate / 1000000; | 93 | ticks_per_usec = tick_rate / 1000000; |
87 | next_jiffy_time = 0xffffffff; | 94 | next_jiffy_time = 0xffffffff; |
95 | iop_tick_rate = tick_rate; | ||
88 | 96 | ||
89 | timer_ctl = IOP_TMR_EN | IOP_TMR_PRIVILEGED | | 97 | timer_ctl = IOP_TMR_EN | IOP_TMR_PRIVILEGED | |
90 | IOP_TMR_RELOAD | IOP_TMR_RATIO_1_1; | 98 | IOP_TMR_RELOAD | IOP_TMR_RATIO_1_1; |
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig new file mode 100644 index 000000000000..03a65c0dfb60 --- /dev/null +++ b/arch/arm/plat-mxc/Kconfig | |||
@@ -0,0 +1,20 @@ | |||
1 | if ARCH_MXC | ||
2 | |||
3 | menu "Freescale MXC Implementations" | ||
4 | |||
5 | choice | ||
6 | prompt "MXC/iMX System Type" | ||
7 | default 0 | ||
8 | |||
9 | config ARCH_MX3 | ||
10 | bool "MX3-based" | ||
11 | help | ||
12 | This enables support for systems based on the Freescale i.MX3 family | ||
13 | |||
14 | endchoice | ||
15 | |||
16 | source "arch/arm/mach-mx3/Kconfig" | ||
17 | |||
18 | endmenu | ||
19 | |||
20 | endif | ||
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile new file mode 100644 index 000000000000..66ad9c2b6d64 --- /dev/null +++ b/arch/arm/plat-mxc/Makefile | |||
@@ -0,0 +1,10 @@ | |||
1 | # | ||
2 | # Makefile for the linux kernel. | ||
3 | # | ||
4 | |||
5 | # Common support | ||
6 | obj-y := irq.o | ||
7 | |||
8 | obj-m := | ||
9 | obj-n := | ||
10 | obj- := | ||
diff --git a/arch/arm/plat-mxc/irq.c b/arch/arm/plat-mxc/irq.c new file mode 100644 index 000000000000..87d253bc3d3c --- /dev/null +++ b/arch/arm/plat-mxc/irq.c | |||
@@ -0,0 +1,83 @@ | |||
1 | /* | ||
2 | * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | */ | ||
4 | |||
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 version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/module.h> | ||
12 | #include <linux/moduleparam.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/device.h> | ||
15 | #include <linux/errno.h> | ||
16 | #include <asm/hardware.h> | ||
17 | #include <asm/io.h> | ||
18 | #include <asm/irq.h> | ||
19 | #include <asm/mach/irq.h> | ||
20 | #include <asm/arch/common.h> | ||
21 | |||
22 | /*! | ||
23 | * Disable interrupt number "irq" in the AVIC | ||
24 | * | ||
25 | * @param irq interrupt source number | ||
26 | */ | ||
27 | static void mxc_mask_irq(unsigned int irq) | ||
28 | { | ||
29 | __raw_writel(irq, AVIC_INTDISNUM); | ||
30 | } | ||
31 | |||
32 | /*! | ||
33 | * Enable interrupt number "irq" in the AVIC | ||
34 | * | ||
35 | * @param irq interrupt source number | ||
36 | */ | ||
37 | static void mxc_unmask_irq(unsigned int irq) | ||
38 | { | ||
39 | __raw_writel(irq, AVIC_INTENNUM); | ||
40 | } | ||
41 | |||
42 | static struct irq_chip mxc_avic_chip = { | ||
43 | .mask_ack = mxc_mask_irq, | ||
44 | .mask = mxc_mask_irq, | ||
45 | .unmask = mxc_unmask_irq, | ||
46 | }; | ||
47 | |||
48 | /*! | ||
49 | * This function initializes the AVIC hardware and disables all the | ||
50 | * interrupts. It registers the interrupt enable and disable functions | ||
51 | * to the kernel for each interrupt source. | ||
52 | */ | ||
53 | void __init mxc_init_irq(void) | ||
54 | { | ||
55 | int i; | ||
56 | u32 reg; | ||
57 | |||
58 | /* put the AVIC into the reset value with | ||
59 | * all interrupts disabled | ||
60 | */ | ||
61 | __raw_writel(0, AVIC_INTCNTL); | ||
62 | __raw_writel(0x1f, AVIC_NIMASK); | ||
63 | |||
64 | /* disable all interrupts */ | ||
65 | __raw_writel(0, AVIC_INTENABLEH); | ||
66 | __raw_writel(0, AVIC_INTENABLEL); | ||
67 | |||
68 | /* all IRQ no FIQ */ | ||
69 | __raw_writel(0, AVIC_INTTYPEH); | ||
70 | __raw_writel(0, AVIC_INTTYPEL); | ||
71 | for (i = 0; i < MXC_MAX_INT_LINES; i++) { | ||
72 | set_irq_chip(i, &mxc_avic_chip); | ||
73 | set_irq_handler(i, handle_level_irq); | ||
74 | set_irq_flags(i, IRQF_VALID); | ||
75 | } | ||
76 | |||
77 | /* Set WDOG2's interrupt the highest priority level (bit 28-31) */ | ||
78 | reg = __raw_readl(AVIC_NIPRIORITY6); | ||
79 | reg |= (0xF << 28); | ||
80 | __raw_writel(reg, AVIC_NIPRIORITY6); | ||
81 | |||
82 | printk(KERN_INFO "MXC IRQ initialized\n"); | ||
83 | } | ||
diff --git a/arch/arm/plat-s3c/Kconfig b/arch/arm/plat-s3c/Kconfig new file mode 100644 index 000000000000..31656c33e05e --- /dev/null +++ b/arch/arm/plat-s3c/Kconfig | |||
@@ -0,0 +1,104 @@ | |||
1 | # arch/arm/plat-s3c/Kconfig | ||
2 | # | ||
3 | # Copyright 2007 Simtec Electronics | ||
4 | # | ||
5 | # Licensed under GPLv2 | ||
6 | |||
7 | config PLAT_S3C | ||
8 | bool | ||
9 | depends on ARCH_S3C2410 | ||
10 | default y if ARCH_S3C2410 | ||
11 | select NO_IOPORT | ||
12 | help | ||
13 | Base platform code for any Samsung S3C device | ||
14 | |||
15 | # low-level serial option nodes | ||
16 | |||
17 | config CPU_LLSERIAL_S3C2410_ONLY | ||
18 | bool | ||
19 | depends on ARCH_S3C2410 | ||
20 | default y if CPU_LLSERIAL_S3C2410 && !CPU_LLSERIAL_S3C2440 | ||
21 | |||
22 | config CPU_LLSERIAL_S3C2440_ONLY | ||
23 | bool | ||
24 | depends on ARCH_S3C2410 | ||
25 | default y if CPU_LLSERIAL_S3C2440 && !CPU_LLSERIAL_S3C2410 | ||
26 | |||
27 | config CPU_LLSERIAL_S3C2410 | ||
28 | bool | ||
29 | depends on ARCH_S3C2410 | ||
30 | help | ||
31 | Selected if there is an S3C2410 (or register compatible) serial | ||
32 | low-level implementation needed | ||
33 | |||
34 | config CPU_LLSERIAL_S3C2440 | ||
35 | bool | ||
36 | depends on ARCH_S3C2410 | ||
37 | help | ||
38 | Selected if there is an S3C2440 (or register compatible) serial | ||
39 | low-level implementation needed | ||
40 | |||
41 | # boot configurations | ||
42 | |||
43 | comment "Boot options" | ||
44 | |||
45 | config S3C_BOOT_WATCHDOG | ||
46 | bool "S3C Initialisation watchdog" | ||
47 | depends on PLAT_S3C && S3C2410_WATCHDOG | ||
48 | help | ||
49 | Say y to enable the watchdog during the kernel decompression | ||
50 | stage. If the kernel fails to uncompress, then the watchdog | ||
51 | will trigger a reset and the system should restart. | ||
52 | |||
53 | config S3C_BOOT_ERROR_RESET | ||
54 | bool "S3C Reboot on decompression error" | ||
55 | depends on PLAT_S3C | ||
56 | help | ||
57 | Say y here to use the watchdog to reset the system if the | ||
58 | kernel decompressor detects an error during decompression. | ||
59 | |||
60 | comment "Power management" | ||
61 | |||
62 | config S3C2410_PM_DEBUG | ||
63 | bool "S3C2410 PM Suspend debug" | ||
64 | depends on PLAT_S3C && PM | ||
65 | help | ||
66 | Say Y here if you want verbose debugging from the PM Suspend and | ||
67 | Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt> | ||
68 | for more information. | ||
69 | |||
70 | config S3C2410_PM_CHECK | ||
71 | bool "S3C2410 PM Suspend Memory CRC" | ||
72 | depends on PLAT_S3C && PM && CRC32 | ||
73 | help | ||
74 | Enable the PM code's memory area checksum over sleep. This option | ||
75 | will generate CRCs of all blocks of memory, and store them before | ||
76 | going to sleep. The blocks are then checked on resume for any | ||
77 | errors. | ||
78 | |||
79 | Note, this can take several seconds depending on memory size | ||
80 | and CPU speed. | ||
81 | |||
82 | See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt> | ||
83 | |||
84 | config S3C2410_PM_CHECK_CHUNKSIZE | ||
85 | int "S3C2410 PM Suspend CRC Chunksize (KiB)" | ||
86 | depends on PLAT_S3C && PM && S3C2410_PM_CHECK | ||
87 | default 64 | ||
88 | help | ||
89 | Set the chunksize in Kilobytes of the CRC for checking memory | ||
90 | corruption over suspend and resume. A smaller value will mean that | ||
91 | the CRC data block will take more memory, but wil identify any | ||
92 | faults with better precision. | ||
93 | |||
94 | See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt> | ||
95 | |||
96 | config S3C_LOWLEVEL_UART_PORT | ||
97 | int "S3C UART to use for low-level messages" | ||
98 | depends on PLAT_S3C | ||
99 | default 0 | ||
100 | help | ||
101 | Choice of which UART port to use for the low-level messages, | ||
102 | such as the `Uncompressing...` at start time. The value of | ||
103 | this configuration should be between zero and two. The port | ||
104 | must have been initialised by the boot-loader before use. | ||
diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig index b972f36d547c..b66fb3c4e228 100644 --- a/arch/arm/plat-s3c24xx/Kconfig +++ b/arch/arm/plat-s3c24xx/Kconfig | |||
@@ -10,7 +10,7 @@ config PLAT_S3C24XX | |||
10 | default y if ARCH_S3C2410 | 10 | default y if ARCH_S3C2410 |
11 | select NO_IOPORT | 11 | select NO_IOPORT |
12 | help | 12 | help |
13 | Base platform code for any Samsung S3C device | 13 | Base platform code for any Samsung S3C24XX device |
14 | 14 | ||
15 | if PLAT_S3C24XX | 15 | if PLAT_S3C24XX |
16 | 16 | ||
@@ -26,64 +26,6 @@ config PM_SIMTEC | |||
26 | Common power management code for systems that are | 26 | Common power management code for systems that are |
27 | compatible with the Simtec style of power management | 27 | compatible with the Simtec style of power management |
28 | 28 | ||
29 | config S3C2410_BOOT_WATCHDOG | ||
30 | bool "S3C2410 Initialisation watchdog" | ||
31 | depends on ARCH_S3C2410 && S3C2410_WATCHDOG | ||
32 | help | ||
33 | Say y to enable the watchdog during the kernel decompression | ||
34 | stage. If the kernel fails to uncompress, then the watchdog | ||
35 | will trigger a reset and the system should restart. | ||
36 | |||
37 | config S3C2410_BOOT_ERROR_RESET | ||
38 | bool "S3C2410 Reboot on decompression error" | ||
39 | depends on ARCH_S3C2410 | ||
40 | help | ||
41 | Say y here to use the watchdog to reset the system if the | ||
42 | kernel decompressor detects an error during decompression. | ||
43 | |||
44 | config S3C2410_PM_DEBUG | ||
45 | bool "S3C2410 PM Suspend debug" | ||
46 | depends on ARCH_S3C2410 && PM | ||
47 | help | ||
48 | Say Y here if you want verbose debugging from the PM Suspend and | ||
49 | Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt> | ||
50 | for more information. | ||
51 | |||
52 | config S3C2410_PM_CHECK | ||
53 | bool "S3C2410 PM Suspend Memory CRC" | ||
54 | depends on ARCH_S3C2410 && PM && CRC32 | ||
55 | help | ||
56 | Enable the PM code's memory area checksum over sleep. This option | ||
57 | will generate CRCs of all blocks of memory, and store them before | ||
58 | going to sleep. The blocks are then checked on resume for any | ||
59 | errors. | ||
60 | |||
61 | Note, this can take several seconds depending on memory size | ||
62 | and CPU speed. | ||
63 | |||
64 | See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt> | ||
65 | |||
66 | config S3C2410_PM_CHECK_CHUNKSIZE | ||
67 | int "S3C2410 PM Suspend CRC Chunksize (KiB)" | ||
68 | depends on ARCH_S3C2410 && PM && S3C2410_PM_CHECK | ||
69 | default 64 | ||
70 | help | ||
71 | Set the chunksize in Kilobytes of the CRC for checking memory | ||
72 | corruption over suspend and resume. A smaller value will mean that | ||
73 | the CRC data block will take more memory, but wil identify any | ||
74 | faults with better precision. | ||
75 | |||
76 | See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt> | ||
77 | |||
78 | config S3C2410_LOWLEVEL_UART_PORT | ||
79 | int "S3C2410 UART to use for low-level messages" | ||
80 | default 0 | ||
81 | help | ||
82 | Choice of which UART port to use for the low-level messages, | ||
83 | such as the `Uncompressing...` at start time. The value of | ||
84 | this configuration should be between zero and two. The port | ||
85 | must have been initialised by the boot-loader before use. | ||
86 | |||
87 | config S3C2410_DMA | 29 | config S3C2410_DMA |
88 | bool "S3C2410 DMA support" | 30 | bool "S3C2410 DMA support" |
89 | depends on ARCH_S3C2410 | 31 | depends on ARCH_S3C2410 |
diff --git a/arch/arm/plat-s3c24xx/common-smdk.c b/arch/arm/plat-s3c24xx/common-smdk.c index 7ed19b23ce56..398c7ac25296 100644 --- a/arch/arm/plat-s3c24xx/common-smdk.c +++ b/arch/arm/plat-s3c24xx/common-smdk.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #include <asm/arch/regs-gpio.h> | 38 | #include <asm/arch/regs-gpio.h> |
39 | #include <asm/arch/leds-gpio.h> | 39 | #include <asm/arch/leds-gpio.h> |
40 | 40 | ||
41 | #include <asm/arch/nand.h> | 41 | #include <asm/plat-s3c/nand.h> |
42 | 42 | ||
43 | #include <asm/plat-s3c24xx/common-smdk.h> | 43 | #include <asm/plat-s3c24xx/common-smdk.h> |
44 | #include <asm/plat-s3c24xx/devs.h> | 44 | #include <asm/plat-s3c24xx/devs.h> |
diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c index 8ce4904d3131..f513ab083b8f 100644 --- a/arch/arm/plat-s3c24xx/cpu.c +++ b/arch/arm/plat-s3c24xx/cpu.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #include <asm/mach/map.h> | 38 | #include <asm/mach/map.h> |
39 | 39 | ||
40 | #include <asm/arch/regs-gpio.h> | 40 | #include <asm/arch/regs-gpio.h> |
41 | #include <asm/arch/regs-serial.h> | 41 | #include <asm/plat-s3c/regs-serial.h> |
42 | 42 | ||
43 | #include <asm/plat-s3c24xx/cpu.h> | 43 | #include <asm/plat-s3c24xx/cpu.h> |
44 | #include <asm/plat-s3c24xx/devs.h> | 44 | #include <asm/plat-s3c24xx/devs.h> |
diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c index 5875da0ae0eb..e546e933b3f7 100644 --- a/arch/arm/plat-s3c24xx/devs.c +++ b/arch/arm/plat-s3c24xx/devs.c | |||
@@ -28,12 +28,12 @@ | |||
28 | #include <asm/io.h> | 28 | #include <asm/io.h> |
29 | #include <asm/irq.h> | 29 | #include <asm/irq.h> |
30 | 30 | ||
31 | #include <asm/arch/regs-serial.h> | 31 | #include <asm/plat-s3c/regs-serial.h> |
32 | #include <asm/arch/udc.h> | 32 | #include <asm/plat-s3c24xx/udc.h> |
33 | 33 | ||
34 | #include <asm/plat-s3c24xx/devs.h> | 34 | #include <asm/plat-s3c24xx/devs.h> |
35 | #include <asm/plat-s3c24xx/cpu.h> | 35 | #include <asm/plat-s3c24xx/cpu.h> |
36 | #include <asm/arch/regs-spi.h> | 36 | #include <asm/plat-s3c24xx/regs-spi.h> |
37 | 37 | ||
38 | /* Serial port registrations */ | 38 | /* Serial port registrations */ |
39 | 39 | ||
diff --git a/arch/arm/plat-s3c24xx/pm.c b/arch/arm/plat-s3c24xx/pm.c index 5692eccdf4d1..eab1850616d8 100644 --- a/arch/arm/plat-s3c24xx/pm.c +++ b/arch/arm/plat-s3c24xx/pm.c | |||
@@ -40,7 +40,7 @@ | |||
40 | #include <asm/hardware.h> | 40 | #include <asm/hardware.h> |
41 | #include <asm/io.h> | 41 | #include <asm/io.h> |
42 | 42 | ||
43 | #include <asm/arch/regs-serial.h> | 43 | #include <asm/plat-s3c/regs-serial.h> |
44 | #include <asm/arch/regs-clock.h> | 44 | #include <asm/arch/regs-clock.h> |
45 | #include <asm/arch/regs-gpio.h> | 45 | #include <asm/arch/regs-gpio.h> |
46 | #include <asm/arch/regs-mem.h> | 46 | #include <asm/arch/regs-mem.h> |
diff --git a/arch/arm/plat-s3c24xx/s3c244x.c b/arch/arm/plat-s3c24xx/s3c244x.c index 767f2e9a3a55..3444b13afac5 100644 --- a/arch/arm/plat-s3c24xx/s3c244x.c +++ b/arch/arm/plat-s3c24xx/s3c244x.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include <asm/irq.h> | 30 | #include <asm/irq.h> |
31 | 31 | ||
32 | #include <asm/arch/regs-clock.h> | 32 | #include <asm/arch/regs-clock.h> |
33 | #include <asm/arch/regs-serial.h> | 33 | #include <asm/plat-s3c/regs-serial.h> |
34 | #include <asm/arch/regs-gpio.h> | 34 | #include <asm/arch/regs-gpio.h> |
35 | #include <asm/arch/regs-gpioj.h> | 35 | #include <asm/arch/regs-gpioj.h> |
36 | #include <asm/arch/regs-dsc.h> | 36 | #include <asm/arch/regs-dsc.h> |
@@ -47,7 +47,6 @@ static struct map_desc s3c244x_iodesc[] __initdata = { | |||
47 | IODESC_ENT(CLKPWR), | 47 | IODESC_ENT(CLKPWR), |
48 | IODESC_ENT(TIMER), | 48 | IODESC_ENT(TIMER), |
49 | IODESC_ENT(WATCHDOG), | 49 | IODESC_ENT(WATCHDOG), |
50 | IODESC_ENT(LCD), | ||
51 | }; | 50 | }; |
52 | 51 | ||
53 | /* uart initialisation */ | 52 | /* uart initialisation */ |
diff --git a/arch/arm/plat-s3c24xx/sleep.S b/arch/arm/plat-s3c24xx/sleep.S index 7b7ae790b00d..d47113bbc34c 100644 --- a/arch/arm/plat-s3c24xx/sleep.S +++ b/arch/arm/plat-s3c24xx/sleep.S | |||
@@ -32,7 +32,7 @@ | |||
32 | #include <asm/arch/regs-gpio.h> | 32 | #include <asm/arch/regs-gpio.h> |
33 | #include <asm/arch/regs-clock.h> | 33 | #include <asm/arch/regs-clock.h> |
34 | #include <asm/arch/regs-mem.h> | 34 | #include <asm/arch/regs-mem.h> |
35 | #include <asm/arch/regs-serial.h> | 35 | #include <asm/plat-s3c/regs-serial.h> |
36 | 36 | ||
37 | /* CONFIG_DEBUG_RESUME is dangerous if your bootloader does not | 37 | /* CONFIG_DEBUG_RESUME is dangerous if your bootloader does not |
38 | * reset the UART configuration, only enable if you really need this! | 38 | * reset the UART configuration, only enable if you really need this! |
diff --git a/arch/arm/plat-s3c24xx/time.c b/arch/arm/plat-s3c24xx/time.c index b7667375bcec..2ec1daaa0e53 100644 --- a/arch/arm/plat-s3c24xx/time.c +++ b/arch/arm/plat-s3c24xx/time.c | |||
@@ -33,7 +33,7 @@ | |||
33 | #include <asm/io.h> | 33 | #include <asm/io.h> |
34 | #include <asm/irq.h> | 34 | #include <asm/irq.h> |
35 | #include <asm/arch/map.h> | 35 | #include <asm/arch/map.h> |
36 | #include <asm/arch/regs-timer.h> | 36 | #include <asm/plat-s3c/regs-timer.h> |
37 | #include <asm/arch/regs-irq.h> | 37 | #include <asm/arch/regs-irq.h> |
38 | #include <asm/mach/time.h> | 38 | #include <asm/mach/time.h> |
39 | 39 | ||
diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S index d4b7b229631d..0ac022f800a1 100644 --- a/arch/arm/vfp/vfphw.S +++ b/arch/arm/vfp/vfphw.S | |||
@@ -74,14 +74,14 @@ vfp_support_entry: | |||
74 | 74 | ||
75 | VFPFMRX r1, FPEXC @ Is the VFP enabled? | 75 | VFPFMRX r1, FPEXC @ Is the VFP enabled? |
76 | DBGSTR1 "fpexc %08x", r1 | 76 | DBGSTR1 "fpexc %08x", r1 |
77 | tst r1, #FPEXC_ENABLE | 77 | tst r1, #FPEXC_EN |
78 | bne look_for_VFP_exceptions @ VFP is already enabled | 78 | bne look_for_VFP_exceptions @ VFP is already enabled |
79 | 79 | ||
80 | DBGSTR1 "enable %x", r10 | 80 | DBGSTR1 "enable %x", r10 |
81 | ldr r3, last_VFP_context_address | 81 | ldr r3, last_VFP_context_address |
82 | orr r1, r1, #FPEXC_ENABLE @ user FPEXC has the enable bit set | 82 | orr r1, r1, #FPEXC_EN @ user FPEXC has the enable bit set |
83 | ldr r4, [r3, r11, lsl #2] @ last_VFP_context pointer | 83 | ldr r4, [r3, r11, lsl #2] @ last_VFP_context pointer |
84 | bic r5, r1, #FPEXC_EXCEPTION @ make sure exceptions are disabled | 84 | bic r5, r1, #FPEXC_EX @ make sure exceptions are disabled |
85 | cmp r4, r10 | 85 | cmp r4, r10 |
86 | beq check_for_exception @ we are returning to the same | 86 | beq check_for_exception @ we are returning to the same |
87 | @ process, so the registers are | 87 | @ process, so the registers are |
@@ -124,7 +124,7 @@ no_old_VFP_process: | |||
124 | VFPFMXR FPSCR, r5 @ restore status | 124 | VFPFMXR FPSCR, r5 @ restore status |
125 | 125 | ||
126 | check_for_exception: | 126 | check_for_exception: |
127 | tst r1, #FPEXC_EXCEPTION | 127 | tst r1, #FPEXC_EX |
128 | bne process_exception @ might as well handle the pending | 128 | bne process_exception @ might as well handle the pending |
129 | @ exception before retrying branch | 129 | @ exception before retrying branch |
130 | @ out before setting an FPEXC that | 130 | @ out before setting an FPEXC that |
@@ -136,10 +136,10 @@ check_for_exception: | |||
136 | 136 | ||
137 | 137 | ||
138 | look_for_VFP_exceptions: | 138 | look_for_VFP_exceptions: |
139 | tst r1, #FPEXC_EXCEPTION | 139 | tst r1, #FPEXC_EX |
140 | bne process_exception | 140 | bne process_exception |
141 | VFPFMRX r5, FPSCR | 141 | VFPFMRX r5, FPSCR |
142 | tst r5, #FPSCR_IXE @ IXE doesn't set FPEXC_EXCEPTION ! | 142 | tst r5, #FPSCR_IXE @ IXE doesn't set FPEXC_EX ! |
143 | bne process_exception | 143 | bne process_exception |
144 | 144 | ||
145 | @ Fall into hand on to next handler - appropriate coproc instr | 145 | @ Fall into hand on to next handler - appropriate coproc instr |
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 1106b5f9cf19..04ddab2bd876 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c | |||
@@ -53,7 +53,7 @@ static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v) | |||
53 | * case the thread migrates to a different CPU. The | 53 | * case the thread migrates to a different CPU. The |
54 | * restoring is done lazily. | 54 | * restoring is done lazily. |
55 | */ | 55 | */ |
56 | if ((fpexc & FPEXC_ENABLE) && last_VFP_context[cpu]) { | 56 | if ((fpexc & FPEXC_EN) && last_VFP_context[cpu]) { |
57 | vfp_save_state(last_VFP_context[cpu], fpexc); | 57 | vfp_save_state(last_VFP_context[cpu], fpexc); |
58 | last_VFP_context[cpu]->hard.cpu = cpu; | 58 | last_VFP_context[cpu]->hard.cpu = cpu; |
59 | } | 59 | } |
@@ -70,7 +70,7 @@ static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v) | |||
70 | * Always disable VFP so we can lazily save/restore the | 70 | * Always disable VFP so we can lazily save/restore the |
71 | * old state. | 71 | * old state. |
72 | */ | 72 | */ |
73 | fmxr(FPEXC, fpexc & ~FPEXC_ENABLE); | 73 | fmxr(FPEXC, fpexc & ~FPEXC_EN); |
74 | return NOTIFY_DONE; | 74 | return NOTIFY_DONE; |
75 | } | 75 | } |
76 | 76 | ||
@@ -81,13 +81,13 @@ static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v) | |||
81 | */ | 81 | */ |
82 | memset(vfp, 0, sizeof(union vfp_state)); | 82 | memset(vfp, 0, sizeof(union vfp_state)); |
83 | 83 | ||
84 | vfp->hard.fpexc = FPEXC_ENABLE; | 84 | vfp->hard.fpexc = FPEXC_EN; |
85 | vfp->hard.fpscr = FPSCR_ROUND_NEAREST; | 85 | vfp->hard.fpscr = FPSCR_ROUND_NEAREST; |
86 | 86 | ||
87 | /* | 87 | /* |
88 | * Disable VFP to ensure we initialise it first. | 88 | * Disable VFP to ensure we initialise it first. |
89 | */ | 89 | */ |
90 | fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_ENABLE); | 90 | fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN); |
91 | } | 91 | } |
92 | 92 | ||
93 | /* flush and release case: Per-thread VFP cleanup. */ | 93 | /* flush and release case: Per-thread VFP cleanup. */ |
@@ -229,7 +229,7 @@ void VFP9_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) | |||
229 | /* | 229 | /* |
230 | * Enable access to the VFP so we can handle the bounce. | 230 | * Enable access to the VFP so we can handle the bounce. |
231 | */ | 231 | */ |
232 | fmxr(FPEXC, fpexc & ~(FPEXC_EXCEPTION|FPEXC_INV|FPEXC_UFC|FPEXC_IOC)); | 232 | fmxr(FPEXC, fpexc & ~(FPEXC_EX|FPEXC_INV|FPEXC_UFC|FPEXC_IOC)); |
233 | 233 | ||
234 | orig_fpscr = fpscr = fmrx(FPSCR); | 234 | orig_fpscr = fpscr = fmrx(FPSCR); |
235 | 235 | ||
@@ -248,7 +248,7 @@ void VFP9_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) | |||
248 | /* | 248 | /* |
249 | * Modify fpscr to indicate the number of iterations remaining | 249 | * Modify fpscr to indicate the number of iterations remaining |
250 | */ | 250 | */ |
251 | if (fpexc & FPEXC_EXCEPTION) { | 251 | if (fpexc & FPEXC_EX) { |
252 | u32 len; | 252 | u32 len; |
253 | 253 | ||
254 | len = fpexc + (1 << FPEXC_LENGTH_BIT); | 254 | len = fpexc + (1 << FPEXC_LENGTH_BIT); |
diff --git a/arch/arm26/kernel/armksyms.c b/arch/arm26/kernel/armksyms.c index f735d7e018e4..fe1e3ceed7cb 100644 --- a/arch/arm26/kernel/armksyms.c +++ b/arch/arm26/kernel/armksyms.c | |||
@@ -107,8 +107,6 @@ EXPORT_SYMBOL(__bug); | |||
107 | #endif | 107 | #endif |
108 | EXPORT_SYMBOL(__bad_xchg); | 108 | EXPORT_SYMBOL(__bad_xchg); |
109 | EXPORT_SYMBOL(__readwrite_bug); | 109 | EXPORT_SYMBOL(__readwrite_bug); |
110 | EXPORT_SYMBOL(enable_irq); | ||
111 | EXPORT_SYMBOL(disable_irq); | ||
112 | EXPORT_SYMBOL(set_irq_type); | 110 | EXPORT_SYMBOL(set_irq_type); |
113 | EXPORT_SYMBOL(pm_idle); | 111 | EXPORT_SYMBOL(pm_idle); |
114 | EXPORT_SYMBOL(pm_power_off); | 112 | EXPORT_SYMBOL(pm_power_off); |
diff --git a/arch/arm26/kernel/irq.c b/arch/arm26/kernel/irq.c index d53382c83bf9..2ffe695b062e 100644 --- a/arch/arm26/kernel/irq.c +++ b/arch/arm26/kernel/irq.c | |||
@@ -95,6 +95,11 @@ void disable_irq(unsigned int irq) | |||
95 | desc->enabled = 0; | 95 | desc->enabled = 0; |
96 | spin_unlock_irqrestore(&irq_controller_lock, flags); | 96 | spin_unlock_irqrestore(&irq_controller_lock, flags); |
97 | } | 97 | } |
98 | EXPORT_SYMBOL(disable_irq); | ||
99 | |||
100 | void disable_irq_nosync(unsigned int irq) __attribute__((alias("disable_irq"))); | ||
101 | |||
102 | EXPORT_SYMBOL(disable_irq_nosync); | ||
98 | 103 | ||
99 | /** | 104 | /** |
100 | * enable_irq - enable interrupt handling on an irq | 105 | * enable_irq - enable interrupt handling on an irq |
@@ -131,6 +136,7 @@ void enable_irq(unsigned int irq) | |||
131 | } | 136 | } |
132 | spin_unlock_irqrestore(&irq_controller_lock, flags); | 137 | spin_unlock_irqrestore(&irq_controller_lock, flags); |
133 | } | 138 | } |
139 | EXPORT_SYMBOL(enable_irq); | ||
134 | 140 | ||
135 | int show_interrupts(struct seq_file *p, void *v) | 141 | int show_interrupts(struct seq_file *p, void *v) |
136 | { | 142 | { |
diff --git a/arch/avr32/boards/atngw100/setup.c b/arch/avr32/boards/atngw100/setup.c index 6c4dc0a00e9f..2edcecdea8bd 100644 --- a/arch/avr32/boards/atngw100/setup.c +++ b/arch/avr32/boards/atngw100/setup.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/linkage.h> | 13 | #include <linux/linkage.h> |
14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
15 | #include <linux/types.h> | 15 | #include <linux/types.h> |
16 | #include <linux/leds.h> | ||
16 | #include <linux/spi/spi.h> | 17 | #include <linux/spi/spi.h> |
17 | 18 | ||
18 | #include <asm/io.h> | 19 | #include <asm/io.h> |
@@ -21,6 +22,7 @@ | |||
21 | #include <asm/arch/at32ap7000.h> | 22 | #include <asm/arch/at32ap7000.h> |
22 | #include <asm/arch/board.h> | 23 | #include <asm/arch/board.h> |
23 | #include <asm/arch/init.h> | 24 | #include <asm/arch/init.h> |
25 | #include <asm/arch/portmux.h> | ||
24 | 26 | ||
25 | /* Initialized by bootloader-specific startup code. */ | 27 | /* Initialized by bootloader-specific startup code. */ |
26 | struct tag *bootloader_tags __initdata; | 28 | struct tag *bootloader_tags __initdata; |
@@ -100,8 +102,31 @@ void __init setup_board(void) | |||
100 | at32_setup_serial_console(0); | 102 | at32_setup_serial_console(0); |
101 | } | 103 | } |
102 | 104 | ||
105 | static const struct gpio_led ngw_leds[] = { | ||
106 | { .name = "sys", .gpio = GPIO_PIN_PA(16), .active_low = 1, | ||
107 | .default_trigger = "heartbeat", | ||
108 | }, | ||
109 | { .name = "a", .gpio = GPIO_PIN_PA(19), .active_low = 1, }, | ||
110 | { .name = "b", .gpio = GPIO_PIN_PE(19), .active_low = 1, }, | ||
111 | }; | ||
112 | |||
113 | static const struct gpio_led_platform_data ngw_led_data = { | ||
114 | .num_leds = ARRAY_SIZE(ngw_leds), | ||
115 | .leds = (void *) ngw_leds, | ||
116 | }; | ||
117 | |||
118 | static struct platform_device ngw_gpio_leds = { | ||
119 | .name = "leds-gpio", | ||
120 | .id = -1, | ||
121 | .dev = { | ||
122 | .platform_data = (void *) &ngw_led_data, | ||
123 | } | ||
124 | }; | ||
125 | |||
103 | static int __init atngw100_init(void) | 126 | static int __init atngw100_init(void) |
104 | { | 127 | { |
128 | unsigned i; | ||
129 | |||
105 | /* | 130 | /* |
106 | * ATNGW100 uses 16-bit SDRAM interface, so we don't need to | 131 | * ATNGW100 uses 16-bit SDRAM interface, so we don't need to |
107 | * reserve any pins for it. | 132 | * reserve any pins for it. |
@@ -116,6 +141,12 @@ static int __init atngw100_init(void) | |||
116 | 141 | ||
117 | at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info)); | 142 | at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info)); |
118 | 143 | ||
144 | for (i = 0; i < ARRAY_SIZE(ngw_leds); i++) { | ||
145 | at32_select_gpio(ngw_leds[i].gpio, | ||
146 | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); | ||
147 | } | ||
148 | platform_device_register(&ngw_gpio_leds); | ||
149 | |||
119 | return 0; | 150 | return 0; |
120 | } | 151 | } |
121 | postcore_initcall(atngw100_init); | 152 | postcore_initcall(atngw100_init); |
diff --git a/arch/avr32/configs/atngw100_defconfig b/arch/avr32/configs/atngw100_defconfig index 49493ad3b5a9..b799a68ffd97 100644 --- a/arch/avr32/configs/atngw100_defconfig +++ b/arch/avr32/configs/atngw100_defconfig | |||
@@ -712,7 +712,21 @@ CONFIG_SPI_ATMEL=y | |||
712 | # | 712 | # |
713 | # LED devices | 713 | # LED devices |
714 | # | 714 | # |
715 | # CONFIG_NEW_LEDS is not set | 715 | CONFIG_NEW_LEDS=y |
716 | CONFIG_LEDS_CLASS=y | ||
717 | |||
718 | # | ||
719 | # LED drivers | ||
720 | # | ||
721 | CONFIG_LEDS_GPIO=y | ||
722 | |||
723 | # | ||
724 | # LED Triggers | ||
725 | # | ||
726 | CONFIG_LEDS_TRIGGERS=y | ||
727 | CONFIG_LEDS_TRIGGER_TIMER=y | ||
728 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y | ||
729 | |||
716 | 730 | ||
717 | # | 731 | # |
718 | # LED drivers | 732 | # LED drivers |
diff --git a/arch/i386/kernel/acpi/Makefile b/arch/i386/kernel/acpi/Makefile index 7f7be01f44e6..223f58fc9f46 100644 --- a/arch/i386/kernel/acpi/Makefile +++ b/arch/i386/kernel/acpi/Makefile | |||
@@ -2,7 +2,7 @@ obj-$(CONFIG_ACPI) += boot.o | |||
2 | ifneq ($(CONFIG_PCI),) | 2 | ifneq ($(CONFIG_PCI),) |
3 | obj-$(CONFIG_X86_IO_APIC) += earlyquirk.o | 3 | obj-$(CONFIG_X86_IO_APIC) += earlyquirk.o |
4 | endif | 4 | endif |
5 | obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup.o | 5 | obj-$(CONFIG_ACPI) += sleep.o wakeup.o |
6 | 6 | ||
7 | ifneq ($(CONFIG_ACPI_PROCESSOR),) | 7 | ifneq ($(CONFIG_ACPI_PROCESSOR),) |
8 | obj-y += cstate.o processor.o | 8 | obj-y += cstate.o processor.o |
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index b87cedeaf59b..cacdd883bf2b 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c | |||
@@ -986,14 +986,6 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = { | |||
986 | }, | 986 | }, |
987 | { | 987 | { |
988 | .callback = force_acpi_ht, | 988 | .callback = force_acpi_ht, |
989 | .ident = "DELL GX240", | ||
990 | .matches = { | ||
991 | DMI_MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"), | ||
992 | DMI_MATCH(DMI_BOARD_NAME, "OptiPlex GX240"), | ||
993 | }, | ||
994 | }, | ||
995 | { | ||
996 | .callback = force_acpi_ht, | ||
997 | .ident = "HP VISUALIZE NT Workstation", | 989 | .ident = "HP VISUALIZE NT Workstation", |
998 | .matches = { | 990 | .matches = { |
999 | DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), | 991 | DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), |
diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c index 0695be538de5..c3750c2c4113 100644 --- a/arch/i386/kernel/alternative.c +++ b/arch/i386/kernel/alternative.c | |||
@@ -2,8 +2,14 @@ | |||
2 | #include <linux/sched.h> | 2 | #include <linux/sched.h> |
3 | #include <linux/spinlock.h> | 3 | #include <linux/spinlock.h> |
4 | #include <linux/list.h> | 4 | #include <linux/list.h> |
5 | #include <linux/kprobes.h> | ||
6 | #include <linux/mm.h> | ||
7 | #include <linux/vmalloc.h> | ||
5 | #include <asm/alternative.h> | 8 | #include <asm/alternative.h> |
6 | #include <asm/sections.h> | 9 | #include <asm/sections.h> |
10 | #include <asm/pgtable.h> | ||
11 | #include <asm/mce.h> | ||
12 | #include <asm/nmi.h> | ||
7 | 13 | ||
8 | #ifdef CONFIG_HOTPLUG_CPU | 14 | #ifdef CONFIG_HOTPLUG_CPU |
9 | static int smp_alt_once; | 15 | static int smp_alt_once; |
@@ -150,7 +156,7 @@ static void nop_out(void *insns, unsigned int len) | |||
150 | unsigned int noplen = len; | 156 | unsigned int noplen = len; |
151 | if (noplen > ASM_NOP_MAX) | 157 | if (noplen > ASM_NOP_MAX) |
152 | noplen = ASM_NOP_MAX; | 158 | noplen = ASM_NOP_MAX; |
153 | memcpy(insns, noptable[noplen], noplen); | 159 | text_poke(insns, noptable[noplen], noplen); |
154 | insns += noplen; | 160 | insns += noplen; |
155 | len -= noplen; | 161 | len -= noplen; |
156 | } | 162 | } |
@@ -202,7 +208,7 @@ static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end) | |||
202 | continue; | 208 | continue; |
203 | if (*ptr > text_end) | 209 | if (*ptr > text_end) |
204 | continue; | 210 | continue; |
205 | **ptr = 0xf0; /* lock prefix */ | 211 | text_poke(*ptr, ((unsigned char []){0xf0}), 1); /* add lock prefix */ |
206 | }; | 212 | }; |
207 | } | 213 | } |
208 | 214 | ||
@@ -360,10 +366,6 @@ void apply_paravirt(struct paravirt_patch_site *start, | |||
360 | /* Pad the rest with nops */ | 366 | /* Pad the rest with nops */ |
361 | nop_out(p->instr + used, p->len - used); | 367 | nop_out(p->instr + used, p->len - used); |
362 | } | 368 | } |
363 | |||
364 | /* Sync to be conservative, in case we patched following | ||
365 | * instructions */ | ||
366 | sync_core(); | ||
367 | } | 369 | } |
368 | extern struct paravirt_patch_site __start_parainstructions[], | 370 | extern struct paravirt_patch_site __start_parainstructions[], |
369 | __stop_parainstructions[]; | 371 | __stop_parainstructions[]; |
@@ -373,6 +375,14 @@ void __init alternative_instructions(void) | |||
373 | { | 375 | { |
374 | unsigned long flags; | 376 | unsigned long flags; |
375 | 377 | ||
378 | /* The patching is not fully atomic, so try to avoid local interruptions | ||
379 | that might execute the to be patched code. | ||
380 | Other CPUs are not running. */ | ||
381 | stop_nmi(); | ||
382 | #ifdef CONFIG_MCE | ||
383 | stop_mce(); | ||
384 | #endif | ||
385 | |||
376 | local_irq_save(flags); | 386 | local_irq_save(flags); |
377 | apply_alternatives(__alt_instructions, __alt_instructions_end); | 387 | apply_alternatives(__alt_instructions, __alt_instructions_end); |
378 | 388 | ||
@@ -405,4 +415,37 @@ void __init alternative_instructions(void) | |||
405 | #endif | 415 | #endif |
406 | apply_paravirt(__parainstructions, __parainstructions_end); | 416 | apply_paravirt(__parainstructions, __parainstructions_end); |
407 | local_irq_restore(flags); | 417 | local_irq_restore(flags); |
418 | |||
419 | restart_nmi(); | ||
420 | #ifdef CONFIG_MCE | ||
421 | restart_mce(); | ||
422 | #endif | ||
423 | } | ||
424 | |||
425 | /* | ||
426 | * Warning: | ||
427 | * When you use this code to patch more than one byte of an instruction | ||
428 | * you need to make sure that other CPUs cannot execute this code in parallel. | ||
429 | * Also no thread must be currently preempted in the middle of these instructions. | ||
430 | * And on the local CPU you need to be protected again NMI or MCE handlers | ||
431 | * seeing an inconsistent instruction while you patch. | ||
432 | */ | ||
433 | void __kprobes text_poke(void *oaddr, unsigned char *opcode, int len) | ||
434 | { | ||
435 | u8 *addr = oaddr; | ||
436 | if (!pte_write(*lookup_address((unsigned long)addr))) { | ||
437 | struct page *p[2] = { virt_to_page(addr), virt_to_page(addr+PAGE_SIZE) }; | ||
438 | addr = vmap(p, 2, VM_MAP, PAGE_KERNEL); | ||
439 | if (!addr) | ||
440 | return; | ||
441 | addr += ((unsigned long)oaddr) % PAGE_SIZE; | ||
442 | } | ||
443 | memcpy(addr, opcode, len); | ||
444 | sync_core(); | ||
445 | /* Not strictly needed, but can speed CPU recovery up. Ignore cross cacheline | ||
446 | case. */ | ||
447 | if (cpu_has_clflush) | ||
448 | asm("clflush (%0) " :: "r" (oaddr) : "memory"); | ||
449 | if (addr != oaddr) | ||
450 | vunmap(addr); | ||
408 | } | 451 | } |
diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c index 815a5f0aa474..c7ba455d5ac7 100644 --- a/arch/i386/kernel/cpu/amd.c +++ b/arch/i386/kernel/cpu/amd.c | |||
@@ -231,6 +231,9 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) | |||
231 | 231 | ||
232 | switch (c->x86) { | 232 | switch (c->x86) { |
233 | case 15: | 233 | case 15: |
234 | /* Use K8 tuning for Fam10h and Fam11h */ | ||
235 | case 0x10: | ||
236 | case 0x11: | ||
234 | set_bit(X86_FEATURE_K8, c->x86_capability); | 237 | set_bit(X86_FEATURE_K8, c->x86_capability); |
235 | break; | 238 | break; |
236 | case 6: | 239 | case 6: |
diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c index 18c8b67ea3a7..6f846bee2103 100644 --- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c | |||
@@ -665,8 +665,8 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
665 | data->max_freq = perf->states[0].core_frequency * 1000; | 665 | data->max_freq = perf->states[0].core_frequency * 1000; |
666 | /* table init */ | 666 | /* table init */ |
667 | for (i=0; i<perf->state_count; i++) { | 667 | for (i=0; i<perf->state_count; i++) { |
668 | if (i>0 && perf->states[i].core_frequency == | 668 | if (i>0 && perf->states[i].core_frequency >= |
669 | perf->states[i-1].core_frequency) | 669 | data->freq_table[valid_states-1].frequency / 1000) |
670 | continue; | 670 | continue; |
671 | 671 | ||
672 | data->freq_table[valid_states].index = i; | 672 | data->freq_table[valid_states].index = i; |
diff --git a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c index 194144539a6f..461dabc4e495 100644 --- a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c +++ b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c | |||
@@ -79,7 +79,7 @@ | |||
79 | #include <linux/smp.h> | 79 | #include <linux/smp.h> |
80 | #include <linux/cpufreq.h> | 80 | #include <linux/cpufreq.h> |
81 | #include <linux/pci.h> | 81 | #include <linux/pci.h> |
82 | #include <asm/processor.h> | 82 | #include <asm/processor-cyrix.h> |
83 | #include <asm/errno.h> | 83 | #include <asm/errno.h> |
84 | 84 | ||
85 | /* PCI config registers, all at F0 */ | 85 | /* PCI config registers, all at F0 */ |
diff --git a/arch/i386/kernel/cpu/cyrix.c b/arch/i386/kernel/cpu/cyrix.c index e88d2fba156b..122d2d75aa9f 100644 --- a/arch/i386/kernel/cpu/cyrix.c +++ b/arch/i386/kernel/cpu/cyrix.c | |||
@@ -4,7 +4,7 @@ | |||
4 | #include <linux/pci.h> | 4 | #include <linux/pci.h> |
5 | #include <asm/dma.h> | 5 | #include <asm/dma.h> |
6 | #include <asm/io.h> | 6 | #include <asm/io.h> |
7 | #include <asm/processor.h> | 7 | #include <asm/processor-cyrix.h> |
8 | #include <asm/timer.h> | 8 | #include <asm/timer.h> |
9 | #include <asm/pci-direct.h> | 9 | #include <asm/pci-direct.h> |
10 | #include <asm/tsc.h> | 10 | #include <asm/tsc.h> |
diff --git a/arch/i386/kernel/cpu/mcheck/mce.c b/arch/i386/kernel/cpu/mcheck/mce.c index 56cd485b127c..34c781eddee4 100644 --- a/arch/i386/kernel/cpu/mcheck/mce.c +++ b/arch/i386/kernel/cpu/mcheck/mce.c | |||
@@ -60,6 +60,20 @@ void mcheck_init(struct cpuinfo_x86 *c) | |||
60 | } | 60 | } |
61 | } | 61 | } |
62 | 62 | ||
63 | static unsigned long old_cr4 __initdata; | ||
64 | |||
65 | void __init stop_mce(void) | ||
66 | { | ||
67 | old_cr4 = read_cr4(); | ||
68 | clear_in_cr4(X86_CR4_MCE); | ||
69 | } | ||
70 | |||
71 | void __init restart_mce(void) | ||
72 | { | ||
73 | if (old_cr4 & X86_CR4_MCE) | ||
74 | set_in_cr4(X86_CR4_MCE); | ||
75 | } | ||
76 | |||
63 | static int __init mcheck_disable(char *str) | 77 | static int __init mcheck_disable(char *str) |
64 | { | 78 | { |
65 | mce_disabled = 1; | 79 | mce_disabled = 1; |
diff --git a/arch/i386/kernel/cpu/mtrr/cyrix.c b/arch/i386/kernel/cpu/mtrr/cyrix.c index 1001f1e0fe6d..2287d4863a8a 100644 --- a/arch/i386/kernel/cpu/mtrr/cyrix.c +++ b/arch/i386/kernel/cpu/mtrr/cyrix.c | |||
@@ -3,6 +3,7 @@ | |||
3 | #include <asm/mtrr.h> | 3 | #include <asm/mtrr.h> |
4 | #include <asm/msr.h> | 4 | #include <asm/msr.h> |
5 | #include <asm/io.h> | 5 | #include <asm/io.h> |
6 | #include <asm/processor-cyrix.h> | ||
6 | #include "mtrr.h" | 7 | #include "mtrr.h" |
7 | 8 | ||
8 | int arr3_protected; | 9 | int arr3_protected; |
diff --git a/arch/i386/kernel/cpu/mtrr/state.c b/arch/i386/kernel/cpu/mtrr/state.c index 7b39a2f954d9..c9014ca4a575 100644 --- a/arch/i386/kernel/cpu/mtrr/state.c +++ b/arch/i386/kernel/cpu/mtrr/state.c | |||
@@ -3,6 +3,7 @@ | |||
3 | #include <asm/io.h> | 3 | #include <asm/io.h> |
4 | #include <asm/mtrr.h> | 4 | #include <asm/mtrr.h> |
5 | #include <asm/msr.h> | 5 | #include <asm/msr.h> |
6 | #include <asm-i386/processor-cyrix.h> | ||
6 | #include "mtrr.h" | 7 | #include "mtrr.h" |
7 | 8 | ||
8 | 9 | ||
diff --git a/arch/i386/kernel/cpu/perfctr-watchdog.c b/arch/i386/kernel/cpu/perfctr-watchdog.c index 30b5e48aa76b..4be488e73bee 100644 --- a/arch/i386/kernel/cpu/perfctr-watchdog.c +++ b/arch/i386/kernel/cpu/perfctr-watchdog.c | |||
@@ -325,7 +325,7 @@ static struct wd_ops k7_wd_ops = { | |||
325 | .stop = single_msr_stop_watchdog, | 325 | .stop = single_msr_stop_watchdog, |
326 | .perfctr = MSR_K7_PERFCTR0, | 326 | .perfctr = MSR_K7_PERFCTR0, |
327 | .evntsel = MSR_K7_EVNTSEL0, | 327 | .evntsel = MSR_K7_EVNTSEL0, |
328 | .checkbit = 1ULL<<63, | 328 | .checkbit = 1ULL<<47, |
329 | }; | 329 | }; |
330 | 330 | ||
331 | /* Intel Model 6 (PPro+,P2,P3,P-M,Core1) */ | 331 | /* Intel Model 6 (PPro+,P2,P3,P-M,Core1) */ |
@@ -346,7 +346,9 @@ static int setup_p6_watchdog(unsigned nmi_hz) | |||
346 | perfctr_msr = MSR_P6_PERFCTR0; | 346 | perfctr_msr = MSR_P6_PERFCTR0; |
347 | evntsel_msr = MSR_P6_EVNTSEL0; | 347 | evntsel_msr = MSR_P6_EVNTSEL0; |
348 | 348 | ||
349 | wrmsrl(perfctr_msr, 0UL); | 349 | /* KVM doesn't implement this MSR */ |
350 | if (wrmsr_safe(perfctr_msr, 0, 0) < 0) | ||
351 | return 0; | ||
350 | 352 | ||
351 | evntsel = P6_EVNTSEL_INT | 353 | evntsel = P6_EVNTSEL_INT |
352 | | P6_EVNTSEL_OS | 354 | | P6_EVNTSEL_OS |
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c index dde828a333c3..448a50b1324c 100644 --- a/arch/i386/kernel/kprobes.c +++ b/arch/i386/kernel/kprobes.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <asm/cacheflush.h> | 35 | #include <asm/cacheflush.h> |
36 | #include <asm/desc.h> | 36 | #include <asm/desc.h> |
37 | #include <asm/uaccess.h> | 37 | #include <asm/uaccess.h> |
38 | #include <asm/alternative.h> | ||
38 | 39 | ||
39 | void jprobe_return_end(void); | 40 | void jprobe_return_end(void); |
40 | 41 | ||
@@ -169,16 +170,12 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) | |||
169 | 170 | ||
170 | void __kprobes arch_arm_kprobe(struct kprobe *p) | 171 | void __kprobes arch_arm_kprobe(struct kprobe *p) |
171 | { | 172 | { |
172 | *p->addr = BREAKPOINT_INSTRUCTION; | 173 | text_poke(p->addr, ((unsigned char []){BREAKPOINT_INSTRUCTION}), 1); |
173 | flush_icache_range((unsigned long) p->addr, | ||
174 | (unsigned long) p->addr + sizeof(kprobe_opcode_t)); | ||
175 | } | 174 | } |
176 | 175 | ||
177 | void __kprobes arch_disarm_kprobe(struct kprobe *p) | 176 | void __kprobes arch_disarm_kprobe(struct kprobe *p) |
178 | { | 177 | { |
179 | *p->addr = p->opcode; | 178 | text_poke(p->addr, &p->opcode, 1); |
180 | flush_icache_range((unsigned long) p->addr, | ||
181 | (unsigned long) p->addr + sizeof(kprobe_opcode_t)); | ||
182 | } | 179 | } |
183 | 180 | ||
184 | void __kprobes arch_remove_kprobe(struct kprobe *p) | 181 | void __kprobes arch_remove_kprobe(struct kprobe *p) |
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index 03b7f5584d71..99beac7f96ce 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c | |||
@@ -353,7 +353,7 @@ __kprobes int nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) | |||
353 | * Take the local apic timer and PIT/HPET into account. We don't | 353 | * Take the local apic timer and PIT/HPET into account. We don't |
354 | * know which one is active, when we have highres/dyntick on | 354 | * know which one is active, when we have highres/dyntick on |
355 | */ | 355 | */ |
356 | sum = per_cpu(irq_stat, cpu).apic_timer_irqs + kstat_irqs(0); | 356 | sum = per_cpu(irq_stat, cpu).apic_timer_irqs + kstat_cpu(cpu).irqs[0]; |
357 | 357 | ||
358 | /* if the none of the timers isn't firing, this cpu isn't doing much */ | 358 | /* if the none of the timers isn't firing, this cpu isn't doing much */ |
359 | if (!touched && last_irq_sums[cpu] == sum) { | 359 | if (!touched && last_irq_sums[cpu] == sum) { |
diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c index 53f07a8275e3..ea962c0667d5 100644 --- a/arch/i386/kernel/paravirt.c +++ b/arch/i386/kernel/paravirt.c | |||
@@ -124,20 +124,28 @@ unsigned paravirt_patch_ignore(unsigned len) | |||
124 | return len; | 124 | return len; |
125 | } | 125 | } |
126 | 126 | ||
127 | struct branch { | ||
128 | unsigned char opcode; | ||
129 | u32 delta; | ||
130 | } __attribute__((packed)); | ||
131 | |||
127 | unsigned paravirt_patch_call(void *target, u16 tgt_clobbers, | 132 | unsigned paravirt_patch_call(void *target, u16 tgt_clobbers, |
128 | void *site, u16 site_clobbers, | 133 | void *site, u16 site_clobbers, |
129 | unsigned len) | 134 | unsigned len) |
130 | { | 135 | { |
131 | unsigned char *call = site; | 136 | unsigned char *call = site; |
132 | unsigned long delta = (unsigned long)target - (unsigned long)(call+5); | 137 | unsigned long delta = (unsigned long)target - (unsigned long)(call+5); |
138 | struct branch b; | ||
133 | 139 | ||
134 | if (tgt_clobbers & ~site_clobbers) | 140 | if (tgt_clobbers & ~site_clobbers) |
135 | return len; /* target would clobber too much for this site */ | 141 | return len; /* target would clobber too much for this site */ |
136 | if (len < 5) | 142 | if (len < 5) |
137 | return len; /* call too long for patch site */ | 143 | return len; /* call too long for patch site */ |
138 | 144 | ||
139 | *call++ = 0xe8; /* call */ | 145 | b.opcode = 0xe8; /* call */ |
140 | *(unsigned long *)call = delta; | 146 | b.delta = delta; |
147 | BUILD_BUG_ON(sizeof(b) != 5); | ||
148 | text_poke(call, (unsigned char *)&b, 5); | ||
141 | 149 | ||
142 | return 5; | 150 | return 5; |
143 | } | 151 | } |
@@ -146,12 +154,14 @@ unsigned paravirt_patch_jmp(void *target, void *site, unsigned len) | |||
146 | { | 154 | { |
147 | unsigned char *jmp = site; | 155 | unsigned char *jmp = site; |
148 | unsigned long delta = (unsigned long)target - (unsigned long)(jmp+5); | 156 | unsigned long delta = (unsigned long)target - (unsigned long)(jmp+5); |
157 | struct branch b; | ||
149 | 158 | ||
150 | if (len < 5) | 159 | if (len < 5) |
151 | return len; /* call too long for patch site */ | 160 | return len; /* call too long for patch site */ |
152 | 161 | ||
153 | *jmp++ = 0xe9; /* jmp */ | 162 | b.opcode = 0xe9; /* jmp */ |
154 | *(unsigned long *)jmp = delta; | 163 | b.delta = delta; |
164 | text_poke(jmp, (unsigned char *)&b, 5); | ||
155 | 165 | ||
156 | return 5; | 166 | return 5; |
157 | } | 167 | } |
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index d474cd639bcb..7fe5da3c932e 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c | |||
@@ -422,7 +422,7 @@ void __init setup_bootmem_allocator(void) | |||
422 | */ | 422 | */ |
423 | reserve_bootmem(PAGE_SIZE, PAGE_SIZE); | 423 | reserve_bootmem(PAGE_SIZE, PAGE_SIZE); |
424 | #endif | 424 | #endif |
425 | #ifdef CONFIG_ACPI_SLEEP | 425 | #ifdef CONFIG_ACPI |
426 | /* | 426 | /* |
427 | * Reserve low memory region for sleep support. | 427 | * Reserve low memory region for sleep support. |
428 | */ | 428 | */ |
diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c index d574e38f0f77..f5dd85656c18 100644 --- a/arch/i386/kernel/signal.c +++ b/arch/i386/kernel/signal.c | |||
@@ -199,6 +199,13 @@ asmlinkage int sys_sigreturn(unsigned long __unused) | |||
199 | return eax; | 199 | return eax; |
200 | 200 | ||
201 | badframe: | 201 | badframe: |
202 | if (show_unhandled_signals && printk_ratelimit()) | ||
203 | printk("%s%s[%d] bad frame in sigreturn frame:%p eip:%lx" | ||
204 | " esp:%lx oeax:%lx\n", | ||
205 | current->pid > 1 ? KERN_INFO : KERN_EMERG, | ||
206 | current->comm, current->pid, frame, regs->eip, | ||
207 | regs->esp, regs->orig_eax); | ||
208 | |||
202 | force_sig(SIGSEGV, current); | 209 | force_sig(SIGSEGV, current); |
203 | return 0; | 210 | return 0; |
204 | } | 211 | } |
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 5910d3fac561..e4f61d1c6248 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c | |||
@@ -308,7 +308,7 @@ cpumask_t cpu_coregroup_map(int cpu) | |||
308 | /* representing cpus for which sibling maps can be computed */ | 308 | /* representing cpus for which sibling maps can be computed */ |
309 | static cpumask_t cpu_sibling_setup_map; | 309 | static cpumask_t cpu_sibling_setup_map; |
310 | 310 | ||
311 | void set_cpu_sibling_map(int cpu) | 311 | void __cpuinit set_cpu_sibling_map(int cpu) |
312 | { | 312 | { |
313 | int i; | 313 | int i; |
314 | struct cpuinfo_x86 *c = cpu_data; | 314 | struct cpuinfo_x86 *c = cpu_data; |
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 57772a18c394..cfffe3dd9e83 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c | |||
@@ -618,6 +618,13 @@ fastcall void __kprobes do_general_protection(struct pt_regs * regs, | |||
618 | 618 | ||
619 | current->thread.error_code = error_code; | 619 | current->thread.error_code = error_code; |
620 | current->thread.trap_no = 13; | 620 | current->thread.trap_no = 13; |
621 | if (show_unhandled_signals && unhandled_signal(current, SIGSEGV) && | ||
622 | printk_ratelimit()) | ||
623 | printk(KERN_INFO | ||
624 | "%s[%d] general protection eip:%lx esp:%lx error:%lx\n", | ||
625 | current->comm, current->pid, | ||
626 | regs->eip, regs->esp, error_code); | ||
627 | |||
621 | force_sig(SIGSEGV, current); | 628 | force_sig(SIGSEGV, current); |
622 | return; | 629 | return; |
623 | 630 | ||
@@ -768,6 +775,8 @@ static __kprobes void default_do_nmi(struct pt_regs * regs) | |||
768 | reassert_nmi(); | 775 | reassert_nmi(); |
769 | } | 776 | } |
770 | 777 | ||
778 | static int ignore_nmis; | ||
779 | |||
771 | fastcall __kprobes void do_nmi(struct pt_regs * regs, long error_code) | 780 | fastcall __kprobes void do_nmi(struct pt_regs * regs, long error_code) |
772 | { | 781 | { |
773 | int cpu; | 782 | int cpu; |
@@ -778,11 +787,24 @@ fastcall __kprobes void do_nmi(struct pt_regs * regs, long error_code) | |||
778 | 787 | ||
779 | ++nmi_count(cpu); | 788 | ++nmi_count(cpu); |
780 | 789 | ||
781 | default_do_nmi(regs); | 790 | if (!ignore_nmis) |
791 | default_do_nmi(regs); | ||
782 | 792 | ||
783 | nmi_exit(); | 793 | nmi_exit(); |
784 | } | 794 | } |
785 | 795 | ||
796 | void stop_nmi(void) | ||
797 | { | ||
798 | acpi_nmi_disable(); | ||
799 | ignore_nmis++; | ||
800 | } | ||
801 | |||
802 | void restart_nmi(void) | ||
803 | { | ||
804 | ignore_nmis--; | ||
805 | acpi_nmi_enable(); | ||
806 | } | ||
807 | |||
786 | #ifdef CONFIG_KPROBES | 808 | #ifdef CONFIG_KPROBES |
787 | fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code) | 809 | fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code) |
788 | { | 810 | { |
diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c index e92a10124935..01ffdd4964f0 100644 --- a/arch/i386/mm/fault.c +++ b/arch/i386/mm/fault.c | |||
@@ -283,6 +283,8 @@ static inline int vmalloc_fault(unsigned long address) | |||
283 | return 0; | 283 | return 0; |
284 | } | 284 | } |
285 | 285 | ||
286 | int show_unhandled_signals = 1; | ||
287 | |||
286 | /* | 288 | /* |
287 | * This routine handles page faults. It determines the address, | 289 | * This routine handles page faults. It determines the address, |
288 | * and the problem, and then passes it off to one of the appropriate | 290 | * and the problem, and then passes it off to one of the appropriate |
@@ -469,6 +471,14 @@ bad_area_nosemaphore: | |||
469 | if (is_prefetch(regs, address, error_code)) | 471 | if (is_prefetch(regs, address, error_code)) |
470 | return; | 472 | return; |
471 | 473 | ||
474 | if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && | ||
475 | printk_ratelimit()) { | ||
476 | printk("%s%s[%d]: segfault at %08lx eip %08lx " | ||
477 | "esp %08lx error %lx\n", | ||
478 | tsk->pid > 1 ? KERN_INFO : KERN_EMERG, | ||
479 | tsk->comm, tsk->pid, address, regs->eip, | ||
480 | regs->esp, error_code); | ||
481 | } | ||
472 | tsk->thread.cr2 = address; | 482 | tsk->thread.cr2 = address; |
473 | /* Kernel addresses are always protection faults */ | 483 | /* Kernel addresses are always protection faults */ |
474 | tsk->thread.error_code = error_code | (address >= TASK_SIZE); | 484 | tsk->thread.error_code = error_code | (address >= TASK_SIZE); |
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index e1a9a805c445..1b1a1e66d099 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c | |||
@@ -432,7 +432,7 @@ static void __init pagetable_init (void) | |||
432 | paravirt_pagetable_setup_done(pgd_base); | 432 | paravirt_pagetable_setup_done(pgd_base); |
433 | } | 433 | } |
434 | 434 | ||
435 | #if defined(CONFIG_SOFTWARE_SUSPEND) || defined(CONFIG_ACPI_SLEEP) | 435 | #if defined(CONFIG_SOFTWARE_SUSPEND) || defined(CONFIG_ACPI) |
436 | /* | 436 | /* |
437 | * Swap suspend & friends need this for resume because things like the intel-agp | 437 | * Swap suspend & friends need this for resume because things like the intel-agp |
438 | * driver might have split up a kernel 4MB mapping. | 438 | * driver might have split up a kernel 4MB mapping. |
@@ -800,17 +800,9 @@ void mark_rodata_ro(void) | |||
800 | unsigned long start = PFN_ALIGN(_text); | 800 | unsigned long start = PFN_ALIGN(_text); |
801 | unsigned long size = PFN_ALIGN(_etext) - start; | 801 | unsigned long size = PFN_ALIGN(_etext) - start; |
802 | 802 | ||
803 | #ifndef CONFIG_KPROBES | 803 | change_page_attr(virt_to_page(start), |
804 | #ifdef CONFIG_HOTPLUG_CPU | 804 | size >> PAGE_SHIFT, PAGE_KERNEL_RX); |
805 | /* It must still be possible to apply SMP alternatives. */ | 805 | printk("Write protecting the kernel text: %luk\n", size >> 10); |
806 | if (num_possible_cpus() <= 1) | ||
807 | #endif | ||
808 | { | ||
809 | change_page_attr(virt_to_page(start), | ||
810 | size >> PAGE_SHIFT, PAGE_KERNEL_RX); | ||
811 | printk("Write protecting the kernel text: %luk\n", size >> 10); | ||
812 | } | ||
813 | #endif | ||
814 | start += size; | 806 | start += size; |
815 | size = (unsigned long)__end_rodata - start; | 807 | size = (unsigned long)__end_rodata - start; |
816 | change_page_attr(virt_to_page(start), | 808 | change_page_attr(virt_to_page(start), |
diff --git a/arch/i386/xen/xen-head.S b/arch/i386/xen/xen-head.S index 2998d55a0017..bc71f3bc4014 100644 --- a/arch/i386/xen/xen-head.S +++ b/arch/i386/xen/xen-head.S | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <asm/boot.h> | 7 | #include <asm/boot.h> |
8 | #include <xen/interface/elfnote.h> | 8 | #include <xen/interface/elfnote.h> |
9 | 9 | ||
10 | .section .init.text | ||
10 | ENTRY(startup_xen) | 11 | ENTRY(startup_xen) |
11 | movl %esi,xen_start_info | 12 | movl %esi,xen_start_info |
12 | cld | 13 | cld |
@@ -19,6 +20,7 @@ ENTRY(hypercall_page) | |||
19 | .skip 0x1000 | 20 | .skip 0x1000 |
20 | .popsection | 21 | .popsection |
21 | 22 | ||
23 | .section .text | ||
22 | ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz "linux") | 24 | ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz "linux") |
23 | ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz "2.6") | 25 | ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz "2.6") |
24 | ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz "xen-3.0") | 26 | ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz "xen-3.0") |
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 103dd8edda71..c6ede8780ded 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c | |||
@@ -67,6 +67,8 @@ EXPORT_SYMBOL(pm_power_off); | |||
67 | unsigned int acpi_cpei_override; | 67 | unsigned int acpi_cpei_override; |
68 | unsigned int acpi_cpei_phys_cpuid; | 68 | unsigned int acpi_cpei_phys_cpuid; |
69 | 69 | ||
70 | unsigned long acpi_wakeup_address = 0; | ||
71 | |||
70 | const char __init * | 72 | const char __init * |
71 | acpi_get_sysname(void) | 73 | acpi_get_sysname(void) |
72 | { | 74 | { |
@@ -986,4 +988,21 @@ int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base) | |||
986 | 988 | ||
987 | EXPORT_SYMBOL(acpi_unregister_ioapic); | 989 | EXPORT_SYMBOL(acpi_unregister_ioapic); |
988 | 990 | ||
991 | /* | ||
992 | * acpi_save_state_mem() - save kernel state | ||
993 | * | ||
994 | * TBD when when IA64 starts to support suspend... | ||
995 | */ | ||
996 | int acpi_save_state_mem(void) { return 0; } | ||
997 | |||
998 | /* | ||
999 | * acpi_restore_state() | ||
1000 | */ | ||
1001 | void acpi_restore_state_mem(void) {} | ||
1002 | |||
1003 | /* | ||
1004 | * do_suspend_lowlevel() | ||
1005 | */ | ||
1006 | void do_suspend_lowlevel(void) {} | ||
1007 | |||
989 | #endif /* CONFIG_ACPI */ | 1008 | #endif /* CONFIG_ACPI */ |
diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c index 60d4d75f5798..2b412454cb41 100644 --- a/arch/m68k/kernel/ints.c +++ b/arch/m68k/kernel/ints.c | |||
@@ -326,6 +326,10 @@ void disable_irq(unsigned int irq) | |||
326 | 326 | ||
327 | EXPORT_SYMBOL(disable_irq); | 327 | EXPORT_SYMBOL(disable_irq); |
328 | 328 | ||
329 | void disable_irq_nosync(unsigned int irq) __attribute__((alias("disable_irq"))); | ||
330 | |||
331 | EXPORT_SYMBOL(disable_irq_nosync); | ||
332 | |||
329 | int m68k_irq_startup(unsigned int irq) | 333 | int m68k_irq_startup(unsigned int irq) |
330 | { | 334 | { |
331 | if (irq <= IRQ_AUTO_7) | 335 | if (irq <= IRQ_AUTO_7) |
diff --git a/arch/powerpc/configs/prpmc2800_defconfig b/arch/powerpc/configs/prpmc2800_defconfig index fb504a714625..858f865f2d59 100644 --- a/arch/powerpc/configs/prpmc2800_defconfig +++ b/arch/powerpc/configs/prpmc2800_defconfig | |||
@@ -48,7 +48,7 @@ CONFIG_PPC_STD_MMU_32=y | |||
48 | # CONFIG_PPC_MM_SLICES is not set | 48 | # CONFIG_PPC_MM_SLICES is not set |
49 | # CONFIG_SMP is not set | 49 | # CONFIG_SMP is not set |
50 | CONFIG_NOT_COHERENT_CACHE=y | 50 | CONFIG_NOT_COHERENT_CACHE=y |
51 | CONFIG_CONFIG_CHECK_CACHE_COHERENCY=y | 51 | CONFIG_CHECK_CACHE_COHERENCY=y |
52 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | 52 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" |
53 | 53 | ||
54 | # | 54 | # |
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 94b4a028232a..fe7d1255e11e 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c | |||
@@ -166,7 +166,7 @@ int pcibios_add_platform_entries(struct pci_dev *pdev) | |||
166 | 166 | ||
167 | } | 167 | } |
168 | 168 | ||
169 | char __init *pcibios_setup(char *str) | 169 | char __devinit *pcibios_setup(char *str) |
170 | { | 170 | { |
171 | return str; | 171 | return str; |
172 | } | 172 | } |
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index bdcd23d8d8b9..a38197b12d3e 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
@@ -1218,7 +1218,7 @@ void of_attach_node(struct device_node *np) | |||
1218 | * a reference to the node. The memory associated with the node | 1218 | * a reference to the node. The memory associated with the node |
1219 | * is not freed until its refcount goes to zero. | 1219 | * is not freed until its refcount goes to zero. |
1220 | */ | 1220 | */ |
1221 | void of_detach_node(const struct device_node *np) | 1221 | void of_detach_node(struct device_node *np) |
1222 | { | 1222 | { |
1223 | struct device_node *parent; | 1223 | struct device_node *parent; |
1224 | 1224 | ||
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index d577b71db375..087c92f2a3eb 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
@@ -284,7 +284,7 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int | |||
284 | int wait) | 284 | int wait) |
285 | { | 285 | { |
286 | cpumask_t map = CPU_MASK_NONE; | 286 | cpumask_t map = CPU_MASK_NONE; |
287 | int ret = -EBUSY; | 287 | int ret = 0; |
288 | 288 | ||
289 | if (!cpu_online(cpu)) | 289 | if (!cpu_online(cpu)) |
290 | return -EINVAL; | 290 | return -EINVAL; |
@@ -292,6 +292,11 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int | |||
292 | cpu_set(cpu, map); | 292 | cpu_set(cpu, map); |
293 | if (cpu != get_cpu()) | 293 | if (cpu != get_cpu()) |
294 | ret = smp_call_function_map(func,info,nonatomic,wait,map); | 294 | ret = smp_call_function_map(func,info,nonatomic,wait,map); |
295 | else { | ||
296 | local_irq_disable(); | ||
297 | func(info); | ||
298 | local_irq_enable(); | ||
299 | } | ||
295 | put_cpu(); | 300 | put_cpu(); |
296 | return ret; | 301 | return ret; |
297 | } | 302 | } |
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index 3767211b3d0f..ab3546c5ac3a 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c | |||
@@ -283,7 +283,13 @@ good_area: | |||
283 | /* protection fault */ | 283 | /* protection fault */ |
284 | if (error_code & DSISR_PROTFAULT) | 284 | if (error_code & DSISR_PROTFAULT) |
285 | goto bad_area; | 285 | goto bad_area; |
286 | if (!(vma->vm_flags & VM_EXEC)) | 286 | /* |
287 | * Allow execution from readable areas if the MMU does not | ||
288 | * provide separate controls over reading and executing. | ||
289 | */ | ||
290 | if (!(vma->vm_flags & VM_EXEC) && | ||
291 | (cpu_has_feature(CPU_FTR_NOEXECUTE) || | ||
292 | !(vma->vm_flags & (VM_READ | VM_WRITE)))) | ||
287 | goto bad_area; | 293 | goto bad_area; |
288 | #else | 294 | #else |
289 | pte_t *ptep; | 295 | pte_t *ptep; |
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 2ce9491b48d4..bc7b0cedae5e 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c | |||
@@ -609,7 +609,7 @@ static void demote_segment_4k(struct mm_struct *mm, unsigned long addr) | |||
609 | mm->context.sllp = SLB_VSID_USER | mmu_psize_defs[MMU_PAGE_4K].sllp; | 609 | mm->context.sllp = SLB_VSID_USER | mmu_psize_defs[MMU_PAGE_4K].sllp; |
610 | #endif /* CONFIG_PPC_MM_SLICES */ | 610 | #endif /* CONFIG_PPC_MM_SLICES */ |
611 | 611 | ||
612 | #ifdef CONFIG_SPE_BASE | 612 | #ifdef CONFIG_SPU_BASE |
613 | spu_flush_all_slbs(mm); | 613 | spu_flush_all_slbs(mm); |
614 | #endif | 614 | #endif |
615 | } | 615 | } |
@@ -744,7 +744,7 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) | |||
744 | "to 4kB pages because of " | 744 | "to 4kB pages because of " |
745 | "non-cacheable mapping\n"); | 745 | "non-cacheable mapping\n"); |
746 | psize = mmu_vmalloc_psize = MMU_PAGE_4K; | 746 | psize = mmu_vmalloc_psize = MMU_PAGE_4K; |
747 | #ifdef CONFIG_SPE_BASE | 747 | #ifdef CONFIG_SPU_BASE |
748 | spu_flush_all_slbs(mm); | 748 | spu_flush_all_slbs(mm); |
749 | #endif | 749 | #endif |
750 | } | 750 | } |
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index b8b5fde94668..e4b2aee53a73 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype | |||
@@ -215,7 +215,7 @@ config NOT_COHERENT_CACHE | |||
215 | depends on 4xx || 8xx || E200 | 215 | depends on 4xx || 8xx || E200 |
216 | default y | 216 | default y |
217 | 217 | ||
218 | config CONFIG_CHECK_CACHE_COHERENCY | 218 | config CHECK_CACHE_COHERENCY |
219 | bool | 219 | bool |
220 | 220 | ||
221 | endmenu | 221 | endmenu |
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index c2aaec5289dc..4100ddc52f02 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c | |||
@@ -941,13 +941,6 @@ static const struct file_operations spufs_signal1_nosched_fops = { | |||
941 | .mmap = spufs_signal1_mmap, | 941 | .mmap = spufs_signal1_mmap, |
942 | }; | 942 | }; |
943 | 943 | ||
944 | static const struct file_operations spufs_signal1_nosched_fops = { | ||
945 | .open = spufs_signal1_open, | ||
946 | .release = spufs_signal1_release, | ||
947 | .write = spufs_signal1_write, | ||
948 | .mmap = spufs_signal1_mmap, | ||
949 | }; | ||
950 | |||
951 | static int spufs_signal2_open(struct inode *inode, struct file *file) | 944 | static int spufs_signal2_open(struct inode *inode, struct file *file) |
952 | { | 945 | { |
953 | struct spufs_inode_info *i = SPUFS_I(inode); | 946 | struct spufs_inode_info *i = SPUFS_I(inode); |
@@ -1083,13 +1076,6 @@ static const struct file_operations spufs_signal2_nosched_fops = { | |||
1083 | .mmap = spufs_signal2_mmap, | 1076 | .mmap = spufs_signal2_mmap, |
1084 | }; | 1077 | }; |
1085 | 1078 | ||
1086 | static const struct file_operations spufs_signal2_nosched_fops = { | ||
1087 | .open = spufs_signal2_open, | ||
1088 | .release = spufs_signal2_release, | ||
1089 | .write = spufs_signal2_write, | ||
1090 | .mmap = spufs_signal2_mmap, | ||
1091 | }; | ||
1092 | |||
1093 | static void spufs_signal1_type_set(void *data, u64 val) | 1079 | static void spufs_signal1_type_set(void *data, u64 val) |
1094 | { | 1080 | { |
1095 | struct spu_context *ctx = data; | 1081 | struct spu_context *ctx = data; |
diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig index bec772674e40..2d12f77e46bc 100644 --- a/arch/powerpc/platforms/embedded6xx/Kconfig +++ b/arch/powerpc/platforms/embedded6xx/Kconfig | |||
@@ -59,7 +59,7 @@ config MPC10X_BRIDGE | |||
59 | config MV64X60 | 59 | config MV64X60 |
60 | bool | 60 | bool |
61 | select PPC_INDIRECT_PCI | 61 | select PPC_INDIRECT_PCI |
62 | select CONFIG_CHECK_CACHE_COHERENCY | 62 | select CHECK_CACHE_COHERENCY |
63 | 63 | ||
64 | config MPC10X_OPENPIC | 64 | config MPC10X_OPENPIC |
65 | bool | 65 | bool |
diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c index 29bf83bfb1f0..8b18a1c40092 100644 --- a/arch/powerpc/platforms/pseries/firmware.c +++ b/arch/powerpc/platforms/pseries/firmware.c | |||
@@ -66,24 +66,13 @@ firmware_features_table[FIRMWARE_MAX_FEATURES] = { | |||
66 | * device-tree/ibm,hypertas-functions. Ultimately this functionality may | 66 | * device-tree/ibm,hypertas-functions. Ultimately this functionality may |
67 | * be moved into prom.c prom_init(). | 67 | * be moved into prom.c prom_init(). |
68 | */ | 68 | */ |
69 | void __init fw_feature_init(void) | 69 | void __init fw_feature_init(const char *hypertas, unsigned long len) |
70 | { | 70 | { |
71 | struct device_node *dn; | 71 | const char *s; |
72 | const char *hypertas, *s; | 72 | int i; |
73 | int len, i; | ||
74 | 73 | ||
75 | DBG(" -> fw_feature_init()\n"); | 74 | DBG(" -> fw_feature_init()\n"); |
76 | 75 | ||
77 | dn = of_find_node_by_path("/rtas"); | ||
78 | if (dn == NULL) { | ||
79 | printk(KERN_ERR "WARNING! Cannot find RTAS in device-tree!\n"); | ||
80 | goto out; | ||
81 | } | ||
82 | |||
83 | hypertas = of_get_property(dn, "ibm,hypertas-functions", &len); | ||
84 | if (hypertas == NULL) | ||
85 | goto out; | ||
86 | |||
87 | for (s = hypertas; s < hypertas + len; s += strlen(s) + 1) { | 76 | for (s = hypertas; s < hypertas + len; s += strlen(s) + 1) { |
88 | for (i = 0; i < FIRMWARE_MAX_FEATURES; i++) { | 77 | for (i = 0; i < FIRMWARE_MAX_FEATURES; i++) { |
89 | /* check value against table of strings */ | 78 | /* check value against table of strings */ |
@@ -98,7 +87,5 @@ void __init fw_feature_init(void) | |||
98 | } | 87 | } |
99 | } | 88 | } |
100 | 89 | ||
101 | out: | ||
102 | of_node_put(dn); | ||
103 | DBG(" <- fw_feature_init()\n"); | 90 | DBG(" <- fw_feature_init()\n"); |
104 | } | 91 | } |
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h index 61e19f78b923..61136d019554 100644 --- a/arch/powerpc/platforms/pseries/pseries.h +++ b/arch/powerpc/platforms/pseries/pseries.h | |||
@@ -10,7 +10,7 @@ | |||
10 | #ifndef _PSERIES_PSERIES_H | 10 | #ifndef _PSERIES_PSERIES_H |
11 | #define _PSERIES_PSERIES_H | 11 | #define _PSERIES_PSERIES_H |
12 | 12 | ||
13 | extern void __init fw_feature_init(void); | 13 | extern void __init fw_feature_init(const char *hypertas, unsigned long len); |
14 | 14 | ||
15 | struct pt_regs; | 15 | struct pt_regs; |
16 | 16 | ||
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 59e69f085cb4..f0b7146a110f 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c | |||
@@ -320,8 +320,6 @@ static void __init pSeries_init_early(void) | |||
320 | { | 320 | { |
321 | DBG(" -> pSeries_init_early()\n"); | 321 | DBG(" -> pSeries_init_early()\n"); |
322 | 322 | ||
323 | fw_feature_init(); | ||
324 | |||
325 | if (firmware_has_feature(FW_FEATURE_LPAR)) | 323 | if (firmware_has_feature(FW_FEATURE_LPAR)) |
326 | find_udbg_vterm(); | 324 | find_udbg_vterm(); |
327 | 325 | ||
@@ -343,14 +341,21 @@ static int __init pSeries_probe_hypertas(unsigned long node, | |||
343 | const char *uname, int depth, | 341 | const char *uname, int depth, |
344 | void *data) | 342 | void *data) |
345 | { | 343 | { |
344 | const char *hypertas; | ||
345 | unsigned long len; | ||
346 | |||
346 | if (depth != 1 || | 347 | if (depth != 1 || |
347 | (strcmp(uname, "rtas") != 0 && strcmp(uname, "rtas@0") != 0)) | 348 | (strcmp(uname, "rtas") != 0 && strcmp(uname, "rtas@0") != 0)) |
348 | return 0; | 349 | return 0; |
350 | |||
351 | hypertas = of_get_flat_dt_prop(node, "ibm,hypertas-functions", &len); | ||
352 | if (!hypertas) | ||
353 | return 1; | ||
349 | 354 | ||
350 | if (of_get_flat_dt_prop(node, "ibm,hypertas-functions", NULL) != NULL) | 355 | powerpc_firmware_features |= FW_FEATURE_LPAR; |
351 | powerpc_firmware_features |= FW_FEATURE_LPAR; | 356 | fw_feature_init(hypertas, len); |
352 | 357 | ||
353 | return 1; | 358 | return 1; |
354 | } | 359 | } |
355 | 360 | ||
356 | static int __init pSeries_probe(void) | 361 | static int __init pSeries_probe(void) |
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 75aad38179f0..74c64c0d3b71 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c | |||
@@ -877,6 +877,8 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq, | |||
877 | 877 | ||
878 | if (hw == mpic->spurious_vec) | 878 | if (hw == mpic->spurious_vec) |
879 | return -EINVAL; | 879 | return -EINVAL; |
880 | if (mpic->protected && test_bit(hw, mpic->protected)) | ||
881 | return -EINVAL; | ||
880 | 882 | ||
881 | #ifdef CONFIG_SMP | 883 | #ifdef CONFIG_SMP |
882 | else if (hw >= mpic->ipi_vecs[0]) { | 884 | else if (hw >= mpic->ipi_vecs[0]) { |
@@ -1034,6 +1036,25 @@ struct mpic * __init mpic_alloc(struct device_node *node, | |||
1034 | if (node && of_get_property(node, "big-endian", NULL) != NULL) | 1036 | if (node && of_get_property(node, "big-endian", NULL) != NULL) |
1035 | mpic->flags |= MPIC_BIG_ENDIAN; | 1037 | mpic->flags |= MPIC_BIG_ENDIAN; |
1036 | 1038 | ||
1039 | /* Look for protected sources */ | ||
1040 | if (node) { | ||
1041 | unsigned int psize, bits, mapsize; | ||
1042 | const u32 *psrc = | ||
1043 | of_get_property(node, "protected-sources", &psize); | ||
1044 | if (psrc) { | ||
1045 | psize /= 4; | ||
1046 | bits = intvec_top + 1; | ||
1047 | mapsize = BITS_TO_LONGS(bits) * sizeof(unsigned long); | ||
1048 | mpic->protected = alloc_bootmem(mapsize); | ||
1049 | BUG_ON(mpic->protected == NULL); | ||
1050 | memset(mpic->protected, 0, mapsize); | ||
1051 | for (i = 0; i < psize; i++) { | ||
1052 | if (psrc[i] > intvec_top) | ||
1053 | continue; | ||
1054 | __set_bit(psrc[i], mpic->protected); | ||
1055 | } | ||
1056 | } | ||
1057 | } | ||
1037 | 1058 | ||
1038 | #ifdef CONFIG_MPIC_WEIRD | 1059 | #ifdef CONFIG_MPIC_WEIRD |
1039 | mpic->hw_set = mpic_infos[MPIC_GET_REGSET(flags)]; | 1060 | mpic->hw_set = mpic_infos[MPIC_GET_REGSET(flags)]; |
@@ -1213,6 +1234,9 @@ void __init mpic_init(struct mpic *mpic) | |||
1213 | u32 vecpri = MPIC_VECPRI_MASK | i | | 1234 | u32 vecpri = MPIC_VECPRI_MASK | i | |
1214 | (8 << MPIC_VECPRI_PRIORITY_SHIFT); | 1235 | (8 << MPIC_VECPRI_PRIORITY_SHIFT); |
1215 | 1236 | ||
1237 | /* check if protected */ | ||
1238 | if (mpic->protected && test_bit(i, mpic->protected)) | ||
1239 | continue; | ||
1216 | /* init hw */ | 1240 | /* init hw */ |
1217 | mpic_irq_write(i, MPIC_INFO(IRQ_VECTOR_PRI), vecpri); | 1241 | mpic_irq_write(i, MPIC_INFO(IRQ_VECTOR_PRI), vecpri); |
1218 | mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION), | 1242 | mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION), |
@@ -1407,6 +1431,14 @@ unsigned int mpic_get_one_irq(struct mpic *mpic) | |||
1407 | mpic_eoi(mpic); | 1431 | mpic_eoi(mpic); |
1408 | return NO_IRQ; | 1432 | return NO_IRQ; |
1409 | } | 1433 | } |
1434 | if (unlikely(mpic->protected && test_bit(src, mpic->protected))) { | ||
1435 | if (printk_ratelimit()) | ||
1436 | printk(KERN_WARNING "%s: Got protected source %d !\n", | ||
1437 | mpic->name, (int)src); | ||
1438 | mpic_eoi(mpic); | ||
1439 | return NO_IRQ; | ||
1440 | } | ||
1441 | |||
1410 | return irq_linear_revmap(mpic->irqhost, src); | 1442 | return irq_linear_revmap(mpic->irqhost, src); |
1411 | } | 1443 | } |
1412 | 1444 | ||
diff --git a/arch/powerpc/xmon/nonstdio.c b/arch/powerpc/xmon/nonstdio.c index 78765833f4c0..bfac84fbe780 100644 --- a/arch/powerpc/xmon/nonstdio.c +++ b/arch/powerpc/xmon/nonstdio.c | |||
@@ -132,3 +132,8 @@ void xmon_printf(const char *format, ...) | |||
132 | va_end(args); | 132 | va_end(args); |
133 | xmon_write(xmon_outbuf, n); | 133 | xmon_write(xmon_outbuf, n); |
134 | } | 134 | } |
135 | |||
136 | void xmon_puts(const char *str) | ||
137 | { | ||
138 | xmon_write(str, strlen(str)); | ||
139 | } | ||
diff --git a/arch/powerpc/xmon/nonstdio.h b/arch/powerpc/xmon/nonstdio.h index 47cebbd2b1b1..23dd95f4599c 100644 --- a/arch/powerpc/xmon/nonstdio.h +++ b/arch/powerpc/xmon/nonstdio.h | |||
@@ -5,10 +5,11 @@ | |||
5 | 5 | ||
6 | extern int xmon_putchar(int c); | 6 | extern int xmon_putchar(int c); |
7 | extern int xmon_getchar(void); | 7 | extern int xmon_getchar(void); |
8 | extern void xmon_puts(const char *); | ||
8 | extern char *xmon_gets(char *, int); | 9 | extern char *xmon_gets(char *, int); |
9 | extern void xmon_printf(const char *, ...); | 10 | extern void xmon_printf(const char *, ...); |
10 | extern void xmon_map_scc(void); | 11 | extern void xmon_map_scc(void); |
11 | extern int xmon_expect(const char *str, unsigned long timeout); | 12 | extern int xmon_expect(const char *str, unsigned long timeout); |
12 | extern int xmon_write(void *ptr, int nb); | 13 | extern int xmon_write(const void *ptr, int nb); |
13 | extern int xmon_readchar(void); | 14 | extern int xmon_readchar(void); |
14 | extern int xmon_read_poll(void); | 15 | extern int xmon_read_poll(void); |
diff --git a/arch/powerpc/xmon/start.c b/arch/powerpc/xmon/start.c index 712552c4f242..8864de2af382 100644 --- a/arch/powerpc/xmon/start.c +++ b/arch/powerpc/xmon/start.c | |||
@@ -14,7 +14,7 @@ void xmon_map_scc(void) | |||
14 | { | 14 | { |
15 | } | 15 | } |
16 | 16 | ||
17 | int xmon_write(void *ptr, int nb) | 17 | int xmon_write(const void *ptr, int nb) |
18 | { | 18 | { |
19 | return udbg_write(ptr, nb); | 19 | return udbg_write(ptr, nb); |
20 | } | 20 | } |
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 669e6566ad70..121b04d165d1 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c | |||
@@ -833,7 +833,7 @@ cmds(struct pt_regs *excp) | |||
833 | mdelay(2000); | 833 | mdelay(2000); |
834 | return cmd; | 834 | return cmd; |
835 | case '?': | 835 | case '?': |
836 | printf(help_string); | 836 | xmon_puts(help_string); |
837 | break; | 837 | break; |
838 | case 'b': | 838 | case 'b': |
839 | bpt_cmds(); | 839 | bpt_cmds(); |
diff --git a/arch/ppc/syslib/mv64x60.c b/arch/ppc/syslib/mv64x60.c index 032f4b7f4225..d212b1c418a9 100644 --- a/arch/ppc/syslib/mv64x60.c +++ b/arch/ppc/syslib/mv64x60.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/pci.h> | 14 | #include <linux/pci.h> |
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/mutex.h> | ||
17 | #include <linux/string.h> | 18 | #include <linux/string.h> |
18 | #include <linux/spinlock.h> | 19 | #include <linux/spinlock.h> |
19 | #include <linux/mv643xx.h> | 20 | #include <linux/mv643xx.h> |
@@ -2359,7 +2360,7 @@ mv64460_chip_specific_init(struct mv64x60_handle *bh, | |||
2359 | /* Export the hotswap register via sysfs for enum event monitoring */ | 2360 | /* Export the hotswap register via sysfs for enum event monitoring */ |
2360 | #define VAL_LEN_MAX 11 /* 32-bit hex or dec stringified number + '\n' */ | 2361 | #define VAL_LEN_MAX 11 /* 32-bit hex or dec stringified number + '\n' */ |
2361 | 2362 | ||
2362 | DECLARE_MUTEX(mv64xxx_hs_lock); | 2363 | static DEFINE_MUTEX(mv64xxx_hs_lock); |
2363 | 2364 | ||
2364 | static ssize_t | 2365 | static ssize_t |
2365 | mv64xxx_hs_reg_read(struct kobject *kobj, char *buf, loff_t off, size_t count) | 2366 | mv64xxx_hs_reg_read(struct kobject *kobj, char *buf, loff_t off, size_t count) |
@@ -2372,14 +2373,14 @@ mv64xxx_hs_reg_read(struct kobject *kobj, char *buf, loff_t off, size_t count) | |||
2372 | if (count < VAL_LEN_MAX) | 2373 | if (count < VAL_LEN_MAX) |
2373 | return -EINVAL; | 2374 | return -EINVAL; |
2374 | 2375 | ||
2375 | if (down_interruptible(&mv64xxx_hs_lock)) | 2376 | if (mutex_lock_interruptible(&mv64xxx_hs_lock)) |
2376 | return -ERESTARTSYS; | 2377 | return -ERESTARTSYS; |
2377 | save_exclude = mv64x60_pci_exclude_bridge; | 2378 | save_exclude = mv64x60_pci_exclude_bridge; |
2378 | mv64x60_pci_exclude_bridge = 0; | 2379 | mv64x60_pci_exclude_bridge = 0; |
2379 | early_read_config_dword(&sysfs_hose_a, 0, PCI_DEVFN(0, 0), | 2380 | early_read_config_dword(&sysfs_hose_a, 0, PCI_DEVFN(0, 0), |
2380 | MV64360_PCICFG_CPCI_HOTSWAP, &v); | 2381 | MV64360_PCICFG_CPCI_HOTSWAP, &v); |
2381 | mv64x60_pci_exclude_bridge = save_exclude; | 2382 | mv64x60_pci_exclude_bridge = save_exclude; |
2382 | up(&mv64xxx_hs_lock); | 2383 | mutex_unlock(&mv64xxx_hs_lock); |
2383 | 2384 | ||
2384 | return sprintf(buf, "0x%08x\n", v); | 2385 | return sprintf(buf, "0x%08x\n", v); |
2385 | } | 2386 | } |
@@ -2396,14 +2397,14 @@ mv64xxx_hs_reg_write(struct kobject *kobj, char *buf, loff_t off, size_t count) | |||
2396 | return -EINVAL; | 2397 | return -EINVAL; |
2397 | 2398 | ||
2398 | if (sscanf(buf, "%i", &v) == 1) { | 2399 | if (sscanf(buf, "%i", &v) == 1) { |
2399 | if (down_interruptible(&mv64xxx_hs_lock)) | 2400 | if (mutex_lock_interruptible(&mv64xxx_hs_lock)) |
2400 | return -ERESTARTSYS; | 2401 | return -ERESTARTSYS; |
2401 | save_exclude = mv64x60_pci_exclude_bridge; | 2402 | save_exclude = mv64x60_pci_exclude_bridge; |
2402 | mv64x60_pci_exclude_bridge = 0; | 2403 | mv64x60_pci_exclude_bridge = 0; |
2403 | early_write_config_dword(&sysfs_hose_a, 0, PCI_DEVFN(0, 0), | 2404 | early_write_config_dword(&sysfs_hose_a, 0, PCI_DEVFN(0, 0), |
2404 | MV64360_PCICFG_CPCI_HOTSWAP, v); | 2405 | MV64360_PCICFG_CPCI_HOTSWAP, v); |
2405 | mv64x60_pci_exclude_bridge = save_exclude; | 2406 | mv64x60_pci_exclude_bridge = save_exclude; |
2406 | up(&mv64xxx_hs_lock); | 2407 | mutex_unlock(&mv64xxx_hs_lock); |
2407 | } | 2408 | } |
2408 | else | 2409 | else |
2409 | count = -EINVAL; | 2410 | count = -EINVAL; |
@@ -2433,10 +2434,10 @@ mv64xxx_hs_reg_valid_show(struct device *dev, struct device_attribute *attr, | |||
2433 | pdev = container_of(dev, struct platform_device, dev); | 2434 | pdev = container_of(dev, struct platform_device, dev); |
2434 | pdp = (struct mv64xxx_pdata *)pdev->dev.platform_data; | 2435 | pdp = (struct mv64xxx_pdata *)pdev->dev.platform_data; |
2435 | 2436 | ||
2436 | if (down_interruptible(&mv64xxx_hs_lock)) | 2437 | if (mutex_lock_interruptible(&mv64xxx_hs_lock)) |
2437 | return -ERESTARTSYS; | 2438 | return -ERESTARTSYS; |
2438 | v = pdp->hs_reg_valid; | 2439 | v = pdp->hs_reg_valid; |
2439 | up(&mv64xxx_hs_lock); | 2440 | mutex_unlock(&mv64xxx_hs_lock); |
2440 | 2441 | ||
2441 | return sprintf(buf, "%i\n", v); | 2442 | return sprintf(buf, "%i\n", v); |
2442 | } | 2443 | } |
diff --git a/arch/x86_64/boot/compressed/Makefile b/arch/x86_64/boot/compressed/Makefile index c9f2da7496c1..877c0bdbbc67 100644 --- a/arch/x86_64/boot/compressed/Makefile +++ b/arch/x86_64/boot/compressed/Makefile | |||
@@ -3,8 +3,6 @@ | |||
3 | # | 3 | # |
4 | # create a compressed vmlinux image from the original vmlinux | 4 | # create a compressed vmlinux image from the original vmlinux |
5 | # | 5 | # |
6 | # Note all the files here are compiled/linked as 32bit executables. | ||
7 | # | ||
8 | 6 | ||
9 | targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o | 7 | targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o |
10 | 8 | ||
diff --git a/arch/x86_64/kernel/acpi/Makefile b/arch/x86_64/kernel/acpi/Makefile index 080b9963f1bc..17595d23fee7 100644 --- a/arch/x86_64/kernel/acpi/Makefile +++ b/arch/x86_64/kernel/acpi/Makefile | |||
@@ -1,6 +1,6 @@ | |||
1 | obj-y := boot.o | 1 | obj-y := boot.o |
2 | boot-y := ../../../i386/kernel/acpi/boot.o | 2 | boot-y := ../../../i386/kernel/acpi/boot.o |
3 | obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup.o | 3 | obj-y += sleep.o wakeup.o |
4 | 4 | ||
5 | ifneq ($(CONFIG_ACPI_PROCESSOR),) | 5 | ifneq ($(CONFIG_ACPI_PROCESSOR),) |
6 | obj-y += processor.o | 6 | obj-y += processor.o |
diff --git a/arch/x86_64/kernel/acpi/sleep.c b/arch/x86_64/kernel/acpi/sleep.c index 4277f2b27e6d..79475d237071 100644 --- a/arch/x86_64/kernel/acpi/sleep.c +++ b/arch/x86_64/kernel/acpi/sleep.c | |||
@@ -51,8 +51,6 @@ | |||
51 | Low-Level Sleep Support | 51 | Low-Level Sleep Support |
52 | -------------------------------------------------------------------------- */ | 52 | -------------------------------------------------------------------------- */ |
53 | 53 | ||
54 | #ifdef CONFIG_ACPI_SLEEP | ||
55 | |||
56 | /* address in low memory of the wakeup routine. */ | 54 | /* address in low memory of the wakeup routine. */ |
57 | unsigned long acpi_wakeup_address = 0; | 55 | unsigned long acpi_wakeup_address = 0; |
58 | unsigned long acpi_realmode_flags; | 56 | unsigned long acpi_realmode_flags; |
@@ -117,8 +115,6 @@ static int __init acpi_sleep_setup(char *str) | |||
117 | 115 | ||
118 | __setup("acpi_sleep=", acpi_sleep_setup); | 116 | __setup("acpi_sleep=", acpi_sleep_setup); |
119 | 117 | ||
120 | #endif /*CONFIG_ACPI_SLEEP */ | ||
121 | |||
122 | void acpi_pci_link_exit(void) | 118 | void acpi_pci_link_exit(void) |
123 | { | 119 | { |
124 | } | 120 | } |
diff --git a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S index 941c84baecc8..3a16e417dd8d 100644 --- a/arch/x86_64/kernel/head.S +++ b/arch/x86_64/kernel/head.S | |||
@@ -25,7 +25,7 @@ | |||
25 | */ | 25 | */ |
26 | 26 | ||
27 | .text | 27 | .text |
28 | .section .bootstrap.text | 28 | .section .text.head |
29 | .code64 | 29 | .code64 |
30 | .globl startup_64 | 30 | .globl startup_64 |
31 | startup_64: | 31 | startup_64: |
@@ -120,7 +120,7 @@ ident_complete: | |||
120 | addq %rbp, trampoline_level4_pgt + 0(%rip) | 120 | addq %rbp, trampoline_level4_pgt + 0(%rip) |
121 | addq %rbp, trampoline_level4_pgt + (511*8)(%rip) | 121 | addq %rbp, trampoline_level4_pgt + (511*8)(%rip) |
122 | #endif | 122 | #endif |
123 | #ifdef CONFIG_ACPI_SLEEP | 123 | #ifdef CONFIG_ACPI |
124 | addq %rbp, wakeup_level4_pgt + 0(%rip) | 124 | addq %rbp, wakeup_level4_pgt + 0(%rip) |
125 | addq %rbp, wakeup_level4_pgt + (511*8)(%rip) | 125 | addq %rbp, wakeup_level4_pgt + (511*8)(%rip) |
126 | #endif | 126 | #endif |
@@ -243,10 +243,16 @@ ENTRY(secondary_startup_64) | |||
243 | lretq | 243 | lretq |
244 | 244 | ||
245 | /* SMP bootup changes these two */ | 245 | /* SMP bootup changes these two */ |
246 | #ifndef CONFIG_HOTPLUG_CPU | ||
247 | .pushsection .init.data | ||
248 | #endif | ||
246 | .align 8 | 249 | .align 8 |
247 | .globl initial_code | 250 | .globl initial_code |
248 | initial_code: | 251 | initial_code: |
249 | .quad x86_64_start_kernel | 252 | .quad x86_64_start_kernel |
253 | #ifndef CONFIG_HOTPLUG_CPU | ||
254 | .popsection | ||
255 | #endif | ||
250 | .globl init_rsp | 256 | .globl init_rsp |
251 | init_rsp: | 257 | init_rsp: |
252 | .quad init_thread_union+THREAD_SIZE-8 | 258 | .quad init_thread_union+THREAD_SIZE-8 |
diff --git a/arch/x86_64/kernel/hpet.c b/arch/x86_64/kernel/hpet.c index 636f4f9fc6bb..e2d1b912e154 100644 --- a/arch/x86_64/kernel/hpet.c +++ b/arch/x86_64/kernel/hpet.c | |||
@@ -133,7 +133,7 @@ struct clocksource clocksource_hpet = { | |||
133 | .vread = vread_hpet, | 133 | .vread = vread_hpet, |
134 | }; | 134 | }; |
135 | 135 | ||
136 | int hpet_arch_init(void) | 136 | int __init hpet_arch_init(void) |
137 | { | 137 | { |
138 | unsigned int id; | 138 | unsigned int id; |
139 | u64 tmp; | 139 | u64 tmp; |
diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c index d4a0d0ac9935..a30e004682e2 100644 --- a/arch/x86_64/kernel/kprobes.c +++ b/arch/x86_64/kernel/kprobes.c | |||
@@ -39,9 +39,9 @@ | |||
39 | #include <linux/module.h> | 39 | #include <linux/module.h> |
40 | #include <linux/kdebug.h> | 40 | #include <linux/kdebug.h> |
41 | 41 | ||
42 | #include <asm/cacheflush.h> | ||
43 | #include <asm/pgtable.h> | 42 | #include <asm/pgtable.h> |
44 | #include <asm/uaccess.h> | 43 | #include <asm/uaccess.h> |
44 | #include <asm/alternative.h> | ||
45 | 45 | ||
46 | void jprobe_return_end(void); | 46 | void jprobe_return_end(void); |
47 | static void __kprobes arch_copy_kprobe(struct kprobe *p); | 47 | static void __kprobes arch_copy_kprobe(struct kprobe *p); |
@@ -209,16 +209,12 @@ static void __kprobes arch_copy_kprobe(struct kprobe *p) | |||
209 | 209 | ||
210 | void __kprobes arch_arm_kprobe(struct kprobe *p) | 210 | void __kprobes arch_arm_kprobe(struct kprobe *p) |
211 | { | 211 | { |
212 | *p->addr = BREAKPOINT_INSTRUCTION; | 212 | text_poke(p->addr, ((unsigned char []){BREAKPOINT_INSTRUCTION}), 1); |
213 | flush_icache_range((unsigned long) p->addr, | ||
214 | (unsigned long) p->addr + sizeof(kprobe_opcode_t)); | ||
215 | } | 213 | } |
216 | 214 | ||
217 | void __kprobes arch_disarm_kprobe(struct kprobe *p) | 215 | void __kprobes arch_disarm_kprobe(struct kprobe *p) |
218 | { | 216 | { |
219 | *p->addr = p->opcode; | 217 | text_poke(p->addr, &p->opcode, 1); |
220 | flush_icache_range((unsigned long) p->addr, | ||
221 | (unsigned long) p->addr + sizeof(kprobe_opcode_t)); | ||
222 | } | 218 | } |
223 | 219 | ||
224 | void __kprobes arch_remove_kprobe(struct kprobe *p) | 220 | void __kprobes arch_remove_kprobe(struct kprobe *p) |
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c index 4d8450ee3635..a66d607f5b92 100644 --- a/arch/x86_64/kernel/mce.c +++ b/arch/x86_64/kernel/mce.c | |||
@@ -667,6 +667,20 @@ static struct miscdevice mce_log_device = { | |||
667 | &mce_chrdev_ops, | 667 | &mce_chrdev_ops, |
668 | }; | 668 | }; |
669 | 669 | ||
670 | static unsigned long old_cr4 __initdata; | ||
671 | |||
672 | void __init stop_mce(void) | ||
673 | { | ||
674 | old_cr4 = read_cr4(); | ||
675 | clear_in_cr4(X86_CR4_MCE); | ||
676 | } | ||
677 | |||
678 | void __init restart_mce(void) | ||
679 | { | ||
680 | if (old_cr4 & X86_CR4_MCE) | ||
681 | set_in_cr4(X86_CR4_MCE); | ||
682 | } | ||
683 | |||
670 | /* | 684 | /* |
671 | * Old style boot options parsing. Only for compatibility. | 685 | * Old style boot options parsing. Only for compatibility. |
672 | */ | 686 | */ |
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c index edbbc59b7523..cb8ee9d02f86 100644 --- a/arch/x86_64/kernel/nmi.c +++ b/arch/x86_64/kernel/nmi.c | |||
@@ -384,11 +384,14 @@ int __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) | |||
384 | return rc; | 384 | return rc; |
385 | } | 385 | } |
386 | 386 | ||
387 | static unsigned ignore_nmis; | ||
388 | |||
387 | asmlinkage __kprobes void do_nmi(struct pt_regs * regs, long error_code) | 389 | asmlinkage __kprobes void do_nmi(struct pt_regs * regs, long error_code) |
388 | { | 390 | { |
389 | nmi_enter(); | 391 | nmi_enter(); |
390 | add_pda(__nmi_count,1); | 392 | add_pda(__nmi_count,1); |
391 | default_do_nmi(regs); | 393 | if (!ignore_nmis) |
394 | default_do_nmi(regs); | ||
392 | nmi_exit(); | 395 | nmi_exit(); |
393 | } | 396 | } |
394 | 397 | ||
@@ -401,6 +404,18 @@ int do_nmi_callback(struct pt_regs * regs, int cpu) | |||
401 | return 0; | 404 | return 0; |
402 | } | 405 | } |
403 | 406 | ||
407 | void stop_nmi(void) | ||
408 | { | ||
409 | acpi_nmi_disable(); | ||
410 | ignore_nmis++; | ||
411 | } | ||
412 | |||
413 | void restart_nmi(void) | ||
414 | { | ||
415 | ignore_nmis--; | ||
416 | acpi_nmi_enable(); | ||
417 | } | ||
418 | |||
404 | #ifdef CONFIG_SYSCTL | 419 | #ifdef CONFIG_SYSCTL |
405 | 420 | ||
406 | static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu) | 421 | static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu) |
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c index 92fade4a62cf..e7ac629d4c46 100644 --- a/arch/x86_64/kernel/process.c +++ b/arch/x86_64/kernel/process.c | |||
@@ -342,10 +342,10 @@ void __show_regs(struct pt_regs * regs) | |||
342 | rdmsrl(MSR_GS_BASE, gs); | 342 | rdmsrl(MSR_GS_BASE, gs); |
343 | rdmsrl(MSR_KERNEL_GS_BASE, shadowgs); | 343 | rdmsrl(MSR_KERNEL_GS_BASE, shadowgs); |
344 | 344 | ||
345 | asm("movq %%cr0, %0": "=r" (cr0)); | 345 | cr0 = read_cr0(); |
346 | asm("movq %%cr2, %0": "=r" (cr2)); | 346 | cr2 = read_cr2(); |
347 | asm("movq %%cr3, %0": "=r" (cr3)); | 347 | cr3 = read_cr3(); |
348 | asm("movq %%cr4, %0": "=r" (cr4)); | 348 | cr4 = read_cr4(); |
349 | 349 | ||
350 | printk("FS: %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n", | 350 | printk("FS: %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n", |
351 | fs,fsindex,gs,gsindex,shadowgs); | 351 | fs,fsindex,gs,gsindex,shadowgs); |
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 6fa0a302e2aa..0f400f3c4694 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c | |||
@@ -333,7 +333,7 @@ void __init setup_arch(char **cmdline_p) | |||
333 | reserve_bootmem_generic(SMP_TRAMPOLINE_BASE, 2*PAGE_SIZE); | 333 | reserve_bootmem_generic(SMP_TRAMPOLINE_BASE, 2*PAGE_SIZE); |
334 | #endif | 334 | #endif |
335 | 335 | ||
336 | #ifdef CONFIG_ACPI_SLEEP | 336 | #ifdef CONFIG_ACPI |
337 | /* | 337 | /* |
338 | * Reserve low memory region for sleep support. | 338 | * Reserve low memory region for sleep support. |
339 | */ | 339 | */ |
@@ -608,6 +608,9 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) | |||
608 | else | 608 | else |
609 | num_cache_leaves = 3; | 609 | num_cache_leaves = 3; |
610 | 610 | ||
611 | if (c->x86 == 0xf || c->x86 == 0x10 || c->x86 == 0x11) | ||
612 | set_bit(X86_FEATURE_K8, &c->x86_capability); | ||
613 | |||
611 | /* RDTSC can be speculated around */ | 614 | /* RDTSC can be speculated around */ |
612 | clear_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); | 615 | clear_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); |
613 | 616 | ||
diff --git a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c index 4886afcd6287..739175b01e06 100644 --- a/arch/x86_64/kernel/signal.c +++ b/arch/x86_64/kernel/signal.c | |||
@@ -487,7 +487,7 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) | |||
487 | void signal_fault(struct pt_regs *regs, void __user *frame, char *where) | 487 | void signal_fault(struct pt_regs *regs, void __user *frame, char *where) |
488 | { | 488 | { |
489 | struct task_struct *me = current; | 489 | struct task_struct *me = current; |
490 | if (exception_trace) | 490 | if (show_unhandled_signals && printk_ratelimit()) |
491 | printk("%s[%d] bad frame in %s frame:%p rip:%lx rsp:%lx orax:%lx\n", | 491 | printk("%s[%d] bad frame in %s frame:%p rip:%lx rsp:%lx orax:%lx\n", |
492 | me->comm,me->pid,where,frame,regs->rip,regs->rsp,regs->orig_rax); | 492 | me->comm,me->pid,where,frame,regs->rip,regs->rsp,regs->orig_rax); |
493 | 493 | ||
diff --git a/arch/x86_64/kernel/suspend.c b/arch/x86_64/kernel/suspend.c index 6a5a98f2a75c..ea83a9f91965 100644 --- a/arch/x86_64/kernel/suspend.c +++ b/arch/x86_64/kernel/suspend.c | |||
@@ -55,11 +55,11 @@ void __save_processor_state(struct saved_context *ctxt) | |||
55 | * control registers | 55 | * control registers |
56 | */ | 56 | */ |
57 | rdmsrl(MSR_EFER, ctxt->efer); | 57 | rdmsrl(MSR_EFER, ctxt->efer); |
58 | asm volatile ("movq %%cr0, %0" : "=r" (ctxt->cr0)); | 58 | ctxt->cr0 = read_cr0(); |
59 | asm volatile ("movq %%cr2, %0" : "=r" (ctxt->cr2)); | 59 | ctxt->cr2 = read_cr2(); |
60 | asm volatile ("movq %%cr3, %0" : "=r" (ctxt->cr3)); | 60 | ctxt->cr3 = read_cr3(); |
61 | asm volatile ("movq %%cr4, %0" : "=r" (ctxt->cr4)); | 61 | ctxt->cr4 = read_cr4(); |
62 | asm volatile ("movq %%cr8, %0" : "=r" (ctxt->cr8)); | 62 | ctxt->cr8 = read_cr8(); |
63 | } | 63 | } |
64 | 64 | ||
65 | void save_processor_state(void) | 65 | void save_processor_state(void) |
@@ -81,11 +81,11 @@ void __restore_processor_state(struct saved_context *ctxt) | |||
81 | * control registers | 81 | * control registers |
82 | */ | 82 | */ |
83 | wrmsrl(MSR_EFER, ctxt->efer); | 83 | wrmsrl(MSR_EFER, ctxt->efer); |
84 | asm volatile ("movq %0, %%cr8" :: "r" (ctxt->cr8)); | 84 | write_cr8(ctxt->cr8); |
85 | asm volatile ("movq %0, %%cr4" :: "r" (ctxt->cr4)); | 85 | write_cr4(ctxt->cr4); |
86 | asm volatile ("movq %0, %%cr3" :: "r" (ctxt->cr3)); | 86 | write_cr3(ctxt->cr3); |
87 | asm volatile ("movq %0, %%cr2" :: "r" (ctxt->cr2)); | 87 | write_cr2(ctxt->cr2); |
88 | asm volatile ("movq %0, %%cr0" :: "r" (ctxt->cr0)); | 88 | write_cr0(ctxt->cr0); |
89 | 89 | ||
90 | /* | 90 | /* |
91 | * now restore the descriptor tables to their proper values | 91 | * now restore the descriptor tables to their proper values |
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 8713ad4a4db1..03888420775d 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c | |||
@@ -584,7 +584,8 @@ static void __kprobes do_trap(int trapnr, int signr, char *str, | |||
584 | tsk->thread.error_code = error_code; | 584 | tsk->thread.error_code = error_code; |
585 | tsk->thread.trap_no = trapnr; | 585 | tsk->thread.trap_no = trapnr; |
586 | 586 | ||
587 | if (exception_trace && unhandled_signal(tsk, signr)) | 587 | if (show_unhandled_signals && unhandled_signal(tsk, signr) && |
588 | printk_ratelimit()) | ||
588 | printk(KERN_INFO | 589 | printk(KERN_INFO |
589 | "%s[%d] trap %s rip:%lx rsp:%lx error:%lx\n", | 590 | "%s[%d] trap %s rip:%lx rsp:%lx error:%lx\n", |
590 | tsk->comm, tsk->pid, str, | 591 | tsk->comm, tsk->pid, str, |
@@ -688,7 +689,8 @@ asmlinkage void __kprobes do_general_protection(struct pt_regs * regs, | |||
688 | tsk->thread.error_code = error_code; | 689 | tsk->thread.error_code = error_code; |
689 | tsk->thread.trap_no = 13; | 690 | tsk->thread.trap_no = 13; |
690 | 691 | ||
691 | if (exception_trace && unhandled_signal(tsk, SIGSEGV)) | 692 | if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && |
693 | printk_ratelimit()) | ||
692 | printk(KERN_INFO | 694 | printk(KERN_INFO |
693 | "%s[%d] general protection rip:%lx rsp:%lx error:%lx\n", | 695 | "%s[%d] general protection rip:%lx rsp:%lx error:%lx\n", |
694 | tsk->comm, tsk->pid, | 696 | tsk->comm, tsk->pid, |
diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S index e7a5eb6cd785..ba8ea97abd21 100644 --- a/arch/x86_64/kernel/vmlinux.lds.S +++ b/arch/x86_64/kernel/vmlinux.lds.S | |||
@@ -28,7 +28,7 @@ SECTIONS | |||
28 | _text = .; /* Text and read-only data */ | 28 | _text = .; /* Text and read-only data */ |
29 | .text : AT(ADDR(.text) - LOAD_OFFSET) { | 29 | .text : AT(ADDR(.text) - LOAD_OFFSET) { |
30 | /* First the code that has to be first for bootstrapping */ | 30 | /* First the code that has to be first for bootstrapping */ |
31 | *(.bootstrap.text) | 31 | *(.text.head) |
32 | _stext = .; | 32 | _stext = .; |
33 | /* Then the rest */ | 33 | /* Then the rest */ |
34 | TEXT_TEXT | 34 | TEXT_TEXT |
diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c index 2074bddd4f04..327c9f2fa626 100644 --- a/arch/x86_64/mm/fault.c +++ b/arch/x86_64/mm/fault.c | |||
@@ -159,7 +159,7 @@ void dump_pagetable(unsigned long address) | |||
159 | pmd_t *pmd; | 159 | pmd_t *pmd; |
160 | pte_t *pte; | 160 | pte_t *pte; |
161 | 161 | ||
162 | asm("movq %%cr3,%0" : "=r" (pgd)); | 162 | pgd = (pgd_t *)read_cr3(); |
163 | 163 | ||
164 | pgd = __va((unsigned long)pgd & PHYSICAL_PAGE_MASK); | 164 | pgd = __va((unsigned long)pgd & PHYSICAL_PAGE_MASK); |
165 | pgd += pgd_index(address); | 165 | pgd += pgd_index(address); |
@@ -221,16 +221,6 @@ static int is_errata93(struct pt_regs *regs, unsigned long address) | |||
221 | return 0; | 221 | return 0; |
222 | } | 222 | } |
223 | 223 | ||
224 | int unhandled_signal(struct task_struct *tsk, int sig) | ||
225 | { | ||
226 | if (is_init(tsk)) | ||
227 | return 1; | ||
228 | if (tsk->ptrace & PT_PTRACED) | ||
229 | return 0; | ||
230 | return (tsk->sighand->action[sig-1].sa.sa_handler == SIG_IGN) || | ||
231 | (tsk->sighand->action[sig-1].sa.sa_handler == SIG_DFL); | ||
232 | } | ||
233 | |||
234 | static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs, | 224 | static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs, |
235 | unsigned long error_code) | 225 | unsigned long error_code) |
236 | { | 226 | { |
@@ -302,7 +292,7 @@ static int vmalloc_fault(unsigned long address) | |||
302 | } | 292 | } |
303 | 293 | ||
304 | static int page_fault_trace; | 294 | static int page_fault_trace; |
305 | int exception_trace = 1; | 295 | int show_unhandled_signals = 1; |
306 | 296 | ||
307 | /* | 297 | /* |
308 | * This routine handles page faults. It determines the address, | 298 | * This routine handles page faults. It determines the address, |
@@ -326,7 +316,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, | |||
326 | prefetchw(&mm->mmap_sem); | 316 | prefetchw(&mm->mmap_sem); |
327 | 317 | ||
328 | /* get the address */ | 318 | /* get the address */ |
329 | __asm__("movq %%cr2,%0":"=r" (address)); | 319 | address = read_cr2(); |
330 | 320 | ||
331 | info.si_code = SEGV_MAPERR; | 321 | info.si_code = SEGV_MAPERR; |
332 | 322 | ||
@@ -494,7 +484,8 @@ bad_area_nosemaphore: | |||
494 | (address >> 32)) | 484 | (address >> 32)) |
495 | return; | 485 | return; |
496 | 486 | ||
497 | if (exception_trace && unhandled_signal(tsk, SIGSEGV)) { | 487 | if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && |
488 | printk_ratelimit()) { | ||
498 | printk( | 489 | printk( |
499 | "%s%s[%d]: segfault at %016lx rip %016lx rsp %016lx error %lx\n", | 490 | "%s%s[%d]: segfault at %016lx rip %016lx rsp %016lx error %lx\n", |
500 | tsk->pid > 1 ? KERN_INFO : KERN_EMERG, | 491 | tsk->pid > 1 ? KERN_INFO : KERN_EMERG, |
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index 381c2ecd407e..38f5d6368006 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c | |||
@@ -383,7 +383,7 @@ void __meminit init_memory_mapping(unsigned long start, unsigned long end) | |||
383 | } | 383 | } |
384 | 384 | ||
385 | if (!after_bootmem) | 385 | if (!after_bootmem) |
386 | asm volatile("movq %%cr4,%0" : "=r" (mmu_cr4_features)); | 386 | mmu_cr4_features = read_cr4(); |
387 | __flush_tlb_all(); | 387 | __flush_tlb_all(); |
388 | } | 388 | } |
389 | 389 | ||
@@ -600,16 +600,6 @@ void mark_rodata_ro(void) | |||
600 | { | 600 | { |
601 | unsigned long start = (unsigned long)_stext, end; | 601 | unsigned long start = (unsigned long)_stext, end; |
602 | 602 | ||
603 | #ifdef CONFIG_HOTPLUG_CPU | ||
604 | /* It must still be possible to apply SMP alternatives. */ | ||
605 | if (num_possible_cpus() > 1) | ||
606 | start = (unsigned long)_etext; | ||
607 | #endif | ||
608 | |||
609 | #ifdef CONFIG_KPROBES | ||
610 | start = (unsigned long)__start_rodata; | ||
611 | #endif | ||
612 | |||
613 | end = (unsigned long)__end_rodata; | 603 | end = (unsigned long)__end_rodata; |
614 | start = (start + PAGE_SIZE - 1) & PAGE_MASK; | 604 | start = (start + PAGE_SIZE - 1) & PAGE_MASK; |
615 | end &= PAGE_MASK; | 605 | end &= PAGE_MASK; |
@@ -697,39 +687,6 @@ int kern_addr_valid(unsigned long addr) | |||
697 | return pfn_valid(pte_pfn(*pte)); | 687 | return pfn_valid(pte_pfn(*pte)); |
698 | } | 688 | } |
699 | 689 | ||
700 | #ifdef CONFIG_SYSCTL | ||
701 | #include <linux/sysctl.h> | ||
702 | |||
703 | static ctl_table debug_table2[] = { | ||
704 | { | ||
705 | .ctl_name = 99, | ||
706 | .procname = "exception-trace", | ||
707 | .data = &exception_trace, | ||
708 | .maxlen = sizeof(int), | ||
709 | .mode = 0644, | ||
710 | .proc_handler = proc_dointvec | ||
711 | }, | ||
712 | {} | ||
713 | }; | ||
714 | |||
715 | static ctl_table debug_root_table2[] = { | ||
716 | { | ||
717 | .ctl_name = CTL_DEBUG, | ||
718 | .procname = "debug", | ||
719 | .mode = 0555, | ||
720 | .child = debug_table2 | ||
721 | }, | ||
722 | {} | ||
723 | }; | ||
724 | |||
725 | static __init int x8664_sysctl_init(void) | ||
726 | { | ||
727 | register_sysctl_table(debug_root_table2); | ||
728 | return 0; | ||
729 | } | ||
730 | __initcall(x8664_sysctl_init); | ||
731 | #endif | ||
732 | |||
733 | /* A pseudo VMA to allow ptrace access for the vsyscall page. This only | 690 | /* A pseudo VMA to allow ptrace access for the vsyscall page. This only |
734 | covers the 64bit vsyscall page now. 32bit has a real VMA now and does | 691 | covers the 64bit vsyscall page now. 32bit has a real VMA now and does |
735 | not need special handling anymore. */ | 692 | not need special handling anymore. */ |
@@ -767,7 +724,7 @@ int in_gate_area_no_task(unsigned long addr) | |||
767 | return (addr >= VSYSCALL_START) && (addr < VSYSCALL_END); | 724 | return (addr >= VSYSCALL_START) && (addr < VSYSCALL_END); |
768 | } | 725 | } |
769 | 726 | ||
770 | void *alloc_bootmem_high_node(pg_data_t *pgdat, unsigned long size) | 727 | void * __init alloc_bootmem_high_node(pg_data_t *pgdat, unsigned long size) |
771 | { | 728 | { |
772 | return __alloc_bootmem_core(pgdat->bdata, size, | 729 | return __alloc_bootmem_core(pgdat->bdata, size, |
773 | SMP_CACHE_BYTES, (4UL*1024*1024*1024), 0); | 730 | SMP_CACHE_BYTES, (4UL*1024*1024*1024), 0); |
diff --git a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c index 36377b6b8efe..7e161c698af4 100644 --- a/arch/x86_64/mm/pageattr.c +++ b/arch/x86_64/mm/pageattr.c | |||
@@ -13,7 +13,7 @@ | |||
13 | #include <asm/tlbflush.h> | 13 | #include <asm/tlbflush.h> |
14 | #include <asm/io.h> | 14 | #include <asm/io.h> |
15 | 15 | ||
16 | static inline pte_t *lookup_address(unsigned long address) | 16 | pte_t *lookup_address(unsigned long address) |
17 | { | 17 | { |
18 | pgd_t *pgd = pgd_offset_k(address); | 18 | pgd_t *pgd = pgd_offset_k(address); |
19 | pud_t *pud; | 19 | pud_t *pud; |
diff --git a/arch/x86_64/vdso/Makefile b/arch/x86_64/vdso/Makefile index faaa72fb250c..8d03de029d9b 100644 --- a/arch/x86_64/vdso/Makefile +++ b/arch/x86_64/vdso/Makefile | |||
@@ -32,10 +32,10 @@ $(obj)/vdso.o: $(src)/vdso.S $(obj)/vdso.so | |||
32 | $(obj)/vdso.so: $(src)/vdso.lds $(vobjs) FORCE | 32 | $(obj)/vdso.so: $(src)/vdso.lds $(vobjs) FORCE |
33 | $(call if_changed,syscall) | 33 | $(call if_changed,syscall) |
34 | 34 | ||
35 | CF := $(PROFILING) -mcmodel=small -fPIC -g0 -O2 -fasynchronous-unwind-tables -m64 | 35 | CFL := $(PROFILING) -mcmodel=small -fPIC -g0 -O2 -fasynchronous-unwind-tables -m64 |
36 | 36 | ||
37 | $(obj)/vclock_gettime.o: CFLAGS = $(CF) | 37 | $(obj)/vclock_gettime.o: CFLAGS = $(CFL) |
38 | $(obj)/vgetcpu.o: CFLAGS = $(CF) | 38 | $(obj)/vgetcpu.o: CFLAGS = $(CFL) |
39 | 39 | ||
40 | # We also create a special relocatable object that should mirror the symbol | 40 | # We also create a special relocatable object that should mirror the symbol |
41 | # table and layout of the linked DSO. With ld -R we can then refer to | 41 | # table and layout of the linked DSO. With ld -R we can then refer to |
diff --git a/block/Kconfig b/block/Kconfig index 0768741d6813..ca2ef4e08497 100644 --- a/block/Kconfig +++ b/block/Kconfig | |||
@@ -53,7 +53,7 @@ endif # BLOCK | |||
53 | 53 | ||
54 | config BLK_DEV_BSG | 54 | config BLK_DEV_BSG |
55 | bool "Block layer SG support v4 (EXPERIMENTAL)" | 55 | bool "Block layer SG support v4 (EXPERIMENTAL)" |
56 | depends on (SCSI=y) && EXPERIMENTAL | 56 | depends on EXPERIMENTAL |
57 | ---help--- | 57 | ---help--- |
58 | Saying Y here will enable generic SG (SCSI generic) v4 support | 58 | Saying Y here will enable generic SG (SCSI generic) v4 support |
59 | for any block device. | 59 | for any block device. |
diff --git a/block/bsg.c b/block/bsg.c index f2992e72b841..b571869928a8 100644 --- a/block/bsg.c +++ b/block/bsg.c | |||
@@ -932,24 +932,34 @@ void bsg_unregister_queue(struct request_queue *q) | |||
932 | { | 932 | { |
933 | struct bsg_class_device *bcd = &q->bsg_dev; | 933 | struct bsg_class_device *bcd = &q->bsg_dev; |
934 | 934 | ||
935 | WARN_ON(!bcd->class_dev); | 935 | if (!bcd->class_dev) |
936 | return; | ||
936 | 937 | ||
937 | mutex_lock(&bsg_mutex); | 938 | mutex_lock(&bsg_mutex); |
938 | sysfs_remove_link(&q->kobj, "bsg"); | 939 | sysfs_remove_link(&q->kobj, "bsg"); |
939 | class_device_destroy(bsg_class, MKDEV(bsg_major, bcd->minor)); | 940 | class_device_unregister(bcd->class_dev); |
941 | put_device(bcd->dev); | ||
940 | bcd->class_dev = NULL; | 942 | bcd->class_dev = NULL; |
943 | bcd->dev = NULL; | ||
941 | list_del_init(&bcd->list); | 944 | list_del_init(&bcd->list); |
942 | bsg_device_nr--; | 945 | bsg_device_nr--; |
943 | mutex_unlock(&bsg_mutex); | 946 | mutex_unlock(&bsg_mutex); |
944 | } | 947 | } |
945 | EXPORT_SYMBOL_GPL(bsg_unregister_queue); | 948 | EXPORT_SYMBOL_GPL(bsg_unregister_queue); |
946 | 949 | ||
947 | int bsg_register_queue(struct request_queue *q, const char *name) | 950 | int bsg_register_queue(struct request_queue *q, struct device *gdev, |
951 | const char *name) | ||
948 | { | 952 | { |
949 | struct bsg_class_device *bcd, *__bcd; | 953 | struct bsg_class_device *bcd, *__bcd; |
950 | dev_t dev; | 954 | dev_t dev; |
951 | int ret = -EMFILE; | 955 | int ret = -EMFILE; |
952 | struct class_device *class_dev = NULL; | 956 | struct class_device *class_dev = NULL; |
957 | const char *devname; | ||
958 | |||
959 | if (name) | ||
960 | devname = name; | ||
961 | else | ||
962 | devname = gdev->bus_id; | ||
953 | 963 | ||
954 | /* | 964 | /* |
955 | * we need a proper transport to send commands, not a stacked device | 965 | * we need a proper transport to send commands, not a stacked device |
@@ -982,18 +992,20 @@ retry: | |||
982 | bsg_minor_idx = 0; | 992 | bsg_minor_idx = 0; |
983 | 993 | ||
984 | bcd->queue = q; | 994 | bcd->queue = q; |
995 | bcd->dev = get_device(gdev); | ||
985 | dev = MKDEV(bsg_major, bcd->minor); | 996 | dev = MKDEV(bsg_major, bcd->minor); |
986 | class_dev = class_device_create(bsg_class, NULL, dev, bcd->dev, "%s", name); | 997 | class_dev = class_device_create(bsg_class, NULL, dev, gdev, "%s", |
998 | devname); | ||
987 | if (IS_ERR(class_dev)) { | 999 | if (IS_ERR(class_dev)) { |
988 | ret = PTR_ERR(class_dev); | 1000 | ret = PTR_ERR(class_dev); |
989 | goto err; | 1001 | goto err_put; |
990 | } | 1002 | } |
991 | bcd->class_dev = class_dev; | 1003 | bcd->class_dev = class_dev; |
992 | 1004 | ||
993 | if (q->kobj.sd) { | 1005 | if (q->kobj.sd) { |
994 | ret = sysfs_create_link(&q->kobj, &bcd->class_dev->kobj, "bsg"); | 1006 | ret = sysfs_create_link(&q->kobj, &bcd->class_dev->kobj, "bsg"); |
995 | if (ret) | 1007 | if (ret) |
996 | goto err; | 1008 | goto err_unregister; |
997 | } | 1009 | } |
998 | 1010 | ||
999 | list_add_tail(&bcd->list, &bsg_class_list); | 1011 | list_add_tail(&bcd->list, &bsg_class_list); |
@@ -1001,37 +1013,17 @@ retry: | |||
1001 | 1013 | ||
1002 | mutex_unlock(&bsg_mutex); | 1014 | mutex_unlock(&bsg_mutex); |
1003 | return 0; | 1015 | return 0; |
1016 | |||
1017 | err_unregister: | ||
1018 | class_device_unregister(class_dev); | ||
1019 | err_put: | ||
1020 | put_device(gdev); | ||
1004 | err: | 1021 | err: |
1005 | if (class_dev) | ||
1006 | class_device_destroy(bsg_class, MKDEV(bsg_major, bcd->minor)); | ||
1007 | mutex_unlock(&bsg_mutex); | 1022 | mutex_unlock(&bsg_mutex); |
1008 | return ret; | 1023 | return ret; |
1009 | } | 1024 | } |
1010 | EXPORT_SYMBOL_GPL(bsg_register_queue); | 1025 | EXPORT_SYMBOL_GPL(bsg_register_queue); |
1011 | 1026 | ||
1012 | static int bsg_add(struct class_device *cl_dev, struct class_interface *cl_intf) | ||
1013 | { | ||
1014 | int ret; | ||
1015 | struct scsi_device *sdp = to_scsi_device(cl_dev->dev); | ||
1016 | struct request_queue *rq = sdp->request_queue; | ||
1017 | |||
1018 | if (rq->kobj.parent) | ||
1019 | ret = bsg_register_queue(rq, kobject_name(rq->kobj.parent)); | ||
1020 | else | ||
1021 | ret = bsg_register_queue(rq, kobject_name(&sdp->sdev_gendev.kobj)); | ||
1022 | return ret; | ||
1023 | } | ||
1024 | |||
1025 | static void bsg_remove(struct class_device *cl_dev, struct class_interface *cl_intf) | ||
1026 | { | ||
1027 | bsg_unregister_queue(to_scsi_device(cl_dev->dev)->request_queue); | ||
1028 | } | ||
1029 | |||
1030 | static struct class_interface bsg_intf = { | ||
1031 | .add = bsg_add, | ||
1032 | .remove = bsg_remove, | ||
1033 | }; | ||
1034 | |||
1035 | static struct cdev bsg_cdev = { | 1027 | static struct cdev bsg_cdev = { |
1036 | .kobj = {.name = "bsg", }, | 1028 | .kobj = {.name = "bsg", }, |
1037 | .owner = THIS_MODULE, | 1029 | .owner = THIS_MODULE, |
@@ -1069,16 +1061,9 @@ static int __init bsg_init(void) | |||
1069 | if (ret) | 1061 | if (ret) |
1070 | goto unregister_chrdev; | 1062 | goto unregister_chrdev; |
1071 | 1063 | ||
1072 | ret = scsi_register_interface(&bsg_intf); | ||
1073 | if (ret) | ||
1074 | goto remove_cdev; | ||
1075 | |||
1076 | printk(KERN_INFO BSG_DESCRIPTION " version " BSG_VERSION | 1064 | printk(KERN_INFO BSG_DESCRIPTION " version " BSG_VERSION |
1077 | " loaded (major %d)\n", bsg_major); | 1065 | " loaded (major %d)\n", bsg_major); |
1078 | return 0; | 1066 | return 0; |
1079 | remove_cdev: | ||
1080 | printk(KERN_ERR "bsg: failed register scsi interface %d\n", ret); | ||
1081 | cdev_del(&bsg_cdev); | ||
1082 | unregister_chrdev: | 1067 | unregister_chrdev: |
1083 | unregister_chrdev_region(MKDEV(bsg_major, 0), BSG_MAX_DEVS); | 1068 | unregister_chrdev_region(MKDEV(bsg_major, 0), BSG_MAX_DEVS); |
1084 | destroy_bsg_class: | 1069 | destroy_bsg_class: |
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index 71bdf88884b2..d359a715bbc8 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c | |||
@@ -214,8 +214,8 @@ int blk_verify_command(unsigned char *cmd, int has_write_perm) | |||
214 | } | 214 | } |
215 | EXPORT_SYMBOL_GPL(blk_verify_command); | 215 | EXPORT_SYMBOL_GPL(blk_verify_command); |
216 | 216 | ||
217 | int blk_fill_sghdr_rq(request_queue_t *q, struct request *rq, | 217 | static int blk_fill_sghdr_rq(request_queue_t *q, struct request *rq, |
218 | struct sg_io_hdr *hdr, int has_write_perm) | 218 | struct sg_io_hdr *hdr, int has_write_perm) |
219 | { | 219 | { |
220 | memset(rq->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */ | 220 | memset(rq->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */ |
221 | 221 | ||
@@ -238,22 +238,20 @@ int blk_fill_sghdr_rq(request_queue_t *q, struct request *rq, | |||
238 | 238 | ||
239 | return 0; | 239 | return 0; |
240 | } | 240 | } |
241 | EXPORT_SYMBOL_GPL(blk_fill_sghdr_rq); | ||
242 | 241 | ||
243 | /* | 242 | /* |
244 | * unmap a request that was previously mapped to this sg_io_hdr. handles | 243 | * unmap a request that was previously mapped to this sg_io_hdr. handles |
245 | * both sg and non-sg sg_io_hdr. | 244 | * both sg and non-sg sg_io_hdr. |
246 | */ | 245 | */ |
247 | int blk_unmap_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr) | 246 | static int blk_unmap_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr) |
248 | { | 247 | { |
249 | blk_rq_unmap_user(rq->bio); | 248 | blk_rq_unmap_user(rq->bio); |
250 | blk_put_request(rq); | 249 | blk_put_request(rq); |
251 | return 0; | 250 | return 0; |
252 | } | 251 | } |
253 | EXPORT_SYMBOL_GPL(blk_unmap_sghdr_rq); | ||
254 | 252 | ||
255 | int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr, | 253 | static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr, |
256 | struct bio *bio) | 254 | struct bio *bio) |
257 | { | 255 | { |
258 | int r, ret = 0; | 256 | int r, ret = 0; |
259 | 257 | ||
@@ -287,7 +285,6 @@ int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr, | |||
287 | 285 | ||
288 | return r; | 286 | return r; |
289 | } | 287 | } |
290 | EXPORT_SYMBOL_GPL(blk_complete_sghdr_rq); | ||
291 | 288 | ||
292 | static int sg_io(struct file *file, request_queue_t *q, | 289 | static int sg_io(struct file *file, request_queue_t *q, |
293 | struct gendisk *bd_disk, struct sg_io_hdr *hdr) | 290 | struct gendisk *bd_disk, struct sg_io_hdr *hdr) |
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 139f41f033d8..251344cb29ae 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -2,19 +2,18 @@ | |||
2 | # ACPI Configuration | 2 | # ACPI Configuration |
3 | # | 3 | # |
4 | 4 | ||
5 | menu "ACPI (Advanced Configuration and Power Interface) Support" | 5 | menuconfig ACPI |
6 | bool "ACPI Support (Advanced Configuration and Power Interface) Support" | ||
6 | depends on !X86_NUMAQ | 7 | depends on !X86_NUMAQ |
7 | depends on !X86_VISWS | 8 | depends on !X86_VISWS |
8 | depends on !IA64_HP_SIM | 9 | depends on !IA64_HP_SIM |
9 | depends on IA64 || X86 | 10 | depends on IA64 || X86 |
10 | depends on PM | ||
11 | |||
12 | config ACPI | ||
13 | bool "ACPI Support" | ||
14 | depends on IA64 || X86 | ||
15 | depends on PCI | 11 | depends on PCI |
16 | depends on PM | 12 | depends on PM |
17 | select PNP | 13 | select PNP |
14 | # for sleep | ||
15 | select HOTPLUG_CPU if X86 && SMP | ||
16 | select SUSPEND_SMP if X86 && SMP | ||
18 | default y | 17 | default y |
19 | ---help--- | 18 | ---help--- |
20 | Advanced Configuration and Power Interface (ACPI) support for | 19 | Advanced Configuration and Power Interface (ACPI) support for |
@@ -46,53 +45,26 @@ config ACPI | |||
46 | 45 | ||
47 | if ACPI | 46 | if ACPI |
48 | 47 | ||
49 | config ACPI_SLEEP | 48 | config ACPI_PROCFS |
50 | bool "Sleep States" | 49 | bool "Deprecated /proc/acpi files" |
51 | depends on X86 && (!SMP || SUSPEND_SMP) | 50 | depends on PROC_FS |
52 | depends on PM | ||
53 | default y | ||
54 | ---help--- | 51 | ---help--- |
55 | This option adds support for ACPI suspend states. | 52 | For backwards compatibility, this option allows |
56 | 53 | depricated /proc/acpi/ files to exist, even when | |
57 | With this option, you will be able to put the system "to sleep". | 54 | they have been replaced by functions in /sys. |
58 | Sleep states are low power states for the system and devices. All | 55 | The deprecated files (and their replacements) include: |
59 | of the system operating state is saved to either memory or disk | ||
60 | (depending on the state), to allow the system to resume operation | ||
61 | quickly at your request. | ||
62 | |||
63 | Although this option sounds really nifty, barely any of the device | ||
64 | drivers have been converted to the new driver model and hence few | ||
65 | have proper power management support. | ||
66 | 56 | ||
67 | This option is not recommended for anyone except those doing driver | 57 | /proc/acpi/sleep (/sys/power/state) |
68 | power management development. | 58 | /proc/acpi/info (/sys/modules/acpi/parameters/acpica_version) |
69 | 59 | /proc/acpi/dsdt (/sys/firmware/acpi/tables/DSDT) | |
70 | config ACPI_SLEEP_PROC_FS | 60 | /proc/acpi/fadt (/sys/firmware/acpi/tables/FACP) |
71 | bool | 61 | /proc/acpi/debug_layer (/sys/module/acpi/parameters/debug_layer) |
72 | depends on ACPI_SLEEP && PROC_FS | 62 | /proc/acpi/debug_level (/sys/module/acpi/parameters/debug_level) |
73 | default y | ||
74 | 63 | ||
75 | config ACPI_SLEEP_PROC_SLEEP | 64 | This option has no effect on /proc/acpi/ files |
76 | bool "/proc/acpi/sleep (deprecated)" | 65 | and functions which do not yet exist in /sys. |
77 | depends on ACPI_SLEEP_PROC_FS | ||
78 | default n | ||
79 | ---help--- | ||
80 | Create /proc/acpi/sleep | ||
81 | Deprecated by /sys/power/state | ||
82 | 66 | ||
83 | config ACPI_PROCFS | 67 | Say N to delete /proc/acpi/ files that have moved to /sys/ |
84 | bool "Procfs interface (deprecated)" | ||
85 | depends on ACPI | ||
86 | default y | ||
87 | ---help--- | ||
88 | The Procfs interface for ACPI is made optional for backward compatibility. | ||
89 | As the same functions are duplicated in the sysfs interface | ||
90 | and this proc interface will be removed some time later, | ||
91 | it's marked as deprecated. | ||
92 | ( /proc/acpi/debug_layer && debug_level are deprecated by | ||
93 | /sys/module/acpi/parameters/debug_layer && debug_level. | ||
94 | /proc/acpi/info is deprecated by | ||
95 | /sys/module/acpi/parameters/acpica_version ) | ||
96 | 68 | ||
97 | config ACPI_AC | 69 | config ACPI_AC |
98 | tristate "AC Adapter" | 70 | tristate "AC Adapter" |
@@ -124,7 +96,7 @@ config ACPI_BUTTON | |||
124 | 96 | ||
125 | config ACPI_VIDEO | 97 | config ACPI_VIDEO |
126 | tristate "Video" | 98 | tristate "Video" |
127 | depends on X86 && BACKLIGHT_CLASS_DEVICE | 99 | depends on X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL |
128 | help | 100 | help |
129 | This driver implement the ACPI Extensions For Display Adapters | 101 | This driver implement the ACPI Extensions For Display Adapters |
130 | for integrated graphics devices on motherboard, as specified in | 102 | for integrated graphics devices on motherboard, as specified in |
@@ -280,6 +252,14 @@ config ACPI_DEBUG | |||
280 | of verbosity. Saying Y enables these statements. This will increase | 252 | of verbosity. Saying Y enables these statements. This will increase |
281 | your kernel size by around 50K. | 253 | your kernel size by around 50K. |
282 | 254 | ||
255 | config ACPI_DEBUG_FUNC_TRACE | ||
256 | bool "Additionally enable ACPI function tracing" | ||
257 | default n | ||
258 | depends on ACPI_DEBUG | ||
259 | help | ||
260 | ACPI Debug Statements slow down ACPI processing. Function trace | ||
261 | is about half of the penalty and is rarely useful. | ||
262 | |||
283 | config ACPI_EC | 263 | config ACPI_EC |
284 | bool | 264 | bool |
285 | default y | 265 | default y |
@@ -330,7 +310,6 @@ config ACPI_CONTAINER | |||
330 | 310 | ||
331 | config ACPI_HOTPLUG_MEMORY | 311 | config ACPI_HOTPLUG_MEMORY |
332 | tristate "Memory Hotplug" | 312 | tristate "Memory Hotplug" |
333 | depends on ACPI | ||
334 | depends on MEMORY_HOTPLUG | 313 | depends on MEMORY_HOTPLUG |
335 | default n | 314 | default n |
336 | help | 315 | help |
@@ -359,5 +338,3 @@ config ACPI_SBS | |||
359 | to today's ACPI "Control Method" battery. | 338 | to today's ACPI "Control Method" battery. |
360 | 339 | ||
361 | endif # ACPI | 340 | endif # ACPI |
362 | |||
363 | endmenu | ||
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index e64c76c8b726..cad932de383d 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -43,21 +43,30 @@ | |||
43 | #define ACPI_BATTERY_CLASS "battery" | 43 | #define ACPI_BATTERY_CLASS "battery" |
44 | #define ACPI_BATTERY_HID "PNP0C0A" | 44 | #define ACPI_BATTERY_HID "PNP0C0A" |
45 | #define ACPI_BATTERY_DEVICE_NAME "Battery" | 45 | #define ACPI_BATTERY_DEVICE_NAME "Battery" |
46 | #define ACPI_BATTERY_FILE_INFO "info" | ||
47 | #define ACPI_BATTERY_FILE_STATUS "state" | ||
48 | #define ACPI_BATTERY_FILE_ALARM "alarm" | ||
49 | #define ACPI_BATTERY_NOTIFY_STATUS 0x80 | 46 | #define ACPI_BATTERY_NOTIFY_STATUS 0x80 |
50 | #define ACPI_BATTERY_NOTIFY_INFO 0x81 | 47 | #define ACPI_BATTERY_NOTIFY_INFO 0x81 |
51 | #define ACPI_BATTERY_UNITS_WATTS "mW" | 48 | #define ACPI_BATTERY_UNITS_WATTS "mW" |
52 | #define ACPI_BATTERY_UNITS_AMPS "mA" | 49 | #define ACPI_BATTERY_UNITS_AMPS "mA" |
53 | 50 | ||
54 | #define _COMPONENT ACPI_BATTERY_COMPONENT | 51 | #define _COMPONENT ACPI_BATTERY_COMPONENT |
52 | |||
53 | #define ACPI_BATTERY_UPDATE_TIME 0 | ||
54 | |||
55 | #define ACPI_BATTERY_NONE_UPDATE 0 | ||
56 | #define ACPI_BATTERY_EASY_UPDATE 1 | ||
57 | #define ACPI_BATTERY_INIT_UPDATE 2 | ||
58 | |||
55 | ACPI_MODULE_NAME("battery"); | 59 | ACPI_MODULE_NAME("battery"); |
56 | 60 | ||
57 | MODULE_AUTHOR("Paul Diefenbaugh"); | 61 | MODULE_AUTHOR("Paul Diefenbaugh"); |
58 | MODULE_DESCRIPTION("ACPI Battery Driver"); | 62 | MODULE_DESCRIPTION("ACPI Battery Driver"); |
59 | MODULE_LICENSE("GPL"); | 63 | MODULE_LICENSE("GPL"); |
60 | 64 | ||
65 | static unsigned int update_time = ACPI_BATTERY_UPDATE_TIME; | ||
66 | |||
67 | /* 0 - every time, > 0 - by update_time */ | ||
68 | module_param(update_time, uint, 0644); | ||
69 | |||
61 | extern struct proc_dir_entry *acpi_lock_battery_dir(void); | 70 | extern struct proc_dir_entry *acpi_lock_battery_dir(void); |
62 | extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); | 71 | extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); |
63 | 72 | ||
@@ -76,7 +85,7 @@ static struct acpi_driver acpi_battery_driver = { | |||
76 | }, | 85 | }, |
77 | }; | 86 | }; |
78 | 87 | ||
79 | struct acpi_battery_status { | 88 | struct acpi_battery_state { |
80 | acpi_integer state; | 89 | acpi_integer state; |
81 | acpi_integer present_rate; | 90 | acpi_integer present_rate; |
82 | acpi_integer remaining_capacity; | 91 | acpi_integer remaining_capacity; |
@@ -99,33 +108,111 @@ struct acpi_battery_info { | |||
99 | acpi_string oem_info; | 108 | acpi_string oem_info; |
100 | }; | 109 | }; |
101 | 110 | ||
102 | struct acpi_battery_flags { | 111 | enum acpi_battery_files{ |
103 | u8 present:1; /* Bay occupied? */ | 112 | ACPI_BATTERY_INFO = 0, |
104 | u8 power_unit:1; /* 0=watts, 1=apms */ | 113 | ACPI_BATTERY_STATE, |
105 | u8 alarm:1; /* _BTP present? */ | 114 | ACPI_BATTERY_ALARM, |
106 | u8 reserved:5; | 115 | ACPI_BATTERY_NUMFILES, |
107 | }; | 116 | }; |
108 | 117 | ||
109 | struct acpi_battery_trips { | 118 | struct acpi_battery_flags { |
110 | unsigned long warning; | 119 | u8 battery_present_prev; |
111 | unsigned long low; | 120 | u8 alarm_present; |
121 | u8 init_update; | ||
122 | u8 update[ACPI_BATTERY_NUMFILES]; | ||
123 | u8 power_unit; | ||
112 | }; | 124 | }; |
113 | 125 | ||
114 | struct acpi_battery { | 126 | struct acpi_battery { |
115 | struct acpi_device * device; | 127 | struct mutex mutex; |
128 | struct acpi_device *device; | ||
116 | struct acpi_battery_flags flags; | 129 | struct acpi_battery_flags flags; |
117 | struct acpi_battery_trips trips; | 130 | struct acpi_buffer bif_data; |
131 | struct acpi_buffer bst_data; | ||
118 | unsigned long alarm; | 132 | unsigned long alarm; |
119 | struct acpi_battery_info *info; | 133 | unsigned long update_time[ACPI_BATTERY_NUMFILES]; |
120 | }; | 134 | }; |
121 | 135 | ||
136 | inline int acpi_battery_present(struct acpi_battery *battery) | ||
137 | { | ||
138 | return battery->device->status.battery_present; | ||
139 | } | ||
140 | inline char *acpi_battery_power_units(struct acpi_battery *battery) | ||
141 | { | ||
142 | if (battery->flags.power_unit) | ||
143 | return ACPI_BATTERY_UNITS_AMPS; | ||
144 | else | ||
145 | return ACPI_BATTERY_UNITS_WATTS; | ||
146 | } | ||
147 | |||
148 | inline acpi_handle acpi_battery_handle(struct acpi_battery *battery) | ||
149 | { | ||
150 | return battery->device->handle; | ||
151 | } | ||
152 | |||
122 | /* -------------------------------------------------------------------------- | 153 | /* -------------------------------------------------------------------------- |
123 | Battery Management | 154 | Battery Management |
124 | -------------------------------------------------------------------------- */ | 155 | -------------------------------------------------------------------------- */ |
125 | 156 | ||
126 | static int | 157 | static void acpi_battery_check_result(struct acpi_battery *battery, int result) |
127 | acpi_battery_get_info(struct acpi_battery *battery, | 158 | { |
128 | struct acpi_battery_info **bif) | 159 | if (!battery) |
160 | return; | ||
161 | |||
162 | if (result) { | ||
163 | battery->flags.init_update = 1; | ||
164 | } | ||
165 | } | ||
166 | |||
167 | static int acpi_battery_extract_package(struct acpi_battery *battery, | ||
168 | union acpi_object *package, | ||
169 | struct acpi_buffer *format, | ||
170 | struct acpi_buffer *data, | ||
171 | char *package_name) | ||
172 | { | ||
173 | acpi_status status = AE_OK; | ||
174 | struct acpi_buffer data_null = { 0, NULL }; | ||
175 | |||
176 | status = acpi_extract_package(package, format, &data_null); | ||
177 | if (status != AE_BUFFER_OVERFLOW) { | ||
178 | ACPI_EXCEPTION((AE_INFO, status, "Extracting size %s", | ||
179 | package_name)); | ||
180 | return -ENODEV; | ||
181 | } | ||
182 | |||
183 | if (data_null.length != data->length) { | ||
184 | kfree(data->pointer); | ||
185 | data->pointer = kzalloc(data_null.length, GFP_KERNEL); | ||
186 | if (!data->pointer) { | ||
187 | ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, "kzalloc()")); | ||
188 | return -ENOMEM; | ||
189 | } | ||
190 | data->length = data_null.length; | ||
191 | } | ||
192 | |||
193 | status = acpi_extract_package(package, format, data); | ||
194 | if (ACPI_FAILURE(status)) { | ||
195 | ACPI_EXCEPTION((AE_INFO, status, "Extracting %s", | ||
196 | package_name)); | ||
197 | return -ENODEV; | ||
198 | } | ||
199 | |||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | static int acpi_battery_get_status(struct acpi_battery *battery) | ||
204 | { | ||
205 | int result = 0; | ||
206 | |||
207 | result = acpi_bus_get_status(battery->device); | ||
208 | if (result) { | ||
209 | ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA")); | ||
210 | return -ENODEV; | ||
211 | } | ||
212 | return result; | ||
213 | } | ||
214 | |||
215 | static int acpi_battery_get_info(struct acpi_battery *battery) | ||
129 | { | 216 | { |
130 | int result = 0; | 217 | int result = 0; |
131 | acpi_status status = 0; | 218 | acpi_status status = 0; |
@@ -133,16 +220,20 @@ acpi_battery_get_info(struct acpi_battery *battery, | |||
133 | struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BIF), | 220 | struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BIF), |
134 | ACPI_BATTERY_FORMAT_BIF | 221 | ACPI_BATTERY_FORMAT_BIF |
135 | }; | 222 | }; |
136 | struct acpi_buffer data = { 0, NULL }; | ||
137 | union acpi_object *package = NULL; | 223 | union acpi_object *package = NULL; |
224 | struct acpi_buffer *data = NULL; | ||
225 | struct acpi_battery_info *bif = NULL; | ||
138 | 226 | ||
227 | battery->update_time[ACPI_BATTERY_INFO] = get_seconds(); | ||
139 | 228 | ||
140 | if (!battery || !bif) | 229 | if (!acpi_battery_present(battery)) |
141 | return -EINVAL; | 230 | return 0; |
142 | 231 | ||
143 | /* Evalute _BIF */ | 232 | /* Evaluate _BIF */ |
144 | 233 | ||
145 | status = acpi_evaluate_object(battery->device->handle, "_BIF", NULL, &buffer); | 234 | status = |
235 | acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", NULL, | ||
236 | &buffer); | ||
146 | if (ACPI_FAILURE(status)) { | 237 | if (ACPI_FAILURE(status)) { |
147 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); | 238 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); |
148 | return -ENODEV; | 239 | return -ENODEV; |
@@ -150,41 +241,29 @@ acpi_battery_get_info(struct acpi_battery *battery, | |||
150 | 241 | ||
151 | package = buffer.pointer; | 242 | package = buffer.pointer; |
152 | 243 | ||
153 | /* Extract Package Data */ | 244 | data = &battery->bif_data; |
154 | |||
155 | status = acpi_extract_package(package, &format, &data); | ||
156 | if (status != AE_BUFFER_OVERFLOW) { | ||
157 | ACPI_EXCEPTION((AE_INFO, status, "Extracting _BIF")); | ||
158 | result = -ENODEV; | ||
159 | goto end; | ||
160 | } | ||
161 | 245 | ||
162 | data.pointer = kzalloc(data.length, GFP_KERNEL); | 246 | /* Extract Package Data */ |
163 | if (!data.pointer) { | ||
164 | result = -ENOMEM; | ||
165 | goto end; | ||
166 | } | ||
167 | 247 | ||
168 | status = acpi_extract_package(package, &format, &data); | 248 | result = |
169 | if (ACPI_FAILURE(status)) { | 249 | acpi_battery_extract_package(battery, package, &format, data, |
170 | ACPI_EXCEPTION((AE_INFO, status, "Extracting _BIF")); | 250 | "_BIF"); |
171 | kfree(data.pointer); | 251 | if (result) |
172 | result = -ENODEV; | ||
173 | goto end; | 252 | goto end; |
174 | } | ||
175 | 253 | ||
176 | end: | 254 | end: |
255 | |||
177 | kfree(buffer.pointer); | 256 | kfree(buffer.pointer); |
178 | 257 | ||
179 | if (!result) | 258 | if (!result) { |
180 | (*bif) = data.pointer; | 259 | bif = data->pointer; |
260 | battery->flags.power_unit = bif->power_unit; | ||
261 | } | ||
181 | 262 | ||
182 | return result; | 263 | return result; |
183 | } | 264 | } |
184 | 265 | ||
185 | static int | 266 | static int acpi_battery_get_state(struct acpi_battery *battery) |
186 | acpi_battery_get_status(struct acpi_battery *battery, | ||
187 | struct acpi_battery_status **bst) | ||
188 | { | 267 | { |
189 | int result = 0; | 268 | int result = 0; |
190 | acpi_status status = 0; | 269 | acpi_status status = 0; |
@@ -192,16 +271,19 @@ acpi_battery_get_status(struct acpi_battery *battery, | |||
192 | struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BST), | 271 | struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BST), |
193 | ACPI_BATTERY_FORMAT_BST | 272 | ACPI_BATTERY_FORMAT_BST |
194 | }; | 273 | }; |
195 | struct acpi_buffer data = { 0, NULL }; | ||
196 | union acpi_object *package = NULL; | 274 | union acpi_object *package = NULL; |
275 | struct acpi_buffer *data = NULL; | ||
197 | 276 | ||
277 | battery->update_time[ACPI_BATTERY_STATE] = get_seconds(); | ||
198 | 278 | ||
199 | if (!battery || !bst) | 279 | if (!acpi_battery_present(battery)) |
200 | return -EINVAL; | 280 | return 0; |
201 | 281 | ||
202 | /* Evalute _BST */ | 282 | /* Evaluate _BST */ |
203 | 283 | ||
204 | status = acpi_evaluate_object(battery->device->handle, "_BST", NULL, &buffer); | 284 | status = |
285 | acpi_evaluate_object(acpi_battery_handle(battery), "_BST", NULL, | ||
286 | &buffer); | ||
205 | if (ACPI_FAILURE(status)) { | 287 | if (ACPI_FAILURE(status)) { |
206 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST")); | 288 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST")); |
207 | return -ENODEV; | 289 | return -ENODEV; |
@@ -209,55 +291,49 @@ acpi_battery_get_status(struct acpi_battery *battery, | |||
209 | 291 | ||
210 | package = buffer.pointer; | 292 | package = buffer.pointer; |
211 | 293 | ||
212 | /* Extract Package Data */ | 294 | data = &battery->bst_data; |
213 | |||
214 | status = acpi_extract_package(package, &format, &data); | ||
215 | if (status != AE_BUFFER_OVERFLOW) { | ||
216 | ACPI_EXCEPTION((AE_INFO, status, "Extracting _BST")); | ||
217 | result = -ENODEV; | ||
218 | goto end; | ||
219 | } | ||
220 | 295 | ||
221 | data.pointer = kzalloc(data.length, GFP_KERNEL); | 296 | /* Extract Package Data */ |
222 | if (!data.pointer) { | ||
223 | result = -ENOMEM; | ||
224 | goto end; | ||
225 | } | ||
226 | 297 | ||
227 | status = acpi_extract_package(package, &format, &data); | 298 | result = |
228 | if (ACPI_FAILURE(status)) { | 299 | acpi_battery_extract_package(battery, package, &format, data, |
229 | ACPI_EXCEPTION((AE_INFO, status, "Extracting _BST")); | 300 | "_BST"); |
230 | kfree(data.pointer); | 301 | if (result) |
231 | result = -ENODEV; | ||
232 | goto end; | 302 | goto end; |
233 | } | ||
234 | 303 | ||
235 | end: | 304 | end: |
236 | kfree(buffer.pointer); | 305 | kfree(buffer.pointer); |
237 | 306 | ||
238 | if (!result) | ||
239 | (*bst) = data.pointer; | ||
240 | |||
241 | return result; | 307 | return result; |
242 | } | 308 | } |
243 | 309 | ||
244 | static int | 310 | static int acpi_battery_get_alarm(struct acpi_battery *battery) |
245 | acpi_battery_set_alarm(struct acpi_battery *battery, unsigned long alarm) | 311 | { |
312 | battery->update_time[ACPI_BATTERY_ALARM] = get_seconds(); | ||
313 | |||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | static int acpi_battery_set_alarm(struct acpi_battery *battery, | ||
318 | unsigned long alarm) | ||
246 | { | 319 | { |
247 | acpi_status status = 0; | 320 | acpi_status status = 0; |
248 | union acpi_object arg0 = { ACPI_TYPE_INTEGER }; | 321 | union acpi_object arg0 = { ACPI_TYPE_INTEGER }; |
249 | struct acpi_object_list arg_list = { 1, &arg0 }; | 322 | struct acpi_object_list arg_list = { 1, &arg0 }; |
250 | 323 | ||
324 | battery->update_time[ACPI_BATTERY_ALARM] = get_seconds(); | ||
251 | 325 | ||
252 | if (!battery) | 326 | if (!acpi_battery_present(battery)) |
253 | return -EINVAL; | 327 | return -ENODEV; |
254 | 328 | ||
255 | if (!battery->flags.alarm) | 329 | if (!battery->flags.alarm_present) |
256 | return -ENODEV; | 330 | return -ENODEV; |
257 | 331 | ||
258 | arg0.integer.value = alarm; | 332 | arg0.integer.value = alarm; |
259 | 333 | ||
260 | status = acpi_evaluate_object(battery->device->handle, "_BTP", &arg_list, NULL); | 334 | status = |
335 | acpi_evaluate_object(acpi_battery_handle(battery), "_BTP", | ||
336 | &arg_list, NULL); | ||
261 | if (ACPI_FAILURE(status)) | 337 | if (ACPI_FAILURE(status)) |
262 | return -ENODEV; | 338 | return -ENODEV; |
263 | 339 | ||
@@ -268,65 +344,114 @@ acpi_battery_set_alarm(struct acpi_battery *battery, unsigned long alarm) | |||
268 | return 0; | 344 | return 0; |
269 | } | 345 | } |
270 | 346 | ||
271 | static int acpi_battery_check(struct acpi_battery *battery) | 347 | static int acpi_battery_init_alarm(struct acpi_battery *battery) |
272 | { | 348 | { |
273 | int result = 0; | 349 | int result = 0; |
274 | acpi_status status = AE_OK; | 350 | acpi_status status = AE_OK; |
275 | acpi_handle handle = NULL; | 351 | acpi_handle handle = NULL; |
276 | struct acpi_device *device = NULL; | 352 | struct acpi_battery_info *bif = battery->bif_data.pointer; |
277 | struct acpi_battery_info *bif = NULL; | 353 | unsigned long alarm = battery->alarm; |
278 | 354 | ||
355 | /* See if alarms are supported, and if so, set default */ | ||
279 | 356 | ||
280 | if (!battery) | 357 | status = acpi_get_handle(acpi_battery_handle(battery), "_BTP", &handle); |
281 | return -EINVAL; | 358 | if (ACPI_SUCCESS(status)) { |
282 | 359 | battery->flags.alarm_present = 1; | |
283 | device = battery->device; | 360 | if (!alarm && bif) { |
361 | alarm = bif->design_capacity_warning; | ||
362 | } | ||
363 | result = acpi_battery_set_alarm(battery, alarm); | ||
364 | if (result) | ||
365 | goto end; | ||
366 | } else { | ||
367 | battery->flags.alarm_present = 0; | ||
368 | } | ||
284 | 369 | ||
285 | result = acpi_bus_get_status(device); | 370 | end: |
286 | if (result) | ||
287 | return result; | ||
288 | 371 | ||
289 | /* Insertion? */ | 372 | return result; |
373 | } | ||
290 | 374 | ||
291 | if (!battery->flags.present && device->status.battery_present) { | 375 | static int acpi_battery_init_update(struct acpi_battery *battery) |
376 | { | ||
377 | int result = 0; | ||
292 | 378 | ||
293 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Battery inserted\n")); | 379 | result = acpi_battery_get_status(battery); |
380 | if (result) | ||
381 | return result; | ||
294 | 382 | ||
295 | /* Evalute _BIF to get certain static information */ | 383 | battery->flags.battery_present_prev = acpi_battery_present(battery); |
296 | 384 | ||
297 | result = acpi_battery_get_info(battery, &bif); | 385 | if (acpi_battery_present(battery)) { |
386 | result = acpi_battery_get_info(battery); | ||
387 | if (result) | ||
388 | return result; | ||
389 | result = acpi_battery_get_state(battery); | ||
298 | if (result) | 390 | if (result) |
299 | return result; | 391 | return result; |
300 | 392 | ||
301 | battery->flags.power_unit = bif->power_unit; | 393 | acpi_battery_init_alarm(battery); |
302 | battery->trips.warning = bif->design_capacity_warning; | 394 | } |
303 | battery->trips.low = bif->design_capacity_low; | 395 | |
304 | kfree(bif); | 396 | return result; |
397 | } | ||
305 | 398 | ||
306 | /* See if alarms are supported, and if so, set default */ | 399 | static int acpi_battery_update(struct acpi_battery *battery, |
400 | int update, int *update_result_ptr) | ||
401 | { | ||
402 | int result = 0; | ||
403 | int update_result = ACPI_BATTERY_NONE_UPDATE; | ||
404 | |||
405 | if (!acpi_battery_present(battery)) { | ||
406 | update = 1; | ||
407 | } | ||
307 | 408 | ||
308 | status = acpi_get_handle(battery->device->handle, "_BTP", &handle); | 409 | if (battery->flags.init_update) { |
309 | if (ACPI_SUCCESS(status)) { | 410 | result = acpi_battery_init_update(battery); |
310 | battery->flags.alarm = 1; | 411 | if (result) |
311 | acpi_battery_set_alarm(battery, battery->trips.warning); | 412 | goto end; |
413 | update_result = ACPI_BATTERY_INIT_UPDATE; | ||
414 | } else if (update) { | ||
415 | result = acpi_battery_get_status(battery); | ||
416 | if (result) | ||
417 | goto end; | ||
418 | if ((!battery->flags.battery_present_prev & acpi_battery_present(battery)) | ||
419 | || (battery->flags.battery_present_prev & !acpi_battery_present(battery))) { | ||
420 | result = acpi_battery_init_update(battery); | ||
421 | if (result) | ||
422 | goto end; | ||
423 | update_result = ACPI_BATTERY_INIT_UPDATE; | ||
424 | } else { | ||
425 | update_result = ACPI_BATTERY_EASY_UPDATE; | ||
312 | } | 426 | } |
313 | } | 427 | } |
314 | 428 | ||
315 | /* Removal? */ | 429 | end: |
316 | 430 | ||
317 | else if (battery->flags.present && !device->status.battery_present) { | 431 | battery->flags.init_update = (result != 0); |
318 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Battery removed\n")); | ||
319 | } | ||
320 | 432 | ||
321 | battery->flags.present = device->status.battery_present; | 433 | *update_result_ptr = update_result; |
322 | 434 | ||
323 | return result; | 435 | return result; |
324 | } | 436 | } |
325 | 437 | ||
326 | static void acpi_battery_check_present(struct acpi_battery *battery) | 438 | static void acpi_battery_notify_update(struct acpi_battery *battery) |
327 | { | 439 | { |
328 | if (!battery->flags.present) { | 440 | acpi_battery_get_status(battery); |
329 | acpi_battery_check(battery); | 441 | |
442 | if (battery->flags.init_update) { | ||
443 | return; | ||
444 | } | ||
445 | |||
446 | if ((!battery->flags.battery_present_prev & | ||
447 | acpi_battery_present(battery)) || | ||
448 | (battery->flags.battery_present_prev & | ||
449 | !acpi_battery_present(battery))) { | ||
450 | battery->flags.init_update = 1; | ||
451 | } else { | ||
452 | battery->flags.update[ACPI_BATTERY_INFO] = 1; | ||
453 | battery->flags.update[ACPI_BATTERY_STATE] = 1; | ||
454 | battery->flags.update[ACPI_BATTERY_ALARM] = 1; | ||
330 | } | 455 | } |
331 | } | 456 | } |
332 | 457 | ||
@@ -335,37 +460,33 @@ static void acpi_battery_check_present(struct acpi_battery *battery) | |||
335 | -------------------------------------------------------------------------- */ | 460 | -------------------------------------------------------------------------- */ |
336 | 461 | ||
337 | static struct proc_dir_entry *acpi_battery_dir; | 462 | static struct proc_dir_entry *acpi_battery_dir; |
338 | static int acpi_battery_read_info(struct seq_file *seq, void *offset) | 463 | |
464 | static int acpi_battery_print_info(struct seq_file *seq, int result) | ||
339 | { | 465 | { |
340 | int result = 0; | ||
341 | struct acpi_battery *battery = seq->private; | 466 | struct acpi_battery *battery = seq->private; |
342 | struct acpi_battery_info *bif = NULL; | 467 | struct acpi_battery_info *bif = NULL; |
343 | char *units = "?"; | 468 | char *units = "?"; |
344 | 469 | ||
345 | 470 | if (result) | |
346 | if (!battery) | ||
347 | goto end; | 471 | goto end; |
348 | 472 | ||
349 | acpi_battery_check_present(battery); | 473 | if (acpi_battery_present(battery)) |
350 | |||
351 | if (battery->flags.present) | ||
352 | seq_printf(seq, "present: yes\n"); | 474 | seq_printf(seq, "present: yes\n"); |
353 | else { | 475 | else { |
354 | seq_printf(seq, "present: no\n"); | 476 | seq_printf(seq, "present: no\n"); |
355 | goto end; | 477 | goto end; |
356 | } | 478 | } |
357 | 479 | ||
358 | /* Battery Info (_BIF) */ | 480 | bif = battery->bif_data.pointer; |
359 | 481 | if (!bif) { | |
360 | result = acpi_battery_get_info(battery, &bif); | 482 | ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BIF buffer is NULL")); |
361 | if (result || !bif) { | 483 | result = -ENODEV; |
362 | seq_printf(seq, "ERROR: Unable to read battery information\n"); | ||
363 | goto end; | 484 | goto end; |
364 | } | 485 | } |
365 | 486 | ||
366 | units = | 487 | /* Battery Units */ |
367 | bif-> | 488 | |
368 | power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS; | 489 | units = acpi_battery_power_units(battery); |
369 | 490 | ||
370 | if (bif->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN) | 491 | if (bif->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN) |
371 | seq_printf(seq, "design capacity: unknown\n"); | 492 | seq_printf(seq, "design capacity: unknown\n"); |
@@ -396,7 +517,6 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset) | |||
396 | else | 517 | else |
397 | seq_printf(seq, "design voltage: %d mV\n", | 518 | seq_printf(seq, "design voltage: %d mV\n", |
398 | (u32) bif->design_voltage); | 519 | (u32) bif->design_voltage); |
399 | |||
400 | seq_printf(seq, "design capacity warning: %d %sh\n", | 520 | seq_printf(seq, "design capacity warning: %d %sh\n", |
401 | (u32) bif->design_capacity_warning, units); | 521 | (u32) bif->design_capacity_warning, units); |
402 | seq_printf(seq, "design capacity low: %d %sh\n", | 522 | seq_printf(seq, "design capacity low: %d %sh\n", |
@@ -411,50 +531,40 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset) | |||
411 | seq_printf(seq, "OEM info: %s\n", bif->oem_info); | 531 | seq_printf(seq, "OEM info: %s\n", bif->oem_info); |
412 | 532 | ||
413 | end: | 533 | end: |
414 | kfree(bif); | ||
415 | 534 | ||
416 | return 0; | 535 | if (result) |
417 | } | 536 | seq_printf(seq, "ERROR: Unable to read battery info\n"); |
418 | 537 | ||
419 | static int acpi_battery_info_open_fs(struct inode *inode, struct file *file) | 538 | return result; |
420 | { | ||
421 | return single_open(file, acpi_battery_read_info, PDE(inode)->data); | ||
422 | } | 539 | } |
423 | 540 | ||
424 | static int acpi_battery_read_state(struct seq_file *seq, void *offset) | 541 | static int acpi_battery_print_state(struct seq_file *seq, int result) |
425 | { | 542 | { |
426 | int result = 0; | ||
427 | struct acpi_battery *battery = seq->private; | 543 | struct acpi_battery *battery = seq->private; |
428 | struct acpi_battery_status *bst = NULL; | 544 | struct acpi_battery_state *bst = NULL; |
429 | char *units = "?"; | 545 | char *units = "?"; |
430 | 546 | ||
431 | 547 | if (result) | |
432 | if (!battery) | ||
433 | goto end; | 548 | goto end; |
434 | 549 | ||
435 | acpi_battery_check_present(battery); | 550 | if (acpi_battery_present(battery)) |
436 | |||
437 | if (battery->flags.present) | ||
438 | seq_printf(seq, "present: yes\n"); | 551 | seq_printf(seq, "present: yes\n"); |
439 | else { | 552 | else { |
440 | seq_printf(seq, "present: no\n"); | 553 | seq_printf(seq, "present: no\n"); |
441 | goto end; | 554 | goto end; |
442 | } | 555 | } |
443 | 556 | ||
444 | /* Battery Units */ | 557 | bst = battery->bst_data.pointer; |
445 | 558 | if (!bst) { | |
446 | units = | 559 | ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BST buffer is NULL")); |
447 | battery->flags. | 560 | result = -ENODEV; |
448 | power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS; | ||
449 | |||
450 | /* Battery Status (_BST) */ | ||
451 | |||
452 | result = acpi_battery_get_status(battery, &bst); | ||
453 | if (result || !bst) { | ||
454 | seq_printf(seq, "ERROR: Unable to read battery status\n"); | ||
455 | goto end; | 561 | goto end; |
456 | } | 562 | } |
457 | 563 | ||
564 | /* Battery Units */ | ||
565 | |||
566 | units = acpi_battery_power_units(battery); | ||
567 | |||
458 | if (!(bst->state & 0x04)) | 568 | if (!(bst->state & 0x04)) |
459 | seq_printf(seq, "capacity state: ok\n"); | 569 | seq_printf(seq, "capacity state: ok\n"); |
460 | else | 570 | else |
@@ -490,48 +600,43 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset) | |||
490 | (u32) bst->present_voltage); | 600 | (u32) bst->present_voltage); |
491 | 601 | ||
492 | end: | 602 | end: |
493 | kfree(bst); | ||
494 | 603 | ||
495 | return 0; | 604 | if (result) { |
496 | } | 605 | seq_printf(seq, "ERROR: Unable to read battery state\n"); |
606 | } | ||
497 | 607 | ||
498 | static int acpi_battery_state_open_fs(struct inode *inode, struct file *file) | 608 | return result; |
499 | { | ||
500 | return single_open(file, acpi_battery_read_state, PDE(inode)->data); | ||
501 | } | 609 | } |
502 | 610 | ||
503 | static int acpi_battery_read_alarm(struct seq_file *seq, void *offset) | 611 | static int acpi_battery_print_alarm(struct seq_file *seq, int result) |
504 | { | 612 | { |
505 | struct acpi_battery *battery = seq->private; | 613 | struct acpi_battery *battery = seq->private; |
506 | char *units = "?"; | 614 | char *units = "?"; |
507 | 615 | ||
508 | 616 | if (result) | |
509 | if (!battery) | ||
510 | goto end; | 617 | goto end; |
511 | 618 | ||
512 | acpi_battery_check_present(battery); | 619 | if (!acpi_battery_present(battery)) { |
513 | |||
514 | if (!battery->flags.present) { | ||
515 | seq_printf(seq, "present: no\n"); | 620 | seq_printf(seq, "present: no\n"); |
516 | goto end; | 621 | goto end; |
517 | } | 622 | } |
518 | 623 | ||
519 | /* Battery Units */ | 624 | /* Battery Units */ |
520 | 625 | ||
521 | units = | 626 | units = acpi_battery_power_units(battery); |
522 | battery->flags. | ||
523 | power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS; | ||
524 | |||
525 | /* Battery Alarm */ | ||
526 | 627 | ||
527 | seq_printf(seq, "alarm: "); | 628 | seq_printf(seq, "alarm: "); |
528 | if (!battery->alarm) | 629 | if (!battery->alarm) |
529 | seq_printf(seq, "unsupported\n"); | 630 | seq_printf(seq, "unsupported\n"); |
530 | else | 631 | else |
531 | seq_printf(seq, "%d %sh\n", (u32) battery->alarm, units); | 632 | seq_printf(seq, "%lu %sh\n", battery->alarm, units); |
532 | 633 | ||
533 | end: | 634 | end: |
534 | return 0; | 635 | |
636 | if (result) | ||
637 | seq_printf(seq, "ERROR: Unable to read battery alarm\n"); | ||
638 | |||
639 | return result; | ||
535 | } | 640 | } |
536 | 641 | ||
537 | static ssize_t | 642 | static ssize_t |
@@ -543,27 +648,113 @@ acpi_battery_write_alarm(struct file *file, | |||
543 | char alarm_string[12] = { '\0' }; | 648 | char alarm_string[12] = { '\0' }; |
544 | struct seq_file *m = file->private_data; | 649 | struct seq_file *m = file->private_data; |
545 | struct acpi_battery *battery = m->private; | 650 | struct acpi_battery *battery = m->private; |
546 | 651 | int update_result = ACPI_BATTERY_NONE_UPDATE; | |
547 | 652 | ||
548 | if (!battery || (count > sizeof(alarm_string) - 1)) | 653 | if (!battery || (count > sizeof(alarm_string) - 1)) |
549 | return -EINVAL; | 654 | return -EINVAL; |
550 | 655 | ||
551 | acpi_battery_check_present(battery); | 656 | mutex_lock(&battery->mutex); |
552 | 657 | ||
553 | if (!battery->flags.present) | 658 | result = acpi_battery_update(battery, 1, &update_result); |
554 | return -ENODEV; | 659 | if (result) { |
660 | result = -ENODEV; | ||
661 | goto end; | ||
662 | } | ||
663 | |||
664 | if (!acpi_battery_present(battery)) { | ||
665 | result = -ENODEV; | ||
666 | goto end; | ||
667 | } | ||
555 | 668 | ||
556 | if (copy_from_user(alarm_string, buffer, count)) | 669 | if (copy_from_user(alarm_string, buffer, count)) { |
557 | return -EFAULT; | 670 | result = -EFAULT; |
671 | goto end; | ||
672 | } | ||
558 | 673 | ||
559 | alarm_string[count] = '\0'; | 674 | alarm_string[count] = '\0'; |
560 | 675 | ||
561 | result = acpi_battery_set_alarm(battery, | 676 | result = acpi_battery_set_alarm(battery, |
562 | simple_strtoul(alarm_string, NULL, 0)); | 677 | simple_strtoul(alarm_string, NULL, 0)); |
563 | if (result) | 678 | if (result) |
564 | return result; | 679 | goto end; |
680 | |||
681 | end: | ||
565 | 682 | ||
566 | return count; | 683 | acpi_battery_check_result(battery, result); |
684 | |||
685 | if (!result) | ||
686 | result = count; | ||
687 | |||
688 | mutex_unlock(&battery->mutex); | ||
689 | |||
690 | return result; | ||
691 | } | ||
692 | |||
693 | typedef int(*print_func)(struct seq_file *seq, int result); | ||
694 | typedef int(*get_func)(struct acpi_battery *battery); | ||
695 | |||
696 | static struct acpi_read_mux { | ||
697 | print_func print; | ||
698 | get_func get; | ||
699 | } acpi_read_funcs[ACPI_BATTERY_NUMFILES] = { | ||
700 | {.get = acpi_battery_get_info, .print = acpi_battery_print_info}, | ||
701 | {.get = acpi_battery_get_state, .print = acpi_battery_print_state}, | ||
702 | {.get = acpi_battery_get_alarm, .print = acpi_battery_print_alarm}, | ||
703 | }; | ||
704 | |||
705 | static int acpi_battery_read(int fid, struct seq_file *seq) | ||
706 | { | ||
707 | struct acpi_battery *battery = seq->private; | ||
708 | int result = 0; | ||
709 | int update_result = ACPI_BATTERY_NONE_UPDATE; | ||
710 | int update = 0; | ||
711 | |||
712 | mutex_lock(&battery->mutex); | ||
713 | |||
714 | update = (get_seconds() - battery->update_time[fid] >= update_time); | ||
715 | update = (update | battery->flags.update[fid]); | ||
716 | |||
717 | result = acpi_battery_update(battery, update, &update_result); | ||
718 | if (result) | ||
719 | goto end; | ||
720 | |||
721 | if (update_result == ACPI_BATTERY_EASY_UPDATE) { | ||
722 | result = acpi_read_funcs[fid].get(battery); | ||
723 | if (result) | ||
724 | goto end; | ||
725 | } | ||
726 | |||
727 | end: | ||
728 | result = acpi_read_funcs[fid].print(seq, result); | ||
729 | acpi_battery_check_result(battery, result); | ||
730 | battery->flags.update[fid] = result; | ||
731 | mutex_unlock(&battery->mutex); | ||
732 | return result; | ||
733 | } | ||
734 | |||
735 | static int acpi_battery_read_info(struct seq_file *seq, void *offset) | ||
736 | { | ||
737 | return acpi_battery_read(ACPI_BATTERY_INFO, seq); | ||
738 | } | ||
739 | |||
740 | static int acpi_battery_read_state(struct seq_file *seq, void *offset) | ||
741 | { | ||
742 | return acpi_battery_read(ACPI_BATTERY_STATE, seq); | ||
743 | } | ||
744 | |||
745 | static int acpi_battery_read_alarm(struct seq_file *seq, void *offset) | ||
746 | { | ||
747 | return acpi_battery_read(ACPI_BATTERY_ALARM, seq); | ||
748 | } | ||
749 | |||
750 | static int acpi_battery_info_open_fs(struct inode *inode, struct file *file) | ||
751 | { | ||
752 | return single_open(file, acpi_battery_read_info, PDE(inode)->data); | ||
753 | } | ||
754 | |||
755 | static int acpi_battery_state_open_fs(struct inode *inode, struct file *file) | ||
756 | { | ||
757 | return single_open(file, acpi_battery_read_state, PDE(inode)->data); | ||
567 | } | 758 | } |
568 | 759 | ||
569 | static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file) | 760 | static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file) |
@@ -571,35 +762,51 @@ static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file) | |||
571 | return single_open(file, acpi_battery_read_alarm, PDE(inode)->data); | 762 | return single_open(file, acpi_battery_read_alarm, PDE(inode)->data); |
572 | } | 763 | } |
573 | 764 | ||
574 | static const struct file_operations acpi_battery_info_ops = { | 765 | static struct battery_file { |
766 | struct file_operations ops; | ||
767 | mode_t mode; | ||
768 | char *name; | ||
769 | } acpi_battery_file[] = { | ||
770 | { | ||
771 | .name = "info", | ||
772 | .mode = S_IRUGO, | ||
773 | .ops = { | ||
575 | .open = acpi_battery_info_open_fs, | 774 | .open = acpi_battery_info_open_fs, |
576 | .read = seq_read, | 775 | .read = seq_read, |
577 | .llseek = seq_lseek, | 776 | .llseek = seq_lseek, |
578 | .release = single_release, | 777 | .release = single_release, |
579 | .owner = THIS_MODULE, | 778 | .owner = THIS_MODULE, |
580 | }; | 779 | }, |
581 | 780 | }, | |
582 | static const struct file_operations acpi_battery_state_ops = { | 781 | { |
782 | .name = "state", | ||
783 | .mode = S_IRUGO, | ||
784 | .ops = { | ||
583 | .open = acpi_battery_state_open_fs, | 785 | .open = acpi_battery_state_open_fs, |
584 | .read = seq_read, | 786 | .read = seq_read, |
585 | .llseek = seq_lseek, | 787 | .llseek = seq_lseek, |
586 | .release = single_release, | 788 | .release = single_release, |
587 | .owner = THIS_MODULE, | 789 | .owner = THIS_MODULE, |
588 | }; | 790 | }, |
589 | 791 | }, | |
590 | static const struct file_operations acpi_battery_alarm_ops = { | 792 | { |
793 | .name = "alarm", | ||
794 | .mode = S_IFREG | S_IRUGO | S_IWUSR, | ||
795 | .ops = { | ||
591 | .open = acpi_battery_alarm_open_fs, | 796 | .open = acpi_battery_alarm_open_fs, |
592 | .read = seq_read, | 797 | .read = seq_read, |
593 | .write = acpi_battery_write_alarm, | 798 | .write = acpi_battery_write_alarm, |
594 | .llseek = seq_lseek, | 799 | .llseek = seq_lseek, |
595 | .release = single_release, | 800 | .release = single_release, |
596 | .owner = THIS_MODULE, | 801 | .owner = THIS_MODULE, |
802 | }, | ||
803 | }, | ||
597 | }; | 804 | }; |
598 | 805 | ||
599 | static int acpi_battery_add_fs(struct acpi_device *device) | 806 | static int acpi_battery_add_fs(struct acpi_device *device) |
600 | { | 807 | { |
601 | struct proc_dir_entry *entry = NULL; | 808 | struct proc_dir_entry *entry = NULL; |
602 | 809 | int i; | |
603 | 810 | ||
604 | if (!acpi_device_dir(device)) { | 811 | if (!acpi_device_dir(device)) { |
605 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), | 812 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), |
@@ -609,38 +816,16 @@ static int acpi_battery_add_fs(struct acpi_device *device) | |||
609 | acpi_device_dir(device)->owner = THIS_MODULE; | 816 | acpi_device_dir(device)->owner = THIS_MODULE; |
610 | } | 817 | } |
611 | 818 | ||
612 | /* 'info' [R] */ | 819 | for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) { |
613 | entry = create_proc_entry(ACPI_BATTERY_FILE_INFO, | 820 | entry = create_proc_entry(acpi_battery_file[i].name, |
614 | S_IRUGO, acpi_device_dir(device)); | 821 | acpi_battery_file[i].mode, acpi_device_dir(device)); |
615 | if (!entry) | 822 | if (!entry) |
616 | return -ENODEV; | 823 | return -ENODEV; |
617 | else { | 824 | else { |
618 | entry->proc_fops = &acpi_battery_info_ops; | 825 | entry->proc_fops = &acpi_battery_file[i].ops; |
619 | entry->data = acpi_driver_data(device); | 826 | entry->data = acpi_driver_data(device); |
620 | entry->owner = THIS_MODULE; | 827 | entry->owner = THIS_MODULE; |
621 | } | 828 | } |
622 | |||
623 | /* 'status' [R] */ | ||
624 | entry = create_proc_entry(ACPI_BATTERY_FILE_STATUS, | ||
625 | S_IRUGO, acpi_device_dir(device)); | ||
626 | if (!entry) | ||
627 | return -ENODEV; | ||
628 | else { | ||
629 | entry->proc_fops = &acpi_battery_state_ops; | ||
630 | entry->data = acpi_driver_data(device); | ||
631 | entry->owner = THIS_MODULE; | ||
632 | } | ||
633 | |||
634 | /* 'alarm' [R/W] */ | ||
635 | entry = create_proc_entry(ACPI_BATTERY_FILE_ALARM, | ||
636 | S_IFREG | S_IRUGO | S_IWUSR, | ||
637 | acpi_device_dir(device)); | ||
638 | if (!entry) | ||
639 | return -ENODEV; | ||
640 | else { | ||
641 | entry->proc_fops = &acpi_battery_alarm_ops; | ||
642 | entry->data = acpi_driver_data(device); | ||
643 | entry->owner = THIS_MODULE; | ||
644 | } | 829 | } |
645 | 830 | ||
646 | return 0; | 831 | return 0; |
@@ -648,15 +833,12 @@ static int acpi_battery_add_fs(struct acpi_device *device) | |||
648 | 833 | ||
649 | static int acpi_battery_remove_fs(struct acpi_device *device) | 834 | static int acpi_battery_remove_fs(struct acpi_device *device) |
650 | { | 835 | { |
651 | 836 | int i; | |
652 | if (acpi_device_dir(device)) { | 837 | if (acpi_device_dir(device)) { |
653 | remove_proc_entry(ACPI_BATTERY_FILE_ALARM, | 838 | for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) { |
839 | remove_proc_entry(acpi_battery_file[i].name, | ||
654 | acpi_device_dir(device)); | 840 | acpi_device_dir(device)); |
655 | remove_proc_entry(ACPI_BATTERY_FILE_STATUS, | 841 | } |
656 | acpi_device_dir(device)); | ||
657 | remove_proc_entry(ACPI_BATTERY_FILE_INFO, | ||
658 | acpi_device_dir(device)); | ||
659 | |||
660 | remove_proc_entry(acpi_device_bid(device), acpi_battery_dir); | 842 | remove_proc_entry(acpi_device_bid(device), acpi_battery_dir); |
661 | acpi_device_dir(device) = NULL; | 843 | acpi_device_dir(device) = NULL; |
662 | } | 844 | } |
@@ -673,7 +855,6 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) | |||
673 | struct acpi_battery *battery = data; | 855 | struct acpi_battery *battery = data; |
674 | struct acpi_device *device = NULL; | 856 | struct acpi_device *device = NULL; |
675 | 857 | ||
676 | |||
677 | if (!battery) | 858 | if (!battery) |
678 | return; | 859 | return; |
679 | 860 | ||
@@ -684,8 +865,10 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) | |||
684 | case ACPI_BATTERY_NOTIFY_INFO: | 865 | case ACPI_BATTERY_NOTIFY_INFO: |
685 | case ACPI_NOTIFY_BUS_CHECK: | 866 | case ACPI_NOTIFY_BUS_CHECK: |
686 | case ACPI_NOTIFY_DEVICE_CHECK: | 867 | case ACPI_NOTIFY_DEVICE_CHECK: |
687 | acpi_battery_check(battery); | 868 | device = battery->device; |
688 | acpi_bus_generate_event(device, event, battery->flags.present); | 869 | acpi_battery_notify_update(battery); |
870 | acpi_bus_generate_event(device, event, | ||
871 | acpi_battery_present(battery)); | ||
689 | break; | 872 | break; |
690 | default: | 873 | default: |
691 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 874 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
@@ -702,7 +885,6 @@ static int acpi_battery_add(struct acpi_device *device) | |||
702 | acpi_status status = 0; | 885 | acpi_status status = 0; |
703 | struct acpi_battery *battery = NULL; | 886 | struct acpi_battery *battery = NULL; |
704 | 887 | ||
705 | |||
706 | if (!device) | 888 | if (!device) |
707 | return -EINVAL; | 889 | return -EINVAL; |
708 | 890 | ||
@@ -710,15 +892,21 @@ static int acpi_battery_add(struct acpi_device *device) | |||
710 | if (!battery) | 892 | if (!battery) |
711 | return -ENOMEM; | 893 | return -ENOMEM; |
712 | 894 | ||
895 | mutex_init(&battery->mutex); | ||
896 | |||
897 | mutex_lock(&battery->mutex); | ||
898 | |||
713 | battery->device = device; | 899 | battery->device = device; |
714 | strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); | 900 | strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); |
715 | strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); | 901 | strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); |
716 | acpi_driver_data(device) = battery; | 902 | acpi_driver_data(device) = battery; |
717 | 903 | ||
718 | result = acpi_battery_check(battery); | 904 | result = acpi_battery_get_status(battery); |
719 | if (result) | 905 | if (result) |
720 | goto end; | 906 | goto end; |
721 | 907 | ||
908 | battery->flags.init_update = 1; | ||
909 | |||
722 | result = acpi_battery_add_fs(device); | 910 | result = acpi_battery_add_fs(device); |
723 | if (result) | 911 | if (result) |
724 | goto end; | 912 | goto end; |
@@ -727,6 +915,7 @@ static int acpi_battery_add(struct acpi_device *device) | |||
727 | ACPI_ALL_NOTIFY, | 915 | ACPI_ALL_NOTIFY, |
728 | acpi_battery_notify, battery); | 916 | acpi_battery_notify, battery); |
729 | if (ACPI_FAILURE(status)) { | 917 | if (ACPI_FAILURE(status)) { |
918 | ACPI_EXCEPTION((AE_INFO, status, "Installing notify handler")); | ||
730 | result = -ENODEV; | 919 | result = -ENODEV; |
731 | goto end; | 920 | goto end; |
732 | } | 921 | } |
@@ -736,11 +925,14 @@ static int acpi_battery_add(struct acpi_device *device) | |||
736 | device->status.battery_present ? "present" : "absent"); | 925 | device->status.battery_present ? "present" : "absent"); |
737 | 926 | ||
738 | end: | 927 | end: |
928 | |||
739 | if (result) { | 929 | if (result) { |
740 | acpi_battery_remove_fs(device); | 930 | acpi_battery_remove_fs(device); |
741 | kfree(battery); | 931 | kfree(battery); |
742 | } | 932 | } |
743 | 933 | ||
934 | mutex_unlock(&battery->mutex); | ||
935 | |||
744 | return result; | 936 | return result; |
745 | } | 937 | } |
746 | 938 | ||
@@ -749,18 +941,27 @@ static int acpi_battery_remove(struct acpi_device *device, int type) | |||
749 | acpi_status status = 0; | 941 | acpi_status status = 0; |
750 | struct acpi_battery *battery = NULL; | 942 | struct acpi_battery *battery = NULL; |
751 | 943 | ||
752 | |||
753 | if (!device || !acpi_driver_data(device)) | 944 | if (!device || !acpi_driver_data(device)) |
754 | return -EINVAL; | 945 | return -EINVAL; |
755 | 946 | ||
756 | battery = acpi_driver_data(device); | 947 | battery = acpi_driver_data(device); |
757 | 948 | ||
949 | mutex_lock(&battery->mutex); | ||
950 | |||
758 | status = acpi_remove_notify_handler(device->handle, | 951 | status = acpi_remove_notify_handler(device->handle, |
759 | ACPI_ALL_NOTIFY, | 952 | ACPI_ALL_NOTIFY, |
760 | acpi_battery_notify); | 953 | acpi_battery_notify); |
761 | 954 | ||
762 | acpi_battery_remove_fs(device); | 955 | acpi_battery_remove_fs(device); |
763 | 956 | ||
957 | kfree(battery->bif_data.pointer); | ||
958 | |||
959 | kfree(battery->bst_data.pointer); | ||
960 | |||
961 | mutex_unlock(&battery->mutex); | ||
962 | |||
963 | mutex_destroy(&battery->mutex); | ||
964 | |||
764 | kfree(battery); | 965 | kfree(battery); |
765 | 966 | ||
766 | return 0; | 967 | return 0; |
@@ -775,7 +976,10 @@ static int acpi_battery_resume(struct acpi_device *device) | |||
775 | return -EINVAL; | 976 | return -EINVAL; |
776 | 977 | ||
777 | battery = device->driver_data; | 978 | battery = device->driver_data; |
778 | return acpi_battery_check(battery); | 979 | |
980 | battery->flags.init_update = 1; | ||
981 | |||
982 | return 0; | ||
779 | } | 983 | } |
780 | 984 | ||
781 | static int __init acpi_battery_init(void) | 985 | static int __init acpi_battery_init(void) |
@@ -800,7 +1004,6 @@ static int __init acpi_battery_init(void) | |||
800 | 1004 | ||
801 | static void __exit acpi_battery_exit(void) | 1005 | static void __exit acpi_battery_exit(void) |
802 | { | 1006 | { |
803 | |||
804 | acpi_bus_unregister_driver(&acpi_battery_driver); | 1007 | acpi_bus_unregister_driver(&acpi_battery_driver); |
805 | 1008 | ||
806 | acpi_unlock_battery_dir(acpi_battery_dir); | 1009 | acpi_unlock_battery_dir(acpi_battery_dir); |
diff --git a/drivers/acpi/bay.c b/drivers/acpi/bay.c index fb3f31b5e69f..56a5b3fffeb3 100644 --- a/drivers/acpi/bay.c +++ b/drivers/acpi/bay.c | |||
@@ -288,6 +288,11 @@ static int bay_add(acpi_handle handle, int id) | |||
288 | new_bay->pdev = pdev; | 288 | new_bay->pdev = pdev; |
289 | platform_set_drvdata(pdev, new_bay); | 289 | platform_set_drvdata(pdev, new_bay); |
290 | 290 | ||
291 | /* | ||
292 | * we want the bay driver to be able to send uevents | ||
293 | */ | ||
294 | pdev->dev.uevent_suppress = 0; | ||
295 | |||
291 | if (acpi_bay_add_fs(new_bay)) { | 296 | if (acpi_bay_add_fs(new_bay)) { |
292 | platform_device_unregister(new_bay->pdev); | 297 | platform_device_unregister(new_bay->pdev); |
293 | goto bay_add_err; | 298 | goto bay_add_err; |
@@ -328,18 +333,12 @@ static void bay_notify(acpi_handle handle, u32 event, void *data) | |||
328 | { | 333 | { |
329 | struct bay *bay_dev = (struct bay *)data; | 334 | struct bay *bay_dev = (struct bay *)data; |
330 | struct device *dev = &bay_dev->pdev->dev; | 335 | struct device *dev = &bay_dev->pdev->dev; |
336 | char event_string[12]; | ||
337 | char *envp[] = { event_string, NULL }; | ||
331 | 338 | ||
332 | bay_dprintk(handle, "Bay event"); | 339 | bay_dprintk(handle, "Bay event"); |
333 | 340 | sprintf(event_string, "BAY_EVENT=%d\n", event); | |
334 | switch(event) { | 341 | kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); |
335 | case ACPI_NOTIFY_BUS_CHECK: | ||
336 | case ACPI_NOTIFY_DEVICE_CHECK: | ||
337 | case ACPI_NOTIFY_EJECT_REQUEST: | ||
338 | kobject_uevent(&dev->kobj, KOBJ_CHANGE); | ||
339 | break; | ||
340 | default: | ||
341 | printk(KERN_ERR PREFIX "Bay: unknown event %d\n", event); | ||
342 | } | ||
343 | } | 342 | } |
344 | 343 | ||
345 | static acpi_status | 344 | static acpi_status |
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index e5084ececb6f..6b2658c96242 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -292,6 +292,10 @@ int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data) | |||
292 | if (!device) | 292 | if (!device) |
293 | return -EINVAL; | 293 | return -EINVAL; |
294 | 294 | ||
295 | if (acpi_bus_generate_genetlink_event(device, type, data)) | ||
296 | printk(KERN_WARNING PREFIX | ||
297 | "Failed to generate an ACPI event via genetlink!\n"); | ||
298 | |||
295 | /* drop event on the floor if no one's listening */ | 299 | /* drop event on the floor if no one's listening */ |
296 | if (!event_is_open) | 300 | if (!event_is_open) |
297 | return 0; | 301 | return 0; |
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 4546bf873aea..6192c8be66df 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
@@ -40,8 +40,15 @@ MODULE_AUTHOR("Kristen Carlson Accardi"); | |||
40 | MODULE_DESCRIPTION(ACPI_DOCK_DRIVER_DESCRIPTION); | 40 | MODULE_DESCRIPTION(ACPI_DOCK_DRIVER_DESCRIPTION); |
41 | MODULE_LICENSE("GPL"); | 41 | MODULE_LICENSE("GPL"); |
42 | 42 | ||
43 | static int immediate_undock = 1; | ||
44 | module_param(immediate_undock, bool, 0644); | ||
45 | MODULE_PARM_DESC(immediate_undock, "1 (default) will cause the driver to " | ||
46 | "undock immediately when the undock button is pressed, 0 will cause" | ||
47 | " the driver to wait for userspace to write the undock sysfs file " | ||
48 | " before undocking"); | ||
49 | |||
43 | static struct atomic_notifier_head dock_notifier_list; | 50 | static struct atomic_notifier_head dock_notifier_list; |
44 | static struct platform_device dock_device; | 51 | static struct platform_device *dock_device; |
45 | static char dock_device_name[] = "dock"; | 52 | static char dock_device_name[] = "dock"; |
46 | 53 | ||
47 | struct dock_station { | 54 | struct dock_station { |
@@ -63,6 +70,7 @@ struct dock_dependent_device { | |||
63 | }; | 70 | }; |
64 | 71 | ||
65 | #define DOCK_DOCKING 0x00000001 | 72 | #define DOCK_DOCKING 0x00000001 |
73 | #define DOCK_UNDOCKING 0x00000002 | ||
66 | #define DOCK_EVENT 3 | 74 | #define DOCK_EVENT 3 |
67 | #define UNDOCK_EVENT 2 | 75 | #define UNDOCK_EVENT 2 |
68 | 76 | ||
@@ -327,12 +335,20 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event) | |||
327 | 335 | ||
328 | static void dock_event(struct dock_station *ds, u32 event, int num) | 336 | static void dock_event(struct dock_station *ds, u32 event, int num) |
329 | { | 337 | { |
330 | struct device *dev = &dock_device.dev; | 338 | struct device *dev = &dock_device->dev; |
339 | char event_string[7]; | ||
340 | char *envp[] = { event_string, NULL }; | ||
341 | |||
342 | if (num == UNDOCK_EVENT) | ||
343 | sprintf(event_string, "UNDOCK"); | ||
344 | else | ||
345 | sprintf(event_string, "DOCK"); | ||
346 | |||
331 | /* | 347 | /* |
332 | * Indicate that the status of the dock station has | 348 | * Indicate that the status of the dock station has |
333 | * changed. | 349 | * changed. |
334 | */ | 350 | */ |
335 | kobject_uevent(&dev->kobj, KOBJ_CHANGE); | 351 | kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); |
336 | } | 352 | } |
337 | 353 | ||
338 | /** | 354 | /** |
@@ -380,12 +396,11 @@ static void handle_dock(struct dock_station *ds, int dock) | |||
380 | union acpi_object arg; | 396 | union acpi_object arg; |
381 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 397 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
382 | struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 398 | struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
383 | union acpi_object *obj; | ||
384 | 399 | ||
385 | acpi_get_name(ds->handle, ACPI_FULL_PATHNAME, &name_buffer); | 400 | acpi_get_name(ds->handle, ACPI_FULL_PATHNAME, &name_buffer); |
386 | obj = name_buffer.pointer; | ||
387 | 401 | ||
388 | printk(KERN_INFO PREFIX "%s\n", dock ? "docking" : "undocking"); | 402 | printk(KERN_INFO PREFIX "%s - %s\n", |
403 | (char *)name_buffer.pointer, dock ? "docking" : "undocking"); | ||
389 | 404 | ||
390 | /* _DCK method has one argument */ | 405 | /* _DCK method has one argument */ |
391 | arg_list.count = 1; | 406 | arg_list.count = 1; |
@@ -394,7 +409,8 @@ static void handle_dock(struct dock_station *ds, int dock) | |||
394 | arg.integer.value = dock; | 409 | arg.integer.value = dock; |
395 | status = acpi_evaluate_object(ds->handle, "_DCK", &arg_list, &buffer); | 410 | status = acpi_evaluate_object(ds->handle, "_DCK", &arg_list, &buffer); |
396 | if (ACPI_FAILURE(status)) | 411 | if (ACPI_FAILURE(status)) |
397 | pr_debug("%s: failed to execute _DCK\n", obj->string.pointer); | 412 | printk(KERN_ERR PREFIX "%s - failed to execute _DCK\n", |
413 | (char *)name_buffer.pointer); | ||
398 | kfree(buffer.pointer); | 414 | kfree(buffer.pointer); |
399 | kfree(name_buffer.pointer); | 415 | kfree(name_buffer.pointer); |
400 | } | 416 | } |
@@ -420,6 +436,16 @@ static inline void complete_dock(struct dock_station *ds) | |||
420 | ds->last_dock_time = jiffies; | 436 | ds->last_dock_time = jiffies; |
421 | } | 437 | } |
422 | 438 | ||
439 | static inline void begin_undock(struct dock_station *ds) | ||
440 | { | ||
441 | ds->flags |= DOCK_UNDOCKING; | ||
442 | } | ||
443 | |||
444 | static inline void complete_undock(struct dock_station *ds) | ||
445 | { | ||
446 | ds->flags &= ~(DOCK_UNDOCKING); | ||
447 | } | ||
448 | |||
423 | /** | 449 | /** |
424 | * dock_in_progress - see if we are in the middle of handling a dock event | 450 | * dock_in_progress - see if we are in the middle of handling a dock event |
425 | * @ds: the dock station | 451 | * @ds: the dock station |
@@ -550,7 +576,7 @@ static int handle_eject_request(struct dock_station *ds, u32 event) | |||
550 | printk(KERN_ERR PREFIX "Unable to undock!\n"); | 576 | printk(KERN_ERR PREFIX "Unable to undock!\n"); |
551 | return -EBUSY; | 577 | return -EBUSY; |
552 | } | 578 | } |
553 | 579 | complete_undock(ds); | |
554 | return 0; | 580 | return 0; |
555 | } | 581 | } |
556 | 582 | ||
@@ -594,7 +620,11 @@ static void dock_notify(acpi_handle handle, u32 event, void *data) | |||
594 | * to the driver who wish to hotplug. | 620 | * to the driver who wish to hotplug. |
595 | */ | 621 | */ |
596 | case ACPI_NOTIFY_EJECT_REQUEST: | 622 | case ACPI_NOTIFY_EJECT_REQUEST: |
597 | handle_eject_request(ds, event); | 623 | begin_undock(ds); |
624 | if (immediate_undock) | ||
625 | handle_eject_request(ds, event); | ||
626 | else | ||
627 | dock_event(ds, event, UNDOCK_EVENT); | ||
598 | break; | 628 | break; |
599 | default: | 629 | default: |
600 | printk(KERN_ERR PREFIX "Unknown dock event %d\n", event); | 630 | printk(KERN_ERR PREFIX "Unknown dock event %d\n", event); |
@@ -653,6 +683,17 @@ static ssize_t show_docked(struct device *dev, | |||
653 | DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL); | 683 | DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL); |
654 | 684 | ||
655 | /* | 685 | /* |
686 | * show_flags - read method for flags file in sysfs | ||
687 | */ | ||
688 | static ssize_t show_flags(struct device *dev, | ||
689 | struct device_attribute *attr, char *buf) | ||
690 | { | ||
691 | return snprintf(buf, PAGE_SIZE, "%d\n", dock_station->flags); | ||
692 | |||
693 | } | ||
694 | DEVICE_ATTR(flags, S_IRUGO, show_flags, NULL); | ||
695 | |||
696 | /* | ||
656 | * write_undock - write method for "undock" file in sysfs | 697 | * write_undock - write method for "undock" file in sysfs |
657 | */ | 698 | */ |
658 | static ssize_t write_undock(struct device *dev, struct device_attribute *attr, | 699 | static ssize_t write_undock(struct device *dev, struct device_attribute *attr, |
@@ -675,16 +716,15 @@ static ssize_t show_dock_uid(struct device *dev, | |||
675 | struct device_attribute *attr, char *buf) | 716 | struct device_attribute *attr, char *buf) |
676 | { | 717 | { |
677 | unsigned long lbuf; | 718 | unsigned long lbuf; |
678 | acpi_status status = acpi_evaluate_integer(dock_station->handle, "_UID", NULL, &lbuf); | 719 | acpi_status status = acpi_evaluate_integer(dock_station->handle, |
679 | if(ACPI_FAILURE(status)) { | 720 | "_UID", NULL, &lbuf); |
721 | if (ACPI_FAILURE(status)) | ||
680 | return 0; | 722 | return 0; |
681 | } | 723 | |
682 | return snprintf(buf, PAGE_SIZE, "%lx\n", lbuf); | 724 | return snprintf(buf, PAGE_SIZE, "%lx\n", lbuf); |
683 | } | 725 | } |
684 | DEVICE_ATTR(uid, S_IRUGO, show_dock_uid, NULL); | 726 | DEVICE_ATTR(uid, S_IRUGO, show_dock_uid, NULL); |
685 | 727 | ||
686 | |||
687 | |||
688 | /** | 728 | /** |
689 | * dock_add - add a new dock station | 729 | * dock_add - add a new dock station |
690 | * @handle: the dock station handle | 730 | * @handle: the dock station handle |
@@ -711,33 +751,53 @@ static int dock_add(acpi_handle handle) | |||
711 | ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); | 751 | ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); |
712 | 752 | ||
713 | /* initialize platform device stuff */ | 753 | /* initialize platform device stuff */ |
714 | dock_device.name = dock_device_name; | 754 | dock_device = |
715 | ret = platform_device_register(&dock_device); | 755 | platform_device_register_simple(dock_device_name, 0, NULL, 0); |
756 | if (IS_ERR(dock_device)) { | ||
757 | kfree(dock_station); | ||
758 | dock_station = NULL; | ||
759 | return PTR_ERR(dock_device); | ||
760 | } | ||
761 | |||
762 | /* we want the dock device to send uevents */ | ||
763 | dock_device->dev.uevent_suppress = 0; | ||
764 | |||
765 | ret = device_create_file(&dock_device->dev, &dev_attr_docked); | ||
716 | if (ret) { | 766 | if (ret) { |
717 | printk(KERN_ERR PREFIX "Error %d registering dock device\n", ret); | 767 | printk("Error %d adding sysfs file\n", ret); |
768 | platform_device_unregister(dock_device); | ||
718 | kfree(dock_station); | 769 | kfree(dock_station); |
770 | dock_station = NULL; | ||
719 | return ret; | 771 | return ret; |
720 | } | 772 | } |
721 | ret = device_create_file(&dock_device.dev, &dev_attr_docked); | 773 | ret = device_create_file(&dock_device->dev, &dev_attr_undock); |
722 | if (ret) { | 774 | if (ret) { |
723 | printk("Error %d adding sysfs file\n", ret); | 775 | printk("Error %d adding sysfs file\n", ret); |
724 | platform_device_unregister(&dock_device); | 776 | device_remove_file(&dock_device->dev, &dev_attr_docked); |
777 | platform_device_unregister(dock_device); | ||
725 | kfree(dock_station); | 778 | kfree(dock_station); |
779 | dock_station = NULL; | ||
726 | return ret; | 780 | return ret; |
727 | } | 781 | } |
728 | ret = device_create_file(&dock_device.dev, &dev_attr_undock); | 782 | ret = device_create_file(&dock_device->dev, &dev_attr_uid); |
729 | if (ret) { | 783 | if (ret) { |
730 | printk("Error %d adding sysfs file\n", ret); | 784 | printk("Error %d adding sysfs file\n", ret); |
731 | device_remove_file(&dock_device.dev, &dev_attr_docked); | 785 | device_remove_file(&dock_device->dev, &dev_attr_docked); |
732 | platform_device_unregister(&dock_device); | 786 | device_remove_file(&dock_device->dev, &dev_attr_undock); |
787 | platform_device_unregister(dock_device); | ||
733 | kfree(dock_station); | 788 | kfree(dock_station); |
789 | dock_station = NULL; | ||
734 | return ret; | 790 | return ret; |
735 | } | 791 | } |
736 | ret = device_create_file(&dock_device.dev, &dev_attr_uid); | 792 | ret = device_create_file(&dock_device->dev, &dev_attr_flags); |
737 | if (ret) { | 793 | if (ret) { |
738 | printk("Error %d adding sysfs file\n", ret); | 794 | printk("Error %d adding sysfs file\n", ret); |
739 | platform_device_unregister(&dock_device); | 795 | device_remove_file(&dock_device->dev, &dev_attr_docked); |
796 | device_remove_file(&dock_device->dev, &dev_attr_undock); | ||
797 | device_remove_file(&dock_device->dev, &dev_attr_uid); | ||
798 | platform_device_unregister(dock_device); | ||
740 | kfree(dock_station); | 799 | kfree(dock_station); |
800 | dock_station = NULL; | ||
741 | return ret; | 801 | return ret; |
742 | } | 802 | } |
743 | 803 | ||
@@ -750,6 +810,7 @@ static int dock_add(acpi_handle handle) | |||
750 | dd = alloc_dock_dependent_device(handle); | 810 | dd = alloc_dock_dependent_device(handle); |
751 | if (!dd) { | 811 | if (!dd) { |
752 | kfree(dock_station); | 812 | kfree(dock_station); |
813 | dock_station = NULL; | ||
753 | ret = -ENOMEM; | 814 | ret = -ENOMEM; |
754 | goto dock_add_err_unregister; | 815 | goto dock_add_err_unregister; |
755 | } | 816 | } |
@@ -773,10 +834,13 @@ static int dock_add(acpi_handle handle) | |||
773 | dock_add_err: | 834 | dock_add_err: |
774 | kfree(dd); | 835 | kfree(dd); |
775 | dock_add_err_unregister: | 836 | dock_add_err_unregister: |
776 | device_remove_file(&dock_device.dev, &dev_attr_docked); | 837 | device_remove_file(&dock_device->dev, &dev_attr_docked); |
777 | device_remove_file(&dock_device.dev, &dev_attr_undock); | 838 | device_remove_file(&dock_device->dev, &dev_attr_undock); |
778 | platform_device_unregister(&dock_device); | 839 | device_remove_file(&dock_device->dev, &dev_attr_uid); |
840 | device_remove_file(&dock_device->dev, &dev_attr_flags); | ||
841 | platform_device_unregister(dock_device); | ||
779 | kfree(dock_station); | 842 | kfree(dock_station); |
843 | dock_station = NULL; | ||
780 | return ret; | 844 | return ret; |
781 | } | 845 | } |
782 | 846 | ||
@@ -804,12 +868,15 @@ static int dock_remove(void) | |||
804 | printk(KERN_ERR "Error removing notify handler\n"); | 868 | printk(KERN_ERR "Error removing notify handler\n"); |
805 | 869 | ||
806 | /* cleanup sysfs */ | 870 | /* cleanup sysfs */ |
807 | device_remove_file(&dock_device.dev, &dev_attr_docked); | 871 | device_remove_file(&dock_device->dev, &dev_attr_docked); |
808 | device_remove_file(&dock_device.dev, &dev_attr_undock); | 872 | device_remove_file(&dock_device->dev, &dev_attr_undock); |
809 | platform_device_unregister(&dock_device); | 873 | device_remove_file(&dock_device->dev, &dev_attr_uid); |
874 | device_remove_file(&dock_device->dev, &dev_attr_flags); | ||
875 | platform_device_unregister(dock_device); | ||
810 | 876 | ||
811 | /* free dock station memory */ | 877 | /* free dock station memory */ |
812 | kfree(dock_station); | 878 | kfree(dock_station); |
879 | dock_station = NULL; | ||
813 | return 0; | 880 | return 0; |
814 | } | 881 | } |
815 | 882 | ||
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 82f496c07675..10e851021eca 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -34,25 +34,26 @@ | |||
34 | #include <linux/proc_fs.h> | 34 | #include <linux/proc_fs.h> |
35 | #include <linux/seq_file.h> | 35 | #include <linux/seq_file.h> |
36 | #include <linux/interrupt.h> | 36 | #include <linux/interrupt.h> |
37 | #include <linux/list.h> | ||
37 | #include <asm/io.h> | 38 | #include <asm/io.h> |
38 | #include <acpi/acpi_bus.h> | 39 | #include <acpi/acpi_bus.h> |
39 | #include <acpi/acpi_drivers.h> | 40 | #include <acpi/acpi_drivers.h> |
40 | #include <acpi/actypes.h> | 41 | #include <acpi/actypes.h> |
41 | 42 | ||
42 | #define _COMPONENT ACPI_EC_COMPONENT | ||
43 | ACPI_MODULE_NAME("ec"); | ||
44 | #define ACPI_EC_COMPONENT 0x00100000 | ||
45 | #define ACPI_EC_CLASS "embedded_controller" | 43 | #define ACPI_EC_CLASS "embedded_controller" |
46 | #define ACPI_EC_HID "PNP0C09" | 44 | #define ACPI_EC_HID "PNP0C09" |
47 | #define ACPI_EC_DEVICE_NAME "Embedded Controller" | 45 | #define ACPI_EC_DEVICE_NAME "Embedded Controller" |
48 | #define ACPI_EC_FILE_INFO "info" | 46 | #define ACPI_EC_FILE_INFO "info" |
47 | |||
49 | #undef PREFIX | 48 | #undef PREFIX |
50 | #define PREFIX "ACPI: EC: " | 49 | #define PREFIX "ACPI: EC: " |
50 | |||
51 | /* EC status register */ | 51 | /* EC status register */ |
52 | #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ | 52 | #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ |
53 | #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ | 53 | #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ |
54 | #define ACPI_EC_FLAG_BURST 0x10 /* burst mode */ | 54 | #define ACPI_EC_FLAG_BURST 0x10 /* burst mode */ |
55 | #define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */ | 55 | #define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */ |
56 | |||
56 | /* EC commands */ | 57 | /* EC commands */ |
57 | enum ec_command { | 58 | enum ec_command { |
58 | ACPI_EC_COMMAND_READ = 0x80, | 59 | ACPI_EC_COMMAND_READ = 0x80, |
@@ -61,6 +62,7 @@ enum ec_command { | |||
61 | ACPI_EC_BURST_DISABLE = 0x83, | 62 | ACPI_EC_BURST_DISABLE = 0x83, |
62 | ACPI_EC_COMMAND_QUERY = 0x84, | 63 | ACPI_EC_COMMAND_QUERY = 0x84, |
63 | }; | 64 | }; |
65 | |||
64 | /* EC events */ | 66 | /* EC events */ |
65 | enum ec_event { | 67 | enum ec_event { |
66 | ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */ | 68 | ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */ |
@@ -94,6 +96,16 @@ static struct acpi_driver acpi_ec_driver = { | |||
94 | 96 | ||
95 | /* If we find an EC via the ECDT, we need to keep a ptr to its context */ | 97 | /* If we find an EC via the ECDT, we need to keep a ptr to its context */ |
96 | /* External interfaces use first EC only, so remember */ | 98 | /* External interfaces use first EC only, so remember */ |
99 | typedef int (*acpi_ec_query_func) (void *data); | ||
100 | |||
101 | struct acpi_ec_query_handler { | ||
102 | struct list_head node; | ||
103 | acpi_ec_query_func func; | ||
104 | acpi_handle handle; | ||
105 | void *data; | ||
106 | u8 query_bit; | ||
107 | }; | ||
108 | |||
97 | static struct acpi_ec { | 109 | static struct acpi_ec { |
98 | acpi_handle handle; | 110 | acpi_handle handle; |
99 | unsigned long gpe; | 111 | unsigned long gpe; |
@@ -104,6 +116,7 @@ static struct acpi_ec { | |||
104 | atomic_t query_pending; | 116 | atomic_t query_pending; |
105 | atomic_t event_count; | 117 | atomic_t event_count; |
106 | wait_queue_head_t wait; | 118 | wait_queue_head_t wait; |
119 | struct list_head list; | ||
107 | } *boot_ec, *first_ec; | 120 | } *boot_ec, *first_ec; |
108 | 121 | ||
109 | /* -------------------------------------------------------------------------- | 122 | /* -------------------------------------------------------------------------- |
@@ -245,7 +258,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, | |||
245 | 258 | ||
246 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0, 0); | 259 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0, 0); |
247 | if (status) { | 260 | if (status) { |
248 | printk(KERN_DEBUG PREFIX | 261 | printk(KERN_ERR PREFIX |
249 | "input buffer is not empty, aborting transaction\n"); | 262 | "input buffer is not empty, aborting transaction\n"); |
250 | goto end; | 263 | goto end; |
251 | } | 264 | } |
@@ -394,21 +407,67 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data) | |||
394 | /* -------------------------------------------------------------------------- | 407 | /* -------------------------------------------------------------------------- |
395 | Event Management | 408 | Event Management |
396 | -------------------------------------------------------------------------- */ | 409 | -------------------------------------------------------------------------- */ |
410 | int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, | ||
411 | acpi_handle handle, acpi_ec_query_func func, | ||
412 | void *data) | ||
413 | { | ||
414 | struct acpi_ec_query_handler *handler = | ||
415 | kzalloc(sizeof(struct acpi_ec_query_handler), GFP_KERNEL); | ||
416 | if (!handler) | ||
417 | return -ENOMEM; | ||
418 | |||
419 | handler->query_bit = query_bit; | ||
420 | handler->handle = handle; | ||
421 | handler->func = func; | ||
422 | handler->data = data; | ||
423 | mutex_lock(&ec->lock); | ||
424 | list_add_tail(&handler->node, &ec->list); | ||
425 | mutex_unlock(&ec->lock); | ||
426 | return 0; | ||
427 | } | ||
428 | |||
429 | EXPORT_SYMBOL_GPL(acpi_ec_add_query_handler); | ||
430 | |||
431 | void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit) | ||
432 | { | ||
433 | struct acpi_ec_query_handler *handler; | ||
434 | mutex_lock(&ec->lock); | ||
435 | list_for_each_entry(handler, &ec->list, node) { | ||
436 | if (query_bit == handler->query_bit) { | ||
437 | list_del(&handler->node); | ||
438 | kfree(handler); | ||
439 | break; | ||
440 | } | ||
441 | } | ||
442 | mutex_unlock(&ec->lock); | ||
443 | } | ||
444 | |||
445 | EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler); | ||
397 | 446 | ||
398 | static void acpi_ec_gpe_query(void *ec_cxt) | 447 | static void acpi_ec_gpe_query(void *ec_cxt) |
399 | { | 448 | { |
400 | struct acpi_ec *ec = ec_cxt; | 449 | struct acpi_ec *ec = ec_cxt; |
401 | u8 value = 0; | 450 | u8 value = 0; |
402 | char object_name[8]; | 451 | struct acpi_ec_query_handler *handler, copy; |
403 | 452 | ||
404 | if (!ec || acpi_ec_query(ec, &value)) | 453 | if (!ec || acpi_ec_query(ec, &value)) |
405 | return; | 454 | return; |
406 | 455 | mutex_lock(&ec->lock); | |
407 | snprintf(object_name, 8, "_Q%2.2X", value); | 456 | list_for_each_entry(handler, &ec->list, node) { |
408 | 457 | if (value == handler->query_bit) { | |
409 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s", object_name)); | 458 | /* have custom handler for this bit */ |
410 | 459 | memcpy(©, handler, sizeof(copy)); | |
411 | acpi_evaluate_object(ec->handle, object_name, NULL, NULL); | 460 | mutex_unlock(&ec->lock); |
461 | if (copy.func) { | ||
462 | copy.func(copy.data); | ||
463 | } else if (copy.handle) { | ||
464 | acpi_evaluate_object(copy.handle, NULL, NULL, NULL); | ||
465 | } | ||
466 | return; | ||
467 | } | ||
468 | } | ||
469 | mutex_unlock(&ec->lock); | ||
470 | printk(KERN_ERR PREFIX "Handler for query 0x%x is not found!\n", value); | ||
412 | } | 471 | } |
413 | 472 | ||
414 | static u32 acpi_ec_gpe_handler(void *data) | 473 | static u32 acpi_ec_gpe_handler(void *data) |
@@ -427,8 +486,7 @@ static u32 acpi_ec_gpe_handler(void *data) | |||
427 | if ((value & ACPI_EC_FLAG_SCI) && !atomic_read(&ec->query_pending)) { | 486 | if ((value & ACPI_EC_FLAG_SCI) && !atomic_read(&ec->query_pending)) { |
428 | atomic_set(&ec->query_pending, 1); | 487 | atomic_set(&ec->query_pending, 1); |
429 | status = | 488 | status = |
430 | acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, | 489 | acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec); |
431 | ec); | ||
432 | } | 490 | } |
433 | 491 | ||
434 | return status == AE_OK ? | 492 | return status == AE_OK ? |
@@ -454,57 +512,35 @@ acpi_ec_space_setup(acpi_handle region_handle, | |||
454 | } | 512 | } |
455 | 513 | ||
456 | static acpi_status | 514 | static acpi_status |
457 | acpi_ec_space_handler(u32 function, | 515 | acpi_ec_space_handler(u32 function, acpi_physical_address address, |
458 | acpi_physical_address address, | 516 | u32 bits, acpi_integer *value, |
459 | u32 bit_width, | ||
460 | acpi_integer * value, | ||
461 | void *handler_context, void *region_context) | 517 | void *handler_context, void *region_context) |
462 | { | 518 | { |
463 | int result = 0; | ||
464 | struct acpi_ec *ec = handler_context; | 519 | struct acpi_ec *ec = handler_context; |
465 | u64 temp = *value; | 520 | int result = 0, i = 0; |
466 | acpi_integer f_v = 0; | 521 | u8 temp = 0; |
467 | int i = 0; | ||
468 | 522 | ||
469 | if ((address > 0xFF) || !value || !handler_context) | 523 | if ((address > 0xFF) || !value || !handler_context) |
470 | return AE_BAD_PARAMETER; | 524 | return AE_BAD_PARAMETER; |
471 | 525 | ||
472 | if (bit_width != 8 && acpi_strict) { | 526 | if (function != ACPI_READ && function != ACPI_WRITE) |
473 | return AE_BAD_PARAMETER; | 527 | return AE_BAD_PARAMETER; |
474 | } | ||
475 | |||
476 | next_byte: | ||
477 | switch (function) { | ||
478 | case ACPI_READ: | ||
479 | temp = 0; | ||
480 | result = acpi_ec_read(ec, (u8) address, (u8 *) & temp); | ||
481 | break; | ||
482 | case ACPI_WRITE: | ||
483 | result = acpi_ec_write(ec, (u8) address, (u8) temp); | ||
484 | break; | ||
485 | default: | ||
486 | result = -EINVAL; | ||
487 | goto out; | ||
488 | break; | ||
489 | } | ||
490 | 528 | ||
491 | bit_width -= 8; | 529 | if (bits != 8 && acpi_strict) |
492 | if (bit_width) { | 530 | return AE_BAD_PARAMETER; |
493 | if (function == ACPI_READ) | ||
494 | f_v |= temp << 8 * i; | ||
495 | if (function == ACPI_WRITE) | ||
496 | temp >>= 8; | ||
497 | i++; | ||
498 | address++; | ||
499 | goto next_byte; | ||
500 | } | ||
501 | 531 | ||
502 | if (function == ACPI_READ) { | 532 | while (bits - i > 0) { |
503 | f_v |= temp << 8 * i; | 533 | if (function == ACPI_READ) { |
504 | *value = f_v; | 534 | result = acpi_ec_read(ec, address, &temp); |
535 | (*value) |= ((acpi_integer)temp) << i; | ||
536 | } else { | ||
537 | temp = 0xff & ((*value) >> i); | ||
538 | result = acpi_ec_write(ec, address, temp); | ||
539 | } | ||
540 | i += 8; | ||
541 | ++address; | ||
505 | } | 542 | } |
506 | 543 | ||
507 | out: | ||
508 | switch (result) { | 544 | switch (result) { |
509 | case -EINVAL: | 545 | case -EINVAL: |
510 | return AE_BAD_PARAMETER; | 546 | return AE_BAD_PARAMETER; |
@@ -597,9 +633,6 @@ static int acpi_ec_remove_fs(struct acpi_device *device) | |||
597 | static acpi_status | 633 | static acpi_status |
598 | ec_parse_io_ports(struct acpi_resource *resource, void *context); | 634 | ec_parse_io_ports(struct acpi_resource *resource, void *context); |
599 | 635 | ||
600 | static acpi_status | ||
601 | ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval); | ||
602 | |||
603 | static struct acpi_ec *make_acpi_ec(void) | 636 | static struct acpi_ec *make_acpi_ec(void) |
604 | { | 637 | { |
605 | struct acpi_ec *ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL); | 638 | struct acpi_ec *ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL); |
@@ -610,13 +643,52 @@ static struct acpi_ec *make_acpi_ec(void) | |||
610 | atomic_set(&ec->event_count, 1); | 643 | atomic_set(&ec->event_count, 1); |
611 | mutex_init(&ec->lock); | 644 | mutex_init(&ec->lock); |
612 | init_waitqueue_head(&ec->wait); | 645 | init_waitqueue_head(&ec->wait); |
646 | INIT_LIST_HEAD(&ec->list); | ||
613 | 647 | ||
614 | return ec; | 648 | return ec; |
615 | } | 649 | } |
616 | 650 | ||
651 | static acpi_status | ||
652 | acpi_ec_register_query_methods(acpi_handle handle, u32 level, | ||
653 | void *context, void **return_value) | ||
654 | { | ||
655 | struct acpi_namespace_node *node = handle; | ||
656 | struct acpi_ec *ec = context; | ||
657 | int value = 0; | ||
658 | if (sscanf(node->name.ascii, "_Q%x", &value) == 1) { | ||
659 | acpi_ec_add_query_handler(ec, value, handle, NULL, NULL); | ||
660 | } | ||
661 | return AE_OK; | ||
662 | } | ||
663 | |||
664 | static int ec_parse_device(struct acpi_ec *ec, acpi_handle handle) | ||
665 | { | ||
666 | if (ACPI_FAILURE(acpi_walk_resources(handle, METHOD_NAME__CRS, | ||
667 | ec_parse_io_ports, ec))) | ||
668 | return -EINVAL; | ||
669 | |||
670 | /* Get GPE bit assignment (EC events). */ | ||
671 | /* TODO: Add support for _GPE returning a package */ | ||
672 | if (ACPI_FAILURE(acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe))) | ||
673 | return -EINVAL; | ||
674 | |||
675 | /* Use the global lock for all EC transactions? */ | ||
676 | acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock); | ||
677 | |||
678 | /* Find and register all query methods */ | ||
679 | acpi_walk_namespace(ACPI_TYPE_METHOD, handle, 1, | ||
680 | acpi_ec_register_query_methods, ec, NULL); | ||
681 | |||
682 | ec->handle = handle; | ||
683 | |||
684 | printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx", | ||
685 | ec->gpe, ec->command_addr, ec->data_addr); | ||
686 | |||
687 | return 0; | ||
688 | } | ||
689 | |||
617 | static int acpi_ec_add(struct acpi_device *device) | 690 | static int acpi_ec_add(struct acpi_device *device) |
618 | { | 691 | { |
619 | acpi_status status = AE_OK; | ||
620 | struct acpi_ec *ec = NULL; | 692 | struct acpi_ec *ec = NULL; |
621 | 693 | ||
622 | if (!device) | 694 | if (!device) |
@@ -629,8 +701,7 @@ static int acpi_ec_add(struct acpi_device *device) | |||
629 | if (!ec) | 701 | if (!ec) |
630 | return -ENOMEM; | 702 | return -ENOMEM; |
631 | 703 | ||
632 | status = ec_parse_device(device->handle, 0, ec, NULL); | 704 | if (ec_parse_device(ec, device->handle)) { |
633 | if (status != AE_CTRL_TERMINATE) { | ||
634 | kfree(ec); | 705 | kfree(ec); |
635 | return -EINVAL; | 706 | return -EINVAL; |
636 | } | 707 | } |
@@ -641,6 +712,8 @@ static int acpi_ec_add(struct acpi_device *device) | |||
641 | /* We might have incorrect info for GL at boot time */ | 712 | /* We might have incorrect info for GL at boot time */ |
642 | mutex_lock(&boot_ec->lock); | 713 | mutex_lock(&boot_ec->lock); |
643 | boot_ec->global_lock = ec->global_lock; | 714 | boot_ec->global_lock = ec->global_lock; |
715 | /* Copy handlers from new ec into boot ec */ | ||
716 | list_splice(&ec->list, &boot_ec->list); | ||
644 | mutex_unlock(&boot_ec->lock); | 717 | mutex_unlock(&boot_ec->lock); |
645 | kfree(ec); | 718 | kfree(ec); |
646 | ec = boot_ec; | 719 | ec = boot_ec; |
@@ -651,22 +724,24 @@ static int acpi_ec_add(struct acpi_device *device) | |||
651 | acpi_driver_data(device) = ec; | 724 | acpi_driver_data(device) = ec; |
652 | 725 | ||
653 | acpi_ec_add_fs(device); | 726 | acpi_ec_add_fs(device); |
654 | |||
655 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s [%s] (gpe %d) interrupt mode.", | ||
656 | acpi_device_name(device), acpi_device_bid(device), | ||
657 | (u32) ec->gpe)); | ||
658 | |||
659 | return 0; | 727 | return 0; |
660 | } | 728 | } |
661 | 729 | ||
662 | static int acpi_ec_remove(struct acpi_device *device, int type) | 730 | static int acpi_ec_remove(struct acpi_device *device, int type) |
663 | { | 731 | { |
664 | struct acpi_ec *ec; | 732 | struct acpi_ec *ec; |
733 | struct acpi_ec_query_handler *handler; | ||
665 | 734 | ||
666 | if (!device) | 735 | if (!device) |
667 | return -EINVAL; | 736 | return -EINVAL; |
668 | 737 | ||
669 | ec = acpi_driver_data(device); | 738 | ec = acpi_driver_data(device); |
739 | mutex_lock(&ec->lock); | ||
740 | list_for_each_entry(handler, &ec->list, node) { | ||
741 | list_del(&handler->node); | ||
742 | kfree(handler); | ||
743 | } | ||
744 | mutex_unlock(&ec->lock); | ||
670 | acpi_ec_remove_fs(device); | 745 | acpi_ec_remove_fs(device); |
671 | acpi_driver_data(device) = NULL; | 746 | acpi_driver_data(device) = NULL; |
672 | if (ec == first_ec) | 747 | if (ec == first_ec) |
@@ -722,15 +797,13 @@ static int ec_install_handlers(struct acpi_ec *ec) | |||
722 | return -ENODEV; | 797 | return -ENODEV; |
723 | } | 798 | } |
724 | 799 | ||
725 | /* EC is fully operational, allow queries */ | ||
726 | atomic_set(&ec->query_pending, 0); | ||
727 | |||
728 | return 0; | 800 | return 0; |
729 | } | 801 | } |
730 | 802 | ||
731 | static int acpi_ec_start(struct acpi_device *device) | 803 | static int acpi_ec_start(struct acpi_device *device) |
732 | { | 804 | { |
733 | struct acpi_ec *ec; | 805 | struct acpi_ec *ec; |
806 | int ret = 0; | ||
734 | 807 | ||
735 | if (!device) | 808 | if (!device) |
736 | return -EINVAL; | 809 | return -EINVAL; |
@@ -740,14 +813,14 @@ static int acpi_ec_start(struct acpi_device *device) | |||
740 | if (!ec) | 813 | if (!ec) |
741 | return -EINVAL; | 814 | return -EINVAL; |
742 | 815 | ||
743 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02lx, ports=0x%2lx,0x%2lx", | ||
744 | ec->gpe, ec->command_addr, ec->data_addr)); | ||
745 | |||
746 | /* Boot EC is already working */ | 816 | /* Boot EC is already working */ |
747 | if (ec == boot_ec) | 817 | if (ec != boot_ec) |
748 | return 0; | 818 | ret = ec_install_handlers(ec); |
819 | |||
820 | /* EC is fully operational, allow queries */ | ||
821 | atomic_set(&ec->query_pending, 0); | ||
749 | 822 | ||
750 | return ec_install_handlers(ec); | 823 | return ret; |
751 | } | 824 | } |
752 | 825 | ||
753 | static int acpi_ec_stop(struct acpi_device *device, int type) | 826 | static int acpi_ec_stop(struct acpi_device *device, int type) |
@@ -779,34 +852,6 @@ static int acpi_ec_stop(struct acpi_device *device, int type) | |||
779 | return 0; | 852 | return 0; |
780 | } | 853 | } |
781 | 854 | ||
782 | static acpi_status | ||
783 | ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) | ||
784 | { | ||
785 | acpi_status status; | ||
786 | |||
787 | struct acpi_ec *ec = context; | ||
788 | status = acpi_walk_resources(handle, METHOD_NAME__CRS, | ||
789 | ec_parse_io_ports, ec); | ||
790 | if (ACPI_FAILURE(status)) | ||
791 | return status; | ||
792 | |||
793 | /* Get GPE bit assignment (EC events). */ | ||
794 | /* TODO: Add support for _GPE returning a package */ | ||
795 | status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe); | ||
796 | if (ACPI_FAILURE(status)) | ||
797 | return status; | ||
798 | |||
799 | /* Use the global lock for all EC transactions? */ | ||
800 | acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock); | ||
801 | |||
802 | ec->handle = handle; | ||
803 | |||
804 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "GPE=0x%02lx, ports=0x%2lx, 0x%2lx", | ||
805 | ec->gpe, ec->command_addr, ec->data_addr)); | ||
806 | |||
807 | return AE_CTRL_TERMINATE; | ||
808 | } | ||
809 | |||
810 | int __init acpi_ec_ecdt_probe(void) | 855 | int __init acpi_ec_ecdt_probe(void) |
811 | { | 856 | { |
812 | int ret; | 857 | int ret; |
@@ -825,7 +870,7 @@ int __init acpi_ec_ecdt_probe(void) | |||
825 | if (ACPI_FAILURE(status)) | 870 | if (ACPI_FAILURE(status)) |
826 | goto error; | 871 | goto error; |
827 | 872 | ||
828 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found ECDT")); | 873 | printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n"); |
829 | 874 | ||
830 | boot_ec->command_addr = ecdt_ptr->control.address; | 875 | boot_ec->command_addr = ecdt_ptr->control.address; |
831 | boot_ec->data_addr = ecdt_ptr->data.address; | 876 | boot_ec->data_addr = ecdt_ptr->data.address; |
diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c index 3b23562e6f92..dfa5853b17f0 100644 --- a/drivers/acpi/event.c +++ b/drivers/acpi/event.c | |||
@@ -11,6 +11,8 @@ | |||
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | #include <linux/poll.h> | 12 | #include <linux/poll.h> |
13 | #include <acpi/acpi_drivers.h> | 13 | #include <acpi/acpi_drivers.h> |
14 | #include <net/netlink.h> | ||
15 | #include <net/genetlink.h> | ||
14 | 16 | ||
15 | #define _COMPONENT ACPI_SYSTEM_COMPONENT | 17 | #define _COMPONENT ACPI_SYSTEM_COMPONENT |
16 | ACPI_MODULE_NAME("event"); | 18 | ACPI_MODULE_NAME("event"); |
@@ -48,7 +50,6 @@ acpi_system_read_event(struct file *file, char __user * buffer, size_t count, | |||
48 | static int chars_remaining = 0; | 50 | static int chars_remaining = 0; |
49 | static char *ptr; | 51 | static char *ptr; |
50 | 52 | ||
51 | |||
52 | if (!chars_remaining) { | 53 | if (!chars_remaining) { |
53 | memset(&event, 0, sizeof(struct acpi_bus_event)); | 54 | memset(&event, 0, sizeof(struct acpi_bus_event)); |
54 | 55 | ||
@@ -106,23 +107,161 @@ static const struct file_operations acpi_system_event_ops = { | |||
106 | .poll = acpi_system_poll_event, | 107 | .poll = acpi_system_poll_event, |
107 | }; | 108 | }; |
108 | 109 | ||
110 | #ifdef CONFIG_NET | ||
111 | unsigned int acpi_event_seqnum; | ||
112 | struct acpi_genl_event { | ||
113 | acpi_device_class device_class; | ||
114 | char bus_id[15]; | ||
115 | u32 type; | ||
116 | u32 data; | ||
117 | }; | ||
118 | |||
119 | /* attributes of acpi_genl_family */ | ||
120 | enum { | ||
121 | ACPI_GENL_ATTR_UNSPEC, | ||
122 | ACPI_GENL_ATTR_EVENT, /* ACPI event info needed by user space */ | ||
123 | __ACPI_GENL_ATTR_MAX, | ||
124 | }; | ||
125 | #define ACPI_GENL_ATTR_MAX (__ACPI_GENL_ATTR_MAX - 1) | ||
126 | |||
127 | /* commands supported by the acpi_genl_family */ | ||
128 | enum { | ||
129 | ACPI_GENL_CMD_UNSPEC, | ||
130 | ACPI_GENL_CMD_EVENT, /* kernel->user notifications for ACPI events */ | ||
131 | __ACPI_GENL_CMD_MAX, | ||
132 | }; | ||
133 | #define ACPI_GENL_CMD_MAX (__ACPI_GENL_CMD_MAX - 1) | ||
134 | |||
135 | #define ACPI_GENL_FAMILY_NAME "acpi_event" | ||
136 | #define ACPI_GENL_VERSION 0x01 | ||
137 | #define ACPI_GENL_MCAST_GROUP_NAME "acpi_mc_group" | ||
138 | |||
139 | static struct genl_family acpi_event_genl_family = { | ||
140 | .id = GENL_ID_GENERATE, | ||
141 | .name = ACPI_GENL_FAMILY_NAME, | ||
142 | .version = ACPI_GENL_VERSION, | ||
143 | .maxattr = ACPI_GENL_ATTR_MAX, | ||
144 | }; | ||
145 | |||
146 | static struct genl_multicast_group acpi_event_mcgrp = { | ||
147 | .name = ACPI_GENL_MCAST_GROUP_NAME, | ||
148 | }; | ||
149 | |||
150 | int acpi_bus_generate_genetlink_event(struct acpi_device *device, | ||
151 | u8 type, int data) | ||
152 | { | ||
153 | struct sk_buff *skb; | ||
154 | struct nlattr *attr; | ||
155 | struct acpi_genl_event *event; | ||
156 | void *msg_header; | ||
157 | int size; | ||
158 | int result; | ||
159 | |||
160 | /* allocate memory */ | ||
161 | size = nla_total_size(sizeof(struct acpi_genl_event)) + | ||
162 | nla_total_size(0); | ||
163 | |||
164 | skb = genlmsg_new(size, GFP_ATOMIC); | ||
165 | if (!skb) | ||
166 | return -ENOMEM; | ||
167 | |||
168 | /* add the genetlink message header */ | ||
169 | msg_header = genlmsg_put(skb, 0, acpi_event_seqnum++, | ||
170 | &acpi_event_genl_family, 0, | ||
171 | ACPI_GENL_CMD_EVENT); | ||
172 | if (!msg_header) { | ||
173 | nlmsg_free(skb); | ||
174 | return -ENOMEM; | ||
175 | } | ||
176 | |||
177 | /* fill the data */ | ||
178 | attr = | ||
179 | nla_reserve(skb, ACPI_GENL_ATTR_EVENT, | ||
180 | sizeof(struct acpi_genl_event)); | ||
181 | if (!attr) { | ||
182 | nlmsg_free(skb); | ||
183 | return -EINVAL; | ||
184 | } | ||
185 | |||
186 | event = nla_data(attr); | ||
187 | if (!event) { | ||
188 | nlmsg_free(skb); | ||
189 | return -EINVAL; | ||
190 | } | ||
191 | |||
192 | memset(event, 0, sizeof(struct acpi_genl_event)); | ||
193 | |||
194 | strcpy(event->device_class, device->pnp.device_class); | ||
195 | strcpy(event->bus_id, device->dev.bus_id); | ||
196 | event->type = type; | ||
197 | event->data = data; | ||
198 | |||
199 | /* send multicast genetlink message */ | ||
200 | result = genlmsg_end(skb, msg_header); | ||
201 | if (result < 0) { | ||
202 | nlmsg_free(skb); | ||
203 | return result; | ||
204 | } | ||
205 | |||
206 | result = | ||
207 | genlmsg_multicast(skb, 0, acpi_event_mcgrp.id, GFP_ATOMIC); | ||
208 | if (result) | ||
209 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
210 | "Failed to send a Genetlink message!\n")); | ||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | static int acpi_event_genetlink_init(void) | ||
215 | { | ||
216 | int result; | ||
217 | |||
218 | result = genl_register_family(&acpi_event_genl_family); | ||
219 | if (result) | ||
220 | return result; | ||
221 | |||
222 | result = genl_register_mc_group(&acpi_event_genl_family, | ||
223 | &acpi_event_mcgrp); | ||
224 | if (result) | ||
225 | genl_unregister_family(&acpi_event_genl_family); | ||
226 | |||
227 | return result; | ||
228 | } | ||
229 | |||
230 | #else | ||
231 | int acpi_bus_generate_genetlink_event(struct acpi_device *device, u8 type, | ||
232 | int data) | ||
233 | { | ||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | static int acpi_event_genetlink_init(void) | ||
238 | { | ||
239 | return -ENODEV; | ||
240 | } | ||
241 | #endif | ||
242 | |||
109 | static int __init acpi_event_init(void) | 243 | static int __init acpi_event_init(void) |
110 | { | 244 | { |
111 | struct proc_dir_entry *entry; | 245 | struct proc_dir_entry *entry; |
112 | int error = 0; | 246 | int error = 0; |
113 | 247 | ||
114 | |||
115 | if (acpi_disabled) | 248 | if (acpi_disabled) |
116 | return 0; | 249 | return 0; |
117 | 250 | ||
251 | /* create genetlink for acpi event */ | ||
252 | error = acpi_event_genetlink_init(); | ||
253 | if (error) | ||
254 | printk(KERN_WARNING PREFIX | ||
255 | "Failed to create genetlink family for ACPI event\n"); | ||
256 | |||
118 | /* 'event' [R] */ | 257 | /* 'event' [R] */ |
119 | entry = create_proc_entry("event", S_IRUSR, acpi_root_dir); | 258 | entry = create_proc_entry("event", S_IRUSR, acpi_root_dir); |
120 | if (entry) | 259 | if (entry) |
121 | entry->proc_fops = &acpi_system_event_ops; | 260 | entry->proc_fops = &acpi_system_event_ops; |
122 | else { | 261 | else |
123 | error = -ENODEV; | 262 | return -ENODEV; |
124 | } | 263 | |
125 | return error; | 264 | return 0; |
126 | } | 265 | } |
127 | 266 | ||
128 | subsys_initcall(acpi_event_init); | 267 | fs_initcall(acpi_event_init); |
diff --git a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c index 902c287b3a4f..361ebe6c4a6f 100644 --- a/drivers/acpi/events/evgpeblk.c +++ b/drivers/acpi/events/evgpeblk.c | |||
@@ -586,6 +586,10 @@ acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt) | |||
586 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | 586 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); |
587 | if (gpe_xrupt->previous) { | 587 | if (gpe_xrupt->previous) { |
588 | gpe_xrupt->previous->next = gpe_xrupt->next; | 588 | gpe_xrupt->previous->next = gpe_xrupt->next; |
589 | } else { | ||
590 | /* No previous, update list head */ | ||
591 | |||
592 | acpi_gbl_gpe_xrupt_list_head = gpe_xrupt->next; | ||
589 | } | 593 | } |
590 | 594 | ||
591 | if (gpe_xrupt->next) { | 595 | if (gpe_xrupt->next) { |
diff --git a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c index 400d90fca966..23ee7bc4a705 100644 --- a/drivers/acpi/events/evrgnini.c +++ b/drivers/acpi/events/evrgnini.c | |||
@@ -284,6 +284,7 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, | |||
284 | } | 284 | } |
285 | 285 | ||
286 | if (!pci_device_node) { | 286 | if (!pci_device_node) { |
287 | ACPI_FREE(pci_id); | ||
287 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | 288 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
288 | } | 289 | } |
289 | 290 | ||
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 41427a41f620..4893e256e399 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c | |||
@@ -16,7 +16,7 @@ | |||
16 | #if ACPI_GLUE_DEBUG | 16 | #if ACPI_GLUE_DEBUG |
17 | #define DBG(x...) printk(PREFIX x) | 17 | #define DBG(x...) printk(PREFIX x) |
18 | #else | 18 | #else |
19 | #define DBG(x...) | 19 | #define DBG(x...) do { } while(0) |
20 | #endif | 20 | #endif |
21 | static LIST_HEAD(bus_type_list); | 21 | static LIST_HEAD(bus_type_list); |
22 | static DECLARE_RWSEM(bus_type_sem); | 22 | static DECLARE_RWSEM(bus_type_sem); |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 00d53c2fd1e8..12c09fafce9a 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -77,13 +77,7 @@ static struct workqueue_struct *kacpi_notify_wq; | |||
77 | #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ | 77 | #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ |
78 | static char osi_additional_string[OSI_STRING_LENGTH_MAX]; | 78 | static char osi_additional_string[OSI_STRING_LENGTH_MAX]; |
79 | 79 | ||
80 | #define OSI_LINUX_ENABLED | 80 | static int osi_linux; /* disable _OSI(Linux) by default */ |
81 | #ifdef OSI_LINUX_ENABLED | ||
82 | int osi_linux = 1; /* enable _OSI(Linux) by default */ | ||
83 | #else | ||
84 | int osi_linux; /* disable _OSI(Linux) by default */ | ||
85 | #endif | ||
86 | |||
87 | 81 | ||
88 | #ifdef CONFIG_DMI | 82 | #ifdef CONFIG_DMI |
89 | static struct __initdata dmi_system_id acpi_osl_dmi_table[]; | 83 | static struct __initdata dmi_system_id acpi_osl_dmi_table[]; |
@@ -1183,17 +1177,10 @@ acpi_os_validate_interface (char *interface) | |||
1183 | if (!strcmp("Linux", interface)) { | 1177 | if (!strcmp("Linux", interface)) { |
1184 | printk(KERN_WARNING PREFIX | 1178 | printk(KERN_WARNING PREFIX |
1185 | "System BIOS is requesting _OSI(Linux)\n"); | 1179 | "System BIOS is requesting _OSI(Linux)\n"); |
1186 | #ifdef OSI_LINUX_ENABLED | ||
1187 | printk(KERN_WARNING PREFIX | ||
1188 | "Please test with \"acpi_osi=!Linux\"\n" | ||
1189 | "Please send dmidecode " | ||
1190 | "to linux-acpi@vger.kernel.org\n"); | ||
1191 | #else | ||
1192 | printk(KERN_WARNING PREFIX | 1180 | printk(KERN_WARNING PREFIX |
1193 | "If \"acpi_osi=Linux\" works better,\n" | 1181 | "If \"acpi_osi=Linux\" works better,\n" |
1194 | "Please send dmidecode " | 1182 | "Please send dmidecode " |
1195 | "to linux-acpi@vger.kernel.org\n"); | 1183 | "to linux-acpi@vger.kernel.org\n"); |
1196 | #endif | ||
1197 | if(osi_linux) | 1184 | if(osi_linux) |
1198 | return AE_OK; | 1185 | return AE_OK; |
1199 | } | 1186 | } |
@@ -1227,36 +1214,14 @@ acpi_os_validate_address ( | |||
1227 | } | 1214 | } |
1228 | 1215 | ||
1229 | #ifdef CONFIG_DMI | 1216 | #ifdef CONFIG_DMI |
1230 | #ifdef OSI_LINUX_ENABLED | ||
1231 | static int dmi_osi_not_linux(struct dmi_system_id *d) | ||
1232 | { | ||
1233 | printk(KERN_NOTICE "%s detected: requires not _OSI(Linux)\n", d->ident); | ||
1234 | enable_osi_linux(0); | ||
1235 | return 0; | ||
1236 | } | ||
1237 | #else | ||
1238 | static int dmi_osi_linux(struct dmi_system_id *d) | 1217 | static int dmi_osi_linux(struct dmi_system_id *d) |
1239 | { | 1218 | { |
1240 | printk(KERN_NOTICE "%s detected: requires _OSI(Linux)\n", d->ident); | 1219 | printk(KERN_NOTICE "%s detected: enabling _OSI(Linux)\n", d->ident); |
1241 | enable_osi_linux(1); | 1220 | enable_osi_linux(1); |
1242 | return 0; | 1221 | return 0; |
1243 | } | 1222 | } |
1244 | #endif | ||
1245 | 1223 | ||
1246 | static struct dmi_system_id acpi_osl_dmi_table[] __initdata = { | 1224 | static struct dmi_system_id acpi_osl_dmi_table[] __initdata = { |
1247 | #ifdef OSI_LINUX_ENABLED | ||
1248 | /* | ||
1249 | * Boxes that need NOT _OSI(Linux) | ||
1250 | */ | ||
1251 | { | ||
1252 | .callback = dmi_osi_not_linux, | ||
1253 | .ident = "Toshiba Satellite P100", | ||
1254 | .matches = { | ||
1255 | DMI_MATCH(DMI_BOARD_VENDOR, "TOSHIBA"), | ||
1256 | DMI_MATCH(DMI_BOARD_NAME, "Satellite P100"), | ||
1257 | }, | ||
1258 | }, | ||
1259 | #else | ||
1260 | /* | 1225 | /* |
1261 | * Boxes that need _OSI(Linux) | 1226 | * Boxes that need _OSI(Linux) |
1262 | */ | 1227 | */ |
@@ -1268,7 +1233,6 @@ static struct dmi_system_id acpi_osl_dmi_table[] __initdata = { | |||
1268 | DMI_MATCH(DMI_BOARD_NAME, "MPAD-MSAE Customer Reference Boards"), | 1233 | DMI_MATCH(DMI_BOARD_NAME, "MPAD-MSAE Customer Reference Boards"), |
1269 | }, | 1234 | }, |
1270 | }, | 1235 | }, |
1271 | #endif | ||
1272 | {} | 1236 | {} |
1273 | }; | 1237 | }; |
1274 | #endif /* CONFIG_DMI */ | 1238 | #endif /* CONFIG_DMI */ |
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index acc594771379..3448edd61dc4 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c | |||
@@ -733,7 +733,7 @@ static int acpi_pci_link_add(struct acpi_device *device) | |||
733 | /* query and set link->irq.active */ | 733 | /* query and set link->irq.active */ |
734 | acpi_pci_link_get_current(link); | 734 | acpi_pci_link_get_current(link); |
735 | 735 | ||
736 | printk(PREFIX "%s [%s] (IRQs", acpi_device_name(device), | 736 | printk(KERN_INFO PREFIX "%s [%s] (IRQs", acpi_device_name(device), |
737 | acpi_device_bid(device)); | 737 | acpi_device_bid(device)); |
738 | for (i = 0; i < link->irq.possible_count; i++) { | 738 | for (i = 0; i < link->irq.possible_count; i++) { |
739 | if (link->irq.active == link->irq.possible[i]) { | 739 | if (link->irq.active == link->irq.possible[i]) { |
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index e1ca86dfdd66..81aceb5da7c7 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -66,6 +66,7 @@ | |||
66 | #define ACPI_PROCESSOR_FILE_LIMIT "limit" | 66 | #define ACPI_PROCESSOR_FILE_LIMIT "limit" |
67 | #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80 | 67 | #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80 |
68 | #define ACPI_PROCESSOR_NOTIFY_POWER 0x81 | 68 | #define ACPI_PROCESSOR_NOTIFY_POWER 0x81 |
69 | #define ACPI_PROCESSOR_NOTIFY_THROTTLING 0x82 | ||
69 | 70 | ||
70 | #define ACPI_PROCESSOR_LIMIT_USER 0 | 71 | #define ACPI_PROCESSOR_LIMIT_USER 0 |
71 | #define ACPI_PROCESSOR_LIMIT_THERMAL 1 | 72 | #define ACPI_PROCESSOR_LIMIT_THERMAL 1 |
@@ -84,6 +85,8 @@ static int acpi_processor_info_open_fs(struct inode *inode, struct file *file); | |||
84 | static void acpi_processor_notify(acpi_handle handle, u32 event, void *data); | 85 | static void acpi_processor_notify(acpi_handle handle, u32 event, void *data); |
85 | static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu); | 86 | static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu); |
86 | static int acpi_processor_handle_eject(struct acpi_processor *pr); | 87 | static int acpi_processor_handle_eject(struct acpi_processor *pr); |
88 | extern int acpi_processor_tstate_has_changed(struct acpi_processor *pr); | ||
89 | |||
87 | 90 | ||
88 | static struct acpi_driver acpi_processor_driver = { | 91 | static struct acpi_driver acpi_processor_driver = { |
89 | .name = "processor", | 92 | .name = "processor", |
@@ -696,6 +699,9 @@ static void acpi_processor_notify(acpi_handle handle, u32 event, void *data) | |||
696 | acpi_processor_cst_has_changed(pr); | 699 | acpi_processor_cst_has_changed(pr); |
697 | acpi_bus_generate_event(device, event, 0); | 700 | acpi_bus_generate_event(device, event, 0); |
698 | break; | 701 | break; |
702 | case ACPI_PROCESSOR_NOTIFY_THROTTLING: | ||
703 | acpi_processor_tstate_has_changed(pr); | ||
704 | acpi_bus_generate_event(device, event, 0); | ||
699 | default: | 705 | default: |
700 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 706 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
701 | "Unsupported event [0x%x]\n", event)); | 707 | "Unsupported event [0x%x]\n", event)); |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index bb5d23be4260..a898991f77cb 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -490,7 +490,17 @@ static void acpi_processor_idle(void) | |||
490 | 490 | ||
491 | case ACPI_STATE_C3: | 491 | case ACPI_STATE_C3: |
492 | 492 | ||
493 | if (pr->flags.bm_check) { | 493 | /* |
494 | * disable bus master | ||
495 | * bm_check implies we need ARB_DIS | ||
496 | * !bm_check implies we need cache flush | ||
497 | * bm_control implies whether we can do ARB_DIS | ||
498 | * | ||
499 | * That leaves a case where bm_check is set and bm_control is | ||
500 | * not set. In that case we cannot do much, we enter C3 | ||
501 | * without doing anything. | ||
502 | */ | ||
503 | if (pr->flags.bm_check && pr->flags.bm_control) { | ||
494 | if (atomic_inc_return(&c3_cpu_count) == | 504 | if (atomic_inc_return(&c3_cpu_count) == |
495 | num_online_cpus()) { | 505 | num_online_cpus()) { |
496 | /* | 506 | /* |
@@ -499,7 +509,7 @@ static void acpi_processor_idle(void) | |||
499 | */ | 509 | */ |
500 | acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1); | 510 | acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1); |
501 | } | 511 | } |
502 | } else { | 512 | } else if (!pr->flags.bm_check) { |
503 | /* SMP with no shared cache... Invalidate cache */ | 513 | /* SMP with no shared cache... Invalidate cache */ |
504 | ACPI_FLUSH_CPU_CACHE(); | 514 | ACPI_FLUSH_CPU_CACHE(); |
505 | } | 515 | } |
@@ -511,7 +521,7 @@ static void acpi_processor_idle(void) | |||
511 | acpi_cstate_enter(cx); | 521 | acpi_cstate_enter(cx); |
512 | /* Get end time (ticks) */ | 522 | /* Get end time (ticks) */ |
513 | t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); | 523 | t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); |
514 | if (pr->flags.bm_check) { | 524 | if (pr->flags.bm_check && pr->flags.bm_control) { |
515 | /* Enable bus master arbitration */ | 525 | /* Enable bus master arbitration */ |
516 | atomic_dec(&c3_cpu_count); | 526 | atomic_dec(&c3_cpu_count); |
517 | acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); | 527 | acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); |
@@ -961,9 +971,9 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr, | |||
961 | if (pr->flags.bm_check) { | 971 | if (pr->flags.bm_check) { |
962 | /* bus mastering control is necessary */ | 972 | /* bus mastering control is necessary */ |
963 | if (!pr->flags.bm_control) { | 973 | if (!pr->flags.bm_control) { |
974 | /* In this case we enter C3 without bus mastering */ | ||
964 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 975 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
965 | "C3 support requires bus mastering control\n")); | 976 | "C3 support without bus mastering control\n")); |
966 | return; | ||
967 | } | 977 | } |
968 | } else { | 978 | } else { |
969 | /* | 979 | /* |
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index b33486009f41..0b8204e7082a 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c | |||
@@ -44,17 +44,251 @@ | |||
44 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT | 44 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT |
45 | ACPI_MODULE_NAME("processor_throttling"); | 45 | ACPI_MODULE_NAME("processor_throttling"); |
46 | 46 | ||
47 | static int acpi_processor_get_throttling(struct acpi_processor *pr); | ||
48 | int acpi_processor_set_throttling(struct acpi_processor *pr, int state); | ||
49 | |||
50 | /* | ||
51 | * _TPC - Throttling Present Capabilities | ||
52 | */ | ||
53 | static int acpi_processor_get_platform_limit(struct acpi_processor *pr) | ||
54 | { | ||
55 | acpi_status status = 0; | ||
56 | unsigned long tpc = 0; | ||
57 | |||
58 | if (!pr) | ||
59 | return -EINVAL; | ||
60 | status = acpi_evaluate_integer(pr->handle, "_TPC", NULL, &tpc); | ||
61 | if (ACPI_FAILURE(status)) { | ||
62 | if (status != AE_NOT_FOUND) { | ||
63 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _TPC")); | ||
64 | } | ||
65 | return -ENODEV; | ||
66 | } | ||
67 | pr->throttling_platform_limit = (int)tpc; | ||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | int acpi_processor_tstate_has_changed(struct acpi_processor *pr) | ||
72 | { | ||
73 | return acpi_processor_get_platform_limit(pr); | ||
74 | } | ||
75 | |||
76 | /* | ||
77 | * _PTC - Processor Throttling Control (and status) register location | ||
78 | */ | ||
79 | static int acpi_processor_get_throttling_control(struct acpi_processor *pr) | ||
80 | { | ||
81 | int result = 0; | ||
82 | acpi_status status = 0; | ||
83 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
84 | union acpi_object *ptc = NULL; | ||
85 | union acpi_object obj = { 0 }; | ||
86 | |||
87 | status = acpi_evaluate_object(pr->handle, "_PTC", NULL, &buffer); | ||
88 | if (ACPI_FAILURE(status)) { | ||
89 | if (status != AE_NOT_FOUND) { | ||
90 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PTC")); | ||
91 | } | ||
92 | return -ENODEV; | ||
93 | } | ||
94 | |||
95 | ptc = (union acpi_object *)buffer.pointer; | ||
96 | if (!ptc || (ptc->type != ACPI_TYPE_PACKAGE) | ||
97 | || (ptc->package.count != 2)) { | ||
98 | printk(KERN_ERR PREFIX "Invalid _PTC data\n"); | ||
99 | result = -EFAULT; | ||
100 | goto end; | ||
101 | } | ||
102 | |||
103 | /* | ||
104 | * control_register | ||
105 | */ | ||
106 | |||
107 | obj = ptc->package.elements[0]; | ||
108 | |||
109 | if ((obj.type != ACPI_TYPE_BUFFER) | ||
110 | || (obj.buffer.length < sizeof(struct acpi_ptc_register)) | ||
111 | || (obj.buffer.pointer == NULL)) { | ||
112 | printk(KERN_ERR PREFIX | ||
113 | "Invalid _PTC data (control_register)\n"); | ||
114 | result = -EFAULT; | ||
115 | goto end; | ||
116 | } | ||
117 | memcpy(&pr->throttling.control_register, obj.buffer.pointer, | ||
118 | sizeof(struct acpi_ptc_register)); | ||
119 | |||
120 | /* | ||
121 | * status_register | ||
122 | */ | ||
123 | |||
124 | obj = ptc->package.elements[1]; | ||
125 | |||
126 | if ((obj.type != ACPI_TYPE_BUFFER) | ||
127 | || (obj.buffer.length < sizeof(struct acpi_ptc_register)) | ||
128 | || (obj.buffer.pointer == NULL)) { | ||
129 | printk(KERN_ERR PREFIX "Invalid _PTC data (status_register)\n"); | ||
130 | result = -EFAULT; | ||
131 | goto end; | ||
132 | } | ||
133 | |||
134 | memcpy(&pr->throttling.status_register, obj.buffer.pointer, | ||
135 | sizeof(struct acpi_ptc_register)); | ||
136 | |||
137 | end: | ||
138 | kfree(buffer.pointer); | ||
139 | |||
140 | return result; | ||
141 | } | ||
142 | |||
143 | /* | ||
144 | * _TSS - Throttling Supported States | ||
145 | */ | ||
146 | static int acpi_processor_get_throttling_states(struct acpi_processor *pr) | ||
147 | { | ||
148 | int result = 0; | ||
149 | acpi_status status = AE_OK; | ||
150 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
151 | struct acpi_buffer format = { sizeof("NNNNN"), "NNNNN" }; | ||
152 | struct acpi_buffer state = { 0, NULL }; | ||
153 | union acpi_object *tss = NULL; | ||
154 | int i; | ||
155 | |||
156 | status = acpi_evaluate_object(pr->handle, "_TSS", NULL, &buffer); | ||
157 | if (ACPI_FAILURE(status)) { | ||
158 | if (status != AE_NOT_FOUND) { | ||
159 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _TSS")); | ||
160 | } | ||
161 | return -ENODEV; | ||
162 | } | ||
163 | |||
164 | tss = buffer.pointer; | ||
165 | if (!tss || (tss->type != ACPI_TYPE_PACKAGE)) { | ||
166 | printk(KERN_ERR PREFIX "Invalid _TSS data\n"); | ||
167 | result = -EFAULT; | ||
168 | goto end; | ||
169 | } | ||
170 | |||
171 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d throttling states\n", | ||
172 | tss->package.count)); | ||
173 | |||
174 | pr->throttling.state_count = tss->package.count; | ||
175 | pr->throttling.states_tss = | ||
176 | kmalloc(sizeof(struct acpi_processor_tx_tss) * tss->package.count, | ||
177 | GFP_KERNEL); | ||
178 | if (!pr->throttling.states_tss) { | ||
179 | result = -ENOMEM; | ||
180 | goto end; | ||
181 | } | ||
182 | |||
183 | for (i = 0; i < pr->throttling.state_count; i++) { | ||
184 | |||
185 | struct acpi_processor_tx_tss *tx = | ||
186 | (struct acpi_processor_tx_tss *)&(pr->throttling. | ||
187 | states_tss[i]); | ||
188 | |||
189 | state.length = sizeof(struct acpi_processor_tx_tss); | ||
190 | state.pointer = tx; | ||
191 | |||
192 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Extracting state %d\n", i)); | ||
193 | |||
194 | status = acpi_extract_package(&(tss->package.elements[i]), | ||
195 | &format, &state); | ||
196 | if (ACPI_FAILURE(status)) { | ||
197 | ACPI_EXCEPTION((AE_INFO, status, "Invalid _TSS data")); | ||
198 | result = -EFAULT; | ||
199 | kfree(pr->throttling.states_tss); | ||
200 | goto end; | ||
201 | } | ||
202 | |||
203 | if (!tx->freqpercentage) { | ||
204 | printk(KERN_ERR PREFIX | ||
205 | "Invalid _TSS data: freq is zero\n"); | ||
206 | result = -EFAULT; | ||
207 | kfree(pr->throttling.states_tss); | ||
208 | goto end; | ||
209 | } | ||
210 | } | ||
211 | |||
212 | end: | ||
213 | kfree(buffer.pointer); | ||
214 | |||
215 | return result; | ||
216 | } | ||
217 | |||
218 | /* | ||
219 | * _TSD - T-State Dependencies | ||
220 | */ | ||
221 | static int acpi_processor_get_tsd(struct acpi_processor *pr) | ||
222 | { | ||
223 | int result = 0; | ||
224 | acpi_status status = AE_OK; | ||
225 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
226 | struct acpi_buffer format = { sizeof("NNNNN"), "NNNNN" }; | ||
227 | struct acpi_buffer state = { 0, NULL }; | ||
228 | union acpi_object *tsd = NULL; | ||
229 | struct acpi_tsd_package *pdomain; | ||
230 | |||
231 | status = acpi_evaluate_object(pr->handle, "_TSD", NULL, &buffer); | ||
232 | if (ACPI_FAILURE(status)) { | ||
233 | if (status != AE_NOT_FOUND) { | ||
234 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _TSD")); | ||
235 | } | ||
236 | return -ENODEV; | ||
237 | } | ||
238 | |||
239 | tsd = buffer.pointer; | ||
240 | if (!tsd || (tsd->type != ACPI_TYPE_PACKAGE)) { | ||
241 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _TSD data\n")); | ||
242 | result = -EFAULT; | ||
243 | goto end; | ||
244 | } | ||
245 | |||
246 | if (tsd->package.count != 1) { | ||
247 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _TSD data\n")); | ||
248 | result = -EFAULT; | ||
249 | goto end; | ||
250 | } | ||
251 | |||
252 | pdomain = &(pr->throttling.domain_info); | ||
253 | |||
254 | state.length = sizeof(struct acpi_tsd_package); | ||
255 | state.pointer = pdomain; | ||
256 | |||
257 | status = acpi_extract_package(&(tsd->package.elements[0]), | ||
258 | &format, &state); | ||
259 | if (ACPI_FAILURE(status)) { | ||
260 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _TSD data\n")); | ||
261 | result = -EFAULT; | ||
262 | goto end; | ||
263 | } | ||
264 | |||
265 | if (pdomain->num_entries != ACPI_TSD_REV0_ENTRIES) { | ||
266 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _TSD:num_entries\n")); | ||
267 | result = -EFAULT; | ||
268 | goto end; | ||
269 | } | ||
270 | |||
271 | if (pdomain->revision != ACPI_TSD_REV0_REVISION) { | ||
272 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _TSD:revision\n")); | ||
273 | result = -EFAULT; | ||
274 | goto end; | ||
275 | } | ||
276 | |||
277 | end: | ||
278 | kfree(buffer.pointer); | ||
279 | return result; | ||
280 | } | ||
281 | |||
47 | /* -------------------------------------------------------------------------- | 282 | /* -------------------------------------------------------------------------- |
48 | Throttling Control | 283 | Throttling Control |
49 | -------------------------------------------------------------------------- */ | 284 | -------------------------------------------------------------------------- */ |
50 | static int acpi_processor_get_throttling(struct acpi_processor *pr) | 285 | static int acpi_processor_get_throttling_fadt(struct acpi_processor *pr) |
51 | { | 286 | { |
52 | int state = 0; | 287 | int state = 0; |
53 | u32 value = 0; | 288 | u32 value = 0; |
54 | u32 duty_mask = 0; | 289 | u32 duty_mask = 0; |
55 | u32 duty_value = 0; | 290 | u32 duty_value = 0; |
56 | 291 | ||
57 | |||
58 | if (!pr) | 292 | if (!pr) |
59 | return -EINVAL; | 293 | return -EINVAL; |
60 | 294 | ||
@@ -94,13 +328,115 @@ static int acpi_processor_get_throttling(struct acpi_processor *pr) | |||
94 | return 0; | 328 | return 0; |
95 | } | 329 | } |
96 | 330 | ||
97 | int acpi_processor_set_throttling(struct acpi_processor *pr, int state) | 331 | static int acpi_read_throttling_status(struct acpi_processor_throttling |
332 | *throttling) | ||
333 | { | ||
334 | int value = -1; | ||
335 | switch (throttling->status_register.space_id) { | ||
336 | case ACPI_ADR_SPACE_SYSTEM_IO: | ||
337 | acpi_os_read_port((acpi_io_address) throttling->status_register. | ||
338 | address, &value, | ||
339 | (u32) throttling->status_register.bit_width * | ||
340 | 8); | ||
341 | break; | ||
342 | case ACPI_ADR_SPACE_FIXED_HARDWARE: | ||
343 | printk(KERN_ERR PREFIX | ||
344 | "HARDWARE addr space,NOT supported yet\n"); | ||
345 | break; | ||
346 | default: | ||
347 | printk(KERN_ERR PREFIX "Unknown addr space %d\n", | ||
348 | (u32) (throttling->status_register.space_id)); | ||
349 | } | ||
350 | return value; | ||
351 | } | ||
352 | |||
353 | static int acpi_write_throttling_state(struct acpi_processor_throttling | ||
354 | *throttling, int value) | ||
355 | { | ||
356 | int ret = -1; | ||
357 | |||
358 | switch (throttling->control_register.space_id) { | ||
359 | case ACPI_ADR_SPACE_SYSTEM_IO: | ||
360 | acpi_os_write_port((acpi_io_address) throttling-> | ||
361 | control_register.address, value, | ||
362 | (u32) throttling->control_register. | ||
363 | bit_width * 8); | ||
364 | ret = 0; | ||
365 | break; | ||
366 | case ACPI_ADR_SPACE_FIXED_HARDWARE: | ||
367 | printk(KERN_ERR PREFIX | ||
368 | "HARDWARE addr space,NOT supported yet\n"); | ||
369 | break; | ||
370 | default: | ||
371 | printk(KERN_ERR PREFIX "Unknown addr space %d\n", | ||
372 | (u32) (throttling->control_register.space_id)); | ||
373 | } | ||
374 | return ret; | ||
375 | } | ||
376 | |||
377 | static int acpi_get_throttling_state(struct acpi_processor *pr, int value) | ||
378 | { | ||
379 | int i; | ||
380 | |||
381 | for (i = 0; i < pr->throttling.state_count; i++) { | ||
382 | struct acpi_processor_tx_tss *tx = | ||
383 | (struct acpi_processor_tx_tss *)&(pr->throttling. | ||
384 | states_tss[i]); | ||
385 | if (tx->control == value) | ||
386 | break; | ||
387 | } | ||
388 | if (i > pr->throttling.state_count) | ||
389 | i = -1; | ||
390 | return i; | ||
391 | } | ||
392 | |||
393 | static int acpi_get_throttling_value(struct acpi_processor *pr, int state) | ||
394 | { | ||
395 | int value = -1; | ||
396 | if (state >= 0 && state <= pr->throttling.state_count) { | ||
397 | struct acpi_processor_tx_tss *tx = | ||
398 | (struct acpi_processor_tx_tss *)&(pr->throttling. | ||
399 | states_tss[state]); | ||
400 | value = tx->control; | ||
401 | } | ||
402 | return value; | ||
403 | } | ||
404 | |||
405 | static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr) | ||
406 | { | ||
407 | int state = 0; | ||
408 | u32 value = 0; | ||
409 | |||
410 | if (!pr) | ||
411 | return -EINVAL; | ||
412 | |||
413 | if (!pr->flags.throttling) | ||
414 | return -ENODEV; | ||
415 | |||
416 | pr->throttling.state = 0; | ||
417 | local_irq_disable(); | ||
418 | value = acpi_read_throttling_status(&pr->throttling); | ||
419 | if (value >= 0) { | ||
420 | state = acpi_get_throttling_state(pr, value); | ||
421 | pr->throttling.state = state; | ||
422 | } | ||
423 | local_irq_enable(); | ||
424 | |||
425 | return 0; | ||
426 | } | ||
427 | |||
428 | static int acpi_processor_get_throttling(struct acpi_processor *pr) | ||
429 | { | ||
430 | return pr->throttling.acpi_processor_get_throttling(pr); | ||
431 | } | ||
432 | |||
433 | static int acpi_processor_set_throttling_fadt(struct acpi_processor *pr, | ||
434 | int state) | ||
98 | { | 435 | { |
99 | u32 value = 0; | 436 | u32 value = 0; |
100 | u32 duty_mask = 0; | 437 | u32 duty_mask = 0; |
101 | u32 duty_value = 0; | 438 | u32 duty_value = 0; |
102 | 439 | ||
103 | |||
104 | if (!pr) | 440 | if (!pr) |
105 | return -EINVAL; | 441 | return -EINVAL; |
106 | 442 | ||
@@ -113,6 +449,8 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state) | |||
113 | if (state == pr->throttling.state) | 449 | if (state == pr->throttling.state) |
114 | return 0; | 450 | return 0; |
115 | 451 | ||
452 | if (state < pr->throttling_platform_limit) | ||
453 | return -EPERM; | ||
116 | /* | 454 | /* |
117 | * Calculate the duty_value and duty_mask. | 455 | * Calculate the duty_value and duty_mask. |
118 | */ | 456 | */ |
@@ -165,13 +503,49 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state) | |||
165 | return 0; | 503 | return 0; |
166 | } | 504 | } |
167 | 505 | ||
506 | static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr, | ||
507 | int state) | ||
508 | { | ||
509 | u32 value = 0; | ||
510 | |||
511 | if (!pr) | ||
512 | return -EINVAL; | ||
513 | |||
514 | if ((state < 0) || (state > (pr->throttling.state_count - 1))) | ||
515 | return -EINVAL; | ||
516 | |||
517 | if (!pr->flags.throttling) | ||
518 | return -ENODEV; | ||
519 | |||
520 | if (state == pr->throttling.state) | ||
521 | return 0; | ||
522 | |||
523 | if (state < pr->throttling_platform_limit) | ||
524 | return -EPERM; | ||
525 | |||
526 | local_irq_disable(); | ||
527 | |||
528 | value = acpi_get_throttling_value(pr, state); | ||
529 | if (value >= 0) { | ||
530 | acpi_write_throttling_state(&pr->throttling, value); | ||
531 | pr->throttling.state = state; | ||
532 | } | ||
533 | local_irq_enable(); | ||
534 | |||
535 | return 0; | ||
536 | } | ||
537 | |||
538 | int acpi_processor_set_throttling(struct acpi_processor *pr, int state) | ||
539 | { | ||
540 | return pr->throttling.acpi_processor_set_throttling(pr, state); | ||
541 | } | ||
542 | |||
168 | int acpi_processor_get_throttling_info(struct acpi_processor *pr) | 543 | int acpi_processor_get_throttling_info(struct acpi_processor *pr) |
169 | { | 544 | { |
170 | int result = 0; | 545 | int result = 0; |
171 | int step = 0; | 546 | int step = 0; |
172 | int i = 0; | 547 | int i = 0; |
173 | 548 | ||
174 | |||
175 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 549 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
176 | "pblk_address[0x%08x] duty_offset[%d] duty_width[%d]\n", | 550 | "pblk_address[0x%08x] duty_offset[%d] duty_width[%d]\n", |
177 | pr->throttling.address, | 551 | pr->throttling.address, |
@@ -181,7 +555,26 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr) | |||
181 | if (!pr) | 555 | if (!pr) |
182 | return -EINVAL; | 556 | return -EINVAL; |
183 | 557 | ||
184 | /* TBD: Support ACPI 2.0 objects */ | 558 | /* |
559 | * Evaluate _PTC, _TSS and _TPC | ||
560 | * They must all be present or none of them can be used. | ||
561 | */ | ||
562 | if (acpi_processor_get_throttling_control(pr) || | ||
563 | acpi_processor_get_throttling_states(pr) || | ||
564 | acpi_processor_get_platform_limit(pr)) | ||
565 | { | ||
566 | pr->throttling.acpi_processor_get_throttling = | ||
567 | &acpi_processor_get_throttling_fadt; | ||
568 | pr->throttling.acpi_processor_set_throttling = | ||
569 | &acpi_processor_set_throttling_fadt; | ||
570 | } else { | ||
571 | pr->throttling.acpi_processor_get_throttling = | ||
572 | &acpi_processor_get_throttling_ptc; | ||
573 | pr->throttling.acpi_processor_set_throttling = | ||
574 | &acpi_processor_set_throttling_ptc; | ||
575 | } | ||
576 | |||
577 | acpi_processor_get_tsd(pr); | ||
185 | 578 | ||
186 | if (!pr->throttling.address) { | 579 | if (!pr->throttling.address) { |
187 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling register\n")); | 580 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling register\n")); |
@@ -262,7 +655,6 @@ static int acpi_processor_throttling_seq_show(struct seq_file *seq, | |||
262 | int i = 0; | 655 | int i = 0; |
263 | int result = 0; | 656 | int result = 0; |
264 | 657 | ||
265 | |||
266 | if (!pr) | 658 | if (!pr) |
267 | goto end; | 659 | goto end; |
268 | 660 | ||
@@ -280,15 +672,27 @@ static int acpi_processor_throttling_seq_show(struct seq_file *seq, | |||
280 | } | 672 | } |
281 | 673 | ||
282 | seq_printf(seq, "state count: %d\n" | 674 | seq_printf(seq, "state count: %d\n" |
283 | "active state: T%d\n", | 675 | "active state: T%d\n" |
284 | pr->throttling.state_count, pr->throttling.state); | 676 | "state available: T%d to T%d\n", |
677 | pr->throttling.state_count, pr->throttling.state, | ||
678 | pr->throttling_platform_limit, | ||
679 | pr->throttling.state_count - 1); | ||
285 | 680 | ||
286 | seq_puts(seq, "states:\n"); | 681 | seq_puts(seq, "states:\n"); |
287 | for (i = 0; i < pr->throttling.state_count; i++) | 682 | if (pr->throttling.acpi_processor_get_throttling == |
288 | seq_printf(seq, " %cT%d: %02d%%\n", | 683 | acpi_processor_get_throttling_fadt) { |
289 | (i == pr->throttling.state ? '*' : ' '), i, | 684 | for (i = 0; i < pr->throttling.state_count; i++) |
290 | (pr->throttling.states[i].performance ? pr-> | 685 | seq_printf(seq, " %cT%d: %02d%%\n", |
291 | throttling.states[i].performance / 10 : 0)); | 686 | (i == pr->throttling.state ? '*' : ' '), i, |
687 | (pr->throttling.states[i].performance ? pr-> | ||
688 | throttling.states[i].performance / 10 : 0)); | ||
689 | } else { | ||
690 | for (i = 0; i < pr->throttling.state_count; i++) | ||
691 | seq_printf(seq, " %cT%d: %02d%%\n", | ||
692 | (i == pr->throttling.state ? '*' : ' '), i, | ||
693 | (int)pr->throttling.states_tss[i]. | ||
694 | freqpercentage); | ||
695 | } | ||
292 | 696 | ||
293 | end: | 697 | end: |
294 | return 0; | 698 | return 0; |
@@ -301,7 +705,7 @@ static int acpi_processor_throttling_open_fs(struct inode *inode, | |||
301 | PDE(inode)->data); | 705 | PDE(inode)->data); |
302 | } | 706 | } |
303 | 707 | ||
304 | static ssize_t acpi_processor_write_throttling(struct file * file, | 708 | static ssize_t acpi_processor_write_throttling(struct file *file, |
305 | const char __user * buffer, | 709 | const char __user * buffer, |
306 | size_t count, loff_t * data) | 710 | size_t count, loff_t * data) |
307 | { | 711 | { |
@@ -310,7 +714,6 @@ static ssize_t acpi_processor_write_throttling(struct file * file, | |||
310 | struct acpi_processor *pr = m->private; | 714 | struct acpi_processor *pr = m->private; |
311 | char state_string[12] = { '\0' }; | 715 | char state_string[12] = { '\0' }; |
312 | 716 | ||
313 | |||
314 | if (!pr || (count > sizeof(state_string) - 1)) | 717 | if (!pr || (count > sizeof(state_string) - 1)) |
315 | return -EINVAL; | 718 | return -EINVAL; |
316 | 719 | ||
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index c1bae106833c..974d00ccfe84 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c | |||
@@ -127,7 +127,7 @@ static int acpi_sbs_resume(struct acpi_device *device); | |||
127 | static struct acpi_driver acpi_sbs_driver = { | 127 | static struct acpi_driver acpi_sbs_driver = { |
128 | .name = "sbs", | 128 | .name = "sbs", |
129 | .class = ACPI_SBS_CLASS, | 129 | .class = ACPI_SBS_CLASS, |
130 | .ids = ACPI_SBS_HID, | 130 | .ids = "ACPI0001,ACPI0005", |
131 | .ops = { | 131 | .ops = { |
132 | .add = acpi_sbs_add, | 132 | .add = acpi_sbs_add, |
133 | .remove = acpi_sbs_remove, | 133 | .remove = acpi_sbs_remove, |
@@ -176,10 +176,8 @@ struct acpi_battery { | |||
176 | }; | 176 | }; |
177 | 177 | ||
178 | struct acpi_sbs { | 178 | struct acpi_sbs { |
179 | acpi_handle handle; | ||
180 | int base; | 179 | int base; |
181 | struct acpi_device *device; | 180 | struct acpi_device *device; |
182 | struct acpi_ec_smbus *smbus; | ||
183 | struct mutex mutex; | 181 | struct mutex mutex; |
184 | int sbsm_present; | 182 | int sbsm_present; |
185 | int sbsm_batteries_supported; | 183 | int sbsm_batteries_supported; |
@@ -511,7 +509,7 @@ static int acpi_sbsm_get_info(struct acpi_sbs *sbs) | |||
511 | "acpi_sbs_read_word() failed")); | 509 | "acpi_sbs_read_word() failed")); |
512 | goto end; | 510 | goto end; |
513 | } | 511 | } |
514 | 512 | sbs->sbsm_present = 1; | |
515 | sbs->sbsm_batteries_supported = battery_system_info & 0x000f; | 513 | sbs->sbsm_batteries_supported = battery_system_info & 0x000f; |
516 | 514 | ||
517 | end: | 515 | end: |
@@ -1630,13 +1628,12 @@ static int acpi_sbs_add(struct acpi_device *device) | |||
1630 | { | 1628 | { |
1631 | struct acpi_sbs *sbs = NULL; | 1629 | struct acpi_sbs *sbs = NULL; |
1632 | int result = 0, remove_result = 0; | 1630 | int result = 0, remove_result = 0; |
1633 | unsigned long sbs_obj; | ||
1634 | int id; | 1631 | int id; |
1635 | acpi_status status = AE_OK; | 1632 | acpi_status status = AE_OK; |
1636 | unsigned long val; | 1633 | unsigned long val; |
1637 | 1634 | ||
1638 | status = | 1635 | status = |
1639 | acpi_evaluate_integer(device->parent->handle, "_EC", NULL, &val); | 1636 | acpi_evaluate_integer(device->handle, "_EC", NULL, &val); |
1640 | if (ACPI_FAILURE(status)) { | 1637 | if (ACPI_FAILURE(status)) { |
1641 | ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Error obtaining _EC")); | 1638 | ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Error obtaining _EC")); |
1642 | return -EIO; | 1639 | return -EIO; |
@@ -1653,7 +1650,7 @@ static int acpi_sbs_add(struct acpi_device *device) | |||
1653 | 1650 | ||
1654 | sbs_mutex_lock(sbs); | 1651 | sbs_mutex_lock(sbs); |
1655 | 1652 | ||
1656 | sbs->base = (val & 0xff00ull) >> 8; | 1653 | sbs->base = 0xff & (val >> 8); |
1657 | sbs->device = device; | 1654 | sbs->device = device; |
1658 | 1655 | ||
1659 | strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME); | 1656 | strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME); |
@@ -1665,24 +1662,10 @@ static int acpi_sbs_add(struct acpi_device *device) | |||
1665 | ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_ac_add() failed")); | 1662 | ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_ac_add() failed")); |
1666 | goto end; | 1663 | goto end; |
1667 | } | 1664 | } |
1668 | status = acpi_evaluate_integer(device->handle, "_SBS", NULL, &sbs_obj); | ||
1669 | if (status) { | ||
1670 | ACPI_EXCEPTION((AE_INFO, status, | ||
1671 | "acpi_evaluate_integer() failed")); | ||
1672 | result = -EIO; | ||
1673 | goto end; | ||
1674 | } | ||
1675 | if (sbs_obj > 0) { | ||
1676 | result = acpi_sbsm_get_info(sbs); | ||
1677 | if (result) { | ||
1678 | ACPI_EXCEPTION((AE_INFO, AE_ERROR, | ||
1679 | "acpi_sbsm_get_info() failed")); | ||
1680 | goto end; | ||
1681 | } | ||
1682 | sbs->sbsm_present = 1; | ||
1683 | } | ||
1684 | 1665 | ||
1685 | if (sbs->sbsm_present == 0) { | 1666 | acpi_sbsm_get_info(sbs); |
1667 | |||
1668 | if (!sbs->sbsm_present) { | ||
1686 | result = acpi_battery_add(sbs, 0); | 1669 | result = acpi_battery_add(sbs, 0); |
1687 | if (result) { | 1670 | if (result) { |
1688 | ACPI_EXCEPTION((AE_INFO, AE_ERROR, | 1671 | ACPI_EXCEPTION((AE_INFO, AE_ERROR, |
@@ -1702,8 +1685,6 @@ static int acpi_sbs_add(struct acpi_device *device) | |||
1702 | } | 1685 | } |
1703 | } | 1686 | } |
1704 | 1687 | ||
1705 | sbs->handle = device->handle; | ||
1706 | |||
1707 | init_timer(&sbs->update_timer); | 1688 | init_timer(&sbs->update_timer); |
1708 | result = acpi_check_update_proc(sbs); | 1689 | result = acpi_check_update_proc(sbs); |
1709 | if (result) | 1690 | if (result) |
diff --git a/drivers/acpi/sleep/Makefile b/drivers/acpi/sleep/Makefile index d6c017709c85..01a993a1d086 100644 --- a/drivers/acpi/sleep/Makefile +++ b/drivers/acpi/sleep/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | obj-y := poweroff.o wakeup.o | 1 | obj-y := poweroff.o wakeup.o |
2 | obj-$(CONFIG_ACPI_SLEEP) += main.o | 2 | obj-y += main.o |
3 | obj-$(CONFIG_ACPI_SLEEP_PROC_FS) += proc.o | 3 | obj-$(CONFIG_X86) += proc.o |
4 | 4 | ||
5 | EXTRA_CFLAGS += $(ACPI_CFLAGS) | 5 | EXTRA_CFLAGS += $(ACPI_CFLAGS) |
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c index 29bdb013f46c..ab21357c5c7b 100644 --- a/drivers/acpi/sleep/main.c +++ b/drivers/acpi/sleep/main.c | |||
@@ -154,10 +154,12 @@ static int acpi_pm_finish(suspend_state_t pm_state) | |||
154 | 154 | ||
155 | acpi_target_sleep_state = ACPI_STATE_S0; | 155 | acpi_target_sleep_state = ACPI_STATE_S0; |
156 | 156 | ||
157 | #ifdef CONFIG_X86 | ||
157 | if (init_8259A_after_S1) { | 158 | if (init_8259A_after_S1) { |
158 | printk("Broken toshiba laptop -> kicking interrupts\n"); | 159 | printk("Broken toshiba laptop -> kicking interrupts\n"); |
159 | init_8259A(0); | 160 | init_8259A(0); |
160 | } | 161 | } |
162 | #endif | ||
161 | return 0; | 163 | return 0; |
162 | } | 164 | } |
163 | 165 | ||
@@ -229,11 +231,6 @@ static void acpi_hibernation_finish(void) | |||
229 | 231 | ||
230 | /* reset firmware waking vector */ | 232 | /* reset firmware waking vector */ |
231 | acpi_set_firmware_waking_vector((acpi_physical_address) 0); | 233 | acpi_set_firmware_waking_vector((acpi_physical_address) 0); |
232 | |||
233 | if (init_8259A_after_S1) { | ||
234 | printk("Broken toshiba laptop -> kicking interrupts\n"); | ||
235 | init_8259A(0); | ||
236 | } | ||
237 | } | 234 | } |
238 | 235 | ||
239 | static int acpi_hibernation_pre_restore(void) | 236 | static int acpi_hibernation_pre_restore(void) |
diff --git a/drivers/acpi/sleep/poweroff.c b/drivers/acpi/sleep/poweroff.c index 39e40d56b034..b3f68ef0669e 100644 --- a/drivers/acpi/sleep/poweroff.c +++ b/drivers/acpi/sleep/poweroff.c | |||
@@ -18,7 +18,6 @@ | |||
18 | 18 | ||
19 | int acpi_sleep_prepare(u32 acpi_state) | 19 | int acpi_sleep_prepare(u32 acpi_state) |
20 | { | 20 | { |
21 | #ifdef CONFIG_ACPI_SLEEP | ||
22 | /* do we have a wakeup address for S2 and S3? */ | 21 | /* do we have a wakeup address for S2 and S3? */ |
23 | if (acpi_state == ACPI_STATE_S3) { | 22 | if (acpi_state == ACPI_STATE_S3) { |
24 | if (!acpi_wakeup_address) { | 23 | if (!acpi_wakeup_address) { |
@@ -31,7 +30,6 @@ int acpi_sleep_prepare(u32 acpi_state) | |||
31 | } | 30 | } |
32 | ACPI_FLUSH_CPU_CACHE(); | 31 | ACPI_FLUSH_CPU_CACHE(); |
33 | acpi_enable_wakeup_device_prep(acpi_state); | 32 | acpi_enable_wakeup_device_prep(acpi_state); |
34 | #endif | ||
35 | acpi_gpe_sleep_prepare(acpi_state); | 33 | acpi_gpe_sleep_prepare(acpi_state); |
36 | acpi_enter_sleep_state_prep(acpi_state); | 34 | acpi_enter_sleep_state_prep(acpi_state); |
37 | return 0; | 35 | return 0; |
diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c index 61f1822cc350..ed58e1168aed 100644 --- a/drivers/acpi/sleep/proc.c +++ b/drivers/acpi/sleep/proc.c | |||
@@ -14,8 +14,16 @@ | |||
14 | #include "sleep.h" | 14 | #include "sleep.h" |
15 | 15 | ||
16 | #define _COMPONENT ACPI_SYSTEM_COMPONENT | 16 | #define _COMPONENT ACPI_SYSTEM_COMPONENT |
17 | |||
18 | /* | ||
19 | * this file provides support for: | ||
20 | * /proc/acpi/sleep | ||
21 | * /proc/acpi/alarm | ||
22 | * /proc/acpi/wakeup | ||
23 | */ | ||
24 | |||
17 | ACPI_MODULE_NAME("sleep") | 25 | ACPI_MODULE_NAME("sleep") |
18 | #ifdef CONFIG_ACPI_SLEEP_PROC_SLEEP | 26 | #ifdef CONFIG_ACPI_PROCFS |
19 | static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset) | 27 | static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset) |
20 | { | 28 | { |
21 | int i; | 29 | int i; |
@@ -68,7 +76,7 @@ acpi_system_write_sleep(struct file *file, | |||
68 | Done: | 76 | Done: |
69 | return error ? error : count; | 77 | return error ? error : count; |
70 | } | 78 | } |
71 | #endif /* CONFIG_ACPI_SLEEP_PROC_SLEEP */ | 79 | #endif /* CONFIG_ACPI_PROCFS */ |
72 | 80 | ||
73 | #if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) | 81 | #if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) |
74 | /* use /sys/class/rtc/rtcX/wakealarm instead; it's not ACPI-specific */ | 82 | /* use /sys/class/rtc/rtcX/wakealarm instead; it's not ACPI-specific */ |
@@ -463,7 +471,7 @@ static const struct file_operations acpi_system_wakeup_device_fops = { | |||
463 | .release = single_release, | 471 | .release = single_release, |
464 | }; | 472 | }; |
465 | 473 | ||
466 | #ifdef CONFIG_ACPI_SLEEP_PROC_SLEEP | 474 | #ifdef CONFIG_ACPI_PROCFS |
467 | static const struct file_operations acpi_system_sleep_fops = { | 475 | static const struct file_operations acpi_system_sleep_fops = { |
468 | .open = acpi_system_sleep_open_fs, | 476 | .open = acpi_system_sleep_open_fs, |
469 | .read = seq_read, | 477 | .read = seq_read, |
@@ -471,7 +479,7 @@ static const struct file_operations acpi_system_sleep_fops = { | |||
471 | .llseek = seq_lseek, | 479 | .llseek = seq_lseek, |
472 | .release = single_release, | 480 | .release = single_release, |
473 | }; | 481 | }; |
474 | #endif /* CONFIG_ACPI_SLEEP_PROC_SLEEP */ | 482 | #endif /* CONFIG_ACPI_PROCFS */ |
475 | 483 | ||
476 | #ifdef HAVE_ACPI_LEGACY_ALARM | 484 | #ifdef HAVE_ACPI_LEGACY_ALARM |
477 | static const struct file_operations acpi_system_alarm_fops = { | 485 | static const struct file_operations acpi_system_alarm_fops = { |
@@ -498,14 +506,14 @@ static int __init acpi_sleep_proc_init(void) | |||
498 | if (acpi_disabled) | 506 | if (acpi_disabled) |
499 | return 0; | 507 | return 0; |
500 | 508 | ||
501 | #ifdef CONFIG_ACPI_SLEEP_PROC_SLEEP | 509 | #ifdef CONFIG_ACPI_PROCFS |
502 | /* 'sleep' [R/W] */ | 510 | /* 'sleep' [R/W] */ |
503 | entry = | 511 | entry = |
504 | create_proc_entry("sleep", S_IFREG | S_IRUGO | S_IWUSR, | 512 | create_proc_entry("sleep", S_IFREG | S_IRUGO | S_IWUSR, |
505 | acpi_root_dir); | 513 | acpi_root_dir); |
506 | if (entry) | 514 | if (entry) |
507 | entry->proc_fops = &acpi_system_sleep_fops; | 515 | entry->proc_fops = &acpi_system_sleep_fops; |
508 | #endif | 516 | #endif /* CONFIG_ACPI_PROCFS */ |
509 | 517 | ||
510 | #ifdef HAVE_ACPI_LEGACY_ALARM | 518 | #ifdef HAVE_ACPI_LEGACY_ALARM |
511 | /* 'alarm' [R/W] */ | 519 | /* 'alarm' [R/W] */ |
diff --git a/drivers/acpi/sleep/wakeup.c b/drivers/acpi/sleep/wakeup.c index fab8f2694f03..97c27ddb144d 100644 --- a/drivers/acpi/sleep/wakeup.c +++ b/drivers/acpi/sleep/wakeup.c | |||
@@ -17,7 +17,6 @@ ACPI_MODULE_NAME("wakeup_devices") | |||
17 | extern struct list_head acpi_wakeup_device_list; | 17 | extern struct list_head acpi_wakeup_device_list; |
18 | extern spinlock_t acpi_device_lock; | 18 | extern spinlock_t acpi_device_lock; |
19 | 19 | ||
20 | #ifdef CONFIG_ACPI_SLEEP | ||
21 | /** | 20 | /** |
22 | * acpi_enable_wakeup_device_prep - prepare wakeup devices | 21 | * acpi_enable_wakeup_device_prep - prepare wakeup devices |
23 | * @sleep_state: ACPI state | 22 | * @sleep_state: ACPI state |
@@ -180,7 +179,6 @@ static int __init acpi_wakeup_device_init(void) | |||
180 | } | 179 | } |
181 | 180 | ||
182 | late_initcall(acpi_wakeup_device_init); | 181 | late_initcall(acpi_wakeup_device_init); |
183 | #endif | ||
184 | 182 | ||
185 | /* | 183 | /* |
186 | * Disable all wakeup GPEs before entering requested sleep state. | 184 | * Disable all wakeup GPEs before entering requested sleep state. |
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index 83a8d3097904..edee2806e37b 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c | |||
@@ -39,15 +39,12 @@ ACPI_MODULE_NAME("system"); | |||
39 | 39 | ||
40 | #define ACPI_SYSTEM_CLASS "system" | 40 | #define ACPI_SYSTEM_CLASS "system" |
41 | #define ACPI_SYSTEM_DEVICE_NAME "System" | 41 | #define ACPI_SYSTEM_DEVICE_NAME "System" |
42 | #define ACPI_SYSTEM_FILE_INFO "info" | ||
43 | #define ACPI_SYSTEM_FILE_EVENT "event" | ||
44 | #define ACPI_SYSTEM_FILE_DSDT "dsdt" | ||
45 | #define ACPI_SYSTEM_FILE_FADT "fadt" | ||
46 | 42 | ||
47 | /* | 43 | /* |
48 | * Make ACPICA version work as module param | 44 | * Make ACPICA version work as module param |
49 | */ | 45 | */ |
50 | static int param_get_acpica_version(char *buffer, struct kernel_param *kp) { | 46 | static int param_get_acpica_version(char *buffer, struct kernel_param *kp) |
47 | { | ||
51 | int result; | 48 | int result; |
52 | 49 | ||
53 | result = sprintf(buffer, "%x", ACPI_CA_VERSION); | 50 | result = sprintf(buffer, "%x", ACPI_CA_VERSION); |
@@ -58,9 +55,126 @@ static int param_get_acpica_version(char *buffer, struct kernel_param *kp) { | |||
58 | module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444); | 55 | module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444); |
59 | 56 | ||
60 | /* -------------------------------------------------------------------------- | 57 | /* -------------------------------------------------------------------------- |
58 | FS Interface (/sys) | ||
59 | -------------------------------------------------------------------------- */ | ||
60 | static LIST_HEAD(acpi_table_attr_list); | ||
61 | static struct kobject tables_kobj; | ||
62 | |||
63 | struct acpi_table_attr { | ||
64 | struct bin_attribute attr; | ||
65 | char name[8]; | ||
66 | int instance; | ||
67 | struct list_head node; | ||
68 | }; | ||
69 | |||
70 | static ssize_t acpi_table_show(struct kobject *kobj, | ||
71 | struct bin_attribute *bin_attr, char *buf, | ||
72 | loff_t offset, size_t count) | ||
73 | { | ||
74 | struct acpi_table_attr *table_attr = | ||
75 | container_of(bin_attr, struct acpi_table_attr, attr); | ||
76 | struct acpi_table_header *table_header = NULL; | ||
77 | acpi_status status; | ||
78 | ssize_t ret_count = count; | ||
79 | |||
80 | status = | ||
81 | acpi_get_table(table_attr->name, table_attr->instance, | ||
82 | &table_header); | ||
83 | if (ACPI_FAILURE(status)) | ||
84 | return -ENODEV; | ||
85 | |||
86 | if (offset >= table_header->length) { | ||
87 | ret_count = 0; | ||
88 | goto end; | ||
89 | } | ||
90 | |||
91 | if (offset + ret_count > table_header->length) | ||
92 | ret_count = table_header->length - offset; | ||
93 | |||
94 | memcpy(buf, ((char *)table_header) + offset, ret_count); | ||
95 | |||
96 | end: | ||
97 | return ret_count; | ||
98 | } | ||
99 | |||
100 | static void acpi_table_attr_init(struct acpi_table_attr *table_attr, | ||
101 | struct acpi_table_header *table_header) | ||
102 | { | ||
103 | struct acpi_table_header *header = NULL; | ||
104 | struct acpi_table_attr *attr = NULL; | ||
105 | |||
106 | memcpy(table_attr->name, table_header->signature, ACPI_NAME_SIZE); | ||
107 | |||
108 | list_for_each_entry(attr, &acpi_table_attr_list, node) { | ||
109 | if (!memcmp(table_header->signature, attr->name, | ||
110 | ACPI_NAME_SIZE)) | ||
111 | if (table_attr->instance < attr->instance) | ||
112 | table_attr->instance = attr->instance; | ||
113 | } | ||
114 | table_attr->instance++; | ||
115 | |||
116 | if (table_attr->instance > 1 || (table_attr->instance == 1 && | ||
117 | !acpi_get_table(table_header-> | ||
118 | signature, 2, | ||
119 | &header))) | ||
120 | sprintf(table_attr->name + 4, "%d", table_attr->instance); | ||
121 | |||
122 | table_attr->attr.size = 0; | ||
123 | table_attr->attr.read = acpi_table_show; | ||
124 | table_attr->attr.attr.name = table_attr->name; | ||
125 | table_attr->attr.attr.mode = 0444; | ||
126 | table_attr->attr.attr.owner = THIS_MODULE; | ||
127 | |||
128 | return; | ||
129 | } | ||
130 | |||
131 | static int acpi_system_sysfs_init(void) | ||
132 | { | ||
133 | struct acpi_table_attr *table_attr; | ||
134 | struct acpi_table_header *table_header = NULL; | ||
135 | int table_index = 0; | ||
136 | int result; | ||
137 | |||
138 | tables_kobj.parent = &acpi_subsys.kobj; | ||
139 | kobject_set_name(&tables_kobj, "tables"); | ||
140 | result = kobject_register(&tables_kobj); | ||
141 | if (result) | ||
142 | return result; | ||
143 | |||
144 | do { | ||
145 | result = acpi_get_table_by_index(table_index, &table_header); | ||
146 | if (!result) { | ||
147 | table_index++; | ||
148 | table_attr = NULL; | ||
149 | table_attr = | ||
150 | kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL); | ||
151 | if (!table_attr) | ||
152 | return -ENOMEM; | ||
153 | |||
154 | acpi_table_attr_init(table_attr, table_header); | ||
155 | result = | ||
156 | sysfs_create_bin_file(&tables_kobj, | ||
157 | &table_attr->attr); | ||
158 | if (result) { | ||
159 | kfree(table_attr); | ||
160 | return result; | ||
161 | } else | ||
162 | list_add_tail(&table_attr->node, | ||
163 | &acpi_table_attr_list); | ||
164 | } | ||
165 | } while (!result); | ||
166 | |||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | /* -------------------------------------------------------------------------- | ||
61 | FS Interface (/proc) | 171 | FS Interface (/proc) |
62 | -------------------------------------------------------------------------- */ | 172 | -------------------------------------------------------------------------- */ |
63 | #ifdef CONFIG_ACPI_PROCFS | 173 | #ifdef CONFIG_ACPI_PROCFS |
174 | #define ACPI_SYSTEM_FILE_INFO "info" | ||
175 | #define ACPI_SYSTEM_FILE_EVENT "event" | ||
176 | #define ACPI_SYSTEM_FILE_DSDT "dsdt" | ||
177 | #define ACPI_SYSTEM_FILE_FADT "fadt" | ||
64 | 178 | ||
65 | static int acpi_system_read_info(struct seq_file *seq, void *offset) | 179 | static int acpi_system_read_info(struct seq_file *seq, void *offset) |
66 | { | 180 | { |
@@ -80,7 +194,6 @@ static const struct file_operations acpi_system_info_ops = { | |||
80 | .llseek = seq_lseek, | 194 | .llseek = seq_lseek, |
81 | .release = single_release, | 195 | .release = single_release, |
82 | }; | 196 | }; |
83 | #endif | ||
84 | 197 | ||
85 | static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t, | 198 | static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t, |
86 | loff_t *); | 199 | loff_t *); |
@@ -97,13 +210,11 @@ acpi_system_read_dsdt(struct file *file, | |||
97 | struct acpi_table_header *dsdt = NULL; | 210 | struct acpi_table_header *dsdt = NULL; |
98 | ssize_t res; | 211 | ssize_t res; |
99 | 212 | ||
100 | |||
101 | status = acpi_get_table(ACPI_SIG_DSDT, 1, &dsdt); | 213 | status = acpi_get_table(ACPI_SIG_DSDT, 1, &dsdt); |
102 | if (ACPI_FAILURE(status)) | 214 | if (ACPI_FAILURE(status)) |
103 | return -ENODEV; | 215 | return -ENODEV; |
104 | 216 | ||
105 | res = simple_read_from_buffer(buffer, count, ppos, | 217 | res = simple_read_from_buffer(buffer, count, ppos, dsdt, dsdt->length); |
106 | dsdt, dsdt->length); | ||
107 | 218 | ||
108 | return res; | 219 | return res; |
109 | } | 220 | } |
@@ -123,28 +234,21 @@ acpi_system_read_fadt(struct file *file, | |||
123 | struct acpi_table_header *fadt = NULL; | 234 | struct acpi_table_header *fadt = NULL; |
124 | ssize_t res; | 235 | ssize_t res; |
125 | 236 | ||
126 | |||
127 | status = acpi_get_table(ACPI_SIG_FADT, 1, &fadt); | 237 | status = acpi_get_table(ACPI_SIG_FADT, 1, &fadt); |
128 | if (ACPI_FAILURE(status)) | 238 | if (ACPI_FAILURE(status)) |
129 | return -ENODEV; | 239 | return -ENODEV; |
130 | 240 | ||
131 | res = simple_read_from_buffer(buffer, count, ppos, | 241 | res = simple_read_from_buffer(buffer, count, ppos, fadt, fadt->length); |
132 | fadt, fadt->length); | ||
133 | 242 | ||
134 | return res; | 243 | return res; |
135 | } | 244 | } |
136 | 245 | ||
137 | static int __init acpi_system_init(void) | 246 | static int acpi_system_procfs_init(void) |
138 | { | 247 | { |
139 | struct proc_dir_entry *entry; | 248 | struct proc_dir_entry *entry; |
140 | int error = 0; | 249 | int error = 0; |
141 | char *name; | 250 | char *name; |
142 | 251 | ||
143 | |||
144 | if (acpi_disabled) | ||
145 | return 0; | ||
146 | |||
147 | #ifdef CONFIG_ACPI_PROCFS | ||
148 | /* 'info' [R] */ | 252 | /* 'info' [R] */ |
149 | name = ACPI_SYSTEM_FILE_INFO; | 253 | name = ACPI_SYSTEM_FILE_INFO; |
150 | entry = create_proc_entry(name, S_IRUGO, acpi_root_dir); | 254 | entry = create_proc_entry(name, S_IRUGO, acpi_root_dir); |
@@ -153,7 +257,6 @@ static int __init acpi_system_init(void) | |||
153 | else { | 257 | else { |
154 | entry->proc_fops = &acpi_system_info_ops; | 258 | entry->proc_fops = &acpi_system_info_ops; |
155 | } | 259 | } |
156 | #endif | ||
157 | 260 | ||
158 | /* 'dsdt' [R] */ | 261 | /* 'dsdt' [R] */ |
159 | name = ACPI_SYSTEM_FILE_DSDT; | 262 | name = ACPI_SYSTEM_FILE_DSDT; |
@@ -177,12 +280,32 @@ static int __init acpi_system_init(void) | |||
177 | Error: | 280 | Error: |
178 | remove_proc_entry(ACPI_SYSTEM_FILE_FADT, acpi_root_dir); | 281 | remove_proc_entry(ACPI_SYSTEM_FILE_FADT, acpi_root_dir); |
179 | remove_proc_entry(ACPI_SYSTEM_FILE_DSDT, acpi_root_dir); | 282 | remove_proc_entry(ACPI_SYSTEM_FILE_DSDT, acpi_root_dir); |
180 | #ifdef CONFIG_ACPI_PROCFS | ||
181 | remove_proc_entry(ACPI_SYSTEM_FILE_INFO, acpi_root_dir); | 283 | remove_proc_entry(ACPI_SYSTEM_FILE_INFO, acpi_root_dir); |
182 | #endif | ||
183 | 284 | ||
184 | error = -EFAULT; | 285 | error = -EFAULT; |
185 | goto Done; | 286 | goto Done; |
186 | } | 287 | } |
288 | #else | ||
289 | static int acpi_system_procfs_init(void) | ||
290 | { | ||
291 | return 0; | ||
292 | } | ||
293 | #endif | ||
294 | |||
295 | static int __init acpi_system_init(void) | ||
296 | { | ||
297 | int result = 0; | ||
298 | |||
299 | if (acpi_disabled) | ||
300 | return 0; | ||
301 | |||
302 | result = acpi_system_procfs_init(); | ||
303 | if (result) | ||
304 | return result; | ||
305 | |||
306 | result = acpi_system_sysfs_init(); | ||
307 | |||
308 | return result; | ||
309 | } | ||
187 | 310 | ||
188 | subsys_initcall(acpi_system_init); | 311 | subsys_initcall(acpi_system_init); |
diff --git a/drivers/acpi/tables/tbfadt.c b/drivers/acpi/tables/tbfadt.c index 1285e91474fb..002bb33003af 100644 --- a/drivers/acpi/tables/tbfadt.c +++ b/drivers/acpi/tables/tbfadt.c | |||
@@ -211,14 +211,17 @@ void acpi_tb_parse_fadt(acpi_native_uint table_index, u8 flags) | |||
211 | * DESCRIPTION: Get a local copy of the FADT and convert it to a common format. | 211 | * DESCRIPTION: Get a local copy of the FADT and convert it to a common format. |
212 | * Performs validation on some important FADT fields. | 212 | * Performs validation on some important FADT fields. |
213 | * | 213 | * |
214 | * NOTE: We create a local copy of the FADT regardless of the version. | ||
215 | * | ||
214 | ******************************************************************************/ | 216 | ******************************************************************************/ |
215 | 217 | ||
216 | void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) | 218 | void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) |
217 | { | 219 | { |
218 | 220 | ||
219 | /* | 221 | /* |
220 | * Check if the FADT is larger than what we know about (ACPI 2.0 version). | 222 | * Check if the FADT is larger than the largest table that we expect |
221 | * Truncate the table, but make some noise. | 223 | * (the ACPI 2.0/3.0 version). If so, truncate the table, and issue |
224 | * a warning. | ||
222 | */ | 225 | */ |
223 | if (length > sizeof(struct acpi_table_fadt)) { | 226 | if (length > sizeof(struct acpi_table_fadt)) { |
224 | ACPI_WARNING((AE_INFO, | 227 | ACPI_WARNING((AE_INFO, |
@@ -227,10 +230,12 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) | |||
227 | sizeof(struct acpi_table_fadt))); | 230 | sizeof(struct acpi_table_fadt))); |
228 | } | 231 | } |
229 | 232 | ||
230 | /* Copy the entire FADT locally. Zero first for tb_convert_fadt */ | 233 | /* Clear the entire local FADT */ |
231 | 234 | ||
232 | ACPI_MEMSET(&acpi_gbl_FADT, 0, sizeof(struct acpi_table_fadt)); | 235 | ACPI_MEMSET(&acpi_gbl_FADT, 0, sizeof(struct acpi_table_fadt)); |
233 | 236 | ||
237 | /* Copy the original FADT, up to sizeof (struct acpi_table_fadt) */ | ||
238 | |||
234 | ACPI_MEMCPY(&acpi_gbl_FADT, table, | 239 | ACPI_MEMCPY(&acpi_gbl_FADT, table, |
235 | ACPI_MIN(length, sizeof(struct acpi_table_fadt))); | 240 | ACPI_MIN(length, sizeof(struct acpi_table_fadt))); |
236 | 241 | ||
@@ -251,7 +256,7 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) | |||
251 | * RETURN: None | 256 | * RETURN: None |
252 | * | 257 | * |
253 | * DESCRIPTION: Converts all versions of the FADT to a common internal format. | 258 | * DESCRIPTION: Converts all versions of the FADT to a common internal format. |
254 | * -> Expand all 32-bit addresses to 64-bit. | 259 | * Expand all 32-bit addresses to 64-bit. |
255 | * | 260 | * |
256 | * NOTE: acpi_gbl_FADT must be of size (struct acpi_table_fadt), | 261 | * NOTE: acpi_gbl_FADT must be of size (struct acpi_table_fadt), |
257 | * and must contain a copy of the actual FADT. | 262 | * and must contain a copy of the actual FADT. |
@@ -292,8 +297,23 @@ static void acpi_tb_convert_fadt(void) | |||
292 | } | 297 | } |
293 | 298 | ||
294 | /* | 299 | /* |
295 | * Expand the 32-bit V1.0 addresses to the 64-bit "X" generic address | 300 | * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which |
296 | * structures as necessary. | 301 | * should be zero are indeed zero. This will workaround BIOSs that |
302 | * inadvertently place values in these fields. | ||
303 | * | ||
304 | * The ACPI 1.0 reserved fields that will be zeroed are the bytes located at | ||
305 | * offset 45, 55, 95, and the word located at offset 109, 110. | ||
306 | */ | ||
307 | if (acpi_gbl_FADT.header.revision < 3) { | ||
308 | acpi_gbl_FADT.preferred_profile = 0; | ||
309 | acpi_gbl_FADT.pstate_control = 0; | ||
310 | acpi_gbl_FADT.cst_control = 0; | ||
311 | acpi_gbl_FADT.boot_flags = 0; | ||
312 | } | ||
313 | |||
314 | /* | ||
315 | * Expand the ACPI 1.0 32-bit V1.0 addresses to the ACPI 2.0 64-bit "X" | ||
316 | * generic address structures as necessary. | ||
297 | */ | 317 | */ |
298 | for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { | 318 | for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { |
299 | target = | 319 | target = |
@@ -349,18 +369,6 @@ static void acpi_tb_convert_fadt(void) | |||
349 | acpi_gbl_FADT.xpm1a_event_block.space_id; | 369 | acpi_gbl_FADT.xpm1a_event_block.space_id; |
350 | 370 | ||
351 | } | 371 | } |
352 | |||
353 | /* | ||
354 | * For ACPI 1.0 FADTs, ensure that reserved fields (which should be zero) | ||
355 | * are indeed zero. This will workaround BIOSs that inadvertently placed | ||
356 | * values in these fields. | ||
357 | */ | ||
358 | if (acpi_gbl_FADT.header.revision < 3) { | ||
359 | acpi_gbl_FADT.preferred_profile = 0; | ||
360 | acpi_gbl_FADT.pstate_control = 0; | ||
361 | acpi_gbl_FADT.cst_control = 0; | ||
362 | acpi_gbl_FADT.boot_flags = 0; | ||
363 | } | ||
364 | } | 372 | } |
365 | 373 | ||
366 | /****************************************************************************** | 374 | /****************************************************************************** |
diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c index 8ec6f8e48138..f112af433e36 100644 --- a/drivers/acpi/utilities/uteval.c +++ b/drivers/acpi/utilities/uteval.c | |||
@@ -62,16 +62,13 @@ acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc, | |||
62 | static char *acpi_interfaces_supported[] = { | 62 | static char *acpi_interfaces_supported[] = { |
63 | /* Operating System Vendor Strings */ | 63 | /* Operating System Vendor Strings */ |
64 | 64 | ||
65 | "Windows 2000", | 65 | "Windows 2000", /* Windows 2000 */ |
66 | "Windows 2001", | 66 | "Windows 2001", /* Windows XP */ |
67 | "Windows 2001 SP0", | 67 | "Windows 2001 SP1", /* Windows XP SP1 */ |
68 | "Windows 2001 SP1", | 68 | "Windows 2001 SP2", /* Windows XP SP2 */ |
69 | "Windows 2001 SP2", | 69 | "Windows 2001.1", /* Windows Server 2003 */ |
70 | "Windows 2001 SP3", | 70 | "Windows 2001.1 SP1", /* Windows Server 2003 SP1 - Added 03/2006 */ |
71 | "Windows 2001 SP4", | 71 | "Windows 2006", /* Windows Vista - Added 03/2006 */ |
72 | "Windows 2001.1", | ||
73 | "Windows 2001.1 SP1", /* Added 03/2006 */ | ||
74 | "Windows 2006", /* Added 03/2006 */ | ||
75 | 72 | ||
76 | /* Feature Group Strings */ | 73 | /* Feature Group Strings */ |
77 | 74 | ||
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 00d25b347255..04ea697f72bf 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/seq_file.h> | 33 | #include <linux/seq_file.h> |
34 | 34 | ||
35 | #include <linux/backlight.h> | 35 | #include <linux/backlight.h> |
36 | #include <linux/video_output.h> | ||
36 | #include <asm/uaccess.h> | 37 | #include <asm/uaccess.h> |
37 | 38 | ||
38 | #include <acpi/acpi_bus.h> | 39 | #include <acpi/acpi_bus.h> |
@@ -169,6 +170,7 @@ struct acpi_video_device { | |||
169 | struct acpi_device *dev; | 170 | struct acpi_device *dev; |
170 | struct acpi_video_device_brightness *brightness; | 171 | struct acpi_video_device_brightness *brightness; |
171 | struct backlight_device *backlight; | 172 | struct backlight_device *backlight; |
173 | struct output_device *output_dev; | ||
172 | }; | 174 | }; |
173 | 175 | ||
174 | /* bus */ | 176 | /* bus */ |
@@ -272,13 +274,17 @@ static int acpi_video_get_next_level(struct acpi_video_device *device, | |||
272 | u32 level_current, u32 event); | 274 | u32 level_current, u32 event); |
273 | static void acpi_video_switch_brightness(struct acpi_video_device *device, | 275 | static void acpi_video_switch_brightness(struct acpi_video_device *device, |
274 | int event); | 276 | int event); |
277 | static int acpi_video_device_get_state(struct acpi_video_device *device, | ||
278 | unsigned long *state); | ||
279 | static int acpi_video_output_get(struct output_device *od); | ||
280 | static int acpi_video_device_set_state(struct acpi_video_device *device, int state); | ||
275 | 281 | ||
276 | /*backlight device sysfs support*/ | 282 | /*backlight device sysfs support*/ |
277 | static int acpi_video_get_brightness(struct backlight_device *bd) | 283 | static int acpi_video_get_brightness(struct backlight_device *bd) |
278 | { | 284 | { |
279 | unsigned long cur_level; | 285 | unsigned long cur_level; |
280 | struct acpi_video_device *vd = | 286 | struct acpi_video_device *vd = |
281 | (struct acpi_video_device *)class_get_devdata(&bd->class_dev); | 287 | (struct acpi_video_device *)bl_get_data(bd); |
282 | acpi_video_device_lcd_get_level_current(vd, &cur_level); | 288 | acpi_video_device_lcd_get_level_current(vd, &cur_level); |
283 | return (int) cur_level; | 289 | return (int) cur_level; |
284 | } | 290 | } |
@@ -287,7 +293,7 @@ static int acpi_video_set_brightness(struct backlight_device *bd) | |||
287 | { | 293 | { |
288 | int request_level = bd->props.brightness; | 294 | int request_level = bd->props.brightness; |
289 | struct acpi_video_device *vd = | 295 | struct acpi_video_device *vd = |
290 | (struct acpi_video_device *)class_get_devdata(&bd->class_dev); | 296 | (struct acpi_video_device *)bl_get_data(bd); |
291 | acpi_video_device_lcd_set_level(vd, request_level); | 297 | acpi_video_device_lcd_set_level(vd, request_level); |
292 | return 0; | 298 | return 0; |
293 | } | 299 | } |
@@ -297,6 +303,28 @@ static struct backlight_ops acpi_backlight_ops = { | |||
297 | .update_status = acpi_video_set_brightness, | 303 | .update_status = acpi_video_set_brightness, |
298 | }; | 304 | }; |
299 | 305 | ||
306 | /*video output device sysfs support*/ | ||
307 | static int acpi_video_output_get(struct output_device *od) | ||
308 | { | ||
309 | unsigned long state; | ||
310 | struct acpi_video_device *vd = | ||
311 | (struct acpi_video_device *)class_get_devdata(&od->class_dev); | ||
312 | acpi_video_device_get_state(vd, &state); | ||
313 | return (int)state; | ||
314 | } | ||
315 | |||
316 | static int acpi_video_output_set(struct output_device *od) | ||
317 | { | ||
318 | unsigned long state = od->request_state; | ||
319 | struct acpi_video_device *vd= | ||
320 | (struct acpi_video_device *)class_get_devdata(&od->class_dev); | ||
321 | return acpi_video_device_set_state(vd, state); | ||
322 | } | ||
323 | |||
324 | static struct output_properties acpi_output_properties = { | ||
325 | .set_state = acpi_video_output_set, | ||
326 | .get_status = acpi_video_output_get, | ||
327 | }; | ||
300 | /* -------------------------------------------------------------------------- | 328 | /* -------------------------------------------------------------------------- |
301 | Video Management | 329 | Video Management |
302 | -------------------------------------------------------------------------- */ | 330 | -------------------------------------------------------------------------- */ |
@@ -531,7 +559,6 @@ acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag) | |||
531 | 559 | ||
532 | static void acpi_video_device_find_cap(struct acpi_video_device *device) | 560 | static void acpi_video_device_find_cap(struct acpi_video_device *device) |
533 | { | 561 | { |
534 | acpi_integer status; | ||
535 | acpi_handle h_dummy1; | 562 | acpi_handle h_dummy1; |
536 | int i; | 563 | int i; |
537 | u32 max_level = 0; | 564 | u32 max_level = 0; |
@@ -565,50 +592,55 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
565 | device->cap._DSS = 1; | 592 | device->cap._DSS = 1; |
566 | } | 593 | } |
567 | 594 | ||
568 | status = acpi_video_device_lcd_query_levels(device, &obj); | 595 | if (ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) { |
569 | 596 | ||
570 | if (obj && obj->type == ACPI_TYPE_PACKAGE && obj->package.count >= 2) { | 597 | if (obj->package.count >= 2) { |
571 | int count = 0; | 598 | int count = 0; |
572 | union acpi_object *o; | 599 | union acpi_object *o; |
573 | 600 | ||
574 | br = kzalloc(sizeof(*br), GFP_KERNEL); | 601 | br = kzalloc(sizeof(*br), GFP_KERNEL); |
575 | if (!br) { | 602 | if (!br) { |
576 | printk(KERN_ERR "can't allocate memory\n"); | 603 | printk(KERN_ERR "can't allocate memory\n"); |
577 | } else { | ||
578 | br->levels = kmalloc(obj->package.count * | ||
579 | sizeof *(br->levels), GFP_KERNEL); | ||
580 | if (!br->levels) | ||
581 | goto out; | ||
582 | |||
583 | for (i = 0; i < obj->package.count; i++) { | ||
584 | o = (union acpi_object *)&obj->package. | ||
585 | elements[i]; | ||
586 | if (o->type != ACPI_TYPE_INTEGER) { | ||
587 | printk(KERN_ERR PREFIX "Invalid data\n"); | ||
588 | continue; | ||
589 | } | ||
590 | br->levels[count] = (u32) o->integer.value; | ||
591 | if (br->levels[count] > max_level) | ||
592 | max_level = br->levels[count]; | ||
593 | count++; | ||
594 | } | ||
595 | out: | ||
596 | if (count < 2) { | ||
597 | kfree(br->levels); | ||
598 | kfree(br); | ||
599 | } else { | 604 | } else { |
600 | br->count = count; | 605 | br->levels = kmalloc(obj->package.count * |
601 | device->brightness = br; | 606 | sizeof *(br->levels), GFP_KERNEL); |
602 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 607 | if (!br->levels) |
603 | "found %d brightness levels\n", | 608 | goto out; |
604 | count)); | 609 | |
610 | for (i = 0; i < obj->package.count; i++) { | ||
611 | o = (union acpi_object *)&obj->package. | ||
612 | elements[i]; | ||
613 | if (o->type != ACPI_TYPE_INTEGER) { | ||
614 | printk(KERN_ERR PREFIX "Invalid data\n"); | ||
615 | continue; | ||
616 | } | ||
617 | br->levels[count] = (u32) o->integer.value; | ||
618 | |||
619 | if (br->levels[count] > max_level) | ||
620 | max_level = br->levels[count]; | ||
621 | count++; | ||
622 | } | ||
623 | out: | ||
624 | if (count < 2) { | ||
625 | kfree(br->levels); | ||
626 | kfree(br); | ||
627 | } else { | ||
628 | br->count = count; | ||
629 | device->brightness = br; | ||
630 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
631 | "found %d brightness levels\n", | ||
632 | count)); | ||
633 | } | ||
605 | } | 634 | } |
606 | } | 635 | } |
636 | |||
637 | } else { | ||
638 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available LCD brightness level\n")); | ||
607 | } | 639 | } |
608 | 640 | ||
609 | kfree(obj); | 641 | kfree(obj); |
610 | 642 | ||
611 | if (device->cap._BCL && device->cap._BCM && device->cap._BQC){ | 643 | if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){ |
612 | unsigned long tmp; | 644 | unsigned long tmp; |
613 | static int count = 0; | 645 | static int count = 0; |
614 | char *name; | 646 | char *name; |
@@ -626,6 +658,17 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
626 | 658 | ||
627 | kfree(name); | 659 | kfree(name); |
628 | } | 660 | } |
661 | if (device->cap._DCS && device->cap._DSS){ | ||
662 | static int count = 0; | ||
663 | char *name; | ||
664 | name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); | ||
665 | if (!name) | ||
666 | return; | ||
667 | sprintf(name, "acpi_video%d", count++); | ||
668 | device->output_dev = video_output_register(name, | ||
669 | NULL, device, &acpi_output_properties); | ||
670 | kfree(name); | ||
671 | } | ||
629 | return; | 672 | return; |
630 | } | 673 | } |
631 | 674 | ||
@@ -1669,6 +1712,7 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) | |||
1669 | ACPI_DEVICE_NOTIFY, | 1712 | ACPI_DEVICE_NOTIFY, |
1670 | acpi_video_device_notify); | 1713 | acpi_video_device_notify); |
1671 | backlight_device_unregister(device->backlight); | 1714 | backlight_device_unregister(device->backlight); |
1715 | video_output_unregister(device->output_dev); | ||
1672 | return 0; | 1716 | return 0; |
1673 | } | 1717 | } |
1674 | 1718 | ||
diff --git a/drivers/char/hvc_iseries.c b/drivers/char/hvc_iseries.c index b37f1d5a5be6..a08f8f981c11 100644 --- a/drivers/char/hvc_iseries.c +++ b/drivers/char/hvc_iseries.c | |||
@@ -472,7 +472,7 @@ static void hvc_handle_event(struct HvLpEvent *event) | |||
472 | } | 472 | } |
473 | } | 473 | } |
474 | 474 | ||
475 | static int send_open(HvLpIndex remoteLp, void *sem) | 475 | static int __init send_open(HvLpIndex remoteLp, void *sem) |
476 | { | 476 | { |
477 | return HvCallEvent_signalLpEventFast(remoteLp, | 477 | return HvCallEvent_signalLpEventFast(remoteLp, |
478 | HvLpEvent_Type_VirtualIo, | 478 | HvLpEvent_Type_VirtualIo, |
@@ -484,7 +484,7 @@ static int send_open(HvLpIndex remoteLp, void *sem) | |||
484 | 0, 0, 0, 0); | 484 | 0, 0, 0, 0); |
485 | } | 485 | } |
486 | 486 | ||
487 | static int hvc_vio_init(void) | 487 | static int __init hvc_vio_init(void) |
488 | { | 488 | { |
489 | atomic_t wait_flag; | 489 | atomic_t wait_flag; |
490 | int rc; | 490 | int rc; |
@@ -552,14 +552,14 @@ static int hvc_vio_init(void) | |||
552 | } | 552 | } |
553 | module_init(hvc_vio_init); /* after drivers/char/hvc_console.c */ | 553 | module_init(hvc_vio_init); /* after drivers/char/hvc_console.c */ |
554 | 554 | ||
555 | static void hvc_vio_exit(void) | 555 | static void __exit hvc_vio_exit(void) |
556 | { | 556 | { |
557 | vio_unregister_driver(&hvc_vio_driver); | 557 | vio_unregister_driver(&hvc_vio_driver); |
558 | } | 558 | } |
559 | module_exit(hvc_vio_exit); | 559 | module_exit(hvc_vio_exit); |
560 | 560 | ||
561 | /* the device tree order defines our numbering */ | 561 | /* the device tree order defines our numbering */ |
562 | static int hvc_find_vtys(void) | 562 | static int __init hvc_find_vtys(void) |
563 | { | 563 | { |
564 | struct device_node *vty; | 564 | struct device_node *vty; |
565 | int num_found = 0; | 565 | int num_found = 0; |
diff --git a/drivers/char/hvc_rtas.c b/drivers/char/hvc_rtas.c index 4b97eaf18602..bb09413d5a21 100644 --- a/drivers/char/hvc_rtas.c +++ b/drivers/char/hvc_rtas.c | |||
@@ -115,7 +115,7 @@ static void __exit hvc_rtas_exit(void) | |||
115 | module_exit(hvc_rtas_exit); | 115 | module_exit(hvc_rtas_exit); |
116 | 116 | ||
117 | /* This will happen prior to module init. There is no tty at this time? */ | 117 | /* This will happen prior to module init. There is no tty at this time? */ |
118 | static int hvc_rtas_console_init(void) | 118 | static int __init hvc_rtas_console_init(void) |
119 | { | 119 | { |
120 | rtascons_put_char_token = rtas_token("put-term-char"); | 120 | rtascons_put_char_token = rtas_token("put-term-char"); |
121 | if (rtascons_put_char_token == RTAS_UNKNOWN_SERVICE) | 121 | if (rtascons_put_char_token == RTAS_UNKNOWN_SERVICE) |
diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c index 17f96e04266f..69d8866de783 100644 --- a/drivers/char/hvcs.c +++ b/drivers/char/hvcs.c | |||
@@ -210,9 +210,9 @@ static struct ktermios hvcs_tty_termios = { | |||
210 | static int hvcs_parm_num_devs = -1; | 210 | static int hvcs_parm_num_devs = -1; |
211 | module_param(hvcs_parm_num_devs, int, 0); | 211 | module_param(hvcs_parm_num_devs, int, 0); |
212 | 212 | ||
213 | char hvcs_driver_name[] = "hvcs"; | 213 | static const char hvcs_driver_name[] = "hvcs"; |
214 | char hvcs_device_node[] = "hvcs"; | 214 | static const char hvcs_device_node[] = "hvcs"; |
215 | char hvcs_driver_string[] | 215 | static const char hvcs_driver_string[] |
216 | = "IBM hvcs (Hypervisor Virtual Console Server) Driver"; | 216 | = "IBM hvcs (Hypervisor Virtual Console Server) Driver"; |
217 | 217 | ||
218 | /* Status of partner info rescan triggered via sysfs. */ | 218 | /* Status of partner info rescan triggered via sysfs. */ |
@@ -1092,7 +1092,7 @@ static int hvcs_enable_device(struct hvcs_struct *hvcsd, uint32_t unit_address, | |||
1092 | * NOTICE: Do NOT hold either the hvcs_struct.lock or hvcs_structs_lock when | 1092 | * NOTICE: Do NOT hold either the hvcs_struct.lock or hvcs_structs_lock when |
1093 | * calling this function or you will get deadlock. | 1093 | * calling this function or you will get deadlock. |
1094 | */ | 1094 | */ |
1095 | struct hvcs_struct *hvcs_get_by_index(int index) | 1095 | static struct hvcs_struct *hvcs_get_by_index(int index) |
1096 | { | 1096 | { |
1097 | struct hvcs_struct *hvcsd = NULL; | 1097 | struct hvcs_struct *hvcsd = NULL; |
1098 | unsigned long flags; | 1098 | unsigned long flags; |
diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig index ad5cc5f6862f..16fb23125e96 100644 --- a/drivers/char/watchdog/Kconfig +++ b/drivers/char/watchdog/Kconfig | |||
@@ -187,6 +187,22 @@ config PNX4008_WATCHDOG | |||
187 | 187 | ||
188 | Say N if you are unsure. | 188 | Say N if you are unsure. |
189 | 189 | ||
190 | config IOP_WATCHDOG | ||
191 | tristate "IOP Watchdog" | ||
192 | depends on WATCHDOG && PLAT_IOP | ||
193 | select WATCHDOG_NOWAYOUT if (ARCH_IOP32X || ARCH_IOP33X) | ||
194 | help | ||
195 | Say Y here if to include support for the watchdog timer | ||
196 | in the Intel IOP3XX & IOP13XX I/O Processors. This driver can | ||
197 | be built as a module by choosing M. The module will | ||
198 | be called iop_wdt. | ||
199 | |||
200 | Note: The IOP13XX watchdog does an Internal Bus Reset which will | ||
201 | affect both cores and the peripherals of the IOP. The ATU-X | ||
202 | and/or ATUe configuration registers will remain intact, but if | ||
203 | operating as an Root Complex and/or Central Resource, the PCI-X | ||
204 | and/or PCIe busses will also be reset. THIS IS A VERY BIG HAMMER. | ||
205 | |||
190 | # AVR32 Architecture | 206 | # AVR32 Architecture |
191 | 207 | ||
192 | config AT32AP700X_WDT | 208 | config AT32AP700X_WDT |
diff --git a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile index 3907ec04a4e5..bdb9d5e3bb41 100644 --- a/drivers/char/watchdog/Makefile +++ b/drivers/char/watchdog/Makefile | |||
@@ -35,6 +35,7 @@ obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o | |||
35 | obj-$(CONFIG_MPCORE_WATCHDOG) += mpcore_wdt.o | 35 | obj-$(CONFIG_MPCORE_WATCHDOG) += mpcore_wdt.o |
36 | obj-$(CONFIG_EP93XX_WATCHDOG) += ep93xx_wdt.o | 36 | obj-$(CONFIG_EP93XX_WATCHDOG) += ep93xx_wdt.o |
37 | obj-$(CONFIG_PNX4008_WATCHDOG) += pnx4008_wdt.o | 37 | obj-$(CONFIG_PNX4008_WATCHDOG) += pnx4008_wdt.o |
38 | obj-$(CONFIG_IOP_WATCHDOG) += iop_wdt.o | ||
38 | 39 | ||
39 | # AVR32 Architecture | 40 | # AVR32 Architecture |
40 | obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o | 41 | obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o |
diff --git a/drivers/char/watchdog/iop_wdt.c b/drivers/char/watchdog/iop_wdt.c new file mode 100644 index 000000000000..bbbd91af754d --- /dev/null +++ b/drivers/char/watchdog/iop_wdt.c | |||
@@ -0,0 +1,262 @@ | |||
1 | /* | ||
2 | * drivers/char/watchdog/iop_wdt.c | ||
3 | * | ||
4 | * WDT driver for Intel I/O Processors | ||
5 | * Copyright (C) 2005, Intel Corporation. | ||
6 | * | ||
7 | * Based on ixp4xx driver, Copyright 2004 (c) MontaVista, Software, Inc. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms and conditions of the GNU General Public License, | ||
11 | * version 2, as published by the Free Software Foundation. | ||
12 | * | ||
13 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
16 | * more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along with | ||
19 | * this program; if not, write to the Free Software Foundation, Inc., 59 Temple | ||
20 | * Place - Suite 330, Boston, MA 02111-1307 USA. | ||
21 | * | ||
22 | * Curt E Bruns <curt.e.bruns@intel.com> | ||
23 | * Peter Milne <peter.milne@d-tacq.com> | ||
24 | * Dan Williams <dan.j.williams@intel.com> | ||
25 | */ | ||
26 | |||
27 | #include <linux/module.h> | ||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/fs.h> | ||
30 | #include <linux/init.h> | ||
31 | #include <linux/device.h> | ||
32 | #include <linux/miscdevice.h> | ||
33 | #include <linux/watchdog.h> | ||
34 | #include <linux/uaccess.h> | ||
35 | #include <asm/hardware.h> | ||
36 | |||
37 | static int nowayout = WATCHDOG_NOWAYOUT; | ||
38 | static unsigned long wdt_status; | ||
39 | static unsigned long boot_status; | ||
40 | |||
41 | #define WDT_IN_USE 0 | ||
42 | #define WDT_OK_TO_CLOSE 1 | ||
43 | #define WDT_ENABLED 2 | ||
44 | |||
45 | static unsigned long iop_watchdog_timeout(void) | ||
46 | { | ||
47 | return (0xffffffffUL / get_iop_tick_rate()); | ||
48 | } | ||
49 | |||
50 | /** | ||
51 | * wdt_supports_disable - determine if we are accessing a iop13xx watchdog | ||
52 | * or iop3xx by whether it has a disable command | ||
53 | */ | ||
54 | static int wdt_supports_disable(void) | ||
55 | { | ||
56 | int can_disable; | ||
57 | |||
58 | if (IOP_WDTCR_EN_ARM != IOP_WDTCR_DIS_ARM) | ||
59 | can_disable = 1; | ||
60 | else | ||
61 | can_disable = 0; | ||
62 | |||
63 | return can_disable; | ||
64 | } | ||
65 | |||
66 | static void wdt_enable(void) | ||
67 | { | ||
68 | /* Arm and enable the Timer to starting counting down from 0xFFFF.FFFF | ||
69 | * Takes approx. 10.7s to timeout | ||
70 | */ | ||
71 | write_wdtcr(IOP_WDTCR_EN_ARM); | ||
72 | write_wdtcr(IOP_WDTCR_EN); | ||
73 | } | ||
74 | |||
75 | /* returns 0 if the timer was successfully disabled */ | ||
76 | static int wdt_disable(void) | ||
77 | { | ||
78 | /* Stop Counting */ | ||
79 | if (wdt_supports_disable()) { | ||
80 | write_wdtcr(IOP_WDTCR_DIS_ARM); | ||
81 | write_wdtcr(IOP_WDTCR_DIS); | ||
82 | clear_bit(WDT_ENABLED, &wdt_status); | ||
83 | printk(KERN_INFO "WATCHDOG: Disabled\n"); | ||
84 | return 0; | ||
85 | } else | ||
86 | return 1; | ||
87 | } | ||
88 | |||
89 | static int iop_wdt_open(struct inode *inode, struct file *file) | ||
90 | { | ||
91 | if (test_and_set_bit(WDT_IN_USE, &wdt_status)) | ||
92 | return -EBUSY; | ||
93 | |||
94 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); | ||
95 | |||
96 | wdt_enable(); | ||
97 | |||
98 | set_bit(WDT_ENABLED, &wdt_status); | ||
99 | |||
100 | return nonseekable_open(inode, file); | ||
101 | } | ||
102 | |||
103 | static ssize_t | ||
104 | iop_wdt_write(struct file *file, const char *data, size_t len, | ||
105 | loff_t *ppos) | ||
106 | { | ||
107 | if (len) { | ||
108 | if (!nowayout) { | ||
109 | size_t i; | ||
110 | |||
111 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); | ||
112 | |||
113 | for (i = 0; i != len; i++) { | ||
114 | char c; | ||
115 | |||
116 | if (get_user(c, data + i)) | ||
117 | return -EFAULT; | ||
118 | if (c == 'V') | ||
119 | set_bit(WDT_OK_TO_CLOSE, &wdt_status); | ||
120 | } | ||
121 | } | ||
122 | wdt_enable(); | ||
123 | } | ||
124 | |||
125 | return len; | ||
126 | } | ||
127 | |||
128 | static struct watchdog_info ident = { | ||
129 | .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, | ||
130 | .identity = "iop watchdog", | ||
131 | }; | ||
132 | |||
133 | static int | ||
134 | iop_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | ||
135 | unsigned long arg) | ||
136 | { | ||
137 | int options; | ||
138 | int ret = -ENOTTY; | ||
139 | |||
140 | switch (cmd) { | ||
141 | case WDIOC_GETSUPPORT: | ||
142 | if (copy_to_user | ||
143 | ((struct watchdog_info *)arg, &ident, sizeof ident)) | ||
144 | ret = -EFAULT; | ||
145 | else | ||
146 | ret = 0; | ||
147 | break; | ||
148 | |||
149 | case WDIOC_GETSTATUS: | ||
150 | ret = put_user(0, (int *)arg); | ||
151 | break; | ||
152 | |||
153 | case WDIOC_GETBOOTSTATUS: | ||
154 | ret = put_user(boot_status, (int *)arg); | ||
155 | break; | ||
156 | |||
157 | case WDIOC_GETTIMEOUT: | ||
158 | ret = put_user(iop_watchdog_timeout(), (int *)arg); | ||
159 | break; | ||
160 | |||
161 | case WDIOC_KEEPALIVE: | ||
162 | wdt_enable(); | ||
163 | ret = 0; | ||
164 | break; | ||
165 | |||
166 | case WDIOC_SETOPTIONS: | ||
167 | if (get_user(options, (int *)arg)) | ||
168 | return -EFAULT; | ||
169 | |||
170 | if (options & WDIOS_DISABLECARD) { | ||
171 | if (!nowayout) { | ||
172 | if (wdt_disable() == 0) { | ||
173 | set_bit(WDT_OK_TO_CLOSE, &wdt_status); | ||
174 | ret = 0; | ||
175 | } else | ||
176 | ret = -ENXIO; | ||
177 | } else | ||
178 | ret = 0; | ||
179 | } | ||
180 | |||
181 | if (options & WDIOS_ENABLECARD) { | ||
182 | wdt_enable(); | ||
183 | ret = 0; | ||
184 | } | ||
185 | break; | ||
186 | } | ||
187 | |||
188 | return ret; | ||
189 | } | ||
190 | |||
191 | static int iop_wdt_release(struct inode *inode, struct file *file) | ||
192 | { | ||
193 | int state = 1; | ||
194 | if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) | ||
195 | if (test_bit(WDT_ENABLED, &wdt_status)) | ||
196 | state = wdt_disable(); | ||
197 | |||
198 | /* if the timer is not disbaled reload and notify that we are still | ||
199 | * going down | ||
200 | */ | ||
201 | if (state != 0) { | ||
202 | wdt_enable(); | ||
203 | printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - " | ||
204 | "reset in %lu seconds\n", iop_watchdog_timeout()); | ||
205 | } | ||
206 | |||
207 | clear_bit(WDT_IN_USE, &wdt_status); | ||
208 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); | ||
209 | |||
210 | return 0; | ||
211 | } | ||
212 | |||
213 | static const struct file_operations iop_wdt_fops = { | ||
214 | .owner = THIS_MODULE, | ||
215 | .llseek = no_llseek, | ||
216 | .write = iop_wdt_write, | ||
217 | .ioctl = iop_wdt_ioctl, | ||
218 | .open = iop_wdt_open, | ||
219 | .release = iop_wdt_release, | ||
220 | }; | ||
221 | |||
222 | static struct miscdevice iop_wdt_miscdev = { | ||
223 | .minor = WATCHDOG_MINOR, | ||
224 | .name = "watchdog", | ||
225 | .fops = &iop_wdt_fops, | ||
226 | }; | ||
227 | |||
228 | static int __init iop_wdt_init(void) | ||
229 | { | ||
230 | int ret; | ||
231 | |||
232 | ret = misc_register(&iop_wdt_miscdev); | ||
233 | if (ret == 0) | ||
234 | printk("iop watchdog timer: timeout %lu sec\n", | ||
235 | iop_watchdog_timeout()); | ||
236 | |||
237 | /* check if the reset was caused by the watchdog timer */ | ||
238 | boot_status = (read_rcsr() & IOP_RCSR_WDT) ? WDIOF_CARDRESET : 0; | ||
239 | |||
240 | /* Configure Watchdog Timeout to cause an Internal Bus (IB) Reset | ||
241 | * NOTE: An IB Reset will Reset both cores in the IOP342 | ||
242 | */ | ||
243 | write_wdtsr(IOP13XX_WDTCR_IB_RESET); | ||
244 | |||
245 | return ret; | ||
246 | } | ||
247 | |||
248 | static void __exit iop_wdt_exit(void) | ||
249 | { | ||
250 | misc_deregister(&iop_wdt_miscdev); | ||
251 | } | ||
252 | |||
253 | module_init(iop_wdt_init); | ||
254 | module_exit(iop_wdt_exit); | ||
255 | |||
256 | module_param(nowayout, int, 0); | ||
257 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"); | ||
258 | |||
259 | MODULE_AUTHOR("Curt E Bruns <curt.e.bruns@intel.com>"); | ||
260 | MODULE_DESCRIPTION("iop watchdog timer driver"); | ||
261 | MODULE_LICENSE("GPL"); | ||
262 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | ||
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index fc984474162c..3e4a369d0057 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c | |||
@@ -1160,7 +1160,7 @@ static struct device_attribute *sbp2_scsi_sysfs_attrs[] = { | |||
1160 | static struct scsi_host_template scsi_driver_template = { | 1160 | static struct scsi_host_template scsi_driver_template = { |
1161 | .module = THIS_MODULE, | 1161 | .module = THIS_MODULE, |
1162 | .name = "SBP-2 IEEE-1394", | 1162 | .name = "SBP-2 IEEE-1394", |
1163 | .proc_name = (char *)sbp2_driver_name, | 1163 | .proc_name = sbp2_driver_name, |
1164 | .queuecommand = sbp2_scsi_queuecommand, | 1164 | .queuecommand = sbp2_scsi_queuecommand, |
1165 | .slave_alloc = sbp2_scsi_slave_alloc, | 1165 | .slave_alloc = sbp2_scsi_slave_alloc, |
1166 | .slave_configure = sbp2_scsi_slave_configure, | 1166 | .slave_configure = sbp2_scsi_slave_configure, |
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h index 043e4fb23fb0..3725aa8664d9 100644 --- a/drivers/infiniband/hw/ehca/ehca_classes.h +++ b/drivers/infiniband/hw/ehca/ehca_classes.h | |||
@@ -43,7 +43,6 @@ | |||
43 | #ifndef __EHCA_CLASSES_H__ | 43 | #ifndef __EHCA_CLASSES_H__ |
44 | #define __EHCA_CLASSES_H__ | 44 | #define __EHCA_CLASSES_H__ |
45 | 45 | ||
46 | |||
47 | struct ehca_module; | 46 | struct ehca_module; |
48 | struct ehca_qp; | 47 | struct ehca_qp; |
49 | struct ehca_cq; | 48 | struct ehca_cq; |
@@ -100,6 +99,11 @@ struct ehca_sport { | |||
100 | struct ehca_sma_attr saved_attr; | 99 | struct ehca_sma_attr saved_attr; |
101 | }; | 100 | }; |
102 | 101 | ||
102 | #define HCA_CAP_MR_PGSIZE_4K 1 | ||
103 | #define HCA_CAP_MR_PGSIZE_64K 2 | ||
104 | #define HCA_CAP_MR_PGSIZE_1M 4 | ||
105 | #define HCA_CAP_MR_PGSIZE_16M 8 | ||
106 | |||
103 | struct ehca_shca { | 107 | struct ehca_shca { |
104 | struct ib_device ib_device; | 108 | struct ib_device ib_device; |
105 | struct ibmebus_dev *ibmebus_dev; | 109 | struct ibmebus_dev *ibmebus_dev; |
@@ -115,6 +119,8 @@ struct ehca_shca { | |||
115 | struct h_galpas galpas; | 119 | struct h_galpas galpas; |
116 | struct mutex modify_mutex; | 120 | struct mutex modify_mutex; |
117 | u64 hca_cap; | 121 | u64 hca_cap; |
122 | /* MR pgsize: bit 0-3 means 4K, 64K, 1M, 16M respectively */ | ||
123 | u32 hca_cap_mr_pgsize; | ||
118 | int max_mtu; | 124 | int max_mtu; |
119 | }; | 125 | }; |
120 | 126 | ||
@@ -122,6 +128,10 @@ struct ehca_pd { | |||
122 | struct ib_pd ib_pd; | 128 | struct ib_pd ib_pd; |
123 | struct ipz_pd fw_pd; | 129 | struct ipz_pd fw_pd; |
124 | u32 ownpid; | 130 | u32 ownpid; |
131 | /* small queue mgmt */ | ||
132 | struct mutex lock; | ||
133 | struct list_head free[2]; | ||
134 | struct list_head full[2]; | ||
125 | }; | 135 | }; |
126 | 136 | ||
127 | enum ehca_ext_qp_type { | 137 | enum ehca_ext_qp_type { |
@@ -206,6 +216,7 @@ struct ehca_mr { | |||
206 | enum ehca_mr_flag flags; | 216 | enum ehca_mr_flag flags; |
207 | u32 num_kpages; /* number of kernel pages */ | 217 | u32 num_kpages; /* number of kernel pages */ |
208 | u32 num_hwpages; /* number of hw pages to form MR */ | 218 | u32 num_hwpages; /* number of hw pages to form MR */ |
219 | u64 hwpage_size; /* hw page size used for this MR */ | ||
209 | int acl; /* ACL (stored here for usage in reregister) */ | 220 | int acl; /* ACL (stored here for usage in reregister) */ |
210 | u64 *start; /* virtual start address (stored here for */ | 221 | u64 *start; /* virtual start address (stored here for */ |
211 | /* usage in reregister) */ | 222 | /* usage in reregister) */ |
@@ -240,6 +251,7 @@ struct ehca_mr_pginfo { | |||
240 | enum ehca_mr_pgi_type type; | 251 | enum ehca_mr_pgi_type type; |
241 | u64 num_kpages; | 252 | u64 num_kpages; |
242 | u64 kpage_cnt; | 253 | u64 kpage_cnt; |
254 | u64 hwpage_size; /* hw page size used for this MR */ | ||
243 | u64 num_hwpages; /* number of hw pages */ | 255 | u64 num_hwpages; /* number of hw pages */ |
244 | u64 hwpage_cnt; /* counter for hw pages */ | 256 | u64 hwpage_cnt; /* counter for hw pages */ |
245 | u64 next_hwpage; /* next hw page in buffer/chunk/listelem */ | 257 | u64 next_hwpage; /* next hw page in buffer/chunk/listelem */ |
@@ -298,6 +310,8 @@ int ehca_init_av_cache(void); | |||
298 | void ehca_cleanup_av_cache(void); | 310 | void ehca_cleanup_av_cache(void); |
299 | int ehca_init_mrmw_cache(void); | 311 | int ehca_init_mrmw_cache(void); |
300 | void ehca_cleanup_mrmw_cache(void); | 312 | void ehca_cleanup_mrmw_cache(void); |
313 | int ehca_init_small_qp_cache(void); | ||
314 | void ehca_cleanup_small_qp_cache(void); | ||
301 | 315 | ||
302 | extern rwlock_t ehca_qp_idr_lock; | 316 | extern rwlock_t ehca_qp_idr_lock; |
303 | extern rwlock_t ehca_cq_idr_lock; | 317 | extern rwlock_t ehca_cq_idr_lock; |
@@ -315,7 +329,7 @@ struct ipzu_queue_resp { | |||
315 | u32 queue_length; /* queue length allocated in bytes */ | 329 | u32 queue_length; /* queue length allocated in bytes */ |
316 | u32 pagesize; | 330 | u32 pagesize; |
317 | u32 toggle_state; | 331 | u32 toggle_state; |
318 | u32 dummy; /* padding for 8 byte alignment */ | 332 | u32 offset; /* save offset within a page for small_qp */ |
319 | }; | 333 | }; |
320 | 334 | ||
321 | struct ehca_create_cq_resp { | 335 | struct ehca_create_cq_resp { |
@@ -357,15 +371,29 @@ enum ehca_ll_comp_flags { | |||
357 | LLQP_COMP_MASK = 0x60, | 371 | LLQP_COMP_MASK = 0x60, |
358 | }; | 372 | }; |
359 | 373 | ||
374 | struct ehca_alloc_queue_parms { | ||
375 | /* input parameters */ | ||
376 | int max_wr; | ||
377 | int max_sge; | ||
378 | int page_size; | ||
379 | int is_small; | ||
380 | |||
381 | /* output parameters */ | ||
382 | u16 act_nr_wqes; | ||
383 | u8 act_nr_sges; | ||
384 | u32 queue_size; /* bytes for small queues, pages otherwise */ | ||
385 | }; | ||
386 | |||
360 | struct ehca_alloc_qp_parms { | 387 | struct ehca_alloc_qp_parms { |
361 | /* input parameters */ | 388 | struct ehca_alloc_queue_parms squeue; |
389 | struct ehca_alloc_queue_parms rqueue; | ||
390 | |||
391 | /* input parameters */ | ||
362 | enum ehca_service_type servicetype; | 392 | enum ehca_service_type servicetype; |
393 | int qp_storage; | ||
363 | int sigtype; | 394 | int sigtype; |
364 | enum ehca_ext_qp_type ext_type; | 395 | enum ehca_ext_qp_type ext_type; |
365 | enum ehca_ll_comp_flags ll_comp_flags; | 396 | enum ehca_ll_comp_flags ll_comp_flags; |
366 | |||
367 | int max_send_wr, max_recv_wr; | ||
368 | int max_send_sge, max_recv_sge; | ||
369 | int ud_av_l_key_ctl; | 397 | int ud_av_l_key_ctl; |
370 | 398 | ||
371 | u32 token; | 399 | u32 token; |
@@ -375,18 +403,10 @@ struct ehca_alloc_qp_parms { | |||
375 | 403 | ||
376 | u32 srq_qpn, srq_token, srq_limit; | 404 | u32 srq_qpn, srq_token, srq_limit; |
377 | 405 | ||
378 | /* output parameters */ | 406 | /* output parameters */ |
379 | u32 real_qp_num; | 407 | u32 real_qp_num; |
380 | struct ipz_qp_handle qp_handle; | 408 | struct ipz_qp_handle qp_handle; |
381 | struct h_galpas galpas; | 409 | struct h_galpas galpas; |
382 | |||
383 | u16 act_nr_send_wqes; | ||
384 | u16 act_nr_recv_wqes; | ||
385 | u8 act_nr_recv_sges; | ||
386 | u8 act_nr_send_sges; | ||
387 | |||
388 | u32 nr_rq_pages; | ||
389 | u32 nr_sq_pages; | ||
390 | }; | 410 | }; |
391 | 411 | ||
392 | int ehca_cq_assign_qp(struct ehca_cq *cq, struct ehca_qp *qp); | 412 | int ehca_cq_assign_qp(struct ehca_cq *cq, struct ehca_qp *qp); |
diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c index 1e8ca3fca4aa..81aff36101ba 100644 --- a/drivers/infiniband/hw/ehca/ehca_cq.c +++ b/drivers/infiniband/hw/ehca/ehca_cq.c | |||
@@ -190,8 +190,8 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector, | |||
190 | goto create_cq_exit2; | 190 | goto create_cq_exit2; |
191 | } | 191 | } |
192 | 192 | ||
193 | ipz_rc = ipz_queue_ctor(&my_cq->ipz_queue, param.act_pages, | 193 | ipz_rc = ipz_queue_ctor(NULL, &my_cq->ipz_queue, param.act_pages, |
194 | EHCA_PAGESIZE, sizeof(struct ehca_cqe), 0); | 194 | EHCA_PAGESIZE, sizeof(struct ehca_cqe), 0, 0); |
195 | if (!ipz_rc) { | 195 | if (!ipz_rc) { |
196 | ehca_err(device, "ipz_queue_ctor() failed ipz_rc=%x device=%p", | 196 | ehca_err(device, "ipz_queue_ctor() failed ipz_rc=%x device=%p", |
197 | ipz_rc, device); | 197 | ipz_rc, device); |
@@ -285,7 +285,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector, | |||
285 | return cq; | 285 | return cq; |
286 | 286 | ||
287 | create_cq_exit4: | 287 | create_cq_exit4: |
288 | ipz_queue_dtor(&my_cq->ipz_queue); | 288 | ipz_queue_dtor(NULL, &my_cq->ipz_queue); |
289 | 289 | ||
290 | create_cq_exit3: | 290 | create_cq_exit3: |
291 | h_ret = hipz_h_destroy_cq(adapter_handle, my_cq, 1); | 291 | h_ret = hipz_h_destroy_cq(adapter_handle, my_cq, 1); |
@@ -359,7 +359,7 @@ int ehca_destroy_cq(struct ib_cq *cq) | |||
359 | "ehca_cq=%p cq_num=%x", h_ret, my_cq, cq_num); | 359 | "ehca_cq=%p cq_num=%x", h_ret, my_cq, cq_num); |
360 | return ehca2ib_return_code(h_ret); | 360 | return ehca2ib_return_code(h_ret); |
361 | } | 361 | } |
362 | ipz_queue_dtor(&my_cq->ipz_queue); | 362 | ipz_queue_dtor(NULL, &my_cq->ipz_queue); |
363 | kmem_cache_free(cq_cache, my_cq); | 363 | kmem_cache_free(cq_cache, my_cq); |
364 | 364 | ||
365 | return 0; | 365 | return 0; |
diff --git a/drivers/infiniband/hw/ehca/ehca_eq.c b/drivers/infiniband/hw/ehca/ehca_eq.c index 4825975f88cf..1d41faa7a337 100644 --- a/drivers/infiniband/hw/ehca/ehca_eq.c +++ b/drivers/infiniband/hw/ehca/ehca_eq.c | |||
@@ -86,8 +86,8 @@ int ehca_create_eq(struct ehca_shca *shca, | |||
86 | return -EINVAL; | 86 | return -EINVAL; |
87 | } | 87 | } |
88 | 88 | ||
89 | ret = ipz_queue_ctor(&eq->ipz_queue, nr_pages, | 89 | ret = ipz_queue_ctor(NULL, &eq->ipz_queue, nr_pages, |
90 | EHCA_PAGESIZE, sizeof(struct ehca_eqe), 0); | 90 | EHCA_PAGESIZE, sizeof(struct ehca_eqe), 0, 0); |
91 | if (!ret) { | 91 | if (!ret) { |
92 | ehca_err(ib_dev, "Can't allocate EQ pages eq=%p", eq); | 92 | ehca_err(ib_dev, "Can't allocate EQ pages eq=%p", eq); |
93 | goto create_eq_exit1; | 93 | goto create_eq_exit1; |
@@ -145,7 +145,7 @@ int ehca_create_eq(struct ehca_shca *shca, | |||
145 | return 0; | 145 | return 0; |
146 | 146 | ||
147 | create_eq_exit2: | 147 | create_eq_exit2: |
148 | ipz_queue_dtor(&eq->ipz_queue); | 148 | ipz_queue_dtor(NULL, &eq->ipz_queue); |
149 | 149 | ||
150 | create_eq_exit1: | 150 | create_eq_exit1: |
151 | hipz_h_destroy_eq(shca->ipz_hca_handle, eq); | 151 | hipz_h_destroy_eq(shca->ipz_hca_handle, eq); |
@@ -181,7 +181,7 @@ int ehca_destroy_eq(struct ehca_shca *shca, struct ehca_eq *eq) | |||
181 | ehca_err(&shca->ib_device, "Can't free EQ resources."); | 181 | ehca_err(&shca->ib_device, "Can't free EQ resources."); |
182 | return -EINVAL; | 182 | return -EINVAL; |
183 | } | 183 | } |
184 | ipz_queue_dtor(&eq->ipz_queue); | 184 | ipz_queue_dtor(NULL, &eq->ipz_queue); |
185 | 185 | ||
186 | return 0; | 186 | return 0; |
187 | } | 187 | } |
diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c index 4fb01fcb63ae..71c0799b3500 100644 --- a/drivers/infiniband/hw/ehca/ehca_irq.c +++ b/drivers/infiniband/hw/ehca/ehca_irq.c | |||
@@ -175,9 +175,8 @@ error_data1: | |||
175 | 175 | ||
176 | } | 176 | } |
177 | 177 | ||
178 | static void qp_event_callback(struct ehca_shca *shca, | 178 | static void qp_event_callback(struct ehca_shca *shca, u64 eqe, |
179 | u64 eqe, | 179 | enum ib_event_type event_type, int fatal) |
180 | enum ib_event_type event_type) | ||
181 | { | 180 | { |
182 | struct ib_event event; | 181 | struct ib_event event; |
183 | struct ehca_qp *qp; | 182 | struct ehca_qp *qp; |
@@ -191,16 +190,26 @@ static void qp_event_callback(struct ehca_shca *shca, | |||
191 | if (!qp) | 190 | if (!qp) |
192 | return; | 191 | return; |
193 | 192 | ||
194 | ehca_error_data(shca, qp, qp->ipz_qp_handle.handle); | 193 | if (fatal) |
194 | ehca_error_data(shca, qp, qp->ipz_qp_handle.handle); | ||
195 | 195 | ||
196 | if (!qp->ib_qp.event_handler) | 196 | event.device = &shca->ib_device; |
197 | return; | ||
198 | 197 | ||
199 | event.device = &shca->ib_device; | 198 | if (qp->ext_type == EQPT_SRQ) { |
200 | event.event = event_type; | 199 | if (!qp->ib_srq.event_handler) |
201 | event.element.qp = &qp->ib_qp; | 200 | return; |
202 | 201 | ||
203 | qp->ib_qp.event_handler(&event, qp->ib_qp.qp_context); | 202 | event.event = fatal ? IB_EVENT_SRQ_ERR : event_type; |
203 | event.element.srq = &qp->ib_srq; | ||
204 | qp->ib_srq.event_handler(&event, qp->ib_srq.srq_context); | ||
205 | } else { | ||
206 | if (!qp->ib_qp.event_handler) | ||
207 | return; | ||
208 | |||
209 | event.event = event_type; | ||
210 | event.element.qp = &qp->ib_qp; | ||
211 | qp->ib_qp.event_handler(&event, qp->ib_qp.qp_context); | ||
212 | } | ||
204 | 213 | ||
205 | return; | 214 | return; |
206 | } | 215 | } |
@@ -234,17 +243,17 @@ static void parse_identifier(struct ehca_shca *shca, u64 eqe) | |||
234 | 243 | ||
235 | switch (identifier) { | 244 | switch (identifier) { |
236 | case 0x02: /* path migrated */ | 245 | case 0x02: /* path migrated */ |
237 | qp_event_callback(shca, eqe, IB_EVENT_PATH_MIG); | 246 | qp_event_callback(shca, eqe, IB_EVENT_PATH_MIG, 0); |
238 | break; | 247 | break; |
239 | case 0x03: /* communication established */ | 248 | case 0x03: /* communication established */ |
240 | qp_event_callback(shca, eqe, IB_EVENT_COMM_EST); | 249 | qp_event_callback(shca, eqe, IB_EVENT_COMM_EST, 0); |
241 | break; | 250 | break; |
242 | case 0x04: /* send queue drained */ | 251 | case 0x04: /* send queue drained */ |
243 | qp_event_callback(shca, eqe, IB_EVENT_SQ_DRAINED); | 252 | qp_event_callback(shca, eqe, IB_EVENT_SQ_DRAINED, 0); |
244 | break; | 253 | break; |
245 | case 0x05: /* QP error */ | 254 | case 0x05: /* QP error */ |
246 | case 0x06: /* QP error */ | 255 | case 0x06: /* QP error */ |
247 | qp_event_callback(shca, eqe, IB_EVENT_QP_FATAL); | 256 | qp_event_callback(shca, eqe, IB_EVENT_QP_FATAL, 1); |
248 | break; | 257 | break; |
249 | case 0x07: /* CQ error */ | 258 | case 0x07: /* CQ error */ |
250 | case 0x08: /* CQ error */ | 259 | case 0x08: /* CQ error */ |
@@ -278,6 +287,11 @@ static void parse_identifier(struct ehca_shca *shca, u64 eqe) | |||
278 | ehca_err(&shca->ib_device, "Interface trace stopped."); | 287 | ehca_err(&shca->ib_device, "Interface trace stopped."); |
279 | break; | 288 | break; |
280 | case 0x14: /* first error capture info available */ | 289 | case 0x14: /* first error capture info available */ |
290 | ehca_info(&shca->ib_device, "First error capture available"); | ||
291 | break; | ||
292 | case 0x15: /* SRQ limit reached */ | ||
293 | qp_event_callback(shca, eqe, IB_EVENT_SRQ_LIMIT_REACHED, 0); | ||
294 | break; | ||
281 | default: | 295 | default: |
282 | ehca_err(&shca->ib_device, "Unknown identifier: %x on %s.", | 296 | ehca_err(&shca->ib_device, "Unknown identifier: %x on %s.", |
283 | identifier, shca->ib_device.name); | 297 | identifier, shca->ib_device.name); |
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c index 04c324330b7c..99036b65bb84 100644 --- a/drivers/infiniband/hw/ehca/ehca_main.c +++ b/drivers/infiniband/hw/ehca/ehca_main.c | |||
@@ -63,6 +63,7 @@ int ehca_port_act_time = 30; | |||
63 | int ehca_poll_all_eqs = 1; | 63 | int ehca_poll_all_eqs = 1; |
64 | int ehca_static_rate = -1; | 64 | int ehca_static_rate = -1; |
65 | int ehca_scaling_code = 0; | 65 | int ehca_scaling_code = 0; |
66 | int ehca_mr_largepage = 0; | ||
66 | 67 | ||
67 | module_param_named(open_aqp1, ehca_open_aqp1, int, 0); | 68 | module_param_named(open_aqp1, ehca_open_aqp1, int, 0); |
68 | module_param_named(debug_level, ehca_debug_level, int, 0); | 69 | module_param_named(debug_level, ehca_debug_level, int, 0); |
@@ -72,7 +73,8 @@ module_param_named(use_hp_mr, ehca_use_hp_mr, int, 0); | |||
72 | module_param_named(port_act_time, ehca_port_act_time, int, 0); | 73 | module_param_named(port_act_time, ehca_port_act_time, int, 0); |
73 | module_param_named(poll_all_eqs, ehca_poll_all_eqs, int, 0); | 74 | module_param_named(poll_all_eqs, ehca_poll_all_eqs, int, 0); |
74 | module_param_named(static_rate, ehca_static_rate, int, 0); | 75 | module_param_named(static_rate, ehca_static_rate, int, 0); |
75 | module_param_named(scaling_code, ehca_scaling_code, int, 0); | 76 | module_param_named(scaling_code, ehca_scaling_code, int, 0); |
77 | module_param_named(mr_largepage, ehca_mr_largepage, int, 0); | ||
76 | 78 | ||
77 | MODULE_PARM_DESC(open_aqp1, | 79 | MODULE_PARM_DESC(open_aqp1, |
78 | "AQP1 on startup (0: no (default), 1: yes)"); | 80 | "AQP1 on startup (0: no (default), 1: yes)"); |
@@ -95,6 +97,9 @@ MODULE_PARM_DESC(static_rate, | |||
95 | "set permanent static rate (default: disabled)"); | 97 | "set permanent static rate (default: disabled)"); |
96 | MODULE_PARM_DESC(scaling_code, | 98 | MODULE_PARM_DESC(scaling_code, |
97 | "set scaling code (0: disabled/default, 1: enabled)"); | 99 | "set scaling code (0: disabled/default, 1: enabled)"); |
100 | MODULE_PARM_DESC(mr_largepage, | ||
101 | "use large page for MR (0: use PAGE_SIZE (default), " | ||
102 | "1: use large page depending on MR size"); | ||
98 | 103 | ||
99 | DEFINE_RWLOCK(ehca_qp_idr_lock); | 104 | DEFINE_RWLOCK(ehca_qp_idr_lock); |
100 | DEFINE_RWLOCK(ehca_cq_idr_lock); | 105 | DEFINE_RWLOCK(ehca_cq_idr_lock); |
@@ -125,6 +130,23 @@ void ehca_free_fw_ctrlblock(void *ptr) | |||
125 | } | 130 | } |
126 | #endif | 131 | #endif |
127 | 132 | ||
133 | int ehca2ib_return_code(u64 ehca_rc) | ||
134 | { | ||
135 | switch (ehca_rc) { | ||
136 | case H_SUCCESS: | ||
137 | return 0; | ||
138 | case H_RESOURCE: /* Resource in use */ | ||
139 | case H_BUSY: | ||
140 | return -EBUSY; | ||
141 | case H_NOT_ENOUGH_RESOURCES: /* insufficient resources */ | ||
142 | case H_CONSTRAINED: /* resource constraint */ | ||
143 | case H_NO_MEM: | ||
144 | return -ENOMEM; | ||
145 | default: | ||
146 | return -EINVAL; | ||
147 | } | ||
148 | } | ||
149 | |||
128 | static int ehca_create_slab_caches(void) | 150 | static int ehca_create_slab_caches(void) |
129 | { | 151 | { |
130 | int ret; | 152 | int ret; |
@@ -159,6 +181,12 @@ static int ehca_create_slab_caches(void) | |||
159 | goto create_slab_caches5; | 181 | goto create_slab_caches5; |
160 | } | 182 | } |
161 | 183 | ||
184 | ret = ehca_init_small_qp_cache(); | ||
185 | if (ret) { | ||
186 | ehca_gen_err("Cannot create small queue SLAB cache."); | ||
187 | goto create_slab_caches6; | ||
188 | } | ||
189 | |||
162 | #ifdef CONFIG_PPC_64K_PAGES | 190 | #ifdef CONFIG_PPC_64K_PAGES |
163 | ctblk_cache = kmem_cache_create("ehca_cache_ctblk", | 191 | ctblk_cache = kmem_cache_create("ehca_cache_ctblk", |
164 | EHCA_PAGESIZE, H_CB_ALIGNMENT, | 192 | EHCA_PAGESIZE, H_CB_ALIGNMENT, |
@@ -166,12 +194,15 @@ static int ehca_create_slab_caches(void) | |||
166 | NULL); | 194 | NULL); |
167 | if (!ctblk_cache) { | 195 | if (!ctblk_cache) { |
168 | ehca_gen_err("Cannot create ctblk SLAB cache."); | 196 | ehca_gen_err("Cannot create ctblk SLAB cache."); |
169 | ehca_cleanup_mrmw_cache(); | 197 | ehca_cleanup_small_qp_cache(); |
170 | goto create_slab_caches5; | 198 | goto create_slab_caches6; |
171 | } | 199 | } |
172 | #endif | 200 | #endif |
173 | return 0; | 201 | return 0; |
174 | 202 | ||
203 | create_slab_caches6: | ||
204 | ehca_cleanup_mrmw_cache(); | ||
205 | |||
175 | create_slab_caches5: | 206 | create_slab_caches5: |
176 | ehca_cleanup_av_cache(); | 207 | ehca_cleanup_av_cache(); |
177 | 208 | ||
@@ -189,6 +220,7 @@ create_slab_caches2: | |||
189 | 220 | ||
190 | static void ehca_destroy_slab_caches(void) | 221 | static void ehca_destroy_slab_caches(void) |
191 | { | 222 | { |
223 | ehca_cleanup_small_qp_cache(); | ||
192 | ehca_cleanup_mrmw_cache(); | 224 | ehca_cleanup_mrmw_cache(); |
193 | ehca_cleanup_av_cache(); | 225 | ehca_cleanup_av_cache(); |
194 | ehca_cleanup_qp_cache(); | 226 | ehca_cleanup_qp_cache(); |
@@ -295,6 +327,8 @@ int ehca_sense_attributes(struct ehca_shca *shca) | |||
295 | if (EHCA_BMASK_GET(hca_cap_descr[i].mask, shca->hca_cap)) | 327 | if (EHCA_BMASK_GET(hca_cap_descr[i].mask, shca->hca_cap)) |
296 | ehca_gen_dbg(" %s", hca_cap_descr[i].descr); | 328 | ehca_gen_dbg(" %s", hca_cap_descr[i].descr); |
297 | 329 | ||
330 | shca->hca_cap_mr_pgsize = rblock->memory_page_size_supported; | ||
331 | |||
298 | port = (struct hipz_query_port *)rblock; | 332 | port = (struct hipz_query_port *)rblock; |
299 | h_ret = hipz_h_query_port(shca->ipz_hca_handle, 1, port); | 333 | h_ret = hipz_h_query_port(shca->ipz_hca_handle, 1, port); |
300 | if (h_ret != H_SUCCESS) { | 334 | if (h_ret != H_SUCCESS) { |
@@ -590,6 +624,14 @@ static ssize_t ehca_show_adapter_handle(struct device *dev, | |||
590 | } | 624 | } |
591 | static DEVICE_ATTR(adapter_handle, S_IRUGO, ehca_show_adapter_handle, NULL); | 625 | static DEVICE_ATTR(adapter_handle, S_IRUGO, ehca_show_adapter_handle, NULL); |
592 | 626 | ||
627 | static ssize_t ehca_show_mr_largepage(struct device *dev, | ||
628 | struct device_attribute *attr, | ||
629 | char *buf) | ||
630 | { | ||
631 | return sprintf(buf, "%d\n", ehca_mr_largepage); | ||
632 | } | ||
633 | static DEVICE_ATTR(mr_largepage, S_IRUGO, ehca_show_mr_largepage, NULL); | ||
634 | |||
593 | static struct attribute *ehca_dev_attrs[] = { | 635 | static struct attribute *ehca_dev_attrs[] = { |
594 | &dev_attr_adapter_handle.attr, | 636 | &dev_attr_adapter_handle.attr, |
595 | &dev_attr_num_ports.attr, | 637 | &dev_attr_num_ports.attr, |
@@ -606,6 +648,7 @@ static struct attribute *ehca_dev_attrs[] = { | |||
606 | &dev_attr_cur_mw.attr, | 648 | &dev_attr_cur_mw.attr, |
607 | &dev_attr_max_pd.attr, | 649 | &dev_attr_max_pd.attr, |
608 | &dev_attr_max_ah.attr, | 650 | &dev_attr_max_ah.attr, |
651 | &dev_attr_mr_largepage.attr, | ||
609 | NULL | 652 | NULL |
610 | }; | 653 | }; |
611 | 654 | ||
diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c index 9f4c9d46e8ef..c1b868b79d67 100644 --- a/drivers/infiniband/hw/ehca/ehca_mrmw.c +++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c | |||
@@ -5,6 +5,7 @@ | |||
5 | * | 5 | * |
6 | * Authors: Dietmar Decker <ddecker@de.ibm.com> | 6 | * Authors: Dietmar Decker <ddecker@de.ibm.com> |
7 | * Christoph Raisch <raisch@de.ibm.com> | 7 | * Christoph Raisch <raisch@de.ibm.com> |
8 | * Hoang-Nam Nguyen <hnguyen@de.ibm.com> | ||
8 | * | 9 | * |
9 | * Copyright (c) 2005 IBM Corporation | 10 | * Copyright (c) 2005 IBM Corporation |
10 | * | 11 | * |
@@ -56,6 +57,37 @@ | |||
56 | static struct kmem_cache *mr_cache; | 57 | static struct kmem_cache *mr_cache; |
57 | static struct kmem_cache *mw_cache; | 58 | static struct kmem_cache *mw_cache; |
58 | 59 | ||
60 | enum ehca_mr_pgsize { | ||
61 | EHCA_MR_PGSIZE4K = 0x1000L, | ||
62 | EHCA_MR_PGSIZE64K = 0x10000L, | ||
63 | EHCA_MR_PGSIZE1M = 0x100000L, | ||
64 | EHCA_MR_PGSIZE16M = 0x1000000L | ||
65 | }; | ||
66 | |||
67 | extern int ehca_mr_largepage; | ||
68 | |||
69 | static u32 ehca_encode_hwpage_size(u32 pgsize) | ||
70 | { | ||
71 | u32 idx = 0; | ||
72 | pgsize >>= 12; | ||
73 | /* | ||
74 | * map mr page size into hw code: | ||
75 | * 0, 1, 2, 3 for 4K, 64K, 1M, 64M | ||
76 | */ | ||
77 | while (!(pgsize & 1)) { | ||
78 | idx++; | ||
79 | pgsize >>= 4; | ||
80 | } | ||
81 | return idx; | ||
82 | } | ||
83 | |||
84 | static u64 ehca_get_max_hwpage_size(struct ehca_shca *shca) | ||
85 | { | ||
86 | if (shca->hca_cap_mr_pgsize & HCA_CAP_MR_PGSIZE_16M) | ||
87 | return EHCA_MR_PGSIZE16M; | ||
88 | return EHCA_MR_PGSIZE4K; | ||
89 | } | ||
90 | |||
59 | static struct ehca_mr *ehca_mr_new(void) | 91 | static struct ehca_mr *ehca_mr_new(void) |
60 | { | 92 | { |
61 | struct ehca_mr *me; | 93 | struct ehca_mr *me; |
@@ -207,19 +239,23 @@ struct ib_mr *ehca_reg_phys_mr(struct ib_pd *pd, | |||
207 | struct ehca_mr_pginfo pginfo; | 239 | struct ehca_mr_pginfo pginfo; |
208 | u32 num_kpages; | 240 | u32 num_kpages; |
209 | u32 num_hwpages; | 241 | u32 num_hwpages; |
242 | u64 hw_pgsize; | ||
210 | 243 | ||
211 | num_kpages = NUM_CHUNKS(((u64)iova_start % PAGE_SIZE) + size, | 244 | num_kpages = NUM_CHUNKS(((u64)iova_start % PAGE_SIZE) + size, |
212 | PAGE_SIZE); | 245 | PAGE_SIZE); |
213 | num_hwpages = NUM_CHUNKS(((u64)iova_start % EHCA_PAGESIZE) + | 246 | /* for kernel space we try most possible pgsize */ |
214 | size, EHCA_PAGESIZE); | 247 | hw_pgsize = ehca_get_max_hwpage_size(shca); |
248 | num_hwpages = NUM_CHUNKS(((u64)iova_start % hw_pgsize) + size, | ||
249 | hw_pgsize); | ||
215 | memset(&pginfo, 0, sizeof(pginfo)); | 250 | memset(&pginfo, 0, sizeof(pginfo)); |
216 | pginfo.type = EHCA_MR_PGI_PHYS; | 251 | pginfo.type = EHCA_MR_PGI_PHYS; |
217 | pginfo.num_kpages = num_kpages; | 252 | pginfo.num_kpages = num_kpages; |
253 | pginfo.hwpage_size = hw_pgsize; | ||
218 | pginfo.num_hwpages = num_hwpages; | 254 | pginfo.num_hwpages = num_hwpages; |
219 | pginfo.u.phy.num_phys_buf = num_phys_buf; | 255 | pginfo.u.phy.num_phys_buf = num_phys_buf; |
220 | pginfo.u.phy.phys_buf_array = phys_buf_array; | 256 | pginfo.u.phy.phys_buf_array = phys_buf_array; |
221 | pginfo.next_hwpage = (((u64)iova_start & ~PAGE_MASK) / | 257 | pginfo.next_hwpage = |
222 | EHCA_PAGESIZE); | 258 | ((u64)iova_start & ~(hw_pgsize - 1)) / hw_pgsize; |
223 | 259 | ||
224 | ret = ehca_reg_mr(shca, e_mr, iova_start, size, mr_access_flags, | 260 | ret = ehca_reg_mr(shca, e_mr, iova_start, size, mr_access_flags, |
225 | e_pd, &pginfo, &e_mr->ib.ib_mr.lkey, | 261 | e_pd, &pginfo, &e_mr->ib.ib_mr.lkey, |
@@ -259,6 +295,7 @@ struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, | |||
259 | int ret; | 295 | int ret; |
260 | u32 num_kpages; | 296 | u32 num_kpages; |
261 | u32 num_hwpages; | 297 | u32 num_hwpages; |
298 | u64 hwpage_size; | ||
262 | 299 | ||
263 | if (!pd) { | 300 | if (!pd) { |
264 | ehca_gen_err("bad pd=%p", pd); | 301 | ehca_gen_err("bad pd=%p", pd); |
@@ -309,16 +346,32 @@ struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, | |||
309 | 346 | ||
310 | /* determine number of MR pages */ | 347 | /* determine number of MR pages */ |
311 | num_kpages = NUM_CHUNKS((virt % PAGE_SIZE) + length, PAGE_SIZE); | 348 | num_kpages = NUM_CHUNKS((virt % PAGE_SIZE) + length, PAGE_SIZE); |
312 | num_hwpages = NUM_CHUNKS((virt % EHCA_PAGESIZE) + length, | 349 | /* select proper hw_pgsize */ |
313 | EHCA_PAGESIZE); | 350 | if (ehca_mr_largepage && |
351 | (shca->hca_cap_mr_pgsize & HCA_CAP_MR_PGSIZE_16M)) { | ||
352 | if (length <= EHCA_MR_PGSIZE4K | ||
353 | && PAGE_SIZE == EHCA_MR_PGSIZE4K) | ||
354 | hwpage_size = EHCA_MR_PGSIZE4K; | ||
355 | else if (length <= EHCA_MR_PGSIZE64K) | ||
356 | hwpage_size = EHCA_MR_PGSIZE64K; | ||
357 | else if (length <= EHCA_MR_PGSIZE1M) | ||
358 | hwpage_size = EHCA_MR_PGSIZE1M; | ||
359 | else | ||
360 | hwpage_size = EHCA_MR_PGSIZE16M; | ||
361 | } else | ||
362 | hwpage_size = EHCA_MR_PGSIZE4K; | ||
363 | ehca_dbg(pd->device, "hwpage_size=%lx", hwpage_size); | ||
314 | 364 | ||
365 | reg_user_mr_fallback: | ||
366 | num_hwpages = NUM_CHUNKS((virt % hwpage_size) + length, hwpage_size); | ||
315 | /* register MR on HCA */ | 367 | /* register MR on HCA */ |
316 | memset(&pginfo, 0, sizeof(pginfo)); | 368 | memset(&pginfo, 0, sizeof(pginfo)); |
317 | pginfo.type = EHCA_MR_PGI_USER; | 369 | pginfo.type = EHCA_MR_PGI_USER; |
370 | pginfo.hwpage_size = hwpage_size; | ||
318 | pginfo.num_kpages = num_kpages; | 371 | pginfo.num_kpages = num_kpages; |
319 | pginfo.num_hwpages = num_hwpages; | 372 | pginfo.num_hwpages = num_hwpages; |
320 | pginfo.u.usr.region = e_mr->umem; | 373 | pginfo.u.usr.region = e_mr->umem; |
321 | pginfo.next_hwpage = e_mr->umem->offset / EHCA_PAGESIZE; | 374 | pginfo.next_hwpage = e_mr->umem->offset / hwpage_size; |
322 | pginfo.u.usr.next_chunk = list_prepare_entry(pginfo.u.usr.next_chunk, | 375 | pginfo.u.usr.next_chunk = list_prepare_entry(pginfo.u.usr.next_chunk, |
323 | (&e_mr->umem->chunk_list), | 376 | (&e_mr->umem->chunk_list), |
324 | list); | 377 | list); |
@@ -326,6 +379,18 @@ struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, | |||
326 | ret = ehca_reg_mr(shca, e_mr, (u64 *)virt, length, mr_access_flags, | 379 | ret = ehca_reg_mr(shca, e_mr, (u64 *)virt, length, mr_access_flags, |
327 | e_pd, &pginfo, &e_mr->ib.ib_mr.lkey, | 380 | e_pd, &pginfo, &e_mr->ib.ib_mr.lkey, |
328 | &e_mr->ib.ib_mr.rkey); | 381 | &e_mr->ib.ib_mr.rkey); |
382 | if (ret == -EINVAL && pginfo.hwpage_size > PAGE_SIZE) { | ||
383 | ehca_warn(pd->device, "failed to register mr " | ||
384 | "with hwpage_size=%lx", hwpage_size); | ||
385 | ehca_info(pd->device, "try to register mr with " | ||
386 | "kpage_size=%lx", PAGE_SIZE); | ||
387 | /* | ||
388 | * this means kpages are not contiguous for a hw page | ||
389 | * try kernel page size as fallback solution | ||
390 | */ | ||
391 | hwpage_size = PAGE_SIZE; | ||
392 | goto reg_user_mr_fallback; | ||
393 | } | ||
329 | if (ret) { | 394 | if (ret) { |
330 | ib_mr = ERR_PTR(ret); | 395 | ib_mr = ERR_PTR(ret); |
331 | goto reg_user_mr_exit2; | 396 | goto reg_user_mr_exit2; |
@@ -452,6 +517,8 @@ int ehca_rereg_phys_mr(struct ib_mr *mr, | |||
452 | new_pd = container_of(mr->pd, struct ehca_pd, ib_pd); | 517 | new_pd = container_of(mr->pd, struct ehca_pd, ib_pd); |
453 | 518 | ||
454 | if (mr_rereg_mask & IB_MR_REREG_TRANS) { | 519 | if (mr_rereg_mask & IB_MR_REREG_TRANS) { |
520 | u64 hw_pgsize = ehca_get_max_hwpage_size(shca); | ||
521 | |||
455 | new_start = iova_start; /* change address */ | 522 | new_start = iova_start; /* change address */ |
456 | /* check physical buffer list and calculate size */ | 523 | /* check physical buffer list and calculate size */ |
457 | ret = ehca_mr_chk_buf_and_calc_size(phys_buf_array, | 524 | ret = ehca_mr_chk_buf_and_calc_size(phys_buf_array, |
@@ -468,16 +535,17 @@ int ehca_rereg_phys_mr(struct ib_mr *mr, | |||
468 | } | 535 | } |
469 | num_kpages = NUM_CHUNKS(((u64)new_start % PAGE_SIZE) + | 536 | num_kpages = NUM_CHUNKS(((u64)new_start % PAGE_SIZE) + |
470 | new_size, PAGE_SIZE); | 537 | new_size, PAGE_SIZE); |
471 | num_hwpages = NUM_CHUNKS(((u64)new_start % EHCA_PAGESIZE) + | 538 | num_hwpages = NUM_CHUNKS(((u64)new_start % hw_pgsize) + |
472 | new_size, EHCA_PAGESIZE); | 539 | new_size, hw_pgsize); |
473 | memset(&pginfo, 0, sizeof(pginfo)); | 540 | memset(&pginfo, 0, sizeof(pginfo)); |
474 | pginfo.type = EHCA_MR_PGI_PHYS; | 541 | pginfo.type = EHCA_MR_PGI_PHYS; |
475 | pginfo.num_kpages = num_kpages; | 542 | pginfo.num_kpages = num_kpages; |
543 | pginfo.hwpage_size = hw_pgsize; | ||
476 | pginfo.num_hwpages = num_hwpages; | 544 | pginfo.num_hwpages = num_hwpages; |
477 | pginfo.u.phy.num_phys_buf = num_phys_buf; | 545 | pginfo.u.phy.num_phys_buf = num_phys_buf; |
478 | pginfo.u.phy.phys_buf_array = phys_buf_array; | 546 | pginfo.u.phy.phys_buf_array = phys_buf_array; |
479 | pginfo.next_hwpage = (((u64)iova_start & ~PAGE_MASK) / | 547 | pginfo.next_hwpage = |
480 | EHCA_PAGESIZE); | 548 | ((u64)iova_start & ~(hw_pgsize - 1)) / hw_pgsize; |
481 | } | 549 | } |
482 | if (mr_rereg_mask & IB_MR_REREG_ACCESS) | 550 | if (mr_rereg_mask & IB_MR_REREG_ACCESS) |
483 | new_acl = mr_access_flags; | 551 | new_acl = mr_access_flags; |
@@ -709,6 +777,7 @@ struct ib_fmr *ehca_alloc_fmr(struct ib_pd *pd, | |||
709 | int ret; | 777 | int ret; |
710 | u32 tmp_lkey, tmp_rkey; | 778 | u32 tmp_lkey, tmp_rkey; |
711 | struct ehca_mr_pginfo pginfo; | 779 | struct ehca_mr_pginfo pginfo; |
780 | u64 hw_pgsize; | ||
712 | 781 | ||
713 | /* check other parameters */ | 782 | /* check other parameters */ |
714 | if (((mr_access_flags & IB_ACCESS_REMOTE_WRITE) && | 783 | if (((mr_access_flags & IB_ACCESS_REMOTE_WRITE) && |
@@ -738,8 +807,8 @@ struct ib_fmr *ehca_alloc_fmr(struct ib_pd *pd, | |||
738 | ib_fmr = ERR_PTR(-EINVAL); | 807 | ib_fmr = ERR_PTR(-EINVAL); |
739 | goto alloc_fmr_exit0; | 808 | goto alloc_fmr_exit0; |
740 | } | 809 | } |
741 | if (((1 << fmr_attr->page_shift) != EHCA_PAGESIZE) && | 810 | hw_pgsize = ehca_get_max_hwpage_size(shca); |
742 | ((1 << fmr_attr->page_shift) != PAGE_SIZE)) { | 811 | if ((1 << fmr_attr->page_shift) != hw_pgsize) { |
743 | ehca_err(pd->device, "unsupported fmr_attr->page_shift=%x", | 812 | ehca_err(pd->device, "unsupported fmr_attr->page_shift=%x", |
744 | fmr_attr->page_shift); | 813 | fmr_attr->page_shift); |
745 | ib_fmr = ERR_PTR(-EINVAL); | 814 | ib_fmr = ERR_PTR(-EINVAL); |
@@ -755,6 +824,10 @@ struct ib_fmr *ehca_alloc_fmr(struct ib_pd *pd, | |||
755 | 824 | ||
756 | /* register MR on HCA */ | 825 | /* register MR on HCA */ |
757 | memset(&pginfo, 0, sizeof(pginfo)); | 826 | memset(&pginfo, 0, sizeof(pginfo)); |
827 | /* | ||
828 | * pginfo.num_hwpages==0, ie register_rpages() will not be called | ||
829 | * but deferred to map_phys_fmr() | ||
830 | */ | ||
758 | ret = ehca_reg_mr(shca, e_fmr, NULL, | 831 | ret = ehca_reg_mr(shca, e_fmr, NULL, |
759 | fmr_attr->max_pages * (1 << fmr_attr->page_shift), | 832 | fmr_attr->max_pages * (1 << fmr_attr->page_shift), |
760 | mr_access_flags, e_pd, &pginfo, | 833 | mr_access_flags, e_pd, &pginfo, |
@@ -765,6 +838,7 @@ struct ib_fmr *ehca_alloc_fmr(struct ib_pd *pd, | |||
765 | } | 838 | } |
766 | 839 | ||
767 | /* successful */ | 840 | /* successful */ |
841 | e_fmr->hwpage_size = hw_pgsize; | ||
768 | e_fmr->fmr_page_size = 1 << fmr_attr->page_shift; | 842 | e_fmr->fmr_page_size = 1 << fmr_attr->page_shift; |
769 | e_fmr->fmr_max_pages = fmr_attr->max_pages; | 843 | e_fmr->fmr_max_pages = fmr_attr->max_pages; |
770 | e_fmr->fmr_max_maps = fmr_attr->max_maps; | 844 | e_fmr->fmr_max_maps = fmr_attr->max_maps; |
@@ -822,10 +896,12 @@ int ehca_map_phys_fmr(struct ib_fmr *fmr, | |||
822 | memset(&pginfo, 0, sizeof(pginfo)); | 896 | memset(&pginfo, 0, sizeof(pginfo)); |
823 | pginfo.type = EHCA_MR_PGI_FMR; | 897 | pginfo.type = EHCA_MR_PGI_FMR; |
824 | pginfo.num_kpages = list_len; | 898 | pginfo.num_kpages = list_len; |
825 | pginfo.num_hwpages = list_len * (e_fmr->fmr_page_size / EHCA_PAGESIZE); | 899 | pginfo.hwpage_size = e_fmr->hwpage_size; |
900 | pginfo.num_hwpages = | ||
901 | list_len * e_fmr->fmr_page_size / pginfo.hwpage_size; | ||
826 | pginfo.u.fmr.page_list = page_list; | 902 | pginfo.u.fmr.page_list = page_list; |
827 | pginfo.next_hwpage = ((iova & (e_fmr->fmr_page_size-1)) / | 903 | pginfo.next_hwpage = |
828 | EHCA_PAGESIZE); | 904 | (iova & (e_fmr->fmr_page_size-1)) / pginfo.hwpage_size; |
829 | pginfo.u.fmr.fmr_pgsize = e_fmr->fmr_page_size; | 905 | pginfo.u.fmr.fmr_pgsize = e_fmr->fmr_page_size; |
830 | 906 | ||
831 | ret = ehca_rereg_mr(shca, e_fmr, (u64 *)iova, | 907 | ret = ehca_rereg_mr(shca, e_fmr, (u64 *)iova, |
@@ -964,7 +1040,7 @@ int ehca_reg_mr(struct ehca_shca *shca, | |||
964 | struct ehca_mr_hipzout_parms hipzout; | 1040 | struct ehca_mr_hipzout_parms hipzout; |
965 | 1041 | ||
966 | ehca_mrmw_map_acl(acl, &hipz_acl); | 1042 | ehca_mrmw_map_acl(acl, &hipz_acl); |
967 | ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl); | 1043 | ehca_mrmw_set_pgsize_hipz_acl(pginfo->hwpage_size, &hipz_acl); |
968 | if (ehca_use_hp_mr == 1) | 1044 | if (ehca_use_hp_mr == 1) |
969 | hipz_acl |= 0x00000001; | 1045 | hipz_acl |= 0x00000001; |
970 | 1046 | ||
@@ -987,6 +1063,7 @@ int ehca_reg_mr(struct ehca_shca *shca, | |||
987 | /* successful registration */ | 1063 | /* successful registration */ |
988 | e_mr->num_kpages = pginfo->num_kpages; | 1064 | e_mr->num_kpages = pginfo->num_kpages; |
989 | e_mr->num_hwpages = pginfo->num_hwpages; | 1065 | e_mr->num_hwpages = pginfo->num_hwpages; |
1066 | e_mr->hwpage_size = pginfo->hwpage_size; | ||
990 | e_mr->start = iova_start; | 1067 | e_mr->start = iova_start; |
991 | e_mr->size = size; | 1068 | e_mr->size = size; |
992 | e_mr->acl = acl; | 1069 | e_mr->acl = acl; |
@@ -1029,6 +1106,9 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca, | |||
1029 | u32 i; | 1106 | u32 i; |
1030 | u64 *kpage; | 1107 | u64 *kpage; |
1031 | 1108 | ||
1109 | if (!pginfo->num_hwpages) /* in case of fmr */ | ||
1110 | return 0; | ||
1111 | |||
1032 | kpage = ehca_alloc_fw_ctrlblock(GFP_KERNEL); | 1112 | kpage = ehca_alloc_fw_ctrlblock(GFP_KERNEL); |
1033 | if (!kpage) { | 1113 | if (!kpage) { |
1034 | ehca_err(&shca->ib_device, "kpage alloc failed"); | 1114 | ehca_err(&shca->ib_device, "kpage alloc failed"); |
@@ -1036,7 +1116,7 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca, | |||
1036 | goto ehca_reg_mr_rpages_exit0; | 1116 | goto ehca_reg_mr_rpages_exit0; |
1037 | } | 1117 | } |
1038 | 1118 | ||
1039 | /* max 512 pages per shot */ | 1119 | /* max MAX_RPAGES ehca mr pages per register call */ |
1040 | for (i = 0; i < NUM_CHUNKS(pginfo->num_hwpages, MAX_RPAGES); i++) { | 1120 | for (i = 0; i < NUM_CHUNKS(pginfo->num_hwpages, MAX_RPAGES); i++) { |
1041 | 1121 | ||
1042 | if (i == NUM_CHUNKS(pginfo->num_hwpages, MAX_RPAGES) - 1) { | 1122 | if (i == NUM_CHUNKS(pginfo->num_hwpages, MAX_RPAGES) - 1) { |
@@ -1049,8 +1129,8 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca, | |||
1049 | ret = ehca_set_pagebuf(pginfo, rnum, kpage); | 1129 | ret = ehca_set_pagebuf(pginfo, rnum, kpage); |
1050 | if (ret) { | 1130 | if (ret) { |
1051 | ehca_err(&shca->ib_device, "ehca_set_pagebuf " | 1131 | ehca_err(&shca->ib_device, "ehca_set_pagebuf " |
1052 | "bad rc, ret=%x rnum=%x kpage=%p", | 1132 | "bad rc, ret=%x rnum=%x kpage=%p", |
1053 | ret, rnum, kpage); | 1133 | ret, rnum, kpage); |
1054 | goto ehca_reg_mr_rpages_exit1; | 1134 | goto ehca_reg_mr_rpages_exit1; |
1055 | } | 1135 | } |
1056 | 1136 | ||
@@ -1065,9 +1145,10 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca, | |||
1065 | } else | 1145 | } else |
1066 | rpage = *kpage; | 1146 | rpage = *kpage; |
1067 | 1147 | ||
1068 | h_ret = hipz_h_register_rpage_mr(shca->ipz_hca_handle, e_mr, | 1148 | h_ret = hipz_h_register_rpage_mr( |
1069 | 0, /* pagesize 4k */ | 1149 | shca->ipz_hca_handle, e_mr, |
1070 | 0, rpage, rnum); | 1150 | ehca_encode_hwpage_size(pginfo->hwpage_size), |
1151 | 0, rpage, rnum); | ||
1071 | 1152 | ||
1072 | if (i == NUM_CHUNKS(pginfo->num_hwpages, MAX_RPAGES) - 1) { | 1153 | if (i == NUM_CHUNKS(pginfo->num_hwpages, MAX_RPAGES) - 1) { |
1073 | /* | 1154 | /* |
@@ -1131,7 +1212,7 @@ inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca, | |||
1131 | struct ehca_mr_hipzout_parms hipzout; | 1212 | struct ehca_mr_hipzout_parms hipzout; |
1132 | 1213 | ||
1133 | ehca_mrmw_map_acl(acl, &hipz_acl); | 1214 | ehca_mrmw_map_acl(acl, &hipz_acl); |
1134 | ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl); | 1215 | ehca_mrmw_set_pgsize_hipz_acl(pginfo->hwpage_size, &hipz_acl); |
1135 | 1216 | ||
1136 | kpage = ehca_alloc_fw_ctrlblock(GFP_KERNEL); | 1217 | kpage = ehca_alloc_fw_ctrlblock(GFP_KERNEL); |
1137 | if (!kpage) { | 1218 | if (!kpage) { |
@@ -1182,6 +1263,7 @@ inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca, | |||
1182 | */ | 1263 | */ |
1183 | e_mr->num_kpages = pginfo->num_kpages; | 1264 | e_mr->num_kpages = pginfo->num_kpages; |
1184 | e_mr->num_hwpages = pginfo->num_hwpages; | 1265 | e_mr->num_hwpages = pginfo->num_hwpages; |
1266 | e_mr->hwpage_size = pginfo->hwpage_size; | ||
1185 | e_mr->start = iova_start; | 1267 | e_mr->start = iova_start; |
1186 | e_mr->size = size; | 1268 | e_mr->size = size; |
1187 | e_mr->acl = acl; | 1269 | e_mr->acl = acl; |
@@ -1268,13 +1350,14 @@ int ehca_rereg_mr(struct ehca_shca *shca, | |||
1268 | 1350 | ||
1269 | /* set some MR values */ | 1351 | /* set some MR values */ |
1270 | e_mr->flags = save_mr.flags; | 1352 | e_mr->flags = save_mr.flags; |
1353 | e_mr->hwpage_size = save_mr.hwpage_size; | ||
1271 | e_mr->fmr_page_size = save_mr.fmr_page_size; | 1354 | e_mr->fmr_page_size = save_mr.fmr_page_size; |
1272 | e_mr->fmr_max_pages = save_mr.fmr_max_pages; | 1355 | e_mr->fmr_max_pages = save_mr.fmr_max_pages; |
1273 | e_mr->fmr_max_maps = save_mr.fmr_max_maps; | 1356 | e_mr->fmr_max_maps = save_mr.fmr_max_maps; |
1274 | e_mr->fmr_map_cnt = save_mr.fmr_map_cnt; | 1357 | e_mr->fmr_map_cnt = save_mr.fmr_map_cnt; |
1275 | 1358 | ||
1276 | ret = ehca_reg_mr(shca, e_mr, iova_start, size, acl, | 1359 | ret = ehca_reg_mr(shca, e_mr, iova_start, size, acl, |
1277 | e_pd, pginfo, lkey, rkey); | 1360 | e_pd, pginfo, lkey, rkey); |
1278 | if (ret) { | 1361 | if (ret) { |
1279 | u32 offset = (u64)(&e_mr->flags) - (u64)e_mr; | 1362 | u32 offset = (u64)(&e_mr->flags) - (u64)e_mr; |
1280 | memcpy(&e_mr->flags, &(save_mr.flags), | 1363 | memcpy(&e_mr->flags, &(save_mr.flags), |
@@ -1355,6 +1438,7 @@ int ehca_unmap_one_fmr(struct ehca_shca *shca, | |||
1355 | 1438 | ||
1356 | /* set some MR values */ | 1439 | /* set some MR values */ |
1357 | e_fmr->flags = save_fmr.flags; | 1440 | e_fmr->flags = save_fmr.flags; |
1441 | e_fmr->hwpage_size = save_fmr.hwpage_size; | ||
1358 | e_fmr->fmr_page_size = save_fmr.fmr_page_size; | 1442 | e_fmr->fmr_page_size = save_fmr.fmr_page_size; |
1359 | e_fmr->fmr_max_pages = save_fmr.fmr_max_pages; | 1443 | e_fmr->fmr_max_pages = save_fmr.fmr_max_pages; |
1360 | e_fmr->fmr_max_maps = save_fmr.fmr_max_maps; | 1444 | e_fmr->fmr_max_maps = save_fmr.fmr_max_maps; |
@@ -1363,8 +1447,6 @@ int ehca_unmap_one_fmr(struct ehca_shca *shca, | |||
1363 | 1447 | ||
1364 | memset(&pginfo, 0, sizeof(pginfo)); | 1448 | memset(&pginfo, 0, sizeof(pginfo)); |
1365 | pginfo.type = EHCA_MR_PGI_FMR; | 1449 | pginfo.type = EHCA_MR_PGI_FMR; |
1366 | pginfo.num_kpages = 0; | ||
1367 | pginfo.num_hwpages = 0; | ||
1368 | ret = ehca_reg_mr(shca, e_fmr, NULL, | 1450 | ret = ehca_reg_mr(shca, e_fmr, NULL, |
1369 | (e_fmr->fmr_max_pages * e_fmr->fmr_page_size), | 1451 | (e_fmr->fmr_max_pages * e_fmr->fmr_page_size), |
1370 | e_fmr->acl, e_pd, &pginfo, &tmp_lkey, | 1452 | e_fmr->acl, e_pd, &pginfo, &tmp_lkey, |
@@ -1373,7 +1455,6 @@ int ehca_unmap_one_fmr(struct ehca_shca *shca, | |||
1373 | u32 offset = (u64)(&e_fmr->flags) - (u64)e_fmr; | 1455 | u32 offset = (u64)(&e_fmr->flags) - (u64)e_fmr; |
1374 | memcpy(&e_fmr->flags, &(save_mr.flags), | 1456 | memcpy(&e_fmr->flags, &(save_mr.flags), |
1375 | sizeof(struct ehca_mr) - offset); | 1457 | sizeof(struct ehca_mr) - offset); |
1376 | goto ehca_unmap_one_fmr_exit0; | ||
1377 | } | 1458 | } |
1378 | 1459 | ||
1379 | ehca_unmap_one_fmr_exit0: | 1460 | ehca_unmap_one_fmr_exit0: |
@@ -1401,7 +1482,7 @@ int ehca_reg_smr(struct ehca_shca *shca, | |||
1401 | struct ehca_mr_hipzout_parms hipzout; | 1482 | struct ehca_mr_hipzout_parms hipzout; |
1402 | 1483 | ||
1403 | ehca_mrmw_map_acl(acl, &hipz_acl); | 1484 | ehca_mrmw_map_acl(acl, &hipz_acl); |
1404 | ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl); | 1485 | ehca_mrmw_set_pgsize_hipz_acl(e_origmr->hwpage_size, &hipz_acl); |
1405 | 1486 | ||
1406 | h_ret = hipz_h_register_smr(shca->ipz_hca_handle, e_newmr, e_origmr, | 1487 | h_ret = hipz_h_register_smr(shca->ipz_hca_handle, e_newmr, e_origmr, |
1407 | (u64)iova_start, hipz_acl, e_pd->fw_pd, | 1488 | (u64)iova_start, hipz_acl, e_pd->fw_pd, |
@@ -1420,6 +1501,7 @@ int ehca_reg_smr(struct ehca_shca *shca, | |||
1420 | /* successful registration */ | 1501 | /* successful registration */ |
1421 | e_newmr->num_kpages = e_origmr->num_kpages; | 1502 | e_newmr->num_kpages = e_origmr->num_kpages; |
1422 | e_newmr->num_hwpages = e_origmr->num_hwpages; | 1503 | e_newmr->num_hwpages = e_origmr->num_hwpages; |
1504 | e_newmr->hwpage_size = e_origmr->hwpage_size; | ||
1423 | e_newmr->start = iova_start; | 1505 | e_newmr->start = iova_start; |
1424 | e_newmr->size = e_origmr->size; | 1506 | e_newmr->size = e_origmr->size; |
1425 | e_newmr->acl = acl; | 1507 | e_newmr->acl = acl; |
@@ -1452,6 +1534,7 @@ int ehca_reg_internal_maxmr( | |||
1452 | struct ib_phys_buf ib_pbuf; | 1534 | struct ib_phys_buf ib_pbuf; |
1453 | u32 num_kpages; | 1535 | u32 num_kpages; |
1454 | u32 num_hwpages; | 1536 | u32 num_hwpages; |
1537 | u64 hw_pgsize; | ||
1455 | 1538 | ||
1456 | e_mr = ehca_mr_new(); | 1539 | e_mr = ehca_mr_new(); |
1457 | if (!e_mr) { | 1540 | if (!e_mr) { |
@@ -1468,13 +1551,15 @@ int ehca_reg_internal_maxmr( | |||
1468 | ib_pbuf.size = size_maxmr; | 1551 | ib_pbuf.size = size_maxmr; |
1469 | num_kpages = NUM_CHUNKS(((u64)iova_start % PAGE_SIZE) + size_maxmr, | 1552 | num_kpages = NUM_CHUNKS(((u64)iova_start % PAGE_SIZE) + size_maxmr, |
1470 | PAGE_SIZE); | 1553 | PAGE_SIZE); |
1471 | num_hwpages = NUM_CHUNKS(((u64)iova_start % EHCA_PAGESIZE) + size_maxmr, | 1554 | hw_pgsize = ehca_get_max_hwpage_size(shca); |
1472 | EHCA_PAGESIZE); | 1555 | num_hwpages = NUM_CHUNKS(((u64)iova_start % hw_pgsize) + size_maxmr, |
1556 | hw_pgsize); | ||
1473 | 1557 | ||
1474 | memset(&pginfo, 0, sizeof(pginfo)); | 1558 | memset(&pginfo, 0, sizeof(pginfo)); |
1475 | pginfo.type = EHCA_MR_PGI_PHYS; | 1559 | pginfo.type = EHCA_MR_PGI_PHYS; |
1476 | pginfo.num_kpages = num_kpages; | 1560 | pginfo.num_kpages = num_kpages; |
1477 | pginfo.num_hwpages = num_hwpages; | 1561 | pginfo.num_hwpages = num_hwpages; |
1562 | pginfo.hwpage_size = hw_pgsize; | ||
1478 | pginfo.u.phy.num_phys_buf = 1; | 1563 | pginfo.u.phy.num_phys_buf = 1; |
1479 | pginfo.u.phy.phys_buf_array = &ib_pbuf; | 1564 | pginfo.u.phy.phys_buf_array = &ib_pbuf; |
1480 | 1565 | ||
@@ -1523,7 +1608,7 @@ int ehca_reg_maxmr(struct ehca_shca *shca, | |||
1523 | struct ehca_mr_hipzout_parms hipzout; | 1608 | struct ehca_mr_hipzout_parms hipzout; |
1524 | 1609 | ||
1525 | ehca_mrmw_map_acl(acl, &hipz_acl); | 1610 | ehca_mrmw_map_acl(acl, &hipz_acl); |
1526 | ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl); | 1611 | ehca_mrmw_set_pgsize_hipz_acl(e_origmr->hwpage_size, &hipz_acl); |
1527 | 1612 | ||
1528 | h_ret = hipz_h_register_smr(shca->ipz_hca_handle, e_newmr, e_origmr, | 1613 | h_ret = hipz_h_register_smr(shca->ipz_hca_handle, e_newmr, e_origmr, |
1529 | (u64)iova_start, hipz_acl, e_pd->fw_pd, | 1614 | (u64)iova_start, hipz_acl, e_pd->fw_pd, |
@@ -1539,6 +1624,7 @@ int ehca_reg_maxmr(struct ehca_shca *shca, | |||
1539 | /* successful registration */ | 1624 | /* successful registration */ |
1540 | e_newmr->num_kpages = e_origmr->num_kpages; | 1625 | e_newmr->num_kpages = e_origmr->num_kpages; |
1541 | e_newmr->num_hwpages = e_origmr->num_hwpages; | 1626 | e_newmr->num_hwpages = e_origmr->num_hwpages; |
1627 | e_newmr->hwpage_size = e_origmr->hwpage_size; | ||
1542 | e_newmr->start = iova_start; | 1628 | e_newmr->start = iova_start; |
1543 | e_newmr->size = e_origmr->size; | 1629 | e_newmr->size = e_origmr->size; |
1544 | e_newmr->acl = acl; | 1630 | e_newmr->acl = acl; |
@@ -1684,6 +1770,7 @@ static int ehca_set_pagebuf_user1(struct ehca_mr_pginfo *pginfo, | |||
1684 | u64 pgaddr; | 1770 | u64 pgaddr; |
1685 | u32 i = 0; | 1771 | u32 i = 0; |
1686 | u32 j = 0; | 1772 | u32 j = 0; |
1773 | int hwpages_per_kpage = PAGE_SIZE / pginfo->hwpage_size; | ||
1687 | 1774 | ||
1688 | /* loop over desired chunk entries */ | 1775 | /* loop over desired chunk entries */ |
1689 | chunk = pginfo->u.usr.next_chunk; | 1776 | chunk = pginfo->u.usr.next_chunk; |
@@ -1695,7 +1782,7 @@ static int ehca_set_pagebuf_user1(struct ehca_mr_pginfo *pginfo, | |||
1695 | << PAGE_SHIFT ; | 1782 | << PAGE_SHIFT ; |
1696 | *kpage = phys_to_abs(pgaddr + | 1783 | *kpage = phys_to_abs(pgaddr + |
1697 | (pginfo->next_hwpage * | 1784 | (pginfo->next_hwpage * |
1698 | EHCA_PAGESIZE)); | 1785 | pginfo->hwpage_size)); |
1699 | if ( !(*kpage) ) { | 1786 | if ( !(*kpage) ) { |
1700 | ehca_gen_err("pgaddr=%lx " | 1787 | ehca_gen_err("pgaddr=%lx " |
1701 | "chunk->page_list[i]=%lx " | 1788 | "chunk->page_list[i]=%lx " |
@@ -1708,8 +1795,7 @@ static int ehca_set_pagebuf_user1(struct ehca_mr_pginfo *pginfo, | |||
1708 | (pginfo->hwpage_cnt)++; | 1795 | (pginfo->hwpage_cnt)++; |
1709 | (pginfo->next_hwpage)++; | 1796 | (pginfo->next_hwpage)++; |
1710 | kpage++; | 1797 | kpage++; |
1711 | if (pginfo->next_hwpage % | 1798 | if (pginfo->next_hwpage % hwpages_per_kpage == 0) { |
1712 | (PAGE_SIZE / EHCA_PAGESIZE) == 0) { | ||
1713 | (pginfo->kpage_cnt)++; | 1799 | (pginfo->kpage_cnt)++; |
1714 | (pginfo->u.usr.next_nmap)++; | 1800 | (pginfo->u.usr.next_nmap)++; |
1715 | pginfo->next_hwpage = 0; | 1801 | pginfo->next_hwpage = 0; |
@@ -1738,6 +1824,143 @@ static int ehca_set_pagebuf_user1(struct ehca_mr_pginfo *pginfo, | |||
1738 | return ret; | 1824 | return ret; |
1739 | } | 1825 | } |
1740 | 1826 | ||
1827 | /* | ||
1828 | * check given pages for contiguous layout | ||
1829 | * last page addr is returned in prev_pgaddr for further check | ||
1830 | */ | ||
1831 | static int ehca_check_kpages_per_ate(struct scatterlist *page_list, | ||
1832 | int start_idx, int end_idx, | ||
1833 | u64 *prev_pgaddr) | ||
1834 | { | ||
1835 | int t; | ||
1836 | for (t = start_idx; t <= end_idx; t++) { | ||
1837 | u64 pgaddr = page_to_pfn(page_list[t].page) << PAGE_SHIFT; | ||
1838 | ehca_gen_dbg("chunk_page=%lx value=%016lx", pgaddr, | ||
1839 | *(u64 *)abs_to_virt(phys_to_abs(pgaddr))); | ||
1840 | if (pgaddr - PAGE_SIZE != *prev_pgaddr) { | ||
1841 | ehca_gen_err("uncontiguous page found pgaddr=%lx " | ||
1842 | "prev_pgaddr=%lx page_list_i=%x", | ||
1843 | pgaddr, *prev_pgaddr, t); | ||
1844 | return -EINVAL; | ||
1845 | } | ||
1846 | *prev_pgaddr = pgaddr; | ||
1847 | } | ||
1848 | return 0; | ||
1849 | } | ||
1850 | |||
1851 | /* PAGE_SIZE < pginfo->hwpage_size */ | ||
1852 | static int ehca_set_pagebuf_user2(struct ehca_mr_pginfo *pginfo, | ||
1853 | u32 number, | ||
1854 | u64 *kpage) | ||
1855 | { | ||
1856 | int ret = 0; | ||
1857 | struct ib_umem_chunk *prev_chunk; | ||
1858 | struct ib_umem_chunk *chunk; | ||
1859 | u64 pgaddr, prev_pgaddr; | ||
1860 | u32 i = 0; | ||
1861 | u32 j = 0; | ||
1862 | int kpages_per_hwpage = pginfo->hwpage_size / PAGE_SIZE; | ||
1863 | int nr_kpages = kpages_per_hwpage; | ||
1864 | |||
1865 | /* loop over desired chunk entries */ | ||
1866 | chunk = pginfo->u.usr.next_chunk; | ||
1867 | prev_chunk = pginfo->u.usr.next_chunk; | ||
1868 | list_for_each_entry_continue( | ||
1869 | chunk, (&(pginfo->u.usr.region->chunk_list)), list) { | ||
1870 | for (i = pginfo->u.usr.next_nmap; i < chunk->nmap; ) { | ||
1871 | if (nr_kpages == kpages_per_hwpage) { | ||
1872 | pgaddr = ( page_to_pfn(chunk->page_list[i].page) | ||
1873 | << PAGE_SHIFT ); | ||
1874 | *kpage = phys_to_abs(pgaddr); | ||
1875 | if ( !(*kpage) ) { | ||
1876 | ehca_gen_err("pgaddr=%lx i=%x", | ||
1877 | pgaddr, i); | ||
1878 | ret = -EFAULT; | ||
1879 | return ret; | ||
1880 | } | ||
1881 | /* | ||
1882 | * The first page in a hwpage must be aligned; | ||
1883 | * the first MR page is exempt from this rule. | ||
1884 | */ | ||
1885 | if (pgaddr & (pginfo->hwpage_size - 1)) { | ||
1886 | if (pginfo->hwpage_cnt) { | ||
1887 | ehca_gen_err( | ||
1888 | "invalid alignment " | ||
1889 | "pgaddr=%lx i=%x " | ||
1890 | "mr_pgsize=%lx", | ||
1891 | pgaddr, i, | ||
1892 | pginfo->hwpage_size); | ||
1893 | ret = -EFAULT; | ||
1894 | return ret; | ||
1895 | } | ||
1896 | /* first MR page */ | ||
1897 | pginfo->kpage_cnt = | ||
1898 | (pgaddr & | ||
1899 | (pginfo->hwpage_size - 1)) >> | ||
1900 | PAGE_SHIFT; | ||
1901 | nr_kpages -= pginfo->kpage_cnt; | ||
1902 | *kpage = phys_to_abs( | ||
1903 | pgaddr & | ||
1904 | ~(pginfo->hwpage_size - 1)); | ||
1905 | } | ||
1906 | ehca_gen_dbg("kpage=%lx chunk_page=%lx " | ||
1907 | "value=%016lx", *kpage, pgaddr, | ||
1908 | *(u64 *)abs_to_virt( | ||
1909 | phys_to_abs(pgaddr))); | ||
1910 | prev_pgaddr = pgaddr; | ||
1911 | i++; | ||
1912 | pginfo->kpage_cnt++; | ||
1913 | pginfo->u.usr.next_nmap++; | ||
1914 | nr_kpages--; | ||
1915 | if (!nr_kpages) | ||
1916 | goto next_kpage; | ||
1917 | continue; | ||
1918 | } | ||
1919 | if (i + nr_kpages > chunk->nmap) { | ||
1920 | ret = ehca_check_kpages_per_ate( | ||
1921 | chunk->page_list, i, | ||
1922 | chunk->nmap - 1, &prev_pgaddr); | ||
1923 | if (ret) return ret; | ||
1924 | pginfo->kpage_cnt += chunk->nmap - i; | ||
1925 | pginfo->u.usr.next_nmap += chunk->nmap - i; | ||
1926 | nr_kpages -= chunk->nmap - i; | ||
1927 | break; | ||
1928 | } | ||
1929 | |||
1930 | ret = ehca_check_kpages_per_ate(chunk->page_list, i, | ||
1931 | i + nr_kpages - 1, | ||
1932 | &prev_pgaddr); | ||
1933 | if (ret) return ret; | ||
1934 | i += nr_kpages; | ||
1935 | pginfo->kpage_cnt += nr_kpages; | ||
1936 | pginfo->u.usr.next_nmap += nr_kpages; | ||
1937 | next_kpage: | ||
1938 | nr_kpages = kpages_per_hwpage; | ||
1939 | (pginfo->hwpage_cnt)++; | ||
1940 | kpage++; | ||
1941 | j++; | ||
1942 | if (j >= number) break; | ||
1943 | } | ||
1944 | if ((pginfo->u.usr.next_nmap >= chunk->nmap) && | ||
1945 | (j >= number)) { | ||
1946 | pginfo->u.usr.next_nmap = 0; | ||
1947 | prev_chunk = chunk; | ||
1948 | break; | ||
1949 | } else if (pginfo->u.usr.next_nmap >= chunk->nmap) { | ||
1950 | pginfo->u.usr.next_nmap = 0; | ||
1951 | prev_chunk = chunk; | ||
1952 | } else if (j >= number) | ||
1953 | break; | ||
1954 | else | ||
1955 | prev_chunk = chunk; | ||
1956 | } | ||
1957 | pginfo->u.usr.next_chunk = | ||
1958 | list_prepare_entry(prev_chunk, | ||
1959 | (&(pginfo->u.usr.region->chunk_list)), | ||
1960 | list); | ||
1961 | return ret; | ||
1962 | } | ||
1963 | |||
1741 | int ehca_set_pagebuf_phys(struct ehca_mr_pginfo *pginfo, | 1964 | int ehca_set_pagebuf_phys(struct ehca_mr_pginfo *pginfo, |
1742 | u32 number, | 1965 | u32 number, |
1743 | u64 *kpage) | 1966 | u64 *kpage) |
@@ -1750,9 +1973,10 @@ int ehca_set_pagebuf_phys(struct ehca_mr_pginfo *pginfo, | |||
1750 | /* loop over desired phys_buf_array entries */ | 1973 | /* loop over desired phys_buf_array entries */ |
1751 | while (i < number) { | 1974 | while (i < number) { |
1752 | pbuf = pginfo->u.phy.phys_buf_array + pginfo->u.phy.next_buf; | 1975 | pbuf = pginfo->u.phy.phys_buf_array + pginfo->u.phy.next_buf; |
1753 | num_hw = NUM_CHUNKS((pbuf->addr % EHCA_PAGESIZE) + | 1976 | num_hw = NUM_CHUNKS((pbuf->addr % pginfo->hwpage_size) + |
1754 | pbuf->size, EHCA_PAGESIZE); | 1977 | pbuf->size, pginfo->hwpage_size); |
1755 | offs_hw = (pbuf->addr & ~PAGE_MASK) / EHCA_PAGESIZE; | 1978 | offs_hw = (pbuf->addr & ~(pginfo->hwpage_size - 1)) / |
1979 | pginfo->hwpage_size; | ||
1756 | while (pginfo->next_hwpage < offs_hw + num_hw) { | 1980 | while (pginfo->next_hwpage < offs_hw + num_hw) { |
1757 | /* sanity check */ | 1981 | /* sanity check */ |
1758 | if ((pginfo->kpage_cnt >= pginfo->num_kpages) || | 1982 | if ((pginfo->kpage_cnt >= pginfo->num_kpages) || |
@@ -1768,21 +1992,23 @@ int ehca_set_pagebuf_phys(struct ehca_mr_pginfo *pginfo, | |||
1768 | return -EFAULT; | 1992 | return -EFAULT; |
1769 | } | 1993 | } |
1770 | *kpage = phys_to_abs( | 1994 | *kpage = phys_to_abs( |
1771 | (pbuf->addr & EHCA_PAGEMASK) | 1995 | (pbuf->addr & ~(pginfo->hwpage_size - 1)) + |
1772 | + (pginfo->next_hwpage * EHCA_PAGESIZE)); | 1996 | (pginfo->next_hwpage * pginfo->hwpage_size)); |
1773 | if ( !(*kpage) && pbuf->addr ) { | 1997 | if ( !(*kpage) && pbuf->addr ) { |
1774 | ehca_gen_err("pbuf->addr=%lx " | 1998 | ehca_gen_err("pbuf->addr=%lx pbuf->size=%lx " |
1775 | "pbuf->size=%lx " | ||
1776 | "next_hwpage=%lx", pbuf->addr, | 1999 | "next_hwpage=%lx", pbuf->addr, |
1777 | pbuf->size, | 2000 | pbuf->size, pginfo->next_hwpage); |
1778 | pginfo->next_hwpage); | ||
1779 | return -EFAULT; | 2001 | return -EFAULT; |
1780 | } | 2002 | } |
1781 | (pginfo->hwpage_cnt)++; | 2003 | (pginfo->hwpage_cnt)++; |
1782 | (pginfo->next_hwpage)++; | 2004 | (pginfo->next_hwpage)++; |
1783 | if (pginfo->next_hwpage % | 2005 | if (PAGE_SIZE >= pginfo->hwpage_size) { |
1784 | (PAGE_SIZE / EHCA_PAGESIZE) == 0) | 2006 | if (pginfo->next_hwpage % |
1785 | (pginfo->kpage_cnt)++; | 2007 | (PAGE_SIZE / pginfo->hwpage_size) == 0) |
2008 | (pginfo->kpage_cnt)++; | ||
2009 | } else | ||
2010 | pginfo->kpage_cnt += pginfo->hwpage_size / | ||
2011 | PAGE_SIZE; | ||
1786 | kpage++; | 2012 | kpage++; |
1787 | i++; | 2013 | i++; |
1788 | if (i >= number) break; | 2014 | if (i >= number) break; |
@@ -1806,8 +2032,8 @@ int ehca_set_pagebuf_fmr(struct ehca_mr_pginfo *pginfo, | |||
1806 | /* loop over desired page_list entries */ | 2032 | /* loop over desired page_list entries */ |
1807 | fmrlist = pginfo->u.fmr.page_list + pginfo->u.fmr.next_listelem; | 2033 | fmrlist = pginfo->u.fmr.page_list + pginfo->u.fmr.next_listelem; |
1808 | for (i = 0; i < number; i++) { | 2034 | for (i = 0; i < number; i++) { |
1809 | *kpage = phys_to_abs((*fmrlist & EHCA_PAGEMASK) + | 2035 | *kpage = phys_to_abs((*fmrlist & ~(pginfo->hwpage_size - 1)) + |
1810 | pginfo->next_hwpage * EHCA_PAGESIZE); | 2036 | pginfo->next_hwpage * pginfo->hwpage_size); |
1811 | if ( !(*kpage) ) { | 2037 | if ( !(*kpage) ) { |
1812 | ehca_gen_err("*fmrlist=%lx fmrlist=%p " | 2038 | ehca_gen_err("*fmrlist=%lx fmrlist=%p " |
1813 | "next_listelem=%lx next_hwpage=%lx", | 2039 | "next_listelem=%lx next_hwpage=%lx", |
@@ -1817,15 +2043,38 @@ int ehca_set_pagebuf_fmr(struct ehca_mr_pginfo *pginfo, | |||
1817 | return -EFAULT; | 2043 | return -EFAULT; |
1818 | } | 2044 | } |
1819 | (pginfo->hwpage_cnt)++; | 2045 | (pginfo->hwpage_cnt)++; |
1820 | (pginfo->next_hwpage)++; | 2046 | if (pginfo->u.fmr.fmr_pgsize >= pginfo->hwpage_size) { |
1821 | kpage++; | 2047 | if (pginfo->next_hwpage % |
1822 | if (pginfo->next_hwpage % | 2048 | (pginfo->u.fmr.fmr_pgsize / |
1823 | (pginfo->u.fmr.fmr_pgsize / EHCA_PAGESIZE) == 0) { | 2049 | pginfo->hwpage_size) == 0) { |
1824 | (pginfo->kpage_cnt)++; | 2050 | (pginfo->kpage_cnt)++; |
1825 | (pginfo->u.fmr.next_listelem)++; | 2051 | (pginfo->u.fmr.next_listelem)++; |
1826 | fmrlist++; | 2052 | fmrlist++; |
1827 | pginfo->next_hwpage = 0; | 2053 | pginfo->next_hwpage = 0; |
2054 | } else | ||
2055 | (pginfo->next_hwpage)++; | ||
2056 | } else { | ||
2057 | unsigned int cnt_per_hwpage = pginfo->hwpage_size / | ||
2058 | pginfo->u.fmr.fmr_pgsize; | ||
2059 | unsigned int j; | ||
2060 | u64 prev = *kpage; | ||
2061 | /* check if adrs are contiguous */ | ||
2062 | for (j = 1; j < cnt_per_hwpage; j++) { | ||
2063 | u64 p = phys_to_abs(fmrlist[j] & | ||
2064 | ~(pginfo->hwpage_size - 1)); | ||
2065 | if (prev + pginfo->u.fmr.fmr_pgsize != p) { | ||
2066 | ehca_gen_err("uncontiguous fmr pages " | ||
2067 | "found prev=%lx p=%lx " | ||
2068 | "idx=%x", prev, p, i + j); | ||
2069 | return -EINVAL; | ||
2070 | } | ||
2071 | prev = p; | ||
2072 | } | ||
2073 | pginfo->kpage_cnt += cnt_per_hwpage; | ||
2074 | pginfo->u.fmr.next_listelem += cnt_per_hwpage; | ||
2075 | fmrlist += cnt_per_hwpage; | ||
1828 | } | 2076 | } |
2077 | kpage++; | ||
1829 | } | 2078 | } |
1830 | return ret; | 2079 | return ret; |
1831 | } | 2080 | } |
@@ -1842,7 +2091,9 @@ int ehca_set_pagebuf(struct ehca_mr_pginfo *pginfo, | |||
1842 | ret = ehca_set_pagebuf_phys(pginfo, number, kpage); | 2091 | ret = ehca_set_pagebuf_phys(pginfo, number, kpage); |
1843 | break; | 2092 | break; |
1844 | case EHCA_MR_PGI_USER: | 2093 | case EHCA_MR_PGI_USER: |
1845 | ret = ehca_set_pagebuf_user1(pginfo, number, kpage); | 2094 | ret = PAGE_SIZE >= pginfo->hwpage_size ? |
2095 | ehca_set_pagebuf_user1(pginfo, number, kpage) : | ||
2096 | ehca_set_pagebuf_user2(pginfo, number, kpage); | ||
1846 | break; | 2097 | break; |
1847 | case EHCA_MR_PGI_FMR: | 2098 | case EHCA_MR_PGI_FMR: |
1848 | ret = ehca_set_pagebuf_fmr(pginfo, number, kpage); | 2099 | ret = ehca_set_pagebuf_fmr(pginfo, number, kpage); |
@@ -1895,9 +2146,9 @@ void ehca_mrmw_map_acl(int ib_acl, | |||
1895 | /*----------------------------------------------------------------------*/ | 2146 | /*----------------------------------------------------------------------*/ |
1896 | 2147 | ||
1897 | /* sets page size in hipz access control for MR/MW. */ | 2148 | /* sets page size in hipz access control for MR/MW. */ |
1898 | void ehca_mrmw_set_pgsize_hipz_acl(u32 *hipz_acl) /*INOUT*/ | 2149 | void ehca_mrmw_set_pgsize_hipz_acl(u32 pgsize, u32 *hipz_acl) /*INOUT*/ |
1899 | { | 2150 | { |
1900 | return; /* HCA supports only 4k */ | 2151 | *hipz_acl |= (ehca_encode_hwpage_size(pgsize) << 24); |
1901 | } /* end ehca_mrmw_set_pgsize_hipz_acl() */ | 2152 | } /* end ehca_mrmw_set_pgsize_hipz_acl() */ |
1902 | 2153 | ||
1903 | /*----------------------------------------------------------------------*/ | 2154 | /*----------------------------------------------------------------------*/ |
diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.h b/drivers/infiniband/hw/ehca/ehca_mrmw.h index 24f13fe3708b..bc8f4e31c123 100644 --- a/drivers/infiniband/hw/ehca/ehca_mrmw.h +++ b/drivers/infiniband/hw/ehca/ehca_mrmw.h | |||
@@ -111,7 +111,7 @@ int ehca_mr_is_maxmr(u64 size, | |||
111 | void ehca_mrmw_map_acl(int ib_acl, | 111 | void ehca_mrmw_map_acl(int ib_acl, |
112 | u32 *hipz_acl); | 112 | u32 *hipz_acl); |
113 | 113 | ||
114 | void ehca_mrmw_set_pgsize_hipz_acl(u32 *hipz_acl); | 114 | void ehca_mrmw_set_pgsize_hipz_acl(u32 pgsize, u32 *hipz_acl); |
115 | 115 | ||
116 | void ehca_mrmw_reverse_map_acl(const u32 *hipz_acl, | 116 | void ehca_mrmw_reverse_map_acl(const u32 *hipz_acl, |
117 | int *ib_acl); | 117 | int *ib_acl); |
diff --git a/drivers/infiniband/hw/ehca/ehca_pd.c b/drivers/infiniband/hw/ehca/ehca_pd.c index c85312ad292b..3dafd7ff36cd 100644 --- a/drivers/infiniband/hw/ehca/ehca_pd.c +++ b/drivers/infiniband/hw/ehca/ehca_pd.c | |||
@@ -49,6 +49,7 @@ struct ib_pd *ehca_alloc_pd(struct ib_device *device, | |||
49 | struct ib_ucontext *context, struct ib_udata *udata) | 49 | struct ib_ucontext *context, struct ib_udata *udata) |
50 | { | 50 | { |
51 | struct ehca_pd *pd; | 51 | struct ehca_pd *pd; |
52 | int i; | ||
52 | 53 | ||
53 | pd = kmem_cache_zalloc(pd_cache, GFP_KERNEL); | 54 | pd = kmem_cache_zalloc(pd_cache, GFP_KERNEL); |
54 | if (!pd) { | 55 | if (!pd) { |
@@ -58,6 +59,11 @@ struct ib_pd *ehca_alloc_pd(struct ib_device *device, | |||
58 | } | 59 | } |
59 | 60 | ||
60 | pd->ownpid = current->tgid; | 61 | pd->ownpid = current->tgid; |
62 | for (i = 0; i < 2; i++) { | ||
63 | INIT_LIST_HEAD(&pd->free[i]); | ||
64 | INIT_LIST_HEAD(&pd->full[i]); | ||
65 | } | ||
66 | mutex_init(&pd->lock); | ||
61 | 67 | ||
62 | /* | 68 | /* |
63 | * Kernel PD: when device = -1, 0 | 69 | * Kernel PD: when device = -1, 0 |
@@ -81,6 +87,9 @@ int ehca_dealloc_pd(struct ib_pd *pd) | |||
81 | { | 87 | { |
82 | u32 cur_pid = current->tgid; | 88 | u32 cur_pid = current->tgid; |
83 | struct ehca_pd *my_pd = container_of(pd, struct ehca_pd, ib_pd); | 89 | struct ehca_pd *my_pd = container_of(pd, struct ehca_pd, ib_pd); |
90 | int i, leftovers = 0; | ||
91 | extern struct kmem_cache *small_qp_cache; | ||
92 | struct ipz_small_queue_page *page, *tmp; | ||
84 | 93 | ||
85 | if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context && | 94 | if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context && |
86 | my_pd->ownpid != cur_pid) { | 95 | my_pd->ownpid != cur_pid) { |
@@ -89,8 +98,20 @@ int ehca_dealloc_pd(struct ib_pd *pd) | |||
89 | return -EINVAL; | 98 | return -EINVAL; |
90 | } | 99 | } |
91 | 100 | ||
92 | kmem_cache_free(pd_cache, | 101 | for (i = 0; i < 2; i++) { |
93 | container_of(pd, struct ehca_pd, ib_pd)); | 102 | list_splice(&my_pd->full[i], &my_pd->free[i]); |
103 | list_for_each_entry_safe(page, tmp, &my_pd->free[i], list) { | ||
104 | leftovers = 1; | ||
105 | free_page(page->page); | ||
106 | kmem_cache_free(small_qp_cache, page); | ||
107 | } | ||
108 | } | ||
109 | |||
110 | if (leftovers) | ||
111 | ehca_warn(pd->device, | ||
112 | "Some small queue pages were not freed"); | ||
113 | |||
114 | kmem_cache_free(pd_cache, my_pd); | ||
94 | 115 | ||
95 | return 0; | 116 | return 0; |
96 | } | 117 | } |
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c index a3146e696c5d..b178cba96345 100644 --- a/drivers/infiniband/hw/ehca/ehca_qp.c +++ b/drivers/infiniband/hw/ehca/ehca_qp.c | |||
@@ -275,34 +275,39 @@ static inline void queue2resp(struct ipzu_queue_resp *resp, | |||
275 | resp->toggle_state = queue->toggle_state; | 275 | resp->toggle_state = queue->toggle_state; |
276 | } | 276 | } |
277 | 277 | ||
278 | static inline int ll_qp_msg_size(int nr_sge) | ||
279 | { | ||
280 | return 128 << nr_sge; | ||
281 | } | ||
282 | |||
283 | /* | 278 | /* |
284 | * init_qp_queue initializes/constructs r/squeue and registers queue pages. | 279 | * init_qp_queue initializes/constructs r/squeue and registers queue pages. |
285 | */ | 280 | */ |
286 | static inline int init_qp_queue(struct ehca_shca *shca, | 281 | static inline int init_qp_queue(struct ehca_shca *shca, |
282 | struct ehca_pd *pd, | ||
287 | struct ehca_qp *my_qp, | 283 | struct ehca_qp *my_qp, |
288 | struct ipz_queue *queue, | 284 | struct ipz_queue *queue, |
289 | int q_type, | 285 | int q_type, |
290 | u64 expected_hret, | 286 | u64 expected_hret, |
291 | int nr_q_pages, | 287 | struct ehca_alloc_queue_parms *parms, |
292 | int wqe_size, | 288 | int wqe_size) |
293 | int nr_sges) | ||
294 | { | 289 | { |
295 | int ret, cnt, ipz_rc; | 290 | int ret, cnt, ipz_rc, nr_q_pages; |
296 | void *vpage; | 291 | void *vpage; |
297 | u64 rpage, h_ret; | 292 | u64 rpage, h_ret; |
298 | struct ib_device *ib_dev = &shca->ib_device; | 293 | struct ib_device *ib_dev = &shca->ib_device; |
299 | struct ipz_adapter_handle ipz_hca_handle = shca->ipz_hca_handle; | 294 | struct ipz_adapter_handle ipz_hca_handle = shca->ipz_hca_handle; |
300 | 295 | ||
301 | if (!nr_q_pages) | 296 | if (!parms->queue_size) |
302 | return 0; | 297 | return 0; |
303 | 298 | ||
304 | ipz_rc = ipz_queue_ctor(queue, nr_q_pages, EHCA_PAGESIZE, | 299 | if (parms->is_small) { |
305 | wqe_size, nr_sges); | 300 | nr_q_pages = 1; |
301 | ipz_rc = ipz_queue_ctor(pd, queue, nr_q_pages, | ||
302 | 128 << parms->page_size, | ||
303 | wqe_size, parms->act_nr_sges, 1); | ||
304 | } else { | ||
305 | nr_q_pages = parms->queue_size; | ||
306 | ipz_rc = ipz_queue_ctor(pd, queue, nr_q_pages, | ||
307 | EHCA_PAGESIZE, wqe_size, | ||
308 | parms->act_nr_sges, 0); | ||
309 | } | ||
310 | |||
306 | if (!ipz_rc) { | 311 | if (!ipz_rc) { |
307 | ehca_err(ib_dev, "Cannot allocate page for queue. ipz_rc=%x", | 312 | ehca_err(ib_dev, "Cannot allocate page for queue. ipz_rc=%x", |
308 | ipz_rc); | 313 | ipz_rc); |
@@ -323,7 +328,7 @@ static inline int init_qp_queue(struct ehca_shca *shca, | |||
323 | h_ret = hipz_h_register_rpage_qp(ipz_hca_handle, | 328 | h_ret = hipz_h_register_rpage_qp(ipz_hca_handle, |
324 | my_qp->ipz_qp_handle, | 329 | my_qp->ipz_qp_handle, |
325 | NULL, 0, q_type, | 330 | NULL, 0, q_type, |
326 | rpage, 1, | 331 | rpage, parms->is_small ? 0 : 1, |
327 | my_qp->galpas.kernel); | 332 | my_qp->galpas.kernel); |
328 | if (cnt == (nr_q_pages - 1)) { /* last page! */ | 333 | if (cnt == (nr_q_pages - 1)) { /* last page! */ |
329 | if (h_ret != expected_hret) { | 334 | if (h_ret != expected_hret) { |
@@ -354,19 +359,55 @@ static inline int init_qp_queue(struct ehca_shca *shca, | |||
354 | return 0; | 359 | return 0; |
355 | 360 | ||
356 | init_qp_queue1: | 361 | init_qp_queue1: |
357 | ipz_queue_dtor(queue); | 362 | ipz_queue_dtor(pd, queue); |
358 | return ret; | 363 | return ret; |
359 | } | 364 | } |
360 | 365 | ||
366 | static inline int ehca_calc_wqe_size(int act_nr_sge, int is_llqp) | ||
367 | { | ||
368 | if (is_llqp) | ||
369 | return 128 << act_nr_sge; | ||
370 | else | ||
371 | return offsetof(struct ehca_wqe, | ||
372 | u.nud.sg_list[act_nr_sge]); | ||
373 | } | ||
374 | |||
375 | static void ehca_determine_small_queue(struct ehca_alloc_queue_parms *queue, | ||
376 | int req_nr_sge, int is_llqp) | ||
377 | { | ||
378 | u32 wqe_size, q_size; | ||
379 | int act_nr_sge = req_nr_sge; | ||
380 | |||
381 | if (!is_llqp) | ||
382 | /* round up #SGEs so WQE size is a power of 2 */ | ||
383 | for (act_nr_sge = 4; act_nr_sge <= 252; | ||
384 | act_nr_sge = 4 + 2 * act_nr_sge) | ||
385 | if (act_nr_sge >= req_nr_sge) | ||
386 | break; | ||
387 | |||
388 | wqe_size = ehca_calc_wqe_size(act_nr_sge, is_llqp); | ||
389 | q_size = wqe_size * (queue->max_wr + 1); | ||
390 | |||
391 | if (q_size <= 512) | ||
392 | queue->page_size = 2; | ||
393 | else if (q_size <= 1024) | ||
394 | queue->page_size = 3; | ||
395 | else | ||
396 | queue->page_size = 0; | ||
397 | |||
398 | queue->is_small = (queue->page_size != 0); | ||
399 | } | ||
400 | |||
361 | /* | 401 | /* |
362 | * Create an ib_qp struct that is either a QP or an SRQ, depending on | 402 | * Create an ib_qp struct that is either a QP or an SRQ, depending on |
363 | * the value of the is_srq parameter. If init_attr and srq_init_attr share | 403 | * the value of the is_srq parameter. If init_attr and srq_init_attr share |
364 | * fields, the field out of init_attr is used. | 404 | * fields, the field out of init_attr is used. |
365 | */ | 405 | */ |
366 | struct ehca_qp *internal_create_qp(struct ib_pd *pd, | 406 | static struct ehca_qp *internal_create_qp( |
367 | struct ib_qp_init_attr *init_attr, | 407 | struct ib_pd *pd, |
368 | struct ib_srq_init_attr *srq_init_attr, | 408 | struct ib_qp_init_attr *init_attr, |
369 | struct ib_udata *udata, int is_srq) | 409 | struct ib_srq_init_attr *srq_init_attr, |
410 | struct ib_udata *udata, int is_srq) | ||
370 | { | 411 | { |
371 | struct ehca_qp *my_qp; | 412 | struct ehca_qp *my_qp; |
372 | struct ehca_pd *my_pd = container_of(pd, struct ehca_pd, ib_pd); | 413 | struct ehca_pd *my_pd = container_of(pd, struct ehca_pd, ib_pd); |
@@ -552,10 +593,20 @@ struct ehca_qp *internal_create_qp(struct ib_pd *pd, | |||
552 | if (my_qp->recv_cq) | 593 | if (my_qp->recv_cq) |
553 | parms.recv_cq_handle = my_qp->recv_cq->ipz_cq_handle; | 594 | parms.recv_cq_handle = my_qp->recv_cq->ipz_cq_handle; |
554 | 595 | ||
555 | parms.max_send_wr = init_attr->cap.max_send_wr; | 596 | parms.squeue.max_wr = init_attr->cap.max_send_wr; |
556 | parms.max_recv_wr = init_attr->cap.max_recv_wr; | 597 | parms.rqueue.max_wr = init_attr->cap.max_recv_wr; |
557 | parms.max_send_sge = max_send_sge; | 598 | parms.squeue.max_sge = max_send_sge; |
558 | parms.max_recv_sge = max_recv_sge; | 599 | parms.rqueue.max_sge = max_recv_sge; |
600 | |||
601 | if (EHCA_BMASK_GET(HCA_CAP_MINI_QP, shca->hca_cap) | ||
602 | && !(context && udata)) { /* no small QP support in userspace ATM */ | ||
603 | ehca_determine_small_queue( | ||
604 | &parms.squeue, max_send_sge, is_llqp); | ||
605 | ehca_determine_small_queue( | ||
606 | &parms.rqueue, max_recv_sge, is_llqp); | ||
607 | parms.qp_storage = | ||
608 | (parms.squeue.is_small || parms.rqueue.is_small); | ||
609 | } | ||
559 | 610 | ||
560 | h_ret = hipz_h_alloc_resource_qp(shca->ipz_hca_handle, &parms); | 611 | h_ret = hipz_h_alloc_resource_qp(shca->ipz_hca_handle, &parms); |
561 | if (h_ret != H_SUCCESS) { | 612 | if (h_ret != H_SUCCESS) { |
@@ -569,50 +620,33 @@ struct ehca_qp *internal_create_qp(struct ib_pd *pd, | |||
569 | my_qp->ipz_qp_handle = parms.qp_handle; | 620 | my_qp->ipz_qp_handle = parms.qp_handle; |
570 | my_qp->galpas = parms.galpas; | 621 | my_qp->galpas = parms.galpas; |
571 | 622 | ||
623 | swqe_size = ehca_calc_wqe_size(parms.squeue.act_nr_sges, is_llqp); | ||
624 | rwqe_size = ehca_calc_wqe_size(parms.rqueue.act_nr_sges, is_llqp); | ||
625 | |||
572 | switch (qp_type) { | 626 | switch (qp_type) { |
573 | case IB_QPT_RC: | 627 | case IB_QPT_RC: |
574 | if (!is_llqp) { | 628 | if (is_llqp) { |
575 | swqe_size = offsetof(struct ehca_wqe, u.nud.sg_list[ | 629 | parms.squeue.act_nr_sges = 1; |
576 | (parms.act_nr_send_sges)]); | 630 | parms.rqueue.act_nr_sges = 1; |
577 | rwqe_size = offsetof(struct ehca_wqe, u.nud.sg_list[ | ||
578 | (parms.act_nr_recv_sges)]); | ||
579 | } else { /* for LLQP we need to use msg size, not wqe size */ | ||
580 | swqe_size = ll_qp_msg_size(max_send_sge); | ||
581 | rwqe_size = ll_qp_msg_size(max_recv_sge); | ||
582 | parms.act_nr_send_sges = 1; | ||
583 | parms.act_nr_recv_sges = 1; | ||
584 | } | 631 | } |
585 | break; | 632 | break; |
586 | case IB_QPT_UC: | ||
587 | swqe_size = offsetof(struct ehca_wqe, | ||
588 | u.nud.sg_list[parms.act_nr_send_sges]); | ||
589 | rwqe_size = offsetof(struct ehca_wqe, | ||
590 | u.nud.sg_list[parms.act_nr_recv_sges]); | ||
591 | break; | ||
592 | |||
593 | case IB_QPT_UD: | 633 | case IB_QPT_UD: |
594 | case IB_QPT_GSI: | 634 | case IB_QPT_GSI: |
595 | case IB_QPT_SMI: | 635 | case IB_QPT_SMI: |
636 | /* UD circumvention */ | ||
596 | if (is_llqp) { | 637 | if (is_llqp) { |
597 | swqe_size = ll_qp_msg_size(parms.act_nr_send_sges); | 638 | parms.squeue.act_nr_sges = 1; |
598 | rwqe_size = ll_qp_msg_size(parms.act_nr_recv_sges); | 639 | parms.rqueue.act_nr_sges = 1; |
599 | parms.act_nr_send_sges = 1; | ||
600 | parms.act_nr_recv_sges = 1; | ||
601 | } else { | 640 | } else { |
602 | /* UD circumvention */ | 641 | parms.squeue.act_nr_sges -= 2; |
603 | parms.act_nr_send_sges -= 2; | 642 | parms.rqueue.act_nr_sges -= 2; |
604 | parms.act_nr_recv_sges -= 2; | ||
605 | swqe_size = offsetof(struct ehca_wqe, u.ud_av.sg_list[ | ||
606 | parms.act_nr_send_sges]); | ||
607 | rwqe_size = offsetof(struct ehca_wqe, u.ud_av.sg_list[ | ||
608 | parms.act_nr_recv_sges]); | ||
609 | } | 643 | } |
610 | 644 | ||
611 | if (IB_QPT_GSI == qp_type || IB_QPT_SMI == qp_type) { | 645 | if (IB_QPT_GSI == qp_type || IB_QPT_SMI == qp_type) { |
612 | parms.act_nr_send_wqes = init_attr->cap.max_send_wr; | 646 | parms.squeue.act_nr_wqes = init_attr->cap.max_send_wr; |
613 | parms.act_nr_recv_wqes = init_attr->cap.max_recv_wr; | 647 | parms.rqueue.act_nr_wqes = init_attr->cap.max_recv_wr; |
614 | parms.act_nr_send_sges = init_attr->cap.max_send_sge; | 648 | parms.squeue.act_nr_sges = init_attr->cap.max_send_sge; |
615 | parms.act_nr_recv_sges = init_attr->cap.max_recv_sge; | 649 | parms.rqueue.act_nr_sges = init_attr->cap.max_recv_sge; |
616 | ib_qp_num = (qp_type == IB_QPT_SMI) ? 0 : 1; | 650 | ib_qp_num = (qp_type == IB_QPT_SMI) ? 0 : 1; |
617 | } | 651 | } |
618 | 652 | ||
@@ -625,10 +659,9 @@ struct ehca_qp *internal_create_qp(struct ib_pd *pd, | |||
625 | /* initialize r/squeue and register queue pages */ | 659 | /* initialize r/squeue and register queue pages */ |
626 | if (HAS_SQ(my_qp)) { | 660 | if (HAS_SQ(my_qp)) { |
627 | ret = init_qp_queue( | 661 | ret = init_qp_queue( |
628 | shca, my_qp, &my_qp->ipz_squeue, 0, | 662 | shca, my_pd, my_qp, &my_qp->ipz_squeue, 0, |
629 | HAS_RQ(my_qp) ? H_PAGE_REGISTERED : H_SUCCESS, | 663 | HAS_RQ(my_qp) ? H_PAGE_REGISTERED : H_SUCCESS, |
630 | parms.nr_sq_pages, swqe_size, | 664 | &parms.squeue, swqe_size); |
631 | parms.act_nr_send_sges); | ||
632 | if (ret) { | 665 | if (ret) { |
633 | ehca_err(pd->device, "Couldn't initialize squeue " | 666 | ehca_err(pd->device, "Couldn't initialize squeue " |
634 | "and pages ret=%x", ret); | 667 | "and pages ret=%x", ret); |
@@ -638,9 +671,8 @@ struct ehca_qp *internal_create_qp(struct ib_pd *pd, | |||
638 | 671 | ||
639 | if (HAS_RQ(my_qp)) { | 672 | if (HAS_RQ(my_qp)) { |
640 | ret = init_qp_queue( | 673 | ret = init_qp_queue( |
641 | shca, my_qp, &my_qp->ipz_rqueue, 1, | 674 | shca, my_pd, my_qp, &my_qp->ipz_rqueue, 1, |
642 | H_SUCCESS, parms.nr_rq_pages, rwqe_size, | 675 | H_SUCCESS, &parms.rqueue, rwqe_size); |
643 | parms.act_nr_recv_sges); | ||
644 | if (ret) { | 676 | if (ret) { |
645 | ehca_err(pd->device, "Couldn't initialize rqueue " | 677 | ehca_err(pd->device, "Couldn't initialize rqueue " |
646 | "and pages ret=%x", ret); | 678 | "and pages ret=%x", ret); |
@@ -670,10 +702,10 @@ struct ehca_qp *internal_create_qp(struct ib_pd *pd, | |||
670 | } | 702 | } |
671 | 703 | ||
672 | init_attr->cap.max_inline_data = 0; /* not supported yet */ | 704 | init_attr->cap.max_inline_data = 0; /* not supported yet */ |
673 | init_attr->cap.max_recv_sge = parms.act_nr_recv_sges; | 705 | init_attr->cap.max_recv_sge = parms.rqueue.act_nr_sges; |
674 | init_attr->cap.max_recv_wr = parms.act_nr_recv_wqes; | 706 | init_attr->cap.max_recv_wr = parms.rqueue.act_nr_wqes; |
675 | init_attr->cap.max_send_sge = parms.act_nr_send_sges; | 707 | init_attr->cap.max_send_sge = parms.squeue.act_nr_sges; |
676 | init_attr->cap.max_send_wr = parms.act_nr_send_wqes; | 708 | init_attr->cap.max_send_wr = parms.squeue.act_nr_wqes; |
677 | my_qp->init_attr = *init_attr; | 709 | my_qp->init_attr = *init_attr; |
678 | 710 | ||
679 | /* NOTE: define_apq0() not supported yet */ | 711 | /* NOTE: define_apq0() not supported yet */ |
@@ -707,6 +739,8 @@ struct ehca_qp *internal_create_qp(struct ib_pd *pd, | |||
707 | resp.ext_type = my_qp->ext_type; | 739 | resp.ext_type = my_qp->ext_type; |
708 | resp.qkey = my_qp->qkey; | 740 | resp.qkey = my_qp->qkey; |
709 | resp.real_qp_num = my_qp->real_qp_num; | 741 | resp.real_qp_num = my_qp->real_qp_num; |
742 | resp.ipz_rqueue.offset = my_qp->ipz_rqueue.offset; | ||
743 | resp.ipz_squeue.offset = my_qp->ipz_squeue.offset; | ||
710 | if (HAS_SQ(my_qp)) | 744 | if (HAS_SQ(my_qp)) |
711 | queue2resp(&resp.ipz_squeue, &my_qp->ipz_squeue); | 745 | queue2resp(&resp.ipz_squeue, &my_qp->ipz_squeue); |
712 | if (HAS_RQ(my_qp)) | 746 | if (HAS_RQ(my_qp)) |
@@ -723,11 +757,11 @@ struct ehca_qp *internal_create_qp(struct ib_pd *pd, | |||
723 | 757 | ||
724 | create_qp_exit4: | 758 | create_qp_exit4: |
725 | if (HAS_RQ(my_qp)) | 759 | if (HAS_RQ(my_qp)) |
726 | ipz_queue_dtor(&my_qp->ipz_rqueue); | 760 | ipz_queue_dtor(my_pd, &my_qp->ipz_rqueue); |
727 | 761 | ||
728 | create_qp_exit3: | 762 | create_qp_exit3: |
729 | if (HAS_SQ(my_qp)) | 763 | if (HAS_SQ(my_qp)) |
730 | ipz_queue_dtor(&my_qp->ipz_squeue); | 764 | ipz_queue_dtor(my_pd, &my_qp->ipz_squeue); |
731 | 765 | ||
732 | create_qp_exit2: | 766 | create_qp_exit2: |
733 | hipz_h_destroy_qp(shca->ipz_hca_handle, my_qp); | 767 | hipz_h_destroy_qp(shca->ipz_hca_handle, my_qp); |
@@ -752,8 +786,8 @@ struct ib_qp *ehca_create_qp(struct ib_pd *pd, | |||
752 | return IS_ERR(ret) ? (struct ib_qp *)ret : &ret->ib_qp; | 786 | return IS_ERR(ret) ? (struct ib_qp *)ret : &ret->ib_qp; |
753 | } | 787 | } |
754 | 788 | ||
755 | int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp, | 789 | static int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp, |
756 | struct ib_uobject *uobject); | 790 | struct ib_uobject *uobject); |
757 | 791 | ||
758 | struct ib_srq *ehca_create_srq(struct ib_pd *pd, | 792 | struct ib_srq *ehca_create_srq(struct ib_pd *pd, |
759 | struct ib_srq_init_attr *srq_init_attr, | 793 | struct ib_srq_init_attr *srq_init_attr, |
@@ -1669,8 +1703,8 @@ query_srq_exit1: | |||
1669 | return ret; | 1703 | return ret; |
1670 | } | 1704 | } |
1671 | 1705 | ||
1672 | int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp, | 1706 | static int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp, |
1673 | struct ib_uobject *uobject) | 1707 | struct ib_uobject *uobject) |
1674 | { | 1708 | { |
1675 | struct ehca_shca *shca = container_of(dev, struct ehca_shca, ib_device); | 1709 | struct ehca_shca *shca = container_of(dev, struct ehca_shca, ib_device); |
1676 | struct ehca_pd *my_pd = container_of(my_qp->ib_qp.pd, struct ehca_pd, | 1710 | struct ehca_pd *my_pd = container_of(my_qp->ib_qp.pd, struct ehca_pd, |
@@ -1734,9 +1768,9 @@ int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp, | |||
1734 | } | 1768 | } |
1735 | 1769 | ||
1736 | if (HAS_RQ(my_qp)) | 1770 | if (HAS_RQ(my_qp)) |
1737 | ipz_queue_dtor(&my_qp->ipz_rqueue); | 1771 | ipz_queue_dtor(my_pd, &my_qp->ipz_rqueue); |
1738 | if (HAS_SQ(my_qp)) | 1772 | if (HAS_SQ(my_qp)) |
1739 | ipz_queue_dtor(&my_qp->ipz_squeue); | 1773 | ipz_queue_dtor(my_pd, &my_qp->ipz_squeue); |
1740 | kmem_cache_free(qp_cache, my_qp); | 1774 | kmem_cache_free(qp_cache, my_qp); |
1741 | return 0; | 1775 | return 0; |
1742 | } | 1776 | } |
diff --git a/drivers/infiniband/hw/ehca/ehca_tools.h b/drivers/infiniband/hw/ehca/ehca_tools.h index 678b81391861..57c77a715f46 100644 --- a/drivers/infiniband/hw/ehca/ehca_tools.h +++ b/drivers/infiniband/hw/ehca/ehca_tools.h | |||
@@ -154,24 +154,7 @@ extern int ehca_debug_level; | |||
154 | #define EHCA_BMASK_GET(mask, value) \ | 154 | #define EHCA_BMASK_GET(mask, value) \ |
155 | (EHCA_BMASK_MASK(mask) & (((u64)(value)) >> EHCA_BMASK_SHIFTPOS(mask))) | 155 | (EHCA_BMASK_MASK(mask) & (((u64)(value)) >> EHCA_BMASK_SHIFTPOS(mask))) |
156 | 156 | ||
157 | |||
158 | /* Converts ehca to ib return code */ | 157 | /* Converts ehca to ib return code */ |
159 | static inline int ehca2ib_return_code(u64 ehca_rc) | 158 | int ehca2ib_return_code(u64 ehca_rc); |
160 | { | ||
161 | switch (ehca_rc) { | ||
162 | case H_SUCCESS: | ||
163 | return 0; | ||
164 | case H_RESOURCE: /* Resource in use */ | ||
165 | case H_BUSY: | ||
166 | return -EBUSY; | ||
167 | case H_NOT_ENOUGH_RESOURCES: /* insufficient resources */ | ||
168 | case H_CONSTRAINED: /* resource constraint */ | ||
169 | case H_NO_MEM: | ||
170 | return -ENOMEM; | ||
171 | default: | ||
172 | return -EINVAL; | ||
173 | } | ||
174 | } | ||
175 | |||
176 | 159 | ||
177 | #endif /* EHCA_TOOLS_H */ | 160 | #endif /* EHCA_TOOLS_H */ |
diff --git a/drivers/infiniband/hw/ehca/ehca_uverbs.c b/drivers/infiniband/hw/ehca/ehca_uverbs.c index 05c415744e3b..4bc687fdf531 100644 --- a/drivers/infiniband/hw/ehca/ehca_uverbs.c +++ b/drivers/infiniband/hw/ehca/ehca_uverbs.c | |||
@@ -149,7 +149,7 @@ static int ehca_mmap_queue(struct vm_area_struct *vma, struct ipz_queue *queue, | |||
149 | ehca_gen_err("vm_insert_page() failed rc=%x", ret); | 149 | ehca_gen_err("vm_insert_page() failed rc=%x", ret); |
150 | return ret; | 150 | return ret; |
151 | } | 151 | } |
152 | start += PAGE_SIZE; | 152 | start += PAGE_SIZE; |
153 | } | 153 | } |
154 | vma->vm_private_data = mm_count; | 154 | vma->vm_private_data = mm_count; |
155 | (*mm_count)++; | 155 | (*mm_count)++; |
diff --git a/drivers/infiniband/hw/ehca/hcp_if.c b/drivers/infiniband/hw/ehca/hcp_if.c index 3394e05f4b4f..fdbfebea7d11 100644 --- a/drivers/infiniband/hw/ehca/hcp_if.c +++ b/drivers/infiniband/hw/ehca/hcp_if.c | |||
@@ -52,10 +52,13 @@ | |||
52 | #define H_ALL_RES_QP_ENHANCED_OPS EHCA_BMASK_IBM(9, 11) | 52 | #define H_ALL_RES_QP_ENHANCED_OPS EHCA_BMASK_IBM(9, 11) |
53 | #define H_ALL_RES_QP_PTE_PIN EHCA_BMASK_IBM(12, 12) | 53 | #define H_ALL_RES_QP_PTE_PIN EHCA_BMASK_IBM(12, 12) |
54 | #define H_ALL_RES_QP_SERVICE_TYPE EHCA_BMASK_IBM(13, 15) | 54 | #define H_ALL_RES_QP_SERVICE_TYPE EHCA_BMASK_IBM(13, 15) |
55 | #define H_ALL_RES_QP_STORAGE EHCA_BMASK_IBM(16, 17) | ||
55 | #define H_ALL_RES_QP_LL_RQ_CQE_POSTING EHCA_BMASK_IBM(18, 18) | 56 | #define H_ALL_RES_QP_LL_RQ_CQE_POSTING EHCA_BMASK_IBM(18, 18) |
56 | #define H_ALL_RES_QP_LL_SQ_CQE_POSTING EHCA_BMASK_IBM(19, 21) | 57 | #define H_ALL_RES_QP_LL_SQ_CQE_POSTING EHCA_BMASK_IBM(19, 21) |
57 | #define H_ALL_RES_QP_SIGNALING_TYPE EHCA_BMASK_IBM(22, 23) | 58 | #define H_ALL_RES_QP_SIGNALING_TYPE EHCA_BMASK_IBM(22, 23) |
58 | #define H_ALL_RES_QP_UD_AV_LKEY_CTRL EHCA_BMASK_IBM(31, 31) | 59 | #define H_ALL_RES_QP_UD_AV_LKEY_CTRL EHCA_BMASK_IBM(31, 31) |
60 | #define H_ALL_RES_QP_SMALL_SQ_PAGE_SIZE EHCA_BMASK_IBM(32, 35) | ||
61 | #define H_ALL_RES_QP_SMALL_RQ_PAGE_SIZE EHCA_BMASK_IBM(36, 39) | ||
59 | #define H_ALL_RES_QP_RESOURCE_TYPE EHCA_BMASK_IBM(56, 63) | 62 | #define H_ALL_RES_QP_RESOURCE_TYPE EHCA_BMASK_IBM(56, 63) |
60 | 63 | ||
61 | #define H_ALL_RES_QP_MAX_OUTST_SEND_WR EHCA_BMASK_IBM(0, 15) | 64 | #define H_ALL_RES_QP_MAX_OUTST_SEND_WR EHCA_BMASK_IBM(0, 15) |
@@ -299,6 +302,11 @@ u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle, | |||
299 | | EHCA_BMASK_SET(H_ALL_RES_QP_PTE_PIN, 0) | 302 | | EHCA_BMASK_SET(H_ALL_RES_QP_PTE_PIN, 0) |
300 | | EHCA_BMASK_SET(H_ALL_RES_QP_SERVICE_TYPE, parms->servicetype) | 303 | | EHCA_BMASK_SET(H_ALL_RES_QP_SERVICE_TYPE, parms->servicetype) |
301 | | EHCA_BMASK_SET(H_ALL_RES_QP_SIGNALING_TYPE, parms->sigtype) | 304 | | EHCA_BMASK_SET(H_ALL_RES_QP_SIGNALING_TYPE, parms->sigtype) |
305 | | EHCA_BMASK_SET(H_ALL_RES_QP_STORAGE, parms->qp_storage) | ||
306 | | EHCA_BMASK_SET(H_ALL_RES_QP_SMALL_SQ_PAGE_SIZE, | ||
307 | parms->squeue.page_size) | ||
308 | | EHCA_BMASK_SET(H_ALL_RES_QP_SMALL_RQ_PAGE_SIZE, | ||
309 | parms->rqueue.page_size) | ||
302 | | EHCA_BMASK_SET(H_ALL_RES_QP_LL_RQ_CQE_POSTING, | 310 | | EHCA_BMASK_SET(H_ALL_RES_QP_LL_RQ_CQE_POSTING, |
303 | !!(parms->ll_comp_flags & LLQP_RECV_COMP)) | 311 | !!(parms->ll_comp_flags & LLQP_RECV_COMP)) |
304 | | EHCA_BMASK_SET(H_ALL_RES_QP_LL_SQ_CQE_POSTING, | 312 | | EHCA_BMASK_SET(H_ALL_RES_QP_LL_SQ_CQE_POSTING, |
@@ -309,13 +317,13 @@ u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle, | |||
309 | 317 | ||
310 | max_r10_reg = | 318 | max_r10_reg = |
311 | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_OUTST_SEND_WR, | 319 | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_OUTST_SEND_WR, |
312 | parms->max_send_wr + 1) | 320 | parms->squeue.max_wr + 1) |
313 | | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_OUTST_RECV_WR, | 321 | | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_OUTST_RECV_WR, |
314 | parms->max_recv_wr + 1) | 322 | parms->rqueue.max_wr + 1) |
315 | | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_SEND_SGE, | 323 | | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_SEND_SGE, |
316 | parms->max_send_sge) | 324 | parms->squeue.max_sge) |
317 | | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_RECV_SGE, | 325 | | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_RECV_SGE, |
318 | parms->max_recv_sge); | 326 | parms->rqueue.max_sge); |
319 | 327 | ||
320 | r11 = EHCA_BMASK_SET(H_ALL_RES_QP_SRQ_QP_TOKEN, parms->srq_token); | 328 | r11 = EHCA_BMASK_SET(H_ALL_RES_QP_SRQ_QP_TOKEN, parms->srq_token); |
321 | 329 | ||
@@ -335,17 +343,17 @@ u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle, | |||
335 | 343 | ||
336 | parms->qp_handle.handle = outs[0]; | 344 | parms->qp_handle.handle = outs[0]; |
337 | parms->real_qp_num = (u32)outs[1]; | 345 | parms->real_qp_num = (u32)outs[1]; |
338 | parms->act_nr_send_wqes = | 346 | parms->squeue.act_nr_wqes = |
339 | (u16)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_SEND_WR, outs[2]); | 347 | (u16)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_SEND_WR, outs[2]); |
340 | parms->act_nr_recv_wqes = | 348 | parms->rqueue.act_nr_wqes = |
341 | (u16)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_RECV_WR, outs[2]); | 349 | (u16)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_RECV_WR, outs[2]); |
342 | parms->act_nr_send_sges = | 350 | parms->squeue.act_nr_sges = |
343 | (u8)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_SEND_SGE, outs[3]); | 351 | (u8)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_SEND_SGE, outs[3]); |
344 | parms->act_nr_recv_sges = | 352 | parms->rqueue.act_nr_sges = |
345 | (u8)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_RECV_SGE, outs[3]); | 353 | (u8)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_RECV_SGE, outs[3]); |
346 | parms->nr_sq_pages = | 354 | parms->squeue.queue_size = |
347 | (u32)EHCA_BMASK_GET(H_ALL_RES_QP_SQUEUE_SIZE_PAGES, outs[4]); | 355 | (u32)EHCA_BMASK_GET(H_ALL_RES_QP_SQUEUE_SIZE_PAGES, outs[4]); |
348 | parms->nr_rq_pages = | 356 | parms->rqueue.queue_size = |
349 | (u32)EHCA_BMASK_GET(H_ALL_RES_QP_RQUEUE_SIZE_PAGES, outs[4]); | 357 | (u32)EHCA_BMASK_GET(H_ALL_RES_QP_RQUEUE_SIZE_PAGES, outs[4]); |
350 | 358 | ||
351 | if (ret == H_SUCCESS) | 359 | if (ret == H_SUCCESS) |
@@ -427,7 +435,8 @@ u64 hipz_h_register_rpage(const struct ipz_adapter_handle adapter_handle, | |||
427 | { | 435 | { |
428 | return ehca_plpar_hcall_norets(H_REGISTER_RPAGES, | 436 | return ehca_plpar_hcall_norets(H_REGISTER_RPAGES, |
429 | adapter_handle.handle, /* r4 */ | 437 | adapter_handle.handle, /* r4 */ |
430 | queue_type | pagesize << 8, /* r5 */ | 438 | (u64)queue_type | ((u64)pagesize) << 8, |
439 | /* r5 */ | ||
431 | resource_handle, /* r6 */ | 440 | resource_handle, /* r6 */ |
432 | logical_address_of_page, /* r7 */ | 441 | logical_address_of_page, /* r7 */ |
433 | count, /* r8 */ | 442 | count, /* r8 */ |
@@ -496,7 +505,7 @@ u64 hipz_h_register_rpage_qp(const struct ipz_adapter_handle adapter_handle, | |||
496 | const u64 count, | 505 | const u64 count, |
497 | const struct h_galpa galpa) | 506 | const struct h_galpa galpa) |
498 | { | 507 | { |
499 | if (count != 1) { | 508 | if (count > 1) { |
500 | ehca_gen_err("Page counter=%lx", count); | 509 | ehca_gen_err("Page counter=%lx", count); |
501 | return H_PARAMETER; | 510 | return H_PARAMETER; |
502 | } | 511 | } |
@@ -724,6 +733,9 @@ u64 hipz_h_alloc_resource_mr(const struct ipz_adapter_handle adapter_handle, | |||
724 | u64 ret; | 733 | u64 ret; |
725 | u64 outs[PLPAR_HCALL9_BUFSIZE]; | 734 | u64 outs[PLPAR_HCALL9_BUFSIZE]; |
726 | 735 | ||
736 | ehca_gen_dbg("kernel PAGE_SIZE=%x access_ctrl=%016x " | ||
737 | "vaddr=%lx length=%lx", | ||
738 | (u32)PAGE_SIZE, access_ctrl, vaddr, length); | ||
727 | ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs, | 739 | ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs, |
728 | adapter_handle.handle, /* r4 */ | 740 | adapter_handle.handle, /* r4 */ |
729 | 5, /* r5 */ | 741 | 5, /* r5 */ |
@@ -746,8 +758,22 @@ u64 hipz_h_register_rpage_mr(const struct ipz_adapter_handle adapter_handle, | |||
746 | const u64 logical_address_of_page, | 758 | const u64 logical_address_of_page, |
747 | const u64 count) | 759 | const u64 count) |
748 | { | 760 | { |
761 | extern int ehca_debug_level; | ||
749 | u64 ret; | 762 | u64 ret; |
750 | 763 | ||
764 | if (unlikely(ehca_debug_level >= 2)) { | ||
765 | if (count > 1) { | ||
766 | u64 *kpage; | ||
767 | int i; | ||
768 | kpage = (u64 *)abs_to_virt(logical_address_of_page); | ||
769 | for (i = 0; i < count; i++) | ||
770 | ehca_gen_dbg("kpage[%d]=%p", | ||
771 | i, (void *)kpage[i]); | ||
772 | } else | ||
773 | ehca_gen_dbg("kpage=%p", | ||
774 | (void *)logical_address_of_page); | ||
775 | } | ||
776 | |||
751 | if ((count > 1) && (logical_address_of_page & (EHCA_PAGESIZE-1))) { | 777 | if ((count > 1) && (logical_address_of_page & (EHCA_PAGESIZE-1))) { |
752 | ehca_gen_err("logical_address_of_page not on a 4k boundary " | 778 | ehca_gen_err("logical_address_of_page not on a 4k boundary " |
753 | "adapter_handle=%lx mr=%p mr_handle=%lx " | 779 | "adapter_handle=%lx mr=%p mr_handle=%lx " |
diff --git a/drivers/infiniband/hw/ehca/ipz_pt_fn.c b/drivers/infiniband/hw/ehca/ipz_pt_fn.c index 9606f13ed092..a090c679c397 100644 --- a/drivers/infiniband/hw/ehca/ipz_pt_fn.c +++ b/drivers/infiniband/hw/ehca/ipz_pt_fn.c | |||
@@ -40,6 +40,11 @@ | |||
40 | 40 | ||
41 | #include "ehca_tools.h" | 41 | #include "ehca_tools.h" |
42 | #include "ipz_pt_fn.h" | 42 | #include "ipz_pt_fn.h" |
43 | #include "ehca_classes.h" | ||
44 | |||
45 | #define PAGES_PER_KPAGE (PAGE_SIZE >> EHCA_PAGESHIFT) | ||
46 | |||
47 | struct kmem_cache *small_qp_cache; | ||
43 | 48 | ||
44 | void *ipz_qpageit_get_inc(struct ipz_queue *queue) | 49 | void *ipz_qpageit_get_inc(struct ipz_queue *queue) |
45 | { | 50 | { |
@@ -49,7 +54,7 @@ void *ipz_qpageit_get_inc(struct ipz_queue *queue) | |||
49 | queue->current_q_offset -= queue->pagesize; | 54 | queue->current_q_offset -= queue->pagesize; |
50 | ret = NULL; | 55 | ret = NULL; |
51 | } | 56 | } |
52 | if (((u64)ret) % EHCA_PAGESIZE) { | 57 | if (((u64)ret) % queue->pagesize) { |
53 | ehca_gen_err("ERROR!! not at PAGE-Boundary"); | 58 | ehca_gen_err("ERROR!! not at PAGE-Boundary"); |
54 | return NULL; | 59 | return NULL; |
55 | } | 60 | } |
@@ -83,80 +88,195 @@ int ipz_queue_abs_to_offset(struct ipz_queue *queue, u64 addr, u64 *q_offset) | |||
83 | return -EINVAL; | 88 | return -EINVAL; |
84 | } | 89 | } |
85 | 90 | ||
86 | int ipz_queue_ctor(struct ipz_queue *queue, | 91 | #if PAGE_SHIFT < EHCA_PAGESHIFT |
87 | const u32 nr_of_pages, | 92 | #error Kernel pages must be at least as large than eHCA pages (4K) ! |
88 | const u32 pagesize, const u32 qe_size, const u32 nr_of_sg) | 93 | #endif |
94 | |||
95 | /* | ||
96 | * allocate pages for queue: | ||
97 | * outer loop allocates whole kernel pages (page aligned) and | ||
98 | * inner loop divides a kernel page into smaller hca queue pages | ||
99 | */ | ||
100 | static int alloc_queue_pages(struct ipz_queue *queue, const u32 nr_of_pages) | ||
89 | { | 101 | { |
90 | int pages_per_kpage = PAGE_SIZE >> EHCA_PAGESHIFT; | 102 | int k, f = 0; |
91 | int f; | 103 | u8 *kpage; |
92 | 104 | ||
93 | if (pagesize > PAGE_SIZE) { | ||
94 | ehca_gen_err("FATAL ERROR: pagesize=%x is greater " | ||
95 | "than kernel page size", pagesize); | ||
96 | return 0; | ||
97 | } | ||
98 | if (!pages_per_kpage) { | ||
99 | ehca_gen_err("FATAL ERROR: invalid kernel page size. " | ||
100 | "pages_per_kpage=%x", pages_per_kpage); | ||
101 | return 0; | ||
102 | } | ||
103 | queue->queue_length = nr_of_pages * pagesize; | ||
104 | queue->queue_pages = vmalloc(nr_of_pages * sizeof(void *)); | ||
105 | if (!queue->queue_pages) { | ||
106 | ehca_gen_err("ERROR!! didn't get the memory"); | ||
107 | return 0; | ||
108 | } | ||
109 | memset(queue->queue_pages, 0, nr_of_pages * sizeof(void *)); | ||
110 | /* | ||
111 | * allocate pages for queue: | ||
112 | * outer loop allocates whole kernel pages (page aligned) and | ||
113 | * inner loop divides a kernel page into smaller hca queue pages | ||
114 | */ | ||
115 | f = 0; | ||
116 | while (f < nr_of_pages) { | 105 | while (f < nr_of_pages) { |
117 | u8 *kpage = (u8 *)get_zeroed_page(GFP_KERNEL); | 106 | kpage = (u8 *)get_zeroed_page(GFP_KERNEL); |
118 | int k; | ||
119 | if (!kpage) | 107 | if (!kpage) |
120 | goto ipz_queue_ctor_exit0; /*NOMEM*/ | 108 | goto out; |
121 | for (k = 0; k < pages_per_kpage && f < nr_of_pages; k++) { | 109 | |
122 | (queue->queue_pages)[f] = (struct ipz_page *)kpage; | 110 | for (k = 0; k < PAGES_PER_KPAGE && f < nr_of_pages; k++) { |
111 | queue->queue_pages[f] = (struct ipz_page *)kpage; | ||
123 | kpage += EHCA_PAGESIZE; | 112 | kpage += EHCA_PAGESIZE; |
124 | f++; | 113 | f++; |
125 | } | 114 | } |
126 | } | 115 | } |
116 | return 1; | ||
127 | 117 | ||
128 | queue->current_q_offset = 0; | 118 | out: |
119 | for (f = 0; f < nr_of_pages && queue->queue_pages[f]; | ||
120 | f += PAGES_PER_KPAGE) | ||
121 | free_page((unsigned long)(queue->queue_pages)[f]); | ||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | static int alloc_small_queue_page(struct ipz_queue *queue, struct ehca_pd *pd) | ||
126 | { | ||
127 | int order = ilog2(queue->pagesize) - 9; | ||
128 | struct ipz_small_queue_page *page; | ||
129 | unsigned long bit; | ||
130 | |||
131 | mutex_lock(&pd->lock); | ||
132 | |||
133 | if (!list_empty(&pd->free[order])) | ||
134 | page = list_entry(pd->free[order].next, | ||
135 | struct ipz_small_queue_page, list); | ||
136 | else { | ||
137 | page = kmem_cache_zalloc(small_qp_cache, GFP_KERNEL); | ||
138 | if (!page) | ||
139 | goto out; | ||
140 | |||
141 | page->page = get_zeroed_page(GFP_KERNEL); | ||
142 | if (!page->page) { | ||
143 | kmem_cache_free(small_qp_cache, page); | ||
144 | goto out; | ||
145 | } | ||
146 | |||
147 | list_add(&page->list, &pd->free[order]); | ||
148 | } | ||
149 | |||
150 | bit = find_first_zero_bit(page->bitmap, IPZ_SPAGE_PER_KPAGE >> order); | ||
151 | __set_bit(bit, page->bitmap); | ||
152 | page->fill++; | ||
153 | |||
154 | if (page->fill == IPZ_SPAGE_PER_KPAGE >> order) | ||
155 | list_move(&page->list, &pd->full[order]); | ||
156 | |||
157 | mutex_unlock(&pd->lock); | ||
158 | |||
159 | queue->queue_pages[0] = (void *)(page->page | (bit << (order + 9))); | ||
160 | queue->small_page = page; | ||
161 | return 1; | ||
162 | |||
163 | out: | ||
164 | ehca_err(pd->ib_pd.device, "failed to allocate small queue page"); | ||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | static void free_small_queue_page(struct ipz_queue *queue, struct ehca_pd *pd) | ||
169 | { | ||
170 | int order = ilog2(queue->pagesize) - 9; | ||
171 | struct ipz_small_queue_page *page = queue->small_page; | ||
172 | unsigned long bit; | ||
173 | int free_page = 0; | ||
174 | |||
175 | bit = ((unsigned long)queue->queue_pages[0] & PAGE_MASK) | ||
176 | >> (order + 9); | ||
177 | |||
178 | mutex_lock(&pd->lock); | ||
179 | |||
180 | __clear_bit(bit, page->bitmap); | ||
181 | page->fill--; | ||
182 | |||
183 | if (page->fill == 0) { | ||
184 | list_del(&page->list); | ||
185 | free_page = 1; | ||
186 | } | ||
187 | |||
188 | if (page->fill == (IPZ_SPAGE_PER_KPAGE >> order) - 1) | ||
189 | /* the page was full until we freed the chunk */ | ||
190 | list_move_tail(&page->list, &pd->free[order]); | ||
191 | |||
192 | mutex_unlock(&pd->lock); | ||
193 | |||
194 | if (free_page) { | ||
195 | free_page(page->page); | ||
196 | kmem_cache_free(small_qp_cache, page); | ||
197 | } | ||
198 | } | ||
199 | |||
200 | int ipz_queue_ctor(struct ehca_pd *pd, struct ipz_queue *queue, | ||
201 | const u32 nr_of_pages, const u32 pagesize, | ||
202 | const u32 qe_size, const u32 nr_of_sg, | ||
203 | int is_small) | ||
204 | { | ||
205 | if (pagesize > PAGE_SIZE) { | ||
206 | ehca_gen_err("FATAL ERROR: pagesize=%x " | ||
207 | "is greater than kernel page size", pagesize); | ||
208 | return 0; | ||
209 | } | ||
210 | |||
211 | /* init queue fields */ | ||
212 | queue->queue_length = nr_of_pages * pagesize; | ||
213 | queue->pagesize = pagesize; | ||
129 | queue->qe_size = qe_size; | 214 | queue->qe_size = qe_size; |
130 | queue->act_nr_of_sg = nr_of_sg; | 215 | queue->act_nr_of_sg = nr_of_sg; |
131 | queue->pagesize = pagesize; | 216 | queue->current_q_offset = 0; |
132 | queue->toggle_state = 1; | 217 | queue->toggle_state = 1; |
133 | return 1; | 218 | queue->small_page = NULL; |
134 | 219 | ||
135 | ipz_queue_ctor_exit0: | 220 | /* allocate queue page pointers */ |
136 | ehca_gen_err("Couldn't get alloc pages queue=%p f=%x nr_of_pages=%x", | 221 | queue->queue_pages = vmalloc(nr_of_pages * sizeof(void *)); |
137 | queue, f, nr_of_pages); | 222 | if (!queue->queue_pages) { |
138 | for (f = 0; f < nr_of_pages; f += pages_per_kpage) { | 223 | ehca_gen_err("Couldn't allocate queue page list"); |
139 | if (!(queue->queue_pages)[f]) | 224 | return 0; |
140 | break; | ||
141 | free_page((unsigned long)(queue->queue_pages)[f]); | ||
142 | } | 225 | } |
226 | memset(queue->queue_pages, 0, nr_of_pages * sizeof(void *)); | ||
227 | |||
228 | /* allocate actual queue pages */ | ||
229 | if (is_small) { | ||
230 | if (!alloc_small_queue_page(queue, pd)) | ||
231 | goto ipz_queue_ctor_exit0; | ||
232 | } else | ||
233 | if (!alloc_queue_pages(queue, nr_of_pages)) | ||
234 | goto ipz_queue_ctor_exit0; | ||
235 | |||
236 | return 1; | ||
237 | |||
238 | ipz_queue_ctor_exit0: | ||
239 | ehca_gen_err("Couldn't alloc pages queue=%p " | ||
240 | "nr_of_pages=%x", queue, nr_of_pages); | ||
241 | vfree(queue->queue_pages); | ||
242 | |||
143 | return 0; | 243 | return 0; |
144 | } | 244 | } |
145 | 245 | ||
146 | int ipz_queue_dtor(struct ipz_queue *queue) | 246 | int ipz_queue_dtor(struct ehca_pd *pd, struct ipz_queue *queue) |
147 | { | 247 | { |
148 | int pages_per_kpage = PAGE_SIZE >> EHCA_PAGESHIFT; | 248 | int i, nr_pages; |
149 | int g; | ||
150 | int nr_pages; | ||
151 | 249 | ||
152 | if (!queue || !queue->queue_pages) { | 250 | if (!queue || !queue->queue_pages) { |
153 | ehca_gen_dbg("queue or queue_pages is NULL"); | 251 | ehca_gen_dbg("queue or queue_pages is NULL"); |
154 | return 0; | 252 | return 0; |
155 | } | 253 | } |
156 | nr_pages = queue->queue_length / queue->pagesize; | 254 | |
157 | for (g = 0; g < nr_pages; g += pages_per_kpage) | 255 | if (queue->small_page) |
158 | free_page((unsigned long)(queue->queue_pages)[g]); | 256 | free_small_queue_page(queue, pd); |
257 | else { | ||
258 | nr_pages = queue->queue_length / queue->pagesize; | ||
259 | for (i = 0; i < nr_pages; i += PAGES_PER_KPAGE) | ||
260 | free_page((unsigned long)queue->queue_pages[i]); | ||
261 | } | ||
262 | |||
159 | vfree(queue->queue_pages); | 263 | vfree(queue->queue_pages); |
160 | 264 | ||
161 | return 1; | 265 | return 1; |
162 | } | 266 | } |
267 | |||
268 | int ehca_init_small_qp_cache(void) | ||
269 | { | ||
270 | small_qp_cache = kmem_cache_create("ehca_cache_small_qp", | ||
271 | sizeof(struct ipz_small_queue_page), | ||
272 | 0, SLAB_HWCACHE_ALIGN, NULL); | ||
273 | if (!small_qp_cache) | ||
274 | return -ENOMEM; | ||
275 | |||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | void ehca_cleanup_small_qp_cache(void) | ||
280 | { | ||
281 | kmem_cache_destroy(small_qp_cache); | ||
282 | } | ||
diff --git a/drivers/infiniband/hw/ehca/ipz_pt_fn.h b/drivers/infiniband/hw/ehca/ipz_pt_fn.h index 39a4f64aff41..c6937a044e8a 100644 --- a/drivers/infiniband/hw/ehca/ipz_pt_fn.h +++ b/drivers/infiniband/hw/ehca/ipz_pt_fn.h | |||
@@ -51,11 +51,25 @@ | |||
51 | #include "ehca_tools.h" | 51 | #include "ehca_tools.h" |
52 | #include "ehca_qes.h" | 52 | #include "ehca_qes.h" |
53 | 53 | ||
54 | struct ehca_pd; | ||
55 | struct ipz_small_queue_page; | ||
56 | |||
54 | /* struct generic ehca page */ | 57 | /* struct generic ehca page */ |
55 | struct ipz_page { | 58 | struct ipz_page { |
56 | u8 entries[EHCA_PAGESIZE]; | 59 | u8 entries[EHCA_PAGESIZE]; |
57 | }; | 60 | }; |
58 | 61 | ||
62 | #define IPZ_SPAGE_PER_KPAGE (PAGE_SIZE / 512) | ||
63 | |||
64 | struct ipz_small_queue_page { | ||
65 | unsigned long page; | ||
66 | unsigned long bitmap[IPZ_SPAGE_PER_KPAGE / BITS_PER_LONG]; | ||
67 | int fill; | ||
68 | void *mapped_addr; | ||
69 | u32 mmap_count; | ||
70 | struct list_head list; | ||
71 | }; | ||
72 | |||
59 | /* struct generic queue in linux kernel virtual memory (kv) */ | 73 | /* struct generic queue in linux kernel virtual memory (kv) */ |
60 | struct ipz_queue { | 74 | struct ipz_queue { |
61 | u64 current_q_offset; /* current queue entry */ | 75 | u64 current_q_offset; /* current queue entry */ |
@@ -66,7 +80,8 @@ struct ipz_queue { | |||
66 | u32 queue_length; /* queue length allocated in bytes */ | 80 | u32 queue_length; /* queue length allocated in bytes */ |
67 | u32 pagesize; | 81 | u32 pagesize; |
68 | u32 toggle_state; /* toggle flag - per page */ | 82 | u32 toggle_state; /* toggle flag - per page */ |
69 | u32 dummy3; /* 64 bit alignment */ | 83 | u32 offset; /* save offset within page for small_qp */ |
84 | struct ipz_small_queue_page *small_page; | ||
70 | }; | 85 | }; |
71 | 86 | ||
72 | /* | 87 | /* |
@@ -188,9 +203,10 @@ struct ipz_qpt { | |||
188 | * see ipz_qpt_ctor() | 203 | * see ipz_qpt_ctor() |
189 | * returns true if ok, false if out of memory | 204 | * returns true if ok, false if out of memory |
190 | */ | 205 | */ |
191 | int ipz_queue_ctor(struct ipz_queue *queue, const u32 nr_of_pages, | 206 | int ipz_queue_ctor(struct ehca_pd *pd, struct ipz_queue *queue, |
192 | const u32 pagesize, const u32 qe_size, | 207 | const u32 nr_of_pages, const u32 pagesize, |
193 | const u32 nr_of_sg); | 208 | const u32 qe_size, const u32 nr_of_sg, |
209 | int is_small); | ||
194 | 210 | ||
195 | /* | 211 | /* |
196 | * destructor for a ipz_queue_t | 212 | * destructor for a ipz_queue_t |
@@ -198,7 +214,7 @@ int ipz_queue_ctor(struct ipz_queue *queue, const u32 nr_of_pages, | |||
198 | * see ipz_queue_ctor() | 214 | * see ipz_queue_ctor() |
199 | * returns true if ok, false if queue was NULL-ptr of free failed | 215 | * returns true if ok, false if queue was NULL-ptr of free failed |
200 | */ | 216 | */ |
201 | int ipz_queue_dtor(struct ipz_queue *queue); | 217 | int ipz_queue_dtor(struct ehca_pd *pd, struct ipz_queue *queue); |
202 | 218 | ||
203 | /* | 219 | /* |
204 | * constructor for a ipz_qpt_t, | 220 | * constructor for a ipz_qpt_t, |
diff --git a/drivers/infiniband/hw/ipath/Makefile b/drivers/infiniband/hw/ipath/Makefile index ec2e603ea241..fe6738826865 100644 --- a/drivers/infiniband/hw/ipath/Makefile +++ b/drivers/infiniband/hw/ipath/Makefile | |||
@@ -14,7 +14,6 @@ ib_ipath-y := \ | |||
14 | ipath_init_chip.o \ | 14 | ipath_init_chip.o \ |
15 | ipath_intr.o \ | 15 | ipath_intr.o \ |
16 | ipath_keys.o \ | 16 | ipath_keys.o \ |
17 | ipath_layer.o \ | ||
18 | ipath_mad.o \ | 17 | ipath_mad.o \ |
19 | ipath_mmap.o \ | 18 | ipath_mmap.o \ |
20 | ipath_mr.o \ | 19 | ipath_mr.o \ |
diff --git a/drivers/infiniband/hw/ipath/ipath_layer.c b/drivers/infiniband/hw/ipath/ipath_layer.c deleted file mode 100644 index 82616b779e24..000000000000 --- a/drivers/infiniband/hw/ipath/ipath_layer.c +++ /dev/null | |||
@@ -1,365 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved. | ||
3 | * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. | ||
4 | * | ||
5 | * This software is available to you under a choice of one of two | ||
6 | * licenses. You may choose to be licensed under the terms of the GNU | ||
7 | * General Public License (GPL) Version 2, available from the file | ||
8 | * COPYING in the main directory of this source tree, or the | ||
9 | * OpenIB.org BSD license below: | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or | ||
12 | * without modification, are permitted provided that the following | ||
13 | * conditions are met: | ||
14 | * | ||
15 | * - Redistributions of source code must retain the above | ||
16 | * copyright notice, this list of conditions and the following | ||
17 | * disclaimer. | ||
18 | * | ||
19 | * - Redistributions in binary form must reproduce the above | ||
20 | * copyright notice, this list of conditions and the following | ||
21 | * disclaimer in the documentation and/or other materials | ||
22 | * provided with the distribution. | ||
23 | * | ||
24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
25 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
26 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
27 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
28 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
29 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
30 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
31 | * SOFTWARE. | ||
32 | */ | ||
33 | |||
34 | /* | ||
35 | * These are the routines used by layered drivers, currently just the | ||
36 | * layered ethernet driver and verbs layer. | ||
37 | */ | ||
38 | |||
39 | #include <linux/io.h> | ||
40 | #include <asm/byteorder.h> | ||
41 | |||
42 | #include "ipath_kernel.h" | ||
43 | #include "ipath_layer.h" | ||
44 | #include "ipath_verbs.h" | ||
45 | #include "ipath_common.h" | ||
46 | |||
47 | /* Acquire before ipath_devs_lock. */ | ||
48 | static DEFINE_MUTEX(ipath_layer_mutex); | ||
49 | |||
50 | u16 ipath_layer_rcv_opcode; | ||
51 | |||
52 | static int (*layer_intr)(void *, u32); | ||
53 | static int (*layer_rcv)(void *, void *, struct sk_buff *); | ||
54 | static int (*layer_rcv_lid)(void *, void *); | ||
55 | |||
56 | static void *(*layer_add_one)(int, struct ipath_devdata *); | ||
57 | static void (*layer_remove_one)(void *); | ||
58 | |||
59 | int __ipath_layer_intr(struct ipath_devdata *dd, u32 arg) | ||
60 | { | ||
61 | int ret = -ENODEV; | ||
62 | |||
63 | if (dd->ipath_layer.l_arg && layer_intr) | ||
64 | ret = layer_intr(dd->ipath_layer.l_arg, arg); | ||
65 | |||
66 | return ret; | ||
67 | } | ||
68 | |||
69 | int ipath_layer_intr(struct ipath_devdata *dd, u32 arg) | ||
70 | { | ||
71 | int ret; | ||
72 | |||
73 | mutex_lock(&ipath_layer_mutex); | ||
74 | |||
75 | ret = __ipath_layer_intr(dd, arg); | ||
76 | |||
77 | mutex_unlock(&ipath_layer_mutex); | ||
78 | |||
79 | return ret; | ||
80 | } | ||
81 | |||
82 | int __ipath_layer_rcv(struct ipath_devdata *dd, void *hdr, | ||
83 | struct sk_buff *skb) | ||
84 | { | ||
85 | int ret = -ENODEV; | ||
86 | |||
87 | if (dd->ipath_layer.l_arg && layer_rcv) | ||
88 | ret = layer_rcv(dd->ipath_layer.l_arg, hdr, skb); | ||
89 | |||
90 | return ret; | ||
91 | } | ||
92 | |||
93 | int __ipath_layer_rcv_lid(struct ipath_devdata *dd, void *hdr) | ||
94 | { | ||
95 | int ret = -ENODEV; | ||
96 | |||
97 | if (dd->ipath_layer.l_arg && layer_rcv_lid) | ||
98 | ret = layer_rcv_lid(dd->ipath_layer.l_arg, hdr); | ||
99 | |||
100 | return ret; | ||
101 | } | ||
102 | |||
103 | void ipath_layer_lid_changed(struct ipath_devdata *dd) | ||
104 | { | ||
105 | mutex_lock(&ipath_layer_mutex); | ||
106 | |||
107 | if (dd->ipath_layer.l_arg && layer_intr) | ||
108 | layer_intr(dd->ipath_layer.l_arg, IPATH_LAYER_INT_LID); | ||
109 | |||
110 | mutex_unlock(&ipath_layer_mutex); | ||
111 | } | ||
112 | |||
113 | void ipath_layer_add(struct ipath_devdata *dd) | ||
114 | { | ||
115 | mutex_lock(&ipath_layer_mutex); | ||
116 | |||
117 | if (layer_add_one) | ||
118 | dd->ipath_layer.l_arg = | ||
119 | layer_add_one(dd->ipath_unit, dd); | ||
120 | |||
121 | mutex_unlock(&ipath_layer_mutex); | ||
122 | } | ||
123 | |||
124 | void ipath_layer_remove(struct ipath_devdata *dd) | ||
125 | { | ||
126 | mutex_lock(&ipath_layer_mutex); | ||
127 | |||
128 | if (dd->ipath_layer.l_arg && layer_remove_one) { | ||
129 | layer_remove_one(dd->ipath_layer.l_arg); | ||
130 | dd->ipath_layer.l_arg = NULL; | ||
131 | } | ||
132 | |||
133 | mutex_unlock(&ipath_layer_mutex); | ||
134 | } | ||
135 | |||
136 | int ipath_layer_register(void *(*l_add)(int, struct ipath_devdata *), | ||
137 | void (*l_remove)(void *), | ||
138 | int (*l_intr)(void *, u32), | ||
139 | int (*l_rcv)(void *, void *, struct sk_buff *), | ||
140 | u16 l_rcv_opcode, | ||
141 | int (*l_rcv_lid)(void *, void *)) | ||
142 | { | ||
143 | struct ipath_devdata *dd, *tmp; | ||
144 | unsigned long flags; | ||
145 | |||
146 | mutex_lock(&ipath_layer_mutex); | ||
147 | |||
148 | layer_add_one = l_add; | ||
149 | layer_remove_one = l_remove; | ||
150 | layer_intr = l_intr; | ||
151 | layer_rcv = l_rcv; | ||
152 | layer_rcv_lid = l_rcv_lid; | ||
153 | ipath_layer_rcv_opcode = l_rcv_opcode; | ||
154 | |||
155 | spin_lock_irqsave(&ipath_devs_lock, flags); | ||
156 | |||
157 | list_for_each_entry_safe(dd, tmp, &ipath_dev_list, ipath_list) { | ||
158 | if (!(dd->ipath_flags & IPATH_INITTED)) | ||
159 | continue; | ||
160 | |||
161 | if (dd->ipath_layer.l_arg) | ||
162 | continue; | ||
163 | |||
164 | spin_unlock_irqrestore(&ipath_devs_lock, flags); | ||
165 | dd->ipath_layer.l_arg = l_add(dd->ipath_unit, dd); | ||
166 | spin_lock_irqsave(&ipath_devs_lock, flags); | ||
167 | } | ||
168 | |||
169 | spin_unlock_irqrestore(&ipath_devs_lock, flags); | ||
170 | mutex_unlock(&ipath_layer_mutex); | ||
171 | |||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | EXPORT_SYMBOL_GPL(ipath_layer_register); | ||
176 | |||
177 | void ipath_layer_unregister(void) | ||
178 | { | ||
179 | struct ipath_devdata *dd, *tmp; | ||
180 | unsigned long flags; | ||
181 | |||
182 | mutex_lock(&ipath_layer_mutex); | ||
183 | spin_lock_irqsave(&ipath_devs_lock, flags); | ||
184 | |||
185 | list_for_each_entry_safe(dd, tmp, &ipath_dev_list, ipath_list) { | ||
186 | if (dd->ipath_layer.l_arg && layer_remove_one) { | ||
187 | spin_unlock_irqrestore(&ipath_devs_lock, flags); | ||
188 | layer_remove_one(dd->ipath_layer.l_arg); | ||
189 | spin_lock_irqsave(&ipath_devs_lock, flags); | ||
190 | dd->ipath_layer.l_arg = NULL; | ||
191 | } | ||
192 | } | ||
193 | |||
194 | spin_unlock_irqrestore(&ipath_devs_lock, flags); | ||
195 | |||
196 | layer_add_one = NULL; | ||
197 | layer_remove_one = NULL; | ||
198 | layer_intr = NULL; | ||
199 | layer_rcv = NULL; | ||
200 | layer_rcv_lid = NULL; | ||
201 | |||
202 | mutex_unlock(&ipath_layer_mutex); | ||
203 | } | ||
204 | |||
205 | EXPORT_SYMBOL_GPL(ipath_layer_unregister); | ||
206 | |||
207 | int ipath_layer_open(struct ipath_devdata *dd, u32 * pktmax) | ||
208 | { | ||
209 | int ret; | ||
210 | u32 intval = 0; | ||
211 | |||
212 | mutex_lock(&ipath_layer_mutex); | ||
213 | |||
214 | if (!dd->ipath_layer.l_arg) { | ||
215 | ret = -EINVAL; | ||
216 | goto bail; | ||
217 | } | ||
218 | |||
219 | ret = ipath_setrcvhdrsize(dd, IPATH_HEADER_QUEUE_WORDS); | ||
220 | |||
221 | if (ret < 0) | ||
222 | goto bail; | ||
223 | |||
224 | *pktmax = dd->ipath_ibmaxlen; | ||
225 | |||
226 | if (*dd->ipath_statusp & IPATH_STATUS_IB_READY) | ||
227 | intval |= IPATH_LAYER_INT_IF_UP; | ||
228 | if (dd->ipath_lid) | ||
229 | intval |= IPATH_LAYER_INT_LID; | ||
230 | if (dd->ipath_mlid) | ||
231 | intval |= IPATH_LAYER_INT_BCAST; | ||
232 | /* | ||
233 | * do this on open, in case low level is already up and | ||
234 | * just layered driver was reloaded, etc. | ||
235 | */ | ||
236 | if (intval) | ||
237 | layer_intr(dd->ipath_layer.l_arg, intval); | ||
238 | |||
239 | ret = 0; | ||
240 | bail: | ||
241 | mutex_unlock(&ipath_layer_mutex); | ||
242 | |||
243 | return ret; | ||
244 | } | ||
245 | |||
246 | EXPORT_SYMBOL_GPL(ipath_layer_open); | ||
247 | |||
248 | u16 ipath_layer_get_lid(struct ipath_devdata *dd) | ||
249 | { | ||
250 | return dd->ipath_lid; | ||
251 | } | ||
252 | |||
253 | EXPORT_SYMBOL_GPL(ipath_layer_get_lid); | ||
254 | |||
255 | /** | ||
256 | * ipath_layer_get_mac - get the MAC address | ||
257 | * @dd: the infinipath device | ||
258 | * @mac: the MAC is put here | ||
259 | * | ||
260 | * This is the EUID-64 OUI octets (top 3), then | ||
261 | * skip the next 2 (which should both be zero or 0xff). | ||
262 | * The returned MAC is in network order | ||
263 | * mac points to at least 6 bytes of buffer | ||
264 | * We assume that by the time the LID is set, that the GUID is as valid | ||
265 | * as it's ever going to be, rather than adding yet another status bit. | ||
266 | */ | ||
267 | |||
268 | int ipath_layer_get_mac(struct ipath_devdata *dd, u8 * mac) | ||
269 | { | ||
270 | u8 *guid; | ||
271 | |||
272 | guid = (u8 *) &dd->ipath_guid; | ||
273 | |||
274 | mac[0] = guid[0]; | ||
275 | mac[1] = guid[1]; | ||
276 | mac[2] = guid[2]; | ||
277 | mac[3] = guid[5]; | ||
278 | mac[4] = guid[6]; | ||
279 | mac[5] = guid[7]; | ||
280 | if ((guid[3] || guid[4]) && !(guid[3] == 0xff && guid[4] == 0xff)) | ||
281 | ipath_dbg("Warning, guid bytes 3 and 4 not 0 or 0xffff: " | ||
282 | "%x %x\n", guid[3], guid[4]); | ||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | EXPORT_SYMBOL_GPL(ipath_layer_get_mac); | ||
287 | |||
288 | u16 ipath_layer_get_bcast(struct ipath_devdata *dd) | ||
289 | { | ||
290 | return dd->ipath_mlid; | ||
291 | } | ||
292 | |||
293 | EXPORT_SYMBOL_GPL(ipath_layer_get_bcast); | ||
294 | |||
295 | int ipath_layer_send_hdr(struct ipath_devdata *dd, struct ether_header *hdr) | ||
296 | { | ||
297 | int ret = 0; | ||
298 | u32 __iomem *piobuf; | ||
299 | u32 plen, *uhdr; | ||
300 | size_t count; | ||
301 | __be16 vlsllnh; | ||
302 | |||
303 | if (!(dd->ipath_flags & IPATH_RCVHDRSZ_SET)) { | ||
304 | ipath_dbg("send while not open\n"); | ||
305 | ret = -EINVAL; | ||
306 | } else | ||
307 | if ((dd->ipath_flags & (IPATH_LINKUNK | IPATH_LINKDOWN)) || | ||
308 | dd->ipath_lid == 0) { | ||
309 | /* | ||
310 | * lid check is for when sma hasn't yet configured | ||
311 | */ | ||
312 | ret = -ENETDOWN; | ||
313 | ipath_cdbg(VERBOSE, "send while not ready, " | ||
314 | "mylid=%u, flags=0x%x\n", | ||
315 | dd->ipath_lid, dd->ipath_flags); | ||
316 | } | ||
317 | |||
318 | vlsllnh = *((__be16 *) hdr); | ||
319 | if (vlsllnh != htons(IPATH_LRH_BTH)) { | ||
320 | ipath_dbg("Warning: lrh[0] wrong (%x, not %x); " | ||
321 | "not sending\n", be16_to_cpu(vlsllnh), | ||
322 | IPATH_LRH_BTH); | ||
323 | ret = -EINVAL; | ||
324 | } | ||
325 | if (ret) | ||
326 | goto done; | ||
327 | |||
328 | /* Get a PIO buffer to use. */ | ||
329 | piobuf = ipath_getpiobuf(dd, NULL); | ||
330 | if (piobuf == NULL) { | ||
331 | ret = -EBUSY; | ||
332 | goto done; | ||
333 | } | ||
334 | |||
335 | plen = (sizeof(*hdr) >> 2); /* actual length */ | ||
336 | ipath_cdbg(EPKT, "0x%x+1w pio %p\n", plen, piobuf); | ||
337 | |||
338 | writeq(plen+1, piobuf); /* len (+1 for pad) to pbc, no flags */ | ||
339 | ipath_flush_wc(); | ||
340 | piobuf += 2; | ||
341 | uhdr = (u32 *)hdr; | ||
342 | count = plen-1; /* amount we can copy before trigger word */ | ||
343 | __iowrite32_copy(piobuf, uhdr, count); | ||
344 | ipath_flush_wc(); | ||
345 | __raw_writel(uhdr[count], piobuf + count); | ||
346 | ipath_flush_wc(); /* ensure it's sent, now */ | ||
347 | |||
348 | ipath_stats.sps_ether_spkts++; /* ether packet sent */ | ||
349 | |||
350 | done: | ||
351 | return ret; | ||
352 | } | ||
353 | |||
354 | EXPORT_SYMBOL_GPL(ipath_layer_send_hdr); | ||
355 | |||
356 | int ipath_layer_set_piointbufavail_int(struct ipath_devdata *dd) | ||
357 | { | ||
358 | set_bit(IPATH_S_PIOINTBUFAVAIL, &dd->ipath_sendctrl); | ||
359 | |||
360 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | ||
361 | dd->ipath_sendctrl); | ||
362 | return 0; | ||
363 | } | ||
364 | |||
365 | EXPORT_SYMBOL_GPL(ipath_layer_set_piointbufavail_int); | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_layer.h b/drivers/infiniband/hw/ipath/ipath_layer.h deleted file mode 100644 index 415709c4d85b..000000000000 --- a/drivers/infiniband/hw/ipath/ipath_layer.h +++ /dev/null | |||
@@ -1,71 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved. | ||
3 | * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. | ||
4 | * | ||
5 | * This software is available to you under a choice of one of two | ||
6 | * licenses. You may choose to be licensed under the terms of the GNU | ||
7 | * General Public License (GPL) Version 2, available from the file | ||
8 | * COPYING in the main directory of this source tree, or the | ||
9 | * OpenIB.org BSD license below: | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or | ||
12 | * without modification, are permitted provided that the following | ||
13 | * conditions are met: | ||
14 | * | ||
15 | * - Redistributions of source code must retain the above | ||
16 | * copyright notice, this list of conditions and the following | ||
17 | * disclaimer. | ||
18 | * | ||
19 | * - Redistributions in binary form must reproduce the above | ||
20 | * copyright notice, this list of conditions and the following | ||
21 | * disclaimer in the documentation and/or other materials | ||
22 | * provided with the distribution. | ||
23 | * | ||
24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
25 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
26 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
27 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
28 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
29 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
30 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
31 | * SOFTWARE. | ||
32 | */ | ||
33 | |||
34 | #ifndef _IPATH_LAYER_H | ||
35 | #define _IPATH_LAYER_H | ||
36 | |||
37 | /* | ||
38 | * This header file is for symbols shared between the infinipath driver | ||
39 | * and drivers layered upon it (such as ipath). | ||
40 | */ | ||
41 | |||
42 | struct sk_buff; | ||
43 | struct ipath_devdata; | ||
44 | struct ether_header; | ||
45 | |||
46 | int ipath_layer_register(void *(*l_add)(int, struct ipath_devdata *), | ||
47 | void (*l_remove)(void *), | ||
48 | int (*l_intr)(void *, u32), | ||
49 | int (*l_rcv)(void *, void *, | ||
50 | struct sk_buff *), | ||
51 | u16 rcv_opcode, | ||
52 | int (*l_rcv_lid)(void *, void *)); | ||
53 | void ipath_layer_unregister(void); | ||
54 | int ipath_layer_open(struct ipath_devdata *, u32 * pktmax); | ||
55 | u16 ipath_layer_get_lid(struct ipath_devdata *dd); | ||
56 | int ipath_layer_get_mac(struct ipath_devdata *dd, u8 *); | ||
57 | u16 ipath_layer_get_bcast(struct ipath_devdata *dd); | ||
58 | int ipath_layer_send_hdr(struct ipath_devdata *dd, | ||
59 | struct ether_header *hdr); | ||
60 | int ipath_layer_set_piointbufavail_int(struct ipath_devdata *dd); | ||
61 | |||
62 | /* ipath_ether interrupt values */ | ||
63 | #define IPATH_LAYER_INT_IF_UP 0x2 | ||
64 | #define IPATH_LAYER_INT_IF_DOWN 0x4 | ||
65 | #define IPATH_LAYER_INT_LID 0x8 | ||
66 | #define IPATH_LAYER_INT_SEND_CONTINUE 0x10 | ||
67 | #define IPATH_LAYER_INT_BCAST 0x40 | ||
68 | |||
69 | extern unsigned ipath_debug; /* debugging bit mask */ | ||
70 | |||
71 | #endif /* _IPATH_LAYER_H */ | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.h b/drivers/infiniband/hw/ipath/ipath_verbs.h index 9bbe81967f14..1a24c6a4a814 100644 --- a/drivers/infiniband/hw/ipath/ipath_verbs.h +++ b/drivers/infiniband/hw/ipath/ipath_verbs.h | |||
@@ -42,8 +42,6 @@ | |||
42 | #include <rdma/ib_pack.h> | 42 | #include <rdma/ib_pack.h> |
43 | #include <rdma/ib_user_verbs.h> | 43 | #include <rdma/ib_user_verbs.h> |
44 | 44 | ||
45 | #include "ipath_layer.h" | ||
46 | |||
47 | #define IPATH_MAX_RDMA_ATOMIC 4 | 45 | #define IPATH_MAX_RDMA_ATOMIC 4 |
48 | 46 | ||
49 | #define QPN_MAX (1 << 24) | 47 | #define QPN_MAX (1 << 24) |
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index b5a24fbef70d..f6315dfb213e 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c | |||
@@ -415,9 +415,11 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd, | |||
415 | return 0; | 415 | return 0; |
416 | 416 | ||
417 | err_wrid: | 417 | err_wrid: |
418 | if (pd->uobject && !init_attr->srq) | 418 | if (pd->uobject) { |
419 | mlx4_ib_db_unmap_user(to_mucontext(pd->uobject->context), &qp->db); | 419 | if (!init_attr->srq) |
420 | else { | 420 | mlx4_ib_db_unmap_user(to_mucontext(pd->uobject->context), |
421 | &qp->db); | ||
422 | } else { | ||
421 | kfree(qp->sq.wrid); | 423 | kfree(qp->sq.wrid); |
422 | kfree(qp->rq.wrid); | 424 | kfree(qp->rq.wrid); |
423 | } | 425 | } |
@@ -742,7 +744,7 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp, | |||
742 | if (attr->path_mtu < IB_MTU_256 || attr->path_mtu > IB_MTU_4096) { | 744 | if (attr->path_mtu < IB_MTU_256 || attr->path_mtu > IB_MTU_4096) { |
743 | printk(KERN_ERR "path MTU (%u) is invalid\n", | 745 | printk(KERN_ERR "path MTU (%u) is invalid\n", |
744 | attr->path_mtu); | 746 | attr->path_mtu); |
745 | return -EINVAL; | 747 | goto out; |
746 | } | 748 | } |
747 | context->mtu_msgmax = (attr->path_mtu << 5) | 31; | 749 | context->mtu_msgmax = (attr->path_mtu << 5) | 31; |
748 | } | 750 | } |
@@ -781,10 +783,8 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp, | |||
781 | 783 | ||
782 | if (attr_mask & IB_QP_AV) { | 784 | if (attr_mask & IB_QP_AV) { |
783 | if (mlx4_set_path(dev, &attr->ah_attr, &context->pri_path, | 785 | if (mlx4_set_path(dev, &attr->ah_attr, &context->pri_path, |
784 | attr_mask & IB_QP_PORT ? attr->port_num : qp->port)) { | 786 | attr_mask & IB_QP_PORT ? attr->port_num : qp->port)) |
785 | err = -EINVAL; | ||
786 | goto out; | 787 | goto out; |
787 | } | ||
788 | 788 | ||
789 | optpar |= (MLX4_QP_OPTPAR_PRIMARY_ADDR_PATH | | 789 | optpar |= (MLX4_QP_OPTPAR_PRIMARY_ADDR_PATH | |
790 | MLX4_QP_OPTPAR_SCHED_QUEUE); | 790 | MLX4_QP_OPTPAR_SCHED_QUEUE); |
@@ -798,15 +798,15 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp, | |||
798 | if (attr_mask & IB_QP_ALT_PATH) { | 798 | if (attr_mask & IB_QP_ALT_PATH) { |
799 | if (attr->alt_port_num == 0 || | 799 | if (attr->alt_port_num == 0 || |
800 | attr->alt_port_num > dev->dev->caps.num_ports) | 800 | attr->alt_port_num > dev->dev->caps.num_ports) |
801 | return -EINVAL; | 801 | goto out; |
802 | 802 | ||
803 | if (attr->alt_pkey_index >= | 803 | if (attr->alt_pkey_index >= |
804 | dev->dev->caps.pkey_table_len[attr->alt_port_num]) | 804 | dev->dev->caps.pkey_table_len[attr->alt_port_num]) |
805 | return -EINVAL; | 805 | goto out; |
806 | 806 | ||
807 | if (mlx4_set_path(dev, &attr->alt_ah_attr, &context->alt_path, | 807 | if (mlx4_set_path(dev, &attr->alt_ah_attr, &context->alt_path, |
808 | attr->alt_port_num)) | 808 | attr->alt_port_num)) |
809 | return -EINVAL; | 809 | goto out; |
810 | 810 | ||
811 | context->alt_path.pkey_index = attr->alt_pkey_index; | 811 | context->alt_path.pkey_index = attr->alt_pkey_index; |
812 | context->alt_path.ackto = attr->alt_timeout << 3; | 812 | context->alt_path.ackto = attr->alt_timeout << 3; |
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index f40558d76475..acc95892713a 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/drivers/infiniband/hw/mthca/mthca_cmd.c | |||
@@ -357,8 +357,6 @@ void mthca_cmd_event(struct mthca_dev *dev, | |||
357 | context->status = status; | 357 | context->status = status; |
358 | context->out_param = out_param; | 358 | context->out_param = out_param; |
359 | 359 | ||
360 | context->token += dev->cmd.token_mask + 1; | ||
361 | |||
362 | complete(&context->done); | 360 | complete(&context->done); |
363 | } | 361 | } |
364 | 362 | ||
@@ -380,6 +378,7 @@ static int mthca_cmd_wait(struct mthca_dev *dev, | |||
380 | spin_lock(&dev->cmd.context_lock); | 378 | spin_lock(&dev->cmd.context_lock); |
381 | BUG_ON(dev->cmd.free_head < 0); | 379 | BUG_ON(dev->cmd.free_head < 0); |
382 | context = &dev->cmd.context[dev->cmd.free_head]; | 380 | context = &dev->cmd.context[dev->cmd.free_head]; |
381 | context->token += dev->cmd.token_mask + 1; | ||
383 | dev->cmd.free_head = context->next; | 382 | dev->cmd.free_head = context->next; |
384 | spin_unlock(&dev->cmd.context_lock); | 383 | spin_unlock(&dev->cmd.context_lock); |
385 | 384 | ||
diff --git a/drivers/kvm/Kconfig b/drivers/kvm/Kconfig index 2f661e5f0dae..6cecc396e040 100644 --- a/drivers/kvm/Kconfig +++ b/drivers/kvm/Kconfig | |||
@@ -11,6 +11,7 @@ if VIRTUALIZATION | |||
11 | config KVM | 11 | config KVM |
12 | tristate "Kernel-based Virtual Machine (KVM) support" | 12 | tristate "Kernel-based Virtual Machine (KVM) support" |
13 | depends on X86 && EXPERIMENTAL | 13 | depends on X86 && EXPERIMENTAL |
14 | select ANON_INODES | ||
14 | ---help--- | 15 | ---help--- |
15 | Support hosting fully virtualized guest machines using hardware | 16 | Support hosting fully virtualized guest machines using hardware |
16 | virtualization extensions. You will need a fairly recent | 17 | virtualization extensions. You will need a fairly recent |
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 87d2046f866c..4468cb3a8d24 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig | |||
@@ -1,9 +1,6 @@ | |||
1 | 1 | menuconfig NEW_LEDS | |
2 | menu "LED devices" | ||
3 | depends on HAS_IOMEM | ||
4 | |||
5 | config NEW_LEDS | ||
6 | bool "LED Support" | 2 | bool "LED Support" |
3 | depends on HAS_IOMEM | ||
7 | help | 4 | help |
8 | Say Y to enable Linux LED support. This allows control of supported | 5 | Say Y to enable Linux LED support. This allows control of supported |
9 | LEDs from both userspace and optionally, by kernel events (triggers). | 6 | LEDs from both userspace and optionally, by kernel events (triggers). |
@@ -11,9 +8,10 @@ config NEW_LEDS | |||
11 | This is not related to standard keyboard LEDs which are controlled | 8 | This is not related to standard keyboard LEDs which are controlled |
12 | via the input system. | 9 | via the input system. |
13 | 10 | ||
11 | if NEW_LEDS | ||
12 | |||
14 | config LEDS_CLASS | 13 | config LEDS_CLASS |
15 | tristate "LED Class Support" | 14 | tristate "LED Class Support" |
16 | depends on NEW_LEDS | ||
17 | help | 15 | help |
18 | This option enables the led sysfs class in /sys/class/leds. You'll | 16 | This option enables the led sysfs class in /sys/class/leds. You'll |
19 | need this to do anything useful with LEDs. If unsure, say N. | 17 | need this to do anything useful with LEDs. If unsure, say N. |
@@ -95,11 +93,18 @@ config LEDS_COBALT | |||
95 | help | 93 | help |
96 | This option enables support for the front LED on Cobalt Server | 94 | This option enables support for the front LED on Cobalt Server |
97 | 95 | ||
96 | config LEDS_GPIO | ||
97 | tristate "LED Support for GPIO connected LEDs" | ||
98 | depends on LEDS_CLASS && GENERIC_GPIO | ||
99 | help | ||
100 | This option enables support for the LEDs connected to GPIO | ||
101 | outputs. To be useful the particular board must have LEDs | ||
102 | and they must be connected to the GPIO lines. | ||
103 | |||
98 | comment "LED Triggers" | 104 | comment "LED Triggers" |
99 | 105 | ||
100 | config LEDS_TRIGGERS | 106 | config LEDS_TRIGGERS |
101 | bool "LED Trigger support" | 107 | bool "LED Trigger support" |
102 | depends on NEW_LEDS | ||
103 | help | 108 | help |
104 | This option enables trigger support for the leds class. | 109 | This option enables trigger support for the leds class. |
105 | These triggers allow kernel events to drive the LEDs and can | 110 | These triggers allow kernel events to drive the LEDs and can |
@@ -128,5 +133,4 @@ config LEDS_TRIGGER_HEARTBEAT | |||
128 | load average. | 133 | load average. |
129 | If unsure, say Y. | 134 | If unsure, say Y. |
130 | 135 | ||
131 | endmenu | 136 | endif # NEW_LEDS |
132 | |||
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index aa2c18efa5b2..f8995c9bc2ea 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile | |||
@@ -16,6 +16,7 @@ obj-$(CONFIG_LEDS_NET48XX) += leds-net48xx.o | |||
16 | obj-$(CONFIG_LEDS_WRAP) += leds-wrap.o | 16 | obj-$(CONFIG_LEDS_WRAP) += leds-wrap.o |
17 | obj-$(CONFIG_LEDS_H1940) += leds-h1940.o | 17 | obj-$(CONFIG_LEDS_H1940) += leds-h1940.o |
18 | obj-$(CONFIG_LEDS_COBALT) += leds-cobalt.o | 18 | obj-$(CONFIG_LEDS_COBALT) += leds-cobalt.o |
19 | obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o | ||
19 | 20 | ||
20 | # LED Triggers | 21 | # LED Triggers |
21 | obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o | 22 | obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o |
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 3c1711210e38..4211293ce862 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * LED Class Core | 2 | * LED Class Core |
3 | * | 3 | * |
4 | * Copyright (C) 2005 John Lenz <lenz@cs.wisc.edu> | 4 | * Copyright (C) 2005 John Lenz <lenz@cs.wisc.edu> |
5 | * Copyright (C) 2005-2006 Richard Purdie <rpurdie@openedhand.com> | 5 | * Copyright (C) 2005-2007 Richard Purdie <rpurdie@openedhand.com> |
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 |
@@ -24,9 +24,10 @@ | |||
24 | 24 | ||
25 | static struct class *leds_class; | 25 | static struct class *leds_class; |
26 | 26 | ||
27 | static ssize_t led_brightness_show(struct class_device *dev, char *buf) | 27 | static ssize_t led_brightness_show(struct device *dev, |
28 | struct device_attribute *attr, char *buf) | ||
28 | { | 29 | { |
29 | struct led_classdev *led_cdev = class_get_devdata(dev); | 30 | struct led_classdev *led_cdev = dev_get_drvdata(dev); |
30 | ssize_t ret = 0; | 31 | ssize_t ret = 0; |
31 | 32 | ||
32 | /* no lock needed for this */ | 33 | /* no lock needed for this */ |
@@ -36,10 +37,10 @@ static ssize_t led_brightness_show(struct class_device *dev, char *buf) | |||
36 | return ret; | 37 | return ret; |
37 | } | 38 | } |
38 | 39 | ||
39 | static ssize_t led_brightness_store(struct class_device *dev, | 40 | static ssize_t led_brightness_store(struct device *dev, |
40 | const char *buf, size_t size) | 41 | struct device_attribute *attr, const char *buf, size_t size) |
41 | { | 42 | { |
42 | struct led_classdev *led_cdev = class_get_devdata(dev); | 43 | struct led_classdev *led_cdev = dev_get_drvdata(dev); |
43 | ssize_t ret = -EINVAL; | 44 | ssize_t ret = -EINVAL; |
44 | char *after; | 45 | char *after; |
45 | unsigned long state = simple_strtoul(buf, &after, 10); | 46 | unsigned long state = simple_strtoul(buf, &after, 10); |
@@ -56,10 +57,9 @@ static ssize_t led_brightness_store(struct class_device *dev, | |||
56 | return ret; | 57 | return ret; |
57 | } | 58 | } |
58 | 59 | ||
59 | static CLASS_DEVICE_ATTR(brightness, 0644, led_brightness_show, | 60 | static DEVICE_ATTR(brightness, 0644, led_brightness_show, led_brightness_store); |
60 | led_brightness_store); | ||
61 | #ifdef CONFIG_LEDS_TRIGGERS | 61 | #ifdef CONFIG_LEDS_TRIGGERS |
62 | static CLASS_DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store); | 62 | static DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store); |
63 | #endif | 63 | #endif |
64 | 64 | ||
65 | /** | 65 | /** |
@@ -93,16 +93,15 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) | |||
93 | { | 93 | { |
94 | int rc; | 94 | int rc; |
95 | 95 | ||
96 | led_cdev->class_dev = class_device_create(leds_class, NULL, 0, | 96 | led_cdev->dev = device_create(leds_class, parent, 0, "%s", |
97 | parent, "%s", led_cdev->name); | 97 | led_cdev->name); |
98 | if (unlikely(IS_ERR(led_cdev->class_dev))) | 98 | if (unlikely(IS_ERR(led_cdev->dev))) |
99 | return PTR_ERR(led_cdev->class_dev); | 99 | return PTR_ERR(led_cdev->dev); |
100 | 100 | ||
101 | class_set_devdata(led_cdev->class_dev, led_cdev); | 101 | dev_set_drvdata(led_cdev->dev, led_cdev); |
102 | 102 | ||
103 | /* register the attributes */ | 103 | /* register the attributes */ |
104 | rc = class_device_create_file(led_cdev->class_dev, | 104 | rc = device_create_file(led_cdev->dev, &dev_attr_brightness); |
105 | &class_device_attr_brightness); | ||
106 | if (rc) | 105 | if (rc) |
107 | goto err_out; | 106 | goto err_out; |
108 | 107 | ||
@@ -114,8 +113,7 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) | |||
114 | #ifdef CONFIG_LEDS_TRIGGERS | 113 | #ifdef CONFIG_LEDS_TRIGGERS |
115 | rwlock_init(&led_cdev->trigger_lock); | 114 | rwlock_init(&led_cdev->trigger_lock); |
116 | 115 | ||
117 | rc = class_device_create_file(led_cdev->class_dev, | 116 | rc = device_create_file(led_cdev->dev, &dev_attr_trigger); |
118 | &class_device_attr_trigger); | ||
119 | if (rc) | 117 | if (rc) |
120 | goto err_out_led_list; | 118 | goto err_out_led_list; |
121 | 119 | ||
@@ -123,18 +121,17 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) | |||
123 | #endif | 121 | #endif |
124 | 122 | ||
125 | printk(KERN_INFO "Registered led device: %s\n", | 123 | printk(KERN_INFO "Registered led device: %s\n", |
126 | led_cdev->class_dev->class_id); | 124 | led_cdev->name); |
127 | 125 | ||
128 | return 0; | 126 | return 0; |
129 | 127 | ||
130 | #ifdef CONFIG_LEDS_TRIGGERS | 128 | #ifdef CONFIG_LEDS_TRIGGERS |
131 | err_out_led_list: | 129 | err_out_led_list: |
132 | class_device_remove_file(led_cdev->class_dev, | 130 | device_remove_file(led_cdev->dev, &dev_attr_brightness); |
133 | &class_device_attr_brightness); | ||
134 | list_del(&led_cdev->node); | 131 | list_del(&led_cdev->node); |
135 | #endif | 132 | #endif |
136 | err_out: | 133 | err_out: |
137 | class_device_unregister(led_cdev->class_dev); | 134 | device_unregister(led_cdev->dev); |
138 | return rc; | 135 | return rc; |
139 | } | 136 | } |
140 | EXPORT_SYMBOL_GPL(led_classdev_register); | 137 | EXPORT_SYMBOL_GPL(led_classdev_register); |
@@ -147,18 +144,16 @@ EXPORT_SYMBOL_GPL(led_classdev_register); | |||
147 | */ | 144 | */ |
148 | void led_classdev_unregister(struct led_classdev *led_cdev) | 145 | void led_classdev_unregister(struct led_classdev *led_cdev) |
149 | { | 146 | { |
150 | class_device_remove_file(led_cdev->class_dev, | 147 | device_remove_file(led_cdev->dev, &dev_attr_brightness); |
151 | &class_device_attr_brightness); | ||
152 | #ifdef CONFIG_LEDS_TRIGGERS | 148 | #ifdef CONFIG_LEDS_TRIGGERS |
153 | class_device_remove_file(led_cdev->class_dev, | 149 | device_remove_file(led_cdev->dev, &dev_attr_trigger); |
154 | &class_device_attr_trigger); | ||
155 | write_lock(&led_cdev->trigger_lock); | 150 | write_lock(&led_cdev->trigger_lock); |
156 | if (led_cdev->trigger) | 151 | if (led_cdev->trigger) |
157 | led_trigger_set(led_cdev, NULL); | 152 | led_trigger_set(led_cdev, NULL); |
158 | write_unlock(&led_cdev->trigger_lock); | 153 | write_unlock(&led_cdev->trigger_lock); |
159 | #endif | 154 | #endif |
160 | 155 | ||
161 | class_device_unregister(led_cdev->class_dev); | 156 | device_unregister(led_cdev->dev); |
162 | 157 | ||
163 | write_lock(&leds_list_lock); | 158 | write_lock(&leds_list_lock); |
164 | list_del(&led_cdev->node); | 159 | list_del(&led_cdev->node); |
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index 454fb0901f82..575368c2b100 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * LED Triggers Core | 2 | * LED Triggers Core |
3 | * | 3 | * |
4 | * Copyright 2005-2006 Openedhand Ltd. | 4 | * Copyright 2005-2007 Openedhand Ltd. |
5 | * | 5 | * |
6 | * Author: Richard Purdie <rpurdie@openedhand.com> | 6 | * Author: Richard Purdie <rpurdie@openedhand.com> |
7 | * | 7 | * |
@@ -28,10 +28,10 @@ | |||
28 | static DEFINE_RWLOCK(triggers_list_lock); | 28 | static DEFINE_RWLOCK(triggers_list_lock); |
29 | static LIST_HEAD(trigger_list); | 29 | static LIST_HEAD(trigger_list); |
30 | 30 | ||
31 | ssize_t led_trigger_store(struct class_device *dev, const char *buf, | 31 | ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr, |
32 | size_t count) | 32 | const char *buf, size_t count) |
33 | { | 33 | { |
34 | struct led_classdev *led_cdev = class_get_devdata(dev); | 34 | struct led_classdev *led_cdev = dev_get_drvdata(dev); |
35 | char trigger_name[TRIG_NAME_MAX]; | 35 | char trigger_name[TRIG_NAME_MAX]; |
36 | struct led_trigger *trig; | 36 | struct led_trigger *trig; |
37 | size_t len; | 37 | size_t len; |
@@ -67,9 +67,10 @@ ssize_t led_trigger_store(struct class_device *dev, const char *buf, | |||
67 | } | 67 | } |
68 | 68 | ||
69 | 69 | ||
70 | ssize_t led_trigger_show(struct class_device *dev, char *buf) | 70 | ssize_t led_trigger_show(struct device *dev, struct device_attribute *attr, |
71 | char *buf) | ||
71 | { | 72 | { |
72 | struct led_classdev *led_cdev = class_get_devdata(dev); | 73 | struct led_classdev *led_cdev = dev_get_drvdata(dev); |
73 | struct led_trigger *trig; | 74 | struct led_trigger *trig; |
74 | int len = 0; | 75 | int len = 0; |
75 | 76 | ||
@@ -183,13 +184,20 @@ int led_trigger_register(struct led_trigger *trigger) | |||
183 | void led_trigger_register_simple(const char *name, struct led_trigger **tp) | 184 | void led_trigger_register_simple(const char *name, struct led_trigger **tp) |
184 | { | 185 | { |
185 | struct led_trigger *trigger; | 186 | struct led_trigger *trigger; |
187 | int err; | ||
186 | 188 | ||
187 | trigger = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); | 189 | trigger = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); |
188 | 190 | ||
189 | if (trigger) { | 191 | if (trigger) { |
190 | trigger->name = name; | 192 | trigger->name = name; |
191 | led_trigger_register(trigger); | 193 | err = led_trigger_register(trigger); |
192 | } | 194 | if (err < 0) |
195 | printk(KERN_WARNING "LED trigger %s failed to register" | ||
196 | " (%d)\n", name, err); | ||
197 | } else | ||
198 | printk(KERN_WARNING "LED trigger %s failed to register" | ||
199 | " (no memory)\n", name); | ||
200 | |||
193 | *tp = trigger; | 201 | *tp = trigger; |
194 | } | 202 | } |
195 | 203 | ||
@@ -215,7 +223,8 @@ void led_trigger_unregister(struct led_trigger *trigger) | |||
215 | 223 | ||
216 | void led_trigger_unregister_simple(struct led_trigger *trigger) | 224 | void led_trigger_unregister_simple(struct led_trigger *trigger) |
217 | { | 225 | { |
218 | led_trigger_unregister(trigger); | 226 | if (trigger) |
227 | led_trigger_unregister(trigger); | ||
219 | kfree(trigger); | 228 | kfree(trigger); |
220 | } | 229 | } |
221 | 230 | ||
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c new file mode 100644 index 000000000000..47d90db280ce --- /dev/null +++ b/drivers/leds/leds-gpio.c | |||
@@ -0,0 +1,199 @@ | |||
1 | /* | ||
2 | * LEDs driver for GPIOs | ||
3 | * | ||
4 | * Copyright (C) 2007 8D Technologies inc. | ||
5 | * Raphael Assenat <raph@8d.com> | ||
6 | * | ||
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 | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | */ | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/leds.h> | ||
16 | #include <linux/workqueue.h> | ||
17 | |||
18 | #include <asm/gpio.h> | ||
19 | |||
20 | struct gpio_led_data { | ||
21 | struct led_classdev cdev; | ||
22 | unsigned gpio; | ||
23 | struct work_struct work; | ||
24 | u8 new_level; | ||
25 | u8 can_sleep; | ||
26 | u8 active_low; | ||
27 | }; | ||
28 | |||
29 | static void gpio_led_work(struct work_struct *work) | ||
30 | { | ||
31 | struct gpio_led_data *led_dat = | ||
32 | container_of(work, struct gpio_led_data, work); | ||
33 | |||
34 | gpio_set_value_cansleep(led_dat->gpio, led_dat->new_level); | ||
35 | } | ||
36 | |||
37 | static void gpio_led_set(struct led_classdev *led_cdev, | ||
38 | enum led_brightness value) | ||
39 | { | ||
40 | struct gpio_led_data *led_dat = | ||
41 | container_of(led_cdev, struct gpio_led_data, cdev); | ||
42 | int level; | ||
43 | |||
44 | if (value == LED_OFF) | ||
45 | level = 0; | ||
46 | else | ||
47 | level = 1; | ||
48 | |||
49 | if (led_dat->active_low) | ||
50 | level = !level; | ||
51 | |||
52 | /* setting GPIOs with I2C/etc requires a preemptible task context */ | ||
53 | if (led_dat->can_sleep) { | ||
54 | if (preempt_count()) { | ||
55 | led_dat->new_level = level; | ||
56 | schedule_work(&led_dat->work); | ||
57 | } else | ||
58 | gpio_set_value_cansleep(led_dat->gpio, level); | ||
59 | } else | ||
60 | gpio_set_value(led_dat->gpio, level); | ||
61 | } | ||
62 | |||
63 | static int __init gpio_led_probe(struct platform_device *pdev) | ||
64 | { | ||
65 | struct gpio_led_platform_data *pdata = pdev->dev.platform_data; | ||
66 | struct gpio_led *cur_led; | ||
67 | struct gpio_led_data *leds_data, *led_dat; | ||
68 | int i, ret = 0; | ||
69 | |||
70 | if (!pdata) | ||
71 | return -EBUSY; | ||
72 | |||
73 | leds_data = kzalloc(sizeof(struct gpio_led_data) * pdata->num_leds, | ||
74 | GFP_KERNEL); | ||
75 | if (!leds_data) | ||
76 | return -ENOMEM; | ||
77 | |||
78 | for (i = 0; i < pdata->num_leds; i++) { | ||
79 | cur_led = &pdata->leds[i]; | ||
80 | led_dat = &leds_data[i]; | ||
81 | |||
82 | led_dat->cdev.name = cur_led->name; | ||
83 | led_dat->cdev.default_trigger = cur_led->default_trigger; | ||
84 | led_dat->gpio = cur_led->gpio; | ||
85 | led_dat->can_sleep = gpio_cansleep(cur_led->gpio); | ||
86 | led_dat->active_low = cur_led->active_low; | ||
87 | led_dat->cdev.brightness_set = gpio_led_set; | ||
88 | led_dat->cdev.brightness = cur_led->active_low ? LED_FULL : LED_OFF; | ||
89 | |||
90 | ret = gpio_request(led_dat->gpio, led_dat->cdev.name); | ||
91 | if (ret < 0) | ||
92 | goto err; | ||
93 | |||
94 | gpio_direction_output(led_dat->gpio, led_dat->active_low); | ||
95 | |||
96 | ret = led_classdev_register(&pdev->dev, &led_dat->cdev); | ||
97 | if (ret < 0) { | ||
98 | gpio_free(led_dat->gpio); | ||
99 | goto err; | ||
100 | } | ||
101 | |||
102 | INIT_WORK(&led_dat->work, gpio_led_work); | ||
103 | } | ||
104 | |||
105 | platform_set_drvdata(pdev, leds_data); | ||
106 | |||
107 | return 0; | ||
108 | |||
109 | err: | ||
110 | if (i > 0) { | ||
111 | for (i = i - 1; i >= 0; i--) { | ||
112 | led_classdev_unregister(&leds_data[i].cdev); | ||
113 | gpio_free(leds_data[i].gpio); | ||
114 | } | ||
115 | } | ||
116 | |||
117 | flush_scheduled_work(); | ||
118 | kfree(leds_data); | ||
119 | |||
120 | return ret; | ||
121 | } | ||
122 | |||
123 | static int __exit gpio_led_remove(struct platform_device *pdev) | ||
124 | { | ||
125 | int i; | ||
126 | struct gpio_led_platform_data *pdata = pdev->dev.platform_data; | ||
127 | struct gpio_led_data *leds_data; | ||
128 | |||
129 | leds_data = platform_get_drvdata(pdev); | ||
130 | |||
131 | for (i = 0; i < pdata->num_leds; i++) { | ||
132 | led_classdev_unregister(&leds_data[i].cdev); | ||
133 | gpio_free(leds_data[i].gpio); | ||
134 | } | ||
135 | |||
136 | kfree(leds_data); | ||
137 | |||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | #ifdef CONFIG_PM | ||
142 | static int gpio_led_suspend(struct platform_device *pdev, pm_message_t state) | ||
143 | { | ||
144 | struct gpio_led_platform_data *pdata = pdev->dev.platform_data; | ||
145 | struct gpio_led_data *leds_data; | ||
146 | int i; | ||
147 | |||
148 | leds_data = platform_get_drvdata(pdev); | ||
149 | |||
150 | for (i = 0; i < pdata->num_leds; i++) | ||
151 | led_classdev_suspend(&leds_data[i].cdev); | ||
152 | |||
153 | return 0; | ||
154 | } | ||
155 | |||
156 | static int gpio_led_resume(struct platform_device *pdev) | ||
157 | { | ||
158 | struct gpio_led_platform_data *pdata = pdev->dev.platform_data; | ||
159 | struct gpio_led_data *leds_data; | ||
160 | int i; | ||
161 | |||
162 | leds_data = platform_get_drvdata(pdev); | ||
163 | |||
164 | for (i = 0; i < pdata->num_leds; i++) | ||
165 | led_classdev_resume(&leds_data[i].cdev); | ||
166 | |||
167 | return 0; | ||
168 | } | ||
169 | #else | ||
170 | #define gpio_led_suspend NULL | ||
171 | #define gpio_led_resume NULL | ||
172 | #endif | ||
173 | |||
174 | static struct platform_driver gpio_led_driver = { | ||
175 | .remove = __exit_p(gpio_led_remove), | ||
176 | .suspend = gpio_led_suspend, | ||
177 | .resume = gpio_led_resume, | ||
178 | .driver = { | ||
179 | .name = "leds-gpio", | ||
180 | .owner = THIS_MODULE, | ||
181 | }, | ||
182 | }; | ||
183 | |||
184 | static int __init gpio_led_init(void) | ||
185 | { | ||
186 | return platform_driver_probe(&gpio_led_driver, gpio_led_probe); | ||
187 | } | ||
188 | |||
189 | static void __exit gpio_led_exit(void) | ||
190 | { | ||
191 | platform_driver_unregister(&gpio_led_driver); | ||
192 | } | ||
193 | |||
194 | module_init(gpio_led_init); | ||
195 | module_exit(gpio_led_exit); | ||
196 | |||
197 | MODULE_AUTHOR("Raphael Assenat <raph@8d.com>"); | ||
198 | MODULE_DESCRIPTION("GPIO LED driver"); | ||
199 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/leds/leds-locomo.c b/drivers/leds/leds-locomo.c index 6f2d449ba983..bfac499f3258 100644 --- a/drivers/leds/leds-locomo.c +++ b/drivers/leds/leds-locomo.c | |||
@@ -19,7 +19,7 @@ | |||
19 | static void locomoled_brightness_set(struct led_classdev *led_cdev, | 19 | static void locomoled_brightness_set(struct led_classdev *led_cdev, |
20 | enum led_brightness value, int offset) | 20 | enum led_brightness value, int offset) |
21 | { | 21 | { |
22 | struct locomo_dev *locomo_dev = LOCOMO_DEV(led_cdev->class_dev->dev); | 22 | struct locomo_dev *locomo_dev = LOCOMO_DEV(led_cdev->dev); |
23 | unsigned long flags; | 23 | unsigned long flags; |
24 | 24 | ||
25 | local_irq_save(flags); | 25 | local_irq_save(flags); |
diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h index a715c4ed93ff..f2f3884fe063 100644 --- a/drivers/leds/leds.h +++ b/drivers/leds/leds.h | |||
@@ -13,6 +13,7 @@ | |||
13 | #ifndef __LEDS_H_INCLUDED | 13 | #ifndef __LEDS_H_INCLUDED |
14 | #define __LEDS_H_INCLUDED | 14 | #define __LEDS_H_INCLUDED |
15 | 15 | ||
16 | #include <linux/device.h> | ||
16 | #include <linux/leds.h> | 17 | #include <linux/leds.h> |
17 | 18 | ||
18 | static inline void led_set_brightness(struct led_classdev *led_cdev, | 19 | static inline void led_set_brightness(struct led_classdev *led_cdev, |
@@ -37,8 +38,9 @@ void led_trigger_set(struct led_classdev *led_cdev, | |||
37 | #define led_trigger_set(x, y) do {} while(0) | 38 | #define led_trigger_set(x, y) do {} while(0) |
38 | #endif | 39 | #endif |
39 | 40 | ||
40 | ssize_t led_trigger_store(struct class_device *dev, const char *buf, | 41 | ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr, |
41 | size_t count); | 42 | const char *buf, size_t count); |
42 | ssize_t led_trigger_show(struct class_device *dev, char *buf); | 43 | ssize_t led_trigger_show(struct device *dev, struct device_attribute *attr, |
44 | char *buf); | ||
43 | 45 | ||
44 | #endif /* __LEDS_H_INCLUDED */ | 46 | #endif /* __LEDS_H_INCLUDED */ |
diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/ledtrig-timer.c index d756bdb01c59..ed9ff02c77ea 100644 --- a/drivers/leds/ledtrig-timer.c +++ b/drivers/leds/ledtrig-timer.c | |||
@@ -52,9 +52,10 @@ static void led_timer_function(unsigned long data) | |||
52 | mod_timer(&timer_data->timer, jiffies + msecs_to_jiffies(delay)); | 52 | mod_timer(&timer_data->timer, jiffies + msecs_to_jiffies(delay)); |
53 | } | 53 | } |
54 | 54 | ||
55 | static ssize_t led_delay_on_show(struct class_device *dev, char *buf) | 55 | static ssize_t led_delay_on_show(struct device *dev, |
56 | struct device_attribute *attr, char *buf) | ||
56 | { | 57 | { |
57 | struct led_classdev *led_cdev = class_get_devdata(dev); | 58 | struct led_classdev *led_cdev = dev_get_drvdata(dev); |
58 | struct timer_trig_data *timer_data = led_cdev->trigger_data; | 59 | struct timer_trig_data *timer_data = led_cdev->trigger_data; |
59 | 60 | ||
60 | sprintf(buf, "%lu\n", timer_data->delay_on); | 61 | sprintf(buf, "%lu\n", timer_data->delay_on); |
@@ -62,10 +63,10 @@ static ssize_t led_delay_on_show(struct class_device *dev, char *buf) | |||
62 | return strlen(buf) + 1; | 63 | return strlen(buf) + 1; |
63 | } | 64 | } |
64 | 65 | ||
65 | static ssize_t led_delay_on_store(struct class_device *dev, const char *buf, | 66 | static ssize_t led_delay_on_store(struct device *dev, |
66 | size_t size) | 67 | struct device_attribute *attr, const char *buf, size_t size) |
67 | { | 68 | { |
68 | struct led_classdev *led_cdev = class_get_devdata(dev); | 69 | struct led_classdev *led_cdev = dev_get_drvdata(dev); |
69 | struct timer_trig_data *timer_data = led_cdev->trigger_data; | 70 | struct timer_trig_data *timer_data = led_cdev->trigger_data; |
70 | int ret = -EINVAL; | 71 | int ret = -EINVAL; |
71 | char *after; | 72 | char *after; |
@@ -84,9 +85,10 @@ static ssize_t led_delay_on_store(struct class_device *dev, const char *buf, | |||
84 | return ret; | 85 | return ret; |
85 | } | 86 | } |
86 | 87 | ||
87 | static ssize_t led_delay_off_show(struct class_device *dev, char *buf) | 88 | static ssize_t led_delay_off_show(struct device *dev, |
89 | struct device_attribute *attr, char *buf) | ||
88 | { | 90 | { |
89 | struct led_classdev *led_cdev = class_get_devdata(dev); | 91 | struct led_classdev *led_cdev = dev_get_drvdata(dev); |
90 | struct timer_trig_data *timer_data = led_cdev->trigger_data; | 92 | struct timer_trig_data *timer_data = led_cdev->trigger_data; |
91 | 93 | ||
92 | sprintf(buf, "%lu\n", timer_data->delay_off); | 94 | sprintf(buf, "%lu\n", timer_data->delay_off); |
@@ -94,10 +96,10 @@ static ssize_t led_delay_off_show(struct class_device *dev, char *buf) | |||
94 | return strlen(buf) + 1; | 96 | return strlen(buf) + 1; |
95 | } | 97 | } |
96 | 98 | ||
97 | static ssize_t led_delay_off_store(struct class_device *dev, const char *buf, | 99 | static ssize_t led_delay_off_store(struct device *dev, |
98 | size_t size) | 100 | struct device_attribute *attr, const char *buf, size_t size) |
99 | { | 101 | { |
100 | struct led_classdev *led_cdev = class_get_devdata(dev); | 102 | struct led_classdev *led_cdev = dev_get_drvdata(dev); |
101 | struct timer_trig_data *timer_data = led_cdev->trigger_data; | 103 | struct timer_trig_data *timer_data = led_cdev->trigger_data; |
102 | int ret = -EINVAL; | 104 | int ret = -EINVAL; |
103 | char *after; | 105 | char *after; |
@@ -116,10 +118,8 @@ static ssize_t led_delay_off_store(struct class_device *dev, const char *buf, | |||
116 | return ret; | 118 | return ret; |
117 | } | 119 | } |
118 | 120 | ||
119 | static CLASS_DEVICE_ATTR(delay_on, 0644, led_delay_on_show, | 121 | static DEVICE_ATTR(delay_on, 0644, led_delay_on_show, led_delay_on_store); |
120 | led_delay_on_store); | 122 | static DEVICE_ATTR(delay_off, 0644, led_delay_off_show, led_delay_off_store); |
121 | static CLASS_DEVICE_ATTR(delay_off, 0644, led_delay_off_show, | ||
122 | led_delay_off_store); | ||
123 | 123 | ||
124 | static void timer_trig_activate(struct led_classdev *led_cdev) | 124 | static void timer_trig_activate(struct led_classdev *led_cdev) |
125 | { | 125 | { |
@@ -136,18 +136,17 @@ static void timer_trig_activate(struct led_classdev *led_cdev) | |||
136 | timer_data->timer.function = led_timer_function; | 136 | timer_data->timer.function = led_timer_function; |
137 | timer_data->timer.data = (unsigned long) led_cdev; | 137 | timer_data->timer.data = (unsigned long) led_cdev; |
138 | 138 | ||
139 | rc = class_device_create_file(led_cdev->class_dev, | 139 | rc = device_create_file(led_cdev->dev, &dev_attr_delay_on); |
140 | &class_device_attr_delay_on); | 140 | if (rc) |
141 | if (rc) goto err_out; | 141 | goto err_out; |
142 | rc = class_device_create_file(led_cdev->class_dev, | 142 | rc = device_create_file(led_cdev->dev, &dev_attr_delay_off); |
143 | &class_device_attr_delay_off); | 143 | if (rc) |
144 | if (rc) goto err_out_delayon; | 144 | goto err_out_delayon; |
145 | 145 | ||
146 | return; | 146 | return; |
147 | 147 | ||
148 | err_out_delayon: | 148 | err_out_delayon: |
149 | class_device_remove_file(led_cdev->class_dev, | 149 | device_remove_file(led_cdev->dev, &dev_attr_delay_on); |
150 | &class_device_attr_delay_on); | ||
151 | err_out: | 150 | err_out: |
152 | led_cdev->trigger_data = NULL; | 151 | led_cdev->trigger_data = NULL; |
153 | kfree(timer_data); | 152 | kfree(timer_data); |
@@ -158,10 +157,8 @@ static void timer_trig_deactivate(struct led_classdev *led_cdev) | |||
158 | struct timer_trig_data *timer_data = led_cdev->trigger_data; | 157 | struct timer_trig_data *timer_data = led_cdev->trigger_data; |
159 | 158 | ||
160 | if (timer_data) { | 159 | if (timer_data) { |
161 | class_device_remove_file(led_cdev->class_dev, | 160 | device_remove_file(led_cdev->dev, &dev_attr_delay_on); |
162 | &class_device_attr_delay_on); | 161 | device_remove_file(led_cdev->dev, &dev_attr_delay_off); |
163 | class_device_remove_file(led_cdev->class_dev, | ||
164 | &class_device_attr_delay_off); | ||
165 | del_timer_sync(&timer_data->timer); | 162 | del_timer_sync(&timer_data->timer); |
166 | kfree(timer_data); | 163 | kfree(timer_data); |
167 | } | 164 | } |
diff --git a/drivers/macintosh/rack-meter.c b/drivers/macintosh/rack-meter.c index 4177ff004753..2c21d4f25cc8 100644 --- a/drivers/macintosh/rack-meter.c +++ b/drivers/macintosh/rack-meter.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <asm/machdep.h> | 30 | #include <asm/machdep.h> |
31 | #include <asm/pmac_feature.h> | 31 | #include <asm/pmac_feature.h> |
32 | #include <asm/dbdma.h> | 32 | #include <asm/dbdma.h> |
33 | #include <asm/dbdma.h> | ||
34 | #include <asm/macio.h> | 33 | #include <asm/macio.h> |
35 | #include <asm/keylargo.h> | 34 | #include <asm/keylargo.h> |
36 | 35 | ||
diff --git a/drivers/message/fusion/Kconfig b/drivers/message/fusion/Kconfig index c88cc75ab49b..4494e0fd36c6 100644 --- a/drivers/message/fusion/Kconfig +++ b/drivers/message/fusion/Kconfig | |||
@@ -37,6 +37,7 @@ config FUSION_FC | |||
37 | LSIFC929 | 37 | LSIFC929 |
38 | LSIFC929X | 38 | LSIFC929X |
39 | LSIFC929XL | 39 | LSIFC929XL |
40 | Brocade FC 410/420 | ||
40 | 41 | ||
41 | config FUSION_SAS | 42 | config FUSION_SAS |
42 | tristate "Fusion MPT ScsiHost drivers for SAS" | 43 | tristate "Fusion MPT ScsiHost drivers for SAS" |
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 5a10c87239c2..04f75e24dcec 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c | |||
@@ -161,6 +161,7 @@ static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum); | |||
161 | static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc); | 161 | static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc); |
162 | static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc); | 162 | static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc); |
163 | static void mpt_timer_expired(unsigned long data); | 163 | static void mpt_timer_expired(unsigned long data); |
164 | static void mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc); | ||
164 | static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch); | 165 | static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch); |
165 | static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp); | 166 | static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp); |
166 | static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag); | 167 | static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag); |
@@ -1131,6 +1132,248 @@ mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp) | |||
1131 | return -1; | 1132 | return -1; |
1132 | } | 1133 | } |
1133 | 1134 | ||
1135 | /** | ||
1136 | * mpt_get_product_name - returns product string | ||
1137 | * @vendor: pci vendor id | ||
1138 | * @device: pci device id | ||
1139 | * @revision: pci revision id | ||
1140 | * @prod_name: string returned | ||
1141 | * | ||
1142 | * Returns product string displayed when driver loads, | ||
1143 | * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product | ||
1144 | * | ||
1145 | **/ | ||
1146 | static void | ||
1147 | mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name) | ||
1148 | { | ||
1149 | char *product_str = NULL; | ||
1150 | |||
1151 | if (vendor == PCI_VENDOR_ID_BROCADE) { | ||
1152 | switch (device) | ||
1153 | { | ||
1154 | case MPI_MANUFACTPAGE_DEVICEID_FC949E: | ||
1155 | switch (revision) | ||
1156 | { | ||
1157 | case 0x00: | ||
1158 | product_str = "BRE040 A0"; | ||
1159 | break; | ||
1160 | case 0x01: | ||
1161 | product_str = "BRE040 A1"; | ||
1162 | break; | ||
1163 | default: | ||
1164 | product_str = "BRE040"; | ||
1165 | break; | ||
1166 | } | ||
1167 | break; | ||
1168 | } | ||
1169 | goto out; | ||
1170 | } | ||
1171 | |||
1172 | switch (device) | ||
1173 | { | ||
1174 | case MPI_MANUFACTPAGE_DEVICEID_FC909: | ||
1175 | product_str = "LSIFC909 B1"; | ||
1176 | break; | ||
1177 | case MPI_MANUFACTPAGE_DEVICEID_FC919: | ||
1178 | product_str = "LSIFC919 B0"; | ||
1179 | break; | ||
1180 | case MPI_MANUFACTPAGE_DEVICEID_FC929: | ||
1181 | product_str = "LSIFC929 B0"; | ||
1182 | break; | ||
1183 | case MPI_MANUFACTPAGE_DEVICEID_FC919X: | ||
1184 | if (revision < 0x80) | ||
1185 | product_str = "LSIFC919X A0"; | ||
1186 | else | ||
1187 | product_str = "LSIFC919XL A1"; | ||
1188 | break; | ||
1189 | case MPI_MANUFACTPAGE_DEVICEID_FC929X: | ||
1190 | if (revision < 0x80) | ||
1191 | product_str = "LSIFC929X A0"; | ||
1192 | else | ||
1193 | product_str = "LSIFC929XL A1"; | ||
1194 | break; | ||
1195 | case MPI_MANUFACTPAGE_DEVICEID_FC939X: | ||
1196 | product_str = "LSIFC939X A1"; | ||
1197 | break; | ||
1198 | case MPI_MANUFACTPAGE_DEVICEID_FC949X: | ||
1199 | product_str = "LSIFC949X A1"; | ||
1200 | break; | ||
1201 | case MPI_MANUFACTPAGE_DEVICEID_FC949E: | ||
1202 | switch (revision) | ||
1203 | { | ||
1204 | case 0x00: | ||
1205 | product_str = "LSIFC949E A0"; | ||
1206 | break; | ||
1207 | case 0x01: | ||
1208 | product_str = "LSIFC949E A1"; | ||
1209 | break; | ||
1210 | default: | ||
1211 | product_str = "LSIFC949E"; | ||
1212 | break; | ||
1213 | } | ||
1214 | break; | ||
1215 | case MPI_MANUFACTPAGE_DEVID_53C1030: | ||
1216 | switch (revision) | ||
1217 | { | ||
1218 | case 0x00: | ||
1219 | product_str = "LSI53C1030 A0"; | ||
1220 | break; | ||
1221 | case 0x01: | ||
1222 | product_str = "LSI53C1030 B0"; | ||
1223 | break; | ||
1224 | case 0x03: | ||
1225 | product_str = "LSI53C1030 B1"; | ||
1226 | break; | ||
1227 | case 0x07: | ||
1228 | product_str = "LSI53C1030 B2"; | ||
1229 | break; | ||
1230 | case 0x08: | ||
1231 | product_str = "LSI53C1030 C0"; | ||
1232 | break; | ||
1233 | case 0x80: | ||
1234 | product_str = "LSI53C1030T A0"; | ||
1235 | break; | ||
1236 | case 0x83: | ||
1237 | product_str = "LSI53C1030T A2"; | ||
1238 | break; | ||
1239 | case 0x87: | ||
1240 | product_str = "LSI53C1030T A3"; | ||
1241 | break; | ||
1242 | case 0xc1: | ||
1243 | product_str = "LSI53C1020A A1"; | ||
1244 | break; | ||
1245 | default: | ||
1246 | product_str = "LSI53C1030"; | ||
1247 | break; | ||
1248 | } | ||
1249 | break; | ||
1250 | case MPI_MANUFACTPAGE_DEVID_1030_53C1035: | ||
1251 | switch (revision) | ||
1252 | { | ||
1253 | case 0x03: | ||
1254 | product_str = "LSI53C1035 A2"; | ||
1255 | break; | ||
1256 | case 0x04: | ||
1257 | product_str = "LSI53C1035 B0"; | ||
1258 | break; | ||
1259 | default: | ||
1260 | product_str = "LSI53C1035"; | ||
1261 | break; | ||
1262 | } | ||
1263 | break; | ||
1264 | case MPI_MANUFACTPAGE_DEVID_SAS1064: | ||
1265 | switch (revision) | ||
1266 | { | ||
1267 | case 0x00: | ||
1268 | product_str = "LSISAS1064 A1"; | ||
1269 | break; | ||
1270 | case 0x01: | ||
1271 | product_str = "LSISAS1064 A2"; | ||
1272 | break; | ||
1273 | case 0x02: | ||
1274 | product_str = "LSISAS1064 A3"; | ||
1275 | break; | ||
1276 | case 0x03: | ||
1277 | product_str = "LSISAS1064 A4"; | ||
1278 | break; | ||
1279 | default: | ||
1280 | product_str = "LSISAS1064"; | ||
1281 | break; | ||
1282 | } | ||
1283 | break; | ||
1284 | case MPI_MANUFACTPAGE_DEVID_SAS1064E: | ||
1285 | switch (revision) | ||
1286 | { | ||
1287 | case 0x00: | ||
1288 | product_str = "LSISAS1064E A0"; | ||
1289 | break; | ||
1290 | case 0x01: | ||
1291 | product_str = "LSISAS1064E B0"; | ||
1292 | break; | ||
1293 | case 0x02: | ||
1294 | product_str = "LSISAS1064E B1"; | ||
1295 | break; | ||
1296 | case 0x04: | ||
1297 | product_str = "LSISAS1064E B2"; | ||
1298 | break; | ||
1299 | case 0x08: | ||
1300 | product_str = "LSISAS1064E B3"; | ||
1301 | break; | ||
1302 | default: | ||
1303 | product_str = "LSISAS1064E"; | ||
1304 | break; | ||
1305 | } | ||
1306 | break; | ||
1307 | case MPI_MANUFACTPAGE_DEVID_SAS1068: | ||
1308 | switch (revision) | ||
1309 | { | ||
1310 | case 0x00: | ||
1311 | product_str = "LSISAS1068 A0"; | ||
1312 | break; | ||
1313 | case 0x01: | ||
1314 | product_str = "LSISAS1068 B0"; | ||
1315 | break; | ||
1316 | case 0x02: | ||
1317 | product_str = "LSISAS1068 B1"; | ||
1318 | break; | ||
1319 | default: | ||
1320 | product_str = "LSISAS1068"; | ||
1321 | break; | ||
1322 | } | ||
1323 | break; | ||
1324 | case MPI_MANUFACTPAGE_DEVID_SAS1068E: | ||
1325 | switch (revision) | ||
1326 | { | ||
1327 | case 0x00: | ||
1328 | product_str = "LSISAS1068E A0"; | ||
1329 | break; | ||
1330 | case 0x01: | ||
1331 | product_str = "LSISAS1068E B0"; | ||
1332 | break; | ||
1333 | case 0x02: | ||
1334 | product_str = "LSISAS1068E B1"; | ||
1335 | break; | ||
1336 | case 0x04: | ||
1337 | product_str = "LSISAS1068E B2"; | ||
1338 | break; | ||
1339 | case 0x08: | ||
1340 | product_str = "LSISAS1068E B3"; | ||
1341 | break; | ||
1342 | default: | ||
1343 | product_str = "LSISAS1068E"; | ||
1344 | break; | ||
1345 | } | ||
1346 | break; | ||
1347 | case MPI_MANUFACTPAGE_DEVID_SAS1078: | ||
1348 | switch (revision) | ||
1349 | { | ||
1350 | case 0x00: | ||
1351 | product_str = "LSISAS1078 A0"; | ||
1352 | break; | ||
1353 | case 0x01: | ||
1354 | product_str = "LSISAS1078 B0"; | ||
1355 | break; | ||
1356 | case 0x02: | ||
1357 | product_str = "LSISAS1078 C0"; | ||
1358 | break; | ||
1359 | case 0x03: | ||
1360 | product_str = "LSISAS1078 C1"; | ||
1361 | break; | ||
1362 | case 0x04: | ||
1363 | product_str = "LSISAS1078 C2"; | ||
1364 | break; | ||
1365 | default: | ||
1366 | product_str = "LSISAS1078"; | ||
1367 | break; | ||
1368 | } | ||
1369 | break; | ||
1370 | } | ||
1371 | |||
1372 | out: | ||
1373 | if (product_str) | ||
1374 | sprintf(prod_name, "%s", product_str); | ||
1375 | } | ||
1376 | |||
1134 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 1377 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
1135 | /** | 1378 | /** |
1136 | * mpt_attach - Install a PCI intelligent MPT adapter. | 1379 | * mpt_attach - Install a PCI intelligent MPT adapter. |
@@ -1274,23 +1517,23 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1274 | ioc->pio_chip = (SYSIF_REGS __iomem *)pmem; | 1517 | ioc->pio_chip = (SYSIF_REGS __iomem *)pmem; |
1275 | } | 1518 | } |
1276 | 1519 | ||
1277 | if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC909) { | 1520 | pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); |
1278 | ioc->prod_name = "LSIFC909"; | 1521 | mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name); |
1279 | ioc->bus_type = FC; | 1522 | |
1280 | } | 1523 | switch (pdev->device) |
1281 | else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) { | 1524 | { |
1282 | ioc->prod_name = "LSIFC929"; | 1525 | case MPI_MANUFACTPAGE_DEVICEID_FC939X: |
1283 | ioc->bus_type = FC; | 1526 | case MPI_MANUFACTPAGE_DEVICEID_FC949X: |
1284 | } | 1527 | ioc->errata_flag_1064 = 1; |
1285 | else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919) { | 1528 | case MPI_MANUFACTPAGE_DEVICEID_FC909: |
1286 | ioc->prod_name = "LSIFC919"; | 1529 | case MPI_MANUFACTPAGE_DEVICEID_FC929: |
1287 | ioc->bus_type = FC; | 1530 | case MPI_MANUFACTPAGE_DEVICEID_FC919: |
1288 | } | 1531 | case MPI_MANUFACTPAGE_DEVICEID_FC949E: |
1289 | else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929X) { | ||
1290 | pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); | ||
1291 | ioc->bus_type = FC; | 1532 | ioc->bus_type = FC; |
1533 | break; | ||
1534 | |||
1535 | case MPI_MANUFACTPAGE_DEVICEID_FC929X: | ||
1292 | if (revision < XL_929) { | 1536 | if (revision < XL_929) { |
1293 | ioc->prod_name = "LSIFC929X"; | ||
1294 | /* 929X Chip Fix. Set Split transactions level | 1537 | /* 929X Chip Fix. Set Split transactions level |
1295 | * for PCIX. Set MOST bits to zero. | 1538 | * for PCIX. Set MOST bits to zero. |
1296 | */ | 1539 | */ |
@@ -1298,75 +1541,46 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1298 | pcixcmd &= 0x8F; | 1541 | pcixcmd &= 0x8F; |
1299 | pci_write_config_byte(pdev, 0x6a, pcixcmd); | 1542 | pci_write_config_byte(pdev, 0x6a, pcixcmd); |
1300 | } else { | 1543 | } else { |
1301 | ioc->prod_name = "LSIFC929XL"; | ||
1302 | /* 929XL Chip Fix. Set MMRBC to 0x08. | 1544 | /* 929XL Chip Fix. Set MMRBC to 0x08. |
1303 | */ | 1545 | */ |
1304 | pci_read_config_byte(pdev, 0x6a, &pcixcmd); | 1546 | pci_read_config_byte(pdev, 0x6a, &pcixcmd); |
1305 | pcixcmd |= 0x08; | 1547 | pcixcmd |= 0x08; |
1306 | pci_write_config_byte(pdev, 0x6a, pcixcmd); | 1548 | pci_write_config_byte(pdev, 0x6a, pcixcmd); |
1307 | } | 1549 | } |
1308 | } | ||
1309 | else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919X) { | ||
1310 | ioc->prod_name = "LSIFC919X"; | ||
1311 | ioc->bus_type = FC; | 1550 | ioc->bus_type = FC; |
1551 | break; | ||
1552 | |||
1553 | case MPI_MANUFACTPAGE_DEVICEID_FC919X: | ||
1312 | /* 919X Chip Fix. Set Split transactions level | 1554 | /* 919X Chip Fix. Set Split transactions level |
1313 | * for PCIX. Set MOST bits to zero. | 1555 | * for PCIX. Set MOST bits to zero. |
1314 | */ | 1556 | */ |
1315 | pci_read_config_byte(pdev, 0x6a, &pcixcmd); | 1557 | pci_read_config_byte(pdev, 0x6a, &pcixcmd); |
1316 | pcixcmd &= 0x8F; | 1558 | pcixcmd &= 0x8F; |
1317 | pci_write_config_byte(pdev, 0x6a, pcixcmd); | 1559 | pci_write_config_byte(pdev, 0x6a, pcixcmd); |
1318 | } | ||
1319 | else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC939X) { | ||
1320 | ioc->prod_name = "LSIFC939X"; | ||
1321 | ioc->bus_type = FC; | ||
1322 | ioc->errata_flag_1064 = 1; | ||
1323 | } | ||
1324 | else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949X) { | ||
1325 | ioc->prod_name = "LSIFC949X"; | ||
1326 | ioc->bus_type = FC; | 1560 | ioc->bus_type = FC; |
1327 | ioc->errata_flag_1064 = 1; | 1561 | break; |
1328 | } | 1562 | |
1329 | else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949E) { | 1563 | case MPI_MANUFACTPAGE_DEVID_53C1030: |
1330 | ioc->prod_name = "LSIFC949E"; | ||
1331 | ioc->bus_type = FC; | ||
1332 | } | ||
1333 | else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) { | ||
1334 | ioc->prod_name = "LSI53C1030"; | ||
1335 | ioc->bus_type = SPI; | ||
1336 | /* 1030 Chip Fix. Disable Split transactions | 1564 | /* 1030 Chip Fix. Disable Split transactions |
1337 | * for PCIX. Set MOST bits to zero if Rev < C0( = 8). | 1565 | * for PCIX. Set MOST bits to zero if Rev < C0( = 8). |
1338 | */ | 1566 | */ |
1339 | pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); | ||
1340 | if (revision < C0_1030) { | 1567 | if (revision < C0_1030) { |
1341 | pci_read_config_byte(pdev, 0x6a, &pcixcmd); | 1568 | pci_read_config_byte(pdev, 0x6a, &pcixcmd); |
1342 | pcixcmd &= 0x8F; | 1569 | pcixcmd &= 0x8F; |
1343 | pci_write_config_byte(pdev, 0x6a, pcixcmd); | 1570 | pci_write_config_byte(pdev, 0x6a, pcixcmd); |
1344 | } | 1571 | } |
1345 | } | 1572 | |
1346 | else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) { | 1573 | case MPI_MANUFACTPAGE_DEVID_1030_53C1035: |
1347 | ioc->prod_name = "LSI53C1035"; | ||
1348 | ioc->bus_type = SPI; | 1574 | ioc->bus_type = SPI; |
1349 | } | 1575 | break; |
1350 | else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064) { | 1576 | |
1351 | ioc->prod_name = "LSISAS1064"; | 1577 | case MPI_MANUFACTPAGE_DEVID_SAS1064: |
1352 | ioc->bus_type = SAS; | 1578 | case MPI_MANUFACTPAGE_DEVID_SAS1068: |
1353 | ioc->errata_flag_1064 = 1; | ||
1354 | } | ||
1355 | else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068) { | ||
1356 | ioc->prod_name = "LSISAS1068"; | ||
1357 | ioc->bus_type = SAS; | ||
1358 | ioc->errata_flag_1064 = 1; | 1579 | ioc->errata_flag_1064 = 1; |
1359 | } | 1580 | |
1360 | else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064E) { | 1581 | case MPI_MANUFACTPAGE_DEVID_SAS1064E: |
1361 | ioc->prod_name = "LSISAS1064E"; | 1582 | case MPI_MANUFACTPAGE_DEVID_SAS1068E: |
1362 | ioc->bus_type = SAS; | 1583 | case MPI_MANUFACTPAGE_DEVID_SAS1078: |
1363 | } | ||
1364 | else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068E) { | ||
1365 | ioc->prod_name = "LSISAS1068E"; | ||
1366 | ioc->bus_type = SAS; | ||
1367 | } | ||
1368 | else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) { | ||
1369 | ioc->prod_name = "LSISAS1078"; | ||
1370 | ioc->bus_type = SAS; | 1584 | ioc->bus_type = SAS; |
1371 | } | 1585 | } |
1372 | 1586 | ||
@@ -1880,6 +2094,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) | |||
1880 | } | 2094 | } |
1881 | 2095 | ||
1882 | GetIoUnitPage2(ioc); | 2096 | GetIoUnitPage2(ioc); |
2097 | mpt_get_manufacturing_pg_0(ioc); | ||
1883 | } | 2098 | } |
1884 | 2099 | ||
1885 | /* | 2100 | /* |
@@ -2138,8 +2353,8 @@ MptDisplayIocCapabilities(MPT_ADAPTER *ioc) | |||
2138 | int i = 0; | 2353 | int i = 0; |
2139 | 2354 | ||
2140 | printk(KERN_INFO "%s: ", ioc->name); | 2355 | printk(KERN_INFO "%s: ", ioc->name); |
2141 | if (ioc->prod_name && strlen(ioc->prod_name) > 3) | 2356 | if (ioc->prod_name) |
2142 | printk("%s: ", ioc->prod_name+3); | 2357 | printk("%s: ", ioc->prod_name); |
2143 | printk("Capabilities={"); | 2358 | printk("Capabilities={"); |
2144 | 2359 | ||
2145 | if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) { | 2360 | if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) { |
@@ -5190,6 +5405,49 @@ mpt_read_ioc_pg_1(MPT_ADAPTER *ioc) | |||
5190 | return; | 5405 | return; |
5191 | } | 5406 | } |
5192 | 5407 | ||
5408 | static void | ||
5409 | mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc) | ||
5410 | { | ||
5411 | CONFIGPARMS cfg; | ||
5412 | ConfigPageHeader_t hdr; | ||
5413 | dma_addr_t buf_dma; | ||
5414 | ManufacturingPage0_t *pbuf = NULL; | ||
5415 | |||
5416 | memset(&cfg, 0 , sizeof(CONFIGPARMS)); | ||
5417 | memset(&hdr, 0 , sizeof(ConfigPageHeader_t)); | ||
5418 | |||
5419 | hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING; | ||
5420 | cfg.cfghdr.hdr = &hdr; | ||
5421 | cfg.physAddr = -1; | ||
5422 | cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; | ||
5423 | cfg.timeout = 10; | ||
5424 | |||
5425 | if (mpt_config(ioc, &cfg) != 0) | ||
5426 | goto out; | ||
5427 | |||
5428 | if (!cfg.cfghdr.hdr->PageLength) | ||
5429 | goto out; | ||
5430 | |||
5431 | cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; | ||
5432 | pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma); | ||
5433 | if (!pbuf) | ||
5434 | goto out; | ||
5435 | |||
5436 | cfg.physAddr = buf_dma; | ||
5437 | |||
5438 | if (mpt_config(ioc, &cfg) != 0) | ||
5439 | goto out; | ||
5440 | |||
5441 | memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name)); | ||
5442 | memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly)); | ||
5443 | memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer)); | ||
5444 | |||
5445 | out: | ||
5446 | |||
5447 | if (pbuf) | ||
5448 | pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma); | ||
5449 | } | ||
5450 | |||
5193 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 5451 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
5194 | /** | 5452 | /** |
5195 | * SendEventNotification - Send EventNotification (on or off) request to adapter | 5453 | * SendEventNotification - Send EventNotification (on or off) request to adapter |
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index 05eb6e528753..98eb9c688e17 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h | |||
@@ -537,7 +537,14 @@ typedef struct _MPT_ADAPTER | |||
537 | int id; /* Unique adapter id N {0,1,2,...} */ | 537 | int id; /* Unique adapter id N {0,1,2,...} */ |
538 | int pci_irq; /* This irq */ | 538 | int pci_irq; /* This irq */ |
539 | char name[MPT_NAME_LENGTH]; /* "iocN" */ | 539 | char name[MPT_NAME_LENGTH]; /* "iocN" */ |
540 | char *prod_name; /* "LSIFC9x9" */ | 540 | char prod_name[MPT_NAME_LENGTH]; /* "LSIFC9x9" */ |
541 | char board_name[16]; | ||
542 | char board_assembly[16]; | ||
543 | char board_tracer[16]; | ||
544 | u16 nvdata_version_persistent; | ||
545 | u16 nvdata_version_default; | ||
546 | u8 io_missing_delay; | ||
547 | u8 device_missing_delay; | ||
541 | SYSIF_REGS __iomem *chip; /* == c8817000 (mmap) */ | 548 | SYSIF_REGS __iomem *chip; /* == c8817000 (mmap) */ |
542 | SYSIF_REGS __iomem *pio_chip; /* Programmed IO (downloadboot) */ | 549 | SYSIF_REGS __iomem *pio_chip; /* Programmed IO (downloadboot) */ |
543 | u8 bus_type; | 550 | u8 bus_type; |
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index b766445f19aa..f2ebaa9992fe 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c | |||
@@ -130,6 +130,7 @@ static struct scsi_host_template mptfc_driver_template = { | |||
130 | .max_sectors = 8192, | 130 | .max_sectors = 8192, |
131 | .cmd_per_lun = 7, | 131 | .cmd_per_lun = 7, |
132 | .use_clustering = ENABLE_CLUSTERING, | 132 | .use_clustering = ENABLE_CLUSTERING, |
133 | .shost_attrs = mptscsih_host_attrs, | ||
133 | }; | 134 | }; |
134 | 135 | ||
135 | /**************************************************************************** | 136 | /**************************************************************************** |
@@ -153,6 +154,8 @@ static struct pci_device_id mptfc_pci_table[] = { | |||
153 | PCI_ANY_ID, PCI_ANY_ID }, | 154 | PCI_ANY_ID, PCI_ANY_ID }, |
154 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC949E, | 155 | { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC949E, |
155 | PCI_ANY_ID, PCI_ANY_ID }, | 156 | PCI_ANY_ID, PCI_ANY_ID }, |
157 | { PCI_VENDOR_ID_BROCADE, MPI_MANUFACTPAGE_DEVICEID_FC949E, | ||
158 | PCI_ANY_ID, PCI_ANY_ID }, | ||
156 | {0} /* Terminating entry */ | 159 | {0} /* Terminating entry */ |
157 | }; | 160 | }; |
158 | MODULE_DEVICE_TABLE(pci, mptfc_pci_table); | 161 | MODULE_DEVICE_TABLE(pci, mptfc_pci_table); |
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 9e5424e1871f..d50664640512 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c | |||
@@ -1119,6 +1119,7 @@ static struct scsi_host_template mptsas_driver_template = { | |||
1119 | .max_sectors = 8192, | 1119 | .max_sectors = 8192, |
1120 | .cmd_per_lun = 7, | 1120 | .cmd_per_lun = 7, |
1121 | .use_clustering = ENABLE_CLUSTERING, | 1121 | .use_clustering = ENABLE_CLUSTERING, |
1122 | .shost_attrs = mptscsih_host_attrs, | ||
1122 | }; | 1123 | }; |
1123 | 1124 | ||
1124 | static int mptsas_get_linkerrors(struct sas_phy *phy) | 1125 | static int mptsas_get_linkerrors(struct sas_phy *phy) |
@@ -1390,6 +1391,11 @@ mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) | |||
1390 | goto out_free_consistent; | 1391 | goto out_free_consistent; |
1391 | } | 1392 | } |
1392 | 1393 | ||
1394 | ioc->nvdata_version_persistent = | ||
1395 | le16_to_cpu(buffer->NvdataVersionPersistent); | ||
1396 | ioc->nvdata_version_default = | ||
1397 | le16_to_cpu(buffer->NvdataVersionDefault); | ||
1398 | |||
1393 | for (i = 0; i < port_info->num_phys; i++) { | 1399 | for (i = 0; i < port_info->num_phys; i++) { |
1394 | mptsas_print_phy_data(&buffer->PhyData[i]); | 1400 | mptsas_print_phy_data(&buffer->PhyData[i]); |
1395 | port_info->phy_info[i].phy_id = i; | 1401 | port_info->phy_info[i].phy_id = i; |
@@ -1410,6 +1416,63 @@ mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) | |||
1410 | } | 1416 | } |
1411 | 1417 | ||
1412 | static int | 1418 | static int |
1419 | mptsas_sas_io_unit_pg1(MPT_ADAPTER *ioc) | ||
1420 | { | ||
1421 | ConfigExtendedPageHeader_t hdr; | ||
1422 | CONFIGPARMS cfg; | ||
1423 | SasIOUnitPage1_t *buffer; | ||
1424 | dma_addr_t dma_handle; | ||
1425 | int error; | ||
1426 | u16 device_missing_delay; | ||
1427 | |||
1428 | memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t)); | ||
1429 | memset(&cfg, 0, sizeof(CONFIGPARMS)); | ||
1430 | |||
1431 | cfg.cfghdr.ehdr = &hdr; | ||
1432 | cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; | ||
1433 | cfg.timeout = 10; | ||
1434 | cfg.cfghdr.ehdr->PageType = MPI_CONFIG_PAGETYPE_EXTENDED; | ||
1435 | cfg.cfghdr.ehdr->ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; | ||
1436 | cfg.cfghdr.ehdr->PageVersion = MPI_SASIOUNITPAGE1_PAGEVERSION; | ||
1437 | cfg.cfghdr.ehdr->PageNumber = 1; | ||
1438 | |||
1439 | error = mpt_config(ioc, &cfg); | ||
1440 | if (error) | ||
1441 | goto out; | ||
1442 | if (!hdr.ExtPageLength) { | ||
1443 | error = -ENXIO; | ||
1444 | goto out; | ||
1445 | } | ||
1446 | |||
1447 | buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4, | ||
1448 | &dma_handle); | ||
1449 | if (!buffer) { | ||
1450 | error = -ENOMEM; | ||
1451 | goto out; | ||
1452 | } | ||
1453 | |||
1454 | cfg.physAddr = dma_handle; | ||
1455 | cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; | ||
1456 | |||
1457 | error = mpt_config(ioc, &cfg); | ||
1458 | if (error) | ||
1459 | goto out_free_consistent; | ||
1460 | |||
1461 | ioc->io_missing_delay = | ||
1462 | le16_to_cpu(buffer->IODeviceMissingDelay); | ||
1463 | device_missing_delay = le16_to_cpu(buffer->ReportDeviceMissingDelay); | ||
1464 | ioc->device_missing_delay = (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16) ? | ||
1465 | (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16 : | ||
1466 | device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK; | ||
1467 | |||
1468 | out_free_consistent: | ||
1469 | pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4, | ||
1470 | buffer, dma_handle); | ||
1471 | out: | ||
1472 | return error; | ||
1473 | } | ||
1474 | |||
1475 | static int | ||
1413 | mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, | 1476 | mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, |
1414 | u32 form, u32 form_specific) | 1477 | u32 form, u32 form_specific) |
1415 | { | 1478 | { |
@@ -1990,6 +2053,7 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc) | |||
1990 | if (error) | 2053 | if (error) |
1991 | goto out_free_port_info; | 2054 | goto out_free_port_info; |
1992 | 2055 | ||
2056 | mptsas_sas_io_unit_pg1(ioc); | ||
1993 | mutex_lock(&ioc->sas_topology_mutex); | 2057 | mutex_lock(&ioc->sas_topology_mutex); |
1994 | ioc->handle = hba->phy_info[0].handle; | 2058 | ioc->handle = hba->phy_info[0].handle; |
1995 | port_info = mptsas_find_portinfo_by_handle(ioc, ioc->handle); | 2059 | port_info = mptsas_find_portinfo_by_handle(ioc, ioc->handle); |
@@ -3237,6 +3301,8 @@ static struct pci_driver mptsas_driver = { | |||
3237 | static int __init | 3301 | static int __init |
3238 | mptsas_init(void) | 3302 | mptsas_init(void) |
3239 | { | 3303 | { |
3304 | int error; | ||
3305 | |||
3240 | show_mptmod_ver(my_NAME, my_VERSION); | 3306 | show_mptmod_ver(my_NAME, my_VERSION); |
3241 | 3307 | ||
3242 | mptsas_transport_template = | 3308 | mptsas_transport_template = |
@@ -3260,7 +3326,11 @@ mptsas_init(void) | |||
3260 | ": Registered for IOC reset notifications\n")); | 3326 | ": Registered for IOC reset notifications\n")); |
3261 | } | 3327 | } |
3262 | 3328 | ||
3263 | return pci_register_driver(&mptsas_driver); | 3329 | error = pci_register_driver(&mptsas_driver); |
3330 | if (error) | ||
3331 | sas_release_transport(mptsas_transport_template); | ||
3332 | |||
3333 | return error; | ||
3264 | } | 3334 | } |
3265 | 3335 | ||
3266 | static void __exit | 3336 | static void __exit |
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index d35617376f87..fd3aa2619f42 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c | |||
@@ -3187,6 +3187,159 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice) | |||
3187 | mptscsih_do_cmd(hd, &iocmd); | 3187 | mptscsih_do_cmd(hd, &iocmd); |
3188 | } | 3188 | } |
3189 | 3189 | ||
3190 | static ssize_t | ||
3191 | mptscsih_version_fw_show(struct class_device *cdev, char *buf) | ||
3192 | { | ||
3193 | struct Scsi_Host *host = class_to_shost(cdev); | ||
3194 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; | ||
3195 | MPT_ADAPTER *ioc = hd->ioc; | ||
3196 | |||
3197 | return snprintf(buf, PAGE_SIZE, "%02d.%02d.%02d.%02d\n", | ||
3198 | (ioc->facts.FWVersion.Word & 0xFF000000) >> 24, | ||
3199 | (ioc->facts.FWVersion.Word & 0x00FF0000) >> 16, | ||
3200 | (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8, | ||
3201 | ioc->facts.FWVersion.Word & 0x000000FF); | ||
3202 | } | ||
3203 | static CLASS_DEVICE_ATTR(version_fw, S_IRUGO, mptscsih_version_fw_show, NULL); | ||
3204 | |||
3205 | static ssize_t | ||
3206 | mptscsih_version_bios_show(struct class_device *cdev, char *buf) | ||
3207 | { | ||
3208 | struct Scsi_Host *host = class_to_shost(cdev); | ||
3209 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; | ||
3210 | MPT_ADAPTER *ioc = hd->ioc; | ||
3211 | |||
3212 | return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n", | ||
3213 | (ioc->biosVersion & 0xFF000000) >> 24, | ||
3214 | (ioc->biosVersion & 0x00FF0000) >> 16, | ||
3215 | (ioc->biosVersion & 0x0000FF00) >> 8, | ||
3216 | ioc->biosVersion & 0x000000FF); | ||
3217 | } | ||
3218 | static CLASS_DEVICE_ATTR(version_bios, S_IRUGO, mptscsih_version_bios_show, NULL); | ||
3219 | |||
3220 | static ssize_t | ||
3221 | mptscsih_version_mpi_show(struct class_device *cdev, char *buf) | ||
3222 | { | ||
3223 | struct Scsi_Host *host = class_to_shost(cdev); | ||
3224 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; | ||
3225 | MPT_ADAPTER *ioc = hd->ioc; | ||
3226 | |||
3227 | return snprintf(buf, PAGE_SIZE, "%03x\n", ioc->facts.MsgVersion); | ||
3228 | } | ||
3229 | static CLASS_DEVICE_ATTR(version_mpi, S_IRUGO, mptscsih_version_mpi_show, NULL); | ||
3230 | |||
3231 | static ssize_t | ||
3232 | mptscsih_version_product_show(struct class_device *cdev, char *buf) | ||
3233 | { | ||
3234 | struct Scsi_Host *host = class_to_shost(cdev); | ||
3235 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; | ||
3236 | MPT_ADAPTER *ioc = hd->ioc; | ||
3237 | |||
3238 | return snprintf(buf, PAGE_SIZE, "%s\n", ioc->prod_name); | ||
3239 | } | ||
3240 | static CLASS_DEVICE_ATTR(version_product, S_IRUGO, | ||
3241 | mptscsih_version_product_show, NULL); | ||
3242 | |||
3243 | static ssize_t | ||
3244 | mptscsih_version_nvdata_persistent_show(struct class_device *cdev, char *buf) | ||
3245 | { | ||
3246 | struct Scsi_Host *host = class_to_shost(cdev); | ||
3247 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; | ||
3248 | MPT_ADAPTER *ioc = hd->ioc; | ||
3249 | |||
3250 | return snprintf(buf, PAGE_SIZE, "%02xh\n", | ||
3251 | ioc->nvdata_version_persistent); | ||
3252 | } | ||
3253 | static CLASS_DEVICE_ATTR(version_nvdata_persistent, S_IRUGO, | ||
3254 | mptscsih_version_nvdata_persistent_show, NULL); | ||
3255 | |||
3256 | static ssize_t | ||
3257 | mptscsih_version_nvdata_default_show(struct class_device *cdev, char *buf) | ||
3258 | { | ||
3259 | struct Scsi_Host *host = class_to_shost(cdev); | ||
3260 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; | ||
3261 | MPT_ADAPTER *ioc = hd->ioc; | ||
3262 | |||
3263 | return snprintf(buf, PAGE_SIZE, "%02xh\n",ioc->nvdata_version_default); | ||
3264 | } | ||
3265 | static CLASS_DEVICE_ATTR(version_nvdata_default, S_IRUGO, | ||
3266 | mptscsih_version_nvdata_default_show, NULL); | ||
3267 | |||
3268 | static ssize_t | ||
3269 | mptscsih_board_name_show(struct class_device *cdev, char *buf) | ||
3270 | { | ||
3271 | struct Scsi_Host *host = class_to_shost(cdev); | ||
3272 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; | ||
3273 | MPT_ADAPTER *ioc = hd->ioc; | ||
3274 | |||
3275 | return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_name); | ||
3276 | } | ||
3277 | static CLASS_DEVICE_ATTR(board_name, S_IRUGO, mptscsih_board_name_show, NULL); | ||
3278 | |||
3279 | static ssize_t | ||
3280 | mptscsih_board_assembly_show(struct class_device *cdev, char *buf) | ||
3281 | { | ||
3282 | struct Scsi_Host *host = class_to_shost(cdev); | ||
3283 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; | ||
3284 | MPT_ADAPTER *ioc = hd->ioc; | ||
3285 | |||
3286 | return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_assembly); | ||
3287 | } | ||
3288 | static CLASS_DEVICE_ATTR(board_assembly, S_IRUGO, | ||
3289 | mptscsih_board_assembly_show, NULL); | ||
3290 | |||
3291 | static ssize_t | ||
3292 | mptscsih_board_tracer_show(struct class_device *cdev, char *buf) | ||
3293 | { | ||
3294 | struct Scsi_Host *host = class_to_shost(cdev); | ||
3295 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; | ||
3296 | MPT_ADAPTER *ioc = hd->ioc; | ||
3297 | |||
3298 | return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_tracer); | ||
3299 | } | ||
3300 | static CLASS_DEVICE_ATTR(board_tracer, S_IRUGO, | ||
3301 | mptscsih_board_tracer_show, NULL); | ||
3302 | |||
3303 | static ssize_t | ||
3304 | mptscsih_io_delay_show(struct class_device *cdev, char *buf) | ||
3305 | { | ||
3306 | struct Scsi_Host *host = class_to_shost(cdev); | ||
3307 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; | ||
3308 | MPT_ADAPTER *ioc = hd->ioc; | ||
3309 | |||
3310 | return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->io_missing_delay); | ||
3311 | } | ||
3312 | static CLASS_DEVICE_ATTR(io_delay, S_IRUGO, | ||
3313 | mptscsih_io_delay_show, NULL); | ||
3314 | |||
3315 | static ssize_t | ||
3316 | mptscsih_device_delay_show(struct class_device *cdev, char *buf) | ||
3317 | { | ||
3318 | struct Scsi_Host *host = class_to_shost(cdev); | ||
3319 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; | ||
3320 | MPT_ADAPTER *ioc = hd->ioc; | ||
3321 | |||
3322 | return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->device_missing_delay); | ||
3323 | } | ||
3324 | static CLASS_DEVICE_ATTR(device_delay, S_IRUGO, | ||
3325 | mptscsih_device_delay_show, NULL); | ||
3326 | |||
3327 | struct class_device_attribute *mptscsih_host_attrs[] = { | ||
3328 | &class_device_attr_version_fw, | ||
3329 | &class_device_attr_version_bios, | ||
3330 | &class_device_attr_version_mpi, | ||
3331 | &class_device_attr_version_product, | ||
3332 | &class_device_attr_version_nvdata_persistent, | ||
3333 | &class_device_attr_version_nvdata_default, | ||
3334 | &class_device_attr_board_name, | ||
3335 | &class_device_attr_board_assembly, | ||
3336 | &class_device_attr_board_tracer, | ||
3337 | &class_device_attr_io_delay, | ||
3338 | &class_device_attr_device_delay, | ||
3339 | NULL, | ||
3340 | }; | ||
3341 | EXPORT_SYMBOL(mptscsih_host_attrs); | ||
3342 | |||
3190 | EXPORT_SYMBOL(mptscsih_remove); | 3343 | EXPORT_SYMBOL(mptscsih_remove); |
3191 | EXPORT_SYMBOL(mptscsih_shutdown); | 3344 | EXPORT_SYMBOL(mptscsih_shutdown); |
3192 | #ifdef CONFIG_PM | 3345 | #ifdef CONFIG_PM |
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h index 8eccdfe5701a..67b088db2f10 100644 --- a/drivers/message/fusion/mptscsih.h +++ b/drivers/message/fusion/mptscsih.h | |||
@@ -129,3 +129,4 @@ extern void mptscsih_timer_expired(unsigned long data); | |||
129 | extern int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout); | 129 | extern int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout); |
130 | extern u8 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id); | 130 | extern u8 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id); |
131 | extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id); | 131 | extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id); |
132 | extern struct class_device_attribute *mptscsih_host_attrs[]; | ||
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 6b3e0c00952b..947fe2901800 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c | |||
@@ -821,6 +821,7 @@ static struct scsi_host_template mptspi_driver_template = { | |||
821 | .max_sectors = 8192, | 821 | .max_sectors = 8192, |
822 | .cmd_per_lun = 7, | 822 | .cmd_per_lun = 7, |
823 | .use_clustering = ENABLE_CLUSTERING, | 823 | .use_clustering = ENABLE_CLUSTERING, |
824 | .shost_attrs = mptscsih_host_attrs, | ||
824 | }; | 825 | }; |
825 | 826 | ||
826 | static int mptspi_write_spi_device_pg1(struct scsi_target *starget, | 827 | static int mptspi_write_spi_device_pg1(struct scsi_target *starget, |
@@ -1523,6 +1524,8 @@ static struct pci_driver mptspi_driver = { | |||
1523 | static int __init | 1524 | static int __init |
1524 | mptspi_init(void) | 1525 | mptspi_init(void) |
1525 | { | 1526 | { |
1527 | int error; | ||
1528 | |||
1526 | show_mptmod_ver(my_NAME, my_VERSION); | 1529 | show_mptmod_ver(my_NAME, my_VERSION); |
1527 | 1530 | ||
1528 | mptspi_transport_template = spi_attach_transport(&mptspi_transport_functions); | 1531 | mptspi_transport_template = spi_attach_transport(&mptspi_transport_functions); |
@@ -1543,7 +1546,11 @@ mptspi_init(void) | |||
1543 | ": Registered for IOC reset notifications\n")); | 1546 | ": Registered for IOC reset notifications\n")); |
1544 | } | 1547 | } |
1545 | 1548 | ||
1546 | return pci_register_driver(&mptspi_driver); | 1549 | error = pci_register_driver(&mptspi_driver); |
1550 | if (error) | ||
1551 | spi_release_transport(mptspi_transport_template); | ||
1552 | |||
1553 | return error; | ||
1547 | } | 1554 | } |
1548 | 1555 | ||
1549 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 1556 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 1d516f24ba53..aaaa61ea4217 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
@@ -150,6 +150,7 @@ config THINKPAD_ACPI | |||
150 | depends on X86 && ACPI | 150 | depends on X86 && ACPI |
151 | select BACKLIGHT_CLASS_DEVICE | 151 | select BACKLIGHT_CLASS_DEVICE |
152 | select HWMON | 152 | select HWMON |
153 | select NVRAM | ||
153 | ---help--- | 154 | ---help--- |
154 | This is a driver for the IBM and Lenovo ThinkPad laptops. It adds | 155 | This is a driver for the IBM and Lenovo ThinkPad laptops. It adds |
155 | support for Fn-Fx key combinations, Bluetooth control, video | 156 | support for Fn-Fx key combinations, Bluetooth control, video |
@@ -196,4 +197,17 @@ config THINKPAD_ACPI_BAY | |||
196 | 197 | ||
197 | If you are not sure, say Y here. | 198 | If you are not sure, say Y here. |
198 | 199 | ||
200 | config THINKPAD_ACPI_INPUT_ENABLED | ||
201 | bool "Enable input layer support by default" | ||
202 | depends on THINKPAD_ACPI | ||
203 | default y | ||
204 | ---help--- | ||
205 | Enables hot key handling over the input layer by default. If unset, | ||
206 | the driver does not enable any hot key handling by default, and also | ||
207 | starts up with a mostly empty keymap. | ||
208 | |||
209 | If you are not sure, say Y here. Say N to retain the deprecated | ||
210 | behavior of ibm-acpi, and thinkpad-acpi for kernels up to 2.6.21. | ||
211 | |||
212 | |||
199 | endif # MISC_DEVICES | 213 | endif # MISC_DEVICES |
diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c index f75306059971..6b89854bd3ff 100644 --- a/drivers/misc/asus-laptop.c +++ b/drivers/misc/asus-laptop.c | |||
@@ -1067,19 +1067,16 @@ static void asus_backlight_exit(void) | |||
1067 | } | 1067 | } |
1068 | 1068 | ||
1069 | #define ASUS_LED_UNREGISTER(object) \ | 1069 | #define ASUS_LED_UNREGISTER(object) \ |
1070 | if(object##_led.class_dev \ | 1070 | led_classdev_unregister(&object##_led) |
1071 | && !IS_ERR(object##_led.class_dev)) \ | ||
1072 | led_classdev_unregister(&object##_led) | ||
1073 | 1071 | ||
1074 | static void asus_led_exit(void) | 1072 | static void asus_led_exit(void) |
1075 | { | 1073 | { |
1074 | destroy_workqueue(led_workqueue); | ||
1076 | ASUS_LED_UNREGISTER(mled); | 1075 | ASUS_LED_UNREGISTER(mled); |
1077 | ASUS_LED_UNREGISTER(tled); | 1076 | ASUS_LED_UNREGISTER(tled); |
1078 | ASUS_LED_UNREGISTER(pled); | 1077 | ASUS_LED_UNREGISTER(pled); |
1079 | ASUS_LED_UNREGISTER(rled); | 1078 | ASUS_LED_UNREGISTER(rled); |
1080 | ASUS_LED_UNREGISTER(gled); | 1079 | ASUS_LED_UNREGISTER(gled); |
1081 | |||
1082 | destroy_workqueue(led_workqueue); | ||
1083 | } | 1080 | } |
1084 | 1081 | ||
1085 | static void __exit asus_laptop_exit(void) | 1082 | static void __exit asus_laptop_exit(void) |
@@ -1135,29 +1132,42 @@ static int asus_led_init(struct device *dev) | |||
1135 | 1132 | ||
1136 | rv = ASUS_LED_REGISTER(mled, dev); | 1133 | rv = ASUS_LED_REGISTER(mled, dev); |
1137 | if (rv) | 1134 | if (rv) |
1138 | return rv; | 1135 | goto out; |
1139 | 1136 | ||
1140 | rv = ASUS_LED_REGISTER(tled, dev); | 1137 | rv = ASUS_LED_REGISTER(tled, dev); |
1141 | if (rv) | 1138 | if (rv) |
1142 | return rv; | 1139 | goto out1; |
1143 | 1140 | ||
1144 | rv = ASUS_LED_REGISTER(rled, dev); | 1141 | rv = ASUS_LED_REGISTER(rled, dev); |
1145 | if (rv) | 1142 | if (rv) |
1146 | return rv; | 1143 | goto out2; |
1147 | 1144 | ||
1148 | rv = ASUS_LED_REGISTER(pled, dev); | 1145 | rv = ASUS_LED_REGISTER(pled, dev); |
1149 | if (rv) | 1146 | if (rv) |
1150 | return rv; | 1147 | goto out3; |
1151 | 1148 | ||
1152 | rv = ASUS_LED_REGISTER(gled, dev); | 1149 | rv = ASUS_LED_REGISTER(gled, dev); |
1153 | if (rv) | 1150 | if (rv) |
1154 | return rv; | 1151 | goto out4; |
1155 | 1152 | ||
1156 | led_workqueue = create_singlethread_workqueue("led_workqueue"); | 1153 | led_workqueue = create_singlethread_workqueue("led_workqueue"); |
1157 | if (!led_workqueue) | 1154 | if (!led_workqueue) |
1158 | return -ENOMEM; | 1155 | goto out5; |
1159 | 1156 | ||
1160 | return 0; | 1157 | return 0; |
1158 | out5: | ||
1159 | rv = -ENOMEM; | ||
1160 | ASUS_LED_UNREGISTER(gled); | ||
1161 | out4: | ||
1162 | ASUS_LED_UNREGISTER(pled); | ||
1163 | out3: | ||
1164 | ASUS_LED_UNREGISTER(rled); | ||
1165 | out2: | ||
1166 | ASUS_LED_UNREGISTER(tled); | ||
1167 | out1: | ||
1168 | ASUS_LED_UNREGISTER(mled); | ||
1169 | out: | ||
1170 | return rv; | ||
1161 | } | 1171 | } |
1162 | 1172 | ||
1163 | static int __init asus_laptop_init(void) | 1173 | static int __init asus_laptop_init(void) |
diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c index 9623eaf4f89f..303e48ca0e8a 100644 --- a/drivers/misc/sony-laptop.c +++ b/drivers/misc/sony-laptop.c | |||
@@ -142,43 +142,124 @@ struct sony_laptop_keypress { | |||
142 | int key; | 142 | int key; |
143 | }; | 143 | }; |
144 | 144 | ||
145 | /* Correspondance table between sonypi events and input layer events */ | 145 | /* Correspondance table between sonypi events |
146 | static struct { | 146 | * and input layer indexes in the keymap |
147 | int sonypiev; | 147 | */ |
148 | int inputev; | 148 | static int sony_laptop_input_index[] = { |
149 | } sony_laptop_inputkeys[] = { | 149 | -1, /* no event */ |
150 | { SONYPI_EVENT_CAPTURE_PRESSED, KEY_CAMERA }, | 150 | -1, /* SONYPI_EVENT_JOGDIAL_DOWN */ |
151 | { SONYPI_EVENT_FNKEY_ONLY, KEY_FN }, | 151 | -1, /* SONYPI_EVENT_JOGDIAL_UP */ |
152 | { SONYPI_EVENT_FNKEY_ESC, KEY_FN_ESC }, | 152 | -1, /* SONYPI_EVENT_JOGDIAL_DOWN_PRESSED */ |
153 | { SONYPI_EVENT_FNKEY_F1, KEY_FN_F1 }, | 153 | -1, /* SONYPI_EVENT_JOGDIAL_UP_PRESSED */ |
154 | { SONYPI_EVENT_FNKEY_F2, KEY_FN_F2 }, | 154 | -1, /* SONYPI_EVENT_JOGDIAL_PRESSED */ |
155 | { SONYPI_EVENT_FNKEY_F3, KEY_FN_F3 }, | 155 | -1, /* SONYPI_EVENT_JOGDIAL_RELEASED */ |
156 | { SONYPI_EVENT_FNKEY_F4, KEY_FN_F4 }, | 156 | 0, /* SONYPI_EVENT_CAPTURE_PRESSED */ |
157 | { SONYPI_EVENT_FNKEY_F5, KEY_FN_F5 }, | 157 | 1, /* SONYPI_EVENT_CAPTURE_RELEASED */ |
158 | { SONYPI_EVENT_FNKEY_F6, KEY_FN_F6 }, | 158 | 2, /* SONYPI_EVENT_CAPTURE_PARTIALPRESSED */ |
159 | { SONYPI_EVENT_FNKEY_F7, KEY_FN_F7 }, | 159 | 3, /* SONYPI_EVENT_CAPTURE_PARTIALRELEASED */ |
160 | { SONYPI_EVENT_FNKEY_F8, KEY_FN_F8 }, | 160 | 4, /* SONYPI_EVENT_FNKEY_ESC */ |
161 | { SONYPI_EVENT_FNKEY_F9, KEY_FN_F9 }, | 161 | 5, /* SONYPI_EVENT_FNKEY_F1 */ |
162 | { SONYPI_EVENT_FNKEY_F10, KEY_FN_F10 }, | 162 | 6, /* SONYPI_EVENT_FNKEY_F2 */ |
163 | { SONYPI_EVENT_FNKEY_F11, KEY_FN_F11 }, | 163 | 7, /* SONYPI_EVENT_FNKEY_F3 */ |
164 | { SONYPI_EVENT_FNKEY_F12, KEY_FN_F12 }, | 164 | 8, /* SONYPI_EVENT_FNKEY_F4 */ |
165 | { SONYPI_EVENT_FNKEY_1, KEY_FN_1 }, | 165 | 9, /* SONYPI_EVENT_FNKEY_F5 */ |
166 | { SONYPI_EVENT_FNKEY_2, KEY_FN_2 }, | 166 | 10, /* SONYPI_EVENT_FNKEY_F6 */ |
167 | { SONYPI_EVENT_FNKEY_D, KEY_FN_D }, | 167 | 11, /* SONYPI_EVENT_FNKEY_F7 */ |
168 | { SONYPI_EVENT_FNKEY_E, KEY_FN_E }, | 168 | 12, /* SONYPI_EVENT_FNKEY_F8 */ |
169 | { SONYPI_EVENT_FNKEY_F, KEY_FN_F }, | 169 | 13, /* SONYPI_EVENT_FNKEY_F9 */ |
170 | { SONYPI_EVENT_FNKEY_S, KEY_FN_S }, | 170 | 14, /* SONYPI_EVENT_FNKEY_F10 */ |
171 | { SONYPI_EVENT_FNKEY_B, KEY_FN_B }, | 171 | 15, /* SONYPI_EVENT_FNKEY_F11 */ |
172 | { SONYPI_EVENT_BLUETOOTH_PRESSED, KEY_BLUE }, | 172 | 16, /* SONYPI_EVENT_FNKEY_F12 */ |
173 | { SONYPI_EVENT_BLUETOOTH_ON, KEY_BLUE }, | 173 | 17, /* SONYPI_EVENT_FNKEY_1 */ |
174 | { SONYPI_EVENT_PKEY_P1, KEY_PROG1 }, | 174 | 18, /* SONYPI_EVENT_FNKEY_2 */ |
175 | { SONYPI_EVENT_PKEY_P2, KEY_PROG2 }, | 175 | 19, /* SONYPI_EVENT_FNKEY_D */ |
176 | { SONYPI_EVENT_PKEY_P3, KEY_PROG3 }, | 176 | 20, /* SONYPI_EVENT_FNKEY_E */ |
177 | { SONYPI_EVENT_BACK_PRESSED, KEY_BACK }, | 177 | 21, /* SONYPI_EVENT_FNKEY_F */ |
178 | { SONYPI_EVENT_HELP_PRESSED, KEY_HELP }, | 178 | 22, /* SONYPI_EVENT_FNKEY_S */ |
179 | { SONYPI_EVENT_ZOOM_PRESSED, KEY_ZOOM }, | 179 | 23, /* SONYPI_EVENT_FNKEY_B */ |
180 | { SONYPI_EVENT_THUMBPHRASE_PRESSED, BTN_THUMB }, | 180 | 24, /* SONYPI_EVENT_BLUETOOTH_PRESSED */ |
181 | { 0, 0 }, | 181 | 25, /* SONYPI_EVENT_PKEY_P1 */ |
182 | 26, /* SONYPI_EVENT_PKEY_P2 */ | ||
183 | 27, /* SONYPI_EVENT_PKEY_P3 */ | ||
184 | 28, /* SONYPI_EVENT_BACK_PRESSED */ | ||
185 | -1, /* SONYPI_EVENT_LID_CLOSED */ | ||
186 | -1, /* SONYPI_EVENT_LID_OPENED */ | ||
187 | 29, /* SONYPI_EVENT_BLUETOOTH_ON */ | ||
188 | 30, /* SONYPI_EVENT_BLUETOOTH_OFF */ | ||
189 | 31, /* SONYPI_EVENT_HELP_PRESSED */ | ||
190 | 32, /* SONYPI_EVENT_FNKEY_ONLY */ | ||
191 | 33, /* SONYPI_EVENT_JOGDIAL_FAST_DOWN */ | ||
192 | 34, /* SONYPI_EVENT_JOGDIAL_FAST_UP */ | ||
193 | 35, /* SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED */ | ||
194 | 36, /* SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED */ | ||
195 | 37, /* SONYPI_EVENT_JOGDIAL_VFAST_DOWN */ | ||
196 | 38, /* SONYPI_EVENT_JOGDIAL_VFAST_UP */ | ||
197 | 39, /* SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED */ | ||
198 | 40, /* SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED */ | ||
199 | 41, /* SONYPI_EVENT_ZOOM_PRESSED */ | ||
200 | 42, /* SONYPI_EVENT_THUMBPHRASE_PRESSED */ | ||
201 | 43, /* SONYPI_EVENT_MEYE_FACE */ | ||
202 | 44, /* SONYPI_EVENT_MEYE_OPPOSITE */ | ||
203 | 45, /* SONYPI_EVENT_MEMORYSTICK_INSERT */ | ||
204 | 46, /* SONYPI_EVENT_MEMORYSTICK_EJECT */ | ||
205 | -1, /* SONYPI_EVENT_ANYBUTTON_RELEASED */ | ||
206 | -1, /* SONYPI_EVENT_BATTERY_INSERT */ | ||
207 | -1, /* SONYPI_EVENT_BATTERY_REMOVE */ | ||
208 | -1, /* SONYPI_EVENT_FNKEY_RELEASED */ | ||
209 | 47, /* SONYPI_EVENT_WIRELESS_ON */ | ||
210 | 48, /* SONYPI_EVENT_WIRELESS_OFF */ | ||
211 | }; | ||
212 | |||
213 | static int sony_laptop_input_keycode_map[] = { | ||
214 | KEY_CAMERA, /* 0 SONYPI_EVENT_CAPTURE_PRESSED */ | ||
215 | KEY_RESERVED, /* 1 SONYPI_EVENT_CAPTURE_RELEASED */ | ||
216 | KEY_RESERVED, /* 2 SONYPI_EVENT_CAPTURE_PARTIALPRESSED */ | ||
217 | KEY_RESERVED, /* 3 SONYPI_EVENT_CAPTURE_PARTIALRELEASED */ | ||
218 | KEY_FN_ESC, /* 4 SONYPI_EVENT_FNKEY_ESC */ | ||
219 | KEY_FN_F1, /* 5 SONYPI_EVENT_FNKEY_F1 */ | ||
220 | KEY_FN_F2, /* 6 SONYPI_EVENT_FNKEY_F2 */ | ||
221 | KEY_FN_F3, /* 7 SONYPI_EVENT_FNKEY_F3 */ | ||
222 | KEY_FN_F4, /* 8 SONYPI_EVENT_FNKEY_F4 */ | ||
223 | KEY_FN_F5, /* 9 SONYPI_EVENT_FNKEY_F5 */ | ||
224 | KEY_FN_F6, /* 10 SONYPI_EVENT_FNKEY_F6 */ | ||
225 | KEY_FN_F7, /* 11 SONYPI_EVENT_FNKEY_F7 */ | ||
226 | KEY_FN_F8, /* 12 SONYPI_EVENT_FNKEY_F8 */ | ||
227 | KEY_FN_F9, /* 13 SONYPI_EVENT_FNKEY_F9 */ | ||
228 | KEY_FN_F10, /* 14 SONYPI_EVENT_FNKEY_F10 */ | ||
229 | KEY_FN_F11, /* 15 SONYPI_EVENT_FNKEY_F11 */ | ||
230 | KEY_FN_F12, /* 16 SONYPI_EVENT_FNKEY_F12 */ | ||
231 | KEY_FN_F1, /* 17 SONYPI_EVENT_FNKEY_1 */ | ||
232 | KEY_FN_F2, /* 18 SONYPI_EVENT_FNKEY_2 */ | ||
233 | KEY_FN_D, /* 19 SONYPI_EVENT_FNKEY_D */ | ||
234 | KEY_FN_E, /* 20 SONYPI_EVENT_FNKEY_E */ | ||
235 | KEY_FN_F, /* 21 SONYPI_EVENT_FNKEY_F */ | ||
236 | KEY_FN_S, /* 22 SONYPI_EVENT_FNKEY_S */ | ||
237 | KEY_FN_B, /* 23 SONYPI_EVENT_FNKEY_B */ | ||
238 | KEY_BLUETOOTH, /* 24 SONYPI_EVENT_BLUETOOTH_PRESSED */ | ||
239 | KEY_PROG1, /* 25 SONYPI_EVENT_PKEY_P1 */ | ||
240 | KEY_PROG2, /* 26 SONYPI_EVENT_PKEY_P2 */ | ||
241 | KEY_PROG3, /* 27 SONYPI_EVENT_PKEY_P3 */ | ||
242 | KEY_BACK, /* 28 SONYPI_EVENT_BACK_PRESSED */ | ||
243 | KEY_BLUETOOTH, /* 29 SONYPI_EVENT_BLUETOOTH_ON */ | ||
244 | KEY_BLUETOOTH, /* 30 SONYPI_EVENT_BLUETOOTH_OFF */ | ||
245 | KEY_HELP, /* 31 SONYPI_EVENT_HELP_PRESSED */ | ||
246 | KEY_FN, /* 32 SONYPI_EVENT_FNKEY_ONLY */ | ||
247 | KEY_RESERVED, /* 33 SONYPI_EVENT_JOGDIAL_FAST_DOWN */ | ||
248 | KEY_RESERVED, /* 34 SONYPI_EVENT_JOGDIAL_FAST_UP */ | ||
249 | KEY_RESERVED, /* 35 SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED */ | ||
250 | KEY_RESERVED, /* 36 SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED */ | ||
251 | KEY_RESERVED, /* 37 SONYPI_EVENT_JOGDIAL_VFAST_DOWN */ | ||
252 | KEY_RESERVED, /* 38 SONYPI_EVENT_JOGDIAL_VFAST_UP */ | ||
253 | KEY_RESERVED, /* 39 SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED */ | ||
254 | KEY_RESERVED, /* 40 SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED */ | ||
255 | KEY_ZOOM, /* 41 SONYPI_EVENT_ZOOM_PRESSED */ | ||
256 | BTN_THUMB, /* 42 SONYPI_EVENT_THUMBPHRASE_PRESSED */ | ||
257 | KEY_RESERVED, /* 43 SONYPI_EVENT_MEYE_FACE */ | ||
258 | KEY_RESERVED, /* 44 SONYPI_EVENT_MEYE_OPPOSITE */ | ||
259 | KEY_RESERVED, /* 45 SONYPI_EVENT_MEMORYSTICK_INSERT */ | ||
260 | KEY_RESERVED, /* 46 SONYPI_EVENT_MEMORYSTICK_EJECT */ | ||
261 | KEY_WLAN, /* 47 SONYPI_EVENT_WIRELESS_ON */ | ||
262 | KEY_WLAN, /* 48 SONYPI_EVENT_WIRELESS_OFF */ | ||
182 | }; | 263 | }; |
183 | 264 | ||
184 | /* release buttons after a short delay if pressed */ | 265 | /* release buttons after a short delay if pressed */ |
@@ -202,7 +283,6 @@ static void sony_laptop_report_input_event(u8 event) | |||
202 | struct input_dev *jog_dev = sony_laptop_input.jog_dev; | 283 | struct input_dev *jog_dev = sony_laptop_input.jog_dev; |
203 | struct input_dev *key_dev = sony_laptop_input.key_dev; | 284 | struct input_dev *key_dev = sony_laptop_input.key_dev; |
204 | struct sony_laptop_keypress kp = { NULL }; | 285 | struct sony_laptop_keypress kp = { NULL }; |
205 | int i; | ||
206 | 286 | ||
207 | if (event == SONYPI_EVENT_FNKEY_RELEASED) { | 287 | if (event == SONYPI_EVENT_FNKEY_RELEASED) { |
208 | /* Nothing, not all VAIOs generate this event */ | 288 | /* Nothing, not all VAIOs generate this event */ |
@@ -231,17 +311,22 @@ static void sony_laptop_report_input_event(u8 event) | |||
231 | break; | 311 | break; |
232 | 312 | ||
233 | default: | 313 | default: |
234 | for (i = 0; sony_laptop_inputkeys[i].sonypiev; i++) | 314 | if (event > ARRAY_SIZE (sony_laptop_input_keycode_map)) { |
235 | if (event == sony_laptop_inputkeys[i].sonypiev) { | 315 | dprintk("sony_laptop_report_input_event, event not known: %d\n", event); |
316 | break; | ||
317 | } | ||
318 | if (sony_laptop_input_index[event] != -1) { | ||
319 | kp.key = sony_laptop_input_keycode_map[sony_laptop_input_index[event]]; | ||
320 | if (kp.key != KEY_UNKNOWN) | ||
236 | kp.dev = key_dev; | 321 | kp.dev = key_dev; |
237 | kp.key = sony_laptop_inputkeys[i].inputev; | 322 | } |
238 | break; | ||
239 | } | ||
240 | break; | 323 | break; |
241 | } | 324 | } |
242 | 325 | ||
243 | if (kp.dev) { | 326 | if (kp.dev) { |
244 | input_report_key(kp.dev, kp.key, 1); | 327 | input_report_key(kp.dev, kp.key, 1); |
328 | /* we emit the scancode so we can always remap the key */ | ||
329 | input_event(kp.dev, EV_MSC, MSC_SCAN, event); | ||
245 | input_sync(kp.dev); | 330 | input_sync(kp.dev); |
246 | kfifo_put(sony_laptop_input.fifo, | 331 | kfifo_put(sony_laptop_input.fifo, |
247 | (unsigned char *)&kp, sizeof(kp)); | 332 | (unsigned char *)&kp, sizeof(kp)); |
@@ -296,11 +381,18 @@ static int sony_laptop_setup_input(void) | |||
296 | key_dev->id.vendor = PCI_VENDOR_ID_SONY; | 381 | key_dev->id.vendor = PCI_VENDOR_ID_SONY; |
297 | 382 | ||
298 | /* Initialize the Input Drivers: special keys */ | 383 | /* Initialize the Input Drivers: special keys */ |
299 | key_dev->evbit[0] = BIT(EV_KEY); | 384 | set_bit(EV_KEY, key_dev->evbit); |
300 | for (i = 0; sony_laptop_inputkeys[i].sonypiev; i++) | 385 | set_bit(EV_MSC, key_dev->evbit); |
301 | if (sony_laptop_inputkeys[i].inputev) | 386 | set_bit(MSC_SCAN, key_dev->mscbit); |
302 | set_bit(sony_laptop_inputkeys[i].inputev, | 387 | key_dev->keycodesize = sizeof(sony_laptop_input_keycode_map[0]); |
303 | key_dev->keybit); | 388 | key_dev->keycodemax = ARRAY_SIZE(sony_laptop_input_keycode_map); |
389 | key_dev->keycode = &sony_laptop_input_keycode_map; | ||
390 | for (i = 0; i < ARRAY_SIZE(sony_laptop_input_keycode_map); i++) { | ||
391 | if (sony_laptop_input_keycode_map[i] != KEY_RESERVED) { | ||
392 | set_bit(sony_laptop_input_keycode_map[i], | ||
393 | key_dev->keybit); | ||
394 | } | ||
395 | } | ||
304 | 396 | ||
305 | error = input_register_device(key_dev); | 397 | error = input_register_device(key_dev); |
306 | if (error) | 398 | if (error) |
@@ -487,6 +579,14 @@ SNC_HANDLE_NAMES(audiopower_set, "AZPW"); | |||
487 | SNC_HANDLE_NAMES(lanpower_get, "GLNP"); | 579 | SNC_HANDLE_NAMES(lanpower_get, "GLNP"); |
488 | SNC_HANDLE_NAMES(lanpower_set, "LNPW"); | 580 | SNC_HANDLE_NAMES(lanpower_set, "LNPW"); |
489 | 581 | ||
582 | SNC_HANDLE_NAMES(lidstate_get, "GLID"); | ||
583 | |||
584 | SNC_HANDLE_NAMES(indicatorlamp_get, "GILS"); | ||
585 | SNC_HANDLE_NAMES(indicatorlamp_set, "SILS"); | ||
586 | |||
587 | SNC_HANDLE_NAMES(gainbass_get, "GMGB"); | ||
588 | SNC_HANDLE_NAMES(gainbass_set, "CMGB"); | ||
589 | |||
490 | SNC_HANDLE_NAMES(PID_get, "GPID"); | 590 | SNC_HANDLE_NAMES(PID_get, "GPID"); |
491 | 591 | ||
492 | SNC_HANDLE_NAMES(CTR_get, "GCTR"); | 592 | SNC_HANDLE_NAMES(CTR_get, "GCTR"); |
@@ -507,6 +607,12 @@ static struct sony_nc_value sony_nc_values[] = { | |||
507 | boolean_validate, 0), | 607 | boolean_validate, 0), |
508 | SNC_HANDLE(lanpower, snc_lanpower_get, snc_lanpower_set, | 608 | SNC_HANDLE(lanpower, snc_lanpower_get, snc_lanpower_set, |
509 | boolean_validate, 1), | 609 | boolean_validate, 1), |
610 | SNC_HANDLE(lidstate, snc_lidstate_get, NULL, | ||
611 | boolean_validate, 0), | ||
612 | SNC_HANDLE(indicatorlamp, snc_indicatorlamp_get, snc_indicatorlamp_set, | ||
613 | boolean_validate, 0), | ||
614 | SNC_HANDLE(gainbass, snc_gainbass_get, snc_gainbass_set, | ||
615 | boolean_validate, 0), | ||
510 | /* unknown methods */ | 616 | /* unknown methods */ |
511 | SNC_HANDLE(PID, snc_PID_get, NULL, NULL, 1), | 617 | SNC_HANDLE(PID, snc_PID_get, NULL, NULL, 1), |
512 | SNC_HANDLE(CTR, snc_CTR_get, snc_CTR_set, NULL, 1), | 618 | SNC_HANDLE(CTR, snc_CTR_get, snc_CTR_set, NULL, 1), |
@@ -689,13 +795,116 @@ static struct backlight_ops sony_backlight_ops = { | |||
689 | }; | 795 | }; |
690 | 796 | ||
691 | /* | 797 | /* |
798 | * New SNC-only Vaios event mapping to driver known keys | ||
799 | */ | ||
800 | struct sony_nc_event { | ||
801 | u8 data; | ||
802 | u8 event; | ||
803 | }; | ||
804 | |||
805 | static struct sony_nc_event *sony_nc_events; | ||
806 | |||
807 | /* Vaio C* --maybe also FE*, N* and AR* ?-- special init sequence | ||
808 | * for Fn keys | ||
809 | */ | ||
810 | static int sony_nc_C_enable(struct dmi_system_id *id) | ||
811 | { | ||
812 | int result = 0; | ||
813 | |||
814 | printk(KERN_NOTICE DRV_PFX "detected %s\n", id->ident); | ||
815 | |||
816 | sony_nc_events = id->driver_data; | ||
817 | |||
818 | if (acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0x4, &result) < 0 | ||
819 | || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x2, &result) < 0 | ||
820 | || acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0x10, &result) < 0 | ||
821 | || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x0, &result) < 0 | ||
822 | || acpi_callsetfunc(sony_nc_acpi_handle, "SN03", 0x2, &result) < 0 | ||
823 | || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x101, &result) < 0) { | ||
824 | printk(KERN_WARNING DRV_PFX "failed to initialize SNC, some " | ||
825 | "functionalities may be missing\n"); | ||
826 | return 1; | ||
827 | } | ||
828 | return 0; | ||
829 | } | ||
830 | |||
831 | static struct sony_nc_event sony_C_events[] = { | ||
832 | { 0x81, SONYPI_EVENT_FNKEY_F1 }, | ||
833 | { 0x01, SONYPI_EVENT_FNKEY_RELEASED }, | ||
834 | { 0x85, SONYPI_EVENT_FNKEY_F5 }, | ||
835 | { 0x05, SONYPI_EVENT_FNKEY_RELEASED }, | ||
836 | { 0x86, SONYPI_EVENT_FNKEY_F6 }, | ||
837 | { 0x06, SONYPI_EVENT_FNKEY_RELEASED }, | ||
838 | { 0x87, SONYPI_EVENT_FNKEY_F7 }, | ||
839 | { 0x07, SONYPI_EVENT_FNKEY_RELEASED }, | ||
840 | { 0x8A, SONYPI_EVENT_FNKEY_F10 }, | ||
841 | { 0x0A, SONYPI_EVENT_FNKEY_RELEASED }, | ||
842 | { 0x8C, SONYPI_EVENT_FNKEY_F12 }, | ||
843 | { 0x0C, SONYPI_EVENT_FNKEY_RELEASED }, | ||
844 | { 0, 0 }, | ||
845 | }; | ||
846 | |||
847 | /* SNC-only model map */ | ||
848 | struct dmi_system_id sony_nc_ids[] = { | ||
849 | { | ||
850 | .ident = "Sony Vaio FE Series", | ||
851 | .callback = sony_nc_C_enable, | ||
852 | .driver_data = sony_C_events, | ||
853 | .matches = { | ||
854 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
855 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FE"), | ||
856 | }, | ||
857 | }, | ||
858 | { | ||
859 | .ident = "Sony Vaio C Series", | ||
860 | .callback = sony_nc_C_enable, | ||
861 | .driver_data = sony_C_events, | ||
862 | .matches = { | ||
863 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
864 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-C"), | ||
865 | }, | ||
866 | }, | ||
867 | { } | ||
868 | }; | ||
869 | |||
870 | /* | ||
692 | * ACPI callbacks | 871 | * ACPI callbacks |
693 | */ | 872 | */ |
694 | static void sony_acpi_notify(acpi_handle handle, u32 event, void *data) | 873 | static void sony_acpi_notify(acpi_handle handle, u32 event, void *data) |
695 | { | 874 | { |
696 | dprintk("sony_acpi_notify, event: %d\n", event); | 875 | struct sony_nc_event *evmap; |
697 | sony_laptop_report_input_event(event); | 876 | u32 ev = event; |
698 | acpi_bus_generate_event(sony_nc_acpi_device, 1, event); | 877 | int result; |
878 | |||
879 | if (ev == 0x92) { | ||
880 | /* read the key pressed from EC.GECR | ||
881 | * A call to SN07 with 0x0202 will do it as well respecting | ||
882 | * the current protocol on different OSes | ||
883 | * | ||
884 | * Note: the path for GECR may be | ||
885 | * \_SB.PCI0.LPCB.EC (C, FE, AR, N and friends) | ||
886 | * \_SB.PCI0.PIB.EC0 (VGN-FR notifications are sent directly, no GECR) | ||
887 | * | ||
888 | * TODO: we may want to do the same for the older GHKE -need | ||
889 | * dmi list- so this snippet may become one more callback. | ||
890 | */ | ||
891 | if (acpi_callsetfunc(handle, "SN07", 0x0202, &result) < 0) | ||
892 | dprintk("sony_acpi_notify, unable to decode event 0x%.2x\n", ev); | ||
893 | else | ||
894 | ev = result & 0xFF; | ||
895 | } | ||
896 | |||
897 | if (sony_nc_events) | ||
898 | for (evmap = sony_nc_events; evmap->event; evmap++) { | ||
899 | if (evmap->data == ev) { | ||
900 | ev = evmap->event; | ||
901 | break; | ||
902 | } | ||
903 | } | ||
904 | |||
905 | dprintk("sony_acpi_notify, event: 0x%.2x\n", ev); | ||
906 | sony_laptop_report_input_event(ev); | ||
907 | acpi_bus_generate_event(sony_nc_acpi_device, 1, ev); | ||
699 | } | 908 | } |
700 | 909 | ||
701 | static acpi_status sony_walk_callback(acpi_handle handle, u32 level, | 910 | static acpi_status sony_walk_callback(acpi_handle handle, u32 level, |
@@ -732,6 +941,10 @@ static int sony_nc_resume(struct acpi_device *device) | |||
732 | break; | 941 | break; |
733 | } | 942 | } |
734 | } | 943 | } |
944 | |||
945 | /* re-initialize models with specific requirements */ | ||
946 | dmi_check_system(sony_nc_ids); | ||
947 | |||
735 | return 0; | 948 | return 0; |
736 | } | 949 | } |
737 | 950 | ||
@@ -750,6 +963,15 @@ static int sony_nc_add(struct acpi_device *device) | |||
750 | 963 | ||
751 | sony_nc_acpi_handle = device->handle; | 964 | sony_nc_acpi_handle = device->handle; |
752 | 965 | ||
966 | /* read device status */ | ||
967 | result = acpi_bus_get_status(device); | ||
968 | /* bail IFF the above call was successful and the device is not present */ | ||
969 | if (!result && !device->status.present) { | ||
970 | dprintk("Device not present\n"); | ||
971 | result = -ENODEV; | ||
972 | goto outwalk; | ||
973 | } | ||
974 | |||
753 | if (debug) { | 975 | if (debug) { |
754 | status = acpi_walk_namespace(ACPI_TYPE_METHOD, sony_nc_acpi_handle, | 976 | status = acpi_walk_namespace(ACPI_TYPE_METHOD, sony_nc_acpi_handle, |
755 | 1, sony_walk_callback, NULL, NULL); | 977 | 1, sony_walk_callback, NULL, NULL); |
@@ -760,6 +982,15 @@ static int sony_nc_add(struct acpi_device *device) | |||
760 | } | 982 | } |
761 | } | 983 | } |
762 | 984 | ||
985 | /* try to _INI the device if such method exists (ACPI spec 3.0-6.5.1 | ||
986 | * should be respected as we already checked for the device presence above */ | ||
987 | if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, METHOD_NAME__INI, &handle))) { | ||
988 | dprintk("Invoking _INI\n"); | ||
989 | if (ACPI_FAILURE(acpi_evaluate_object(sony_nc_acpi_handle, METHOD_NAME__INI, | ||
990 | NULL, NULL))) | ||
991 | dprintk("_INI Method failed\n"); | ||
992 | } | ||
993 | |||
763 | /* setup input devices and helper fifo */ | 994 | /* setup input devices and helper fifo */ |
764 | result = sony_laptop_setup_input(); | 995 | result = sony_laptop_setup_input(); |
765 | if (result) { | 996 | if (result) { |
@@ -772,7 +1003,7 @@ static int sony_nc_add(struct acpi_device *device) | |||
772 | ACPI_DEVICE_NOTIFY, | 1003 | ACPI_DEVICE_NOTIFY, |
773 | sony_acpi_notify, NULL); | 1004 | sony_acpi_notify, NULL); |
774 | if (ACPI_FAILURE(status)) { | 1005 | if (ACPI_FAILURE(status)) { |
775 | printk(KERN_WARNING DRV_PFX "unable to install notify handler\n"); | 1006 | printk(KERN_WARNING DRV_PFX "unable to install notify handler (%u)\n", status); |
776 | result = -ENODEV; | 1007 | result = -ENODEV; |
777 | goto outinput; | 1008 | goto outinput; |
778 | } | 1009 | } |
@@ -795,6 +1026,9 @@ static int sony_nc_add(struct acpi_device *device) | |||
795 | 1026 | ||
796 | } | 1027 | } |
797 | 1028 | ||
1029 | /* initialize models with specific requirements */ | ||
1030 | dmi_check_system(sony_nc_ids); | ||
1031 | |||
798 | result = sony_pf_add(); | 1032 | result = sony_pf_add(); |
799 | if (result) | 1033 | if (result) |
800 | goto outbacklight; | 1034 | goto outbacklight; |
@@ -908,7 +1142,9 @@ static struct acpi_driver sony_nc_driver = { | |||
908 | #define SONYPI_DEVICE_TYPE2 0x00000002 | 1142 | #define SONYPI_DEVICE_TYPE2 0x00000002 |
909 | #define SONYPI_DEVICE_TYPE3 0x00000004 | 1143 | #define SONYPI_DEVICE_TYPE3 0x00000004 |
910 | 1144 | ||
911 | #define SONY_PIC_EV_MASK 0xff | 1145 | #define SONYPI_TYPE1_OFFSET 0x04 |
1146 | #define SONYPI_TYPE2_OFFSET 0x12 | ||
1147 | #define SONYPI_TYPE3_OFFSET 0x12 | ||
912 | 1148 | ||
913 | struct sony_pic_ioport { | 1149 | struct sony_pic_ioport { |
914 | struct acpi_resource_io io; | 1150 | struct acpi_resource_io io; |
@@ -922,6 +1158,7 @@ struct sony_pic_irq { | |||
922 | 1158 | ||
923 | struct sony_pic_dev { | 1159 | struct sony_pic_dev { |
924 | int model; | 1160 | int model; |
1161 | u16 evport_offset; | ||
925 | u8 camera_power; | 1162 | u8 camera_power; |
926 | u8 bluetooth_power; | 1163 | u8 bluetooth_power; |
927 | u8 wwan_power; | 1164 | u8 wwan_power; |
@@ -1999,20 +2236,17 @@ end: | |||
1999 | static irqreturn_t sony_pic_irq(int irq, void *dev_id) | 2236 | static irqreturn_t sony_pic_irq(int irq, void *dev_id) |
2000 | { | 2237 | { |
2001 | int i, j; | 2238 | int i, j; |
2002 | u32 port_val = 0; | ||
2003 | u8 ev = 0; | 2239 | u8 ev = 0; |
2004 | u8 data_mask = 0; | 2240 | u8 data_mask = 0; |
2005 | u8 device_event = 0; | 2241 | u8 device_event = 0; |
2006 | 2242 | ||
2007 | struct sony_pic_dev *dev = (struct sony_pic_dev *) dev_id; | 2243 | struct sony_pic_dev *dev = (struct sony_pic_dev *) dev_id; |
2008 | 2244 | ||
2009 | acpi_os_read_port(dev->cur_ioport->io.minimum, &port_val, | 2245 | ev = inb_p(dev->cur_ioport->io.minimum); |
2010 | dev->cur_ioport->io.address_length); | 2246 | data_mask = inb_p(dev->cur_ioport->io.minimum + dev->evport_offset); |
2011 | ev = port_val & SONY_PIC_EV_MASK; | ||
2012 | data_mask = 0xff & (port_val >> (dev->cur_ioport->io.address_length - 8)); | ||
2013 | 2247 | ||
2014 | dprintk("event (0x%.8x [%.2x] [%.2x]) at port 0x%.4x\n", | 2248 | dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n", |
2015 | port_val, ev, data_mask, dev->cur_ioport->io.minimum); | 2249 | ev, data_mask, dev->cur_ioport->io.minimum, dev->evport_offset); |
2016 | 2250 | ||
2017 | if (ev == 0x00 || ev == 0xff) | 2251 | if (ev == 0x00 || ev == 0xff) |
2018 | return IRQ_HANDLED; | 2252 | return IRQ_HANDLED; |
@@ -2103,6 +2337,20 @@ static int sony_pic_add(struct acpi_device *device) | |||
2103 | spic_dev.model = sony_pic_detect_device_type(); | 2337 | spic_dev.model = sony_pic_detect_device_type(); |
2104 | mutex_init(&spic_dev.lock); | 2338 | mutex_init(&spic_dev.lock); |
2105 | 2339 | ||
2340 | /* model specific characteristics */ | ||
2341 | switch(spic_dev.model) { | ||
2342 | case SONYPI_DEVICE_TYPE1: | ||
2343 | spic_dev.evport_offset = SONYPI_TYPE1_OFFSET; | ||
2344 | break; | ||
2345 | case SONYPI_DEVICE_TYPE3: | ||
2346 | spic_dev.evport_offset = SONYPI_TYPE3_OFFSET; | ||
2347 | break; | ||
2348 | case SONYPI_DEVICE_TYPE2: | ||
2349 | default: | ||
2350 | spic_dev.evport_offset = SONYPI_TYPE2_OFFSET; | ||
2351 | break; | ||
2352 | } | ||
2353 | |||
2106 | /* read _PRS resources */ | 2354 | /* read _PRS resources */ |
2107 | result = sony_pic_possible_resources(device); | 2355 | result = sony_pic_possible_resources(device); |
2108 | if (result) { | 2356 | if (result) { |
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index 95c0b96e83f2..f15a58f7403f 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c | |||
@@ -21,8 +21,8 @@ | |||
21 | * 02110-1301, USA. | 21 | * 02110-1301, USA. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #define IBM_VERSION "0.14" | 24 | #define IBM_VERSION "0.15" |
25 | #define TPACPI_SYSFS_VERSION 0x000100 | 25 | #define TPACPI_SYSFS_VERSION 0x010000 |
26 | 26 | ||
27 | /* | 27 | /* |
28 | * Changelog: | 28 | * Changelog: |
@@ -92,6 +92,29 @@ MODULE_LICENSE("GPL"); | |||
92 | /* Please remove this in year 2009 */ | 92 | /* Please remove this in year 2009 */ |
93 | MODULE_ALIAS("ibm_acpi"); | 93 | MODULE_ALIAS("ibm_acpi"); |
94 | 94 | ||
95 | /* | ||
96 | * DMI matching for module autoloading | ||
97 | * | ||
98 | * See http://thinkwiki.org/wiki/List_of_DMI_IDs | ||
99 | * See http://thinkwiki.org/wiki/BIOS_Upgrade_Downloads | ||
100 | * | ||
101 | * Only models listed in thinkwiki will be supported, so add yours | ||
102 | * if it is not there yet. | ||
103 | */ | ||
104 | #define IBM_BIOS_MODULE_ALIAS(__type) \ | ||
105 | MODULE_ALIAS("dmi:bvnIBM:bvr" __type "ET??WW") | ||
106 | |||
107 | /* Non-ancient thinkpads */ | ||
108 | MODULE_ALIAS("dmi:bvnIBM:*:svnIBM:*:pvrThinkPad*:rvnIBM:*"); | ||
109 | MODULE_ALIAS("dmi:bvnLENOVO:*:svnLENOVO:*:pvrThinkPad*:rvnLENOVO:*"); | ||
110 | |||
111 | /* Ancient thinkpad BIOSes have to be identified by | ||
112 | * BIOS type or model number, and there are far less | ||
113 | * BIOS types than model numbers... */ | ||
114 | IBM_BIOS_MODULE_ALIAS("I[B,D,H,I,M,N,O,T,W,V,Y,Z]"); | ||
115 | IBM_BIOS_MODULE_ALIAS("1[0,3,6,8,A-G,I,K,M-P,S,T]"); | ||
116 | IBM_BIOS_MODULE_ALIAS("K[U,X-Z]"); | ||
117 | |||
95 | #define __unused __attribute__ ((unused)) | 118 | #define __unused __attribute__ ((unused)) |
96 | 119 | ||
97 | /**************************************************************************** | 120 | /**************************************************************************** |
@@ -106,7 +129,7 @@ MODULE_ALIAS("ibm_acpi"); | |||
106 | * ACPI basic handles | 129 | * ACPI basic handles |
107 | */ | 130 | */ |
108 | 131 | ||
109 | static acpi_handle root_handle = NULL; | 132 | static acpi_handle root_handle; |
110 | 133 | ||
111 | #define IBM_HANDLE(object, parent, paths...) \ | 134 | #define IBM_HANDLE(object, parent, paths...) \ |
112 | static acpi_handle object##_handle; \ | 135 | static acpi_handle object##_handle; \ |
@@ -487,19 +510,36 @@ static char *next_cmd(char **cmds) | |||
487 | /**************************************************************************** | 510 | /**************************************************************************** |
488 | **************************************************************************** | 511 | **************************************************************************** |
489 | * | 512 | * |
490 | * Device model: hwmon and platform | 513 | * Device model: input, hwmon and platform |
491 | * | 514 | * |
492 | **************************************************************************** | 515 | **************************************************************************** |
493 | ****************************************************************************/ | 516 | ****************************************************************************/ |
494 | 517 | ||
495 | static struct platform_device *tpacpi_pdev = NULL; | 518 | static struct platform_device *tpacpi_pdev; |
496 | static struct class_device *tpacpi_hwmon = NULL; | 519 | static struct class_device *tpacpi_hwmon; |
520 | static struct input_dev *tpacpi_inputdev; | ||
521 | |||
522 | |||
523 | static int tpacpi_resume_handler(struct platform_device *pdev) | ||
524 | { | ||
525 | struct ibm_struct *ibm, *itmp; | ||
526 | |||
527 | list_for_each_entry_safe(ibm, itmp, | ||
528 | &tpacpi_all_drivers, | ||
529 | all_drivers) { | ||
530 | if (ibm->resume) | ||
531 | (ibm->resume)(); | ||
532 | } | ||
533 | |||
534 | return 0; | ||
535 | } | ||
497 | 536 | ||
498 | static struct platform_driver tpacpi_pdriver = { | 537 | static struct platform_driver tpacpi_pdriver = { |
499 | .driver = { | 538 | .driver = { |
500 | .name = IBM_DRVR_NAME, | 539 | .name = IBM_DRVR_NAME, |
501 | .owner = THIS_MODULE, | 540 | .owner = THIS_MODULE, |
502 | }, | 541 | }, |
542 | .resume = tpacpi_resume_handler, | ||
503 | }; | 543 | }; |
504 | 544 | ||
505 | 545 | ||
@@ -677,9 +717,19 @@ static int __init thinkpad_acpi_driver_init(struct ibm_init_struct *iibm) | |||
677 | printk(IBM_INFO "%s v%s\n", IBM_DESC, IBM_VERSION); | 717 | printk(IBM_INFO "%s v%s\n", IBM_DESC, IBM_VERSION); |
678 | printk(IBM_INFO "%s\n", IBM_URL); | 718 | printk(IBM_INFO "%s\n", IBM_URL); |
679 | 719 | ||
680 | if (ibm_thinkpad_ec_found) | 720 | printk(IBM_INFO "ThinkPad BIOS %s, EC %s\n", |
681 | printk(IBM_INFO "ThinkPad EC firmware %s\n", | 721 | (thinkpad_id.bios_version_str) ? |
682 | ibm_thinkpad_ec_found); | 722 | thinkpad_id.bios_version_str : "unknown", |
723 | (thinkpad_id.ec_version_str) ? | ||
724 | thinkpad_id.ec_version_str : "unknown"); | ||
725 | |||
726 | if (thinkpad_id.vendor && thinkpad_id.model_str) | ||
727 | printk(IBM_INFO "%s %s\n", | ||
728 | (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ? | ||
729 | "IBM" : ((thinkpad_id.vendor == | ||
730 | PCI_VENDOR_ID_LENOVO) ? | ||
731 | "Lenovo" : "Unknown vendor"), | ||
732 | thinkpad_id.model_str); | ||
683 | 733 | ||
684 | return 0; | 734 | return 0; |
685 | } | 735 | } |
@@ -704,16 +754,28 @@ static struct ibm_struct thinkpad_acpi_driver_data = { | |||
704 | */ | 754 | */ |
705 | 755 | ||
706 | static int hotkey_orig_status; | 756 | static int hotkey_orig_status; |
707 | static int hotkey_orig_mask; | 757 | static u32 hotkey_orig_mask; |
758 | static u32 hotkey_all_mask; | ||
759 | static u32 hotkey_reserved_mask; | ||
760 | |||
761 | static u16 *hotkey_keycode_map; | ||
708 | 762 | ||
709 | static struct attribute_set *hotkey_dev_attributes = NULL; | 763 | static struct attribute_set *hotkey_dev_attributes; |
764 | |||
765 | static int hotkey_get_wlsw(int *status) | ||
766 | { | ||
767 | if (!acpi_evalf(hkey_handle, status, "WLSW", "d")) | ||
768 | return -EIO; | ||
769 | return 0; | ||
770 | } | ||
710 | 771 | ||
711 | /* sysfs hotkey enable ------------------------------------------------- */ | 772 | /* sysfs hotkey enable ------------------------------------------------- */ |
712 | static ssize_t hotkey_enable_show(struct device *dev, | 773 | static ssize_t hotkey_enable_show(struct device *dev, |
713 | struct device_attribute *attr, | 774 | struct device_attribute *attr, |
714 | char *buf) | 775 | char *buf) |
715 | { | 776 | { |
716 | int res, status, mask; | 777 | int res, status; |
778 | u32 mask; | ||
717 | 779 | ||
718 | res = hotkey_get(&status, &mask); | 780 | res = hotkey_get(&status, &mask); |
719 | if (res) | 781 | if (res) |
@@ -727,7 +789,8 @@ static ssize_t hotkey_enable_store(struct device *dev, | |||
727 | const char *buf, size_t count) | 789 | const char *buf, size_t count) |
728 | { | 790 | { |
729 | unsigned long t; | 791 | unsigned long t; |
730 | int res, status, mask; | 792 | int res, status; |
793 | u32 mask; | ||
731 | 794 | ||
732 | if (parse_strtoul(buf, 1, &t)) | 795 | if (parse_strtoul(buf, 1, &t)) |
733 | return -EINVAL; | 796 | return -EINVAL; |
@@ -748,13 +811,14 @@ static ssize_t hotkey_mask_show(struct device *dev, | |||
748 | struct device_attribute *attr, | 811 | struct device_attribute *attr, |
749 | char *buf) | 812 | char *buf) |
750 | { | 813 | { |
751 | int res, status, mask; | 814 | int res, status; |
815 | u32 mask; | ||
752 | 816 | ||
753 | res = hotkey_get(&status, &mask); | 817 | res = hotkey_get(&status, &mask); |
754 | if (res) | 818 | if (res) |
755 | return res; | 819 | return res; |
756 | 820 | ||
757 | return snprintf(buf, PAGE_SIZE, "0x%04x\n", mask); | 821 | return snprintf(buf, PAGE_SIZE, "0x%08x\n", mask); |
758 | } | 822 | } |
759 | 823 | ||
760 | static ssize_t hotkey_mask_store(struct device *dev, | 824 | static ssize_t hotkey_mask_store(struct device *dev, |
@@ -762,9 +826,10 @@ static ssize_t hotkey_mask_store(struct device *dev, | |||
762 | const char *buf, size_t count) | 826 | const char *buf, size_t count) |
763 | { | 827 | { |
764 | unsigned long t; | 828 | unsigned long t; |
765 | int res, status, mask; | 829 | int res, status; |
830 | u32 mask; | ||
766 | 831 | ||
767 | if (parse_strtoul(buf, 0xffff, &t)) | 832 | if (parse_strtoul(buf, 0xffffffffUL, &t)) |
768 | return -EINVAL; | 833 | return -EINVAL; |
769 | 834 | ||
770 | res = hotkey_get(&status, &mask); | 835 | res = hotkey_get(&status, &mask); |
@@ -794,26 +859,123 @@ static ssize_t hotkey_bios_mask_show(struct device *dev, | |||
794 | struct device_attribute *attr, | 859 | struct device_attribute *attr, |
795 | char *buf) | 860 | char *buf) |
796 | { | 861 | { |
797 | return snprintf(buf, PAGE_SIZE, "0x%04x\n", hotkey_orig_mask); | 862 | return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_orig_mask); |
798 | } | 863 | } |
799 | 864 | ||
800 | static struct device_attribute dev_attr_hotkey_bios_mask = | 865 | static struct device_attribute dev_attr_hotkey_bios_mask = |
801 | __ATTR(hotkey_bios_mask, S_IRUGO, hotkey_bios_mask_show, NULL); | 866 | __ATTR(hotkey_bios_mask, S_IRUGO, hotkey_bios_mask_show, NULL); |
802 | 867 | ||
868 | /* sysfs hotkey all_mask ----------------------------------------------- */ | ||
869 | static ssize_t hotkey_all_mask_show(struct device *dev, | ||
870 | struct device_attribute *attr, | ||
871 | char *buf) | ||
872 | { | ||
873 | return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_all_mask); | ||
874 | } | ||
875 | |||
876 | static struct device_attribute dev_attr_hotkey_all_mask = | ||
877 | __ATTR(hotkey_all_mask, S_IRUGO, hotkey_all_mask_show, NULL); | ||
878 | |||
879 | /* sysfs hotkey recommended_mask --------------------------------------- */ | ||
880 | static ssize_t hotkey_recommended_mask_show(struct device *dev, | ||
881 | struct device_attribute *attr, | ||
882 | char *buf) | ||
883 | { | ||
884 | return snprintf(buf, PAGE_SIZE, "0x%08x\n", | ||
885 | hotkey_all_mask & ~hotkey_reserved_mask); | ||
886 | } | ||
887 | |||
888 | static struct device_attribute dev_attr_hotkey_recommended_mask = | ||
889 | __ATTR(hotkey_recommended_mask, S_IRUGO, | ||
890 | hotkey_recommended_mask_show, NULL); | ||
891 | |||
892 | /* sysfs hotkey radio_sw ----------------------------------------------- */ | ||
893 | static ssize_t hotkey_radio_sw_show(struct device *dev, | ||
894 | struct device_attribute *attr, | ||
895 | char *buf) | ||
896 | { | ||
897 | int res, s; | ||
898 | res = hotkey_get_wlsw(&s); | ||
899 | if (res < 0) | ||
900 | return res; | ||
901 | |||
902 | return snprintf(buf, PAGE_SIZE, "%d\n", !!s); | ||
903 | } | ||
904 | |||
905 | static struct device_attribute dev_attr_hotkey_radio_sw = | ||
906 | __ATTR(hotkey_radio_sw, S_IRUGO, hotkey_radio_sw_show, NULL); | ||
907 | |||
803 | /* --------------------------------------------------------------------- */ | 908 | /* --------------------------------------------------------------------- */ |
804 | 909 | ||
805 | static struct attribute *hotkey_mask_attributes[] = { | 910 | static struct attribute *hotkey_mask_attributes[] = { |
806 | &dev_attr_hotkey_mask.attr, | 911 | &dev_attr_hotkey_mask.attr, |
807 | &dev_attr_hotkey_bios_enabled.attr, | 912 | &dev_attr_hotkey_bios_enabled.attr, |
808 | &dev_attr_hotkey_bios_mask.attr, | 913 | &dev_attr_hotkey_bios_mask.attr, |
914 | &dev_attr_hotkey_all_mask.attr, | ||
915 | &dev_attr_hotkey_recommended_mask.attr, | ||
809 | }; | 916 | }; |
810 | 917 | ||
811 | static int __init hotkey_init(struct ibm_init_struct *iibm) | 918 | static int __init hotkey_init(struct ibm_init_struct *iibm) |
812 | { | 919 | { |
813 | int res; | 920 | |
921 | static u16 ibm_keycode_map[] __initdata = { | ||
922 | /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */ | ||
923 | KEY_FN_F1, KEY_FN_F2, KEY_COFFEE, KEY_SLEEP, | ||
924 | KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8, | ||
925 | KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND, | ||
926 | /* Scan codes 0x0C to 0x0F: Other ACPI HKEY hot keys */ | ||
927 | KEY_UNKNOWN, /* 0x0C: FN+BACKSPACE */ | ||
928 | KEY_UNKNOWN, /* 0x0D: FN+INSERT */ | ||
929 | KEY_UNKNOWN, /* 0x0E: FN+DELETE */ | ||
930 | KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */ | ||
931 | /* Scan codes 0x10 to 0x1F: Extended ACPI HKEY hot keys */ | ||
932 | KEY_RESERVED, /* 0x10: FN+END (brightness down) */ | ||
933 | KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */ | ||
934 | KEY_UNKNOWN, /* 0x12: FN+PGDOWN */ | ||
935 | KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */ | ||
936 | KEY_RESERVED, /* 0x14: VOLUME UP */ | ||
937 | KEY_RESERVED, /* 0x15: VOLUME DOWN */ | ||
938 | KEY_RESERVED, /* 0x16: MUTE */ | ||
939 | KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */ | ||
940 | /* (assignments unknown, please report if found) */ | ||
941 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, | ||
942 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, | ||
943 | }; | ||
944 | static u16 lenovo_keycode_map[] __initdata = { | ||
945 | /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */ | ||
946 | KEY_FN_F1, KEY_COFFEE, KEY_BATTERY, KEY_SLEEP, | ||
947 | KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8, | ||
948 | KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND, | ||
949 | /* Scan codes 0x0C to 0x0F: Other ACPI HKEY hot keys */ | ||
950 | KEY_UNKNOWN, /* 0x0C: FN+BACKSPACE */ | ||
951 | KEY_UNKNOWN, /* 0x0D: FN+INSERT */ | ||
952 | KEY_UNKNOWN, /* 0x0E: FN+DELETE */ | ||
953 | KEY_BRIGHTNESSUP, /* 0x0F: FN+HOME (brightness up) */ | ||
954 | /* Scan codes 0x10 to 0x1F: Extended ACPI HKEY hot keys */ | ||
955 | KEY_BRIGHTNESSDOWN, /* 0x10: FN+END (brightness down) */ | ||
956 | KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */ | ||
957 | KEY_UNKNOWN, /* 0x12: FN+PGDOWN */ | ||
958 | KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */ | ||
959 | KEY_RESERVED, /* 0x14: VOLUME UP */ | ||
960 | KEY_RESERVED, /* 0x15: VOLUME DOWN */ | ||
961 | KEY_RESERVED, /* 0x16: MUTE */ | ||
962 | KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */ | ||
963 | /* (assignments unknown, please report if found) */ | ||
964 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, | ||
965 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, | ||
966 | }; | ||
967 | |||
968 | #define TPACPI_HOTKEY_MAP_LEN ARRAY_SIZE(ibm_keycode_map) | ||
969 | #define TPACPI_HOTKEY_MAP_SIZE sizeof(ibm_keycode_map) | ||
970 | #define TPACPI_HOTKEY_MAP_TYPESIZE sizeof(ibm_keycode_map[0]) | ||
971 | |||
972 | int res, i; | ||
973 | int status; | ||
814 | 974 | ||
815 | vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n"); | 975 | vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n"); |
816 | 976 | ||
977 | BUG_ON(!tpacpi_inputdev); | ||
978 | |||
817 | IBM_ACPIHANDLE_INIT(hkey); | 979 | IBM_ACPIHANDLE_INIT(hkey); |
818 | mutex_init(&hotkey_mutex); | 980 | mutex_init(&hotkey_mutex); |
819 | 981 | ||
@@ -824,7 +986,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
824 | str_supported(tp_features.hotkey)); | 986 | str_supported(tp_features.hotkey)); |
825 | 987 | ||
826 | if (tp_features.hotkey) { | 988 | if (tp_features.hotkey) { |
827 | hotkey_dev_attributes = create_attr_set(4, NULL); | 989 | hotkey_dev_attributes = create_attr_set(7, NULL); |
828 | if (!hotkey_dev_attributes) | 990 | if (!hotkey_dev_attributes) |
829 | return -ENOMEM; | 991 | return -ENOMEM; |
830 | res = add_to_attr_set(hotkey_dev_attributes, | 992 | res = add_to_attr_set(hotkey_dev_attributes, |
@@ -840,19 +1002,92 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
840 | vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n", | 1002 | vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n", |
841 | str_supported(tp_features.hotkey_mask)); | 1003 | str_supported(tp_features.hotkey_mask)); |
842 | 1004 | ||
1005 | if (tp_features.hotkey_mask) { | ||
1006 | /* MHKA available in A31, R40, R40e, T4x, X31, and later */ | ||
1007 | if (!acpi_evalf(hkey_handle, &hotkey_all_mask, | ||
1008 | "MHKA", "qd")) | ||
1009 | hotkey_all_mask = 0x080cU; /* FN+F12, FN+F4, FN+F3 */ | ||
1010 | } | ||
1011 | |||
843 | res = hotkey_get(&hotkey_orig_status, &hotkey_orig_mask); | 1012 | res = hotkey_get(&hotkey_orig_status, &hotkey_orig_mask); |
844 | if (!res && tp_features.hotkey_mask) { | 1013 | if (!res && tp_features.hotkey_mask) { |
845 | res = add_many_to_attr_set(hotkey_dev_attributes, | 1014 | res = add_many_to_attr_set(hotkey_dev_attributes, |
846 | hotkey_mask_attributes, | 1015 | hotkey_mask_attributes, |
847 | ARRAY_SIZE(hotkey_mask_attributes)); | 1016 | ARRAY_SIZE(hotkey_mask_attributes)); |
848 | } | 1017 | } |
1018 | |||
1019 | /* Not all thinkpads have a hardware radio switch */ | ||
1020 | if (!res && acpi_evalf(hkey_handle, &status, "WLSW", "qd")) { | ||
1021 | tp_features.hotkey_wlsw = 1; | ||
1022 | printk(IBM_INFO | ||
1023 | "radio switch found; radios are %s\n", | ||
1024 | enabled(status, 0)); | ||
1025 | res = add_to_attr_set(hotkey_dev_attributes, | ||
1026 | &dev_attr_hotkey_radio_sw.attr); | ||
1027 | } | ||
1028 | |||
849 | if (!res) | 1029 | if (!res) |
850 | res = register_attr_set_with_sysfs( | 1030 | res = register_attr_set_with_sysfs( |
851 | hotkey_dev_attributes, | 1031 | hotkey_dev_attributes, |
852 | &tpacpi_pdev->dev.kobj); | 1032 | &tpacpi_pdev->dev.kobj); |
1033 | if (res) | ||
1034 | return res; | ||
1035 | |||
1036 | /* Set up key map */ | ||
1037 | |||
1038 | hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE, | ||
1039 | GFP_KERNEL); | ||
1040 | if (!hotkey_keycode_map) { | ||
1041 | printk(IBM_ERR "failed to allocate memory for key map\n"); | ||
1042 | return -ENOMEM; | ||
1043 | } | ||
1044 | |||
1045 | if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) { | ||
1046 | dbg_printk(TPACPI_DBG_INIT, | ||
1047 | "using Lenovo default hot key map\n"); | ||
1048 | memcpy(hotkey_keycode_map, &lenovo_keycode_map, | ||
1049 | TPACPI_HOTKEY_MAP_SIZE); | ||
1050 | } else { | ||
1051 | dbg_printk(TPACPI_DBG_INIT, | ||
1052 | "using IBM default hot key map\n"); | ||
1053 | memcpy(hotkey_keycode_map, &ibm_keycode_map, | ||
1054 | TPACPI_HOTKEY_MAP_SIZE); | ||
1055 | } | ||
853 | 1056 | ||
1057 | #ifndef CONFIG_THINKPAD_ACPI_INPUT_ENABLED | ||
1058 | for (i = 0; i < 12; i++) | ||
1059 | hotkey_keycode_map[i] = KEY_UNKNOWN; | ||
1060 | #endif /* ! CONFIG_THINKPAD_ACPI_INPUT_ENABLED */ | ||
1061 | |||
1062 | set_bit(EV_KEY, tpacpi_inputdev->evbit); | ||
1063 | set_bit(EV_MSC, tpacpi_inputdev->evbit); | ||
1064 | set_bit(MSC_SCAN, tpacpi_inputdev->mscbit); | ||
1065 | tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE; | ||
1066 | tpacpi_inputdev->keycodemax = TPACPI_HOTKEY_MAP_LEN; | ||
1067 | tpacpi_inputdev->keycode = hotkey_keycode_map; | ||
1068 | for (i = 0; i < TPACPI_HOTKEY_MAP_LEN; i++) { | ||
1069 | if (hotkey_keycode_map[i] != KEY_RESERVED) { | ||
1070 | set_bit(hotkey_keycode_map[i], | ||
1071 | tpacpi_inputdev->keybit); | ||
1072 | } else { | ||
1073 | if (i < sizeof(hotkey_reserved_mask)*8) | ||
1074 | hotkey_reserved_mask |= 1 << i; | ||
1075 | } | ||
1076 | } | ||
1077 | |||
1078 | if (tp_features.hotkey_wlsw) { | ||
1079 | set_bit(EV_SW, tpacpi_inputdev->evbit); | ||
1080 | set_bit(SW_RADIO, tpacpi_inputdev->swbit); | ||
1081 | } | ||
1082 | |||
1083 | #ifdef CONFIG_THINKPAD_ACPI_INPUT_ENABLED | ||
1084 | dbg_printk(TPACPI_DBG_INIT, | ||
1085 | "enabling hot key handling\n"); | ||
1086 | res = hotkey_set(1, (hotkey_all_mask & ~hotkey_reserved_mask) | ||
1087 | | hotkey_orig_mask); | ||
854 | if (res) | 1088 | if (res) |
855 | return res; | 1089 | return res; |
1090 | #endif /* CONFIG_THINKPAD_ACPI_INPUT_ENABLED */ | ||
856 | } | 1091 | } |
857 | 1092 | ||
858 | return (tp_features.hotkey)? 0 : 1; | 1093 | return (tp_features.hotkey)? 0 : 1; |
@@ -875,22 +1110,101 @@ static void hotkey_exit(void) | |||
875 | } | 1110 | } |
876 | } | 1111 | } |
877 | 1112 | ||
1113 | static void tpacpi_input_send_key(unsigned int scancode, | ||
1114 | unsigned int keycode) | ||
1115 | { | ||
1116 | if (keycode != KEY_RESERVED) { | ||
1117 | input_report_key(tpacpi_inputdev, keycode, 1); | ||
1118 | if (keycode == KEY_UNKNOWN) | ||
1119 | input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN, | ||
1120 | scancode); | ||
1121 | input_sync(tpacpi_inputdev); | ||
1122 | |||
1123 | input_report_key(tpacpi_inputdev, keycode, 0); | ||
1124 | if (keycode == KEY_UNKNOWN) | ||
1125 | input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN, | ||
1126 | scancode); | ||
1127 | input_sync(tpacpi_inputdev); | ||
1128 | } | ||
1129 | } | ||
1130 | |||
1131 | static void tpacpi_input_send_radiosw(void) | ||
1132 | { | ||
1133 | int wlsw; | ||
1134 | |||
1135 | if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw)) | ||
1136 | input_report_switch(tpacpi_inputdev, | ||
1137 | SW_RADIO, !!wlsw); | ||
1138 | } | ||
1139 | |||
878 | static void hotkey_notify(struct ibm_struct *ibm, u32 event) | 1140 | static void hotkey_notify(struct ibm_struct *ibm, u32 event) |
879 | { | 1141 | { |
880 | int hkey; | 1142 | u32 hkey; |
1143 | unsigned int keycode, scancode; | ||
1144 | int sendacpi = 1; | ||
1145 | |||
1146 | if (event == 0x80 && acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) { | ||
1147 | if (tpacpi_inputdev->users > 0) { | ||
1148 | switch (hkey >> 12) { | ||
1149 | case 1: | ||
1150 | /* 0x1000-0x1FFF: key presses */ | ||
1151 | scancode = hkey & 0xfff; | ||
1152 | if (scancode > 0 && scancode < 0x21) { | ||
1153 | scancode--; | ||
1154 | keycode = hotkey_keycode_map[scancode]; | ||
1155 | tpacpi_input_send_key(scancode, keycode); | ||
1156 | sendacpi = (keycode == KEY_RESERVED | ||
1157 | || keycode == KEY_UNKNOWN); | ||
1158 | } else { | ||
1159 | printk(IBM_ERR | ||
1160 | "hotkey 0x%04x out of range for keyboard map\n", | ||
1161 | hkey); | ||
1162 | } | ||
1163 | break; | ||
1164 | case 5: | ||
1165 | /* 0x5000-0x5FFF: LID */ | ||
1166 | /* we don't handle it through this path, just | ||
1167 | * eat up known LID events */ | ||
1168 | if (hkey != 0x5001 && hkey != 0x5002) { | ||
1169 | printk(IBM_ERR | ||
1170 | "unknown LID-related hotkey event: 0x%04x\n", | ||
1171 | hkey); | ||
1172 | } | ||
1173 | break; | ||
1174 | case 7: | ||
1175 | /* 0x7000-0x7FFF: misc */ | ||
1176 | if (tp_features.hotkey_wlsw && hkey == 0x7000) { | ||
1177 | tpacpi_input_send_radiosw(); | ||
1178 | sendacpi = 0; | ||
1179 | break; | ||
1180 | } | ||
1181 | /* fallthrough to default */ | ||
1182 | default: | ||
1183 | /* case 2: dock-related */ | ||
1184 | /* 0x2305 - T43 waking up due to bay lever eject while aslept */ | ||
1185 | /* case 3: ultra-bay related. maybe bay in dock? */ | ||
1186 | /* 0x3003 - T43 after wake up by bay lever eject (0x2305) */ | ||
1187 | printk(IBM_NOTICE "unhandled hotkey event 0x%04x\n", hkey); | ||
1188 | } | ||
1189 | } | ||
881 | 1190 | ||
882 | if (acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) | 1191 | if (sendacpi) |
883 | acpi_bus_generate_event(ibm->acpi->device, event, hkey); | 1192 | acpi_bus_generate_event(ibm->acpi->device, event, hkey); |
884 | else { | 1193 | } else { |
885 | printk(IBM_ERR "unknown hotkey event %d\n", event); | 1194 | printk(IBM_ERR "unknown hotkey notification event %d\n", event); |
886 | acpi_bus_generate_event(ibm->acpi->device, event, 0); | 1195 | acpi_bus_generate_event(ibm->acpi->device, event, 0); |
887 | } | 1196 | } |
888 | } | 1197 | } |
889 | 1198 | ||
1199 | static void hotkey_resume(void) | ||
1200 | { | ||
1201 | tpacpi_input_send_radiosw(); | ||
1202 | } | ||
1203 | |||
890 | /* | 1204 | /* |
891 | * Call with hotkey_mutex held | 1205 | * Call with hotkey_mutex held |
892 | */ | 1206 | */ |
893 | static int hotkey_get(int *status, int *mask) | 1207 | static int hotkey_get(int *status, u32 *mask) |
894 | { | 1208 | { |
895 | if (!acpi_evalf(hkey_handle, status, "DHKC", "d")) | 1209 | if (!acpi_evalf(hkey_handle, status, "DHKC", "d")) |
896 | return -EIO; | 1210 | return -EIO; |
@@ -905,7 +1219,7 @@ static int hotkey_get(int *status, int *mask) | |||
905 | /* | 1219 | /* |
906 | * Call with hotkey_mutex held | 1220 | * Call with hotkey_mutex held |
907 | */ | 1221 | */ |
908 | static int hotkey_set(int status, int mask) | 1222 | static int hotkey_set(int status, u32 mask) |
909 | { | 1223 | { |
910 | int i; | 1224 | int i; |
911 | 1225 | ||
@@ -926,7 +1240,8 @@ static int hotkey_set(int status, int mask) | |||
926 | /* procfs -------------------------------------------------------------- */ | 1240 | /* procfs -------------------------------------------------------------- */ |
927 | static int hotkey_read(char *p) | 1241 | static int hotkey_read(char *p) |
928 | { | 1242 | { |
929 | int res, status, mask; | 1243 | int res, status; |
1244 | u32 mask; | ||
930 | int len = 0; | 1245 | int len = 0; |
931 | 1246 | ||
932 | if (!tp_features.hotkey) { | 1247 | if (!tp_features.hotkey) { |
@@ -944,7 +1259,7 @@ static int hotkey_read(char *p) | |||
944 | 1259 | ||
945 | len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0)); | 1260 | len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0)); |
946 | if (tp_features.hotkey_mask) { | 1261 | if (tp_features.hotkey_mask) { |
947 | len += sprintf(p + len, "mask:\t\t0x%04x\n", mask); | 1262 | len += sprintf(p + len, "mask:\t\t0x%08x\n", mask); |
948 | len += sprintf(p + len, | 1263 | len += sprintf(p + len, |
949 | "commands:\tenable, disable, reset, <mask>\n"); | 1264 | "commands:\tenable, disable, reset, <mask>\n"); |
950 | } else { | 1265 | } else { |
@@ -957,7 +1272,8 @@ static int hotkey_read(char *p) | |||
957 | 1272 | ||
958 | static int hotkey_write(char *buf) | 1273 | static int hotkey_write(char *buf) |
959 | { | 1274 | { |
960 | int res, status, mask; | 1275 | int res, status; |
1276 | u32 mask; | ||
961 | char *cmd; | 1277 | char *cmd; |
962 | int do_cmd = 0; | 1278 | int do_cmd = 0; |
963 | 1279 | ||
@@ -1012,6 +1328,7 @@ static struct ibm_struct hotkey_driver_data = { | |||
1012 | .read = hotkey_read, | 1328 | .read = hotkey_read, |
1013 | .write = hotkey_write, | 1329 | .write = hotkey_write, |
1014 | .exit = hotkey_exit, | 1330 | .exit = hotkey_exit, |
1331 | .resume = hotkey_resume, | ||
1015 | .acpi = &ibm_hotkey_acpidriver, | 1332 | .acpi = &ibm_hotkey_acpidriver, |
1016 | }; | 1333 | }; |
1017 | 1334 | ||
@@ -1770,7 +2087,10 @@ static struct tp_acpi_drv_struct ibm_dock_acpidriver[2] = { | |||
1770 | .type = ACPI_SYSTEM_NOTIFY, | 2087 | .type = ACPI_SYSTEM_NOTIFY, |
1771 | }, | 2088 | }, |
1772 | { | 2089 | { |
1773 | .hid = IBM_PCI_HID, | 2090 | /* THIS ONE MUST NEVER BE USED FOR DRIVER AUTOLOADING. |
2091 | * We just use it to get notifications of dock hotplug | ||
2092 | * in very old thinkpads */ | ||
2093 | .hid = PCI_ROOT_HID_STRING, | ||
1774 | .notify = dock_notify, | 2094 | .notify = dock_notify, |
1775 | .handle = &pci_handle, | 2095 | .handle = &pci_handle, |
1776 | .type = ACPI_SYSTEM_NOTIFY, | 2096 | .type = ACPI_SYSTEM_NOTIFY, |
@@ -1829,7 +2149,7 @@ static int __init dock_init2(struct ibm_init_struct *iibm) | |||
1829 | static void dock_notify(struct ibm_struct *ibm, u32 event) | 2149 | static void dock_notify(struct ibm_struct *ibm, u32 event) |
1830 | { | 2150 | { |
1831 | int docked = dock_docked(); | 2151 | int docked = dock_docked(); |
1832 | int pci = ibm->acpi->hid && strstr(ibm->acpi->hid, IBM_PCI_HID); | 2152 | int pci = ibm->acpi->hid && strstr(ibm->acpi->hid, PCI_ROOT_HID_STRING); |
1833 | 2153 | ||
1834 | if (event == 1 && !pci) /* 570 */ | 2154 | if (event == 1 && !pci) /* 570 */ |
1835 | acpi_bus_generate_event(ibm->acpi->device, event, 1); /* button */ | 2155 | acpi_bus_generate_event(ibm->acpi->device, event, 1); /* button */ |
@@ -2389,7 +2709,7 @@ static int __init thermal_init(struct ibm_init_struct *iibm) | |||
2389 | 2709 | ||
2390 | acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv"); | 2710 | acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv"); |
2391 | 2711 | ||
2392 | if (ibm_thinkpad_ec_found && experimental) { | 2712 | if (thinkpad_id.ec_model) { |
2393 | /* | 2713 | /* |
2394 | * Direct EC access mode: sensors at registers | 2714 | * Direct EC access mode: sensors at registers |
2395 | * 0x78-0x7F, 0xC0-0xC7. Registers return 0x00 for | 2715 | * 0x78-0x7F, 0xC0-0xC7. Registers return 0x00 for |
@@ -2533,6 +2853,8 @@ static int thermal_get_sensor(int idx, s32 *value) | |||
2533 | snprintf(tmpi, sizeof(tmpi), "TMP%c", '0' + idx); | 2853 | snprintf(tmpi, sizeof(tmpi), "TMP%c", '0' + idx); |
2534 | if (!acpi_evalf(ec_handle, &t, tmpi, "d")) | 2854 | if (!acpi_evalf(ec_handle, &t, tmpi, "d")) |
2535 | return -EIO; | 2855 | return -EIO; |
2856 | if (t > 127 || t < -127) | ||
2857 | t = TP_EC_THERMAL_TMP_NA; | ||
2536 | *value = t * 1000; | 2858 | *value = t * 1000; |
2537 | return 0; | 2859 | return 0; |
2538 | } | 2860 | } |
@@ -2671,22 +2993,39 @@ static struct ibm_struct ecdump_driver_data = { | |||
2671 | * Backlight/brightness subdriver | 2993 | * Backlight/brightness subdriver |
2672 | */ | 2994 | */ |
2673 | 2995 | ||
2674 | static struct backlight_device *ibm_backlight_device = NULL; | 2996 | static struct backlight_device *ibm_backlight_device; |
2675 | 2997 | ||
2676 | static struct backlight_ops ibm_backlight_data = { | 2998 | static struct backlight_ops ibm_backlight_data = { |
2677 | .get_brightness = brightness_get, | 2999 | .get_brightness = brightness_get, |
2678 | .update_status = brightness_update_status, | 3000 | .update_status = brightness_update_status, |
2679 | }; | 3001 | }; |
2680 | 3002 | ||
3003 | static struct mutex brightness_mutex; | ||
3004 | |||
2681 | static int __init brightness_init(struct ibm_init_struct *iibm) | 3005 | static int __init brightness_init(struct ibm_init_struct *iibm) |
2682 | { | 3006 | { |
2683 | int b; | 3007 | int b; |
2684 | 3008 | ||
2685 | vdbg_printk(TPACPI_DBG_INIT, "initializing brightness subdriver\n"); | 3009 | vdbg_printk(TPACPI_DBG_INIT, "initializing brightness subdriver\n"); |
2686 | 3010 | ||
3011 | mutex_init(&brightness_mutex); | ||
3012 | |||
3013 | if (!brightness_mode) { | ||
3014 | if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) | ||
3015 | brightness_mode = 2; | ||
3016 | else | ||
3017 | brightness_mode = 3; | ||
3018 | |||
3019 | dbg_printk(TPACPI_DBG_INIT, "selected brightness_mode=%d\n", | ||
3020 | brightness_mode); | ||
3021 | } | ||
3022 | |||
3023 | if (brightness_mode > 3) | ||
3024 | return -EINVAL; | ||
3025 | |||
2687 | b = brightness_get(NULL); | 3026 | b = brightness_get(NULL); |
2688 | if (b < 0) | 3027 | if (b < 0) |
2689 | return b; | 3028 | return 1; |
2690 | 3029 | ||
2691 | ibm_backlight_device = backlight_device_register( | 3030 | ibm_backlight_device = backlight_device_register( |
2692 | TPACPI_BACKLIGHT_DEV_NAME, NULL, NULL, | 3031 | TPACPI_BACKLIGHT_DEV_NAME, NULL, NULL, |
@@ -2722,34 +3061,79 @@ static int brightness_update_status(struct backlight_device *bd) | |||
2722 | bd->props.brightness : 0); | 3061 | bd->props.brightness : 0); |
2723 | } | 3062 | } |
2724 | 3063 | ||
3064 | /* | ||
3065 | * ThinkPads can read brightness from two places: EC 0x31, or | ||
3066 | * CMOS NVRAM byte 0x5E, bits 0-3. | ||
3067 | */ | ||
2725 | static int brightness_get(struct backlight_device *bd) | 3068 | static int brightness_get(struct backlight_device *bd) |
2726 | { | 3069 | { |
2727 | u8 level; | 3070 | u8 lec = 0, lcmos = 0, level = 0; |
2728 | if (!acpi_ec_read(brightness_offset, &level)) | ||
2729 | return -EIO; | ||
2730 | 3071 | ||
2731 | level &= 0x7; | 3072 | if (brightness_mode & 1) { |
3073 | if (!acpi_ec_read(brightness_offset, &lec)) | ||
3074 | return -EIO; | ||
3075 | lec &= 7; | ||
3076 | level = lec; | ||
3077 | }; | ||
3078 | if (brightness_mode & 2) { | ||
3079 | lcmos = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS) | ||
3080 | & TP_NVRAM_MASK_LEVEL_BRIGHTNESS) | ||
3081 | >> TP_NVRAM_POS_LEVEL_BRIGHTNESS; | ||
3082 | level = lcmos; | ||
3083 | } | ||
3084 | |||
3085 | if (brightness_mode == 3 && lec != lcmos) { | ||
3086 | printk(IBM_ERR | ||
3087 | "CMOS NVRAM (%u) and EC (%u) do not agree " | ||
3088 | "on display brightness level\n", | ||
3089 | (unsigned int) lcmos, | ||
3090 | (unsigned int) lec); | ||
3091 | return -EIO; | ||
3092 | } | ||
2732 | 3093 | ||
2733 | return level; | 3094 | return level; |
2734 | } | 3095 | } |
2735 | 3096 | ||
2736 | static int brightness_set(int value) | 3097 | static int brightness_set(int value) |
2737 | { | 3098 | { |
2738 | int cmos_cmd, inc, i; | 3099 | int cmos_cmd, inc, i, res; |
2739 | int current_value = brightness_get(NULL); | 3100 | int current_value; |
3101 | |||
3102 | if (value > 7) | ||
3103 | return -EINVAL; | ||
2740 | 3104 | ||
2741 | value &= 7; | 3105 | res = mutex_lock_interruptible(&brightness_mutex); |
3106 | if (res < 0) | ||
3107 | return res; | ||
3108 | |||
3109 | current_value = brightness_get(NULL); | ||
3110 | if (current_value < 0) { | ||
3111 | res = current_value; | ||
3112 | goto errout; | ||
3113 | } | ||
2742 | 3114 | ||
2743 | cmos_cmd = value > current_value ? TP_CMOS_BRIGHTNESS_UP : TP_CMOS_BRIGHTNESS_DOWN; | 3115 | cmos_cmd = value > current_value ? |
3116 | TP_CMOS_BRIGHTNESS_UP : | ||
3117 | TP_CMOS_BRIGHTNESS_DOWN; | ||
2744 | inc = value > current_value ? 1 : -1; | 3118 | inc = value > current_value ? 1 : -1; |
3119 | |||
3120 | res = 0; | ||
2745 | for (i = current_value; i != value; i += inc) { | 3121 | for (i = current_value; i != value; i += inc) { |
2746 | if (issue_thinkpad_cmos_command(cmos_cmd)) | 3122 | if ((brightness_mode & 2) && |
2747 | return -EIO; | 3123 | issue_thinkpad_cmos_command(cmos_cmd)) { |
2748 | if (!acpi_ec_write(brightness_offset, i + inc)) | 3124 | res = -EIO; |
2749 | return -EIO; | 3125 | goto errout; |
3126 | } | ||
3127 | if ((brightness_mode & 1) && | ||
3128 | !acpi_ec_write(brightness_offset, i + inc)) { | ||
3129 | res = -EIO; | ||
3130 | goto errout;; | ||
3131 | } | ||
2750 | } | 3132 | } |
2751 | 3133 | ||
2752 | return 0; | 3134 | errout: |
3135 | mutex_unlock(&brightness_mutex); | ||
3136 | return res; | ||
2753 | } | 3137 | } |
2754 | 3138 | ||
2755 | static int brightness_read(char *p) | 3139 | static int brightness_read(char *p) |
@@ -3273,20 +3657,19 @@ static int __init fan_init(struct ibm_init_struct *iibm) | |||
3273 | * Enable for TP-1Y (T43), TP-78 (R51e), | 3657 | * Enable for TP-1Y (T43), TP-78 (R51e), |
3274 | * TP-76 (R52), TP-70 (T43, R52), which are known | 3658 | * TP-76 (R52), TP-70 (T43, R52), which are known |
3275 | * to be buggy. */ | 3659 | * to be buggy. */ |
3276 | if (fan_control_initial_status == 0x07 && | 3660 | if (fan_control_initial_status == 0x07) { |
3277 | ibm_thinkpad_ec_found && | 3661 | switch (thinkpad_id.ec_model) { |
3278 | ((ibm_thinkpad_ec_found[0] == '1' && | 3662 | case 0x5931: /* TP-1Y */ |
3279 | ibm_thinkpad_ec_found[1] == 'Y') || | 3663 | case 0x3837: /* TP-78 */ |
3280 | (ibm_thinkpad_ec_found[0] == '7' && | 3664 | case 0x3637: /* TP-76 */ |
3281 | (ibm_thinkpad_ec_found[1] == '6' || | 3665 | case 0x3037: /* TP-70 */ |
3282 | ibm_thinkpad_ec_found[1] == '8' || | 3666 | printk(IBM_NOTICE |
3283 | ibm_thinkpad_ec_found[1] == '0')) | 3667 | "fan_init: initial fan status is " |
3284 | )) { | 3668 | "unknown, assuming it is in auto " |
3285 | printk(IBM_NOTICE | 3669 | "mode\n"); |
3286 | "fan_init: initial fan status is " | 3670 | tp_features.fan_ctrl_status_undef = 1; |
3287 | "unknown, assuming it is in auto " | 3671 | ;; |
3288 | "mode\n"); | 3672 | } |
3289 | tp_features.fan_ctrl_status_undef = 1; | ||
3290 | } | 3673 | } |
3291 | } else { | 3674 | } else { |
3292 | printk(IBM_ERR | 3675 | printk(IBM_ERR |
@@ -3474,7 +3857,7 @@ static void fan_watchdog_fire(struct work_struct *ignored) | |||
3474 | 3857 | ||
3475 | static void fan_watchdog_reset(void) | 3858 | static void fan_watchdog_reset(void) |
3476 | { | 3859 | { |
3477 | static int fan_watchdog_active = 0; | 3860 | static int fan_watchdog_active; |
3478 | 3861 | ||
3479 | if (fan_control_access_mode == TPACPI_FAN_WR_NONE) | 3862 | if (fan_control_access_mode == TPACPI_FAN_WR_NONE) |
3480 | return; | 3863 | return; |
@@ -3877,7 +4260,7 @@ static struct ibm_struct fan_driver_data = { | |||
3877 | ****************************************************************************/ | 4260 | ****************************************************************************/ |
3878 | 4261 | ||
3879 | /* /proc support */ | 4262 | /* /proc support */ |
3880 | static struct proc_dir_entry *proc_dir = NULL; | 4263 | static struct proc_dir_entry *proc_dir; |
3881 | 4264 | ||
3882 | /* Subdriver registry */ | 4265 | /* Subdriver registry */ |
3883 | static LIST_HEAD(tpacpi_all_drivers); | 4266 | static LIST_HEAD(tpacpi_all_drivers); |
@@ -4020,13 +4403,30 @@ static void ibm_exit(struct ibm_struct *ibm) | |||
4020 | 4403 | ||
4021 | /* Probing */ | 4404 | /* Probing */ |
4022 | 4405 | ||
4023 | static char *ibm_thinkpad_ec_found = NULL; | 4406 | static void __init get_thinkpad_model_data(struct thinkpad_id_data *tp) |
4024 | |||
4025 | static char* __init check_dmi_for_ec(void) | ||
4026 | { | 4407 | { |
4027 | struct dmi_device *dev = NULL; | 4408 | struct dmi_device *dev = NULL; |
4028 | char ec_fw_string[18]; | 4409 | char ec_fw_string[18]; |
4029 | 4410 | ||
4411 | if (!tp) | ||
4412 | return; | ||
4413 | |||
4414 | memset(tp, 0, sizeof(*tp)); | ||
4415 | |||
4416 | if (dmi_name_in_vendors("IBM")) | ||
4417 | tp->vendor = PCI_VENDOR_ID_IBM; | ||
4418 | else if (dmi_name_in_vendors("LENOVO")) | ||
4419 | tp->vendor = PCI_VENDOR_ID_LENOVO; | ||
4420 | else | ||
4421 | return; | ||
4422 | |||
4423 | tp->bios_version_str = kstrdup(dmi_get_system_info(DMI_BIOS_VERSION), | ||
4424 | GFP_KERNEL); | ||
4425 | if (!tp->bios_version_str) | ||
4426 | return; | ||
4427 | tp->bios_model = tp->bios_version_str[0] | ||
4428 | | (tp->bios_version_str[1] << 8); | ||
4429 | |||
4030 | /* | 4430 | /* |
4031 | * ThinkPad T23 or newer, A31 or newer, R50e or newer, | 4431 | * ThinkPad T23 or newer, A31 or newer, R50e or newer, |
4032 | * X32 or newer, all Z series; Some models must have an | 4432 | * X32 or newer, all Z series; Some models must have an |
@@ -4040,10 +4440,20 @@ static char* __init check_dmi_for_ec(void) | |||
4040 | ec_fw_string) == 1) { | 4440 | ec_fw_string) == 1) { |
4041 | ec_fw_string[sizeof(ec_fw_string) - 1] = 0; | 4441 | ec_fw_string[sizeof(ec_fw_string) - 1] = 0; |
4042 | ec_fw_string[strcspn(ec_fw_string, " ]")] = 0; | 4442 | ec_fw_string[strcspn(ec_fw_string, " ]")] = 0; |
4043 | return kstrdup(ec_fw_string, GFP_KERNEL); | 4443 | |
4444 | tp->ec_version_str = kstrdup(ec_fw_string, GFP_KERNEL); | ||
4445 | tp->ec_model = ec_fw_string[0] | ||
4446 | | (ec_fw_string[1] << 8); | ||
4447 | break; | ||
4044 | } | 4448 | } |
4045 | } | 4449 | } |
4046 | return NULL; | 4450 | |
4451 | tp->model_str = kstrdup(dmi_get_system_info(DMI_PRODUCT_VERSION), | ||
4452 | GFP_KERNEL); | ||
4453 | if (strnicmp(tp->model_str, "ThinkPad", 8) != 0) { | ||
4454 | kfree(tp->model_str); | ||
4455 | tp->model_str = NULL; | ||
4456 | } | ||
4047 | } | 4457 | } |
4048 | 4458 | ||
4049 | static int __init probe_for_thinkpad(void) | 4459 | static int __init probe_for_thinkpad(void) |
@@ -4057,7 +4467,7 @@ static int __init probe_for_thinkpad(void) | |||
4057 | * Non-ancient models have better DMI tagging, but very old models | 4467 | * Non-ancient models have better DMI tagging, but very old models |
4058 | * don't. | 4468 | * don't. |
4059 | */ | 4469 | */ |
4060 | is_thinkpad = dmi_name_in_vendors("ThinkPad"); | 4470 | is_thinkpad = (thinkpad_id.model_str != NULL); |
4061 | 4471 | ||
4062 | /* ec is required because many other handles are relative to it */ | 4472 | /* ec is required because many other handles are relative to it */ |
4063 | IBM_ACPIHANDLE_INIT(ec); | 4473 | IBM_ACPIHANDLE_INIT(ec); |
@@ -4073,7 +4483,7 @@ static int __init probe_for_thinkpad(void) | |||
4073 | * false positives a damn great deal | 4483 | * false positives a damn great deal |
4074 | */ | 4484 | */ |
4075 | if (!is_thinkpad) | 4485 | if (!is_thinkpad) |
4076 | is_thinkpad = dmi_name_in_vendors("IBM"); | 4486 | is_thinkpad = (thinkpad_id.vendor == PCI_VENDOR_ID_IBM); |
4077 | 4487 | ||
4078 | if (!is_thinkpad && !force_load) | 4488 | if (!is_thinkpad && !force_load) |
4079 | return -ENODEV; | 4489 | return -ENODEV; |
@@ -4185,10 +4595,13 @@ static u32 dbg_level; | |||
4185 | module_param_named(debug, dbg_level, uint, 0); | 4595 | module_param_named(debug, dbg_level, uint, 0); |
4186 | 4596 | ||
4187 | static int force_load; | 4597 | static int force_load; |
4188 | module_param(force_load, int, 0); | 4598 | module_param(force_load, bool, 0); |
4189 | 4599 | ||
4190 | static int fan_control_allowed; | 4600 | static int fan_control_allowed; |
4191 | module_param_named(fan_control, fan_control_allowed, int, 0); | 4601 | module_param_named(fan_control, fan_control_allowed, bool, 0); |
4602 | |||
4603 | static int brightness_mode; | ||
4604 | module_param_named(brightness_mode, brightness_mode, int, 0); | ||
4192 | 4605 | ||
4193 | #define IBM_PARAM(feature) \ | 4606 | #define IBM_PARAM(feature) \ |
4194 | module_param_call(feature, set_ibm_param, NULL, NULL, 0) | 4607 | module_param_call(feature, set_ibm_param, NULL, NULL, 0) |
@@ -4216,12 +4629,16 @@ static int __init thinkpad_acpi_module_init(void) | |||
4216 | int ret, i; | 4629 | int ret, i; |
4217 | 4630 | ||
4218 | /* Driver-level probe */ | 4631 | /* Driver-level probe */ |
4632 | |||
4633 | get_thinkpad_model_data(&thinkpad_id); | ||
4219 | ret = probe_for_thinkpad(); | 4634 | ret = probe_for_thinkpad(); |
4220 | if (ret) | 4635 | if (ret) { |
4636 | thinkpad_acpi_module_exit(); | ||
4221 | return ret; | 4637 | return ret; |
4638 | } | ||
4222 | 4639 | ||
4223 | /* Driver initialization */ | 4640 | /* Driver initialization */ |
4224 | ibm_thinkpad_ec_found = check_dmi_for_ec(); | 4641 | |
4225 | IBM_ACPIHANDLE_INIT(ecrd); | 4642 | IBM_ACPIHANDLE_INIT(ecrd); |
4226 | IBM_ACPIHANDLE_INIT(ecwr); | 4643 | IBM_ACPIHANDLE_INIT(ecwr); |
4227 | 4644 | ||
@@ -4265,6 +4682,22 @@ static int __init thinkpad_acpi_module_init(void) | |||
4265 | thinkpad_acpi_module_exit(); | 4682 | thinkpad_acpi_module_exit(); |
4266 | return ret; | 4683 | return ret; |
4267 | } | 4684 | } |
4685 | tpacpi_inputdev = input_allocate_device(); | ||
4686 | if (!tpacpi_inputdev) { | ||
4687 | printk(IBM_ERR "unable to allocate input device\n"); | ||
4688 | thinkpad_acpi_module_exit(); | ||
4689 | return -ENOMEM; | ||
4690 | } else { | ||
4691 | /* Prepare input device, but don't register */ | ||
4692 | tpacpi_inputdev->name = "ThinkPad Extra Buttons"; | ||
4693 | tpacpi_inputdev->phys = IBM_DRVR_NAME "/input0"; | ||
4694 | tpacpi_inputdev->id.bustype = BUS_HOST; | ||
4695 | tpacpi_inputdev->id.vendor = (thinkpad_id.vendor) ? | ||
4696 | thinkpad_id.vendor : | ||
4697 | PCI_VENDOR_ID_IBM; | ||
4698 | tpacpi_inputdev->id.product = TPACPI_HKEY_INPUT_PRODUCT; | ||
4699 | tpacpi_inputdev->id.version = TPACPI_HKEY_INPUT_VERSION; | ||
4700 | } | ||
4268 | for (i = 0; i < ARRAY_SIZE(ibms_init); i++) { | 4701 | for (i = 0; i < ARRAY_SIZE(ibms_init); i++) { |
4269 | ret = ibm_init(&ibms_init[i]); | 4702 | ret = ibm_init(&ibms_init[i]); |
4270 | if (ret >= 0 && *ibms_init[i].param) | 4703 | if (ret >= 0 && *ibms_init[i].param) |
@@ -4274,6 +4707,14 @@ static int __init thinkpad_acpi_module_init(void) | |||
4274 | return ret; | 4707 | return ret; |
4275 | } | 4708 | } |
4276 | } | 4709 | } |
4710 | ret = input_register_device(tpacpi_inputdev); | ||
4711 | if (ret < 0) { | ||
4712 | printk(IBM_ERR "unable to register input device\n"); | ||
4713 | thinkpad_acpi_module_exit(); | ||
4714 | return ret; | ||
4715 | } else { | ||
4716 | tp_features.input_device_registered = 1; | ||
4717 | } | ||
4277 | 4718 | ||
4278 | return 0; | 4719 | return 0; |
4279 | } | 4720 | } |
@@ -4290,6 +4731,13 @@ static void thinkpad_acpi_module_exit(void) | |||
4290 | 4731 | ||
4291 | dbg_printk(TPACPI_DBG_INIT, "finished subdriver exit path...\n"); | 4732 | dbg_printk(TPACPI_DBG_INIT, "finished subdriver exit path...\n"); |
4292 | 4733 | ||
4734 | if (tpacpi_inputdev) { | ||
4735 | if (tp_features.input_device_registered) | ||
4736 | input_unregister_device(tpacpi_inputdev); | ||
4737 | else | ||
4738 | input_free_device(tpacpi_inputdev); | ||
4739 | } | ||
4740 | |||
4293 | if (tpacpi_hwmon) | 4741 | if (tpacpi_hwmon) |
4294 | hwmon_device_unregister(tpacpi_hwmon); | 4742 | hwmon_device_unregister(tpacpi_hwmon); |
4295 | 4743 | ||
@@ -4302,7 +4750,9 @@ static void thinkpad_acpi_module_exit(void) | |||
4302 | if (proc_dir) | 4750 | if (proc_dir) |
4303 | remove_proc_entry(IBM_PROC_DIR, acpi_root_dir); | 4751 | remove_proc_entry(IBM_PROC_DIR, acpi_root_dir); |
4304 | 4752 | ||
4305 | kfree(ibm_thinkpad_ec_found); | 4753 | kfree(thinkpad_id.bios_version_str); |
4754 | kfree(thinkpad_id.ec_version_str); | ||
4755 | kfree(thinkpad_id.model_str); | ||
4306 | } | 4756 | } |
4307 | 4757 | ||
4308 | module_init(thinkpad_acpi_module_init); | 4758 | module_init(thinkpad_acpi_module_init); |
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h index 72d62f2dabb9..b7a4a888cc8b 100644 --- a/drivers/misc/thinkpad_acpi.h +++ b/drivers/misc/thinkpad_acpi.h | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/list.h> | 32 | #include <linux/list.h> |
33 | #include <linux/mutex.h> | 33 | #include <linux/mutex.h> |
34 | 34 | ||
35 | #include <linux/nvram.h> | ||
35 | #include <linux/proc_fs.h> | 36 | #include <linux/proc_fs.h> |
36 | #include <linux/sysfs.h> | 37 | #include <linux/sysfs.h> |
37 | #include <linux/backlight.h> | 38 | #include <linux/backlight.h> |
@@ -39,6 +40,7 @@ | |||
39 | #include <linux/platform_device.h> | 40 | #include <linux/platform_device.h> |
40 | #include <linux/hwmon.h> | 41 | #include <linux/hwmon.h> |
41 | #include <linux/hwmon-sysfs.h> | 42 | #include <linux/hwmon-sysfs.h> |
43 | #include <linux/input.h> | ||
42 | #include <asm/uaccess.h> | 44 | #include <asm/uaccess.h> |
43 | 45 | ||
44 | #include <linux/dmi.h> | 46 | #include <linux/dmi.h> |
@@ -48,6 +50,7 @@ | |||
48 | #include <acpi/acpi_drivers.h> | 50 | #include <acpi/acpi_drivers.h> |
49 | #include <acpi/acnamesp.h> | 51 | #include <acpi/acnamesp.h> |
50 | 52 | ||
53 | #include <linux/pci_ids.h> | ||
51 | 54 | ||
52 | /**************************************************************************** | 55 | /**************************************************************************** |
53 | * Main driver | 56 | * Main driver |
@@ -78,6 +81,11 @@ | |||
78 | #define TP_CMOS_BRIGHTNESS_UP 4 | 81 | #define TP_CMOS_BRIGHTNESS_UP 4 |
79 | #define TP_CMOS_BRIGHTNESS_DOWN 5 | 82 | #define TP_CMOS_BRIGHTNESS_DOWN 5 |
80 | 83 | ||
84 | /* ThinkPad CMOS NVRAM constants */ | ||
85 | #define TP_NVRAM_ADDR_BRIGHTNESS 0x5e | ||
86 | #define TP_NVRAM_MASK_LEVEL_BRIGHTNESS 0x07 | ||
87 | #define TP_NVRAM_POS_LEVEL_BRIGHTNESS 0 | ||
88 | |||
81 | #define onoff(status,bit) ((status) & (1 << (bit)) ? "on" : "off") | 89 | #define onoff(status,bit) ((status) & (1 << (bit)) ? "on" : "off") |
82 | #define enabled(status,bit) ((status) & (1 << (bit)) ? "enabled" : "disabled") | 90 | #define enabled(status,bit) ((status) & (1 << (bit)) ? "enabled" : "disabled") |
83 | #define strlencmp(a,b) (strncmp((a), (b), strlen(b))) | 91 | #define strlencmp(a,b) (strncmp((a), (b), strlen(b))) |
@@ -98,9 +106,13 @@ static const char *str_supported(int is_supported); | |||
98 | #define vdbg_printk(a_dbg_level, format, arg...) | 106 | #define vdbg_printk(a_dbg_level, format, arg...) |
99 | #endif | 107 | #endif |
100 | 108 | ||
109 | /* Input IDs */ | ||
110 | #define TPACPI_HKEY_INPUT_VENDOR PCI_VENDOR_ID_IBM | ||
111 | #define TPACPI_HKEY_INPUT_PRODUCT 0x5054 /* "TP" */ | ||
112 | #define TPACPI_HKEY_INPUT_VERSION 0x4101 | ||
113 | |||
101 | /* ACPI HIDs */ | 114 | /* ACPI HIDs */ |
102 | #define IBM_HKEY_HID "IBM0068" | 115 | #define IBM_HKEY_HID "IBM0068" |
103 | #define IBM_PCI_HID "PNP0A03" | ||
104 | 116 | ||
105 | /* ACPI helpers */ | 117 | /* ACPI helpers */ |
106 | static int __must_check acpi_evalf(acpi_handle handle, | 118 | static int __must_check acpi_evalf(acpi_handle handle, |
@@ -161,6 +173,7 @@ static int parse_strtoul(const char *buf, unsigned long max, | |||
161 | static struct platform_device *tpacpi_pdev; | 173 | static struct platform_device *tpacpi_pdev; |
162 | static struct class_device *tpacpi_hwmon; | 174 | static struct class_device *tpacpi_hwmon; |
163 | static struct platform_driver tpacpi_pdriver; | 175 | static struct platform_driver tpacpi_pdriver; |
176 | static struct input_dev *tpacpi_inputdev; | ||
164 | static int tpacpi_create_driver_attributes(struct device_driver *drv); | 177 | static int tpacpi_create_driver_attributes(struct device_driver *drv); |
165 | static void tpacpi_remove_driver_attributes(struct device_driver *drv); | 178 | static void tpacpi_remove_driver_attributes(struct device_driver *drv); |
166 | 179 | ||
@@ -168,9 +181,7 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv); | |||
168 | static int experimental; | 181 | static int experimental; |
169 | static u32 dbg_level; | 182 | static u32 dbg_level; |
170 | static int force_load; | 183 | static int force_load; |
171 | static char *ibm_thinkpad_ec_found; | ||
172 | 184 | ||
173 | static char* check_dmi_for_ec(void); | ||
174 | static int thinkpad_acpi_module_init(void); | 185 | static int thinkpad_acpi_module_init(void); |
175 | static void thinkpad_acpi_module_exit(void); | 186 | static void thinkpad_acpi_module_exit(void); |
176 | 187 | ||
@@ -197,6 +208,7 @@ struct ibm_struct { | |||
197 | int (*read) (char *); | 208 | int (*read) (char *); |
198 | int (*write) (char *); | 209 | int (*write) (char *); |
199 | void (*exit) (void); | 210 | void (*exit) (void); |
211 | void (*resume) (void); | ||
200 | 212 | ||
201 | struct list_head all_drivers; | 213 | struct list_head all_drivers; |
202 | 214 | ||
@@ -228,12 +240,29 @@ static struct { | |||
228 | u16 bluetooth:1; | 240 | u16 bluetooth:1; |
229 | u16 hotkey:1; | 241 | u16 hotkey:1; |
230 | u16 hotkey_mask:1; | 242 | u16 hotkey_mask:1; |
243 | u16 hotkey_wlsw:1; | ||
231 | u16 light:1; | 244 | u16 light:1; |
232 | u16 light_status:1; | 245 | u16 light_status:1; |
233 | u16 wan:1; | 246 | u16 wan:1; |
234 | u16 fan_ctrl_status_undef:1; | 247 | u16 fan_ctrl_status_undef:1; |
248 | u16 input_device_registered:1; | ||
235 | } tp_features; | 249 | } tp_features; |
236 | 250 | ||
251 | struct thinkpad_id_data { | ||
252 | unsigned int vendor; /* ThinkPad vendor: | ||
253 | * PCI_VENDOR_ID_IBM/PCI_VENDOR_ID_LENOVO */ | ||
254 | |||
255 | char *bios_version_str; /* Something like 1ZET51WW (1.03z) */ | ||
256 | char *ec_version_str; /* Something like 1ZHT51WW-1.04a */ | ||
257 | |||
258 | u16 bios_model; /* Big Endian, TP-1Y = 0x5931, 0 = unknown */ | ||
259 | u16 ec_model; | ||
260 | |||
261 | char *model_str; | ||
262 | }; | ||
263 | |||
264 | static struct thinkpad_id_data thinkpad_id; | ||
265 | |||
237 | static struct list_head tpacpi_all_drivers; | 266 | static struct list_head tpacpi_all_drivers; |
238 | 267 | ||
239 | static struct ibm_init_struct ibms_init[]; | 268 | static struct ibm_init_struct ibms_init[]; |
@@ -300,6 +329,7 @@ static int bluetooth_write(char *buf); | |||
300 | 329 | ||
301 | static struct backlight_device *ibm_backlight_device; | 330 | static struct backlight_device *ibm_backlight_device; |
302 | static int brightness_offset = 0x31; | 331 | static int brightness_offset = 0x31; |
332 | static int brightness_mode; | ||
303 | 333 | ||
304 | static int brightness_init(struct ibm_init_struct *iibm); | 334 | static int brightness_init(struct ibm_init_struct *iibm); |
305 | static void brightness_exit(void); | 335 | static void brightness_exit(void); |
@@ -415,14 +445,14 @@ static int fan_write_cmd_watchdog(const char *cmd, int *rc); | |||
415 | */ | 445 | */ |
416 | 446 | ||
417 | static int hotkey_orig_status; | 447 | static int hotkey_orig_status; |
418 | static int hotkey_orig_mask; | 448 | static u32 hotkey_orig_mask; |
419 | 449 | ||
420 | static struct mutex hotkey_mutex; | 450 | static struct mutex hotkey_mutex; |
421 | 451 | ||
422 | static int hotkey_init(struct ibm_init_struct *iibm); | 452 | static int hotkey_init(struct ibm_init_struct *iibm); |
423 | static void hotkey_exit(void); | 453 | static void hotkey_exit(void); |
424 | static int hotkey_get(int *status, int *mask); | 454 | static int hotkey_get(int *status, u32 *mask); |
425 | static int hotkey_set(int status, int mask); | 455 | static int hotkey_set(int status, u32 mask); |
426 | static void hotkey_notify(struct ibm_struct *ibm, u32 event); | 456 | static void hotkey_notify(struct ibm_struct *ibm, u32 event); |
427 | static int hotkey_read(char *p); | 457 | static int hotkey_read(char *p); |
428 | static int hotkey_write(char *buf); | 458 | static int hotkey_write(char *buf); |
diff --git a/drivers/net/arm/ether1.c b/drivers/net/arm/ether1.c index f21148e7b579..80f33b6d5713 100644 --- a/drivers/net/arm/ether1.c +++ b/drivers/net/arm/ether1.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/types.h> | 36 | #include <linux/types.h> |
37 | #include <linux/fcntl.h> | 37 | #include <linux/fcntl.h> |
38 | #include <linux/interrupt.h> | 38 | #include <linux/interrupt.h> |
39 | #include <linux/ptrace.h> | ||
40 | #include <linux/ioport.h> | 39 | #include <linux/ioport.h> |
41 | #include <linux/in.h> | 40 | #include <linux/in.h> |
42 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
@@ -75,7 +74,7 @@ static void ether1_timeout(struct net_device *dev); | |||
75 | 74 | ||
76 | /* ------------------------------------------------------------------------- */ | 75 | /* ------------------------------------------------------------------------- */ |
77 | 76 | ||
78 | static char version[] __initdata = "ether1 ethernet driver (c) 2000 Russell King v1.07\n"; | 77 | static char version[] __devinitdata = "ether1 ethernet driver (c) 2000 Russell King v1.07\n"; |
79 | 78 | ||
80 | #define BUS_16 16 | 79 | #define BUS_16 16 |
81 | #define BUS_8 8 | 80 | #define BUS_8 8 |
diff --git a/drivers/net/arm/ether3.c b/drivers/net/arm/ether3.c index a7cac695a9bd..3805506a3ab8 100644 --- a/drivers/net/arm/ether3.c +++ b/drivers/net/arm/ether3.c | |||
@@ -51,7 +51,6 @@ | |||
51 | #include <linux/types.h> | 51 | #include <linux/types.h> |
52 | #include <linux/fcntl.h> | 52 | #include <linux/fcntl.h> |
53 | #include <linux/interrupt.h> | 53 | #include <linux/interrupt.h> |
54 | #include <linux/ptrace.h> | ||
55 | #include <linux/ioport.h> | 54 | #include <linux/ioport.h> |
56 | #include <linux/in.h> | 55 | #include <linux/in.h> |
57 | #include <linux/slab.h> | 56 | #include <linux/slab.h> |
@@ -69,7 +68,7 @@ | |||
69 | #include <asm/ecard.h> | 68 | #include <asm/ecard.h> |
70 | #include <asm/io.h> | 69 | #include <asm/io.h> |
71 | 70 | ||
72 | static char version[] __initdata = "ether3 ethernet driver (c) 1995-2000 R.M.King v1.17\n"; | 71 | static char version[] __devinitdata = "ether3 ethernet driver (c) 1995-2000 R.M.King v1.17\n"; |
73 | 72 | ||
74 | #include "ether3.h" | 73 | #include "ether3.h" |
75 | 74 | ||
diff --git a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c index 769ba69451f4..0d37d9d1fd78 100644 --- a/drivers/net/arm/etherh.c +++ b/drivers/net/arm/etherh.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <linux/types.h> | 31 | #include <linux/types.h> |
32 | #include <linux/fcntl.h> | 32 | #include <linux/fcntl.h> |
33 | #include <linux/interrupt.h> | 33 | #include <linux/interrupt.h> |
34 | #include <linux/ptrace.h> | ||
35 | #include <linux/ioport.h> | 34 | #include <linux/ioport.h> |
36 | #include <linux/in.h> | 35 | #include <linux/in.h> |
37 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
diff --git a/drivers/net/mlx4/cmd.c b/drivers/net/mlx4/cmd.c index c1f81a993f5d..a9f31753661a 100644 --- a/drivers/net/mlx4/cmd.c +++ b/drivers/net/mlx4/cmd.c | |||
@@ -246,8 +246,6 @@ void mlx4_cmd_event(struct mlx4_dev *dev, u16 token, u8 status, u64 out_param) | |||
246 | context->result = mlx4_status_to_errno(status); | 246 | context->result = mlx4_status_to_errno(status); |
247 | context->out_param = out_param; | 247 | context->out_param = out_param; |
248 | 248 | ||
249 | context->token += priv->cmd.token_mask + 1; | ||
250 | |||
251 | complete(&context->done); | 249 | complete(&context->done); |
252 | } | 250 | } |
253 | 251 | ||
@@ -264,6 +262,7 @@ static int mlx4_cmd_wait(struct mlx4_dev *dev, u64 in_param, u64 *out_param, | |||
264 | spin_lock(&cmd->context_lock); | 262 | spin_lock(&cmd->context_lock); |
265 | BUG_ON(cmd->free_head < 0); | 263 | BUG_ON(cmd->free_head < 0); |
266 | context = &cmd->context[cmd->free_head]; | 264 | context = &cmd->context[cmd->free_head]; |
265 | context->token += cmd->token_mask + 1; | ||
267 | cmd->free_head = context->next; | 266 | cmd->free_head = context->next; |
268 | spin_unlock(&cmd->context_lock); | 267 | spin_unlock(&cmd->context_lock); |
269 | 268 | ||
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c index 3c45142c40b2..b01985498460 100644 --- a/drivers/pcmcia/m8xx_pcmcia.c +++ b/drivers/pcmcia/m8xx_pcmcia.c | |||
@@ -1316,7 +1316,7 @@ static struct of_device_id m8xx_pcmcia_match[] = { | |||
1316 | MODULE_DEVICE_TABLE(of, m8xx_pcmcia_match); | 1316 | MODULE_DEVICE_TABLE(of, m8xx_pcmcia_match); |
1317 | 1317 | ||
1318 | static struct of_platform_driver m8xx_pcmcia_driver = { | 1318 | static struct of_platform_driver m8xx_pcmcia_driver = { |
1319 | .name = (char *)driver_name, | 1319 | .name = driver_name, |
1320 | .match_table = m8xx_pcmcia_match, | 1320 | .match_table = m8xx_pcmcia_match, |
1321 | .probe = m8xx_probe, | 1321 | .probe = m8xx_probe, |
1322 | .remove = m8xx_remove, | 1322 | .remove = m8xx_remove, |
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 9726261c367d..ab5ec1feaf4e 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c | |||
@@ -1526,15 +1526,12 @@ zfcp_gid_pn_buffers_alloc(struct zfcp_gid_pn_data **gid_pn, mempool_t *pool) | |||
1526 | * zfcp_gid_pn_buffers_free - free buffers for GID_PN nameserver request | 1526 | * zfcp_gid_pn_buffers_free - free buffers for GID_PN nameserver request |
1527 | * @gid_pn: pointer to struct zfcp_gid_pn_data which has to be freed | 1527 | * @gid_pn: pointer to struct zfcp_gid_pn_data which has to be freed |
1528 | */ | 1528 | */ |
1529 | static void | 1529 | static void zfcp_gid_pn_buffers_free(struct zfcp_gid_pn_data *gid_pn) |
1530 | zfcp_gid_pn_buffers_free(struct zfcp_gid_pn_data *gid_pn) | ||
1531 | { | 1530 | { |
1532 | if ((gid_pn->ct.pool != 0)) | 1531 | if (gid_pn->ct.pool) |
1533 | mempool_free(gid_pn, gid_pn->ct.pool); | 1532 | mempool_free(gid_pn, gid_pn->ct.pool); |
1534 | else | 1533 | else |
1535 | kfree(gid_pn); | 1534 | kfree(gid_pn); |
1536 | |||
1537 | return; | ||
1538 | } | 1535 | } |
1539 | 1536 | ||
1540 | /** | 1537 | /** |
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 22649639230b..b36dfc40d9fa 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h | |||
@@ -126,6 +126,7 @@ zfcp_address_to_sg(void *address, struct scatterlist *list) | |||
126 | #define ZFCP_MIN_OUTPUT_THRESHOLD 1 /* ignored by QDIO layer */ | 126 | #define ZFCP_MIN_OUTPUT_THRESHOLD 1 /* ignored by QDIO layer */ |
127 | 127 | ||
128 | #define QDIO_SCSI_QFMT 1 /* 1 for FSF */ | 128 | #define QDIO_SCSI_QFMT 1 /* 1 for FSF */ |
129 | #define QBUFF_PER_PAGE (PAGE_SIZE / sizeof(struct qdio_buffer)) | ||
129 | 130 | ||
130 | /********************* FSF SPECIFIC DEFINES *********************************/ | 131 | /********************* FSF SPECIFIC DEFINES *********************************/ |
131 | 132 | ||
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 4e7cb6dc4d34..d8cd75ce2d9a 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c | |||
@@ -1626,7 +1626,7 @@ zfcp_erp_schedule_work(struct zfcp_unit *unit) | |||
1626 | { | 1626 | { |
1627 | struct zfcp_erp_add_work *p; | 1627 | struct zfcp_erp_add_work *p; |
1628 | 1628 | ||
1629 | p = kmalloc(sizeof(*p), GFP_KERNEL); | 1629 | p = kzalloc(sizeof(*p), GFP_KERNEL); |
1630 | if (!p) { | 1630 | if (!p) { |
1631 | ZFCP_LOG_NORMAL("error: Out of resources. Could not register " | 1631 | ZFCP_LOG_NORMAL("error: Out of resources. Could not register " |
1632 | "the FCP-LUN 0x%Lx connected to " | 1632 | "the FCP-LUN 0x%Lx connected to " |
@@ -1639,7 +1639,6 @@ zfcp_erp_schedule_work(struct zfcp_unit *unit) | |||
1639 | } | 1639 | } |
1640 | 1640 | ||
1641 | zfcp_unit_get(unit); | 1641 | zfcp_unit_get(unit); |
1642 | memset(p, 0, sizeof(*p)); | ||
1643 | atomic_set_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status); | 1642 | atomic_set_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status); |
1644 | INIT_WORK(&p->work, zfcp_erp_scsi_scan); | 1643 | INIT_WORK(&p->work, zfcp_erp_scsi_scan); |
1645 | p->unit = unit; | 1644 | p->unit = unit; |
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 0eb31e162b15..b240800b78d7 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
@@ -1930,7 +1930,7 @@ static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req) | |||
1930 | skip_fsfstatus: | 1930 | skip_fsfstatus: |
1931 | send_els->status = retval; | 1931 | send_els->status = retval; |
1932 | 1932 | ||
1933 | if (send_els->handler != 0) | 1933 | if (send_els->handler) |
1934 | send_els->handler(send_els->handler_data); | 1934 | send_els->handler(send_els->handler_data); |
1935 | 1935 | ||
1936 | return retval; | 1936 | return retval; |
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index bdf5782b8a7a..c408badd2ae9 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c | |||
@@ -47,103 +47,56 @@ static int zfcp_qdio_handler_error_check(struct zfcp_adapter *, | |||
47 | #define ZFCP_LOG_AREA ZFCP_LOG_AREA_QDIO | 47 | #define ZFCP_LOG_AREA ZFCP_LOG_AREA_QDIO |
48 | 48 | ||
49 | /* | 49 | /* |
50 | * Allocates BUFFER memory to each of the pointers of the qdio_buffer_t | 50 | * Frees BUFFER memory for each of the pointers of the struct qdio_buffer array |
51 | * array in the adapter struct. | 51 | * in the adapter struct sbuf is the pointer array. |
52 | * Cur_buf is the pointer array and count can be any number of required | ||
53 | * buffers, the page-fitting arithmetic is done entirely within this funciton. | ||
54 | * | 52 | * |
55 | * returns: number of buffers allocated | ||
56 | * locks: must only be called with zfcp_data.config_sema taken | 53 | * locks: must only be called with zfcp_data.config_sema taken |
57 | */ | 54 | */ |
58 | static int | 55 | static void |
59 | zfcp_qdio_buffers_enqueue(struct qdio_buffer **cur_buf, int count) | 56 | zfcp_qdio_buffers_dequeue(struct qdio_buffer **sbuf) |
60 | { | 57 | { |
61 | int buf_pos; | 58 | int pos; |
62 | int qdio_buffers_per_page; | ||
63 | int page_pos = 0; | ||
64 | struct qdio_buffer *first_in_page = NULL; | ||
65 | |||
66 | qdio_buffers_per_page = PAGE_SIZE / sizeof (struct qdio_buffer); | ||
67 | ZFCP_LOG_TRACE("buffers_per_page=%d\n", qdio_buffers_per_page); | ||
68 | |||
69 | for (buf_pos = 0; buf_pos < count; buf_pos++) { | ||
70 | if (page_pos == 0) { | ||
71 | cur_buf[buf_pos] = (struct qdio_buffer *) | ||
72 | get_zeroed_page(GFP_KERNEL); | ||
73 | if (cur_buf[buf_pos] == NULL) { | ||
74 | ZFCP_LOG_INFO("error: allocation of " | ||
75 | "QDIO buffer failed \n"); | ||
76 | goto out; | ||
77 | } | ||
78 | first_in_page = cur_buf[buf_pos]; | ||
79 | } else { | ||
80 | cur_buf[buf_pos] = first_in_page + page_pos; | ||
81 | 59 | ||
82 | } | 60 | for (pos = 0; pos < QDIO_MAX_BUFFERS_PER_Q; pos += QBUFF_PER_PAGE) |
83 | /* was initialised to zero */ | 61 | free_page((unsigned long) sbuf[pos]); |
84 | page_pos++; | ||
85 | page_pos %= qdio_buffers_per_page; | ||
86 | } | ||
87 | out: | ||
88 | return buf_pos; | ||
89 | } | 62 | } |
90 | 63 | ||
91 | /* | 64 | /* |
92 | * Frees BUFFER memory for each of the pointers of the struct qdio_buffer array | 65 | * Allocates BUFFER memory to each of the pointers of the qdio_buffer_t |
93 | * in the adapter struct cur_buf is the pointer array and count can be any | 66 | * array in the adapter struct. |
94 | * number of buffers in the array that should be freed starting from buffer 0 | 67 | * Cur_buf is the pointer array |
95 | * | 68 | * |
69 | * returns: zero on success else -ENOMEM | ||
96 | * locks: must only be called with zfcp_data.config_sema taken | 70 | * locks: must only be called with zfcp_data.config_sema taken |
97 | */ | 71 | */ |
98 | static void | 72 | static int |
99 | zfcp_qdio_buffers_dequeue(struct qdio_buffer **cur_buf, int count) | 73 | zfcp_qdio_buffers_enqueue(struct qdio_buffer **sbuf) |
100 | { | 74 | { |
101 | int buf_pos; | 75 | int pos; |
102 | int qdio_buffers_per_page; | ||
103 | |||
104 | qdio_buffers_per_page = PAGE_SIZE / sizeof (struct qdio_buffer); | ||
105 | ZFCP_LOG_TRACE("buffers_per_page=%d\n", qdio_buffers_per_page); | ||
106 | 76 | ||
107 | for (buf_pos = 0; buf_pos < count; buf_pos += qdio_buffers_per_page) | 77 | for (pos = 0; pos < QDIO_MAX_BUFFERS_PER_Q; pos += QBUFF_PER_PAGE) { |
108 | free_page((unsigned long) cur_buf[buf_pos]); | 78 | sbuf[pos] = (struct qdio_buffer *) get_zeroed_page(GFP_KERNEL); |
109 | return; | 79 | if (!sbuf[pos]) { |
80 | zfcp_qdio_buffers_dequeue(sbuf); | ||
81 | return -ENOMEM; | ||
82 | } | ||
83 | } | ||
84 | for (pos = 0; pos < QDIO_MAX_BUFFERS_PER_Q; pos++) | ||
85 | if (pos % QBUFF_PER_PAGE) | ||
86 | sbuf[pos] = sbuf[pos - 1] + 1; | ||
87 | return 0; | ||
110 | } | 88 | } |
111 | 89 | ||
112 | /* locks: must only be called with zfcp_data.config_sema taken */ | 90 | /* locks: must only be called with zfcp_data.config_sema taken */ |
113 | int | 91 | int |
114 | zfcp_qdio_allocate_queues(struct zfcp_adapter *adapter) | 92 | zfcp_qdio_allocate_queues(struct zfcp_adapter *adapter) |
115 | { | 93 | { |
116 | int buffer_count; | 94 | int ret; |
117 | int retval = 0; | ||
118 | 95 | ||
119 | buffer_count = | 96 | ret = zfcp_qdio_buffers_enqueue(adapter->request_queue.buffer); |
120 | zfcp_qdio_buffers_enqueue(&(adapter->request_queue.buffer[0]), | 97 | if (ret) |
121 | QDIO_MAX_BUFFERS_PER_Q); | 98 | return ret; |
122 | if (buffer_count < QDIO_MAX_BUFFERS_PER_Q) { | 99 | return zfcp_qdio_buffers_enqueue(adapter->response_queue.buffer); |
123 | ZFCP_LOG_DEBUG("only %d QDIO buffers allocated for request " | ||
124 | "queue\n", buffer_count); | ||
125 | zfcp_qdio_buffers_dequeue(&(adapter->request_queue.buffer[0]), | ||
126 | buffer_count); | ||
127 | retval = -ENOMEM; | ||
128 | goto out; | ||
129 | } | ||
130 | |||
131 | buffer_count = | ||
132 | zfcp_qdio_buffers_enqueue(&(adapter->response_queue.buffer[0]), | ||
133 | QDIO_MAX_BUFFERS_PER_Q); | ||
134 | if (buffer_count < QDIO_MAX_BUFFERS_PER_Q) { | ||
135 | ZFCP_LOG_DEBUG("only %d QDIO buffers allocated for response " | ||
136 | "queue", buffer_count); | ||
137 | zfcp_qdio_buffers_dequeue(&(adapter->response_queue.buffer[0]), | ||
138 | buffer_count); | ||
139 | ZFCP_LOG_TRACE("freeing request_queue buffers\n"); | ||
140 | zfcp_qdio_buffers_dequeue(&(adapter->request_queue.buffer[0]), | ||
141 | QDIO_MAX_BUFFERS_PER_Q); | ||
142 | retval = -ENOMEM; | ||
143 | goto out; | ||
144 | } | ||
145 | out: | ||
146 | return retval; | ||
147 | } | 100 | } |
148 | 101 | ||
149 | /* locks: must only be called with zfcp_data.config_sema taken */ | 102 | /* locks: must only be called with zfcp_data.config_sema taken */ |
@@ -151,12 +104,10 @@ void | |||
151 | zfcp_qdio_free_queues(struct zfcp_adapter *adapter) | 104 | zfcp_qdio_free_queues(struct zfcp_adapter *adapter) |
152 | { | 105 | { |
153 | ZFCP_LOG_TRACE("freeing request_queue buffers\n"); | 106 | ZFCP_LOG_TRACE("freeing request_queue buffers\n"); |
154 | zfcp_qdio_buffers_dequeue(&(adapter->request_queue.buffer[0]), | 107 | zfcp_qdio_buffers_dequeue(adapter->request_queue.buffer); |
155 | QDIO_MAX_BUFFERS_PER_Q); | ||
156 | 108 | ||
157 | ZFCP_LOG_TRACE("freeing response_queue buffers\n"); | 109 | ZFCP_LOG_TRACE("freeing response_queue buffers\n"); |
158 | zfcp_qdio_buffers_dequeue(&(adapter->response_queue.buffer[0]), | 110 | zfcp_qdio_buffers_dequeue(adapter->response_queue.buffer); |
159 | QDIO_MAX_BUFFERS_PER_Q); | ||
160 | } | 111 | } |
161 | 112 | ||
162 | int | 113 | int |
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index 6b49f6a2524d..efd9d8d3a890 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c | |||
@@ -4,7 +4,7 @@ | |||
4 | Written By: Adam Radford <linuxraid@amcc.com> | 4 | Written By: Adam Radford <linuxraid@amcc.com> |
5 | Modifications By: Tom Couch <linuxraid@amcc.com> | 5 | Modifications By: Tom Couch <linuxraid@amcc.com> |
6 | 6 | ||
7 | Copyright (C) 2004-2006 Applied Micro Circuits Corporation. | 7 | Copyright (C) 2004-2007 Applied Micro Circuits Corporation. |
8 | 8 | ||
9 | This program is free software; you can redistribute it and/or modify | 9 | This program is free software; you can redistribute it and/or modify |
10 | it under the terms of the GNU General Public License as published by | 10 | it under the terms of the GNU General Public License as published by |
@@ -69,6 +69,8 @@ | |||
69 | 2.26.02.008 - Free irq handler in __twa_shutdown(). | 69 | 2.26.02.008 - Free irq handler in __twa_shutdown(). |
70 | Serialize reset code. | 70 | Serialize reset code. |
71 | Add support for 9650SE controllers. | 71 | Add support for 9650SE controllers. |
72 | 2.26.02.009 - Fix dma mask setting to fallback to 32-bit if 64-bit fails. | ||
73 | 2.26.02.010 - Add support for 9690SA controllers. | ||
72 | */ | 74 | */ |
73 | 75 | ||
74 | #include <linux/module.h> | 76 | #include <linux/module.h> |
@@ -92,7 +94,7 @@ | |||
92 | #include "3w-9xxx.h" | 94 | #include "3w-9xxx.h" |
93 | 95 | ||
94 | /* Globals */ | 96 | /* Globals */ |
95 | #define TW_DRIVER_VERSION "2.26.02.008" | 97 | #define TW_DRIVER_VERSION "2.26.02.010" |
96 | static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT]; | 98 | static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT]; |
97 | static unsigned int twa_device_extension_count; | 99 | static unsigned int twa_device_extension_count; |
98 | static int twa_major = -1; | 100 | static int twa_major = -1; |
@@ -124,11 +126,11 @@ static int twa_initconnection(TW_Device_Extension *tw_dev, int message_credits, | |||
124 | unsigned short *fw_on_ctlr_branch, | 126 | unsigned short *fw_on_ctlr_branch, |
125 | unsigned short *fw_on_ctlr_build, | 127 | unsigned short *fw_on_ctlr_build, |
126 | u32 *init_connect_result); | 128 | u32 *init_connect_result); |
127 | static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length); | 129 | static void twa_load_sgl(TW_Device_Extension *tw_dev, TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length); |
128 | static int twa_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds); | 130 | static int twa_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds); |
129 | static int twa_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds); | 131 | static int twa_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds); |
130 | static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id, char internal); | 132 | static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id, char internal); |
131 | static int twa_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset); | 133 | static int twa_reset_device_extension(TW_Device_Extension *tw_dev); |
132 | static int twa_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset); | 134 | static int twa_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset); |
133 | static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Entry *sglistarg); | 135 | static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Entry *sglistarg); |
134 | static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int request_id); | 136 | static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int request_id); |
@@ -683,7 +685,7 @@ static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int | |||
683 | full_command_packet = &tw_ioctl->firmware_command; | 685 | full_command_packet = &tw_ioctl->firmware_command; |
684 | 686 | ||
685 | /* Load request id and sglist for both command types */ | 687 | /* Load request id and sglist for both command types */ |
686 | twa_load_sgl(full_command_packet, request_id, dma_handle, data_buffer_length_adjusted); | 688 | twa_load_sgl(tw_dev, full_command_packet, request_id, dma_handle, data_buffer_length_adjusted); |
687 | 689 | ||
688 | memcpy(tw_dev->command_packet_virt[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command_Full)); | 690 | memcpy(tw_dev->command_packet_virt[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command_Full)); |
689 | 691 | ||
@@ -700,10 +702,10 @@ static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int | |||
700 | if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) { | 702 | if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) { |
701 | /* Now we need to reset the board */ | 703 | /* Now we need to reset the board */ |
702 | printk(KERN_WARNING "3w-9xxx: scsi%d: WARNING: (0x%02X:0x%04X): Character ioctl (0x%x) timed out, resetting card.\n", | 704 | printk(KERN_WARNING "3w-9xxx: scsi%d: WARNING: (0x%02X:0x%04X): Character ioctl (0x%x) timed out, resetting card.\n", |
703 | tw_dev->host->host_no, TW_DRIVER, 0xc, | 705 | tw_dev->host->host_no, TW_DRIVER, 0x37, |
704 | cmd); | 706 | cmd); |
705 | retval = TW_IOCTL_ERROR_OS_EIO; | 707 | retval = TW_IOCTL_ERROR_OS_EIO; |
706 | twa_reset_device_extension(tw_dev, 1); | 708 | twa_reset_device_extension(tw_dev); |
707 | goto out3; | 709 | goto out3; |
708 | } | 710 | } |
709 | 711 | ||
@@ -890,7 +892,9 @@ static int twa_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value) | |||
890 | } | 892 | } |
891 | 893 | ||
892 | if (status_reg_value & TW_STATUS_QUEUE_ERROR) { | 894 | if (status_reg_value & TW_STATUS_QUEUE_ERROR) { |
893 | if ((tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9650SE) || (!test_bit(TW_IN_RESET, &tw_dev->flags))) | 895 | if (((tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9650SE) && |
896 | (tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9690SA)) || | ||
897 | (!test_bit(TW_IN_RESET, &tw_dev->flags))) | ||
894 | TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Controller Queue Error: clearing"); | 898 | TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Controller Queue Error: clearing"); |
895 | writel(TW_CONTROL_CLEAR_QUEUE_ERROR, TW_CONTROL_REG_ADDR(tw_dev)); | 899 | writel(TW_CONTROL_CLEAR_QUEUE_ERROR, TW_CONTROL_REG_ADDR(tw_dev)); |
896 | } | 900 | } |
@@ -935,8 +939,7 @@ static int twa_empty_response_queue_large(TW_Device_Extension *tw_dev) | |||
935 | unsigned long before; | 939 | unsigned long before; |
936 | int retval = 1; | 940 | int retval = 1; |
937 | 941 | ||
938 | if ((tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9550SX) || | 942 | if (tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9000) { |
939 | (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE)) { | ||
940 | before = jiffies; | 943 | before = jiffies; |
941 | while ((response_que_value & TW_9550SX_DRAIN_COMPLETED) != TW_9550SX_DRAIN_COMPLETED) { | 944 | while ((response_que_value & TW_9550SX_DRAIN_COMPLETED) != TW_9550SX_DRAIN_COMPLETED) { |
942 | response_que_value = readl(TW_RESPONSE_QUEUE_REG_ADDR_LARGE(tw_dev)); | 945 | response_que_value = readl(TW_RESPONSE_QUEUE_REG_ADDR_LARGE(tw_dev)); |
@@ -1195,7 +1198,6 @@ static irqreturn_t twa_interrupt(int irq, void *dev_instance) | |||
1195 | u32 status_reg_value; | 1198 | u32 status_reg_value; |
1196 | TW_Response_Queue response_que; | 1199 | TW_Response_Queue response_que; |
1197 | TW_Command_Full *full_command_packet; | 1200 | TW_Command_Full *full_command_packet; |
1198 | TW_Command *command_packet; | ||
1199 | TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance; | 1201 | TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance; |
1200 | int handled = 0; | 1202 | int handled = 0; |
1201 | 1203 | ||
@@ -1273,7 +1275,6 @@ static irqreturn_t twa_interrupt(int irq, void *dev_instance) | |||
1273 | request_id = TW_RESID_OUT(response_que.response_id); | 1275 | request_id = TW_RESID_OUT(response_que.response_id); |
1274 | full_command_packet = tw_dev->command_packet_virt[request_id]; | 1276 | full_command_packet = tw_dev->command_packet_virt[request_id]; |
1275 | error = 0; | 1277 | error = 0; |
1276 | command_packet = &full_command_packet->command.oldcommand; | ||
1277 | /* Check for command packet errors */ | 1278 | /* Check for command packet errors */ |
1278 | if (full_command_packet->command.newcommand.status != 0) { | 1279 | if (full_command_packet->command.newcommand.status != 0) { |
1279 | if (tw_dev->srb[request_id] != 0) { | 1280 | if (tw_dev->srb[request_id] != 0) { |
@@ -1352,11 +1353,15 @@ twa_interrupt_bail: | |||
1352 | } /* End twa_interrupt() */ | 1353 | } /* End twa_interrupt() */ |
1353 | 1354 | ||
1354 | /* This function will load the request id and various sgls for ioctls */ | 1355 | /* This function will load the request id and various sgls for ioctls */ |
1355 | static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length) | 1356 | static void twa_load_sgl(TW_Device_Extension *tw_dev, TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length) |
1356 | { | 1357 | { |
1357 | TW_Command *oldcommand; | 1358 | TW_Command *oldcommand; |
1358 | TW_Command_Apache *newcommand; | 1359 | TW_Command_Apache *newcommand; |
1359 | TW_SG_Entry *sgl; | 1360 | TW_SG_Entry *sgl; |
1361 | unsigned int pae = 0; | ||
1362 | |||
1363 | if ((sizeof(long) < 8) && (sizeof(dma_addr_t) > 4)) | ||
1364 | pae = 1; | ||
1360 | 1365 | ||
1361 | if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) { | 1366 | if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) { |
1362 | newcommand = &full_command_packet->command.newcommand; | 1367 | newcommand = &full_command_packet->command.newcommand; |
@@ -1372,12 +1377,14 @@ static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, d | |||
1372 | 1377 | ||
1373 | if (TW_SGL_OUT(oldcommand->opcode__sgloffset)) { | 1378 | if (TW_SGL_OUT(oldcommand->opcode__sgloffset)) { |
1374 | /* Load the sg list */ | 1379 | /* Load the sg list */ |
1375 | sgl = (TW_SG_Entry *)((u32 *)oldcommand+TW_SGL_OUT(oldcommand->opcode__sgloffset)); | 1380 | if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9690SA) |
1381 | sgl = (TW_SG_Entry *)((u32 *)oldcommand+oldcommand->size - (sizeof(TW_SG_Entry)/4) + pae); | ||
1382 | else | ||
1383 | sgl = (TW_SG_Entry *)((u32 *)oldcommand+TW_SGL_OUT(oldcommand->opcode__sgloffset)); | ||
1376 | sgl->address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1); | 1384 | sgl->address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1); |
1377 | sgl->length = cpu_to_le32(length); | 1385 | sgl->length = cpu_to_le32(length); |
1378 | 1386 | ||
1379 | if ((sizeof(long) < 8) && (sizeof(dma_addr_t) > 4)) | 1387 | oldcommand->size += pae; |
1380 | oldcommand->size += 1; | ||
1381 | } | 1388 | } |
1382 | } | 1389 | } |
1383 | } /* End twa_load_sgl() */ | 1390 | } /* End twa_load_sgl() */ |
@@ -1506,7 +1513,8 @@ static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id, | |||
1506 | command_que_value = tw_dev->command_packet_phys[request_id]; | 1513 | command_que_value = tw_dev->command_packet_phys[request_id]; |
1507 | 1514 | ||
1508 | /* For 9650SE write low 4 bytes first */ | 1515 | /* For 9650SE write low 4 bytes first */ |
1509 | if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) { | 1516 | if ((tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) || |
1517 | (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9690SA)) { | ||
1510 | command_que_value += TW_COMMAND_OFFSET; | 1518 | command_que_value += TW_COMMAND_OFFSET; |
1511 | writel((u32)command_que_value, TW_COMMAND_QUEUE_REG_ADDR_LARGE(tw_dev)); | 1519 | writel((u32)command_que_value, TW_COMMAND_QUEUE_REG_ADDR_LARGE(tw_dev)); |
1512 | } | 1520 | } |
@@ -1537,7 +1545,8 @@ static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id, | |||
1537 | TW_UNMASK_COMMAND_INTERRUPT(tw_dev); | 1545 | TW_UNMASK_COMMAND_INTERRUPT(tw_dev); |
1538 | goto out; | 1546 | goto out; |
1539 | } else { | 1547 | } else { |
1540 | if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) { | 1548 | if ((tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) || |
1549 | (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9690SA)) { | ||
1541 | /* Now write upper 4 bytes */ | 1550 | /* Now write upper 4 bytes */ |
1542 | writel((u32)((u64)command_que_value >> 32), TW_COMMAND_QUEUE_REG_ADDR_LARGE(tw_dev) + 0x4); | 1551 | writel((u32)((u64)command_que_value >> 32), TW_COMMAND_QUEUE_REG_ADDR_LARGE(tw_dev) + 0x4); |
1543 | } else { | 1552 | } else { |
@@ -1561,7 +1570,7 @@ out: | |||
1561 | } /* End twa_post_command_packet() */ | 1570 | } /* End twa_post_command_packet() */ |
1562 | 1571 | ||
1563 | /* This function will reset a device extension */ | 1572 | /* This function will reset a device extension */ |
1564 | static int twa_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset) | 1573 | static int twa_reset_device_extension(TW_Device_Extension *tw_dev) |
1565 | { | 1574 | { |
1566 | int i = 0; | 1575 | int i = 0; |
1567 | int retval = 1; | 1576 | int retval = 1; |
@@ -1719,7 +1728,7 @@ static int twa_scsi_eh_reset(struct scsi_cmnd *SCpnt) | |||
1719 | mutex_lock(&tw_dev->ioctl_lock); | 1728 | mutex_lock(&tw_dev->ioctl_lock); |
1720 | 1729 | ||
1721 | /* Now reset the card and some of the device extension data */ | 1730 | /* Now reset the card and some of the device extension data */ |
1722 | if (twa_reset_device_extension(tw_dev, 0)) { | 1731 | if (twa_reset_device_extension(tw_dev)) { |
1723 | TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2b, "Controller reset failed during scsi host reset"); | 1732 | TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2b, "Controller reset failed during scsi host reset"); |
1724 | goto out; | 1733 | goto out; |
1725 | } | 1734 | } |
@@ -2001,11 +2010,14 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id | |||
2001 | 2010 | ||
2002 | pci_set_master(pdev); | 2011 | pci_set_master(pdev); |
2003 | 2012 | ||
2004 | retval = pci_set_dma_mask(pdev, sizeof(dma_addr_t) > 4 ? DMA_64BIT_MASK : DMA_32BIT_MASK); | 2013 | if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) |
2005 | if (retval) { | 2014 | || pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) |
2006 | TW_PRINTK(host, TW_DRIVER, 0x23, "Failed to set dma mask"); | 2015 | if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) |
2007 | goto out_disable_device; | 2016 | || pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) { |
2008 | } | 2017 | TW_PRINTK(host, TW_DRIVER, 0x23, "Failed to set dma mask"); |
2018 | retval = -ENODEV; | ||
2019 | goto out_disable_device; | ||
2020 | } | ||
2009 | 2021 | ||
2010 | host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension)); | 2022 | host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension)); |
2011 | if (!host) { | 2023 | if (!host) { |
@@ -2053,7 +2065,8 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id | |||
2053 | goto out_iounmap; | 2065 | goto out_iounmap; |
2054 | 2066 | ||
2055 | /* Set host specific parameters */ | 2067 | /* Set host specific parameters */ |
2056 | if (pdev->device == PCI_DEVICE_ID_3WARE_9650SE) | 2068 | if ((pdev->device == PCI_DEVICE_ID_3WARE_9650SE) || |
2069 | (pdev->device == PCI_DEVICE_ID_3WARE_9690SA)) | ||
2057 | host->max_id = TW_MAX_UNITS_9650SE; | 2070 | host->max_id = TW_MAX_UNITS_9650SE; |
2058 | else | 2071 | else |
2059 | host->max_id = TW_MAX_UNITS; | 2072 | host->max_id = TW_MAX_UNITS; |
@@ -2160,6 +2173,8 @@ static struct pci_device_id twa_pci_tbl[] __devinitdata = { | |||
2160 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 2173 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
2161 | { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9650SE, | 2174 | { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9650SE, |
2162 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 2175 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
2176 | { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9690SA, | ||
2177 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
2163 | { } | 2178 | { } |
2164 | }; | 2179 | }; |
2165 | MODULE_DEVICE_TABLE(pci, twa_pci_tbl); | 2180 | MODULE_DEVICE_TABLE(pci, twa_pci_tbl); |
diff --git a/drivers/scsi/3w-9xxx.h b/drivers/scsi/3w-9xxx.h index 7901517d4513..d14a9479e389 100644 --- a/drivers/scsi/3w-9xxx.h +++ b/drivers/scsi/3w-9xxx.h | |||
@@ -4,7 +4,7 @@ | |||
4 | Written By: Adam Radford <linuxraid@amcc.com> | 4 | Written By: Adam Radford <linuxraid@amcc.com> |
5 | Modifications By: Tom Couch <linuxraid@amcc.com> | 5 | Modifications By: Tom Couch <linuxraid@amcc.com> |
6 | 6 | ||
7 | Copyright (C) 2004-2006 Applied Micro Circuits Corporation. | 7 | Copyright (C) 2004-2007 Applied Micro Circuits Corporation. |
8 | 8 | ||
9 | This program is free software; you can redistribute it and/or modify | 9 | This program is free software; you can redistribute it and/or modify |
10 | it under the terms of the GNU General Public License as published by | 10 | it under the terms of the GNU General Public License as published by |
@@ -419,6 +419,9 @@ static twa_message_type twa_error_table[] = { | |||
419 | #ifndef PCI_DEVICE_ID_3WARE_9650SE | 419 | #ifndef PCI_DEVICE_ID_3WARE_9650SE |
420 | #define PCI_DEVICE_ID_3WARE_9650SE 0x1004 | 420 | #define PCI_DEVICE_ID_3WARE_9650SE 0x1004 |
421 | #endif | 421 | #endif |
422 | #ifndef PCI_DEVICE_ID_3WARE_9690SA | ||
423 | #define PCI_DEVICE_ID_3WARE_9690SA 0x1005 | ||
424 | #endif | ||
422 | 425 | ||
423 | /* Bitmask macros to eliminate bitfields */ | 426 | /* Bitmask macros to eliminate bitfields */ |
424 | 427 | ||
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index a947257b8964..d2b3898b750a 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig | |||
@@ -282,7 +282,7 @@ config SCSI_ISCSI_ATTRS | |||
282 | 282 | ||
283 | config SCSI_SAS_ATTRS | 283 | config SCSI_SAS_ATTRS |
284 | tristate "SAS Transport Attributes" | 284 | tristate "SAS Transport Attributes" |
285 | depends on SCSI | 285 | depends on SCSI && BLK_DEV_BSG |
286 | help | 286 | help |
287 | If you wish to export transport-specific information about | 287 | If you wish to export transport-specific information about |
288 | each attached SAS device to sysfs, say Y. | 288 | each attached SAS device to sysfs, say Y. |
@@ -291,8 +291,12 @@ source "drivers/scsi/libsas/Kconfig" | |||
291 | 291 | ||
292 | endmenu | 292 | endmenu |
293 | 293 | ||
294 | menu "SCSI low-level drivers" | 294 | menuconfig SCSI_LOWLEVEL |
295 | bool "SCSI low-level drivers" | ||
295 | depends on SCSI!=n | 296 | depends on SCSI!=n |
297 | default y | ||
298 | |||
299 | if SCSI_LOWLEVEL | ||
296 | 300 | ||
297 | config ISCSI_TCP | 301 | config ISCSI_TCP |
298 | tristate "iSCSI Initiator over TCP/IP" | 302 | tristate "iSCSI Initiator over TCP/IP" |
@@ -1800,7 +1804,7 @@ config SCSI_SRP | |||
1800 | To compile this driver as a module, choose M here: the | 1804 | To compile this driver as a module, choose M here: the |
1801 | module will be called libsrp. | 1805 | module will be called libsrp. |
1802 | 1806 | ||
1803 | endmenu | 1807 | endif # SCSI_LOWLEVEL |
1804 | 1808 | ||
1805 | source "drivers/scsi/pcmcia/Kconfig" | 1809 | source "drivers/scsi/pcmcia/Kconfig" |
1806 | 1810 | ||
diff --git a/drivers/scsi/a4000t.c b/drivers/scsi/a4000t.c index 6a5784683ed3..0c758d1452ba 100644 --- a/drivers/scsi/a4000t.c +++ b/drivers/scsi/a4000t.c | |||
@@ -79,6 +79,7 @@ static int __devinit a4000t_probe(struct device *dev) | |||
79 | goto out_put_host; | 79 | goto out_put_host; |
80 | } | 80 | } |
81 | 81 | ||
82 | dev_set_drvdata(dev, host); | ||
82 | scsi_scan_host(host); | 83 | scsi_scan_host(host); |
83 | 84 | ||
84 | return 0; | 85 | return 0; |
@@ -95,7 +96,7 @@ static int __devinit a4000t_probe(struct device *dev) | |||
95 | 96 | ||
96 | static __devexit int a4000t_device_remove(struct device *dev) | 97 | static __devexit int a4000t_device_remove(struct device *dev) |
97 | { | 98 | { |
98 | struct Scsi_Host *host = dev_to_shost(dev); | 99 | struct Scsi_Host *host = dev_get_drvdata(dev); |
99 | struct NCR_700_Host_Parameters *hostdata = shost_priv(host); | 100 | struct NCR_700_Host_Parameters *hostdata = shost_priv(host); |
100 | 101 | ||
101 | scsi_remove_host(host); | 102 | scsi_remove_host(host); |
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 0b6fd0b654d2..a26baab09dbf 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c | |||
@@ -751,6 +751,101 @@ static void setinqstr(struct aac_dev *dev, void *data, int tindex) | |||
751 | inqstrcpy ("V1.0", str->prl); | 751 | inqstrcpy ("V1.0", str->prl); |
752 | } | 752 | } |
753 | 753 | ||
754 | static void get_container_serial_callback(void *context, struct fib * fibptr) | ||
755 | { | ||
756 | struct aac_get_serial_resp * get_serial_reply; | ||
757 | struct scsi_cmnd * scsicmd; | ||
758 | |||
759 | BUG_ON(fibptr == NULL); | ||
760 | |||
761 | scsicmd = (struct scsi_cmnd *) context; | ||
762 | if (!aac_valid_context(scsicmd, fibptr)) | ||
763 | return; | ||
764 | |||
765 | get_serial_reply = (struct aac_get_serial_resp *) fib_data(fibptr); | ||
766 | /* Failure is irrelevant, using default value instead */ | ||
767 | if (le32_to_cpu(get_serial_reply->status) == CT_OK) { | ||
768 | char sp[13]; | ||
769 | /* EVPD bit set */ | ||
770 | sp[0] = INQD_PDT_DA; | ||
771 | sp[1] = scsicmd->cmnd[2]; | ||
772 | sp[2] = 0; | ||
773 | sp[3] = snprintf(sp+4, sizeof(sp)-4, "%08X", | ||
774 | le32_to_cpu(get_serial_reply->uid)); | ||
775 | aac_internal_transfer(scsicmd, sp, 0, sizeof(sp)); | ||
776 | } | ||
777 | |||
778 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | ||
779 | |||
780 | aac_fib_complete(fibptr); | ||
781 | aac_fib_free(fibptr); | ||
782 | scsicmd->scsi_done(scsicmd); | ||
783 | } | ||
784 | |||
785 | /** | ||
786 | * aac_get_container_serial - get container serial, none blocking. | ||
787 | */ | ||
788 | static int aac_get_container_serial(struct scsi_cmnd * scsicmd) | ||
789 | { | ||
790 | int status; | ||
791 | struct aac_get_serial *dinfo; | ||
792 | struct fib * cmd_fibcontext; | ||
793 | struct aac_dev * dev; | ||
794 | |||
795 | dev = (struct aac_dev *)scsicmd->device->host->hostdata; | ||
796 | |||
797 | if (!(cmd_fibcontext = aac_fib_alloc(dev))) | ||
798 | return -ENOMEM; | ||
799 | |||
800 | aac_fib_init(cmd_fibcontext); | ||
801 | dinfo = (struct aac_get_serial *) fib_data(cmd_fibcontext); | ||
802 | |||
803 | dinfo->command = cpu_to_le32(VM_ContainerConfig); | ||
804 | dinfo->type = cpu_to_le32(CT_CID_TO_32BITS_UID); | ||
805 | dinfo->cid = cpu_to_le32(scmd_id(scsicmd)); | ||
806 | |||
807 | status = aac_fib_send(ContainerCommand, | ||
808 | cmd_fibcontext, | ||
809 | sizeof (struct aac_get_serial), | ||
810 | FsaNormal, | ||
811 | 0, 1, | ||
812 | (fib_callback) get_container_serial_callback, | ||
813 | (void *) scsicmd); | ||
814 | |||
815 | /* | ||
816 | * Check that the command queued to the controller | ||
817 | */ | ||
818 | if (status == -EINPROGRESS) { | ||
819 | scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; | ||
820 | return 0; | ||
821 | } | ||
822 | |||
823 | printk(KERN_WARNING "aac_get_container_serial: aac_fib_send failed with status: %d.\n", status); | ||
824 | aac_fib_complete(cmd_fibcontext); | ||
825 | aac_fib_free(cmd_fibcontext); | ||
826 | return -1; | ||
827 | } | ||
828 | |||
829 | /* Function: setinqserial | ||
830 | * | ||
831 | * Arguments: [1] pointer to void [1] int | ||
832 | * | ||
833 | * Purpose: Sets SCSI Unit Serial number. | ||
834 | * This is a fake. We should read a proper | ||
835 | * serial number from the container. <SuSE>But | ||
836 | * without docs it's quite hard to do it :-) | ||
837 | * So this will have to do in the meantime.</SuSE> | ||
838 | */ | ||
839 | |||
840 | static int setinqserial(struct aac_dev *dev, void *data, int cid) | ||
841 | { | ||
842 | /* | ||
843 | * This breaks array migration. | ||
844 | */ | ||
845 | return snprintf((char *)(data), sizeof(struct scsi_inq) - 4, "%08X%02X", | ||
846 | le32_to_cpu(dev->adapter_info.serial[0]), cid); | ||
847 | } | ||
848 | |||
754 | static void set_sense(u8 *sense_buf, u8 sense_key, u8 sense_code, | 849 | static void set_sense(u8 *sense_buf, u8 sense_key, u8 sense_code, |
755 | u8 a_sense_code, u8 incorrect_length, | 850 | u8 a_sense_code, u8 incorrect_length, |
756 | u8 bit_pointer, u16 field_pointer, | 851 | u8 bit_pointer, u16 field_pointer, |
@@ -1798,6 +1893,49 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
1798 | dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", cid)); | 1893 | dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", cid)); |
1799 | memset(&inq_data, 0, sizeof (struct inquiry_data)); | 1894 | memset(&inq_data, 0, sizeof (struct inquiry_data)); |
1800 | 1895 | ||
1896 | if (scsicmd->cmnd[1] & 0x1 ) { | ||
1897 | char *arr = (char *)&inq_data; | ||
1898 | |||
1899 | /* EVPD bit set */ | ||
1900 | arr[0] = (scmd_id(scsicmd) == host->this_id) ? | ||
1901 | INQD_PDT_PROC : INQD_PDT_DA; | ||
1902 | if (scsicmd->cmnd[2] == 0) { | ||
1903 | /* supported vital product data pages */ | ||
1904 | arr[3] = 2; | ||
1905 | arr[4] = 0x0; | ||
1906 | arr[5] = 0x80; | ||
1907 | arr[1] = scsicmd->cmnd[2]; | ||
1908 | aac_internal_transfer(scsicmd, &inq_data, 0, | ||
1909 | sizeof(inq_data)); | ||
1910 | scsicmd->result = DID_OK << 16 | | ||
1911 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | ||
1912 | } else if (scsicmd->cmnd[2] == 0x80) { | ||
1913 | /* unit serial number page */ | ||
1914 | arr[3] = setinqserial(dev, &arr[4], | ||
1915 | scmd_id(scsicmd)); | ||
1916 | arr[1] = scsicmd->cmnd[2]; | ||
1917 | aac_internal_transfer(scsicmd, &inq_data, 0, | ||
1918 | sizeof(inq_data)); | ||
1919 | return aac_get_container_serial(scsicmd); | ||
1920 | } else { | ||
1921 | /* vpd page not implemented */ | ||
1922 | scsicmd->result = DID_OK << 16 | | ||
1923 | COMMAND_COMPLETE << 8 | | ||
1924 | SAM_STAT_CHECK_CONDITION; | ||
1925 | set_sense((u8 *) &dev->fsa_dev[cid].sense_data, | ||
1926 | ILLEGAL_REQUEST, | ||
1927 | SENCODE_INVALID_CDB_FIELD, | ||
1928 | ASENCODE_NO_SENSE, 0, 7, 2, 0); | ||
1929 | memcpy(scsicmd->sense_buffer, | ||
1930 | &dev->fsa_dev[cid].sense_data, | ||
1931 | (sizeof(dev->fsa_dev[cid].sense_data) > | ||
1932 | sizeof(scsicmd->sense_buffer)) | ||
1933 | ? sizeof(scsicmd->sense_buffer) | ||
1934 | : sizeof(dev->fsa_dev[cid].sense_data)); | ||
1935 | } | ||
1936 | scsicmd->scsi_done(scsicmd); | ||
1937 | return 0; | ||
1938 | } | ||
1801 | inq_data.inqd_ver = 2; /* claim compliance to SCSI-2 */ | 1939 | inq_data.inqd_ver = 2; /* claim compliance to SCSI-2 */ |
1802 | inq_data.inqd_rdf = 2; /* A response data format value of two indicates that the data shall be in the format specified in SCSI-2 */ | 1940 | inq_data.inqd_rdf = 2; /* A response data format value of two indicates that the data shall be in the format specified in SCSI-2 */ |
1803 | inq_data.inqd_len = 31; | 1941 | inq_data.inqd_len = 31; |
@@ -2070,7 +2208,7 @@ static int query_disk(struct aac_dev *dev, void __user *arg) | |||
2070 | } | 2208 | } |
2071 | else return -EINVAL; | 2209 | else return -EINVAL; |
2072 | 2210 | ||
2073 | qd.valid = fsa_dev_ptr[qd.cnum].valid; | 2211 | qd.valid = fsa_dev_ptr[qd.cnum].valid != 0; |
2074 | qd.locked = fsa_dev_ptr[qd.cnum].locked; | 2212 | qd.locked = fsa_dev_ptr[qd.cnum].locked; |
2075 | qd.deleted = fsa_dev_ptr[qd.cnum].deleted; | 2213 | qd.deleted = fsa_dev_ptr[qd.cnum].deleted; |
2076 | 2214 | ||
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index f1d3b66af879..400d03403cd5 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h | |||
@@ -1567,6 +1567,20 @@ struct aac_get_name_resp { | |||
1567 | u8 data[16]; | 1567 | u8 data[16]; |
1568 | }; | 1568 | }; |
1569 | 1569 | ||
1570 | #define CT_CID_TO_32BITS_UID 165 | ||
1571 | struct aac_get_serial { | ||
1572 | __le32 command; /* VM_ContainerConfig */ | ||
1573 | __le32 type; /* CT_CID_TO_32BITS_UID */ | ||
1574 | __le32 cid; | ||
1575 | }; | ||
1576 | |||
1577 | struct aac_get_serial_resp { | ||
1578 | __le32 dummy0; | ||
1579 | __le32 dummy1; | ||
1580 | __le32 status; /* CT_OK */ | ||
1581 | __le32 uid; | ||
1582 | }; | ||
1583 | |||
1570 | /* | 1584 | /* |
1571 | * The following command is sent to shut down each container. | 1585 | * The following command is sent to shut down each container. |
1572 | */ | 1586 | */ |
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index d510839c0bb2..bb870906b4cf 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c | |||
@@ -80,7 +80,11 @@ static int fib_map_alloc(struct aac_dev *dev) | |||
80 | 80 | ||
81 | void aac_fib_map_free(struct aac_dev *dev) | 81 | void aac_fib_map_free(struct aac_dev *dev) |
82 | { | 82 | { |
83 | pci_free_consistent(dev->pdev, dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB), dev->hw_fib_va, dev->hw_fib_pa); | 83 | pci_free_consistent(dev->pdev, |
84 | dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB), | ||
85 | dev->hw_fib_va, dev->hw_fib_pa); | ||
86 | dev->hw_fib_va = NULL; | ||
87 | dev->hw_fib_pa = 0; | ||
84 | } | 88 | } |
85 | 89 | ||
86 | /** | 90 | /** |
@@ -1087,8 +1091,6 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced) | |||
1087 | * case. | 1091 | * case. |
1088 | */ | 1092 | */ |
1089 | aac_fib_map_free(aac); | 1093 | aac_fib_map_free(aac); |
1090 | aac->hw_fib_va = NULL; | ||
1091 | aac->hw_fib_pa = 0; | ||
1092 | pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, aac->comm_phys); | 1094 | pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, aac->comm_phys); |
1093 | aac->comm_addr = NULL; | 1095 | aac->comm_addr = NULL; |
1094 | aac->comm_phys = 0; | 1096 | aac->comm_phys = 0; |
@@ -1098,12 +1100,12 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced) | |||
1098 | kfree(aac->fsa_dev); | 1100 | kfree(aac->fsa_dev); |
1099 | aac->fsa_dev = NULL; | 1101 | aac->fsa_dev = NULL; |
1100 | if (aac_get_driver_ident(index)->quirks & AAC_QUIRK_31BIT) { | 1102 | if (aac_get_driver_ident(index)->quirks & AAC_QUIRK_31BIT) { |
1101 | if (((retval = pci_set_dma_mask(aac->pdev, DMA_32BIT_MASK))) || | 1103 | if (((retval = pci_set_dma_mask(aac->pdev, DMA_31BIT_MASK))) || |
1102 | ((retval = pci_set_consistent_dma_mask(aac->pdev, DMA_32BIT_MASK)))) | 1104 | ((retval = pci_set_consistent_dma_mask(aac->pdev, DMA_31BIT_MASK)))) |
1103 | goto out; | 1105 | goto out; |
1104 | } else { | 1106 | } else { |
1105 | if (((retval = pci_set_dma_mask(aac->pdev, 0x7FFFFFFFULL))) || | 1107 | if (((retval = pci_set_dma_mask(aac->pdev, DMA_32BIT_MASK))) || |
1106 | ((retval = pci_set_consistent_dma_mask(aac->pdev, 0x7FFFFFFFULL)))) | 1108 | ((retval = pci_set_consistent_dma_mask(aac->pdev, DMA_32BIT_MASK)))) |
1107 | goto out; | 1109 | goto out; |
1108 | } | 1110 | } |
1109 | if ((retval = (*(aac_get_driver_ident(index)->init))(aac))) | 1111 | if ((retval = (*(aac_get_driver_ident(index)->init))(aac))) |
diff --git a/drivers/scsi/aic94xx/aic94xx_dev.c b/drivers/scsi/aic94xx/aic94xx_dev.c index c520e5b41fb5..3dce618bf414 100644 --- a/drivers/scsi/aic94xx/aic94xx_dev.c +++ b/drivers/scsi/aic94xx/aic94xx_dev.c | |||
@@ -126,7 +126,7 @@ static inline int asd_init_sata(struct domain_device *dev) | |||
126 | if (w76 & 0x100) /* NCQ? */ | 126 | if (w76 & 0x100) /* NCQ? */ |
127 | qdepth = (w75 & 0x1F) + 1; | 127 | qdepth = (w75 & 0x1F) + 1; |
128 | asd_ddbsite_write_dword(asd_ha, ddb, SATA_TAG_ALLOC_MASK, | 128 | asd_ddbsite_write_dword(asd_ha, ddb, SATA_TAG_ALLOC_MASK, |
129 | (1<<qdepth)-1); | 129 | (1ULL<<qdepth)-1); |
130 | asd_ddbsite_write_byte(asd_ha, ddb, NUM_SATA_TAGS, qdepth); | 130 | asd_ddbsite_write_byte(asd_ha, ddb, NUM_SATA_TAGS, qdepth); |
131 | } | 131 | } |
132 | if (dev->dev_type == SATA_DEV || dev->dev_type == SATA_PM || | 132 | if (dev->dev_type == SATA_DEV || dev->dev_type == SATA_PM || |
diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c index b8c6810090d5..ab00aecc5466 100644 --- a/drivers/scsi/aic94xx/aic94xx_init.c +++ b/drivers/scsi/aic94xx/aic94xx_init.c | |||
@@ -81,6 +81,9 @@ static struct scsi_host_template aic94xx_sht = { | |||
81 | .use_clustering = ENABLE_CLUSTERING, | 81 | .use_clustering = ENABLE_CLUSTERING, |
82 | .eh_device_reset_handler = sas_eh_device_reset_handler, | 82 | .eh_device_reset_handler = sas_eh_device_reset_handler, |
83 | .eh_bus_reset_handler = sas_eh_bus_reset_handler, | 83 | .eh_bus_reset_handler = sas_eh_bus_reset_handler, |
84 | .slave_alloc = sas_slave_alloc, | ||
85 | .target_destroy = sas_target_destroy, | ||
86 | .ioctl = sas_ioctl, | ||
84 | }; | 87 | }; |
85 | 88 | ||
86 | static int __devinit asd_map_memio(struct asd_ha_struct *asd_ha) | 89 | static int __devinit asd_map_memio(struct asd_ha_struct *asd_ha) |
diff --git a/drivers/scsi/aic94xx/aic94xx_task.c b/drivers/scsi/aic94xx/aic94xx_task.c index e2ad5bed9403..d5d8caba3560 100644 --- a/drivers/scsi/aic94xx/aic94xx_task.c +++ b/drivers/scsi/aic94xx/aic94xx_task.c | |||
@@ -74,8 +74,13 @@ static inline int asd_map_scatterlist(struct sas_task *task, | |||
74 | return 0; | 74 | return 0; |
75 | } | 75 | } |
76 | 76 | ||
77 | num_sg = pci_map_sg(asd_ha->pcidev, task->scatter, task->num_scatter, | 77 | /* STP tasks come from libata which has already mapped |
78 | task->data_dir); | 78 | * the SG list */ |
79 | if (sas_protocol_ata(task->task_proto)) | ||
80 | num_sg = task->num_scatter; | ||
81 | else | ||
82 | num_sg = pci_map_sg(asd_ha->pcidev, task->scatter, | ||
83 | task->num_scatter, task->data_dir); | ||
79 | if (num_sg == 0) | 84 | if (num_sg == 0) |
80 | return -ENOMEM; | 85 | return -ENOMEM; |
81 | 86 | ||
@@ -120,8 +125,9 @@ static inline int asd_map_scatterlist(struct sas_task *task, | |||
120 | 125 | ||
121 | return 0; | 126 | return 0; |
122 | err_unmap: | 127 | err_unmap: |
123 | pci_unmap_sg(asd_ha->pcidev, task->scatter, task->num_scatter, | 128 | if (sas_protocol_ata(task->task_proto)) |
124 | task->data_dir); | 129 | pci_unmap_sg(asd_ha->pcidev, task->scatter, task->num_scatter, |
130 | task->data_dir); | ||
125 | return res; | 131 | return res; |
126 | } | 132 | } |
127 | 133 | ||
@@ -142,8 +148,9 @@ static inline void asd_unmap_scatterlist(struct asd_ascb *ascb) | |||
142 | } | 148 | } |
143 | 149 | ||
144 | asd_free_coherent(asd_ha, ascb->sg_arr); | 150 | asd_free_coherent(asd_ha, ascb->sg_arr); |
145 | pci_unmap_sg(asd_ha->pcidev, task->scatter, task->num_scatter, | 151 | if (task->task_proto != SAS_PROTOCOL_STP) |
146 | task->data_dir); | 152 | pci_unmap_sg(asd_ha->pcidev, task->scatter, task->num_scatter, |
153 | task->data_dir); | ||
147 | } | 154 | } |
148 | 155 | ||
149 | /* ---------- Task complete tasklet ---------- */ | 156 | /* ---------- Task complete tasklet ---------- */ |
@@ -391,7 +398,6 @@ static int asd_build_ata_ascb(struct asd_ascb *ascb, struct sas_task *task, | |||
391 | 398 | ||
392 | scb->ata_task.total_xfer_len = cpu_to_le32(task->total_xfer_len); | 399 | scb->ata_task.total_xfer_len = cpu_to_le32(task->total_xfer_len); |
393 | scb->ata_task.fis = task->ata_task.fis; | 400 | scb->ata_task.fis = task->ata_task.fis; |
394 | scb->ata_task.fis.fis_type = 0x27; | ||
395 | if (likely(!task->ata_task.device_control_reg_update)) | 401 | if (likely(!task->ata_task.device_control_reg_update)) |
396 | scb->ata_task.fis.flags |= 0x80; /* C=1: update ATA cmd reg */ | 402 | scb->ata_task.fis.flags |= 0x80; /* C=1: update ATA cmd reg */ |
397 | scb->ata_task.fis.flags &= 0xF0; /* PM_PORT field shall be 0 */ | 403 | scb->ata_task.fis.flags &= 0xF0; /* PM_PORT field shall be 0 */ |
diff --git a/drivers/scsi/arm/cumana_1.c b/drivers/scsi/arm/cumana_1.c index cf9a21cea6d9..49d838e90a24 100644 --- a/drivers/scsi/arm/cumana_1.c +++ b/drivers/scsi/arm/cumana_1.c | |||
@@ -24,7 +24,7 @@ | |||
24 | 24 | ||
25 | #define CUMANASCSI_PUBLIC_RELEASE 1 | 25 | #define CUMANASCSI_PUBLIC_RELEASE 1 |
26 | 26 | ||
27 | #define NCR5380_implementation_fields int port, ctrl | 27 | #define priv(host) ((struct NCR5380_hostdata *)(host)->hostdata) |
28 | #define NCR5380_local_declare() struct Scsi_Host *_instance | 28 | #define NCR5380_local_declare() struct Scsi_Host *_instance |
29 | #define NCR5380_setup(instance) _instance = instance | 29 | #define NCR5380_setup(instance) _instance = instance |
30 | #define NCR5380_read(reg) cumanascsi_read(_instance, reg) | 30 | #define NCR5380_read(reg) cumanascsi_read(_instance, reg) |
@@ -33,6 +33,11 @@ | |||
33 | #define NCR5380_queue_command cumanascsi_queue_command | 33 | #define NCR5380_queue_command cumanascsi_queue_command |
34 | #define NCR5380_proc_info cumanascsi_proc_info | 34 | #define NCR5380_proc_info cumanascsi_proc_info |
35 | 35 | ||
36 | #define NCR5380_implementation_fields \ | ||
37 | unsigned ctrl; \ | ||
38 | void __iomem *base; \ | ||
39 | void __iomem *dma | ||
40 | |||
36 | #define BOARD_NORMAL 0 | 41 | #define BOARD_NORMAL 0 |
37 | #define BOARD_NCR53C400 1 | 42 | #define BOARD_NCR53C400 1 |
38 | 43 | ||
@@ -47,192 +52,162 @@ const char *cumanascsi_info(struct Scsi_Host *spnt) | |||
47 | return ""; | 52 | return ""; |
48 | } | 53 | } |
49 | 54 | ||
50 | #ifdef NOT_EFFICIENT | 55 | #define CTRL 0x16fc |
51 | #define CTRL(p,v) outb(*ctrl = (v), (p) - 577) | 56 | #define STAT 0x2004 |
52 | #define STAT(p) inb((p)+1) | 57 | #define L(v) (((v)<<16)|((v) & 0x0000ffff)) |
53 | #define IN(p) inb((p)) | 58 | #define H(v) (((v)>>16)|((v) & 0xffff0000)) |
54 | #define OUT(v,p) outb((v), (p)) | ||
55 | #else | ||
56 | #define CTRL(p,v) (p[-2308] = (*ctrl = (v))) | ||
57 | #define STAT(p) (p[4]) | ||
58 | #define IN(p) (*(p)) | ||
59 | #define IN2(p) ((unsigned short)(*(volatile unsigned long *)(p))) | ||
60 | #define OUT(v,p) (*(p) = (v)) | ||
61 | #define OUT2(v,p) (*((volatile unsigned long *)(p)) = (v)) | ||
62 | #endif | ||
63 | #define L(v) (((v)<<16)|((v) & 0x0000ffff)) | ||
64 | #define H(v) (((v)>>16)|((v) & 0xffff0000)) | ||
65 | 59 | ||
66 | static inline int | 60 | static inline int |
67 | NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *addr, int len) | 61 | NCR5380_pwrite(struct Scsi_Host *host, unsigned char *addr, int len) |
68 | { | 62 | { |
69 | int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl; | ||
70 | int oldctrl = *ctrl; | ||
71 | unsigned long *laddr; | 63 | unsigned long *laddr; |
72 | #ifdef NOT_EFFICIENT | 64 | void __iomem *dma = priv(host)->dma + 0x2000; |
73 | int iobase = instance->io_port; | ||
74 | int dma_io = iobase & ~(0x3C0000>>2); | ||
75 | #else | ||
76 | volatile unsigned char *iobase = (unsigned char *)ioaddr(instance->io_port); | ||
77 | volatile unsigned char *dma_io = (unsigned char *)((int)iobase & ~0x3C0000); | ||
78 | #endif | ||
79 | 65 | ||
80 | if(!len) return 0; | 66 | if(!len) return 0; |
81 | 67 | ||
82 | CTRL(iobase, 0x02); | 68 | writeb(0x02, priv(host)->base + CTRL); |
83 | laddr = (unsigned long *)addr; | 69 | laddr = (unsigned long *)addr; |
84 | while(len >= 32) | 70 | while(len >= 32) |
85 | { | 71 | { |
86 | int status; | 72 | unsigned int status; |
87 | unsigned long v; | 73 | unsigned long v; |
88 | status = STAT(iobase); | 74 | status = readb(priv(host)->base + STAT); |
89 | if(status & 0x80) | 75 | if(status & 0x80) |
90 | goto end; | 76 | goto end; |
91 | if(!(status & 0x40)) | 77 | if(!(status & 0x40)) |
92 | continue; | 78 | continue; |
93 | v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); | 79 | v=*laddr++; writew(L(v), dma); writew(H(v), dma); |
94 | v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); | 80 | v=*laddr++; writew(L(v), dma); writew(H(v), dma); |
95 | v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); | 81 | v=*laddr++; writew(L(v), dma); writew(H(v), dma); |
96 | v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); | 82 | v=*laddr++; writew(L(v), dma); writew(H(v), dma); |
97 | v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); | 83 | v=*laddr++; writew(L(v), dma); writew(H(v), dma); |
98 | v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); | 84 | v=*laddr++; writew(L(v), dma); writew(H(v), dma); |
99 | v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); | 85 | v=*laddr++; writew(L(v), dma); writew(H(v), dma); |
100 | v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); | 86 | v=*laddr++; writew(L(v), dma); writew(H(v), dma); |
101 | len -= 32; | 87 | len -= 32; |
102 | if(len == 0) | 88 | if(len == 0) |
103 | break; | 89 | break; |
104 | } | 90 | } |
105 | 91 | ||
106 | addr = (unsigned char *)laddr; | 92 | addr = (unsigned char *)laddr; |
107 | CTRL(iobase, 0x12); | 93 | writeb(0x12, priv(host)->base + CTRL); |
94 | |||
108 | while(len > 0) | 95 | while(len > 0) |
109 | { | 96 | { |
110 | int status; | 97 | unsigned int status; |
111 | status = STAT(iobase); | 98 | status = readb(priv(host)->base + STAT); |
112 | if(status & 0x80) | 99 | if(status & 0x80) |
113 | goto end; | 100 | goto end; |
114 | if(status & 0x40) | 101 | if(status & 0x40) |
115 | { | 102 | { |
116 | OUT(*addr++, dma_io); | 103 | writeb(*addr++, dma); |
117 | if(--len == 0) | 104 | if(--len == 0) |
118 | break; | 105 | break; |
119 | } | 106 | } |
120 | 107 | ||
121 | status = STAT(iobase); | 108 | status = readb(priv(host)->base + STAT); |
122 | if(status & 0x80) | 109 | if(status & 0x80) |
123 | goto end; | 110 | goto end; |
124 | if(status & 0x40) | 111 | if(status & 0x40) |
125 | { | 112 | { |
126 | OUT(*addr++, dma_io); | 113 | writeb(*addr++, dma); |
127 | if(--len == 0) | 114 | if(--len == 0) |
128 | break; | 115 | break; |
129 | } | 116 | } |
130 | } | 117 | } |
131 | end: | 118 | end: |
132 | CTRL(iobase, oldctrl|0x40); | 119 | writeb(priv(host)->ctrl | 0x40, priv(host)->base + CTRL); |
133 | return len; | 120 | return len; |
134 | } | 121 | } |
135 | 122 | ||
136 | static inline int | 123 | static inline int |
137 | NCR5380_pread(struct Scsi_Host *instance, unsigned char *addr, int len) | 124 | NCR5380_pread(struct Scsi_Host *host, unsigned char *addr, int len) |
138 | { | 125 | { |
139 | int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl; | ||
140 | int oldctrl = *ctrl; | ||
141 | unsigned long *laddr; | 126 | unsigned long *laddr; |
142 | #ifdef NOT_EFFICIENT | 127 | void __iomem *dma = priv(host)->dma + 0x2000; |
143 | int iobase = instance->io_port; | ||
144 | int dma_io = iobase & ~(0x3C0000>>2); | ||
145 | #else | ||
146 | volatile unsigned char *iobase = (unsigned char *)ioaddr(instance->io_port); | ||
147 | volatile unsigned char *dma_io = (unsigned char *)((int)iobase & ~0x3C0000); | ||
148 | #endif | ||
149 | 128 | ||
150 | if(!len) return 0; | 129 | if(!len) return 0; |
151 | 130 | ||
152 | CTRL(iobase, 0x00); | 131 | writeb(0x00, priv(host)->base + CTRL); |
153 | laddr = (unsigned long *)addr; | 132 | laddr = (unsigned long *)addr; |
154 | while(len >= 32) | 133 | while(len >= 32) |
155 | { | 134 | { |
156 | int status; | 135 | unsigned int status; |
157 | status = STAT(iobase); | 136 | status = readb(priv(host)->base + STAT); |
158 | if(status & 0x80) | 137 | if(status & 0x80) |
159 | goto end; | 138 | goto end; |
160 | if(!(status & 0x40)) | 139 | if(!(status & 0x40)) |
161 | continue; | 140 | continue; |
162 | *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); | 141 | *laddr++ = readw(dma) | (readw(dma) << 16); |
163 | *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); | 142 | *laddr++ = readw(dma) | (readw(dma) << 16); |
164 | *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); | 143 | *laddr++ = readw(dma) | (readw(dma) << 16); |
165 | *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); | 144 | *laddr++ = readw(dma) | (readw(dma) << 16); |
166 | *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); | 145 | *laddr++ = readw(dma) | (readw(dma) << 16); |
167 | *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); | 146 | *laddr++ = readw(dma) | (readw(dma) << 16); |
168 | *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); | 147 | *laddr++ = readw(dma) | (readw(dma) << 16); |
169 | *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); | 148 | *laddr++ = readw(dma) | (readw(dma) << 16); |
170 | len -= 32; | 149 | len -= 32; |
171 | if(len == 0) | 150 | if(len == 0) |
172 | break; | 151 | break; |
173 | } | 152 | } |
174 | 153 | ||
175 | addr = (unsigned char *)laddr; | 154 | addr = (unsigned char *)laddr; |
176 | CTRL(iobase, 0x10); | 155 | writeb(0x10, priv(host)->base + CTRL); |
156 | |||
177 | while(len > 0) | 157 | while(len > 0) |
178 | { | 158 | { |
179 | int status; | 159 | unsigned int status; |
180 | status = STAT(iobase); | 160 | status = readb(priv(host)->base + STAT); |
181 | if(status & 0x80) | 161 | if(status & 0x80) |
182 | goto end; | 162 | goto end; |
183 | if(status & 0x40) | 163 | if(status & 0x40) |
184 | { | 164 | { |
185 | *addr++ = IN(dma_io); | 165 | *addr++ = readb(dma); |
186 | if(--len == 0) | 166 | if(--len == 0) |
187 | break; | 167 | break; |
188 | } | 168 | } |
189 | 169 | ||
190 | status = STAT(iobase); | 170 | status = readb(priv(host)->base + STAT); |
191 | if(status & 0x80) | 171 | if(status & 0x80) |
192 | goto end; | 172 | goto end; |
193 | if(status & 0x40) | 173 | if(status & 0x40) |
194 | { | 174 | { |
195 | *addr++ = IN(dma_io); | 175 | *addr++ = readb(dma); |
196 | if(--len == 0) | 176 | if(--len == 0) |
197 | break; | 177 | break; |
198 | } | 178 | } |
199 | } | 179 | } |
200 | end: | 180 | end: |
201 | CTRL(iobase, oldctrl|0x40); | 181 | writeb(priv(host)->ctrl | 0x40, priv(host)->base + CTRL); |
202 | return len; | 182 | return len; |
203 | } | 183 | } |
204 | 184 | ||
205 | #undef STAT | 185 | static unsigned char cumanascsi_read(struct Scsi_Host *host, unsigned int reg) |
206 | #undef CTRL | 186 | { |
207 | #undef IN | 187 | void __iomem *base = priv(host)->base; |
208 | #undef OUT | 188 | unsigned char val; |
209 | 189 | ||
210 | #define CTRL(p,v) outb(*ctrl = (v), (p) - 577) | 190 | writeb(0, base + CTRL); |
211 | 191 | ||
212 | static char cumanascsi_read(struct Scsi_Host *instance, int reg) | 192 | val = readb(base + 0x2100 + (reg << 2)); |
213 | { | ||
214 | unsigned int iobase = instance->io_port; | ||
215 | int i; | ||
216 | int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl; | ||
217 | 193 | ||
218 | CTRL(iobase, 0); | 194 | priv(host)->ctrl = 0x40; |
219 | i = inb(iobase + 64 + reg); | 195 | writeb(0x40, base + CTRL); |
220 | CTRL(iobase, 0x40); | ||
221 | 196 | ||
222 | return i; | 197 | return val; |
223 | } | 198 | } |
224 | 199 | ||
225 | static void cumanascsi_write(struct Scsi_Host *instance, int reg, int value) | 200 | static void cumanascsi_write(struct Scsi_Host *host, unsigned int reg, unsigned int value) |
226 | { | 201 | { |
227 | int iobase = instance->io_port; | 202 | void __iomem *base = priv(host)->base; |
228 | int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl; | ||
229 | 203 | ||
230 | CTRL(iobase, 0); | 204 | writeb(0, base + CTRL); |
231 | outb(value, iobase + 64 + reg); | ||
232 | CTRL(iobase, 0x40); | ||
233 | } | ||
234 | 205 | ||
235 | #undef CTRL | 206 | writeb(value, base + 0x2100 + (reg << 2)); |
207 | |||
208 | priv(host)->ctrl = 0x40; | ||
209 | writeb(0x40, base + CTRL); | ||
210 | } | ||
236 | 211 | ||
237 | #include "../NCR5380.c" | 212 | #include "../NCR5380.c" |
238 | 213 | ||
@@ -256,32 +231,46 @@ static int __devinit | |||
256 | cumanascsi1_probe(struct expansion_card *ec, const struct ecard_id *id) | 231 | cumanascsi1_probe(struct expansion_card *ec, const struct ecard_id *id) |
257 | { | 232 | { |
258 | struct Scsi_Host *host; | 233 | struct Scsi_Host *host; |
259 | int ret = -ENOMEM; | 234 | int ret; |
260 | 235 | ||
261 | host = scsi_host_alloc(&cumanascsi_template, sizeof(struct NCR5380_hostdata)); | 236 | ret = ecard_request_resources(ec); |
262 | if (!host) | 237 | if (ret) |
263 | goto out; | 238 | goto out; |
264 | 239 | ||
265 | host->io_port = ecard_address(ec, ECARD_IOC, ECARD_SLOW) + 0x800; | 240 | host = scsi_host_alloc(&cumanascsi_template, sizeof(struct NCR5380_hostdata)); |
241 | if (!host) { | ||
242 | ret = -ENOMEM; | ||
243 | goto out_release; | ||
244 | } | ||
245 | |||
246 | priv(host)->base = ioremap(ecard_resource_start(ec, ECARD_RES_IOCSLOW), | ||
247 | ecard_resource_len(ec, ECARD_RES_IOCSLOW)); | ||
248 | priv(host)->dma = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC), | ||
249 | ecard_resource_len(ec, ECARD_RES_MEMC)); | ||
250 | if (!priv(host)->base || !priv(host)->dma) { | ||
251 | ret = -ENOMEM; | ||
252 | goto out_unmap; | ||
253 | } | ||
254 | |||
266 | host->irq = ec->irq; | 255 | host->irq = ec->irq; |
267 | 256 | ||
268 | NCR5380_init(host, 0); | 257 | NCR5380_init(host, 0); |
269 | 258 | ||
259 | priv(host)->ctrl = 0; | ||
260 | writeb(0, priv(host)->base + CTRL); | ||
261 | |||
270 | host->n_io_port = 255; | 262 | host->n_io_port = 255; |
271 | if (!(request_region(host->io_port, host->n_io_port, "CumanaSCSI-1"))) { | 263 | if (!(request_region(host->io_port, host->n_io_port, "CumanaSCSI-1"))) { |
272 | ret = -EBUSY; | 264 | ret = -EBUSY; |
273 | goto out_free; | 265 | goto out_unmap; |
274 | } | 266 | } |
275 | 267 | ||
276 | ((struct NCR5380_hostdata *)host->hostdata)->ctrl = 0; | ||
277 | outb(0x00, host->io_port - 577); | ||
278 | |||
279 | ret = request_irq(host->irq, cumanascsi_intr, IRQF_DISABLED, | 268 | ret = request_irq(host->irq, cumanascsi_intr, IRQF_DISABLED, |
280 | "CumanaSCSI-1", host); | 269 | "CumanaSCSI-1", host); |
281 | if (ret) { | 270 | if (ret) { |
282 | printk("scsi%d: IRQ%d not free: %d\n", | 271 | printk("scsi%d: IRQ%d not free: %d\n", |
283 | host->host_no, host->irq, ret); | 272 | host->host_no, host->irq, ret); |
284 | goto out_release; | 273 | goto out_unmap; |
285 | } | 274 | } |
286 | 275 | ||
287 | printk("scsi%d: at port 0x%08lx irq %d", | 276 | printk("scsi%d: at port 0x%08lx irq %d", |
@@ -301,10 +290,12 @@ cumanascsi1_probe(struct expansion_card *ec, const struct ecard_id *id) | |||
301 | 290 | ||
302 | out_free_irq: | 291 | out_free_irq: |
303 | free_irq(host->irq, host); | 292 | free_irq(host->irq, host); |
304 | out_release: | 293 | out_unmap: |
305 | release_region(host->io_port, host->n_io_port); | 294 | iounmap(priv(host)->base); |
306 | out_free: | 295 | iounmap(priv(host)->dma); |
307 | scsi_host_put(host); | 296 | scsi_host_put(host); |
297 | out_release: | ||
298 | ecard_release_resources(ec); | ||
308 | out: | 299 | out: |
309 | return ret; | 300 | return ret; |
310 | } | 301 | } |
@@ -318,8 +309,10 @@ static void __devexit cumanascsi1_remove(struct expansion_card *ec) | |||
318 | scsi_remove_host(host); | 309 | scsi_remove_host(host); |
319 | free_irq(host->irq, host); | 310 | free_irq(host->irq, host); |
320 | NCR5380_exit(host); | 311 | NCR5380_exit(host); |
321 | release_region(host->io_port, host->n_io_port); | 312 | iounmap(priv(host)->base); |
313 | iounmap(priv(host)->dma); | ||
322 | scsi_host_put(host); | 314 | scsi_host_put(host); |
315 | ecard_release_resources(ec); | ||
323 | } | 316 | } |
324 | 317 | ||
325 | static const struct ecard_id cumanascsi1_cids[] = { | 318 | static const struct ecard_id cumanascsi1_cids[] = { |
diff --git a/drivers/scsi/arm/ecoscsi.c b/drivers/scsi/arm/ecoscsi.c index 378e7af0c5d6..5265a9884338 100644 --- a/drivers/scsi/arm/ecoscsi.c +++ b/drivers/scsi/arm/ecoscsi.c | |||
@@ -34,35 +34,25 @@ | |||
34 | #include "../scsi.h" | 34 | #include "../scsi.h" |
35 | #include <scsi/scsi_host.h> | 35 | #include <scsi/scsi_host.h> |
36 | 36 | ||
37 | #define NCR5380_implementation_fields int port, ctrl | 37 | #define priv(host) ((struct NCR5380_hostdata *)(host)->hostdata) |
38 | #define NCR5380_local_declare() struct Scsi_Host *_instance | ||
39 | #define NCR5380_setup(instance) _instance = instance | ||
40 | 38 | ||
41 | #define NCR5380_read(reg) ecoscsi_read(_instance, reg) | 39 | #define NCR5380_local_declare() void __iomem *_base |
42 | #define NCR5380_write(reg, value) ecoscsi_write(_instance, reg, value) | 40 | #define NCR5380_setup(host) _base = priv(host)->base |
41 | |||
42 | #define NCR5380_read(reg) ({ writeb(reg | 8, _base); readb(_base + 4); }) | ||
43 | #define NCR5380_write(reg, value) ({ writeb(reg | 8, _base); writeb(value, _base + 4); }) | ||
43 | 44 | ||
44 | #define NCR5380_intr ecoscsi_intr | 45 | #define NCR5380_intr ecoscsi_intr |
45 | #define NCR5380_queue_command ecoscsi_queue_command | 46 | #define NCR5380_queue_command ecoscsi_queue_command |
46 | #define NCR5380_proc_info ecoscsi_proc_info | 47 | #define NCR5380_proc_info ecoscsi_proc_info |
47 | 48 | ||
49 | #define NCR5380_implementation_fields \ | ||
50 | void __iomem *base | ||
51 | |||
48 | #include "../NCR5380.h" | 52 | #include "../NCR5380.h" |
49 | 53 | ||
50 | #define ECOSCSI_PUBLIC_RELEASE 1 | 54 | #define ECOSCSI_PUBLIC_RELEASE 1 |
51 | 55 | ||
52 | static char ecoscsi_read(struct Scsi_Host *instance, int reg) | ||
53 | { | ||
54 | int iobase = instance->io_port; | ||
55 | outb(reg | 8, iobase); | ||
56 | return inb(iobase + 1); | ||
57 | } | ||
58 | |||
59 | static void ecoscsi_write(struct Scsi_Host *instance, int reg, int value) | ||
60 | { | ||
61 | int iobase = instance->io_port; | ||
62 | outb(reg | 8, iobase); | ||
63 | outb(value, iobase + 1); | ||
64 | } | ||
65 | |||
66 | /* | 56 | /* |
67 | * Function : ecoscsi_setup(char *str, int *ints) | 57 | * Function : ecoscsi_setup(char *str, int *ints) |
68 | * | 58 | * |
@@ -82,73 +72,6 @@ const char * ecoscsi_info (struct Scsi_Host *spnt) | |||
82 | return ""; | 72 | return ""; |
83 | } | 73 | } |
84 | 74 | ||
85 | #if 0 | ||
86 | #define STAT(p) inw(p + 144) | ||
87 | |||
88 | static inline int NCR5380_pwrite(struct Scsi_Host *host, unsigned char *addr, | ||
89 | int len) | ||
90 | { | ||
91 | int iobase = host->io_port; | ||
92 | printk("writing %p len %d\n",addr, len); | ||
93 | if(!len) return -1; | ||
94 | |||
95 | while(1) | ||
96 | { | ||
97 | int status; | ||
98 | while(((status = STAT(iobase)) & 0x100)==0); | ||
99 | } | ||
100 | } | ||
101 | |||
102 | static inline int NCR5380_pread(struct Scsi_Host *host, unsigned char *addr, | ||
103 | int len) | ||
104 | { | ||
105 | int iobase = host->io_port; | ||
106 | int iobase2= host->io_port + 0x100; | ||
107 | unsigned char *start = addr; | ||
108 | int s; | ||
109 | printk("reading %p len %d\n",addr, len); | ||
110 | outb(inb(iobase + 128), iobase + 135); | ||
111 | while(len > 0) | ||
112 | { | ||
113 | int status,b,i, timeout; | ||
114 | timeout = 0x07FFFFFF; | ||
115 | while(((status = STAT(iobase)) & 0x100)==0) | ||
116 | { | ||
117 | timeout--; | ||
118 | if(status & 0x200 || !timeout) | ||
119 | { | ||
120 | printk("status = %p\n",status); | ||
121 | outb(0, iobase + 135); | ||
122 | return 1; | ||
123 | } | ||
124 | } | ||
125 | if(len >= 128) | ||
126 | { | ||
127 | for(i=0; i<64; i++) | ||
128 | { | ||
129 | b = inw(iobase + 136); | ||
130 | *addr++ = b; | ||
131 | *addr++ = b>>8; | ||
132 | } | ||
133 | len -= 128; | ||
134 | } | ||
135 | else | ||
136 | { | ||
137 | b = inw(iobase + 136); | ||
138 | *addr ++ = b; | ||
139 | len -= 1; | ||
140 | if(len) | ||
141 | *addr ++ = b>>8; | ||
142 | len -= 1; | ||
143 | } | ||
144 | } | ||
145 | outb(0, iobase + 135); | ||
146 | printk("first bytes = %02X %02X %02X %20X %02X %02X %02X\n",*start, start[1], start[2], start[3], start[4], start[5], start[6]); | ||
147 | return 1; | ||
148 | } | ||
149 | #endif | ||
150 | #undef STAT | ||
151 | |||
152 | #define BOARD_NORMAL 0 | 75 | #define BOARD_NORMAL 0 |
153 | #define BOARD_NCR53C400 1 | 76 | #define BOARD_NCR53C400 1 |
154 | 77 | ||
@@ -173,25 +96,36 @@ static struct Scsi_Host *host; | |||
173 | 96 | ||
174 | static int __init ecoscsi_init(void) | 97 | static int __init ecoscsi_init(void) |
175 | { | 98 | { |
99 | void __iomem *_base; | ||
100 | int ret; | ||
176 | 101 | ||
177 | host = scsi_host_alloc(tpnt, sizeof(struct NCR5380_hostdata)); | 102 | if (!request_mem_region(0x33a0000, 4096, "ecoscsi")) { |
178 | if (!host) | 103 | ret = -EBUSY; |
179 | return 0; | 104 | goto out; |
105 | } | ||
180 | 106 | ||
181 | host->io_port = 0x80ce8000; | 107 | _base = ioremap(0x33a0000, 4096); |
182 | host->n_io_port = 144; | 108 | if (!_base) { |
183 | host->irq = IRQ_NONE; | 109 | ret = -ENOMEM; |
110 | goto out_release; | ||
111 | } | ||
184 | 112 | ||
185 | if (!(request_region(host->io_port, host->n_io_port, "ecoscsi")) ) | 113 | NCR5380_write(MODE_REG, 0x20); /* Is it really SCSI? */ |
186 | goto unregister_scsi; | 114 | if (NCR5380_read(MODE_REG) != 0x20) /* Write to a reg. */ |
115 | goto out_unmap; | ||
187 | 116 | ||
188 | ecoscsi_write(host, MODE_REG, 0x20); /* Is it really SCSI? */ | 117 | NCR5380_write(MODE_REG, 0x00); /* it back. */ |
189 | if (ecoscsi_read(host, MODE_REG) != 0x20) /* Write to a reg. */ | 118 | if (NCR5380_read(MODE_REG) != 0x00) |
190 | goto release_reg; | 119 | goto out_unmap; |
191 | 120 | ||
192 | ecoscsi_write(host, MODE_REG, 0x00 ); /* it back. */ | 121 | host = scsi_host_alloc(tpnt, sizeof(struct NCR5380_hostdata)); |
193 | if (ecoscsi_read(host, MODE_REG) != 0x00) | 122 | if (!host) { |
194 | goto release_reg; | 123 | ret = -ENOMEM; |
124 | goto out_unmap; | ||
125 | } | ||
126 | |||
127 | priv(host)->base = _base; | ||
128 | host->irq = IRQ_NONE; | ||
195 | 129 | ||
196 | NCR5380_init(host, 0); | 130 | NCR5380_init(host, 0); |
197 | 131 | ||
@@ -206,24 +140,20 @@ static int __init ecoscsi_init(void) | |||
206 | scsi_scan_host(host); | 140 | scsi_scan_host(host); |
207 | return 0; | 141 | return 0; |
208 | 142 | ||
209 | release_reg: | 143 | out_unmap: |
210 | release_region(host->io_port, host->n_io_port); | 144 | iounmap(_base); |
211 | unregister_scsi: | 145 | out_release: |
212 | scsi_host_put(host); | 146 | release_mem_region(0x33a0000, 4096); |
213 | return -ENODEV; | 147 | out: |
148 | return ret; | ||
214 | } | 149 | } |
215 | 150 | ||
216 | static void __exit ecoscsi_exit(void) | 151 | static void __exit ecoscsi_exit(void) |
217 | { | 152 | { |
218 | scsi_remove_host(host); | 153 | scsi_remove_host(host); |
219 | |||
220 | if (shpnt->irq != IRQ_NONE) | ||
221 | free_irq(shpnt->irq, NULL); | ||
222 | NCR5380_exit(host); | 154 | NCR5380_exit(host); |
223 | if (shpnt->io_port) | ||
224 | release_region(shpnt->io_port, shpnt->n_io_port); | ||
225 | |||
226 | scsi_host_put(host); | 155 | scsi_host_put(host); |
156 | release_mem_region(0x33a0000, 4096); | ||
227 | return 0; | 157 | return 0; |
228 | } | 158 | } |
229 | 159 | ||
diff --git a/drivers/scsi/arm/oak.c b/drivers/scsi/arm/oak.c index c21b8392c928..849cdf89f7bb 100644 --- a/drivers/scsi/arm/oak.c +++ b/drivers/scsi/arm/oak.c | |||
@@ -23,15 +23,18 @@ | |||
23 | 23 | ||
24 | #define OAKSCSI_PUBLIC_RELEASE 1 | 24 | #define OAKSCSI_PUBLIC_RELEASE 1 |
25 | 25 | ||
26 | #define NCR5380_read(reg) oakscsi_read(_instance, reg) | 26 | #define priv(host) ((struct NCR5380_hostdata *)(host)->hostdata) |
27 | #define NCR5380_write(reg, value) oakscsi_write(_instance, reg, value) | 27 | #define NCR5380_local_declare() void __iomem *_base |
28 | #define NCR5380_setup(host) _base = priv(host)->base | ||
29 | |||
30 | #define NCR5380_read(reg) readb(_base + ((reg) << 2)) | ||
31 | #define NCR5380_write(reg, value) writeb(value, _base + ((reg) << 2)) | ||
28 | #define NCR5380_intr oakscsi_intr | 32 | #define NCR5380_intr oakscsi_intr |
29 | #define NCR5380_queue_command oakscsi_queue_command | 33 | #define NCR5380_queue_command oakscsi_queue_command |
30 | #define NCR5380_proc_info oakscsi_proc_info | 34 | #define NCR5380_proc_info oakscsi_proc_info |
31 | 35 | ||
32 | #define NCR5380_implementation_fields int port, ctrl | 36 | #define NCR5380_implementation_fields \ |
33 | #define NCR5380_local_declare() struct Scsi_Host *_instance | 37 | void __iomem *base |
34 | #define NCR5380_setup(instance) _instance = instance | ||
35 | 38 | ||
36 | #define BOARD_NORMAL 0 | 39 | #define BOARD_NORMAL 0 |
37 | #define BOARD_NCR53C400 1 | 40 | #define BOARD_NCR53C400 1 |
@@ -39,60 +42,62 @@ | |||
39 | #include "../NCR5380.h" | 42 | #include "../NCR5380.h" |
40 | 43 | ||
41 | #undef START_DMA_INITIATOR_RECEIVE_REG | 44 | #undef START_DMA_INITIATOR_RECEIVE_REG |
42 | #define START_DMA_INITIATOR_RECEIVE_REG (7 + 128) | 45 | #define START_DMA_INITIATOR_RECEIVE_REG (128 + 7) |
43 | 46 | ||
44 | const char * oakscsi_info (struct Scsi_Host *spnt) | 47 | const char * oakscsi_info (struct Scsi_Host *spnt) |
45 | { | 48 | { |
46 | return ""; | 49 | return ""; |
47 | } | 50 | } |
48 | 51 | ||
49 | #define STAT(p) inw(p + 144) | 52 | #define STAT ((128 + 16) << 2) |
50 | extern void inswb(int from, void *to, int len); | 53 | #define DATA ((128 + 8) << 2) |
51 | 54 | ||
52 | static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *addr, | 55 | static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *addr, |
53 | int len) | 56 | int len) |
54 | { | 57 | { |
55 | int iobase = instance->io_port; | 58 | void __iomem *base = priv(instance)->base; |
59 | |||
56 | printk("writing %p len %d\n",addr, len); | 60 | printk("writing %p len %d\n",addr, len); |
57 | if(!len) return -1; | 61 | if(!len) return -1; |
58 | 62 | ||
59 | while(1) | 63 | while(1) |
60 | { | 64 | { |
61 | int status; | 65 | int status; |
62 | while(((status = STAT(iobase)) & 0x100)==0); | 66 | while (((status = readw(base + STAT)) & 0x100)==0); |
63 | } | 67 | } |
64 | } | 68 | } |
65 | 69 | ||
66 | static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *addr, | 70 | static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *addr, |
67 | int len) | 71 | int len) |
68 | { | 72 | { |
69 | int iobase = instance->io_port; | 73 | void __iomem *base = priv(instance)->base; |
70 | printk("reading %p len %d\n", addr, len); | 74 | printk("reading %p len %d\n", addr, len); |
71 | while(len > 0) | 75 | while(len > 0) |
72 | { | 76 | { |
73 | int status, timeout; | 77 | unsigned int status, timeout; |
74 | unsigned long b; | 78 | unsigned long b; |
75 | 79 | ||
76 | timeout = 0x01FFFFFF; | 80 | timeout = 0x01FFFFFF; |
77 | 81 | ||
78 | while(((status = STAT(iobase)) & 0x100)==0) | 82 | while (((status = readw(base + STAT)) & 0x100)==0) |
79 | { | 83 | { |
80 | timeout--; | 84 | timeout--; |
81 | if(status & 0x200 || !timeout) | 85 | if(status & 0x200 || !timeout) |
82 | { | 86 | { |
83 | printk("status = %08X\n",status); | 87 | printk("status = %08X\n", status); |
84 | return 1; | 88 | return 1; |
85 | } | 89 | } |
86 | } | 90 | } |
91 | |||
87 | if(len >= 128) | 92 | if(len >= 128) |
88 | { | 93 | { |
89 | inswb(iobase + 136, addr, 128); | 94 | readsw(base + DATA, addr, 128); |
90 | addr += 128; | 95 | addr += 128; |
91 | len -= 128; | 96 | len -= 128; |
92 | } | 97 | } |
93 | else | 98 | else |
94 | { | 99 | { |
95 | b = (unsigned long) inw(iobase + 136); | 100 | b = (unsigned long) readw(base + DATA); |
96 | *addr ++ = b; | 101 | *addr ++ = b; |
97 | len -= 1; | 102 | len -= 1; |
98 | if(len) | 103 | if(len) |
@@ -103,10 +108,8 @@ printk("reading %p len %d\n", addr, len); | |||
103 | return 0; | 108 | return 0; |
104 | } | 109 | } |
105 | 110 | ||
106 | #define oakscsi_read(instance,reg) (inb((instance)->io_port + (reg))) | ||
107 | #define oakscsi_write(instance,reg,val) (outb((val), (instance)->io_port + (reg))) | ||
108 | |||
109 | #undef STAT | 111 | #undef STAT |
112 | #undef DATA | ||
110 | 113 | ||
111 | #include "../NCR5380.c" | 114 | #include "../NCR5380.c" |
112 | 115 | ||
@@ -132,18 +135,26 @@ oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id) | |||
132 | struct Scsi_Host *host; | 135 | struct Scsi_Host *host; |
133 | int ret = -ENOMEM; | 136 | int ret = -ENOMEM; |
134 | 137 | ||
135 | host = scsi_host_alloc(&oakscsi_template, sizeof(struct NCR5380_hostdata)); | 138 | ret = ecard_request_resources(ec); |
136 | if (!host) | 139 | if (ret) |
137 | goto out; | 140 | goto out; |
138 | 141 | ||
139 | host->io_port = ecard_address(ec, ECARD_MEMC, 0); | 142 | host = scsi_host_alloc(&oakscsi_template, sizeof(struct NCR5380_hostdata)); |
143 | if (!host) { | ||
144 | ret = -ENOMEM; | ||
145 | goto release; | ||
146 | } | ||
147 | |||
148 | priv(host)->base = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC), | ||
149 | ecard_resource_len(ec, ECARD_RES_MEMC)); | ||
150 | if (!priv(host)->base) { | ||
151 | ret = -ENOMEM; | ||
152 | goto unreg; | ||
153 | } | ||
154 | |||
140 | host->irq = IRQ_NONE; | 155 | host->irq = IRQ_NONE; |
141 | host->n_io_port = 255; | 156 | host->n_io_port = 255; |
142 | 157 | ||
143 | ret = -EBUSY; | ||
144 | if (!request_region (host->io_port, host->n_io_port, "Oak SCSI")) | ||
145 | goto unreg; | ||
146 | |||
147 | NCR5380_init(host, 0); | 158 | NCR5380_init(host, 0); |
148 | 159 | ||
149 | printk("scsi%d: at port 0x%08lx irqs disabled", | 160 | printk("scsi%d: at port 0x%08lx irqs disabled", |
@@ -156,15 +167,17 @@ oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id) | |||
156 | 167 | ||
157 | ret = scsi_add_host(host, &ec->dev); | 168 | ret = scsi_add_host(host, &ec->dev); |
158 | if (ret) | 169 | if (ret) |
159 | goto out_release; | 170 | goto out_unmap; |
160 | 171 | ||
161 | scsi_scan_host(host); | 172 | scsi_scan_host(host); |
162 | goto out; | 173 | goto out; |
163 | 174 | ||
164 | out_release: | 175 | out_unmap: |
165 | release_region(host->io_port, host->n_io_port); | 176 | iounmap(priv(host)->base); |
166 | unreg: | 177 | unreg: |
167 | scsi_host_put(host); | 178 | scsi_host_put(host); |
179 | release: | ||
180 | ecard_release_resources(ec); | ||
168 | out: | 181 | out: |
169 | return ret; | 182 | return ret; |
170 | } | 183 | } |
@@ -177,8 +190,9 @@ static void __devexit oakscsi_remove(struct expansion_card *ec) | |||
177 | scsi_remove_host(host); | 190 | scsi_remove_host(host); |
178 | 191 | ||
179 | NCR5380_exit(host); | 192 | NCR5380_exit(host); |
180 | release_region(host->io_port, host->n_io_port); | 193 | iounmap(priv(host)->base); |
181 | scsi_host_put(host); | 194 | scsi_host_put(host); |
195 | ecard_release_resources(ec); | ||
182 | } | 196 | } |
183 | 197 | ||
184 | static const struct ecard_id oakscsi_cids[] = { | 198 | static const struct ecard_id oakscsi_cids[] = { |
diff --git a/drivers/scsi/bvme6000_scsi.c b/drivers/scsi/bvme6000_scsi.c index 012cdea7946d..cac354086737 100644 --- a/drivers/scsi/bvme6000_scsi.c +++ b/drivers/scsi/bvme6000_scsi.c | |||
@@ -74,6 +74,7 @@ bvme6000_probe(struct device *dev) | |||
74 | goto out_put_host; | 74 | goto out_put_host; |
75 | } | 75 | } |
76 | 76 | ||
77 | dev_set_drvdata(dev, host); | ||
77 | scsi_scan_host(host); | 78 | scsi_scan_host(host); |
78 | 79 | ||
79 | return 0; | 80 | return 0; |
@@ -89,7 +90,7 @@ bvme6000_probe(struct device *dev) | |||
89 | static __devexit int | 90 | static __devexit int |
90 | bvme6000_device_remove(struct device *dev) | 91 | bvme6000_device_remove(struct device *dev) |
91 | { | 92 | { |
92 | struct Scsi_Host *host = dev_to_shost(dev); | 93 | struct Scsi_Host *host = dev_get_drvdata(dev); |
93 | struct NCR_700_Host_Parameters *hostdata = shost_priv(host); | 94 | struct NCR_700_Host_Parameters *hostdata = shost_priv(host); |
94 | 95 | ||
95 | scsi_remove_host(host); | 96 | scsi_remove_host(host); |
diff --git a/drivers/scsi/esp_scsi.h b/drivers/scsi/esp_scsi.h index d5576d54ce76..856e38b14861 100644 --- a/drivers/scsi/esp_scsi.h +++ b/drivers/scsi/esp_scsi.h | |||
@@ -220,7 +220,7 @@ | |||
220 | #define ESP_BUSID_RESELID 0x10 | 220 | #define ESP_BUSID_RESELID 0x10 |
221 | #define ESP_BUSID_CTR32BIT 0x40 | 221 | #define ESP_BUSID_CTR32BIT 0x40 |
222 | 222 | ||
223 | #define ESP_BUS_TIMEOUT 250 /* In milli-seconds */ | 223 | #define ESP_BUS_TIMEOUT 275 /* In milli-seconds */ |
224 | #define ESP_TIMEO_CONST 8192 | 224 | #define ESP_TIMEO_CONST 8192 |
225 | #define ESP_NEG_DEFP(mhz, cfact) \ | 225 | #define ESP_NEG_DEFP(mhz, cfact) \ |
226 | ((ESP_BUS_TIMEOUT * ((mhz) / 1000)) / (8192 * (cfact))) | 226 | ((ESP_BUS_TIMEOUT * ((mhz) / 1000)) / (8192 * (cfact))) |
diff --git a/drivers/scsi/libsas/Kconfig b/drivers/scsi/libsas/Kconfig index aafdc92f8312..3a3c1ac9c6cd 100644 --- a/drivers/scsi/libsas/Kconfig +++ b/drivers/scsi/libsas/Kconfig | |||
@@ -30,6 +30,13 @@ config SCSI_SAS_LIBSAS | |||
30 | This provides transport specific helpers for SAS drivers which | 30 | This provides transport specific helpers for SAS drivers which |
31 | use the domain device construct (like the aic94xxx). | 31 | use the domain device construct (like the aic94xxx). |
32 | 32 | ||
33 | config SCSI_SAS_ATA | ||
34 | bool "ATA support for libsas (requires libata)" | ||
35 | depends on SCSI_SAS_LIBSAS && ATA | ||
36 | help | ||
37 | Builds in ATA support into libsas. Will necessitate | ||
38 | the loading of libata along with libsas. | ||
39 | |||
33 | config SCSI_SAS_LIBSAS_DEBUG | 40 | config SCSI_SAS_LIBSAS_DEBUG |
34 | bool "Compile the SAS Domain Transport Attributes in debug mode" | 41 | bool "Compile the SAS Domain Transport Attributes in debug mode" |
35 | default y | 42 | default y |
diff --git a/drivers/scsi/libsas/Makefile b/drivers/scsi/libsas/Makefile index 44d972a3b4bd..fd387b91856e 100644 --- a/drivers/scsi/libsas/Makefile +++ b/drivers/scsi/libsas/Makefile | |||
@@ -34,3 +34,4 @@ libsas-y += sas_init.o \ | |||
34 | sas_discover.o \ | 34 | sas_discover.o \ |
35 | sas_expander.o \ | 35 | sas_expander.o \ |
36 | sas_scsi_host.o | 36 | sas_scsi_host.o |
37 | libsas-$(CONFIG_SCSI_SAS_ATA) += sas_ata.o | ||
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c new file mode 100644 index 000000000000..ced2de32c511 --- /dev/null +++ b/drivers/scsi/libsas/sas_ata.c | |||
@@ -0,0 +1,817 @@ | |||
1 | /* | ||
2 | * Support for SATA devices on Serial Attached SCSI (SAS) controllers | ||
3 | * | ||
4 | * Copyright (C) 2006 IBM Corporation | ||
5 | * | ||
6 | * Written by: Darrick J. Wong <djwong@us.ibm.com>, IBM Corporation | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License as | ||
10 | * published by the Free Software Foundation; either version 2 of the | ||
11 | * License, or (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * 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, MA 02111-1307 | ||
21 | * USA | ||
22 | */ | ||
23 | |||
24 | #include <linux/scatterlist.h> | ||
25 | |||
26 | #include <scsi/sas_ata.h> | ||
27 | #include "sas_internal.h" | ||
28 | #include <scsi/scsi_host.h> | ||
29 | #include <scsi/scsi_device.h> | ||
30 | #include <scsi/scsi_tcq.h> | ||
31 | #include <scsi/scsi.h> | ||
32 | #include <scsi/scsi_transport.h> | ||
33 | #include <scsi/scsi_transport_sas.h> | ||
34 | #include "../scsi_sas_internal.h" | ||
35 | #include "../scsi_transport_api.h" | ||
36 | #include <scsi/scsi_eh.h> | ||
37 | |||
38 | static enum ata_completion_errors sas_to_ata_err(struct task_status_struct *ts) | ||
39 | { | ||
40 | /* Cheesy attempt to translate SAS errors into ATA. Hah! */ | ||
41 | |||
42 | /* transport error */ | ||
43 | if (ts->resp == SAS_TASK_UNDELIVERED) | ||
44 | return AC_ERR_ATA_BUS; | ||
45 | |||
46 | /* ts->resp == SAS_TASK_COMPLETE */ | ||
47 | /* task delivered, what happened afterwards? */ | ||
48 | switch (ts->stat) { | ||
49 | case SAS_DEV_NO_RESPONSE: | ||
50 | return AC_ERR_TIMEOUT; | ||
51 | |||
52 | case SAS_INTERRUPTED: | ||
53 | case SAS_PHY_DOWN: | ||
54 | case SAS_NAK_R_ERR: | ||
55 | return AC_ERR_ATA_BUS; | ||
56 | |||
57 | |||
58 | case SAS_DATA_UNDERRUN: | ||
59 | /* | ||
60 | * Some programs that use the taskfile interface | ||
61 | * (smartctl in particular) can cause underrun | ||
62 | * problems. Ignore these errors, perhaps at our | ||
63 | * peril. | ||
64 | */ | ||
65 | return 0; | ||
66 | |||
67 | case SAS_DATA_OVERRUN: | ||
68 | case SAS_QUEUE_FULL: | ||
69 | case SAS_DEVICE_UNKNOWN: | ||
70 | case SAS_SG_ERR: | ||
71 | return AC_ERR_INVALID; | ||
72 | |||
73 | case SAM_CHECK_COND: | ||
74 | case SAS_OPEN_TO: | ||
75 | case SAS_OPEN_REJECT: | ||
76 | SAS_DPRINTK("%s: Saw error %d. What to do?\n", | ||
77 | __FUNCTION__, ts->stat); | ||
78 | return AC_ERR_OTHER; | ||
79 | |||
80 | case SAS_ABORTED_TASK: | ||
81 | return AC_ERR_DEV; | ||
82 | |||
83 | case SAS_PROTO_RESPONSE: | ||
84 | /* This means the ending_fis has the error | ||
85 | * value; return 0 here to collect it */ | ||
86 | return 0; | ||
87 | default: | ||
88 | return 0; | ||
89 | } | ||
90 | } | ||
91 | |||
92 | static void sas_ata_task_done(struct sas_task *task) | ||
93 | { | ||
94 | struct ata_queued_cmd *qc = task->uldd_task; | ||
95 | struct domain_device *dev; | ||
96 | struct task_status_struct *stat = &task->task_status; | ||
97 | struct ata_task_resp *resp = (struct ata_task_resp *)stat->buf; | ||
98 | struct sas_ha_struct *sas_ha; | ||
99 | enum ata_completion_errors ac; | ||
100 | unsigned long flags; | ||
101 | |||
102 | if (!qc) | ||
103 | goto qc_already_gone; | ||
104 | |||
105 | dev = qc->ap->private_data; | ||
106 | sas_ha = dev->port->ha; | ||
107 | |||
108 | spin_lock_irqsave(dev->sata_dev.ap->lock, flags); | ||
109 | if (stat->stat == SAS_PROTO_RESPONSE || stat->stat == SAM_GOOD) { | ||
110 | ata_tf_from_fis(resp->ending_fis, &dev->sata_dev.tf); | ||
111 | qc->err_mask |= ac_err_mask(dev->sata_dev.tf.command); | ||
112 | dev->sata_dev.sstatus = resp->sstatus; | ||
113 | dev->sata_dev.serror = resp->serror; | ||
114 | dev->sata_dev.scontrol = resp->scontrol; | ||
115 | } else if (stat->stat != SAM_STAT_GOOD) { | ||
116 | ac = sas_to_ata_err(stat); | ||
117 | if (ac) { | ||
118 | SAS_DPRINTK("%s: SAS error %x\n", __FUNCTION__, | ||
119 | stat->stat); | ||
120 | /* We saw a SAS error. Send a vague error. */ | ||
121 | qc->err_mask = ac; | ||
122 | dev->sata_dev.tf.feature = 0x04; /* status err */ | ||
123 | dev->sata_dev.tf.command = ATA_ERR; | ||
124 | } | ||
125 | } | ||
126 | |||
127 | qc->lldd_task = NULL; | ||
128 | if (qc->scsicmd) | ||
129 | ASSIGN_SAS_TASK(qc->scsicmd, NULL); | ||
130 | ata_qc_complete(qc); | ||
131 | spin_unlock_irqrestore(dev->sata_dev.ap->lock, flags); | ||
132 | |||
133 | /* | ||
134 | * If the sas_task has an ata qc, a scsi_cmnd and the aborted | ||
135 | * flag is set, then we must have come in via the libsas EH | ||
136 | * functions. When we exit this function, we need to put the | ||
137 | * scsi_cmnd on the list of finished errors. The ata_qc_complete | ||
138 | * call cleans up the libata side of things but we're protected | ||
139 | * from the scsi_cmnd going away because the scsi_cmnd is owned | ||
140 | * by the EH, making libata's call to scsi_done a NOP. | ||
141 | */ | ||
142 | spin_lock_irqsave(&task->task_state_lock, flags); | ||
143 | if (qc->scsicmd && task->task_state_flags & SAS_TASK_STATE_ABORTED) | ||
144 | scsi_eh_finish_cmd(qc->scsicmd, &sas_ha->eh_done_q); | ||
145 | spin_unlock_irqrestore(&task->task_state_lock, flags); | ||
146 | |||
147 | qc_already_gone: | ||
148 | list_del_init(&task->list); | ||
149 | sas_free_task(task); | ||
150 | } | ||
151 | |||
152 | static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc) | ||
153 | { | ||
154 | int res; | ||
155 | struct sas_task *task; | ||
156 | struct domain_device *dev = qc->ap->private_data; | ||
157 | struct sas_ha_struct *sas_ha = dev->port->ha; | ||
158 | struct Scsi_Host *host = sas_ha->core.shost; | ||
159 | struct sas_internal *i = to_sas_internal(host->transportt); | ||
160 | struct scatterlist *sg; | ||
161 | unsigned int num = 0; | ||
162 | unsigned int xfer = 0; | ||
163 | |||
164 | task = sas_alloc_task(GFP_ATOMIC); | ||
165 | if (!task) | ||
166 | return AC_ERR_SYSTEM; | ||
167 | task->dev = dev; | ||
168 | task->task_proto = SAS_PROTOCOL_STP; | ||
169 | task->task_done = sas_ata_task_done; | ||
170 | |||
171 | if (qc->tf.command == ATA_CMD_FPDMA_WRITE || | ||
172 | qc->tf.command == ATA_CMD_FPDMA_READ) { | ||
173 | /* Need to zero out the tag libata assigned us */ | ||
174 | qc->tf.nsect = 0; | ||
175 | } | ||
176 | |||
177 | ata_tf_to_fis(&qc->tf, 1, 0, (u8*)&task->ata_task.fis); | ||
178 | task->uldd_task = qc; | ||
179 | if (is_atapi_taskfile(&qc->tf)) { | ||
180 | memcpy(task->ata_task.atapi_packet, qc->cdb, qc->dev->cdb_len); | ||
181 | task->total_xfer_len = qc->nbytes + qc->pad_len; | ||
182 | task->num_scatter = qc->pad_len ? qc->n_elem + 1 : qc->n_elem; | ||
183 | } else { | ||
184 | ata_for_each_sg(sg, qc) { | ||
185 | num++; | ||
186 | xfer += sg->length; | ||
187 | } | ||
188 | |||
189 | task->total_xfer_len = xfer; | ||
190 | task->num_scatter = num; | ||
191 | } | ||
192 | |||
193 | task->data_dir = qc->dma_dir; | ||
194 | task->scatter = qc->__sg; | ||
195 | task->ata_task.retry_count = 1; | ||
196 | task->task_state_flags = SAS_TASK_STATE_PENDING; | ||
197 | qc->lldd_task = task; | ||
198 | |||
199 | switch (qc->tf.protocol) { | ||
200 | case ATA_PROT_NCQ: | ||
201 | task->ata_task.use_ncq = 1; | ||
202 | /* fall through */ | ||
203 | case ATA_PROT_ATAPI_DMA: | ||
204 | case ATA_PROT_DMA: | ||
205 | task->ata_task.dma_xfer = 1; | ||
206 | break; | ||
207 | } | ||
208 | |||
209 | if (qc->scsicmd) | ||
210 | ASSIGN_SAS_TASK(qc->scsicmd, task); | ||
211 | |||
212 | if (sas_ha->lldd_max_execute_num < 2) | ||
213 | res = i->dft->lldd_execute_task(task, 1, GFP_ATOMIC); | ||
214 | else | ||
215 | res = sas_queue_up(task); | ||
216 | |||
217 | /* Examine */ | ||
218 | if (res) { | ||
219 | SAS_DPRINTK("lldd_execute_task returned: %d\n", res); | ||
220 | |||
221 | if (qc->scsicmd) | ||
222 | ASSIGN_SAS_TASK(qc->scsicmd, NULL); | ||
223 | sas_free_task(task); | ||
224 | return AC_ERR_SYSTEM; | ||
225 | } | ||
226 | |||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | static u8 sas_ata_check_status(struct ata_port *ap) | ||
231 | { | ||
232 | struct domain_device *dev = ap->private_data; | ||
233 | return dev->sata_dev.tf.command; | ||
234 | } | ||
235 | |||
236 | static void sas_ata_phy_reset(struct ata_port *ap) | ||
237 | { | ||
238 | struct domain_device *dev = ap->private_data; | ||
239 | struct sas_internal *i = | ||
240 | to_sas_internal(dev->port->ha->core.shost->transportt); | ||
241 | int res = 0; | ||
242 | |||
243 | if (i->dft->lldd_I_T_nexus_reset) | ||
244 | res = i->dft->lldd_I_T_nexus_reset(dev); | ||
245 | |||
246 | if (res) | ||
247 | SAS_DPRINTK("%s: Unable to reset I T nexus?\n", __FUNCTION__); | ||
248 | |||
249 | switch (dev->sata_dev.command_set) { | ||
250 | case ATA_COMMAND_SET: | ||
251 | SAS_DPRINTK("%s: Found ATA device.\n", __FUNCTION__); | ||
252 | ap->device[0].class = ATA_DEV_ATA; | ||
253 | break; | ||
254 | case ATAPI_COMMAND_SET: | ||
255 | SAS_DPRINTK("%s: Found ATAPI device.\n", __FUNCTION__); | ||
256 | ap->device[0].class = ATA_DEV_ATAPI; | ||
257 | break; | ||
258 | default: | ||
259 | SAS_DPRINTK("%s: Unknown SATA command set: %d.\n", | ||
260 | __FUNCTION__, | ||
261 | dev->sata_dev.command_set); | ||
262 | ap->device[0].class = ATA_DEV_UNKNOWN; | ||
263 | break; | ||
264 | } | ||
265 | |||
266 | ap->cbl = ATA_CBL_SATA; | ||
267 | } | ||
268 | |||
269 | static void sas_ata_post_internal(struct ata_queued_cmd *qc) | ||
270 | { | ||
271 | if (qc->flags & ATA_QCFLAG_FAILED) | ||
272 | qc->err_mask |= AC_ERR_OTHER; | ||
273 | |||
274 | if (qc->err_mask) { | ||
275 | /* | ||
276 | * Find the sas_task and kill it. By this point, | ||
277 | * libata has decided to kill the qc, so we needn't | ||
278 | * bother with sas_ata_task_done. But we still | ||
279 | * ought to abort the task. | ||
280 | */ | ||
281 | struct sas_task *task = qc->lldd_task; | ||
282 | unsigned long flags; | ||
283 | |||
284 | qc->lldd_task = NULL; | ||
285 | if (task) { | ||
286 | /* Should this be a AT(API) device reset? */ | ||
287 | spin_lock_irqsave(&task->task_state_lock, flags); | ||
288 | task->task_state_flags |= SAS_TASK_NEED_DEV_RESET; | ||
289 | spin_unlock_irqrestore(&task->task_state_lock, flags); | ||
290 | |||
291 | task->uldd_task = NULL; | ||
292 | __sas_task_abort(task); | ||
293 | } | ||
294 | } | ||
295 | } | ||
296 | |||
297 | static void sas_ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) | ||
298 | { | ||
299 | struct domain_device *dev = ap->private_data; | ||
300 | memcpy(tf, &dev->sata_dev.tf, sizeof (*tf)); | ||
301 | } | ||
302 | |||
303 | static int sas_ata_scr_write(struct ata_port *ap, unsigned int sc_reg_in, | ||
304 | u32 val) | ||
305 | { | ||
306 | struct domain_device *dev = ap->private_data; | ||
307 | |||
308 | SAS_DPRINTK("STUB %s\n", __FUNCTION__); | ||
309 | switch (sc_reg_in) { | ||
310 | case SCR_STATUS: | ||
311 | dev->sata_dev.sstatus = val; | ||
312 | break; | ||
313 | case SCR_CONTROL: | ||
314 | dev->sata_dev.scontrol = val; | ||
315 | break; | ||
316 | case SCR_ERROR: | ||
317 | dev->sata_dev.serror = val; | ||
318 | break; | ||
319 | case SCR_ACTIVE: | ||
320 | dev->sata_dev.ap->sactive = val; | ||
321 | break; | ||
322 | default: | ||
323 | return -EINVAL; | ||
324 | } | ||
325 | return 0; | ||
326 | } | ||
327 | |||
328 | static int sas_ata_scr_read(struct ata_port *ap, unsigned int sc_reg_in, | ||
329 | u32 *val) | ||
330 | { | ||
331 | struct domain_device *dev = ap->private_data; | ||
332 | |||
333 | SAS_DPRINTK("STUB %s\n", __FUNCTION__); | ||
334 | switch (sc_reg_in) { | ||
335 | case SCR_STATUS: | ||
336 | *val = dev->sata_dev.sstatus; | ||
337 | return 0; | ||
338 | case SCR_CONTROL: | ||
339 | *val = dev->sata_dev.scontrol; | ||
340 | return 0; | ||
341 | case SCR_ERROR: | ||
342 | *val = dev->sata_dev.serror; | ||
343 | return 0; | ||
344 | case SCR_ACTIVE: | ||
345 | *val = dev->sata_dev.ap->sactive; | ||
346 | return 0; | ||
347 | default: | ||
348 | return -EINVAL; | ||
349 | } | ||
350 | } | ||
351 | |||
352 | static struct ata_port_operations sas_sata_ops = { | ||
353 | .port_disable = ata_port_disable, | ||
354 | .check_status = sas_ata_check_status, | ||
355 | .check_altstatus = sas_ata_check_status, | ||
356 | .dev_select = ata_noop_dev_select, | ||
357 | .phy_reset = sas_ata_phy_reset, | ||
358 | .post_internal_cmd = sas_ata_post_internal, | ||
359 | .tf_read = sas_ata_tf_read, | ||
360 | .qc_prep = ata_noop_qc_prep, | ||
361 | .qc_issue = sas_ata_qc_issue, | ||
362 | .port_start = ata_sas_port_start, | ||
363 | .port_stop = ata_sas_port_stop, | ||
364 | .scr_read = sas_ata_scr_read, | ||
365 | .scr_write = sas_ata_scr_write | ||
366 | }; | ||
367 | |||
368 | static struct ata_port_info sata_port_info = { | ||
369 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_SATA_RESET | | ||
370 | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | ATA_FLAG_NCQ, | ||
371 | .pio_mask = 0x1f, /* PIO0-4 */ | ||
372 | .mwdma_mask = 0x07, /* MWDMA0-2 */ | ||
373 | .udma_mask = ATA_UDMA6, | ||
374 | .port_ops = &sas_sata_ops | ||
375 | }; | ||
376 | |||
377 | int sas_ata_init_host_and_port(struct domain_device *found_dev, | ||
378 | struct scsi_target *starget) | ||
379 | { | ||
380 | struct Scsi_Host *shost = dev_to_shost(&starget->dev); | ||
381 | struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost); | ||
382 | struct ata_port *ap; | ||
383 | |||
384 | ata_host_init(&found_dev->sata_dev.ata_host, | ||
385 | &ha->pcidev->dev, | ||
386 | sata_port_info.flags, | ||
387 | &sas_sata_ops); | ||
388 | ap = ata_sas_port_alloc(&found_dev->sata_dev.ata_host, | ||
389 | &sata_port_info, | ||
390 | shost); | ||
391 | if (!ap) { | ||
392 | SAS_DPRINTK("ata_sas_port_alloc failed.\n"); | ||
393 | return -ENODEV; | ||
394 | } | ||
395 | |||
396 | ap->private_data = found_dev; | ||
397 | ap->cbl = ATA_CBL_SATA; | ||
398 | ap->scsi_host = shost; | ||
399 | found_dev->sata_dev.ap = ap; | ||
400 | |||
401 | return 0; | ||
402 | } | ||
403 | |||
404 | void sas_ata_task_abort(struct sas_task *task) | ||
405 | { | ||
406 | struct ata_queued_cmd *qc = task->uldd_task; | ||
407 | struct completion *waiting; | ||
408 | |||
409 | /* Bounce SCSI-initiated commands to the SCSI EH */ | ||
410 | if (qc->scsicmd) { | ||
411 | scsi_req_abort_cmd(qc->scsicmd); | ||
412 | scsi_schedule_eh(qc->scsicmd->device->host); | ||
413 | return; | ||
414 | } | ||
415 | |||
416 | /* Internal command, fake a timeout and complete. */ | ||
417 | qc->flags &= ~ATA_QCFLAG_ACTIVE; | ||
418 | qc->flags |= ATA_QCFLAG_FAILED; | ||
419 | qc->err_mask |= AC_ERR_TIMEOUT; | ||
420 | waiting = qc->private_data; | ||
421 | complete(waiting); | ||
422 | } | ||
423 | |||
424 | static void sas_task_timedout(unsigned long _task) | ||
425 | { | ||
426 | struct sas_task *task = (void *) _task; | ||
427 | unsigned long flags; | ||
428 | |||
429 | spin_lock_irqsave(&task->task_state_lock, flags); | ||
430 | if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) | ||
431 | task->task_state_flags |= SAS_TASK_STATE_ABORTED; | ||
432 | spin_unlock_irqrestore(&task->task_state_lock, flags); | ||
433 | |||
434 | complete(&task->completion); | ||
435 | } | ||
436 | |||
437 | static void sas_disc_task_done(struct sas_task *task) | ||
438 | { | ||
439 | if (!del_timer(&task->timer)) | ||
440 | return; | ||
441 | complete(&task->completion); | ||
442 | } | ||
443 | |||
444 | #define SAS_DEV_TIMEOUT 10 | ||
445 | |||
446 | /** | ||
447 | * sas_execute_task -- Basic task processing for discovery | ||
448 | * @task: the task to be executed | ||
449 | * @buffer: pointer to buffer to do I/O | ||
450 | * @size: size of @buffer | ||
451 | * @pci_dma_dir: PCI_DMA_... | ||
452 | */ | ||
453 | static int sas_execute_task(struct sas_task *task, void *buffer, int size, | ||
454 | int pci_dma_dir) | ||
455 | { | ||
456 | int res = 0; | ||
457 | struct scatterlist *scatter = NULL; | ||
458 | struct task_status_struct *ts = &task->task_status; | ||
459 | int num_scatter = 0; | ||
460 | int retries = 0; | ||
461 | struct sas_internal *i = | ||
462 | to_sas_internal(task->dev->port->ha->core.shost->transportt); | ||
463 | |||
464 | if (pci_dma_dir != PCI_DMA_NONE) { | ||
465 | scatter = kzalloc(sizeof(*scatter), GFP_KERNEL); | ||
466 | if (!scatter) | ||
467 | goto out; | ||
468 | |||
469 | sg_init_one(scatter, buffer, size); | ||
470 | num_scatter = 1; | ||
471 | } | ||
472 | |||
473 | task->task_proto = task->dev->tproto; | ||
474 | task->scatter = scatter; | ||
475 | task->num_scatter = num_scatter; | ||
476 | task->total_xfer_len = size; | ||
477 | task->data_dir = pci_dma_dir; | ||
478 | task->task_done = sas_disc_task_done; | ||
479 | if (pci_dma_dir != PCI_DMA_NONE && | ||
480 | sas_protocol_ata(task->task_proto)) { | ||
481 | task->num_scatter = pci_map_sg(task->dev->port->ha->pcidev, | ||
482 | task->scatter, | ||
483 | task->num_scatter, | ||
484 | task->data_dir); | ||
485 | } | ||
486 | |||
487 | for (retries = 0; retries < 5; retries++) { | ||
488 | task->task_state_flags = SAS_TASK_STATE_PENDING; | ||
489 | init_completion(&task->completion); | ||
490 | |||
491 | task->timer.data = (unsigned long) task; | ||
492 | task->timer.function = sas_task_timedout; | ||
493 | task->timer.expires = jiffies + SAS_DEV_TIMEOUT*HZ; | ||
494 | add_timer(&task->timer); | ||
495 | |||
496 | res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL); | ||
497 | if (res) { | ||
498 | del_timer(&task->timer); | ||
499 | SAS_DPRINTK("executing SAS discovery task failed:%d\n", | ||
500 | res); | ||
501 | goto ex_err; | ||
502 | } | ||
503 | wait_for_completion(&task->completion); | ||
504 | res = -ETASK; | ||
505 | if (task->task_state_flags & SAS_TASK_STATE_ABORTED) { | ||
506 | int res2; | ||
507 | SAS_DPRINTK("task aborted, flags:0x%x\n", | ||
508 | task->task_state_flags); | ||
509 | res2 = i->dft->lldd_abort_task(task); | ||
510 | SAS_DPRINTK("came back from abort task\n"); | ||
511 | if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { | ||
512 | if (res2 == TMF_RESP_FUNC_COMPLETE) | ||
513 | continue; /* Retry the task */ | ||
514 | else | ||
515 | goto ex_err; | ||
516 | } | ||
517 | } | ||
518 | if (task->task_status.stat == SAM_BUSY || | ||
519 | task->task_status.stat == SAM_TASK_SET_FULL || | ||
520 | task->task_status.stat == SAS_QUEUE_FULL) { | ||
521 | SAS_DPRINTK("task: q busy, sleeping...\n"); | ||
522 | schedule_timeout_interruptible(HZ); | ||
523 | } else if (task->task_status.stat == SAM_CHECK_COND) { | ||
524 | struct scsi_sense_hdr shdr; | ||
525 | |||
526 | if (!scsi_normalize_sense(ts->buf, ts->buf_valid_size, | ||
527 | &shdr)) { | ||
528 | SAS_DPRINTK("couldn't normalize sense\n"); | ||
529 | continue; | ||
530 | } | ||
531 | if ((shdr.sense_key == 6 && shdr.asc == 0x29) || | ||
532 | (shdr.sense_key == 2 && shdr.asc == 4 && | ||
533 | shdr.ascq == 1)) { | ||
534 | SAS_DPRINTK("device %016llx LUN: %016llx " | ||
535 | "powering up or not ready yet, " | ||
536 | "sleeping...\n", | ||
537 | SAS_ADDR(task->dev->sas_addr), | ||
538 | SAS_ADDR(task->ssp_task.LUN)); | ||
539 | |||
540 | schedule_timeout_interruptible(5*HZ); | ||
541 | } else if (shdr.sense_key == 1) { | ||
542 | res = 0; | ||
543 | break; | ||
544 | } else if (shdr.sense_key == 5) { | ||
545 | break; | ||
546 | } else { | ||
547 | SAS_DPRINTK("dev %016llx LUN: %016llx " | ||
548 | "sense key:0x%x ASC:0x%x ASCQ:0x%x" | ||
549 | "\n", | ||
550 | SAS_ADDR(task->dev->sas_addr), | ||
551 | SAS_ADDR(task->ssp_task.LUN), | ||
552 | shdr.sense_key, | ||
553 | shdr.asc, shdr.ascq); | ||
554 | } | ||
555 | } else if (task->task_status.resp != SAS_TASK_COMPLETE || | ||
556 | task->task_status.stat != SAM_GOOD) { | ||
557 | SAS_DPRINTK("task finished with resp:0x%x, " | ||
558 | "stat:0x%x\n", | ||
559 | task->task_status.resp, | ||
560 | task->task_status.stat); | ||
561 | goto ex_err; | ||
562 | } else { | ||
563 | res = 0; | ||
564 | break; | ||
565 | } | ||
566 | } | ||
567 | ex_err: | ||
568 | if (pci_dma_dir != PCI_DMA_NONE) { | ||
569 | if (sas_protocol_ata(task->task_proto)) | ||
570 | pci_unmap_sg(task->dev->port->ha->pcidev, | ||
571 | task->scatter, task->num_scatter, | ||
572 | task->data_dir); | ||
573 | kfree(scatter); | ||
574 | } | ||
575 | out: | ||
576 | return res; | ||
577 | } | ||
578 | |||
579 | /* ---------- SATA ---------- */ | ||
580 | |||
581 | static void sas_get_ata_command_set(struct domain_device *dev) | ||
582 | { | ||
583 | struct dev_to_host_fis *fis = | ||
584 | (struct dev_to_host_fis *) dev->frame_rcvd; | ||
585 | |||
586 | if ((fis->sector_count == 1 && /* ATA */ | ||
587 | fis->lbal == 1 && | ||
588 | fis->lbam == 0 && | ||
589 | fis->lbah == 0 && | ||
590 | fis->device == 0) | ||
591 | || | ||
592 | (fis->sector_count == 0 && /* CE-ATA (mATA) */ | ||
593 | fis->lbal == 0 && | ||
594 | fis->lbam == 0xCE && | ||
595 | fis->lbah == 0xAA && | ||
596 | (fis->device & ~0x10) == 0)) | ||
597 | |||
598 | dev->sata_dev.command_set = ATA_COMMAND_SET; | ||
599 | |||
600 | else if ((fis->interrupt_reason == 1 && /* ATAPI */ | ||
601 | fis->lbal == 1 && | ||
602 | fis->byte_count_low == 0x14 && | ||
603 | fis->byte_count_high == 0xEB && | ||
604 | (fis->device & ~0x10) == 0)) | ||
605 | |||
606 | dev->sata_dev.command_set = ATAPI_COMMAND_SET; | ||
607 | |||
608 | else if ((fis->sector_count == 1 && /* SEMB */ | ||
609 | fis->lbal == 1 && | ||
610 | fis->lbam == 0x3C && | ||
611 | fis->lbah == 0xC3 && | ||
612 | fis->device == 0) | ||
613 | || | ||
614 | (fis->interrupt_reason == 1 && /* SATA PM */ | ||
615 | fis->lbal == 1 && | ||
616 | fis->byte_count_low == 0x69 && | ||
617 | fis->byte_count_high == 0x96 && | ||
618 | (fis->device & ~0x10) == 0)) | ||
619 | |||
620 | /* Treat it as a superset? */ | ||
621 | dev->sata_dev.command_set = ATAPI_COMMAND_SET; | ||
622 | } | ||
623 | |||
624 | /** | ||
625 | * sas_issue_ata_cmd -- Basic SATA command processing for discovery | ||
626 | * @dev: the device to send the command to | ||
627 | * @command: the command register | ||
628 | * @features: the features register | ||
629 | * @buffer: pointer to buffer to do I/O | ||
630 | * @size: size of @buffer | ||
631 | * @pci_dma_dir: PCI_DMA_... | ||
632 | */ | ||
633 | static int sas_issue_ata_cmd(struct domain_device *dev, u8 command, | ||
634 | u8 features, void *buffer, int size, | ||
635 | int pci_dma_dir) | ||
636 | { | ||
637 | int res = 0; | ||
638 | struct sas_task *task; | ||
639 | struct dev_to_host_fis *d2h_fis = (struct dev_to_host_fis *) | ||
640 | &dev->frame_rcvd[0]; | ||
641 | |||
642 | res = -ENOMEM; | ||
643 | task = sas_alloc_task(GFP_KERNEL); | ||
644 | if (!task) | ||
645 | goto out; | ||
646 | |||
647 | task->dev = dev; | ||
648 | |||
649 | task->ata_task.fis.fis_type = 0x27; | ||
650 | task->ata_task.fis.command = command; | ||
651 | task->ata_task.fis.features = features; | ||
652 | task->ata_task.fis.device = d2h_fis->device; | ||
653 | task->ata_task.retry_count = 1; | ||
654 | |||
655 | res = sas_execute_task(task, buffer, size, pci_dma_dir); | ||
656 | |||
657 | sas_free_task(task); | ||
658 | out: | ||
659 | return res; | ||
660 | } | ||
661 | |||
662 | static void sas_sata_propagate_sas_addr(struct domain_device *dev) | ||
663 | { | ||
664 | unsigned long flags; | ||
665 | struct asd_sas_port *port = dev->port; | ||
666 | struct asd_sas_phy *phy; | ||
667 | |||
668 | BUG_ON(dev->parent); | ||
669 | |||
670 | memcpy(port->attached_sas_addr, dev->sas_addr, SAS_ADDR_SIZE); | ||
671 | spin_lock_irqsave(&port->phy_list_lock, flags); | ||
672 | list_for_each_entry(phy, &port->phy_list, port_phy_el) | ||
673 | memcpy(phy->attached_sas_addr, dev->sas_addr, SAS_ADDR_SIZE); | ||
674 | spin_unlock_irqrestore(&port->phy_list_lock, flags); | ||
675 | } | ||
676 | |||
677 | #define ATA_IDENTIFY_DEV 0xEC | ||
678 | #define ATA_IDENTIFY_PACKET_DEV 0xA1 | ||
679 | #define ATA_SET_FEATURES 0xEF | ||
680 | #define ATA_FEATURE_PUP_STBY_SPIN_UP 0x07 | ||
681 | |||
682 | /** | ||
683 | * sas_discover_sata_dev -- discover a STP/SATA device (SATA_DEV) | ||
684 | * @dev: STP/SATA device of interest (ATA/ATAPI) | ||
685 | * | ||
686 | * The LLDD has already been notified of this device, so that we can | ||
687 | * send FISes to it. Here we try to get IDENTIFY DEVICE or IDENTIFY | ||
688 | * PACKET DEVICE, if ATAPI device, so that the LLDD can fine-tune its | ||
689 | * performance for this device. | ||
690 | */ | ||
691 | static int sas_discover_sata_dev(struct domain_device *dev) | ||
692 | { | ||
693 | int res; | ||
694 | __le16 *identify_x; | ||
695 | u8 command; | ||
696 | |||
697 | identify_x = kzalloc(512, GFP_KERNEL); | ||
698 | if (!identify_x) | ||
699 | return -ENOMEM; | ||
700 | |||
701 | if (dev->sata_dev.command_set == ATA_COMMAND_SET) { | ||
702 | dev->sata_dev.identify_device = identify_x; | ||
703 | command = ATA_IDENTIFY_DEV; | ||
704 | } else { | ||
705 | dev->sata_dev.identify_packet_device = identify_x; | ||
706 | command = ATA_IDENTIFY_PACKET_DEV; | ||
707 | } | ||
708 | |||
709 | res = sas_issue_ata_cmd(dev, command, 0, identify_x, 512, | ||
710 | PCI_DMA_FROMDEVICE); | ||
711 | if (res) | ||
712 | goto out_err; | ||
713 | |||
714 | /* lives on the media? */ | ||
715 | if (le16_to_cpu(identify_x[0]) & 4) { | ||
716 | /* incomplete response */ | ||
717 | SAS_DPRINTK("sending SET FEATURE/PUP_STBY_SPIN_UP to " | ||
718 | "dev %llx\n", SAS_ADDR(dev->sas_addr)); | ||
719 | if (!le16_to_cpu(identify_x[83] & (1<<6))) | ||
720 | goto cont1; | ||
721 | res = sas_issue_ata_cmd(dev, ATA_SET_FEATURES, | ||
722 | ATA_FEATURE_PUP_STBY_SPIN_UP, | ||
723 | NULL, 0, PCI_DMA_NONE); | ||
724 | if (res) | ||
725 | goto cont1; | ||
726 | |||
727 | schedule_timeout_interruptible(5*HZ); /* More time? */ | ||
728 | res = sas_issue_ata_cmd(dev, command, 0, identify_x, 512, | ||
729 | PCI_DMA_FROMDEVICE); | ||
730 | if (res) | ||
731 | goto out_err; | ||
732 | } | ||
733 | cont1: | ||
734 | /* Get WWN */ | ||
735 | if (dev->port->oob_mode != SATA_OOB_MODE) { | ||
736 | memcpy(dev->sas_addr, dev->sata_dev.rps_resp.rps.stp_sas_addr, | ||
737 | SAS_ADDR_SIZE); | ||
738 | } else if (dev->sata_dev.command_set == ATA_COMMAND_SET && | ||
739 | (le16_to_cpu(dev->sata_dev.identify_device[108]) & 0xF000) | ||
740 | == 0x5000) { | ||
741 | int i; | ||
742 | |||
743 | for (i = 0; i < 4; i++) { | ||
744 | dev->sas_addr[2*i] = | ||
745 | (le16_to_cpu(dev->sata_dev.identify_device[108+i]) & 0xFF00) >> 8; | ||
746 | dev->sas_addr[2*i+1] = | ||
747 | le16_to_cpu(dev->sata_dev.identify_device[108+i]) & 0x00FF; | ||
748 | } | ||
749 | } | ||
750 | sas_hash_addr(dev->hashed_sas_addr, dev->sas_addr); | ||
751 | if (!dev->parent) | ||
752 | sas_sata_propagate_sas_addr(dev); | ||
753 | |||
754 | /* XXX Hint: register this SATA device with SATL. | ||
755 | When this returns, dev->sata_dev->lu is alive and | ||
756 | present. | ||
757 | sas_satl_register_dev(dev); | ||
758 | */ | ||
759 | |||
760 | sas_fill_in_rphy(dev, dev->rphy); | ||
761 | |||
762 | return 0; | ||
763 | out_err: | ||
764 | dev->sata_dev.identify_packet_device = NULL; | ||
765 | dev->sata_dev.identify_device = NULL; | ||
766 | kfree(identify_x); | ||
767 | return res; | ||
768 | } | ||
769 | |||
770 | static int sas_discover_sata_pm(struct domain_device *dev) | ||
771 | { | ||
772 | return -ENODEV; | ||
773 | } | ||
774 | |||
775 | /** | ||
776 | * sas_discover_sata -- discover an STP/SATA domain device | ||
777 | * @dev: pointer to struct domain_device of interest | ||
778 | * | ||
779 | * First we notify the LLDD of this device, so we can send frames to | ||
780 | * it. Then depending on the type of device we call the appropriate | ||
781 | * discover functions. Once device discover is done, we notify the | ||
782 | * LLDD so that it can fine-tune its parameters for the device, by | ||
783 | * removing it and then adding it. That is, the second time around, | ||
784 | * the driver would have certain fields, that it is looking at, set. | ||
785 | * Finally we initialize the kobj so that the device can be added to | ||
786 | * the system at registration time. Devices directly attached to a HA | ||
787 | * port, have no parents. All other devices do, and should have their | ||
788 | * "parent" pointer set appropriately before calling this function. | ||
789 | */ | ||
790 | int sas_discover_sata(struct domain_device *dev) | ||
791 | { | ||
792 | int res; | ||
793 | |||
794 | sas_get_ata_command_set(dev); | ||
795 | |||
796 | res = sas_notify_lldd_dev_found(dev); | ||
797 | if (res) | ||
798 | return res; | ||
799 | |||
800 | switch (dev->dev_type) { | ||
801 | case SATA_DEV: | ||
802 | res = sas_discover_sata_dev(dev); | ||
803 | break; | ||
804 | case SATA_PM: | ||
805 | res = sas_discover_sata_pm(dev); | ||
806 | break; | ||
807 | default: | ||
808 | break; | ||
809 | } | ||
810 | sas_notify_lldd_dev_gone(dev); | ||
811 | if (!res) { | ||
812 | sas_notify_lldd_dev_found(dev); | ||
813 | res = sas_rphy_add(dev->rphy); | ||
814 | } | ||
815 | |||
816 | return res; | ||
817 | } | ||
diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c index a65598b1e536..6ac9f61d006a 100644 --- a/drivers/scsi/libsas/sas_discover.c +++ b/drivers/scsi/libsas/sas_discover.c | |||
@@ -55,149 +55,6 @@ void sas_init_dev(struct domain_device *dev) | |||
55 | } | 55 | } |
56 | } | 56 | } |
57 | 57 | ||
58 | static void sas_task_timedout(unsigned long _task) | ||
59 | { | ||
60 | struct sas_task *task = (void *) _task; | ||
61 | unsigned long flags; | ||
62 | |||
63 | spin_lock_irqsave(&task->task_state_lock, flags); | ||
64 | if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) | ||
65 | task->task_state_flags |= SAS_TASK_STATE_ABORTED; | ||
66 | spin_unlock_irqrestore(&task->task_state_lock, flags); | ||
67 | |||
68 | complete(&task->completion); | ||
69 | } | ||
70 | |||
71 | static void sas_disc_task_done(struct sas_task *task) | ||
72 | { | ||
73 | if (!del_timer(&task->timer)) | ||
74 | return; | ||
75 | complete(&task->completion); | ||
76 | } | ||
77 | |||
78 | #define SAS_DEV_TIMEOUT 10 | ||
79 | |||
80 | /** | ||
81 | * sas_execute_task -- Basic task processing for discovery | ||
82 | * @task: the task to be executed | ||
83 | * @buffer: pointer to buffer to do I/O | ||
84 | * @size: size of @buffer | ||
85 | * @pci_dma_dir: PCI_DMA_... | ||
86 | */ | ||
87 | static int sas_execute_task(struct sas_task *task, void *buffer, int size, | ||
88 | int pci_dma_dir) | ||
89 | { | ||
90 | int res = 0; | ||
91 | struct scatterlist *scatter = NULL; | ||
92 | struct task_status_struct *ts = &task->task_status; | ||
93 | int num_scatter = 0; | ||
94 | int retries = 0; | ||
95 | struct sas_internal *i = | ||
96 | to_sas_internal(task->dev->port->ha->core.shost->transportt); | ||
97 | |||
98 | if (pci_dma_dir != PCI_DMA_NONE) { | ||
99 | scatter = kzalloc(sizeof(*scatter), GFP_KERNEL); | ||
100 | if (!scatter) | ||
101 | goto out; | ||
102 | |||
103 | sg_init_one(scatter, buffer, size); | ||
104 | num_scatter = 1; | ||
105 | } | ||
106 | |||
107 | task->task_proto = task->dev->tproto; | ||
108 | task->scatter = scatter; | ||
109 | task->num_scatter = num_scatter; | ||
110 | task->total_xfer_len = size; | ||
111 | task->data_dir = pci_dma_dir; | ||
112 | task->task_done = sas_disc_task_done; | ||
113 | |||
114 | for (retries = 0; retries < 5; retries++) { | ||
115 | task->task_state_flags = SAS_TASK_STATE_PENDING; | ||
116 | init_completion(&task->completion); | ||
117 | |||
118 | task->timer.data = (unsigned long) task; | ||
119 | task->timer.function = sas_task_timedout; | ||
120 | task->timer.expires = jiffies + SAS_DEV_TIMEOUT*HZ; | ||
121 | add_timer(&task->timer); | ||
122 | |||
123 | res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL); | ||
124 | if (res) { | ||
125 | del_timer(&task->timer); | ||
126 | SAS_DPRINTK("executing SAS discovery task failed:%d\n", | ||
127 | res); | ||
128 | goto ex_err; | ||
129 | } | ||
130 | wait_for_completion(&task->completion); | ||
131 | res = -ETASK; | ||
132 | if (task->task_state_flags & SAS_TASK_STATE_ABORTED) { | ||
133 | int res2; | ||
134 | SAS_DPRINTK("task aborted, flags:0x%x\n", | ||
135 | task->task_state_flags); | ||
136 | res2 = i->dft->lldd_abort_task(task); | ||
137 | SAS_DPRINTK("came back from abort task\n"); | ||
138 | if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { | ||
139 | if (res2 == TMF_RESP_FUNC_COMPLETE) | ||
140 | continue; /* Retry the task */ | ||
141 | else | ||
142 | goto ex_err; | ||
143 | } | ||
144 | } | ||
145 | if (task->task_status.stat == SAM_BUSY || | ||
146 | task->task_status.stat == SAM_TASK_SET_FULL || | ||
147 | task->task_status.stat == SAS_QUEUE_FULL) { | ||
148 | SAS_DPRINTK("task: q busy, sleeping...\n"); | ||
149 | schedule_timeout_interruptible(HZ); | ||
150 | } else if (task->task_status.stat == SAM_CHECK_COND) { | ||
151 | struct scsi_sense_hdr shdr; | ||
152 | |||
153 | if (!scsi_normalize_sense(ts->buf, ts->buf_valid_size, | ||
154 | &shdr)) { | ||
155 | SAS_DPRINTK("couldn't normalize sense\n"); | ||
156 | continue; | ||
157 | } | ||
158 | if ((shdr.sense_key == 6 && shdr.asc == 0x29) || | ||
159 | (shdr.sense_key == 2 && shdr.asc == 4 && | ||
160 | shdr.ascq == 1)) { | ||
161 | SAS_DPRINTK("device %016llx LUN: %016llx " | ||
162 | "powering up or not ready yet, " | ||
163 | "sleeping...\n", | ||
164 | SAS_ADDR(task->dev->sas_addr), | ||
165 | SAS_ADDR(task->ssp_task.LUN)); | ||
166 | |||
167 | schedule_timeout_interruptible(5*HZ); | ||
168 | } else if (shdr.sense_key == 1) { | ||
169 | res = 0; | ||
170 | break; | ||
171 | } else if (shdr.sense_key == 5) { | ||
172 | break; | ||
173 | } else { | ||
174 | SAS_DPRINTK("dev %016llx LUN: %016llx " | ||
175 | "sense key:0x%x ASC:0x%x ASCQ:0x%x" | ||
176 | "\n", | ||
177 | SAS_ADDR(task->dev->sas_addr), | ||
178 | SAS_ADDR(task->ssp_task.LUN), | ||
179 | shdr.sense_key, | ||
180 | shdr.asc, shdr.ascq); | ||
181 | } | ||
182 | } else if (task->task_status.resp != SAS_TASK_COMPLETE || | ||
183 | task->task_status.stat != SAM_GOOD) { | ||
184 | SAS_DPRINTK("task finished with resp:0x%x, " | ||
185 | "stat:0x%x\n", | ||
186 | task->task_status.resp, | ||
187 | task->task_status.stat); | ||
188 | goto ex_err; | ||
189 | } else { | ||
190 | res = 0; | ||
191 | break; | ||
192 | } | ||
193 | } | ||
194 | ex_err: | ||
195 | if (pci_dma_dir != PCI_DMA_NONE) | ||
196 | kfree(scatter); | ||
197 | out: | ||
198 | return res; | ||
199 | } | ||
200 | |||
201 | /* ---------- Domain device discovery ---------- */ | 58 | /* ---------- Domain device discovery ---------- */ |
202 | 59 | ||
203 | /** | 60 | /** |
@@ -255,6 +112,7 @@ static int sas_get_port_device(struct asd_sas_port *port) | |||
255 | 112 | ||
256 | switch (dev->dev_type) { | 113 | switch (dev->dev_type) { |
257 | case SAS_END_DEV: | 114 | case SAS_END_DEV: |
115 | case SATA_DEV: | ||
258 | rphy = sas_end_device_alloc(port->port); | 116 | rphy = sas_end_device_alloc(port->port); |
259 | break; | 117 | break; |
260 | case EDGE_DEV: | 118 | case EDGE_DEV: |
@@ -265,7 +123,6 @@ static int sas_get_port_device(struct asd_sas_port *port) | |||
265 | rphy = sas_expander_alloc(port->port, | 123 | rphy = sas_expander_alloc(port->port, |
266 | SAS_FANOUT_EXPANDER_DEVICE); | 124 | SAS_FANOUT_EXPANDER_DEVICE); |
267 | break; | 125 | break; |
268 | case SATA_DEV: | ||
269 | default: | 126 | default: |
270 | printk("ERROR: Unidentified device type %d\n", dev->dev_type); | 127 | printk("ERROR: Unidentified device type %d\n", dev->dev_type); |
271 | rphy = NULL; | 128 | rphy = NULL; |
@@ -292,207 +149,15 @@ static int sas_get_port_device(struct asd_sas_port *port) | |||
292 | port->disc.max_level = 0; | 149 | port->disc.max_level = 0; |
293 | 150 | ||
294 | dev->rphy = rphy; | 151 | dev->rphy = rphy; |
295 | spin_lock(&port->dev_list_lock); | 152 | spin_lock_irq(&port->dev_list_lock); |
296 | list_add_tail(&dev->dev_list_node, &port->dev_list); | 153 | list_add_tail(&dev->dev_list_node, &port->dev_list); |
297 | spin_unlock(&port->dev_list_lock); | 154 | spin_unlock_irq(&port->dev_list_lock); |
298 | 155 | ||
299 | return 0; | 156 | return 0; |
300 | } | 157 | } |
301 | 158 | ||
302 | /* ---------- Discover and Revalidate ---------- */ | 159 | /* ---------- Discover and Revalidate ---------- */ |
303 | 160 | ||
304 | /* ---------- SATA ---------- */ | ||
305 | |||
306 | static void sas_get_ata_command_set(struct domain_device *dev) | ||
307 | { | ||
308 | struct dev_to_host_fis *fis = | ||
309 | (struct dev_to_host_fis *) dev->frame_rcvd; | ||
310 | |||
311 | if ((fis->sector_count == 1 && /* ATA */ | ||
312 | fis->lbal == 1 && | ||
313 | fis->lbam == 0 && | ||
314 | fis->lbah == 0 && | ||
315 | fis->device == 0) | ||
316 | || | ||
317 | (fis->sector_count == 0 && /* CE-ATA (mATA) */ | ||
318 | fis->lbal == 0 && | ||
319 | fis->lbam == 0xCE && | ||
320 | fis->lbah == 0xAA && | ||
321 | (fis->device & ~0x10) == 0)) | ||
322 | |||
323 | dev->sata_dev.command_set = ATA_COMMAND_SET; | ||
324 | |||
325 | else if ((fis->interrupt_reason == 1 && /* ATAPI */ | ||
326 | fis->lbal == 1 && | ||
327 | fis->byte_count_low == 0x14 && | ||
328 | fis->byte_count_high == 0xEB && | ||
329 | (fis->device & ~0x10) == 0)) | ||
330 | |||
331 | dev->sata_dev.command_set = ATAPI_COMMAND_SET; | ||
332 | |||
333 | else if ((fis->sector_count == 1 && /* SEMB */ | ||
334 | fis->lbal == 1 && | ||
335 | fis->lbam == 0x3C && | ||
336 | fis->lbah == 0xC3 && | ||
337 | fis->device == 0) | ||
338 | || | ||
339 | (fis->interrupt_reason == 1 && /* SATA PM */ | ||
340 | fis->lbal == 1 && | ||
341 | fis->byte_count_low == 0x69 && | ||
342 | fis->byte_count_high == 0x96 && | ||
343 | (fis->device & ~0x10) == 0)) | ||
344 | |||
345 | /* Treat it as a superset? */ | ||
346 | dev->sata_dev.command_set = ATAPI_COMMAND_SET; | ||
347 | } | ||
348 | |||
349 | /** | ||
350 | * sas_issue_ata_cmd -- Basic SATA command processing for discovery | ||
351 | * @dev: the device to send the command to | ||
352 | * @command: the command register | ||
353 | * @features: the features register | ||
354 | * @buffer: pointer to buffer to do I/O | ||
355 | * @size: size of @buffer | ||
356 | * @pci_dma_dir: PCI_DMA_... | ||
357 | */ | ||
358 | static int sas_issue_ata_cmd(struct domain_device *dev, u8 command, | ||
359 | u8 features, void *buffer, int size, | ||
360 | int pci_dma_dir) | ||
361 | { | ||
362 | int res = 0; | ||
363 | struct sas_task *task; | ||
364 | struct dev_to_host_fis *d2h_fis = (struct dev_to_host_fis *) | ||
365 | &dev->frame_rcvd[0]; | ||
366 | |||
367 | res = -ENOMEM; | ||
368 | task = sas_alloc_task(GFP_KERNEL); | ||
369 | if (!task) | ||
370 | goto out; | ||
371 | |||
372 | task->dev = dev; | ||
373 | |||
374 | task->ata_task.fis.command = command; | ||
375 | task->ata_task.fis.features = features; | ||
376 | task->ata_task.fis.device = d2h_fis->device; | ||
377 | task->ata_task.retry_count = 1; | ||
378 | |||
379 | res = sas_execute_task(task, buffer, size, pci_dma_dir); | ||
380 | |||
381 | sas_free_task(task); | ||
382 | out: | ||
383 | return res; | ||
384 | } | ||
385 | |||
386 | static void sas_sata_propagate_sas_addr(struct domain_device *dev) | ||
387 | { | ||
388 | unsigned long flags; | ||
389 | struct asd_sas_port *port = dev->port; | ||
390 | struct asd_sas_phy *phy; | ||
391 | |||
392 | BUG_ON(dev->parent); | ||
393 | |||
394 | memcpy(port->attached_sas_addr, dev->sas_addr, SAS_ADDR_SIZE); | ||
395 | spin_lock_irqsave(&port->phy_list_lock, flags); | ||
396 | list_for_each_entry(phy, &port->phy_list, port_phy_el) | ||
397 | memcpy(phy->attached_sas_addr, dev->sas_addr, SAS_ADDR_SIZE); | ||
398 | spin_unlock_irqrestore(&port->phy_list_lock, flags); | ||
399 | } | ||
400 | |||
401 | #define ATA_IDENTIFY_DEV 0xEC | ||
402 | #define ATA_IDENTIFY_PACKET_DEV 0xA1 | ||
403 | #define ATA_SET_FEATURES 0xEF | ||
404 | #define ATA_FEATURE_PUP_STBY_SPIN_UP 0x07 | ||
405 | |||
406 | /** | ||
407 | * sas_discover_sata_dev -- discover a STP/SATA device (SATA_DEV) | ||
408 | * @dev: STP/SATA device of interest (ATA/ATAPI) | ||
409 | * | ||
410 | * The LLDD has already been notified of this device, so that we can | ||
411 | * send FISes to it. Here we try to get IDENTIFY DEVICE or IDENTIFY | ||
412 | * PACKET DEVICE, if ATAPI device, so that the LLDD can fine-tune its | ||
413 | * performance for this device. | ||
414 | */ | ||
415 | static int sas_discover_sata_dev(struct domain_device *dev) | ||
416 | { | ||
417 | int res; | ||
418 | __le16 *identify_x; | ||
419 | u8 command; | ||
420 | |||
421 | identify_x = kzalloc(512, GFP_KERNEL); | ||
422 | if (!identify_x) | ||
423 | return -ENOMEM; | ||
424 | |||
425 | if (dev->sata_dev.command_set == ATA_COMMAND_SET) { | ||
426 | dev->sata_dev.identify_device = identify_x; | ||
427 | command = ATA_IDENTIFY_DEV; | ||
428 | } else { | ||
429 | dev->sata_dev.identify_packet_device = identify_x; | ||
430 | command = ATA_IDENTIFY_PACKET_DEV; | ||
431 | } | ||
432 | |||
433 | res = sas_issue_ata_cmd(dev, command, 0, identify_x, 512, | ||
434 | PCI_DMA_FROMDEVICE); | ||
435 | if (res) | ||
436 | goto out_err; | ||
437 | |||
438 | /* lives on the media? */ | ||
439 | if (le16_to_cpu(identify_x[0]) & 4) { | ||
440 | /* incomplete response */ | ||
441 | SAS_DPRINTK("sending SET FEATURE/PUP_STBY_SPIN_UP to " | ||
442 | "dev %llx\n", SAS_ADDR(dev->sas_addr)); | ||
443 | if (!le16_to_cpu(identify_x[83] & (1<<6))) | ||
444 | goto cont1; | ||
445 | res = sas_issue_ata_cmd(dev, ATA_SET_FEATURES, | ||
446 | ATA_FEATURE_PUP_STBY_SPIN_UP, | ||
447 | NULL, 0, PCI_DMA_NONE); | ||
448 | if (res) | ||
449 | goto cont1; | ||
450 | |||
451 | schedule_timeout_interruptible(5*HZ); /* More time? */ | ||
452 | res = sas_issue_ata_cmd(dev, command, 0, identify_x, 512, | ||
453 | PCI_DMA_FROMDEVICE); | ||
454 | if (res) | ||
455 | goto out_err; | ||
456 | } | ||
457 | cont1: | ||
458 | /* Get WWN */ | ||
459 | if (dev->port->oob_mode != SATA_OOB_MODE) { | ||
460 | memcpy(dev->sas_addr, dev->sata_dev.rps_resp.rps.stp_sas_addr, | ||
461 | SAS_ADDR_SIZE); | ||
462 | } else if (dev->sata_dev.command_set == ATA_COMMAND_SET && | ||
463 | (le16_to_cpu(dev->sata_dev.identify_device[108]) & 0xF000) | ||
464 | == 0x5000) { | ||
465 | int i; | ||
466 | |||
467 | for (i = 0; i < 4; i++) { | ||
468 | dev->sas_addr[2*i] = | ||
469 | (le16_to_cpu(dev->sata_dev.identify_device[108+i]) & 0xFF00) >> 8; | ||
470 | dev->sas_addr[2*i+1] = | ||
471 | le16_to_cpu(dev->sata_dev.identify_device[108+i]) & 0x00FF; | ||
472 | } | ||
473 | } | ||
474 | sas_hash_addr(dev->hashed_sas_addr, dev->sas_addr); | ||
475 | if (!dev->parent) | ||
476 | sas_sata_propagate_sas_addr(dev); | ||
477 | |||
478 | /* XXX Hint: register this SATA device with SATL. | ||
479 | When this returns, dev->sata_dev->lu is alive and | ||
480 | present. | ||
481 | sas_satl_register_dev(dev); | ||
482 | */ | ||
483 | return 0; | ||
484 | out_err: | ||
485 | dev->sata_dev.identify_packet_device = NULL; | ||
486 | dev->sata_dev.identify_device = NULL; | ||
487 | kfree(identify_x); | ||
488 | return res; | ||
489 | } | ||
490 | |||
491 | static int sas_discover_sata_pm(struct domain_device *dev) | ||
492 | { | ||
493 | return -ENODEV; | ||
494 | } | ||
495 | |||
496 | int sas_notify_lldd_dev_found(struct domain_device *dev) | 161 | int sas_notify_lldd_dev_found(struct domain_device *dev) |
497 | { | 162 | { |
498 | int res = 0; | 163 | int res = 0; |
@@ -525,60 +190,6 @@ void sas_notify_lldd_dev_gone(struct domain_device *dev) | |||
525 | 190 | ||
526 | /* ---------- Common/dispatchers ---------- */ | 191 | /* ---------- Common/dispatchers ---------- */ |
527 | 192 | ||
528 | /** | ||
529 | * sas_discover_sata -- discover an STP/SATA domain device | ||
530 | * @dev: pointer to struct domain_device of interest | ||
531 | * | ||
532 | * First we notify the LLDD of this device, so we can send frames to | ||
533 | * it. Then depending on the type of device we call the appropriate | ||
534 | * discover functions. Once device discover is done, we notify the | ||
535 | * LLDD so that it can fine-tune its parameters for the device, by | ||
536 | * removing it and then adding it. That is, the second time around, | ||
537 | * the driver would have certain fields, that it is looking at, set. | ||
538 | * Finally we initialize the kobj so that the device can be added to | ||
539 | * the system at registration time. Devices directly attached to a HA | ||
540 | * port, have no parents. All other devices do, and should have their | ||
541 | * "parent" pointer set appropriately before calling this function. | ||
542 | */ | ||
543 | int sas_discover_sata(struct domain_device *dev) | ||
544 | { | ||
545 | int res; | ||
546 | |||
547 | sas_get_ata_command_set(dev); | ||
548 | |||
549 | res = sas_notify_lldd_dev_found(dev); | ||
550 | if (res) | ||
551 | goto out_err2; | ||
552 | |||
553 | switch (dev->dev_type) { | ||
554 | case SATA_DEV: | ||
555 | res = sas_discover_sata_dev(dev); | ||
556 | break; | ||
557 | case SATA_PM: | ||
558 | res = sas_discover_sata_pm(dev); | ||
559 | break; | ||
560 | default: | ||
561 | break; | ||
562 | } | ||
563 | if (res) | ||
564 | goto out_err; | ||
565 | |||
566 | sas_notify_lldd_dev_gone(dev); | ||
567 | res = sas_notify_lldd_dev_found(dev); | ||
568 | if (res) | ||
569 | goto out_err2; | ||
570 | |||
571 | res = sas_rphy_add(dev->rphy); | ||
572 | if (res) | ||
573 | goto out_err; | ||
574 | |||
575 | return res; | ||
576 | |||
577 | out_err: | ||
578 | sas_notify_lldd_dev_gone(dev); | ||
579 | out_err2: | ||
580 | return res; | ||
581 | } | ||
582 | 193 | ||
583 | /** | 194 | /** |
584 | * sas_discover_end_dev -- discover an end device (SSP, etc) | 195 | * sas_discover_end_dev -- discover an end device (SSP, etc) |
@@ -685,11 +296,14 @@ static void sas_discover_domain(struct work_struct *work) | |||
685 | case FANOUT_DEV: | 296 | case FANOUT_DEV: |
686 | error = sas_discover_root_expander(dev); | 297 | error = sas_discover_root_expander(dev); |
687 | break; | 298 | break; |
299 | #ifdef CONFIG_SCSI_SAS_ATA | ||
688 | case SATA_DEV: | 300 | case SATA_DEV: |
689 | case SATA_PM: | 301 | case SATA_PM: |
690 | error = sas_discover_sata(dev); | 302 | error = sas_discover_sata(dev); |
691 | break; | 303 | break; |
304 | #endif | ||
692 | default: | 305 | default: |
306 | error = -ENXIO; | ||
693 | SAS_DPRINTK("unhandled device %d\n", dev->dev_type); | 307 | SAS_DPRINTK("unhandled device %d\n", dev->dev_type); |
694 | break; | 308 | break; |
695 | } | 309 | } |
@@ -698,9 +312,9 @@ static void sas_discover_domain(struct work_struct *work) | |||
698 | sas_rphy_free(dev->rphy); | 312 | sas_rphy_free(dev->rphy); |
699 | dev->rphy = NULL; | 313 | dev->rphy = NULL; |
700 | 314 | ||
701 | spin_lock(&port->dev_list_lock); | 315 | spin_lock_irq(&port->dev_list_lock); |
702 | list_del_init(&dev->dev_list_node); | 316 | list_del_init(&dev->dev_list_node); |
703 | spin_unlock(&port->dev_list_lock); | 317 | spin_unlock_irq(&port->dev_list_lock); |
704 | 318 | ||
705 | kfree(dev); /* not kobject_register-ed yet */ | 319 | kfree(dev); /* not kobject_register-ed yet */ |
706 | port->port_dev = NULL; | 320 | port->port_dev = NULL; |
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 23e90c5f8f35..b500f0c1449c 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c | |||
@@ -23,6 +23,7 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <linux/scatterlist.h> | 25 | #include <linux/scatterlist.h> |
26 | #include <linux/blkdev.h> | ||
26 | 27 | ||
27 | #include "sas_internal.h" | 28 | #include "sas_internal.h" |
28 | 29 | ||
@@ -36,14 +37,6 @@ static int sas_configure_phy(struct domain_device *dev, int phy_id, | |||
36 | u8 *sas_addr, int include); | 37 | u8 *sas_addr, int include); |
37 | static int sas_disable_routing(struct domain_device *dev, u8 *sas_addr); | 38 | static int sas_disable_routing(struct domain_device *dev, u8 *sas_addr); |
38 | 39 | ||
39 | #if 0 | ||
40 | /* FIXME: smp needs to migrate into the sas class */ | ||
41 | static ssize_t smp_portal_read(struct kobject *, struct bin_attribute *, | ||
42 | char *, loff_t, size_t); | ||
43 | static ssize_t smp_portal_write(struct kobject *, struct bin_attribute *, | ||
44 | char *, loff_t, size_t); | ||
45 | #endif | ||
46 | |||
47 | /* ---------- SMP task management ---------- */ | 40 | /* ---------- SMP task management ---------- */ |
48 | 41 | ||
49 | static void smp_task_timedout(unsigned long _task) | 42 | static void smp_task_timedout(unsigned long _task) |
@@ -220,6 +213,36 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, | |||
220 | #define DISCOVER_REQ_SIZE 16 | 213 | #define DISCOVER_REQ_SIZE 16 |
221 | #define DISCOVER_RESP_SIZE 56 | 214 | #define DISCOVER_RESP_SIZE 56 |
222 | 215 | ||
216 | static int sas_ex_phy_discover_helper(struct domain_device *dev, u8 *disc_req, | ||
217 | u8 *disc_resp, int single) | ||
218 | { | ||
219 | int i, res; | ||
220 | |||
221 | disc_req[9] = single; | ||
222 | for (i = 1 ; i < 3; i++) { | ||
223 | struct discover_resp *dr; | ||
224 | |||
225 | res = smp_execute_task(dev, disc_req, DISCOVER_REQ_SIZE, | ||
226 | disc_resp, DISCOVER_RESP_SIZE); | ||
227 | if (res) | ||
228 | return res; | ||
229 | /* This is detecting a failure to transmit inital | ||
230 | * dev to host FIS as described in section G.5 of | ||
231 | * sas-2 r 04b */ | ||
232 | dr = &((struct smp_resp *)disc_resp)->disc; | ||
233 | if (!(dr->attached_dev_type == 0 && | ||
234 | dr->attached_sata_dev)) | ||
235 | break; | ||
236 | /* In order to generate the dev to host FIS, we | ||
237 | * send a link reset to the expander port */ | ||
238 | sas_smp_phy_control(dev, single, PHY_FUNC_LINK_RESET, NULL); | ||
239 | /* Wait for the reset to trigger the negotiation */ | ||
240 | msleep(500); | ||
241 | } | ||
242 | sas_set_ex_phy(dev, single, disc_resp); | ||
243 | return 0; | ||
244 | } | ||
245 | |||
223 | static int sas_ex_phy_discover(struct domain_device *dev, int single) | 246 | static int sas_ex_phy_discover(struct domain_device *dev, int single) |
224 | { | 247 | { |
225 | struct expander_device *ex = &dev->ex_dev; | 248 | struct expander_device *ex = &dev->ex_dev; |
@@ -240,23 +263,15 @@ static int sas_ex_phy_discover(struct domain_device *dev, int single) | |||
240 | disc_req[1] = SMP_DISCOVER; | 263 | disc_req[1] = SMP_DISCOVER; |
241 | 264 | ||
242 | if (0 <= single && single < ex->num_phys) { | 265 | if (0 <= single && single < ex->num_phys) { |
243 | disc_req[9] = single; | 266 | res = sas_ex_phy_discover_helper(dev, disc_req, disc_resp, single); |
244 | res = smp_execute_task(dev, disc_req, DISCOVER_REQ_SIZE, | ||
245 | disc_resp, DISCOVER_RESP_SIZE); | ||
246 | if (res) | ||
247 | goto out_err; | ||
248 | sas_set_ex_phy(dev, single, disc_resp); | ||
249 | } else { | 267 | } else { |
250 | int i; | 268 | int i; |
251 | 269 | ||
252 | for (i = 0; i < ex->num_phys; i++) { | 270 | for (i = 0; i < ex->num_phys; i++) { |
253 | disc_req[9] = i; | 271 | res = sas_ex_phy_discover_helper(dev, disc_req, |
254 | res = smp_execute_task(dev, disc_req, | 272 | disc_resp, i); |
255 | DISCOVER_REQ_SIZE, disc_resp, | ||
256 | DISCOVER_RESP_SIZE); | ||
257 | if (res) | 273 | if (res) |
258 | goto out_err; | 274 | goto out_err; |
259 | sas_set_ex_phy(dev, i, disc_resp); | ||
260 | } | 275 | } |
261 | } | 276 | } |
262 | out_err: | 277 | out_err: |
@@ -520,6 +535,8 @@ int sas_smp_get_phy_events(struct sas_phy *phy) | |||
520 | 535 | ||
521 | } | 536 | } |
522 | 537 | ||
538 | #ifdef CONFIG_SCSI_SAS_ATA | ||
539 | |||
523 | #define RPS_REQ_SIZE 16 | 540 | #define RPS_REQ_SIZE 16 |
524 | #define RPS_RESP_SIZE 60 | 541 | #define RPS_RESP_SIZE 60 |
525 | 542 | ||
@@ -529,6 +546,7 @@ static int sas_get_report_phy_sata(struct domain_device *dev, | |||
529 | { | 546 | { |
530 | int res; | 547 | int res; |
531 | u8 *rps_req = alloc_smp_req(RPS_REQ_SIZE); | 548 | u8 *rps_req = alloc_smp_req(RPS_REQ_SIZE); |
549 | u8 *resp = (u8 *)rps_resp; | ||
532 | 550 | ||
533 | if (!rps_req) | 551 | if (!rps_req) |
534 | return -ENOMEM; | 552 | return -ENOMEM; |
@@ -539,9 +557,30 @@ static int sas_get_report_phy_sata(struct domain_device *dev, | |||
539 | res = smp_execute_task(dev, rps_req, RPS_REQ_SIZE, | 557 | res = smp_execute_task(dev, rps_req, RPS_REQ_SIZE, |
540 | rps_resp, RPS_RESP_SIZE); | 558 | rps_resp, RPS_RESP_SIZE); |
541 | 559 | ||
560 | /* 0x34 is the FIS type for the D2H fis. There's a potential | ||
561 | * standards cockup here. sas-2 explicitly specifies the FIS | ||
562 | * should be encoded so that FIS type is in resp[24]. | ||
563 | * However, some expanders endian reverse this. Undo the | ||
564 | * reversal here */ | ||
565 | if (!res && resp[27] == 0x34 && resp[24] != 0x34) { | ||
566 | int i; | ||
567 | |||
568 | for (i = 0; i < 5; i++) { | ||
569 | int j = 24 + (i*4); | ||
570 | u8 a, b; | ||
571 | a = resp[j + 0]; | ||
572 | b = resp[j + 1]; | ||
573 | resp[j + 0] = resp[j + 3]; | ||
574 | resp[j + 1] = resp[j + 2]; | ||
575 | resp[j + 2] = b; | ||
576 | resp[j + 3] = a; | ||
577 | } | ||
578 | } | ||
579 | |||
542 | kfree(rps_req); | 580 | kfree(rps_req); |
543 | return 0; | 581 | return res; |
544 | } | 582 | } |
583 | #endif | ||
545 | 584 | ||
546 | static void sas_ex_get_linkrate(struct domain_device *parent, | 585 | static void sas_ex_get_linkrate(struct domain_device *parent, |
547 | struct domain_device *child, | 586 | struct domain_device *child, |
@@ -609,6 +648,7 @@ static struct domain_device *sas_ex_discover_end_dev( | |||
609 | } | 648 | } |
610 | sas_ex_get_linkrate(parent, child, phy); | 649 | sas_ex_get_linkrate(parent, child, phy); |
611 | 650 | ||
651 | #ifdef CONFIG_SCSI_SAS_ATA | ||
612 | if ((phy->attached_tproto & SAS_PROTO_STP) || phy->attached_sata_dev) { | 652 | if ((phy->attached_tproto & SAS_PROTO_STP) || phy->attached_sata_dev) { |
613 | child->dev_type = SATA_DEV; | 653 | child->dev_type = SATA_DEV; |
614 | if (phy->attached_tproto & SAS_PROTO_STP) | 654 | if (phy->attached_tproto & SAS_PROTO_STP) |
@@ -625,16 +665,30 @@ static struct domain_device *sas_ex_discover_end_dev( | |||
625 | } | 665 | } |
626 | memcpy(child->frame_rcvd, &child->sata_dev.rps_resp.rps.fis, | 666 | memcpy(child->frame_rcvd, &child->sata_dev.rps_resp.rps.fis, |
627 | sizeof(struct dev_to_host_fis)); | 667 | sizeof(struct dev_to_host_fis)); |
668 | |||
669 | rphy = sas_end_device_alloc(phy->port); | ||
670 | if (unlikely(!rphy)) | ||
671 | goto out_free; | ||
672 | |||
628 | sas_init_dev(child); | 673 | sas_init_dev(child); |
674 | |||
675 | child->rphy = rphy; | ||
676 | |||
677 | spin_lock_irq(&parent->port->dev_list_lock); | ||
678 | list_add_tail(&child->dev_list_node, &parent->port->dev_list); | ||
679 | spin_unlock_irq(&parent->port->dev_list_lock); | ||
680 | |||
629 | res = sas_discover_sata(child); | 681 | res = sas_discover_sata(child); |
630 | if (res) { | 682 | if (res) { |
631 | SAS_DPRINTK("sas_discover_sata() for device %16llx at " | 683 | SAS_DPRINTK("sas_discover_sata() for device %16llx at " |
632 | "%016llx:0x%x returned 0x%x\n", | 684 | "%016llx:0x%x returned 0x%x\n", |
633 | SAS_ADDR(child->sas_addr), | 685 | SAS_ADDR(child->sas_addr), |
634 | SAS_ADDR(parent->sas_addr), phy_id, res); | 686 | SAS_ADDR(parent->sas_addr), phy_id, res); |
635 | goto out_free; | 687 | goto out_list_del; |
636 | } | 688 | } |
637 | } else if (phy->attached_tproto & SAS_PROTO_SSP) { | 689 | } else |
690 | #endif | ||
691 | if (phy->attached_tproto & SAS_PROTO_SSP) { | ||
638 | child->dev_type = SAS_END_DEV; | 692 | child->dev_type = SAS_END_DEV; |
639 | rphy = sas_end_device_alloc(phy->port); | 693 | rphy = sas_end_device_alloc(phy->port); |
640 | /* FIXME: error handling */ | 694 | /* FIXME: error handling */ |
@@ -646,9 +700,9 @@ static struct domain_device *sas_ex_discover_end_dev( | |||
646 | child->rphy = rphy; | 700 | child->rphy = rphy; |
647 | sas_fill_in_rphy(child, rphy); | 701 | sas_fill_in_rphy(child, rphy); |
648 | 702 | ||
649 | spin_lock(&parent->port->dev_list_lock); | 703 | spin_lock_irq(&parent->port->dev_list_lock); |
650 | list_add_tail(&child->dev_list_node, &parent->port->dev_list); | 704 | list_add_tail(&child->dev_list_node, &parent->port->dev_list); |
651 | spin_unlock(&parent->port->dev_list_lock); | 705 | spin_unlock_irq(&parent->port->dev_list_lock); |
652 | 706 | ||
653 | res = sas_discover_end_dev(child); | 707 | res = sas_discover_end_dev(child); |
654 | if (res) { | 708 | if (res) { |
@@ -662,6 +716,7 @@ static struct domain_device *sas_ex_discover_end_dev( | |||
662 | SAS_DPRINTK("target proto 0x%x at %016llx:0x%x not handled\n", | 716 | SAS_DPRINTK("target proto 0x%x at %016llx:0x%x not handled\n", |
663 | phy->attached_tproto, SAS_ADDR(parent->sas_addr), | 717 | phy->attached_tproto, SAS_ADDR(parent->sas_addr), |
664 | phy_id); | 718 | phy_id); |
719 | goto out_free; | ||
665 | } | 720 | } |
666 | 721 | ||
667 | list_add_tail(&child->siblings, &parent_ex->children); | 722 | list_add_tail(&child->siblings, &parent_ex->children); |
@@ -761,9 +816,9 @@ static struct domain_device *sas_ex_discover_expander( | |||
761 | sas_fill_in_rphy(child, rphy); | 816 | sas_fill_in_rphy(child, rphy); |
762 | sas_rphy_add(rphy); | 817 | sas_rphy_add(rphy); |
763 | 818 | ||
764 | spin_lock(&parent->port->dev_list_lock); | 819 | spin_lock_irq(&parent->port->dev_list_lock); |
765 | list_add_tail(&child->dev_list_node, &parent->port->dev_list); | 820 | list_add_tail(&child->dev_list_node, &parent->port->dev_list); |
766 | spin_unlock(&parent->port->dev_list_lock); | 821 | spin_unlock_irq(&parent->port->dev_list_lock); |
767 | 822 | ||
768 | res = sas_discover_expander(child); | 823 | res = sas_discover_expander(child); |
769 | if (res) { | 824 | if (res) { |
@@ -1359,30 +1414,6 @@ static int sas_disable_routing(struct domain_device *dev, u8 *sas_addr) | |||
1359 | return 0; | 1414 | return 0; |
1360 | } | 1415 | } |
1361 | 1416 | ||
1362 | #if 0 | ||
1363 | #define SMP_BIN_ATTR_NAME "smp_portal" | ||
1364 | |||
1365 | static void sas_ex_smp_hook(struct domain_device *dev) | ||
1366 | { | ||
1367 | struct expander_device *ex_dev = &dev->ex_dev; | ||
1368 | struct bin_attribute *bin_attr = &ex_dev->smp_bin_attr; | ||
1369 | |||
1370 | memset(bin_attr, 0, sizeof(*bin_attr)); | ||
1371 | |||
1372 | bin_attr->attr.name = SMP_BIN_ATTR_NAME; | ||
1373 | bin_attr->attr.mode = 0600; | ||
1374 | |||
1375 | bin_attr->size = 0; | ||
1376 | bin_attr->private = NULL; | ||
1377 | bin_attr->read = smp_portal_read; | ||
1378 | bin_attr->write= smp_portal_write; | ||
1379 | bin_attr->mmap = NULL; | ||
1380 | |||
1381 | ex_dev->smp_portal_pid = -1; | ||
1382 | init_MUTEX(&ex_dev->smp_sema); | ||
1383 | } | ||
1384 | #endif | ||
1385 | |||
1386 | /** | 1417 | /** |
1387 | * sas_discover_expander -- expander discovery | 1418 | * sas_discover_expander -- expander discovery |
1388 | * @ex: pointer to expander domain device | 1419 | * @ex: pointer to expander domain device |
@@ -1844,76 +1875,49 @@ out: | |||
1844 | return res; | 1875 | return res; |
1845 | } | 1876 | } |
1846 | 1877 | ||
1847 | #if 0 | 1878 | int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, |
1848 | /* ---------- SMP portal ---------- */ | 1879 | struct request *req) |
1849 | |||
1850 | static ssize_t smp_portal_write(struct kobject *kobj, | ||
1851 | struct bin_attribute *bin_attr, | ||
1852 | char *buf, loff_t offs, size_t size) | ||
1853 | { | 1880 | { |
1854 | struct domain_device *dev = to_dom_device(kobj); | 1881 | struct domain_device *dev; |
1855 | struct expander_device *ex = &dev->ex_dev; | 1882 | int ret, type = rphy->identify.device_type; |
1856 | 1883 | struct request *rsp = req->next_rq; | |
1857 | if (offs != 0) | ||
1858 | return -EFBIG; | ||
1859 | else if (size == 0) | ||
1860 | return 0; | ||
1861 | 1884 | ||
1862 | down_interruptible(&ex->smp_sema); | 1885 | if (!rsp) { |
1863 | if (ex->smp_req) | 1886 | printk("%s: space for a smp response is missing\n", |
1864 | kfree(ex->smp_req); | 1887 | __FUNCTION__); |
1865 | ex->smp_req = kzalloc(size, GFP_USER); | 1888 | return -EINVAL; |
1866 | if (!ex->smp_req) { | ||
1867 | up(&ex->smp_sema); | ||
1868 | return -ENOMEM; | ||
1869 | } | 1889 | } |
1870 | memcpy(ex->smp_req, buf, size); | ||
1871 | ex->smp_req_size = size; | ||
1872 | ex->smp_portal_pid = current->pid; | ||
1873 | up(&ex->smp_sema); | ||
1874 | 1890 | ||
1875 | return size; | 1891 | /* seems aic94xx doesn't support */ |
1876 | } | 1892 | if (!rphy) { |
1877 | 1893 | printk("%s: can we send a smp request to a host?\n", | |
1878 | static ssize_t smp_portal_read(struct kobject *kobj, | 1894 | __FUNCTION__); |
1879 | struct bin_attribute *bin_attr, | 1895 | return -EINVAL; |
1880 | char *buf, loff_t offs, size_t size) | 1896 | } |
1881 | { | ||
1882 | struct domain_device *dev = to_dom_device(kobj); | ||
1883 | struct expander_device *ex = &dev->ex_dev; | ||
1884 | u8 *smp_resp; | ||
1885 | int res = -EINVAL; | ||
1886 | |||
1887 | /* XXX: sysfs gives us an offset of 0x10 or 0x8 while in fact | ||
1888 | * it should be 0. | ||
1889 | */ | ||
1890 | 1897 | ||
1891 | down_interruptible(&ex->smp_sema); | 1898 | if (type != SAS_EDGE_EXPANDER_DEVICE && |
1892 | if (!ex->smp_req || ex->smp_portal_pid != current->pid) | 1899 | type != SAS_FANOUT_EXPANDER_DEVICE) { |
1893 | goto out; | 1900 | printk("%s: can we send a smp request to a device?\n", |
1901 | __FUNCTION__); | ||
1902 | return -EINVAL; | ||
1903 | } | ||
1894 | 1904 | ||
1895 | res = 0; | 1905 | dev = sas_find_dev_by_rphy(rphy); |
1896 | if (size == 0) | 1906 | if (!dev) { |
1897 | goto out; | 1907 | printk("%s: fail to find a domain_device?\n", __FUNCTION__); |
1908 | return -EINVAL; | ||
1909 | } | ||
1898 | 1910 | ||
1899 | res = -ENOMEM; | 1911 | /* do we need to support multiple segments? */ |
1900 | smp_resp = alloc_smp_resp(size); | 1912 | if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) { |
1901 | if (!smp_resp) | 1913 | printk("%s: multiple segments req %u %u, rsp %u %u\n", |
1902 | goto out; | 1914 | __FUNCTION__, req->bio->bi_vcnt, req->data_len, |
1903 | res = smp_execute_task(dev, ex->smp_req, ex->smp_req_size, | 1915 | rsp->bio->bi_vcnt, rsp->data_len); |
1904 | smp_resp, size); | 1916 | return -EINVAL; |
1905 | if (!res) { | ||
1906 | memcpy(buf, smp_resp, size); | ||
1907 | res = size; | ||
1908 | } | 1917 | } |
1909 | 1918 | ||
1910 | kfree(smp_resp); | 1919 | ret = smp_execute_task(dev, bio_data(req->bio), req->data_len, |
1911 | out: | 1920 | bio_data(rsp->bio), rsp->data_len); |
1912 | kfree(ex->smp_req); | 1921 | |
1913 | ex->smp_req = NULL; | 1922 | return ret; |
1914 | ex->smp_req_size = 0; | ||
1915 | ex->smp_portal_pid = -1; | ||
1916 | up(&ex->smp_sema); | ||
1917 | return res; | ||
1918 | } | 1923 | } |
1919 | #endif | ||
diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c index 1396c83b0c9c..9cd5abe9e714 100644 --- a/drivers/scsi/libsas/sas_init.c +++ b/drivers/scsi/libsas/sas_init.c | |||
@@ -259,6 +259,7 @@ static struct sas_function_template sft = { | |||
259 | .phy_reset = sas_phy_reset, | 259 | .phy_reset = sas_phy_reset, |
260 | .set_phy_speed = sas_set_phy_speed, | 260 | .set_phy_speed = sas_set_phy_speed, |
261 | .get_linkerrors = sas_get_linkerrors, | 261 | .get_linkerrors = sas_get_linkerrors, |
262 | .smp_handler = sas_smp_handler, | ||
262 | }; | 263 | }; |
263 | 264 | ||
264 | struct scsi_transport_template * | 265 | struct scsi_transport_template * |
diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h index a78638df2018..2b8213b1832d 100644 --- a/drivers/scsi/libsas/sas_internal.h +++ b/drivers/scsi/libsas/sas_internal.h | |||
@@ -39,6 +39,9 @@ | |||
39 | #define SAS_DPRINTK(fmt, ...) | 39 | #define SAS_DPRINTK(fmt, ...) |
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | #define TO_SAS_TASK(_scsi_cmd) ((void *)(_scsi_cmd)->host_scribble) | ||
43 | #define ASSIGN_SAS_TASK(_sc, _t) do { (_sc)->host_scribble = (void *) _t; } while (0) | ||
44 | |||
42 | void sas_scsi_recover_host(struct Scsi_Host *shost); | 45 | void sas_scsi_recover_host(struct Scsi_Host *shost); |
43 | 46 | ||
44 | int sas_show_class(enum sas_class class, char *buf); | 47 | int sas_show_class(enum sas_class class, char *buf); |
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index 9c5342e7a69c..7663841eb4cf 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <scsi/scsi_eh.h> | 34 | #include <scsi/scsi_eh.h> |
35 | #include <scsi/scsi_transport.h> | 35 | #include <scsi/scsi_transport.h> |
36 | #include <scsi/scsi_transport_sas.h> | 36 | #include <scsi/scsi_transport_sas.h> |
37 | #include <scsi/sas_ata.h> | ||
37 | #include "../scsi_sas_internal.h" | 38 | #include "../scsi_sas_internal.h" |
38 | #include "../scsi_transport_api.h" | 39 | #include "../scsi_transport_api.h" |
39 | #include "../scsi_priv.h" | 40 | #include "../scsi_priv.h" |
@@ -42,12 +43,10 @@ | |||
42 | #include <linux/blkdev.h> | 43 | #include <linux/blkdev.h> |
43 | #include <linux/freezer.h> | 44 | #include <linux/freezer.h> |
44 | #include <linux/scatterlist.h> | 45 | #include <linux/scatterlist.h> |
46 | #include <linux/libata.h> | ||
45 | 47 | ||
46 | /* ---------- SCSI Host glue ---------- */ | 48 | /* ---------- SCSI Host glue ---------- */ |
47 | 49 | ||
48 | #define TO_SAS_TASK(_scsi_cmd) ((void *)(_scsi_cmd)->host_scribble) | ||
49 | #define ASSIGN_SAS_TASK(_sc, _t) do { (_sc)->host_scribble = (void *) _t; } while (0) | ||
50 | |||
51 | static void sas_scsi_task_done(struct sas_task *task) | 50 | static void sas_scsi_task_done(struct sas_task *task) |
52 | { | 51 | { |
53 | struct task_status_struct *ts = &task->task_status; | 52 | struct task_status_struct *ts = &task->task_status; |
@@ -172,7 +171,7 @@ static struct sas_task *sas_create_task(struct scsi_cmnd *cmd, | |||
172 | return task; | 171 | return task; |
173 | } | 172 | } |
174 | 173 | ||
175 | static int sas_queue_up(struct sas_task *task) | 174 | int sas_queue_up(struct sas_task *task) |
176 | { | 175 | { |
177 | struct sas_ha_struct *sas_ha = task->dev->port->ha; | 176 | struct sas_ha_struct *sas_ha = task->dev->port->ha; |
178 | struct scsi_core *core = &sas_ha->core; | 177 | struct scsi_core *core = &sas_ha->core; |
@@ -213,6 +212,16 @@ int sas_queuecommand(struct scsi_cmnd *cmd, | |||
213 | struct sas_ha_struct *sas_ha = dev->port->ha; | 212 | struct sas_ha_struct *sas_ha = dev->port->ha; |
214 | struct sas_task *task; | 213 | struct sas_task *task; |
215 | 214 | ||
215 | if (dev_is_sata(dev)) { | ||
216 | unsigned long flags; | ||
217 | |||
218 | spin_lock_irqsave(dev->sata_dev.ap->lock, flags); | ||
219 | res = ata_sas_queuecmd(cmd, scsi_done, | ||
220 | dev->sata_dev.ap); | ||
221 | spin_unlock_irqrestore(dev->sata_dev.ap->lock, flags); | ||
222 | goto out; | ||
223 | } | ||
224 | |||
216 | res = -ENOMEM; | 225 | res = -ENOMEM; |
217 | task = sas_create_task(cmd, dev, GFP_ATOMIC); | 226 | task = sas_create_task(cmd, dev, GFP_ATOMIC); |
218 | if (!task) | 227 | if (!task) |
@@ -684,6 +693,16 @@ enum scsi_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd) | |||
684 | return EH_NOT_HANDLED; | 693 | return EH_NOT_HANDLED; |
685 | } | 694 | } |
686 | 695 | ||
696 | int sas_ioctl(struct scsi_device *sdev, int cmd, void __user *arg) | ||
697 | { | ||
698 | struct domain_device *dev = sdev_to_domain_dev(sdev); | ||
699 | |||
700 | if (dev_is_sata(dev)) | ||
701 | return ata_scsi_ioctl(sdev, cmd, arg); | ||
702 | |||
703 | return -EINVAL; | ||
704 | } | ||
705 | |||
687 | struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy) | 706 | struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy) |
688 | { | 707 | { |
689 | struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent); | 708 | struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent); |
@@ -723,10 +742,17 @@ static inline struct domain_device *sas_find_target(struct scsi_target *starget) | |||
723 | int sas_target_alloc(struct scsi_target *starget) | 742 | int sas_target_alloc(struct scsi_target *starget) |
724 | { | 743 | { |
725 | struct domain_device *found_dev = sas_find_target(starget); | 744 | struct domain_device *found_dev = sas_find_target(starget); |
745 | int res; | ||
726 | 746 | ||
727 | if (!found_dev) | 747 | if (!found_dev) |
728 | return -ENODEV; | 748 | return -ENODEV; |
729 | 749 | ||
750 | if (dev_is_sata(found_dev)) { | ||
751 | res = sas_ata_init_host_and_port(found_dev, starget); | ||
752 | if (res) | ||
753 | return res; | ||
754 | } | ||
755 | |||
730 | starget->hostdata = found_dev; | 756 | starget->hostdata = found_dev; |
731 | return 0; | 757 | return 0; |
732 | } | 758 | } |
@@ -741,6 +767,11 @@ int sas_slave_configure(struct scsi_device *scsi_dev) | |||
741 | 767 | ||
742 | BUG_ON(dev->rphy->identify.device_type != SAS_END_DEVICE); | 768 | BUG_ON(dev->rphy->identify.device_type != SAS_END_DEVICE); |
743 | 769 | ||
770 | if (dev_is_sata(dev)) { | ||
771 | ata_sas_slave_configure(scsi_dev, dev->sata_dev.ap); | ||
772 | return 0; | ||
773 | } | ||
774 | |||
744 | sas_ha = dev->port->ha; | 775 | sas_ha = dev->port->ha; |
745 | 776 | ||
746 | sas_read_port_mode_page(scsi_dev); | 777 | sas_read_port_mode_page(scsi_dev); |
@@ -764,6 +795,10 @@ int sas_slave_configure(struct scsi_device *scsi_dev) | |||
764 | 795 | ||
765 | void sas_slave_destroy(struct scsi_device *scsi_dev) | 796 | void sas_slave_destroy(struct scsi_device *scsi_dev) |
766 | { | 797 | { |
798 | struct domain_device *dev = sdev_to_domain_dev(scsi_dev); | ||
799 | |||
800 | if (dev_is_sata(dev)) | ||
801 | ata_port_disable(dev->sata_dev.ap); | ||
767 | } | 802 | } |
768 | 803 | ||
769 | int sas_change_queue_depth(struct scsi_device *scsi_dev, int new_depth) | 804 | int sas_change_queue_depth(struct scsi_device *scsi_dev, int new_depth) |
@@ -980,10 +1015,38 @@ void sas_task_abort(struct sas_task *task) | |||
980 | return; | 1015 | return; |
981 | } | 1016 | } |
982 | 1017 | ||
1018 | if (dev_is_sata(task->dev)) { | ||
1019 | sas_ata_task_abort(task); | ||
1020 | return; | ||
1021 | } | ||
1022 | |||
983 | scsi_req_abort_cmd(sc); | 1023 | scsi_req_abort_cmd(sc); |
984 | scsi_schedule_eh(sc->device->host); | 1024 | scsi_schedule_eh(sc->device->host); |
985 | } | 1025 | } |
986 | 1026 | ||
1027 | int sas_slave_alloc(struct scsi_device *scsi_dev) | ||
1028 | { | ||
1029 | struct domain_device *dev = sdev_to_domain_dev(scsi_dev); | ||
1030 | |||
1031 | if (dev_is_sata(dev)) | ||
1032 | return ata_sas_port_init(dev->sata_dev.ap); | ||
1033 | |||
1034 | return 0; | ||
1035 | } | ||
1036 | |||
1037 | void sas_target_destroy(struct scsi_target *starget) | ||
1038 | { | ||
1039 | struct domain_device *found_dev = sas_find_target(starget); | ||
1040 | |||
1041 | if (!found_dev) | ||
1042 | return; | ||
1043 | |||
1044 | if (dev_is_sata(found_dev)) | ||
1045 | ata_sas_port_destroy(found_dev->sata_dev.ap); | ||
1046 | |||
1047 | return; | ||
1048 | } | ||
1049 | |||
987 | EXPORT_SYMBOL_GPL(sas_queuecommand); | 1050 | EXPORT_SYMBOL_GPL(sas_queuecommand); |
988 | EXPORT_SYMBOL_GPL(sas_target_alloc); | 1051 | EXPORT_SYMBOL_GPL(sas_target_alloc); |
989 | EXPORT_SYMBOL_GPL(sas_slave_configure); | 1052 | EXPORT_SYMBOL_GPL(sas_slave_configure); |
@@ -997,3 +1060,6 @@ EXPORT_SYMBOL_GPL(sas_phy_reset); | |||
997 | EXPORT_SYMBOL_GPL(sas_phy_enable); | 1060 | EXPORT_SYMBOL_GPL(sas_phy_enable); |
998 | EXPORT_SYMBOL_GPL(sas_eh_device_reset_handler); | 1061 | EXPORT_SYMBOL_GPL(sas_eh_device_reset_handler); |
999 | EXPORT_SYMBOL_GPL(sas_eh_bus_reset_handler); | 1062 | EXPORT_SYMBOL_GPL(sas_eh_bus_reset_handler); |
1063 | EXPORT_SYMBOL_GPL(sas_slave_alloc); | ||
1064 | EXPORT_SYMBOL_GPL(sas_target_destroy); | ||
1065 | EXPORT_SYMBOL_GPL(sas_ioctl); | ||
diff --git a/drivers/scsi/mvme16x_scsi.c b/drivers/scsi/mvme16x_scsi.c index d6ef22a941c4..1bdddad48571 100644 --- a/drivers/scsi/mvme16x_scsi.c +++ b/drivers/scsi/mvme16x_scsi.c | |||
@@ -89,6 +89,7 @@ mvme16x_probe(struct device *dev) | |||
89 | out_be32(0xfff4202c, v); | 89 | out_be32(0xfff4202c, v); |
90 | } | 90 | } |
91 | 91 | ||
92 | dev_set_drvdata(dev, host); | ||
92 | scsi_scan_host(host); | 93 | scsi_scan_host(host); |
93 | 94 | ||
94 | return 0; | 95 | return 0; |
@@ -104,7 +105,7 @@ mvme16x_probe(struct device *dev) | |||
104 | static __devexit int | 105 | static __devexit int |
105 | mvme16x_device_remove(struct device *dev) | 106 | mvme16x_device_remove(struct device *dev) |
106 | { | 107 | { |
107 | struct Scsi_Host *host = dev_to_shost(dev); | 108 | struct Scsi_Host *host = dev_get_drvdata(dev); |
108 | struct NCR_700_Host_Parameters *hostdata = shost_priv(host); | 109 | struct NCR_700_Host_Parameters *hostdata = shost_priv(host); |
109 | 110 | ||
110 | /* Disable scsi chip ints */ | 111 | /* Disable scsi chip ints */ |
diff --git a/drivers/scsi/pcmcia/Kconfig b/drivers/scsi/pcmcia/Kconfig index 7dd787f6ab27..fa481b515ead 100644 --- a/drivers/scsi/pcmcia/Kconfig +++ b/drivers/scsi/pcmcia/Kconfig | |||
@@ -2,9 +2,12 @@ | |||
2 | # PCMCIA SCSI adapter configuration | 2 | # PCMCIA SCSI adapter configuration |
3 | # | 3 | # |
4 | 4 | ||
5 | menu "PCMCIA SCSI adapter support" | 5 | menuconfig SCSI_LOWLEVEL_PCMCIA |
6 | bool "PCMCIA SCSI adapter support" | ||
6 | depends on SCSI!=n && PCMCIA!=n | 7 | depends on SCSI!=n && PCMCIA!=n |
7 | 8 | ||
9 | if SCSI_LOWLEVEL_PCMCIA && SCSI && PCMCIA | ||
10 | |||
8 | config PCMCIA_AHA152X | 11 | config PCMCIA_AHA152X |
9 | tristate "Adaptec AHA152X PCMCIA support" | 12 | tristate "Adaptec AHA152X PCMCIA support" |
10 | depends on !64BIT | 13 | depends on !64BIT |
@@ -77,4 +80,4 @@ config PCMCIA_SYM53C500 | |||
77 | To compile this driver as a module, choose M here: the | 80 | To compile this driver as a module, choose M here: the |
78 | module will be called sym53c500_cs. | 81 | module will be called sym53c500_cs. |
79 | 82 | ||
80 | endmenu | 83 | endif # SCSI_LOWLEVEL_PCMCIA |
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 3eb2208675ae..1612f9200a52 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -98,7 +98,7 @@ qla2x00_sysfs_read_nvram(struct kobject *kobj, | |||
98 | 98 | ||
99 | /* Read NVRAM. */ | 99 | /* Read NVRAM. */ |
100 | spin_lock_irqsave(&ha->hardware_lock, flags); | 100 | spin_lock_irqsave(&ha->hardware_lock, flags); |
101 | ha->isp_ops.read_nvram(ha, (uint8_t *)buf, ha->nvram_base, | 101 | ha->isp_ops->read_nvram(ha, (uint8_t *)buf, ha->nvram_base, |
102 | ha->nvram_size); | 102 | ha->nvram_size); |
103 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 103 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
104 | 104 | ||
@@ -119,7 +119,7 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj, | |||
119 | return 0; | 119 | return 0; |
120 | 120 | ||
121 | /* Checksum NVRAM. */ | 121 | /* Checksum NVRAM. */ |
122 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 122 | if (IS_FWI2_CAPABLE(ha)) { |
123 | uint32_t *iter; | 123 | uint32_t *iter; |
124 | uint32_t chksum; | 124 | uint32_t chksum; |
125 | 125 | ||
@@ -143,7 +143,7 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj, | |||
143 | 143 | ||
144 | /* Write NVRAM. */ | 144 | /* Write NVRAM. */ |
145 | spin_lock_irqsave(&ha->hardware_lock, flags); | 145 | spin_lock_irqsave(&ha->hardware_lock, flags); |
146 | ha->isp_ops.write_nvram(ha, (uint8_t *)buf, ha->nvram_base, count); | 146 | ha->isp_ops->write_nvram(ha, (uint8_t *)buf, ha->nvram_base, count); |
147 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 147 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
148 | 148 | ||
149 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 149 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); |
@@ -206,7 +206,7 @@ static struct bin_attribute sysfs_optrom_attr = { | |||
206 | .name = "optrom", | 206 | .name = "optrom", |
207 | .mode = S_IRUSR | S_IWUSR, | 207 | .mode = S_IRUSR | S_IWUSR, |
208 | }, | 208 | }, |
209 | .size = OPTROM_SIZE_24XX, | 209 | .size = 0, |
210 | .read = qla2x00_sysfs_read_optrom, | 210 | .read = qla2x00_sysfs_read_optrom, |
211 | .write = qla2x00_sysfs_write_optrom, | 211 | .write = qla2x00_sysfs_write_optrom, |
212 | }; | 212 | }; |
@@ -252,7 +252,7 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj, | |||
252 | } | 252 | } |
253 | 253 | ||
254 | memset(ha->optrom_buffer, 0, ha->optrom_size); | 254 | memset(ha->optrom_buffer, 0, ha->optrom_size); |
255 | ha->isp_ops.read_optrom(ha, ha->optrom_buffer, 0, | 255 | ha->isp_ops->read_optrom(ha, ha->optrom_buffer, 0, |
256 | ha->optrom_size); | 256 | ha->optrom_size); |
257 | break; | 257 | break; |
258 | case 2: | 258 | case 2: |
@@ -275,7 +275,7 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj, | |||
275 | if (ha->optrom_state != QLA_SWRITING) | 275 | if (ha->optrom_state != QLA_SWRITING) |
276 | break; | 276 | break; |
277 | 277 | ||
278 | ha->isp_ops.write_optrom(ha, ha->optrom_buffer, 0, | 278 | ha->isp_ops->write_optrom(ha, ha->optrom_buffer, 0, |
279 | ha->optrom_size); | 279 | ha->optrom_size); |
280 | break; | 280 | break; |
281 | } | 281 | } |
@@ -305,7 +305,8 @@ qla2x00_sysfs_read_vpd(struct kobject *kobj, | |||
305 | 305 | ||
306 | /* Read NVRAM. */ | 306 | /* Read NVRAM. */ |
307 | spin_lock_irqsave(&ha->hardware_lock, flags); | 307 | spin_lock_irqsave(&ha->hardware_lock, flags); |
308 | ha->isp_ops.read_nvram(ha, (uint8_t *)buf, ha->vpd_base, ha->vpd_size); | 308 | ha->isp_ops->read_nvram(ha, (uint8_t *)buf, ha->vpd_base, |
309 | ha->vpd_size); | ||
309 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 310 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
310 | 311 | ||
311 | return ha->vpd_size; | 312 | return ha->vpd_size; |
@@ -325,7 +326,7 @@ qla2x00_sysfs_write_vpd(struct kobject *kobj, | |||
325 | 326 | ||
326 | /* Write NVRAM. */ | 327 | /* Write NVRAM. */ |
327 | spin_lock_irqsave(&ha->hardware_lock, flags); | 328 | spin_lock_irqsave(&ha->hardware_lock, flags); |
328 | ha->isp_ops.write_nvram(ha, (uint8_t *)buf, ha->vpd_base, count); | 329 | ha->isp_ops->write_nvram(ha, (uint8_t *)buf, ha->vpd_base, count); |
329 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 330 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
330 | 331 | ||
331 | return count; | 332 | return count; |
@@ -410,7 +411,7 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha) | |||
410 | int ret; | 411 | int ret; |
411 | 412 | ||
412 | for (iter = bin_file_entries; iter->name; iter++) { | 413 | for (iter = bin_file_entries; iter->name; iter++) { |
413 | if (iter->is4GBp_only && (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))) | 414 | if (iter->is4GBp_only && !IS_FWI2_CAPABLE(ha)) |
414 | continue; | 415 | continue; |
415 | 416 | ||
416 | ret = sysfs_create_bin_file(&host->shost_gendev.kobj, | 417 | ret = sysfs_create_bin_file(&host->shost_gendev.kobj, |
@@ -429,7 +430,7 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *ha) | |||
429 | struct sysfs_entry *iter; | 430 | struct sysfs_entry *iter; |
430 | 431 | ||
431 | for (iter = bin_file_entries; iter->name; iter++) { | 432 | for (iter = bin_file_entries; iter->name; iter++) { |
432 | if (iter->is4GBp_only && (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))) | 433 | if (iter->is4GBp_only && !IS_FWI2_CAPABLE(ha)) |
433 | continue; | 434 | continue; |
434 | 435 | ||
435 | sysfs_remove_bin_file(&host->shost_gendev.kobj, | 436 | sysfs_remove_bin_file(&host->shost_gendev.kobj, |
@@ -437,7 +438,7 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *ha) | |||
437 | } | 438 | } |
438 | 439 | ||
439 | if (ha->beacon_blink_led == 1) | 440 | if (ha->beacon_blink_led == 1) |
440 | ha->isp_ops.beacon_off(ha); | 441 | ha->isp_ops->beacon_off(ha); |
441 | } | 442 | } |
442 | 443 | ||
443 | /* Scsi_Host attributes. */ | 444 | /* Scsi_Host attributes. */ |
@@ -455,7 +456,7 @@ qla2x00_fw_version_show(struct class_device *cdev, char *buf) | |||
455 | char fw_str[30]; | 456 | char fw_str[30]; |
456 | 457 | ||
457 | return snprintf(buf, PAGE_SIZE, "%s\n", | 458 | return snprintf(buf, PAGE_SIZE, "%s\n", |
458 | ha->isp_ops.fw_version_str(ha, fw_str)); | 459 | ha->isp_ops->fw_version_str(ha, fw_str)); |
459 | } | 460 | } |
460 | 461 | ||
461 | static ssize_t | 462 | static ssize_t |
@@ -507,7 +508,7 @@ qla2x00_pci_info_show(struct class_device *cdev, char *buf) | |||
507 | char pci_info[30]; | 508 | char pci_info[30]; |
508 | 509 | ||
509 | return snprintf(buf, PAGE_SIZE, "%s\n", | 510 | return snprintf(buf, PAGE_SIZE, "%s\n", |
510 | ha->isp_ops.pci_info_str(ha, pci_info)); | 511 | ha->isp_ops->pci_info_str(ha, pci_info)); |
511 | } | 512 | } |
512 | 513 | ||
513 | static ssize_t | 514 | static ssize_t |
@@ -652,9 +653,9 @@ qla2x00_beacon_store(struct class_device *cdev, const char *buf, | |||
652 | return -EINVAL; | 653 | return -EINVAL; |
653 | 654 | ||
654 | if (val) | 655 | if (val) |
655 | rval = ha->isp_ops.beacon_on(ha); | 656 | rval = ha->isp_ops->beacon_on(ha); |
656 | else | 657 | else |
657 | rval = ha->isp_ops.beacon_off(ha); | 658 | rval = ha->isp_ops->beacon_off(ha); |
658 | 659 | ||
659 | if (rval != QLA_SUCCESS) | 660 | if (rval != QLA_SUCCESS) |
660 | count = 0; | 661 | count = 0; |
@@ -898,7 +899,7 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost) | |||
898 | pfc_host_stat = &ha->fc_host_stat; | 899 | pfc_host_stat = &ha->fc_host_stat; |
899 | memset(pfc_host_stat, -1, sizeof(struct fc_host_statistics)); | 900 | memset(pfc_host_stat, -1, sizeof(struct fc_host_statistics)); |
900 | 901 | ||
901 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 902 | if (IS_FWI2_CAPABLE(ha)) { |
902 | rval = qla24xx_get_isp_stats(ha, (uint32_t *)&stat_buf, | 903 | rval = qla24xx_get_isp_stats(ha, (uint32_t *)&stat_buf, |
903 | sizeof(stat_buf) / 4, mb_stat); | 904 | sizeof(stat_buf) / 4, mb_stat); |
904 | } else if (atomic_read(&ha->loop_state) == LOOP_READY && | 905 | } else if (atomic_read(&ha->loop_state) == LOOP_READY && |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 996c47a63074..563d18f4ff50 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c | |||
@@ -37,6 +37,121 @@ qla2xxx_copy_queues(scsi_qla_host_t *ha, void *ptr) | |||
37 | return ptr + (ha->response_q_length * sizeof(response_t)); | 37 | return ptr + (ha->response_q_length * sizeof(response_t)); |
38 | } | 38 | } |
39 | 39 | ||
40 | static int | ||
41 | qla2xxx_dump_memory(scsi_qla_host_t *ha, uint32_t *code_ram, | ||
42 | uint32_t cram_size, uint32_t *ext_mem, void **nxt) | ||
43 | { | ||
44 | int rval; | ||
45 | uint32_t cnt, stat, timer, risc_address, ext_mem_cnt; | ||
46 | uint16_t mb[4]; | ||
47 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | ||
48 | |||
49 | rval = QLA_SUCCESS; | ||
50 | risc_address = ext_mem_cnt = 0; | ||
51 | memset(mb, 0, sizeof(mb)); | ||
52 | |||
53 | /* Code RAM. */ | ||
54 | risc_address = 0x20000; | ||
55 | WRT_REG_WORD(®->mailbox0, MBC_READ_RAM_EXTENDED); | ||
56 | clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | ||
57 | |||
58 | for (cnt = 0; cnt < cram_size / 4 && rval == QLA_SUCCESS; | ||
59 | cnt++, risc_address++) { | ||
60 | WRT_REG_WORD(®->mailbox1, LSW(risc_address)); | ||
61 | WRT_REG_WORD(®->mailbox8, MSW(risc_address)); | ||
62 | RD_REG_WORD(®->mailbox8); | ||
63 | WRT_REG_DWORD(®->hccr, HCCRX_SET_HOST_INT); | ||
64 | |||
65 | for (timer = 6000000; timer; timer--) { | ||
66 | /* Check for pending interrupts. */ | ||
67 | stat = RD_REG_DWORD(®->host_status); | ||
68 | if (stat & HSRX_RISC_INT) { | ||
69 | stat &= 0xff; | ||
70 | |||
71 | if (stat == 0x1 || stat == 0x2 || | ||
72 | stat == 0x10 || stat == 0x11) { | ||
73 | set_bit(MBX_INTERRUPT, | ||
74 | &ha->mbx_cmd_flags); | ||
75 | |||
76 | mb[0] = RD_REG_WORD(®->mailbox0); | ||
77 | mb[2] = RD_REG_WORD(®->mailbox2); | ||
78 | mb[3] = RD_REG_WORD(®->mailbox3); | ||
79 | |||
80 | WRT_REG_DWORD(®->hccr, | ||
81 | HCCRX_CLR_RISC_INT); | ||
82 | RD_REG_DWORD(®->hccr); | ||
83 | break; | ||
84 | } | ||
85 | |||
86 | /* Clear this intr; it wasn't a mailbox intr */ | ||
87 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | ||
88 | RD_REG_DWORD(®->hccr); | ||
89 | } | ||
90 | udelay(5); | ||
91 | } | ||
92 | |||
93 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | ||
94 | rval = mb[0] & MBS_MASK; | ||
95 | code_ram[cnt] = htonl((mb[3] << 16) | mb[2]); | ||
96 | } else { | ||
97 | rval = QLA_FUNCTION_FAILED; | ||
98 | } | ||
99 | } | ||
100 | |||
101 | if (rval == QLA_SUCCESS) { | ||
102 | /* External Memory. */ | ||
103 | risc_address = 0x100000; | ||
104 | ext_mem_cnt = ha->fw_memory_size - 0x100000 + 1; | ||
105 | WRT_REG_WORD(®->mailbox0, MBC_READ_RAM_EXTENDED); | ||
106 | clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | ||
107 | } | ||
108 | for (cnt = 0; cnt < ext_mem_cnt && rval == QLA_SUCCESS; | ||
109 | cnt++, risc_address++) { | ||
110 | WRT_REG_WORD(®->mailbox1, LSW(risc_address)); | ||
111 | WRT_REG_WORD(®->mailbox8, MSW(risc_address)); | ||
112 | RD_REG_WORD(®->mailbox8); | ||
113 | WRT_REG_DWORD(®->hccr, HCCRX_SET_HOST_INT); | ||
114 | |||
115 | for (timer = 6000000; timer; timer--) { | ||
116 | /* Check for pending interrupts. */ | ||
117 | stat = RD_REG_DWORD(®->host_status); | ||
118 | if (stat & HSRX_RISC_INT) { | ||
119 | stat &= 0xff; | ||
120 | |||
121 | if (stat == 0x1 || stat == 0x2 || | ||
122 | stat == 0x10 || stat == 0x11) { | ||
123 | set_bit(MBX_INTERRUPT, | ||
124 | &ha->mbx_cmd_flags); | ||
125 | |||
126 | mb[0] = RD_REG_WORD(®->mailbox0); | ||
127 | mb[2] = RD_REG_WORD(®->mailbox2); | ||
128 | mb[3] = RD_REG_WORD(®->mailbox3); | ||
129 | |||
130 | WRT_REG_DWORD(®->hccr, | ||
131 | HCCRX_CLR_RISC_INT); | ||
132 | RD_REG_DWORD(®->hccr); | ||
133 | break; | ||
134 | } | ||
135 | |||
136 | /* Clear this intr; it wasn't a mailbox intr */ | ||
137 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | ||
138 | RD_REG_DWORD(®->hccr); | ||
139 | } | ||
140 | udelay(5); | ||
141 | } | ||
142 | |||
143 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | ||
144 | rval = mb[0] & MBS_MASK; | ||
145 | ext_mem[cnt] = htonl((mb[3] << 16) | mb[2]); | ||
146 | } else { | ||
147 | rval = QLA_FUNCTION_FAILED; | ||
148 | } | ||
149 | } | ||
150 | |||
151 | *nxt = rval == QLA_SUCCESS ? &ext_mem[cnt]: NULL; | ||
152 | return rval; | ||
153 | } | ||
154 | |||
40 | /** | 155 | /** |
41 | * qla2300_fw_dump() - Dumps binary data from the 2300 firmware. | 156 | * qla2300_fw_dump() - Dumps binary data from the 2300 firmware. |
42 | * @ha: HA context | 157 | * @ha: HA context |
@@ -633,11 +748,10 @@ void | |||
633 | qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | 748 | qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) |
634 | { | 749 | { |
635 | int rval; | 750 | int rval; |
636 | uint32_t cnt, timer; | 751 | uint32_t cnt; |
637 | uint32_t risc_address; | 752 | uint32_t risc_address; |
638 | uint16_t mb[4], wd; | 753 | uint16_t mb0, wd; |
639 | 754 | ||
640 | uint32_t stat; | ||
641 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 755 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
642 | uint32_t __iomem *dmp_reg; | 756 | uint32_t __iomem *dmp_reg; |
643 | uint32_t *iter_reg; | 757 | uint32_t *iter_reg; |
@@ -645,10 +759,9 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
645 | unsigned long flags; | 759 | unsigned long flags; |
646 | struct qla24xx_fw_dump *fw; | 760 | struct qla24xx_fw_dump *fw; |
647 | uint32_t ext_mem_cnt; | 761 | uint32_t ext_mem_cnt; |
648 | void *eft; | 762 | void *nxt; |
649 | 763 | ||
650 | risc_address = ext_mem_cnt = 0; | 764 | risc_address = ext_mem_cnt = 0; |
651 | memset(mb, 0, sizeof(mb)); | ||
652 | flags = 0; | 765 | flags = 0; |
653 | 766 | ||
654 | if (!hardware_locked) | 767 | if (!hardware_locked) |
@@ -701,250 +814,236 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
701 | /* Shadow registers. */ | 814 | /* Shadow registers. */ |
702 | WRT_REG_DWORD(®->iobase_addr, 0x0F70); | 815 | WRT_REG_DWORD(®->iobase_addr, 0x0F70); |
703 | RD_REG_DWORD(®->iobase_addr); | 816 | RD_REG_DWORD(®->iobase_addr); |
704 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | 817 | WRT_REG_DWORD(®->iobase_select, 0xB0000000); |
705 | WRT_REG_DWORD(dmp_reg, 0xB0000000); | 818 | fw->shadow_reg[0] = htonl(RD_REG_DWORD(®->iobase_sdata)); |
706 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | 819 | |
707 | fw->shadow_reg[0] = htonl(RD_REG_DWORD(dmp_reg)); | 820 | WRT_REG_DWORD(®->iobase_select, 0xB0100000); |
708 | 821 | fw->shadow_reg[1] = htonl(RD_REG_DWORD(®->iobase_sdata)); | |
709 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | 822 | |
710 | WRT_REG_DWORD(dmp_reg, 0xB0100000); | 823 | WRT_REG_DWORD(®->iobase_select, 0xB0200000); |
711 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | 824 | fw->shadow_reg[2] = htonl(RD_REG_DWORD(®->iobase_sdata)); |
712 | fw->shadow_reg[1] = htonl(RD_REG_DWORD(dmp_reg)); | 825 | |
713 | 826 | WRT_REG_DWORD(®->iobase_select, 0xB0300000); | |
714 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | 827 | fw->shadow_reg[3] = htonl(RD_REG_DWORD(®->iobase_sdata)); |
715 | WRT_REG_DWORD(dmp_reg, 0xB0200000); | 828 | |
716 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | 829 | WRT_REG_DWORD(®->iobase_select, 0xB0400000); |
717 | fw->shadow_reg[2] = htonl(RD_REG_DWORD(dmp_reg)); | 830 | fw->shadow_reg[4] = htonl(RD_REG_DWORD(®->iobase_sdata)); |
718 | 831 | ||
719 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | 832 | WRT_REG_DWORD(®->iobase_select, 0xB0500000); |
720 | WRT_REG_DWORD(dmp_reg, 0xB0300000); | 833 | fw->shadow_reg[5] = htonl(RD_REG_DWORD(®->iobase_sdata)); |
721 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | 834 | |
722 | fw->shadow_reg[3] = htonl(RD_REG_DWORD(dmp_reg)); | 835 | WRT_REG_DWORD(®->iobase_select, 0xB0600000); |
723 | 836 | fw->shadow_reg[6] = htonl(RD_REG_DWORD(®->iobase_sdata)); | |
724 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | ||
725 | WRT_REG_DWORD(dmp_reg, 0xB0400000); | ||
726 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | ||
727 | fw->shadow_reg[4] = htonl(RD_REG_DWORD(dmp_reg)); | ||
728 | |||
729 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | ||
730 | WRT_REG_DWORD(dmp_reg, 0xB0500000); | ||
731 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | ||
732 | fw->shadow_reg[5] = htonl(RD_REG_DWORD(dmp_reg)); | ||
733 | |||
734 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | ||
735 | WRT_REG_DWORD(dmp_reg, 0xB0600000); | ||
736 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | ||
737 | fw->shadow_reg[6] = htonl(RD_REG_DWORD(dmp_reg)); | ||
738 | 837 | ||
739 | /* Mailbox registers. */ | 838 | /* Mailbox registers. */ |
740 | mbx_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 839 | mbx_reg = ®->mailbox0; |
741 | for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) | 840 | for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) |
742 | fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++)); | 841 | fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++)); |
743 | 842 | ||
744 | /* Transfer sequence registers. */ | 843 | /* Transfer sequence registers. */ |
745 | iter_reg = fw->xseq_gp_reg; | 844 | iter_reg = fw->xseq_gp_reg; |
746 | WRT_REG_DWORD(®->iobase_addr, 0xBF00); | 845 | WRT_REG_DWORD(®->iobase_addr, 0xBF00); |
747 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 846 | dmp_reg = ®->iobase_window; |
748 | for (cnt = 0; cnt < 16; cnt++) | 847 | for (cnt = 0; cnt < 16; cnt++) |
749 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 848 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
750 | 849 | ||
751 | WRT_REG_DWORD(®->iobase_addr, 0xBF10); | 850 | WRT_REG_DWORD(®->iobase_addr, 0xBF10); |
752 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 851 | dmp_reg = ®->iobase_window; |
753 | for (cnt = 0; cnt < 16; cnt++) | 852 | for (cnt = 0; cnt < 16; cnt++) |
754 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 853 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
755 | 854 | ||
756 | WRT_REG_DWORD(®->iobase_addr, 0xBF20); | 855 | WRT_REG_DWORD(®->iobase_addr, 0xBF20); |
757 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 856 | dmp_reg = ®->iobase_window; |
758 | for (cnt = 0; cnt < 16; cnt++) | 857 | for (cnt = 0; cnt < 16; cnt++) |
759 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 858 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
760 | 859 | ||
761 | WRT_REG_DWORD(®->iobase_addr, 0xBF30); | 860 | WRT_REG_DWORD(®->iobase_addr, 0xBF30); |
762 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 861 | dmp_reg = ®->iobase_window; |
763 | for (cnt = 0; cnt < 16; cnt++) | 862 | for (cnt = 0; cnt < 16; cnt++) |
764 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 863 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
765 | 864 | ||
766 | WRT_REG_DWORD(®->iobase_addr, 0xBF40); | 865 | WRT_REG_DWORD(®->iobase_addr, 0xBF40); |
767 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 866 | dmp_reg = ®->iobase_window; |
768 | for (cnt = 0; cnt < 16; cnt++) | 867 | for (cnt = 0; cnt < 16; cnt++) |
769 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 868 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
770 | 869 | ||
771 | WRT_REG_DWORD(®->iobase_addr, 0xBF50); | 870 | WRT_REG_DWORD(®->iobase_addr, 0xBF50); |
772 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 871 | dmp_reg = ®->iobase_window; |
773 | for (cnt = 0; cnt < 16; cnt++) | 872 | for (cnt = 0; cnt < 16; cnt++) |
774 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 873 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
775 | 874 | ||
776 | WRT_REG_DWORD(®->iobase_addr, 0xBF60); | 875 | WRT_REG_DWORD(®->iobase_addr, 0xBF60); |
777 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 876 | dmp_reg = ®->iobase_window; |
778 | for (cnt = 0; cnt < 16; cnt++) | 877 | for (cnt = 0; cnt < 16; cnt++) |
779 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 878 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
780 | 879 | ||
781 | WRT_REG_DWORD(®->iobase_addr, 0xBF70); | 880 | WRT_REG_DWORD(®->iobase_addr, 0xBF70); |
782 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 881 | dmp_reg = ®->iobase_window; |
783 | for (cnt = 0; cnt < 16; cnt++) | 882 | for (cnt = 0; cnt < 16; cnt++) |
784 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 883 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
785 | 884 | ||
786 | WRT_REG_DWORD(®->iobase_addr, 0xBFE0); | 885 | WRT_REG_DWORD(®->iobase_addr, 0xBFE0); |
787 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 886 | dmp_reg = ®->iobase_window; |
788 | for (cnt = 0; cnt < sizeof(fw->xseq_0_reg) / 4; cnt++) | 887 | for (cnt = 0; cnt < sizeof(fw->xseq_0_reg) / 4; cnt++) |
789 | fw->xseq_0_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); | 888 | fw->xseq_0_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); |
790 | 889 | ||
791 | WRT_REG_DWORD(®->iobase_addr, 0xBFF0); | 890 | WRT_REG_DWORD(®->iobase_addr, 0xBFF0); |
792 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 891 | dmp_reg = ®->iobase_window; |
793 | for (cnt = 0; cnt < sizeof(fw->xseq_1_reg) / 4; cnt++) | 892 | for (cnt = 0; cnt < sizeof(fw->xseq_1_reg) / 4; cnt++) |
794 | fw->xseq_1_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); | 893 | fw->xseq_1_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); |
795 | 894 | ||
796 | /* Receive sequence registers. */ | 895 | /* Receive sequence registers. */ |
797 | iter_reg = fw->rseq_gp_reg; | 896 | iter_reg = fw->rseq_gp_reg; |
798 | WRT_REG_DWORD(®->iobase_addr, 0xFF00); | 897 | WRT_REG_DWORD(®->iobase_addr, 0xFF00); |
799 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 898 | dmp_reg = ®->iobase_window; |
800 | for (cnt = 0; cnt < 16; cnt++) | 899 | for (cnt = 0; cnt < 16; cnt++) |
801 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 900 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
802 | 901 | ||
803 | WRT_REG_DWORD(®->iobase_addr, 0xFF10); | 902 | WRT_REG_DWORD(®->iobase_addr, 0xFF10); |
804 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 903 | dmp_reg = ®->iobase_window; |
805 | for (cnt = 0; cnt < 16; cnt++) | 904 | for (cnt = 0; cnt < 16; cnt++) |
806 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 905 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
807 | 906 | ||
808 | WRT_REG_DWORD(®->iobase_addr, 0xFF20); | 907 | WRT_REG_DWORD(®->iobase_addr, 0xFF20); |
809 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 908 | dmp_reg = ®->iobase_window; |
810 | for (cnt = 0; cnt < 16; cnt++) | 909 | for (cnt = 0; cnt < 16; cnt++) |
811 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 910 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
812 | 911 | ||
813 | WRT_REG_DWORD(®->iobase_addr, 0xFF30); | 912 | WRT_REG_DWORD(®->iobase_addr, 0xFF30); |
814 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 913 | dmp_reg = ®->iobase_window; |
815 | for (cnt = 0; cnt < 16; cnt++) | 914 | for (cnt = 0; cnt < 16; cnt++) |
816 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 915 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
817 | 916 | ||
818 | WRT_REG_DWORD(®->iobase_addr, 0xFF40); | 917 | WRT_REG_DWORD(®->iobase_addr, 0xFF40); |
819 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 918 | dmp_reg = ®->iobase_window; |
820 | for (cnt = 0; cnt < 16; cnt++) | 919 | for (cnt = 0; cnt < 16; cnt++) |
821 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 920 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
822 | 921 | ||
823 | WRT_REG_DWORD(®->iobase_addr, 0xFF50); | 922 | WRT_REG_DWORD(®->iobase_addr, 0xFF50); |
824 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 923 | dmp_reg = ®->iobase_window; |
825 | for (cnt = 0; cnt < 16; cnt++) | 924 | for (cnt = 0; cnt < 16; cnt++) |
826 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 925 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
827 | 926 | ||
828 | WRT_REG_DWORD(®->iobase_addr, 0xFF60); | 927 | WRT_REG_DWORD(®->iobase_addr, 0xFF60); |
829 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 928 | dmp_reg = ®->iobase_window; |
830 | for (cnt = 0; cnt < 16; cnt++) | 929 | for (cnt = 0; cnt < 16; cnt++) |
831 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 930 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
832 | 931 | ||
833 | WRT_REG_DWORD(®->iobase_addr, 0xFF70); | 932 | WRT_REG_DWORD(®->iobase_addr, 0xFF70); |
834 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 933 | dmp_reg = ®->iobase_window; |
835 | for (cnt = 0; cnt < 16; cnt++) | 934 | for (cnt = 0; cnt < 16; cnt++) |
836 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 935 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
837 | 936 | ||
838 | WRT_REG_DWORD(®->iobase_addr, 0xFFD0); | 937 | WRT_REG_DWORD(®->iobase_addr, 0xFFD0); |
839 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 938 | dmp_reg = ®->iobase_window; |
840 | for (cnt = 0; cnt < sizeof(fw->rseq_0_reg) / 4; cnt++) | 939 | for (cnt = 0; cnt < sizeof(fw->rseq_0_reg) / 4; cnt++) |
841 | fw->rseq_0_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); | 940 | fw->rseq_0_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); |
842 | 941 | ||
843 | WRT_REG_DWORD(®->iobase_addr, 0xFFE0); | 942 | WRT_REG_DWORD(®->iobase_addr, 0xFFE0); |
844 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 943 | dmp_reg = ®->iobase_window; |
845 | for (cnt = 0; cnt < sizeof(fw->rseq_1_reg) / 4; cnt++) | 944 | for (cnt = 0; cnt < sizeof(fw->rseq_1_reg) / 4; cnt++) |
846 | fw->rseq_1_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); | 945 | fw->rseq_1_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); |
847 | 946 | ||
848 | WRT_REG_DWORD(®->iobase_addr, 0xFFF0); | 947 | WRT_REG_DWORD(®->iobase_addr, 0xFFF0); |
849 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 948 | dmp_reg = ®->iobase_window; |
850 | for (cnt = 0; cnt < sizeof(fw->rseq_2_reg) / 4; cnt++) | 949 | for (cnt = 0; cnt < sizeof(fw->rseq_2_reg) / 4; cnt++) |
851 | fw->rseq_2_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); | 950 | fw->rseq_2_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); |
852 | 951 | ||
853 | /* Command DMA registers. */ | 952 | /* Command DMA registers. */ |
854 | WRT_REG_DWORD(®->iobase_addr, 0x7100); | 953 | WRT_REG_DWORD(®->iobase_addr, 0x7100); |
855 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 954 | dmp_reg = ®->iobase_window; |
856 | for (cnt = 0; cnt < sizeof(fw->cmd_dma_reg) / 4; cnt++) | 955 | for (cnt = 0; cnt < sizeof(fw->cmd_dma_reg) / 4; cnt++) |
857 | fw->cmd_dma_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); | 956 | fw->cmd_dma_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); |
858 | 957 | ||
859 | /* Queues. */ | 958 | /* Queues. */ |
860 | iter_reg = fw->req0_dma_reg; | 959 | iter_reg = fw->req0_dma_reg; |
861 | WRT_REG_DWORD(®->iobase_addr, 0x7200); | 960 | WRT_REG_DWORD(®->iobase_addr, 0x7200); |
862 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 961 | dmp_reg = ®->iobase_window; |
863 | for (cnt = 0; cnt < 8; cnt++) | 962 | for (cnt = 0; cnt < 8; cnt++) |
864 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 963 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
865 | 964 | ||
866 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4); | 965 | dmp_reg = ®->iobase_q; |
867 | for (cnt = 0; cnt < 7; cnt++) | 966 | for (cnt = 0; cnt < 7; cnt++) |
868 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 967 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
869 | 968 | ||
870 | iter_reg = fw->resp0_dma_reg; | 969 | iter_reg = fw->resp0_dma_reg; |
871 | WRT_REG_DWORD(®->iobase_addr, 0x7300); | 970 | WRT_REG_DWORD(®->iobase_addr, 0x7300); |
872 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 971 | dmp_reg = ®->iobase_window; |
873 | for (cnt = 0; cnt < 8; cnt++) | 972 | for (cnt = 0; cnt < 8; cnt++) |
874 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 973 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
875 | 974 | ||
876 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4); | 975 | dmp_reg = ®->iobase_q; |
877 | for (cnt = 0; cnt < 7; cnt++) | 976 | for (cnt = 0; cnt < 7; cnt++) |
878 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 977 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
879 | 978 | ||
880 | iter_reg = fw->req1_dma_reg; | 979 | iter_reg = fw->req1_dma_reg; |
881 | WRT_REG_DWORD(®->iobase_addr, 0x7400); | 980 | WRT_REG_DWORD(®->iobase_addr, 0x7400); |
882 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 981 | dmp_reg = ®->iobase_window; |
883 | for (cnt = 0; cnt < 8; cnt++) | 982 | for (cnt = 0; cnt < 8; cnt++) |
884 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 983 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
885 | 984 | ||
886 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4); | 985 | dmp_reg = ®->iobase_q; |
887 | for (cnt = 0; cnt < 7; cnt++) | 986 | for (cnt = 0; cnt < 7; cnt++) |
888 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 987 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
889 | 988 | ||
890 | /* Transmit DMA registers. */ | 989 | /* Transmit DMA registers. */ |
891 | iter_reg = fw->xmt0_dma_reg; | 990 | iter_reg = fw->xmt0_dma_reg; |
892 | WRT_REG_DWORD(®->iobase_addr, 0x7600); | 991 | WRT_REG_DWORD(®->iobase_addr, 0x7600); |
893 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 992 | dmp_reg = ®->iobase_window; |
894 | for (cnt = 0; cnt < 16; cnt++) | 993 | for (cnt = 0; cnt < 16; cnt++) |
895 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 994 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
896 | 995 | ||
897 | WRT_REG_DWORD(®->iobase_addr, 0x7610); | 996 | WRT_REG_DWORD(®->iobase_addr, 0x7610); |
898 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 997 | dmp_reg = ®->iobase_window; |
899 | for (cnt = 0; cnt < 16; cnt++) | 998 | for (cnt = 0; cnt < 16; cnt++) |
900 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 999 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
901 | 1000 | ||
902 | iter_reg = fw->xmt1_dma_reg; | 1001 | iter_reg = fw->xmt1_dma_reg; |
903 | WRT_REG_DWORD(®->iobase_addr, 0x7620); | 1002 | WRT_REG_DWORD(®->iobase_addr, 0x7620); |
904 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1003 | dmp_reg = ®->iobase_window; |
905 | for (cnt = 0; cnt < 16; cnt++) | 1004 | for (cnt = 0; cnt < 16; cnt++) |
906 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1005 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
907 | 1006 | ||
908 | WRT_REG_DWORD(®->iobase_addr, 0x7630); | 1007 | WRT_REG_DWORD(®->iobase_addr, 0x7630); |
909 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1008 | dmp_reg = ®->iobase_window; |
910 | for (cnt = 0; cnt < 16; cnt++) | 1009 | for (cnt = 0; cnt < 16; cnt++) |
911 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1010 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
912 | 1011 | ||
913 | iter_reg = fw->xmt2_dma_reg; | 1012 | iter_reg = fw->xmt2_dma_reg; |
914 | WRT_REG_DWORD(®->iobase_addr, 0x7640); | 1013 | WRT_REG_DWORD(®->iobase_addr, 0x7640); |
915 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1014 | dmp_reg = ®->iobase_window; |
916 | for (cnt = 0; cnt < 16; cnt++) | 1015 | for (cnt = 0; cnt < 16; cnt++) |
917 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1016 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
918 | 1017 | ||
919 | WRT_REG_DWORD(®->iobase_addr, 0x7650); | 1018 | WRT_REG_DWORD(®->iobase_addr, 0x7650); |
920 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1019 | dmp_reg = ®->iobase_window; |
921 | for (cnt = 0; cnt < 16; cnt++) | 1020 | for (cnt = 0; cnt < 16; cnt++) |
922 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1021 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
923 | 1022 | ||
924 | iter_reg = fw->xmt3_dma_reg; | 1023 | iter_reg = fw->xmt3_dma_reg; |
925 | WRT_REG_DWORD(®->iobase_addr, 0x7660); | 1024 | WRT_REG_DWORD(®->iobase_addr, 0x7660); |
926 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1025 | dmp_reg = ®->iobase_window; |
927 | for (cnt = 0; cnt < 16; cnt++) | 1026 | for (cnt = 0; cnt < 16; cnt++) |
928 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1027 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
929 | 1028 | ||
930 | WRT_REG_DWORD(®->iobase_addr, 0x7670); | 1029 | WRT_REG_DWORD(®->iobase_addr, 0x7670); |
931 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1030 | dmp_reg = ®->iobase_window; |
932 | for (cnt = 0; cnt < 16; cnt++) | 1031 | for (cnt = 0; cnt < 16; cnt++) |
933 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1032 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
934 | 1033 | ||
935 | iter_reg = fw->xmt4_dma_reg; | 1034 | iter_reg = fw->xmt4_dma_reg; |
936 | WRT_REG_DWORD(®->iobase_addr, 0x7680); | 1035 | WRT_REG_DWORD(®->iobase_addr, 0x7680); |
937 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1036 | dmp_reg = ®->iobase_window; |
938 | for (cnt = 0; cnt < 16; cnt++) | 1037 | for (cnt = 0; cnt < 16; cnt++) |
939 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1038 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
940 | 1039 | ||
941 | WRT_REG_DWORD(®->iobase_addr, 0x7690); | 1040 | WRT_REG_DWORD(®->iobase_addr, 0x7690); |
942 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1041 | dmp_reg = ®->iobase_window; |
943 | for (cnt = 0; cnt < 16; cnt++) | 1042 | for (cnt = 0; cnt < 16; cnt++) |
944 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1043 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
945 | 1044 | ||
946 | WRT_REG_DWORD(®->iobase_addr, 0x76A0); | 1045 | WRT_REG_DWORD(®->iobase_addr, 0x76A0); |
947 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1046 | dmp_reg = ®->iobase_window; |
948 | for (cnt = 0; cnt < sizeof(fw->xmt_data_dma_reg) / 4; cnt++) | 1047 | for (cnt = 0; cnt < sizeof(fw->xmt_data_dma_reg) / 4; cnt++) |
949 | fw->xmt_data_dma_reg[cnt] = | 1048 | fw->xmt_data_dma_reg[cnt] = |
950 | htonl(RD_REG_DWORD(dmp_reg++)); | 1049 | htonl(RD_REG_DWORD(dmp_reg++)); |
@@ -952,221 +1051,221 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
952 | /* Receive DMA registers. */ | 1051 | /* Receive DMA registers. */ |
953 | iter_reg = fw->rcvt0_data_dma_reg; | 1052 | iter_reg = fw->rcvt0_data_dma_reg; |
954 | WRT_REG_DWORD(®->iobase_addr, 0x7700); | 1053 | WRT_REG_DWORD(®->iobase_addr, 0x7700); |
955 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1054 | dmp_reg = ®->iobase_window; |
956 | for (cnt = 0; cnt < 16; cnt++) | 1055 | for (cnt = 0; cnt < 16; cnt++) |
957 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1056 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
958 | 1057 | ||
959 | WRT_REG_DWORD(®->iobase_addr, 0x7710); | 1058 | WRT_REG_DWORD(®->iobase_addr, 0x7710); |
960 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1059 | dmp_reg = ®->iobase_window; |
961 | for (cnt = 0; cnt < 16; cnt++) | 1060 | for (cnt = 0; cnt < 16; cnt++) |
962 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1061 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
963 | 1062 | ||
964 | iter_reg = fw->rcvt1_data_dma_reg; | 1063 | iter_reg = fw->rcvt1_data_dma_reg; |
965 | WRT_REG_DWORD(®->iobase_addr, 0x7720); | 1064 | WRT_REG_DWORD(®->iobase_addr, 0x7720); |
966 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1065 | dmp_reg = ®->iobase_window; |
967 | for (cnt = 0; cnt < 16; cnt++) | 1066 | for (cnt = 0; cnt < 16; cnt++) |
968 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1067 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
969 | 1068 | ||
970 | WRT_REG_DWORD(®->iobase_addr, 0x7730); | 1069 | WRT_REG_DWORD(®->iobase_addr, 0x7730); |
971 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1070 | dmp_reg = ®->iobase_window; |
972 | for (cnt = 0; cnt < 16; cnt++) | 1071 | for (cnt = 0; cnt < 16; cnt++) |
973 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1072 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
974 | 1073 | ||
975 | /* RISC registers. */ | 1074 | /* RISC registers. */ |
976 | iter_reg = fw->risc_gp_reg; | 1075 | iter_reg = fw->risc_gp_reg; |
977 | WRT_REG_DWORD(®->iobase_addr, 0x0F00); | 1076 | WRT_REG_DWORD(®->iobase_addr, 0x0F00); |
978 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1077 | dmp_reg = ®->iobase_window; |
979 | for (cnt = 0; cnt < 16; cnt++) | 1078 | for (cnt = 0; cnt < 16; cnt++) |
980 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1079 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
981 | 1080 | ||
982 | WRT_REG_DWORD(®->iobase_addr, 0x0F10); | 1081 | WRT_REG_DWORD(®->iobase_addr, 0x0F10); |
983 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1082 | dmp_reg = ®->iobase_window; |
984 | for (cnt = 0; cnt < 16; cnt++) | 1083 | for (cnt = 0; cnt < 16; cnt++) |
985 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1084 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
986 | 1085 | ||
987 | WRT_REG_DWORD(®->iobase_addr, 0x0F20); | 1086 | WRT_REG_DWORD(®->iobase_addr, 0x0F20); |
988 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1087 | dmp_reg = ®->iobase_window; |
989 | for (cnt = 0; cnt < 16; cnt++) | 1088 | for (cnt = 0; cnt < 16; cnt++) |
990 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1089 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
991 | 1090 | ||
992 | WRT_REG_DWORD(®->iobase_addr, 0x0F30); | 1091 | WRT_REG_DWORD(®->iobase_addr, 0x0F30); |
993 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1092 | dmp_reg = ®->iobase_window; |
994 | for (cnt = 0; cnt < 16; cnt++) | 1093 | for (cnt = 0; cnt < 16; cnt++) |
995 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1094 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
996 | 1095 | ||
997 | WRT_REG_DWORD(®->iobase_addr, 0x0F40); | 1096 | WRT_REG_DWORD(®->iobase_addr, 0x0F40); |
998 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1097 | dmp_reg = ®->iobase_window; |
999 | for (cnt = 0; cnt < 16; cnt++) | 1098 | for (cnt = 0; cnt < 16; cnt++) |
1000 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1099 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1001 | 1100 | ||
1002 | WRT_REG_DWORD(®->iobase_addr, 0x0F50); | 1101 | WRT_REG_DWORD(®->iobase_addr, 0x0F50); |
1003 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1102 | dmp_reg = ®->iobase_window; |
1004 | for (cnt = 0; cnt < 16; cnt++) | 1103 | for (cnt = 0; cnt < 16; cnt++) |
1005 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1104 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1006 | 1105 | ||
1007 | WRT_REG_DWORD(®->iobase_addr, 0x0F60); | 1106 | WRT_REG_DWORD(®->iobase_addr, 0x0F60); |
1008 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1107 | dmp_reg = ®->iobase_window; |
1009 | for (cnt = 0; cnt < 16; cnt++) | 1108 | for (cnt = 0; cnt < 16; cnt++) |
1010 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1109 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1011 | 1110 | ||
1012 | WRT_REG_DWORD(®->iobase_addr, 0x0F70); | 1111 | WRT_REG_DWORD(®->iobase_addr, 0x0F70); |
1013 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1112 | dmp_reg = ®->iobase_window; |
1014 | for (cnt = 0; cnt < 16; cnt++) | 1113 | for (cnt = 0; cnt < 16; cnt++) |
1015 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1114 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1016 | 1115 | ||
1017 | /* Local memory controller registers. */ | 1116 | /* Local memory controller registers. */ |
1018 | iter_reg = fw->lmc_reg; | 1117 | iter_reg = fw->lmc_reg; |
1019 | WRT_REG_DWORD(®->iobase_addr, 0x3000); | 1118 | WRT_REG_DWORD(®->iobase_addr, 0x3000); |
1020 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1119 | dmp_reg = ®->iobase_window; |
1021 | for (cnt = 0; cnt < 16; cnt++) | 1120 | for (cnt = 0; cnt < 16; cnt++) |
1022 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1121 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1023 | 1122 | ||
1024 | WRT_REG_DWORD(®->iobase_addr, 0x3010); | 1123 | WRT_REG_DWORD(®->iobase_addr, 0x3010); |
1025 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1124 | dmp_reg = ®->iobase_window; |
1026 | for (cnt = 0; cnt < 16; cnt++) | 1125 | for (cnt = 0; cnt < 16; cnt++) |
1027 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1126 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1028 | 1127 | ||
1029 | WRT_REG_DWORD(®->iobase_addr, 0x3020); | 1128 | WRT_REG_DWORD(®->iobase_addr, 0x3020); |
1030 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1129 | dmp_reg = ®->iobase_window; |
1031 | for (cnt = 0; cnt < 16; cnt++) | 1130 | for (cnt = 0; cnt < 16; cnt++) |
1032 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1131 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1033 | 1132 | ||
1034 | WRT_REG_DWORD(®->iobase_addr, 0x3030); | 1133 | WRT_REG_DWORD(®->iobase_addr, 0x3030); |
1035 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1134 | dmp_reg = ®->iobase_window; |
1036 | for (cnt = 0; cnt < 16; cnt++) | 1135 | for (cnt = 0; cnt < 16; cnt++) |
1037 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1136 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1038 | 1137 | ||
1039 | WRT_REG_DWORD(®->iobase_addr, 0x3040); | 1138 | WRT_REG_DWORD(®->iobase_addr, 0x3040); |
1040 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1139 | dmp_reg = ®->iobase_window; |
1041 | for (cnt = 0; cnt < 16; cnt++) | 1140 | for (cnt = 0; cnt < 16; cnt++) |
1042 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1141 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1043 | 1142 | ||
1044 | WRT_REG_DWORD(®->iobase_addr, 0x3050); | 1143 | WRT_REG_DWORD(®->iobase_addr, 0x3050); |
1045 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1144 | dmp_reg = ®->iobase_window; |
1046 | for (cnt = 0; cnt < 16; cnt++) | 1145 | for (cnt = 0; cnt < 16; cnt++) |
1047 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1146 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1048 | 1147 | ||
1049 | WRT_REG_DWORD(®->iobase_addr, 0x3060); | 1148 | WRT_REG_DWORD(®->iobase_addr, 0x3060); |
1050 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1149 | dmp_reg = ®->iobase_window; |
1051 | for (cnt = 0; cnt < 16; cnt++) | 1150 | for (cnt = 0; cnt < 16; cnt++) |
1052 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1151 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1053 | 1152 | ||
1054 | /* Fibre Protocol Module registers. */ | 1153 | /* Fibre Protocol Module registers. */ |
1055 | iter_reg = fw->fpm_hdw_reg; | 1154 | iter_reg = fw->fpm_hdw_reg; |
1056 | WRT_REG_DWORD(®->iobase_addr, 0x4000); | 1155 | WRT_REG_DWORD(®->iobase_addr, 0x4000); |
1057 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1156 | dmp_reg = ®->iobase_window; |
1058 | for (cnt = 0; cnt < 16; cnt++) | 1157 | for (cnt = 0; cnt < 16; cnt++) |
1059 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1158 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1060 | 1159 | ||
1061 | WRT_REG_DWORD(®->iobase_addr, 0x4010); | 1160 | WRT_REG_DWORD(®->iobase_addr, 0x4010); |
1062 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1161 | dmp_reg = ®->iobase_window; |
1063 | for (cnt = 0; cnt < 16; cnt++) | 1162 | for (cnt = 0; cnt < 16; cnt++) |
1064 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1163 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1065 | 1164 | ||
1066 | WRT_REG_DWORD(®->iobase_addr, 0x4020); | 1165 | WRT_REG_DWORD(®->iobase_addr, 0x4020); |
1067 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1166 | dmp_reg = ®->iobase_window; |
1068 | for (cnt = 0; cnt < 16; cnt++) | 1167 | for (cnt = 0; cnt < 16; cnt++) |
1069 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1168 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1070 | 1169 | ||
1071 | WRT_REG_DWORD(®->iobase_addr, 0x4030); | 1170 | WRT_REG_DWORD(®->iobase_addr, 0x4030); |
1072 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1171 | dmp_reg = ®->iobase_window; |
1073 | for (cnt = 0; cnt < 16; cnt++) | 1172 | for (cnt = 0; cnt < 16; cnt++) |
1074 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1173 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1075 | 1174 | ||
1076 | WRT_REG_DWORD(®->iobase_addr, 0x4040); | 1175 | WRT_REG_DWORD(®->iobase_addr, 0x4040); |
1077 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1176 | dmp_reg = ®->iobase_window; |
1078 | for (cnt = 0; cnt < 16; cnt++) | 1177 | for (cnt = 0; cnt < 16; cnt++) |
1079 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1178 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1080 | 1179 | ||
1081 | WRT_REG_DWORD(®->iobase_addr, 0x4050); | 1180 | WRT_REG_DWORD(®->iobase_addr, 0x4050); |
1082 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1181 | dmp_reg = ®->iobase_window; |
1083 | for (cnt = 0; cnt < 16; cnt++) | 1182 | for (cnt = 0; cnt < 16; cnt++) |
1084 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1183 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1085 | 1184 | ||
1086 | WRT_REG_DWORD(®->iobase_addr, 0x4060); | 1185 | WRT_REG_DWORD(®->iobase_addr, 0x4060); |
1087 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1186 | dmp_reg = ®->iobase_window; |
1088 | for (cnt = 0; cnt < 16; cnt++) | 1187 | for (cnt = 0; cnt < 16; cnt++) |
1089 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1188 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1090 | 1189 | ||
1091 | WRT_REG_DWORD(®->iobase_addr, 0x4070); | 1190 | WRT_REG_DWORD(®->iobase_addr, 0x4070); |
1092 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1191 | dmp_reg = ®->iobase_window; |
1093 | for (cnt = 0; cnt < 16; cnt++) | 1192 | for (cnt = 0; cnt < 16; cnt++) |
1094 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1193 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1095 | 1194 | ||
1096 | WRT_REG_DWORD(®->iobase_addr, 0x4080); | 1195 | WRT_REG_DWORD(®->iobase_addr, 0x4080); |
1097 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1196 | dmp_reg = ®->iobase_window; |
1098 | for (cnt = 0; cnt < 16; cnt++) | 1197 | for (cnt = 0; cnt < 16; cnt++) |
1099 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1198 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1100 | 1199 | ||
1101 | WRT_REG_DWORD(®->iobase_addr, 0x4090); | 1200 | WRT_REG_DWORD(®->iobase_addr, 0x4090); |
1102 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1201 | dmp_reg = ®->iobase_window; |
1103 | for (cnt = 0; cnt < 16; cnt++) | 1202 | for (cnt = 0; cnt < 16; cnt++) |
1104 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1203 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1105 | 1204 | ||
1106 | WRT_REG_DWORD(®->iobase_addr, 0x40A0); | 1205 | WRT_REG_DWORD(®->iobase_addr, 0x40A0); |
1107 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1206 | dmp_reg = ®->iobase_window; |
1108 | for (cnt = 0; cnt < 16; cnt++) | 1207 | for (cnt = 0; cnt < 16; cnt++) |
1109 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1208 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1110 | 1209 | ||
1111 | WRT_REG_DWORD(®->iobase_addr, 0x40B0); | 1210 | WRT_REG_DWORD(®->iobase_addr, 0x40B0); |
1112 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1211 | dmp_reg = ®->iobase_window; |
1113 | for (cnt = 0; cnt < 16; cnt++) | 1212 | for (cnt = 0; cnt < 16; cnt++) |
1114 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1213 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1115 | 1214 | ||
1116 | /* Frame Buffer registers. */ | 1215 | /* Frame Buffer registers. */ |
1117 | iter_reg = fw->fb_hdw_reg; | 1216 | iter_reg = fw->fb_hdw_reg; |
1118 | WRT_REG_DWORD(®->iobase_addr, 0x6000); | 1217 | WRT_REG_DWORD(®->iobase_addr, 0x6000); |
1119 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1218 | dmp_reg = ®->iobase_window; |
1120 | for (cnt = 0; cnt < 16; cnt++) | 1219 | for (cnt = 0; cnt < 16; cnt++) |
1121 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1220 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1122 | 1221 | ||
1123 | WRT_REG_DWORD(®->iobase_addr, 0x6010); | 1222 | WRT_REG_DWORD(®->iobase_addr, 0x6010); |
1124 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1223 | dmp_reg = ®->iobase_window; |
1125 | for (cnt = 0; cnt < 16; cnt++) | 1224 | for (cnt = 0; cnt < 16; cnt++) |
1126 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1225 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1127 | 1226 | ||
1128 | WRT_REG_DWORD(®->iobase_addr, 0x6020); | 1227 | WRT_REG_DWORD(®->iobase_addr, 0x6020); |
1129 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1228 | dmp_reg = ®->iobase_window; |
1130 | for (cnt = 0; cnt < 16; cnt++) | 1229 | for (cnt = 0; cnt < 16; cnt++) |
1131 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1230 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1132 | 1231 | ||
1133 | WRT_REG_DWORD(®->iobase_addr, 0x6030); | 1232 | WRT_REG_DWORD(®->iobase_addr, 0x6030); |
1134 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1233 | dmp_reg = ®->iobase_window; |
1135 | for (cnt = 0; cnt < 16; cnt++) | 1234 | for (cnt = 0; cnt < 16; cnt++) |
1136 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1235 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1137 | 1236 | ||
1138 | WRT_REG_DWORD(®->iobase_addr, 0x6040); | 1237 | WRT_REG_DWORD(®->iobase_addr, 0x6040); |
1139 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1238 | dmp_reg = ®->iobase_window; |
1140 | for (cnt = 0; cnt < 16; cnt++) | 1239 | for (cnt = 0; cnt < 16; cnt++) |
1141 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1240 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1142 | 1241 | ||
1143 | WRT_REG_DWORD(®->iobase_addr, 0x6100); | 1242 | WRT_REG_DWORD(®->iobase_addr, 0x6100); |
1144 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1243 | dmp_reg = ®->iobase_window; |
1145 | for (cnt = 0; cnt < 16; cnt++) | 1244 | for (cnt = 0; cnt < 16; cnt++) |
1146 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1245 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1147 | 1246 | ||
1148 | WRT_REG_DWORD(®->iobase_addr, 0x6130); | 1247 | WRT_REG_DWORD(®->iobase_addr, 0x6130); |
1149 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1248 | dmp_reg = ®->iobase_window; |
1150 | for (cnt = 0; cnt < 16; cnt++) | 1249 | for (cnt = 0; cnt < 16; cnt++) |
1151 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1250 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1152 | 1251 | ||
1153 | WRT_REG_DWORD(®->iobase_addr, 0x6150); | 1252 | WRT_REG_DWORD(®->iobase_addr, 0x6150); |
1154 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1253 | dmp_reg = ®->iobase_window; |
1155 | for (cnt = 0; cnt < 16; cnt++) | 1254 | for (cnt = 0; cnt < 16; cnt++) |
1156 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1255 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1157 | 1256 | ||
1158 | WRT_REG_DWORD(®->iobase_addr, 0x6170); | 1257 | WRT_REG_DWORD(®->iobase_addr, 0x6170); |
1159 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1258 | dmp_reg = ®->iobase_window; |
1160 | for (cnt = 0; cnt < 16; cnt++) | 1259 | for (cnt = 0; cnt < 16; cnt++) |
1161 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1260 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1162 | 1261 | ||
1163 | WRT_REG_DWORD(®->iobase_addr, 0x6190); | 1262 | WRT_REG_DWORD(®->iobase_addr, 0x6190); |
1164 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1263 | dmp_reg = ®->iobase_window; |
1165 | for (cnt = 0; cnt < 16; cnt++) | 1264 | for (cnt = 0; cnt < 16; cnt++) |
1166 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1265 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1167 | 1266 | ||
1168 | WRT_REG_DWORD(®->iobase_addr, 0x61B0); | 1267 | WRT_REG_DWORD(®->iobase_addr, 0x61B0); |
1169 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1268 | dmp_reg = ®->iobase_window; |
1170 | for (cnt = 0; cnt < 16; cnt++) | 1269 | for (cnt = 0; cnt < 16; cnt++) |
1171 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1270 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1172 | 1271 | ||
@@ -1187,10 +1286,10 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
1187 | 1286 | ||
1188 | udelay(100); | 1287 | udelay(100); |
1189 | /* Wait for firmware to complete NVRAM accesses. */ | 1288 | /* Wait for firmware to complete NVRAM accesses. */ |
1190 | mb[0] = (uint32_t) RD_REG_WORD(®->mailbox0); | 1289 | mb0 = (uint32_t) RD_REG_WORD(®->mailbox0); |
1191 | for (cnt = 10000 ; cnt && mb[0]; cnt--) { | 1290 | for (cnt = 10000 ; cnt && mb0; cnt--) { |
1192 | udelay(5); | 1291 | udelay(5); |
1193 | mb[0] = (uint32_t) RD_REG_WORD(®->mailbox0); | 1292 | mb0 = (uint32_t) RD_REG_WORD(®->mailbox0); |
1194 | barrier(); | 1293 | barrier(); |
1195 | } | 1294 | } |
1196 | 1295 | ||
@@ -1214,110 +1313,717 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
1214 | rval = QLA_FUNCTION_TIMEOUT; | 1313 | rval = QLA_FUNCTION_TIMEOUT; |
1215 | } | 1314 | } |
1216 | 1315 | ||
1217 | /* Memory. */ | 1316 | if (rval == QLA_SUCCESS) |
1317 | rval = qla2xxx_dump_memory(ha, fw->code_ram, | ||
1318 | sizeof(fw->code_ram), fw->ext_mem, &nxt); | ||
1319 | |||
1218 | if (rval == QLA_SUCCESS) { | 1320 | if (rval == QLA_SUCCESS) { |
1219 | /* Code RAM. */ | 1321 | nxt = qla2xxx_copy_queues(ha, nxt); |
1220 | risc_address = 0x20000; | 1322 | if (ha->eft) |
1221 | WRT_REG_WORD(®->mailbox0, MBC_READ_RAM_EXTENDED); | 1323 | memcpy(nxt, ha->eft, ntohl(ha->fw_dump->eft_size)); |
1222 | clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | ||
1223 | } | 1324 | } |
1224 | for (cnt = 0; cnt < sizeof(fw->code_ram) / 4 && rval == QLA_SUCCESS; | ||
1225 | cnt++, risc_address++) { | ||
1226 | WRT_REG_WORD(®->mailbox1, LSW(risc_address)); | ||
1227 | WRT_REG_WORD(®->mailbox8, MSW(risc_address)); | ||
1228 | RD_REG_WORD(®->mailbox8); | ||
1229 | WRT_REG_DWORD(®->hccr, HCCRX_SET_HOST_INT); | ||
1230 | 1325 | ||
1231 | for (timer = 6000000; timer; timer--) { | 1326 | if (rval != QLA_SUCCESS) { |
1232 | /* Check for pending interrupts. */ | 1327 | qla_printk(KERN_WARNING, ha, |
1233 | stat = RD_REG_DWORD(®->host_status); | 1328 | "Failed to dump firmware (%x)!!!\n", rval); |
1234 | if (stat & HSRX_RISC_INT) { | 1329 | ha->fw_dumped = 0; |
1235 | stat &= 0xff; | ||
1236 | 1330 | ||
1237 | if (stat == 0x1 || stat == 0x2 || | 1331 | } else { |
1238 | stat == 0x10 || stat == 0x11) { | 1332 | qla_printk(KERN_INFO, ha, |
1239 | set_bit(MBX_INTERRUPT, | 1333 | "Firmware dump saved to temp buffer (%ld/%p).\n", |
1240 | &ha->mbx_cmd_flags); | 1334 | ha->host_no, ha->fw_dump); |
1335 | ha->fw_dumped = 1; | ||
1336 | } | ||
1241 | 1337 | ||
1242 | mb[0] = RD_REG_WORD(®->mailbox0); | 1338 | qla24xx_fw_dump_failed: |
1243 | mb[2] = RD_REG_WORD(®->mailbox2); | 1339 | if (!hardware_locked) |
1244 | mb[3] = RD_REG_WORD(®->mailbox3); | 1340 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
1341 | } | ||
1245 | 1342 | ||
1246 | WRT_REG_DWORD(®->hccr, | 1343 | void |
1247 | HCCRX_CLR_RISC_INT); | 1344 | qla25xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) |
1248 | RD_REG_DWORD(®->hccr); | 1345 | { |
1249 | break; | 1346 | int rval; |
1250 | } | 1347 | uint32_t cnt; |
1348 | uint32_t risc_address; | ||
1349 | uint16_t mb0, wd; | ||
1251 | 1350 | ||
1252 | /* Clear this intr; it wasn't a mailbox intr */ | 1351 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
1253 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 1352 | uint32_t __iomem *dmp_reg; |
1254 | RD_REG_DWORD(®->hccr); | 1353 | uint32_t *iter_reg; |
1255 | } | 1354 | uint16_t __iomem *mbx_reg; |
1256 | udelay(5); | 1355 | unsigned long flags; |
1257 | } | 1356 | struct qla25xx_fw_dump *fw; |
1357 | uint32_t ext_mem_cnt; | ||
1358 | void *nxt; | ||
1258 | 1359 | ||
1259 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | 1360 | risc_address = ext_mem_cnt = 0; |
1260 | rval = mb[0] & MBS_MASK; | 1361 | flags = 0; |
1261 | fw->code_ram[cnt] = htonl((mb[3] << 16) | mb[2]); | 1362 | |
1262 | } else { | 1363 | if (!hardware_locked) |
1263 | rval = QLA_FUNCTION_FAILED; | 1364 | spin_lock_irqsave(&ha->hardware_lock, flags); |
1365 | |||
1366 | if (!ha->fw_dump) { | ||
1367 | qla_printk(KERN_WARNING, ha, | ||
1368 | "No buffer available for dump!!!\n"); | ||
1369 | goto qla25xx_fw_dump_failed; | ||
1370 | } | ||
1371 | |||
1372 | if (ha->fw_dumped) { | ||
1373 | qla_printk(KERN_WARNING, ha, | ||
1374 | "Firmware has been previously dumped (%p) -- ignoring " | ||
1375 | "request...\n", ha->fw_dump); | ||
1376 | goto qla25xx_fw_dump_failed; | ||
1377 | } | ||
1378 | fw = &ha->fw_dump->isp.isp25; | ||
1379 | qla2xxx_prep_dump(ha, ha->fw_dump); | ||
1380 | |||
1381 | rval = QLA_SUCCESS; | ||
1382 | fw->host_status = htonl(RD_REG_DWORD(®->host_status)); | ||
1383 | |||
1384 | /* Pause RISC. */ | ||
1385 | if ((RD_REG_DWORD(®->hccr) & HCCRX_RISC_PAUSE) == 0) { | ||
1386 | WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_RESET | | ||
1387 | HCCRX_CLR_HOST_INT); | ||
1388 | RD_REG_DWORD(®->hccr); /* PCI Posting. */ | ||
1389 | WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_PAUSE); | ||
1390 | for (cnt = 30000; | ||
1391 | (RD_REG_DWORD(®->hccr) & HCCRX_RISC_PAUSE) == 0 && | ||
1392 | rval == QLA_SUCCESS; cnt--) { | ||
1393 | if (cnt) | ||
1394 | udelay(100); | ||
1395 | else | ||
1396 | rval = QLA_FUNCTION_TIMEOUT; | ||
1264 | } | 1397 | } |
1265 | } | 1398 | } |
1266 | 1399 | ||
1267 | if (rval == QLA_SUCCESS) { | 1400 | if (rval == QLA_SUCCESS) { |
1268 | /* External Memory. */ | 1401 | /* Host interface registers. */ |
1269 | risc_address = 0x100000; | 1402 | dmp_reg = (uint32_t __iomem *)(reg + 0); |
1270 | ext_mem_cnt = ha->fw_memory_size - 0x100000 + 1; | 1403 | for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++) |
1271 | WRT_REG_WORD(®->mailbox0, MBC_READ_RAM_EXTENDED); | 1404 | fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); |
1272 | clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | ||
1273 | } | ||
1274 | for (cnt = 0; cnt < ext_mem_cnt && rval == QLA_SUCCESS; | ||
1275 | cnt++, risc_address++) { | ||
1276 | WRT_REG_WORD(®->mailbox1, LSW(risc_address)); | ||
1277 | WRT_REG_WORD(®->mailbox8, MSW(risc_address)); | ||
1278 | RD_REG_WORD(®->mailbox8); | ||
1279 | WRT_REG_DWORD(®->hccr, HCCRX_SET_HOST_INT); | ||
1280 | 1405 | ||
1281 | for (timer = 6000000; timer; timer--) { | 1406 | /* Disable interrupts. */ |
1282 | /* Check for pending interrupts. */ | 1407 | WRT_REG_DWORD(®->ictrl, 0); |
1283 | stat = RD_REG_DWORD(®->host_status); | 1408 | RD_REG_DWORD(®->ictrl); |
1284 | if (stat & HSRX_RISC_INT) { | ||
1285 | stat &= 0xff; | ||
1286 | 1409 | ||
1287 | if (stat == 0x1 || stat == 0x2 || | 1410 | /* Shadow registers. */ |
1288 | stat == 0x10 || stat == 0x11) { | 1411 | WRT_REG_DWORD(®->iobase_addr, 0x0F70); |
1289 | set_bit(MBX_INTERRUPT, | 1412 | RD_REG_DWORD(®->iobase_addr); |
1290 | &ha->mbx_cmd_flags); | 1413 | WRT_REG_DWORD(®->iobase_select, 0xB0000000); |
1414 | fw->shadow_reg[0] = htonl(RD_REG_DWORD(®->iobase_sdata)); | ||
1291 | 1415 | ||
1292 | mb[0] = RD_REG_WORD(®->mailbox0); | 1416 | WRT_REG_DWORD(®->iobase_select, 0xB0100000); |
1293 | mb[2] = RD_REG_WORD(®->mailbox2); | 1417 | fw->shadow_reg[1] = htonl(RD_REG_DWORD(®->iobase_sdata)); |
1294 | mb[3] = RD_REG_WORD(®->mailbox3); | ||
1295 | 1418 | ||
1296 | WRT_REG_DWORD(®->hccr, | 1419 | WRT_REG_DWORD(®->iobase_select, 0xB0200000); |
1297 | HCCRX_CLR_RISC_INT); | 1420 | fw->shadow_reg[2] = htonl(RD_REG_DWORD(®->iobase_sdata)); |
1298 | RD_REG_DWORD(®->hccr); | ||
1299 | break; | ||
1300 | } | ||
1301 | 1421 | ||
1302 | /* Clear this intr; it wasn't a mailbox intr */ | 1422 | WRT_REG_DWORD(®->iobase_select, 0xB0300000); |
1303 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 1423 | fw->shadow_reg[3] = htonl(RD_REG_DWORD(®->iobase_sdata)); |
1304 | RD_REG_DWORD(®->hccr); | 1424 | |
1305 | } | 1425 | WRT_REG_DWORD(®->iobase_select, 0xB0400000); |
1426 | fw->shadow_reg[4] = htonl(RD_REG_DWORD(®->iobase_sdata)); | ||
1427 | |||
1428 | WRT_REG_DWORD(®->iobase_select, 0xB0500000); | ||
1429 | fw->shadow_reg[5] = htonl(RD_REG_DWORD(®->iobase_sdata)); | ||
1430 | |||
1431 | WRT_REG_DWORD(®->iobase_select, 0xB0600000); | ||
1432 | fw->shadow_reg[6] = htonl(RD_REG_DWORD(®->iobase_sdata)); | ||
1433 | |||
1434 | WRT_REG_DWORD(®->iobase_select, 0xB0700000); | ||
1435 | fw->shadow_reg[7] = htonl(RD_REG_DWORD(®->iobase_sdata)); | ||
1436 | |||
1437 | WRT_REG_DWORD(®->iobase_select, 0xB0800000); | ||
1438 | fw->shadow_reg[8] = htonl(RD_REG_DWORD(®->iobase_sdata)); | ||
1439 | |||
1440 | WRT_REG_DWORD(®->iobase_select, 0xB0900000); | ||
1441 | fw->shadow_reg[9] = htonl(RD_REG_DWORD(®->iobase_sdata)); | ||
1442 | |||
1443 | WRT_REG_DWORD(®->iobase_select, 0xB0A00000); | ||
1444 | fw->shadow_reg[10] = htonl(RD_REG_DWORD(®->iobase_sdata)); | ||
1445 | |||
1446 | /* RISC I/O register. */ | ||
1447 | WRT_REG_DWORD(®->iobase_addr, 0x0010); | ||
1448 | RD_REG_DWORD(®->iobase_addr); | ||
1449 | fw->risc_io_reg = htonl(RD_REG_DWORD(®->iobase_window)); | ||
1450 | |||
1451 | /* Mailbox registers. */ | ||
1452 | mbx_reg = ®->mailbox0; | ||
1453 | for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) | ||
1454 | fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++)); | ||
1455 | |||
1456 | /* Transfer sequence registers. */ | ||
1457 | iter_reg = fw->xseq_gp_reg; | ||
1458 | WRT_REG_DWORD(®->iobase_addr, 0xBF00); | ||
1459 | dmp_reg = ®->iobase_window; | ||
1460 | for (cnt = 0; cnt < 16; cnt++) | ||
1461 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1462 | |||
1463 | WRT_REG_DWORD(®->iobase_addr, 0xBF10); | ||
1464 | dmp_reg = ®->iobase_window; | ||
1465 | for (cnt = 0; cnt < 16; cnt++) | ||
1466 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1467 | |||
1468 | WRT_REG_DWORD(®->iobase_addr, 0xBF20); | ||
1469 | dmp_reg = ®->iobase_window; | ||
1470 | for (cnt = 0; cnt < 16; cnt++) | ||
1471 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1472 | |||
1473 | WRT_REG_DWORD(®->iobase_addr, 0xBF30); | ||
1474 | dmp_reg = ®->iobase_window; | ||
1475 | for (cnt = 0; cnt < 16; cnt++) | ||
1476 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1477 | |||
1478 | WRT_REG_DWORD(®->iobase_addr, 0xBF40); | ||
1479 | dmp_reg = ®->iobase_window; | ||
1480 | for (cnt = 0; cnt < 16; cnt++) | ||
1481 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1482 | |||
1483 | WRT_REG_DWORD(®->iobase_addr, 0xBF50); | ||
1484 | dmp_reg = ®->iobase_window; | ||
1485 | for (cnt = 0; cnt < 16; cnt++) | ||
1486 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1487 | |||
1488 | WRT_REG_DWORD(®->iobase_addr, 0xBF60); | ||
1489 | dmp_reg = ®->iobase_window; | ||
1490 | for (cnt = 0; cnt < 16; cnt++) | ||
1491 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1492 | |||
1493 | WRT_REG_DWORD(®->iobase_addr, 0xBF70); | ||
1494 | dmp_reg = ®->iobase_window; | ||
1495 | for (cnt = 0; cnt < 16; cnt++) | ||
1496 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1497 | |||
1498 | iter_reg = fw->xseq_0_reg; | ||
1499 | WRT_REG_DWORD(®->iobase_addr, 0xBFC0); | ||
1500 | dmp_reg = ®->iobase_window; | ||
1501 | for (cnt = 0; cnt < 16; cnt++) | ||
1502 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1503 | |||
1504 | WRT_REG_DWORD(®->iobase_addr, 0xBFD0); | ||
1505 | dmp_reg = ®->iobase_window; | ||
1506 | for (cnt = 0; cnt < 16; cnt++) | ||
1507 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1508 | |||
1509 | WRT_REG_DWORD(®->iobase_addr, 0xBFE0); | ||
1510 | dmp_reg = ®->iobase_window; | ||
1511 | for (cnt = 0; cnt < 16; cnt++) | ||
1512 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1513 | |||
1514 | WRT_REG_DWORD(®->iobase_addr, 0xBFF0); | ||
1515 | dmp_reg = ®->iobase_window; | ||
1516 | for (cnt = 0; cnt < sizeof(fw->xseq_1_reg) / 4; cnt++) | ||
1517 | fw->xseq_1_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1518 | |||
1519 | /* Receive sequence registers. */ | ||
1520 | iter_reg = fw->rseq_gp_reg; | ||
1521 | WRT_REG_DWORD(®->iobase_addr, 0xFF00); | ||
1522 | dmp_reg = ®->iobase_window; | ||
1523 | for (cnt = 0; cnt < 16; cnt++) | ||
1524 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1525 | |||
1526 | WRT_REG_DWORD(®->iobase_addr, 0xFF10); | ||
1527 | dmp_reg = ®->iobase_window; | ||
1528 | for (cnt = 0; cnt < 16; cnt++) | ||
1529 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1530 | |||
1531 | WRT_REG_DWORD(®->iobase_addr, 0xFF20); | ||
1532 | dmp_reg = ®->iobase_window; | ||
1533 | for (cnt = 0; cnt < 16; cnt++) | ||
1534 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1535 | |||
1536 | WRT_REG_DWORD(®->iobase_addr, 0xFF30); | ||
1537 | dmp_reg = ®->iobase_window; | ||
1538 | for (cnt = 0; cnt < 16; cnt++) | ||
1539 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1540 | |||
1541 | WRT_REG_DWORD(®->iobase_addr, 0xFF40); | ||
1542 | dmp_reg = ®->iobase_window; | ||
1543 | for (cnt = 0; cnt < 16; cnt++) | ||
1544 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1545 | |||
1546 | WRT_REG_DWORD(®->iobase_addr, 0xFF50); | ||
1547 | dmp_reg = ®->iobase_window; | ||
1548 | for (cnt = 0; cnt < 16; cnt++) | ||
1549 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1550 | |||
1551 | WRT_REG_DWORD(®->iobase_addr, 0xFF60); | ||
1552 | dmp_reg = ®->iobase_window; | ||
1553 | for (cnt = 0; cnt < 16; cnt++) | ||
1554 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1555 | |||
1556 | WRT_REG_DWORD(®->iobase_addr, 0xFF70); | ||
1557 | dmp_reg = ®->iobase_window; | ||
1558 | for (cnt = 0; cnt < 16; cnt++) | ||
1559 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1560 | |||
1561 | iter_reg = fw->rseq_0_reg; | ||
1562 | WRT_REG_DWORD(®->iobase_addr, 0xFFC0); | ||
1563 | dmp_reg = ®->iobase_window; | ||
1564 | for (cnt = 0; cnt < 16; cnt++) | ||
1565 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1566 | |||
1567 | WRT_REG_DWORD(®->iobase_addr, 0xFFD0); | ||
1568 | dmp_reg = ®->iobase_window; | ||
1569 | for (cnt = 0; cnt < 16; cnt++) | ||
1570 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1571 | |||
1572 | WRT_REG_DWORD(®->iobase_addr, 0xFFE0); | ||
1573 | dmp_reg = ®->iobase_window; | ||
1574 | for (cnt = 0; cnt < sizeof(fw->rseq_1_reg) / 4; cnt++) | ||
1575 | fw->rseq_1_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1576 | |||
1577 | WRT_REG_DWORD(®->iobase_addr, 0xFFF0); | ||
1578 | dmp_reg = ®->iobase_window; | ||
1579 | for (cnt = 0; cnt < sizeof(fw->rseq_2_reg) / 4; cnt++) | ||
1580 | fw->rseq_2_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1581 | |||
1582 | /* Auxiliary sequence registers. */ | ||
1583 | iter_reg = fw->aseq_gp_reg; | ||
1584 | WRT_REG_DWORD(®->iobase_addr, 0xB000); | ||
1585 | dmp_reg = ®->iobase_window; | ||
1586 | for (cnt = 0; cnt < 16; cnt++) | ||
1587 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1588 | |||
1589 | WRT_REG_DWORD(®->iobase_addr, 0xB010); | ||
1590 | dmp_reg = ®->iobase_window; | ||
1591 | for (cnt = 0; cnt < 16; cnt++) | ||
1592 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1593 | |||
1594 | WRT_REG_DWORD(®->iobase_addr, 0xB020); | ||
1595 | dmp_reg = ®->iobase_window; | ||
1596 | for (cnt = 0; cnt < 16; cnt++) | ||
1597 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1598 | |||
1599 | WRT_REG_DWORD(®->iobase_addr, 0xB030); | ||
1600 | dmp_reg = ®->iobase_window; | ||
1601 | for (cnt = 0; cnt < 16; cnt++) | ||
1602 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1603 | |||
1604 | WRT_REG_DWORD(®->iobase_addr, 0xB040); | ||
1605 | dmp_reg = ®->iobase_window; | ||
1606 | for (cnt = 0; cnt < 16; cnt++) | ||
1607 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1608 | |||
1609 | WRT_REG_DWORD(®->iobase_addr, 0xB050); | ||
1610 | dmp_reg = ®->iobase_window; | ||
1611 | for (cnt = 0; cnt < 16; cnt++) | ||
1612 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1613 | |||
1614 | WRT_REG_DWORD(®->iobase_addr, 0xB060); | ||
1615 | dmp_reg = ®->iobase_window; | ||
1616 | for (cnt = 0; cnt < 16; cnt++) | ||
1617 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1618 | |||
1619 | WRT_REG_DWORD(®->iobase_addr, 0xB070); | ||
1620 | dmp_reg = ®->iobase_window; | ||
1621 | for (cnt = 0; cnt < 16; cnt++) | ||
1622 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1623 | |||
1624 | iter_reg = fw->aseq_0_reg; | ||
1625 | WRT_REG_DWORD(®->iobase_addr, 0xB0C0); | ||
1626 | dmp_reg = ®->iobase_window; | ||
1627 | for (cnt = 0; cnt < 16; cnt++) | ||
1628 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1629 | |||
1630 | WRT_REG_DWORD(®->iobase_addr, 0xB0D0); | ||
1631 | dmp_reg = ®->iobase_window; | ||
1632 | for (cnt = 0; cnt < 16; cnt++) | ||
1633 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1634 | |||
1635 | WRT_REG_DWORD(®->iobase_addr, 0xB0E0); | ||
1636 | dmp_reg = ®->iobase_window; | ||
1637 | for (cnt = 0; cnt < sizeof(fw->aseq_1_reg) / 4; cnt++) | ||
1638 | fw->aseq_1_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1639 | |||
1640 | WRT_REG_DWORD(®->iobase_addr, 0xB0F0); | ||
1641 | dmp_reg = ®->iobase_window; | ||
1642 | for (cnt = 0; cnt < sizeof(fw->aseq_2_reg) / 4; cnt++) | ||
1643 | fw->aseq_2_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1644 | |||
1645 | /* Command DMA registers. */ | ||
1646 | WRT_REG_DWORD(®->iobase_addr, 0x7100); | ||
1647 | dmp_reg = ®->iobase_window; | ||
1648 | for (cnt = 0; cnt < sizeof(fw->cmd_dma_reg) / 4; cnt++) | ||
1649 | fw->cmd_dma_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1650 | |||
1651 | /* Queues. */ | ||
1652 | iter_reg = fw->req0_dma_reg; | ||
1653 | WRT_REG_DWORD(®->iobase_addr, 0x7200); | ||
1654 | dmp_reg = ®->iobase_window; | ||
1655 | for (cnt = 0; cnt < 8; cnt++) | ||
1656 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1657 | |||
1658 | dmp_reg = ®->iobase_q; | ||
1659 | for (cnt = 0; cnt < 7; cnt++) | ||
1660 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1661 | |||
1662 | iter_reg = fw->resp0_dma_reg; | ||
1663 | WRT_REG_DWORD(®->iobase_addr, 0x7300); | ||
1664 | dmp_reg = ®->iobase_window; | ||
1665 | for (cnt = 0; cnt < 8; cnt++) | ||
1666 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1667 | |||
1668 | dmp_reg = ®->iobase_q; | ||
1669 | for (cnt = 0; cnt < 7; cnt++) | ||
1670 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1671 | |||
1672 | iter_reg = fw->req1_dma_reg; | ||
1673 | WRT_REG_DWORD(®->iobase_addr, 0x7400); | ||
1674 | dmp_reg = ®->iobase_window; | ||
1675 | for (cnt = 0; cnt < 8; cnt++) | ||
1676 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1677 | |||
1678 | dmp_reg = ®->iobase_q; | ||
1679 | for (cnt = 0; cnt < 7; cnt++) | ||
1680 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1681 | |||
1682 | /* Transmit DMA registers. */ | ||
1683 | iter_reg = fw->xmt0_dma_reg; | ||
1684 | WRT_REG_DWORD(®->iobase_addr, 0x7600); | ||
1685 | dmp_reg = ®->iobase_window; | ||
1686 | for (cnt = 0; cnt < 16; cnt++) | ||
1687 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1688 | |||
1689 | WRT_REG_DWORD(®->iobase_addr, 0x7610); | ||
1690 | dmp_reg = ®->iobase_window; | ||
1691 | for (cnt = 0; cnt < 16; cnt++) | ||
1692 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1693 | |||
1694 | iter_reg = fw->xmt1_dma_reg; | ||
1695 | WRT_REG_DWORD(®->iobase_addr, 0x7620); | ||
1696 | dmp_reg = ®->iobase_window; | ||
1697 | for (cnt = 0; cnt < 16; cnt++) | ||
1698 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1699 | |||
1700 | WRT_REG_DWORD(®->iobase_addr, 0x7630); | ||
1701 | dmp_reg = ®->iobase_window; | ||
1702 | for (cnt = 0; cnt < 16; cnt++) | ||
1703 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1704 | |||
1705 | iter_reg = fw->xmt2_dma_reg; | ||
1706 | WRT_REG_DWORD(®->iobase_addr, 0x7640); | ||
1707 | dmp_reg = ®->iobase_window; | ||
1708 | for (cnt = 0; cnt < 16; cnt++) | ||
1709 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1710 | |||
1711 | WRT_REG_DWORD(®->iobase_addr, 0x7650); | ||
1712 | dmp_reg = ®->iobase_window; | ||
1713 | for (cnt = 0; cnt < 16; cnt++) | ||
1714 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1715 | |||
1716 | iter_reg = fw->xmt3_dma_reg; | ||
1717 | WRT_REG_DWORD(®->iobase_addr, 0x7660); | ||
1718 | dmp_reg = ®->iobase_window; | ||
1719 | for (cnt = 0; cnt < 16; cnt++) | ||
1720 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1721 | |||
1722 | WRT_REG_DWORD(®->iobase_addr, 0x7670); | ||
1723 | dmp_reg = ®->iobase_window; | ||
1724 | for (cnt = 0; cnt < 16; cnt++) | ||
1725 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1726 | |||
1727 | iter_reg = fw->xmt4_dma_reg; | ||
1728 | WRT_REG_DWORD(®->iobase_addr, 0x7680); | ||
1729 | dmp_reg = ®->iobase_window; | ||
1730 | for (cnt = 0; cnt < 16; cnt++) | ||
1731 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1732 | |||
1733 | WRT_REG_DWORD(®->iobase_addr, 0x7690); | ||
1734 | dmp_reg = ®->iobase_window; | ||
1735 | for (cnt = 0; cnt < 16; cnt++) | ||
1736 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1737 | |||
1738 | WRT_REG_DWORD(®->iobase_addr, 0x76A0); | ||
1739 | dmp_reg = ®->iobase_window; | ||
1740 | for (cnt = 0; cnt < sizeof(fw->xmt_data_dma_reg) / 4; cnt++) | ||
1741 | fw->xmt_data_dma_reg[cnt] = | ||
1742 | htonl(RD_REG_DWORD(dmp_reg++)); | ||
1743 | |||
1744 | /* Receive DMA registers. */ | ||
1745 | iter_reg = fw->rcvt0_data_dma_reg; | ||
1746 | WRT_REG_DWORD(®->iobase_addr, 0x7700); | ||
1747 | dmp_reg = ®->iobase_window; | ||
1748 | for (cnt = 0; cnt < 16; cnt++) | ||
1749 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1750 | |||
1751 | WRT_REG_DWORD(®->iobase_addr, 0x7710); | ||
1752 | dmp_reg = ®->iobase_window; | ||
1753 | for (cnt = 0; cnt < 16; cnt++) | ||
1754 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1755 | |||
1756 | iter_reg = fw->rcvt1_data_dma_reg; | ||
1757 | WRT_REG_DWORD(®->iobase_addr, 0x7720); | ||
1758 | dmp_reg = ®->iobase_window; | ||
1759 | for (cnt = 0; cnt < 16; cnt++) | ||
1760 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1761 | |||
1762 | WRT_REG_DWORD(®->iobase_addr, 0x7730); | ||
1763 | dmp_reg = ®->iobase_window; | ||
1764 | for (cnt = 0; cnt < 16; cnt++) | ||
1765 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1766 | |||
1767 | /* RISC registers. */ | ||
1768 | iter_reg = fw->risc_gp_reg; | ||
1769 | WRT_REG_DWORD(®->iobase_addr, 0x0F00); | ||
1770 | dmp_reg = ®->iobase_window; | ||
1771 | for (cnt = 0; cnt < 16; cnt++) | ||
1772 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1773 | |||
1774 | WRT_REG_DWORD(®->iobase_addr, 0x0F10); | ||
1775 | dmp_reg = ®->iobase_window; | ||
1776 | for (cnt = 0; cnt < 16; cnt++) | ||
1777 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1778 | |||
1779 | WRT_REG_DWORD(®->iobase_addr, 0x0F20); | ||
1780 | dmp_reg = ®->iobase_window; | ||
1781 | for (cnt = 0; cnt < 16; cnt++) | ||
1782 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1783 | |||
1784 | WRT_REG_DWORD(®->iobase_addr, 0x0F30); | ||
1785 | dmp_reg = ®->iobase_window; | ||
1786 | for (cnt = 0; cnt < 16; cnt++) | ||
1787 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1788 | |||
1789 | WRT_REG_DWORD(®->iobase_addr, 0x0F40); | ||
1790 | dmp_reg = ®->iobase_window; | ||
1791 | for (cnt = 0; cnt < 16; cnt++) | ||
1792 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1793 | |||
1794 | WRT_REG_DWORD(®->iobase_addr, 0x0F50); | ||
1795 | dmp_reg = ®->iobase_window; | ||
1796 | for (cnt = 0; cnt < 16; cnt++) | ||
1797 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1798 | |||
1799 | WRT_REG_DWORD(®->iobase_addr, 0x0F60); | ||
1800 | dmp_reg = ®->iobase_window; | ||
1801 | for (cnt = 0; cnt < 16; cnt++) | ||
1802 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1803 | |||
1804 | WRT_REG_DWORD(®->iobase_addr, 0x0F70); | ||
1805 | dmp_reg = ®->iobase_window; | ||
1806 | for (cnt = 0; cnt < 16; cnt++) | ||
1807 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1808 | |||
1809 | /* Local memory controller registers. */ | ||
1810 | iter_reg = fw->lmc_reg; | ||
1811 | WRT_REG_DWORD(®->iobase_addr, 0x3000); | ||
1812 | dmp_reg = ®->iobase_window; | ||
1813 | for (cnt = 0; cnt < 16; cnt++) | ||
1814 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1815 | |||
1816 | WRT_REG_DWORD(®->iobase_addr, 0x3010); | ||
1817 | dmp_reg = ®->iobase_window; | ||
1818 | for (cnt = 0; cnt < 16; cnt++) | ||
1819 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1820 | |||
1821 | WRT_REG_DWORD(®->iobase_addr, 0x3020); | ||
1822 | dmp_reg = ®->iobase_window; | ||
1823 | for (cnt = 0; cnt < 16; cnt++) | ||
1824 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1825 | |||
1826 | WRT_REG_DWORD(®->iobase_addr, 0x3030); | ||
1827 | dmp_reg = ®->iobase_window; | ||
1828 | for (cnt = 0; cnt < 16; cnt++) | ||
1829 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1830 | |||
1831 | WRT_REG_DWORD(®->iobase_addr, 0x3040); | ||
1832 | dmp_reg = ®->iobase_window; | ||
1833 | for (cnt = 0; cnt < 16; cnt++) | ||
1834 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1835 | |||
1836 | WRT_REG_DWORD(®->iobase_addr, 0x3050); | ||
1837 | dmp_reg = ®->iobase_window; | ||
1838 | for (cnt = 0; cnt < 16; cnt++) | ||
1839 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1840 | |||
1841 | WRT_REG_DWORD(®->iobase_addr, 0x3060); | ||
1842 | dmp_reg = ®->iobase_window; | ||
1843 | for (cnt = 0; cnt < 16; cnt++) | ||
1844 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1845 | |||
1846 | WRT_REG_DWORD(®->iobase_addr, 0x3070); | ||
1847 | dmp_reg = ®->iobase_window; | ||
1848 | for (cnt = 0; cnt < 16; cnt++) | ||
1849 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1850 | |||
1851 | /* Fibre Protocol Module registers. */ | ||
1852 | iter_reg = fw->fpm_hdw_reg; | ||
1853 | WRT_REG_DWORD(®->iobase_addr, 0x4000); | ||
1854 | dmp_reg = ®->iobase_window; | ||
1855 | for (cnt = 0; cnt < 16; cnt++) | ||
1856 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1857 | |||
1858 | WRT_REG_DWORD(®->iobase_addr, 0x4010); | ||
1859 | dmp_reg = ®->iobase_window; | ||
1860 | for (cnt = 0; cnt < 16; cnt++) | ||
1861 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1862 | |||
1863 | WRT_REG_DWORD(®->iobase_addr, 0x4020); | ||
1864 | dmp_reg = ®->iobase_window; | ||
1865 | for (cnt = 0; cnt < 16; cnt++) | ||
1866 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1867 | |||
1868 | WRT_REG_DWORD(®->iobase_addr, 0x4030); | ||
1869 | dmp_reg = ®->iobase_window; | ||
1870 | for (cnt = 0; cnt < 16; cnt++) | ||
1871 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1872 | |||
1873 | WRT_REG_DWORD(®->iobase_addr, 0x4040); | ||
1874 | dmp_reg = ®->iobase_window; | ||
1875 | for (cnt = 0; cnt < 16; cnt++) | ||
1876 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1877 | |||
1878 | WRT_REG_DWORD(®->iobase_addr, 0x4050); | ||
1879 | dmp_reg = ®->iobase_window; | ||
1880 | for (cnt = 0; cnt < 16; cnt++) | ||
1881 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1882 | |||
1883 | WRT_REG_DWORD(®->iobase_addr, 0x4060); | ||
1884 | dmp_reg = ®->iobase_window; | ||
1885 | for (cnt = 0; cnt < 16; cnt++) | ||
1886 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1887 | |||
1888 | WRT_REG_DWORD(®->iobase_addr, 0x4070); | ||
1889 | dmp_reg = ®->iobase_window; | ||
1890 | for (cnt = 0; cnt < 16; cnt++) | ||
1891 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1892 | |||
1893 | WRT_REG_DWORD(®->iobase_addr, 0x4080); | ||
1894 | dmp_reg = ®->iobase_window; | ||
1895 | for (cnt = 0; cnt < 16; cnt++) | ||
1896 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1897 | |||
1898 | WRT_REG_DWORD(®->iobase_addr, 0x4090); | ||
1899 | dmp_reg = ®->iobase_window; | ||
1900 | for (cnt = 0; cnt < 16; cnt++) | ||
1901 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1902 | |||
1903 | WRT_REG_DWORD(®->iobase_addr, 0x40A0); | ||
1904 | dmp_reg = ®->iobase_window; | ||
1905 | for (cnt = 0; cnt < 16; cnt++) | ||
1906 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1907 | |||
1908 | WRT_REG_DWORD(®->iobase_addr, 0x40B0); | ||
1909 | dmp_reg = ®->iobase_window; | ||
1910 | for (cnt = 0; cnt < 16; cnt++) | ||
1911 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1912 | |||
1913 | /* Frame Buffer registers. */ | ||
1914 | iter_reg = fw->fb_hdw_reg; | ||
1915 | WRT_REG_DWORD(®->iobase_addr, 0x6000); | ||
1916 | dmp_reg = ®->iobase_window; | ||
1917 | for (cnt = 0; cnt < 16; cnt++) | ||
1918 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1919 | |||
1920 | WRT_REG_DWORD(®->iobase_addr, 0x6010); | ||
1921 | dmp_reg = ®->iobase_window; | ||
1922 | for (cnt = 0; cnt < 16; cnt++) | ||
1923 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1924 | |||
1925 | WRT_REG_DWORD(®->iobase_addr, 0x6020); | ||
1926 | dmp_reg = ®->iobase_window; | ||
1927 | for (cnt = 0; cnt < 16; cnt++) | ||
1928 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1929 | |||
1930 | WRT_REG_DWORD(®->iobase_addr, 0x6030); | ||
1931 | dmp_reg = ®->iobase_window; | ||
1932 | for (cnt = 0; cnt < 16; cnt++) | ||
1933 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1934 | |||
1935 | WRT_REG_DWORD(®->iobase_addr, 0x6040); | ||
1936 | dmp_reg = ®->iobase_window; | ||
1937 | for (cnt = 0; cnt < 16; cnt++) | ||
1938 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1939 | |||
1940 | WRT_REG_DWORD(®->iobase_addr, 0x6100); | ||
1941 | dmp_reg = ®->iobase_window; | ||
1942 | for (cnt = 0; cnt < 16; cnt++) | ||
1943 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1944 | |||
1945 | WRT_REG_DWORD(®->iobase_addr, 0x6130); | ||
1946 | dmp_reg = ®->iobase_window; | ||
1947 | for (cnt = 0; cnt < 16; cnt++) | ||
1948 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1949 | |||
1950 | WRT_REG_DWORD(®->iobase_addr, 0x6150); | ||
1951 | dmp_reg = ®->iobase_window; | ||
1952 | for (cnt = 0; cnt < 16; cnt++) | ||
1953 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1954 | |||
1955 | WRT_REG_DWORD(®->iobase_addr, 0x6170); | ||
1956 | dmp_reg = ®->iobase_window; | ||
1957 | for (cnt = 0; cnt < 16; cnt++) | ||
1958 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1959 | |||
1960 | WRT_REG_DWORD(®->iobase_addr, 0x6190); | ||
1961 | dmp_reg = ®->iobase_window; | ||
1962 | for (cnt = 0; cnt < 16; cnt++) | ||
1963 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1964 | |||
1965 | WRT_REG_DWORD(®->iobase_addr, 0x61B0); | ||
1966 | dmp_reg = ®->iobase_window; | ||
1967 | for (cnt = 0; cnt < 16; cnt++) | ||
1968 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1969 | |||
1970 | WRT_REG_DWORD(®->iobase_addr, 0x6F00); | ||
1971 | dmp_reg = ®->iobase_window; | ||
1972 | for (cnt = 0; cnt < 16; cnt++) | ||
1973 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1974 | |||
1975 | /* Reset RISC. */ | ||
1976 | WRT_REG_DWORD(®->ctrl_status, | ||
1977 | CSRX_DMA_SHUTDOWN|MWB_4096_BYTES); | ||
1978 | for (cnt = 0; cnt < 30000; cnt++) { | ||
1979 | if ((RD_REG_DWORD(®->ctrl_status) & | ||
1980 | CSRX_DMA_ACTIVE) == 0) | ||
1981 | break; | ||
1982 | |||
1983 | udelay(10); | ||
1984 | } | ||
1985 | |||
1986 | WRT_REG_DWORD(®->ctrl_status, | ||
1987 | CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES); | ||
1988 | pci_read_config_word(ha->pdev, PCI_COMMAND, &wd); | ||
1989 | |||
1990 | udelay(100); | ||
1991 | /* Wait for firmware to complete NVRAM accesses. */ | ||
1992 | mb0 = (uint32_t) RD_REG_WORD(®->mailbox0); | ||
1993 | for (cnt = 10000 ; cnt && mb0; cnt--) { | ||
1306 | udelay(5); | 1994 | udelay(5); |
1995 | mb0 = (uint32_t) RD_REG_WORD(®->mailbox0); | ||
1996 | barrier(); | ||
1307 | } | 1997 | } |
1308 | 1998 | ||
1309 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | 1999 | /* Wait for soft-reset to complete. */ |
1310 | rval = mb[0] & MBS_MASK; | 2000 | for (cnt = 0; cnt < 30000; cnt++) { |
1311 | fw->ext_mem[cnt] = htonl((mb[3] << 16) | mb[2]); | 2001 | if ((RD_REG_DWORD(®->ctrl_status) & |
1312 | } else { | 2002 | CSRX_ISP_SOFT_RESET) == 0) |
1313 | rval = QLA_FUNCTION_FAILED; | 2003 | break; |
2004 | |||
2005 | udelay(10); | ||
1314 | } | 2006 | } |
2007 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_RESET); | ||
2008 | RD_REG_DWORD(®->hccr); /* PCI Posting. */ | ||
1315 | } | 2009 | } |
1316 | 2010 | ||
2011 | for (cnt = 30000; RD_REG_WORD(®->mailbox0) != 0 && | ||
2012 | rval == QLA_SUCCESS; cnt--) { | ||
2013 | if (cnt) | ||
2014 | udelay(100); | ||
2015 | else | ||
2016 | rval = QLA_FUNCTION_TIMEOUT; | ||
2017 | } | ||
2018 | |||
2019 | if (rval == QLA_SUCCESS) | ||
2020 | rval = qla2xxx_dump_memory(ha, fw->code_ram, | ||
2021 | sizeof(fw->code_ram), fw->ext_mem, &nxt); | ||
2022 | |||
1317 | if (rval == QLA_SUCCESS) { | 2023 | if (rval == QLA_SUCCESS) { |
1318 | eft = qla2xxx_copy_queues(ha, &fw->ext_mem[cnt]); | 2024 | nxt = qla2xxx_copy_queues(ha, nxt); |
1319 | if (ha->eft) | 2025 | if (ha->eft) |
1320 | memcpy(eft, ha->eft, ntohl(ha->fw_dump->eft_size)); | 2026 | memcpy(nxt, ha->eft, ntohl(ha->fw_dump->eft_size)); |
1321 | } | 2027 | } |
1322 | 2028 | ||
1323 | if (rval != QLA_SUCCESS) { | 2029 | if (rval != QLA_SUCCESS) { |
@@ -1332,7 +2038,7 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
1332 | ha->fw_dumped = 1; | 2038 | ha->fw_dumped = 1; |
1333 | } | 2039 | } |
1334 | 2040 | ||
1335 | qla24xx_fw_dump_failed: | 2041 | qla25xx_fw_dump_failed: |
1336 | if (!hardware_locked) | 2042 | if (!hardware_locked) |
1337 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 2043 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
1338 | } | 2044 | } |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index 49dffeb78512..cca4b0d8253e 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h | |||
@@ -213,6 +213,43 @@ struct qla24xx_fw_dump { | |||
213 | uint32_t ext_mem[1]; | 213 | uint32_t ext_mem[1]; |
214 | }; | 214 | }; |
215 | 215 | ||
216 | struct qla25xx_fw_dump { | ||
217 | uint32_t host_status; | ||
218 | uint32_t host_reg[32]; | ||
219 | uint32_t shadow_reg[11]; | ||
220 | uint32_t risc_io_reg; | ||
221 | uint16_t mailbox_reg[32]; | ||
222 | uint32_t xseq_gp_reg[128]; | ||
223 | uint32_t xseq_0_reg[48]; | ||
224 | uint32_t xseq_1_reg[16]; | ||
225 | uint32_t rseq_gp_reg[128]; | ||
226 | uint32_t rseq_0_reg[32]; | ||
227 | uint32_t rseq_1_reg[16]; | ||
228 | uint32_t rseq_2_reg[16]; | ||
229 | uint32_t aseq_gp_reg[128]; | ||
230 | uint32_t aseq_0_reg[32]; | ||
231 | uint32_t aseq_1_reg[16]; | ||
232 | uint32_t aseq_2_reg[16]; | ||
233 | uint32_t cmd_dma_reg[16]; | ||
234 | uint32_t req0_dma_reg[15]; | ||
235 | uint32_t resp0_dma_reg[15]; | ||
236 | uint32_t req1_dma_reg[15]; | ||
237 | uint32_t xmt0_dma_reg[32]; | ||
238 | uint32_t xmt1_dma_reg[32]; | ||
239 | uint32_t xmt2_dma_reg[32]; | ||
240 | uint32_t xmt3_dma_reg[32]; | ||
241 | uint32_t xmt4_dma_reg[32]; | ||
242 | uint32_t xmt_data_dma_reg[16]; | ||
243 | uint32_t rcvt0_data_dma_reg[32]; | ||
244 | uint32_t rcvt1_data_dma_reg[32]; | ||
245 | uint32_t risc_gp_reg[128]; | ||
246 | uint32_t lmc_reg[128]; | ||
247 | uint32_t fpm_hdw_reg[192]; | ||
248 | uint32_t fb_hdw_reg[192]; | ||
249 | uint32_t code_ram[0x2000]; | ||
250 | uint32_t ext_mem[1]; | ||
251 | }; | ||
252 | |||
216 | #define EFT_NUM_BUFFERS 4 | 253 | #define EFT_NUM_BUFFERS 4 |
217 | #define EFT_BYTES_PER_BUFFER 0x4000 | 254 | #define EFT_BYTES_PER_BUFFER 0x4000 |
218 | #define EFT_SIZE ((EFT_BYTES_PER_BUFFER) * (EFT_NUM_BUFFERS)) | 255 | #define EFT_SIZE ((EFT_BYTES_PER_BUFFER) * (EFT_NUM_BUFFERS)) |
@@ -246,5 +283,6 @@ struct qla2xxx_fw_dump { | |||
246 | struct qla2100_fw_dump isp21; | 283 | struct qla2100_fw_dump isp21; |
247 | struct qla2300_fw_dump isp23; | 284 | struct qla2300_fw_dump isp23; |
248 | struct qla24xx_fw_dump isp24; | 285 | struct qla24xx_fw_dump isp24; |
286 | struct qla25xx_fw_dump isp25; | ||
249 | } isp; | 287 | } isp; |
250 | }; | 288 | }; |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index a1ca590ba447..0c9f36c8a248 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -1711,6 +1711,14 @@ struct ct_fdmi_hba_attributes { | |||
1711 | #define FDMI_PORT_OS_DEVICE_NAME 5 | 1711 | #define FDMI_PORT_OS_DEVICE_NAME 5 |
1712 | #define FDMI_PORT_HOST_NAME 6 | 1712 | #define FDMI_PORT_HOST_NAME 6 |
1713 | 1713 | ||
1714 | #define FDMI_PORT_SPEED_1GB 0x1 | ||
1715 | #define FDMI_PORT_SPEED_2GB 0x2 | ||
1716 | #define FDMI_PORT_SPEED_10GB 0x4 | ||
1717 | #define FDMI_PORT_SPEED_4GB 0x8 | ||
1718 | #define FDMI_PORT_SPEED_8GB 0x10 | ||
1719 | #define FDMI_PORT_SPEED_16GB 0x20 | ||
1720 | #define FDMI_PORT_SPEED_UNKNOWN 0x8000 | ||
1721 | |||
1714 | struct ct_fdmi_port_attr { | 1722 | struct ct_fdmi_port_attr { |
1715 | uint16_t type; | 1723 | uint16_t type; |
1716 | uint16_t len; | 1724 | uint16_t len; |
@@ -2201,6 +2209,7 @@ typedef struct scsi_qla_host { | |||
2201 | #define SWITCH_FOUND BIT_3 | 2209 | #define SWITCH_FOUND BIT_3 |
2202 | #define DFLG_NO_CABLE BIT_4 | 2210 | #define DFLG_NO_CABLE BIT_4 |
2203 | 2211 | ||
2212 | #define PCI_DEVICE_ID_QLOGIC_ISP2532 0x2532 | ||
2204 | uint32_t device_type; | 2213 | uint32_t device_type; |
2205 | #define DT_ISP2100 BIT_0 | 2214 | #define DT_ISP2100 BIT_0 |
2206 | #define DT_ISP2200 BIT_1 | 2215 | #define DT_ISP2200 BIT_1 |
@@ -2213,8 +2222,11 @@ typedef struct scsi_qla_host { | |||
2213 | #define DT_ISP2432 BIT_8 | 2222 | #define DT_ISP2432 BIT_8 |
2214 | #define DT_ISP5422 BIT_9 | 2223 | #define DT_ISP5422 BIT_9 |
2215 | #define DT_ISP5432 BIT_10 | 2224 | #define DT_ISP5432 BIT_10 |
2216 | #define DT_ISP_LAST (DT_ISP5432 << 1) | 2225 | #define DT_ISP2532 BIT_11 |
2226 | #define DT_ISP_LAST (DT_ISP2532 << 1) | ||
2217 | 2227 | ||
2228 | #define DT_IIDMA BIT_26 | ||
2229 | #define DT_FWI2 BIT_27 | ||
2218 | #define DT_ZIO_SUPPORTED BIT_28 | 2230 | #define DT_ZIO_SUPPORTED BIT_28 |
2219 | #define DT_OEM_001 BIT_29 | 2231 | #define DT_OEM_001 BIT_29 |
2220 | #define DT_ISP2200A BIT_30 | 2232 | #define DT_ISP2200A BIT_30 |
@@ -2232,12 +2244,16 @@ typedef struct scsi_qla_host { | |||
2232 | #define IS_QLA2432(ha) (DT_MASK(ha) & DT_ISP2432) | 2244 | #define IS_QLA2432(ha) (DT_MASK(ha) & DT_ISP2432) |
2233 | #define IS_QLA5422(ha) (DT_MASK(ha) & DT_ISP5422) | 2245 | #define IS_QLA5422(ha) (DT_MASK(ha) & DT_ISP5422) |
2234 | #define IS_QLA5432(ha) (DT_MASK(ha) & DT_ISP5432) | 2246 | #define IS_QLA5432(ha) (DT_MASK(ha) & DT_ISP5432) |
2247 | #define IS_QLA2532(ha) (DT_MASK(ha) & DT_ISP2532) | ||
2235 | 2248 | ||
2236 | #define IS_QLA23XX(ha) (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \ | 2249 | #define IS_QLA23XX(ha) (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \ |
2237 | IS_QLA6312(ha) || IS_QLA6322(ha)) | 2250 | IS_QLA6312(ha) || IS_QLA6322(ha)) |
2238 | #define IS_QLA24XX(ha) (IS_QLA2422(ha) || IS_QLA2432(ha)) | 2251 | #define IS_QLA24XX(ha) (IS_QLA2422(ha) || IS_QLA2432(ha)) |
2239 | #define IS_QLA54XX(ha) (IS_QLA5422(ha) || IS_QLA5432(ha)) | 2252 | #define IS_QLA54XX(ha) (IS_QLA5422(ha) || IS_QLA5432(ha)) |
2253 | #define IS_QLA25XX(ha) (IS_QLA2532(ha)) | ||
2240 | 2254 | ||
2255 | #define IS_IIDMA_CAPABLE(ha) ((ha)->device_type & DT_IIDMA) | ||
2256 | #define IS_FWI2_CAPABLE(ha) ((ha)->device_type & DT_FWI2) | ||
2241 | #define IS_ZIO_SUPPORTED(ha) ((ha)->device_type & DT_ZIO_SUPPORTED) | 2257 | #define IS_ZIO_SUPPORTED(ha) ((ha)->device_type & DT_ZIO_SUPPORTED) |
2242 | #define IS_OEM_001(ha) ((ha)->device_type & DT_OEM_001) | 2258 | #define IS_OEM_001(ha) ((ha)->device_type & DT_OEM_001) |
2243 | #define HAS_EXTENDED_IDS(ha) ((ha)->device_type & DT_EXTENDED_IDS) | 2259 | #define HAS_EXTENDED_IDS(ha) ((ha)->device_type & DT_EXTENDED_IDS) |
@@ -2274,7 +2290,7 @@ typedef struct scsi_qla_host { | |||
2274 | uint16_t rsp_ring_index; /* Current index. */ | 2290 | uint16_t rsp_ring_index; /* Current index. */ |
2275 | uint16_t response_q_length; | 2291 | uint16_t response_q_length; |
2276 | 2292 | ||
2277 | struct isp_operations isp_ops; | 2293 | struct isp_operations *isp_ops; |
2278 | 2294 | ||
2279 | /* Outstandings ISP commands. */ | 2295 | /* Outstandings ISP commands. */ |
2280 | srb_t *outstanding_cmds[MAX_OUTSTANDING_COMMANDS]; | 2296 | srb_t *outstanding_cmds[MAX_OUTSTANDING_COMMANDS]; |
@@ -2298,6 +2314,7 @@ typedef struct scsi_qla_host { | |||
2298 | #define PORT_SPEED_1GB 0x00 | 2314 | #define PORT_SPEED_1GB 0x00 |
2299 | #define PORT_SPEED_2GB 0x01 | 2315 | #define PORT_SPEED_2GB 0x01 |
2300 | #define PORT_SPEED_4GB 0x03 | 2316 | #define PORT_SPEED_4GB 0x03 |
2317 | #define PORT_SPEED_8GB 0x04 | ||
2301 | uint16_t link_data_rate; /* F/W operating speed */ | 2318 | uint16_t link_data_rate; /* F/W operating speed */ |
2302 | 2319 | ||
2303 | uint8_t current_topology; | 2320 | uint8_t current_topology; |
@@ -2564,6 +2581,7 @@ typedef struct scsi_qla_host { | |||
2564 | #define OPTROM_SIZE_2300 0x20000 | 2581 | #define OPTROM_SIZE_2300 0x20000 |
2565 | #define OPTROM_SIZE_2322 0x100000 | 2582 | #define OPTROM_SIZE_2322 0x100000 |
2566 | #define OPTROM_SIZE_24XX 0x100000 | 2583 | #define OPTROM_SIZE_24XX 0x100000 |
2584 | #define OPTROM_SIZE_25XX 0x200000 | ||
2567 | 2585 | ||
2568 | #include "qla_gbl.h" | 2586 | #include "qla_gbl.h" |
2569 | #include "qla_dbg.h" | 2587 | #include "qla_dbg.h" |
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 63a11fef5d1b..99fe49618d61 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h | |||
@@ -8,14 +8,17 @@ | |||
8 | #define __QLA_FW_H | 8 | #define __QLA_FW_H |
9 | 9 | ||
10 | #define MBS_CHECKSUM_ERROR 0x4010 | 10 | #define MBS_CHECKSUM_ERROR 0x4010 |
11 | #define MBS_INVALID_PRODUCT_KEY 0x4020 | ||
11 | 12 | ||
12 | /* | 13 | /* |
13 | * Firmware Options. | 14 | * Firmware Options. |
14 | */ | 15 | */ |
15 | #define FO1_ENABLE_PUREX BIT_10 | 16 | #define FO1_ENABLE_PUREX BIT_10 |
16 | #define FO1_DISABLE_LED_CTRL BIT_6 | 17 | #define FO1_DISABLE_LED_CTRL BIT_6 |
18 | #define FO1_ENABLE_8016 BIT_0 | ||
17 | #define FO2_ENABLE_SEL_CLASS2 BIT_5 | 19 | #define FO2_ENABLE_SEL_CLASS2 BIT_5 |
18 | #define FO3_NO_ABTS_ON_LINKDOWN BIT_14 | 20 | #define FO3_NO_ABTS_ON_LINKDOWN BIT_14 |
21 | #define FO3_HOLD_STS_IOCB BIT_12 | ||
19 | 22 | ||
20 | /* | 23 | /* |
21 | * Port Database structure definition for ISP 24xx. | 24 | * Port Database structure definition for ISP 24xx. |
@@ -341,7 +344,9 @@ struct init_cb_24xx { | |||
341 | * BIT 10 = Reserved | 344 | * BIT 10 = Reserved |
342 | * BIT 11 = Enable FC-SP Security | 345 | * BIT 11 = Enable FC-SP Security |
343 | * BIT 12 = FC Tape Enable | 346 | * BIT 12 = FC Tape Enable |
344 | * BIT 13-31 = Reserved | 347 | * BIT 13 = Reserved |
348 | * BIT 14 = Enable Target PRLI Control | ||
349 | * BIT 15-31 = Reserved | ||
345 | */ | 350 | */ |
346 | uint32_t firmware_options_2; | 351 | uint32_t firmware_options_2; |
347 | 352 | ||
@@ -363,7 +368,8 @@ struct init_cb_24xx { | |||
363 | * BIT 13 = Data Rate bit 0 | 368 | * BIT 13 = Data Rate bit 0 |
364 | * BIT 14 = Data Rate bit 1 | 369 | * BIT 14 = Data Rate bit 1 |
365 | * BIT 15 = Data Rate bit 2 | 370 | * BIT 15 = Data Rate bit 2 |
366 | * BIT 16-31 = Reserved | 371 | * BIT 16 = Enable 75 ohm Termination Select |
372 | * BIT 17-31 = Reserved | ||
367 | */ | 373 | */ |
368 | uint32_t firmware_options_3; | 374 | uint32_t firmware_options_3; |
369 | 375 | ||
@@ -435,6 +441,7 @@ struct cmd_type_7 { | |||
435 | #define TMF_LUN_RESET BIT_12 | 441 | #define TMF_LUN_RESET BIT_12 |
436 | #define TMF_CLEAR_TASK_SET BIT_10 | 442 | #define TMF_CLEAR_TASK_SET BIT_10 |
437 | #define TMF_ABORT_TASK_SET BIT_9 | 443 | #define TMF_ABORT_TASK_SET BIT_9 |
444 | #define TMF_DSD_LIST_ENABLE BIT_2 | ||
438 | #define TMF_READ_DATA BIT_1 | 445 | #define TMF_READ_DATA BIT_1 |
439 | #define TMF_WRITE_DATA BIT_0 | 446 | #define TMF_WRITE_DATA BIT_0 |
440 | 447 | ||
@@ -589,7 +596,7 @@ struct els_entry_24xx { | |||
589 | #define EST_SOFI3 (1 << 4) | 596 | #define EST_SOFI3 (1 << 4) |
590 | #define EST_SOFI2 (3 << 4) | 597 | #define EST_SOFI2 (3 << 4) |
591 | 598 | ||
592 | uint32_t rx_xchg_address[2]; /* Receive exchange address. */ | 599 | uint32_t rx_xchg_address; /* Receive exchange address. */ |
593 | uint16_t rx_dsd_count; | 600 | uint16_t rx_dsd_count; |
594 | 601 | ||
595 | uint8_t opcode; | 602 | uint8_t opcode; |
@@ -650,6 +657,7 @@ struct logio_entry_24xx { | |||
650 | 657 | ||
651 | uint16_t control_flags; /* Control flags. */ | 658 | uint16_t control_flags; /* Control flags. */ |
652 | /* Modifiers. */ | 659 | /* Modifiers. */ |
660 | #define LCF_INCLUDE_SNS BIT_10 /* Include SNS (FFFFFC) during LOGO. */ | ||
653 | #define LCF_FCP2_OVERRIDE BIT_9 /* Set/Reset word 3 of PRLI. */ | 661 | #define LCF_FCP2_OVERRIDE BIT_9 /* Set/Reset word 3 of PRLI. */ |
654 | #define LCF_CLASS_2 BIT_8 /* Enable class 2 during PLOGI. */ | 662 | #define LCF_CLASS_2 BIT_8 /* Enable class 2 during PLOGI. */ |
655 | #define LCF_FREE_NPORT BIT_7 /* Release NPORT handle after LOGO. */ | 663 | #define LCF_FREE_NPORT BIT_7 /* Release NPORT handle after LOGO. */ |
@@ -779,6 +787,15 @@ struct device_reg_24xx { | |||
779 | #define FA_RISC_CODE_ADDR 0x20000 | 787 | #define FA_RISC_CODE_ADDR 0x20000 |
780 | #define FA_RISC_CODE_SEGMENTS 2 | 788 | #define FA_RISC_CODE_SEGMENTS 2 |
781 | 789 | ||
790 | #define FA_FW_AREA_ADDR 0x40000 | ||
791 | #define FA_VPD_NVRAM_ADDR 0x48000 | ||
792 | #define FA_FEATURE_ADDR 0x4C000 | ||
793 | #define FA_FLASH_DESCR_ADDR 0x50000 | ||
794 | #define FA_HW_EVENT_ADDR 0x54000 | ||
795 | #define FA_BOOT_LOG_ADDR 0x58000 | ||
796 | #define FA_FW_DUMP0_ADDR 0x60000 | ||
797 | #define FA_FW_DUMP1_ADDR 0x70000 | ||
798 | |||
782 | uint32_t flash_data; /* Flash/NVRAM BIOS data. */ | 799 | uint32_t flash_data; /* Flash/NVRAM BIOS data. */ |
783 | 800 | ||
784 | uint32_t ctrl_status; /* Control/Status. */ | 801 | uint32_t ctrl_status; /* Control/Status. */ |
@@ -859,10 +876,13 @@ struct device_reg_24xx { | |||
859 | #define HCCRX_CLR_RISC_INT 0xA0000000 | 876 | #define HCCRX_CLR_RISC_INT 0xA0000000 |
860 | 877 | ||
861 | uint32_t gpiod; /* GPIO Data register. */ | 878 | uint32_t gpiod; /* GPIO Data register. */ |
879 | |||
862 | /* LED update mask. */ | 880 | /* LED update mask. */ |
863 | #define GPDX_LED_UPDATE_MASK (BIT_20|BIT_19|BIT_18) | 881 | #define GPDX_LED_UPDATE_MASK (BIT_20|BIT_19|BIT_18) |
864 | /* Data update mask. */ | 882 | /* Data update mask. */ |
865 | #define GPDX_DATA_UPDATE_MASK (BIT_17|BIT_16) | 883 | #define GPDX_DATA_UPDATE_MASK (BIT_17|BIT_16) |
884 | /* Data update mask. */ | ||
885 | #define GPDX_DATA_UPDATE_2_MASK (BIT_28|BIT_27|BIT_26|BIT_17|BIT_16) | ||
866 | /* LED control mask. */ | 886 | /* LED control mask. */ |
867 | #define GPDX_LED_COLOR_MASK (BIT_4|BIT_3|BIT_2) | 887 | #define GPDX_LED_COLOR_MASK (BIT_4|BIT_3|BIT_2) |
868 | /* LED bit values. Color names as | 888 | /* LED bit values. Color names as |
@@ -877,6 +897,8 @@ struct device_reg_24xx { | |||
877 | uint32_t gpioe; /* GPIO Enable register. */ | 897 | uint32_t gpioe; /* GPIO Enable register. */ |
878 | /* Enable update mask. */ | 898 | /* Enable update mask. */ |
879 | #define GPEX_ENABLE_UPDATE_MASK (BIT_17|BIT_16) | 899 | #define GPEX_ENABLE_UPDATE_MASK (BIT_17|BIT_16) |
900 | /* Enable update mask. */ | ||
901 | #define GPEX_ENABLE_UPDATE_2_MASK (BIT_28|BIT_27|BIT_26|BIT_17|BIT_16) | ||
880 | /* Enable. */ | 902 | /* Enable. */ |
881 | #define GPEX_ENABLE (BIT_1|BIT_0) | 903 | #define GPEX_ENABLE (BIT_1|BIT_0) |
882 | 904 | ||
@@ -916,6 +938,14 @@ struct device_reg_24xx { | |||
916 | uint16_t mailbox29; | 938 | uint16_t mailbox29; |
917 | uint16_t mailbox30; | 939 | uint16_t mailbox30; |
918 | uint16_t mailbox31; | 940 | uint16_t mailbox31; |
941 | |||
942 | uint32_t iobase_window; | ||
943 | uint32_t unused_4[8]; /* Gap. */ | ||
944 | uint32_t iobase_q; | ||
945 | uint32_t unused_5[2]; /* Gap. */ | ||
946 | uint32_t iobase_select; | ||
947 | uint32_t unused_6[2]; /* Gap. */ | ||
948 | uint32_t iobase_sdata; | ||
919 | }; | 949 | }; |
920 | 950 | ||
921 | /* MID Support ***************************************************************/ | 951 | /* MID Support ***************************************************************/ |
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index b44eff2803ce..aa1e41152283 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -17,6 +17,7 @@ extern int qla2x00_initialize_adapter(scsi_qla_host_t *); | |||
17 | extern int qla2100_pci_config(struct scsi_qla_host *); | 17 | extern int qla2100_pci_config(struct scsi_qla_host *); |
18 | extern int qla2300_pci_config(struct scsi_qla_host *); | 18 | extern int qla2300_pci_config(struct scsi_qla_host *); |
19 | extern int qla24xx_pci_config(scsi_qla_host_t *); | 19 | extern int qla24xx_pci_config(scsi_qla_host_t *); |
20 | extern int qla25xx_pci_config(scsi_qla_host_t *); | ||
20 | extern void qla2x00_reset_chip(struct scsi_qla_host *); | 21 | extern void qla2x00_reset_chip(struct scsi_qla_host *); |
21 | extern void qla24xx_reset_chip(struct scsi_qla_host *); | 22 | extern void qla24xx_reset_chip(struct scsi_qla_host *); |
22 | extern int qla2x00_chip_diag(struct scsi_qla_host *); | 23 | extern int qla2x00_chip_diag(struct scsi_qla_host *); |
@@ -281,6 +282,10 @@ extern int qla2x00_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t, | |||
281 | uint32_t); | 282 | uint32_t); |
282 | extern int qla24xx_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t, | 283 | extern int qla24xx_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t, |
283 | uint32_t); | 284 | uint32_t); |
285 | extern uint8_t *qla25xx_read_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t, | ||
286 | uint32_t); | ||
287 | extern int qla25xx_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t, | ||
288 | uint32_t); | ||
284 | 289 | ||
285 | extern int qla2x00_beacon_on(struct scsi_qla_host *); | 290 | extern int qla2x00_beacon_on(struct scsi_qla_host *); |
286 | extern int qla2x00_beacon_off(struct scsi_qla_host *); | 291 | extern int qla2x00_beacon_off(struct scsi_qla_host *); |
@@ -307,6 +312,7 @@ extern int qla24xx_get_flash_version(scsi_qla_host_t *, void *); | |||
307 | extern void qla2100_fw_dump(scsi_qla_host_t *, int); | 312 | extern void qla2100_fw_dump(scsi_qla_host_t *, int); |
308 | extern void qla2300_fw_dump(scsi_qla_host_t *, int); | 313 | extern void qla2300_fw_dump(scsi_qla_host_t *, int); |
309 | extern void qla24xx_fw_dump(scsi_qla_host_t *, int); | 314 | extern void qla24xx_fw_dump(scsi_qla_host_t *, int); |
315 | extern void qla25xx_fw_dump(scsi_qla_host_t *, int); | ||
310 | extern void qla2x00_dump_regs(scsi_qla_host_t *); | 316 | extern void qla2x00_dump_regs(scsi_qla_host_t *); |
311 | extern void qla2x00_dump_buffer(uint8_t *, uint32_t); | 317 | extern void qla2x00_dump_buffer(uint8_t *, uint32_t); |
312 | extern void qla2x00_print_scsi_cmd(struct scsi_cmnd *); | 318 | extern void qla2x00_print_scsi_cmd(struct scsi_cmnd *); |
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index a086b3f0df65..b06cbb8580d3 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c | |||
@@ -127,7 +127,7 @@ qla2x00_chk_ms_status(scsi_qla_host_t *ha, ms_iocb_entry_t *ms_pkt, | |||
127 | DEBUG2_3(printk("scsi(%ld): %s failed, error status (%x).\n", | 127 | DEBUG2_3(printk("scsi(%ld): %s failed, error status (%x).\n", |
128 | ha->host_no, routine, ms_pkt->entry_status)); | 128 | ha->host_no, routine, ms_pkt->entry_status)); |
129 | } else { | 129 | } else { |
130 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) | 130 | if (IS_FWI2_CAPABLE(ha)) |
131 | comp_status = le16_to_cpu( | 131 | comp_status = le16_to_cpu( |
132 | ((struct ct_entry_24xx *)ms_pkt)->comp_status); | 132 | ((struct ct_entry_24xx *)ms_pkt)->comp_status); |
133 | else | 133 | else |
@@ -180,7 +180,8 @@ qla2x00_ga_nxt(scsi_qla_host_t *ha, fc_port_t *fcport) | |||
180 | 180 | ||
181 | /* Issue GA_NXT */ | 181 | /* Issue GA_NXT */ |
182 | /* Prepare common MS IOCB */ | 182 | /* Prepare common MS IOCB */ |
183 | ms_pkt = ha->isp_ops.prep_ms_iocb(ha, GA_NXT_REQ_SIZE, GA_NXT_RSP_SIZE); | 183 | ms_pkt = ha->isp_ops->prep_ms_iocb(ha, GA_NXT_REQ_SIZE, |
184 | GA_NXT_RSP_SIZE); | ||
184 | 185 | ||
185 | /* Prepare CT request */ | 186 | /* Prepare CT request */ |
186 | ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GA_NXT_CMD, | 187 | ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GA_NXT_CMD, |
@@ -266,7 +267,8 @@ qla2x00_gid_pt(scsi_qla_host_t *ha, sw_info_t *list) | |||
266 | 267 | ||
267 | /* Issue GID_PT */ | 268 | /* Issue GID_PT */ |
268 | /* Prepare common MS IOCB */ | 269 | /* Prepare common MS IOCB */ |
269 | ms_pkt = ha->isp_ops.prep_ms_iocb(ha, GID_PT_REQ_SIZE, GID_PT_RSP_SIZE); | 270 | ms_pkt = ha->isp_ops->prep_ms_iocb(ha, GID_PT_REQ_SIZE, |
271 | GID_PT_RSP_SIZE); | ||
270 | 272 | ||
271 | /* Prepare CT request */ | 273 | /* Prepare CT request */ |
272 | ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GID_PT_CMD, | 274 | ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GID_PT_CMD, |
@@ -338,7 +340,7 @@ qla2x00_gpn_id(scsi_qla_host_t *ha, sw_info_t *list) | |||
338 | for (i = 0; i < MAX_FIBRE_DEVICES; i++) { | 340 | for (i = 0; i < MAX_FIBRE_DEVICES; i++) { |
339 | /* Issue GPN_ID */ | 341 | /* Issue GPN_ID */ |
340 | /* Prepare common MS IOCB */ | 342 | /* Prepare common MS IOCB */ |
341 | ms_pkt = ha->isp_ops.prep_ms_iocb(ha, GPN_ID_REQ_SIZE, | 343 | ms_pkt = ha->isp_ops->prep_ms_iocb(ha, GPN_ID_REQ_SIZE, |
342 | GPN_ID_RSP_SIZE); | 344 | GPN_ID_RSP_SIZE); |
343 | 345 | ||
344 | /* Prepare CT request */ | 346 | /* Prepare CT request */ |
@@ -399,7 +401,7 @@ qla2x00_gnn_id(scsi_qla_host_t *ha, sw_info_t *list) | |||
399 | for (i = 0; i < MAX_FIBRE_DEVICES; i++) { | 401 | for (i = 0; i < MAX_FIBRE_DEVICES; i++) { |
400 | /* Issue GNN_ID */ | 402 | /* Issue GNN_ID */ |
401 | /* Prepare common MS IOCB */ | 403 | /* Prepare common MS IOCB */ |
402 | ms_pkt = ha->isp_ops.prep_ms_iocb(ha, GNN_ID_REQ_SIZE, | 404 | ms_pkt = ha->isp_ops->prep_ms_iocb(ha, GNN_ID_REQ_SIZE, |
403 | GNN_ID_RSP_SIZE); | 405 | GNN_ID_RSP_SIZE); |
404 | 406 | ||
405 | /* Prepare CT request */ | 407 | /* Prepare CT request */ |
@@ -473,7 +475,8 @@ qla2x00_rft_id(scsi_qla_host_t *ha) | |||
473 | 475 | ||
474 | /* Issue RFT_ID */ | 476 | /* Issue RFT_ID */ |
475 | /* Prepare common MS IOCB */ | 477 | /* Prepare common MS IOCB */ |
476 | ms_pkt = ha->isp_ops.prep_ms_iocb(ha, RFT_ID_REQ_SIZE, RFT_ID_RSP_SIZE); | 478 | ms_pkt = ha->isp_ops->prep_ms_iocb(ha, RFT_ID_REQ_SIZE, |
479 | RFT_ID_RSP_SIZE); | ||
477 | 480 | ||
478 | /* Prepare CT request */ | 481 | /* Prepare CT request */ |
479 | ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RFT_ID_CMD, | 482 | ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RFT_ID_CMD, |
@@ -528,7 +531,8 @@ qla2x00_rff_id(scsi_qla_host_t *ha) | |||
528 | 531 | ||
529 | /* Issue RFF_ID */ | 532 | /* Issue RFF_ID */ |
530 | /* Prepare common MS IOCB */ | 533 | /* Prepare common MS IOCB */ |
531 | ms_pkt = ha->isp_ops.prep_ms_iocb(ha, RFF_ID_REQ_SIZE, RFF_ID_RSP_SIZE); | 534 | ms_pkt = ha->isp_ops->prep_ms_iocb(ha, RFF_ID_REQ_SIZE, |
535 | RFF_ID_RSP_SIZE); | ||
532 | 536 | ||
533 | /* Prepare CT request */ | 537 | /* Prepare CT request */ |
534 | ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RFF_ID_CMD, | 538 | ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RFF_ID_CMD, |
@@ -582,7 +586,8 @@ qla2x00_rnn_id(scsi_qla_host_t *ha) | |||
582 | 586 | ||
583 | /* Issue RNN_ID */ | 587 | /* Issue RNN_ID */ |
584 | /* Prepare common MS IOCB */ | 588 | /* Prepare common MS IOCB */ |
585 | ms_pkt = ha->isp_ops.prep_ms_iocb(ha, RNN_ID_REQ_SIZE, RNN_ID_RSP_SIZE); | 589 | ms_pkt = ha->isp_ops->prep_ms_iocb(ha, RNN_ID_REQ_SIZE, |
590 | RNN_ID_RSP_SIZE); | ||
586 | 591 | ||
587 | /* Prepare CT request */ | 592 | /* Prepare CT request */ |
588 | ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RNN_ID_CMD, | 593 | ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RNN_ID_CMD, |
@@ -645,7 +650,7 @@ qla2x00_rsnn_nn(scsi_qla_host_t *ha) | |||
645 | /* Issue RSNN_NN */ | 650 | /* Issue RSNN_NN */ |
646 | /* Prepare common MS IOCB */ | 651 | /* Prepare common MS IOCB */ |
647 | /* Request size adjusted after CT preparation */ | 652 | /* Request size adjusted after CT preparation */ |
648 | ms_pkt = ha->isp_ops.prep_ms_iocb(ha, 0, RSNN_NN_RSP_SIZE); | 653 | ms_pkt = ha->isp_ops->prep_ms_iocb(ha, 0, RSNN_NN_RSP_SIZE); |
649 | 654 | ||
650 | /* Prepare CT request */ | 655 | /* Prepare CT request */ |
651 | ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RSNN_NN_CMD, | 656 | ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RSNN_NN_CMD, |
@@ -1102,7 +1107,7 @@ qla2x00_mgmt_svr_login(scsi_qla_host_t *ha) | |||
1102 | if (ha->flags.management_server_logged_in) | 1107 | if (ha->flags.management_server_logged_in) |
1103 | return ret; | 1108 | return ret; |
1104 | 1109 | ||
1105 | ha->isp_ops.fabric_login(ha, ha->mgmt_svr_loop_id, 0xff, 0xff, 0xfa, | 1110 | ha->isp_ops->fabric_login(ha, ha->mgmt_svr_loop_id, 0xff, 0xff, 0xfa, |
1106 | mb, BIT_1); | 1111 | mb, BIT_1); |
1107 | if (mb[0] != MBS_COMMAND_COMPLETE) { | 1112 | if (mb[0] != MBS_COMMAND_COMPLETE) { |
1108 | DEBUG2_13(printk("%s(%ld): Failed MANAGEMENT_SERVER login: " | 1113 | DEBUG2_13(printk("%s(%ld): Failed MANAGEMENT_SERVER login: " |
@@ -1198,7 +1203,7 @@ qla2x00_update_ms_fdmi_iocb(scsi_qla_host_t *ha, uint32_t req_size) | |||
1198 | ms_iocb_entry_t *ms_pkt = ha->ms_iocb; | 1203 | ms_iocb_entry_t *ms_pkt = ha->ms_iocb; |
1199 | struct ct_entry_24xx *ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb; | 1204 | struct ct_entry_24xx *ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb; |
1200 | 1205 | ||
1201 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 1206 | if (IS_FWI2_CAPABLE(ha)) { |
1202 | ct_pkt->cmd_byte_count = cpu_to_le32(req_size); | 1207 | ct_pkt->cmd_byte_count = cpu_to_le32(req_size); |
1203 | ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count; | 1208 | ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count; |
1204 | } else { | 1209 | } else { |
@@ -1253,7 +1258,7 @@ qla2x00_fdmi_rhba(scsi_qla_host_t *ha) | |||
1253 | /* Issue RHBA */ | 1258 | /* Issue RHBA */ |
1254 | /* Prepare common MS IOCB */ | 1259 | /* Prepare common MS IOCB */ |
1255 | /* Request size adjusted after CT preparation */ | 1260 | /* Request size adjusted after CT preparation */ |
1256 | ms_pkt = ha->isp_ops.prep_ms_fdmi_iocb(ha, 0, RHBA_RSP_SIZE); | 1261 | ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(ha, 0, RHBA_RSP_SIZE); |
1257 | 1262 | ||
1258 | /* Prepare CT request */ | 1263 | /* Prepare CT request */ |
1259 | ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, RHBA_CMD, | 1264 | ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, RHBA_CMD, |
@@ -1373,7 +1378,7 @@ qla2x00_fdmi_rhba(scsi_qla_host_t *ha) | |||
1373 | /* Firmware version */ | 1378 | /* Firmware version */ |
1374 | eiter = (struct ct_fdmi_hba_attr *) (entries + size); | 1379 | eiter = (struct ct_fdmi_hba_attr *) (entries + size); |
1375 | eiter->type = __constant_cpu_to_be16(FDMI_HBA_FIRMWARE_VERSION); | 1380 | eiter->type = __constant_cpu_to_be16(FDMI_HBA_FIRMWARE_VERSION); |
1376 | ha->isp_ops.fw_version_str(ha, eiter->a.fw_version); | 1381 | ha->isp_ops->fw_version_str(ha, eiter->a.fw_version); |
1377 | alen = strlen(eiter->a.fw_version); | 1382 | alen = strlen(eiter->a.fw_version); |
1378 | alen += (alen & 3) ? (4 - (alen & 3)) : 4; | 1383 | alen += (alen & 3) ? (4 - (alen & 3)) : 4; |
1379 | eiter->len = cpu_to_be16(4 + alen); | 1384 | eiter->len = cpu_to_be16(4 + alen); |
@@ -1439,7 +1444,7 @@ qla2x00_fdmi_dhba(scsi_qla_host_t *ha) | |||
1439 | 1444 | ||
1440 | /* Issue RPA */ | 1445 | /* Issue RPA */ |
1441 | /* Prepare common MS IOCB */ | 1446 | /* Prepare common MS IOCB */ |
1442 | ms_pkt = ha->isp_ops.prep_ms_fdmi_iocb(ha, DHBA_REQ_SIZE, | 1447 | ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(ha, DHBA_REQ_SIZE, |
1443 | DHBA_RSP_SIZE); | 1448 | DHBA_RSP_SIZE); |
1444 | 1449 | ||
1445 | /* Prepare CT request */ | 1450 | /* Prepare CT request */ |
@@ -1497,7 +1502,7 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha) | |||
1497 | /* Issue RPA */ | 1502 | /* Issue RPA */ |
1498 | /* Prepare common MS IOCB */ | 1503 | /* Prepare common MS IOCB */ |
1499 | /* Request size adjusted after CT preparation */ | 1504 | /* Request size adjusted after CT preparation */ |
1500 | ms_pkt = ha->isp_ops.prep_ms_fdmi_iocb(ha, 0, RPA_RSP_SIZE); | 1505 | ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(ha, 0, RPA_RSP_SIZE); |
1501 | 1506 | ||
1502 | /* Prepare CT request */ | 1507 | /* Prepare CT request */ |
1503 | ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, RPA_CMD, | 1508 | ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, RPA_CMD, |
@@ -1527,12 +1532,20 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha) | |||
1527 | eiter = (struct ct_fdmi_port_attr *) (entries + size); | 1532 | eiter = (struct ct_fdmi_port_attr *) (entries + size); |
1528 | eiter->type = __constant_cpu_to_be16(FDMI_PORT_SUPPORT_SPEED); | 1533 | eiter->type = __constant_cpu_to_be16(FDMI_PORT_SUPPORT_SPEED); |
1529 | eiter->len = __constant_cpu_to_be16(4 + 4); | 1534 | eiter->len = __constant_cpu_to_be16(4 + 4); |
1530 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) | 1535 | if (IS_QLA25XX(ha)) |
1531 | eiter->a.sup_speed = __constant_cpu_to_be32(4); | 1536 | eiter->a.sup_speed = __constant_cpu_to_be32( |
1537 | FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB| | ||
1538 | FDMI_PORT_SPEED_4GB|FDMI_PORT_SPEED_8GB); | ||
1539 | else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) | ||
1540 | eiter->a.sup_speed = __constant_cpu_to_be32( | ||
1541 | FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB| | ||
1542 | FDMI_PORT_SPEED_4GB); | ||
1532 | else if (IS_QLA23XX(ha)) | 1543 | else if (IS_QLA23XX(ha)) |
1533 | eiter->a.sup_speed = __constant_cpu_to_be32(2); | 1544 | eiter->a.sup_speed =__constant_cpu_to_be32( |
1545 | FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB); | ||
1534 | else | 1546 | else |
1535 | eiter->a.sup_speed = __constant_cpu_to_be32(1); | 1547 | eiter->a.sup_speed = __constant_cpu_to_be32( |
1548 | FDMI_PORT_SPEED_1GB); | ||
1536 | size += 4 + 4; | 1549 | size += 4 + 4; |
1537 | 1550 | ||
1538 | DEBUG13(printk("%s(%ld): SUPPORTED_SPEED=%x.\n", __func__, ha->host_no, | 1551 | DEBUG13(printk("%s(%ld): SUPPORTED_SPEED=%x.\n", __func__, ha->host_no, |
@@ -1543,14 +1556,25 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha) | |||
1543 | eiter->type = __constant_cpu_to_be16(FDMI_PORT_CURRENT_SPEED); | 1556 | eiter->type = __constant_cpu_to_be16(FDMI_PORT_CURRENT_SPEED); |
1544 | eiter->len = __constant_cpu_to_be16(4 + 4); | 1557 | eiter->len = __constant_cpu_to_be16(4 + 4); |
1545 | switch (ha->link_data_rate) { | 1558 | switch (ha->link_data_rate) { |
1546 | case 0: | 1559 | case PORT_SPEED_1GB: |
1547 | eiter->a.cur_speed = __constant_cpu_to_be32(1); | 1560 | eiter->a.cur_speed = |
1561 | __constant_cpu_to_be32(FDMI_PORT_SPEED_1GB); | ||
1562 | break; | ||
1563 | case PORT_SPEED_2GB: | ||
1564 | eiter->a.cur_speed = | ||
1565 | __constant_cpu_to_be32(FDMI_PORT_SPEED_2GB); | ||
1566 | break; | ||
1567 | case PORT_SPEED_4GB: | ||
1568 | eiter->a.cur_speed = | ||
1569 | __constant_cpu_to_be32(FDMI_PORT_SPEED_4GB); | ||
1548 | break; | 1570 | break; |
1549 | case 1: | 1571 | case PORT_SPEED_8GB: |
1550 | eiter->a.cur_speed = __constant_cpu_to_be32(2); | 1572 | eiter->a.cur_speed = |
1573 | __constant_cpu_to_be32(FDMI_PORT_SPEED_8GB); | ||
1551 | break; | 1574 | break; |
1552 | case 3: | 1575 | default: |
1553 | eiter->a.cur_speed = __constant_cpu_to_be32(4); | 1576 | eiter->a.cur_speed = |
1577 | __constant_cpu_to_be32(FDMI_PORT_SPEED_UNKNOWN); | ||
1554 | break; | 1578 | break; |
1555 | } | 1579 | } |
1556 | size += 4 + 4; | 1580 | size += 4 + 4; |
@@ -1562,7 +1586,7 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha) | |||
1562 | eiter = (struct ct_fdmi_port_attr *) (entries + size); | 1586 | eiter = (struct ct_fdmi_port_attr *) (entries + size); |
1563 | eiter->type = __constant_cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE); | 1587 | eiter->type = __constant_cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE); |
1564 | eiter->len = __constant_cpu_to_be16(4 + 4); | 1588 | eiter->len = __constant_cpu_to_be16(4 + 4); |
1565 | max_frame_size = IS_QLA24XX(ha) || IS_QLA54XX(ha) ? | 1589 | max_frame_size = IS_FWI2_CAPABLE(ha) ? |
1566 | (uint32_t) icb24->frame_payload_size: | 1590 | (uint32_t) icb24->frame_payload_size: |
1567 | (uint32_t) ha->init_cb->frame_payload_size; | 1591 | (uint32_t) ha->init_cb->frame_payload_size; |
1568 | eiter->a.max_frame_size = cpu_to_be32(max_frame_size); | 1592 | eiter->a.max_frame_size = cpu_to_be32(max_frame_size); |
@@ -1678,7 +1702,7 @@ qla2x00_gfpn_id(scsi_qla_host_t *ha, sw_info_t *list) | |||
1678 | struct ct_sns_req *ct_req; | 1702 | struct ct_sns_req *ct_req; |
1679 | struct ct_sns_rsp *ct_rsp; | 1703 | struct ct_sns_rsp *ct_rsp; |
1680 | 1704 | ||
1681 | if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) | 1705 | if (!IS_IIDMA_CAPABLE(ha)) |
1682 | return QLA_FUNCTION_FAILED; | 1706 | return QLA_FUNCTION_FAILED; |
1683 | 1707 | ||
1684 | for (i = 0; i < MAX_FIBRE_DEVICES; i++) { | 1708 | for (i = 0; i < MAX_FIBRE_DEVICES; i++) { |
@@ -1686,7 +1710,7 @@ qla2x00_gfpn_id(scsi_qla_host_t *ha, sw_info_t *list) | |||
1686 | memset(list[i].fabric_port_name, 0, WWN_SIZE); | 1710 | memset(list[i].fabric_port_name, 0, WWN_SIZE); |
1687 | 1711 | ||
1688 | /* Prepare common MS IOCB */ | 1712 | /* Prepare common MS IOCB */ |
1689 | ms_pkt = ha->isp_ops.prep_ms_iocb(ha, GFPN_ID_REQ_SIZE, | 1713 | ms_pkt = ha->isp_ops->prep_ms_iocb(ha, GFPN_ID_REQ_SIZE, |
1690 | GFPN_ID_RSP_SIZE); | 1714 | GFPN_ID_RSP_SIZE); |
1691 | 1715 | ||
1692 | /* Prepare CT request */ | 1716 | /* Prepare CT request */ |
@@ -1786,7 +1810,7 @@ qla2x00_gpsc(scsi_qla_host_t *ha, sw_info_t *list) | |||
1786 | struct ct_sns_req *ct_req; | 1810 | struct ct_sns_req *ct_req; |
1787 | struct ct_sns_rsp *ct_rsp; | 1811 | struct ct_sns_rsp *ct_rsp; |
1788 | 1812 | ||
1789 | if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) | 1813 | if (!IS_IIDMA_CAPABLE(ha)) |
1790 | return QLA_FUNCTION_FAILED; | 1814 | return QLA_FUNCTION_FAILED; |
1791 | if (!ha->flags.gpsc_supported) | 1815 | if (!ha->flags.gpsc_supported) |
1792 | return QLA_FUNCTION_FAILED; | 1816 | return QLA_FUNCTION_FAILED; |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index cc6ebb609e98..5ec798c2bf13 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -79,20 +79,20 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha) | |||
79 | set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); | 79 | set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); |
80 | 80 | ||
81 | qla_printk(KERN_INFO, ha, "Configuring PCI space...\n"); | 81 | qla_printk(KERN_INFO, ha, "Configuring PCI space...\n"); |
82 | rval = ha->isp_ops.pci_config(ha); | 82 | rval = ha->isp_ops->pci_config(ha); |
83 | if (rval) { | 83 | if (rval) { |
84 | DEBUG2(printk("scsi(%ld): Unable to configure PCI space.\n", | 84 | DEBUG2(printk("scsi(%ld): Unable to configure PCI space.\n", |
85 | ha->host_no)); | 85 | ha->host_no)); |
86 | return (rval); | 86 | return (rval); |
87 | } | 87 | } |
88 | 88 | ||
89 | ha->isp_ops.reset_chip(ha); | 89 | ha->isp_ops->reset_chip(ha); |
90 | 90 | ||
91 | ha->isp_ops.get_flash_version(ha, ha->request_ring); | 91 | ha->isp_ops->get_flash_version(ha, ha->request_ring); |
92 | 92 | ||
93 | qla_printk(KERN_INFO, ha, "Configure NVRAM parameters...\n"); | 93 | qla_printk(KERN_INFO, ha, "Configure NVRAM parameters...\n"); |
94 | 94 | ||
95 | ha->isp_ops.nvram_config(ha); | 95 | ha->isp_ops->nvram_config(ha); |
96 | 96 | ||
97 | if (ha->flags.disable_serdes) { | 97 | if (ha->flags.disable_serdes) { |
98 | /* Mask HBA via NVRAM settings? */ | 98 | /* Mask HBA via NVRAM settings? */ |
@@ -108,7 +108,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha) | |||
108 | qla_printk(KERN_INFO, ha, "Verifying loaded RISC code...\n"); | 108 | qla_printk(KERN_INFO, ha, "Verifying loaded RISC code...\n"); |
109 | 109 | ||
110 | if (qla2x00_isp_firmware(ha) != QLA_SUCCESS) { | 110 | if (qla2x00_isp_firmware(ha) != QLA_SUCCESS) { |
111 | rval = ha->isp_ops.chip_diag(ha); | 111 | rval = ha->isp_ops->chip_diag(ha); |
112 | if (rval) | 112 | if (rval) |
113 | return (rval); | 113 | return (rval); |
114 | rval = qla2x00_setup_chip(ha); | 114 | rval = qla2x00_setup_chip(ha); |
@@ -129,14 +129,13 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha) | |||
129 | int | 129 | int |
130 | qla2100_pci_config(scsi_qla_host_t *ha) | 130 | qla2100_pci_config(scsi_qla_host_t *ha) |
131 | { | 131 | { |
132 | int ret; | ||
133 | uint16_t w; | 132 | uint16_t w; |
134 | uint32_t d; | 133 | uint32_t d; |
135 | unsigned long flags; | 134 | unsigned long flags; |
136 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | 135 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; |
137 | 136 | ||
138 | pci_set_master(ha->pdev); | 137 | pci_set_master(ha->pdev); |
139 | ret = pci_set_mwi(ha->pdev); | 138 | pci_try_set_mwi(ha->pdev); |
140 | 139 | ||
141 | pci_read_config_word(ha->pdev, PCI_COMMAND, &w); | 140 | pci_read_config_word(ha->pdev, PCI_COMMAND, &w); |
142 | w |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR); | 141 | w |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR); |
@@ -164,7 +163,6 @@ qla2100_pci_config(scsi_qla_host_t *ha) | |||
164 | int | 163 | int |
165 | qla2300_pci_config(scsi_qla_host_t *ha) | 164 | qla2300_pci_config(scsi_qla_host_t *ha) |
166 | { | 165 | { |
167 | int ret; | ||
168 | uint16_t w; | 166 | uint16_t w; |
169 | uint32_t d; | 167 | uint32_t d; |
170 | unsigned long flags = 0; | 168 | unsigned long flags = 0; |
@@ -172,7 +170,7 @@ qla2300_pci_config(scsi_qla_host_t *ha) | |||
172 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | 170 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; |
173 | 171 | ||
174 | pci_set_master(ha->pdev); | 172 | pci_set_master(ha->pdev); |
175 | ret = pci_set_mwi(ha->pdev); | 173 | pci_try_set_mwi(ha->pdev); |
176 | 174 | ||
177 | pci_read_config_word(ha->pdev, PCI_COMMAND, &w); | 175 | pci_read_config_word(ha->pdev, PCI_COMMAND, &w); |
178 | w |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR); | 176 | w |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR); |
@@ -250,15 +248,13 @@ qla2300_pci_config(scsi_qla_host_t *ha) | |||
250 | int | 248 | int |
251 | qla24xx_pci_config(scsi_qla_host_t *ha) | 249 | qla24xx_pci_config(scsi_qla_host_t *ha) |
252 | { | 250 | { |
253 | int ret; | ||
254 | uint16_t w; | 251 | uint16_t w; |
255 | uint32_t d; | 252 | uint32_t d; |
256 | unsigned long flags = 0; | 253 | unsigned long flags = 0; |
257 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 254 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
258 | int pcix_cmd_reg, pcie_dctl_reg; | ||
259 | 255 | ||
260 | pci_set_master(ha->pdev); | 256 | pci_set_master(ha->pdev); |
261 | ret = pci_set_mwi(ha->pdev); | 257 | pci_try_set_mwi(ha->pdev); |
262 | 258 | ||
263 | pci_read_config_word(ha->pdev, PCI_COMMAND, &w); | 259 | pci_read_config_word(ha->pdev, PCI_COMMAND, &w); |
264 | w |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR); | 260 | w |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR); |
@@ -268,28 +264,12 @@ qla24xx_pci_config(scsi_qla_host_t *ha) | |||
268 | pci_write_config_byte(ha->pdev, PCI_LATENCY_TIMER, 0x80); | 264 | pci_write_config_byte(ha->pdev, PCI_LATENCY_TIMER, 0x80); |
269 | 265 | ||
270 | /* PCI-X -- adjust Maximum Memory Read Byte Count (2048). */ | 266 | /* PCI-X -- adjust Maximum Memory Read Byte Count (2048). */ |
271 | pcix_cmd_reg = pci_find_capability(ha->pdev, PCI_CAP_ID_PCIX); | 267 | if (pci_find_capability(ha->pdev, PCI_CAP_ID_PCIX)) |
272 | if (pcix_cmd_reg) { | 268 | pcix_set_mmrbc(ha->pdev, 2048); |
273 | uint16_t pcix_cmd; | ||
274 | |||
275 | pcix_cmd_reg += PCI_X_CMD; | ||
276 | pci_read_config_word(ha->pdev, pcix_cmd_reg, &pcix_cmd); | ||
277 | pcix_cmd &= ~PCI_X_CMD_MAX_READ; | ||
278 | pcix_cmd |= 0x0008; | ||
279 | pci_write_config_word(ha->pdev, pcix_cmd_reg, pcix_cmd); | ||
280 | } | ||
281 | 269 | ||
282 | /* PCIe -- adjust Maximum Read Request Size (2048). */ | 270 | /* PCIe -- adjust Maximum Read Request Size (2048). */ |
283 | pcie_dctl_reg = pci_find_capability(ha->pdev, PCI_CAP_ID_EXP); | 271 | if (pci_find_capability(ha->pdev, PCI_CAP_ID_EXP)) |
284 | if (pcie_dctl_reg) { | 272 | pcie_set_readrq(ha->pdev, 2048); |
285 | uint16_t pcie_dctl; | ||
286 | |||
287 | pcie_dctl_reg += PCI_EXP_DEVCTL; | ||
288 | pci_read_config_word(ha->pdev, pcie_dctl_reg, &pcie_dctl); | ||
289 | pcie_dctl &= ~PCI_EXP_DEVCTL_READRQ; | ||
290 | pcie_dctl |= 0x4000; | ||
291 | pci_write_config_word(ha->pdev, pcie_dctl_reg, pcie_dctl); | ||
292 | } | ||
293 | 273 | ||
294 | /* Reset expansion ROM address decode enable */ | 274 | /* Reset expansion ROM address decode enable */ |
295 | pci_read_config_dword(ha->pdev, PCI_ROM_ADDRESS, &d); | 275 | pci_read_config_dword(ha->pdev, PCI_ROM_ADDRESS, &d); |
@@ -307,6 +287,40 @@ qla24xx_pci_config(scsi_qla_host_t *ha) | |||
307 | } | 287 | } |
308 | 288 | ||
309 | /** | 289 | /** |
290 | * qla25xx_pci_config() - Setup ISP25xx PCI configuration registers. | ||
291 | * @ha: HA context | ||
292 | * | ||
293 | * Returns 0 on success. | ||
294 | */ | ||
295 | int | ||
296 | qla25xx_pci_config(scsi_qla_host_t *ha) | ||
297 | { | ||
298 | uint16_t w; | ||
299 | uint32_t d; | ||
300 | |||
301 | pci_set_master(ha->pdev); | ||
302 | pci_try_set_mwi(ha->pdev); | ||
303 | |||
304 | pci_read_config_word(ha->pdev, PCI_COMMAND, &w); | ||
305 | w |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR); | ||
306 | w &= ~PCI_COMMAND_INTX_DISABLE; | ||
307 | pci_write_config_word(ha->pdev, PCI_COMMAND, w); | ||
308 | |||
309 | /* PCIe -- adjust Maximum Read Request Size (2048). */ | ||
310 | if (pci_find_capability(ha->pdev, PCI_CAP_ID_EXP)) | ||
311 | pcie_set_readrq(ha->pdev, 2048); | ||
312 | |||
313 | /* Reset expansion ROM address decode enable */ | ||
314 | pci_read_config_dword(ha->pdev, PCI_ROM_ADDRESS, &d); | ||
315 | d &= ~PCI_ROM_ADDRESS_ENABLE; | ||
316 | pci_write_config_dword(ha->pdev, PCI_ROM_ADDRESS, d); | ||
317 | |||
318 | ha->chip_revision = ha->pdev->revision; | ||
319 | |||
320 | return QLA_SUCCESS; | ||
321 | } | ||
322 | |||
323 | /** | ||
310 | * qla2x00_isp_firmware() - Choose firmware image. | 324 | * qla2x00_isp_firmware() - Choose firmware image. |
311 | * @ha: HA context | 325 | * @ha: HA context |
312 | * | 326 | * |
@@ -351,7 +365,7 @@ qla2x00_reset_chip(scsi_qla_host_t *ha) | |||
351 | uint32_t cnt; | 365 | uint32_t cnt; |
352 | uint16_t cmd; | 366 | uint16_t cmd; |
353 | 367 | ||
354 | ha->isp_ops.disable_intrs(ha); | 368 | ha->isp_ops->disable_intrs(ha); |
355 | 369 | ||
356 | spin_lock_irqsave(&ha->hardware_lock, flags); | 370 | spin_lock_irqsave(&ha->hardware_lock, flags); |
357 | 371 | ||
@@ -551,7 +565,7 @@ qla24xx_reset_risc(scsi_qla_host_t *ha) | |||
551 | void | 565 | void |
552 | qla24xx_reset_chip(scsi_qla_host_t *ha) | 566 | qla24xx_reset_chip(scsi_qla_host_t *ha) |
553 | { | 567 | { |
554 | ha->isp_ops.disable_intrs(ha); | 568 | ha->isp_ops->disable_intrs(ha); |
555 | 569 | ||
556 | /* Perform RISC reset. */ | 570 | /* Perform RISC reset. */ |
557 | qla24xx_reset_risc(ha); | 571 | qla24xx_reset_risc(ha); |
@@ -736,8 +750,10 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *ha) | |||
736 | fixed_size = offsetof(struct qla2300_fw_dump, data_ram); | 750 | fixed_size = offsetof(struct qla2300_fw_dump, data_ram); |
737 | mem_size = (ha->fw_memory_size - 0x11000 + 1) * | 751 | mem_size = (ha->fw_memory_size - 0x11000 + 1) * |
738 | sizeof(uint16_t); | 752 | sizeof(uint16_t); |
739 | } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 753 | } else if (IS_FWI2_CAPABLE(ha)) { |
740 | fixed_size = offsetof(struct qla24xx_fw_dump, ext_mem); | 754 | fixed_size = IS_QLA25XX(ha) ? |
755 | offsetof(struct qla25xx_fw_dump, ext_mem): | ||
756 | offsetof(struct qla24xx_fw_dump, ext_mem); | ||
741 | mem_size = (ha->fw_memory_size - 0x100000 + 1) * | 757 | mem_size = (ha->fw_memory_size - 0x100000 + 1) * |
742 | sizeof(uint32_t); | 758 | sizeof(uint32_t); |
743 | 759 | ||
@@ -879,7 +895,7 @@ qla2x00_setup_chip(scsi_qla_host_t *ha) | |||
879 | uint32_t srisc_address = 0; | 895 | uint32_t srisc_address = 0; |
880 | 896 | ||
881 | /* Load firmware sequences */ | 897 | /* Load firmware sequences */ |
882 | rval = ha->isp_ops.load_risc(ha, &srisc_address); | 898 | rval = ha->isp_ops->load_risc(ha, &srisc_address); |
883 | if (rval == QLA_SUCCESS) { | 899 | if (rval == QLA_SUCCESS) { |
884 | DEBUG(printk("scsi(%ld): Verifying Checksum of loaded RISC " | 900 | DEBUG(printk("scsi(%ld): Verifying Checksum of loaded RISC " |
885 | "code.\n", ha->host_no)); | 901 | "code.\n", ha->host_no)); |
@@ -1130,12 +1146,12 @@ qla2x00_init_rings(scsi_qla_host_t *ha) | |||
1130 | /* Initialize response queue entries */ | 1146 | /* Initialize response queue entries */ |
1131 | qla2x00_init_response_q_entries(ha); | 1147 | qla2x00_init_response_q_entries(ha); |
1132 | 1148 | ||
1133 | ha->isp_ops.config_rings(ha); | 1149 | ha->isp_ops->config_rings(ha); |
1134 | 1150 | ||
1135 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1151 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
1136 | 1152 | ||
1137 | /* Update any ISP specific firmware options before initialization. */ | 1153 | /* Update any ISP specific firmware options before initialization. */ |
1138 | ha->isp_ops.update_fw_options(ha); | 1154 | ha->isp_ops->update_fw_options(ha); |
1139 | 1155 | ||
1140 | DEBUG(printk("scsi(%ld): Issue init firmware.\n", ha->host_no)); | 1156 | DEBUG(printk("scsi(%ld): Issue init firmware.\n", ha->host_no)); |
1141 | 1157 | ||
@@ -1459,7 +1475,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) | |||
1459 | ha->nvram_base = 0x80; | 1475 | ha->nvram_base = 0x80; |
1460 | 1476 | ||
1461 | /* Get NVRAM data and calculate checksum. */ | 1477 | /* Get NVRAM data and calculate checksum. */ |
1462 | ha->isp_ops.read_nvram(ha, ptr, ha->nvram_base, ha->nvram_size); | 1478 | ha->isp_ops->read_nvram(ha, ptr, ha->nvram_base, ha->nvram_size); |
1463 | for (cnt = 0, chksum = 0; cnt < ha->nvram_size; cnt++) | 1479 | for (cnt = 0, chksum = 0; cnt < ha->nvram_size; cnt++) |
1464 | chksum += *ptr++; | 1480 | chksum += *ptr++; |
1465 | 1481 | ||
@@ -2119,7 +2135,7 @@ qla2x00_iidma_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) | |||
2119 | int rval; | 2135 | int rval; |
2120 | uint16_t port_speed, mb[6]; | 2136 | uint16_t port_speed, mb[6]; |
2121 | 2137 | ||
2122 | if (!IS_QLA24XX(ha)) | 2138 | if (!IS_IIDMA_CAPABLE(ha)) |
2123 | return; | 2139 | return; |
2124 | 2140 | ||
2125 | switch (be16_to_cpu(fcport->fp_speed)) { | 2141 | switch (be16_to_cpu(fcport->fp_speed)) { |
@@ -2267,7 +2283,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha) | |||
2267 | scsi_qla_host_t *pha = to_qla_parent(ha); | 2283 | scsi_qla_host_t *pha = to_qla_parent(ha); |
2268 | 2284 | ||
2269 | /* If FL port exists, then SNS is present */ | 2285 | /* If FL port exists, then SNS is present */ |
2270 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) | 2286 | if (IS_FWI2_CAPABLE(ha)) |
2271 | loop_id = NPH_F_PORT; | 2287 | loop_id = NPH_F_PORT; |
2272 | else | 2288 | else |
2273 | loop_id = SNS_FL_PORT; | 2289 | loop_id = SNS_FL_PORT; |
@@ -2294,11 +2310,11 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha) | |||
2294 | qla2x00_fdmi_register(ha); | 2310 | qla2x00_fdmi_register(ha); |
2295 | 2311 | ||
2296 | /* Ensure we are logged into the SNS. */ | 2312 | /* Ensure we are logged into the SNS. */ |
2297 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) | 2313 | if (IS_FWI2_CAPABLE(ha)) |
2298 | loop_id = NPH_SNS; | 2314 | loop_id = NPH_SNS; |
2299 | else | 2315 | else |
2300 | loop_id = SIMPLE_NAME_SERVER; | 2316 | loop_id = SIMPLE_NAME_SERVER; |
2301 | ha->isp_ops.fabric_login(ha, loop_id, 0xff, 0xff, | 2317 | ha->isp_ops->fabric_login(ha, loop_id, 0xff, 0xff, |
2302 | 0xfc, mb, BIT_1 | BIT_0); | 2318 | 0xfc, mb, BIT_1 | BIT_0); |
2303 | if (mb[0] != MBS_COMMAND_COMPLETE) { | 2319 | if (mb[0] != MBS_COMMAND_COMPLETE) { |
2304 | DEBUG2(qla_printk(KERN_INFO, ha, | 2320 | DEBUG2(qla_printk(KERN_INFO, ha, |
@@ -2355,7 +2371,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha) | |||
2355 | (fcport->flags & FCF_TAPE_PRESENT) == 0 && | 2371 | (fcport->flags & FCF_TAPE_PRESENT) == 0 && |
2356 | fcport->port_type != FCT_INITIATOR && | 2372 | fcport->port_type != FCT_INITIATOR && |
2357 | fcport->port_type != FCT_BROADCAST) { | 2373 | fcport->port_type != FCT_BROADCAST) { |
2358 | ha->isp_ops.fabric_logout(ha, | 2374 | ha->isp_ops->fabric_logout(ha, |
2359 | fcport->loop_id, | 2375 | fcport->loop_id, |
2360 | fcport->d_id.b.domain, | 2376 | fcport->d_id.b.domain, |
2361 | fcport->d_id.b.area, | 2377 | fcport->d_id.b.area, |
@@ -2664,7 +2680,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports) | |||
2664 | (fcport->flags & FCF_TAPE_PRESENT) == 0 && | 2680 | (fcport->flags & FCF_TAPE_PRESENT) == 0 && |
2665 | fcport->port_type != FCT_INITIATOR && | 2681 | fcport->port_type != FCT_INITIATOR && |
2666 | fcport->port_type != FCT_BROADCAST) { | 2682 | fcport->port_type != FCT_BROADCAST) { |
2667 | ha->isp_ops.fabric_logout(ha, fcport->loop_id, | 2683 | ha->isp_ops->fabric_logout(ha, fcport->loop_id, |
2668 | fcport->d_id.b.domain, fcport->d_id.b.area, | 2684 | fcport->d_id.b.domain, fcport->d_id.b.area, |
2669 | fcport->d_id.b.al_pa); | 2685 | fcport->d_id.b.al_pa); |
2670 | fcport->loop_id = FC_NO_LOOP_ID; | 2686 | fcport->loop_id = FC_NO_LOOP_ID; |
@@ -2919,7 +2935,7 @@ qla2x00_fabric_dev_login(scsi_qla_host_t *ha, fc_port_t *fcport, | |||
2919 | opts |= BIT_1; | 2935 | opts |= BIT_1; |
2920 | rval = qla2x00_get_port_database(ha, fcport, opts); | 2936 | rval = qla2x00_get_port_database(ha, fcport, opts); |
2921 | if (rval != QLA_SUCCESS) { | 2937 | if (rval != QLA_SUCCESS) { |
2922 | ha->isp_ops.fabric_logout(ha, fcport->loop_id, | 2938 | ha->isp_ops->fabric_logout(ha, fcport->loop_id, |
2923 | fcport->d_id.b.domain, fcport->d_id.b.area, | 2939 | fcport->d_id.b.domain, fcport->d_id.b.area, |
2924 | fcport->d_id.b.al_pa); | 2940 | fcport->d_id.b.al_pa); |
2925 | qla2x00_mark_device_lost(ha, fcport, 1, 0); | 2941 | qla2x00_mark_device_lost(ha, fcport, 1, 0); |
@@ -2964,7 +2980,7 @@ qla2x00_fabric_login(scsi_qla_host_t *ha, fc_port_t *fcport, | |||
2964 | fcport->d_id.b.area, fcport->d_id.b.al_pa)); | 2980 | fcport->d_id.b.area, fcport->d_id.b.al_pa)); |
2965 | 2981 | ||
2966 | /* Login fcport on switch. */ | 2982 | /* Login fcport on switch. */ |
2967 | ha->isp_ops.fabric_login(ha, fcport->loop_id, | 2983 | ha->isp_ops->fabric_login(ha, fcport->loop_id, |
2968 | fcport->d_id.b.domain, fcport->d_id.b.area, | 2984 | fcport->d_id.b.domain, fcport->d_id.b.area, |
2969 | fcport->d_id.b.al_pa, mb, BIT_0); | 2985 | fcport->d_id.b.al_pa, mb, BIT_0); |
2970 | if (mb[0] == MBS_PORT_ID_USED) { | 2986 | if (mb[0] == MBS_PORT_ID_USED) { |
@@ -3032,7 +3048,7 @@ qla2x00_fabric_login(scsi_qla_host_t *ha, fc_port_t *fcport, | |||
3032 | * dead. | 3048 | * dead. |
3033 | */ | 3049 | */ |
3034 | *next_loopid = fcport->loop_id; | 3050 | *next_loopid = fcport->loop_id; |
3035 | ha->isp_ops.fabric_logout(ha, fcport->loop_id, | 3051 | ha->isp_ops->fabric_logout(ha, fcport->loop_id, |
3036 | fcport->d_id.b.domain, fcport->d_id.b.area, | 3052 | fcport->d_id.b.domain, fcport->d_id.b.area, |
3037 | fcport->d_id.b.al_pa); | 3053 | fcport->d_id.b.al_pa); |
3038 | qla2x00_mark_device_lost(ha, fcport, 1, 0); | 3054 | qla2x00_mark_device_lost(ha, fcport, 1, 0); |
@@ -3050,7 +3066,7 @@ qla2x00_fabric_login(scsi_qla_host_t *ha, fc_port_t *fcport, | |||
3050 | fcport->d_id.b.al_pa, fcport->loop_id, jiffies)); | 3066 | fcport->d_id.b.al_pa, fcport->loop_id, jiffies)); |
3051 | 3067 | ||
3052 | *next_loopid = fcport->loop_id; | 3068 | *next_loopid = fcport->loop_id; |
3053 | ha->isp_ops.fabric_logout(ha, fcport->loop_id, | 3069 | ha->isp_ops->fabric_logout(ha, fcport->loop_id, |
3054 | fcport->d_id.b.domain, fcport->d_id.b.area, | 3070 | fcport->d_id.b.domain, fcport->d_id.b.area, |
3055 | fcport->d_id.b.al_pa); | 3071 | fcport->d_id.b.al_pa); |
3056 | fcport->loop_id = FC_NO_LOOP_ID; | 3072 | fcport->loop_id = FC_NO_LOOP_ID; |
@@ -3206,7 +3222,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) | |||
3206 | 3222 | ||
3207 | qla_printk(KERN_INFO, ha, | 3223 | qla_printk(KERN_INFO, ha, |
3208 | "Performing ISP error recovery - ha= %p.\n", ha); | 3224 | "Performing ISP error recovery - ha= %p.\n", ha); |
3209 | ha->isp_ops.reset_chip(ha); | 3225 | ha->isp_ops->reset_chip(ha); |
3210 | 3226 | ||
3211 | atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); | 3227 | atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); |
3212 | if (atomic_read(&ha->loop_state) != LOOP_DOWN) { | 3228 | if (atomic_read(&ha->loop_state) != LOOP_DOWN) { |
@@ -3232,9 +3248,9 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) | |||
3232 | } | 3248 | } |
3233 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 3249 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
3234 | 3250 | ||
3235 | ha->isp_ops.get_flash_version(ha, ha->request_ring); | 3251 | ha->isp_ops->get_flash_version(ha, ha->request_ring); |
3236 | 3252 | ||
3237 | ha->isp_ops.nvram_config(ha); | 3253 | ha->isp_ops->nvram_config(ha); |
3238 | 3254 | ||
3239 | if (!qla2x00_restart_isp(ha)) { | 3255 | if (!qla2x00_restart_isp(ha)) { |
3240 | clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); | 3256 | clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); |
@@ -3249,7 +3265,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) | |||
3249 | 3265 | ||
3250 | ha->flags.online = 1; | 3266 | ha->flags.online = 1; |
3251 | 3267 | ||
3252 | ha->isp_ops.enable_intrs(ha); | 3268 | ha->isp_ops->enable_intrs(ha); |
3253 | 3269 | ||
3254 | ha->isp_abort_cnt = 0; | 3270 | ha->isp_abort_cnt = 0; |
3255 | clear_bit(ISP_ABORT_RETRY, &ha->dpc_flags); | 3271 | clear_bit(ISP_ABORT_RETRY, &ha->dpc_flags); |
@@ -3274,7 +3290,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) | |||
3274 | * The next call disables the board | 3290 | * The next call disables the board |
3275 | * completely. | 3291 | * completely. |
3276 | */ | 3292 | */ |
3277 | ha->isp_ops.reset_adapter(ha); | 3293 | ha->isp_ops->reset_adapter(ha); |
3278 | ha->flags.online = 0; | 3294 | ha->flags.online = 0; |
3279 | clear_bit(ISP_ABORT_RETRY, | 3295 | clear_bit(ISP_ABORT_RETRY, |
3280 | &ha->dpc_flags); | 3296 | &ha->dpc_flags); |
@@ -3331,7 +3347,7 @@ qla2x00_restart_isp(scsi_qla_host_t *ha) | |||
3331 | /* If firmware needs to be loaded */ | 3347 | /* If firmware needs to be loaded */ |
3332 | if (qla2x00_isp_firmware(ha)) { | 3348 | if (qla2x00_isp_firmware(ha)) { |
3333 | ha->flags.online = 0; | 3349 | ha->flags.online = 0; |
3334 | if (!(status = ha->isp_ops.chip_diag(ha))) { | 3350 | if (!(status = ha->isp_ops->chip_diag(ha))) { |
3335 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) { | 3351 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) { |
3336 | status = qla2x00_setup_chip(ha); | 3352 | status = qla2x00_setup_chip(ha); |
3337 | goto done; | 3353 | goto done; |
@@ -3423,7 +3439,7 @@ qla2x00_reset_adapter(scsi_qla_host_t *ha) | |||
3423 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | 3439 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; |
3424 | 3440 | ||
3425 | ha->flags.online = 0; | 3441 | ha->flags.online = 0; |
3426 | ha->isp_ops.disable_intrs(ha); | 3442 | ha->isp_ops->disable_intrs(ha); |
3427 | 3443 | ||
3428 | spin_lock_irqsave(&ha->hardware_lock, flags); | 3444 | spin_lock_irqsave(&ha->hardware_lock, flags); |
3429 | WRT_REG_WORD(®->hccr, HCCR_RESET_RISC); | 3445 | WRT_REG_WORD(®->hccr, HCCR_RESET_RISC); |
@@ -3440,7 +3456,7 @@ qla24xx_reset_adapter(scsi_qla_host_t *ha) | |||
3440 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 3456 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
3441 | 3457 | ||
3442 | ha->flags.online = 0; | 3458 | ha->flags.online = 0; |
3443 | ha->isp_ops.disable_intrs(ha); | 3459 | ha->isp_ops->disable_intrs(ha); |
3444 | 3460 | ||
3445 | spin_lock_irqsave(&ha->hardware_lock, flags); | 3461 | spin_lock_irqsave(&ha->hardware_lock, flags); |
3446 | WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_RESET); | 3462 | WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_RESET); |
@@ -3498,7 +3514,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) | |||
3498 | 3514 | ||
3499 | /* Get NVRAM data and calculate checksum. */ | 3515 | /* Get NVRAM data and calculate checksum. */ |
3500 | dptr = (uint32_t *)nv; | 3516 | dptr = (uint32_t *)nv; |
3501 | ha->isp_ops.read_nvram(ha, (uint8_t *)dptr, ha->nvram_base, | 3517 | ha->isp_ops->read_nvram(ha, (uint8_t *)dptr, ha->nvram_base, |
3502 | ha->nvram_size); | 3518 | ha->nvram_size); |
3503 | for (cnt = 0, chksum = 0; cnt < ha->nvram_size >> 2; cnt++) | 3519 | for (cnt = 0, chksum = 0; cnt < ha->nvram_size >> 2; cnt++) |
3504 | chksum += le32_to_cpu(*dptr++); | 3520 | chksum += le32_to_cpu(*dptr++); |
@@ -4012,7 +4028,7 @@ qla2x00_try_to_stop_firmware(scsi_qla_host_t *ha) | |||
4012 | { | 4028 | { |
4013 | int ret, retries; | 4029 | int ret, retries; |
4014 | 4030 | ||
4015 | if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) | 4031 | if (!IS_FWI2_CAPABLE(ha)) |
4016 | return; | 4032 | return; |
4017 | if (!ha->fw_major_version) | 4033 | if (!ha->fw_major_version) |
4018 | return; | 4034 | return; |
diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h index d3023338628f..8e3b04464cff 100644 --- a/drivers/scsi/qla2xxx/qla_inline.h +++ b/drivers/scsi/qla2xxx/qla_inline.h | |||
@@ -104,7 +104,7 @@ static __inline__ void qla2x00_poll(scsi_qla_host_t *); | |||
104 | static inline void | 104 | static inline void |
105 | qla2x00_poll(scsi_qla_host_t *ha) | 105 | qla2x00_poll(scsi_qla_host_t *ha) |
106 | { | 106 | { |
107 | ha->isp_ops.intr_handler(0, ha); | 107 | ha->isp_ops->intr_handler(0, ha); |
108 | } | 108 | } |
109 | 109 | ||
110 | static __inline__ void qla2x00_check_fabric_devices(scsi_qla_host_t *); | 110 | static __inline__ void qla2x00_check_fabric_devices(scsi_qla_host_t *); |
@@ -163,7 +163,7 @@ static inline int qla2x00_is_reserved_id(scsi_qla_host_t *, uint16_t); | |||
163 | static inline int | 163 | static inline int |
164 | qla2x00_is_reserved_id(scsi_qla_host_t *ha, uint16_t loop_id) | 164 | qla2x00_is_reserved_id(scsi_qla_host_t *ha, uint16_t loop_id) |
165 | { | 165 | { |
166 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) | 166 | if (IS_FWI2_CAPABLE(ha)) |
167 | return (loop_id > NPH_LAST_HANDLE); | 167 | return (loop_id > NPH_LAST_HANDLE); |
168 | 168 | ||
169 | return ((loop_id > ha->last_loop_id && loop_id < SNS_FIRST_LOOP_ID) || | 169 | return ((loop_id > ha->last_loop_id && loop_id < SNS_FIRST_LOOP_ID) || |
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index c71863ff5489..3a5e78cb6b3f 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c | |||
@@ -326,7 +326,7 @@ qla2x00_start_scsi(srb_t *sp) | |||
326 | tot_dsds = nseg; | 326 | tot_dsds = nseg; |
327 | 327 | ||
328 | /* Calculate the number of request entries needed. */ | 328 | /* Calculate the number of request entries needed. */ |
329 | req_cnt = ha->isp_ops.calc_req_entries(tot_dsds); | 329 | req_cnt = ha->isp_ops->calc_req_entries(tot_dsds); |
330 | if (ha->req_q_cnt < (req_cnt + 2)) { | 330 | if (ha->req_q_cnt < (req_cnt + 2)) { |
331 | cnt = RD_REG_WORD_RELAXED(ISP_REQ_Q_OUT(ha, reg)); | 331 | cnt = RD_REG_WORD_RELAXED(ISP_REQ_Q_OUT(ha, reg)); |
332 | if (ha->req_ring_index < cnt) | 332 | if (ha->req_ring_index < cnt) |
@@ -364,7 +364,7 @@ qla2x00_start_scsi(srb_t *sp) | |||
364 | cmd_pkt->byte_count = cpu_to_le32((uint32_t)scsi_bufflen(cmd)); | 364 | cmd_pkt->byte_count = cpu_to_le32((uint32_t)scsi_bufflen(cmd)); |
365 | 365 | ||
366 | /* Build IOCB segments */ | 366 | /* Build IOCB segments */ |
367 | ha->isp_ops.build_iocbs(sp, cmd_pkt, tot_dsds); | 367 | ha->isp_ops->build_iocbs(sp, cmd_pkt, tot_dsds); |
368 | 368 | ||
369 | /* Set total data segment count. */ | 369 | /* Set total data segment count. */ |
370 | cmd_pkt->entry_count = (uint8_t)req_cnt; | 370 | cmd_pkt->entry_count = (uint8_t)req_cnt; |
@@ -432,7 +432,7 @@ __qla2x00_marker(scsi_qla_host_t *ha, uint16_t loop_id, uint16_t lun, | |||
432 | mrk->entry_type = MARKER_TYPE; | 432 | mrk->entry_type = MARKER_TYPE; |
433 | mrk->modifier = type; | 433 | mrk->modifier = type; |
434 | if (type != MK_SYNC_ALL) { | 434 | if (type != MK_SYNC_ALL) { |
435 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 435 | if (IS_FWI2_CAPABLE(ha)) { |
436 | mrk24 = (struct mrk_entry_24xx *) mrk; | 436 | mrk24 = (struct mrk_entry_24xx *) mrk; |
437 | mrk24->nport_handle = cpu_to_le16(loop_id); | 437 | mrk24->nport_handle = cpu_to_le16(loop_id); |
438 | mrk24->lun[1] = LSB(lun); | 438 | mrk24->lun[1] = LSB(lun); |
@@ -487,7 +487,7 @@ qla2x00_req_pkt(scsi_qla_host_t *ha) | |||
487 | for (timer = HZ; timer; timer--) { | 487 | for (timer = HZ; timer; timer--) { |
488 | if ((req_cnt + 2) >= ha->req_q_cnt) { | 488 | if ((req_cnt + 2) >= ha->req_q_cnt) { |
489 | /* Calculate number of free request entries. */ | 489 | /* Calculate number of free request entries. */ |
490 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) | 490 | if (IS_FWI2_CAPABLE(ha)) |
491 | cnt = (uint16_t)RD_REG_DWORD( | 491 | cnt = (uint16_t)RD_REG_DWORD( |
492 | ®->isp24.req_q_out); | 492 | ®->isp24.req_q_out); |
493 | else | 493 | else |
@@ -561,7 +561,7 @@ qla2x00_isp_cmd(scsi_qla_host_t *ha) | |||
561 | ha->request_ring_ptr++; | 561 | ha->request_ring_ptr++; |
562 | 562 | ||
563 | /* Set chip new ring index. */ | 563 | /* Set chip new ring index. */ |
564 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 564 | if (IS_FWI2_CAPABLE(ha)) { |
565 | WRT_REG_DWORD(®->isp24.req_q_in, ha->req_ring_index); | 565 | WRT_REG_DWORD(®->isp24.req_q_in, ha->req_ring_index); |
566 | RD_REG_DWORD_RELAXED(®->isp24.req_q_in); | 566 | RD_REG_DWORD_RELAXED(®->isp24.req_q_in); |
567 | } else { | 567 | } else { |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 0ba4c8d37879..b8f226ae2633 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -143,7 +143,7 @@ qla2300_intr_handler(int irq, void *dev_id) | |||
143 | WRT_REG_WORD(®->hccr, HCCR_RESET_RISC); | 143 | WRT_REG_WORD(®->hccr, HCCR_RESET_RISC); |
144 | RD_REG_WORD(®->hccr); | 144 | RD_REG_WORD(®->hccr); |
145 | 145 | ||
146 | ha->isp_ops.fw_dump(ha, 1); | 146 | ha->isp_ops->fw_dump(ha, 1); |
147 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 147 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); |
148 | break; | 148 | break; |
149 | } else if ((stat & HSR_RISC_INT) == 0) | 149 | } else if ((stat & HSR_RISC_INT) == 0) |
@@ -247,7 +247,7 @@ void | |||
247 | qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | 247 | qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) |
248 | { | 248 | { |
249 | #define LS_UNKNOWN 2 | 249 | #define LS_UNKNOWN 2 |
250 | static char *link_speeds[5] = { "1", "2", "?", "4", "10" }; | 250 | static char *link_speeds[5] = { "1", "2", "?", "4", "8" }; |
251 | char *link_speed; | 251 | char *link_speed; |
252 | uint16_t handle_cnt; | 252 | uint16_t handle_cnt; |
253 | uint16_t cnt; | 253 | uint16_t cnt; |
@@ -334,9 +334,9 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
334 | "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh.\n", | 334 | "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh.\n", |
335 | mb[1], mb[2], mb[3]); | 335 | mb[1], mb[2], mb[3]); |
336 | 336 | ||
337 | ha->isp_ops.fw_dump(ha, 1); | 337 | ha->isp_ops->fw_dump(ha, 1); |
338 | 338 | ||
339 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 339 | if (IS_FWI2_CAPABLE(ha)) { |
340 | if (mb[1] == 0 && mb[2] == 0) { | 340 | if (mb[1] == 0 && mb[2] == 0) { |
341 | qla_printk(KERN_ERR, ha, | 341 | qla_printk(KERN_ERR, ha, |
342 | "Unrecoverable Hardware Error: adapter " | 342 | "Unrecoverable Hardware Error: adapter " |
@@ -601,7 +601,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
601 | "scsi(%ld): [R|Z]IO update completion.\n", | 601 | "scsi(%ld): [R|Z]IO update completion.\n", |
602 | ha->host_no)); | 602 | ha->host_no)); |
603 | 603 | ||
604 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) | 604 | if (IS_FWI2_CAPABLE(ha)) |
605 | qla24xx_process_response_queue(ha); | 605 | qla24xx_process_response_queue(ha); |
606 | else | 606 | else |
607 | qla2x00_process_response_queue(ha); | 607 | qla2x00_process_response_queue(ha); |
@@ -823,7 +823,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
823 | 823 | ||
824 | sts = (sts_entry_t *) pkt; | 824 | sts = (sts_entry_t *) pkt; |
825 | sts24 = (struct sts_entry_24xx *) pkt; | 825 | sts24 = (struct sts_entry_24xx *) pkt; |
826 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 826 | if (IS_FWI2_CAPABLE(ha)) { |
827 | comp_status = le16_to_cpu(sts24->comp_status); | 827 | comp_status = le16_to_cpu(sts24->comp_status); |
828 | scsi_status = le16_to_cpu(sts24->scsi_status) & SS_MASK; | 828 | scsi_status = le16_to_cpu(sts24->scsi_status) & SS_MASK; |
829 | } else { | 829 | } else { |
@@ -872,7 +872,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
872 | fcport = sp->fcport; | 872 | fcport = sp->fcport; |
873 | 873 | ||
874 | sense_len = rsp_info_len = resid_len = fw_resid_len = 0; | 874 | sense_len = rsp_info_len = resid_len = fw_resid_len = 0; |
875 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 875 | if (IS_FWI2_CAPABLE(ha)) { |
876 | sense_len = le32_to_cpu(sts24->sense_len); | 876 | sense_len = le32_to_cpu(sts24->sense_len); |
877 | rsp_info_len = le32_to_cpu(sts24->rsp_data_len); | 877 | rsp_info_len = le32_to_cpu(sts24->rsp_data_len); |
878 | resid_len = le32_to_cpu(sts24->rsp_residual_count); | 878 | resid_len = le32_to_cpu(sts24->rsp_residual_count); |
@@ -891,7 +891,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
891 | /* Check for any FCP transport errors. */ | 891 | /* Check for any FCP transport errors. */ |
892 | if (scsi_status & SS_RESPONSE_INFO_LEN_VALID) { | 892 | if (scsi_status & SS_RESPONSE_INFO_LEN_VALID) { |
893 | /* Sense data lies beyond any FCP RESPONSE data. */ | 893 | /* Sense data lies beyond any FCP RESPONSE data. */ |
894 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) | 894 | if (IS_FWI2_CAPABLE(ha)) |
895 | sense_data += rsp_info_len; | 895 | sense_data += rsp_info_len; |
896 | if (rsp_info_len > 3 && rsp_info[3]) { | 896 | if (rsp_info_len > 3 && rsp_info[3]) { |
897 | DEBUG2(printk("scsi(%ld:%d:%d:%d) FCP I/O protocol " | 897 | DEBUG2(printk("scsi(%ld:%d:%d:%d) FCP I/O protocol " |
@@ -990,7 +990,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
990 | case CS_DATA_UNDERRUN: | 990 | case CS_DATA_UNDERRUN: |
991 | resid = resid_len; | 991 | resid = resid_len; |
992 | /* Use F/W calculated residual length. */ | 992 | /* Use F/W calculated residual length. */ |
993 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) | 993 | if (IS_FWI2_CAPABLE(ha)) |
994 | resid = fw_resid_len; | 994 | resid = fw_resid_len; |
995 | 995 | ||
996 | if (scsi_status & SS_RESIDUAL_UNDER) { | 996 | if (scsi_status & SS_RESIDUAL_UNDER) { |
@@ -1062,6 +1062,25 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
1062 | cp->device->id, cp->device->lun, cp, | 1062 | cp->device->id, cp->device->lun, cp, |
1063 | cp->serial_number)); | 1063 | cp->serial_number)); |
1064 | 1064 | ||
1065 | /* | ||
1066 | * In case of a Underrun condition, set both the lscsi | ||
1067 | * status and the completion status to appropriate | ||
1068 | * values. | ||
1069 | */ | ||
1070 | if (resid && | ||
1071 | ((unsigned)(cp->request_bufflen - resid) < | ||
1072 | cp->underflow)) { | ||
1073 | DEBUG2(qla_printk(KERN_INFO, ha, | ||
1074 | "scsi(%ld:%d:%d:%d): Mid-layer underflow " | ||
1075 | "detected (%x of %x bytes)...returning " | ||
1076 | "error status.\n", ha->host_no, | ||
1077 | cp->device->channel, cp->device->id, | ||
1078 | cp->device->lun, resid, | ||
1079 | cp->request_bufflen)); | ||
1080 | |||
1081 | cp->result = DID_ERROR << 16 | lscsi_status; | ||
1082 | } | ||
1083 | |||
1065 | if (sense_len) | 1084 | if (sense_len) |
1066 | DEBUG5(qla2x00_dump_buffer(cp->sense_buffer, | 1085 | DEBUG5(qla2x00_dump_buffer(cp->sense_buffer, |
1067 | CMD_ACTUAL_SNSLEN(cp))); | 1086 | CMD_ACTUAL_SNSLEN(cp))); |
@@ -1166,7 +1185,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
1166 | case CS_TIMEOUT: | 1185 | case CS_TIMEOUT: |
1167 | cp->result = DID_BUS_BUSY << 16; | 1186 | cp->result = DID_BUS_BUSY << 16; |
1168 | 1187 | ||
1169 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 1188 | if (IS_FWI2_CAPABLE(ha)) { |
1170 | DEBUG2(printk(KERN_INFO | 1189 | DEBUG2(printk(KERN_INFO |
1171 | "scsi(%ld:%d:%d:%d): TIMEOUT status detected " | 1190 | "scsi(%ld:%d:%d:%d): TIMEOUT status detected " |
1172 | "0x%x-0x%x\n", ha->host_no, cp->device->channel, | 1191 | "0x%x-0x%x\n", ha->host_no, cp->device->channel, |
@@ -1235,7 +1254,7 @@ qla2x00_status_cont_entry(scsi_qla_host_t *ha, sts_cont_entry_t *pkt) | |||
1235 | } | 1254 | } |
1236 | 1255 | ||
1237 | /* Move sense data. */ | 1256 | /* Move sense data. */ |
1238 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) | 1257 | if (IS_FWI2_CAPABLE(ha)) |
1239 | host_to_fcp_swap(pkt->data, sizeof(pkt->data)); | 1258 | host_to_fcp_swap(pkt->data, sizeof(pkt->data)); |
1240 | memcpy(sp->request_sense_ptr, pkt->data, sense_sz); | 1259 | memcpy(sp->request_sense_ptr, pkt->data, sense_sz); |
1241 | DEBUG5(qla2x00_dump_buffer(sp->request_sense_ptr, sense_sz)); | 1260 | DEBUG5(qla2x00_dump_buffer(sp->request_sense_ptr, sense_sz)); |
@@ -1483,7 +1502,7 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
1483 | 1502 | ||
1484 | qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " | 1503 | qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " |
1485 | "Dumping firmware!\n", hccr); | 1504 | "Dumping firmware!\n", hccr); |
1486 | ha->isp_ops.fw_dump(ha, 1); | 1505 | ha->isp_ops->fw_dump(ha, 1); |
1487 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 1506 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); |
1488 | break; | 1507 | break; |
1489 | } else if ((stat & HSRX_RISC_INT) == 0) | 1508 | } else if ((stat & HSRX_RISC_INT) == 0) |
@@ -1617,7 +1636,7 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1617 | 1636 | ||
1618 | qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " | 1637 | qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " |
1619 | "Dumping firmware!\n", hccr); | 1638 | "Dumping firmware!\n", hccr); |
1620 | ha->isp_ops.fw_dump(ha, 1); | 1639 | ha->isp_ops->fw_dump(ha, 1); |
1621 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 1640 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); |
1622 | break; | 1641 | break; |
1623 | } else if ((stat & HSRX_RISC_INT) == 0) | 1642 | } else if ((stat & HSRX_RISC_INT) == 0) |
@@ -1739,11 +1758,11 @@ qla2x00_request_irqs(scsi_qla_host_t *ha) | |||
1739 | int ret; | 1758 | int ret; |
1740 | 1759 | ||
1741 | /* If possible, enable MSI-X. */ | 1760 | /* If possible, enable MSI-X. */ |
1742 | if (!IS_QLA2432(ha)) | 1761 | if (!IS_QLA2432(ha) && !IS_QLA2532(ha)) |
1743 | goto skip_msix; | 1762 | goto skip_msix; |
1744 | 1763 | ||
1745 | if (ha->chip_revision < QLA_MSIX_CHIP_REV_24XX || | 1764 | if (IS_QLA2432(ha) && (ha->chip_revision < QLA_MSIX_CHIP_REV_24XX || |
1746 | !QLA_MSIX_FW_MODE_1(ha->fw_attributes)) { | 1765 | !QLA_MSIX_FW_MODE_1(ha->fw_attributes))) { |
1747 | DEBUG2(qla_printk(KERN_WARNING, ha, | 1766 | DEBUG2(qla_printk(KERN_WARNING, ha, |
1748 | "MSI-X: Unsupported ISP2432 (0x%X, 0x%X).\n", | 1767 | "MSI-X: Unsupported ISP2432 (0x%X, 0x%X).\n", |
1749 | ha->chip_revision, ha->fw_attributes)); | 1768 | ha->chip_revision, ha->fw_attributes)); |
@@ -1762,7 +1781,7 @@ qla2x00_request_irqs(scsi_qla_host_t *ha) | |||
1762 | "MSI-X: Falling back-to INTa mode -- %d.\n", ret); | 1781 | "MSI-X: Falling back-to INTa mode -- %d.\n", ret); |
1763 | skip_msix: | 1782 | skip_msix: |
1764 | 1783 | ||
1765 | if (!IS_QLA24XX(ha)) | 1784 | if (!IS_QLA24XX(ha) && !IS_QLA2532(ha)) |
1766 | goto skip_msi; | 1785 | goto skip_msi; |
1767 | 1786 | ||
1768 | ret = pci_enable_msi(ha->pdev); | 1787 | ret = pci_enable_msi(ha->pdev); |
@@ -1772,7 +1791,7 @@ skip_msix: | |||
1772 | } | 1791 | } |
1773 | skip_msi: | 1792 | skip_msi: |
1774 | 1793 | ||
1775 | ret = request_irq(ha->pdev->irq, ha->isp_ops.intr_handler, | 1794 | ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler, |
1776 | IRQF_DISABLED|IRQF_SHARED, QLA2XXX_DRIVER_NAME, ha); | 1795 | IRQF_DISABLED|IRQF_SHARED, QLA2XXX_DRIVER_NAME, ha); |
1777 | if (!ret) { | 1796 | if (!ret) { |
1778 | ha->flags.inta_enabled = 1; | 1797 | ha->flags.inta_enabled = 1; |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 2cd0cff25928..d3746ec80a85 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -90,7 +90,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *pvha, mbx_cmd_t *mcp) | |||
90 | spin_lock_irqsave(&ha->hardware_lock, flags); | 90 | spin_lock_irqsave(&ha->hardware_lock, flags); |
91 | 91 | ||
92 | /* Load mailbox registers. */ | 92 | /* Load mailbox registers. */ |
93 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) | 93 | if (IS_FWI2_CAPABLE(ha)) |
94 | optr = (uint16_t __iomem *)®->isp24.mailbox0; | 94 | optr = (uint16_t __iomem *)®->isp24.mailbox0; |
95 | else | 95 | else |
96 | optr = (uint16_t __iomem *)MAILBOX_REG(ha, ®->isp, 0); | 96 | optr = (uint16_t __iomem *)MAILBOX_REG(ha, ®->isp, 0); |
@@ -154,7 +154,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *pvha, mbx_cmd_t *mcp) | |||
154 | 154 | ||
155 | set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); | 155 | set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); |
156 | 156 | ||
157 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) | 157 | if (IS_FWI2_CAPABLE(ha)) |
158 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_SET_HOST_INT); | 158 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_SET_HOST_INT); |
159 | else | 159 | else |
160 | WRT_REG_WORD(®->isp.hccr, HCCR_SET_HOST_INT); | 160 | WRT_REG_WORD(®->isp.hccr, HCCR_SET_HOST_INT); |
@@ -175,7 +175,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *pvha, mbx_cmd_t *mcp) | |||
175 | DEBUG3_11(printk("%s(%ld): cmd=%x POLLING MODE.\n", __func__, | 175 | DEBUG3_11(printk("%s(%ld): cmd=%x POLLING MODE.\n", __func__, |
176 | ha->host_no, command)); | 176 | ha->host_no, command)); |
177 | 177 | ||
178 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) | 178 | if (IS_FWI2_CAPABLE(ha)) |
179 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_SET_HOST_INT); | 179 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_SET_HOST_INT); |
180 | else | 180 | else |
181 | WRT_REG_WORD(®->isp.hccr, HCCR_SET_HOST_INT); | 181 | WRT_REG_WORD(®->isp.hccr, HCCR_SET_HOST_INT); |
@@ -228,7 +228,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *pvha, mbx_cmd_t *mcp) | |||
228 | uint16_t mb0; | 228 | uint16_t mb0; |
229 | uint32_t ictrl; | 229 | uint32_t ictrl; |
230 | 230 | ||
231 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 231 | if (IS_FWI2_CAPABLE(ha)) { |
232 | mb0 = RD_REG_WORD(®->isp24.mailbox0); | 232 | mb0 = RD_REG_WORD(®->isp24.mailbox0); |
233 | ictrl = RD_REG_DWORD(®->isp24.ictrl); | 233 | ictrl = RD_REG_DWORD(®->isp24.ictrl); |
234 | } else { | 234 | } else { |
@@ -322,7 +322,7 @@ qla2x00_load_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint32_t risc_addr, | |||
322 | 322 | ||
323 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); | 323 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
324 | 324 | ||
325 | if (MSW(risc_addr) || IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 325 | if (MSW(risc_addr) || IS_FWI2_CAPABLE(ha)) { |
326 | mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED; | 326 | mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED; |
327 | mcp->mb[8] = MSW(risc_addr); | 327 | mcp->mb[8] = MSW(risc_addr); |
328 | mcp->out_mb = MBX_8|MBX_0; | 328 | mcp->out_mb = MBX_8|MBX_0; |
@@ -336,7 +336,7 @@ qla2x00_load_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint32_t risc_addr, | |||
336 | mcp->mb[6] = MSW(MSD(req_dma)); | 336 | mcp->mb[6] = MSW(MSD(req_dma)); |
337 | mcp->mb[7] = LSW(MSD(req_dma)); | 337 | mcp->mb[7] = LSW(MSD(req_dma)); |
338 | mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1; | 338 | mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1; |
339 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 339 | if (IS_FWI2_CAPABLE(ha)) { |
340 | mcp->mb[4] = MSW(risc_code_size); | 340 | mcp->mb[4] = MSW(risc_code_size); |
341 | mcp->mb[5] = LSW(risc_code_size); | 341 | mcp->mb[5] = LSW(risc_code_size); |
342 | mcp->out_mb |= MBX_5|MBX_4; | 342 | mcp->out_mb |= MBX_5|MBX_4; |
@@ -387,7 +387,7 @@ qla2x00_execute_fw(scsi_qla_host_t *ha, uint32_t risc_addr) | |||
387 | mcp->mb[0] = MBC_EXECUTE_FIRMWARE; | 387 | mcp->mb[0] = MBC_EXECUTE_FIRMWARE; |
388 | mcp->out_mb = MBX_0; | 388 | mcp->out_mb = MBX_0; |
389 | mcp->in_mb = MBX_0; | 389 | mcp->in_mb = MBX_0; |
390 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 390 | if (IS_FWI2_CAPABLE(ha)) { |
391 | mcp->mb[1] = MSW(risc_addr); | 391 | mcp->mb[1] = MSW(risc_addr); |
392 | mcp->mb[2] = LSW(risc_addr); | 392 | mcp->mb[2] = LSW(risc_addr); |
393 | mcp->mb[3] = 0; | 393 | mcp->mb[3] = 0; |
@@ -410,7 +410,7 @@ qla2x00_execute_fw(scsi_qla_host_t *ha, uint32_t risc_addr) | |||
410 | DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x.\n", __func__, | 410 | DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x.\n", __func__, |
411 | ha->host_no, rval, mcp->mb[0])); | 411 | ha->host_no, rval, mcp->mb[0])); |
412 | } else { | 412 | } else { |
413 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 413 | if (IS_FWI2_CAPABLE(ha)) { |
414 | DEBUG11(printk("%s(%ld): done exchanges=%x.\n", | 414 | DEBUG11(printk("%s(%ld): done exchanges=%x.\n", |
415 | __func__, ha->host_no, mcp->mb[1])); | 415 | __func__, ha->host_no, mcp->mb[1])); |
416 | } else { | 416 | } else { |
@@ -551,7 +551,7 @@ qla2x00_set_fw_options(scsi_qla_host_t *ha, uint16_t *fwopts) | |||
551 | mcp->mb[3] = fwopts[3]; | 551 | mcp->mb[3] = fwopts[3]; |
552 | mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; | 552 | mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; |
553 | mcp->in_mb = MBX_0; | 553 | mcp->in_mb = MBX_0; |
554 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 554 | if (IS_FWI2_CAPABLE(ha)) { |
555 | mcp->in_mb |= MBX_1; | 555 | mcp->in_mb |= MBX_1; |
556 | } else { | 556 | } else { |
557 | mcp->mb[10] = fwopts[10]; | 557 | mcp->mb[10] = fwopts[10]; |
@@ -664,7 +664,7 @@ qla2x00_verify_checksum(scsi_qla_host_t *ha, uint32_t risc_addr) | |||
664 | mcp->mb[0] = MBC_VERIFY_CHECKSUM; | 664 | mcp->mb[0] = MBC_VERIFY_CHECKSUM; |
665 | mcp->out_mb = MBX_0; | 665 | mcp->out_mb = MBX_0; |
666 | mcp->in_mb = MBX_0; | 666 | mcp->in_mb = MBX_0; |
667 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 667 | if (IS_FWI2_CAPABLE(ha)) { |
668 | mcp->mb[1] = MSW(risc_addr); | 668 | mcp->mb[1] = MSW(risc_addr); |
669 | mcp->mb[2] = LSW(risc_addr); | 669 | mcp->mb[2] = LSW(risc_addr); |
670 | mcp->out_mb |= MBX_2|MBX_1; | 670 | mcp->out_mb |= MBX_2|MBX_1; |
@@ -681,8 +681,8 @@ qla2x00_verify_checksum(scsi_qla_host_t *ha, uint32_t risc_addr) | |||
681 | 681 | ||
682 | if (rval != QLA_SUCCESS) { | 682 | if (rval != QLA_SUCCESS) { |
683 | DEBUG2_3_11(printk("%s(%ld): failed=%x chk sum=%x.\n", __func__, | 683 | DEBUG2_3_11(printk("%s(%ld): failed=%x chk sum=%x.\n", __func__, |
684 | ha->host_no, rval, (IS_QLA24XX(ha) || IS_QLA54XX(ha) ? | 684 | ha->host_no, rval, IS_FWI2_CAPABLE(ha) ? |
685 | (mcp->mb[2] << 16) | mcp->mb[1]: mcp->mb[1]))); | 685 | (mcp->mb[2] << 16) | mcp->mb[1]: mcp->mb[1])); |
686 | } else { | 686 | } else { |
687 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); | 687 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
688 | } | 688 | } |
@@ -739,7 +739,7 @@ qla2x00_issue_iocb(scsi_qla_host_t *ha, void* buffer, dma_addr_t phys_addr, | |||
739 | 739 | ||
740 | /* Mask reserved bits. */ | 740 | /* Mask reserved bits. */ |
741 | sts_entry->entry_status &= | 741 | sts_entry->entry_status &= |
742 | IS_QLA24XX(ha) || IS_QLA54XX(ha) ? RF_MASK_24XX :RF_MASK; | 742 | IS_FWI2_CAPABLE(ha) ? RF_MASK_24XX :RF_MASK; |
743 | } | 743 | } |
744 | 744 | ||
745 | return rval; | 745 | return rval; |
@@ -1085,7 +1085,7 @@ qla2x00_get_port_database(scsi_qla_host_t *ha, fc_port_t *fcport, uint8_t opt) | |||
1085 | memset(pd, 0, max(PORT_DATABASE_SIZE, PORT_DATABASE_24XX_SIZE)); | 1085 | memset(pd, 0, max(PORT_DATABASE_SIZE, PORT_DATABASE_24XX_SIZE)); |
1086 | 1086 | ||
1087 | mcp->mb[0] = MBC_GET_PORT_DATABASE; | 1087 | mcp->mb[0] = MBC_GET_PORT_DATABASE; |
1088 | if (opt != 0 && !IS_QLA24XX(ha) && !IS_QLA54XX(ha)) | 1088 | if (opt != 0 && !IS_FWI2_CAPABLE(ha)) |
1089 | mcp->mb[0] = MBC_ENHANCED_GET_PORT_DATABASE; | 1089 | mcp->mb[0] = MBC_ENHANCED_GET_PORT_DATABASE; |
1090 | mcp->mb[2] = MSW(pd_dma); | 1090 | mcp->mb[2] = MSW(pd_dma); |
1091 | mcp->mb[3] = LSW(pd_dma); | 1091 | mcp->mb[3] = LSW(pd_dma); |
@@ -1094,7 +1094,7 @@ qla2x00_get_port_database(scsi_qla_host_t *ha, fc_port_t *fcport, uint8_t opt) | |||
1094 | mcp->mb[9] = ha->vp_idx; | 1094 | mcp->mb[9] = ha->vp_idx; |
1095 | mcp->out_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; | 1095 | mcp->out_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; |
1096 | mcp->in_mb = MBX_0; | 1096 | mcp->in_mb = MBX_0; |
1097 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 1097 | if (IS_FWI2_CAPABLE(ha)) { |
1098 | mcp->mb[1] = fcport->loop_id; | 1098 | mcp->mb[1] = fcport->loop_id; |
1099 | mcp->mb[10] = opt; | 1099 | mcp->mb[10] = opt; |
1100 | mcp->out_mb |= MBX_10|MBX_1; | 1100 | mcp->out_mb |= MBX_10|MBX_1; |
@@ -1107,15 +1107,15 @@ qla2x00_get_port_database(scsi_qla_host_t *ha, fc_port_t *fcport, uint8_t opt) | |||
1107 | mcp->mb[1] = fcport->loop_id << 8 | opt; | 1107 | mcp->mb[1] = fcport->loop_id << 8 | opt; |
1108 | mcp->out_mb |= MBX_1; | 1108 | mcp->out_mb |= MBX_1; |
1109 | } | 1109 | } |
1110 | mcp->buf_size = (IS_QLA24XX(ha) || IS_QLA54XX(ha) ? | 1110 | mcp->buf_size = IS_FWI2_CAPABLE(ha) ? |
1111 | PORT_DATABASE_24XX_SIZE : PORT_DATABASE_SIZE); | 1111 | PORT_DATABASE_24XX_SIZE : PORT_DATABASE_SIZE; |
1112 | mcp->flags = MBX_DMA_IN; | 1112 | mcp->flags = MBX_DMA_IN; |
1113 | mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2); | 1113 | mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2); |
1114 | rval = qla2x00_mailbox_command(ha, mcp); | 1114 | rval = qla2x00_mailbox_command(ha, mcp); |
1115 | if (rval != QLA_SUCCESS) | 1115 | if (rval != QLA_SUCCESS) |
1116 | goto gpd_error_out; | 1116 | goto gpd_error_out; |
1117 | 1117 | ||
1118 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 1118 | if (IS_FWI2_CAPABLE(ha)) { |
1119 | pd24 = (struct port_database_24xx *) pd; | 1119 | pd24 = (struct port_database_24xx *) pd; |
1120 | 1120 | ||
1121 | /* Check for logged in state. */ | 1121 | /* Check for logged in state. */ |
@@ -1333,7 +1333,7 @@ qla2x00_lip_reset(scsi_qla_host_t *ha) | |||
1333 | 1333 | ||
1334 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); | 1334 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
1335 | 1335 | ||
1336 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 1336 | if (IS_FWI2_CAPABLE(ha)) { |
1337 | mcp->mb[0] = MBC_LIP_FULL_LOGIN; | 1337 | mcp->mb[0] = MBC_LIP_FULL_LOGIN; |
1338 | mcp->mb[1] = BIT_6; | 1338 | mcp->mb[1] = BIT_6; |
1339 | mcp->mb[2] = 0; | 1339 | mcp->mb[2] = 0; |
@@ -1637,7 +1637,7 @@ qla2x00_login_local_device(scsi_qla_host_t *ha, fc_port_t *fcport, | |||
1637 | mbx_cmd_t mc; | 1637 | mbx_cmd_t mc; |
1638 | mbx_cmd_t *mcp = &mc; | 1638 | mbx_cmd_t *mcp = &mc; |
1639 | 1639 | ||
1640 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) | 1640 | if (IS_FWI2_CAPABLE(ha)) |
1641 | return qla24xx_login_fabric(ha, fcport->loop_id, | 1641 | return qla24xx_login_fabric(ha, fcport->loop_id, |
1642 | fcport->d_id.b.domain, fcport->d_id.b.area, | 1642 | fcport->d_id.b.domain, fcport->d_id.b.area, |
1643 | fcport->d_id.b.al_pa, mb_ret, opt); | 1643 | fcport->d_id.b.al_pa, mb_ret, opt); |
@@ -1821,7 +1821,7 @@ qla2x00_full_login_lip(scsi_qla_host_t *ha) | |||
1821 | ha->host_no)); | 1821 | ha->host_no)); |
1822 | 1822 | ||
1823 | mcp->mb[0] = MBC_LIP_FULL_LOGIN; | 1823 | mcp->mb[0] = MBC_LIP_FULL_LOGIN; |
1824 | mcp->mb[1] = IS_QLA24XX(ha) || IS_QLA54XX(ha) ? BIT_3: 0; | 1824 | mcp->mb[1] = IS_FWI2_CAPABLE(ha) ? BIT_3: 0; |
1825 | mcp->mb[2] = 0; | 1825 | mcp->mb[2] = 0; |
1826 | mcp->mb[3] = 0; | 1826 | mcp->mb[3] = 0; |
1827 | mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; | 1827 | mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; |
@@ -1871,7 +1871,7 @@ qla2x00_get_id_list(scsi_qla_host_t *ha, void *id_list, dma_addr_t id_list_dma, | |||
1871 | 1871 | ||
1872 | mcp->mb[0] = MBC_GET_ID_LIST; | 1872 | mcp->mb[0] = MBC_GET_ID_LIST; |
1873 | mcp->out_mb = MBX_0; | 1873 | mcp->out_mb = MBX_0; |
1874 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 1874 | if (IS_FWI2_CAPABLE(ha)) { |
1875 | mcp->mb[2] = MSW(id_list_dma); | 1875 | mcp->mb[2] = MSW(id_list_dma); |
1876 | mcp->mb[3] = LSW(id_list_dma); | 1876 | mcp->mb[3] = LSW(id_list_dma); |
1877 | mcp->mb[6] = MSW(MSD(id_list_dma)); | 1877 | mcp->mb[6] = MSW(MSD(id_list_dma)); |
@@ -2063,7 +2063,7 @@ qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id, | |||
2063 | mcp->mb[7] = LSW(MSD(stat_buf_dma)); | 2063 | mcp->mb[7] = LSW(MSD(stat_buf_dma)); |
2064 | mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; | 2064 | mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; |
2065 | mcp->in_mb = MBX_0; | 2065 | mcp->in_mb = MBX_0; |
2066 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 2066 | if (IS_FWI2_CAPABLE(ha)) { |
2067 | mcp->mb[1] = loop_id; | 2067 | mcp->mb[1] = loop_id; |
2068 | mcp->mb[4] = 0; | 2068 | mcp->mb[4] = 0; |
2069 | mcp->mb[10] = 0; | 2069 | mcp->mb[10] = 0; |
@@ -2334,7 +2334,7 @@ qla2x00_system_error(scsi_qla_host_t *ha) | |||
2334 | mbx_cmd_t mc; | 2334 | mbx_cmd_t mc; |
2335 | mbx_cmd_t *mcp = &mc; | 2335 | mbx_cmd_t *mcp = &mc; |
2336 | 2336 | ||
2337 | if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) | 2337 | if (!IS_FWI2_CAPABLE(ha)) |
2338 | return QLA_FUNCTION_FAILED; | 2338 | return QLA_FUNCTION_FAILED; |
2339 | 2339 | ||
2340 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); | 2340 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
@@ -2444,7 +2444,7 @@ qla2x00_stop_firmware(scsi_qla_host_t *ha) | |||
2444 | mbx_cmd_t mc; | 2444 | mbx_cmd_t mc; |
2445 | mbx_cmd_t *mcp = &mc; | 2445 | mbx_cmd_t *mcp = &mc; |
2446 | 2446 | ||
2447 | if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) | 2447 | if (!IS_FWI2_CAPABLE(ha)) |
2448 | return QLA_FUNCTION_FAILED; | 2448 | return QLA_FUNCTION_FAILED; |
2449 | 2449 | ||
2450 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); | 2450 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
@@ -2474,7 +2474,7 @@ qla2x00_trace_control(scsi_qla_host_t *ha, uint16_t ctrl, dma_addr_t eft_dma, | |||
2474 | mbx_cmd_t mc; | 2474 | mbx_cmd_t mc; |
2475 | mbx_cmd_t *mcp = &mc; | 2475 | mbx_cmd_t *mcp = &mc; |
2476 | 2476 | ||
2477 | if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) | 2477 | if (!IS_FWI2_CAPABLE(ha)) |
2478 | return QLA_FUNCTION_FAILED; | 2478 | return QLA_FUNCTION_FAILED; |
2479 | 2479 | ||
2480 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); | 2480 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
@@ -2514,7 +2514,7 @@ qla2x00_read_sfp(scsi_qla_host_t *ha, dma_addr_t sfp_dma, uint16_t addr, | |||
2514 | mbx_cmd_t mc; | 2514 | mbx_cmd_t mc; |
2515 | mbx_cmd_t *mcp = &mc; | 2515 | mbx_cmd_t *mcp = &mc; |
2516 | 2516 | ||
2517 | if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) | 2517 | if (!IS_FWI2_CAPABLE(ha)) |
2518 | return QLA_FUNCTION_FAILED; | 2518 | return QLA_FUNCTION_FAILED; |
2519 | 2519 | ||
2520 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); | 2520 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
@@ -2552,7 +2552,7 @@ qla2x00_get_idma_speed(scsi_qla_host_t *ha, uint16_t loop_id, | |||
2552 | mbx_cmd_t mc; | 2552 | mbx_cmd_t mc; |
2553 | mbx_cmd_t *mcp = &mc; | 2553 | mbx_cmd_t *mcp = &mc; |
2554 | 2554 | ||
2555 | if (!IS_QLA24XX(ha)) | 2555 | if (!IS_IIDMA_CAPABLE(ha)) |
2556 | return QLA_FUNCTION_FAILED; | 2556 | return QLA_FUNCTION_FAILED; |
2557 | 2557 | ||
2558 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); | 2558 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
@@ -2595,7 +2595,7 @@ qla2x00_set_idma_speed(scsi_qla_host_t *ha, uint16_t loop_id, | |||
2595 | mbx_cmd_t mc; | 2595 | mbx_cmd_t mc; |
2596 | mbx_cmd_t *mcp = &mc; | 2596 | mbx_cmd_t *mcp = &mc; |
2597 | 2597 | ||
2598 | if (!IS_QLA24XX(ha)) | 2598 | if (!IS_IIDMA_CAPABLE(ha)) |
2599 | return QLA_FUNCTION_FAILED; | 2599 | return QLA_FUNCTION_FAILED; |
2600 | 2600 | ||
2601 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); | 2601 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 92376f9dfdd5..c488996cb958 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -265,6 +265,8 @@ qla24xx_pci_info_str(struct scsi_qla_host *ha, char *str) | |||
265 | strcpy(str, "PCIe ("); | 265 | strcpy(str, "PCIe ("); |
266 | if (lspeed == 1) | 266 | if (lspeed == 1) |
267 | strcat(str, "2.5Gb/s "); | 267 | strcat(str, "2.5Gb/s "); |
268 | else if (lspeed == 2) | ||
269 | strcat(str, "5.0Gb/s "); | ||
268 | else | 270 | else |
269 | strcat(str, "<unknown> "); | 271 | strcat(str, "<unknown> "); |
270 | snprintf(lwstr, sizeof(lwstr), "x%d)", lwidth); | 272 | snprintf(lwstr, sizeof(lwstr), "x%d)", lwidth); |
@@ -343,6 +345,12 @@ qla24xx_fw_version_str(struct scsi_qla_host *ha, char *str) | |||
343 | strcat(str, "[IP] "); | 345 | strcat(str, "[IP] "); |
344 | if (ha->fw_attributes & BIT_2) | 346 | if (ha->fw_attributes & BIT_2) |
345 | strcat(str, "[Multi-ID] "); | 347 | strcat(str, "[Multi-ID] "); |
348 | if (ha->fw_attributes & BIT_3) | ||
349 | strcat(str, "[SB-2] "); | ||
350 | if (ha->fw_attributes & BIT_4) | ||
351 | strcat(str, "[T10 CRC] "); | ||
352 | if (ha->fw_attributes & BIT_5) | ||
353 | strcat(str, "[VI] "); | ||
346 | if (ha->fw_attributes & BIT_13) | 354 | if (ha->fw_attributes & BIT_13) |
347 | strcat(str, "[Experimental]"); | 355 | strcat(str, "[Experimental]"); |
348 | return str; | 356 | return str; |
@@ -681,7 +689,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
681 | DEBUG3(qla2x00_print_scsi_cmd(cmd)); | 689 | DEBUG3(qla2x00_print_scsi_cmd(cmd)); |
682 | 690 | ||
683 | spin_unlock_irqrestore(&pha->hardware_lock, flags); | 691 | spin_unlock_irqrestore(&pha->hardware_lock, flags); |
684 | if (ha->isp_ops.abort_command(ha, sp)) { | 692 | if (ha->isp_ops->abort_command(ha, sp)) { |
685 | DEBUG2(printk("%s(%ld): abort_command " | 693 | DEBUG2(printk("%s(%ld): abort_command " |
686 | "mbx failed.\n", __func__, ha->host_no)); | 694 | "mbx failed.\n", __func__, ha->host_no)); |
687 | } else { | 695 | } else { |
@@ -813,7 +821,7 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) | |||
813 | #if defined(LOGOUT_AFTER_DEVICE_RESET) | 821 | #if defined(LOGOUT_AFTER_DEVICE_RESET) |
814 | if (ret == SUCCESS) { | 822 | if (ret == SUCCESS) { |
815 | if (fcport->flags & FC_FABRIC_DEVICE) { | 823 | if (fcport->flags & FC_FABRIC_DEVICE) { |
816 | ha->isp_ops.fabric_logout(ha, fcport->loop_id); | 824 | ha->isp_ops->fabric_logout(ha, fcport->loop_id); |
817 | qla2x00_mark_device_lost(ha, fcport, 0, 0); | 825 | qla2x00_mark_device_lost(ha, fcport, 0, 0); |
818 | } | 826 | } |
819 | } | 827 | } |
@@ -1105,7 +1113,7 @@ static int | |||
1105 | qla2x00_device_reset(scsi_qla_host_t *ha, fc_port_t *reset_fcport) | 1113 | qla2x00_device_reset(scsi_qla_host_t *ha, fc_port_t *reset_fcport) |
1106 | { | 1114 | { |
1107 | /* Abort Target command will clear Reservation */ | 1115 | /* Abort Target command will clear Reservation */ |
1108 | return ha->isp_ops.abort_target(reset_fcport); | 1116 | return ha->isp_ops->abort_target(reset_fcport); |
1109 | } | 1117 | } |
1110 | 1118 | ||
1111 | static int | 1119 | static int |
@@ -1184,8 +1192,8 @@ qla2x00_config_dma_addressing(scsi_qla_host_t *ha) | |||
1184 | !pci_set_consistent_dma_mask(ha->pdev, DMA_64BIT_MASK)) { | 1192 | !pci_set_consistent_dma_mask(ha->pdev, DMA_64BIT_MASK)) { |
1185 | /* Ok, a 64bit DMA mask is applicable. */ | 1193 | /* Ok, a 64bit DMA mask is applicable. */ |
1186 | ha->flags.enable_64bit_addressing = 1; | 1194 | ha->flags.enable_64bit_addressing = 1; |
1187 | ha->isp_ops.calc_req_entries = qla2x00_calc_iocbs_64; | 1195 | ha->isp_ops->calc_req_entries = qla2x00_calc_iocbs_64; |
1188 | ha->isp_ops.build_iocbs = qla2x00_build_scsi_iocbs_64; | 1196 | ha->isp_ops->build_iocbs = qla2x00_build_scsi_iocbs_64; |
1189 | return; | 1197 | return; |
1190 | } | 1198 | } |
1191 | } | 1199 | } |
@@ -1194,6 +1202,193 @@ qla2x00_config_dma_addressing(scsi_qla_host_t *ha) | |||
1194 | pci_set_consistent_dma_mask(ha->pdev, DMA_32BIT_MASK); | 1202 | pci_set_consistent_dma_mask(ha->pdev, DMA_32BIT_MASK); |
1195 | } | 1203 | } |
1196 | 1204 | ||
1205 | static void | ||
1206 | qla2x00_enable_intrs(scsi_qla_host_t *ha) | ||
1207 | { | ||
1208 | unsigned long flags = 0; | ||
1209 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | ||
1210 | |||
1211 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
1212 | ha->interrupts_on = 1; | ||
1213 | /* enable risc and host interrupts */ | ||
1214 | WRT_REG_WORD(®->ictrl, ICR_EN_INT | ICR_EN_RISC); | ||
1215 | RD_REG_WORD(®->ictrl); | ||
1216 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
1217 | |||
1218 | } | ||
1219 | |||
1220 | static void | ||
1221 | qla2x00_disable_intrs(scsi_qla_host_t *ha) | ||
1222 | { | ||
1223 | unsigned long flags = 0; | ||
1224 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | ||
1225 | |||
1226 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
1227 | ha->interrupts_on = 0; | ||
1228 | /* disable risc and host interrupts */ | ||
1229 | WRT_REG_WORD(®->ictrl, 0); | ||
1230 | RD_REG_WORD(®->ictrl); | ||
1231 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
1232 | } | ||
1233 | |||
1234 | static void | ||
1235 | qla24xx_enable_intrs(scsi_qla_host_t *ha) | ||
1236 | { | ||
1237 | unsigned long flags = 0; | ||
1238 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | ||
1239 | |||
1240 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
1241 | ha->interrupts_on = 1; | ||
1242 | WRT_REG_DWORD(®->ictrl, ICRX_EN_RISC_INT); | ||
1243 | RD_REG_DWORD(®->ictrl); | ||
1244 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
1245 | } | ||
1246 | |||
1247 | static void | ||
1248 | qla24xx_disable_intrs(scsi_qla_host_t *ha) | ||
1249 | { | ||
1250 | unsigned long flags = 0; | ||
1251 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | ||
1252 | |||
1253 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
1254 | ha->interrupts_on = 0; | ||
1255 | WRT_REG_DWORD(®->ictrl, 0); | ||
1256 | RD_REG_DWORD(®->ictrl); | ||
1257 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
1258 | } | ||
1259 | |||
1260 | static struct isp_operations qla2100_isp_ops = { | ||
1261 | .pci_config = qla2100_pci_config, | ||
1262 | .reset_chip = qla2x00_reset_chip, | ||
1263 | .chip_diag = qla2x00_chip_diag, | ||
1264 | .config_rings = qla2x00_config_rings, | ||
1265 | .reset_adapter = qla2x00_reset_adapter, | ||
1266 | .nvram_config = qla2x00_nvram_config, | ||
1267 | .update_fw_options = qla2x00_update_fw_options, | ||
1268 | .load_risc = qla2x00_load_risc, | ||
1269 | .pci_info_str = qla2x00_pci_info_str, | ||
1270 | .fw_version_str = qla2x00_fw_version_str, | ||
1271 | .intr_handler = qla2100_intr_handler, | ||
1272 | .enable_intrs = qla2x00_enable_intrs, | ||
1273 | .disable_intrs = qla2x00_disable_intrs, | ||
1274 | .abort_command = qla2x00_abort_command, | ||
1275 | .abort_target = qla2x00_abort_target, | ||
1276 | .fabric_login = qla2x00_login_fabric, | ||
1277 | .fabric_logout = qla2x00_fabric_logout, | ||
1278 | .calc_req_entries = qla2x00_calc_iocbs_32, | ||
1279 | .build_iocbs = qla2x00_build_scsi_iocbs_32, | ||
1280 | .prep_ms_iocb = qla2x00_prep_ms_iocb, | ||
1281 | .prep_ms_fdmi_iocb = qla2x00_prep_ms_fdmi_iocb, | ||
1282 | .read_nvram = qla2x00_read_nvram_data, | ||
1283 | .write_nvram = qla2x00_write_nvram_data, | ||
1284 | .fw_dump = qla2100_fw_dump, | ||
1285 | .beacon_on = NULL, | ||
1286 | .beacon_off = NULL, | ||
1287 | .beacon_blink = NULL, | ||
1288 | .read_optrom = qla2x00_read_optrom_data, | ||
1289 | .write_optrom = qla2x00_write_optrom_data, | ||
1290 | .get_flash_version = qla2x00_get_flash_version, | ||
1291 | }; | ||
1292 | |||
1293 | static struct isp_operations qla2300_isp_ops = { | ||
1294 | .pci_config = qla2300_pci_config, | ||
1295 | .reset_chip = qla2x00_reset_chip, | ||
1296 | .chip_diag = qla2x00_chip_diag, | ||
1297 | .config_rings = qla2x00_config_rings, | ||
1298 | .reset_adapter = qla2x00_reset_adapter, | ||
1299 | .nvram_config = qla2x00_nvram_config, | ||
1300 | .update_fw_options = qla2x00_update_fw_options, | ||
1301 | .load_risc = qla2x00_load_risc, | ||
1302 | .pci_info_str = qla2x00_pci_info_str, | ||
1303 | .fw_version_str = qla2x00_fw_version_str, | ||
1304 | .intr_handler = qla2300_intr_handler, | ||
1305 | .enable_intrs = qla2x00_enable_intrs, | ||
1306 | .disable_intrs = qla2x00_disable_intrs, | ||
1307 | .abort_command = qla2x00_abort_command, | ||
1308 | .abort_target = qla2x00_abort_target, | ||
1309 | .fabric_login = qla2x00_login_fabric, | ||
1310 | .fabric_logout = qla2x00_fabric_logout, | ||
1311 | .calc_req_entries = qla2x00_calc_iocbs_32, | ||
1312 | .build_iocbs = qla2x00_build_scsi_iocbs_32, | ||
1313 | .prep_ms_iocb = qla2x00_prep_ms_iocb, | ||
1314 | .prep_ms_fdmi_iocb = qla2x00_prep_ms_fdmi_iocb, | ||
1315 | .read_nvram = qla2x00_read_nvram_data, | ||
1316 | .write_nvram = qla2x00_write_nvram_data, | ||
1317 | .fw_dump = qla2300_fw_dump, | ||
1318 | .beacon_on = qla2x00_beacon_on, | ||
1319 | .beacon_off = qla2x00_beacon_off, | ||
1320 | .beacon_blink = qla2x00_beacon_blink, | ||
1321 | .read_optrom = qla2x00_read_optrom_data, | ||
1322 | .write_optrom = qla2x00_write_optrom_data, | ||
1323 | .get_flash_version = qla2x00_get_flash_version, | ||
1324 | }; | ||
1325 | |||
1326 | static struct isp_operations qla24xx_isp_ops = { | ||
1327 | .pci_config = qla24xx_pci_config, | ||
1328 | .reset_chip = qla24xx_reset_chip, | ||
1329 | .chip_diag = qla24xx_chip_diag, | ||
1330 | .config_rings = qla24xx_config_rings, | ||
1331 | .reset_adapter = qla24xx_reset_adapter, | ||
1332 | .nvram_config = qla24xx_nvram_config, | ||
1333 | .update_fw_options = qla24xx_update_fw_options, | ||
1334 | .load_risc = qla24xx_load_risc, | ||
1335 | .pci_info_str = qla24xx_pci_info_str, | ||
1336 | .fw_version_str = qla24xx_fw_version_str, | ||
1337 | .intr_handler = qla24xx_intr_handler, | ||
1338 | .enable_intrs = qla24xx_enable_intrs, | ||
1339 | .disable_intrs = qla24xx_disable_intrs, | ||
1340 | .abort_command = qla24xx_abort_command, | ||
1341 | .abort_target = qla24xx_abort_target, | ||
1342 | .fabric_login = qla24xx_login_fabric, | ||
1343 | .fabric_logout = qla24xx_fabric_logout, | ||
1344 | .calc_req_entries = NULL, | ||
1345 | .build_iocbs = NULL, | ||
1346 | .prep_ms_iocb = qla24xx_prep_ms_iocb, | ||
1347 | .prep_ms_fdmi_iocb = qla24xx_prep_ms_fdmi_iocb, | ||
1348 | .read_nvram = qla24xx_read_nvram_data, | ||
1349 | .write_nvram = qla24xx_write_nvram_data, | ||
1350 | .fw_dump = qla24xx_fw_dump, | ||
1351 | .beacon_on = qla24xx_beacon_on, | ||
1352 | .beacon_off = qla24xx_beacon_off, | ||
1353 | .beacon_blink = qla24xx_beacon_blink, | ||
1354 | .read_optrom = qla24xx_read_optrom_data, | ||
1355 | .write_optrom = qla24xx_write_optrom_data, | ||
1356 | .get_flash_version = qla24xx_get_flash_version, | ||
1357 | }; | ||
1358 | |||
1359 | static struct isp_operations qla25xx_isp_ops = { | ||
1360 | .pci_config = qla25xx_pci_config, | ||
1361 | .reset_chip = qla24xx_reset_chip, | ||
1362 | .chip_diag = qla24xx_chip_diag, | ||
1363 | .config_rings = qla24xx_config_rings, | ||
1364 | .reset_adapter = qla24xx_reset_adapter, | ||
1365 | .nvram_config = qla24xx_nvram_config, | ||
1366 | .update_fw_options = qla24xx_update_fw_options, | ||
1367 | .load_risc = qla24xx_load_risc, | ||
1368 | .pci_info_str = qla24xx_pci_info_str, | ||
1369 | .fw_version_str = qla24xx_fw_version_str, | ||
1370 | .intr_handler = qla24xx_intr_handler, | ||
1371 | .enable_intrs = qla24xx_enable_intrs, | ||
1372 | .disable_intrs = qla24xx_disable_intrs, | ||
1373 | .abort_command = qla24xx_abort_command, | ||
1374 | .abort_target = qla24xx_abort_target, | ||
1375 | .fabric_login = qla24xx_login_fabric, | ||
1376 | .fabric_logout = qla24xx_fabric_logout, | ||
1377 | .calc_req_entries = NULL, | ||
1378 | .build_iocbs = NULL, | ||
1379 | .prep_ms_iocb = qla24xx_prep_ms_iocb, | ||
1380 | .prep_ms_fdmi_iocb = qla24xx_prep_ms_fdmi_iocb, | ||
1381 | .read_nvram = qla25xx_read_nvram_data, | ||
1382 | .write_nvram = qla25xx_write_nvram_data, | ||
1383 | .fw_dump = qla25xx_fw_dump, | ||
1384 | .beacon_on = qla24xx_beacon_on, | ||
1385 | .beacon_off = qla24xx_beacon_off, | ||
1386 | .beacon_blink = qla24xx_beacon_blink, | ||
1387 | .read_optrom = qla24xx_read_optrom_data, | ||
1388 | .write_optrom = qla24xx_write_optrom_data, | ||
1389 | .get_flash_version = qla24xx_get_flash_version, | ||
1390 | }; | ||
1391 | |||
1197 | static inline void | 1392 | static inline void |
1198 | qla2x00_set_isp_flags(scsi_qla_host_t *ha) | 1393 | qla2x00_set_isp_flags(scsi_qla_host_t *ha) |
1199 | { | 1394 | { |
@@ -1238,19 +1433,32 @@ qla2x00_set_isp_flags(scsi_qla_host_t *ha) | |||
1238 | case PCI_DEVICE_ID_QLOGIC_ISP2422: | 1433 | case PCI_DEVICE_ID_QLOGIC_ISP2422: |
1239 | ha->device_type |= DT_ISP2422; | 1434 | ha->device_type |= DT_ISP2422; |
1240 | ha->device_type |= DT_ZIO_SUPPORTED; | 1435 | ha->device_type |= DT_ZIO_SUPPORTED; |
1436 | ha->device_type |= DT_FWI2; | ||
1437 | ha->device_type |= DT_IIDMA; | ||
1241 | ha->fw_srisc_address = RISC_START_ADDRESS_2400; | 1438 | ha->fw_srisc_address = RISC_START_ADDRESS_2400; |
1242 | break; | 1439 | break; |
1243 | case PCI_DEVICE_ID_QLOGIC_ISP2432: | 1440 | case PCI_DEVICE_ID_QLOGIC_ISP2432: |
1244 | ha->device_type |= DT_ISP2432; | 1441 | ha->device_type |= DT_ISP2432; |
1245 | ha->device_type |= DT_ZIO_SUPPORTED; | 1442 | ha->device_type |= DT_ZIO_SUPPORTED; |
1443 | ha->device_type |= DT_FWI2; | ||
1444 | ha->device_type |= DT_IIDMA; | ||
1246 | ha->fw_srisc_address = RISC_START_ADDRESS_2400; | 1445 | ha->fw_srisc_address = RISC_START_ADDRESS_2400; |
1247 | break; | 1446 | break; |
1248 | case PCI_DEVICE_ID_QLOGIC_ISP5422: | 1447 | case PCI_DEVICE_ID_QLOGIC_ISP5422: |
1249 | ha->device_type |= DT_ISP5422; | 1448 | ha->device_type |= DT_ISP5422; |
1449 | ha->device_type |= DT_FWI2; | ||
1250 | ha->fw_srisc_address = RISC_START_ADDRESS_2400; | 1450 | ha->fw_srisc_address = RISC_START_ADDRESS_2400; |
1251 | break; | 1451 | break; |
1252 | case PCI_DEVICE_ID_QLOGIC_ISP5432: | 1452 | case PCI_DEVICE_ID_QLOGIC_ISP5432: |
1253 | ha->device_type |= DT_ISP5432; | 1453 | ha->device_type |= DT_ISP5432; |
1454 | ha->device_type |= DT_FWI2; | ||
1455 | ha->fw_srisc_address = RISC_START_ADDRESS_2400; | ||
1456 | break; | ||
1457 | case PCI_DEVICE_ID_QLOGIC_ISP2532: | ||
1458 | ha->device_type |= DT_ISP2532; | ||
1459 | ha->device_type |= DT_ZIO_SUPPORTED; | ||
1460 | ha->device_type |= DT_FWI2; | ||
1461 | ha->device_type |= DT_IIDMA; | ||
1254 | ha->fw_srisc_address = RISC_START_ADDRESS_2400; | 1462 | ha->fw_srisc_address = RISC_START_ADDRESS_2400; |
1255 | break; | 1463 | break; |
1256 | } | 1464 | } |
@@ -1323,61 +1531,6 @@ iospace_error_exit: | |||
1323 | } | 1531 | } |
1324 | 1532 | ||
1325 | static void | 1533 | static void |
1326 | qla2x00_enable_intrs(scsi_qla_host_t *ha) | ||
1327 | { | ||
1328 | unsigned long flags = 0; | ||
1329 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | ||
1330 | |||
1331 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
1332 | ha->interrupts_on = 1; | ||
1333 | /* enable risc and host interrupts */ | ||
1334 | WRT_REG_WORD(®->ictrl, ICR_EN_INT | ICR_EN_RISC); | ||
1335 | RD_REG_WORD(®->ictrl); | ||
1336 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
1337 | |||
1338 | } | ||
1339 | |||
1340 | static void | ||
1341 | qla2x00_disable_intrs(scsi_qla_host_t *ha) | ||
1342 | { | ||
1343 | unsigned long flags = 0; | ||
1344 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | ||
1345 | |||
1346 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
1347 | ha->interrupts_on = 0; | ||
1348 | /* disable risc and host interrupts */ | ||
1349 | WRT_REG_WORD(®->ictrl, 0); | ||
1350 | RD_REG_WORD(®->ictrl); | ||
1351 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
1352 | } | ||
1353 | |||
1354 | static void | ||
1355 | qla24xx_enable_intrs(scsi_qla_host_t *ha) | ||
1356 | { | ||
1357 | unsigned long flags = 0; | ||
1358 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | ||
1359 | |||
1360 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
1361 | ha->interrupts_on = 1; | ||
1362 | WRT_REG_DWORD(®->ictrl, ICRX_EN_RISC_INT); | ||
1363 | RD_REG_DWORD(®->ictrl); | ||
1364 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
1365 | } | ||
1366 | |||
1367 | static void | ||
1368 | qla24xx_disable_intrs(scsi_qla_host_t *ha) | ||
1369 | { | ||
1370 | unsigned long flags = 0; | ||
1371 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | ||
1372 | |||
1373 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
1374 | ha->interrupts_on = 0; | ||
1375 | WRT_REG_DWORD(®->ictrl, 0); | ||
1376 | RD_REG_DWORD(®->ictrl); | ||
1377 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
1378 | } | ||
1379 | |||
1380 | static void | ||
1381 | qla2xxx_scan_start(struct Scsi_Host *shost) | 1534 | qla2xxx_scan_start(struct Scsi_Host *shost) |
1382 | { | 1535 | { |
1383 | scsi_qla_host_t *ha = (scsi_qla_host_t *)shost->hostdata; | 1536 | scsi_qla_host_t *ha = (scsi_qla_host_t *)shost->hostdata; |
@@ -1422,7 +1575,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1422 | if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 || | 1575 | if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 || |
1423 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 || | 1576 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 || |
1424 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5422 || | 1577 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5422 || |
1425 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5432) | 1578 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5432 || |
1579 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532) | ||
1426 | sht = &qla24xx_driver_template; | 1580 | sht = &qla24xx_driver_template; |
1427 | host = scsi_host_alloc(sht, sizeof(scsi_qla_host_t)); | 1581 | host = scsi_host_alloc(sht, sizeof(scsi_qla_host_t)); |
1428 | if (host == NULL) { | 1582 | if (host == NULL) { |
@@ -1466,33 +1620,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1466 | ha->max_q_depth = ql2xmaxqdepth; | 1620 | ha->max_q_depth = ql2xmaxqdepth; |
1467 | 1621 | ||
1468 | /* Assign ISP specific operations. */ | 1622 | /* Assign ISP specific operations. */ |
1469 | ha->isp_ops.pci_config = qla2100_pci_config; | ||
1470 | ha->isp_ops.reset_chip = qla2x00_reset_chip; | ||
1471 | ha->isp_ops.chip_diag = qla2x00_chip_diag; | ||
1472 | ha->isp_ops.config_rings = qla2x00_config_rings; | ||
1473 | ha->isp_ops.reset_adapter = qla2x00_reset_adapter; | ||
1474 | ha->isp_ops.nvram_config = qla2x00_nvram_config; | ||
1475 | ha->isp_ops.update_fw_options = qla2x00_update_fw_options; | ||
1476 | ha->isp_ops.load_risc = qla2x00_load_risc; | ||
1477 | ha->isp_ops.pci_info_str = qla2x00_pci_info_str; | ||
1478 | ha->isp_ops.fw_version_str = qla2x00_fw_version_str; | ||
1479 | ha->isp_ops.intr_handler = qla2100_intr_handler; | ||
1480 | ha->isp_ops.enable_intrs = qla2x00_enable_intrs; | ||
1481 | ha->isp_ops.disable_intrs = qla2x00_disable_intrs; | ||
1482 | ha->isp_ops.abort_command = qla2x00_abort_command; | ||
1483 | ha->isp_ops.abort_target = qla2x00_abort_target; | ||
1484 | ha->isp_ops.fabric_login = qla2x00_login_fabric; | ||
1485 | ha->isp_ops.fabric_logout = qla2x00_fabric_logout; | ||
1486 | ha->isp_ops.calc_req_entries = qla2x00_calc_iocbs_32; | ||
1487 | ha->isp_ops.build_iocbs = qla2x00_build_scsi_iocbs_32; | ||
1488 | ha->isp_ops.prep_ms_iocb = qla2x00_prep_ms_iocb; | ||
1489 | ha->isp_ops.prep_ms_fdmi_iocb = qla2x00_prep_ms_fdmi_iocb; | ||
1490 | ha->isp_ops.read_nvram = qla2x00_read_nvram_data; | ||
1491 | ha->isp_ops.write_nvram = qla2x00_write_nvram_data; | ||
1492 | ha->isp_ops.fw_dump = qla2100_fw_dump; | ||
1493 | ha->isp_ops.read_optrom = qla2x00_read_optrom_data; | ||
1494 | ha->isp_ops.write_optrom = qla2x00_write_optrom_data; | ||
1495 | ha->isp_ops.get_flash_version = qla2x00_get_flash_version; | ||
1496 | if (IS_QLA2100(ha)) { | 1623 | if (IS_QLA2100(ha)) { |
1497 | host->max_id = MAX_TARGETS_2100; | 1624 | host->max_id = MAX_TARGETS_2100; |
1498 | ha->mbx_count = MAILBOX_REGISTER_COUNT_2100; | 1625 | ha->mbx_count = MAILBOX_REGISTER_COUNT_2100; |
@@ -1501,6 +1628,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1501 | ha->last_loop_id = SNS_LAST_LOOP_ID_2100; | 1628 | ha->last_loop_id = SNS_LAST_LOOP_ID_2100; |
1502 | host->sg_tablesize = 32; | 1629 | host->sg_tablesize = 32; |
1503 | ha->gid_list_info_size = 4; | 1630 | ha->gid_list_info_size = 4; |
1631 | ha->isp_ops = &qla2100_isp_ops; | ||
1504 | } else if (IS_QLA2200(ha)) { | 1632 | } else if (IS_QLA2200(ha)) { |
1505 | host->max_id = MAX_TARGETS_2200; | 1633 | host->max_id = MAX_TARGETS_2200; |
1506 | ha->mbx_count = MAILBOX_REGISTER_COUNT; | 1634 | ha->mbx_count = MAILBOX_REGISTER_COUNT; |
@@ -1508,21 +1636,17 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1508 | ha->response_q_length = RESPONSE_ENTRY_CNT_2100; | 1636 | ha->response_q_length = RESPONSE_ENTRY_CNT_2100; |
1509 | ha->last_loop_id = SNS_LAST_LOOP_ID_2100; | 1637 | ha->last_loop_id = SNS_LAST_LOOP_ID_2100; |
1510 | ha->gid_list_info_size = 4; | 1638 | ha->gid_list_info_size = 4; |
1639 | ha->isp_ops = &qla2100_isp_ops; | ||
1511 | } else if (IS_QLA23XX(ha)) { | 1640 | } else if (IS_QLA23XX(ha)) { |
1512 | host->max_id = MAX_TARGETS_2200; | 1641 | host->max_id = MAX_TARGETS_2200; |
1513 | ha->mbx_count = MAILBOX_REGISTER_COUNT; | 1642 | ha->mbx_count = MAILBOX_REGISTER_COUNT; |
1514 | ha->request_q_length = REQUEST_ENTRY_CNT_2200; | 1643 | ha->request_q_length = REQUEST_ENTRY_CNT_2200; |
1515 | ha->response_q_length = RESPONSE_ENTRY_CNT_2300; | 1644 | ha->response_q_length = RESPONSE_ENTRY_CNT_2300; |
1516 | ha->last_loop_id = SNS_LAST_LOOP_ID_2300; | 1645 | ha->last_loop_id = SNS_LAST_LOOP_ID_2300; |
1517 | ha->isp_ops.pci_config = qla2300_pci_config; | ||
1518 | ha->isp_ops.intr_handler = qla2300_intr_handler; | ||
1519 | ha->isp_ops.fw_dump = qla2300_fw_dump; | ||
1520 | ha->isp_ops.beacon_on = qla2x00_beacon_on; | ||
1521 | ha->isp_ops.beacon_off = qla2x00_beacon_off; | ||
1522 | ha->isp_ops.beacon_blink = qla2x00_beacon_blink; | ||
1523 | ha->gid_list_info_size = 6; | 1646 | ha->gid_list_info_size = 6; |
1524 | if (IS_QLA2322(ha) || IS_QLA6322(ha)) | 1647 | if (IS_QLA2322(ha) || IS_QLA6322(ha)) |
1525 | ha->optrom_size = OPTROM_SIZE_2322; | 1648 | ha->optrom_size = OPTROM_SIZE_2322; |
1649 | ha->isp_ops = &qla2300_isp_ops; | ||
1526 | } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 1650 | } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { |
1527 | host->max_id = MAX_TARGETS_2200; | 1651 | host->max_id = MAX_TARGETS_2200; |
1528 | ha->mbx_count = MAILBOX_REGISTER_COUNT; | 1652 | ha->mbx_count = MAILBOX_REGISTER_COUNT; |
@@ -1531,36 +1655,20 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1531 | ha->last_loop_id = SNS_LAST_LOOP_ID_2300; | 1655 | ha->last_loop_id = SNS_LAST_LOOP_ID_2300; |
1532 | ha->init_cb_size = sizeof(struct mid_init_cb_24xx); | 1656 | ha->init_cb_size = sizeof(struct mid_init_cb_24xx); |
1533 | ha->mgmt_svr_loop_id = 10 + ha->vp_idx; | 1657 | ha->mgmt_svr_loop_id = 10 + ha->vp_idx; |
1534 | ha->isp_ops.pci_config = qla24xx_pci_config; | ||
1535 | ha->isp_ops.reset_chip = qla24xx_reset_chip; | ||
1536 | ha->isp_ops.chip_diag = qla24xx_chip_diag; | ||
1537 | ha->isp_ops.config_rings = qla24xx_config_rings; | ||
1538 | ha->isp_ops.reset_adapter = qla24xx_reset_adapter; | ||
1539 | ha->isp_ops.nvram_config = qla24xx_nvram_config; | ||
1540 | ha->isp_ops.update_fw_options = qla24xx_update_fw_options; | ||
1541 | ha->isp_ops.load_risc = qla24xx_load_risc; | ||
1542 | ha->isp_ops.pci_info_str = qla24xx_pci_info_str; | ||
1543 | ha->isp_ops.fw_version_str = qla24xx_fw_version_str; | ||
1544 | ha->isp_ops.intr_handler = qla24xx_intr_handler; | ||
1545 | ha->isp_ops.enable_intrs = qla24xx_enable_intrs; | ||
1546 | ha->isp_ops.disable_intrs = qla24xx_disable_intrs; | ||
1547 | ha->isp_ops.abort_command = qla24xx_abort_command; | ||
1548 | ha->isp_ops.abort_target = qla24xx_abort_target; | ||
1549 | ha->isp_ops.fabric_login = qla24xx_login_fabric; | ||
1550 | ha->isp_ops.fabric_logout = qla24xx_fabric_logout; | ||
1551 | ha->isp_ops.prep_ms_iocb = qla24xx_prep_ms_iocb; | ||
1552 | ha->isp_ops.prep_ms_fdmi_iocb = qla24xx_prep_ms_fdmi_iocb; | ||
1553 | ha->isp_ops.read_nvram = qla24xx_read_nvram_data; | ||
1554 | ha->isp_ops.write_nvram = qla24xx_write_nvram_data; | ||
1555 | ha->isp_ops.fw_dump = qla24xx_fw_dump; | ||
1556 | ha->isp_ops.read_optrom = qla24xx_read_optrom_data; | ||
1557 | ha->isp_ops.write_optrom = qla24xx_write_optrom_data; | ||
1558 | ha->isp_ops.beacon_on = qla24xx_beacon_on; | ||
1559 | ha->isp_ops.beacon_off = qla24xx_beacon_off; | ||
1560 | ha->isp_ops.beacon_blink = qla24xx_beacon_blink; | ||
1561 | ha->isp_ops.get_flash_version = qla24xx_get_flash_version; | ||
1562 | ha->gid_list_info_size = 8; | 1658 | ha->gid_list_info_size = 8; |
1563 | ha->optrom_size = OPTROM_SIZE_24XX; | 1659 | ha->optrom_size = OPTROM_SIZE_24XX; |
1660 | ha->isp_ops = &qla24xx_isp_ops; | ||
1661 | } else if (IS_QLA25XX(ha)) { | ||
1662 | host->max_id = MAX_TARGETS_2200; | ||
1663 | ha->mbx_count = MAILBOX_REGISTER_COUNT; | ||
1664 | ha->request_q_length = REQUEST_ENTRY_CNT_24XX; | ||
1665 | ha->response_q_length = RESPONSE_ENTRY_CNT_2300; | ||
1666 | ha->last_loop_id = SNS_LAST_LOOP_ID_2300; | ||
1667 | ha->init_cb_size = sizeof(struct mid_init_cb_24xx); | ||
1668 | ha->mgmt_svr_loop_id = 10 + ha->vp_idx; | ||
1669 | ha->gid_list_info_size = 8; | ||
1670 | ha->optrom_size = OPTROM_SIZE_25XX; | ||
1671 | ha->isp_ops = &qla25xx_isp_ops; | ||
1564 | } | 1672 | } |
1565 | host->can_queue = ha->request_q_length + 128; | 1673 | host->can_queue = ha->request_q_length + 128; |
1566 | 1674 | ||
@@ -1628,11 +1736,11 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1628 | DEBUG2(printk("DEBUG: detect hba %ld at address = %p\n", | 1736 | DEBUG2(printk("DEBUG: detect hba %ld at address = %p\n", |
1629 | ha->host_no, ha)); | 1737 | ha->host_no, ha)); |
1630 | 1738 | ||
1631 | ha->isp_ops.disable_intrs(ha); | 1739 | ha->isp_ops->disable_intrs(ha); |
1632 | 1740 | ||
1633 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1741 | spin_lock_irqsave(&ha->hardware_lock, flags); |
1634 | reg = ha->iobase; | 1742 | reg = ha->iobase; |
1635 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 1743 | if (IS_FWI2_CAPABLE(ha)) { |
1636 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_HOST_INT); | 1744 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_HOST_INT); |
1637 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_RISC_INT); | 1745 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_RISC_INT); |
1638 | } else { | 1746 | } else { |
@@ -1654,7 +1762,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1654 | } | 1762 | } |
1655 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1763 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
1656 | 1764 | ||
1657 | ha->isp_ops.enable_intrs(ha); | 1765 | ha->isp_ops->enable_intrs(ha); |
1658 | 1766 | ||
1659 | pci_set_drvdata(pdev, ha); | 1767 | pci_set_drvdata(pdev, ha); |
1660 | 1768 | ||
@@ -1679,9 +1787,9 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1679 | " ISP%04X: %s @ %s hdma%c, host#=%ld, fw=%s\n", | 1787 | " ISP%04X: %s @ %s hdma%c, host#=%ld, fw=%s\n", |
1680 | qla2x00_version_str, ha->model_number, | 1788 | qla2x00_version_str, ha->model_number, |
1681 | ha->model_desc ? ha->model_desc: "", pdev->device, | 1789 | ha->model_desc ? ha->model_desc: "", pdev->device, |
1682 | ha->isp_ops.pci_info_str(ha, pci_info), pci_name(pdev), | 1790 | ha->isp_ops->pci_info_str(ha, pci_info), pci_name(pdev), |
1683 | ha->flags.enable_64bit_addressing ? '+': '-', ha->host_no, | 1791 | ha->flags.enable_64bit_addressing ? '+': '-', ha->host_no, |
1684 | ha->isp_ops.fw_version_str(ha, fw_str)); | 1792 | ha->isp_ops->fw_version_str(ha, fw_str)); |
1685 | 1793 | ||
1686 | return 0; | 1794 | return 0; |
1687 | 1795 | ||
@@ -1747,7 +1855,7 @@ qla2x00_free_device(scsi_qla_host_t *ha) | |||
1747 | 1855 | ||
1748 | /* turn-off interrupts on the card */ | 1856 | /* turn-off interrupts on the card */ |
1749 | if (ha->interrupts_on) | 1857 | if (ha->interrupts_on) |
1750 | ha->isp_ops.disable_intrs(ha); | 1858 | ha->isp_ops->disable_intrs(ha); |
1751 | 1859 | ||
1752 | qla2x00_mem_free(ha); | 1860 | qla2x00_mem_free(ha); |
1753 | 1861 | ||
@@ -2025,7 +2133,7 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha) | |||
2025 | } | 2133 | } |
2026 | memset(ha->ct_sns, 0, sizeof(struct ct_sns_pkt)); | 2134 | memset(ha->ct_sns, 0, sizeof(struct ct_sns_pkt)); |
2027 | 2135 | ||
2028 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 2136 | if (IS_FWI2_CAPABLE(ha)) { |
2029 | /* | 2137 | /* |
2030 | * Get consistent memory allocated for SFP | 2138 | * Get consistent memory allocated for SFP |
2031 | * block. | 2139 | * block. |
@@ -2305,7 +2413,7 @@ qla2x00_do_dpc(void *data) | |||
2305 | if (fcport->flags & FCF_FABRIC_DEVICE) { | 2413 | if (fcport->flags & FCF_FABRIC_DEVICE) { |
2306 | if (fcport->flags & | 2414 | if (fcport->flags & |
2307 | FCF_TAPE_PRESENT) | 2415 | FCF_TAPE_PRESENT) |
2308 | ha->isp_ops.fabric_logout( | 2416 | ha->isp_ops->fabric_logout( |
2309 | ha, fcport->loop_id, | 2417 | ha, fcport->loop_id, |
2310 | fcport->d_id.b.domain, | 2418 | fcport->d_id.b.domain, |
2311 | fcport->d_id.b.area, | 2419 | fcport->d_id.b.area, |
@@ -2385,10 +2493,10 @@ qla2x00_do_dpc(void *data) | |||
2385 | } | 2493 | } |
2386 | 2494 | ||
2387 | if (!ha->interrupts_on) | 2495 | if (!ha->interrupts_on) |
2388 | ha->isp_ops.enable_intrs(ha); | 2496 | ha->isp_ops->enable_intrs(ha); |
2389 | 2497 | ||
2390 | if (test_and_clear_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags)) | 2498 | if (test_and_clear_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags)) |
2391 | ha->isp_ops.beacon_blink(ha); | 2499 | ha->isp_ops->beacon_blink(ha); |
2392 | 2500 | ||
2393 | qla2x00_do_dpc_all_vps(ha); | 2501 | qla2x00_do_dpc_all_vps(ha); |
2394 | 2502 | ||
@@ -2617,18 +2725,20 @@ qla2x00_down_timeout(struct semaphore *sema, unsigned long timeout) | |||
2617 | 2725 | ||
2618 | /* Firmware interface routines. */ | 2726 | /* Firmware interface routines. */ |
2619 | 2727 | ||
2620 | #define FW_BLOBS 5 | 2728 | #define FW_BLOBS 6 |
2621 | #define FW_ISP21XX 0 | 2729 | #define FW_ISP21XX 0 |
2622 | #define FW_ISP22XX 1 | 2730 | #define FW_ISP22XX 1 |
2623 | #define FW_ISP2300 2 | 2731 | #define FW_ISP2300 2 |
2624 | #define FW_ISP2322 3 | 2732 | #define FW_ISP2322 3 |
2625 | #define FW_ISP24XX 4 | 2733 | #define FW_ISP24XX 4 |
2734 | #define FW_ISP25XX 5 | ||
2626 | 2735 | ||
2627 | #define FW_FILE_ISP21XX "ql2100_fw.bin" | 2736 | #define FW_FILE_ISP21XX "ql2100_fw.bin" |
2628 | #define FW_FILE_ISP22XX "ql2200_fw.bin" | 2737 | #define FW_FILE_ISP22XX "ql2200_fw.bin" |
2629 | #define FW_FILE_ISP2300 "ql2300_fw.bin" | 2738 | #define FW_FILE_ISP2300 "ql2300_fw.bin" |
2630 | #define FW_FILE_ISP2322 "ql2322_fw.bin" | 2739 | #define FW_FILE_ISP2322 "ql2322_fw.bin" |
2631 | #define FW_FILE_ISP24XX "ql2400_fw.bin" | 2740 | #define FW_FILE_ISP24XX "ql2400_fw.bin" |
2741 | #define FW_FILE_ISP25XX "ql2500_fw.bin" | ||
2632 | 2742 | ||
2633 | static DECLARE_MUTEX(qla_fw_lock); | 2743 | static DECLARE_MUTEX(qla_fw_lock); |
2634 | 2744 | ||
@@ -2638,6 +2748,7 @@ static struct fw_blob qla_fw_blobs[FW_BLOBS] = { | |||
2638 | { .name = FW_FILE_ISP2300, .segs = { 0x800, 0 }, }, | 2748 | { .name = FW_FILE_ISP2300, .segs = { 0x800, 0 }, }, |
2639 | { .name = FW_FILE_ISP2322, .segs = { 0x800, 0x1c000, 0x1e000, 0 }, }, | 2749 | { .name = FW_FILE_ISP2322, .segs = { 0x800, 0x1c000, 0x1e000, 0 }, }, |
2640 | { .name = FW_FILE_ISP24XX, }, | 2750 | { .name = FW_FILE_ISP24XX, }, |
2751 | { .name = FW_FILE_ISP25XX, }, | ||
2641 | }; | 2752 | }; |
2642 | 2753 | ||
2643 | struct fw_blob * | 2754 | struct fw_blob * |
@@ -2656,6 +2767,8 @@ qla2x00_request_firmware(scsi_qla_host_t *ha) | |||
2656 | blob = &qla_fw_blobs[FW_ISP2322]; | 2767 | blob = &qla_fw_blobs[FW_ISP2322]; |
2657 | } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 2768 | } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { |
2658 | blob = &qla_fw_blobs[FW_ISP24XX]; | 2769 | blob = &qla_fw_blobs[FW_ISP24XX]; |
2770 | } else if (IS_QLA25XX(ha)) { | ||
2771 | blob = &qla_fw_blobs[FW_ISP25XX]; | ||
2659 | } | 2772 | } |
2660 | 2773 | ||
2661 | down(&qla_fw_lock); | 2774 | down(&qla_fw_lock); |
@@ -2699,6 +2812,7 @@ static struct pci_device_id qla2xxx_pci_tbl[] = { | |||
2699 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432) }, | 2812 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432) }, |
2700 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5422) }, | 2813 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5422) }, |
2701 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5432) }, | 2814 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5432) }, |
2815 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2532) }, | ||
2702 | { 0 }, | 2816 | { 0 }, |
2703 | }; | 2817 | }; |
2704 | MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl); | 2818 | MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl); |
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index 206bda093da2..a925a3f179f9 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c | |||
@@ -766,6 +766,29 @@ qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr, | |||
766 | return ret; | 766 | return ret; |
767 | } | 767 | } |
768 | 768 | ||
769 | uint8_t * | ||
770 | qla25xx_read_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr, | ||
771 | uint32_t bytes) | ||
772 | { | ||
773 | uint32_t i; | ||
774 | uint32_t *dwptr; | ||
775 | |||
776 | /* Dword reads to flash. */ | ||
777 | dwptr = (uint32_t *)buf; | ||
778 | for (i = 0; i < bytes >> 2; i++, naddr++) | ||
779 | dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(ha, | ||
780 | flash_data_to_access_addr(FA_VPD_NVRAM_ADDR | naddr))); | ||
781 | |||
782 | return buf; | ||
783 | } | ||
784 | |||
785 | int | ||
786 | qla25xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr, | ||
787 | uint32_t bytes) | ||
788 | { | ||
789 | return qla24xx_write_flash_data(ha, (uint32_t *)buf, | ||
790 | FA_VPD_NVRAM_ADDR | naddr, bytes >> 2); | ||
791 | } | ||
769 | 792 | ||
770 | static inline void | 793 | static inline void |
771 | qla2x00_flip_colors(scsi_qla_host_t *ha, uint16_t *pflags) | 794 | qla2x00_flip_colors(scsi_qla_host_t *ha, uint16_t *pflags) |
@@ -919,7 +942,7 @@ qla2x00_beacon_off(struct scsi_qla_host *ha) | |||
919 | else | 942 | else |
920 | ha->beacon_color_state = QLA_LED_GRN_ON; | 943 | ha->beacon_color_state = QLA_LED_GRN_ON; |
921 | 944 | ||
922 | ha->isp_ops.beacon_blink(ha); /* This turns green LED off */ | 945 | ha->isp_ops->beacon_blink(ha); /* This turns green LED off */ |
923 | 946 | ||
924 | ha->fw_options[1] &= ~FO1_SET_EMPHASIS_SWING; | 947 | ha->fw_options[1] &= ~FO1_SET_EMPHASIS_SWING; |
925 | ha->fw_options[1] &= ~FO1_DISABLE_GPIO6_7; | 948 | ha->fw_options[1] &= ~FO1_DISABLE_GPIO6_7; |
@@ -1031,7 +1054,7 @@ qla24xx_beacon_off(struct scsi_qla_host *ha) | |||
1031 | ha->beacon_blink_led = 0; | 1054 | ha->beacon_blink_led = 0; |
1032 | ha->beacon_color_state = QLA_LED_ALL_ON; | 1055 | ha->beacon_color_state = QLA_LED_ALL_ON; |
1033 | 1056 | ||
1034 | ha->isp_ops.beacon_blink(ha); /* Will flip to all off. */ | 1057 | ha->isp_ops->beacon_blink(ha); /* Will flip to all off. */ |
1035 | 1058 | ||
1036 | /* Give control back to firmware. */ | 1059 | /* Give control back to firmware. */ |
1037 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1060 | spin_lock_irqsave(&ha->hardware_lock, flags); |
@@ -1419,7 +1442,7 @@ qla2x00_suspend_hba(struct scsi_qla_host *ha) | |||
1419 | 1442 | ||
1420 | /* Suspend HBA. */ | 1443 | /* Suspend HBA. */ |
1421 | scsi_block_requests(ha->host); | 1444 | scsi_block_requests(ha->host); |
1422 | ha->isp_ops.disable_intrs(ha); | 1445 | ha->isp_ops->disable_intrs(ha); |
1423 | set_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); | 1446 | set_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); |
1424 | 1447 | ||
1425 | /* Pause RISC. */ | 1448 | /* Pause RISC. */ |
@@ -1705,7 +1728,7 @@ qla24xx_read_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, | |||
1705 | { | 1728 | { |
1706 | /* Suspend HBA. */ | 1729 | /* Suspend HBA. */ |
1707 | scsi_block_requests(ha->host); | 1730 | scsi_block_requests(ha->host); |
1708 | ha->isp_ops.disable_intrs(ha); | 1731 | ha->isp_ops->disable_intrs(ha); |
1709 | set_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); | 1732 | set_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); |
1710 | 1733 | ||
1711 | /* Go with read. */ | 1734 | /* Go with read. */ |
@@ -1713,7 +1736,7 @@ qla24xx_read_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, | |||
1713 | 1736 | ||
1714 | /* Resume HBA. */ | 1737 | /* Resume HBA. */ |
1715 | clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); | 1738 | clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); |
1716 | ha->isp_ops.enable_intrs(ha); | 1739 | ha->isp_ops->enable_intrs(ha); |
1717 | scsi_unblock_requests(ha->host); | 1740 | scsi_unblock_requests(ha->host); |
1718 | 1741 | ||
1719 | return buf; | 1742 | return buf; |
@@ -1727,7 +1750,7 @@ qla24xx_write_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, | |||
1727 | 1750 | ||
1728 | /* Suspend HBA. */ | 1751 | /* Suspend HBA. */ |
1729 | scsi_block_requests(ha->host); | 1752 | scsi_block_requests(ha->host); |
1730 | ha->isp_ops.disable_intrs(ha); | 1753 | ha->isp_ops->disable_intrs(ha); |
1731 | set_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); | 1754 | set_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); |
1732 | 1755 | ||
1733 | /* Go with write. */ | 1756 | /* Go with write. */ |
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index fd2f10a25348..dd1f8ceb79c4 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h | |||
@@ -7,7 +7,7 @@ | |||
7 | /* | 7 | /* |
8 | * Driver version | 8 | * Driver version |
9 | */ | 9 | */ |
10 | #define QLA2XXX_VERSION "8.02.00-k1" | 10 | #define QLA2XXX_VERSION "8.02.00-k2" |
11 | 11 | ||
12 | #define QLA_DRIVER_MAJOR_VER 8 | 12 | #define QLA_DRIVER_MAJOR_VER 8 |
13 | #define QLA_DRIVER_MINOR_VER 2 | 13 | #define QLA_DRIVER_MINOR_VER 2 |
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 4cd9c58efef1..4947dfe625a6 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c | |||
@@ -2875,7 +2875,7 @@ static int __init scsi_debug_init(void) | |||
2875 | 2875 | ||
2876 | init_all_queued(); | 2876 | init_all_queued(); |
2877 | 2877 | ||
2878 | sdebug_driver_template.proc_name = (char *)sdebug_proc_name; | 2878 | sdebug_driver_template.proc_name = sdebug_proc_name; |
2879 | 2879 | ||
2880 | host_to_add = scsi_debug_add_host; | 2880 | host_to_add = scsi_debug_add_host; |
2881 | scsi_debug_add_host = 0; | 2881 | scsi_debug_add_host = 0; |
diff --git a/drivers/scsi/scsi_sysctl.c b/drivers/scsi/scsi_sysctl.c index 6cfaaa2d0c81..63a30f566f3a 100644 --- a/drivers/scsi/scsi_sysctl.c +++ b/drivers/scsi/scsi_sysctl.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/sysctl.h> | 9 | #include <linux/sysctl.h> |
10 | 10 | ||
11 | #include "scsi_logging.h" | 11 | #include "scsi_logging.h" |
12 | #include "scsi_priv.h" | ||
12 | 13 | ||
13 | 14 | ||
14 | static ctl_table scsi_table[] = { | 15 | static ctl_table scsi_table[] = { |
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index ed720863ab97..34cdce6738a6 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <scsi/scsi_host.h> | 16 | #include <scsi/scsi_host.h> |
17 | #include <scsi/scsi_tcq.h> | 17 | #include <scsi/scsi_tcq.h> |
18 | #include <scsi/scsi_transport.h> | 18 | #include <scsi/scsi_transport.h> |
19 | #include <scsi/scsi_driver.h> | ||
19 | 20 | ||
20 | #include "scsi_priv.h" | 21 | #include "scsi_priv.h" |
21 | #include "scsi_logging.h" | 22 | #include "scsi_logging.h" |
@@ -714,6 +715,7 @@ static int attr_add(struct device *dev, struct device_attribute *attr) | |||
714 | int scsi_sysfs_add_sdev(struct scsi_device *sdev) | 715 | int scsi_sysfs_add_sdev(struct scsi_device *sdev) |
715 | { | 716 | { |
716 | int error, i; | 717 | int error, i; |
718 | struct request_queue *rq = sdev->request_queue; | ||
717 | 719 | ||
718 | if ((error = scsi_device_set_state(sdev, SDEV_RUNNING)) != 0) | 720 | if ((error = scsi_device_set_state(sdev, SDEV_RUNNING)) != 0) |
719 | return error; | 721 | return error; |
@@ -733,6 +735,17 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) | |||
733 | /* take a reference for the sdev_classdev; this is | 735 | /* take a reference for the sdev_classdev; this is |
734 | * released by the sdev_class .release */ | 736 | * released by the sdev_class .release */ |
735 | get_device(&sdev->sdev_gendev); | 737 | get_device(&sdev->sdev_gendev); |
738 | |||
739 | error = bsg_register_queue(rq, &sdev->sdev_gendev, NULL); | ||
740 | |||
741 | if (error) | ||
742 | sdev_printk(KERN_INFO, sdev, | ||
743 | "Failed to register bsg queue, errno=%d\n", error); | ||
744 | |||
745 | /* we're treating error on bsg register as non-fatal, so pretend | ||
746 | * nothing went wrong */ | ||
747 | error = 0; | ||
748 | |||
736 | if (sdev->host->hostt->sdev_attrs) { | 749 | if (sdev->host->hostt->sdev_attrs) { |
737 | for (i = 0; sdev->host->hostt->sdev_attrs[i]; i++) { | 750 | for (i = 0; sdev->host->hostt->sdev_attrs[i]; i++) { |
738 | error = attr_add(&sdev->sdev_gendev, | 751 | error = attr_add(&sdev->sdev_gendev, |
@@ -779,6 +792,7 @@ void __scsi_remove_device(struct scsi_device *sdev) | |||
779 | if (scsi_device_set_state(sdev, SDEV_CANCEL) != 0) | 792 | if (scsi_device_set_state(sdev, SDEV_CANCEL) != 0) |
780 | return; | 793 | return; |
781 | 794 | ||
795 | bsg_unregister_queue(sdev->request_queue); | ||
782 | class_device_unregister(&sdev->sdev_classdev); | 796 | class_device_unregister(&sdev->sdev_classdev); |
783 | transport_remove_device(dev); | 797 | transport_remove_device(dev); |
784 | device_del(dev); | 798 | device_del(dev); |
@@ -803,7 +817,7 @@ void scsi_remove_device(struct scsi_device *sdev) | |||
803 | } | 817 | } |
804 | EXPORT_SYMBOL(scsi_remove_device); | 818 | EXPORT_SYMBOL(scsi_remove_device); |
805 | 819 | ||
806 | void __scsi_remove_target(struct scsi_target *starget) | 820 | static void __scsi_remove_target(struct scsi_target *starget) |
807 | { | 821 | { |
808 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); | 822 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); |
809 | unsigned long flags; | 823 | unsigned long flags; |
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index e8825709797e..47057254850d 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c | |||
@@ -2358,7 +2358,7 @@ fc_rport_final_delete(struct work_struct *work) | |||
2358 | * Notes: | 2358 | * Notes: |
2359 | * This routine assumes no locks are held on entry. | 2359 | * This routine assumes no locks are held on entry. |
2360 | **/ | 2360 | **/ |
2361 | struct fc_rport * | 2361 | static struct fc_rport * |
2362 | fc_rport_create(struct Scsi_Host *shost, int channel, | 2362 | fc_rport_create(struct Scsi_Host *shost, int channel, |
2363 | struct fc_rport_identifiers *ids) | 2363 | struct fc_rport_identifiers *ids) |
2364 | { | 2364 | { |
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index b2ef71a86292..3120f4b3a11a 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c | |||
@@ -29,6 +29,8 @@ | |||
29 | #include <linux/err.h> | 29 | #include <linux/err.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/string.h> | 31 | #include <linux/string.h> |
32 | #include <linux/blkdev.h> | ||
33 | #include <linux/bsg.h> | ||
32 | 34 | ||
33 | #include <scsi/scsi.h> | 35 | #include <scsi/scsi.h> |
34 | #include <scsi/scsi_device.h> | 36 | #include <scsi/scsi_device.h> |
@@ -40,6 +42,7 @@ | |||
40 | struct sas_host_attrs { | 42 | struct sas_host_attrs { |
41 | struct list_head rphy_list; | 43 | struct list_head rphy_list; |
42 | struct mutex lock; | 44 | struct mutex lock; |
45 | struct request_queue *q; | ||
43 | u32 next_target_id; | 46 | u32 next_target_id; |
44 | u32 next_expander_id; | 47 | u32 next_expander_id; |
45 | int next_port_id; | 48 | int next_port_id; |
@@ -152,6 +155,106 @@ static struct { | |||
152 | sas_bitfield_name_search(linkspeed, sas_linkspeed_names) | 155 | sas_bitfield_name_search(linkspeed, sas_linkspeed_names) |
153 | sas_bitfield_name_set(linkspeed, sas_linkspeed_names) | 156 | sas_bitfield_name_set(linkspeed, sas_linkspeed_names) |
154 | 157 | ||
158 | static void sas_smp_request(struct request_queue *q, struct Scsi_Host *shost, | ||
159 | struct sas_rphy *rphy) | ||
160 | { | ||
161 | struct request *req; | ||
162 | int ret; | ||
163 | int (*handler)(struct Scsi_Host *, struct sas_rphy *, struct request *); | ||
164 | |||
165 | while (!blk_queue_plugged(q)) { | ||
166 | req = elv_next_request(q); | ||
167 | if (!req) | ||
168 | break; | ||
169 | |||
170 | blkdev_dequeue_request(req); | ||
171 | |||
172 | spin_unlock_irq(q->queue_lock); | ||
173 | |||
174 | handler = to_sas_internal(shost->transportt)->f->smp_handler; | ||
175 | ret = handler(shost, rphy, req); | ||
176 | |||
177 | spin_lock_irq(q->queue_lock); | ||
178 | |||
179 | req->end_io(req, ret); | ||
180 | } | ||
181 | } | ||
182 | |||
183 | static void sas_host_smp_request(struct request_queue *q) | ||
184 | { | ||
185 | sas_smp_request(q, (struct Scsi_Host *)q->queuedata, NULL); | ||
186 | } | ||
187 | |||
188 | static void sas_non_host_smp_request(struct request_queue *q) | ||
189 | { | ||
190 | struct sas_rphy *rphy = q->queuedata; | ||
191 | sas_smp_request(q, rphy_to_shost(rphy), rphy); | ||
192 | } | ||
193 | |||
194 | static int sas_bsg_initialize(struct Scsi_Host *shost, struct sas_rphy *rphy) | ||
195 | { | ||
196 | struct request_queue *q; | ||
197 | int error; | ||
198 | struct device *dev; | ||
199 | char namebuf[BUS_ID_SIZE]; | ||
200 | const char *name; | ||
201 | |||
202 | if (!to_sas_internal(shost->transportt)->f->smp_handler) { | ||
203 | printk("%s can't handle SMP requests\n", shost->hostt->name); | ||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | if (rphy) { | ||
208 | q = blk_init_queue(sas_non_host_smp_request, NULL); | ||
209 | dev = &rphy->dev; | ||
210 | name = dev->bus_id; | ||
211 | } else { | ||
212 | q = blk_init_queue(sas_host_smp_request, NULL); | ||
213 | dev = &shost->shost_gendev; | ||
214 | snprintf(namebuf, sizeof(namebuf), | ||
215 | "sas_host%d", shost->host_no); | ||
216 | name = namebuf; | ||
217 | } | ||
218 | if (!q) | ||
219 | return -ENOMEM; | ||
220 | |||
221 | error = bsg_register_queue(q, dev, name); | ||
222 | if (error) { | ||
223 | blk_cleanup_queue(q); | ||
224 | return -ENOMEM; | ||
225 | } | ||
226 | |||
227 | if (rphy) | ||
228 | rphy->q = q; | ||
229 | else | ||
230 | to_sas_host_attrs(shost)->q = q; | ||
231 | |||
232 | if (rphy) | ||
233 | q->queuedata = rphy; | ||
234 | else | ||
235 | q->queuedata = shost; | ||
236 | |||
237 | set_bit(QUEUE_FLAG_BIDI, &q->queue_flags); | ||
238 | |||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | static void sas_bsg_remove(struct Scsi_Host *shost, struct sas_rphy *rphy) | ||
243 | { | ||
244 | struct request_queue *q; | ||
245 | |||
246 | if (rphy) | ||
247 | q = rphy->q; | ||
248 | else | ||
249 | q = to_sas_host_attrs(shost)->q; | ||
250 | |||
251 | if (!q) | ||
252 | return; | ||
253 | |||
254 | bsg_unregister_queue(q); | ||
255 | blk_cleanup_queue(q); | ||
256 | } | ||
257 | |||
155 | /* | 258 | /* |
156 | * SAS host attributes | 259 | * SAS host attributes |
157 | */ | 260 | */ |
@@ -167,11 +270,26 @@ static int sas_host_setup(struct transport_container *tc, struct device *dev, | |||
167 | sas_host->next_target_id = 0; | 270 | sas_host->next_target_id = 0; |
168 | sas_host->next_expander_id = 0; | 271 | sas_host->next_expander_id = 0; |
169 | sas_host->next_port_id = 0; | 272 | sas_host->next_port_id = 0; |
273 | |||
274 | if (sas_bsg_initialize(shost, NULL)) | ||
275 | dev_printk(KERN_ERR, dev, "fail to a bsg device %d\n", | ||
276 | shost->host_no); | ||
277 | |||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | static int sas_host_remove(struct transport_container *tc, struct device *dev, | ||
282 | struct class_device *cdev) | ||
283 | { | ||
284 | struct Scsi_Host *shost = dev_to_shost(dev); | ||
285 | |||
286 | sas_bsg_remove(shost, NULL); | ||
287 | |||
170 | return 0; | 288 | return 0; |
171 | } | 289 | } |
172 | 290 | ||
173 | static DECLARE_TRANSPORT_CLASS(sas_host_class, | 291 | static DECLARE_TRANSPORT_CLASS(sas_host_class, |
174 | "sas_host", sas_host_setup, NULL, NULL); | 292 | "sas_host", sas_host_setup, sas_host_remove, NULL); |
175 | 293 | ||
176 | static int sas_host_match(struct attribute_container *cont, | 294 | static int sas_host_match(struct attribute_container *cont, |
177 | struct device *dev) | 295 | struct device *dev) |
@@ -1287,6 +1405,9 @@ int sas_rphy_add(struct sas_rphy *rphy) | |||
1287 | return error; | 1405 | return error; |
1288 | transport_add_device(&rphy->dev); | 1406 | transport_add_device(&rphy->dev); |
1289 | transport_configure_device(&rphy->dev); | 1407 | transport_configure_device(&rphy->dev); |
1408 | if (sas_bsg_initialize(shost, rphy)) | ||
1409 | printk("fail to a bsg device %s\n", rphy->dev.bus_id); | ||
1410 | |||
1290 | 1411 | ||
1291 | mutex_lock(&sas_host->lock); | 1412 | mutex_lock(&sas_host->lock); |
1292 | list_add_tail(&rphy->list, &sas_host->rphy_list); | 1413 | list_add_tail(&rphy->list, &sas_host->rphy_list); |
@@ -1329,6 +1450,8 @@ void sas_rphy_free(struct sas_rphy *rphy) | |||
1329 | list_del(&rphy->list); | 1450 | list_del(&rphy->list); |
1330 | mutex_unlock(&sas_host->lock); | 1451 | mutex_unlock(&sas_host->lock); |
1331 | 1452 | ||
1453 | sas_bsg_remove(shost, rphy); | ||
1454 | |||
1332 | transport_destroy_device(dev); | 1455 | transport_destroy_device(dev); |
1333 | 1456 | ||
1334 | put_device(dev); | 1457 | put_device(dev); |
diff --git a/drivers/scsi/seagate.c b/drivers/scsi/seagate.c index ff62e9708e1c..ce80fa9ad815 100644 --- a/drivers/scsi/seagate.c +++ b/drivers/scsi/seagate.c | |||
@@ -420,7 +420,7 @@ static inline void borken_wait (void) | |||
420 | #define ULOOP( i ) for (clock = i*8;;) | 420 | #define ULOOP( i ) for (clock = i*8;;) |
421 | #define TIMEOUT (!(clock--)) | 421 | #define TIMEOUT (!(clock--)) |
422 | 422 | ||
423 | int __init seagate_st0x_detect (struct scsi_host_template * tpnt) | 423 | static int __init seagate_st0x_detect (struct scsi_host_template * tpnt) |
424 | { | 424 | { |
425 | struct Scsi_Host *instance; | 425 | struct Scsi_Host *instance; |
426 | int i, j; | 426 | int i, j; |
diff --git a/drivers/scsi/sim710.c b/drivers/scsi/sim710.c index 710f19de3d40..d63d229e2323 100644 --- a/drivers/scsi/sim710.c +++ b/drivers/scsi/sim710.c | |||
@@ -138,6 +138,7 @@ sim710_probe_common(struct device *dev, unsigned long base_addr, | |||
138 | goto out_put_host; | 138 | goto out_put_host; |
139 | } | 139 | } |
140 | 140 | ||
141 | dev_set_drvdata(dev, host); | ||
141 | scsi_scan_host(host); | 142 | scsi_scan_host(host); |
142 | 143 | ||
143 | return 0; | 144 | return 0; |
@@ -155,7 +156,7 @@ sim710_probe_common(struct device *dev, unsigned long base_addr, | |||
155 | static __devexit int | 156 | static __devexit int |
156 | sim710_device_remove(struct device *dev) | 157 | sim710_device_remove(struct device *dev) |
157 | { | 158 | { |
158 | struct Scsi_Host *host = dev_to_shost(dev); | 159 | struct Scsi_Host *host = dev_get_drvdata(dev); |
159 | struct NCR_700_Host_Parameters *hostdata = | 160 | struct NCR_700_Host_Parameters *hostdata = |
160 | (struct NCR_700_Host_Parameters *)host->hostdata[0]; | 161 | (struct NCR_700_Host_Parameters *)host->hostdata[0]; |
161 | 162 | ||
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 5143c8990845..e7b6a7fde1cb 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c | |||
@@ -175,7 +175,7 @@ static void scsi_cd_put(struct scsi_cd *cd) | |||
175 | * an inode for that to work, and we do not always have one. | 175 | * an inode for that to work, and we do not always have one. |
176 | */ | 176 | */ |
177 | 177 | ||
178 | int sr_media_change(struct cdrom_device_info *cdi, int slot) | 178 | static int sr_media_change(struct cdrom_device_info *cdi, int slot) |
179 | { | 179 | { |
180 | struct scsi_cd *cd = cdi->handle; | 180 | struct scsi_cd *cd = cdi->handle; |
181 | int retval; | 181 | int retval; |
diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c index fa4e08e508ad..b92ff047af38 100644 --- a/drivers/scsi/wd33c93.c +++ b/drivers/scsi/wd33c93.c | |||
@@ -89,6 +89,8 @@ | |||
89 | #include <scsi/scsi_device.h> | 89 | #include <scsi/scsi_device.h> |
90 | #include <scsi/scsi_host.h> | 90 | #include <scsi/scsi_host.h> |
91 | 91 | ||
92 | #include <asm/irq.h> | ||
93 | |||
92 | #include "wd33c93.h" | 94 | #include "wd33c93.h" |
93 | 95 | ||
94 | #define optimum_sx_per(hostdata) (hostdata)->sx_table[1].period_ns | 96 | #define optimum_sx_per(hostdata) (hostdata)->sx_table[1].period_ns |
@@ -1762,7 +1764,7 @@ static char setup_buffer[SETUP_BUFFER_SIZE]; | |||
1762 | static char setup_used[MAX_SETUP_ARGS]; | 1764 | static char setup_used[MAX_SETUP_ARGS]; |
1763 | static int done_setup = 0; | 1765 | static int done_setup = 0; |
1764 | 1766 | ||
1765 | int | 1767 | static int |
1766 | wd33c93_setup(char *str) | 1768 | wd33c93_setup(char *str) |
1767 | { | 1769 | { |
1768 | int i; | 1770 | int i; |
diff --git a/drivers/scsi/zorro7xx.c b/drivers/scsi/zorro7xx.c index 50703877a585..c822debc2668 100644 --- a/drivers/scsi/zorro7xx.c +++ b/drivers/scsi/zorro7xx.c | |||
@@ -130,6 +130,7 @@ static int __devinit zorro7xx_init_one(struct zorro_dev *z, | |||
130 | goto out_put_host; | 130 | goto out_put_host; |
131 | } | 131 | } |
132 | 132 | ||
133 | zorro_set_drvdata(z, host); | ||
133 | scsi_scan_host(host); | 134 | scsi_scan_host(host); |
134 | 135 | ||
135 | return 0; | 136 | return 0; |
@@ -148,7 +149,7 @@ static int __devinit zorro7xx_init_one(struct zorro_dev *z, | |||
148 | 149 | ||
149 | static __devexit void zorro7xx_remove_one(struct zorro_dev *z) | 150 | static __devexit void zorro7xx_remove_one(struct zorro_dev *z) |
150 | { | 151 | { |
151 | struct Scsi_Host *host = dev_to_shost(&z->dev); | 152 | struct Scsi_Host *host = zorro_get_drvdata(z); |
152 | struct NCR_700_Host_Parameters *hostdata = shost_priv(host); | 153 | struct NCR_700_Host_Parameters *hostdata = shost_priv(host); |
153 | 154 | ||
154 | scsi_remove_host(host); | 155 | scsi_remove_host(host); |
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index e42faa4e4282..dc1967176fe2 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c | |||
@@ -1114,8 +1114,8 @@ static int __init imx_serial_init(void) | |||
1114 | 1114 | ||
1115 | static void __exit imx_serial_exit(void) | 1115 | static void __exit imx_serial_exit(void) |
1116 | { | 1116 | { |
1117 | uart_unregister_driver(&imx_reg); | ||
1118 | platform_driver_unregister(&serial_imx_driver); | 1117 | platform_driver_unregister(&serial_imx_driver); |
1118 | uart_unregister_driver(&imx_reg); | ||
1119 | } | 1119 | } |
1120 | 1120 | ||
1121 | module_init(imx_serial_init); | 1121 | module_init(imx_serial_init); |
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c index 10bc0209cd66..3f26c4b2f322 100644 --- a/drivers/serial/s3c2410.c +++ b/drivers/serial/s3c2410.c | |||
@@ -78,7 +78,7 @@ | |||
78 | 78 | ||
79 | #include <asm/hardware.h> | 79 | #include <asm/hardware.h> |
80 | 80 | ||
81 | #include <asm/arch/regs-serial.h> | 81 | #include <asm/plat-s3c/regs-serial.h> |
82 | #include <asm/arch/regs-gpio.h> | 82 | #include <asm/arch/regs-gpio.h> |
83 | 83 | ||
84 | /* structures */ | 84 | /* structures */ |
diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c index b09c83568c1a..1cb56f2d5c84 100644 --- a/drivers/usb/misc/appledisplay.c +++ b/drivers/usb/misc/appledisplay.c | |||
@@ -138,7 +138,7 @@ exit: | |||
138 | 138 | ||
139 | static int appledisplay_bl_update_status(struct backlight_device *bd) | 139 | static int appledisplay_bl_update_status(struct backlight_device *bd) |
140 | { | 140 | { |
141 | struct appledisplay *pdata = class_get_devdata(&bd->class_dev); | 141 | struct appledisplay *pdata = bl_get_data(bd); |
142 | int retval; | 142 | int retval; |
143 | 143 | ||
144 | pdata->msgdata[0] = 0x10; | 144 | pdata->msgdata[0] = 0x10; |
@@ -159,7 +159,7 @@ static int appledisplay_bl_update_status(struct backlight_device *bd) | |||
159 | 159 | ||
160 | static int appledisplay_bl_get_brightness(struct backlight_device *bd) | 160 | static int appledisplay_bl_get_brightness(struct backlight_device *bd) |
161 | { | 161 | { |
162 | struct appledisplay *pdata = class_get_devdata(&bd->class_dev); | 162 | struct appledisplay *pdata = bl_get_data(bd); |
163 | int retval; | 163 | int retval; |
164 | 164 | ||
165 | retval = usb_control_msg( | 165 | retval = usb_control_msg( |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 2a237f09ee5d..564cc9b51822 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -12,6 +12,13 @@ config VGASTATE | |||
12 | tristate | 12 | tristate |
13 | default n | 13 | default n |
14 | 14 | ||
15 | config VIDEO_OUTPUT_CONTROL | ||
16 | tristate "Lowlevel video output switch controls" | ||
17 | default m | ||
18 | help | ||
19 | This framework adds support for low-level control of the video | ||
20 | output switch. | ||
21 | |||
15 | config FB | 22 | config FB |
16 | tristate "Support for frame buffer devices" | 23 | tristate "Support for frame buffer devices" |
17 | ---help--- | 24 | ---help--- |
diff --git a/drivers/video/Makefile b/drivers/video/Makefile index a562f9d69d2c..518933d4905f 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile | |||
@@ -123,3 +123,6 @@ obj-$(CONFIG_FB_OF) += offb.o | |||
123 | 123 | ||
124 | # the test framebuffer is last | 124 | # the test framebuffer is last |
125 | obj-$(CONFIG_FB_VIRTUAL) += vfb.o | 125 | obj-$(CONFIG_FB_VIRTUAL) += vfb.o |
126 | |||
127 | #video output switch sysfs driver | ||
128 | obj-$(CONFIG_VIDEO_OUTPUT_CONTROL) += output.o | ||
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c index 7fea4d8ae8e2..cfcbe37d2d70 100644 --- a/drivers/video/aty/aty128fb.c +++ b/drivers/video/aty/aty128fb.c | |||
@@ -1733,7 +1733,7 @@ static int aty128_bl_get_level_brightness(struct aty128fb_par *par, | |||
1733 | 1733 | ||
1734 | static int aty128_bl_update_status(struct backlight_device *bd) | 1734 | static int aty128_bl_update_status(struct backlight_device *bd) |
1735 | { | 1735 | { |
1736 | struct aty128fb_par *par = class_get_devdata(&bd->class_dev); | 1736 | struct aty128fb_par *par = bl_get_data(bd); |
1737 | unsigned int reg = aty_ld_le32(LVDS_GEN_CNTL); | 1737 | unsigned int reg = aty_ld_le32(LVDS_GEN_CNTL); |
1738 | int level; | 1738 | int level; |
1739 | 1739 | ||
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index 13990697b5c1..bc6f0096aa04 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c | |||
@@ -2141,7 +2141,7 @@ static int aty_bl_get_level_brightness(struct atyfb_par *par, int level) | |||
2141 | 2141 | ||
2142 | static int aty_bl_update_status(struct backlight_device *bd) | 2142 | static int aty_bl_update_status(struct backlight_device *bd) |
2143 | { | 2143 | { |
2144 | struct atyfb_par *par = class_get_devdata(&bd->class_dev); | 2144 | struct atyfb_par *par = bl_get_data(bd); |
2145 | unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, par); | 2145 | unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, par); |
2146 | int level; | 2146 | int level; |
2147 | 2147 | ||
diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/aty/radeon_backlight.c index 0be25fa5540c..1a056adb61c8 100644 --- a/drivers/video/aty/radeon_backlight.c +++ b/drivers/video/aty/radeon_backlight.c | |||
@@ -47,7 +47,7 @@ static int radeon_bl_get_level_brightness(struct radeon_bl_privdata *pdata, | |||
47 | 47 | ||
48 | static int radeon_bl_update_status(struct backlight_device *bd) | 48 | static int radeon_bl_update_status(struct backlight_device *bd) |
49 | { | 49 | { |
50 | struct radeon_bl_privdata *pdata = class_get_devdata(&bd->class_dev); | 50 | struct radeon_bl_privdata *pdata = bl_get_data(bd); |
51 | struct radeonfb_info *rinfo = pdata->rinfo; | 51 | struct radeonfb_info *rinfo = pdata->rinfo; |
52 | u32 lvds_gen_cntl, tmpPixclksCntl; | 52 | u32 lvds_gen_cntl, tmpPixclksCntl; |
53 | int level; | 53 | int level; |
@@ -206,7 +206,7 @@ void radeonfb_bl_exit(struct radeonfb_info *rinfo) | |||
206 | if (bd) { | 206 | if (bd) { |
207 | struct radeon_bl_privdata *pdata; | 207 | struct radeon_bl_privdata *pdata; |
208 | 208 | ||
209 | pdata = class_get_devdata(&bd->class_dev); | 209 | pdata = bl_get_data(bd); |
210 | backlight_device_unregister(bd); | 210 | backlight_device_unregister(bd); |
211 | kfree(pdata); | 211 | kfree(pdata); |
212 | rinfo->info->bl_dev = NULL; | 212 | rinfo->info->bl_dev = NULL; |
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index fbef663fc057..2580f5fa2486 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig | |||
@@ -8,26 +8,32 @@ menuconfig BACKLIGHT_LCD_SUPPORT | |||
8 | Enable this to be able to choose the drivers for controlling the | 8 | Enable this to be able to choose the drivers for controlling the |
9 | backlight and the LCD panel on some platforms, for example on PDAs. | 9 | backlight and the LCD panel on some platforms, for example on PDAs. |
10 | 10 | ||
11 | config BACKLIGHT_CLASS_DEVICE | 11 | # |
12 | tristate "Lowlevel Backlight controls" | 12 | # LCD |
13 | # | ||
14 | config LCD_CLASS_DEVICE | ||
15 | tristate "Lowlevel LCD controls" | ||
13 | depends on BACKLIGHT_LCD_SUPPORT | 16 | depends on BACKLIGHT_LCD_SUPPORT |
14 | default m | 17 | default m |
15 | help | 18 | help |
16 | This framework adds support for low-level control of the LCD | 19 | This framework adds support for low-level control of LCD. |
17 | backlight. This includes support for brightness and power. | 20 | Some framebuffer devices connect to platform-specific LCD modules |
21 | in order to have a platform-specific way to control the flat panel | ||
22 | (contrast and applying power to the LCD (not to the backlight!)). | ||
18 | 23 | ||
19 | To have support for your specific LCD panel you will have to | 24 | To have support for your specific LCD panel you will have to |
20 | select the proper drivers which depend on this option. | 25 | select the proper drivers which depend on this option. |
21 | 26 | ||
22 | config LCD_CLASS_DEVICE | 27 | # |
23 | tristate "Lowlevel LCD controls" | 28 | # Backlight |
29 | # | ||
30 | config BACKLIGHT_CLASS_DEVICE | ||
31 | tristate "Lowlevel Backlight controls" | ||
24 | depends on BACKLIGHT_LCD_SUPPORT | 32 | depends on BACKLIGHT_LCD_SUPPORT |
25 | default m | 33 | default m |
26 | help | 34 | help |
27 | This framework adds support for low-level control of LCD. | 35 | This framework adds support for low-level control of the LCD |
28 | Some framebuffer devices connect to platform-specific LCD modules | 36 | backlight. This includes support for brightness and power. |
29 | in order to have a platform-specific way to control the flat panel | ||
30 | (contrast and applying power to the LCD (not to the backlight!)). | ||
31 | 37 | ||
32 | To have support for your specific LCD panel you will have to | 38 | To have support for your specific LCD panel you will have to |
33 | select the proper drivers which depend on this option. | 39 | select the proper drivers which depend on this option. |
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index 7e06223bca94..b26de8cf3112 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c | |||
@@ -69,18 +69,20 @@ static inline void backlight_unregister_fb(struct backlight_device *bd) | |||
69 | } | 69 | } |
70 | #endif /* CONFIG_FB */ | 70 | #endif /* CONFIG_FB */ |
71 | 71 | ||
72 | static ssize_t backlight_show_power(struct class_device *cdev, char *buf) | 72 | static ssize_t backlight_show_power(struct device *dev, |
73 | struct device_attribute *attr,char *buf) | ||
73 | { | 74 | { |
74 | struct backlight_device *bd = to_backlight_device(cdev); | 75 | struct backlight_device *bd = to_backlight_device(dev); |
75 | 76 | ||
76 | return sprintf(buf, "%d\n", bd->props.power); | 77 | return sprintf(buf, "%d\n", bd->props.power); |
77 | } | 78 | } |
78 | 79 | ||
79 | static ssize_t backlight_store_power(struct class_device *cdev, const char *buf, size_t count) | 80 | static ssize_t backlight_store_power(struct device *dev, |
81 | struct device_attribute *attr, const char *buf, size_t count) | ||
80 | { | 82 | { |
81 | int rc = -ENXIO; | 83 | int rc = -ENXIO; |
82 | char *endp; | 84 | char *endp; |
83 | struct backlight_device *bd = to_backlight_device(cdev); | 85 | struct backlight_device *bd = to_backlight_device(dev); |
84 | int power = simple_strtoul(buf, &endp, 0); | 86 | int power = simple_strtoul(buf, &endp, 0); |
85 | size_t size = endp - buf; | 87 | size_t size = endp - buf; |
86 | 88 | ||
@@ -101,18 +103,20 @@ static ssize_t backlight_store_power(struct class_device *cdev, const char *buf, | |||
101 | return rc; | 103 | return rc; |
102 | } | 104 | } |
103 | 105 | ||
104 | static ssize_t backlight_show_brightness(struct class_device *cdev, char *buf) | 106 | static ssize_t backlight_show_brightness(struct device *dev, |
107 | struct device_attribute *attr, char *buf) | ||
105 | { | 108 | { |
106 | struct backlight_device *bd = to_backlight_device(cdev); | 109 | struct backlight_device *bd = to_backlight_device(dev); |
107 | 110 | ||
108 | return sprintf(buf, "%d\n", bd->props.brightness); | 111 | return sprintf(buf, "%d\n", bd->props.brightness); |
109 | } | 112 | } |
110 | 113 | ||
111 | static ssize_t backlight_store_brightness(struct class_device *cdev, const char *buf, size_t count) | 114 | static ssize_t backlight_store_brightness(struct device *dev, |
115 | struct device_attribute *attr, const char *buf, size_t count) | ||
112 | { | 116 | { |
113 | int rc = -ENXIO; | 117 | int rc = -ENXIO; |
114 | char *endp; | 118 | char *endp; |
115 | struct backlight_device *bd = to_backlight_device(cdev); | 119 | struct backlight_device *bd = to_backlight_device(dev); |
116 | int brightness = simple_strtoul(buf, &endp, 0); | 120 | int brightness = simple_strtoul(buf, &endp, 0); |
117 | size_t size = endp - buf; | 121 | size_t size = endp - buf; |
118 | 122 | ||
@@ -138,18 +142,19 @@ static ssize_t backlight_store_brightness(struct class_device *cdev, const char | |||
138 | return rc; | 142 | return rc; |
139 | } | 143 | } |
140 | 144 | ||
141 | static ssize_t backlight_show_max_brightness(struct class_device *cdev, char *buf) | 145 | static ssize_t backlight_show_max_brightness(struct device *dev, |
146 | struct device_attribute *attr, char *buf) | ||
142 | { | 147 | { |
143 | struct backlight_device *bd = to_backlight_device(cdev); | 148 | struct backlight_device *bd = to_backlight_device(dev); |
144 | 149 | ||
145 | return sprintf(buf, "%d\n", bd->props.max_brightness); | 150 | return sprintf(buf, "%d\n", bd->props.max_brightness); |
146 | } | 151 | } |
147 | 152 | ||
148 | static ssize_t backlight_show_actual_brightness(struct class_device *cdev, | 153 | static ssize_t backlight_show_actual_brightness(struct device *dev, |
149 | char *buf) | 154 | struct device_attribute *attr, char *buf) |
150 | { | 155 | { |
151 | int rc = -ENXIO; | 156 | int rc = -ENXIO; |
152 | struct backlight_device *bd = to_backlight_device(cdev); | 157 | struct backlight_device *bd = to_backlight_device(dev); |
153 | 158 | ||
154 | mutex_lock(&bd->ops_lock); | 159 | mutex_lock(&bd->ops_lock); |
155 | if (bd->ops && bd->ops->get_brightness) | 160 | if (bd->ops && bd->ops->get_brightness) |
@@ -159,31 +164,22 @@ static ssize_t backlight_show_actual_brightness(struct class_device *cdev, | |||
159 | return rc; | 164 | return rc; |
160 | } | 165 | } |
161 | 166 | ||
162 | static void backlight_class_release(struct class_device *dev) | 167 | struct class *backlight_class; |
168 | |||
169 | static void bl_device_release(struct device *dev) | ||
163 | { | 170 | { |
164 | struct backlight_device *bd = to_backlight_device(dev); | 171 | struct backlight_device *bd = to_backlight_device(dev); |
165 | kfree(bd); | 172 | kfree(bd); |
166 | } | 173 | } |
167 | 174 | ||
168 | static struct class backlight_class = { | 175 | static struct device_attribute bl_device_attributes[] = { |
169 | .name = "backlight", | 176 | __ATTR(bl_power, 0644, backlight_show_power, backlight_store_power), |
170 | .release = backlight_class_release, | 177 | __ATTR(brightness, 0644, backlight_show_brightness, |
171 | }; | ||
172 | |||
173 | #define DECLARE_ATTR(_name,_mode,_show,_store) \ | ||
174 | { \ | ||
175 | .attr = { .name = __stringify(_name), .mode = _mode }, \ | ||
176 | .show = _show, \ | ||
177 | .store = _store, \ | ||
178 | } | ||
179 | |||
180 | static const struct class_device_attribute bl_class_device_attributes[] = { | ||
181 | DECLARE_ATTR(power, 0644, backlight_show_power, backlight_store_power), | ||
182 | DECLARE_ATTR(brightness, 0644, backlight_show_brightness, | ||
183 | backlight_store_brightness), | 178 | backlight_store_brightness), |
184 | DECLARE_ATTR(actual_brightness, 0444, backlight_show_actual_brightness, | 179 | __ATTR(actual_brightness, 0444, backlight_show_actual_brightness, |
185 | NULL), | 180 | NULL), |
186 | DECLARE_ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL), | 181 | __ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL), |
182 | __ATTR_NULL, | ||
187 | }; | 183 | }; |
188 | 184 | ||
189 | /** | 185 | /** |
@@ -191,22 +187,20 @@ static const struct class_device_attribute bl_class_device_attributes[] = { | |||
191 | * backlight_device class. | 187 | * backlight_device class. |
192 | * @name: the name of the new object(must be the same as the name of the | 188 | * @name: the name of the new object(must be the same as the name of the |
193 | * respective framebuffer device). | 189 | * respective framebuffer device). |
194 | * @devdata: an optional pointer to be stored in the class_device. The | 190 | * @devdata: an optional pointer to be stored for private driver use. The |
195 | * methods may retrieve it by using class_get_devdata(&bd->class_dev). | 191 | * methods may retrieve it by using bl_get_data(bd). |
196 | * @ops: the backlight operations structure. | 192 | * @ops: the backlight operations structure. |
197 | * | 193 | * |
198 | * Creates and registers new backlight class_device. Returns either an | 194 | * Creates and registers new backlight device. Returns either an |
199 | * ERR_PTR() or a pointer to the newly allocated device. | 195 | * ERR_PTR() or a pointer to the newly allocated device. |
200 | */ | 196 | */ |
201 | struct backlight_device *backlight_device_register(const char *name, | 197 | struct backlight_device *backlight_device_register(const char *name, |
202 | struct device *dev, | 198 | struct device *parent, void *devdata, struct backlight_ops *ops) |
203 | void *devdata, | ||
204 | struct backlight_ops *ops) | ||
205 | { | 199 | { |
206 | int i, rc; | ||
207 | struct backlight_device *new_bd; | 200 | struct backlight_device *new_bd; |
201 | int rc; | ||
208 | 202 | ||
209 | pr_debug("backlight_device_alloc: name=%s\n", name); | 203 | pr_debug("backlight_device_register: name=%s\n", name); |
210 | 204 | ||
211 | new_bd = kzalloc(sizeof(struct backlight_device), GFP_KERNEL); | 205 | new_bd = kzalloc(sizeof(struct backlight_device), GFP_KERNEL); |
212 | if (!new_bd) | 206 | if (!new_bd) |
@@ -214,13 +208,14 @@ struct backlight_device *backlight_device_register(const char *name, | |||
214 | 208 | ||
215 | mutex_init(&new_bd->update_lock); | 209 | mutex_init(&new_bd->update_lock); |
216 | mutex_init(&new_bd->ops_lock); | 210 | mutex_init(&new_bd->ops_lock); |
217 | new_bd->ops = ops; | ||
218 | new_bd->class_dev.class = &backlight_class; | ||
219 | new_bd->class_dev.dev = dev; | ||
220 | strlcpy(new_bd->class_dev.class_id, name, KOBJ_NAME_LEN); | ||
221 | class_set_devdata(&new_bd->class_dev, devdata); | ||
222 | 211 | ||
223 | rc = class_device_register(&new_bd->class_dev); | 212 | new_bd->dev.class = backlight_class; |
213 | new_bd->dev.parent = parent; | ||
214 | new_bd->dev.release = bl_device_release; | ||
215 | strlcpy(new_bd->dev.bus_id, name, BUS_ID_SIZE); | ||
216 | dev_set_drvdata(&new_bd->dev, devdata); | ||
217 | |||
218 | rc = device_register(&new_bd->dev); | ||
224 | if (rc) { | 219 | if (rc) { |
225 | kfree(new_bd); | 220 | kfree(new_bd); |
226 | return ERR_PTR(rc); | 221 | return ERR_PTR(rc); |
@@ -228,23 +223,11 @@ struct backlight_device *backlight_device_register(const char *name, | |||
228 | 223 | ||
229 | rc = backlight_register_fb(new_bd); | 224 | rc = backlight_register_fb(new_bd); |
230 | if (rc) { | 225 | if (rc) { |
231 | class_device_unregister(&new_bd->class_dev); | 226 | device_unregister(&new_bd->dev); |
232 | return ERR_PTR(rc); | 227 | return ERR_PTR(rc); |
233 | } | 228 | } |
234 | 229 | ||
235 | 230 | new_bd->ops = ops; | |
236 | for (i = 0; i < ARRAY_SIZE(bl_class_device_attributes); i++) { | ||
237 | rc = class_device_create_file(&new_bd->class_dev, | ||
238 | &bl_class_device_attributes[i]); | ||
239 | if (rc) { | ||
240 | while (--i >= 0) | ||
241 | class_device_remove_file(&new_bd->class_dev, | ||
242 | &bl_class_device_attributes[i]); | ||
243 | class_device_unregister(&new_bd->class_dev); | ||
244 | /* No need to kfree(new_bd) since release() method was called */ | ||
245 | return ERR_PTR(rc); | ||
246 | } | ||
247 | } | ||
248 | 231 | ||
249 | #ifdef CONFIG_PMAC_BACKLIGHT | 232 | #ifdef CONFIG_PMAC_BACKLIGHT |
250 | mutex_lock(&pmac_backlight_mutex); | 233 | mutex_lock(&pmac_backlight_mutex); |
@@ -265,42 +248,40 @@ EXPORT_SYMBOL(backlight_device_register); | |||
265 | */ | 248 | */ |
266 | void backlight_device_unregister(struct backlight_device *bd) | 249 | void backlight_device_unregister(struct backlight_device *bd) |
267 | { | 250 | { |
268 | int i; | ||
269 | |||
270 | if (!bd) | 251 | if (!bd) |
271 | return; | 252 | return; |
272 | 253 | ||
273 | pr_debug("backlight_device_unregister: name=%s\n", bd->class_dev.class_id); | ||
274 | |||
275 | #ifdef CONFIG_PMAC_BACKLIGHT | 254 | #ifdef CONFIG_PMAC_BACKLIGHT |
276 | mutex_lock(&pmac_backlight_mutex); | 255 | mutex_lock(&pmac_backlight_mutex); |
277 | if (pmac_backlight == bd) | 256 | if (pmac_backlight == bd) |
278 | pmac_backlight = NULL; | 257 | pmac_backlight = NULL; |
279 | mutex_unlock(&pmac_backlight_mutex); | 258 | mutex_unlock(&pmac_backlight_mutex); |
280 | #endif | 259 | #endif |
281 | |||
282 | for (i = 0; i < ARRAY_SIZE(bl_class_device_attributes); i++) | ||
283 | class_device_remove_file(&bd->class_dev, | ||
284 | &bl_class_device_attributes[i]); | ||
285 | |||
286 | mutex_lock(&bd->ops_lock); | 260 | mutex_lock(&bd->ops_lock); |
287 | bd->ops = NULL; | 261 | bd->ops = NULL; |
288 | mutex_unlock(&bd->ops_lock); | 262 | mutex_unlock(&bd->ops_lock); |
289 | 263 | ||
290 | backlight_unregister_fb(bd); | 264 | backlight_unregister_fb(bd); |
291 | 265 | device_unregister(&bd->dev); | |
292 | class_device_unregister(&bd->class_dev); | ||
293 | } | 266 | } |
294 | EXPORT_SYMBOL(backlight_device_unregister); | 267 | EXPORT_SYMBOL(backlight_device_unregister); |
295 | 268 | ||
296 | static void __exit backlight_class_exit(void) | 269 | static void __exit backlight_class_exit(void) |
297 | { | 270 | { |
298 | class_unregister(&backlight_class); | 271 | class_destroy(backlight_class); |
299 | } | 272 | } |
300 | 273 | ||
301 | static int __init backlight_class_init(void) | 274 | static int __init backlight_class_init(void) |
302 | { | 275 | { |
303 | return class_register(&backlight_class); | 276 | backlight_class = class_create(THIS_MODULE, "backlight"); |
277 | if (IS_ERR(backlight_class)) { | ||
278 | printk(KERN_WARNING "Unable to create backlight class; errno = %ld\n", | ||
279 | PTR_ERR(backlight_class)); | ||
280 | return PTR_ERR(backlight_class); | ||
281 | } | ||
282 | |||
283 | backlight_class->dev_attrs = bl_device_attributes; | ||
284 | return 0; | ||
304 | } | 285 | } |
305 | 286 | ||
306 | /* | 287 | /* |
diff --git a/drivers/video/backlight/cr_bllcd.c b/drivers/video/backlight/cr_bllcd.c index 1b3f6586bc9f..b7904da51b23 100644 --- a/drivers/video/backlight/cr_bllcd.c +++ b/drivers/video/backlight/cr_bllcd.c | |||
@@ -202,7 +202,7 @@ static int cr_backlight_probe(struct platform_device *pdev) | |||
202 | } | 202 | } |
203 | 203 | ||
204 | crp->cr_lcd_device = lcd_device_register("cr-lcd", | 204 | crp->cr_lcd_device = lcd_device_register("cr-lcd", |
205 | &pdev->dev, | 205 | &pdev->dev, NULL, |
206 | &cr_lcd_ops); | 206 | &cr_lcd_ops); |
207 | 207 | ||
208 | if (IS_ERR(crp->cr_lcd_device)) { | 208 | if (IS_ERR(crp->cr_lcd_device)) { |
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c index 648b53c1fdea..6f652c65fae1 100644 --- a/drivers/video/backlight/lcd.c +++ b/drivers/video/backlight/lcd.c | |||
@@ -61,10 +61,11 @@ static inline void lcd_unregister_fb(struct lcd_device *ld) | |||
61 | } | 61 | } |
62 | #endif /* CONFIG_FB */ | 62 | #endif /* CONFIG_FB */ |
63 | 63 | ||
64 | static ssize_t lcd_show_power(struct class_device *cdev, char *buf) | 64 | static ssize_t lcd_show_power(struct device *dev, struct device_attribute *attr, |
65 | char *buf) | ||
65 | { | 66 | { |
66 | int rc; | 67 | int rc; |
67 | struct lcd_device *ld = to_lcd_device(cdev); | 68 | struct lcd_device *ld = to_lcd_device(dev); |
68 | 69 | ||
69 | mutex_lock(&ld->ops_lock); | 70 | mutex_lock(&ld->ops_lock); |
70 | if (ld->ops && ld->ops->get_power) | 71 | if (ld->ops && ld->ops->get_power) |
@@ -76,11 +77,12 @@ static ssize_t lcd_show_power(struct class_device *cdev, char *buf) | |||
76 | return rc; | 77 | return rc; |
77 | } | 78 | } |
78 | 79 | ||
79 | static ssize_t lcd_store_power(struct class_device *cdev, const char *buf, size_t count) | 80 | static ssize_t lcd_store_power(struct device *dev, |
81 | struct device_attribute *attr, const char *buf, size_t count) | ||
80 | { | 82 | { |
81 | int rc = -ENXIO; | 83 | int rc = -ENXIO; |
82 | char *endp; | 84 | char *endp; |
83 | struct lcd_device *ld = to_lcd_device(cdev); | 85 | struct lcd_device *ld = to_lcd_device(dev); |
84 | int power = simple_strtoul(buf, &endp, 0); | 86 | int power = simple_strtoul(buf, &endp, 0); |
85 | size_t size = endp - buf; | 87 | size_t size = endp - buf; |
86 | 88 | ||
@@ -100,10 +102,11 @@ static ssize_t lcd_store_power(struct class_device *cdev, const char *buf, size_ | |||
100 | return rc; | 102 | return rc; |
101 | } | 103 | } |
102 | 104 | ||
103 | static ssize_t lcd_show_contrast(struct class_device *cdev, char *buf) | 105 | static ssize_t lcd_show_contrast(struct device *dev, |
106 | struct device_attribute *attr, char *buf) | ||
104 | { | 107 | { |
105 | int rc = -ENXIO; | 108 | int rc = -ENXIO; |
106 | struct lcd_device *ld = to_lcd_device(cdev); | 109 | struct lcd_device *ld = to_lcd_device(dev); |
107 | 110 | ||
108 | mutex_lock(&ld->ops_lock); | 111 | mutex_lock(&ld->ops_lock); |
109 | if (ld->ops && ld->ops->get_contrast) | 112 | if (ld->ops && ld->ops->get_contrast) |
@@ -113,11 +116,12 @@ static ssize_t lcd_show_contrast(struct class_device *cdev, char *buf) | |||
113 | return rc; | 116 | return rc; |
114 | } | 117 | } |
115 | 118 | ||
116 | static ssize_t lcd_store_contrast(struct class_device *cdev, const char *buf, size_t count) | 119 | static ssize_t lcd_store_contrast(struct device *dev, |
120 | struct device_attribute *attr, const char *buf, size_t count) | ||
117 | { | 121 | { |
118 | int rc = -ENXIO; | 122 | int rc = -ENXIO; |
119 | char *endp; | 123 | char *endp; |
120 | struct lcd_device *ld = to_lcd_device(cdev); | 124 | struct lcd_device *ld = to_lcd_device(dev); |
121 | int contrast = simple_strtoul(buf, &endp, 0); | 125 | int contrast = simple_strtoul(buf, &endp, 0); |
122 | size_t size = endp - buf; | 126 | size_t size = endp - buf; |
123 | 127 | ||
@@ -137,53 +141,45 @@ static ssize_t lcd_store_contrast(struct class_device *cdev, const char *buf, si | |||
137 | return rc; | 141 | return rc; |
138 | } | 142 | } |
139 | 143 | ||
140 | static ssize_t lcd_show_max_contrast(struct class_device *cdev, char *buf) | 144 | static ssize_t lcd_show_max_contrast(struct device *dev, |
145 | struct device_attribute *attr, char *buf) | ||
141 | { | 146 | { |
142 | struct lcd_device *ld = to_lcd_device(cdev); | 147 | struct lcd_device *ld = to_lcd_device(dev); |
143 | 148 | ||
144 | return sprintf(buf, "%d\n", ld->props.max_contrast); | 149 | return sprintf(buf, "%d\n", ld->props.max_contrast); |
145 | } | 150 | } |
146 | 151 | ||
147 | static void lcd_class_release(struct class_device *dev) | 152 | struct class *lcd_class; |
153 | |||
154 | static void lcd_device_release(struct device *dev) | ||
148 | { | 155 | { |
149 | struct lcd_device *ld = to_lcd_device(dev); | 156 | struct lcd_device *ld = to_lcd_device(dev); |
150 | kfree(ld); | 157 | kfree(ld); |
151 | } | 158 | } |
152 | 159 | ||
153 | static struct class lcd_class = { | 160 | static struct device_attribute lcd_device_attributes[] = { |
154 | .name = "lcd", | 161 | __ATTR(lcd_power, 0644, lcd_show_power, lcd_store_power), |
155 | .release = lcd_class_release, | 162 | __ATTR(contrast, 0644, lcd_show_contrast, lcd_store_contrast), |
156 | }; | 163 | __ATTR(max_contrast, 0444, lcd_show_max_contrast, NULL), |
157 | 164 | __ATTR_NULL, | |
158 | #define DECLARE_ATTR(_name,_mode,_show,_store) \ | ||
159 | { \ | ||
160 | .attr = { .name = __stringify(_name), .mode = _mode }, \ | ||
161 | .show = _show, \ | ||
162 | .store = _store, \ | ||
163 | } | ||
164 | |||
165 | static const struct class_device_attribute lcd_class_device_attributes[] = { | ||
166 | DECLARE_ATTR(power, 0644, lcd_show_power, lcd_store_power), | ||
167 | DECLARE_ATTR(contrast, 0644, lcd_show_contrast, lcd_store_contrast), | ||
168 | DECLARE_ATTR(max_contrast, 0444, lcd_show_max_contrast, NULL), | ||
169 | }; | 165 | }; |
170 | 166 | ||
171 | /** | 167 | /** |
172 | * lcd_device_register - register a new object of lcd_device class. | 168 | * lcd_device_register - register a new object of lcd_device class. |
173 | * @name: the name of the new object(must be the same as the name of the | 169 | * @name: the name of the new object(must be the same as the name of the |
174 | * respective framebuffer device). | 170 | * respective framebuffer device). |
175 | * @devdata: an optional pointer to be stored in the class_device. The | 171 | * @devdata: an optional pointer to be stored in the device. The |
176 | * methods may retrieve it by using class_get_devdata(ld->class_dev). | 172 | * methods may retrieve it by using lcd_get_data(ld). |
177 | * @ops: the lcd operations structure. | 173 | * @ops: the lcd operations structure. |
178 | * | 174 | * |
179 | * Creates and registers a new lcd class_device. Returns either an ERR_PTR() | 175 | * Creates and registers a new lcd device. Returns either an ERR_PTR() |
180 | * or a pointer to the newly allocated device. | 176 | * or a pointer to the newly allocated device. |
181 | */ | 177 | */ |
182 | struct lcd_device *lcd_device_register(const char *name, void *devdata, | 178 | struct lcd_device *lcd_device_register(const char *name, struct device *parent, |
183 | struct lcd_ops *ops) | 179 | void *devdata, struct lcd_ops *ops) |
184 | { | 180 | { |
185 | int i, rc; | ||
186 | struct lcd_device *new_ld; | 181 | struct lcd_device *new_ld; |
182 | int rc; | ||
187 | 183 | ||
188 | pr_debug("lcd_device_register: name=%s\n", name); | 184 | pr_debug("lcd_device_register: name=%s\n", name); |
189 | 185 | ||
@@ -193,12 +189,14 @@ struct lcd_device *lcd_device_register(const char *name, void *devdata, | |||
193 | 189 | ||
194 | mutex_init(&new_ld->ops_lock); | 190 | mutex_init(&new_ld->ops_lock); |
195 | mutex_init(&new_ld->update_lock); | 191 | mutex_init(&new_ld->update_lock); |
196 | new_ld->ops = ops; | ||
197 | new_ld->class_dev.class = &lcd_class; | ||
198 | strlcpy(new_ld->class_dev.class_id, name, KOBJ_NAME_LEN); | ||
199 | class_set_devdata(&new_ld->class_dev, devdata); | ||
200 | 192 | ||
201 | rc = class_device_register(&new_ld->class_dev); | 193 | new_ld->dev.class = lcd_class; |
194 | new_ld->dev.parent = parent; | ||
195 | new_ld->dev.release = lcd_device_release; | ||
196 | strlcpy(new_ld->dev.bus_id, name, BUS_ID_SIZE); | ||
197 | dev_set_drvdata(&new_ld->dev, devdata); | ||
198 | |||
199 | rc = device_register(&new_ld->dev); | ||
202 | if (rc) { | 200 | if (rc) { |
203 | kfree(new_ld); | 201 | kfree(new_ld); |
204 | return ERR_PTR(rc); | 202 | return ERR_PTR(rc); |
@@ -206,22 +204,11 @@ struct lcd_device *lcd_device_register(const char *name, void *devdata, | |||
206 | 204 | ||
207 | rc = lcd_register_fb(new_ld); | 205 | rc = lcd_register_fb(new_ld); |
208 | if (rc) { | 206 | if (rc) { |
209 | class_device_unregister(&new_ld->class_dev); | 207 | device_unregister(&new_ld->dev); |
210 | return ERR_PTR(rc); | 208 | return ERR_PTR(rc); |
211 | } | 209 | } |
212 | 210 | ||
213 | for (i = 0; i < ARRAY_SIZE(lcd_class_device_attributes); i++) { | 211 | new_ld->ops = ops; |
214 | rc = class_device_create_file(&new_ld->class_dev, | ||
215 | &lcd_class_device_attributes[i]); | ||
216 | if (rc) { | ||
217 | while (--i >= 0) | ||
218 | class_device_remove_file(&new_ld->class_dev, | ||
219 | &lcd_class_device_attributes[i]); | ||
220 | class_device_unregister(&new_ld->class_dev); | ||
221 | /* No need to kfree(new_ld) since release() method was called */ | ||
222 | return ERR_PTR(rc); | ||
223 | } | ||
224 | } | ||
225 | 212 | ||
226 | return new_ld; | 213 | return new_ld; |
227 | } | 214 | } |
@@ -235,33 +222,34 @@ EXPORT_SYMBOL(lcd_device_register); | |||
235 | */ | 222 | */ |
236 | void lcd_device_unregister(struct lcd_device *ld) | 223 | void lcd_device_unregister(struct lcd_device *ld) |
237 | { | 224 | { |
238 | int i; | ||
239 | |||
240 | if (!ld) | 225 | if (!ld) |
241 | return; | 226 | return; |
242 | 227 | ||
243 | pr_debug("lcd_device_unregister: name=%s\n", ld->class_dev.class_id); | ||
244 | |||
245 | for (i = 0; i < ARRAY_SIZE(lcd_class_device_attributes); i++) | ||
246 | class_device_remove_file(&ld->class_dev, | ||
247 | &lcd_class_device_attributes[i]); | ||
248 | |||
249 | mutex_lock(&ld->ops_lock); | 228 | mutex_lock(&ld->ops_lock); |
250 | ld->ops = NULL; | 229 | ld->ops = NULL; |
251 | mutex_unlock(&ld->ops_lock); | 230 | mutex_unlock(&ld->ops_lock); |
252 | lcd_unregister_fb(ld); | 231 | lcd_unregister_fb(ld); |
253 | class_device_unregister(&ld->class_dev); | 232 | |
233 | device_unregister(&ld->dev); | ||
254 | } | 234 | } |
255 | EXPORT_SYMBOL(lcd_device_unregister); | 235 | EXPORT_SYMBOL(lcd_device_unregister); |
256 | 236 | ||
257 | static void __exit lcd_class_exit(void) | 237 | static void __exit lcd_class_exit(void) |
258 | { | 238 | { |
259 | class_unregister(&lcd_class); | 239 | class_destroy(lcd_class); |
260 | } | 240 | } |
261 | 241 | ||
262 | static int __init lcd_class_init(void) | 242 | static int __init lcd_class_init(void) |
263 | { | 243 | { |
264 | return class_register(&lcd_class); | 244 | lcd_class = class_create(THIS_MODULE, "lcd"); |
245 | if (IS_ERR(lcd_class)) { | ||
246 | printk(KERN_WARNING "Unable to create backlight class; errno = %ld\n", | ||
247 | PTR_ERR(lcd_class)); | ||
248 | return PTR_ERR(lcd_class); | ||
249 | } | ||
250 | |||
251 | lcd_class->dev_attrs = lcd_device_attributes; | ||
252 | return 0; | ||
265 | } | 253 | } |
266 | 254 | ||
267 | /* | 255 | /* |
diff --git a/drivers/video/nvidia/nv_backlight.c b/drivers/video/nvidia/nv_backlight.c index 43f62d8ee41d..443e3c85a9a0 100644 --- a/drivers/video/nvidia/nv_backlight.c +++ b/drivers/video/nvidia/nv_backlight.c | |||
@@ -50,7 +50,7 @@ static int nvidia_bl_get_level_brightness(struct nvidia_par *par, | |||
50 | 50 | ||
51 | static int nvidia_bl_update_status(struct backlight_device *bd) | 51 | static int nvidia_bl_update_status(struct backlight_device *bd) |
52 | { | 52 | { |
53 | struct nvidia_par *par = class_get_devdata(&bd->class_dev); | 53 | struct nvidia_par *par = bl_get_data(bd); |
54 | u32 tmp_pcrt, tmp_pmc, fpcontrol; | 54 | u32 tmp_pcrt, tmp_pmc, fpcontrol; |
55 | int level; | 55 | int level; |
56 | 56 | ||
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c index 41381e61832c..5c47968e7f21 100644 --- a/drivers/video/riva/fbdev.c +++ b/drivers/video/riva/fbdev.c | |||
@@ -307,7 +307,7 @@ static int riva_bl_get_level_brightness(struct riva_par *par, | |||
307 | 307 | ||
308 | static int riva_bl_update_status(struct backlight_device *bd) | 308 | static int riva_bl_update_status(struct backlight_device *bd) |
309 | { | 309 | { |
310 | struct riva_par *par = class_get_devdata(&bd->class_dev); | 310 | struct riva_par *par = bl_get_data(bd); |
311 | U032 tmp_pcrt, tmp_pmc; | 311 | U032 tmp_pcrt, tmp_pmc; |
312 | int level; | 312 | int level; |
313 | 313 | ||
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index b34b7a711d5b..b2a851c1b8cb 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -732,7 +732,7 @@ static int nfs_parse_mount_options(char *raw, | |||
732 | return 0; | 732 | return 0; |
733 | if (option < 0 || option > 65535) | 733 | if (option < 0 || option > 65535) |
734 | return 0; | 734 | return 0; |
735 | mnt->nfs_server.address.sin_port = htonl(option); | 735 | mnt->nfs_server.address.sin_port = htons(option); |
736 | break; | 736 | break; |
737 | case Opt_rsize: | 737 | case Opt_rsize: |
738 | if (match_int(args, &mnt->rsize)) | 738 | if (match_int(args, &mnt->rsize)) |
diff --git a/include/acpi/acmacros.h b/include/acpi/acmacros.h index 8948a6461834..45662f6dbdb6 100644 --- a/include/acpi/acmacros.h +++ b/include/acpi/acmacros.h | |||
@@ -486,6 +486,8 @@ | |||
486 | #define ACPI_FUNCTION_NAME(name) | 486 | #define ACPI_FUNCTION_NAME(name) |
487 | #endif | 487 | #endif |
488 | 488 | ||
489 | #ifdef DEBUG_FUNC_TRACE | ||
490 | |||
489 | #define ACPI_FUNCTION_TRACE(a) ACPI_FUNCTION_NAME(a) \ | 491 | #define ACPI_FUNCTION_TRACE(a) ACPI_FUNCTION_NAME(a) \ |
490 | acpi_ut_trace(ACPI_DEBUG_PARAMETERS) | 492 | acpi_ut_trace(ACPI_DEBUG_PARAMETERS) |
491 | #define ACPI_FUNCTION_TRACE_PTR(a,b) ACPI_FUNCTION_NAME(a) \ | 493 | #define ACPI_FUNCTION_TRACE_PTR(a,b) ACPI_FUNCTION_NAME(a) \ |
@@ -563,6 +565,27 @@ | |||
563 | 565 | ||
564 | #endif /* ACPI_SIMPLE_RETURN_MACROS */ | 566 | #endif /* ACPI_SIMPLE_RETURN_MACROS */ |
565 | 567 | ||
568 | #else /* !DEBUG_FUNC_TRACE */ | ||
569 | |||
570 | #define ACPI_FUNCTION_TRACE(a) | ||
571 | #define ACPI_FUNCTION_TRACE_PTR(a,b) | ||
572 | #define ACPI_FUNCTION_TRACE_U32(a,b) | ||
573 | #define ACPI_FUNCTION_TRACE_STR(a,b) | ||
574 | #define ACPI_FUNCTION_EXIT | ||
575 | #define ACPI_FUNCTION_STATUS_EXIT(s) | ||
576 | #define ACPI_FUNCTION_VALUE_EXIT(s) | ||
577 | #define ACPI_FUNCTION_TRACE(a) | ||
578 | #define ACPI_FUNCTION_ENTRY() | ||
579 | |||
580 | #define return_VOID return | ||
581 | #define return_ACPI_STATUS(s) return(s) | ||
582 | #define return_VALUE(s) return(s) | ||
583 | #define return_UINT8(s) return(s) | ||
584 | #define return_UINT32(s) return(s) | ||
585 | #define return_PTR(s) return(s) | ||
586 | |||
587 | #endif /* DEBUG_FUNC_TRACE */ | ||
588 | |||
566 | /* Conditional execution */ | 589 | /* Conditional execution */ |
567 | 590 | ||
568 | #define ACPI_DEBUG_EXEC(a) a | 591 | #define ACPI_DEBUG_EXEC(a) a |
@@ -599,26 +622,26 @@ | |||
599 | #define ACPI_DEBUG_EXEC(a) | 622 | #define ACPI_DEBUG_EXEC(a) |
600 | #define ACPI_NORMAL_EXEC(a) a; | 623 | #define ACPI_NORMAL_EXEC(a) a; |
601 | 624 | ||
602 | #define ACPI_DEBUG_DEFINE(a) | 625 | #define ACPI_DEBUG_DEFINE(a) do { } while(0) |
603 | #define ACPI_DEBUG_ONLY_MEMBERS(a) | 626 | #define ACPI_DEBUG_ONLY_MEMBERS(a) do { } while(0) |
604 | #define ACPI_FUNCTION_NAME(a) | 627 | #define ACPI_FUNCTION_NAME(a) do { } while(0) |
605 | #define ACPI_FUNCTION_TRACE(a) | 628 | #define ACPI_FUNCTION_TRACE(a) do { } while(0) |
606 | #define ACPI_FUNCTION_TRACE_PTR(a,b) | 629 | #define ACPI_FUNCTION_TRACE_PTR(a,b) do { } while(0) |
607 | #define ACPI_FUNCTION_TRACE_U32(a,b) | 630 | #define ACPI_FUNCTION_TRACE_U32(a,b) do { } while(0) |
608 | #define ACPI_FUNCTION_TRACE_STR(a,b) | 631 | #define ACPI_FUNCTION_TRACE_STR(a,b) do { } while(0) |
609 | #define ACPI_FUNCTION_EXIT | 632 | #define ACPI_FUNCTION_EXIT do { } while(0) |
610 | #define ACPI_FUNCTION_STATUS_EXIT(s) | 633 | #define ACPI_FUNCTION_STATUS_EXIT(s) do { } while(0) |
611 | #define ACPI_FUNCTION_VALUE_EXIT(s) | 634 | #define ACPI_FUNCTION_VALUE_EXIT(s) do { } while(0) |
612 | #define ACPI_FUNCTION_ENTRY() | 635 | #define ACPI_FUNCTION_ENTRY() do { } while(0) |
613 | #define ACPI_DUMP_STACK_ENTRY(a) | 636 | #define ACPI_DUMP_STACK_ENTRY(a) do { } while(0) |
614 | #define ACPI_DUMP_OPERANDS(a,b,c,d,e) | 637 | #define ACPI_DUMP_OPERANDS(a,b,c,d,e) do { } while(0) |
615 | #define ACPI_DUMP_ENTRY(a,b) | 638 | #define ACPI_DUMP_ENTRY(a,b) do { } while(0) |
616 | #define ACPI_DUMP_TABLES(a,b) | 639 | #define ACPI_DUMP_TABLES(a,b) do { } while(0) |
617 | #define ACPI_DUMP_PATHNAME(a,b,c,d) | 640 | #define ACPI_DUMP_PATHNAME(a,b,c,d) do { } while(0) |
618 | #define ACPI_DUMP_RESOURCE_LIST(a) | 641 | #define ACPI_DUMP_RESOURCE_LIST(a) do { } while(0) |
619 | #define ACPI_DUMP_BUFFER(a,b) | 642 | #define ACPI_DUMP_BUFFER(a,b) do { } while(0) |
620 | #define ACPI_DEBUG_PRINT(pl) | 643 | #define ACPI_DEBUG_PRINT(pl) do { } while(0) |
621 | #define ACPI_DEBUG_PRINT_RAW(pl) | 644 | #define ACPI_DEBUG_PRINT_RAW(pl) do { } while(0) |
622 | 645 | ||
623 | #define return_VOID return | 646 | #define return_VOID return |
624 | #define return_ACPI_STATUS(s) return(s) | 647 | #define return_ACPI_STATUS(s) return(s) |
diff --git a/include/acpi/acoutput.h b/include/acpi/acoutput.h index 7812267b577f..c090a8b0bc99 100644 --- a/include/acpi/acoutput.h +++ b/include/acpi/acoutput.h | |||
@@ -178,8 +178,8 @@ | |||
178 | 178 | ||
179 | /* Defaults for debug_level, debug and normal */ | 179 | /* Defaults for debug_level, debug and normal */ |
180 | 180 | ||
181 | #define ACPI_DEBUG_DEFAULT (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR | ACPI_LV_DEBUG_OBJECT) | 181 | #define ACPI_DEBUG_DEFAULT (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR) |
182 | #define ACPI_NORMAL_DEFAULT (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR | ACPI_LV_DEBUG_OBJECT) | 182 | #define ACPI_NORMAL_DEFAULT (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR) |
183 | #define ACPI_DEBUG_ALL (ACPI_LV_AML_DISASSEMBLE | ACPI_LV_ALL_EXCEPTIONS | ACPI_LV_ALL) | 183 | #define ACPI_DEBUG_ALL (ACPI_LV_AML_DISASSEMBLE | ACPI_LV_ALL_EXCEPTIONS | ACPI_LV_ALL) |
184 | 184 | ||
185 | #endif /* __ACOUTPUT_H__ */ | 185 | #endif /* __ACOUTPUT_H__ */ |
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 529d03554c7a..a9f73efa01bc 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
@@ -321,7 +321,8 @@ struct acpi_bus_event { | |||
321 | }; | 321 | }; |
322 | 322 | ||
323 | extern struct kset acpi_subsys; | 323 | extern struct kset acpi_subsys; |
324 | 324 | extern int acpi_bus_generate_genetlink_event(struct acpi_device *device, | |
325 | u8 type, int data); | ||
325 | /* | 326 | /* |
326 | * External Functions | 327 | * External Functions |
327 | */ | 328 | */ |
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h index 553515912c0b..07b5d76b92cc 100644 --- a/include/acpi/acpi_drivers.h +++ b/include/acpi/acpi_drivers.h | |||
@@ -142,10 +142,6 @@ static inline void unregister_hotplug_dock_device(acpi_handle handle) | |||
142 | /*-------------------------------------------------------------------------- | 142 | /*-------------------------------------------------------------------------- |
143 | Suspend/Resume | 143 | Suspend/Resume |
144 | -------------------------------------------------------------------------- */ | 144 | -------------------------------------------------------------------------- */ |
145 | #ifdef CONFIG_ACPI_SLEEP | ||
146 | extern int acpi_sleep_init(void); | 145 | extern int acpi_sleep_init(void); |
147 | #else | ||
148 | #define acpi_sleep_init() do {} while (0) | ||
149 | #endif | ||
150 | 146 | ||
151 | #endif /*__ACPI_DRIVERS_H__*/ | 147 | #endif /*__ACPI_DRIVERS_H__*/ |
diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h index dab2ec59a3b0..c785485e62a6 100644 --- a/include/acpi/platform/acenv.h +++ b/include/acpi/platform/acenv.h | |||
@@ -136,7 +136,7 @@ | |||
136 | 136 | ||
137 | /*! [Begin] no source code translation */ | 137 | /*! [Begin] no source code translation */ |
138 | 138 | ||
139 | #if defined(__linux__) | 139 | #if defined(_LINUX) || defined(__linux__) |
140 | #include "aclinux.h" | 140 | #include "aclinux.h" |
141 | 141 | ||
142 | #elif defined(_AED_EFI) | 142 | #elif defined(_AED_EFI) |
diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h index a568717f98c6..6ed15a0978eb 100644 --- a/include/acpi/platform/aclinux.h +++ b/include/acpi/platform/aclinux.h | |||
@@ -91,7 +91,10 @@ | |||
91 | #define ACPI_USE_NATIVE_DIVIDE | 91 | #define ACPI_USE_NATIVE_DIVIDE |
92 | #endif | 92 | #endif |
93 | 93 | ||
94 | #ifndef __cdecl | ||
94 | #define __cdecl | 95 | #define __cdecl |
96 | #endif | ||
97 | |||
95 | #define ACPI_FLUSH_CPU_CACHE() | 98 | #define ACPI_FLUSH_CPU_CACHE() |
96 | #endif /* __KERNEL__ */ | 99 | #endif /* __KERNEL__ */ |
97 | 100 | ||
diff --git a/include/acpi/processor.h b/include/acpi/processor.h index b4b0ffdab098..f9f987f8e661 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h | |||
@@ -21,6 +21,8 @@ | |||
21 | #define ACPI_PSD_REV0_REVISION 0 /* Support for _PSD as in ACPI 3.0 */ | 21 | #define ACPI_PSD_REV0_REVISION 0 /* Support for _PSD as in ACPI 3.0 */ |
22 | #define ACPI_PSD_REV0_ENTRIES 5 | 22 | #define ACPI_PSD_REV0_ENTRIES 5 |
23 | 23 | ||
24 | #define ACPI_TSD_REV0_REVISION 0 /* Support for _PSD as in ACPI 3.0 */ | ||
25 | #define ACPI_TSD_REV0_ENTRIES 5 | ||
24 | /* | 26 | /* |
25 | * Types of coordination defined in ACPI 3.0. Same macros can be used across | 27 | * Types of coordination defined in ACPI 3.0. Same macros can be used across |
26 | * P, C and T states | 28 | * P, C and T states |
@@ -125,17 +127,53 @@ struct acpi_processor_performance { | |||
125 | 127 | ||
126 | /* Throttling Control */ | 128 | /* Throttling Control */ |
127 | 129 | ||
130 | struct acpi_tsd_package { | ||
131 | acpi_integer num_entries; | ||
132 | acpi_integer revision; | ||
133 | acpi_integer domain; | ||
134 | acpi_integer coord_type; | ||
135 | acpi_integer num_processors; | ||
136 | } __attribute__ ((packed)); | ||
137 | |||
138 | struct acpi_ptc_register { | ||
139 | u8 descriptor; | ||
140 | u16 length; | ||
141 | u8 space_id; | ||
142 | u8 bit_width; | ||
143 | u8 bit_offset; | ||
144 | u8 reserved; | ||
145 | u64 address; | ||
146 | } __attribute__ ((packed)); | ||
147 | |||
148 | struct acpi_processor_tx_tss { | ||
149 | acpi_integer freqpercentage; /* */ | ||
150 | acpi_integer power; /* milliWatts */ | ||
151 | acpi_integer transition_latency; /* microseconds */ | ||
152 | acpi_integer control; /* control value */ | ||
153 | acpi_integer status; /* success indicator */ | ||
154 | }; | ||
128 | struct acpi_processor_tx { | 155 | struct acpi_processor_tx { |
129 | u16 power; | 156 | u16 power; |
130 | u16 performance; | 157 | u16 performance; |
131 | }; | 158 | }; |
132 | 159 | ||
160 | struct acpi_processor; | ||
133 | struct acpi_processor_throttling { | 161 | struct acpi_processor_throttling { |
134 | int state; | 162 | unsigned int state; |
163 | unsigned int platform_limit; | ||
164 | struct acpi_pct_register control_register; | ||
165 | struct acpi_pct_register status_register; | ||
166 | unsigned int state_count; | ||
167 | struct acpi_processor_tx_tss *states_tss; | ||
168 | struct acpi_tsd_package domain_info; | ||
169 | cpumask_t shared_cpu_map; | ||
170 | int (*acpi_processor_get_throttling) (struct acpi_processor * pr); | ||
171 | int (*acpi_processor_set_throttling) (struct acpi_processor * pr, | ||
172 | int state); | ||
173 | |||
135 | u32 address; | 174 | u32 address; |
136 | u8 duty_offset; | 175 | u8 duty_offset; |
137 | u8 duty_width; | 176 | u8 duty_width; |
138 | int state_count; | ||
139 | struct acpi_processor_tx states[ACPI_PROCESSOR_MAX_THROTTLING]; | 177 | struct acpi_processor_tx states[ACPI_PROCESSOR_MAX_THROTTLING]; |
140 | }; | 178 | }; |
141 | 179 | ||
@@ -169,6 +207,9 @@ struct acpi_processor { | |||
169 | u32 id; | 207 | u32 id; |
170 | u32 pblk; | 208 | u32 pblk; |
171 | int performance_platform_limit; | 209 | int performance_platform_limit; |
210 | int throttling_platform_limit; | ||
211 | /* 0 - states 0..n-th state available */ | ||
212 | |||
172 | struct acpi_processor_flags flags; | 213 | struct acpi_processor_flags flags; |
173 | struct acpi_processor_power power; | 214 | struct acpi_processor_power power; |
174 | struct acpi_processor_performance *performance; | 215 | struct acpi_processor_performance *performance; |
@@ -270,7 +311,7 @@ static inline int acpi_processor_ppc_has_changed(struct acpi_processor *pr) | |||
270 | 311 | ||
271 | /* in processor_throttling.c */ | 312 | /* in processor_throttling.c */ |
272 | int acpi_processor_get_throttling_info(struct acpi_processor *pr); | 313 | int acpi_processor_get_throttling_info(struct acpi_processor *pr); |
273 | int acpi_processor_set_throttling(struct acpi_processor *pr, int state); | 314 | extern int acpi_processor_set_throttling(struct acpi_processor *pr, int state); |
274 | extern struct file_operations acpi_processor_throttling_fops; | 315 | extern struct file_operations acpi_processor_throttling_fops; |
275 | 316 | ||
276 | /* in processor_idle.c */ | 317 | /* in processor_idle.c */ |
diff --git a/include/asm-alpha/irq.h b/include/asm-alpha/irq.h index 917b9fe372cf..06377400dc09 100644 --- a/include/asm-alpha/irq.h +++ b/include/asm-alpha/irq.h | |||
@@ -85,10 +85,6 @@ static __inline__ int irq_canonicalize(int irq) | |||
85 | return ((irq == 2) ? 9 : irq); | 85 | return ((irq == 2) ? 9 : irq); |
86 | } | 86 | } |
87 | 87 | ||
88 | extern void disable_irq(unsigned int); | ||
89 | extern void disable_irq_nosync(unsigned int); | ||
90 | extern void enable_irq(unsigned int); | ||
91 | |||
92 | struct pt_regs; | 88 | struct pt_regs; |
93 | extern void (*perf_irq)(unsigned long, struct pt_regs *); | 89 | extern void (*perf_irq)(unsigned long, struct pt_regs *); |
94 | 90 | ||
diff --git a/include/asm-arm/arch-at91/at91_mci.h b/include/asm-arm/arch-at91/at91_mci.h index 40a9876b661a..c2e11cc374ba 100644 --- a/include/asm-arm/arch-at91/at91_mci.h +++ b/include/asm-arm/arch-at91/at91_mci.h | |||
@@ -26,6 +26,9 @@ | |||
26 | #define AT91_MCI_MR 0x04 /* Mode Register */ | 26 | #define AT91_MCI_MR 0x04 /* Mode Register */ |
27 | #define AT91_MCI_CLKDIV (0xff << 0) /* Clock Divider */ | 27 | #define AT91_MCI_CLKDIV (0xff << 0) /* Clock Divider */ |
28 | #define AT91_MCI_PWSDIV (7 << 8) /* Power Saving Divider */ | 28 | #define AT91_MCI_PWSDIV (7 << 8) /* Power Saving Divider */ |
29 | #define AT91_MCI_RDPROOF (1 << 11) /* Read Proof Enable [SAM926[03] only] */ | ||
30 | #define AT91_MCI_WRPROOF (1 << 12) /* Write Proof Enable [SAM926[03] only] */ | ||
31 | #define AT91_MCI_PDCFBYTE (1 << 13) /* PDC Force Byte Transfer [SAM926[03] only] */ | ||
29 | #define AT91_MCI_PDCPADV (1 << 14) /* PDC Padding Value */ | 32 | #define AT91_MCI_PDCPADV (1 << 14) /* PDC Padding Value */ |
30 | #define AT91_MCI_PDCMODE (1 << 15) /* PDC-orientated Mode */ | 33 | #define AT91_MCI_PDCMODE (1 << 15) /* PDC-orientated Mode */ |
31 | #define AT91_MCI_BLKLEN (0xfff << 18) /* Data Block Length */ | 34 | #define AT91_MCI_BLKLEN (0xfff << 18) /* Data Block Length */ |
diff --git a/include/asm-arm/arch-iop13xx/iop13xx.h b/include/asm-arm/arch-iop13xx/iop13xx.h index d4e4f828577c..52b7fab7ef60 100644 --- a/include/asm-arm/arch-iop13xx/iop13xx.h +++ b/include/asm-arm/arch-iop13xx/iop13xx.h | |||
@@ -19,6 +19,39 @@ static inline int iop13xx_cpu_id(void) | |||
19 | return id; | 19 | return id; |
20 | } | 20 | } |
21 | 21 | ||
22 | /* WDTCR CP6 R7 Page 9 */ | ||
23 | static inline u32 read_wdtcr(void) | ||
24 | { | ||
25 | u32 val; | ||
26 | asm volatile("mrc p6, 0, %0, c7, c9, 0":"=r" (val)); | ||
27 | return val; | ||
28 | } | ||
29 | static inline void write_wdtcr(u32 val) | ||
30 | { | ||
31 | asm volatile("mcr p6, 0, %0, c7, c9, 0"::"r" (val)); | ||
32 | } | ||
33 | |||
34 | /* WDTSR CP6 R8 Page 9 */ | ||
35 | static inline u32 read_wdtsr(void) | ||
36 | { | ||
37 | u32 val; | ||
38 | asm volatile("mrc p6, 0, %0, c8, c9, 0":"=r" (val)); | ||
39 | return val; | ||
40 | } | ||
41 | static inline void write_wdtsr(u32 val) | ||
42 | { | ||
43 | asm volatile("mcr p6, 0, %0, c8, c9, 0"::"r" (val)); | ||
44 | } | ||
45 | |||
46 | /* RCSR - Reset Cause Status Register */ | ||
47 | static inline u32 read_rcsr(void) | ||
48 | { | ||
49 | u32 val; | ||
50 | asm volatile("mrc p6, 0, %0, c0, c1, 0":"=r" (val)); | ||
51 | return val; | ||
52 | } | ||
53 | |||
54 | extern unsigned long get_iop_tick_rate(void); | ||
22 | #endif | 55 | #endif |
23 | 56 | ||
24 | /* | 57 | /* |
@@ -480,4 +513,14 @@ static inline int iop13xx_cpu_id(void) | |||
480 | #define IOP13XX_PBI_LR1 IOP13XX_PBI_OFFSET(0x14) | 513 | #define IOP13XX_PBI_LR1 IOP13XX_PBI_OFFSET(0x14) |
481 | 514 | ||
482 | #define IOP13XX_PROCESSOR_FREQ IOP13XX_REG_ADDR32(0x2180) | 515 | #define IOP13XX_PROCESSOR_FREQ IOP13XX_REG_ADDR32(0x2180) |
516 | |||
517 | /* Watchdog timer definitions */ | ||
518 | #define IOP_WDTCR_EN_ARM 0x1e1e1e1e | ||
519 | #define IOP_WDTCR_EN 0xe1e1e1e1 | ||
520 | #define IOP_WDTCR_DIS_ARM 0x1f1f1f1f | ||
521 | #define IOP_WDTCR_DIS 0xf1f1f1f1 | ||
522 | #define IOP_RCSR_WDT (1 << 5) /* reset caused by watchdog timer */ | ||
523 | #define IOP13XX_WDTSR_WRITE_EN (1 << 31) /* used to speed up reset requests */ | ||
524 | #define IOP13XX_WDTCR_IB_RESET (1 << 0) | ||
525 | |||
483 | #endif /* _IOP13XX_HW_H_ */ | 526 | #endif /* _IOP13XX_HW_H_ */ |
diff --git a/include/asm-arm/arch-iop13xx/system.h b/include/asm-arm/arch-iop13xx/system.h index 127827058e1f..8575af8db78c 100644 --- a/include/asm-arm/arch-iop13xx/system.h +++ b/include/asm-arm/arch-iop13xx/system.h | |||
@@ -13,43 +13,13 @@ static inline void arch_idle(void) | |||
13 | cpu_do_idle(); | 13 | cpu_do_idle(); |
14 | } | 14 | } |
15 | 15 | ||
16 | /* WDTCR CP6 R7 Page 9 */ | ||
17 | static inline u32 read_wdtcr(void) | ||
18 | { | ||
19 | u32 val; | ||
20 | asm volatile("mrc p6, 0, %0, c7, c9, 0":"=r" (val)); | ||
21 | return val; | ||
22 | } | ||
23 | static inline void write_wdtcr(u32 val) | ||
24 | { | ||
25 | asm volatile("mcr p6, 0, %0, c7, c9, 0"::"r" (val)); | ||
26 | } | ||
27 | |||
28 | /* WDTSR CP6 R8 Page 9 */ | ||
29 | static inline u32 read_wdtsr(void) | ||
30 | { | ||
31 | u32 val; | ||
32 | asm volatile("mrc p6, 0, %0, c8, c9, 0":"=r" (val)); | ||
33 | return val; | ||
34 | } | ||
35 | static inline void write_wdtsr(u32 val) | ||
36 | { | ||
37 | asm volatile("mcr p6, 0, %0, c8, c9, 0"::"r" (val)); | ||
38 | } | ||
39 | |||
40 | #define IOP13XX_WDTCR_EN_ARM 0x1e1e1e1e | ||
41 | #define IOP13XX_WDTCR_EN 0xe1e1e1e1 | ||
42 | #define IOP13XX_WDTCR_DIS_ARM 0x1f1f1f1f | ||
43 | #define IOP13XX_WDTCR_DIS 0xf1f1f1f1 | ||
44 | #define IOP13XX_WDTSR_WRITE_EN (1 << 31) | ||
45 | #define IOP13XX_WDTCR_IB_RESET (1 << 0) | ||
46 | static inline void arch_reset(char mode) | 16 | static inline void arch_reset(char mode) |
47 | { | 17 | { |
48 | /* | 18 | /* |
49 | * Reset the internal bus (warning both cores are reset) | 19 | * Reset the internal bus (warning both cores are reset) |
50 | */ | 20 | */ |
51 | write_wdtcr(IOP13XX_WDTCR_EN_ARM); | 21 | write_wdtcr(IOP_WDTCR_EN_ARM); |
52 | write_wdtcr(IOP13XX_WDTCR_EN); | 22 | write_wdtcr(IOP_WDTCR_EN); |
53 | write_wdtsr(IOP13XX_WDTSR_WRITE_EN | IOP13XX_WDTCR_IB_RESET); | 23 | write_wdtsr(IOP13XX_WDTSR_WRITE_EN | IOP13XX_WDTCR_IB_RESET); |
54 | write_wdtcr(0x1000); | 24 | write_wdtcr(0x1000); |
55 | 25 | ||
diff --git a/include/asm-arm/arch-iop13xx/uncompress.h b/include/asm-arm/arch-iop13xx/uncompress.h index b9525d59b7ad..dd9c2934190e 100644 --- a/include/asm-arm/arch-iop13xx/uncompress.h +++ b/include/asm-arm/arch-iop13xx/uncompress.h | |||
@@ -1,7 +1,6 @@ | |||
1 | #include <asm/types.h> | 1 | #include <asm/types.h> |
2 | #include <linux/serial_reg.h> | 2 | #include <linux/serial_reg.h> |
3 | #include <asm/hardware.h> | 3 | #include <asm/hardware.h> |
4 | #include <asm/processor.h> | ||
5 | 4 | ||
6 | #define UART_BASE ((volatile u32 *)IOP13XX_UART1_PHYS) | 5 | #define UART_BASE ((volatile u32 *)IOP13XX_UART1_PHYS) |
7 | #define TX_DONE (UART_LSR_TEMT | UART_LSR_THRE) | 6 | #define TX_DONE (UART_LSR_TEMT | UART_LSR_THRE) |
@@ -9,7 +8,7 @@ | |||
9 | static inline void putc(char c) | 8 | static inline void putc(char c) |
10 | { | 9 | { |
11 | while ((UART_BASE[UART_LSR] & TX_DONE) != TX_DONE) | 10 | while ((UART_BASE[UART_LSR] & TX_DONE) != TX_DONE) |
12 | cpu_relax(); | 11 | barrier(); |
13 | UART_BASE[UART_TX] = c; | 12 | UART_BASE[UART_TX] = c; |
14 | } | 13 | } |
15 | 14 | ||
diff --git a/include/asm-arm/arch-iop32x/uncompress.h b/include/asm-arm/arch-iop32x/uncompress.h index e64f52bf2bce..070f15818fe7 100644 --- a/include/asm-arm/arch-iop32x/uncompress.h +++ b/include/asm-arm/arch-iop32x/uncompress.h | |||
@@ -26,7 +26,7 @@ static __inline__ void __arch_decomp_setup(unsigned long arch_id) | |||
26 | { | 26 | { |
27 | if (machine_is_iq80321()) | 27 | if (machine_is_iq80321()) |
28 | uart_base = (volatile u8 *)IQ80321_UART; | 28 | uart_base = (volatile u8 *)IQ80321_UART; |
29 | else if (machine_is_iq31244()) | 29 | else if (machine_is_iq31244() || machine_is_em7210()) |
30 | uart_base = (volatile u8 *)IQ31244_UART; | 30 | uart_base = (volatile u8 *)IQ31244_UART; |
31 | else | 31 | else |
32 | uart_base = (volatile u8 *)0xfe800000; | 32 | uart_base = (volatile u8 *)0xfe800000; |
diff --git a/include/asm-arm/arch-mxc/board-mx31ads.h b/include/asm-arm/arch-mxc/board-mx31ads.h new file mode 100644 index 000000000000..be29b83ad4ae --- /dev/null +++ b/include/asm-arm/arch-mxc/board-mx31ads.h | |||
@@ -0,0 +1,142 @@ | |||
1 | /* | ||
2 | * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | */ | ||
4 | |||
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 version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #ifndef __ASM_ARCH_MXC_BOARD_MX31ADS_H__ | ||
12 | #define __ASM_ARCH_MXC_BOARD_MX31ADS_H__ | ||
13 | |||
14 | /*! | ||
15 | * @name PBC Controller parameters | ||
16 | */ | ||
17 | /*! @{ */ | ||
18 | /*! | ||
19 | * Base address of PBC controller | ||
20 | */ | ||
21 | #define PBC_BASE_ADDRESS IO_ADDRESS(CS4_BASE_ADDR) | ||
22 | /* Offsets for the PBC Controller register */ | ||
23 | /*! | ||
24 | * PBC Board status register offset | ||
25 | */ | ||
26 | #define PBC_BSTAT 0x000002 | ||
27 | /*! | ||
28 | * PBC Board control register 1 set address. | ||
29 | */ | ||
30 | #define PBC_BCTRL1_SET 0x000004 | ||
31 | /*! | ||
32 | * PBC Board control register 1 clear address. | ||
33 | */ | ||
34 | #define PBC_BCTRL1_CLEAR 0x000006 | ||
35 | /*! | ||
36 | * PBC Board control register 2 set address. | ||
37 | */ | ||
38 | #define PBC_BCTRL2_SET 0x000008 | ||
39 | /*! | ||
40 | * PBC Board control register 2 clear address. | ||
41 | */ | ||
42 | #define PBC_BCTRL2_CLEAR 0x00000A | ||
43 | /*! | ||
44 | * PBC Board control register 3 set address. | ||
45 | */ | ||
46 | #define PBC_BCTRL3_SET 0x00000C | ||
47 | /*! | ||
48 | * PBC Board control register 3 clear address. | ||
49 | */ | ||
50 | #define PBC_BCTRL3_CLEAR 0x00000E | ||
51 | /*! | ||
52 | * PBC Board control register 4 set address. | ||
53 | */ | ||
54 | #define PBC_BCTRL4_SET 0x000010 | ||
55 | /*! | ||
56 | * PBC Board control register 4 clear address. | ||
57 | */ | ||
58 | #define PBC_BCTRL4_CLEAR 0x000012 | ||
59 | /*! | ||
60 | * PBC Board status register 1. | ||
61 | */ | ||
62 | #define PBC_BSTAT1 0x000014 | ||
63 | /*! | ||
64 | * PBC Board interrupt status register. | ||
65 | */ | ||
66 | #define PBC_INTSTATUS 0x000016 | ||
67 | /*! | ||
68 | * PBC Board interrupt current status register. | ||
69 | */ | ||
70 | #define PBC_INTCURR_STATUS 0x000018 | ||
71 | /*! | ||
72 | * PBC Interrupt mask register set address. | ||
73 | */ | ||
74 | #define PBC_INTMASK_SET 0x00001A | ||
75 | /*! | ||
76 | * PBC Interrupt mask register clear address. | ||
77 | */ | ||
78 | #define PBC_INTMASK_CLEAR 0x00001C | ||
79 | |||
80 | /*! | ||
81 | * External UART A. | ||
82 | */ | ||
83 | #define PBC_SC16C652_UARTA 0x010000 | ||
84 | /*! | ||
85 | * External UART B. | ||
86 | */ | ||
87 | #define PBC_SC16C652_UARTB 0x010010 | ||
88 | /*! | ||
89 | * Ethernet Controller IO base address. | ||
90 | */ | ||
91 | #define PBC_CS8900A_IOBASE 0x020000 | ||
92 | /*! | ||
93 | * Ethernet Controller Memory base address. | ||
94 | */ | ||
95 | #define PBC_CS8900A_MEMBASE 0x021000 | ||
96 | /*! | ||
97 | * Ethernet Controller DMA base address. | ||
98 | */ | ||
99 | #define PBC_CS8900A_DMABASE 0x022000 | ||
100 | /*! | ||
101 | * External chip select 0. | ||
102 | */ | ||
103 | #define PBC_XCS0 0x040000 | ||
104 | /*! | ||
105 | * LCD Display enable. | ||
106 | */ | ||
107 | #define PBC_LCD_EN_B 0x060000 | ||
108 | /*! | ||
109 | * Code test debug enable. | ||
110 | */ | ||
111 | #define PBC_CODE_B 0x070000 | ||
112 | /*! | ||
113 | * PSRAM memory select. | ||
114 | */ | ||
115 | #define PBC_PSRAM_B 0x5000000 | ||
116 | |||
117 | #define PBC_INTSTATUS_REG (PBC_INTSTATUS + PBC_BASE_ADDRESS) | ||
118 | #define PBC_INTCURR_STATUS_REG (PBC_INTCURR_STATUS + PBC_BASE_ADDRESS) | ||
119 | #define PBC_INTMASK_SET_REG (PBC_INTMASK_SET + PBC_BASE_ADDRESS) | ||
120 | #define PBC_INTMASK_CLEAR_REG (PBC_INTMASK_CLEAR + PBC_BASE_ADDRESS) | ||
121 | #define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_4) | ||
122 | |||
123 | #define EXPIO_INT_LOW_BAT (MXC_EXP_IO_BASE + 0) | ||
124 | #define EXPIO_INT_PB_IRQ (MXC_EXP_IO_BASE + 1) | ||
125 | #define EXPIO_INT_OTG_FS_OVR (MXC_EXP_IO_BASE + 2) | ||
126 | #define EXPIO_INT_FSH_OVR (MXC_EXP_IO_BASE + 3) | ||
127 | #define EXPIO_INT_RES4 (MXC_EXP_IO_BASE + 4) | ||
128 | #define EXPIO_INT_RES5 (MXC_EXP_IO_BASE + 5) | ||
129 | #define EXPIO_INT_RES6 (MXC_EXP_IO_BASE + 6) | ||
130 | #define EXPIO_INT_RES7 (MXC_EXP_IO_BASE + 7) | ||
131 | #define EXPIO_INT_ENET_INT (MXC_EXP_IO_BASE + 8) | ||
132 | #define EXPIO_INT_OTG_FS_INT (MXC_EXP_IO_BASE + 9) | ||
133 | #define EXPIO_INT_XUART_INTA (MXC_EXP_IO_BASE + 10) | ||
134 | #define EXPIO_INT_XUART_INTB (MXC_EXP_IO_BASE + 11) | ||
135 | #define EXPIO_INT_SYNTH_IRQ (MXC_EXP_IO_BASE + 12) | ||
136 | #define EXPIO_INT_CE_INT1 (MXC_EXP_IO_BASE + 13) | ||
137 | #define EXPIO_INT_CE_INT2 (MXC_EXP_IO_BASE + 14) | ||
138 | #define EXPIO_INT_RES15 (MXC_EXP_IO_BASE + 15) | ||
139 | |||
140 | #define MXC_MAX_EXP_IO_LINES 16 | ||
141 | |||
142 | #endif /* __ASM_ARCH_MXC_BOARD_MX31ADS_H__ */ | ||
diff --git a/include/asm-arm/arch-mxc/common.h b/include/asm-arm/arch-mxc/common.h new file mode 100644 index 000000000000..23b4350edbd6 --- /dev/null +++ b/include/asm-arm/arch-mxc/common.h | |||
@@ -0,0 +1,20 @@ | |||
1 | /* | ||
2 | * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | */ | ||
4 | |||
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 version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #ifndef __ASM_ARCH_MXC_COMMON_H__ | ||
12 | #define __ASM_ARCH_MXC_COMMON_H__ | ||
13 | |||
14 | struct sys_timer; | ||
15 | |||
16 | extern void mxc_map_io(void); | ||
17 | extern void mxc_init_irq(void); | ||
18 | extern struct sys_timer mxc_timer; | ||
19 | |||
20 | #endif | ||
diff --git a/include/asm-arm/arch-mxc/dma.h b/include/asm-arm/arch-mxc/dma.h new file mode 100644 index 000000000000..65e639d51d2b --- /dev/null +++ b/include/asm-arm/arch-mxc/dma.h | |||
@@ -0,0 +1,21 @@ | |||
1 | /* | ||
2 | * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | */ | ||
4 | |||
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 version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #ifndef __ASM_ARCH_MXC_DMA_H__ | ||
12 | #define __ASM_ARCH_MXC_DMA_H__ | ||
13 | |||
14 | /*! | ||
15 | * @file dma.h | ||
16 | * @brief This file contains Unified DMA API for all MXC platforms. | ||
17 | * The API is platform independent. | ||
18 | * | ||
19 | * @ingroup SDMA | ||
20 | */ | ||
21 | #endif | ||
diff --git a/include/asm-arm/arch-mxc/entry-macro.S b/include/asm-arm/arch-mxc/entry-macro.S new file mode 100644 index 000000000000..b542433afb1b --- /dev/null +++ b/include/asm-arm/arch-mxc/entry-macro.S | |||
@@ -0,0 +1,39 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007 Lennert Buytenhek <buytenh@wantstofly.org> | ||
3 | * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
4 | */ | ||
5 | |||
6 | /* | ||
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 | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | @ this macro disables fast irq (not implemented) | ||
13 | .macro disable_fiq | ||
14 | .endm | ||
15 | |||
16 | .macro get_irqnr_preamble, base, tmp | ||
17 | .endm | ||
18 | |||
19 | .macro arch_ret_to_user, tmp1, tmp2 | ||
20 | .endm | ||
21 | |||
22 | @ this macro checks which interrupt occured | ||
23 | @ and returns its number in irqnr | ||
24 | @ and returns if an interrupt occured in irqstat | ||
25 | .macro get_irqnr_and_base, irqnr, irqstat, base, tmp | ||
26 | ldr \base, =AVIC_IO_ADDRESS(AVIC_BASE_ADDR) | ||
27 | @ Load offset & priority of the highest priority | ||
28 | @ interrupt pending from AVIC_NIVECSR | ||
29 | ldr \irqstat, [\base, #0x40] | ||
30 | @ Shift to get the decoded IRQ number, using ASR so | ||
31 | @ 'no interrupt pending' becomes 0xffffffff | ||
32 | mov \irqnr, \irqstat, asr #16 | ||
33 | @ set zero flag if IRQ + 1 == 0 | ||
34 | adds \tmp, \irqnr, #1 | ||
35 | .endm | ||
36 | |||
37 | @ irq priority table (not used) | ||
38 | .macro irq_prio_table | ||
39 | .endm | ||
diff --git a/include/asm-arm/arch-mxc/hardware.h b/include/asm-arm/arch-mxc/hardware.h new file mode 100644 index 000000000000..3c09b92fef0d --- /dev/null +++ b/include/asm-arm/arch-mxc/hardware.h | |||
@@ -0,0 +1,52 @@ | |||
1 | /* | ||
2 | * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | */ | ||
4 | |||
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 version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | /*! | ||
12 | * @file hardware.h | ||
13 | * @brief This file contains the hardware definitions of the board. | ||
14 | * | ||
15 | * @ingroup System | ||
16 | */ | ||
17 | #ifndef __ASM_ARCH_MXC_HARDWARE_H__ | ||
18 | #define __ASM_ARCH_MXC_HARDWARE_H__ | ||
19 | |||
20 | #include <asm/sizes.h> | ||
21 | |||
22 | #include <asm/arch/mx31.h> | ||
23 | |||
24 | #include <asm/arch/mxc.h> | ||
25 | |||
26 | #define MXC_MAX_GPIO_LINES (GPIO_NUM_PIN * GPIO_PORT_NUM) | ||
27 | |||
28 | /* | ||
29 | * --------------------------------------------------------------------------- | ||
30 | * Board specific defines | ||
31 | * --------------------------------------------------------------------------- | ||
32 | */ | ||
33 | #define MXC_EXP_IO_BASE (MXC_GPIO_INT_BASE + MXC_MAX_GPIO_LINES) | ||
34 | |||
35 | #include <asm/arch/board-mx31ads.h> | ||
36 | |||
37 | #ifndef MXC_MAX_EXP_IO_LINES | ||
38 | #define MXC_MAX_EXP_IO_LINES 0 | ||
39 | #endif | ||
40 | |||
41 | #define MXC_MAX_VIRTUAL_INTS 16 | ||
42 | #define MXC_VIRTUAL_INTS_BASE (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES) | ||
43 | #define MXC_SDIO1_CARD_IRQ MXC_VIRTUAL_INTS_BASE | ||
44 | #define MXC_SDIO2_CARD_IRQ (MXC_VIRTUAL_INTS_BASE + 1) | ||
45 | #define MXC_SDIO3_CARD_IRQ (MXC_VIRTUAL_INTS_BASE + 2) | ||
46 | |||
47 | #define MXC_MAX_INTS (MXC_MAX_INT_LINES + \ | ||
48 | MXC_MAX_GPIO_LINES + \ | ||
49 | MXC_MAX_EXP_IO_LINES + \ | ||
50 | MXC_MAX_VIRTUAL_INTS) | ||
51 | |||
52 | #endif /* __ASM_ARCH_MXC_HARDWARE_H__ */ | ||
diff --git a/include/asm-arm/arch-mxc/io.h b/include/asm-arm/arch-mxc/io.h new file mode 100644 index 000000000000..cf6c83a4b9f7 --- /dev/null +++ b/include/asm-arm/arch-mxc/io.h | |||
@@ -0,0 +1,33 @@ | |||
1 | /* | ||
2 | * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | */ | ||
4 | |||
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 version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | /*! | ||
12 | * @file io.h | ||
13 | * @brief This file contains some memory mapping macros. | ||
14 | * @note There is no real ISA or PCI buses. But have to define these macros | ||
15 | * for some drivers to compile. | ||
16 | * | ||
17 | * @ingroup System | ||
18 | */ | ||
19 | |||
20 | #ifndef __ASM_ARCH_MXC_IO_H__ | ||
21 | #define __ASM_ARCH_MXC_IO_H__ | ||
22 | |||
23 | /*! Allow IO space to be anywhere in the memory */ | ||
24 | #define IO_SPACE_LIMIT 0xffffffff | ||
25 | |||
26 | /*! | ||
27 | * io address mapping macro | ||
28 | */ | ||
29 | #define __io(a) ((void __iomem *)(a)) | ||
30 | |||
31 | #define __mem_pci(a) (a) | ||
32 | |||
33 | #endif | ||
diff --git a/include/asm-arm/arch-mxc/irqs.h b/include/asm-arm/arch-mxc/irqs.h new file mode 100644 index 000000000000..e4686c6bc4bf --- /dev/null +++ b/include/asm-arm/arch-mxc/irqs.h | |||
@@ -0,0 +1,38 @@ | |||
1 | /* | ||
2 | * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | */ | ||
4 | |||
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 version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #ifndef __ASM_ARCH_MXC_IRQS_H__ | ||
12 | #define __ASM_ARCH_MXC_IRQS_H__ | ||
13 | |||
14 | #include <asm/hardware.h> | ||
15 | |||
16 | /*! | ||
17 | * @file irqs.h | ||
18 | * @brief This file defines the number of normal interrupts and fast interrupts | ||
19 | * | ||
20 | * @ingroup Interrupt | ||
21 | */ | ||
22 | |||
23 | #define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_EXP_IO_BASE) | ||
24 | |||
25 | #define MXC_IRQ_TO_GPIO(irq) ((irq) - MXC_GPIO_INT_BASE) | ||
26 | #define MXC_GPIO_TO_IRQ(x) (MXC_GPIO_INT_BASE + x) | ||
27 | |||
28 | /*! | ||
29 | * Number of normal interrupts | ||
30 | */ | ||
31 | #define NR_IRQS MXC_MAX_INTS | ||
32 | |||
33 | /*! | ||
34 | * Number of fast interrupts | ||
35 | */ | ||
36 | #define NR_FIQS MXC_MAX_INTS | ||
37 | |||
38 | #endif /* __ASM_ARCH_MXC_IRQS_H__ */ | ||
diff --git a/include/asm-arm/arch-mxc/memory.h b/include/asm-arm/arch-mxc/memory.h new file mode 100644 index 000000000000..c89aac83a407 --- /dev/null +++ b/include/asm-arm/arch-mxc/memory.h | |||
@@ -0,0 +1,36 @@ | |||
1 | /* | ||
2 | * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | */ | ||
4 | |||
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 version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #ifndef __ASM_ARCH_MXC_MEMORY_H__ | ||
12 | #define __ASM_ARCH_MXC_MEMORY_H__ | ||
13 | |||
14 | #include <asm/hardware.h> | ||
15 | |||
16 | /*! | ||
17 | * @file memory.h | ||
18 | * @brief This file contains macros needed by the Linux kernel and drivers. | ||
19 | * | ||
20 | * @ingroup Memory | ||
21 | */ | ||
22 | |||
23 | /*! | ||
24 | * Virtual view <-> DMA view memory address translations | ||
25 | * This macro is used to translate the virtual address to an address | ||
26 | * suitable to be passed to set_dma_addr() | ||
27 | */ | ||
28 | #define __virt_to_bus(a) __virt_to_phys(a) | ||
29 | |||
30 | /*! | ||
31 | * Used to convert an address for DMA operations to an address that the | ||
32 | * kernel can use. | ||
33 | */ | ||
34 | #define __bus_to_virt(a) __phys_to_virt(a) | ||
35 | |||
36 | #endif /* __ASM_ARCH_MXC_MEMORY_H__ */ | ||
diff --git a/include/asm-arm/arch-mxc/mx31.h b/include/asm-arm/arch-mxc/mx31.h new file mode 100644 index 000000000000..85c49c9e5d15 --- /dev/null +++ b/include/asm-arm/arch-mxc/mx31.h | |||
@@ -0,0 +1,335 @@ | |||
1 | /* | ||
2 | * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | */ | ||
4 | |||
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 version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #ifndef __ASM_ARCH_MXC_MX31_H__ | ||
12 | #define __ASM_ARCH_MXC_MX31_H__ | ||
13 | |||
14 | #ifndef __ASM_ARCH_MXC_HARDWARE_H__ | ||
15 | #error "Do not include directly." | ||
16 | #endif | ||
17 | |||
18 | /*! | ||
19 | * defines the hardware clock tick rate | ||
20 | */ | ||
21 | #define CLOCK_TICK_RATE 16625000 | ||
22 | |||
23 | /* | ||
24 | * MX31 memory map: | ||
25 | * | ||
26 | * Virt Phys Size What | ||
27 | * --------------------------------------------------------------------------- | ||
28 | * F8000000 1FFC0000 16K IRAM | ||
29 | * F9000000 30000000 256M L2CC | ||
30 | * FC000000 43F00000 1M AIPS 1 | ||
31 | * FC100000 50000000 1M SPBA | ||
32 | * FC200000 53F00000 1M AIPS 2 | ||
33 | * FC500000 60000000 128M ROMPATCH | ||
34 | * FC400000 68000000 128M AVIC | ||
35 | * 70000000 256M IPU (MAX M2) | ||
36 | * 80000000 256M CSD0 SDRAM/DDR | ||
37 | * 90000000 256M CSD1 SDRAM/DDR | ||
38 | * A0000000 128M CS0 Flash | ||
39 | * A8000000 128M CS1 Flash | ||
40 | * B0000000 32M CS2 | ||
41 | * B2000000 32M CS3 | ||
42 | * F4000000 B4000000 32M CS4 | ||
43 | * B6000000 32M CS5 | ||
44 | * FC320000 B8000000 64K NAND, SDRAM, WEIM, M3IF, EMI controllers | ||
45 | * C0000000 64M PCMCIA/CF | ||
46 | */ | ||
47 | |||
48 | #define CS0_BASE_ADDR 0xA0000000 | ||
49 | #define CS1_BASE_ADDR 0xA8000000 | ||
50 | #define CS2_BASE_ADDR 0xB0000000 | ||
51 | #define CS3_BASE_ADDR 0xB2000000 | ||
52 | |||
53 | #define CS4_BASE_ADDR 0xB4000000 | ||
54 | #define CS4_BASE_ADDR_VIRT 0xF4000000 | ||
55 | #define CS4_SIZE SZ_32M | ||
56 | |||
57 | #define CS5_BASE_ADDR 0xB6000000 | ||
58 | #define PCMCIA_MEM_BASE_ADDR 0xBC000000 | ||
59 | |||
60 | /* | ||
61 | * IRAM | ||
62 | */ | ||
63 | #define IRAM_BASE_ADDR 0x1FFC0000 /* internal ram */ | ||
64 | #define IRAM_BASE_ADDR_VIRT 0xF8000000 | ||
65 | #define IRAM_SIZE SZ_16K | ||
66 | |||
67 | /* | ||
68 | * L2CC | ||
69 | */ | ||
70 | #define L2CC_BASE_ADDR 0x30000000 | ||
71 | #define L2CC_BASE_ADDR_VIRT 0xF9000000 | ||
72 | #define L2CC_SIZE SZ_1M | ||
73 | |||
74 | /* | ||
75 | * AIPS 1 | ||
76 | */ | ||
77 | #define AIPS1_BASE_ADDR 0x43F00000 | ||
78 | #define AIPS1_BASE_ADDR_VIRT 0xFC000000 | ||
79 | #define AIPS1_SIZE SZ_1M | ||
80 | |||
81 | #define MAX_BASE_ADDR (AIPS1_BASE_ADDR + 0x00004000) | ||
82 | #define EVTMON_BASE_ADDR (AIPS1_BASE_ADDR + 0x00008000) | ||
83 | #define CLKCTL_BASE_ADDR (AIPS1_BASE_ADDR + 0x0000C000) | ||
84 | #define ETB_SLOT4_BASE_ADDR (AIPS1_BASE_ADDR + 0x00010000) | ||
85 | #define ETB_SLOT5_BASE_ADDR (AIPS1_BASE_ADDR + 0x00014000) | ||
86 | #define ECT_CTIO_BASE_ADDR (AIPS1_BASE_ADDR + 0x00018000) | ||
87 | #define I2C_BASE_ADDR (AIPS1_BASE_ADDR + 0x00080000) | ||
88 | #define I2C3_BASE_ADDR (AIPS1_BASE_ADDR + 0x00084000) | ||
89 | #define OTG_BASE_ADDR (AIPS1_BASE_ADDR + 0x00088000) | ||
90 | #define ATA_BASE_ADDR (AIPS1_BASE_ADDR + 0x0008C000) | ||
91 | #define UART1_BASE_ADDR (AIPS1_BASE_ADDR + 0x00090000) | ||
92 | #define UART2_BASE_ADDR (AIPS1_BASE_ADDR + 0x00094000) | ||
93 | #define I2C2_BASE_ADDR (AIPS1_BASE_ADDR + 0x00098000) | ||
94 | #define OWIRE_BASE_ADDR (AIPS1_BASE_ADDR + 0x0009C000) | ||
95 | #define SSI1_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A0000) | ||
96 | #define CSPI1_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A4000) | ||
97 | #define KPP_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A8000) | ||
98 | #define IOMUXC_BASE_ADDR (AIPS1_BASE_ADDR + 0x000AC000) | ||
99 | #define UART4_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B0000) | ||
100 | #define UART5_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B4000) | ||
101 | #define ECT_IP1_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B8000) | ||
102 | #define ECT_IP2_BASE_ADDR (AIPS1_BASE_ADDR + 0x000BC000) | ||
103 | |||
104 | /* | ||
105 | * SPBA global module enabled #0 | ||
106 | */ | ||
107 | #define SPBA0_BASE_ADDR 0x50000000 | ||
108 | #define SPBA0_BASE_ADDR_VIRT 0xFC100000 | ||
109 | #define SPBA0_SIZE SZ_1M | ||
110 | |||
111 | #define MMC_SDHC1_BASE_ADDR (SPBA0_BASE_ADDR + 0x00004000) | ||
112 | #define MMC_SDHC2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00008000) | ||
113 | #define UART3_BASE_ADDR (SPBA0_BASE_ADDR + 0x0000C000) | ||
114 | #define CSPI2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00010000) | ||
115 | #define SSI2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00014000) | ||
116 | #define SIM1_BASE_ADDR (SPBA0_BASE_ADDR + 0x00018000) | ||
117 | #define IIM_BASE_ADDR (SPBA0_BASE_ADDR + 0x0001C000) | ||
118 | #define ATA_DMA_BASE_ADDR (SPBA0_BASE_ADDR + 0x00020000) | ||
119 | #define MSHC1_BASE_ADDR (SPBA0_BASE_ADDR + 0x00024000) | ||
120 | #define MSHC2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00024000) | ||
121 | #define SPBA_CTRL_BASE_ADDR (SPBA0_BASE_ADDR + 0x0003C000) | ||
122 | |||
123 | /* | ||
124 | * AIPS 2 | ||
125 | */ | ||
126 | #define AIPS2_BASE_ADDR 0x53F00000 | ||
127 | #define AIPS2_BASE_ADDR_VIRT 0xFC200000 | ||
128 | #define AIPS2_SIZE SZ_1M | ||
129 | #define CCM_BASE_ADDR (AIPS2_BASE_ADDR + 0x00080000) | ||
130 | #define CSPI3_BASE_ADDR (AIPS2_BASE_ADDR + 0x00084000) | ||
131 | #define FIRI_BASE_ADDR (AIPS2_BASE_ADDR + 0x0008C000) | ||
132 | #define GPT1_BASE_ADDR (AIPS2_BASE_ADDR + 0x00090000) | ||
133 | #define EPIT1_BASE_ADDR (AIPS2_BASE_ADDR + 0x00094000) | ||
134 | #define EPIT2_BASE_ADDR (AIPS2_BASE_ADDR + 0x00098000) | ||
135 | #define GPIO3_BASE_ADDR (AIPS2_BASE_ADDR + 0x000A4000) | ||
136 | #define SCC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000AC000) | ||
137 | #define SCM_BASE_ADDR (AIPS2_BASE_ADDR + 0x000AE000) | ||
138 | #define SMN_BASE_ADDR (AIPS2_BASE_ADDR + 0x000AF000) | ||
139 | #define RNGA_BASE_ADDR (AIPS2_BASE_ADDR + 0x000B0000) | ||
140 | #define IPU_CTRL_BASE_ADDR (AIPS2_BASE_ADDR + 0x000C0000) | ||
141 | #define AUDMUX_BASE_ADDR (AIPS2_BASE_ADDR + 0x000C4000) | ||
142 | #define MPEG4_ENC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000C8000) | ||
143 | #define GPIO1_BASE_ADDR (AIPS2_BASE_ADDR + 0x000CC000) | ||
144 | #define GPIO2_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D0000) | ||
145 | #define SDMA_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D4000) | ||
146 | #define RTC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D8000) | ||
147 | #define WDOG_BASE_ADDR (AIPS2_BASE_ADDR + 0x000DC000) | ||
148 | #define PWM_BASE_ADDR (AIPS2_BASE_ADDR + 0x000E0000) | ||
149 | #define RTIC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000EC000) | ||
150 | |||
151 | /* | ||
152 | * ROMP and AVIC | ||
153 | */ | ||
154 | #define ROMP_BASE_ADDR 0x60000000 | ||
155 | #define ROMP_BASE_ADDR_VIRT 0xFC500000 | ||
156 | #define ROMP_SIZE SZ_1M | ||
157 | |||
158 | #define AVIC_BASE_ADDR 0x68000000 | ||
159 | #define AVIC_BASE_ADDR_VIRT 0xFC400000 | ||
160 | #define AVIC_SIZE SZ_1M | ||
161 | |||
162 | /* | ||
163 | * NAND, SDRAM, WEIM, M3IF, EMI controllers | ||
164 | */ | ||
165 | #define X_MEMC_BASE_ADDR 0xB8000000 | ||
166 | #define X_MEMC_BASE_ADDR_VIRT 0xFC320000 | ||
167 | #define X_MEMC_SIZE SZ_64K | ||
168 | |||
169 | #define NFC_BASE_ADDR (X_MEMC_BASE_ADDR + 0x0000) | ||
170 | #define ESDCTL_BASE_ADDR (X_MEMC_BASE_ADDR + 0x1000) | ||
171 | #define WEIM_BASE_ADDR (X_MEMC_BASE_ADDR + 0x2000) | ||
172 | #define M3IF_BASE_ADDR (X_MEMC_BASE_ADDR + 0x3000) | ||
173 | #define EMI_CTL_BASE_ADDR (X_MEMC_BASE_ADDR + 0x4000) | ||
174 | #define PCMCIA_CTL_BASE_ADDR EMI_CTL_BASE_ADDR | ||
175 | |||
176 | /* | ||
177 | * Memory regions and CS | ||
178 | */ | ||
179 | #define IPU_MEM_BASE_ADDR 0x70000000 | ||
180 | #define CSD0_BASE_ADDR 0x80000000 | ||
181 | #define CSD1_BASE_ADDR 0x90000000 | ||
182 | #define CS0_BASE_ADDR 0xA0000000 | ||
183 | #define CS1_BASE_ADDR 0xA8000000 | ||
184 | #define CS2_BASE_ADDR 0xB0000000 | ||
185 | #define CS3_BASE_ADDR 0xB2000000 | ||
186 | |||
187 | #define CS4_BASE_ADDR 0xB4000000 | ||
188 | #define CS4_BASE_ADDR_VIRT 0xF4000000 | ||
189 | #define CS4_SIZE SZ_32M | ||
190 | |||
191 | #define CS5_BASE_ADDR 0xB6000000 | ||
192 | #define PCMCIA_MEM_BASE_ADDR 0xBC000000 | ||
193 | |||
194 | /*! | ||
195 | * This macro defines the physical to virtual address mapping for all the | ||
196 | * peripheral modules. It is used by passing in the physical address as x | ||
197 | * and returning the virtual address. If the physical address is not mapped, | ||
198 | * it returns 0xDEADBEEF | ||
199 | */ | ||
200 | #define IO_ADDRESS(x) \ | ||
201 | (((x >= IRAM_BASE_ADDR) && (x < (IRAM_BASE_ADDR + IRAM_SIZE))) ? IRAM_IO_ADDRESS(x):\ | ||
202 | ((x >= L2CC_BASE_ADDR) && (x < (L2CC_BASE_ADDR + L2CC_SIZE))) ? L2CC_IO_ADDRESS(x):\ | ||
203 | ((x >= AIPS1_BASE_ADDR) && (x < (AIPS1_BASE_ADDR + AIPS1_SIZE))) ? AIPS1_IO_ADDRESS(x):\ | ||
204 | ((x >= SPBA0_BASE_ADDR) && (x < (SPBA0_BASE_ADDR + SPBA0_SIZE))) ? SPBA0_IO_ADDRESS(x):\ | ||
205 | ((x >= AIPS2_BASE_ADDR) && (x < (AIPS2_BASE_ADDR + AIPS2_SIZE))) ? AIPS2_IO_ADDRESS(x):\ | ||
206 | ((x >= ROMP_BASE_ADDR) && (x < (ROMP_BASE_ADDR + ROMP_SIZE))) ? ROMP_IO_ADDRESS(x):\ | ||
207 | ((x >= AVIC_BASE_ADDR) && (x < (AVIC_BASE_ADDR + AVIC_SIZE))) ? AVIC_IO_ADDRESS(x):\ | ||
208 | ((x >= CS4_BASE_ADDR) && (x < (CS4_BASE_ADDR + CS4_SIZE))) ? CS4_IO_ADDRESS(x):\ | ||
209 | ((x >= X_MEMC_BASE_ADDR) && (x < (X_MEMC_BASE_ADDR + X_MEMC_SIZE))) ? X_MEMC_IO_ADDRESS(x):\ | ||
210 | 0xDEADBEEF) | ||
211 | |||
212 | /* | ||
213 | * define the address mapping macros: in physical address order | ||
214 | */ | ||
215 | |||
216 | #define IRAM_IO_ADDRESS(x) \ | ||
217 | (((x) - IRAM_BASE_ADDR) + IRAM_BASE_ADDR_VIRT) | ||
218 | |||
219 | #define L2CC_IO_ADDRESS(x) \ | ||
220 | (((x) - L2CC_BASE_ADDR) + L2CC_BASE_ADDR_VIRT) | ||
221 | |||
222 | #define AIPS1_IO_ADDRESS(x) \ | ||
223 | (((x) - AIPS1_BASE_ADDR) + AIPS1_BASE_ADDR_VIRT) | ||
224 | |||
225 | #define SPBA0_IO_ADDRESS(x) \ | ||
226 | (((x) - SPBA0_BASE_ADDR) + SPBA0_BASE_ADDR_VIRT) | ||
227 | |||
228 | #define AIPS2_IO_ADDRESS(x) \ | ||
229 | (((x) - AIPS2_BASE_ADDR) + AIPS2_BASE_ADDR_VIRT) | ||
230 | |||
231 | #define ROMP_IO_ADDRESS(x) \ | ||
232 | (((x) - ROMP_BASE_ADDR) + ROMP_BASE_ADDR_VIRT) | ||
233 | |||
234 | #define AVIC_IO_ADDRESS(x) \ | ||
235 | (((x) - AVIC_BASE_ADDR) + AVIC_BASE_ADDR_VIRT) | ||
236 | |||
237 | #define CS4_IO_ADDRESS(x) \ | ||
238 | (((x) - CS4_BASE_ADDR) + CS4_BASE_ADDR_VIRT) | ||
239 | |||
240 | #define X_MEMC_IO_ADDRESS(x) \ | ||
241 | (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT) | ||
242 | |||
243 | #define PCMCIA_IO_ADDRESS(x) \ | ||
244 | (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT) | ||
245 | |||
246 | /* Start of physical RAM - On many MX31 platforms, this is the first SDRAM bank (CSD0) */ | ||
247 | #define PHYS_OFFSET CSD0_BASE_ADDR | ||
248 | |||
249 | /* | ||
250 | * Interrupt numbers | ||
251 | */ | ||
252 | #define MXC_INT_PEN_ADS7843 0 | ||
253 | #define MXC_INT_RESV1 1 | ||
254 | #define MXC_INT_CS8900A 2 | ||
255 | #define MXC_INT_I2C3 3 | ||
256 | #define MXC_INT_I2C2 4 | ||
257 | #define MXC_INT_MPEG4_ENCODER 5 | ||
258 | #define MXC_INT_RTIC 6 | ||
259 | #define MXC_INT_FIRI 7 | ||
260 | #define MXC_INT_MMC_SDHC2 8 | ||
261 | #define MXC_INT_MMC_SDHC1 9 | ||
262 | #define MXC_INT_I2C 10 | ||
263 | #define MXC_INT_SSI2 11 | ||
264 | #define MXC_INT_SSI1 12 | ||
265 | #define MXC_INT_CSPI2 13 | ||
266 | #define MXC_INT_CSPI1 14 | ||
267 | #define MXC_INT_ATA 15 | ||
268 | #define MXC_INT_MBX 16 | ||
269 | #define MXC_INT_CSPI3 17 | ||
270 | #define MXC_INT_UART3 18 | ||
271 | #define MXC_INT_IIM 19 | ||
272 | #define MXC_INT_SIM2 20 | ||
273 | #define MXC_INT_SIM1 21 | ||
274 | #define MXC_INT_RNGA 22 | ||
275 | #define MXC_INT_EVTMON 23 | ||
276 | #define MXC_INT_KPP 24 | ||
277 | #define MXC_INT_RTC 25 | ||
278 | #define MXC_INT_PWM 26 | ||
279 | #define MXC_INT_EPIT2 27 | ||
280 | #define MXC_INT_EPIT1 28 | ||
281 | #define MXC_INT_GPT 29 | ||
282 | #define MXC_INT_RESV30 30 | ||
283 | #define MXC_INT_RESV31 31 | ||
284 | #define MXC_INT_UART2 32 | ||
285 | #define MXC_INT_NANDFC 33 | ||
286 | #define MXC_INT_SDMA 34 | ||
287 | #define MXC_INT_USB1 35 | ||
288 | #define MXC_INT_USB2 36 | ||
289 | #define MXC_INT_USB3 37 | ||
290 | #define MXC_INT_USB4 38 | ||
291 | #define MXC_INT_MSHC1 39 | ||
292 | #define MXC_INT_MSHC2 40 | ||
293 | #define MXC_INT_IPU_ERR 41 | ||
294 | #define MXC_INT_IPU_SYN 42 | ||
295 | #define MXC_INT_RESV43 43 | ||
296 | #define MXC_INT_RESV44 44 | ||
297 | #define MXC_INT_UART1 45 | ||
298 | #define MXC_INT_UART4 46 | ||
299 | #define MXC_INT_UART5 47 | ||
300 | #define MXC_INT_ECT 48 | ||
301 | #define MXC_INT_SCC_SCM 49 | ||
302 | #define MXC_INT_SCC_SMN 50 | ||
303 | #define MXC_INT_GPIO2 51 | ||
304 | #define MXC_INT_GPIO1 52 | ||
305 | #define MXC_INT_CCM 53 | ||
306 | #define MXC_INT_PCMCIA 54 | ||
307 | #define MXC_INT_WDOG 55 | ||
308 | #define MXC_INT_GPIO3 56 | ||
309 | #define MXC_INT_RESV57 57 | ||
310 | #define MXC_INT_EXT_POWER 58 | ||
311 | #define MXC_INT_EXT_TEMPER 59 | ||
312 | #define MXC_INT_EXT_SENSOR60 60 | ||
313 | #define MXC_INT_EXT_SENSOR61 61 | ||
314 | #define MXC_INT_EXT_WDOG 62 | ||
315 | #define MXC_INT_EXT_TV 63 | ||
316 | |||
317 | #define MXC_MAX_INT_LINES 64 | ||
318 | |||
319 | #define MXC_GPIO_INT_BASE MXC_MAX_INT_LINES | ||
320 | |||
321 | /*! | ||
322 | * Number of GPIO port as defined in the IC Spec | ||
323 | */ | ||
324 | #define GPIO_PORT_NUM 3 | ||
325 | /*! | ||
326 | * Number of GPIO pins per port | ||
327 | */ | ||
328 | #define GPIO_NUM_PIN 32 | ||
329 | |||
330 | #define PROD_SIGNATURE 0x1 /* For MX31 */ | ||
331 | |||
332 | #define SYSTEM_REV_MIN CHIP_REV_1_0 | ||
333 | #define SYSTEM_REV_NUM 3 | ||
334 | |||
335 | #endif /* __ASM_ARCH_MXC_MX31_H__ */ | ||
diff --git a/include/asm-arm/arch-mxc/mxc.h b/include/asm-arm/arch-mxc/mxc.h new file mode 100644 index 000000000000..0837f1f9ca31 --- /dev/null +++ b/include/asm-arm/arch-mxc/mxc.h | |||
@@ -0,0 +1,149 @@ | |||
1 | /* | ||
2 | * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | */ | ||
4 | |||
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 version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #ifndef __ASM_ARCH_MXC_H__ | ||
12 | #define __ASM_ARCH_MXC_H__ | ||
13 | |||
14 | #ifndef __ASM_ARCH_MXC_HARDWARE_H__ | ||
15 | #error "Do not include directly." | ||
16 | #endif | ||
17 | |||
18 | /* | ||
19 | ***************************************** | ||
20 | * GPT Register definitions * | ||
21 | ***************************************** | ||
22 | */ | ||
23 | #define MXC_GPT_GPTCR IO_ADDRESS(GPT1_BASE_ADDR + 0x00) | ||
24 | #define MXC_GPT_GPTPR IO_ADDRESS(GPT1_BASE_ADDR + 0x04) | ||
25 | #define MXC_GPT_GPTSR IO_ADDRESS(GPT1_BASE_ADDR + 0x08) | ||
26 | #define MXC_GPT_GPTIR IO_ADDRESS(GPT1_BASE_ADDR + 0x0C) | ||
27 | #define MXC_GPT_GPTOCR1 IO_ADDRESS(GPT1_BASE_ADDR + 0x10) | ||
28 | #define MXC_GPT_GPTOCR2 IO_ADDRESS(GPT1_BASE_ADDR + 0x14) | ||
29 | #define MXC_GPT_GPTOCR3 IO_ADDRESS(GPT1_BASE_ADDR + 0x18) | ||
30 | #define MXC_GPT_GPTICR1 IO_ADDRESS(GPT1_BASE_ADDR + 0x1C) | ||
31 | #define MXC_GPT_GPTICR2 IO_ADDRESS(GPT1_BASE_ADDR + 0x20) | ||
32 | #define MXC_GPT_GPTCNT IO_ADDRESS(GPT1_BASE_ADDR + 0x24) | ||
33 | |||
34 | /*! | ||
35 | * GPT Control register bit definitions | ||
36 | */ | ||
37 | #define GPTCR_FO3 (1 << 31) | ||
38 | #define GPTCR_FO2 (1 << 30) | ||
39 | #define GPTCR_FO1 (1 << 29) | ||
40 | |||
41 | #define GPTCR_OM3_SHIFT 26 | ||
42 | #define GPTCR_OM3_MASK (7 << GPTCR_OM3_SHIFT) | ||
43 | #define GPTCR_OM3_DISCONNECTED (0 << GPTCR_OM3_SHIFT) | ||
44 | #define GPTCR_OM3_TOGGLE (1 << GPTCR_OM3_SHIFT) | ||
45 | #define GPTCR_OM3_CLEAR (2 << GPTCR_OM3_SHIFT) | ||
46 | #define GPTCR_OM3_SET (3 << GPTCR_OM3_SHIFT) | ||
47 | #define GPTCR_OM3_GENERATE_LOW (7 << GPTCR_OM3_SHIFT) | ||
48 | |||
49 | #define GPTCR_OM2_SHIFT 23 | ||
50 | #define GPTCR_OM2_MASK (7 << GPTCR_OM2_SHIFT) | ||
51 | #define GPTCR_OM2_DISCONNECTED (0 << GPTCR_OM2_SHIFT) | ||
52 | #define GPTCR_OM2_TOGGLE (1 << GPTCR_OM2_SHIFT) | ||
53 | #define GPTCR_OM2_CLEAR (2 << GPTCR_OM2_SHIFT) | ||
54 | #define GPTCR_OM2_SET (3 << GPTCR_OM2_SHIFT) | ||
55 | #define GPTCR_OM2_GENERATE_LOW (7 << GPTCR_OM2_SHIFT) | ||
56 | |||
57 | #define GPTCR_OM1_SHIFT 20 | ||
58 | #define GPTCR_OM1_MASK (7 << GPTCR_OM1_SHIFT) | ||
59 | #define GPTCR_OM1_DISCONNECTED (0 << GPTCR_OM1_SHIFT) | ||
60 | #define GPTCR_OM1_TOGGLE (1 << GPTCR_OM1_SHIFT) | ||
61 | #define GPTCR_OM1_CLEAR (2 << GPTCR_OM1_SHIFT) | ||
62 | #define GPTCR_OM1_SET (3 << GPTCR_OM1_SHIFT) | ||
63 | #define GPTCR_OM1_GENERATE_LOW (7 << GPTCR_OM1_SHIFT) | ||
64 | |||
65 | #define GPTCR_IM2_SHIFT 18 | ||
66 | #define GPTCR_IM2_MASK (3 << GPTCR_IM2_SHIFT) | ||
67 | #define GPTCR_IM2_CAPTURE_DISABLE (0 << GPTCR_IM2_SHIFT) | ||
68 | #define GPTCR_IM2_CAPTURE_RISING (1 << GPTCR_IM2_SHIFT) | ||
69 | #define GPTCR_IM2_CAPTURE_FALLING (2 << GPTCR_IM2_SHIFT) | ||
70 | #define GPTCR_IM2_CAPTURE_BOTH (3 << GPTCR_IM2_SHIFT) | ||
71 | |||
72 | #define GPTCR_IM1_SHIFT 16 | ||
73 | #define GPTCR_IM1_MASK (3 << GPTCR_IM1_SHIFT) | ||
74 | #define GPTCR_IM1_CAPTURE_DISABLE (0 << GPTCR_IM1_SHIFT) | ||
75 | #define GPTCR_IM1_CAPTURE_RISING (1 << GPTCR_IM1_SHIFT) | ||
76 | #define GPTCR_IM1_CAPTURE_FALLING (2 << GPTCR_IM1_SHIFT) | ||
77 | #define GPTCR_IM1_CAPTURE_BOTH (3 << GPTCR_IM1_SHIFT) | ||
78 | |||
79 | #define GPTCR_SWR (1 << 15) | ||
80 | #define GPTCR_FRR (1 << 9) | ||
81 | |||
82 | #define GPTCR_CLKSRC_SHIFT 6 | ||
83 | #define GPTCR_CLKSRC_MASK (7 << GPTCR_CLKSRC_SHIFT) | ||
84 | #define GPTCR_CLKSRC_NOCLOCK (0 << GPTCR_CLKSRC_SHIFT) | ||
85 | #define GPTCR_CLKSRC_HIGHFREQ (2 << GPTCR_CLKSRC_SHIFT) | ||
86 | #define GPTCR_CLKSRC_CLKIN (3 << GPTCR_CLKSRC_SHIFT) | ||
87 | #define GPTCR_CLKSRC_CLK32K (7 << GPTCR_CLKSRC_SHIFT) | ||
88 | |||
89 | #define GPTCR_STOPEN (1 << 5) | ||
90 | #define GPTCR_DOZEN (1 << 4) | ||
91 | #define GPTCR_WAITEN (1 << 3) | ||
92 | #define GPTCR_DBGEN (1 << 2) | ||
93 | |||
94 | #define GPTCR_ENMOD (1 << 1) | ||
95 | #define GPTCR_ENABLE (1 << 0) | ||
96 | |||
97 | #define GPTSR_OF1 (1 << 0) | ||
98 | #define GPTSR_OF2 (1 << 1) | ||
99 | #define GPTSR_OF3 (1 << 2) | ||
100 | #define GPTSR_IF1 (1 << 3) | ||
101 | #define GPTSR_IF2 (1 << 4) | ||
102 | #define GPTSR_ROV (1 << 5) | ||
103 | |||
104 | #define GPTIR_OF1IE GPTSR_OF1 | ||
105 | #define GPTIR_OF2IE GPTSR_OF2 | ||
106 | #define GPTIR_OF3IE GPTSR_OF3 | ||
107 | #define GPTIR_IF1IE GPTSR_IF1 | ||
108 | #define GPTIR_IF2IE GPTSR_IF2 | ||
109 | #define GPTIR_ROVIE GPTSR_ROV | ||
110 | |||
111 | /* | ||
112 | ***************************************** | ||
113 | * AVIC Registers * | ||
114 | ***************************************** | ||
115 | */ | ||
116 | #define AVIC_BASE IO_ADDRESS(AVIC_BASE_ADDR) | ||
117 | #define AVIC_INTCNTL (AVIC_BASE + 0x00) /* int control reg */ | ||
118 | #define AVIC_NIMASK (AVIC_BASE + 0x04) /* int mask reg */ | ||
119 | #define AVIC_INTENNUM (AVIC_BASE + 0x08) /* int enable number reg */ | ||
120 | #define AVIC_INTDISNUM (AVIC_BASE + 0x0C) /* int disable number reg */ | ||
121 | #define AVIC_INTENABLEH (AVIC_BASE + 0x10) /* int enable reg high */ | ||
122 | #define AVIC_INTENABLEL (AVIC_BASE + 0x14) /* int enable reg low */ | ||
123 | #define AVIC_INTTYPEH (AVIC_BASE + 0x18) /* int type reg high */ | ||
124 | #define AVIC_INTTYPEL (AVIC_BASE + 0x1C) /* int type reg low */ | ||
125 | #define AVIC_NIPRIORITY7 (AVIC_BASE + 0x20) /* norm int priority lvl7 */ | ||
126 | #define AVIC_NIPRIORITY6 (AVIC_BASE + 0x24) /* norm int priority lvl6 */ | ||
127 | #define AVIC_NIPRIORITY5 (AVIC_BASE + 0x28) /* norm int priority lvl5 */ | ||
128 | #define AVIC_NIPRIORITY4 (AVIC_BASE + 0x2C) /* norm int priority lvl4 */ | ||
129 | #define AVIC_NIPRIORITY3 (AVIC_BASE + 0x30) /* norm int priority lvl3 */ | ||
130 | #define AVIC_NIPRIORITY2 (AVIC_BASE + 0x34) /* norm int priority lvl2 */ | ||
131 | #define AVIC_NIPRIORITY1 (AVIC_BASE + 0x38) /* norm int priority lvl1 */ | ||
132 | #define AVIC_NIPRIORITY0 (AVIC_BASE + 0x3C) /* norm int priority lvl0 */ | ||
133 | #define AVIC_NIVECSR (AVIC_BASE + 0x40) /* norm int vector/status */ | ||
134 | #define AVIC_FIVECSR (AVIC_BASE + 0x44) /* fast int vector/status */ | ||
135 | #define AVIC_INTSRCH (AVIC_BASE + 0x48) /* int source reg high */ | ||
136 | #define AVIC_INTSRCL (AVIC_BASE + 0x4C) /* int source reg low */ | ||
137 | #define AVIC_INTFRCH (AVIC_BASE + 0x50) /* int force reg high */ | ||
138 | #define AVIC_INTFRCL (AVIC_BASE + 0x54) /* int force reg low */ | ||
139 | #define AVIC_NIPNDH (AVIC_BASE + 0x58) /* norm int pending high */ | ||
140 | #define AVIC_NIPNDL (AVIC_BASE + 0x5C) /* norm int pending low */ | ||
141 | #define AVIC_FIPNDH (AVIC_BASE + 0x60) /* fast int pending high */ | ||
142 | #define AVIC_FIPNDL (AVIC_BASE + 0x64) /* fast int pending low */ | ||
143 | |||
144 | #define SYSTEM_PREV_REG IO_ADDRESS(IIM_BASE_ADDR + 0x20) | ||
145 | #define SYSTEM_SREV_REG IO_ADDRESS(IIM_BASE_ADDR + 0x24) | ||
146 | #define IIM_PROD_REV_SH 3 | ||
147 | #define IIM_PROD_REV_LEN 5 | ||
148 | |||
149 | #endif /* __ASM_ARCH_MXC_H__ */ | ||
diff --git a/include/asm-arm/arch-mxc/system.h b/include/asm-arm/arch-mxc/system.h new file mode 100644 index 000000000000..109956b41aca --- /dev/null +++ b/include/asm-arm/arch-mxc/system.h | |||
@@ -0,0 +1,50 @@ | |||
1 | /* | ||
2 | * Copyright (C) 1999 ARM Limited | ||
3 | * Copyright (C) 2000 Deep Blue Solutions Ltd | ||
4 | * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
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, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
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 | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #ifndef __ASM_ARCH_MXC_SYSTEM_H__ | ||
22 | #define __ASM_ARCH_MXC_SYSTEM_H__ | ||
23 | |||
24 | /*! | ||
25 | * @file system.h | ||
26 | * @brief This file contains idle and reset functions. | ||
27 | * | ||
28 | * @ingroup System | ||
29 | */ | ||
30 | |||
31 | /*! | ||
32 | * This function puts the CPU into idle mode. It is called by default_idle() | ||
33 | * in process.c file. | ||
34 | */ | ||
35 | static inline void arch_idle(void) | ||
36 | { | ||
37 | cpu_do_idle(); | ||
38 | } | ||
39 | |||
40 | /* | ||
41 | * This function resets the system. It is called by machine_restart(). | ||
42 | * | ||
43 | * @param mode indicates different kinds of resets | ||
44 | */ | ||
45 | static inline void arch_reset(char mode) | ||
46 | { | ||
47 | cpu_reset(0); | ||
48 | } | ||
49 | |||
50 | #endif /* __ASM_ARCH_MXC_SYSTEM_H__ */ | ||
diff --git a/include/asm-arm/arch-mxc/timex.h b/include/asm-arm/arch-mxc/timex.h new file mode 100644 index 000000000000..59019fa58f82 --- /dev/null +++ b/include/asm-arm/arch-mxc/timex.h | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * Copyright (C) 1999 ARM Limited | ||
3 | * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
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; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | */ | ||
19 | |||
20 | #ifndef __ASM_ARCH_MXC_TIMEX_H__ | ||
21 | #define __ASM_ARCH_MXC_TIMEX_H__ | ||
22 | |||
23 | #include <asm/hardware.h> /* for CLOCK_TICK_RATE */ | ||
24 | |||
25 | #endif /* __ASM_ARCH_MXC_TIMEX_H__ */ | ||
diff --git a/include/asm-arm/arch-mxc/uncompress.h b/include/asm-arm/arch-mxc/uncompress.h new file mode 100644 index 000000000000..ec5787d0e78c --- /dev/null +++ b/include/asm-arm/arch-mxc/uncompress.h | |||
@@ -0,0 +1,79 @@ | |||
1 | /* | ||
2 | * include/asm-arm/arch-mxc/uncompress.h | ||
3 | * | ||
4 | * | ||
5 | * | ||
6 | * Copyright (C) 1999 ARM Limited | ||
7 | * Copyright (C) Shane Nay (shane@minirl.com) | ||
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 of the License, or | ||
12 | * (at your option) 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | */ | ||
23 | #ifndef __ASM_ARCH_MXC_UNCOMPRESS_H__ | ||
24 | #define __ASM_ARCH_MXC_UNCOMPRESS_H__ | ||
25 | |||
26 | #define __MXC_BOOT_UNCOMPRESS | ||
27 | |||
28 | #include <asm/hardware.h> | ||
29 | #include <asm/processor.h> | ||
30 | |||
31 | #define UART(x) (*(volatile unsigned long *)(serial_port + (x))) | ||
32 | |||
33 | #define USR2 0x98 | ||
34 | #define USR2_TXFE (1<<14) | ||
35 | #define TXR 0x40 | ||
36 | #define UCR1 0x80 | ||
37 | #define UCR1_UARTEN 1 | ||
38 | |||
39 | /* | ||
40 | * The following code assumes the serial port has already been | ||
41 | * initialized by the bootloader. We search for the first enabled | ||
42 | * port in the most probable order. If you didn't setup a port in | ||
43 | * your bootloader then nothing will appear (which might be desired). | ||
44 | * | ||
45 | * This does not append a newline | ||
46 | */ | ||
47 | |||
48 | static void putc(int ch) | ||
49 | { | ||
50 | static unsigned long serial_port = 0; | ||
51 | |||
52 | if (unlikely(serial_port == 0)) { | ||
53 | do { | ||
54 | serial_port = UART1_BASE_ADDR; | ||
55 | if (UART(UCR1) & UCR1_UARTEN) | ||
56 | break; | ||
57 | serial_port = UART2_BASE_ADDR; | ||
58 | if (UART(UCR1) & UCR1_UARTEN) | ||
59 | break; | ||
60 | return; | ||
61 | } while (0); | ||
62 | } | ||
63 | |||
64 | while (!(UART(USR2) & USR2_TXFE)) | ||
65 | cpu_relax(); | ||
66 | |||
67 | UART(TXR) = ch; | ||
68 | } | ||
69 | |||
70 | #define flush() do { } while (0) | ||
71 | |||
72 | /* | ||
73 | * nothing to do | ||
74 | */ | ||
75 | #define arch_decomp_setup() | ||
76 | |||
77 | #define arch_decomp_wdog() | ||
78 | |||
79 | #endif /* __ASM_ARCH_MXC_UNCOMPRESS_H__ */ | ||
diff --git a/include/asm-arm/arch-mxc/vmalloc.h b/include/asm-arm/arch-mxc/vmalloc.h new file mode 100644 index 000000000000..83a73da895eb --- /dev/null +++ b/include/asm-arm/arch-mxc/vmalloc.h | |||
@@ -0,0 +1,36 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000 Russell King. | ||
3 | * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
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; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | */ | ||
19 | |||
20 | #ifndef __ASM_ARCH_MXC_VMALLOC_H__ | ||
21 | #define __ASM_ARCH_MXC_VMALLOC_H__ | ||
22 | |||
23 | /*! | ||
24 | * @file vmalloc.h | ||
25 | * | ||
26 | * @brief This file contains platform specific macros for vmalloc. | ||
27 | * | ||
28 | * @ingroup System | ||
29 | */ | ||
30 | |||
31 | /*! | ||
32 | * vmalloc ending address | ||
33 | */ | ||
34 | #define VMALLOC_END 0xF4000000 | ||
35 | |||
36 | #endif /* __ASM_ARCH_MXC_VMALLOC_H__ */ | ||
diff --git a/include/asm-arm/arch-ns9xxx/regs-bbu.h b/include/asm-arm/arch-ns9xxx/regs-bbu.h index e26269546240..7ee194dc6354 100644 --- a/include/asm-arm/arch-ns9xxx/regs-bbu.h +++ b/include/asm-arm/arch-ns9xxx/regs-bbu.h | |||
@@ -15,7 +15,31 @@ | |||
15 | 15 | ||
16 | /* BBus Utility */ | 16 | /* BBus Utility */ |
17 | 17 | ||
18 | /* GPIO Configuration Register */ | 18 | /* GPIO Configuration Registers block 1 */ |
19 | #define BBU_GC(x) __REG2(0x9060000c, (x)) | 19 | /* NOTE: the HRM starts counting at 1 for the GPIO registers, here the start is |
20 | * at 0 for each block. That is, BBU_GCONFb1(0) is GPIO Configuration Register | ||
21 | * #1, BBU_GCONFb2(0) is GPIO Configuration Register #8. */ | ||
22 | #define BBU_GCONFb1(x) __REG2(0x90600010, (x)) | ||
23 | #define BBU_GCONFb2(x) __REG2(0x90600100, (x)) | ||
24 | |||
25 | #define BBU_GCONFx_DIR(m) __REGBIT(3 + (((m) & 7) << 2)) | ||
26 | #define BBU_GCONFx_DIR_INPUT(m) __REGVAL(BBU_GCONFx_DIR(m), 0) | ||
27 | #define BBU_GCONFx_DIR_OUTPUT(m) __REGVAL(BBU_GCONFx_DIR(m), 1) | ||
28 | #define BBU_GCONFx_INV(m) __REGBIT(2 + (((m) & 7) << 2)) | ||
29 | #define BBU_GCONFx_INV_NO(m) __REGVAL(BBU_GCONFx_INV(m), 0) | ||
30 | #define BBU_GCONFx_INV_YES(m) __REGVAL(BBU_GCONFx_INV(m), 1) | ||
31 | #define BBU_GCONFx_FUNC(m) __REGBITS(1 + (((m) & 7) << 2), ((m) & 7) << 2) | ||
32 | #define BBU_GCONFx_FUNC_0(m) __REGVAL(BBU_GCONFx_FUNC(m), 0) | ||
33 | #define BBU_GCONFx_FUNC_1(m) __REGVAL(BBU_GCONFx_FUNC(m), 1) | ||
34 | #define BBU_GCONFx_FUNC_2(m) __REGVAL(BBU_GCONFx_FUNC(m), 2) | ||
35 | #define BBU_GCONFx_FUNC_3(m) __REGVAL(BBU_GCONFx_FUNC(m), 3) | ||
36 | |||
37 | #define BBU_GCTRL1 __REG(0x90600030) | ||
38 | #define BBU_GCTRL2 __REG(0x90600034) | ||
39 | #define BBU_GCTRL3 __REG(0x90600120) | ||
40 | |||
41 | #define BBU_GSTAT1 __REG(0x90600040) | ||
42 | #define BBU_GSTAT2 __REG(0x90600044) | ||
43 | #define BBU_GSTAT3 __REG(0x90600130) | ||
20 | 44 | ||
21 | #endif /* ifndef __ASM_ARCH_REGSBBU_H */ | 45 | #endif /* ifndef __ASM_ARCH_REGSBBU_H */ |
diff --git a/include/asm-arm/arch-ns9xxx/regs-mem.h b/include/asm-arm/arch-ns9xxx/regs-mem.h index 8ed8448767b9..fb455a0ed845 100644 --- a/include/asm-arm/arch-ns9xxx/regs-mem.h +++ b/include/asm-arm/arch-ns9xxx/regs-mem.h | |||
@@ -79,9 +79,9 @@ | |||
79 | #define MEM_SMC(x) __REG2(0xa0700200, (x) << 3) | 79 | #define MEM_SMC(x) __REG2(0xa0700200, (x) << 3) |
80 | 80 | ||
81 | /* Static Memory Configuration Register x: Write protect */ | 81 | /* Static Memory Configuration Register x: Write protect */ |
82 | #define MEM_SMC_WSMC __REGBIT(20) | 82 | #define MEM_SMC_PSMC __REGBIT(20) |
83 | #define MEM_SMC_WSMC_OFF __REGVAL(MEM_SMC_WSMC, 0) | 83 | #define MEM_SMC_PSMC_OFF __REGVAL(MEM_SMC_PSMC, 0) |
84 | #define MEM_SMC_WSMC_ON __REGVAL(MEM_SMC_WSMC, 1) | 84 | #define MEM_SMC_PSMC_ON __REGVAL(MEM_SMC_PSMC, 1) |
85 | 85 | ||
86 | /* Static Memory Configuration Register x: Buffer enable */ | 86 | /* Static Memory Configuration Register x: Buffer enable */ |
87 | #define MEM_SMC_BSMC __REGBIT(19) | 87 | #define MEM_SMC_BSMC __REGBIT(19) |
diff --git a/include/asm-arm/arch-ns9xxx/regs-sys.h b/include/asm-arm/arch-ns9xxx/regs-sys.h index a42546aeb92a..749262f86204 100644 --- a/include/asm-arm/arch-ns9xxx/regs-sys.h +++ b/include/asm-arm/arch-ns9xxx/regs-sys.h | |||
@@ -64,7 +64,7 @@ | |||
64 | 64 | ||
65 | /* Timer x Control register: Timer enable */ | 65 | /* Timer x Control register: Timer enable */ |
66 | #define SYS_TCx_TEN __REGBIT(15) | 66 | #define SYS_TCx_TEN __REGBIT(15) |
67 | #define SYS_TCx_TEN_DIS __REGVAL(SYS_TCx_TEN, 1) | 67 | #define SYS_TCx_TEN_DIS __REGVAL(SYS_TCx_TEN, 0) |
68 | #define SYS_TCx_TEN_EN __REGVAL(SYS_TCx_TEN, 1) | 68 | #define SYS_TCx_TEN_EN __REGVAL(SYS_TCx_TEN, 1) |
69 | 69 | ||
70 | /* Timer x Control register: CPU debug mode */ | 70 | /* Timer x Control register: CPU debug mode */ |
diff --git a/include/asm-arm/arch-pxa/pm.h b/include/asm-arm/arch-pxa/pm.h index 52243a62c4e7..6903db7fae15 100644 --- a/include/asm-arm/arch-pxa/pm.h +++ b/include/asm-arm/arch-pxa/pm.h | |||
@@ -7,5 +7,19 @@ | |||
7 | * | 7 | * |
8 | */ | 8 | */ |
9 | 9 | ||
10 | extern int pxa_pm_prepare(suspend_state_t state); | 10 | struct pxa_cpu_pm_fns { |
11 | int save_size; | ||
12 | void (*save)(unsigned long *); | ||
13 | void (*restore)(unsigned long *); | ||
14 | int (*valid)(suspend_state_t state); | ||
15 | void (*enter)(suspend_state_t state); | ||
16 | }; | ||
17 | |||
18 | extern struct pxa_cpu_pm_fns *pxa_cpu_pm_fns; | ||
19 | |||
20 | /* sleep.S */ | ||
21 | extern void pxa25x_cpu_suspend(unsigned int); | ||
22 | extern void pxa27x_cpu_suspend(unsigned int); | ||
23 | extern void pxa_cpu_resume(void); | ||
24 | |||
11 | extern int pxa_pm_enter(suspend_state_t state); | 25 | extern int pxa_pm_enter(suspend_state_t state); |
diff --git a/include/asm-arm/arch-s3c2400/map.h b/include/asm-arm/arch-s3c2400/map.h new file mode 100644 index 000000000000..1184d907b31e --- /dev/null +++ b/include/asm-arm/arch-s3c2400/map.h | |||
@@ -0,0 +1,66 @@ | |||
1 | /* linux/include/asm-arm/arch-s3c2400/map.h | ||
2 | * | ||
3 | * Copyright 2003,2007 Simtec Electronics | ||
4 | * http://armlinux.simtec.co.uk/ | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * | ||
7 | * Copyright 2003, Lucas Correia Villa Real | ||
8 | * | ||
9 | * S3C2400 - Memory map definitions | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * published by the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | #define S3C2400_PA_MEMCTRL (0x14000000) | ||
17 | #define S3C2400_PA_USBHOST (0x14200000) | ||
18 | #define S3C2400_PA_IRQ (0x14400000) | ||
19 | #define S3C2400_PA_DMA (0x14600000) | ||
20 | #define S3C2400_PA_CLKPWR (0x14800000) | ||
21 | #define S3C2400_PA_LCD (0x14A00000) | ||
22 | #define S3C2400_PA_UART (0x15000000) | ||
23 | #define S3C2400_PA_TIMER (0x15100000) | ||
24 | #define S3C2400_PA_USBDEV (0x15200140) | ||
25 | #define S3C2400_PA_WATCHDOG (0x15300000) | ||
26 | #define S3C2400_PA_IIC (0x15400000) | ||
27 | #define S3C2400_PA_IIS (0x15508000) | ||
28 | #define S3C2400_PA_GPIO (0x15600000) | ||
29 | #define S3C2400_PA_RTC (0x15700040) | ||
30 | #define S3C2400_PA_ADC (0x15800000) | ||
31 | #define S3C2400_PA_SPI (0x15900000) | ||
32 | |||
33 | #define S3C2400_PA_MMC (0x15A00000) | ||
34 | #define S3C2400_SZ_MMC SZ_1M | ||
35 | |||
36 | /* physical addresses of all the chip-select areas */ | ||
37 | |||
38 | #define S3C2400_CS0 (0x00000000) | ||
39 | #define S3C2400_CS1 (0x02000000) | ||
40 | #define S3C2400_CS2 (0x04000000) | ||
41 | #define S3C2400_CS3 (0x06000000) | ||
42 | #define S3C2400_CS4 (0x08000000) | ||
43 | #define S3C2400_CS5 (0x0A000000) | ||
44 | #define S3C2400_CS6 (0x0C000000) | ||
45 | #define S3C2400_CS7 (0x0E000000) | ||
46 | |||
47 | #define S3C2400_SDRAM_PA (S3C2400_CS6) | ||
48 | |||
49 | /* Use a single interface for common resources between S3C24XX cpus */ | ||
50 | |||
51 | #define S3C24XX_PA_IRQ S3C2400_PA_IRQ | ||
52 | #define S3C24XX_PA_MEMCTRL S3C2400_PA_MEMCTRL | ||
53 | #define S3C24XX_PA_USBHOST S3C2400_PA_USBHOST | ||
54 | #define S3C24XX_PA_DMA S3C2400_PA_DMA | ||
55 | #define S3C24XX_PA_CLKPWR S3C2400_PA_CLKPWR | ||
56 | #define S3C24XX_PA_LCD S3C2400_PA_LCD | ||
57 | #define S3C24XX_PA_UART S3C2400_PA_UART | ||
58 | #define S3C24XX_PA_TIMER S3C2400_PA_TIMER | ||
59 | #define S3C24XX_PA_USBDEV S3C2400_PA_USBDEV | ||
60 | #define S3C24XX_PA_WATCHDOG S3C2400_PA_WATCHDOG | ||
61 | #define S3C24XX_PA_IIC S3C2400_PA_IIC | ||
62 | #define S3C24XX_PA_IIS S3C2400_PA_IIS | ||
63 | #define S3C24XX_PA_GPIO S3C2400_PA_GPIO | ||
64 | #define S3C24XX_PA_RTC S3C2400_PA_RTC | ||
65 | #define S3C24XX_PA_ADC S3C2400_PA_ADC | ||
66 | #define S3C24XX_PA_SPI S3C2400_PA_SPI | ||
diff --git a/include/asm-arm/arch-s3c2400/memory.h b/include/asm-arm/arch-s3c2400/memory.h new file mode 100644 index 000000000000..fb0381dde704 --- /dev/null +++ b/include/asm-arm/arch-s3c2400/memory.h | |||
@@ -0,0 +1,23 @@ | |||
1 | /* linux/include/asm-arm/arch-s3c2400/memory.h | ||
2 | * from linux/include/asm-arm/arch-rpc/memory.h | ||
3 | * | ||
4 | * Copyright 2007 Simtec Electronics | ||
5 | * http://armlinux.simtec.co.uk/ | ||
6 | * Ben Dooks <ben@simtec.co.uk> | ||
7 | * | ||
8 | * Copyright (C) 1996,1997,1998 Russell King. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #ifndef __ASM_ARCH_MEMORY_H | ||
16 | #define __ASM_ARCH_MEMORY_H | ||
17 | |||
18 | #define PHYS_OFFSET UL(0x0C000000) | ||
19 | |||
20 | #define __virt_to_bus(x) __virt_to_phys(x) | ||
21 | #define __bus_to_virt(x) __phys_to_virt(x) | ||
22 | |||
23 | #endif | ||
diff --git a/include/asm-arm/arch-s3c2410/debug-macro.S b/include/asm-arm/arch-s3c2410/debug-macro.S index 93064860e0e5..9c8cd9abb82b 100644 --- a/include/asm-arm/arch-s3c2410/debug-macro.S +++ b/include/asm-arm/arch-s3c2410/debug-macro.S | |||
@@ -13,32 +13,23 @@ | |||
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <asm/arch/map.h> | 15 | #include <asm/arch/map.h> |
16 | #include <asm/arch/regs-serial.h> | ||
17 | #include <asm/arch/regs-gpio.h> | 16 | #include <asm/arch/regs-gpio.h> |
17 | #include <asm/plat-s3c/regs-serial.h> | ||
18 | 18 | ||
19 | #define S3C2410_UART1_OFF (0x4000) | 19 | #define S3C2410_UART1_OFF (0x4000) |
20 | #define SHIFT_2440TXF (14-9) | 20 | #define SHIFT_2440TXF (14-9) |
21 | 21 | ||
22 | .macro addruart, rx | 22 | .macro addruart, rx |
23 | mrc p15, 0, \rx, c1, c0 | 23 | mrc p15, 0, \rx, c1, c0 |
24 | tst \rx, #1 | 24 | tst \rx, #1 |
25 | ldreq \rx, = S3C24XX_PA_UART | 25 | ldreq \rx, = S3C24XX_PA_UART |
26 | ldrne \rx, = S3C24XX_VA_UART | 26 | ldrne \rx, = S3C24XX_VA_UART |
27 | #if CONFIG_DEBUG_S3C2410_UART != 0 | 27 | #if CONFIG_DEBUG_S3C_UART != 0 |
28 | add \rx, \rx, #(S3C2410_UART1_OFF * CONFIG_DEBUG_S3C2410_UART) | 28 | add \rx, \rx, #(S3C2410_UART1_OFF * CONFIG_DEBUG_S3C_UART) |
29 | #endif | 29 | #endif |
30 | .endm | 30 | .endm |
31 | 31 | ||
32 | .macro senduart,rd,rx | 32 | .macro fifo_full_s3c24xx rd, rx |
33 | strb \rd, [\rx, # S3C2410_UTXH ] | ||
34 | .endm | ||
35 | |||
36 | .macro busyuart, rd, rx | ||
37 | ldr \rd, [ \rx, # S3C2410_UFCON ] | ||
38 | tst \rd, #S3C2410_UFCON_FIFOMODE @ fifo enabled? | ||
39 | beq 1001f @ | ||
40 | @ FIFO enabled... | ||
41 | 1003: | ||
42 | @ check for arm920 vs arm926. currently assume all arm926 | 33 | @ check for arm920 vs arm926. currently assume all arm926 |
43 | @ devices have an 64 byte FIFO identical to the s3c2440 | 34 | @ devices have an 64 byte FIFO identical to the s3c2440 |
44 | mrc p15, 0, \rd, c0, c0 | 35 | mrc p15, 0, \rd, c0, c0 |
@@ -57,25 +48,22 @@ | |||
57 | ldr \rd, [ \rx, # S3C2410_UFSTAT ] | 48 | ldr \rd, [ \rx, # S3C2410_UFSTAT ] |
58 | moveq \rd, \rd, lsr #SHIFT_2440TXF | 49 | moveq \rd, \rd, lsr #SHIFT_2440TXF |
59 | tst \rd, #S3C2410_UFSTAT_TXFULL | 50 | tst \rd, #S3C2410_UFSTAT_TXFULL |
60 | bne 1003b | 51 | .endm |
61 | b 1002f | ||
62 | |||
63 | 1001: | ||
64 | @ busy waiting for non fifo | ||
65 | ldr \rd, [ \rx, # S3C2410_UTRSTAT ] | ||
66 | tst \rd, #S3C2410_UTRSTAT_TXFE | ||
67 | beq 1001b | ||
68 | 52 | ||
69 | 1002: @ exit busyuart | 53 | .macro fifo_full_s3c2410 rd, rx |
70 | .endm | 54 | ldr \rd, [ \rx, # S3C2410_UFSTAT ] |
55 | tst \rd, #S3C2410_UFSTAT_TXFULL | ||
56 | .endm | ||
71 | 57 | ||
72 | .macro waituart,rd,rx | 58 | /* fifo level reading */ |
73 | 59 | ||
74 | ldr \rd, [ \rx, # S3C2410_UFCON ] | 60 | .macro fifo_level_s3c24xx rd, rx |
75 | tst \rd, #S3C2410_UFCON_FIFOMODE @ fifo enabled? | 61 | @ check for arm920 vs arm926. currently assume all arm926 |
76 | beq 1001f @ | 62 | @ devices have an 64 byte FIFO identical to the s3c2440 |
77 | @ FIFO enabled... | 63 | mrc p15, 0, \rd, c0, c0 |
78 | 1003: | 64 | and \rd, \rd, #0xff0 |
65 | teq \rd, #0x260 | ||
66 | beq 10000f | ||
79 | mrc p15, 0, \rd, c1, c0 | 67 | mrc p15, 0, \rd, c1, c0 |
80 | tst \rd, #1 | 68 | tst \rd, #1 |
81 | addeq \rd, \rx, #(S3C24XX_PA_GPIO - S3C24XX_PA_UART) | 69 | addeq \rd, \rx, #(S3C24XX_PA_GPIO - S3C24XX_PA_UART) |
@@ -85,18 +73,32 @@ | |||
85 | and \rd, \rd, #0x00ff0000 | 73 | and \rd, \rd, #0x00ff0000 |
86 | teq \rd, #0x00440000 @ is it 2440? | 74 | teq \rd, #0x00440000 @ is it 2440? |
87 | 75 | ||
76 | 10000: | ||
88 | ldr \rd, [ \rx, # S3C2410_UFSTAT ] | 77 | ldr \rd, [ \rx, # S3C2410_UFSTAT ] |
89 | andne \rd, \rd, #S3C2410_UFSTAT_TXMASK | 78 | andne \rd, \rd, #S3C2410_UFSTAT_TXMASK |
90 | andeq \rd, \rd, #S3C2440_UFSTAT_TXMASK | 79 | andeq \rd, \rd, #S3C2440_UFSTAT_TXMASK |
91 | teq \rd, #0 | 80 | .endm |
92 | bne 1003b | 81 | |
93 | b 1002f | 82 | .macro fifo_level_s3c2410 rd, rx |
83 | ldr \rd, [ \rx, # S3C2410_UFSTAT ] | ||
84 | and \rd, \rd, #S3C2410_UFSTAT_TXMASK | ||
85 | .endm | ||
86 | |||
87 | /* Select the correct implementation depending on the configuration. The | ||
88 | * S3C2440 will get selected by default, as these are the most widely | ||
89 | * used variants of these | ||
90 | */ | ||
91 | |||
92 | #if defined(CONFIG_CPU_LLSERIAL_S3C2410_ONLY) | ||
93 | #define fifo_full fifo_full_s3c2410 | ||
94 | #define fifo_level fifo_level_s3c2410 | ||
95 | #warning 2410only | ||
96 | #elif !defined(CONFIG_CPU_LLSERIAL_S3C2440_ONLY) | ||
97 | #define fifo_full fifo_full_s3c24xx | ||
98 | #define fifo_level fifo_level_s3c24xx | ||
99 | #warning generic | ||
100 | #endif | ||
94 | 101 | ||
95 | 1001: | 102 | /* include the reset of the code which will do the work */ |
96 | @ idle waiting for non fifo | ||
97 | ldr \rd, [ \rx, # S3C2410_UTRSTAT ] | ||
98 | tst \rd, #S3C2410_UTRSTAT_TXFE | ||
99 | beq 1001b | ||
100 | 103 | ||
101 | 1002: @ exit busyuart | 104 | #include <asm/plat-s3c/debug-macro.S> |
102 | .endm | ||
diff --git a/include/asm-arm/arch-s3c2410/map.h b/include/asm-arm/arch-s3c2410/map.h index 19e77f038042..b33ed3b05ef5 100644 --- a/include/asm-arm/arch-s3c2410/map.h +++ b/include/asm-arm/arch-s3c2410/map.h | |||
@@ -13,58 +13,36 @@ | |||
13 | #ifndef __ASM_ARCH_MAP_H | 13 | #ifndef __ASM_ARCH_MAP_H |
14 | #define __ASM_ARCH_MAP_H | 14 | #define __ASM_ARCH_MAP_H |
15 | 15 | ||
16 | /* we have a bit of a tight squeeze to fit all our registers from | 16 | #include <asm/plat-s3c/map.h> |
17 | * 0xF00000000 upwards, since we use all of the nGCS space in some | ||
18 | * capacity, and also need to fit the S3C2410 registers in as well... | ||
19 | * | ||
20 | * we try to ensure stuff like the IRQ registers are available for | ||
21 | * an single MOVS instruction (ie, only 8 bits of set data) | ||
22 | * | ||
23 | * Note, we are trying to remove some of these from the implementation | ||
24 | * as they are only useful to certain drivers... | ||
25 | */ | ||
26 | |||
27 | #ifndef __ASSEMBLY__ | ||
28 | #define S3C2410_ADDR(x) ((void __iomem __force *)0xF0000000 + (x)) | ||
29 | #else | ||
30 | #define S3C2410_ADDR(x) (0xF0000000 + (x)) | ||
31 | #endif | ||
32 | 17 | ||
33 | #define S3C2400_ADDR(x) S3C2410_ADDR(x) | 18 | #define S3C2410_ADDR(x) S3C_ADDR(x) |
34 | 19 | ||
35 | /* interrupt controller is the first thing we put in, to make | 20 | /* interrupt controller is the first thing we put in, to make |
36 | * the assembly code for the irq detection easier | 21 | * the assembly code for the irq detection easier |
37 | */ | 22 | */ |
38 | #define S3C24XX_VA_IRQ S3C2410_ADDR(0x00000000) | 23 | #define S3C24XX_VA_IRQ S3C_VA_IRQ |
39 | #define S3C2400_PA_IRQ (0x14400000) | ||
40 | #define S3C2410_PA_IRQ (0x4A000000) | 24 | #define S3C2410_PA_IRQ (0x4A000000) |
41 | #define S3C24XX_SZ_IRQ SZ_1M | 25 | #define S3C24XX_SZ_IRQ SZ_1M |
42 | 26 | ||
43 | /* memory controller registers */ | 27 | /* memory controller registers */ |
44 | #define S3C24XX_VA_MEMCTRL S3C2410_ADDR(0x00100000) | 28 | #define S3C24XX_VA_MEMCTRL S3C_VA_MEM |
45 | #define S3C2400_PA_MEMCTRL (0x14000000) | ||
46 | #define S3C2410_PA_MEMCTRL (0x48000000) | 29 | #define S3C2410_PA_MEMCTRL (0x48000000) |
47 | #define S3C24XX_SZ_MEMCTRL SZ_1M | 30 | #define S3C24XX_SZ_MEMCTRL SZ_1M |
48 | 31 | ||
49 | /* USB host controller */ | 32 | /* USB host controller */ |
50 | #define S3C2400_PA_USBHOST (0x14200000) | ||
51 | #define S3C2410_PA_USBHOST (0x49000000) | 33 | #define S3C2410_PA_USBHOST (0x49000000) |
52 | #define S3C24XX_SZ_USBHOST SZ_1M | 34 | #define S3C24XX_SZ_USBHOST SZ_1M |
53 | 35 | ||
54 | /* DMA controller */ | 36 | /* DMA controller */ |
55 | #define S3C2400_PA_DMA (0x14600000) | ||
56 | #define S3C2410_PA_DMA (0x4B000000) | 37 | #define S3C2410_PA_DMA (0x4B000000) |
57 | #define S3C24XX_SZ_DMA SZ_1M | 38 | #define S3C24XX_SZ_DMA SZ_1M |
58 | 39 | ||
59 | /* Clock and Power management */ | 40 | /* Clock and Power management */ |
60 | #define S3C24XX_VA_CLKPWR S3C2410_ADDR(0x00200000) | 41 | #define S3C24XX_VA_CLKPWR S3C_VA_SYS |
61 | #define S3C2400_PA_CLKPWR (0x14800000) | ||
62 | #define S3C2410_PA_CLKPWR (0x4C000000) | 42 | #define S3C2410_PA_CLKPWR (0x4C000000) |
63 | #define S3C24XX_SZ_CLKPWR SZ_1M | 43 | #define S3C24XX_SZ_CLKPWR SZ_1M |
64 | 44 | ||
65 | /* LCD controller */ | 45 | /* LCD controller */ |
66 | #define S3C24XX_VA_LCD S3C2410_ADDR(0x00300000) | ||
67 | #define S3C2400_PA_LCD (0x14A00000) | ||
68 | #define S3C2410_PA_LCD (0x4D000000) | 46 | #define S3C2410_PA_LCD (0x4D000000) |
69 | #define S3C24XX_SZ_LCD SZ_1M | 47 | #define S3C24XX_SZ_LCD SZ_1M |
70 | 48 | ||
@@ -72,41 +50,30 @@ | |||
72 | #define S3C2410_PA_NAND (0x4E000000) | 50 | #define S3C2410_PA_NAND (0x4E000000) |
73 | #define S3C24XX_SZ_NAND SZ_1M | 51 | #define S3C24XX_SZ_NAND SZ_1M |
74 | 52 | ||
75 | /* MMC controller - available on the S3C2400 */ | ||
76 | #define S3C2400_PA_MMC (0x15A00000) | ||
77 | #define S3C2400_SZ_MMC SZ_1M | ||
78 | |||
79 | /* UARTs */ | 53 | /* UARTs */ |
80 | #define S3C24XX_VA_UART S3C2410_ADDR(0x00400000) | 54 | #define S3C24XX_VA_UART S3C_VA_UART |
81 | #define S3C2400_PA_UART (0x15000000) | ||
82 | #define S3C2410_PA_UART (0x50000000) | 55 | #define S3C2410_PA_UART (0x50000000) |
83 | #define S3C24XX_SZ_UART SZ_1M | 56 | #define S3C24XX_SZ_UART SZ_1M |
84 | 57 | ||
85 | /* Timers */ | 58 | /* Timers */ |
86 | #define S3C24XX_VA_TIMER S3C2410_ADDR(0x00500000) | 59 | #define S3C24XX_VA_TIMER S3C_VA_TIMER |
87 | #define S3C2400_PA_TIMER (0x15100000) | ||
88 | #define S3C2410_PA_TIMER (0x51000000) | 60 | #define S3C2410_PA_TIMER (0x51000000) |
89 | #define S3C24XX_SZ_TIMER SZ_1M | 61 | #define S3C24XX_SZ_TIMER SZ_1M |
90 | 62 | ||
91 | /* USB Device port */ | 63 | /* USB Device port */ |
92 | #define S3C24XX_VA_USBDEV S3C2410_ADDR(0x00600000) | ||
93 | #define S3C2400_PA_USBDEV (0x15200140) | ||
94 | #define S3C2410_PA_USBDEV (0x52000000) | 64 | #define S3C2410_PA_USBDEV (0x52000000) |
95 | #define S3C24XX_SZ_USBDEV SZ_1M | 65 | #define S3C24XX_SZ_USBDEV SZ_1M |
96 | 66 | ||
97 | /* Watchdog */ | 67 | /* Watchdog */ |
98 | #define S3C24XX_VA_WATCHDOG S3C2410_ADDR(0x00700000) | 68 | #define S3C24XX_VA_WATCHDOG S3C_VA_WATCHDOG |
99 | #define S3C2400_PA_WATCHDOG (0x15300000) | ||
100 | #define S3C2410_PA_WATCHDOG (0x53000000) | 69 | #define S3C2410_PA_WATCHDOG (0x53000000) |
101 | #define S3C24XX_SZ_WATCHDOG SZ_1M | 70 | #define S3C24XX_SZ_WATCHDOG SZ_1M |
102 | 71 | ||
103 | /* IIC hardware controller */ | 72 | /* IIC hardware controller */ |
104 | #define S3C2400_PA_IIC (0x15400000) | ||
105 | #define S3C2410_PA_IIC (0x54000000) | 73 | #define S3C2410_PA_IIC (0x54000000) |
106 | #define S3C24XX_SZ_IIC SZ_1M | 74 | #define S3C24XX_SZ_IIC SZ_1M |
107 | 75 | ||
108 | /* IIS controller */ | 76 | /* IIS controller */ |
109 | #define S3C2400_PA_IIS (0x15508000) | ||
110 | #define S3C2410_PA_IIS (0x55000000) | 77 | #define S3C2410_PA_IIS (0x55000000) |
111 | #define S3C24XX_SZ_IIS SZ_1M | 78 | #define S3C24XX_SZ_IIS SZ_1M |
112 | 79 | ||
@@ -116,27 +83,23 @@ | |||
116 | * it is the same distance apart from the UART in the | 83 | * it is the same distance apart from the UART in the |
117 | * phsyical address space, as the initial mapping for the IO | 84 | * phsyical address space, as the initial mapping for the IO |
118 | * is done as a 1:1 maping. This puts it (currently) at | 85 | * is done as a 1:1 maping. This puts it (currently) at |
119 | * 0xF6800000, which is not in the way of any current mapping | 86 | * 0xFA800000, which is not in the way of any current mapping |
120 | * by the base system. | 87 | * by the base system. |
121 | */ | 88 | */ |
122 | 89 | ||
123 | #define S3C2400_PA_GPIO (0x15600000) | ||
124 | #define S3C2410_PA_GPIO (0x56000000) | 90 | #define S3C2410_PA_GPIO (0x56000000) |
125 | #define S3C24XX_VA_GPIO ((S3C2410_PA_GPIO - S3C24XX_PA_UART) + S3C24XX_VA_UART) | 91 | #define S3C24XX_VA_GPIO ((S3C2410_PA_GPIO - S3C24XX_PA_UART) + S3C24XX_VA_UART) |
126 | #define S3C24XX_SZ_GPIO SZ_1M | 92 | #define S3C24XX_SZ_GPIO SZ_1M |
127 | 93 | ||
128 | /* RTC */ | 94 | /* RTC */ |
129 | #define S3C2400_PA_RTC (0x15700040) | ||
130 | #define S3C2410_PA_RTC (0x57000000) | 95 | #define S3C2410_PA_RTC (0x57000000) |
131 | #define S3C24XX_SZ_RTC SZ_1M | 96 | #define S3C24XX_SZ_RTC SZ_1M |
132 | 97 | ||
133 | /* ADC */ | 98 | /* ADC */ |
134 | #define S3C2400_PA_ADC (0x15800000) | ||
135 | #define S3C2410_PA_ADC (0x58000000) | 99 | #define S3C2410_PA_ADC (0x58000000) |
136 | #define S3C24XX_SZ_ADC SZ_1M | 100 | #define S3C24XX_SZ_ADC SZ_1M |
137 | 101 | ||
138 | /* SPI */ | 102 | /* SPI */ |
139 | #define S3C2400_PA_SPI (0x15900000) | ||
140 | #define S3C2410_PA_SPI (0x59000000) | 103 | #define S3C2410_PA_SPI (0x59000000) |
141 | #define S3C24XX_SZ_SPI SZ_1M | 104 | #define S3C24XX_SZ_SPI SZ_1M |
142 | 105 | ||
@@ -177,37 +140,8 @@ | |||
177 | 140 | ||
178 | #define S3C2410_SDRAM_PA (S3C2410_CS6) | 141 | #define S3C2410_SDRAM_PA (S3C2410_CS6) |
179 | 142 | ||
180 | #define S3C2400_CS0 (0x00000000) | ||
181 | #define S3C2400_CS1 (0x02000000) | ||
182 | #define S3C2400_CS2 (0x04000000) | ||
183 | #define S3C2400_CS3 (0x06000000) | ||
184 | #define S3C2400_CS4 (0x08000000) | ||
185 | #define S3C2400_CS5 (0x0A000000) | ||
186 | #define S3C2400_CS6 (0x0C000000) | ||
187 | #define S3C2400_CS7 (0x0E000000) | ||
188 | |||
189 | #define S3C2400_SDRAM_PA (S3C2400_CS6) | ||
190 | |||
191 | /* Use a single interface for common resources between S3C24XX cpus */ | 143 | /* Use a single interface for common resources between S3C24XX cpus */ |
192 | 144 | ||
193 | #ifdef CONFIG_CPU_S3C2400 | ||
194 | #define S3C24XX_PA_IRQ S3C2400_PA_IRQ | ||
195 | #define S3C24XX_PA_MEMCTRL S3C2400_PA_MEMCTRL | ||
196 | #define S3C24XX_PA_USBHOST S3C2400_PA_USBHOST | ||
197 | #define S3C24XX_PA_DMA S3C2400_PA_DMA | ||
198 | #define S3C24XX_PA_CLKPWR S3C2400_PA_CLKPWR | ||
199 | #define S3C24XX_PA_LCD S3C2400_PA_LCD | ||
200 | #define S3C24XX_PA_UART S3C2400_PA_UART | ||
201 | #define S3C24XX_PA_TIMER S3C2400_PA_TIMER | ||
202 | #define S3C24XX_PA_USBDEV S3C2400_PA_USBDEV | ||
203 | #define S3C24XX_PA_WATCHDOG S3C2400_PA_WATCHDOG | ||
204 | #define S3C24XX_PA_IIC S3C2400_PA_IIC | ||
205 | #define S3C24XX_PA_IIS S3C2400_PA_IIS | ||
206 | #define S3C24XX_PA_GPIO S3C2400_PA_GPIO | ||
207 | #define S3C24XX_PA_RTC S3C2400_PA_RTC | ||
208 | #define S3C24XX_PA_ADC S3C2400_PA_ADC | ||
209 | #define S3C24XX_PA_SPI S3C2400_PA_SPI | ||
210 | #else | ||
211 | #define S3C24XX_PA_IRQ S3C2410_PA_IRQ | 145 | #define S3C24XX_PA_IRQ S3C2410_PA_IRQ |
212 | #define S3C24XX_PA_MEMCTRL S3C2410_PA_MEMCTRL | 146 | #define S3C24XX_PA_MEMCTRL S3C2410_PA_MEMCTRL |
213 | #define S3C24XX_PA_USBHOST S3C2410_PA_USBHOST | 147 | #define S3C24XX_PA_USBHOST S3C2410_PA_USBHOST |
@@ -224,7 +158,6 @@ | |||
224 | #define S3C24XX_PA_RTC S3C2410_PA_RTC | 158 | #define S3C24XX_PA_RTC S3C2410_PA_RTC |
225 | #define S3C24XX_PA_ADC S3C2410_PA_ADC | 159 | #define S3C24XX_PA_ADC S3C2410_PA_ADC |
226 | #define S3C24XX_PA_SPI S3C2410_PA_SPI | 160 | #define S3C24XX_PA_SPI S3C2410_PA_SPI |
227 | #endif | ||
228 | 161 | ||
229 | /* deal with the registers that move under the 2412/2413 */ | 162 | /* deal with the registers that move under the 2412/2413 */ |
230 | 163 | ||
diff --git a/include/asm-arm/arch-s3c2410/memory.h b/include/asm-arm/arch-s3c2410/memory.h index 4be6a74c4303..533e2436e707 100644 --- a/include/asm-arm/arch-s3c2410/memory.h +++ b/include/asm-arm/arch-s3c2410/memory.h | |||
@@ -11,20 +11,7 @@ | |||
11 | #ifndef __ASM_ARCH_MEMORY_H | 11 | #ifndef __ASM_ARCH_MEMORY_H |
12 | #define __ASM_ARCH_MEMORY_H | 12 | #define __ASM_ARCH_MEMORY_H |
13 | 13 | ||
14 | /* | ||
15 | * DRAM starts at 0x30000000 for S3C2410/S3C2440 | ||
16 | * and at 0x0C000000 for S3C2400 | ||
17 | */ | ||
18 | #ifdef CONFIG_CPU_S3C2400 | ||
19 | #define PHYS_OFFSET UL(0x0C000000) | ||
20 | #else | ||
21 | #define PHYS_OFFSET UL(0x30000000) | 14 | #define PHYS_OFFSET UL(0x30000000) |
22 | #endif | ||
23 | |||
24 | /* | ||
25 | * These are exactly the same on the S3C2410 as the | ||
26 | * physical memory view. | ||
27 | */ | ||
28 | 15 | ||
29 | #define __virt_to_bus(x) __virt_to_phys(x) | 16 | #define __virt_to_bus(x) __virt_to_phys(x) |
30 | #define __bus_to_virt(x) __phys_to_virt(x) | 17 | #define __bus_to_virt(x) __phys_to_virt(x) |
diff --git a/include/asm-arm/arch-s3c2410/regs-lcd.h b/include/asm-arm/arch-s3c2410/regs-lcd.h index b7faeb04c0ff..76fe5f693426 100644 --- a/include/asm-arm/arch-s3c2410/regs-lcd.h +++ b/include/asm-arm/arch-s3c2410/regs-lcd.h | |||
@@ -12,7 +12,7 @@ | |||
12 | #ifndef ___ASM_ARCH_REGS_LCD_H | 12 | #ifndef ___ASM_ARCH_REGS_LCD_H |
13 | #define ___ASM_ARCH_REGS_LCD_H "$Id: lcd.h,v 1.3 2003/06/26 13:25:06 ben Exp $" | 13 | #define ___ASM_ARCH_REGS_LCD_H "$Id: lcd.h,v 1.3 2003/06/26 13:25:06 ben Exp $" |
14 | 14 | ||
15 | #define S3C2410_LCDREG(x) ((x) + S3C24XX_VA_LCD) | 15 | #define S3C2410_LCDREG(x) (x) |
16 | 16 | ||
17 | /* LCD control registers */ | 17 | /* LCD control registers */ |
18 | #define S3C2410_LCDCON1 S3C2410_LCDREG(0x00) | 18 | #define S3C2410_LCDCON1 S3C2410_LCDREG(0x00) |
diff --git a/include/asm-arm/arch-s3c2410/system.h b/include/asm-arm/arch-s3c2410/system.h index 1c74ef17da33..63891786dfa0 100644 --- a/include/asm-arm/arch-s3c2410/system.h +++ b/include/asm-arm/arch-s3c2410/system.h | |||
@@ -17,7 +17,7 @@ | |||
17 | #include <asm/arch/idle.h> | 17 | #include <asm/arch/idle.h> |
18 | #include <asm/arch/reset.h> | 18 | #include <asm/arch/reset.h> |
19 | 19 | ||
20 | #include <asm/arch/regs-watchdog.h> | 20 | #include <asm/plat-s3c/regs-watchdog.h> |
21 | #include <asm/arch/regs-clock.h> | 21 | #include <asm/arch/regs-clock.h> |
22 | 22 | ||
23 | void (*s3c24xx_idle)(void); | 23 | void (*s3c24xx_idle)(void); |
diff --git a/include/asm-arm/arch-s3c2410/uncompress.h b/include/asm-arm/arch-s3c2410/uncompress.h index dcb2cef38f50..48a5731ee988 100644 --- a/include/asm-arm/arch-s3c2410/uncompress.h +++ b/include/asm-arm/arch-s3c2410/uncompress.h | |||
@@ -1,6 +1,7 @@ | |||
1 | /* linux/include/asm-arm/arch-s3c2410/uncompress.h | 1 | /* linux/include/asm-arm/arch-s3c2410/uncompress.h |
2 | * | 2 | * |
3 | * Copyright (c) 2003 Simtec Electronics | 3 | * Copyright (c) 2003, 2007 Simtec Electronics |
4 | * http://armlinux.simtec.co.uk/ | ||
4 | * Ben Dooks <ben@simtec.co.uk> | 5 | * Ben Dooks <ben@simtec.co.uk> |
5 | * | 6 | * |
6 | * S3C2410 - uncompress code | 7 | * S3C2410 - uncompress code |
@@ -13,153 +14,39 @@ | |||
13 | #ifndef __ASM_ARCH_UNCOMPRESS_H | 14 | #ifndef __ASM_ARCH_UNCOMPRESS_H |
14 | #define __ASM_ARCH_UNCOMPRESS_H | 15 | #define __ASM_ARCH_UNCOMPRESS_H |
15 | 16 | ||
16 | typedef unsigned int upf_t; /* cannot include linux/serial_core.h */ | 17 | #include <asm/arch/regs-gpio.h> |
17 | |||
18 | /* defines for UART registers */ | ||
19 | #include "asm/arch/regs-serial.h" | ||
20 | #include "asm/arch/regs-gpio.h" | ||
21 | #include "asm/arch/regs-watchdog.h" | ||
22 | |||
23 | #include <asm/arch/map.h> | 18 | #include <asm/arch/map.h> |
24 | 19 | ||
25 | /* working in physical space... */ | 20 | /* working in physical space... */ |
26 | #undef S3C2410_GPIOREG | 21 | #undef S3C2410_GPIOREG |
27 | #undef S3C2410_WDOGREG | ||
28 | |||
29 | #define S3C2410_GPIOREG(x) ((S3C24XX_PA_GPIO + (x))) | 22 | #define S3C2410_GPIOREG(x) ((S3C24XX_PA_GPIO + (x))) |
30 | #define S3C2410_WDOGREG(x) ((S3C24XX_PA_WATCHDOG + (x))) | ||
31 | 23 | ||
32 | /* how many bytes we allow into the FIFO at a time in FIFO mode */ | 24 | #include <asm/plat-s3c/uncompress.h> |
33 | #define FIFO_MAX (14) | ||
34 | 25 | ||
35 | #define uart_base S3C24XX_PA_UART + (0x4000*CONFIG_S3C2410_LOWLEVEL_UART_PORT) | 26 | static inline int is_arm926(void) |
36 | |||
37 | static __inline__ void | ||
38 | uart_wr(unsigned int reg, unsigned int val) | ||
39 | { | 27 | { |
40 | volatile unsigned int *ptr; | 28 | unsigned int cpuid; |
41 | |||
42 | ptr = (volatile unsigned int *)(reg + uart_base); | ||
43 | *ptr = val; | ||
44 | } | ||
45 | 29 | ||
46 | static __inline__ unsigned int | 30 | asm volatile ("mrc p15, 0, %0, c1, c0, 0" : "=r" (cpuid)); |
47 | uart_rd(unsigned int reg) | ||
48 | { | ||
49 | volatile unsigned int *ptr; | ||
50 | 31 | ||
51 | ptr = (volatile unsigned int *)(reg + uart_base); | 32 | return ((cpuid & 0xff0) == 0x260); |
52 | return *ptr; | ||
53 | } | 33 | } |
54 | 34 | ||
55 | 35 | static void arch_detect_cpu(void) | |
56 | /* we can deal with the case the UARTs are being run | ||
57 | * in FIFO mode, so that we don't hold up our execution | ||
58 | * waiting for tx to happen... | ||
59 | */ | ||
60 | |||
61 | static void putc(int ch) | ||
62 | { | 36 | { |
63 | int cpuid = S3C2410_GSTATUS1_2410; | 37 | unsigned int cpuid; |
64 | 38 | ||
65 | #ifndef CONFIG_CPU_S3C2400 | ||
66 | cpuid = *((volatile unsigned int *)S3C2410_GSTATUS1); | 39 | cpuid = *((volatile unsigned int *)S3C2410_GSTATUS1); |
67 | cpuid &= S3C2410_GSTATUS1_IDMASK; | 40 | cpuid &= S3C2410_GSTATUS1_IDMASK; |
68 | #endif | ||
69 | |||
70 | if (uart_rd(S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE) { | ||
71 | int level; | ||
72 | |||
73 | while (1) { | ||
74 | level = uart_rd(S3C2410_UFSTAT); | ||
75 | |||
76 | if (cpuid == S3C2410_GSTATUS1_2440 || | ||
77 | cpuid == S3C2410_GSTATUS1_2442) { | ||
78 | level &= S3C2440_UFSTAT_TXMASK; | ||
79 | level >>= S3C2440_UFSTAT_TXSHIFT; | ||
80 | } else { | ||
81 | level &= S3C2410_UFSTAT_TXMASK; | ||
82 | level >>= S3C2410_UFSTAT_TXSHIFT; | ||
83 | } | ||
84 | |||
85 | if (level < FIFO_MAX) | ||
86 | break; | ||
87 | } | ||
88 | 41 | ||
42 | if (is_arm926() || cpuid == S3C2410_GSTATUS1_2440 || | ||
43 | cpuid == S3C2410_GSTATUS1_2442) { | ||
44 | fifo_mask = S3C2440_UFSTAT_TXMASK; | ||
45 | fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT; | ||
89 | } else { | 46 | } else { |
90 | /* not using fifos */ | 47 | fifo_mask = S3C2410_UFSTAT_TXMASK; |
91 | 48 | fifo_max = 15 << S3C2410_UFSTAT_TXSHIFT; | |
92 | while ((uart_rd(S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE) != S3C2410_UTRSTAT_TXE) | ||
93 | barrier(); | ||
94 | } | 49 | } |
95 | |||
96 | /* write byte to transmission register */ | ||
97 | uart_wr(S3C2410_UTXH, ch); | ||
98 | } | 50 | } |
99 | 51 | ||
100 | static inline void flush(void) | ||
101 | { | ||
102 | } | ||
103 | |||
104 | #define __raw_writel(d,ad) do { *((volatile unsigned int *)(ad)) = (d); } while(0) | ||
105 | |||
106 | /* CONFIG_S3C2410_BOOT_WATCHDOG | ||
107 | * | ||
108 | * Simple boot-time watchdog setup, to reboot the system if there is | ||
109 | * any problem with the boot process | ||
110 | */ | ||
111 | |||
112 | #ifdef CONFIG_S3C2410_BOOT_WATCHDOG | ||
113 | |||
114 | #define WDOG_COUNT (0xff00) | ||
115 | |||
116 | static inline void arch_decomp_wdog(void) | ||
117 | { | ||
118 | __raw_writel(WDOG_COUNT, S3C2410_WTCNT); | ||
119 | } | ||
120 | |||
121 | static void arch_decomp_wdog_start(void) | ||
122 | { | ||
123 | __raw_writel(WDOG_COUNT, S3C2410_WTDAT); | ||
124 | __raw_writel(WDOG_COUNT, S3C2410_WTCNT); | ||
125 | __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x80), S3C2410_WTCON); | ||
126 | } | ||
127 | |||
128 | #else | ||
129 | #define arch_decomp_wdog_start() | ||
130 | #define arch_decomp_wdog() | ||
131 | #endif | ||
132 | |||
133 | #ifdef CONFIG_S3C2410_BOOT_ERROR_RESET | ||
134 | |||
135 | static void arch_decomp_error(const char *x) | ||
136 | { | ||
137 | putstr("\n\n"); | ||
138 | putstr(x); | ||
139 | putstr("\n\n -- System resetting\n"); | ||
140 | |||
141 | __raw_writel(0x4000, S3C2410_WTDAT); | ||
142 | __raw_writel(0x4000, S3C2410_WTCNT); | ||
143 | __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x40), S3C2410_WTCON); | ||
144 | |||
145 | while(1); | ||
146 | } | ||
147 | |||
148 | #define arch_error arch_decomp_error | ||
149 | #endif | ||
150 | |||
151 | static void error(char *err); | ||
152 | |||
153 | static void | ||
154 | arch_decomp_setup(void) | ||
155 | { | ||
156 | /* we may need to setup the uart(s) here if we are not running | ||
157 | * on an BAST... the BAST will have left the uarts configured | ||
158 | * after calling linux. | ||
159 | */ | ||
160 | |||
161 | arch_decomp_wdog_start(); | ||
162 | } | ||
163 | |||
164 | |||
165 | #endif /* __ASM_ARCH_UNCOMPRESS_H */ | 52 | #endif /* __ASM_ARCH_UNCOMPRESS_H */ |
diff --git a/include/asm-arm/arch-sa1100/jornada720.h b/include/asm-arm/arch-sa1100/jornada720.h new file mode 100644 index 000000000000..45d2bb59f9d0 --- /dev/null +++ b/include/asm-arm/arch-sa1100/jornada720.h | |||
@@ -0,0 +1,27 @@ | |||
1 | /* | ||
2 | * include/asm-arm/arch-sa1100/jornada720.h | ||
3 | * | ||
4 | * This file contains SSP/MCU communication definitions for HP Jornada 710/720/728 | ||
5 | * | ||
6 | * Copyright (C) 2007 Kristoffer Ericson <Kristoffer.Ericson@gmail.com> | ||
7 | * Copyright (C) 2000 John Ankcorn <jca@lcs.mit.edu> | ||
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 version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | /* HP Jornada 7xx microprocessor commands */ | ||
16 | #define GETBATTERYDATA 0xc0 | ||
17 | #define GETSCANKEYCODE 0x90 | ||
18 | #define GETTOUCHSAMPLES 0xa0 | ||
19 | #define GETCONTRAST 0xD0 | ||
20 | #define SETCONTRAST 0xD1 | ||
21 | #define GETBRIGHTNESS 0xD2 | ||
22 | #define SETBRIGHTNESS 0xD3 | ||
23 | #define CONTRASTOFF 0xD8 | ||
24 | #define BRIGHTNESSOFF 0xD9 | ||
25 | #define PWMOFF 0xDF | ||
26 | #define TXDUMMY 0x11 | ||
27 | #define ERRORCODE 0x00 | ||
diff --git a/include/asm-arm/elf.h b/include/asm-arm/elf.h index d7a777f05088..ec1c685562ce 100644 --- a/include/asm-arm/elf.h +++ b/include/asm-arm/elf.h | |||
@@ -1,13 +1,14 @@ | |||
1 | #ifndef __ASMARM_ELF_H | 1 | #ifndef __ASMARM_ELF_H |
2 | #define __ASMARM_ELF_H | 2 | #define __ASMARM_ELF_H |
3 | 3 | ||
4 | #include <asm/hwcap.h> | ||
5 | |||
4 | #ifndef __ASSEMBLY__ | 6 | #ifndef __ASSEMBLY__ |
5 | /* | 7 | /* |
6 | * ELF register definitions.. | 8 | * ELF register definitions.. |
7 | */ | 9 | */ |
8 | #include <asm/ptrace.h> | 10 | #include <asm/ptrace.h> |
9 | #include <asm/user.h> | 11 | #include <asm/user.h> |
10 | #include <asm/hwcap.h> | ||
11 | 12 | ||
12 | typedef unsigned long elf_greg_t; | 13 | typedef unsigned long elf_greg_t; |
13 | typedef unsigned long elf_freg_t[3]; | 14 | typedef unsigned long elf_freg_t[3]; |
diff --git a/include/asm-arm/floppy.h b/include/asm-arm/floppy.h index 54b5ae44ed94..d595c15166a4 100644 --- a/include/asm-arm/floppy.h +++ b/include/asm-arm/floppy.h | |||
@@ -30,15 +30,21 @@ | |||
30 | #define fd_disable_irq() disable_irq(IRQ_FLOPPYDISK) | 30 | #define fd_disable_irq() disable_irq(IRQ_FLOPPYDISK) |
31 | #define fd_enable_irq() enable_irq(IRQ_FLOPPYDISK) | 31 | #define fd_enable_irq() enable_irq(IRQ_FLOPPYDISK) |
32 | 32 | ||
33 | static inline int fd_dma_setup(void *data, unsigned int length, | ||
34 | unsigned int mode, unsigned long addr) | ||
35 | { | ||
36 | set_dma_mode(DMA_FLOPPY, mode); | ||
37 | __set_dma_addr(DMA_FLOPPY, data); | ||
38 | set_dma_count(DMA_FLOPPY, length); | ||
39 | virtual_dma_port = addr; | ||
40 | enable_dma(DMA_FLOPPY); | ||
41 | return 0; | ||
42 | } | ||
43 | #define fd_dma_setup fd_dma_setup | ||
44 | |||
33 | #define fd_request_dma() request_dma(DMA_FLOPPY,"floppy") | 45 | #define fd_request_dma() request_dma(DMA_FLOPPY,"floppy") |
34 | #define fd_free_dma() free_dma(DMA_FLOPPY) | 46 | #define fd_free_dma() free_dma(DMA_FLOPPY) |
35 | #define fd_disable_dma() disable_dma(DMA_FLOPPY) | 47 | #define fd_disable_dma() disable_dma(DMA_FLOPPY) |
36 | #define fd_enable_dma() enable_dma(DMA_FLOPPY) | ||
37 | #define fd_clear_dma_ff() clear_dma_ff(DMA_FLOPPY) | ||
38 | #define fd_set_dma_mode(mode) set_dma_mode(DMA_FLOPPY, (mode)) | ||
39 | #define fd_set_dma_addr(addr) set_dma_addr(DMA_FLOPPY, virt_to_bus((addr))) | ||
40 | #define fd_set_dma_count(len) set_dma_count(DMA_FLOPPY, (len)) | ||
41 | #define fd_cacheflush(addr,sz) | ||
42 | 48 | ||
43 | /* need to clean up dma.h */ | 49 | /* need to clean up dma.h */ |
44 | #define DMA_FLOPPYDISK DMA_FLOPPY | 50 | #define DMA_FLOPPYDISK DMA_FLOPPY |
diff --git a/include/asm-arm/hardware/iop3xx.h b/include/asm-arm/hardware/iop3xx.h index 81ca5d3e2bff..fb90b421f31c 100644 --- a/include/asm-arm/hardware/iop3xx.h +++ b/include/asm-arm/hardware/iop3xx.h | |||
@@ -194,6 +194,13 @@ extern int init_atu; | |||
194 | #define IOP_TMR_PRIVILEGED 0x08 | 194 | #define IOP_TMR_PRIVILEGED 0x08 |
195 | #define IOP_TMR_RATIO_1_1 0x00 | 195 | #define IOP_TMR_RATIO_1_1 0x00 |
196 | 196 | ||
197 | /* Watchdog timer definitions */ | ||
198 | #define IOP_WDTCR_EN_ARM 0x1e1e1e1e | ||
199 | #define IOP_WDTCR_EN 0xe1e1e1e1 | ||
200 | /* iop3xx does not support stopping the watchdog, so we just re-arm */ | ||
201 | #define IOP_WDTCR_DIS_ARM (IOP_WDTCR_EN_ARM) | ||
202 | #define IOP_WDTCR_DIS (IOP_WDTCR_EN) | ||
203 | |||
197 | /* Application accelerator unit */ | 204 | /* Application accelerator unit */ |
198 | #define IOP3XX_AAU_PHYS_BASE (IOP3XX_PERIPHERAL_PHYS_BASE + 0x800) | 205 | #define IOP3XX_AAU_PHYS_BASE (IOP3XX_PERIPHERAL_PHYS_BASE + 0x800) |
199 | #define IOP3XX_AAU_UPPER_PA (IOP3XX_AAU_PHYS_BASE + 0xa7) | 206 | #define IOP3XX_AAU_UPPER_PA (IOP3XX_AAU_PHYS_BASE + 0xa7) |
@@ -274,6 +281,32 @@ static inline void write_tisr(u32 val) | |||
274 | asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (val)); | 281 | asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (val)); |
275 | } | 282 | } |
276 | 283 | ||
284 | static inline u32 read_wdtcr(void) | ||
285 | { | ||
286 | u32 val; | ||
287 | asm volatile("mrc p6, 0, %0, c7, c1, 0":"=r" (val)); | ||
288 | return val; | ||
289 | } | ||
290 | static inline void write_wdtcr(u32 val) | ||
291 | { | ||
292 | asm volatile("mcr p6, 0, %0, c7, c1, 0"::"r" (val)); | ||
293 | } | ||
294 | |||
295 | extern unsigned long get_iop_tick_rate(void); | ||
296 | |||
297 | /* only iop13xx has these registers, we define these to present a | ||
298 | * common register interface for the iop_wdt driver. | ||
299 | */ | ||
300 | #define IOP_RCSR_WDT (0) | ||
301 | static inline u32 read_rcsr(void) | ||
302 | { | ||
303 | return 0; | ||
304 | } | ||
305 | static inline void write_wdtsr(u32 val) | ||
306 | { | ||
307 | do { } while (0); | ||
308 | } | ||
309 | |||
277 | extern struct platform_device iop3xx_dma_0_channel; | 310 | extern struct platform_device iop3xx_dma_0_channel; |
278 | extern struct platform_device iop3xx_dma_1_channel; | 311 | extern struct platform_device iop3xx_dma_1_channel; |
279 | extern struct platform_device iop3xx_aau_channel; | 312 | extern struct platform_device iop3xx_aau_channel; |
diff --git a/include/asm-arm/pgtable-nommu.h b/include/asm-arm/pgtable-nommu.h index 0c8be19fd66b..b186bc820e30 100644 --- a/include/asm-arm/pgtable-nommu.h +++ b/include/asm-arm/pgtable-nommu.h | |||
@@ -102,7 +102,8 @@ extern int is_in_rom(unsigned long); | |||
102 | #define v4_tlb_fns (0) | 102 | #define v4_tlb_fns (0) |
103 | #define v4wb_tlb_fns (0) | 103 | #define v4wb_tlb_fns (0) |
104 | #define v4wbi_tlb_fns (0) | 104 | #define v4wbi_tlb_fns (0) |
105 | #define v6_tlb_fns (0) | 105 | #define v6wbi_tlb_fns (0) |
106 | #define v7wbi_tlb_fns (0) | ||
106 | 107 | ||
107 | #define v3_user_fns (0) | 108 | #define v3_user_fns (0) |
108 | #define v4_user_fns (0) | 109 | #define v4_user_fns (0) |
diff --git a/include/asm-arm/plat-s3c/debug-macro.S b/include/asm-arm/plat-s3c/debug-macro.S new file mode 100644 index 000000000000..84c40b847da8 --- /dev/null +++ b/include/asm-arm/plat-s3c/debug-macro.S | |||
@@ -0,0 +1,75 @@ | |||
1 | /* linux/include/asm-arm/plat-s3c/debug-macro.S | ||
2 | * | ||
3 | * Copyright 2005, 2007 Simtec Electronics | ||
4 | * http://armlinux.simtec.co.uk/ | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * | ||
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 | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <asm/plat-s3c/regs-serial.h> | ||
13 | |||
14 | /* The S3C2440 implementations are used by default as they are the | ||
15 | * most widely re-used */ | ||
16 | |||
17 | .macro fifo_level_s3c2440 rd, rx | ||
18 | ldr \rd, [ \rx, # S3C2410_UFSTAT ] | ||
19 | and \rd, \rd, #S3C2440_UFSTAT_TXMASK | ||
20 | .endm | ||
21 | |||
22 | #ifndef fifo_level | ||
23 | #define fifo_level fifo_level_s3c2410 | ||
24 | #endif | ||
25 | |||
26 | .macro fifo_full_s3c2440 rd, rx | ||
27 | ldr \rd, [ \rx, # S3C2410_UFSTAT ] | ||
28 | tst \rd, #S3C2440_UFSTAT_TXFULL | ||
29 | .endm | ||
30 | |||
31 | #ifndef fifo_full | ||
32 | #define fifo_full fifo_full_s3c2440 | ||
33 | #endif | ||
34 | |||
35 | .macro senduart,rd,rx | ||
36 | strb \rd, [\rx, # S3C2410_UTXH ] | ||
37 | .endm | ||
38 | |||
39 | .macro busyuart, rd, rx | ||
40 | ldr \rd, [ \rx, # S3C2410_UFCON ] | ||
41 | tst \rd, #S3C2410_UFCON_FIFOMODE @ fifo enabled? | ||
42 | beq 1001f @ | ||
43 | @ FIFO enabled... | ||
44 | 1003: | ||
45 | fifo_full \rd, \rx | ||
46 | bne 1003b | ||
47 | b 1002f | ||
48 | |||
49 | 1001: | ||
50 | @ busy waiting for non fifo | ||
51 | ldr \rd, [ \rx, # S3C2410_UTRSTAT ] | ||
52 | tst \rd, #S3C2410_UTRSTAT_TXFE | ||
53 | beq 1001b | ||
54 | |||
55 | 1002: @ exit busyuart | ||
56 | .endm | ||
57 | |||
58 | .macro waituart,rd,rx | ||
59 | ldr \rd, [ \rx, # S3C2410_UFCON ] | ||
60 | tst \rd, #S3C2410_UFCON_FIFOMODE @ fifo enabled? | ||
61 | beq 1001f @ | ||
62 | @ FIFO enabled... | ||
63 | 1003: | ||
64 | fifo_level \rd, \rx | ||
65 | teq \rd, #0 | ||
66 | bne 1003b | ||
67 | b 1002f | ||
68 | 1001: | ||
69 | @ idle waiting for non fifo | ||
70 | ldr \rd, [ \rx, # S3C2410_UTRSTAT ] | ||
71 | tst \rd, #S3C2410_UTRSTAT_TXFE | ||
72 | beq 1001b | ||
73 | |||
74 | 1002: @ exit busyuart | ||
75 | .endm | ||
diff --git a/include/asm-arm/arch-s3c2410/iic.h b/include/asm-arm/plat-s3c/iic.h index 71211c8b5384..71211c8b5384 100644 --- a/include/asm-arm/arch-s3c2410/iic.h +++ b/include/asm-arm/plat-s3c/iic.h | |||
diff --git a/include/asm-arm/plat-s3c/map.h b/include/asm-arm/plat-s3c/map.h new file mode 100644 index 000000000000..95a82b0e84a1 --- /dev/null +++ b/include/asm-arm/plat-s3c/map.h | |||
@@ -0,0 +1,40 @@ | |||
1 | /* linux/include/asm-arm/plat-s3c/map.h | ||
2 | * | ||
3 | * Copyright 2003, 2007 Simtec Electronics | ||
4 | * http://armlinux.simtec.co.uk/ | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * | ||
7 | * S3C - Memory map definitions (virtual addresses) | ||
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 version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #ifndef __ASM_PLAT_MAP_H | ||
15 | #define __ASM_PLAT_MAP_H __FILE__ | ||
16 | |||
17 | /* Fit all our registers in at 0xF4000000 upwards, trying to use as | ||
18 | * little of the VA space as possible so vmalloc and friends have a | ||
19 | * better chance of getting memory. | ||
20 | * | ||
21 | * we try to ensure stuff like the IRQ registers are available for | ||
22 | * an single MOVS instruction (ie, only 8 bits of set data) | ||
23 | */ | ||
24 | |||
25 | #define S3C_ADDR_BASE (0xF4000000) | ||
26 | |||
27 | #ifndef __ASSEMBLY__ | ||
28 | #define S3C_ADDR(x) ((void __iomem __force *)S3C_ADDR_BASE + (x)) | ||
29 | #else | ||
30 | #define S3C_ADDR(x) (S3C_ADDR_BASE + (x)) | ||
31 | #endif | ||
32 | |||
33 | #define S3C_VA_IRQ S3C_ADDR(0x000000000) /* irq controller(s) */ | ||
34 | #define S3C_VA_SYS S3C_ADDR(0x001000000) /* system control */ | ||
35 | #define S3C_VA_MEM S3C_ADDR(0x002000000) /* system control */ | ||
36 | #define S3C_VA_TIMER S3C_ADDR(0x003000000) /* timer block */ | ||
37 | #define S3C_VA_WATCHDOG S3C_ADDR(0x004000000) /* watchdog */ | ||
38 | #define S3C_VA_UART S3C_ADDR(0x010000000) /* UART */ | ||
39 | |||
40 | #endif /* __ASM_PLAT_MAP_H */ | ||
diff --git a/include/asm-arm/arch-s3c2410/nand.h b/include/asm-arm/plat-s3c/nand.h index 8816f7f9cee1..8816f7f9cee1 100644 --- a/include/asm-arm/arch-s3c2410/nand.h +++ b/include/asm-arm/plat-s3c/nand.h | |||
diff --git a/include/asm-arm/arch-s3c2410/regs-ac97.h b/include/asm-arm/plat-s3c/regs-ac97.h index b004dee6bcaf..b004dee6bcaf 100644 --- a/include/asm-arm/arch-s3c2410/regs-ac97.h +++ b/include/asm-arm/plat-s3c/regs-ac97.h | |||
diff --git a/include/asm-arm/arch-s3c2410/regs-adc.h b/include/asm-arm/plat-s3c/regs-adc.h index c7f231963e76..c7f231963e76 100644 --- a/include/asm-arm/arch-s3c2410/regs-adc.h +++ b/include/asm-arm/plat-s3c/regs-adc.h | |||
diff --git a/include/asm-arm/arch-s3c2410/regs-iic.h b/include/asm-arm/plat-s3c/regs-iic.h index 2ae29522f253..2ae29522f253 100644 --- a/include/asm-arm/arch-s3c2410/regs-iic.h +++ b/include/asm-arm/plat-s3c/regs-iic.h | |||
diff --git a/include/asm-arm/arch-s3c2410/regs-nand.h b/include/asm-arm/plat-s3c/regs-nand.h index b824d371ae0b..b824d371ae0b 100644 --- a/include/asm-arm/arch-s3c2410/regs-nand.h +++ b/include/asm-arm/plat-s3c/regs-nand.h | |||
diff --git a/include/asm-arm/arch-s3c2410/regs-rtc.h b/include/asm-arm/plat-s3c/regs-rtc.h index 93b03c49710a..93b03c49710a 100644 --- a/include/asm-arm/arch-s3c2410/regs-rtc.h +++ b/include/asm-arm/plat-s3c/regs-rtc.h | |||
diff --git a/include/asm-arm/arch-s3c2410/regs-serial.h b/include/asm-arm/plat-s3c/regs-serial.h index 8946702a87f5..923e114db663 100644 --- a/include/asm-arm/arch-s3c2410/regs-serial.h +++ b/include/asm-arm/plat-s3c/regs-serial.h | |||
@@ -32,10 +32,10 @@ | |||
32 | #ifndef __ASM_ARM_REGS_SERIAL_H | 32 | #ifndef __ASM_ARM_REGS_SERIAL_H |
33 | #define __ASM_ARM_REGS_SERIAL_H | 33 | #define __ASM_ARM_REGS_SERIAL_H |
34 | 34 | ||
35 | #define S3C24XX_VA_UART0 (S3C24XX_VA_UART) | 35 | #define S3C24XX_VA_UART0 (S3C_VA_UART) |
36 | #define S3C24XX_VA_UART1 (S3C24XX_VA_UART + 0x4000 ) | 36 | #define S3C24XX_VA_UART1 (S3C_VA_UART + 0x4000 ) |
37 | #define S3C24XX_VA_UART2 (S3C24XX_VA_UART + 0x8000 ) | 37 | #define S3C24XX_VA_UART2 (S3C_VA_UART + 0x8000 ) |
38 | #define S3C24XX_VA_UART3 (S3C24XX_VA_UART + 0xC000 ) | 38 | #define S3C24XX_VA_UART3 (S3C_VA_UART + 0xC000 ) |
39 | 39 | ||
40 | #define S3C2410_PA_UART0 (S3C24XX_PA_UART) | 40 | #define S3C2410_PA_UART0 (S3C24XX_PA_UART) |
41 | #define S3C2410_PA_UART1 (S3C24XX_PA_UART + 0x4000 ) | 41 | #define S3C2410_PA_UART1 (S3C24XX_PA_UART + 0x4000 ) |
diff --git a/include/asm-arm/arch-s3c2410/regs-timer.h b/include/asm-arm/plat-s3c/regs-timer.h index 6f8fe432fe3a..8b0d594397b1 100644 --- a/include/asm-arm/arch-s3c2410/regs-timer.h +++ b/include/asm-arm/plat-s3c/regs-timer.h | |||
@@ -14,12 +14,12 @@ | |||
14 | #ifndef __ASM_ARCH_REGS_TIMER_H | 14 | #ifndef __ASM_ARCH_REGS_TIMER_H |
15 | #define __ASM_ARCH_REGS_TIMER_H "$Id: timer.h,v 1.4 2003/05/06 19:30:50 ben Exp $" | 15 | #define __ASM_ARCH_REGS_TIMER_H "$Id: timer.h,v 1.4 2003/05/06 19:30:50 ben Exp $" |
16 | 16 | ||
17 | #define S3C2410_TIMERREG(x) (S3C24XX_VA_TIMER + (x)) | 17 | #define S3C_TIMERREG(x) (S3C_VA_TIMER + (x)) |
18 | #define S3C2410_TIMERREG2(tmr,reg) S3C2410_TIMERREG((reg)+0x0c+((tmr)*0x0c)) | 18 | #define S3C_TIMERREG2(tmr,reg) S3C_TIMERREG((reg)+0x0c+((tmr)*0x0c)) |
19 | 19 | ||
20 | #define S3C2410_TCFG0 S3C2410_TIMERREG(0x00) | 20 | #define S3C2410_TCFG0 S3C_TIMERREG(0x00) |
21 | #define S3C2410_TCFG1 S3C2410_TIMERREG(0x04) | 21 | #define S3C2410_TCFG1 S3C_TIMERREG(0x04) |
22 | #define S3C2410_TCON S3C2410_TIMERREG(0x08) | 22 | #define S3C2410_TCON S3C_TIMERREG(0x08) |
23 | 23 | ||
24 | #define S3C2410_TCFG_PRESCALER0_MASK (255<<0) | 24 | #define S3C2410_TCFG_PRESCALER0_MASK (255<<0) |
25 | #define S3C2410_TCFG_PRESCALER1_MASK (255<<8) | 25 | #define S3C2410_TCFG_PRESCALER1_MASK (255<<8) |
@@ -71,9 +71,9 @@ | |||
71 | 71 | ||
72 | /* WARNING - timer 4 has no buffer reg, and it's observation is at +4 */ | 72 | /* WARNING - timer 4 has no buffer reg, and it's observation is at +4 */ |
73 | 73 | ||
74 | #define S3C2410_TCNTB(tmr) S3C2410_TIMERREG2(tmr, 0x00) | 74 | #define S3C2410_TCNTB(tmr) S3C_TIMERREG2(tmr, 0x00) |
75 | #define S3C2410_TCMPB(tmr) S3C2410_TIMERREG2(tmr, 0x04) | 75 | #define S3C2410_TCMPB(tmr) S3C_TIMERREG2(tmr, 0x04) |
76 | #define S3C2410_TCNTO(tmr) S3C2410_TIMERREG2(tmr, (((tmr) == 4) ? 0x04 : 0x08)) | 76 | #define S3C2410_TCNTO(tmr) S3C_TIMERREG2(tmr, (((tmr) == 4) ? 0x04 : 0x08)) |
77 | 77 | ||
78 | #define S3C2410_TCON_T4RELOAD (1<<22) | 78 | #define S3C2410_TCON_T4RELOAD (1<<22) |
79 | #define S3C2410_TCON_T4MANUALUPD (1<<21) | 79 | #define S3C2410_TCON_T4MANUALUPD (1<<21) |
diff --git a/include/asm-arm/arch-s3c2410/regs-watchdog.h b/include/asm-arm/plat-s3c/regs-watchdog.h index a9c5d491bdb6..56c4193b7a46 100644 --- a/include/asm-arm/arch-s3c2410/regs-watchdog.h +++ b/include/asm-arm/plat-s3c/regs-watchdog.h | |||
@@ -14,11 +14,11 @@ | |||
14 | #ifndef __ASM_ARCH_REGS_WATCHDOG_H | 14 | #ifndef __ASM_ARCH_REGS_WATCHDOG_H |
15 | #define __ASM_ARCH_REGS_WATCHDOG_H "$Id: watchdog.h,v 1.2 2003/04/29 13:31:09 ben Exp $" | 15 | #define __ASM_ARCH_REGS_WATCHDOG_H "$Id: watchdog.h,v 1.2 2003/04/29 13:31:09 ben Exp $" |
16 | 16 | ||
17 | #define S3C2410_WDOGREG(x) ((x) + S3C24XX_VA_WATCHDOG) | 17 | #define S3C_WDOGREG(x) ((x) + S3C_VA_WATCHDOG) |
18 | 18 | ||
19 | #define S3C2410_WTCON S3C2410_WDOGREG(0x00) | 19 | #define S3C2410_WTCON S3C_WDOGREG(0x00) |
20 | #define S3C2410_WTDAT S3C2410_WDOGREG(0x04) | 20 | #define S3C2410_WTDAT S3C_WDOGREG(0x04) |
21 | #define S3C2410_WTCNT S3C2410_WDOGREG(0x08) | 21 | #define S3C2410_WTCNT S3C_WDOGREG(0x08) |
22 | 22 | ||
23 | /* the watchdog can either generate a reset pulse, or an | 23 | /* the watchdog can either generate a reset pulse, or an |
24 | * interrupt. | 24 | * interrupt. |
diff --git a/include/asm-arm/plat-s3c/uncompress.h b/include/asm-arm/plat-s3c/uncompress.h new file mode 100644 index 000000000000..b5e6208175d1 --- /dev/null +++ b/include/asm-arm/plat-s3c/uncompress.h | |||
@@ -0,0 +1,155 @@ | |||
1 | /* linux/include/asm-arm/plat-s3c/uncompress.h | ||
2 | * | ||
3 | * Copyright 2003, 2007 Simtec Electronics | ||
4 | * http://armlinux.simtec.co.uk/ | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * | ||
7 | * S3C - uncompress code | ||
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 version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #ifndef __ASM_PLAT_UNCOMPRESS_H | ||
15 | #define __ASM_PLAT_UNCOMPRESS_H | ||
16 | |||
17 | typedef unsigned int upf_t; /* cannot include linux/serial_core.h */ | ||
18 | |||
19 | /* uart setup */ | ||
20 | |||
21 | static unsigned int fifo_mask; | ||
22 | static unsigned int fifo_max; | ||
23 | |||
24 | /* forward declerations */ | ||
25 | |||
26 | static void arch_detect_cpu(void); | ||
27 | |||
28 | /* defines for UART registers */ | ||
29 | |||
30 | #include "asm/plat-s3c/regs-serial.h" | ||
31 | #include "asm/plat-s3c/regs-watchdog.h" | ||
32 | |||
33 | /* working in physical space... */ | ||
34 | #undef S3C2410_WDOGREG | ||
35 | #define S3C2410_WDOGREG(x) ((S3C24XX_PA_WATCHDOG + (x))) | ||
36 | |||
37 | /* how many bytes we allow into the FIFO at a time in FIFO mode */ | ||
38 | #define FIFO_MAX (14) | ||
39 | |||
40 | #define uart_base S3C24XX_PA_UART + (0x4000*CONFIG_S3C_LOWLEVEL_UART_PORT) | ||
41 | |||
42 | static __inline__ void | ||
43 | uart_wr(unsigned int reg, unsigned int val) | ||
44 | { | ||
45 | volatile unsigned int *ptr; | ||
46 | |||
47 | ptr = (volatile unsigned int *)(reg + uart_base); | ||
48 | *ptr = val; | ||
49 | } | ||
50 | |||
51 | static __inline__ unsigned int | ||
52 | uart_rd(unsigned int reg) | ||
53 | { | ||
54 | volatile unsigned int *ptr; | ||
55 | |||
56 | ptr = (volatile unsigned int *)(reg + uart_base); | ||
57 | return *ptr; | ||
58 | } | ||
59 | |||
60 | /* we can deal with the case the UARTs are being run | ||
61 | * in FIFO mode, so that we don't hold up our execution | ||
62 | * waiting for tx to happen... | ||
63 | */ | ||
64 | |||
65 | static void putc(int ch) | ||
66 | { | ||
67 | if (uart_rd(S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE) { | ||
68 | int level; | ||
69 | |||
70 | while (1) { | ||
71 | level = uart_rd(S3C2410_UFSTAT); | ||
72 | level &= fifo_mask; | ||
73 | |||
74 | if (level < fifo_max) | ||
75 | break; | ||
76 | } | ||
77 | |||
78 | } else { | ||
79 | /* not using fifos */ | ||
80 | |||
81 | while ((uart_rd(S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE) != S3C2410_UTRSTAT_TXE) | ||
82 | barrier(); | ||
83 | } | ||
84 | |||
85 | /* write byte to transmission register */ | ||
86 | uart_wr(S3C2410_UTXH, ch); | ||
87 | } | ||
88 | |||
89 | static inline void flush(void) | ||
90 | { | ||
91 | } | ||
92 | |||
93 | #define __raw_writel(d,ad) do { *((volatile unsigned int *)(ad)) = (d); } while(0) | ||
94 | |||
95 | /* CONFIG_S3C_BOOT_WATCHDOG | ||
96 | * | ||
97 | * Simple boot-time watchdog setup, to reboot the system if there is | ||
98 | * any problem with the boot process | ||
99 | */ | ||
100 | |||
101 | #ifdef CONFIG_S3C_BOOT_WATCHDOG | ||
102 | |||
103 | #define WDOG_COUNT (0xff00) | ||
104 | |||
105 | static inline void arch_decomp_wdog(void) | ||
106 | { | ||
107 | __raw_writel(WDOG_COUNT, S3C2410_WTCNT); | ||
108 | } | ||
109 | |||
110 | static void arch_decomp_wdog_start(void) | ||
111 | { | ||
112 | __raw_writel(WDOG_COUNT, S3C2410_WTDAT); | ||
113 | __raw_writel(WDOG_COUNT, S3C2410_WTCNT); | ||
114 | __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x80), S3C2410_WTCON); | ||
115 | } | ||
116 | |||
117 | #else | ||
118 | #define arch_decomp_wdog_start() | ||
119 | #define arch_decomp_wdog() | ||
120 | #endif | ||
121 | |||
122 | #ifdef CONFIG_S3C_BOOT_ERROR_RESET | ||
123 | |||
124 | static void arch_decomp_error(const char *x) | ||
125 | { | ||
126 | putstr("\n\n"); | ||
127 | putstr(x); | ||
128 | putstr("\n\n -- System resetting\n"); | ||
129 | |||
130 | __raw_writel(0x4000, S3C2410_WTDAT); | ||
131 | __raw_writel(0x4000, S3C2410_WTCNT); | ||
132 | __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x40), S3C2410_WTCON); | ||
133 | |||
134 | while(1); | ||
135 | } | ||
136 | |||
137 | #define arch_error arch_decomp_error | ||
138 | #endif | ||
139 | |||
140 | static void error(char *err); | ||
141 | |||
142 | static void | ||
143 | arch_decomp_setup(void) | ||
144 | { | ||
145 | /* we may need to setup the uart(s) here if we are not running | ||
146 | * on an BAST... the BAST will have left the uarts configured | ||
147 | * after calling linux. | ||
148 | */ | ||
149 | |||
150 | arch_detect_cpu(); | ||
151 | arch_decomp_wdog_start(); | ||
152 | } | ||
153 | |||
154 | |||
155 | #endif /* __ASM_PLAT_UNCOMPRESS_H */ | ||
diff --git a/include/asm-arm/arch-s3c2410/regs-iis.h b/include/asm-arm/plat-s3c24xx/regs-iis.h index eaf77916a602..eaf77916a602 100644 --- a/include/asm-arm/arch-s3c2410/regs-iis.h +++ b/include/asm-arm/plat-s3c24xx/regs-iis.h | |||
diff --git a/include/asm-arm/arch-s3c2410/regs-spi.h b/include/asm-arm/plat-s3c24xx/regs-spi.h index 4a499a138256..4a499a138256 100644 --- a/include/asm-arm/arch-s3c2410/regs-spi.h +++ b/include/asm-arm/plat-s3c24xx/regs-spi.h | |||
diff --git a/include/asm-arm/arch-s3c2410/regs-udc.h b/include/asm-arm/plat-s3c24xx/regs-udc.h index e1e9805d2d9a..e1e9805d2d9a 100644 --- a/include/asm-arm/arch-s3c2410/regs-udc.h +++ b/include/asm-arm/plat-s3c24xx/regs-udc.h | |||
diff --git a/include/asm-arm/arch-s3c2410/udc.h b/include/asm-arm/plat-s3c24xx/udc.h index b8aa6cb69b58..b8aa6cb69b58 100644 --- a/include/asm-arm/arch-s3c2410/udc.h +++ b/include/asm-arm/plat-s3c24xx/udc.h | |||
diff --git a/include/asm-arm/thread_info.h b/include/asm-arm/thread_info.h index eae85b09db2e..69c65d56a6ac 100644 --- a/include/asm-arm/thread_info.h +++ b/include/asm-arm/thread_info.h | |||
@@ -24,7 +24,6 @@ | |||
24 | struct task_struct; | 24 | struct task_struct; |
25 | struct exec_domain; | 25 | struct exec_domain; |
26 | 26 | ||
27 | #include <asm/ptrace.h> | ||
28 | #include <asm/types.h> | 27 | #include <asm/types.h> |
29 | #include <asm/domain.h> | 28 | #include <asm/domain.h> |
30 | 29 | ||
diff --git a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h index bfdbebebdc1b..d327b25c986c 100644 --- a/include/asm-arm/unistd.h +++ b/include/asm-arm/unistd.h | |||
@@ -441,7 +441,6 @@ | |||
441 | /* | 441 | /* |
442 | * Unimplemented (or alternatively implemented) syscalls | 442 | * Unimplemented (or alternatively implemented) syscalls |
443 | */ | 443 | */ |
444 | #define __IGNORE_sync_file_range 1 | ||
445 | #define __IGNORE_fadvise64_64 1 | 444 | #define __IGNORE_fadvise64_64 1 |
446 | 445 | ||
447 | #endif /* __KERNEL__ */ | 446 | #endif /* __KERNEL__ */ |
diff --git a/include/asm-arm/vfp.h b/include/asm-arm/vfp.h index 14c5e0946c47..bd6be9d7f772 100644 --- a/include/asm-arm/vfp.h +++ b/include/asm-arm/vfp.h | |||
@@ -26,8 +26,8 @@ | |||
26 | #define FPSID_REV_MASK (0xF << FPSID_REV_BIT) | 26 | #define FPSID_REV_MASK (0xF << FPSID_REV_BIT) |
27 | 27 | ||
28 | /* FPEXC bits */ | 28 | /* FPEXC bits */ |
29 | #define FPEXC_EXCEPTION (1<<31) | 29 | #define FPEXC_EX (1 << 31) |
30 | #define FPEXC_ENABLE (1<<30) | 30 | #define FPEXC_EN (1 << 30) |
31 | 31 | ||
32 | /* FPSCR bits */ | 32 | /* FPSCR bits */ |
33 | #define FPSCR_DEFAULT_NAN (1<<25) | 33 | #define FPSCR_DEFAULT_NAN (1<<25) |
diff --git a/include/asm-arm26/irq.h b/include/asm-arm26/irq.h index 9aaac87efba9..52971b49ed3b 100644 --- a/include/asm-arm26/irq.h +++ b/include/asm-arm26/irq.h | |||
@@ -24,11 +24,6 @@ | |||
24 | 24 | ||
25 | struct irqaction; | 25 | struct irqaction; |
26 | 26 | ||
27 | #define disable_irq_nosync(i) disable_irq(i) | ||
28 | |||
29 | extern void disable_irq(unsigned int); | ||
30 | extern void enable_irq(unsigned int); | ||
31 | |||
32 | #define __IRQT_FALEDGE (1 << 0) | 27 | #define __IRQT_FALEDGE (1 << 0) |
33 | #define __IRQT_RISEDGE (1 << 1) | 28 | #define __IRQT_RISEDGE (1 << 1) |
34 | #define __IRQT_LOWLVL (1 << 2) | 29 | #define __IRQT_LOWLVL (1 << 2) |
diff --git a/include/asm-h8300/irq.h b/include/asm-h8300/irq.h index 41be646c3514..56eec28cc2c4 100644 --- a/include/asm-h8300/irq.h +++ b/include/asm-h8300/irq.h | |||
@@ -59,7 +59,4 @@ static __inline__ int irq_canonicalize(int irq) | |||
59 | return irq; | 59 | return irq; |
60 | } | 60 | } |
61 | 61 | ||
62 | extern void enable_irq(unsigned int); | ||
63 | extern void disable_irq(unsigned int); | ||
64 | |||
65 | #endif /* _H8300_IRQ_H_ */ | 62 | #endif /* _H8300_IRQ_H_ */ |
diff --git a/include/asm-i386/acpi.h b/include/asm-i386/acpi.h index 449f3f272e07..125179adf044 100644 --- a/include/asm-i386/acpi.h +++ b/include/asm-i386/acpi.h | |||
@@ -121,19 +121,6 @@ static inline void acpi_disable_pci(void) | |||
121 | } | 121 | } |
122 | extern int acpi_irq_balance_set(char *str); | 122 | extern int acpi_irq_balance_set(char *str); |
123 | 123 | ||
124 | #else /* !CONFIG_ACPI */ | ||
125 | |||
126 | #define acpi_lapic 0 | ||
127 | #define acpi_ioapic 0 | ||
128 | static inline void acpi_noirq_set(void) { } | ||
129 | static inline void acpi_disable_pci(void) { } | ||
130 | static inline void disable_acpi(void) { } | ||
131 | |||
132 | #endif /* !CONFIG_ACPI */ | ||
133 | |||
134 | |||
135 | #ifdef CONFIG_ACPI_SLEEP | ||
136 | |||
137 | /* routines for saving/restoring kernel state */ | 124 | /* routines for saving/restoring kernel state */ |
138 | extern int acpi_save_state_mem(void); | 125 | extern int acpi_save_state_mem(void); |
139 | extern void acpi_restore_state_mem(void); | 126 | extern void acpi_restore_state_mem(void); |
@@ -143,7 +130,15 @@ extern unsigned long acpi_wakeup_address; | |||
143 | /* early initialization routine */ | 130 | /* early initialization routine */ |
144 | extern void acpi_reserve_bootmem(void); | 131 | extern void acpi_reserve_bootmem(void); |
145 | 132 | ||
146 | #endif /*CONFIG_ACPI_SLEEP*/ | 133 | #else /* !CONFIG_ACPI */ |
134 | |||
135 | #define acpi_lapic 0 | ||
136 | #define acpi_ioapic 0 | ||
137 | static inline void acpi_noirq_set(void) { } | ||
138 | static inline void acpi_disable_pci(void) { } | ||
139 | static inline void disable_acpi(void) { } | ||
140 | |||
141 | #endif /* !CONFIG_ACPI */ | ||
147 | 142 | ||
148 | #define ARCH_HAS_POWER_INIT 1 | 143 | #define ARCH_HAS_POWER_INIT 1 |
149 | 144 | ||
diff --git a/include/asm-i386/alternative.h b/include/asm-i386/alternative.h index eb7da5402bfa..bda6c810c0f4 100644 --- a/include/asm-i386/alternative.h +++ b/include/asm-i386/alternative.h | |||
@@ -149,4 +149,6 @@ apply_paravirt(struct paravirt_patch_site *start, | |||
149 | #define __parainstructions_end NULL | 149 | #define __parainstructions_end NULL |
150 | #endif | 150 | #endif |
151 | 151 | ||
152 | extern void text_poke(void *addr, unsigned char *opcode, int len); | ||
153 | |||
152 | #endif /* _I386_ALTERNATIVE_H */ | 154 | #endif /* _I386_ALTERNATIVE_H */ |
diff --git a/include/asm-i386/cmpxchg.h b/include/asm-i386/cmpxchg.h index 64dcdf46117b..f86ede28f6dc 100644 --- a/include/asm-i386/cmpxchg.h +++ b/include/asm-i386/cmpxchg.h | |||
@@ -34,7 +34,7 @@ static inline void __set_64bit (unsigned long long * ptr, | |||
34 | "\n1:\t" | 34 | "\n1:\t" |
35 | "movl (%0), %%eax\n\t" | 35 | "movl (%0), %%eax\n\t" |
36 | "movl 4(%0), %%edx\n\t" | 36 | "movl 4(%0), %%edx\n\t" |
37 | "lock cmpxchg8b (%0)\n\t" | 37 | LOCK_PREFIX "cmpxchg8b (%0)\n\t" |
38 | "jnz 1b" | 38 | "jnz 1b" |
39 | : /* no outputs */ | 39 | : /* no outputs */ |
40 | : "D"(ptr), | 40 | : "D"(ptr), |
diff --git a/include/asm-i386/mce.h b/include/asm-i386/mce.h index b0a02ee34ffd..d56d89742e8f 100644 --- a/include/asm-i386/mce.h +++ b/include/asm-i386/mce.h | |||
@@ -5,3 +5,7 @@ extern void mcheck_init(struct cpuinfo_x86 *c); | |||
5 | #endif | 5 | #endif |
6 | 6 | ||
7 | extern int mce_disabled; | 7 | extern int mce_disabled; |
8 | |||
9 | extern void stop_mce(void); | ||
10 | extern void restart_mce(void); | ||
11 | |||
diff --git a/include/asm-i386/nmi.h b/include/asm-i386/nmi.h index fb1e133efd9f..ff30c98f87b0 100644 --- a/include/asm-i386/nmi.h +++ b/include/asm-i386/nmi.h | |||
@@ -57,5 +57,7 @@ unsigned lapic_adjust_nmi_hz(unsigned hz); | |||
57 | int lapic_watchdog_ok(void); | 57 | int lapic_watchdog_ok(void); |
58 | void disable_lapic_nmi_watchdog(void); | 58 | void disable_lapic_nmi_watchdog(void); |
59 | void enable_lapic_nmi_watchdog(void); | 59 | void enable_lapic_nmi_watchdog(void); |
60 | void stop_nmi(void); | ||
61 | void restart_nmi(void); | ||
60 | 62 | ||
61 | #endif /* ASM_NMI_H */ | 63 | #endif /* ASM_NMI_H */ |
diff --git a/include/asm-i386/processor-cyrix.h b/include/asm-i386/processor-cyrix.h new file mode 100644 index 000000000000..97568ada1f97 --- /dev/null +++ b/include/asm-i386/processor-cyrix.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | * NSC/Cyrix CPU indexed register access. Must be inlined instead of | ||
3 | * macros to ensure correct access ordering | ||
4 | * Access order is always 0x22 (=offset), 0x23 (=value) | ||
5 | * | ||
6 | * When using the old macros a line like | ||
7 | * setCx86(CX86_CCR2, getCx86(CX86_CCR2) | 0x88); | ||
8 | * gets expanded to: | ||
9 | * do { | ||
10 | * outb((CX86_CCR2), 0x22); | ||
11 | * outb((({ | ||
12 | * outb((CX86_CCR2), 0x22); | ||
13 | * inb(0x23); | ||
14 | * }) | 0x88), 0x23); | ||
15 | * } while (0); | ||
16 | * | ||
17 | * which in fact violates the access order (= 0x22, 0x22, 0x23, 0x23). | ||
18 | */ | ||
19 | |||
20 | static inline u8 getCx86(u8 reg) | ||
21 | { | ||
22 | outb(reg, 0x22); | ||
23 | return inb(0x23); | ||
24 | } | ||
25 | |||
26 | static inline void setCx86(u8 reg, u8 data) | ||
27 | { | ||
28 | outb(reg, 0x22); | ||
29 | outb(data, 0x23); | ||
30 | } | ||
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h index 48a7f69bb767..3845fe72383e 100644 --- a/include/asm-i386/processor.h +++ b/include/asm-i386/processor.h | |||
@@ -168,17 +168,6 @@ static inline void clear_in_cr4 (unsigned long mask) | |||
168 | write_cr4(cr4); | 168 | write_cr4(cr4); |
169 | } | 169 | } |
170 | 170 | ||
171 | /* | ||
172 | * NSC/Cyrix CPU indexed register access macros | ||
173 | */ | ||
174 | |||
175 | #define getCx86(reg) ({ outb((reg), 0x22); inb(0x23); }) | ||
176 | |||
177 | #define setCx86(reg, data) do { \ | ||
178 | outb((reg), 0x22); \ | ||
179 | outb((data), 0x23); \ | ||
180 | } while (0) | ||
181 | |||
182 | /* Stop speculative execution */ | 171 | /* Stop speculative execution */ |
183 | static inline void sync_core(void) | 172 | static inline void sync_core(void) |
184 | { | 173 | { |
diff --git a/include/asm-i386/suspend.h b/include/asm-i386/suspend.h index 8dbaafe611ff..a2520732ffd6 100644 --- a/include/asm-i386/suspend.h +++ b/include/asm-i386/suspend.h | |||
@@ -21,7 +21,7 @@ struct saved_context { | |||
21 | unsigned long return_address; | 21 | unsigned long return_address; |
22 | } __attribute__((packed)); | 22 | } __attribute__((packed)); |
23 | 23 | ||
24 | #ifdef CONFIG_ACPI_SLEEP | 24 | #ifdef CONFIG_ACPI |
25 | extern unsigned long saved_eip; | 25 | extern unsigned long saved_eip; |
26 | extern unsigned long saved_esp; | 26 | extern unsigned long saved_esp; |
27 | extern unsigned long saved_ebp; | 27 | extern unsigned long saved_ebp; |
diff --git a/include/asm-ia64/acpi.h b/include/asm-ia64/acpi.h index 5b526357d178..49730ffbbae4 100644 --- a/include/asm-ia64/acpi.h +++ b/include/asm-ia64/acpi.h | |||
@@ -100,6 +100,11 @@ const char *acpi_get_sysname (void); | |||
100 | int acpi_request_vector (u32 int_type); | 100 | int acpi_request_vector (u32 int_type); |
101 | int acpi_gsi_to_irq (u32 gsi, unsigned int *irq); | 101 | int acpi_gsi_to_irq (u32 gsi, unsigned int *irq); |
102 | 102 | ||
103 | /* routines for saving/restoring kernel state */ | ||
104 | extern int acpi_save_state_mem(void); | ||
105 | extern void acpi_restore_state_mem(void); | ||
106 | extern unsigned long acpi_wakeup_address; | ||
107 | |||
103 | /* | 108 | /* |
104 | * Record the cpei override flag and current logical cpu. This is | 109 | * Record the cpei override flag and current logical cpu. This is |
105 | * useful for CPU removal. | 110 | * useful for CPU removal. |
diff --git a/include/asm-ia64/irq.h b/include/asm-ia64/irq.h index 35b360b82e43..a66d26827cbb 100644 --- a/include/asm-ia64/irq.h +++ b/include/asm-ia64/irq.h | |||
@@ -33,9 +33,6 @@ irq_canonicalize (int irq) | |||
33 | return ((irq == 2) ? 9 : irq); | 33 | return ((irq == 2) ? 9 : irq); |
34 | } | 34 | } |
35 | 35 | ||
36 | extern void disable_irq (unsigned int); | ||
37 | extern void disable_irq_nosync (unsigned int); | ||
38 | extern void enable_irq (unsigned int); | ||
39 | extern void set_irq_affinity_info (unsigned int irq, int dest, int redir); | 36 | extern void set_irq_affinity_info (unsigned int irq, int dest, int redir); |
40 | bool is_affinity_mask_valid(cpumask_t cpumask); | 37 | bool is_affinity_mask_valid(cpumask_t cpumask); |
41 | 38 | ||
diff --git a/include/asm-m68k/irq.h b/include/asm-m68k/irq.h index 4901cb105e2f..eb29a5260591 100644 --- a/include/asm-m68k/irq.h +++ b/include/asm-m68k/irq.h | |||
@@ -59,9 +59,6 @@ | |||
59 | #define IRQ_USER 8 | 59 | #define IRQ_USER 8 |
60 | 60 | ||
61 | extern unsigned int irq_canonicalize(unsigned int irq); | 61 | extern unsigned int irq_canonicalize(unsigned int irq); |
62 | extern void enable_irq(unsigned int); | ||
63 | extern void disable_irq(unsigned int); | ||
64 | #define disable_irq_nosync disable_irq | ||
65 | 62 | ||
66 | struct pt_regs; | 63 | struct pt_regs; |
67 | 64 | ||
diff --git a/include/asm-powerpc/mpic.h b/include/asm-powerpc/mpic.h index 2ffb06abe881..262db6b8da73 100644 --- a/include/asm-powerpc/mpic.h +++ b/include/asm-powerpc/mpic.h | |||
@@ -296,6 +296,9 @@ struct mpic | |||
296 | unsigned int dcr_base; | 296 | unsigned int dcr_base; |
297 | #endif | 297 | #endif |
298 | 298 | ||
299 | /* Protected sources */ | ||
300 | unsigned long *protected; | ||
301 | |||
299 | #ifdef CONFIG_MPIC_WEIRD | 302 | #ifdef CONFIG_MPIC_WEIRD |
300 | /* Pointer to HW info array */ | 303 | /* Pointer to HW info array */ |
301 | u32 *hw_set; | 304 | u32 *hw_set; |
diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h index 6e391c9894ce..672083787a1d 100644 --- a/include/asm-powerpc/prom.h +++ b/include/asm-powerpc/prom.h | |||
@@ -139,7 +139,7 @@ extern unsigned long __init of_get_flat_dt_root(void); | |||
139 | 139 | ||
140 | /* For updating the device tree at runtime */ | 140 | /* For updating the device tree at runtime */ |
141 | extern void of_attach_node(struct device_node *); | 141 | extern void of_attach_node(struct device_node *); |
142 | extern void of_detach_node(const struct device_node *); | 142 | extern void of_detach_node(struct device_node *); |
143 | 143 | ||
144 | /* Other Prototypes */ | 144 | /* Other Prototypes */ |
145 | extern void finish_device_tree(void); | 145 | extern void finish_device_tree(void); |
diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h index f1311a8f310f..cc45780421ca 100644 --- a/include/asm-ppc/system.h +++ b/include/asm-ppc/system.h | |||
@@ -54,6 +54,7 @@ extern void show_regs(struct pt_regs * regs); | |||
54 | extern void flush_instruction_cache(void); | 54 | extern void flush_instruction_cache(void); |
55 | extern void hard_reset_now(void); | 55 | extern void hard_reset_now(void); |
56 | extern void poweroff_now(void); | 56 | extern void poweroff_now(void); |
57 | extern int set_dabr(unsigned long dabr); | ||
57 | #ifdef CONFIG_6xx | 58 | #ifdef CONFIG_6xx |
58 | extern long _get_L2CR(void); | 59 | extern long _get_L2CR(void); |
59 | extern long _get_L3CR(void); | 60 | extern long _get_L3CR(void); |
diff --git a/include/asm-sh64/irq.h b/include/asm-sh64/irq.h index 1ca49e29288a..5c9e6a873aeb 100644 --- a/include/asm-sh64/irq.h +++ b/include/asm-sh64/irq.h | |||
@@ -114,10 +114,6 @@ | |||
114 | #define IRL0_PRIORITY 13 | 114 | #define IRL0_PRIORITY 13 |
115 | #define TOP_PRIORITY 15 | 115 | #define TOP_PRIORITY 15 |
116 | 116 | ||
117 | extern void disable_irq(unsigned int); | ||
118 | extern void disable_irq_nosync(unsigned int); | ||
119 | extern void enable_irq(unsigned int); | ||
120 | |||
121 | extern int intc_evt_to_irq[(0xE20/0x20)+1]; | 117 | extern int intc_evt_to_irq[(0xE20/0x20)+1]; |
122 | int intc_irq_describe(char* p, int irq); | 118 | int intc_irq_describe(char* p, int irq); |
123 | 119 | ||
diff --git a/include/asm-sparc/irq.h b/include/asm-sparc/irq.h index afb88a5973f0..61fb99643afd 100644 --- a/include/asm-sparc/irq.h +++ b/include/asm-sparc/irq.h | |||
@@ -13,10 +13,6 @@ | |||
13 | 13 | ||
14 | #define irq_canonicalize(irq) (irq) | 14 | #define irq_canonicalize(irq) (irq) |
15 | 15 | ||
16 | extern void disable_irq_nosync(unsigned int irq); | ||
17 | extern void disable_irq(unsigned int irq); | ||
18 | extern void enable_irq(unsigned int irq); | ||
19 | |||
20 | extern int request_fast_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, __const__ char *devname); | 16 | extern int request_fast_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, __const__ char *devname); |
21 | 17 | ||
22 | #endif | 18 | #endif |
diff --git a/include/asm-v850/irq.h b/include/asm-v850/irq.h index 88687c181f01..7d0d4cd1ce54 100644 --- a/include/asm-v850/irq.h +++ b/include/asm-v850/irq.h | |||
@@ -50,16 +50,6 @@ init_irq_handlers (int base_irq, int num, int interval, | |||
50 | interrupt. */ | 50 | interrupt. */ |
51 | extern unsigned int handle_irq (int irq, struct pt_regs *regs); | 51 | extern unsigned int handle_irq (int irq, struct pt_regs *regs); |
52 | 52 | ||
53 | |||
54 | /* Enable interrupt handling on an irq. */ | ||
55 | extern void enable_irq(unsigned int irq); | ||
56 | |||
57 | /* Disable an irq and wait for completion. */ | ||
58 | extern void disable_irq (unsigned int irq); | ||
59 | |||
60 | /* Disable an irq without waiting. */ | ||
61 | extern void disable_irq_nosync (unsigned int irq); | ||
62 | |||
63 | #endif /* !__ASSEMBLY__ */ | 53 | #endif /* !__ASSEMBLY__ */ |
64 | 54 | ||
65 | #endif /* __V850_IRQ_H__ */ | 55 | #endif /* __V850_IRQ_H__ */ |
diff --git a/include/asm-x86_64/acpi.h b/include/asm-x86_64/acpi.h index 1da8f49c0fe2..98173357dd89 100644 --- a/include/asm-x86_64/acpi.h +++ b/include/asm-x86_64/acpi.h | |||
@@ -108,6 +108,15 @@ static inline void acpi_disable_pci(void) | |||
108 | } | 108 | } |
109 | extern int acpi_irq_balance_set(char *str); | 109 | extern int acpi_irq_balance_set(char *str); |
110 | 110 | ||
111 | /* routines for saving/restoring kernel state */ | ||
112 | extern int acpi_save_state_mem(void); | ||
113 | extern void acpi_restore_state_mem(void); | ||
114 | |||
115 | extern unsigned long acpi_wakeup_address; | ||
116 | |||
117 | /* early initialization routine */ | ||
118 | extern void acpi_reserve_bootmem(void); | ||
119 | |||
111 | #else /* !CONFIG_ACPI */ | 120 | #else /* !CONFIG_ACPI */ |
112 | 121 | ||
113 | #define acpi_lapic 0 | 122 | #define acpi_lapic 0 |
@@ -121,19 +130,6 @@ extern int acpi_numa; | |||
121 | extern int acpi_scan_nodes(unsigned long start, unsigned long end); | 130 | extern int acpi_scan_nodes(unsigned long start, unsigned long end); |
122 | #define NR_NODE_MEMBLKS (MAX_NUMNODES*2) | 131 | #define NR_NODE_MEMBLKS (MAX_NUMNODES*2) |
123 | 132 | ||
124 | #ifdef CONFIG_ACPI_SLEEP | ||
125 | |||
126 | /* routines for saving/restoring kernel state */ | ||
127 | extern int acpi_save_state_mem(void); | ||
128 | extern void acpi_restore_state_mem(void); | ||
129 | |||
130 | extern unsigned long acpi_wakeup_address; | ||
131 | |||
132 | /* early initialization routine */ | ||
133 | extern void acpi_reserve_bootmem(void); | ||
134 | |||
135 | #endif /*CONFIG_ACPI_SLEEP*/ | ||
136 | |||
137 | extern int acpi_disabled; | 133 | extern int acpi_disabled; |
138 | extern int acpi_pci_disabled; | 134 | extern int acpi_pci_disabled; |
139 | 135 | ||
diff --git a/include/asm-x86_64/alternative.h b/include/asm-x86_64/alternative.h index eea7aecfac78..ab161e810151 100644 --- a/include/asm-x86_64/alternative.h +++ b/include/asm-x86_64/alternative.h | |||
@@ -154,4 +154,6 @@ apply_paravirt(struct paravirt_patch *start, struct paravirt_patch *end) | |||
154 | #define __parainstructions_end NULL | 154 | #define __parainstructions_end NULL |
155 | #endif | 155 | #endif |
156 | 156 | ||
157 | extern void text_poke(void *addr, unsigned char *opcode, int len); | ||
158 | |||
157 | #endif /* _X86_64_ALTERNATIVE_H */ | 159 | #endif /* _X86_64_ALTERNATIVE_H */ |
diff --git a/include/asm-x86_64/cmpxchg.h b/include/asm-x86_64/cmpxchg.h index 09a6b6b6b74d..5e182062e6ec 100644 --- a/include/asm-x86_64/cmpxchg.h +++ b/include/asm-x86_64/cmpxchg.h | |||
@@ -128,7 +128,7 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr, | |||
128 | ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\ | 128 | ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\ |
129 | (unsigned long)(n),sizeof(*(ptr)))) | 129 | (unsigned long)(n),sizeof(*(ptr)))) |
130 | #define cmpxchg_local(ptr,o,n)\ | 130 | #define cmpxchg_local(ptr,o,n)\ |
131 | ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\ | 131 | ((__typeof__(*(ptr)))__cmpxchg_local((ptr),(unsigned long)(o),\ |
132 | (unsigned long)(n),sizeof(*(ptr)))) | 132 | (unsigned long)(n),sizeof(*(ptr)))) |
133 | 133 | ||
134 | #endif | 134 | #endif |
diff --git a/include/asm-x86_64/hypertransport.h b/include/asm-x86_64/hypertransport.h index c16c6ff4bdd7..5cbf9fa5e0b5 100644 --- a/include/asm-x86_64/hypertransport.h +++ b/include/asm-x86_64/hypertransport.h | |||
@@ -1,42 +1 @@ | |||
1 | #ifndef ASM_HYPERTRANSPORT_H | #include <asm-i386/hypertransport.h> | |
2 | #define ASM_HYPERTRANSPORT_H | ||
3 | |||
4 | /* | ||
5 | * Constants for x86 Hypertransport Interrupts. | ||
6 | */ | ||
7 | |||
8 | #define HT_IRQ_LOW_BASE 0xf8000000 | ||
9 | |||
10 | #define HT_IRQ_LOW_VECTOR_SHIFT 16 | ||
11 | #define HT_IRQ_LOW_VECTOR_MASK 0x00ff0000 | ||
12 | #define HT_IRQ_LOW_VECTOR(v) (((v) << HT_IRQ_LOW_VECTOR_SHIFT) & HT_IRQ_LOW_VECTOR_MASK) | ||
13 | |||
14 | #define HT_IRQ_LOW_DEST_ID_SHIFT 8 | ||
15 | #define HT_IRQ_LOW_DEST_ID_MASK 0x0000ff00 | ||
16 | #define HT_IRQ_LOW_DEST_ID(v) (((v) << HT_IRQ_LOW_DEST_ID_SHIFT) & HT_IRQ_LOW_DEST_ID_MASK) | ||
17 | |||
18 | #define HT_IRQ_LOW_DM_PHYSICAL 0x0000000 | ||
19 | #define HT_IRQ_LOW_DM_LOGICAL 0x0000040 | ||
20 | |||
21 | #define HT_IRQ_LOW_RQEOI_EDGE 0x0000000 | ||
22 | #define HT_IRQ_LOW_RQEOI_LEVEL 0x0000020 | ||
23 | |||
24 | |||
25 | #define HT_IRQ_LOW_MT_FIXED 0x0000000 | ||
26 | #define HT_IRQ_LOW_MT_ARBITRATED 0x0000004 | ||
27 | #define HT_IRQ_LOW_MT_SMI 0x0000008 | ||
28 | #define HT_IRQ_LOW_MT_NMI 0x000000c | ||
29 | #define HT_IRQ_LOW_MT_INIT 0x0000010 | ||
30 | #define HT_IRQ_LOW_MT_STARTUP 0x0000014 | ||
31 | #define HT_IRQ_LOW_MT_EXTINT 0x0000018 | ||
32 | #define HT_IRQ_LOW_MT_LINT1 0x000008c | ||
33 | #define HT_IRQ_LOW_MT_LINT0 0x0000098 | ||
34 | |||
35 | #define HT_IRQ_LOW_IRQ_MASKED 0x0000001 | ||
36 | |||
37 | |||
38 | #define HT_IRQ_HIGH_DEST_ID_SHIFT 0 | ||
39 | #define HT_IRQ_HIGH_DEST_ID_MASK 0x00ffffff | ||
40 | #define HT_IRQ_HIGH_DEST_ID(v) ((((v) >> 8) << HT_IRQ_HIGH_DEST_ID_SHIFT) & HT_IRQ_HIGH_DEST_ID_MASK) | ||
41 | |||
42 | #endif /* ASM_HYPERTRANSPORT_H */ | ||
diff --git a/include/asm-x86_64/mce.h b/include/asm-x86_64/mce.h index 556be5563e30..7bc030a1996d 100644 --- a/include/asm-x86_64/mce.h +++ b/include/asm-x86_64/mce.h | |||
@@ -107,6 +107,9 @@ extern void do_machine_check(struct pt_regs *, long); | |||
107 | 107 | ||
108 | extern int mce_notify_user(void); | 108 | extern int mce_notify_user(void); |
109 | 109 | ||
110 | extern void stop_mce(void); | ||
111 | extern void restart_mce(void); | ||
112 | |||
110 | #endif | 113 | #endif |
111 | 114 | ||
112 | #endif | 115 | #endif |
diff --git a/include/asm-x86_64/msidef.h b/include/asm-x86_64/msidef.h index 5b8acddb70fb..083ad5827e48 100644 --- a/include/asm-x86_64/msidef.h +++ b/include/asm-x86_64/msidef.h | |||
@@ -1,47 +1 @@ | |||
1 | #ifndef ASM_MSIDEF_H | #include <asm-i386/msidef.h> | |
2 | #define ASM_MSIDEF_H | ||
3 | |||
4 | /* | ||
5 | * Constants for Intel APIC based MSI messages. | ||
6 | */ | ||
7 | |||
8 | /* | ||
9 | * Shifts for MSI data | ||
10 | */ | ||
11 | |||
12 | #define MSI_DATA_VECTOR_SHIFT 0 | ||
13 | #define MSI_DATA_VECTOR_MASK 0x000000ff | ||
14 | #define MSI_DATA_VECTOR(v) (((v) << MSI_DATA_VECTOR_SHIFT) & MSI_DATA_VECTOR_MASK) | ||
15 | |||
16 | #define MSI_DATA_DELIVERY_MODE_SHIFT 8 | ||
17 | #define MSI_DATA_DELIVERY_FIXED (0 << MSI_DATA_DELIVERY_MODE_SHIFT) | ||
18 | #define MSI_DATA_DELIVERY_LOWPRI (1 << MSI_DATA_DELIVERY_MODE_SHIFT) | ||
19 | |||
20 | #define MSI_DATA_LEVEL_SHIFT 14 | ||
21 | #define MSI_DATA_LEVEL_DEASSERT (0 << MSI_DATA_LEVEL_SHIFT) | ||
22 | #define MSI_DATA_LEVEL_ASSERT (1 << MSI_DATA_LEVEL_SHIFT) | ||
23 | |||
24 | #define MSI_DATA_TRIGGER_SHIFT 15 | ||
25 | #define MSI_DATA_TRIGGER_EDGE (0 << MSI_DATA_TRIGGER_SHIFT) | ||
26 | #define MSI_DATA_TRIGGER_LEVEL (1 << MSI_DATA_TRIGGER_SHIFT) | ||
27 | |||
28 | /* | ||
29 | * Shift/mask fields for msi address | ||
30 | */ | ||
31 | |||
32 | #define MSI_ADDR_BASE_HI 0 | ||
33 | #define MSI_ADDR_BASE_LO 0xfee00000 | ||
34 | |||
35 | #define MSI_ADDR_DEST_MODE_SHIFT 2 | ||
36 | #define MSI_ADDR_DEST_MODE_PHYSICAL (0 << MSI_ADDR_DEST_MODE_SHIFT) | ||
37 | #define MSI_ADDR_DEST_MODE_LOGICAL (1 << MSI_ADDR_DEST_MODE_SHIFT) | ||
38 | |||
39 | #define MSI_ADDR_REDIRECTION_SHIFT 3 | ||
40 | #define MSI_ADDR_REDIRECTION_CPU (0 << MSI_ADDR_REDIRECTION_SHIFT) /* dedicated cpu */ | ||
41 | #define MSI_ADDR_REDIRECTION_LOWPRI (1 << MSI_ADDR_REDIRECTION_SHIFT) /* lowest priority */ | ||
42 | |||
43 | #define MSI_ADDR_DEST_ID_SHIFT 12 | ||
44 | #define MSI_ADDR_DEST_ID_MASK 0x00ffff0 | ||
45 | #define MSI_ADDR_DEST_ID(dest) (((dest) << MSI_ADDR_DEST_ID_SHIFT) & MSI_ADDR_DEST_ID_MASK) | ||
46 | |||
47 | #endif /* ASM_MSIDEF_H */ | ||
diff --git a/include/asm-x86_64/nmi.h b/include/asm-x86_64/nmi.h index d0a7f53b1497..5fb3c0de5ccc 100644 --- a/include/asm-x86_64/nmi.h +++ b/include/asm-x86_64/nmi.h | |||
@@ -88,5 +88,7 @@ unsigned lapic_adjust_nmi_hz(unsigned hz); | |||
88 | int lapic_watchdog_ok(void); | 88 | int lapic_watchdog_ok(void); |
89 | void disable_lapic_nmi_watchdog(void); | 89 | void disable_lapic_nmi_watchdog(void); |
90 | void enable_lapic_nmi_watchdog(void); | 90 | void enable_lapic_nmi_watchdog(void); |
91 | void stop_nmi(void); | ||
92 | void restart_nmi(void); | ||
91 | 93 | ||
92 | #endif /* ASM_NMI_H */ | 94 | #endif /* ASM_NMI_H */ |
diff --git a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h index 60cff1e4f7a3..c9d8764c89d1 100644 --- a/include/asm-x86_64/pgtable.h +++ b/include/asm-x86_64/pgtable.h | |||
@@ -403,6 +403,8 @@ extern struct list_head pgd_list; | |||
403 | 403 | ||
404 | extern int kern_addr_valid(unsigned long addr); | 404 | extern int kern_addr_valid(unsigned long addr); |
405 | 405 | ||
406 | pte_t *lookup_address(unsigned long addr); | ||
407 | |||
406 | #define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ | 408 | #define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ |
407 | remap_pfn_range(vma, vaddr, pfn, size, prot) | 409 | remap_pfn_range(vma, vaddr, pfn, size, prot) |
408 | 410 | ||
diff --git a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h index a1645bbc03bd..19525175b91c 100644 --- a/include/asm-x86_64/processor.h +++ b/include/asm-x86_64/processor.h | |||
@@ -389,17 +389,6 @@ static inline void prefetchw(void *x) | |||
389 | 389 | ||
390 | #define cpu_relax() rep_nop() | 390 | #define cpu_relax() rep_nop() |
391 | 391 | ||
392 | /* | ||
393 | * NSC/Cyrix CPU indexed register access macros | ||
394 | */ | ||
395 | |||
396 | #define getCx86(reg) ({ outb((reg), 0x22); inb(0x23); }) | ||
397 | |||
398 | #define setCx86(reg, data) do { \ | ||
399 | outb((reg), 0x22); \ | ||
400 | outb((data), 0x23); \ | ||
401 | } while (0) | ||
402 | |||
403 | static inline void serialize_cpu(void) | 392 | static inline void serialize_cpu(void) |
404 | { | 393 | { |
405 | __asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx"); | 394 | __asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx"); |
diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h index d6e3225549c0..31f20ad65876 100644 --- a/include/asm-x86_64/proto.h +++ b/include/asm-x86_64/proto.h | |||
@@ -75,8 +75,6 @@ extern void setup_node_bootmem(int nodeid, unsigned long start, unsigned long en | |||
75 | extern void early_quirks(void); | 75 | extern void early_quirks(void); |
76 | extern void check_efer(void); | 76 | extern void check_efer(void); |
77 | 77 | ||
78 | extern int unhandled_signal(struct task_struct *tsk, int sig); | ||
79 | |||
80 | extern void select_idle_routine(const struct cpuinfo_x86 *c); | 78 | extern void select_idle_routine(const struct cpuinfo_x86 *c); |
81 | 79 | ||
82 | extern unsigned long table_start, table_end; | 80 | extern unsigned long table_start, table_end; |
diff --git a/include/asm-x86_64/suspend.h b/include/asm-x86_64/suspend.h index 9c3f8de90d2d..b897e8cb55fb 100644 --- a/include/asm-x86_64/suspend.h +++ b/include/asm-x86_64/suspend.h | |||
@@ -44,7 +44,6 @@ extern unsigned long saved_context_eflags; | |||
44 | 44 | ||
45 | extern void fix_processor_context(void); | 45 | extern void fix_processor_context(void); |
46 | 46 | ||
47 | #ifdef CONFIG_ACPI_SLEEP | ||
48 | extern unsigned long saved_rip; | 47 | extern unsigned long saved_rip; |
49 | extern unsigned long saved_rsp; | 48 | extern unsigned long saved_rsp; |
50 | extern unsigned long saved_rbp; | 49 | extern unsigned long saved_rbp; |
@@ -54,4 +53,3 @@ extern unsigned long saved_rdi; | |||
54 | 53 | ||
55 | /* routines for saving/restoring kernel state */ | 54 | /* routines for saving/restoring kernel state */ |
56 | extern int acpi_save_state_mem(void); | 55 | extern int acpi_save_state_mem(void); |
57 | #endif | ||
diff --git a/include/asm-x86_64/system.h b/include/asm-x86_64/system.h index 6313d33a0686..02175aa1d16a 100644 --- a/include/asm-x86_64/system.h +++ b/include/asm-x86_64/system.h | |||
@@ -75,19 +75,31 @@ static inline unsigned long read_cr0(void) | |||
75 | unsigned long cr0; | 75 | unsigned long cr0; |
76 | asm volatile("movq %%cr0,%0" : "=r" (cr0)); | 76 | asm volatile("movq %%cr0,%0" : "=r" (cr0)); |
77 | return cr0; | 77 | return cr0; |
78 | } | 78 | } |
79 | 79 | ||
80 | static inline void write_cr0(unsigned long val) | 80 | static inline void write_cr0(unsigned long val) |
81 | { | 81 | { |
82 | asm volatile("movq %0,%%cr0" :: "r" (val)); | 82 | asm volatile("movq %0,%%cr0" :: "r" (val)); |
83 | } | 83 | } |
84 | |||
85 | static inline unsigned long read_cr2(void) | ||
86 | { | ||
87 | unsigned long cr2; | ||
88 | asm("movq %%cr2,%0" : "=r" (cr2)); | ||
89 | return cr2; | ||
90 | } | ||
91 | |||
92 | static inline void write_cr2(unsigned long val) | ||
93 | { | ||
94 | asm volatile("movq %0,%%cr2" :: "r" (val)); | ||
95 | } | ||
84 | 96 | ||
85 | static inline unsigned long read_cr3(void) | 97 | static inline unsigned long read_cr3(void) |
86 | { | 98 | { |
87 | unsigned long cr3; | 99 | unsigned long cr3; |
88 | asm("movq %%cr3,%0" : "=r" (cr3)); | 100 | asm("movq %%cr3,%0" : "=r" (cr3)); |
89 | return cr3; | 101 | return cr3; |
90 | } | 102 | } |
91 | 103 | ||
92 | static inline void write_cr3(unsigned long val) | 104 | static inline void write_cr3(unsigned long val) |
93 | { | 105 | { |
@@ -99,12 +111,24 @@ static inline unsigned long read_cr4(void) | |||
99 | unsigned long cr4; | 111 | unsigned long cr4; |
100 | asm("movq %%cr4,%0" : "=r" (cr4)); | 112 | asm("movq %%cr4,%0" : "=r" (cr4)); |
101 | return cr4; | 113 | return cr4; |
102 | } | 114 | } |
103 | 115 | ||
104 | static inline void write_cr4(unsigned long val) | 116 | static inline void write_cr4(unsigned long val) |
105 | { | 117 | { |
106 | asm volatile("movq %0,%%cr4" :: "r" (val) : "memory"); | 118 | asm volatile("movq %0,%%cr4" :: "r" (val) : "memory"); |
107 | } | 119 | } |
120 | |||
121 | static inline unsigned long read_cr8(void) | ||
122 | { | ||
123 | unsigned long cr8; | ||
124 | asm("movq %%cr8,%0" : "=r" (cr8)); | ||
125 | return cr8; | ||
126 | } | ||
127 | |||
128 | static inline void write_cr8(unsigned long val) | ||
129 | { | ||
130 | asm volatile("movq %0,%%cr8" :: "r" (val) : "memory"); | ||
131 | } | ||
108 | 132 | ||
109 | #define stts() write_cr0(8 | read_cr0()) | 133 | #define stts() write_cr0(8 | read_cr0()) |
110 | 134 | ||
diff --git a/include/linux/audit.h b/include/linux/audit.h index 8ca7ca0b47f0..4bbd8601b8f0 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h | |||
@@ -161,7 +161,7 @@ | |||
161 | * are currently used in an audit field constant understood by the kernel. | 161 | * are currently used in an audit field constant understood by the kernel. |
162 | * If you are adding a new #define AUDIT_<whatever>, please ensure that | 162 | * If you are adding a new #define AUDIT_<whatever>, please ensure that |
163 | * AUDIT_UNUSED_BITS is updated if need be. */ | 163 | * AUDIT_UNUSED_BITS is updated if need be. */ |
164 | #define AUDIT_UNUSED_BITS 0x0FFFFC00 | 164 | #define AUDIT_UNUSED_BITS 0x07FFFC00 |
165 | 165 | ||
166 | 166 | ||
167 | /* Rule fields */ | 167 | /* Rule fields */ |
@@ -213,25 +213,29 @@ | |||
213 | #define AUDIT_NEGATE 0x80000000 | 213 | #define AUDIT_NEGATE 0x80000000 |
214 | 214 | ||
215 | /* These are the supported operators. | 215 | /* These are the supported operators. |
216 | * 4 2 1 | 216 | * 4 2 1 8 |
217 | * = > < | 217 | * = > < ? |
218 | * ------- | 218 | * ---------- |
219 | * 0 0 0 0 nonsense | 219 | * 0 0 0 0 00 nonsense |
220 | * 0 0 1 1 < | 220 | * 0 0 0 1 08 & bit mask |
221 | * 0 1 0 2 > | 221 | * 0 0 1 0 10 < |
222 | * 0 1 1 3 != | 222 | * 0 1 0 0 20 > |
223 | * 1 0 0 4 = | 223 | * 0 1 1 0 30 != |
224 | * 1 0 1 5 <= | 224 | * 1 0 0 0 40 = |
225 | * 1 1 0 6 >= | 225 | * 1 0 0 1 48 &= bit test |
226 | * 1 1 1 7 all operators | 226 | * 1 0 1 0 50 <= |
227 | * 1 1 0 0 60 >= | ||
228 | * 1 1 1 1 78 all operators | ||
227 | */ | 229 | */ |
230 | #define AUDIT_BIT_MASK 0x08000000 | ||
228 | #define AUDIT_LESS_THAN 0x10000000 | 231 | #define AUDIT_LESS_THAN 0x10000000 |
229 | #define AUDIT_GREATER_THAN 0x20000000 | 232 | #define AUDIT_GREATER_THAN 0x20000000 |
230 | #define AUDIT_NOT_EQUAL 0x30000000 | 233 | #define AUDIT_NOT_EQUAL 0x30000000 |
231 | #define AUDIT_EQUAL 0x40000000 | 234 | #define AUDIT_EQUAL 0x40000000 |
235 | #define AUDIT_BIT_TEST (AUDIT_BIT_MASK|AUDIT_EQUAL) | ||
232 | #define AUDIT_LESS_THAN_OR_EQUAL (AUDIT_LESS_THAN|AUDIT_EQUAL) | 236 | #define AUDIT_LESS_THAN_OR_EQUAL (AUDIT_LESS_THAN|AUDIT_EQUAL) |
233 | #define AUDIT_GREATER_THAN_OR_EQUAL (AUDIT_GREATER_THAN|AUDIT_EQUAL) | 237 | #define AUDIT_GREATER_THAN_OR_EQUAL (AUDIT_GREATER_THAN|AUDIT_EQUAL) |
234 | #define AUDIT_OPERATORS (AUDIT_EQUAL|AUDIT_NOT_EQUAL) | 238 | #define AUDIT_OPERATORS (AUDIT_EQUAL|AUDIT_NOT_EQUAL|AUDIT_BIT_MASK) |
235 | 239 | ||
236 | /* Status symbols */ | 240 | /* Status symbols */ |
237 | /* Mask values */ | 241 | /* Mask values */ |
@@ -407,7 +411,6 @@ extern int audit_bprm(struct linux_binprm *bprm); | |||
407 | extern int audit_socketcall(int nargs, unsigned long *args); | 411 | extern int audit_socketcall(int nargs, unsigned long *args); |
408 | extern int audit_sockaddr(int len, void *addr); | 412 | extern int audit_sockaddr(int len, void *addr); |
409 | extern int __audit_fd_pair(int fd1, int fd2); | 413 | extern int __audit_fd_pair(int fd1, int fd2); |
410 | extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt); | ||
411 | extern int audit_set_macxattr(const char *name); | 414 | extern int audit_set_macxattr(const char *name); |
412 | extern int __audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr); | 415 | extern int __audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr); |
413 | extern int __audit_mq_timedsend(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec __user *u_abs_timeout); | 416 | extern int __audit_mq_timedsend(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec __user *u_abs_timeout); |
@@ -487,7 +490,6 @@ extern int audit_signals; | |||
487 | #define audit_socketcall(n,a) ({ 0; }) | 490 | #define audit_socketcall(n,a) ({ 0; }) |
488 | #define audit_fd_pair(n,a) ({ 0; }) | 491 | #define audit_fd_pair(n,a) ({ 0; }) |
489 | #define audit_sockaddr(len, addr) ({ 0; }) | 492 | #define audit_sockaddr(len, addr) ({ 0; }) |
490 | #define audit_avc_path(dentry, mnt) ({ 0; }) | ||
491 | #define audit_set_macxattr(n) do { ; } while (0) | 493 | #define audit_set_macxattr(n) do { ; } while (0) |
492 | #define audit_mq_open(o,m,a) ({ 0; }) | 494 | #define audit_mq_open(o,m,a) ({ 0; }) |
493 | #define audit_mq_timedsend(d,l,p,t) ({ 0; }) | 495 | #define audit_mq_timedsend(d,l,p,t) ({ 0; }) |
diff --git a/include/linux/backlight.h b/include/linux/backlight.h index 1023ba0d6e55..c897c7b03858 100644 --- a/include/linux/backlight.h +++ b/include/linux/backlight.h | |||
@@ -69,8 +69,8 @@ struct backlight_device { | |||
69 | 69 | ||
70 | /* The framebuffer notifier block */ | 70 | /* The framebuffer notifier block */ |
71 | struct notifier_block fb_notif; | 71 | struct notifier_block fb_notif; |
72 | /* The class device structure */ | 72 | |
73 | struct class_device class_dev; | 73 | struct device dev; |
74 | }; | 74 | }; |
75 | 75 | ||
76 | static inline void backlight_update_status(struct backlight_device *bd) | 76 | static inline void backlight_update_status(struct backlight_device *bd) |
@@ -85,6 +85,11 @@ extern struct backlight_device *backlight_device_register(const char *name, | |||
85 | struct device *dev, void *devdata, struct backlight_ops *ops); | 85 | struct device *dev, void *devdata, struct backlight_ops *ops); |
86 | extern void backlight_device_unregister(struct backlight_device *bd); | 86 | extern void backlight_device_unregister(struct backlight_device *bd); |
87 | 87 | ||
88 | #define to_backlight_device(obj) container_of(obj, struct backlight_device, class_dev) | 88 | #define to_backlight_device(obj) container_of(obj, struct backlight_device, dev) |
89 | |||
90 | static inline void * bl_get_data(struct backlight_device *bl_dev) | ||
91 | { | ||
92 | return dev_get_drvdata(&bl_dev->dev); | ||
93 | } | ||
89 | 94 | ||
90 | #endif | 95 | #endif |
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index f78965fc6426..695e34964cb7 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -698,11 +698,6 @@ extern int blk_execute_rq(request_queue_t *, struct gendisk *, | |||
698 | struct request *, int); | 698 | struct request *, int); |
699 | extern void blk_execute_rq_nowait(request_queue_t *, struct gendisk *, | 699 | extern void blk_execute_rq_nowait(request_queue_t *, struct gendisk *, |
700 | struct request *, int, rq_end_io_fn *); | 700 | struct request *, int, rq_end_io_fn *); |
701 | extern int blk_fill_sghdr_rq(request_queue_t *, struct request *, | ||
702 | struct sg_io_hdr *, int); | ||
703 | extern int blk_unmap_sghdr_rq(struct request *, struct sg_io_hdr *); | ||
704 | extern int blk_complete_sghdr_rq(struct request *, struct sg_io_hdr *, | ||
705 | struct bio *); | ||
706 | extern int blk_verify_command(unsigned char *, int); | 701 | extern int blk_verify_command(unsigned char *, int); |
707 | 702 | ||
708 | static inline request_queue_t *bdev_get_queue(struct block_device *bdev) | 703 | static inline request_queue_t *bdev_get_queue(struct block_device *bdev) |
diff --git a/include/linux/bsg.h b/include/linux/bsg.h index 8547b10c388b..f415f89e0ac8 100644 --- a/include/linux/bsg.h +++ b/include/linux/bsg.h | |||
@@ -57,10 +57,10 @@ struct bsg_class_device { | |||
57 | struct request_queue *queue; | 57 | struct request_queue *queue; |
58 | }; | 58 | }; |
59 | 59 | ||
60 | extern int bsg_register_queue(struct request_queue *, const char *); | 60 | extern int bsg_register_queue(struct request_queue *, struct device *, const char *); |
61 | extern void bsg_unregister_queue(struct request_queue *); | 61 | extern void bsg_unregister_queue(struct request_queue *); |
62 | #else | 62 | #else |
63 | #define bsg_register_queue(disk, name) (0) | 63 | #define bsg_register_queue(disk, dev, name) (0) |
64 | #define bsg_unregister_queue(disk) do { } while (0) | 64 | #define bsg_unregister_queue(disk) do { } while (0) |
65 | #endif | 65 | #endif |
66 | 66 | ||
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 5323f6275854..0a3c2ebf2008 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h | |||
@@ -120,11 +120,11 @@ extern void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id); | |||
120 | # define local_irq_enable_in_hardirq() local_irq_enable() | 120 | # define local_irq_enable_in_hardirq() local_irq_enable() |
121 | #endif | 121 | #endif |
122 | 122 | ||
123 | #ifdef CONFIG_GENERIC_HARDIRQS | ||
124 | extern void disable_irq_nosync(unsigned int irq); | 123 | extern void disable_irq_nosync(unsigned int irq); |
125 | extern void disable_irq(unsigned int irq); | 124 | extern void disable_irq(unsigned int irq); |
126 | extern void enable_irq(unsigned int irq); | 125 | extern void enable_irq(unsigned int irq); |
127 | 126 | ||
127 | #ifdef CONFIG_GENERIC_HARDIRQS | ||
128 | /* | 128 | /* |
129 | * Special lockdep variants of irq disabling/enabling. | 129 | * Special lockdep variants of irq disabling/enabling. |
130 | * These should be used for locking constructs that | 130 | * These should be used for locking constructs that |
diff --git a/include/linux/lcd.h b/include/linux/lcd.h index 598793c0745b..1d379787f2e7 100644 --- a/include/linux/lcd.h +++ b/include/linux/lcd.h | |||
@@ -62,8 +62,8 @@ struct lcd_device { | |||
62 | struct mutex update_lock; | 62 | struct mutex update_lock; |
63 | /* The framebuffer notifier block */ | 63 | /* The framebuffer notifier block */ |
64 | struct notifier_block fb_notif; | 64 | struct notifier_block fb_notif; |
65 | /* The class device structure */ | 65 | |
66 | struct class_device class_dev; | 66 | struct device dev; |
67 | }; | 67 | }; |
68 | 68 | ||
69 | static inline void lcd_set_power(struct lcd_device *ld, int power) | 69 | static inline void lcd_set_power(struct lcd_device *ld, int power) |
@@ -75,9 +75,15 @@ static inline void lcd_set_power(struct lcd_device *ld, int power) | |||
75 | } | 75 | } |
76 | 76 | ||
77 | extern struct lcd_device *lcd_device_register(const char *name, | 77 | extern struct lcd_device *lcd_device_register(const char *name, |
78 | void *devdata, struct lcd_ops *ops); | 78 | struct device *parent, void *devdata, struct lcd_ops *ops); |
79 | extern void lcd_device_unregister(struct lcd_device *ld); | 79 | extern void lcd_device_unregister(struct lcd_device *ld); |
80 | 80 | ||
81 | #define to_lcd_device(obj) container_of(obj, struct lcd_device, class_dev) | 81 | #define to_lcd_device(obj) container_of(obj, struct lcd_device, dev) |
82 | |||
83 | static inline void * lcd_get_data(struct lcd_device *ld_dev) | ||
84 | { | ||
85 | return dev_get_drvdata(&ld_dev->dev); | ||
86 | } | ||
87 | |||
82 | 88 | ||
83 | #endif | 89 | #endif |
diff --git a/include/linux/leds.h b/include/linux/leds.h index 494bed7c2fc1..421175092ee2 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/list.h> | 15 | #include <linux/list.h> |
16 | 16 | ||
17 | struct device; | 17 | struct device; |
18 | struct class_device; | ||
19 | /* | 18 | /* |
20 | * LED Core | 19 | * LED Core |
21 | */ | 20 | */ |
@@ -37,7 +36,7 @@ struct led_classdev { | |||
37 | void (*brightness_set)(struct led_classdev *led_cdev, | 36 | void (*brightness_set)(struct led_classdev *led_cdev, |
38 | enum led_brightness brightness); | 37 | enum led_brightness brightness); |
39 | 38 | ||
40 | struct class_device *class_dev; | 39 | struct device *dev; |
41 | struct list_head node; /* LED Device list */ | 40 | struct list_head node; /* LED Device list */ |
42 | char *default_trigger; /* Trigger to use */ | 41 | char *default_trigger; /* Trigger to use */ |
43 | 42 | ||
@@ -109,4 +108,18 @@ extern void ledtrig_ide_activity(void); | |||
109 | #define ledtrig_ide_activity() do {} while(0) | 108 | #define ledtrig_ide_activity() do {} while(0) |
110 | #endif | 109 | #endif |
111 | 110 | ||
111 | /* For the leds-gpio driver */ | ||
112 | struct gpio_led { | ||
113 | const char *name; | ||
114 | char *default_trigger; | ||
115 | unsigned gpio; | ||
116 | u8 active_low; | ||
117 | }; | ||
118 | |||
119 | struct gpio_led_platform_data { | ||
120 | int num_leds; | ||
121 | struct gpio_led *leds; | ||
122 | }; | ||
123 | |||
124 | |||
112 | #endif /* __LINUX_LEDS_H_INCLUDED */ | 125 | #endif /* __LINUX_LEDS_H_INCLUDED */ |
diff --git a/include/linux/libata.h b/include/linux/libata.h index be5a43928c84..9aa6c10f7bb1 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -412,6 +412,7 @@ struct ata_queued_cmd { | |||
412 | ata_qc_cb_t complete_fn; | 412 | ata_qc_cb_t complete_fn; |
413 | 413 | ||
414 | void *private_data; | 414 | void *private_data; |
415 | void *lldd_task; | ||
415 | }; | 416 | }; |
416 | 417 | ||
417 | struct ata_port_stats { | 418 | struct ata_port_stats { |
diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h index 5fd44e63fb26..448f70b30a0c 100644 --- a/include/linux/of_platform.h +++ b/include/linux/of_platform.h | |||
@@ -31,8 +31,8 @@ extern struct bus_type of_platform_bus_type; | |||
31 | */ | 31 | */ |
32 | struct of_platform_driver | 32 | struct of_platform_driver |
33 | { | 33 | { |
34 | char *name; | 34 | const char *name; |
35 | struct of_device_id *match_table; | 35 | const struct of_device_id *match_table; |
36 | struct module *owner; | 36 | struct module *owner; |
37 | 37 | ||
38 | int (*probe)(struct of_device* dev, | 38 | int (*probe)(struct of_device* dev, |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index b15c6498fe67..cbabb9c675c9 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -2019,6 +2019,8 @@ | |||
2019 | 2019 | ||
2020 | #define PCI_VENDOR_ID_ARIMA 0x161f | 2020 | #define PCI_VENDOR_ID_ARIMA 0x161f |
2021 | 2021 | ||
2022 | #define PCI_VENDOR_ID_BROCADE 0x1657 | ||
2023 | |||
2022 | #define PCI_VENDOR_ID_SIBYTE 0x166d | 2024 | #define PCI_VENDOR_ID_SIBYTE 0x166d |
2023 | #define PCI_DEVICE_ID_BCM1250_PCI 0x0001 | 2025 | #define PCI_DEVICE_ID_BCM1250_PCI 0x0001 |
2024 | #define PCI_DEVICE_ID_BCM1250_HT 0x0002 | 2026 | #define PCI_DEVICE_ID_BCM1250_HT 0x0002 |
@@ -2040,6 +2042,8 @@ | |||
2040 | #define PCI_DEVICE_ID_ALTIMA_AC9100 0x03ea | 2042 | #define PCI_DEVICE_ID_ALTIMA_AC9100 0x03ea |
2041 | #define PCI_DEVICE_ID_ALTIMA_AC1003 0x03eb | 2043 | #define PCI_DEVICE_ID_ALTIMA_AC1003 0x03eb |
2042 | 2044 | ||
2045 | #define PCI_VENDOR_ID_LENOVO 0x17aa | ||
2046 | |||
2043 | #define PCI_VENDOR_ID_ARECA 0x17d3 | 2047 | #define PCI_VENDOR_ID_ARECA 0x17d3 |
2044 | #define PCI_DEVICE_ID_ARECA_1110 0x1110 | 2048 | #define PCI_DEVICE_ID_ARECA_1110 0x1110 |
2045 | #define PCI_DEVICE_ID_ARECA_1120 0x1120 | 2049 | #define PCI_DEVICE_ID_ARECA_1120 0x1120 |
diff --git a/include/linux/signal.h b/include/linux/signal.h index ea91abe740da..0ae338866240 100644 --- a/include/linux/signal.h +++ b/include/linux/signal.h | |||
@@ -237,12 +237,15 @@ extern int group_send_sig_info(int sig, struct siginfo *info, struct task_struct | |||
237 | extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *); | 237 | extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *); |
238 | extern long do_sigpending(void __user *, unsigned long); | 238 | extern long do_sigpending(void __user *, unsigned long); |
239 | extern int sigprocmask(int, sigset_t *, sigset_t *); | 239 | extern int sigprocmask(int, sigset_t *, sigset_t *); |
240 | extern int show_unhandled_signals; | ||
240 | 241 | ||
241 | struct pt_regs; | 242 | struct pt_regs; |
242 | extern int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, struct pt_regs *regs, void *cookie); | 243 | extern int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, struct pt_regs *regs, void *cookie); |
243 | 244 | ||
244 | extern struct kmem_cache *sighand_cachep; | 245 | extern struct kmem_cache *sighand_cachep; |
245 | 246 | ||
247 | int unhandled_signal(struct task_struct *tsk, int sig); | ||
248 | |||
246 | /* | 249 | /* |
247 | * In POSIX a signal is sent either to a specific thread (Linux task) | 250 | * In POSIX a signal is sent either to a specific thread (Linux task) |
248 | * or to the process as a whole (Linux thread group). How the signal | 251 | * or to the process as a whole (Linux thread group). How the signal |
diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index 2e6bdc4e7a0a..df36461fe881 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/timer.h> | 30 | #include <linux/timer.h> |
31 | #include <linux/pci.h> | 31 | #include <linux/pci.h> |
32 | #include <scsi/sas.h> | 32 | #include <scsi/sas.h> |
33 | #include <linux/libata.h> | ||
33 | #include <linux/list.h> | 34 | #include <linux/list.h> |
34 | #include <asm/semaphore.h> | 35 | #include <asm/semaphore.h> |
35 | #include <scsi/scsi_device.h> | 36 | #include <scsi/scsi_device.h> |
@@ -165,6 +166,13 @@ struct sata_device { | |||
165 | 166 | ||
166 | u8 port_no; /* port number, if this is a PM (Port) */ | 167 | u8 port_no; /* port number, if this is a PM (Port) */ |
167 | struct list_head children; /* PM Ports if this is a PM */ | 168 | struct list_head children; /* PM Ports if this is a PM */ |
169 | |||
170 | struct ata_port *ap; | ||
171 | struct ata_host ata_host; | ||
172 | struct ata_taskfile tf; | ||
173 | u32 sstatus; | ||
174 | u32 serror; | ||
175 | u32 scontrol; | ||
168 | }; | 176 | }; |
169 | 177 | ||
170 | /* ---------- Domain device ---------- */ | 178 | /* ---------- Domain device ---------- */ |
@@ -624,6 +632,7 @@ int sas_set_phy_speed(struct sas_phy *phy, | |||
624 | struct sas_phy_linkrates *rates); | 632 | struct sas_phy_linkrates *rates); |
625 | int sas_phy_enable(struct sas_phy *phy, int enabled); | 633 | int sas_phy_enable(struct sas_phy *phy, int enabled); |
626 | int sas_phy_reset(struct sas_phy *phy, int hard_reset); | 634 | int sas_phy_reset(struct sas_phy *phy, int hard_reset); |
635 | int sas_queue_up(struct sas_task *task); | ||
627 | extern int sas_queuecommand(struct scsi_cmnd *, | 636 | extern int sas_queuecommand(struct scsi_cmnd *, |
628 | void (*scsi_done)(struct scsi_cmnd *)); | 637 | void (*scsi_done)(struct scsi_cmnd *)); |
629 | extern int sas_target_alloc(struct scsi_target *); | 638 | extern int sas_target_alloc(struct scsi_target *); |
@@ -661,4 +670,10 @@ int __sas_task_abort(struct sas_task *); | |||
661 | int sas_eh_device_reset_handler(struct scsi_cmnd *cmd); | 670 | int sas_eh_device_reset_handler(struct scsi_cmnd *cmd); |
662 | int sas_eh_bus_reset_handler(struct scsi_cmnd *cmd); | 671 | int sas_eh_bus_reset_handler(struct scsi_cmnd *cmd); |
663 | 672 | ||
673 | extern void sas_target_destroy(struct scsi_target *); | ||
674 | extern int sas_slave_alloc(struct scsi_device *); | ||
675 | extern int sas_ioctl(struct scsi_device *sdev, int cmd, void __user *arg); | ||
676 | |||
677 | extern int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, | ||
678 | struct request *req); | ||
664 | #endif /* _SASLIB_H_ */ | 679 | #endif /* _SASLIB_H_ */ |
diff --git a/include/scsi/sas_ata.h b/include/scsi/sas_ata.h new file mode 100644 index 000000000000..dd5edc915417 --- /dev/null +++ b/include/scsi/sas_ata.h | |||
@@ -0,0 +1,60 @@ | |||
1 | /* | ||
2 | * Support for SATA devices on Serial Attached SCSI (SAS) controllers | ||
3 | * | ||
4 | * Copyright (C) 2006 IBM Corporation | ||
5 | * | ||
6 | * Written by: Darrick J. Wong <djwong@us.ibm.com>, IBM Corporation | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License as | ||
10 | * published by the Free Software Foundation; either version 2 of the | ||
11 | * License, or (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * 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, MA 02111-1307 | ||
21 | * USA | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | #ifndef _SAS_ATA_H_ | ||
26 | #define _SAS_ATA_H_ | ||
27 | |||
28 | #include <linux/libata.h> | ||
29 | #include <scsi/libsas.h> | ||
30 | |||
31 | #ifdef CONFIG_SCSI_SAS_ATA | ||
32 | |||
33 | static inline int dev_is_sata(struct domain_device *dev) | ||
34 | { | ||
35 | return (dev->rphy->identify.target_port_protocols & SAS_PROTOCOL_SATA); | ||
36 | } | ||
37 | |||
38 | int sas_ata_init_host_and_port(struct domain_device *found_dev, | ||
39 | struct scsi_target *starget); | ||
40 | |||
41 | void sas_ata_task_abort(struct sas_task *task); | ||
42 | |||
43 | #else | ||
44 | |||
45 | |||
46 | static inline int dev_is_sata(struct domain_device *dev) | ||
47 | { | ||
48 | return 0; | ||
49 | } | ||
50 | int sas_ata_init_host_and_port(struct domain_device *found_dev, | ||
51 | struct scsi_target *starget) | ||
52 | { | ||
53 | return 0; | ||
54 | } | ||
55 | void sas_ata_task_abort(struct sas_task *task) | ||
56 | { | ||
57 | } | ||
58 | #endif | ||
59 | |||
60 | #endif /* _SAS_ATA_H_ */ | ||
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index ba07cf7c04ba..3b8a6a85c2f8 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h | |||
@@ -341,7 +341,7 @@ struct scsi_host_template { | |||
341 | /* | 341 | /* |
342 | * Name of proc directory | 342 | * Name of proc directory |
343 | */ | 343 | */ |
344 | char *proc_name; | 344 | const char *proc_name; |
345 | 345 | ||
346 | /* | 346 | /* |
347 | * Used to store the procfs directory if a driver implements the | 347 | * Used to store the procfs directory if a driver implements the |
diff --git a/include/scsi/scsi_transport_sas.h b/include/scsi/scsi_transport_sas.h index 9aedc19820b0..abdfd2e27dd7 100644 --- a/include/scsi/scsi_transport_sas.h +++ b/include/scsi/scsi_transport_sas.h | |||
@@ -7,7 +7,7 @@ | |||
7 | 7 | ||
8 | struct scsi_transport_template; | 8 | struct scsi_transport_template; |
9 | struct sas_rphy; | 9 | struct sas_rphy; |
10 | 10 | struct request; | |
11 | 11 | ||
12 | enum sas_device_type { | 12 | enum sas_device_type { |
13 | SAS_PHY_UNUSED, | 13 | SAS_PHY_UNUSED, |
@@ -23,6 +23,12 @@ enum sas_protocol { | |||
23 | SAS_PROTOCOL_SSP = 0x08, | 23 | SAS_PROTOCOL_SSP = 0x08, |
24 | }; | 24 | }; |
25 | 25 | ||
26 | static inline int sas_protocol_ata(enum sas_protocol proto) | ||
27 | { | ||
28 | return ((proto & SAS_PROTOCOL_SATA) || | ||
29 | (proto & SAS_PROTOCOL_STP))? 1 : 0; | ||
30 | } | ||
31 | |||
26 | enum sas_linkrate { | 32 | enum sas_linkrate { |
27 | /* These Values are defined in the SAS standard */ | 33 | /* These Values are defined in the SAS standard */ |
28 | SAS_LINK_RATE_UNKNOWN = 0, | 34 | SAS_LINK_RATE_UNKNOWN = 0, |
@@ -85,10 +91,12 @@ struct sas_phy { | |||
85 | #define phy_to_shost(phy) \ | 91 | #define phy_to_shost(phy) \ |
86 | dev_to_shost((phy)->dev.parent) | 92 | dev_to_shost((phy)->dev.parent) |
87 | 93 | ||
94 | struct request_queue; | ||
88 | struct sas_rphy { | 95 | struct sas_rphy { |
89 | struct device dev; | 96 | struct device dev; |
90 | struct sas_identify identify; | 97 | struct sas_identify identify; |
91 | struct list_head list; | 98 | struct list_head list; |
99 | struct request_queue *q; | ||
92 | u32 scsi_target_id; | 100 | u32 scsi_target_id; |
93 | }; | 101 | }; |
94 | 102 | ||
@@ -166,6 +174,7 @@ struct sas_function_template { | |||
166 | int (*phy_reset)(struct sas_phy *, int); | 174 | int (*phy_reset)(struct sas_phy *, int); |
167 | int (*phy_enable)(struct sas_phy *, int); | 175 | int (*phy_enable)(struct sas_phy *, int); |
168 | int (*set_phy_speed)(struct sas_phy *, struct sas_phy_linkrates *); | 176 | int (*set_phy_speed)(struct sas_phy *, struct sas_phy_linkrates *); |
177 | int (*smp_handler)(struct Scsi_Host *, struct sas_rphy *, struct request *); | ||
169 | }; | 178 | }; |
170 | 179 | ||
171 | 180 | ||
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 1bf093dcffe0..359645cff5b2 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c | |||
@@ -304,7 +304,7 @@ int __init audit_register_class(int class, unsigned *list) | |||
304 | 304 | ||
305 | int audit_match_class(int class, unsigned syscall) | 305 | int audit_match_class(int class, unsigned syscall) |
306 | { | 306 | { |
307 | if (unlikely(syscall >= AUDIT_BITMASK_SIZE * sizeof(__u32))) | 307 | if (unlikely(syscall >= AUDIT_BITMASK_SIZE * 32)) |
308 | return 0; | 308 | return 0; |
309 | if (unlikely(class >= AUDIT_SYSCALL_CLASSES || !classes[class])) | 309 | if (unlikely(class >= AUDIT_SYSCALL_CLASSES || !classes[class])) |
310 | return 0; | 310 | return 0; |
@@ -456,6 +456,13 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule) | |||
456 | case AUDIT_DEVMINOR: | 456 | case AUDIT_DEVMINOR: |
457 | case AUDIT_EXIT: | 457 | case AUDIT_EXIT: |
458 | case AUDIT_SUCCESS: | 458 | case AUDIT_SUCCESS: |
459 | /* bit ops are only useful on syscall args */ | ||
460 | if (f->op == AUDIT_BIT_MASK || | ||
461 | f->op == AUDIT_BIT_TEST) { | ||
462 | err = -EINVAL; | ||
463 | goto exit_free; | ||
464 | } | ||
465 | break; | ||
459 | case AUDIT_ARG0: | 466 | case AUDIT_ARG0: |
460 | case AUDIT_ARG1: | 467 | case AUDIT_ARG1: |
461 | case AUDIT_ARG2: | 468 | case AUDIT_ARG2: |
@@ -1566,6 +1573,10 @@ int audit_comparator(const u32 left, const u32 op, const u32 right) | |||
1566 | return (left > right); | 1573 | return (left > right); |
1567 | case AUDIT_GREATER_THAN_OR_EQUAL: | 1574 | case AUDIT_GREATER_THAN_OR_EQUAL: |
1568 | return (left >= right); | 1575 | return (left >= right); |
1576 | case AUDIT_BIT_MASK: | ||
1577 | return (left & right); | ||
1578 | case AUDIT_BIT_TEST: | ||
1579 | return ((left & right) == right); | ||
1569 | } | 1580 | } |
1570 | BUG(); | 1581 | BUG(); |
1571 | return 0; | 1582 | return 0; |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 145cbb79c4b9..bde1124d5908 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -173,12 +173,6 @@ struct audit_aux_data_fd_pair { | |||
173 | int fd[2]; | 173 | int fd[2]; |
174 | }; | 174 | }; |
175 | 175 | ||
176 | struct audit_aux_data_path { | ||
177 | struct audit_aux_data d; | ||
178 | struct dentry *dentry; | ||
179 | struct vfsmount *mnt; | ||
180 | }; | ||
181 | |||
182 | struct audit_aux_data_pids { | 176 | struct audit_aux_data_pids { |
183 | struct audit_aux_data d; | 177 | struct audit_aux_data d; |
184 | pid_t target_pid[AUDIT_AUX_PIDS]; | 178 | pid_t target_pid[AUDIT_AUX_PIDS]; |
@@ -654,12 +648,6 @@ static inline void audit_free_aux(struct audit_context *context) | |||
654 | struct audit_aux_data *aux; | 648 | struct audit_aux_data *aux; |
655 | 649 | ||
656 | while ((aux = context->aux)) { | 650 | while ((aux = context->aux)) { |
657 | if (aux->type == AUDIT_AVC_PATH) { | ||
658 | struct audit_aux_data_path *axi = (void *)aux; | ||
659 | dput(axi->dentry); | ||
660 | mntput(axi->mnt); | ||
661 | } | ||
662 | |||
663 | context->aux = aux->next; | 651 | context->aux = aux->next; |
664 | kfree(aux); | 652 | kfree(aux); |
665 | } | 653 | } |
@@ -995,7 +983,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
995 | case AUDIT_IPC: { | 983 | case AUDIT_IPC: { |
996 | struct audit_aux_data_ipcctl *axi = (void *)aux; | 984 | struct audit_aux_data_ipcctl *axi = (void *)aux; |
997 | audit_log_format(ab, | 985 | audit_log_format(ab, |
998 | "ouid=%u ogid=%u mode=%x", | 986 | "ouid=%u ogid=%u mode=%#o", |
999 | axi->uid, axi->gid, axi->mode); | 987 | axi->uid, axi->gid, axi->mode); |
1000 | if (axi->osid != 0) { | 988 | if (axi->osid != 0) { |
1001 | char *ctx = NULL; | 989 | char *ctx = NULL; |
@@ -1014,7 +1002,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
1014 | case AUDIT_IPC_SET_PERM: { | 1002 | case AUDIT_IPC_SET_PERM: { |
1015 | struct audit_aux_data_ipcctl *axi = (void *)aux; | 1003 | struct audit_aux_data_ipcctl *axi = (void *)aux; |
1016 | audit_log_format(ab, | 1004 | audit_log_format(ab, |
1017 | "qbytes=%lx ouid=%u ogid=%u mode=%x", | 1005 | "qbytes=%lx ouid=%u ogid=%u mode=%#o", |
1018 | axi->qbytes, axi->uid, axi->gid, axi->mode); | 1006 | axi->qbytes, axi->uid, axi->gid, axi->mode); |
1019 | break; } | 1007 | break; } |
1020 | 1008 | ||
@@ -1038,11 +1026,6 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
1038 | audit_log_hex(ab, axs->a, axs->len); | 1026 | audit_log_hex(ab, axs->a, axs->len); |
1039 | break; } | 1027 | break; } |
1040 | 1028 | ||
1041 | case AUDIT_AVC_PATH: { | ||
1042 | struct audit_aux_data_path *axi = (void *)aux; | ||
1043 | audit_log_d_path(ab, "path=", axi->dentry, axi->mnt); | ||
1044 | break; } | ||
1045 | |||
1046 | case AUDIT_FD_PAIR: { | 1029 | case AUDIT_FD_PAIR: { |
1047 | struct audit_aux_data_fd_pair *axs = (void *)aux; | 1030 | struct audit_aux_data_fd_pair *axs = (void *)aux; |
1048 | audit_log_format(ab, "fd0=%d fd1=%d", axs->fd[0], axs->fd[1]); | 1031 | audit_log_format(ab, "fd0=%d fd1=%d", axs->fd[0], axs->fd[1]); |
@@ -1991,36 +1974,6 @@ void __audit_ptrace(struct task_struct *t) | |||
1991 | } | 1974 | } |
1992 | 1975 | ||
1993 | /** | 1976 | /** |
1994 | * audit_avc_path - record the granting or denial of permissions | ||
1995 | * @dentry: dentry to record | ||
1996 | * @mnt: mnt to record | ||
1997 | * | ||
1998 | * Returns 0 for success or NULL context or < 0 on error. | ||
1999 | * | ||
2000 | * Called from security/selinux/avc.c::avc_audit() | ||
2001 | */ | ||
2002 | int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt) | ||
2003 | { | ||
2004 | struct audit_aux_data_path *ax; | ||
2005 | struct audit_context *context = current->audit_context; | ||
2006 | |||
2007 | if (likely(!context)) | ||
2008 | return 0; | ||
2009 | |||
2010 | ax = kmalloc(sizeof(*ax), GFP_ATOMIC); | ||
2011 | if (!ax) | ||
2012 | return -ENOMEM; | ||
2013 | |||
2014 | ax->dentry = dget(dentry); | ||
2015 | ax->mnt = mntget(mnt); | ||
2016 | |||
2017 | ax->d.type = AUDIT_AVC_PATH; | ||
2018 | ax->d.next = context->aux; | ||
2019 | context->aux = (void *)ax; | ||
2020 | return 0; | ||
2021 | } | ||
2022 | |||
2023 | /** | ||
2024 | * audit_signal_info - record signal info for shutting down audit subsystem | 1977 | * audit_signal_info - record signal info for shutting down audit subsystem |
2025 | * @sig: signal value | 1978 | * @sig: signal value |
2026 | * @t: task being signaled | 1979 | * @t: task being signaled |
diff --git a/kernel/signal.c b/kernel/signal.c index 39d122753bac..ef8156a6aad5 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -255,6 +255,16 @@ flush_signal_handlers(struct task_struct *t, int force_default) | |||
255 | } | 255 | } |
256 | } | 256 | } |
257 | 257 | ||
258 | int unhandled_signal(struct task_struct *tsk, int sig) | ||
259 | { | ||
260 | if (is_init(tsk)) | ||
261 | return 1; | ||
262 | if (tsk->ptrace & PT_PTRACED) | ||
263 | return 0; | ||
264 | return (tsk->sighand->action[sig-1].sa.sa_handler == SIG_IGN) || | ||
265 | (tsk->sighand->action[sig-1].sa.sa_handler == SIG_DFL); | ||
266 | } | ||
267 | |||
258 | 268 | ||
259 | /* Notify the system that a driver wants to block all signals for this | 269 | /* Notify the system that a driver wants to block all signals for this |
260 | * process, and wants to be notified if any signals at all were to be | 270 | * process, and wants to be notified if any signals at all were to be |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 222299844ad1..eb26f2ba51ed 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -689,7 +689,7 @@ static ctl_table kern_table[] = { | |||
689 | .proc_handler = &proc_dointvec, | 689 | .proc_handler = &proc_dointvec, |
690 | }, | 690 | }, |
691 | #endif | 691 | #endif |
692 | #ifdef CONFIG_ACPI_SLEEP | 692 | #if defined(CONFIG_ACPI) && defined(CONFIG_X86) |
693 | { | 693 | { |
694 | .ctl_name = KERN_ACPI_VIDEO_FLAGS, | 694 | .ctl_name = KERN_ACPI_VIDEO_FLAGS, |
695 | .procname = "acpi_video_flags", | 695 | .procname = "acpi_video_flags", |
@@ -1203,6 +1203,16 @@ static ctl_table fs_table[] = { | |||
1203 | }; | 1203 | }; |
1204 | 1204 | ||
1205 | static ctl_table debug_table[] = { | 1205 | static ctl_table debug_table[] = { |
1206 | #ifdef CONFIG_X86 | ||
1207 | { | ||
1208 | .ctl_name = CTL_UNNUMBERED, | ||
1209 | .procname = "exception-trace", | ||
1210 | .data = &show_unhandled_signals, | ||
1211 | .maxlen = sizeof(int), | ||
1212 | .mode = 0644, | ||
1213 | .proc_handler = proc_dointvec | ||
1214 | }, | ||
1215 | #endif | ||
1206 | { .ctl_name = 0 } | 1216 | { .ctl_name = 0 } |
1207 | }; | 1217 | }; |
1208 | 1218 | ||
diff --git a/mm/sparse.c b/mm/sparse.c index e03b39f3540f..3047bf06c1f3 100644 --- a/mm/sparse.c +++ b/mm/sparse.c | |||
@@ -209,7 +209,7 @@ static int __meminit sparse_init_one_section(struct mem_section *ms, | |||
209 | return 1; | 209 | return 1; |
210 | } | 210 | } |
211 | 211 | ||
212 | __attribute__((weak)) | 212 | __attribute__((weak)) __init |
213 | void *alloc_bootmem_high_node(pg_data_t *pgdat, unsigned long size) | 213 | void *alloc_bootmem_high_node(pg_data_t *pgdat, unsigned long size) |
214 | { | 214 | { |
215 | return NULL; | 215 | return NULL; |
diff --git a/net/9p/sysctl.c b/net/9p/sysctl.c index e7fe706ab95a..8b61027a24ea 100644 --- a/net/9p/sysctl.c +++ b/net/9p/sysctl.c | |||
@@ -28,15 +28,10 @@ | |||
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <net/9p/9p.h> | 29 | #include <net/9p/9p.h> |
30 | 30 | ||
31 | enum { | 31 | static struct ctl_table p9_table[] = { |
32 | P9_SYSCTL_NET = 487, | ||
33 | P9_SYSCTL_DEBUG = 1, | ||
34 | }; | ||
35 | |||
36 | static ctl_table p9_table[] = { | ||
37 | #ifdef CONFIG_NET_9P_DEBUG | 32 | #ifdef CONFIG_NET_9P_DEBUG |
38 | { | 33 | { |
39 | .ctl_name = P9_SYSCTL_DEBUG, | 34 | .ctl_name = CTL_UNNUMBERED, |
40 | .procname = "debug", | 35 | .procname = "debug", |
41 | .data = &p9_debug_level, | 36 | .data = &p9_debug_level, |
42 | .maxlen = sizeof(int), | 37 | .maxlen = sizeof(int), |
@@ -44,21 +39,21 @@ static ctl_table p9_table[] = { | |||
44 | .proc_handler = &proc_dointvec | 39 | .proc_handler = &proc_dointvec |
45 | }, | 40 | }, |
46 | #endif | 41 | #endif |
47 | { .ctl_name = 0 }, | 42 | {}, |
48 | }; | 43 | }; |
49 | 44 | ||
50 | static ctl_table p9_net_table[] = { | 45 | static struct ctl_table p9_net_table[] = { |
51 | { | 46 | { |
52 | .ctl_name = P9_SYSCTL_NET, | 47 | .ctl_name = CTL_UNNUMBERED, |
53 | .procname = "9p", | 48 | .procname = "9p", |
54 | .maxlen = 0, | 49 | .maxlen = 0, |
55 | .mode = 0555, | 50 | .mode = 0555, |
56 | .child = p9_table, | 51 | .child = p9_table, |
57 | }, | 52 | }, |
58 | { .ctl_name = 0 }, | 53 | {}, |
59 | }; | 54 | }; |
60 | 55 | ||
61 | static ctl_table p9_ctl_table[] = { | 56 | static struct ctl_table p9_ctl_table[] = { |
62 | { | 57 | { |
63 | .ctl_name = CTL_NET, | 58 | .ctl_name = CTL_NET, |
64 | .procname = "net", | 59 | .procname = "net", |
@@ -66,7 +61,7 @@ static ctl_table p9_ctl_table[] = { | |||
66 | .mode = 0555, | 61 | .mode = 0555, |
67 | .child = p9_net_table, | 62 | .child = p9_net_table, |
68 | }, | 63 | }, |
69 | { .ctl_name = 0 }, | 64 | {}, |
70 | }; | 65 | }; |
71 | 66 | ||
72 | static struct ctl_table_header *p9_table_header; | 67 | static struct ctl_table_header *p9_table_header; |
diff --git a/security/selinux/avc.c b/security/selinux/avc.c index ecd067384531..0e69adf63bdb 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c | |||
@@ -570,10 +570,12 @@ void avc_audit(u32 ssid, u32 tsid, | |||
570 | case AVC_AUDIT_DATA_FS: | 570 | case AVC_AUDIT_DATA_FS: |
571 | if (a->u.fs.dentry) { | 571 | if (a->u.fs.dentry) { |
572 | struct dentry *dentry = a->u.fs.dentry; | 572 | struct dentry *dentry = a->u.fs.dentry; |
573 | if (a->u.fs.mnt) | 573 | if (a->u.fs.mnt) { |
574 | audit_avc_path(dentry, a->u.fs.mnt); | 574 | audit_log_d_path(ab, "path=", dentry, a->u.fs.mnt); |
575 | audit_log_format(ab, " name="); | 575 | } else { |
576 | audit_log_untrustedstring(ab, dentry->d_name.name); | 576 | audit_log_format(ab, " name="); |
577 | audit_log_untrustedstring(ab, dentry->d_name.name); | ||
578 | } | ||
577 | inode = dentry->d_inode; | 579 | inode = dentry->d_inode; |
578 | } else if (a->u.fs.inode) { | 580 | } else if (a->u.fs.inode) { |
579 | struct dentry *dentry; | 581 | struct dentry *dentry; |
@@ -624,9 +626,8 @@ void avc_audit(u32 ssid, u32 tsid, | |||
624 | case AF_UNIX: | 626 | case AF_UNIX: |
625 | u = unix_sk(sk); | 627 | u = unix_sk(sk); |
626 | if (u->dentry) { | 628 | if (u->dentry) { |
627 | audit_avc_path(u->dentry, u->mnt); | 629 | audit_log_d_path(ab, "path=", |
628 | audit_log_format(ab, " name="); | 630 | u->dentry, u->mnt); |
629 | audit_log_untrustedstring(ab, u->dentry->d_name.name); | ||
630 | break; | 631 | break; |
631 | } | 632 | } |
632 | if (!u->addr) | 633 | if (!u->addr) |