diff options
553 files changed, 24297 insertions, 9742 deletions
diff --git a/Documentation/DocBook/s390-drivers.tmpl b/Documentation/DocBook/s390-drivers.tmpl index 254e769282a4..3d2f31b99dd9 100644 --- a/Documentation/DocBook/s390-drivers.tmpl +++ b/Documentation/DocBook/s390-drivers.tmpl | |||
@@ -116,6 +116,7 @@ | |||
116 | !Iinclude/asm-s390/ccwdev.h | 116 | !Iinclude/asm-s390/ccwdev.h |
117 | !Edrivers/s390/cio/device.c | 117 | !Edrivers/s390/cio/device.c |
118 | !Edrivers/s390/cio/device_ops.c | 118 | !Edrivers/s390/cio/device_ops.c |
119 | !Edrivers/s390/cio/airq.c | ||
119 | </sect1> | 120 | </sect1> |
120 | <sect1 id="cmf"> | 121 | <sect1 id="cmf"> |
121 | <title>The channel-measurement facility</title> | 122 | <title>The channel-measurement facility</title> |
diff --git a/Documentation/cpu-hotplug.txt b/Documentation/cpu-hotplug.txt index fb94f5a71b68..ba0aacde94fb 100644 --- a/Documentation/cpu-hotplug.txt +++ b/Documentation/cpu-hotplug.txt | |||
@@ -50,7 +50,7 @@ additional_cpus=n (*) Use this to limit hotpluggable cpus. This option sets | |||
50 | cpu_possible_map = cpu_present_map + additional_cpus | 50 | cpu_possible_map = cpu_present_map + additional_cpus |
51 | 51 | ||
52 | (*) Option valid only for following architectures | 52 | (*) Option valid only for following architectures |
53 | - x86_64, ia64, s390 | 53 | - x86_64, ia64 |
54 | 54 | ||
55 | ia64 and x86_64 use the number of disabled local apics in ACPI tables MADT | 55 | ia64 and x86_64 use the number of disabled local apics in ACPI tables MADT |
56 | to determine the number of potentially hot-pluggable cpus. The implementation | 56 | to determine the number of potentially hot-pluggable cpus. The implementation |
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 9b8291f4c211..25370662cc5d 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -191,15 +191,6 @@ Who: Kay Sievers <kay.sievers@suse.de> | |||
191 | 191 | ||
192 | --------------------------- | 192 | --------------------------- |
193 | 193 | ||
194 | What: i2c_adapter.list | ||
195 | When: July 2007 | ||
196 | Why: Superfluous, this list duplicates the one maintained by the driver | ||
197 | core. | ||
198 | Who: Jean Delvare <khali@linux-fr.org>, | ||
199 | David Brownell <dbrownell@users.sourceforge.net> | ||
200 | |||
201 | --------------------------- | ||
202 | |||
203 | What: ACPI procfs interface | 194 | What: ACPI procfs interface |
204 | When: July 2008 | 195 | When: July 2008 |
205 | Why: ACPI sysfs conversion should be finished by January 2008. | 196 | Why: ACPI sysfs conversion should be finished by January 2008. |
@@ -225,14 +216,6 @@ Who: Len Brown <len.brown@intel.com> | |||
225 | 216 | ||
226 | --------------------------- | 217 | --------------------------- |
227 | 218 | ||
228 | What: i2c-ixp2000, i2c-ixp4xx and scx200_i2c drivers | ||
229 | When: September 2007 | ||
230 | Why: Obsolete. The new i2c-gpio driver replaces all hardware-specific | ||
231 | I2C-over-GPIO drivers. | ||
232 | Who: Jean Delvare <khali@linux-fr.org> | ||
233 | |||
234 | --------------------------- | ||
235 | |||
236 | What: 'time' kernel boot parameter | 219 | What: 'time' kernel boot parameter |
237 | When: January 2008 | 220 | When: January 2008 |
238 | Why: replaced by 'printk.time=<value>' so that printk timestamps can be | 221 | Why: replaced by 'printk.time=<value>' so that printk timestamps can be |
@@ -266,13 +249,6 @@ Who: Tejun Heo <htejun@gmail.com> | |||
266 | 249 | ||
267 | --------------------------- | 250 | --------------------------- |
268 | 251 | ||
269 | What: Legacy RTC drivers (under drivers/i2c/chips) | ||
270 | When: November 2007 | ||
271 | Why: Obsolete. We have a RTC subsystem with better drivers. | ||
272 | Who: Jean Delvare <khali@linux-fr.org> | ||
273 | |||
274 | --------------------------- | ||
275 | |||
276 | What: iptables SAME target | 252 | What: iptables SAME target |
277 | When: 1.1. 2008 | 253 | When: 1.1. 2008 |
278 | Files: net/ipv4/netfilter/ipt_SAME.c, include/linux/netfilter_ipv4/ipt_SAME.h | 254 | Files: net/ipv4/netfilter/ipt_SAME.c, include/linux/netfilter_ipv4/ipt_SAME.h |
@@ -323,3 +299,10 @@ Why: This driver has been marked obsolete for many years. | |||
323 | Who: Stephen Hemminger <shemminger@linux-foundation.org> | 299 | Who: Stephen Hemminger <shemminger@linux-foundation.org> |
324 | 300 | ||
325 | --------------------------- | 301 | --------------------------- |
302 | |||
303 | What: i2c-i810, i2c-prosavage and i2c-savage4 | ||
304 | When: May 2008 | ||
305 | Why: These drivers are superseded by i810fb, intelfb and savagefb. | ||
306 | Who: Jean Delvare <khali@linux-fr.org> | ||
307 | |||
308 | --------------------------- | ||
diff --git a/Documentation/i2c/busses/i2c-i801 b/Documentation/i2c/busses/i2c-i801 index fde4420e3f75..3bd958360159 100644 --- a/Documentation/i2c/busses/i2c-i801 +++ b/Documentation/i2c/busses/i2c-i801 | |||
@@ -17,9 +17,8 @@ Supported adapters: | |||
17 | Datasheets: Publicly available at the Intel website | 17 | Datasheets: Publicly available at the Intel website |
18 | 18 | ||
19 | Authors: | 19 | Authors: |
20 | Frodo Looijaard <frodol@dds.nl>, | ||
21 | Philip Edelbrock <phil@netroedge.com>, | ||
22 | Mark Studebaker <mdsxyz123@yahoo.com> | 20 | Mark Studebaker <mdsxyz123@yahoo.com> |
21 | Jean Delvare <khali@linux-fr.org> | ||
23 | 22 | ||
24 | 23 | ||
25 | Module Parameters | 24 | Module Parameters |
@@ -62,7 +61,7 @@ Not supported. | |||
62 | I2C Block Read Support | 61 | I2C Block Read Support |
63 | ---------------------- | 62 | ---------------------- |
64 | 63 | ||
65 | Not supported at the moment. | 64 | I2C block read is supported on the 82801EB (ICH5) and later chips. |
66 | 65 | ||
67 | 66 | ||
68 | SMBus 2.0 Support | 67 | SMBus 2.0 Support |
diff --git a/Documentation/i2c/busses/i2c-viapro b/Documentation/i2c/busses/i2c-viapro index 06b4be3ef6d8..1405fb69984c 100644 --- a/Documentation/i2c/busses/i2c-viapro +++ b/Documentation/i2c/busses/i2c-viapro | |||
@@ -10,7 +10,7 @@ Supported adapters: | |||
10 | * VIA Technologies, Inc. VT8231, VT8233, VT8233A | 10 | * VIA Technologies, Inc. VT8231, VT8233, VT8233A |
11 | Datasheet: available on request from VIA | 11 | Datasheet: available on request from VIA |
12 | 12 | ||
13 | * VIA Technologies, Inc. VT8235, VT8237R, VT8237A, VT8251 | 13 | * VIA Technologies, Inc. VT8235, VT8237R, VT8237A, VT8237S, VT8251 |
14 | Datasheet: available on request and under NDA from VIA | 14 | Datasheet: available on request and under NDA from VIA |
15 | 15 | ||
16 | * VIA Technologies, Inc. CX700 | 16 | * VIA Technologies, Inc. CX700 |
@@ -46,6 +46,7 @@ Your lspci -n listing must show one of these : | |||
46 | device 1106:3177 (VT8235) | 46 | device 1106:3177 (VT8235) |
47 | device 1106:3227 (VT8237R) | 47 | device 1106:3227 (VT8237R) |
48 | device 1106:3337 (VT8237A) | 48 | device 1106:3337 (VT8237A) |
49 | device 1106:3372 (VT8237S) | ||
49 | device 1106:3287 (VT8251) | 50 | device 1106:3287 (VT8251) |
50 | device 1106:8324 (CX700) | 51 | device 1106:8324 (CX700) |
51 | 52 | ||
diff --git a/Documentation/i2c/chips/pcf8575 b/Documentation/i2c/chips/pcf8575 new file mode 100644 index 000000000000..25f5698a61cf --- /dev/null +++ b/Documentation/i2c/chips/pcf8575 | |||
@@ -0,0 +1,72 @@ | |||
1 | About the PCF8575 chip and the pcf8575 kernel driver | ||
2 | ==================================================== | ||
3 | |||
4 | The PCF8575 chip is produced by the following manufacturers: | ||
5 | |||
6 | * Philips NXP | ||
7 | http://www.nxp.com/#/pip/cb=[type=product,path=50807/41735/41850,final=PCF8575_3]|pip=[pip=PCF8575_3][0] | ||
8 | |||
9 | * Texas Instruments | ||
10 | http://focus.ti.com/docs/prod/folders/print/pcf8575.html | ||
11 | |||
12 | |||
13 | Some vendors sell small PCB's with the PCF8575 mounted on it. You can connect | ||
14 | such a board to a Linux host via e.g. an USB to I2C interface. Examples of | ||
15 | PCB boards with a PCF8575: | ||
16 | |||
17 | * SFE Breakout Board for PCF8575 I2C Expander by RobotShop | ||
18 | http://www.robotshop.ca/home/products/robot-parts/electronics/adapters-converters/sfe-pcf8575-i2c-expander-board.html | ||
19 | |||
20 | * Breakout Board for PCF8575 I2C Expander by Spark Fun Electronics | ||
21 | http://www.sparkfun.com/commerce/product_info.php?products_id=8130 | ||
22 | |||
23 | |||
24 | Description | ||
25 | ----------- | ||
26 | The PCF8575 chip is a 16-bit I/O expander for the I2C bus. Up to eight of | ||
27 | these chips can be connected to the same I2C bus. You can find this | ||
28 | chip on some custom designed hardware, but you won't find it on PC | ||
29 | motherboards. | ||
30 | |||
31 | The PCF8575 chip consists of a 16-bit quasi-bidirectional port and an I2C-bus | ||
32 | interface. Each of the sixteen I/O's can be independently used as an input or | ||
33 | an output. To set up an I/O pin as an input, you have to write a 1 to the | ||
34 | corresponding output. | ||
35 | |||
36 | For more information please see the datasheet. | ||
37 | |||
38 | |||
39 | Detection | ||
40 | --------- | ||
41 | |||
42 | There is no method known to detect whether a chip on a given I2C address is | ||
43 | a PCF8575 or whether it is any other I2C device. So there are two alternatives | ||
44 | to let the driver find the installed PCF8575 devices: | ||
45 | - Load this driver after any other I2C driver for I2C devices with addresses | ||
46 | in the range 0x20 .. 0x27. | ||
47 | - Pass the I2C bus and address of the installed PCF8575 devices explicitly to | ||
48 | the driver at load time via the probe=... or force=... parameters. | ||
49 | |||
50 | /sys interface | ||
51 | -------------- | ||
52 | |||
53 | For each address on which a PCF8575 chip was found or forced the following | ||
54 | files will be created under /sys: | ||
55 | * /sys/bus/i2c/devices/<bus>-<address>/read | ||
56 | * /sys/bus/i2c/devices/<bus>-<address>/write | ||
57 | where bus is the I2C bus number (0, 1, ...) and address is the four-digit | ||
58 | hexadecimal representation of the 7-bit I2C address of the PCF8575 | ||
59 | (0020 .. 0027). | ||
60 | |||
61 | The read file is read-only. Reading it will trigger an I2C read and will hence | ||
62 | report the current input state for the pins configured as inputs, and the | ||
63 | current output value for the pins configured as outputs. | ||
64 | |||
65 | The write file is read-write. Writing a value to it will configure all pins | ||
66 | as output for which the corresponding bit is zero. Reading the write file will | ||
67 | return the value last written, or -EAGAIN if no value has yet been written to | ||
68 | the write file. | ||
69 | |||
70 | On module initialization the configuration of the chip is not changed -- the | ||
71 | chip is left in the state it was already configured in through either power-up | ||
72 | or through previous I2C write actions. | ||
diff --git a/Documentation/i2c/i2c-stub b/Documentation/i2c/i2c-stub index 89e69ad3436c..0d8be1c20c16 100644 --- a/Documentation/i2c/i2c-stub +++ b/Documentation/i2c/i2c-stub | |||
@@ -25,6 +25,9 @@ The typical use-case is like this: | |||
25 | 3. load the target sensors chip driver module | 25 | 3. load the target sensors chip driver module |
26 | 4. observe its behavior in the kernel log | 26 | 4. observe its behavior in the kernel log |
27 | 27 | ||
28 | There's a script named i2c-stub-from-dump in the i2c-tools package which | ||
29 | can load register values automatically from a chip dump. | ||
30 | |||
28 | PARAMETERS: | 31 | PARAMETERS: |
29 | 32 | ||
30 | int chip_addr[10]: | 33 | int chip_addr[10]: |
@@ -32,9 +35,6 @@ int chip_addr[10]: | |||
32 | 35 | ||
33 | CAVEATS: | 36 | CAVEATS: |
34 | 37 | ||
35 | There are independent arrays for byte/data and word/data commands. Depending | ||
36 | on if/how a target driver mixes them, you'll need to be careful. | ||
37 | |||
38 | If your target driver polls some byte or word waiting for it to change, the | 38 | If your target driver polls some byte or word waiting for it to change, the |
39 | stub could lock it up. Use i2cset to unlock it. | 39 | stub could lock it up. Use i2cset to unlock it. |
40 | 40 | ||
diff --git a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients index 2c170032bf37..bfb0a5520817 100644 --- a/Documentation/i2c/writing-clients +++ b/Documentation/i2c/writing-clients | |||
@@ -267,9 +267,9 @@ insmod parameter of the form force_<kind>. | |||
267 | Fortunately, as a module writer, you just have to define the `normal_i2c' | 267 | Fortunately, as a module writer, you just have to define the `normal_i2c' |
268 | parameter. The complete declaration could look like this: | 268 | parameter. The complete declaration could look like this: |
269 | 269 | ||
270 | /* Scan 0x37, and 0x48 to 0x4f */ | 270 | /* Scan 0x4c to 0x4f */ |
271 | static unsigned short normal_i2c[] = { 0x37, 0x48, 0x49, 0x4a, 0x4b, 0x4c, | 271 | static const unsigned short normal_i2c[] = { 0x4c, 0x4d, 0x4e, 0x4f, |
272 | 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; | 272 | I2C_CLIENT_END }; |
273 | 273 | ||
274 | /* Magic definition of all other variables and things */ | 274 | /* Magic definition of all other variables and things */ |
275 | I2C_CLIENT_INSMOD; | 275 | I2C_CLIENT_INSMOD; |
diff --git a/Documentation/ide.txt b/Documentation/ide.txt index 1d50f23a5cab..94e2e3b9e77f 100644 --- a/Documentation/ide.txt +++ b/Documentation/ide.txt | |||
@@ -30,7 +30,7 @@ | |||
30 | *** | 30 | *** |
31 | *** The CMD640 is also used on some Vesa Local Bus (VLB) cards, and is *NOT* | 31 | *** The CMD640 is also used on some Vesa Local Bus (VLB) cards, and is *NOT* |
32 | *** automatically detected by Linux. For safe, reliable operation with such | 32 | *** automatically detected by Linux. For safe, reliable operation with such |
33 | *** interfaces, one *MUST* use the "ide0=cmd640_vlb" kernel option. | 33 | *** interfaces, one *MUST* use the "cmd640.probe_vlb" kernel option. |
34 | *** | 34 | *** |
35 | *** Use of the "serialize" option is no longer necessary. | 35 | *** Use of the "serialize" option is no longer necessary. |
36 | 36 | ||
@@ -244,10 +244,6 @@ Summary of ide driver parameters for kernel command line | |||
244 | 244 | ||
245 | "hdx=nodma" : disallow DMA | 245 | "hdx=nodma" : disallow DMA |
246 | 246 | ||
247 | "hdx=swapdata" : when the drive is a disk, byte swap all data | ||
248 | |||
249 | "hdx=bswap" : same as above.......... | ||
250 | |||
251 | "hdx=scsi" : the return of the ide-scsi flag, this is useful for | 247 | "hdx=scsi" : the return of the ide-scsi flag, this is useful for |
252 | allowing ide-floppy, ide-tape, and ide-cdrom|writers | 248 | allowing ide-floppy, ide-tape, and ide-cdrom|writers |
253 | to use ide-scsi emulation on a device specific option. | 249 | to use ide-scsi emulation on a device specific option. |
@@ -292,9 +288,6 @@ The following are valid ONLY on ide0, which usually corresponds | |||
292 | to the first ATA interface found on the particular host, and the defaults for | 288 | to the first ATA interface found on the particular host, and the defaults for |
293 | the base,ctl ports must not be altered. | 289 | the base,ctl ports must not be altered. |
294 | 290 | ||
295 | "ide0=cmd640_vlb" : *REQUIRED* for VLB cards with the CMD640 chip | ||
296 | (not for PCI -- automatically detected) | ||
297 | |||
298 | "ide=doubler" : probe/support IDE doublers on Amiga | 291 | "ide=doubler" : probe/support IDE doublers on Amiga |
299 | 292 | ||
300 | There may be more options than shown -- use the source, Luke! | 293 | There may be more options than shown -- use the source, Luke! |
@@ -310,6 +303,10 @@ i.e. to enable probing for ALI M14xx chipsets (ali14xx host driver) use: | |||
310 | * "probe" module parameter when ali14xx driver is compiled as module | 303 | * "probe" module parameter when ali14xx driver is compiled as module |
311 | ("modprobe ali14xx probe") | 304 | ("modprobe ali14xx probe") |
312 | 305 | ||
306 | Also for legacy CMD640 host driver (cmd640) you need to use "probe_vlb" | ||
307 | kernel paremeter to enable probing for VLB version of the chipset (PCI ones | ||
308 | are detected automatically). | ||
309 | |||
313 | ================================================================================ | 310 | ================================================================================ |
314 | 311 | ||
315 | IDE ATAPI streaming tape driver | 312 | IDE ATAPI streaming tape driver |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 65de5ba7b74c..880f882160e2 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -370,7 +370,8 @@ and is between 256 and 4096 characters. It is defined in the file | |||
370 | configured. Potentially dangerous and should only be | 370 | configured. Potentially dangerous and should only be |
371 | used if you are entirely sure of the consequences. | 371 | used if you are entirely sure of the consequences. |
372 | 372 | ||
373 | chandev= [HW,NET] Generic channel device initialisation | 373 | ccw_timeout_log [S390] |
374 | See Documentation/s390/CommonIO for details. | ||
374 | 375 | ||
375 | checkreqprot [SELINUX] Set initial checkreqprot flag value. | 376 | checkreqprot [SELINUX] Set initial checkreqprot flag value. |
376 | Format: { "0" | "1" } | 377 | Format: { "0" | "1" } |
@@ -382,6 +383,12 @@ and is between 256 and 4096 characters. It is defined in the file | |||
382 | Value can be changed at runtime via | 383 | Value can be changed at runtime via |
383 | /selinux/checkreqprot. | 384 | /selinux/checkreqprot. |
384 | 385 | ||
386 | cio_ignore= [S390] | ||
387 | See Documentation/s390/CommonIO for details. | ||
388 | |||
389 | cio_msg= [S390] | ||
390 | See Documentation/s390/CommonIO for details. | ||
391 | |||
385 | clock= [BUGS=X86-32, HW] gettimeofday clocksource override. | 392 | clock= [BUGS=X86-32, HW] gettimeofday clocksource override. |
386 | [Deprecated] | 393 | [Deprecated] |
387 | Forces specified clocksource (if available) to be used | 394 | Forces specified clocksource (if available) to be used |
diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt index cb12ae175aa2..53a63890aea4 100644 --- a/Documentation/kprobes.txt +++ b/Documentation/kprobes.txt | |||
@@ -141,6 +141,7 @@ architectures: | |||
141 | - ppc64 | 141 | - ppc64 |
142 | - ia64 (Does not support probes on instruction slot1.) | 142 | - ia64 (Does not support probes on instruction slot1.) |
143 | - sparc64 (Return probes not yet implemented.) | 143 | - sparc64 (Return probes not yet implemented.) |
144 | - arm | ||
144 | 145 | ||
145 | 3. Configuring Kprobes | 146 | 3. Configuring Kprobes |
146 | 147 | ||
diff --git a/Documentation/s390/CommonIO b/Documentation/s390/CommonIO index 86320aa3fb0b..8fbc0a852870 100644 --- a/Documentation/s390/CommonIO +++ b/Documentation/s390/CommonIO | |||
@@ -4,6 +4,11 @@ S/390 common I/O-Layer - command line parameters, procfs and debugfs entries | |||
4 | Command line parameters | 4 | Command line parameters |
5 | ----------------------- | 5 | ----------------------- |
6 | 6 | ||
7 | * ccw_timeout_log | ||
8 | |||
9 | Enable logging of debug information in case of ccw device timeouts. | ||
10 | |||
11 | |||
7 | * cio_msg = yes | no | 12 | * cio_msg = yes | no |
8 | 13 | ||
9 | Determines whether information on found devices and sensed device | 14 | Determines whether information on found devices and sensed device |
diff --git a/MAINTAINERS b/MAINTAINERS index 59db481c77de..29371226f682 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -758,22 +758,20 @@ S: Supported | |||
758 | 758 | ||
759 | BLACKFIN RTC DRIVER | 759 | BLACKFIN RTC DRIVER |
760 | P: Mike Frysinger | 760 | P: Mike Frysinger |
761 | M: michael.frysinger@analog.com | ||
762 | M: vapier.adi@gmail.com | 761 | M: vapier.adi@gmail.com |
763 | L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only) | 762 | L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only) |
764 | W: http://blackfin.uclinux.org | 763 | W: http://blackfin.uclinux.org |
765 | S: Supported | 764 | S: Supported |
766 | 765 | ||
767 | BLACKFIN SERIAL DRIVER | 766 | BLACKFIN SERIAL DRIVER |
768 | P: Aubrey Li | 767 | P: Sonic Zhang |
769 | M: aubrey.li@analog.com | 768 | M: sonic.zhang@analog.com |
770 | L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only) | 769 | L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only) |
771 | W: http://blackfin.uclinux.org | 770 | W: http://blackfin.uclinux.org |
772 | S: Supported | 771 | S: Supported |
773 | 772 | ||
774 | BLACKFIN WATCHDOG DRIVER | 773 | BLACKFIN WATCHDOG DRIVER |
775 | P: Mike Frysinger | 774 | P: Mike Frysinger |
776 | M: michael.frysinger@analog.com | ||
777 | M: vapier.adi@gmail.com | 775 | M: vapier.adi@gmail.com |
778 | L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only) | 776 | L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only) |
779 | W: http://blackfin.uclinux.org | 777 | W: http://blackfin.uclinux.org |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index a04f507e7f2c..e53b0ed9d00a 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -180,8 +180,8 @@ config ARCH_AT91 | |||
180 | bool "Atmel AT91" | 180 | bool "Atmel AT91" |
181 | select GENERIC_GPIO | 181 | select GENERIC_GPIO |
182 | help | 182 | help |
183 | This enables support for systems based on the Atmel AT91RM9200 | 183 | This enables support for systems based on the Atmel AT91RM9200, |
184 | and AT91SAM9xxx processors. | 184 | AT91SAM9 and AT91CAP9 processors. |
185 | 185 | ||
186 | config ARCH_CLPS7500 | 186 | config ARCH_CLPS7500 |
187 | bool "Cirrus CL-PS7500FE" | 187 | bool "Cirrus CL-PS7500FE" |
@@ -217,6 +217,7 @@ config ARCH_EP93XX | |||
217 | bool "EP93xx-based" | 217 | bool "EP93xx-based" |
218 | select ARM_AMBA | 218 | select ARM_AMBA |
219 | select ARM_VIC | 219 | select ARM_VIC |
220 | select GENERIC_GPIO | ||
220 | help | 221 | help |
221 | This enables support for the Cirrus EP93xx series of CPUs. | 222 | This enables support for the Cirrus EP93xx series of CPUs. |
222 | 223 | ||
@@ -366,6 +367,7 @@ config ARCH_SA1100 | |||
366 | select ARCH_DISCONTIGMEM_ENABLE | 367 | select ARCH_DISCONTIGMEM_ENABLE |
367 | select ARCH_MTD_XIP | 368 | select ARCH_MTD_XIP |
368 | select GENERIC_GPIO | 369 | select GENERIC_GPIO |
370 | select GENERIC_TIME | ||
369 | help | 371 | help |
370 | Support for StrongARM 11x0 based boards. | 372 | Support for StrongARM 11x0 based boards. |
371 | 373 | ||
@@ -409,6 +411,17 @@ config ARCH_OMAP | |||
409 | help | 411 | help |
410 | Support for TI's OMAP platform (OMAP1 and OMAP2). | 412 | Support for TI's OMAP platform (OMAP1 and OMAP2). |
411 | 413 | ||
414 | config ARCH_MSM7X00A | ||
415 | bool "Qualcomm MSM7X00A" | ||
416 | select GENERIC_TIME | ||
417 | select GENERIC_CLOCKEVENTS | ||
418 | help | ||
419 | Support for Qualcomm MSM7X00A based systems. This runs on the ARM11 | ||
420 | apps processor of the MSM7X00A and depends on a shared memory | ||
421 | interface to the ARM9 modem processor which runs the baseband stack | ||
422 | and controls some vital subsystems (clock and power control, etc). | ||
423 | <http://www.cdmatech.com/products/msm7200_chipset_solution.jsp> | ||
424 | |||
412 | endchoice | 425 | endchoice |
413 | 426 | ||
414 | source "arch/arm/mach-clps711x/Kconfig" | 427 | source "arch/arm/mach-clps711x/Kconfig" |
@@ -477,6 +490,8 @@ source "arch/arm/mach-davinci/Kconfig" | |||
477 | 490 | ||
478 | source "arch/arm/mach-ks8695/Kconfig" | 491 | source "arch/arm/mach-ks8695/Kconfig" |
479 | 492 | ||
493 | source "arch/arm/mach-msm/Kconfig" | ||
494 | |||
480 | # Definitions to make life easier | 495 | # Definitions to make life easier |
481 | config ARCH_ACORN | 496 | config ARCH_ACORN |
482 | bool | 497 | bool |
@@ -657,6 +672,7 @@ config HZ | |||
657 | default 128 if ARCH_L7200 | 672 | default 128 if ARCH_L7200 |
658 | default 200 if ARCH_EBSA110 || ARCH_S3C2410 | 673 | default 200 if ARCH_EBSA110 || ARCH_S3C2410 |
659 | default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER | 674 | default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER |
675 | default AT91_TIMER_HZ if ARCH_AT91 | ||
660 | default 100 | 676 | default 100 |
661 | 677 | ||
662 | config AEABI | 678 | config AEABI |
@@ -951,7 +967,7 @@ config FPE_FASTFPE | |||
951 | 967 | ||
952 | config VFP | 968 | config VFP |
953 | bool "VFP-format floating point maths" | 969 | bool "VFP-format floating point maths" |
954 | depends on CPU_V6 || CPU_ARM926T | 970 | depends on CPU_V6 || CPU_ARM926T || CPU_V7 |
955 | help | 971 | help |
956 | Say Y to include VFP support code in the kernel. This is needed | 972 | Say Y to include VFP support code in the kernel. This is needed |
957 | if your hardware includes a VFP unit. | 973 | if your hardware includes a VFP unit. |
@@ -961,6 +977,18 @@ config VFP | |||
961 | 977 | ||
962 | Say N if your target does not have VFP hardware. | 978 | Say N if your target does not have VFP hardware. |
963 | 979 | ||
980 | config VFPv3 | ||
981 | bool | ||
982 | depends on VFP | ||
983 | default y if CPU_V7 | ||
984 | |||
985 | config NEON | ||
986 | bool "Advanced SIMD (NEON) Extension support" | ||
987 | depends on VFPv3 && CPU_V7 | ||
988 | help | ||
989 | Say Y to include support code for NEON, the ARMv7 Advanced SIMD | ||
990 | Extension. | ||
991 | |||
964 | endmenu | 992 | endmenu |
965 | 993 | ||
966 | menu "Userspace binary formats" | 994 | menu "Userspace binary formats" |
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 18101f5f5f24..192ee01a9ba2 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug | |||
@@ -43,6 +43,12 @@ config DEBUG_ERRORS | |||
43 | you are concerned with the code size or don't want to see these | 43 | you are concerned with the code size or don't want to see these |
44 | messages. | 44 | messages. |
45 | 45 | ||
46 | config DEBUG_STACK_USAGE | ||
47 | bool "Enable stack utilization instrumentation" | ||
48 | depends on DEBUG_KERNEL | ||
49 | help | ||
50 | Enables the display of the minimum amount of free stack which each | ||
51 | task has ever had available in the sysrq-T output. | ||
46 | 52 | ||
47 | # These options are only for real kernel hackers who want to get their hands dirty. | 53 | # These options are only for real kernel hackers who want to get their hands dirty. |
48 | config DEBUG_LL | 54 | config DEBUG_LL |
diff --git a/arch/arm/Kconfig.instrumentation b/arch/arm/Kconfig.instrumentation index 63b8c6d5606a..453ad8e15d69 100644 --- a/arch/arm/Kconfig.instrumentation +++ b/arch/arm/Kconfig.instrumentation | |||
@@ -43,6 +43,16 @@ config OPROFILE_MPCORE | |||
43 | config OPROFILE_ARM11_CORE | 43 | config OPROFILE_ARM11_CORE |
44 | bool | 44 | bool |
45 | 45 | ||
46 | config KPROBES | ||
47 | bool "Kprobes" | ||
48 | depends on KALLSYMS && MODULES && !UML && !XIP_KERNEL | ||
49 | help | ||
50 | Kprobes allows you to trap at almost any kernel address and | ||
51 | execute a callback function. register_kprobe() establishes | ||
52 | a probepoint and specifies the callback. Kprobes is useful | ||
53 | for kernel debugging, non-intrusive instrumentation and testing. | ||
54 | If in doubt, say "N". | ||
55 | |||
46 | config MARKERS | 56 | config MARKERS |
47 | bool "Activate markers" | 57 | bool "Activate markers" |
48 | help | 58 | help |
diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 35e56c99ad1d..dd220d189843 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile | |||
@@ -139,6 +139,7 @@ endif | |||
139 | machine-$(CONFIG_ARCH_KS8695) := ks8695 | 139 | machine-$(CONFIG_ARCH_KS8695) := ks8695 |
140 | incdir-$(CONFIG_ARCH_MXC) := mxc | 140 | incdir-$(CONFIG_ARCH_MXC) := mxc |
141 | machine-$(CONFIG_ARCH_MX3) := mx3 | 141 | machine-$(CONFIG_ARCH_MX3) := mx3 |
142 | machine-$(CONFIG_ARCH_MSM7X00A) := msm | ||
142 | 143 | ||
143 | ifeq ($(CONFIG_ARCH_EBSA110),y) | 144 | ifeq ($(CONFIG_ARCH_EBSA110),y) |
144 | # This is what happens if you forget the IOCS16 line. | 145 | # This is what happens if you forget the IOCS16 line. |
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 5fde99f9d9f9..de9d9ee50958 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile | |||
@@ -44,10 +44,6 @@ ifeq ($(CONFIG_PXA_SHARPSL),y) | |||
44 | OBJS += head-sharpsl.o | 44 | OBJS += head-sharpsl.o |
45 | endif | 45 | endif |
46 | 46 | ||
47 | ifeq ($(CONFIG_ARCH_AT91RM9200),y) | ||
48 | OBJS += head-at91rm9200.o | ||
49 | endif | ||
50 | |||
51 | ifeq ($(CONFIG_CPU_BIG_ENDIAN),y) | 47 | ifeq ($(CONFIG_CPU_BIG_ENDIAN),y) |
52 | ifeq ($(CONFIG_CPU_CP15),y) | 48 | ifeq ($(CONFIG_CPU_CP15),y) |
53 | OBJS += big-endian.o | 49 | OBJS += big-endian.o |
diff --git a/arch/arm/boot/compressed/head-at91rm9200.S b/arch/arm/boot/compressed/head-at91rm9200.S deleted file mode 100644 index 11782ccd93a1..000000000000 --- a/arch/arm/boot/compressed/head-at91rm9200.S +++ /dev/null | |||
@@ -1,81 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/boot/compressed/head-at91rm9200.S | ||
3 | * | ||
4 | * Copyright (C) 2003 SAN People | ||
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 | */ | ||
12 | #include <asm/mach-types.h> | ||
13 | |||
14 | .section ".start", "ax" | ||
15 | |||
16 | @ Atmel AT91RM9200-DK : 262 | ||
17 | mov r3, #(MACH_TYPE_AT91RM9200DK & 0xff) | ||
18 | orr r3, r3, #(MACH_TYPE_AT91RM9200DK & 0xff00) | ||
19 | cmp r7, r3 | ||
20 | beq 99f | ||
21 | |||
22 | @ Cogent CSB337 : 399 | ||
23 | mov r3, #(MACH_TYPE_CSB337 & 0xff) | ||
24 | orr r3, r3, #(MACH_TYPE_CSB337 & 0xff00) | ||
25 | cmp r7, r3 | ||
26 | beq 99f | ||
27 | |||
28 | @ Cogent CSB637 : 648 | ||
29 | mov r3, #(MACH_TYPE_CSB637 & 0xff) | ||
30 | orr r3, r3, #(MACH_TYPE_CSB637 & 0xff00) | ||
31 | cmp r7, r3 | ||
32 | beq 99f | ||
33 | |||
34 | @ Atmel AT91RM9200-EK : 705 | ||
35 | mov r3, #(MACH_TYPE_AT91RM9200EK & 0xff) | ||
36 | orr r3, r3, #(MACH_TYPE_AT91RM9200EK & 0xff00) | ||
37 | cmp r7, r3 | ||
38 | beq 99f | ||
39 | |||
40 | @ Conitec Carmeva : 769 | ||
41 | mov r3, #(MACH_TYPE_CARMEVA & 0xff) | ||
42 | orr r3, r3, #(MACH_TYPE_CARMEVA & 0xff00) | ||
43 | cmp r7, r3 | ||
44 | beq 99f | ||
45 | |||
46 | @ KwikByte KB920x : 612 | ||
47 | mov r3, #(MACH_TYPE_KB9200 & 0xff) | ||
48 | orr r3, r3, #(MACH_TYPE_KB9200 & 0xff00) | ||
49 | cmp r7, r3 | ||
50 | beq 99f | ||
51 | |||
52 | @ Embest ATEB9200 : 923 | ||
53 | mov r3, #(MACH_TYPE_ATEB9200 & 0xff) | ||
54 | orr r3, r3, #(MACH_TYPE_ATEB9200 & 0xff00) | ||
55 | cmp r7, r3 | ||
56 | beq 99f | ||
57 | |||
58 | @ Sperry-Sun KAFA : 662 | ||
59 | mov r3, #(MACH_TYPE_KAFA & 0xff) | ||
60 | orr r3, r3, #(MACH_TYPE_KAFA & 0xff00) | ||
61 | cmp r7, r3 | ||
62 | beq 99f | ||
63 | |||
64 | @ picotux 200 : 963 | ||
65 | mov r3, #(MACH_TYPE_PICOTUX2XX & 0xff) | ||
66 | orr r3, r3, #(MACH_TYPE_PICOTUX2XX & 0xff00) | ||
67 | cmp r7, r3 | ||
68 | beq 99f | ||
69 | |||
70 | @ Ajeco 1ARM : 1075 | ||
71 | mov r3, #(MACH_TYPE_ONEARM & 0xff) | ||
72 | orr r3, r3, #(MACH_TYPE_ONEARM & 0xff00) | ||
73 | cmp r7, r3 | ||
74 | beq 99f | ||
75 | |||
76 | @ Unknown board, use the AT91RM9200DK board | ||
77 | @ mov r7, #MACH_TYPE_AT91RM9200 | ||
78 | mov r7, #(MACH_TYPE_AT91RM9200DK & 0xff) | ||
79 | orr r7, r7, #(MACH_TYPE_AT91RM9200DK & 0xff00) | ||
80 | |||
81 | 99: | ||
diff --git a/arch/arm/common/rtctime.c b/arch/arm/common/rtctime.c index bf1075e1f571..f53bca46e23c 100644 --- a/arch/arm/common/rtctime.c +++ b/arch/arm/common/rtctime.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/capability.h> | 20 | #include <linux/capability.h> |
21 | #include <linux/device.h> | 21 | #include <linux/device.h> |
22 | #include <linux/mutex.h> | 22 | #include <linux/mutex.h> |
23 | #include <linux/rtc.h> | ||
24 | 23 | ||
25 | #include <asm/rtc.h> | 24 | #include <asm/rtc.h> |
26 | #include <asm/semaphore.h> | 25 | #include <asm/semaphore.h> |
diff --git a/arch/arm/configs/at91cap9adk_defconfig b/arch/arm/configs/at91cap9adk_defconfig new file mode 100644 index 000000000000..e32e73648129 --- /dev/null +++ b/arch/arm/configs/at91cap9adk_defconfig | |||
@@ -0,0 +1,1143 @@ | |||
1 | # | ||
2 | # Automatically generated make config: don't edit | ||
3 | # Linux kernel version: 2.6.24-rc8 | ||
4 | # Wed Jan 23 22:55:57 2008 | ||
5 | # | ||
6 | CONFIG_ARM=y | ||
7 | CONFIG_SYS_SUPPORTS_APM_EMULATION=y | ||
8 | CONFIG_GENERIC_GPIO=y | ||
9 | # CONFIG_GENERIC_TIME is not set | ||
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_VECTORS_BASE=0xffff0000 | ||
26 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | ||
27 | |||
28 | # | ||
29 | # General setup | ||
30 | # | ||
31 | CONFIG_EXPERIMENTAL=y | ||
32 | CONFIG_BROKEN_ON_SMP=y | ||
33 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
34 | CONFIG_LOCALVERSION="" | ||
35 | # CONFIG_LOCALVERSION_AUTO is not set | ||
36 | # CONFIG_SWAP is not set | ||
37 | CONFIG_SYSVIPC=y | ||
38 | CONFIG_SYSVIPC_SYSCTL=y | ||
39 | # CONFIG_POSIX_MQUEUE is not set | ||
40 | # CONFIG_BSD_PROCESS_ACCT is not set | ||
41 | # CONFIG_TASKSTATS is not set | ||
42 | # CONFIG_USER_NS is not set | ||
43 | # CONFIG_PID_NS is not set | ||
44 | # CONFIG_AUDIT is not set | ||
45 | # CONFIG_IKCONFIG is not set | ||
46 | CONFIG_LOG_BUF_SHIFT=14 | ||
47 | # CONFIG_CGROUPS is not set | ||
48 | CONFIG_FAIR_GROUP_SCHED=y | ||
49 | CONFIG_FAIR_USER_SCHED=y | ||
50 | # CONFIG_FAIR_CGROUP_SCHED is not set | ||
51 | CONFIG_SYSFS_DEPRECATED=y | ||
52 | # CONFIG_RELAY is not set | ||
53 | CONFIG_BLK_DEV_INITRD=y | ||
54 | CONFIG_INITRAMFS_SOURCE="" | ||
55 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | ||
56 | CONFIG_SYSCTL=y | ||
57 | # CONFIG_EMBEDDED is not set | ||
58 | CONFIG_UID16=y | ||
59 | CONFIG_SYSCTL_SYSCALL=y | ||
60 | CONFIG_KALLSYMS=y | ||
61 | # CONFIG_KALLSYMS_ALL is not set | ||
62 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | ||
63 | CONFIG_HOTPLUG=y | ||
64 | CONFIG_PRINTK=y | ||
65 | CONFIG_BUG=y | ||
66 | CONFIG_ELF_CORE=y | ||
67 | CONFIG_BASE_FULL=y | ||
68 | CONFIG_FUTEX=y | ||
69 | CONFIG_ANON_INODES=y | ||
70 | CONFIG_EPOLL=y | ||
71 | CONFIG_SIGNALFD=y | ||
72 | CONFIG_EVENTFD=y | ||
73 | CONFIG_SHMEM=y | ||
74 | CONFIG_VM_EVENT_COUNTERS=y | ||
75 | CONFIG_SLAB=y | ||
76 | # CONFIG_SLUB is not set | ||
77 | # CONFIG_SLOB is not set | ||
78 | CONFIG_SLABINFO=y | ||
79 | CONFIG_RT_MUTEXES=y | ||
80 | # CONFIG_TINY_SHMEM is not set | ||
81 | CONFIG_BASE_SMALL=0 | ||
82 | CONFIG_MODULES=y | ||
83 | CONFIG_MODULE_UNLOAD=y | ||
84 | # CONFIG_MODULE_FORCE_UNLOAD is not set | ||
85 | # CONFIG_MODVERSIONS is not set | ||
86 | # CONFIG_MODULE_SRCVERSION_ALL is not set | ||
87 | CONFIG_KMOD=y | ||
88 | CONFIG_BLOCK=y | ||
89 | # CONFIG_LBD is not set | ||
90 | # CONFIG_BLK_DEV_IO_TRACE is not set | ||
91 | # CONFIG_LSF is not set | ||
92 | # CONFIG_BLK_DEV_BSG is not set | ||
93 | |||
94 | # | ||
95 | # IO Schedulers | ||
96 | # | ||
97 | CONFIG_IOSCHED_NOOP=y | ||
98 | CONFIG_IOSCHED_AS=y | ||
99 | # CONFIG_IOSCHED_DEADLINE is not set | ||
100 | # CONFIG_IOSCHED_CFQ is not set | ||
101 | CONFIG_DEFAULT_AS=y | ||
102 | # CONFIG_DEFAULT_DEADLINE is not set | ||
103 | # CONFIG_DEFAULT_CFQ is not set | ||
104 | # CONFIG_DEFAULT_NOOP is not set | ||
105 | CONFIG_DEFAULT_IOSCHED="anticipatory" | ||
106 | |||
107 | # | ||
108 | # System Type | ||
109 | # | ||
110 | # CONFIG_ARCH_AAEC2000 is not set | ||
111 | # CONFIG_ARCH_INTEGRATOR is not set | ||
112 | # CONFIG_ARCH_REALVIEW is not set | ||
113 | # CONFIG_ARCH_VERSATILE is not set | ||
114 | CONFIG_ARCH_AT91=y | ||
115 | # CONFIG_ARCH_CLPS7500 is not set | ||
116 | # CONFIG_ARCH_CLPS711X is not set | ||
117 | # CONFIG_ARCH_CO285 is not set | ||
118 | # CONFIG_ARCH_EBSA110 is not set | ||
119 | # CONFIG_ARCH_EP93XX is not set | ||
120 | # CONFIG_ARCH_FOOTBRIDGE is not set | ||
121 | # CONFIG_ARCH_NETX is not set | ||
122 | # CONFIG_ARCH_H720X is not set | ||
123 | # CONFIG_ARCH_IMX is not set | ||
124 | # CONFIG_ARCH_IOP13XX is not set | ||
125 | # CONFIG_ARCH_IOP32X is not set | ||
126 | # CONFIG_ARCH_IOP33X is not set | ||
127 | # CONFIG_ARCH_IXP23XX is not set | ||
128 | # CONFIG_ARCH_IXP2000 is not set | ||
129 | # CONFIG_ARCH_IXP4XX is not set | ||
130 | # CONFIG_ARCH_L7200 is not set | ||
131 | # CONFIG_ARCH_KS8695 is not set | ||
132 | # CONFIG_ARCH_NS9XXX is not set | ||
133 | # CONFIG_ARCH_MXC is not set | ||
134 | # CONFIG_ARCH_PNX4008 is not set | ||
135 | # CONFIG_ARCH_PXA is not set | ||
136 | # CONFIG_ARCH_RPC is not set | ||
137 | # CONFIG_ARCH_SA1100 is not set | ||
138 | # CONFIG_ARCH_S3C2410 is not set | ||
139 | # CONFIG_ARCH_SHARK is not set | ||
140 | # CONFIG_ARCH_LH7A40X is not set | ||
141 | # CONFIG_ARCH_DAVINCI is not set | ||
142 | # CONFIG_ARCH_OMAP is not set | ||
143 | |||
144 | # | ||
145 | # Boot options | ||
146 | # | ||
147 | |||
148 | # | ||
149 | # Power management | ||
150 | # | ||
151 | |||
152 | # | ||
153 | # Atmel AT91 System-on-Chip | ||
154 | # | ||
155 | # CONFIG_ARCH_AT91RM9200 is not set | ||
156 | # CONFIG_ARCH_AT91SAM9260 is not set | ||
157 | # CONFIG_ARCH_AT91SAM9261 is not set | ||
158 | # CONFIG_ARCH_AT91SAM9263 is not set | ||
159 | # CONFIG_ARCH_AT91SAM9RL is not set | ||
160 | CONFIG_ARCH_AT91CAP9=y | ||
161 | # CONFIG_ARCH_AT91X40 is not set | ||
162 | CONFIG_AT91_PMC_UNIT=y | ||
163 | |||
164 | # | ||
165 | # AT91CAP9 Board Type | ||
166 | # | ||
167 | CONFIG_MACH_AT91CAP9ADK=y | ||
168 | |||
169 | # | ||
170 | # AT91 Board Options | ||
171 | # | ||
172 | CONFIG_MTD_AT91_DATAFLASH_CARD=y | ||
173 | # CONFIG_MTD_NAND_AT91_BUSWIDTH_16 is not set | ||
174 | |||
175 | # | ||
176 | # AT91 Feature Selections | ||
177 | # | ||
178 | CONFIG_AT91_PROGRAMMABLE_CLOCKS=y | ||
179 | CONFIG_AT91_TIMER_HZ=100 | ||
180 | |||
181 | # | ||
182 | # Processor Type | ||
183 | # | ||
184 | CONFIG_CPU_32=y | ||
185 | CONFIG_CPU_ARM926T=y | ||
186 | CONFIG_CPU_32v5=y | ||
187 | CONFIG_CPU_ABRT_EV5TJ=y | ||
188 | CONFIG_CPU_CACHE_VIVT=y | ||
189 | CONFIG_CPU_COPY_V4WB=y | ||
190 | CONFIG_CPU_TLB_V4WBI=y | ||
191 | CONFIG_CPU_CP15=y | ||
192 | CONFIG_CPU_CP15_MMU=y | ||
193 | |||
194 | # | ||
195 | # Processor Features | ||
196 | # | ||
197 | # CONFIG_ARM_THUMB is not set | ||
198 | # CONFIG_CPU_ICACHE_DISABLE is not set | ||
199 | # CONFIG_CPU_DCACHE_DISABLE is not set | ||
200 | # CONFIG_CPU_DCACHE_WRITETHROUGH is not set | ||
201 | # CONFIG_CPU_CACHE_ROUND_ROBIN is not set | ||
202 | # CONFIG_OUTER_CACHE is not set | ||
203 | |||
204 | # | ||
205 | # Bus support | ||
206 | # | ||
207 | # CONFIG_PCI_SYSCALL is not set | ||
208 | # CONFIG_ARCH_SUPPORTS_MSI is not set | ||
209 | # CONFIG_PCCARD is not set | ||
210 | |||
211 | # | ||
212 | # Kernel Features | ||
213 | # | ||
214 | # CONFIG_TICK_ONESHOT is not set | ||
215 | # CONFIG_PREEMPT is not set | ||
216 | # CONFIG_NO_IDLE_HZ is not set | ||
217 | CONFIG_HZ=100 | ||
218 | CONFIG_AEABI=y | ||
219 | CONFIG_OABI_COMPAT=y | ||
220 | # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set | ||
221 | CONFIG_SELECT_MEMORY_MODEL=y | ||
222 | CONFIG_FLATMEM_MANUAL=y | ||
223 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
224 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
225 | CONFIG_FLATMEM=y | ||
226 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
227 | # CONFIG_SPARSEMEM_STATIC is not set | ||
228 | # CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set | ||
229 | CONFIG_SPLIT_PTLOCK_CPUS=4096 | ||
230 | # CONFIG_RESOURCES_64BIT is not set | ||
231 | CONFIG_ZONE_DMA_FLAG=1 | ||
232 | CONFIG_BOUNCE=y | ||
233 | CONFIG_VIRT_TO_BUS=y | ||
234 | CONFIG_LEDS=y | ||
235 | CONFIG_LEDS_TIMER=y | ||
236 | CONFIG_LEDS_CPU=y | ||
237 | CONFIG_ALIGNMENT_TRAP=y | ||
238 | |||
239 | # | ||
240 | # Boot options | ||
241 | # | ||
242 | CONFIG_ZBOOT_ROM_TEXT=0x0 | ||
243 | CONFIG_ZBOOT_ROM_BSS=0x0 | ||
244 | CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/ram0 rw" | ||
245 | # CONFIG_XIP_KERNEL is not set | ||
246 | # CONFIG_KEXEC is not set | ||
247 | |||
248 | # | ||
249 | # Floating point emulation | ||
250 | # | ||
251 | |||
252 | # | ||
253 | # At least one emulation must be selected | ||
254 | # | ||
255 | CONFIG_FPE_NWFPE=y | ||
256 | # CONFIG_FPE_NWFPE_XP is not set | ||
257 | # CONFIG_FPE_FASTFPE is not set | ||
258 | # CONFIG_VFP is not set | ||
259 | |||
260 | # | ||
261 | # Userspace binary formats | ||
262 | # | ||
263 | CONFIG_BINFMT_ELF=y | ||
264 | # CONFIG_BINFMT_AOUT is not set | ||
265 | # CONFIG_BINFMT_MISC is not set | ||
266 | |||
267 | # | ||
268 | # Power management options | ||
269 | # | ||
270 | # CONFIG_PM is not set | ||
271 | CONFIG_SUSPEND_UP_POSSIBLE=y | ||
272 | |||
273 | # | ||
274 | # Networking | ||
275 | # | ||
276 | CONFIG_NET=y | ||
277 | |||
278 | # | ||
279 | # Networking options | ||
280 | # | ||
281 | CONFIG_PACKET=y | ||
282 | # CONFIG_PACKET_MMAP is not set | ||
283 | CONFIG_UNIX=y | ||
284 | # CONFIG_NET_KEY is not set | ||
285 | CONFIG_INET=y | ||
286 | # CONFIG_IP_MULTICAST is not set | ||
287 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
288 | CONFIG_IP_FIB_HASH=y | ||
289 | CONFIG_IP_PNP=y | ||
290 | # CONFIG_IP_PNP_DHCP is not set | ||
291 | CONFIG_IP_PNP_BOOTP=y | ||
292 | CONFIG_IP_PNP_RARP=y | ||
293 | # CONFIG_NET_IPIP is not set | ||
294 | # CONFIG_NET_IPGRE is not set | ||
295 | # CONFIG_ARPD is not set | ||
296 | # CONFIG_SYN_COOKIES is not set | ||
297 | # CONFIG_INET_AH is not set | ||
298 | # CONFIG_INET_ESP is not set | ||
299 | # CONFIG_INET_IPCOMP is not set | ||
300 | # CONFIG_INET_XFRM_TUNNEL is not set | ||
301 | # CONFIG_INET_TUNNEL is not set | ||
302 | # CONFIG_INET_XFRM_MODE_TRANSPORT is not set | ||
303 | # CONFIG_INET_XFRM_MODE_TUNNEL is not set | ||
304 | # CONFIG_INET_XFRM_MODE_BEET is not set | ||
305 | # CONFIG_INET_LRO is not set | ||
306 | # CONFIG_INET_DIAG is not set | ||
307 | # CONFIG_TCP_CONG_ADVANCED is not set | ||
308 | CONFIG_TCP_CONG_CUBIC=y | ||
309 | CONFIG_DEFAULT_TCP_CONG="cubic" | ||
310 | # CONFIG_TCP_MD5SIG is not set | ||
311 | # CONFIG_IPV6 is not set | ||
312 | # CONFIG_INET6_XFRM_TUNNEL is not set | ||
313 | # CONFIG_INET6_TUNNEL is not set | ||
314 | # CONFIG_NETWORK_SECMARK is not set | ||
315 | # CONFIG_NETFILTER is not set | ||
316 | # CONFIG_IP_DCCP is not set | ||
317 | # CONFIG_IP_SCTP is not set | ||
318 | # CONFIG_TIPC is not set | ||
319 | # CONFIG_ATM is not set | ||
320 | # CONFIG_BRIDGE is not set | ||
321 | # CONFIG_VLAN_8021Q is not set | ||
322 | # CONFIG_DECNET is not set | ||
323 | # CONFIG_LLC2 is not set | ||
324 | # CONFIG_IPX is not set | ||
325 | # CONFIG_ATALK is not set | ||
326 | # CONFIG_X25 is not set | ||
327 | # CONFIG_LAPB is not set | ||
328 | # CONFIG_ECONET is not set | ||
329 | # CONFIG_WAN_ROUTER is not set | ||
330 | # CONFIG_NET_SCHED is not set | ||
331 | |||
332 | # | ||
333 | # Network testing | ||
334 | # | ||
335 | # CONFIG_NET_PKTGEN is not set | ||
336 | # CONFIG_HAMRADIO is not set | ||
337 | # CONFIG_IRDA is not set | ||
338 | # CONFIG_BT is not set | ||
339 | # CONFIG_AF_RXRPC is not set | ||
340 | |||
341 | # | ||
342 | # Wireless | ||
343 | # | ||
344 | # CONFIG_CFG80211 is not set | ||
345 | # CONFIG_WIRELESS_EXT is not set | ||
346 | # CONFIG_MAC80211 is not set | ||
347 | # CONFIG_IEEE80211 is not set | ||
348 | # CONFIG_RFKILL is not set | ||
349 | # CONFIG_NET_9P is not set | ||
350 | |||
351 | # | ||
352 | # Device Drivers | ||
353 | # | ||
354 | |||
355 | # | ||
356 | # Generic Driver Options | ||
357 | # | ||
358 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
359 | CONFIG_STANDALONE=y | ||
360 | CONFIG_PREVENT_FIRMWARE_BUILD=y | ||
361 | # CONFIG_FW_LOADER is not set | ||
362 | # CONFIG_DEBUG_DRIVER is not set | ||
363 | # CONFIG_DEBUG_DEVRES is not set | ||
364 | # CONFIG_SYS_HYPERVISOR is not set | ||
365 | # CONFIG_CONNECTOR is not set | ||
366 | CONFIG_MTD=y | ||
367 | # CONFIG_MTD_DEBUG is not set | ||
368 | # CONFIG_MTD_CONCAT is not set | ||
369 | CONFIG_MTD_PARTITIONS=y | ||
370 | # CONFIG_MTD_REDBOOT_PARTS is not set | ||
371 | CONFIG_MTD_CMDLINE_PARTS=y | ||
372 | # CONFIG_MTD_AFS_PARTS is not set | ||
373 | |||
374 | # | ||
375 | # User Modules And Translation Layers | ||
376 | # | ||
377 | CONFIG_MTD_CHAR=y | ||
378 | CONFIG_MTD_BLKDEVS=y | ||
379 | CONFIG_MTD_BLOCK=y | ||
380 | # CONFIG_FTL is not set | ||
381 | # CONFIG_NFTL is not set | ||
382 | # CONFIG_INFTL is not set | ||
383 | # CONFIG_RFD_FTL is not set | ||
384 | # CONFIG_SSFDC is not set | ||
385 | # CONFIG_MTD_OOPS is not set | ||
386 | |||
387 | # | ||
388 | # RAM/ROM/Flash chip drivers | ||
389 | # | ||
390 | CONFIG_MTD_CFI=y | ||
391 | CONFIG_MTD_JEDECPROBE=y | ||
392 | CONFIG_MTD_GEN_PROBE=y | ||
393 | # CONFIG_MTD_CFI_ADV_OPTIONS is not set | ||
394 | CONFIG_MTD_MAP_BANK_WIDTH_1=y | ||
395 | CONFIG_MTD_MAP_BANK_WIDTH_2=y | ||
396 | CONFIG_MTD_MAP_BANK_WIDTH_4=y | ||
397 | # CONFIG_MTD_MAP_BANK_WIDTH_8 is not set | ||
398 | # CONFIG_MTD_MAP_BANK_WIDTH_16 is not set | ||
399 | # CONFIG_MTD_MAP_BANK_WIDTH_32 is not set | ||
400 | CONFIG_MTD_CFI_I1=y | ||
401 | CONFIG_MTD_CFI_I2=y | ||
402 | # CONFIG_MTD_CFI_I4 is not set | ||
403 | # CONFIG_MTD_CFI_I8 is not set | ||
404 | # CONFIG_MTD_CFI_INTELEXT is not set | ||
405 | CONFIG_MTD_CFI_AMDSTD=y | ||
406 | # CONFIG_MTD_CFI_STAA is not set | ||
407 | CONFIG_MTD_CFI_UTIL=y | ||
408 | # CONFIG_MTD_RAM is not set | ||
409 | # CONFIG_MTD_ROM is not set | ||
410 | # CONFIG_MTD_ABSENT is not set | ||
411 | |||
412 | # | ||
413 | # Mapping drivers for chip access | ||
414 | # | ||
415 | # CONFIG_MTD_COMPLEX_MAPPINGS is not set | ||
416 | CONFIG_MTD_PHYSMAP=y | ||
417 | CONFIG_MTD_PHYSMAP_START=0x0 | ||
418 | CONFIG_MTD_PHYSMAP_LEN=0x0 | ||
419 | CONFIG_MTD_PHYSMAP_BANKWIDTH=0 | ||
420 | # CONFIG_MTD_ARM_INTEGRATOR is not set | ||
421 | # CONFIG_MTD_IMPA7 is not set | ||
422 | # CONFIG_MTD_PLATRAM is not set | ||
423 | |||
424 | # | ||
425 | # Self-contained MTD device drivers | ||
426 | # | ||
427 | CONFIG_MTD_DATAFLASH=y | ||
428 | # CONFIG_MTD_M25P80 is not set | ||
429 | # CONFIG_MTD_SLRAM is not set | ||
430 | # CONFIG_MTD_PHRAM is not set | ||
431 | # CONFIG_MTD_MTDRAM is not set | ||
432 | # CONFIG_MTD_BLOCK2MTD is not set | ||
433 | |||
434 | # | ||
435 | # Disk-On-Chip Device Drivers | ||
436 | # | ||
437 | # CONFIG_MTD_DOC2000 is not set | ||
438 | # CONFIG_MTD_DOC2001 is not set | ||
439 | # CONFIG_MTD_DOC2001PLUS is not set | ||
440 | CONFIG_MTD_NAND=y | ||
441 | # CONFIG_MTD_NAND_VERIFY_WRITE is not set | ||
442 | # CONFIG_MTD_NAND_ECC_SMC is not set | ||
443 | # CONFIG_MTD_NAND_MUSEUM_IDS is not set | ||
444 | CONFIG_MTD_NAND_IDS=y | ||
445 | # CONFIG_MTD_NAND_DISKONCHIP is not set | ||
446 | CONFIG_MTD_NAND_AT91=y | ||
447 | # CONFIG_MTD_NAND_NANDSIM is not set | ||
448 | # CONFIG_MTD_NAND_PLATFORM is not set | ||
449 | # CONFIG_MTD_ALAUDA is not set | ||
450 | # CONFIG_MTD_ONENAND is not set | ||
451 | |||
452 | # | ||
453 | # UBI - Unsorted block images | ||
454 | # | ||
455 | # CONFIG_MTD_UBI is not set | ||
456 | # CONFIG_PARPORT is not set | ||
457 | CONFIG_BLK_DEV=y | ||
458 | # CONFIG_BLK_DEV_COW_COMMON is not set | ||
459 | CONFIG_BLK_DEV_LOOP=y | ||
460 | # CONFIG_BLK_DEV_CRYPTOLOOP is not set | ||
461 | # CONFIG_BLK_DEV_NBD is not set | ||
462 | # CONFIG_BLK_DEV_UB is not set | ||
463 | CONFIG_BLK_DEV_RAM=y | ||
464 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
465 | CONFIG_BLK_DEV_RAM_SIZE=8192 | ||
466 | CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 | ||
467 | # CONFIG_CDROM_PKTCDVD is not set | ||
468 | # CONFIG_ATA_OVER_ETH is not set | ||
469 | CONFIG_MISC_DEVICES=y | ||
470 | # CONFIG_EEPROM_93CX6 is not set | ||
471 | CONFIG_ATMEL_SSC=y | ||
472 | |||
473 | # | ||
474 | # SCSI device support | ||
475 | # | ||
476 | # CONFIG_RAID_ATTRS is not set | ||
477 | CONFIG_SCSI=y | ||
478 | CONFIG_SCSI_DMA=y | ||
479 | # CONFIG_SCSI_TGT is not set | ||
480 | # CONFIG_SCSI_NETLINK is not set | ||
481 | CONFIG_SCSI_PROC_FS=y | ||
482 | |||
483 | # | ||
484 | # SCSI support type (disk, tape, CD-ROM) | ||
485 | # | ||
486 | CONFIG_BLK_DEV_SD=y | ||
487 | # CONFIG_CHR_DEV_ST is not set | ||
488 | # CONFIG_CHR_DEV_OSST is not set | ||
489 | # CONFIG_BLK_DEV_SR is not set | ||
490 | # CONFIG_CHR_DEV_SG is not set | ||
491 | # CONFIG_CHR_DEV_SCH is not set | ||
492 | |||
493 | # | ||
494 | # Some SCSI devices (e.g. CD jukebox) support multiple LUNs | ||
495 | # | ||
496 | CONFIG_SCSI_MULTI_LUN=y | ||
497 | # CONFIG_SCSI_CONSTANTS is not set | ||
498 | # CONFIG_SCSI_LOGGING is not set | ||
499 | # CONFIG_SCSI_SCAN_ASYNC is not set | ||
500 | CONFIG_SCSI_WAIT_SCAN=m | ||
501 | |||
502 | # | ||
503 | # SCSI Transports | ||
504 | # | ||
505 | # CONFIG_SCSI_SPI_ATTRS is not set | ||
506 | # CONFIG_SCSI_FC_ATTRS is not set | ||
507 | # CONFIG_SCSI_ISCSI_ATTRS is not set | ||
508 | # CONFIG_SCSI_SAS_LIBSAS is not set | ||
509 | # CONFIG_SCSI_SRP_ATTRS is not set | ||
510 | CONFIG_SCSI_LOWLEVEL=y | ||
511 | # CONFIG_ISCSI_TCP is not set | ||
512 | # CONFIG_SCSI_DEBUG is not set | ||
513 | # CONFIG_ATA is not set | ||
514 | # CONFIG_MD is not set | ||
515 | CONFIG_NETDEVICES=y | ||
516 | # CONFIG_NETDEVICES_MULTIQUEUE is not set | ||
517 | # CONFIG_DUMMY is not set | ||
518 | # CONFIG_BONDING is not set | ||
519 | # CONFIG_MACVLAN is not set | ||
520 | # CONFIG_EQUALIZER is not set | ||
521 | # CONFIG_TUN is not set | ||
522 | # CONFIG_VETH is not set | ||
523 | CONFIG_PHYLIB=y | ||
524 | |||
525 | # | ||
526 | # MII PHY device drivers | ||
527 | # | ||
528 | # CONFIG_MARVELL_PHY is not set | ||
529 | # CONFIG_DAVICOM_PHY is not set | ||
530 | # CONFIG_QSEMI_PHY is not set | ||
531 | # CONFIG_LXT_PHY is not set | ||
532 | # CONFIG_CICADA_PHY is not set | ||
533 | # CONFIG_VITESSE_PHY is not set | ||
534 | # CONFIG_SMSC_PHY is not set | ||
535 | # CONFIG_BROADCOM_PHY is not set | ||
536 | # CONFIG_ICPLUS_PHY is not set | ||
537 | # CONFIG_FIXED_PHY is not set | ||
538 | # CONFIG_MDIO_BITBANG is not set | ||
539 | CONFIG_NET_ETHERNET=y | ||
540 | CONFIG_MII=y | ||
541 | CONFIG_MACB=y | ||
542 | # CONFIG_AX88796 is not set | ||
543 | # CONFIG_SMC91X is not set | ||
544 | # CONFIG_DM9000 is not set | ||
545 | # CONFIG_IBM_NEW_EMAC_ZMII is not set | ||
546 | # CONFIG_IBM_NEW_EMAC_RGMII is not set | ||
547 | # CONFIG_IBM_NEW_EMAC_TAH is not set | ||
548 | # CONFIG_IBM_NEW_EMAC_EMAC4 is not set | ||
549 | # CONFIG_B44 is not set | ||
550 | # CONFIG_NETDEV_1000 is not set | ||
551 | # CONFIG_NETDEV_10000 is not set | ||
552 | |||
553 | # | ||
554 | # Wireless LAN | ||
555 | # | ||
556 | # CONFIG_WLAN_PRE80211 is not set | ||
557 | # CONFIG_WLAN_80211 is not set | ||
558 | |||
559 | # | ||
560 | # USB Network Adapters | ||
561 | # | ||
562 | # CONFIG_USB_CATC is not set | ||
563 | # CONFIG_USB_KAWETH is not set | ||
564 | # CONFIG_USB_PEGASUS is not set | ||
565 | # CONFIG_USB_RTL8150 is not set | ||
566 | # CONFIG_USB_USBNET is not set | ||
567 | # CONFIG_WAN is not set | ||
568 | # CONFIG_PPP is not set | ||
569 | # CONFIG_SLIP is not set | ||
570 | # CONFIG_SHAPER is not set | ||
571 | # CONFIG_NETCONSOLE is not set | ||
572 | # CONFIG_NETPOLL is not set | ||
573 | # CONFIG_NET_POLL_CONTROLLER is not set | ||
574 | # CONFIG_ISDN is not set | ||
575 | |||
576 | # | ||
577 | # Input device support | ||
578 | # | ||
579 | CONFIG_INPUT=y | ||
580 | # CONFIG_INPUT_FF_MEMLESS is not set | ||
581 | # CONFIG_INPUT_POLLDEV is not set | ||
582 | |||
583 | # | ||
584 | # Userland interfaces | ||
585 | # | ||
586 | CONFIG_INPUT_MOUSEDEV=y | ||
587 | # CONFIG_INPUT_MOUSEDEV_PSAUX is not set | ||
588 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 | ||
589 | CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | ||
590 | # CONFIG_INPUT_JOYDEV is not set | ||
591 | CONFIG_INPUT_EVDEV=y | ||
592 | # CONFIG_INPUT_EVBUG is not set | ||
593 | |||
594 | # | ||
595 | # Input Device Drivers | ||
596 | # | ||
597 | # CONFIG_INPUT_KEYBOARD is not set | ||
598 | # CONFIG_INPUT_MOUSE is not set | ||
599 | # CONFIG_INPUT_JOYSTICK is not set | ||
600 | # CONFIG_INPUT_TABLET is not set | ||
601 | CONFIG_INPUT_TOUCHSCREEN=y | ||
602 | CONFIG_TOUCHSCREEN_ADS7846=y | ||
603 | # CONFIG_TOUCHSCREEN_FUJITSU is not set | ||
604 | # CONFIG_TOUCHSCREEN_GUNZE is not set | ||
605 | # CONFIG_TOUCHSCREEN_ELO is not set | ||
606 | # CONFIG_TOUCHSCREEN_MTOUCH is not set | ||
607 | # CONFIG_TOUCHSCREEN_MK712 is not set | ||
608 | # CONFIG_TOUCHSCREEN_PENMOUNT is not set | ||
609 | # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set | ||
610 | # CONFIG_TOUCHSCREEN_TOUCHWIN is not set | ||
611 | # CONFIG_TOUCHSCREEN_UCB1400 is not set | ||
612 | # CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set | ||
613 | # CONFIG_INPUT_MISC is not set | ||
614 | |||
615 | # | ||
616 | # Hardware I/O ports | ||
617 | # | ||
618 | # CONFIG_SERIO is not set | ||
619 | # CONFIG_GAMEPORT is not set | ||
620 | |||
621 | # | ||
622 | # Character devices | ||
623 | # | ||
624 | CONFIG_VT=y | ||
625 | CONFIG_VT_CONSOLE=y | ||
626 | CONFIG_HW_CONSOLE=y | ||
627 | # CONFIG_VT_HW_CONSOLE_BINDING is not set | ||
628 | # CONFIG_SERIAL_NONSTANDARD is not set | ||
629 | |||
630 | # | ||
631 | # Serial drivers | ||
632 | # | ||
633 | # CONFIG_SERIAL_8250 is not set | ||
634 | |||
635 | # | ||
636 | # Non-8250 serial port support | ||
637 | # | ||
638 | CONFIG_SERIAL_ATMEL=y | ||
639 | CONFIG_SERIAL_ATMEL_CONSOLE=y | ||
640 | # CONFIG_SERIAL_ATMEL_TTYAT is not set | ||
641 | CONFIG_SERIAL_CORE=y | ||
642 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
643 | CONFIG_UNIX98_PTYS=y | ||
644 | CONFIG_LEGACY_PTYS=y | ||
645 | CONFIG_LEGACY_PTY_COUNT=256 | ||
646 | # CONFIG_IPMI_HANDLER is not set | ||
647 | CONFIG_HW_RANDOM=y | ||
648 | # CONFIG_NVRAM is not set | ||
649 | # CONFIG_R3964 is not set | ||
650 | # CONFIG_RAW_DRIVER is not set | ||
651 | # CONFIG_TCG_TPM is not set | ||
652 | CONFIG_I2C=y | ||
653 | CONFIG_I2C_BOARDINFO=y | ||
654 | CONFIG_I2C_CHARDEV=y | ||
655 | |||
656 | # | ||
657 | # I2C Algorithms | ||
658 | # | ||
659 | # CONFIG_I2C_ALGOBIT is not set | ||
660 | # CONFIG_I2C_ALGOPCF is not set | ||
661 | # CONFIG_I2C_ALGOPCA is not set | ||
662 | |||
663 | # | ||
664 | # I2C Hardware Bus support | ||
665 | # | ||
666 | # CONFIG_I2C_GPIO is not set | ||
667 | # CONFIG_I2C_OCORES is not set | ||
668 | # CONFIG_I2C_PARPORT_LIGHT is not set | ||
669 | # CONFIG_I2C_SIMTEC is not set | ||
670 | # CONFIG_I2C_TAOS_EVM is not set | ||
671 | # CONFIG_I2C_STUB is not set | ||
672 | # CONFIG_I2C_TINY_USB is not set | ||
673 | |||
674 | # | ||
675 | # Miscellaneous I2C Chip support | ||
676 | # | ||
677 | # CONFIG_SENSORS_DS1337 is not set | ||
678 | # CONFIG_SENSORS_DS1374 is not set | ||
679 | # CONFIG_DS1682 is not set | ||
680 | # CONFIG_SENSORS_EEPROM is not set | ||
681 | # CONFIG_SENSORS_PCF8574 is not set | ||
682 | # CONFIG_SENSORS_PCA9539 is not set | ||
683 | # CONFIG_SENSORS_PCF8591 is not set | ||
684 | # CONFIG_SENSORS_MAX6875 is not set | ||
685 | # CONFIG_SENSORS_TSL2550 is not set | ||
686 | # CONFIG_I2C_DEBUG_CORE is not set | ||
687 | # CONFIG_I2C_DEBUG_ALGO is not set | ||
688 | # CONFIG_I2C_DEBUG_BUS is not set | ||
689 | # CONFIG_I2C_DEBUG_CHIP is not set | ||
690 | |||
691 | # | ||
692 | # SPI support | ||
693 | # | ||
694 | CONFIG_SPI=y | ||
695 | # CONFIG_SPI_DEBUG is not set | ||
696 | CONFIG_SPI_MASTER=y | ||
697 | |||
698 | # | ||
699 | # SPI Master Controller Drivers | ||
700 | # | ||
701 | CONFIG_SPI_ATMEL=y | ||
702 | # CONFIG_SPI_BITBANG is not set | ||
703 | |||
704 | # | ||
705 | # SPI Protocol Masters | ||
706 | # | ||
707 | # CONFIG_SPI_AT25 is not set | ||
708 | # CONFIG_SPI_SPIDEV is not set | ||
709 | # CONFIG_SPI_TLE62X0 is not set | ||
710 | # CONFIG_W1 is not set | ||
711 | # CONFIG_POWER_SUPPLY is not set | ||
712 | # CONFIG_HWMON is not set | ||
713 | CONFIG_WATCHDOG=y | ||
714 | CONFIG_WATCHDOG_NOWAYOUT=y | ||
715 | |||
716 | # | ||
717 | # Watchdog Device Drivers | ||
718 | # | ||
719 | # CONFIG_SOFT_WATCHDOG is not set | ||
720 | |||
721 | # | ||
722 | # USB-based Watchdog Cards | ||
723 | # | ||
724 | # CONFIG_USBPCWATCHDOG is not set | ||
725 | |||
726 | # | ||
727 | # Sonics Silicon Backplane | ||
728 | # | ||
729 | CONFIG_SSB_POSSIBLE=y | ||
730 | # CONFIG_SSB is not set | ||
731 | |||
732 | # | ||
733 | # Multifunction device drivers | ||
734 | # | ||
735 | # CONFIG_MFD_SM501 is not set | ||
736 | |||
737 | # | ||
738 | # Multimedia devices | ||
739 | # | ||
740 | # CONFIG_VIDEO_DEV is not set | ||
741 | # CONFIG_DVB_CORE is not set | ||
742 | # CONFIG_DAB is not set | ||
743 | |||
744 | # | ||
745 | # Graphics support | ||
746 | # | ||
747 | # CONFIG_VGASTATE is not set | ||
748 | # CONFIG_VIDEO_OUTPUT_CONTROL is not set | ||
749 | CONFIG_FB=y | ||
750 | # CONFIG_FIRMWARE_EDID is not set | ||
751 | # CONFIG_FB_DDC is not set | ||
752 | CONFIG_FB_CFB_FILLRECT=y | ||
753 | CONFIG_FB_CFB_COPYAREA=y | ||
754 | CONFIG_FB_CFB_IMAGEBLIT=y | ||
755 | # CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set | ||
756 | # CONFIG_FB_SYS_FILLRECT is not set | ||
757 | # CONFIG_FB_SYS_COPYAREA is not set | ||
758 | # CONFIG_FB_SYS_IMAGEBLIT is not set | ||
759 | # CONFIG_FB_SYS_FOPS is not set | ||
760 | CONFIG_FB_DEFERRED_IO=y | ||
761 | # CONFIG_FB_SVGALIB is not set | ||
762 | # CONFIG_FB_MACMODES is not set | ||
763 | # CONFIG_FB_BACKLIGHT is not set | ||
764 | # CONFIG_FB_MODE_HELPERS is not set | ||
765 | # CONFIG_FB_TILEBLITTING is not set | ||
766 | |||
767 | # | ||
768 | # Frame buffer hardware drivers | ||
769 | # | ||
770 | # CONFIG_FB_S1D13XXX is not set | ||
771 | CONFIG_FB_ATMEL=y | ||
772 | # CONFIG_FB_VIRTUAL is not set | ||
773 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set | ||
774 | |||
775 | # | ||
776 | # Display device support | ||
777 | # | ||
778 | # CONFIG_DISPLAY_SUPPORT is not set | ||
779 | |||
780 | # | ||
781 | # Console display driver support | ||
782 | # | ||
783 | # CONFIG_VGA_CONSOLE is not set | ||
784 | CONFIG_DUMMY_CONSOLE=y | ||
785 | # CONFIG_FRAMEBUFFER_CONSOLE is not set | ||
786 | CONFIG_LOGO=y | ||
787 | # CONFIG_LOGO_LINUX_MONO is not set | ||
788 | CONFIG_LOGO_LINUX_VGA16=y | ||
789 | # CONFIG_LOGO_LINUX_CLUT224 is not set | ||
790 | |||
791 | # | ||
792 | # Sound | ||
793 | # | ||
794 | # CONFIG_SOUND is not set | ||
795 | CONFIG_HID_SUPPORT=y | ||
796 | CONFIG_HID=y | ||
797 | CONFIG_HID_DEBUG=y | ||
798 | # CONFIG_HIDRAW is not set | ||
799 | |||
800 | # | ||
801 | # USB Input Devices | ||
802 | # | ||
803 | # CONFIG_USB_HID is not set | ||
804 | |||
805 | # | ||
806 | # USB HID Boot Protocol drivers | ||
807 | # | ||
808 | # CONFIG_USB_KBD is not set | ||
809 | # CONFIG_USB_MOUSE is not set | ||
810 | CONFIG_USB_SUPPORT=y | ||
811 | CONFIG_USB_ARCH_HAS_HCD=y | ||
812 | CONFIG_USB_ARCH_HAS_OHCI=y | ||
813 | # CONFIG_USB_ARCH_HAS_EHCI is not set | ||
814 | CONFIG_USB=y | ||
815 | # CONFIG_USB_DEBUG is not set | ||
816 | |||
817 | # | ||
818 | # Miscellaneous USB options | ||
819 | # | ||
820 | CONFIG_USB_DEVICEFS=y | ||
821 | CONFIG_USB_DEVICE_CLASS=y | ||
822 | # CONFIG_USB_DYNAMIC_MINORS is not set | ||
823 | # CONFIG_USB_OTG is not set | ||
824 | |||
825 | # | ||
826 | # USB Host Controller Drivers | ||
827 | # | ||
828 | # CONFIG_USB_ISP116X_HCD is not set | ||
829 | CONFIG_USB_OHCI_HCD=y | ||
830 | # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set | ||
831 | # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set | ||
832 | CONFIG_USB_OHCI_LITTLE_ENDIAN=y | ||
833 | # CONFIG_USB_SL811_HCD is not set | ||
834 | # CONFIG_USB_R8A66597_HCD is not set | ||
835 | |||
836 | # | ||
837 | # USB Device Class drivers | ||
838 | # | ||
839 | # CONFIG_USB_ACM is not set | ||
840 | # CONFIG_USB_PRINTER is not set | ||
841 | |||
842 | # | ||
843 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' | ||
844 | # | ||
845 | |||
846 | # | ||
847 | # may also be needed; see USB_STORAGE Help for more information | ||
848 | # | ||
849 | CONFIG_USB_STORAGE=y | ||
850 | # CONFIG_USB_STORAGE_DEBUG is not set | ||
851 | # CONFIG_USB_STORAGE_DATAFAB is not set | ||
852 | # CONFIG_USB_STORAGE_FREECOM is not set | ||
853 | # CONFIG_USB_STORAGE_ISD200 is not set | ||
854 | # CONFIG_USB_STORAGE_DPCM is not set | ||
855 | # CONFIG_USB_STORAGE_USBAT is not set | ||
856 | # CONFIG_USB_STORAGE_SDDR09 is not set | ||
857 | # CONFIG_USB_STORAGE_SDDR55 is not set | ||
858 | # CONFIG_USB_STORAGE_JUMPSHOT is not set | ||
859 | # CONFIG_USB_STORAGE_ALAUDA is not set | ||
860 | # CONFIG_USB_STORAGE_ONETOUCH is not set | ||
861 | # CONFIG_USB_STORAGE_KARMA is not set | ||
862 | # CONFIG_USB_LIBUSUAL is not set | ||
863 | |||
864 | # | ||
865 | # USB Imaging devices | ||
866 | # | ||
867 | # CONFIG_USB_MDC800 is not set | ||
868 | # CONFIG_USB_MICROTEK is not set | ||
869 | CONFIG_USB_MON=y | ||
870 | |||
871 | # | ||
872 | # USB port drivers | ||
873 | # | ||
874 | |||
875 | # | ||
876 | # USB Serial Converter support | ||
877 | # | ||
878 | # CONFIG_USB_SERIAL is not set | ||
879 | |||
880 | # | ||
881 | # USB Miscellaneous drivers | ||
882 | # | ||
883 | # CONFIG_USB_EMI62 is not set | ||
884 | # CONFIG_USB_EMI26 is not set | ||
885 | # CONFIG_USB_ADUTUX is not set | ||
886 | # CONFIG_USB_AUERSWALD is not set | ||
887 | # CONFIG_USB_RIO500 is not set | ||
888 | # CONFIG_USB_LEGOTOWER is not set | ||
889 | # CONFIG_USB_LCD is not set | ||
890 | # CONFIG_USB_BERRY_CHARGE is not set | ||
891 | # CONFIG_USB_LED is not set | ||
892 | # CONFIG_USB_CYPRESS_CY7C63 is not set | ||
893 | # CONFIG_USB_CYTHERM is not set | ||
894 | # CONFIG_USB_PHIDGET is not set | ||
895 | # CONFIG_USB_IDMOUSE is not set | ||
896 | # CONFIG_USB_FTDI_ELAN is not set | ||
897 | # CONFIG_USB_APPLEDISPLAY is not set | ||
898 | # CONFIG_USB_LD is not set | ||
899 | # CONFIG_USB_TRANCEVIBRATOR is not set | ||
900 | # CONFIG_USB_IOWARRIOR is not set | ||
901 | # CONFIG_USB_TEST is not set | ||
902 | |||
903 | # | ||
904 | # USB DSL modem support | ||
905 | # | ||
906 | |||
907 | # | ||
908 | # USB Gadget Support | ||
909 | # | ||
910 | # CONFIG_USB_GADGET is not set | ||
911 | CONFIG_MMC=y | ||
912 | # CONFIG_MMC_DEBUG is not set | ||
913 | # CONFIG_MMC_UNSAFE_RESUME is not set | ||
914 | |||
915 | # | ||
916 | # MMC/SD Card Drivers | ||
917 | # | ||
918 | CONFIG_MMC_BLOCK=y | ||
919 | CONFIG_MMC_BLOCK_BOUNCE=y | ||
920 | # CONFIG_SDIO_UART is not set | ||
921 | |||
922 | # | ||
923 | # MMC/SD Host Controller Drivers | ||
924 | # | ||
925 | CONFIG_MMC_AT91=y | ||
926 | # CONFIG_MMC_SPI is not set | ||
927 | # CONFIG_NEW_LEDS is not set | ||
928 | CONFIG_RTC_LIB=y | ||
929 | # CONFIG_RTC_CLASS is not set | ||
930 | |||
931 | # | ||
932 | # File systems | ||
933 | # | ||
934 | CONFIG_EXT2_FS=y | ||
935 | # CONFIG_EXT2_FS_XATTR is not set | ||
936 | # CONFIG_EXT2_FS_XIP is not set | ||
937 | # CONFIG_EXT3_FS is not set | ||
938 | # CONFIG_EXT4DEV_FS is not set | ||
939 | # CONFIG_REISERFS_FS is not set | ||
940 | # CONFIG_JFS_FS is not set | ||
941 | # CONFIG_FS_POSIX_ACL is not set | ||
942 | # CONFIG_XFS_FS is not set | ||
943 | # CONFIG_GFS2_FS is not set | ||
944 | # CONFIG_OCFS2_FS is not set | ||
945 | # CONFIG_MINIX_FS is not set | ||
946 | # CONFIG_ROMFS_FS is not set | ||
947 | CONFIG_INOTIFY=y | ||
948 | CONFIG_INOTIFY_USER=y | ||
949 | # CONFIG_QUOTA is not set | ||
950 | CONFIG_DNOTIFY=y | ||
951 | # CONFIG_AUTOFS_FS is not set | ||
952 | # CONFIG_AUTOFS4_FS is not set | ||
953 | # CONFIG_FUSE_FS is not set | ||
954 | |||
955 | # | ||
956 | # CD-ROM/DVD Filesystems | ||
957 | # | ||
958 | # CONFIG_ISO9660_FS is not set | ||
959 | # CONFIG_UDF_FS is not set | ||
960 | |||
961 | # | ||
962 | # DOS/FAT/NT Filesystems | ||
963 | # | ||
964 | CONFIG_FAT_FS=y | ||
965 | # CONFIG_MSDOS_FS is not set | ||
966 | CONFIG_VFAT_FS=y | ||
967 | CONFIG_FAT_DEFAULT_CODEPAGE=437 | ||
968 | CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" | ||
969 | # CONFIG_NTFS_FS is not set | ||
970 | |||
971 | # | ||
972 | # Pseudo filesystems | ||
973 | # | ||
974 | CONFIG_PROC_FS=y | ||
975 | CONFIG_PROC_SYSCTL=y | ||
976 | CONFIG_SYSFS=y | ||
977 | CONFIG_TMPFS=y | ||
978 | # CONFIG_TMPFS_POSIX_ACL is not set | ||
979 | # CONFIG_HUGETLB_PAGE is not set | ||
980 | # CONFIG_CONFIGFS_FS is not set | ||
981 | |||
982 | # | ||
983 | # Miscellaneous filesystems | ||
984 | # | ||
985 | # CONFIG_ADFS_FS is not set | ||
986 | # CONFIG_AFFS_FS is not set | ||
987 | # CONFIG_HFS_FS is not set | ||
988 | # CONFIG_HFSPLUS_FS is not set | ||
989 | # CONFIG_BEFS_FS is not set | ||
990 | # CONFIG_BFS_FS is not set | ||
991 | # CONFIG_EFS_FS is not set | ||
992 | CONFIG_JFFS2_FS=y | ||
993 | CONFIG_JFFS2_FS_DEBUG=0 | ||
994 | CONFIG_JFFS2_FS_WRITEBUFFER=y | ||
995 | # CONFIG_JFFS2_FS_WBUF_VERIFY is not set | ||
996 | # CONFIG_JFFS2_SUMMARY is not set | ||
997 | # CONFIG_JFFS2_FS_XATTR is not set | ||
998 | # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set | ||
999 | CONFIG_JFFS2_ZLIB=y | ||
1000 | # CONFIG_JFFS2_LZO is not set | ||
1001 | CONFIG_JFFS2_RTIME=y | ||
1002 | # CONFIG_JFFS2_RUBIN is not set | ||
1003 | CONFIG_CRAMFS=y | ||
1004 | # CONFIG_VXFS_FS is not set | ||
1005 | # CONFIG_HPFS_FS is not set | ||
1006 | # CONFIG_QNX4FS_FS is not set | ||
1007 | # CONFIG_SYSV_FS is not set | ||
1008 | # CONFIG_UFS_FS is not set | ||
1009 | CONFIG_NETWORK_FILESYSTEMS=y | ||
1010 | CONFIG_NFS_FS=y | ||
1011 | # CONFIG_NFS_V3 is not set | ||
1012 | # CONFIG_NFS_V4 is not set | ||
1013 | # CONFIG_NFS_DIRECTIO is not set | ||
1014 | # CONFIG_NFSD is not set | ||
1015 | CONFIG_ROOT_NFS=y | ||
1016 | CONFIG_LOCKD=y | ||
1017 | CONFIG_NFS_COMMON=y | ||
1018 | CONFIG_SUNRPC=y | ||
1019 | # CONFIG_SUNRPC_BIND34 is not set | ||
1020 | # CONFIG_RPCSEC_GSS_KRB5 is not set | ||
1021 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | ||
1022 | # CONFIG_SMB_FS is not set | ||
1023 | # CONFIG_CIFS is not set | ||
1024 | # CONFIG_NCP_FS is not set | ||
1025 | # CONFIG_CODA_FS is not set | ||
1026 | # CONFIG_AFS_FS is not set | ||
1027 | |||
1028 | # | ||
1029 | # Partition Types | ||
1030 | # | ||
1031 | # CONFIG_PARTITION_ADVANCED is not set | ||
1032 | CONFIG_MSDOS_PARTITION=y | ||
1033 | CONFIG_NLS=y | ||
1034 | CONFIG_NLS_DEFAULT="iso8859-1" | ||
1035 | CONFIG_NLS_CODEPAGE_437=y | ||
1036 | # CONFIG_NLS_CODEPAGE_737 is not set | ||
1037 | # CONFIG_NLS_CODEPAGE_775 is not set | ||
1038 | CONFIG_NLS_CODEPAGE_850=y | ||
1039 | # CONFIG_NLS_CODEPAGE_852 is not set | ||
1040 | # CONFIG_NLS_CODEPAGE_855 is not set | ||
1041 | # CONFIG_NLS_CODEPAGE_857 is not set | ||
1042 | # CONFIG_NLS_CODEPAGE_860 is not set | ||
1043 | # CONFIG_NLS_CODEPAGE_861 is not set | ||
1044 | # CONFIG_NLS_CODEPAGE_862 is not set | ||
1045 | # CONFIG_NLS_CODEPAGE_863 is not set | ||
1046 | # CONFIG_NLS_CODEPAGE_864 is not set | ||
1047 | # CONFIG_NLS_CODEPAGE_865 is not set | ||
1048 | # CONFIG_NLS_CODEPAGE_866 is not set | ||
1049 | # CONFIG_NLS_CODEPAGE_869 is not set | ||
1050 | # CONFIG_NLS_CODEPAGE_936 is not set | ||
1051 | # CONFIG_NLS_CODEPAGE_950 is not set | ||
1052 | # CONFIG_NLS_CODEPAGE_932 is not set | ||
1053 | # CONFIG_NLS_CODEPAGE_949 is not set | ||
1054 | # CONFIG_NLS_CODEPAGE_874 is not set | ||
1055 | # CONFIG_NLS_ISO8859_8 is not set | ||
1056 | # CONFIG_NLS_CODEPAGE_1250 is not set | ||
1057 | # CONFIG_NLS_CODEPAGE_1251 is not set | ||
1058 | # CONFIG_NLS_ASCII is not set | ||
1059 | CONFIG_NLS_ISO8859_1=y | ||
1060 | # CONFIG_NLS_ISO8859_2 is not set | ||
1061 | # CONFIG_NLS_ISO8859_3 is not set | ||
1062 | # CONFIG_NLS_ISO8859_4 is not set | ||
1063 | # CONFIG_NLS_ISO8859_5 is not set | ||
1064 | # CONFIG_NLS_ISO8859_6 is not set | ||
1065 | # CONFIG_NLS_ISO8859_7 is not set | ||
1066 | # CONFIG_NLS_ISO8859_9 is not set | ||
1067 | # CONFIG_NLS_ISO8859_13 is not set | ||
1068 | # CONFIG_NLS_ISO8859_14 is not set | ||
1069 | # CONFIG_NLS_ISO8859_15 is not set | ||
1070 | # CONFIG_NLS_KOI8_R is not set | ||
1071 | # CONFIG_NLS_KOI8_U is not set | ||
1072 | # CONFIG_NLS_UTF8 is not set | ||
1073 | # CONFIG_DLM is not set | ||
1074 | CONFIG_INSTRUMENTATION=y | ||
1075 | # CONFIG_PROFILING is not set | ||
1076 | # CONFIG_MARKERS is not set | ||
1077 | |||
1078 | # | ||
1079 | # Kernel hacking | ||
1080 | # | ||
1081 | # CONFIG_PRINTK_TIME is not set | ||
1082 | CONFIG_ENABLE_WARN_DEPRECATED=y | ||
1083 | CONFIG_ENABLE_MUST_CHECK=y | ||
1084 | # CONFIG_MAGIC_SYSRQ is not set | ||
1085 | # CONFIG_UNUSED_SYMBOLS is not set | ||
1086 | CONFIG_DEBUG_FS=y | ||
1087 | # CONFIG_HEADERS_CHECK is not set | ||
1088 | CONFIG_DEBUG_KERNEL=y | ||
1089 | # CONFIG_DEBUG_SHIRQ is not set | ||
1090 | CONFIG_DETECT_SOFTLOCKUP=y | ||
1091 | CONFIG_SCHED_DEBUG=y | ||
1092 | # CONFIG_SCHEDSTATS is not set | ||
1093 | # CONFIG_TIMER_STATS is not set | ||
1094 | # CONFIG_DEBUG_SLAB is not set | ||
1095 | # CONFIG_DEBUG_RT_MUTEXES is not set | ||
1096 | # CONFIG_RT_MUTEX_TESTER is not set | ||
1097 | # CONFIG_DEBUG_SPINLOCK is not set | ||
1098 | # CONFIG_DEBUG_MUTEXES is not set | ||
1099 | # CONFIG_DEBUG_LOCK_ALLOC is not set | ||
1100 | # CONFIG_PROVE_LOCKING is not set | ||
1101 | # CONFIG_LOCK_STAT is not set | ||
1102 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | ||
1103 | # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set | ||
1104 | # CONFIG_DEBUG_KOBJECT is not set | ||
1105 | CONFIG_DEBUG_BUGVERBOSE=y | ||
1106 | CONFIG_DEBUG_INFO=y | ||
1107 | # CONFIG_DEBUG_VM is not set | ||
1108 | # CONFIG_DEBUG_LIST is not set | ||
1109 | # CONFIG_DEBUG_SG is not set | ||
1110 | CONFIG_FRAME_POINTER=y | ||
1111 | CONFIG_FORCED_INLINING=y | ||
1112 | # CONFIG_BOOT_PRINTK_DELAY is not set | ||
1113 | # CONFIG_RCU_TORTURE_TEST is not set | ||
1114 | # CONFIG_FAULT_INJECTION is not set | ||
1115 | # CONFIG_SAMPLES is not set | ||
1116 | CONFIG_DEBUG_USER=y | ||
1117 | # CONFIG_DEBUG_ERRORS is not set | ||
1118 | # CONFIG_DEBUG_LL is not set | ||
1119 | |||
1120 | # | ||
1121 | # Security options | ||
1122 | # | ||
1123 | # CONFIG_KEYS is not set | ||
1124 | # CONFIG_SECURITY is not set | ||
1125 | # CONFIG_SECURITY_FILE_CAPABILITIES is not set | ||
1126 | # CONFIG_CRYPTO is not set | ||
1127 | |||
1128 | # | ||
1129 | # Library routines | ||
1130 | # | ||
1131 | CONFIG_BITREVERSE=y | ||
1132 | # CONFIG_CRC_CCITT is not set | ||
1133 | # CONFIG_CRC16 is not set | ||
1134 | # CONFIG_CRC_ITU_T is not set | ||
1135 | CONFIG_CRC32=y | ||
1136 | # CONFIG_CRC7 is not set | ||
1137 | # CONFIG_LIBCRC32C is not set | ||
1138 | CONFIG_ZLIB_INFLATE=y | ||
1139 | CONFIG_ZLIB_DEFLATE=y | ||
1140 | CONFIG_PLIST=y | ||
1141 | CONFIG_HAS_IOMEM=y | ||
1142 | CONFIG_HAS_IOPORT=y | ||
1143 | CONFIG_HAS_DMA=y | ||
diff --git a/arch/arm/configs/collie_defconfig b/arch/arm/configs/collie_defconfig index 970c8c772eb7..4264e273202d 100644 --- a/arch/arm/configs/collie_defconfig +++ b/arch/arm/configs/collie_defconfig | |||
@@ -367,7 +367,6 @@ CONFIG_MTD_CFI_UTIL=y | |||
367 | # CONFIG_MTD_RAM is not set | 367 | # CONFIG_MTD_RAM is not set |
368 | # CONFIG_MTD_ROM is not set | 368 | # CONFIG_MTD_ROM is not set |
369 | # CONFIG_MTD_ABSENT is not set | 369 | # CONFIG_MTD_ABSENT is not set |
370 | CONFIG_MTD_OBSOLETE_CHIPS=y | ||
371 | CONFIG_MTD_SHARP=y | 370 | CONFIG_MTD_SHARP=y |
372 | # CONFIG_MTD_XIP is not set | 371 | # CONFIG_MTD_XIP is not set |
373 | 372 | ||
diff --git a/arch/arm/configs/iop13xx_defconfig b/arch/arm/configs/iop13xx_defconfig index add03c9e5553..988b4d13e76f 100644 --- a/arch/arm/configs/iop13xx_defconfig +++ b/arch/arm/configs/iop13xx_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.22 | 3 | # Linux kernel version: 2.6.24-rc5 |
4 | # Thu Jul 19 15:57:52 2007 | 4 | # Wed Dec 12 16:11:03 2007 |
5 | # | 5 | # |
6 | CONFIG_ARM=y | 6 | CONFIG_ARM=y |
7 | CONFIG_SYS_SUPPORTS_APM_EMULATION=y | 7 | CONFIG_SYS_SUPPORTS_APM_EMULATION=y |
@@ -26,15 +26,11 @@ CONFIG_VECTORS_BASE=0xffff0000 | |||
26 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | 26 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" |
27 | 27 | ||
28 | # | 28 | # |
29 | # Code maturity level options | 29 | # General setup |
30 | # | 30 | # |
31 | CONFIG_EXPERIMENTAL=y | 31 | CONFIG_EXPERIMENTAL=y |
32 | CONFIG_BROKEN_ON_SMP=y | 32 | CONFIG_BROKEN_ON_SMP=y |
33 | CONFIG_INIT_ENV_ARG_LIMIT=32 | 33 | CONFIG_INIT_ENV_ARG_LIMIT=32 |
34 | |||
35 | # | ||
36 | # General setup | ||
37 | # | ||
38 | CONFIG_LOCALVERSION="" | 34 | CONFIG_LOCALVERSION="" |
39 | # CONFIG_LOCALVERSION_AUTO is not set | 35 | # CONFIG_LOCALVERSION_AUTO is not set |
40 | CONFIG_SWAP=y | 36 | CONFIG_SWAP=y |
@@ -45,10 +41,15 @@ CONFIG_BSD_PROCESS_ACCT=y | |||
45 | # CONFIG_BSD_PROCESS_ACCT_V3 is not set | 41 | # CONFIG_BSD_PROCESS_ACCT_V3 is not set |
46 | # CONFIG_TASKSTATS is not set | 42 | # CONFIG_TASKSTATS is not set |
47 | # CONFIG_USER_NS is not set | 43 | # CONFIG_USER_NS is not set |
44 | # CONFIG_PID_NS is not set | ||
48 | # CONFIG_AUDIT is not set | 45 | # CONFIG_AUDIT is not set |
49 | CONFIG_IKCONFIG=y | 46 | CONFIG_IKCONFIG=y |
50 | CONFIG_IKCONFIG_PROC=y | 47 | CONFIG_IKCONFIG_PROC=y |
51 | CONFIG_LOG_BUF_SHIFT=14 | 48 | CONFIG_LOG_BUF_SHIFT=14 |
49 | # CONFIG_CGROUPS is not set | ||
50 | CONFIG_FAIR_GROUP_SCHED=y | ||
51 | CONFIG_FAIR_USER_SCHED=y | ||
52 | # CONFIG_FAIR_CGROUP_SCHED is not set | ||
52 | CONFIG_SYSFS_DEPRECATED=y | 53 | CONFIG_SYSFS_DEPRECATED=y |
53 | # CONFIG_RELAY is not set | 54 | # CONFIG_RELAY is not set |
54 | CONFIG_BLK_DEV_INITRD=y | 55 | CONFIG_BLK_DEV_INITRD=y |
@@ -69,7 +70,6 @@ CONFIG_FUTEX=y | |||
69 | CONFIG_ANON_INODES=y | 70 | CONFIG_ANON_INODES=y |
70 | CONFIG_EPOLL=y | 71 | CONFIG_EPOLL=y |
71 | CONFIG_SIGNALFD=y | 72 | CONFIG_SIGNALFD=y |
72 | CONFIG_TIMERFD=y | ||
73 | CONFIG_EVENTFD=y | 73 | CONFIG_EVENTFD=y |
74 | CONFIG_SHMEM=y | 74 | CONFIG_SHMEM=y |
75 | CONFIG_VM_EVENT_COUNTERS=y | 75 | CONFIG_VM_EVENT_COUNTERS=y |
@@ -130,6 +130,7 @@ CONFIG_ARCH_IOP13XX=y | |||
130 | # CONFIG_ARCH_L7200 is not set | 130 | # CONFIG_ARCH_L7200 is not set |
131 | # CONFIG_ARCH_KS8695 is not set | 131 | # CONFIG_ARCH_KS8695 is not set |
132 | # CONFIG_ARCH_NS9XXX is not set | 132 | # CONFIG_ARCH_NS9XXX is not set |
133 | # CONFIG_ARCH_MXC is not set | ||
133 | # CONFIG_ARCH_PNX4008 is not set | 134 | # CONFIG_ARCH_PNX4008 is not set |
134 | # CONFIG_ARCH_PXA is not set | 135 | # CONFIG_ARCH_PXA is not set |
135 | # CONFIG_ARCH_RPC is not set | 136 | # CONFIG_ARCH_RPC is not set |
@@ -151,9 +152,12 @@ CONFIG_MACH_IQ81340SC=y | |||
151 | CONFIG_MACH_IQ81340MC=y | 152 | CONFIG_MACH_IQ81340MC=y |
152 | 153 | ||
153 | # | 154 | # |
154 | # IOP13XX IMU Support | 155 | # Boot options |
156 | # | ||
157 | |||
158 | # | ||
159 | # Power management | ||
155 | # | 160 | # |
156 | # CONFIG_IOP_IMU is not set | ||
157 | CONFIG_PLAT_IOP=y | 161 | CONFIG_PLAT_IOP=y |
158 | 162 | ||
159 | # | 163 | # |
@@ -185,10 +189,7 @@ CONFIG_PCI=y | |||
185 | CONFIG_PCI_SYSCALL=y | 189 | CONFIG_PCI_SYSCALL=y |
186 | CONFIG_ARCH_SUPPORTS_MSI=y | 190 | CONFIG_ARCH_SUPPORTS_MSI=y |
187 | # CONFIG_PCI_MSI is not set | 191 | # CONFIG_PCI_MSI is not set |
188 | 192 | CONFIG_PCI_LEGACY=y | |
189 | # | ||
190 | # PCCARD (PCMCIA/CardBus) support | ||
191 | # | ||
192 | # CONFIG_PCCARD is not set | 193 | # CONFIG_PCCARD is not set |
193 | 194 | ||
194 | # | 195 | # |
@@ -207,6 +208,7 @@ CONFIG_FLATMEM_MANUAL=y | |||
207 | CONFIG_FLATMEM=y | 208 | CONFIG_FLATMEM=y |
208 | CONFIG_FLAT_NODE_MEM_MAP=y | 209 | CONFIG_FLAT_NODE_MEM_MAP=y |
209 | # CONFIG_SPARSEMEM_STATIC is not set | 210 | # CONFIG_SPARSEMEM_STATIC is not set |
211 | # CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set | ||
210 | CONFIG_SPLIT_PTLOCK_CPUS=4096 | 212 | CONFIG_SPLIT_PTLOCK_CPUS=4096 |
211 | # CONFIG_RESOURCES_64BIT is not set | 213 | # CONFIG_RESOURCES_64BIT is not set |
212 | CONFIG_ZONE_DMA_FLAG=1 | 214 | CONFIG_ZONE_DMA_FLAG=1 |
@@ -246,6 +248,7 @@ CONFIG_BINFMT_AOUT=y | |||
246 | # Power management options | 248 | # Power management options |
247 | # | 249 | # |
248 | # CONFIG_PM is not set | 250 | # CONFIG_PM is not set |
251 | CONFIG_SUSPEND_UP_POSSIBLE=y | ||
249 | 252 | ||
250 | # | 253 | # |
251 | # Networking | 254 | # Networking |
@@ -285,6 +288,7 @@ CONFIG_IP_PNP_BOOTP=y | |||
285 | CONFIG_INET_XFRM_MODE_TRANSPORT=y | 288 | CONFIG_INET_XFRM_MODE_TRANSPORT=y |
286 | CONFIG_INET_XFRM_MODE_TUNNEL=y | 289 | CONFIG_INET_XFRM_MODE_TUNNEL=y |
287 | CONFIG_INET_XFRM_MODE_BEET=y | 290 | CONFIG_INET_XFRM_MODE_BEET=y |
291 | # CONFIG_INET_LRO is not set | ||
288 | CONFIG_INET_DIAG=y | 292 | CONFIG_INET_DIAG=y |
289 | CONFIG_INET_TCP_DIAG=y | 293 | CONFIG_INET_TCP_DIAG=y |
290 | # CONFIG_TCP_CONG_ADVANCED is not set | 294 | # CONFIG_TCP_CONG_ADVANCED is not set |
@@ -324,10 +328,6 @@ CONFIG_IPV6=y | |||
324 | # CONFIG_LAPB is not set | 328 | # CONFIG_LAPB is not set |
325 | # CONFIG_ECONET is not set | 329 | # CONFIG_ECONET is not set |
326 | # CONFIG_WAN_ROUTER is not set | 330 | # CONFIG_WAN_ROUTER is not set |
327 | |||
328 | # | ||
329 | # QoS and/or fair queueing | ||
330 | # | ||
331 | # CONFIG_NET_SCHED is not set | 331 | # CONFIG_NET_SCHED is not set |
332 | 332 | ||
333 | # | 333 | # |
@@ -356,6 +356,7 @@ CONFIG_IPV6=y | |||
356 | # | 356 | # |
357 | # Generic Driver Options | 357 | # Generic Driver Options |
358 | # | 358 | # |
359 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
359 | CONFIG_STANDALONE=y | 360 | CONFIG_STANDALONE=y |
360 | CONFIG_PREVENT_FIRMWARE_BUILD=y | 361 | CONFIG_PREVENT_FIRMWARE_BUILD=y |
361 | # CONFIG_FW_LOADER is not set | 362 | # CONFIG_FW_LOADER is not set |
@@ -383,6 +384,7 @@ CONFIG_MTD_BLOCK=y | |||
383 | # CONFIG_INFTL is not set | 384 | # CONFIG_INFTL is not set |
384 | # CONFIG_RFD_FTL is not set | 385 | # CONFIG_RFD_FTL is not set |
385 | # CONFIG_SSFDC is not set | 386 | # CONFIG_SSFDC is not set |
387 | # CONFIG_MTD_OOPS is not set | ||
386 | 388 | ||
387 | # | 389 | # |
388 | # RAM/ROM/Flash chip drivers | 390 | # RAM/ROM/Flash chip drivers |
@@ -423,6 +425,7 @@ CONFIG_MTD_PHYSMAP_START=0xfa000000 | |||
423 | CONFIG_MTD_PHYSMAP_LEN=0x0 | 425 | CONFIG_MTD_PHYSMAP_LEN=0x0 |
424 | CONFIG_MTD_PHYSMAP_BANKWIDTH=2 | 426 | CONFIG_MTD_PHYSMAP_BANKWIDTH=2 |
425 | # CONFIG_MTD_ARM_INTEGRATOR is not set | 427 | # CONFIG_MTD_ARM_INTEGRATOR is not set |
428 | # CONFIG_MTD_INTEL_VR_NOR is not set | ||
426 | # CONFIG_MTD_PLATRAM is not set | 429 | # CONFIG_MTD_PLATRAM is not set |
427 | 430 | ||
428 | # | 431 | # |
@@ -463,6 +466,11 @@ CONFIG_BLK_DEV_RAM_SIZE=8192 | |||
463 | CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 | 466 | CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 |
464 | # CONFIG_CDROM_PKTCDVD is not set | 467 | # CONFIG_CDROM_PKTCDVD is not set |
465 | # CONFIG_ATA_OVER_ETH is not set | 468 | # CONFIG_ATA_OVER_ETH is not set |
469 | CONFIG_MISC_DEVICES=y | ||
470 | # CONFIG_PHANTOM is not set | ||
471 | # CONFIG_EEPROM_93CX6 is not set | ||
472 | # CONFIG_SGI_IOC4 is not set | ||
473 | # CONFIG_TIFM_CORE is not set | ||
466 | 474 | ||
467 | # | 475 | # |
468 | # SCSI device support | 476 | # SCSI device support |
@@ -499,12 +507,9 @@ CONFIG_SCSI_WAIT_SCAN=m | |||
499 | # CONFIG_SCSI_SPI_ATTRS is not set | 507 | # CONFIG_SCSI_SPI_ATTRS is not set |
500 | # CONFIG_SCSI_FC_ATTRS is not set | 508 | # CONFIG_SCSI_FC_ATTRS is not set |
501 | CONFIG_SCSI_ISCSI_ATTRS=y | 509 | CONFIG_SCSI_ISCSI_ATTRS=y |
502 | CONFIG_SCSI_SAS_ATTRS=y | ||
503 | # CONFIG_SCSI_SAS_LIBSAS is not set | 510 | # CONFIG_SCSI_SAS_LIBSAS is not set |
504 | 511 | # CONFIG_SCSI_SRP_ATTRS is not set | |
505 | # | 512 | CONFIG_SCSI_LOWLEVEL=y |
506 | # SCSI low-level drivers | ||
507 | # | ||
508 | # CONFIG_ISCSI_TCP is not set | 513 | # CONFIG_ISCSI_TCP is not set |
509 | # CONFIG_BLK_DEV_3W_XXXX_RAID is not set | 514 | # CONFIG_BLK_DEV_3W_XXXX_RAID is not set |
510 | # CONFIG_SCSI_3W_9XXX is not set | 515 | # CONFIG_SCSI_3W_9XXX is not set |
@@ -515,6 +520,7 @@ CONFIG_SCSI_SAS_ATTRS=y | |||
515 | # CONFIG_SCSI_AIC79XX is not set | 520 | # CONFIG_SCSI_AIC79XX is not set |
516 | # CONFIG_SCSI_AIC94XX is not set | 521 | # CONFIG_SCSI_AIC94XX is not set |
517 | # CONFIG_SCSI_DPT_I2O is not set | 522 | # CONFIG_SCSI_DPT_I2O is not set |
523 | # CONFIG_SCSI_ADVANSYS is not set | ||
518 | # CONFIG_SCSI_ARCMSR is not set | 524 | # CONFIG_SCSI_ARCMSR is not set |
519 | # CONFIG_MEGARAID_NEWGEN is not set | 525 | # CONFIG_MEGARAID_NEWGEN is not set |
520 | # CONFIG_MEGARAID_LEGACY is not set | 526 | # CONFIG_MEGARAID_LEGACY is not set |
@@ -555,14 +561,8 @@ CONFIG_BLK_DEV_DM=y | |||
555 | # CONFIG_DM_ZERO is not set | 561 | # CONFIG_DM_ZERO is not set |
556 | # CONFIG_DM_MULTIPATH is not set | 562 | # CONFIG_DM_MULTIPATH is not set |
557 | # CONFIG_DM_DELAY is not set | 563 | # CONFIG_DM_DELAY is not set |
558 | 564 | # CONFIG_DM_UEVENT is not set | |
559 | # | ||
560 | # Fusion MPT device support | ||
561 | # | ||
562 | # CONFIG_FUSION is not set | 565 | # CONFIG_FUSION is not set |
563 | # CONFIG_FUSION_SPI is not set | ||
564 | # CONFIG_FUSION_FC is not set | ||
565 | # CONFIG_FUSION_SAS is not set | ||
566 | 566 | ||
567 | # | 567 | # |
568 | # IEEE 1394 (FireWire) support | 568 | # IEEE 1394 (FireWire) support |
@@ -577,6 +577,8 @@ CONFIG_NETDEVICES=y | |||
577 | # CONFIG_MACVLAN is not set | 577 | # CONFIG_MACVLAN is not set |
578 | # CONFIG_EQUALIZER is not set | 578 | # CONFIG_EQUALIZER is not set |
579 | # CONFIG_TUN is not set | 579 | # CONFIG_TUN is not set |
580 | # CONFIG_VETH is not set | ||
581 | # CONFIG_IP1000 is not set | ||
580 | # CONFIG_ARCNET is not set | 582 | # CONFIG_ARCNET is not set |
581 | # CONFIG_NET_ETHERNET is not set | 583 | # CONFIG_NET_ETHERNET is not set |
582 | CONFIG_NETDEV_1000=y | 584 | CONFIG_NETDEV_1000=y |
@@ -585,6 +587,7 @@ CONFIG_NETDEV_1000=y | |||
585 | CONFIG_E1000=y | 587 | CONFIG_E1000=y |
586 | CONFIG_E1000_NAPI=y | 588 | CONFIG_E1000_NAPI=y |
587 | # CONFIG_E1000_DISABLE_PACKET_SPLIT is not set | 589 | # CONFIG_E1000_DISABLE_PACKET_SPLIT is not set |
590 | # CONFIG_E1000E is not set | ||
588 | # CONFIG_NS83820 is not set | 591 | # CONFIG_NS83820 is not set |
589 | # CONFIG_HAMACHI is not set | 592 | # CONFIG_HAMACHI is not set |
590 | # CONFIG_YELLOWFIN is not set | 593 | # CONFIG_YELLOWFIN is not set |
@@ -592,6 +595,7 @@ CONFIG_E1000_NAPI=y | |||
592 | # CONFIG_SIS190 is not set | 595 | # CONFIG_SIS190 is not set |
593 | # CONFIG_SKGE is not set | 596 | # CONFIG_SKGE is not set |
594 | # CONFIG_SKY2 is not set | 597 | # CONFIG_SKY2 is not set |
598 | # CONFIG_SK98LIN is not set | ||
595 | # CONFIG_VIA_VELOCITY is not set | 599 | # CONFIG_VIA_VELOCITY is not set |
596 | # CONFIG_TIGON3 is not set | 600 | # CONFIG_TIGON3 is not set |
597 | # CONFIG_BNX2 is not set | 601 | # CONFIG_BNX2 is not set |
@@ -600,11 +604,14 @@ CONFIG_E1000_NAPI=y | |||
600 | CONFIG_NETDEV_10000=y | 604 | CONFIG_NETDEV_10000=y |
601 | # CONFIG_CHELSIO_T1 is not set | 605 | # CONFIG_CHELSIO_T1 is not set |
602 | # CONFIG_CHELSIO_T3 is not set | 606 | # CONFIG_CHELSIO_T3 is not set |
607 | # CONFIG_IXGBE is not set | ||
603 | # CONFIG_IXGB is not set | 608 | # CONFIG_IXGB is not set |
604 | # CONFIG_S2IO is not set | 609 | # CONFIG_S2IO is not set |
605 | # CONFIG_MYRI10GE is not set | 610 | # CONFIG_MYRI10GE is not set |
606 | # CONFIG_NETXEN_NIC is not set | 611 | # CONFIG_NETXEN_NIC is not set |
612 | # CONFIG_NIU is not set | ||
607 | # CONFIG_MLX4_CORE is not set | 613 | # CONFIG_MLX4_CORE is not set |
614 | # CONFIG_TEHUTI is not set | ||
608 | # CONFIG_TR is not set | 615 | # CONFIG_TR is not set |
609 | 616 | ||
610 | # | 617 | # |
@@ -639,7 +646,6 @@ CONFIG_INPUT_MOUSEDEV=y | |||
639 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 | 646 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 |
640 | CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | 647 | CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 |
641 | # CONFIG_INPUT_JOYDEV is not set | 648 | # CONFIG_INPUT_JOYDEV is not set |
642 | # CONFIG_INPUT_TSDEV is not set | ||
643 | # CONFIG_INPUT_EVDEV is not set | 649 | # CONFIG_INPUT_EVDEV is not set |
644 | # CONFIG_INPUT_EVBUG is not set | 650 | # CONFIG_INPUT_EVBUG is not set |
645 | 651 | ||
@@ -688,12 +694,10 @@ CONFIG_UNIX98_PTYS=y | |||
688 | CONFIG_LEGACY_PTYS=y | 694 | CONFIG_LEGACY_PTYS=y |
689 | CONFIG_LEGACY_PTY_COUNT=256 | 695 | CONFIG_LEGACY_PTY_COUNT=256 |
690 | # CONFIG_IPMI_HANDLER is not set | 696 | # CONFIG_IPMI_HANDLER is not set |
691 | # CONFIG_WATCHDOG is not set | ||
692 | CONFIG_HW_RANDOM=y | 697 | CONFIG_HW_RANDOM=y |
693 | # CONFIG_NVRAM is not set | 698 | # CONFIG_NVRAM is not set |
694 | # CONFIG_R3964 is not set | 699 | # CONFIG_R3964 is not set |
695 | # CONFIG_APPLICOM is not set | 700 | # CONFIG_APPLICOM is not set |
696 | # CONFIG_DRM is not set | ||
697 | # CONFIG_RAW_DRIVER is not set | 701 | # CONFIG_RAW_DRIVER is not set |
698 | # CONFIG_TCG_TPM is not set | 702 | # CONFIG_TCG_TPM is not set |
699 | CONFIG_DEVPORT=y | 703 | CONFIG_DEVPORT=y |
@@ -758,9 +762,9 @@ CONFIG_I2C_IOP3XX=y | |||
758 | # CONFIG_SPI is not set | 762 | # CONFIG_SPI is not set |
759 | # CONFIG_SPI_MASTER is not set | 763 | # CONFIG_SPI_MASTER is not set |
760 | # CONFIG_W1 is not set | 764 | # CONFIG_W1 is not set |
765 | # CONFIG_POWER_SUPPLY is not set | ||
761 | CONFIG_HWMON=y | 766 | CONFIG_HWMON=y |
762 | # CONFIG_HWMON_VID is not set | 767 | # CONFIG_HWMON_VID is not set |
763 | # CONFIG_SENSORS_ABITUGURU is not set | ||
764 | # CONFIG_SENSORS_AD7418 is not set | 768 | # CONFIG_SENSORS_AD7418 is not set |
765 | # CONFIG_SENSORS_ADM1021 is not set | 769 | # CONFIG_SENSORS_ADM1021 is not set |
766 | # CONFIG_SENSORS_ADM1025 is not set | 770 | # CONFIG_SENSORS_ADM1025 is not set |
@@ -768,12 +772,13 @@ CONFIG_HWMON=y | |||
768 | # CONFIG_SENSORS_ADM1029 is not set | 772 | # CONFIG_SENSORS_ADM1029 is not set |
769 | # CONFIG_SENSORS_ADM1031 is not set | 773 | # CONFIG_SENSORS_ADM1031 is not set |
770 | # CONFIG_SENSORS_ADM9240 is not set | 774 | # CONFIG_SENSORS_ADM9240 is not set |
771 | # CONFIG_SENSORS_ASB100 is not set | 775 | # CONFIG_SENSORS_ADT7470 is not set |
772 | # CONFIG_SENSORS_ATXP1 is not set | 776 | # CONFIG_SENSORS_ATXP1 is not set |
773 | # CONFIG_SENSORS_DS1621 is not set | 777 | # CONFIG_SENSORS_DS1621 is not set |
778 | # CONFIG_SENSORS_I5K_AMB is not set | ||
774 | # CONFIG_SENSORS_F71805F is not set | 779 | # CONFIG_SENSORS_F71805F is not set |
775 | # CONFIG_SENSORS_FSCHER is not set | 780 | # CONFIG_SENSORS_F71882FG is not set |
776 | # CONFIG_SENSORS_FSCPOS is not set | 781 | # CONFIG_SENSORS_F75375S is not set |
777 | # CONFIG_SENSORS_GL518SM is not set | 782 | # CONFIG_SENSORS_GL518SM is not set |
778 | # CONFIG_SENSORS_GL520SM is not set | 783 | # CONFIG_SENSORS_GL520SM is not set |
779 | # CONFIG_SENSORS_IT87 is not set | 784 | # CONFIG_SENSORS_IT87 is not set |
@@ -787,14 +792,17 @@ CONFIG_HWMON=y | |||
787 | # CONFIG_SENSORS_LM87 is not set | 792 | # CONFIG_SENSORS_LM87 is not set |
788 | # CONFIG_SENSORS_LM90 is not set | 793 | # CONFIG_SENSORS_LM90 is not set |
789 | # CONFIG_SENSORS_LM92 is not set | 794 | # CONFIG_SENSORS_LM92 is not set |
795 | # CONFIG_SENSORS_LM93 is not set | ||
790 | # CONFIG_SENSORS_MAX1619 is not set | 796 | # CONFIG_SENSORS_MAX1619 is not set |
791 | # CONFIG_SENSORS_MAX6650 is not set | 797 | # CONFIG_SENSORS_MAX6650 is not set |
792 | # CONFIG_SENSORS_PC87360 is not set | 798 | # CONFIG_SENSORS_PC87360 is not set |
793 | # CONFIG_SENSORS_PC87427 is not set | 799 | # CONFIG_SENSORS_PC87427 is not set |
794 | # CONFIG_SENSORS_SIS5595 is not set | 800 | # CONFIG_SENSORS_SIS5595 is not set |
801 | # CONFIG_SENSORS_DME1737 is not set | ||
795 | # CONFIG_SENSORS_SMSC47M1 is not set | 802 | # CONFIG_SENSORS_SMSC47M1 is not set |
796 | # CONFIG_SENSORS_SMSC47M192 is not set | 803 | # CONFIG_SENSORS_SMSC47M192 is not set |
797 | # CONFIG_SENSORS_SMSC47B397 is not set | 804 | # CONFIG_SENSORS_SMSC47B397 is not set |
805 | # CONFIG_SENSORS_THMC50 is not set | ||
798 | # CONFIG_SENSORS_VIA686A is not set | 806 | # CONFIG_SENSORS_VIA686A is not set |
799 | # CONFIG_SENSORS_VT1211 is not set | 807 | # CONFIG_SENSORS_VT1211 is not set |
800 | # CONFIG_SENSORS_VT8231 is not set | 808 | # CONFIG_SENSORS_VT8231 is not set |
@@ -806,29 +814,18 @@ CONFIG_HWMON=y | |||
806 | # CONFIG_SENSORS_W83627HF is not set | 814 | # CONFIG_SENSORS_W83627HF is not set |
807 | # CONFIG_SENSORS_W83627EHF is not set | 815 | # CONFIG_SENSORS_W83627EHF is not set |
808 | # CONFIG_HWMON_DEBUG_CHIP is not set | 816 | # CONFIG_HWMON_DEBUG_CHIP is not set |
809 | CONFIG_MISC_DEVICES=y | 817 | # CONFIG_WATCHDOG is not set |
810 | # CONFIG_PHANTOM is not set | ||
811 | # CONFIG_EEPROM_93CX6 is not set | ||
812 | # CONFIG_SGI_IOC4 is not set | ||
813 | # CONFIG_TIFM_CORE is not set | ||
814 | |||
815 | # | ||
816 | # Multifunction device drivers | ||
817 | # | ||
818 | # CONFIG_MFD_SM501 is not set | ||
819 | |||
820 | # | ||
821 | # LED devices | ||
822 | # | ||
823 | # CONFIG_NEW_LEDS is not set | ||
824 | 818 | ||
825 | # | 819 | # |
826 | # LED drivers | 820 | # Sonics Silicon Backplane |
827 | # | 821 | # |
822 | CONFIG_SSB_POSSIBLE=y | ||
823 | # CONFIG_SSB is not set | ||
828 | 824 | ||
829 | # | 825 | # |
830 | # LED Triggers | 826 | # Multifunction device drivers |
831 | # | 827 | # |
828 | # CONFIG_MFD_SM501 is not set | ||
832 | 829 | ||
833 | # | 830 | # |
834 | # Multimedia devices | 831 | # Multimedia devices |
@@ -840,14 +837,16 @@ CONFIG_DAB=y | |||
840 | # | 837 | # |
841 | # Graphics support | 838 | # Graphics support |
842 | # | 839 | # |
840 | # CONFIG_DRM is not set | ||
841 | # CONFIG_VGASTATE is not set | ||
842 | # CONFIG_VIDEO_OUTPUT_CONTROL is not set | ||
843 | # CONFIG_FB is not set | ||
843 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set | 844 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set |
844 | 845 | ||
845 | # | 846 | # |
846 | # Display device support | 847 | # Display device support |
847 | # | 848 | # |
848 | # CONFIG_DISPLAY_SUPPORT is not set | 849 | # CONFIG_DISPLAY_SUPPORT is not set |
849 | # CONFIG_VGASTATE is not set | ||
850 | # CONFIG_FB is not set | ||
851 | 850 | ||
852 | # | 851 | # |
853 | # Console display driver support | 852 | # Console display driver support |
@@ -862,6 +861,7 @@ CONFIG_DUMMY_CONSOLE=y | |||
862 | CONFIG_HID_SUPPORT=y | 861 | CONFIG_HID_SUPPORT=y |
863 | CONFIG_HID=y | 862 | CONFIG_HID=y |
864 | # CONFIG_HID_DEBUG is not set | 863 | # CONFIG_HID_DEBUG is not set |
864 | # CONFIG_HIDRAW is not set | ||
865 | CONFIG_USB_SUPPORT=y | 865 | CONFIG_USB_SUPPORT=y |
866 | CONFIG_USB_ARCH_HAS_HCD=y | 866 | CONFIG_USB_ARCH_HAS_HCD=y |
867 | CONFIG_USB_ARCH_HAS_OHCI=y | 867 | CONFIG_USB_ARCH_HAS_OHCI=y |
@@ -877,16 +877,15 @@ CONFIG_USB_ARCH_HAS_EHCI=y | |||
877 | # | 877 | # |
878 | # CONFIG_USB_GADGET is not set | 878 | # CONFIG_USB_GADGET is not set |
879 | # CONFIG_MMC is not set | 879 | # CONFIG_MMC is not set |
880 | 880 | # CONFIG_NEW_LEDS is not set | |
881 | # | ||
882 | # Real Time Clock | ||
883 | # | ||
884 | CONFIG_RTC_LIB=y | 881 | CONFIG_RTC_LIB=y |
885 | # CONFIG_RTC_CLASS is not set | 882 | # CONFIG_RTC_CLASS is not set |
883 | CONFIG_DMADEVICES=y | ||
886 | 884 | ||
887 | # | 885 | # |
888 | # DMA Engine support | 886 | # DMA Devices |
889 | # | 887 | # |
888 | CONFIG_INTEL_IOP_ADMA=y | ||
890 | CONFIG_DMA_ENGINE=y | 889 | CONFIG_DMA_ENGINE=y |
891 | 890 | ||
892 | # | 891 | # |
@@ -895,12 +894,6 @@ CONFIG_DMA_ENGINE=y | |||
895 | # CONFIG_NET_DMA is not set | 894 | # CONFIG_NET_DMA is not set |
896 | 895 | ||
897 | # | 896 | # |
898 | # DMA Devices | ||
899 | # | ||
900 | # CONFIG_INTEL_IOATDMA is not set | ||
901 | CONFIG_INTEL_IOP_ADMA=y | ||
902 | |||
903 | # | ||
904 | # File systems | 897 | # File systems |
905 | # | 898 | # |
906 | CONFIG_EXT2_FS=y | 899 | CONFIG_EXT2_FS=y |
@@ -912,7 +905,6 @@ CONFIG_EXT3_FS_XATTR=y | |||
912 | # CONFIG_EXT3_FS_SECURITY is not set | 905 | # CONFIG_EXT3_FS_SECURITY is not set |
913 | # CONFIG_EXT4DEV_FS is not set | 906 | # CONFIG_EXT4DEV_FS is not set |
914 | CONFIG_JBD=y | 907 | CONFIG_JBD=y |
915 | # CONFIG_JBD_DEBUG is not set | ||
916 | CONFIG_FS_MBCACHE=y | 908 | CONFIG_FS_MBCACHE=y |
917 | # CONFIG_REISERFS_FS is not set | 909 | # CONFIG_REISERFS_FS is not set |
918 | # CONFIG_JFS_FS is not set | 910 | # CONFIG_JFS_FS is not set |
@@ -952,7 +944,6 @@ CONFIG_SYSFS=y | |||
952 | CONFIG_TMPFS=y | 944 | CONFIG_TMPFS=y |
953 | # CONFIG_TMPFS_POSIX_ACL is not set | 945 | # CONFIG_TMPFS_POSIX_ACL is not set |
954 | # CONFIG_HUGETLB_PAGE is not set | 946 | # CONFIG_HUGETLB_PAGE is not set |
955 | CONFIG_RAMFS=y | ||
956 | # CONFIG_CONFIGFS_FS is not set | 947 | # CONFIG_CONFIGFS_FS is not set |
957 | 948 | ||
958 | # | 949 | # |
@@ -969,10 +960,12 @@ CONFIG_ECRYPT_FS=y | |||
969 | CONFIG_JFFS2_FS=y | 960 | CONFIG_JFFS2_FS=y |
970 | CONFIG_JFFS2_FS_DEBUG=0 | 961 | CONFIG_JFFS2_FS_DEBUG=0 |
971 | CONFIG_JFFS2_FS_WRITEBUFFER=y | 962 | CONFIG_JFFS2_FS_WRITEBUFFER=y |
963 | # CONFIG_JFFS2_FS_WBUF_VERIFY is not set | ||
972 | # CONFIG_JFFS2_SUMMARY is not set | 964 | # CONFIG_JFFS2_SUMMARY is not set |
973 | # CONFIG_JFFS2_FS_XATTR is not set | 965 | # CONFIG_JFFS2_FS_XATTR is not set |
974 | # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set | 966 | # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set |
975 | CONFIG_JFFS2_ZLIB=y | 967 | CONFIG_JFFS2_ZLIB=y |
968 | # CONFIG_JFFS2_LZO is not set | ||
976 | CONFIG_JFFS2_RTIME=y | 969 | CONFIG_JFFS2_RTIME=y |
977 | # CONFIG_JFFS2_RUBIN is not set | 970 | # CONFIG_JFFS2_RUBIN is not set |
978 | CONFIG_CRAMFS=y | 971 | CONFIG_CRAMFS=y |
@@ -981,10 +974,7 @@ CONFIG_CRAMFS=y | |||
981 | # CONFIG_QNX4FS_FS is not set | 974 | # CONFIG_QNX4FS_FS is not set |
982 | # CONFIG_SYSV_FS is not set | 975 | # CONFIG_SYSV_FS is not set |
983 | # CONFIG_UFS_FS is not set | 976 | # CONFIG_UFS_FS is not set |
984 | 977 | CONFIG_NETWORK_FILESYSTEMS=y | |
985 | # | ||
986 | # Network File Systems | ||
987 | # | ||
988 | CONFIG_NFS_FS=y | 978 | CONFIG_NFS_FS=y |
989 | CONFIG_NFS_V3=y | 979 | CONFIG_NFS_V3=y |
990 | # CONFIG_NFS_V3_ACL is not set | 980 | # CONFIG_NFS_V3_ACL is not set |
@@ -1037,10 +1027,6 @@ CONFIG_MSDOS_PARTITION=y | |||
1037 | # CONFIG_KARMA_PARTITION is not set | 1027 | # CONFIG_KARMA_PARTITION is not set |
1038 | # CONFIG_EFI_PARTITION is not set | 1028 | # CONFIG_EFI_PARTITION is not set |
1039 | # CONFIG_SYSV68_PARTITION is not set | 1029 | # CONFIG_SYSV68_PARTITION is not set |
1040 | |||
1041 | # | ||
1042 | # Native Language Support | ||
1043 | # | ||
1044 | CONFIG_NLS=y | 1030 | CONFIG_NLS=y |
1045 | CONFIG_NLS_DEFAULT="iso8859-1" | 1031 | CONFIG_NLS_DEFAULT="iso8859-1" |
1046 | # CONFIG_NLS_CODEPAGE_437 is not set | 1032 | # CONFIG_NLS_CODEPAGE_437 is not set |
@@ -1081,21 +1067,16 @@ CONFIG_NLS_DEFAULT="iso8859-1" | |||
1081 | # CONFIG_NLS_KOI8_R is not set | 1067 | # CONFIG_NLS_KOI8_R is not set |
1082 | # CONFIG_NLS_KOI8_U is not set | 1068 | # CONFIG_NLS_KOI8_U is not set |
1083 | # CONFIG_NLS_UTF8 is not set | 1069 | # CONFIG_NLS_UTF8 is not set |
1084 | |||
1085 | # | ||
1086 | # Distributed Lock Manager | ||
1087 | # | ||
1088 | # CONFIG_DLM is not set | 1070 | # CONFIG_DLM is not set |
1089 | 1071 | CONFIG_INSTRUMENTATION=y | |
1090 | # | ||
1091 | # Profiling support | ||
1092 | # | ||
1093 | # CONFIG_PROFILING is not set | 1072 | # CONFIG_PROFILING is not set |
1073 | # CONFIG_MARKERS is not set | ||
1094 | 1074 | ||
1095 | # | 1075 | # |
1096 | # Kernel hacking | 1076 | # Kernel hacking |
1097 | # | 1077 | # |
1098 | # CONFIG_PRINTK_TIME is not set | 1078 | # CONFIG_PRINTK_TIME is not set |
1079 | CONFIG_ENABLE_WARN_DEPRECATED=y | ||
1099 | CONFIG_ENABLE_MUST_CHECK=y | 1080 | CONFIG_ENABLE_MUST_CHECK=y |
1100 | # CONFIG_MAGIC_SYSRQ is not set | 1081 | # CONFIG_MAGIC_SYSRQ is not set |
1101 | # CONFIG_UNUSED_SYMBOLS is not set | 1082 | # CONFIG_UNUSED_SYMBOLS is not set |
@@ -1104,6 +1085,7 @@ CONFIG_ENABLE_MUST_CHECK=y | |||
1104 | # CONFIG_DEBUG_KERNEL is not set | 1085 | # CONFIG_DEBUG_KERNEL is not set |
1105 | CONFIG_DEBUG_BUGVERBOSE=y | 1086 | CONFIG_DEBUG_BUGVERBOSE=y |
1106 | CONFIG_FRAME_POINTER=y | 1087 | CONFIG_FRAME_POINTER=y |
1088 | # CONFIG_SAMPLES is not set | ||
1107 | CONFIG_DEBUG_USER=y | 1089 | CONFIG_DEBUG_USER=y |
1108 | 1090 | ||
1109 | # | 1091 | # |
@@ -1112,6 +1094,7 @@ CONFIG_DEBUG_USER=y | |||
1112 | CONFIG_KEYS=y | 1094 | CONFIG_KEYS=y |
1113 | CONFIG_KEYS_DEBUG_PROC_KEYS=y | 1095 | CONFIG_KEYS_DEBUG_PROC_KEYS=y |
1114 | # CONFIG_SECURITY is not set | 1096 | # CONFIG_SECURITY is not set |
1097 | # CONFIG_SECURITY_FILE_CAPABILITIES is not set | ||
1115 | CONFIG_XOR_BLOCKS=y | 1098 | CONFIG_XOR_BLOCKS=y |
1116 | CONFIG_ASYNC_CORE=y | 1099 | CONFIG_ASYNC_CORE=y |
1117 | CONFIG_ASYNC_MEMCPY=y | 1100 | CONFIG_ASYNC_MEMCPY=y |
@@ -1136,6 +1119,7 @@ CONFIG_CRYPTO_ECB=y | |||
1136 | CONFIG_CRYPTO_CBC=y | 1119 | CONFIG_CRYPTO_CBC=y |
1137 | CONFIG_CRYPTO_PCBC=m | 1120 | CONFIG_CRYPTO_PCBC=m |
1138 | CONFIG_CRYPTO_LRW=y | 1121 | CONFIG_CRYPTO_LRW=y |
1122 | # CONFIG_CRYPTO_XTS is not set | ||
1139 | # CONFIG_CRYPTO_CRYPTD is not set | 1123 | # CONFIG_CRYPTO_CRYPTD is not set |
1140 | CONFIG_CRYPTO_DES=y | 1124 | CONFIG_CRYPTO_DES=y |
1141 | # CONFIG_CRYPTO_FCRYPT is not set | 1125 | # CONFIG_CRYPTO_FCRYPT is not set |
@@ -1150,11 +1134,13 @@ CONFIG_CRYPTO_TEA=y | |||
1150 | CONFIG_CRYPTO_ARC4=y | 1134 | CONFIG_CRYPTO_ARC4=y |
1151 | CONFIG_CRYPTO_KHAZAD=y | 1135 | CONFIG_CRYPTO_KHAZAD=y |
1152 | CONFIG_CRYPTO_ANUBIS=y | 1136 | CONFIG_CRYPTO_ANUBIS=y |
1137 | # CONFIG_CRYPTO_SEED is not set | ||
1153 | CONFIG_CRYPTO_DEFLATE=y | 1138 | CONFIG_CRYPTO_DEFLATE=y |
1154 | CONFIG_CRYPTO_MICHAEL_MIC=y | 1139 | CONFIG_CRYPTO_MICHAEL_MIC=y |
1155 | CONFIG_CRYPTO_CRC32C=y | 1140 | CONFIG_CRYPTO_CRC32C=y |
1156 | # CONFIG_CRYPTO_CAMELLIA is not set | 1141 | # CONFIG_CRYPTO_CAMELLIA is not set |
1157 | # CONFIG_CRYPTO_TEST is not set | 1142 | # CONFIG_CRYPTO_TEST is not set |
1143 | # CONFIG_CRYPTO_AUTHENC is not set | ||
1158 | CONFIG_CRYPTO_HW=y | 1144 | CONFIG_CRYPTO_HW=y |
1159 | 1145 | ||
1160 | # | 1146 | # |
diff --git a/arch/arm/configs/iop32x_defconfig b/arch/arm/configs/iop32x_defconfig index 027aef22b4d1..83f40d4041a6 100644 --- a/arch/arm/configs/iop32x_defconfig +++ b/arch/arm/configs/iop32x_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.22 | 3 | # Linux kernel version: 2.6.24-rc5 |
4 | # Thu Jul 19 16:00:36 2007 | 4 | # Wed Dec 12 15:49:08 2007 |
5 | # | 5 | # |
6 | CONFIG_ARM=y | 6 | CONFIG_ARM=y |
7 | CONFIG_SYS_SUPPORTS_APM_EMULATION=y | 7 | CONFIG_SYS_SUPPORTS_APM_EMULATION=y |
@@ -26,15 +26,11 @@ CONFIG_VECTORS_BASE=0xffff0000 | |||
26 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | 26 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" |
27 | 27 | ||
28 | # | 28 | # |
29 | # Code maturity level options | 29 | # General setup |
30 | # | 30 | # |
31 | CONFIG_EXPERIMENTAL=y | 31 | CONFIG_EXPERIMENTAL=y |
32 | CONFIG_BROKEN_ON_SMP=y | 32 | CONFIG_BROKEN_ON_SMP=y |
33 | CONFIG_INIT_ENV_ARG_LIMIT=32 | 33 | CONFIG_INIT_ENV_ARG_LIMIT=32 |
34 | |||
35 | # | ||
36 | # General setup | ||
37 | # | ||
38 | CONFIG_LOCALVERSION="" | 34 | CONFIG_LOCALVERSION="" |
39 | CONFIG_LOCALVERSION_AUTO=y | 35 | CONFIG_LOCALVERSION_AUTO=y |
40 | CONFIG_SWAP=y | 36 | CONFIG_SWAP=y |
@@ -45,9 +41,14 @@ CONFIG_BSD_PROCESS_ACCT=y | |||
45 | # CONFIG_BSD_PROCESS_ACCT_V3 is not set | 41 | # CONFIG_BSD_PROCESS_ACCT_V3 is not set |
46 | # CONFIG_TASKSTATS is not set | 42 | # CONFIG_TASKSTATS is not set |
47 | # CONFIG_USER_NS is not set | 43 | # CONFIG_USER_NS is not set |
44 | # CONFIG_PID_NS is not set | ||
48 | # CONFIG_AUDIT is not set | 45 | # CONFIG_AUDIT is not set |
49 | # CONFIG_IKCONFIG is not set | 46 | # CONFIG_IKCONFIG is not set |
50 | CONFIG_LOG_BUF_SHIFT=14 | 47 | CONFIG_LOG_BUF_SHIFT=14 |
48 | # CONFIG_CGROUPS is not set | ||
49 | CONFIG_FAIR_GROUP_SCHED=y | ||
50 | CONFIG_FAIR_USER_SCHED=y | ||
51 | # CONFIG_FAIR_CGROUP_SCHED is not set | ||
51 | CONFIG_SYSFS_DEPRECATED=y | 52 | CONFIG_SYSFS_DEPRECATED=y |
52 | # CONFIG_RELAY is not set | 53 | # CONFIG_RELAY is not set |
53 | CONFIG_BLK_DEV_INITRD=y | 54 | CONFIG_BLK_DEV_INITRD=y |
@@ -69,7 +70,6 @@ CONFIG_FUTEX=y | |||
69 | CONFIG_ANON_INODES=y | 70 | CONFIG_ANON_INODES=y |
70 | CONFIG_EPOLL=y | 71 | CONFIG_EPOLL=y |
71 | CONFIG_SIGNALFD=y | 72 | CONFIG_SIGNALFD=y |
72 | CONFIG_TIMERFD=y | ||
73 | CONFIG_EVENTFD=y | 73 | CONFIG_EVENTFD=y |
74 | CONFIG_SHMEM=y | 74 | CONFIG_SHMEM=y |
75 | CONFIG_VM_EVENT_COUNTERS=y | 75 | CONFIG_VM_EVENT_COUNTERS=y |
@@ -130,6 +130,7 @@ CONFIG_ARCH_IOP32X=y | |||
130 | # CONFIG_ARCH_L7200 is not set | 130 | # CONFIG_ARCH_L7200 is not set |
131 | # CONFIG_ARCH_KS8695 is not set | 131 | # CONFIG_ARCH_KS8695 is not set |
132 | # CONFIG_ARCH_NS9XXX is not set | 132 | # CONFIG_ARCH_NS9XXX is not set |
133 | # CONFIG_ARCH_MXC is not set | ||
133 | # CONFIG_ARCH_PNX4008 is not set | 134 | # CONFIG_ARCH_PNX4008 is not set |
134 | # CONFIG_ARCH_PXA is not set | 135 | # CONFIG_ARCH_PXA is not set |
135 | # CONFIG_ARCH_RPC is not set | 136 | # CONFIG_ARCH_RPC is not set |
@@ -153,6 +154,15 @@ CONFIG_ARCH_IQ80321=y | |||
153 | CONFIG_ARCH_IQ31244=y | 154 | CONFIG_ARCH_IQ31244=y |
154 | CONFIG_MACH_N2100=y | 155 | CONFIG_MACH_N2100=y |
155 | CONFIG_IOP3XX_ATU=y | 156 | CONFIG_IOP3XX_ATU=y |
157 | # CONFIG_MACH_EM7210 is not set | ||
158 | |||
159 | # | ||
160 | # Boot options | ||
161 | # | ||
162 | |||
163 | # | ||
164 | # Power management | ||
165 | # | ||
156 | CONFIG_PLAT_IOP=y | 166 | CONFIG_PLAT_IOP=y |
157 | 167 | ||
158 | # | 168 | # |
@@ -182,11 +192,8 @@ CONFIG_XSCALE_PMU=y | |||
182 | CONFIG_PCI=y | 192 | CONFIG_PCI=y |
183 | CONFIG_PCI_SYSCALL=y | 193 | CONFIG_PCI_SYSCALL=y |
184 | # CONFIG_ARCH_SUPPORTS_MSI is not set | 194 | # CONFIG_ARCH_SUPPORTS_MSI is not set |
195 | CONFIG_PCI_LEGACY=y | ||
185 | # CONFIG_PCI_DEBUG is not set | 196 | # CONFIG_PCI_DEBUG is not set |
186 | |||
187 | # | ||
188 | # PCCARD (PCMCIA/CardBus) support | ||
189 | # | ||
190 | # CONFIG_PCCARD is not set | 197 | # CONFIG_PCCARD is not set |
191 | 198 | ||
192 | # | 199 | # |
@@ -205,6 +212,7 @@ CONFIG_FLATMEM_MANUAL=y | |||
205 | CONFIG_FLATMEM=y | 212 | CONFIG_FLATMEM=y |
206 | CONFIG_FLAT_NODE_MEM_MAP=y | 213 | CONFIG_FLAT_NODE_MEM_MAP=y |
207 | # CONFIG_SPARSEMEM_STATIC is not set | 214 | # CONFIG_SPARSEMEM_STATIC is not set |
215 | # CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set | ||
208 | CONFIG_SPLIT_PTLOCK_CPUS=4096 | 216 | CONFIG_SPLIT_PTLOCK_CPUS=4096 |
209 | # CONFIG_RESOURCES_64BIT is not set | 217 | # CONFIG_RESOURCES_64BIT is not set |
210 | CONFIG_ZONE_DMA_FLAG=1 | 218 | CONFIG_ZONE_DMA_FLAG=1 |
@@ -244,6 +252,7 @@ CONFIG_BINFMT_AOUT=y | |||
244 | # Power management options | 252 | # Power management options |
245 | # | 253 | # |
246 | # CONFIG_PM is not set | 254 | # CONFIG_PM is not set |
255 | CONFIG_SUSPEND_UP_POSSIBLE=y | ||
247 | 256 | ||
248 | # | 257 | # |
249 | # Networking | 258 | # Networking |
@@ -282,6 +291,7 @@ CONFIG_IP_PNP_BOOTP=y | |||
282 | CONFIG_INET_XFRM_MODE_TRANSPORT=y | 291 | CONFIG_INET_XFRM_MODE_TRANSPORT=y |
283 | CONFIG_INET_XFRM_MODE_TUNNEL=y | 292 | CONFIG_INET_XFRM_MODE_TUNNEL=y |
284 | CONFIG_INET_XFRM_MODE_BEET=y | 293 | CONFIG_INET_XFRM_MODE_BEET=y |
294 | # CONFIG_INET_LRO is not set | ||
285 | CONFIG_INET_DIAG=y | 295 | CONFIG_INET_DIAG=y |
286 | CONFIG_INET_TCP_DIAG=y | 296 | CONFIG_INET_TCP_DIAG=y |
287 | # CONFIG_TCP_CONG_ADVANCED is not set | 297 | # CONFIG_TCP_CONG_ADVANCED is not set |
@@ -321,10 +331,6 @@ CONFIG_IPV6=y | |||
321 | # CONFIG_LAPB is not set | 331 | # CONFIG_LAPB is not set |
322 | # CONFIG_ECONET is not set | 332 | # CONFIG_ECONET is not set |
323 | # CONFIG_WAN_ROUTER is not set | 333 | # CONFIG_WAN_ROUTER is not set |
324 | |||
325 | # | ||
326 | # QoS and/or fair queueing | ||
327 | # | ||
328 | # CONFIG_NET_SCHED is not set | 334 | # CONFIG_NET_SCHED is not set |
329 | 335 | ||
330 | # | 336 | # |
@@ -353,6 +359,7 @@ CONFIG_IPV6=y | |||
353 | # | 359 | # |
354 | # Generic Driver Options | 360 | # Generic Driver Options |
355 | # | 361 | # |
362 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
356 | CONFIG_STANDALONE=y | 363 | CONFIG_STANDALONE=y |
357 | CONFIG_PREVENT_FIRMWARE_BUILD=y | 364 | CONFIG_PREVENT_FIRMWARE_BUILD=y |
358 | # CONFIG_FW_LOADER is not set | 365 | # CONFIG_FW_LOADER is not set |
@@ -382,6 +389,7 @@ CONFIG_MTD_BLOCK=y | |||
382 | # CONFIG_INFTL is not set | 389 | # CONFIG_INFTL is not set |
383 | # CONFIG_RFD_FTL is not set | 390 | # CONFIG_RFD_FTL is not set |
384 | # CONFIG_SSFDC is not set | 391 | # CONFIG_SSFDC is not set |
392 | # CONFIG_MTD_OOPS is not set | ||
385 | 393 | ||
386 | # | 394 | # |
387 | # RAM/ROM/Flash chip drivers | 395 | # RAM/ROM/Flash chip drivers |
@@ -417,6 +425,7 @@ CONFIG_MTD_PHYSMAP_START=0x0 | |||
417 | CONFIG_MTD_PHYSMAP_LEN=0x0 | 425 | CONFIG_MTD_PHYSMAP_LEN=0x0 |
418 | CONFIG_MTD_PHYSMAP_BANKWIDTH=1 | 426 | CONFIG_MTD_PHYSMAP_BANKWIDTH=1 |
419 | # CONFIG_MTD_ARM_INTEGRATOR is not set | 427 | # CONFIG_MTD_ARM_INTEGRATOR is not set |
428 | # CONFIG_MTD_INTEL_VR_NOR is not set | ||
420 | # CONFIG_MTD_PLATRAM is not set | 429 | # CONFIG_MTD_PLATRAM is not set |
421 | 430 | ||
422 | # | 431 | # |
@@ -459,6 +468,11 @@ CONFIG_BLK_DEV_RAM_SIZE=8192 | |||
459 | CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 | 468 | CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 |
460 | # CONFIG_CDROM_PKTCDVD is not set | 469 | # CONFIG_CDROM_PKTCDVD is not set |
461 | # CONFIG_ATA_OVER_ETH is not set | 470 | # CONFIG_ATA_OVER_ETH is not set |
471 | CONFIG_MISC_DEVICES=y | ||
472 | # CONFIG_PHANTOM is not set | ||
473 | # CONFIG_EEPROM_93CX6 is not set | ||
474 | # CONFIG_SGI_IOC4 is not set | ||
475 | # CONFIG_TIFM_CORE is not set | ||
462 | # CONFIG_IDE is not set | 476 | # CONFIG_IDE is not set |
463 | 477 | ||
464 | # | 478 | # |
@@ -496,12 +510,9 @@ CONFIG_SCSI_WAIT_SCAN=m | |||
496 | # CONFIG_SCSI_SPI_ATTRS is not set | 510 | # CONFIG_SCSI_SPI_ATTRS is not set |
497 | # CONFIG_SCSI_FC_ATTRS is not set | 511 | # CONFIG_SCSI_FC_ATTRS is not set |
498 | # CONFIG_SCSI_ISCSI_ATTRS is not set | 512 | # CONFIG_SCSI_ISCSI_ATTRS is not set |
499 | # CONFIG_SCSI_SAS_ATTRS is not set | ||
500 | # CONFIG_SCSI_SAS_LIBSAS is not set | 513 | # CONFIG_SCSI_SAS_LIBSAS is not set |
501 | 514 | # CONFIG_SCSI_SRP_ATTRS is not set | |
502 | # | 515 | CONFIG_SCSI_LOWLEVEL=y |
503 | # SCSI low-level drivers | ||
504 | # | ||
505 | # CONFIG_ISCSI_TCP is not set | 516 | # CONFIG_ISCSI_TCP is not set |
506 | # CONFIG_BLK_DEV_3W_XXXX_RAID is not set | 517 | # CONFIG_BLK_DEV_3W_XXXX_RAID is not set |
507 | # CONFIG_SCSI_3W_9XXX is not set | 518 | # CONFIG_SCSI_3W_9XXX is not set |
@@ -512,6 +523,7 @@ CONFIG_SCSI_WAIT_SCAN=m | |||
512 | # CONFIG_SCSI_AIC79XX is not set | 523 | # CONFIG_SCSI_AIC79XX is not set |
513 | # CONFIG_SCSI_AIC94XX is not set | 524 | # CONFIG_SCSI_AIC94XX is not set |
514 | # CONFIG_SCSI_DPT_I2O is not set | 525 | # CONFIG_SCSI_DPT_I2O is not set |
526 | # CONFIG_SCSI_ADVANSYS is not set | ||
515 | # CONFIG_SCSI_ARCMSR is not set | 527 | # CONFIG_SCSI_ARCMSR is not set |
516 | # CONFIG_MEGARAID_NEWGEN is not set | 528 | # CONFIG_MEGARAID_NEWGEN is not set |
517 | # CONFIG_MEGARAID_LEGACY is not set | 529 | # CONFIG_MEGARAID_LEGACY is not set |
@@ -576,6 +588,7 @@ CONFIG_SATA_VITESSE=y | |||
576 | # CONFIG_PATA_OLDPIIX is not set | 588 | # CONFIG_PATA_OLDPIIX is not set |
577 | # CONFIG_PATA_NETCELL is not set | 589 | # CONFIG_PATA_NETCELL is not set |
578 | # CONFIG_PATA_NS87410 is not set | 590 | # CONFIG_PATA_NS87410 is not set |
591 | # CONFIG_PATA_NS87415 is not set | ||
579 | # CONFIG_PATA_OPTI is not set | 592 | # CONFIG_PATA_OPTI is not set |
580 | # CONFIG_PATA_OPTIDMA is not set | 593 | # CONFIG_PATA_OPTIDMA is not set |
581 | # CONFIG_PATA_PDC_OLD is not set | 594 | # CONFIG_PATA_PDC_OLD is not set |
@@ -606,14 +619,8 @@ CONFIG_BLK_DEV_DM=y | |||
606 | # CONFIG_DM_ZERO is not set | 619 | # CONFIG_DM_ZERO is not set |
607 | # CONFIG_DM_MULTIPATH is not set | 620 | # CONFIG_DM_MULTIPATH is not set |
608 | # CONFIG_DM_DELAY is not set | 621 | # CONFIG_DM_DELAY is not set |
609 | 622 | # CONFIG_DM_UEVENT is not set | |
610 | # | ||
611 | # Fusion MPT device support | ||
612 | # | ||
613 | # CONFIG_FUSION is not set | 623 | # CONFIG_FUSION is not set |
614 | # CONFIG_FUSION_SPI is not set | ||
615 | # CONFIG_FUSION_FC is not set | ||
616 | # CONFIG_FUSION_SAS is not set | ||
617 | 624 | ||
618 | # | 625 | # |
619 | # IEEE 1394 (FireWire) support | 626 | # IEEE 1394 (FireWire) support |
@@ -628,6 +635,8 @@ CONFIG_NETDEVICES=y | |||
628 | # CONFIG_MACVLAN is not set | 635 | # CONFIG_MACVLAN is not set |
629 | # CONFIG_EQUALIZER is not set | 636 | # CONFIG_EQUALIZER is not set |
630 | # CONFIG_TUN is not set | 637 | # CONFIG_TUN is not set |
638 | # CONFIG_VETH is not set | ||
639 | # CONFIG_IP1000 is not set | ||
631 | # CONFIG_ARCNET is not set | 640 | # CONFIG_ARCNET is not set |
632 | # CONFIG_PHYLIB is not set | 641 | # CONFIG_PHYLIB is not set |
633 | CONFIG_NET_ETHERNET=y | 642 | CONFIG_NET_ETHERNET=y |
@@ -641,13 +650,16 @@ CONFIG_MII=y | |||
641 | # CONFIG_DM9000 is not set | 650 | # CONFIG_DM9000 is not set |
642 | # CONFIG_NET_TULIP is not set | 651 | # CONFIG_NET_TULIP is not set |
643 | # CONFIG_HP100 is not set | 652 | # CONFIG_HP100 is not set |
653 | # CONFIG_IBM_NEW_EMAC_ZMII is not set | ||
654 | # CONFIG_IBM_NEW_EMAC_RGMII is not set | ||
655 | # CONFIG_IBM_NEW_EMAC_TAH is not set | ||
656 | # CONFIG_IBM_NEW_EMAC_EMAC4 is not set | ||
644 | CONFIG_NET_PCI=y | 657 | CONFIG_NET_PCI=y |
645 | # CONFIG_PCNET32 is not set | 658 | # CONFIG_PCNET32 is not set |
646 | # CONFIG_AMD8111_ETH is not set | 659 | # CONFIG_AMD8111_ETH is not set |
647 | # CONFIG_ADAPTEC_STARFIRE is not set | 660 | # CONFIG_ADAPTEC_STARFIRE is not set |
648 | # CONFIG_B44 is not set | 661 | # CONFIG_B44 is not set |
649 | # CONFIG_FORCEDETH is not set | 662 | # CONFIG_FORCEDETH is not set |
650 | # CONFIG_DGRS is not set | ||
651 | # CONFIG_EEPRO100 is not set | 663 | # CONFIG_EEPRO100 is not set |
652 | CONFIG_E100=y | 664 | CONFIG_E100=y |
653 | # CONFIG_FEALNX is not set | 665 | # CONFIG_FEALNX is not set |
@@ -667,6 +679,7 @@ CONFIG_NETDEV_1000=y | |||
667 | CONFIG_E1000=y | 679 | CONFIG_E1000=y |
668 | CONFIG_E1000_NAPI=y | 680 | CONFIG_E1000_NAPI=y |
669 | # CONFIG_E1000_DISABLE_PACKET_SPLIT is not set | 681 | # CONFIG_E1000_DISABLE_PACKET_SPLIT is not set |
682 | # CONFIG_E1000E is not set | ||
670 | # CONFIG_NS83820 is not set | 683 | # CONFIG_NS83820 is not set |
671 | # CONFIG_HAMACHI is not set | 684 | # CONFIG_HAMACHI is not set |
672 | # CONFIG_YELLOWFIN is not set | 685 | # CONFIG_YELLOWFIN is not set |
@@ -675,6 +688,7 @@ CONFIG_R8169=y | |||
675 | # CONFIG_SIS190 is not set | 688 | # CONFIG_SIS190 is not set |
676 | # CONFIG_SKGE is not set | 689 | # CONFIG_SKGE is not set |
677 | # CONFIG_SKY2 is not set | 690 | # CONFIG_SKY2 is not set |
691 | # CONFIG_SK98LIN is not set | ||
678 | # CONFIG_VIA_VELOCITY is not set | 692 | # CONFIG_VIA_VELOCITY is not set |
679 | # CONFIG_TIGON3 is not set | 693 | # CONFIG_TIGON3 is not set |
680 | # CONFIG_BNX2 is not set | 694 | # CONFIG_BNX2 is not set |
@@ -683,11 +697,14 @@ CONFIG_R8169=y | |||
683 | CONFIG_NETDEV_10000=y | 697 | CONFIG_NETDEV_10000=y |
684 | # CONFIG_CHELSIO_T1 is not set | 698 | # CONFIG_CHELSIO_T1 is not set |
685 | # CONFIG_CHELSIO_T3 is not set | 699 | # CONFIG_CHELSIO_T3 is not set |
700 | # CONFIG_IXGBE is not set | ||
686 | # CONFIG_IXGB is not set | 701 | # CONFIG_IXGB is not set |
687 | # CONFIG_S2IO is not set | 702 | # CONFIG_S2IO is not set |
688 | # CONFIG_MYRI10GE is not set | 703 | # CONFIG_MYRI10GE is not set |
689 | # CONFIG_NETXEN_NIC is not set | 704 | # CONFIG_NETXEN_NIC is not set |
705 | # CONFIG_NIU is not set | ||
690 | # CONFIG_MLX4_CORE is not set | 706 | # CONFIG_MLX4_CORE is not set |
707 | # CONFIG_TEHUTI is not set | ||
691 | # CONFIG_TR is not set | 708 | # CONFIG_TR is not set |
692 | 709 | ||
693 | # | 710 | # |
@@ -703,7 +720,6 @@ CONFIG_NETDEV_10000=y | |||
703 | # CONFIG_USB_KAWETH is not set | 720 | # CONFIG_USB_KAWETH is not set |
704 | # CONFIG_USB_PEGASUS is not set | 721 | # CONFIG_USB_PEGASUS is not set |
705 | # CONFIG_USB_RTL8150 is not set | 722 | # CONFIG_USB_RTL8150 is not set |
706 | # CONFIG_USB_USBNET_MII is not set | ||
707 | # CONFIG_USB_USBNET is not set | 723 | # CONFIG_USB_USBNET is not set |
708 | # CONFIG_WAN is not set | 724 | # CONFIG_WAN is not set |
709 | # CONFIG_FDDI is not set | 725 | # CONFIG_FDDI is not set |
@@ -732,7 +748,6 @@ CONFIG_INPUT_MOUSEDEV=y | |||
732 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 | 748 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 |
733 | CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | 749 | CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 |
734 | # CONFIG_INPUT_JOYDEV is not set | 750 | # CONFIG_INPUT_JOYDEV is not set |
735 | # CONFIG_INPUT_TSDEV is not set | ||
736 | # CONFIG_INPUT_EVDEV is not set | 751 | # CONFIG_INPUT_EVDEV is not set |
737 | # CONFIG_INPUT_EVBUG is not set | 752 | # CONFIG_INPUT_EVBUG is not set |
738 | 753 | ||
@@ -781,12 +796,10 @@ CONFIG_UNIX98_PTYS=y | |||
781 | CONFIG_LEGACY_PTYS=y | 796 | CONFIG_LEGACY_PTYS=y |
782 | CONFIG_LEGACY_PTY_COUNT=256 | 797 | CONFIG_LEGACY_PTY_COUNT=256 |
783 | # CONFIG_IPMI_HANDLER is not set | 798 | # CONFIG_IPMI_HANDLER is not set |
784 | # CONFIG_WATCHDOG is not set | ||
785 | CONFIG_HW_RANDOM=y | 799 | CONFIG_HW_RANDOM=y |
786 | # CONFIG_NVRAM is not set | 800 | # CONFIG_NVRAM is not set |
787 | # CONFIG_R3964 is not set | 801 | # CONFIG_R3964 is not set |
788 | # CONFIG_APPLICOM is not set | 802 | # CONFIG_APPLICOM is not set |
789 | # CONFIG_DRM is not set | ||
790 | # CONFIG_RAW_DRIVER is not set | 803 | # CONFIG_RAW_DRIVER is not set |
791 | # CONFIG_TCG_TPM is not set | 804 | # CONFIG_TCG_TPM is not set |
792 | CONFIG_DEVPORT=y | 805 | CONFIG_DEVPORT=y |
@@ -852,9 +865,9 @@ CONFIG_I2C_IOP3XX=y | |||
852 | # CONFIG_SPI is not set | 865 | # CONFIG_SPI is not set |
853 | # CONFIG_SPI_MASTER is not set | 866 | # CONFIG_SPI_MASTER is not set |
854 | # CONFIG_W1 is not set | 867 | # CONFIG_W1 is not set |
868 | # CONFIG_POWER_SUPPLY is not set | ||
855 | CONFIG_HWMON=y | 869 | CONFIG_HWMON=y |
856 | # CONFIG_HWMON_VID is not set | 870 | # CONFIG_HWMON_VID is not set |
857 | # CONFIG_SENSORS_ABITUGURU is not set | ||
858 | # CONFIG_SENSORS_AD7418 is not set | 871 | # CONFIG_SENSORS_AD7418 is not set |
859 | # CONFIG_SENSORS_ADM1021 is not set | 872 | # CONFIG_SENSORS_ADM1021 is not set |
860 | # CONFIG_SENSORS_ADM1025 is not set | 873 | # CONFIG_SENSORS_ADM1025 is not set |
@@ -862,12 +875,13 @@ CONFIG_HWMON=y | |||
862 | # CONFIG_SENSORS_ADM1029 is not set | 875 | # CONFIG_SENSORS_ADM1029 is not set |
863 | # CONFIG_SENSORS_ADM1031 is not set | 876 | # CONFIG_SENSORS_ADM1031 is not set |
864 | # CONFIG_SENSORS_ADM9240 is not set | 877 | # CONFIG_SENSORS_ADM9240 is not set |
865 | # CONFIG_SENSORS_ASB100 is not set | 878 | # CONFIG_SENSORS_ADT7470 is not set |
866 | # CONFIG_SENSORS_ATXP1 is not set | 879 | # CONFIG_SENSORS_ATXP1 is not set |
867 | # CONFIG_SENSORS_DS1621 is not set | 880 | # CONFIG_SENSORS_DS1621 is not set |
881 | # CONFIG_SENSORS_I5K_AMB is not set | ||
868 | # CONFIG_SENSORS_F71805F is not set | 882 | # CONFIG_SENSORS_F71805F is not set |
869 | # CONFIG_SENSORS_FSCHER is not set | 883 | # CONFIG_SENSORS_F71882FG is not set |
870 | # CONFIG_SENSORS_FSCPOS is not set | 884 | # CONFIG_SENSORS_F75375S is not set |
871 | # CONFIG_SENSORS_GL518SM is not set | 885 | # CONFIG_SENSORS_GL518SM is not set |
872 | # CONFIG_SENSORS_GL520SM is not set | 886 | # CONFIG_SENSORS_GL520SM is not set |
873 | # CONFIG_SENSORS_IT87 is not set | 887 | # CONFIG_SENSORS_IT87 is not set |
@@ -881,14 +895,17 @@ CONFIG_HWMON=y | |||
881 | # CONFIG_SENSORS_LM87 is not set | 895 | # CONFIG_SENSORS_LM87 is not set |
882 | # CONFIG_SENSORS_LM90 is not set | 896 | # CONFIG_SENSORS_LM90 is not set |
883 | # CONFIG_SENSORS_LM92 is not set | 897 | # CONFIG_SENSORS_LM92 is not set |
898 | # CONFIG_SENSORS_LM93 is not set | ||
884 | # CONFIG_SENSORS_MAX1619 is not set | 899 | # CONFIG_SENSORS_MAX1619 is not set |
885 | # CONFIG_SENSORS_MAX6650 is not set | 900 | # CONFIG_SENSORS_MAX6650 is not set |
886 | # CONFIG_SENSORS_PC87360 is not set | 901 | # CONFIG_SENSORS_PC87360 is not set |
887 | # CONFIG_SENSORS_PC87427 is not set | 902 | # CONFIG_SENSORS_PC87427 is not set |
888 | # CONFIG_SENSORS_SIS5595 is not set | 903 | # CONFIG_SENSORS_SIS5595 is not set |
904 | # CONFIG_SENSORS_DME1737 is not set | ||
889 | # CONFIG_SENSORS_SMSC47M1 is not set | 905 | # CONFIG_SENSORS_SMSC47M1 is not set |
890 | # CONFIG_SENSORS_SMSC47M192 is not set | 906 | # CONFIG_SENSORS_SMSC47M192 is not set |
891 | # CONFIG_SENSORS_SMSC47B397 is not set | 907 | # CONFIG_SENSORS_SMSC47B397 is not set |
908 | # CONFIG_SENSORS_THMC50 is not set | ||
892 | # CONFIG_SENSORS_VIA686A is not set | 909 | # CONFIG_SENSORS_VIA686A is not set |
893 | # CONFIG_SENSORS_VT1211 is not set | 910 | # CONFIG_SENSORS_VT1211 is not set |
894 | # CONFIG_SENSORS_VT8231 is not set | 911 | # CONFIG_SENSORS_VT8231 is not set |
@@ -900,29 +917,18 @@ CONFIG_HWMON=y | |||
900 | # CONFIG_SENSORS_W83627HF is not set | 917 | # CONFIG_SENSORS_W83627HF is not set |
901 | # CONFIG_SENSORS_W83627EHF is not set | 918 | # CONFIG_SENSORS_W83627EHF is not set |
902 | # CONFIG_HWMON_DEBUG_CHIP is not set | 919 | # CONFIG_HWMON_DEBUG_CHIP is not set |
903 | CONFIG_MISC_DEVICES=y | 920 | # CONFIG_WATCHDOG is not set |
904 | # CONFIG_PHANTOM is not set | ||
905 | # CONFIG_EEPROM_93CX6 is not set | ||
906 | # CONFIG_SGI_IOC4 is not set | ||
907 | # CONFIG_TIFM_CORE is not set | ||
908 | |||
909 | # | ||
910 | # Multifunction device drivers | ||
911 | # | ||
912 | # CONFIG_MFD_SM501 is not set | ||
913 | |||
914 | # | ||
915 | # LED devices | ||
916 | # | ||
917 | # CONFIG_NEW_LEDS is not set | ||
918 | 921 | ||
919 | # | 922 | # |
920 | # LED drivers | 923 | # Sonics Silicon Backplane |
921 | # | 924 | # |
925 | CONFIG_SSB_POSSIBLE=y | ||
926 | # CONFIG_SSB is not set | ||
922 | 927 | ||
923 | # | 928 | # |
924 | # LED Triggers | 929 | # Multifunction device drivers |
925 | # | 930 | # |
931 | # CONFIG_MFD_SM501 is not set | ||
926 | 932 | ||
927 | # | 933 | # |
928 | # Multimedia devices | 934 | # Multimedia devices |
@@ -935,14 +941,16 @@ CONFIG_DAB=y | |||
935 | # | 941 | # |
936 | # Graphics support | 942 | # Graphics support |
937 | # | 943 | # |
944 | # CONFIG_DRM is not set | ||
945 | # CONFIG_VGASTATE is not set | ||
946 | # CONFIG_VIDEO_OUTPUT_CONTROL is not set | ||
947 | # CONFIG_FB is not set | ||
938 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set | 948 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set |
939 | 949 | ||
940 | # | 950 | # |
941 | # Display device support | 951 | # Display device support |
942 | # | 952 | # |
943 | # CONFIG_DISPLAY_SUPPORT is not set | 953 | # CONFIG_DISPLAY_SUPPORT is not set |
944 | # CONFIG_VGASTATE is not set | ||
945 | # CONFIG_FB is not set | ||
946 | 954 | ||
947 | # | 955 | # |
948 | # Console display driver support | 956 | # Console display driver support |
@@ -957,6 +965,7 @@ CONFIG_DUMMY_CONSOLE=y | |||
957 | CONFIG_HID_SUPPORT=y | 965 | CONFIG_HID_SUPPORT=y |
958 | CONFIG_HID=y | 966 | CONFIG_HID=y |
959 | # CONFIG_HID_DEBUG is not set | 967 | # CONFIG_HID_DEBUG is not set |
968 | # CONFIG_HIDRAW is not set | ||
960 | 969 | ||
961 | # | 970 | # |
962 | # USB Input Devices | 971 | # USB Input Devices |
@@ -1013,6 +1022,7 @@ CONFIG_USB_STORAGE=y | |||
1013 | # CONFIG_USB_STORAGE_DEBUG is not set | 1022 | # CONFIG_USB_STORAGE_DEBUG is not set |
1014 | # CONFIG_USB_STORAGE_DATAFAB is not set | 1023 | # CONFIG_USB_STORAGE_DATAFAB is not set |
1015 | # CONFIG_USB_STORAGE_FREECOM is not set | 1024 | # CONFIG_USB_STORAGE_FREECOM is not set |
1025 | # CONFIG_USB_STORAGE_ISD200 is not set | ||
1016 | # CONFIG_USB_STORAGE_DPCM is not set | 1026 | # CONFIG_USB_STORAGE_DPCM is not set |
1017 | # CONFIG_USB_STORAGE_USBAT is not set | 1027 | # CONFIG_USB_STORAGE_USBAT is not set |
1018 | # CONFIG_USB_STORAGE_SDDR09 is not set | 1028 | # CONFIG_USB_STORAGE_SDDR09 is not set |
@@ -1070,28 +1080,66 @@ CONFIG_USB_MON=y | |||
1070 | # | 1080 | # |
1071 | # CONFIG_USB_GADGET is not set | 1081 | # CONFIG_USB_GADGET is not set |
1072 | # CONFIG_MMC is not set | 1082 | # CONFIG_MMC is not set |
1083 | # CONFIG_NEW_LEDS is not set | ||
1084 | CONFIG_RTC_LIB=y | ||
1085 | CONFIG_RTC_CLASS=y | ||
1086 | CONFIG_RTC_HCTOSYS=y | ||
1087 | CONFIG_RTC_HCTOSYS_DEVICE="rtc0" | ||
1088 | # CONFIG_RTC_DEBUG is not set | ||
1073 | 1089 | ||
1074 | # | 1090 | # |
1075 | # Real Time Clock | 1091 | # RTC interfaces |
1076 | # | 1092 | # |
1077 | CONFIG_RTC_LIB=y | 1093 | CONFIG_RTC_INTF_SYSFS=y |
1078 | # CONFIG_RTC_CLASS is not set | 1094 | CONFIG_RTC_INTF_PROC=y |
1095 | CONFIG_RTC_INTF_DEV=y | ||
1096 | # CONFIG_RTC_INTF_DEV_UIE_EMUL is not set | ||
1097 | # CONFIG_RTC_DRV_TEST is not set | ||
1079 | 1098 | ||
1080 | # | 1099 | # |
1081 | # DMA Engine support | 1100 | # I2C RTC drivers |
1082 | # | 1101 | # |
1083 | CONFIG_DMA_ENGINE=y | 1102 | # CONFIG_RTC_DRV_DS1307 is not set |
1103 | # CONFIG_RTC_DRV_DS1374 is not set | ||
1104 | # CONFIG_RTC_DRV_DS1672 is not set | ||
1105 | # CONFIG_RTC_DRV_MAX6900 is not set | ||
1106 | CONFIG_RTC_DRV_RS5C372=y | ||
1107 | # CONFIG_RTC_DRV_ISL1208 is not set | ||
1108 | # CONFIG_RTC_DRV_X1205 is not set | ||
1109 | # CONFIG_RTC_DRV_PCF8563 is not set | ||
1110 | # CONFIG_RTC_DRV_PCF8583 is not set | ||
1111 | # CONFIG_RTC_DRV_M41T80 is not set | ||
1084 | 1112 | ||
1085 | # | 1113 | # |
1086 | # DMA Clients | 1114 | # SPI RTC drivers |
1087 | # | 1115 | # |
1088 | CONFIG_NET_DMA=y | 1116 | |
1117 | # | ||
1118 | # Platform RTC drivers | ||
1119 | # | ||
1120 | # CONFIG_RTC_DRV_CMOS is not set | ||
1121 | # CONFIG_RTC_DRV_DS1553 is not set | ||
1122 | # CONFIG_RTC_DRV_STK17TA8 is not set | ||
1123 | # CONFIG_RTC_DRV_DS1742 is not set | ||
1124 | # CONFIG_RTC_DRV_M48T86 is not set | ||
1125 | # CONFIG_RTC_DRV_M48T59 is not set | ||
1126 | # CONFIG_RTC_DRV_V3020 is not set | ||
1127 | |||
1128 | # | ||
1129 | # on-CPU RTC drivers | ||
1130 | # | ||
1131 | CONFIG_DMADEVICES=y | ||
1089 | 1132 | ||
1090 | # | 1133 | # |
1091 | # DMA Devices | 1134 | # DMA Devices |
1092 | # | 1135 | # |
1093 | # CONFIG_INTEL_IOATDMA is not set | ||
1094 | CONFIG_INTEL_IOP_ADMA=y | 1136 | CONFIG_INTEL_IOP_ADMA=y |
1137 | CONFIG_DMA_ENGINE=y | ||
1138 | |||
1139 | # | ||
1140 | # DMA Clients | ||
1141 | # | ||
1142 | CONFIG_NET_DMA=y | ||
1095 | 1143 | ||
1096 | # | 1144 | # |
1097 | # File systems | 1145 | # File systems |
@@ -1105,7 +1153,6 @@ CONFIG_EXT3_FS_XATTR=y | |||
1105 | # CONFIG_EXT3_FS_SECURITY is not set | 1153 | # CONFIG_EXT3_FS_SECURITY is not set |
1106 | # CONFIG_EXT4DEV_FS is not set | 1154 | # CONFIG_EXT4DEV_FS is not set |
1107 | CONFIG_JBD=y | 1155 | CONFIG_JBD=y |
1108 | # CONFIG_JBD_DEBUG is not set | ||
1109 | CONFIG_FS_MBCACHE=y | 1156 | CONFIG_FS_MBCACHE=y |
1110 | # CONFIG_REISERFS_FS is not set | 1157 | # CONFIG_REISERFS_FS is not set |
1111 | # CONFIG_JFS_FS is not set | 1158 | # CONFIG_JFS_FS is not set |
@@ -1145,7 +1192,6 @@ CONFIG_SYSFS=y | |||
1145 | CONFIG_TMPFS=y | 1192 | CONFIG_TMPFS=y |
1146 | # CONFIG_TMPFS_POSIX_ACL is not set | 1193 | # CONFIG_TMPFS_POSIX_ACL is not set |
1147 | # CONFIG_HUGETLB_PAGE is not set | 1194 | # CONFIG_HUGETLB_PAGE is not set |
1148 | CONFIG_RAMFS=y | ||
1149 | # CONFIG_CONFIGFS_FS is not set | 1195 | # CONFIG_CONFIGFS_FS is not set |
1150 | 1196 | ||
1151 | # | 1197 | # |
@@ -1162,10 +1208,12 @@ CONFIG_ECRYPT_FS=y | |||
1162 | CONFIG_JFFS2_FS=y | 1208 | CONFIG_JFFS2_FS=y |
1163 | CONFIG_JFFS2_FS_DEBUG=0 | 1209 | CONFIG_JFFS2_FS_DEBUG=0 |
1164 | CONFIG_JFFS2_FS_WRITEBUFFER=y | 1210 | CONFIG_JFFS2_FS_WRITEBUFFER=y |
1211 | # CONFIG_JFFS2_FS_WBUF_VERIFY is not set | ||
1165 | # CONFIG_JFFS2_SUMMARY is not set | 1212 | # CONFIG_JFFS2_SUMMARY is not set |
1166 | # CONFIG_JFFS2_FS_XATTR is not set | 1213 | # CONFIG_JFFS2_FS_XATTR is not set |
1167 | # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set | 1214 | # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set |
1168 | CONFIG_JFFS2_ZLIB=y | 1215 | CONFIG_JFFS2_ZLIB=y |
1216 | # CONFIG_JFFS2_LZO is not set | ||
1169 | CONFIG_JFFS2_RTIME=y | 1217 | CONFIG_JFFS2_RTIME=y |
1170 | # CONFIG_JFFS2_RUBIN is not set | 1218 | # CONFIG_JFFS2_RUBIN is not set |
1171 | CONFIG_CRAMFS=y | 1219 | CONFIG_CRAMFS=y |
@@ -1174,10 +1222,7 @@ CONFIG_CRAMFS=y | |||
1174 | # CONFIG_QNX4FS_FS is not set | 1222 | # CONFIG_QNX4FS_FS is not set |
1175 | # CONFIG_SYSV_FS is not set | 1223 | # CONFIG_SYSV_FS is not set |
1176 | # CONFIG_UFS_FS is not set | 1224 | # CONFIG_UFS_FS is not set |
1177 | 1225 | CONFIG_NETWORK_FILESYSTEMS=y | |
1178 | # | ||
1179 | # Network File Systems | ||
1180 | # | ||
1181 | CONFIG_NFS_FS=y | 1226 | CONFIG_NFS_FS=y |
1182 | CONFIG_NFS_V3=y | 1227 | CONFIG_NFS_V3=y |
1183 | # CONFIG_NFS_V3_ACL is not set | 1228 | # CONFIG_NFS_V3_ACL is not set |
@@ -1224,26 +1269,17 @@ CONFIG_MSDOS_PARTITION=y | |||
1224 | # CONFIG_KARMA_PARTITION is not set | 1269 | # CONFIG_KARMA_PARTITION is not set |
1225 | # CONFIG_EFI_PARTITION is not set | 1270 | # CONFIG_EFI_PARTITION is not set |
1226 | # CONFIG_SYSV68_PARTITION is not set | 1271 | # CONFIG_SYSV68_PARTITION is not set |
1227 | |||
1228 | # | ||
1229 | # Native Language Support | ||
1230 | # | ||
1231 | # CONFIG_NLS is not set | 1272 | # CONFIG_NLS is not set |
1232 | |||
1233 | # | ||
1234 | # Distributed Lock Manager | ||
1235 | # | ||
1236 | # CONFIG_DLM is not set | 1273 | # CONFIG_DLM is not set |
1237 | 1274 | CONFIG_INSTRUMENTATION=y | |
1238 | # | ||
1239 | # Profiling support | ||
1240 | # | ||
1241 | # CONFIG_PROFILING is not set | 1275 | # CONFIG_PROFILING is not set |
1276 | # CONFIG_MARKERS is not set | ||
1242 | 1277 | ||
1243 | # | 1278 | # |
1244 | # Kernel hacking | 1279 | # Kernel hacking |
1245 | # | 1280 | # |
1246 | # CONFIG_PRINTK_TIME is not set | 1281 | # CONFIG_PRINTK_TIME is not set |
1282 | CONFIG_ENABLE_WARN_DEPRECATED=y | ||
1247 | CONFIG_ENABLE_MUST_CHECK=y | 1283 | CONFIG_ENABLE_MUST_CHECK=y |
1248 | CONFIG_MAGIC_SYSRQ=y | 1284 | CONFIG_MAGIC_SYSRQ=y |
1249 | # CONFIG_UNUSED_SYMBOLS is not set | 1285 | # CONFIG_UNUSED_SYMBOLS is not set |
@@ -1270,10 +1306,13 @@ CONFIG_DEBUG_BUGVERBOSE=y | |||
1270 | # CONFIG_DEBUG_INFO is not set | 1306 | # CONFIG_DEBUG_INFO is not set |
1271 | # CONFIG_DEBUG_VM is not set | 1307 | # CONFIG_DEBUG_VM is not set |
1272 | # CONFIG_DEBUG_LIST is not set | 1308 | # CONFIG_DEBUG_LIST is not set |
1309 | # CONFIG_DEBUG_SG is not set | ||
1273 | CONFIG_FRAME_POINTER=y | 1310 | CONFIG_FRAME_POINTER=y |
1274 | # CONFIG_FORCED_INLINING is not set | 1311 | # CONFIG_FORCED_INLINING is not set |
1312 | # CONFIG_BOOT_PRINTK_DELAY is not set | ||
1275 | # CONFIG_RCU_TORTURE_TEST is not set | 1313 | # CONFIG_RCU_TORTURE_TEST is not set |
1276 | # CONFIG_FAULT_INJECTION is not set | 1314 | # CONFIG_FAULT_INJECTION is not set |
1315 | # CONFIG_SAMPLES is not set | ||
1277 | CONFIG_DEBUG_USER=y | 1316 | CONFIG_DEBUG_USER=y |
1278 | # CONFIG_DEBUG_ERRORS is not set | 1317 | # CONFIG_DEBUG_ERRORS is not set |
1279 | CONFIG_DEBUG_LL=y | 1318 | CONFIG_DEBUG_LL=y |
@@ -1285,6 +1324,7 @@ CONFIG_DEBUG_LL=y | |||
1285 | CONFIG_KEYS=y | 1324 | CONFIG_KEYS=y |
1286 | CONFIG_KEYS_DEBUG_PROC_KEYS=y | 1325 | CONFIG_KEYS_DEBUG_PROC_KEYS=y |
1287 | # CONFIG_SECURITY is not set | 1326 | # CONFIG_SECURITY is not set |
1327 | # CONFIG_SECURITY_FILE_CAPABILITIES is not set | ||
1288 | CONFIG_XOR_BLOCKS=y | 1328 | CONFIG_XOR_BLOCKS=y |
1289 | CONFIG_ASYNC_CORE=y | 1329 | CONFIG_ASYNC_CORE=y |
1290 | CONFIG_ASYNC_MEMCPY=y | 1330 | CONFIG_ASYNC_MEMCPY=y |
@@ -1309,6 +1349,7 @@ CONFIG_CRYPTO_ECB=y | |||
1309 | CONFIG_CRYPTO_CBC=y | 1349 | CONFIG_CRYPTO_CBC=y |
1310 | CONFIG_CRYPTO_PCBC=m | 1350 | CONFIG_CRYPTO_PCBC=m |
1311 | CONFIG_CRYPTO_LRW=y | 1351 | CONFIG_CRYPTO_LRW=y |
1352 | # CONFIG_CRYPTO_XTS is not set | ||
1312 | # CONFIG_CRYPTO_CRYPTD is not set | 1353 | # CONFIG_CRYPTO_CRYPTD is not set |
1313 | CONFIG_CRYPTO_DES=y | 1354 | CONFIG_CRYPTO_DES=y |
1314 | # CONFIG_CRYPTO_FCRYPT is not set | 1355 | # CONFIG_CRYPTO_FCRYPT is not set |
@@ -1323,11 +1364,13 @@ CONFIG_CRYPTO_TEA=y | |||
1323 | CONFIG_CRYPTO_ARC4=y | 1364 | CONFIG_CRYPTO_ARC4=y |
1324 | CONFIG_CRYPTO_KHAZAD=y | 1365 | CONFIG_CRYPTO_KHAZAD=y |
1325 | CONFIG_CRYPTO_ANUBIS=y | 1366 | CONFIG_CRYPTO_ANUBIS=y |
1367 | # CONFIG_CRYPTO_SEED is not set | ||
1326 | CONFIG_CRYPTO_DEFLATE=y | 1368 | CONFIG_CRYPTO_DEFLATE=y |
1327 | CONFIG_CRYPTO_MICHAEL_MIC=y | 1369 | CONFIG_CRYPTO_MICHAEL_MIC=y |
1328 | CONFIG_CRYPTO_CRC32C=y | 1370 | CONFIG_CRYPTO_CRC32C=y |
1329 | # CONFIG_CRYPTO_CAMELLIA is not set | 1371 | # CONFIG_CRYPTO_CAMELLIA is not set |
1330 | # CONFIG_CRYPTO_TEST is not set | 1372 | # CONFIG_CRYPTO_TEST is not set |
1373 | # CONFIG_CRYPTO_AUTHENC is not set | ||
1331 | CONFIG_CRYPTO_HW=y | 1374 | CONFIG_CRYPTO_HW=y |
1332 | 1375 | ||
1333 | # | 1376 | # |
diff --git a/arch/arm/configs/iop33x_defconfig b/arch/arm/configs/iop33x_defconfig index 721ee64a13f7..917afb5ccfac 100644 --- a/arch/arm/configs/iop33x_defconfig +++ b/arch/arm/configs/iop33x_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.22 | 3 | # Linux kernel version: 2.6.24-rc5 |
4 | # Thu Jul 19 16:05:59 2007 | 4 | # Wed Dec 12 16:11:27 2007 |
5 | # | 5 | # |
6 | CONFIG_ARM=y | 6 | CONFIG_ARM=y |
7 | CONFIG_SYS_SUPPORTS_APM_EMULATION=y | 7 | CONFIG_SYS_SUPPORTS_APM_EMULATION=y |
@@ -26,15 +26,11 @@ CONFIG_VECTORS_BASE=0xffff0000 | |||
26 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | 26 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" |
27 | 27 | ||
28 | # | 28 | # |
29 | # Code maturity level options | 29 | # General setup |
30 | # | 30 | # |
31 | CONFIG_EXPERIMENTAL=y | 31 | CONFIG_EXPERIMENTAL=y |
32 | CONFIG_BROKEN_ON_SMP=y | 32 | CONFIG_BROKEN_ON_SMP=y |
33 | CONFIG_INIT_ENV_ARG_LIMIT=32 | 33 | CONFIG_INIT_ENV_ARG_LIMIT=32 |
34 | |||
35 | # | ||
36 | # General setup | ||
37 | # | ||
38 | CONFIG_LOCALVERSION="" | 34 | CONFIG_LOCALVERSION="" |
39 | CONFIG_LOCALVERSION_AUTO=y | 35 | CONFIG_LOCALVERSION_AUTO=y |
40 | CONFIG_SWAP=y | 36 | CONFIG_SWAP=y |
@@ -45,9 +41,14 @@ CONFIG_BSD_PROCESS_ACCT=y | |||
45 | # CONFIG_BSD_PROCESS_ACCT_V3 is not set | 41 | # CONFIG_BSD_PROCESS_ACCT_V3 is not set |
46 | # CONFIG_TASKSTATS is not set | 42 | # CONFIG_TASKSTATS is not set |
47 | # CONFIG_USER_NS is not set | 43 | # CONFIG_USER_NS is not set |
44 | # CONFIG_PID_NS is not set | ||
48 | # CONFIG_AUDIT is not set | 45 | # CONFIG_AUDIT is not set |
49 | # CONFIG_IKCONFIG is not set | 46 | # CONFIG_IKCONFIG is not set |
50 | CONFIG_LOG_BUF_SHIFT=14 | 47 | CONFIG_LOG_BUF_SHIFT=14 |
48 | # CONFIG_CGROUPS is not set | ||
49 | CONFIG_FAIR_GROUP_SCHED=y | ||
50 | CONFIG_FAIR_USER_SCHED=y | ||
51 | # CONFIG_FAIR_CGROUP_SCHED is not set | ||
51 | CONFIG_SYSFS_DEPRECATED=y | 52 | CONFIG_SYSFS_DEPRECATED=y |
52 | # CONFIG_RELAY is not set | 53 | # CONFIG_RELAY is not set |
53 | CONFIG_BLK_DEV_INITRD=y | 54 | CONFIG_BLK_DEV_INITRD=y |
@@ -69,7 +70,6 @@ CONFIG_FUTEX=y | |||
69 | CONFIG_ANON_INODES=y | 70 | CONFIG_ANON_INODES=y |
70 | CONFIG_EPOLL=y | 71 | CONFIG_EPOLL=y |
71 | CONFIG_SIGNALFD=y | 72 | CONFIG_SIGNALFD=y |
72 | CONFIG_TIMERFD=y | ||
73 | CONFIG_EVENTFD=y | 73 | CONFIG_EVENTFD=y |
74 | CONFIG_SHMEM=y | 74 | CONFIG_SHMEM=y |
75 | CONFIG_VM_EVENT_COUNTERS=y | 75 | CONFIG_VM_EVENT_COUNTERS=y |
@@ -130,6 +130,7 @@ CONFIG_ARCH_IOP33X=y | |||
130 | # CONFIG_ARCH_L7200 is not set | 130 | # CONFIG_ARCH_L7200 is not set |
131 | # CONFIG_ARCH_KS8695 is not set | 131 | # CONFIG_ARCH_KS8695 is not set |
132 | # CONFIG_ARCH_NS9XXX is not set | 132 | # CONFIG_ARCH_NS9XXX is not set |
133 | # CONFIG_ARCH_MXC is not set | ||
133 | # CONFIG_ARCH_PNX4008 is not set | 134 | # CONFIG_ARCH_PNX4008 is not set |
134 | # CONFIG_ARCH_PXA is not set | 135 | # CONFIG_ARCH_PXA is not set |
135 | # CONFIG_ARCH_RPC is not set | 136 | # CONFIG_ARCH_RPC is not set |
@@ -150,6 +151,14 @@ CONFIG_IOP3XX_ATU=y | |||
150 | # | 151 | # |
151 | CONFIG_ARCH_IQ80331=y | 152 | CONFIG_ARCH_IQ80331=y |
152 | CONFIG_MACH_IQ80332=y | 153 | CONFIG_MACH_IQ80332=y |
154 | |||
155 | # | ||
156 | # Boot options | ||
157 | # | ||
158 | |||
159 | # | ||
160 | # Power management | ||
161 | # | ||
153 | CONFIG_PLAT_IOP=y | 162 | CONFIG_PLAT_IOP=y |
154 | 163 | ||
155 | # | 164 | # |
@@ -179,11 +188,8 @@ CONFIG_XSCALE_PMU=y | |||
179 | CONFIG_PCI=y | 188 | CONFIG_PCI=y |
180 | CONFIG_PCI_SYSCALL=y | 189 | CONFIG_PCI_SYSCALL=y |
181 | # CONFIG_ARCH_SUPPORTS_MSI is not set | 190 | # CONFIG_ARCH_SUPPORTS_MSI is not set |
191 | CONFIG_PCI_LEGACY=y | ||
182 | # CONFIG_PCI_DEBUG is not set | 192 | # CONFIG_PCI_DEBUG is not set |
183 | |||
184 | # | ||
185 | # PCCARD (PCMCIA/CardBus) support | ||
186 | # | ||
187 | # CONFIG_PCCARD is not set | 193 | # CONFIG_PCCARD is not set |
188 | 194 | ||
189 | # | 195 | # |
@@ -202,6 +208,7 @@ CONFIG_FLATMEM_MANUAL=y | |||
202 | CONFIG_FLATMEM=y | 208 | CONFIG_FLATMEM=y |
203 | CONFIG_FLAT_NODE_MEM_MAP=y | 209 | CONFIG_FLAT_NODE_MEM_MAP=y |
204 | # CONFIG_SPARSEMEM_STATIC is not set | 210 | # CONFIG_SPARSEMEM_STATIC is not set |
211 | # CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set | ||
205 | CONFIG_SPLIT_PTLOCK_CPUS=4096 | 212 | CONFIG_SPLIT_PTLOCK_CPUS=4096 |
206 | # CONFIG_RESOURCES_64BIT is not set | 213 | # CONFIG_RESOURCES_64BIT is not set |
207 | CONFIG_ZONE_DMA_FLAG=1 | 214 | CONFIG_ZONE_DMA_FLAG=1 |
@@ -241,6 +248,7 @@ CONFIG_BINFMT_AOUT=y | |||
241 | # Power management options | 248 | # Power management options |
242 | # | 249 | # |
243 | # CONFIG_PM is not set | 250 | # CONFIG_PM is not set |
251 | CONFIG_SUSPEND_UP_POSSIBLE=y | ||
244 | 252 | ||
245 | # | 253 | # |
246 | # Networking | 254 | # Networking |
@@ -279,6 +287,7 @@ CONFIG_IP_PNP_BOOTP=y | |||
279 | CONFIG_INET_XFRM_MODE_TRANSPORT=y | 287 | CONFIG_INET_XFRM_MODE_TRANSPORT=y |
280 | CONFIG_INET_XFRM_MODE_TUNNEL=y | 288 | CONFIG_INET_XFRM_MODE_TUNNEL=y |
281 | CONFIG_INET_XFRM_MODE_BEET=y | 289 | CONFIG_INET_XFRM_MODE_BEET=y |
290 | # CONFIG_INET_LRO is not set | ||
282 | CONFIG_INET_DIAG=y | 291 | CONFIG_INET_DIAG=y |
283 | CONFIG_INET_TCP_DIAG=y | 292 | CONFIG_INET_TCP_DIAG=y |
284 | # CONFIG_TCP_CONG_ADVANCED is not set | 293 | # CONFIG_TCP_CONG_ADVANCED is not set |
@@ -318,10 +327,6 @@ CONFIG_IPV6=y | |||
318 | # CONFIG_LAPB is not set | 327 | # CONFIG_LAPB is not set |
319 | # CONFIG_ECONET is not set | 328 | # CONFIG_ECONET is not set |
320 | # CONFIG_WAN_ROUTER is not set | 329 | # CONFIG_WAN_ROUTER is not set |
321 | |||
322 | # | ||
323 | # QoS and/or fair queueing | ||
324 | # | ||
325 | # CONFIG_NET_SCHED is not set | 330 | # CONFIG_NET_SCHED is not set |
326 | 331 | ||
327 | # | 332 | # |
@@ -350,6 +355,7 @@ CONFIG_IPV6=y | |||
350 | # | 355 | # |
351 | # Generic Driver Options | 356 | # Generic Driver Options |
352 | # | 357 | # |
358 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
353 | CONFIG_STANDALONE=y | 359 | CONFIG_STANDALONE=y |
354 | CONFIG_PREVENT_FIRMWARE_BUILD=y | 360 | CONFIG_PREVENT_FIRMWARE_BUILD=y |
355 | # CONFIG_FW_LOADER is not set | 361 | # CONFIG_FW_LOADER is not set |
@@ -379,6 +385,7 @@ CONFIG_MTD_BLOCK=y | |||
379 | # CONFIG_INFTL is not set | 385 | # CONFIG_INFTL is not set |
380 | # CONFIG_RFD_FTL is not set | 386 | # CONFIG_RFD_FTL is not set |
381 | # CONFIG_SSFDC is not set | 387 | # CONFIG_SSFDC is not set |
388 | # CONFIG_MTD_OOPS is not set | ||
382 | 389 | ||
383 | # | 390 | # |
384 | # RAM/ROM/Flash chip drivers | 391 | # RAM/ROM/Flash chip drivers |
@@ -419,6 +426,7 @@ CONFIG_MTD_PHYSMAP_START=0x0 | |||
419 | CONFIG_MTD_PHYSMAP_LEN=0x0 | 426 | CONFIG_MTD_PHYSMAP_LEN=0x0 |
420 | CONFIG_MTD_PHYSMAP_BANKWIDTH=1 | 427 | CONFIG_MTD_PHYSMAP_BANKWIDTH=1 |
421 | # CONFIG_MTD_ARM_INTEGRATOR is not set | 428 | # CONFIG_MTD_ARM_INTEGRATOR is not set |
429 | # CONFIG_MTD_INTEL_VR_NOR is not set | ||
422 | # CONFIG_MTD_PLATRAM is not set | 430 | # CONFIG_MTD_PLATRAM is not set |
423 | 431 | ||
424 | # | 432 | # |
@@ -459,6 +467,11 @@ CONFIG_BLK_DEV_RAM_SIZE=8192 | |||
459 | CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 | 467 | CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 |
460 | # CONFIG_CDROM_PKTCDVD is not set | 468 | # CONFIG_CDROM_PKTCDVD is not set |
461 | # CONFIG_ATA_OVER_ETH is not set | 469 | # CONFIG_ATA_OVER_ETH is not set |
470 | CONFIG_MISC_DEVICES=y | ||
471 | # CONFIG_PHANTOM is not set | ||
472 | # CONFIG_EEPROM_93CX6 is not set | ||
473 | # CONFIG_SGI_IOC4 is not set | ||
474 | # CONFIG_TIFM_CORE is not set | ||
462 | # CONFIG_IDE is not set | 475 | # CONFIG_IDE is not set |
463 | 476 | ||
464 | # | 477 | # |
@@ -496,12 +509,9 @@ CONFIG_SCSI_WAIT_SCAN=m | |||
496 | # CONFIG_SCSI_SPI_ATTRS is not set | 509 | # CONFIG_SCSI_SPI_ATTRS is not set |
497 | # CONFIG_SCSI_FC_ATTRS is not set | 510 | # CONFIG_SCSI_FC_ATTRS is not set |
498 | # CONFIG_SCSI_ISCSI_ATTRS is not set | 511 | # CONFIG_SCSI_ISCSI_ATTRS is not set |
499 | # CONFIG_SCSI_SAS_ATTRS is not set | ||
500 | # CONFIG_SCSI_SAS_LIBSAS is not set | 512 | # CONFIG_SCSI_SAS_LIBSAS is not set |
501 | 513 | # CONFIG_SCSI_SRP_ATTRS is not set | |
502 | # | 514 | CONFIG_SCSI_LOWLEVEL=y |
503 | # SCSI low-level drivers | ||
504 | # | ||
505 | # CONFIG_ISCSI_TCP is not set | 515 | # CONFIG_ISCSI_TCP is not set |
506 | # CONFIG_BLK_DEV_3W_XXXX_RAID is not set | 516 | # CONFIG_BLK_DEV_3W_XXXX_RAID is not set |
507 | # CONFIG_SCSI_3W_9XXX is not set | 517 | # CONFIG_SCSI_3W_9XXX is not set |
@@ -512,6 +522,7 @@ CONFIG_SCSI_WAIT_SCAN=m | |||
512 | # CONFIG_SCSI_AIC79XX is not set | 522 | # CONFIG_SCSI_AIC79XX is not set |
513 | # CONFIG_SCSI_AIC94XX is not set | 523 | # CONFIG_SCSI_AIC94XX is not set |
514 | # CONFIG_SCSI_DPT_I2O is not set | 524 | # CONFIG_SCSI_DPT_I2O is not set |
525 | # CONFIG_SCSI_ADVANSYS is not set | ||
515 | # CONFIG_SCSI_ARCMSR is not set | 526 | # CONFIG_SCSI_ARCMSR is not set |
516 | # CONFIG_MEGARAID_NEWGEN is not set | 527 | # CONFIG_MEGARAID_NEWGEN is not set |
517 | # CONFIG_MEGARAID_LEGACY is not set | 528 | # CONFIG_MEGARAID_LEGACY is not set |
@@ -552,14 +563,8 @@ CONFIG_BLK_DEV_DM=y | |||
552 | # CONFIG_DM_ZERO is not set | 563 | # CONFIG_DM_ZERO is not set |
553 | # CONFIG_DM_MULTIPATH is not set | 564 | # CONFIG_DM_MULTIPATH is not set |
554 | # CONFIG_DM_DELAY is not set | 565 | # CONFIG_DM_DELAY is not set |
555 | 566 | # CONFIG_DM_UEVENT is not set | |
556 | # | ||
557 | # Fusion MPT device support | ||
558 | # | ||
559 | # CONFIG_FUSION is not set | 567 | # CONFIG_FUSION is not set |
560 | # CONFIG_FUSION_SPI is not set | ||
561 | # CONFIG_FUSION_FC is not set | ||
562 | # CONFIG_FUSION_SAS is not set | ||
563 | 568 | ||
564 | # | 569 | # |
565 | # IEEE 1394 (FireWire) support | 570 | # IEEE 1394 (FireWire) support |
@@ -574,6 +579,8 @@ CONFIG_NETDEVICES=y | |||
574 | # CONFIG_MACVLAN is not set | 579 | # CONFIG_MACVLAN is not set |
575 | # CONFIG_EQUALIZER is not set | 580 | # CONFIG_EQUALIZER is not set |
576 | # CONFIG_TUN is not set | 581 | # CONFIG_TUN is not set |
582 | # CONFIG_VETH is not set | ||
583 | # CONFIG_IP1000 is not set | ||
577 | # CONFIG_ARCNET is not set | 584 | # CONFIG_ARCNET is not set |
578 | # CONFIG_NET_ETHERNET is not set | 585 | # CONFIG_NET_ETHERNET is not set |
579 | CONFIG_NETDEV_1000=y | 586 | CONFIG_NETDEV_1000=y |
@@ -582,6 +589,7 @@ CONFIG_NETDEV_1000=y | |||
582 | CONFIG_E1000=y | 589 | CONFIG_E1000=y |
583 | CONFIG_E1000_NAPI=y | 590 | CONFIG_E1000_NAPI=y |
584 | # CONFIG_E1000_DISABLE_PACKET_SPLIT is not set | 591 | # CONFIG_E1000_DISABLE_PACKET_SPLIT is not set |
592 | # CONFIG_E1000E is not set | ||
585 | # CONFIG_NS83820 is not set | 593 | # CONFIG_NS83820 is not set |
586 | # CONFIG_HAMACHI is not set | 594 | # CONFIG_HAMACHI is not set |
587 | # CONFIG_YELLOWFIN is not set | 595 | # CONFIG_YELLOWFIN is not set |
@@ -589,6 +597,7 @@ CONFIG_E1000_NAPI=y | |||
589 | # CONFIG_SIS190 is not set | 597 | # CONFIG_SIS190 is not set |
590 | # CONFIG_SKGE is not set | 598 | # CONFIG_SKGE is not set |
591 | # CONFIG_SKY2 is not set | 599 | # CONFIG_SKY2 is not set |
600 | # CONFIG_SK98LIN is not set | ||
592 | # CONFIG_VIA_VELOCITY is not set | 601 | # CONFIG_VIA_VELOCITY is not set |
593 | # CONFIG_TIGON3 is not set | 602 | # CONFIG_TIGON3 is not set |
594 | # CONFIG_BNX2 is not set | 603 | # CONFIG_BNX2 is not set |
@@ -597,11 +606,14 @@ CONFIG_E1000_NAPI=y | |||
597 | CONFIG_NETDEV_10000=y | 606 | CONFIG_NETDEV_10000=y |
598 | # CONFIG_CHELSIO_T1 is not set | 607 | # CONFIG_CHELSIO_T1 is not set |
599 | # CONFIG_CHELSIO_T3 is not set | 608 | # CONFIG_CHELSIO_T3 is not set |
609 | # CONFIG_IXGBE is not set | ||
600 | # CONFIG_IXGB is not set | 610 | # CONFIG_IXGB is not set |
601 | # CONFIG_S2IO is not set | 611 | # CONFIG_S2IO is not set |
602 | # CONFIG_MYRI10GE is not set | 612 | # CONFIG_MYRI10GE is not set |
603 | # CONFIG_NETXEN_NIC is not set | 613 | # CONFIG_NETXEN_NIC is not set |
614 | # CONFIG_NIU is not set | ||
604 | # CONFIG_MLX4_CORE is not set | 615 | # CONFIG_MLX4_CORE is not set |
616 | # CONFIG_TEHUTI is not set | ||
605 | # CONFIG_TR is not set | 617 | # CONFIG_TR is not set |
606 | 618 | ||
607 | # | 619 | # |
@@ -636,7 +648,6 @@ CONFIG_INPUT_MOUSEDEV=y | |||
636 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 | 648 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 |
637 | CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | 649 | CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 |
638 | # CONFIG_INPUT_JOYDEV is not set | 650 | # CONFIG_INPUT_JOYDEV is not set |
639 | # CONFIG_INPUT_TSDEV is not set | ||
640 | # CONFIG_INPUT_EVDEV is not set | 651 | # CONFIG_INPUT_EVDEV is not set |
641 | # CONFIG_INPUT_EVBUG is not set | 652 | # CONFIG_INPUT_EVBUG is not set |
642 | 653 | ||
@@ -685,12 +696,10 @@ CONFIG_UNIX98_PTYS=y | |||
685 | CONFIG_LEGACY_PTYS=y | 696 | CONFIG_LEGACY_PTYS=y |
686 | CONFIG_LEGACY_PTY_COUNT=256 | 697 | CONFIG_LEGACY_PTY_COUNT=256 |
687 | # CONFIG_IPMI_HANDLER is not set | 698 | # CONFIG_IPMI_HANDLER is not set |
688 | # CONFIG_WATCHDOG is not set | ||
689 | CONFIG_HW_RANDOM=y | 699 | CONFIG_HW_RANDOM=y |
690 | # CONFIG_NVRAM is not set | 700 | # CONFIG_NVRAM is not set |
691 | # CONFIG_R3964 is not set | 701 | # CONFIG_R3964 is not set |
692 | # CONFIG_APPLICOM is not set | 702 | # CONFIG_APPLICOM is not set |
693 | # CONFIG_DRM is not set | ||
694 | # CONFIG_RAW_DRIVER is not set | 703 | # CONFIG_RAW_DRIVER is not set |
695 | # CONFIG_TCG_TPM is not set | 704 | # CONFIG_TCG_TPM is not set |
696 | CONFIG_DEVPORT=y | 705 | CONFIG_DEVPORT=y |
@@ -755,9 +764,9 @@ CONFIG_I2C_IOP3XX=y | |||
755 | # CONFIG_SPI is not set | 764 | # CONFIG_SPI is not set |
756 | # CONFIG_SPI_MASTER is not set | 765 | # CONFIG_SPI_MASTER is not set |
757 | # CONFIG_W1 is not set | 766 | # CONFIG_W1 is not set |
767 | # CONFIG_POWER_SUPPLY is not set | ||
758 | CONFIG_HWMON=y | 768 | CONFIG_HWMON=y |
759 | # CONFIG_HWMON_VID is not set | 769 | # CONFIG_HWMON_VID is not set |
760 | # CONFIG_SENSORS_ABITUGURU is not set | ||
761 | # CONFIG_SENSORS_AD7418 is not set | 770 | # CONFIG_SENSORS_AD7418 is not set |
762 | # CONFIG_SENSORS_ADM1021 is not set | 771 | # CONFIG_SENSORS_ADM1021 is not set |
763 | # CONFIG_SENSORS_ADM1025 is not set | 772 | # CONFIG_SENSORS_ADM1025 is not set |
@@ -765,12 +774,13 @@ CONFIG_HWMON=y | |||
765 | # CONFIG_SENSORS_ADM1029 is not set | 774 | # CONFIG_SENSORS_ADM1029 is not set |
766 | # CONFIG_SENSORS_ADM1031 is not set | 775 | # CONFIG_SENSORS_ADM1031 is not set |
767 | # CONFIG_SENSORS_ADM9240 is not set | 776 | # CONFIG_SENSORS_ADM9240 is not set |
768 | # CONFIG_SENSORS_ASB100 is not set | 777 | # CONFIG_SENSORS_ADT7470 is not set |
769 | # CONFIG_SENSORS_ATXP1 is not set | 778 | # CONFIG_SENSORS_ATXP1 is not set |
770 | # CONFIG_SENSORS_DS1621 is not set | 779 | # CONFIG_SENSORS_DS1621 is not set |
780 | # CONFIG_SENSORS_I5K_AMB is not set | ||
771 | # CONFIG_SENSORS_F71805F is not set | 781 | # CONFIG_SENSORS_F71805F is not set |
772 | # CONFIG_SENSORS_FSCHER is not set | 782 | # CONFIG_SENSORS_F71882FG is not set |
773 | # CONFIG_SENSORS_FSCPOS is not set | 783 | # CONFIG_SENSORS_F75375S is not set |
774 | # CONFIG_SENSORS_GL518SM is not set | 784 | # CONFIG_SENSORS_GL518SM is not set |
775 | # CONFIG_SENSORS_GL520SM is not set | 785 | # CONFIG_SENSORS_GL520SM is not set |
776 | # CONFIG_SENSORS_IT87 is not set | 786 | # CONFIG_SENSORS_IT87 is not set |
@@ -784,14 +794,17 @@ CONFIG_HWMON=y | |||
784 | # CONFIG_SENSORS_LM87 is not set | 794 | # CONFIG_SENSORS_LM87 is not set |
785 | # CONFIG_SENSORS_LM90 is not set | 795 | # CONFIG_SENSORS_LM90 is not set |
786 | # CONFIG_SENSORS_LM92 is not set | 796 | # CONFIG_SENSORS_LM92 is not set |
797 | # CONFIG_SENSORS_LM93 is not set | ||
787 | # CONFIG_SENSORS_MAX1619 is not set | 798 | # CONFIG_SENSORS_MAX1619 is not set |
788 | # CONFIG_SENSORS_MAX6650 is not set | 799 | # CONFIG_SENSORS_MAX6650 is not set |
789 | # CONFIG_SENSORS_PC87360 is not set | 800 | # CONFIG_SENSORS_PC87360 is not set |
790 | # CONFIG_SENSORS_PC87427 is not set | 801 | # CONFIG_SENSORS_PC87427 is not set |
791 | # CONFIG_SENSORS_SIS5595 is not set | 802 | # CONFIG_SENSORS_SIS5595 is not set |
803 | # CONFIG_SENSORS_DME1737 is not set | ||
792 | # CONFIG_SENSORS_SMSC47M1 is not set | 804 | # CONFIG_SENSORS_SMSC47M1 is not set |
793 | # CONFIG_SENSORS_SMSC47M192 is not set | 805 | # CONFIG_SENSORS_SMSC47M192 is not set |
794 | # CONFIG_SENSORS_SMSC47B397 is not set | 806 | # CONFIG_SENSORS_SMSC47B397 is not set |
807 | # CONFIG_SENSORS_THMC50 is not set | ||
795 | # CONFIG_SENSORS_VIA686A is not set | 808 | # CONFIG_SENSORS_VIA686A is not set |
796 | # CONFIG_SENSORS_VT1211 is not set | 809 | # CONFIG_SENSORS_VT1211 is not set |
797 | # CONFIG_SENSORS_VT8231 is not set | 810 | # CONFIG_SENSORS_VT8231 is not set |
@@ -803,29 +816,18 @@ CONFIG_HWMON=y | |||
803 | # CONFIG_SENSORS_W83627HF is not set | 816 | # CONFIG_SENSORS_W83627HF is not set |
804 | # CONFIG_SENSORS_W83627EHF is not set | 817 | # CONFIG_SENSORS_W83627EHF is not set |
805 | # CONFIG_HWMON_DEBUG_CHIP is not set | 818 | # CONFIG_HWMON_DEBUG_CHIP is not set |
806 | CONFIG_MISC_DEVICES=y | 819 | # CONFIG_WATCHDOG is not set |
807 | # CONFIG_PHANTOM is not set | ||
808 | # CONFIG_EEPROM_93CX6 is not set | ||
809 | # CONFIG_SGI_IOC4 is not set | ||
810 | # CONFIG_TIFM_CORE is not set | ||
811 | |||
812 | # | ||
813 | # Multifunction device drivers | ||
814 | # | ||
815 | # CONFIG_MFD_SM501 is not set | ||
816 | |||
817 | # | ||
818 | # LED devices | ||
819 | # | ||
820 | # CONFIG_NEW_LEDS is not set | ||
821 | 820 | ||
822 | # | 821 | # |
823 | # LED drivers | 822 | # Sonics Silicon Backplane |
824 | # | 823 | # |
824 | CONFIG_SSB_POSSIBLE=y | ||
825 | # CONFIG_SSB is not set | ||
825 | 826 | ||
826 | # | 827 | # |
827 | # LED Triggers | 828 | # Multifunction device drivers |
828 | # | 829 | # |
830 | # CONFIG_MFD_SM501 is not set | ||
829 | 831 | ||
830 | # | 832 | # |
831 | # Multimedia devices | 833 | # Multimedia devices |
@@ -837,14 +839,16 @@ CONFIG_DAB=y | |||
837 | # | 839 | # |
838 | # Graphics support | 840 | # Graphics support |
839 | # | 841 | # |
842 | # CONFIG_DRM is not set | ||
843 | # CONFIG_VGASTATE is not set | ||
844 | # CONFIG_VIDEO_OUTPUT_CONTROL is not set | ||
845 | # CONFIG_FB is not set | ||
840 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set | 846 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set |
841 | 847 | ||
842 | # | 848 | # |
843 | # Display device support | 849 | # Display device support |
844 | # | 850 | # |
845 | # CONFIG_DISPLAY_SUPPORT is not set | 851 | # CONFIG_DISPLAY_SUPPORT is not set |
846 | # CONFIG_VGASTATE is not set | ||
847 | # CONFIG_FB is not set | ||
848 | 852 | ||
849 | # | 853 | # |
850 | # Console display driver support | 854 | # Console display driver support |
@@ -859,6 +863,7 @@ CONFIG_DUMMY_CONSOLE=y | |||
859 | CONFIG_HID_SUPPORT=y | 863 | CONFIG_HID_SUPPORT=y |
860 | CONFIG_HID=y | 864 | CONFIG_HID=y |
861 | # CONFIG_HID_DEBUG is not set | 865 | # CONFIG_HID_DEBUG is not set |
866 | # CONFIG_HIDRAW is not set | ||
862 | CONFIG_USB_SUPPORT=y | 867 | CONFIG_USB_SUPPORT=y |
863 | CONFIG_USB_ARCH_HAS_HCD=y | 868 | CONFIG_USB_ARCH_HAS_HCD=y |
864 | CONFIG_USB_ARCH_HAS_OHCI=y | 869 | CONFIG_USB_ARCH_HAS_OHCI=y |
@@ -874,16 +879,15 @@ CONFIG_USB_ARCH_HAS_EHCI=y | |||
874 | # | 879 | # |
875 | # CONFIG_USB_GADGET is not set | 880 | # CONFIG_USB_GADGET is not set |
876 | # CONFIG_MMC is not set | 881 | # CONFIG_MMC is not set |
877 | 882 | # CONFIG_NEW_LEDS is not set | |
878 | # | ||
879 | # Real Time Clock | ||
880 | # | ||
881 | CONFIG_RTC_LIB=y | 883 | CONFIG_RTC_LIB=y |
882 | # CONFIG_RTC_CLASS is not set | 884 | # CONFIG_RTC_CLASS is not set |
885 | CONFIG_DMADEVICES=y | ||
883 | 886 | ||
884 | # | 887 | # |
885 | # DMA Engine support | 888 | # DMA Devices |
886 | # | 889 | # |
890 | CONFIG_INTEL_IOP_ADMA=y | ||
887 | CONFIG_DMA_ENGINE=y | 891 | CONFIG_DMA_ENGINE=y |
888 | 892 | ||
889 | # | 893 | # |
@@ -892,12 +896,6 @@ CONFIG_DMA_ENGINE=y | |||
892 | CONFIG_NET_DMA=y | 896 | CONFIG_NET_DMA=y |
893 | 897 | ||
894 | # | 898 | # |
895 | # DMA Devices | ||
896 | # | ||
897 | # CONFIG_INTEL_IOATDMA is not set | ||
898 | CONFIG_INTEL_IOP_ADMA=y | ||
899 | |||
900 | # | ||
901 | # File systems | 899 | # File systems |
902 | # | 900 | # |
903 | CONFIG_EXT2_FS=y | 901 | CONFIG_EXT2_FS=y |
@@ -909,7 +907,6 @@ CONFIG_EXT3_FS_XATTR=y | |||
909 | # CONFIG_EXT3_FS_SECURITY is not set | 907 | # CONFIG_EXT3_FS_SECURITY is not set |
910 | # CONFIG_EXT4DEV_FS is not set | 908 | # CONFIG_EXT4DEV_FS is not set |
911 | CONFIG_JBD=y | 909 | CONFIG_JBD=y |
912 | # CONFIG_JBD_DEBUG is not set | ||
913 | CONFIG_FS_MBCACHE=y | 910 | CONFIG_FS_MBCACHE=y |
914 | # CONFIG_REISERFS_FS is not set | 911 | # CONFIG_REISERFS_FS is not set |
915 | # CONFIG_JFS_FS is not set | 912 | # CONFIG_JFS_FS is not set |
@@ -949,7 +946,6 @@ CONFIG_SYSFS=y | |||
949 | CONFIG_TMPFS=y | 946 | CONFIG_TMPFS=y |
950 | # CONFIG_TMPFS_POSIX_ACL is not set | 947 | # CONFIG_TMPFS_POSIX_ACL is not set |
951 | # CONFIG_HUGETLB_PAGE is not set | 948 | # CONFIG_HUGETLB_PAGE is not set |
952 | CONFIG_RAMFS=y | ||
953 | # CONFIG_CONFIGFS_FS is not set | 949 | # CONFIG_CONFIGFS_FS is not set |
954 | 950 | ||
955 | # | 951 | # |
@@ -969,10 +965,7 @@ CONFIG_CRAMFS=y | |||
969 | # CONFIG_QNX4FS_FS is not set | 965 | # CONFIG_QNX4FS_FS is not set |
970 | # CONFIG_SYSV_FS is not set | 966 | # CONFIG_SYSV_FS is not set |
971 | # CONFIG_UFS_FS is not set | 967 | # CONFIG_UFS_FS is not set |
972 | 968 | CONFIG_NETWORK_FILESYSTEMS=y | |
973 | # | ||
974 | # Network File Systems | ||
975 | # | ||
976 | CONFIG_NFS_FS=y | 969 | CONFIG_NFS_FS=y |
977 | CONFIG_NFS_V3=y | 970 | CONFIG_NFS_V3=y |
978 | # CONFIG_NFS_V3_ACL is not set | 971 | # CONFIG_NFS_V3_ACL is not set |
@@ -1019,26 +1012,17 @@ CONFIG_MSDOS_PARTITION=y | |||
1019 | # CONFIG_KARMA_PARTITION is not set | 1012 | # CONFIG_KARMA_PARTITION is not set |
1020 | # CONFIG_EFI_PARTITION is not set | 1013 | # CONFIG_EFI_PARTITION is not set |
1021 | # CONFIG_SYSV68_PARTITION is not set | 1014 | # CONFIG_SYSV68_PARTITION is not set |
1022 | |||
1023 | # | ||
1024 | # Native Language Support | ||
1025 | # | ||
1026 | # CONFIG_NLS is not set | 1015 | # CONFIG_NLS is not set |
1027 | |||
1028 | # | ||
1029 | # Distributed Lock Manager | ||
1030 | # | ||
1031 | # CONFIG_DLM is not set | 1016 | # CONFIG_DLM is not set |
1032 | 1017 | CONFIG_INSTRUMENTATION=y | |
1033 | # | ||
1034 | # Profiling support | ||
1035 | # | ||
1036 | # CONFIG_PROFILING is not set | 1018 | # CONFIG_PROFILING is not set |
1019 | # CONFIG_MARKERS is not set | ||
1037 | 1020 | ||
1038 | # | 1021 | # |
1039 | # Kernel hacking | 1022 | # Kernel hacking |
1040 | # | 1023 | # |
1041 | # CONFIG_PRINTK_TIME is not set | 1024 | # CONFIG_PRINTK_TIME is not set |
1025 | CONFIG_ENABLE_WARN_DEPRECATED=y | ||
1042 | CONFIG_ENABLE_MUST_CHECK=y | 1026 | CONFIG_ENABLE_MUST_CHECK=y |
1043 | CONFIG_MAGIC_SYSRQ=y | 1027 | CONFIG_MAGIC_SYSRQ=y |
1044 | # CONFIG_UNUSED_SYMBOLS is not set | 1028 | # CONFIG_UNUSED_SYMBOLS is not set |
@@ -1065,10 +1049,13 @@ CONFIG_DEBUG_BUGVERBOSE=y | |||
1065 | # CONFIG_DEBUG_INFO is not set | 1049 | # CONFIG_DEBUG_INFO is not set |
1066 | # CONFIG_DEBUG_VM is not set | 1050 | # CONFIG_DEBUG_VM is not set |
1067 | # CONFIG_DEBUG_LIST is not set | 1051 | # CONFIG_DEBUG_LIST is not set |
1052 | # CONFIG_DEBUG_SG is not set | ||
1068 | CONFIG_FRAME_POINTER=y | 1053 | CONFIG_FRAME_POINTER=y |
1069 | # CONFIG_FORCED_INLINING is not set | 1054 | # CONFIG_FORCED_INLINING is not set |
1055 | # CONFIG_BOOT_PRINTK_DELAY is not set | ||
1070 | # CONFIG_RCU_TORTURE_TEST is not set | 1056 | # CONFIG_RCU_TORTURE_TEST is not set |
1071 | # CONFIG_FAULT_INJECTION is not set | 1057 | # CONFIG_FAULT_INJECTION is not set |
1058 | # CONFIG_SAMPLES is not set | ||
1072 | CONFIG_DEBUG_USER=y | 1059 | CONFIG_DEBUG_USER=y |
1073 | # CONFIG_DEBUG_ERRORS is not set | 1060 | # CONFIG_DEBUG_ERRORS is not set |
1074 | CONFIG_DEBUG_LL=y | 1061 | CONFIG_DEBUG_LL=y |
@@ -1079,6 +1066,7 @@ CONFIG_DEBUG_LL=y | |||
1079 | # | 1066 | # |
1080 | # CONFIG_KEYS is not set | 1067 | # CONFIG_KEYS is not set |
1081 | # CONFIG_SECURITY is not set | 1068 | # CONFIG_SECURITY is not set |
1069 | # CONFIG_SECURITY_FILE_CAPABILITIES is not set | ||
1082 | CONFIG_XOR_BLOCKS=y | 1070 | CONFIG_XOR_BLOCKS=y |
1083 | CONFIG_ASYNC_CORE=y | 1071 | CONFIG_ASYNC_CORE=y |
1084 | CONFIG_ASYNC_MEMCPY=y | 1072 | CONFIG_ASYNC_MEMCPY=y |
diff --git a/arch/arm/configs/msm_defconfig b/arch/arm/configs/msm_defconfig new file mode 100644 index 000000000000..ae4c5e62086a --- /dev/null +++ b/arch/arm/configs/msm_defconfig | |||
@@ -0,0 +1,895 @@ | |||
1 | # | ||
2 | # Automatically generated make config: don't edit | ||
3 | # Linux kernel version: 2.6.23 | ||
4 | # Wed Nov 7 01:36:45 2007 | ||
5 | # | ||
6 | CONFIG_ARM=y | ||
7 | CONFIG_SYS_SUPPORTS_APM_EMULATION=y | ||
8 | # CONFIG_GENERIC_GPIO is not set | ||
9 | CONFIG_GENERIC_TIME=y | ||
10 | CONFIG_GENERIC_CLOCKEVENTS=y | ||
11 | CONFIG_MMU=y | ||
12 | # CONFIG_NO_IOPORT is not set | ||
13 | CONFIG_GENERIC_HARDIRQS=y | ||
14 | CONFIG_GENERIC_GPIOS=y | ||
15 | CONFIG_STACKTRACE_SUPPORT=y | ||
16 | CONFIG_LOCKDEP_SUPPORT=y | ||
17 | CONFIG_TRACE_IRQFLAGS_SUPPORT=y | ||
18 | CONFIG_HARDIRQS_SW_RESEND=y | ||
19 | CONFIG_GENERIC_IRQ_PROBE=y | ||
20 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
21 | # CONFIG_ARCH_HAS_ILOG2_U32 is not set | ||
22 | # CONFIG_ARCH_HAS_ILOG2_U64 is not set | ||
23 | CONFIG_GENERIC_HWEIGHT=y | ||
24 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
25 | CONFIG_ZONE_DMA=y | ||
26 | CONFIG_VECTORS_BASE=0xffff0000 | ||
27 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | ||
28 | |||
29 | # | ||
30 | # General setup | ||
31 | # | ||
32 | CONFIG_EXPERIMENTAL=y | ||
33 | CONFIG_BROKEN_ON_SMP=y | ||
34 | CONFIG_LOCK_KERNEL=y | ||
35 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
36 | CONFIG_LOCALVERSION="" | ||
37 | CONFIG_LOCALVERSION_AUTO=y | ||
38 | CONFIG_SWAP=y | ||
39 | # CONFIG_SYSVIPC is not set | ||
40 | # CONFIG_POSIX_MQUEUE is not set | ||
41 | # CONFIG_BSD_PROCESS_ACCT is not set | ||
42 | # CONFIG_TASKSTATS is not set | ||
43 | # CONFIG_USER_NS is not set | ||
44 | # CONFIG_AUDIT is not set | ||
45 | CONFIG_IKCONFIG=y | ||
46 | CONFIG_IKCONFIG_PROC=y | ||
47 | CONFIG_LOG_BUF_SHIFT=17 | ||
48 | CONFIG_SYSFS_DEPRECATED=y | ||
49 | # CONFIG_RELAY is not set | ||
50 | CONFIG_BLK_DEV_INITRD=y | ||
51 | CONFIG_INITRAMFS_SOURCE="" | ||
52 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | ||
53 | CONFIG_SYSCTL=y | ||
54 | CONFIG_PANIC_TIMEOUT=0 | ||
55 | # CONFIG_EMBEDDED is not set | ||
56 | CONFIG_UID16=y | ||
57 | CONFIG_SYSCTL_SYSCALL=y | ||
58 | CONFIG_KALLSYMS=y | ||
59 | # CONFIG_KALLSYMS_ALL is not set | ||
60 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | ||
61 | CONFIG_HOTPLUG=y | ||
62 | CONFIG_PRINTK=y | ||
63 | CONFIG_BUG=y | ||
64 | CONFIG_ELF_CORE=y | ||
65 | CONFIG_BASE_FULL=y | ||
66 | CONFIG_FUTEX=y | ||
67 | CONFIG_ANON_INODES=y | ||
68 | CONFIG_EPOLL=y | ||
69 | CONFIG_SIGNALFD=y | ||
70 | CONFIG_EVENTFD=y | ||
71 | CONFIG_SHMEM=y | ||
72 | CONFIG_VM_EVENT_COUNTERS=y | ||
73 | CONFIG_SLAB=y | ||
74 | # CONFIG_SLUB is not set | ||
75 | # CONFIG_SLOB is not set | ||
76 | CONFIG_RT_MUTEXES=y | ||
77 | # CONFIG_TINY_SHMEM is not set | ||
78 | CONFIG_BASE_SMALL=0 | ||
79 | # CONFIG_MODULES is not set | ||
80 | CONFIG_BLOCK=y | ||
81 | # CONFIG_LBD is not set | ||
82 | # CONFIG_BLK_DEV_IO_TRACE is not set | ||
83 | # CONFIG_LSF is not set | ||
84 | # CONFIG_BLK_DEV_BSG is not set | ||
85 | |||
86 | # | ||
87 | # IO Schedulers | ||
88 | # | ||
89 | CONFIG_IOSCHED_NOOP=y | ||
90 | CONFIG_IOSCHED_AS=y | ||
91 | # CONFIG_IOSCHED_DEADLINE is not set | ||
92 | # CONFIG_IOSCHED_CFQ is not set | ||
93 | CONFIG_DEFAULT_AS=y | ||
94 | # CONFIG_DEFAULT_DEADLINE is not set | ||
95 | # CONFIG_DEFAULT_CFQ is not set | ||
96 | # CONFIG_DEFAULT_NOOP is not set | ||
97 | CONFIG_DEFAULT_IOSCHED="anticipatory" | ||
98 | |||
99 | # | ||
100 | # System Type | ||
101 | # | ||
102 | # CONFIG_ARCH_AAEC2000 is not set | ||
103 | # CONFIG_ARCH_GOLDFISH is not set | ||
104 | # CONFIG_ARCH_INTEGRATOR is not set | ||
105 | # CONFIG_ARCH_REALVIEW is not set | ||
106 | # CONFIG_ARCH_VERSATILE is not set | ||
107 | # CONFIG_ARCH_AT91 is not set | ||
108 | # CONFIG_ARCH_CLPS7500 is not set | ||
109 | # CONFIG_ARCH_CLPS711X is not set | ||
110 | # CONFIG_ARCH_CO285 is not set | ||
111 | # CONFIG_ARCH_EBSA110 is not set | ||
112 | # CONFIG_ARCH_EP93XX is not set | ||
113 | # CONFIG_ARCH_FOOTBRIDGE is not set | ||
114 | # CONFIG_ARCH_NETX is not set | ||
115 | # CONFIG_ARCH_H720X is not set | ||
116 | # CONFIG_ARCH_IMX is not set | ||
117 | # CONFIG_ARCH_IOP13XX is not set | ||
118 | # CONFIG_ARCH_IOP32X is not set | ||
119 | # CONFIG_ARCH_IOP33X is not set | ||
120 | # CONFIG_ARCH_IXP23XX is not set | ||
121 | # CONFIG_ARCH_IXP2000 is not set | ||
122 | # CONFIG_ARCH_IXP4XX is not set | ||
123 | # CONFIG_ARCH_L7200 is not set | ||
124 | # CONFIG_ARCH_KS8695 is not set | ||
125 | # CONFIG_ARCH_NS9XXX is not set | ||
126 | # CONFIG_ARCH_MXC is not set | ||
127 | # CONFIG_ARCH_PNX4008 is not set | ||
128 | # CONFIG_ARCH_PXA is not set | ||
129 | # CONFIG_ARCH_RPC is not set | ||
130 | # CONFIG_ARCH_SA1100 is not set | ||
131 | # CONFIG_ARCH_S3C2410 is not set | ||
132 | # CONFIG_ARCH_SHARK is not set | ||
133 | # CONFIG_ARCH_LH7A40X is not set | ||
134 | # CONFIG_ARCH_DAVINCI is not set | ||
135 | # CONFIG_ARCH_OMAP is not set | ||
136 | CONFIG_ARCH_MSM7X00A=y | ||
137 | |||
138 | # | ||
139 | # Boot options | ||
140 | # | ||
141 | |||
142 | # | ||
143 | # Power management | ||
144 | # | ||
145 | |||
146 | # | ||
147 | # MSM7200 Board Type | ||
148 | # | ||
149 | CONFIG_MACH_HALIBUT=y | ||
150 | CONFIG_SERIAL_MSM=y | ||
151 | CONFIG_SERIAL_MSM_CONSOLE=y | ||
152 | # CONFIG_SERIAL_MSM_NOINIT is not set | ||
153 | CONFIG_MSM_SMD=y | ||
154 | |||
155 | # | ||
156 | # Processor Type | ||
157 | # | ||
158 | CONFIG_CPU_32=y | ||
159 | CONFIG_CPU_V6=y | ||
160 | # CONFIG_CPU_32v6K is not set | ||
161 | CONFIG_CPU_32v6=y | ||
162 | CONFIG_CPU_ABRT_EV6=y | ||
163 | CONFIG_CPU_CACHE_V6=y | ||
164 | CONFIG_CPU_CACHE_VIPT=y | ||
165 | CONFIG_CPU_COPY_V6=y | ||
166 | CONFIG_CPU_TLB_V6=y | ||
167 | CONFIG_CPU_HAS_ASID=y | ||
168 | CONFIG_CPU_CP15=y | ||
169 | CONFIG_CPU_CP15_MMU=y | ||
170 | |||
171 | # | ||
172 | # Processor Features | ||
173 | # | ||
174 | CONFIG_ARM_THUMB=y | ||
175 | # CONFIG_CPU_ICACHE_DISABLE is not set | ||
176 | # CONFIG_CPU_DCACHE_DISABLE is not set | ||
177 | # CONFIG_CPU_BPREDICT_DISABLE is not set | ||
178 | # CONFIG_OUTER_CACHE is not set | ||
179 | |||
180 | # | ||
181 | # Bus support | ||
182 | # | ||
183 | # CONFIG_PCI_SYSCALL is not set | ||
184 | # CONFIG_ARCH_SUPPORTS_MSI is not set | ||
185 | |||
186 | # | ||
187 | # PCCARD (PCMCIA/CardBus) support | ||
188 | # | ||
189 | # CONFIG_PCCARD is not set | ||
190 | |||
191 | # | ||
192 | # Kernel Features | ||
193 | # | ||
194 | CONFIG_TICK_ONESHOT=y | ||
195 | CONFIG_NO_HZ=y | ||
196 | CONFIG_HIGH_RES_TIMERS=y | ||
197 | CONFIG_PREEMPT=y | ||
198 | CONFIG_HZ=100 | ||
199 | CONFIG_AEABI=y | ||
200 | # CONFIG_OABI_COMPAT is not set | ||
201 | # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set | ||
202 | CONFIG_SELECT_MEMORY_MODEL=y | ||
203 | CONFIG_FLATMEM_MANUAL=y | ||
204 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
205 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
206 | CONFIG_FLATMEM=y | ||
207 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
208 | # CONFIG_SPARSEMEM_STATIC is not set | ||
209 | CONFIG_SPLIT_PTLOCK_CPUS=4 | ||
210 | CONFIG_RESOURCES_64BIT=y | ||
211 | CONFIG_ZONE_DMA_FLAG=1 | ||
212 | CONFIG_BOUNCE=y | ||
213 | CONFIG_VIRT_TO_BUS=y | ||
214 | CONFIG_ALIGNMENT_TRAP=y | ||
215 | |||
216 | # | ||
217 | # Boot options | ||
218 | # | ||
219 | CONFIG_ZBOOT_ROM_TEXT=0x0 | ||
220 | CONFIG_ZBOOT_ROM_BSS=0x0 | ||
221 | CONFIG_CMDLINE="mem=64M console=ttyMSM,115200n8" | ||
222 | # CONFIG_XIP_KERNEL is not set | ||
223 | # CONFIG_KEXEC is not set | ||
224 | |||
225 | # | ||
226 | # Floating point emulation | ||
227 | # | ||
228 | |||
229 | # | ||
230 | # At least one emulation must be selected | ||
231 | # | ||
232 | # CONFIG_VFP is not set | ||
233 | |||
234 | # | ||
235 | # Userspace binary formats | ||
236 | # | ||
237 | CONFIG_BINFMT_ELF=y | ||
238 | # CONFIG_BINFMT_AOUT is not set | ||
239 | # CONFIG_BINFMT_MISC is not set | ||
240 | |||
241 | # | ||
242 | # Power management options | ||
243 | # | ||
244 | CONFIG_PM=y | ||
245 | CONFIG_SUSPEND_UP_POSSIBLE=y | ||
246 | |||
247 | # | ||
248 | # Networking | ||
249 | # | ||
250 | CONFIG_NET=y | ||
251 | |||
252 | # | ||
253 | # Networking options | ||
254 | # | ||
255 | # CONFIG_PACKET is not set | ||
256 | CONFIG_UNIX=y | ||
257 | # CONFIG_NET_KEY is not set | ||
258 | CONFIG_INET=y | ||
259 | # CONFIG_IP_MULTICAST is not set | ||
260 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
261 | CONFIG_IP_FIB_HASH=y | ||
262 | # CONFIG_IP_PNP is not set | ||
263 | # CONFIG_NET_IPIP is not set | ||
264 | # CONFIG_NET_IPGRE is not set | ||
265 | # CONFIG_ARPD is not set | ||
266 | # CONFIG_SYN_COOKIES is not set | ||
267 | # CONFIG_INET_AH is not set | ||
268 | # CONFIG_INET_ESP is not set | ||
269 | # CONFIG_INET_IPCOMP is not set | ||
270 | # CONFIG_INET_XFRM_TUNNEL is not set | ||
271 | # CONFIG_INET_TUNNEL is not set | ||
272 | # CONFIG_INET_XFRM_MODE_TRANSPORT is not set | ||
273 | # CONFIG_INET_XFRM_MODE_TUNNEL is not set | ||
274 | # CONFIG_INET_XFRM_MODE_BEET is not set | ||
275 | # CONFIG_INET_DIAG is not set | ||
276 | # CONFIG_TCP_CONG_ADVANCED is not set | ||
277 | CONFIG_TCP_CONG_CUBIC=y | ||
278 | CONFIG_DEFAULT_TCP_CONG="cubic" | ||
279 | # CONFIG_TCP_MD5SIG is not set | ||
280 | # CONFIG_IPV6 is not set | ||
281 | # CONFIG_INET6_XFRM_TUNNEL is not set | ||
282 | # CONFIG_INET6_TUNNEL is not set | ||
283 | # CONFIG_NETWORK_SECMARK is not set | ||
284 | # CONFIG_NETFILTER is not set | ||
285 | # CONFIG_IP_DCCP is not set | ||
286 | # CONFIG_IP_SCTP is not set | ||
287 | # CONFIG_TIPC is not set | ||
288 | # CONFIG_ATM is not set | ||
289 | # CONFIG_BRIDGE is not set | ||
290 | # CONFIG_VLAN_8021Q is not set | ||
291 | # CONFIG_DECNET is not set | ||
292 | # CONFIG_LLC2 is not set | ||
293 | # CONFIG_IPX is not set | ||
294 | # CONFIG_ATALK is not set | ||
295 | # CONFIG_X25 is not set | ||
296 | # CONFIG_LAPB is not set | ||
297 | # CONFIG_ECONET is not set | ||
298 | # CONFIG_WAN_ROUTER is not set | ||
299 | |||
300 | # | ||
301 | # QoS and/or fair queueing | ||
302 | # | ||
303 | # CONFIG_NET_SCHED is not set | ||
304 | |||
305 | # | ||
306 | # Network testing | ||
307 | # | ||
308 | # CONFIG_NET_PKTGEN is not set | ||
309 | # CONFIG_HAMRADIO is not set | ||
310 | # CONFIG_IRDA is not set | ||
311 | # CONFIG_BT is not set | ||
312 | # CONFIG_AF_RXRPC is not set | ||
313 | |||
314 | # | ||
315 | # Wireless | ||
316 | # | ||
317 | # CONFIG_CFG80211 is not set | ||
318 | # CONFIG_WIRELESS_EXT is not set | ||
319 | # CONFIG_MAC80211 is not set | ||
320 | # CONFIG_IEEE80211 is not set | ||
321 | # CONFIG_RFKILL is not set | ||
322 | # CONFIG_NET_9P is not set | ||
323 | |||
324 | # | ||
325 | # Device Drivers | ||
326 | # | ||
327 | |||
328 | # | ||
329 | # Generic Driver Options | ||
330 | # | ||
331 | CONFIG_STANDALONE=y | ||
332 | CONFIG_PREVENT_FIRMWARE_BUILD=y | ||
333 | CONFIG_FW_LOADER=y | ||
334 | # CONFIG_DEBUG_DRIVER is not set | ||
335 | # CONFIG_DEBUG_DEVRES is not set | ||
336 | # CONFIG_SYS_HYPERVISOR is not set | ||
337 | # CONFIG_CONNECTOR is not set | ||
338 | CONFIG_MTD=y | ||
339 | # CONFIG_MTD_DEBUG is not set | ||
340 | # CONFIG_MTD_CONCAT is not set | ||
341 | CONFIG_MTD_PARTITIONS=y | ||
342 | # CONFIG_MTD_REDBOOT_PARTS is not set | ||
343 | CONFIG_MTD_CMDLINE_PARTS=y | ||
344 | # CONFIG_MTD_AFS_PARTS is not set | ||
345 | |||
346 | # | ||
347 | # User Modules And Translation Layers | ||
348 | # | ||
349 | CONFIG_MTD_CHAR=y | ||
350 | CONFIG_MTD_BLKDEVS=y | ||
351 | CONFIG_MTD_BLOCK=y | ||
352 | # CONFIG_FTL is not set | ||
353 | # CONFIG_NFTL is not set | ||
354 | # CONFIG_INFTL is not set | ||
355 | # CONFIG_RFD_FTL is not set | ||
356 | # CONFIG_SSFDC is not set | ||
357 | |||
358 | # | ||
359 | # RAM/ROM/Flash chip drivers | ||
360 | # | ||
361 | # CONFIG_MTD_CFI is not set | ||
362 | # CONFIG_MTD_JEDECPROBE is not set | ||
363 | CONFIG_MTD_MAP_BANK_WIDTH_1=y | ||
364 | CONFIG_MTD_MAP_BANK_WIDTH_2=y | ||
365 | CONFIG_MTD_MAP_BANK_WIDTH_4=y | ||
366 | # CONFIG_MTD_MAP_BANK_WIDTH_8 is not set | ||
367 | # CONFIG_MTD_MAP_BANK_WIDTH_16 is not set | ||
368 | # CONFIG_MTD_MAP_BANK_WIDTH_32 is not set | ||
369 | CONFIG_MTD_CFI_I1=y | ||
370 | CONFIG_MTD_CFI_I2=y | ||
371 | # CONFIG_MTD_CFI_I4 is not set | ||
372 | # CONFIG_MTD_CFI_I8 is not set | ||
373 | # CONFIG_MTD_RAM is not set | ||
374 | # CONFIG_MTD_ROM is not set | ||
375 | # CONFIG_MTD_ABSENT is not set | ||
376 | |||
377 | # | ||
378 | # Mapping drivers for chip access | ||
379 | # | ||
380 | # CONFIG_MTD_COMPLEX_MAPPINGS is not set | ||
381 | # CONFIG_MTD_PLATRAM is not set | ||
382 | |||
383 | # | ||
384 | # Self-contained MTD device drivers | ||
385 | # | ||
386 | # CONFIG_MTD_SLRAM is not set | ||
387 | # CONFIG_MTD_PHRAM is not set | ||
388 | # CONFIG_MTD_MTDRAM is not set | ||
389 | # CONFIG_MTD_BLOCK2MTD is not set | ||
390 | CONFIG_MTD_MSM_NAND=y | ||
391 | |||
392 | # | ||
393 | # Disk-On-Chip Device Drivers | ||
394 | # | ||
395 | # CONFIG_MTD_DOC2000 is not set | ||
396 | # CONFIG_MTD_DOC2001 is not set | ||
397 | # CONFIG_MTD_DOC2001PLUS is not set | ||
398 | # CONFIG_MTD_GOLDFISH_NAND is not set | ||
399 | # CONFIG_MTD_NAND is not set | ||
400 | # CONFIG_MTD_ONENAND is not set | ||
401 | |||
402 | # | ||
403 | # UBI - Unsorted block images | ||
404 | # | ||
405 | # CONFIG_MTD_UBI is not set | ||
406 | # CONFIG_PARPORT is not set | ||
407 | CONFIG_BLK_DEV=y | ||
408 | # CONFIG_BLK_DEV_COW_COMMON is not set | ||
409 | # CONFIG_BLK_DEV_LOOP is not set | ||
410 | # CONFIG_BLK_DEV_NBD is not set | ||
411 | # CONFIG_BLK_DEV_RAM is not set | ||
412 | # CONFIG_CDROM_PKTCDVD is not set | ||
413 | # CONFIG_ATA_OVER_ETH is not set | ||
414 | |||
415 | # | ||
416 | # SCSI device support | ||
417 | # | ||
418 | # CONFIG_RAID_ATTRS is not set | ||
419 | # CONFIG_SCSI is not set | ||
420 | # CONFIG_SCSI_DMA is not set | ||
421 | # CONFIG_SCSI_NETLINK is not set | ||
422 | # CONFIG_ATA is not set | ||
423 | # CONFIG_MD is not set | ||
424 | CONFIG_NETDEVICES=y | ||
425 | # CONFIG_NETDEVICES_MULTIQUEUE is not set | ||
426 | CONFIG_DUMMY=y | ||
427 | # CONFIG_BONDING is not set | ||
428 | # CONFIG_MACVLAN is not set | ||
429 | # CONFIG_EQUALIZER is not set | ||
430 | # CONFIG_TUN is not set | ||
431 | # CONFIG_PHYLIB is not set | ||
432 | CONFIG_NET_ETHERNET=y | ||
433 | CONFIG_MII=y | ||
434 | # CONFIG_AX88796 is not set | ||
435 | CONFIG_SMC91X=y | ||
436 | # CONFIG_DM9000 is not set | ||
437 | CONFIG_NETDEV_1000=y | ||
438 | CONFIG_NETDEV_10000=y | ||
439 | |||
440 | # | ||
441 | # Wireless LAN | ||
442 | # | ||
443 | # CONFIG_WLAN_PRE80211 is not set | ||
444 | # CONFIG_WLAN_80211 is not set | ||
445 | # CONFIG_WAN is not set | ||
446 | CONFIG_PPP=y | ||
447 | # CONFIG_PPP_MULTILINK is not set | ||
448 | # CONFIG_PPP_FILTER is not set | ||
449 | CONFIG_PPP_ASYNC=y | ||
450 | # CONFIG_PPP_SYNC_TTY is not set | ||
451 | CONFIG_PPP_DEFLATE=y | ||
452 | CONFIG_PPP_BSDCOMP=y | ||
453 | # CONFIG_PPP_MPPE is not set | ||
454 | # CONFIG_PPPOE is not set | ||
455 | # CONFIG_PPPOL2TP is not set | ||
456 | # CONFIG_SLIP is not set | ||
457 | CONFIG_SLHC=y | ||
458 | # CONFIG_SHAPER is not set | ||
459 | # CONFIG_NETCONSOLE is not set | ||
460 | CONFIG_MSM_RMNET=y | ||
461 | # CONFIG_NETPOLL is not set | ||
462 | # CONFIG_NET_POLL_CONTROLLER is not set | ||
463 | # CONFIG_ISDN is not set | ||
464 | |||
465 | # | ||
466 | # Input device support | ||
467 | # | ||
468 | CONFIG_INPUT=y | ||
469 | # CONFIG_INPUT_FF_MEMLESS is not set | ||
470 | # CONFIG_INPUT_POLLDEV is not set | ||
471 | |||
472 | # | ||
473 | # Userland interfaces | ||
474 | # | ||
475 | CONFIG_INPUT_MOUSEDEV=y | ||
476 | # CONFIG_INPUT_MOUSEDEV_PSAUX is not set | ||
477 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 | ||
478 | CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | ||
479 | # CONFIG_INPUT_JOYDEV is not set | ||
480 | # CONFIG_INPUT_TSDEV is not set | ||
481 | CONFIG_INPUT_EVDEV=y | ||
482 | # CONFIG_INPUT_EVBUG is not set | ||
483 | |||
484 | # | ||
485 | # Input Device Drivers | ||
486 | # | ||
487 | CONFIG_INPUT_KEYBOARD=y | ||
488 | # CONFIG_KEYBOARD_ATKBD is not set | ||
489 | # CONFIG_KEYBOARD_SUNKBD is not set | ||
490 | # CONFIG_KEYBOARD_LKKBD is not set | ||
491 | # CONFIG_KEYBOARD_XTKBD is not set | ||
492 | # CONFIG_KEYBOARD_NEWTON is not set | ||
493 | # CONFIG_KEYBOARD_STOWAWAY is not set | ||
494 | # CONFIG_KEYBOARD_GOLDFISH_EVENTS is not set | ||
495 | # CONFIG_INPUT_MOUSE is not set | ||
496 | # CONFIG_INPUT_JOYSTICK is not set | ||
497 | # CONFIG_INPUT_TABLET is not set | ||
498 | CONFIG_INPUT_TOUCHSCREEN=y | ||
499 | # CONFIG_TOUCHSCREEN_FUJITSU is not set | ||
500 | # CONFIG_TOUCHSCREEN_GUNZE is not set | ||
501 | # CONFIG_TOUCHSCREEN_ELO is not set | ||
502 | # CONFIG_TOUCHSCREEN_MTOUCH is not set | ||
503 | # CONFIG_TOUCHSCREEN_MK712 is not set | ||
504 | # CONFIG_TOUCHSCREEN_PENMOUNT is not set | ||
505 | # CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_MEP is not set | ||
506 | CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI=y | ||
507 | # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set | ||
508 | # CONFIG_TOUCHSCREEN_TOUCHWIN is not set | ||
509 | # CONFIG_TOUCHSCREEN_UCB1400 is not set | ||
510 | # CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set | ||
511 | CONFIG_INPUT_MISC=y | ||
512 | # CONFIG_INPUT_ATI_REMOTE is not set | ||
513 | # CONFIG_INPUT_ATI_REMOTE2 is not set | ||
514 | # CONFIG_INPUT_KEYSPAN_REMOTE is not set | ||
515 | # CONFIG_INPUT_POWERMATE is not set | ||
516 | # CONFIG_INPUT_YEALINK is not set | ||
517 | # CONFIG_INPUT_UINPUT is not set | ||
518 | CONFIG_INPUT_GPIO=y | ||
519 | |||
520 | # | ||
521 | # Hardware I/O ports | ||
522 | # | ||
523 | # CONFIG_SERIO is not set | ||
524 | # CONFIG_GAMEPORT is not set | ||
525 | |||
526 | # | ||
527 | # Character devices | ||
528 | # | ||
529 | CONFIG_VT=y | ||
530 | CONFIG_VT_CONSOLE=y | ||
531 | CONFIG_HW_CONSOLE=y | ||
532 | CONFIG_VT_HW_CONSOLE_BINDING=y | ||
533 | # CONFIG_SERIAL_NONSTANDARD is not set | ||
534 | |||
535 | # | ||
536 | # Serial drivers | ||
537 | # | ||
538 | # CONFIG_SERIAL_8250 is not set | ||
539 | |||
540 | # | ||
541 | # Non-8250 serial port support | ||
542 | # | ||
543 | CONFIG_SERIAL_CORE=y | ||
544 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
545 | CONFIG_UNIX98_PTYS=y | ||
546 | # CONFIG_LEGACY_PTYS is not set | ||
547 | # CONFIG_IPMI_HANDLER is not set | ||
548 | # CONFIG_WATCHDOG is not set | ||
549 | # CONFIG_HW_RANDOM is not set | ||
550 | # CONFIG_NVRAM is not set | ||
551 | # CONFIG_R3964 is not set | ||
552 | # CONFIG_RAW_DRIVER is not set | ||
553 | # CONFIG_TCG_TPM is not set | ||
554 | CONFIG_DCC_TTY=y | ||
555 | # CONFIG_GOLDFISH_TTY is not set | ||
556 | CONFIG_BINDER=y | ||
557 | CONFIG_I2C=y | ||
558 | CONFIG_I2C_BOARDINFO=y | ||
559 | # CONFIG_I2C_CHARDEV is not set | ||
560 | |||
561 | # | ||
562 | # I2C Algorithms | ||
563 | # | ||
564 | # CONFIG_I2C_ALGOBIT is not set | ||
565 | # CONFIG_I2C_ALGOPCF is not set | ||
566 | # CONFIG_I2C_ALGOPCA is not set | ||
567 | |||
568 | # | ||
569 | # I2C Hardware Bus support | ||
570 | # | ||
571 | CONFIG_I2C_MSM=y | ||
572 | # CONFIG_I2C_OCORES is not set | ||
573 | # CONFIG_I2C_PARPORT_LIGHT is not set | ||
574 | # CONFIG_I2C_SIMTEC is not set | ||
575 | # CONFIG_I2C_TAOS_EVM is not set | ||
576 | |||
577 | # | ||
578 | # Miscellaneous I2C Chip support | ||
579 | # | ||
580 | # CONFIG_SENSORS_DS1337 is not set | ||
581 | # CONFIG_SENSORS_DS1374 is not set | ||
582 | # CONFIG_DS1682 is not set | ||
583 | # CONFIG_SENSORS_EEPROM is not set | ||
584 | # CONFIG_SENSORS_PCF8574 is not set | ||
585 | # CONFIG_SENSORS_PCA9539 is not set | ||
586 | CONFIG_SENSORS_PCA9633=y | ||
587 | # CONFIG_SENSORS_PCF8591 is not set | ||
588 | # CONFIG_SENSORS_MAX6875 is not set | ||
589 | CONFIG_SENSORS_AKM8976=y | ||
590 | # CONFIG_SENSORS_TSL2550 is not set | ||
591 | # CONFIG_I2C_DEBUG_CORE is not set | ||
592 | # CONFIG_I2C_DEBUG_ALGO is not set | ||
593 | # CONFIG_I2C_DEBUG_BUS is not set | ||
594 | # CONFIG_I2C_DEBUG_CHIP is not set | ||
595 | |||
596 | # | ||
597 | # SPI support | ||
598 | # | ||
599 | # CONFIG_SPI is not set | ||
600 | # CONFIG_SPI_MASTER is not set | ||
601 | # CONFIG_W1 is not set | ||
602 | # CONFIG_HWMON is not set | ||
603 | CONFIG_MISC_DEVICES=y | ||
604 | # CONFIG_EEPROM_93CX6 is not set | ||
605 | CONFIG_LOW_MEMORY_KILLER=y | ||
606 | |||
607 | # | ||
608 | # Multifunction device drivers | ||
609 | # | ||
610 | # CONFIG_MFD_SM501 is not set | ||
611 | CONFIG_NEW_LEDS=y | ||
612 | CONFIG_LEDS_CLASS=y | ||
613 | |||
614 | # | ||
615 | # Multimedia devices | ||
616 | # | ||
617 | # CONFIG_VIDEO_DEV is not set | ||
618 | # CONFIG_DVB_CORE is not set | ||
619 | CONFIG_DAB=y | ||
620 | |||
621 | # | ||
622 | # Graphics support | ||
623 | # | ||
624 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set | ||
625 | |||
626 | # | ||
627 | # Display device support | ||
628 | # | ||
629 | # CONFIG_DISPLAY_SUPPORT is not set | ||
630 | # CONFIG_VGASTATE is not set | ||
631 | CONFIG_VIDEO_OUTPUT_CONTROL=y | ||
632 | CONFIG_FB=y | ||
633 | # CONFIG_FIRMWARE_EDID is not set | ||
634 | # CONFIG_FB_DDC is not set | ||
635 | CONFIG_FB_CFB_FILLRECT=y | ||
636 | CONFIG_FB_CFB_COPYAREA=y | ||
637 | CONFIG_FB_CFB_IMAGEBLIT=y | ||
638 | # CONFIG_FB_SYS_FILLRECT is not set | ||
639 | # CONFIG_FB_SYS_COPYAREA is not set | ||
640 | # CONFIG_FB_SYS_IMAGEBLIT is not set | ||
641 | # CONFIG_FB_SYS_FOPS is not set | ||
642 | CONFIG_FB_DEFERRED_IO=y | ||
643 | # CONFIG_FB_SVGALIB is not set | ||
644 | # CONFIG_FB_MACMODES is not set | ||
645 | # CONFIG_FB_BACKLIGHT is not set | ||
646 | CONFIG_FB_MODE_HELPERS=y | ||
647 | CONFIG_FB_TILEBLITTING=y | ||
648 | |||
649 | # | ||
650 | # Frame buffer hardware drivers | ||
651 | # | ||
652 | # CONFIG_FB_S1D13XXX is not set | ||
653 | CONFIG_FB_MSM=y | ||
654 | # CONFIG_FB_GOLDFISH is not set | ||
655 | # CONFIG_FB_VIRTUAL is not set | ||
656 | |||
657 | # | ||
658 | # Console display driver support | ||
659 | # | ||
660 | # CONFIG_VGA_CONSOLE is not set | ||
661 | CONFIG_DUMMY_CONSOLE=y | ||
662 | CONFIG_FRAMEBUFFER_CONSOLE=y | ||
663 | # CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set | ||
664 | # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set | ||
665 | # CONFIG_FONTS is not set | ||
666 | CONFIG_FONT_8x8=y | ||
667 | CONFIG_FONT_8x16=y | ||
668 | # CONFIG_LOGO is not set | ||
669 | |||
670 | # | ||
671 | # Sound | ||
672 | # | ||
673 | # CONFIG_SOUND is not set | ||
674 | CONFIG_HID_SUPPORT=y | ||
675 | CONFIG_HID=y | ||
676 | # CONFIG_HID_DEBUG is not set | ||
677 | CONFIG_USB_SUPPORT=y | ||
678 | CONFIG_USB_ARCH_HAS_HCD=y | ||
679 | # CONFIG_USB_ARCH_HAS_OHCI is not set | ||
680 | # CONFIG_USB_ARCH_HAS_EHCI is not set | ||
681 | # CONFIG_USB is not set | ||
682 | |||
683 | # | ||
684 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' | ||
685 | # | ||
686 | |||
687 | # | ||
688 | # USB Gadget Support | ||
689 | # | ||
690 | # CONFIG_USB_GADGET is not set | ||
691 | |||
692 | # | ||
693 | # USB Function Support | ||
694 | # | ||
695 | CONFIG_USB_FUNCTION=y | ||
696 | CONFIG_USB_FUNCTION_MSM_HSUSB=y | ||
697 | # CONFIG_USB_FUNCTION_NULL is not set | ||
698 | # CONFIG_USB_FUNCTION_ZERO is not set | ||
699 | # CONFIG_USB_FUNCTION_LOOPBACK is not set | ||
700 | CONFIG_USB_FUNCTION_ADB=y | ||
701 | # CONFIG_MMC is not set | ||
702 | CONFIG_RTC_LIB=y | ||
703 | # CONFIG_RTC_CLASS is not set | ||
704 | |||
705 | # | ||
706 | # DMA Engine support | ||
707 | # | ||
708 | # CONFIG_DMA_ENGINE is not set | ||
709 | |||
710 | # | ||
711 | # DMA Clients | ||
712 | # | ||
713 | |||
714 | # | ||
715 | # DMA Devices | ||
716 | # | ||
717 | |||
718 | # | ||
719 | # Android | ||
720 | # | ||
721 | # CONFIG_ANDROID_GADGET is not set | ||
722 | # CONFIG_ANDROID_RAM_CONSOLE is not set | ||
723 | CONFIG_ANDROID_LOGGER=y | ||
724 | CONFIG_ANDROID_VIBRATOR=y | ||
725 | |||
726 | # | ||
727 | # File systems | ||
728 | # | ||
729 | # CONFIG_EXT2_FS is not set | ||
730 | # CONFIG_EXT3_FS is not set | ||
731 | # CONFIG_EXT4DEV_FS is not set | ||
732 | # CONFIG_REISERFS_FS is not set | ||
733 | # CONFIG_JFS_FS is not set | ||
734 | # CONFIG_FS_POSIX_ACL is not set | ||
735 | # CONFIG_XFS_FS is not set | ||
736 | # CONFIG_GFS2_FS is not set | ||
737 | # CONFIG_OCFS2_FS is not set | ||
738 | # CONFIG_MINIX_FS is not set | ||
739 | # CONFIG_ROMFS_FS is not set | ||
740 | CONFIG_INOTIFY=y | ||
741 | CONFIG_INOTIFY_USER=y | ||
742 | # CONFIG_QUOTA is not set | ||
743 | CONFIG_DNOTIFY=y | ||
744 | # CONFIG_AUTOFS_FS is not set | ||
745 | # CONFIG_AUTOFS4_FS is not set | ||
746 | # CONFIG_FUSE_FS is not set | ||
747 | |||
748 | # | ||
749 | # CD-ROM/DVD Filesystems | ||
750 | # | ||
751 | # CONFIG_ISO9660_FS is not set | ||
752 | # CONFIG_UDF_FS is not set | ||
753 | |||
754 | # | ||
755 | # DOS/FAT/NT Filesystems | ||
756 | # | ||
757 | # CONFIG_MSDOS_FS is not set | ||
758 | # CONFIG_VFAT_FS is not set | ||
759 | # CONFIG_NTFS_FS is not set | ||
760 | |||
761 | # | ||
762 | # Pseudo filesystems | ||
763 | # | ||
764 | CONFIG_PROC_FS=y | ||
765 | CONFIG_PROC_SYSCTL=y | ||
766 | CONFIG_SYSFS=y | ||
767 | CONFIG_TMPFS=y | ||
768 | # CONFIG_TMPFS_POSIX_ACL is not set | ||
769 | # CONFIG_HUGETLB_PAGE is not set | ||
770 | CONFIG_RAMFS=y | ||
771 | # CONFIG_CONFIGFS_FS is not set | ||
772 | |||
773 | # | ||
774 | # Miscellaneous filesystems | ||
775 | # | ||
776 | # CONFIG_ADFS_FS is not set | ||
777 | # CONFIG_AFFS_FS is not set | ||
778 | # CONFIG_HFS_FS is not set | ||
779 | # CONFIG_HFSPLUS_FS is not set | ||
780 | # CONFIG_BEFS_FS is not set | ||
781 | # CONFIG_BFS_FS is not set | ||
782 | # CONFIG_EFS_FS is not set | ||
783 | CONFIG_YAFFS_FS=y | ||
784 | CONFIG_YAFFS_YAFFS1=y | ||
785 | # CONFIG_YAFFS_9BYTE_TAGS is not set | ||
786 | # CONFIG_YAFFS_DOES_ECC is not set | ||
787 | CONFIG_YAFFS_YAFFS2=y | ||
788 | CONFIG_YAFFS_AUTO_YAFFS2=y | ||
789 | # CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set | ||
790 | CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS=10 | ||
791 | # CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set | ||
792 | # CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set | ||
793 | CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y | ||
794 | # CONFIG_JFFS2_FS is not set | ||
795 | # CONFIG_CRAMFS is not set | ||
796 | # CONFIG_VXFS_FS is not set | ||
797 | # CONFIG_HPFS_FS is not set | ||
798 | # CONFIG_QNX4FS_FS is not set | ||
799 | # CONFIG_SYSV_FS is not set | ||
800 | # CONFIG_UFS_FS is not set | ||
801 | |||
802 | # | ||
803 | # Network File Systems | ||
804 | # | ||
805 | # CONFIG_NFS_FS is not set | ||
806 | # CONFIG_NFSD is not set | ||
807 | # CONFIG_SMB_FS is not set | ||
808 | # CONFIG_CIFS is not set | ||
809 | # CONFIG_NCP_FS is not set | ||
810 | # CONFIG_CODA_FS is not set | ||
811 | # CONFIG_AFS_FS is not set | ||
812 | |||
813 | # | ||
814 | # Partition Types | ||
815 | # | ||
816 | # CONFIG_PARTITION_ADVANCED is not set | ||
817 | CONFIG_MSDOS_PARTITION=y | ||
818 | |||
819 | # | ||
820 | # Native Language Support | ||
821 | # | ||
822 | # CONFIG_NLS is not set | ||
823 | |||
824 | # | ||
825 | # Distributed Lock Manager | ||
826 | # | ||
827 | # CONFIG_DLM is not set | ||
828 | |||
829 | # | ||
830 | # Profiling support | ||
831 | # | ||
832 | # CONFIG_PROFILING is not set | ||
833 | |||
834 | # | ||
835 | # Kernel hacking | ||
836 | # | ||
837 | # CONFIG_PRINTK_TIME is not set | ||
838 | CONFIG_ENABLE_MUST_CHECK=y | ||
839 | CONFIG_MAGIC_SYSRQ=y | ||
840 | # CONFIG_UNUSED_SYMBOLS is not set | ||
841 | # CONFIG_DEBUG_FS is not set | ||
842 | # CONFIG_HEADERS_CHECK is not set | ||
843 | CONFIG_DEBUG_KERNEL=y | ||
844 | # CONFIG_DEBUG_SHIRQ is not set | ||
845 | CONFIG_DETECT_SOFTLOCKUP=y | ||
846 | CONFIG_SCHED_DEBUG=y | ||
847 | CONFIG_SCHEDSTATS=y | ||
848 | # CONFIG_TIMER_STATS is not set | ||
849 | # CONFIG_DEBUG_SLAB is not set | ||
850 | CONFIG_DEBUG_PREEMPT=y | ||
851 | # CONFIG_DEBUG_RT_MUTEXES is not set | ||
852 | # CONFIG_RT_MUTEX_TESTER is not set | ||
853 | # CONFIG_DEBUG_SPINLOCK is not set | ||
854 | CONFIG_DEBUG_MUTEXES=y | ||
855 | # CONFIG_DEBUG_LOCK_ALLOC is not set | ||
856 | # CONFIG_PROVE_LOCKING is not set | ||
857 | # CONFIG_LOCK_STAT is not set | ||
858 | CONFIG_DEBUG_SPINLOCK_SLEEP=y | ||
859 | # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set | ||
860 | # CONFIG_DEBUG_KOBJECT is not set | ||
861 | CONFIG_DEBUG_BUGVERBOSE=y | ||
862 | CONFIG_DEBUG_INFO=y | ||
863 | # CONFIG_DEBUG_VM is not set | ||
864 | # CONFIG_DEBUG_LIST is not set | ||
865 | CONFIG_FRAME_POINTER=y | ||
866 | # CONFIG_FORCED_INLINING is not set | ||
867 | # CONFIG_FAULT_INJECTION is not set | ||
868 | # CONFIG_DEBUG_USER is not set | ||
869 | # CONFIG_DEBUG_ERRORS is not set | ||
870 | CONFIG_DEBUG_LL=y | ||
871 | # CONFIG_DEBUG_ICEDCC is not set | ||
872 | |||
873 | # | ||
874 | # Security options | ||
875 | # | ||
876 | # CONFIG_KEYS is not set | ||
877 | # CONFIG_SECURITY is not set | ||
878 | # CONFIG_CRYPTO is not set | ||
879 | |||
880 | # | ||
881 | # Library routines | ||
882 | # | ||
883 | CONFIG_BITREVERSE=y | ||
884 | CONFIG_CRC_CCITT=y | ||
885 | # CONFIG_CRC16 is not set | ||
886 | # CONFIG_CRC_ITU_T is not set | ||
887 | CONFIG_CRC32=y | ||
888 | # CONFIG_CRC7 is not set | ||
889 | # CONFIG_LIBCRC32C is not set | ||
890 | CONFIG_ZLIB_INFLATE=y | ||
891 | CONFIG_ZLIB_DEFLATE=y | ||
892 | CONFIG_PLIST=y | ||
893 | CONFIG_HAS_IOMEM=y | ||
894 | CONFIG_HAS_IOPORT=y | ||
895 | CONFIG_HAS_DMA=y | ||
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 593b56509f4f..faa761921153 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile | |||
@@ -19,6 +19,7 @@ obj-$(CONFIG_ISA_DMA) += dma-isa.o | |||
19 | obj-$(CONFIG_PCI) += bios32.o isa.o | 19 | obj-$(CONFIG_PCI) += bios32.o isa.o |
20 | obj-$(CONFIG_SMP) += smp.o | 20 | obj-$(CONFIG_SMP) += smp.o |
21 | obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o | 21 | obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o |
22 | obj-$(CONFIG_KPROBES) += kprobes.o kprobes-decode.o | ||
22 | obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o | 23 | obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o |
23 | 24 | ||
24 | obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o | 25 | obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o |
diff --git a/arch/arm/kernel/dma-isa.c b/arch/arm/kernel/dma-isa.c index 0a3e9ad297d8..2f080a35a2d9 100644 --- a/arch/arm/kernel/dma-isa.c +++ b/arch/arm/kernel/dma-isa.c | |||
@@ -216,7 +216,7 @@ void __init isa_init_dma(dma_t *dma) | |||
216 | 216 | ||
217 | request_dma(DMA_ISA_CASCADE, "cascade"); | 217 | request_dma(DMA_ISA_CASCADE, "cascade"); |
218 | 218 | ||
219 | for (i = 0; i < sizeof(dma_resources) / sizeof(dma_resources[0]); i++) | 219 | for (i = 0; i < ARRAY_SIZE(dma_resources); i++) |
220 | request_resource(&ioport_resource, dma_resources + i); | 220 | request_resource(&ioport_resource, dma_resources + i); |
221 | } | 221 | } |
222 | } | 222 | } |
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 29dec080a604..a46d5b456765 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
@@ -11,8 +11,8 @@ | |||
11 | * | 11 | * |
12 | * Low-level vector interface routines | 12 | * Low-level vector interface routines |
13 | * | 13 | * |
14 | * Note: there is a StrongARM bug in the STMIA rn, {regs}^ instruction that causes | 14 | * Note: there is a StrongARM bug in the STMIA rn, {regs}^ instruction |
15 | * it to save wrong values... Be aware! | 15 | * that causes it to save wrong values... Be aware! |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <asm/memory.h> | 18 | #include <asm/memory.h> |
@@ -58,6 +58,12 @@ | |||
58 | 58 | ||
59 | .endm | 59 | .endm |
60 | 60 | ||
61 | #ifdef CONFIG_KPROBES | ||
62 | .section .kprobes.text,"ax",%progbits | ||
63 | #else | ||
64 | .text | ||
65 | #endif | ||
66 | |||
61 | /* | 67 | /* |
62 | * Invalid mode handlers | 68 | * Invalid mode handlers |
63 | */ | 69 | */ |
@@ -112,8 +118,8 @@ common_invalid: | |||
112 | #define SPFIX(code...) | 118 | #define SPFIX(code...) |
113 | #endif | 119 | #endif |
114 | 120 | ||
115 | .macro svc_entry | 121 | .macro svc_entry, stack_hole=0 |
116 | sub sp, sp, #S_FRAME_SIZE | 122 | sub sp, sp, #(S_FRAME_SIZE + \stack_hole) |
117 | SPFIX( tst sp, #4 ) | 123 | SPFIX( tst sp, #4 ) |
118 | SPFIX( bicne sp, sp, #4 ) | 124 | SPFIX( bicne sp, sp, #4 ) |
119 | stmib sp, {r1 - r12} | 125 | stmib sp, {r1 - r12} |
@@ -121,7 +127,7 @@ common_invalid: | |||
121 | ldmia r0, {r1 - r3} | 127 | ldmia r0, {r1 - r3} |
122 | add r5, sp, #S_SP @ here for interlock avoidance | 128 | add r5, sp, #S_SP @ here for interlock avoidance |
123 | mov r4, #-1 @ "" "" "" "" | 129 | mov r4, #-1 @ "" "" "" "" |
124 | add r0, sp, #S_FRAME_SIZE @ "" "" "" "" | 130 | add r0, sp, #(S_FRAME_SIZE + \stack_hole) |
125 | SPFIX( addne r0, r0, #4 ) | 131 | SPFIX( addne r0, r0, #4 ) |
126 | str r1, [sp] @ save the "real" r0 copied | 132 | str r1, [sp] @ save the "real" r0 copied |
127 | @ from the exception stack | 133 | @ from the exception stack |
@@ -242,7 +248,14 @@ svc_preempt: | |||
242 | 248 | ||
243 | .align 5 | 249 | .align 5 |
244 | __und_svc: | 250 | __und_svc: |
251 | #ifdef CONFIG_KPROBES | ||
252 | @ If a kprobe is about to simulate a "stmdb sp..." instruction, | ||
253 | @ it obviously needs free stack space which then will belong to | ||
254 | @ the saved context. | ||
255 | svc_entry 64 | ||
256 | #else | ||
245 | svc_entry | 257 | svc_entry |
258 | #endif | ||
246 | 259 | ||
247 | @ | 260 | @ |
248 | @ call emulation code, which returns using r9 if it has emulated | 261 | @ call emulation code, which returns using r9 if it has emulated |
@@ -480,6 +493,13 @@ __und_usr: | |||
480 | * co-processor instructions. However, we have to watch out | 493 | * co-processor instructions. However, we have to watch out |
481 | * for the ARM6/ARM7 SWI bug. | 494 | * for the ARM6/ARM7 SWI bug. |
482 | * | 495 | * |
496 | * NEON is a special case that has to be handled here. Not all | ||
497 | * NEON instructions are co-processor instructions, so we have | ||
498 | * to make a special case of checking for them. Plus, there's | ||
499 | * five groups of them, so we have a table of mask/opcode pairs | ||
500 | * to check against, and if any match then we branch off into the | ||
501 | * NEON handler code. | ||
502 | * | ||
483 | * Emulators may wish to make use of the following registers: | 503 | * Emulators may wish to make use of the following registers: |
484 | * r0 = instruction opcode. | 504 | * r0 = instruction opcode. |
485 | * r2 = PC+4 | 505 | * r2 = PC+4 |
@@ -488,6 +508,23 @@ __und_usr: | |||
488 | * lr = unrecognised instruction return address | 508 | * lr = unrecognised instruction return address |
489 | */ | 509 | */ |
490 | call_fpe: | 510 | call_fpe: |
511 | #ifdef CONFIG_NEON | ||
512 | adr r6, .LCneon_opcodes | ||
513 | 2: | ||
514 | ldr r7, [r6], #4 @ mask value | ||
515 | cmp r7, #0 @ end mask? | ||
516 | beq 1f | ||
517 | and r8, r0, r7 | ||
518 | ldr r7, [r6], #4 @ opcode bits matching in mask | ||
519 | cmp r8, r7 @ NEON instruction? | ||
520 | bne 2b | ||
521 | get_thread_info r10 | ||
522 | mov r7, #1 | ||
523 | strb r7, [r10, #TI_USED_CP + 10] @ mark CP#10 as used | ||
524 | strb r7, [r10, #TI_USED_CP + 11] @ mark CP#11 as used | ||
525 | b do_vfp @ let VFP handler handle this | ||
526 | 1: | ||
527 | #endif | ||
491 | tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27 | 528 | tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27 |
492 | #if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710) | 529 | #if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710) |
493 | and r8, r0, #0x0f000000 @ mask out op-code bits | 530 | and r8, r0, #0x0f000000 @ mask out op-code bits |
@@ -537,6 +574,20 @@ call_fpe: | |||
537 | mov pc, lr @ CP#14 (Debug) | 574 | mov pc, lr @ CP#14 (Debug) |
538 | mov pc, lr @ CP#15 (Control) | 575 | mov pc, lr @ CP#15 (Control) |
539 | 576 | ||
577 | #ifdef CONFIG_NEON | ||
578 | .align 6 | ||
579 | |||
580 | .LCneon_opcodes: | ||
581 | .word 0xfe000000 @ mask | ||
582 | .word 0xf2000000 @ opcode | ||
583 | |||
584 | .word 0xff100000 @ mask | ||
585 | .word 0xf4000000 @ opcode | ||
586 | |||
587 | .word 0x00000000 @ mask | ||
588 | .word 0x00000000 @ opcode | ||
589 | #endif | ||
590 | |||
540 | do_fpe: | 591 | do_fpe: |
541 | enable_irq | 592 | enable_irq |
542 | ldr r4, .LCfp | 593 | ldr r4, .LCfp |
@@ -555,7 +606,7 @@ do_fpe: | |||
555 | .data | 606 | .data |
556 | ENTRY(fp_enter) | 607 | ENTRY(fp_enter) |
557 | .word no_fp | 608 | .word no_fp |
558 | .text | 609 | .previous |
559 | 610 | ||
560 | no_fp: mov pc, lr | 611 | no_fp: mov pc, lr |
561 | 612 | ||
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 33e6cc2ffd3b..6c90c50a9ee3 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S | |||
@@ -72,7 +72,7 @@ no_work_pending: | |||
72 | ldr r1, [sp, #S_PSR] @ get calling cpsr | 72 | ldr r1, [sp, #S_PSR] @ get calling cpsr |
73 | ldr lr, [sp, #S_PC]! @ get pc | 73 | ldr lr, [sp, #S_PC]! @ get pc |
74 | msr spsr_cxsf, r1 @ save in spsr_svc | 74 | msr spsr_cxsf, r1 @ save in spsr_svc |
75 | ldmdb sp, {r0 - lr}^ @ get calling r1 - lr | 75 | ldmdb sp, {r0 - lr}^ @ get calling r0 - lr |
76 | mov r0, r0 | 76 | mov r0, r0 |
77 | add sp, sp, #S_FRAME_SIZE - S_PC | 77 | add sp, sp, #S_FRAME_SIZE - S_PC |
78 | movs pc, lr @ return & move spsr_svc into cpsr | 78 | movs pc, lr @ return & move spsr_svc into cpsr |
diff --git a/arch/arm/kernel/kprobes-decode.c b/arch/arm/kernel/kprobes-decode.c new file mode 100644 index 000000000000..d51bc8b60557 --- /dev/null +++ b/arch/arm/kernel/kprobes-decode.c | |||
@@ -0,0 +1,1529 @@ | |||
1 | /* | ||
2 | * arch/arm/kernel/kprobes-decode.c | ||
3 | * | ||
4 | * Copyright (C) 2006, 2007 Motorola Inc. | ||
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 | * 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 GNU | ||
13 | * General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | /* | ||
17 | * We do not have hardware single-stepping on ARM, This | ||
18 | * effort is further complicated by the ARM not having a | ||
19 | * "next PC" register. Instructions that change the PC | ||
20 | * can't be safely single-stepped in a MP environment, so | ||
21 | * we have a lot of work to do: | ||
22 | * | ||
23 | * In the prepare phase: | ||
24 | * *) If it is an instruction that does anything | ||
25 | * with the CPU mode, we reject it for a kprobe. | ||
26 | * (This is out of laziness rather than need. The | ||
27 | * instructions could be simulated.) | ||
28 | * | ||
29 | * *) Otherwise, decode the instruction rewriting its | ||
30 | * registers to take fixed, ordered registers and | ||
31 | * setting a handler for it to run the instruction. | ||
32 | * | ||
33 | * In the execution phase by an instruction's handler: | ||
34 | * | ||
35 | * *) If the PC is written to by the instruction, the | ||
36 | * instruction must be fully simulated in software. | ||
37 | * If it is a conditional instruction, the handler | ||
38 | * will use insn[0] to copy its condition code to | ||
39 | * set r0 to 1 and insn[1] to "mov pc, lr" to return. | ||
40 | * | ||
41 | * *) Otherwise, a modified form of the instruction is | ||
42 | * directly executed. Its handler calls the | ||
43 | * instruction in insn[0]. In insn[1] is a | ||
44 | * "mov pc, lr" to return. | ||
45 | * | ||
46 | * Before calling, load up the reordered registers | ||
47 | * from the original instruction's registers. If one | ||
48 | * of the original input registers is the PC, compute | ||
49 | * and adjust the appropriate input register. | ||
50 | * | ||
51 | * After call completes, copy the output registers to | ||
52 | * the original instruction's original registers. | ||
53 | * | ||
54 | * We don't use a real breakpoint instruction since that | ||
55 | * would have us in the kernel go from SVC mode to SVC | ||
56 | * mode losing the link register. Instead we use an | ||
57 | * undefined instruction. To simplify processing, the | ||
58 | * undefined instruction used for kprobes must be reserved | ||
59 | * exclusively for kprobes use. | ||
60 | * | ||
61 | * TODO: ifdef out some instruction decoding based on architecture. | ||
62 | */ | ||
63 | |||
64 | #include <linux/kernel.h> | ||
65 | #include <linux/kprobes.h> | ||
66 | |||
67 | #define sign_extend(x, signbit) ((x) | (0 - ((x) & (1 << (signbit))))) | ||
68 | |||
69 | #define branch_displacement(insn) sign_extend(((insn) & 0xffffff) << 2, 25) | ||
70 | |||
71 | #define PSR_fs (PSR_f|PSR_s) | ||
72 | |||
73 | #define KPROBE_RETURN_INSTRUCTION 0xe1a0f00e /* mov pc, lr */ | ||
74 | #define SET_R0_TRUE_INSTRUCTION 0xe3a00001 /* mov r0, #1 */ | ||
75 | |||
76 | #define truecc_insn(insn) (((insn) & 0xf0000000) | \ | ||
77 | (SET_R0_TRUE_INSTRUCTION & 0x0fffffff)) | ||
78 | |||
79 | typedef long (insn_0arg_fn_t)(void); | ||
80 | typedef long (insn_1arg_fn_t)(long); | ||
81 | typedef long (insn_2arg_fn_t)(long, long); | ||
82 | typedef long (insn_3arg_fn_t)(long, long, long); | ||
83 | typedef long (insn_4arg_fn_t)(long, long, long, long); | ||
84 | typedef long long (insn_llret_0arg_fn_t)(void); | ||
85 | typedef long long (insn_llret_3arg_fn_t)(long, long, long); | ||
86 | typedef long long (insn_llret_4arg_fn_t)(long, long, long, long); | ||
87 | |||
88 | union reg_pair { | ||
89 | long long dr; | ||
90 | #ifdef __LITTLE_ENDIAN | ||
91 | struct { long r0, r1; }; | ||
92 | #else | ||
93 | struct { long r1, r0; }; | ||
94 | #endif | ||
95 | }; | ||
96 | |||
97 | /* | ||
98 | * For STR and STM instructions, an ARM core may choose to use either | ||
99 | * a +8 or a +12 displacement from the current instruction's address. | ||
100 | * Whichever value is chosen for a given core, it must be the same for | ||
101 | * both instructions and may not change. This function measures it. | ||
102 | */ | ||
103 | |||
104 | static int str_pc_offset; | ||
105 | |||
106 | static void __init find_str_pc_offset(void) | ||
107 | { | ||
108 | int addr, scratch, ret; | ||
109 | |||
110 | __asm__ ( | ||
111 | "sub %[ret], pc, #4 \n\t" | ||
112 | "str pc, %[addr] \n\t" | ||
113 | "ldr %[scr], %[addr] \n\t" | ||
114 | "sub %[ret], %[scr], %[ret] \n\t" | ||
115 | : [ret] "=r" (ret), [scr] "=r" (scratch), [addr] "+m" (addr)); | ||
116 | |||
117 | str_pc_offset = ret; | ||
118 | } | ||
119 | |||
120 | /* | ||
121 | * The insnslot_?arg_r[w]flags() functions below are to keep the | ||
122 | * msr -> *fn -> mrs instruction sequences indivisible so that | ||
123 | * the state of the CPSR flags aren't inadvertently modified | ||
124 | * just before or just after the call. | ||
125 | */ | ||
126 | |||
127 | static inline long __kprobes | ||
128 | insnslot_0arg_rflags(long cpsr, insn_0arg_fn_t *fn) | ||
129 | { | ||
130 | register long ret asm("r0"); | ||
131 | |||
132 | __asm__ __volatile__ ( | ||
133 | "msr cpsr_fs, %[cpsr] \n\t" | ||
134 | "mov lr, pc \n\t" | ||
135 | "mov pc, %[fn] \n\t" | ||
136 | : "=r" (ret) | ||
137 | : [cpsr] "r" (cpsr), [fn] "r" (fn) | ||
138 | : "lr", "cc" | ||
139 | ); | ||
140 | return ret; | ||
141 | } | ||
142 | |||
143 | static inline long long __kprobes | ||
144 | insnslot_llret_0arg_rflags(long cpsr, insn_llret_0arg_fn_t *fn) | ||
145 | { | ||
146 | register long ret0 asm("r0"); | ||
147 | register long ret1 asm("r1"); | ||
148 | union reg_pair fnr; | ||
149 | |||
150 | __asm__ __volatile__ ( | ||
151 | "msr cpsr_fs, %[cpsr] \n\t" | ||
152 | "mov lr, pc \n\t" | ||
153 | "mov pc, %[fn] \n\t" | ||
154 | : "=r" (ret0), "=r" (ret1) | ||
155 | : [cpsr] "r" (cpsr), [fn] "r" (fn) | ||
156 | : "lr", "cc" | ||
157 | ); | ||
158 | fnr.r0 = ret0; | ||
159 | fnr.r1 = ret1; | ||
160 | return fnr.dr; | ||
161 | } | ||
162 | |||
163 | static inline long __kprobes | ||
164 | insnslot_1arg_rflags(long r0, long cpsr, insn_1arg_fn_t *fn) | ||
165 | { | ||
166 | register long rr0 asm("r0") = r0; | ||
167 | register long ret asm("r0"); | ||
168 | |||
169 | __asm__ __volatile__ ( | ||
170 | "msr cpsr_fs, %[cpsr] \n\t" | ||
171 | "mov lr, pc \n\t" | ||
172 | "mov pc, %[fn] \n\t" | ||
173 | : "=r" (ret) | ||
174 | : "0" (rr0), [cpsr] "r" (cpsr), [fn] "r" (fn) | ||
175 | : "lr", "cc" | ||
176 | ); | ||
177 | return ret; | ||
178 | } | ||
179 | |||
180 | static inline long __kprobes | ||
181 | insnslot_2arg_rflags(long r0, long r1, long cpsr, insn_2arg_fn_t *fn) | ||
182 | { | ||
183 | register long rr0 asm("r0") = r0; | ||
184 | register long rr1 asm("r1") = r1; | ||
185 | register long ret asm("r0"); | ||
186 | |||
187 | __asm__ __volatile__ ( | ||
188 | "msr cpsr_fs, %[cpsr] \n\t" | ||
189 | "mov lr, pc \n\t" | ||
190 | "mov pc, %[fn] \n\t" | ||
191 | : "=r" (ret) | ||
192 | : "0" (rr0), "r" (rr1), | ||
193 | [cpsr] "r" (cpsr), [fn] "r" (fn) | ||
194 | : "lr", "cc" | ||
195 | ); | ||
196 | return ret; | ||
197 | } | ||
198 | |||
199 | static inline long __kprobes | ||
200 | insnslot_3arg_rflags(long r0, long r1, long r2, long cpsr, insn_3arg_fn_t *fn) | ||
201 | { | ||
202 | register long rr0 asm("r0") = r0; | ||
203 | register long rr1 asm("r1") = r1; | ||
204 | register long rr2 asm("r2") = r2; | ||
205 | register long ret asm("r0"); | ||
206 | |||
207 | __asm__ __volatile__ ( | ||
208 | "msr cpsr_fs, %[cpsr] \n\t" | ||
209 | "mov lr, pc \n\t" | ||
210 | "mov pc, %[fn] \n\t" | ||
211 | : "=r" (ret) | ||
212 | : "0" (rr0), "r" (rr1), "r" (rr2), | ||
213 | [cpsr] "r" (cpsr), [fn] "r" (fn) | ||
214 | : "lr", "cc" | ||
215 | ); | ||
216 | return ret; | ||
217 | } | ||
218 | |||
219 | static inline long long __kprobes | ||
220 | insnslot_llret_3arg_rflags(long r0, long r1, long r2, long cpsr, | ||
221 | insn_llret_3arg_fn_t *fn) | ||
222 | { | ||
223 | register long rr0 asm("r0") = r0; | ||
224 | register long rr1 asm("r1") = r1; | ||
225 | register long rr2 asm("r2") = r2; | ||
226 | register long ret0 asm("r0"); | ||
227 | register long ret1 asm("r1"); | ||
228 | union reg_pair fnr; | ||
229 | |||
230 | __asm__ __volatile__ ( | ||
231 | "msr cpsr_fs, %[cpsr] \n\t" | ||
232 | "mov lr, pc \n\t" | ||
233 | "mov pc, %[fn] \n\t" | ||
234 | : "=r" (ret0), "=r" (ret1) | ||
235 | : "0" (rr0), "r" (rr1), "r" (rr2), | ||
236 | [cpsr] "r" (cpsr), [fn] "r" (fn) | ||
237 | : "lr", "cc" | ||
238 | ); | ||
239 | fnr.r0 = ret0; | ||
240 | fnr.r1 = ret1; | ||
241 | return fnr.dr; | ||
242 | } | ||
243 | |||
244 | static inline long __kprobes | ||
245 | insnslot_4arg_rflags(long r0, long r1, long r2, long r3, long cpsr, | ||
246 | insn_4arg_fn_t *fn) | ||
247 | { | ||
248 | register long rr0 asm("r0") = r0; | ||
249 | register long rr1 asm("r1") = r1; | ||
250 | register long rr2 asm("r2") = r2; | ||
251 | register long rr3 asm("r3") = r3; | ||
252 | register long ret asm("r0"); | ||
253 | |||
254 | __asm__ __volatile__ ( | ||
255 | "msr cpsr_fs, %[cpsr] \n\t" | ||
256 | "mov lr, pc \n\t" | ||
257 | "mov pc, %[fn] \n\t" | ||
258 | : "=r" (ret) | ||
259 | : "0" (rr0), "r" (rr1), "r" (rr2), "r" (rr3), | ||
260 | [cpsr] "r" (cpsr), [fn] "r" (fn) | ||
261 | : "lr", "cc" | ||
262 | ); | ||
263 | return ret; | ||
264 | } | ||
265 | |||
266 | static inline long __kprobes | ||
267 | insnslot_1arg_rwflags(long r0, long *cpsr, insn_1arg_fn_t *fn) | ||
268 | { | ||
269 | register long rr0 asm("r0") = r0; | ||
270 | register long ret asm("r0"); | ||
271 | long oldcpsr = *cpsr; | ||
272 | long newcpsr; | ||
273 | |||
274 | __asm__ __volatile__ ( | ||
275 | "msr cpsr_fs, %[oldcpsr] \n\t" | ||
276 | "mov lr, pc \n\t" | ||
277 | "mov pc, %[fn] \n\t" | ||
278 | "mrs %[newcpsr], cpsr \n\t" | ||
279 | : "=r" (ret), [newcpsr] "=r" (newcpsr) | ||
280 | : "0" (rr0), [oldcpsr] "r" (oldcpsr), [fn] "r" (fn) | ||
281 | : "lr", "cc" | ||
282 | ); | ||
283 | *cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs); | ||
284 | return ret; | ||
285 | } | ||
286 | |||
287 | static inline long __kprobes | ||
288 | insnslot_2arg_rwflags(long r0, long r1, long *cpsr, insn_2arg_fn_t *fn) | ||
289 | { | ||
290 | register long rr0 asm("r0") = r0; | ||
291 | register long rr1 asm("r1") = r1; | ||
292 | register long ret asm("r0"); | ||
293 | long oldcpsr = *cpsr; | ||
294 | long newcpsr; | ||
295 | |||
296 | __asm__ __volatile__ ( | ||
297 | "msr cpsr_fs, %[oldcpsr] \n\t" | ||
298 | "mov lr, pc \n\t" | ||
299 | "mov pc, %[fn] \n\t" | ||
300 | "mrs %[newcpsr], cpsr \n\t" | ||
301 | : "=r" (ret), [newcpsr] "=r" (newcpsr) | ||
302 | : "0" (rr0), "r" (rr1), [oldcpsr] "r" (oldcpsr), [fn] "r" (fn) | ||
303 | : "lr", "cc" | ||
304 | ); | ||
305 | *cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs); | ||
306 | return ret; | ||
307 | } | ||
308 | |||
309 | static inline long __kprobes | ||
310 | insnslot_3arg_rwflags(long r0, long r1, long r2, long *cpsr, | ||
311 | insn_3arg_fn_t *fn) | ||
312 | { | ||
313 | register long rr0 asm("r0") = r0; | ||
314 | register long rr1 asm("r1") = r1; | ||
315 | register long rr2 asm("r2") = r2; | ||
316 | register long ret asm("r0"); | ||
317 | long oldcpsr = *cpsr; | ||
318 | long newcpsr; | ||
319 | |||
320 | __asm__ __volatile__ ( | ||
321 | "msr cpsr_fs, %[oldcpsr] \n\t" | ||
322 | "mov lr, pc \n\t" | ||
323 | "mov pc, %[fn] \n\t" | ||
324 | "mrs %[newcpsr], cpsr \n\t" | ||
325 | : "=r" (ret), [newcpsr] "=r" (newcpsr) | ||
326 | : "0" (rr0), "r" (rr1), "r" (rr2), | ||
327 | [oldcpsr] "r" (oldcpsr), [fn] "r" (fn) | ||
328 | : "lr", "cc" | ||
329 | ); | ||
330 | *cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs); | ||
331 | return ret; | ||
332 | } | ||
333 | |||
334 | static inline long __kprobes | ||
335 | insnslot_4arg_rwflags(long r0, long r1, long r2, long r3, long *cpsr, | ||
336 | insn_4arg_fn_t *fn) | ||
337 | { | ||
338 | register long rr0 asm("r0") = r0; | ||
339 | register long rr1 asm("r1") = r1; | ||
340 | register long rr2 asm("r2") = r2; | ||
341 | register long rr3 asm("r3") = r3; | ||
342 | register long ret asm("r0"); | ||
343 | long oldcpsr = *cpsr; | ||
344 | long newcpsr; | ||
345 | |||
346 | __asm__ __volatile__ ( | ||
347 | "msr cpsr_fs, %[oldcpsr] \n\t" | ||
348 | "mov lr, pc \n\t" | ||
349 | "mov pc, %[fn] \n\t" | ||
350 | "mrs %[newcpsr], cpsr \n\t" | ||
351 | : "=r" (ret), [newcpsr] "=r" (newcpsr) | ||
352 | : "0" (rr0), "r" (rr1), "r" (rr2), "r" (rr3), | ||
353 | [oldcpsr] "r" (oldcpsr), [fn] "r" (fn) | ||
354 | : "lr", "cc" | ||
355 | ); | ||
356 | *cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs); | ||
357 | return ret; | ||
358 | } | ||
359 | |||
360 | static inline long long __kprobes | ||
361 | insnslot_llret_4arg_rwflags(long r0, long r1, long r2, long r3, long *cpsr, | ||
362 | insn_llret_4arg_fn_t *fn) | ||
363 | { | ||
364 | register long rr0 asm("r0") = r0; | ||
365 | register long rr1 asm("r1") = r1; | ||
366 | register long rr2 asm("r2") = r2; | ||
367 | register long rr3 asm("r3") = r3; | ||
368 | register long ret0 asm("r0"); | ||
369 | register long ret1 asm("r1"); | ||
370 | long oldcpsr = *cpsr; | ||
371 | long newcpsr; | ||
372 | union reg_pair fnr; | ||
373 | |||
374 | __asm__ __volatile__ ( | ||
375 | "msr cpsr_fs, %[oldcpsr] \n\t" | ||
376 | "mov lr, pc \n\t" | ||
377 | "mov pc, %[fn] \n\t" | ||
378 | "mrs %[newcpsr], cpsr \n\t" | ||
379 | : "=r" (ret0), "=r" (ret1), [newcpsr] "=r" (newcpsr) | ||
380 | : "0" (rr0), "r" (rr1), "r" (rr2), "r" (rr3), | ||
381 | [oldcpsr] "r" (oldcpsr), [fn] "r" (fn) | ||
382 | : "lr", "cc" | ||
383 | ); | ||
384 | *cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs); | ||
385 | fnr.r0 = ret0; | ||
386 | fnr.r1 = ret1; | ||
387 | return fnr.dr; | ||
388 | } | ||
389 | |||
390 | /* | ||
391 | * To avoid the complications of mimicing single-stepping on a | ||
392 | * processor without a Next-PC or a single-step mode, and to | ||
393 | * avoid having to deal with the side-effects of boosting, we | ||
394 | * simulate or emulate (almost) all ARM instructions. | ||
395 | * | ||
396 | * "Simulation" is where the instruction's behavior is duplicated in | ||
397 | * C code. "Emulation" is where the original instruction is rewritten | ||
398 | * and executed, often by altering its registers. | ||
399 | * | ||
400 | * By having all behavior of the kprobe'd instruction completed before | ||
401 | * returning from the kprobe_handler(), all locks (scheduler and | ||
402 | * interrupt) can safely be released. There is no need for secondary | ||
403 | * breakpoints, no race with MP or preemptable kernels, nor having to | ||
404 | * clean up resources counts at a later time impacting overall system | ||
405 | * performance. By rewriting the instruction, only the minimum registers | ||
406 | * need to be loaded and saved back optimizing performance. | ||
407 | * | ||
408 | * Calling the insnslot_*_rwflags version of a function doesn't hurt | ||
409 | * anything even when the CPSR flags aren't updated by the | ||
410 | * instruction. It's just a little slower in return for saving | ||
411 | * a little space by not having a duplicate function that doesn't | ||
412 | * update the flags. (The same optimization can be said for | ||
413 | * instructions that do or don't perform register writeback) | ||
414 | * Also, instructions can either read the flags, only write the | ||
415 | * flags, or read and write the flags. To save combinations | ||
416 | * rather than for sheer performance, flag functions just assume | ||
417 | * read and write of flags. | ||
418 | */ | ||
419 | |||
420 | static void __kprobes simulate_bbl(struct kprobe *p, struct pt_regs *regs) | ||
421 | { | ||
422 | insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; | ||
423 | kprobe_opcode_t insn = p->opcode; | ||
424 | long iaddr = (long)p->addr; | ||
425 | int disp = branch_displacement(insn); | ||
426 | |||
427 | if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn)) | ||
428 | return; | ||
429 | |||
430 | if (insn & (1 << 24)) | ||
431 | regs->ARM_lr = iaddr + 4; | ||
432 | |||
433 | regs->ARM_pc = iaddr + 8 + disp; | ||
434 | } | ||
435 | |||
436 | static void __kprobes simulate_blx1(struct kprobe *p, struct pt_regs *regs) | ||
437 | { | ||
438 | kprobe_opcode_t insn = p->opcode; | ||
439 | long iaddr = (long)p->addr; | ||
440 | int disp = branch_displacement(insn); | ||
441 | |||
442 | regs->ARM_lr = iaddr + 4; | ||
443 | regs->ARM_pc = iaddr + 8 + disp + ((insn >> 23) & 0x2); | ||
444 | regs->ARM_cpsr |= PSR_T_BIT; | ||
445 | } | ||
446 | |||
447 | static void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs) | ||
448 | { | ||
449 | insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; | ||
450 | kprobe_opcode_t insn = p->opcode; | ||
451 | int rm = insn & 0xf; | ||
452 | long rmv = regs->uregs[rm]; | ||
453 | |||
454 | if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn)) | ||
455 | return; | ||
456 | |||
457 | if (insn & (1 << 5)) | ||
458 | regs->ARM_lr = (long)p->addr + 4; | ||
459 | |||
460 | regs->ARM_pc = rmv & ~0x1; | ||
461 | regs->ARM_cpsr &= ~PSR_T_BIT; | ||
462 | if (rmv & 0x1) | ||
463 | regs->ARM_cpsr |= PSR_T_BIT; | ||
464 | } | ||
465 | |||
466 | static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs) | ||
467 | { | ||
468 | insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; | ||
469 | kprobe_opcode_t insn = p->opcode; | ||
470 | int rn = (insn >> 16) & 0xf; | ||
471 | int lbit = insn & (1 << 20); | ||
472 | int wbit = insn & (1 << 21); | ||
473 | int ubit = insn & (1 << 23); | ||
474 | int pbit = insn & (1 << 24); | ||
475 | long *addr = (long *)regs->uregs[rn]; | ||
476 | int reg_bit_vector; | ||
477 | int reg_count; | ||
478 | |||
479 | if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn)) | ||
480 | return; | ||
481 | |||
482 | reg_count = 0; | ||
483 | reg_bit_vector = insn & 0xffff; | ||
484 | while (reg_bit_vector) { | ||
485 | reg_bit_vector &= (reg_bit_vector - 1); | ||
486 | ++reg_count; | ||
487 | } | ||
488 | |||
489 | if (!ubit) | ||
490 | addr -= reg_count; | ||
491 | addr += (!pbit ^ !ubit); | ||
492 | |||
493 | reg_bit_vector = insn & 0xffff; | ||
494 | while (reg_bit_vector) { | ||
495 | int reg = __ffs(reg_bit_vector); | ||
496 | reg_bit_vector &= (reg_bit_vector - 1); | ||
497 | if (lbit) | ||
498 | regs->uregs[reg] = *addr++; | ||
499 | else | ||
500 | *addr++ = regs->uregs[reg]; | ||
501 | } | ||
502 | |||
503 | if (wbit) { | ||
504 | if (!ubit) | ||
505 | addr -= reg_count; | ||
506 | addr -= (!pbit ^ !ubit); | ||
507 | regs->uregs[rn] = (long)addr; | ||
508 | } | ||
509 | } | ||
510 | |||
511 | static void __kprobes simulate_stm1_pc(struct kprobe *p, struct pt_regs *regs) | ||
512 | { | ||
513 | insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; | ||
514 | |||
515 | if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn)) | ||
516 | return; | ||
517 | |||
518 | regs->ARM_pc = (long)p->addr + str_pc_offset; | ||
519 | simulate_ldm1stm1(p, regs); | ||
520 | regs->ARM_pc = (long)p->addr + 4; | ||
521 | } | ||
522 | |||
523 | static void __kprobes simulate_mov_ipsp(struct kprobe *p, struct pt_regs *regs) | ||
524 | { | ||
525 | regs->uregs[12] = regs->uregs[13]; | ||
526 | } | ||
527 | |||
528 | static void __kprobes emulate_ldcstc(struct kprobe *p, struct pt_regs *regs) | ||
529 | { | ||
530 | insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; | ||
531 | kprobe_opcode_t insn = p->opcode; | ||
532 | int rn = (insn >> 16) & 0xf; | ||
533 | long rnv = regs->uregs[rn]; | ||
534 | |||
535 | /* Save Rn in case of writeback. */ | ||
536 | regs->uregs[rn] = insnslot_1arg_rflags(rnv, regs->ARM_cpsr, i_fn); | ||
537 | } | ||
538 | |||
539 | static void __kprobes emulate_ldrd(struct kprobe *p, struct pt_regs *regs) | ||
540 | { | ||
541 | insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0]; | ||
542 | kprobe_opcode_t insn = p->opcode; | ||
543 | int rd = (insn >> 12) & 0xf; | ||
544 | int rn = (insn >> 16) & 0xf; | ||
545 | int rm = insn & 0xf; /* rm may be invalid, don't care. */ | ||
546 | |||
547 | /* Not following the C calling convention here, so need asm(). */ | ||
548 | __asm__ __volatile__ ( | ||
549 | "ldr r0, %[rn] \n\t" | ||
550 | "ldr r1, %[rm] \n\t" | ||
551 | "msr cpsr_fs, %[cpsr]\n\t" | ||
552 | "mov lr, pc \n\t" | ||
553 | "mov pc, %[i_fn] \n\t" | ||
554 | "str r0, %[rn] \n\t" /* in case of writeback */ | ||
555 | "str r2, %[rd0] \n\t" | ||
556 | "str r3, %[rd1] \n\t" | ||
557 | : [rn] "+m" (regs->uregs[rn]), | ||
558 | [rd0] "=m" (regs->uregs[rd]), | ||
559 | [rd1] "=m" (regs->uregs[rd+1]) | ||
560 | : [rm] "m" (regs->uregs[rm]), | ||
561 | [cpsr] "r" (regs->ARM_cpsr), | ||
562 | [i_fn] "r" (i_fn) | ||
563 | : "r0", "r1", "r2", "r3", "lr", "cc" | ||
564 | ); | ||
565 | } | ||
566 | |||
567 | static void __kprobes emulate_strd(struct kprobe *p, struct pt_regs *regs) | ||
568 | { | ||
569 | insn_4arg_fn_t *i_fn = (insn_4arg_fn_t *)&p->ainsn.insn[0]; | ||
570 | kprobe_opcode_t insn = p->opcode; | ||
571 | int rd = (insn >> 12) & 0xf; | ||
572 | int rn = (insn >> 16) & 0xf; | ||
573 | int rm = insn & 0xf; | ||
574 | long rnv = regs->uregs[rn]; | ||
575 | long rmv = regs->uregs[rm]; /* rm/rmv may be invalid, don't care. */ | ||
576 | |||
577 | regs->uregs[rn] = insnslot_4arg_rflags(rnv, rmv, regs->uregs[rd], | ||
578 | regs->uregs[rd+1], | ||
579 | regs->ARM_cpsr, i_fn); | ||
580 | } | ||
581 | |||
582 | static void __kprobes emulate_ldr(struct kprobe *p, struct pt_regs *regs) | ||
583 | { | ||
584 | insn_llret_3arg_fn_t *i_fn = (insn_llret_3arg_fn_t *)&p->ainsn.insn[0]; | ||
585 | kprobe_opcode_t insn = p->opcode; | ||
586 | union reg_pair fnr; | ||
587 | int rd = (insn >> 12) & 0xf; | ||
588 | int rn = (insn >> 16) & 0xf; | ||
589 | int rm = insn & 0xf; | ||
590 | long rdv; | ||
591 | long rnv = regs->uregs[rn]; | ||
592 | long rmv = regs->uregs[rm]; /* rm/rmv may be invalid, don't care. */ | ||
593 | long cpsr = regs->ARM_cpsr; | ||
594 | |||
595 | fnr.dr = insnslot_llret_3arg_rflags(rnv, 0, rmv, cpsr, i_fn); | ||
596 | regs->uregs[rn] = fnr.r0; /* Save Rn in case of writeback. */ | ||
597 | rdv = fnr.r1; | ||
598 | |||
599 | if (rd == 15) { | ||
600 | #if __LINUX_ARM_ARCH__ >= 5 | ||
601 | cpsr &= ~PSR_T_BIT; | ||
602 | if (rdv & 0x1) | ||
603 | cpsr |= PSR_T_BIT; | ||
604 | regs->ARM_cpsr = cpsr; | ||
605 | rdv &= ~0x1; | ||
606 | #else | ||
607 | rdv &= ~0x2; | ||
608 | #endif | ||
609 | } | ||
610 | regs->uregs[rd] = rdv; | ||
611 | } | ||
612 | |||
613 | static void __kprobes emulate_str(struct kprobe *p, struct pt_regs *regs) | ||
614 | { | ||
615 | insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0]; | ||
616 | kprobe_opcode_t insn = p->opcode; | ||
617 | long iaddr = (long)p->addr; | ||
618 | int rd = (insn >> 12) & 0xf; | ||
619 | int rn = (insn >> 16) & 0xf; | ||
620 | int rm = insn & 0xf; | ||
621 | long rdv = (rd == 15) ? iaddr + str_pc_offset : regs->uregs[rd]; | ||
622 | long rnv = (rn == 15) ? iaddr + 8 : regs->uregs[rn]; | ||
623 | long rmv = regs->uregs[rm]; /* rm/rmv may be invalid, don't care. */ | ||
624 | |||
625 | /* Save Rn in case of writeback. */ | ||
626 | regs->uregs[rn] = | ||
627 | insnslot_3arg_rflags(rnv, rdv, rmv, regs->ARM_cpsr, i_fn); | ||
628 | } | ||
629 | |||
630 | static void __kprobes emulate_mrrc(struct kprobe *p, struct pt_regs *regs) | ||
631 | { | ||
632 | insn_llret_0arg_fn_t *i_fn = (insn_llret_0arg_fn_t *)&p->ainsn.insn[0]; | ||
633 | kprobe_opcode_t insn = p->opcode; | ||
634 | union reg_pair fnr; | ||
635 | int rd = (insn >> 12) & 0xf; | ||
636 | int rn = (insn >> 16) & 0xf; | ||
637 | |||
638 | fnr.dr = insnslot_llret_0arg_rflags(regs->ARM_cpsr, i_fn); | ||
639 | regs->uregs[rn] = fnr.r0; | ||
640 | regs->uregs[rd] = fnr.r1; | ||
641 | } | ||
642 | |||
643 | static void __kprobes emulate_mcrr(struct kprobe *p, struct pt_regs *regs) | ||
644 | { | ||
645 | insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0]; | ||
646 | kprobe_opcode_t insn = p->opcode; | ||
647 | int rd = (insn >> 12) & 0xf; | ||
648 | int rn = (insn >> 16) & 0xf; | ||
649 | long rnv = regs->uregs[rn]; | ||
650 | long rdv = regs->uregs[rd]; | ||
651 | |||
652 | insnslot_2arg_rflags(rnv, rdv, regs->ARM_cpsr, i_fn); | ||
653 | } | ||
654 | |||
655 | static void __kprobes emulate_sat(struct kprobe *p, struct pt_regs *regs) | ||
656 | { | ||
657 | insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; | ||
658 | kprobe_opcode_t insn = p->opcode; | ||
659 | int rd = (insn >> 12) & 0xf; | ||
660 | int rm = insn & 0xf; | ||
661 | long rmv = regs->uregs[rm]; | ||
662 | |||
663 | /* Writes Q flag */ | ||
664 | regs->uregs[rd] = insnslot_1arg_rwflags(rmv, ®s->ARM_cpsr, i_fn); | ||
665 | } | ||
666 | |||
667 | static void __kprobes emulate_sel(struct kprobe *p, struct pt_regs *regs) | ||
668 | { | ||
669 | insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0]; | ||
670 | kprobe_opcode_t insn = p->opcode; | ||
671 | int rd = (insn >> 12) & 0xf; | ||
672 | int rn = (insn >> 16) & 0xf; | ||
673 | int rm = insn & 0xf; | ||
674 | long rnv = regs->uregs[rn]; | ||
675 | long rmv = regs->uregs[rm]; | ||
676 | |||
677 | /* Reads GE bits */ | ||
678 | regs->uregs[rd] = insnslot_2arg_rflags(rnv, rmv, regs->ARM_cpsr, i_fn); | ||
679 | } | ||
680 | |||
681 | static void __kprobes emulate_none(struct kprobe *p, struct pt_regs *regs) | ||
682 | { | ||
683 | insn_0arg_fn_t *i_fn = (insn_0arg_fn_t *)&p->ainsn.insn[0]; | ||
684 | |||
685 | insnslot_0arg_rflags(regs->ARM_cpsr, i_fn); | ||
686 | } | ||
687 | |||
688 | static void __kprobes emulate_rd12(struct kprobe *p, struct pt_regs *regs) | ||
689 | { | ||
690 | insn_0arg_fn_t *i_fn = (insn_0arg_fn_t *)&p->ainsn.insn[0]; | ||
691 | kprobe_opcode_t insn = p->opcode; | ||
692 | int rd = (insn >> 12) & 0xf; | ||
693 | |||
694 | regs->uregs[rd] = insnslot_0arg_rflags(regs->ARM_cpsr, i_fn); | ||
695 | } | ||
696 | |||
697 | static void __kprobes emulate_ird12(struct kprobe *p, struct pt_regs *regs) | ||
698 | { | ||
699 | insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; | ||
700 | kprobe_opcode_t insn = p->opcode; | ||
701 | int ird = (insn >> 12) & 0xf; | ||
702 | |||
703 | insnslot_1arg_rflags(regs->uregs[ird], regs->ARM_cpsr, i_fn); | ||
704 | } | ||
705 | |||
706 | static void __kprobes emulate_rn16(struct kprobe *p, struct pt_regs *regs) | ||
707 | { | ||
708 | insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; | ||
709 | kprobe_opcode_t insn = p->opcode; | ||
710 | int rn = (insn >> 16) & 0xf; | ||
711 | long rnv = regs->uregs[rn]; | ||
712 | |||
713 | insnslot_1arg_rflags(rnv, regs->ARM_cpsr, i_fn); | ||
714 | } | ||
715 | |||
716 | static void __kprobes emulate_rd12rm0(struct kprobe *p, struct pt_regs *regs) | ||
717 | { | ||
718 | insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; | ||
719 | kprobe_opcode_t insn = p->opcode; | ||
720 | int rd = (insn >> 12) & 0xf; | ||
721 | int rm = insn & 0xf; | ||
722 | long rmv = regs->uregs[rm]; | ||
723 | |||
724 | regs->uregs[rd] = insnslot_1arg_rflags(rmv, regs->ARM_cpsr, i_fn); | ||
725 | } | ||
726 | |||
727 | static void __kprobes | ||
728 | emulate_rd12rn16rm0_rwflags(struct kprobe *p, struct pt_regs *regs) | ||
729 | { | ||
730 | insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0]; | ||
731 | kprobe_opcode_t insn = p->opcode; | ||
732 | int rd = (insn >> 12) & 0xf; | ||
733 | int rn = (insn >> 16) & 0xf; | ||
734 | int rm = insn & 0xf; | ||
735 | long rnv = regs->uregs[rn]; | ||
736 | long rmv = regs->uregs[rm]; | ||
737 | |||
738 | regs->uregs[rd] = | ||
739 | insnslot_2arg_rwflags(rnv, rmv, ®s->ARM_cpsr, i_fn); | ||
740 | } | ||
741 | |||
742 | static void __kprobes | ||
743 | emulate_rd16rn12rs8rm0_rwflags(struct kprobe *p, struct pt_regs *regs) | ||
744 | { | ||
745 | insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0]; | ||
746 | kprobe_opcode_t insn = p->opcode; | ||
747 | int rd = (insn >> 16) & 0xf; | ||
748 | int rn = (insn >> 12) & 0xf; | ||
749 | int rs = (insn >> 8) & 0xf; | ||
750 | int rm = insn & 0xf; | ||
751 | long rnv = regs->uregs[rn]; | ||
752 | long rsv = regs->uregs[rs]; | ||
753 | long rmv = regs->uregs[rm]; | ||
754 | |||
755 | regs->uregs[rd] = | ||
756 | insnslot_3arg_rwflags(rnv, rsv, rmv, ®s->ARM_cpsr, i_fn); | ||
757 | } | ||
758 | |||
759 | static void __kprobes | ||
760 | emulate_rd16rs8rm0_rwflags(struct kprobe *p, struct pt_regs *regs) | ||
761 | { | ||
762 | insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0]; | ||
763 | kprobe_opcode_t insn = p->opcode; | ||
764 | int rd = (insn >> 16) & 0xf; | ||
765 | int rs = (insn >> 8) & 0xf; | ||
766 | int rm = insn & 0xf; | ||
767 | long rsv = regs->uregs[rs]; | ||
768 | long rmv = regs->uregs[rm]; | ||
769 | |||
770 | regs->uregs[rd] = | ||
771 | insnslot_2arg_rwflags(rsv, rmv, ®s->ARM_cpsr, i_fn); | ||
772 | } | ||
773 | |||
774 | static void __kprobes | ||
775 | emulate_rdhi16rdlo12rs8rm0_rwflags(struct kprobe *p, struct pt_regs *regs) | ||
776 | { | ||
777 | insn_llret_4arg_fn_t *i_fn = (insn_llret_4arg_fn_t *)&p->ainsn.insn[0]; | ||
778 | kprobe_opcode_t insn = p->opcode; | ||
779 | union reg_pair fnr; | ||
780 | int rdhi = (insn >> 16) & 0xf; | ||
781 | int rdlo = (insn >> 12) & 0xf; | ||
782 | int rs = (insn >> 8) & 0xf; | ||
783 | int rm = insn & 0xf; | ||
784 | long rsv = regs->uregs[rs]; | ||
785 | long rmv = regs->uregs[rm]; | ||
786 | |||
787 | fnr.dr = insnslot_llret_4arg_rwflags(regs->uregs[rdhi], | ||
788 | regs->uregs[rdlo], rsv, rmv, | ||
789 | ®s->ARM_cpsr, i_fn); | ||
790 | regs->uregs[rdhi] = fnr.r0; | ||
791 | regs->uregs[rdlo] = fnr.r1; | ||
792 | } | ||
793 | |||
794 | static void __kprobes | ||
795 | emulate_alu_imm_rflags(struct kprobe *p, struct pt_regs *regs) | ||
796 | { | ||
797 | insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; | ||
798 | kprobe_opcode_t insn = p->opcode; | ||
799 | int rd = (insn >> 12) & 0xf; | ||
800 | int rn = (insn >> 16) & 0xf; | ||
801 | long rnv = (rn == 15) ? (long)p->addr + 8 : regs->uregs[rn]; | ||
802 | |||
803 | regs->uregs[rd] = insnslot_1arg_rflags(rnv, regs->ARM_cpsr, i_fn); | ||
804 | } | ||
805 | |||
806 | static void __kprobes | ||
807 | emulate_alu_imm_rwflags(struct kprobe *p, struct pt_regs *regs) | ||
808 | { | ||
809 | insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; | ||
810 | kprobe_opcode_t insn = p->opcode; | ||
811 | int rd = (insn >> 12) & 0xf; | ||
812 | int rn = (insn >> 16) & 0xf; | ||
813 | long rnv = (rn == 15) ? (long)p->addr + 8 : regs->uregs[rn]; | ||
814 | |||
815 | regs->uregs[rd] = insnslot_1arg_rwflags(rnv, ®s->ARM_cpsr, i_fn); | ||
816 | } | ||
817 | |||
818 | static void __kprobes | ||
819 | emulate_alu_rflags(struct kprobe *p, struct pt_regs *regs) | ||
820 | { | ||
821 | insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0]; | ||
822 | kprobe_opcode_t insn = p->opcode; | ||
823 | long ppc = (long)p->addr + 8; | ||
824 | int rd = (insn >> 12) & 0xf; | ||
825 | int rn = (insn >> 16) & 0xf; /* rn/rnv/rs/rsv may be */ | ||
826 | int rs = (insn >> 8) & 0xf; /* invalid, don't care. */ | ||
827 | int rm = insn & 0xf; | ||
828 | long rnv = (rn == 15) ? ppc : regs->uregs[rn]; | ||
829 | long rmv = (rm == 15) ? ppc : regs->uregs[rm]; | ||
830 | long rsv = regs->uregs[rs]; | ||
831 | |||
832 | regs->uregs[rd] = | ||
833 | insnslot_3arg_rflags(rnv, rmv, rsv, regs->ARM_cpsr, i_fn); | ||
834 | } | ||
835 | |||
836 | static void __kprobes | ||
837 | emulate_alu_rwflags(struct kprobe *p, struct pt_regs *regs) | ||
838 | { | ||
839 | insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0]; | ||
840 | kprobe_opcode_t insn = p->opcode; | ||
841 | long ppc = (long)p->addr + 8; | ||
842 | int rd = (insn >> 12) & 0xf; | ||
843 | int rn = (insn >> 16) & 0xf; /* rn/rnv/rs/rsv may be */ | ||
844 | int rs = (insn >> 8) & 0xf; /* invalid, don't care. */ | ||
845 | int rm = insn & 0xf; | ||
846 | long rnv = (rn == 15) ? ppc : regs->uregs[rn]; | ||
847 | long rmv = (rm == 15) ? ppc : regs->uregs[rm]; | ||
848 | long rsv = regs->uregs[rs]; | ||
849 | |||
850 | regs->uregs[rd] = | ||
851 | insnslot_3arg_rwflags(rnv, rmv, rsv, ®s->ARM_cpsr, i_fn); | ||
852 | } | ||
853 | |||
854 | static enum kprobe_insn __kprobes | ||
855 | prep_emulate_ldr_str(kprobe_opcode_t insn, struct arch_specific_insn *asi) | ||
856 | { | ||
857 | int ibit = (insn & (1 << 26)) ? 25 : 22; | ||
858 | |||
859 | insn &= 0xfff00fff; | ||
860 | insn |= 0x00001000; /* Rn = r0, Rd = r1 */ | ||
861 | if (insn & (1 << ibit)) { | ||
862 | insn &= ~0xf; | ||
863 | insn |= 2; /* Rm = r2 */ | ||
864 | } | ||
865 | asi->insn[0] = insn; | ||
866 | asi->insn_handler = (insn & (1 << 20)) ? emulate_ldr : emulate_str; | ||
867 | return INSN_GOOD; | ||
868 | } | ||
869 | |||
870 | static enum kprobe_insn __kprobes | ||
871 | prep_emulate_rd12rm0(kprobe_opcode_t insn, struct arch_specific_insn *asi) | ||
872 | { | ||
873 | insn &= 0xffff0ff0; /* Rd = r0, Rm = r0 */ | ||
874 | asi->insn[0] = insn; | ||
875 | asi->insn_handler = emulate_rd12rm0; | ||
876 | return INSN_GOOD; | ||
877 | } | ||
878 | |||
879 | static enum kprobe_insn __kprobes | ||
880 | prep_emulate_rd12(kprobe_opcode_t insn, struct arch_specific_insn *asi) | ||
881 | { | ||
882 | insn &= 0xffff0fff; /* Rd = r0 */ | ||
883 | asi->insn[0] = insn; | ||
884 | asi->insn_handler = emulate_rd12; | ||
885 | return INSN_GOOD; | ||
886 | } | ||
887 | |||
888 | static enum kprobe_insn __kprobes | ||
889 | prep_emulate_rd12rn16rm0_wflags(kprobe_opcode_t insn, | ||
890 | struct arch_specific_insn *asi) | ||
891 | { | ||
892 | insn &= 0xfff00ff0; /* Rd = r0, Rn = r0 */ | ||
893 | insn |= 0x00000001; /* Rm = r1 */ | ||
894 | asi->insn[0] = insn; | ||
895 | asi->insn_handler = emulate_rd12rn16rm0_rwflags; | ||
896 | return INSN_GOOD; | ||
897 | } | ||
898 | |||
899 | static enum kprobe_insn __kprobes | ||
900 | prep_emulate_rd16rs8rm0_wflags(kprobe_opcode_t insn, | ||
901 | struct arch_specific_insn *asi) | ||
902 | { | ||
903 | insn &= 0xfff0f0f0; /* Rd = r0, Rs = r0 */ | ||
904 | insn |= 0x00000001; /* Rm = r1 */ | ||
905 | asi->insn[0] = insn; | ||
906 | asi->insn_handler = emulate_rd16rs8rm0_rwflags; | ||
907 | return INSN_GOOD; | ||
908 | } | ||
909 | |||
910 | static enum kprobe_insn __kprobes | ||
911 | prep_emulate_rd16rn12rs8rm0_wflags(kprobe_opcode_t insn, | ||
912 | struct arch_specific_insn *asi) | ||
913 | { | ||
914 | insn &= 0xfff000f0; /* Rd = r0, Rn = r0 */ | ||
915 | insn |= 0x00000102; /* Rs = r1, Rm = r2 */ | ||
916 | asi->insn[0] = insn; | ||
917 | asi->insn_handler = emulate_rd16rn12rs8rm0_rwflags; | ||
918 | return INSN_GOOD; | ||
919 | } | ||
920 | |||
921 | static enum kprobe_insn __kprobes | ||
922 | prep_emulate_rdhi16rdlo12rs8rm0_wflags(kprobe_opcode_t insn, | ||
923 | struct arch_specific_insn *asi) | ||
924 | { | ||
925 | insn &= 0xfff000f0; /* RdHi = r0, RdLo = r1 */ | ||
926 | insn |= 0x00001203; /* Rs = r2, Rm = r3 */ | ||
927 | asi->insn[0] = insn; | ||
928 | asi->insn_handler = emulate_rdhi16rdlo12rs8rm0_rwflags; | ||
929 | return INSN_GOOD; | ||
930 | } | ||
931 | |||
932 | /* | ||
933 | * For the instruction masking and comparisons in all the "space_*" | ||
934 | * functions below, Do _not_ rearrange the order of tests unless | ||
935 | * you're very, very sure of what you are doing. For the sake of | ||
936 | * efficiency, the masks for some tests sometimes assume other test | ||
937 | * have been done prior to them so the number of patterns to test | ||
938 | * for an instruction set can be as broad as possible to reduce the | ||
939 | * number of tests needed. | ||
940 | */ | ||
941 | |||
942 | static enum kprobe_insn __kprobes | ||
943 | space_1111(kprobe_opcode_t insn, struct arch_specific_insn *asi) | ||
944 | { | ||
945 | /* CPS mmod == 1 : 1111 0001 0000 xx10 xxxx xxxx xx0x xxxx */ | ||
946 | /* RFE : 1111 100x x0x1 xxxx xxxx 1010 xxxx xxxx */ | ||
947 | /* SRS : 1111 100x x1x0 1101 xxxx 0101 xxxx xxxx */ | ||
948 | if ((insn & 0xfff30020) == 0xf1020000 || | ||
949 | (insn & 0xfe500f00) == 0xf8100a00 || | ||
950 | (insn & 0xfe5f0f00) == 0xf84d0500) | ||
951 | return INSN_REJECTED; | ||
952 | |||
953 | /* PLD : 1111 01x1 x101 xxxx xxxx xxxx xxxx xxxx : */ | ||
954 | if ((insn & 0xfd700000) == 0xf4500000) { | ||
955 | insn &= 0xfff0ffff; /* Rn = r0 */ | ||
956 | asi->insn[0] = insn; | ||
957 | asi->insn_handler = emulate_rn16; | ||
958 | return INSN_GOOD; | ||
959 | } | ||
960 | |||
961 | /* BLX(1) : 1111 101x xxxx xxxx xxxx xxxx xxxx xxxx : */ | ||
962 | if ((insn & 0xfe000000) == 0xfa000000) { | ||
963 | asi->insn_handler = simulate_blx1; | ||
964 | return INSN_GOOD_NO_SLOT; | ||
965 | } | ||
966 | |||
967 | /* SETEND : 1111 0001 0000 0001 xxxx xxxx 0000 xxxx */ | ||
968 | /* CDP2 : 1111 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */ | ||
969 | if ((insn & 0xffff00f0) == 0xf1010000 || | ||
970 | (insn & 0xff000010) == 0xfe000000) { | ||
971 | asi->insn[0] = insn; | ||
972 | asi->insn_handler = emulate_none; | ||
973 | return INSN_GOOD; | ||
974 | } | ||
975 | |||
976 | /* MCRR2 : 1111 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd != Rn) */ | ||
977 | /* MRRC2 : 1111 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd != Rn) */ | ||
978 | if ((insn & 0xffe00000) == 0xfc400000) { | ||
979 | insn &= 0xfff00fff; /* Rn = r0 */ | ||
980 | insn |= 0x00001000; /* Rd = r1 */ | ||
981 | asi->insn[0] = insn; | ||
982 | asi->insn_handler = | ||
983 | (insn & (1 << 20)) ? emulate_mrrc : emulate_mcrr; | ||
984 | return INSN_GOOD; | ||
985 | } | ||
986 | |||
987 | /* LDC2 : 1111 110x xxx1 xxxx xxxx xxxx xxxx xxxx */ | ||
988 | /* STC2 : 1111 110x xxx0 xxxx xxxx xxxx xxxx xxxx */ | ||
989 | if ((insn & 0xfe000000) == 0xfc000000) { | ||
990 | insn &= 0xfff0ffff; /* Rn = r0 */ | ||
991 | asi->insn[0] = insn; | ||
992 | asi->insn_handler = emulate_ldcstc; | ||
993 | return INSN_GOOD; | ||
994 | } | ||
995 | |||
996 | /* MCR2 : 1111 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */ | ||
997 | /* MRC2 : 1111 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */ | ||
998 | insn &= 0xffff0fff; /* Rd = r0 */ | ||
999 | asi->insn[0] = insn; | ||
1000 | asi->insn_handler = (insn & (1 << 20)) ? emulate_rd12 : emulate_ird12; | ||
1001 | return INSN_GOOD; | ||
1002 | } | ||
1003 | |||
1004 | static enum kprobe_insn __kprobes | ||
1005 | space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi) | ||
1006 | { | ||
1007 | /* cccc 0001 0xx0 xxxx xxxx xxxx xxxx xxx0 xxxx */ | ||
1008 | if ((insn & 0x0f900010) == 0x01000000) { | ||
1009 | |||
1010 | /* BXJ : cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */ | ||
1011 | /* MSR : cccc 0001 0x10 xxxx xxxx xxxx 0000 xxxx */ | ||
1012 | if ((insn & 0x0ff000f0) == 0x01200020 || | ||
1013 | (insn & 0x0fb000f0) == 0x01200000) | ||
1014 | return INSN_REJECTED; | ||
1015 | |||
1016 | /* MRS : cccc 0001 0x00 xxxx xxxx xxxx 0000 xxxx */ | ||
1017 | if ((insn & 0x0fb00010) == 0x01000000) | ||
1018 | return prep_emulate_rd12(insn, asi); | ||
1019 | |||
1020 | /* SMLALxy : cccc 0001 0100 xxxx xxxx xxxx 1xx0 xxxx */ | ||
1021 | if ((insn & 0x0ff00090) == 0x01400080) | ||
1022 | return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi); | ||
1023 | |||
1024 | /* SMULWy : cccc 0001 0010 xxxx xxxx xxxx 1x10 xxxx */ | ||
1025 | /* SMULxy : cccc 0001 0110 xxxx xxxx xxxx 1xx0 xxxx */ | ||
1026 | if ((insn & 0x0ff000b0) == 0x012000a0 || | ||
1027 | (insn & 0x0ff00090) == 0x01600080) | ||
1028 | return prep_emulate_rd16rs8rm0_wflags(insn, asi); | ||
1029 | |||
1030 | /* SMLAxy : cccc 0001 0000 xxxx xxxx xxxx 1xx0 xxxx : Q */ | ||
1031 | /* SMLAWy : cccc 0001 0010 xxxx xxxx xxxx 0x00 xxxx : Q */ | ||
1032 | return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); | ||
1033 | |||
1034 | } | ||
1035 | |||
1036 | /* cccc 0001 0xx0 xxxx xxxx xxxx xxxx 0xx1 xxxx */ | ||
1037 | else if ((insn & 0x0f900090) == 0x01000010) { | ||
1038 | |||
1039 | /* BKPT : 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */ | ||
1040 | if ((insn & 0xfff000f0) == 0xe1200070) | ||
1041 | return INSN_REJECTED; | ||
1042 | |||
1043 | /* BLX(2) : cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */ | ||
1044 | /* BX : cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */ | ||
1045 | if ((insn & 0x0ff000d0) == 0x01200010) { | ||
1046 | asi->insn[0] = truecc_insn(insn); | ||
1047 | asi->insn_handler = simulate_blx2bx; | ||
1048 | return INSN_GOOD; | ||
1049 | } | ||
1050 | |||
1051 | /* CLZ : cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */ | ||
1052 | if ((insn & 0x0ff000f0) == 0x01600010) | ||
1053 | return prep_emulate_rd12rm0(insn, asi); | ||
1054 | |||
1055 | /* QADD : cccc 0001 0000 xxxx xxxx xxxx 0101 xxxx :Q */ | ||
1056 | /* QSUB : cccc 0001 0010 xxxx xxxx xxxx 0101 xxxx :Q */ | ||
1057 | /* QDADD : cccc 0001 0100 xxxx xxxx xxxx 0101 xxxx :Q */ | ||
1058 | /* QDSUB : cccc 0001 0110 xxxx xxxx xxxx 0101 xxxx :Q */ | ||
1059 | return prep_emulate_rd12rn16rm0_wflags(insn, asi); | ||
1060 | } | ||
1061 | |||
1062 | /* cccc 0000 xxxx xxxx xxxx xxxx xxxx 1001 xxxx */ | ||
1063 | else if ((insn & 0x0f000090) == 0x00000090) { | ||
1064 | |||
1065 | /* MUL : cccc 0000 0000 xxxx xxxx xxxx 1001 xxxx : */ | ||
1066 | /* MULS : cccc 0000 0001 xxxx xxxx xxxx 1001 xxxx :cc */ | ||
1067 | /* MLA : cccc 0000 0010 xxxx xxxx xxxx 1001 xxxx : */ | ||
1068 | /* MLAS : cccc 0000 0011 xxxx xxxx xxxx 1001 xxxx :cc */ | ||
1069 | /* UMAAL : cccc 0000 0100 xxxx xxxx xxxx 1001 xxxx : */ | ||
1070 | /* UMULL : cccc 0000 1000 xxxx xxxx xxxx 1001 xxxx : */ | ||
1071 | /* UMULLS : cccc 0000 1001 xxxx xxxx xxxx 1001 xxxx :cc */ | ||
1072 | /* UMLAL : cccc 0000 1010 xxxx xxxx xxxx 1001 xxxx : */ | ||
1073 | /* UMLALS : cccc 0000 1011 xxxx xxxx xxxx 1001 xxxx :cc */ | ||
1074 | /* SMULL : cccc 0000 1100 xxxx xxxx xxxx 1001 xxxx : */ | ||
1075 | /* SMULLS : cccc 0000 1101 xxxx xxxx xxxx 1001 xxxx :cc */ | ||
1076 | /* SMLAL : cccc 0000 1110 xxxx xxxx xxxx 1001 xxxx : */ | ||
1077 | /* SMLALS : cccc 0000 1111 xxxx xxxx xxxx 1001 xxxx :cc */ | ||
1078 | if ((insn & 0x0fe000f0) == 0x00000090) { | ||
1079 | return prep_emulate_rd16rs8rm0_wflags(insn, asi); | ||
1080 | } else if ((insn & 0x0fe000f0) == 0x00200090) { | ||
1081 | return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); | ||
1082 | } else { | ||
1083 | return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi); | ||
1084 | } | ||
1085 | } | ||
1086 | |||
1087 | /* cccc 000x xxxx xxxx xxxx xxxx xxxx 1xx1 xxxx */ | ||
1088 | else if ((insn & 0x0e000090) == 0x00000090) { | ||
1089 | |||
1090 | /* SWP : cccc 0001 0000 xxxx xxxx xxxx 1001 xxxx */ | ||
1091 | /* SWPB : cccc 0001 0100 xxxx xxxx xxxx 1001 xxxx */ | ||
1092 | /* LDRD : cccc 000x xxx0 xxxx xxxx xxxx 1101 xxxx */ | ||
1093 | /* STRD : cccc 000x xxx0 xxxx xxxx xxxx 1111 xxxx */ | ||
1094 | /* STREX : cccc 0001 1000 xxxx xxxx xxxx 1001 xxxx */ | ||
1095 | /* LDREX : cccc 0001 1001 xxxx xxxx xxxx 1001 xxxx */ | ||
1096 | /* LDRH : cccc 000x xxx1 xxxx xxxx xxxx 1011 xxxx */ | ||
1097 | /* STRH : cccc 000x xxx0 xxxx xxxx xxxx 1011 xxxx */ | ||
1098 | /* LDRSB : cccc 000x xxx1 xxxx xxxx xxxx 1101 xxxx */ | ||
1099 | /* LDRSH : cccc 000x xxx1 xxxx xxxx xxxx 1111 xxxx */ | ||
1100 | if ((insn & 0x0fb000f0) == 0x01000090) { | ||
1101 | /* SWP/SWPB */ | ||
1102 | return prep_emulate_rd12rn16rm0_wflags(insn, asi); | ||
1103 | } else if ((insn & 0x0e1000d0) == 0x00000d0) { | ||
1104 | /* STRD/LDRD */ | ||
1105 | insn &= 0xfff00fff; | ||
1106 | insn |= 0x00002000; /* Rn = r0, Rd = r2 */ | ||
1107 | if (insn & (1 << 22)) { | ||
1108 | /* I bit */ | ||
1109 | insn &= ~0xf; | ||
1110 | insn |= 1; /* Rm = r1 */ | ||
1111 | } | ||
1112 | asi->insn[0] = insn; | ||
1113 | asi->insn_handler = | ||
1114 | (insn & (1 << 5)) ? emulate_strd : emulate_ldrd; | ||
1115 | return INSN_GOOD; | ||
1116 | } | ||
1117 | |||
1118 | return prep_emulate_ldr_str(insn, asi); | ||
1119 | } | ||
1120 | |||
1121 | /* cccc 000x xxxx xxxx xxxx xxxx xxxx xxxx xxxx */ | ||
1122 | |||
1123 | /* | ||
1124 | * ALU op with S bit and Rd == 15 : | ||
1125 | * cccc 000x xxx1 xxxx 1111 xxxx xxxx xxxx | ||
1126 | */ | ||
1127 | if ((insn & 0x0e10f000) == 0x0010f000) | ||
1128 | return INSN_REJECTED; | ||
1129 | |||
1130 | /* | ||
1131 | * "mov ip, sp" is the most common kprobe'd instruction by far. | ||
1132 | * Check and optimize for it explicitly. | ||
1133 | */ | ||
1134 | if (insn == 0xe1a0c00d) { | ||
1135 | asi->insn_handler = simulate_mov_ipsp; | ||
1136 | return INSN_GOOD_NO_SLOT; | ||
1137 | } | ||
1138 | |||
1139 | /* | ||
1140 | * Data processing: Immediate-shift / Register-shift | ||
1141 | * ALU op : cccc 000x xxxx xxxx xxxx xxxx xxxx xxxx | ||
1142 | * CPY : cccc 0001 1010 xxxx xxxx 0000 0000 xxxx | ||
1143 | * MOV : cccc 0001 101x xxxx xxxx xxxx xxxx xxxx | ||
1144 | * *S (bit 20) updates condition codes | ||
1145 | * ADC/SBC/RSC reads the C flag | ||
1146 | */ | ||
1147 | insn &= 0xfff00ff0; /* Rn = r0, Rd = r0 */ | ||
1148 | insn |= 0x00000001; /* Rm = r1 */ | ||
1149 | if (insn & 0x010) { | ||
1150 | insn &= 0xfffff0ff; /* register shift */ | ||
1151 | insn |= 0x00000200; /* Rs = r2 */ | ||
1152 | } | ||
1153 | asi->insn[0] = insn; | ||
1154 | asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */ | ||
1155 | emulate_alu_rwflags : emulate_alu_rflags; | ||
1156 | return INSN_GOOD; | ||
1157 | } | ||
1158 | |||
1159 | static enum kprobe_insn __kprobes | ||
1160 | space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi) | ||
1161 | { | ||
1162 | /* | ||
1163 | * MSR : cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx | ||
1164 | * Undef : cccc 0011 0x00 xxxx xxxx xxxx xxxx xxxx | ||
1165 | * ALU op with S bit and Rd == 15 : | ||
1166 | * cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx | ||
1167 | */ | ||
1168 | if ((insn & 0x0f900000) == 0x03200000 || /* MSR & Undef */ | ||
1169 | (insn & 0x0e10f000) == 0x0210f000) /* ALU s-bit, R15 */ | ||
1170 | return INSN_REJECTED; | ||
1171 | |||
1172 | /* | ||
1173 | * Data processing: 32-bit Immediate | ||
1174 | * ALU op : cccc 001x xxxx xxxx xxxx xxxx xxxx xxxx | ||
1175 | * MOV : cccc 0011 101x xxxx xxxx xxxx xxxx xxxx | ||
1176 | * *S (bit 20) updates condition codes | ||
1177 | * ADC/SBC/RSC reads the C flag | ||
1178 | */ | ||
1179 | insn &= 0xfff00ff0; /* Rn = r0, Rd = r0 */ | ||
1180 | asi->insn[0] = insn; | ||
1181 | asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */ | ||
1182 | emulate_alu_imm_rwflags : emulate_alu_imm_rflags; | ||
1183 | return INSN_GOOD; | ||
1184 | } | ||
1185 | |||
1186 | static enum kprobe_insn __kprobes | ||
1187 | space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi) | ||
1188 | { | ||
1189 | /* SEL : cccc 0110 1000 xxxx xxxx xxxx 1011 xxxx GE: !!! */ | ||
1190 | if ((insn & 0x0ff000f0) == 0x068000b0) { | ||
1191 | insn &= 0xfff00ff0; /* Rd = r0, Rn = r0 */ | ||
1192 | insn |= 0x00000001; /* Rm = r1 */ | ||
1193 | asi->insn[0] = insn; | ||
1194 | asi->insn_handler = emulate_sel; | ||
1195 | return INSN_GOOD; | ||
1196 | } | ||
1197 | |||
1198 | /* SSAT : cccc 0110 101x xxxx xxxx xxxx xx01 xxxx :Q */ | ||
1199 | /* USAT : cccc 0110 111x xxxx xxxx xxxx xx01 xxxx :Q */ | ||
1200 | /* SSAT16 : cccc 0110 1010 xxxx xxxx xxxx 0011 xxxx :Q */ | ||
1201 | /* USAT16 : cccc 0110 1110 xxxx xxxx xxxx 0011 xxxx :Q */ | ||
1202 | if ((insn & 0x0fa00030) == 0x06a00010 || | ||
1203 | (insn & 0x0fb000f0) == 0x06a00030) { | ||
1204 | insn &= 0xffff0ff0; /* Rd = r0, Rm = r0 */ | ||
1205 | asi->insn[0] = insn; | ||
1206 | asi->insn_handler = emulate_sat; | ||
1207 | return INSN_GOOD; | ||
1208 | } | ||
1209 | |||
1210 | /* REV : cccc 0110 1011 xxxx xxxx xxxx 0011 xxxx */ | ||
1211 | /* REV16 : cccc 0110 1011 xxxx xxxx xxxx 1011 xxxx */ | ||
1212 | /* REVSH : cccc 0110 1111 xxxx xxxx xxxx 1011 xxxx */ | ||
1213 | if ((insn & 0x0ff00070) == 0x06b00030 || | ||
1214 | (insn & 0x0ff000f0) == 0x06f000b0) | ||
1215 | return prep_emulate_rd12rm0(insn, asi); | ||
1216 | |||
1217 | /* SADD16 : cccc 0110 0001 xxxx xxxx xxxx 0001 xxxx :GE */ | ||
1218 | /* SADDSUBX : cccc 0110 0001 xxxx xxxx xxxx 0011 xxxx :GE */ | ||
1219 | /* SSUBADDX : cccc 0110 0001 xxxx xxxx xxxx 0101 xxxx :GE */ | ||
1220 | /* SSUB16 : cccc 0110 0001 xxxx xxxx xxxx 0111 xxxx :GE */ | ||
1221 | /* SADD8 : cccc 0110 0001 xxxx xxxx xxxx 1001 xxxx :GE */ | ||
1222 | /* SSUB8 : cccc 0110 0001 xxxx xxxx xxxx 1111 xxxx :GE */ | ||
1223 | /* QADD16 : cccc 0110 0010 xxxx xxxx xxxx 0001 xxxx : */ | ||
1224 | /* QADDSUBX : cccc 0110 0010 xxxx xxxx xxxx 0011 xxxx : */ | ||
1225 | /* QSUBADDX : cccc 0110 0010 xxxx xxxx xxxx 0101 xxxx : */ | ||
1226 | /* QSUB16 : cccc 0110 0010 xxxx xxxx xxxx 0111 xxxx : */ | ||
1227 | /* QADD8 : cccc 0110 0010 xxxx xxxx xxxx 1001 xxxx : */ | ||
1228 | /* QSUB8 : cccc 0110 0010 xxxx xxxx xxxx 1111 xxxx : */ | ||
1229 | /* SHADD16 : cccc 0110 0011 xxxx xxxx xxxx 0001 xxxx : */ | ||
1230 | /* SHADDSUBX : cccc 0110 0011 xxxx xxxx xxxx 0011 xxxx : */ | ||
1231 | /* SHSUBADDX : cccc 0110 0011 xxxx xxxx xxxx 0101 xxxx : */ | ||
1232 | /* SHSUB16 : cccc 0110 0011 xxxx xxxx xxxx 0111 xxxx : */ | ||
1233 | /* SHADD8 : cccc 0110 0011 xxxx xxxx xxxx 1001 xxxx : */ | ||
1234 | /* SHSUB8 : cccc 0110 0011 xxxx xxxx xxxx 1111 xxxx : */ | ||
1235 | /* UADD16 : cccc 0110 0101 xxxx xxxx xxxx 0001 xxxx :GE */ | ||
1236 | /* UADDSUBX : cccc 0110 0101 xxxx xxxx xxxx 0011 xxxx :GE */ | ||
1237 | /* USUBADDX : cccc 0110 0101 xxxx xxxx xxxx 0101 xxxx :GE */ | ||
1238 | /* USUB16 : cccc 0110 0101 xxxx xxxx xxxx 0111 xxxx :GE */ | ||
1239 | /* UADD8 : cccc 0110 0101 xxxx xxxx xxxx 1001 xxxx :GE */ | ||
1240 | /* USUB8 : cccc 0110 0101 xxxx xxxx xxxx 1111 xxxx :GE */ | ||
1241 | /* UQADD16 : cccc 0110 0110 xxxx xxxx xxxx 0001 xxxx : */ | ||
1242 | /* UQADDSUBX : cccc 0110 0110 xxxx xxxx xxxx 0011 xxxx : */ | ||
1243 | /* UQSUBADDX : cccc 0110 0110 xxxx xxxx xxxx 0101 xxxx : */ | ||
1244 | /* UQSUB16 : cccc 0110 0110 xxxx xxxx xxxx 0111 xxxx : */ | ||
1245 | /* UQADD8 : cccc 0110 0110 xxxx xxxx xxxx 1001 xxxx : */ | ||
1246 | /* UQSUB8 : cccc 0110 0110 xxxx xxxx xxxx 1111 xxxx : */ | ||
1247 | /* UHADD16 : cccc 0110 0111 xxxx xxxx xxxx 0001 xxxx : */ | ||
1248 | /* UHADDSUBX : cccc 0110 0111 xxxx xxxx xxxx 0011 xxxx : */ | ||
1249 | /* UHSUBADDX : cccc 0110 0111 xxxx xxxx xxxx 0101 xxxx : */ | ||
1250 | /* UHSUB16 : cccc 0110 0111 xxxx xxxx xxxx 0111 xxxx : */ | ||
1251 | /* UHADD8 : cccc 0110 0111 xxxx xxxx xxxx 1001 xxxx : */ | ||
1252 | /* UHSUB8 : cccc 0110 0111 xxxx xxxx xxxx 1111 xxxx : */ | ||
1253 | /* PKHBT : cccc 0110 1000 xxxx xxxx xxxx x001 xxxx : */ | ||
1254 | /* PKHTB : cccc 0110 1000 xxxx xxxx xxxx x101 xxxx : */ | ||
1255 | /* SXTAB16 : cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx : */ | ||
1256 | /* SXTB : cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx : */ | ||
1257 | /* SXTAB : cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx : */ | ||
1258 | /* SXTAH : cccc 0110 1011 xxxx xxxx xxxx 0111 xxxx : */ | ||
1259 | /* UXTAB16 : cccc 0110 1100 xxxx xxxx xxxx 0111 xxxx : */ | ||
1260 | /* UXTAB : cccc 0110 1110 xxxx xxxx xxxx 0111 xxxx : */ | ||
1261 | /* UXTAH : cccc 0110 1111 xxxx xxxx xxxx 0111 xxxx : */ | ||
1262 | return prep_emulate_rd12rn16rm0_wflags(insn, asi); | ||
1263 | } | ||
1264 | |||
1265 | static enum kprobe_insn __kprobes | ||
1266 | space_cccc_0111__1(kprobe_opcode_t insn, struct arch_specific_insn *asi) | ||
1267 | { | ||
1268 | /* Undef : cccc 0111 1111 xxxx xxxx xxxx 1111 xxxx */ | ||
1269 | if ((insn & 0x0ff000f0) == 0x03f000f0) | ||
1270 | return INSN_REJECTED; | ||
1271 | |||
1272 | /* USADA8 : cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx */ | ||
1273 | /* USAD8 : cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx */ | ||
1274 | if ((insn & 0x0ff000f0) == 0x07800010) | ||
1275 | return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); | ||
1276 | |||
1277 | /* SMLALD : cccc 0111 0100 xxxx xxxx xxxx 00x1 xxxx */ | ||
1278 | /* SMLSLD : cccc 0111 0100 xxxx xxxx xxxx 01x1 xxxx */ | ||
1279 | if ((insn & 0x0ff00090) == 0x07400010) | ||
1280 | return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi); | ||
1281 | |||
1282 | /* SMLAD : cccc 0111 0000 xxxx xxxx xxxx 00x1 xxxx :Q */ | ||
1283 | /* SMLSD : cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx :Q */ | ||
1284 | /* SMMLA : cccc 0111 0101 xxxx xxxx xxxx 00x1 xxxx : */ | ||
1285 | /* SMMLS : cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx : */ | ||
1286 | if ((insn & 0x0ff00090) == 0x07000010 || | ||
1287 | (insn & 0x0ff000d0) == 0x07500010 || | ||
1288 | (insn & 0x0ff000d0) == 0x075000d0) | ||
1289 | return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); | ||
1290 | |||
1291 | /* SMUSD : cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx : */ | ||
1292 | /* SMUAD : cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx :Q */ | ||
1293 | /* SMMUL : cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx : */ | ||
1294 | return prep_emulate_rd16rs8rm0_wflags(insn, asi); | ||
1295 | } | ||
1296 | |||
1297 | static enum kprobe_insn __kprobes | ||
1298 | space_cccc_01xx(kprobe_opcode_t insn, struct arch_specific_insn *asi) | ||
1299 | { | ||
1300 | /* LDR : cccc 01xx x0x1 xxxx xxxx xxxx xxxx xxxx */ | ||
1301 | /* LDRB : cccc 01xx x1x1 xxxx xxxx xxxx xxxx xxxx */ | ||
1302 | /* LDRBT : cccc 01x0 x111 xxxx xxxx xxxx xxxx xxxx */ | ||
1303 | /* LDRT : cccc 01x0 x011 xxxx xxxx xxxx xxxx xxxx */ | ||
1304 | /* STR : cccc 01xx x0x0 xxxx xxxx xxxx xxxx xxxx */ | ||
1305 | /* STRB : cccc 01xx x1x0 xxxx xxxx xxxx xxxx xxxx */ | ||
1306 | /* STRBT : cccc 01x0 x110 xxxx xxxx xxxx xxxx xxxx */ | ||
1307 | /* STRT : cccc 01x0 x010 xxxx xxxx xxxx xxxx xxxx */ | ||
1308 | return prep_emulate_ldr_str(insn, asi); | ||
1309 | } | ||
1310 | |||
1311 | static enum kprobe_insn __kprobes | ||
1312 | space_cccc_100x(kprobe_opcode_t insn, struct arch_specific_insn *asi) | ||
1313 | { | ||
1314 | /* LDM(2) : cccc 100x x101 xxxx 0xxx xxxx xxxx xxxx */ | ||
1315 | /* LDM(3) : cccc 100x x1x1 xxxx 1xxx xxxx xxxx xxxx */ | ||
1316 | if ((insn & 0x0e708000) == 0x85000000 || | ||
1317 | (insn & 0x0e508000) == 0x85010000) | ||
1318 | return INSN_REJECTED; | ||
1319 | |||
1320 | /* LDM(1) : cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */ | ||
1321 | /* STM(1) : cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */ | ||
1322 | asi->insn[0] = truecc_insn(insn); | ||
1323 | asi->insn_handler = ((insn & 0x108000) == 0x008000) ? /* STM & R15 */ | ||
1324 | simulate_stm1_pc : simulate_ldm1stm1; | ||
1325 | return INSN_GOOD; | ||
1326 | } | ||
1327 | |||
1328 | static enum kprobe_insn __kprobes | ||
1329 | space_cccc_101x(kprobe_opcode_t insn, struct arch_specific_insn *asi) | ||
1330 | { | ||
1331 | /* B : cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */ | ||
1332 | /* BL : cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */ | ||
1333 | asi->insn[0] = truecc_insn(insn); | ||
1334 | asi->insn_handler = simulate_bbl; | ||
1335 | return INSN_GOOD; | ||
1336 | } | ||
1337 | |||
1338 | static enum kprobe_insn __kprobes | ||
1339 | space_cccc_1100_010x(kprobe_opcode_t insn, struct arch_specific_insn *asi) | ||
1340 | { | ||
1341 | /* MCRR : cccc 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */ | ||
1342 | /* MRRC : cccc 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */ | ||
1343 | insn &= 0xfff00fff; | ||
1344 | insn |= 0x00001000; /* Rn = r0, Rd = r1 */ | ||
1345 | asi->insn[0] = insn; | ||
1346 | asi->insn_handler = (insn & (1 << 20)) ? emulate_mrrc : emulate_mcrr; | ||
1347 | return INSN_GOOD; | ||
1348 | } | ||
1349 | |||
1350 | static enum kprobe_insn __kprobes | ||
1351 | space_cccc_110x(kprobe_opcode_t insn, struct arch_specific_insn *asi) | ||
1352 | { | ||
1353 | /* LDC : cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */ | ||
1354 | /* STC : cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */ | ||
1355 | insn &= 0xfff0ffff; /* Rn = r0 */ | ||
1356 | asi->insn[0] = insn; | ||
1357 | asi->insn_handler = emulate_ldcstc; | ||
1358 | return INSN_GOOD; | ||
1359 | } | ||
1360 | |||
1361 | static enum kprobe_insn __kprobes | ||
1362 | space_cccc_111x(kprobe_opcode_t insn, struct arch_specific_insn *asi) | ||
1363 | { | ||
1364 | /* BKPT : 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */ | ||
1365 | /* SWI : cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */ | ||
1366 | if ((insn & 0xfff000f0) == 0xe1200070 || | ||
1367 | (insn & 0x0f000000) == 0x0f000000) | ||
1368 | return INSN_REJECTED; | ||
1369 | |||
1370 | /* CDP : cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */ | ||
1371 | if ((insn & 0x0f000010) == 0x0e000000) { | ||
1372 | asi->insn[0] = insn; | ||
1373 | asi->insn_handler = emulate_none; | ||
1374 | return INSN_GOOD; | ||
1375 | } | ||
1376 | |||
1377 | /* MCR : cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */ | ||
1378 | /* MRC : cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */ | ||
1379 | insn &= 0xffff0fff; /* Rd = r0 */ | ||
1380 | asi->insn[0] = insn; | ||
1381 | asi->insn_handler = (insn & (1 << 20)) ? emulate_rd12 : emulate_ird12; | ||
1382 | return INSN_GOOD; | ||
1383 | } | ||
1384 | |||
1385 | /* Return: | ||
1386 | * INSN_REJECTED If instruction is one not allowed to kprobe, | ||
1387 | * INSN_GOOD If instruction is supported and uses instruction slot, | ||
1388 | * INSN_GOOD_NO_SLOT If instruction is supported but doesn't use its slot. | ||
1389 | * | ||
1390 | * For instructions we don't want to kprobe (INSN_REJECTED return result): | ||
1391 | * These are generally ones that modify the processor state making | ||
1392 | * them "hard" to simulate such as switches processor modes or | ||
1393 | * make accesses in alternate modes. Any of these could be simulated | ||
1394 | * if the work was put into it, but low return considering they | ||
1395 | * should also be very rare. | ||
1396 | */ | ||
1397 | enum kprobe_insn __kprobes | ||
1398 | arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi) | ||
1399 | { | ||
1400 | asi->insn[1] = KPROBE_RETURN_INSTRUCTION; | ||
1401 | |||
1402 | if ((insn & 0xf0000000) == 0xf0000000) { | ||
1403 | |||
1404 | return space_1111(insn, asi); | ||
1405 | |||
1406 | } else if ((insn & 0x0e000000) == 0x00000000) { | ||
1407 | |||
1408 | return space_cccc_000x(insn, asi); | ||
1409 | |||
1410 | } else if ((insn & 0x0e000000) == 0x02000000) { | ||
1411 | |||
1412 | return space_cccc_001x(insn, asi); | ||
1413 | |||
1414 | } else if ((insn & 0x0f000010) == 0x06000010) { | ||
1415 | |||
1416 | return space_cccc_0110__1(insn, asi); | ||
1417 | |||
1418 | } else if ((insn & 0x0f000010) == 0x07000010) { | ||
1419 | |||
1420 | return space_cccc_0111__1(insn, asi); | ||
1421 | |||
1422 | } else if ((insn & 0x0c000000) == 0x04000000) { | ||
1423 | |||
1424 | return space_cccc_01xx(insn, asi); | ||
1425 | |||
1426 | } else if ((insn & 0x0e000000) == 0x08000000) { | ||
1427 | |||
1428 | return space_cccc_100x(insn, asi); | ||
1429 | |||
1430 | } else if ((insn & 0x0e000000) == 0x0a000000) { | ||
1431 | |||
1432 | return space_cccc_101x(insn, asi); | ||
1433 | |||
1434 | } else if ((insn & 0x0fe00000) == 0x0c400000) { | ||
1435 | |||
1436 | return space_cccc_1100_010x(insn, asi); | ||
1437 | |||
1438 | } else if ((insn & 0x0e000000) == 0x0c400000) { | ||
1439 | |||
1440 | return space_cccc_110x(insn, asi); | ||
1441 | |||
1442 | } | ||
1443 | |||
1444 | return space_cccc_111x(insn, asi); | ||
1445 | } | ||
1446 | |||
1447 | void __init arm_kprobe_decode_init(void) | ||
1448 | { | ||
1449 | find_str_pc_offset(); | ||
1450 | } | ||
1451 | |||
1452 | |||
1453 | /* | ||
1454 | * All ARM instructions listed below. | ||
1455 | * | ||
1456 | * Instructions and their general purpose registers are given. | ||
1457 | * If a particular register may not use R15, it is prefixed with a "!". | ||
1458 | * If marked with a "*" means the value returned by reading R15 | ||
1459 | * is implementation defined. | ||
1460 | * | ||
1461 | * ADC/ADD/AND/BIC/CMN/CMP/EOR/MOV/MVN/ORR/RSB/RSC/SBC/SUB/TEQ | ||
1462 | * TST: Rd, Rn, Rm, !Rs | ||
1463 | * BX: Rm | ||
1464 | * BLX(2): !Rm | ||
1465 | * BX: Rm (R15 legal, but discouraged) | ||
1466 | * BXJ: !Rm, | ||
1467 | * CLZ: !Rd, !Rm | ||
1468 | * CPY: Rd, Rm | ||
1469 | * LDC/2,STC/2 immediate offset & unindex: Rn | ||
1470 | * LDC/2,STC/2 immediate pre/post-indexed: !Rn | ||
1471 | * LDM(1/3): !Rn, register_list | ||
1472 | * LDM(2): !Rn, !register_list | ||
1473 | * LDR,STR,PLD immediate offset: Rd, Rn | ||
1474 | * LDR,STR,PLD register offset: Rd, Rn, !Rm | ||
1475 | * LDR,STR,PLD scaled register offset: Rd, !Rn, !Rm | ||
1476 | * LDR,STR immediate pre/post-indexed: Rd, !Rn | ||
1477 | * LDR,STR register pre/post-indexed: Rd, !Rn, !Rm | ||
1478 | * LDR,STR scaled register pre/post-indexed: Rd, !Rn, !Rm | ||
1479 | * LDRB,STRB immediate offset: !Rd, Rn | ||
1480 | * LDRB,STRB register offset: !Rd, Rn, !Rm | ||
1481 | * LDRB,STRB scaled register offset: !Rd, !Rn, !Rm | ||
1482 | * LDRB,STRB immediate pre/post-indexed: !Rd, !Rn | ||
1483 | * LDRB,STRB register pre/post-indexed: !Rd, !Rn, !Rm | ||
1484 | * LDRB,STRB scaled register pre/post-indexed: !Rd, !Rn, !Rm | ||
1485 | * LDRT,LDRBT,STRBT immediate pre/post-indexed: !Rd, !Rn | ||
1486 | * LDRT,LDRBT,STRBT register pre/post-indexed: !Rd, !Rn, !Rm | ||
1487 | * LDRT,LDRBT,STRBT scaled register pre/post-indexed: !Rd, !Rn, !Rm | ||
1488 | * LDRH/SH/SB/D,STRH/SH/SB/D immediate offset: !Rd, Rn | ||
1489 | * LDRH/SH/SB/D,STRH/SH/SB/D register offset: !Rd, Rn, !Rm | ||
1490 | * LDRH/SH/SB/D,STRH/SH/SB/D immediate pre/post-indexed: !Rd, !Rn | ||
1491 | * LDRH/SH/SB/D,STRH/SH/SB/D register pre/post-indexed: !Rd, !Rn, !Rm | ||
1492 | * LDREX: !Rd, !Rn | ||
1493 | * MCR/2: !Rd | ||
1494 | * MCRR/2,MRRC/2: !Rd, !Rn | ||
1495 | * MLA: !Rd, !Rn, !Rm, !Rs | ||
1496 | * MOV: Rd | ||
1497 | * MRC/2: !Rd (if Rd==15, only changes cond codes, not the register) | ||
1498 | * MRS,MSR: !Rd | ||
1499 | * MUL: !Rd, !Rm, !Rs | ||
1500 | * PKH{BT,TB}: !Rd, !Rn, !Rm | ||
1501 | * QDADD,[U]QADD/16/8/SUBX: !Rd, !Rm, !Rn | ||
1502 | * QDSUB,[U]QSUB/16/8/ADDX: !Rd, !Rm, !Rn | ||
1503 | * REV/16/SH: !Rd, !Rm | ||
1504 | * RFE: !Rn | ||
1505 | * {S,U}[H]ADD{16,8,SUBX},{S,U}[H]SUB{16,8,ADDX}: !Rd, !Rn, !Rm | ||
1506 | * SEL: !Rd, !Rn, !Rm | ||
1507 | * SMLA<x><y>,SMLA{D,W<y>},SMLSD,SMML{A,S}: !Rd, !Rn, !Rm, !Rs | ||
1508 | * SMLAL<x><y>,SMLA{D,LD},SMLSLD,SMMULL,SMULW<y>: !RdHi, !RdLo, !Rm, !Rs | ||
1509 | * SMMUL,SMUAD,SMUL<x><y>,SMUSD: !Rd, !Rm, !Rs | ||
1510 | * SSAT/16: !Rd, !Rm | ||
1511 | * STM(1/2): !Rn, register_list* (R15 in reg list not recommended) | ||
1512 | * STRT immediate pre/post-indexed: Rd*, !Rn | ||
1513 | * STRT register pre/post-indexed: Rd*, !Rn, !Rm | ||
1514 | * STRT scaled register pre/post-indexed: Rd*, !Rn, !Rm | ||
1515 | * STREX: !Rd, !Rn, !Rm | ||
1516 | * SWP/B: !Rd, !Rn, !Rm | ||
1517 | * {S,U}XTA{B,B16,H}: !Rd, !Rn, !Rm | ||
1518 | * {S,U}XT{B,B16,H}: !Rd, !Rm | ||
1519 | * UM{AA,LA,UL}L: !RdHi, !RdLo, !Rm, !Rs | ||
1520 | * USA{D8,A8,T,T16}: !Rd, !Rm, !Rs | ||
1521 | * | ||
1522 | * May transfer control by writing R15 (possible mode changes or alternate | ||
1523 | * mode accesses marked by "*"): | ||
1524 | * ALU op (* with s-bit), B, BL, BKPT, BLX(1/2), BX, BXJ, CPS*, CPY, | ||
1525 | * LDM(1), LDM(2/3)*, LDR, MOV, RFE*, SWI* | ||
1526 | * | ||
1527 | * Instructions that do not take general registers, nor transfer control: | ||
1528 | * CDP/2, SETEND, SRS* | ||
1529 | */ | ||
diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c new file mode 100644 index 000000000000..a22a98c43ca5 --- /dev/null +++ b/arch/arm/kernel/kprobes.c | |||
@@ -0,0 +1,447 @@ | |||
1 | /* | ||
2 | * arch/arm/kernel/kprobes.c | ||
3 | * | ||
4 | * Kprobes on ARM | ||
5 | * | ||
6 | * Abhishek Sagar <sagar.abhishek@gmail.com> | ||
7 | * Copyright (C) 2006, 2007 Motorola Inc. | ||
8 | * | ||
9 | * Nicolas Pitre <nico@marvell.com> | ||
10 | * Copyright (C) 2007 Marvell Ltd. | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License version 2 as | ||
14 | * published by the Free Software Foundation. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
19 | * General Public License for more details. | ||
20 | */ | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/kprobes.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/stringify.h> | ||
26 | #include <asm/traps.h> | ||
27 | #include <asm/cacheflush.h> | ||
28 | |||
29 | #define MIN_STACK_SIZE(addr) \ | ||
30 | min((unsigned long)MAX_STACK_SIZE, \ | ||
31 | (unsigned long)current_thread_info() + THREAD_START_SP - (addr)) | ||
32 | |||
33 | #define flush_insns(addr, cnt) \ | ||
34 | flush_icache_range((unsigned long)(addr), \ | ||
35 | (unsigned long)(addr) + \ | ||
36 | sizeof(kprobe_opcode_t) * (cnt)) | ||
37 | |||
38 | /* Used as a marker in ARM_pc to note when we're in a jprobe. */ | ||
39 | #define JPROBE_MAGIC_ADDR 0xffffffff | ||
40 | |||
41 | DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; | ||
42 | DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); | ||
43 | |||
44 | |||
45 | int __kprobes arch_prepare_kprobe(struct kprobe *p) | ||
46 | { | ||
47 | kprobe_opcode_t insn; | ||
48 | kprobe_opcode_t tmp_insn[MAX_INSN_SIZE]; | ||
49 | unsigned long addr = (unsigned long)p->addr; | ||
50 | int is; | ||
51 | |||
52 | if (addr & 0x3 || in_exception_text(addr)) | ||
53 | return -EINVAL; | ||
54 | |||
55 | insn = *p->addr; | ||
56 | p->opcode = insn; | ||
57 | p->ainsn.insn = tmp_insn; | ||
58 | |||
59 | switch (arm_kprobe_decode_insn(insn, &p->ainsn)) { | ||
60 | case INSN_REJECTED: /* not supported */ | ||
61 | return -EINVAL; | ||
62 | |||
63 | case INSN_GOOD: /* instruction uses slot */ | ||
64 | p->ainsn.insn = get_insn_slot(); | ||
65 | if (!p->ainsn.insn) | ||
66 | return -ENOMEM; | ||
67 | for (is = 0; is < MAX_INSN_SIZE; ++is) | ||
68 | p->ainsn.insn[is] = tmp_insn[is]; | ||
69 | flush_insns(&p->ainsn.insn, MAX_INSN_SIZE); | ||
70 | break; | ||
71 | |||
72 | case INSN_GOOD_NO_SLOT: /* instruction doesn't need insn slot */ | ||
73 | p->ainsn.insn = NULL; | ||
74 | break; | ||
75 | } | ||
76 | |||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | void __kprobes arch_arm_kprobe(struct kprobe *p) | ||
81 | { | ||
82 | *p->addr = KPROBE_BREAKPOINT_INSTRUCTION; | ||
83 | flush_insns(p->addr, 1); | ||
84 | } | ||
85 | |||
86 | void __kprobes arch_disarm_kprobe(struct kprobe *p) | ||
87 | { | ||
88 | *p->addr = p->opcode; | ||
89 | flush_insns(p->addr, 1); | ||
90 | } | ||
91 | |||
92 | void __kprobes arch_remove_kprobe(struct kprobe *p) | ||
93 | { | ||
94 | if (p->ainsn.insn) { | ||
95 | mutex_lock(&kprobe_mutex); | ||
96 | free_insn_slot(p->ainsn.insn, 0); | ||
97 | mutex_unlock(&kprobe_mutex); | ||
98 | p->ainsn.insn = NULL; | ||
99 | } | ||
100 | } | ||
101 | |||
102 | static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) | ||
103 | { | ||
104 | kcb->prev_kprobe.kp = kprobe_running(); | ||
105 | kcb->prev_kprobe.status = kcb->kprobe_status; | ||
106 | } | ||
107 | |||
108 | static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb) | ||
109 | { | ||
110 | __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; | ||
111 | kcb->kprobe_status = kcb->prev_kprobe.status; | ||
112 | } | ||
113 | |||
114 | static void __kprobes set_current_kprobe(struct kprobe *p) | ||
115 | { | ||
116 | __get_cpu_var(current_kprobe) = p; | ||
117 | } | ||
118 | |||
119 | static void __kprobes singlestep(struct kprobe *p, struct pt_regs *regs, | ||
120 | struct kprobe_ctlblk *kcb) | ||
121 | { | ||
122 | regs->ARM_pc += 4; | ||
123 | p->ainsn.insn_handler(p, regs); | ||
124 | } | ||
125 | |||
126 | /* | ||
127 | * Called with IRQs disabled. IRQs must remain disabled from that point | ||
128 | * all the way until processing this kprobe is complete. The current | ||
129 | * kprobes implementation cannot process more than one nested level of | ||
130 | * kprobe, and that level is reserved for user kprobe handlers, so we can't | ||
131 | * risk encountering a new kprobe in an interrupt handler. | ||
132 | */ | ||
133 | void __kprobes kprobe_handler(struct pt_regs *regs) | ||
134 | { | ||
135 | struct kprobe *p, *cur; | ||
136 | struct kprobe_ctlblk *kcb; | ||
137 | kprobe_opcode_t *addr = (kprobe_opcode_t *)regs->ARM_pc; | ||
138 | |||
139 | kcb = get_kprobe_ctlblk(); | ||
140 | cur = kprobe_running(); | ||
141 | p = get_kprobe(addr); | ||
142 | |||
143 | if (p) { | ||
144 | if (cur) { | ||
145 | /* Kprobe is pending, so we're recursing. */ | ||
146 | switch (kcb->kprobe_status) { | ||
147 | case KPROBE_HIT_ACTIVE: | ||
148 | case KPROBE_HIT_SSDONE: | ||
149 | /* A pre- or post-handler probe got us here. */ | ||
150 | kprobes_inc_nmissed_count(p); | ||
151 | save_previous_kprobe(kcb); | ||
152 | set_current_kprobe(p); | ||
153 | kcb->kprobe_status = KPROBE_REENTER; | ||
154 | singlestep(p, regs, kcb); | ||
155 | restore_previous_kprobe(kcb); | ||
156 | break; | ||
157 | default: | ||
158 | /* impossible cases */ | ||
159 | BUG(); | ||
160 | } | ||
161 | } else { | ||
162 | set_current_kprobe(p); | ||
163 | kcb->kprobe_status = KPROBE_HIT_ACTIVE; | ||
164 | |||
165 | /* | ||
166 | * If we have no pre-handler or it returned 0, we | ||
167 | * continue with normal processing. If we have a | ||
168 | * pre-handler and it returned non-zero, it prepped | ||
169 | * for calling the break_handler below on re-entry, | ||
170 | * so get out doing nothing more here. | ||
171 | */ | ||
172 | if (!p->pre_handler || !p->pre_handler(p, regs)) { | ||
173 | kcb->kprobe_status = KPROBE_HIT_SS; | ||
174 | singlestep(p, regs, kcb); | ||
175 | if (p->post_handler) { | ||
176 | kcb->kprobe_status = KPROBE_HIT_SSDONE; | ||
177 | p->post_handler(p, regs, 0); | ||
178 | } | ||
179 | reset_current_kprobe(); | ||
180 | } | ||
181 | } | ||
182 | } else if (cur) { | ||
183 | /* We probably hit a jprobe. Call its break handler. */ | ||
184 | if (cur->break_handler && cur->break_handler(cur, regs)) { | ||
185 | kcb->kprobe_status = KPROBE_HIT_SS; | ||
186 | singlestep(cur, regs, kcb); | ||
187 | if (cur->post_handler) { | ||
188 | kcb->kprobe_status = KPROBE_HIT_SSDONE; | ||
189 | cur->post_handler(cur, regs, 0); | ||
190 | } | ||
191 | } | ||
192 | reset_current_kprobe(); | ||
193 | } else { | ||
194 | /* | ||
195 | * The probe was removed and a race is in progress. | ||
196 | * There is nothing we can do about it. Let's restart | ||
197 | * the instruction. By the time we can restart, the | ||
198 | * real instruction will be there. | ||
199 | */ | ||
200 | } | ||
201 | } | ||
202 | |||
203 | int kprobe_trap_handler(struct pt_regs *regs, unsigned int instr) | ||
204 | { | ||
205 | kprobe_handler(regs); | ||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr) | ||
210 | { | ||
211 | struct kprobe *cur = kprobe_running(); | ||
212 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | ||
213 | |||
214 | switch (kcb->kprobe_status) { | ||
215 | case KPROBE_HIT_SS: | ||
216 | case KPROBE_REENTER: | ||
217 | /* | ||
218 | * We are here because the instruction being single | ||
219 | * stepped caused a page fault. We reset the current | ||
220 | * kprobe and the PC to point back to the probe address | ||
221 | * and allow the page fault handler to continue as a | ||
222 | * normal page fault. | ||
223 | */ | ||
224 | regs->ARM_pc = (long)cur->addr; | ||
225 | if (kcb->kprobe_status == KPROBE_REENTER) { | ||
226 | restore_previous_kprobe(kcb); | ||
227 | } else { | ||
228 | reset_current_kprobe(); | ||
229 | } | ||
230 | break; | ||
231 | |||
232 | case KPROBE_HIT_ACTIVE: | ||
233 | case KPROBE_HIT_SSDONE: | ||
234 | /* | ||
235 | * We increment the nmissed count for accounting, | ||
236 | * we can also use npre/npostfault count for accounting | ||
237 | * these specific fault cases. | ||
238 | */ | ||
239 | kprobes_inc_nmissed_count(cur); | ||
240 | |||
241 | /* | ||
242 | * We come here because instructions in the pre/post | ||
243 | * handler caused the page_fault, this could happen | ||
244 | * if handler tries to access user space by | ||
245 | * copy_from_user(), get_user() etc. Let the | ||
246 | * user-specified handler try to fix it. | ||
247 | */ | ||
248 | if (cur->fault_handler && cur->fault_handler(cur, regs, fsr)) | ||
249 | return 1; | ||
250 | break; | ||
251 | |||
252 | default: | ||
253 | break; | ||
254 | } | ||
255 | |||
256 | return 0; | ||
257 | } | ||
258 | |||
259 | int __kprobes kprobe_exceptions_notify(struct notifier_block *self, | ||
260 | unsigned long val, void *data) | ||
261 | { | ||
262 | /* | ||
263 | * notify_die() is currently never called on ARM, | ||
264 | * so this callback is currently empty. | ||
265 | */ | ||
266 | return NOTIFY_DONE; | ||
267 | } | ||
268 | |||
269 | /* | ||
270 | * When a retprobed function returns, trampoline_handler() is called, | ||
271 | * calling the kretprobe's handler. We construct a struct pt_regs to | ||
272 | * give a view of registers r0-r11 to the user return-handler. This is | ||
273 | * not a complete pt_regs structure, but that should be plenty sufficient | ||
274 | * for kretprobe handlers which should normally be interested in r0 only | ||
275 | * anyway. | ||
276 | */ | ||
277 | static void __attribute__((naked)) __kprobes kretprobe_trampoline(void) | ||
278 | { | ||
279 | __asm__ __volatile__ ( | ||
280 | "stmdb sp!, {r0 - r11} \n\t" | ||
281 | "mov r0, sp \n\t" | ||
282 | "bl trampoline_handler \n\t" | ||
283 | "mov lr, r0 \n\t" | ||
284 | "ldmia sp!, {r0 - r11} \n\t" | ||
285 | "mov pc, lr \n\t" | ||
286 | : : : "memory"); | ||
287 | } | ||
288 | |||
289 | /* Called from kretprobe_trampoline */ | ||
290 | static __used __kprobes void *trampoline_handler(struct pt_regs *regs) | ||
291 | { | ||
292 | struct kretprobe_instance *ri = NULL; | ||
293 | struct hlist_head *head, empty_rp; | ||
294 | struct hlist_node *node, *tmp; | ||
295 | unsigned long flags, orig_ret_address = 0; | ||
296 | unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline; | ||
297 | |||
298 | INIT_HLIST_HEAD(&empty_rp); | ||
299 | spin_lock_irqsave(&kretprobe_lock, flags); | ||
300 | head = kretprobe_inst_table_head(current); | ||
301 | |||
302 | /* | ||
303 | * It is possible to have multiple instances associated with a given | ||
304 | * task either because multiple functions in the call path have | ||
305 | * a return probe installed on them, and/or more than one return | ||
306 | * probe was registered for a target function. | ||
307 | * | ||
308 | * We can handle this because: | ||
309 | * - instances are always inserted at the head of the list | ||
310 | * - when multiple return probes are registered for the same | ||
311 | * function, the first instance's ret_addr will point to the | ||
312 | * real return address, and all the rest will point to | ||
313 | * kretprobe_trampoline | ||
314 | */ | ||
315 | hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { | ||
316 | if (ri->task != current) | ||
317 | /* another task is sharing our hash bucket */ | ||
318 | continue; | ||
319 | |||
320 | if (ri->rp && ri->rp->handler) { | ||
321 | __get_cpu_var(current_kprobe) = &ri->rp->kp; | ||
322 | get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE; | ||
323 | ri->rp->handler(ri, regs); | ||
324 | __get_cpu_var(current_kprobe) = NULL; | ||
325 | } | ||
326 | |||
327 | orig_ret_address = (unsigned long)ri->ret_addr; | ||
328 | recycle_rp_inst(ri, &empty_rp); | ||
329 | |||
330 | if (orig_ret_address != trampoline_address) | ||
331 | /* | ||
332 | * This is the real return address. Any other | ||
333 | * instances associated with this task are for | ||
334 | * other calls deeper on the call stack | ||
335 | */ | ||
336 | break; | ||
337 | } | ||
338 | |||
339 | kretprobe_assert(ri, orig_ret_address, trampoline_address); | ||
340 | spin_unlock_irqrestore(&kretprobe_lock, flags); | ||
341 | |||
342 | hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) { | ||
343 | hlist_del(&ri->hlist); | ||
344 | kfree(ri); | ||
345 | } | ||
346 | |||
347 | return (void *)orig_ret_address; | ||
348 | } | ||
349 | |||
350 | /* Called with kretprobe_lock held. */ | ||
351 | void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, | ||
352 | struct pt_regs *regs) | ||
353 | { | ||
354 | ri->ret_addr = (kprobe_opcode_t *)regs->ARM_lr; | ||
355 | |||
356 | /* Replace the return addr with trampoline addr. */ | ||
357 | regs->ARM_lr = (unsigned long)&kretprobe_trampoline; | ||
358 | } | ||
359 | |||
360 | int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | ||
361 | { | ||
362 | struct jprobe *jp = container_of(p, struct jprobe, kp); | ||
363 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | ||
364 | long sp_addr = regs->ARM_sp; | ||
365 | |||
366 | kcb->jprobe_saved_regs = *regs; | ||
367 | memcpy(kcb->jprobes_stack, (void *)sp_addr, MIN_STACK_SIZE(sp_addr)); | ||
368 | regs->ARM_pc = (long)jp->entry; | ||
369 | regs->ARM_cpsr |= PSR_I_BIT; | ||
370 | preempt_disable(); | ||
371 | return 1; | ||
372 | } | ||
373 | |||
374 | void __kprobes jprobe_return(void) | ||
375 | { | ||
376 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | ||
377 | |||
378 | __asm__ __volatile__ ( | ||
379 | /* | ||
380 | * Setup an empty pt_regs. Fill SP and PC fields as | ||
381 | * they're needed by longjmp_break_handler. | ||
382 | */ | ||
383 | "sub sp, %0, %1 \n\t" | ||
384 | "ldr r0, ="__stringify(JPROBE_MAGIC_ADDR)"\n\t" | ||
385 | "str %0, [sp, %2] \n\t" | ||
386 | "str r0, [sp, %3] \n\t" | ||
387 | "mov r0, sp \n\t" | ||
388 | "bl kprobe_handler \n\t" | ||
389 | |||
390 | /* | ||
391 | * Return to the context saved by setjmp_pre_handler | ||
392 | * and restored by longjmp_break_handler. | ||
393 | */ | ||
394 | "ldr r0, [sp, %4] \n\t" | ||
395 | "msr cpsr_cxsf, r0 \n\t" | ||
396 | "ldmia sp, {r0 - pc} \n\t" | ||
397 | : | ||
398 | : "r" (kcb->jprobe_saved_regs.ARM_sp), | ||
399 | "I" (sizeof(struct pt_regs)), | ||
400 | "J" (offsetof(struct pt_regs, ARM_sp)), | ||
401 | "J" (offsetof(struct pt_regs, ARM_pc)), | ||
402 | "J" (offsetof(struct pt_regs, ARM_cpsr)) | ||
403 | : "memory", "cc"); | ||
404 | } | ||
405 | |||
406 | int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) | ||
407 | { | ||
408 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | ||
409 | long stack_addr = kcb->jprobe_saved_regs.ARM_sp; | ||
410 | long orig_sp = regs->ARM_sp; | ||
411 | struct jprobe *jp = container_of(p, struct jprobe, kp); | ||
412 | |||
413 | if (regs->ARM_pc == JPROBE_MAGIC_ADDR) { | ||
414 | if (orig_sp != stack_addr) { | ||
415 | struct pt_regs *saved_regs = | ||
416 | (struct pt_regs *)kcb->jprobe_saved_regs.ARM_sp; | ||
417 | printk("current sp %lx does not match saved sp %lx\n", | ||
418 | orig_sp, stack_addr); | ||
419 | printk("Saved registers for jprobe %p\n", jp); | ||
420 | show_regs(saved_regs); | ||
421 | printk("Current registers\n"); | ||
422 | show_regs(regs); | ||
423 | BUG(); | ||
424 | } | ||
425 | *regs = kcb->jprobe_saved_regs; | ||
426 | memcpy((void *)stack_addr, kcb->jprobes_stack, | ||
427 | MIN_STACK_SIZE(stack_addr)); | ||
428 | preempt_enable_no_resched(); | ||
429 | return 1; | ||
430 | } | ||
431 | return 0; | ||
432 | } | ||
433 | |||
434 | static struct undef_hook kprobes_break_hook = { | ||
435 | .instr_mask = 0xffffffff, | ||
436 | .instr_val = KPROBE_BREAKPOINT_INSTRUCTION, | ||
437 | .cpsr_mask = MODE_MASK, | ||
438 | .cpsr_val = SVC_MODE, | ||
439 | .fn = kprobe_trap_handler, | ||
440 | }; | ||
441 | |||
442 | int __init arch_init_kprobes() | ||
443 | { | ||
444 | arm_kprobe_decode_init(); | ||
445 | register_undef_hook(&kprobes_break_hook); | ||
446 | return 0; | ||
447 | } | ||
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index e59b5b84168d..b5867eca1d0b 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c | |||
@@ -325,7 +325,9 @@ void timer_tick(void) | |||
325 | profile_tick(CPU_PROFILING); | 325 | profile_tick(CPU_PROFILING); |
326 | do_leds(); | 326 | do_leds(); |
327 | do_set_rtc(); | 327 | do_set_rtc(); |
328 | write_seqlock(&xtime_lock); | ||
328 | do_timer(1); | 329 | do_timer(1); |
330 | write_sequnlock(&xtime_lock); | ||
329 | #ifndef CONFIG_SMP | 331 | #ifndef CONFIG_SMP |
330 | update_process_times(user_mode(get_irq_regs())); | 332 | update_process_times(user_mode(get_irq_regs())); |
331 | #endif | 333 | #endif |
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index c34db4e868fa..5595fdd75e82 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/kallsyms.h> | 19 | #include <linux/kallsyms.h> |
20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/kprobes.h> | ||
22 | 23 | ||
23 | #include <asm/atomic.h> | 24 | #include <asm/atomic.h> |
24 | #include <asm/cacheflush.h> | 25 | #include <asm/cacheflush.h> |
@@ -46,15 +47,6 @@ __setup("user_debug=", user_debug_setup); | |||
46 | 47 | ||
47 | static void dump_mem(const char *str, unsigned long bottom, unsigned long top); | 48 | static void dump_mem(const char *str, unsigned long bottom, unsigned long top); |
48 | 49 | ||
49 | static inline int in_exception_text(unsigned long ptr) | ||
50 | { | ||
51 | extern char __exception_text_start[]; | ||
52 | extern char __exception_text_end[]; | ||
53 | |||
54 | return ptr >= (unsigned long)&__exception_text_start && | ||
55 | ptr < (unsigned long)&__exception_text_end; | ||
56 | } | ||
57 | |||
58 | void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame) | 50 | void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame) |
59 | { | 51 | { |
60 | #ifdef CONFIG_KALLSYMS | 52 | #ifdef CONFIG_KALLSYMS |
@@ -322,6 +314,17 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs) | |||
322 | get_user(instr, (u32 __user *)pc); | 314 | get_user(instr, (u32 __user *)pc); |
323 | } | 315 | } |
324 | 316 | ||
317 | #ifdef CONFIG_KPROBES | ||
318 | /* | ||
319 | * It is possible to have recursive kprobes, so we can't call | ||
320 | * the kprobe trap handler with the undef_lock held. | ||
321 | */ | ||
322 | if (instr == KPROBE_BREAKPOINT_INSTRUCTION && !user_mode(regs)) { | ||
323 | kprobe_trap_handler(regs, instr); | ||
324 | return; | ||
325 | } | ||
326 | #endif | ||
327 | |||
325 | spin_lock_irqsave(&undef_lock, flags); | 328 | spin_lock_irqsave(&undef_lock, flags); |
326 | list_for_each_entry(hook, &undef_hook, node) { | 329 | list_for_each_entry(hook, &undef_hook, node) { |
327 | if ((instr & hook->instr_mask) == hook->instr_val && | 330 | if ((instr & hook->instr_mask) == hook->instr_val && |
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index 5ff5406666b4..30f732c7fdb5 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S | |||
@@ -94,6 +94,7 @@ SECTIONS | |||
94 | TEXT_TEXT | 94 | TEXT_TEXT |
95 | SCHED_TEXT | 95 | SCHED_TEXT |
96 | LOCK_TEXT | 96 | LOCK_TEXT |
97 | KPROBES_TEXT | ||
97 | #ifdef CONFIG_MMU | 98 | #ifdef CONFIG_MMU |
98 | *(.fixup) | 99 | *(.fixup) |
99 | #endif | 100 | #endif |
diff --git a/arch/arm/mach-aaec2000/core.c b/arch/arm/mach-aaec2000/core.c index 0446ef2f5bd6..b016be2b0e35 100644 --- a/arch/arm/mach-aaec2000/core.c +++ b/arch/arm/mach-aaec2000/core.c | |||
@@ -130,13 +130,9 @@ static irqreturn_t | |||
130 | aaec2000_timer_interrupt(int irq, void *dev_id) | 130 | aaec2000_timer_interrupt(int irq, void *dev_id) |
131 | { | 131 | { |
132 | /* TODO: Check timer accuracy */ | 132 | /* TODO: Check timer accuracy */ |
133 | write_seqlock(&xtime_lock); | ||
134 | |||
135 | timer_tick(); | 133 | timer_tick(); |
136 | TIMER1_CLEAR = 1; | 134 | TIMER1_CLEAR = 1; |
137 | 135 | ||
138 | write_sequnlock(&xtime_lock); | ||
139 | |||
140 | return IRQ_HANDLED; | 136 | return IRQ_HANDLED; |
141 | } | 137 | } |
142 | 138 | ||
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 05a9f8a1b45e..5b0422cdde76 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig | |||
@@ -22,6 +22,9 @@ config ARCH_AT91SAM9263 | |||
22 | config ARCH_AT91SAM9RL | 22 | config ARCH_AT91SAM9RL |
23 | bool "AT91SAM9RL" | 23 | bool "AT91SAM9RL" |
24 | 24 | ||
25 | config ARCH_AT91CAP9 | ||
26 | bool "AT91CAP9" | ||
27 | |||
25 | config ARCH_AT91X40 | 28 | config ARCH_AT91X40 |
26 | bool "AT91x40" | 29 | bool "AT91x40" |
27 | 30 | ||
@@ -178,6 +181,21 @@ endif | |||
178 | 181 | ||
179 | # ---------------------------------------------------------- | 182 | # ---------------------------------------------------------- |
180 | 183 | ||
184 | if ARCH_AT91CAP9 | ||
185 | |||
186 | comment "AT91CAP9 Board Type" | ||
187 | |||
188 | config MACH_AT91CAP9ADK | ||
189 | bool "Atmel AT91CAP9A-DK Evaluation Kit" | ||
190 | depends on ARCH_AT91CAP9 | ||
191 | help | ||
192 | Select this if you are using Atmel's AT91CAP9A-DK Evaluation Kit. | ||
193 | <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4138> | ||
194 | |||
195 | endif | ||
196 | |||
197 | # ---------------------------------------------------------- | ||
198 | |||
181 | if ARCH_AT91X40 | 199 | if ARCH_AT91X40 |
182 | 200 | ||
183 | comment "AT91X40 Board Type" | 201 | comment "AT91X40 Board Type" |
@@ -198,13 +216,13 @@ comment "AT91 Board Options" | |||
198 | 216 | ||
199 | config MTD_AT91_DATAFLASH_CARD | 217 | config MTD_AT91_DATAFLASH_CARD |
200 | bool "Enable DataFlash Card support" | 218 | bool "Enable DataFlash Card support" |
201 | depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK) | 219 | depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91CAP9ADK) |
202 | help | 220 | help |
203 | Enable support for the DataFlash card. | 221 | Enable support for the DataFlash card. |
204 | 222 | ||
205 | config MTD_NAND_AT91_BUSWIDTH_16 | 223 | config MTD_NAND_AT91_BUSWIDTH_16 |
206 | bool "Enable 16-bit data bus interface to NAND flash" | 224 | bool "Enable 16-bit data bus interface to NAND flash" |
207 | depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK) | 225 | depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91CAP9ADK) |
208 | help | 226 | help |
209 | On AT91SAM926x boards both types of NAND flash can be present | 227 | On AT91SAM926x boards both types of NAND flash can be present |
210 | (8 and 16 bit data bus width). | 228 | (8 and 16 bit data bus width). |
@@ -219,6 +237,22 @@ config AT91_PROGRAMMABLE_CLOCKS | |||
219 | Select this if you need to program one or more of the PCK0..PCK3 | 237 | Select this if you need to program one or more of the PCK0..PCK3 |
220 | programmable clock outputs. | 238 | programmable clock outputs. |
221 | 239 | ||
240 | config AT91_TIMER_HZ | ||
241 | int "Kernel HZ (jiffies per second)" | ||
242 | range 32 1024 | ||
243 | depends on ARCH_AT91 | ||
244 | default "128" if ARCH_AT91RM9200 | ||
245 | default "100" | ||
246 | help | ||
247 | On AT91rm9200 chips where you're using a system clock derived | ||
248 | from the 32768 Hz hardware clock, this tick rate should divide | ||
249 | it exactly: use a power-of-two value, such as 128 or 256, to | ||
250 | reduce timing errors caused by rounding. | ||
251 | |||
252 | On AT91sam926x chips, or otherwise when using a higher precision | ||
253 | system clock (of at least several MHz), rounding is less of a | ||
254 | problem so it can be safer to use a decimal values like 100. | ||
255 | |||
222 | endmenu | 256 | endmenu |
223 | 257 | ||
224 | endif | 258 | endif |
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index a21f08c64ea6..bf5f293dccf8 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile | |||
@@ -8,7 +8,6 @@ obj-n := | |||
8 | obj- := | 8 | obj- := |
9 | 9 | ||
10 | obj-$(CONFIG_AT91_PMC_UNIT) += clock.o | 10 | obj-$(CONFIG_AT91_PMC_UNIT) += clock.o |
11 | obj-$(CONFIG_PM) += pm.o | ||
12 | 11 | ||
13 | # CPU-specific support | 12 | # CPU-specific support |
14 | obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.o | 13 | obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.o |
@@ -16,6 +15,7 @@ obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_d | |||
16 | obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o | 15 | obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o |
17 | obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o | 16 | obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o |
18 | obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o | 17 | obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o |
18 | obj-$(CONFIG_ARCH_AT91CAP9) += at91cap9.o at91sam926x_time.o at91cap9_devices.o | ||
19 | obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o | 19 | obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o |
20 | 20 | ||
21 | # AT91RM9200 board-specific support | 21 | # AT91RM9200 board-specific support |
@@ -29,7 +29,6 @@ obj-$(CONFIG_MACH_KB9200) += board-kb9202.o | |||
29 | obj-$(CONFIG_MACH_ATEB9200) += board-eb9200.o | 29 | obj-$(CONFIG_MACH_ATEB9200) += board-eb9200.o |
30 | obj-$(CONFIG_MACH_KAFA) += board-kafa.o | 30 | obj-$(CONFIG_MACH_KAFA) += board-kafa.o |
31 | obj-$(CONFIG_MACH_PICOTUX2XX) += board-picotux200.o | 31 | obj-$(CONFIG_MACH_PICOTUX2XX) += board-picotux200.o |
32 | obj-$(CONFIG_MACH_AT91EB01) += board-eb01.o | ||
33 | 32 | ||
34 | # AT91SAM9260 board-specific support | 33 | # AT91SAM9260 board-specific support |
35 | obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o | 34 | obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o |
@@ -43,19 +42,17 @@ obj-$(CONFIG_MACH_AT91SAM9263EK) += board-sam9263ek.o | |||
43 | # AT91SAM9RL board-specific support | 42 | # AT91SAM9RL board-specific support |
44 | obj-$(CONFIG_MACH_AT91SAM9RLEK) += board-sam9rlek.o | 43 | obj-$(CONFIG_MACH_AT91SAM9RLEK) += board-sam9rlek.o |
45 | 44 | ||
46 | # LEDs support | 45 | # AT91CAP9 board-specific support |
47 | led-$(CONFIG_ARCH_AT91RM9200DK) += leds.o | 46 | obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o |
48 | led-$(CONFIG_MACH_AT91RM9200EK) += leds.o | ||
49 | led-$(CONFIG_MACH_AT91SAM9261EK)+= leds.o | ||
50 | led-$(CONFIG_MACH_CSB337) += leds.o | ||
51 | led-$(CONFIG_MACH_CSB637) += leds.o | ||
52 | led-$(CONFIG_MACH_KB9200) += leds.o | ||
53 | led-$(CONFIG_MACH_KAFA) += leds.o | ||
54 | obj-$(CONFIG_LEDS) += $(led-y) | ||
55 | 47 | ||
56 | # VGA support | 48 | # AT91X40 board-specific support |
57 | #obj-$(CONFIG_FB_S1D13XXX) += ics1523.o | 49 | obj-$(CONFIG_MACH_AT91EB01) += board-eb01.o |
58 | 50 | ||
51 | # Drivers | ||
52 | obj-y += leds.o | ||
53 | |||
54 | # Power Management | ||
55 | obj-$(CONFIG_PM) += pm.o | ||
59 | 56 | ||
60 | ifeq ($(CONFIG_PM_DEBUG),y) | 57 | ifeq ($(CONFIG_PM_DEBUG),y) |
61 | CFLAGS_pm.o += -DDEBUG | 58 | CFLAGS_pm.o += -DDEBUG |
diff --git a/arch/arm/mach-at91/Makefile.boot b/arch/arm/mach-at91/Makefile.boot index e667dcc7cd34..071a2506a69f 100644 --- a/arch/arm/mach-at91/Makefile.boot +++ b/arch/arm/mach-at91/Makefile.boot | |||
@@ -3,7 +3,12 @@ | |||
3 | # PARAMS_PHYS must be within 4MB of ZRELADDR | 3 | # PARAMS_PHYS must be within 4MB of ZRELADDR |
4 | # INITRD_PHYS must be in RAM | 4 | # INITRD_PHYS must be in RAM |
5 | 5 | ||
6 | ifeq ($(CONFIG_ARCH_AT91CAP9),y) | ||
7 | zreladdr-y := 0x70008000 | ||
8 | params_phys-y := 0x70000100 | ||
9 | initrd_phys-y := 0x70410000 | ||
10 | else | ||
6 | zreladdr-y := 0x20008000 | 11 | zreladdr-y := 0x20008000 |
7 | params_phys-y := 0x20000100 | 12 | params_phys-y := 0x20000100 |
8 | initrd_phys-y := 0x20410000 | 13 | initrd_phys-y := 0x20410000 |
9 | 14 | endif | |
diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c new file mode 100644 index 000000000000..48d27d8000b0 --- /dev/null +++ b/arch/arm/mach-at91/at91cap9.c | |||
@@ -0,0 +1,365 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-at91/at91cap9.c | ||
3 | * | ||
4 | * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com> | ||
5 | * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com> | ||
6 | * Copyright (C) 2007 Atmel Corporation. | ||
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 | */ | ||
14 | |||
15 | #include <linux/module.h> | ||
16 | |||
17 | #include <asm/mach/arch.h> | ||
18 | #include <asm/mach/map.h> | ||
19 | #include <asm/arch/at91cap9.h> | ||
20 | #include <asm/arch/at91_pmc.h> | ||
21 | #include <asm/arch/at91_rstc.h> | ||
22 | |||
23 | #include "generic.h" | ||
24 | #include "clock.h" | ||
25 | |||
26 | static struct map_desc at91cap9_io_desc[] __initdata = { | ||
27 | { | ||
28 | .virtual = AT91_VA_BASE_SYS, | ||
29 | .pfn = __phys_to_pfn(AT91_BASE_SYS), | ||
30 | .length = SZ_16K, | ||
31 | .type = MT_DEVICE, | ||
32 | }, { | ||
33 | .virtual = AT91_IO_VIRT_BASE - AT91CAP9_SRAM_SIZE, | ||
34 | .pfn = __phys_to_pfn(AT91CAP9_SRAM_BASE), | ||
35 | .length = AT91CAP9_SRAM_SIZE, | ||
36 | .type = MT_DEVICE, | ||
37 | }, | ||
38 | }; | ||
39 | |||
40 | /* -------------------------------------------------------------------- | ||
41 | * Clocks | ||
42 | * -------------------------------------------------------------------- */ | ||
43 | |||
44 | /* | ||
45 | * The peripheral clocks. | ||
46 | */ | ||
47 | static struct clk pioABCD_clk = { | ||
48 | .name = "pioABCD_clk", | ||
49 | .pmc_mask = 1 << AT91CAP9_ID_PIOABCD, | ||
50 | .type = CLK_TYPE_PERIPHERAL, | ||
51 | }; | ||
52 | static struct clk mpb0_clk = { | ||
53 | .name = "mpb0_clk", | ||
54 | .pmc_mask = 1 << AT91CAP9_ID_MPB0, | ||
55 | .type = CLK_TYPE_PERIPHERAL, | ||
56 | }; | ||
57 | static struct clk mpb1_clk = { | ||
58 | .name = "mpb1_clk", | ||
59 | .pmc_mask = 1 << AT91CAP9_ID_MPB1, | ||
60 | .type = CLK_TYPE_PERIPHERAL, | ||
61 | }; | ||
62 | static struct clk mpb2_clk = { | ||
63 | .name = "mpb2_clk", | ||
64 | .pmc_mask = 1 << AT91CAP9_ID_MPB2, | ||
65 | .type = CLK_TYPE_PERIPHERAL, | ||
66 | }; | ||
67 | static struct clk mpb3_clk = { | ||
68 | .name = "mpb3_clk", | ||
69 | .pmc_mask = 1 << AT91CAP9_ID_MPB3, | ||
70 | .type = CLK_TYPE_PERIPHERAL, | ||
71 | }; | ||
72 | static struct clk mpb4_clk = { | ||
73 | .name = "mpb4_clk", | ||
74 | .pmc_mask = 1 << AT91CAP9_ID_MPB4, | ||
75 | .type = CLK_TYPE_PERIPHERAL, | ||
76 | }; | ||
77 | static struct clk usart0_clk = { | ||
78 | .name = "usart0_clk", | ||
79 | .pmc_mask = 1 << AT91CAP9_ID_US0, | ||
80 | .type = CLK_TYPE_PERIPHERAL, | ||
81 | }; | ||
82 | static struct clk usart1_clk = { | ||
83 | .name = "usart1_clk", | ||
84 | .pmc_mask = 1 << AT91CAP9_ID_US1, | ||
85 | .type = CLK_TYPE_PERIPHERAL, | ||
86 | }; | ||
87 | static struct clk usart2_clk = { | ||
88 | .name = "usart2_clk", | ||
89 | .pmc_mask = 1 << AT91CAP9_ID_US2, | ||
90 | .type = CLK_TYPE_PERIPHERAL, | ||
91 | }; | ||
92 | static struct clk mmc0_clk = { | ||
93 | .name = "mci0_clk", | ||
94 | .pmc_mask = 1 << AT91CAP9_ID_MCI0, | ||
95 | .type = CLK_TYPE_PERIPHERAL, | ||
96 | }; | ||
97 | static struct clk mmc1_clk = { | ||
98 | .name = "mci1_clk", | ||
99 | .pmc_mask = 1 << AT91CAP9_ID_MCI1, | ||
100 | .type = CLK_TYPE_PERIPHERAL, | ||
101 | }; | ||
102 | static struct clk can_clk = { | ||
103 | .name = "can_clk", | ||
104 | .pmc_mask = 1 << AT91CAP9_ID_CAN, | ||
105 | .type = CLK_TYPE_PERIPHERAL, | ||
106 | }; | ||
107 | static struct clk twi_clk = { | ||
108 | .name = "twi_clk", | ||
109 | .pmc_mask = 1 << AT91CAP9_ID_TWI, | ||
110 | .type = CLK_TYPE_PERIPHERAL, | ||
111 | }; | ||
112 | static struct clk spi0_clk = { | ||
113 | .name = "spi0_clk", | ||
114 | .pmc_mask = 1 << AT91CAP9_ID_SPI0, | ||
115 | .type = CLK_TYPE_PERIPHERAL, | ||
116 | }; | ||
117 | static struct clk spi1_clk = { | ||
118 | .name = "spi1_clk", | ||
119 | .pmc_mask = 1 << AT91CAP9_ID_SPI1, | ||
120 | .type = CLK_TYPE_PERIPHERAL, | ||
121 | }; | ||
122 | static struct clk ssc0_clk = { | ||
123 | .name = "ssc0_clk", | ||
124 | .pmc_mask = 1 << AT91CAP9_ID_SSC0, | ||
125 | .type = CLK_TYPE_PERIPHERAL, | ||
126 | }; | ||
127 | static struct clk ssc1_clk = { | ||
128 | .name = "ssc1_clk", | ||
129 | .pmc_mask = 1 << AT91CAP9_ID_SSC1, | ||
130 | .type = CLK_TYPE_PERIPHERAL, | ||
131 | }; | ||
132 | static struct clk ac97_clk = { | ||
133 | .name = "ac97_clk", | ||
134 | .pmc_mask = 1 << AT91CAP9_ID_AC97C, | ||
135 | .type = CLK_TYPE_PERIPHERAL, | ||
136 | }; | ||
137 | static struct clk tcb_clk = { | ||
138 | .name = "tcb_clk", | ||
139 | .pmc_mask = 1 << AT91CAP9_ID_TCB, | ||
140 | .type = CLK_TYPE_PERIPHERAL, | ||
141 | }; | ||
142 | static struct clk pwmc_clk = { | ||
143 | .name = "pwmc_clk", | ||
144 | .pmc_mask = 1 << AT91CAP9_ID_PWMC, | ||
145 | .type = CLK_TYPE_PERIPHERAL, | ||
146 | }; | ||
147 | static struct clk macb_clk = { | ||
148 | .name = "macb_clk", | ||
149 | .pmc_mask = 1 << AT91CAP9_ID_EMAC, | ||
150 | .type = CLK_TYPE_PERIPHERAL, | ||
151 | }; | ||
152 | static struct clk aestdes_clk = { | ||
153 | .name = "aestdes_clk", | ||
154 | .pmc_mask = 1 << AT91CAP9_ID_AESTDES, | ||
155 | .type = CLK_TYPE_PERIPHERAL, | ||
156 | }; | ||
157 | static struct clk adc_clk = { | ||
158 | .name = "adc_clk", | ||
159 | .pmc_mask = 1 << AT91CAP9_ID_ADC, | ||
160 | .type = CLK_TYPE_PERIPHERAL, | ||
161 | }; | ||
162 | static struct clk isi_clk = { | ||
163 | .name = "isi_clk", | ||
164 | .pmc_mask = 1 << AT91CAP9_ID_ISI, | ||
165 | .type = CLK_TYPE_PERIPHERAL, | ||
166 | }; | ||
167 | static struct clk lcdc_clk = { | ||
168 | .name = "lcdc_clk", | ||
169 | .pmc_mask = 1 << AT91CAP9_ID_LCDC, | ||
170 | .type = CLK_TYPE_PERIPHERAL, | ||
171 | }; | ||
172 | static struct clk dma_clk = { | ||
173 | .name = "dma_clk", | ||
174 | .pmc_mask = 1 << AT91CAP9_ID_DMA, | ||
175 | .type = CLK_TYPE_PERIPHERAL, | ||
176 | }; | ||
177 | static struct clk udphs_clk = { | ||
178 | .name = "udphs_clk", | ||
179 | .pmc_mask = 1 << AT91CAP9_ID_UDPHS, | ||
180 | .type = CLK_TYPE_PERIPHERAL, | ||
181 | }; | ||
182 | static struct clk ohci_clk = { | ||
183 | .name = "ohci_clk", | ||
184 | .pmc_mask = 1 << AT91CAP9_ID_UHP, | ||
185 | .type = CLK_TYPE_PERIPHERAL, | ||
186 | }; | ||
187 | |||
188 | static struct clk *periph_clocks[] __initdata = { | ||
189 | &pioABCD_clk, | ||
190 | &mpb0_clk, | ||
191 | &mpb1_clk, | ||
192 | &mpb2_clk, | ||
193 | &mpb3_clk, | ||
194 | &mpb4_clk, | ||
195 | &usart0_clk, | ||
196 | &usart1_clk, | ||
197 | &usart2_clk, | ||
198 | &mmc0_clk, | ||
199 | &mmc1_clk, | ||
200 | &can_clk, | ||
201 | &twi_clk, | ||
202 | &spi0_clk, | ||
203 | &spi1_clk, | ||
204 | &ssc0_clk, | ||
205 | &ssc1_clk, | ||
206 | &ac97_clk, | ||
207 | &tcb_clk, | ||
208 | &pwmc_clk, | ||
209 | &macb_clk, | ||
210 | &aestdes_clk, | ||
211 | &adc_clk, | ||
212 | &isi_clk, | ||
213 | &lcdc_clk, | ||
214 | &dma_clk, | ||
215 | &udphs_clk, | ||
216 | &ohci_clk, | ||
217 | // irq0 .. irq1 | ||
218 | }; | ||
219 | |||
220 | /* | ||
221 | * The four programmable clocks. | ||
222 | * You must configure pin multiplexing to bring these signals out. | ||
223 | */ | ||
224 | static struct clk pck0 = { | ||
225 | .name = "pck0", | ||
226 | .pmc_mask = AT91_PMC_PCK0, | ||
227 | .type = CLK_TYPE_PROGRAMMABLE, | ||
228 | .id = 0, | ||
229 | }; | ||
230 | static struct clk pck1 = { | ||
231 | .name = "pck1", | ||
232 | .pmc_mask = AT91_PMC_PCK1, | ||
233 | .type = CLK_TYPE_PROGRAMMABLE, | ||
234 | .id = 1, | ||
235 | }; | ||
236 | static struct clk pck2 = { | ||
237 | .name = "pck2", | ||
238 | .pmc_mask = AT91_PMC_PCK2, | ||
239 | .type = CLK_TYPE_PROGRAMMABLE, | ||
240 | .id = 2, | ||
241 | }; | ||
242 | static struct clk pck3 = { | ||
243 | .name = "pck3", | ||
244 | .pmc_mask = AT91_PMC_PCK3, | ||
245 | .type = CLK_TYPE_PROGRAMMABLE, | ||
246 | .id = 3, | ||
247 | }; | ||
248 | |||
249 | static void __init at91cap9_register_clocks(void) | ||
250 | { | ||
251 | int i; | ||
252 | |||
253 | for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) | ||
254 | clk_register(periph_clocks[i]); | ||
255 | |||
256 | clk_register(&pck0); | ||
257 | clk_register(&pck1); | ||
258 | clk_register(&pck2); | ||
259 | clk_register(&pck3); | ||
260 | } | ||
261 | |||
262 | /* -------------------------------------------------------------------- | ||
263 | * GPIO | ||
264 | * -------------------------------------------------------------------- */ | ||
265 | |||
266 | static struct at91_gpio_bank at91cap9_gpio[] = { | ||
267 | { | ||
268 | .id = AT91CAP9_ID_PIOABCD, | ||
269 | .offset = AT91_PIOA, | ||
270 | .clock = &pioABCD_clk, | ||
271 | }, { | ||
272 | .id = AT91CAP9_ID_PIOABCD, | ||
273 | .offset = AT91_PIOB, | ||
274 | .clock = &pioABCD_clk, | ||
275 | }, { | ||
276 | .id = AT91CAP9_ID_PIOABCD, | ||
277 | .offset = AT91_PIOC, | ||
278 | .clock = &pioABCD_clk, | ||
279 | }, { | ||
280 | .id = AT91CAP9_ID_PIOABCD, | ||
281 | .offset = AT91_PIOD, | ||
282 | .clock = &pioABCD_clk, | ||
283 | } | ||
284 | }; | ||
285 | |||
286 | static void at91cap9_reset(void) | ||
287 | { | ||
288 | at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST); | ||
289 | } | ||
290 | |||
291 | /* -------------------------------------------------------------------- | ||
292 | * AT91CAP9 processor initialization | ||
293 | * -------------------------------------------------------------------- */ | ||
294 | |||
295 | void __init at91cap9_initialize(unsigned long main_clock) | ||
296 | { | ||
297 | /* Map peripherals */ | ||
298 | iotable_init(at91cap9_io_desc, ARRAY_SIZE(at91cap9_io_desc)); | ||
299 | |||
300 | at91_arch_reset = at91cap9_reset; | ||
301 | at91_extern_irq = (1 << AT91CAP9_ID_IRQ0) | (1 << AT91CAP9_ID_IRQ1); | ||
302 | |||
303 | /* Init clock subsystem */ | ||
304 | at91_clock_init(main_clock); | ||
305 | |||
306 | /* Register the processor-specific clocks */ | ||
307 | at91cap9_register_clocks(); | ||
308 | |||
309 | /* Register GPIO subsystem */ | ||
310 | at91_gpio_init(at91cap9_gpio, 4); | ||
311 | } | ||
312 | |||
313 | /* -------------------------------------------------------------------- | ||
314 | * Interrupt initialization | ||
315 | * -------------------------------------------------------------------- */ | ||
316 | |||
317 | /* | ||
318 | * The default interrupt priority levels (0 = lowest, 7 = highest). | ||
319 | */ | ||
320 | static unsigned int at91cap9_default_irq_priority[NR_AIC_IRQS] __initdata = { | ||
321 | 7, /* Advanced Interrupt Controller (FIQ) */ | ||
322 | 7, /* System Peripherals */ | ||
323 | 1, /* Parallel IO Controller A, B, C and D */ | ||
324 | 0, /* MP Block Peripheral 0 */ | ||
325 | 0, /* MP Block Peripheral 1 */ | ||
326 | 0, /* MP Block Peripheral 2 */ | ||
327 | 0, /* MP Block Peripheral 3 */ | ||
328 | 0, /* MP Block Peripheral 4 */ | ||
329 | 5, /* USART 0 */ | ||
330 | 5, /* USART 1 */ | ||
331 | 5, /* USART 2 */ | ||
332 | 0, /* Multimedia Card Interface 0 */ | ||
333 | 0, /* Multimedia Card Interface 1 */ | ||
334 | 3, /* CAN */ | ||
335 | 6, /* Two-Wire Interface */ | ||
336 | 5, /* Serial Peripheral Interface 0 */ | ||
337 | 5, /* Serial Peripheral Interface 1 */ | ||
338 | 4, /* Serial Synchronous Controller 0 */ | ||
339 | 4, /* Serial Synchronous Controller 1 */ | ||
340 | 5, /* AC97 Controller */ | ||
341 | 0, /* Timer Counter 0, 1 and 2 */ | ||
342 | 0, /* Pulse Width Modulation Controller */ | ||
343 | 3, /* Ethernet */ | ||
344 | 0, /* Advanced Encryption Standard, Triple DES*/ | ||
345 | 0, /* Analog-to-Digital Converter */ | ||
346 | 0, /* Image Sensor Interface */ | ||
347 | 3, /* LCD Controller */ | ||
348 | 0, /* DMA Controller */ | ||
349 | 2, /* USB Device Port */ | ||
350 | 2, /* USB Host port */ | ||
351 | 0, /* Advanced Interrupt Controller (IRQ0) */ | ||
352 | 0, /* Advanced Interrupt Controller (IRQ1) */ | ||
353 | }; | ||
354 | |||
355 | void __init at91cap9_init_interrupts(unsigned int priority[NR_AIC_IRQS]) | ||
356 | { | ||
357 | if (!priority) | ||
358 | priority = at91cap9_default_irq_priority; | ||
359 | |||
360 | /* Initialize the AIC interrupt controller */ | ||
361 | at91_aic_init(priority); | ||
362 | |||
363 | /* Enable GPIO interrupts */ | ||
364 | at91_gpio_irq_setup(); | ||
365 | } | ||
diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c new file mode 100644 index 000000000000..c50fad9cd143 --- /dev/null +++ b/arch/arm/mach-at91/at91cap9_devices.c | |||
@@ -0,0 +1,1066 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-at91/at91cap9_devices.c | ||
3 | * | ||
4 | * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com> | ||
5 | * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com> | ||
6 | * Copyright (C) 2007 Atmel Corporation. | ||
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 | */ | ||
14 | #include <asm/mach/arch.h> | ||
15 | #include <asm/mach/map.h> | ||
16 | |||
17 | #include <linux/dma-mapping.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/mtd/physmap.h> | ||
20 | |||
21 | #include <video/atmel_lcdc.h> | ||
22 | |||
23 | #include <asm/arch/board.h> | ||
24 | #include <asm/arch/gpio.h> | ||
25 | #include <asm/arch/at91cap9.h> | ||
26 | #include <asm/arch/at91sam926x_mc.h> | ||
27 | #include <asm/arch/at91cap9_matrix.h> | ||
28 | |||
29 | #include "generic.h" | ||
30 | |||
31 | |||
32 | /* -------------------------------------------------------------------- | ||
33 | * USB Host | ||
34 | * -------------------------------------------------------------------- */ | ||
35 | |||
36 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | ||
37 | static u64 ohci_dmamask = DMA_BIT_MASK(32); | ||
38 | static struct at91_usbh_data usbh_data; | ||
39 | |||
40 | static struct resource usbh_resources[] = { | ||
41 | [0] = { | ||
42 | .start = AT91CAP9_UHP_BASE, | ||
43 | .end = AT91CAP9_UHP_BASE + SZ_1M - 1, | ||
44 | .flags = IORESOURCE_MEM, | ||
45 | }, | ||
46 | [1] = { | ||
47 | .start = AT91CAP9_ID_UHP, | ||
48 | .end = AT91CAP9_ID_UHP, | ||
49 | .flags = IORESOURCE_IRQ, | ||
50 | }, | ||
51 | }; | ||
52 | |||
53 | static struct platform_device at91_usbh_device = { | ||
54 | .name = "at91_ohci", | ||
55 | .id = -1, | ||
56 | .dev = { | ||
57 | .dma_mask = &ohci_dmamask, | ||
58 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
59 | .platform_data = &usbh_data, | ||
60 | }, | ||
61 | .resource = usbh_resources, | ||
62 | .num_resources = ARRAY_SIZE(usbh_resources), | ||
63 | }; | ||
64 | |||
65 | void __init at91_add_device_usbh(struct at91_usbh_data *data) | ||
66 | { | ||
67 | int i; | ||
68 | |||
69 | if (!data) | ||
70 | return; | ||
71 | |||
72 | /* Enable VBus control for UHP ports */ | ||
73 | for (i = 0; i < data->ports; i++) { | ||
74 | if (data->vbus_pin[i]) | ||
75 | at91_set_gpio_output(data->vbus_pin[i], 0); | ||
76 | } | ||
77 | |||
78 | usbh_data = *data; | ||
79 | platform_device_register(&at91_usbh_device); | ||
80 | } | ||
81 | #else | ||
82 | void __init at91_add_device_usbh(struct at91_usbh_data *data) {} | ||
83 | #endif | ||
84 | |||
85 | |||
86 | /* -------------------------------------------------------------------- | ||
87 | * Ethernet | ||
88 | * -------------------------------------------------------------------- */ | ||
89 | |||
90 | #if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) | ||
91 | static u64 eth_dmamask = DMA_BIT_MASK(32); | ||
92 | static struct at91_eth_data eth_data; | ||
93 | |||
94 | static struct resource eth_resources[] = { | ||
95 | [0] = { | ||
96 | .start = AT91CAP9_BASE_EMAC, | ||
97 | .end = AT91CAP9_BASE_EMAC + SZ_16K - 1, | ||
98 | .flags = IORESOURCE_MEM, | ||
99 | }, | ||
100 | [1] = { | ||
101 | .start = AT91CAP9_ID_EMAC, | ||
102 | .end = AT91CAP9_ID_EMAC, | ||
103 | .flags = IORESOURCE_IRQ, | ||
104 | }, | ||
105 | }; | ||
106 | |||
107 | static struct platform_device at91cap9_eth_device = { | ||
108 | .name = "macb", | ||
109 | .id = -1, | ||
110 | .dev = { | ||
111 | .dma_mask = ð_dmamask, | ||
112 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
113 | .platform_data = ð_data, | ||
114 | }, | ||
115 | .resource = eth_resources, | ||
116 | .num_resources = ARRAY_SIZE(eth_resources), | ||
117 | }; | ||
118 | |||
119 | void __init at91_add_device_eth(struct at91_eth_data *data) | ||
120 | { | ||
121 | if (!data) | ||
122 | return; | ||
123 | |||
124 | if (data->phy_irq_pin) { | ||
125 | at91_set_gpio_input(data->phy_irq_pin, 0); | ||
126 | at91_set_deglitch(data->phy_irq_pin, 1); | ||
127 | } | ||
128 | |||
129 | /* Pins used for MII and RMII */ | ||
130 | at91_set_A_periph(AT91_PIN_PB21, 0); /* ETXCK_EREFCK */ | ||
131 | at91_set_A_periph(AT91_PIN_PB22, 0); /* ERXDV */ | ||
132 | at91_set_A_periph(AT91_PIN_PB25, 0); /* ERX0 */ | ||
133 | at91_set_A_periph(AT91_PIN_PB26, 0); /* ERX1 */ | ||
134 | at91_set_A_periph(AT91_PIN_PB27, 0); /* ERXER */ | ||
135 | at91_set_A_periph(AT91_PIN_PB28, 0); /* ETXEN */ | ||
136 | at91_set_A_periph(AT91_PIN_PB23, 0); /* ETX0 */ | ||
137 | at91_set_A_periph(AT91_PIN_PB24, 0); /* ETX1 */ | ||
138 | at91_set_A_periph(AT91_PIN_PB30, 0); /* EMDIO */ | ||
139 | at91_set_A_periph(AT91_PIN_PB29, 0); /* EMDC */ | ||
140 | |||
141 | if (!data->is_rmii) { | ||
142 | at91_set_B_periph(AT91_PIN_PC25, 0); /* ECRS */ | ||
143 | at91_set_B_periph(AT91_PIN_PC26, 0); /* ECOL */ | ||
144 | at91_set_B_periph(AT91_PIN_PC22, 0); /* ERX2 */ | ||
145 | at91_set_B_periph(AT91_PIN_PC23, 0); /* ERX3 */ | ||
146 | at91_set_B_periph(AT91_PIN_PC27, 0); /* ERXCK */ | ||
147 | at91_set_B_periph(AT91_PIN_PC20, 0); /* ETX2 */ | ||
148 | at91_set_B_periph(AT91_PIN_PC21, 0); /* ETX3 */ | ||
149 | at91_set_B_periph(AT91_PIN_PC24, 0); /* ETXER */ | ||
150 | } | ||
151 | |||
152 | eth_data = *data; | ||
153 | platform_device_register(&at91cap9_eth_device); | ||
154 | } | ||
155 | #else | ||
156 | void __init at91_add_device_eth(struct at91_eth_data *data) {} | ||
157 | #endif | ||
158 | |||
159 | |||
160 | /* -------------------------------------------------------------------- | ||
161 | * MMC / SD | ||
162 | * -------------------------------------------------------------------- */ | ||
163 | |||
164 | #if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) | ||
165 | static u64 mmc_dmamask = DMA_BIT_MASK(32); | ||
166 | static struct at91_mmc_data mmc0_data, mmc1_data; | ||
167 | |||
168 | static struct resource mmc0_resources[] = { | ||
169 | [0] = { | ||
170 | .start = AT91CAP9_BASE_MCI0, | ||
171 | .end = AT91CAP9_BASE_MCI0 + SZ_16K - 1, | ||
172 | .flags = IORESOURCE_MEM, | ||
173 | }, | ||
174 | [1] = { | ||
175 | .start = AT91CAP9_ID_MCI0, | ||
176 | .end = AT91CAP9_ID_MCI0, | ||
177 | .flags = IORESOURCE_IRQ, | ||
178 | }, | ||
179 | }; | ||
180 | |||
181 | static struct platform_device at91cap9_mmc0_device = { | ||
182 | .name = "at91_mci", | ||
183 | .id = 0, | ||
184 | .dev = { | ||
185 | .dma_mask = &mmc_dmamask, | ||
186 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
187 | .platform_data = &mmc0_data, | ||
188 | }, | ||
189 | .resource = mmc0_resources, | ||
190 | .num_resources = ARRAY_SIZE(mmc0_resources), | ||
191 | }; | ||
192 | |||
193 | static struct resource mmc1_resources[] = { | ||
194 | [0] = { | ||
195 | .start = AT91CAP9_BASE_MCI1, | ||
196 | .end = AT91CAP9_BASE_MCI1 + SZ_16K - 1, | ||
197 | .flags = IORESOURCE_MEM, | ||
198 | }, | ||
199 | [1] = { | ||
200 | .start = AT91CAP9_ID_MCI1, | ||
201 | .end = AT91CAP9_ID_MCI1, | ||
202 | .flags = IORESOURCE_IRQ, | ||
203 | }, | ||
204 | }; | ||
205 | |||
206 | static struct platform_device at91cap9_mmc1_device = { | ||
207 | .name = "at91_mci", | ||
208 | .id = 1, | ||
209 | .dev = { | ||
210 | .dma_mask = &mmc_dmamask, | ||
211 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
212 | .platform_data = &mmc1_data, | ||
213 | }, | ||
214 | .resource = mmc1_resources, | ||
215 | .num_resources = ARRAY_SIZE(mmc1_resources), | ||
216 | }; | ||
217 | |||
218 | void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) | ||
219 | { | ||
220 | if (!data) | ||
221 | return; | ||
222 | |||
223 | /* input/irq */ | ||
224 | if (data->det_pin) { | ||
225 | at91_set_gpio_input(data->det_pin, 1); | ||
226 | at91_set_deglitch(data->det_pin, 1); | ||
227 | } | ||
228 | if (data->wp_pin) | ||
229 | at91_set_gpio_input(data->wp_pin, 1); | ||
230 | if (data->vcc_pin) | ||
231 | at91_set_gpio_output(data->vcc_pin, 0); | ||
232 | |||
233 | if (mmc_id == 0) { /* MCI0 */ | ||
234 | /* CLK */ | ||
235 | at91_set_A_periph(AT91_PIN_PA2, 0); | ||
236 | |||
237 | /* CMD */ | ||
238 | at91_set_A_periph(AT91_PIN_PA1, 1); | ||
239 | |||
240 | /* DAT0, maybe DAT1..DAT3 */ | ||
241 | at91_set_A_periph(AT91_PIN_PA0, 1); | ||
242 | if (data->wire4) { | ||
243 | at91_set_A_periph(AT91_PIN_PA3, 1); | ||
244 | at91_set_A_periph(AT91_PIN_PA4, 1); | ||
245 | at91_set_A_periph(AT91_PIN_PA5, 1); | ||
246 | } | ||
247 | |||
248 | mmc0_data = *data; | ||
249 | at91_clock_associate("mci0_clk", &at91cap9_mmc1_device.dev, "mci_clk"); | ||
250 | platform_device_register(&at91cap9_mmc0_device); | ||
251 | } else { /* MCI1 */ | ||
252 | /* CLK */ | ||
253 | at91_set_A_periph(AT91_PIN_PA16, 0); | ||
254 | |||
255 | /* CMD */ | ||
256 | at91_set_A_periph(AT91_PIN_PA17, 1); | ||
257 | |||
258 | /* DAT0, maybe DAT1..DAT3 */ | ||
259 | at91_set_A_periph(AT91_PIN_PA18, 1); | ||
260 | if (data->wire4) { | ||
261 | at91_set_A_periph(AT91_PIN_PA19, 1); | ||
262 | at91_set_A_periph(AT91_PIN_PA20, 1); | ||
263 | at91_set_A_periph(AT91_PIN_PA21, 1); | ||
264 | } | ||
265 | |||
266 | mmc1_data = *data; | ||
267 | at91_clock_associate("mci1_clk", &at91cap9_mmc1_device.dev, "mci_clk"); | ||
268 | platform_device_register(&at91cap9_mmc1_device); | ||
269 | } | ||
270 | } | ||
271 | #else | ||
272 | void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} | ||
273 | #endif | ||
274 | |||
275 | |||
276 | /* -------------------------------------------------------------------- | ||
277 | * NAND / SmartMedia | ||
278 | * -------------------------------------------------------------------- */ | ||
279 | |||
280 | #if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) | ||
281 | static struct at91_nand_data nand_data; | ||
282 | |||
283 | #define NAND_BASE AT91_CHIPSELECT_3 | ||
284 | |||
285 | static struct resource nand_resources[] = { | ||
286 | { | ||
287 | .start = NAND_BASE, | ||
288 | .end = NAND_BASE + SZ_256M - 1, | ||
289 | .flags = IORESOURCE_MEM, | ||
290 | } | ||
291 | }; | ||
292 | |||
293 | static struct platform_device at91cap9_nand_device = { | ||
294 | .name = "at91_nand", | ||
295 | .id = -1, | ||
296 | .dev = { | ||
297 | .platform_data = &nand_data, | ||
298 | }, | ||
299 | .resource = nand_resources, | ||
300 | .num_resources = ARRAY_SIZE(nand_resources), | ||
301 | }; | ||
302 | |||
303 | void __init at91_add_device_nand(struct at91_nand_data *data) | ||
304 | { | ||
305 | unsigned long csa, mode; | ||
306 | |||
307 | if (!data) | ||
308 | return; | ||
309 | |||
310 | csa = at91_sys_read(AT91_MATRIX_EBICSA); | ||
311 | at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA | AT91_MATRIX_EBI_VDDIOMSEL_3_3V); | ||
312 | |||
313 | /* set the bus interface characteristics */ | ||
314 | at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(2) | AT91_SMC_NCS_WRSETUP_(1) | ||
315 | | AT91_SMC_NRDSETUP_(2) | AT91_SMC_NCS_RDSETUP_(1)); | ||
316 | |||
317 | at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(4) | AT91_SMC_NCS_WRPULSE_(6) | ||
318 | | AT91_SMC_NRDPULSE_(4) | AT91_SMC_NCS_RDPULSE_(6)); | ||
319 | |||
320 | at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(8) | AT91_SMC_NRDCYCLE_(8)); | ||
321 | |||
322 | if (data->bus_width_16) | ||
323 | mode = AT91_SMC_DBW_16; | ||
324 | else | ||
325 | mode = AT91_SMC_DBW_8; | ||
326 | at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(1)); | ||
327 | |||
328 | /* enable pin */ | ||
329 | if (data->enable_pin) | ||
330 | at91_set_gpio_output(data->enable_pin, 1); | ||
331 | |||
332 | /* ready/busy pin */ | ||
333 | if (data->rdy_pin) | ||
334 | at91_set_gpio_input(data->rdy_pin, 1); | ||
335 | |||
336 | /* card detect pin */ | ||
337 | if (data->det_pin) | ||
338 | at91_set_gpio_input(data->det_pin, 1); | ||
339 | |||
340 | nand_data = *data; | ||
341 | platform_device_register(&at91cap9_nand_device); | ||
342 | } | ||
343 | #else | ||
344 | void __init at91_add_device_nand(struct at91_nand_data *data) {} | ||
345 | #endif | ||
346 | |||
347 | /* -------------------------------------------------------------------- | ||
348 | * TWI (i2c) | ||
349 | * -------------------------------------------------------------------- */ | ||
350 | |||
351 | /* | ||
352 | * Prefer the GPIO code since the TWI controller isn't robust | ||
353 | * (gets overruns and underruns under load) and can only issue | ||
354 | * repeated STARTs in one scenario (the driver doesn't yet handle them). | ||
355 | */ | ||
356 | #if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) | ||
357 | |||
358 | static struct i2c_gpio_platform_data pdata = { | ||
359 | .sda_pin = AT91_PIN_PB4, | ||
360 | .sda_is_open_drain = 1, | ||
361 | .scl_pin = AT91_PIN_PB5, | ||
362 | .scl_is_open_drain = 1, | ||
363 | .udelay = 2, /* ~100 kHz */ | ||
364 | }; | ||
365 | |||
366 | static struct platform_device at91cap9_twi_device = { | ||
367 | .name = "i2c-gpio", | ||
368 | .id = -1, | ||
369 | .dev.platform_data = &pdata, | ||
370 | }; | ||
371 | |||
372 | void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) | ||
373 | { | ||
374 | at91_set_GPIO_periph(AT91_PIN_PB4, 1); /* TWD (SDA) */ | ||
375 | at91_set_multi_drive(AT91_PIN_PB4, 1); | ||
376 | |||
377 | at91_set_GPIO_periph(AT91_PIN_PB5, 1); /* TWCK (SCL) */ | ||
378 | at91_set_multi_drive(AT91_PIN_PB5, 1); | ||
379 | |||
380 | i2c_register_board_info(0, devices, nr_devices); | ||
381 | platform_device_register(&at91cap9_twi_device); | ||
382 | } | ||
383 | |||
384 | #elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) | ||
385 | |||
386 | static struct resource twi_resources[] = { | ||
387 | [0] = { | ||
388 | .start = AT91CAP9_BASE_TWI, | ||
389 | .end = AT91CAP9_BASE_TWI + SZ_16K - 1, | ||
390 | .flags = IORESOURCE_MEM, | ||
391 | }, | ||
392 | [1] = { | ||
393 | .start = AT91CAP9_ID_TWI, | ||
394 | .end = AT91CAP9_ID_TWI, | ||
395 | .flags = IORESOURCE_IRQ, | ||
396 | }, | ||
397 | }; | ||
398 | |||
399 | static struct platform_device at91cap9_twi_device = { | ||
400 | .name = "at91_i2c", | ||
401 | .id = -1, | ||
402 | .resource = twi_resources, | ||
403 | .num_resources = ARRAY_SIZE(twi_resources), | ||
404 | }; | ||
405 | |||
406 | void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) | ||
407 | { | ||
408 | /* pins used for TWI interface */ | ||
409 | at91_set_B_periph(AT91_PIN_PB4, 0); /* TWD */ | ||
410 | at91_set_multi_drive(AT91_PIN_PB4, 1); | ||
411 | |||
412 | at91_set_B_periph(AT91_PIN_PB5, 0); /* TWCK */ | ||
413 | at91_set_multi_drive(AT91_PIN_PB5, 1); | ||
414 | |||
415 | i2c_register_board_info(0, devices, nr_devices); | ||
416 | platform_device_register(&at91cap9_twi_device); | ||
417 | } | ||
418 | #else | ||
419 | void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {} | ||
420 | #endif | ||
421 | |||
422 | /* -------------------------------------------------------------------- | ||
423 | * SPI | ||
424 | * -------------------------------------------------------------------- */ | ||
425 | |||
426 | #if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) | ||
427 | static u64 spi_dmamask = DMA_BIT_MASK(32); | ||
428 | |||
429 | static struct resource spi0_resources[] = { | ||
430 | [0] = { | ||
431 | .start = AT91CAP9_BASE_SPI0, | ||
432 | .end = AT91CAP9_BASE_SPI0 + SZ_16K - 1, | ||
433 | .flags = IORESOURCE_MEM, | ||
434 | }, | ||
435 | [1] = { | ||
436 | .start = AT91CAP9_ID_SPI0, | ||
437 | .end = AT91CAP9_ID_SPI0, | ||
438 | .flags = IORESOURCE_IRQ, | ||
439 | }, | ||
440 | }; | ||
441 | |||
442 | static struct platform_device at91cap9_spi0_device = { | ||
443 | .name = "atmel_spi", | ||
444 | .id = 0, | ||
445 | .dev = { | ||
446 | .dma_mask = &spi_dmamask, | ||
447 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
448 | }, | ||
449 | .resource = spi0_resources, | ||
450 | .num_resources = ARRAY_SIZE(spi0_resources), | ||
451 | }; | ||
452 | |||
453 | static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA5, AT91_PIN_PA3, AT91_PIN_PD0, AT91_PIN_PD1 }; | ||
454 | |||
455 | static struct resource spi1_resources[] = { | ||
456 | [0] = { | ||
457 | .start = AT91CAP9_BASE_SPI1, | ||
458 | .end = AT91CAP9_BASE_SPI1 + SZ_16K - 1, | ||
459 | .flags = IORESOURCE_MEM, | ||
460 | }, | ||
461 | [1] = { | ||
462 | .start = AT91CAP9_ID_SPI1, | ||
463 | .end = AT91CAP9_ID_SPI1, | ||
464 | .flags = IORESOURCE_IRQ, | ||
465 | }, | ||
466 | }; | ||
467 | |||
468 | static struct platform_device at91cap9_spi1_device = { | ||
469 | .name = "atmel_spi", | ||
470 | .id = 1, | ||
471 | .dev = { | ||
472 | .dma_mask = &spi_dmamask, | ||
473 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
474 | }, | ||
475 | .resource = spi1_resources, | ||
476 | .num_resources = ARRAY_SIZE(spi1_resources), | ||
477 | }; | ||
478 | |||
479 | static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB15, AT91_PIN_PB16, AT91_PIN_PB17, AT91_PIN_PB18 }; | ||
480 | |||
481 | void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) | ||
482 | { | ||
483 | int i; | ||
484 | unsigned long cs_pin; | ||
485 | short enable_spi0 = 0; | ||
486 | short enable_spi1 = 0; | ||
487 | |||
488 | /* Choose SPI chip-selects */ | ||
489 | for (i = 0; i < nr_devices; i++) { | ||
490 | if (devices[i].controller_data) | ||
491 | cs_pin = (unsigned long) devices[i].controller_data; | ||
492 | else if (devices[i].bus_num == 0) | ||
493 | cs_pin = spi0_standard_cs[devices[i].chip_select]; | ||
494 | else | ||
495 | cs_pin = spi1_standard_cs[devices[i].chip_select]; | ||
496 | |||
497 | if (devices[i].bus_num == 0) | ||
498 | enable_spi0 = 1; | ||
499 | else | ||
500 | enable_spi1 = 1; | ||
501 | |||
502 | /* enable chip-select pin */ | ||
503 | at91_set_gpio_output(cs_pin, 1); | ||
504 | |||
505 | /* pass chip-select pin to driver */ | ||
506 | devices[i].controller_data = (void *) cs_pin; | ||
507 | } | ||
508 | |||
509 | spi_register_board_info(devices, nr_devices); | ||
510 | |||
511 | /* Configure SPI bus(es) */ | ||
512 | if (enable_spi0) { | ||
513 | at91_set_B_periph(AT91_PIN_PA0, 0); /* SPI0_MISO */ | ||
514 | at91_set_B_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */ | ||
515 | at91_set_B_periph(AT91_PIN_PA2, 0); /* SPI0_SPCK */ | ||
516 | |||
517 | at91_clock_associate("spi0_clk", &at91cap9_spi0_device.dev, "spi_clk"); | ||
518 | platform_device_register(&at91cap9_spi0_device); | ||
519 | } | ||
520 | if (enable_spi1) { | ||
521 | at91_set_A_periph(AT91_PIN_PB12, 0); /* SPI1_MISO */ | ||
522 | at91_set_A_periph(AT91_PIN_PB13, 0); /* SPI1_MOSI */ | ||
523 | at91_set_A_periph(AT91_PIN_PB14, 0); /* SPI1_SPCK */ | ||
524 | |||
525 | at91_clock_associate("spi1_clk", &at91cap9_spi1_device.dev, "spi_clk"); | ||
526 | platform_device_register(&at91cap9_spi1_device); | ||
527 | } | ||
528 | } | ||
529 | #else | ||
530 | void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} | ||
531 | #endif | ||
532 | |||
533 | |||
534 | /* -------------------------------------------------------------------- | ||
535 | * RTT | ||
536 | * -------------------------------------------------------------------- */ | ||
537 | |||
538 | static struct platform_device at91cap9_rtt_device = { | ||
539 | .name = "at91_rtt", | ||
540 | .id = -1, | ||
541 | .num_resources = 0, | ||
542 | }; | ||
543 | |||
544 | static void __init at91_add_device_rtt(void) | ||
545 | { | ||
546 | platform_device_register(&at91cap9_rtt_device); | ||
547 | } | ||
548 | |||
549 | |||
550 | /* -------------------------------------------------------------------- | ||
551 | * Watchdog | ||
552 | * -------------------------------------------------------------------- */ | ||
553 | |||
554 | #if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE) | ||
555 | static struct platform_device at91cap9_wdt_device = { | ||
556 | .name = "at91_wdt", | ||
557 | .id = -1, | ||
558 | .num_resources = 0, | ||
559 | }; | ||
560 | |||
561 | static void __init at91_add_device_watchdog(void) | ||
562 | { | ||
563 | platform_device_register(&at91cap9_wdt_device); | ||
564 | } | ||
565 | #else | ||
566 | static void __init at91_add_device_watchdog(void) {} | ||
567 | #endif | ||
568 | |||
569 | |||
570 | /* -------------------------------------------------------------------- | ||
571 | * AC97 | ||
572 | * -------------------------------------------------------------------- */ | ||
573 | |||
574 | #if defined(CONFIG_SND_AT91_AC97) || defined(CONFIG_SND_AT91_AC97_MODULE) | ||
575 | static u64 ac97_dmamask = DMA_BIT_MASK(32); | ||
576 | static struct atmel_ac97_data ac97_data; | ||
577 | |||
578 | static struct resource ac97_resources[] = { | ||
579 | [0] = { | ||
580 | .start = AT91CAP9_BASE_AC97C, | ||
581 | .end = AT91CAP9_BASE_AC97C + SZ_16K - 1, | ||
582 | .flags = IORESOURCE_MEM, | ||
583 | }, | ||
584 | [1] = { | ||
585 | .start = AT91CAP9_ID_AC97C, | ||
586 | .end = AT91CAP9_ID_AC97C, | ||
587 | .flags = IORESOURCE_IRQ, | ||
588 | }, | ||
589 | }; | ||
590 | |||
591 | static struct platform_device at91cap9_ac97_device = { | ||
592 | .name = "ac97c", | ||
593 | .id = 1, | ||
594 | .dev = { | ||
595 | .dma_mask = &ac97_dmamask, | ||
596 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
597 | .platform_data = &ac97_data, | ||
598 | }, | ||
599 | .resource = ac97_resources, | ||
600 | .num_resources = ARRAY_SIZE(ac97_resources), | ||
601 | }; | ||
602 | |||
603 | void __init at91_add_device_ac97(struct atmel_ac97_data *data) | ||
604 | { | ||
605 | if (!data) | ||
606 | return; | ||
607 | |||
608 | at91_set_A_periph(AT91_PIN_PA6, 0); /* AC97FS */ | ||
609 | at91_set_A_periph(AT91_PIN_PA7, 0); /* AC97CK */ | ||
610 | at91_set_A_periph(AT91_PIN_PA8, 0); /* AC97TX */ | ||
611 | at91_set_A_periph(AT91_PIN_PA9, 0); /* AC97RX */ | ||
612 | |||
613 | /* reset */ | ||
614 | if (data->reset_pin) | ||
615 | at91_set_gpio_output(data->reset_pin, 0); | ||
616 | |||
617 | ac97_data = *data; | ||
618 | platform_device_register(&at91cap9_ac97_device); | ||
619 | } | ||
620 | #else | ||
621 | void __init at91_add_device_ac97(struct atmel_ac97_data *data) {} | ||
622 | #endif | ||
623 | |||
624 | |||
625 | /* -------------------------------------------------------------------- | ||
626 | * LCD Controller | ||
627 | * -------------------------------------------------------------------- */ | ||
628 | |||
629 | #if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) | ||
630 | static u64 lcdc_dmamask = DMA_BIT_MASK(32); | ||
631 | static struct atmel_lcdfb_info lcdc_data; | ||
632 | |||
633 | static struct resource lcdc_resources[] = { | ||
634 | [0] = { | ||
635 | .start = AT91CAP9_LCDC_BASE, | ||
636 | .end = AT91CAP9_LCDC_BASE + SZ_4K - 1, | ||
637 | .flags = IORESOURCE_MEM, | ||
638 | }, | ||
639 | [1] = { | ||
640 | .start = AT91CAP9_ID_LCDC, | ||
641 | .end = AT91CAP9_ID_LCDC, | ||
642 | .flags = IORESOURCE_IRQ, | ||
643 | }, | ||
644 | }; | ||
645 | |||
646 | static struct platform_device at91_lcdc_device = { | ||
647 | .name = "atmel_lcdfb", | ||
648 | .id = 0, | ||
649 | .dev = { | ||
650 | .dma_mask = &lcdc_dmamask, | ||
651 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
652 | .platform_data = &lcdc_data, | ||
653 | }, | ||
654 | .resource = lcdc_resources, | ||
655 | .num_resources = ARRAY_SIZE(lcdc_resources), | ||
656 | }; | ||
657 | |||
658 | void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) | ||
659 | { | ||
660 | if (!data) | ||
661 | return; | ||
662 | |||
663 | at91_set_A_periph(AT91_PIN_PC1, 0); /* LCDHSYNC */ | ||
664 | at91_set_A_periph(AT91_PIN_PC2, 0); /* LCDDOTCK */ | ||
665 | at91_set_A_periph(AT91_PIN_PC3, 0); /* LCDDEN */ | ||
666 | at91_set_B_periph(AT91_PIN_PB9, 0); /* LCDCC */ | ||
667 | at91_set_A_periph(AT91_PIN_PC6, 0); /* LCDD2 */ | ||
668 | at91_set_A_periph(AT91_PIN_PC7, 0); /* LCDD3 */ | ||
669 | at91_set_A_periph(AT91_PIN_PC8, 0); /* LCDD4 */ | ||
670 | at91_set_A_periph(AT91_PIN_PC9, 0); /* LCDD5 */ | ||
671 | at91_set_A_periph(AT91_PIN_PC10, 0); /* LCDD6 */ | ||
672 | at91_set_A_periph(AT91_PIN_PC11, 0); /* LCDD7 */ | ||
673 | at91_set_A_periph(AT91_PIN_PC14, 0); /* LCDD10 */ | ||
674 | at91_set_A_periph(AT91_PIN_PC15, 0); /* LCDD11 */ | ||
675 | at91_set_A_periph(AT91_PIN_PC16, 0); /* LCDD12 */ | ||
676 | at91_set_A_periph(AT91_PIN_PC17, 0); /* LCDD13 */ | ||
677 | at91_set_A_periph(AT91_PIN_PC18, 0); /* LCDD14 */ | ||
678 | at91_set_A_periph(AT91_PIN_PC19, 0); /* LCDD15 */ | ||
679 | at91_set_A_periph(AT91_PIN_PC22, 0); /* LCDD18 */ | ||
680 | at91_set_A_periph(AT91_PIN_PC23, 0); /* LCDD19 */ | ||
681 | at91_set_A_periph(AT91_PIN_PC24, 0); /* LCDD20 */ | ||
682 | at91_set_A_periph(AT91_PIN_PC25, 0); /* LCDD21 */ | ||
683 | at91_set_A_periph(AT91_PIN_PC26, 0); /* LCDD22 */ | ||
684 | at91_set_A_periph(AT91_PIN_PC27, 0); /* LCDD23 */ | ||
685 | |||
686 | lcdc_data = *data; | ||
687 | platform_device_register(&at91_lcdc_device); | ||
688 | } | ||
689 | #else | ||
690 | void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {} | ||
691 | #endif | ||
692 | |||
693 | |||
694 | /* -------------------------------------------------------------------- | ||
695 | * SSC -- Synchronous Serial Controller | ||
696 | * -------------------------------------------------------------------- */ | ||
697 | |||
698 | #if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE) | ||
699 | static u64 ssc0_dmamask = DMA_BIT_MASK(32); | ||
700 | |||
701 | static struct resource ssc0_resources[] = { | ||
702 | [0] = { | ||
703 | .start = AT91CAP9_BASE_SSC0, | ||
704 | .end = AT91CAP9_BASE_SSC0 + SZ_16K - 1, | ||
705 | .flags = IORESOURCE_MEM, | ||
706 | }, | ||
707 | [1] = { | ||
708 | .start = AT91CAP9_ID_SSC0, | ||
709 | .end = AT91CAP9_ID_SSC0, | ||
710 | .flags = IORESOURCE_IRQ, | ||
711 | }, | ||
712 | }; | ||
713 | |||
714 | static struct platform_device at91cap9_ssc0_device = { | ||
715 | .name = "ssc", | ||
716 | .id = 0, | ||
717 | .dev = { | ||
718 | .dma_mask = &ssc0_dmamask, | ||
719 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
720 | }, | ||
721 | .resource = ssc0_resources, | ||
722 | .num_resources = ARRAY_SIZE(ssc0_resources), | ||
723 | }; | ||
724 | |||
725 | static inline void configure_ssc0_pins(unsigned pins) | ||
726 | { | ||
727 | if (pins & ATMEL_SSC_TF) | ||
728 | at91_set_A_periph(AT91_PIN_PB0, 1); | ||
729 | if (pins & ATMEL_SSC_TK) | ||
730 | at91_set_A_periph(AT91_PIN_PB1, 1); | ||
731 | if (pins & ATMEL_SSC_TD) | ||
732 | at91_set_A_periph(AT91_PIN_PB2, 1); | ||
733 | if (pins & ATMEL_SSC_RD) | ||
734 | at91_set_A_periph(AT91_PIN_PB3, 1); | ||
735 | if (pins & ATMEL_SSC_RK) | ||
736 | at91_set_A_periph(AT91_PIN_PB4, 1); | ||
737 | if (pins & ATMEL_SSC_RF) | ||
738 | at91_set_A_periph(AT91_PIN_PB5, 1); | ||
739 | } | ||
740 | |||
741 | static u64 ssc1_dmamask = DMA_BIT_MASK(32); | ||
742 | |||
743 | static struct resource ssc1_resources[] = { | ||
744 | [0] = { | ||
745 | .start = AT91CAP9_BASE_SSC1, | ||
746 | .end = AT91CAP9_BASE_SSC1 + SZ_16K - 1, | ||
747 | .flags = IORESOURCE_MEM, | ||
748 | }, | ||
749 | [1] = { | ||
750 | .start = AT91CAP9_ID_SSC1, | ||
751 | .end = AT91CAP9_ID_SSC1, | ||
752 | .flags = IORESOURCE_IRQ, | ||
753 | }, | ||
754 | }; | ||
755 | |||
756 | static struct platform_device at91cap9_ssc1_device = { | ||
757 | .name = "ssc", | ||
758 | .id = 1, | ||
759 | .dev = { | ||
760 | .dma_mask = &ssc1_dmamask, | ||
761 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
762 | }, | ||
763 | .resource = ssc1_resources, | ||
764 | .num_resources = ARRAY_SIZE(ssc1_resources), | ||
765 | }; | ||
766 | |||
767 | static inline void configure_ssc1_pins(unsigned pins) | ||
768 | { | ||
769 | if (pins & ATMEL_SSC_TF) | ||
770 | at91_set_A_periph(AT91_PIN_PB6, 1); | ||
771 | if (pins & ATMEL_SSC_TK) | ||
772 | at91_set_A_periph(AT91_PIN_PB7, 1); | ||
773 | if (pins & ATMEL_SSC_TD) | ||
774 | at91_set_A_periph(AT91_PIN_PB8, 1); | ||
775 | if (pins & ATMEL_SSC_RD) | ||
776 | at91_set_A_periph(AT91_PIN_PB9, 1); | ||
777 | if (pins & ATMEL_SSC_RK) | ||
778 | at91_set_A_periph(AT91_PIN_PB10, 1); | ||
779 | if (pins & ATMEL_SSC_RF) | ||
780 | at91_set_A_periph(AT91_PIN_PB11, 1); | ||
781 | } | ||
782 | |||
783 | /* | ||
784 | * SSC controllers are accessed through library code, instead of any | ||
785 | * kind of all-singing/all-dancing driver. For example one could be | ||
786 | * used by a particular I2S audio codec's driver, while another one | ||
787 | * on the same system might be used by a custom data capture driver. | ||
788 | */ | ||
789 | void __init at91_add_device_ssc(unsigned id, unsigned pins) | ||
790 | { | ||
791 | struct platform_device *pdev; | ||
792 | |||
793 | /* | ||
794 | * NOTE: caller is responsible for passing information matching | ||
795 | * "pins" to whatever will be using each particular controller. | ||
796 | */ | ||
797 | switch (id) { | ||
798 | case AT91CAP9_ID_SSC0: | ||
799 | pdev = &at91cap9_ssc0_device; | ||
800 | configure_ssc0_pins(pins); | ||
801 | at91_clock_associate("ssc0_clk", &pdev->dev, "ssc"); | ||
802 | break; | ||
803 | case AT91CAP9_ID_SSC1: | ||
804 | pdev = &at91cap9_ssc1_device; | ||
805 | configure_ssc1_pins(pins); | ||
806 | at91_clock_associate("ssc1_clk", &pdev->dev, "ssc"); | ||
807 | break; | ||
808 | default: | ||
809 | return; | ||
810 | } | ||
811 | |||
812 | platform_device_register(pdev); | ||
813 | } | ||
814 | |||
815 | #else | ||
816 | void __init at91_add_device_ssc(unsigned id, unsigned pins) {} | ||
817 | #endif | ||
818 | |||
819 | |||
820 | /* -------------------------------------------------------------------- | ||
821 | * UART | ||
822 | * -------------------------------------------------------------------- */ | ||
823 | |||
824 | #if defined(CONFIG_SERIAL_ATMEL) | ||
825 | static struct resource dbgu_resources[] = { | ||
826 | [0] = { | ||
827 | .start = AT91_VA_BASE_SYS + AT91_DBGU, | ||
828 | .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, | ||
829 | .flags = IORESOURCE_MEM, | ||
830 | }, | ||
831 | [1] = { | ||
832 | .start = AT91_ID_SYS, | ||
833 | .end = AT91_ID_SYS, | ||
834 | .flags = IORESOURCE_IRQ, | ||
835 | }, | ||
836 | }; | ||
837 | |||
838 | static struct atmel_uart_data dbgu_data = { | ||
839 | .use_dma_tx = 0, | ||
840 | .use_dma_rx = 0, /* DBGU not capable of receive DMA */ | ||
841 | .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), | ||
842 | }; | ||
843 | |||
844 | static u64 dbgu_dmamask = DMA_BIT_MASK(32); | ||
845 | |||
846 | static struct platform_device at91cap9_dbgu_device = { | ||
847 | .name = "atmel_usart", | ||
848 | .id = 0, | ||
849 | .dev = { | ||
850 | .dma_mask = &dbgu_dmamask, | ||
851 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
852 | .platform_data = &dbgu_data, | ||
853 | }, | ||
854 | .resource = dbgu_resources, | ||
855 | .num_resources = ARRAY_SIZE(dbgu_resources), | ||
856 | }; | ||
857 | |||
858 | static inline void configure_dbgu_pins(void) | ||
859 | { | ||
860 | at91_set_A_periph(AT91_PIN_PC30, 0); /* DRXD */ | ||
861 | at91_set_A_periph(AT91_PIN_PC31, 1); /* DTXD */ | ||
862 | } | ||
863 | |||
864 | static struct resource uart0_resources[] = { | ||
865 | [0] = { | ||
866 | .start = AT91CAP9_BASE_US0, | ||
867 | .end = AT91CAP9_BASE_US0 + SZ_16K - 1, | ||
868 | .flags = IORESOURCE_MEM, | ||
869 | }, | ||
870 | [1] = { | ||
871 | .start = AT91CAP9_ID_US0, | ||
872 | .end = AT91CAP9_ID_US0, | ||
873 | .flags = IORESOURCE_IRQ, | ||
874 | }, | ||
875 | }; | ||
876 | |||
877 | static struct atmel_uart_data uart0_data = { | ||
878 | .use_dma_tx = 1, | ||
879 | .use_dma_rx = 1, | ||
880 | }; | ||
881 | |||
882 | static u64 uart0_dmamask = DMA_BIT_MASK(32); | ||
883 | |||
884 | static struct platform_device at91cap9_uart0_device = { | ||
885 | .name = "atmel_usart", | ||
886 | .id = 1, | ||
887 | .dev = { | ||
888 | .dma_mask = &uart0_dmamask, | ||
889 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
890 | .platform_data = &uart0_data, | ||
891 | }, | ||
892 | .resource = uart0_resources, | ||
893 | .num_resources = ARRAY_SIZE(uart0_resources), | ||
894 | }; | ||
895 | |||
896 | static inline void configure_usart0_pins(unsigned pins) | ||
897 | { | ||
898 | at91_set_A_periph(AT91_PIN_PA22, 1); /* TXD0 */ | ||
899 | at91_set_A_periph(AT91_PIN_PA23, 0); /* RXD0 */ | ||
900 | |||
901 | if (pins & ATMEL_UART_RTS) | ||
902 | at91_set_A_periph(AT91_PIN_PA24, 0); /* RTS0 */ | ||
903 | if (pins & ATMEL_UART_CTS) | ||
904 | at91_set_A_periph(AT91_PIN_PA25, 0); /* CTS0 */ | ||
905 | } | ||
906 | |||
907 | static struct resource uart1_resources[] = { | ||
908 | [0] = { | ||
909 | .start = AT91CAP9_BASE_US1, | ||
910 | .end = AT91CAP9_BASE_US1 + SZ_16K - 1, | ||
911 | .flags = IORESOURCE_MEM, | ||
912 | }, | ||
913 | [1] = { | ||
914 | .start = AT91CAP9_ID_US1, | ||
915 | .end = AT91CAP9_ID_US1, | ||
916 | .flags = IORESOURCE_IRQ, | ||
917 | }, | ||
918 | }; | ||
919 | |||
920 | static struct atmel_uart_data uart1_data = { | ||
921 | .use_dma_tx = 1, | ||
922 | .use_dma_rx = 1, | ||
923 | }; | ||
924 | |||
925 | static u64 uart1_dmamask = DMA_BIT_MASK(32); | ||
926 | |||
927 | static struct platform_device at91cap9_uart1_device = { | ||
928 | .name = "atmel_usart", | ||
929 | .id = 2, | ||
930 | .dev = { | ||
931 | .dma_mask = &uart1_dmamask, | ||
932 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
933 | .platform_data = &uart1_data, | ||
934 | }, | ||
935 | .resource = uart1_resources, | ||
936 | .num_resources = ARRAY_SIZE(uart1_resources), | ||
937 | }; | ||
938 | |||
939 | static inline void configure_usart1_pins(unsigned pins) | ||
940 | { | ||
941 | at91_set_A_periph(AT91_PIN_PD0, 1); /* TXD1 */ | ||
942 | at91_set_A_periph(AT91_PIN_PD1, 0); /* RXD1 */ | ||
943 | |||
944 | if (pins & ATMEL_UART_RTS) | ||
945 | at91_set_B_periph(AT91_PIN_PD7, 0); /* RTS1 */ | ||
946 | if (pins & ATMEL_UART_CTS) | ||
947 | at91_set_B_periph(AT91_PIN_PD8, 0); /* CTS1 */ | ||
948 | } | ||
949 | |||
950 | static struct resource uart2_resources[] = { | ||
951 | [0] = { | ||
952 | .start = AT91CAP9_BASE_US2, | ||
953 | .end = AT91CAP9_BASE_US2 + SZ_16K - 1, | ||
954 | .flags = IORESOURCE_MEM, | ||
955 | }, | ||
956 | [1] = { | ||
957 | .start = AT91CAP9_ID_US2, | ||
958 | .end = AT91CAP9_ID_US2, | ||
959 | .flags = IORESOURCE_IRQ, | ||
960 | }, | ||
961 | }; | ||
962 | |||
963 | static struct atmel_uart_data uart2_data = { | ||
964 | .use_dma_tx = 1, | ||
965 | .use_dma_rx = 1, | ||
966 | }; | ||
967 | |||
968 | static u64 uart2_dmamask = DMA_BIT_MASK(32); | ||
969 | |||
970 | static struct platform_device at91cap9_uart2_device = { | ||
971 | .name = "atmel_usart", | ||
972 | .id = 3, | ||
973 | .dev = { | ||
974 | .dma_mask = &uart2_dmamask, | ||
975 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
976 | .platform_data = &uart2_data, | ||
977 | }, | ||
978 | .resource = uart2_resources, | ||
979 | .num_resources = ARRAY_SIZE(uart2_resources), | ||
980 | }; | ||
981 | |||
982 | static inline void configure_usart2_pins(unsigned pins) | ||
983 | { | ||
984 | at91_set_A_periph(AT91_PIN_PD2, 1); /* TXD2 */ | ||
985 | at91_set_A_periph(AT91_PIN_PD3, 0); /* RXD2 */ | ||
986 | |||
987 | if (pins & ATMEL_UART_RTS) | ||
988 | at91_set_B_periph(AT91_PIN_PD5, 0); /* RTS2 */ | ||
989 | if (pins & ATMEL_UART_CTS) | ||
990 | at91_set_B_periph(AT91_PIN_PD6, 0); /* CTS2 */ | ||
991 | } | ||
992 | |||
993 | static struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ | ||
994 | struct platform_device *atmel_default_console_device; /* the serial console device */ | ||
995 | |||
996 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) | ||
997 | { | ||
998 | struct platform_device *pdev; | ||
999 | |||
1000 | switch (id) { | ||
1001 | case 0: /* DBGU */ | ||
1002 | pdev = &at91cap9_dbgu_device; | ||
1003 | configure_dbgu_pins(); | ||
1004 | at91_clock_associate("mck", &pdev->dev, "usart"); | ||
1005 | break; | ||
1006 | case AT91CAP9_ID_US0: | ||
1007 | pdev = &at91cap9_uart0_device; | ||
1008 | configure_usart0_pins(pins); | ||
1009 | at91_clock_associate("usart0_clk", &pdev->dev, "usart"); | ||
1010 | break; | ||
1011 | case AT91CAP9_ID_US1: | ||
1012 | pdev = &at91cap9_uart1_device; | ||
1013 | configure_usart1_pins(pins); | ||
1014 | at91_clock_associate("usart1_clk", &pdev->dev, "usart"); | ||
1015 | break; | ||
1016 | case AT91CAP9_ID_US2: | ||
1017 | pdev = &at91cap9_uart2_device; | ||
1018 | configure_usart2_pins(pins); | ||
1019 | at91_clock_associate("usart2_clk", &pdev->dev, "usart"); | ||
1020 | break; | ||
1021 | default: | ||
1022 | return; | ||
1023 | } | ||
1024 | pdev->id = portnr; /* update to mapped ID */ | ||
1025 | |||
1026 | if (portnr < ATMEL_MAX_UART) | ||
1027 | at91_uarts[portnr] = pdev; | ||
1028 | } | ||
1029 | |||
1030 | void __init at91_set_serial_console(unsigned portnr) | ||
1031 | { | ||
1032 | if (portnr < ATMEL_MAX_UART) | ||
1033 | atmel_default_console_device = at91_uarts[portnr]; | ||
1034 | if (!atmel_default_console_device) | ||
1035 | printk(KERN_INFO "AT91: No default serial console defined.\n"); | ||
1036 | } | ||
1037 | |||
1038 | void __init at91_add_device_serial(void) | ||
1039 | { | ||
1040 | int i; | ||
1041 | |||
1042 | for (i = 0; i < ATMEL_MAX_UART; i++) { | ||
1043 | if (at91_uarts[i]) | ||
1044 | platform_device_register(at91_uarts[i]); | ||
1045 | } | ||
1046 | } | ||
1047 | #else | ||
1048 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} | ||
1049 | void __init at91_set_serial_console(unsigned portnr) {} | ||
1050 | void __init at91_add_device_serial(void) {} | ||
1051 | #endif | ||
1052 | |||
1053 | |||
1054 | /* -------------------------------------------------------------------- */ | ||
1055 | /* | ||
1056 | * These devices are always present and don't need any board-specific | ||
1057 | * setup. | ||
1058 | */ | ||
1059 | static int __init at91_add_standard_devices(void) | ||
1060 | { | ||
1061 | at91_add_device_rtt(); | ||
1062 | at91_add_device_watchdog(); | ||
1063 | return 0; | ||
1064 | } | ||
1065 | |||
1066 | arch_initcall(at91_add_standard_devices); | ||
diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c index 2cad2bf864be..d688c1dbd925 100644 --- a/arch/arm/mach-at91/at91rm9200.c +++ b/arch/arm/mach-at91/at91rm9200.c | |||
@@ -301,28 +301,28 @@ void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks | |||
301 | static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = { | 301 | static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = { |
302 | 7, /* Advanced Interrupt Controller (FIQ) */ | 302 | 7, /* Advanced Interrupt Controller (FIQ) */ |
303 | 7, /* System Peripherals */ | 303 | 7, /* System Peripherals */ |
304 | 0, /* Parallel IO Controller A */ | 304 | 1, /* Parallel IO Controller A */ |
305 | 0, /* Parallel IO Controller B */ | 305 | 1, /* Parallel IO Controller B */ |
306 | 0, /* Parallel IO Controller C */ | 306 | 1, /* Parallel IO Controller C */ |
307 | 0, /* Parallel IO Controller D */ | 307 | 1, /* Parallel IO Controller D */ |
308 | 6, /* USART 0 */ | 308 | 5, /* USART 0 */ |
309 | 6, /* USART 1 */ | 309 | 5, /* USART 1 */ |
310 | 6, /* USART 2 */ | 310 | 5, /* USART 2 */ |
311 | 6, /* USART 3 */ | 311 | 5, /* USART 3 */ |
312 | 0, /* Multimedia Card Interface */ | 312 | 0, /* Multimedia Card Interface */ |
313 | 4, /* USB Device Port */ | 313 | 2, /* USB Device Port */ |
314 | 0, /* Two-Wire Interface */ | 314 | 6, /* Two-Wire Interface */ |
315 | 6, /* Serial Peripheral Interface */ | 315 | 5, /* Serial Peripheral Interface */ |
316 | 5, /* Serial Synchronous Controller 0 */ | 316 | 4, /* Serial Synchronous Controller 0 */ |
317 | 5, /* Serial Synchronous Controller 1 */ | 317 | 4, /* Serial Synchronous Controller 1 */ |
318 | 5, /* Serial Synchronous Controller 2 */ | 318 | 4, /* Serial Synchronous Controller 2 */ |
319 | 0, /* Timer Counter 0 */ | 319 | 0, /* Timer Counter 0 */ |
320 | 0, /* Timer Counter 1 */ | 320 | 0, /* Timer Counter 1 */ |
321 | 0, /* Timer Counter 2 */ | 321 | 0, /* Timer Counter 2 */ |
322 | 0, /* Timer Counter 3 */ | 322 | 0, /* Timer Counter 3 */ |
323 | 0, /* Timer Counter 4 */ | 323 | 0, /* Timer Counter 4 */ |
324 | 0, /* Timer Counter 5 */ | 324 | 0, /* Timer Counter 5 */ |
325 | 3, /* USB Host port */ | 325 | 2, /* USB Host port */ |
326 | 3, /* Ethernet MAC */ | 326 | 3, /* Ethernet MAC */ |
327 | 0, /* Advanced Interrupt Controller (IRQ0) */ | 327 | 0, /* Advanced Interrupt Controller (IRQ0) */ |
328 | 0, /* Advanced Interrupt Controller (IRQ1) */ | 328 | 0, /* Advanced Interrupt Controller (IRQ1) */ |
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c index 9296833f91cc..ef6aeb86e980 100644 --- a/arch/arm/mach-at91/at91rm9200_devices.c +++ b/arch/arm/mach-at91/at91rm9200_devices.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <asm/mach/arch.h> | 13 | #include <asm/mach/arch.h> |
14 | #include <asm/mach/map.h> | 14 | #include <asm/mach/map.h> |
15 | 15 | ||
16 | #include <linux/dma-mapping.h> | ||
16 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
17 | #include <linux/i2c-gpio.h> | 18 | #include <linux/i2c-gpio.h> |
18 | 19 | ||
@@ -29,7 +30,7 @@ | |||
29 | * -------------------------------------------------------------------- */ | 30 | * -------------------------------------------------------------------- */ |
30 | 31 | ||
31 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | 32 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) |
32 | static u64 ohci_dmamask = 0xffffffffUL; | 33 | static u64 ohci_dmamask = DMA_BIT_MASK(32); |
33 | static struct at91_usbh_data usbh_data; | 34 | static struct at91_usbh_data usbh_data; |
34 | 35 | ||
35 | static struct resource usbh_resources[] = { | 36 | static struct resource usbh_resources[] = { |
@@ -50,7 +51,7 @@ static struct platform_device at91rm9200_usbh_device = { | |||
50 | .id = -1, | 51 | .id = -1, |
51 | .dev = { | 52 | .dev = { |
52 | .dma_mask = &ohci_dmamask, | 53 | .dma_mask = &ohci_dmamask, |
53 | .coherent_dma_mask = 0xffffffff, | 54 | .coherent_dma_mask = DMA_BIT_MASK(32), |
54 | .platform_data = &usbh_data, | 55 | .platform_data = &usbh_data, |
55 | }, | 56 | }, |
56 | .resource = usbh_resources, | 57 | .resource = usbh_resources, |
@@ -125,7 +126,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data) {} | |||
125 | * -------------------------------------------------------------------- */ | 126 | * -------------------------------------------------------------------- */ |
126 | 127 | ||
127 | #if defined(CONFIG_ARM_AT91_ETHER) || defined(CONFIG_ARM_AT91_ETHER_MODULE) | 128 | #if defined(CONFIG_ARM_AT91_ETHER) || defined(CONFIG_ARM_AT91_ETHER_MODULE) |
128 | static u64 eth_dmamask = 0xffffffffUL; | 129 | static u64 eth_dmamask = DMA_BIT_MASK(32); |
129 | static struct at91_eth_data eth_data; | 130 | static struct at91_eth_data eth_data; |
130 | 131 | ||
131 | static struct resource eth_resources[] = { | 132 | static struct resource eth_resources[] = { |
@@ -146,7 +147,7 @@ static struct platform_device at91rm9200_eth_device = { | |||
146 | .id = -1, | 147 | .id = -1, |
147 | .dev = { | 148 | .dev = { |
148 | .dma_mask = ð_dmamask, | 149 | .dma_mask = ð_dmamask, |
149 | .coherent_dma_mask = 0xffffffff, | 150 | .coherent_dma_mask = DMA_BIT_MASK(32), |
150 | .platform_data = ð_data, | 151 | .platform_data = ð_data, |
151 | }, | 152 | }, |
152 | .resource = eth_resources, | 153 | .resource = eth_resources, |
@@ -285,7 +286,7 @@ void __init at91_add_device_cf(struct at91_cf_data *data) {} | |||
285 | * -------------------------------------------------------------------- */ | 286 | * -------------------------------------------------------------------- */ |
286 | 287 | ||
287 | #if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) | 288 | #if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) |
288 | static u64 mmc_dmamask = 0xffffffffUL; | 289 | static u64 mmc_dmamask = DMA_BIT_MASK(32); |
289 | static struct at91_mmc_data mmc_data; | 290 | static struct at91_mmc_data mmc_data; |
290 | 291 | ||
291 | static struct resource mmc_resources[] = { | 292 | static struct resource mmc_resources[] = { |
@@ -306,7 +307,7 @@ static struct platform_device at91rm9200_mmc_device = { | |||
306 | .id = -1, | 307 | .id = -1, |
307 | .dev = { | 308 | .dev = { |
308 | .dma_mask = &mmc_dmamask, | 309 | .dma_mask = &mmc_dmamask, |
309 | .coherent_dma_mask = 0xffffffff, | 310 | .coherent_dma_mask = DMA_BIT_MASK(32), |
310 | .platform_data = &mmc_data, | 311 | .platform_data = &mmc_data, |
311 | }, | 312 | }, |
312 | .resource = mmc_resources, | 313 | .resource = mmc_resources, |
@@ -375,7 +376,7 @@ static struct at91_nand_data nand_data; | |||
375 | static struct resource nand_resources[] = { | 376 | static struct resource nand_resources[] = { |
376 | { | 377 | { |
377 | .start = NAND_BASE, | 378 | .start = NAND_BASE, |
378 | .end = NAND_BASE + SZ_8M - 1, | 379 | .end = NAND_BASE + SZ_256M - 1, |
379 | .flags = IORESOURCE_MEM, | 380 | .flags = IORESOURCE_MEM, |
380 | } | 381 | } |
381 | }; | 382 | }; |
@@ -513,7 +514,7 @@ void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) | |||
513 | * -------------------------------------------------------------------- */ | 514 | * -------------------------------------------------------------------- */ |
514 | 515 | ||
515 | #if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) | 516 | #if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) |
516 | static u64 spi_dmamask = 0xffffffffUL; | 517 | static u64 spi_dmamask = DMA_BIT_MASK(32); |
517 | 518 | ||
518 | static struct resource spi_resources[] = { | 519 | static struct resource spi_resources[] = { |
519 | [0] = { | 520 | [0] = { |
@@ -533,7 +534,7 @@ static struct platform_device at91rm9200_spi_device = { | |||
533 | .id = 0, | 534 | .id = 0, |
534 | .dev = { | 535 | .dev = { |
535 | .dma_mask = &spi_dmamask, | 536 | .dma_mask = &spi_dmamask, |
536 | .coherent_dma_mask = 0xffffffff, | 537 | .coherent_dma_mask = DMA_BIT_MASK(32), |
537 | }, | 538 | }, |
538 | .resource = spi_resources, | 539 | .resource = spi_resources, |
539 | .num_resources = ARRAY_SIZE(spi_resources), | 540 | .num_resources = ARRAY_SIZE(spi_resources), |
@@ -557,8 +558,11 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) | |||
557 | else | 558 | else |
558 | cs_pin = spi_standard_cs[devices[i].chip_select]; | 559 | cs_pin = spi_standard_cs[devices[i].chip_select]; |
559 | 560 | ||
560 | /* enable chip-select pin */ | 561 | if (devices[i].chip_select == 0) /* for CS0 errata */ |
561 | at91_set_gpio_output(cs_pin, 1); | 562 | at91_set_A_periph(cs_pin, 0); |
563 | else | ||
564 | at91_set_gpio_output(cs_pin, 1); | ||
565 | |||
562 | 566 | ||
563 | /* pass chip-select pin to driver */ | 567 | /* pass chip-select pin to driver */ |
564 | devices[i].controller_data = (void *) cs_pin; | 568 | devices[i].controller_data = (void *) cs_pin; |
@@ -613,24 +617,175 @@ static void __init at91_add_device_watchdog(void) {} | |||
613 | 617 | ||
614 | 618 | ||
615 | /* -------------------------------------------------------------------- | 619 | /* -------------------------------------------------------------------- |
616 | * LEDs | 620 | * SSC -- Synchronous Serial Controller |
617 | * -------------------------------------------------------------------- */ | 621 | * -------------------------------------------------------------------- */ |
618 | 622 | ||
619 | #if defined(CONFIG_LEDS) | 623 | #if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE) |
620 | u8 at91_leds_cpu; | 624 | static u64 ssc0_dmamask = DMA_BIT_MASK(32); |
621 | u8 at91_leds_timer; | 625 | |
626 | static struct resource ssc0_resources[] = { | ||
627 | [0] = { | ||
628 | .start = AT91RM9200_BASE_SSC0, | ||
629 | .end = AT91RM9200_BASE_SSC0 + SZ_16K - 1, | ||
630 | .flags = IORESOURCE_MEM, | ||
631 | }, | ||
632 | [1] = { | ||
633 | .start = AT91RM9200_ID_SSC0, | ||
634 | .end = AT91RM9200_ID_SSC0, | ||
635 | .flags = IORESOURCE_IRQ, | ||
636 | }, | ||
637 | }; | ||
638 | |||
639 | static struct platform_device at91rm9200_ssc0_device = { | ||
640 | .name = "ssc", | ||
641 | .id = 0, | ||
642 | .dev = { | ||
643 | .dma_mask = &ssc0_dmamask, | ||
644 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
645 | }, | ||
646 | .resource = ssc0_resources, | ||
647 | .num_resources = ARRAY_SIZE(ssc0_resources), | ||
648 | }; | ||
649 | |||
650 | static inline void configure_ssc0_pins(unsigned pins) | ||
651 | { | ||
652 | if (pins & ATMEL_SSC_TF) | ||
653 | at91_set_A_periph(AT91_PIN_PB0, 1); | ||
654 | if (pins & ATMEL_SSC_TK) | ||
655 | at91_set_A_periph(AT91_PIN_PB1, 1); | ||
656 | if (pins & ATMEL_SSC_TD) | ||
657 | at91_set_A_periph(AT91_PIN_PB2, 1); | ||
658 | if (pins & ATMEL_SSC_RD) | ||
659 | at91_set_A_periph(AT91_PIN_PB3, 1); | ||
660 | if (pins & ATMEL_SSC_RK) | ||
661 | at91_set_A_periph(AT91_PIN_PB4, 1); | ||
662 | if (pins & ATMEL_SSC_RF) | ||
663 | at91_set_A_periph(AT91_PIN_PB5, 1); | ||
664 | } | ||
665 | |||
666 | static u64 ssc1_dmamask = DMA_BIT_MASK(32); | ||
667 | |||
668 | static struct resource ssc1_resources[] = { | ||
669 | [0] = { | ||
670 | .start = AT91RM9200_BASE_SSC1, | ||
671 | .end = AT91RM9200_BASE_SSC1 + SZ_16K - 1, | ||
672 | .flags = IORESOURCE_MEM, | ||
673 | }, | ||
674 | [1] = { | ||
675 | .start = AT91RM9200_ID_SSC1, | ||
676 | .end = AT91RM9200_ID_SSC1, | ||
677 | .flags = IORESOURCE_IRQ, | ||
678 | }, | ||
679 | }; | ||
680 | |||
681 | static struct platform_device at91rm9200_ssc1_device = { | ||
682 | .name = "ssc", | ||
683 | .id = 1, | ||
684 | .dev = { | ||
685 | .dma_mask = &ssc1_dmamask, | ||
686 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
687 | }, | ||
688 | .resource = ssc1_resources, | ||
689 | .num_resources = ARRAY_SIZE(ssc1_resources), | ||
690 | }; | ||
691 | |||
692 | static inline void configure_ssc1_pins(unsigned pins) | ||
693 | { | ||
694 | if (pins & ATMEL_SSC_TF) | ||
695 | at91_set_A_periph(AT91_PIN_PB6, 1); | ||
696 | if (pins & ATMEL_SSC_TK) | ||
697 | at91_set_A_periph(AT91_PIN_PB7, 1); | ||
698 | if (pins & ATMEL_SSC_TD) | ||
699 | at91_set_A_periph(AT91_PIN_PB8, 1); | ||
700 | if (pins & ATMEL_SSC_RD) | ||
701 | at91_set_A_periph(AT91_PIN_PB9, 1); | ||
702 | if (pins & ATMEL_SSC_RK) | ||
703 | at91_set_A_periph(AT91_PIN_PB10, 1); | ||
704 | if (pins & ATMEL_SSC_RF) | ||
705 | at91_set_A_periph(AT91_PIN_PB11, 1); | ||
706 | } | ||
707 | |||
708 | static u64 ssc2_dmamask = DMA_BIT_MASK(32); | ||
709 | |||
710 | static struct resource ssc2_resources[] = { | ||
711 | [0] = { | ||
712 | .start = AT91RM9200_BASE_SSC2, | ||
713 | .end = AT91RM9200_BASE_SSC2 + SZ_16K - 1, | ||
714 | .flags = IORESOURCE_MEM, | ||
715 | }, | ||
716 | [1] = { | ||
717 | .start = AT91RM9200_ID_SSC2, | ||
718 | .end = AT91RM9200_ID_SSC2, | ||
719 | .flags = IORESOURCE_IRQ, | ||
720 | }, | ||
721 | }; | ||
722 | |||
723 | static struct platform_device at91rm9200_ssc2_device = { | ||
724 | .name = "ssc", | ||
725 | .id = 2, | ||
726 | .dev = { | ||
727 | .dma_mask = &ssc2_dmamask, | ||
728 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
729 | }, | ||
730 | .resource = ssc2_resources, | ||
731 | .num_resources = ARRAY_SIZE(ssc2_resources), | ||
732 | }; | ||
733 | |||
734 | static inline void configure_ssc2_pins(unsigned pins) | ||
735 | { | ||
736 | if (pins & ATMEL_SSC_TF) | ||
737 | at91_set_A_periph(AT91_PIN_PB12, 1); | ||
738 | if (pins & ATMEL_SSC_TK) | ||
739 | at91_set_A_periph(AT91_PIN_PB13, 1); | ||
740 | if (pins & ATMEL_SSC_TD) | ||
741 | at91_set_A_periph(AT91_PIN_PB14, 1); | ||
742 | if (pins & ATMEL_SSC_RD) | ||
743 | at91_set_A_periph(AT91_PIN_PB15, 1); | ||
744 | if (pins & ATMEL_SSC_RK) | ||
745 | at91_set_A_periph(AT91_PIN_PB16, 1); | ||
746 | if (pins & ATMEL_SSC_RF) | ||
747 | at91_set_A_periph(AT91_PIN_PB17, 1); | ||
748 | } | ||
622 | 749 | ||
623 | void __init at91_init_leds(u8 cpu_led, u8 timer_led) | 750 | /* |
751 | * SSC controllers are accessed through library code, instead of any | ||
752 | * kind of all-singing/all-dancing driver. For example one could be | ||
753 | * used by a particular I2S audio codec's driver, while another one | ||
754 | * on the same system might be used by a custom data capture driver. | ||
755 | */ | ||
756 | void __init at91_add_device_ssc(unsigned id, unsigned pins) | ||
624 | { | 757 | { |
625 | /* Enable GPIO to access the LEDs */ | 758 | struct platform_device *pdev; |
626 | at91_set_gpio_output(cpu_led, 1); | ||
627 | at91_set_gpio_output(timer_led, 1); | ||
628 | 759 | ||
629 | at91_leds_cpu = cpu_led; | 760 | /* |
630 | at91_leds_timer = timer_led; | 761 | * NOTE: caller is responsible for passing information matching |
762 | * "pins" to whatever will be using each particular controller. | ||
763 | */ | ||
764 | switch (id) { | ||
765 | case AT91RM9200_ID_SSC0: | ||
766 | pdev = &at91rm9200_ssc0_device; | ||
767 | configure_ssc0_pins(pins); | ||
768 | at91_clock_associate("ssc0_clk", &pdev->dev, "ssc"); | ||
769 | break; | ||
770 | case AT91RM9200_ID_SSC1: | ||
771 | pdev = &at91rm9200_ssc1_device; | ||
772 | configure_ssc1_pins(pins); | ||
773 | at91_clock_associate("ssc1_clk", &pdev->dev, "ssc"); | ||
774 | break; | ||
775 | case AT91RM9200_ID_SSC2: | ||
776 | pdev = &at91rm9200_ssc2_device; | ||
777 | configure_ssc2_pins(pins); | ||
778 | at91_clock_associate("ssc2_clk", &pdev->dev, "ssc"); | ||
779 | break; | ||
780 | default: | ||
781 | return; | ||
782 | } | ||
783 | |||
784 | platform_device_register(pdev); | ||
631 | } | 785 | } |
786 | |||
632 | #else | 787 | #else |
633 | void __init at91_init_leds(u8 cpu_led, u8 timer_led) {} | 788 | void __init at91_add_device_ssc(unsigned id, unsigned pins) {} |
634 | #endif | 789 | #endif |
635 | 790 | ||
636 | 791 | ||
@@ -658,12 +813,15 @@ static struct atmel_uart_data dbgu_data = { | |||
658 | .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), | 813 | .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), |
659 | }; | 814 | }; |
660 | 815 | ||
816 | static u64 dbgu_dmamask = DMA_BIT_MASK(32); | ||
817 | |||
661 | static struct platform_device at91rm9200_dbgu_device = { | 818 | static struct platform_device at91rm9200_dbgu_device = { |
662 | .name = "atmel_usart", | 819 | .name = "atmel_usart", |
663 | .id = 0, | 820 | .id = 0, |
664 | .dev = { | 821 | .dev = { |
665 | .platform_data = &dbgu_data, | 822 | .dma_mask = &dbgu_dmamask, |
666 | .coherent_dma_mask = 0xffffffff, | 823 | .coherent_dma_mask = DMA_BIT_MASK(32), |
824 | .platform_data = &dbgu_data, | ||
667 | }, | 825 | }, |
668 | .resource = dbgu_resources, | 826 | .resource = dbgu_resources, |
669 | .num_resources = ARRAY_SIZE(dbgu_resources), | 827 | .num_resources = ARRAY_SIZE(dbgu_resources), |
@@ -693,28 +851,35 @@ static struct atmel_uart_data uart0_data = { | |||
693 | .use_dma_rx = 1, | 851 | .use_dma_rx = 1, |
694 | }; | 852 | }; |
695 | 853 | ||
854 | static u64 uart0_dmamask = DMA_BIT_MASK(32); | ||
855 | |||
696 | static struct platform_device at91rm9200_uart0_device = { | 856 | static struct platform_device at91rm9200_uart0_device = { |
697 | .name = "atmel_usart", | 857 | .name = "atmel_usart", |
698 | .id = 1, | 858 | .id = 1, |
699 | .dev = { | 859 | .dev = { |
700 | .platform_data = &uart0_data, | 860 | .dma_mask = &uart0_dmamask, |
701 | .coherent_dma_mask = 0xffffffff, | 861 | .coherent_dma_mask = DMA_BIT_MASK(32), |
862 | .platform_data = &uart0_data, | ||
702 | }, | 863 | }, |
703 | .resource = uart0_resources, | 864 | .resource = uart0_resources, |
704 | .num_resources = ARRAY_SIZE(uart0_resources), | 865 | .num_resources = ARRAY_SIZE(uart0_resources), |
705 | }; | 866 | }; |
706 | 867 | ||
707 | static inline void configure_usart0_pins(void) | 868 | static inline void configure_usart0_pins(unsigned pins) |
708 | { | 869 | { |
709 | at91_set_A_periph(AT91_PIN_PA17, 1); /* TXD0 */ | 870 | at91_set_A_periph(AT91_PIN_PA17, 1); /* TXD0 */ |
710 | at91_set_A_periph(AT91_PIN_PA18, 0); /* RXD0 */ | 871 | at91_set_A_periph(AT91_PIN_PA18, 0); /* RXD0 */ |
711 | at91_set_A_periph(AT91_PIN_PA20, 0); /* CTS0 */ | ||
712 | 872 | ||
713 | /* | 873 | if (pins & ATMEL_UART_CTS) |
714 | * AT91RM9200 Errata #39 - RTS0 is not internally connected to PA21. | 874 | at91_set_A_periph(AT91_PIN_PA20, 0); /* CTS0 */ |
715 | * We need to drive the pin manually. Default is off (RTS is active low). | 875 | |
716 | */ | 876 | if (pins & ATMEL_UART_RTS) { |
717 | at91_set_gpio_output(AT91_PIN_PA21, 1); | 877 | /* |
878 | * AT91RM9200 Errata #39 - RTS0 is not internally connected to PA21. | ||
879 | * We need to drive the pin manually. Default is off (RTS is active low). | ||
880 | */ | ||
881 | at91_set_gpio_output(AT91_PIN_PA21, 1); | ||
882 | } | ||
718 | } | 883 | } |
719 | 884 | ||
720 | static struct resource uart1_resources[] = { | 885 | static struct resource uart1_resources[] = { |
@@ -735,27 +900,37 @@ static struct atmel_uart_data uart1_data = { | |||
735 | .use_dma_rx = 1, | 900 | .use_dma_rx = 1, |
736 | }; | 901 | }; |
737 | 902 | ||
903 | static u64 uart1_dmamask = DMA_BIT_MASK(32); | ||
904 | |||
738 | static struct platform_device at91rm9200_uart1_device = { | 905 | static struct platform_device at91rm9200_uart1_device = { |
739 | .name = "atmel_usart", | 906 | .name = "atmel_usart", |
740 | .id = 2, | 907 | .id = 2, |
741 | .dev = { | 908 | .dev = { |
742 | .platform_data = &uart1_data, | 909 | .dma_mask = &uart1_dmamask, |
743 | .coherent_dma_mask = 0xffffffff, | 910 | .coherent_dma_mask = DMA_BIT_MASK(32), |
911 | .platform_data = &uart1_data, | ||
744 | }, | 912 | }, |
745 | .resource = uart1_resources, | 913 | .resource = uart1_resources, |
746 | .num_resources = ARRAY_SIZE(uart1_resources), | 914 | .num_resources = ARRAY_SIZE(uart1_resources), |
747 | }; | 915 | }; |
748 | 916 | ||
749 | static inline void configure_usart1_pins(void) | 917 | static inline void configure_usart1_pins(unsigned pins) |
750 | { | 918 | { |
751 | at91_set_A_periph(AT91_PIN_PB18, 0); /* RI1 */ | ||
752 | at91_set_A_periph(AT91_PIN_PB19, 0); /* DTR1 */ | ||
753 | at91_set_A_periph(AT91_PIN_PB20, 1); /* TXD1 */ | 919 | at91_set_A_periph(AT91_PIN_PB20, 1); /* TXD1 */ |
754 | at91_set_A_periph(AT91_PIN_PB21, 0); /* RXD1 */ | 920 | at91_set_A_periph(AT91_PIN_PB21, 0); /* RXD1 */ |
755 | at91_set_A_periph(AT91_PIN_PB23, 0); /* DCD1 */ | 921 | |
756 | at91_set_A_periph(AT91_PIN_PB24, 0); /* CTS1 */ | 922 | if (pins & ATMEL_UART_RI) |
757 | at91_set_A_periph(AT91_PIN_PB25, 0); /* DSR1 */ | 923 | at91_set_A_periph(AT91_PIN_PB18, 0); /* RI1 */ |
758 | at91_set_A_periph(AT91_PIN_PB26, 0); /* RTS1 */ | 924 | if (pins & ATMEL_UART_DTR) |
925 | at91_set_A_periph(AT91_PIN_PB19, 0); /* DTR1 */ | ||
926 | if (pins & ATMEL_UART_DCD) | ||
927 | at91_set_A_periph(AT91_PIN_PB23, 0); /* DCD1 */ | ||
928 | if (pins & ATMEL_UART_CTS) | ||
929 | at91_set_A_periph(AT91_PIN_PB24, 0); /* CTS1 */ | ||
930 | if (pins & ATMEL_UART_DSR) | ||
931 | at91_set_A_periph(AT91_PIN_PB25, 0); /* DSR1 */ | ||
932 | if (pins & ATMEL_UART_RTS) | ||
933 | at91_set_A_periph(AT91_PIN_PB26, 0); /* RTS1 */ | ||
759 | } | 934 | } |
760 | 935 | ||
761 | static struct resource uart2_resources[] = { | 936 | static struct resource uart2_resources[] = { |
@@ -776,21 +951,29 @@ static struct atmel_uart_data uart2_data = { | |||
776 | .use_dma_rx = 1, | 951 | .use_dma_rx = 1, |
777 | }; | 952 | }; |
778 | 953 | ||
954 | static u64 uart2_dmamask = DMA_BIT_MASK(32); | ||
955 | |||
779 | static struct platform_device at91rm9200_uart2_device = { | 956 | static struct platform_device at91rm9200_uart2_device = { |
780 | .name = "atmel_usart", | 957 | .name = "atmel_usart", |
781 | .id = 3, | 958 | .id = 3, |
782 | .dev = { | 959 | .dev = { |
783 | .platform_data = &uart2_data, | 960 | .dma_mask = &uart2_dmamask, |
784 | .coherent_dma_mask = 0xffffffff, | 961 | .coherent_dma_mask = DMA_BIT_MASK(32), |
962 | .platform_data = &uart2_data, | ||
785 | }, | 963 | }, |
786 | .resource = uart2_resources, | 964 | .resource = uart2_resources, |
787 | .num_resources = ARRAY_SIZE(uart2_resources), | 965 | .num_resources = ARRAY_SIZE(uart2_resources), |
788 | }; | 966 | }; |
789 | 967 | ||
790 | static inline void configure_usart2_pins(void) | 968 | static inline void configure_usart2_pins(unsigned pins) |
791 | { | 969 | { |
792 | at91_set_A_periph(AT91_PIN_PA22, 0); /* RXD2 */ | 970 | at91_set_A_periph(AT91_PIN_PA22, 0); /* RXD2 */ |
793 | at91_set_A_periph(AT91_PIN_PA23, 1); /* TXD2 */ | 971 | at91_set_A_periph(AT91_PIN_PA23, 1); /* TXD2 */ |
972 | |||
973 | if (pins & ATMEL_UART_CTS) | ||
974 | at91_set_B_periph(AT91_PIN_PA30, 0); /* CTS2 */ | ||
975 | if (pins & ATMEL_UART_RTS) | ||
976 | at91_set_B_periph(AT91_PIN_PA31, 0); /* RTS2 */ | ||
794 | } | 977 | } |
795 | 978 | ||
796 | static struct resource uart3_resources[] = { | 979 | static struct resource uart3_resources[] = { |
@@ -811,27 +994,35 @@ static struct atmel_uart_data uart3_data = { | |||
811 | .use_dma_rx = 1, | 994 | .use_dma_rx = 1, |
812 | }; | 995 | }; |
813 | 996 | ||
997 | static u64 uart3_dmamask = DMA_BIT_MASK(32); | ||
998 | |||
814 | static struct platform_device at91rm9200_uart3_device = { | 999 | static struct platform_device at91rm9200_uart3_device = { |
815 | .name = "atmel_usart", | 1000 | .name = "atmel_usart", |
816 | .id = 4, | 1001 | .id = 4, |
817 | .dev = { | 1002 | .dev = { |
818 | .platform_data = &uart3_data, | 1003 | .dma_mask = &uart3_dmamask, |
819 | .coherent_dma_mask = 0xffffffff, | 1004 | .coherent_dma_mask = DMA_BIT_MASK(32), |
1005 | .platform_data = &uart3_data, | ||
820 | }, | 1006 | }, |
821 | .resource = uart3_resources, | 1007 | .resource = uart3_resources, |
822 | .num_resources = ARRAY_SIZE(uart3_resources), | 1008 | .num_resources = ARRAY_SIZE(uart3_resources), |
823 | }; | 1009 | }; |
824 | 1010 | ||
825 | static inline void configure_usart3_pins(void) | 1011 | static inline void configure_usart3_pins(unsigned pins) |
826 | { | 1012 | { |
827 | at91_set_B_periph(AT91_PIN_PA5, 1); /* TXD3 */ | 1013 | at91_set_B_periph(AT91_PIN_PA5, 1); /* TXD3 */ |
828 | at91_set_B_periph(AT91_PIN_PA6, 0); /* RXD3 */ | 1014 | at91_set_B_periph(AT91_PIN_PA6, 0); /* RXD3 */ |
1015 | |||
1016 | if (pins & ATMEL_UART_CTS) | ||
1017 | at91_set_B_periph(AT91_PIN_PB1, 0); /* CTS3 */ | ||
1018 | if (pins & ATMEL_UART_RTS) | ||
1019 | at91_set_B_periph(AT91_PIN_PB0, 0); /* RTS3 */ | ||
829 | } | 1020 | } |
830 | 1021 | ||
831 | struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ | 1022 | static struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ |
832 | struct platform_device *atmel_default_console_device; /* the serial console device */ | 1023 | struct platform_device *atmel_default_console_device; /* the serial console device */ |
833 | 1024 | ||
834 | void __init at91_init_serial(struct at91_uart_config *config) | 1025 | void __init __deprecated at91_init_serial(struct at91_uart_config *config) |
835 | { | 1026 | { |
836 | int i; | 1027 | int i; |
837 | 1028 | ||
@@ -839,22 +1030,22 @@ void __init at91_init_serial(struct at91_uart_config *config) | |||
839 | for (i = 0; i < config->nr_tty; i++) { | 1030 | for (i = 0; i < config->nr_tty; i++) { |
840 | switch (config->tty_map[i]) { | 1031 | switch (config->tty_map[i]) { |
841 | case 0: | 1032 | case 0: |
842 | configure_usart0_pins(); | 1033 | configure_usart0_pins(ATMEL_UART_CTS | ATMEL_UART_RTS); |
843 | at91_uarts[i] = &at91rm9200_uart0_device; | 1034 | at91_uarts[i] = &at91rm9200_uart0_device; |
844 | at91_clock_associate("usart0_clk", &at91rm9200_uart0_device.dev, "usart"); | 1035 | at91_clock_associate("usart0_clk", &at91rm9200_uart0_device.dev, "usart"); |
845 | break; | 1036 | break; |
846 | case 1: | 1037 | case 1: |
847 | configure_usart1_pins(); | 1038 | configure_usart1_pins(ATMEL_UART_CTS | ATMEL_UART_RTS | ATMEL_UART_DSR | ATMEL_UART_DTR | ATMEL_UART_DCD | ATMEL_UART_RI); |
848 | at91_uarts[i] = &at91rm9200_uart1_device; | 1039 | at91_uarts[i] = &at91rm9200_uart1_device; |
849 | at91_clock_associate("usart1_clk", &at91rm9200_uart1_device.dev, "usart"); | 1040 | at91_clock_associate("usart1_clk", &at91rm9200_uart1_device.dev, "usart"); |
850 | break; | 1041 | break; |
851 | case 2: | 1042 | case 2: |
852 | configure_usart2_pins(); | 1043 | configure_usart2_pins(0); |
853 | at91_uarts[i] = &at91rm9200_uart2_device; | 1044 | at91_uarts[i] = &at91rm9200_uart2_device; |
854 | at91_clock_associate("usart2_clk", &at91rm9200_uart2_device.dev, "usart"); | 1045 | at91_clock_associate("usart2_clk", &at91rm9200_uart2_device.dev, "usart"); |
855 | break; | 1046 | break; |
856 | case 3: | 1047 | case 3: |
857 | configure_usart3_pins(); | 1048 | configure_usart3_pins(0); |
858 | at91_uarts[i] = &at91rm9200_uart3_device; | 1049 | at91_uarts[i] = &at91rm9200_uart3_device; |
859 | at91_clock_associate("usart3_clk", &at91rm9200_uart3_device.dev, "usart"); | 1050 | at91_clock_associate("usart3_clk", &at91rm9200_uart3_device.dev, "usart"); |
860 | break; | 1051 | break; |
@@ -876,6 +1067,53 @@ void __init at91_init_serial(struct at91_uart_config *config) | |||
876 | printk(KERN_INFO "AT91: No default serial console defined.\n"); | 1067 | printk(KERN_INFO "AT91: No default serial console defined.\n"); |
877 | } | 1068 | } |
878 | 1069 | ||
1070 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) | ||
1071 | { | ||
1072 | struct platform_device *pdev; | ||
1073 | |||
1074 | switch (id) { | ||
1075 | case 0: /* DBGU */ | ||
1076 | pdev = &at91rm9200_dbgu_device; | ||
1077 | configure_dbgu_pins(); | ||
1078 | at91_clock_associate("mck", &pdev->dev, "usart"); | ||
1079 | break; | ||
1080 | case AT91RM9200_ID_US0: | ||
1081 | pdev = &at91rm9200_uart0_device; | ||
1082 | configure_usart0_pins(pins); | ||
1083 | at91_clock_associate("usart0_clk", &pdev->dev, "usart"); | ||
1084 | break; | ||
1085 | case AT91RM9200_ID_US1: | ||
1086 | pdev = &at91rm9200_uart1_device; | ||
1087 | configure_usart1_pins(pins); | ||
1088 | at91_clock_associate("usart1_clk", &pdev->dev, "usart"); | ||
1089 | break; | ||
1090 | case AT91RM9200_ID_US2: | ||
1091 | pdev = &at91rm9200_uart2_device; | ||
1092 | configure_usart2_pins(pins); | ||
1093 | at91_clock_associate("usart2_clk", &pdev->dev, "usart"); | ||
1094 | break; | ||
1095 | case AT91RM9200_ID_US3: | ||
1096 | pdev = &at91rm9200_uart3_device; | ||
1097 | configure_usart3_pins(pins); | ||
1098 | at91_clock_associate("usart3_clk", &pdev->dev, "usart"); | ||
1099 | break; | ||
1100 | default: | ||
1101 | return; | ||
1102 | } | ||
1103 | pdev->id = portnr; /* update to mapped ID */ | ||
1104 | |||
1105 | if (portnr < ATMEL_MAX_UART) | ||
1106 | at91_uarts[portnr] = pdev; | ||
1107 | } | ||
1108 | |||
1109 | void __init at91_set_serial_console(unsigned portnr) | ||
1110 | { | ||
1111 | if (portnr < ATMEL_MAX_UART) | ||
1112 | atmel_default_console_device = at91_uarts[portnr]; | ||
1113 | if (!atmel_default_console_device) | ||
1114 | printk(KERN_INFO "AT91: No default serial console defined.\n"); | ||
1115 | } | ||
1116 | |||
879 | void __init at91_add_device_serial(void) | 1117 | void __init at91_add_device_serial(void) |
880 | { | 1118 | { |
881 | int i; | 1119 | int i; |
@@ -886,7 +1124,9 @@ void __init at91_add_device_serial(void) | |||
886 | } | 1124 | } |
887 | } | 1125 | } |
888 | #else | 1126 | #else |
889 | void __init at91_init_serial(struct at91_uart_config *config) {} | 1127 | void __init __deprecated at91_init_serial(struct at91_uart_config *config) {} |
1128 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} | ||
1129 | void __init at91_set_serial_console(unsigned portnr) {} | ||
890 | void __init at91_add_device_serial(void) {} | 1130 | void __init at91_add_device_serial(void) {} |
891 | #endif | 1131 | #endif |
892 | 1132 | ||
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index e47381e8aaba..18d06612ce8a 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c | |||
@@ -327,30 +327,30 @@ void __init at91sam9260_initialize(unsigned long main_clock) | |||
327 | static unsigned int at91sam9260_default_irq_priority[NR_AIC_IRQS] __initdata = { | 327 | static unsigned int at91sam9260_default_irq_priority[NR_AIC_IRQS] __initdata = { |
328 | 7, /* Advanced Interrupt Controller */ | 328 | 7, /* Advanced Interrupt Controller */ |
329 | 7, /* System Peripherals */ | 329 | 7, /* System Peripherals */ |
330 | 0, /* Parallel IO Controller A */ | 330 | 1, /* Parallel IO Controller A */ |
331 | 0, /* Parallel IO Controller B */ | 331 | 1, /* Parallel IO Controller B */ |
332 | 0, /* Parallel IO Controller C */ | 332 | 1, /* Parallel IO Controller C */ |
333 | 0, /* Analog-to-Digital Converter */ | 333 | 0, /* Analog-to-Digital Converter */ |
334 | 6, /* USART 0 */ | 334 | 5, /* USART 0 */ |
335 | 6, /* USART 1 */ | 335 | 5, /* USART 1 */ |
336 | 6, /* USART 2 */ | 336 | 5, /* USART 2 */ |
337 | 0, /* Multimedia Card Interface */ | 337 | 0, /* Multimedia Card Interface */ |
338 | 4, /* USB Device Port */ | 338 | 2, /* USB Device Port */ |
339 | 0, /* Two-Wire Interface */ | 339 | 6, /* Two-Wire Interface */ |
340 | 6, /* Serial Peripheral Interface 0 */ | 340 | 5, /* Serial Peripheral Interface 0 */ |
341 | 6, /* Serial Peripheral Interface 1 */ | 341 | 5, /* Serial Peripheral Interface 1 */ |
342 | 5, /* Serial Synchronous Controller */ | 342 | 5, /* Serial Synchronous Controller */ |
343 | 0, | 343 | 0, |
344 | 0, | 344 | 0, |
345 | 0, /* Timer Counter 0 */ | 345 | 0, /* Timer Counter 0 */ |
346 | 0, /* Timer Counter 1 */ | 346 | 0, /* Timer Counter 1 */ |
347 | 0, /* Timer Counter 2 */ | 347 | 0, /* Timer Counter 2 */ |
348 | 3, /* USB Host port */ | 348 | 2, /* USB Host port */ |
349 | 3, /* Ethernet */ | 349 | 3, /* Ethernet */ |
350 | 0, /* Image Sensor Interface */ | 350 | 0, /* Image Sensor Interface */ |
351 | 6, /* USART 3 */ | 351 | 5, /* USART 3 */ |
352 | 6, /* USART 4 */ | 352 | 5, /* USART 4 */ |
353 | 6, /* USART 5 */ | 353 | 5, /* USART 5 */ |
354 | 0, /* Timer Counter 3 */ | 354 | 0, /* Timer Counter 3 */ |
355 | 0, /* Timer Counter 4 */ | 355 | 0, /* Timer Counter 4 */ |
356 | 0, /* Timer Counter 5 */ | 356 | 0, /* Timer Counter 5 */ |
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index 3091bf47d8c9..105f8403860b 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <asm/mach/arch.h> | 12 | #include <asm/mach/arch.h> |
13 | #include <asm/mach/map.h> | 13 | #include <asm/mach/map.h> |
14 | 14 | ||
15 | #include <linux/dma-mapping.h> | ||
15 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
16 | #include <linux/i2c-gpio.h> | 17 | #include <linux/i2c-gpio.h> |
17 | 18 | ||
@@ -29,7 +30,7 @@ | |||
29 | * -------------------------------------------------------------------- */ | 30 | * -------------------------------------------------------------------- */ |
30 | 31 | ||
31 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | 32 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) |
32 | static u64 ohci_dmamask = 0xffffffffUL; | 33 | static u64 ohci_dmamask = DMA_BIT_MASK(32); |
33 | static struct at91_usbh_data usbh_data; | 34 | static struct at91_usbh_data usbh_data; |
34 | 35 | ||
35 | static struct resource usbh_resources[] = { | 36 | static struct resource usbh_resources[] = { |
@@ -50,7 +51,7 @@ static struct platform_device at91_usbh_device = { | |||
50 | .id = -1, | 51 | .id = -1, |
51 | .dev = { | 52 | .dev = { |
52 | .dma_mask = &ohci_dmamask, | 53 | .dma_mask = &ohci_dmamask, |
53 | .coherent_dma_mask = 0xffffffff, | 54 | .coherent_dma_mask = DMA_BIT_MASK(32), |
54 | .platform_data = &usbh_data, | 55 | .platform_data = &usbh_data, |
55 | }, | 56 | }, |
56 | .resource = usbh_resources, | 57 | .resource = usbh_resources, |
@@ -125,7 +126,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data) {} | |||
125 | * -------------------------------------------------------------------- */ | 126 | * -------------------------------------------------------------------- */ |
126 | 127 | ||
127 | #if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) | 128 | #if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) |
128 | static u64 eth_dmamask = 0xffffffffUL; | 129 | static u64 eth_dmamask = DMA_BIT_MASK(32); |
129 | static struct at91_eth_data eth_data; | 130 | static struct at91_eth_data eth_data; |
130 | 131 | ||
131 | static struct resource eth_resources[] = { | 132 | static struct resource eth_resources[] = { |
@@ -146,7 +147,7 @@ static struct platform_device at91sam9260_eth_device = { | |||
146 | .id = -1, | 147 | .id = -1, |
147 | .dev = { | 148 | .dev = { |
148 | .dma_mask = ð_dmamask, | 149 | .dma_mask = ð_dmamask, |
149 | .coherent_dma_mask = 0xffffffff, | 150 | .coherent_dma_mask = DMA_BIT_MASK(32), |
150 | .platform_data = ð_data, | 151 | .platform_data = ð_data, |
151 | }, | 152 | }, |
152 | .resource = eth_resources, | 153 | .resource = eth_resources, |
@@ -199,7 +200,7 @@ void __init at91_add_device_eth(struct at91_eth_data *data) {} | |||
199 | * -------------------------------------------------------------------- */ | 200 | * -------------------------------------------------------------------- */ |
200 | 201 | ||
201 | #if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) | 202 | #if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) |
202 | static u64 mmc_dmamask = 0xffffffffUL; | 203 | static u64 mmc_dmamask = DMA_BIT_MASK(32); |
203 | static struct at91_mmc_data mmc_data; | 204 | static struct at91_mmc_data mmc_data; |
204 | 205 | ||
205 | static struct resource mmc_resources[] = { | 206 | static struct resource mmc_resources[] = { |
@@ -220,7 +221,7 @@ static struct platform_device at91sam9260_mmc_device = { | |||
220 | .id = -1, | 221 | .id = -1, |
221 | .dev = { | 222 | .dev = { |
222 | .dma_mask = &mmc_dmamask, | 223 | .dma_mask = &mmc_dmamask, |
223 | .coherent_dma_mask = 0xffffffff, | 224 | .coherent_dma_mask = DMA_BIT_MASK(32), |
224 | .platform_data = &mmc_data, | 225 | .platform_data = &mmc_data, |
225 | }, | 226 | }, |
226 | .resource = mmc_resources, | 227 | .resource = mmc_resources, |
@@ -289,7 +290,7 @@ static struct at91_nand_data nand_data; | |||
289 | static struct resource nand_resources[] = { | 290 | static struct resource nand_resources[] = { |
290 | { | 291 | { |
291 | .start = NAND_BASE, | 292 | .start = NAND_BASE, |
292 | .end = NAND_BASE + SZ_8M - 1, | 293 | .end = NAND_BASE + SZ_256M - 1, |
293 | .flags = IORESOURCE_MEM, | 294 | .flags = IORESOURCE_MEM, |
294 | } | 295 | } |
295 | }; | 296 | }; |
@@ -312,7 +313,7 @@ void __init at91_add_device_nand(struct at91_nand_data *data) | |||
312 | return; | 313 | return; |
313 | 314 | ||
314 | csa = at91_sys_read(AT91_MATRIX_EBICSA); | 315 | csa = at91_sys_read(AT91_MATRIX_EBICSA); |
315 | at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC); | 316 | at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); |
316 | 317 | ||
317 | /* set the bus interface characteristics */ | 318 | /* set the bus interface characteristics */ |
318 | at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0) | 319 | at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0) |
@@ -431,7 +432,7 @@ void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) | |||
431 | * -------------------------------------------------------------------- */ | 432 | * -------------------------------------------------------------------- */ |
432 | 433 | ||
433 | #if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) | 434 | #if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) |
434 | static u64 spi_dmamask = 0xffffffffUL; | 435 | static u64 spi_dmamask = DMA_BIT_MASK(32); |
435 | 436 | ||
436 | static struct resource spi0_resources[] = { | 437 | static struct resource spi0_resources[] = { |
437 | [0] = { | 438 | [0] = { |
@@ -451,7 +452,7 @@ static struct platform_device at91sam9260_spi0_device = { | |||
451 | .id = 0, | 452 | .id = 0, |
452 | .dev = { | 453 | .dev = { |
453 | .dma_mask = &spi_dmamask, | 454 | .dma_mask = &spi_dmamask, |
454 | .coherent_dma_mask = 0xffffffff, | 455 | .coherent_dma_mask = DMA_BIT_MASK(32), |
455 | }, | 456 | }, |
456 | .resource = spi0_resources, | 457 | .resource = spi0_resources, |
457 | .num_resources = ARRAY_SIZE(spi0_resources), | 458 | .num_resources = ARRAY_SIZE(spi0_resources), |
@@ -477,7 +478,7 @@ static struct platform_device at91sam9260_spi1_device = { | |||
477 | .id = 1, | 478 | .id = 1, |
478 | .dev = { | 479 | .dev = { |
479 | .dma_mask = &spi_dmamask, | 480 | .dma_mask = &spi_dmamask, |
480 | .coherent_dma_mask = 0xffffffff, | 481 | .coherent_dma_mask = DMA_BIT_MASK(32), |
481 | }, | 482 | }, |
482 | .resource = spi1_resources, | 483 | .resource = spi1_resources, |
483 | .num_resources = ARRAY_SIZE(spi1_resources), | 484 | .num_resources = ARRAY_SIZE(spi1_resources), |
@@ -539,24 +540,126 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) | |||
539 | 540 | ||
540 | 541 | ||
541 | /* -------------------------------------------------------------------- | 542 | /* -------------------------------------------------------------------- |
542 | * LEDs | 543 | * RTT |
543 | * -------------------------------------------------------------------- */ | 544 | * -------------------------------------------------------------------- */ |
544 | 545 | ||
545 | #if defined(CONFIG_LEDS) | 546 | static struct resource rtt_resources[] = { |
546 | u8 at91_leds_cpu; | 547 | { |
547 | u8 at91_leds_timer; | 548 | .start = AT91_BASE_SYS + AT91_RTT, |
549 | .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1, | ||
550 | .flags = IORESOURCE_MEM, | ||
551 | } | ||
552 | }; | ||
548 | 553 | ||
549 | void __init at91_init_leds(u8 cpu_led, u8 timer_led) | 554 | static struct platform_device at91sam9260_rtt_device = { |
555 | .name = "at91_rtt", | ||
556 | .id = -1, | ||
557 | .resource = rtt_resources, | ||
558 | .num_resources = ARRAY_SIZE(rtt_resources), | ||
559 | }; | ||
560 | |||
561 | static void __init at91_add_device_rtt(void) | ||
550 | { | 562 | { |
551 | /* Enable GPIO to access the LEDs */ | 563 | platform_device_register(&at91sam9260_rtt_device); |
552 | at91_set_gpio_output(cpu_led, 1); | 564 | } |
553 | at91_set_gpio_output(timer_led, 1); | 565 | |
554 | 566 | ||
555 | at91_leds_cpu = cpu_led; | 567 | /* -------------------------------------------------------------------- |
556 | at91_leds_timer = timer_led; | 568 | * Watchdog |
569 | * -------------------------------------------------------------------- */ | ||
570 | |||
571 | #if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE) | ||
572 | static struct platform_device at91sam9260_wdt_device = { | ||
573 | .name = "at91_wdt", | ||
574 | .id = -1, | ||
575 | .num_resources = 0, | ||
576 | }; | ||
577 | |||
578 | static void __init at91_add_device_watchdog(void) | ||
579 | { | ||
580 | platform_device_register(&at91sam9260_wdt_device); | ||
557 | } | 581 | } |
558 | #else | 582 | #else |
559 | void __init at91_init_leds(u8 cpu_led, u8 timer_led) {} | 583 | static void __init at91_add_device_watchdog(void) {} |
584 | #endif | ||
585 | |||
586 | |||
587 | /* -------------------------------------------------------------------- | ||
588 | * SSC -- Synchronous Serial Controller | ||
589 | * -------------------------------------------------------------------- */ | ||
590 | |||
591 | #if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE) | ||
592 | static u64 ssc_dmamask = DMA_BIT_MASK(32); | ||
593 | |||
594 | static struct resource ssc_resources[] = { | ||
595 | [0] = { | ||
596 | .start = AT91SAM9260_BASE_SSC, | ||
597 | .end = AT91SAM9260_BASE_SSC + SZ_16K - 1, | ||
598 | .flags = IORESOURCE_MEM, | ||
599 | }, | ||
600 | [1] = { | ||
601 | .start = AT91SAM9260_ID_SSC, | ||
602 | .end = AT91SAM9260_ID_SSC, | ||
603 | .flags = IORESOURCE_IRQ, | ||
604 | }, | ||
605 | }; | ||
606 | |||
607 | static struct platform_device at91sam9260_ssc_device = { | ||
608 | .name = "ssc", | ||
609 | .id = 0, | ||
610 | .dev = { | ||
611 | .dma_mask = &ssc_dmamask, | ||
612 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
613 | }, | ||
614 | .resource = ssc_resources, | ||
615 | .num_resources = ARRAY_SIZE(ssc_resources), | ||
616 | }; | ||
617 | |||
618 | static inline void configure_ssc_pins(unsigned pins) | ||
619 | { | ||
620 | if (pins & ATMEL_SSC_TF) | ||
621 | at91_set_A_periph(AT91_PIN_PB17, 1); | ||
622 | if (pins & ATMEL_SSC_TK) | ||
623 | at91_set_A_periph(AT91_PIN_PB16, 1); | ||
624 | if (pins & ATMEL_SSC_TD) | ||
625 | at91_set_A_periph(AT91_PIN_PB18, 1); | ||
626 | if (pins & ATMEL_SSC_RD) | ||
627 | at91_set_A_periph(AT91_PIN_PB19, 1); | ||
628 | if (pins & ATMEL_SSC_RK) | ||
629 | at91_set_A_periph(AT91_PIN_PB20, 1); | ||
630 | if (pins & ATMEL_SSC_RF) | ||
631 | at91_set_A_periph(AT91_PIN_PB21, 1); | ||
632 | } | ||
633 | |||
634 | /* | ||
635 | * SSC controllers are accessed through library code, instead of any | ||
636 | * kind of all-singing/all-dancing driver. For example one could be | ||
637 | * used by a particular I2S audio codec's driver, while another one | ||
638 | * on the same system might be used by a custom data capture driver. | ||
639 | */ | ||
640 | void __init at91_add_device_ssc(unsigned id, unsigned pins) | ||
641 | { | ||
642 | struct platform_device *pdev; | ||
643 | |||
644 | /* | ||
645 | * NOTE: caller is responsible for passing information matching | ||
646 | * "pins" to whatever will be using each particular controller. | ||
647 | */ | ||
648 | switch (id) { | ||
649 | case AT91SAM9260_ID_SSC: | ||
650 | pdev = &at91sam9260_ssc_device; | ||
651 | configure_ssc_pins(pins); | ||
652 | at91_clock_associate("ssc_clk", &pdev->dev, "pclk"); | ||
653 | break; | ||
654 | default: | ||
655 | return; | ||
656 | } | ||
657 | |||
658 | platform_device_register(pdev); | ||
659 | } | ||
660 | |||
661 | #else | ||
662 | void __init at91_add_device_ssc(unsigned id, unsigned pins) {} | ||
560 | #endif | 663 | #endif |
561 | 664 | ||
562 | 665 | ||
@@ -583,12 +686,15 @@ static struct atmel_uart_data dbgu_data = { | |||
583 | .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), | 686 | .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), |
584 | }; | 687 | }; |
585 | 688 | ||
689 | static u64 dbgu_dmamask = DMA_BIT_MASK(32); | ||
690 | |||
586 | static struct platform_device at91sam9260_dbgu_device = { | 691 | static struct platform_device at91sam9260_dbgu_device = { |
587 | .name = "atmel_usart", | 692 | .name = "atmel_usart", |
588 | .id = 0, | 693 | .id = 0, |
589 | .dev = { | 694 | .dev = { |
590 | .platform_data = &dbgu_data, | 695 | .dma_mask = &dbgu_dmamask, |
591 | .coherent_dma_mask = 0xffffffff, | 696 | .coherent_dma_mask = DMA_BIT_MASK(32), |
697 | .platform_data = &dbgu_data, | ||
592 | }, | 698 | }, |
593 | .resource = dbgu_resources, | 699 | .resource = dbgu_resources, |
594 | .num_resources = ARRAY_SIZE(dbgu_resources), | 700 | .num_resources = ARRAY_SIZE(dbgu_resources), |
@@ -618,27 +724,37 @@ static struct atmel_uart_data uart0_data = { | |||
618 | .use_dma_rx = 1, | 724 | .use_dma_rx = 1, |
619 | }; | 725 | }; |
620 | 726 | ||
727 | static u64 uart0_dmamask = DMA_BIT_MASK(32); | ||
728 | |||
621 | static struct platform_device at91sam9260_uart0_device = { | 729 | static struct platform_device at91sam9260_uart0_device = { |
622 | .name = "atmel_usart", | 730 | .name = "atmel_usart", |
623 | .id = 1, | 731 | .id = 1, |
624 | .dev = { | 732 | .dev = { |
625 | .platform_data = &uart0_data, | 733 | .dma_mask = &uart0_dmamask, |
626 | .coherent_dma_mask = 0xffffffff, | 734 | .coherent_dma_mask = DMA_BIT_MASK(32), |
735 | .platform_data = &uart0_data, | ||
627 | }, | 736 | }, |
628 | .resource = uart0_resources, | 737 | .resource = uart0_resources, |
629 | .num_resources = ARRAY_SIZE(uart0_resources), | 738 | .num_resources = ARRAY_SIZE(uart0_resources), |
630 | }; | 739 | }; |
631 | 740 | ||
632 | static inline void configure_usart0_pins(void) | 741 | static inline void configure_usart0_pins(unsigned pins) |
633 | { | 742 | { |
634 | at91_set_A_periph(AT91_PIN_PB4, 1); /* TXD0 */ | 743 | at91_set_A_periph(AT91_PIN_PB4, 1); /* TXD0 */ |
635 | at91_set_A_periph(AT91_PIN_PB5, 0); /* RXD0 */ | 744 | at91_set_A_periph(AT91_PIN_PB5, 0); /* RXD0 */ |
636 | at91_set_A_periph(AT91_PIN_PB26, 0); /* RTS0 */ | 745 | |
637 | at91_set_A_periph(AT91_PIN_PB27, 0); /* CTS0 */ | 746 | if (pins & ATMEL_UART_RTS) |
638 | at91_set_A_periph(AT91_PIN_PB24, 0); /* DTR0 */ | 747 | at91_set_A_periph(AT91_PIN_PB26, 0); /* RTS0 */ |
639 | at91_set_A_periph(AT91_PIN_PB22, 0); /* DSR0 */ | 748 | if (pins & ATMEL_UART_CTS) |
640 | at91_set_A_periph(AT91_PIN_PB23, 0); /* DCD0 */ | 749 | at91_set_A_periph(AT91_PIN_PB27, 0); /* CTS0 */ |
641 | at91_set_A_periph(AT91_PIN_PB25, 0); /* RI0 */ | 750 | if (pins & ATMEL_UART_DTR) |
751 | at91_set_A_periph(AT91_PIN_PB24, 0); /* DTR0 */ | ||
752 | if (pins & ATMEL_UART_DSR) | ||
753 | at91_set_A_periph(AT91_PIN_PB22, 0); /* DSR0 */ | ||
754 | if (pins & ATMEL_UART_DCD) | ||
755 | at91_set_A_periph(AT91_PIN_PB23, 0); /* DCD0 */ | ||
756 | if (pins & ATMEL_UART_RI) | ||
757 | at91_set_A_periph(AT91_PIN_PB25, 0); /* RI0 */ | ||
642 | } | 758 | } |
643 | 759 | ||
644 | static struct resource uart1_resources[] = { | 760 | static struct resource uart1_resources[] = { |
@@ -659,23 +775,29 @@ static struct atmel_uart_data uart1_data = { | |||
659 | .use_dma_rx = 1, | 775 | .use_dma_rx = 1, |
660 | }; | 776 | }; |
661 | 777 | ||
778 | static u64 uart1_dmamask = DMA_BIT_MASK(32); | ||
779 | |||
662 | static struct platform_device at91sam9260_uart1_device = { | 780 | static struct platform_device at91sam9260_uart1_device = { |
663 | .name = "atmel_usart", | 781 | .name = "atmel_usart", |
664 | .id = 2, | 782 | .id = 2, |
665 | .dev = { | 783 | .dev = { |
666 | .platform_data = &uart1_data, | 784 | .dma_mask = &uart1_dmamask, |
667 | .coherent_dma_mask = 0xffffffff, | 785 | .coherent_dma_mask = DMA_BIT_MASK(32), |
786 | .platform_data = &uart1_data, | ||
668 | }, | 787 | }, |
669 | .resource = uart1_resources, | 788 | .resource = uart1_resources, |
670 | .num_resources = ARRAY_SIZE(uart1_resources), | 789 | .num_resources = ARRAY_SIZE(uart1_resources), |
671 | }; | 790 | }; |
672 | 791 | ||
673 | static inline void configure_usart1_pins(void) | 792 | static inline void configure_usart1_pins(unsigned pins) |
674 | { | 793 | { |
675 | at91_set_A_periph(AT91_PIN_PB6, 1); /* TXD1 */ | 794 | at91_set_A_periph(AT91_PIN_PB6, 1); /* TXD1 */ |
676 | at91_set_A_periph(AT91_PIN_PB7, 0); /* RXD1 */ | 795 | at91_set_A_periph(AT91_PIN_PB7, 0); /* RXD1 */ |
677 | at91_set_A_periph(AT91_PIN_PB28, 0); /* RTS1 */ | 796 | |
678 | at91_set_A_periph(AT91_PIN_PB29, 0); /* CTS1 */ | 797 | if (pins & ATMEL_UART_RTS) |
798 | at91_set_A_periph(AT91_PIN_PB28, 0); /* RTS1 */ | ||
799 | if (pins & ATMEL_UART_CTS) | ||
800 | at91_set_A_periph(AT91_PIN_PB29, 0); /* CTS1 */ | ||
679 | } | 801 | } |
680 | 802 | ||
681 | static struct resource uart2_resources[] = { | 803 | static struct resource uart2_resources[] = { |
@@ -696,21 +818,29 @@ static struct atmel_uart_data uart2_data = { | |||
696 | .use_dma_rx = 1, | 818 | .use_dma_rx = 1, |
697 | }; | 819 | }; |
698 | 820 | ||
821 | static u64 uart2_dmamask = DMA_BIT_MASK(32); | ||
822 | |||
699 | static struct platform_device at91sam9260_uart2_device = { | 823 | static struct platform_device at91sam9260_uart2_device = { |
700 | .name = "atmel_usart", | 824 | .name = "atmel_usart", |
701 | .id = 3, | 825 | .id = 3, |
702 | .dev = { | 826 | .dev = { |
703 | .platform_data = &uart2_data, | 827 | .dma_mask = &uart2_dmamask, |
704 | .coherent_dma_mask = 0xffffffff, | 828 | .coherent_dma_mask = DMA_BIT_MASK(32), |
829 | .platform_data = &uart2_data, | ||
705 | }, | 830 | }, |
706 | .resource = uart2_resources, | 831 | .resource = uart2_resources, |
707 | .num_resources = ARRAY_SIZE(uart2_resources), | 832 | .num_resources = ARRAY_SIZE(uart2_resources), |
708 | }; | 833 | }; |
709 | 834 | ||
710 | static inline void configure_usart2_pins(void) | 835 | static inline void configure_usart2_pins(unsigned pins) |
711 | { | 836 | { |
712 | at91_set_A_periph(AT91_PIN_PB8, 1); /* TXD2 */ | 837 | at91_set_A_periph(AT91_PIN_PB8, 1); /* TXD2 */ |
713 | at91_set_A_periph(AT91_PIN_PB9, 0); /* RXD2 */ | 838 | at91_set_A_periph(AT91_PIN_PB9, 0); /* RXD2 */ |
839 | |||
840 | if (pins & ATMEL_UART_RTS) | ||
841 | at91_set_A_periph(AT91_PIN_PA4, 0); /* RTS2 */ | ||
842 | if (pins & ATMEL_UART_CTS) | ||
843 | at91_set_A_periph(AT91_PIN_PA5, 0); /* CTS2 */ | ||
714 | } | 844 | } |
715 | 845 | ||
716 | static struct resource uart3_resources[] = { | 846 | static struct resource uart3_resources[] = { |
@@ -731,21 +861,29 @@ static struct atmel_uart_data uart3_data = { | |||
731 | .use_dma_rx = 1, | 861 | .use_dma_rx = 1, |
732 | }; | 862 | }; |
733 | 863 | ||
864 | static u64 uart3_dmamask = DMA_BIT_MASK(32); | ||
865 | |||
734 | static struct platform_device at91sam9260_uart3_device = { | 866 | static struct platform_device at91sam9260_uart3_device = { |
735 | .name = "atmel_usart", | 867 | .name = "atmel_usart", |
736 | .id = 4, | 868 | .id = 4, |
737 | .dev = { | 869 | .dev = { |
738 | .platform_data = &uart3_data, | 870 | .dma_mask = &uart3_dmamask, |
739 | .coherent_dma_mask = 0xffffffff, | 871 | .coherent_dma_mask = DMA_BIT_MASK(32), |
872 | .platform_data = &uart3_data, | ||
740 | }, | 873 | }, |
741 | .resource = uart3_resources, | 874 | .resource = uart3_resources, |
742 | .num_resources = ARRAY_SIZE(uart3_resources), | 875 | .num_resources = ARRAY_SIZE(uart3_resources), |
743 | }; | 876 | }; |
744 | 877 | ||
745 | static inline void configure_usart3_pins(void) | 878 | static inline void configure_usart3_pins(unsigned pins) |
746 | { | 879 | { |
747 | at91_set_A_periph(AT91_PIN_PB10, 1); /* TXD3 */ | 880 | at91_set_A_periph(AT91_PIN_PB10, 1); /* TXD3 */ |
748 | at91_set_A_periph(AT91_PIN_PB11, 0); /* RXD3 */ | 881 | at91_set_A_periph(AT91_PIN_PB11, 0); /* RXD3 */ |
882 | |||
883 | if (pins & ATMEL_UART_RTS) | ||
884 | at91_set_B_periph(AT91_PIN_PC8, 0); /* RTS3 */ | ||
885 | if (pins & ATMEL_UART_CTS) | ||
886 | at91_set_B_periph(AT91_PIN_PC10, 0); /* CTS3 */ | ||
749 | } | 887 | } |
750 | 888 | ||
751 | static struct resource uart4_resources[] = { | 889 | static struct resource uart4_resources[] = { |
@@ -766,12 +904,15 @@ static struct atmel_uart_data uart4_data = { | |||
766 | .use_dma_rx = 1, | 904 | .use_dma_rx = 1, |
767 | }; | 905 | }; |
768 | 906 | ||
907 | static u64 uart4_dmamask = DMA_BIT_MASK(32); | ||
908 | |||
769 | static struct platform_device at91sam9260_uart4_device = { | 909 | static struct platform_device at91sam9260_uart4_device = { |
770 | .name = "atmel_usart", | 910 | .name = "atmel_usart", |
771 | .id = 5, | 911 | .id = 5, |
772 | .dev = { | 912 | .dev = { |
773 | .platform_data = &uart4_data, | 913 | .dma_mask = &uart4_dmamask, |
774 | .coherent_dma_mask = 0xffffffff, | 914 | .coherent_dma_mask = DMA_BIT_MASK(32), |
915 | .platform_data = &uart4_data, | ||
775 | }, | 916 | }, |
776 | .resource = uart4_resources, | 917 | .resource = uart4_resources, |
777 | .num_resources = ARRAY_SIZE(uart4_resources), | 918 | .num_resources = ARRAY_SIZE(uart4_resources), |
@@ -801,12 +942,15 @@ static struct atmel_uart_data uart5_data = { | |||
801 | .use_dma_rx = 1, | 942 | .use_dma_rx = 1, |
802 | }; | 943 | }; |
803 | 944 | ||
945 | static u64 uart5_dmamask = DMA_BIT_MASK(32); | ||
946 | |||
804 | static struct platform_device at91sam9260_uart5_device = { | 947 | static struct platform_device at91sam9260_uart5_device = { |
805 | .name = "atmel_usart", | 948 | .name = "atmel_usart", |
806 | .id = 6, | 949 | .id = 6, |
807 | .dev = { | 950 | .dev = { |
808 | .platform_data = &uart5_data, | 951 | .dma_mask = &uart5_dmamask, |
809 | .coherent_dma_mask = 0xffffffff, | 952 | .coherent_dma_mask = DMA_BIT_MASK(32), |
953 | .platform_data = &uart5_data, | ||
810 | }, | 954 | }, |
811 | .resource = uart5_resources, | 955 | .resource = uart5_resources, |
812 | .num_resources = ARRAY_SIZE(uart5_resources), | 956 | .num_resources = ARRAY_SIZE(uart5_resources), |
@@ -818,10 +962,10 @@ static inline void configure_usart5_pins(void) | |||
818 | at91_set_A_periph(AT91_PIN_PB13, 0); /* RXD5 */ | 962 | at91_set_A_periph(AT91_PIN_PB13, 0); /* RXD5 */ |
819 | } | 963 | } |
820 | 964 | ||
821 | struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ | 965 | static struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ |
822 | struct platform_device *atmel_default_console_device; /* the serial console device */ | 966 | struct platform_device *atmel_default_console_device; /* the serial console device */ |
823 | 967 | ||
824 | void __init at91_init_serial(struct at91_uart_config *config) | 968 | void __init __deprecated at91_init_serial(struct at91_uart_config *config) |
825 | { | 969 | { |
826 | int i; | 970 | int i; |
827 | 971 | ||
@@ -829,22 +973,22 @@ void __init at91_init_serial(struct at91_uart_config *config) | |||
829 | for (i = 0; i < config->nr_tty; i++) { | 973 | for (i = 0; i < config->nr_tty; i++) { |
830 | switch (config->tty_map[i]) { | 974 | switch (config->tty_map[i]) { |
831 | case 0: | 975 | case 0: |
832 | configure_usart0_pins(); | 976 | configure_usart0_pins(ATMEL_UART_CTS | ATMEL_UART_RTS | ATMEL_UART_DSR | ATMEL_UART_DTR | ATMEL_UART_DCD | ATMEL_UART_RI); |
833 | at91_uarts[i] = &at91sam9260_uart0_device; | 977 | at91_uarts[i] = &at91sam9260_uart0_device; |
834 | at91_clock_associate("usart0_clk", &at91sam9260_uart0_device.dev, "usart"); | 978 | at91_clock_associate("usart0_clk", &at91sam9260_uart0_device.dev, "usart"); |
835 | break; | 979 | break; |
836 | case 1: | 980 | case 1: |
837 | configure_usart1_pins(); | 981 | configure_usart1_pins(ATMEL_UART_CTS | ATMEL_UART_RTS); |
838 | at91_uarts[i] = &at91sam9260_uart1_device; | 982 | at91_uarts[i] = &at91sam9260_uart1_device; |
839 | at91_clock_associate("usart1_clk", &at91sam9260_uart1_device.dev, "usart"); | 983 | at91_clock_associate("usart1_clk", &at91sam9260_uart1_device.dev, "usart"); |
840 | break; | 984 | break; |
841 | case 2: | 985 | case 2: |
842 | configure_usart2_pins(); | 986 | configure_usart2_pins(0); |
843 | at91_uarts[i] = &at91sam9260_uart2_device; | 987 | at91_uarts[i] = &at91sam9260_uart2_device; |
844 | at91_clock_associate("usart2_clk", &at91sam9260_uart2_device.dev, "usart"); | 988 | at91_clock_associate("usart2_clk", &at91sam9260_uart2_device.dev, "usart"); |
845 | break; | 989 | break; |
846 | case 3: | 990 | case 3: |
847 | configure_usart3_pins(); | 991 | configure_usart3_pins(0); |
848 | at91_uarts[i] = &at91sam9260_uart3_device; | 992 | at91_uarts[i] = &at91sam9260_uart3_device; |
849 | at91_clock_associate("usart3_clk", &at91sam9260_uart3_device.dev, "usart"); | 993 | at91_clock_associate("usart3_clk", &at91sam9260_uart3_device.dev, "usart"); |
850 | break; | 994 | break; |
@@ -876,6 +1020,63 @@ void __init at91_init_serial(struct at91_uart_config *config) | |||
876 | printk(KERN_INFO "AT91: No default serial console defined.\n"); | 1020 | printk(KERN_INFO "AT91: No default serial console defined.\n"); |
877 | } | 1021 | } |
878 | 1022 | ||
1023 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) | ||
1024 | { | ||
1025 | struct platform_device *pdev; | ||
1026 | |||
1027 | switch (id) { | ||
1028 | case 0: /* DBGU */ | ||
1029 | pdev = &at91sam9260_dbgu_device; | ||
1030 | configure_dbgu_pins(); | ||
1031 | at91_clock_associate("mck", &pdev->dev, "usart"); | ||
1032 | break; | ||
1033 | case AT91SAM9260_ID_US0: | ||
1034 | pdev = &at91sam9260_uart0_device; | ||
1035 | configure_usart0_pins(pins); | ||
1036 | at91_clock_associate("usart0_clk", &pdev->dev, "usart"); | ||
1037 | break; | ||
1038 | case AT91SAM9260_ID_US1: | ||
1039 | pdev = &at91sam9260_uart1_device; | ||
1040 | configure_usart1_pins(pins); | ||
1041 | at91_clock_associate("usart1_clk", &pdev->dev, "usart"); | ||
1042 | break; | ||
1043 | case AT91SAM9260_ID_US2: | ||
1044 | pdev = &at91sam9260_uart2_device; | ||
1045 | configure_usart2_pins(pins); | ||
1046 | at91_clock_associate("usart2_clk", &pdev->dev, "usart"); | ||
1047 | break; | ||
1048 | case AT91SAM9260_ID_US3: | ||
1049 | pdev = &at91sam9260_uart3_device; | ||
1050 | configure_usart3_pins(pins); | ||
1051 | at91_clock_associate("usart3_clk", &pdev->dev, "usart"); | ||
1052 | break; | ||
1053 | case AT91SAM9260_ID_US4: | ||
1054 | pdev = &at91sam9260_uart4_device; | ||
1055 | configure_usart4_pins(); | ||
1056 | at91_clock_associate("usart4_clk", &pdev->dev, "usart"); | ||
1057 | break; | ||
1058 | case AT91SAM9260_ID_US5: | ||
1059 | pdev = &at91sam9260_uart5_device; | ||
1060 | configure_usart5_pins(); | ||
1061 | at91_clock_associate("usart5_clk", &pdev->dev, "usart"); | ||
1062 | break; | ||
1063 | default: | ||
1064 | return; | ||
1065 | } | ||
1066 | pdev->id = portnr; /* update to mapped ID */ | ||
1067 | |||
1068 | if (portnr < ATMEL_MAX_UART) | ||
1069 | at91_uarts[portnr] = pdev; | ||
1070 | } | ||
1071 | |||
1072 | void __init at91_set_serial_console(unsigned portnr) | ||
1073 | { | ||
1074 | if (portnr < ATMEL_MAX_UART) | ||
1075 | atmel_default_console_device = at91_uarts[portnr]; | ||
1076 | if (!atmel_default_console_device) | ||
1077 | printk(KERN_INFO "AT91: No default serial console defined.\n"); | ||
1078 | } | ||
1079 | |||
879 | void __init at91_add_device_serial(void) | 1080 | void __init at91_add_device_serial(void) |
880 | { | 1081 | { |
881 | int i; | 1082 | int i; |
@@ -886,7 +1087,9 @@ void __init at91_add_device_serial(void) | |||
886 | } | 1087 | } |
887 | } | 1088 | } |
888 | #else | 1089 | #else |
889 | void __init at91_init_serial(struct at91_uart_config *config) {} | 1090 | void __init __deprecated at91_init_serial(struct at91_uart_config *config) {} |
1091 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} | ||
1092 | void __init at91_set_serial_console(unsigned portnr) {} | ||
890 | void __init at91_add_device_serial(void) {} | 1093 | void __init at91_add_device_serial(void) {} |
891 | #endif | 1094 | #endif |
892 | 1095 | ||
@@ -898,6 +1101,8 @@ void __init at91_add_device_serial(void) {} | |||
898 | */ | 1101 | */ |
899 | static int __init at91_add_standard_devices(void) | 1102 | static int __init at91_add_standard_devices(void) |
900 | { | 1103 | { |
1104 | at91_add_device_rtt(); | ||
1105 | at91_add_device_watchdog(); | ||
901 | return 0; | 1106 | return 0; |
902 | } | 1107 | } |
903 | 1108 | ||
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index dfe8c39c9fb9..90b87e1877d9 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c | |||
@@ -279,25 +279,25 @@ void __init at91sam9261_initialize(unsigned long main_clock) | |||
279 | static unsigned int at91sam9261_default_irq_priority[NR_AIC_IRQS] __initdata = { | 279 | static unsigned int at91sam9261_default_irq_priority[NR_AIC_IRQS] __initdata = { |
280 | 7, /* Advanced Interrupt Controller */ | 280 | 7, /* Advanced Interrupt Controller */ |
281 | 7, /* System Peripherals */ | 281 | 7, /* System Peripherals */ |
282 | 0, /* Parallel IO Controller A */ | 282 | 1, /* Parallel IO Controller A */ |
283 | 0, /* Parallel IO Controller B */ | 283 | 1, /* Parallel IO Controller B */ |
284 | 0, /* Parallel IO Controller C */ | 284 | 1, /* Parallel IO Controller C */ |
285 | 0, | 285 | 0, |
286 | 6, /* USART 0 */ | 286 | 5, /* USART 0 */ |
287 | 6, /* USART 1 */ | 287 | 5, /* USART 1 */ |
288 | 6, /* USART 2 */ | 288 | 5, /* USART 2 */ |
289 | 0, /* Multimedia Card Interface */ | 289 | 0, /* Multimedia Card Interface */ |
290 | 4, /* USB Device Port */ | 290 | 2, /* USB Device Port */ |
291 | 0, /* Two-Wire Interface */ | 291 | 6, /* Two-Wire Interface */ |
292 | 6, /* Serial Peripheral Interface 0 */ | 292 | 5, /* Serial Peripheral Interface 0 */ |
293 | 6, /* Serial Peripheral Interface 1 */ | 293 | 5, /* Serial Peripheral Interface 1 */ |
294 | 5, /* Serial Synchronous Controller 0 */ | 294 | 4, /* Serial Synchronous Controller 0 */ |
295 | 5, /* Serial Synchronous Controller 1 */ | 295 | 4, /* Serial Synchronous Controller 1 */ |
296 | 5, /* Serial Synchronous Controller 2 */ | 296 | 4, /* Serial Synchronous Controller 2 */ |
297 | 0, /* Timer Counter 0 */ | 297 | 0, /* Timer Counter 0 */ |
298 | 0, /* Timer Counter 1 */ | 298 | 0, /* Timer Counter 1 */ |
299 | 0, /* Timer Counter 2 */ | 299 | 0, /* Timer Counter 2 */ |
300 | 3, /* USB Host port */ | 300 | 2, /* USB Host port */ |
301 | 3, /* LCD Controller */ | 301 | 3, /* LCD Controller */ |
302 | 0, | 302 | 0, |
303 | 0, | 303 | 0, |
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index 64979a9023c2..245641263fce 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <asm/mach/arch.h> | 13 | #include <asm/mach/arch.h> |
14 | #include <asm/mach/map.h> | 14 | #include <asm/mach/map.h> |
15 | 15 | ||
16 | #include <linux/dma-mapping.h> | ||
16 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
17 | #include <linux/i2c-gpio.h> | 18 | #include <linux/i2c-gpio.h> |
18 | 19 | ||
@@ -33,7 +34,7 @@ | |||
33 | * -------------------------------------------------------------------- */ | 34 | * -------------------------------------------------------------------- */ |
34 | 35 | ||
35 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | 36 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) |
36 | static u64 ohci_dmamask = 0xffffffffUL; | 37 | static u64 ohci_dmamask = DMA_BIT_MASK(32); |
37 | static struct at91_usbh_data usbh_data; | 38 | static struct at91_usbh_data usbh_data; |
38 | 39 | ||
39 | static struct resource usbh_resources[] = { | 40 | static struct resource usbh_resources[] = { |
@@ -54,7 +55,7 @@ static struct platform_device at91sam9261_usbh_device = { | |||
54 | .id = -1, | 55 | .id = -1, |
55 | .dev = { | 56 | .dev = { |
56 | .dma_mask = &ohci_dmamask, | 57 | .dma_mask = &ohci_dmamask, |
57 | .coherent_dma_mask = 0xffffffff, | 58 | .coherent_dma_mask = DMA_BIT_MASK(32), |
58 | .platform_data = &usbh_data, | 59 | .platform_data = &usbh_data, |
59 | }, | 60 | }, |
60 | .resource = usbh_resources, | 61 | .resource = usbh_resources, |
@@ -106,8 +107,6 @@ static struct platform_device at91sam9261_udc_device = { | |||
106 | 107 | ||
107 | void __init at91_add_device_udc(struct at91_udc_data *data) | 108 | void __init at91_add_device_udc(struct at91_udc_data *data) |
108 | { | 109 | { |
109 | unsigned long x; | ||
110 | |||
111 | if (!data) | 110 | if (!data) |
112 | return; | 111 | return; |
113 | 112 | ||
@@ -116,9 +115,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data) | |||
116 | at91_set_deglitch(data->vbus_pin, 1); | 115 | at91_set_deglitch(data->vbus_pin, 1); |
117 | } | 116 | } |
118 | 117 | ||
119 | /* Pullup pin is handled internally */ | 118 | /* Pullup pin is handled internally by USB device peripheral */ |
120 | x = at91_sys_read(AT91_MATRIX_USBPUCR); | ||
121 | at91_sys_write(AT91_MATRIX_USBPUCR, x | AT91_MATRIX_USBPUCR_PUON); | ||
122 | 119 | ||
123 | udc_data = *data; | 120 | udc_data = *data; |
124 | platform_device_register(&at91sam9261_udc_device); | 121 | platform_device_register(&at91sam9261_udc_device); |
@@ -132,7 +129,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data) {} | |||
132 | * -------------------------------------------------------------------- */ | 129 | * -------------------------------------------------------------------- */ |
133 | 130 | ||
134 | #if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) | 131 | #if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) |
135 | static u64 mmc_dmamask = 0xffffffffUL; | 132 | static u64 mmc_dmamask = DMA_BIT_MASK(32); |
136 | static struct at91_mmc_data mmc_data; | 133 | static struct at91_mmc_data mmc_data; |
137 | 134 | ||
138 | static struct resource mmc_resources[] = { | 135 | static struct resource mmc_resources[] = { |
@@ -153,7 +150,7 @@ static struct platform_device at91sam9261_mmc_device = { | |||
153 | .id = -1, | 150 | .id = -1, |
154 | .dev = { | 151 | .dev = { |
155 | .dma_mask = &mmc_dmamask, | 152 | .dma_mask = &mmc_dmamask, |
156 | .coherent_dma_mask = 0xffffffff, | 153 | .coherent_dma_mask = DMA_BIT_MASK(32), |
157 | .platform_data = &mmc_data, | 154 | .platform_data = &mmc_data, |
158 | }, | 155 | }, |
159 | .resource = mmc_resources, | 156 | .resource = mmc_resources, |
@@ -232,7 +229,7 @@ void __init at91_add_device_nand(struct at91_nand_data *data) | |||
232 | return; | 229 | return; |
233 | 230 | ||
234 | csa = at91_sys_read(AT91_MATRIX_EBICSA); | 231 | csa = at91_sys_read(AT91_MATRIX_EBICSA); |
235 | at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC); | 232 | at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); |
236 | 233 | ||
237 | /* set the bus interface characteristics */ | 234 | /* set the bus interface characteristics */ |
238 | at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0) | 235 | at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0) |
@@ -354,7 +351,7 @@ void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) | |||
354 | * -------------------------------------------------------------------- */ | 351 | * -------------------------------------------------------------------- */ |
355 | 352 | ||
356 | #if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) | 353 | #if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) |
357 | static u64 spi_dmamask = 0xffffffffUL; | 354 | static u64 spi_dmamask = DMA_BIT_MASK(32); |
358 | 355 | ||
359 | static struct resource spi0_resources[] = { | 356 | static struct resource spi0_resources[] = { |
360 | [0] = { | 357 | [0] = { |
@@ -374,7 +371,7 @@ static struct platform_device at91sam9261_spi0_device = { | |||
374 | .id = 0, | 371 | .id = 0, |
375 | .dev = { | 372 | .dev = { |
376 | .dma_mask = &spi_dmamask, | 373 | .dma_mask = &spi_dmamask, |
377 | .coherent_dma_mask = 0xffffffff, | 374 | .coherent_dma_mask = DMA_BIT_MASK(32), |
378 | }, | 375 | }, |
379 | .resource = spi0_resources, | 376 | .resource = spi0_resources, |
380 | .num_resources = ARRAY_SIZE(spi0_resources), | 377 | .num_resources = ARRAY_SIZE(spi0_resources), |
@@ -400,7 +397,7 @@ static struct platform_device at91sam9261_spi1_device = { | |||
400 | .id = 1, | 397 | .id = 1, |
401 | .dev = { | 398 | .dev = { |
402 | .dma_mask = &spi_dmamask, | 399 | .dma_mask = &spi_dmamask, |
403 | .coherent_dma_mask = 0xffffffff, | 400 | .coherent_dma_mask = DMA_BIT_MASK(32), |
404 | }, | 401 | }, |
405 | .resource = spi1_resources, | 402 | .resource = spi1_resources, |
406 | .num_resources = ARRAY_SIZE(spi1_resources), | 403 | .num_resources = ARRAY_SIZE(spi1_resources), |
@@ -466,7 +463,7 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) | |||
466 | * -------------------------------------------------------------------- */ | 463 | * -------------------------------------------------------------------- */ |
467 | 464 | ||
468 | #if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) | 465 | #if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) |
469 | static u64 lcdc_dmamask = 0xffffffffUL; | 466 | static u64 lcdc_dmamask = DMA_BIT_MASK(32); |
470 | static struct atmel_lcdfb_info lcdc_data; | 467 | static struct atmel_lcdfb_info lcdc_data; |
471 | 468 | ||
472 | static struct resource lcdc_resources[] = { | 469 | static struct resource lcdc_resources[] = { |
@@ -494,7 +491,7 @@ static struct platform_device at91_lcdc_device = { | |||
494 | .id = 0, | 491 | .id = 0, |
495 | .dev = { | 492 | .dev = { |
496 | .dma_mask = &lcdc_dmamask, | 493 | .dma_mask = &lcdc_dmamask, |
497 | .coherent_dma_mask = 0xffffffff, | 494 | .coherent_dma_mask = DMA_BIT_MASK(32), |
498 | .platform_data = &lcdc_data, | 495 | .platform_data = &lcdc_data, |
499 | }, | 496 | }, |
500 | .resource = lcdc_resources, | 497 | .resource = lcdc_resources, |
@@ -507,6 +504,17 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) | |||
507 | return; | 504 | return; |
508 | } | 505 | } |
509 | 506 | ||
507 | #if defined(CONFIG_FB_ATMEL_STN) | ||
508 | at91_set_A_periph(AT91_PIN_PB0, 0); /* LCDVSYNC */ | ||
509 | at91_set_A_periph(AT91_PIN_PB1, 0); /* LCDHSYNC */ | ||
510 | at91_set_A_periph(AT91_PIN_PB2, 0); /* LCDDOTCK */ | ||
511 | at91_set_A_periph(AT91_PIN_PB3, 0); /* LCDDEN */ | ||
512 | at91_set_A_periph(AT91_PIN_PB4, 0); /* LCDCC */ | ||
513 | at91_set_A_periph(AT91_PIN_PB5, 0); /* LCDD0 */ | ||
514 | at91_set_A_periph(AT91_PIN_PB6, 0); /* LCDD1 */ | ||
515 | at91_set_A_periph(AT91_PIN_PB7, 0); /* LCDD2 */ | ||
516 | at91_set_A_periph(AT91_PIN_PB8, 0); /* LCDD3 */ | ||
517 | #else | ||
510 | at91_set_A_periph(AT91_PIN_PB1, 0); /* LCDHSYNC */ | 518 | at91_set_A_periph(AT91_PIN_PB1, 0); /* LCDHSYNC */ |
511 | at91_set_A_periph(AT91_PIN_PB2, 0); /* LCDDOTCK */ | 519 | at91_set_A_periph(AT91_PIN_PB2, 0); /* LCDDOTCK */ |
512 | at91_set_A_periph(AT91_PIN_PB3, 0); /* LCDDEN */ | 520 | at91_set_A_periph(AT91_PIN_PB3, 0); /* LCDDEN */ |
@@ -529,6 +537,7 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) | |||
529 | at91_set_B_periph(AT91_PIN_PB26, 0); /* LCDD21 */ | 537 | at91_set_B_periph(AT91_PIN_PB26, 0); /* LCDD21 */ |
530 | at91_set_B_periph(AT91_PIN_PB27, 0); /* LCDD22 */ | 538 | at91_set_B_periph(AT91_PIN_PB27, 0); /* LCDD22 */ |
531 | at91_set_B_periph(AT91_PIN_PB28, 0); /* LCDD23 */ | 539 | at91_set_B_periph(AT91_PIN_PB28, 0); /* LCDD23 */ |
540 | #endif | ||
532 | 541 | ||
533 | lcdc_data = *data; | 542 | lcdc_data = *data; |
534 | platform_device_register(&at91_lcdc_device); | 543 | platform_device_register(&at91_lcdc_device); |
@@ -539,24 +548,220 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {} | |||
539 | 548 | ||
540 | 549 | ||
541 | /* -------------------------------------------------------------------- | 550 | /* -------------------------------------------------------------------- |
542 | * LEDs | 551 | * RTT |
552 | * -------------------------------------------------------------------- */ | ||
553 | |||
554 | static struct resource rtt_resources[] = { | ||
555 | { | ||
556 | .start = AT91_BASE_SYS + AT91_RTT, | ||
557 | .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1, | ||
558 | .flags = IORESOURCE_MEM, | ||
559 | } | ||
560 | }; | ||
561 | |||
562 | static struct platform_device at91sam9261_rtt_device = { | ||
563 | .name = "at91_rtt", | ||
564 | .id = -1, | ||
565 | .resource = rtt_resources, | ||
566 | .num_resources = ARRAY_SIZE(rtt_resources), | ||
567 | }; | ||
568 | |||
569 | static void __init at91_add_device_rtt(void) | ||
570 | { | ||
571 | platform_device_register(&at91sam9261_rtt_device); | ||
572 | } | ||
573 | |||
574 | |||
575 | /* -------------------------------------------------------------------- | ||
576 | * Watchdog | ||
577 | * -------------------------------------------------------------------- */ | ||
578 | |||
579 | #if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE) | ||
580 | static struct platform_device at91sam9261_wdt_device = { | ||
581 | .name = "at91_wdt", | ||
582 | .id = -1, | ||
583 | .num_resources = 0, | ||
584 | }; | ||
585 | |||
586 | static void __init at91_add_device_watchdog(void) | ||
587 | { | ||
588 | platform_device_register(&at91sam9261_wdt_device); | ||
589 | } | ||
590 | #else | ||
591 | static void __init at91_add_device_watchdog(void) {} | ||
592 | #endif | ||
593 | |||
594 | |||
595 | /* -------------------------------------------------------------------- | ||
596 | * SSC -- Synchronous Serial Controller | ||
543 | * -------------------------------------------------------------------- */ | 597 | * -------------------------------------------------------------------- */ |
544 | 598 | ||
545 | #if defined(CONFIG_LEDS) | 599 | #if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE) |
546 | u8 at91_leds_cpu; | 600 | static u64 ssc0_dmamask = DMA_BIT_MASK(32); |
547 | u8 at91_leds_timer; | 601 | |
602 | static struct resource ssc0_resources[] = { | ||
603 | [0] = { | ||
604 | .start = AT91SAM9261_BASE_SSC0, | ||
605 | .end = AT91SAM9261_BASE_SSC0 + SZ_16K - 1, | ||
606 | .flags = IORESOURCE_MEM, | ||
607 | }, | ||
608 | [1] = { | ||
609 | .start = AT91SAM9261_ID_SSC0, | ||
610 | .end = AT91SAM9261_ID_SSC0, | ||
611 | .flags = IORESOURCE_IRQ, | ||
612 | }, | ||
613 | }; | ||
614 | |||
615 | static struct platform_device at91sam9261_ssc0_device = { | ||
616 | .name = "ssc", | ||
617 | .id = 0, | ||
618 | .dev = { | ||
619 | .dma_mask = &ssc0_dmamask, | ||
620 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
621 | }, | ||
622 | .resource = ssc0_resources, | ||
623 | .num_resources = ARRAY_SIZE(ssc0_resources), | ||
624 | }; | ||
625 | |||
626 | static inline void configure_ssc0_pins(unsigned pins) | ||
627 | { | ||
628 | if (pins & ATMEL_SSC_TF) | ||
629 | at91_set_A_periph(AT91_PIN_PB21, 1); | ||
630 | if (pins & ATMEL_SSC_TK) | ||
631 | at91_set_A_periph(AT91_PIN_PB22, 1); | ||
632 | if (pins & ATMEL_SSC_TD) | ||
633 | at91_set_A_periph(AT91_PIN_PB23, 1); | ||
634 | if (pins & ATMEL_SSC_RD) | ||
635 | at91_set_A_periph(AT91_PIN_PB24, 1); | ||
636 | if (pins & ATMEL_SSC_RK) | ||
637 | at91_set_A_periph(AT91_PIN_PB25, 1); | ||
638 | if (pins & ATMEL_SSC_RF) | ||
639 | at91_set_A_periph(AT91_PIN_PB26, 1); | ||
640 | } | ||
641 | |||
642 | static u64 ssc1_dmamask = DMA_BIT_MASK(32); | ||
643 | |||
644 | static struct resource ssc1_resources[] = { | ||
645 | [0] = { | ||
646 | .start = AT91SAM9261_BASE_SSC1, | ||
647 | .end = AT91SAM9261_BASE_SSC1 + SZ_16K - 1, | ||
648 | .flags = IORESOURCE_MEM, | ||
649 | }, | ||
650 | [1] = { | ||
651 | .start = AT91SAM9261_ID_SSC1, | ||
652 | .end = AT91SAM9261_ID_SSC1, | ||
653 | .flags = IORESOURCE_IRQ, | ||
654 | }, | ||
655 | }; | ||
656 | |||
657 | static struct platform_device at91sam9261_ssc1_device = { | ||
658 | .name = "ssc", | ||
659 | .id = 1, | ||
660 | .dev = { | ||
661 | .dma_mask = &ssc1_dmamask, | ||
662 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
663 | }, | ||
664 | .resource = ssc1_resources, | ||
665 | .num_resources = ARRAY_SIZE(ssc1_resources), | ||
666 | }; | ||
667 | |||
668 | static inline void configure_ssc1_pins(unsigned pins) | ||
669 | { | ||
670 | if (pins & ATMEL_SSC_TF) | ||
671 | at91_set_B_periph(AT91_PIN_PA17, 1); | ||
672 | if (pins & ATMEL_SSC_TK) | ||
673 | at91_set_B_periph(AT91_PIN_PA18, 1); | ||
674 | if (pins & ATMEL_SSC_TD) | ||
675 | at91_set_B_periph(AT91_PIN_PA19, 1); | ||
676 | if (pins & ATMEL_SSC_RD) | ||
677 | at91_set_B_periph(AT91_PIN_PA20, 1); | ||
678 | if (pins & ATMEL_SSC_RK) | ||
679 | at91_set_B_periph(AT91_PIN_PA21, 1); | ||
680 | if (pins & ATMEL_SSC_RF) | ||
681 | at91_set_B_periph(AT91_PIN_PA22, 1); | ||
682 | } | ||
683 | |||
684 | static u64 ssc2_dmamask = DMA_BIT_MASK(32); | ||
685 | |||
686 | static struct resource ssc2_resources[] = { | ||
687 | [0] = { | ||
688 | .start = AT91SAM9261_BASE_SSC2, | ||
689 | .end = AT91SAM9261_BASE_SSC2 + SZ_16K - 1, | ||
690 | .flags = IORESOURCE_MEM, | ||
691 | }, | ||
692 | [1] = { | ||
693 | .start = AT91SAM9261_ID_SSC2, | ||
694 | .end = AT91SAM9261_ID_SSC2, | ||
695 | .flags = IORESOURCE_IRQ, | ||
696 | }, | ||
697 | }; | ||
698 | |||
699 | static struct platform_device at91sam9261_ssc2_device = { | ||
700 | .name = "ssc", | ||
701 | .id = 2, | ||
702 | .dev = { | ||
703 | .dma_mask = &ssc2_dmamask, | ||
704 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
705 | }, | ||
706 | .resource = ssc2_resources, | ||
707 | .num_resources = ARRAY_SIZE(ssc2_resources), | ||
708 | }; | ||
709 | |||
710 | static inline void configure_ssc2_pins(unsigned pins) | ||
711 | { | ||
712 | if (pins & ATMEL_SSC_TF) | ||
713 | at91_set_B_periph(AT91_PIN_PC25, 1); | ||
714 | if (pins & ATMEL_SSC_TK) | ||
715 | at91_set_B_periph(AT91_PIN_PC26, 1); | ||
716 | if (pins & ATMEL_SSC_TD) | ||
717 | at91_set_B_periph(AT91_PIN_PC27, 1); | ||
718 | if (pins & ATMEL_SSC_RD) | ||
719 | at91_set_B_periph(AT91_PIN_PC28, 1); | ||
720 | if (pins & ATMEL_SSC_RK) | ||
721 | at91_set_B_periph(AT91_PIN_PC29, 1); | ||
722 | if (pins & ATMEL_SSC_RF) | ||
723 | at91_set_B_periph(AT91_PIN_PC30, 1); | ||
724 | } | ||
548 | 725 | ||
549 | void __init at91_init_leds(u8 cpu_led, u8 timer_led) | 726 | /* |
727 | * SSC controllers are accessed through library code, instead of any | ||
728 | * kind of all-singing/all-dancing driver. For example one could be | ||
729 | * used by a particular I2S audio codec's driver, while another one | ||
730 | * on the same system might be used by a custom data capture driver. | ||
731 | */ | ||
732 | void __init at91_add_device_ssc(unsigned id, unsigned pins) | ||
550 | { | 733 | { |
551 | /* Enable GPIO to access the LEDs */ | 734 | struct platform_device *pdev; |
552 | at91_set_gpio_output(cpu_led, 1); | 735 | |
553 | at91_set_gpio_output(timer_led, 1); | 736 | /* |
737 | * NOTE: caller is responsible for passing information matching | ||
738 | * "pins" to whatever will be using each particular controller. | ||
739 | */ | ||
740 | switch (id) { | ||
741 | case AT91SAM9261_ID_SSC0: | ||
742 | pdev = &at91sam9261_ssc0_device; | ||
743 | configure_ssc0_pins(pins); | ||
744 | at91_clock_associate("ssc0_clk", &pdev->dev, "pclk"); | ||
745 | break; | ||
746 | case AT91SAM9261_ID_SSC1: | ||
747 | pdev = &at91sam9261_ssc1_device; | ||
748 | configure_ssc1_pins(pins); | ||
749 | at91_clock_associate("ssc1_clk", &pdev->dev, "pclk"); | ||
750 | break; | ||
751 | case AT91SAM9261_ID_SSC2: | ||
752 | pdev = &at91sam9261_ssc2_device; | ||
753 | configure_ssc2_pins(pins); | ||
754 | at91_clock_associate("ssc2_clk", &pdev->dev, "pclk"); | ||
755 | break; | ||
756 | default: | ||
757 | return; | ||
758 | } | ||
554 | 759 | ||
555 | at91_leds_cpu = cpu_led; | 760 | platform_device_register(pdev); |
556 | at91_leds_timer = timer_led; | ||
557 | } | 761 | } |
762 | |||
558 | #else | 763 | #else |
559 | void __init at91_init_leds(u8 cpu_led, u8 timer_led) {} | 764 | void __init at91_add_device_ssc(unsigned id, unsigned pins) {} |
560 | #endif | 765 | #endif |
561 | 766 | ||
562 | 767 | ||
@@ -584,12 +789,15 @@ static struct atmel_uart_data dbgu_data = { | |||
584 | .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), | 789 | .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), |
585 | }; | 790 | }; |
586 | 791 | ||
792 | static u64 dbgu_dmamask = DMA_BIT_MASK(32); | ||
793 | |||
587 | static struct platform_device at91sam9261_dbgu_device = { | 794 | static struct platform_device at91sam9261_dbgu_device = { |
588 | .name = "atmel_usart", | 795 | .name = "atmel_usart", |
589 | .id = 0, | 796 | .id = 0, |
590 | .dev = { | 797 | .dev = { |
591 | .platform_data = &dbgu_data, | 798 | .dma_mask = &dbgu_dmamask, |
592 | .coherent_dma_mask = 0xffffffff, | 799 | .coherent_dma_mask = DMA_BIT_MASK(32), |
800 | .platform_data = &dbgu_data, | ||
593 | }, | 801 | }, |
594 | .resource = dbgu_resources, | 802 | .resource = dbgu_resources, |
595 | .num_resources = ARRAY_SIZE(dbgu_resources), | 803 | .num_resources = ARRAY_SIZE(dbgu_resources), |
@@ -619,23 +827,29 @@ static struct atmel_uart_data uart0_data = { | |||
619 | .use_dma_rx = 1, | 827 | .use_dma_rx = 1, |
620 | }; | 828 | }; |
621 | 829 | ||
830 | static u64 uart0_dmamask = DMA_BIT_MASK(32); | ||
831 | |||
622 | static struct platform_device at91sam9261_uart0_device = { | 832 | static struct platform_device at91sam9261_uart0_device = { |
623 | .name = "atmel_usart", | 833 | .name = "atmel_usart", |
624 | .id = 1, | 834 | .id = 1, |
625 | .dev = { | 835 | .dev = { |
626 | .platform_data = &uart0_data, | 836 | .dma_mask = &uart0_dmamask, |
627 | .coherent_dma_mask = 0xffffffff, | 837 | .coherent_dma_mask = DMA_BIT_MASK(32), |
838 | .platform_data = &uart0_data, | ||
628 | }, | 839 | }, |
629 | .resource = uart0_resources, | 840 | .resource = uart0_resources, |
630 | .num_resources = ARRAY_SIZE(uart0_resources), | 841 | .num_resources = ARRAY_SIZE(uart0_resources), |
631 | }; | 842 | }; |
632 | 843 | ||
633 | static inline void configure_usart0_pins(void) | 844 | static inline void configure_usart0_pins(unsigned pins) |
634 | { | 845 | { |
635 | at91_set_A_periph(AT91_PIN_PC8, 1); /* TXD0 */ | 846 | at91_set_A_periph(AT91_PIN_PC8, 1); /* TXD0 */ |
636 | at91_set_A_periph(AT91_PIN_PC9, 0); /* RXD0 */ | 847 | at91_set_A_periph(AT91_PIN_PC9, 0); /* RXD0 */ |
637 | at91_set_A_periph(AT91_PIN_PC10, 0); /* RTS0 */ | 848 | |
638 | at91_set_A_periph(AT91_PIN_PC11, 0); /* CTS0 */ | 849 | if (pins & ATMEL_UART_RTS) |
850 | at91_set_A_periph(AT91_PIN_PC10, 0); /* RTS0 */ | ||
851 | if (pins & ATMEL_UART_CTS) | ||
852 | at91_set_A_periph(AT91_PIN_PC11, 0); /* CTS0 */ | ||
639 | } | 853 | } |
640 | 854 | ||
641 | static struct resource uart1_resources[] = { | 855 | static struct resource uart1_resources[] = { |
@@ -656,21 +870,29 @@ static struct atmel_uart_data uart1_data = { | |||
656 | .use_dma_rx = 1, | 870 | .use_dma_rx = 1, |
657 | }; | 871 | }; |
658 | 872 | ||
873 | static u64 uart1_dmamask = DMA_BIT_MASK(32); | ||
874 | |||
659 | static struct platform_device at91sam9261_uart1_device = { | 875 | static struct platform_device at91sam9261_uart1_device = { |
660 | .name = "atmel_usart", | 876 | .name = "atmel_usart", |
661 | .id = 2, | 877 | .id = 2, |
662 | .dev = { | 878 | .dev = { |
663 | .platform_data = &uart1_data, | 879 | .dma_mask = &uart1_dmamask, |
664 | .coherent_dma_mask = 0xffffffff, | 880 | .coherent_dma_mask = DMA_BIT_MASK(32), |
881 | .platform_data = &uart1_data, | ||
665 | }, | 882 | }, |
666 | .resource = uart1_resources, | 883 | .resource = uart1_resources, |
667 | .num_resources = ARRAY_SIZE(uart1_resources), | 884 | .num_resources = ARRAY_SIZE(uart1_resources), |
668 | }; | 885 | }; |
669 | 886 | ||
670 | static inline void configure_usart1_pins(void) | 887 | static inline void configure_usart1_pins(unsigned pins) |
671 | { | 888 | { |
672 | at91_set_A_periph(AT91_PIN_PC12, 1); /* TXD1 */ | 889 | at91_set_A_periph(AT91_PIN_PC12, 1); /* TXD1 */ |
673 | at91_set_A_periph(AT91_PIN_PC13, 0); /* RXD1 */ | 890 | at91_set_A_periph(AT91_PIN_PC13, 0); /* RXD1 */ |
891 | |||
892 | if (pins & ATMEL_UART_RTS) | ||
893 | at91_set_B_periph(AT91_PIN_PA12, 0); /* RTS1 */ | ||
894 | if (pins & ATMEL_UART_CTS) | ||
895 | at91_set_B_periph(AT91_PIN_PA13, 0); /* CTS1 */ | ||
674 | } | 896 | } |
675 | 897 | ||
676 | static struct resource uart2_resources[] = { | 898 | static struct resource uart2_resources[] = { |
@@ -691,27 +913,35 @@ static struct atmel_uart_data uart2_data = { | |||
691 | .use_dma_rx = 1, | 913 | .use_dma_rx = 1, |
692 | }; | 914 | }; |
693 | 915 | ||
916 | static u64 uart2_dmamask = DMA_BIT_MASK(32); | ||
917 | |||
694 | static struct platform_device at91sam9261_uart2_device = { | 918 | static struct platform_device at91sam9261_uart2_device = { |
695 | .name = "atmel_usart", | 919 | .name = "atmel_usart", |
696 | .id = 3, | 920 | .id = 3, |
697 | .dev = { | 921 | .dev = { |
698 | .platform_data = &uart2_data, | 922 | .dma_mask = &uart2_dmamask, |
699 | .coherent_dma_mask = 0xffffffff, | 923 | .coherent_dma_mask = DMA_BIT_MASK(32), |
924 | .platform_data = &uart2_data, | ||
700 | }, | 925 | }, |
701 | .resource = uart2_resources, | 926 | .resource = uart2_resources, |
702 | .num_resources = ARRAY_SIZE(uart2_resources), | 927 | .num_resources = ARRAY_SIZE(uart2_resources), |
703 | }; | 928 | }; |
704 | 929 | ||
705 | static inline void configure_usart2_pins(void) | 930 | static inline void configure_usart2_pins(unsigned pins) |
706 | { | 931 | { |
707 | at91_set_A_periph(AT91_PIN_PC15, 0); /* RXD2 */ | 932 | at91_set_A_periph(AT91_PIN_PC15, 0); /* RXD2 */ |
708 | at91_set_A_periph(AT91_PIN_PC14, 1); /* TXD2 */ | 933 | at91_set_A_periph(AT91_PIN_PC14, 1); /* TXD2 */ |
934 | |||
935 | if (pins & ATMEL_UART_RTS) | ||
936 | at91_set_B_periph(AT91_PIN_PA15, 0); /* RTS2*/ | ||
937 | if (pins & ATMEL_UART_CTS) | ||
938 | at91_set_B_periph(AT91_PIN_PA16, 0); /* CTS2 */ | ||
709 | } | 939 | } |
710 | 940 | ||
711 | struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ | 941 | static struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ |
712 | struct platform_device *atmel_default_console_device; /* the serial console device */ | 942 | struct platform_device *atmel_default_console_device; /* the serial console device */ |
713 | 943 | ||
714 | void __init at91_init_serial(struct at91_uart_config *config) | 944 | void __init __deprecated at91_init_serial(struct at91_uart_config *config) |
715 | { | 945 | { |
716 | int i; | 946 | int i; |
717 | 947 | ||
@@ -719,17 +949,17 @@ void __init at91_init_serial(struct at91_uart_config *config) | |||
719 | for (i = 0; i < config->nr_tty; i++) { | 949 | for (i = 0; i < config->nr_tty; i++) { |
720 | switch (config->tty_map[i]) { | 950 | switch (config->tty_map[i]) { |
721 | case 0: | 951 | case 0: |
722 | configure_usart0_pins(); | 952 | configure_usart0_pins(ATMEL_UART_CTS | ATMEL_UART_RTS); |
723 | at91_uarts[i] = &at91sam9261_uart0_device; | 953 | at91_uarts[i] = &at91sam9261_uart0_device; |
724 | at91_clock_associate("usart0_clk", &at91sam9261_uart0_device.dev, "usart"); | 954 | at91_clock_associate("usart0_clk", &at91sam9261_uart0_device.dev, "usart"); |
725 | break; | 955 | break; |
726 | case 1: | 956 | case 1: |
727 | configure_usart1_pins(); | 957 | configure_usart1_pins(0); |
728 | at91_uarts[i] = &at91sam9261_uart1_device; | 958 | at91_uarts[i] = &at91sam9261_uart1_device; |
729 | at91_clock_associate("usart1_clk", &at91sam9261_uart1_device.dev, "usart"); | 959 | at91_clock_associate("usart1_clk", &at91sam9261_uart1_device.dev, "usart"); |
730 | break; | 960 | break; |
731 | case 2: | 961 | case 2: |
732 | configure_usart2_pins(); | 962 | configure_usart2_pins(0); |
733 | at91_uarts[i] = &at91sam9261_uart2_device; | 963 | at91_uarts[i] = &at91sam9261_uart2_device; |
734 | at91_clock_associate("usart2_clk", &at91sam9261_uart2_device.dev, "usart"); | 964 | at91_clock_associate("usart2_clk", &at91sam9261_uart2_device.dev, "usart"); |
735 | break; | 965 | break; |
@@ -751,6 +981,48 @@ void __init at91_init_serial(struct at91_uart_config *config) | |||
751 | printk(KERN_INFO "AT91: No default serial console defined.\n"); | 981 | printk(KERN_INFO "AT91: No default serial console defined.\n"); |
752 | } | 982 | } |
753 | 983 | ||
984 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) | ||
985 | { | ||
986 | struct platform_device *pdev; | ||
987 | |||
988 | switch (id) { | ||
989 | case 0: /* DBGU */ | ||
990 | pdev = &at91sam9261_dbgu_device; | ||
991 | configure_dbgu_pins(); | ||
992 | at91_clock_associate("mck", &pdev->dev, "usart"); | ||
993 | break; | ||
994 | case AT91SAM9261_ID_US0: | ||
995 | pdev = &at91sam9261_uart0_device; | ||
996 | configure_usart0_pins(pins); | ||
997 | at91_clock_associate("usart0_clk", &pdev->dev, "usart"); | ||
998 | break; | ||
999 | case AT91SAM9261_ID_US1: | ||
1000 | pdev = &at91sam9261_uart1_device; | ||
1001 | configure_usart1_pins(pins); | ||
1002 | at91_clock_associate("usart1_clk", &pdev->dev, "usart"); | ||
1003 | break; | ||
1004 | case AT91SAM9261_ID_US2: | ||
1005 | pdev = &at91sam9261_uart2_device; | ||
1006 | configure_usart2_pins(pins); | ||
1007 | at91_clock_associate("usart2_clk", &pdev->dev, "usart"); | ||
1008 | break; | ||
1009 | default: | ||
1010 | return; | ||
1011 | } | ||
1012 | pdev->id = portnr; /* update to mapped ID */ | ||
1013 | |||
1014 | if (portnr < ATMEL_MAX_UART) | ||
1015 | at91_uarts[portnr] = pdev; | ||
1016 | } | ||
1017 | |||
1018 | void __init at91_set_serial_console(unsigned portnr) | ||
1019 | { | ||
1020 | if (portnr < ATMEL_MAX_UART) | ||
1021 | atmel_default_console_device = at91_uarts[portnr]; | ||
1022 | if (!atmel_default_console_device) | ||
1023 | printk(KERN_INFO "AT91: No default serial console defined.\n"); | ||
1024 | } | ||
1025 | |||
754 | void __init at91_add_device_serial(void) | 1026 | void __init at91_add_device_serial(void) |
755 | { | 1027 | { |
756 | int i; | 1028 | int i; |
@@ -761,7 +1033,9 @@ void __init at91_add_device_serial(void) | |||
761 | } | 1033 | } |
762 | } | 1034 | } |
763 | #else | 1035 | #else |
764 | void __init at91_init_serial(struct at91_uart_config *config) {} | 1036 | void __init __deprecated at91_init_serial(struct at91_uart_config *config) {} |
1037 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} | ||
1038 | void __init at91_set_serial_console(unsigned portnr) {} | ||
765 | void __init at91_add_device_serial(void) {} | 1039 | void __init at91_add_device_serial(void) {} |
766 | #endif | 1040 | #endif |
767 | 1041 | ||
@@ -774,6 +1048,8 @@ void __init at91_add_device_serial(void) {} | |||
774 | */ | 1048 | */ |
775 | static int __init at91_add_standard_devices(void) | 1049 | static int __init at91_add_standard_devices(void) |
776 | { | 1050 | { |
1051 | at91_add_device_rtt(); | ||
1052 | at91_add_device_watchdog(); | ||
777 | return 0; | 1053 | return 0; |
778 | } | 1054 | } |
779 | 1055 | ||
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index 00e27b177857..a53ba0f74351 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c | |||
@@ -304,34 +304,34 @@ void __init at91sam9263_initialize(unsigned long main_clock) | |||
304 | static unsigned int at91sam9263_default_irq_priority[NR_AIC_IRQS] __initdata = { | 304 | static unsigned int at91sam9263_default_irq_priority[NR_AIC_IRQS] __initdata = { |
305 | 7, /* Advanced Interrupt Controller (FIQ) */ | 305 | 7, /* Advanced Interrupt Controller (FIQ) */ |
306 | 7, /* System Peripherals */ | 306 | 7, /* System Peripherals */ |
307 | 0, /* Parallel IO Controller A */ | 307 | 1, /* Parallel IO Controller A */ |
308 | 0, /* Parallel IO Controller B */ | 308 | 1, /* Parallel IO Controller B */ |
309 | 0, /* Parallel IO Controller C, D and E */ | 309 | 1, /* Parallel IO Controller C, D and E */ |
310 | 0, | 310 | 0, |
311 | 0, | 311 | 0, |
312 | 6, /* USART 0 */ | 312 | 5, /* USART 0 */ |
313 | 6, /* USART 1 */ | 313 | 5, /* USART 1 */ |
314 | 6, /* USART 2 */ | 314 | 5, /* USART 2 */ |
315 | 0, /* Multimedia Card Interface 0 */ | 315 | 0, /* Multimedia Card Interface 0 */ |
316 | 0, /* Multimedia Card Interface 1 */ | 316 | 0, /* Multimedia Card Interface 1 */ |
317 | 4, /* CAN */ | 317 | 3, /* CAN */ |
318 | 0, /* Two-Wire Interface */ | 318 | 6, /* Two-Wire Interface */ |
319 | 6, /* Serial Peripheral Interface 0 */ | 319 | 5, /* Serial Peripheral Interface 0 */ |
320 | 6, /* Serial Peripheral Interface 1 */ | 320 | 5, /* Serial Peripheral Interface 1 */ |
321 | 5, /* Serial Synchronous Controller 0 */ | 321 | 4, /* Serial Synchronous Controller 0 */ |
322 | 5, /* Serial Synchronous Controller 1 */ | 322 | 4, /* Serial Synchronous Controller 1 */ |
323 | 6, /* AC97 Controller */ | 323 | 5, /* AC97 Controller */ |
324 | 0, /* Timer Counter 0, 1 and 2 */ | 324 | 0, /* Timer Counter 0, 1 and 2 */ |
325 | 0, /* Pulse Width Modulation Controller */ | 325 | 0, /* Pulse Width Modulation Controller */ |
326 | 3, /* Ethernet */ | 326 | 3, /* Ethernet */ |
327 | 0, | 327 | 0, |
328 | 0, /* 2D Graphic Engine */ | 328 | 0, /* 2D Graphic Engine */ |
329 | 3, /* USB Device Port */ | 329 | 2, /* USB Device Port */ |
330 | 0, /* Image Sensor Interface */ | 330 | 0, /* Image Sensor Interface */ |
331 | 3, /* LDC Controller */ | 331 | 3, /* LDC Controller */ |
332 | 0, /* DMA Controller */ | 332 | 0, /* DMA Controller */ |
333 | 0, | 333 | 0, |
334 | 3, /* USB Host port */ | 334 | 2, /* USB Host port */ |
335 | 0, /* Advanced Interrupt Controller (IRQ0) */ | 335 | 0, /* Advanced Interrupt Controller (IRQ0) */ |
336 | 0, /* Advanced Interrupt Controller (IRQ1) */ | 336 | 0, /* Advanced Interrupt Controller (IRQ1) */ |
337 | }; | 337 | }; |
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index ac329a98e959..0b12e1adcc8e 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <asm/mach/arch.h> | 12 | #include <asm/mach/arch.h> |
13 | #include <asm/mach/map.h> | 13 | #include <asm/mach/map.h> |
14 | 14 | ||
15 | #include <linux/dma-mapping.h> | ||
15 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
16 | #include <linux/i2c-gpio.h> | 17 | #include <linux/i2c-gpio.h> |
17 | 18 | ||
@@ -32,7 +33,7 @@ | |||
32 | * -------------------------------------------------------------------- */ | 33 | * -------------------------------------------------------------------- */ |
33 | 34 | ||
34 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | 35 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) |
35 | static u64 ohci_dmamask = 0xffffffffUL; | 36 | static u64 ohci_dmamask = DMA_BIT_MASK(32); |
36 | static struct at91_usbh_data usbh_data; | 37 | static struct at91_usbh_data usbh_data; |
37 | 38 | ||
38 | static struct resource usbh_resources[] = { | 39 | static struct resource usbh_resources[] = { |
@@ -53,7 +54,7 @@ static struct platform_device at91_usbh_device = { | |||
53 | .id = -1, | 54 | .id = -1, |
54 | .dev = { | 55 | .dev = { |
55 | .dma_mask = &ohci_dmamask, | 56 | .dma_mask = &ohci_dmamask, |
56 | .coherent_dma_mask = 0xffffffff, | 57 | .coherent_dma_mask = DMA_BIT_MASK(32), |
57 | .platform_data = &usbh_data, | 58 | .platform_data = &usbh_data, |
58 | }, | 59 | }, |
59 | .resource = usbh_resources, | 60 | .resource = usbh_resources, |
@@ -136,7 +137,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data) {} | |||
136 | * -------------------------------------------------------------------- */ | 137 | * -------------------------------------------------------------------- */ |
137 | 138 | ||
138 | #if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) | 139 | #if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) |
139 | static u64 eth_dmamask = 0xffffffffUL; | 140 | static u64 eth_dmamask = DMA_BIT_MASK(32); |
140 | static struct at91_eth_data eth_data; | 141 | static struct at91_eth_data eth_data; |
141 | 142 | ||
142 | static struct resource eth_resources[] = { | 143 | static struct resource eth_resources[] = { |
@@ -157,7 +158,7 @@ static struct platform_device at91sam9263_eth_device = { | |||
157 | .id = -1, | 158 | .id = -1, |
158 | .dev = { | 159 | .dev = { |
159 | .dma_mask = ð_dmamask, | 160 | .dma_mask = ð_dmamask, |
160 | .coherent_dma_mask = 0xffffffff, | 161 | .coherent_dma_mask = DMA_BIT_MASK(32), |
161 | .platform_data = ð_data, | 162 | .platform_data = ð_data, |
162 | }, | 163 | }, |
163 | .resource = eth_resources, | 164 | .resource = eth_resources, |
@@ -210,7 +211,7 @@ void __init at91_add_device_eth(struct at91_eth_data *data) {} | |||
210 | * -------------------------------------------------------------------- */ | 211 | * -------------------------------------------------------------------- */ |
211 | 212 | ||
212 | #if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) | 213 | #if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) |
213 | static u64 mmc_dmamask = 0xffffffffUL; | 214 | static u64 mmc_dmamask = DMA_BIT_MASK(32); |
214 | static struct at91_mmc_data mmc0_data, mmc1_data; | 215 | static struct at91_mmc_data mmc0_data, mmc1_data; |
215 | 216 | ||
216 | static struct resource mmc0_resources[] = { | 217 | static struct resource mmc0_resources[] = { |
@@ -231,7 +232,7 @@ static struct platform_device at91sam9263_mmc0_device = { | |||
231 | .id = 0, | 232 | .id = 0, |
232 | .dev = { | 233 | .dev = { |
233 | .dma_mask = &mmc_dmamask, | 234 | .dma_mask = &mmc_dmamask, |
234 | .coherent_dma_mask = 0xffffffff, | 235 | .coherent_dma_mask = DMA_BIT_MASK(32), |
235 | .platform_data = &mmc0_data, | 236 | .platform_data = &mmc0_data, |
236 | }, | 237 | }, |
237 | .resource = mmc0_resources, | 238 | .resource = mmc0_resources, |
@@ -256,7 +257,7 @@ static struct platform_device at91sam9263_mmc1_device = { | |||
256 | .id = 1, | 257 | .id = 1, |
257 | .dev = { | 258 | .dev = { |
258 | .dma_mask = &mmc_dmamask, | 259 | .dma_mask = &mmc_dmamask, |
259 | .coherent_dma_mask = 0xffffffff, | 260 | .coherent_dma_mask = DMA_BIT_MASK(32), |
260 | .platform_data = &mmc1_data, | 261 | .platform_data = &mmc1_data, |
261 | }, | 262 | }, |
262 | .resource = mmc1_resources, | 263 | .resource = mmc1_resources, |
@@ -382,7 +383,7 @@ void __init at91_add_device_nand(struct at91_nand_data *data) | |||
382 | return; | 383 | return; |
383 | 384 | ||
384 | csa = at91_sys_read(AT91_MATRIX_EBI0CSA); | 385 | csa = at91_sys_read(AT91_MATRIX_EBI0CSA); |
385 | at91_sys_write(AT91_MATRIX_EBI0CSA, csa | AT91_MATRIX_EBI0_CS3A_SMC); | 386 | at91_sys_write(AT91_MATRIX_EBI0CSA, csa | AT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA); |
386 | 387 | ||
387 | /* set the bus interface characteristics */ | 388 | /* set the bus interface characteristics */ |
388 | at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0) | 389 | at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0) |
@@ -500,7 +501,7 @@ void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) | |||
500 | * -------------------------------------------------------------------- */ | 501 | * -------------------------------------------------------------------- */ |
501 | 502 | ||
502 | #if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) | 503 | #if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) |
503 | static u64 spi_dmamask = 0xffffffffUL; | 504 | static u64 spi_dmamask = DMA_BIT_MASK(32); |
504 | 505 | ||
505 | static struct resource spi0_resources[] = { | 506 | static struct resource spi0_resources[] = { |
506 | [0] = { | 507 | [0] = { |
@@ -520,7 +521,7 @@ static struct platform_device at91sam9263_spi0_device = { | |||
520 | .id = 0, | 521 | .id = 0, |
521 | .dev = { | 522 | .dev = { |
522 | .dma_mask = &spi_dmamask, | 523 | .dma_mask = &spi_dmamask, |
523 | .coherent_dma_mask = 0xffffffff, | 524 | .coherent_dma_mask = DMA_BIT_MASK(32), |
524 | }, | 525 | }, |
525 | .resource = spi0_resources, | 526 | .resource = spi0_resources, |
526 | .num_resources = ARRAY_SIZE(spi0_resources), | 527 | .num_resources = ARRAY_SIZE(spi0_resources), |
@@ -546,7 +547,7 @@ static struct platform_device at91sam9263_spi1_device = { | |||
546 | .id = 1, | 547 | .id = 1, |
547 | .dev = { | 548 | .dev = { |
548 | .dma_mask = &spi_dmamask, | 549 | .dma_mask = &spi_dmamask, |
549 | .coherent_dma_mask = 0xffffffff, | 550 | .coherent_dma_mask = DMA_BIT_MASK(32), |
550 | }, | 551 | }, |
551 | .resource = spi1_resources, | 552 | .resource = spi1_resources, |
552 | .num_resources = ARRAY_SIZE(spi1_resources), | 553 | .num_resources = ARRAY_SIZE(spi1_resources), |
@@ -612,7 +613,7 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) | |||
612 | * -------------------------------------------------------------------- */ | 613 | * -------------------------------------------------------------------- */ |
613 | 614 | ||
614 | #if defined(CONFIG_SND_AT91_AC97) || defined(CONFIG_SND_AT91_AC97_MODULE) | 615 | #if defined(CONFIG_SND_AT91_AC97) || defined(CONFIG_SND_AT91_AC97_MODULE) |
615 | static u64 ac97_dmamask = 0xffffffffUL; | 616 | static u64 ac97_dmamask = DMA_BIT_MASK(32); |
616 | static struct atmel_ac97_data ac97_data; | 617 | static struct atmel_ac97_data ac97_data; |
617 | 618 | ||
618 | static struct resource ac97_resources[] = { | 619 | static struct resource ac97_resources[] = { |
@@ -633,7 +634,7 @@ static struct platform_device at91sam9263_ac97_device = { | |||
633 | .id = 1, | 634 | .id = 1, |
634 | .dev = { | 635 | .dev = { |
635 | .dma_mask = &ac97_dmamask, | 636 | .dma_mask = &ac97_dmamask, |
636 | .coherent_dma_mask = 0xffffffff, | 637 | .coherent_dma_mask = DMA_BIT_MASK(32), |
637 | .platform_data = &ac97_data, | 638 | .platform_data = &ac97_data, |
638 | }, | 639 | }, |
639 | .resource = ac97_resources, | 640 | .resource = ac97_resources, |
@@ -667,7 +668,7 @@ void __init at91_add_device_ac97(struct atmel_ac97_data *data) {} | |||
667 | * -------------------------------------------------------------------- */ | 668 | * -------------------------------------------------------------------- */ |
668 | 669 | ||
669 | #if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) | 670 | #if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) |
670 | static u64 lcdc_dmamask = 0xffffffffUL; | 671 | static u64 lcdc_dmamask = DMA_BIT_MASK(32); |
671 | static struct atmel_lcdfb_info lcdc_data; | 672 | static struct atmel_lcdfb_info lcdc_data; |
672 | 673 | ||
673 | static struct resource lcdc_resources[] = { | 674 | static struct resource lcdc_resources[] = { |
@@ -688,7 +689,7 @@ static struct platform_device at91_lcdc_device = { | |||
688 | .id = 0, | 689 | .id = 0, |
689 | .dev = { | 690 | .dev = { |
690 | .dma_mask = &lcdc_dmamask, | 691 | .dma_mask = &lcdc_dmamask, |
691 | .coherent_dma_mask = 0xffffffff, | 692 | .coherent_dma_mask = DMA_BIT_MASK(32), |
692 | .platform_data = &lcdc_data, | 693 | .platform_data = &lcdc_data, |
693 | }, | 694 | }, |
694 | .resource = lcdc_resources, | 695 | .resource = lcdc_resources, |
@@ -732,24 +733,242 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {} | |||
732 | 733 | ||
733 | 734 | ||
734 | /* -------------------------------------------------------------------- | 735 | /* -------------------------------------------------------------------- |
735 | * LEDs | 736 | * Image Sensor Interface |
736 | * -------------------------------------------------------------------- */ | 737 | * -------------------------------------------------------------------- */ |
737 | 738 | ||
738 | #if defined(CONFIG_LEDS) | 739 | #if defined(CONFIG_VIDEO_AT91_ISI) || defined(CONFIG_VIDEO_AT91_ISI_MODULE) |
739 | u8 at91_leds_cpu; | ||
740 | u8 at91_leds_timer; | ||
741 | 740 | ||
742 | void __init at91_init_leds(u8 cpu_led, u8 timer_led) | 741 | struct resource isi_resources[] = { |
742 | [0] = { | ||
743 | .start = AT91SAM9263_BASE_ISI, | ||
744 | .end = AT91SAM9263_BASE_ISI + SZ_16K - 1, | ||
745 | .flags = IORESOURCE_MEM, | ||
746 | }, | ||
747 | [1] = { | ||
748 | .start = AT91SAM9263_ID_ISI, | ||
749 | .end = AT91SAM9263_ID_ISI, | ||
750 | .flags = IORESOURCE_IRQ, | ||
751 | }, | ||
752 | }; | ||
753 | |||
754 | static struct platform_device at91sam9263_isi_device = { | ||
755 | .name = "at91_isi", | ||
756 | .id = -1, | ||
757 | .resource = isi_resources, | ||
758 | .num_resources = ARRAY_SIZE(isi_resources), | ||
759 | }; | ||
760 | |||
761 | void __init at91_add_device_isi(void) | ||
762 | { | ||
763 | at91_set_A_periph(AT91_PIN_PE0, 0); /* ISI_D0 */ | ||
764 | at91_set_A_periph(AT91_PIN_PE1, 0); /* ISI_D1 */ | ||
765 | at91_set_A_periph(AT91_PIN_PE2, 0); /* ISI_D2 */ | ||
766 | at91_set_A_periph(AT91_PIN_PE3, 0); /* ISI_D3 */ | ||
767 | at91_set_A_periph(AT91_PIN_PE4, 0); /* ISI_D4 */ | ||
768 | at91_set_A_periph(AT91_PIN_PE5, 0); /* ISI_D5 */ | ||
769 | at91_set_A_periph(AT91_PIN_PE6, 0); /* ISI_D6 */ | ||
770 | at91_set_A_periph(AT91_PIN_PE7, 0); /* ISI_D7 */ | ||
771 | at91_set_A_periph(AT91_PIN_PE8, 0); /* ISI_PCK */ | ||
772 | at91_set_A_periph(AT91_PIN_PE9, 0); /* ISI_HSYNC */ | ||
773 | at91_set_A_periph(AT91_PIN_PE10, 0); /* ISI_VSYNC */ | ||
774 | at91_set_B_periph(AT91_PIN_PE11, 0); /* ISI_MCK (PCK3) */ | ||
775 | at91_set_B_periph(AT91_PIN_PE12, 0); /* ISI_PD8 */ | ||
776 | at91_set_B_periph(AT91_PIN_PE13, 0); /* ISI_PD9 */ | ||
777 | at91_set_B_periph(AT91_PIN_PE14, 0); /* ISI_PD10 */ | ||
778 | at91_set_B_periph(AT91_PIN_PE15, 0); /* ISI_PD11 */ | ||
779 | } | ||
780 | #else | ||
781 | void __init at91_add_device_isi(void) {} | ||
782 | #endif | ||
783 | |||
784 | |||
785 | /* -------------------------------------------------------------------- | ||
786 | * RTT | ||
787 | * -------------------------------------------------------------------- */ | ||
788 | |||
789 | static struct resource rtt0_resources[] = { | ||
790 | { | ||
791 | .start = AT91_BASE_SYS + AT91_RTT0, | ||
792 | .end = AT91_BASE_SYS + AT91_RTT0 + SZ_16 - 1, | ||
793 | .flags = IORESOURCE_MEM, | ||
794 | } | ||
795 | }; | ||
796 | |||
797 | static struct platform_device at91sam9263_rtt0_device = { | ||
798 | .name = "at91_rtt", | ||
799 | .id = 0, | ||
800 | .resource = rtt0_resources, | ||
801 | .num_resources = ARRAY_SIZE(rtt0_resources), | ||
802 | }; | ||
803 | |||
804 | static struct resource rtt1_resources[] = { | ||
805 | { | ||
806 | .start = AT91_BASE_SYS + AT91_RTT1, | ||
807 | .end = AT91_BASE_SYS + AT91_RTT1 + SZ_16 - 1, | ||
808 | .flags = IORESOURCE_MEM, | ||
809 | } | ||
810 | }; | ||
811 | |||
812 | static struct platform_device at91sam9263_rtt1_device = { | ||
813 | .name = "at91_rtt", | ||
814 | .id = 1, | ||
815 | .resource = rtt1_resources, | ||
816 | .num_resources = ARRAY_SIZE(rtt1_resources), | ||
817 | }; | ||
818 | |||
819 | static void __init at91_add_device_rtt(void) | ||
820 | { | ||
821 | platform_device_register(&at91sam9263_rtt0_device); | ||
822 | platform_device_register(&at91sam9263_rtt1_device); | ||
823 | } | ||
824 | |||
825 | |||
826 | /* -------------------------------------------------------------------- | ||
827 | * Watchdog | ||
828 | * -------------------------------------------------------------------- */ | ||
829 | |||
830 | #if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE) | ||
831 | static struct platform_device at91sam9263_wdt_device = { | ||
832 | .name = "at91_wdt", | ||
833 | .id = -1, | ||
834 | .num_resources = 0, | ||
835 | }; | ||
836 | |||
837 | static void __init at91_add_device_watchdog(void) | ||
838 | { | ||
839 | platform_device_register(&at91sam9263_wdt_device); | ||
840 | } | ||
841 | #else | ||
842 | static void __init at91_add_device_watchdog(void) {} | ||
843 | #endif | ||
844 | |||
845 | |||
846 | /* -------------------------------------------------------------------- | ||
847 | * SSC -- Synchronous Serial Controller | ||
848 | * -------------------------------------------------------------------- */ | ||
849 | |||
850 | #if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE) | ||
851 | static u64 ssc0_dmamask = DMA_BIT_MASK(32); | ||
852 | |||
853 | static struct resource ssc0_resources[] = { | ||
854 | [0] = { | ||
855 | .start = AT91SAM9263_BASE_SSC0, | ||
856 | .end = AT91SAM9263_BASE_SSC0 + SZ_16K - 1, | ||
857 | .flags = IORESOURCE_MEM, | ||
858 | }, | ||
859 | [1] = { | ||
860 | .start = AT91SAM9263_ID_SSC0, | ||
861 | .end = AT91SAM9263_ID_SSC0, | ||
862 | .flags = IORESOURCE_IRQ, | ||
863 | }, | ||
864 | }; | ||
865 | |||
866 | static struct platform_device at91sam9263_ssc0_device = { | ||
867 | .name = "ssc", | ||
868 | .id = 0, | ||
869 | .dev = { | ||
870 | .dma_mask = &ssc0_dmamask, | ||
871 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
872 | }, | ||
873 | .resource = ssc0_resources, | ||
874 | .num_resources = ARRAY_SIZE(ssc0_resources), | ||
875 | }; | ||
876 | |||
877 | static inline void configure_ssc0_pins(unsigned pins) | ||
878 | { | ||
879 | if (pins & ATMEL_SSC_TF) | ||
880 | at91_set_B_periph(AT91_PIN_PB0, 1); | ||
881 | if (pins & ATMEL_SSC_TK) | ||
882 | at91_set_B_periph(AT91_PIN_PB1, 1); | ||
883 | if (pins & ATMEL_SSC_TD) | ||
884 | at91_set_B_periph(AT91_PIN_PB2, 1); | ||
885 | if (pins & ATMEL_SSC_RD) | ||
886 | at91_set_B_periph(AT91_PIN_PB3, 1); | ||
887 | if (pins & ATMEL_SSC_RK) | ||
888 | at91_set_B_periph(AT91_PIN_PB4, 1); | ||
889 | if (pins & ATMEL_SSC_RF) | ||
890 | at91_set_B_periph(AT91_PIN_PB5, 1); | ||
891 | } | ||
892 | |||
893 | static u64 ssc1_dmamask = DMA_BIT_MASK(32); | ||
894 | |||
895 | static struct resource ssc1_resources[] = { | ||
896 | [0] = { | ||
897 | .start = AT91SAM9263_BASE_SSC1, | ||
898 | .end = AT91SAM9263_BASE_SSC1 + SZ_16K - 1, | ||
899 | .flags = IORESOURCE_MEM, | ||
900 | }, | ||
901 | [1] = { | ||
902 | .start = AT91SAM9263_ID_SSC1, | ||
903 | .end = AT91SAM9263_ID_SSC1, | ||
904 | .flags = IORESOURCE_IRQ, | ||
905 | }, | ||
906 | }; | ||
907 | |||
908 | static struct platform_device at91sam9263_ssc1_device = { | ||
909 | .name = "ssc", | ||
910 | .id = 1, | ||
911 | .dev = { | ||
912 | .dma_mask = &ssc1_dmamask, | ||
913 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
914 | }, | ||
915 | .resource = ssc1_resources, | ||
916 | .num_resources = ARRAY_SIZE(ssc1_resources), | ||
917 | }; | ||
918 | |||
919 | static inline void configure_ssc1_pins(unsigned pins) | ||
920 | { | ||
921 | if (pins & ATMEL_SSC_TF) | ||
922 | at91_set_A_periph(AT91_PIN_PB6, 1); | ||
923 | if (pins & ATMEL_SSC_TK) | ||
924 | at91_set_A_periph(AT91_PIN_PB7, 1); | ||
925 | if (pins & ATMEL_SSC_TD) | ||
926 | at91_set_A_periph(AT91_PIN_PB8, 1); | ||
927 | if (pins & ATMEL_SSC_RD) | ||
928 | at91_set_A_periph(AT91_PIN_PB9, 1); | ||
929 | if (pins & ATMEL_SSC_RK) | ||
930 | at91_set_A_periph(AT91_PIN_PB10, 1); | ||
931 | if (pins & ATMEL_SSC_RF) | ||
932 | at91_set_A_periph(AT91_PIN_PB11, 1); | ||
933 | } | ||
934 | |||
935 | /* | ||
936 | * Return the device node so that board init code can use it as the | ||
937 | * parent for the device node reflecting how it's used on this board. | ||
938 | * | ||
939 | * SSC controllers are accessed through library code, instead of any | ||
940 | * kind of all-singing/all-dancing driver. For example one could be | ||
941 | * used by a particular I2S audio codec's driver, while another one | ||
942 | * on the same system might be used by a custom data capture driver. | ||
943 | */ | ||
944 | void __init at91_add_device_ssc(unsigned id, unsigned pins) | ||
743 | { | 945 | { |
744 | /* Enable GPIO to access the LEDs */ | 946 | struct platform_device *pdev; |
745 | at91_set_gpio_output(cpu_led, 1); | 947 | |
746 | at91_set_gpio_output(timer_led, 1); | 948 | /* |
949 | * NOTE: caller is responsible for passing information matching | ||
950 | * "pins" to whatever will be using each particular controller. | ||
951 | */ | ||
952 | switch (id) { | ||
953 | case AT91SAM9263_ID_SSC0: | ||
954 | pdev = &at91sam9263_ssc0_device; | ||
955 | configure_ssc0_pins(pins); | ||
956 | at91_clock_associate("ssc0_clk", &pdev->dev, "pclk"); | ||
957 | break; | ||
958 | case AT91SAM9263_ID_SSC1: | ||
959 | pdev = &at91sam9263_ssc1_device; | ||
960 | configure_ssc1_pins(pins); | ||
961 | at91_clock_associate("ssc1_clk", &pdev->dev, "pclk"); | ||
962 | break; | ||
963 | default: | ||
964 | return; | ||
965 | } | ||
747 | 966 | ||
748 | at91_leds_cpu = cpu_led; | 967 | platform_device_register(pdev); |
749 | at91_leds_timer = timer_led; | ||
750 | } | 968 | } |
969 | |||
751 | #else | 970 | #else |
752 | void __init at91_init_leds(u8 cpu_led, u8 timer_led) {} | 971 | void __init at91_add_device_ssc(unsigned id, unsigned pins) {} |
753 | #endif | 972 | #endif |
754 | 973 | ||
755 | 974 | ||
@@ -778,12 +997,15 @@ static struct atmel_uart_data dbgu_data = { | |||
778 | .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), | 997 | .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), |
779 | }; | 998 | }; |
780 | 999 | ||
1000 | static u64 dbgu_dmamask = DMA_BIT_MASK(32); | ||
1001 | |||
781 | static struct platform_device at91sam9263_dbgu_device = { | 1002 | static struct platform_device at91sam9263_dbgu_device = { |
782 | .name = "atmel_usart", | 1003 | .name = "atmel_usart", |
783 | .id = 0, | 1004 | .id = 0, |
784 | .dev = { | 1005 | .dev = { |
785 | .platform_data = &dbgu_data, | 1006 | .dma_mask = &dbgu_dmamask, |
786 | .coherent_dma_mask = 0xffffffff, | 1007 | .coherent_dma_mask = DMA_BIT_MASK(32), |
1008 | .platform_data = &dbgu_data, | ||
787 | }, | 1009 | }, |
788 | .resource = dbgu_resources, | 1010 | .resource = dbgu_resources, |
789 | .num_resources = ARRAY_SIZE(dbgu_resources), | 1011 | .num_resources = ARRAY_SIZE(dbgu_resources), |
@@ -813,23 +1035,29 @@ static struct atmel_uart_data uart0_data = { | |||
813 | .use_dma_rx = 1, | 1035 | .use_dma_rx = 1, |
814 | }; | 1036 | }; |
815 | 1037 | ||
1038 | static u64 uart0_dmamask = DMA_BIT_MASK(32); | ||
1039 | |||
816 | static struct platform_device at91sam9263_uart0_device = { | 1040 | static struct platform_device at91sam9263_uart0_device = { |
817 | .name = "atmel_usart", | 1041 | .name = "atmel_usart", |
818 | .id = 1, | 1042 | .id = 1, |
819 | .dev = { | 1043 | .dev = { |
820 | .platform_data = &uart0_data, | 1044 | .dma_mask = &uart0_dmamask, |
821 | .coherent_dma_mask = 0xffffffff, | 1045 | .coherent_dma_mask = DMA_BIT_MASK(32), |
1046 | .platform_data = &uart0_data, | ||
822 | }, | 1047 | }, |
823 | .resource = uart0_resources, | 1048 | .resource = uart0_resources, |
824 | .num_resources = ARRAY_SIZE(uart0_resources), | 1049 | .num_resources = ARRAY_SIZE(uart0_resources), |
825 | }; | 1050 | }; |
826 | 1051 | ||
827 | static inline void configure_usart0_pins(void) | 1052 | static inline void configure_usart0_pins(unsigned pins) |
828 | { | 1053 | { |
829 | at91_set_A_periph(AT91_PIN_PA26, 1); /* TXD0 */ | 1054 | at91_set_A_periph(AT91_PIN_PA26, 1); /* TXD0 */ |
830 | at91_set_A_periph(AT91_PIN_PA27, 0); /* RXD0 */ | 1055 | at91_set_A_periph(AT91_PIN_PA27, 0); /* RXD0 */ |
831 | at91_set_A_periph(AT91_PIN_PA28, 0); /* RTS0 */ | 1056 | |
832 | at91_set_A_periph(AT91_PIN_PA29, 0); /* CTS0 */ | 1057 | if (pins & ATMEL_UART_RTS) |
1058 | at91_set_A_periph(AT91_PIN_PA28, 0); /* RTS0 */ | ||
1059 | if (pins & ATMEL_UART_CTS) | ||
1060 | at91_set_A_periph(AT91_PIN_PA29, 0); /* CTS0 */ | ||
833 | } | 1061 | } |
834 | 1062 | ||
835 | static struct resource uart1_resources[] = { | 1063 | static struct resource uart1_resources[] = { |
@@ -850,23 +1078,29 @@ static struct atmel_uart_data uart1_data = { | |||
850 | .use_dma_rx = 1, | 1078 | .use_dma_rx = 1, |
851 | }; | 1079 | }; |
852 | 1080 | ||
1081 | static u64 uart1_dmamask = DMA_BIT_MASK(32); | ||
1082 | |||
853 | static struct platform_device at91sam9263_uart1_device = { | 1083 | static struct platform_device at91sam9263_uart1_device = { |
854 | .name = "atmel_usart", | 1084 | .name = "atmel_usart", |
855 | .id = 2, | 1085 | .id = 2, |
856 | .dev = { | 1086 | .dev = { |
857 | .platform_data = &uart1_data, | 1087 | .dma_mask = &uart1_dmamask, |
858 | .coherent_dma_mask = 0xffffffff, | 1088 | .coherent_dma_mask = DMA_BIT_MASK(32), |
1089 | .platform_data = &uart1_data, | ||
859 | }, | 1090 | }, |
860 | .resource = uart1_resources, | 1091 | .resource = uart1_resources, |
861 | .num_resources = ARRAY_SIZE(uart1_resources), | 1092 | .num_resources = ARRAY_SIZE(uart1_resources), |
862 | }; | 1093 | }; |
863 | 1094 | ||
864 | static inline void configure_usart1_pins(void) | 1095 | static inline void configure_usart1_pins(unsigned pins) |
865 | { | 1096 | { |
866 | at91_set_A_periph(AT91_PIN_PD0, 1); /* TXD1 */ | 1097 | at91_set_A_periph(AT91_PIN_PD0, 1); /* TXD1 */ |
867 | at91_set_A_periph(AT91_PIN_PD1, 0); /* RXD1 */ | 1098 | at91_set_A_periph(AT91_PIN_PD1, 0); /* RXD1 */ |
868 | at91_set_B_periph(AT91_PIN_PD7, 0); /* RTS1 */ | 1099 | |
869 | at91_set_B_periph(AT91_PIN_PD8, 0); /* CTS1 */ | 1100 | if (pins & ATMEL_UART_RTS) |
1101 | at91_set_B_periph(AT91_PIN_PD7, 0); /* RTS1 */ | ||
1102 | if (pins & ATMEL_UART_CTS) | ||
1103 | at91_set_B_periph(AT91_PIN_PD8, 0); /* CTS1 */ | ||
870 | } | 1104 | } |
871 | 1105 | ||
872 | static struct resource uart2_resources[] = { | 1106 | static struct resource uart2_resources[] = { |
@@ -887,29 +1121,35 @@ static struct atmel_uart_data uart2_data = { | |||
887 | .use_dma_rx = 1, | 1121 | .use_dma_rx = 1, |
888 | }; | 1122 | }; |
889 | 1123 | ||
1124 | static u64 uart2_dmamask = DMA_BIT_MASK(32); | ||
1125 | |||
890 | static struct platform_device at91sam9263_uart2_device = { | 1126 | static struct platform_device at91sam9263_uart2_device = { |
891 | .name = "atmel_usart", | 1127 | .name = "atmel_usart", |
892 | .id = 3, | 1128 | .id = 3, |
893 | .dev = { | 1129 | .dev = { |
894 | .platform_data = &uart2_data, | 1130 | .dma_mask = &uart2_dmamask, |
895 | .coherent_dma_mask = 0xffffffff, | 1131 | .coherent_dma_mask = DMA_BIT_MASK(32), |
1132 | .platform_data = &uart2_data, | ||
896 | }, | 1133 | }, |
897 | .resource = uart2_resources, | 1134 | .resource = uart2_resources, |
898 | .num_resources = ARRAY_SIZE(uart2_resources), | 1135 | .num_resources = ARRAY_SIZE(uart2_resources), |
899 | }; | 1136 | }; |
900 | 1137 | ||
901 | static inline void configure_usart2_pins(void) | 1138 | static inline void configure_usart2_pins(unsigned pins) |
902 | { | 1139 | { |
903 | at91_set_A_periph(AT91_PIN_PD2, 1); /* TXD2 */ | 1140 | at91_set_A_periph(AT91_PIN_PD2, 1); /* TXD2 */ |
904 | at91_set_A_periph(AT91_PIN_PD3, 0); /* RXD2 */ | 1141 | at91_set_A_periph(AT91_PIN_PD3, 0); /* RXD2 */ |
905 | at91_set_B_periph(AT91_PIN_PD5, 0); /* RTS2 */ | 1142 | |
906 | at91_set_B_periph(AT91_PIN_PD6, 0); /* CTS2 */ | 1143 | if (pins & ATMEL_UART_RTS) |
1144 | at91_set_B_periph(AT91_PIN_PD5, 0); /* RTS2 */ | ||
1145 | if (pins & ATMEL_UART_CTS) | ||
1146 | at91_set_B_periph(AT91_PIN_PD6, 0); /* CTS2 */ | ||
907 | } | 1147 | } |
908 | 1148 | ||
909 | struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ | 1149 | static struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ |
910 | struct platform_device *atmel_default_console_device; /* the serial console device */ | 1150 | struct platform_device *atmel_default_console_device; /* the serial console device */ |
911 | 1151 | ||
912 | void __init at91_init_serial(struct at91_uart_config *config) | 1152 | void __init __deprecated at91_init_serial(struct at91_uart_config *config) |
913 | { | 1153 | { |
914 | int i; | 1154 | int i; |
915 | 1155 | ||
@@ -917,17 +1157,17 @@ void __init at91_init_serial(struct at91_uart_config *config) | |||
917 | for (i = 0; i < config->nr_tty; i++) { | 1157 | for (i = 0; i < config->nr_tty; i++) { |
918 | switch (config->tty_map[i]) { | 1158 | switch (config->tty_map[i]) { |
919 | case 0: | 1159 | case 0: |
920 | configure_usart0_pins(); | 1160 | configure_usart0_pins(ATMEL_UART_CTS | ATMEL_UART_RTS); |
921 | at91_uarts[i] = &at91sam9263_uart0_device; | 1161 | at91_uarts[i] = &at91sam9263_uart0_device; |
922 | at91_clock_associate("usart0_clk", &at91sam9263_uart0_device.dev, "usart"); | 1162 | at91_clock_associate("usart0_clk", &at91sam9263_uart0_device.dev, "usart"); |
923 | break; | 1163 | break; |
924 | case 1: | 1164 | case 1: |
925 | configure_usart1_pins(); | 1165 | configure_usart1_pins(ATMEL_UART_CTS | ATMEL_UART_RTS); |
926 | at91_uarts[i] = &at91sam9263_uart1_device; | 1166 | at91_uarts[i] = &at91sam9263_uart1_device; |
927 | at91_clock_associate("usart1_clk", &at91sam9263_uart1_device.dev, "usart"); | 1167 | at91_clock_associate("usart1_clk", &at91sam9263_uart1_device.dev, "usart"); |
928 | break; | 1168 | break; |
929 | case 2: | 1169 | case 2: |
930 | configure_usart2_pins(); | 1170 | configure_usart2_pins(ATMEL_UART_CTS | ATMEL_UART_RTS); |
931 | at91_uarts[i] = &at91sam9263_uart2_device; | 1171 | at91_uarts[i] = &at91sam9263_uart2_device; |
932 | at91_clock_associate("usart2_clk", &at91sam9263_uart2_device.dev, "usart"); | 1172 | at91_clock_associate("usart2_clk", &at91sam9263_uart2_device.dev, "usart"); |
933 | break; | 1173 | break; |
@@ -949,6 +1189,48 @@ void __init at91_init_serial(struct at91_uart_config *config) | |||
949 | printk(KERN_INFO "AT91: No default serial console defined.\n"); | 1189 | printk(KERN_INFO "AT91: No default serial console defined.\n"); |
950 | } | 1190 | } |
951 | 1191 | ||
1192 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) | ||
1193 | { | ||
1194 | struct platform_device *pdev; | ||
1195 | |||
1196 | switch (id) { | ||
1197 | case 0: /* DBGU */ | ||
1198 | pdev = &at91sam9263_dbgu_device; | ||
1199 | configure_dbgu_pins(); | ||
1200 | at91_clock_associate("mck", &pdev->dev, "usart"); | ||
1201 | break; | ||
1202 | case AT91SAM9263_ID_US0: | ||
1203 | pdev = &at91sam9263_uart0_device; | ||
1204 | configure_usart0_pins(pins); | ||
1205 | at91_clock_associate("usart0_clk", &pdev->dev, "usart"); | ||
1206 | break; | ||
1207 | case AT91SAM9263_ID_US1: | ||
1208 | pdev = &at91sam9263_uart1_device; | ||
1209 | configure_usart1_pins(pins); | ||
1210 | at91_clock_associate("usart1_clk", &pdev->dev, "usart"); | ||
1211 | break; | ||
1212 | case AT91SAM9263_ID_US2: | ||
1213 | pdev = &at91sam9263_uart2_device; | ||
1214 | configure_usart2_pins(pins); | ||
1215 | at91_clock_associate("usart2_clk", &pdev->dev, "usart"); | ||
1216 | break; | ||
1217 | default: | ||
1218 | return; | ||
1219 | } | ||
1220 | pdev->id = portnr; /* update to mapped ID */ | ||
1221 | |||
1222 | if (portnr < ATMEL_MAX_UART) | ||
1223 | at91_uarts[portnr] = pdev; | ||
1224 | } | ||
1225 | |||
1226 | void __init at91_set_serial_console(unsigned portnr) | ||
1227 | { | ||
1228 | if (portnr < ATMEL_MAX_UART) | ||
1229 | atmel_default_console_device = at91_uarts[portnr]; | ||
1230 | if (!atmel_default_console_device) | ||
1231 | printk(KERN_INFO "AT91: No default serial console defined.\n"); | ||
1232 | } | ||
1233 | |||
952 | void __init at91_add_device_serial(void) | 1234 | void __init at91_add_device_serial(void) |
953 | { | 1235 | { |
954 | int i; | 1236 | int i; |
@@ -960,6 +1242,8 @@ void __init at91_add_device_serial(void) | |||
960 | } | 1242 | } |
961 | #else | 1243 | #else |
962 | void __init at91_init_serial(struct at91_uart_config *config) {} | 1244 | void __init at91_init_serial(struct at91_uart_config *config) {} |
1245 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} | ||
1246 | void __init at91_set_serial_console(unsigned portnr) {} | ||
963 | void __init at91_add_device_serial(void) {} | 1247 | void __init at91_add_device_serial(void) {} |
964 | #endif | 1248 | #endif |
965 | 1249 | ||
@@ -971,6 +1255,8 @@ void __init at91_add_device_serial(void) {} | |||
971 | */ | 1255 | */ |
972 | static int __init at91_add_standard_devices(void) | 1256 | static int __init at91_add_standard_devices(void) |
973 | { | 1257 | { |
1258 | at91_add_device_rtt(); | ||
1259 | at91_add_device_watchdog(); | ||
974 | return 0; | 1260 | return 0; |
975 | } | 1261 | } |
976 | 1262 | ||
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index 2bd60a3dc623..f43b5c33e45d 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <asm/mach/arch.h> | 9 | #include <asm/mach/arch.h> |
10 | #include <asm/mach/map.h> | 10 | #include <asm/mach/map.h> |
11 | 11 | ||
12 | #include <linux/dma-mapping.h> | ||
12 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
13 | #include <linux/i2c-gpio.h> | 14 | #include <linux/i2c-gpio.h> |
14 | 15 | ||
@@ -29,7 +30,7 @@ | |||
29 | * -------------------------------------------------------------------- */ | 30 | * -------------------------------------------------------------------- */ |
30 | 31 | ||
31 | #if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) | 32 | #if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) |
32 | static u64 mmc_dmamask = 0xffffffffUL; | 33 | static u64 mmc_dmamask = DMA_BIT_MASK(32); |
33 | static struct at91_mmc_data mmc_data; | 34 | static struct at91_mmc_data mmc_data; |
34 | 35 | ||
35 | static struct resource mmc_resources[] = { | 36 | static struct resource mmc_resources[] = { |
@@ -50,7 +51,7 @@ static struct platform_device at91sam9rl_mmc_device = { | |||
50 | .id = -1, | 51 | .id = -1, |
51 | .dev = { | 52 | .dev = { |
52 | .dma_mask = &mmc_dmamask, | 53 | .dma_mask = &mmc_dmamask, |
53 | .coherent_dma_mask = 0xffffffff, | 54 | .coherent_dma_mask = DMA_BIT_MASK(32), |
54 | .platform_data = &mmc_data, | 55 | .platform_data = &mmc_data, |
55 | }, | 56 | }, |
56 | .resource = mmc_resources, | 57 | .resource = mmc_resources, |
@@ -247,7 +248,7 @@ void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) | |||
247 | * -------------------------------------------------------------------- */ | 248 | * -------------------------------------------------------------------- */ |
248 | 249 | ||
249 | #if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) | 250 | #if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) |
250 | static u64 spi_dmamask = 0xffffffffUL; | 251 | static u64 spi_dmamask = DMA_BIT_MASK(32); |
251 | 252 | ||
252 | static struct resource spi_resources[] = { | 253 | static struct resource spi_resources[] = { |
253 | [0] = { | 254 | [0] = { |
@@ -267,7 +268,7 @@ static struct platform_device at91sam9rl_spi_device = { | |||
267 | .id = 0, | 268 | .id = 0, |
268 | .dev = { | 269 | .dev = { |
269 | .dma_mask = &spi_dmamask, | 270 | .dma_mask = &spi_dmamask, |
270 | .coherent_dma_mask = 0xffffffff, | 271 | .coherent_dma_mask = DMA_BIT_MASK(32), |
271 | }, | 272 | }, |
272 | .resource = spi_resources, | 273 | .resource = spi_resources, |
273 | .num_resources = ARRAY_SIZE(spi_resources), | 274 | .num_resources = ARRAY_SIZE(spi_resources), |
@@ -312,7 +313,7 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) | |||
312 | * -------------------------------------------------------------------- */ | 313 | * -------------------------------------------------------------------- */ |
313 | 314 | ||
314 | #if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) | 315 | #if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) |
315 | static u64 lcdc_dmamask = 0xffffffffUL; | 316 | static u64 lcdc_dmamask = DMA_BIT_MASK(32); |
316 | static struct atmel_lcdfb_info lcdc_data; | 317 | static struct atmel_lcdfb_info lcdc_data; |
317 | 318 | ||
318 | static struct resource lcdc_resources[] = { | 319 | static struct resource lcdc_resources[] = { |
@@ -340,7 +341,7 @@ static struct platform_device at91_lcdc_device = { | |||
340 | .id = 0, | 341 | .id = 0, |
341 | .dev = { | 342 | .dev = { |
342 | .dma_mask = &lcdc_dmamask, | 343 | .dma_mask = &lcdc_dmamask, |
343 | .coherent_dma_mask = 0xffffffff, | 344 | .coherent_dma_mask = DMA_BIT_MASK(32), |
344 | .platform_data = &lcdc_data, | 345 | .platform_data = &lcdc_data, |
345 | }, | 346 | }, |
346 | .resource = lcdc_resources, | 347 | .resource = lcdc_resources, |
@@ -384,24 +385,196 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {} | |||
384 | 385 | ||
385 | 386 | ||
386 | /* -------------------------------------------------------------------- | 387 | /* -------------------------------------------------------------------- |
387 | * LEDs | 388 | * RTC |
388 | * -------------------------------------------------------------------- */ | 389 | * -------------------------------------------------------------------- */ |
389 | 390 | ||
390 | #if defined(CONFIG_LEDS) | 391 | #if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE) |
391 | u8 at91_leds_cpu; | 392 | static struct platform_device at91sam9rl_rtc_device = { |
392 | u8 at91_leds_timer; | 393 | .name = "at91_rtc", |
394 | .id = -1, | ||
395 | .num_resources = 0, | ||
396 | }; | ||
393 | 397 | ||
394 | void __init at91_init_leds(u8 cpu_led, u8 timer_led) | 398 | static void __init at91_add_device_rtc(void) |
395 | { | 399 | { |
396 | /* Enable GPIO to access the LEDs */ | 400 | platform_device_register(&at91sam9rl_rtc_device); |
397 | at91_set_gpio_output(cpu_led, 1); | 401 | } |
398 | at91_set_gpio_output(timer_led, 1); | 402 | #else |
403 | static void __init at91_add_device_rtc(void) {} | ||
404 | #endif | ||
405 | |||
406 | |||
407 | /* -------------------------------------------------------------------- | ||
408 | * RTT | ||
409 | * -------------------------------------------------------------------- */ | ||
410 | |||
411 | static struct resource rtt_resources[] = { | ||
412 | { | ||
413 | .start = AT91_BASE_SYS + AT91_RTT, | ||
414 | .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1, | ||
415 | .flags = IORESOURCE_MEM, | ||
416 | } | ||
417 | }; | ||
418 | |||
419 | static struct platform_device at91sam9rl_rtt_device = { | ||
420 | .name = "at91_rtt", | ||
421 | .id = -1, | ||
422 | .resource = rtt_resources, | ||
423 | .num_resources = ARRAY_SIZE(rtt_resources), | ||
424 | }; | ||
399 | 425 | ||
400 | at91_leds_cpu = cpu_led; | 426 | static void __init at91_add_device_rtt(void) |
401 | at91_leds_timer = timer_led; | 427 | { |
428 | platform_device_register(&at91sam9rl_rtt_device); | ||
429 | } | ||
430 | |||
431 | |||
432 | /* -------------------------------------------------------------------- | ||
433 | * Watchdog | ||
434 | * -------------------------------------------------------------------- */ | ||
435 | |||
436 | #if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE) | ||
437 | static struct platform_device at91sam9rl_wdt_device = { | ||
438 | .name = "at91_wdt", | ||
439 | .id = -1, | ||
440 | .num_resources = 0, | ||
441 | }; | ||
442 | |||
443 | static void __init at91_add_device_watchdog(void) | ||
444 | { | ||
445 | platform_device_register(&at91sam9rl_wdt_device); | ||
402 | } | 446 | } |
403 | #else | 447 | #else |
404 | void __init at91_init_leds(u8 cpu_led, u8 timer_led) {} | 448 | static void __init at91_add_device_watchdog(void) {} |
449 | #endif | ||
450 | |||
451 | |||
452 | /* -------------------------------------------------------------------- | ||
453 | * SSC -- Synchronous Serial Controller | ||
454 | * -------------------------------------------------------------------- */ | ||
455 | |||
456 | #if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE) | ||
457 | static u64 ssc0_dmamask = DMA_BIT_MASK(32); | ||
458 | |||
459 | static struct resource ssc0_resources[] = { | ||
460 | [0] = { | ||
461 | .start = AT91SAM9RL_BASE_SSC0, | ||
462 | .end = AT91SAM9RL_BASE_SSC0 + SZ_16K - 1, | ||
463 | .flags = IORESOURCE_MEM, | ||
464 | }, | ||
465 | [1] = { | ||
466 | .start = AT91SAM9RL_ID_SSC0, | ||
467 | .end = AT91SAM9RL_ID_SSC0, | ||
468 | .flags = IORESOURCE_IRQ, | ||
469 | }, | ||
470 | }; | ||
471 | |||
472 | static struct platform_device at91sam9rl_ssc0_device = { | ||
473 | .name = "ssc", | ||
474 | .id = 0, | ||
475 | .dev = { | ||
476 | .dma_mask = &ssc0_dmamask, | ||
477 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
478 | }, | ||
479 | .resource = ssc0_resources, | ||
480 | .num_resources = ARRAY_SIZE(ssc0_resources), | ||
481 | }; | ||
482 | |||
483 | static inline void configure_ssc0_pins(unsigned pins) | ||
484 | { | ||
485 | if (pins & ATMEL_SSC_TF) | ||
486 | at91_set_A_periph(AT91_PIN_PC0, 1); | ||
487 | if (pins & ATMEL_SSC_TK) | ||
488 | at91_set_A_periph(AT91_PIN_PC1, 1); | ||
489 | if (pins & ATMEL_SSC_TD) | ||
490 | at91_set_A_periph(AT91_PIN_PA15, 1); | ||
491 | if (pins & ATMEL_SSC_RD) | ||
492 | at91_set_A_periph(AT91_PIN_PA16, 1); | ||
493 | if (pins & ATMEL_SSC_RK) | ||
494 | at91_set_B_periph(AT91_PIN_PA10, 1); | ||
495 | if (pins & ATMEL_SSC_RF) | ||
496 | at91_set_B_periph(AT91_PIN_PA22, 1); | ||
497 | } | ||
498 | |||
499 | static u64 ssc1_dmamask = DMA_BIT_MASK(32); | ||
500 | |||
501 | static struct resource ssc1_resources[] = { | ||
502 | [0] = { | ||
503 | .start = AT91SAM9RL_BASE_SSC1, | ||
504 | .end = AT91SAM9RL_BASE_SSC1 + SZ_16K - 1, | ||
505 | .flags = IORESOURCE_MEM, | ||
506 | }, | ||
507 | [1] = { | ||
508 | .start = AT91SAM9RL_ID_SSC1, | ||
509 | .end = AT91SAM9RL_ID_SSC1, | ||
510 | .flags = IORESOURCE_IRQ, | ||
511 | }, | ||
512 | }; | ||
513 | |||
514 | static struct platform_device at91sam9rl_ssc1_device = { | ||
515 | .name = "ssc", | ||
516 | .id = 1, | ||
517 | .dev = { | ||
518 | .dma_mask = &ssc1_dmamask, | ||
519 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
520 | }, | ||
521 | .resource = ssc1_resources, | ||
522 | .num_resources = ARRAY_SIZE(ssc1_resources), | ||
523 | }; | ||
524 | |||
525 | static inline void configure_ssc1_pins(unsigned pins) | ||
526 | { | ||
527 | if (pins & ATMEL_SSC_TF) | ||
528 | at91_set_B_periph(AT91_PIN_PA29, 1); | ||
529 | if (pins & ATMEL_SSC_TK) | ||
530 | at91_set_B_periph(AT91_PIN_PA30, 1); | ||
531 | if (pins & ATMEL_SSC_TD) | ||
532 | at91_set_B_periph(AT91_PIN_PA13, 1); | ||
533 | if (pins & ATMEL_SSC_RD) | ||
534 | at91_set_B_periph(AT91_PIN_PA14, 1); | ||
535 | if (pins & ATMEL_SSC_RK) | ||
536 | at91_set_B_periph(AT91_PIN_PA9, 1); | ||
537 | if (pins & ATMEL_SSC_RF) | ||
538 | at91_set_B_periph(AT91_PIN_PA8, 1); | ||
539 | } | ||
540 | |||
541 | /* | ||
542 | * Return the device node so that board init code can use it as the | ||
543 | * parent for the device node reflecting how it's used on this board. | ||
544 | * | ||
545 | * SSC controllers are accessed through library code, instead of any | ||
546 | * kind of all-singing/all-dancing driver. For example one could be | ||
547 | * used by a particular I2S audio codec's driver, while another one | ||
548 | * on the same system might be used by a custom data capture driver. | ||
549 | */ | ||
550 | void __init at91_add_device_ssc(unsigned id, unsigned pins) | ||
551 | { | ||
552 | struct platform_device *pdev; | ||
553 | |||
554 | /* | ||
555 | * NOTE: caller is responsible for passing information matching | ||
556 | * "pins" to whatever will be using each particular controller. | ||
557 | */ | ||
558 | switch (id) { | ||
559 | case AT91SAM9RL_ID_SSC0: | ||
560 | pdev = &at91sam9rl_ssc0_device; | ||
561 | configure_ssc0_pins(pins); | ||
562 | at91_clock_associate("ssc0_clk", &pdev->dev, "pclk"); | ||
563 | break; | ||
564 | case AT91SAM9RL_ID_SSC1: | ||
565 | pdev = &at91sam9rl_ssc1_device; | ||
566 | configure_ssc1_pins(pins); | ||
567 | at91_clock_associate("ssc1_clk", &pdev->dev, "pclk"); | ||
568 | break; | ||
569 | default: | ||
570 | return; | ||
571 | } | ||
572 | |||
573 | platform_device_register(pdev); | ||
574 | } | ||
575 | |||
576 | #else | ||
577 | void __init at91_add_device_ssc(unsigned id, unsigned pins) {} | ||
405 | #endif | 578 | #endif |
406 | 579 | ||
407 | 580 | ||
@@ -429,12 +602,15 @@ static struct atmel_uart_data dbgu_data = { | |||
429 | .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), | 602 | .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), |
430 | }; | 603 | }; |
431 | 604 | ||
605 | static u64 dbgu_dmamask = DMA_BIT_MASK(32); | ||
606 | |||
432 | static struct platform_device at91sam9rl_dbgu_device = { | 607 | static struct platform_device at91sam9rl_dbgu_device = { |
433 | .name = "atmel_usart", | 608 | .name = "atmel_usart", |
434 | .id = 0, | 609 | .id = 0, |
435 | .dev = { | 610 | .dev = { |
436 | .platform_data = &dbgu_data, | 611 | .dma_mask = &dbgu_dmamask, |
437 | .coherent_dma_mask = 0xffffffff, | 612 | .coherent_dma_mask = DMA_BIT_MASK(32), |
613 | .platform_data = &dbgu_data, | ||
438 | }, | 614 | }, |
439 | .resource = dbgu_resources, | 615 | .resource = dbgu_resources, |
440 | .num_resources = ARRAY_SIZE(dbgu_resources), | 616 | .num_resources = ARRAY_SIZE(dbgu_resources), |
@@ -464,23 +640,37 @@ static struct atmel_uart_data uart0_data = { | |||
464 | .use_dma_rx = 1, | 640 | .use_dma_rx = 1, |
465 | }; | 641 | }; |
466 | 642 | ||
643 | static u64 uart0_dmamask = DMA_BIT_MASK(32); | ||
644 | |||
467 | static struct platform_device at91sam9rl_uart0_device = { | 645 | static struct platform_device at91sam9rl_uart0_device = { |
468 | .name = "atmel_usart", | 646 | .name = "atmel_usart", |
469 | .id = 1, | 647 | .id = 1, |
470 | .dev = { | 648 | .dev = { |
471 | .platform_data = &uart0_data, | 649 | .dma_mask = &uart0_dmamask, |
472 | .coherent_dma_mask = 0xffffffff, | 650 | .coherent_dma_mask = DMA_BIT_MASK(32), |
651 | .platform_data = &uart0_data, | ||
473 | }, | 652 | }, |
474 | .resource = uart0_resources, | 653 | .resource = uart0_resources, |
475 | .num_resources = ARRAY_SIZE(uart0_resources), | 654 | .num_resources = ARRAY_SIZE(uart0_resources), |
476 | }; | 655 | }; |
477 | 656 | ||
478 | static inline void configure_usart0_pins(void) | 657 | static inline void configure_usart0_pins(unsigned pins) |
479 | { | 658 | { |
480 | at91_set_A_periph(AT91_PIN_PA6, 1); /* TXD0 */ | 659 | at91_set_A_periph(AT91_PIN_PA6, 1); /* TXD0 */ |
481 | at91_set_A_periph(AT91_PIN_PA7, 0); /* RXD0 */ | 660 | at91_set_A_periph(AT91_PIN_PA7, 0); /* RXD0 */ |
482 | at91_set_A_periph(AT91_PIN_PA9, 0); /* RTS0 */ | 661 | |
483 | at91_set_A_periph(AT91_PIN_PA10, 0); /* CTS0 */ | 662 | if (pins & ATMEL_UART_RTS) |
663 | at91_set_A_periph(AT91_PIN_PA9, 0); /* RTS0 */ | ||
664 | if (pins & ATMEL_UART_CTS) | ||
665 | at91_set_A_periph(AT91_PIN_PA10, 0); /* CTS0 */ | ||
666 | if (pins & ATMEL_UART_DSR) | ||
667 | at91_set_A_periph(AT91_PIN_PD14, 0); /* DSR0 */ | ||
668 | if (pins & ATMEL_UART_DTR) | ||
669 | at91_set_A_periph(AT91_PIN_PD15, 0); /* DTR0 */ | ||
670 | if (pins & ATMEL_UART_DCD) | ||
671 | at91_set_A_periph(AT91_PIN_PD16, 0); /* DCD0 */ | ||
672 | if (pins & ATMEL_UART_RI) | ||
673 | at91_set_A_periph(AT91_PIN_PD17, 0); /* RI0 */ | ||
484 | } | 674 | } |
485 | 675 | ||
486 | static struct resource uart1_resources[] = { | 676 | static struct resource uart1_resources[] = { |
@@ -501,21 +691,29 @@ static struct atmel_uart_data uart1_data = { | |||
501 | .use_dma_rx = 1, | 691 | .use_dma_rx = 1, |
502 | }; | 692 | }; |
503 | 693 | ||
694 | static u64 uart1_dmamask = DMA_BIT_MASK(32); | ||
695 | |||
504 | static struct platform_device at91sam9rl_uart1_device = { | 696 | static struct platform_device at91sam9rl_uart1_device = { |
505 | .name = "atmel_usart", | 697 | .name = "atmel_usart", |
506 | .id = 2, | 698 | .id = 2, |
507 | .dev = { | 699 | .dev = { |
508 | .platform_data = &uart1_data, | 700 | .dma_mask = &uart1_dmamask, |
509 | .coherent_dma_mask = 0xffffffff, | 701 | .coherent_dma_mask = DMA_BIT_MASK(32), |
702 | .platform_data = &uart1_data, | ||
510 | }, | 703 | }, |
511 | .resource = uart1_resources, | 704 | .resource = uart1_resources, |
512 | .num_resources = ARRAY_SIZE(uart1_resources), | 705 | .num_resources = ARRAY_SIZE(uart1_resources), |
513 | }; | 706 | }; |
514 | 707 | ||
515 | static inline void configure_usart1_pins(void) | 708 | static inline void configure_usart1_pins(unsigned pins) |
516 | { | 709 | { |
517 | at91_set_A_periph(AT91_PIN_PA11, 1); /* TXD1 */ | 710 | at91_set_A_periph(AT91_PIN_PA11, 1); /* TXD1 */ |
518 | at91_set_A_periph(AT91_PIN_PA12, 0); /* RXD1 */ | 711 | at91_set_A_periph(AT91_PIN_PA12, 0); /* RXD1 */ |
712 | |||
713 | if (pins & ATMEL_UART_RTS) | ||
714 | at91_set_B_periph(AT91_PIN_PA18, 0); /* RTS1 */ | ||
715 | if (pins & ATMEL_UART_CTS) | ||
716 | at91_set_B_periph(AT91_PIN_PA19, 0); /* CTS1 */ | ||
519 | } | 717 | } |
520 | 718 | ||
521 | static struct resource uart2_resources[] = { | 719 | static struct resource uart2_resources[] = { |
@@ -536,21 +734,29 @@ static struct atmel_uart_data uart2_data = { | |||
536 | .use_dma_rx = 1, | 734 | .use_dma_rx = 1, |
537 | }; | 735 | }; |
538 | 736 | ||
737 | static u64 uart2_dmamask = DMA_BIT_MASK(32); | ||
738 | |||
539 | static struct platform_device at91sam9rl_uart2_device = { | 739 | static struct platform_device at91sam9rl_uart2_device = { |
540 | .name = "atmel_usart", | 740 | .name = "atmel_usart", |
541 | .id = 3, | 741 | .id = 3, |
542 | .dev = { | 742 | .dev = { |
543 | .platform_data = &uart2_data, | 743 | .dma_mask = &uart2_dmamask, |
544 | .coherent_dma_mask = 0xffffffff, | 744 | .coherent_dma_mask = DMA_BIT_MASK(32), |
745 | .platform_data = &uart2_data, | ||
545 | }, | 746 | }, |
546 | .resource = uart2_resources, | 747 | .resource = uart2_resources, |
547 | .num_resources = ARRAY_SIZE(uart2_resources), | 748 | .num_resources = ARRAY_SIZE(uart2_resources), |
548 | }; | 749 | }; |
549 | 750 | ||
550 | static inline void configure_usart2_pins(void) | 751 | static inline void configure_usart2_pins(unsigned pins) |
551 | { | 752 | { |
552 | at91_set_A_periph(AT91_PIN_PA13, 1); /* TXD2 */ | 753 | at91_set_A_periph(AT91_PIN_PA13, 1); /* TXD2 */ |
553 | at91_set_A_periph(AT91_PIN_PA14, 0); /* RXD2 */ | 754 | at91_set_A_periph(AT91_PIN_PA14, 0); /* RXD2 */ |
755 | |||
756 | if (pins & ATMEL_UART_RTS) | ||
757 | at91_set_A_periph(AT91_PIN_PA29, 0); /* RTS2 */ | ||
758 | if (pins & ATMEL_UART_CTS) | ||
759 | at91_set_A_periph(AT91_PIN_PA30, 0); /* CTS2 */ | ||
554 | } | 760 | } |
555 | 761 | ||
556 | static struct resource uart3_resources[] = { | 762 | static struct resource uart3_resources[] = { |
@@ -571,27 +777,35 @@ static struct atmel_uart_data uart3_data = { | |||
571 | .use_dma_rx = 1, | 777 | .use_dma_rx = 1, |
572 | }; | 778 | }; |
573 | 779 | ||
780 | static u64 uart3_dmamask = DMA_BIT_MASK(32); | ||
781 | |||
574 | static struct platform_device at91sam9rl_uart3_device = { | 782 | static struct platform_device at91sam9rl_uart3_device = { |
575 | .name = "atmel_usart", | 783 | .name = "atmel_usart", |
576 | .id = 4, | 784 | .id = 4, |
577 | .dev = { | 785 | .dev = { |
578 | .platform_data = &uart3_data, | 786 | .dma_mask = &uart3_dmamask, |
579 | .coherent_dma_mask = 0xffffffff, | 787 | .coherent_dma_mask = DMA_BIT_MASK(32), |
788 | .platform_data = &uart3_data, | ||
580 | }, | 789 | }, |
581 | .resource = uart3_resources, | 790 | .resource = uart3_resources, |
582 | .num_resources = ARRAY_SIZE(uart3_resources), | 791 | .num_resources = ARRAY_SIZE(uart3_resources), |
583 | }; | 792 | }; |
584 | 793 | ||
585 | static inline void configure_usart3_pins(void) | 794 | static inline void configure_usart3_pins(unsigned pins) |
586 | { | 795 | { |
587 | at91_set_A_periph(AT91_PIN_PB0, 1); /* TXD3 */ | 796 | at91_set_A_periph(AT91_PIN_PB0, 1); /* TXD3 */ |
588 | at91_set_A_periph(AT91_PIN_PB1, 0); /* RXD3 */ | 797 | at91_set_A_periph(AT91_PIN_PB1, 0); /* RXD3 */ |
798 | |||
799 | if (pins & ATMEL_UART_RTS) | ||
800 | at91_set_B_periph(AT91_PIN_PD4, 0); /* RTS3 */ | ||
801 | if (pins & ATMEL_UART_CTS) | ||
802 | at91_set_B_periph(AT91_PIN_PD3, 0); /* CTS3 */ | ||
589 | } | 803 | } |
590 | 804 | ||
591 | struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ | 805 | static struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ |
592 | struct platform_device *atmel_default_console_device; /* the serial console device */ | 806 | struct platform_device *atmel_default_console_device; /* the serial console device */ |
593 | 807 | ||
594 | void __init at91_init_serial(struct at91_uart_config *config) | 808 | void __init __deprecated at91_init_serial(struct at91_uart_config *config) |
595 | { | 809 | { |
596 | int i; | 810 | int i; |
597 | 811 | ||
@@ -599,22 +813,22 @@ void __init at91_init_serial(struct at91_uart_config *config) | |||
599 | for (i = 0; i < config->nr_tty; i++) { | 813 | for (i = 0; i < config->nr_tty; i++) { |
600 | switch (config->tty_map[i]) { | 814 | switch (config->tty_map[i]) { |
601 | case 0: | 815 | case 0: |
602 | configure_usart0_pins(); | 816 | configure_usart0_pins(ATMEL_UART_CTS | ATMEL_UART_RTS); |
603 | at91_uarts[i] = &at91sam9rl_uart0_device; | 817 | at91_uarts[i] = &at91sam9rl_uart0_device; |
604 | at91_clock_associate("usart0_clk", &at91sam9rl_uart0_device.dev, "usart"); | 818 | at91_clock_associate("usart0_clk", &at91sam9rl_uart0_device.dev, "usart"); |
605 | break; | 819 | break; |
606 | case 1: | 820 | case 1: |
607 | configure_usart1_pins(); | 821 | configure_usart1_pins(0); |
608 | at91_uarts[i] = &at91sam9rl_uart1_device; | 822 | at91_uarts[i] = &at91sam9rl_uart1_device; |
609 | at91_clock_associate("usart1_clk", &at91sam9rl_uart1_device.dev, "usart"); | 823 | at91_clock_associate("usart1_clk", &at91sam9rl_uart1_device.dev, "usart"); |
610 | break; | 824 | break; |
611 | case 2: | 825 | case 2: |
612 | configure_usart2_pins(); | 826 | configure_usart2_pins(0); |
613 | at91_uarts[i] = &at91sam9rl_uart2_device; | 827 | at91_uarts[i] = &at91sam9rl_uart2_device; |
614 | at91_clock_associate("usart2_clk", &at91sam9rl_uart2_device.dev, "usart"); | 828 | at91_clock_associate("usart2_clk", &at91sam9rl_uart2_device.dev, "usart"); |
615 | break; | 829 | break; |
616 | case 3: | 830 | case 3: |
617 | configure_usart3_pins(); | 831 | configure_usart3_pins(0); |
618 | at91_uarts[i] = &at91sam9rl_uart3_device; | 832 | at91_uarts[i] = &at91sam9rl_uart3_device; |
619 | at91_clock_associate("usart3_clk", &at91sam9rl_uart3_device.dev, "usart"); | 833 | at91_clock_associate("usart3_clk", &at91sam9rl_uart3_device.dev, "usart"); |
620 | break; | 834 | break; |
@@ -636,6 +850,53 @@ void __init at91_init_serial(struct at91_uart_config *config) | |||
636 | printk(KERN_INFO "AT91: No default serial console defined.\n"); | 850 | printk(KERN_INFO "AT91: No default serial console defined.\n"); |
637 | } | 851 | } |
638 | 852 | ||
853 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) | ||
854 | { | ||
855 | struct platform_device *pdev; | ||
856 | |||
857 | switch (id) { | ||
858 | case 0: /* DBGU */ | ||
859 | pdev = &at91sam9rl_dbgu_device; | ||
860 | configure_dbgu_pins(); | ||
861 | at91_clock_associate("mck", &pdev->dev, "usart"); | ||
862 | break; | ||
863 | case AT91SAM9RL_ID_US0: | ||
864 | pdev = &at91sam9rl_uart0_device; | ||
865 | configure_usart0_pins(pins); | ||
866 | at91_clock_associate("usart0_clk", &pdev->dev, "usart"); | ||
867 | break; | ||
868 | case AT91SAM9RL_ID_US1: | ||
869 | pdev = &at91sam9rl_uart1_device; | ||
870 | configure_usart1_pins(pins); | ||
871 | at91_clock_associate("usart1_clk", &pdev->dev, "usart"); | ||
872 | break; | ||
873 | case AT91SAM9RL_ID_US2: | ||
874 | pdev = &at91sam9rl_uart2_device; | ||
875 | configure_usart2_pins(pins); | ||
876 | at91_clock_associate("usart2_clk", &pdev->dev, "usart"); | ||
877 | break; | ||
878 | case AT91SAM9RL_ID_US3: | ||
879 | pdev = &at91sam9rl_uart3_device; | ||
880 | configure_usart3_pins(pins); | ||
881 | at91_clock_associate("usart3_clk", &pdev->dev, "usart"); | ||
882 | break; | ||
883 | default: | ||
884 | return; | ||
885 | } | ||
886 | pdev->id = portnr; /* update to mapped ID */ | ||
887 | |||
888 | if (portnr < ATMEL_MAX_UART) | ||
889 | at91_uarts[portnr] = pdev; | ||
890 | } | ||
891 | |||
892 | void __init at91_set_serial_console(unsigned portnr) | ||
893 | { | ||
894 | if (portnr < ATMEL_MAX_UART) | ||
895 | atmel_default_console_device = at91_uarts[portnr]; | ||
896 | if (!atmel_default_console_device) | ||
897 | printk(KERN_INFO "AT91: No default serial console defined.\n"); | ||
898 | } | ||
899 | |||
639 | void __init at91_add_device_serial(void) | 900 | void __init at91_add_device_serial(void) |
640 | { | 901 | { |
641 | int i; | 902 | int i; |
@@ -646,7 +907,9 @@ void __init at91_add_device_serial(void) | |||
646 | } | 907 | } |
647 | } | 908 | } |
648 | #else | 909 | #else |
649 | void __init at91_init_serial(struct at91_uart_config *config) {} | 910 | void __init __deprecated at91_init_serial(struct at91_uart_config *config) {} |
911 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} | ||
912 | void __init at91_set_serial_console(unsigned portnr) {} | ||
650 | void __init at91_add_device_serial(void) {} | 913 | void __init at91_add_device_serial(void) {} |
651 | #endif | 914 | #endif |
652 | 915 | ||
@@ -659,6 +922,9 @@ void __init at91_add_device_serial(void) {} | |||
659 | */ | 922 | */ |
660 | static int __init at91_add_standard_devices(void) | 923 | static int __init at91_add_standard_devices(void) |
661 | { | 924 | { |
925 | at91_add_device_rtc(); | ||
926 | at91_add_device_rtt(); | ||
927 | at91_add_device_watchdog(); | ||
662 | return 0; | 928 | return 0; |
663 | } | 929 | } |
664 | 930 | ||
diff --git a/arch/arm/mach-at91/board-cap9adk.c b/arch/arm/mach-at91/board-cap9adk.c new file mode 100644 index 000000000000..185437131541 --- /dev/null +++ b/arch/arm/mach-at91/board-cap9adk.c | |||
@@ -0,0 +1,359 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-at91/board-cap9adk.c | ||
3 | * | ||
4 | * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com> | ||
5 | * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com> | ||
6 | * Copyright (C) 2005 SAN People | ||
7 | * Copyright (C) 2007 Atmel Corporation. | ||
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 | |||
24 | #include <linux/types.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/mm.h> | ||
27 | #include <linux/module.h> | ||
28 | #include <linux/platform_device.h> | ||
29 | #include <linux/spi/spi.h> | ||
30 | #include <linux/spi/ads7846.h> | ||
31 | #include <linux/fb.h> | ||
32 | #include <linux/mtd/physmap.h> | ||
33 | |||
34 | #include <video/atmel_lcdc.h> | ||
35 | |||
36 | #include <asm/hardware.h> | ||
37 | #include <asm/setup.h> | ||
38 | #include <asm/mach-types.h> | ||
39 | #include <asm/irq.h> | ||
40 | |||
41 | #include <asm/mach/arch.h> | ||
42 | #include <asm/mach/map.h> | ||
43 | #include <asm/mach/irq.h> | ||
44 | |||
45 | #include <asm/arch/board.h> | ||
46 | #include <asm/arch/gpio.h> | ||
47 | #include <asm/arch/at91cap9_matrix.h> | ||
48 | #include <asm/arch/at91sam926x_mc.h> | ||
49 | |||
50 | #include "generic.h" | ||
51 | |||
52 | |||
53 | static void __init cap9adk_map_io(void) | ||
54 | { | ||
55 | /* Initialize processor: 12 MHz crystal */ | ||
56 | at91cap9_initialize(12000000); | ||
57 | |||
58 | /* Setup the LEDs: USER1 and USER2 LED for cpu/timer... */ | ||
59 | at91_init_leds(AT91_PIN_PA10, AT91_PIN_PA11); | ||
60 | /* ... POWER LED always on */ | ||
61 | at91_set_gpio_output(AT91_PIN_PC29, 1); | ||
62 | |||
63 | /* Setup the serial ports and console */ | ||
64 | at91_register_uart(0, 0, 0); /* DBGU = ttyS0 */ | ||
65 | at91_set_serial_console(0); | ||
66 | } | ||
67 | |||
68 | static void __init cap9adk_init_irq(void) | ||
69 | { | ||
70 | at91cap9_init_interrupts(NULL); | ||
71 | } | ||
72 | |||
73 | |||
74 | /* | ||
75 | * USB Host port | ||
76 | */ | ||
77 | static struct at91_usbh_data __initdata cap9adk_usbh_data = { | ||
78 | .ports = 2, | ||
79 | }; | ||
80 | |||
81 | |||
82 | /* | ||
83 | * ADS7846 Touchscreen | ||
84 | */ | ||
85 | #if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) | ||
86 | static int ads7843_pendown_state(void) | ||
87 | { | ||
88 | return !at91_get_gpio_value(AT91_PIN_PC4); /* Touchscreen PENIRQ */ | ||
89 | } | ||
90 | |||
91 | static struct ads7846_platform_data ads_info = { | ||
92 | .model = 7843, | ||
93 | .x_min = 150, | ||
94 | .x_max = 3830, | ||
95 | .y_min = 190, | ||
96 | .y_max = 3830, | ||
97 | .vref_delay_usecs = 100, | ||
98 | .x_plate_ohms = 450, | ||
99 | .y_plate_ohms = 250, | ||
100 | .pressure_max = 15000, | ||
101 | .debounce_max = 1, | ||
102 | .debounce_rep = 0, | ||
103 | .debounce_tol = (~0), | ||
104 | .get_pendown_state = ads7843_pendown_state, | ||
105 | }; | ||
106 | |||
107 | static void __init cap9adk_add_device_ts(void) | ||
108 | { | ||
109 | at91_set_gpio_input(AT91_PIN_PC4, 1); /* Touchscreen PENIRQ */ | ||
110 | at91_set_gpio_input(AT91_PIN_PC5, 1); /* Touchscreen BUSY */ | ||
111 | } | ||
112 | #else | ||
113 | static void __init cap9adk_add_device_ts(void) {} | ||
114 | #endif | ||
115 | |||
116 | |||
117 | /* | ||
118 | * SPI devices. | ||
119 | */ | ||
120 | static struct spi_board_info cap9adk_spi_devices[] = { | ||
121 | #if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) | ||
122 | { /* DataFlash card */ | ||
123 | .modalias = "mtd_dataflash", | ||
124 | .chip_select = 0, | ||
125 | .max_speed_hz = 15 * 1000 * 1000, | ||
126 | .bus_num = 0, | ||
127 | }, | ||
128 | #endif | ||
129 | #if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) | ||
130 | { | ||
131 | .modalias = "ads7846", | ||
132 | .chip_select = 3, /* can be 2 or 3, depending on J2 jumper */ | ||
133 | .max_speed_hz = 125000 * 26, /* (max sample rate @ 3V) * (cmd + data + overhead) */ | ||
134 | .bus_num = 0, | ||
135 | .platform_data = &ads_info, | ||
136 | .irq = AT91_PIN_PC4, | ||
137 | }, | ||
138 | #endif | ||
139 | }; | ||
140 | |||
141 | |||
142 | /* | ||
143 | * MCI (SD/MMC) | ||
144 | */ | ||
145 | static struct at91_mmc_data __initdata cap9adk_mmc_data = { | ||
146 | .wire4 = 1, | ||
147 | // .det_pin = ... not connected | ||
148 | // .wp_pin = ... not connected | ||
149 | // .vcc_pin = ... not connected | ||
150 | }; | ||
151 | |||
152 | |||
153 | /* | ||
154 | * MACB Ethernet device | ||
155 | */ | ||
156 | static struct at91_eth_data __initdata cap9adk_macb_data = { | ||
157 | .is_rmii = 1, | ||
158 | }; | ||
159 | |||
160 | |||
161 | /* | ||
162 | * NAND flash | ||
163 | */ | ||
164 | static struct mtd_partition __initdata cap9adk_nand_partitions[] = { | ||
165 | { | ||
166 | .name = "NAND partition", | ||
167 | .offset = 0, | ||
168 | .size = MTDPART_SIZ_FULL, | ||
169 | }, | ||
170 | }; | ||
171 | |||
172 | static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) | ||
173 | { | ||
174 | *num_partitions = ARRAY_SIZE(cap9adk_nand_partitions); | ||
175 | return cap9adk_nand_partitions; | ||
176 | } | ||
177 | |||
178 | static struct at91_nand_data __initdata cap9adk_nand_data = { | ||
179 | .ale = 21, | ||
180 | .cle = 22, | ||
181 | // .det_pin = ... not connected | ||
182 | // .rdy_pin = ... not connected | ||
183 | .enable_pin = AT91_PIN_PD15, | ||
184 | .partition_info = nand_partitions, | ||
185 | #if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16) | ||
186 | .bus_width_16 = 1, | ||
187 | #else | ||
188 | .bus_width_16 = 0, | ||
189 | #endif | ||
190 | }; | ||
191 | |||
192 | |||
193 | /* | ||
194 | * NOR flash | ||
195 | */ | ||
196 | static struct mtd_partition cap9adk_nor_partitions[] = { | ||
197 | { | ||
198 | .name = "NOR partition", | ||
199 | .offset = 0, | ||
200 | .size = MTDPART_SIZ_FULL, | ||
201 | }, | ||
202 | }; | ||
203 | |||
204 | static struct physmap_flash_data cap9adk_nor_data = { | ||
205 | .width = 2, | ||
206 | .parts = cap9adk_nor_partitions, | ||
207 | .nr_parts = ARRAY_SIZE(cap9adk_nor_partitions), | ||
208 | }; | ||
209 | |||
210 | #define NOR_BASE AT91_CHIPSELECT_0 | ||
211 | #define NOR_SIZE 0x800000 | ||
212 | |||
213 | static struct resource nor_flash_resources[] = { | ||
214 | { | ||
215 | .start = NOR_BASE, | ||
216 | .end = NOR_BASE + NOR_SIZE - 1, | ||
217 | .flags = IORESOURCE_MEM, | ||
218 | } | ||
219 | }; | ||
220 | |||
221 | static struct platform_device cap9adk_nor_flash = { | ||
222 | .name = "physmap-flash", | ||
223 | .id = 0, | ||
224 | .dev = { | ||
225 | .platform_data = &cap9adk_nor_data, | ||
226 | }, | ||
227 | .resource = nor_flash_resources, | ||
228 | .num_resources = ARRAY_SIZE(nor_flash_resources), | ||
229 | }; | ||
230 | |||
231 | static __init void cap9adk_add_device_nor(void) | ||
232 | { | ||
233 | unsigned long csa; | ||
234 | |||
235 | csa = at91_sys_read(AT91_MATRIX_EBICSA); | ||
236 | at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_VDDIOMSEL_3_3V); | ||
237 | |||
238 | /* set the bus interface characteristics */ | ||
239 | at91_sys_write(AT91_SMC_SETUP(0), AT91_SMC_NWESETUP_(4) | AT91_SMC_NCS_WRSETUP_(2) | ||
240 | | AT91_SMC_NRDSETUP_(4) | AT91_SMC_NCS_RDSETUP_(2)); | ||
241 | |||
242 | at91_sys_write(AT91_SMC_PULSE(0), AT91_SMC_NWEPULSE_(8) | AT91_SMC_NCS_WRPULSE_(10) | ||
243 | | AT91_SMC_NRDPULSE_(8) | AT91_SMC_NCS_RDPULSE_(10)); | ||
244 | |||
245 | at91_sys_write(AT91_SMC_CYCLE(0), AT91_SMC_NWECYCLE_(16) | AT91_SMC_NRDCYCLE_(16)); | ||
246 | |||
247 | at91_sys_write(AT91_SMC_MODE(0), AT91_SMC_READMODE | AT91_SMC_WRITEMODE | ||
248 | | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE | ||
249 | | AT91_SMC_DBW_16 | AT91_SMC_TDF_(1)); | ||
250 | |||
251 | platform_device_register(&cap9adk_nor_flash); | ||
252 | } | ||
253 | |||
254 | |||
255 | /* | ||
256 | * LCD Controller | ||
257 | */ | ||
258 | #if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) | ||
259 | static struct fb_videomode at91_tft_vga_modes[] = { | ||
260 | { | ||
261 | .name = "TX09D50VM1CCA @ 60", | ||
262 | .refresh = 60, | ||
263 | .xres = 240, .yres = 320, | ||
264 | .pixclock = KHZ2PICOS(4965), | ||
265 | |||
266 | .left_margin = 1, .right_margin = 33, | ||
267 | .upper_margin = 1, .lower_margin = 0, | ||
268 | .hsync_len = 5, .vsync_len = 1, | ||
269 | |||
270 | .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
271 | .vmode = FB_VMODE_NONINTERLACED, | ||
272 | }, | ||
273 | }; | ||
274 | |||
275 | static struct fb_monspecs at91fb_default_monspecs = { | ||
276 | .manufacturer = "HIT", | ||
277 | .monitor = "TX09D70VM1CCA", | ||
278 | |||
279 | .modedb = at91_tft_vga_modes, | ||
280 | .modedb_len = ARRAY_SIZE(at91_tft_vga_modes), | ||
281 | .hfmin = 15000, | ||
282 | .hfmax = 64000, | ||
283 | .vfmin = 50, | ||
284 | .vfmax = 150, | ||
285 | }; | ||
286 | |||
287 | #define AT91CAP9_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \ | ||
288 | | ATMEL_LCDC_DISTYPE_TFT \ | ||
289 | | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE) | ||
290 | |||
291 | static void at91_lcdc_power_control(int on) | ||
292 | { | ||
293 | if (on) | ||
294 | at91_set_gpio_value(AT91_PIN_PC0, 0); /* power up */ | ||
295 | else | ||
296 | at91_set_gpio_value(AT91_PIN_PC0, 1); /* power down */ | ||
297 | } | ||
298 | |||
299 | /* Driver datas */ | ||
300 | static struct atmel_lcdfb_info __initdata cap9adk_lcdc_data = { | ||
301 | .default_bpp = 16, | ||
302 | .default_dmacon = ATMEL_LCDC_DMAEN, | ||
303 | .default_lcdcon2 = AT91CAP9_DEFAULT_LCDCON2, | ||
304 | .default_monspecs = &at91fb_default_monspecs, | ||
305 | .atmel_lcdfb_power_control = at91_lcdc_power_control, | ||
306 | .guard_time = 1, | ||
307 | }; | ||
308 | |||
309 | #else | ||
310 | static struct atmel_lcdfb_info __initdata cap9adk_lcdc_data; | ||
311 | #endif | ||
312 | |||
313 | |||
314 | /* | ||
315 | * AC97 | ||
316 | */ | ||
317 | static struct atmel_ac97_data cap9adk_ac97_data = { | ||
318 | // .reset_pin = ... not connected | ||
319 | }; | ||
320 | |||
321 | |||
322 | static void __init cap9adk_board_init(void) | ||
323 | { | ||
324 | /* Serial */ | ||
325 | at91_add_device_serial(); | ||
326 | /* USB Host */ | ||
327 | set_irq_type(AT91CAP9_ID_UHP, IRQT_HIGH); | ||
328 | at91_add_device_usbh(&cap9adk_usbh_data); | ||
329 | /* SPI */ | ||
330 | at91_add_device_spi(cap9adk_spi_devices, ARRAY_SIZE(cap9adk_spi_devices)); | ||
331 | /* Touchscreen */ | ||
332 | cap9adk_add_device_ts(); | ||
333 | /* MMC */ | ||
334 | at91_add_device_mmc(1, &cap9adk_mmc_data); | ||
335 | /* Ethernet */ | ||
336 | at91_add_device_eth(&cap9adk_macb_data); | ||
337 | /* NAND */ | ||
338 | at91_add_device_nand(&cap9adk_nand_data); | ||
339 | /* NOR Flash */ | ||
340 | cap9adk_add_device_nor(); | ||
341 | /* I2C */ | ||
342 | at91_add_device_i2c(NULL, 0); | ||
343 | /* LCD Controller */ | ||
344 | set_irq_type(AT91CAP9_ID_LCDC, IRQT_HIGH); | ||
345 | at91_add_device_lcdc(&cap9adk_lcdc_data); | ||
346 | /* AC97 */ | ||
347 | at91_add_device_ac97(&cap9adk_ac97_data); | ||
348 | } | ||
349 | |||
350 | MACHINE_START(AT91CAP9ADK, "Atmel AT91CAP9A-DK") | ||
351 | /* Maintainer: Stelian Pop <stelian.pop@leadtechdesign.com> */ | ||
352 | .phys_io = AT91_BASE_SYS, | ||
353 | .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, | ||
354 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
355 | .timer = &at91sam926x_timer, | ||
356 | .map_io = cap9adk_map_io, | ||
357 | .init_irq = cap9adk_init_irq, | ||
358 | .init_machine = cap9adk_board_init, | ||
359 | MACHINE_END | ||
diff --git a/arch/arm/mach-at91/board-csb337.c b/arch/arm/mach-at91/board-csb337.c index d0aa20c9383e..0e2a11fc5bbd 100644 --- a/arch/arm/mach-at91/board-csb337.c +++ b/arch/arm/mach-at91/board-csb337.c | |||
@@ -25,6 +25,8 @@ | |||
25 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
26 | #include <linux/spi/spi.h> | 26 | #include <linux/spi/spi.h> |
27 | #include <linux/mtd/physmap.h> | 27 | #include <linux/mtd/physmap.h> |
28 | #include <linux/input.h> | ||
29 | #include <linux/gpio_keys.h> | ||
28 | 30 | ||
29 | #include <asm/hardware.h> | 31 | #include <asm/hardware.h> |
30 | #include <asm/setup.h> | 32 | #include <asm/setup.h> |
@@ -156,6 +158,85 @@ static struct platform_device csb_flash = { | |||
156 | .num_resources = ARRAY_SIZE(csb_flash_resources), | 158 | .num_resources = ARRAY_SIZE(csb_flash_resources), |
157 | }; | 159 | }; |
158 | 160 | ||
161 | /* | ||
162 | * GPIO Buttons (on CSB300) | ||
163 | */ | ||
164 | #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) | ||
165 | static struct gpio_keys_button csb300_buttons[] = { | ||
166 | { | ||
167 | .gpio = AT91_PIN_PB29, | ||
168 | .code = BTN_0, | ||
169 | .desc = "sw0", | ||
170 | .active_low = 1, | ||
171 | .wakeup = 1, | ||
172 | }, | ||
173 | { | ||
174 | .gpio = AT91_PIN_PB28, | ||
175 | .code = BTN_1, | ||
176 | .desc = "sw1", | ||
177 | .active_low = 1, | ||
178 | .wakeup = 1, | ||
179 | }, | ||
180 | { | ||
181 | .gpio = AT91_PIN_PA21, | ||
182 | .code = BTN_2, | ||
183 | .desc = "sw2", | ||
184 | .active_low = 1, | ||
185 | .wakeup = 1, | ||
186 | } | ||
187 | }; | ||
188 | |||
189 | static struct gpio_keys_platform_data csb300_button_data = { | ||
190 | .buttons = csb300_buttons, | ||
191 | .nbuttons = ARRAY_SIZE(csb300_buttons), | ||
192 | }; | ||
193 | |||
194 | static struct platform_device csb300_button_device = { | ||
195 | .name = "gpio-keys", | ||
196 | .id = -1, | ||
197 | .num_resources = 0, | ||
198 | .dev = { | ||
199 | .platform_data = &csb300_button_data, | ||
200 | } | ||
201 | }; | ||
202 | |||
203 | static void __init csb300_add_device_buttons(void) | ||
204 | { | ||
205 | at91_set_gpio_input(AT91_PIN_PB29, 0); /* sw0 */ | ||
206 | at91_set_deglitch(AT91_PIN_PB29, 1); | ||
207 | at91_set_gpio_input(AT91_PIN_PB28, 0); /* sw1 */ | ||
208 | at91_set_deglitch(AT91_PIN_PB28, 1); | ||
209 | at91_set_gpio_input(AT91_PIN_PA21, 0); /* sw2 */ | ||
210 | at91_set_deglitch(AT91_PIN_PA21, 1); | ||
211 | |||
212 | platform_device_register(&csb300_button_device); | ||
213 | } | ||
214 | #else | ||
215 | static void __init csb300_add_device_buttons(void) {} | ||
216 | #endif | ||
217 | |||
218 | static struct gpio_led csb_leds[] = { | ||
219 | { /* "led0", yellow */ | ||
220 | .name = "led0", | ||
221 | .gpio = AT91_PIN_PB2, | ||
222 | .active_low = 1, | ||
223 | .default_trigger = "heartbeat", | ||
224 | }, | ||
225 | { /* "led1", green */ | ||
226 | .name = "led1", | ||
227 | .gpio = AT91_PIN_PB1, | ||
228 | .active_low = 1, | ||
229 | .default_trigger = "mmc0", | ||
230 | }, | ||
231 | { /* "led2", yellow */ | ||
232 | .name = "led2", | ||
233 | .gpio = AT91_PIN_PB0, | ||
234 | .active_low = 1, | ||
235 | .default_trigger = "ide-disk", | ||
236 | }, | ||
237 | }; | ||
238 | |||
239 | |||
159 | static void __init csb337_board_init(void) | 240 | static void __init csb337_board_init(void) |
160 | { | 241 | { |
161 | /* Serial */ | 242 | /* Serial */ |
@@ -177,6 +258,10 @@ static void __init csb337_board_init(void) | |||
177 | at91_add_device_mmc(0, &csb337_mmc_data); | 258 | at91_add_device_mmc(0, &csb337_mmc_data); |
178 | /* NOR flash */ | 259 | /* NOR flash */ |
179 | platform_device_register(&csb_flash); | 260 | platform_device_register(&csb_flash); |
261 | /* LEDs */ | ||
262 | at91_gpio_leds(csb_leds, ARRAY_SIZE(csb_leds)); | ||
263 | /* Switches on CSB300 */ | ||
264 | csb300_add_device_buttons(); | ||
180 | } | 265 | } |
181 | 266 | ||
182 | MACHINE_START(CSB337, "Cogent CSB337") | 267 | MACHINE_START(CSB337, "Cogent CSB337") |
diff --git a/arch/arm/mach-at91/board-dk.c b/arch/arm/mach-at91/board-dk.c index 40c9e4331706..0a897efeba8e 100644 --- a/arch/arm/mach-at91/board-dk.c +++ b/arch/arm/mach-at91/board-dk.c | |||
@@ -183,6 +183,14 @@ static struct platform_device dk_flash = { | |||
183 | .num_resources = 1, | 183 | .num_resources = 1, |
184 | }; | 184 | }; |
185 | 185 | ||
186 | static struct gpio_led dk_leds[] = { | ||
187 | { | ||
188 | .name = "led0", | ||
189 | .gpio = AT91_PIN_PB2, | ||
190 | .active_low = 1, | ||
191 | .default_trigger = "heartbeat", | ||
192 | } | ||
193 | }; | ||
186 | 194 | ||
187 | static void __init dk_board_init(void) | 195 | static void __init dk_board_init(void) |
188 | { | 196 | { |
@@ -213,6 +221,8 @@ static void __init dk_board_init(void) | |||
213 | at91_add_device_nand(&dk_nand_data); | 221 | at91_add_device_nand(&dk_nand_data); |
214 | /* NOR Flash */ | 222 | /* NOR Flash */ |
215 | platform_device_register(&dk_flash); | 223 | platform_device_register(&dk_flash); |
224 | /* LEDs */ | ||
225 | at91_gpio_leds(dk_leds, ARRAY_SIZE(dk_leds)); | ||
216 | /* VGA */ | 226 | /* VGA */ |
217 | // dk_add_device_video(); | 227 | // dk_add_device_video(); |
218 | } | 228 | } |
diff --git a/arch/arm/mach-at91/board-ek.c b/arch/arm/mach-at91/board-ek.c index 53a5ef9e72ee..0574e50a30dd 100644 --- a/arch/arm/mach-at91/board-ek.c +++ b/arch/arm/mach-at91/board-ek.c | |||
@@ -141,6 +141,25 @@ static struct platform_device ek_flash = { | |||
141 | .num_resources = 1, | 141 | .num_resources = 1, |
142 | }; | 142 | }; |
143 | 143 | ||
144 | static struct gpio_led ek_leds[] = { | ||
145 | { /* "user led 1", DS2 */ | ||
146 | .name = "green", | ||
147 | .gpio = AT91_PIN_PB0, | ||
148 | .active_low = 1, | ||
149 | .default_trigger = "mmc0", | ||
150 | }, | ||
151 | { /* "user led 2", DS4 */ | ||
152 | .name = "yellow", | ||
153 | .gpio = AT91_PIN_PB1, | ||
154 | .active_low = 1, | ||
155 | .default_trigger = "heartbeat", | ||
156 | }, | ||
157 | { /* "user led 3", DS6 */ | ||
158 | .name = "red", | ||
159 | .gpio = AT91_PIN_PB2, | ||
160 | .active_low = 1, | ||
161 | } | ||
162 | }; | ||
144 | 163 | ||
145 | static void __init ek_board_init(void) | 164 | static void __init ek_board_init(void) |
146 | { | 165 | { |
@@ -167,6 +186,8 @@ static void __init ek_board_init(void) | |||
167 | #endif | 186 | #endif |
168 | /* NOR Flash */ | 187 | /* NOR Flash */ |
169 | platform_device_register(&ek_flash); | 188 | platform_device_register(&ek_flash); |
189 | /* LEDs */ | ||
190 | at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); | ||
170 | /* VGA */ | 191 | /* VGA */ |
171 | // ek_add_device_video(); | 192 | // ek_add_device_video(); |
172 | } | 193 | } |
diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c index 550ae59a3aca..aa29ea58ca09 100644 --- a/arch/arm/mach-at91/board-sam9261ek.c +++ b/arch/arm/mach-at91/board-sam9261ek.c | |||
@@ -280,6 +280,68 @@ static struct spi_board_info ek_spi_devices[] = { | |||
280 | * LCD Controller | 280 | * LCD Controller |
281 | */ | 281 | */ |
282 | #if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) | 282 | #if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) |
283 | |||
284 | #if defined(CONFIG_FB_ATMEL_STN) | ||
285 | |||
286 | /* STN */ | ||
287 | static struct fb_videomode at91_stn_modes[] = { | ||
288 | { | ||
289 | .name = "SP06Q002 @ 75", | ||
290 | .refresh = 75, | ||
291 | .xres = 320, .yres = 240, | ||
292 | .pixclock = KHZ2PICOS(1440), | ||
293 | |||
294 | .left_margin = 1, .right_margin = 1, | ||
295 | .upper_margin = 0, .lower_margin = 0, | ||
296 | .hsync_len = 1, .vsync_len = 1, | ||
297 | |||
298 | .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
299 | .vmode = FB_VMODE_NONINTERLACED, | ||
300 | }, | ||
301 | }; | ||
302 | |||
303 | static struct fb_monspecs at91fb_default_stn_monspecs = { | ||
304 | .manufacturer = "HIT", | ||
305 | .monitor = "SP06Q002", | ||
306 | |||
307 | .modedb = at91_stn_modes, | ||
308 | .modedb_len = ARRAY_SIZE(at91_stn_modes), | ||
309 | .hfmin = 15000, | ||
310 | .hfmax = 64000, | ||
311 | .vfmin = 50, | ||
312 | .vfmax = 150, | ||
313 | }; | ||
314 | |||
315 | #define AT91SAM9261_DEFAULT_STN_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \ | ||
316 | | ATMEL_LCDC_DISTYPE_STNMONO \ | ||
317 | | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE \ | ||
318 | | ATMEL_LCDC_IFWIDTH_4 \ | ||
319 | | ATMEL_LCDC_SCANMOD_SINGLE) | ||
320 | |||
321 | static void at91_lcdc_stn_power_control(int on) | ||
322 | { | ||
323 | /* backlight */ | ||
324 | if (on) { /* power up */ | ||
325 | at91_set_gpio_value(AT91_PIN_PC14, 0); | ||
326 | at91_set_gpio_value(AT91_PIN_PC15, 0); | ||
327 | } else { /* power down */ | ||
328 | at91_set_gpio_value(AT91_PIN_PC14, 1); | ||
329 | at91_set_gpio_value(AT91_PIN_PC15, 1); | ||
330 | } | ||
331 | } | ||
332 | |||
333 | static struct atmel_lcdfb_info __initdata ek_lcdc_data = { | ||
334 | .default_bpp = 1, | ||
335 | .default_dmacon = ATMEL_LCDC_DMAEN, | ||
336 | .default_lcdcon2 = AT91SAM9261_DEFAULT_STN_LCDCON2, | ||
337 | .default_monspecs = &at91fb_default_stn_monspecs, | ||
338 | .atmel_lcdfb_power_control = at91_lcdc_stn_power_control, | ||
339 | .guard_time = 1, | ||
340 | }; | ||
341 | |||
342 | #else | ||
343 | |||
344 | /* TFT */ | ||
283 | static struct fb_videomode at91_tft_vga_modes[] = { | 345 | static struct fb_videomode at91_tft_vga_modes[] = { |
284 | { | 346 | { |
285 | .name = "TX09D50VM1CCA @ 60", | 347 | .name = "TX09D50VM1CCA @ 60", |
@@ -296,7 +358,7 @@ static struct fb_videomode at91_tft_vga_modes[] = { | |||
296 | }, | 358 | }, |
297 | }; | 359 | }; |
298 | 360 | ||
299 | static struct fb_monspecs at91fb_default_monspecs = { | 361 | static struct fb_monspecs at91fb_default_tft_monspecs = { |
300 | .manufacturer = "HIT", | 362 | .manufacturer = "HIT", |
301 | .monitor = "TX09D50VM1CCA", | 363 | .monitor = "TX09D50VM1CCA", |
302 | 364 | ||
@@ -308,11 +370,11 @@ static struct fb_monspecs at91fb_default_monspecs = { | |||
308 | .vfmax = 150, | 370 | .vfmax = 150, |
309 | }; | 371 | }; |
310 | 372 | ||
311 | #define AT91SAM9261_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \ | 373 | #define AT91SAM9261_DEFAULT_TFT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \ |
312 | | ATMEL_LCDC_DISTYPE_TFT \ | 374 | | ATMEL_LCDC_DISTYPE_TFT \ |
313 | | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE) | 375 | | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE) |
314 | 376 | ||
315 | static void at91_lcdc_power_control(int on) | 377 | static void at91_lcdc_tft_power_control(int on) |
316 | { | 378 | { |
317 | if (on) | 379 | if (on) |
318 | at91_set_gpio_value(AT91_PIN_PA12, 0); /* power up */ | 380 | at91_set_gpio_value(AT91_PIN_PA12, 0); /* power up */ |
@@ -320,15 +382,15 @@ static void at91_lcdc_power_control(int on) | |||
320 | at91_set_gpio_value(AT91_PIN_PA12, 1); /* power down */ | 382 | at91_set_gpio_value(AT91_PIN_PA12, 1); /* power down */ |
321 | } | 383 | } |
322 | 384 | ||
323 | /* Driver datas */ | ||
324 | static struct atmel_lcdfb_info __initdata ek_lcdc_data = { | 385 | static struct atmel_lcdfb_info __initdata ek_lcdc_data = { |
325 | .default_bpp = 16, | 386 | .default_bpp = 16, |
326 | .default_dmacon = ATMEL_LCDC_DMAEN, | 387 | .default_dmacon = ATMEL_LCDC_DMAEN, |
327 | .default_lcdcon2 = AT91SAM9261_DEFAULT_LCDCON2, | 388 | .default_lcdcon2 = AT91SAM9261_DEFAULT_TFT_LCDCON2, |
328 | .default_monspecs = &at91fb_default_monspecs, | 389 | .default_monspecs = &at91fb_default_tft_monspecs, |
329 | .atmel_lcdfb_power_control = at91_lcdc_power_control, | 390 | .atmel_lcdfb_power_control = at91_lcdc_tft_power_control, |
330 | .guard_time = 1, | 391 | .guard_time = 1, |
331 | }; | 392 | }; |
393 | #endif | ||
332 | 394 | ||
333 | #else | 395 | #else |
334 | static struct atmel_lcdfb_info __initdata ek_lcdc_data; | 396 | static struct atmel_lcdfb_info __initdata ek_lcdc_data; |
@@ -342,25 +404,25 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data; | |||
342 | static struct gpio_keys_button ek_buttons[] = { | 404 | static struct gpio_keys_button ek_buttons[] = { |
343 | { | 405 | { |
344 | .gpio = AT91_PIN_PA27, | 406 | .gpio = AT91_PIN_PA27, |
345 | .keycode = BTN_0, | 407 | .code = BTN_0, |
346 | .desc = "Button 0", | 408 | .desc = "Button 0", |
347 | .active_low = 1, | 409 | .active_low = 1, |
348 | }, | 410 | }, |
349 | { | 411 | { |
350 | .gpio = AT91_PIN_PA26, | 412 | .gpio = AT91_PIN_PA26, |
351 | .keycode = BTN_1, | 413 | .code = BTN_1, |
352 | .desc = "Button 1", | 414 | .desc = "Button 1", |
353 | .active_low = 1, | 415 | .active_low = 1, |
354 | }, | 416 | }, |
355 | { | 417 | { |
356 | .gpio = AT91_PIN_PA25, | 418 | .gpio = AT91_PIN_PA25, |
357 | .keycode = BTN_2, | 419 | .code = BTN_2, |
358 | .desc = "Button 2", | 420 | .desc = "Button 2", |
359 | .active_low = 1, | 421 | .active_low = 1, |
360 | }, | 422 | }, |
361 | { | 423 | { |
362 | .gpio = AT91_PIN_PA24, | 424 | .gpio = AT91_PIN_PA24, |
363 | .keycode = BTN_3, | 425 | .code = BTN_3, |
364 | .desc = "Button 3", | 426 | .desc = "Button 3", |
365 | .active_low = 1, | 427 | .active_low = 1, |
366 | } | 428 | } |
diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c index ab9dcc075454..f09347a86e71 100644 --- a/arch/arm/mach-at91/board-sam9263ek.c +++ b/arch/arm/mach-at91/board-sam9263ek.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/spi/spi.h> | 27 | #include <linux/spi/spi.h> |
28 | #include <linux/spi/ads7846.h> | 28 | #include <linux/spi/ads7846.h> |
29 | #include <linux/fb.h> | 29 | #include <linux/fb.h> |
30 | #include <linux/gpio_keys.h> | ||
31 | #include <linux/input.h> | ||
30 | 32 | ||
31 | #include <video/atmel_lcdc.h> | 33 | #include <video/atmel_lcdc.h> |
32 | 34 | ||
@@ -163,6 +165,7 @@ static struct at91_mmc_data __initdata ek_mmc_data = { | |||
163 | * MACB Ethernet device | 165 | * MACB Ethernet device |
164 | */ | 166 | */ |
165 | static struct at91_eth_data __initdata ek_macb_data = { | 167 | static struct at91_eth_data __initdata ek_macb_data = { |
168 | .phy_irq_pin = AT91_PIN_PE31, | ||
166 | .is_rmii = 1, | 169 | .is_rmii = 1, |
167 | }; | 170 | }; |
168 | 171 | ||
@@ -264,6 +267,55 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data; | |||
264 | 267 | ||
265 | 268 | ||
266 | /* | 269 | /* |
270 | * GPIO Buttons | ||
271 | */ | ||
272 | #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) | ||
273 | static struct gpio_keys_button ek_buttons[] = { | ||
274 | { /* BP1, "leftclic" */ | ||
275 | .code = BTN_LEFT, | ||
276 | .gpio = AT91_PIN_PC5, | ||
277 | .active_low = 1, | ||
278 | .desc = "left_click", | ||
279 | .wakeup = 1, | ||
280 | }, | ||
281 | { /* BP2, "rightclic" */ | ||
282 | .code = BTN_RIGHT, | ||
283 | .gpio = AT91_PIN_PC4, | ||
284 | .active_low = 1, | ||
285 | .desc = "right_click", | ||
286 | .wakeup = 1, | ||
287 | }, | ||
288 | }; | ||
289 | |||
290 | static struct gpio_keys_platform_data ek_button_data = { | ||
291 | .buttons = ek_buttons, | ||
292 | .nbuttons = ARRAY_SIZE(ek_buttons), | ||
293 | }; | ||
294 | |||
295 | static struct platform_device ek_button_device = { | ||
296 | .name = "gpio-keys", | ||
297 | .id = -1, | ||
298 | .num_resources = 0, | ||
299 | .dev = { | ||
300 | .platform_data = &ek_button_data, | ||
301 | } | ||
302 | }; | ||
303 | |||
304 | static void __init ek_add_device_buttons(void) | ||
305 | { | ||
306 | at91_set_GPIO_periph(AT91_PIN_PC5, 0); /* left button */ | ||
307 | at91_set_deglitch(AT91_PIN_PC5, 1); | ||
308 | at91_set_GPIO_periph(AT91_PIN_PC4, 0); /* right button */ | ||
309 | at91_set_deglitch(AT91_PIN_PC4, 1); | ||
310 | |||
311 | platform_device_register(&ek_button_device); | ||
312 | } | ||
313 | #else | ||
314 | static void __init ek_add_device_buttons(void) {} | ||
315 | #endif | ||
316 | |||
317 | |||
318 | /* | ||
267 | * AC97 | 319 | * AC97 |
268 | */ | 320 | */ |
269 | static struct atmel_ac97_data ek_ac97_data = { | 321 | static struct atmel_ac97_data ek_ac97_data = { |
@@ -271,6 +323,30 @@ static struct atmel_ac97_data ek_ac97_data = { | |||
271 | }; | 323 | }; |
272 | 324 | ||
273 | 325 | ||
326 | /* | ||
327 | * LEDs ... these could all be PWM-driven, for variable brightness | ||
328 | */ | ||
329 | static struct gpio_led ek_leds[] = { | ||
330 | { /* "left" led, green, userled1, pwm1 */ | ||
331 | .name = "ds1", | ||
332 | .gpio = AT91_PIN_PB8, | ||
333 | .active_low = 1, | ||
334 | .default_trigger = "mmc0", | ||
335 | }, | ||
336 | { /* "right" led, green, userled2, pwm2 */ | ||
337 | .name = "ds2", | ||
338 | .gpio = AT91_PIN_PC29, | ||
339 | .active_low = 1, | ||
340 | .default_trigger = "nand-disk", | ||
341 | }, | ||
342 | { /* "power" led, yellow, pwm0 */ | ||
343 | .name = "ds3", | ||
344 | .gpio = AT91_PIN_PB7, | ||
345 | .default_trigger = "heartbeat", | ||
346 | }, | ||
347 | }; | ||
348 | |||
349 | |||
274 | static void __init ek_board_init(void) | 350 | static void __init ek_board_init(void) |
275 | { | 351 | { |
276 | /* Serial */ | 352 | /* Serial */ |
@@ -294,8 +370,12 @@ static void __init ek_board_init(void) | |||
294 | at91_add_device_i2c(NULL, 0); | 370 | at91_add_device_i2c(NULL, 0); |
295 | /* LCD Controller */ | 371 | /* LCD Controller */ |
296 | at91_add_device_lcdc(&ek_lcdc_data); | 372 | at91_add_device_lcdc(&ek_lcdc_data); |
373 | /* Push Buttons */ | ||
374 | ek_add_device_buttons(); | ||
297 | /* AC97 */ | 375 | /* AC97 */ |
298 | at91_add_device_ac97(&ek_ac97_data); | 376 | at91_add_device_ac97(&ek_ac97_data); |
377 | /* LEDs */ | ||
378 | at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); | ||
299 | } | 379 | } |
300 | 380 | ||
301 | MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK") | 381 | MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK") |
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index 57c3b647ce83..ec76eeaafd45 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c | |||
@@ -574,6 +574,8 @@ int __init at91_clock_init(unsigned long main_clock) | |||
574 | } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263()) { | 574 | } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263()) { |
575 | uhpck.pmc_mask = AT91SAM926x_PMC_UHP; | 575 | uhpck.pmc_mask = AT91SAM926x_PMC_UHP; |
576 | udpck.pmc_mask = AT91SAM926x_PMC_UDP; | 576 | udpck.pmc_mask = AT91SAM926x_PMC_UDP; |
577 | } else if (cpu_is_at91cap9()) { | ||
578 | uhpck.pmc_mask = AT91CAP9_PMC_UHP; | ||
577 | } | 579 | } |
578 | at91_sys_write(AT91_CKGR_PLLBR, 0); | 580 | at91_sys_write(AT91_CKGR_PLLBR, 0); |
579 | 581 | ||
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h index 77d4c0a37842..b5daf7f5e011 100644 --- a/arch/arm/mach-at91/generic.h +++ b/arch/arm/mach-at91/generic.h | |||
@@ -15,6 +15,7 @@ extern void __init at91sam9261_initialize(unsigned long main_clock); | |||
15 | extern void __init at91sam9263_initialize(unsigned long main_clock); | 15 | extern void __init at91sam9263_initialize(unsigned long main_clock); |
16 | extern void __init at91sam9rl_initialize(unsigned long main_clock); | 16 | extern void __init at91sam9rl_initialize(unsigned long main_clock); |
17 | extern void __init at91x40_initialize(unsigned long main_clock); | 17 | extern void __init at91x40_initialize(unsigned long main_clock); |
18 | extern void __init at91cap9_initialize(unsigned long main_clock); | ||
18 | 19 | ||
19 | /* Interrupts */ | 20 | /* Interrupts */ |
20 | extern void __init at91rm9200_init_interrupts(unsigned int priority[]); | 21 | extern void __init at91rm9200_init_interrupts(unsigned int priority[]); |
@@ -23,6 +24,7 @@ extern void __init at91sam9261_init_interrupts(unsigned int priority[]); | |||
23 | extern void __init at91sam9263_init_interrupts(unsigned int priority[]); | 24 | extern void __init at91sam9263_init_interrupts(unsigned int priority[]); |
24 | extern void __init at91sam9rl_init_interrupts(unsigned int priority[]); | 25 | extern void __init at91sam9rl_init_interrupts(unsigned int priority[]); |
25 | extern void __init at91x40_init_interrupts(unsigned int priority[]); | 26 | extern void __init at91x40_init_interrupts(unsigned int priority[]); |
27 | extern void __init at91cap9_init_interrupts(unsigned int priority[]); | ||
26 | extern void __init at91_aic_init(unsigned int priority[]); | 28 | extern void __init at91_aic_init(unsigned int priority[]); |
27 | 29 | ||
28 | /* Timer */ | 30 | /* Timer */ |
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c index aa2d365c93fb..6aeddd68d8af 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c | |||
@@ -13,6 +13,8 @@ | |||
13 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
14 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
15 | #include <linux/irq.h> | 15 | #include <linux/irq.h> |
16 | #include <linux/debugfs.h> | ||
17 | #include <linux/seq_file.h> | ||
16 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
17 | #include <linux/list.h> | 19 | #include <linux/list.h> |
18 | #include <linux/module.h> | 20 | #include <linux/module.h> |
@@ -414,6 +416,66 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) | |||
414 | 416 | ||
415 | /*--------------------------------------------------------------------------*/ | 417 | /*--------------------------------------------------------------------------*/ |
416 | 418 | ||
419 | #ifdef CONFIG_DEBUG_FS | ||
420 | |||
421 | static int at91_gpio_show(struct seq_file *s, void *unused) | ||
422 | { | ||
423 | int bank, j; | ||
424 | |||
425 | /* print heading */ | ||
426 | seq_printf(s, "Pin\t"); | ||
427 | for (bank = 0; bank < gpio_banks; bank++) { | ||
428 | seq_printf(s, "PIO%c\t", 'A' + bank); | ||
429 | }; | ||
430 | seq_printf(s, "\n\n"); | ||
431 | |||
432 | /* print pin status */ | ||
433 | for (j = 0; j < 32; j++) { | ||
434 | seq_printf(s, "%i:\t", j); | ||
435 | |||
436 | for (bank = 0; bank < gpio_banks; bank++) { | ||
437 | unsigned pin = PIN_BASE + (32 * bank) + j; | ||
438 | void __iomem *pio = pin_to_controller(pin); | ||
439 | unsigned mask = pin_to_mask(pin); | ||
440 | |||
441 | if (__raw_readl(pio + PIO_PSR) & mask) | ||
442 | seq_printf(s, "GPIO:%s", __raw_readl(pio + PIO_PDSR) & mask ? "1" : "0"); | ||
443 | else | ||
444 | seq_printf(s, "%s", __raw_readl(pio + PIO_ABSR) & mask ? "B" : "A"); | ||
445 | |||
446 | seq_printf(s, "\t"); | ||
447 | } | ||
448 | |||
449 | seq_printf(s, "\n"); | ||
450 | } | ||
451 | |||
452 | return 0; | ||
453 | } | ||
454 | |||
455 | static int at91_gpio_open(struct inode *inode, struct file *file) | ||
456 | { | ||
457 | return single_open(file, at91_gpio_show, NULL); | ||
458 | } | ||
459 | |||
460 | static const struct file_operations at91_gpio_operations = { | ||
461 | .open = at91_gpio_open, | ||
462 | .read = seq_read, | ||
463 | .llseek = seq_lseek, | ||
464 | .release = single_release, | ||
465 | }; | ||
466 | |||
467 | static int __init at91_gpio_debugfs_init(void) | ||
468 | { | ||
469 | /* /sys/kernel/debug/at91_gpio */ | ||
470 | (void) debugfs_create_file("at91_gpio", S_IFREG | S_IRUGO, NULL, NULL, &at91_gpio_operations); | ||
471 | return 0; | ||
472 | } | ||
473 | postcore_initcall(at91_gpio_debugfs_init); | ||
474 | |||
475 | #endif | ||
476 | |||
477 | /*--------------------------------------------------------------------------*/ | ||
478 | |||
417 | /* | 479 | /* |
418 | * Called from the processor-specific init to enable GPIO interrupt support. | 480 | * Called from the processor-specific init to enable GPIO interrupt support. |
419 | */ | 481 | */ |
diff --git a/arch/arm/mach-at91/leds.c b/arch/arm/mach-at91/leds.c index 0d5144973988..9cdcda500fe8 100644 --- a/arch/arm/mach-at91/leds.c +++ b/arch/arm/mach-at91/leds.c | |||
@@ -14,11 +14,62 @@ | |||
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | 15 | ||
16 | #include <asm/mach-types.h> | 16 | #include <asm/mach-types.h> |
17 | #include <asm/leds.h> | ||
18 | #include <asm/arch/board.h> | 17 | #include <asm/arch/board.h> |
19 | #include <asm/arch/gpio.h> | 18 | #include <asm/arch/gpio.h> |
20 | 19 | ||
21 | 20 | ||
21 | /* ------------------------------------------------------------------------- */ | ||
22 | |||
23 | #if defined(CONFIG_NEW_LEDS) | ||
24 | |||
25 | #include <linux/platform_device.h> | ||
26 | |||
27 | /* | ||
28 | * New cross-platform LED support. | ||
29 | */ | ||
30 | |||
31 | static struct gpio_led_platform_data led_data; | ||
32 | |||
33 | static struct platform_device at91_leds = { | ||
34 | .name = "leds-gpio", | ||
35 | .id = -1, | ||
36 | .dev.platform_data = &led_data, | ||
37 | }; | ||
38 | |||
39 | void __init at91_gpio_leds(struct gpio_led *leds, int nr) | ||
40 | { | ||
41 | int i; | ||
42 | |||
43 | if (!nr) | ||
44 | return; | ||
45 | |||
46 | for (i = 0; i < nr; i++) | ||
47 | at91_set_gpio_output(leds[i].gpio, leds[i].active_low); | ||
48 | |||
49 | led_data.leds = leds; | ||
50 | led_data.num_leds = nr; | ||
51 | platform_device_register(&at91_leds); | ||
52 | } | ||
53 | |||
54 | #else | ||
55 | void __init at91_gpio_leds(struct gpio_led *leds, int nr) {} | ||
56 | #endif | ||
57 | |||
58 | |||
59 | /* ------------------------------------------------------------------------- */ | ||
60 | |||
61 | #if defined(CONFIG_LEDS) | ||
62 | |||
63 | #include <asm/leds.h> | ||
64 | |||
65 | /* | ||
66 | * Old ARM-specific LED framework; not fully functional when generic time is | ||
67 | * in use. | ||
68 | */ | ||
69 | |||
70 | static u8 at91_leds_cpu; | ||
71 | static u8 at91_leds_timer; | ||
72 | |||
22 | static inline void at91_led_on(unsigned int led) | 73 | static inline void at91_led_on(unsigned int led) |
23 | { | 74 | { |
24 | at91_set_gpio_value(led, 0); | 75 | at91_set_gpio_value(led, 0); |
@@ -93,3 +144,18 @@ static int __init leds_init(void) | |||
93 | } | 144 | } |
94 | 145 | ||
95 | __initcall(leds_init); | 146 | __initcall(leds_init); |
147 | |||
148 | |||
149 | void __init at91_init_leds(u8 cpu_led, u8 timer_led) | ||
150 | { | ||
151 | /* Enable GPIO to access the LEDs */ | ||
152 | at91_set_gpio_output(cpu_led, 1); | ||
153 | at91_set_gpio_output(timer_led, 1); | ||
154 | |||
155 | at91_leds_cpu = cpu_led; | ||
156 | at91_leds_timer = timer_led; | ||
157 | } | ||
158 | |||
159 | #else | ||
160 | void __init at91_init_leds(u8 cpu_led, u8 timer_led) {} | ||
161 | #endif | ||
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 98cb61482917..4b120cc36135 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c | |||
@@ -80,6 +80,11 @@ static int at91_pm_verify_clocks(void) | |||
80 | pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n"); | 80 | pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n"); |
81 | return 0; | 81 | return 0; |
82 | } | 82 | } |
83 | } else if (cpu_is_at91cap9()) { | ||
84 | if ((scsr & AT91CAP9_PMC_UHP) != 0) { | ||
85 | pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n"); | ||
86 | return 0; | ||
87 | } | ||
83 | } | 88 | } |
84 | 89 | ||
85 | #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS | 90 | #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS |
diff --git a/arch/arm/mach-clps711x/time.c b/arch/arm/mach-clps711x/time.c index f428af7545b4..e5dc33f1f95c 100644 --- a/arch/arm/mach-clps711x/time.c +++ b/arch/arm/mach-clps711x/time.c | |||
@@ -50,9 +50,7 @@ static unsigned long clps711x_gettimeoffset(void) | |||
50 | static irqreturn_t | 50 | static irqreturn_t |
51 | p720t_timer_interrupt(int irq, void *dev_id) | 51 | p720t_timer_interrupt(int irq, void *dev_id) |
52 | { | 52 | { |
53 | write_seqlock(&xtime_lock); | ||
54 | timer_tick(); | 53 | timer_tick(); |
55 | write_sequnlock(&xtime_lock); | ||
56 | return IRQ_HANDLED; | 54 | return IRQ_HANDLED; |
57 | } | 55 | } |
58 | 56 | ||
diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c index 986205ec9269..2ac63671ea5f 100644 --- a/arch/arm/mach-clps7500/core.c +++ b/arch/arm/mach-clps7500/core.c | |||
@@ -298,8 +298,6 @@ extern unsigned long ioc_timer_gettimeoffset(void); | |||
298 | static irqreturn_t | 298 | static irqreturn_t |
299 | clps7500_timer_interrupt(int irq, void *dev_id) | 299 | clps7500_timer_interrupt(int irq, void *dev_id) |
300 | { | 300 | { |
301 | write_seqlock(&xtime_lock); | ||
302 | |||
303 | timer_tick(); | 301 | timer_tick(); |
304 | 302 | ||
305 | /* Why not using do_leds interface?? */ | 303 | /* Why not using do_leds interface?? */ |
@@ -313,8 +311,6 @@ clps7500_timer_interrupt(int irq, void *dev_id) | |||
313 | } | 311 | } |
314 | } | 312 | } |
315 | 313 | ||
316 | write_sequnlock(&xtime_lock); | ||
317 | |||
318 | return IRQ_HANDLED; | 314 | return IRQ_HANDLED; |
319 | } | 315 | } |
320 | 316 | ||
diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c index 8c1b5690dfe8..7710e14b5268 100644 --- a/arch/arm/mach-ebsa110/core.c +++ b/arch/arm/mach-ebsa110/core.c | |||
@@ -178,8 +178,6 @@ ebsa110_timer_interrupt(int irq, void *dev_id) | |||
178 | { | 178 | { |
179 | u32 count; | 179 | u32 count; |
180 | 180 | ||
181 | write_seqlock(&xtime_lock); | ||
182 | |||
183 | /* latch and read timer 1 */ | 181 | /* latch and read timer 1 */ |
184 | __raw_writeb(0x40, PIT_CTRL); | 182 | __raw_writeb(0x40, PIT_CTRL); |
185 | count = __raw_readb(PIT_T1); | 183 | count = __raw_readb(PIT_T1); |
@@ -192,8 +190,6 @@ ebsa110_timer_interrupt(int irq, void *dev_id) | |||
192 | 190 | ||
193 | timer_tick(); | 191 | timer_tick(); |
194 | 192 | ||
195 | write_sequnlock(&xtime_lock); | ||
196 | |||
197 | return IRQ_HANDLED; | 193 | return IRQ_HANDLED; |
198 | } | 194 | } |
199 | 195 | ||
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index 70b2c7801110..91f6a07a51d5 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * Core routines for Cirrus EP93xx chips. | 3 | * Core routines for Cirrus EP93xx chips. |
4 | * | 4 | * |
5 | * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org> | 5 | * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org> |
6 | * Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.org> | ||
6 | * | 7 | * |
7 | * Thanks go to Michael Burian and Ray Lehtiniemi for their key | 8 | * Thanks go to Michael Burian and Ray Lehtiniemi for their key |
8 | * role in the ep93xx linux community. | 9 | * role in the ep93xx linux community. |
@@ -21,7 +22,6 @@ | |||
21 | #include <linux/serial.h> | 22 | #include <linux/serial.h> |
22 | #include <linux/tty.h> | 23 | #include <linux/tty.h> |
23 | #include <linux/bitops.h> | 24 | #include <linux/bitops.h> |
24 | #include <linux/serial.h> | ||
25 | #include <linux/serial_8250.h> | 25 | #include <linux/serial_8250.h> |
26 | #include <linux/serial_core.h> | 26 | #include <linux/serial_core.h> |
27 | #include <linux/device.h> | 27 | #include <linux/device.h> |
@@ -99,8 +99,6 @@ static unsigned int last_jiffy_time; | |||
99 | 99 | ||
100 | static int ep93xx_timer_interrupt(int irq, void *dev_id) | 100 | static int ep93xx_timer_interrupt(int irq, void *dev_id) |
101 | { | 101 | { |
102 | write_seqlock(&xtime_lock); | ||
103 | |||
104 | __raw_writel(1, EP93XX_TIMER1_CLEAR); | 102 | __raw_writel(1, EP93XX_TIMER1_CLEAR); |
105 | while ((signed long) | 103 | while ((signed long) |
106 | (__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time) | 104 | (__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time) |
@@ -109,8 +107,6 @@ static int ep93xx_timer_interrupt(int irq, void *dev_id) | |||
109 | timer_tick(); | 107 | timer_tick(); |
110 | } | 108 | } |
111 | 109 | ||
112 | write_sequnlock(&xtime_lock); | ||
113 | |||
114 | return IRQ_HANDLED; | 110 | return IRQ_HANDLED; |
115 | } | 111 | } |
116 | 112 | ||
@@ -157,38 +153,41 @@ static unsigned char gpio_int_enabled[3]; | |||
157 | static unsigned char gpio_int_type1[3]; | 153 | static unsigned char gpio_int_type1[3]; |
158 | static unsigned char gpio_int_type2[3]; | 154 | static unsigned char gpio_int_type2[3]; |
159 | 155 | ||
160 | static void update_gpio_int_params(int abf) | 156 | /* Port ordering is: A B F */ |
157 | static const u8 int_type1_register_offset[3] = { 0x90, 0xac, 0x4c }; | ||
158 | static const u8 int_type2_register_offset[3] = { 0x94, 0xb0, 0x50 }; | ||
159 | static const u8 eoi_register_offset[3] = { 0x98, 0xb4, 0x54 }; | ||
160 | static const u8 int_en_register_offset[3] = { 0x9c, 0xb8, 0x5c }; | ||
161 | |||
162 | static void update_gpio_int_params(unsigned port) | ||
161 | { | 163 | { |
162 | if (abf == 0) { | 164 | BUG_ON(port > 2); |
163 | __raw_writeb(0, EP93XX_GPIO_A_INT_ENABLE); | ||
164 | __raw_writeb(gpio_int_type2[0], EP93XX_GPIO_A_INT_TYPE2); | ||
165 | __raw_writeb(gpio_int_type1[0], EP93XX_GPIO_A_INT_TYPE1); | ||
166 | __raw_writeb(gpio_int_unmasked[0] & gpio_int_enabled[0], EP93XX_GPIO_A_INT_ENABLE); | ||
167 | } else if (abf == 1) { | ||
168 | __raw_writeb(0, EP93XX_GPIO_B_INT_ENABLE); | ||
169 | __raw_writeb(gpio_int_type2[1], EP93XX_GPIO_B_INT_TYPE2); | ||
170 | __raw_writeb(gpio_int_type1[1], EP93XX_GPIO_B_INT_TYPE1); | ||
171 | __raw_writeb(gpio_int_unmasked[1] & gpio_int_enabled[1], EP93XX_GPIO_B_INT_ENABLE); | ||
172 | } else if (abf == 2) { | ||
173 | __raw_writeb(0, EP93XX_GPIO_F_INT_ENABLE); | ||
174 | __raw_writeb(gpio_int_type2[2], EP93XX_GPIO_F_INT_TYPE2); | ||
175 | __raw_writeb(gpio_int_type1[2], EP93XX_GPIO_F_INT_TYPE1); | ||
176 | __raw_writeb(gpio_int_unmasked[2] & gpio_int_enabled[2], EP93XX_GPIO_F_INT_ENABLE); | ||
177 | } else { | ||
178 | BUG(); | ||
179 | } | ||
180 | } | ||
181 | 165 | ||
166 | __raw_writeb(0, EP93XX_GPIO_REG(int_en_register_offset[port])); | ||
182 | 167 | ||
183 | static unsigned char data_register_offset[8] = { | 168 | __raw_writeb(gpio_int_type2[port], |
184 | 0x00, 0x04, 0x08, 0x0c, 0x20, 0x30, 0x38, 0x40, | 169 | EP93XX_GPIO_REG(int_type2_register_offset[port])); |
170 | |||
171 | __raw_writeb(gpio_int_type1[port], | ||
172 | EP93XX_GPIO_REG(int_type1_register_offset[port])); | ||
173 | |||
174 | __raw_writeb(gpio_int_unmasked[port] & gpio_int_enabled[port], | ||
175 | EP93XX_GPIO_REG(int_en_register_offset[port])); | ||
176 | } | ||
177 | |||
178 | /* Port ordering is: A B F D E C G H */ | ||
179 | static const u8 data_register_offset[8] = { | ||
180 | 0x00, 0x04, 0x30, 0x0c, 0x20, 0x08, 0x38, 0x40, | ||
185 | }; | 181 | }; |
186 | 182 | ||
187 | static unsigned char data_direction_register_offset[8] = { | 183 | static const u8 data_direction_register_offset[8] = { |
188 | 0x10, 0x14, 0x18, 0x1c, 0x24, 0x34, 0x3c, 0x44, | 184 | 0x10, 0x14, 0x34, 0x1c, 0x24, 0x18, 0x3c, 0x44, |
189 | }; | 185 | }; |
190 | 186 | ||
191 | void gpio_line_config(int line, int direction) | 187 | #define GPIO_IN 0 |
188 | #define GPIO_OUT 1 | ||
189 | |||
190 | static void ep93xx_gpio_set_direction(unsigned line, int direction) | ||
192 | { | 191 | { |
193 | unsigned int data_direction_register; | 192 | unsigned int data_direction_register; |
194 | unsigned long flags; | 193 | unsigned long flags; |
@@ -199,14 +198,10 @@ void gpio_line_config(int line, int direction) | |||
199 | 198 | ||
200 | local_irq_save(flags); | 199 | local_irq_save(flags); |
201 | if (direction == GPIO_OUT) { | 200 | if (direction == GPIO_OUT) { |
202 | if (line >= 0 && line < 16) { | 201 | if (line >= 0 && line <= EP93XX_GPIO_LINE_MAX_IRQ) { |
203 | /* Port A/B. */ | 202 | /* Port A/B/F */ |
204 | gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7)); | 203 | gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7)); |
205 | update_gpio_int_params(line >> 3); | 204 | update_gpio_int_params(line >> 3); |
206 | } else if (line >= 40 && line < 48) { | ||
207 | /* Port F. */ | ||
208 | gpio_int_unmasked[2] &= ~(1 << (line & 7)); | ||
209 | update_gpio_int_params(2); | ||
210 | } | 205 | } |
211 | 206 | ||
212 | v = __raw_readb(data_direction_register); | 207 | v = __raw_readb(data_direction_register); |
@@ -219,39 +214,58 @@ void gpio_line_config(int line, int direction) | |||
219 | } | 214 | } |
220 | local_irq_restore(flags); | 215 | local_irq_restore(flags); |
221 | } | 216 | } |
222 | EXPORT_SYMBOL(gpio_line_config); | ||
223 | 217 | ||
224 | int gpio_line_get(int line) | 218 | int gpio_direction_input(unsigned gpio) |
219 | { | ||
220 | if (gpio > EP93XX_GPIO_LINE_MAX) | ||
221 | return -EINVAL; | ||
222 | |||
223 | ep93xx_gpio_set_direction(gpio, GPIO_IN); | ||
224 | |||
225 | return 0; | ||
226 | } | ||
227 | EXPORT_SYMBOL(gpio_direction_input); | ||
228 | |||
229 | int gpio_direction_output(unsigned gpio, int value) | ||
230 | { | ||
231 | if (gpio > EP93XX_GPIO_LINE_MAX) | ||
232 | return -EINVAL; | ||
233 | |||
234 | gpio_set_value(gpio, value); | ||
235 | ep93xx_gpio_set_direction(gpio, GPIO_OUT); | ||
236 | |||
237 | return 0; | ||
238 | } | ||
239 | EXPORT_SYMBOL(gpio_direction_output); | ||
240 | |||
241 | int gpio_get_value(unsigned gpio) | ||
225 | { | 242 | { |
226 | unsigned int data_register; | 243 | unsigned int data_register; |
227 | 244 | ||
228 | data_register = EP93XX_GPIO_REG(data_register_offset[line >> 3]); | 245 | data_register = EP93XX_GPIO_REG(data_register_offset[gpio >> 3]); |
229 | 246 | ||
230 | return !!(__raw_readb(data_register) & (1 << (line & 7))); | 247 | return !!(__raw_readb(data_register) & (1 << (gpio & 7))); |
231 | } | 248 | } |
232 | EXPORT_SYMBOL(gpio_line_get); | 249 | EXPORT_SYMBOL(gpio_get_value); |
233 | 250 | ||
234 | void gpio_line_set(int line, int value) | 251 | void gpio_set_value(unsigned gpio, int value) |
235 | { | 252 | { |
236 | unsigned int data_register; | 253 | unsigned int data_register; |
237 | unsigned long flags; | 254 | unsigned long flags; |
238 | unsigned char v; | 255 | unsigned char v; |
239 | 256 | ||
240 | data_register = EP93XX_GPIO_REG(data_register_offset[line >> 3]); | 257 | data_register = EP93XX_GPIO_REG(data_register_offset[gpio >> 3]); |
241 | 258 | ||
242 | local_irq_save(flags); | 259 | local_irq_save(flags); |
243 | if (value == EP93XX_GPIO_HIGH) { | 260 | v = __raw_readb(data_register); |
244 | v = __raw_readb(data_register); | 261 | if (value) |
245 | v |= 1 << (line & 7); | 262 | v |= 1 << (gpio & 7); |
246 | __raw_writeb(v, data_register); | 263 | else |
247 | } else if (value == EP93XX_GPIO_LOW) { | 264 | v &= ~(1 << (gpio & 7)); |
248 | v = __raw_readb(data_register); | 265 | __raw_writeb(v, data_register); |
249 | v &= ~(1 << (line & 7)); | ||
250 | __raw_writeb(v, data_register); | ||
251 | } | ||
252 | local_irq_restore(flags); | 266 | local_irq_restore(flags); |
253 | } | 267 | } |
254 | EXPORT_SYMBOL(gpio_line_set); | 268 | EXPORT_SYMBOL(gpio_set_value); |
255 | 269 | ||
256 | 270 | ||
257 | /************************************************************************* | 271 | /************************************************************************* |
@@ -265,47 +279,67 @@ static void ep93xx_gpio_ab_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
265 | status = __raw_readb(EP93XX_GPIO_A_INT_STATUS); | 279 | status = __raw_readb(EP93XX_GPIO_A_INT_STATUS); |
266 | for (i = 0; i < 8; i++) { | 280 | for (i = 0; i < 8; i++) { |
267 | if (status & (1 << i)) { | 281 | if (status & (1 << i)) { |
268 | desc = irq_desc + IRQ_EP93XX_GPIO(0) + i; | 282 | int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_A(0)) + i; |
269 | desc_handle_irq(IRQ_EP93XX_GPIO(0) + i, desc); | 283 | desc = irq_desc + gpio_irq; |
284 | desc_handle_irq(gpio_irq, desc); | ||
270 | } | 285 | } |
271 | } | 286 | } |
272 | 287 | ||
273 | status = __raw_readb(EP93XX_GPIO_B_INT_STATUS); | 288 | status = __raw_readb(EP93XX_GPIO_B_INT_STATUS); |
274 | for (i = 0; i < 8; i++) { | 289 | for (i = 0; i < 8; i++) { |
275 | if (status & (1 << i)) { | 290 | if (status & (1 << i)) { |
276 | desc = irq_desc + IRQ_EP93XX_GPIO(8) + i; | 291 | int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_B(0)) + i; |
277 | desc_handle_irq(IRQ_EP93XX_GPIO(8) + i, desc); | 292 | desc = irq_desc + gpio_irq; |
293 | desc_handle_irq(gpio_irq, desc); | ||
278 | } | 294 | } |
279 | } | 295 | } |
280 | } | 296 | } |
281 | 297 | ||
282 | static void ep93xx_gpio_f_irq_handler(unsigned int irq, struct irq_desc *desc) | 298 | static void ep93xx_gpio_f_irq_handler(unsigned int irq, struct irq_desc *desc) |
283 | { | 299 | { |
284 | int gpio_irq = IRQ_EP93XX_GPIO(16) + (((irq + 1) & 7) ^ 4); | 300 | /* |
301 | * map discontiguous hw irq range to continous sw irq range: | ||
302 | * | ||
303 | * IRQ_EP93XX_GPIO{0..7}MUX -> gpio_to_irq(EP93XX_GPIO_LINE_F({0..7}) | ||
304 | */ | ||
305 | int port_f_idx = ((irq + 1) & 7) ^ 4; /* {19..22,47..50} -> {0..7} */ | ||
306 | int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_F(0)) + port_f_idx; | ||
285 | 307 | ||
286 | desc_handle_irq(gpio_irq, irq_desc + gpio_irq); | 308 | desc_handle_irq(gpio_irq, irq_desc + gpio_irq); |
287 | } | 309 | } |
288 | 310 | ||
311 | static void ep93xx_gpio_irq_ack(unsigned int irq) | ||
312 | { | ||
313 | int line = irq_to_gpio(irq); | ||
314 | int port = line >> 3; | ||
315 | int port_mask = 1 << (line & 7); | ||
316 | |||
317 | if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQT_BOTHEDGE) { | ||
318 | gpio_int_type2[port] ^= port_mask; /* switch edge direction */ | ||
319 | update_gpio_int_params(port); | ||
320 | } | ||
321 | |||
322 | __raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port])); | ||
323 | } | ||
324 | |||
289 | static void ep93xx_gpio_irq_mask_ack(unsigned int irq) | 325 | static void ep93xx_gpio_irq_mask_ack(unsigned int irq) |
290 | { | 326 | { |
291 | int line = irq - IRQ_EP93XX_GPIO(0); | 327 | int line = irq_to_gpio(irq); |
292 | int port = line >> 3; | 328 | int port = line >> 3; |
329 | int port_mask = 1 << (line & 7); | ||
293 | 330 | ||
294 | gpio_int_unmasked[port] &= ~(1 << (line & 7)); | 331 | if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQT_BOTHEDGE) |
332 | gpio_int_type2[port] ^= port_mask; /* switch edge direction */ | ||
333 | |||
334 | gpio_int_unmasked[port] &= ~port_mask; | ||
295 | update_gpio_int_params(port); | 335 | update_gpio_int_params(port); |
296 | 336 | ||
297 | if (port == 0) { | 337 | __raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port])); |
298 | __raw_writel(1 << (line & 7), EP93XX_GPIO_A_INT_ACK); | ||
299 | } else if (port == 1) { | ||
300 | __raw_writel(1 << (line & 7), EP93XX_GPIO_B_INT_ACK); | ||
301 | } else if (port == 2) { | ||
302 | __raw_writel(1 << (line & 7), EP93XX_GPIO_F_INT_ACK); | ||
303 | } | ||
304 | } | 338 | } |
305 | 339 | ||
306 | static void ep93xx_gpio_irq_mask(unsigned int irq) | 340 | static void ep93xx_gpio_irq_mask(unsigned int irq) |
307 | { | 341 | { |
308 | int line = irq - IRQ_EP93XX_GPIO(0); | 342 | int line = irq_to_gpio(irq); |
309 | int port = line >> 3; | 343 | int port = line >> 3; |
310 | 344 | ||
311 | gpio_int_unmasked[port] &= ~(1 << (line & 7)); | 345 | gpio_int_unmasked[port] &= ~(1 << (line & 7)); |
@@ -314,7 +348,7 @@ static void ep93xx_gpio_irq_mask(unsigned int irq) | |||
314 | 348 | ||
315 | static void ep93xx_gpio_irq_unmask(unsigned int irq) | 349 | static void ep93xx_gpio_irq_unmask(unsigned int irq) |
316 | { | 350 | { |
317 | int line = irq - IRQ_EP93XX_GPIO(0); | 351 | int line = irq_to_gpio(irq); |
318 | int port = line >> 3; | 352 | int port = line >> 3; |
319 | 353 | ||
320 | gpio_int_unmasked[port] |= 1 << (line & 7); | 354 | gpio_int_unmasked[port] |= 1 << (line & 7); |
@@ -329,38 +363,54 @@ static void ep93xx_gpio_irq_unmask(unsigned int irq) | |||
329 | */ | 363 | */ |
330 | static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type) | 364 | static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type) |
331 | { | 365 | { |
332 | int port; | 366 | struct irq_desc *desc = irq_desc + irq; |
333 | int line; | 367 | const int gpio = irq_to_gpio(irq); |
334 | 368 | const int port = gpio >> 3; | |
335 | line = irq - IRQ_EP93XX_GPIO(0); | 369 | const int port_mask = 1 << (gpio & 7); |
336 | if (line >= 0 && line < 16) { | 370 | |
337 | gpio_line_config(line, GPIO_IN); | 371 | ep93xx_gpio_set_direction(gpio, GPIO_IN); |
338 | } else { | 372 | |
339 | gpio_line_config(EP93XX_GPIO_LINE_F(line-16), GPIO_IN); | 373 | switch (type) { |
374 | case IRQT_RISING: | ||
375 | gpio_int_type1[port] |= port_mask; | ||
376 | gpio_int_type2[port] |= port_mask; | ||
377 | desc->handle_irq = handle_edge_irq; | ||
378 | break; | ||
379 | case IRQT_FALLING: | ||
380 | gpio_int_type1[port] |= port_mask; | ||
381 | gpio_int_type2[port] &= ~port_mask; | ||
382 | desc->handle_irq = handle_edge_irq; | ||
383 | break; | ||
384 | case IRQT_HIGH: | ||
385 | gpio_int_type1[port] &= ~port_mask; | ||
386 | gpio_int_type2[port] |= port_mask; | ||
387 | desc->handle_irq = handle_level_irq; | ||
388 | break; | ||
389 | case IRQT_LOW: | ||
390 | gpio_int_type1[port] &= ~port_mask; | ||
391 | gpio_int_type2[port] &= ~port_mask; | ||
392 | desc->handle_irq = handle_level_irq; | ||
393 | break; | ||
394 | case IRQT_BOTHEDGE: | ||
395 | gpio_int_type1[port] |= port_mask; | ||
396 | /* set initial polarity based on current input level */ | ||
397 | if (gpio_get_value(gpio)) | ||
398 | gpio_int_type2[port] &= ~port_mask; /* falling */ | ||
399 | else | ||
400 | gpio_int_type2[port] |= port_mask; /* rising */ | ||
401 | desc->handle_irq = handle_edge_irq; | ||
402 | break; | ||
403 | default: | ||
404 | pr_err("ep93xx: failed to set irq type %d for gpio %d\n", | ||
405 | type, gpio); | ||
406 | return -EINVAL; | ||
340 | } | 407 | } |
341 | 408 | ||
342 | port = line >> 3; | 409 | gpio_int_enabled[port] |= port_mask; |
343 | line &= 7; | 410 | |
344 | 411 | desc->status &= ~IRQ_TYPE_SENSE_MASK; | |
345 | if (type & IRQT_RISING) { | 412 | desc->status |= type & IRQ_TYPE_SENSE_MASK; |
346 | gpio_int_enabled[port] |= 1 << line; | 413 | |
347 | gpio_int_type1[port] |= 1 << line; | ||
348 | gpio_int_type2[port] |= 1 << line; | ||
349 | } else if (type & IRQT_FALLING) { | ||
350 | gpio_int_enabled[port] |= 1 << line; | ||
351 | gpio_int_type1[port] |= 1 << line; | ||
352 | gpio_int_type2[port] &= ~(1 << line); | ||
353 | } else if (type & IRQT_HIGH) { | ||
354 | gpio_int_enabled[port] |= 1 << line; | ||
355 | gpio_int_type1[port] &= ~(1 << line); | ||
356 | gpio_int_type2[port] |= 1 << line; | ||
357 | } else if (type & IRQT_LOW) { | ||
358 | gpio_int_enabled[port] |= 1 << line; | ||
359 | gpio_int_type1[port] &= ~(1 << line); | ||
360 | gpio_int_type2[port] &= ~(1 << line); | ||
361 | } else { | ||
362 | gpio_int_enabled[port] &= ~(1 << line); | ||
363 | } | ||
364 | update_gpio_int_params(port); | 414 | update_gpio_int_params(port); |
365 | 415 | ||
366 | return 0; | 416 | return 0; |
@@ -368,7 +418,8 @@ static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type) | |||
368 | 418 | ||
369 | static struct irq_chip ep93xx_gpio_irq_chip = { | 419 | static struct irq_chip ep93xx_gpio_irq_chip = { |
370 | .name = "GPIO", | 420 | .name = "GPIO", |
371 | .ack = ep93xx_gpio_irq_mask_ack, | 421 | .ack = ep93xx_gpio_irq_ack, |
422 | .mask_ack = ep93xx_gpio_irq_mask_ack, | ||
372 | .mask = ep93xx_gpio_irq_mask, | 423 | .mask = ep93xx_gpio_irq_mask, |
373 | .unmask = ep93xx_gpio_irq_unmask, | 424 | .unmask = ep93xx_gpio_irq_unmask, |
374 | .set_type = ep93xx_gpio_irq_type, | 425 | .set_type = ep93xx_gpio_irq_type, |
@@ -377,15 +428,16 @@ static struct irq_chip ep93xx_gpio_irq_chip = { | |||
377 | 428 | ||
378 | void __init ep93xx_init_irq(void) | 429 | void __init ep93xx_init_irq(void) |
379 | { | 430 | { |
380 | int irq; | 431 | int gpio_irq; |
381 | 432 | ||
382 | vic_init((void *)EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK); | 433 | vic_init((void *)EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK); |
383 | vic_init((void *)EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK); | 434 | vic_init((void *)EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK); |
384 | 435 | ||
385 | for (irq = IRQ_EP93XX_GPIO(0); irq <= IRQ_EP93XX_GPIO(23); irq++) { | 436 | for (gpio_irq = gpio_to_irq(0); |
386 | set_irq_chip(irq, &ep93xx_gpio_irq_chip); | 437 | gpio_irq <= gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ); ++gpio_irq) { |
387 | set_irq_handler(irq, handle_level_irq); | 438 | set_irq_chip(gpio_irq, &ep93xx_gpio_irq_chip); |
388 | set_irq_flags(irq, IRQF_VALID); | 439 | set_irq_handler(gpio_irq, handle_level_irq); |
440 | set_irq_flags(gpio_irq, IRQF_VALID); | ||
389 | } | 441 | } |
390 | 442 | ||
391 | set_irq_chained_handler(IRQ_EP93XX_GPIO_AB, ep93xx_gpio_ab_irq_handler); | 443 | set_irq_chained_handler(IRQ_EP93XX_GPIO_AB, ep93xx_gpio_ab_irq_handler); |
diff --git a/arch/arm/mach-footbridge/dc21285-timer.c b/arch/arm/mach-footbridge/dc21285-timer.c index 3a63941d43be..b2a21189dd81 100644 --- a/arch/arm/mach-footbridge/dc21285-timer.c +++ b/arch/arm/mach-footbridge/dc21285-timer.c | |||
@@ -30,14 +30,10 @@ static unsigned long timer1_gettimeoffset (void) | |||
30 | static irqreturn_t | 30 | static irqreturn_t |
31 | timer1_interrupt(int irq, void *dev_id) | 31 | timer1_interrupt(int irq, void *dev_id) |
32 | { | 32 | { |
33 | write_seqlock(&xtime_lock); | ||
34 | |||
35 | *CSR_TIMER1_CLR = 0; | 33 | *CSR_TIMER1_CLR = 0; |
36 | 34 | ||
37 | timer_tick(); | 35 | timer_tick(); |
38 | 36 | ||
39 | write_sequnlock(&xtime_lock); | ||
40 | |||
41 | return IRQ_HANDLED; | 37 | return IRQ_HANDLED; |
42 | } | 38 | } |
43 | 39 | ||
diff --git a/arch/arm/mach-footbridge/isa-timer.c b/arch/arm/mach-footbridge/isa-timer.c index d08d64139d00..a764e01d3573 100644 --- a/arch/arm/mach-footbridge/isa-timer.c +++ b/arch/arm/mach-footbridge/isa-timer.c | |||
@@ -64,9 +64,7 @@ static unsigned long isa_gettimeoffset(void) | |||
64 | static irqreturn_t | 64 | static irqreturn_t |
65 | isa_timer_interrupt(int irq, void *dev_id) | 65 | isa_timer_interrupt(int irq, void *dev_id) |
66 | { | 66 | { |
67 | write_seqlock(&xtime_lock); | ||
68 | timer_tick(); | 67 | timer_tick(); |
69 | write_sequnlock(&xtime_lock); | ||
70 | return IRQ_HANDLED; | 68 | return IRQ_HANDLED; |
71 | } | 69 | } |
72 | 70 | ||
diff --git a/arch/arm/mach-h720x/cpu-h7201.c b/arch/arm/mach-h720x/cpu-h7201.c index 9107b8e2ad6e..c2a431f482f0 100644 --- a/arch/arm/mach-h720x/cpu-h7201.c +++ b/arch/arm/mach-h720x/cpu-h7201.c | |||
@@ -29,13 +29,9 @@ | |||
29 | static irqreturn_t | 29 | static irqreturn_t |
30 | h7201_timer_interrupt(int irq, void *dev_id) | 30 | h7201_timer_interrupt(int irq, void *dev_id) |
31 | { | 31 | { |
32 | write_seqlock(&xtime_lock); | ||
33 | |||
34 | CPU_REG (TIMER_VIRT, TIMER_TOPSTAT); | 32 | CPU_REG (TIMER_VIRT, TIMER_TOPSTAT); |
35 | timer_tick(); | 33 | timer_tick(); |
36 | 34 | ||
37 | write_sequnlock(&xtime_lock); | ||
38 | |||
39 | return IRQ_HANDLED; | 35 | return IRQ_HANDLED; |
40 | } | 36 | } |
41 | 37 | ||
diff --git a/arch/arm/mach-h720x/cpu-h7202.c b/arch/arm/mach-h720x/cpu-h7202.c index 0a1a25fb8ba8..c627fa124eb3 100644 --- a/arch/arm/mach-h720x/cpu-h7202.c +++ b/arch/arm/mach-h720x/cpu-h7202.c | |||
@@ -113,9 +113,7 @@ h7202_timerx_demux_handler(unsigned int irq_unused, struct irq_desc *desc) | |||
113 | mask = CPU_REG (TIMER_VIRT, TIMER_TOPSTAT); | 113 | mask = CPU_REG (TIMER_VIRT, TIMER_TOPSTAT); |
114 | 114 | ||
115 | if ( mask & TSTAT_T0INT ) { | 115 | if ( mask & TSTAT_T0INT ) { |
116 | write_seqlock(&xtime_lock); | ||
117 | timer_tick(); | 116 | timer_tick(); |
118 | write_sequnlock(&xtime_lock); | ||
119 | if( mask == TSTAT_T0INT ) | 117 | if( mask == TSTAT_T0INT ) |
120 | return; | 118 | return; |
121 | } | 119 | } |
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index e9c82deb791d..7fbbc17f8e8b 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c | |||
@@ -250,8 +250,6 @@ unsigned long integrator_gettimeoffset(void) | |||
250 | static irqreturn_t | 250 | static irqreturn_t |
251 | integrator_timer_interrupt(int irq, void *dev_id) | 251 | integrator_timer_interrupt(int irq, void *dev_id) |
252 | { | 252 | { |
253 | write_seqlock(&xtime_lock); | ||
254 | |||
255 | /* | 253 | /* |
256 | * clear the interrupt | 254 | * clear the interrupt |
257 | */ | 255 | */ |
@@ -259,8 +257,6 @@ integrator_timer_interrupt(int irq, void *dev_id) | |||
259 | 257 | ||
260 | timer_tick(); | 258 | timer_tick(); |
261 | 259 | ||
262 | write_sequnlock(&xtime_lock); | ||
263 | |||
264 | return IRQ_HANDLED; | 260 | return IRQ_HANDLED; |
265 | } | 261 | } |
266 | 262 | ||
diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c index d4d8134ce567..d55fa4e9bb43 100644 --- a/arch/arm/mach-integrator/pci_v3.c +++ b/arch/arm/mach-integrator/pci_v3.c | |||
@@ -440,7 +440,7 @@ v3_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |||
440 | return 1; | 440 | return 1; |
441 | } | 441 | } |
442 | 442 | ||
443 | static irqreturn_t v3_irq(int irq, void *devid) | 443 | static irqreturn_t v3_irq(int dummy, void *devid) |
444 | { | 444 | { |
445 | #ifdef CONFIG_DEBUG_LL | 445 | #ifdef CONFIG_DEBUG_LL |
446 | struct pt_regs *regs = get_irq_regs(); | 446 | struct pt_regs *regs = get_irq_regs(); |
@@ -448,8 +448,10 @@ static irqreturn_t v3_irq(int irq, void *devid) | |||
448 | unsigned long instr = *(unsigned long *)pc; | 448 | unsigned long instr = *(unsigned long *)pc; |
449 | char buf[128]; | 449 | char buf[128]; |
450 | 450 | ||
451 | sprintf(buf, "V3 int %d: pc=0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x ISTAT=%02x\n", irq, | 451 | sprintf(buf, "V3 int %d: pc=0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x " |
452 | pc, instr, __raw_readl(SC_LBFADDR), __raw_readl(SC_LBFCODE) & 255, | 452 | "ISTAT=%02x\n", IRQ_AP_V3INT, pc, instr, |
453 | __raw_readl(SC_LBFADDR), | ||
454 | __raw_readl(SC_LBFCODE) & 255, | ||
453 | v3_readb(V3_LB_ISTAT)); | 455 | v3_readb(V3_LB_ISTAT)); |
454 | printascii(buf); | 456 | printascii(buf); |
455 | #endif | 457 | #endif |
diff --git a/arch/arm/mach-iop32x/glantank.c b/arch/arm/mach-iop32x/glantank.c index 2b086ab2668c..74c65ce221de 100644 --- a/arch/arm/mach-iop32x/glantank.c +++ b/arch/arm/mach-iop32x/glantank.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Board support code for the GLAN Tank. | 4 | * Board support code for the GLAN Tank. |
5 | * | 5 | * |
6 | * Copyright (C) 2006 Martin Michlmayr <tbm@cyrius.com> | 6 | * Copyright (C) 2006, 2007 Martin Michlmayr <tbm@cyrius.com> |
7 | * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org> | 7 | * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org> |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify it | 9 | * This program is free software; you can redistribute it and/or modify it |
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/serial_core.h> | 21 | #include <linux/serial_core.h> |
22 | #include <linux/serial_8250.h> | 22 | #include <linux/serial_8250.h> |
23 | #include <linux/mtd/physmap.h> | 23 | #include <linux/mtd/physmap.h> |
24 | #include <linux/i2c.h> | ||
24 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
25 | #include <asm/hardware.h> | 26 | #include <asm/hardware.h> |
26 | #include <asm/io.h> | 27 | #include <asm/io.h> |
@@ -118,7 +119,7 @@ subsys_initcall(glantank_pci_init); | |||
118 | * GLAN Tank machine initialization. | 119 | * GLAN Tank machine initialization. |
119 | */ | 120 | */ |
120 | static struct physmap_flash_data glantank_flash_data = { | 121 | static struct physmap_flash_data glantank_flash_data = { |
121 | .width = 1, | 122 | .width = 2, |
122 | }; | 123 | }; |
123 | 124 | ||
124 | static struct resource glantank_flash_resource = { | 125 | static struct resource glantank_flash_resource = { |
@@ -166,6 +167,13 @@ static struct platform_device glantank_serial_device = { | |||
166 | .resource = &glantank_uart_resource, | 167 | .resource = &glantank_uart_resource, |
167 | }; | 168 | }; |
168 | 169 | ||
170 | static struct i2c_board_info __initdata glantank_i2c_devices[] = { | ||
171 | { | ||
172 | I2C_BOARD_INFO("rtc-rs5c372", 0x32), | ||
173 | .type = "rs5c372a", | ||
174 | }, | ||
175 | }; | ||
176 | |||
169 | static void glantank_power_off(void) | 177 | static void glantank_power_off(void) |
170 | { | 178 | { |
171 | __raw_writeb(0x01, 0xfe8d0004); | 179 | __raw_writeb(0x01, 0xfe8d0004); |
@@ -183,6 +191,9 @@ static void __init glantank_init_machine(void) | |||
183 | platform_device_register(&iop3xx_dma_0_channel); | 191 | platform_device_register(&iop3xx_dma_0_channel); |
184 | platform_device_register(&iop3xx_dma_1_channel); | 192 | platform_device_register(&iop3xx_dma_1_channel); |
185 | 193 | ||
194 | i2c_register_board_info(0, glantank_i2c_devices, | ||
195 | ARRAY_SIZE(glantank_i2c_devices)); | ||
196 | |||
186 | pm_power_off = glantank_power_off; | 197 | pm_power_off = glantank_power_off; |
187 | } | 198 | } |
188 | 199 | ||
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c index cb6ad211887a..81cdc8267206 100644 --- a/arch/arm/mach-ixp2000/core.c +++ b/arch/arm/mach-ixp2000/core.c | |||
@@ -206,8 +206,6 @@ unsigned long ixp2000_gettimeoffset (void) | |||
206 | 206 | ||
207 | static int ixp2000_timer_interrupt(int irq, void *dev_id) | 207 | static int ixp2000_timer_interrupt(int irq, void *dev_id) |
208 | { | 208 | { |
209 | write_seqlock(&xtime_lock); | ||
210 | |||
211 | /* clear timer 1 */ | 209 | /* clear timer 1 */ |
212 | ixp2000_reg_wrb(IXP2000_T1_CLR, 1); | 210 | ixp2000_reg_wrb(IXP2000_T1_CLR, 1); |
213 | 211 | ||
@@ -217,8 +215,6 @@ static int ixp2000_timer_interrupt(int irq, void *dev_id) | |||
217 | next_jiffy_time -= ticks_per_jiffy; | 215 | next_jiffy_time -= ticks_per_jiffy; |
218 | } | 216 | } |
219 | 217 | ||
220 | write_sequnlock(&xtime_lock); | ||
221 | |||
222 | return IRQ_HANDLED; | 218 | return IRQ_HANDLED; |
223 | } | 219 | } |
224 | 220 | ||
diff --git a/arch/arm/mach-ixp23xx/core.c b/arch/arm/mach-ixp23xx/core.c index 16356ffc86ae..5fea5a132939 100644 --- a/arch/arm/mach-ixp23xx/core.c +++ b/arch/arm/mach-ixp23xx/core.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/serial.h> | 22 | #include <linux/serial.h> |
23 | #include <linux/tty.h> | 23 | #include <linux/tty.h> |
24 | #include <linux/bitops.h> | 24 | #include <linux/bitops.h> |
25 | #include <linux/serial.h> | ||
26 | #include <linux/serial_8250.h> | 25 | #include <linux/serial_8250.h> |
27 | #include <linux/serial_core.h> | 26 | #include <linux/serial_core.h> |
28 | #include <linux/device.h> | 27 | #include <linux/device.h> |
diff --git a/arch/arm/mach-ixp23xx/espresso.c b/arch/arm/mach-ixp23xx/espresso.c index 7a85ced56718..d3a779a7a35f 100644 --- a/arch/arm/mach-ixp23xx/espresso.c +++ b/arch/arm/mach-ixp23xx/espresso.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/tty.h> | 19 | #include <linux/tty.h> |
20 | #include <linux/bitops.h> | 20 | #include <linux/bitops.h> |
21 | #include <linux/ioport.h> | 21 | #include <linux/ioport.h> |
22 | #include <linux/serial.h> | ||
23 | #include <linux/serial_8250.h> | 22 | #include <linux/serial_8250.h> |
24 | #include <linux/serial_core.h> | 23 | #include <linux/serial_core.h> |
25 | #include <linux/device.h> | 24 | #include <linux/device.h> |
@@ -40,7 +39,6 @@ | |||
40 | #include <asm/mach/map.h> | 39 | #include <asm/mach/map.h> |
41 | #include <asm/mach/irq.h> | 40 | #include <asm/mach/irq.h> |
42 | #include <asm/mach/arch.h> | 41 | #include <asm/mach/arch.h> |
43 | #include <asm/mach/irq.h> | ||
44 | #include <asm/mach/pci.h> | 42 | #include <asm/mach/pci.h> |
45 | 43 | ||
46 | static int __init espresso_pci_init(void) | 44 | static int __init espresso_pci_init(void) |
diff --git a/arch/arm/mach-ixp23xx/ixdp2351.c b/arch/arm/mach-ixp23xx/ixdp2351.c index c41a6b5a0acc..5c5d4d66dee8 100644 --- a/arch/arm/mach-ixp23xx/ixdp2351.c +++ b/arch/arm/mach-ixp23xx/ixdp2351.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/tty.h> | 24 | #include <linux/tty.h> |
25 | #include <linux/bitops.h> | 25 | #include <linux/bitops.h> |
26 | #include <linux/ioport.h> | 26 | #include <linux/ioport.h> |
27 | #include <linux/serial.h> | ||
28 | #include <linux/serial_8250.h> | 27 | #include <linux/serial_8250.h> |
29 | #include <linux/serial_core.h> | 28 | #include <linux/serial_core.h> |
30 | #include <linux/device.h> | 29 | #include <linux/device.h> |
@@ -44,7 +43,6 @@ | |||
44 | #include <asm/mach/map.h> | 43 | #include <asm/mach/map.h> |
45 | #include <asm/mach/irq.h> | 44 | #include <asm/mach/irq.h> |
46 | #include <asm/mach/arch.h> | 45 | #include <asm/mach/arch.h> |
47 | #include <asm/mach/irq.h> | ||
48 | #include <asm/mach/pci.h> | 46 | #include <asm/mach/pci.h> |
49 | 47 | ||
50 | /* | 48 | /* |
diff --git a/arch/arm/mach-ixp23xx/roadrunner.c b/arch/arm/mach-ixp23xx/roadrunner.c index e35644961aa4..f0f70ba1e46d 100644 --- a/arch/arm/mach-ixp23xx/roadrunner.c +++ b/arch/arm/mach-ixp23xx/roadrunner.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/tty.h> | 23 | #include <linux/tty.h> |
24 | #include <linux/bitops.h> | 24 | #include <linux/bitops.h> |
25 | #include <linux/ioport.h> | 25 | #include <linux/ioport.h> |
26 | #include <linux/serial.h> | ||
27 | #include <linux/serial_8250.h> | 26 | #include <linux/serial_8250.h> |
28 | #include <linux/serial_core.h> | 27 | #include <linux/serial_core.h> |
29 | #include <linux/device.h> | 28 | #include <linux/device.h> |
@@ -44,7 +43,6 @@ | |||
44 | #include <asm/mach/map.h> | 43 | #include <asm/mach/map.h> |
45 | #include <asm/mach/irq.h> | 44 | #include <asm/mach/irq.h> |
46 | #include <asm/mach/arch.h> | 45 | #include <asm/mach/arch.h> |
47 | #include <asm/mach/irq.h> | ||
48 | #include <asm/mach/pci.h> | 46 | #include <asm/mach/pci.h> |
49 | 47 | ||
50 | /* | 48 | /* |
diff --git a/arch/arm/mach-ixp4xx/avila-setup.c b/arch/arm/mach-ixp4xx/avila-setup.c index d59b8dc7dc7a..e38f45fa58ae 100644 --- a/arch/arm/mach-ixp4xx/avila-setup.c +++ b/arch/arm/mach-ixp4xx/avila-setup.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/tty.h> | 18 | #include <linux/tty.h> |
19 | #include <linux/serial_8250.h> | 19 | #include <linux/serial_8250.h> |
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/i2c-gpio.h> | ||
21 | 22 | ||
22 | #include <asm/types.h> | 23 | #include <asm/types.h> |
23 | #include <asm/setup.h> | 24 | #include <asm/setup.h> |
@@ -47,18 +48,17 @@ static struct platform_device avila_flash = { | |||
47 | .resource = &avila_flash_resource, | 48 | .resource = &avila_flash_resource, |
48 | }; | 49 | }; |
49 | 50 | ||
50 | static struct ixp4xx_i2c_pins avila_i2c_gpio_pins = { | 51 | static struct i2c_gpio_platform_data avila_i2c_gpio_data = { |
51 | .sda_pin = AVILA_SDA_PIN, | 52 | .sda_pin = AVILA_SDA_PIN, |
52 | .scl_pin = AVILA_SCL_PIN, | 53 | .scl_pin = AVILA_SCL_PIN, |
53 | }; | 54 | }; |
54 | 55 | ||
55 | static struct platform_device avila_i2c_controller = { | 56 | static struct platform_device avila_i2c_gpio = { |
56 | .name = "IXP4XX-I2C", | 57 | .name = "i2c-gpio", |
57 | .id = 0, | 58 | .id = 0, |
58 | .dev = { | 59 | .dev = { |
59 | .platform_data = &avila_i2c_gpio_pins, | 60 | .platform_data = &avila_i2c_gpio_data, |
60 | }, | 61 | }, |
61 | .num_resources = 0 | ||
62 | }; | 62 | }; |
63 | 63 | ||
64 | static struct resource avila_uart_resources[] = { | 64 | static struct resource avila_uart_resources[] = { |
@@ -133,7 +133,7 @@ static struct platform_device avila_pata = { | |||
133 | }; | 133 | }; |
134 | 134 | ||
135 | static struct platform_device *avila_devices[] __initdata = { | 135 | static struct platform_device *avila_devices[] __initdata = { |
136 | &avila_i2c_controller, | 136 | &avila_i2c_gpio, |
137 | &avila_flash, | 137 | &avila_flash, |
138 | &avila_uart | 138 | &avila_uart |
139 | }; | 139 | }; |
diff --git a/arch/arm/mach-ixp4xx/dsmg600-setup.c b/arch/arm/mach-ixp4xx/dsmg600-setup.c index 1e75e105c4f7..c473d408aa7c 100644 --- a/arch/arm/mach-ixp4xx/dsmg600-setup.c +++ b/arch/arm/mach-ixp4xx/dsmg600-setup.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/serial.h> | 15 | #include <linux/serial.h> |
16 | #include <linux/serial_8250.h> | 16 | #include <linux/serial_8250.h> |
17 | #include <linux/i2c-gpio.h> | ||
17 | 18 | ||
18 | #include <asm/mach-types.h> | 19 | #include <asm/mach-types.h> |
19 | #include <asm/mach/arch.h> | 20 | #include <asm/mach/arch.h> |
@@ -37,15 +38,17 @@ static struct platform_device dsmg600_flash = { | |||
37 | .resource = &dsmg600_flash_resource, | 38 | .resource = &dsmg600_flash_resource, |
38 | }; | 39 | }; |
39 | 40 | ||
40 | static struct ixp4xx_i2c_pins dsmg600_i2c_gpio_pins = { | 41 | static struct i2c_gpio_platform_data dsmg600_i2c_gpio_data = { |
41 | .sda_pin = DSMG600_SDA_PIN, | 42 | .sda_pin = DSMG600_SDA_PIN, |
42 | .scl_pin = DSMG600_SCL_PIN, | 43 | .scl_pin = DSMG600_SCL_PIN, |
43 | }; | 44 | }; |
44 | 45 | ||
45 | static struct platform_device dsmg600_i2c_controller = { | 46 | static struct platform_device dsmg600_i2c_gpio = { |
46 | .name = "IXP4XX-I2C", | 47 | .name = "i2c-gpio", |
47 | .id = 0, | 48 | .id = 0, |
48 | .dev.platform_data = &dsmg600_i2c_gpio_pins, | 49 | .dev = { |
50 | .platform_data = &dsmg600_i2c_gpio_data, | ||
51 | }, | ||
49 | }; | 52 | }; |
50 | 53 | ||
51 | #ifdef CONFIG_LEDS_CLASS | 54 | #ifdef CONFIG_LEDS_CLASS |
@@ -116,7 +119,7 @@ static struct platform_device dsmg600_uart = { | |||
116 | }; | 119 | }; |
117 | 120 | ||
118 | static struct platform_device *dsmg600_devices[] __initdata = { | 121 | static struct platform_device *dsmg600_devices[] __initdata = { |
119 | &dsmg600_i2c_controller, | 122 | &dsmg600_i2c_gpio, |
120 | &dsmg600_flash, | 123 | &dsmg600_flash, |
121 | }; | 124 | }; |
122 | 125 | ||
diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c index d5008d8fc9a5..e89070da28bf 100644 --- a/arch/arm/mach-ixp4xx/ixdp425-setup.c +++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/tty.h> | 15 | #include <linux/tty.h> |
16 | #include <linux/serial_8250.h> | 16 | #include <linux/serial_8250.h> |
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/i2c-gpio.h> | ||
18 | #include <linux/io.h> | 19 | #include <linux/io.h> |
19 | #include <linux/mtd/mtd.h> | 20 | #include <linux/mtd/mtd.h> |
20 | #include <linux/mtd/nand.h> | 21 | #include <linux/mtd/nand.h> |
@@ -120,18 +121,17 @@ static struct platform_device ixdp425_flash_nand = { | |||
120 | }; | 121 | }; |
121 | #endif /* CONFIG_MTD_NAND_PLATFORM */ | 122 | #endif /* CONFIG_MTD_NAND_PLATFORM */ |
122 | 123 | ||
123 | static struct ixp4xx_i2c_pins ixdp425_i2c_gpio_pins = { | 124 | static struct i2c_gpio_platform_data ixdp425_i2c_gpio_data = { |
124 | .sda_pin = IXDP425_SDA_PIN, | 125 | .sda_pin = IXDP425_SDA_PIN, |
125 | .scl_pin = IXDP425_SCL_PIN, | 126 | .scl_pin = IXDP425_SCL_PIN, |
126 | }; | 127 | }; |
127 | 128 | ||
128 | static struct platform_device ixdp425_i2c_controller = { | 129 | static struct platform_device ixdp425_i2c_gpio = { |
129 | .name = "IXP4XX-I2C", | 130 | .name = "i2c-gpio", |
130 | .id = 0, | 131 | .id = 0, |
131 | .dev = { | 132 | .dev = { |
132 | .platform_data = &ixdp425_i2c_gpio_pins, | 133 | .platform_data = &ixdp425_i2c_gpio_data, |
133 | }, | 134 | }, |
134 | .num_resources = 0 | ||
135 | }; | 135 | }; |
136 | 136 | ||
137 | static struct resource ixdp425_uart_resources[] = { | 137 | static struct resource ixdp425_uart_resources[] = { |
@@ -178,7 +178,7 @@ static struct platform_device ixdp425_uart = { | |||
178 | }; | 178 | }; |
179 | 179 | ||
180 | static struct platform_device *ixdp425_devices[] __initdata = { | 180 | static struct platform_device *ixdp425_devices[] __initdata = { |
181 | &ixdp425_i2c_controller, | 181 | &ixdp425_i2c_gpio, |
182 | &ixdp425_flash, | 182 | &ixdp425_flash, |
183 | #if defined(CONFIG_MTD_NAND_PLATFORM) || \ | 183 | #if defined(CONFIG_MTD_NAND_PLATFORM) || \ |
184 | defined(CONFIG_MTD_NAND_PLATFORM_MODULE) | 184 | defined(CONFIG_MTD_NAND_PLATFORM_MODULE) |
diff --git a/arch/arm/mach-ixp4xx/nas100d-setup.c b/arch/arm/mach-ixp4xx/nas100d-setup.c index 78a17413ceca..54d884fb2517 100644 --- a/arch/arm/mach-ixp4xx/nas100d-setup.c +++ b/arch/arm/mach-ixp4xx/nas100d-setup.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/serial.h> | 16 | #include <linux/serial.h> |
17 | #include <linux/serial_8250.h> | 17 | #include <linux/serial_8250.h> |
18 | #include <linux/leds.h> | 18 | #include <linux/leds.h> |
19 | #include <linux/i2c-gpio.h> | ||
19 | 20 | ||
20 | #include <asm/mach-types.h> | 21 | #include <asm/mach-types.h> |
21 | #include <asm/mach/arch.h> | 22 | #include <asm/mach/arch.h> |
@@ -68,16 +69,17 @@ static struct platform_device nas100d_leds = { | |||
68 | }; | 69 | }; |
69 | #endif | 70 | #endif |
70 | 71 | ||
71 | static struct ixp4xx_i2c_pins nas100d_i2c_gpio_pins = { | 72 | static struct i2c_gpio_platform_data nas100d_i2c_gpio_data = { |
72 | .sda_pin = NAS100D_SDA_PIN, | 73 | .sda_pin = NAS100D_SDA_PIN, |
73 | .scl_pin = NAS100D_SCL_PIN, | 74 | .scl_pin = NAS100D_SCL_PIN, |
74 | }; | 75 | }; |
75 | 76 | ||
76 | static struct platform_device nas100d_i2c_controller = { | 77 | static struct platform_device nas100d_i2c_gpio = { |
77 | .name = "IXP4XX-I2C", | 78 | .name = "i2c-gpio", |
78 | .id = 0, | 79 | .id = 0, |
79 | .dev.platform_data = &nas100d_i2c_gpio_pins, | 80 | .dev = { |
80 | .num_resources = 0, | 81 | .platform_data = &nas100d_i2c_gpio_data, |
82 | }, | ||
81 | }; | 83 | }; |
82 | 84 | ||
83 | static struct resource nas100d_uart_resources[] = { | 85 | static struct resource nas100d_uart_resources[] = { |
@@ -124,7 +126,7 @@ static struct platform_device nas100d_uart = { | |||
124 | }; | 126 | }; |
125 | 127 | ||
126 | static struct platform_device *nas100d_devices[] __initdata = { | 128 | static struct platform_device *nas100d_devices[] __initdata = { |
127 | &nas100d_i2c_controller, | 129 | &nas100d_i2c_gpio, |
128 | &nas100d_flash, | 130 | &nas100d_flash, |
129 | #ifdef CONFIG_LEDS_IXP4XX | 131 | #ifdef CONFIG_LEDS_IXP4XX |
130 | &nas100d_leds, | 132 | &nas100d_leds, |
diff --git a/arch/arm/mach-ixp4xx/nslu2-power.c b/arch/arm/mach-ixp4xx/nslu2-power.c index acd71e9c38a7..6f10dc208320 100644 --- a/arch/arm/mach-ixp4xx/nslu2-power.c +++ b/arch/arm/mach-ixp4xx/nslu2-power.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/reboot.h> | 21 | #include <linux/reboot.h> |
22 | #include <linux/irq.h> | 22 | #include <linux/irq.h> |
23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
24 | #include <linux/reboot.h> | ||
25 | 24 | ||
26 | #include <asm/mach-types.h> | 25 | #include <asm/mach-types.h> |
27 | 26 | ||
diff --git a/arch/arm/mach-ixp4xx/nslu2-setup.c b/arch/arm/mach-ixp4xx/nslu2-setup.c index 9bf8ccbcaccf..77277d27fcc5 100644 --- a/arch/arm/mach-ixp4xx/nslu2-setup.c +++ b/arch/arm/mach-ixp4xx/nslu2-setup.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/serial.h> | 18 | #include <linux/serial.h> |
19 | #include <linux/serial_8250.h> | 19 | #include <linux/serial_8250.h> |
20 | #include <linux/leds.h> | 20 | #include <linux/leds.h> |
21 | #include <linux/i2c-gpio.h> | ||
21 | 22 | ||
22 | #include <asm/mach-types.h> | 23 | #include <asm/mach-types.h> |
23 | #include <asm/mach/arch.h> | 24 | #include <asm/mach/arch.h> |
@@ -41,7 +42,7 @@ static struct platform_device nslu2_flash = { | |||
41 | .resource = &nslu2_flash_resource, | 42 | .resource = &nslu2_flash_resource, |
42 | }; | 43 | }; |
43 | 44 | ||
44 | static struct ixp4xx_i2c_pins nslu2_i2c_gpio_pins = { | 45 | static struct i2c_gpio_platform_data nslu2_i2c_gpio_data = { |
45 | .sda_pin = NSLU2_SDA_PIN, | 46 | .sda_pin = NSLU2_SDA_PIN, |
46 | .scl_pin = NSLU2_SCL_PIN, | 47 | .scl_pin = NSLU2_SCL_PIN, |
47 | }; | 48 | }; |
@@ -82,11 +83,12 @@ static struct platform_device nslu2_leds = { | |||
82 | }; | 83 | }; |
83 | #endif | 84 | #endif |
84 | 85 | ||
85 | static struct platform_device nslu2_i2c_controller = { | 86 | static struct platform_device nslu2_i2c_gpio = { |
86 | .name = "IXP4XX-I2C", | 87 | .name = "i2c-gpio", |
87 | .id = 0, | 88 | .id = 0, |
88 | .dev.platform_data = &nslu2_i2c_gpio_pins, | 89 | .dev = { |
89 | .num_resources = 0, | 90 | .platform_data = &nslu2_i2c_gpio_data, |
91 | }, | ||
90 | }; | 92 | }; |
91 | 93 | ||
92 | static struct platform_device nslu2_beeper = { | 94 | static struct platform_device nslu2_beeper = { |
@@ -139,7 +141,7 @@ static struct platform_device nslu2_uart = { | |||
139 | }; | 141 | }; |
140 | 142 | ||
141 | static struct platform_device *nslu2_devices[] __initdata = { | 143 | static struct platform_device *nslu2_devices[] __initdata = { |
142 | &nslu2_i2c_controller, | 144 | &nslu2_i2c_gpio, |
143 | &nslu2_flash, | 145 | &nslu2_flash, |
144 | &nslu2_beeper, | 146 | &nslu2_beeper, |
145 | #ifdef CONFIG_LEDS_IXP4XX | 147 | #ifdef CONFIG_LEDS_IXP4XX |
diff --git a/arch/arm/mach-ks8695/time.c b/arch/arm/mach-ks8695/time.c index d2c86e4a72eb..02f766b3121d 100644 --- a/arch/arm/mach-ks8695/time.c +++ b/arch/arm/mach-ks8695/time.c | |||
@@ -70,10 +70,7 @@ static unsigned long ks8695_gettimeoffset (void) | |||
70 | */ | 70 | */ |
71 | static irqreturn_t ks8695_timer_interrupt(int irq, void *dev_id) | 71 | static irqreturn_t ks8695_timer_interrupt(int irq, void *dev_id) |
72 | { | 72 | { |
73 | write_seqlock(&xtime_lock); | ||
74 | timer_tick(); | 73 | timer_tick(); |
75 | write_sequnlock(&xtime_lock); | ||
76 | |||
77 | return IRQ_HANDLED; | 74 | return IRQ_HANDLED; |
78 | } | 75 | } |
79 | 76 | ||
diff --git a/arch/arm/mach-lh7a40x/time.c b/arch/arm/mach-lh7a40x/time.c index c25316d02537..e50e60b33851 100644 --- a/arch/arm/mach-lh7a40x/time.c +++ b/arch/arm/mach-lh7a40x/time.c | |||
@@ -41,13 +41,9 @@ | |||
41 | static irqreturn_t | 41 | static irqreturn_t |
42 | lh7a40x_timer_interrupt(int irq, void *dev_id) | 42 | lh7a40x_timer_interrupt(int irq, void *dev_id) |
43 | { | 43 | { |
44 | write_seqlock(&xtime_lock); | ||
45 | |||
46 | TIMER_EOI = 0; | 44 | TIMER_EOI = 0; |
47 | timer_tick(); | 45 | timer_tick(); |
48 | 46 | ||
49 | write_sequnlock(&xtime_lock); | ||
50 | |||
51 | return IRQ_HANDLED; | 47 | return IRQ_HANDLED; |
52 | } | 48 | } |
53 | 49 | ||
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig new file mode 100644 index 000000000000..3553babbbf05 --- /dev/null +++ b/arch/arm/mach-msm/Kconfig | |||
@@ -0,0 +1,18 @@ | |||
1 | if ARCH_MSM7X00A | ||
2 | |||
3 | comment "MSM7X00A Board Type" | ||
4 | depends on ARCH_MSM7X00A | ||
5 | |||
6 | config MACH_HALIBUT | ||
7 | depends on ARCH_MSM7X00A | ||
8 | default y | ||
9 | bool "Halibut Board (QCT SURF7200A)" | ||
10 | help | ||
11 | Support for the Qualcomm SURF7200A eval board. | ||
12 | |||
13 | config MSM7X00A_IDLE | ||
14 | depends on ARCH_MSM7X00A | ||
15 | default y | ||
16 | bool "Idle Support for MSM7X00A" | ||
17 | |||
18 | endif | ||
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile new file mode 100644 index 000000000000..d12f23655850 --- /dev/null +++ b/arch/arm/mach-msm/Makefile | |||
@@ -0,0 +1,7 @@ | |||
1 | obj-y += io.o idle.o irq.o timer.o dma.o | ||
2 | |||
3 | # Common code for board init | ||
4 | obj-y += common.o | ||
5 | |||
6 | obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o | ||
7 | |||
diff --git a/arch/arm/mach-msm/Makefile.boot b/arch/arm/mach-msm/Makefile.boot new file mode 100644 index 000000000000..24dfbf8c07c4 --- /dev/null +++ b/arch/arm/mach-msm/Makefile.boot | |||
@@ -0,0 +1,3 @@ | |||
1 | zreladdr-y := 0x10008000 | ||
2 | params_phys-y := 0x10000100 | ||
3 | initrd_phys-y := 0x10800000 | ||
diff --git a/arch/arm/mach-msm/board-halibut.c b/arch/arm/mach-msm/board-halibut.c new file mode 100644 index 000000000000..86dfb2b5261c --- /dev/null +++ b/arch/arm/mach-msm/board-halibut.c | |||
@@ -0,0 +1,114 @@ | |||
1 | /* linux/arch/arm/mach-msm/board-halibut.c | ||
2 | * | ||
3 | * Copyright (C) 2007 Google, Inc. | ||
4 | * Author: Brian Swetland <swetland@google.com> | ||
5 | * | ||
6 | * This software is licensed under the terms of the GNU General Public | ||
7 | * License version 2, as published by the Free Software Foundation, and | ||
8 | * may be copied, distributed, and modified under those terms. | ||
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 | */ | ||
16 | |||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/input.h> | ||
21 | |||
22 | #include <asm/hardware.h> | ||
23 | #include <asm/mach-types.h> | ||
24 | #include <asm/mach/arch.h> | ||
25 | #include <asm/mach/map.h> | ||
26 | #include <asm/mach/flash.h> | ||
27 | |||
28 | #include <asm/arch/board.h> | ||
29 | #include <asm/arch/msm_iomap.h> | ||
30 | |||
31 | #include <asm/io.h> | ||
32 | #include <asm/delay.h> | ||
33 | |||
34 | #include <linux/mtd/nand.h> | ||
35 | #include <linux/mtd/partitions.h> | ||
36 | |||
37 | static struct resource smc91x_resources[] = { | ||
38 | [0] = { | ||
39 | .start = 0x9C004300, | ||
40 | .end = 0x9C004400, | ||
41 | .flags = IORESOURCE_MEM, | ||
42 | }, | ||
43 | [1] = { | ||
44 | .start = MSM_GPIO_TO_INT(49), | ||
45 | .end = MSM_GPIO_TO_INT(49), | ||
46 | .flags = IORESOURCE_IRQ, | ||
47 | }, | ||
48 | }; | ||
49 | |||
50 | static struct platform_device smc91x_device = { | ||
51 | .name = "smc91x", | ||
52 | .id = 0, | ||
53 | .num_resources = ARRAY_SIZE(smc91x_resources), | ||
54 | .resource = smc91x_resources, | ||
55 | }; | ||
56 | |||
57 | static void mddi0_panel_power(int on) | ||
58 | { | ||
59 | } | ||
60 | |||
61 | static struct msm_mddi_platform_data msm_mddi0_pdata = { | ||
62 | .panel_power = mddi0_panel_power, | ||
63 | .has_vsync_irq = 0, | ||
64 | }; | ||
65 | |||
66 | static struct platform_device msm_mddi0_device = { | ||
67 | .name = "msm_mddi", | ||
68 | .id = 0, | ||
69 | .dev = { | ||
70 | .platform_data = &msm_mddi0_pdata | ||
71 | }, | ||
72 | }; | ||
73 | |||
74 | static struct platform_device msm_serial0_device = { | ||
75 | .name = "msm_serial", | ||
76 | .id = 0, | ||
77 | }; | ||
78 | |||
79 | static struct platform_device *devices[] __initdata = { | ||
80 | &msm_serial0_device, | ||
81 | &msm_mddi0_device, | ||
82 | &smc91x_device, | ||
83 | }; | ||
84 | |||
85 | extern struct sys_timer msm_timer; | ||
86 | |||
87 | static void __init halibut_init_irq(void) | ||
88 | { | ||
89 | msm_init_irq(); | ||
90 | } | ||
91 | |||
92 | static void __init halibut_init(void) | ||
93 | { | ||
94 | platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
95 | msm_add_devices(); | ||
96 | } | ||
97 | |||
98 | static void __init halibut_map_io(void) | ||
99 | { | ||
100 | msm_map_common_io(); | ||
101 | } | ||
102 | |||
103 | MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)") | ||
104 | |||
105 | /* UART for LL DEBUG */ | ||
106 | .phys_io = MSM_UART1_PHYS, | ||
107 | .io_pg_offst = ((MSM_UART1_BASE) >> 18) & 0xfffc, | ||
108 | |||
109 | .boot_params = 0x10000100, | ||
110 | .map_io = halibut_map_io, | ||
111 | .init_irq = halibut_init_irq, | ||
112 | .init_machine = halibut_init, | ||
113 | .timer = &msm_timer, | ||
114 | MACHINE_END | ||
diff --git a/arch/arm/mach-msm/common.c b/arch/arm/mach-msm/common.c new file mode 100644 index 000000000000..3f5d3362f887 --- /dev/null +++ b/arch/arm/mach-msm/common.c | |||
@@ -0,0 +1,116 @@ | |||
1 | /* linux/arch/arm/mach-msm/common.c | ||
2 | * | ||
3 | * Common setup code for MSM7K Boards | ||
4 | * | ||
5 | * Copyright (C) 2007 Google, Inc. | ||
6 | * Author: Brian Swetland <swetland@google.com> | ||
7 | * | ||
8 | * This software is licensed under the terms of the GNU General Public | ||
9 | * License version 2, as published by the Free Software Foundation, and | ||
10 | * may be copied, distributed, and modified under those terms. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | |||
23 | #include <asm/mach/flash.h> | ||
24 | #include <asm/io.h> | ||
25 | |||
26 | #include <asm/setup.h> | ||
27 | |||
28 | #include <linux/mtd/nand.h> | ||
29 | #include <linux/mtd/partitions.h> | ||
30 | |||
31 | #include <asm/arch/msm_iomap.h> | ||
32 | |||
33 | #include <asm/arch/board.h> | ||
34 | |||
35 | struct flash_platform_data msm_nand_data = { | ||
36 | .parts = 0, | ||
37 | .nr_parts = 0, | ||
38 | }; | ||
39 | |||
40 | static struct resource msm_nand_resources[] = { | ||
41 | [0] = { | ||
42 | .start = 7, | ||
43 | .end = 7, | ||
44 | .flags = IORESOURCE_DMA, | ||
45 | }, | ||
46 | }; | ||
47 | |||
48 | static struct platform_device msm_nand_device = { | ||
49 | .name = "msm_nand", | ||
50 | .id = -1, | ||
51 | .num_resources = ARRAY_SIZE(msm_nand_resources), | ||
52 | .resource = msm_nand_resources, | ||
53 | .dev = { | ||
54 | .platform_data = &msm_nand_data, | ||
55 | }, | ||
56 | }; | ||
57 | |||
58 | static struct platform_device msm_smd_device = { | ||
59 | .name = "msm_smd", | ||
60 | .id = -1, | ||
61 | }; | ||
62 | |||
63 | static struct resource msm_i2c_resources[] = { | ||
64 | { | ||
65 | .start = MSM_I2C_BASE, | ||
66 | .end = MSM_I2C_BASE + MSM_I2C_SIZE - 1, | ||
67 | .flags = IORESOURCE_MEM, | ||
68 | }, | ||
69 | { | ||
70 | .start = INT_PWB_I2C, | ||
71 | .end = INT_PWB_I2C, | ||
72 | .flags = IORESOURCE_IRQ, | ||
73 | }, | ||
74 | }; | ||
75 | |||
76 | static struct platform_device msm_i2c_device = { | ||
77 | .name = "msm_i2c", | ||
78 | .id = 0, | ||
79 | .num_resources = ARRAY_SIZE(msm_i2c_resources), | ||
80 | .resource = msm_i2c_resources, | ||
81 | }; | ||
82 | |||
83 | static struct resource usb_resources[] = { | ||
84 | { | ||
85 | .start = MSM_HSUSB_PHYS, | ||
86 | .end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE, | ||
87 | .flags = IORESOURCE_MEM, | ||
88 | }, | ||
89 | { | ||
90 | .start = INT_USB_HS, | ||
91 | .end = INT_USB_HS, | ||
92 | .flags = IORESOURCE_IRQ, | ||
93 | }, | ||
94 | }; | ||
95 | |||
96 | static struct platform_device msm_hsusb_device = { | ||
97 | .name = "msm_hsusb", | ||
98 | .id = -1, | ||
99 | .num_resources = ARRAY_SIZE(usb_resources), | ||
100 | .resource = usb_resources, | ||
101 | .dev = { | ||
102 | .coherent_dma_mask = 0xffffffff, | ||
103 | }, | ||
104 | }; | ||
105 | |||
106 | static struct platform_device *devices[] __initdata = { | ||
107 | &msm_nand_device, | ||
108 | &msm_smd_device, | ||
109 | &msm_i2c_device, | ||
110 | &msm_hsusb_device, | ||
111 | }; | ||
112 | |||
113 | void __init msm_add_devices(void) | ||
114 | { | ||
115 | platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
116 | } | ||
diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c new file mode 100644 index 000000000000..8b0f339b3274 --- /dev/null +++ b/arch/arm/mach-msm/dma.c | |||
@@ -0,0 +1,214 @@ | |||
1 | /* linux/arch/arm/mach-msm/dma.c | ||
2 | * | ||
3 | * Copyright (C) 2007 Google, Inc. | ||
4 | * | ||
5 | * This software is licensed under the terms of the GNU General Public | ||
6 | * License version 2, as published by the Free Software Foundation, and | ||
7 | * may be copied, distributed, and modified under those terms. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <asm/io.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <asm/arch/dma.h> | ||
19 | |||
20 | #define MSM_DMOV_CHANNEL_COUNT 16 | ||
21 | |||
22 | enum { | ||
23 | MSM_DMOV_PRINT_ERRORS = 1, | ||
24 | MSM_DMOV_PRINT_IO = 2, | ||
25 | MSM_DMOV_PRINT_FLOW = 4 | ||
26 | }; | ||
27 | |||
28 | static DEFINE_SPINLOCK(msm_dmov_lock); | ||
29 | static struct msm_dmov_cmd active_command; | ||
30 | static struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT]; | ||
31 | static struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT]; | ||
32 | unsigned int msm_dmov_print_mask = MSM_DMOV_PRINT_ERRORS; | ||
33 | |||
34 | #define MSM_DMOV_DPRINTF(mask, format, args...) \ | ||
35 | do { \ | ||
36 | if ((mask) & msm_dmov_print_mask) \ | ||
37 | printk(KERN_ERR format, args); \ | ||
38 | } while (0) | ||
39 | #define PRINT_ERROR(format, args...) \ | ||
40 | MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_ERRORS, format, args); | ||
41 | #define PRINT_IO(format, args...) \ | ||
42 | MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_IO, format, args); | ||
43 | #define PRINT_FLOW(format, args...) \ | ||
44 | MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_FLOW, format, args); | ||
45 | |||
46 | void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd) | ||
47 | { | ||
48 | unsigned long irq_flags; | ||
49 | unsigned int status; | ||
50 | |||
51 | spin_lock_irqsave(&msm_dmov_lock, irq_flags); | ||
52 | status = readl(DMOV_STATUS(id)); | ||
53 | if (list_empty(&ready_commands[id]) && | ||
54 | (status & DMOV_STATUS_CMD_PTR_RDY)) { | ||
55 | #if 0 | ||
56 | if (list_empty(&active_commands[id])) { | ||
57 | PRINT_FLOW("msm_dmov_enqueue_cmd(%d), enable interrupt\n", id); | ||
58 | writel(DMOV_CONFIG_IRQ_EN, DMOV_CONFIG(id)); | ||
59 | } | ||
60 | #endif | ||
61 | PRINT_IO("msm_dmov_enqueue_cmd(%d), start command, status %x\n", id, status); | ||
62 | list_add_tail(&cmd->list, &active_commands[id]); | ||
63 | writel(cmd->cmdptr, DMOV_CMD_PTR(id)); | ||
64 | } else { | ||
65 | if (list_empty(&active_commands[id])) | ||
66 | PRINT_ERROR("msm_dmov_enqueue_cmd(%d), error datamover stalled, status %x\n", id, status); | ||
67 | |||
68 | PRINT_IO("msm_dmov_enqueue_cmd(%d), enqueue command, status %x\n", id, status); | ||
69 | list_add_tail(&cmd->list, &ready_commands[id]); | ||
70 | } | ||
71 | spin_unlock_irqrestore(&msm_dmov_lock, irq_flags); | ||
72 | } | ||
73 | |||
74 | struct msm_dmov_exec_cmdptr_cmd { | ||
75 | struct msm_dmov_cmd dmov_cmd; | ||
76 | struct completion complete; | ||
77 | unsigned id; | ||
78 | unsigned int result; | ||
79 | unsigned int flush[6]; | ||
80 | }; | ||
81 | |||
82 | static void dmov_exec_cmdptr_complete_func(struct msm_dmov_cmd *_cmd, unsigned int result) | ||
83 | { | ||
84 | struct msm_dmov_exec_cmdptr_cmd *cmd = container_of(_cmd, struct msm_dmov_exec_cmdptr_cmd, dmov_cmd); | ||
85 | cmd->result = result; | ||
86 | if (result != 0x80000002) { | ||
87 | cmd->flush[0] = readl(DMOV_FLUSH0(cmd->id)); | ||
88 | cmd->flush[1] = readl(DMOV_FLUSH1(cmd->id)); | ||
89 | cmd->flush[2] = readl(DMOV_FLUSH2(cmd->id)); | ||
90 | cmd->flush[3] = readl(DMOV_FLUSH3(cmd->id)); | ||
91 | cmd->flush[4] = readl(DMOV_FLUSH4(cmd->id)); | ||
92 | cmd->flush[5] = readl(DMOV_FLUSH5(cmd->id)); | ||
93 | } | ||
94 | complete(&cmd->complete); | ||
95 | } | ||
96 | |||
97 | int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr) | ||
98 | { | ||
99 | struct msm_dmov_exec_cmdptr_cmd cmd; | ||
100 | |||
101 | PRINT_FLOW("dmov_exec_cmdptr(%d, %x)\n", id, cmdptr); | ||
102 | |||
103 | cmd.dmov_cmd.cmdptr = cmdptr; | ||
104 | cmd.dmov_cmd.complete_func = dmov_exec_cmdptr_complete_func; | ||
105 | cmd.id = id; | ||
106 | init_completion(&cmd.complete); | ||
107 | |||
108 | msm_dmov_enqueue_cmd(id, &cmd.dmov_cmd); | ||
109 | wait_for_completion(&cmd.complete); | ||
110 | |||
111 | if (cmd.result != 0x80000002) { | ||
112 | PRINT_ERROR("dmov_exec_cmdptr(%d): ERROR, result: %x\n", id, cmd.result); | ||
113 | PRINT_ERROR("dmov_exec_cmdptr(%d): flush: %x %x %x %x\n", | ||
114 | id, cmd.flush[0], cmd.flush[1], cmd.flush[2], cmd.flush[3]); | ||
115 | return -EIO; | ||
116 | } | ||
117 | PRINT_FLOW("dmov_exec_cmdptr(%d, %x) done\n", id, cmdptr); | ||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | |||
122 | static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id) | ||
123 | { | ||
124 | unsigned int int_status, mask, id; | ||
125 | unsigned long irq_flags; | ||
126 | unsigned int ch_status; | ||
127 | unsigned int ch_result; | ||
128 | struct msm_dmov_cmd *cmd; | ||
129 | |||
130 | spin_lock_irqsave(&msm_dmov_lock, irq_flags); | ||
131 | |||
132 | int_status = readl(DMOV_ISR); /* read and clear interrupt */ | ||
133 | PRINT_FLOW("msm_datamover_irq_handler: DMOV_ISR %x\n", int_status); | ||
134 | |||
135 | while (int_status) { | ||
136 | mask = int_status & -int_status; | ||
137 | id = fls(mask) - 1; | ||
138 | PRINT_FLOW("msm_datamover_irq_handler %08x %08x id %d\n", int_status, mask, id); | ||
139 | int_status &= ~mask; | ||
140 | ch_status = readl(DMOV_STATUS(id)); | ||
141 | if (!(ch_status & DMOV_STATUS_RSLT_VALID)) { | ||
142 | PRINT_FLOW("msm_datamover_irq_handler id %d, result not valid %x\n", id, ch_status); | ||
143 | continue; | ||
144 | } | ||
145 | do { | ||
146 | ch_result = readl(DMOV_RSLT(id)); | ||
147 | if (list_empty(&active_commands[id])) { | ||
148 | PRINT_ERROR("msm_datamover_irq_handler id %d, got result " | ||
149 | "with no active command, status %x, result %x\n", | ||
150 | id, ch_status, ch_result); | ||
151 | cmd = NULL; | ||
152 | } else | ||
153 | cmd = list_entry(active_commands[id].next, typeof(*cmd), list); | ||
154 | PRINT_FLOW("msm_datamover_irq_handler id %d, status %x, result %x\n", id, ch_status, ch_result); | ||
155 | if (ch_result & DMOV_RSLT_DONE) { | ||
156 | PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", | ||
157 | id, ch_status); | ||
158 | PRINT_IO("msm_datamover_irq_handler id %d, got result " | ||
159 | "for %p, result %x\n", id, cmd, ch_result); | ||
160 | if (cmd) { | ||
161 | list_del(&cmd->list); | ||
162 | cmd->complete_func(cmd, ch_result); | ||
163 | } | ||
164 | } | ||
165 | if (ch_result & DMOV_RSLT_FLUSH) { | ||
166 | unsigned int flush0 = readl(DMOV_FLUSH0(id)); | ||
167 | PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status); | ||
168 | PRINT_FLOW("msm_datamover_irq_handler id %d, flush, result %x, flush0 %x\n", id, ch_result, flush0); | ||
169 | if (cmd) { | ||
170 | list_del(&cmd->list); | ||
171 | cmd->complete_func(cmd, ch_result); | ||
172 | } | ||
173 | } | ||
174 | if (ch_result & DMOV_RSLT_ERROR) { | ||
175 | unsigned int flush0 = readl(DMOV_FLUSH0(id)); | ||
176 | PRINT_ERROR("msm_datamover_irq_handler id %d, status %x\n", id, ch_status); | ||
177 | PRINT_ERROR("msm_datamover_irq_handler id %d, error, result %x, flush0 %x\n", id, ch_result, flush0); | ||
178 | if (cmd) { | ||
179 | list_del(&cmd->list); | ||
180 | cmd->complete_func(cmd, ch_result); | ||
181 | } | ||
182 | /* this does not seem to work, once we get an error */ | ||
183 | /* the datamover will no longer accept commands */ | ||
184 | writel(0, DMOV_FLUSH0(id)); | ||
185 | } | ||
186 | ch_status = readl(DMOV_STATUS(id)); | ||
187 | PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status); | ||
188 | if ((ch_status & DMOV_STATUS_CMD_PTR_RDY) && !list_empty(&ready_commands[id])) { | ||
189 | cmd = list_entry(ready_commands[id].next, typeof(*cmd), list); | ||
190 | list_del(&cmd->list); | ||
191 | list_add_tail(&cmd->list, &active_commands[id]); | ||
192 | PRINT_FLOW("msm_datamover_irq_handler id %d, start command\n", id); | ||
193 | writel(cmd->cmdptr, DMOV_CMD_PTR(id)); | ||
194 | } | ||
195 | } while (ch_status & DMOV_STATUS_RSLT_VALID); | ||
196 | PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status); | ||
197 | } | ||
198 | spin_unlock_irqrestore(&msm_dmov_lock, irq_flags); | ||
199 | return IRQ_HANDLED; | ||
200 | } | ||
201 | |||
202 | static int __init msm_init_datamover(void) | ||
203 | { | ||
204 | int i; | ||
205 | for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) { | ||
206 | INIT_LIST_HEAD(&ready_commands[i]); | ||
207 | INIT_LIST_HEAD(&active_commands[i]); | ||
208 | writel(DMOV_CONFIG_IRQ_EN | DMOV_CONFIG_FORCE_TOP_PTR_RSLT | DMOV_CONFIG_FORCE_FLUSH_RSLT, DMOV_CONFIG(i)); | ||
209 | } | ||
210 | return request_irq(INT_ADM_AARM, msm_datamover_irq_handler, 0, "msmdatamover", NULL); | ||
211 | } | ||
212 | |||
213 | arch_initcall(msm_init_datamover); | ||
214 | |||
diff --git a/arch/arm/mach-msm/idle.S b/arch/arm/mach-msm/idle.S new file mode 100644 index 000000000000..2b1cb7f16943 --- /dev/null +++ b/arch/arm/mach-msm/idle.S | |||
@@ -0,0 +1,36 @@ | |||
1 | /* linux/include/asm-arm/arch-msm/idle.S | ||
2 | * | ||
3 | * Idle processing for MSM7K - work around bugs with SWFI. | ||
4 | * | ||
5 | * Copyright (c) 2007 QUALCOMM Incorporated. | ||
6 | * Copyright (C) 2007 Google, Inc. | ||
7 | * | ||
8 | * This software is licensed under the terms of the GNU General Public | ||
9 | * License version 2, as published by the Free Software Foundation, and | ||
10 | * may be copied, distributed, and modified under those terms. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | #include <linux/linkage.h> | ||
20 | #include <asm/assembler.h> | ||
21 | |||
22 | ENTRY(arch_idle) | ||
23 | #ifdef CONFIG_MSM7X00A_IDLE | ||
24 | mrc p15, 0, r1, c1, c0, 0 /* read current CR */ | ||
25 | bic r0, r1, #(1 << 2) /* clear dcache bit */ | ||
26 | bic r0, r0, #(1 << 12) /* clear icache bit */ | ||
27 | mcr p15, 0, r0, c1, c0, 0 /* disable d/i cache */ | ||
28 | |||
29 | mov r0, #0 /* prepare wfi value */ | ||
30 | mcr p15, 0, r0, c7, c10, 0 /* flush the cache */ | ||
31 | mcr p15, 0, r0, c7, c10, 4 /* memory barrier */ | ||
32 | mcr p15, 0, r0, c7, c0, 4 /* wait for interrupt */ | ||
33 | |||
34 | mcr p15, 0, r1, c1, c0, 0 /* restore d/i cache */ | ||
35 | #endif | ||
36 | mov pc, lr | ||
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c new file mode 100644 index 000000000000..c39edb994a88 --- /dev/null +++ b/arch/arm/mach-msm/io.c | |||
@@ -0,0 +1,85 @@ | |||
1 | /* arch/arm/mach-msm/io.c | ||
2 | * | ||
3 | * MSM7K io support | ||
4 | * | ||
5 | * Copyright (C) 2007 Google, Inc. | ||
6 | * Author: Brian Swetland <swetland@google.com> | ||
7 | * | ||
8 | * This software is licensed under the terms of the GNU General Public | ||
9 | * License version 2, as published by the Free Software Foundation, and | ||
10 | * may be copied, distributed, and modified under those terms. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/init.h> | ||
21 | |||
22 | #include <asm/hardware.h> | ||
23 | #include <asm/io.h> | ||
24 | #include <asm/page.h> | ||
25 | #include <asm/arch/msm_iomap.h> | ||
26 | #include <asm/mach/map.h> | ||
27 | |||
28 | #include <asm/arch/board.h> | ||
29 | |||
30 | #define MSM_DEVICE(name) { \ | ||
31 | .virtual = MSM_##name##_BASE, \ | ||
32 | .pfn = __phys_to_pfn(MSM_##name##_PHYS), \ | ||
33 | .length = MSM_##name##_SIZE, \ | ||
34 | .type = MT_DEVICE_NONSHARED, \ | ||
35 | } | ||
36 | |||
37 | static struct map_desc msm_io_desc[] __initdata = { | ||
38 | MSM_DEVICE(VIC), | ||
39 | MSM_DEVICE(CSR), | ||
40 | MSM_DEVICE(GPT), | ||
41 | MSM_DEVICE(DMOV), | ||
42 | MSM_DEVICE(UART1), | ||
43 | MSM_DEVICE(UART2), | ||
44 | MSM_DEVICE(UART3), | ||
45 | MSM_DEVICE(I2C), | ||
46 | MSM_DEVICE(GPIO1), | ||
47 | MSM_DEVICE(GPIO2), | ||
48 | MSM_DEVICE(HSUSB), | ||
49 | MSM_DEVICE(CLK_CTL), | ||
50 | MSM_DEVICE(PMDH), | ||
51 | MSM_DEVICE(EMDH), | ||
52 | MSM_DEVICE(MDP), | ||
53 | { | ||
54 | .virtual = MSM_SHARED_RAM_BASE, | ||
55 | .pfn = __phys_to_pfn(MSM_SHARED_RAM_PHYS), | ||
56 | .length = MSM_SHARED_RAM_SIZE, | ||
57 | .type = MT_DEVICE, | ||
58 | }, | ||
59 | }; | ||
60 | |||
61 | void __init msm_map_common_io(void) | ||
62 | { | ||
63 | /* Make sure the peripheral register window is closed, since | ||
64 | * we will use PTE flags (TEX[1]=1,B=0,C=1) to determine which | ||
65 | * pages are peripheral interface or not. | ||
66 | */ | ||
67 | asm("mcr p15, 0, %0, c15, c2, 4" : : "r" (0)); | ||
68 | |||
69 | iotable_init(msm_io_desc, ARRAY_SIZE(msm_io_desc)); | ||
70 | } | ||
71 | |||
72 | void __iomem * | ||
73 | __msm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype) | ||
74 | { | ||
75 | if (mtype == MT_DEVICE) { | ||
76 | /* The peripherals in the 88000000 - D0000000 range | ||
77 | * are only accessable by type MT_DEVICE_NONSHARED. | ||
78 | * Adjust mtype as necessary to make this "just work." | ||
79 | */ | ||
80 | if ((phys_addr >= 0x88000000) && (phys_addr < 0xD0000000)) | ||
81 | mtype = MT_DEVICE_NONSHARED; | ||
82 | } | ||
83 | |||
84 | return __arm_ioremap(phys_addr, size, mtype); | ||
85 | } | ||
diff --git a/arch/arm/mach-msm/irq.c b/arch/arm/mach-msm/irq.c new file mode 100644 index 000000000000..24158040b789 --- /dev/null +++ b/arch/arm/mach-msm/irq.c | |||
@@ -0,0 +1,154 @@ | |||
1 | /* linux/arch/arm/mach-msm/irq.c | ||
2 | * | ||
3 | * Copyright (C) 2007 Google, Inc. | ||
4 | * | ||
5 | * This software is licensed under the terms of the GNU General Public | ||
6 | * License version 2, as published by the Free Software Foundation, and | ||
7 | * may be copied, distributed, and modified under those terms. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/init.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/sched.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/ptrace.h> | ||
21 | #include <linux/timer.h> | ||
22 | |||
23 | #include <linux/irq.h> | ||
24 | #include <asm/hardware.h> | ||
25 | |||
26 | #include <asm/io.h> | ||
27 | |||
28 | #include <asm/arch/msm_iomap.h> | ||
29 | |||
30 | #define VIC_REG(off) (MSM_VIC_BASE + (off)) | ||
31 | |||
32 | #define VIC_INT_SELECT0 VIC_REG(0x0000) /* 1: FIQ, 0: IRQ */ | ||
33 | #define VIC_INT_SELECT1 VIC_REG(0x0004) /* 1: FIQ, 0: IRQ */ | ||
34 | #define VIC_INT_EN0 VIC_REG(0x0010) | ||
35 | #define VIC_INT_EN1 VIC_REG(0x0014) | ||
36 | #define VIC_INT_ENCLEAR0 VIC_REG(0x0020) | ||
37 | #define VIC_INT_ENCLEAR1 VIC_REG(0x0024) | ||
38 | #define VIC_INT_ENSET0 VIC_REG(0x0030) | ||
39 | #define VIC_INT_ENSET1 VIC_REG(0x0034) | ||
40 | #define VIC_INT_TYPE0 VIC_REG(0x0040) /* 1: EDGE, 0: LEVEL */ | ||
41 | #define VIC_INT_TYPE1 VIC_REG(0x0044) /* 1: EDGE, 0: LEVEL */ | ||
42 | #define VIC_INT_POLARITY0 VIC_REG(0x0050) /* 1: NEG, 0: POS */ | ||
43 | #define VIC_INT_POLARITY1 VIC_REG(0x0054) /* 1: NEG, 0: POS */ | ||
44 | #define VIC_NO_PEND_VAL VIC_REG(0x0060) | ||
45 | #define VIC_INT_MASTEREN VIC_REG(0x0064) /* 1: IRQ, 2: FIQ */ | ||
46 | #define VIC_PROTECTION VIC_REG(0x006C) /* 1: ENABLE */ | ||
47 | #define VIC_CONFIG VIC_REG(0x0068) /* 1: USE ARM1136 VIC */ | ||
48 | #define VIC_IRQ_STATUS0 VIC_REG(0x0080) | ||
49 | #define VIC_IRQ_STATUS1 VIC_REG(0x0084) | ||
50 | #define VIC_FIQ_STATUS0 VIC_REG(0x0090) | ||
51 | #define VIC_FIQ_STATUS1 VIC_REG(0x0094) | ||
52 | #define VIC_RAW_STATUS0 VIC_REG(0x00A0) | ||
53 | #define VIC_RAW_STATUS1 VIC_REG(0x00A4) | ||
54 | #define VIC_INT_CLEAR0 VIC_REG(0x00B0) | ||
55 | #define VIC_INT_CLEAR1 VIC_REG(0x00B4) | ||
56 | #define VIC_SOFTINT0 VIC_REG(0x00C0) | ||
57 | #define VIC_SOFTINT1 VIC_REG(0x00C4) | ||
58 | #define VIC_IRQ_VEC_RD VIC_REG(0x00D0) /* pending int # */ | ||
59 | #define VIC_IRQ_VEC_PEND_RD VIC_REG(0x00D4) /* pending vector addr */ | ||
60 | #define VIC_IRQ_VEC_WR VIC_REG(0x00D8) | ||
61 | #define VIC_IRQ_IN_SERVICE VIC_REG(0x00E0) | ||
62 | #define VIC_IRQ_IN_STACK VIC_REG(0x00E4) | ||
63 | #define VIC_TEST_BUS_SEL VIC_REG(0x00E8) | ||
64 | |||
65 | #define VIC_VECTPRIORITY(n) VIC_REG(0x0200+((n) * 4)) | ||
66 | #define VIC_VECTADDR(n) VIC_REG(0x0400+((n) * 4)) | ||
67 | |||
68 | static void msm_irq_ack(unsigned int irq) | ||
69 | { | ||
70 | unsigned reg = VIC_INT_CLEAR0 + ((irq & 32) ? 4 : 0); | ||
71 | irq = 1 << (irq & 31); | ||
72 | writel(irq, reg); | ||
73 | } | ||
74 | |||
75 | static void msm_irq_mask(unsigned int irq) | ||
76 | { | ||
77 | unsigned reg = VIC_INT_ENCLEAR0 + ((irq & 32) ? 4 : 0); | ||
78 | writel(1 << (irq & 31), reg); | ||
79 | } | ||
80 | |||
81 | static void msm_irq_unmask(unsigned int irq) | ||
82 | { | ||
83 | unsigned reg = VIC_INT_ENSET0 + ((irq & 32) ? 4 : 0); | ||
84 | writel(1 << (irq & 31), reg); | ||
85 | } | ||
86 | |||
87 | static int msm_irq_set_wake(unsigned int irq, unsigned int on) | ||
88 | { | ||
89 | return -EINVAL; | ||
90 | } | ||
91 | |||
92 | static int msm_irq_set_type(unsigned int irq, unsigned int flow_type) | ||
93 | { | ||
94 | unsigned treg = VIC_INT_TYPE0 + ((irq & 32) ? 4 : 0); | ||
95 | unsigned preg = VIC_INT_POLARITY0 + ((irq & 32) ? 4 : 0); | ||
96 | int b = 1 << (irq & 31); | ||
97 | |||
98 | if (flow_type & (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW)) | ||
99 | writel(readl(preg) | b, preg); | ||
100 | if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_HIGH)) | ||
101 | writel(readl(preg) & (~b), preg); | ||
102 | |||
103 | if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) { | ||
104 | writel(readl(treg) | b, treg); | ||
105 | set_irq_handler(irq, handle_edge_irq); | ||
106 | } | ||
107 | if (flow_type & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW)) { | ||
108 | writel(readl(treg) & (~b), treg); | ||
109 | set_irq_handler(irq, handle_level_irq); | ||
110 | } | ||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | static struct irq_chip msm_irq_chip = { | ||
115 | .name = "msm", | ||
116 | .ack = msm_irq_ack, | ||
117 | .mask = msm_irq_mask, | ||
118 | .unmask = msm_irq_unmask, | ||
119 | .set_wake = msm_irq_set_wake, | ||
120 | .set_type = msm_irq_set_type, | ||
121 | }; | ||
122 | |||
123 | void __init msm_init_irq(void) | ||
124 | { | ||
125 | unsigned n; | ||
126 | |||
127 | /* select level interrupts */ | ||
128 | writel(0, VIC_INT_TYPE0); | ||
129 | writel(0, VIC_INT_TYPE1); | ||
130 | |||
131 | /* select highlevel interrupts */ | ||
132 | writel(0, VIC_INT_POLARITY0); | ||
133 | writel(0, VIC_INT_POLARITY1); | ||
134 | |||
135 | /* select IRQ for all INTs */ | ||
136 | writel(0, VIC_INT_SELECT0); | ||
137 | writel(0, VIC_INT_SELECT1); | ||
138 | |||
139 | /* disable all INTs */ | ||
140 | writel(0, VIC_INT_EN0); | ||
141 | writel(0, VIC_INT_EN1); | ||
142 | |||
143 | /* don't use 1136 vic */ | ||
144 | writel(0, VIC_CONFIG); | ||
145 | |||
146 | /* enable interrupt controller */ | ||
147 | writel(1, VIC_INT_MASTEREN); | ||
148 | |||
149 | for (n = 0; n < NR_MSM_IRQS; n++) { | ||
150 | set_irq_chip(n, &msm_irq_chip); | ||
151 | set_irq_handler(n, handle_level_irq); | ||
152 | set_irq_flags(n, IRQF_VALID); | ||
153 | } | ||
154 | } | ||
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c new file mode 100644 index 000000000000..bd4732d1ab3e --- /dev/null +++ b/arch/arm/mach-msm/timer.c | |||
@@ -0,0 +1,205 @@ | |||
1 | /* linux/arch/arm/mach-msm/timer.c | ||
2 | * | ||
3 | * Copyright (C) 2007 Google, Inc. | ||
4 | * | ||
5 | * This software is licensed under the terms of the GNU General Public | ||
6 | * License version 2, as published by the Free Software Foundation, and | ||
7 | * may be copied, distributed, and modified under those terms. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/init.h> | ||
17 | #include <linux/time.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/irq.h> | ||
20 | #include <linux/clk.h> | ||
21 | #include <linux/clockchips.h> | ||
22 | #include <linux/delay.h> | ||
23 | |||
24 | #include <asm/mach/time.h> | ||
25 | #include <asm/arch/msm_iomap.h> | ||
26 | |||
27 | #include <asm/io.h> | ||
28 | |||
29 | #define MSM_DGT_BASE (MSM_GPT_BASE + 0x10) | ||
30 | #define MSM_DGT_SHIFT (5) | ||
31 | |||
32 | #define TIMER_MATCH_VAL 0x0000 | ||
33 | #define TIMER_COUNT_VAL 0x0004 | ||
34 | #define TIMER_ENABLE 0x0008 | ||
35 | #define TIMER_ENABLE_CLR_ON_MATCH_EN 2 | ||
36 | #define TIMER_ENABLE_EN 1 | ||
37 | #define TIMER_CLEAR 0x000C | ||
38 | |||
39 | #define CSR_PROTECTION 0x0020 | ||
40 | #define CSR_PROTECTION_EN 1 | ||
41 | |||
42 | #define GPT_HZ 32768 | ||
43 | #define DGT_HZ 19200000 /* 19.2 MHz or 600 KHz after shift */ | ||
44 | |||
45 | struct msm_clock { | ||
46 | struct clock_event_device clockevent; | ||
47 | struct clocksource clocksource; | ||
48 | struct irqaction irq; | ||
49 | uint32_t regbase; | ||
50 | uint32_t freq; | ||
51 | uint32_t shift; | ||
52 | }; | ||
53 | |||
54 | static irqreturn_t msm_timer_interrupt(int irq, void *dev_id) | ||
55 | { | ||
56 | struct clock_event_device *evt = dev_id; | ||
57 | evt->event_handler(evt); | ||
58 | return IRQ_HANDLED; | ||
59 | } | ||
60 | |||
61 | static cycle_t msm_gpt_read(void) | ||
62 | { | ||
63 | return readl(MSM_GPT_BASE + TIMER_COUNT_VAL); | ||
64 | } | ||
65 | |||
66 | static cycle_t msm_dgt_read(void) | ||
67 | { | ||
68 | return readl(MSM_DGT_BASE + TIMER_COUNT_VAL) >> MSM_DGT_SHIFT; | ||
69 | } | ||
70 | |||
71 | static int msm_timer_set_next_event(unsigned long cycles, | ||
72 | struct clock_event_device *evt) | ||
73 | { | ||
74 | struct msm_clock *clock = container_of(evt, struct msm_clock, clockevent); | ||
75 | uint32_t now = readl(clock->regbase + TIMER_COUNT_VAL); | ||
76 | uint32_t alarm = now + (cycles << clock->shift); | ||
77 | int late; | ||
78 | |||
79 | writel(alarm, clock->regbase + TIMER_MATCH_VAL); | ||
80 | now = readl(clock->regbase + TIMER_COUNT_VAL); | ||
81 | late = now - alarm; | ||
82 | if (late >= (-2 << clock->shift) && late < DGT_HZ*5) { | ||
83 | printk(KERN_NOTICE "msm_timer_set_next_event(%lu) clock %s, " | ||
84 | "alarm already expired, now %x, alarm %x, late %d\n", | ||
85 | cycles, clock->clockevent.name, now, alarm, late); | ||
86 | return -ETIME; | ||
87 | } | ||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | static void msm_timer_set_mode(enum clock_event_mode mode, | ||
92 | struct clock_event_device *evt) | ||
93 | { | ||
94 | struct msm_clock *clock = container_of(evt, struct msm_clock, clockevent); | ||
95 | switch (mode) { | ||
96 | case CLOCK_EVT_MODE_RESUME: | ||
97 | case CLOCK_EVT_MODE_PERIODIC: | ||
98 | break; | ||
99 | case CLOCK_EVT_MODE_ONESHOT: | ||
100 | writel(TIMER_ENABLE_EN, clock->regbase + TIMER_ENABLE); | ||
101 | break; | ||
102 | case CLOCK_EVT_MODE_UNUSED: | ||
103 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
104 | writel(0, clock->regbase + TIMER_ENABLE); | ||
105 | break; | ||
106 | } | ||
107 | } | ||
108 | |||
109 | static struct msm_clock msm_clocks[] = { | ||
110 | { | ||
111 | .clockevent = { | ||
112 | .name = "gp_timer", | ||
113 | .features = CLOCK_EVT_FEAT_ONESHOT, | ||
114 | .shift = 32, | ||
115 | .rating = 200, | ||
116 | .set_next_event = msm_timer_set_next_event, | ||
117 | .set_mode = msm_timer_set_mode, | ||
118 | }, | ||
119 | .clocksource = { | ||
120 | .name = "gp_timer", | ||
121 | .rating = 200, | ||
122 | .read = msm_gpt_read, | ||
123 | .mask = CLOCKSOURCE_MASK(32), | ||
124 | .shift = 24, | ||
125 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
126 | }, | ||
127 | .irq = { | ||
128 | .name = "gp_timer", | ||
129 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_RISING, | ||
130 | .handler = msm_timer_interrupt, | ||
131 | .dev_id = &msm_clocks[0].clockevent, | ||
132 | .irq = INT_GP_TIMER_EXP | ||
133 | }, | ||
134 | .regbase = MSM_GPT_BASE, | ||
135 | .freq = GPT_HZ | ||
136 | }, | ||
137 | { | ||
138 | .clockevent = { | ||
139 | .name = "dg_timer", | ||
140 | .features = CLOCK_EVT_FEAT_ONESHOT, | ||
141 | .shift = 32 + MSM_DGT_SHIFT, | ||
142 | .rating = 300, | ||
143 | .set_next_event = msm_timer_set_next_event, | ||
144 | .set_mode = msm_timer_set_mode, | ||
145 | }, | ||
146 | .clocksource = { | ||
147 | .name = "dg_timer", | ||
148 | .rating = 300, | ||
149 | .read = msm_dgt_read, | ||
150 | .mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT)), | ||
151 | .shift = 24 - MSM_DGT_SHIFT, | ||
152 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
153 | }, | ||
154 | .irq = { | ||
155 | .name = "dg_timer", | ||
156 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_RISING, | ||
157 | .handler = msm_timer_interrupt, | ||
158 | .dev_id = &msm_clocks[1].clockevent, | ||
159 | .irq = INT_DEBUG_TIMER_EXP | ||
160 | }, | ||
161 | .regbase = MSM_DGT_BASE, | ||
162 | .freq = DGT_HZ >> MSM_DGT_SHIFT, | ||
163 | .shift = MSM_DGT_SHIFT | ||
164 | } | ||
165 | }; | ||
166 | |||
167 | static void __init msm_timer_init(void) | ||
168 | { | ||
169 | int i; | ||
170 | int res; | ||
171 | |||
172 | for (i = 0; i < ARRAY_SIZE(msm_clocks); i++) { | ||
173 | struct msm_clock *clock = &msm_clocks[i]; | ||
174 | struct clock_event_device *ce = &clock->clockevent; | ||
175 | struct clocksource *cs = &clock->clocksource; | ||
176 | writel(0, clock->regbase + TIMER_ENABLE); | ||
177 | writel(0, clock->regbase + TIMER_CLEAR); | ||
178 | writel(~0, clock->regbase + TIMER_MATCH_VAL); | ||
179 | |||
180 | ce->mult = div_sc(clock->freq, NSEC_PER_SEC, ce->shift); | ||
181 | /* allow at least 10 seconds to notice that the timer wrapped */ | ||
182 | ce->max_delta_ns = | ||
183 | clockevent_delta2ns(0xf0000000 >> clock->shift, ce); | ||
184 | /* 4 gets rounded down to 3 */ | ||
185 | ce->min_delta_ns = clockevent_delta2ns(4, ce); | ||
186 | ce->cpumask = cpumask_of_cpu(0); | ||
187 | |||
188 | cs->mult = clocksource_hz2mult(clock->freq, cs->shift); | ||
189 | res = clocksource_register(cs); | ||
190 | if (res) | ||
191 | printk(KERN_ERR "msm_timer_init: clocksource_register " | ||
192 | "failed for %s\n", cs->name); | ||
193 | |||
194 | res = setup_irq(clock->irq.irq, &clock->irq); | ||
195 | if (res) | ||
196 | printk(KERN_ERR "msm_timer_init: setup_irq " | ||
197 | "failed for %s\n", cs->name); | ||
198 | |||
199 | clockevents_register_device(ce); | ||
200 | } | ||
201 | } | ||
202 | |||
203 | struct sys_timer msm_timer = { | ||
204 | .init = msm_timer_init | ||
205 | }; | ||
diff --git a/arch/arm/mach-mx3/time.c b/arch/arm/mach-mx3/time.c index e81fb5c5d7c3..fb565c98dbfb 100644 --- a/arch/arm/mach-mx3/time.c +++ b/arch/arm/mach-mx3/time.c | |||
@@ -45,8 +45,6 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) | |||
45 | { | 45 | { |
46 | unsigned int next_match; | 46 | unsigned int next_match; |
47 | 47 | ||
48 | write_seqlock(&xtime_lock); | ||
49 | |||
50 | if (__raw_readl(MXC_GPT_GPTSR) & GPTSR_OF1) { | 48 | if (__raw_readl(MXC_GPT_GPTSR) & GPTSR_OF1) { |
51 | do { | 49 | do { |
52 | timer_tick(); | 50 | timer_tick(); |
@@ -57,8 +55,6 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) | |||
57 | __raw_readl(MXC_GPT_GPTCNT)) <= 0); | 55 | __raw_readl(MXC_GPT_GPTCNT)) <= 0); |
58 | } | 56 | } |
59 | 57 | ||
60 | write_sequnlock(&xtime_lock); | ||
61 | |||
62 | return IRQ_HANDLED; | 58 | return IRQ_HANDLED; |
63 | } | 59 | } |
64 | 60 | ||
diff --git a/arch/arm/mach-netx/time.c b/arch/arm/mach-netx/time.c index 4762e207b0bf..ea07b54afa59 100644 --- a/arch/arm/mach-netx/time.c +++ b/arch/arm/mach-netx/time.c | |||
@@ -33,12 +33,8 @@ | |||
33 | static irqreturn_t | 33 | static irqreturn_t |
34 | netx_timer_interrupt(int irq, void *dev_id) | 34 | netx_timer_interrupt(int irq, void *dev_id) |
35 | { | 35 | { |
36 | write_seqlock(&xtime_lock); | ||
37 | |||
38 | timer_tick(); | 36 | timer_tick(); |
39 | 37 | ||
40 | write_sequnlock(&xtime_lock); | ||
41 | |||
42 | /* acknowledge interrupt */ | 38 | /* acknowledge interrupt */ |
43 | writel(COUNTER_BIT(0), NETX_GPIO_IRQ); | 39 | writel(COUNTER_BIT(0), NETX_GPIO_IRQ); |
44 | 40 | ||
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c index 130681201c19..9393824cc150 100644 --- a/arch/arm/mach-omap1/board-h2.c +++ b/arch/arm/mach-omap1/board-h2.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/mtd/nand.h> | 27 | #include <linux/mtd/nand.h> |
28 | #include <linux/mtd/partitions.h> | 28 | #include <linux/mtd/partitions.h> |
29 | #include <linux/input.h> | 29 | #include <linux/input.h> |
30 | #include <linux/i2c/tps65010.h> | ||
30 | 31 | ||
31 | #include <asm/hardware.h> | 32 | #include <asm/hardware.h> |
32 | #include <asm/gpio.h> | 33 | #include <asm/gpio.h> |
@@ -36,7 +37,6 @@ | |||
36 | #include <asm/mach/flash.h> | 37 | #include <asm/mach/flash.h> |
37 | #include <asm/mach/map.h> | 38 | #include <asm/mach/map.h> |
38 | 39 | ||
39 | #include <asm/arch/tps65010.h> | ||
40 | #include <asm/arch/mux.h> | 40 | #include <asm/arch/mux.h> |
41 | #include <asm/arch/tc.h> | 41 | #include <asm/arch/tc.h> |
42 | #include <asm/arch/irda.h> | 42 | #include <asm/arch/irda.h> |
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c index 4f84ae273a1f..978cdab16535 100644 --- a/arch/arm/mach-omap1/board-h3.c +++ b/arch/arm/mach-omap1/board-h3.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/mtd/nand.h> | 26 | #include <linux/mtd/nand.h> |
27 | #include <linux/mtd/partitions.h> | 27 | #include <linux/mtd/partitions.h> |
28 | #include <linux/input.h> | 28 | #include <linux/input.h> |
29 | #include <linux/i2c/tps65010.h> | ||
29 | 30 | ||
30 | #include <asm/setup.h> | 31 | #include <asm/setup.h> |
31 | #include <asm/page.h> | 32 | #include <asm/page.h> |
@@ -37,7 +38,6 @@ | |||
37 | #include <asm/mach/flash.h> | 38 | #include <asm/mach/flash.h> |
38 | #include <asm/mach/map.h> | 39 | #include <asm/mach/map.h> |
39 | 40 | ||
40 | #include <asm/arch/tps65010.h> | ||
41 | #include <asm/arch/gpioexpander.h> | 41 | #include <asm/arch/gpioexpander.h> |
42 | #include <asm/arch/irqs.h> | 42 | #include <asm/arch/irqs.h> |
43 | #include <asm/arch/mux.h> | 43 | #include <asm/arch/mux.h> |
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c index 182a98a9df4c..e2c8ffd75cff 100644 --- a/arch/arm/mach-omap1/board-nokia770.c +++ b/arch/arm/mach-omap1/board-nokia770.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <asm/arch/common.h> | 32 | #include <asm/arch/common.h> |
33 | #include <asm/arch/dsp_common.h> | 33 | #include <asm/arch/dsp_common.h> |
34 | #include <asm/arch/aic23.h> | 34 | #include <asm/arch/aic23.h> |
35 | #include <asm/arch/gpio.h> | ||
36 | #include <asm/arch/omapfb.h> | 35 | #include <asm/arch/omapfb.h> |
37 | #include <asm/arch/lcd_mipid.h> | 36 | #include <asm/arch/lcd_mipid.h> |
38 | 37 | ||
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index 5db182da322b..4e016179f312 100644 --- a/arch/arm/mach-omap1/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c | |||
@@ -31,12 +31,13 @@ | |||
31 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
32 | #include <linux/interrupt.h> | 32 | #include <linux/interrupt.h> |
33 | #include <linux/irq.h> | 33 | #include <linux/irq.h> |
34 | #include <linux/interrupt.h> | ||
35 | #include <linux/i2c.h> | 34 | #include <linux/i2c.h> |
36 | 35 | ||
37 | #include <linux/mtd/mtd.h> | 36 | #include <linux/mtd/mtd.h> |
38 | #include <linux/mtd/partitions.h> | 37 | #include <linux/mtd/partitions.h> |
39 | 38 | ||
39 | #include <linux/i2c/tps65010.h> | ||
40 | |||
40 | #include <asm/hardware.h> | 41 | #include <asm/hardware.h> |
41 | #include <asm/gpio.h> | 42 | #include <asm/gpio.h> |
42 | 43 | ||
@@ -46,7 +47,6 @@ | |||
46 | #include <asm/mach/flash.h> | 47 | #include <asm/mach/flash.h> |
47 | 48 | ||
48 | #include <asm/arch/usb.h> | 49 | #include <asm/arch/usb.h> |
49 | #include <asm/arch/tps65010.h> | ||
50 | #include <asm/arch/mux.h> | 50 | #include <asm/arch/mux.h> |
51 | #include <asm/arch/tc.h> | 51 | #include <asm/arch/tc.h> |
52 | #include <asm/arch/common.h> | 52 | #include <asm/arch/common.h> |
diff --git a/arch/arm/mach-omap1/board-palmtt.c b/arch/arm/mach-omap1/board-palmtt.c index e47010fec275..ed7094a70064 100644 --- a/arch/arm/mach-omap1/board-palmtt.c +++ b/arch/arm/mach-omap1/board-palmtt.c | |||
@@ -42,7 +42,6 @@ | |||
42 | #include <asm/arch/common.h> | 42 | #include <asm/arch/common.h> |
43 | #include <asm/arch/omap-alsa.h> | 43 | #include <asm/arch/omap-alsa.h> |
44 | 44 | ||
45 | #include <linux/input.h> | ||
46 | #include <linux/spi/spi.h> | 45 | #include <linux/spi/spi.h> |
47 | #include <linux/spi/ads7846.h> | 46 | #include <linux/spi/ads7846.h> |
48 | 47 | ||
diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c index c275d517764a..a9a0f6610c3d 100644 --- a/arch/arm/mach-omap1/board-palmz71.c +++ b/arch/arm/mach-omap1/board-palmz71.c | |||
@@ -44,7 +44,6 @@ | |||
44 | #include <asm/arch/common.h> | 44 | #include <asm/arch/common.h> |
45 | #include <asm/arch/omap-alsa.h> | 45 | #include <asm/arch/omap-alsa.h> |
46 | 46 | ||
47 | #include <linux/input.h> | ||
48 | #include <linux/spi/spi.h> | 47 | #include <linux/spi/spi.h> |
49 | #include <linux/spi/ads7846.h> | 48 | #include <linux/spi/ads7846.h> |
50 | 49 | ||
diff --git a/arch/arm/mach-omap1/leds-osk.c b/arch/arm/mach-omap1/leds-osk.c index 86de303ecab2..6939d5e7569a 100644 --- a/arch/arm/mach-omap1/leds-osk.c +++ b/arch/arm/mach-omap1/leds-osk.c | |||
@@ -5,13 +5,13 @@ | |||
5 | */ | 5 | */ |
6 | #include <linux/init.h> | 6 | #include <linux/init.h> |
7 | #include <linux/workqueue.h> | 7 | #include <linux/workqueue.h> |
8 | #include <linux/i2c/tps65010.h> | ||
8 | 9 | ||
9 | #include <asm/hardware.h> | 10 | #include <asm/hardware.h> |
10 | #include <asm/leds.h> | 11 | #include <asm/leds.h> |
11 | #include <asm/system.h> | 12 | #include <asm/system.h> |
12 | 13 | ||
13 | #include <asm/arch/gpio.h> | 14 | #include <asm/arch/gpio.h> |
14 | #include <asm/arch/tps65010.h> | ||
15 | 15 | ||
16 | #include "leds.h" | 16 | #include "leds.h" |
17 | 17 | ||
diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c index d9805e3d9304..06b7e54a0128 100644 --- a/arch/arm/mach-omap1/pm.c +++ b/arch/arm/mach-omap1/pm.c | |||
@@ -639,7 +639,7 @@ static void omap_pm_finish(void) | |||
639 | } | 639 | } |
640 | 640 | ||
641 | 641 | ||
642 | static irqreturn_t omap_wakeup_interrupt(int irq, void *dev) | 642 | static irqreturn_t omap_wakeup_interrupt(int irq, void *dev) |
643 | { | 643 | { |
644 | return IRQ_HANDLED; | 644 | return IRQ_HANDLED; |
645 | } | 645 | } |
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c index 3bb49c17c858..94e38cc2bb6c 100644 --- a/arch/arm/mach-omap2/board-apollon.c +++ b/arch/arm/mach-omap2/board-apollon.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
28 | #include <linux/leds.h> | 28 | #include <linux/leds.h> |
29 | #include <linux/irq.h> | ||
30 | 29 | ||
31 | #include <asm/hardware.h> | 30 | #include <asm/hardware.h> |
32 | #include <asm/mach-types.h> | 31 | #include <asm/mach-types.h> |
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c index 8d322c20ccae..3234deedb946 100644 --- a/arch/arm/mach-omap2/timer-gp.c +++ b/arch/arm/mach-omap2/timer-gp.c | |||
@@ -40,13 +40,9 @@ static inline void omap2_gp_timer_start(unsigned long load_val) | |||
40 | 40 | ||
41 | static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id) | 41 | static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id) |
42 | { | 42 | { |
43 | write_seqlock(&xtime_lock); | ||
44 | |||
45 | omap_dm_timer_write_status(gptimer, OMAP_TIMER_INT_OVERFLOW); | 43 | omap_dm_timer_write_status(gptimer, OMAP_TIMER_INT_OVERFLOW); |
46 | timer_tick(); | 44 | timer_tick(); |
47 | 45 | ||
48 | write_sequnlock(&xtime_lock); | ||
49 | |||
50 | return IRQ_HANDLED; | 46 | return IRQ_HANDLED; |
51 | } | 47 | } |
52 | 48 | ||
diff --git a/arch/arm/mach-pnx4008/time.c b/arch/arm/mach-pnx4008/time.c index 67e05f005a6b..6d4ca8fc0cb4 100644 --- a/arch/arm/mach-pnx4008/time.c +++ b/arch/arm/mach-pnx4008/time.c | |||
@@ -51,8 +51,6 @@ static irqreturn_t pnx4008_timer_interrupt(int irq, void *dev_id) | |||
51 | { | 51 | { |
52 | if (__raw_readl(HSTIM_INT) & MATCH0_INT) { | 52 | if (__raw_readl(HSTIM_INT) & MATCH0_INT) { |
53 | 53 | ||
54 | write_seqlock(&xtime_lock); | ||
55 | |||
56 | do { | 54 | do { |
57 | timer_tick(); | 55 | timer_tick(); |
58 | 56 | ||
@@ -73,8 +71,6 @@ static irqreturn_t pnx4008_timer_interrupt(int irq, void *dev_id) | |||
73 | } while ((signed) | 71 | } while ((signed) |
74 | (__raw_readl(HSTIM_MATCH0) - | 72 | (__raw_readl(HSTIM_MATCH0) - |
75 | __raw_readl(HSTIM_COUNTER)) < 0); | 73 | __raw_readl(HSTIM_COUNTER)) < 0); |
76 | |||
77 | write_sequnlock(&xtime_lock); | ||
78 | } | 74 | } |
79 | 75 | ||
80 | return IRQ_HANDLED; | 76 | return IRQ_HANDLED; |
diff --git a/arch/arm/mach-pxa/akita-ioexp.c b/arch/arm/mach-pxa/akita-ioexp.c index 12d2fe0ceff6..254892ac30cd 100644 --- a/arch/arm/mach-pxa/akita-ioexp.c +++ b/arch/arm/mach-pxa/akita-ioexp.c | |||
@@ -29,7 +29,7 @@ | |||
29 | #define MAX7310_TIMEOUT 0x04 | 29 | #define MAX7310_TIMEOUT 0x04 |
30 | 30 | ||
31 | /* Addresses to scan */ | 31 | /* Addresses to scan */ |
32 | static unsigned short normal_i2c[] = { 0x18, I2C_CLIENT_END }; | 32 | static const unsigned short normal_i2c[] = { 0x18, I2C_CLIENT_END }; |
33 | 33 | ||
34 | /* I2C Magic */ | 34 | /* I2C Magic */ |
35 | I2C_CLIENT_INSMOD; | 35 | I2C_CLIENT_INSMOD; |
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index 9732d5d9466b..006a6e09589c 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c | |||
@@ -111,11 +111,14 @@ static const struct clkops clk_pxa25x_lcd_ops = { | |||
111 | * 95.842MHz -> MMC 19.169MHz, I2C 31.949MHz, FICP 47.923MHz, USB 47.923MHz | 111 | * 95.842MHz -> MMC 19.169MHz, I2C 31.949MHz, FICP 47.923MHz, USB 47.923MHz |
112 | * 147.456MHz -> UART 14.7456MHz, AC97 12.288MHz, I2S 5.672MHz (allegedly) | 112 | * 147.456MHz -> UART 14.7456MHz, AC97 12.288MHz, I2S 5.672MHz (allegedly) |
113 | */ | 113 | */ |
114 | static struct clk pxa25x_hwuart_clk = | ||
115 | INIT_CKEN("UARTCLK", HWUART, 14745600, 1, &pxa_device_hwuart.dev) | ||
116 | ; | ||
117 | |||
114 | static struct clk pxa25x_clks[] = { | 118 | static struct clk pxa25x_clks[] = { |
115 | INIT_CK("LCDCLK", LCD, &clk_pxa25x_lcd_ops, &pxa_device_fb.dev), | 119 | INIT_CK("LCDCLK", LCD, &clk_pxa25x_lcd_ops, &pxa_device_fb.dev), |
116 | INIT_CKEN("UARTCLK", FFUART, 14745600, 1, &pxa_device_ffuart.dev), | 120 | INIT_CKEN("UARTCLK", FFUART, 14745600, 1, &pxa_device_ffuart.dev), |
117 | INIT_CKEN("UARTCLK", BTUART, 14745600, 1, &pxa_device_btuart.dev), | 121 | INIT_CKEN("UARTCLK", BTUART, 14745600, 1, &pxa_device_btuart.dev), |
118 | INIT_CKEN("UARTCLK", BTUART, 14745600, 1, &pxa_device_btuart.dev), | ||
119 | INIT_CKEN("UARTCLK", STUART, 14745600, 1, NULL), | 122 | INIT_CKEN("UARTCLK", STUART, 14745600, 1, NULL), |
120 | INIT_CKEN("UDCCLK", USB, 47923000, 5, &pxa_device_udc.dev), | 123 | INIT_CKEN("UDCCLK", USB, 47923000, 5, &pxa_device_udc.dev), |
121 | INIT_CKEN("MMCCLK", MMC, 19169000, 0, &pxa_device_mci.dev), | 124 | INIT_CKEN("MMCCLK", MMC, 19169000, 0, &pxa_device_mci.dev), |
@@ -303,6 +306,10 @@ static int __init pxa25x_init(void) | |||
303 | { | 306 | { |
304 | int ret = 0; | 307 | int ret = 0; |
305 | 308 | ||
309 | /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */ | ||
310 | if (cpu_is_pxa25x()) | ||
311 | clks_register(&pxa25x_hwuart_clk, 1); | ||
312 | |||
306 | if (cpu_is_pxa21x() || cpu_is_pxa25x()) { | 313 | if (cpu_is_pxa21x() || cpu_is_pxa25x()) { |
307 | clks_register(pxa25x_clks, ARRAY_SIZE(pxa25x_clks)); | 314 | clks_register(pxa25x_clks, ARRAY_SIZE(pxa25x_clks)); |
308 | 315 | ||
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 8e126e6b74c3..57efebdc4324 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <asm/arch/ohci.h> | 24 | #include <asm/arch/ohci.h> |
25 | #include <asm/arch/pm.h> | 25 | #include <asm/arch/pm.h> |
26 | #include <asm/arch/dma.h> | 26 | #include <asm/arch/dma.h> |
27 | #include <asm/arch/i2c.h> | ||
27 | 28 | ||
28 | #include "generic.h" | 29 | #include "generic.h" |
29 | #include "devices.h" | 30 | #include "devices.h" |
@@ -423,6 +424,11 @@ struct platform_device pxa27x_device_i2c_power = { | |||
423 | .num_resources = ARRAY_SIZE(i2c_power_resources), | 424 | .num_resources = ARRAY_SIZE(i2c_power_resources), |
424 | }; | 425 | }; |
425 | 426 | ||
427 | void __init pxa_set_i2c_power_info(struct i2c_pxa_platform_data *info) | ||
428 | { | ||
429 | pxa27x_device_i2c_power.dev.platform_data = info; | ||
430 | } | ||
431 | |||
426 | static struct platform_device *devices[] __initdata = { | 432 | static struct platform_device *devices[] __initdata = { |
427 | &pxa_device_mci, | 433 | &pxa_device_mci, |
428 | &pxa_device_udc, | 434 | &pxa_device_udc, |
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index 61d9c9d69e6b..37e93f9ba8fc 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c | |||
@@ -86,7 +86,7 @@ unsigned int pxa3xx_get_clk_frequency_khz(int info) | |||
86 | HSS / 1000000, (HSS % 1000000) / 10000); | 86 | HSS / 1000000, (HSS % 1000000) / 10000); |
87 | } | 87 | } |
88 | 88 | ||
89 | return CLK; | 89 | return CLK / 1000; |
90 | } | 90 | } |
91 | 91 | ||
92 | /* | 92 | /* |
diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c index 422afee88169..b2eb38543d1c 100644 --- a/arch/arm/mach-pxa/ssp.c +++ b/arch/arm/mach-pxa/ssp.c | |||
@@ -67,7 +67,7 @@ static int use_count[PXA_SSP_PORTS] = {0, 0, 0}; | |||
67 | 67 | ||
68 | static irqreturn_t ssp_interrupt(int irq, void *dev_id) | 68 | static irqreturn_t ssp_interrupt(int irq, void *dev_id) |
69 | { | 69 | { |
70 | struct ssp_dev *dev = (struct ssp_dev*) dev_id; | 70 | struct ssp_dev *dev = dev_id; |
71 | unsigned int status = SSSR_P(dev->port); | 71 | unsigned int status = SSSR_P(dev->port); |
72 | 72 | ||
73 | SSSR_P(dev->port) = status; /* clear status bits */ | 73 | SSSR_P(dev->port) = status; /* clear status bits */ |
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index c7f1b44da40d..61d70218f1e8 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c | |||
@@ -530,8 +530,6 @@ static unsigned long realview_gettimeoffset(void) | |||
530 | */ | 530 | */ |
531 | static irqreturn_t realview_timer_interrupt(int irq, void *dev_id) | 531 | static irqreturn_t realview_timer_interrupt(int irq, void *dev_id) |
532 | { | 532 | { |
533 | write_seqlock(&xtime_lock); | ||
534 | |||
535 | // ...clear the interrupt | 533 | // ...clear the interrupt |
536 | writel(1, TIMER0_VA_BASE + TIMER_INTCLR); | 534 | writel(1, TIMER0_VA_BASE + TIMER_INTCLR); |
537 | 535 | ||
@@ -542,8 +540,6 @@ static irqreturn_t realview_timer_interrupt(int irq, void *dev_id) | |||
542 | update_process_times(user_mode(get_irq_regs())); | 540 | update_process_times(user_mode(get_irq_regs())); |
543 | #endif | 541 | #endif |
544 | 542 | ||
545 | write_sequnlock(&xtime_lock); | ||
546 | |||
547 | return IRQ_HANDLED; | 543 | return IRQ_HANDLED; |
548 | } | 544 | } |
549 | 545 | ||
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index 587864fe25fb..66175471fff3 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c | |||
@@ -530,7 +530,7 @@ static struct s3c2410fb_mach_info __initdata bast_fb_info = { | |||
530 | 530 | ||
531 | .displays = bast_lcd_info, | 531 | .displays = bast_lcd_info, |
532 | .num_displays = ARRAY_SIZE(bast_lcd_info), | 532 | .num_displays = ARRAY_SIZE(bast_lcd_info), |
533 | .default_display = 4, | 533 | .default_display = 1, |
534 | }; | 534 | }; |
535 | 535 | ||
536 | /* Standard BAST devices */ | 536 | /* Standard BAST devices */ |
@@ -540,7 +540,6 @@ static struct platform_device *bast_devices[] __initdata = { | |||
540 | &s3c_device_lcd, | 540 | &s3c_device_lcd, |
541 | &s3c_device_wdt, | 541 | &s3c_device_wdt, |
542 | &s3c_device_i2c, | 542 | &s3c_device_i2c, |
543 | &s3c_device_iis, | ||
544 | &s3c_device_rtc, | 543 | &s3c_device_rtc, |
545 | &s3c_device_nand, | 544 | &s3c_device_nand, |
546 | &bast_device_nor, | 545 | &bast_device_nor, |
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c index 9f43f3f124f5..3aade7b78fe5 100644 --- a/arch/arm/mach-s3c2410/mach-vr1000.c +++ b/arch/arm/mach-s3c2410/mach-vr1000.c | |||
@@ -365,7 +365,6 @@ static struct platform_device *vr1000_devices[] __initdata = { | |||
365 | &s3c_device_lcd, | 365 | &s3c_device_lcd, |
366 | &s3c_device_wdt, | 366 | &s3c_device_wdt, |
367 | &s3c_device_i2c, | 367 | &s3c_device_i2c, |
368 | &s3c_device_iis, | ||
369 | &s3c_device_adc, | 368 | &s3c_device_adc, |
370 | &serial_device, | 369 | &serial_device, |
371 | &vr1000_nor, | 370 | &vr1000_nor, |
diff --git a/arch/arm/mach-s3c2410/usb-simtec.c b/arch/arm/mach-s3c2410/usb-simtec.c index bcd562ac1d3d..6aec86a5da56 100644 --- a/arch/arm/mach-s3c2410/usb-simtec.c +++ b/arch/arm/mach-s3c2410/usb-simtec.c | |||
@@ -60,7 +60,7 @@ usb_simtec_powercontrol(int port, int to) | |||
60 | static irqreturn_t | 60 | static irqreturn_t |
61 | usb_simtec_ocirq(int irq, void *pw) | 61 | usb_simtec_ocirq(int irq, void *pw) |
62 | { | 62 | { |
63 | struct s3c2410_hcd_info *info = (struct s3c2410_hcd_info *)pw; | 63 | struct s3c2410_hcd_info *info = pw; |
64 | 64 | ||
65 | if (s3c2410_gpio_getpin(S3C2410_GPG10) == 0) { | 65 | if (s3c2410_gpio_getpin(S3C2410_GPG10) == 0) { |
66 | pr_debug("usb_simtec: over-current irq (oc detected)\n"); | 66 | pr_debug("usb_simtec: over-current irq (oc detected)\n"); |
diff --git a/arch/arm/mach-s3c2412/Kconfig b/arch/arm/mach-s3c2412/Kconfig index 8e8fe48ea47f..0b43431d4b75 100644 --- a/arch/arm/mach-s3c2412/Kconfig +++ b/arch/arm/mach-s3c2412/Kconfig | |||
@@ -10,6 +10,7 @@ config CPU_S3C2412 | |||
10 | select CPU_LLSERIAL_S3C2440 | 10 | select CPU_LLSERIAL_S3C2440 |
11 | select S3C2412_PM if PM | 11 | select S3C2412_PM if PM |
12 | select S3C2412_DMA if S3C2410_DMA | 12 | select S3C2412_DMA if S3C2410_DMA |
13 | select S3C2410_GPIO | ||
13 | help | 14 | help |
14 | Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line | 15 | Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line |
15 | 16 | ||
diff --git a/arch/arm/mach-s3c2412/Makefile b/arch/arm/mach-s3c2412/Makefile index f8e011691b31..267f3348301e 100644 --- a/arch/arm/mach-s3c2412/Makefile +++ b/arch/arm/mach-s3c2412/Makefile | |||
@@ -12,8 +12,9 @@ obj- := | |||
12 | obj-$(CONFIG_CPU_S3C2412) += s3c2412.o | 12 | obj-$(CONFIG_CPU_S3C2412) += s3c2412.o |
13 | obj-$(CONFIG_CPU_S3C2412) += irq.o | 13 | obj-$(CONFIG_CPU_S3C2412) += irq.o |
14 | obj-$(CONFIG_CPU_S3C2412) += clock.o | 14 | obj-$(CONFIG_CPU_S3C2412) += clock.o |
15 | obj-$(CONFIG_CPU_S3C2412) += gpio.o | ||
15 | obj-$(CONFIG_S3C2412_DMA) += dma.o | 16 | obj-$(CONFIG_S3C2412_DMA) += dma.o |
16 | obj-$(CONFIG_S3C2412_PM) += pm.o | 17 | obj-$(CONFIG_S3C2412_PM) += pm.o sleep.o |
17 | 18 | ||
18 | # Machine support | 19 | # Machine support |
19 | 20 | ||
diff --git a/arch/arm/mach-s3c2412/clock.c b/arch/arm/mach-s3c2412/clock.c index 458993601897..2697a65ba727 100644 --- a/arch/arm/mach-s3c2412/clock.c +++ b/arch/arm/mach-s3c2412/clock.c | |||
@@ -217,7 +217,7 @@ static int s3c2412_setparent_msysclk(struct clk *clk, struct clk *parent) | |||
217 | 217 | ||
218 | if (parent == &clk_mdivclk) | 218 | if (parent == &clk_mdivclk) |
219 | clksrc &= ~S3C2412_CLKSRC_MSYSCLK_MPLL; | 219 | clksrc &= ~S3C2412_CLKSRC_MSYSCLK_MPLL; |
220 | else if (parent == &clk_upll) | 220 | else if (parent == &clk_mpll) |
221 | clksrc |= S3C2412_CLKSRC_MSYSCLK_MPLL; | 221 | clksrc |= S3C2412_CLKSRC_MSYSCLK_MPLL; |
222 | else | 222 | else |
223 | return -EINVAL; | 223 | return -EINVAL; |
@@ -234,6 +234,45 @@ static struct clk clk_msysclk = { | |||
234 | .set_parent = s3c2412_setparent_msysclk, | 234 | .set_parent = s3c2412_setparent_msysclk, |
235 | }; | 235 | }; |
236 | 236 | ||
237 | static int s3c2412_setparent_armclk(struct clk *clk, struct clk *parent) | ||
238 | { | ||
239 | unsigned long flags; | ||
240 | unsigned long clkdiv; | ||
241 | unsigned long dvs; | ||
242 | |||
243 | /* Note, we current equate fclk andf msysclk for S3C2412 */ | ||
244 | |||
245 | if (parent == &clk_msysclk || parent == &clk_f) | ||
246 | dvs = 0; | ||
247 | else if (parent == &clk_h) | ||
248 | dvs = S3C2412_CLKDIVN_DVSEN; | ||
249 | else | ||
250 | return -EINVAL; | ||
251 | |||
252 | clk->parent = parent; | ||
253 | |||
254 | /* update this under irq lockdown, clkdivn is not protected | ||
255 | * by the clock system. */ | ||
256 | |||
257 | local_irq_save(flags); | ||
258 | |||
259 | clkdiv = __raw_readl(S3C2410_CLKDIVN); | ||
260 | clkdiv &= ~S3C2412_CLKDIVN_DVSEN; | ||
261 | clkdiv |= dvs; | ||
262 | __raw_writel(clkdiv, S3C2410_CLKDIVN); | ||
263 | |||
264 | local_irq_restore(flags); | ||
265 | |||
266 | return 0; | ||
267 | } | ||
268 | |||
269 | static struct clk clk_armclk = { | ||
270 | .name = "armclk", | ||
271 | .id = -1, | ||
272 | .parent = &clk_msysclk, | ||
273 | .set_parent = s3c2412_setparent_armclk, | ||
274 | }; | ||
275 | |||
237 | /* these next clocks have an divider immediately after them, | 276 | /* these next clocks have an divider immediately after them, |
238 | * so we can register them with their divider and leave out the | 277 | * so we can register them with their divider and leave out the |
239 | * intermediate clock stage | 278 | * intermediate clock stage |
@@ -630,11 +669,13 @@ static struct clk *clks[] __initdata = { | |||
630 | &clk_erefclk, | 669 | &clk_erefclk, |
631 | &clk_urefclk, | 670 | &clk_urefclk, |
632 | &clk_mrefclk, | 671 | &clk_mrefclk, |
672 | &clk_armclk, | ||
633 | }; | 673 | }; |
634 | 674 | ||
635 | int __init s3c2412_baseclk_add(void) | 675 | int __init s3c2412_baseclk_add(void) |
636 | { | 676 | { |
637 | unsigned long clkcon = __raw_readl(S3C2410_CLKCON); | 677 | unsigned long clkcon = __raw_readl(S3C2410_CLKCON); |
678 | unsigned int dvs; | ||
638 | struct clk *clkp; | 679 | struct clk *clkp; |
639 | int ret; | 680 | int ret; |
640 | int ptr; | 681 | int ptr; |
@@ -643,6 +684,8 @@ int __init s3c2412_baseclk_add(void) | |||
643 | clk_usb_bus.parent = &clk_usbsrc; | 684 | clk_usb_bus.parent = &clk_usbsrc; |
644 | clk_usb_bus.rate = 0x0; | 685 | clk_usb_bus.rate = 0x0; |
645 | 686 | ||
687 | clk_f.parent = &clk_msysclk; | ||
688 | |||
646 | s3c2412_clk_initparents(); | 689 | s3c2412_clk_initparents(); |
647 | 690 | ||
648 | for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) { | 691 | for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) { |
@@ -655,6 +698,15 @@ int __init s3c2412_baseclk_add(void) | |||
655 | } | 698 | } |
656 | } | 699 | } |
657 | 700 | ||
701 | /* set the dvs state according to what we got at boot time */ | ||
702 | |||
703 | dvs = __raw_readl(S3C2410_CLKDIVN) & S3C2412_CLKDIVN_DVSEN; | ||
704 | |||
705 | if (dvs) | ||
706 | clk_armclk.parent = &clk_h; | ||
707 | |||
708 | printk(KERN_INFO "S3C2412: DVS is %s\n", dvs ? "on" : "off"); | ||
709 | |||
658 | /* ensure usb bus clock is within correct rate of 48MHz */ | 710 | /* ensure usb bus clock is within correct rate of 48MHz */ |
659 | 711 | ||
660 | if (clk_get_rate(&clk_usb_bus) != (48 * 1000 * 1000)) { | 712 | if (clk_get_rate(&clk_usb_bus) != (48 * 1000 * 1000)) { |
diff --git a/arch/arm/mach-s3c2412/dma.c b/arch/arm/mach-s3c2412/dma.c index 53c1d5bbce19..1dd864993566 100644 --- a/arch/arm/mach-s3c2412/dma.c +++ b/arch/arm/mach-s3c2412/dma.c | |||
@@ -30,6 +30,7 @@ | |||
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/plat-s3c24xx/regs-s3c2412-iis.h> | ||
33 | #include <asm/plat-s3c24xx/regs-iis.h> | 34 | #include <asm/plat-s3c24xx/regs-iis.h> |
34 | #include <asm/plat-s3c24xx/regs-spi.h> | 35 | #include <asm/plat-s3c24xx/regs-spi.h> |
35 | 36 | ||
@@ -39,106 +40,141 @@ static struct s3c24xx_dma_map __initdata s3c2412_dma_mappings[] = { | |||
39 | [DMACH_XD0] = { | 40 | [DMACH_XD0] = { |
40 | .name = "xdreq0", | 41 | .name = "xdreq0", |
41 | .channels = MAP(S3C2412_DMAREQSEL_XDREQ0), | 42 | .channels = MAP(S3C2412_DMAREQSEL_XDREQ0), |
43 | .channels_rx = MAP(S3C2412_DMAREQSEL_XDREQ0), | ||
42 | }, | 44 | }, |
43 | [DMACH_XD1] = { | 45 | [DMACH_XD1] = { |
44 | .name = "xdreq1", | 46 | .name = "xdreq1", |
45 | .channels = MAP(S3C2412_DMAREQSEL_XDREQ1), | 47 | .channels = MAP(S3C2412_DMAREQSEL_XDREQ1), |
48 | .channels_rx = MAP(S3C2412_DMAREQSEL_XDREQ1), | ||
46 | }, | 49 | }, |
47 | [DMACH_SDI] = { | 50 | [DMACH_SDI] = { |
48 | .name = "sdi", | 51 | .name = "sdi", |
49 | .channels = MAP(S3C2412_DMAREQSEL_SDI), | 52 | .channels = MAP(S3C2412_DMAREQSEL_SDI), |
50 | .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO, | 53 | .channels_rx = MAP(S3C2412_DMAREQSEL_SDI), |
51 | .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO, | 54 | .hw_addr.to = S3C2410_PA_SDI + S3C2410_SDIDATA, |
55 | .hw_addr.from = S3C2410_PA_SDI + S3C2410_SDIDATA, | ||
52 | }, | 56 | }, |
53 | [DMACH_SPI0] = { | 57 | [DMACH_SPI0] = { |
54 | .name = "spi0", | 58 | .name = "spi0", |
55 | .channels = MAP(S3C2412_DMAREQSEL_SPI0TX), | 59 | .channels = MAP(S3C2412_DMAREQSEL_SPI0TX), |
60 | .channels_rx = MAP(S3C2412_DMAREQSEL_SPI0RX), | ||
56 | .hw_addr.to = S3C2410_PA_SPI + S3C2410_SPTDAT, | 61 | .hw_addr.to = S3C2410_PA_SPI + S3C2410_SPTDAT, |
57 | .hw_addr.from = S3C2410_PA_SPI + S3C2410_SPRDAT, | 62 | .hw_addr.from = S3C2410_PA_SPI + S3C2410_SPRDAT, |
58 | }, | 63 | }, |
59 | [DMACH_SPI1] = { | 64 | [DMACH_SPI1] = { |
60 | .name = "spi1", | 65 | .name = "spi1", |
61 | .channels = MAP(S3C2412_DMAREQSEL_SPI1TX), | 66 | .channels = MAP(S3C2412_DMAREQSEL_SPI1TX), |
67 | .channels_rx = MAP(S3C2412_DMAREQSEL_SPI1RX), | ||
62 | .hw_addr.to = S3C2410_PA_SPI + S3C2412_SPI1 + S3C2410_SPTDAT, | 68 | .hw_addr.to = S3C2410_PA_SPI + S3C2412_SPI1 + S3C2410_SPTDAT, |
63 | .hw_addr.from = S3C2410_PA_SPI + S3C2412_SPI1 + S3C2410_SPRDAT, | 69 | .hw_addr.from = S3C2410_PA_SPI + S3C2412_SPI1 + S3C2410_SPRDAT, |
64 | }, | 70 | }, |
65 | [DMACH_UART0] = { | 71 | [DMACH_UART0] = { |
66 | .name = "uart0", | 72 | .name = "uart0", |
67 | .channels = MAP(S3C2412_DMAREQSEL_UART0_0), | 73 | .channels = MAP(S3C2412_DMAREQSEL_UART0_0), |
74 | .channels_rx = MAP(S3C2412_DMAREQSEL_UART0_0), | ||
68 | .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH, | 75 | .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH, |
69 | .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH, | 76 | .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH, |
70 | }, | 77 | }, |
71 | [DMACH_UART1] = { | 78 | [DMACH_UART1] = { |
72 | .name = "uart1", | 79 | .name = "uart1", |
73 | .channels = MAP(S3C2412_DMAREQSEL_UART1_0), | 80 | .channels = MAP(S3C2412_DMAREQSEL_UART1_0), |
81 | .channels_rx = MAP(S3C2412_DMAREQSEL_UART1_0), | ||
74 | .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH, | 82 | .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH, |
75 | .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH, | 83 | .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH, |
76 | }, | 84 | }, |
77 | [DMACH_UART2] = { | 85 | [DMACH_UART2] = { |
78 | .name = "uart2", | 86 | .name = "uart2", |
79 | .channels = MAP(S3C2412_DMAREQSEL_UART2_0), | 87 | .channels = MAP(S3C2412_DMAREQSEL_UART2_0), |
88 | .channels_rx = MAP(S3C2412_DMAREQSEL_UART2_0), | ||
80 | .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH, | 89 | .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH, |
81 | .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH, | 90 | .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH, |
82 | }, | 91 | }, |
83 | [DMACH_UART0_SRC2] = { | 92 | [DMACH_UART0_SRC2] = { |
84 | .name = "uart0", | 93 | .name = "uart0", |
85 | .channels = MAP(S3C2412_DMAREQSEL_UART0_1), | 94 | .channels = MAP(S3C2412_DMAREQSEL_UART0_1), |
95 | .channels_rx = MAP(S3C2412_DMAREQSEL_UART0_1), | ||
86 | .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH, | 96 | .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH, |
87 | .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH, | 97 | .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH, |
88 | }, | 98 | }, |
89 | [DMACH_UART1_SRC2] = { | 99 | [DMACH_UART1_SRC2] = { |
90 | .name = "uart1", | 100 | .name = "uart1", |
91 | .channels = MAP(S3C2412_DMAREQSEL_UART1_1), | 101 | .channels = MAP(S3C2412_DMAREQSEL_UART1_1), |
102 | .channels_rx = MAP(S3C2412_DMAREQSEL_UART1_1), | ||
92 | .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH, | 103 | .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH, |
93 | .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH, | 104 | .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH, |
94 | }, | 105 | }, |
95 | [DMACH_UART2_SRC2] = { | 106 | [DMACH_UART2_SRC2] = { |
96 | .name = "uart2", | 107 | .name = "uart2", |
97 | .channels = MAP(S3C2412_DMAREQSEL_UART2_1), | 108 | .channels = MAP(S3C2412_DMAREQSEL_UART2_1), |
109 | .channels_rx = MAP(S3C2412_DMAREQSEL_UART2_1), | ||
98 | .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH, | 110 | .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH, |
99 | .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH, | 111 | .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH, |
100 | }, | 112 | }, |
101 | [DMACH_TIMER] = { | 113 | [DMACH_TIMER] = { |
102 | .name = "timer", | 114 | .name = "timer", |
103 | .channels = MAP(S3C2412_DMAREQSEL_TIMER), | 115 | .channels = MAP(S3C2412_DMAREQSEL_TIMER), |
116 | .channels_rx = MAP(S3C2412_DMAREQSEL_TIMER), | ||
104 | }, | 117 | }, |
105 | [DMACH_I2S_IN] = { | 118 | [DMACH_I2S_IN] = { |
106 | .name = "i2s-sdi", | 119 | .name = "i2s-sdi", |
107 | .channels = MAP(S3C2412_DMAREQSEL_I2SRX), | 120 | .channels = MAP(S3C2412_DMAREQSEL_I2SRX), |
108 | .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO, | 121 | .channels_rx = MAP(S3C2412_DMAREQSEL_I2SRX), |
122 | .hw_addr.from = S3C2410_PA_IIS + S3C2412_IISRXD, | ||
109 | }, | 123 | }, |
110 | [DMACH_I2S_OUT] = { | 124 | [DMACH_I2S_OUT] = { |
111 | .name = "i2s-sdo", | 125 | .name = "i2s-sdo", |
112 | .channels = MAP(S3C2412_DMAREQSEL_I2STX), | 126 | .channels = MAP(S3C2412_DMAREQSEL_I2STX), |
113 | .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO, | 127 | .channels_rx = MAP(S3C2412_DMAREQSEL_I2STX), |
128 | .hw_addr.to = S3C2410_PA_IIS + S3C2412_IISTXD, | ||
114 | }, | 129 | }, |
115 | [DMACH_USB_EP1] = { | 130 | [DMACH_USB_EP1] = { |
116 | .name = "usb-ep1", | 131 | .name = "usb-ep1", |
117 | .channels = MAP(S3C2412_DMAREQSEL_USBEP1), | 132 | .channels = MAP(S3C2412_DMAREQSEL_USBEP1), |
133 | .channels_rx = MAP(S3C2412_DMAREQSEL_USBEP1), | ||
118 | }, | 134 | }, |
119 | [DMACH_USB_EP2] = { | 135 | [DMACH_USB_EP2] = { |
120 | .name = "usb-ep2", | 136 | .name = "usb-ep2", |
121 | .channels = MAP(S3C2412_DMAREQSEL_USBEP2), | 137 | .channels = MAP(S3C2412_DMAREQSEL_USBEP2), |
138 | .channels_rx = MAP(S3C2412_DMAREQSEL_USBEP2), | ||
122 | }, | 139 | }, |
123 | [DMACH_USB_EP3] = { | 140 | [DMACH_USB_EP3] = { |
124 | .name = "usb-ep3", | 141 | .name = "usb-ep3", |
125 | .channels = MAP(S3C2412_DMAREQSEL_USBEP3), | 142 | .channels = MAP(S3C2412_DMAREQSEL_USBEP3), |
143 | .channels_rx = MAP(S3C2412_DMAREQSEL_USBEP3), | ||
126 | }, | 144 | }, |
127 | [DMACH_USB_EP4] = { | 145 | [DMACH_USB_EP4] = { |
128 | .name = "usb-ep4", | 146 | .name = "usb-ep4", |
129 | .channels = MAP(S3C2412_DMAREQSEL_USBEP4), | 147 | .channels = MAP(S3C2412_DMAREQSEL_USBEP4), |
148 | .channels_rx = MAP(S3C2412_DMAREQSEL_USBEP4), | ||
130 | }, | 149 | }, |
131 | }; | 150 | }; |
132 | 151 | ||
152 | static void s3c2412_dma_direction(struct s3c2410_dma_chan *chan, | ||
153 | struct s3c24xx_dma_map *map, | ||
154 | enum s3c2410_dmasrc dir) | ||
155 | { | ||
156 | unsigned long chsel; | ||
157 | |||
158 | if (dir == S3C2410_DMASRC_HW) | ||
159 | chsel = map->channels_rx[0]; | ||
160 | else | ||
161 | chsel = map->channels[0]; | ||
162 | |||
163 | chsel &= ~DMA_CH_VALID; | ||
164 | chsel |= S3C2412_DMAREQSEL_HW; | ||
165 | |||
166 | writel(chsel, chan->regs + S3C2412_DMA_DMAREQSEL); | ||
167 | } | ||
168 | |||
133 | static void s3c2412_dma_select(struct s3c2410_dma_chan *chan, | 169 | static void s3c2412_dma_select(struct s3c2410_dma_chan *chan, |
134 | struct s3c24xx_dma_map *map) | 170 | struct s3c24xx_dma_map *map) |
135 | { | 171 | { |
136 | writel(map->channels[0] | S3C2412_DMAREQSEL_HW, | 172 | s3c2412_dma_direction(chan, map, chan->source); |
137 | chan->regs + S3C2412_DMA_DMAREQSEL); | ||
138 | } | 173 | } |
139 | 174 | ||
140 | static struct s3c24xx_dma_selection __initdata s3c2412_dma_sel = { | 175 | static struct s3c24xx_dma_selection __initdata s3c2412_dma_sel = { |
141 | .select = s3c2412_dma_select, | 176 | .select = s3c2412_dma_select, |
177 | .direction = s3c2412_dma_direction, | ||
142 | .dcon_mask = 0, | 178 | .dcon_mask = 0, |
143 | .map = s3c2412_dma_mappings, | 179 | .map = s3c2412_dma_mappings, |
144 | .map_size = ARRAY_SIZE(s3c2412_dma_mappings), | 180 | .map_size = ARRAY_SIZE(s3c2412_dma_mappings), |
diff --git a/arch/arm/mach-s3c2412/gpio.c b/arch/arm/mach-s3c2412/gpio.c new file mode 100644 index 000000000000..8e55c3a2eab8 --- /dev/null +++ b/arch/arm/mach-s3c2412/gpio.c | |||
@@ -0,0 +1,60 @@ | |||
1 | /* linux/arch/arm/mach-s3c2412/gpio.c | ||
2 | * | ||
3 | * Copyright (c) 2007 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * | ||
6 | * http://armlinux.simtec.co.uk/. | ||
7 | * | ||
8 | * S3C2412/S3C2413 specific GPIO support | ||
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 | #include <linux/kernel.h> | ||
16 | #include <linux/types.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | |||
20 | #include <asm/mach/arch.h> | ||
21 | #include <asm/mach/map.h> | ||
22 | |||
23 | #include <asm/arch/regs-gpio.h> | ||
24 | |||
25 | #include <asm/hardware.h> | ||
26 | |||
27 | int s3c2412_gpio_set_sleepcfg(unsigned int pin, unsigned int state) | ||
28 | { | ||
29 | void __iomem *base = S3C24XX_GPIO_BASE(pin); | ||
30 | unsigned long offs = S3C2410_GPIO_OFFSET(pin); | ||
31 | unsigned long flags; | ||
32 | unsigned long slpcon; | ||
33 | |||
34 | offs *= 2; | ||
35 | |||
36 | if (pin < S3C2410_GPIO_BANKB) | ||
37 | return -EINVAL; | ||
38 | |||
39 | if (pin >= S3C2410_GPIO_BANKF && | ||
40 | pin <= S3C2410_GPIO_BANKG) | ||
41 | return -EINVAL; | ||
42 | |||
43 | if (pin > (S3C2410_GPIO_BANKH + 32)) | ||
44 | return -EINVAL; | ||
45 | |||
46 | local_irq_save(flags); | ||
47 | |||
48 | slpcon = __raw_readl(base + 0x0C); | ||
49 | |||
50 | slpcon &= ~(3 << offs); | ||
51 | slpcon |= state << offs; | ||
52 | |||
53 | __raw_writel(slpcon, base + 0x0C); | ||
54 | |||
55 | local_irq_restore(flags); | ||
56 | |||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | EXPORT_SYMBOL(s3c2412_gpio_set_sleepcfg); | ||
diff --git a/arch/arm/mach-s3c2412/irq.c b/arch/arm/mach-s3c2412/irq.c index e9d0c769f5da..cc1917bf952a 100644 --- a/arch/arm/mach-s3c2412/irq.c +++ b/arch/arm/mach-s3c2412/irq.c | |||
@@ -33,6 +33,7 @@ | |||
33 | 33 | ||
34 | #include <asm/arch/regs-irq.h> | 34 | #include <asm/arch/regs-irq.h> |
35 | #include <asm/arch/regs-gpio.h> | 35 | #include <asm/arch/regs-gpio.h> |
36 | #include <asm/arch/regs-power.h> | ||
36 | 37 | ||
37 | #include <asm/plat-s3c24xx/cpu.h> | 38 | #include <asm/plat-s3c24xx/cpu.h> |
38 | #include <asm/plat-s3c24xx/irq.h> | 39 | #include <asm/plat-s3c24xx/irq.h> |
@@ -153,6 +154,22 @@ static struct irq_chip s3c2412_irq_cfsdi = { | |||
153 | .unmask = s3c2412_irq_cfsdi_unmask, | 154 | .unmask = s3c2412_irq_cfsdi_unmask, |
154 | }; | 155 | }; |
155 | 156 | ||
157 | static int s3c2412_irq_rtc_wake(unsigned int irqno, unsigned int state) | ||
158 | { | ||
159 | unsigned long pwrcfg; | ||
160 | |||
161 | pwrcfg = __raw_readl(S3C2412_PWRCFG); | ||
162 | if (state) | ||
163 | pwrcfg &= ~S3C2412_PWRCFG_RTC_MASKIRQ; | ||
164 | else | ||
165 | pwrcfg |= S3C2412_PWRCFG_RTC_MASKIRQ; | ||
166 | __raw_writel(pwrcfg, S3C2412_PWRCFG); | ||
167 | |||
168 | return s3c_irq_chip.set_wake(irqno, state); | ||
169 | } | ||
170 | |||
171 | static struct irq_chip s3c2412_irq_rtc_chip; | ||
172 | |||
156 | static int s3c2412_irq_add(struct sys_device *sysdev) | 173 | static int s3c2412_irq_add(struct sys_device *sysdev) |
157 | { | 174 | { |
158 | unsigned int irqno; | 175 | unsigned int irqno; |
@@ -173,6 +190,13 @@ static int s3c2412_irq_add(struct sys_device *sysdev) | |||
173 | set_irq_flags(irqno, IRQF_VALID); | 190 | set_irq_flags(irqno, IRQF_VALID); |
174 | } | 191 | } |
175 | 192 | ||
193 | /* change RTC IRQ's set wake method */ | ||
194 | |||
195 | s3c2412_irq_rtc_chip = s3c_irq_chip; | ||
196 | s3c2412_irq_rtc_chip.set_wake = s3c2412_irq_rtc_wake; | ||
197 | |||
198 | set_irq_chip(IRQ_RTC, &s3c2412_irq_rtc_chip); | ||
199 | |||
176 | return 0; | 200 | return 0; |
177 | } | 201 | } |
178 | 202 | ||
diff --git a/arch/arm/mach-s3c2412/pm.c b/arch/arm/mach-s3c2412/pm.c index 8988dac388a9..d4ffb2d98076 100644 --- a/arch/arm/mach-s3c2412/pm.c +++ b/arch/arm/mach-s3c2412/pm.c | |||
@@ -33,6 +33,8 @@ | |||
33 | 33 | ||
34 | #include <asm/plat-s3c24xx/s3c2412.h> | 34 | #include <asm/plat-s3c24xx/s3c2412.h> |
35 | 35 | ||
36 | extern void s3c2412_sleep_enter(void); | ||
37 | |||
36 | static void s3c2412_cpu_suspend(void) | 38 | static void s3c2412_cpu_suspend(void) |
37 | { | 39 | { |
38 | unsigned long tmp; | 40 | unsigned long tmp; |
@@ -43,20 +45,7 @@ static void s3c2412_cpu_suspend(void) | |||
43 | tmp |= S3C2412_PWRCFG_STANDBYWFI_SLEEP; | 45 | tmp |= S3C2412_PWRCFG_STANDBYWFI_SLEEP; |
44 | __raw_writel(tmp, S3C2412_PWRCFG); | 46 | __raw_writel(tmp, S3C2412_PWRCFG); |
45 | 47 | ||
46 | /* issue the standby signal into the pm unit. Note, we | 48 | s3c2412_sleep_enter(); |
47 | * issue a write-buffer drain just in case */ | ||
48 | |||
49 | tmp = 0; | ||
50 | |||
51 | asm("b 1f\n\t" | ||
52 | ".align 5\n\t" | ||
53 | "1:\n\t" | ||
54 | "mcr p15, 0, %0, c7, c10, 4\n\t" | ||
55 | "mcr p15, 0, %0, c7, c0, 4" :: "r" (tmp)); | ||
56 | |||
57 | /* we should never get past here */ | ||
58 | |||
59 | panic("sleep resumed to originator?"); | ||
60 | } | 49 | } |
61 | 50 | ||
62 | static void s3c2412_pm_prepare(void) | 51 | static void s3c2412_pm_prepare(void) |
@@ -88,7 +77,6 @@ static struct sleep_save s3c2412_sleep[] = { | |||
88 | SAVE_ITEM(S3C2412_GPBSLPCON), | 77 | SAVE_ITEM(S3C2412_GPBSLPCON), |
89 | SAVE_ITEM(S3C2412_GPCSLPCON), | 78 | SAVE_ITEM(S3C2412_GPCSLPCON), |
90 | SAVE_ITEM(S3C2412_GPDSLPCON), | 79 | SAVE_ITEM(S3C2412_GPDSLPCON), |
91 | SAVE_ITEM(S3C2412_GPESLPCON), | ||
92 | SAVE_ITEM(S3C2412_GPFSLPCON), | 80 | SAVE_ITEM(S3C2412_GPFSLPCON), |
93 | SAVE_ITEM(S3C2412_GPGSLPCON), | 81 | SAVE_ITEM(S3C2412_GPGSLPCON), |
94 | SAVE_ITEM(S3C2412_GPHSLPCON), | 82 | SAVE_ITEM(S3C2412_GPHSLPCON), |
diff --git a/arch/arm/mach-s3c2412/s3c2412.c b/arch/arm/mach-s3c2412/s3c2412.c index 265cd3f567a3..abf1599c9f97 100644 --- a/arch/arm/mach-s3c2412/s3c2412.c +++ b/arch/arm/mach-s3c2412/s3c2412.c | |||
@@ -168,6 +168,8 @@ void __init s3c2412_init_clocks(int xtal) | |||
168 | 168 | ||
169 | fclk = s3c2410_get_pll(__raw_readl(S3C2410_MPLLCON), xtal*2); | 169 | fclk = s3c2410_get_pll(__raw_readl(S3C2410_MPLLCON), xtal*2); |
170 | 170 | ||
171 | clk_mpll.rate = fclk; | ||
172 | |||
171 | tmp = __raw_readl(S3C2410_CLKDIVN); | 173 | tmp = __raw_readl(S3C2410_CLKDIVN); |
172 | 174 | ||
173 | /* work out clock scalings */ | 175 | /* work out clock scalings */ |
diff --git a/arch/arm/mach-s3c2412/sleep.S b/arch/arm/mach-s3c2412/sleep.S new file mode 100644 index 000000000000..db32cac4199a --- /dev/null +++ b/arch/arm/mach-s3c2412/sleep.S | |||
@@ -0,0 +1,68 @@ | |||
1 | /* linux/arch/arm/mach-s3c2412/sleep.S | ||
2 | * | ||
3 | * Copyright (c) 2007 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * | ||
6 | * S3C2412 Power Manager low-level sleep support | ||
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/linkage.h> | ||
24 | #include <asm/assembler.h> | ||
25 | #include <asm/hardware.h> | ||
26 | #include <asm/arch/map.h> | ||
27 | |||
28 | #include <asm/arch/regs-irq.h> | ||
29 | |||
30 | .text | ||
31 | |||
32 | .global s3c2412_sleep_enter | ||
33 | |||
34 | s3c2412_sleep_enter: | ||
35 | mov r0, #0 /* argument for coprocessors */ | ||
36 | ldr r1, =S3C2410_INTPND | ||
37 | ldr r2, =S3C2410_SRCPND | ||
38 | ldr r3, =S3C2410_EINTPEND | ||
39 | |||
40 | teq r0, r0 | ||
41 | bl s3c2412_sleep_enter1 | ||
42 | teq pc, r0 | ||
43 | bl s3c2412_sleep_enter1 | ||
44 | |||
45 | .align 5 | ||
46 | |||
47 | /* this is called twice, first with the Z flag to ensure that the | ||
48 | * instructions have been loaded into the cache, and the second | ||
49 | * time to try and suspend the system. | ||
50 | */ | ||
51 | s3c2412_sleep_enter1: | ||
52 | mcr p15, 0, r0, c7, c10, 4 | ||
53 | mcrne p15, 0, r0, c7, c0, 4 | ||
54 | |||
55 | /* if we return from here, it is because an interrupt was | ||
56 | * active when we tried to shutdown. Try and ack the IRQ and | ||
57 | * retry, as simply returning causes the system to lock. | ||
58 | */ | ||
59 | |||
60 | ldrne r9, [ r1 ] | ||
61 | strne r9, [ r1 ] | ||
62 | ldrne r9, [ r2 ] | ||
63 | strne r9, [ r2 ] | ||
64 | ldrne r9, [ r3 ] | ||
65 | strne r9, [ r3 ] | ||
66 | bne s3c2412_sleep_enter1 | ||
67 | |||
68 | mov pc, r14 | ||
diff --git a/arch/arm/mach-s3c2440/clock.c b/arch/arm/mach-s3c2440/clock.c index 79e2ea4adaf3..184d804934c9 100644 --- a/arch/arm/mach-s3c2440/clock.c +++ b/arch/arm/mach-s3c2440/clock.c | |||
@@ -111,14 +111,9 @@ static struct clk s3c2440_clk_ac97 = { | |||
111 | 111 | ||
112 | static int s3c2440_clk_add(struct sys_device *sysdev) | 112 | static int s3c2440_clk_add(struct sys_device *sysdev) |
113 | { | 113 | { |
114 | unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN); | 114 | struct clk *clock_upll; |
115 | unsigned long clkdivn; | ||
116 | struct clk *clock_h; | 115 | struct clk *clock_h; |
117 | struct clk *clock_p; | 116 | struct clk *clock_p; |
118 | struct clk *clock_upll; | ||
119 | |||
120 | printk("S3C2440: Clock Support, DVS %s\n", | ||
121 | (camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off"); | ||
122 | 117 | ||
123 | clock_p = clk_get(NULL, "pclk"); | 118 | clock_p = clk_get(NULL, "pclk"); |
124 | clock_h = clk_get(NULL, "hclk"); | 119 | clock_h = clk_get(NULL, "hclk"); |
@@ -129,21 +124,6 @@ static int s3c2440_clk_add(struct sys_device *sysdev) | |||
129 | return -EINVAL; | 124 | return -EINVAL; |
130 | } | 125 | } |
131 | 126 | ||
132 | /* check rate of UPLL, and if it is near 96MHz, then change | ||
133 | * to using half the UPLL rate for the system */ | ||
134 | |||
135 | if (clk_get_rate(clock_upll) > (94 * MHZ)) { | ||
136 | clk_usb_bus.rate = clk_get_rate(clock_upll) / 2; | ||
137 | |||
138 | mutex_lock(&clocks_mutex); | ||
139 | |||
140 | clkdivn = __raw_readl(S3C2410_CLKDIVN); | ||
141 | clkdivn |= S3C2440_CLKDIVN_UCLK; | ||
142 | __raw_writel(clkdivn, S3C2410_CLKDIVN); | ||
143 | |||
144 | mutex_unlock(&clocks_mutex); | ||
145 | } | ||
146 | |||
147 | s3c2440_clk_cam.parent = clock_h; | 127 | s3c2440_clk_cam.parent = clock_h; |
148 | s3c2440_clk_ac97.parent = clock_p; | 128 | s3c2440_clk_ac97.parent = clock_p; |
149 | s3c2440_clk_cam_upll.parent = clock_upll; | 129 | s3c2440_clk_cam_upll.parent = clock_upll; |
diff --git a/arch/arm/mach-s3c2442/clock.c b/arch/arm/mach-s3c2442/clock.c index 5b9e830ac4d3..2d030d439fe9 100644 --- a/arch/arm/mach-s3c2442/clock.c +++ b/arch/arm/mach-s3c2442/clock.c | |||
@@ -115,14 +115,9 @@ static struct clk s3c2442_clk_cam_upll = { | |||
115 | 115 | ||
116 | static int s3c2442_clk_add(struct sys_device *sysdev) | 116 | static int s3c2442_clk_add(struct sys_device *sysdev) |
117 | { | 117 | { |
118 | unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN); | 118 | struct clk *clock_upll; |
119 | unsigned long clkdivn; | ||
120 | struct clk *clock_h; | 119 | struct clk *clock_h; |
121 | struct clk *clock_p; | 120 | struct clk *clock_p; |
122 | struct clk *clock_upll; | ||
123 | |||
124 | printk("S3C2442: Clock Support, DVS %s\n", | ||
125 | (camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off"); | ||
126 | 121 | ||
127 | clock_p = clk_get(NULL, "pclk"); | 122 | clock_p = clk_get(NULL, "pclk"); |
128 | clock_h = clk_get(NULL, "hclk"); | 123 | clock_h = clk_get(NULL, "hclk"); |
@@ -133,21 +128,6 @@ static int s3c2442_clk_add(struct sys_device *sysdev) | |||
133 | return -EINVAL; | 128 | return -EINVAL; |
134 | } | 129 | } |
135 | 130 | ||
136 | /* check rate of UPLL, and if it is near 96MHz, then change | ||
137 | * to using half the UPLL rate for the system */ | ||
138 | |||
139 | if (clk_get_rate(clock_upll) > (94 * MHZ)) { | ||
140 | clk_usb_bus.rate = clk_get_rate(clock_upll) / 2; | ||
141 | |||
142 | mutex_lock(&clocks_mutex); | ||
143 | |||
144 | clkdivn = __raw_readl(S3C2410_CLKDIVN); | ||
145 | clkdivn |= S3C2440_CLKDIVN_UCLK; | ||
146 | __raw_writel(clkdivn, S3C2410_CLKDIVN); | ||
147 | |||
148 | mutex_unlock(&clocks_mutex); | ||
149 | } | ||
150 | |||
151 | s3c2442_clk_cam.parent = clock_h; | 131 | s3c2442_clk_cam.parent = clock_h; |
152 | s3c2442_clk_cam_upll.parent = clock_upll; | 132 | s3c2442_clk_cam_upll.parent = clock_upll; |
153 | 133 | ||
diff --git a/arch/arm/mach-sa1100/ssp.c b/arch/arm/mach-sa1100/ssp.c index 59703c6fb29b..06206ceb312e 100644 --- a/arch/arm/mach-sa1100/ssp.c +++ b/arch/arm/mach-sa1100/ssp.c | |||
@@ -29,9 +29,8 @@ static irqreturn_t ssp_interrupt(int irq, void *dev_id) | |||
29 | { | 29 | { |
30 | unsigned int status = Ser4SSSR; | 30 | unsigned int status = Ser4SSSR; |
31 | 31 | ||
32 | if (status & SSSR_ROR) { | 32 | if (status & SSSR_ROR) |
33 | printk(KERN_WARNING "SSP: receiver overrun\n"); | 33 | printk(KERN_WARNING "SSP: receiver overrun\n"); |
34 | } | ||
35 | 34 | ||
36 | Ser4SSSR = SSSR_ROR; | 35 | Ser4SSSR = SSSR_ROR; |
37 | 36 | ||
diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c index fdf7b016e7ad..c2677368d6af 100644 --- a/arch/arm/mach-sa1100/time.c +++ b/arch/arm/mach-sa1100/time.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/irq.h> | 14 | #include <linux/irq.h> |
15 | #include <linux/timex.h> | 15 | #include <linux/timex.h> |
16 | #include <linux/signal.h> | 16 | #include <linux/signal.h> |
17 | #include <linux/clocksource.h> | ||
17 | 18 | ||
18 | #include <asm/mach/time.h> | 19 | #include <asm/mach/time.h> |
19 | #include <asm/hardware.h> | 20 | #include <asm/hardware.h> |
@@ -35,23 +36,6 @@ static int sa1100_set_rtc(void) | |||
35 | return 0; | 36 | return 0; |
36 | } | 37 | } |
37 | 38 | ||
38 | /* IRQs are disabled before entering here from do_gettimeofday() */ | ||
39 | static unsigned long sa1100_gettimeoffset (void) | ||
40 | { | ||
41 | unsigned long ticks_to_match, elapsed, usec; | ||
42 | |||
43 | /* Get ticks before next timer match */ | ||
44 | ticks_to_match = OSMR0 - OSCR; | ||
45 | |||
46 | /* We need elapsed ticks since last match */ | ||
47 | elapsed = LATCH - ticks_to_match; | ||
48 | |||
49 | /* Now convert them to usec */ | ||
50 | usec = (unsigned long)(elapsed * (tick_nsec / 1000))/LATCH; | ||
51 | |||
52 | return usec; | ||
53 | } | ||
54 | |||
55 | #ifdef CONFIG_NO_IDLE_HZ | 39 | #ifdef CONFIG_NO_IDLE_HZ |
56 | static unsigned long initial_match; | 40 | static unsigned long initial_match; |
57 | static int match_posponed; | 41 | static int match_posponed; |
@@ -62,8 +46,6 @@ sa1100_timer_interrupt(int irq, void *dev_id) | |||
62 | { | 46 | { |
63 | unsigned int next_match; | 47 | unsigned int next_match; |
64 | 48 | ||
65 | write_seqlock(&xtime_lock); | ||
66 | |||
67 | #ifdef CONFIG_NO_IDLE_HZ | 49 | #ifdef CONFIG_NO_IDLE_HZ |
68 | if (match_posponed) { | 50 | if (match_posponed) { |
69 | match_posponed = 0; | 51 | match_posponed = 0; |
@@ -85,8 +67,6 @@ sa1100_timer_interrupt(int irq, void *dev_id) | |||
85 | next_match = (OSMR0 += LATCH); | 67 | next_match = (OSMR0 += LATCH); |
86 | } while ((signed long)(next_match - OSCR) <= 0); | 68 | } while ((signed long)(next_match - OSCR) <= 0); |
87 | 69 | ||
88 | write_sequnlock(&xtime_lock); | ||
89 | |||
90 | return IRQ_HANDLED; | 70 | return IRQ_HANDLED; |
91 | } | 71 | } |
92 | 72 | ||
@@ -96,6 +76,20 @@ static struct irqaction sa1100_timer_irq = { | |||
96 | .handler = sa1100_timer_interrupt, | 76 | .handler = sa1100_timer_interrupt, |
97 | }; | 77 | }; |
98 | 78 | ||
79 | static cycle_t sa1100_read_oscr(void) | ||
80 | { | ||
81 | return OSCR; | ||
82 | } | ||
83 | |||
84 | static struct clocksource cksrc_sa1100_oscr = { | ||
85 | .name = "oscr", | ||
86 | .rating = 200, | ||
87 | .read = sa1100_read_oscr, | ||
88 | .mask = CLOCKSOURCE_MASK(32), | ||
89 | .shift = 20, | ||
90 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
91 | }; | ||
92 | |||
99 | static void __init sa1100_timer_init(void) | 93 | static void __init sa1100_timer_init(void) |
100 | { | 94 | { |
101 | unsigned long flags; | 95 | unsigned long flags; |
@@ -109,6 +103,11 @@ static void __init sa1100_timer_init(void) | |||
109 | OIER = OIER_E0; /* enable match on timer 0 to cause interrupts */ | 103 | OIER = OIER_E0; /* enable match on timer 0 to cause interrupts */ |
110 | OSMR0 = OSCR + LATCH; /* set initial match */ | 104 | OSMR0 = OSCR + LATCH; /* set initial match */ |
111 | local_irq_restore(flags); | 105 | local_irq_restore(flags); |
106 | |||
107 | cksrc_sa1100_oscr.mult = | ||
108 | clocksource_hz2mult(CLOCK_TICK_RATE, cksrc_sa1100_oscr.shift); | ||
109 | |||
110 | clocksource_register(&cksrc_sa1100_oscr); | ||
112 | } | 111 | } |
113 | 112 | ||
114 | #ifdef CONFIG_NO_IDLE_HZ | 113 | #ifdef CONFIG_NO_IDLE_HZ |
@@ -182,7 +181,6 @@ struct sys_timer sa1100_timer = { | |||
182 | .init = sa1100_timer_init, | 181 | .init = sa1100_timer_init, |
183 | .suspend = sa1100_timer_suspend, | 182 | .suspend = sa1100_timer_suspend, |
184 | .resume = sa1100_timer_resume, | 183 | .resume = sa1100_timer_resume, |
185 | .offset = sa1100_gettimeoffset, | ||
186 | #ifdef CONFIG_NO_IDLE_HZ | 184 | #ifdef CONFIG_NO_IDLE_HZ |
187 | .dyn_tick = &sa1100_dyn_tick, | 185 | .dyn_tick = &sa1100_dyn_tick, |
188 | #endif | 186 | #endif |
diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c index a0545db2a34f..09d9f33d4072 100644 --- a/arch/arm/mach-shark/core.c +++ b/arch/arm/mach-shark/core.c | |||
@@ -82,9 +82,7 @@ static void __init shark_map_io(void) | |||
82 | static irqreturn_t | 82 | static irqreturn_t |
83 | shark_timer_interrupt(int irq, void *dev_id) | 83 | shark_timer_interrupt(int irq, void *dev_id) |
84 | { | 84 | { |
85 | write_seqlock(&xtime_lock); | ||
86 | timer_tick(); | 85 | timer_tick(); |
87 | write_sequnlock(&xtime_lock); | ||
88 | return IRQ_HANDLED; | 86 | return IRQ_HANDLED; |
89 | } | 87 | } |
90 | 88 | ||
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 7868f4dc1d00..cb104c2a7329 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig | |||
@@ -171,8 +171,8 @@ config CPU_ARM925T | |||
171 | # ARM926T | 171 | # ARM926T |
172 | config CPU_ARM926T | 172 | config CPU_ARM926T |
173 | bool "Support ARM926T processor" | 173 | bool "Support ARM926T processor" |
174 | depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_NS9XXX || ARCH_DAVINCI | 174 | depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || ARCH_NS9XXX || ARCH_DAVINCI |
175 | default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_NS9XXX || ARCH_DAVINCI | 175 | default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || ARCH_NS9XXX || ARCH_DAVINCI |
176 | select CPU_32v5 | 176 | select CPU_32v5 |
177 | select CPU_ABRT_EV5TJ | 177 | select CPU_ABRT_EV5TJ |
178 | select CPU_CACHE_VIVT | 178 | select CPU_CACHE_VIVT |
@@ -345,8 +345,9 @@ 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 || ARCH_MX3 | 348 | depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP2 || ARCH_MX3 || ARCH_MSM7X00A |
349 | default y if ARCH_MX3 | 349 | default y if ARCH_MX3 |
350 | default y if ARCH_MSM7X00A | ||
350 | select CPU_32v6 | 351 | select CPU_32v6 |
351 | select CPU_ABRT_EV6 | 352 | select CPU_ABRT_EV6 |
352 | select CPU_CACHE_V6 | 353 | select CPU_CACHE_V6 |
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index a8a7dab757eb..28ad7ab1c0cd 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/signal.h> | 12 | #include <linux/signal.h> |
13 | #include <linux/mm.h> | 13 | #include <linux/mm.h> |
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/kprobes.h> | ||
15 | 16 | ||
16 | #include <asm/system.h> | 17 | #include <asm/system.h> |
17 | #include <asm/pgtable.h> | 18 | #include <asm/pgtable.h> |
@@ -20,6 +21,29 @@ | |||
20 | 21 | ||
21 | #include "fault.h" | 22 | #include "fault.h" |
22 | 23 | ||
24 | |||
25 | #ifdef CONFIG_KPROBES | ||
26 | static inline int notify_page_fault(struct pt_regs *regs, unsigned int fsr) | ||
27 | { | ||
28 | int ret = 0; | ||
29 | |||
30 | if (!user_mode(regs)) { | ||
31 | /* kprobe_running() needs smp_processor_id() */ | ||
32 | preempt_disable(); | ||
33 | if (kprobe_running() && kprobe_fault_handler(regs, fsr)) | ||
34 | ret = 1; | ||
35 | preempt_enable(); | ||
36 | } | ||
37 | |||
38 | return ret; | ||
39 | } | ||
40 | #else | ||
41 | static inline int notify_page_fault(struct pt_regs *regs, unsigned int fsr) | ||
42 | { | ||
43 | return 0; | ||
44 | } | ||
45 | #endif | ||
46 | |||
23 | /* | 47 | /* |
24 | * This is useful to dump out the page tables associated with | 48 | * This is useful to dump out the page tables associated with |
25 | * 'addr' in mm 'mm'. | 49 | * 'addr' in mm 'mm'. |
@@ -215,13 +239,16 @@ out: | |||
215 | return fault; | 239 | return fault; |
216 | } | 240 | } |
217 | 241 | ||
218 | static int | 242 | static int __kprobes |
219 | do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | 243 | do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) |
220 | { | 244 | { |
221 | struct task_struct *tsk; | 245 | struct task_struct *tsk; |
222 | struct mm_struct *mm; | 246 | struct mm_struct *mm; |
223 | int fault, sig, code; | 247 | int fault, sig, code; |
224 | 248 | ||
249 | if (notify_page_fault(regs, fsr)) | ||
250 | return 0; | ||
251 | |||
225 | tsk = current; | 252 | tsk = current; |
226 | mm = tsk->mm; | 253 | mm = tsk->mm; |
227 | 254 | ||
@@ -311,7 +338,7 @@ no_context: | |||
311 | * interrupt or a critical region, and should only copy the information | 338 | * interrupt or a critical region, and should only copy the information |
312 | * from the master page table, nothing more. | 339 | * from the master page table, nothing more. |
313 | */ | 340 | */ |
314 | static int | 341 | static int __kprobes |
315 | do_translation_fault(unsigned long addr, unsigned int fsr, | 342 | do_translation_fault(unsigned long addr, unsigned int fsr, |
316 | struct pt_regs *regs) | 343 | struct pt_regs *regs) |
317 | { | 344 | { |
diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index 0360b1f14d11..45a77df668f1 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c | |||
@@ -212,7 +212,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox) | |||
212 | 212 | ||
213 | static irqreturn_t mbox_interrupt(int irq, void *p) | 213 | static irqreturn_t mbox_interrupt(int irq, void *p) |
214 | { | 214 | { |
215 | struct omap_mbox *mbox = (struct omap_mbox *)p; | 215 | struct omap_mbox *mbox = p; |
216 | 216 | ||
217 | if (is_mbox_irq(mbox, IRQ_TX)) | 217 | if (is_mbox_irq(mbox, IRQ_TX)) |
218 | __mbox_tx_interrupt(mbox); | 218 | __mbox_tx_interrupt(mbox); |
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index f7b9ccdaacbc..2af5bd5a1344 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c | |||
@@ -98,9 +98,10 @@ static void omap_mcbsp_dump_reg(u8 id) | |||
98 | 98 | ||
99 | static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id) | 99 | static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id) |
100 | { | 100 | { |
101 | struct omap_mcbsp * mcbsp_tx = (struct omap_mcbsp *)(dev_id); | 101 | struct omap_mcbsp *mcbsp_tx = dev_id; |
102 | 102 | ||
103 | DBG("TX IRQ callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2)); | 103 | DBG("TX IRQ callback : 0x%x\n", |
104 | OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2)); | ||
104 | 105 | ||
105 | complete(&mcbsp_tx->tx_irq_completion); | 106 | complete(&mcbsp_tx->tx_irq_completion); |
106 | return IRQ_HANDLED; | 107 | return IRQ_HANDLED; |
@@ -108,9 +109,10 @@ static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id) | |||
108 | 109 | ||
109 | static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id) | 110 | static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id) |
110 | { | 111 | { |
111 | struct omap_mcbsp * mcbsp_rx = (struct omap_mcbsp *)(dev_id); | 112 | struct omap_mcbsp *mcbsp_rx = dev_id; |
112 | 113 | ||
113 | DBG("RX IRQ callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2)); | 114 | DBG("RX IRQ callback : 0x%x\n", |
115 | OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2)); | ||
114 | 116 | ||
115 | complete(&mcbsp_rx->rx_irq_completion); | 117 | complete(&mcbsp_rx->rx_irq_completion); |
116 | return IRQ_HANDLED; | 118 | return IRQ_HANDLED; |
@@ -118,9 +120,10 @@ static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id) | |||
118 | 120 | ||
119 | static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data) | 121 | static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data) |
120 | { | 122 | { |
121 | struct omap_mcbsp * mcbsp_dma_tx = (struct omap_mcbsp *)(data); | 123 | struct omap_mcbsp *mcbsp_dma_tx = data; |
122 | 124 | ||
123 | DBG("TX DMA callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2)); | 125 | DBG("TX DMA callback : 0x%x\n", |
126 | OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2)); | ||
124 | 127 | ||
125 | /* We can free the channels */ | 128 | /* We can free the channels */ |
126 | omap_free_dma(mcbsp_dma_tx->dma_tx_lch); | 129 | omap_free_dma(mcbsp_dma_tx->dma_tx_lch); |
@@ -131,9 +134,10 @@ static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data) | |||
131 | 134 | ||
132 | static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data) | 135 | static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data) |
133 | { | 136 | { |
134 | struct omap_mcbsp * mcbsp_dma_rx = (struct omap_mcbsp *)(data); | 137 | struct omap_mcbsp *mcbsp_dma_rx = data; |
135 | 138 | ||
136 | DBG("RX DMA callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2)); | 139 | DBG("RX DMA callback : 0x%x\n", |
140 | OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2)); | ||
137 | 141 | ||
138 | /* We can free the channels */ | 142 | /* We can free the channels */ |
139 | omap_free_dma(mcbsp_dma_rx->dma_rx_lch); | 143 | omap_free_dma(mcbsp_dma_rx->dma_rx_lch); |
diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile index 8e5ccaa1f03c..131d20237dd7 100644 --- a/arch/arm/plat-s3c24xx/Makefile +++ b/arch/arm/plat-s3c24xx/Makefile | |||
@@ -23,6 +23,7 @@ obj-y += clock.o | |||
23 | 23 | ||
24 | obj-$(CONFIG_CPU_S3C244X) += s3c244x.o | 24 | obj-$(CONFIG_CPU_S3C244X) += s3c244x.o |
25 | obj-$(CONFIG_CPU_S3C244X) += s3c244x-irq.o | 25 | obj-$(CONFIG_CPU_S3C244X) += s3c244x-irq.o |
26 | obj-$(CONFIG_CPU_S3C244X) += s3c244x-clock.o | ||
26 | obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o | 27 | obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o |
27 | obj-$(CONFIG_PM) += pm.o | 28 | obj-$(CONFIG_PM) += pm.o |
28 | obj-$(CONFIG_PM) += sleep.o | 29 | obj-$(CONFIG_PM) += sleep.o |
diff --git a/arch/arm/plat-s3c24xx/clock.c b/arch/arm/plat-s3c24xx/clock.c index 79cda0faec86..99a44746f8f2 100644 --- a/arch/arm/plat-s3c24xx/clock.c +++ b/arch/arm/plat-s3c24xx/clock.c | |||
@@ -172,6 +172,15 @@ int clk_set_rate(struct clk *clk, unsigned long rate) | |||
172 | if (IS_ERR(clk)) | 172 | if (IS_ERR(clk)) |
173 | return -EINVAL; | 173 | return -EINVAL; |
174 | 174 | ||
175 | /* We do not default just do a clk->rate = rate as | ||
176 | * the clock may have been made this way by choice. | ||
177 | */ | ||
178 | |||
179 | WARN_ON(clk->set_rate == NULL); | ||
180 | |||
181 | if (clk->set_rate == NULL) | ||
182 | return -EINVAL; | ||
183 | |||
175 | mutex_lock(&clocks_mutex); | 184 | mutex_lock(&clocks_mutex); |
176 | ret = (clk->set_rate)(clk, rate); | 185 | ret = (clk->set_rate)(clk, rate); |
177 | mutex_unlock(&clocks_mutex); | 186 | mutex_unlock(&clocks_mutex); |
@@ -213,6 +222,12 @@ EXPORT_SYMBOL(clk_set_parent); | |||
213 | 222 | ||
214 | /* base clocks */ | 223 | /* base clocks */ |
215 | 224 | ||
225 | static int clk_default_setrate(struct clk *clk, unsigned long rate) | ||
226 | { | ||
227 | clk->rate = rate; | ||
228 | return 0; | ||
229 | } | ||
230 | |||
216 | struct clk clk_xtal = { | 231 | struct clk clk_xtal = { |
217 | .name = "xtal", | 232 | .name = "xtal", |
218 | .id = -1, | 233 | .id = -1, |
@@ -224,6 +239,7 @@ struct clk clk_xtal = { | |||
224 | struct clk clk_mpll = { | 239 | struct clk clk_mpll = { |
225 | .name = "mpll", | 240 | .name = "mpll", |
226 | .id = -1, | 241 | .id = -1, |
242 | .set_rate = clk_default_setrate, | ||
227 | }; | 243 | }; |
228 | 244 | ||
229 | struct clk clk_upll = { | 245 | struct clk clk_upll = { |
@@ -239,6 +255,7 @@ struct clk clk_f = { | |||
239 | .rate = 0, | 255 | .rate = 0, |
240 | .parent = &clk_mpll, | 256 | .parent = &clk_mpll, |
241 | .ctrlbit = 0, | 257 | .ctrlbit = 0, |
258 | .set_rate = clk_default_setrate, | ||
242 | }; | 259 | }; |
243 | 260 | ||
244 | struct clk clk_h = { | 261 | struct clk clk_h = { |
@@ -247,6 +264,7 @@ struct clk clk_h = { | |||
247 | .rate = 0, | 264 | .rate = 0, |
248 | .parent = NULL, | 265 | .parent = NULL, |
249 | .ctrlbit = 0, | 266 | .ctrlbit = 0, |
267 | .set_rate = clk_default_setrate, | ||
250 | }; | 268 | }; |
251 | 269 | ||
252 | struct clk clk_p = { | 270 | struct clk clk_p = { |
@@ -255,6 +273,7 @@ struct clk clk_p = { | |||
255 | .rate = 0, | 273 | .rate = 0, |
256 | .parent = NULL, | 274 | .parent = NULL, |
257 | .ctrlbit = 0, | 275 | .ctrlbit = 0, |
276 | .set_rate = clk_default_setrate, | ||
258 | }; | 277 | }; |
259 | 278 | ||
260 | struct clk clk_usb_bus = { | 279 | struct clk clk_usb_bus = { |
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c index aae1b9cbaf44..ac9ff1666fcc 100644 --- a/arch/arm/plat-s3c24xx/dma.c +++ b/arch/arm/plat-s3c24xx/dma.c | |||
@@ -525,7 +525,8 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id, | |||
525 | } | 525 | } |
526 | } else if (chan->state == S3C2410_DMA_IDLE) { | 526 | } else if (chan->state == S3C2410_DMA_IDLE) { |
527 | if (chan->flags & S3C2410_DMAF_AUTOSTART) { | 527 | if (chan->flags & S3C2410_DMAF_AUTOSTART) { |
528 | s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_START); | 528 | s3c2410_dma_ctrl(chan->number | DMACH_LOW_LEVEL, |
529 | S3C2410_DMAOP_START); | ||
529 | } | 530 | } |
530 | } | 531 | } |
531 | 532 | ||
@@ -787,7 +788,7 @@ int s3c2410_dma_request(unsigned int channel, | |||
787 | 788 | ||
788 | pr_debug("%s: channel initialised, %p\n", __FUNCTION__, chan); | 789 | pr_debug("%s: channel initialised, %p\n", __FUNCTION__, chan); |
789 | 790 | ||
790 | return 0; | 791 | return chan->number | DMACH_LOW_LEVEL; |
791 | } | 792 | } |
792 | 793 | ||
793 | EXPORT_SYMBOL(s3c2410_dma_request); | 794 | EXPORT_SYMBOL(s3c2410_dma_request); |
@@ -1173,6 +1174,7 @@ int s3c2410_dma_devconfig(int channel, | |||
1173 | 1174 | ||
1174 | chan->source = source; | 1175 | chan->source = source; |
1175 | chan->dev_addr = devaddr; | 1176 | chan->dev_addr = devaddr; |
1177 | chan->hw_cfg = hwcfg; | ||
1176 | 1178 | ||
1177 | switch (source) { | 1179 | switch (source) { |
1178 | case S3C2410_DMASRC_HW: | 1180 | case S3C2410_DMASRC_HW: |
@@ -1184,7 +1186,7 @@ int s3c2410_dma_devconfig(int channel, | |||
1184 | dma_wrreg(chan, S3C2410_DMA_DIDSTC, (0<<1) | (0<<0)); | 1186 | dma_wrreg(chan, S3C2410_DMA_DIDSTC, (0<<1) | (0<<0)); |
1185 | 1187 | ||
1186 | chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DIDST); | 1188 | chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DIDST); |
1187 | return 0; | 1189 | break; |
1188 | 1190 | ||
1189 | case S3C2410_DMASRC_MEM: | 1191 | case S3C2410_DMASRC_MEM: |
1190 | /* source is memory */ | 1192 | /* source is memory */ |
@@ -1195,11 +1197,19 @@ int s3c2410_dma_devconfig(int channel, | |||
1195 | dma_wrreg(chan, S3C2410_DMA_DIDSTC, hwcfg & 3); | 1197 | dma_wrreg(chan, S3C2410_DMA_DIDSTC, hwcfg & 3); |
1196 | 1198 | ||
1197 | chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DISRC); | 1199 | chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DISRC); |
1198 | return 0; | 1200 | break; |
1201 | |||
1202 | default: | ||
1203 | printk(KERN_ERR "dma%d: invalid source type (%d)\n", | ||
1204 | channel, source); | ||
1205 | |||
1206 | return -EINVAL; | ||
1199 | } | 1207 | } |
1200 | 1208 | ||
1201 | printk(KERN_ERR "dma%d: invalid source type (%d)\n", channel, source); | 1209 | if (dma_sel.direction != NULL) |
1202 | return -EINVAL; | 1210 | (dma_sel.direction)(chan, chan->map, source); |
1211 | |||
1212 | return 0; | ||
1203 | } | 1213 | } |
1204 | 1214 | ||
1205 | EXPORT_SYMBOL(s3c2410_dma_devconfig); | 1215 | EXPORT_SYMBOL(s3c2410_dma_devconfig); |
@@ -1227,6 +1237,10 @@ int s3c2410_dma_getposition(dmach_t channel, dma_addr_t *src, dma_addr_t *dst) | |||
1227 | 1237 | ||
1228 | EXPORT_SYMBOL(s3c2410_dma_getposition); | 1238 | EXPORT_SYMBOL(s3c2410_dma_getposition); |
1229 | 1239 | ||
1240 | static struct s3c2410_dma_chan *to_dma_chan(struct sys_device *dev) | ||
1241 | { | ||
1242 | return container_of(dev, struct s3c2410_dma_chan, dev); | ||
1243 | } | ||
1230 | 1244 | ||
1231 | /* system device class */ | 1245 | /* system device class */ |
1232 | 1246 | ||
@@ -1234,7 +1248,7 @@ EXPORT_SYMBOL(s3c2410_dma_getposition); | |||
1234 | 1248 | ||
1235 | static int s3c2410_dma_suspend(struct sys_device *dev, pm_message_t state) | 1249 | static int s3c2410_dma_suspend(struct sys_device *dev, pm_message_t state) |
1236 | { | 1250 | { |
1237 | struct s3c2410_dma_chan *cp = container_of(dev, struct s3c2410_dma_chan, dev); | 1251 | struct s3c2410_dma_chan *cp = to_dma_chan(dev); |
1238 | 1252 | ||
1239 | printk(KERN_DEBUG "suspending dma channel %d\n", cp->number); | 1253 | printk(KERN_DEBUG "suspending dma channel %d\n", cp->number); |
1240 | 1254 | ||
@@ -1256,6 +1270,24 @@ static int s3c2410_dma_suspend(struct sys_device *dev, pm_message_t state) | |||
1256 | 1270 | ||
1257 | static int s3c2410_dma_resume(struct sys_device *dev) | 1271 | static int s3c2410_dma_resume(struct sys_device *dev) |
1258 | { | 1272 | { |
1273 | struct s3c2410_dma_chan *cp = to_dma_chan(dev); | ||
1274 | unsigned int no = cp->number | DMACH_LOW_LEVEL; | ||
1275 | |||
1276 | /* restore channel's hardware configuration */ | ||
1277 | |||
1278 | if (!cp->in_use) | ||
1279 | return 0; | ||
1280 | |||
1281 | printk(KERN_INFO "dma%d: restoring configuration\n", cp->number); | ||
1282 | |||
1283 | s3c2410_dma_config(no, cp->xfer_unit, cp->dcon); | ||
1284 | s3c2410_dma_devconfig(no, cp->source, cp->hw_cfg, cp->dev_addr); | ||
1285 | |||
1286 | /* re-select the dma source for this channel */ | ||
1287 | |||
1288 | if (cp->map != NULL) | ||
1289 | dma_sel.select(cp, cp->map); | ||
1290 | |||
1259 | return 0; | 1291 | return 0; |
1260 | } | 1292 | } |
1261 | 1293 | ||
@@ -1445,6 +1477,7 @@ static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel) | |||
1445 | 1477 | ||
1446 | found: | 1478 | found: |
1447 | dmach = &s3c2410_chans[ch]; | 1479 | dmach = &s3c2410_chans[ch]; |
1480 | dmach->map = ch_map; | ||
1448 | dma_chan_map[channel] = dmach; | 1481 | dma_chan_map[channel] = dmach; |
1449 | 1482 | ||
1450 | /* select the channel */ | 1483 | /* select the channel */ |
diff --git a/arch/arm/plat-s3c24xx/gpio.c b/arch/arm/plat-s3c24xx/gpio.c index ec3a09c4d181..ee99dcc7f0bd 100644 --- a/arch/arm/plat-s3c24xx/gpio.c +++ b/arch/arm/plat-s3c24xx/gpio.c | |||
@@ -122,6 +122,19 @@ void s3c2410_gpio_pullup(unsigned int pin, unsigned int to) | |||
122 | 122 | ||
123 | EXPORT_SYMBOL(s3c2410_gpio_pullup); | 123 | EXPORT_SYMBOL(s3c2410_gpio_pullup); |
124 | 124 | ||
125 | int s3c2410_gpio_getpull(unsigned int pin) | ||
126 | { | ||
127 | void __iomem *base = S3C24XX_GPIO_BASE(pin); | ||
128 | unsigned long offs = S3C2410_GPIO_OFFSET(pin); | ||
129 | |||
130 | if (pin < S3C2410_GPIO_BANKB) | ||
131 | return -EINVAL; | ||
132 | |||
133 | return (__raw_readl(base + 0x08) & (1L << offs)) ? 1 : 0; | ||
134 | } | ||
135 | |||
136 | EXPORT_SYMBOL(s3c2410_gpio_getpull); | ||
137 | |||
125 | void s3c2410_gpio_setpin(unsigned int pin, unsigned int to) | 138 | void s3c2410_gpio_setpin(unsigned int pin, unsigned int to) |
126 | { | 139 | { |
127 | void __iomem *base = S3C24XX_GPIO_BASE(pin); | 140 | void __iomem *base = S3C24XX_GPIO_BASE(pin); |
@@ -186,3 +199,19 @@ int s3c2410_gpio_getirq(unsigned int pin) | |||
186 | } | 199 | } |
187 | 200 | ||
188 | EXPORT_SYMBOL(s3c2410_gpio_getirq); | 201 | EXPORT_SYMBOL(s3c2410_gpio_getirq); |
202 | |||
203 | int s3c2410_gpio_irq2pin(unsigned int irq) | ||
204 | { | ||
205 | if (irq >= IRQ_EINT0 && irq <= IRQ_EINT3) | ||
206 | return S3C2410_GPF0 + (irq - IRQ_EINT0); | ||
207 | |||
208 | if (irq >= IRQ_EINT4 && irq <= IRQ_EINT7) | ||
209 | return S3C2410_GPF4 + (irq - IRQ_EINT4); | ||
210 | |||
211 | if (irq >= IRQ_EINT8 && irq <= IRQ_EINT23) | ||
212 | return S3C2410_GPG0 + (irq - IRQ_EINT8); | ||
213 | |||
214 | return -EINVAL; | ||
215 | } | ||
216 | |||
217 | EXPORT_SYMBOL(s3c2410_gpio_irq2pin); | ||
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c index 8fbc88470261..d486f5112569 100644 --- a/arch/arm/plat-s3c24xx/irq.c +++ b/arch/arm/plat-s3c24xx/irq.c | |||
@@ -187,7 +187,7 @@ struct irq_chip s3c_irq_level_chip = { | |||
187 | .set_wake = s3c_irq_wake | 187 | .set_wake = s3c_irq_wake |
188 | }; | 188 | }; |
189 | 189 | ||
190 | static struct irq_chip s3c_irq_chip = { | 190 | struct irq_chip s3c_irq_chip = { |
191 | .name = "s3c", | 191 | .name = "s3c", |
192 | .ack = s3c_irq_ack, | 192 | .ack = s3c_irq_ack, |
193 | .mask = s3c_irq_mask, | 193 | .mask = s3c_irq_mask, |
diff --git a/arch/arm/plat-s3c24xx/pm.c b/arch/arm/plat-s3c24xx/pm.c index 4fdb3117744f..bf5581a9aeea 100644 --- a/arch/arm/plat-s3c24xx/pm.c +++ b/arch/arm/plat-s3c24xx/pm.c | |||
@@ -83,38 +83,39 @@ static struct sleep_save core_save[] = { | |||
83 | SAVE_ITEM(S3C2410_REFRESH), | 83 | SAVE_ITEM(S3C2410_REFRESH), |
84 | }; | 84 | }; |
85 | 85 | ||
86 | static struct sleep_save gpio_save[] = { | 86 | static struct gpio_sleep { |
87 | SAVE_ITEM(S3C2410_GPACON), | 87 | void __iomem *base; |
88 | SAVE_ITEM(S3C2410_GPADAT), | 88 | unsigned int gpcon; |
89 | 89 | unsigned int gpdat; | |
90 | SAVE_ITEM(S3C2410_GPBCON), | 90 | unsigned int gpup; |
91 | SAVE_ITEM(S3C2410_GPBDAT), | 91 | } gpio_save[] = { |
92 | SAVE_ITEM(S3C2410_GPBUP), | 92 | [0] = { |
93 | 93 | .base = S3C2410_GPACON, | |
94 | SAVE_ITEM(S3C2410_GPCCON), | 94 | }, |
95 | SAVE_ITEM(S3C2410_GPCDAT), | 95 | [1] = { |
96 | SAVE_ITEM(S3C2410_GPCUP), | 96 | .base = S3C2410_GPBCON, |
97 | 97 | }, | |
98 | SAVE_ITEM(S3C2410_GPDCON), | 98 | [2] = { |
99 | SAVE_ITEM(S3C2410_GPDDAT), | 99 | .base = S3C2410_GPCCON, |
100 | SAVE_ITEM(S3C2410_GPDUP), | 100 | }, |
101 | 101 | [3] = { | |
102 | SAVE_ITEM(S3C2410_GPECON), | 102 | .base = S3C2410_GPDCON, |
103 | SAVE_ITEM(S3C2410_GPEDAT), | 103 | }, |
104 | SAVE_ITEM(S3C2410_GPEUP), | 104 | [4] = { |
105 | 105 | .base = S3C2410_GPECON, | |
106 | SAVE_ITEM(S3C2410_GPFCON), | 106 | }, |
107 | SAVE_ITEM(S3C2410_GPFDAT), | 107 | [5] = { |
108 | SAVE_ITEM(S3C2410_GPFUP), | 108 | .base = S3C2410_GPFCON, |
109 | 109 | }, | |
110 | SAVE_ITEM(S3C2410_GPGCON), | 110 | [6] = { |
111 | SAVE_ITEM(S3C2410_GPGDAT), | 111 | .base = S3C2410_GPGCON, |
112 | SAVE_ITEM(S3C2410_GPGUP), | 112 | }, |
113 | 113 | [7] = { | |
114 | SAVE_ITEM(S3C2410_GPHCON), | 114 | .base = S3C2410_GPHCON, |
115 | SAVE_ITEM(S3C2410_GPHDAT), | 115 | }, |
116 | SAVE_ITEM(S3C2410_GPHUP), | 116 | }; |
117 | 117 | ||
118 | static struct sleep_save misc_save[] = { | ||
118 | SAVE_ITEM(S3C2410_DCLKCON), | 119 | SAVE_ITEM(S3C2410_DCLKCON), |
119 | }; | 120 | }; |
120 | 121 | ||
@@ -486,6 +487,184 @@ static void s3c2410_pm_configure_extint(void) | |||
486 | } | 487 | } |
487 | } | 488 | } |
488 | 489 | ||
490 | /* offsets for CON/DAT/UP registers */ | ||
491 | |||
492 | #define OFFS_CON (S3C2410_GPACON - S3C2410_GPACON) | ||
493 | #define OFFS_DAT (S3C2410_GPADAT - S3C2410_GPACON) | ||
494 | #define OFFS_UP (S3C2410_GPBUP - S3C2410_GPBCON) | ||
495 | |||
496 | /* s3c2410_pm_save_gpios() | ||
497 | * | ||
498 | * Save the state of the GPIOs | ||
499 | */ | ||
500 | |||
501 | static void s3c2410_pm_save_gpios(void) | ||
502 | { | ||
503 | struct gpio_sleep *gps = gpio_save; | ||
504 | unsigned int gpio; | ||
505 | |||
506 | for (gpio = 0; gpio < ARRAY_SIZE(gpio_save); gpio++, gps++) { | ||
507 | void __iomem *base = gps->base; | ||
508 | |||
509 | gps->gpcon = __raw_readl(base + OFFS_CON); | ||
510 | gps->gpdat = __raw_readl(base + OFFS_DAT); | ||
511 | |||
512 | if (gpio > 0) | ||
513 | gps->gpup = __raw_readl(base + OFFS_UP); | ||
514 | |||
515 | } | ||
516 | } | ||
517 | |||
518 | /* Test whether the given masked+shifted bits of an GPIO configuration | ||
519 | * are one of the SFN (special function) modes. */ | ||
520 | |||
521 | static inline int is_sfn(unsigned long con) | ||
522 | { | ||
523 | return (con == 2 || con == 3); | ||
524 | } | ||
525 | |||
526 | /* Test if the given masked+shifted GPIO configuration is an input */ | ||
527 | |||
528 | static inline int is_in(unsigned long con) | ||
529 | { | ||
530 | return con == 0; | ||
531 | } | ||
532 | |||
533 | /* Test if the given masked+shifted GPIO configuration is an output */ | ||
534 | |||
535 | static inline int is_out(unsigned long con) | ||
536 | { | ||
537 | return con == 1; | ||
538 | } | ||
539 | |||
540 | /* s3c2410_pm_restore_gpio() | ||
541 | * | ||
542 | * Restore one of the GPIO banks that was saved during suspend. This is | ||
543 | * not as simple as once thought, due to the possibility of glitches | ||
544 | * from the order that the CON and DAT registers are set in. | ||
545 | * | ||
546 | * The three states the pin can be are {IN,OUT,SFN} which gives us 9 | ||
547 | * combinations of changes to check. Three of these, if the pin stays | ||
548 | * in the same configuration can be discounted. This leaves us with | ||
549 | * the following: | ||
550 | * | ||
551 | * { IN => OUT } Change DAT first | ||
552 | * { IN => SFN } Change CON first | ||
553 | * { OUT => SFN } Change CON first, so new data will not glitch | ||
554 | * { OUT => IN } Change CON first, so new data will not glitch | ||
555 | * { SFN => IN } Change CON first | ||
556 | * { SFN => OUT } Change DAT first, so new data will not glitch [1] | ||
557 | * | ||
558 | * We do not currently deal with the UP registers as these control | ||
559 | * weak resistors, so a small delay in change should not need to bring | ||
560 | * these into the calculations. | ||
561 | * | ||
562 | * [1] this assumes that writing to a pin DAT whilst in SFN will set the | ||
563 | * state for when it is next output. | ||
564 | */ | ||
565 | |||
566 | static void s3c2410_pm_restore_gpio(int index, struct gpio_sleep *gps) | ||
567 | { | ||
568 | void __iomem *base = gps->base; | ||
569 | unsigned long gps_gpcon = gps->gpcon; | ||
570 | unsigned long gps_gpdat = gps->gpdat; | ||
571 | unsigned long old_gpcon; | ||
572 | unsigned long old_gpdat; | ||
573 | unsigned long old_gpup = 0x0; | ||
574 | unsigned long gpcon; | ||
575 | int nr; | ||
576 | |||
577 | old_gpcon = __raw_readl(base + OFFS_CON); | ||
578 | old_gpdat = __raw_readl(base + OFFS_DAT); | ||
579 | |||
580 | if (base == S3C2410_GPACON) { | ||
581 | /* GPACON only has one bit per control / data and no PULLUPs. | ||
582 | * GPACON[x] = 0 => Output, 1 => SFN */ | ||
583 | |||
584 | /* first set all SFN bits to SFN */ | ||
585 | |||
586 | gpcon = old_gpcon | gps->gpcon; | ||
587 | __raw_writel(gpcon, base + OFFS_CON); | ||
588 | |||
589 | /* now set all the other bits */ | ||
590 | |||
591 | __raw_writel(gps_gpdat, base + OFFS_DAT); | ||
592 | __raw_writel(gps_gpcon, base + OFFS_CON); | ||
593 | } else { | ||
594 | unsigned long old, new, mask; | ||
595 | unsigned long change_mask = 0x0; | ||
596 | |||
597 | old_gpup = __raw_readl(base + OFFS_UP); | ||
598 | |||
599 | /* Create a change_mask of all the items that need to have | ||
600 | * their CON value changed before their DAT value, so that | ||
601 | * we minimise the work between the two settings. | ||
602 | */ | ||
603 | |||
604 | for (nr = 0, mask = 0x03; nr < 32; nr += 2, mask <<= 2) { | ||
605 | old = (old_gpcon & mask) >> nr; | ||
606 | new = (gps_gpcon & mask) >> nr; | ||
607 | |||
608 | /* If there is no change, then skip */ | ||
609 | |||
610 | if (old == new) | ||
611 | continue; | ||
612 | |||
613 | /* If both are special function, then skip */ | ||
614 | |||
615 | if (is_sfn(old) && is_sfn(new)) | ||
616 | continue; | ||
617 | |||
618 | /* Change is IN => OUT, do not change now */ | ||
619 | |||
620 | if (is_in(old) && is_out(new)) | ||
621 | continue; | ||
622 | |||
623 | /* Change is SFN => OUT, do not change now */ | ||
624 | |||
625 | if (is_sfn(old) && is_out(new)) | ||
626 | continue; | ||
627 | |||
628 | /* We should now be at the case of IN=>SFN, | ||
629 | * OUT=>SFN, OUT=>IN, SFN=>IN. */ | ||
630 | |||
631 | change_mask |= mask; | ||
632 | } | ||
633 | |||
634 | /* Write the new CON settings */ | ||
635 | |||
636 | gpcon = old_gpcon & ~change_mask; | ||
637 | gpcon |= gps_gpcon & change_mask; | ||
638 | |||
639 | __raw_writel(gpcon, base + OFFS_CON); | ||
640 | |||
641 | /* Now change any items that require DAT,CON */ | ||
642 | |||
643 | __raw_writel(gps_gpdat, base + OFFS_DAT); | ||
644 | __raw_writel(gps_gpcon, base + OFFS_CON); | ||
645 | __raw_writel(gps->gpup, base + OFFS_UP); | ||
646 | } | ||
647 | |||
648 | DBG("GPIO[%d] CON %08lx => %08lx, DAT %08lx => %08lx\n", | ||
649 | index, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat); | ||
650 | } | ||
651 | |||
652 | |||
653 | /** s3c2410_pm_restore_gpios() | ||
654 | * | ||
655 | * Restore the state of the GPIOs | ||
656 | */ | ||
657 | |||
658 | static void s3c2410_pm_restore_gpios(void) | ||
659 | { | ||
660 | struct gpio_sleep *gps = gpio_save; | ||
661 | int gpio; | ||
662 | |||
663 | for (gpio = 0; gpio < ARRAY_SIZE(gpio_save); gpio++, gps++) { | ||
664 | s3c2410_pm_restore_gpio(gpio, gps); | ||
665 | } | ||
666 | } | ||
667 | |||
489 | void (*pm_cpu_prep)(void); | 668 | void (*pm_cpu_prep)(void); |
490 | void (*pm_cpu_sleep)(void); | 669 | void (*pm_cpu_sleep)(void); |
491 | 670 | ||
@@ -535,7 +714,8 @@ static int s3c2410_pm_enter(suspend_state_t state) | |||
535 | 714 | ||
536 | /* save all necessary core registers not covered by the drivers */ | 715 | /* save all necessary core registers not covered by the drivers */ |
537 | 716 | ||
538 | s3c2410_pm_do_save(gpio_save, ARRAY_SIZE(gpio_save)); | 717 | s3c2410_pm_save_gpios(); |
718 | s3c2410_pm_do_save(misc_save, ARRAY_SIZE(misc_save)); | ||
539 | s3c2410_pm_do_save(core_save, ARRAY_SIZE(core_save)); | 719 | s3c2410_pm_do_save(core_save, ARRAY_SIZE(core_save)); |
540 | s3c2410_pm_do_save(uart_save, ARRAY_SIZE(uart_save)); | 720 | s3c2410_pm_do_save(uart_save, ARRAY_SIZE(uart_save)); |
541 | 721 | ||
@@ -585,8 +765,9 @@ static int s3c2410_pm_enter(suspend_state_t state) | |||
585 | /* restore the system state */ | 765 | /* restore the system state */ |
586 | 766 | ||
587 | s3c2410_pm_do_restore_core(core_save, ARRAY_SIZE(core_save)); | 767 | s3c2410_pm_do_restore_core(core_save, ARRAY_SIZE(core_save)); |
588 | s3c2410_pm_do_restore(gpio_save, ARRAY_SIZE(gpio_save)); | 768 | s3c2410_pm_do_restore(misc_save, ARRAY_SIZE(misc_save)); |
589 | s3c2410_pm_do_restore(uart_save, ARRAY_SIZE(uart_save)); | 769 | s3c2410_pm_do_restore(uart_save, ARRAY_SIZE(uart_save)); |
770 | s3c2410_pm_restore_gpios(); | ||
590 | 771 | ||
591 | s3c2410_pm_debug_init(); | 772 | s3c2410_pm_debug_init(); |
592 | 773 | ||
diff --git a/arch/arm/plat-s3c24xx/s3c244x-clock.c b/arch/arm/plat-s3c24xx/s3c244x-clock.c new file mode 100644 index 000000000000..faf3e0f9f4e2 --- /dev/null +++ b/arch/arm/plat-s3c24xx/s3c244x-clock.c | |||
@@ -0,0 +1,137 @@ | |||
1 | /* linux/arch/arm/plat-s3c24xx/s3c24xx-clock.c | ||
2 | * | ||
3 | * Copyright (c) 2004-2005,2008 Simtec Electronics | ||
4 | * http://armlinux.simtec.co.uk/ | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * | ||
7 | * S3C2440/S3C2442 Common clock support | ||
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 | |||
24 | #include <linux/init.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/list.h> | ||
28 | #include <linux/errno.h> | ||
29 | #include <linux/err.h> | ||
30 | #include <linux/device.h> | ||
31 | #include <linux/sysdev.h> | ||
32 | #include <linux/interrupt.h> | ||
33 | #include <linux/ioport.h> | ||
34 | #include <linux/mutex.h> | ||
35 | #include <linux/clk.h> | ||
36 | |||
37 | #include <asm/hardware.h> | ||
38 | #include <asm/atomic.h> | ||
39 | #include <asm/irq.h> | ||
40 | #include <asm/io.h> | ||
41 | |||
42 | #include <asm/arch/regs-clock.h> | ||
43 | |||
44 | #include <asm/plat-s3c24xx/clock.h> | ||
45 | #include <asm/plat-s3c24xx/cpu.h> | ||
46 | |||
47 | static int s3c2440_setparent_armclk(struct clk *clk, struct clk *parent) | ||
48 | { | ||
49 | unsigned long camdivn; | ||
50 | unsigned long dvs; | ||
51 | |||
52 | if (parent == &clk_f) | ||
53 | dvs = 0; | ||
54 | else if (parent == &clk_h) | ||
55 | dvs = S3C2440_CAMDIVN_DVSEN; | ||
56 | else | ||
57 | return -EINVAL; | ||
58 | |||
59 | clk->parent = parent; | ||
60 | |||
61 | camdivn = __raw_readl(S3C2440_CAMDIVN); | ||
62 | camdivn &= ~S3C2440_CAMDIVN_DVSEN; | ||
63 | camdivn |= dvs; | ||
64 | __raw_writel(camdivn, S3C2440_CAMDIVN); | ||
65 | |||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | static struct clk clk_arm = { | ||
70 | .name = "armclk", | ||
71 | .id = -1, | ||
72 | .set_parent = s3c2440_setparent_armclk, | ||
73 | }; | ||
74 | |||
75 | static int s3c244x_clk_add(struct sys_device *sysdev) | ||
76 | { | ||
77 | unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN); | ||
78 | unsigned long clkdivn; | ||
79 | struct clk *clock_upll; | ||
80 | int ret; | ||
81 | |||
82 | printk("S3C244X: Clock Support, DVS %s\n", | ||
83 | (camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off"); | ||
84 | |||
85 | clk_arm.parent = (camdivn & S3C2440_CAMDIVN_DVSEN) ? &clk_h : &clk_f; | ||
86 | |||
87 | ret = s3c24xx_register_clock(&clk_arm); | ||
88 | if (ret < 0) { | ||
89 | printk(KERN_ERR "S3C24XX: Failed to add armclk (%d)\n", ret); | ||
90 | return ret; | ||
91 | } | ||
92 | |||
93 | clock_upll = clk_get(NULL, "upll"); | ||
94 | if (IS_ERR(clock_upll)) { | ||
95 | printk(KERN_ERR "S3C244X: Failed to get upll clock\n"); | ||
96 | return -ENOENT; | ||
97 | } | ||
98 | |||
99 | /* check rate of UPLL, and if it is near 96MHz, then change | ||
100 | * to using half the UPLL rate for the system */ | ||
101 | |||
102 | if (clk_get_rate(clock_upll) > (94 * MHZ)) { | ||
103 | clk_usb_bus.rate = clk_get_rate(clock_upll) / 2; | ||
104 | |||
105 | mutex_lock(&clocks_mutex); | ||
106 | |||
107 | clkdivn = __raw_readl(S3C2410_CLKDIVN); | ||
108 | clkdivn |= S3C2440_CLKDIVN_UCLK; | ||
109 | __raw_writel(clkdivn, S3C2410_CLKDIVN); | ||
110 | |||
111 | mutex_unlock(&clocks_mutex); | ||
112 | } | ||
113 | |||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | static struct sysdev_driver s3c2440_clk_driver = { | ||
118 | .add = s3c244x_clk_add, | ||
119 | }; | ||
120 | |||
121 | static int s3c2440_clk_init(void) | ||
122 | { | ||
123 | return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_clk_driver); | ||
124 | } | ||
125 | |||
126 | arch_initcall(s3c2440_clk_init); | ||
127 | |||
128 | static struct sysdev_driver s3c2442_clk_driver = { | ||
129 | .add = s3c244x_clk_add, | ||
130 | }; | ||
131 | |||
132 | static int s3c2442_clk_init(void) | ||
133 | { | ||
134 | return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_clk_driver); | ||
135 | } | ||
136 | |||
137 | arch_initcall(s3c2442_clk_init); | ||
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index 0a9a5e7f62e5..7ed58c0c24c2 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types | |||
@@ -12,7 +12,7 @@ | |||
12 | # | 12 | # |
13 | # http://www.arm.linux.org.uk/developer/machines/?action=new | 13 | # http://www.arm.linux.org.uk/developer/machines/?action=new |
14 | # | 14 | # |
15 | # Last update: Fri May 11 19:53:41 2007 | 15 | # Last update: Sat Jan 26 14:45:34 2008 |
16 | # | 16 | # |
17 | # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number | 17 | # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number |
18 | # | 18 | # |
@@ -266,7 +266,7 @@ stork_egg ARCH_STORK_EGG STORK_EGG 248 | |||
266 | wismo SA1100_WISMO WISMO 249 | 266 | wismo SA1100_WISMO WISMO 249 |
267 | ezlinx ARCH_EZLINX EZLINX 250 | 267 | ezlinx ARCH_EZLINX EZLINX 250 |
268 | at91rm9200 ARCH_AT91RM9200 AT91RM9200 251 | 268 | at91rm9200 ARCH_AT91RM9200 AT91RM9200 251 |
269 | orion ARCH_ORION ORION 252 | 269 | adtech_orion ARCH_ADTECH_ORION ADTECH_ORION 252 |
270 | neptune ARCH_NEPTUNE NEPTUNE 253 | 270 | neptune ARCH_NEPTUNE NEPTUNE 253 |
271 | hackkit SA1100_HACKKIT HACKKIT 254 | 271 | hackkit SA1100_HACKKIT HACKKIT 254 |
272 | pxa_wins30 ARCH_PXA_WINS30 PXA_WINS30 255 | 272 | pxa_wins30 ARCH_PXA_WINS30 PXA_WINS30 255 |
@@ -661,7 +661,6 @@ a9200ec MACH_A9200EC A9200EC 645 | |||
661 | pnx0105 MACH_PNX0105 PNX0105 646 | 661 | pnx0105 MACH_PNX0105 PNX0105 646 |
662 | adcpoecpu MACH_ADCPOECPU ADCPOECPU 647 | 662 | adcpoecpu MACH_ADCPOECPU ADCPOECPU 647 |
663 | csb637 MACH_CSB637 CSB637 648 | 663 | csb637 MACH_CSB637 CSB637 648 |
664 | ml69q6203 MACH_ML69Q6203 ML69Q6203 649 | ||
665 | mb9200 MACH_MB9200 MB9200 650 | 664 | mb9200 MACH_MB9200 MB9200 650 |
666 | kulun MACH_KULUN KULUN 651 | 665 | kulun MACH_KULUN KULUN 651 |
667 | snapper MACH_SNAPPER SNAPPER 652 | 666 | snapper MACH_SNAPPER SNAPPER 652 |
@@ -953,7 +952,6 @@ fred_jack MACH_FRED_JACK FRED_JACK 939 | |||
953 | ttg_color1 MACH_TTG_COLOR1 TTG_COLOR1 940 | 952 | ttg_color1 MACH_TTG_COLOR1 TTG_COLOR1 940 |
954 | nxeb500hmi MACH_NXEB500HMI NXEB500HMI 941 | 953 | nxeb500hmi MACH_NXEB500HMI NXEB500HMI 941 |
955 | netdcu8 MACH_NETDCU8 NETDCU8 942 | 954 | netdcu8 MACH_NETDCU8 NETDCU8 942 |
956 | ml675050_cpu_boa MACH_ML675050_CPU_BOA ML675050_CPU_BOA 943 | ||
957 | ng_fvx538 MACH_NG_FVX538 NG_FVX538 944 | 955 | ng_fvx538 MACH_NG_FVX538 NG_FVX538 944 |
958 | ng_fvs338 MACH_NG_FVS338 NG_FVS338 945 | 956 | ng_fvs338 MACH_NG_FVS338 NG_FVS338 945 |
959 | pnx4103 MACH_PNX4103 PNX4103 946 | 957 | pnx4103 MACH_PNX4103 PNX4103 946 |
@@ -1148,7 +1146,7 @@ aidx270 MACH_AIDX270 AIDX270 1134 | |||
1148 | rema MACH_REMA REMA 1135 | 1146 | rema MACH_REMA REMA 1135 |
1149 | bps1000 MACH_BPS1000 BPS1000 1136 | 1147 | bps1000 MACH_BPS1000 BPS1000 1136 |
1150 | hw90350 MACH_HW90350 HW90350 1137 | 1148 | hw90350 MACH_HW90350 HW90350 1137 |
1151 | omap_sdp3430 MACH_OMAP_SDP3430 OMAP_SDP3430 1138 | 1149 | omap_3430sdp MACH_OMAP_3430SDP OMAP_3430SDP 1138 |
1152 | bluetouch MACH_BLUETOUCH BLUETOUCH 1139 | 1150 | bluetouch MACH_BLUETOUCH BLUETOUCH 1139 |
1153 | vstms MACH_VSTMS VSTMS 1140 | 1151 | vstms MACH_VSTMS VSTMS 1140 |
1154 | xsbase270 MACH_XSBASE270 XSBASE270 1141 | 1152 | xsbase270 MACH_XSBASE270 XSBASE270 1141 |
@@ -1214,7 +1212,7 @@ osstbox MACH_OSSTBOX OSSTBOX 1203 | |||
1214 | kbat9261 MACH_KBAT9261 KBAT9261 1204 | 1212 | kbat9261 MACH_KBAT9261 KBAT9261 1204 |
1215 | ct1100 MACH_CT1100 CT1100 1205 | 1213 | ct1100 MACH_CT1100 CT1100 1205 |
1216 | akcppxa MACH_AKCPPXA AKCPPXA 1206 | 1214 | akcppxa MACH_AKCPPXA AKCPPXA 1206 |
1217 | zevio_1020 MACH_ZEVIO_1020 ZEVIO_1020 1207 | 1215 | ochaya1020 MACH_OCHAYA1020 OCHAYA1020 1207 |
1218 | hitrack MACH_HITRACK HITRACK 1208 | 1216 | hitrack MACH_HITRACK HITRACK 1208 |
1219 | syme1 MACH_SYME1 SYME1 1209 | 1217 | syme1 MACH_SYME1 SYME1 1209 |
1220 | syhl1 MACH_SYHL1 SYHL1 1210 | 1218 | syhl1 MACH_SYHL1 SYHL1 1210 |
@@ -1299,7 +1297,7 @@ xp179 MACH_XP179 XP179 1290 | |||
1299 | h4300 MACH_H4300 H4300 1291 | 1297 | h4300 MACH_H4300 H4300 1291 |
1300 | goramo_mlr MACH_GORAMO_MLR GORAMO_MLR 1292 | 1298 | goramo_mlr MACH_GORAMO_MLR GORAMO_MLR 1292 |
1301 | mxc30020evb MACH_MXC30020EVB MXC30020EVB 1293 | 1299 | mxc30020evb MACH_MXC30020EVB MXC30020EVB 1293 |
1302 | adsbitsymx MACH_ADSBITSIMX ADSBITSIMX 1294 | 1300 | adsbitsyg5 MACH_ADSBITSYG5 ADSBITSYG5 1294 |
1303 | adsportalplus MACH_ADSPORTALPLUS ADSPORTALPLUS 1295 | 1301 | adsportalplus MACH_ADSPORTALPLUS ADSPORTALPLUS 1295 |
1304 | mmsp2plus MACH_MMSP2PLUS MMSP2PLUS 1296 | 1302 | mmsp2plus MACH_MMSP2PLUS MMSP2PLUS 1296 |
1305 | em_x270 MACH_EM_X270 EM_X270 1297 | 1303 | em_x270 MACH_EM_X270 EM_X270 1297 |
@@ -1367,3 +1365,249 @@ db88f5281 MACH_DB88F5281 DB88F5281 1358 | |||
1367 | csb726 MACH_CSB726 CSB726 1359 | 1365 | csb726 MACH_CSB726 CSB726 1359 |
1368 | tik27 MACH_TIK27 TIK27 1360 | 1366 | tik27 MACH_TIK27 TIK27 1360 |
1369 | mx_uc7420 MACH_MX_UC7420 MX_UC7420 1361 | 1367 | mx_uc7420 MACH_MX_UC7420 MX_UC7420 1361 |
1368 | rirm3 MACH_RIRM3 RIRM3 1362 | ||
1369 | pelco_odyssey MACH_PELCO_ODYSSEY PELCO_ODYSSEY 1363 | ||
1370 | adx_abox MACH_ADX_ABOX ADX_ABOX 1365 | ||
1371 | adx_tpid MACH_ADX_TPID ADX_TPID 1366 | ||
1372 | minicheck MACH_MINICHECK MINICHECK 1367 | ||
1373 | idam MACH_IDAM IDAM 1368 | ||
1374 | mario_mx MACH_MARIO_MX MARIO_MX 1369 | ||
1375 | vi1888 MACH_VI1888 VI1888 1370 | ||
1376 | zr4230 MACH_ZR4230 ZR4230 1371 | ||
1377 | t1_ix_blue MACH_T1_IX_BLUE T1_IX_BLUE 1372 | ||
1378 | syhq2 MACH_SYHQ2 SYHQ2 1373 | ||
1379 | computime_r3 MACH_COMPUTIME_R3 COMPUTIME_R3 1374 | ||
1380 | oratis MACH_ORATIS ORATIS 1375 | ||
1381 | mikko MACH_MIKKO MIKKO 1376 | ||
1382 | holon MACH_HOLON HOLON 1377 | ||
1383 | olip8 MACH_OLIP8 OLIP8 1378 | ||
1384 | ghi270hg MACH_GHI270HG GHI270HG 1379 | ||
1385 | davinci_dm6467_evm MACH_DAVINCI_DM6467_EVM DAVINCI_DM6467_EVM 1380 | ||
1386 | davinci_dm355_evm MACH_DAVINCI_DM350_EVM DAVINCI_DM350_EVM 1381 | ||
1387 | blackriver MACH_BLACKRIVER BLACKRIVER 1383 | ||
1388 | sandgate_wp MACH_SANDGATEWP SANDGATEWP 1384 | ||
1389 | cdotbwsg MACH_CDOTBWSG CDOTBWSG 1385 | ||
1390 | quark963 MACH_QUARK963 QUARK963 1386 | ||
1391 | csb735 MACH_CSB735 CSB735 1387 | ||
1392 | littleton MACH_LITTLETON LITTLETON 1388 | ||
1393 | mio_p550 MACH_MIO_P550 MIO_P550 1389 | ||
1394 | motion2440 MACH_MOTION2440 MOTION2440 1390 | ||
1395 | imm500 MACH_IMM500 IMM500 1391 | ||
1396 | homematic MACH_HOMEMATIC HOMEMATIC 1392 | ||
1397 | ermine MACH_ERMINE ERMINE 1393 | ||
1398 | kb9202b MACH_KB9202B KB9202B 1394 | ||
1399 | hs1xx MACH_HS1XX HS1XX 1395 | ||
1400 | studentmate2440 MACH_STUDENTMATE2440 STUDENTMATE2440 1396 | ||
1401 | arvoo_l1_z1 MACH_ARVOO_L1_Z1 ARVOO_L1_Z1 1397 | ||
1402 | dep2410k MACH_DEP2410K DEP2410K 1398 | ||
1403 | xxsvideo MACH_XXSVIDEO XXSVIDEO 1399 | ||
1404 | im4004 MACH_IM4004 IM4004 1400 | ||
1405 | ochaya1050 MACH_OCHAYA1050 OCHAYA1050 1401 | ||
1406 | lep9261 MACH_LEP9261 LEP9261 1402 | ||
1407 | svenmeb MACH_SVENMEB SVENMEB 1403 | ||
1408 | fortunet2ne MACH_FORTUNET2NE FORTUNET2NE 1404 | ||
1409 | nxhx MACH_NXHX NXHX 1406 | ||
1410 | realview_pb11mp MACH_REALVIEW_PB11MP REALVIEW_PB11MP 1407 | ||
1411 | ids500 MACH_IDS500 IDS500 1408 | ||
1412 | ors_n725 MACH_ORS_N725 ORS_N725 1409 | ||
1413 | hsdarm MACH_HSDARM HSDARM 1410 | ||
1414 | sha_pon003 MACH_SHA_PON003 SHA_PON003 1411 | ||
1415 | sha_pon004 MACH_SHA_PON004 SHA_PON004 1412 | ||
1416 | sha_pon007 MACH_SHA_PON007 SHA_PON007 1413 | ||
1417 | sha_pon011 MACH_SHA_PON011 SHA_PON011 1414 | ||
1418 | h6042 MACH_H6042 H6042 1415 | ||
1419 | h6043 MACH_H6043 H6043 1416 | ||
1420 | looxc550 MACH_LOOXC550 LOOXC550 1417 | ||
1421 | cnty_titan MACH_CNTY_TITAN CNTY_TITAN 1418 | ||
1422 | app3xx MACH_APP3XX APP3XX 1419 | ||
1423 | sideoatsgrama MACH_SIDEOATSGRAMA SIDEOATSGRAMA 1420 | ||
1424 | xscale_palmt700p MACH_XSCALE_PALMT700P XSCALE_PALMT700P 1421 | ||
1425 | xscale_palmt700w MACH_XSCALE_PALMT700W XSCALE_PALMT700W 1422 | ||
1426 | xscale_palmt750 MACH_XSCALE_PALMT750 XSCALE_PALMT750 1423 | ||
1427 | xscale_palmt755p MACH_XSCALE_PALMT755P XSCALE_PALMT755P 1424 | ||
1428 | ezreganut9200 MACH_EZREGANUT9200 EZREGANUT9200 1425 | ||
1429 | sarge MACH_SARGE SARGE 1426 | ||
1430 | a696 MACH_A696 A696 1427 | ||
1431 | turtle1916 MACH_TURTLE TURTLE 1428 | ||
1432 | mx27_3ds MACH_MX27_3DS MX27_3DS 1430 | ||
1433 | bishop MACH_BISHOP BISHOP 1431 | ||
1434 | pxx MACH_PXX PXX 1432 | ||
1435 | redwood MACH_REDWOOD REDWOOD 1433 | ||
1436 | omap_2430dlp MACH_OMAP_2430DLP OMAP_2430DLP 1436 | ||
1437 | omap_2430osk MACH_OMAP_2430OSK OMAP_2430OSK 1437 | ||
1438 | sardine MACH_SARDINE SARDINE 1438 | ||
1439 | halibut MACH_HALIBUT HALIBUT 1439 | ||
1440 | trout MACH_TROUT TROUT 1440 | ||
1441 | goldfish MACH_GOLDFISH GOLDFISH 1441 | ||
1442 | gesbc2440 MACH_GESBC2440 GESBC2440 1442 | ||
1443 | nomad MACH_NOMAD NOMAD 1443 | ||
1444 | rosalind MACH_ROSALIND ROSALIND 1444 | ||
1445 | cc9p9215 MACH_CC9P9215 CC9P9215 1445 | ||
1446 | cc9p9210 MACH_CC9P9210 CC9P9210 1446 | ||
1447 | cc9p9215js MACH_CC9P9215JS CC9P9215JS 1447 | ||
1448 | cc9p9210js MACH_CC9P9210JS CC9P9210JS 1448 | ||
1449 | nasffe MACH_NASFFE NASFFE 1449 | ||
1450 | tn2x0bd MACH_TN2X0BD TN2X0BD 1450 | ||
1451 | gwmpxa MACH_GWMPXA GWMPXA 1451 | ||
1452 | exyplus MACH_EXYPLUS EXYPLUS 1452 | ||
1453 | jadoo21 MACH_JADOO21 JADOO21 1453 | ||
1454 | looxn560 MACH_LOOXN560 LOOXN560 1454 | ||
1455 | bonsai MACH_BONSAI BONSAI 1455 | ||
1456 | adsmilgato MACH_ADSMILGATO ADSMILGATO 1456 | ||
1457 | gba MACH_GBA GBA 1457 | ||
1458 | h6044 MACH_H6044 H6044 1458 | ||
1459 | app MACH_APP APP 1459 | ||
1460 | tct_hammer MACH_TCT_HAMMER TCT_HAMMER 1460 | ||
1461 | herald MACH_HERMES HERMES 1461 | ||
1462 | artemis MACH_ARTEMIS ARTEMIS 1462 | ||
1463 | htctitan MACH_HTCTITAN HTCTITAN 1463 | ||
1464 | qranium MACH_QRANIUM QRANIUM 1464 | ||
1465 | adx_wsc2 MACH_ADX_WSC2 ADX_WSC2 1465 | ||
1466 | adx_medinet MACH_ADX_MEDINET ADX_MEDINET 1466 | ||
1467 | bboard MACH_BBOARD BBOARD 1467 | ||
1468 | cambria MACH_CAMBRIA CAMBRIA 1468 | ||
1469 | mt7xxx MACH_MT7XXX MT7XXX 1469 | ||
1470 | matrix512 MACH_MATRIX512 MATRIX512 1470 | ||
1471 | matrix522 MACH_MATRIX522 MATRIX522 1471 | ||
1472 | ipac5010 MACH_IPAC5010 IPAC5010 1472 | ||
1473 | sakura MACH_SAKURA SAKURA 1473 | ||
1474 | grocx MACH_GROCX GROCX 1474 | ||
1475 | pm9263 MACH_PM9263 PM9263 1475 | ||
1476 | sim_one MACH_SIM_ONE SIM_ONE 1476 | ||
1477 | acq132 MACH_ACQ132 ACQ132 1477 | ||
1478 | datr MACH_DATR DATR 1478 | ||
1479 | actux1 MACH_ACTUX1 ACTUX1 1479 | ||
1480 | actux2 MACH_ACTUX2 ACTUX2 1480 | ||
1481 | actux3 MACH_ACTUX3 ACTUX3 1481 | ||
1482 | flexit MACH_FLEXIT FLEXIT 1482 | ||
1483 | bh2x0bd MACH_BH2X0BD BH2X0BD 1483 | ||
1484 | atb2002 MACH_ATB2002 ATB2002 1484 | ||
1485 | xenon MACH_XENON XENON 1485 | ||
1486 | fm607 MACH_FM607 FM607 1486 | ||
1487 | matrix514 MACH_MATRIX514 MATRIX514 1487 | ||
1488 | matrix524 MACH_MATRIX524 MATRIX524 1488 | ||
1489 | inpod MACH_INPOD INPOD 1489 | ||
1490 | jive MACH_JIVE JIVE 1490 | ||
1491 | tll_mx21 MACH_TLL_MX21 TLL_MX21 1491 | ||
1492 | sbc2800 MACH_SBC2800 SBC2800 1492 | ||
1493 | cc7ucamry MACH_CC7UCAMRY CC7UCAMRY 1493 | ||
1494 | ubisys_p9_sc15 MACH_UBISYS_P9_SC15 UBISYS_P9_SC15 1494 | ||
1495 | ubisys_p9_ssc2d10 MACH_UBISYS_P9_SSC2D10 UBISYS_P9_SSC2D10 1495 | ||
1496 | ubisys_p9_rcu3 MACH_UBISYS_P9_RCU3 UBISYS_P9_RCU3 1496 | ||
1497 | aml_m8000 MACH_AML_M8000 AML_M8000 1497 | ||
1498 | snapper_270 MACH_SNAPPER_270 SNAPPER_270 1498 | ||
1499 | omap_bbx MACH_OMAP_BBX OMAP_BBX 1499 | ||
1500 | ucn2410 MACH_UCN2410 UCN2410 1500 | ||
1501 | sam9_l9260 MACH_SAM9_L9260 SAM9_L9260 1501 | ||
1502 | eti_c2 MACH_ETI_C2 ETI_C2 1502 | ||
1503 | avalanche MACH_AVALANCHE AVALANCHE 1503 | ||
1504 | realview_pb1176 MACH_REALVIEW_PB1176 REALVIEW_PB1176 1504 | ||
1505 | dp1500 MACH_DP1500 DP1500 1505 | ||
1506 | apple_iphone MACH_APPLE_IPHONE APPLE_IPHONE 1506 | ||
1507 | yl9200 MACH_YL9200 YL9200 1507 | ||
1508 | rd88f5182 MACH_RD88F5182 RD88F5182 1508 | ||
1509 | kurobox_pro MACH_KUROBOX_PRO KUROBOX_PRO 1509 | ||
1510 | se_poet MACH_SE_POET SE_POET 1510 | ||
1511 | mx31_3ds MACH_MX31_3DS MX31_3DS 1511 | ||
1512 | r270 MACH_R270 R270 1512 | ||
1513 | armour21 MACH_ARMOUR21 ARMOUR21 1513 | ||
1514 | dt2 MACH_DT2 DT2 1514 | ||
1515 | vt4 MACH_VT4 VT4 1515 | ||
1516 | tyco320 MACH_TYCO320 TYCO320 1516 | ||
1517 | adma MACH_ADMA ADMA 1517 | ||
1518 | wp188 MACH_WP188 WP188 1518 | ||
1519 | corsica MACH_CORSICA CORSICA 1519 | ||
1520 | bigeye MACH_BIGEYE BIGEYE 1520 | ||
1521 | tll5000 MACH_TLL5000 TLL5000 1522 | ||
1522 | hni270 MACH_HNI_X270 HNI_X270 1523 | ||
1523 | qong MACH_QONG QONG 1524 | ||
1524 | tcompact MACH_TCOMPACT TCOMPACT 1525 | ||
1525 | puma5 MACH_PUMA5 PUMA5 1526 | ||
1526 | elara MACH_ELARA ELARA 1527 | ||
1527 | ellington MACH_ELLINGTON ELLINGTON 1528 | ||
1528 | xda_atom MACH_XDA_ATOM XDA_ATOM 1529 | ||
1529 | energizer2 MACH_ENERGIZER2 ENERGIZER2 1530 | ||
1530 | odin MACH_ODIN ODIN 1531 | ||
1531 | actux4 MACH_ACTUX4 ACTUX4 1532 | ||
1532 | esl_omap MACH_ESL_OMAP ESL_OMAP 1533 | ||
1533 | omap2evm MACH_OMAP2EVM OMAP2EVM 1534 | ||
1534 | omap3evm MACH_OMAP3EVM OMAP3EVM 1535 | ||
1535 | adx_pcu57 MACH_ADX_PCU57 ADX_PCU57 1536 | ||
1536 | monaco MACH_MONACO MONACO 1537 | ||
1537 | levante MACH_LEVANTE LEVANTE 1538 | ||
1538 | tmxipx425 MACH_TMXIPX425 TMXIPX425 1539 | ||
1539 | leep MACH_LEEP LEEP 1540 | ||
1540 | raad MACH_RAAD RAAD 1541 | ||
1541 | dns323 MACH_DNS323 DNS323 1542 | ||
1542 | ap1000 MACH_AP1000 AP1000 1543 | ||
1543 | a9sam6432 MACH_A9SAM6432 A9SAM6432 1544 | ||
1544 | shiny MACH_SHINY SHINY 1545 | ||
1545 | omap3_beagle MACH_OMAP3_BEAGLE OMAP3_BEAGLE 1546 | ||
1546 | csr_bdb2 MACH_CSR_BDB2 CSR_BDB2 1547 | ||
1547 | nokia_n810 MACH_NOKIA_N810 NOKIA_N810 1548 | ||
1548 | c270 MACH_C270 C270 1549 | ||
1549 | sentry MACH_SENTRY SENTRY 1550 | ||
1550 | pcm038 MACH_PCM038 PCM038 1551 | ||
1551 | anc300 MACH_ANC300 ANC300 1552 | ||
1552 | htckaiser MACH_HTCKAISER HTCKAISER 1553 | ||
1553 | sbat100 MACH_SBAT100 SBAT100 1554 | ||
1554 | modunorm MACH_MODUNORM MODUNORM 1555 | ||
1555 | pelos_twarm MACH_PELOS_TWARM PELOS_TWARM 1556 | ||
1556 | flank MACH_FLANK FLANK 1557 | ||
1557 | sirloin MACH_SIRLOIN SIRLOIN 1558 | ||
1558 | brisket MACH_BRISKET BRISKET 1559 | ||
1559 | chuck MACH_CHUCK CHUCK 1560 | ||
1560 | otter MACH_OTTER OTTER 1561 | ||
1561 | davinci_ldk MACH_DAVINCI_LDK DAVINCI_LDK 1562 | ||
1562 | phreedom MACH_PHREEDOM PHREEDOM 1563 | ||
1563 | sg310 MACH_SG310 SG310 1564 | ||
1564 | ts_x09 MACH_TS209 TS209 1565 | ||
1565 | at91cap9adk MACH_AT91CAP9ADK AT91CAP9ADK 1566 | ||
1566 | tion9315 MACH_TION9315 TION9315 1567 | ||
1567 | mast MACH_MAST MAST 1568 | ||
1568 | pfw MACH_PFW PFW 1569 | ||
1569 | yl_p2440 MACH_YL_P2440 YL_P2440 1570 | ||
1570 | zsbc32 MACH_ZSBC32 ZSBC32 1571 | ||
1571 | omap_pace2 MACH_OMAP_PACE2 OMAP_PACE2 1572 | ||
1572 | imx_pace2 MACH_IMX_PACE2 IMX_PACE2 1573 | ||
1573 | mx31moboard MACH_MX31MOBOARD MX31MOBOARD 1574 | ||
1574 | mx37_3ds MACH_MX37_3DS MX37_3DS 1575 | ||
1575 | rcc MACH_RCC RCC 1576 | ||
1576 | dmp MACH_ARM9 ARM9 1577 | ||
1577 | vision_ep9307 MACH_VISION_EP9307 VISION_EP9307 1578 | ||
1578 | scly1000 MACH_SCLY1000 SCLY1000 1579 | ||
1579 | fontel_ep MACH_FONTEL_EP FONTEL_EP 1580 | ||
1580 | voiceblue3g MACH_VOICEBLUE3G VOICEBLUE3G 1581 | ||
1581 | tt9200 MACH_TT9200 TT9200 1582 | ||
1582 | digi2410 MACH_DIGI2410 DIGI2410 1583 | ||
1583 | terastation_pro2 MACH_TERASTATION_PRO2 TERASTATION_PRO2 1584 | ||
1584 | linkstation_pro MACH_LINKSTATION_PRO LINKSTATION_PRO 1585 | ||
1585 | motorola_a780 MACH_MOTOROLA_A780 MOTOROLA_A780 1587 | ||
1586 | motorola_e6 MACH_MOTOROLA_E6 MOTOROLA_E6 1588 | ||
1587 | motorola_e2 MACH_MOTOROLA_E2 MOTOROLA_E2 1589 | ||
1588 | motorola_e680 MACH_MOTOROLA_E680 MOTOROLA_E680 1590 | ||
1589 | ur2410 MACH_UR2410 UR2410 1591 | ||
1590 | tas9261 MACH_TAS9261 TAS9261 1592 | ||
1591 | davinci_hermes_hd MACH_HERMES_HD HERMES_HD 1593 | ||
1592 | davinci_perseo_hd MACH_PERSEO_HD PERSEO_HD 1594 | ||
1593 | stargazer2 MACH_STARGAZER2 STARGAZER2 1595 | ||
1594 | e350 MACH_E350 E350 1596 | ||
1595 | wpcm450 MACH_WPCM450 WPCM450 1597 | ||
1596 | cartesio MACH_CARTESIO CARTESIO 1598 | ||
1597 | toybox MACH_TOYBOX TOYBOX 1599 | ||
1598 | tx27 MACH_TX27 TX27 1600 | ||
1599 | ts409 MACH_TS409 TS409 1601 | ||
1600 | p300 MACH_P300 P300 1602 | ||
1601 | xdacomet MACH_XDACOMET XDACOMET 1603 | ||
1602 | dexflex2 MACH_DEXFLEX2 DEXFLEX2 1604 | ||
1603 | ow MACH_OW OW 1605 | ||
1604 | armebs3 MACH_ARMEBS3 ARMEBS3 1606 | ||
1605 | u3 MACH_U3 U3 1607 | ||
1606 | smdk2450 MACH_SMDK2450 SMDK2450 1608 | ||
1607 | rsi_ews MACH_RSI_EWS RSI_EWS 1609 | ||
1608 | tnb MACH_TNB TNB 1610 | ||
1609 | toepath MACH_TOEPATH TOEPATH 1611 | ||
1610 | kb9263 MACH_KB9263 KB9263 1612 | ||
1611 | mt7108 MACH_MT7108 MT7108 1613 | ||
1612 | smtr2440 MACH_SMTR2440 SMTR2440 1614 | ||
1613 | manao MACH_MANAO MANAO 1615 | ||
diff --git a/arch/arm/vfp/vfp.h b/arch/arm/vfp/vfp.h index 791d0238c68f..c85860bad585 100644 --- a/arch/arm/vfp/vfp.h +++ b/arch/arm/vfp/vfp.h | |||
@@ -265,7 +265,11 @@ struct vfp_double { | |||
265 | * which returns (double)0.0. This is useful for the compare with | 265 | * which returns (double)0.0. This is useful for the compare with |
266 | * zero instructions. | 266 | * zero instructions. |
267 | */ | 267 | */ |
268 | #ifdef CONFIG_VFPv3 | ||
269 | #define VFP_REG_ZERO 32 | ||
270 | #else | ||
268 | #define VFP_REG_ZERO 16 | 271 | #define VFP_REG_ZERO 16 |
272 | #endif | ||
269 | extern u64 vfp_get_double(unsigned int reg); | 273 | extern u64 vfp_get_double(unsigned int reg); |
270 | extern void vfp_put_double(u64 val, unsigned int reg); | 274 | extern void vfp_put_double(u64 val, unsigned int reg); |
271 | 275 | ||
diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S index 0ac022f800a1..353f9e5c7919 100644 --- a/arch/arm/vfp/vfphw.S +++ b/arch/arm/vfp/vfphw.S | |||
@@ -99,12 +99,12 @@ vfp_support_entry: | |||
99 | DBGSTR1 "save old state %p", r4 | 99 | DBGSTR1 "save old state %p", r4 |
100 | cmp r4, #0 | 100 | cmp r4, #0 |
101 | beq no_old_VFP_process | 101 | beq no_old_VFP_process |
102 | VFPFSTMIA r4, r5 @ save the working registers | ||
102 | VFPFMRX r5, FPSCR @ current status | 103 | VFPFMRX r5, FPSCR @ current status |
103 | VFPFMRX r6, FPINST @ FPINST (always there, rev0 onwards) | 104 | tst r1, #FPEXC_EX @ is there additional state to save? |
104 | tst r1, #FPEXC_FPV2 @ is there an FPINST2 to read? | 105 | VFPFMRX r6, FPINST, NE @ FPINST (only if FPEXC.EX is set) |
105 | VFPFMRX r8, FPINST2, NE @ FPINST2 if needed - avoids reading | 106 | tstne r1, #FPEXC_FP2V @ is there an FPINST2 to read? |
106 | @ nonexistant reg on rev0 | 107 | VFPFMRX r8, FPINST2, NE @ FPINST2 if needed (and present) |
107 | VFPFSTMIA r4 @ save the working registers | ||
108 | stmia r4, {r1, r5, r6, r8} @ save FPEXC, FPSCR, FPINST, FPINST2 | 108 | stmia r4, {r1, r5, r6, r8} @ save FPEXC, FPSCR, FPINST, FPINST2 |
109 | @ and point r4 at the word at the | 109 | @ and point r4 at the word at the |
110 | @ start of the register dump | 110 | @ start of the register dump |
@@ -114,13 +114,13 @@ no_old_VFP_process: | |||
114 | DBGSTR1 "load state %p", r10 | 114 | DBGSTR1 "load state %p", r10 |
115 | str r10, [r3, r11, lsl #2] @ update the last_VFP_context pointer | 115 | str r10, [r3, r11, lsl #2] @ update the last_VFP_context pointer |
116 | @ Load the saved state back into the VFP | 116 | @ Load the saved state back into the VFP |
117 | VFPFLDMIA r10 @ reload the working registers while | 117 | VFPFLDMIA r10, r5 @ reload the working registers while |
118 | @ FPEXC is in a safe state | 118 | @ FPEXC is in a safe state |
119 | ldmia r10, {r1, r5, r6, r8} @ load FPEXC, FPSCR, FPINST, FPINST2 | 119 | ldmia r10, {r1, r5, r6, r8} @ load FPEXC, FPSCR, FPINST, FPINST2 |
120 | tst r1, #FPEXC_FPV2 @ is there an FPINST2 to write? | 120 | tst r1, #FPEXC_EX @ is there additional state to restore? |
121 | VFPFMXR FPINST2, r8, NE @ FPINST2 if needed - avoids writing | 121 | VFPFMXR FPINST, r6, NE @ restore FPINST (only if FPEXC.EX is set) |
122 | @ nonexistant reg on rev0 | 122 | tstne r1, #FPEXC_FP2V @ is there an FPINST2 to write? |
123 | VFPFMXR FPINST, r6 | 123 | VFPFMXR FPINST2, r8, NE @ FPINST2 if needed (and present) |
124 | VFPFMXR FPSCR, r5 @ restore status | 124 | VFPFMXR FPSCR, r5 @ restore status |
125 | 125 | ||
126 | check_for_exception: | 126 | check_for_exception: |
@@ -136,10 +136,14 @@ check_for_exception: | |||
136 | 136 | ||
137 | 137 | ||
138 | look_for_VFP_exceptions: | 138 | look_for_VFP_exceptions: |
139 | tst r1, #FPEXC_EX | 139 | @ Check for synchronous or asynchronous exception |
140 | tst r1, #FPEXC_EX | FPEXC_DEX | ||
140 | bne process_exception | 141 | bne process_exception |
142 | @ On some implementations of the VFP subarch 1, setting FPSCR.IXE | ||
143 | @ causes all the CDP instructions to be bounced synchronously without | ||
144 | @ setting the FPEXC.EX bit | ||
141 | VFPFMRX r5, FPSCR | 145 | VFPFMRX r5, FPSCR |
142 | tst r5, #FPSCR_IXE @ IXE doesn't set FPEXC_EX ! | 146 | tst r5, #FPSCR_IXE |
143 | bne process_exception | 147 | bne process_exception |
144 | 148 | ||
145 | @ Fall into hand on to next handler - appropriate coproc instr | 149 | @ Fall into hand on to next handler - appropriate coproc instr |
@@ -150,10 +154,6 @@ look_for_VFP_exceptions: | |||
150 | 154 | ||
151 | process_exception: | 155 | process_exception: |
152 | DBGSTR "bounce" | 156 | DBGSTR "bounce" |
153 | sub r2, r2, #4 | ||
154 | str r2, [sp, #S_PC] @ retry the instruction on exit from | ||
155 | @ the imprecise exception handling in | ||
156 | @ the support code | ||
157 | mov r2, sp @ nothing stacked - regdump is at TOS | 157 | mov r2, sp @ nothing stacked - regdump is at TOS |
158 | mov lr, r9 @ setup for a return to the user code. | 158 | mov lr, r9 @ setup for a return to the user code. |
159 | 159 | ||
@@ -161,7 +161,7 @@ process_exception: | |||
161 | @ r0 holds the trigger instruction | 161 | @ r0 holds the trigger instruction |
162 | @ r1 holds the FPEXC value | 162 | @ r1 holds the FPEXC value |
163 | @ r2 pointer to register dump | 163 | @ r2 pointer to register dump |
164 | b VFP9_bounce @ we have handled this - the support | 164 | b VFP_bounce @ we have handled this - the support |
165 | @ code will raise an exception if | 165 | @ code will raise an exception if |
166 | @ required. If not, the user code will | 166 | @ required. If not, the user code will |
167 | @ retry the faulted instruction | 167 | @ retry the faulted instruction |
@@ -174,12 +174,12 @@ vfp_save_state: | |||
174 | @ r0 - save location | 174 | @ r0 - save location |
175 | @ r1 - FPEXC | 175 | @ r1 - FPEXC |
176 | DBGSTR1 "save VFP state %p", r0 | 176 | DBGSTR1 "save VFP state %p", r0 |
177 | VFPFSTMIA r0, r2 @ save the working registers | ||
177 | VFPFMRX r2, FPSCR @ current status | 178 | VFPFMRX r2, FPSCR @ current status |
178 | VFPFMRX r3, FPINST @ FPINST (always there, rev0 onwards) | 179 | tst r1, #FPEXC_EX @ is there additional state to save? |
179 | tst r1, #FPEXC_FPV2 @ is there an FPINST2 to read? | 180 | VFPFMRX r3, FPINST, NE @ FPINST (only if FPEXC.EX is set) |
180 | VFPFMRX r12, FPINST2, NE @ FPINST2 if needed - avoids reading | 181 | tstne r1, #FPEXC_FP2V @ is there an FPINST2 to read? |
181 | @ nonexistant reg on rev0 | 182 | VFPFMRX r12, FPINST2, NE @ FPINST2 if needed (and present) |
182 | VFPFSTMIA r0 @ save the working registers | ||
183 | stmia r0, {r1, r2, r3, r12} @ save FPEXC, FPSCR, FPINST, FPINST2 | 183 | stmia r0, {r1, r2, r3, r12} @ save FPEXC, FPSCR, FPINST, FPINST2 |
184 | mov pc, lr | 184 | mov pc, lr |
185 | #endif | 185 | #endif |
@@ -217,8 +217,15 @@ vfp_get_double: | |||
217 | fmrrd r0, r1, d\dr | 217 | fmrrd r0, r1, d\dr |
218 | mov pc, lr | 218 | mov pc, lr |
219 | .endr | 219 | .endr |
220 | #ifdef CONFIG_VFPv3 | ||
221 | @ d16 - d31 registers | ||
222 | .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 | ||
223 | mrrc p11, 3, r0, r1, c\dr @ fmrrd r0, r1, d\dr | ||
224 | mov pc, lr | ||
225 | .endr | ||
226 | #endif | ||
220 | 227 | ||
221 | @ virtual register 16 for compare with zero | 228 | @ virtual register 16 (or 32 if VFPv3) for compare with zero |
222 | mov r0, #0 | 229 | mov r0, #0 |
223 | mov r1, #0 | 230 | mov r1, #0 |
224 | mov pc, lr | 231 | mov pc, lr |
@@ -231,3 +238,10 @@ vfp_put_double: | |||
231 | fmdrr d\dr, r0, r1 | 238 | fmdrr d\dr, r0, r1 |
232 | mov pc, lr | 239 | mov pc, lr |
233 | .endr | 240 | .endr |
241 | #ifdef CONFIG_VFPv3 | ||
242 | @ d16 - d31 registers | ||
243 | .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 | ||
244 | mcrr p11, 3, r1, r2, c\dr @ fmdrr r1, r2, d\dr | ||
245 | mov pc, lr | ||
246 | .endr | ||
247 | #endif | ||
diff --git a/arch/arm/vfp/vfpinstr.h b/arch/arm/vfp/vfpinstr.h index 7f343a4beca0..15b95b5ab97e 100644 --- a/arch/arm/vfp/vfpinstr.h +++ b/arch/arm/vfp/vfpinstr.h | |||
@@ -52,11 +52,11 @@ | |||
52 | #define FEXT_TO_IDX(inst) ((inst & 0x000f0000) >> 15 | (inst & (1 << 7)) >> 7) | 52 | #define FEXT_TO_IDX(inst) ((inst & 0x000f0000) >> 15 | (inst & (1 << 7)) >> 7) |
53 | 53 | ||
54 | #define vfp_get_sd(inst) ((inst & 0x0000f000) >> 11 | (inst & (1 << 22)) >> 22) | 54 | #define vfp_get_sd(inst) ((inst & 0x0000f000) >> 11 | (inst & (1 << 22)) >> 22) |
55 | #define vfp_get_dd(inst) ((inst & 0x0000f000) >> 12) | 55 | #define vfp_get_dd(inst) ((inst & 0x0000f000) >> 12 | (inst & (1 << 22)) >> 18) |
56 | #define vfp_get_sm(inst) ((inst & 0x0000000f) << 1 | (inst & (1 << 5)) >> 5) | 56 | #define vfp_get_sm(inst) ((inst & 0x0000000f) << 1 | (inst & (1 << 5)) >> 5) |
57 | #define vfp_get_dm(inst) ((inst & 0x0000000f)) | 57 | #define vfp_get_dm(inst) ((inst & 0x0000000f) | (inst & (1 << 5)) >> 1) |
58 | #define vfp_get_sn(inst) ((inst & 0x000f0000) >> 15 | (inst & (1 << 7)) >> 7) | 58 | #define vfp_get_sn(inst) ((inst & 0x000f0000) >> 15 | (inst & (1 << 7)) >> 7) |
59 | #define vfp_get_dn(inst) ((inst & 0x000f0000) >> 16) | 59 | #define vfp_get_dn(inst) ((inst & 0x000f0000) >> 16 | (inst & (1 << 7)) >> 3) |
60 | 60 | ||
61 | #define vfp_single(inst) (((inst) & 0x0000f00) == 0xa00) | 61 | #define vfp_single(inst) (((inst) & 0x0000f00) == 0xa00) |
62 | 62 | ||
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index b4e210df92f2..32455c633f1c 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c | |||
@@ -125,13 +125,13 @@ void vfp_raise_sigfpe(unsigned int sicode, struct pt_regs *regs) | |||
125 | send_sig_info(SIGFPE, &info, current); | 125 | send_sig_info(SIGFPE, &info, current); |
126 | } | 126 | } |
127 | 127 | ||
128 | static void vfp_panic(char *reason) | 128 | static void vfp_panic(char *reason, u32 inst) |
129 | { | 129 | { |
130 | int i; | 130 | int i; |
131 | 131 | ||
132 | printk(KERN_ERR "VFP: Error: %s\n", reason); | 132 | printk(KERN_ERR "VFP: Error: %s\n", reason); |
133 | printk(KERN_ERR "VFP: EXC 0x%08x SCR 0x%08x INST 0x%08x\n", | 133 | printk(KERN_ERR "VFP: EXC 0x%08x SCR 0x%08x INST 0x%08x\n", |
134 | fmrx(FPEXC), fmrx(FPSCR), fmrx(FPINST)); | 134 | fmrx(FPEXC), fmrx(FPSCR), inst); |
135 | for (i = 0; i < 32; i += 2) | 135 | for (i = 0; i < 32; i += 2) |
136 | printk(KERN_ERR "VFP: s%2u: 0x%08x s%2u: 0x%08x\n", | 136 | printk(KERN_ERR "VFP: s%2u: 0x%08x s%2u: 0x%08x\n", |
137 | i, vfp_get_float(i), i+1, vfp_get_float(i+1)); | 137 | i, vfp_get_float(i), i+1, vfp_get_float(i+1)); |
@@ -147,19 +147,16 @@ static void vfp_raise_exceptions(u32 exceptions, u32 inst, u32 fpscr, struct pt_ | |||
147 | pr_debug("VFP: raising exceptions %08x\n", exceptions); | 147 | pr_debug("VFP: raising exceptions %08x\n", exceptions); |
148 | 148 | ||
149 | if (exceptions == VFP_EXCEPTION_ERROR) { | 149 | if (exceptions == VFP_EXCEPTION_ERROR) { |
150 | vfp_panic("unhandled bounce"); | 150 | vfp_panic("unhandled bounce", inst); |
151 | vfp_raise_sigfpe(0, regs); | 151 | vfp_raise_sigfpe(0, regs); |
152 | return; | 152 | return; |
153 | } | 153 | } |
154 | 154 | ||
155 | /* | 155 | /* |
156 | * If any of the status flags are set, update the FPSCR. | 156 | * Update the FPSCR with the additional exception flags. |
157 | * Comparison instructions always return at least one of | 157 | * Comparison instructions always return at least one of |
158 | * these flags set. | 158 | * these flags set. |
159 | */ | 159 | */ |
160 | if (exceptions & (FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V)) | ||
161 | fpscr &= ~(FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V); | ||
162 | |||
163 | fpscr |= exceptions; | 160 | fpscr |= exceptions; |
164 | 161 | ||
165 | fmxr(FPSCR, fpscr); | 162 | fmxr(FPSCR, fpscr); |
@@ -220,35 +217,64 @@ static u32 vfp_emulate_instruction(u32 inst, u32 fpscr, struct pt_regs *regs) | |||
220 | /* | 217 | /* |
221 | * Package up a bounce condition. | 218 | * Package up a bounce condition. |
222 | */ | 219 | */ |
223 | void VFP9_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) | 220 | void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) |
224 | { | 221 | { |
225 | u32 fpscr, orig_fpscr, exceptions, inst; | 222 | u32 fpscr, orig_fpscr, fpsid, exceptions; |
226 | 223 | ||
227 | pr_debug("VFP: bounce: trigger %08x fpexc %08x\n", trigger, fpexc); | 224 | pr_debug("VFP: bounce: trigger %08x fpexc %08x\n", trigger, fpexc); |
228 | 225 | ||
229 | /* | 226 | /* |
230 | * Enable access to the VFP so we can handle the bounce. | 227 | * At this point, FPEXC can have the following configuration: |
228 | * | ||
229 | * EX DEX IXE | ||
230 | * 0 1 x - synchronous exception | ||
231 | * 1 x 0 - asynchronous exception | ||
232 | * 1 x 1 - sychronous on VFP subarch 1 and asynchronous on later | ||
233 | * 0 0 1 - synchronous on VFP9 (non-standard subarch 1 | ||
234 | * implementation), undefined otherwise | ||
235 | * | ||
236 | * Clear various bits and enable access to the VFP so we can | ||
237 | * handle the bounce. | ||
231 | */ | 238 | */ |
232 | fmxr(FPEXC, fpexc & ~(FPEXC_EX|FPEXC_FPV2|FPEXC_INV|FPEXC_UFC|FPEXC_OFC|FPEXC_IOC)); | 239 | fmxr(FPEXC, fpexc & ~(FPEXC_EX|FPEXC_DEX|FPEXC_FP2V|FPEXC_VV|FPEXC_TRAP_MASK)); |
233 | 240 | ||
241 | fpsid = fmrx(FPSID); | ||
234 | orig_fpscr = fpscr = fmrx(FPSCR); | 242 | orig_fpscr = fpscr = fmrx(FPSCR); |
235 | 243 | ||
236 | /* | 244 | /* |
237 | * If we are running with inexact exceptions enabled, we need to | 245 | * Check for the special VFP subarch 1 and FPSCR.IXE bit case |
238 | * emulate the trigger instruction. Note that as we're emulating | ||
239 | * the trigger instruction, we need to increment PC. | ||
240 | */ | 246 | */ |
241 | if (fpscr & FPSCR_IXE) { | 247 | if ((fpsid & FPSID_ARCH_MASK) == (1 << FPSID_ARCH_BIT) |
242 | regs->ARM_pc += 4; | 248 | && (fpscr & FPSCR_IXE)) { |
249 | /* | ||
250 | * Synchronous exception, emulate the trigger instruction | ||
251 | */ | ||
243 | goto emulate; | 252 | goto emulate; |
244 | } | 253 | } |
245 | 254 | ||
246 | barrier(); | 255 | if (fpexc & FPEXC_EX) { |
256 | /* | ||
257 | * Asynchronous exception. The instruction is read from FPINST | ||
258 | * and the interrupted instruction has to be restarted. | ||
259 | */ | ||
260 | trigger = fmrx(FPINST); | ||
261 | regs->ARM_pc -= 4; | ||
262 | } else if (!(fpexc & FPEXC_DEX)) { | ||
263 | /* | ||
264 | * Illegal combination of bits. It can be caused by an | ||
265 | * unallocated VFP instruction but with FPSCR.IXE set and not | ||
266 | * on VFP subarch 1. | ||
267 | */ | ||
268 | vfp_raise_exceptions(VFP_EXCEPTION_ERROR, trigger, fpscr, regs); | ||
269 | return; | ||
270 | } | ||
247 | 271 | ||
248 | /* | 272 | /* |
249 | * Modify fpscr to indicate the number of iterations remaining | 273 | * Modify fpscr to indicate the number of iterations remaining. |
274 | * If FPEXC.EX is 0, FPEXC.DEX is 1 and the FPEXC.VV bit indicates | ||
275 | * whether FPEXC.VECITR or FPSCR.LEN is used. | ||
250 | */ | 276 | */ |
251 | if (fpexc & FPEXC_EX) { | 277 | if (fpexc & (FPEXC_EX | FPEXC_VV)) { |
252 | u32 len; | 278 | u32 len; |
253 | 279 | ||
254 | len = fpexc + (1 << FPEXC_LENGTH_BIT); | 280 | len = fpexc + (1 << FPEXC_LENGTH_BIT); |
@@ -262,15 +288,15 @@ void VFP9_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) | |||
262 | * FPEXC bounce reason, but this appears to be unreliable. | 288 | * FPEXC bounce reason, but this appears to be unreliable. |
263 | * Emulate the bounced instruction instead. | 289 | * Emulate the bounced instruction instead. |
264 | */ | 290 | */ |
265 | inst = fmrx(FPINST); | 291 | exceptions = vfp_emulate_instruction(trigger, fpscr, regs); |
266 | exceptions = vfp_emulate_instruction(inst, fpscr, regs); | ||
267 | if (exceptions) | 292 | if (exceptions) |
268 | vfp_raise_exceptions(exceptions, inst, orig_fpscr, regs); | 293 | vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs); |
269 | 294 | ||
270 | /* | 295 | /* |
271 | * If there isn't a second FP instruction, exit now. | 296 | * If there isn't a second FP instruction, exit now. Note that |
297 | * the FPEXC.FP2V bit is valid only if FPEXC.EX is 1. | ||
272 | */ | 298 | */ |
273 | if (!(fpexc & FPEXC_FPV2)) | 299 | if (fpexc ^ (FPEXC_EX | FPEXC_FP2V)) |
274 | return; | 300 | return; |
275 | 301 | ||
276 | /* | 302 | /* |
@@ -279,10 +305,9 @@ void VFP9_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) | |||
279 | */ | 305 | */ |
280 | barrier(); | 306 | barrier(); |
281 | trigger = fmrx(FPINST2); | 307 | trigger = fmrx(FPINST2); |
282 | orig_fpscr = fpscr = fmrx(FPSCR); | ||
283 | 308 | ||
284 | emulate: | 309 | emulate: |
285 | exceptions = vfp_emulate_instruction(trigger, fpscr, regs); | 310 | exceptions = vfp_emulate_instruction(trigger, orig_fpscr, regs); |
286 | if (exceptions) | 311 | if (exceptions) |
287 | vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs); | 312 | vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs); |
288 | } | 313 | } |
@@ -306,16 +331,9 @@ static int __init vfp_init(void) | |||
306 | { | 331 | { |
307 | unsigned int vfpsid; | 332 | unsigned int vfpsid; |
308 | unsigned int cpu_arch = cpu_architecture(); | 333 | unsigned int cpu_arch = cpu_architecture(); |
309 | u32 access = 0; | ||
310 | 334 | ||
311 | if (cpu_arch >= CPU_ARCH_ARMv6) { | 335 | if (cpu_arch >= CPU_ARCH_ARMv6) |
312 | access = get_copro_access(); | 336 | vfp_enable(NULL); |
313 | |||
314 | /* | ||
315 | * Enable full access to VFP (cp10 and cp11) | ||
316 | */ | ||
317 | set_copro_access(access | CPACC_FULL(10) | CPACC_FULL(11)); | ||
318 | } | ||
319 | 337 | ||
320 | /* | 338 | /* |
321 | * First check that there is a VFP that we can use. | 339 | * First check that there is a VFP that we can use. |
@@ -329,15 +347,9 @@ static int __init vfp_init(void) | |||
329 | vfp_vector = vfp_null_entry; | 347 | vfp_vector = vfp_null_entry; |
330 | 348 | ||
331 | printk(KERN_INFO "VFP support v0.3: "); | 349 | printk(KERN_INFO "VFP support v0.3: "); |
332 | if (VFP_arch) { | 350 | if (VFP_arch) |
333 | printk("not present\n"); | 351 | printk("not present\n"); |
334 | 352 | else if (vfpsid & FPSID_NODOUBLE) { | |
335 | /* | ||
336 | * Restore the copro access register. | ||
337 | */ | ||
338 | if (cpu_arch >= CPU_ARCH_ARMv6) | ||
339 | set_copro_access(access); | ||
340 | } else if (vfpsid & FPSID_NODOUBLE) { | ||
341 | printk("no double precision support\n"); | 353 | printk("no double precision support\n"); |
342 | } else { | 354 | } else { |
343 | smp_call_function(vfp_enable, NULL, 1, 1); | 355 | smp_call_function(vfp_enable, NULL, 1, 1); |
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index 25232ba08119..fc7ca86ac8bf 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig | |||
@@ -85,11 +85,26 @@ config BF522 | |||
85 | help | 85 | help |
86 | BF522 Processor Support. | 86 | BF522 Processor Support. |
87 | 87 | ||
88 | config BF523 | ||
89 | bool "BF523" | ||
90 | help | ||
91 | BF523 Processor Support. | ||
92 | |||
93 | config BF524 | ||
94 | bool "BF524" | ||
95 | help | ||
96 | BF524 Processor Support. | ||
97 | |||
88 | config BF525 | 98 | config BF525 |
89 | bool "BF525" | 99 | bool "BF525" |
90 | help | 100 | help |
91 | BF525 Processor Support. | 101 | BF525 Processor Support. |
92 | 102 | ||
103 | config BF526 | ||
104 | bool "BF526" | ||
105 | help | ||
106 | BF526 Processor Support. | ||
107 | |||
93 | config BF527 | 108 | config BF527 |
94 | bool "BF527" | 109 | bool "BF527" |
95 | help | 110 | help |
@@ -198,7 +213,7 @@ endchoice | |||
198 | 213 | ||
199 | config BF52x | 214 | config BF52x |
200 | bool | 215 | bool |
201 | depends on (BF522 || BF525 || BF527) | 216 | depends on (BF522 || BF523 || BF524 || BF525 || BF526 || BF527) |
202 | default y | 217 | default y |
203 | 218 | ||
204 | config BF53x | 219 | config BF53x |
@@ -253,11 +268,6 @@ config MEM_MT48LC32M16A2TG_75 | |||
253 | depends on (BFIN527_EZKIT) | 268 | depends on (BFIN527_EZKIT) |
254 | default y | 269 | default y |
255 | 270 | ||
256 | config BFIN_SHARED_FLASH_ENET | ||
257 | bool | ||
258 | depends on (BFIN533_STAMP) | ||
259 | default y | ||
260 | |||
261 | source "arch/blackfin/mach-bf527/Kconfig" | 271 | source "arch/blackfin/mach-bf527/Kconfig" |
262 | source "arch/blackfin/mach-bf533/Kconfig" | 272 | source "arch/blackfin/mach-bf533/Kconfig" |
263 | source "arch/blackfin/mach-bf561/Kconfig" | 273 | source "arch/blackfin/mach-bf561/Kconfig" |
@@ -317,7 +327,7 @@ config VCO_MULT | |||
317 | range 1 64 | 327 | range 1 64 |
318 | default "22" if BFIN533_EZKIT | 328 | default "22" if BFIN533_EZKIT |
319 | default "45" if BFIN533_STAMP | 329 | default "45" if BFIN533_STAMP |
320 | default "20" if (BFIN537_STAMP || BFIN527_EZKIT) | 330 | default "20" if (BFIN537_STAMP || BFIN527_EZKIT || BFIN548_EZKIT) |
321 | default "22" if BFIN533_BLUETECHNIX_CM | 331 | default "22" if BFIN533_BLUETECHNIX_CM |
322 | default "20" if BFIN537_BLUETECHNIX_CM | 332 | default "20" if BFIN537_BLUETECHNIX_CM |
323 | default "20" if BFIN561_BLUETECHNIX_CM | 333 | default "20" if BFIN561_BLUETECHNIX_CM |
@@ -354,7 +364,7 @@ config SCLK_DIV | |||
354 | range 1 15 | 364 | range 1 15 |
355 | default 5 if BFIN533_EZKIT | 365 | default 5 if BFIN533_EZKIT |
356 | default 5 if BFIN533_STAMP | 366 | default 5 if BFIN533_STAMP |
357 | default 4 if (BFIN537_STAMP || BFIN527_EZKIT) | 367 | default 4 if (BFIN537_STAMP || BFIN527_EZKIT || BFIN548_EZKIT) |
358 | default 5 if BFIN533_BLUETECHNIX_CM | 368 | default 5 if BFIN533_BLUETECHNIX_CM |
359 | default 4 if BFIN537_BLUETECHNIX_CM | 369 | default 4 if BFIN537_BLUETECHNIX_CM |
360 | default 4 if BFIN561_BLUETECHNIX_CM | 370 | default 4 if BFIN561_BLUETECHNIX_CM |
@@ -371,7 +381,10 @@ config SCLK_DIV | |||
371 | config MAX_VCO_HZ | 381 | config MAX_VCO_HZ |
372 | int | 382 | int |
373 | default 600000000 if BF522 | 383 | default 600000000 if BF522 |
384 | default 400000000 if BF523 | ||
385 | default 400000000 if BF524 | ||
374 | default 600000000 if BF525 | 386 | default 600000000 if BF525 |
387 | default 400000000 if BF526 | ||
375 | default 600000000 if BF527 | 388 | default 600000000 if BF527 |
376 | default 400000000 if BF531 | 389 | default 400000000 if BF531 |
377 | default 400000000 if BF532 | 390 | default 400000000 if BF532 |
@@ -383,6 +396,8 @@ config MAX_VCO_HZ | |||
383 | default 533333333 if BF539 | 396 | default 533333333 if BF539 |
384 | default 600000000 if BF542 | 397 | default 600000000 if BF542 |
385 | default 533333333 if BF544 | 398 | default 533333333 if BF544 |
399 | default 600000000 if BF547 | ||
400 | default 600000000 if BF548 | ||
386 | default 533333333 if BF549 | 401 | default 533333333 if BF549 |
387 | default 600000000 if BF561 | 402 | default 600000000 if BF561 |
388 | 403 | ||
@@ -409,6 +424,7 @@ config MEM_SIZE | |||
409 | default 32 if BFIN533_EZKIT | 424 | default 32 if BFIN533_EZKIT |
410 | default 64 if BFIN527_EZKIT | 425 | default 64 if BFIN527_EZKIT |
411 | default 64 if BFIN537_STAMP | 426 | default 64 if BFIN537_STAMP |
427 | default 64 if BFIN548_EZKIT | ||
412 | default 64 if BFIN561_EZKIT | 428 | default 64 if BFIN561_EZKIT |
413 | default 128 if BFIN533_STAMP | 429 | default 128 if BFIN533_STAMP |
414 | default 64 if PNAV10 | 430 | default 64 if PNAV10 |
@@ -416,6 +432,7 @@ config MEM_SIZE | |||
416 | 432 | ||
417 | config MEM_ADD_WIDTH | 433 | config MEM_ADD_WIDTH |
418 | int "SDRAM Memory Address Width" | 434 | int "SDRAM Memory Address Width" |
435 | depends on (!BF54x) | ||
419 | default 9 if BFIN533_EZKIT | 436 | default 9 if BFIN533_EZKIT |
420 | default 9 if BFIN561_EZKIT | 437 | default 9 if BFIN561_EZKIT |
421 | default 9 if H8606_HVSISTEMAS | 438 | default 9 if H8606_HVSISTEMAS |
@@ -424,6 +441,19 @@ config MEM_ADD_WIDTH | |||
424 | default 11 if BFIN533_STAMP | 441 | default 11 if BFIN533_STAMP |
425 | default 10 if PNAV10 | 442 | default 10 if PNAV10 |
426 | 443 | ||
444 | |||
445 | choice | ||
446 | prompt "DDR SDRAM Chip Type" | ||
447 | depends on BFIN548_EZKIT | ||
448 | default MEM_MT46V32M16_5B | ||
449 | |||
450 | config MEM_MT46V32M16_6T | ||
451 | bool "MT46V32M16_6T" | ||
452 | |||
453 | config MEM_MT46V32M16_5B | ||
454 | bool "MT46V32M16_5B" | ||
455 | endchoice | ||
456 | |||
427 | config ENET_FLASH_PIN | 457 | config ENET_FLASH_PIN |
428 | int "PF port/pin used for flash and ethernet sharing" | 458 | int "PF port/pin used for flash and ethernet sharing" |
429 | depends on (BFIN533_STAMP) | 459 | depends on (BFIN533_STAMP) |
@@ -448,40 +478,6 @@ config BOOT_LOAD | |||
448 | memory region is used to capture NULL pointer references as well | 478 | memory region is used to capture NULL pointer references as well |
449 | as some core kernel functions. | 479 | as some core kernel functions. |
450 | 480 | ||
451 | comment "LED Status Indicators" | ||
452 | depends on (BFIN533_STAMP || BFIN533_BLUETECHNIX_CM) | ||
453 | |||
454 | config BFIN_ALIVE_LED | ||
455 | bool "Enable Board Alive" | ||
456 | depends on (BFIN533_STAMP || BFIN533_BLUETECHNIX_CM) | ||
457 | default n | ||
458 | help | ||
459 | Blink the LEDs you select when the kernel is running. Helps detect | ||
460 | a hung kernel. | ||
461 | |||
462 | config BFIN_ALIVE_LED_NUM | ||
463 | int "LED" | ||
464 | depends on BFIN_ALIVE_LED | ||
465 | range 1 3 if BFIN533_STAMP | ||
466 | default "3" if BFIN533_STAMP | ||
467 | help | ||
468 | Select the LED (marked on the board) for you to blink. | ||
469 | |||
470 | config BFIN_IDLE_LED | ||
471 | bool "Enable System Load/Idle LED" | ||
472 | depends on (BFIN533_STAMP || BFIN533_BLUETECHNIX_CM) | ||
473 | default n | ||
474 | help | ||
475 | Blinks the LED you select when to determine kernel load. | ||
476 | |||
477 | config BFIN_IDLE_LED_NUM | ||
478 | int "LED" | ||
479 | depends on BFIN_IDLE_LED | ||
480 | range 1 3 if BFIN533_STAMP | ||
481 | default "2" if BFIN533_STAMP | ||
482 | help | ||
483 | Select the LED (marked on the board) for you to blink. | ||
484 | |||
485 | choice | 481 | choice |
486 | prompt "Blackfin Exception Scratch Register" | 482 | prompt "Blackfin Exception Scratch Register" |
487 | default BFIN_SCRATCH_REG_RETN | 483 | default BFIN_SCRATCH_REG_RETN |
@@ -528,41 +524,6 @@ config BFIN_SCRATCH_REG_CYCLES | |||
528 | 524 | ||
529 | endchoice | 525 | endchoice |
530 | 526 | ||
531 | # | ||
532 | # Sorry - but you need to put the hex address here - | ||
533 | # | ||
534 | |||
535 | # Flag Data register | ||
536 | config BFIN_ALIVE_LED_PORT | ||
537 | hex | ||
538 | default 0xFFC00700 if (BFIN533_STAMP) | ||
539 | |||
540 | # Peripheral Flag Direction Register | ||
541 | config BFIN_ALIVE_LED_DPORT | ||
542 | hex | ||
543 | default 0xFFC00730 if (BFIN533_STAMP) | ||
544 | |||
545 | config BFIN_ALIVE_LED_PIN | ||
546 | hex | ||
547 | default 0x04 if (BFIN533_STAMP && BFIN_ALIVE_LED_NUM = 1) | ||
548 | default 0x08 if (BFIN533_STAMP && BFIN_ALIVE_LED_NUM = 2) | ||
549 | default 0x10 if (BFIN533_STAMP && BFIN_ALIVE_LED_NUM = 3) | ||
550 | |||
551 | config BFIN_IDLE_LED_PORT | ||
552 | hex | ||
553 | default 0xFFC00700 if (BFIN533_STAMP) | ||
554 | |||
555 | # Peripheral Flag Direction Register | ||
556 | config BFIN_IDLE_LED_DPORT | ||
557 | hex | ||
558 | default 0xFFC00730 if (BFIN533_STAMP) | ||
559 | |||
560 | config BFIN_IDLE_LED_PIN | ||
561 | hex | ||
562 | default 0x04 if (BFIN533_STAMP && BFIN_IDLE_LED_NUM = 1) | ||
563 | default 0x08 if (BFIN533_STAMP && BFIN_IDLE_LED_NUM = 2) | ||
564 | default 0x10 if (BFIN533_STAMP && BFIN_IDLE_LED_NUM = 3) | ||
565 | |||
566 | endmenu | 527 | endmenu |
567 | 528 | ||
568 | 529 | ||
@@ -799,6 +760,15 @@ config L1_MAX_PIECE | |||
799 | Set the max memory pieces for the L1 SRAM allocation algorithm. | 760 | Set the max memory pieces for the L1 SRAM allocation algorithm. |
800 | Min value is 16. Max value is 1024. | 761 | Min value is 16. Max value is 1024. |
801 | 762 | ||
763 | |||
764 | config MPU | ||
765 | bool "Enable the memory protection unit (EXPERIMENTAL)" | ||
766 | default n | ||
767 | help | ||
768 | Use the processor's MPU to protect applications from accessing | ||
769 | memory they do not own. This comes at a performance penalty | ||
770 | and is recommended only for debugging. | ||
771 | |||
802 | comment "Asynchonous Memory Configuration" | 772 | comment "Asynchonous Memory Configuration" |
803 | 773 | ||
804 | menu "EBIU_AMGCTL Global Control" | 774 | menu "EBIU_AMGCTL Global Control" |
@@ -808,7 +778,6 @@ config C_AMCKEN | |||
808 | 778 | ||
809 | config C_CDPRIO | 779 | config C_CDPRIO |
810 | bool "DMA has priority over core for ext. accesses" | 780 | bool "DMA has priority over core for ext. accesses" |
811 | depends on !BF54x | ||
812 | default n | 781 | default n |
813 | 782 | ||
814 | config C_B0PEN | 783 | config C_B0PEN |
@@ -949,8 +918,10 @@ endchoice | |||
949 | config PM_WAKEUP_SIC_IWR | 918 | config PM_WAKEUP_SIC_IWR |
950 | hex "Wakeup Events (SIC_IWR)" | 919 | hex "Wakeup Events (SIC_IWR)" |
951 | depends on PM_WAKEUP_GPIO_BY_SIC_IWR | 920 | depends on PM_WAKEUP_GPIO_BY_SIC_IWR |
952 | default 0x80000000 if (BF537 || BF536 || BF534) | 921 | default 0x8 if (BF537 || BF536 || BF534) |
953 | default 0x100000 if (BF533 || BF532 || BF531) | 922 | default 0x80 if (BF533 || BF532 || BF531) |
923 | default 0x80 if (BF54x) | ||
924 | default 0x80 if (BF52x) | ||
954 | 925 | ||
955 | config PM_WAKEUP_GPIO_NUMBER | 926 | config PM_WAKEUP_GPIO_NUMBER |
956 | int "Wakeup GPIO number" | 927 | int "Wakeup GPIO number" |
diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile index c47e000f8324..0edc402fef54 100644 --- a/arch/blackfin/Makefile +++ b/arch/blackfin/Makefile | |||
@@ -21,7 +21,10 @@ KBUILD_DEFCONFIG := BF537-STAMP_defconfig | |||
21 | 21 | ||
22 | # setup the machine name and the machine dependent settings | 22 | # setup the machine name and the machine dependent settings |
23 | machine-$(CONFIG_BF522) := bf527 | 23 | machine-$(CONFIG_BF522) := bf527 |
24 | machine-$(CONFIG_BF523) := bf527 | ||
25 | machine-$(CONFIG_BF524) := bf527 | ||
24 | machine-$(CONFIG_BF525) := bf527 | 26 | machine-$(CONFIG_BF525) := bf527 |
27 | machine-$(CONFIG_BF526) := bf527 | ||
25 | machine-$(CONFIG_BF527) := bf527 | 28 | machine-$(CONFIG_BF527) := bf527 |
26 | machine-$(CONFIG_BF531) := bf533 | 29 | machine-$(CONFIG_BF531) := bf533 |
27 | machine-$(CONFIG_BF532) := bf533 | 30 | machine-$(CONFIG_BF532) := bf533 |
@@ -39,7 +42,10 @@ MACHINE := $(machine-y) | |||
39 | export MACHINE | 42 | export MACHINE |
40 | 43 | ||
41 | cpu-$(CONFIG_BF522) := bf522 | 44 | cpu-$(CONFIG_BF522) := bf522 |
45 | cpu-$(CONFIG_BF523) := bf523 | ||
46 | cpu-$(CONFIG_BF524) := bf524 | ||
42 | cpu-$(CONFIG_BF525) := bf525 | 47 | cpu-$(CONFIG_BF525) := bf525 |
48 | cpu-$(CONFIG_BF526) := bf526 | ||
43 | cpu-$(CONFIG_BF527) := bf527 | 49 | cpu-$(CONFIG_BF527) := bf527 |
44 | cpu-$(CONFIG_BF531) := bf531 | 50 | cpu-$(CONFIG_BF531) := bf531 |
45 | cpu-$(CONFIG_BF532) := bf532 | 51 | cpu-$(CONFIG_BF532) := bf532 |
@@ -76,6 +82,12 @@ core-y += arch/$(ARCH)/mach-$(MACHINE)/ | |||
76 | core-y += arch/$(ARCH)/mach-$(MACHINE)/boards/ | 82 | core-y += arch/$(ARCH)/mach-$(MACHINE)/boards/ |
77 | endif | 83 | endif |
78 | 84 | ||
85 | ifeq ($(CONFIG_MPU),y) | ||
86 | core-y += arch/$(ARCH)/kernel/cplb-mpu/ | ||
87 | else | ||
88 | core-y += arch/$(ARCH)/kernel/cplb-nompu/ | ||
89 | endif | ||
90 | |||
79 | libs-y += arch/$(ARCH)/lib/ | 91 | libs-y += arch/$(ARCH)/lib/ |
80 | 92 | ||
81 | drivers-$(CONFIG_OPROFILE) += arch/$(ARCH)/oprofile/ | 93 | drivers-$(CONFIG_OPROFILE) += arch/$(ARCH)/oprofile/ |
diff --git a/arch/blackfin/configs/BF527-EZKIT_defconfig b/arch/blackfin/configs/BF527-EZKIT_defconfig index fa6eb4e00fae..d59ee1530bd4 100644 --- a/arch/blackfin/configs/BF527-EZKIT_defconfig +++ b/arch/blackfin/configs/BF527-EZKIT_defconfig | |||
@@ -1,6 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.22.12 | 3 | # Linux kernel version: 2.6.22.14 |
4 | # Thu Nov 29 17:32:47 2007 | ||
4 | # | 5 | # |
5 | # CONFIG_MMU is not set | 6 | # CONFIG_MMU is not set |
6 | # CONFIG_FPU is not set | 7 | # CONFIG_FPU is not set |
@@ -153,8 +154,8 @@ CONFIG_BFIN527_EZKIT=y | |||
153 | CONFIG_BF527_SPORT0_PORTG=y | 154 | CONFIG_BF527_SPORT0_PORTG=y |
154 | CONFIG_BF527_SPORT0_TSCLK_PG10=y | 155 | CONFIG_BF527_SPORT0_TSCLK_PG10=y |
155 | # CONFIG_BF527_SPORT0_TSCLK_PG14 is not set | 156 | # CONFIG_BF527_SPORT0_TSCLK_PG14 is not set |
156 | # CONFIG_BF527_UART1_PORTF is not set | 157 | CONFIG_BF527_UART1_PORTF=y |
157 | CONFIG_BF527_UART1_PORTG=y | 158 | # CONFIG_BF527_UART1_PORTG is not set |
158 | # CONFIG_BF527_NAND_D_PORTF is not set | 159 | # CONFIG_BF527_NAND_D_PORTF is not set |
159 | CONFIG_BF527_NAND_D_PORTH=y | 160 | CONFIG_BF527_NAND_D_PORTH=y |
160 | 161 | ||
@@ -232,7 +233,7 @@ CONFIG_CLKIN_HZ=25000000 | |||
232 | # CONFIG_BFIN_KERNEL_CLOCK is not set | 233 | # CONFIG_BFIN_KERNEL_CLOCK is not set |
233 | CONFIG_MAX_VCO_HZ=600000000 | 234 | CONFIG_MAX_VCO_HZ=600000000 |
234 | CONFIG_MIN_VCO_HZ=50000000 | 235 | CONFIG_MIN_VCO_HZ=50000000 |
235 | CONFIG_MAX_SCLK_HZ=133000000 | 236 | CONFIG_MAX_SCLK_HZ=133333333 |
236 | CONFIG_MIN_SCLK_HZ=27000000 | 237 | CONFIG_MIN_SCLK_HZ=27000000 |
237 | 238 | ||
238 | # | 239 | # |
@@ -626,8 +627,8 @@ CONFIG_BFIN_MAC_RMII=y | |||
626 | # CONFIG_SMSC911X is not set | 627 | # CONFIG_SMSC911X is not set |
627 | # CONFIG_DM9000 is not set | 628 | # CONFIG_DM9000 is not set |
628 | CONFIG_NETDEV_1000=y | 629 | CONFIG_NETDEV_1000=y |
629 | CONFIG_NETDEV_10000=y | ||
630 | # CONFIG_AX88180 is not set | 630 | # CONFIG_AX88180 is not set |
631 | CONFIG_NETDEV_10000=y | ||
631 | 632 | ||
632 | # | 633 | # |
633 | # Wireless LAN | 634 | # Wireless LAN |
@@ -1183,7 +1184,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" | |||
1183 | # | 1184 | # |
1184 | # CONFIG_PRINTK_TIME is not set | 1185 | # CONFIG_PRINTK_TIME is not set |
1185 | CONFIG_ENABLE_MUST_CHECK=y | 1186 | CONFIG_ENABLE_MUST_CHECK=y |
1186 | CONFIG_MAGIC_SYSRQ=y | 1187 | # CONFIG_MAGIC_SYSRQ is not set |
1187 | # CONFIG_UNUSED_SYMBOLS is not set | 1188 | # CONFIG_UNUSED_SYMBOLS is not set |
1188 | CONFIG_DEBUG_FS=y | 1189 | CONFIG_DEBUG_FS=y |
1189 | # CONFIG_HEADERS_CHECK is not set | 1190 | # CONFIG_HEADERS_CHECK is not set |
@@ -1208,7 +1209,7 @@ CONFIG_ACCESS_CHECK=y | |||
1208 | # CONFIG_KEYS is not set | 1209 | # CONFIG_KEYS is not set |
1209 | CONFIG_SECURITY=y | 1210 | CONFIG_SECURITY=y |
1210 | # CONFIG_SECURITY_NETWORK is not set | 1211 | # CONFIG_SECURITY_NETWORK is not set |
1211 | CONFIG_SECURITY_CAPABILITIES=y | 1212 | CONFIG_SECURITY_CAPABILITIES=m |
1212 | 1213 | ||
1213 | # | 1214 | # |
1214 | # Cryptographic options | 1215 | # Cryptographic options |
@@ -1219,7 +1220,7 @@ CONFIG_SECURITY_CAPABILITIES=y | |||
1219 | # Library routines | 1220 | # Library routines |
1220 | # | 1221 | # |
1221 | CONFIG_BITREVERSE=y | 1222 | CONFIG_BITREVERSE=y |
1222 | # CONFIG_CRC_CCITT is not set | 1223 | CONFIG_CRC_CCITT=m |
1223 | # CONFIG_CRC16 is not set | 1224 | # CONFIG_CRC16 is not set |
1224 | # CONFIG_CRC_ITU_T is not set | 1225 | # CONFIG_CRC_ITU_T is not set |
1225 | CONFIG_CRC32=y | 1226 | CONFIG_CRC32=y |
diff --git a/arch/blackfin/configs/BF533-EZKIT_defconfig b/arch/blackfin/configs/BF533-EZKIT_defconfig index 4fdb49362ba3..811711f59a25 100644 --- a/arch/blackfin/configs/BF533-EZKIT_defconfig +++ b/arch/blackfin/configs/BF533-EZKIT_defconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.22.12 | 3 | # Linux kernel version: 2.6.22.16 |
4 | # | 4 | # |
5 | # CONFIG_MMU is not set | 5 | # CONFIG_MMU is not set |
6 | # CONFIG_FPU is not set | 6 | # CONFIG_FPU is not set |
@@ -115,7 +115,10 @@ CONFIG_PREEMPT_VOLUNTARY=y | |||
115 | # Processor and Board Settings | 115 | # Processor and Board Settings |
116 | # | 116 | # |
117 | # CONFIG_BF522 is not set | 117 | # CONFIG_BF522 is not set |
118 | # CONFIG_BF523 is not set | ||
119 | # CONFIG_BF524 is not set | ||
118 | # CONFIG_BF525 is not set | 120 | # CONFIG_BF525 is not set |
121 | # CONFIG_BF526 is not set | ||
119 | # CONFIG_BF527 is not set | 122 | # CONFIG_BF527 is not set |
120 | # CONFIG_BF531 is not set | 123 | # CONFIG_BF531 is not set |
121 | # CONFIG_BF532 is not set | 124 | # CONFIG_BF532 is not set |
@@ -194,7 +197,7 @@ CONFIG_CLKIN_HZ=27000000 | |||
194 | # CONFIG_BFIN_KERNEL_CLOCK is not set | 197 | # CONFIG_BFIN_KERNEL_CLOCK is not set |
195 | CONFIG_MAX_VCO_HZ=750000000 | 198 | CONFIG_MAX_VCO_HZ=750000000 |
196 | CONFIG_MIN_VCO_HZ=50000000 | 199 | CONFIG_MIN_VCO_HZ=50000000 |
197 | CONFIG_MAX_SCLK_HZ=133000000 | 200 | CONFIG_MAX_SCLK_HZ=133333333 |
198 | CONFIG_MIN_SCLK_HZ=27000000 | 201 | CONFIG_MIN_SCLK_HZ=27000000 |
199 | 202 | ||
200 | # | 203 | # |
@@ -267,6 +270,7 @@ CONFIG_BFIN_DCACHE=y | |||
267 | # CONFIG_BFIN_WB is not set | 270 | # CONFIG_BFIN_WB is not set |
268 | CONFIG_BFIN_WT=y | 271 | CONFIG_BFIN_WT=y |
269 | CONFIG_L1_MAX_PIECE=16 | 272 | CONFIG_L1_MAX_PIECE=16 |
273 | # CONFIG_MPU is not set | ||
270 | 274 | ||
271 | # | 275 | # |
272 | # Asynchonous Memory Configuration | 276 | # Asynchonous Memory Configuration |
@@ -321,7 +325,7 @@ CONFIG_PM=y | |||
321 | CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y | 325 | CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y |
322 | # CONFIG_PM_WAKEUP_BY_GPIO is not set | 326 | # CONFIG_PM_WAKEUP_BY_GPIO is not set |
323 | # CONFIG_PM_WAKEUP_GPIO_API is not set | 327 | # CONFIG_PM_WAKEUP_GPIO_API is not set |
324 | CONFIG_PM_WAKEUP_SIC_IWR=0x100000 | 328 | CONFIG_PM_WAKEUP_SIC_IWR=0x80 |
325 | 329 | ||
326 | # | 330 | # |
327 | # CPU Frequency scaling | 331 | # CPU Frequency scaling |
@@ -510,7 +514,6 @@ CONFIG_MTD_CFI_I2=y | |||
510 | # CONFIG_MTD_CFI_INTELEXT is not set | 514 | # CONFIG_MTD_CFI_INTELEXT is not set |
511 | # CONFIG_MTD_CFI_AMDSTD is not set | 515 | # CONFIG_MTD_CFI_AMDSTD is not set |
512 | # CONFIG_MTD_CFI_STAA is not set | 516 | # CONFIG_MTD_CFI_STAA is not set |
513 | CONFIG_MTD_MW320D=m | ||
514 | CONFIG_MTD_RAM=y | 517 | CONFIG_MTD_RAM=y |
515 | CONFIG_MTD_ROM=m | 518 | CONFIG_MTD_ROM=m |
516 | # CONFIG_MTD_ABSENT is not set | 519 | # CONFIG_MTD_ABSENT is not set |
@@ -520,9 +523,6 @@ CONFIG_MTD_ROM=m | |||
520 | # | 523 | # |
521 | CONFIG_MTD_COMPLEX_MAPPINGS=y | 524 | CONFIG_MTD_COMPLEX_MAPPINGS=y |
522 | # CONFIG_MTD_PHYSMAP is not set | 525 | # CONFIG_MTD_PHYSMAP is not set |
523 | CONFIG_MTD_BF5xx=m | ||
524 | CONFIG_BFIN_FLASH_SIZE=0x400000 | ||
525 | CONFIG_EBIU_FLASH_BASE=0x20000000 | ||
526 | # CONFIG_MTD_UCLINUX is not set | 526 | # CONFIG_MTD_UCLINUX is not set |
527 | # CONFIG_MTD_PLATRAM is not set | 527 | # CONFIG_MTD_PLATRAM is not set |
528 | 528 | ||
@@ -610,8 +610,8 @@ CONFIG_SMC91X=y | |||
610 | # CONFIG_SMSC911X is not set | 610 | # CONFIG_SMSC911X is not set |
611 | # CONFIG_DM9000 is not set | 611 | # CONFIG_DM9000 is not set |
612 | CONFIG_NETDEV_1000=y | 612 | CONFIG_NETDEV_1000=y |
613 | CONFIG_NETDEV_10000=y | ||
614 | # CONFIG_AX88180 is not set | 613 | # CONFIG_AX88180 is not set |
614 | CONFIG_NETDEV_10000=y | ||
615 | 615 | ||
616 | # | 616 | # |
617 | # Wireless LAN | 617 | # Wireless LAN |
@@ -680,7 +680,6 @@ CONFIG_INPUT_EVDEV=m | |||
680 | CONFIG_BFIN_SPORT=y | 680 | CONFIG_BFIN_SPORT=y |
681 | # CONFIG_BFIN_TIMER_LATENCY is not set | 681 | # CONFIG_BFIN_TIMER_LATENCY is not set |
682 | # CONFIG_AD5304 is not set | 682 | # CONFIG_AD5304 is not set |
683 | # CONFIG_BF5xx_FBDMA is not set | ||
684 | # CONFIG_VT is not set | 683 | # CONFIG_VT is not set |
685 | # CONFIG_SERIAL_NONSTANDARD is not set | 684 | # CONFIG_SERIAL_NONSTANDARD is not set |
686 | 685 | ||
diff --git a/arch/blackfin/configs/BF533-STAMP_defconfig b/arch/blackfin/configs/BF533-STAMP_defconfig index b04e8e533e9a..9b7123cf27a3 100644 --- a/arch/blackfin/configs/BF533-STAMP_defconfig +++ b/arch/blackfin/configs/BF533-STAMP_defconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.22.12 | 3 | # Linux kernel version: 2.6.22.16 |
4 | # | 4 | # |
5 | # CONFIG_MMU is not set | 5 | # CONFIG_MMU is not set |
6 | # CONFIG_FPU is not set | 6 | # CONFIG_FPU is not set |
@@ -115,7 +115,10 @@ CONFIG_PREEMPT_VOLUNTARY=y | |||
115 | # Processor and Board Settings | 115 | # Processor and Board Settings |
116 | # | 116 | # |
117 | # CONFIG_BF522 is not set | 117 | # CONFIG_BF522 is not set |
118 | # CONFIG_BF523 is not set | ||
119 | # CONFIG_BF524 is not set | ||
118 | # CONFIG_BF525 is not set | 120 | # CONFIG_BF525 is not set |
121 | # CONFIG_BF526 is not set | ||
119 | # CONFIG_BF527 is not set | 122 | # CONFIG_BF527 is not set |
120 | # CONFIG_BF531 is not set | 123 | # CONFIG_BF531 is not set |
121 | # CONFIG_BF532 is not set | 124 | # CONFIG_BF532 is not set |
@@ -140,7 +143,6 @@ CONFIG_BF_REV_0_3=y | |||
140 | CONFIG_BF53x=y | 143 | CONFIG_BF53x=y |
141 | CONFIG_BFIN_SINGLE_CORE=y | 144 | CONFIG_BFIN_SINGLE_CORE=y |
142 | CONFIG_MEM_MT48LC64M4A2FB_7E=y | 145 | CONFIG_MEM_MT48LC64M4A2FB_7E=y |
143 | CONFIG_BFIN_SHARED_FLASH_ENET=y | ||
144 | # CONFIG_BFIN533_EZKIT is not set | 146 | # CONFIG_BFIN533_EZKIT is not set |
145 | CONFIG_BFIN533_STAMP=y | 147 | CONFIG_BFIN533_STAMP=y |
146 | # CONFIG_BFIN533_BLUETECHNIX_CM is not set | 148 | # CONFIG_BFIN533_BLUETECHNIX_CM is not set |
@@ -195,7 +197,7 @@ CONFIG_CLKIN_HZ=11059200 | |||
195 | # CONFIG_BFIN_KERNEL_CLOCK is not set | 197 | # CONFIG_BFIN_KERNEL_CLOCK is not set |
196 | CONFIG_MAX_VCO_HZ=750000000 | 198 | CONFIG_MAX_VCO_HZ=750000000 |
197 | CONFIG_MIN_VCO_HZ=50000000 | 199 | CONFIG_MIN_VCO_HZ=50000000 |
198 | CONFIG_MAX_SCLK_HZ=133000000 | 200 | CONFIG_MAX_SCLK_HZ=133333333 |
199 | CONFIG_MIN_SCLK_HZ=27000000 | 201 | CONFIG_MIN_SCLK_HZ=27000000 |
200 | 202 | ||
201 | # | 203 | # |
@@ -215,18 +217,10 @@ CONFIG_MEM_ADD_WIDTH=11 | |||
215 | CONFIG_ENET_FLASH_PIN=0 | 217 | CONFIG_ENET_FLASH_PIN=0 |
216 | CONFIG_BOOT_LOAD=0x1000 | 218 | CONFIG_BOOT_LOAD=0x1000 |
217 | 219 | ||
218 | # | 220 | |
219 | # LED Status Indicators | ||
220 | # | ||
221 | # CONFIG_BFIN_ALIVE_LED is not set | ||
222 | # CONFIG_BFIN_IDLE_LED is not set | ||
223 | CONFIG_BFIN_SCRATCH_REG_RETN=y | 221 | CONFIG_BFIN_SCRATCH_REG_RETN=y |
224 | # CONFIG_BFIN_SCRATCH_REG_RETE is not set | 222 | # CONFIG_BFIN_SCRATCH_REG_RETE is not set |
225 | # CONFIG_BFIN_SCRATCH_REG_CYCLES is not set | 223 | # CONFIG_BFIN_SCRATCH_REG_CYCLES is not set |
226 | CONFIG_BFIN_ALIVE_LED_PORT=0xFFC00700 | ||
227 | CONFIG_BFIN_ALIVE_LED_DPORT=0xFFC00730 | ||
228 | CONFIG_BFIN_IDLE_LED_PORT=0xFFC00700 | ||
229 | CONFIG_BFIN_IDLE_LED_DPORT=0xFFC00730 | ||
230 | 224 | ||
231 | # | 225 | # |
232 | # Blackfin Kernel Optimizations | 226 | # Blackfin Kernel Optimizations |
@@ -279,6 +273,7 @@ CONFIG_BFIN_DCACHE=y | |||
279 | # CONFIG_BFIN_WB is not set | 273 | # CONFIG_BFIN_WB is not set |
280 | CONFIG_BFIN_WT=y | 274 | CONFIG_BFIN_WT=y |
281 | CONFIG_L1_MAX_PIECE=16 | 275 | CONFIG_L1_MAX_PIECE=16 |
276 | # CONFIG_MPU is not set | ||
282 | 277 | ||
283 | # | 278 | # |
284 | # Asynchonous Memory Configuration | 279 | # Asynchonous Memory Configuration |
@@ -333,7 +328,7 @@ CONFIG_PM=y | |||
333 | CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y | 328 | CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y |
334 | # CONFIG_PM_WAKEUP_BY_GPIO is not set | 329 | # CONFIG_PM_WAKEUP_BY_GPIO is not set |
335 | # CONFIG_PM_WAKEUP_GPIO_API is not set | 330 | # CONFIG_PM_WAKEUP_GPIO_API is not set |
336 | CONFIG_PM_WAKEUP_SIC_IWR=0x100000 | 331 | CONFIG_PM_WAKEUP_SIC_IWR=0x80 |
337 | 332 | ||
338 | # | 333 | # |
339 | # CPU Frequency scaling | 334 | # CPU Frequency scaling |
@@ -522,7 +517,6 @@ CONFIG_MTD_CFI_I2=y | |||
522 | # CONFIG_MTD_CFI_INTELEXT is not set | 517 | # CONFIG_MTD_CFI_INTELEXT is not set |
523 | # CONFIG_MTD_CFI_AMDSTD is not set | 518 | # CONFIG_MTD_CFI_AMDSTD is not set |
524 | # CONFIG_MTD_CFI_STAA is not set | 519 | # CONFIG_MTD_CFI_STAA is not set |
525 | CONFIG_MTD_MW320D=m | ||
526 | CONFIG_MTD_RAM=y | 520 | CONFIG_MTD_RAM=y |
527 | CONFIG_MTD_ROM=m | 521 | CONFIG_MTD_ROM=m |
528 | # CONFIG_MTD_ABSENT is not set | 522 | # CONFIG_MTD_ABSENT is not set |
@@ -532,17 +526,6 @@ CONFIG_MTD_ROM=m | |||
532 | # | 526 | # |
533 | CONFIG_MTD_COMPLEX_MAPPINGS=y | 527 | CONFIG_MTD_COMPLEX_MAPPINGS=y |
534 | # CONFIG_MTD_PHYSMAP is not set | 528 | # CONFIG_MTD_PHYSMAP is not set |
535 | CONFIG_MTD_BF5xx=m | ||
536 | CONFIG_BFIN_FLASH_SIZE=0x400000 | ||
537 | CONFIG_EBIU_FLASH_BASE=0x20000000 | ||
538 | |||
539 | # | ||
540 | # FLASH_EBIU_AMBCTL Control | ||
541 | # | ||
542 | CONFIG_BFIN_FLASH_BANK_0=0x7BB0 | ||
543 | CONFIG_BFIN_FLASH_BANK_1=0x7BB0 | ||
544 | CONFIG_BFIN_FLASH_BANK_2=0x7BB0 | ||
545 | CONFIG_BFIN_FLASH_BANK_3=0x7BB0 | ||
546 | # CONFIG_MTD_UCLINUX is not set | 529 | # CONFIG_MTD_UCLINUX is not set |
547 | # CONFIG_MTD_PLATRAM is not set | 530 | # CONFIG_MTD_PLATRAM is not set |
548 | 531 | ||
@@ -630,8 +613,8 @@ CONFIG_SMC91X=y | |||
630 | # CONFIG_SMSC911X is not set | 613 | # CONFIG_SMSC911X is not set |
631 | # CONFIG_DM9000 is not set | 614 | # CONFIG_DM9000 is not set |
632 | CONFIG_NETDEV_1000=y | 615 | CONFIG_NETDEV_1000=y |
633 | CONFIG_NETDEV_10000=y | ||
634 | # CONFIG_AX88180 is not set | 616 | # CONFIG_AX88180 is not set |
617 | CONFIG_NETDEV_10000=y | ||
635 | 618 | ||
636 | # | 619 | # |
637 | # Wireless LAN | 620 | # Wireless LAN |
@@ -687,7 +670,6 @@ CONFIG_INPUT_MISC=y | |||
687 | # CONFIG_INPUT_POWERMATE is not set | 670 | # CONFIG_INPUT_POWERMATE is not set |
688 | # CONFIG_INPUT_YEALINK is not set | 671 | # CONFIG_INPUT_YEALINK is not set |
689 | # CONFIG_INPUT_UINPUT is not set | 672 | # CONFIG_INPUT_UINPUT is not set |
690 | # CONFIG_BF53X_PFBUTTONS is not set | ||
691 | CONFIG_TWI_KEYPAD=m | 673 | CONFIG_TWI_KEYPAD=m |
692 | CONFIG_BFIN_TWIKEYPAD_IRQ_PFX=39 | 674 | CONFIG_BFIN_TWIKEYPAD_IRQ_PFX=39 |
693 | 675 | ||
@@ -711,8 +693,6 @@ CONFIG_BFIN_SPORT=y | |||
711 | CONFIG_TWI_LCD=m | 693 | CONFIG_TWI_LCD=m |
712 | CONFIG_TWI_LCD_SLAVE_ADDR=34 | 694 | CONFIG_TWI_LCD_SLAVE_ADDR=34 |
713 | # CONFIG_AD5304 is not set | 695 | # CONFIG_AD5304 is not set |
714 | # CONFIG_BF5xx_TEA5764 is not set | ||
715 | # CONFIG_BF5xx_FBDMA is not set | ||
716 | # CONFIG_VT is not set | 696 | # CONFIG_VT is not set |
717 | # CONFIG_SERIAL_NONSTANDARD is not set | 697 | # CONFIG_SERIAL_NONSTANDARD is not set |
718 | 698 | ||
@@ -778,7 +758,6 @@ CONFIG_I2C_ALGOBIT=m | |||
778 | # | 758 | # |
779 | # I2C Hardware Bus support | 759 | # I2C Hardware Bus support |
780 | # | 760 | # |
781 | # CONFIG_I2C_BLACKFIN_GPIO is not set | ||
782 | # CONFIG_I2C_GPIO is not set | 761 | # CONFIG_I2C_GPIO is not set |
783 | # CONFIG_I2C_OCORES is not set | 762 | # CONFIG_I2C_OCORES is not set |
784 | # CONFIG_I2C_PARPORT_LIGHT is not set | 763 | # CONFIG_I2C_PARPORT_LIGHT is not set |
diff --git a/arch/blackfin/configs/BF537-STAMP_defconfig b/arch/blackfin/configs/BF537-STAMP_defconfig index f812b66318b9..b37ccc681e7a 100644 --- a/arch/blackfin/configs/BF537-STAMP_defconfig +++ b/arch/blackfin/configs/BF537-STAMP_defconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.22.12 | 3 | # Linux kernel version: 2.6.22.16 |
4 | # | 4 | # |
5 | # CONFIG_MMU is not set | 5 | # CONFIG_MMU is not set |
6 | # CONFIG_FPU is not set | 6 | # CONFIG_FPU is not set |
@@ -115,7 +115,10 @@ CONFIG_PREEMPT_VOLUNTARY=y | |||
115 | # Processor and Board Settings | 115 | # Processor and Board Settings |
116 | # | 116 | # |
117 | # CONFIG_BF522 is not set | 117 | # CONFIG_BF522 is not set |
118 | # CONFIG_BF523 is not set | ||
119 | # CONFIG_BF524 is not set | ||
118 | # CONFIG_BF525 is not set | 120 | # CONFIG_BF525 is not set |
121 | # CONFIG_BF526 is not set | ||
119 | # CONFIG_BF527 is not set | 122 | # CONFIG_BF527 is not set |
120 | # CONFIG_BF531 is not set | 123 | # CONFIG_BF531 is not set |
121 | # CONFIG_BF532 is not set | 124 | # CONFIG_BF532 is not set |
@@ -170,6 +173,7 @@ CONFIG_IRQ_WATCH=13 | |||
170 | CONFIG_BFIN537_STAMP=y | 173 | CONFIG_BFIN537_STAMP=y |
171 | # CONFIG_BFIN537_BLUETECHNIX_CM is not set | 174 | # CONFIG_BFIN537_BLUETECHNIX_CM is not set |
172 | # CONFIG_PNAV10 is not set | 175 | # CONFIG_PNAV10 is not set |
176 | # CONFIG_CAMSIG_MINOTAUR is not set | ||
173 | # CONFIG_GENERIC_BF537_BOARD is not set | 177 | # CONFIG_GENERIC_BF537_BOARD is not set |
174 | 178 | ||
175 | # | 179 | # |
@@ -201,7 +205,7 @@ CONFIG_CLKIN_HZ=25000000 | |||
201 | # CONFIG_BFIN_KERNEL_CLOCK is not set | 205 | # CONFIG_BFIN_KERNEL_CLOCK is not set |
202 | CONFIG_MAX_VCO_HZ=600000000 | 206 | CONFIG_MAX_VCO_HZ=600000000 |
203 | CONFIG_MIN_VCO_HZ=50000000 | 207 | CONFIG_MIN_VCO_HZ=50000000 |
204 | CONFIG_MAX_SCLK_HZ=133000000 | 208 | CONFIG_MAX_SCLK_HZ=133333333 |
205 | CONFIG_MIN_SCLK_HZ=27000000 | 209 | CONFIG_MIN_SCLK_HZ=27000000 |
206 | 210 | ||
207 | # | 211 | # |
@@ -274,6 +278,7 @@ CONFIG_BFIN_DCACHE=y | |||
274 | # CONFIG_BFIN_WB is not set | 278 | # CONFIG_BFIN_WB is not set |
275 | CONFIG_BFIN_WT=y | 279 | CONFIG_BFIN_WT=y |
276 | CONFIG_L1_MAX_PIECE=16 | 280 | CONFIG_L1_MAX_PIECE=16 |
281 | # CONFIG_MPU is not set | ||
277 | 282 | ||
278 | # | 283 | # |
279 | # Asynchonous Memory Configuration | 284 | # Asynchonous Memory Configuration |
@@ -328,7 +333,7 @@ CONFIG_PM=y | |||
328 | CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y | 333 | CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y |
329 | # CONFIG_PM_WAKEUP_BY_GPIO is not set | 334 | # CONFIG_PM_WAKEUP_BY_GPIO is not set |
330 | # CONFIG_PM_WAKEUP_GPIO_API is not set | 335 | # CONFIG_PM_WAKEUP_GPIO_API is not set |
331 | CONFIG_PM_WAKEUP_SIC_IWR=0x80000000 | 336 | CONFIG_PM_WAKEUP_SIC_IWR=0x8 |
332 | 337 | ||
333 | # | 338 | # |
334 | # CPU Frequency scaling | 339 | # CPU Frequency scaling |
@@ -483,7 +488,7 @@ CONFIG_MTD=y | |||
483 | # CONFIG_MTD_CONCAT is not set | 488 | # CONFIG_MTD_CONCAT is not set |
484 | CONFIG_MTD_PARTITIONS=y | 489 | CONFIG_MTD_PARTITIONS=y |
485 | # CONFIG_MTD_REDBOOT_PARTS is not set | 490 | # CONFIG_MTD_REDBOOT_PARTS is not set |
486 | # CONFIG_MTD_CMDLINE_PARTS is not set | 491 | CONFIG_MTD_CMDLINE_PARTS=y |
487 | 492 | ||
488 | # | 493 | # |
489 | # User Modules And Translation Layers | 494 | # User Modules And Translation Layers |
@@ -500,8 +505,8 @@ CONFIG_MTD_BLOCK=y | |||
500 | # | 505 | # |
501 | # RAM/ROM/Flash chip drivers | 506 | # RAM/ROM/Flash chip drivers |
502 | # | 507 | # |
503 | # CONFIG_MTD_CFI is not set | 508 | CONFIG_MTD_CFI=m |
504 | CONFIG_MTD_JEDECPROBE=m | 509 | # CONFIG_MTD_JEDECPROBE is not set |
505 | CONFIG_MTD_GEN_PROBE=m | 510 | CONFIG_MTD_GEN_PROBE=m |
506 | # CONFIG_MTD_CFI_ADV_OPTIONS is not set | 511 | # CONFIG_MTD_CFI_ADV_OPTIONS is not set |
507 | CONFIG_MTD_MAP_BANK_WIDTH_1=y | 512 | CONFIG_MTD_MAP_BANK_WIDTH_1=y |
@@ -515,9 +520,9 @@ CONFIG_MTD_CFI_I2=y | |||
515 | # CONFIG_MTD_CFI_I4 is not set | 520 | # CONFIG_MTD_CFI_I4 is not set |
516 | # CONFIG_MTD_CFI_I8 is not set | 521 | # CONFIG_MTD_CFI_I8 is not set |
517 | # CONFIG_MTD_CFI_INTELEXT is not set | 522 | # CONFIG_MTD_CFI_INTELEXT is not set |
518 | # CONFIG_MTD_CFI_AMDSTD is not set | 523 | CONFIG_MTD_CFI_AMDSTD=m |
519 | # CONFIG_MTD_CFI_STAA is not set | 524 | # CONFIG_MTD_CFI_STAA is not set |
520 | CONFIG_MTD_MW320D=m | 525 | CONFIG_MTD_CFI_UTIL=m |
521 | CONFIG_MTD_RAM=y | 526 | CONFIG_MTD_RAM=y |
522 | CONFIG_MTD_ROM=m | 527 | CONFIG_MTD_ROM=m |
523 | # CONFIG_MTD_ABSENT is not set | 528 | # CONFIG_MTD_ABSENT is not set |
@@ -525,11 +530,11 @@ CONFIG_MTD_ROM=m | |||
525 | # | 530 | # |
526 | # Mapping drivers for chip access | 531 | # Mapping drivers for chip access |
527 | # | 532 | # |
528 | CONFIG_MTD_COMPLEX_MAPPINGS=y | 533 | # CONFIG_MTD_COMPLEX_MAPPINGS is not set |
529 | # CONFIG_MTD_PHYSMAP is not set | 534 | CONFIG_MTD_PHYSMAP=m |
530 | CONFIG_MTD_BF5xx=m | 535 | CONFIG_MTD_PHYSMAP_START=0x20000000 |
531 | CONFIG_BFIN_FLASH_SIZE=0x400000 | 536 | CONFIG_MTD_PHYSMAP_LEN=0x0 |
532 | CONFIG_EBIU_FLASH_BASE=0x20000000 | 537 | CONFIG_MTD_PHYSMAP_BANKWIDTH=2 |
533 | # CONFIG_MTD_UCLINUX is not set | 538 | # CONFIG_MTD_UCLINUX is not set |
534 | # CONFIG_MTD_PLATRAM is not set | 539 | # CONFIG_MTD_PLATRAM is not set |
535 | 540 | ||
@@ -647,8 +652,8 @@ CONFIG_BFIN_RX_DESC_NUM=20 | |||
647 | # CONFIG_SMSC911X is not set | 652 | # CONFIG_SMSC911X is not set |
648 | # CONFIG_DM9000 is not set | 653 | # CONFIG_DM9000 is not set |
649 | CONFIG_NETDEV_1000=y | 654 | CONFIG_NETDEV_1000=y |
650 | CONFIG_NETDEV_10000=y | ||
651 | # CONFIG_AX88180 is not set | 655 | # CONFIG_AX88180 is not set |
656 | CONFIG_NETDEV_10000=y | ||
652 | 657 | ||
653 | # | 658 | # |
654 | # Wireless LAN | 659 | # Wireless LAN |
@@ -704,7 +709,6 @@ CONFIG_INPUT_MISC=y | |||
704 | # CONFIG_INPUT_POWERMATE is not set | 709 | # CONFIG_INPUT_POWERMATE is not set |
705 | # CONFIG_INPUT_YEALINK is not set | 710 | # CONFIG_INPUT_YEALINK is not set |
706 | # CONFIG_INPUT_UINPUT is not set | 711 | # CONFIG_INPUT_UINPUT is not set |
707 | # CONFIG_BF53X_PFBUTTONS is not set | ||
708 | CONFIG_TWI_KEYPAD=m | 712 | CONFIG_TWI_KEYPAD=m |
709 | CONFIG_BFIN_TWIKEYPAD_IRQ_PFX=72 | 713 | CONFIG_BFIN_TWIKEYPAD_IRQ_PFX=72 |
710 | 714 | ||
@@ -728,8 +732,6 @@ CONFIG_BFIN_SPORT=y | |||
728 | CONFIG_TWI_LCD=m | 732 | CONFIG_TWI_LCD=m |
729 | CONFIG_TWI_LCD_SLAVE_ADDR=34 | 733 | CONFIG_TWI_LCD_SLAVE_ADDR=34 |
730 | # CONFIG_AD5304 is not set | 734 | # CONFIG_AD5304 is not set |
731 | # CONFIG_BF5xx_TEA5764 is not set | ||
732 | # CONFIG_BF5xx_FBDMA is not set | ||
733 | # CONFIG_VT is not set | 735 | # CONFIG_VT is not set |
734 | # CONFIG_SERIAL_NONSTANDARD is not set | 736 | # CONFIG_SERIAL_NONSTANDARD is not set |
735 | 737 | ||
@@ -802,7 +804,6 @@ CONFIG_I2C_CHARDEV=m | |||
802 | # | 804 | # |
803 | # I2C Hardware Bus support | 805 | # I2C Hardware Bus support |
804 | # | 806 | # |
805 | # CONFIG_I2C_BLACKFIN_GPIO is not set | ||
806 | CONFIG_I2C_BLACKFIN_TWI=m | 807 | CONFIG_I2C_BLACKFIN_TWI=m |
807 | CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50 | 808 | CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50 |
808 | # CONFIG_I2C_GPIO is not set | 809 | # CONFIG_I2C_GPIO is not set |
@@ -957,6 +958,7 @@ CONFIG_LQ035_SLAVE_ADDR=0x58 | |||
957 | # CONFIG_FB_BFIN_LANDSCAPE is not set | 958 | # CONFIG_FB_BFIN_LANDSCAPE is not set |
958 | # CONFIG_FB_BFIN_BGR is not set | 959 | # CONFIG_FB_BFIN_BGR is not set |
959 | # CONFIG_FB_BFIN_T350MCQB is not set | 960 | # CONFIG_FB_BFIN_T350MCQB is not set |
961 | # CONFIG_FB_HITACHI_TX09 is not set | ||
960 | # CONFIG_FB_S1D13XXX is not set | 962 | # CONFIG_FB_S1D13XXX is not set |
961 | # CONFIG_FB_VIRTUAL is not set | 963 | # CONFIG_FB_VIRTUAL is not set |
962 | # CONFIG_LOGO is not set | 964 | # CONFIG_LOGO is not set |
@@ -1008,12 +1010,22 @@ CONFIG_SND_BFIN_AD73311_SE=4 | |||
1008 | # | 1010 | # |
1009 | # System on Chip audio support | 1011 | # System on Chip audio support |
1010 | # | 1012 | # |
1011 | # CONFIG_SND_SOC is not set | 1013 | CONFIG_SND_SOC_AC97_BUS=y |
1014 | CONFIG_SND_SOC=m | ||
1015 | CONFIG_SND_BF5XX_SOC=m | ||
1016 | CONFIG_SND_BF5XX_SOC_AC97=m | ||
1017 | # CONFIG_SND_BF5XX_SOC_WM8750 is not set | ||
1018 | # CONFIG_SND_BF5XX_SOC_WM8731 is not set | ||
1019 | CONFIG_SND_BF5XX_SOC_BF5xx=m | ||
1020 | CONFIG_SND_BF5XX_SPORT_NUM=0 | ||
1021 | # CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set | ||
1022 | CONFIG_SND_SOC_AD1980=m | ||
1012 | 1023 | ||
1013 | # | 1024 | # |
1014 | # Open Sound System | 1025 | # Open Sound System |
1015 | # | 1026 | # |
1016 | # CONFIG_SOUND_PRIME is not set | 1027 | # CONFIG_SOUND_PRIME is not set |
1028 | CONFIG_AC97_BUS=m | ||
1017 | 1029 | ||
1018 | # | 1030 | # |
1019 | # HID Devices | 1031 | # HID Devices |
diff --git a/arch/blackfin/configs/BF548-EZKIT_defconfig b/arch/blackfin/configs/BF548-EZKIT_defconfig index 48367cc9fe35..fd702161ef59 100644 --- a/arch/blackfin/configs/BF548-EZKIT_defconfig +++ b/arch/blackfin/configs/BF548-EZKIT_defconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.22.12 | 3 | # Linux kernel version: 2.6.22.16 |
4 | # | 4 | # |
5 | # CONFIG_MMU is not set | 5 | # CONFIG_MMU is not set |
6 | # CONFIG_FPU is not set | 6 | # CONFIG_FPU is not set |
@@ -115,7 +115,10 @@ CONFIG_PREEMPT_VOLUNTARY=y | |||
115 | # Processor and Board Settings | 115 | # Processor and Board Settings |
116 | # | 116 | # |
117 | # CONFIG_BF522 is not set | 117 | # CONFIG_BF522 is not set |
118 | # CONFIG_BF523 is not set | ||
119 | # CONFIG_BF524 is not set | ||
118 | # CONFIG_BF525 is not set | 120 | # CONFIG_BF525 is not set |
121 | # CONFIG_BF526 is not set | ||
119 | # CONFIG_BF527 is not set | 122 | # CONFIG_BF527 is not set |
120 | # CONFIG_BF531 is not set | 123 | # CONFIG_BF531 is not set |
121 | # CONFIG_BF532 is not set | 124 | # CONFIG_BF532 is not set |
@@ -126,8 +129,8 @@ CONFIG_PREEMPT_VOLUNTARY=y | |||
126 | # CONFIG_BF542 is not set | 129 | # CONFIG_BF542 is not set |
127 | # CONFIG_BF544 is not set | 130 | # CONFIG_BF544 is not set |
128 | # CONFIG_BF547 is not set | 131 | # CONFIG_BF547 is not set |
129 | # CONFIG_BF548 is not set | 132 | CONFIG_BF548=y |
130 | CONFIG_BF549=y | 133 | # CONFIG_BF549 is not set |
131 | # CONFIG_BF561 is not set | 134 | # CONFIG_BF561 is not set |
132 | CONFIG_BF_REV_0_0=y | 135 | CONFIG_BF_REV_0_0=y |
133 | # CONFIG_BF_REV_0_1 is not set | 136 | # CONFIG_BF_REV_0_1 is not set |
@@ -265,9 +268,9 @@ CONFIG_PINT3_ASSIGN=0x02020303 | |||
265 | # | 268 | # |
266 | CONFIG_CLKIN_HZ=25000000 | 269 | CONFIG_CLKIN_HZ=25000000 |
267 | # CONFIG_BFIN_KERNEL_CLOCK is not set | 270 | # CONFIG_BFIN_KERNEL_CLOCK is not set |
268 | CONFIG_MAX_VCO_HZ=533000000 | 271 | CONFIG_MAX_VCO_HZ=600000000 |
269 | CONFIG_MIN_VCO_HZ=50000000 | 272 | CONFIG_MIN_VCO_HZ=50000000 |
270 | CONFIG_MAX_SCLK_HZ=133000000 | 273 | CONFIG_MAX_SCLK_HZ=133333333 |
271 | CONFIG_MIN_SCLK_HZ=27000000 | 274 | CONFIG_MIN_SCLK_HZ=27000000 |
272 | 275 | ||
273 | # | 276 | # |
@@ -283,7 +286,8 @@ CONFIG_HZ=250 | |||
283 | # Memory Setup | 286 | # Memory Setup |
284 | # | 287 | # |
285 | CONFIG_MEM_SIZE=64 | 288 | CONFIG_MEM_SIZE=64 |
286 | CONFIG_MEM_ADD_WIDTH=10 | 289 | # CONFIG_MEM_MT46V32M16_6T is not set |
290 | CONFIG_MEM_MT46V32M16_5B=y | ||
287 | CONFIG_BOOT_LOAD=0x1000 | 291 | CONFIG_BOOT_LOAD=0x1000 |
288 | CONFIG_BFIN_SCRATCH_REG_RETN=y | 292 | CONFIG_BFIN_SCRATCH_REG_RETN=y |
289 | # CONFIG_BFIN_SCRATCH_REG_RETE is not set | 293 | # CONFIG_BFIN_SCRATCH_REG_RETE is not set |
@@ -340,6 +344,7 @@ CONFIG_BFIN_DCACHE=y | |||
340 | # CONFIG_BFIN_WB is not set | 344 | # CONFIG_BFIN_WB is not set |
341 | CONFIG_BFIN_WT=y | 345 | CONFIG_BFIN_WT=y |
342 | CONFIG_L1_MAX_PIECE=16 | 346 | CONFIG_L1_MAX_PIECE=16 |
347 | # CONFIG_MPU is not set | ||
343 | 348 | ||
344 | # | 349 | # |
345 | # Asynchonous Memory Configuration | 350 | # Asynchonous Memory Configuration |
@@ -349,6 +354,7 @@ CONFIG_L1_MAX_PIECE=16 | |||
349 | # EBIU_AMGCTL Global Control | 354 | # EBIU_AMGCTL Global Control |
350 | # | 355 | # |
351 | CONFIG_C_AMCKEN=y | 356 | CONFIG_C_AMCKEN=y |
357 | # CONFIG_C_CDPRIO is not set | ||
352 | # CONFIG_C_AMBEN is not set | 358 | # CONFIG_C_AMBEN is not set |
353 | # CONFIG_C_AMBEN_B0 is not set | 359 | # CONFIG_C_AMBEN_B0 is not set |
354 | # CONFIG_C_AMBEN_B0_B1 is not set | 360 | # CONFIG_C_AMBEN_B0_B1 is not set |
@@ -362,9 +368,9 @@ CONFIG_BANK_0=0x7BB0 | |||
362 | CONFIG_BANK_1=0x5554 | 368 | CONFIG_BANK_1=0x5554 |
363 | CONFIG_BANK_2=0x7BB0 | 369 | CONFIG_BANK_2=0x7BB0 |
364 | CONFIG_BANK_3=0x99B3 | 370 | CONFIG_BANK_3=0x99B3 |
365 | CONFIG_EBUI_MBSCTLVAL=0x0 | 371 | CONFIG_EBIU_MBSCTLVAL=0x0 |
366 | CONFIG_EBUI_MODEVAL=0x1 | 372 | CONFIG_EBIU_MODEVAL=0x1 |
367 | CONFIG_EBUI_FCTLVAL=0x6 | 373 | CONFIG_EBIU_FCTLVAL=0x6 |
368 | 374 | ||
369 | # | 375 | # |
370 | # Bus options (PCI, PCMCIA, EISA, MCA, ISA) | 376 | # Bus options (PCI, PCMCIA, EISA, MCA, ISA) |
@@ -537,7 +543,6 @@ CONFIG_MTD_CFI_I2=y | |||
537 | CONFIG_MTD_CFI_INTELEXT=y | 543 | CONFIG_MTD_CFI_INTELEXT=y |
538 | # CONFIG_MTD_CFI_AMDSTD is not set | 544 | # CONFIG_MTD_CFI_AMDSTD is not set |
539 | # CONFIG_MTD_CFI_STAA is not set | 545 | # CONFIG_MTD_CFI_STAA is not set |
540 | # CONFIG_MTD_MW320D is not set | ||
541 | CONFIG_MTD_CFI_UTIL=y | 546 | CONFIG_MTD_CFI_UTIL=y |
542 | CONFIG_MTD_RAM=y | 547 | CONFIG_MTD_RAM=y |
543 | # CONFIG_MTD_ROM is not set | 548 | # CONFIG_MTD_ROM is not set |
@@ -549,9 +554,8 @@ CONFIG_MTD_RAM=y | |||
549 | CONFIG_MTD_COMPLEX_MAPPINGS=y | 554 | CONFIG_MTD_COMPLEX_MAPPINGS=y |
550 | CONFIG_MTD_PHYSMAP=y | 555 | CONFIG_MTD_PHYSMAP=y |
551 | CONFIG_MTD_PHYSMAP_START=0x20000000 | 556 | CONFIG_MTD_PHYSMAP_START=0x20000000 |
552 | CONFIG_MTD_PHYSMAP_LEN=0x400000 | 557 | CONFIG_MTD_PHYSMAP_LEN=0 |
553 | CONFIG_MTD_PHYSMAP_BANKWIDTH=2 | 558 | CONFIG_MTD_PHYSMAP_BANKWIDTH=2 |
554 | # CONFIG_MTD_BF5xx is not set | ||
555 | # CONFIG_MTD_UCLINUX is not set | 559 | # CONFIG_MTD_UCLINUX is not set |
556 | # CONFIG_MTD_PLATRAM is not set | 560 | # CONFIG_MTD_PLATRAM is not set |
557 | 561 | ||
@@ -690,8 +694,8 @@ CONFIG_MII=y | |||
690 | CONFIG_SMSC911X=y | 694 | CONFIG_SMSC911X=y |
691 | # CONFIG_DM9000 is not set | 695 | # CONFIG_DM9000 is not set |
692 | CONFIG_NETDEV_1000=y | 696 | CONFIG_NETDEV_1000=y |
693 | CONFIG_NETDEV_10000=y | ||
694 | # CONFIG_AX88180 is not set | 697 | # CONFIG_AX88180 is not set |
698 | CONFIG_NETDEV_10000=y | ||
695 | 699 | ||
696 | # | 700 | # |
697 | # Wireless LAN | 701 | # Wireless LAN |
@@ -719,7 +723,7 @@ CONFIG_NETDEV_10000=y | |||
719 | # | 723 | # |
720 | # Input device support | 724 | # Input device support |
721 | # | 725 | # |
722 | CONFIG_INPUT=m | 726 | CONFIG_INPUT=y |
723 | # CONFIG_INPUT_FF_MEMLESS is not set | 727 | # CONFIG_INPUT_FF_MEMLESS is not set |
724 | # CONFIG_INPUT_POLLDEV is not set | 728 | # CONFIG_INPUT_POLLDEV is not set |
725 | 729 | ||
@@ -745,7 +749,8 @@ CONFIG_INPUT_KEYBOARD=y | |||
745 | # CONFIG_KEYBOARD_NEWTON is not set | 749 | # CONFIG_KEYBOARD_NEWTON is not set |
746 | # CONFIG_KEYBOARD_STOWAWAY is not set | 750 | # CONFIG_KEYBOARD_STOWAWAY is not set |
747 | # CONFIG_KEYBOARD_GPIO is not set | 751 | # CONFIG_KEYBOARD_GPIO is not set |
748 | CONFIG_KEYBOARD_BFIN=m | 752 | CONFIG_KEYBOARD_BFIN=y |
753 | # CONFIG_KEYBOARD_OPENCORES is not set | ||
749 | # CONFIG_INPUT_MOUSE is not set | 754 | # CONFIG_INPUT_MOUSE is not set |
750 | # CONFIG_INPUT_JOYSTICK is not set | 755 | # CONFIG_INPUT_JOYSTICK is not set |
751 | # CONFIG_INPUT_TABLET is not set | 756 | # CONFIG_INPUT_TABLET is not set |
@@ -768,7 +773,6 @@ CONFIG_INPUT_MISC=y | |||
768 | # CONFIG_INPUT_POWERMATE is not set | 773 | # CONFIG_INPUT_POWERMATE is not set |
769 | # CONFIG_INPUT_YEALINK is not set | 774 | # CONFIG_INPUT_YEALINK is not set |
770 | # CONFIG_INPUT_UINPUT is not set | 775 | # CONFIG_INPUT_UINPUT is not set |
771 | # CONFIG_BF53X_PFBUTTONS is not set | ||
772 | # CONFIG_TWI_KEYPAD is not set | 776 | # CONFIG_TWI_KEYPAD is not set |
773 | 777 | ||
774 | # | 778 | # |
@@ -786,13 +790,16 @@ CONFIG_INPUT_MISC=y | |||
786 | # CONFIG_BF5xx_PPIFCD is not set | 790 | # CONFIG_BF5xx_PPIFCD is not set |
787 | # CONFIG_BFIN_SIMPLE_TIMER is not set | 791 | # CONFIG_BFIN_SIMPLE_TIMER is not set |
788 | # CONFIG_BF5xx_PPI is not set | 792 | # CONFIG_BF5xx_PPI is not set |
793 | CONFIG_BFIN_OTP=y | ||
794 | # CONFIG_BFIN_OTP_WRITE_ENABLE is not set | ||
789 | # CONFIG_BFIN_SPORT is not set | 795 | # CONFIG_BFIN_SPORT is not set |
790 | # CONFIG_BFIN_TIMER_LATENCY is not set | 796 | # CONFIG_BFIN_TIMER_LATENCY is not set |
791 | # CONFIG_TWI_LCD is not set | 797 | # CONFIG_TWI_LCD is not set |
792 | # CONFIG_AD5304 is not set | 798 | # CONFIG_AD5304 is not set |
793 | # CONFIG_BF5xx_TEA5764 is not set | 799 | CONFIG_VT=y |
794 | # CONFIG_BF5xx_FBDMA is not set | 800 | CONFIG_VT_CONSOLE=y |
795 | # CONFIG_VT is not set | 801 | CONFIG_HW_CONSOLE=y |
802 | # CONFIG_VT_HW_CONSOLE_BINDING is not set | ||
796 | # CONFIG_SERIAL_NONSTANDARD is not set | 803 | # CONFIG_SERIAL_NONSTANDARD is not set |
797 | 804 | ||
798 | # | 805 | # |
@@ -858,7 +865,6 @@ CONFIG_I2C_CHARDEV=y | |||
858 | # | 865 | # |
859 | # I2C Hardware Bus support | 866 | # I2C Hardware Bus support |
860 | # | 867 | # |
861 | # CONFIG_I2C_BLACKFIN_GPIO is not set | ||
862 | CONFIG_I2C_BLACKFIN_TWI=y | 868 | CONFIG_I2C_BLACKFIN_TWI=y |
863 | CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50 | 869 | CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50 |
864 | # CONFIG_I2C_GPIO is not set | 870 | # CONFIG_I2C_GPIO is not set |
@@ -976,12 +982,12 @@ CONFIG_DAB=y | |||
976 | # | 982 | # |
977 | # CONFIG_DISPLAY_SUPPORT is not set | 983 | # CONFIG_DISPLAY_SUPPORT is not set |
978 | # CONFIG_VGASTATE is not set | 984 | # CONFIG_VGASTATE is not set |
979 | CONFIG_FB=m | 985 | CONFIG_FB=y |
980 | CONFIG_FIRMWARE_EDID=y | 986 | CONFIG_FIRMWARE_EDID=y |
981 | # CONFIG_FB_DDC is not set | 987 | # CONFIG_FB_DDC is not set |
982 | CONFIG_FB_CFB_FILLRECT=m | 988 | CONFIG_FB_CFB_FILLRECT=y |
983 | CONFIG_FB_CFB_COPYAREA=m | 989 | CONFIG_FB_CFB_COPYAREA=y |
984 | CONFIG_FB_CFB_IMAGEBLIT=m | 990 | CONFIG_FB_CFB_IMAGEBLIT=y |
985 | # CONFIG_FB_SYS_FILLRECT is not set | 991 | # CONFIG_FB_SYS_FILLRECT is not set |
986 | # CONFIG_FB_SYS_COPYAREA is not set | 992 | # CONFIG_FB_SYS_COPYAREA is not set |
987 | # CONFIG_FB_SYS_IMAGEBLIT is not set | 993 | # CONFIG_FB_SYS_IMAGEBLIT is not set |
@@ -998,11 +1004,34 @@ CONFIG_FB_DEFERRED_IO=y | |||
998 | # | 1004 | # |
999 | # CONFIG_FB_BFIN_7171 is not set | 1005 | # CONFIG_FB_BFIN_7171 is not set |
1000 | # CONFIG_FB_BFIN_7393 is not set | 1006 | # CONFIG_FB_BFIN_7393 is not set |
1001 | CONFIG_FB_BF54X_LQ043=m | 1007 | CONFIG_FB_BF54X_LQ043=y |
1002 | # CONFIG_FB_BFIN_T350MCQB is not set | 1008 | # CONFIG_FB_BFIN_T350MCQB is not set |
1003 | # CONFIG_FB_S1D13XXX is not set | 1009 | # CONFIG_FB_S1D13XXX is not set |
1004 | # CONFIG_FB_VIRTUAL is not set | 1010 | # CONFIG_FB_VIRTUAL is not set |
1005 | # CONFIG_LOGO is not set | 1011 | |
1012 | # | ||
1013 | # Console display driver support | ||
1014 | # | ||
1015 | CONFIG_DUMMY_CONSOLE=y | ||
1016 | CONFIG_FRAMEBUFFER_CONSOLE=y | ||
1017 | # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set | ||
1018 | CONFIG_FONTS=y | ||
1019 | # CONFIG_FONT_8x8 is not set | ||
1020 | # CONFIG_FONT_8x16 is not set | ||
1021 | CONFIG_FONT_6x11=y | ||
1022 | # CONFIG_FONT_7x14 is not set | ||
1023 | # CONFIG_FONT_PEARL_8x8 is not set | ||
1024 | # CONFIG_FONT_ACORN_8x8 is not set | ||
1025 | # CONFIG_FONT_MINI_4x6 is not set | ||
1026 | # CONFIG_FONT_SUN8x16 is not set | ||
1027 | # CONFIG_FONT_SUN12x22 is not set | ||
1028 | # CONFIG_FONT_10x18 is not set | ||
1029 | CONFIG_LOGO=y | ||
1030 | # CONFIG_LOGO_LINUX_MONO is not set | ||
1031 | # CONFIG_LOGO_LINUX_VGA16 is not set | ||
1032 | # CONFIG_LOGO_LINUX_CLUT224 is not set | ||
1033 | # CONFIG_LOGO_BLACKFIN_VGA16 is not set | ||
1034 | CONFIG_LOGO_BLACKFIN_CLUT224=y | ||
1006 | 1035 | ||
1007 | # | 1036 | # |
1008 | # Sound | 1037 | # Sound |
@@ -1051,7 +1080,8 @@ CONFIG_SND_BF5XX_SOC_BF548_EZKIT=y | |||
1051 | # CONFIG_SND_BF5XX_SOC_WM8750 is not set | 1080 | # CONFIG_SND_BF5XX_SOC_WM8750 is not set |
1052 | # CONFIG_SND_BF5XX_SOC_WM8731 is not set | 1081 | # CONFIG_SND_BF5XX_SOC_WM8731 is not set |
1053 | CONFIG_SND_BF5XX_SPORT_NUM=0 | 1082 | CONFIG_SND_BF5XX_SPORT_NUM=0 |
1054 | # CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set | 1083 | CONFIG_SND_BF5XX_HAVE_COLD_RESET=y |
1084 | CONFIG_SND_BF5XX_RESET_GPIO_NUM=19 | ||
1055 | CONFIG_SND_SOC_AD1980=y | 1085 | CONFIG_SND_SOC_AD1980=y |
1056 | 1086 | ||
1057 | # | 1087 | # |
@@ -1403,7 +1433,7 @@ CONFIG_NLS_UTF8=m | |||
1403 | # | 1433 | # |
1404 | # CONFIG_PRINTK_TIME is not set | 1434 | # CONFIG_PRINTK_TIME is not set |
1405 | CONFIG_ENABLE_MUST_CHECK=y | 1435 | CONFIG_ENABLE_MUST_CHECK=y |
1406 | CONFIG_MAGIC_SYSRQ=y | 1436 | # CONFIG_MAGIC_SYSRQ is not set |
1407 | # CONFIG_UNUSED_SYMBOLS is not set | 1437 | # CONFIG_UNUSED_SYMBOLS is not set |
1408 | CONFIG_DEBUG_FS=y | 1438 | CONFIG_DEBUG_FS=y |
1409 | # CONFIG_HEADERS_CHECK is not set | 1439 | # CONFIG_HEADERS_CHECK is not set |
@@ -1428,7 +1458,7 @@ CONFIG_ACCESS_CHECK=y | |||
1428 | # CONFIG_KEYS is not set | 1458 | # CONFIG_KEYS is not set |
1429 | CONFIG_SECURITY=y | 1459 | CONFIG_SECURITY=y |
1430 | # CONFIG_SECURITY_NETWORK is not set | 1460 | # CONFIG_SECURITY_NETWORK is not set |
1431 | CONFIG_SECURITY_CAPABILITIES=y | 1461 | CONFIG_SECURITY_CAPABILITIES=m |
1432 | 1462 | ||
1433 | # | 1463 | # |
1434 | # Cryptographic options | 1464 | # Cryptographic options |
@@ -1439,7 +1469,7 @@ CONFIG_SECURITY_CAPABILITIES=y | |||
1439 | # Library routines | 1469 | # Library routines |
1440 | # | 1470 | # |
1441 | CONFIG_BITREVERSE=y | 1471 | CONFIG_BITREVERSE=y |
1442 | # CONFIG_CRC_CCITT is not set | 1472 | CONFIG_CRC_CCITT=m |
1443 | # CONFIG_CRC16 is not set | 1473 | # CONFIG_CRC16 is not set |
1444 | # CONFIG_CRC_ITU_T is not set | 1474 | # CONFIG_CRC_ITU_T is not set |
1445 | CONFIG_CRC32=y | 1475 | CONFIG_CRC32=y |
diff --git a/arch/blackfin/configs/BF561-EZKIT_defconfig b/arch/blackfin/configs/BF561-EZKIT_defconfig index e9f100b45eb1..8546994939fb 100644 --- a/arch/blackfin/configs/BF561-EZKIT_defconfig +++ b/arch/blackfin/configs/BF561-EZKIT_defconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.22.12 | 3 | # Linux kernel version: 2.6.22.16 |
4 | # | 4 | # |
5 | # CONFIG_MMU is not set | 5 | # CONFIG_MMU is not set |
6 | # CONFIG_FPU is not set | 6 | # CONFIG_FPU is not set |
@@ -115,7 +115,10 @@ CONFIG_PREEMPT_VOLUNTARY=y | |||
115 | # Processor and Board Settings | 115 | # Processor and Board Settings |
116 | # | 116 | # |
117 | # CONFIG_BF522 is not set | 117 | # CONFIG_BF522 is not set |
118 | # CONFIG_BF523 is not set | ||
119 | # CONFIG_BF524 is not set | ||
118 | # CONFIG_BF525 is not set | 120 | # CONFIG_BF525 is not set |
121 | # CONFIG_BF526 is not set | ||
119 | # CONFIG_BF527 is not set | 122 | # CONFIG_BF527 is not set |
120 | # CONFIG_BF531 is not set | 123 | # CONFIG_BF531 is not set |
121 | # CONFIG_BF532 is not set | 124 | # CONFIG_BF532 is not set |
@@ -238,7 +241,7 @@ CONFIG_CLKIN_HZ=30000000 | |||
238 | # CONFIG_BFIN_KERNEL_CLOCK is not set | 241 | # CONFIG_BFIN_KERNEL_CLOCK is not set |
239 | CONFIG_MAX_VCO_HZ=600000000 | 242 | CONFIG_MAX_VCO_HZ=600000000 |
240 | CONFIG_MIN_VCO_HZ=50000000 | 243 | CONFIG_MIN_VCO_HZ=50000000 |
241 | CONFIG_MAX_SCLK_HZ=133000000 | 244 | CONFIG_MAX_SCLK_HZ=133333333 |
242 | CONFIG_MIN_SCLK_HZ=27000000 | 245 | CONFIG_MIN_SCLK_HZ=27000000 |
243 | 246 | ||
244 | # | 247 | # |
@@ -311,6 +314,7 @@ CONFIG_BFIN_DCACHE=y | |||
311 | # CONFIG_BFIN_WB is not set | 314 | # CONFIG_BFIN_WB is not set |
312 | CONFIG_BFIN_WT=y | 315 | CONFIG_BFIN_WT=y |
313 | CONFIG_L1_MAX_PIECE=16 | 316 | CONFIG_L1_MAX_PIECE=16 |
317 | # CONFIG_MPU is not set | ||
314 | 318 | ||
315 | # | 319 | # |
316 | # Asynchonous Memory Configuration | 320 | # Asynchonous Memory Configuration |
@@ -512,7 +516,7 @@ CONFIG_MTD=y | |||
512 | # CONFIG_MTD_CONCAT is not set | 516 | # CONFIG_MTD_CONCAT is not set |
513 | CONFIG_MTD_PARTITIONS=y | 517 | CONFIG_MTD_PARTITIONS=y |
514 | # CONFIG_MTD_REDBOOT_PARTS is not set | 518 | # CONFIG_MTD_REDBOOT_PARTS is not set |
515 | # CONFIG_MTD_CMDLINE_PARTS is not set | 519 | CONFIG_MTD_CMDLINE_PARTS=y |
516 | 520 | ||
517 | # | 521 | # |
518 | # User Modules And Translation Layers | 522 | # User Modules And Translation Layers |
@@ -529,8 +533,8 @@ CONFIG_MTD_BLOCK=y | |||
529 | # | 533 | # |
530 | # RAM/ROM/Flash chip drivers | 534 | # RAM/ROM/Flash chip drivers |
531 | # | 535 | # |
532 | # CONFIG_MTD_CFI is not set | 536 | CONFIG_MTD_CFI=m |
533 | CONFIG_MTD_JEDECPROBE=m | 537 | # CONFIG_MTD_JEDECPROBE is not set |
534 | CONFIG_MTD_GEN_PROBE=m | 538 | CONFIG_MTD_GEN_PROBE=m |
535 | # CONFIG_MTD_CFI_ADV_OPTIONS is not set | 539 | # CONFIG_MTD_CFI_ADV_OPTIONS is not set |
536 | CONFIG_MTD_MAP_BANK_WIDTH_1=y | 540 | CONFIG_MTD_MAP_BANK_WIDTH_1=y |
@@ -544,9 +548,9 @@ CONFIG_MTD_CFI_I2=y | |||
544 | # CONFIG_MTD_CFI_I4 is not set | 548 | # CONFIG_MTD_CFI_I4 is not set |
545 | # CONFIG_MTD_CFI_I8 is not set | 549 | # CONFIG_MTD_CFI_I8 is not set |
546 | # CONFIG_MTD_CFI_INTELEXT is not set | 550 | # CONFIG_MTD_CFI_INTELEXT is not set |
547 | # CONFIG_MTD_CFI_AMDSTD is not set | 551 | CONFIG_MTD_CFI_AMDSTD=m |
548 | # CONFIG_MTD_CFI_STAA is not set | 552 | # CONFIG_MTD_CFI_STAA is not set |
549 | CONFIG_MTD_MW320D=m | 553 | CONFIG_MTD_CFI_UTIL=m |
550 | CONFIG_MTD_RAM=y | 554 | CONFIG_MTD_RAM=y |
551 | CONFIG_MTD_ROM=m | 555 | CONFIG_MTD_ROM=m |
552 | # CONFIG_MTD_ABSENT is not set | 556 | # CONFIG_MTD_ABSENT is not set |
@@ -554,12 +558,11 @@ CONFIG_MTD_ROM=m | |||
554 | # | 558 | # |
555 | # Mapping drivers for chip access | 559 | # Mapping drivers for chip access |
556 | # | 560 | # |
557 | CONFIG_MTD_COMPLEX_MAPPINGS=y | 561 | # CONFIG_MTD_COMPLEX_MAPPINGS is not set |
558 | # CONFIG_MTD_PHYSMAP is not set | 562 | CONFIG_MTD_PHYSMAP=m |
559 | # CONFIG_MTD_EZKIT561 is not set | 563 | CONFIG_MTD_PHYSMAP_START=0x20000000 |
560 | CONFIG_MTD_BF5xx=m | 564 | CONFIG_MTD_PHYSMAP_LEN=0x0 |
561 | CONFIG_BFIN_FLASH_SIZE=0x0400000 | 565 | CONFIG_MTD_PHYSMAP_BANKWIDTH=2 |
562 | CONFIG_EBIU_FLASH_BASE=0x20000000 | ||
563 | # CONFIG_MTD_UCLINUX is not set | 566 | # CONFIG_MTD_UCLINUX is not set |
564 | # CONFIG_MTD_PLATRAM is not set | 567 | # CONFIG_MTD_PLATRAM is not set |
565 | 568 | ||
@@ -647,8 +650,8 @@ CONFIG_SMC91X=y | |||
647 | # CONFIG_SMSC911X is not set | 650 | # CONFIG_SMSC911X is not set |
648 | # CONFIG_DM9000 is not set | 651 | # CONFIG_DM9000 is not set |
649 | CONFIG_NETDEV_1000=y | 652 | CONFIG_NETDEV_1000=y |
650 | CONFIG_NETDEV_10000=y | ||
651 | # CONFIG_AX88180 is not set | 653 | # CONFIG_AX88180 is not set |
654 | CONFIG_NETDEV_10000=y | ||
652 | 655 | ||
653 | # | 656 | # |
654 | # Wireless LAN | 657 | # Wireless LAN |
@@ -717,7 +720,6 @@ CONFIG_INPUT_EVDEV=m | |||
717 | # CONFIG_BFIN_SPORT is not set | 720 | # CONFIG_BFIN_SPORT is not set |
718 | # CONFIG_BFIN_TIMER_LATENCY is not set | 721 | # CONFIG_BFIN_TIMER_LATENCY is not set |
719 | # CONFIG_AD5304 is not set | 722 | # CONFIG_AD5304 is not set |
720 | # CONFIG_BF5xx_FBDMA is not set | ||
721 | # CONFIG_VT is not set | 723 | # CONFIG_VT is not set |
722 | # CONFIG_SERIAL_NONSTANDARD is not set | 724 | # CONFIG_SERIAL_NONSTANDARD is not set |
723 | 725 | ||
diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile index 8a4cfb293b27..318b9b692a48 100644 --- a/arch/blackfin/kernel/Makefile +++ b/arch/blackfin/kernel/Makefile | |||
@@ -7,7 +7,7 @@ extra-y := init_task.o vmlinux.lds | |||
7 | obj-y := \ | 7 | obj-y := \ |
8 | entry.o process.o bfin_ksyms.o ptrace.o setup.o signal.o \ | 8 | entry.o process.o bfin_ksyms.o ptrace.o setup.o signal.o \ |
9 | sys_bfin.o time.o traps.o irqchip.o dma-mapping.o flat.o \ | 9 | sys_bfin.o time.o traps.o irqchip.o dma-mapping.o flat.o \ |
10 | fixed_code.o cplbinit.o cacheinit.o reboot.o bfin_gpio.o | 10 | fixed_code.o reboot.o bfin_gpio.o |
11 | 11 | ||
12 | obj-$(CONFIG_BFIN_GPTIMERS) += gptimers.o | 12 | obj-$(CONFIG_BFIN_GPTIMERS) += gptimers.o |
13 | obj-$(CONFIG_MODULES) += module.o | 13 | obj-$(CONFIG_MODULES) += module.o |
diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c index b54446055a43..fa9debe8d5f4 100644 --- a/arch/blackfin/kernel/bfin_dma_5xx.c +++ b/arch/blackfin/kernel/bfin_dma_5xx.c | |||
@@ -339,13 +339,13 @@ EXPORT_SYMBOL(set_dma_config); | |||
339 | 339 | ||
340 | unsigned short | 340 | unsigned short |
341 | set_bfin_dma_config(char direction, char flow_mode, | 341 | set_bfin_dma_config(char direction, char flow_mode, |
342 | char intr_mode, char dma_mode, char width) | 342 | char intr_mode, char dma_mode, char width, char syncmode) |
343 | { | 343 | { |
344 | unsigned short config; | 344 | unsigned short config; |
345 | 345 | ||
346 | config = | 346 | config = |
347 | ((direction << 1) | (width << 2) | (dma_mode << 4) | | 347 | ((direction << 1) | (width << 2) | (dma_mode << 4) | |
348 | (intr_mode << 6) | (flow_mode << 12) | RESTART); | 348 | (intr_mode << 6) | (flow_mode << 12) | (syncmode << 5)); |
349 | return config; | 349 | return config; |
350 | } | 350 | } |
351 | EXPORT_SYMBOL(set_bfin_dma_config); | 351 | EXPORT_SYMBOL(set_bfin_dma_config); |
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index ce85d4bf34ca..6bbe0a2fccb8 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * Description: GPIO Abstraction Layer | 7 | * Description: GPIO Abstraction Layer |
8 | * | 8 | * |
9 | * Modified: | 9 | * Modified: |
10 | * Copyright 2007 Analog Devices Inc. | 10 | * Copyright 2008 Analog Devices Inc. |
11 | * | 11 | * |
12 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | 12 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ |
13 | * | 13 | * |
@@ -83,6 +83,7 @@ | |||
83 | #include <linux/delay.h> | 83 | #include <linux/delay.h> |
84 | #include <linux/module.h> | 84 | #include <linux/module.h> |
85 | #include <linux/err.h> | 85 | #include <linux/err.h> |
86 | #include <linux/proc_fs.h> | ||
86 | #include <asm/blackfin.h> | 87 | #include <asm/blackfin.h> |
87 | #include <asm/gpio.h> | 88 | #include <asm/gpio.h> |
88 | #include <asm/portmux.h> | 89 | #include <asm/portmux.h> |
@@ -136,7 +137,6 @@ static unsigned short *port_fer[gpio_bank(MAX_BLACKFIN_GPIOS)] = { | |||
136 | (unsigned short *) PORTG_FER, | 137 | (unsigned short *) PORTG_FER, |
137 | (unsigned short *) PORTH_FER, | 138 | (unsigned short *) PORTH_FER, |
138 | }; | 139 | }; |
139 | |||
140 | #endif | 140 | #endif |
141 | 141 | ||
142 | #ifdef BF527_FAMILY | 142 | #ifdef BF527_FAMILY |
@@ -178,15 +178,13 @@ static struct gpio_port_t *gpio_array[gpio_bank(MAX_BLACKFIN_GPIOS)] = { | |||
178 | #endif | 178 | #endif |
179 | 179 | ||
180 | static unsigned short reserved_gpio_map[gpio_bank(MAX_BLACKFIN_GPIOS)]; | 180 | static unsigned short reserved_gpio_map[gpio_bank(MAX_BLACKFIN_GPIOS)]; |
181 | static unsigned short reserved_peri_map[gpio_bank(MAX_BLACKFIN_GPIOS + 16)]; | 181 | static unsigned short reserved_peri_map[gpio_bank(MAX_RESOURCES)]; |
182 | 182 | ||
183 | #define MAX_RESOURCES 256 | ||
184 | #define RESOURCE_LABEL_SIZE 16 | 183 | #define RESOURCE_LABEL_SIZE 16 |
185 | 184 | ||
186 | struct str_ident { | 185 | static struct str_ident { |
187 | char name[RESOURCE_LABEL_SIZE]; | 186 | char name[RESOURCE_LABEL_SIZE]; |
188 | } *str_ident; | 187 | } str_ident[MAX_RESOURCES]; |
189 | |||
190 | 188 | ||
191 | #ifdef CONFIG_PM | 189 | #ifdef CONFIG_PM |
192 | static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)]; | 190 | static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)]; |
@@ -212,7 +210,7 @@ static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG0_INT | |||
212 | #endif /* CONFIG_PM */ | 210 | #endif /* CONFIG_PM */ |
213 | 211 | ||
214 | #if defined(BF548_FAMILY) | 212 | #if defined(BF548_FAMILY) |
215 | inline int check_gpio(unsigned short gpio) | 213 | inline int check_gpio(unsigned gpio) |
216 | { | 214 | { |
217 | if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15 | 215 | if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15 |
218 | || gpio == GPIO_PH14 || gpio == GPIO_PH15 | 216 | || gpio == GPIO_PH14 || gpio == GPIO_PH15 |
@@ -222,7 +220,7 @@ inline int check_gpio(unsigned short gpio) | |||
222 | return 0; | 220 | return 0; |
223 | } | 221 | } |
224 | #else | 222 | #else |
225 | inline int check_gpio(unsigned short gpio) | 223 | inline int check_gpio(unsigned gpio) |
226 | { | 224 | { |
227 | if (gpio >= MAX_BLACKFIN_GPIOS) | 225 | if (gpio >= MAX_BLACKFIN_GPIOS) |
228 | return -EINVAL; | 226 | return -EINVAL; |
@@ -230,9 +228,13 @@ inline int check_gpio(unsigned short gpio) | |||
230 | } | 228 | } |
231 | #endif | 229 | #endif |
232 | 230 | ||
233 | static void set_label(unsigned short ident, const char *label) | 231 | void gpio_error(unsigned gpio) |
234 | { | 232 | { |
233 | printk(KERN_ERR "bfin-gpio: GPIO %d wasn't requested!\n", gpio); | ||
234 | } | ||
235 | 235 | ||
236 | static void set_label(unsigned short ident, const char *label) | ||
237 | { | ||
236 | if (label && str_ident) { | 238 | if (label && str_ident) { |
237 | strncpy(str_ident[ident].name, label, | 239 | strncpy(str_ident[ident].name, label, |
238 | RESOURCE_LABEL_SIZE); | 240 | RESOURCE_LABEL_SIZE); |
@@ -250,6 +252,11 @@ static char *get_label(unsigned short ident) | |||
250 | 252 | ||
251 | static int cmp_label(unsigned short ident, const char *label) | 253 | static int cmp_label(unsigned short ident, const char *label) |
252 | { | 254 | { |
255 | if (label == NULL) { | ||
256 | dump_stack(); | ||
257 | printk(KERN_ERR "Please provide none-null label\n"); | ||
258 | } | ||
259 | |||
253 | if (label && str_ident) | 260 | if (label && str_ident) |
254 | return strncmp(str_ident[ident].name, | 261 | return strncmp(str_ident[ident].name, |
255 | label, strlen(label)); | 262 | label, strlen(label)); |
@@ -258,7 +265,7 @@ static int cmp_label(unsigned short ident, const char *label) | |||
258 | } | 265 | } |
259 | 266 | ||
260 | #if defined(BF527_FAMILY) || defined(BF537_FAMILY) | 267 | #if defined(BF527_FAMILY) || defined(BF537_FAMILY) |
261 | static void port_setup(unsigned short gpio, unsigned short usage) | 268 | static void port_setup(unsigned gpio, unsigned short usage) |
262 | { | 269 | { |
263 | if (!check_gpio(gpio)) { | 270 | if (!check_gpio(gpio)) { |
264 | if (usage == GPIO_USAGE) | 271 | if (usage == GPIO_USAGE) |
@@ -269,7 +276,7 @@ static void port_setup(unsigned short gpio, unsigned short usage) | |||
269 | } | 276 | } |
270 | } | 277 | } |
271 | #elif defined(BF548_FAMILY) | 278 | #elif defined(BF548_FAMILY) |
272 | static void port_setup(unsigned short gpio, unsigned short usage) | 279 | static void port_setup(unsigned gpio, unsigned short usage) |
273 | { | 280 | { |
274 | if (usage == GPIO_USAGE) | 281 | if (usage == GPIO_USAGE) |
275 | gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio); | 282 | gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio); |
@@ -390,7 +397,7 @@ inline void portmux_setup(unsigned short portno, unsigned short function) | |||
390 | #endif | 397 | #endif |
391 | 398 | ||
392 | #ifndef BF548_FAMILY | 399 | #ifndef BF548_FAMILY |
393 | static void default_gpio(unsigned short gpio) | 400 | static void default_gpio(unsigned gpio) |
394 | { | 401 | { |
395 | unsigned short bank, bitmask; | 402 | unsigned short bank, bitmask; |
396 | unsigned long flags; | 403 | unsigned long flags; |
@@ -410,7 +417,6 @@ static void default_gpio(unsigned short gpio) | |||
410 | gpio_bankb[bank]->edge &= ~bitmask; | 417 | gpio_bankb[bank]->edge &= ~bitmask; |
411 | AWA_DUMMY_READ(edge); | 418 | AWA_DUMMY_READ(edge); |
412 | local_irq_restore(flags); | 419 | local_irq_restore(flags); |
413 | |||
414 | } | 420 | } |
415 | #else | 421 | #else |
416 | # define default_gpio(...) do { } while (0) | 422 | # define default_gpio(...) do { } while (0) |
@@ -418,12 +424,6 @@ static void default_gpio(unsigned short gpio) | |||
418 | 424 | ||
419 | static int __init bfin_gpio_init(void) | 425 | static int __init bfin_gpio_init(void) |
420 | { | 426 | { |
421 | str_ident = kcalloc(MAX_RESOURCES, | ||
422 | sizeof(struct str_ident), GFP_KERNEL); | ||
423 | if (str_ident == NULL) | ||
424 | return -ENOMEM; | ||
425 | |||
426 | memset(str_ident, 0, MAX_RESOURCES * sizeof(struct str_ident)); | ||
427 | 427 | ||
428 | printk(KERN_INFO "Blackfin GPIO Controller\n"); | 428 | printk(KERN_INFO "Blackfin GPIO Controller\n"); |
429 | 429 | ||
@@ -454,10 +454,9 @@ arch_initcall(bfin_gpio_init); | |||
454 | /* Set a specific bit */ | 454 | /* Set a specific bit */ |
455 | 455 | ||
456 | #define SET_GPIO(name) \ | 456 | #define SET_GPIO(name) \ |
457 | void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \ | 457 | void set_gpio_ ## name(unsigned gpio, unsigned short arg) \ |
458 | { \ | 458 | { \ |
459 | unsigned long flags; \ | 459 | unsigned long flags; \ |
460 | BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); \ | ||
461 | local_irq_save(flags); \ | 460 | local_irq_save(flags); \ |
462 | if (arg) \ | 461 | if (arg) \ |
463 | gpio_bankb[gpio_bank(gpio)]->name |= gpio_bit(gpio); \ | 462 | gpio_bankb[gpio_bank(gpio)]->name |= gpio_bit(gpio); \ |
@@ -477,10 +476,9 @@ SET_GPIO(both) | |||
477 | 476 | ||
478 | #if ANOMALY_05000311 || ANOMALY_05000323 | 477 | #if ANOMALY_05000311 || ANOMALY_05000323 |
479 | #define SET_GPIO_SC(name) \ | 478 | #define SET_GPIO_SC(name) \ |
480 | void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \ | 479 | void set_gpio_ ## name(unsigned gpio, unsigned short arg) \ |
481 | { \ | 480 | { \ |
482 | unsigned long flags; \ | 481 | unsigned long flags; \ |
483 | BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); \ | ||
484 | local_irq_save(flags); \ | 482 | local_irq_save(flags); \ |
485 | if (arg) \ | 483 | if (arg) \ |
486 | gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \ | 484 | gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \ |
@@ -492,9 +490,8 @@ void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \ | |||
492 | EXPORT_SYMBOL(set_gpio_ ## name); | 490 | EXPORT_SYMBOL(set_gpio_ ## name); |
493 | #else | 491 | #else |
494 | #define SET_GPIO_SC(name) \ | 492 | #define SET_GPIO_SC(name) \ |
495 | void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \ | 493 | void set_gpio_ ## name(unsigned gpio, unsigned short arg) \ |
496 | { \ | 494 | { \ |
497 | BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); \ | ||
498 | if (arg) \ | 495 | if (arg) \ |
499 | gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \ | 496 | gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \ |
500 | else \ | 497 | else \ |
@@ -508,19 +505,17 @@ SET_GPIO_SC(maskb) | |||
508 | SET_GPIO_SC(data) | 505 | SET_GPIO_SC(data) |
509 | 506 | ||
510 | #if ANOMALY_05000311 || ANOMALY_05000323 | 507 | #if ANOMALY_05000311 || ANOMALY_05000323 |
511 | void set_gpio_toggle(unsigned short gpio) | 508 | void set_gpio_toggle(unsigned gpio) |
512 | { | 509 | { |
513 | unsigned long flags; | 510 | unsigned long flags; |
514 | BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); | ||
515 | local_irq_save(flags); | 511 | local_irq_save(flags); |
516 | gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio); | 512 | gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio); |
517 | AWA_DUMMY_READ(toggle); | 513 | AWA_DUMMY_READ(toggle); |
518 | local_irq_restore(flags); | 514 | local_irq_restore(flags); |
519 | } | 515 | } |
520 | #else | 516 | #else |
521 | void set_gpio_toggle(unsigned short gpio) | 517 | void set_gpio_toggle(unsigned gpio) |
522 | { | 518 | { |
523 | BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); | ||
524 | gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio); | 519 | gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio); |
525 | } | 520 | } |
526 | #endif | 521 | #endif |
@@ -531,7 +526,7 @@ EXPORT_SYMBOL(set_gpio_toggle); | |||
531 | 526 | ||
532 | #if ANOMALY_05000311 || ANOMALY_05000323 | 527 | #if ANOMALY_05000311 || ANOMALY_05000323 |
533 | #define SET_GPIO_P(name) \ | 528 | #define SET_GPIO_P(name) \ |
534 | void set_gpiop_ ## name(unsigned short gpio, unsigned short arg) \ | 529 | void set_gpiop_ ## name(unsigned gpio, unsigned short arg) \ |
535 | { \ | 530 | { \ |
536 | unsigned long flags; \ | 531 | unsigned long flags; \ |
537 | local_irq_save(flags); \ | 532 | local_irq_save(flags); \ |
@@ -542,7 +537,7 @@ void set_gpiop_ ## name(unsigned short gpio, unsigned short arg) \ | |||
542 | EXPORT_SYMBOL(set_gpiop_ ## name); | 537 | EXPORT_SYMBOL(set_gpiop_ ## name); |
543 | #else | 538 | #else |
544 | #define SET_GPIO_P(name) \ | 539 | #define SET_GPIO_P(name) \ |
545 | void set_gpiop_ ## name(unsigned short gpio, unsigned short arg) \ | 540 | void set_gpiop_ ## name(unsigned gpio, unsigned short arg) \ |
546 | { \ | 541 | { \ |
547 | gpio_bankb[gpio_bank(gpio)]->name = arg; \ | 542 | gpio_bankb[gpio_bank(gpio)]->name = arg; \ |
548 | } \ | 543 | } \ |
@@ -558,11 +553,10 @@ SET_GPIO_P(both) | |||
558 | SET_GPIO_P(maska) | 553 | SET_GPIO_P(maska) |
559 | SET_GPIO_P(maskb) | 554 | SET_GPIO_P(maskb) |
560 | 555 | ||
561 | |||
562 | /* Get a specific bit */ | 556 | /* Get a specific bit */ |
563 | #if ANOMALY_05000311 || ANOMALY_05000323 | 557 | #if ANOMALY_05000311 || ANOMALY_05000323 |
564 | #define GET_GPIO(name) \ | 558 | #define GET_GPIO(name) \ |
565 | unsigned short get_gpio_ ## name(unsigned short gpio) \ | 559 | unsigned short get_gpio_ ## name(unsigned gpio) \ |
566 | { \ | 560 | { \ |
567 | unsigned long flags; \ | 561 | unsigned long flags; \ |
568 | unsigned short ret; \ | 562 | unsigned short ret; \ |
@@ -575,7 +569,7 @@ unsigned short get_gpio_ ## name(unsigned short gpio) \ | |||
575 | EXPORT_SYMBOL(get_gpio_ ## name); | 569 | EXPORT_SYMBOL(get_gpio_ ## name); |
576 | #else | 570 | #else |
577 | #define GET_GPIO(name) \ | 571 | #define GET_GPIO(name) \ |
578 | unsigned short get_gpio_ ## name(unsigned short gpio) \ | 572 | unsigned short get_gpio_ ## name(unsigned gpio) \ |
579 | { \ | 573 | { \ |
580 | return (0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio))); \ | 574 | return (0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio))); \ |
581 | } \ | 575 | } \ |
@@ -595,7 +589,7 @@ GET_GPIO(maskb) | |||
595 | 589 | ||
596 | #if ANOMALY_05000311 || ANOMALY_05000323 | 590 | #if ANOMALY_05000311 || ANOMALY_05000323 |
597 | #define GET_GPIO_P(name) \ | 591 | #define GET_GPIO_P(name) \ |
598 | unsigned short get_gpiop_ ## name(unsigned short gpio) \ | 592 | unsigned short get_gpiop_ ## name(unsigned gpio) \ |
599 | { \ | 593 | { \ |
600 | unsigned long flags; \ | 594 | unsigned long flags; \ |
601 | unsigned short ret; \ | 595 | unsigned short ret; \ |
@@ -608,7 +602,7 @@ unsigned short get_gpiop_ ## name(unsigned short gpio) \ | |||
608 | EXPORT_SYMBOL(get_gpiop_ ## name); | 602 | EXPORT_SYMBOL(get_gpiop_ ## name); |
609 | #else | 603 | #else |
610 | #define GET_GPIO_P(name) \ | 604 | #define GET_GPIO_P(name) \ |
611 | unsigned short get_gpiop_ ## name(unsigned short gpio) \ | 605 | unsigned short get_gpiop_ ## name(unsigned gpio) \ |
612 | { \ | 606 | { \ |
613 | return (gpio_bankb[gpio_bank(gpio)]->name);\ | 607 | return (gpio_bankb[gpio_bank(gpio)]->name);\ |
614 | } \ | 608 | } \ |
@@ -645,7 +639,7 @@ GET_GPIO_P(maskb) | |||
645 | ************************************************************* | 639 | ************************************************************* |
646 | * MODIFICATION HISTORY : | 640 | * MODIFICATION HISTORY : |
647 | **************************************************************/ | 641 | **************************************************************/ |
648 | int gpio_pm_wakeup_request(unsigned short gpio, unsigned char type) | 642 | int gpio_pm_wakeup_request(unsigned gpio, unsigned char type) |
649 | { | 643 | { |
650 | unsigned long flags; | 644 | unsigned long flags; |
651 | 645 | ||
@@ -653,7 +647,6 @@ int gpio_pm_wakeup_request(unsigned short gpio, unsigned char type) | |||
653 | return -EINVAL; | 647 | return -EINVAL; |
654 | 648 | ||
655 | local_irq_save(flags); | 649 | local_irq_save(flags); |
656 | |||
657 | wakeup_map[gpio_bank(gpio)] |= gpio_bit(gpio); | 650 | wakeup_map[gpio_bank(gpio)] |= gpio_bit(gpio); |
658 | wakeup_flags_map[gpio] = type; | 651 | wakeup_flags_map[gpio] = type; |
659 | local_irq_restore(flags); | 652 | local_irq_restore(flags); |
@@ -662,7 +655,7 @@ int gpio_pm_wakeup_request(unsigned short gpio, unsigned char type) | |||
662 | } | 655 | } |
663 | EXPORT_SYMBOL(gpio_pm_wakeup_request); | 656 | EXPORT_SYMBOL(gpio_pm_wakeup_request); |
664 | 657 | ||
665 | void gpio_pm_wakeup_free(unsigned short gpio) | 658 | void gpio_pm_wakeup_free(unsigned gpio) |
666 | { | 659 | { |
667 | unsigned long flags; | 660 | unsigned long flags; |
668 | 661 | ||
@@ -677,7 +670,7 @@ void gpio_pm_wakeup_free(unsigned short gpio) | |||
677 | } | 670 | } |
678 | EXPORT_SYMBOL(gpio_pm_wakeup_free); | 671 | EXPORT_SYMBOL(gpio_pm_wakeup_free); |
679 | 672 | ||
680 | static int bfin_gpio_wakeup_type(unsigned short gpio, unsigned char type) | 673 | static int bfin_gpio_wakeup_type(unsigned gpio, unsigned char type) |
681 | { | 674 | { |
682 | port_setup(gpio, GPIO_USAGE); | 675 | port_setup(gpio, GPIO_USAGE); |
683 | set_gpio_dir(gpio, 0); | 676 | set_gpio_dir(gpio, 0); |
@@ -784,6 +777,14 @@ void gpio_pm_restore(void) | |||
784 | } | 777 | } |
785 | 778 | ||
786 | #endif | 779 | #endif |
780 | #else /* BF548_FAMILY */ | ||
781 | |||
782 | unsigned short get_gpio_dir(unsigned gpio) | ||
783 | { | ||
784 | return (0x01 & (gpio_array[gpio_bank(gpio)]->port_dir_clear >> gpio_sub_n(gpio))); | ||
785 | } | ||
786 | EXPORT_SYMBOL(get_gpio_dir); | ||
787 | |||
787 | #endif /* BF548_FAMILY */ | 788 | #endif /* BF548_FAMILY */ |
788 | 789 | ||
789 | /*********************************************************** | 790 | /*********************************************************** |
@@ -1028,7 +1029,7 @@ EXPORT_SYMBOL(peripheral_free_list); | |||
1028 | * MODIFICATION HISTORY : | 1029 | * MODIFICATION HISTORY : |
1029 | **************************************************************/ | 1030 | **************************************************************/ |
1030 | 1031 | ||
1031 | int gpio_request(unsigned short gpio, const char *label) | 1032 | int gpio_request(unsigned gpio, const char *label) |
1032 | { | 1033 | { |
1033 | unsigned long flags; | 1034 | unsigned long flags; |
1034 | 1035 | ||
@@ -1075,7 +1076,7 @@ int gpio_request(unsigned short gpio, const char *label) | |||
1075 | } | 1076 | } |
1076 | EXPORT_SYMBOL(gpio_request); | 1077 | EXPORT_SYMBOL(gpio_request); |
1077 | 1078 | ||
1078 | void gpio_free(unsigned short gpio) | 1079 | void gpio_free(unsigned gpio) |
1079 | { | 1080 | { |
1080 | unsigned long flags; | 1081 | unsigned long flags; |
1081 | 1082 | ||
@@ -1085,7 +1086,7 @@ void gpio_free(unsigned short gpio) | |||
1085 | local_irq_save(flags); | 1086 | local_irq_save(flags); |
1086 | 1087 | ||
1087 | if (unlikely(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) { | 1088 | if (unlikely(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) { |
1088 | printk(KERN_ERR "bfin-gpio: GPIO %d wasn't reserved!\n", gpio); | 1089 | gpio_error(gpio); |
1089 | dump_stack(); | 1090 | dump_stack(); |
1090 | local_irq_restore(flags); | 1091 | local_irq_restore(flags); |
1091 | return; | 1092 | return; |
@@ -1101,44 +1102,55 @@ void gpio_free(unsigned short gpio) | |||
1101 | } | 1102 | } |
1102 | EXPORT_SYMBOL(gpio_free); | 1103 | EXPORT_SYMBOL(gpio_free); |
1103 | 1104 | ||
1105 | |||
1104 | #ifdef BF548_FAMILY | 1106 | #ifdef BF548_FAMILY |
1105 | void gpio_direction_input(unsigned short gpio) | 1107 | int gpio_direction_input(unsigned gpio) |
1106 | { | 1108 | { |
1107 | unsigned long flags; | 1109 | unsigned long flags; |
1108 | 1110 | ||
1109 | BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); | 1111 | if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { |
1112 | gpio_error(gpio); | ||
1113 | return -EINVAL; | ||
1114 | } | ||
1110 | 1115 | ||
1111 | local_irq_save(flags); | 1116 | local_irq_save(flags); |
1112 | gpio_array[gpio_bank(gpio)]->port_dir_clear = gpio_bit(gpio); | 1117 | gpio_array[gpio_bank(gpio)]->port_dir_clear = gpio_bit(gpio); |
1113 | gpio_array[gpio_bank(gpio)]->port_inen |= gpio_bit(gpio); | 1118 | gpio_array[gpio_bank(gpio)]->port_inen |= gpio_bit(gpio); |
1114 | local_irq_restore(flags); | 1119 | local_irq_restore(flags); |
1120 | |||
1121 | return 0; | ||
1115 | } | 1122 | } |
1116 | EXPORT_SYMBOL(gpio_direction_input); | 1123 | EXPORT_SYMBOL(gpio_direction_input); |
1117 | 1124 | ||
1118 | void gpio_direction_output(unsigned short gpio) | 1125 | int gpio_direction_output(unsigned gpio, int value) |
1119 | { | 1126 | { |
1120 | unsigned long flags; | 1127 | unsigned long flags; |
1121 | 1128 | ||
1122 | BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); | 1129 | if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { |
1130 | gpio_error(gpio); | ||
1131 | return -EINVAL; | ||
1132 | } | ||
1123 | 1133 | ||
1124 | local_irq_save(flags); | 1134 | local_irq_save(flags); |
1125 | gpio_array[gpio_bank(gpio)]->port_inen &= ~gpio_bit(gpio); | 1135 | gpio_array[gpio_bank(gpio)]->port_inen &= ~gpio_bit(gpio); |
1136 | gpio_set_value(gpio, value); | ||
1126 | gpio_array[gpio_bank(gpio)]->port_dir_set = gpio_bit(gpio); | 1137 | gpio_array[gpio_bank(gpio)]->port_dir_set = gpio_bit(gpio); |
1127 | local_irq_restore(flags); | 1138 | local_irq_restore(flags); |
1139 | |||
1140 | return 0; | ||
1128 | } | 1141 | } |
1129 | EXPORT_SYMBOL(gpio_direction_output); | 1142 | EXPORT_SYMBOL(gpio_direction_output); |
1130 | 1143 | ||
1131 | void gpio_set_value(unsigned short gpio, unsigned short arg) | 1144 | void gpio_set_value(unsigned gpio, int arg) |
1132 | { | 1145 | { |
1133 | if (arg) | 1146 | if (arg) |
1134 | gpio_array[gpio_bank(gpio)]->port_set = gpio_bit(gpio); | 1147 | gpio_array[gpio_bank(gpio)]->port_set = gpio_bit(gpio); |
1135 | else | 1148 | else |
1136 | gpio_array[gpio_bank(gpio)]->port_clear = gpio_bit(gpio); | 1149 | gpio_array[gpio_bank(gpio)]->port_clear = gpio_bit(gpio); |
1137 | |||
1138 | } | 1150 | } |
1139 | EXPORT_SYMBOL(gpio_set_value); | 1151 | EXPORT_SYMBOL(gpio_set_value); |
1140 | 1152 | ||
1141 | unsigned short gpio_get_value(unsigned short gpio) | 1153 | int gpio_get_value(unsigned gpio) |
1142 | { | 1154 | { |
1143 | return (1 & (gpio_array[gpio_bank(gpio)]->port_data >> gpio_sub_n(gpio))); | 1155 | return (1 & (gpio_array[gpio_bank(gpio)]->port_data >> gpio_sub_n(gpio))); |
1144 | } | 1156 | } |
@@ -1146,31 +1158,47 @@ EXPORT_SYMBOL(gpio_get_value); | |||
1146 | 1158 | ||
1147 | #else | 1159 | #else |
1148 | 1160 | ||
1149 | void gpio_direction_input(unsigned short gpio) | 1161 | int gpio_direction_input(unsigned gpio) |
1150 | { | 1162 | { |
1151 | unsigned long flags; | 1163 | unsigned long flags; |
1152 | 1164 | ||
1153 | BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); | 1165 | if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { |
1166 | gpio_error(gpio); | ||
1167 | return -EINVAL; | ||
1168 | } | ||
1154 | 1169 | ||
1155 | local_irq_save(flags); | 1170 | local_irq_save(flags); |
1156 | gpio_bankb[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio); | 1171 | gpio_bankb[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio); |
1157 | gpio_bankb[gpio_bank(gpio)]->inen |= gpio_bit(gpio); | 1172 | gpio_bankb[gpio_bank(gpio)]->inen |= gpio_bit(gpio); |
1158 | AWA_DUMMY_READ(inen); | 1173 | AWA_DUMMY_READ(inen); |
1159 | local_irq_restore(flags); | 1174 | local_irq_restore(flags); |
1175 | |||
1176 | return 0; | ||
1160 | } | 1177 | } |
1161 | EXPORT_SYMBOL(gpio_direction_input); | 1178 | EXPORT_SYMBOL(gpio_direction_input); |
1162 | 1179 | ||
1163 | void gpio_direction_output(unsigned short gpio) | 1180 | int gpio_direction_output(unsigned gpio, int value) |
1164 | { | 1181 | { |
1165 | unsigned long flags; | 1182 | unsigned long flags; |
1166 | 1183 | ||
1167 | BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); | 1184 | if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { |
1185 | gpio_error(gpio); | ||
1186 | return -EINVAL; | ||
1187 | } | ||
1168 | 1188 | ||
1169 | local_irq_save(flags); | 1189 | local_irq_save(flags); |
1170 | gpio_bankb[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio); | 1190 | gpio_bankb[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio); |
1191 | |||
1192 | if (value) | ||
1193 | gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio); | ||
1194 | else | ||
1195 | gpio_bankb[gpio_bank(gpio)]->data_clear = gpio_bit(gpio); | ||
1196 | |||
1171 | gpio_bankb[gpio_bank(gpio)]->dir |= gpio_bit(gpio); | 1197 | gpio_bankb[gpio_bank(gpio)]->dir |= gpio_bit(gpio); |
1172 | AWA_DUMMY_READ(dir); | 1198 | AWA_DUMMY_READ(dir); |
1173 | local_irq_restore(flags); | 1199 | local_irq_restore(flags); |
1200 | |||
1201 | return 0; | ||
1174 | } | 1202 | } |
1175 | EXPORT_SYMBOL(gpio_direction_output); | 1203 | EXPORT_SYMBOL(gpio_direction_output); |
1176 | 1204 | ||
@@ -1190,7 +1218,40 @@ void bfin_gpio_reset_spi0_ssel1(void) | |||
1190 | 1218 | ||
1191 | port_setup(gpio, GPIO_USAGE); | 1219 | port_setup(gpio, GPIO_USAGE); |
1192 | gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio); | 1220 | gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio); |
1221 | AWA_DUMMY_READ(data_set); | ||
1193 | udelay(1); | 1222 | udelay(1); |
1194 | } | 1223 | } |
1195 | 1224 | ||
1196 | #endif /*BF548_FAMILY */ | 1225 | #endif /*BF548_FAMILY */ |
1226 | |||
1227 | #if defined(CONFIG_PROC_FS) | ||
1228 | static int gpio_proc_read(char *buf, char **start, off_t offset, | ||
1229 | int len, int *unused_i, void *unused_v) | ||
1230 | { | ||
1231 | int c, outlen = 0; | ||
1232 | |||
1233 | for (c = 0; c < MAX_RESOURCES; c++) { | ||
1234 | if (!check_gpio(c) && (reserved_gpio_map[gpio_bank(c)] & gpio_bit(c))) | ||
1235 | len = sprintf(buf, "GPIO_%d: %s \t\tGPIO %s\n", c, | ||
1236 | get_label(c), get_gpio_dir(c) ? "OUTPUT" : "INPUT"); | ||
1237 | else if (reserved_peri_map[gpio_bank(c)] & gpio_bit(c)) | ||
1238 | len = sprintf(buf, "GPIO_%d: %s \t\tPeripheral\n", c, get_label(c)); | ||
1239 | else | ||
1240 | continue; | ||
1241 | buf += len; | ||
1242 | outlen += len; | ||
1243 | } | ||
1244 | return outlen; | ||
1245 | } | ||
1246 | |||
1247 | static __init int gpio_register_proc(void) | ||
1248 | { | ||
1249 | struct proc_dir_entry *proc_gpio; | ||
1250 | |||
1251 | proc_gpio = create_proc_entry("gpio", S_IRUGO, NULL); | ||
1252 | if (proc_gpio) | ||
1253 | proc_gpio->read_proc = gpio_proc_read; | ||
1254 | return proc_gpio != NULL; | ||
1255 | } | ||
1256 | __initcall(gpio_register_proc); | ||
1257 | #endif | ||
diff --git a/arch/blackfin/kernel/cplb-mpu/Makefile b/arch/blackfin/kernel/cplb-mpu/Makefile new file mode 100644 index 000000000000..286b69357f97 --- /dev/null +++ b/arch/blackfin/kernel/cplb-mpu/Makefile | |||
@@ -0,0 +1,8 @@ | |||
1 | # | ||
2 | # arch/blackfin/kernel/cplb-nompu/Makefile | ||
3 | # | ||
4 | |||
5 | obj-y := cplbinit.o cacheinit.o cplbmgr.o | ||
6 | |||
7 | obj-$(CONFIG_CPLB_INFO) += cplbinfo.o | ||
8 | |||
diff --git a/arch/blackfin/kernel/cplb-mpu/cacheinit.c b/arch/blackfin/kernel/cplb-mpu/cacheinit.c new file mode 100644 index 000000000000..9eecfa403187 --- /dev/null +++ b/arch/blackfin/kernel/cplb-mpu/cacheinit.c | |||
@@ -0,0 +1,62 @@ | |||
1 | /* | ||
2 | * Copyright 2004-2007 Analog Devices Inc. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, see the file COPYING, or write | ||
16 | * to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | */ | ||
19 | |||
20 | #include <linux/cpu.h> | ||
21 | |||
22 | #include <asm/cacheflush.h> | ||
23 | #include <asm/blackfin.h> | ||
24 | #include <asm/cplb.h> | ||
25 | #include <asm/cplbinit.h> | ||
26 | |||
27 | #if defined(CONFIG_BFIN_ICACHE) | ||
28 | void bfin_icache_init(void) | ||
29 | { | ||
30 | unsigned long ctrl; | ||
31 | int i; | ||
32 | |||
33 | SSYNC(); | ||
34 | for (i = 0; i < MAX_CPLBS; i++) { | ||
35 | bfin_write32(ICPLB_ADDR0 + i * 4, icplb_tbl[i].addr); | ||
36 | bfin_write32(ICPLB_DATA0 + i * 4, icplb_tbl[i].data); | ||
37 | } | ||
38 | ctrl = bfin_read_IMEM_CONTROL(); | ||
39 | ctrl |= IMC | ENICPLB; | ||
40 | bfin_write_IMEM_CONTROL(ctrl); | ||
41 | SSYNC(); | ||
42 | } | ||
43 | #endif | ||
44 | |||
45 | #if defined(CONFIG_BFIN_DCACHE) | ||
46 | void bfin_dcache_init(void) | ||
47 | { | ||
48 | unsigned long ctrl; | ||
49 | int i; | ||
50 | |||
51 | SSYNC(); | ||
52 | for (i = 0; i < MAX_CPLBS; i++) { | ||
53 | bfin_write32(DCPLB_ADDR0 + i * 4, dcplb_tbl[i].addr); | ||
54 | bfin_write32(DCPLB_DATA0 + i * 4, dcplb_tbl[i].data); | ||
55 | } | ||
56 | |||
57 | ctrl = bfin_read_DMEM_CONTROL(); | ||
58 | ctrl |= DMEM_CNTR; | ||
59 | bfin_write_DMEM_CONTROL(ctrl); | ||
60 | SSYNC(); | ||
61 | } | ||
62 | #endif | ||
diff --git a/arch/blackfin/kernel/cplb-mpu/cplbinfo.c b/arch/blackfin/kernel/cplb-mpu/cplbinfo.c new file mode 100644 index 000000000000..bd072299f7f2 --- /dev/null +++ b/arch/blackfin/kernel/cplb-mpu/cplbinfo.c | |||
@@ -0,0 +1,144 @@ | |||
1 | /* | ||
2 | * File: arch/blackfin/mach-common/cplbinfo.c | ||
3 | * Based on: | ||
4 | * Author: Sonic Zhang <sonic.zhang@analog.com> | ||
5 | * | ||
6 | * Created: Jan. 2005 | ||
7 | * Description: Display CPLB status | ||
8 | * | ||
9 | * Modified: | ||
10 | * Copyright 2004-2006 Analog Devices Inc. | ||
11 | * | ||
12 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License as published by | ||
16 | * the Free Software Foundation; either version 2 of the License, or | ||
17 | * (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, see the file COPYING, or write | ||
26 | * to the Free Software Foundation, Inc., | ||
27 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
28 | */ | ||
29 | |||
30 | #include <linux/module.h> | ||
31 | #include <linux/kernel.h> | ||
32 | #include <linux/init.h> | ||
33 | #include <linux/proc_fs.h> | ||
34 | #include <linux/uaccess.h> | ||
35 | |||
36 | #include <asm/current.h> | ||
37 | #include <asm/system.h> | ||
38 | #include <asm/cplb.h> | ||
39 | #include <asm/cplbinit.h> | ||
40 | #include <asm/blackfin.h> | ||
41 | |||
42 | #define CPLB_I 1 | ||
43 | #define CPLB_D 2 | ||
44 | |||
45 | #define SYNC_SYS SSYNC() | ||
46 | #define SYNC_CORE CSYNC() | ||
47 | |||
48 | #define CPLB_BIT_PAGESIZE 0x30000 | ||
49 | |||
50 | static char page_size_string_table[][4] = { "1K", "4K", "1M", "4M" }; | ||
51 | |||
52 | static char *cplb_print_entry(char *buf, struct cplb_entry *tbl, int switched) | ||
53 | { | ||
54 | int i; | ||
55 | buf += sprintf(buf, "Index\tAddress\t\tData\tSize\tU/RD\tU/WR\tS/WR\tSwitch\n"); | ||
56 | for (i = 0; i < MAX_CPLBS; i++) { | ||
57 | unsigned long data = tbl[i].data; | ||
58 | unsigned long addr = tbl[i].addr; | ||
59 | if (!(data & CPLB_VALID)) | ||
60 | continue; | ||
61 | |||
62 | buf += | ||
63 | sprintf(buf, | ||
64 | "%d\t0x%08lx\t%06lx\t%s\t%c\t%c\t%c\t%c\n", | ||
65 | i, addr, data, | ||
66 | page_size_string_table[(data & 0x30000) >> 16], | ||
67 | (data & CPLB_USER_RD) ? 'Y' : 'N', | ||
68 | (data & CPLB_USER_WR) ? 'Y' : 'N', | ||
69 | (data & CPLB_SUPV_WR) ? 'Y' : 'N', | ||
70 | i < switched ? 'N' : 'Y'); | ||
71 | } | ||
72 | buf += sprintf(buf, "\n"); | ||
73 | |||
74 | return buf; | ||
75 | } | ||
76 | |||
77 | int cplbinfo_proc_output(char *buf) | ||
78 | { | ||
79 | char *p; | ||
80 | |||
81 | p = buf; | ||
82 | |||
83 | p += sprintf(p, "------------------ CPLB Information ------------------\n\n"); | ||
84 | |||
85 | if (bfin_read_IMEM_CONTROL() & ENICPLB) { | ||
86 | p += sprintf(p, "Instruction CPLB entry:\n"); | ||
87 | p = cplb_print_entry(p, icplb_tbl, first_switched_icplb); | ||
88 | } else | ||
89 | p += sprintf(p, "Instruction CPLB is disabled.\n\n"); | ||
90 | |||
91 | if (1 || bfin_read_DMEM_CONTROL() & ENDCPLB) { | ||
92 | p += sprintf(p, "Data CPLB entry:\n"); | ||
93 | p = cplb_print_entry(p, dcplb_tbl, first_switched_dcplb); | ||
94 | } else | ||
95 | p += sprintf(p, "Data CPLB is disabled.\n"); | ||
96 | |||
97 | p += sprintf(p, "ICPLB miss: %d\nICPLB supervisor miss: %d\n", | ||
98 | nr_icplb_miss, nr_icplb_supv_miss); | ||
99 | p += sprintf(p, "DCPLB miss: %d\nDCPLB protection fault:%d\n", | ||
100 | nr_dcplb_miss, nr_dcplb_prot); | ||
101 | p += sprintf(p, "CPLB flushes: %d\n", | ||
102 | nr_cplb_flush); | ||
103 | |||
104 | return p - buf; | ||
105 | } | ||
106 | |||
107 | static int cplbinfo_read_proc(char *page, char **start, off_t off, | ||
108 | int count, int *eof, void *data) | ||
109 | { | ||
110 | int len; | ||
111 | |||
112 | len = cplbinfo_proc_output(page); | ||
113 | if (len <= off + count) | ||
114 | *eof = 1; | ||
115 | *start = page + off; | ||
116 | len -= off; | ||
117 | if (len > count) | ||
118 | len = count; | ||
119 | if (len < 0) | ||
120 | len = 0; | ||
121 | return len; | ||
122 | } | ||
123 | |||
124 | static int __init cplbinfo_init(void) | ||
125 | { | ||
126 | struct proc_dir_entry *entry; | ||
127 | |||
128 | entry = create_proc_entry("cplbinfo", 0, NULL); | ||
129 | if (!entry) | ||
130 | return -ENOMEM; | ||
131 | |||
132 | entry->read_proc = cplbinfo_read_proc; | ||
133 | entry->data = NULL; | ||
134 | |||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | static void __exit cplbinfo_exit(void) | ||
139 | { | ||
140 | remove_proc_entry("cplbinfo", NULL); | ||
141 | } | ||
142 | |||
143 | module_init(cplbinfo_init); | ||
144 | module_exit(cplbinfo_exit); | ||
diff --git a/arch/blackfin/kernel/cplb-mpu/cplbinit.c b/arch/blackfin/kernel/cplb-mpu/cplbinit.c new file mode 100644 index 000000000000..e2e2b5079f5b --- /dev/null +++ b/arch/blackfin/kernel/cplb-mpu/cplbinit.c | |||
@@ -0,0 +1,91 @@ | |||
1 | /* | ||
2 | * Blackfin CPLB initialization | ||
3 | * | ||
4 | * Copyright 2004-2007 Analog Devices Inc. | ||
5 | * | ||
6 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | ||
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, see the file COPYING, or write | ||
20 | * to the Free Software Foundation, Inc., | ||
21 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
22 | */ | ||
23 | #include <linux/module.h> | ||
24 | |||
25 | #include <asm/blackfin.h> | ||
26 | #include <asm/cplb.h> | ||
27 | #include <asm/cplbinit.h> | ||
28 | |||
29 | struct cplb_entry icplb_tbl[MAX_CPLBS]; | ||
30 | struct cplb_entry dcplb_tbl[MAX_CPLBS]; | ||
31 | |||
32 | int first_switched_icplb, first_switched_dcplb; | ||
33 | int first_mask_dcplb; | ||
34 | |||
35 | void __init generate_cpl_tables(void) | ||
36 | { | ||
37 | int i_d, i_i; | ||
38 | unsigned long addr; | ||
39 | unsigned long d_data, i_data; | ||
40 | unsigned long d_cache = 0, i_cache = 0; | ||
41 | |||
42 | #ifdef CONFIG_BFIN_ICACHE | ||
43 | i_cache = CPLB_L1_CHBL | ANOMALY_05000158_WORKAROUND; | ||
44 | #endif | ||
45 | |||
46 | #ifdef CONFIG_BFIN_DCACHE | ||
47 | d_cache = CPLB_L1_CHBL; | ||
48 | #ifdef CONFIG_BLKFIN_WT | ||
49 | d_cache |= CPLB_L1_AOW | CPLB_WT; | ||
50 | #endif | ||
51 | #endif | ||
52 | i_d = i_i = 0; | ||
53 | |||
54 | /* Set up the zero page. */ | ||
55 | dcplb_tbl[i_d].addr = 0; | ||
56 | dcplb_tbl[i_d++].data = SDRAM_OOPS | PAGE_SIZE_1KB; | ||
57 | |||
58 | #if 0 | ||
59 | icplb_tbl[i_i].addr = 0; | ||
60 | icplb_tbl[i_i++].data = i_cache | CPLB_USER_RD | PAGE_SIZE_4KB; | ||
61 | #endif | ||
62 | |||
63 | /* Cover kernel memory with 4M pages. */ | ||
64 | addr = 0; | ||
65 | d_data = d_cache | CPLB_SUPV_WR | CPLB_VALID | PAGE_SIZE_4MB | CPLB_DIRTY; | ||
66 | i_data = i_cache | CPLB_VALID | CPLB_PORTPRIO | PAGE_SIZE_4MB; | ||
67 | |||
68 | for (; addr < memory_start; addr += 4 * 1024 * 1024) { | ||
69 | dcplb_tbl[i_d].addr = addr; | ||
70 | dcplb_tbl[i_d++].data = d_data; | ||
71 | icplb_tbl[i_i].addr = addr; | ||
72 | icplb_tbl[i_i++].data = i_data | (addr == 0 ? CPLB_USER_RD : 0); | ||
73 | } | ||
74 | |||
75 | /* Cover L1 memory. One 4M area for code and data each is enough. */ | ||
76 | #if L1_DATA_A_LENGTH > 0 || L1_DATA_B_LENGTH > 0 | ||
77 | dcplb_tbl[i_d].addr = L1_DATA_A_START; | ||
78 | dcplb_tbl[i_d++].data = L1_DMEMORY | PAGE_SIZE_4MB; | ||
79 | #endif | ||
80 | icplb_tbl[i_i].addr = L1_CODE_START; | ||
81 | icplb_tbl[i_i++].data = L1_IMEMORY | PAGE_SIZE_4MB; | ||
82 | |||
83 | first_mask_dcplb = i_d; | ||
84 | first_switched_dcplb = i_d + (1 << page_mask_order); | ||
85 | first_switched_icplb = i_i; | ||
86 | |||
87 | while (i_d < MAX_CPLBS) | ||
88 | dcplb_tbl[i_d++].data = 0; | ||
89 | while (i_i < MAX_CPLBS) | ||
90 | icplb_tbl[i_i++].data = 0; | ||
91 | } | ||
diff --git a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c new file mode 100644 index 000000000000..c426a22f9907 --- /dev/null +++ b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c | |||
@@ -0,0 +1,338 @@ | |||
1 | /* | ||
2 | * Blackfin CPLB exception handling. | ||
3 | * Copyright 2004-2007 Analog Devices Inc. | ||
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, see the file COPYING, or write | ||
17 | * to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | */ | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/mm.h> | ||
22 | |||
23 | #include <asm/blackfin.h> | ||
24 | #include <asm/cplbinit.h> | ||
25 | #include <asm/mmu_context.h> | ||
26 | |||
27 | #ifdef CONFIG_BFIN_ICACHE | ||
28 | |||
29 | #define FAULT_RW (1 << 16) | ||
30 | #define FAULT_USERSUPV (1 << 17) | ||
31 | |||
32 | int page_mask_nelts; | ||
33 | int page_mask_order; | ||
34 | unsigned long *current_rwx_mask; | ||
35 | |||
36 | int nr_dcplb_miss, nr_icplb_miss, nr_icplb_supv_miss, nr_dcplb_prot; | ||
37 | int nr_cplb_flush; | ||
38 | |||
39 | static inline void disable_dcplb(void) | ||
40 | { | ||
41 | unsigned long ctrl; | ||
42 | SSYNC(); | ||
43 | ctrl = bfin_read_DMEM_CONTROL(); | ||
44 | ctrl &= ~ENDCPLB; | ||
45 | bfin_write_DMEM_CONTROL(ctrl); | ||
46 | SSYNC(); | ||
47 | } | ||
48 | |||
49 | static inline void enable_dcplb(void) | ||
50 | { | ||
51 | unsigned long ctrl; | ||
52 | SSYNC(); | ||
53 | ctrl = bfin_read_DMEM_CONTROL(); | ||
54 | ctrl |= ENDCPLB; | ||
55 | bfin_write_DMEM_CONTROL(ctrl); | ||
56 | SSYNC(); | ||
57 | } | ||
58 | |||
59 | static inline void disable_icplb(void) | ||
60 | { | ||
61 | unsigned long ctrl; | ||
62 | SSYNC(); | ||
63 | ctrl = bfin_read_IMEM_CONTROL(); | ||
64 | ctrl &= ~ENICPLB; | ||
65 | bfin_write_IMEM_CONTROL(ctrl); | ||
66 | SSYNC(); | ||
67 | } | ||
68 | |||
69 | static inline void enable_icplb(void) | ||
70 | { | ||
71 | unsigned long ctrl; | ||
72 | SSYNC(); | ||
73 | ctrl = bfin_read_IMEM_CONTROL(); | ||
74 | ctrl |= ENICPLB; | ||
75 | bfin_write_IMEM_CONTROL(ctrl); | ||
76 | SSYNC(); | ||
77 | } | ||
78 | |||
79 | /* | ||
80 | * Given the contents of the status register, return the index of the | ||
81 | * CPLB that caused the fault. | ||
82 | */ | ||
83 | static inline int faulting_cplb_index(int status) | ||
84 | { | ||
85 | int signbits = __builtin_bfin_norm_fr1x32(status & 0xFFFF); | ||
86 | return 30 - signbits; | ||
87 | } | ||
88 | |||
89 | /* | ||
90 | * Given the contents of the status register and the DCPLB_DATA contents, | ||
91 | * return true if a write access should be permitted. | ||
92 | */ | ||
93 | static inline int write_permitted(int status, unsigned long data) | ||
94 | { | ||
95 | if (status & FAULT_USERSUPV) | ||
96 | return !!(data & CPLB_SUPV_WR); | ||
97 | else | ||
98 | return !!(data & CPLB_USER_WR); | ||
99 | } | ||
100 | |||
101 | /* Counters to implement round-robin replacement. */ | ||
102 | static int icplb_rr_index, dcplb_rr_index; | ||
103 | |||
104 | /* | ||
105 | * Find an ICPLB entry to be evicted and return its index. | ||
106 | */ | ||
107 | static int evict_one_icplb(void) | ||
108 | { | ||
109 | int i; | ||
110 | for (i = first_switched_icplb; i < MAX_CPLBS; i++) | ||
111 | if ((icplb_tbl[i].data & CPLB_VALID) == 0) | ||
112 | return i; | ||
113 | i = first_switched_icplb + icplb_rr_index; | ||
114 | if (i >= MAX_CPLBS) { | ||
115 | i -= MAX_CPLBS - first_switched_icplb; | ||
116 | icplb_rr_index -= MAX_CPLBS - first_switched_icplb; | ||
117 | } | ||
118 | icplb_rr_index++; | ||
119 | return i; | ||
120 | } | ||
121 | |||
122 | static int evict_one_dcplb(void) | ||
123 | { | ||
124 | int i; | ||
125 | for (i = first_switched_dcplb; i < MAX_CPLBS; i++) | ||
126 | if ((dcplb_tbl[i].data & CPLB_VALID) == 0) | ||
127 | return i; | ||
128 | i = first_switched_dcplb + dcplb_rr_index; | ||
129 | if (i >= MAX_CPLBS) { | ||
130 | i -= MAX_CPLBS - first_switched_dcplb; | ||
131 | dcplb_rr_index -= MAX_CPLBS - first_switched_dcplb; | ||
132 | } | ||
133 | dcplb_rr_index++; | ||
134 | return i; | ||
135 | } | ||
136 | |||
137 | static noinline int dcplb_miss(void) | ||
138 | { | ||
139 | unsigned long addr = bfin_read_DCPLB_FAULT_ADDR(); | ||
140 | int status = bfin_read_DCPLB_STATUS(); | ||
141 | unsigned long *mask; | ||
142 | int idx; | ||
143 | unsigned long d_data; | ||
144 | |||
145 | nr_dcplb_miss++; | ||
146 | if (addr >= _ramend) | ||
147 | return CPLB_PROT_VIOL; | ||
148 | |||
149 | d_data = CPLB_SUPV_WR | CPLB_VALID | CPLB_DIRTY | PAGE_SIZE_4KB; | ||
150 | #ifdef CONFIG_BFIN_DCACHE | ||
151 | d_data |= CPLB_L1_CHBL | ANOMALY_05000158_WORKAROUND; | ||
152 | #ifdef CONFIG_BLKFIN_WT | ||
153 | d_data |= CPLB_L1_AOW | CPLB_WT; | ||
154 | #endif | ||
155 | #endif | ||
156 | mask = current_rwx_mask; | ||
157 | if (mask) { | ||
158 | int page = addr >> PAGE_SHIFT; | ||
159 | int offs = page >> 5; | ||
160 | int bit = 1 << (page & 31); | ||
161 | |||
162 | if (mask[offs] & bit) | ||
163 | d_data |= CPLB_USER_RD; | ||
164 | |||
165 | mask += page_mask_nelts; | ||
166 | if (mask[offs] & bit) | ||
167 | d_data |= CPLB_USER_WR; | ||
168 | } | ||
169 | |||
170 | idx = evict_one_dcplb(); | ||
171 | |||
172 | addr &= PAGE_MASK; | ||
173 | dcplb_tbl[idx].addr = addr; | ||
174 | dcplb_tbl[idx].data = d_data; | ||
175 | |||
176 | disable_dcplb(); | ||
177 | bfin_write32(DCPLB_DATA0 + idx * 4, d_data); | ||
178 | bfin_write32(DCPLB_ADDR0 + idx * 4, addr); | ||
179 | enable_dcplb(); | ||
180 | |||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | static noinline int icplb_miss(void) | ||
185 | { | ||
186 | unsigned long addr = bfin_read_ICPLB_FAULT_ADDR(); | ||
187 | int status = bfin_read_ICPLB_STATUS(); | ||
188 | int idx; | ||
189 | unsigned long i_data; | ||
190 | |||
191 | nr_icplb_miss++; | ||
192 | if (status & FAULT_USERSUPV) | ||
193 | nr_icplb_supv_miss++; | ||
194 | |||
195 | if (addr >= _ramend) | ||
196 | return CPLB_PROT_VIOL; | ||
197 | |||
198 | /* | ||
199 | * First, try to find a CPLB that matches this address. If we | ||
200 | * find one, then the fact that we're in the miss handler means | ||
201 | * that the instruction crosses a page boundary. | ||
202 | */ | ||
203 | for (idx = first_switched_icplb; idx < MAX_CPLBS; idx++) { | ||
204 | if (icplb_tbl[idx].data & CPLB_VALID) { | ||
205 | unsigned long this_addr = icplb_tbl[idx].addr; | ||
206 | if (this_addr <= addr && this_addr + PAGE_SIZE > addr) { | ||
207 | addr += PAGE_SIZE; | ||
208 | break; | ||
209 | } | ||
210 | } | ||
211 | } | ||
212 | |||
213 | i_data = CPLB_VALID | CPLB_PORTPRIO | PAGE_SIZE_4KB; | ||
214 | #ifdef CONFIG_BFIN_ICACHE | ||
215 | i_data |= CPLB_L1_CHBL | ANOMALY_05000158_WORKAROUND; | ||
216 | #endif | ||
217 | |||
218 | /* | ||
219 | * Two cases to distinguish - a supervisor access must necessarily | ||
220 | * be for a module page; we grant it unconditionally (could do better | ||
221 | * here in the future). Otherwise, check the x bitmap of the current | ||
222 | * process. | ||
223 | */ | ||
224 | if (!(status & FAULT_USERSUPV)) { | ||
225 | unsigned long *mask = current_rwx_mask; | ||
226 | |||
227 | if (mask) { | ||
228 | int page = addr >> PAGE_SHIFT; | ||
229 | int offs = page >> 5; | ||
230 | int bit = 1 << (page & 31); | ||
231 | |||
232 | mask += 2 * page_mask_nelts; | ||
233 | if (mask[offs] & bit) | ||
234 | i_data |= CPLB_USER_RD; | ||
235 | } | ||
236 | } | ||
237 | |||
238 | idx = evict_one_icplb(); | ||
239 | addr &= PAGE_MASK; | ||
240 | icplb_tbl[idx].addr = addr; | ||
241 | icplb_tbl[idx].data = i_data; | ||
242 | |||
243 | disable_icplb(); | ||
244 | bfin_write32(ICPLB_DATA0 + idx * 4, i_data); | ||
245 | bfin_write32(ICPLB_ADDR0 + idx * 4, addr); | ||
246 | enable_icplb(); | ||
247 | |||
248 | return 0; | ||
249 | } | ||
250 | |||
251 | static noinline int dcplb_protection_fault(void) | ||
252 | { | ||
253 | unsigned long addr = bfin_read_DCPLB_FAULT_ADDR(); | ||
254 | int status = bfin_read_DCPLB_STATUS(); | ||
255 | |||
256 | nr_dcplb_prot++; | ||
257 | |||
258 | if (status & FAULT_RW) { | ||
259 | int idx = faulting_cplb_index(status); | ||
260 | unsigned long data = dcplb_tbl[idx].data; | ||
261 | if (!(data & CPLB_WT) && !(data & CPLB_DIRTY) && | ||
262 | write_permitted(status, data)) { | ||
263 | data |= CPLB_DIRTY; | ||
264 | dcplb_tbl[idx].data = data; | ||
265 | bfin_write32(DCPLB_DATA0 + idx * 4, data); | ||
266 | return 0; | ||
267 | } | ||
268 | } | ||
269 | return CPLB_PROT_VIOL; | ||
270 | } | ||
271 | |||
272 | int cplb_hdr(int seqstat, struct pt_regs *regs) | ||
273 | { | ||
274 | int cause = seqstat & 0x3f; | ||
275 | switch (cause) { | ||
276 | case 0x23: | ||
277 | return dcplb_protection_fault(); | ||
278 | case 0x2C: | ||
279 | return icplb_miss(); | ||
280 | case 0x26: | ||
281 | return dcplb_miss(); | ||
282 | default: | ||
283 | return 1; | ||
284 | panic_cplb_error(seqstat, regs); | ||
285 | } | ||
286 | } | ||
287 | |||
288 | void flush_switched_cplbs(void) | ||
289 | { | ||
290 | int i; | ||
291 | |||
292 | nr_cplb_flush++; | ||
293 | |||
294 | disable_icplb(); | ||
295 | for (i = first_switched_icplb; i < MAX_CPLBS; i++) { | ||
296 | icplb_tbl[i].data = 0; | ||
297 | bfin_write32(ICPLB_DATA0 + i * 4, 0); | ||
298 | } | ||
299 | enable_icplb(); | ||
300 | |||
301 | disable_dcplb(); | ||
302 | for (i = first_mask_dcplb; i < MAX_CPLBS; i++) { | ||
303 | dcplb_tbl[i].data = 0; | ||
304 | bfin_write32(DCPLB_DATA0 + i * 4, 0); | ||
305 | } | ||
306 | enable_dcplb(); | ||
307 | } | ||
308 | |||
309 | void set_mask_dcplbs(unsigned long *masks) | ||
310 | { | ||
311 | int i; | ||
312 | unsigned long addr = (unsigned long)masks; | ||
313 | unsigned long d_data; | ||
314 | current_rwx_mask = masks; | ||
315 | |||
316 | if (!masks) | ||
317 | return; | ||
318 | |||
319 | d_data = CPLB_SUPV_WR | CPLB_VALID | CPLB_DIRTY | PAGE_SIZE_4KB; | ||
320 | #ifdef CONFIG_BFIN_DCACHE | ||
321 | d_data |= CPLB_L1_CHBL; | ||
322 | #ifdef CONFIG_BLKFIN_WT | ||
323 | d_data |= CPLB_L1_AOW | CPLB_WT; | ||
324 | #endif | ||
325 | #endif | ||
326 | |||
327 | disable_dcplb(); | ||
328 | for (i = first_mask_dcplb; i < first_switched_dcplb; i++) { | ||
329 | dcplb_tbl[i].addr = addr; | ||
330 | dcplb_tbl[i].data = d_data; | ||
331 | bfin_write32(DCPLB_DATA0 + i * 4, d_data); | ||
332 | bfin_write32(DCPLB_ADDR0 + i * 4, addr); | ||
333 | addr += PAGE_SIZE; | ||
334 | } | ||
335 | enable_dcplb(); | ||
336 | } | ||
337 | |||
338 | #endif | ||
diff --git a/arch/blackfin/kernel/cplb-nompu/Makefile b/arch/blackfin/kernel/cplb-nompu/Makefile new file mode 100644 index 000000000000..d36ea9b5382e --- /dev/null +++ b/arch/blackfin/kernel/cplb-nompu/Makefile | |||
@@ -0,0 +1,8 @@ | |||
1 | # | ||
2 | # arch/blackfin/kernel/cplb-nompu/Makefile | ||
3 | # | ||
4 | |||
5 | obj-y := cplbinit.o cacheinit.o cplbhdlr.o cplbmgr.o | ||
6 | |||
7 | obj-$(CONFIG_CPLB_INFO) += cplbinfo.o | ||
8 | |||
diff --git a/arch/blackfin/kernel/cacheinit.c b/arch/blackfin/kernel/cplb-nompu/cacheinit.c index 62cbba7364b0..8a18399f6072 100644 --- a/arch/blackfin/kernel/cacheinit.c +++ b/arch/blackfin/kernel/cplb-nompu/cacheinit.c | |||
@@ -42,6 +42,7 @@ void bfin_icache_init(void) | |||
42 | ctrl = bfin_read_IMEM_CONTROL(); | 42 | ctrl = bfin_read_IMEM_CONTROL(); |
43 | ctrl |= IMC | ENICPLB; | 43 | ctrl |= IMC | ENICPLB; |
44 | bfin_write_IMEM_CONTROL(ctrl); | 44 | bfin_write_IMEM_CONTROL(ctrl); |
45 | SSYNC(); | ||
45 | } | 46 | } |
46 | #endif | 47 | #endif |
47 | 48 | ||
@@ -63,5 +64,6 @@ void bfin_dcache_init(void) | |||
63 | ctrl = bfin_read_DMEM_CONTROL(); | 64 | ctrl = bfin_read_DMEM_CONTROL(); |
64 | ctrl |= DMEM_CNTR; | 65 | ctrl |= DMEM_CNTR; |
65 | bfin_write_DMEM_CONTROL(ctrl); | 66 | bfin_write_DMEM_CONTROL(ctrl); |
67 | SSYNC(); | ||
66 | } | 68 | } |
67 | #endif | 69 | #endif |
diff --git a/arch/blackfin/mach-common/cplbhdlr.S b/arch/blackfin/kernel/cplb-nompu/cplbhdlr.S index 2788532de72b..2788532de72b 100644 --- a/arch/blackfin/mach-common/cplbhdlr.S +++ b/arch/blackfin/kernel/cplb-nompu/cplbhdlr.S | |||
diff --git a/arch/blackfin/mach-common/cplbinfo.c b/arch/blackfin/kernel/cplb-nompu/cplbinfo.c index a4f0b428a34d..a4f0b428a34d 100644 --- a/arch/blackfin/mach-common/cplbinfo.c +++ b/arch/blackfin/kernel/cplb-nompu/cplbinfo.c | |||
diff --git a/arch/blackfin/kernel/cplbinit.c b/arch/blackfin/kernel/cplb-nompu/cplbinit.c index 6320bc45fbba..6320bc45fbba 100644 --- a/arch/blackfin/kernel/cplbinit.c +++ b/arch/blackfin/kernel/cplb-nompu/cplbinit.c | |||
diff --git a/arch/blackfin/mach-common/cplbmgr.S b/arch/blackfin/kernel/cplb-nompu/cplbmgr.S index 6f909cbfac7b..f5cf3accef37 100644 --- a/arch/blackfin/mach-common/cplbmgr.S +++ b/arch/blackfin/kernel/cplb-nompu/cplbmgr.S | |||
@@ -75,6 +75,15 @@ ENTRY(_cplb_mgr) | |||
75 | * from the configuration table. | 75 | * from the configuration table. |
76 | */ | 76 | */ |
77 | 77 | ||
78 | /* A multi-word instruction can cross a page boundary. This means the | ||
79 | * first part of the instruction can be in a valid page, but the | ||
80 | * second part is not, and hence generates the instruction miss. | ||
81 | * However, the fault address is for the start of the instruction, | ||
82 | * not the part that's in the bad page. Therefore, we have to check | ||
83 | * whether the fault address applies to a page that is already present | ||
84 | * in the table. | ||
85 | */ | ||
86 | |||
78 | P4.L = LO(ICPLB_FAULT_ADDR); | 87 | P4.L = LO(ICPLB_FAULT_ADDR); |
79 | P4.H = HI(ICPLB_FAULT_ADDR); | 88 | P4.H = HI(ICPLB_FAULT_ADDR); |
80 | 89 | ||
@@ -87,7 +96,7 @@ ENTRY(_cplb_mgr) | |||
87 | R4 = [P4]; /* Get faulting address*/ | 96 | R4 = [P4]; /* Get faulting address*/ |
88 | R6 = 64; /* Advance past the fault address, which*/ | 97 | R6 = 64; /* Advance past the fault address, which*/ |
89 | R6 = R6 + R4; /* we'll use if we find a match*/ | 98 | R6 = R6 + R4; /* we'll use if we find a match*/ |
90 | R3 = ((16 << 8) | 2); /* Extract mask, bits 16 and 17.*/ | 99 | R3 = ((16 << 8) | 2); /* Extract mask, two bits at posn 16 */ |
91 | 100 | ||
92 | R5 = 0; | 101 | R5 = 0; |
93 | .Lisearch: | 102 | .Lisearch: |
@@ -125,7 +134,9 @@ ENTRY(_cplb_mgr) | |||
125 | P4.L = LO(IMEM_CONTROL); | 134 | P4.L = LO(IMEM_CONTROL); |
126 | P4.H = HI(IMEM_CONTROL); | 135 | P4.H = HI(IMEM_CONTROL); |
127 | 136 | ||
128 | /* disable cplbs */ | 137 | /* Turn off CPLBs while we work, necessary according to HRM before |
138 | * modifying CPLB descriptors | ||
139 | */ | ||
129 | R5 = [P4]; /* Control Register*/ | 140 | R5 = [P4]; /* Control Register*/ |
130 | BITCLR(R5,ENICPLB_P); | 141 | BITCLR(R5,ENICPLB_P); |
131 | CLI R1; | 142 | CLI R1; |
@@ -179,7 +190,14 @@ ENTRY(_cplb_mgr) | |||
179 | [P0 - 4] = R0; | 190 | [P0 - 4] = R0; |
180 | R0 = [P0 - 0x100]; | 191 | R0 = [P0 - 0x100]; |
181 | [P0-0x104] = R0; | 192 | [P0-0x104] = R0; |
182 | .Lie_move:P0+=4; | 193 | .Lie_move: |
194 | P0+=4; | ||
195 | |||
196 | /* Clear ICPLB_DATA15, in case we don't find a replacement | ||
197 | * otherwise, we would have a duplicate entry, and will crash | ||
198 | */ | ||
199 | R0 = 0; | ||
200 | [P0 - 4] = R0; | ||
183 | 201 | ||
184 | /* We've made space in the ICPLB table, so that ICPLB15 | 202 | /* We've made space in the ICPLB table, so that ICPLB15 |
185 | * is now free to be overwritten. Next, we have to determine | 203 | * is now free to be overwritten. Next, we have to determine |
@@ -504,14 +522,23 @@ ENTRY(_cplb_mgr) | |||
504 | R0 = [P0++]; /* move data */ | 522 | R0 = [P0++]; /* move data */ |
505 | [P0 - 8] = R0; | 523 | [P0 - 8] = R0; |
506 | R0 = [P0-0x104] /* move address */ | 524 | R0 = [P0-0x104] /* move address */ |
507 | .Lde_move: [P0-0x108] = R0; | 525 | .Lde_move: |
526 | [P0-0x108] = R0; | ||
527 | |||
528 | .Lde_moved: | ||
529 | NOP; | ||
530 | |||
531 | /* Clear DCPLB_DATA15, in case we don't find a replacement | ||
532 | * otherwise, we would have a duplicate entry, and will crash | ||
533 | */ | ||
534 | R0 = 0; | ||
535 | [P0 - 0x4] = R0; | ||
508 | 536 | ||
509 | /* We've now made space in DCPLB15 for the new CPLB to be | 537 | /* We've now made space in DCPLB15 for the new CPLB to be |
510 | * installed. The next stage is to locate a CPLB in the | 538 | * installed. The next stage is to locate a CPLB in the |
511 | * config table that covers the faulting address. | 539 | * config table that covers the faulting address. |
512 | */ | 540 | */ |
513 | 541 | ||
514 | .Lde_moved:NOP; | ||
515 | R0 = I0; /* Our faulting address */ | 542 | R0 = I0; /* Our faulting address */ |
516 | 543 | ||
517 | P2.L = _dpdt_table; | 544 | P2.L = _dpdt_table; |
diff --git a/arch/blackfin/kernel/early_printk.c b/arch/blackfin/kernel/early_printk.c index 724f4a5a1d46..60f67f90fe35 100644 --- a/arch/blackfin/kernel/early_printk.c +++ b/arch/blackfin/kernel/early_printk.c | |||
@@ -187,7 +187,7 @@ asmlinkage void __init init_early_exception_vectors(void) | |||
187 | bfin_write_EVT15(early_trap); | 187 | bfin_write_EVT15(early_trap); |
188 | CSYNC(); | 188 | CSYNC(); |
189 | 189 | ||
190 | /* Set all the return from interupt, exception, NMI to a known place | 190 | /* Set all the return from interrupt, exception, NMI to a known place |
191 | * so if we do a RETI, RETX or RETN by mistake - we go somewhere known | 191 | * so if we do a RETI, RETX or RETN by mistake - we go somewhere known |
192 | * Note - don't change RETS - we are in a subroutine, or | 192 | * Note - don't change RETS - we are in a subroutine, or |
193 | * RETE - since it might screw up if emulator is attached | 193 | * RETE - since it might screw up if emulator is attached |
@@ -205,7 +205,7 @@ asmlinkage void __init early_trap_c(struct pt_regs *fp, void *retaddr) | |||
205 | if (likely(early_console == NULL)) | 205 | if (likely(early_console == NULL)) |
206 | setup_early_printk(DEFAULT_EARLY_PORT); | 206 | setup_early_printk(DEFAULT_EARLY_PORT); |
207 | 207 | ||
208 | dump_bfin_mem((void *)fp->retx); | 208 | dump_bfin_mem(fp); |
209 | show_regs(fp); | 209 | show_regs(fp); |
210 | dump_bfin_trace_buffer(); | 210 | dump_bfin_trace_buffer(); |
211 | 211 | ||
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c index 5bf15125f0d6..023dc80af187 100644 --- a/arch/blackfin/kernel/process.c +++ b/arch/blackfin/kernel/process.c | |||
@@ -39,9 +39,6 @@ | |||
39 | #include <asm/blackfin.h> | 39 | #include <asm/blackfin.h> |
40 | #include <asm/fixed_code.h> | 40 | #include <asm/fixed_code.h> |
41 | 41 | ||
42 | #define LED_ON 0 | ||
43 | #define LED_OFF 1 | ||
44 | |||
45 | asmlinkage void ret_from_fork(void); | 42 | asmlinkage void ret_from_fork(void); |
46 | 43 | ||
47 | /* Points to the SDRAM backup memory for the stack that is currently in | 44 | /* Points to the SDRAM backup memory for the stack that is currently in |
@@ -70,32 +67,6 @@ void (*pm_power_off)(void) = NULL; | |||
70 | EXPORT_SYMBOL(pm_power_off); | 67 | EXPORT_SYMBOL(pm_power_off); |
71 | 68 | ||
72 | /* | 69 | /* |
73 | * We are using a different LED from the one used to indicate timer interrupt. | ||
74 | */ | ||
75 | #if defined(CONFIG_BFIN_IDLE_LED) | ||
76 | static inline void leds_switch(int flag) | ||
77 | { | ||
78 | unsigned short tmp = 0; | ||
79 | |||
80 | tmp = bfin_read_CONFIG_BFIN_IDLE_LED_PORT(); | ||
81 | SSYNC(); | ||
82 | |||
83 | if (flag == LED_ON) | ||
84 | tmp &= ~CONFIG_BFIN_IDLE_LED_PIN; /* light on */ | ||
85 | else | ||
86 | tmp |= CONFIG_BFIN_IDLE_LED_PIN; /* light off */ | ||
87 | |||
88 | bfin_write_CONFIG_BFIN_IDLE_LED_PORT(tmp); | ||
89 | SSYNC(); | ||
90 | |||
91 | } | ||
92 | #else | ||
93 | static inline void leds_switch(int flag) | ||
94 | { | ||
95 | } | ||
96 | #endif | ||
97 | |||
98 | /* | ||
99 | * The idle loop on BFIN | 70 | * The idle loop on BFIN |
100 | */ | 71 | */ |
101 | #ifdef CONFIG_IDLE_L1 | 72 | #ifdef CONFIG_IDLE_L1 |
@@ -106,12 +77,10 @@ void cpu_idle(void)__attribute__((l1_text)); | |||
106 | void default_idle(void) | 77 | void default_idle(void) |
107 | { | 78 | { |
108 | while (!need_resched()) { | 79 | while (!need_resched()) { |
109 | leds_switch(LED_OFF); | ||
110 | local_irq_disable(); | 80 | local_irq_disable(); |
111 | if (likely(!need_resched())) | 81 | if (likely(!need_resched())) |
112 | idle_with_irq_disabled(); | 82 | idle_with_irq_disabled(); |
113 | local_irq_enable(); | 83 | local_irq_enable(); |
114 | leds_switch(LED_ON); | ||
115 | } | 84 | } |
116 | } | 85 | } |
117 | 86 | ||
@@ -327,6 +296,7 @@ void finish_atomic_sections (struct pt_regs *regs) | |||
327 | } | 296 | } |
328 | 297 | ||
329 | #if defined(CONFIG_ACCESS_CHECK) | 298 | #if defined(CONFIG_ACCESS_CHECK) |
299 | /* Return 1 if access to memory range is OK, 0 otherwise */ | ||
330 | int _access_ok(unsigned long addr, unsigned long size) | 300 | int _access_ok(unsigned long addr, unsigned long size) |
331 | { | 301 | { |
332 | if (size == 0) | 302 | if (size == 0) |
diff --git a/arch/blackfin/kernel/reboot.c b/arch/blackfin/kernel/reboot.c index ae28aac6fec1..483f93dfc1b5 100644 --- a/arch/blackfin/kernel/reboot.c +++ b/arch/blackfin/kernel/reboot.c | |||
@@ -19,6 +19,11 @@ | |||
19 | #define SYSCR_VAL 0x10 | 19 | #define SYSCR_VAL 0x10 |
20 | #endif | 20 | #endif |
21 | 21 | ||
22 | /* | ||
23 | * Delay min 5 SCLK cycles using worst case CCLK/SCLK ratio (15) | ||
24 | */ | ||
25 | #define SWRST_DELAY (5 * 15) | ||
26 | |||
22 | /* A system soft reset makes external memory unusable | 27 | /* A system soft reset makes external memory unusable |
23 | * so force this function into L1. | 28 | * so force this function into L1. |
24 | */ | 29 | */ |
@@ -34,7 +39,13 @@ void bfin_reset(void) | |||
34 | while (1) { | 39 | while (1) { |
35 | /* initiate system soft reset with magic 0x7 */ | 40 | /* initiate system soft reset with magic 0x7 */ |
36 | bfin_write_SWRST(0x7); | 41 | bfin_write_SWRST(0x7); |
37 | asm("ssync;"); | 42 | |
43 | /* Wait for System reset to actually reset, needs to be 5 SCLKs, */ | ||
44 | /* Assume CCLK / SCLK ratio is worst case (15), and use 5*15 */ | ||
45 | |||
46 | asm("LSETUP(.Lfoo,.Lfoo) LC0 = %0\n .Lfoo: NOP;\n" | ||
47 | : : "a" (SWRST_DELAY) : "LC0", "LT0", "LB0"); | ||
48 | |||
38 | /* clear system soft reset */ | 49 | /* clear system soft reset */ |
39 | bfin_write_SWRST(0); | 50 | bfin_write_SWRST(0); |
40 | asm("ssync;"); | 51 | asm("ssync;"); |
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index d2822010b7ce..462cae893757 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c | |||
@@ -238,7 +238,13 @@ void __init setup_arch(char **cmdline_p) | |||
238 | memory_end = _ramend - DMA_UNCACHED_REGION; | 238 | memory_end = _ramend - DMA_UNCACHED_REGION; |
239 | 239 | ||
240 | _ramstart = (unsigned long)__bss_stop; | 240 | _ramstart = (unsigned long)__bss_stop; |
241 | _rambase = (unsigned long)_stext; | ||
242 | #ifdef CONFIG_MPU | ||
243 | /* Round up to multiple of 4MB. */ | ||
244 | memory_start = (_ramstart + 0x3fffff) & ~0x3fffff; | ||
245 | #else | ||
241 | memory_start = PAGE_ALIGN(_ramstart); | 246 | memory_start = PAGE_ALIGN(_ramstart); |
247 | #endif | ||
242 | 248 | ||
243 | #if defined(CONFIG_MTD_UCLINUX) | 249 | #if defined(CONFIG_MTD_UCLINUX) |
244 | /* generic memory mapped MTD driver */ | 250 | /* generic memory mapped MTD driver */ |
@@ -307,6 +313,11 @@ void __init setup_arch(char **cmdline_p) | |||
307 | printk(KERN_NOTICE "Warning: limiting memory to %liMB due to hardware anomaly 05000263\n", memory_end >> 20); | 313 | printk(KERN_NOTICE "Warning: limiting memory to %liMB due to hardware anomaly 05000263\n", memory_end >> 20); |
308 | #endif /* ANOMALY_05000263 */ | 314 | #endif /* ANOMALY_05000263 */ |
309 | 315 | ||
316 | #ifdef CONFIG_MPU | ||
317 | page_mask_nelts = ((_ramend >> PAGE_SHIFT) + 31) / 32; | ||
318 | page_mask_order = get_order(3 * page_mask_nelts * sizeof(long)); | ||
319 | #endif | ||
320 | |||
310 | #if !defined(CONFIG_MTD_UCLINUX) | 321 | #if !defined(CONFIG_MTD_UCLINUX) |
311 | memory_end -= SIZE_4K; /*In case there is no valid CPLB behind memory_end make sure we don't get to close*/ | 322 | memory_end -= SIZE_4K; /*In case there is no valid CPLB behind memory_end make sure we don't get to close*/ |
312 | #endif | 323 | #endif |
@@ -315,8 +326,6 @@ void __init setup_arch(char **cmdline_p) | |||
315 | init_mm.end_data = (unsigned long)_edata; | 326 | init_mm.end_data = (unsigned long)_edata; |
316 | init_mm.brk = (unsigned long)0; | 327 | init_mm.brk = (unsigned long)0; |
317 | 328 | ||
318 | init_leds(); | ||
319 | |||
320 | _bfin_swrst = bfin_read_SWRST(); | 329 | _bfin_swrst = bfin_read_SWRST(); |
321 | 330 | ||
322 | if (_bfin_swrst & RESET_DOUBLE) | 331 | if (_bfin_swrst & RESET_DOUBLE) |
diff --git a/arch/blackfin/kernel/time.c b/arch/blackfin/kernel/time.c index beef057bd1dc..5bd64e341df3 100644 --- a/arch/blackfin/kernel/time.c +++ b/arch/blackfin/kernel/time.c | |||
@@ -42,75 +42,6 @@ | |||
42 | static void time_sched_init(irqreturn_t(*timer_routine) | 42 | static void time_sched_init(irqreturn_t(*timer_routine) |
43 | (int, void *)); | 43 | (int, void *)); |
44 | static unsigned long gettimeoffset(void); | 44 | static unsigned long gettimeoffset(void); |
45 | static inline void do_leds(void); | ||
46 | |||
47 | #if (defined(CONFIG_BFIN_ALIVE_LED) || defined(CONFIG_BFIN_IDLE_LED)) | ||
48 | void __init init_leds(void) | ||
49 | { | ||
50 | unsigned int tmp = 0; | ||
51 | |||
52 | #if defined(CONFIG_BFIN_ALIVE_LED) | ||
53 | /* config pins as output. */ | ||
54 | tmp = bfin_read_CONFIG_BFIN_ALIVE_LED_DPORT(); | ||
55 | SSYNC(); | ||
56 | bfin_write_CONFIG_BFIN_ALIVE_LED_DPORT(tmp | CONFIG_BFIN_ALIVE_LED_PIN); | ||
57 | SSYNC(); | ||
58 | |||
59 | /* First set led be off */ | ||
60 | tmp = bfin_read_CONFIG_BFIN_ALIVE_LED_PORT(); | ||
61 | SSYNC(); | ||
62 | bfin_write_CONFIG_BFIN_ALIVE_LED_PORT(tmp | CONFIG_BFIN_ALIVE_LED_PIN); /* light off */ | ||
63 | SSYNC(); | ||
64 | #endif | ||
65 | |||
66 | #if defined(CONFIG_BFIN_IDLE_LED) | ||
67 | /* config pins as output. */ | ||
68 | tmp = bfin_read_CONFIG_BFIN_IDLE_LED_DPORT(); | ||
69 | SSYNC(); | ||
70 | bfin_write_CONFIG_BFIN_IDLE_LED_DPORT(tmp | CONFIG_BFIN_IDLE_LED_PIN); | ||
71 | SSYNC(); | ||
72 | |||
73 | /* First set led be off */ | ||
74 | tmp = bfin_read_CONFIG_BFIN_IDLE_LED_PORT(); | ||
75 | SSYNC(); | ||
76 | bfin_write_CONFIG_BFIN_IDLE_LED_PORT(tmp | CONFIG_BFIN_IDLE_LED_PIN); /* light off */ | ||
77 | SSYNC(); | ||
78 | #endif | ||
79 | } | ||
80 | #else | ||
81 | void __init init_leds(void) | ||
82 | { | ||
83 | } | ||
84 | #endif | ||
85 | |||
86 | #if defined(CONFIG_BFIN_ALIVE_LED) | ||
87 | static inline void do_leds(void) | ||
88 | { | ||
89 | static unsigned int count = 50; | ||
90 | static int flag; | ||
91 | unsigned short tmp = 0; | ||
92 | |||
93 | if (--count == 0) { | ||
94 | count = 50; | ||
95 | flag = ~flag; | ||
96 | } | ||
97 | tmp = bfin_read_CONFIG_BFIN_ALIVE_LED_PORT(); | ||
98 | SSYNC(); | ||
99 | |||
100 | if (flag) | ||
101 | tmp &= ~CONFIG_BFIN_ALIVE_LED_PIN; /* light on */ | ||
102 | else | ||
103 | tmp |= CONFIG_BFIN_ALIVE_LED_PIN; /* light off */ | ||
104 | |||
105 | bfin_write_CONFIG_BFIN_ALIVE_LED_PORT(tmp); | ||
106 | SSYNC(); | ||
107 | |||
108 | } | ||
109 | #else | ||
110 | static inline void do_leds(void) | ||
111 | { | ||
112 | } | ||
113 | #endif | ||
114 | 45 | ||
115 | static struct irqaction bfin_timer_irq = { | 46 | static struct irqaction bfin_timer_irq = { |
116 | .name = "BFIN Timer Tick", | 47 | .name = "BFIN Timer Tick", |
@@ -205,7 +136,6 @@ irqreturn_t timer_interrupt(int irq, void *dummy) | |||
205 | write_seqlock(&xtime_lock); | 136 | write_seqlock(&xtime_lock); |
206 | 137 | ||
207 | do_timer(1); | 138 | do_timer(1); |
208 | do_leds(); | ||
209 | 139 | ||
210 | #ifndef CONFIG_SMP | 140 | #ifndef CONFIG_SMP |
211 | update_process_times(user_mode(get_irq_regs())); | 141 | update_process_times(user_mode(get_irq_regs())); |
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index 21a55ef19cbd..66b5f3e3ae2a 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c | |||
@@ -36,8 +36,10 @@ | |||
36 | #include <asm/cacheflush.h> | 36 | #include <asm/cacheflush.h> |
37 | #include <asm/blackfin.h> | 37 | #include <asm/blackfin.h> |
38 | #include <asm/irq_handler.h> | 38 | #include <asm/irq_handler.h> |
39 | #include <linux/irq.h> | ||
39 | #include <asm/trace.h> | 40 | #include <asm/trace.h> |
40 | #include <asm/fixed_code.h> | 41 | #include <asm/fixed_code.h> |
42 | #include <asm/dma.h> | ||
41 | 43 | ||
42 | #ifdef CONFIG_KGDB | 44 | #ifdef CONFIG_KGDB |
43 | # include <linux/debugger.h> | 45 | # include <linux/debugger.h> |
@@ -170,7 +172,7 @@ asmlinkage void double_fault_c(struct pt_regs *fp) | |||
170 | oops_in_progress = 1; | 172 | oops_in_progress = 1; |
171 | printk(KERN_EMERG "\n" KERN_EMERG "Double Fault\n"); | 173 | printk(KERN_EMERG "\n" KERN_EMERG "Double Fault\n"); |
172 | dump_bfin_process(fp); | 174 | dump_bfin_process(fp); |
173 | dump_bfin_mem((void *)fp->retx); | 175 | dump_bfin_mem(fp); |
174 | show_regs(fp); | 176 | show_regs(fp); |
175 | panic("Double Fault - unrecoverable event\n"); | 177 | panic("Double Fault - unrecoverable event\n"); |
176 | 178 | ||
@@ -195,9 +197,13 @@ asmlinkage void trap_c(struct pt_regs *fp) | |||
195 | * we will kernel panic, so the system reboots. | 197 | * we will kernel panic, so the system reboots. |
196 | * If KGDB is enabled, don't set this for kernel breakpoints | 198 | * If KGDB is enabled, don't set this for kernel breakpoints |
197 | */ | 199 | */ |
198 | if ((bfin_read_IPEND() & 0xFFC0) | 200 | |
201 | /* TODO: check to see if we are in some sort of deferred HWERR | ||
202 | * that we should be able to recover from, not kernel panic | ||
203 | */ | ||
204 | if ((bfin_read_IPEND() & 0xFFC0) && (trapnr != VEC_STEP) | ||
199 | #ifdef CONFIG_KGDB | 205 | #ifdef CONFIG_KGDB |
200 | && trapnr != VEC_EXCPT02 | 206 | && (trapnr != VEC_EXCPT02) |
201 | #endif | 207 | #endif |
202 | ){ | 208 | ){ |
203 | console_verbose(); | 209 | console_verbose(); |
@@ -433,6 +439,36 @@ asmlinkage void trap_c(struct pt_regs *fp) | |||
433 | /* 0x3D - Reserved, Caught by default */ | 439 | /* 0x3D - Reserved, Caught by default */ |
434 | /* 0x3E - Reserved, Caught by default */ | 440 | /* 0x3E - Reserved, Caught by default */ |
435 | /* 0x3F - Reserved, Caught by default */ | 441 | /* 0x3F - Reserved, Caught by default */ |
442 | case VEC_HWERR: | ||
443 | info.si_code = BUS_ADRALN; | ||
444 | sig = SIGBUS; | ||
445 | switch (fp->seqstat & SEQSTAT_HWERRCAUSE) { | ||
446 | /* System MMR Error */ | ||
447 | case (SEQSTAT_HWERRCAUSE_SYSTEM_MMR): | ||
448 | info.si_code = BUS_ADRALN; | ||
449 | sig = SIGBUS; | ||
450 | printk(KERN_NOTICE HWC_x2(KERN_NOTICE)); | ||
451 | break; | ||
452 | /* External Memory Addressing Error */ | ||
453 | case (SEQSTAT_HWERRCAUSE_EXTERN_ADDR): | ||
454 | info.si_code = BUS_ADRERR; | ||
455 | sig = SIGBUS; | ||
456 | printk(KERN_NOTICE HWC_x3(KERN_NOTICE)); | ||
457 | break; | ||
458 | /* Performance Monitor Overflow */ | ||
459 | case (SEQSTAT_HWERRCAUSE_PERF_FLOW): | ||
460 | printk(KERN_NOTICE HWC_x12(KERN_NOTICE)); | ||
461 | break; | ||
462 | /* RAISE 5 instruction */ | ||
463 | case (SEQSTAT_HWERRCAUSE_RAISE_5): | ||
464 | printk(KERN_NOTICE HWC_x18(KERN_NOTICE)); | ||
465 | break; | ||
466 | default: /* Reserved */ | ||
467 | printk(KERN_NOTICE HWC_default(KERN_NOTICE)); | ||
468 | break; | ||
469 | } | ||
470 | CHK_DEBUGGER_TRAP(); | ||
471 | break; | ||
436 | default: | 472 | default: |
437 | info.si_code = TRAP_ILLTRAP; | 473 | info.si_code = TRAP_ILLTRAP; |
438 | sig = SIGTRAP; | 474 | sig = SIGTRAP; |
@@ -447,7 +483,7 @@ asmlinkage void trap_c(struct pt_regs *fp) | |||
447 | if (sig != SIGTRAP) { | 483 | if (sig != SIGTRAP) { |
448 | unsigned long stack; | 484 | unsigned long stack; |
449 | dump_bfin_process(fp); | 485 | dump_bfin_process(fp); |
450 | dump_bfin_mem((void *)fp->retx); | 486 | dump_bfin_mem(fp); |
451 | show_regs(fp); | 487 | show_regs(fp); |
452 | 488 | ||
453 | /* Print out the trace buffer if it makes sense */ | 489 | /* Print out the trace buffer if it makes sense */ |
@@ -461,6 +497,7 @@ asmlinkage void trap_c(struct pt_regs *fp) | |||
461 | dump_bfin_trace_buffer(); | 497 | dump_bfin_trace_buffer(); |
462 | show_stack(current, &stack); | 498 | show_stack(current, &stack); |
463 | if (oops_in_progress) { | 499 | if (oops_in_progress) { |
500 | print_modules(); | ||
464 | #ifndef CONFIG_ACCESS_CHECK | 501 | #ifndef CONFIG_ACCESS_CHECK |
465 | printk(KERN_EMERG "Please turn on " | 502 | printk(KERN_EMERG "Please turn on " |
466 | "CONFIG_ACCESS_CHECK\n"); | 503 | "CONFIG_ACCESS_CHECK\n"); |
@@ -474,13 +511,6 @@ asmlinkage void trap_c(struct pt_regs *fp) | |||
474 | info.si_addr = (void *)fp->pc; | 511 | info.si_addr = (void *)fp->pc; |
475 | force_sig_info(sig, &info, current); | 512 | force_sig_info(sig, &info, current); |
476 | 513 | ||
477 | /* Ensure that bad return addresses don't end up in an infinite | ||
478 | * loop, due to speculative loads/reads. This needs to be done after | ||
479 | * the signal has been sent. | ||
480 | */ | ||
481 | if (trapnr == VEC_CPLB_I_M && sig != SIGTRAP) | ||
482 | fp->pc = SAFE_USER_INSTRUCTION; | ||
483 | |||
484 | trace_buffer_restore(j); | 514 | trace_buffer_restore(j); |
485 | return; | 515 | return; |
486 | } | 516 | } |
@@ -616,8 +646,10 @@ void dump_bfin_process(struct pt_regs *fp) | |||
616 | if (oops_in_progress) | 646 | if (oops_in_progress) |
617 | printk(KERN_EMERG "Kernel OOPS in progress\n"); | 647 | printk(KERN_EMERG "Kernel OOPS in progress\n"); |
618 | 648 | ||
619 | if (context & 0x0020) | 649 | if (context & 0x0020 && (fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) |
620 | printk(KERN_NOTICE "Deferred excecption or HW Error context\n"); | 650 | printk(KERN_NOTICE "HW Error context\n"); |
651 | else if (context & 0x0020) | ||
652 | printk(KERN_NOTICE "Defered Exception context\n"); | ||
621 | else if (context & 0x3FC0) | 653 | else if (context & 0x3FC0) |
622 | printk(KERN_NOTICE "Interrupt context\n"); | 654 | printk(KERN_NOTICE "Interrupt context\n"); |
623 | else if (context & 0x4000) | 655 | else if (context & 0x4000) |
@@ -645,59 +677,124 @@ void dump_bfin_process(struct pt_regs *fp) | |||
645 | "No Valid process in current context\n"); | 677 | "No Valid process in current context\n"); |
646 | } | 678 | } |
647 | 679 | ||
648 | void dump_bfin_mem(void *retaddr) | 680 | void dump_bfin_mem(struct pt_regs *fp) |
649 | { | 681 | { |
682 | unsigned short *addr, *erraddr, val = 0, err = 0; | ||
683 | char sti = 0, buf[6]; | ||
650 | 684 | ||
651 | if (retaddr >= (void *)FIXED_CODE_START && retaddr < (void *)physical_mem_end | 685 | if (unlikely((fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR)) |
652 | #if L1_CODE_LENGTH != 0 | 686 | erraddr = (void *)fp->pc; |
653 | /* FIXME: Copy the code out of L1 Instruction SRAM through dma | 687 | else |
654 | memcpy. */ | 688 | erraddr = (void *)fp->retx; |
655 | && !(retaddr >= (void *)L1_CODE_START | 689 | |
656 | && retaddr < (void *)(L1_CODE_START + L1_CODE_LENGTH)) | 690 | printk(KERN_NOTICE "return address: [0x%p]; contents of:", erraddr); |
657 | #endif | 691 | |
658 | ) { | 692 | for (addr = (unsigned short *)((unsigned long)erraddr & ~0xF) - 0x10; |
659 | int i = ((unsigned int)retaddr & 0xFFFFFFF0) - 32; | 693 | addr < (unsigned short *)((unsigned long)erraddr & ~0xF) + 0x10; |
660 | unsigned short x = 0; | 694 | addr++) { |
661 | printk(KERN_NOTICE "return address: [0x%p]; contents of:", retaddr); | 695 | if (!((unsigned long)addr & 0xF)) |
662 | for (; i < ((unsigned int)retaddr & 0xFFFFFFF0) + 32; i += 2) { | 696 | printk("\n" KERN_NOTICE "0x%p: ", addr); |
663 | if (!(i & 0xF)) | 697 | |
664 | printk("\n" KERN_NOTICE "0x%08x: ", i); | 698 | if (get_user(val, addr)) { |
665 | 699 | if (addr >= (unsigned short *)L1_CODE_START && | |
666 | if (get_user(x, (unsigned short *)i)) | 700 | addr < (unsigned short *)(L1_CODE_START + L1_CODE_LENGTH)) { |
667 | break; | 701 | dma_memcpy(&val, addr, sizeof(val)); |
702 | sprintf(buf, "%04x", val); | ||
703 | } else if (addr >= (unsigned short *)FIXED_CODE_START && | ||
704 | addr <= (unsigned short *)memory_start) { | ||
705 | val = bfin_read16(addr); | ||
706 | sprintf(buf, "%04x", val); | ||
707 | } else { | ||
708 | val = 0; | ||
709 | sprintf(buf, "????"); | ||
710 | } | ||
711 | } else | ||
712 | sprintf(buf, "%04x", val); | ||
713 | |||
714 | if (addr == erraddr) { | ||
715 | printk("[%s]", buf); | ||
716 | err = val; | ||
717 | } else | ||
718 | printk(" %s ", buf); | ||
719 | |||
720 | /* Do any previous instructions turn on interrupts? */ | ||
721 | if (addr <= erraddr && /* in the past */ | ||
722 | ((val >= 0x0040 && val <= 0x0047) || /* STI instruction */ | ||
723 | val == 0x017b)) /* [SP++] = RETI */ | ||
724 | sti = 1; | ||
725 | } | ||
726 | |||
727 | printk("\n"); | ||
728 | |||
729 | /* Hardware error interrupts can be deferred */ | ||
730 | if (unlikely(sti && (fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR && | ||
731 | oops_in_progress)){ | ||
732 | printk(KERN_NOTICE "Looks like this was a deferred error - sorry\n"); | ||
668 | #ifndef CONFIG_DEBUG_HWERR | 733 | #ifndef CONFIG_DEBUG_HWERR |
669 | /* If one of the last few instructions was a STI | 734 | printk(KERN_NOTICE "The remaining message may be meaningless\n" |
670 | * it is likely that the error occured awhile ago | 735 | KERN_NOTICE "You should enable CONFIG_DEBUG_HWERR to get a" |
671 | * and we just noticed. This only happens in kernel | 736 | " better idea where it came from\n"); |
672 | * context, which should mean an oops is happening | 737 | #else |
673 | */ | 738 | /* If we are handling only one peripheral interrupt |
674 | if (oops_in_progress && x >= 0x0040 && x <= 0x0047 && i <= 0) | 739 | * and current mm and pid are valid, and the last error |
675 | panic("\n\nWARNING : You should reconfigure" | 740 | * was in that user space process's text area |
676 | " the kernel to turn on\n" | 741 | * print it out - because that is where the problem exists |
677 | " 'Hardware error interrupt" | 742 | */ |
678 | " debugging'\n" | 743 | if ((!(((fp)->ipend & ~0x30) & (((fp)->ipend & ~0x30) - 1))) && |
679 | " The rest of this error" | 744 | (current->pid && current->mm)) { |
680 | " is meanless\n"); | 745 | /* And the last RETI points to the current userspace context */ |
681 | #endif | 746 | if ((fp + 1)->pc >= current->mm->start_code && |
682 | if (i == (unsigned int)retaddr) | 747 | (fp + 1)->pc <= current->mm->end_code) { |
683 | printk("[%04x]", x); | 748 | printk(KERN_NOTICE "It might be better to look around here : \n"); |
684 | else | 749 | printk(KERN_NOTICE "-------------------------------------------\n"); |
685 | printk(" %04x ", x); | 750 | show_regs(fp + 1); |
751 | printk(KERN_NOTICE "-------------------------------------------\n"); | ||
752 | } | ||
686 | } | 753 | } |
687 | printk("\n"); | 754 | #endif |
688 | } else | 755 | } |
689 | printk("\n" KERN_NOTICE | ||
690 | "Cannot look at the [PC] <%p> for it is" | ||
691 | " in unreadable memory - sorry\n", retaddr); | ||
692 | } | 756 | } |
693 | 757 | ||
694 | void show_regs(struct pt_regs *fp) | 758 | void show_regs(struct pt_regs *fp) |
695 | { | 759 | { |
696 | char buf [150]; | 760 | char buf [150]; |
761 | struct irqaction *action; | ||
762 | unsigned int i; | ||
763 | unsigned long flags; | ||
697 | 764 | ||
698 | printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\n"); | 765 | printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\t\t%s\n", print_tainted()); |
699 | printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n", | 766 | printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n", |
700 | (long)fp->seqstat, fp->ipend, fp->syscfg); | 767 | (long)fp->seqstat, fp->ipend, fp->syscfg); |
768 | printk(KERN_NOTICE " HWERRCAUSE: 0x%lx\n", | ||
769 | (fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14); | ||
770 | printk(KERN_NOTICE " EXCAUSE : 0x%lx\n", | ||
771 | fp->seqstat & SEQSTAT_EXCAUSE); | ||
772 | for (i = 6; i <= 15 ; i++) { | ||
773 | if (fp->ipend & (1 << i)) { | ||
774 | decode_address(buf, bfin_read32(EVT0 + 4*i)); | ||
775 | printk(KERN_NOTICE " physical IVG%i asserted : %s\n", i, buf); | ||
776 | } | ||
777 | } | ||
778 | |||
779 | /* if no interrupts are going off, don't print this out */ | ||
780 | if (fp->ipend & ~0x3F) { | ||
781 | for (i = 0; i < (NR_IRQS - 1); i++) { | ||
782 | spin_lock_irqsave(&irq_desc[i].lock, flags); | ||
783 | action = irq_desc[i].action; | ||
784 | if (!action) | ||
785 | goto unlock; | ||
786 | |||
787 | decode_address(buf, (unsigned int)action->handler); | ||
788 | printk(KERN_NOTICE " logical irq %3d mapped : %s", i, buf); | ||
789 | for (action = action->next; action; action = action->next) { | ||
790 | decode_address(buf, (unsigned int)action->handler); | ||
791 | printk(", %s", buf); | ||
792 | } | ||
793 | printk("\n"); | ||
794 | unlock: | ||
795 | spin_unlock_irqrestore(&irq_desc[i].lock, flags); | ||
796 | } | ||
797 | } | ||
701 | 798 | ||
702 | decode_address(buf, fp->rete); | 799 | decode_address(buf, fp->rete); |
703 | printk(KERN_NOTICE " RETE: %s\n", buf); | 800 | printk(KERN_NOTICE " RETE: %s\n", buf); |
@@ -708,9 +805,10 @@ void show_regs(struct pt_regs *fp) | |||
708 | decode_address(buf, fp->rets); | 805 | decode_address(buf, fp->rets); |
709 | printk(KERN_NOTICE " RETS: %s\n", buf); | 806 | printk(KERN_NOTICE " RETS: %s\n", buf); |
710 | decode_address(buf, fp->pc); | 807 | decode_address(buf, fp->pc); |
711 | printk(KERN_NOTICE " PC: %s\n", buf); | 808 | printk(KERN_NOTICE " PC : %s\n", buf); |
712 | 809 | ||
713 | if ((long)fp->seqstat & SEQSTAT_EXCAUSE) { | 810 | if (((long)fp->seqstat & SEQSTAT_EXCAUSE) && |
811 | (((long)fp->seqstat & SEQSTAT_EXCAUSE) != VEC_HWERR)) { | ||
714 | decode_address(buf, bfin_read_DCPLB_FAULT_ADDR()); | 812 | decode_address(buf, bfin_read_DCPLB_FAULT_ADDR()); |
715 | printk(KERN_NOTICE "DCPLB_FAULT_ADDR: %s\n", buf); | 813 | printk(KERN_NOTICE "DCPLB_FAULT_ADDR: %s\n", buf); |
716 | decode_address(buf, bfin_read_ICPLB_FAULT_ADDR()); | 814 | decode_address(buf, bfin_read_ICPLB_FAULT_ADDR()); |
@@ -824,7 +922,7 @@ void panic_cplb_error(int cplb_panic, struct pt_regs *fp) | |||
824 | printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n", (void *)bfin_read_DCPLB_FAULT_ADDR()); | 922 | printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n", (void *)bfin_read_DCPLB_FAULT_ADDR()); |
825 | printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n", (void *)bfin_read_ICPLB_FAULT_ADDR()); | 923 | printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n", (void *)bfin_read_ICPLB_FAULT_ADDR()); |
826 | dump_bfin_process(fp); | 924 | dump_bfin_process(fp); |
827 | dump_bfin_mem((void *)fp->retx); | 925 | dump_bfin_mem(fp); |
828 | show_regs(fp); | 926 | show_regs(fp); |
829 | dump_stack(); | 927 | dump_stack(); |
830 | panic("Unrecoverable event\n"); | 928 | panic("Unrecoverable event\n"); |
diff --git a/arch/blackfin/lib/memcpy.S b/arch/blackfin/lib/memcpy.S index 2e6336492b4b..e654a18a0754 100644 --- a/arch/blackfin/lib/memcpy.S +++ b/arch/blackfin/lib/memcpy.S | |||
@@ -70,8 +70,8 @@ ENTRY(_memcpy) | |||
70 | /* Check for aligned data.*/ | 70 | /* Check for aligned data.*/ |
71 | 71 | ||
72 | R3 = R1 | R0; | 72 | R3 = R1 | R0; |
73 | R0 = 0x3; | 73 | R1 = 0x3; |
74 | R3 = R3 & R0; | 74 | R3 = R3 & R1; |
75 | CC = R3; /* low bits set on either address? */ | 75 | CC = R3; /* low bits set on either address? */ |
76 | IF CC JUMP .Lnot_aligned; | 76 | IF CC JUMP .Lnot_aligned; |
77 | 77 | ||
@@ -83,7 +83,6 @@ ENTRY(_memcpy) | |||
83 | /* less than eight bytes... */ | 83 | /* less than eight bytes... */ |
84 | P2 = R2; | 84 | P2 = R2; |
85 | LSETUP(.Lthree_start, .Lthree_end) LC0=P2; | 85 | LSETUP(.Lthree_start, .Lthree_end) LC0=P2; |
86 | R0 = R1; /* setup src address for return */ | ||
87 | .Lthree_start: | 86 | .Lthree_start: |
88 | R3 = B[P1++] (X); | 87 | R3 = B[P1++] (X); |
89 | .Lthree_end: | 88 | .Lthree_end: |
@@ -95,7 +94,6 @@ ENTRY(_memcpy) | |||
95 | /* There's at least eight bytes to copy. */ | 94 | /* There's at least eight bytes to copy. */ |
96 | P2 += -1; /* because we unroll one iteration */ | 95 | P2 += -1; /* because we unroll one iteration */ |
97 | LSETUP(.Lword_loops, .Lword_loope) LC0=P2; | 96 | LSETUP(.Lword_loops, .Lword_loope) LC0=P2; |
98 | R0 = R1; | ||
99 | I1 = P1; | 97 | I1 = P1; |
100 | R3 = [I1++]; | 98 | R3 = [I1++]; |
101 | #if ANOMALY_05000202 | 99 | #if ANOMALY_05000202 |
@@ -120,7 +118,6 @@ ENTRY(_memcpy) | |||
120 | .Lnot_aligned: | 118 | .Lnot_aligned: |
121 | /* From here, we're copying byte-by-byte. */ | 119 | /* From here, we're copying byte-by-byte. */ |
122 | LSETUP (.Lbyte_start, .Lbyte_end) LC0=P2; | 120 | LSETUP (.Lbyte_start, .Lbyte_end) LC0=P2; |
123 | R0 = R1; /* Save src address for return */ | ||
124 | .Lbyte_start: | 121 | .Lbyte_start: |
125 | R1 = B[P1++] (X); | 122 | R1 = B[P1++] (X); |
126 | .Lbyte_end: | 123 | .Lbyte_end: |
@@ -135,7 +132,6 @@ ENTRY(_memcpy) | |||
135 | * Don't bother to work out alignment for | 132 | * Don't bother to work out alignment for |
136 | * the reverse case. | 133 | * the reverse case. |
137 | */ | 134 | */ |
138 | R0 = R1; /* save src for later. */ | ||
139 | P0 = P0 + P2; | 135 | P0 = P0 + P2; |
140 | P0 += -1; | 136 | P0 += -1; |
141 | P1 = P1 + P2; | 137 | P1 = P1 + P2; |
diff --git a/arch/blackfin/mach-bf527/Kconfig b/arch/blackfin/mach-bf527/Kconfig index 5c736837d4bf..3cde4beeb214 100644 --- a/arch/blackfin/mach-bf527/Kconfig +++ b/arch/blackfin/mach-bf527/Kconfig | |||
@@ -43,7 +43,7 @@ endchoice | |||
43 | 43 | ||
44 | choice | 44 | choice |
45 | prompt "UART1" | 45 | prompt "UART1" |
46 | default BF527_UART1_PORTG | 46 | default BF527_UART1_PORTF |
47 | help | 47 | help |
48 | Select PORT used for UART1. See Hardware Reference Manual | 48 | Select PORT used for UART1. See Hardware Reference Manual |
49 | 49 | ||
diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index 003e2ac654d8..f8c411a24af7 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * | 8 | * |
9 | * Modified: | 9 | * Modified: |
10 | * Copyright 2005 National ICT Australia (NICTA) | 10 | * Copyright 2005 National ICT Australia (NICTA) |
11 | * Copyright 2004-2007 Analog Devices Inc. | 11 | * Copyright 2004-2008 Analog Devices Inc. |
12 | * | 12 | * |
13 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | 13 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ |
14 | * | 14 | * |
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/irq.h> | 41 | #include <linux/irq.h> |
42 | #include <linux/interrupt.h> | 42 | #include <linux/interrupt.h> |
43 | #include <linux/usb/sl811.h> | 43 | #include <linux/usb/sl811.h> |
44 | #include <linux/usb/musb.h> | ||
44 | #include <asm/cplb.h> | 45 | #include <asm/cplb.h> |
45 | #include <asm/dma.h> | 46 | #include <asm/dma.h> |
46 | #include <asm/bfin5xx_spi.h> | 47 | #include <asm/bfin5xx_spi.h> |
@@ -105,6 +106,69 @@ void __exit bfin_isp1761_exit(void) | |||
105 | arch_initcall(bfin_isp1761_init); | 106 | arch_initcall(bfin_isp1761_init); |
106 | #endif | 107 | #endif |
107 | 108 | ||
109 | #if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE) | ||
110 | static struct resource musb_resources[] = { | ||
111 | [0] = { | ||
112 | .start = 0xffc03800, | ||
113 | .end = 0xffc03cff, | ||
114 | .flags = IORESOURCE_MEM, | ||
115 | }, | ||
116 | [1] = { /* general IRQ */ | ||
117 | .start = IRQ_USB_INT0, | ||
118 | .end = IRQ_USB_INT0, | ||
119 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, | ||
120 | }, | ||
121 | [2] = { /* DMA IRQ */ | ||
122 | .start = IRQ_USB_DMA, | ||
123 | .end = IRQ_USB_DMA, | ||
124 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, | ||
125 | }, | ||
126 | }; | ||
127 | |||
128 | static struct musb_hdrc_platform_data musb_plat = { | ||
129 | #if defined(CONFIG_USB_MUSB_OTG) | ||
130 | .mode = MUSB_OTG, | ||
131 | #elif defined(CONFIG_USB_MUSB_HDRC_HCD) | ||
132 | .mode = MUSB_HOST, | ||
133 | #elif defined(CONFIG_USB_GADGET_MUSB_HDRC) | ||
134 | .mode = MUSB_PERIPHERAL, | ||
135 | #endif | ||
136 | .multipoint = 0, | ||
137 | }; | ||
138 | |||
139 | static u64 musb_dmamask = ~(u32)0; | ||
140 | |||
141 | static struct platform_device musb_device = { | ||
142 | .name = "musb_hdrc", | ||
143 | .id = 0, | ||
144 | .dev = { | ||
145 | .dma_mask = &musb_dmamask, | ||
146 | .coherent_dma_mask = 0xffffffff, | ||
147 | .platform_data = &musb_plat, | ||
148 | }, | ||
149 | .num_resources = ARRAY_SIZE(musb_resources), | ||
150 | .resource = musb_resources, | ||
151 | }; | ||
152 | #endif | ||
153 | |||
154 | #if defined(CONFIG_FB_BFIN_T350MCQB) || defined(CONFIG_FB_BFIN_T350MCQB_MODULE) | ||
155 | |||
156 | static struct resource bf52x_t350mcqb_resources[] = { | ||
157 | { | ||
158 | .start = IRQ_PPI_ERROR, | ||
159 | .end = IRQ_PPI_ERROR, | ||
160 | .flags = IORESOURCE_IRQ, | ||
161 | }, | ||
162 | }; | ||
163 | |||
164 | static struct platform_device bf52x_t350mcqb_device = { | ||
165 | .name = "bfin-t350mcqb", | ||
166 | .id = -1, | ||
167 | .num_resources = ARRAY_SIZE(bf52x_t350mcqb_resources), | ||
168 | .resource = bf52x_t350mcqb_resources, | ||
169 | }; | ||
170 | #endif | ||
171 | |||
108 | #if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE) | 172 | #if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE) |
109 | static struct mtd_partition partition_info[] = { | 173 | static struct mtd_partition partition_info[] = { |
110 | { | 174 | { |
@@ -253,12 +317,7 @@ static struct resource sl811_hcd_resources[] = { | |||
253 | void sl811_port_power(struct device *dev, int is_on) | 317 | void sl811_port_power(struct device *dev, int is_on) |
254 | { | 318 | { |
255 | gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS"); | 319 | gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS"); |
256 | gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS); | 320 | gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS, is_on); |
257 | |||
258 | if (is_on) | ||
259 | gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 1); | ||
260 | else | ||
261 | gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 0); | ||
262 | } | 321 | } |
263 | #endif | 322 | #endif |
264 | 323 | ||
@@ -718,6 +777,28 @@ static struct platform_device bfin_pata_device = { | |||
718 | }; | 777 | }; |
719 | #endif | 778 | #endif |
720 | 779 | ||
780 | #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) | ||
781 | #include <linux/input.h> | ||
782 | #include <linux/gpio_keys.h> | ||
783 | |||
784 | static struct gpio_keys_button bfin_gpio_keys_table[] = { | ||
785 | {BTN_0, GPIO_PG0, 1, "gpio-keys: BTN0"}, | ||
786 | {BTN_1, GPIO_PG13, 1, "gpio-keys: BTN1"}, | ||
787 | }; | ||
788 | |||
789 | static struct gpio_keys_platform_data bfin_gpio_keys_data = { | ||
790 | .buttons = bfin_gpio_keys_table, | ||
791 | .nbuttons = ARRAY_SIZE(bfin_gpio_keys_table), | ||
792 | }; | ||
793 | |||
794 | static struct platform_device bfin_device_gpiokeys = { | ||
795 | .name = "gpio-keys", | ||
796 | .dev = { | ||
797 | .platform_data = &bfin_gpio_keys_data, | ||
798 | }, | ||
799 | }; | ||
800 | #endif | ||
801 | |||
721 | static struct platform_device *stamp_devices[] __initdata = { | 802 | static struct platform_device *stamp_devices[] __initdata = { |
722 | #if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE) | 803 | #if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE) |
723 | &bf5xx_nand_device, | 804 | &bf5xx_nand_device, |
@@ -739,6 +820,10 @@ static struct platform_device *stamp_devices[] __initdata = { | |||
739 | &isp1362_hcd_device, | 820 | &isp1362_hcd_device, |
740 | #endif | 821 | #endif |
741 | 822 | ||
823 | #if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE) | ||
824 | &musb_device, | ||
825 | #endif | ||
826 | |||
742 | #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) | 827 | #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) |
743 | &smc91x_device, | 828 | &smc91x_device, |
744 | #endif | 829 | #endif |
@@ -763,6 +848,10 @@ static struct platform_device *stamp_devices[] __initdata = { | |||
763 | &bfin_fb_device, | 848 | &bfin_fb_device, |
764 | #endif | 849 | #endif |
765 | 850 | ||
851 | #if defined(CONFIG_FB_BFIN_T350MCQB) || defined(CONFIG_FB_BFIN_T350MCQB_MODULE) | ||
852 | &bf52x_t350mcqb_device, | ||
853 | #endif | ||
854 | |||
766 | #if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE) | 855 | #if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE) |
767 | &bfin_fb_adv7393_device, | 856 | &bfin_fb_adv7393_device, |
768 | #endif | 857 | #endif |
@@ -783,6 +872,10 @@ static struct platform_device *stamp_devices[] __initdata = { | |||
783 | #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) | 872 | #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) |
784 | &bfin_pata_device, | 873 | &bfin_pata_device, |
785 | #endif | 874 | #endif |
875 | |||
876 | #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) | ||
877 | &bfin_device_gpiokeys, | ||
878 | #endif | ||
786 | }; | 879 | }; |
787 | 880 | ||
788 | static int __init stamp_init(void) | 881 | static int __init stamp_init(void) |
diff --git a/arch/blackfin/mach-bf533/boards/H8606.c b/arch/blackfin/mach-bf533/boards/H8606.c index 6bcf4047f89c..a72c7a620fa1 100644 --- a/arch/blackfin/mach-bf533/boards/H8606.c +++ b/arch/blackfin/mach-bf533/boards/H8606.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #endif | 40 | #endif |
41 | #include <linux/pata_platform.h> | 41 | #include <linux/pata_platform.h> |
42 | #include <linux/irq.h> | 42 | #include <linux/irq.h> |
43 | |||
43 | #include <asm/dma.h> | 44 | #include <asm/dma.h> |
44 | #include <asm/bfin5xx_spi.h> | 45 | #include <asm/bfin5xx_spi.h> |
45 | #include <asm/reboot.h> | 46 | #include <asm/reboot.h> |
@@ -303,7 +304,77 @@ static struct platform_device bfin_uart_device = { | |||
303 | }; | 304 | }; |
304 | #endif | 305 | #endif |
305 | 306 | ||
306 | static struct platform_device *stamp_devices[] __initdata = { | 307 | #if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) |
308 | |||
309 | #include <linux/serial_8250.h> | ||
310 | #include <linux/serial.h> | ||
311 | |||
312 | /* | ||
313 | * Configuration for two 16550 UARTS in FPGA at addresses 0x20200000 and 0x202000010. | ||
314 | * running at half system clock, both with interrupt output or-ed to PF8. Change to | ||
315 | * suit different FPGA configuration, or to suit real 16550 UARTS connected to the bus | ||
316 | */ | ||
317 | |||
318 | static struct plat_serial8250_port serial8250_platform_data [] = { | ||
319 | { | ||
320 | .membase = 0x20200000, | ||
321 | .mapbase = 0x20200000, | ||
322 | .irq = IRQ_PF8, | ||
323 | .flags = UPF_BOOT_AUTOCONF | UART_CONFIG_TYPE, | ||
324 | .iotype = UPIO_MEM, | ||
325 | .regshift = 1, | ||
326 | .uartclk = 66666667, | ||
327 | }, { | ||
328 | .membase = 0x20200010, | ||
329 | .mapbase = 0x20200010, | ||
330 | .irq = IRQ_PF8, | ||
331 | .flags = UPF_BOOT_AUTOCONF | UART_CONFIG_TYPE, | ||
332 | .iotype = UPIO_MEM, | ||
333 | .regshift = 1, | ||
334 | .uartclk = 66666667, | ||
335 | }, { | ||
336 | } | ||
337 | }; | ||
338 | |||
339 | static struct platform_device serial8250_device = { | ||
340 | .id = PLAT8250_DEV_PLATFORM, | ||
341 | .name = "serial8250", | ||
342 | .dev = { | ||
343 | .platform_data = serial8250_platform_data, | ||
344 | }, | ||
345 | }; | ||
346 | |||
347 | #endif | ||
348 | |||
349 | #if defined(CONFIG_KEYBOARD_OPENCORES) || defined(CONFIG_KEYBOARD_OPENCORES_MODULE) | ||
350 | |||
351 | /* | ||
352 | * Configuration for one OpenCores keyboard controller in FPGA at address 0x20200030, | ||
353 | * interrupt output wired to PF9. Change to suit different FPGA configuration | ||
354 | */ | ||
355 | |||
356 | static struct resource opencores_kbd_resources[] = { | ||
357 | [0] = { | ||
358 | .start = 0x20200030, | ||
359 | .end = 0x20300030 + 2, | ||
360 | .flags = IORESOURCE_MEM, | ||
361 | }, | ||
362 | [1] = { | ||
363 | .start = IRQ_PF9, | ||
364 | .end = IRQ_PF9, | ||
365 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, | ||
366 | }, | ||
367 | }; | ||
368 | |||
369 | static struct platform_device opencores_kbd_device = { | ||
370 | .id = -1, | ||
371 | .name = "opencores-kbd", | ||
372 | .resource = opencores_kbd_resources, | ||
373 | .num_resources = ARRAY_SIZE(opencores_kbd_resources), | ||
374 | }; | ||
375 | #endif | ||
376 | |||
377 | static struct platform_device *h8606_devices[] __initdata = { | ||
307 | #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) | 378 | #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) |
308 | &rtc_device, | 379 | &rtc_device, |
309 | #endif | 380 | #endif |
@@ -327,13 +398,21 @@ static struct platform_device *stamp_devices[] __initdata = { | |||
327 | #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) | 398 | #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) |
328 | &bfin_uart_device, | 399 | &bfin_uart_device, |
329 | #endif | 400 | #endif |
401 | |||
402 | #if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) | ||
403 | &serial8250_device, | ||
404 | #endif | ||
405 | |||
406 | #if defined(CONFIG_KEYBOARD_OPENCORES) || defined(CONFIG_KEYBOARD_OPENCORES_MODULE) | ||
407 | &opencores_kbd_device, | ||
408 | #endif | ||
330 | }; | 409 | }; |
331 | 410 | ||
332 | static int __init H8606_init(void) | 411 | static int __init H8606_init(void) |
333 | { | 412 | { |
334 | printk(KERN_INFO "HV Sistemas H8606 board support by http://www.hvsistemas.com\n"); | 413 | printk(KERN_INFO "HV Sistemas H8606 board support by http://www.hvsistemas.com\n"); |
335 | printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__); | 414 | printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__); |
336 | platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); | 415 | platform_add_devices(h8606_devices, ARRAY_SIZE(h8606_devices)); |
337 | #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) | 416 | #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) |
338 | spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); | 417 | spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); |
339 | #endif | 418 | #endif |
diff --git a/arch/blackfin/mach-bf533/boards/ezkit.c b/arch/blackfin/mach-bf533/boards/ezkit.c index be852034a68b..c37dd45c8803 100644 --- a/arch/blackfin/mach-bf533/boards/ezkit.c +++ b/arch/blackfin/mach-bf533/boards/ezkit.c | |||
@@ -256,6 +256,50 @@ static struct platform_device bfin_pata_device = { | |||
256 | }; | 256 | }; |
257 | #endif | 257 | #endif |
258 | 258 | ||
259 | #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) | ||
260 | #include <linux/input.h> | ||
261 | #include <linux/gpio_keys.h> | ||
262 | |||
263 | static struct gpio_keys_button bfin_gpio_keys_table[] = { | ||
264 | {BTN_0, GPIO_PF7, 1, "gpio-keys: BTN0"}, | ||
265 | {BTN_1, GPIO_PF8, 1, "gpio-keys: BTN1"}, | ||
266 | {BTN_2, GPIO_PF9, 1, "gpio-keys: BTN2"}, | ||
267 | {BTN_3, GPIO_PF10, 1, "gpio-keys: BTN3"}, | ||
268 | }; | ||
269 | |||
270 | static struct gpio_keys_platform_data bfin_gpio_keys_data = { | ||
271 | .buttons = bfin_gpio_keys_table, | ||
272 | .nbuttons = ARRAY_SIZE(bfin_gpio_keys_table), | ||
273 | }; | ||
274 | |||
275 | static struct platform_device bfin_device_gpiokeys = { | ||
276 | .name = "gpio-keys", | ||
277 | .dev = { | ||
278 | .platform_data = &bfin_gpio_keys_data, | ||
279 | }, | ||
280 | }; | ||
281 | #endif | ||
282 | |||
283 | #if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) | ||
284 | #include <linux/i2c-gpio.h> | ||
285 | |||
286 | static struct i2c_gpio_platform_data i2c_gpio_data = { | ||
287 | .sda_pin = 1, | ||
288 | .scl_pin = 0, | ||
289 | .sda_is_open_drain = 0, | ||
290 | .scl_is_open_drain = 0, | ||
291 | .udelay = 40, | ||
292 | }; | ||
293 | |||
294 | static struct platform_device i2c_gpio_device = { | ||
295 | .name = "i2c-gpio", | ||
296 | .id = 0, | ||
297 | .dev = { | ||
298 | .platform_data = &i2c_gpio_data, | ||
299 | }, | ||
300 | }; | ||
301 | #endif | ||
302 | |||
259 | static struct platform_device *ezkit_devices[] __initdata = { | 303 | static struct platform_device *ezkit_devices[] __initdata = { |
260 | #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) | 304 | #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) |
261 | &smc91x_device, | 305 | &smc91x_device, |
@@ -280,6 +324,14 @@ static struct platform_device *ezkit_devices[] __initdata = { | |||
280 | #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) | 324 | #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) |
281 | &bfin_pata_device, | 325 | &bfin_pata_device, |
282 | #endif | 326 | #endif |
327 | |||
328 | #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) | ||
329 | &bfin_device_gpiokeys, | ||
330 | #endif | ||
331 | |||
332 | #if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) | ||
333 | &i2c_gpio_device, | ||
334 | #endif | ||
283 | }; | 335 | }; |
284 | 336 | ||
285 | static int __init ezkit_init(void) | 337 | static int __init ezkit_init(void) |
diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c index 8fde8d832850..ac52b040b336 100644 --- a/arch/blackfin/mach-bf533/boards/stamp.c +++ b/arch/blackfin/mach-bf533/boards/stamp.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/platform_device.h> | 32 | #include <linux/platform_device.h> |
33 | #include <linux/mtd/mtd.h> | 33 | #include <linux/mtd/mtd.h> |
34 | #include <linux/mtd/partitions.h> | 34 | #include <linux/mtd/partitions.h> |
35 | #include <linux/mtd/physmap.h> | ||
35 | #include <linux/spi/spi.h> | 36 | #include <linux/spi/spi.h> |
36 | #include <linux/spi/flash.h> | 37 | #include <linux/spi/flash.h> |
37 | #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) | 38 | #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) |
@@ -108,6 +109,50 @@ static struct platform_device net2272_bfin_device = { | |||
108 | }; | 109 | }; |
109 | #endif | 110 | #endif |
110 | 111 | ||
112 | static struct mtd_partition stamp_partitions[] = { | ||
113 | { | ||
114 | .name = "Bootloader", | ||
115 | .size = 0x20000, | ||
116 | .offset = 0, | ||
117 | }, { | ||
118 | .name = "Kernel", | ||
119 | .size = 0xE0000, | ||
120 | .offset = MTDPART_OFS_APPEND, | ||
121 | }, { | ||
122 | .name = "RootFS", | ||
123 | .size = MTDPART_SIZ_FULL, | ||
124 | .offset = MTDPART_OFS_APPEND, | ||
125 | } | ||
126 | }; | ||
127 | |||
128 | static struct physmap_flash_data stamp_flash_data = { | ||
129 | .width = 2, | ||
130 | .parts = stamp_partitions, | ||
131 | .nr_parts = ARRAY_SIZE(stamp_partitions), | ||
132 | }; | ||
133 | |||
134 | static struct resource stamp_flash_resource[] = { | ||
135 | { | ||
136 | .name = "cfi_probe", | ||
137 | .start = 0x20000000, | ||
138 | .end = 0x203fffff, | ||
139 | .flags = IORESOURCE_MEM, | ||
140 | }, { | ||
141 | .start = CONFIG_ENET_FLASH_PIN, | ||
142 | .flags = IORESOURCE_IRQ, | ||
143 | } | ||
144 | }; | ||
145 | |||
146 | static struct platform_device stamp_flash_device = { | ||
147 | .name = "BF5xx-Flash", | ||
148 | .id = 0, | ||
149 | .dev = { | ||
150 | .platform_data = &stamp_flash_data, | ||
151 | }, | ||
152 | .num_resources = ARRAY_SIZE(stamp_flash_resource), | ||
153 | .resource = stamp_flash_resource, | ||
154 | }; | ||
155 | |||
111 | #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) | 156 | #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) |
112 | /* all SPI peripherals info goes here */ | 157 | /* all SPI peripherals info goes here */ |
113 | 158 | ||
@@ -373,6 +418,49 @@ static struct platform_device bfin_pata_device = { | |||
373 | }; | 418 | }; |
374 | #endif | 419 | #endif |
375 | 420 | ||
421 | #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) | ||
422 | #include <linux/input.h> | ||
423 | #include <linux/gpio_keys.h> | ||
424 | |||
425 | static struct gpio_keys_button bfin_gpio_keys_table[] = { | ||
426 | {BTN_0, GPIO_PF5, 1, "gpio-keys: BTN0"}, | ||
427 | {BTN_1, GPIO_PF6, 1, "gpio-keys: BTN1"}, | ||
428 | {BTN_2, GPIO_PF8, 1, "gpio-keys: BTN2"}, | ||
429 | }; | ||
430 | |||
431 | static struct gpio_keys_platform_data bfin_gpio_keys_data = { | ||
432 | .buttons = bfin_gpio_keys_table, | ||
433 | .nbuttons = ARRAY_SIZE(bfin_gpio_keys_table), | ||
434 | }; | ||
435 | |||
436 | static struct platform_device bfin_device_gpiokeys = { | ||
437 | .name = "gpio-keys", | ||
438 | .dev = { | ||
439 | .platform_data = &bfin_gpio_keys_data, | ||
440 | }, | ||
441 | }; | ||
442 | #endif | ||
443 | |||
444 | #if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) | ||
445 | #include <linux/i2c-gpio.h> | ||
446 | |||
447 | static struct i2c_gpio_platform_data i2c_gpio_data = { | ||
448 | .sda_pin = 2, | ||
449 | .scl_pin = 3, | ||
450 | .sda_is_open_drain = 0, | ||
451 | .scl_is_open_drain = 0, | ||
452 | .udelay = 40, | ||
453 | }; | ||
454 | |||
455 | static struct platform_device i2c_gpio_device = { | ||
456 | .name = "i2c-gpio", | ||
457 | .id = 0, | ||
458 | .dev = { | ||
459 | .platform_data = &i2c_gpio_data, | ||
460 | }, | ||
461 | }; | ||
462 | #endif | ||
463 | |||
376 | static struct platform_device *stamp_devices[] __initdata = { | 464 | static struct platform_device *stamp_devices[] __initdata = { |
377 | #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) | 465 | #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) |
378 | &rtc_device, | 466 | &rtc_device, |
@@ -406,6 +494,15 @@ static struct platform_device *stamp_devices[] __initdata = { | |||
406 | #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) | 494 | #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) |
407 | &bfin_pata_device, | 495 | &bfin_pata_device, |
408 | #endif | 496 | #endif |
497 | |||
498 | #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) | ||
499 | &bfin_device_gpiokeys, | ||
500 | #endif | ||
501 | |||
502 | #if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) | ||
503 | &i2c_gpio_device, | ||
504 | #endif | ||
505 | &stamp_flash_device, | ||
409 | }; | 506 | }; |
410 | 507 | ||
411 | static int __init stamp_init(void) | 508 | static int __init stamp_init(void) |
@@ -418,12 +515,10 @@ static int __init stamp_init(void) | |||
418 | return ret; | 515 | return ret; |
419 | 516 | ||
420 | #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) | 517 | #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) |
421 | # if defined(CONFIG_BFIN_SHARED_FLASH_ENET) | ||
422 | /* setup BF533_STAMP CPLD to route AMS3 to Ethernet MAC */ | 518 | /* setup BF533_STAMP CPLD to route AMS3 to Ethernet MAC */ |
423 | bfin_write_FIO_DIR(bfin_read_FIO_DIR() | (1 << CONFIG_ENET_FLASH_PIN)); | 519 | bfin_write_FIO_DIR(bfin_read_FIO_DIR() | (1 << CONFIG_ENET_FLASH_PIN)); |
424 | bfin_write_FIO_FLAG_S(1 << CONFIG_ENET_FLASH_PIN); | 520 | bfin_write_FIO_FLAG_S(1 << CONFIG_ENET_FLASH_PIN); |
425 | SSYNC(); | 521 | SSYNC(); |
426 | # endif | ||
427 | #endif | 522 | #endif |
428 | 523 | ||
429 | #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) | 524 | #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) |
@@ -440,10 +535,8 @@ arch_initcall(stamp_init); | |||
440 | 535 | ||
441 | void native_machine_restart(char *cmd) | 536 | void native_machine_restart(char *cmd) |
442 | { | 537 | { |
443 | #if defined(CONFIG_BFIN_SHARED_FLASH_ENET) | 538 | #define BIT_TO_SET (1 << CONFIG_ENET_FLASH_PIN) |
444 | # define BIT_TO_SET (1 << CONFIG_ENET_FLASH_PIN) | ||
445 | bfin_write_FIO_INEN(~BIT_TO_SET); | 539 | bfin_write_FIO_INEN(~BIT_TO_SET); |
446 | bfin_write_FIO_DIR(BIT_TO_SET); | 540 | bfin_write_FIO_DIR(BIT_TO_SET); |
447 | bfin_write_FIO_FLAG_C(BIT_TO_SET); | 541 | bfin_write_FIO_FLAG_C(BIT_TO_SET); |
448 | #endif | ||
449 | } | 542 | } |
diff --git a/arch/blackfin/mach-bf537/boards/Kconfig b/arch/blackfin/mach-bf537/boards/Kconfig index 96a15196e416..7e789dbef036 100644 --- a/arch/blackfin/mach-bf537/boards/Kconfig +++ b/arch/blackfin/mach-bf537/boards/Kconfig | |||
@@ -21,6 +21,12 @@ config PNAV10 | |||
21 | help | 21 | help |
22 | PNAV board support. | 22 | PNAV board support. |
23 | 23 | ||
24 | config CAMSIG_MINOTAUR | ||
25 | bool "Cambridge Signal Processing LTD Minotaur" | ||
26 | depends on (BF537) | ||
27 | help | ||
28 | Board supply package for CSP Minotaur | ||
29 | |||
24 | config GENERIC_BF537_BOARD | 30 | config GENERIC_BF537_BOARD |
25 | bool "Generic" | 31 | bool "Generic" |
26 | help | 32 | help |
diff --git a/arch/blackfin/mach-bf537/boards/Makefile b/arch/blackfin/mach-bf537/boards/Makefile index 94a85174283a..87e450f29e37 100644 --- a/arch/blackfin/mach-bf537/boards/Makefile +++ b/arch/blackfin/mach-bf537/boards/Makefile | |||
@@ -6,3 +6,4 @@ obj-$(CONFIG_GENERIC_BF537_BOARD) += generic_board.o | |||
6 | obj-$(CONFIG_BFIN537_STAMP) += stamp.o led.o | 6 | obj-$(CONFIG_BFIN537_STAMP) += stamp.o led.o |
7 | obj-$(CONFIG_BFIN537_BLUETECHNIX_CM) += cm_bf537.o | 7 | obj-$(CONFIG_BFIN537_BLUETECHNIX_CM) += cm_bf537.o |
8 | obj-$(CONFIG_PNAV10) += pnav10.o | 8 | obj-$(CONFIG_PNAV10) += pnav10.o |
9 | obj-$(CONFIG_CAMSIG_MINOTAUR) += minotaur.o | ||
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537.c b/arch/blackfin/mach-bf537/boards/cm_bf537.c index c0fb06dbc42e..8703b67d5ec6 100644 --- a/arch/blackfin/mach-bf537/boards/cm_bf537.c +++ b/arch/blackfin/mach-bf537/boards/cm_bf537.c | |||
@@ -29,6 +29,7 @@ | |||
29 | */ | 29 | */ |
30 | 30 | ||
31 | #include <linux/device.h> | 31 | #include <linux/device.h> |
32 | #include <linux/etherdevice.h> | ||
32 | #include <linux/platform_device.h> | 33 | #include <linux/platform_device.h> |
33 | #include <linux/mtd/mtd.h> | 34 | #include <linux/mtd/mtd.h> |
34 | #include <linux/mtd/partitions.h> | 35 | #include <linux/mtd/partitions.h> |
@@ -216,6 +217,12 @@ static struct platform_device rtc_device = { | |||
216 | }; | 217 | }; |
217 | #endif | 218 | #endif |
218 | 219 | ||
220 | #if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE) | ||
221 | static struct platform_device hitachi_fb_device = { | ||
222 | .name = "hitachi-tx09", | ||
223 | }; | ||
224 | #endif | ||
225 | |||
219 | #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) | 226 | #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) |
220 | static struct resource smc91x_resources[] = { | 227 | static struct resource smc91x_resources[] = { |
221 | { | 228 | { |
@@ -374,6 +381,10 @@ static struct platform_device bfin_pata_device = { | |||
374 | #endif | 381 | #endif |
375 | 382 | ||
376 | static struct platform_device *cm_bf537_devices[] __initdata = { | 383 | static struct platform_device *cm_bf537_devices[] __initdata = { |
384 | #if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE) | ||
385 | &hitachi_fb_device, | ||
386 | #endif | ||
387 | |||
377 | #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) | 388 | #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) |
378 | &rtc_device, | 389 | &rtc_device, |
379 | #endif | 390 | #endif |
diff --git a/arch/blackfin/mach-bf537/boards/generic_board.c b/arch/blackfin/mach-bf537/boards/generic_board.c index 09f4bfbd2350..3e52f3f5bd58 100644 --- a/arch/blackfin/mach-bf537/boards/generic_board.c +++ b/arch/blackfin/mach-bf537/boards/generic_board.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * | 8 | * |
9 | * Modified: | 9 | * Modified: |
10 | * Copyright 2005 National ICT Australia (NICTA) | 10 | * Copyright 2005 National ICT Australia (NICTA) |
11 | * Copyright 2004-2007 Analog Devices Inc. | 11 | * Copyright 2004-2008 Analog Devices Inc. |
12 | * | 12 | * |
13 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | 13 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ |
14 | * | 14 | * |
@@ -29,6 +29,7 @@ | |||
29 | */ | 29 | */ |
30 | 30 | ||
31 | #include <linux/device.h> | 31 | #include <linux/device.h> |
32 | #include <linux/etherdevice.h> | ||
32 | #include <linux/platform_device.h> | 33 | #include <linux/platform_device.h> |
33 | #include <linux/mtd/mtd.h> | 34 | #include <linux/mtd/mtd.h> |
34 | #include <linux/mtd/partitions.h> | 35 | #include <linux/mtd/partitions.h> |
@@ -204,12 +205,8 @@ static struct resource sl811_hcd_resources[] = { | |||
204 | void sl811_port_power(struct device *dev, int is_on) | 205 | void sl811_port_power(struct device *dev, int is_on) |
205 | { | 206 | { |
206 | gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS"); | 207 | gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS"); |
207 | gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS); | 208 | gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS, is_on); |
208 | 209 | ||
209 | if (is_on) | ||
210 | gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 1); | ||
211 | else | ||
212 | gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 0); | ||
213 | } | 210 | } |
214 | #endif | 211 | #endif |
215 | 212 | ||
@@ -733,9 +730,11 @@ void native_machine_restart(char *cmd) | |||
733 | bfin_gpio_reset_spi0_ssel1(); | 730 | bfin_gpio_reset_spi0_ssel1(); |
734 | } | 731 | } |
735 | 732 | ||
733 | #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) | ||
736 | void bfin_get_ether_addr(char *addr) | 734 | void bfin_get_ether_addr(char *addr) |
737 | { | 735 | { |
738 | random_ether_addr(addr); | 736 | random_ether_addr(addr); |
739 | printk(KERN_WARNING "%s:%s: Setting Ethernet MAC to a random one\n", __FILE__, __func__); | 737 | printk(KERN_WARNING "%s:%s: Setting Ethernet MAC to a random one\n", __FILE__, __func__); |
740 | } | 738 | } |
741 | EXPORT_SYMBOL(bfin_get_ether_addr); | 739 | EXPORT_SYMBOL(bfin_get_ether_addr); |
740 | #endif | ||
diff --git a/arch/blackfin/mach-bf537/boards/minotaur.c b/arch/blackfin/mach-bf537/boards/minotaur.c new file mode 100644 index 000000000000..b8bbba85af53 --- /dev/null +++ b/arch/blackfin/mach-bf537/boards/minotaur.c | |||
@@ -0,0 +1,317 @@ | |||
1 | /* | ||
2 | */ | ||
3 | |||
4 | #include <linux/device.h> | ||
5 | #include <linux/platform_device.h> | ||
6 | #include <linux/mtd/mtd.h> | ||
7 | #include <linux/mtd/partitions.h> | ||
8 | #include <linux/spi/spi.h> | ||
9 | #include <linux/spi/flash.h> | ||
10 | #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) | ||
11 | #include <linux/usb_isp1362.h> | ||
12 | #endif | ||
13 | #include <linux/pata_platform.h> | ||
14 | #include <linux/irq.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/usb_sl811.h> | ||
17 | #include <asm/dma.h> | ||
18 | #include <asm/bfin5xx_spi.h> | ||
19 | #include <asm/reboot.h> | ||
20 | #include <linux/spi/ad7877.h> | ||
21 | |||
22 | /* | ||
23 | * Name the Board for the /proc/cpuinfo | ||
24 | */ | ||
25 | char *bfin_board_name = "CamSig Minotaur BF537"; | ||
26 | |||
27 | #if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) | ||
28 | static struct resource bfin_pcmcia_cf_resources[] = { | ||
29 | { | ||
30 | .start = 0x20310000, /* IO PORT */ | ||
31 | .end = 0x20312000, | ||
32 | .flags = IORESOURCE_MEM, | ||
33 | }, { | ||
34 | .start = 0x20311000, /* Attribute Memory */ | ||
35 | .end = 0x20311FFF, | ||
36 | .flags = IORESOURCE_MEM, | ||
37 | }, { | ||
38 | .start = IRQ_PF4, | ||
39 | .end = IRQ_PF4, | ||
40 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, | ||
41 | }, { | ||
42 | .start = IRQ_PF6, /* Card Detect PF6 */ | ||
43 | .end = IRQ_PF6, | ||
44 | .flags = IORESOURCE_IRQ, | ||
45 | }, | ||
46 | }; | ||
47 | |||
48 | static struct platform_device bfin_pcmcia_cf_device = { | ||
49 | .name = "bfin_cf_pcmcia", | ||
50 | .id = -1, | ||
51 | .num_resources = ARRAY_SIZE(bfin_pcmcia_cf_resources), | ||
52 | .resource = bfin_pcmcia_cf_resources, | ||
53 | }; | ||
54 | #endif | ||
55 | |||
56 | #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) | ||
57 | static struct platform_device rtc_device = { | ||
58 | .name = "rtc-bfin", | ||
59 | .id = -1, | ||
60 | }; | ||
61 | #endif | ||
62 | |||
63 | #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) | ||
64 | static struct platform_device bfin_mac_device = { | ||
65 | .name = "bfin_mac", | ||
66 | }; | ||
67 | #endif | ||
68 | |||
69 | #if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) | ||
70 | static struct resource net2272_bfin_resources[] = { | ||
71 | { | ||
72 | .start = 0x20300000, | ||
73 | .end = 0x20300000 + 0x100, | ||
74 | .flags = IORESOURCE_MEM, | ||
75 | }, { | ||
76 | .start = IRQ_PF7, | ||
77 | .end = IRQ_PF7, | ||
78 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, | ||
79 | }, | ||
80 | }; | ||
81 | |||
82 | static struct platform_device net2272_bfin_device = { | ||
83 | .name = "net2272", | ||
84 | .id = -1, | ||
85 | .num_resources = ARRAY_SIZE(net2272_bfin_resources), | ||
86 | .resource = net2272_bfin_resources, | ||
87 | }; | ||
88 | #endif | ||
89 | |||
90 | #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) | ||
91 | /* all SPI peripherals info goes here */ | ||
92 | |||
93 | #if defined(CONFIG_MTD_M25P80) \ | ||
94 | || defined(CONFIG_MTD_M25P80_MODULE) | ||
95 | |||
96 | /* Partition sizes */ | ||
97 | #define FLASH_SIZE 0x00400000 | ||
98 | #define PSIZE_UBOOT 0x00030000 | ||
99 | #define PSIZE_INITRAMFS 0x00240000 | ||
100 | |||
101 | static struct mtd_partition bfin_spi_flash_partitions[] = { | ||
102 | { | ||
103 | .name = "uboot", | ||
104 | .size = PSIZE_UBOOT, | ||
105 | .offset = 0x000000, | ||
106 | .mask_flags = MTD_CAP_ROM | ||
107 | }, { | ||
108 | .name = "initramfs", | ||
109 | .size = PSIZE_INITRAMFS, | ||
110 | .offset = PSIZE_UBOOT | ||
111 | }, { | ||
112 | .name = "opt", | ||
113 | .size = FLASH_SIZE - (PSIZE_UBOOT + PSIZE_INITRAMFS), | ||
114 | .offset = PSIZE_UBOOT + PSIZE_INITRAMFS, | ||
115 | } | ||
116 | }; | ||
117 | |||
118 | static struct flash_platform_data bfin_spi_flash_data = { | ||
119 | .name = "m25p80", | ||
120 | .parts = bfin_spi_flash_partitions, | ||
121 | .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions), | ||
122 | .type = "m25p64", | ||
123 | }; | ||
124 | |||
125 | /* SPI flash chip (m25p64) */ | ||
126 | static struct bfin5xx_spi_chip spi_flash_chip_info = { | ||
127 | .enable_dma = 0, /* use dma transfer with this chip*/ | ||
128 | .bits_per_word = 8, | ||
129 | }; | ||
130 | #endif | ||
131 | |||
132 | #if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) | ||
133 | static struct bfin5xx_spi_chip spi_mmc_chip_info = { | ||
134 | .enable_dma = 1, | ||
135 | .bits_per_word = 8, | ||
136 | }; | ||
137 | #endif | ||
138 | |||
139 | static struct spi_board_info bfin_spi_board_info[] __initdata = { | ||
140 | #if defined(CONFIG_MTD_M25P80) \ | ||
141 | || defined(CONFIG_MTD_M25P80_MODULE) | ||
142 | { | ||
143 | /* the modalias must be the same as spi device driver name */ | ||
144 | .modalias = "m25p80", /* Name of spi_driver for this device */ | ||
145 | .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ | ||
146 | .bus_num = 0, /* Framework bus number */ | ||
147 | .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/ | ||
148 | .platform_data = &bfin_spi_flash_data, | ||
149 | .controller_data = &spi_flash_chip_info, | ||
150 | .mode = SPI_MODE_3, | ||
151 | }, | ||
152 | #endif | ||
153 | |||
154 | #if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) | ||
155 | { | ||
156 | .modalias = "spi_mmc_dummy", | ||
157 | .max_speed_hz = 5000000, /* max spi clock (SCK) speed in HZ */ | ||
158 | .bus_num = 0, | ||
159 | .chip_select = 0, | ||
160 | .platform_data = NULL, | ||
161 | .controller_data = &spi_mmc_chip_info, | ||
162 | .mode = SPI_MODE_3, | ||
163 | }, | ||
164 | { | ||
165 | .modalias = "spi_mmc", | ||
166 | .max_speed_hz = 5000000, /* max spi clock (SCK) speed in HZ */ | ||
167 | .bus_num = 0, | ||
168 | .chip_select = CONFIG_SPI_MMC_CS_CHAN, | ||
169 | .platform_data = NULL, | ||
170 | .controller_data = &spi_mmc_chip_info, | ||
171 | .mode = SPI_MODE_3, | ||
172 | }, | ||
173 | #endif | ||
174 | }; | ||
175 | |||
176 | /* SPI controller data */ | ||
177 | static struct bfin5xx_spi_master bfin_spi0_info = { | ||
178 | .num_chipselect = 8, | ||
179 | .enable_dma = 1, /* master has the ability to do dma transfer */ | ||
180 | }; | ||
181 | |||
182 | /* SPI (0) */ | ||
183 | static struct resource bfin_spi0_resource[] = { | ||
184 | [0] = { | ||
185 | .start = SPI0_REGBASE, | ||
186 | .end = SPI0_REGBASE + 0xFF, | ||
187 | .flags = IORESOURCE_MEM, | ||
188 | }, | ||
189 | [1] = { | ||
190 | .start = CH_SPI, | ||
191 | .end = CH_SPI, | ||
192 | .flags = IORESOURCE_IRQ, | ||
193 | }, | ||
194 | }; | ||
195 | |||
196 | static struct platform_device bfin_spi0_device = { | ||
197 | .name = "bfin-spi", | ||
198 | .id = 0, /* Bus number */ | ||
199 | .num_resources = ARRAY_SIZE(bfin_spi0_resource), | ||
200 | .resource = bfin_spi0_resource, | ||
201 | .dev = { | ||
202 | .platform_data = &bfin_spi0_info, /* Passed to driver */ | ||
203 | }, | ||
204 | }; | ||
205 | #endif /* spi master and devices */ | ||
206 | |||
207 | #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) | ||
208 | static struct resource bfin_uart_resources[] = { | ||
209 | { | ||
210 | .start = 0xFFC00400, | ||
211 | .end = 0xFFC004FF, | ||
212 | .flags = IORESOURCE_MEM, | ||
213 | }, { | ||
214 | .start = 0xFFC02000, | ||
215 | .end = 0xFFC020FF, | ||
216 | .flags = IORESOURCE_MEM, | ||
217 | }, | ||
218 | }; | ||
219 | |||
220 | static struct platform_device bfin_uart_device = { | ||
221 | .name = "bfin-uart", | ||
222 | .id = 1, | ||
223 | .num_resources = ARRAY_SIZE(bfin_uart_resources), | ||
224 | .resource = bfin_uart_resources, | ||
225 | }; | ||
226 | #endif | ||
227 | |||
228 | #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) | ||
229 | static struct resource bfin_twi0_resource[] = { | ||
230 | [0] = { | ||
231 | .start = TWI0_REGBASE, | ||
232 | .end = TWI0_REGBASE + 0xFF, | ||
233 | .flags = IORESOURCE_MEM, | ||
234 | }, | ||
235 | [1] = { | ||
236 | .start = IRQ_TWI, | ||
237 | .end = IRQ_TWI, | ||
238 | .flags = IORESOURCE_IRQ, | ||
239 | }, | ||
240 | }; | ||
241 | |||
242 | static struct platform_device i2c_bfin_twi_device = { | ||
243 | .name = "i2c-bfin-twi", | ||
244 | .id = 0, | ||
245 | .num_resources = ARRAY_SIZE(bfin_twi0_resource), | ||
246 | .resource = bfin_twi0_resource, | ||
247 | }; | ||
248 | #endif | ||
249 | |||
250 | #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) | ||
251 | static struct platform_device bfin_sport0_uart_device = { | ||
252 | .name = "bfin-sport-uart", | ||
253 | .id = 0, | ||
254 | }; | ||
255 | |||
256 | static struct platform_device bfin_sport1_uart_device = { | ||
257 | .name = "bfin-sport-uart", | ||
258 | .id = 1, | ||
259 | }; | ||
260 | #endif | ||
261 | |||
262 | static struct platform_device *minotaur_devices[] __initdata = { | ||
263 | #if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) | ||
264 | &bfin_pcmcia_cf_device, | ||
265 | #endif | ||
266 | |||
267 | #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) | ||
268 | &rtc_device, | ||
269 | #endif | ||
270 | |||
271 | #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) | ||
272 | &bfin_mac_device, | ||
273 | #endif | ||
274 | |||
275 | #if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) | ||
276 | &net2272_bfin_device, | ||
277 | #endif | ||
278 | |||
279 | #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) | ||
280 | &bfin_spi0_device, | ||
281 | #endif | ||
282 | |||
283 | #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) | ||
284 | &bfin_uart_device, | ||
285 | #endif | ||
286 | |||
287 | #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) | ||
288 | &i2c_bfin_twi_device, | ||
289 | #endif | ||
290 | |||
291 | #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) | ||
292 | &bfin_sport0_uart_device, | ||
293 | &bfin_sport1_uart_device, | ||
294 | #endif | ||
295 | |||
296 | }; | ||
297 | |||
298 | static int __init minotaur_init(void) | ||
299 | { | ||
300 | printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__); | ||
301 | platform_add_devices(minotaur_devices, ARRAY_SIZE(minotaur_devices)); | ||
302 | #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) | ||
303 | spi_register_board_info(bfin_spi_board_info, | ||
304 | ARRAY_SIZE(bfin_spi_board_info)); | ||
305 | #endif | ||
306 | |||
307 | return 0; | ||
308 | } | ||
309 | |||
310 | arch_initcall(minotaur_init); | ||
311 | |||
312 | void native_machine_restart(char *cmd) | ||
313 | { | ||
314 | /* workaround reboot hang when booting from SPI */ | ||
315 | if ((bfin_read_SYSCR() & 0x7) == 0x3) | ||
316 | bfin_gpio_reset_spi0_ssel1(); | ||
317 | } | ||
diff --git a/arch/blackfin/mach-bf537/boards/pnav10.c b/arch/blackfin/mach-bf537/boards/pnav10.c index fd5f4a6f08e4..509a8a236fd0 100644 --- a/arch/blackfin/mach-bf537/boards/pnav10.c +++ b/arch/blackfin/mach-bf537/boards/pnav10.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * | 8 | * |
9 | * Modified: | 9 | * Modified: |
10 | * Copyright 2005 National ICT Australia (NICTA) | 10 | * Copyright 2005 National ICT Australia (NICTA) |
11 | * Copyright 2004-2006 Analog Devices Inc. | 11 | * Copyright 2004-2008 Analog Devices Inc. |
12 | * | 12 | * |
13 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | 13 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ |
14 | * | 14 | * |
@@ -29,6 +29,7 @@ | |||
29 | */ | 29 | */ |
30 | 30 | ||
31 | #include <linux/device.h> | 31 | #include <linux/device.h> |
32 | #include <linux/etherdevice.h> | ||
32 | #include <linux/platform_device.h> | 33 | #include <linux/platform_device.h> |
33 | #include <linux/mtd/mtd.h> | 34 | #include <linux/mtd/mtd.h> |
34 | #include <linux/mtd/partitions.h> | 35 | #include <linux/mtd/partitions.h> |
@@ -133,12 +134,8 @@ static struct resource sl811_hcd_resources[] = { | |||
133 | void sl811_port_power(struct device *dev, int is_on) | 134 | void sl811_port_power(struct device *dev, int is_on) |
134 | { | 135 | { |
135 | gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS"); | 136 | gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS"); |
136 | gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS); | 137 | gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS, is_on); |
137 | 138 | ||
138 | if (is_on) | ||
139 | gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 1); | ||
140 | else | ||
141 | gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 0); | ||
142 | } | 139 | } |
143 | #endif | 140 | #endif |
144 | 141 | ||
diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 07b0dc273d2f..772541548b76 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/platform_device.h> | 32 | #include <linux/platform_device.h> |
33 | #include <linux/mtd/mtd.h> | 33 | #include <linux/mtd/mtd.h> |
34 | #include <linux/mtd/partitions.h> | 34 | #include <linux/mtd/partitions.h> |
35 | #include <linux/mtd/physmap.h> | ||
35 | #include <linux/spi/spi.h> | 36 | #include <linux/spi/spi.h> |
36 | #include <linux/spi/flash.h> | 37 | #include <linux/spi/flash.h> |
37 | #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) | 38 | #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) |
@@ -103,6 +104,30 @@ void __exit bfin_isp1761_exit(void) | |||
103 | arch_initcall(bfin_isp1761_init); | 104 | arch_initcall(bfin_isp1761_init); |
104 | #endif | 105 | #endif |
105 | 106 | ||
107 | #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) | ||
108 | #include <linux/input.h> | ||
109 | #include <linux/gpio_keys.h> | ||
110 | |||
111 | static struct gpio_keys_button bfin_gpio_keys_table[] = { | ||
112 | {BTN_0, GPIO_PF2, 1, "gpio-keys: BTN0"}, | ||
113 | {BTN_1, GPIO_PF3, 1, "gpio-keys: BTN1"}, | ||
114 | {BTN_2, GPIO_PF4, 1, "gpio-keys: BTN2"}, | ||
115 | {BTN_3, GPIO_PF5, 1, "gpio-keys: BTN3"}, | ||
116 | }; | ||
117 | |||
118 | static struct gpio_keys_platform_data bfin_gpio_keys_data = { | ||
119 | .buttons = bfin_gpio_keys_table, | ||
120 | .nbuttons = ARRAY_SIZE(bfin_gpio_keys_table), | ||
121 | }; | ||
122 | |||
123 | static struct platform_device bfin_device_gpiokeys = { | ||
124 | .name = "gpio-keys", | ||
125 | .dev = { | ||
126 | .platform_data = &bfin_gpio_keys_data, | ||
127 | }, | ||
128 | }; | ||
129 | #endif | ||
130 | |||
106 | #if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) | 131 | #if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) |
107 | static struct resource bfin_pcmcia_cf_resources[] = { | 132 | static struct resource bfin_pcmcia_cf_resources[] = { |
108 | { | 133 | { |
@@ -226,12 +251,7 @@ static struct resource sl811_hcd_resources[] = { | |||
226 | void sl811_port_power(struct device *dev, int is_on) | 251 | void sl811_port_power(struct device *dev, int is_on) |
227 | { | 252 | { |
228 | gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS"); | 253 | gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS"); |
229 | gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS); | 254 | gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS, is_on); |
230 | |||
231 | if (is_on) | ||
232 | gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 1); | ||
233 | else | ||
234 | gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 0); | ||
235 | } | 255 | } |
236 | #endif | 256 | #endif |
237 | 257 | ||
@@ -320,6 +340,49 @@ static struct platform_device net2272_bfin_device = { | |||
320 | }; | 340 | }; |
321 | #endif | 341 | #endif |
322 | 342 | ||
343 | static struct mtd_partition stamp_partitions[] = { | ||
344 | { | ||
345 | .name = "Bootloader", | ||
346 | .size = 0x20000, | ||
347 | .offset = 0, | ||
348 | }, { | ||
349 | .name = "Kernel", | ||
350 | .size = 0xE0000, | ||
351 | .offset = MTDPART_OFS_APPEND, | ||
352 | }, { | ||
353 | .name = "RootFS", | ||
354 | .size = 0x400000 - 0x20000 - 0xE0000 - 0x10000, | ||
355 | .offset = MTDPART_OFS_APPEND, | ||
356 | }, { | ||
357 | .name = "MAC Address", | ||
358 | .size = MTDPART_SIZ_FULL, | ||
359 | .offset = 0x3F0000, | ||
360 | .mask_flags = MTD_WRITEABLE, | ||
361 | } | ||
362 | }; | ||
363 | |||
364 | static struct physmap_flash_data stamp_flash_data = { | ||
365 | .width = 2, | ||
366 | .parts = stamp_partitions, | ||
367 | .nr_parts = ARRAY_SIZE(stamp_partitions), | ||
368 | }; | ||
369 | |||
370 | static struct resource stamp_flash_resource = { | ||
371 | .start = 0x20000000, | ||
372 | .end = 0x203fffff, | ||
373 | .flags = IORESOURCE_MEM, | ||
374 | }; | ||
375 | |||
376 | static struct platform_device stamp_flash_device = { | ||
377 | .name = "physmap-flash", | ||
378 | .id = 0, | ||
379 | .dev = { | ||
380 | .platform_data = &stamp_flash_data, | ||
381 | }, | ||
382 | .num_resources = 1, | ||
383 | .resource = &stamp_flash_resource, | ||
384 | }; | ||
385 | |||
323 | #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) | 386 | #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) |
324 | /* all SPI peripherals info goes here */ | 387 | /* all SPI peripherals info goes here */ |
325 | 388 | ||
@@ -738,6 +801,11 @@ static struct platform_device *stamp_devices[] __initdata = { | |||
738 | #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) | 801 | #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) |
739 | &bfin_pata_device, | 802 | &bfin_pata_device, |
740 | #endif | 803 | #endif |
804 | |||
805 | #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) | ||
806 | &bfin_device_gpiokeys, | ||
807 | #endif | ||
808 | &stamp_flash_device, | ||
741 | }; | 809 | }; |
742 | 810 | ||
743 | static int __init stamp_init(void) | 811 | static int __init stamp_init(void) |
diff --git a/arch/blackfin/mach-bf548/Kconfig b/arch/blackfin/mach-bf548/Kconfig index d8bd3b49f150..1bfcd8f646ab 100644 --- a/arch/blackfin/mach-bf548/Kconfig +++ b/arch/blackfin/mach-bf548/Kconfig | |||
@@ -7,7 +7,7 @@ menu "BF548 Specific Configuration" | |||
7 | config DEB_DMA_URGENT | 7 | config DEB_DMA_URGENT |
8 | bool "DMA has priority over core for ext. accesses" | 8 | bool "DMA has priority over core for ext. accesses" |
9 | depends on BF54x | 9 | depends on BF54x |
10 | default n | 10 | default y |
11 | help | 11 | help |
12 | Treat any DEB1, DEB2 and DEB3 request as Urgent | 12 | Treat any DEB1, DEB2 and DEB3 request as Urgent |
13 | 13 | ||
diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c index d37d6653c4bc..14860f04d1bd 100644 --- a/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/arch/blackfin/mach-bf548/boards/ezkit.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/platform_device.h> | 32 | #include <linux/platform_device.h> |
33 | #include <linux/mtd/mtd.h> | 33 | #include <linux/mtd/mtd.h> |
34 | #include <linux/mtd/partitions.h> | 34 | #include <linux/mtd/partitions.h> |
35 | #include <linux/mtd/physmap.h> | ||
35 | #include <linux/spi/spi.h> | 36 | #include <linux/spi/spi.h> |
36 | #include <linux/spi/flash.h> | 37 | #include <linux/spi/flash.h> |
37 | #include <linux/irq.h> | 38 | #include <linux/irq.h> |
@@ -206,23 +207,6 @@ static struct platform_device smsc911x_device = { | |||
206 | }; | 207 | }; |
207 | #endif | 208 | #endif |
208 | 209 | ||
209 | #if defined(CONFIG_USB_BF54x_HCD) || defined(CONFIG_USB_BF54x_HCD_MODULE) | ||
210 | static struct resource bf54x_hcd_resources[] = { | ||
211 | { | ||
212 | .start = 0xFFC03C00, | ||
213 | .end = 0xFFC040FF, | ||
214 | .flags = IORESOURCE_MEM, | ||
215 | }, | ||
216 | }; | ||
217 | |||
218 | static struct platform_device bf54x_hcd = { | ||
219 | .name = "bf54x-hcd", | ||
220 | .id = 0, | ||
221 | .num_resources = ARRAY_SIZE(bf54x_hcd_resources), | ||
222 | .resource = bf54x_hcd_resources, | ||
223 | }; | ||
224 | #endif | ||
225 | |||
226 | #if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE) | 210 | #if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE) |
227 | static struct resource musb_resources[] = { | 211 | static struct resource musb_resources[] = { |
228 | [0] = { | 212 | [0] = { |
@@ -243,14 +227,14 @@ static struct resource musb_resources[] = { | |||
243 | }; | 227 | }; |
244 | 228 | ||
245 | static struct musb_hdrc_platform_data musb_plat = { | 229 | static struct musb_hdrc_platform_data musb_plat = { |
246 | #ifdef CONFIG_USB_MUSB_OTG | 230 | #if defined(CONFIG_USB_MUSB_OTG) |
247 | .mode = MUSB_OTG, | 231 | .mode = MUSB_OTG, |
248 | #elif CONFIG_USB_MUSB_HDRC_HCD | 232 | #elif defined(CONFIG_USB_MUSB_HDRC_HCD) |
249 | .mode = MUSB_HOST, | 233 | .mode = MUSB_HOST, |
250 | #elif CONFIG_USB_GADGET_MUSB_HDRC | 234 | #elif defined(CONFIG_USB_GADGET_MUSB_HDRC) |
251 | .mode = MUSB_PERIPHERAL, | 235 | .mode = MUSB_PERIPHERAL, |
252 | #endif | 236 | #endif |
253 | .multipoint = 1, | 237 | .multipoint = 0, |
254 | }; | 238 | }; |
255 | 239 | ||
256 | static u64 musb_dmamask = ~(u32)0; | 240 | static u64 musb_dmamask = ~(u32)0; |
@@ -344,6 +328,44 @@ static struct platform_device bf54x_sdh_device = { | |||
344 | }; | 328 | }; |
345 | #endif | 329 | #endif |
346 | 330 | ||
331 | static struct mtd_partition ezkit_partitions[] = { | ||
332 | { | ||
333 | .name = "Bootloader", | ||
334 | .size = 0x20000, | ||
335 | .offset = 0, | ||
336 | }, { | ||
337 | .name = "Kernel", | ||
338 | .size = 0xE0000, | ||
339 | .offset = MTDPART_OFS_APPEND, | ||
340 | }, { | ||
341 | .name = "RootFS", | ||
342 | .size = MTDPART_SIZ_FULL, | ||
343 | .offset = MTDPART_OFS_APPEND, | ||
344 | } | ||
345 | }; | ||
346 | |||
347 | static struct physmap_flash_data ezkit_flash_data = { | ||
348 | .width = 2, | ||
349 | .parts = ezkit_partitions, | ||
350 | .nr_parts = ARRAY_SIZE(ezkit_partitions), | ||
351 | }; | ||
352 | |||
353 | static struct resource ezkit_flash_resource = { | ||
354 | .start = 0x20000000, | ||
355 | .end = 0x20ffffff, | ||
356 | .flags = IORESOURCE_MEM, | ||
357 | }; | ||
358 | |||
359 | static struct platform_device ezkit_flash_device = { | ||
360 | .name = "physmap-flash", | ||
361 | .id = 0, | ||
362 | .dev = { | ||
363 | .platform_data = &ezkit_flash_data, | ||
364 | }, | ||
365 | .num_resources = 1, | ||
366 | .resource = &ezkit_flash_resource, | ||
367 | }; | ||
368 | |||
347 | #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) | 369 | #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) |
348 | /* all SPI peripherals info goes here */ | 370 | /* all SPI peripherals info goes here */ |
349 | #if defined(CONFIG_MTD_M25P80) \ | 371 | #if defined(CONFIG_MTD_M25P80) \ |
@@ -531,6 +553,29 @@ static struct platform_device i2c_bfin_twi1_device = { | |||
531 | #endif | 553 | #endif |
532 | #endif | 554 | #endif |
533 | 555 | ||
556 | #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) | ||
557 | #include <linux/gpio_keys.h> | ||
558 | |||
559 | static struct gpio_keys_button bfin_gpio_keys_table[] = { | ||
560 | {BTN_0, GPIO_PB8, 1, "gpio-keys: BTN0"}, | ||
561 | {BTN_1, GPIO_PB9, 1, "gpio-keys: BTN1"}, | ||
562 | {BTN_2, GPIO_PB10, 1, "gpio-keys: BTN2"}, | ||
563 | {BTN_3, GPIO_PB11, 1, "gpio-keys: BTN3"}, | ||
564 | }; | ||
565 | |||
566 | static struct gpio_keys_platform_data bfin_gpio_keys_data = { | ||
567 | .buttons = bfin_gpio_keys_table, | ||
568 | .nbuttons = ARRAY_SIZE(bfin_gpio_keys_table), | ||
569 | }; | ||
570 | |||
571 | static struct platform_device bfin_device_gpiokeys = { | ||
572 | .name = "gpio-keys", | ||
573 | .dev = { | ||
574 | .platform_data = &bfin_gpio_keys_data, | ||
575 | }, | ||
576 | }; | ||
577 | #endif | ||
578 | |||
534 | static struct platform_device *ezkit_devices[] __initdata = { | 579 | static struct platform_device *ezkit_devices[] __initdata = { |
535 | #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) | 580 | #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) |
536 | &rtc_device, | 581 | &rtc_device, |
@@ -548,10 +593,6 @@ static struct platform_device *ezkit_devices[] __initdata = { | |||
548 | &smsc911x_device, | 593 | &smsc911x_device, |
549 | #endif | 594 | #endif |
550 | 595 | ||
551 | #if defined(CONFIG_USB_BF54x_HCD) || defined(CONFIG_USB_BF54x_HCD_MODULE) | ||
552 | &bf54x_hcd, | ||
553 | #endif | ||
554 | |||
555 | #if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE) | 596 | #if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE) |
556 | &musb_device, | 597 | &musb_device, |
557 | #endif | 598 | #endif |
@@ -583,6 +624,11 @@ static struct platform_device *ezkit_devices[] __initdata = { | |||
583 | &i2c_bfin_twi1_device, | 624 | &i2c_bfin_twi1_device, |
584 | #endif | 625 | #endif |
585 | #endif | 626 | #endif |
627 | |||
628 | #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) | ||
629 | &bfin_device_gpiokeys, | ||
630 | #endif | ||
631 | &ezkit_flash_device, | ||
586 | }; | 632 | }; |
587 | 633 | ||
588 | static int __init stamp_init(void) | 634 | static int __init stamp_init(void) |
diff --git a/arch/blackfin/mach-bf548/head.S b/arch/blackfin/mach-bf548/head.S index 74b34c7f3629..74fe258421a5 100644 --- a/arch/blackfin/mach-bf548/head.S +++ b/arch/blackfin/mach-bf548/head.S | |||
@@ -298,8 +298,8 @@ ENTRY(_start_dma_code) | |||
298 | w[p0] = r0.l; | 298 | w[p0] = r0.l; |
299 | ssync; | 299 | ssync; |
300 | 300 | ||
301 | p0.h = hi(SIC_IWR); | 301 | p0.h = hi(SIC_IWR0); |
302 | p0.l = lo(SIC_IWR); | 302 | p0.l = lo(SIC_IWR0); |
303 | r0.l = 0x1; | 303 | r0.l = 0x1; |
304 | r0.h = 0x0; | 304 | r0.h = 0x0; |
305 | [p0] = r0; | 305 | [p0] = r0; |
@@ -324,12 +324,25 @@ ENTRY(_start_dma_code) | |||
324 | w[p0] = r0.l; | 324 | w[p0] = r0.l; |
325 | ssync; | 325 | ssync; |
326 | 326 | ||
327 | #if defined(CONFIG_BF54x) | ||
328 | P2.H = hi(EBIU_RSTCTL); | ||
329 | P2.L = lo(EBIU_RSTCTL); | ||
330 | R0 = [P2]; | ||
331 | BITSET (R0, 3); | ||
332 | #else | ||
327 | P2.H = hi(EBIU_SDGCTL); | 333 | P2.H = hi(EBIU_SDGCTL); |
328 | P2.L = lo(EBIU_SDGCTL); | 334 | P2.L = lo(EBIU_SDGCTL); |
329 | R0 = [P2]; | 335 | R0 = [P2]; |
330 | BITSET (R0, 24); | 336 | BITSET (R0, 24); |
337 | #endif | ||
331 | [P2] = R0; | 338 | [P2] = R0; |
332 | SSYNC; | 339 | SSYNC; |
340 | #if defined(CONFIG_BF54x) | ||
341 | .LSRR_MODE: | ||
342 | R0 = [P2]; | ||
343 | CC = BITTST(R0, 4); | ||
344 | if !CC JUMP .LSRR_MODE; | ||
345 | #endif | ||
333 | 346 | ||
334 | r0 = CONFIG_VCO_MULT & 63; /* Load the VCO multiplier */ | 347 | r0 = CONFIG_VCO_MULT & 63; /* Load the VCO multiplier */ |
335 | r0 = r0 << 9; /* Shift it over, */ | 348 | r0 = r0 << 9; /* Shift it over, */ |
@@ -361,6 +374,39 @@ ENTRY(_start_dma_code) | |||
361 | w[p0] = r0.l; | 374 | w[p0] = r0.l; |
362 | ssync; | 375 | ssync; |
363 | 376 | ||
377 | #if defined(CONFIG_BF54x) | ||
378 | P2.H = hi(EBIU_RSTCTL); | ||
379 | P2.L = lo(EBIU_RSTCTL); | ||
380 | R0 = [P2]; | ||
381 | CC = BITTST(R0, 0); | ||
382 | if CC jump .Lskipddrrst; | ||
383 | BITSET (R0, 0); | ||
384 | .Lskipddrrst: | ||
385 | BITCLR (R0, 3); | ||
386 | [P2] = R0; | ||
387 | SSYNC; | ||
388 | |||
389 | p0.l = lo(EBIU_DDRCTL0); | ||
390 | p0.h = hi(EBIU_DDRCTL0); | ||
391 | r0.l = lo(mem_DDRCTL0); | ||
392 | r0.h = hi(mem_DDRCTL0); | ||
393 | [p0] = r0; | ||
394 | ssync; | ||
395 | |||
396 | p0.l = lo(EBIU_DDRCTL1); | ||
397 | p0.h = hi(EBIU_DDRCTL1); | ||
398 | r0.l = lo(mem_DDRCTL1); | ||
399 | r0.h = hi(mem_DDRCTL1); | ||
400 | [p0] = r0; | ||
401 | ssync; | ||
402 | |||
403 | p0.l = lo(EBIU_DDRCTL2); | ||
404 | p0.h = hi(EBIU_DDRCTL2); | ||
405 | r0.l = lo(mem_DDRCTL2); | ||
406 | r0.h = hi(mem_DDRCTL2); | ||
407 | [p0] = r0; | ||
408 | ssync; | ||
409 | #else | ||
364 | p0.l = lo(EBIU_SDRRC); | 410 | p0.l = lo(EBIU_SDRRC); |
365 | p0.h = hi(EBIU_SDRRC); | 411 | p0.h = hi(EBIU_SDRRC); |
366 | r0 = mem_SDRRC; | 412 | r0 = mem_SDRRC; |
@@ -394,9 +440,10 @@ ENTRY(_start_dma_code) | |||
394 | R1 = R1 | R0; | 440 | R1 = R1 | R0; |
395 | [P2] = R1; | 441 | [P2] = R1; |
396 | SSYNC; | 442 | SSYNC; |
443 | #endif | ||
397 | 444 | ||
398 | p0.h = hi(SIC_IWR); | 445 | p0.h = hi(SIC_IWR0); |
399 | p0.l = lo(SIC_IWR); | 446 | p0.l = lo(SIC_IWR0); |
400 | r0.l = lo(IWR_ENABLE_ALL); | 447 | r0.l = lo(IWR_ENABLE_ALL); |
401 | r0.h = hi(IWR_ENABLE_ALL); | 448 | r0.h = hi(IWR_ENABLE_ALL); |
402 | [p0] = r0; | 449 | [p0] = r0; |
diff --git a/arch/blackfin/mach-bf548/ints-priority.c b/arch/blackfin/mach-bf548/ints-priority.c index cb0ebac53c79..2665653cee37 100644 --- a/arch/blackfin/mach-bf548/ints-priority.c +++ b/arch/blackfin/mach-bf548/ints-priority.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Author: Michael Hennerich | 4 | * Author: Michael Hennerich |
5 | * | 5 | * |
6 | * Created: | 6 | * Created: |
7 | * Description: Set up the interupt priorities | 7 | * Description: Set up the interrupt priorities |
8 | * | 8 | * |
9 | * Modified: | 9 | * Modified: |
10 | * Copyright 2004-2006 Analog Devices Inc. | 10 | * Copyright 2004-2006 Analog Devices Inc. |
@@ -58,7 +58,7 @@ void program_IAR(void) | |||
58 | ((CONFIG_IRQ_PINT1 - 7) << IRQ_PINT1_POS) | | 58 | ((CONFIG_IRQ_PINT1 - 7) << IRQ_PINT1_POS) | |
59 | ((CONFIG_IRQ_MDMAS0 - 7) << IRQ_MDMAS0_POS) | | 59 | ((CONFIG_IRQ_MDMAS0 - 7) << IRQ_MDMAS0_POS) | |
60 | ((CONFIG_IRQ_MDMAS1 - 7) << IRQ_MDMAS1_POS) | | 60 | ((CONFIG_IRQ_MDMAS1 - 7) << IRQ_MDMAS1_POS) | |
61 | ((CONFIG_IRQ_WATCHDOG - 7) << IRQ_WATCHDOG_POS)); | 61 | ((CONFIG_IRQ_WATCHDOG - 7) << IRQ_WATCH_POS)); |
62 | 62 | ||
63 | bfin_write_SIC_IAR3(((CONFIG_IRQ_DMAC1_ERR - 7) << IRQ_DMAC1_ERR_POS) | | 63 | bfin_write_SIC_IAR3(((CONFIG_IRQ_DMAC1_ERR - 7) << IRQ_DMAC1_ERR_POS) | |
64 | ((CONFIG_IRQ_SPORT2_ERR - 7) << IRQ_SPORT2_ERR_POS) | | 64 | ((CONFIG_IRQ_SPORT2_ERR - 7) << IRQ_SPORT2_ERR_POS) | |
diff --git a/arch/blackfin/mach-bf561/boards/cm_bf561.c b/arch/blackfin/mach-bf561/boards/cm_bf561.c index c19cd29b948a..3a79a9061bdc 100644 --- a/arch/blackfin/mach-bf561/boards/cm_bf561.c +++ b/arch/blackfin/mach-bf561/boards/cm_bf561.c | |||
@@ -198,6 +198,13 @@ static struct platform_device bfin_spi0_device = { | |||
198 | #endif /* spi master and devices */ | 198 | #endif /* spi master and devices */ |
199 | 199 | ||
200 | 200 | ||
201 | #if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE) | ||
202 | static struct platform_device hitachi_fb_device = { | ||
203 | .name = "hitachi-tx09", | ||
204 | }; | ||
205 | #endif | ||
206 | |||
207 | |||
201 | #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) | 208 | #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) |
202 | 209 | ||
203 | static struct resource smc91x_resources[] = { | 210 | static struct resource smc91x_resources[] = { |
@@ -315,6 +322,10 @@ static struct platform_device bfin_pata_device = { | |||
315 | 322 | ||
316 | static struct platform_device *cm_bf561_devices[] __initdata = { | 323 | static struct platform_device *cm_bf561_devices[] __initdata = { |
317 | 324 | ||
325 | #if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE) | ||
326 | &hitachi_fb_device, | ||
327 | #endif | ||
328 | |||
318 | #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) | 329 | #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) |
319 | &bfin_uart_device, | 330 | &bfin_uart_device, |
320 | #endif | 331 | #endif |
diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c index 4ff8f6e7a11f..7601c3be1b5c 100644 --- a/arch/blackfin/mach-bf561/boards/ezkit.c +++ b/arch/blackfin/mach-bf561/boards/ezkit.c | |||
@@ -29,6 +29,9 @@ | |||
29 | 29 | ||
30 | #include <linux/device.h> | 30 | #include <linux/device.h> |
31 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
32 | #include <linux/mtd/mtd.h> | ||
33 | #include <linux/mtd/partitions.h> | ||
34 | #include <linux/mtd/physmap.h> | ||
32 | #include <linux/spi/spi.h> | 35 | #include <linux/spi/spi.h> |
33 | #include <linux/irq.h> | 36 | #include <linux/irq.h> |
34 | #include <linux/interrupt.h> | 37 | #include <linux/interrupt.h> |
@@ -155,6 +158,44 @@ static struct platform_device bfin_uart_device = { | |||
155 | }; | 158 | }; |
156 | #endif | 159 | #endif |
157 | 160 | ||
161 | static struct mtd_partition ezkit_partitions[] = { | ||
162 | { | ||
163 | .name = "Bootloader", | ||
164 | .size = 0x20000, | ||
165 | .offset = 0, | ||
166 | }, { | ||
167 | .name = "Kernel", | ||
168 | .size = 0xE0000, | ||
169 | .offset = MTDPART_OFS_APPEND, | ||
170 | }, { | ||
171 | .name = "RootFS", | ||
172 | .size = MTDPART_SIZ_FULL, | ||
173 | .offset = MTDPART_OFS_APPEND, | ||
174 | } | ||
175 | }; | ||
176 | |||
177 | static struct physmap_flash_data ezkit_flash_data = { | ||
178 | .width = 2, | ||
179 | .parts = ezkit_partitions, | ||
180 | .nr_parts = ARRAY_SIZE(ezkit_partitions), | ||
181 | }; | ||
182 | |||
183 | static struct resource ezkit_flash_resource = { | ||
184 | .start = 0x20000000, | ||
185 | .end = 0x207fffff, | ||
186 | .flags = IORESOURCE_MEM, | ||
187 | }; | ||
188 | |||
189 | static struct platform_device ezkit_flash_device = { | ||
190 | .name = "physmap-flash", | ||
191 | .id = 0, | ||
192 | .dev = { | ||
193 | .platform_data = &ezkit_flash_data, | ||
194 | }, | ||
195 | .num_resources = 1, | ||
196 | .resource = &ezkit_flash_resource, | ||
197 | }; | ||
198 | |||
158 | #ifdef CONFIG_SPI_BFIN | 199 | #ifdef CONFIG_SPI_BFIN |
159 | #if defined(CONFIG_SND_BLACKFIN_AD1836) \ | 200 | #if defined(CONFIG_SND_BLACKFIN_AD1836) \ |
160 | || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) | 201 | || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) |
@@ -246,6 +287,50 @@ static struct platform_device bfin_pata_device = { | |||
246 | }; | 287 | }; |
247 | #endif | 288 | #endif |
248 | 289 | ||
290 | #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) | ||
291 | #include <linux/input.h> | ||
292 | #include <linux/gpio_keys.h> | ||
293 | |||
294 | static struct gpio_keys_button bfin_gpio_keys_table[] = { | ||
295 | {BTN_0, GPIO_PF5, 1, "gpio-keys: BTN0"}, | ||
296 | {BTN_1, GPIO_PF6, 1, "gpio-keys: BTN1"}, | ||
297 | {BTN_2, GPIO_PF7, 1, "gpio-keys: BTN2"}, | ||
298 | {BTN_3, GPIO_PF8, 1, "gpio-keys: BTN3"}, | ||
299 | }; | ||
300 | |||
301 | static struct gpio_keys_platform_data bfin_gpio_keys_data = { | ||
302 | .buttons = bfin_gpio_keys_table, | ||
303 | .nbuttons = ARRAY_SIZE(bfin_gpio_keys_table), | ||
304 | }; | ||
305 | |||
306 | static struct platform_device bfin_device_gpiokeys = { | ||
307 | .name = "gpio-keys", | ||
308 | .dev = { | ||
309 | .platform_data = &bfin_gpio_keys_data, | ||
310 | }, | ||
311 | }; | ||
312 | #endif | ||
313 | |||
314 | #if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) | ||
315 | #include <linux/i2c-gpio.h> | ||
316 | |||
317 | static struct i2c_gpio_platform_data i2c_gpio_data = { | ||
318 | .sda_pin = 1, | ||
319 | .scl_pin = 0, | ||
320 | .sda_is_open_drain = 0, | ||
321 | .scl_is_open_drain = 0, | ||
322 | .udelay = 40, | ||
323 | }; | ||
324 | |||
325 | static struct platform_device i2c_gpio_device = { | ||
326 | .name = "i2c-gpio", | ||
327 | .id = 0, | ||
328 | .dev = { | ||
329 | .platform_data = &i2c_gpio_data, | ||
330 | }, | ||
331 | }; | ||
332 | #endif | ||
333 | |||
249 | static struct platform_device *ezkit_devices[] __initdata = { | 334 | static struct platform_device *ezkit_devices[] __initdata = { |
250 | #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) | 335 | #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) |
251 | &smc91x_device, | 336 | &smc91x_device, |
@@ -258,12 +343,23 @@ static struct platform_device *ezkit_devices[] __initdata = { | |||
258 | #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) | 343 | #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) |
259 | &bfin_spi0_device, | 344 | &bfin_spi0_device, |
260 | #endif | 345 | #endif |
346 | |||
261 | #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) | 347 | #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) |
262 | &bfin_uart_device, | 348 | &bfin_uart_device, |
263 | #endif | 349 | #endif |
350 | |||
264 | #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) | 351 | #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) |
265 | &bfin_pata_device, | 352 | &bfin_pata_device, |
266 | #endif | 353 | #endif |
354 | |||
355 | #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) | ||
356 | &bfin_device_gpiokeys, | ||
357 | #endif | ||
358 | |||
359 | #if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) | ||
360 | &i2c_gpio_device, | ||
361 | #endif | ||
362 | &ezkit_flash_device, | ||
267 | }; | 363 | }; |
268 | 364 | ||
269 | static int __init ezkit_init(void) | 365 | static int __init ezkit_init(void) |
diff --git a/arch/blackfin/mach-bf561/coreb.c b/arch/blackfin/mach-bf561/coreb.c index 5d1d21b4c2a7..1b44e9e6dc3b 100644 --- a/arch/blackfin/mach-bf561/coreb.c +++ b/arch/blackfin/mach-bf561/coreb.c | |||
@@ -33,7 +33,9 @@ | |||
33 | #include <linux/ioport.h> | 33 | #include <linux/ioport.h> |
34 | #include <linux/module.h> | 34 | #include <linux/module.h> |
35 | #include <linux/uaccess.h> | 35 | #include <linux/uaccess.h> |
36 | #include <linux/fs.h> | ||
36 | #include <asm/dma.h> | 37 | #include <asm/dma.h> |
38 | #include <asm/cacheflush.h> | ||
37 | 39 | ||
38 | #define MODULE_VER "v0.1" | 40 | #define MODULE_VER "v0.1" |
39 | 41 | ||
@@ -90,11 +92,12 @@ static ssize_t coreb_write(struct file *file, const char *buf, size_t count, | |||
90 | 92 | ||
91 | coreb_dma_done = 0; | 93 | coreb_dma_done = 0; |
92 | 94 | ||
95 | flush_dcache_range((unsigned long)buf, (unsigned long)(buf+len)); | ||
93 | /* Source Channel */ | 96 | /* Source Channel */ |
94 | set_dma_start_addr(CH_MEM_STREAM2_SRC, (unsigned long)buf); | 97 | set_dma_start_addr(CH_MEM_STREAM2_SRC, (unsigned long)buf); |
95 | set_dma_x_count(CH_MEM_STREAM2_SRC, len); | 98 | set_dma_x_count(CH_MEM_STREAM2_SRC, len); |
96 | set_dma_x_modify(CH_MEM_STREAM2_SRC, sizeof(char)); | 99 | set_dma_x_modify(CH_MEM_STREAM2_SRC, sizeof(char)); |
97 | set_dma_config(CH_MEM_STREAM2_SRC, RESTART); | 100 | set_dma_config(CH_MEM_STREAM2_SRC, 0); |
98 | /* Destination Channel */ | 101 | /* Destination Channel */ |
99 | set_dma_start_addr(CH_MEM_STREAM2_DEST, coreb_base + p); | 102 | set_dma_start_addr(CH_MEM_STREAM2_DEST, coreb_base + p); |
100 | set_dma_x_count(CH_MEM_STREAM2_DEST, len); | 103 | set_dma_x_count(CH_MEM_STREAM2_DEST, len); |
@@ -135,11 +138,12 @@ static ssize_t coreb_read(struct file *file, char *buf, size_t count, | |||
135 | 138 | ||
136 | coreb_dma_done = 0; | 139 | coreb_dma_done = 0; |
137 | 140 | ||
141 | invalidate_dcache_range((unsigned long)buf, (unsigned long)(buf+len)); | ||
138 | /* Source Channel */ | 142 | /* Source Channel */ |
139 | set_dma_start_addr(CH_MEM_STREAM2_SRC, coreb_base + p); | 143 | set_dma_start_addr(CH_MEM_STREAM2_SRC, coreb_base + p); |
140 | set_dma_x_count(CH_MEM_STREAM2_SRC, len); | 144 | set_dma_x_count(CH_MEM_STREAM2_SRC, len); |
141 | set_dma_x_modify(CH_MEM_STREAM2_SRC, sizeof(char)); | 145 | set_dma_x_modify(CH_MEM_STREAM2_SRC, sizeof(char)); |
142 | set_dma_config(CH_MEM_STREAM2_SRC, RESTART); | 146 | set_dma_config(CH_MEM_STREAM2_SRC, 0); |
143 | /* Destination Channel */ | 147 | /* Destination Channel */ |
144 | set_dma_start_addr(CH_MEM_STREAM2_DEST, (unsigned long)buf); | 148 | set_dma_start_addr(CH_MEM_STREAM2_DEST, (unsigned long)buf); |
145 | set_dma_x_count(CH_MEM_STREAM2_DEST, len); | 149 | set_dma_x_count(CH_MEM_STREAM2_DEST, len); |
@@ -266,7 +270,7 @@ static int coreb_ioctl(struct inode *inode, struct file *file, | |||
266 | coreb_status |= COREB_IS_RUNNING; | 270 | coreb_status |= COREB_IS_RUNNING; |
267 | bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() & ~0x0020); | 271 | bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() & ~0x0020); |
268 | SSYNC(); | 272 | SSYNC(); |
269 | spin_lock_irq(&coreb_lock); | 273 | spin_unlock_irq(&coreb_lock); |
270 | break; | 274 | break; |
271 | #if defined(CONFIG_BF561_COREB_RESET) | 275 | #if defined(CONFIG_BF561_COREB_RESET) |
272 | case CMD_COREB_STOP: | 276 | case CMD_COREB_STOP: |
@@ -275,7 +279,7 @@ static int coreb_ioctl(struct inode *inode, struct file *file, | |||
275 | bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() | 0x0020); | 279 | bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() | 0x0020); |
276 | bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | 0x0080); | 280 | bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | 0x0080); |
277 | coreb_status &= ~COREB_IS_RUNNING; | 281 | coreb_status &= ~COREB_IS_RUNNING; |
278 | spin_lock_irq(&coreb_lock); | 282 | spin_unlock_irq(&coreb_lock); |
279 | break; | 283 | break; |
280 | case CMD_COREB_RESET: | 284 | case CMD_COREB_RESET: |
281 | printk(KERN_INFO "Resetting Core B\n"); | 285 | printk(KERN_INFO "Resetting Core B\n"); |
diff --git a/arch/blackfin/mach-common/Makefile b/arch/blackfin/mach-common/Makefile index 4d7733dfd5de..8636d4284bdb 100644 --- a/arch/blackfin/mach-common/Makefile +++ b/arch/blackfin/mach-common/Makefile | |||
@@ -3,10 +3,9 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := \ | 5 | obj-y := \ |
6 | cache.o cacheinit.o cplbhdlr.o cplbmgr.o entry.o \ | 6 | cache.o cacheinit.o entry.o \ |
7 | interrupt.o lock.o irqpanic.o arch_checks.o | 7 | interrupt.o lock.o irqpanic.o arch_checks.o |
8 | 8 | ||
9 | obj-$(CONFIG_CPLB_INFO) += cplbinfo.o | ||
10 | obj-$(CONFIG_BFIN_SINGLE_CORE) += ints-priority-sc.o | 9 | obj-$(CONFIG_BFIN_SINGLE_CORE) += ints-priority-sc.o |
11 | obj-$(CONFIG_BFIN_DUAL_CORE) += ints-priority-dc.o | 10 | obj-$(CONFIG_BFIN_DUAL_CORE) += ints-priority-dc.o |
12 | obj-$(CONFIG_PM) += pm.o dpmc.o | 11 | obj-$(CONFIG_PM) += pm.o dpmc.o |
diff --git a/arch/blackfin/mach-common/dpmc.S b/arch/blackfin/mach-common/dpmc.S index 39fbc2861107..b82c096e1980 100644 --- a/arch/blackfin/mach-common/dpmc.S +++ b/arch/blackfin/mach-common/dpmc.S | |||
@@ -38,6 +38,9 @@ ENTRY(_unmask_wdog_wakeup_evt) | |||
38 | #if defined(CONFIG_BF561) | 38 | #if defined(CONFIG_BF561) |
39 | P0.H = hi(SICA_IWR1); | 39 | P0.H = hi(SICA_IWR1); |
40 | P0.L = lo(SICA_IWR1); | 40 | P0.L = lo(SICA_IWR1); |
41 | #elif defined(CONFIG_BF54x) || defined(CONFIG_BF52x) | ||
42 | P0.h = HI(SIC_IWR0); | ||
43 | P0.l = LO(SIC_IWR0); | ||
41 | #else | 44 | #else |
42 | P0.h = HI(SIC_IWR); | 45 | P0.h = HI(SIC_IWR); |
43 | P0.l = LO(SIC_IWR); | 46 | P0.l = LO(SIC_IWR); |
@@ -172,7 +175,7 @@ ENTRY(_sleep_mode) | |||
172 | call _set_sic_iwr; | 175 | call _set_sic_iwr; |
173 | 176 | ||
174 | R0 = 0xFFFF (Z); | 177 | R0 = 0xFFFF (Z); |
175 | call _set_rtc_istat | 178 | call _set_rtc_istat; |
176 | 179 | ||
177 | P0.H = hi(PLL_CTL); | 180 | P0.H = hi(PLL_CTL); |
178 | P0.L = lo(PLL_CTL); | 181 | P0.L = lo(PLL_CTL); |
@@ -210,7 +213,7 @@ ENTRY(_hibernate_mode) | |||
210 | call _set_sic_iwr; | 213 | call _set_sic_iwr; |
211 | 214 | ||
212 | R0 = 0xFFFF (Z); | 215 | R0 = 0xFFFF (Z); |
213 | call _set_rtc_istat | 216 | call _set_rtc_istat; |
214 | 217 | ||
215 | P0.H = hi(VR_CTL); | 218 | P0.H = hi(VR_CTL); |
216 | P0.L = lo(VR_CTL); | 219 | P0.L = lo(VR_CTL); |
@@ -236,7 +239,7 @@ ENTRY(_deep_sleep) | |||
236 | 239 | ||
237 | call _set_sic_iwr; | 240 | call _set_sic_iwr; |
238 | 241 | ||
239 | call _set_sdram_srfs; | 242 | call _set_dram_srfs; |
240 | 243 | ||
241 | /* Clear all the interrupts,bits sticky */ | 244 | /* Clear all the interrupts,bits sticky */ |
242 | R0 = 0xFFFF (Z); | 245 | R0 = 0xFFFF (Z); |
@@ -253,7 +256,7 @@ ENTRY(_deep_sleep) | |||
253 | SSYNC; | 256 | SSYNC; |
254 | IDLE; | 257 | IDLE; |
255 | 258 | ||
256 | call _unset_sdram_srfs; | 259 | call _unset_dram_srfs; |
257 | 260 | ||
258 | call _test_pll_locked; | 261 | call _test_pll_locked; |
259 | 262 | ||
@@ -285,23 +288,22 @@ ENTRY(_sleep_deeper) | |||
285 | P3 = R0; | 288 | P3 = R0; |
286 | R0 = IWR_ENABLE(0); | 289 | R0 = IWR_ENABLE(0); |
287 | call _set_sic_iwr; | 290 | call _set_sic_iwr; |
288 | call _set_sdram_srfs; | 291 | call _set_dram_srfs; /* Set SDRAM Self Refresh */ |
289 | 292 | ||
290 | /* Clear all the interrupts,bits sticky */ | 293 | /* Clear all the interrupts,bits sticky */ |
291 | R0 = 0xFFFF (Z); | 294 | R0 = 0xFFFF (Z); |
292 | call _set_rtc_istat | 295 | call _set_rtc_istat; |
293 | |||
294 | P0.H = hi(PLL_DIV); | 296 | P0.H = hi(PLL_DIV); |
295 | P0.L = lo(PLL_DIV); | 297 | P0.L = lo(PLL_DIV); |
296 | R6 = W[P0](z); | 298 | R6 = W[P0](z); |
297 | R0.L = 0xF; | 299 | R0.L = 0xF; |
298 | W[P0] = R0.l; | 300 | W[P0] = R0.l; /* Set Max VCO to SCLK divider */ |
299 | 301 | ||
300 | P0.H = hi(PLL_CTL); | 302 | P0.H = hi(PLL_CTL); |
301 | P0.L = lo(PLL_CTL); | 303 | P0.L = lo(PLL_CTL); |
302 | R5 = W[P0](z); | 304 | R5 = W[P0](z); |
303 | R0.L = (CONFIG_MIN_VCO_HZ/CONFIG_CLKIN_HZ) << 9; | 305 | R0.L = (CONFIG_MIN_VCO_HZ/CONFIG_CLKIN_HZ) << 9; |
304 | W[P0] = R0.l; | 306 | W[P0] = R0.l; /* Set Min CLKIN to VCO multiplier */ |
305 | 307 | ||
306 | SSYNC; | 308 | SSYNC; |
307 | IDLE; | 309 | IDLE; |
@@ -317,29 +319,28 @@ ENTRY(_sleep_deeper) | |||
317 | R1 = R1|R2; | 319 | R1 = R1|R2; |
318 | 320 | ||
319 | R2 = DEPOSIT(R7, R1); | 321 | R2 = DEPOSIT(R7, R1); |
320 | W[P0] = R2; | 322 | W[P0] = R2; /* Set Min Core Voltage */ |
321 | 323 | ||
322 | SSYNC; | 324 | SSYNC; |
323 | IDLE; | 325 | IDLE; |
324 | 326 | ||
325 | call _test_pll_locked; | 327 | call _test_pll_locked; |
326 | 328 | ||
329 | R0 = P3; | ||
330 | call _set_sic_iwr; /* Set Awake from IDLE */ | ||
331 | |||
327 | P0.H = hi(PLL_CTL); | 332 | P0.H = hi(PLL_CTL); |
328 | P0.L = lo(PLL_CTL); | 333 | P0.L = lo(PLL_CTL); |
329 | R0 = W[P0](z); | 334 | R0 = W[P0](z); |
330 | BITSET (R0, 3); | 335 | BITSET (R0, 3); |
331 | W[P0] = R0.L; | 336 | W[P0] = R0.L; /* Turn CCLK OFF */ |
332 | |||
333 | R0 = P3; | ||
334 | call _set_sic_iwr; | ||
335 | |||
336 | SSYNC; | 337 | SSYNC; |
337 | IDLE; | 338 | IDLE; |
338 | 339 | ||
339 | call _test_pll_locked; | 340 | call _test_pll_locked; |
340 | 341 | ||
341 | R0 = IWR_ENABLE(0); | 342 | R0 = IWR_ENABLE(0); |
342 | call _set_sic_iwr; | 343 | call _set_sic_iwr; /* Set Awake from IDLE PLL */ |
343 | 344 | ||
344 | P0.H = hi(VR_CTL); | 345 | P0.H = hi(VR_CTL); |
345 | P0.L = lo(VR_CTL); | 346 | P0.L = lo(VR_CTL); |
@@ -352,15 +353,15 @@ ENTRY(_sleep_deeper) | |||
352 | 353 | ||
353 | P0.H = hi(PLL_DIV); | 354 | P0.H = hi(PLL_DIV); |
354 | P0.L = lo(PLL_DIV); | 355 | P0.L = lo(PLL_DIV); |
355 | W[P0]= R6; | 356 | W[P0]= R6; /* Restore CCLK and SCLK divider */ |
356 | 357 | ||
357 | P0.H = hi(PLL_CTL); | 358 | P0.H = hi(PLL_CTL); |
358 | P0.L = lo(PLL_CTL); | 359 | P0.L = lo(PLL_CTL); |
359 | w[p0] = R5; | 360 | w[p0] = R5; /* Restore VCO multiplier */ |
360 | IDLE; | 361 | IDLE; |
361 | call _test_pll_locked; | 362 | call _test_pll_locked; |
362 | 363 | ||
363 | call _unset_sdram_srfs; | 364 | call _unset_dram_srfs; /* SDRAM Self Refresh Off */ |
364 | 365 | ||
365 | STI R4; | 366 | STI R4; |
366 | 367 | ||
@@ -368,25 +369,47 @@ ENTRY(_sleep_deeper) | |||
368 | ( R7:0, P5:0 ) = [SP++]; | 369 | ( R7:0, P5:0 ) = [SP++]; |
369 | RTS; | 370 | RTS; |
370 | 371 | ||
371 | ENTRY(_set_sdram_srfs) | 372 | ENTRY(_set_dram_srfs) |
372 | /* set the sdram to self refresh mode */ | 373 | /* set the dram to self refresh mode */ |
374 | #if defined(CONFIG_BF54x) | ||
375 | P0.H = hi(EBIU_RSTCTL); | ||
376 | P0.L = lo(EBIU_RSTCTL); | ||
377 | R2 = [P0]; | ||
378 | R3.H = hi(SRREQ); | ||
379 | R3.L = lo(SRREQ); | ||
380 | #else | ||
373 | P0.H = hi(EBIU_SDGCTL); | 381 | P0.H = hi(EBIU_SDGCTL); |
374 | P0.L = lo(EBIU_SDGCTL); | 382 | P0.L = lo(EBIU_SDGCTL); |
375 | R2 = [P0]; | 383 | R2 = [P0]; |
376 | R3.H = hi(SRFS); | 384 | R3.H = hi(SRFS); |
377 | R3.L = lo(SRFS); | 385 | R3.L = lo(SRFS); |
386 | #endif | ||
378 | R2 = R2|R3; | 387 | R2 = R2|R3; |
379 | [P0] = R2; | 388 | [P0] = R2; |
380 | ssync; | 389 | ssync; |
390 | #if defined(CONFIG_BF54x) | ||
391 | .LSRR_MODE: | ||
392 | R2 = [P0]; | ||
393 | CC = BITTST(R2, 4); | ||
394 | if !CC JUMP .LSRR_MODE; | ||
395 | #endif | ||
381 | RTS; | 396 | RTS; |
382 | 397 | ||
383 | ENTRY(_unset_sdram_srfs) | 398 | ENTRY(_unset_dram_srfs) |
384 | /* set the sdram out of self refresh mode */ | 399 | /* set the dram out of self refresh mode */ |
400 | #if defined(CONFIG_BF54x) | ||
401 | P0.H = hi(EBIU_RSTCTL); | ||
402 | P0.L = lo(EBIU_RSTCTL); | ||
403 | R2 = [P0]; | ||
404 | R3.H = hi(SRREQ); | ||
405 | R3.L = lo(SRREQ); | ||
406 | #else | ||
385 | P0.H = hi(EBIU_SDGCTL); | 407 | P0.H = hi(EBIU_SDGCTL); |
386 | P0.L = lo(EBIU_SDGCTL); | 408 | P0.L = lo(EBIU_SDGCTL); |
387 | R2 = [P0]; | 409 | R2 = [P0]; |
388 | R3.H = hi(SRFS); | 410 | R3.H = hi(SRFS); |
389 | R3.L = lo(SRFS); | 411 | R3.L = lo(SRFS); |
412 | #endif | ||
390 | R3 = ~R3; | 413 | R3 = ~R3; |
391 | R2 = R2&R3; | 414 | R2 = R2&R3; |
392 | [P0] = R2; | 415 | [P0] = R2; |
@@ -394,8 +417,13 @@ ENTRY(_unset_sdram_srfs) | |||
394 | RTS; | 417 | RTS; |
395 | 418 | ||
396 | ENTRY(_set_sic_iwr) | 419 | ENTRY(_set_sic_iwr) |
420 | #if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) | ||
421 | P0.H = hi(SIC_IWR0); | ||
422 | P0.L = lo(SIC_IWR0); | ||
423 | #else | ||
397 | P0.H = hi(SIC_IWR); | 424 | P0.H = hi(SIC_IWR); |
398 | P0.L = lo(SIC_IWR); | 425 | P0.L = lo(SIC_IWR); |
426 | #endif | ||
399 | [P0] = R0; | 427 | [P0] = R0; |
400 | SSYNC; | 428 | SSYNC; |
401 | RTS; | 429 | RTS; |
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index dc9d3ee2e691..56ff51bc8c21 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S | |||
@@ -95,6 +95,9 @@ ENTRY(_ex_workaround_261) | |||
95 | R6 = 0x26; /* Data CPLB Miss */ | 95 | R6 = 0x26; /* Data CPLB Miss */ |
96 | cc = R6 == R7; | 96 | cc = R6 == R7; |
97 | if cc jump _ex_dcplb_miss (BP); | 97 | if cc jump _ex_dcplb_miss (BP); |
98 | R6 = 0x23; /* Data CPLB Miss */ | ||
99 | cc = R6 == R7; | ||
100 | if cc jump _ex_dcplb_viol (BP); | ||
98 | /* Handle 0x23 Data CPLB Protection Violation | 101 | /* Handle 0x23 Data CPLB Protection Violation |
99 | * and Data CPLB Multiple Hits - Linux Trap Zero | 102 | * and Data CPLB Multiple Hits - Linux Trap Zero |
100 | */ | 103 | */ |
@@ -102,17 +105,33 @@ ENTRY(_ex_workaround_261) | |||
102 | ENDPROC(_ex_workaround_261) | 105 | ENDPROC(_ex_workaround_261) |
103 | 106 | ||
104 | #else | 107 | #else |
108 | #ifdef CONFIG_MPU | ||
109 | #define _ex_dviol _ex_dcplb_viol | ||
110 | #else | ||
105 | #define _ex_dviol _ex_trap_c | 111 | #define _ex_dviol _ex_trap_c |
112 | #endif | ||
106 | #define _ex_dmiss _ex_dcplb_miss | 113 | #define _ex_dmiss _ex_dcplb_miss |
107 | #define _ex_dmult _ex_trap_c | 114 | #define _ex_dmult _ex_trap_c |
108 | #endif | 115 | #endif |
109 | 116 | ||
117 | |||
118 | ENTRY(_ex_dcplb_viol) | ||
110 | ENTRY(_ex_dcplb_miss) | 119 | ENTRY(_ex_dcplb_miss) |
111 | ENTRY(_ex_icplb_miss) | 120 | ENTRY(_ex_icplb_miss) |
112 | (R7:6,P5:4) = [sp++]; | 121 | (R7:6,P5:4) = [sp++]; |
113 | ASTAT = [sp++]; | 122 | ASTAT = [sp++]; |
114 | SAVE_ALL_SYS | 123 | SAVE_ALL_SYS |
124 | #ifdef CONFIG_MPU | ||
125 | R0 = SEQSTAT; | ||
126 | R1 = SP; | ||
127 | sp += -12; | ||
128 | call _cplb_hdr; | ||
129 | sp += 12; | ||
130 | CC = R0 == 0; | ||
131 | IF !CC JUMP _handle_bad_cplb; | ||
132 | #else | ||
115 | call __cplb_hdr; | 133 | call __cplb_hdr; |
134 | #endif | ||
116 | DEBUG_START_HWTRACE(p5, r7) | 135 | DEBUG_START_HWTRACE(p5, r7) |
117 | RESTORE_ALL_SYS | 136 | RESTORE_ALL_SYS |
118 | SP = EX_SCRATCH_REG; | 137 | SP = EX_SCRATCH_REG; |
@@ -329,7 +348,7 @@ ENTRY(_exception_to_level5) | |||
329 | R7 = R7 + R6; | 348 | R7 = R7 + R6; |
330 | P5 = R7; | 349 | P5 = R7; |
331 | R1 = [P5]; | 350 | R1 = [P5]; |
332 | [SP + 8] = r1; | 351 | [SP + PT_SEQSTAT] = r1; |
333 | 352 | ||
334 | r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */ | 353 | r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */ |
335 | SP += -12; | 354 | SP += -12; |
@@ -633,9 +652,7 @@ ENTRY(_ret_from_exception) | |||
633 | [sp + PT_IPEND] = r0; | 652 | [sp + PT_IPEND] = r0; |
634 | 653 | ||
635 | 1: | 654 | 1: |
636 | r1 = 0x37(Z); | 655 | r2 = LO(~0x37) (Z); |
637 | r2 = ~r1; | ||
638 | r2.h = 0; | ||
639 | r0 = r2 & r0; | 656 | r0 = r2 & r0; |
640 | cc = r0 == 0; | 657 | cc = r0 == 0; |
641 | if !cc jump 4f; /* if not return to user mode, get out */ | 658 | if !cc jump 4f; /* if not return to user mode, get out */ |
@@ -1364,6 +1381,7 @@ ENTRY(_sys_call_table) | |||
1364 | .long _sys_set_robust_list | 1381 | .long _sys_set_robust_list |
1365 | .long _sys_get_robust_list /* 355 */ | 1382 | .long _sys_get_robust_list /* 355 */ |
1366 | .long _sys_fallocate | 1383 | .long _sys_fallocate |
1384 | .long _sys_semtimedop | ||
1367 | .rept NR_syscalls-(.-_sys_call_table)/4 | 1385 | .rept NR_syscalls-(.-_sys_call_table)/4 |
1368 | .long _sys_ni_syscall | 1386 | .long _sys_ni_syscall |
1369 | .endr | 1387 | .endr |
diff --git a/arch/blackfin/mach-common/interrupt.S b/arch/blackfin/mach-common/interrupt.S index 4de376418a18..7f752c87fe46 100644 --- a/arch/blackfin/mach-common/interrupt.S +++ b/arch/blackfin/mach-common/interrupt.S | |||
@@ -34,9 +34,13 @@ | |||
34 | #include <asm/entry.h> | 34 | #include <asm/entry.h> |
35 | #include <asm/asm-offsets.h> | 35 | #include <asm/asm-offsets.h> |
36 | #include <asm/trace.h> | 36 | #include <asm/trace.h> |
37 | #include <asm/traps.h> | ||
38 | #include <asm/thread_info.h> | ||
37 | 39 | ||
38 | #include <asm/mach-common/context.S> | 40 | #include <asm/mach-common/context.S> |
39 | 41 | ||
42 | .extern _ret_from_exception | ||
43 | |||
40 | #ifdef CONFIG_I_ENTRY_L1 | 44 | #ifdef CONFIG_I_ENTRY_L1 |
41 | .section .l1.text | 45 | .section .l1.text |
42 | #else | 46 | #else |
@@ -117,8 +121,8 @@ __common_int_entry: | |||
117 | 121 | ||
118 | #if ANOMALY_05000283 || ANOMALY_05000315 | 122 | #if ANOMALY_05000283 || ANOMALY_05000315 |
119 | cc = r7 == r7; | 123 | cc = r7 == r7; |
120 | p5.h = 0xffc0; | 124 | p5.h = HI(CHIPID); |
121 | p5.l = 0x0014; | 125 | p5.l = LO(CHIPID); |
122 | if cc jump 1f; | 126 | if cc jump 1f; |
123 | r7.l = W[p5]; | 127 | r7.l = W[p5]; |
124 | 1: | 128 | 1: |
@@ -134,26 +138,22 @@ __common_int_entry: | |||
134 | 138 | ||
135 | /* interrupt routine for ivhw - 5 */ | 139 | /* interrupt routine for ivhw - 5 */ |
136 | ENTRY(_evt_ivhw) | 140 | ENTRY(_evt_ivhw) |
137 | SAVE_CONTEXT | 141 | SAVE_ALL_SYS |
138 | #ifdef CONFIG_FRAME_POINTER | 142 | #ifdef CONFIG_FRAME_POINTER |
139 | fp = 0; | 143 | fp = 0; |
140 | #endif | 144 | #endif |
145 | |||
141 | #if ANOMALY_05000283 | 146 | #if ANOMALY_05000283 |
142 | cc = r7 == r7; | 147 | cc = r7 == r7; |
143 | p5.h = 0xffc0; | 148 | p5.h = HI(CHIPID); |
144 | p5.l = 0x0014; | 149 | p5.l = LO(CHIPID); |
145 | if cc jump 1f; | 150 | if cc jump 1f; |
146 | r7.l = W[p5]; | 151 | r7.l = W[p5]; |
147 | 1: | 152 | 1: |
148 | #endif | 153 | #endif |
149 | 154 | ||
150 | trace_buffer_stop(p0, r0); | ||
151 | |||
152 | r0 = IRQ_HWERR; | ||
153 | r1 = sp; | ||
154 | |||
155 | #ifdef CONFIG_HARDWARE_PM | 155 | #ifdef CONFIG_HARDWARE_PM |
156 | r7 = SEQSTAT; | 156 | r7 = [sp + PT_SEQSTAT]; |
157 | r7 = r7 >>> 0xe; | 157 | r7 = r7 >>> 0xe; |
158 | r6 = 0x1F; | 158 | r6 = 0x1F; |
159 | r7 = r7 & r6; | 159 | r7 = r7 & r6; |
@@ -161,11 +161,29 @@ ENTRY(_evt_ivhw) | |||
161 | cc = r7 == r5; | 161 | cc = r7 == r5; |
162 | if cc jump .Lcall_do_ovf; /* deal with performance counter overflow */ | 162 | if cc jump .Lcall_do_ovf; /* deal with performance counter overflow */ |
163 | #endif | 163 | #endif |
164 | 164 | # We are going to dump something out, so make sure we print IPEND properly | |
165 | p2.l = lo(IPEND); | ||
166 | p2.h = hi(IPEND); | ||
167 | r0 = [p2]; | ||
168 | [sp + PT_IPEND] = r0; | ||
169 | |||
170 | /* set the EXCAUSE to HWERR for trap_c */ | ||
171 | r0 = [sp + PT_SEQSTAT]; | ||
172 | R1.L = LO(VEC_HWERR); | ||
173 | R1.H = HI(VEC_HWERR); | ||
174 | R0 = R0 | R1; | ||
175 | [sp + PT_SEQSTAT] = R0; | ||
176 | |||
177 | r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */ | ||
165 | SP += -12; | 178 | SP += -12; |
166 | call _irq_panic; | 179 | call _trap_c; |
167 | SP += 12; | 180 | SP += 12; |
181 | |||
182 | call _ret_from_exception; | ||
183 | .Lcommon_restore_all_sys: | ||
184 | RESTORE_ALL_SYS | ||
168 | rti; | 185 | rti; |
186 | |||
169 | #ifdef CONFIG_HARDWARE_PM | 187 | #ifdef CONFIG_HARDWARE_PM |
170 | .Lcall_do_ovf: | 188 | .Lcall_do_ovf: |
171 | 189 | ||
@@ -173,9 +191,11 @@ ENTRY(_evt_ivhw) | |||
173 | call _pm_overflow; | 191 | call _pm_overflow; |
174 | SP += 12; | 192 | SP += 12; |
175 | 193 | ||
176 | jump .Lcommon_restore_context; | 194 | jump .Lcommon_restore_all_sys; |
177 | #endif | 195 | #endif |
178 | 196 | ||
197 | ENDPROC(_evt_ivhw) | ||
198 | |||
179 | /* Interrupt routine for evt2 (NMI). | 199 | /* Interrupt routine for evt2 (NMI). |
180 | * We don't actually use this, so just return. | 200 | * We don't actually use this, so just return. |
181 | * For inner circle type details, please see: | 201 | * For inner circle type details, please see: |
diff --git a/arch/blackfin/mach-common/ints-priority-dc.c b/arch/blackfin/mach-common/ints-priority-dc.c index 4882f0e801a9..8d18d6b163bb 100644 --- a/arch/blackfin/mach-common/ints-priority-dc.c +++ b/arch/blackfin/mach-common/ints-priority-dc.c | |||
@@ -222,11 +222,12 @@ static void bf561_gpio_unmask_irq(unsigned int irq) | |||
222 | static unsigned int bf561_gpio_irq_startup(unsigned int irq) | 222 | static unsigned int bf561_gpio_irq_startup(unsigned int irq) |
223 | { | 223 | { |
224 | unsigned int ret; | 224 | unsigned int ret; |
225 | char buf[8]; | ||
225 | u16 gpionr = irq - IRQ_PF0; | 226 | u16 gpionr = irq - IRQ_PF0; |
226 | 227 | ||
227 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { | 228 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { |
228 | 229 | snprintf(buf, sizeof buf, "IRQ %d", irq); | |
229 | ret = gpio_request(gpionr, "IRQ"); | 230 | ret = gpio_request(gpionr, buf); |
230 | if (ret) | 231 | if (ret) |
231 | return ret; | 232 | return ret; |
232 | 233 | ||
@@ -250,6 +251,7 @@ static int bf561_gpio_irq_type(unsigned int irq, unsigned int type) | |||
250 | { | 251 | { |
251 | 252 | ||
252 | unsigned int ret; | 253 | unsigned int ret; |
254 | char buf[8]; | ||
253 | u16 gpionr = irq - IRQ_PF0; | 255 | u16 gpionr = irq - IRQ_PF0; |
254 | 256 | ||
255 | 257 | ||
@@ -265,8 +267,8 @@ static int bf561_gpio_irq_type(unsigned int irq, unsigned int type) | |||
265 | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { | 267 | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { |
266 | 268 | ||
267 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { | 269 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { |
268 | 270 | snprintf(buf, sizeof buf, "IRQ %d", irq); | |
269 | ret = gpio_request(gpionr, "IRQ"); | 271 | ret = gpio_request(gpionr, buf); |
270 | if (ret) | 272 | if (ret) |
271 | return ret; | 273 | return ret; |
272 | 274 | ||
diff --git a/arch/blackfin/mach-common/ints-priority-sc.c b/arch/blackfin/mach-common/ints-priority-sc.c index 147f0731087a..dec42acb5de0 100644 --- a/arch/blackfin/mach-common/ints-priority-sc.c +++ b/arch/blackfin/mach-common/ints-priority-sc.c | |||
@@ -313,6 +313,7 @@ static void bfin_demux_error_irq(unsigned int int_err_irq, | |||
313 | static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)]; | 313 | static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)]; |
314 | static unsigned short gpio_edge_triggered[gpio_bank(MAX_BLACKFIN_GPIOS)]; | 314 | static unsigned short gpio_edge_triggered[gpio_bank(MAX_BLACKFIN_GPIOS)]; |
315 | 315 | ||
316 | |||
316 | static void bfin_gpio_ack_irq(unsigned int irq) | 317 | static void bfin_gpio_ack_irq(unsigned int irq) |
317 | { | 318 | { |
318 | u16 gpionr = irq - IRQ_PF0; | 319 | u16 gpionr = irq - IRQ_PF0; |
@@ -352,9 +353,11 @@ static unsigned int bfin_gpio_irq_startup(unsigned int irq) | |||
352 | { | 353 | { |
353 | unsigned int ret; | 354 | unsigned int ret; |
354 | u16 gpionr = irq - IRQ_PF0; | 355 | u16 gpionr = irq - IRQ_PF0; |
356 | char buf[8]; | ||
355 | 357 | ||
356 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { | 358 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { |
357 | ret = gpio_request(gpionr, "IRQ"); | 359 | snprintf(buf, sizeof buf, "IRQ %d", irq); |
360 | ret = gpio_request(gpionr, buf); | ||
358 | if (ret) | 361 | if (ret) |
359 | return ret; | 362 | return ret; |
360 | } | 363 | } |
@@ -376,6 +379,7 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | |||
376 | { | 379 | { |
377 | 380 | ||
378 | unsigned int ret; | 381 | unsigned int ret; |
382 | char buf[8]; | ||
379 | u16 gpionr = irq - IRQ_PF0; | 383 | u16 gpionr = irq - IRQ_PF0; |
380 | 384 | ||
381 | if (type == IRQ_TYPE_PROBE) { | 385 | if (type == IRQ_TYPE_PROBE) { |
@@ -388,7 +392,8 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | |||
388 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | | 392 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | |
389 | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { | 393 | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { |
390 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { | 394 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { |
391 | ret = gpio_request(gpionr, "IRQ"); | 395 | snprintf(buf, sizeof buf, "IRQ %d", irq); |
396 | ret = gpio_request(gpionr, buf); | ||
392 | if (ret) | 397 | if (ret) |
393 | return ret; | 398 | return ret; |
394 | } | 399 | } |
@@ -478,6 +483,10 @@ static void bfin_demux_gpio_irq(unsigned int intb_irq, | |||
478 | static unsigned char irq2pint_lut[NR_PINTS]; | 483 | static unsigned char irq2pint_lut[NR_PINTS]; |
479 | static unsigned char pint2irq_lut[NR_PINT_SYS_IRQS * NR_PINT_BITS]; | 484 | static unsigned char pint2irq_lut[NR_PINT_SYS_IRQS * NR_PINT_BITS]; |
480 | 485 | ||
486 | static unsigned int gpio_both_edge_triggered[NR_PINT_SYS_IRQS]; | ||
487 | static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)]; | ||
488 | |||
489 | |||
481 | struct pin_int_t { | 490 | struct pin_int_t { |
482 | unsigned int mask_set; | 491 | unsigned int mask_set; |
483 | unsigned int mask_clear; | 492 | unsigned int mask_clear; |
@@ -544,13 +553,20 @@ void init_pint_lut(void) | |||
544 | 553 | ||
545 | } | 554 | } |
546 | 555 | ||
547 | static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)]; | ||
548 | |||
549 | static void bfin_gpio_ack_irq(unsigned int irq) | 556 | static void bfin_gpio_ack_irq(unsigned int irq) |
550 | { | 557 | { |
551 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | 558 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; |
559 | u32 pintbit = PINT_BIT(pint_val); | ||
560 | u8 bank = PINT_2_BANK(pint_val); | ||
561 | |||
562 | if (unlikely(gpio_both_edge_triggered[bank] & pintbit)) { | ||
563 | if (pint[bank]->invert_set & pintbit) | ||
564 | pint[bank]->invert_clear = pintbit; | ||
565 | else | ||
566 | pint[bank]->invert_set = pintbit; | ||
567 | } | ||
568 | pint[bank]->request = pintbit; | ||
552 | 569 | ||
553 | pint[PINT_2_BANK(pint_val)]->request = PINT_BIT(pint_val); | ||
554 | SSYNC(); | 570 | SSYNC(); |
555 | } | 571 | } |
556 | 572 | ||
@@ -560,6 +576,13 @@ static void bfin_gpio_mask_ack_irq(unsigned int irq) | |||
560 | u32 pintbit = PINT_BIT(pint_val); | 576 | u32 pintbit = PINT_BIT(pint_val); |
561 | u8 bank = PINT_2_BANK(pint_val); | 577 | u8 bank = PINT_2_BANK(pint_val); |
562 | 578 | ||
579 | if (unlikely(gpio_both_edge_triggered[bank] & pintbit)) { | ||
580 | if (pint[bank]->invert_set & pintbit) | ||
581 | pint[bank]->invert_clear = pintbit; | ||
582 | else | ||
583 | pint[bank]->invert_set = pintbit; | ||
584 | } | ||
585 | |||
563 | pint[bank]->request = pintbit; | 586 | pint[bank]->request = pintbit; |
564 | pint[bank]->mask_clear = pintbit; | 587 | pint[bank]->mask_clear = pintbit; |
565 | SSYNC(); | 588 | SSYNC(); |
@@ -587,7 +610,8 @@ static void bfin_gpio_unmask_irq(unsigned int irq) | |||
587 | static unsigned int bfin_gpio_irq_startup(unsigned int irq) | 610 | static unsigned int bfin_gpio_irq_startup(unsigned int irq) |
588 | { | 611 | { |
589 | unsigned int ret; | 612 | unsigned int ret; |
590 | u16 gpionr = irq - IRQ_PA0; | 613 | char buf[8]; |
614 | u16 gpionr = irq_to_gpio(irq); | ||
591 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | 615 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; |
592 | 616 | ||
593 | if (pint_val == IRQ_NOT_AVAIL) { | 617 | if (pint_val == IRQ_NOT_AVAIL) { |
@@ -598,7 +622,8 @@ static unsigned int bfin_gpio_irq_startup(unsigned int irq) | |||
598 | } | 622 | } |
599 | 623 | ||
600 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { | 624 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { |
601 | ret = gpio_request(gpionr, "IRQ"); | 625 | snprintf(buf, sizeof buf, "IRQ %d", irq); |
626 | ret = gpio_request(gpionr, buf); | ||
602 | if (ret) | 627 | if (ret) |
603 | return ret; | 628 | return ret; |
604 | } | 629 | } |
@@ -611,16 +636,19 @@ static unsigned int bfin_gpio_irq_startup(unsigned int irq) | |||
611 | 636 | ||
612 | static void bfin_gpio_irq_shutdown(unsigned int irq) | 637 | static void bfin_gpio_irq_shutdown(unsigned int irq) |
613 | { | 638 | { |
639 | u16 gpionr = irq_to_gpio(irq); | ||
640 | |||
614 | bfin_gpio_mask_irq(irq); | 641 | bfin_gpio_mask_irq(irq); |
615 | gpio_free(irq - IRQ_PA0); | 642 | gpio_free(gpionr); |
616 | gpio_enabled[gpio_bank(irq - IRQ_PA0)] &= ~gpio_bit(irq - IRQ_PA0); | 643 | gpio_enabled[gpio_bank(gpionr)] &= ~gpio_bit(gpionr); |
617 | } | 644 | } |
618 | 645 | ||
619 | static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | 646 | static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) |
620 | { | 647 | { |
621 | 648 | ||
622 | unsigned int ret; | 649 | unsigned int ret; |
623 | u16 gpionr = irq - IRQ_PA0; | 650 | char buf[8]; |
651 | u16 gpionr = irq_to_gpio(irq); | ||
624 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | 652 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; |
625 | u32 pintbit = PINT_BIT(pint_val); | 653 | u32 pintbit = PINT_BIT(pint_val); |
626 | u8 bank = PINT_2_BANK(pint_val); | 654 | u8 bank = PINT_2_BANK(pint_val); |
@@ -638,7 +666,8 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | |||
638 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | | 666 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | |
639 | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { | 667 | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { |
640 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { | 668 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { |
641 | ret = gpio_request(gpionr, "IRQ"); | 669 | snprintf(buf, sizeof buf, "IRQ %d", irq); |
670 | ret = gpio_request(gpionr, buf); | ||
642 | if (ret) | 671 | if (ret) |
643 | return ret; | 672 | return ret; |
644 | } | 673 | } |
@@ -651,28 +680,33 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | |||
651 | 680 | ||
652 | gpio_direction_input(gpionr); | 681 | gpio_direction_input(gpionr); |
653 | 682 | ||
654 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { | ||
655 | pint[bank]->edge_set = pintbit; | ||
656 | } else { | ||
657 | pint[bank]->edge_clear = pintbit; | ||
658 | } | ||
659 | |||
660 | if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW))) | 683 | if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW))) |
661 | pint[bank]->invert_set = pintbit; /* low or falling edge denoted by one */ | 684 | pint[bank]->invert_set = pintbit; /* low or falling edge denoted by one */ |
662 | else | 685 | else |
663 | pint[bank]->invert_set = pintbit; /* high or rising edge denoted by zero */ | 686 | pint[bank]->invert_clear = pintbit; /* high or rising edge denoted by zero */ |
664 | 687 | ||
665 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) | 688 | if ((type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) |
666 | pint[bank]->invert_set = pintbit; | 689 | == (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { |
667 | else | ||
668 | pint[bank]->invert_set = pintbit; | ||
669 | 690 | ||
670 | SSYNC(); | 691 | gpio_both_edge_triggered[bank] |= pintbit; |
671 | 692 | ||
672 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) | 693 | if (gpio_get_value(gpionr)) |
694 | pint[bank]->invert_set = pintbit; | ||
695 | else | ||
696 | pint[bank]->invert_clear = pintbit; | ||
697 | } else { | ||
698 | gpio_both_edge_triggered[bank] &= ~pintbit; | ||
699 | } | ||
700 | |||
701 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { | ||
702 | pint[bank]->edge_set = pintbit; | ||
673 | set_irq_handler(irq, handle_edge_irq); | 703 | set_irq_handler(irq, handle_edge_irq); |
674 | else | 704 | } else { |
705 | pint[bank]->edge_clear = pintbit; | ||
675 | set_irq_handler(irq, handle_level_irq); | 706 | set_irq_handler(irq, handle_level_irq); |
707 | } | ||
708 | |||
709 | SSYNC(); | ||
676 | 710 | ||
677 | return 0; | 711 | return 0; |
678 | } | 712 | } |
diff --git a/arch/blackfin/mach-common/irqpanic.c b/arch/blackfin/mach-common/irqpanic.c index b22959b197e5..606ded9ff4e1 100644 --- a/arch/blackfin/mach-common/irqpanic.c +++ b/arch/blackfin/mach-common/irqpanic.c | |||
@@ -46,9 +46,6 @@ void irq_panic(int reason, struct pt_regs *regs) __attribute__ ((l1_text)); | |||
46 | */ | 46 | */ |
47 | asmlinkage void irq_panic(int reason, struct pt_regs *regs) | 47 | asmlinkage void irq_panic(int reason, struct pt_regs *regs) |
48 | { | 48 | { |
49 | int sig = 0; | ||
50 | siginfo_t info; | ||
51 | |||
52 | #ifdef CONFIG_DEBUG_ICACHE_CHECK | 49 | #ifdef CONFIG_DEBUG_ICACHE_CHECK |
53 | unsigned int cmd, tag, ca, cache_hi, cache_lo, *pa; | 50 | unsigned int cmd, tag, ca, cache_hi, cache_lo, *pa; |
54 | unsigned short i, j, die; | 51 | unsigned short i, j, die; |
@@ -136,53 +133,6 @@ asmlinkage void irq_panic(int reason, struct pt_regs *regs) | |||
136 | } | 133 | } |
137 | #endif | 134 | #endif |
138 | 135 | ||
139 | printk(KERN_EMERG "\n"); | ||
140 | printk(KERN_EMERG "Exception: IRQ 0x%x entered\n", reason); | ||
141 | printk(KERN_EMERG " code=[0x%08lx], stack frame=0x%08lx, " | ||
142 | " bad PC=0x%08lx\n", | ||
143 | (unsigned long)regs->seqstat, | ||
144 | (unsigned long)regs, | ||
145 | (unsigned long)regs->pc); | ||
146 | if (reason == 0x5) { | ||
147 | printk(KERN_EMERG "----------- HARDWARE ERROR -----------\n"); | ||
148 | |||
149 | /* There is only need to check for Hardware Errors, since other | ||
150 | * EXCEPTIONS are handled in TRAPS.c (MH) | ||
151 | */ | ||
152 | switch (regs->seqstat & SEQSTAT_HWERRCAUSE) { | ||
153 | case (SEQSTAT_HWERRCAUSE_SYSTEM_MMR): /* System MMR Error */ | ||
154 | info.si_code = BUS_ADRALN; | ||
155 | sig = SIGBUS; | ||
156 | printk(KERN_EMERG HWC_x2(KERN_EMERG)); | ||
157 | break; | ||
158 | case (SEQSTAT_HWERRCAUSE_EXTERN_ADDR): /* External Memory Addressing Error */ | ||
159 | info.si_code = BUS_ADRERR; | ||
160 | sig = SIGBUS; | ||
161 | printk(KERN_EMERG HWC_x3(KERN_EMERG)); | ||
162 | break; | ||
163 | case (SEQSTAT_HWERRCAUSE_PERF_FLOW): /* Performance Monitor Overflow */ | ||
164 | printk(KERN_EMERG HWC_x12(KERN_EMERG)); | ||
165 | break; | ||
166 | case (SEQSTAT_HWERRCAUSE_RAISE_5): /* RAISE 5 instruction */ | ||
167 | printk(KERN_EMERG HWC_x18(KERN_EMERG)); | ||
168 | break; | ||
169 | default: /* Reserved */ | ||
170 | printk(KERN_EMERG HWC_default(KERN_EMERG)); | ||
171 | break; | ||
172 | } | ||
173 | } | ||
174 | |||
175 | regs->ipend = bfin_read_IPEND(); | ||
176 | dump_bfin_process(regs); | ||
177 | dump_bfin_mem((void *)regs->pc); | ||
178 | show_regs(regs); | ||
179 | if (0 == (info.si_signo = sig) || 0 == user_mode(regs)) /* in kernelspace */ | ||
180 | panic("Unhandled IRQ or exceptions!\n"); | ||
181 | else { /* in userspace */ | ||
182 | info.si_errno = 0; | ||
183 | info.si_addr = (void *)regs->pc; | ||
184 | force_sig_info(sig, &info, current); | ||
185 | } | ||
186 | } | 136 | } |
187 | 137 | ||
188 | #ifdef CONFIG_HARDWARE_PM | 138 | #ifdef CONFIG_HARDWARE_PM |
diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c index dac51fb06f22..81930f7d06f1 100644 --- a/arch/blackfin/mach-common/pm.c +++ b/arch/blackfin/mach-common/pm.c | |||
@@ -77,7 +77,15 @@ void bfin_pm_suspend_standby_enter(void) | |||
77 | 77 | ||
78 | gpio_pm_restore(); | 78 | gpio_pm_restore(); |
79 | 79 | ||
80 | #if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) | ||
81 | bfin_write_SIC_IWR0(IWR_ENABLE_ALL); | ||
82 | bfin_write_SIC_IWR1(IWR_ENABLE_ALL); | ||
83 | # ifdef CONFIG_BF54x | ||
84 | bfin_write_SIC_IWR2(IWR_ENABLE_ALL); | ||
85 | # endif | ||
86 | #else | ||
80 | bfin_write_SIC_IWR(IWR_ENABLE_ALL); | 87 | bfin_write_SIC_IWR(IWR_ENABLE_ALL); |
88 | #endif | ||
81 | 89 | ||
82 | local_irq_restore(flags); | 90 | local_irq_restore(flags); |
83 | } | 91 | } |
@@ -85,7 +93,15 @@ void bfin_pm_suspend_standby_enter(void) | |||
85 | 93 | ||
86 | #if defined(CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR) | 94 | #if defined(CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR) |
87 | sleep_deeper(CONFIG_PM_WAKEUP_SIC_IWR); | 95 | sleep_deeper(CONFIG_PM_WAKEUP_SIC_IWR); |
96 | # if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) | ||
97 | bfin_write_SIC_IWR0(IWR_ENABLE_ALL); | ||
98 | bfin_write_SIC_IWR1(IWR_ENABLE_ALL); | ||
99 | # ifdef CONFIG_BF54x | ||
100 | bfin_write_SIC_IWR2(IWR_ENABLE_ALL); | ||
101 | # endif | ||
102 | # else | ||
88 | bfin_write_SIC_IWR(IWR_ENABLE_ALL); | 103 | bfin_write_SIC_IWR(IWR_ENABLE_ALL); |
104 | # endif | ||
89 | #endif /* CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR */ | 105 | #endif /* CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR */ |
90 | } | 106 | } |
91 | 107 | ||
diff --git a/arch/blackfin/mm/init.c b/arch/blackfin/mm/init.c index e97ea8fc8dc4..eb1a12ac9e33 100644 --- a/arch/blackfin/mm/init.c +++ b/arch/blackfin/mm/init.c | |||
@@ -128,8 +128,8 @@ void __init paging_init(void) | |||
128 | void __init mem_init(void) | 128 | void __init mem_init(void) |
129 | { | 129 | { |
130 | unsigned int codek = 0, datak = 0, initk = 0; | 130 | unsigned int codek = 0, datak = 0, initk = 0; |
131 | unsigned int reservedpages = 0, freepages = 0; | ||
131 | unsigned long tmp; | 132 | unsigned long tmp; |
132 | unsigned int len = _ramend - _rambase; | ||
133 | unsigned long start_mem = memory_start; | 133 | unsigned long start_mem = memory_start; |
134 | unsigned long end_mem = memory_end; | 134 | unsigned long end_mem = memory_end; |
135 | 135 | ||
@@ -138,19 +138,36 @@ void __init mem_init(void) | |||
138 | 138 | ||
139 | start_mem = PAGE_ALIGN(start_mem); | 139 | start_mem = PAGE_ALIGN(start_mem); |
140 | max_mapnr = num_physpages = MAP_NR(high_memory); | 140 | max_mapnr = num_physpages = MAP_NR(high_memory); |
141 | printk(KERN_INFO "Physical pages: %lx\n", num_physpages); | 141 | printk(KERN_INFO "Kernel managed physical pages: %lu\n", |
142 | num_physpages); | ||
142 | 143 | ||
143 | /* This will put all memory onto the freelists. */ | 144 | /* This will put all memory onto the freelists. */ |
144 | totalram_pages = free_all_bootmem(); | 145 | totalram_pages = free_all_bootmem(); |
145 | 146 | ||
147 | reservedpages = 0; | ||
148 | for (tmp = 0; tmp < max_mapnr; tmp++) | ||
149 | if (PageReserved(pfn_to_page(tmp))) | ||
150 | reservedpages++; | ||
151 | freepages = max_mapnr - reservedpages; | ||
152 | |||
153 | /* do not count in kernel image between _rambase and _ramstart */ | ||
154 | reservedpages -= (_ramstart - _rambase) >> PAGE_SHIFT; | ||
155 | #if (defined(CONFIG_BFIN_ICACHE) && ANOMALY_05000263) | ||
156 | reservedpages += (_ramend - memory_end - DMA_UNCACHED_REGION) >> | ||
157 | PAGE_SHIFT; | ||
158 | #endif | ||
159 | |||
146 | codek = (_etext - _stext) >> 10; | 160 | codek = (_etext - _stext) >> 10; |
147 | datak = (__bss_stop - __bss_start) >> 10; | ||
148 | initk = (__init_end - __init_begin) >> 10; | 161 | initk = (__init_end - __init_begin) >> 10; |
162 | datak = ((_ramstart - _rambase) >> 10) - codek - initk; | ||
149 | 163 | ||
150 | tmp = nr_free_pages() << PAGE_SHIFT; | ||
151 | printk(KERN_INFO | 164 | printk(KERN_INFO |
152 | "Memory available: %luk/%uk RAM, (%uk init code, %uk kernel code, %uk data, %uk dma)\n", | 165 | "Memory available: %luk/%luk RAM, " |
153 | tmp >> 10, len >> 10, initk, codek, datak, DMA_UNCACHED_REGION >> 10); | 166 | "(%uk init code, %uk kernel code, " |
167 | "%uk data, %uk dma, %uk reserved)\n", | ||
168 | (unsigned long) freepages << (PAGE_SHIFT-10), _ramend >> 10, | ||
169 | initk, codek, datak, DMA_UNCACHED_REGION >> 10, | ||
170 | (reservedpages << (PAGE_SHIFT-10))); | ||
154 | 171 | ||
155 | /* Initialize the blackfin L1 Memory. */ | 172 | /* Initialize the blackfin L1 Memory. */ |
156 | l1sram_init(); | 173 | l1sram_init(); |
@@ -184,13 +201,15 @@ static __init void free_init_pages(const char *what, unsigned long begin, unsign | |||
184 | #ifdef CONFIG_BLK_DEV_INITRD | 201 | #ifdef CONFIG_BLK_DEV_INITRD |
185 | void __init free_initrd_mem(unsigned long start, unsigned long end) | 202 | void __init free_initrd_mem(unsigned long start, unsigned long end) |
186 | { | 203 | { |
204 | #ifndef CONFIG_MPU | ||
187 | free_init_pages("initrd memory", start, end); | 205 | free_init_pages("initrd memory", start, end); |
206 | #endif | ||
188 | } | 207 | } |
189 | #endif | 208 | #endif |
190 | 209 | ||
191 | void __init free_initmem(void) | 210 | void __init free_initmem(void) |
192 | { | 211 | { |
193 | #ifdef CONFIG_RAMKERNEL | 212 | #if defined CONFIG_RAMKERNEL && !defined CONFIG_MPU |
194 | free_init_pages("unused kernel memory", | 213 | free_init_pages("unused kernel memory", |
195 | (unsigned long)(&__init_begin), | 214 | (unsigned long)(&__init_begin), |
196 | (unsigned long)(&__init_end)); | 215 | (unsigned long)(&__init_end)); |
diff --git a/arch/mips/au1000/common/platform.c b/arch/mips/au1000/common/platform.c index d51e18fb789b..841904cdef4d 100644 --- a/arch/mips/au1000/common/platform.c +++ b/arch/mips/au1000/common/platform.c | |||
@@ -270,6 +270,24 @@ static struct platform_device smc91x_device = { | |||
270 | 270 | ||
271 | #endif | 271 | #endif |
272 | 272 | ||
273 | /* All Alchemy demoboards with I2C have this #define in their headers */ | ||
274 | #ifdef SMBUS_PSC_BASE | ||
275 | static struct resource pbdb_smbus_resources[] = { | ||
276 | { | ||
277 | .start = SMBUS_PSC_BASE, | ||
278 | .end = SMBUS_PSC_BASE + 0x24 - 1, | ||
279 | .flags = IORESOURCE_MEM, | ||
280 | }, | ||
281 | }; | ||
282 | |||
283 | static struct platform_device pbdb_smbus_device = { | ||
284 | .name = "au1xpsc_smbus", | ||
285 | .id = 0, /* bus number */ | ||
286 | .num_resources = ARRAY_SIZE(pbdb_smbus_resources), | ||
287 | .resource = pbdb_smbus_resources, | ||
288 | }; | ||
289 | #endif | ||
290 | |||
273 | static struct platform_device *au1xxx_platform_devices[] __initdata = { | 291 | static struct platform_device *au1xxx_platform_devices[] __initdata = { |
274 | &au1xxx_usb_ohci_device, | 292 | &au1xxx_usb_ohci_device, |
275 | &au1x00_pcmcia_device, | 293 | &au1x00_pcmcia_device, |
@@ -287,6 +305,9 @@ static struct platform_device *au1xxx_platform_devices[] __initdata = { | |||
287 | #ifdef CONFIG_MIPS_DB1200 | 305 | #ifdef CONFIG_MIPS_DB1200 |
288 | &smc91x_device, | 306 | &smc91x_device, |
289 | #endif | 307 | #endif |
308 | #ifdef SMBUS_PSC_BASE | ||
309 | &pbdb_smbus_device, | ||
310 | #endif | ||
290 | }; | 311 | }; |
291 | 312 | ||
292 | int __init au1xxx_platform_init(void) | 313 | int __init au1xxx_platform_init(void) |
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c b/arch/ppc/platforms/83xx/mpc834x_sys.c index b84f8df325c4..cb0a7493ff64 100644 --- a/arch/ppc/platforms/83xx/mpc834x_sys.c +++ b/arch/ppc/platforms/83xx/mpc834x_sys.c | |||
@@ -224,26 +224,6 @@ mpc834x_sys_init_IRQ(void) | |||
224 | ipic_set_default_priority(); | 224 | ipic_set_default_priority(); |
225 | } | 225 | } |
226 | 226 | ||
227 | #if defined(CONFIG_I2C_MPC) && defined(CONFIG_SENSORS_DS1374) | ||
228 | extern ulong ds1374_get_rtc_time(void); | ||
229 | extern int ds1374_set_rtc_time(ulong); | ||
230 | |||
231 | static int __init | ||
232 | mpc834x_rtc_hookup(void) | ||
233 | { | ||
234 | struct timespec tv; | ||
235 | |||
236 | ppc_md.get_rtc_time = ds1374_get_rtc_time; | ||
237 | ppc_md.set_rtc_time = ds1374_set_rtc_time; | ||
238 | |||
239 | tv.tv_nsec = 0; | ||
240 | tv.tv_sec = (ppc_md.get_rtc_time)(); | ||
241 | do_settimeofday(&tv); | ||
242 | |||
243 | return 0; | ||
244 | } | ||
245 | late_initcall(mpc834x_rtc_hookup); | ||
246 | #endif | ||
247 | static __inline__ void | 227 | static __inline__ void |
248 | mpc834x_sys_set_bat(void) | 228 | mpc834x_sys_set_bat(void) |
249 | { | 229 | { |
diff --git a/arch/ppc/platforms/85xx/tqm85xx.c b/arch/ppc/platforms/85xx/tqm85xx.c index 4ee2bd156dc5..27ce389c1224 100644 --- a/arch/ppc/platforms/85xx/tqm85xx.c +++ b/arch/ppc/platforms/85xx/tqm85xx.c | |||
@@ -258,27 +258,6 @@ int tqm85xx_show_cpuinfo(struct seq_file *m) | |||
258 | return 0; | 258 | return 0; |
259 | } | 259 | } |
260 | 260 | ||
261 | #if defined(CONFIG_I2C) && defined(CONFIG_SENSORS_DS1337) | ||
262 | extern ulong ds1337_get_rtc_time(void); | ||
263 | extern int ds1337_set_rtc_time(unsigned long nowtime); | ||
264 | |||
265 | static int __init | ||
266 | tqm85xx_rtc_hookup(void) | ||
267 | { | ||
268 | struct timespec tv; | ||
269 | |||
270 | ppc_md.set_rtc_time = ds1337_set_rtc_time; | ||
271 | ppc_md.get_rtc_time = ds1337_get_rtc_time; | ||
272 | |||
273 | tv.tv_nsec = 0; | ||
274 | tv.tv_sec = (ppc_md.get_rtc_time)(); | ||
275 | do_settimeofday(&tv); | ||
276 | |||
277 | return 0; | ||
278 | } | ||
279 | late_initcall(tqm85xx_rtc_hookup); | ||
280 | #endif | ||
281 | |||
282 | #ifdef CONFIG_PCI | 261 | #ifdef CONFIG_PCI |
283 | /* | 262 | /* |
284 | * interrupt routing | 263 | * interrupt routing |
diff --git a/arch/ppc/platforms/katana.c b/arch/ppc/platforms/katana.c index 52f63e6f0856..fe6e88cdb1cd 100644 --- a/arch/ppc/platforms/katana.c +++ b/arch/ppc/platforms/katana.c | |||
@@ -838,27 +838,6 @@ katana_find_end_of_memory(void) | |||
838 | return bdp->bi_memsize; | 838 | return bdp->bi_memsize; |
839 | } | 839 | } |
840 | 840 | ||
841 | #if defined(CONFIG_I2C_MV64XXX) && defined(CONFIG_SENSORS_M41T00) | ||
842 | extern ulong m41t00_get_rtc_time(void); | ||
843 | extern int m41t00_set_rtc_time(ulong); | ||
844 | |||
845 | static int __init | ||
846 | katana_rtc_hookup(void) | ||
847 | { | ||
848 | struct timespec tv; | ||
849 | |||
850 | ppc_md.get_rtc_time = m41t00_get_rtc_time; | ||
851 | ppc_md.set_rtc_time = m41t00_set_rtc_time; | ||
852 | |||
853 | tv.tv_nsec = 0; | ||
854 | tv.tv_sec = (ppc_md.get_rtc_time)(); | ||
855 | do_settimeofday(&tv); | ||
856 | |||
857 | return 0; | ||
858 | } | ||
859 | late_initcall(katana_rtc_hookup); | ||
860 | #endif | ||
861 | |||
862 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(CONFIG_SERIAL_MPSC_CONSOLE) | 841 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(CONFIG_SERIAL_MPSC_CONSOLE) |
863 | static void __init | 842 | static void __init |
864 | katana_map_io(void) | 843 | katana_map_io(void) |
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 1330061020ab..6ef54d27fc00 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
@@ -276,9 +276,6 @@ source "kernel/Kconfig.preempt" | |||
276 | 276 | ||
277 | source "mm/Kconfig" | 277 | source "mm/Kconfig" |
278 | 278 | ||
279 | config HOLES_IN_ZONE | ||
280 | def_bool y | ||
281 | |||
282 | comment "I/O subsystem configuration" | 279 | comment "I/O subsystem configuration" |
283 | 280 | ||
284 | config MACHCHK_WARNING | 281 | config MACHCHK_WARNING |
diff --git a/arch/s390/crypto/Kconfig b/arch/s390/crypto/Kconfig deleted file mode 100644 index d1defbbfcd81..000000000000 --- a/arch/s390/crypto/Kconfig +++ /dev/null | |||
@@ -1,60 +0,0 @@ | |||
1 | config CRYPTO_SHA1_S390 | ||
2 | tristate "SHA1 digest algorithm" | ||
3 | depends on S390 | ||
4 | select CRYPTO_ALGAPI | ||
5 | help | ||
6 | This is the s390 hardware accelerated implementation of the | ||
7 | SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2). | ||
8 | |||
9 | config CRYPTO_SHA256_S390 | ||
10 | tristate "SHA256 digest algorithm" | ||
11 | depends on S390 | ||
12 | select CRYPTO_ALGAPI | ||
13 | help | ||
14 | This is the s390 hardware accelerated implementation of the | ||
15 | SHA256 secure hash standard (DFIPS 180-2). | ||
16 | |||
17 | This version of SHA implements a 256 bit hash with 128 bits of | ||
18 | security against collision attacks. | ||
19 | |||
20 | config CRYPTO_DES_S390 | ||
21 | tristate "DES and Triple DES cipher algorithms" | ||
22 | depends on S390 | ||
23 | select CRYPTO_ALGAPI | ||
24 | select CRYPTO_BLKCIPHER | ||
25 | help | ||
26 | This us the s390 hardware accelerated implementation of the | ||
27 | DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3). | ||
28 | |||
29 | config CRYPTO_AES_S390 | ||
30 | tristate "AES cipher algorithms" | ||
31 | depends on S390 | ||
32 | select CRYPTO_ALGAPI | ||
33 | select CRYPTO_BLKCIPHER | ||
34 | help | ||
35 | This is the s390 hardware accelerated implementation of the | ||
36 | AES cipher algorithms (FIPS-197). AES uses the Rijndael | ||
37 | algorithm. | ||
38 | |||
39 | Rijndael appears to be consistently a very good performer in | ||
40 | both hardware and software across a wide range of computing | ||
41 | environments regardless of its use in feedback or non-feedback | ||
42 | modes. Its key setup time is excellent, and its key agility is | ||
43 | good. Rijndael's very low memory requirements make it very well | ||
44 | suited for restricted-space environments, in which it also | ||
45 | demonstrates excellent performance. Rijndael's operations are | ||
46 | among the easiest to defend against power and timing attacks. | ||
47 | |||
48 | On s390 the System z9-109 currently only supports the key size | ||
49 | of 128 bit. | ||
50 | |||
51 | config S390_PRNG | ||
52 | tristate "Pseudo random number generator device driver" | ||
53 | depends on S390 | ||
54 | default "m" | ||
55 | help | ||
56 | Select this option if you want to use the s390 pseudo random number | ||
57 | generator. The PRNG is part of the cryptographic processor functions | ||
58 | and uses triple-DES to generate secure random numbers like the | ||
59 | ANSI X9.17 standard. The PRNG is usable via the char device | ||
60 | /dev/prandom. | ||
diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c index 46c97058ebe1..a3f67f8b5427 100644 --- a/arch/s390/crypto/aes_s390.c +++ b/arch/s390/crypto/aes_s390.c | |||
@@ -516,7 +516,7 @@ static int __init aes_init(void) | |||
516 | /* z9 109 and z9 BC/EC only support 128 bit key length */ | 516 | /* z9 109 and z9 BC/EC only support 128 bit key length */ |
517 | if (keylen_flag == AES_KEYLEN_128) | 517 | if (keylen_flag == AES_KEYLEN_128) |
518 | printk(KERN_INFO | 518 | printk(KERN_INFO |
519 | "aes_s390: hardware acceleration only available for" | 519 | "aes_s390: hardware acceleration only available for " |
520 | "128 bit keys\n"); | 520 | "128 bit keys\n"); |
521 | 521 | ||
522 | ret = crypto_register_alg(&aes_alg); | 522 | ret = crypto_register_alg(&aes_alg); |
diff --git a/arch/s390/crypto/prng.c b/arch/s390/crypto/prng.c index 8eb3a1aedc22..0cfefddd8375 100644 --- a/arch/s390/crypto/prng.c +++ b/arch/s390/crypto/prng.c | |||
@@ -90,7 +90,7 @@ static ssize_t prng_read(struct file *file, char __user *ubuf, size_t nbytes, | |||
90 | int ret = 0; | 90 | int ret = 0; |
91 | int tmp; | 91 | int tmp; |
92 | 92 | ||
93 | /* nbytes can be arbitrary long, we spilt it into chunks */ | 93 | /* nbytes can be arbitrary length, we split it into chunks */ |
94 | while (nbytes) { | 94 | while (nbytes) { |
95 | /* same as in extract_entropy_user in random.c */ | 95 | /* same as in extract_entropy_user in random.c */ |
96 | if (need_resched()) { | 96 | if (need_resched()) { |
@@ -146,7 +146,7 @@ static ssize_t prng_read(struct file *file, char __user *ubuf, size_t nbytes, | |||
146 | return ret; | 146 | return ret; |
147 | } | 147 | } |
148 | 148 | ||
149 | static struct file_operations prng_fops = { | 149 | static const struct file_operations prng_fops = { |
150 | .owner = THIS_MODULE, | 150 | .owner = THIS_MODULE, |
151 | .open = &prng_open, | 151 | .open = &prng_open, |
152 | .release = NULL, | 152 | .release = NULL, |
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index 56cb71007cd9..b3b650a93c7c 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile | |||
@@ -31,7 +31,3 @@ S390_KEXEC_OBJS := machine_kexec.o crash.o | |||
31 | S390_KEXEC_OBJS += $(if $(CONFIG_64BIT),relocate_kernel64.o,relocate_kernel.o) | 31 | S390_KEXEC_OBJS += $(if $(CONFIG_64BIT),relocate_kernel64.o,relocate_kernel.o) |
32 | obj-$(CONFIG_KEXEC) += $(S390_KEXEC_OBJS) | 32 | obj-$(CONFIG_KEXEC) += $(S390_KEXEC_OBJS) |
33 | 33 | ||
34 | # | ||
35 | # This is just to get the dependencies... | ||
36 | # | ||
37 | binfmt_elf32.o: $(TOPDIR)/fs/binfmt_elf.c | ||
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index 1b3af7dab816..9f7b73b180f0 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c | |||
@@ -276,7 +276,7 @@ void __init startup_init(void) | |||
276 | create_kernel_nss(); | 276 | create_kernel_nss(); |
277 | sort_main_extable(); | 277 | sort_main_extable(); |
278 | setup_lowcore_early(); | 278 | setup_lowcore_early(); |
279 | sclp_readinfo_early(); | 279 | sclp_read_info_early(); |
280 | sclp_facilities_detect(); | 280 | sclp_facilities_detect(); |
281 | memsize = sclp_memory_detect(); | 281 | memsize = sclp_memory_detect(); |
282 | #ifndef CONFIG_64BIT | 282 | #ifndef CONFIG_64BIT |
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index a87b1976d409..79dccd206a6e 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S | |||
@@ -157,7 +157,7 @@ startup_continue: | |||
157 | .long 0xb2b10000 # store facility list | 157 | .long 0xb2b10000 # store facility list |
158 | tm 0xc8,0x08 # check bit for clearing-by-ASCE | 158 | tm 0xc8,0x08 # check bit for clearing-by-ASCE |
159 | bno 0f-.LPG1(%r13) | 159 | bno 0f-.LPG1(%r13) |
160 | lhi %r1,2094 | 160 | lhi %r1,2048 |
161 | lhi %r2,0 | 161 | lhi %r2,0 |
162 | .long 0xb98e2001 | 162 | .long 0xb98e2001 |
163 | oi 7(%r12),0x80 # set IDTE flag | 163 | oi 7(%r12),0x80 # set IDTE flag |
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index b97694fa62ec..db28cca81fef 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * arch/s390/kernel/ipl.c | 2 | * arch/s390/kernel/ipl.c |
3 | * ipl/reipl/dump support for Linux on s390. | 3 | * ipl/reipl/dump support for Linux on s390. |
4 | * | 4 | * |
5 | * Copyright (C) IBM Corp. 2005,2006 | 5 | * Copyright IBM Corp. 2005,2007 |
6 | * Author(s): Michael Holzheu <holzheu@de.ibm.com> | 6 | * Author(s): Michael Holzheu <holzheu@de.ibm.com> |
7 | * Heiko Carstens <heiko.carstens@de.ibm.com> | 7 | * Heiko Carstens <heiko.carstens@de.ibm.com> |
8 | * Volker Sameske <sameske@de.ibm.com> | 8 | * Volker Sameske <sameske@de.ibm.com> |
@@ -31,6 +31,43 @@ | |||
31 | #define IPL_FCP_DUMP_STR "fcp_dump" | 31 | #define IPL_FCP_DUMP_STR "fcp_dump" |
32 | #define IPL_NSS_STR "nss" | 32 | #define IPL_NSS_STR "nss" |
33 | 33 | ||
34 | #define DUMP_CCW_STR "ccw" | ||
35 | #define DUMP_FCP_STR "fcp" | ||
36 | #define DUMP_NONE_STR "none" | ||
37 | |||
38 | /* | ||
39 | * Four shutdown trigger types are supported: | ||
40 | * - panic | ||
41 | * - halt | ||
42 | * - power off | ||
43 | * - reipl | ||
44 | */ | ||
45 | #define ON_PANIC_STR "on_panic" | ||
46 | #define ON_HALT_STR "on_halt" | ||
47 | #define ON_POFF_STR "on_poff" | ||
48 | #define ON_REIPL_STR "on_reboot" | ||
49 | |||
50 | struct shutdown_action; | ||
51 | struct shutdown_trigger { | ||
52 | char *name; | ||
53 | struct shutdown_action *action; | ||
54 | }; | ||
55 | |||
56 | /* | ||
57 | * Five shutdown action types are supported: | ||
58 | */ | ||
59 | #define SHUTDOWN_ACTION_IPL_STR "ipl" | ||
60 | #define SHUTDOWN_ACTION_REIPL_STR "reipl" | ||
61 | #define SHUTDOWN_ACTION_DUMP_STR "dump" | ||
62 | #define SHUTDOWN_ACTION_VMCMD_STR "vmcmd" | ||
63 | #define SHUTDOWN_ACTION_STOP_STR "stop" | ||
64 | |||
65 | struct shutdown_action { | ||
66 | char *name; | ||
67 | void (*fn) (struct shutdown_trigger *trigger); | ||
68 | int (*init) (void); | ||
69 | }; | ||
70 | |||
34 | static char *ipl_type_str(enum ipl_type type) | 71 | static char *ipl_type_str(enum ipl_type type) |
35 | { | 72 | { |
36 | switch (type) { | 73 | switch (type) { |
@@ -54,10 +91,6 @@ enum dump_type { | |||
54 | DUMP_TYPE_FCP = 4, | 91 | DUMP_TYPE_FCP = 4, |
55 | }; | 92 | }; |
56 | 93 | ||
57 | #define DUMP_NONE_STR "none" | ||
58 | #define DUMP_CCW_STR "ccw" | ||
59 | #define DUMP_FCP_STR "fcp" | ||
60 | |||
61 | static char *dump_type_str(enum dump_type type) | 94 | static char *dump_type_str(enum dump_type type) |
62 | { | 95 | { |
63 | switch (type) { | 96 | switch (type) { |
@@ -99,30 +132,6 @@ enum dump_method { | |||
99 | DUMP_METHOD_FCP_DIAG, | 132 | DUMP_METHOD_FCP_DIAG, |
100 | }; | 133 | }; |
101 | 134 | ||
102 | enum shutdown_action { | ||
103 | SHUTDOWN_REIPL, | ||
104 | SHUTDOWN_DUMP, | ||
105 | SHUTDOWN_STOP, | ||
106 | }; | ||
107 | |||
108 | #define SHUTDOWN_REIPL_STR "reipl" | ||
109 | #define SHUTDOWN_DUMP_STR "dump" | ||
110 | #define SHUTDOWN_STOP_STR "stop" | ||
111 | |||
112 | static char *shutdown_action_str(enum shutdown_action action) | ||
113 | { | ||
114 | switch (action) { | ||
115 | case SHUTDOWN_REIPL: | ||
116 | return SHUTDOWN_REIPL_STR; | ||
117 | case SHUTDOWN_DUMP: | ||
118 | return SHUTDOWN_DUMP_STR; | ||
119 | case SHUTDOWN_STOP: | ||
120 | return SHUTDOWN_STOP_STR; | ||
121 | default: | ||
122 | return NULL; | ||
123 | } | ||
124 | } | ||
125 | |||
126 | static int diag308_set_works = 0; | 135 | static int diag308_set_works = 0; |
127 | 136 | ||
128 | static int reipl_capabilities = IPL_TYPE_UNKNOWN; | 137 | static int reipl_capabilities = IPL_TYPE_UNKNOWN; |
@@ -140,8 +149,6 @@ static enum dump_method dump_method = DUMP_METHOD_NONE; | |||
140 | static struct ipl_parameter_block *dump_block_fcp; | 149 | static struct ipl_parameter_block *dump_block_fcp; |
141 | static struct ipl_parameter_block *dump_block_ccw; | 150 | static struct ipl_parameter_block *dump_block_ccw; |
142 | 151 | ||
143 | static enum shutdown_action on_panic_action = SHUTDOWN_STOP; | ||
144 | |||
145 | static struct sclp_ipl_info sclp_ipl_info; | 152 | static struct sclp_ipl_info sclp_ipl_info; |
146 | 153 | ||
147 | int diag308(unsigned long subcode, void *addr) | 154 | int diag308(unsigned long subcode, void *addr) |
@@ -205,8 +212,8 @@ static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj, \ | |||
205 | struct kobj_attribute *attr, \ | 212 | struct kobj_attribute *attr, \ |
206 | const char *buf, size_t len) \ | 213 | const char *buf, size_t len) \ |
207 | { \ | 214 | { \ |
208 | if (sscanf(buf, _fmt_in, _value) != 1) \ | 215 | strncpy(_value, buf, sizeof(_value) - 1); \ |
209 | return -EINVAL; \ | 216 | strstrip(_value); \ |
210 | return len; \ | 217 | return len; \ |
211 | } \ | 218 | } \ |
212 | static struct kobj_attribute sys_##_prefix##_##_name##_attr = \ | 219 | static struct kobj_attribute sys_##_prefix##_##_name##_attr = \ |
@@ -245,33 +252,6 @@ static __init enum ipl_type get_ipl_type(void) | |||
245 | return IPL_TYPE_FCP; | 252 | return IPL_TYPE_FCP; |
246 | } | 253 | } |
247 | 254 | ||
248 | void __init setup_ipl_info(void) | ||
249 | { | ||
250 | ipl_info.type = get_ipl_type(); | ||
251 | switch (ipl_info.type) { | ||
252 | case IPL_TYPE_CCW: | ||
253 | ipl_info.data.ccw.dev_id.devno = ipl_devno; | ||
254 | ipl_info.data.ccw.dev_id.ssid = 0; | ||
255 | break; | ||
256 | case IPL_TYPE_FCP: | ||
257 | case IPL_TYPE_FCP_DUMP: | ||
258 | ipl_info.data.fcp.dev_id.devno = | ||
259 | IPL_PARMBLOCK_START->ipl_info.fcp.devno; | ||
260 | ipl_info.data.fcp.dev_id.ssid = 0; | ||
261 | ipl_info.data.fcp.wwpn = IPL_PARMBLOCK_START->ipl_info.fcp.wwpn; | ||
262 | ipl_info.data.fcp.lun = IPL_PARMBLOCK_START->ipl_info.fcp.lun; | ||
263 | break; | ||
264 | case IPL_TYPE_NSS: | ||
265 | strncpy(ipl_info.data.nss.name, kernel_nss_name, | ||
266 | sizeof(ipl_info.data.nss.name)); | ||
267 | break; | ||
268 | case IPL_TYPE_UNKNOWN: | ||
269 | default: | ||
270 | /* We have no info to copy */ | ||
271 | break; | ||
272 | } | ||
273 | } | ||
274 | |||
275 | struct ipl_info ipl_info; | 255 | struct ipl_info ipl_info; |
276 | EXPORT_SYMBOL_GPL(ipl_info); | 256 | EXPORT_SYMBOL_GPL(ipl_info); |
277 | 257 | ||
@@ -428,8 +408,74 @@ static struct attribute_group ipl_unknown_attr_group = { | |||
428 | 408 | ||
429 | static struct kset *ipl_kset; | 409 | static struct kset *ipl_kset; |
430 | 410 | ||
411 | static int __init ipl_register_fcp_files(void) | ||
412 | { | ||
413 | int rc; | ||
414 | |||
415 | rc = sysfs_create_group(&ipl_kset->kobj, &ipl_fcp_attr_group); | ||
416 | if (rc) | ||
417 | goto out; | ||
418 | rc = sysfs_create_bin_file(&ipl_kset->kobj, &ipl_parameter_attr); | ||
419 | if (rc) | ||
420 | goto out_ipl_parm; | ||
421 | rc = sysfs_create_bin_file(&ipl_kset->kobj, &ipl_scp_data_attr); | ||
422 | if (!rc) | ||
423 | goto out; | ||
424 | |||
425 | sysfs_remove_bin_file(&ipl_kset->kobj, &ipl_parameter_attr); | ||
426 | |||
427 | out_ipl_parm: | ||
428 | sysfs_remove_group(&ipl_kset->kobj, &ipl_fcp_attr_group); | ||
429 | out: | ||
430 | return rc; | ||
431 | } | ||
432 | |||
433 | static void ipl_run(struct shutdown_trigger *trigger) | ||
434 | { | ||
435 | diag308(DIAG308_IPL, NULL); | ||
436 | if (MACHINE_IS_VM) | ||
437 | __cpcmd("IPL", NULL, 0, NULL); | ||
438 | else if (ipl_info.type == IPL_TYPE_CCW) | ||
439 | reipl_ccw_dev(&ipl_info.data.ccw.dev_id); | ||
440 | } | ||
441 | |||
442 | static int ipl_init(void) | ||
443 | { | ||
444 | int rc; | ||
445 | |||
446 | ipl_kset = kset_create_and_add("ipl", NULL, firmware_kobj); | ||
447 | if (!ipl_kset) { | ||
448 | rc = -ENOMEM; | ||
449 | goto out; | ||
450 | } | ||
451 | switch (ipl_info.type) { | ||
452 | case IPL_TYPE_CCW: | ||
453 | rc = sysfs_create_group(&ipl_kset->kobj, &ipl_ccw_attr_group); | ||
454 | break; | ||
455 | case IPL_TYPE_FCP: | ||
456 | case IPL_TYPE_FCP_DUMP: | ||
457 | rc = ipl_register_fcp_files(); | ||
458 | break; | ||
459 | case IPL_TYPE_NSS: | ||
460 | rc = sysfs_create_group(&ipl_kset->kobj, &ipl_nss_attr_group); | ||
461 | break; | ||
462 | default: | ||
463 | rc = sysfs_create_group(&ipl_kset->kobj, | ||
464 | &ipl_unknown_attr_group); | ||
465 | break; | ||
466 | } | ||
467 | out: | ||
468 | if (rc) | ||
469 | panic("ipl_init failed: rc = %i\n", rc); | ||
470 | |||
471 | return 0; | ||
472 | } | ||
473 | |||
474 | static struct shutdown_action ipl_action = {SHUTDOWN_ACTION_IPL_STR, ipl_run, | ||
475 | ipl_init}; | ||
476 | |||
431 | /* | 477 | /* |
432 | * reipl section | 478 | * reipl shutdown action: Reboot Linux on shutdown. |
433 | */ | 479 | */ |
434 | 480 | ||
435 | /* FCP reipl device attributes */ | 481 | /* FCP reipl device attributes */ |
@@ -549,7 +595,9 @@ static int reipl_set_type(enum ipl_type type) | |||
549 | 595 | ||
550 | switch(type) { | 596 | switch(type) { |
551 | case IPL_TYPE_CCW: | 597 | case IPL_TYPE_CCW: |
552 | if (MACHINE_IS_VM) | 598 | if (diag308_set_works) |
599 | reipl_method = REIPL_METHOD_CCW_DIAG; | ||
600 | else if (MACHINE_IS_VM) | ||
553 | reipl_method = REIPL_METHOD_CCW_VM; | 601 | reipl_method = REIPL_METHOD_CCW_VM; |
554 | else | 602 | else |
555 | reipl_method = REIPL_METHOD_CCW_CIO; | 603 | reipl_method = REIPL_METHOD_CCW_CIO; |
@@ -600,143 +648,11 @@ static ssize_t reipl_type_store(struct kobject *kobj, | |||
600 | } | 648 | } |
601 | 649 | ||
602 | static struct kobj_attribute reipl_type_attr = | 650 | static struct kobj_attribute reipl_type_attr = |
603 | __ATTR(reipl_type, 0644, reipl_type_show, reipl_type_store); | 651 | __ATTR(reipl_type, 0644, reipl_type_show, reipl_type_store); |
604 | 652 | ||
605 | static struct kset *reipl_kset; | 653 | static struct kset *reipl_kset; |
606 | 654 | ||
607 | /* | 655 | void reipl_run(struct shutdown_trigger *trigger) |
608 | * dump section | ||
609 | */ | ||
610 | |||
611 | /* FCP dump device attributes */ | ||
612 | |||
613 | DEFINE_IPL_ATTR_RW(dump_fcp, wwpn, "0x%016llx\n", "%016llx\n", | ||
614 | dump_block_fcp->ipl_info.fcp.wwpn); | ||
615 | DEFINE_IPL_ATTR_RW(dump_fcp, lun, "0x%016llx\n", "%016llx\n", | ||
616 | dump_block_fcp->ipl_info.fcp.lun); | ||
617 | DEFINE_IPL_ATTR_RW(dump_fcp, bootprog, "%lld\n", "%lld\n", | ||
618 | dump_block_fcp->ipl_info.fcp.bootprog); | ||
619 | DEFINE_IPL_ATTR_RW(dump_fcp, br_lba, "%lld\n", "%lld\n", | ||
620 | dump_block_fcp->ipl_info.fcp.br_lba); | ||
621 | DEFINE_IPL_ATTR_RW(dump_fcp, device, "0.0.%04llx\n", "0.0.%llx\n", | ||
622 | dump_block_fcp->ipl_info.fcp.devno); | ||
623 | |||
624 | static struct attribute *dump_fcp_attrs[] = { | ||
625 | &sys_dump_fcp_device_attr.attr, | ||
626 | &sys_dump_fcp_wwpn_attr.attr, | ||
627 | &sys_dump_fcp_lun_attr.attr, | ||
628 | &sys_dump_fcp_bootprog_attr.attr, | ||
629 | &sys_dump_fcp_br_lba_attr.attr, | ||
630 | NULL, | ||
631 | }; | ||
632 | |||
633 | static struct attribute_group dump_fcp_attr_group = { | ||
634 | .name = IPL_FCP_STR, | ||
635 | .attrs = dump_fcp_attrs, | ||
636 | }; | ||
637 | |||
638 | /* CCW dump device attributes */ | ||
639 | |||
640 | DEFINE_IPL_ATTR_RW(dump_ccw, device, "0.0.%04llx\n", "0.0.%llx\n", | ||
641 | dump_block_ccw->ipl_info.ccw.devno); | ||
642 | |||
643 | static struct attribute *dump_ccw_attrs[] = { | ||
644 | &sys_dump_ccw_device_attr.attr, | ||
645 | NULL, | ||
646 | }; | ||
647 | |||
648 | static struct attribute_group dump_ccw_attr_group = { | ||
649 | .name = IPL_CCW_STR, | ||
650 | .attrs = dump_ccw_attrs, | ||
651 | }; | ||
652 | |||
653 | /* dump type */ | ||
654 | |||
655 | static int dump_set_type(enum dump_type type) | ||
656 | { | ||
657 | if (!(dump_capabilities & type)) | ||
658 | return -EINVAL; | ||
659 | switch(type) { | ||
660 | case DUMP_TYPE_CCW: | ||
661 | if (MACHINE_IS_VM) | ||
662 | dump_method = DUMP_METHOD_CCW_VM; | ||
663 | else if (diag308_set_works) | ||
664 | dump_method = DUMP_METHOD_CCW_DIAG; | ||
665 | else | ||
666 | dump_method = DUMP_METHOD_CCW_CIO; | ||
667 | break; | ||
668 | case DUMP_TYPE_FCP: | ||
669 | dump_method = DUMP_METHOD_FCP_DIAG; | ||
670 | break; | ||
671 | default: | ||
672 | dump_method = DUMP_METHOD_NONE; | ||
673 | } | ||
674 | dump_type = type; | ||
675 | return 0; | ||
676 | } | ||
677 | |||
678 | static ssize_t dump_type_show(struct kobject *kobj, | ||
679 | struct kobj_attribute *attr, char *page) | ||
680 | { | ||
681 | return sprintf(page, "%s\n", dump_type_str(dump_type)); | ||
682 | } | ||
683 | |||
684 | static ssize_t dump_type_store(struct kobject *kobj, | ||
685 | struct kobj_attribute *attr, | ||
686 | const char *buf, size_t len) | ||
687 | { | ||
688 | int rc = -EINVAL; | ||
689 | |||
690 | if (strncmp(buf, DUMP_NONE_STR, strlen(DUMP_NONE_STR)) == 0) | ||
691 | rc = dump_set_type(DUMP_TYPE_NONE); | ||
692 | else if (strncmp(buf, DUMP_CCW_STR, strlen(DUMP_CCW_STR)) == 0) | ||
693 | rc = dump_set_type(DUMP_TYPE_CCW); | ||
694 | else if (strncmp(buf, DUMP_FCP_STR, strlen(DUMP_FCP_STR)) == 0) | ||
695 | rc = dump_set_type(DUMP_TYPE_FCP); | ||
696 | return (rc != 0) ? rc : len; | ||
697 | } | ||
698 | |||
699 | static struct kobj_attribute dump_type_attr = | ||
700 | __ATTR(dump_type, 0644, dump_type_show, dump_type_store); | ||
701 | |||
702 | static struct kset *dump_kset; | ||
703 | |||
704 | /* | ||
705 | * Shutdown actions section | ||
706 | */ | ||
707 | |||
708 | static struct kset *shutdown_actions_kset; | ||
709 | |||
710 | /* on panic */ | ||
711 | |||
712 | static ssize_t on_panic_show(struct kobject *kobj, | ||
713 | struct kobj_attribute *attr, char *page) | ||
714 | { | ||
715 | return sprintf(page, "%s\n", shutdown_action_str(on_panic_action)); | ||
716 | } | ||
717 | |||
718 | static ssize_t on_panic_store(struct kobject *kobj, | ||
719 | struct kobj_attribute *attr, | ||
720 | const char *buf, size_t len) | ||
721 | { | ||
722 | if (strncmp(buf, SHUTDOWN_REIPL_STR, strlen(SHUTDOWN_REIPL_STR)) == 0) | ||
723 | on_panic_action = SHUTDOWN_REIPL; | ||
724 | else if (strncmp(buf, SHUTDOWN_DUMP_STR, | ||
725 | strlen(SHUTDOWN_DUMP_STR)) == 0) | ||
726 | on_panic_action = SHUTDOWN_DUMP; | ||
727 | else if (strncmp(buf, SHUTDOWN_STOP_STR, | ||
728 | strlen(SHUTDOWN_STOP_STR)) == 0) | ||
729 | on_panic_action = SHUTDOWN_STOP; | ||
730 | else | ||
731 | return -EINVAL; | ||
732 | |||
733 | return len; | ||
734 | } | ||
735 | |||
736 | static struct kobj_attribute on_panic_attr = | ||
737 | __ATTR(on_panic, 0644, on_panic_show, on_panic_store); | ||
738 | |||
739 | void do_reipl(void) | ||
740 | { | 656 | { |
741 | struct ccw_dev_id devid; | 657 | struct ccw_dev_id devid; |
742 | static char buf[100]; | 658 | static char buf[100]; |
@@ -745,8 +661,6 @@ void do_reipl(void) | |||
745 | switch (reipl_method) { | 661 | switch (reipl_method) { |
746 | case REIPL_METHOD_CCW_CIO: | 662 | case REIPL_METHOD_CCW_CIO: |
747 | devid.devno = reipl_block_ccw->ipl_info.ccw.devno; | 663 | devid.devno = reipl_block_ccw->ipl_info.ccw.devno; |
748 | if (ipl_info.type == IPL_TYPE_CCW && devid.devno == ipl_devno) | ||
749 | diag308(DIAG308_IPL, NULL); | ||
750 | devid.ssid = 0; | 664 | devid.ssid = 0; |
751 | reipl_ccw_dev(&devid); | 665 | reipl_ccw_dev(&devid); |
752 | break; | 666 | break; |
@@ -787,98 +701,6 @@ void do_reipl(void) | |||
787 | default: | 701 | default: |
788 | break; | 702 | break; |
789 | } | 703 | } |
790 | signal_processor(smp_processor_id(), sigp_stop_and_store_status); | ||
791 | } | ||
792 | |||
793 | static void do_dump(void) | ||
794 | { | ||
795 | struct ccw_dev_id devid; | ||
796 | static char buf[100]; | ||
797 | |||
798 | switch (dump_method) { | ||
799 | case DUMP_METHOD_CCW_CIO: | ||
800 | smp_send_stop(); | ||
801 | devid.devno = dump_block_ccw->ipl_info.ccw.devno; | ||
802 | devid.ssid = 0; | ||
803 | reipl_ccw_dev(&devid); | ||
804 | break; | ||
805 | case DUMP_METHOD_CCW_VM: | ||
806 | smp_send_stop(); | ||
807 | sprintf(buf, "STORE STATUS"); | ||
808 | __cpcmd(buf, NULL, 0, NULL); | ||
809 | sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno); | ||
810 | __cpcmd(buf, NULL, 0, NULL); | ||
811 | break; | ||
812 | case DUMP_METHOD_CCW_DIAG: | ||
813 | diag308(DIAG308_SET, dump_block_ccw); | ||
814 | diag308(DIAG308_DUMP, NULL); | ||
815 | break; | ||
816 | case DUMP_METHOD_FCP_DIAG: | ||
817 | diag308(DIAG308_SET, dump_block_fcp); | ||
818 | diag308(DIAG308_DUMP, NULL); | ||
819 | break; | ||
820 | case DUMP_METHOD_NONE: | ||
821 | default: | ||
822 | return; | ||
823 | } | ||
824 | printk(KERN_EMERG "Dump failed!\n"); | ||
825 | } | ||
826 | |||
827 | /* init functions */ | ||
828 | |||
829 | static int __init ipl_register_fcp_files(void) | ||
830 | { | ||
831 | int rc; | ||
832 | |||
833 | rc = sysfs_create_group(&ipl_kset->kobj, | ||
834 | &ipl_fcp_attr_group); | ||
835 | if (rc) | ||
836 | goto out; | ||
837 | rc = sysfs_create_bin_file(&ipl_kset->kobj, | ||
838 | &ipl_parameter_attr); | ||
839 | if (rc) | ||
840 | goto out_ipl_parm; | ||
841 | rc = sysfs_create_bin_file(&ipl_kset->kobj, | ||
842 | &ipl_scp_data_attr); | ||
843 | if (!rc) | ||
844 | goto out; | ||
845 | |||
846 | sysfs_remove_bin_file(&ipl_kset->kobj, &ipl_parameter_attr); | ||
847 | |||
848 | out_ipl_parm: | ||
849 | sysfs_remove_group(&ipl_kset->kobj, &ipl_fcp_attr_group); | ||
850 | out: | ||
851 | return rc; | ||
852 | } | ||
853 | |||
854 | static int __init ipl_init(void) | ||
855 | { | ||
856 | int rc; | ||
857 | |||
858 | ipl_kset = kset_create_and_add("ipl", NULL, firmware_kobj); | ||
859 | if (!ipl_kset) | ||
860 | return -ENOMEM; | ||
861 | switch (ipl_info.type) { | ||
862 | case IPL_TYPE_CCW: | ||
863 | rc = sysfs_create_group(&ipl_kset->kobj, | ||
864 | &ipl_ccw_attr_group); | ||
865 | break; | ||
866 | case IPL_TYPE_FCP: | ||
867 | case IPL_TYPE_FCP_DUMP: | ||
868 | rc = ipl_register_fcp_files(); | ||
869 | break; | ||
870 | case IPL_TYPE_NSS: | ||
871 | rc = sysfs_create_group(&ipl_kset->kobj, | ||
872 | &ipl_nss_attr_group); | ||
873 | break; | ||
874 | default: | ||
875 | rc = sysfs_create_group(&ipl_kset->kobj, | ||
876 | &ipl_unknown_attr_group); | ||
877 | break; | ||
878 | } | ||
879 | if (rc) | ||
880 | kset_unregister(ipl_kset); | ||
881 | return rc; | ||
882 | } | 704 | } |
883 | 705 | ||
884 | static void __init reipl_probe(void) | 706 | static void __init reipl_probe(void) |
@@ -923,6 +745,7 @@ static int __init reipl_ccw_init(void) | |||
923 | reipl_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION; | 745 | reipl_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION; |
924 | reipl_block_ccw->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN; | 746 | reipl_block_ccw->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN; |
925 | reipl_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW; | 747 | reipl_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW; |
748 | reipl_block_ccw->hdr.flags = DIAG308_FLAGS_LP_VALID; | ||
926 | /* check if read scp info worked and set loadparm */ | 749 | /* check if read scp info worked and set loadparm */ |
927 | if (sclp_ipl_info.is_valid) | 750 | if (sclp_ipl_info.is_valid) |
928 | memcpy(reipl_block_ccw->ipl_info.ccw.load_param, | 751 | memcpy(reipl_block_ccw->ipl_info.ccw.load_param, |
@@ -931,8 +754,7 @@ static int __init reipl_ccw_init(void) | |||
931 | /* read scp info failed: set empty loadparm (EBCDIC blanks) */ | 754 | /* read scp info failed: set empty loadparm (EBCDIC blanks) */ |
932 | memset(reipl_block_ccw->ipl_info.ccw.load_param, 0x40, | 755 | memset(reipl_block_ccw->ipl_info.ccw.load_param, 0x40, |
933 | LOADPARM_LEN); | 756 | LOADPARM_LEN); |
934 | /* FIXME: check for diag308_set_works when enabling diag ccw reipl */ | 757 | if (!MACHINE_IS_VM && !diag308_set_works) |
935 | if (!MACHINE_IS_VM) | ||
936 | sys_reipl_ccw_loadparm_attr.attr.mode = S_IRUGO; | 758 | sys_reipl_ccw_loadparm_attr.attr.mode = S_IRUGO; |
937 | if (ipl_info.type == IPL_TYPE_CCW) | 759 | if (ipl_info.type == IPL_TYPE_CCW) |
938 | reipl_block_ccw->ipl_info.ccw.devno = ipl_devno; | 760 | reipl_block_ccw->ipl_info.ccw.devno = ipl_devno; |
@@ -970,7 +792,7 @@ static int __init reipl_fcp_init(void) | |||
970 | return 0; | 792 | return 0; |
971 | } | 793 | } |
972 | 794 | ||
973 | static int __init reipl_init(void) | 795 | static int reipl_init(void) |
974 | { | 796 | { |
975 | int rc; | 797 | int rc; |
976 | 798 | ||
@@ -997,6 +819,140 @@ static int __init reipl_init(void) | |||
997 | return 0; | 819 | return 0; |
998 | } | 820 | } |
999 | 821 | ||
822 | static struct shutdown_action reipl_action = {SHUTDOWN_ACTION_REIPL_STR, | ||
823 | reipl_run, reipl_init}; | ||
824 | |||
825 | /* | ||
826 | * dump shutdown action: Dump Linux on shutdown. | ||
827 | */ | ||
828 | |||
829 | /* FCP dump device attributes */ | ||
830 | |||
831 | DEFINE_IPL_ATTR_RW(dump_fcp, wwpn, "0x%016llx\n", "%016llx\n", | ||
832 | dump_block_fcp->ipl_info.fcp.wwpn); | ||
833 | DEFINE_IPL_ATTR_RW(dump_fcp, lun, "0x%016llx\n", "%016llx\n", | ||
834 | dump_block_fcp->ipl_info.fcp.lun); | ||
835 | DEFINE_IPL_ATTR_RW(dump_fcp, bootprog, "%lld\n", "%lld\n", | ||
836 | dump_block_fcp->ipl_info.fcp.bootprog); | ||
837 | DEFINE_IPL_ATTR_RW(dump_fcp, br_lba, "%lld\n", "%lld\n", | ||
838 | dump_block_fcp->ipl_info.fcp.br_lba); | ||
839 | DEFINE_IPL_ATTR_RW(dump_fcp, device, "0.0.%04llx\n", "0.0.%llx\n", | ||
840 | dump_block_fcp->ipl_info.fcp.devno); | ||
841 | |||
842 | static struct attribute *dump_fcp_attrs[] = { | ||
843 | &sys_dump_fcp_device_attr.attr, | ||
844 | &sys_dump_fcp_wwpn_attr.attr, | ||
845 | &sys_dump_fcp_lun_attr.attr, | ||
846 | &sys_dump_fcp_bootprog_attr.attr, | ||
847 | &sys_dump_fcp_br_lba_attr.attr, | ||
848 | NULL, | ||
849 | }; | ||
850 | |||
851 | static struct attribute_group dump_fcp_attr_group = { | ||
852 | .name = IPL_FCP_STR, | ||
853 | .attrs = dump_fcp_attrs, | ||
854 | }; | ||
855 | |||
856 | /* CCW dump device attributes */ | ||
857 | |||
858 | DEFINE_IPL_ATTR_RW(dump_ccw, device, "0.0.%04llx\n", "0.0.%llx\n", | ||
859 | dump_block_ccw->ipl_info.ccw.devno); | ||
860 | |||
861 | static struct attribute *dump_ccw_attrs[] = { | ||
862 | &sys_dump_ccw_device_attr.attr, | ||
863 | NULL, | ||
864 | }; | ||
865 | |||
866 | static struct attribute_group dump_ccw_attr_group = { | ||
867 | .name = IPL_CCW_STR, | ||
868 | .attrs = dump_ccw_attrs, | ||
869 | }; | ||
870 | |||
871 | /* dump type */ | ||
872 | |||
873 | static int dump_set_type(enum dump_type type) | ||
874 | { | ||
875 | if (!(dump_capabilities & type)) | ||
876 | return -EINVAL; | ||
877 | switch (type) { | ||
878 | case DUMP_TYPE_CCW: | ||
879 | if (diag308_set_works) | ||
880 | dump_method = DUMP_METHOD_CCW_DIAG; | ||
881 | else if (MACHINE_IS_VM) | ||
882 | dump_method = DUMP_METHOD_CCW_VM; | ||
883 | else | ||
884 | dump_method = DUMP_METHOD_CCW_CIO; | ||
885 | break; | ||
886 | case DUMP_TYPE_FCP: | ||
887 | dump_method = DUMP_METHOD_FCP_DIAG; | ||
888 | break; | ||
889 | default: | ||
890 | dump_method = DUMP_METHOD_NONE; | ||
891 | } | ||
892 | dump_type = type; | ||
893 | return 0; | ||
894 | } | ||
895 | |||
896 | static ssize_t dump_type_show(struct kobject *kobj, | ||
897 | struct kobj_attribute *attr, char *page) | ||
898 | { | ||
899 | return sprintf(page, "%s\n", dump_type_str(dump_type)); | ||
900 | } | ||
901 | |||
902 | static ssize_t dump_type_store(struct kobject *kobj, | ||
903 | struct kobj_attribute *attr, | ||
904 | const char *buf, size_t len) | ||
905 | { | ||
906 | int rc = -EINVAL; | ||
907 | |||
908 | if (strncmp(buf, DUMP_NONE_STR, strlen(DUMP_NONE_STR)) == 0) | ||
909 | rc = dump_set_type(DUMP_TYPE_NONE); | ||
910 | else if (strncmp(buf, DUMP_CCW_STR, strlen(DUMP_CCW_STR)) == 0) | ||
911 | rc = dump_set_type(DUMP_TYPE_CCW); | ||
912 | else if (strncmp(buf, DUMP_FCP_STR, strlen(DUMP_FCP_STR)) == 0) | ||
913 | rc = dump_set_type(DUMP_TYPE_FCP); | ||
914 | return (rc != 0) ? rc : len; | ||
915 | } | ||
916 | |||
917 | static struct kobj_attribute dump_type_attr = | ||
918 | __ATTR(dump_type, 0644, dump_type_show, dump_type_store); | ||
919 | |||
920 | static struct kset *dump_kset; | ||
921 | |||
922 | static void dump_run(struct shutdown_trigger *trigger) | ||
923 | { | ||
924 | struct ccw_dev_id devid; | ||
925 | static char buf[100]; | ||
926 | |||
927 | switch (dump_method) { | ||
928 | case DUMP_METHOD_CCW_CIO: | ||
929 | smp_send_stop(); | ||
930 | devid.devno = dump_block_ccw->ipl_info.ccw.devno; | ||
931 | devid.ssid = 0; | ||
932 | reipl_ccw_dev(&devid); | ||
933 | break; | ||
934 | case DUMP_METHOD_CCW_VM: | ||
935 | smp_send_stop(); | ||
936 | sprintf(buf, "STORE STATUS"); | ||
937 | __cpcmd(buf, NULL, 0, NULL); | ||
938 | sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno); | ||
939 | __cpcmd(buf, NULL, 0, NULL); | ||
940 | break; | ||
941 | case DUMP_METHOD_CCW_DIAG: | ||
942 | diag308(DIAG308_SET, dump_block_ccw); | ||
943 | diag308(DIAG308_DUMP, NULL); | ||
944 | break; | ||
945 | case DUMP_METHOD_FCP_DIAG: | ||
946 | diag308(DIAG308_SET, dump_block_fcp); | ||
947 | diag308(DIAG308_DUMP, NULL); | ||
948 | break; | ||
949 | case DUMP_METHOD_NONE: | ||
950 | default: | ||
951 | return; | ||
952 | } | ||
953 | printk(KERN_EMERG "Dump failed!\n"); | ||
954 | } | ||
955 | |||
1000 | static int __init dump_ccw_init(void) | 956 | static int __init dump_ccw_init(void) |
1001 | { | 957 | { |
1002 | int rc; | 958 | int rc; |
@@ -1042,31 +998,14 @@ static int __init dump_fcp_init(void) | |||
1042 | return 0; | 998 | return 0; |
1043 | } | 999 | } |
1044 | 1000 | ||
1045 | #define SHUTDOWN_ON_PANIC_PRIO 0 | 1001 | static int dump_init(void) |
1046 | |||
1047 | static int shutdown_on_panic_notify(struct notifier_block *self, | ||
1048 | unsigned long event, void *data) | ||
1049 | { | ||
1050 | if (on_panic_action == SHUTDOWN_DUMP) | ||
1051 | do_dump(); | ||
1052 | else if (on_panic_action == SHUTDOWN_REIPL) | ||
1053 | do_reipl(); | ||
1054 | return NOTIFY_OK; | ||
1055 | } | ||
1056 | |||
1057 | static struct notifier_block shutdown_on_panic_nb = { | ||
1058 | .notifier_call = shutdown_on_panic_notify, | ||
1059 | .priority = SHUTDOWN_ON_PANIC_PRIO | ||
1060 | }; | ||
1061 | |||
1062 | static int __init dump_init(void) | ||
1063 | { | 1002 | { |
1064 | int rc; | 1003 | int rc; |
1065 | 1004 | ||
1066 | dump_kset = kset_create_and_add("dump", NULL, firmware_kobj); | 1005 | dump_kset = kset_create_and_add("dump", NULL, firmware_kobj); |
1067 | if (!dump_kset) | 1006 | if (!dump_kset) |
1068 | return -ENOMEM; | 1007 | return -ENOMEM; |
1069 | rc = sysfs_create_file(&dump_kset->kobj, &dump_type_attr); | 1008 | rc = sysfs_create_file(&dump_kset->kobj, &dump_type_attr.attr); |
1070 | if (rc) { | 1009 | if (rc) { |
1071 | kset_unregister(dump_kset); | 1010 | kset_unregister(dump_kset); |
1072 | return rc; | 1011 | return rc; |
@@ -1081,47 +1020,381 @@ static int __init dump_init(void) | |||
1081 | return 0; | 1020 | return 0; |
1082 | } | 1021 | } |
1083 | 1022 | ||
1084 | static int __init shutdown_actions_init(void) | 1023 | static struct shutdown_action dump_action = {SHUTDOWN_ACTION_DUMP_STR, |
1024 | dump_run, dump_init}; | ||
1025 | |||
1026 | /* | ||
1027 | * vmcmd shutdown action: Trigger vm command on shutdown. | ||
1028 | */ | ||
1029 | |||
1030 | static char vmcmd_on_reboot[128]; | ||
1031 | static char vmcmd_on_panic[128]; | ||
1032 | static char vmcmd_on_halt[128]; | ||
1033 | static char vmcmd_on_poff[128]; | ||
1034 | |||
1035 | DEFINE_IPL_ATTR_STR_RW(vmcmd, on_reboot, "%s\n", "%s\n", vmcmd_on_reboot); | ||
1036 | DEFINE_IPL_ATTR_STR_RW(vmcmd, on_panic, "%s\n", "%s\n", vmcmd_on_panic); | ||
1037 | DEFINE_IPL_ATTR_STR_RW(vmcmd, on_halt, "%s\n", "%s\n", vmcmd_on_halt); | ||
1038 | DEFINE_IPL_ATTR_STR_RW(vmcmd, on_poff, "%s\n", "%s\n", vmcmd_on_poff); | ||
1039 | |||
1040 | static struct attribute *vmcmd_attrs[] = { | ||
1041 | &sys_vmcmd_on_reboot_attr.attr, | ||
1042 | &sys_vmcmd_on_panic_attr.attr, | ||
1043 | &sys_vmcmd_on_halt_attr.attr, | ||
1044 | &sys_vmcmd_on_poff_attr.attr, | ||
1045 | NULL, | ||
1046 | }; | ||
1047 | |||
1048 | static struct attribute_group vmcmd_attr_group = { | ||
1049 | .attrs = vmcmd_attrs, | ||
1050 | }; | ||
1051 | |||
1052 | static struct kset *vmcmd_kset; | ||
1053 | |||
1054 | static void vmcmd_run(struct shutdown_trigger *trigger) | ||
1055 | { | ||
1056 | char *cmd, *next_cmd; | ||
1057 | |||
1058 | if (strcmp(trigger->name, ON_REIPL_STR) == 0) | ||
1059 | cmd = vmcmd_on_reboot; | ||
1060 | else if (strcmp(trigger->name, ON_PANIC_STR) == 0) | ||
1061 | cmd = vmcmd_on_panic; | ||
1062 | else if (strcmp(trigger->name, ON_HALT_STR) == 0) | ||
1063 | cmd = vmcmd_on_halt; | ||
1064 | else if (strcmp(trigger->name, ON_POFF_STR) == 0) | ||
1065 | cmd = vmcmd_on_poff; | ||
1066 | else | ||
1067 | return; | ||
1068 | |||
1069 | if (strlen(cmd) == 0) | ||
1070 | return; | ||
1071 | do { | ||
1072 | next_cmd = strchr(cmd, '\n'); | ||
1073 | if (next_cmd) { | ||
1074 | next_cmd[0] = 0; | ||
1075 | next_cmd += 1; | ||
1076 | } | ||
1077 | __cpcmd(cmd, NULL, 0, NULL); | ||
1078 | cmd = next_cmd; | ||
1079 | } while (cmd != NULL); | ||
1080 | } | ||
1081 | |||
1082 | static int vmcmd_init(void) | ||
1085 | { | 1083 | { |
1086 | int rc; | 1084 | if (!MACHINE_IS_VM) |
1085 | return -ENOTSUPP; | ||
1086 | vmcmd_kset = kset_create_and_add("vmcmd", NULL, firmware_kobj); | ||
1087 | if (!vmcmd_kset) | ||
1088 | return -ENOMEM; | ||
1089 | return sysfs_create_group(&vmcmd_kset->kobj, &vmcmd_attr_group); | ||
1090 | } | ||
1091 | |||
1092 | static struct shutdown_action vmcmd_action = {SHUTDOWN_ACTION_VMCMD_STR, | ||
1093 | vmcmd_run, vmcmd_init}; | ||
1094 | |||
1095 | /* | ||
1096 | * stop shutdown action: Stop Linux on shutdown. | ||
1097 | */ | ||
1098 | |||
1099 | static void stop_run(struct shutdown_trigger *trigger) | ||
1100 | { | ||
1101 | if (strcmp(trigger->name, ON_PANIC_STR) == 0) | ||
1102 | disabled_wait((unsigned long) __builtin_return_address(0)); | ||
1103 | else { | ||
1104 | signal_processor(smp_processor_id(), sigp_stop); | ||
1105 | for (;;); | ||
1106 | } | ||
1107 | } | ||
1108 | |||
1109 | static struct shutdown_action stop_action = {SHUTDOWN_ACTION_STOP_STR, | ||
1110 | stop_run, NULL}; | ||
1111 | |||
1112 | /* action list */ | ||
1113 | |||
1114 | static struct shutdown_action *shutdown_actions_list[] = { | ||
1115 | &ipl_action, &reipl_action, &dump_action, &vmcmd_action, &stop_action}; | ||
1116 | #define SHUTDOWN_ACTIONS_COUNT (sizeof(shutdown_actions_list) / sizeof(void *)) | ||
1117 | |||
1118 | /* | ||
1119 | * Trigger section | ||
1120 | */ | ||
1121 | |||
1122 | static struct kset *shutdown_actions_kset; | ||
1123 | |||
1124 | static int set_trigger(const char *buf, struct shutdown_trigger *trigger, | ||
1125 | size_t len) | ||
1126 | { | ||
1127 | int i; | ||
1128 | for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) { | ||
1129 | if (!shutdown_actions_list[i]) | ||
1130 | continue; | ||
1131 | if (strncmp(buf, shutdown_actions_list[i]->name, | ||
1132 | strlen(shutdown_actions_list[i]->name)) == 0) { | ||
1133 | trigger->action = shutdown_actions_list[i]; | ||
1134 | return len; | ||
1135 | } | ||
1136 | } | ||
1137 | return -EINVAL; | ||
1138 | } | ||
1139 | |||
1140 | /* on reipl */ | ||
1141 | |||
1142 | static struct shutdown_trigger on_reboot_trigger = {ON_REIPL_STR, | ||
1143 | &reipl_action}; | ||
1144 | |||
1145 | static ssize_t on_reboot_show(struct kobject *kobj, | ||
1146 | struct kobj_attribute *attr, char *page) | ||
1147 | { | ||
1148 | return sprintf(page, "%s\n", on_reboot_trigger.action->name); | ||
1149 | } | ||
1150 | |||
1151 | static ssize_t on_reboot_store(struct kobject *kobj, | ||
1152 | struct kobj_attribute *attr, | ||
1153 | const char *buf, size_t len) | ||
1154 | { | ||
1155 | return set_trigger(buf, &on_reboot_trigger, len); | ||
1156 | } | ||
1157 | |||
1158 | static struct kobj_attribute on_reboot_attr = | ||
1159 | __ATTR(on_reboot, 0644, on_reboot_show, on_reboot_store); | ||
1160 | |||
1161 | static void do_machine_restart(char *__unused) | ||
1162 | { | ||
1163 | smp_send_stop(); | ||
1164 | on_reboot_trigger.action->fn(&on_reboot_trigger); | ||
1165 | reipl_run(NULL); | ||
1166 | } | ||
1167 | void (*_machine_restart)(char *command) = do_machine_restart; | ||
1168 | |||
1169 | /* on panic */ | ||
1170 | |||
1171 | static struct shutdown_trigger on_panic_trigger = {ON_PANIC_STR, &stop_action}; | ||
1172 | |||
1173 | static ssize_t on_panic_show(struct kobject *kobj, | ||
1174 | struct kobj_attribute *attr, char *page) | ||
1175 | { | ||
1176 | return sprintf(page, "%s\n", on_panic_trigger.action->name); | ||
1177 | } | ||
1087 | 1178 | ||
1179 | static ssize_t on_panic_store(struct kobject *kobj, | ||
1180 | struct kobj_attribute *attr, | ||
1181 | const char *buf, size_t len) | ||
1182 | { | ||
1183 | return set_trigger(buf, &on_panic_trigger, len); | ||
1184 | } | ||
1185 | |||
1186 | static struct kobj_attribute on_panic_attr = | ||
1187 | __ATTR(on_panic, 0644, on_panic_show, on_panic_store); | ||
1188 | |||
1189 | static void do_panic(void) | ||
1190 | { | ||
1191 | on_panic_trigger.action->fn(&on_panic_trigger); | ||
1192 | stop_run(&on_panic_trigger); | ||
1193 | } | ||
1194 | |||
1195 | /* on halt */ | ||
1196 | |||
1197 | static struct shutdown_trigger on_halt_trigger = {ON_HALT_STR, &stop_action}; | ||
1198 | |||
1199 | static ssize_t on_halt_show(struct kobject *kobj, | ||
1200 | struct kobj_attribute *attr, char *page) | ||
1201 | { | ||
1202 | return sprintf(page, "%s\n", on_halt_trigger.action->name); | ||
1203 | } | ||
1204 | |||
1205 | static ssize_t on_halt_store(struct kobject *kobj, | ||
1206 | struct kobj_attribute *attr, | ||
1207 | const char *buf, size_t len) | ||
1208 | { | ||
1209 | return set_trigger(buf, &on_halt_trigger, len); | ||
1210 | } | ||
1211 | |||
1212 | static struct kobj_attribute on_halt_attr = | ||
1213 | __ATTR(on_halt, 0644, on_halt_show, on_halt_store); | ||
1214 | |||
1215 | |||
1216 | static void do_machine_halt(void) | ||
1217 | { | ||
1218 | smp_send_stop(); | ||
1219 | on_halt_trigger.action->fn(&on_halt_trigger); | ||
1220 | stop_run(&on_halt_trigger); | ||
1221 | } | ||
1222 | void (*_machine_halt)(void) = do_machine_halt; | ||
1223 | |||
1224 | /* on power off */ | ||
1225 | |||
1226 | static struct shutdown_trigger on_poff_trigger = {ON_POFF_STR, &stop_action}; | ||
1227 | |||
1228 | static ssize_t on_poff_show(struct kobject *kobj, | ||
1229 | struct kobj_attribute *attr, char *page) | ||
1230 | { | ||
1231 | return sprintf(page, "%s\n", on_poff_trigger.action->name); | ||
1232 | } | ||
1233 | |||
1234 | static ssize_t on_poff_store(struct kobject *kobj, | ||
1235 | struct kobj_attribute *attr, | ||
1236 | const char *buf, size_t len) | ||
1237 | { | ||
1238 | return set_trigger(buf, &on_poff_trigger, len); | ||
1239 | } | ||
1240 | |||
1241 | static struct kobj_attribute on_poff_attr = | ||
1242 | __ATTR(on_poff, 0644, on_poff_show, on_poff_store); | ||
1243 | |||
1244 | |||
1245 | static void do_machine_power_off(void) | ||
1246 | { | ||
1247 | smp_send_stop(); | ||
1248 | on_poff_trigger.action->fn(&on_poff_trigger); | ||
1249 | stop_run(&on_poff_trigger); | ||
1250 | } | ||
1251 | void (*_machine_power_off)(void) = do_machine_power_off; | ||
1252 | |||
1253 | static void __init shutdown_triggers_init(void) | ||
1254 | { | ||
1088 | shutdown_actions_kset = kset_create_and_add("shutdown_actions", NULL, | 1255 | shutdown_actions_kset = kset_create_and_add("shutdown_actions", NULL, |
1089 | firmware_kobj); | 1256 | firmware_kobj); |
1090 | if (!shutdown_actions_kset) | 1257 | if (!shutdown_actions_kset) |
1091 | return -ENOMEM; | 1258 | goto fail; |
1092 | rc = sysfs_create_file(&shutdown_actions_kset->kobj, &on_panic_attr); | 1259 | if (sysfs_create_file(&shutdown_actions_kset->kobj, |
1093 | if (rc) { | 1260 | &on_reboot_attr.attr)) |
1094 | kset_unregister(shutdown_actions_kset); | 1261 | goto fail; |
1095 | return rc; | 1262 | if (sysfs_create_file(&shutdown_actions_kset->kobj, |
1263 | &on_panic_attr.attr)) | ||
1264 | goto fail; | ||
1265 | if (sysfs_create_file(&shutdown_actions_kset->kobj, | ||
1266 | &on_halt_attr.attr)) | ||
1267 | goto fail; | ||
1268 | if (sysfs_create_file(&shutdown_actions_kset->kobj, | ||
1269 | &on_poff_attr.attr)) | ||
1270 | goto fail; | ||
1271 | |||
1272 | return; | ||
1273 | fail: | ||
1274 | panic("shutdown_triggers_init failed\n"); | ||
1275 | } | ||
1276 | |||
1277 | static void __init shutdown_actions_init(void) | ||
1278 | { | ||
1279 | int i; | ||
1280 | |||
1281 | for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) { | ||
1282 | if (!shutdown_actions_list[i]->init) | ||
1283 | continue; | ||
1284 | if (shutdown_actions_list[i]->init()) | ||
1285 | shutdown_actions_list[i] = NULL; | ||
1096 | } | 1286 | } |
1097 | atomic_notifier_chain_register(&panic_notifier_list, | ||
1098 | &shutdown_on_panic_nb); | ||
1099 | return 0; | ||
1100 | } | 1287 | } |
1101 | 1288 | ||
1102 | static int __init s390_ipl_init(void) | 1289 | static int __init s390_ipl_init(void) |
1103 | { | 1290 | { |
1104 | int rc; | ||
1105 | |||
1106 | sclp_get_ipl_info(&sclp_ipl_info); | ||
1107 | reipl_probe(); | 1291 | reipl_probe(); |
1108 | rc = ipl_init(); | 1292 | sclp_get_ipl_info(&sclp_ipl_info); |
1109 | if (rc) | 1293 | shutdown_actions_init(); |
1110 | return rc; | 1294 | shutdown_triggers_init(); |
1111 | rc = reipl_init(); | ||
1112 | if (rc) | ||
1113 | return rc; | ||
1114 | rc = dump_init(); | ||
1115 | if (rc) | ||
1116 | return rc; | ||
1117 | rc = shutdown_actions_init(); | ||
1118 | if (rc) | ||
1119 | return rc; | ||
1120 | return 0; | 1295 | return 0; |
1121 | } | 1296 | } |
1122 | 1297 | ||
1123 | __initcall(s390_ipl_init); | 1298 | __initcall(s390_ipl_init); |
1124 | 1299 | ||
1300 | static void __init strncpy_skip_quote(char *dst, char *src, int n) | ||
1301 | { | ||
1302 | int sx, dx; | ||
1303 | |||
1304 | dx = 0; | ||
1305 | for (sx = 0; src[sx] != 0; sx++) { | ||
1306 | if (src[sx] == '"') | ||
1307 | continue; | ||
1308 | dst[dx++] = src[sx]; | ||
1309 | if (dx >= n) | ||
1310 | break; | ||
1311 | } | ||
1312 | } | ||
1313 | |||
1314 | static int __init vmcmd_on_reboot_setup(char *str) | ||
1315 | { | ||
1316 | if (!MACHINE_IS_VM) | ||
1317 | return 1; | ||
1318 | strncpy_skip_quote(vmcmd_on_reboot, str, 127); | ||
1319 | vmcmd_on_reboot[127] = 0; | ||
1320 | on_reboot_trigger.action = &vmcmd_action; | ||
1321 | return 1; | ||
1322 | } | ||
1323 | __setup("vmreboot=", vmcmd_on_reboot_setup); | ||
1324 | |||
1325 | static int __init vmcmd_on_panic_setup(char *str) | ||
1326 | { | ||
1327 | if (!MACHINE_IS_VM) | ||
1328 | return 1; | ||
1329 | strncpy_skip_quote(vmcmd_on_panic, str, 127); | ||
1330 | vmcmd_on_panic[127] = 0; | ||
1331 | on_panic_trigger.action = &vmcmd_action; | ||
1332 | return 1; | ||
1333 | } | ||
1334 | __setup("vmpanic=", vmcmd_on_panic_setup); | ||
1335 | |||
1336 | static int __init vmcmd_on_halt_setup(char *str) | ||
1337 | { | ||
1338 | if (!MACHINE_IS_VM) | ||
1339 | return 1; | ||
1340 | strncpy_skip_quote(vmcmd_on_halt, str, 127); | ||
1341 | vmcmd_on_halt[127] = 0; | ||
1342 | on_halt_trigger.action = &vmcmd_action; | ||
1343 | return 1; | ||
1344 | } | ||
1345 | __setup("vmhalt=", vmcmd_on_halt_setup); | ||
1346 | |||
1347 | static int __init vmcmd_on_poff_setup(char *str) | ||
1348 | { | ||
1349 | if (!MACHINE_IS_VM) | ||
1350 | return 1; | ||
1351 | strncpy_skip_quote(vmcmd_on_poff, str, 127); | ||
1352 | vmcmd_on_poff[127] = 0; | ||
1353 | on_poff_trigger.action = &vmcmd_action; | ||
1354 | return 1; | ||
1355 | } | ||
1356 | __setup("vmpoff=", vmcmd_on_poff_setup); | ||
1357 | |||
1358 | static int on_panic_notify(struct notifier_block *self, | ||
1359 | unsigned long event, void *data) | ||
1360 | { | ||
1361 | do_panic(); | ||
1362 | return NOTIFY_OK; | ||
1363 | } | ||
1364 | |||
1365 | static struct notifier_block on_panic_nb = { | ||
1366 | .notifier_call = on_panic_notify, | ||
1367 | .priority = 0, | ||
1368 | }; | ||
1369 | |||
1370 | void __init setup_ipl(void) | ||
1371 | { | ||
1372 | ipl_info.type = get_ipl_type(); | ||
1373 | switch (ipl_info.type) { | ||
1374 | case IPL_TYPE_CCW: | ||
1375 | ipl_info.data.ccw.dev_id.devno = ipl_devno; | ||
1376 | ipl_info.data.ccw.dev_id.ssid = 0; | ||
1377 | break; | ||
1378 | case IPL_TYPE_FCP: | ||
1379 | case IPL_TYPE_FCP_DUMP: | ||
1380 | ipl_info.data.fcp.dev_id.devno = | ||
1381 | IPL_PARMBLOCK_START->ipl_info.fcp.devno; | ||
1382 | ipl_info.data.fcp.dev_id.ssid = 0; | ||
1383 | ipl_info.data.fcp.wwpn = IPL_PARMBLOCK_START->ipl_info.fcp.wwpn; | ||
1384 | ipl_info.data.fcp.lun = IPL_PARMBLOCK_START->ipl_info.fcp.lun; | ||
1385 | break; | ||
1386 | case IPL_TYPE_NSS: | ||
1387 | strncpy(ipl_info.data.nss.name, kernel_nss_name, | ||
1388 | sizeof(ipl_info.data.nss.name)); | ||
1389 | break; | ||
1390 | case IPL_TYPE_UNKNOWN: | ||
1391 | default: | ||
1392 | /* We have no info to copy */ | ||
1393 | break; | ||
1394 | } | ||
1395 | atomic_notifier_chain_register(&panic_notifier_list, &on_panic_nb); | ||
1396 | } | ||
1397 | |||
1125 | void __init ipl_save_parameters(void) | 1398 | void __init ipl_save_parameters(void) |
1126 | { | 1399 | { |
1127 | struct cio_iplinfo iplinfo; | 1400 | struct cio_iplinfo iplinfo; |
@@ -1202,3 +1475,4 @@ void s390_reset_system(void) | |||
1202 | 1475 | ||
1203 | do_reset_calls(); | 1476 | do_reset_calls(); |
1204 | } | 1477 | } |
1478 | |||
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 29f7884b4ffa..0e7aca039307 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c | |||
@@ -36,7 +36,7 @@ | |||
36 | #include <linux/init.h> | 36 | #include <linux/init.h> |
37 | #include <linux/module.h> | 37 | #include <linux/module.h> |
38 | #include <linux/notifier.h> | 38 | #include <linux/notifier.h> |
39 | 39 | #include <linux/utsname.h> | |
40 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
41 | #include <asm/pgtable.h> | 41 | #include <asm/pgtable.h> |
42 | #include <asm/system.h> | 42 | #include <asm/system.h> |
@@ -182,13 +182,15 @@ void cpu_idle(void) | |||
182 | 182 | ||
183 | void show_regs(struct pt_regs *regs) | 183 | void show_regs(struct pt_regs *regs) |
184 | { | 184 | { |
185 | struct task_struct *tsk = current; | 185 | print_modules(); |
186 | 186 | printk("CPU: %d %s %s %.*s\n", | |
187 | printk("CPU: %d %s\n", task_thread_info(tsk)->cpu, print_tainted()); | 187 | task_thread_info(current)->cpu, print_tainted(), |
188 | printk("Process %s (pid: %d, task: %p, ksp: %p)\n", | 188 | init_utsname()->release, |
189 | current->comm, task_pid_nr(current), (void *) tsk, | 189 | (int)strcspn(init_utsname()->version, " "), |
190 | (void *) tsk->thread.ksp); | 190 | init_utsname()->version); |
191 | 191 | printk("Process %s (pid: %d, task: %p, ksp: %p)\n", | |
192 | current->comm, current->pid, current, | ||
193 | (void *) current->thread.ksp); | ||
192 | show_registers(regs); | 194 | show_registers(regs); |
193 | /* Show stack backtrace if pt_regs is from kernel mode */ | 195 | /* Show stack backtrace if pt_regs is from kernel mode */ |
194 | if (!(regs->psw.mask & PSW_MASK_PSTATE)) | 196 | if (!(regs->psw.mask & PSW_MASK_PSTATE)) |
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 1d81bf9488ae..6e036bae9875 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c | |||
@@ -86,13 +86,13 @@ FixPerRegisters(struct task_struct *task) | |||
86 | per_info->control_regs.bits.storage_alt_space_ctl = 0; | 86 | per_info->control_regs.bits.storage_alt_space_ctl = 0; |
87 | } | 87 | } |
88 | 88 | ||
89 | static void set_single_step(struct task_struct *task) | 89 | void user_enable_single_step(struct task_struct *task) |
90 | { | 90 | { |
91 | task->thread.per_info.single_step = 1; | 91 | task->thread.per_info.single_step = 1; |
92 | FixPerRegisters(task); | 92 | FixPerRegisters(task); |
93 | } | 93 | } |
94 | 94 | ||
95 | static void clear_single_step(struct task_struct *task) | 95 | void user_disable_single_step(struct task_struct *task) |
96 | { | 96 | { |
97 | task->thread.per_info.single_step = 0; | 97 | task->thread.per_info.single_step = 0; |
98 | FixPerRegisters(task); | 98 | FixPerRegisters(task); |
@@ -107,7 +107,7 @@ void | |||
107 | ptrace_disable(struct task_struct *child) | 107 | ptrace_disable(struct task_struct *child) |
108 | { | 108 | { |
109 | /* make sure the single step bit is not set. */ | 109 | /* make sure the single step bit is not set. */ |
110 | clear_single_step(child); | 110 | user_disable_single_step(child); |
111 | } | 111 | } |
112 | 112 | ||
113 | #ifndef CONFIG_64BIT | 113 | #ifndef CONFIG_64BIT |
@@ -651,7 +651,7 @@ do_ptrace(struct task_struct *child, long request, long addr, long data) | |||
651 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 651 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
652 | child->exit_code = data; | 652 | child->exit_code = data; |
653 | /* make sure the single step bit is not set. */ | 653 | /* make sure the single step bit is not set. */ |
654 | clear_single_step(child); | 654 | user_disable_single_step(child); |
655 | wake_up_process(child); | 655 | wake_up_process(child); |
656 | return 0; | 656 | return 0; |
657 | 657 | ||
@@ -665,7 +665,7 @@ do_ptrace(struct task_struct *child, long request, long addr, long data) | |||
665 | return 0; | 665 | return 0; |
666 | child->exit_code = SIGKILL; | 666 | child->exit_code = SIGKILL; |
667 | /* make sure the single step bit is not set. */ | 667 | /* make sure the single step bit is not set. */ |
668 | clear_single_step(child); | 668 | user_disable_single_step(child); |
669 | wake_up_process(child); | 669 | wake_up_process(child); |
670 | return 0; | 670 | return 0; |
671 | 671 | ||
@@ -675,10 +675,7 @@ do_ptrace(struct task_struct *child, long request, long addr, long data) | |||
675 | return -EIO; | 675 | return -EIO; |
676 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 676 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
677 | child->exit_code = data; | 677 | child->exit_code = data; |
678 | if (data) | 678 | user_enable_single_step(child); |
679 | set_tsk_thread_flag(child, TIF_SINGLE_STEP); | ||
680 | else | ||
681 | set_single_step(child); | ||
682 | /* give it a chance to run. */ | 679 | /* give it a chance to run. */ |
683 | wake_up_process(child); | 680 | wake_up_process(child); |
684 | return 0; | 681 | return 0; |
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 577aa7dd660e..766c783bd7a7 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -126,75 +126,6 @@ void __cpuinit cpu_init(void) | |||
126 | } | 126 | } |
127 | 127 | ||
128 | /* | 128 | /* |
129 | * VM halt and poweroff setup routines | ||
130 | */ | ||
131 | char vmhalt_cmd[128] = ""; | ||
132 | char vmpoff_cmd[128] = ""; | ||
133 | static char vmpanic_cmd[128] = ""; | ||
134 | |||
135 | static void strncpy_skip_quote(char *dst, char *src, int n) | ||
136 | { | ||
137 | int sx, dx; | ||
138 | |||
139 | dx = 0; | ||
140 | for (sx = 0; src[sx] != 0; sx++) { | ||
141 | if (src[sx] == '"') continue; | ||
142 | dst[dx++] = src[sx]; | ||
143 | if (dx >= n) break; | ||
144 | } | ||
145 | } | ||
146 | |||
147 | static int __init vmhalt_setup(char *str) | ||
148 | { | ||
149 | strncpy_skip_quote(vmhalt_cmd, str, 127); | ||
150 | vmhalt_cmd[127] = 0; | ||
151 | return 1; | ||
152 | } | ||
153 | |||
154 | __setup("vmhalt=", vmhalt_setup); | ||
155 | |||
156 | static int __init vmpoff_setup(char *str) | ||
157 | { | ||
158 | strncpy_skip_quote(vmpoff_cmd, str, 127); | ||
159 | vmpoff_cmd[127] = 0; | ||
160 | return 1; | ||
161 | } | ||
162 | |||
163 | __setup("vmpoff=", vmpoff_setup); | ||
164 | |||
165 | static int vmpanic_notify(struct notifier_block *self, unsigned long event, | ||
166 | void *data) | ||
167 | { | ||
168 | if (MACHINE_IS_VM && strlen(vmpanic_cmd) > 0) | ||
169 | cpcmd(vmpanic_cmd, NULL, 0, NULL); | ||
170 | |||
171 | return NOTIFY_OK; | ||
172 | } | ||
173 | |||
174 | #define PANIC_PRI_VMPANIC 0 | ||
175 | |||
176 | static struct notifier_block vmpanic_nb = { | ||
177 | .notifier_call = vmpanic_notify, | ||
178 | .priority = PANIC_PRI_VMPANIC | ||
179 | }; | ||
180 | |||
181 | static int __init vmpanic_setup(char *str) | ||
182 | { | ||
183 | static int register_done __initdata = 0; | ||
184 | |||
185 | strncpy_skip_quote(vmpanic_cmd, str, 127); | ||
186 | vmpanic_cmd[127] = 0; | ||
187 | if (!register_done) { | ||
188 | register_done = 1; | ||
189 | atomic_notifier_chain_register(&panic_notifier_list, | ||
190 | &vmpanic_nb); | ||
191 | } | ||
192 | return 1; | ||
193 | } | ||
194 | |||
195 | __setup("vmpanic=", vmpanic_setup); | ||
196 | |||
197 | /* | ||
198 | * condev= and conmode= setup parameter. | 129 | * condev= and conmode= setup parameter. |
199 | */ | 130 | */ |
200 | 131 | ||
@@ -308,38 +239,6 @@ static void __init setup_zfcpdump(unsigned int console_devno) | |||
308 | static inline void setup_zfcpdump(unsigned int console_devno) {} | 239 | static inline void setup_zfcpdump(unsigned int console_devno) {} |
309 | #endif /* CONFIG_ZFCPDUMP */ | 240 | #endif /* CONFIG_ZFCPDUMP */ |
310 | 241 | ||
311 | #ifdef CONFIG_SMP | ||
312 | void (*_machine_restart)(char *command) = machine_restart_smp; | ||
313 | void (*_machine_halt)(void) = machine_halt_smp; | ||
314 | void (*_machine_power_off)(void) = machine_power_off_smp; | ||
315 | #else | ||
316 | /* | ||
317 | * Reboot, halt and power_off routines for non SMP. | ||
318 | */ | ||
319 | static void do_machine_restart_nonsmp(char * __unused) | ||
320 | { | ||
321 | do_reipl(); | ||
322 | } | ||
323 | |||
324 | static void do_machine_halt_nonsmp(void) | ||
325 | { | ||
326 | if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0) | ||
327 | __cpcmd(vmhalt_cmd, NULL, 0, NULL); | ||
328 | signal_processor(smp_processor_id(), sigp_stop_and_store_status); | ||
329 | } | ||
330 | |||
331 | static void do_machine_power_off_nonsmp(void) | ||
332 | { | ||
333 | if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0) | ||
334 | __cpcmd(vmpoff_cmd, NULL, 0, NULL); | ||
335 | signal_processor(smp_processor_id(), sigp_stop_and_store_status); | ||
336 | } | ||
337 | |||
338 | void (*_machine_restart)(char *command) = do_machine_restart_nonsmp; | ||
339 | void (*_machine_halt)(void) = do_machine_halt_nonsmp; | ||
340 | void (*_machine_power_off)(void) = do_machine_power_off_nonsmp; | ||
341 | #endif | ||
342 | |||
343 | /* | 242 | /* |
344 | * Reboot, halt and power_off stubs. They just call _machine_restart, | 243 | * Reboot, halt and power_off stubs. They just call _machine_restart, |
345 | * _machine_halt or _machine_power_off. | 244 | * _machine_halt or _machine_power_off. |
@@ -559,7 +458,9 @@ setup_resources(void) | |||
559 | data_resource.start = (unsigned long) &_etext; | 458 | data_resource.start = (unsigned long) &_etext; |
560 | data_resource.end = (unsigned long) &_edata - 1; | 459 | data_resource.end = (unsigned long) &_edata - 1; |
561 | 460 | ||
562 | for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) { | 461 | for (i = 0; i < MEMORY_CHUNKS; i++) { |
462 | if (!memory_chunk[i].size) | ||
463 | continue; | ||
563 | res = alloc_bootmem_low(sizeof(struct resource)); | 464 | res = alloc_bootmem_low(sizeof(struct resource)); |
564 | res->flags = IORESOURCE_BUSY | IORESOURCE_MEM; | 465 | res->flags = IORESOURCE_BUSY | IORESOURCE_MEM; |
565 | switch (memory_chunk[i].type) { | 466 | switch (memory_chunk[i].type) { |
@@ -617,7 +518,7 @@ EXPORT_SYMBOL_GPL(real_memory_size); | |||
617 | static void __init setup_memory_end(void) | 518 | static void __init setup_memory_end(void) |
618 | { | 519 | { |
619 | unsigned long memory_size; | 520 | unsigned long memory_size; |
620 | unsigned long max_mem, max_phys; | 521 | unsigned long max_mem; |
621 | int i; | 522 | int i; |
622 | 523 | ||
623 | #if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE) | 524 | #if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE) |
@@ -625,10 +526,31 @@ static void __init setup_memory_end(void) | |||
625 | memory_end = ZFCPDUMP_HSA_SIZE; | 526 | memory_end = ZFCPDUMP_HSA_SIZE; |
626 | #endif | 527 | #endif |
627 | memory_size = 0; | 528 | memory_size = 0; |
628 | max_phys = VMALLOC_END_INIT - VMALLOC_MIN_SIZE; | ||
629 | memory_end &= PAGE_MASK; | 529 | memory_end &= PAGE_MASK; |
630 | 530 | ||
631 | max_mem = memory_end ? min(max_phys, memory_end) : max_phys; | 531 | max_mem = memory_end ? min(VMALLOC_START, memory_end) : VMALLOC_START; |
532 | memory_end = min(max_mem, memory_end); | ||
533 | |||
534 | /* | ||
535 | * Make sure all chunks are MAX_ORDER aligned so we don't need the | ||
536 | * extra checks that HOLES_IN_ZONE would require. | ||
537 | */ | ||
538 | for (i = 0; i < MEMORY_CHUNKS; i++) { | ||
539 | unsigned long start, end; | ||
540 | struct mem_chunk *chunk; | ||
541 | unsigned long align; | ||
542 | |||
543 | chunk = &memory_chunk[i]; | ||
544 | align = 1UL << (MAX_ORDER + PAGE_SHIFT - 1); | ||
545 | start = (chunk->addr + align - 1) & ~(align - 1); | ||
546 | end = (chunk->addr + chunk->size) & ~(align - 1); | ||
547 | if (start >= end) | ||
548 | memset(chunk, 0, sizeof(*chunk)); | ||
549 | else { | ||
550 | chunk->addr = start; | ||
551 | chunk->size = end - start; | ||
552 | } | ||
553 | } | ||
632 | 554 | ||
633 | for (i = 0; i < MEMORY_CHUNKS; i++) { | 555 | for (i = 0; i < MEMORY_CHUNKS; i++) { |
634 | struct mem_chunk *chunk = &memory_chunk[i]; | 556 | struct mem_chunk *chunk = &memory_chunk[i]; |
@@ -890,7 +812,7 @@ setup_arch(char **cmdline_p) | |||
890 | 812 | ||
891 | parse_early_param(); | 813 | parse_early_param(); |
892 | 814 | ||
893 | setup_ipl_info(); | 815 | setup_ipl(); |
894 | setup_memory_end(); | 816 | setup_memory_end(); |
895 | setup_addressing_mode(); | 817 | setup_addressing_mode(); |
896 | setup_memory(); | 818 | setup_memory(); |
@@ -899,7 +821,6 @@ setup_arch(char **cmdline_p) | |||
899 | 821 | ||
900 | cpu_init(); | 822 | cpu_init(); |
901 | __cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr; | 823 | __cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr; |
902 | smp_setup_cpu_possible_map(); | ||
903 | 824 | ||
904 | /* | 825 | /* |
905 | * Setup capabilities (ELF_HWCAP & ELF_PLATFORM). | 826 | * Setup capabilities (ELF_HWCAP & ELF_PLATFORM). |
@@ -920,7 +841,7 @@ setup_arch(char **cmdline_p) | |||
920 | 841 | ||
921 | void __cpuinit print_cpu_info(struct cpuinfo_S390 *cpuinfo) | 842 | void __cpuinit print_cpu_info(struct cpuinfo_S390 *cpuinfo) |
922 | { | 843 | { |
923 | printk("cpu %d " | 844 | printk(KERN_INFO "cpu %d " |
924 | #ifdef CONFIG_SMP | 845 | #ifdef CONFIG_SMP |
925 | "phys_idx=%d " | 846 | "phys_idx=%d " |
926 | #endif | 847 | #endif |
@@ -996,7 +917,7 @@ static void *c_next(struct seq_file *m, void *v, loff_t *pos) | |||
996 | static void c_stop(struct seq_file *m, void *v) | 917 | static void c_stop(struct seq_file *m, void *v) |
997 | { | 918 | { |
998 | } | 919 | } |
999 | struct seq_operations cpuinfo_op = { | 920 | const struct seq_operations cpuinfo_op = { |
1000 | .start = c_start, | 921 | .start = c_start, |
1001 | .next = c_next, | 922 | .next = c_next, |
1002 | .stop = c_stop, | 923 | .stop = c_stop, |
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index d264671c1b71..4449bf32cbf1 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c | |||
@@ -471,6 +471,7 @@ void do_signal(struct pt_regs *regs) | |||
471 | 471 | ||
472 | if (signr > 0) { | 472 | if (signr > 0) { |
473 | /* Whee! Actually deliver the signal. */ | 473 | /* Whee! Actually deliver the signal. */ |
474 | int ret; | ||
474 | #ifdef CONFIG_COMPAT | 475 | #ifdef CONFIG_COMPAT |
475 | if (test_thread_flag(TIF_31BIT)) { | 476 | if (test_thread_flag(TIF_31BIT)) { |
476 | extern int handle_signal32(unsigned long sig, | 477 | extern int handle_signal32(unsigned long sig, |
@@ -478,15 +479,12 @@ void do_signal(struct pt_regs *regs) | |||
478 | siginfo_t *info, | 479 | siginfo_t *info, |
479 | sigset_t *oldset, | 480 | sigset_t *oldset, |
480 | struct pt_regs *regs); | 481 | struct pt_regs *regs); |
481 | if (handle_signal32( | 482 | ret = handle_signal32(signr, &ka, &info, oldset, regs); |
482 | signr, &ka, &info, oldset, regs) == 0) { | ||
483 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
484 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
485 | } | ||
486 | return; | ||
487 | } | 483 | } |
484 | else | ||
488 | #endif | 485 | #endif |
489 | if (handle_signal(signr, &ka, &info, oldset, regs) == 0) { | 486 | ret = handle_signal(signr, &ka, &info, oldset, regs); |
487 | if (!ret) { | ||
490 | /* | 488 | /* |
491 | * A signal was successfully delivered; the saved | 489 | * A signal was successfully delivered; the saved |
492 | * sigmask will have been stored in the signal frame, | 490 | * sigmask will have been stored in the signal frame, |
@@ -495,6 +493,14 @@ void do_signal(struct pt_regs *regs) | |||
495 | */ | 493 | */ |
496 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | 494 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) |
497 | clear_thread_flag(TIF_RESTORE_SIGMASK); | 495 | clear_thread_flag(TIF_RESTORE_SIGMASK); |
496 | |||
497 | /* | ||
498 | * If we would have taken a single-step trap | ||
499 | * for a normal instruction, act like we took | ||
500 | * one for the handler setup. | ||
501 | */ | ||
502 | if (current->thread.per_info.single_step) | ||
503 | set_thread_flag(TIF_SINGLE_STEP); | ||
498 | } | 504 | } |
499 | return; | 505 | return; |
500 | } | 506 | } |
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 264ea906db4c..aa37fa154512 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <asm/tlbflush.h> | 42 | #include <asm/tlbflush.h> |
43 | #include <asm/timer.h> | 43 | #include <asm/timer.h> |
44 | #include <asm/lowcore.h> | 44 | #include <asm/lowcore.h> |
45 | #include <asm/sclp.h> | ||
45 | #include <asm/cpu.h> | 46 | #include <asm/cpu.h> |
46 | 47 | ||
47 | /* | 48 | /* |
@@ -53,11 +54,27 @@ EXPORT_SYMBOL(lowcore_ptr); | |||
53 | cpumask_t cpu_online_map = CPU_MASK_NONE; | 54 | cpumask_t cpu_online_map = CPU_MASK_NONE; |
54 | EXPORT_SYMBOL(cpu_online_map); | 55 | EXPORT_SYMBOL(cpu_online_map); |
55 | 56 | ||
56 | cpumask_t cpu_possible_map = CPU_MASK_NONE; | 57 | cpumask_t cpu_possible_map = CPU_MASK_ALL; |
57 | EXPORT_SYMBOL(cpu_possible_map); | 58 | EXPORT_SYMBOL(cpu_possible_map); |
58 | 59 | ||
59 | static struct task_struct *current_set[NR_CPUS]; | 60 | static struct task_struct *current_set[NR_CPUS]; |
60 | 61 | ||
62 | static u8 smp_cpu_type; | ||
63 | static int smp_use_sigp_detection; | ||
64 | |||
65 | enum s390_cpu_state { | ||
66 | CPU_STATE_STANDBY, | ||
67 | CPU_STATE_CONFIGURED, | ||
68 | }; | ||
69 | |||
70 | #ifdef CONFIG_HOTPLUG_CPU | ||
71 | static DEFINE_MUTEX(smp_cpu_state_mutex); | ||
72 | #endif | ||
73 | static int smp_cpu_state[NR_CPUS]; | ||
74 | |||
75 | static DEFINE_PER_CPU(struct cpu, cpu_devices); | ||
76 | DEFINE_PER_CPU(struct s390_idle_data, s390_idle); | ||
77 | |||
61 | static void smp_ext_bitcall(int, ec_bit_sig); | 78 | static void smp_ext_bitcall(int, ec_bit_sig); |
62 | 79 | ||
63 | /* | 80 | /* |
@@ -193,6 +210,33 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info, | |||
193 | } | 210 | } |
194 | EXPORT_SYMBOL(smp_call_function_single); | 211 | EXPORT_SYMBOL(smp_call_function_single); |
195 | 212 | ||
213 | /** | ||
214 | * smp_call_function_mask(): Run a function on a set of other CPUs. | ||
215 | * @mask: The set of cpus to run on. Must not include the current cpu. | ||
216 | * @func: The function to run. This must be fast and non-blocking. | ||
217 | * @info: An arbitrary pointer to pass to the function. | ||
218 | * @wait: If true, wait (atomically) until function has completed on other CPUs. | ||
219 | * | ||
220 | * Returns 0 on success, else a negative status code. | ||
221 | * | ||
222 | * If @wait is true, then returns once @func has returned; otherwise | ||
223 | * it returns just before the target cpu calls @func. | ||
224 | * | ||
225 | * You must not call this function with disabled interrupts or from a | ||
226 | * hardware interrupt handler or from a bottom half handler. | ||
227 | */ | ||
228 | int | ||
229 | smp_call_function_mask(cpumask_t mask, | ||
230 | void (*func)(void *), void *info, | ||
231 | int wait) | ||
232 | { | ||
233 | preempt_disable(); | ||
234 | __smp_call_function_map(func, info, 0, wait, mask); | ||
235 | preempt_enable(); | ||
236 | return 0; | ||
237 | } | ||
238 | EXPORT_SYMBOL(smp_call_function_mask); | ||
239 | |||
196 | void smp_send_stop(void) | 240 | void smp_send_stop(void) |
197 | { | 241 | { |
198 | int cpu, rc; | 242 | int cpu, rc; |
@@ -217,33 +261,6 @@ void smp_send_stop(void) | |||
217 | } | 261 | } |
218 | 262 | ||
219 | /* | 263 | /* |
220 | * Reboot, halt and power_off routines for SMP. | ||
221 | */ | ||
222 | void machine_restart_smp(char *__unused) | ||
223 | { | ||
224 | smp_send_stop(); | ||
225 | do_reipl(); | ||
226 | } | ||
227 | |||
228 | void machine_halt_smp(void) | ||
229 | { | ||
230 | smp_send_stop(); | ||
231 | if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0) | ||
232 | __cpcmd(vmhalt_cmd, NULL, 0, NULL); | ||
233 | signal_processor(smp_processor_id(), sigp_stop_and_store_status); | ||
234 | for (;;); | ||
235 | } | ||
236 | |||
237 | void machine_power_off_smp(void) | ||
238 | { | ||
239 | smp_send_stop(); | ||
240 | if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0) | ||
241 | __cpcmd(vmpoff_cmd, NULL, 0, NULL); | ||
242 | signal_processor(smp_processor_id(), sigp_stop_and_store_status); | ||
243 | for (;;); | ||
244 | } | ||
245 | |||
246 | /* | ||
247 | * This is the main routine where commands issued by other | 264 | * This is the main routine where commands issued by other |
248 | * cpus are handled. | 265 | * cpus are handled. |
249 | */ | 266 | */ |
@@ -355,6 +372,13 @@ void smp_ctl_clear_bit(int cr, int bit) | |||
355 | } | 372 | } |
356 | EXPORT_SYMBOL(smp_ctl_clear_bit); | 373 | EXPORT_SYMBOL(smp_ctl_clear_bit); |
357 | 374 | ||
375 | /* | ||
376 | * In early ipl state a temp. logically cpu number is needed, so the sigp | ||
377 | * functions can be used to sense other cpus. Since NR_CPUS is >= 2 on | ||
378 | * CONFIG_SMP and the ipl cpu is logical cpu 0, it must be 1. | ||
379 | */ | ||
380 | #define CPU_INIT_NO 1 | ||
381 | |||
358 | #if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE) | 382 | #if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE) |
359 | 383 | ||
360 | /* | 384 | /* |
@@ -375,9 +399,10 @@ static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) | |||
375 | "kernel was compiled with NR_CPUS=%i\n", cpu, NR_CPUS); | 399 | "kernel was compiled with NR_CPUS=%i\n", cpu, NR_CPUS); |
376 | return; | 400 | return; |
377 | } | 401 | } |
378 | zfcpdump_save_areas[cpu] = alloc_bootmem(sizeof(union save_area)); | 402 | zfcpdump_save_areas[cpu] = kmalloc(sizeof(union save_area), GFP_KERNEL); |
379 | __cpu_logical_map[1] = (__u16) phy_cpu; | 403 | __cpu_logical_map[CPU_INIT_NO] = (__u16) phy_cpu; |
380 | while (signal_processor(1, sigp_stop_and_store_status) == sigp_busy) | 404 | while (signal_processor(CPU_INIT_NO, sigp_stop_and_store_status) == |
405 | sigp_busy) | ||
381 | cpu_relax(); | 406 | cpu_relax(); |
382 | memcpy(zfcpdump_save_areas[cpu], | 407 | memcpy(zfcpdump_save_areas[cpu], |
383 | (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE, | 408 | (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE, |
@@ -397,32 +422,155 @@ static inline void smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) { } | |||
397 | 422 | ||
398 | #endif /* CONFIG_ZFCPDUMP || CONFIG_ZFCPDUMP_MODULE */ | 423 | #endif /* CONFIG_ZFCPDUMP || CONFIG_ZFCPDUMP_MODULE */ |
399 | 424 | ||
400 | /* | 425 | static int cpu_stopped(int cpu) |
401 | * Lets check how many CPUs we have. | ||
402 | */ | ||
403 | static unsigned int __init smp_count_cpus(void) | ||
404 | { | 426 | { |
405 | unsigned int cpu, num_cpus; | 427 | __u32 status; |
406 | __u16 boot_cpu_addr; | ||
407 | 428 | ||
408 | /* | 429 | /* Check for stopped state */ |
409 | * cpu 0 is the boot cpu. See smp_prepare_boot_cpu. | 430 | if (signal_processor_ps(&status, 0, cpu, sigp_sense) == |
410 | */ | 431 | sigp_status_stored) { |
432 | if (status & 0x40) | ||
433 | return 1; | ||
434 | } | ||
435 | return 0; | ||
436 | } | ||
437 | |||
438 | static int cpu_known(int cpu_id) | ||
439 | { | ||
440 | int cpu; | ||
441 | |||
442 | for_each_present_cpu(cpu) { | ||
443 | if (__cpu_logical_map[cpu] == cpu_id) | ||
444 | return 1; | ||
445 | } | ||
446 | return 0; | ||
447 | } | ||
448 | |||
449 | static int smp_rescan_cpus_sigp(cpumask_t avail) | ||
450 | { | ||
451 | int cpu_id, logical_cpu; | ||
452 | |||
453 | logical_cpu = first_cpu(avail); | ||
454 | if (logical_cpu == NR_CPUS) | ||
455 | return 0; | ||
456 | for (cpu_id = 0; cpu_id <= 65535; cpu_id++) { | ||
457 | if (cpu_known(cpu_id)) | ||
458 | continue; | ||
459 | __cpu_logical_map[logical_cpu] = cpu_id; | ||
460 | if (!cpu_stopped(logical_cpu)) | ||
461 | continue; | ||
462 | cpu_set(logical_cpu, cpu_present_map); | ||
463 | smp_cpu_state[logical_cpu] = CPU_STATE_CONFIGURED; | ||
464 | logical_cpu = next_cpu(logical_cpu, avail); | ||
465 | if (logical_cpu == NR_CPUS) | ||
466 | break; | ||
467 | } | ||
468 | return 0; | ||
469 | } | ||
470 | |||
471 | static int smp_rescan_cpus_sclp(cpumask_t avail) | ||
472 | { | ||
473 | struct sclp_cpu_info *info; | ||
474 | int cpu_id, logical_cpu, cpu; | ||
475 | int rc; | ||
476 | |||
477 | logical_cpu = first_cpu(avail); | ||
478 | if (logical_cpu == NR_CPUS) | ||
479 | return 0; | ||
480 | info = kmalloc(sizeof(*info), GFP_KERNEL); | ||
481 | if (!info) | ||
482 | return -ENOMEM; | ||
483 | rc = sclp_get_cpu_info(info); | ||
484 | if (rc) | ||
485 | goto out; | ||
486 | for (cpu = 0; cpu < info->combined; cpu++) { | ||
487 | if (info->has_cpu_type && info->cpu[cpu].type != smp_cpu_type) | ||
488 | continue; | ||
489 | cpu_id = info->cpu[cpu].address; | ||
490 | if (cpu_known(cpu_id)) | ||
491 | continue; | ||
492 | __cpu_logical_map[logical_cpu] = cpu_id; | ||
493 | cpu_set(logical_cpu, cpu_present_map); | ||
494 | if (cpu >= info->configured) | ||
495 | smp_cpu_state[logical_cpu] = CPU_STATE_STANDBY; | ||
496 | else | ||
497 | smp_cpu_state[logical_cpu] = CPU_STATE_CONFIGURED; | ||
498 | logical_cpu = next_cpu(logical_cpu, avail); | ||
499 | if (logical_cpu == NR_CPUS) | ||
500 | break; | ||
501 | } | ||
502 | out: | ||
503 | kfree(info); | ||
504 | return rc; | ||
505 | } | ||
506 | |||
507 | static int smp_rescan_cpus(void) | ||
508 | { | ||
509 | cpumask_t avail; | ||
510 | |||
511 | cpus_xor(avail, cpu_possible_map, cpu_present_map); | ||
512 | if (smp_use_sigp_detection) | ||
513 | return smp_rescan_cpus_sigp(avail); | ||
514 | else | ||
515 | return smp_rescan_cpus_sclp(avail); | ||
516 | } | ||
517 | |||
518 | static void __init smp_detect_cpus(void) | ||
519 | { | ||
520 | unsigned int cpu, c_cpus, s_cpus; | ||
521 | struct sclp_cpu_info *info; | ||
522 | u16 boot_cpu_addr, cpu_addr; | ||
523 | |||
524 | c_cpus = 1; | ||
525 | s_cpus = 0; | ||
411 | boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr; | 526 | boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr; |
412 | current_thread_info()->cpu = 0; | 527 | info = kmalloc(sizeof(*info), GFP_KERNEL); |
413 | num_cpus = 1; | 528 | if (!info) |
414 | for (cpu = 0; cpu <= 65535; cpu++) { | 529 | panic("smp_detect_cpus failed to allocate memory\n"); |
415 | if ((__u16) cpu == boot_cpu_addr) | 530 | /* Use sigp detection algorithm if sclp doesn't work. */ |
531 | if (sclp_get_cpu_info(info)) { | ||
532 | smp_use_sigp_detection = 1; | ||
533 | for (cpu = 0; cpu <= 65535; cpu++) { | ||
534 | if (cpu == boot_cpu_addr) | ||
535 | continue; | ||
536 | __cpu_logical_map[CPU_INIT_NO] = cpu; | ||
537 | if (!cpu_stopped(CPU_INIT_NO)) | ||
538 | continue; | ||
539 | smp_get_save_area(c_cpus, cpu); | ||
540 | c_cpus++; | ||
541 | } | ||
542 | goto out; | ||
543 | } | ||
544 | |||
545 | if (info->has_cpu_type) { | ||
546 | for (cpu = 0; cpu < info->combined; cpu++) { | ||
547 | if (info->cpu[cpu].address == boot_cpu_addr) { | ||
548 | smp_cpu_type = info->cpu[cpu].type; | ||
549 | break; | ||
550 | } | ||
551 | } | ||
552 | } | ||
553 | |||
554 | for (cpu = 0; cpu < info->combined; cpu++) { | ||
555 | if (info->has_cpu_type && info->cpu[cpu].type != smp_cpu_type) | ||
556 | continue; | ||
557 | cpu_addr = info->cpu[cpu].address; | ||
558 | if (cpu_addr == boot_cpu_addr) | ||
416 | continue; | 559 | continue; |
417 | __cpu_logical_map[1] = (__u16) cpu; | 560 | __cpu_logical_map[CPU_INIT_NO] = cpu_addr; |
418 | if (signal_processor(1, sigp_sense) == sigp_not_operational) | 561 | if (!cpu_stopped(CPU_INIT_NO)) { |
562 | s_cpus++; | ||
419 | continue; | 563 | continue; |
420 | smp_get_save_area(num_cpus, cpu); | 564 | } |
421 | num_cpus++; | 565 | smp_get_save_area(c_cpus, cpu_addr); |
566 | c_cpus++; | ||
422 | } | 567 | } |
423 | printk("Detected %d CPU's\n", (int) num_cpus); | 568 | out: |
424 | printk("Boot cpu address %2X\n", boot_cpu_addr); | 569 | kfree(info); |
425 | return num_cpus; | 570 | printk(KERN_INFO "CPUs: %d configured, %d standby\n", c_cpus, s_cpus); |
571 | get_online_cpus(); | ||
572 | smp_rescan_cpus(); | ||
573 | put_online_cpus(); | ||
426 | } | 574 | } |
427 | 575 | ||
428 | /* | 576 | /* |
@@ -453,8 +601,6 @@ int __cpuinit start_secondary(void *cpuvoid) | |||
453 | return 0; | 601 | return 0; |
454 | } | 602 | } |
455 | 603 | ||
456 | DEFINE_PER_CPU(struct s390_idle_data, s390_idle); | ||
457 | |||
458 | static void __init smp_create_idle(unsigned int cpu) | 604 | static void __init smp_create_idle(unsigned int cpu) |
459 | { | 605 | { |
460 | struct task_struct *p; | 606 | struct task_struct *p; |
@@ -470,37 +616,82 @@ static void __init smp_create_idle(unsigned int cpu) | |||
470 | spin_lock_init(&(&per_cpu(s390_idle, cpu))->lock); | 616 | spin_lock_init(&(&per_cpu(s390_idle, cpu))->lock); |
471 | } | 617 | } |
472 | 618 | ||
473 | static int cpu_stopped(int cpu) | 619 | static int __cpuinit smp_alloc_lowcore(int cpu) |
474 | { | 620 | { |
475 | __u32 status; | 621 | unsigned long async_stack, panic_stack; |
622 | struct _lowcore *lowcore; | ||
623 | int lc_order; | ||
624 | |||
625 | lc_order = sizeof(long) == 8 ? 1 : 0; | ||
626 | lowcore = (void *) __get_free_pages(GFP_KERNEL | GFP_DMA, lc_order); | ||
627 | if (!lowcore) | ||
628 | return -ENOMEM; | ||
629 | async_stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER); | ||
630 | if (!async_stack) | ||
631 | goto out_async_stack; | ||
632 | panic_stack = __get_free_page(GFP_KERNEL); | ||
633 | if (!panic_stack) | ||
634 | goto out_panic_stack; | ||
635 | |||
636 | *lowcore = S390_lowcore; | ||
637 | lowcore->async_stack = async_stack + ASYNC_SIZE; | ||
638 | lowcore->panic_stack = panic_stack + PAGE_SIZE; | ||
476 | 639 | ||
477 | /* Check for stopped state */ | 640 | #ifndef CONFIG_64BIT |
478 | if (signal_processor_ps(&status, 0, cpu, sigp_sense) == | 641 | if (MACHINE_HAS_IEEE) { |
479 | sigp_status_stored) { | 642 | unsigned long save_area; |
480 | if (status & 0x40) | 643 | |
481 | return 1; | 644 | save_area = get_zeroed_page(GFP_KERNEL); |
645 | if (!save_area) | ||
646 | goto out_save_area; | ||
647 | lowcore->extended_save_area_addr = (u32) save_area; | ||
482 | } | 648 | } |
649 | #endif | ||
650 | lowcore_ptr[cpu] = lowcore; | ||
483 | return 0; | 651 | return 0; |
652 | |||
653 | #ifndef CONFIG_64BIT | ||
654 | out_save_area: | ||
655 | free_page(panic_stack); | ||
656 | #endif | ||
657 | out_panic_stack: | ||
658 | free_pages(async_stack, ASYNC_ORDER); | ||
659 | out_async_stack: | ||
660 | free_pages((unsigned long) lowcore, lc_order); | ||
661 | return -ENOMEM; | ||
484 | } | 662 | } |
485 | 663 | ||
486 | /* Upping and downing of CPUs */ | 664 | #ifdef CONFIG_HOTPLUG_CPU |
665 | static void smp_free_lowcore(int cpu) | ||
666 | { | ||
667 | struct _lowcore *lowcore; | ||
668 | int lc_order; | ||
669 | |||
670 | lc_order = sizeof(long) == 8 ? 1 : 0; | ||
671 | lowcore = lowcore_ptr[cpu]; | ||
672 | #ifndef CONFIG_64BIT | ||
673 | if (MACHINE_HAS_IEEE) | ||
674 | free_page((unsigned long) lowcore->extended_save_area_addr); | ||
675 | #endif | ||
676 | free_page(lowcore->panic_stack - PAGE_SIZE); | ||
677 | free_pages(lowcore->async_stack - ASYNC_SIZE, ASYNC_ORDER); | ||
678 | free_pages((unsigned long) lowcore, lc_order); | ||
679 | lowcore_ptr[cpu] = NULL; | ||
680 | } | ||
681 | #endif /* CONFIG_HOTPLUG_CPU */ | ||
487 | 682 | ||
488 | int __cpu_up(unsigned int cpu) | 683 | /* Upping and downing of CPUs */ |
684 | int __cpuinit __cpu_up(unsigned int cpu) | ||
489 | { | 685 | { |
490 | struct task_struct *idle; | 686 | struct task_struct *idle; |
491 | struct _lowcore *cpu_lowcore; | 687 | struct _lowcore *cpu_lowcore; |
492 | struct stack_frame *sf; | 688 | struct stack_frame *sf; |
493 | sigp_ccode ccode; | 689 | sigp_ccode ccode; |
494 | int curr_cpu; | ||
495 | 690 | ||
496 | for (curr_cpu = 0; curr_cpu <= 65535; curr_cpu++) { | 691 | if (smp_cpu_state[cpu] != CPU_STATE_CONFIGURED) |
497 | __cpu_logical_map[cpu] = (__u16) curr_cpu; | 692 | return -EIO; |
498 | if (cpu_stopped(cpu)) | 693 | if (smp_alloc_lowcore(cpu)) |
499 | break; | 694 | return -ENOMEM; |
500 | } | ||
501 | |||
502 | if (!cpu_stopped(cpu)) | ||
503 | return -ENODEV; | ||
504 | 695 | ||
505 | ccode = signal_processor_p((__u32)(unsigned long)(lowcore_ptr[cpu]), | 696 | ccode = signal_processor_p((__u32)(unsigned long)(lowcore_ptr[cpu]), |
506 | cpu, sigp_set_prefix); | 697 | cpu, sigp_set_prefix); |
@@ -515,6 +706,7 @@ int __cpu_up(unsigned int cpu) | |||
515 | cpu_lowcore = lowcore_ptr[cpu]; | 706 | cpu_lowcore = lowcore_ptr[cpu]; |
516 | cpu_lowcore->kernel_stack = (unsigned long) | 707 | cpu_lowcore->kernel_stack = (unsigned long) |
517 | task_stack_page(idle) + THREAD_SIZE; | 708 | task_stack_page(idle) + THREAD_SIZE; |
709 | cpu_lowcore->thread_info = (unsigned long) task_thread_info(idle); | ||
518 | sf = (struct stack_frame *) (cpu_lowcore->kernel_stack | 710 | sf = (struct stack_frame *) (cpu_lowcore->kernel_stack |
519 | - sizeof(struct pt_regs) | 711 | - sizeof(struct pt_regs) |
520 | - sizeof(struct stack_frame)); | 712 | - sizeof(struct stack_frame)); |
@@ -528,6 +720,8 @@ int __cpu_up(unsigned int cpu) | |||
528 | cpu_lowcore->percpu_offset = __per_cpu_offset[cpu]; | 720 | cpu_lowcore->percpu_offset = __per_cpu_offset[cpu]; |
529 | cpu_lowcore->current_task = (unsigned long) idle; | 721 | cpu_lowcore->current_task = (unsigned long) idle; |
530 | cpu_lowcore->cpu_data.cpu_nr = cpu; | 722 | cpu_lowcore->cpu_data.cpu_nr = cpu; |
723 | cpu_lowcore->softirq_pending = 0; | ||
724 | cpu_lowcore->ext_call_fast = 0; | ||
531 | eieio(); | 725 | eieio(); |
532 | 726 | ||
533 | while (signal_processor(cpu, sigp_restart) == sigp_busy) | 727 | while (signal_processor(cpu, sigp_restart) == sigp_busy) |
@@ -538,44 +732,20 @@ int __cpu_up(unsigned int cpu) | |||
538 | return 0; | 732 | return 0; |
539 | } | 733 | } |
540 | 734 | ||
541 | static unsigned int __initdata additional_cpus; | 735 | static int __init setup_possible_cpus(char *s) |
542 | static unsigned int __initdata possible_cpus; | ||
543 | |||
544 | void __init smp_setup_cpu_possible_map(void) | ||
545 | { | 736 | { |
546 | unsigned int phy_cpus, pos_cpus, cpu; | 737 | int pcpus, cpu; |
547 | |||
548 | phy_cpus = smp_count_cpus(); | ||
549 | pos_cpus = min(phy_cpus + additional_cpus, (unsigned int) NR_CPUS); | ||
550 | |||
551 | if (possible_cpus) | ||
552 | pos_cpus = min(possible_cpus, (unsigned int) NR_CPUS); | ||
553 | 738 | ||
554 | for (cpu = 0; cpu < pos_cpus; cpu++) | 739 | pcpus = simple_strtoul(s, NULL, 0); |
740 | cpu_possible_map = cpumask_of_cpu(0); | ||
741 | for (cpu = 1; cpu < pcpus && cpu < NR_CPUS; cpu++) | ||
555 | cpu_set(cpu, cpu_possible_map); | 742 | cpu_set(cpu, cpu_possible_map); |
556 | |||
557 | phy_cpus = min(phy_cpus, pos_cpus); | ||
558 | |||
559 | for (cpu = 0; cpu < phy_cpus; cpu++) | ||
560 | cpu_set(cpu, cpu_present_map); | ||
561 | } | ||
562 | |||
563 | #ifdef CONFIG_HOTPLUG_CPU | ||
564 | |||
565 | static int __init setup_additional_cpus(char *s) | ||
566 | { | ||
567 | additional_cpus = simple_strtoul(s, NULL, 0); | ||
568 | return 0; | ||
569 | } | ||
570 | early_param("additional_cpus", setup_additional_cpus); | ||
571 | |||
572 | static int __init setup_possible_cpus(char *s) | ||
573 | { | ||
574 | possible_cpus = simple_strtoul(s, NULL, 0); | ||
575 | return 0; | 743 | return 0; |
576 | } | 744 | } |
577 | early_param("possible_cpus", setup_possible_cpus); | 745 | early_param("possible_cpus", setup_possible_cpus); |
578 | 746 | ||
747 | #ifdef CONFIG_HOTPLUG_CPU | ||
748 | |||
579 | int __cpu_disable(void) | 749 | int __cpu_disable(void) |
580 | { | 750 | { |
581 | struct ec_creg_mask_parms cr_parms; | 751 | struct ec_creg_mask_parms cr_parms; |
@@ -612,7 +782,8 @@ void __cpu_die(unsigned int cpu) | |||
612 | /* Wait until target cpu is down */ | 782 | /* Wait until target cpu is down */ |
613 | while (!smp_cpu_not_running(cpu)) | 783 | while (!smp_cpu_not_running(cpu)) |
614 | cpu_relax(); | 784 | cpu_relax(); |
615 | printk("Processor %d spun down\n", cpu); | 785 | smp_free_lowcore(cpu); |
786 | printk(KERN_INFO "Processor %d spun down\n", cpu); | ||
616 | } | 787 | } |
617 | 788 | ||
618 | void cpu_die(void) | 789 | void cpu_die(void) |
@@ -625,49 +796,19 @@ void cpu_die(void) | |||
625 | 796 | ||
626 | #endif /* CONFIG_HOTPLUG_CPU */ | 797 | #endif /* CONFIG_HOTPLUG_CPU */ |
627 | 798 | ||
628 | /* | ||
629 | * Cycle through the processors and setup structures. | ||
630 | */ | ||
631 | |||
632 | void __init smp_prepare_cpus(unsigned int max_cpus) | 799 | void __init smp_prepare_cpus(unsigned int max_cpus) |
633 | { | 800 | { |
634 | unsigned long stack; | ||
635 | unsigned int cpu; | 801 | unsigned int cpu; |
636 | int i; | 802 | |
803 | smp_detect_cpus(); | ||
637 | 804 | ||
638 | /* request the 0x1201 emergency signal external interrupt */ | 805 | /* request the 0x1201 emergency signal external interrupt */ |
639 | if (register_external_interrupt(0x1201, do_ext_call_interrupt) != 0) | 806 | if (register_external_interrupt(0x1201, do_ext_call_interrupt) != 0) |
640 | panic("Couldn't request external interrupt 0x1201"); | 807 | panic("Couldn't request external interrupt 0x1201"); |
641 | memset(lowcore_ptr, 0, sizeof(lowcore_ptr)); | 808 | memset(lowcore_ptr, 0, sizeof(lowcore_ptr)); |
642 | /* | ||
643 | * Initialize prefix pages and stacks for all possible cpus | ||
644 | */ | ||
645 | print_cpu_info(&S390_lowcore.cpu_data); | 809 | print_cpu_info(&S390_lowcore.cpu_data); |
810 | smp_alloc_lowcore(smp_processor_id()); | ||
646 | 811 | ||
647 | for_each_possible_cpu(i) { | ||
648 | lowcore_ptr[i] = (struct _lowcore *) | ||
649 | __get_free_pages(GFP_KERNEL | GFP_DMA, | ||
650 | sizeof(void*) == 8 ? 1 : 0); | ||
651 | stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER); | ||
652 | if (!lowcore_ptr[i] || !stack) | ||
653 | panic("smp_boot_cpus failed to allocate memory\n"); | ||
654 | |||
655 | *(lowcore_ptr[i]) = S390_lowcore; | ||
656 | lowcore_ptr[i]->async_stack = stack + ASYNC_SIZE; | ||
657 | stack = __get_free_pages(GFP_KERNEL, 0); | ||
658 | if (!stack) | ||
659 | panic("smp_boot_cpus failed to allocate memory\n"); | ||
660 | lowcore_ptr[i]->panic_stack = stack + PAGE_SIZE; | ||
661 | #ifndef CONFIG_64BIT | ||
662 | if (MACHINE_HAS_IEEE) { | ||
663 | lowcore_ptr[i]->extended_save_area_addr = | ||
664 | (__u32) __get_free_pages(GFP_KERNEL, 0); | ||
665 | if (!lowcore_ptr[i]->extended_save_area_addr) | ||
666 | panic("smp_boot_cpus failed to " | ||
667 | "allocate memory\n"); | ||
668 | } | ||
669 | #endif | ||
670 | } | ||
671 | #ifndef CONFIG_64BIT | 812 | #ifndef CONFIG_64BIT |
672 | if (MACHINE_HAS_IEEE) | 813 | if (MACHINE_HAS_IEEE) |
673 | ctl_set_bit(14, 29); /* enable extended save area */ | 814 | ctl_set_bit(14, 29); /* enable extended save area */ |
@@ -683,15 +824,17 @@ void __init smp_prepare_boot_cpu(void) | |||
683 | { | 824 | { |
684 | BUG_ON(smp_processor_id() != 0); | 825 | BUG_ON(smp_processor_id() != 0); |
685 | 826 | ||
827 | current_thread_info()->cpu = 0; | ||
828 | cpu_set(0, cpu_present_map); | ||
686 | cpu_set(0, cpu_online_map); | 829 | cpu_set(0, cpu_online_map); |
687 | S390_lowcore.percpu_offset = __per_cpu_offset[0]; | 830 | S390_lowcore.percpu_offset = __per_cpu_offset[0]; |
688 | current_set[0] = current; | 831 | current_set[0] = current; |
832 | smp_cpu_state[0] = CPU_STATE_CONFIGURED; | ||
689 | spin_lock_init(&(&__get_cpu_var(s390_idle))->lock); | 833 | spin_lock_init(&(&__get_cpu_var(s390_idle))->lock); |
690 | } | 834 | } |
691 | 835 | ||
692 | void __init smp_cpus_done(unsigned int max_cpus) | 836 | void __init smp_cpus_done(unsigned int max_cpus) |
693 | { | 837 | { |
694 | cpu_present_map = cpu_possible_map; | ||
695 | } | 838 | } |
696 | 839 | ||
697 | /* | 840 | /* |
@@ -705,7 +848,79 @@ int setup_profiling_timer(unsigned int multiplier) | |||
705 | return 0; | 848 | return 0; |
706 | } | 849 | } |
707 | 850 | ||
708 | static DEFINE_PER_CPU(struct cpu, cpu_devices); | 851 | #ifdef CONFIG_HOTPLUG_CPU |
852 | static ssize_t cpu_configure_show(struct sys_device *dev, char *buf) | ||
853 | { | ||
854 | ssize_t count; | ||
855 | |||
856 | mutex_lock(&smp_cpu_state_mutex); | ||
857 | count = sprintf(buf, "%d\n", smp_cpu_state[dev->id]); | ||
858 | mutex_unlock(&smp_cpu_state_mutex); | ||
859 | return count; | ||
860 | } | ||
861 | |||
862 | static ssize_t cpu_configure_store(struct sys_device *dev, const char *buf, | ||
863 | size_t count) | ||
864 | { | ||
865 | int cpu = dev->id; | ||
866 | int val, rc; | ||
867 | char delim; | ||
868 | |||
869 | if (sscanf(buf, "%d %c", &val, &delim) != 1) | ||
870 | return -EINVAL; | ||
871 | if (val != 0 && val != 1) | ||
872 | return -EINVAL; | ||
873 | |||
874 | mutex_lock(&smp_cpu_state_mutex); | ||
875 | get_online_cpus(); | ||
876 | rc = -EBUSY; | ||
877 | if (cpu_online(cpu)) | ||
878 | goto out; | ||
879 | rc = 0; | ||
880 | switch (val) { | ||
881 | case 0: | ||
882 | if (smp_cpu_state[cpu] == CPU_STATE_CONFIGURED) { | ||
883 | rc = sclp_cpu_deconfigure(__cpu_logical_map[cpu]); | ||
884 | if (!rc) | ||
885 | smp_cpu_state[cpu] = CPU_STATE_STANDBY; | ||
886 | } | ||
887 | break; | ||
888 | case 1: | ||
889 | if (smp_cpu_state[cpu] == CPU_STATE_STANDBY) { | ||
890 | rc = sclp_cpu_configure(__cpu_logical_map[cpu]); | ||
891 | if (!rc) | ||
892 | smp_cpu_state[cpu] = CPU_STATE_CONFIGURED; | ||
893 | } | ||
894 | break; | ||
895 | default: | ||
896 | break; | ||
897 | } | ||
898 | out: | ||
899 | put_online_cpus(); | ||
900 | mutex_unlock(&smp_cpu_state_mutex); | ||
901 | return rc ? rc : count; | ||
902 | } | ||
903 | static SYSDEV_ATTR(configure, 0644, cpu_configure_show, cpu_configure_store); | ||
904 | #endif /* CONFIG_HOTPLUG_CPU */ | ||
905 | |||
906 | static ssize_t show_cpu_address(struct sys_device *dev, char *buf) | ||
907 | { | ||
908 | return sprintf(buf, "%d\n", __cpu_logical_map[dev->id]); | ||
909 | } | ||
910 | static SYSDEV_ATTR(address, 0444, show_cpu_address, NULL); | ||
911 | |||
912 | |||
913 | static struct attribute *cpu_common_attrs[] = { | ||
914 | #ifdef CONFIG_HOTPLUG_CPU | ||
915 | &attr_configure.attr, | ||
916 | #endif | ||
917 | &attr_address.attr, | ||
918 | NULL, | ||
919 | }; | ||
920 | |||
921 | static struct attribute_group cpu_common_attr_group = { | ||
922 | .attrs = cpu_common_attrs, | ||
923 | }; | ||
709 | 924 | ||
710 | static ssize_t show_capability(struct sys_device *dev, char *buf) | 925 | static ssize_t show_capability(struct sys_device *dev, char *buf) |
711 | { | 926 | { |
@@ -750,15 +965,15 @@ static ssize_t show_idle_time(struct sys_device *dev, char *buf) | |||
750 | } | 965 | } |
751 | static SYSDEV_ATTR(idle_time_us, 0444, show_idle_time, NULL); | 966 | static SYSDEV_ATTR(idle_time_us, 0444, show_idle_time, NULL); |
752 | 967 | ||
753 | static struct attribute *cpu_attrs[] = { | 968 | static struct attribute *cpu_online_attrs[] = { |
754 | &attr_capability.attr, | 969 | &attr_capability.attr, |
755 | &attr_idle_count.attr, | 970 | &attr_idle_count.attr, |
756 | &attr_idle_time_us.attr, | 971 | &attr_idle_time_us.attr, |
757 | NULL, | 972 | NULL, |
758 | }; | 973 | }; |
759 | 974 | ||
760 | static struct attribute_group cpu_attr_group = { | 975 | static struct attribute_group cpu_online_attr_group = { |
761 | .attrs = cpu_attrs, | 976 | .attrs = cpu_online_attrs, |
762 | }; | 977 | }; |
763 | 978 | ||
764 | static int __cpuinit smp_cpu_notify(struct notifier_block *self, | 979 | static int __cpuinit smp_cpu_notify(struct notifier_block *self, |
@@ -778,12 +993,12 @@ static int __cpuinit smp_cpu_notify(struct notifier_block *self, | |||
778 | idle->idle_time = 0; | 993 | idle->idle_time = 0; |
779 | idle->idle_count = 0; | 994 | idle->idle_count = 0; |
780 | spin_unlock_irq(&idle->lock); | 995 | spin_unlock_irq(&idle->lock); |
781 | if (sysfs_create_group(&s->kobj, &cpu_attr_group)) | 996 | if (sysfs_create_group(&s->kobj, &cpu_online_attr_group)) |
782 | return NOTIFY_BAD; | 997 | return NOTIFY_BAD; |
783 | break; | 998 | break; |
784 | case CPU_DEAD: | 999 | case CPU_DEAD: |
785 | case CPU_DEAD_FROZEN: | 1000 | case CPU_DEAD_FROZEN: |
786 | sysfs_remove_group(&s->kobj, &cpu_attr_group); | 1001 | sysfs_remove_group(&s->kobj, &cpu_online_attr_group); |
787 | break; | 1002 | break; |
788 | } | 1003 | } |
789 | return NOTIFY_OK; | 1004 | return NOTIFY_OK; |
@@ -793,6 +1008,62 @@ static struct notifier_block __cpuinitdata smp_cpu_nb = { | |||
793 | .notifier_call = smp_cpu_notify, | 1008 | .notifier_call = smp_cpu_notify, |
794 | }; | 1009 | }; |
795 | 1010 | ||
1011 | static int smp_add_present_cpu(int cpu) | ||
1012 | { | ||
1013 | struct cpu *c = &per_cpu(cpu_devices, cpu); | ||
1014 | struct sys_device *s = &c->sysdev; | ||
1015 | int rc; | ||
1016 | |||
1017 | c->hotpluggable = 1; | ||
1018 | rc = register_cpu(c, cpu); | ||
1019 | if (rc) | ||
1020 | goto out; | ||
1021 | rc = sysfs_create_group(&s->kobj, &cpu_common_attr_group); | ||
1022 | if (rc) | ||
1023 | goto out_cpu; | ||
1024 | if (!cpu_online(cpu)) | ||
1025 | goto out; | ||
1026 | rc = sysfs_create_group(&s->kobj, &cpu_online_attr_group); | ||
1027 | if (!rc) | ||
1028 | return 0; | ||
1029 | sysfs_remove_group(&s->kobj, &cpu_common_attr_group); | ||
1030 | out_cpu: | ||
1031 | #ifdef CONFIG_HOTPLUG_CPU | ||
1032 | unregister_cpu(c); | ||
1033 | #endif | ||
1034 | out: | ||
1035 | return rc; | ||
1036 | } | ||
1037 | |||
1038 | #ifdef CONFIG_HOTPLUG_CPU | ||
1039 | static ssize_t rescan_store(struct sys_device *dev, const char *buf, | ||
1040 | size_t count) | ||
1041 | { | ||
1042 | cpumask_t newcpus; | ||
1043 | int cpu; | ||
1044 | int rc; | ||
1045 | |||
1046 | mutex_lock(&smp_cpu_state_mutex); | ||
1047 | get_online_cpus(); | ||
1048 | newcpus = cpu_present_map; | ||
1049 | rc = smp_rescan_cpus(); | ||
1050 | if (rc) | ||
1051 | goto out; | ||
1052 | cpus_andnot(newcpus, cpu_present_map, newcpus); | ||
1053 | for_each_cpu_mask(cpu, newcpus) { | ||
1054 | rc = smp_add_present_cpu(cpu); | ||
1055 | if (rc) | ||
1056 | cpu_clear(cpu, cpu_present_map); | ||
1057 | } | ||
1058 | rc = 0; | ||
1059 | out: | ||
1060 | put_online_cpus(); | ||
1061 | mutex_unlock(&smp_cpu_state_mutex); | ||
1062 | return rc ? rc : count; | ||
1063 | } | ||
1064 | static SYSDEV_ATTR(rescan, 0200, NULL, rescan_store); | ||
1065 | #endif /* CONFIG_HOTPLUG_CPU */ | ||
1066 | |||
796 | static int __init topology_init(void) | 1067 | static int __init topology_init(void) |
797 | { | 1068 | { |
798 | int cpu; | 1069 | int cpu; |
@@ -800,16 +1071,14 @@ static int __init topology_init(void) | |||
800 | 1071 | ||
801 | register_cpu_notifier(&smp_cpu_nb); | 1072 | register_cpu_notifier(&smp_cpu_nb); |
802 | 1073 | ||
803 | for_each_possible_cpu(cpu) { | 1074 | #ifdef CONFIG_HOTPLUG_CPU |
804 | struct cpu *c = &per_cpu(cpu_devices, cpu); | 1075 | rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj, |
805 | struct sys_device *s = &c->sysdev; | 1076 | &attr_rescan.attr); |
806 | 1077 | if (rc) | |
807 | c->hotpluggable = 1; | 1078 | return rc; |
808 | register_cpu(c, cpu); | 1079 | #endif |
809 | if (!cpu_online(cpu)) | 1080 | for_each_present_cpu(cpu) { |
810 | continue; | 1081 | rc = smp_add_present_cpu(cpu); |
811 | s = &c->sysdev; | ||
812 | rc = sysfs_create_group(&s->kobj, &cpu_attr_group); | ||
813 | if (rc) | 1082 | if (rc) |
814 | return rc; | 1083 | return rc; |
815 | } | 1084 | } |
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index 8ed16a83fba7..52b8342c6bf2 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/reboot.h> | 31 | #include <linux/reboot.h> |
32 | #include <linux/kprobes.h> | 32 | #include <linux/kprobes.h> |
33 | #include <linux/bug.h> | 33 | #include <linux/bug.h> |
34 | #include <linux/utsname.h> | ||
34 | #include <asm/system.h> | 35 | #include <asm/system.h> |
35 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
36 | #include <asm/io.h> | 37 | #include <asm/io.h> |
@@ -168,9 +169,16 @@ void show_stack(struct task_struct *task, unsigned long *sp) | |||
168 | */ | 169 | */ |
169 | void dump_stack(void) | 170 | void dump_stack(void) |
170 | { | 171 | { |
172 | printk("CPU: %d %s %s %.*s\n", | ||
173 | task_thread_info(current)->cpu, print_tainted(), | ||
174 | init_utsname()->release, | ||
175 | (int)strcspn(init_utsname()->version, " "), | ||
176 | init_utsname()->version); | ||
177 | printk("Process %s (pid: %d, task: %p, ksp: %p)\n", | ||
178 | current->comm, current->pid, current, | ||
179 | (void *) current->thread.ksp); | ||
171 | show_stack(NULL, NULL); | 180 | show_stack(NULL, NULL); |
172 | } | 181 | } |
173 | |||
174 | EXPORT_SYMBOL(dump_stack); | 182 | EXPORT_SYMBOL(dump_stack); |
175 | 183 | ||
176 | static inline int mask_bits(struct pt_regs *regs, unsigned long bits) | 184 | static inline int mask_bits(struct pt_regs *regs, unsigned long bits) |
@@ -258,8 +266,14 @@ void die(const char * str, struct pt_regs * regs, long err) | |||
258 | console_verbose(); | 266 | console_verbose(); |
259 | spin_lock_irq(&die_lock); | 267 | spin_lock_irq(&die_lock); |
260 | bust_spinlocks(1); | 268 | bust_spinlocks(1); |
261 | printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); | 269 | printk("%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter); |
262 | print_modules(); | 270 | #ifdef CONFIG_PREEMPT |
271 | printk("PREEMPT "); | ||
272 | #endif | ||
273 | #ifdef CONFIG_SMP | ||
274 | printk("SMP"); | ||
275 | #endif | ||
276 | printk("\n"); | ||
263 | notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV); | 277 | notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV); |
264 | show_regs(regs); | 278 | show_regs(regs); |
265 | bust_spinlocks(0); | 279 | bust_spinlocks(0); |
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index 849120e3e28a..936159199346 100644 --- a/arch/s390/kernel/vmlinux.lds.S +++ b/arch/s390/kernel/vmlinux.lds.S | |||
@@ -17,6 +17,12 @@ ENTRY(_start) | |||
17 | jiffies = jiffies_64; | 17 | jiffies = jiffies_64; |
18 | #endif | 18 | #endif |
19 | 19 | ||
20 | PHDRS { | ||
21 | text PT_LOAD FLAGS(5); /* R_E */ | ||
22 | data PT_LOAD FLAGS(7); /* RWE */ | ||
23 | note PT_NOTE FLAGS(0); /* ___ */ | ||
24 | } | ||
25 | |||
20 | SECTIONS | 26 | SECTIONS |
21 | { | 27 | { |
22 | . = 0x00000000; | 28 | . = 0x00000000; |
@@ -33,6 +39,9 @@ SECTIONS | |||
33 | 39 | ||
34 | _etext = .; /* End of text section */ | 40 | _etext = .; /* End of text section */ |
35 | 41 | ||
42 | NOTES :text :note | ||
43 | BUG_TABLE :text | ||
44 | |||
36 | RODATA | 45 | RODATA |
37 | 46 | ||
38 | #ifdef CONFIG_SHARED_KERNEL | 47 | #ifdef CONFIG_SHARED_KERNEL |
@@ -49,9 +58,6 @@ SECTIONS | |||
49 | __stop___ex_table = .; | 58 | __stop___ex_table = .; |
50 | } | 59 | } |
51 | 60 | ||
52 | NOTES | ||
53 | BUG_TABLE | ||
54 | |||
55 | .data : { /* Data */ | 61 | .data : { /* Data */ |
56 | DATA_DATA | 62 | DATA_DATA |
57 | CONSTRUCTORS | 63 | CONSTRUCTORS |
diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c index 8d76403fcf89..e41f4008afc5 100644 --- a/arch/s390/lib/spinlock.c +++ b/arch/s390/lib/spinlock.c | |||
@@ -39,7 +39,7 @@ static inline void _raw_yield_cpu(int cpu) | |||
39 | _raw_yield(); | 39 | _raw_yield(); |
40 | } | 40 | } |
41 | 41 | ||
42 | void _raw_spin_lock_wait(raw_spinlock_t *lp, unsigned int pc) | 42 | void _raw_spin_lock_wait(raw_spinlock_t *lp) |
43 | { | 43 | { |
44 | int count = spin_retry; | 44 | int count = spin_retry; |
45 | unsigned int cpu = ~smp_processor_id(); | 45 | unsigned int cpu = ~smp_processor_id(); |
@@ -53,15 +53,36 @@ void _raw_spin_lock_wait(raw_spinlock_t *lp, unsigned int pc) | |||
53 | } | 53 | } |
54 | if (__raw_spin_is_locked(lp)) | 54 | if (__raw_spin_is_locked(lp)) |
55 | continue; | 55 | continue; |
56 | if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0) { | 56 | if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0) |
57 | lp->owner_pc = pc; | ||
58 | return; | 57 | return; |
59 | } | ||
60 | } | 58 | } |
61 | } | 59 | } |
62 | EXPORT_SYMBOL(_raw_spin_lock_wait); | 60 | EXPORT_SYMBOL(_raw_spin_lock_wait); |
63 | 61 | ||
64 | int _raw_spin_trylock_retry(raw_spinlock_t *lp, unsigned int pc) | 62 | void _raw_spin_lock_wait_flags(raw_spinlock_t *lp, unsigned long flags) |
63 | { | ||
64 | int count = spin_retry; | ||
65 | unsigned int cpu = ~smp_processor_id(); | ||
66 | |||
67 | local_irq_restore(flags); | ||
68 | while (1) { | ||
69 | if (count-- <= 0) { | ||
70 | unsigned int owner = lp->owner_cpu; | ||
71 | if (owner != 0) | ||
72 | _raw_yield_cpu(~owner); | ||
73 | count = spin_retry; | ||
74 | } | ||
75 | if (__raw_spin_is_locked(lp)) | ||
76 | continue; | ||
77 | local_irq_disable(); | ||
78 | if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0) | ||
79 | return; | ||
80 | local_irq_restore(flags); | ||
81 | } | ||
82 | } | ||
83 | EXPORT_SYMBOL(_raw_spin_lock_wait_flags); | ||
84 | |||
85 | int _raw_spin_trylock_retry(raw_spinlock_t *lp) | ||
65 | { | 86 | { |
66 | unsigned int cpu = ~smp_processor_id(); | 87 | unsigned int cpu = ~smp_processor_id(); |
67 | int count; | 88 | int count; |
@@ -69,10 +90,8 @@ int _raw_spin_trylock_retry(raw_spinlock_t *lp, unsigned int pc) | |||
69 | for (count = spin_retry; count > 0; count--) { | 90 | for (count = spin_retry; count > 0; count--) { |
70 | if (__raw_spin_is_locked(lp)) | 91 | if (__raw_spin_is_locked(lp)) |
71 | continue; | 92 | continue; |
72 | if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0) { | 93 | if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0) |
73 | lp->owner_pc = pc; | ||
74 | return 1; | 94 | return 1; |
75 | } | ||
76 | } | 95 | } |
77 | return 0; | 96 | return 0; |
78 | } | 97 | } |
diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c index 394980b05e6f..880b0ebf894b 100644 --- a/arch/s390/mm/extmem.c +++ b/arch/s390/mm/extmem.c | |||
@@ -83,7 +83,7 @@ struct dcss_segment { | |||
83 | }; | 83 | }; |
84 | 84 | ||
85 | static DEFINE_MUTEX(dcss_lock); | 85 | static DEFINE_MUTEX(dcss_lock); |
86 | static struct list_head dcss_list = LIST_HEAD_INIT(dcss_list); | 86 | static LIST_HEAD(dcss_list); |
87 | static char *segtype_string[] = { "SW", "EW", "SR", "ER", "SN", "EN", "SC", | 87 | static char *segtype_string[] = { "SW", "EW", "SR", "ER", "SN", "EN", "SC", |
88 | "EW/EN-MIXED" }; | 88 | "EW/EN-MIXED" }; |
89 | 89 | ||
diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c index fb9c5a85aa56..79d13a166a3d 100644 --- a/arch/s390/mm/vmem.c +++ b/arch/s390/mm/vmem.c | |||
@@ -15,10 +15,6 @@ | |||
15 | #include <asm/setup.h> | 15 | #include <asm/setup.h> |
16 | #include <asm/tlbflush.h> | 16 | #include <asm/tlbflush.h> |
17 | 17 | ||
18 | unsigned long vmalloc_end; | ||
19 | EXPORT_SYMBOL(vmalloc_end); | ||
20 | |||
21 | static struct page *vmem_map; | ||
22 | static DEFINE_MUTEX(vmem_mutex); | 18 | static DEFINE_MUTEX(vmem_mutex); |
23 | 19 | ||
24 | struct memory_segment { | 20 | struct memory_segment { |
@@ -188,8 +184,8 @@ static int vmem_add_mem_map(unsigned long start, unsigned long size) | |||
188 | pte_t pte; | 184 | pte_t pte; |
189 | int ret = -ENOMEM; | 185 | int ret = -ENOMEM; |
190 | 186 | ||
191 | map_start = vmem_map + PFN_DOWN(start); | 187 | map_start = VMEM_MAP + PFN_DOWN(start); |
192 | map_end = vmem_map + PFN_DOWN(start + size); | 188 | map_end = VMEM_MAP + PFN_DOWN(start + size); |
193 | 189 | ||
194 | start_addr = (unsigned long) map_start & PAGE_MASK; | 190 | start_addr = (unsigned long) map_start & PAGE_MASK; |
195 | end_addr = PFN_ALIGN((unsigned long) map_end); | 191 | end_addr = PFN_ALIGN((unsigned long) map_end); |
@@ -240,10 +236,10 @@ static int vmem_add_mem(unsigned long start, unsigned long size) | |||
240 | { | 236 | { |
241 | int ret; | 237 | int ret; |
242 | 238 | ||
243 | ret = vmem_add_range(start, size); | 239 | ret = vmem_add_mem_map(start, size); |
244 | if (ret) | 240 | if (ret) |
245 | return ret; | 241 | return ret; |
246 | return vmem_add_mem_map(start, size); | 242 | return vmem_add_range(start, size); |
247 | } | 243 | } |
248 | 244 | ||
249 | /* | 245 | /* |
@@ -254,7 +250,7 @@ static int insert_memory_segment(struct memory_segment *seg) | |||
254 | { | 250 | { |
255 | struct memory_segment *tmp; | 251 | struct memory_segment *tmp; |
256 | 252 | ||
257 | if (PFN_DOWN(seg->start + seg->size) > max_pfn || | 253 | if (seg->start + seg->size >= VMALLOC_START || |
258 | seg->start + seg->size < seg->start) | 254 | seg->start + seg->size < seg->start) |
259 | return -ERANGE; | 255 | return -ERANGE; |
260 | 256 | ||
@@ -357,17 +353,15 @@ out: | |||
357 | 353 | ||
358 | /* | 354 | /* |
359 | * map whole physical memory to virtual memory (identity mapping) | 355 | * map whole physical memory to virtual memory (identity mapping) |
356 | * we reserve enough space in the vmalloc area for vmemmap to hotplug | ||
357 | * additional memory segments. | ||
360 | */ | 358 | */ |
361 | void __init vmem_map_init(void) | 359 | void __init vmem_map_init(void) |
362 | { | 360 | { |
363 | unsigned long map_size; | ||
364 | int i; | 361 | int i; |
365 | 362 | ||
366 | map_size = ALIGN(max_low_pfn, MAX_ORDER_NR_PAGES) * sizeof(struct page); | 363 | BUILD_BUG_ON((unsigned long)VMEM_MAP + VMEM_MAP_SIZE > VMEM_MAP_MAX); |
367 | vmalloc_end = PFN_ALIGN(VMALLOC_END_INIT) - PFN_ALIGN(map_size); | 364 | NODE_DATA(0)->node_mem_map = VMEM_MAP; |
368 | vmem_map = (struct page *) vmalloc_end; | ||
369 | NODE_DATA(0)->node_mem_map = vmem_map; | ||
370 | |||
371 | for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) | 365 | for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) |
372 | vmem_add_mem(memory_chunk[i].addr, memory_chunk[i].size); | 366 | vmem_add_mem(memory_chunk[i].addr, memory_chunk[i].size); |
373 | } | 367 | } |
@@ -382,7 +376,7 @@ static int __init vmem_convert_memory_chunk(void) | |||
382 | int i; | 376 | int i; |
383 | 377 | ||
384 | mutex_lock(&vmem_mutex); | 378 | mutex_lock(&vmem_mutex); |
385 | for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) { | 379 | for (i = 0; i < MEMORY_CHUNKS; i++) { |
386 | if (!memory_chunk[i].size) | 380 | if (!memory_chunk[i].size) |
387 | continue; | 381 | continue; |
388 | seg = kzalloc(sizeof(*seg), GFP_KERNEL); | 382 | seg = kzalloc(sizeof(*seg), GFP_KERNEL); |
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 8a70a9edabda..6b658d84d521 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig | |||
@@ -48,8 +48,6 @@ config CRYPTO_DEV_PADLOCK_SHA | |||
48 | If unsure say M. The compiled module will be | 48 | If unsure say M. The compiled module will be |
49 | called padlock-sha.ko | 49 | called padlock-sha.ko |
50 | 50 | ||
51 | source "arch/s390/crypto/Kconfig" | ||
52 | |||
53 | config CRYPTO_DEV_GEODE | 51 | config CRYPTO_DEV_GEODE |
54 | tristate "Support for the Geode LX AES engine" | 52 | tristate "Support for the Geode LX AES engine" |
55 | depends on X86_32 && PCI | 53 | depends on X86_32 && PCI |
@@ -83,6 +81,67 @@ config ZCRYPT_MONOLITHIC | |||
83 | that contains all parts of the crypto device driver (ap bus, | 81 | that contains all parts of the crypto device driver (ap bus, |
84 | request router and all the card drivers). | 82 | request router and all the card drivers). |
85 | 83 | ||
84 | config CRYPTO_SHA1_S390 | ||
85 | tristate "SHA1 digest algorithm" | ||
86 | depends on S390 | ||
87 | select CRYPTO_ALGAPI | ||
88 | help | ||
89 | This is the s390 hardware accelerated implementation of the | ||
90 | SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2). | ||
91 | |||
92 | config CRYPTO_SHA256_S390 | ||
93 | tristate "SHA256 digest algorithm" | ||
94 | depends on S390 | ||
95 | select CRYPTO_ALGAPI | ||
96 | help | ||
97 | This is the s390 hardware accelerated implementation of the | ||
98 | SHA256 secure hash standard (DFIPS 180-2). | ||
99 | |||
100 | This version of SHA implements a 256 bit hash with 128 bits of | ||
101 | security against collision attacks. | ||
102 | |||
103 | config CRYPTO_DES_S390 | ||
104 | tristate "DES and Triple DES cipher algorithms" | ||
105 | depends on S390 | ||
106 | select CRYPTO_ALGAPI | ||
107 | select CRYPTO_BLKCIPHER | ||
108 | help | ||
109 | This us the s390 hardware accelerated implementation of the | ||
110 | DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3). | ||
111 | |||
112 | config CRYPTO_AES_S390 | ||
113 | tristate "AES cipher algorithms" | ||
114 | depends on S390 | ||
115 | select CRYPTO_ALGAPI | ||
116 | select CRYPTO_BLKCIPHER | ||
117 | help | ||
118 | This is the s390 hardware accelerated implementation of the | ||
119 | AES cipher algorithms (FIPS-197). AES uses the Rijndael | ||
120 | algorithm. | ||
121 | |||
122 | Rijndael appears to be consistently a very good performer in | ||
123 | both hardware and software across a wide range of computing | ||
124 | environments regardless of its use in feedback or non-feedback | ||
125 | modes. Its key setup time is excellent, and its key agility is | ||
126 | good. Rijndael's very low memory requirements make it very well | ||
127 | suited for restricted-space environments, in which it also | ||
128 | demonstrates excellent performance. Rijndael's operations are | ||
129 | among the easiest to defend against power and timing attacks. | ||
130 | |||
131 | On s390 the System z9-109 currently only supports the key size | ||
132 | of 128 bit. | ||
133 | |||
134 | config S390_PRNG | ||
135 | tristate "Pseudo random number generator device driver" | ||
136 | depends on S390 | ||
137 | default "m" | ||
138 | help | ||
139 | Select this option if you want to use the s390 pseudo random number | ||
140 | generator. The PRNG is part of the cryptographic processor functions | ||
141 | and uses triple-DES to generate secure random numbers like the | ||
142 | ANSI X9.17 standard. The PRNG is usable via the char device | ||
143 | /dev/prandom. | ||
144 | |||
86 | config CRYPTO_DEV_HIFN_795X | 145 | config CRYPTO_DEV_HIFN_795X |
87 | tristate "Driver HIFN 795x crypto accelerator chips" | 146 | tristate "Driver HIFN 795x crypto accelerator chips" |
88 | select CRYPTO_DES | 147 | select CRYPTO_DES |
diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index a37cb6b8593c..35812823787b 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* ------------------------------------------------------------------------- */ | 1 | /* ------------------------------------------------------------------------- |
2 | /* i2c-algo-bit.c i2c driver algorithms for bit-shift adapters */ | 2 | * i2c-algo-bit.c i2c driver algorithms for bit-shift adapters |
3 | /* ------------------------------------------------------------------------- */ | 3 | * ------------------------------------------------------------------------- |
4 | /* Copyright (C) 1995-2000 Simon G. Vogl | 4 | * Copyright (C) 1995-2000 Simon G. Vogl |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify | 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 | 7 | it under the terms of the GNU General Public License as published by |
@@ -15,8 +15,8 @@ | |||
15 | 15 | ||
16 | You should have received a copy of the GNU General Public License | 16 | You should have received a copy of the GNU General Public License |
17 | along with this program; if not, write to the Free Software | 17 | along with this program; if not, write to the Free Software |
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
19 | /* ------------------------------------------------------------------------- */ | 19 | * ------------------------------------------------------------------------- */ |
20 | 20 | ||
21 | /* With some changes from Frodo Looijaard <frodol@dds.nl>, Kyösti Mälkki | 21 | /* With some changes from Frodo Looijaard <frodol@dds.nl>, Kyösti Mälkki |
22 | <kmalkki@cc.hut.fi> and Jean Delvare <khali@linux-fr.org> */ | 22 | <kmalkki@cc.hut.fi> and Jean Delvare <khali@linux-fr.org> */ |
@@ -60,26 +60,26 @@ MODULE_PARM_DESC(i2c_debug, | |||
60 | 60 | ||
61 | /* --- setting states on the bus with the right timing: --------------- */ | 61 | /* --- setting states on the bus with the right timing: --------------- */ |
62 | 62 | ||
63 | #define setsda(adap,val) adap->setsda(adap->data, val) | 63 | #define setsda(adap, val) adap->setsda(adap->data, val) |
64 | #define setscl(adap,val) adap->setscl(adap->data, val) | 64 | #define setscl(adap, val) adap->setscl(adap->data, val) |
65 | #define getsda(adap) adap->getsda(adap->data) | 65 | #define getsda(adap) adap->getsda(adap->data) |
66 | #define getscl(adap) adap->getscl(adap->data) | 66 | #define getscl(adap) adap->getscl(adap->data) |
67 | 67 | ||
68 | static inline void sdalo(struct i2c_algo_bit_data *adap) | 68 | static inline void sdalo(struct i2c_algo_bit_data *adap) |
69 | { | 69 | { |
70 | setsda(adap,0); | 70 | setsda(adap, 0); |
71 | udelay((adap->udelay + 1) / 2); | 71 | udelay((adap->udelay + 1) / 2); |
72 | } | 72 | } |
73 | 73 | ||
74 | static inline void sdahi(struct i2c_algo_bit_data *adap) | 74 | static inline void sdahi(struct i2c_algo_bit_data *adap) |
75 | { | 75 | { |
76 | setsda(adap,1); | 76 | setsda(adap, 1); |
77 | udelay((adap->udelay + 1) / 2); | 77 | udelay((adap->udelay + 1) / 2); |
78 | } | 78 | } |
79 | 79 | ||
80 | static inline void scllo(struct i2c_algo_bit_data *adap) | 80 | static inline void scllo(struct i2c_algo_bit_data *adap) |
81 | { | 81 | { |
82 | setscl(adap,0); | 82 | setscl(adap, 0); |
83 | udelay(adap->udelay / 2); | 83 | udelay(adap->udelay / 2); |
84 | } | 84 | } |
85 | 85 | ||
@@ -91,22 +91,21 @@ static int sclhi(struct i2c_algo_bit_data *adap) | |||
91 | { | 91 | { |
92 | unsigned long start; | 92 | unsigned long start; |
93 | 93 | ||
94 | setscl(adap,1); | 94 | setscl(adap, 1); |
95 | 95 | ||
96 | /* Not all adapters have scl sense line... */ | 96 | /* Not all adapters have scl sense line... */ |
97 | if (!adap->getscl) | 97 | if (!adap->getscl) |
98 | goto done; | 98 | goto done; |
99 | 99 | ||
100 | start=jiffies; | 100 | start = jiffies; |
101 | while (! getscl(adap) ) { | 101 | while (!getscl(adap)) { |
102 | /* the hw knows how to read the clock line, | 102 | /* This hw knows how to read the clock line, so we wait |
103 | * so we wait until it actually gets high. | 103 | * until it actually gets high. This is safer as some |
104 | * This is safer as some chips may hold it low | 104 | * chips may hold it low ("clock stretching") while they |
105 | * while they are processing data internally. | 105 | * are processing data internally. |
106 | */ | 106 | */ |
107 | if (time_after_eq(jiffies, start+adap->timeout)) { | 107 | if (time_after_eq(jiffies, start + adap->timeout)) |
108 | return -ETIMEDOUT; | 108 | return -ETIMEDOUT; |
109 | } | ||
110 | cond_resched(); | 109 | cond_resched(); |
111 | } | 110 | } |
112 | #ifdef DEBUG | 111 | #ifdef DEBUG |
@@ -118,11 +117,11 @@ static int sclhi(struct i2c_algo_bit_data *adap) | |||
118 | done: | 117 | done: |
119 | udelay(adap->udelay); | 118 | udelay(adap->udelay); |
120 | return 0; | 119 | return 0; |
121 | } | 120 | } |
122 | 121 | ||
123 | 122 | ||
124 | /* --- other auxiliary functions -------------------------------------- */ | 123 | /* --- other auxiliary functions -------------------------------------- */ |
125 | static void i2c_start(struct i2c_algo_bit_data *adap) | 124 | static void i2c_start(struct i2c_algo_bit_data *adap) |
126 | { | 125 | { |
127 | /* assert: scl, sda are high */ | 126 | /* assert: scl, sda are high */ |
128 | setsda(adap, 0); | 127 | setsda(adap, 0); |
@@ -130,7 +129,7 @@ static void i2c_start(struct i2c_algo_bit_data *adap) | |||
130 | scllo(adap); | 129 | scllo(adap); |
131 | } | 130 | } |
132 | 131 | ||
133 | static void i2c_repstart(struct i2c_algo_bit_data *adap) | 132 | static void i2c_repstart(struct i2c_algo_bit_data *adap) |
134 | { | 133 | { |
135 | /* assert: scl is low */ | 134 | /* assert: scl is low */ |
136 | sdahi(adap); | 135 | sdahi(adap); |
@@ -141,18 +140,18 @@ static void i2c_repstart(struct i2c_algo_bit_data *adap) | |||
141 | } | 140 | } |
142 | 141 | ||
143 | 142 | ||
144 | static void i2c_stop(struct i2c_algo_bit_data *adap) | 143 | static void i2c_stop(struct i2c_algo_bit_data *adap) |
145 | { | 144 | { |
146 | /* assert: scl is low */ | 145 | /* assert: scl is low */ |
147 | sdalo(adap); | 146 | sdalo(adap); |
148 | sclhi(adap); | 147 | sclhi(adap); |
149 | setsda(adap, 1); | 148 | setsda(adap, 1); |
150 | udelay(adap->udelay); | 149 | udelay(adap->udelay); |
151 | } | 150 | } |
152 | 151 | ||
153 | 152 | ||
154 | 153 | ||
155 | /* send a byte without start cond., look for arbitration, | 154 | /* send a byte without start cond., look for arbitration, |
156 | check ackn. from slave */ | 155 | check ackn. from slave */ |
157 | /* returns: | 156 | /* returns: |
158 | * 1 if the device acknowledged | 157 | * 1 if the device acknowledged |
@@ -167,27 +166,33 @@ static int i2c_outb(struct i2c_adapter *i2c_adap, unsigned char c) | |||
167 | struct i2c_algo_bit_data *adap = i2c_adap->algo_data; | 166 | struct i2c_algo_bit_data *adap = i2c_adap->algo_data; |
168 | 167 | ||
169 | /* assert: scl is low */ | 168 | /* assert: scl is low */ |
170 | for ( i=7 ; i>=0 ; i-- ) { | 169 | for (i = 7; i >= 0; i--) { |
171 | sb = (c >> i) & 1; | 170 | sb = (c >> i) & 1; |
172 | setsda(adap,sb); | 171 | setsda(adap, sb); |
173 | udelay((adap->udelay + 1) / 2); | 172 | udelay((adap->udelay + 1) / 2); |
174 | if (sclhi(adap)<0) { /* timed out */ | 173 | if (sclhi(adap) < 0) { /* timed out */ |
175 | bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, " | 174 | bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, " |
176 | "timeout at bit #%d\n", (int)c, i); | 175 | "timeout at bit #%d\n", (int)c, i); |
177 | return -ETIMEDOUT; | 176 | return -ETIMEDOUT; |
178 | }; | 177 | } |
179 | /* do arbitration here: | 178 | /* FIXME do arbitration here: |
180 | * if ( sb && ! getsda(adap) ) -> ouch! Get out of here. | 179 | * if (sb && !getsda(adap)) -> ouch! Get out of here. |
180 | * | ||
181 | * Report a unique code, so higher level code can retry | ||
182 | * the whole (combined) message and *NOT* issue STOP. | ||
181 | */ | 183 | */ |
182 | scllo(adap); | 184 | scllo(adap); |
183 | } | 185 | } |
184 | sdahi(adap); | 186 | sdahi(adap); |
185 | if (sclhi(adap)<0){ /* timeout */ | 187 | if (sclhi(adap) < 0) { /* timeout */ |
186 | bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, " | 188 | bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, " |
187 | "timeout at ack\n", (int)c); | 189 | "timeout at ack\n", (int)c); |
188 | return -ETIMEDOUT; | 190 | return -ETIMEDOUT; |
189 | }; | 191 | } |
190 | /* read ack: SDA should be pulled down by slave */ | 192 | |
193 | /* read ack: SDA should be pulled down by slave, or it may | ||
194 | * NAK (usually to report problems with the data we wrote). | ||
195 | */ | ||
191 | ack = !getsda(adap); /* ack: sda is pulled low -> success */ | 196 | ack = !getsda(adap); /* ack: sda is pulled low -> success */ |
192 | bit_dbg(2, &i2c_adap->dev, "i2c_outb: 0x%02x %s\n", (int)c, | 197 | bit_dbg(2, &i2c_adap->dev, "i2c_outb: 0x%02x %s\n", (int)c, |
193 | ack ? "A" : "NA"); | 198 | ack ? "A" : "NA"); |
@@ -198,24 +203,24 @@ static int i2c_outb(struct i2c_adapter *i2c_adap, unsigned char c) | |||
198 | } | 203 | } |
199 | 204 | ||
200 | 205 | ||
201 | static int i2c_inb(struct i2c_adapter *i2c_adap) | 206 | static int i2c_inb(struct i2c_adapter *i2c_adap) |
202 | { | 207 | { |
203 | /* read byte via i2c port, without start/stop sequence */ | 208 | /* read byte via i2c port, without start/stop sequence */ |
204 | /* acknowledge is sent in i2c_read. */ | 209 | /* acknowledge is sent in i2c_read. */ |
205 | int i; | 210 | int i; |
206 | unsigned char indata=0; | 211 | unsigned char indata = 0; |
207 | struct i2c_algo_bit_data *adap = i2c_adap->algo_data; | 212 | struct i2c_algo_bit_data *adap = i2c_adap->algo_data; |
208 | 213 | ||
209 | /* assert: scl is low */ | 214 | /* assert: scl is low */ |
210 | sdahi(adap); | 215 | sdahi(adap); |
211 | for (i=0;i<8;i++) { | 216 | for (i = 0; i < 8; i++) { |
212 | if (sclhi(adap)<0) { /* timeout */ | 217 | if (sclhi(adap) < 0) { /* timeout */ |
213 | bit_dbg(1, &i2c_adap->dev, "i2c_inb: timeout at bit " | 218 | bit_dbg(1, &i2c_adap->dev, "i2c_inb: timeout at bit " |
214 | "#%d\n", 7 - i); | 219 | "#%d\n", 7 - i); |
215 | return -ETIMEDOUT; | 220 | return -ETIMEDOUT; |
216 | }; | 221 | } |
217 | indata *= 2; | 222 | indata *= 2; |
218 | if ( getsda(adap) ) | 223 | if (getsda(adap)) |
219 | indata |= 0x01; | 224 | indata |= 0x01; |
220 | setscl(adap, 0); | 225 | setscl(adap, 0); |
221 | udelay(i == 7 ? adap->udelay / 2 : adap->udelay); | 226 | udelay(i == 7 ? adap->udelay / 2 : adap->udelay); |
@@ -228,66 +233,67 @@ static int i2c_inb(struct i2c_adapter *i2c_adap) | |||
228 | * Sanity check for the adapter hardware - check the reaction of | 233 | * Sanity check for the adapter hardware - check the reaction of |
229 | * the bus lines only if it seems to be idle. | 234 | * the bus lines only if it seems to be idle. |
230 | */ | 235 | */ |
231 | static int test_bus(struct i2c_algo_bit_data *adap, char* name) { | 236 | static int test_bus(struct i2c_algo_bit_data *adap, char *name) |
232 | int scl,sda; | 237 | { |
238 | int scl, sda; | ||
233 | 239 | ||
234 | if (adap->getscl==NULL) | 240 | if (adap->getscl == NULL) |
235 | pr_info("%s: Testing SDA only, SCL is not readable\n", name); | 241 | pr_info("%s: Testing SDA only, SCL is not readable\n", name); |
236 | 242 | ||
237 | sda=getsda(adap); | 243 | sda = getsda(adap); |
238 | scl=(adap->getscl==NULL?1:getscl(adap)); | 244 | scl = (adap->getscl == NULL) ? 1 : getscl(adap); |
239 | if (!scl || !sda ) { | 245 | if (!scl || !sda) { |
240 | printk(KERN_WARNING "%s: bus seems to be busy\n", name); | 246 | printk(KERN_WARNING "%s: bus seems to be busy\n", name); |
241 | goto bailout; | 247 | goto bailout; |
242 | } | 248 | } |
243 | 249 | ||
244 | sdalo(adap); | 250 | sdalo(adap); |
245 | sda=getsda(adap); | 251 | sda = getsda(adap); |
246 | scl=(adap->getscl==NULL?1:getscl(adap)); | 252 | scl = (adap->getscl == NULL) ? 1 : getscl(adap); |
247 | if ( 0 != sda ) { | 253 | if (sda) { |
248 | printk(KERN_WARNING "%s: SDA stuck high!\n", name); | 254 | printk(KERN_WARNING "%s: SDA stuck high!\n", name); |
249 | goto bailout; | 255 | goto bailout; |
250 | } | 256 | } |
251 | if ( 0 == scl ) { | 257 | if (!scl) { |
252 | printk(KERN_WARNING "%s: SCL unexpected low " | 258 | printk(KERN_WARNING "%s: SCL unexpected low " |
253 | "while pulling SDA low!\n", name); | 259 | "while pulling SDA low!\n", name); |
254 | goto bailout; | 260 | goto bailout; |
255 | } | 261 | } |
256 | 262 | ||
257 | sdahi(adap); | 263 | sdahi(adap); |
258 | sda=getsda(adap); | 264 | sda = getsda(adap); |
259 | scl=(adap->getscl==NULL?1:getscl(adap)); | 265 | scl = (adap->getscl == NULL) ? 1 : getscl(adap); |
260 | if ( 0 == sda ) { | 266 | if (!sda) { |
261 | printk(KERN_WARNING "%s: SDA stuck low!\n", name); | 267 | printk(KERN_WARNING "%s: SDA stuck low!\n", name); |
262 | goto bailout; | 268 | goto bailout; |
263 | } | 269 | } |
264 | if ( 0 == scl ) { | 270 | if (!scl) { |
265 | printk(KERN_WARNING "%s: SCL unexpected low " | 271 | printk(KERN_WARNING "%s: SCL unexpected low " |
266 | "while pulling SDA high!\n", name); | 272 | "while pulling SDA high!\n", name); |
267 | goto bailout; | 273 | goto bailout; |
268 | } | 274 | } |
269 | 275 | ||
270 | scllo(adap); | 276 | scllo(adap); |
271 | sda=getsda(adap); | 277 | sda = getsda(adap); |
272 | scl=(adap->getscl==NULL?0:getscl(adap)); | 278 | scl = (adap->getscl == NULL) ? 0 : getscl(adap); |
273 | if ( 0 != scl ) { | 279 | if (scl) { |
274 | printk(KERN_WARNING "%s: SCL stuck high!\n", name); | 280 | printk(KERN_WARNING "%s: SCL stuck high!\n", name); |
275 | goto bailout; | 281 | goto bailout; |
276 | } | 282 | } |
277 | if ( 0 == sda ) { | 283 | if (!sda) { |
278 | printk(KERN_WARNING "%s: SDA unexpected low " | 284 | printk(KERN_WARNING "%s: SDA unexpected low " |
279 | "while pulling SCL low!\n", name); | 285 | "while pulling SCL low!\n", name); |
280 | goto bailout; | 286 | goto bailout; |
281 | } | 287 | } |
282 | 288 | ||
283 | sclhi(adap); | 289 | sclhi(adap); |
284 | sda=getsda(adap); | 290 | sda = getsda(adap); |
285 | scl=(adap->getscl==NULL?1:getscl(adap)); | 291 | scl = (adap->getscl == NULL) ? 1 : getscl(adap); |
286 | if ( 0 == scl ) { | 292 | if (!scl) { |
287 | printk(KERN_WARNING "%s: SCL stuck low!\n", name); | 293 | printk(KERN_WARNING "%s: SCL stuck low!\n", name); |
288 | goto bailout; | 294 | goto bailout; |
289 | } | 295 | } |
290 | if ( 0 == sda ) { | 296 | if (!sda) { |
291 | printk(KERN_WARNING "%s: SDA unexpected low " | 297 | printk(KERN_WARNING "%s: SDA unexpected low " |
292 | "while pulling SCL high!\n", name); | 298 | "while pulling SCL high!\n", name); |
293 | goto bailout; | 299 | goto bailout; |
@@ -314,9 +320,10 @@ static int try_address(struct i2c_adapter *i2c_adap, | |||
314 | unsigned char addr, int retries) | 320 | unsigned char addr, int retries) |
315 | { | 321 | { |
316 | struct i2c_algo_bit_data *adap = i2c_adap->algo_data; | 322 | struct i2c_algo_bit_data *adap = i2c_adap->algo_data; |
317 | int i,ret = -1; | 323 | int i, ret = -1; |
318 | for (i=0;i<=retries;i++) { | 324 | |
319 | ret = i2c_outb(i2c_adap,addr); | 325 | for (i = 0; i <= retries; i++) { |
326 | ret = i2c_outb(i2c_adap, addr); | ||
320 | if (ret == 1 || i == retries) | 327 | if (ret == 1 || i == retries) |
321 | break; | 328 | break; |
322 | bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n"); | 329 | bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n"); |
@@ -338,20 +345,38 @@ static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) | |||
338 | { | 345 | { |
339 | const unsigned char *temp = msg->buf; | 346 | const unsigned char *temp = msg->buf; |
340 | int count = msg->len; | 347 | int count = msg->len; |
341 | unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK; | 348 | unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK; |
342 | int retval; | 349 | int retval; |
343 | int wrcount=0; | 350 | int wrcount = 0; |
344 | 351 | ||
345 | while (count > 0) { | 352 | while (count > 0) { |
346 | retval = i2c_outb(i2c_adap, *temp); | 353 | retval = i2c_outb(i2c_adap, *temp); |
347 | if ((retval>0) || (nak_ok && (retval==0))) { /* ok or ignored NAK */ | 354 | |
348 | count--; | 355 | /* OK/ACK; or ignored NAK */ |
356 | if ((retval > 0) || (nak_ok && (retval == 0))) { | ||
357 | count--; | ||
349 | temp++; | 358 | temp++; |
350 | wrcount++; | 359 | wrcount++; |
351 | } else { /* arbitration or no acknowledge */ | 360 | |
352 | dev_err(&i2c_adap->dev, "sendbytes: error - bailout.\n"); | 361 | /* A slave NAKing the master means the slave didn't like |
353 | return (retval<0)? retval : -EFAULT; | 362 | * something about the data it saw. For example, maybe |
354 | /* got a better one ?? */ | 363 | * the SMBus PEC was wrong. |
364 | */ | ||
365 | } else if (retval == 0) { | ||
366 | dev_err(&i2c_adap->dev, "sendbytes: NAK bailout.\n"); | ||
367 | return -EIO; | ||
368 | |||
369 | /* Timeout; or (someday) lost arbitration | ||
370 | * | ||
371 | * FIXME Lost ARB implies retrying the transaction from | ||
372 | * the first message, after the "winning" master issues | ||
373 | * its STOP. As a rule, upper layer code has no reason | ||
374 | * to know or care about this ... it is *NOT* an error. | ||
375 | */ | ||
376 | } else { | ||
377 | dev_err(&i2c_adap->dev, "sendbytes: error %d\n", | ||
378 | retval); | ||
379 | return retval; | ||
355 | } | 380 | } |
356 | } | 381 | } |
357 | return wrcount; | 382 | return wrcount; |
@@ -376,14 +401,14 @@ static int acknak(struct i2c_adapter *i2c_adap, int is_ack) | |||
376 | static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) | 401 | static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) |
377 | { | 402 | { |
378 | int inval; | 403 | int inval; |
379 | int rdcount=0; /* counts bytes read */ | 404 | int rdcount = 0; /* counts bytes read */ |
380 | unsigned char *temp = msg->buf; | 405 | unsigned char *temp = msg->buf; |
381 | int count = msg->len; | 406 | int count = msg->len; |
382 | const unsigned flags = msg->flags; | 407 | const unsigned flags = msg->flags; |
383 | 408 | ||
384 | while (count > 0) { | 409 | while (count > 0) { |
385 | inval = i2c_inb(i2c_adap); | 410 | inval = i2c_inb(i2c_adap); |
386 | if (inval>=0) { | 411 | if (inval >= 0) { |
387 | *temp = inval; | 412 | *temp = inval; |
388 | rdcount++; | 413 | rdcount++; |
389 | } else { /* read timed out */ | 414 | } else { /* read timed out */ |
@@ -431,7 +456,7 @@ static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) | |||
431 | * returns: | 456 | * returns: |
432 | * 0 everything went okay, the chip ack'ed, or IGNORE_NAK flag was set | 457 | * 0 everything went okay, the chip ack'ed, or IGNORE_NAK flag was set |
433 | * -x an error occurred (like: -EREMOTEIO if the device did not answer, or | 458 | * -x an error occurred (like: -EREMOTEIO if the device did not answer, or |
434 | * -ETIMEDOUT, for example if the lines are stuck...) | 459 | * -ETIMEDOUT, for example if the lines are stuck...) |
435 | */ | 460 | */ |
436 | static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) | 461 | static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) |
437 | { | 462 | { |
@@ -443,10 +468,10 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) | |||
443 | int ret, retries; | 468 | int ret, retries; |
444 | 469 | ||
445 | retries = nak_ok ? 0 : i2c_adap->retries; | 470 | retries = nak_ok ? 0 : i2c_adap->retries; |
446 | 471 | ||
447 | if ( (flags & I2C_M_TEN) ) { | 472 | if (flags & I2C_M_TEN) { |
448 | /* a ten bit address */ | 473 | /* a ten bit address */ |
449 | addr = 0xf0 | (( msg->addr >> 7) & 0x03); | 474 | addr = 0xf0 | ((msg->addr >> 7) & 0x03); |
450 | bit_dbg(2, &i2c_adap->dev, "addr0: %d\n", addr); | 475 | bit_dbg(2, &i2c_adap->dev, "addr0: %d\n", addr); |
451 | /* try extended address code...*/ | 476 | /* try extended address code...*/ |
452 | ret = try_address(i2c_adap, addr, retries); | 477 | ret = try_address(i2c_adap, addr, retries); |
@@ -456,33 +481,33 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) | |||
456 | return -EREMOTEIO; | 481 | return -EREMOTEIO; |
457 | } | 482 | } |
458 | /* the remaining 8 bit address */ | 483 | /* the remaining 8 bit address */ |
459 | ret = i2c_outb(i2c_adap,msg->addr & 0x7f); | 484 | ret = i2c_outb(i2c_adap, msg->addr & 0x7f); |
460 | if ((ret != 1) && !nak_ok) { | 485 | if ((ret != 1) && !nak_ok) { |
461 | /* the chip did not ack / xmission error occurred */ | 486 | /* the chip did not ack / xmission error occurred */ |
462 | dev_err(&i2c_adap->dev, "died at 2nd address code\n"); | 487 | dev_err(&i2c_adap->dev, "died at 2nd address code\n"); |
463 | return -EREMOTEIO; | 488 | return -EREMOTEIO; |
464 | } | 489 | } |
465 | if ( flags & I2C_M_RD ) { | 490 | if (flags & I2C_M_RD) { |
466 | bit_dbg(3, &i2c_adap->dev, "emitting repeated " | 491 | bit_dbg(3, &i2c_adap->dev, "emitting repeated " |
467 | "start condition\n"); | 492 | "start condition\n"); |
468 | i2c_repstart(adap); | 493 | i2c_repstart(adap); |
469 | /* okay, now switch into reading mode */ | 494 | /* okay, now switch into reading mode */ |
470 | addr |= 0x01; | 495 | addr |= 0x01; |
471 | ret = try_address(i2c_adap, addr, retries); | 496 | ret = try_address(i2c_adap, addr, retries); |
472 | if ((ret!=1) && !nak_ok) { | 497 | if ((ret != 1) && !nak_ok) { |
473 | dev_err(&i2c_adap->dev, | 498 | dev_err(&i2c_adap->dev, |
474 | "died at repeated address code\n"); | 499 | "died at repeated address code\n"); |
475 | return -EREMOTEIO; | 500 | return -EREMOTEIO; |
476 | } | 501 | } |
477 | } | 502 | } |
478 | } else { /* normal 7bit address */ | 503 | } else { /* normal 7bit address */ |
479 | addr = ( msg->addr << 1 ); | 504 | addr = msg->addr << 1; |
480 | if (flags & I2C_M_RD ) | 505 | if (flags & I2C_M_RD) |
481 | addr |= 1; | 506 | addr |= 1; |
482 | if (flags & I2C_M_REV_DIR_ADDR ) | 507 | if (flags & I2C_M_REV_DIR_ADDR) |
483 | addr ^= 1; | 508 | addr ^= 1; |
484 | ret = try_address(i2c_adap, addr, retries); | 509 | ret = try_address(i2c_adap, addr, retries); |
485 | if ((ret!=1) && !nak_ok) | 510 | if ((ret != 1) && !nak_ok) |
486 | return -EREMOTEIO; | 511 | return -EREMOTEIO; |
487 | } | 512 | } |
488 | 513 | ||
@@ -494,15 +519,14 @@ static int bit_xfer(struct i2c_adapter *i2c_adap, | |||
494 | { | 519 | { |
495 | struct i2c_msg *pmsg; | 520 | struct i2c_msg *pmsg; |
496 | struct i2c_algo_bit_data *adap = i2c_adap->algo_data; | 521 | struct i2c_algo_bit_data *adap = i2c_adap->algo_data; |
497 | 522 | int i, ret; | |
498 | int i,ret; | ||
499 | unsigned short nak_ok; | 523 | unsigned short nak_ok; |
500 | 524 | ||
501 | bit_dbg(3, &i2c_adap->dev, "emitting start condition\n"); | 525 | bit_dbg(3, &i2c_adap->dev, "emitting start condition\n"); |
502 | i2c_start(adap); | 526 | i2c_start(adap); |
503 | for (i=0;i<num;i++) { | 527 | for (i = 0; i < num; i++) { |
504 | pmsg = &msgs[i]; | 528 | pmsg = &msgs[i]; |
505 | nak_ok = pmsg->flags & I2C_M_IGNORE_NAK; | 529 | nak_ok = pmsg->flags & I2C_M_IGNORE_NAK; |
506 | if (!(pmsg->flags & I2C_M_NOSTART)) { | 530 | if (!(pmsg->flags & I2C_M_NOSTART)) { |
507 | if (i) { | 531 | if (i) { |
508 | bit_dbg(3, &i2c_adap->dev, "emitting " | 532 | bit_dbg(3, &i2c_adap->dev, "emitting " |
@@ -517,7 +541,7 @@ static int bit_xfer(struct i2c_adapter *i2c_adap, | |||
517 | goto bailout; | 541 | goto bailout; |
518 | } | 542 | } |
519 | } | 543 | } |
520 | if (pmsg->flags & I2C_M_RD ) { | 544 | if (pmsg->flags & I2C_M_RD) { |
521 | /* read bytes into buffer*/ | 545 | /* read bytes into buffer*/ |
522 | ret = readbytes(i2c_adap, pmsg); | 546 | ret = readbytes(i2c_adap, pmsg); |
523 | if (ret >= 1) | 547 | if (ret >= 1) |
@@ -551,7 +575,7 @@ bailout: | |||
551 | 575 | ||
552 | static u32 bit_func(struct i2c_adapter *adap) | 576 | static u32 bit_func(struct i2c_adapter *adap) |
553 | { | 577 | { |
554 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | | 578 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | |
555 | I2C_FUNC_SMBUS_READ_BLOCK_DATA | | 579 | I2C_FUNC_SMBUS_READ_BLOCK_DATA | |
556 | I2C_FUNC_SMBUS_BLOCK_PROC_CALL | | 580 | I2C_FUNC_SMBUS_BLOCK_PROC_CALL | |
557 | I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING; | 581 | I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING; |
@@ -565,8 +589,8 @@ static const struct i2c_algorithm i2c_bit_algo = { | |||
565 | .functionality = bit_func, | 589 | .functionality = bit_func, |
566 | }; | 590 | }; |
567 | 591 | ||
568 | /* | 592 | /* |
569 | * registering functions to load algorithms at runtime | 593 | * registering functions to load algorithms at runtime |
570 | */ | 594 | */ |
571 | static int i2c_bit_prepare_bus(struct i2c_adapter *adap) | 595 | static int i2c_bit_prepare_bus(struct i2c_adapter *adap) |
572 | { | 596 | { |
@@ -574,7 +598,7 @@ static int i2c_bit_prepare_bus(struct i2c_adapter *adap) | |||
574 | 598 | ||
575 | if (bit_test) { | 599 | if (bit_test) { |
576 | int ret = test_bus(bit_adap, adap->name); | 600 | int ret = test_bus(bit_adap, adap->name); |
577 | if (ret<0) | 601 | if (ret < 0) |
578 | return -ENODEV; | 602 | return -ENODEV; |
579 | } | 603 | } |
580 | 604 | ||
diff --git a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c index ab2e6f3498b4..8907b0191677 100644 --- a/drivers/i2c/algos/i2c-algo-pcf.c +++ b/drivers/i2c/algos/i2c-algo-pcf.c | |||
@@ -203,35 +203,6 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap) | |||
203 | /* ----- Utility functions | 203 | /* ----- Utility functions |
204 | */ | 204 | */ |
205 | 205 | ||
206 | static inline int try_address(struct i2c_algo_pcf_data *adap, | ||
207 | unsigned char addr, int retries) | ||
208 | { | ||
209 | int i, status, ret = -1; | ||
210 | int wfp; | ||
211 | for (i=0;i<retries;i++) { | ||
212 | i2c_outb(adap, addr); | ||
213 | i2c_start(adap); | ||
214 | status = get_pcf(adap, 1); | ||
215 | if ((wfp = wait_for_pin(adap, &status)) >= 0) { | ||
216 | if ((status & I2C_PCF_LRB) == 0) { | ||
217 | i2c_stop(adap); | ||
218 | break; /* success! */ | ||
219 | } | ||
220 | } | ||
221 | if (wfp == -EINTR) { | ||
222 | /* arbitration lost */ | ||
223 | udelay(adap->udelay); | ||
224 | return -EINTR; | ||
225 | } | ||
226 | i2c_stop(adap); | ||
227 | udelay(adap->udelay); | ||
228 | } | ||
229 | DEB2(if (i) printk(KERN_DEBUG "i2c-algo-pcf.o: needed %d retries for %d\n",i, | ||
230 | addr)); | ||
231 | return ret; | ||
232 | } | ||
233 | |||
234 | |||
235 | static int pcf_sendbytes(struct i2c_adapter *i2c_adap, const char *buf, | 206 | static int pcf_sendbytes(struct i2c_adapter *i2c_adap, const char *buf, |
236 | int count, int last) | 207 | int count, int last) |
237 | { | 208 | { |
@@ -321,47 +292,19 @@ static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf, | |||
321 | } | 292 | } |
322 | 293 | ||
323 | 294 | ||
324 | static inline int pcf_doAddress(struct i2c_algo_pcf_data *adap, | 295 | static int pcf_doAddress(struct i2c_algo_pcf_data *adap, |
325 | struct i2c_msg *msg, int retries) | 296 | struct i2c_msg *msg) |
326 | { | 297 | { |
327 | unsigned short flags = msg->flags; | 298 | unsigned short flags = msg->flags; |
328 | unsigned char addr; | 299 | unsigned char addr; |
329 | int ret; | 300 | |
330 | if ( (flags & I2C_M_TEN) ) { | 301 | addr = msg->addr << 1; |
331 | /* a ten bit address */ | 302 | if (flags & I2C_M_RD) |
332 | addr = 0xf0 | (( msg->addr >> 7) & 0x03); | 303 | addr |= 1; |
333 | DEB2(printk(KERN_DEBUG "addr0: %d\n",addr)); | 304 | if (flags & I2C_M_REV_DIR_ADDR) |
334 | /* try extended address code...*/ | 305 | addr ^= 1; |
335 | ret = try_address(adap, addr, retries); | 306 | i2c_outb(adap, addr); |
336 | if (ret!=1) { | 307 | |
337 | printk(KERN_ERR "died at extended address code.\n"); | ||
338 | return -EREMOTEIO; | ||
339 | } | ||
340 | /* the remaining 8 bit address */ | ||
341 | i2c_outb(adap,msg->addr & 0x7f); | ||
342 | /* Status check comes here */ | ||
343 | if (ret != 1) { | ||
344 | printk(KERN_ERR "died at 2nd address code.\n"); | ||
345 | return -EREMOTEIO; | ||
346 | } | ||
347 | if ( flags & I2C_M_RD ) { | ||
348 | i2c_repstart(adap); | ||
349 | /* okay, now switch into reading mode */ | ||
350 | addr |= 0x01; | ||
351 | ret = try_address(adap, addr, retries); | ||
352 | if (ret!=1) { | ||
353 | printk(KERN_ERR "died at extended address code.\n"); | ||
354 | return -EREMOTEIO; | ||
355 | } | ||
356 | } | ||
357 | } else { /* normal 7bit address */ | ||
358 | addr = ( msg->addr << 1 ); | ||
359 | if (flags & I2C_M_RD ) | ||
360 | addr |= 1; | ||
361 | if (flags & I2C_M_REV_DIR_ADDR ) | ||
362 | addr ^= 1; | ||
363 | i2c_outb(adap, addr); | ||
364 | } | ||
365 | return 0; | 308 | return 0; |
366 | } | 309 | } |
367 | 310 | ||
@@ -390,7 +333,7 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap, | |||
390 | pmsg->flags & I2C_M_RD ? "read" : "write", | 333 | pmsg->flags & I2C_M_RD ? "read" : "write", |
391 | pmsg->len, pmsg->addr, i + 1, num);) | 334 | pmsg->len, pmsg->addr, i + 1, num);) |
392 | 335 | ||
393 | ret = pcf_doAddress(adap, pmsg, i2c_adap->retries); | 336 | ret = pcf_doAddress(adap, pmsg); |
394 | 337 | ||
395 | /* Send START */ | 338 | /* Send START */ |
396 | if (i == 0) { | 339 | if (i == 0) { |
@@ -453,7 +396,7 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap, | |||
453 | static u32 pcf_func(struct i2c_adapter *adap) | 396 | static u32 pcf_func(struct i2c_adapter *adap) |
454 | { | 397 | { |
455 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | | 398 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | |
456 | I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING; | 399 | I2C_FUNC_PROTOCOL_MANGLING; |
457 | } | 400 | } |
458 | 401 | ||
459 | /* -----exported algorithm data: ------------------------------------- */ | 402 | /* -----exported algorithm data: ------------------------------------- */ |
@@ -475,9 +418,7 @@ int i2c_pcf_add_bus(struct i2c_adapter *adap) | |||
475 | 418 | ||
476 | /* register new adapter to i2c module... */ | 419 | /* register new adapter to i2c module... */ |
477 | adap->algo = &pcf_algo; | 420 | adap->algo = &pcf_algo; |
478 | 421 | adap->timeout = 100; | |
479 | adap->timeout = 100; /* default values, should */ | ||
480 | adap->retries = 3; /* be replaced by defines */ | ||
481 | 422 | ||
482 | if ((rval = pcf_init_8584(pcf_adap))) | 423 | if ((rval = pcf_init_8584(pcf_adap))) |
483 | return rval; | 424 | return rval; |
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index c466c6cfc2e5..8d12b26bb6c6 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
@@ -182,7 +182,8 @@ config I2C_I801 | |||
182 | will be called i2c-i801. | 182 | will be called i2c-i801. |
183 | 183 | ||
184 | config I2C_I810 | 184 | config I2C_I810 |
185 | tristate "Intel 810/815" | 185 | tristate "Intel 810/815 (DEPRECATED)" |
186 | default n | ||
186 | depends on PCI | 187 | depends on PCI |
187 | select I2C_ALGOBIT | 188 | select I2C_ALGOBIT |
188 | help | 189 | help |
@@ -195,6 +196,8 @@ config I2C_I810 | |||
195 | i815 | 196 | i815 |
196 | i845G | 197 | i845G |
197 | 198 | ||
199 | This driver is deprecated in favor of the i810fb and intelfb drivers. | ||
200 | |||
198 | This driver can also be built as a module. If so, the module | 201 | This driver can also be built as a module. If so, the module |
199 | will be called i2c-i810. | 202 | will be called i2c-i810. |
200 | 203 | ||
@@ -259,20 +262,6 @@ config I2C_IOP3XX | |||
259 | This driver can also be built as a module. If so, the module | 262 | This driver can also be built as a module. If so, the module |
260 | will be called i2c-iop3xx. | 263 | will be called i2c-iop3xx. |
261 | 264 | ||
262 | config I2C_IXP4XX | ||
263 | tristate "IXP4xx GPIO-Based I2C Interface (DEPRECATED)" | ||
264 | depends on ARCH_IXP4XX | ||
265 | select I2C_ALGOBIT | ||
266 | help | ||
267 | Say Y here if you have an Intel IXP4xx(420,421,422,425) based | ||
268 | system and are using GPIO lines for an I2C bus. | ||
269 | |||
270 | This support is also available as a module. If so, the module | ||
271 | will be called i2c-ixp4xx. | ||
272 | |||
273 | This driver is deprecated and will be dropped soon. Use i2c-gpio | ||
274 | instead. | ||
275 | |||
276 | config I2C_IXP2000 | 265 | config I2C_IXP2000 |
277 | tristate "IXP2000 GPIO-Based I2C Interface (DEPRECATED)" | 266 | tristate "IXP2000 GPIO-Based I2C Interface (DEPRECATED)" |
278 | depends on ARCH_IXP2000 | 267 | depends on ARCH_IXP2000 |
@@ -396,7 +385,8 @@ config I2C_PASEMI | |||
396 | Supports the PA Semi PWRficient on-chip SMBus interfaces. | 385 | Supports the PA Semi PWRficient on-chip SMBus interfaces. |
397 | 386 | ||
398 | config I2C_PROSAVAGE | 387 | config I2C_PROSAVAGE |
399 | tristate "S3/VIA (Pro)Savage" | 388 | tristate "S3/VIA (Pro)Savage (DEPRECATED)" |
389 | default n | ||
400 | depends on PCI | 390 | depends on PCI |
401 | select I2C_ALGOBIT | 391 | select I2C_ALGOBIT |
402 | help | 392 | help |
@@ -407,6 +397,8 @@ config I2C_PROSAVAGE | |||
407 | S3/VIA KM266/VT8375 aka ProSavage8 | 397 | S3/VIA KM266/VT8375 aka ProSavage8 |
408 | S3/VIA KM133/VT8365 aka Savage4 | 398 | S3/VIA KM133/VT8365 aka Savage4 |
409 | 399 | ||
400 | This driver is deprecated in favor of the savagefb driver. | ||
401 | |||
410 | This support is also available as a module. If so, the module | 402 | This support is also available as a module. If so, the module |
411 | will be called i2c-prosavage. | 403 | will be called i2c-prosavage. |
412 | 404 | ||
@@ -418,13 +410,16 @@ config I2C_S3C2410 | |||
418 | Samsung S3C2410 based System-on-Chip devices. | 410 | Samsung S3C2410 based System-on-Chip devices. |
419 | 411 | ||
420 | config I2C_SAVAGE4 | 412 | config I2C_SAVAGE4 |
421 | tristate "S3 Savage 4" | 413 | tristate "S3 Savage 4 (DEPRECATED)" |
422 | depends on PCI && EXPERIMENTAL | 414 | default n |
415 | depends on PCI | ||
423 | select I2C_ALGOBIT | 416 | select I2C_ALGOBIT |
424 | help | 417 | help |
425 | If you say yes to this option, support will be included for the | 418 | If you say yes to this option, support will be included for the |
426 | S3 Savage 4 I2C interface. | 419 | S3 Savage 4 I2C interface. |
427 | 420 | ||
421 | This driver is deprecated in favor of the savagefb driver. | ||
422 | |||
428 | This driver can also be built as a module. If so, the module | 423 | This driver can also be built as a module. If so, the module |
429 | will be called i2c-savage4. | 424 | will be called i2c-savage4. |
430 | 425 | ||
@@ -611,7 +606,7 @@ config I2C_VIAPRO | |||
611 | VT8231 | 606 | VT8231 |
612 | VT8233/A | 607 | VT8233/A |
613 | VT8235 | 608 | VT8235 |
614 | VT8237R/A | 609 | VT8237R/A/S |
615 | VT8251 | 610 | VT8251 |
616 | CX700 | 611 | CX700 |
617 | 612 | ||
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 81d43c27cf93..ea7068f1eb6b 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile | |||
@@ -20,7 +20,6 @@ obj-$(CONFIG_I2C_I810) += i2c-i810.o | |||
20 | obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o | 20 | obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o |
21 | obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o | 21 | obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o |
22 | obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o | 22 | obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o |
23 | obj-$(CONFIG_I2C_IXP4XX) += i2c-ixp4xx.o | ||
24 | obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o | 23 | obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o |
25 | obj-$(CONFIG_I2C_MPC) += i2c-mpc.o | 24 | obj-$(CONFIG_I2C_MPC) += i2c-mpc.o |
26 | obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o | 25 | obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o |
diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c index 7490dc1771ae..573abe440842 100644 --- a/drivers/i2c/busses/i2c-amd756.c +++ b/drivers/i2c/busses/i2c-amd756.c | |||
@@ -334,6 +334,10 @@ static int __devinit amd756_probe(struct pci_dev *pdev, | |||
334 | int error; | 334 | int error; |
335 | u8 temp; | 335 | u8 temp; |
336 | 336 | ||
337 | /* driver_data might come from user-space, so check it */ | ||
338 | if (id->driver_data > ARRAY_SIZE(chipname)) | ||
339 | return -EINVAL; | ||
340 | |||
337 | if (amd756_ioport) { | 341 | if (amd756_ioport) { |
338 | dev_err(&pdev->dev, "Only one device supported " | 342 | dev_err(&pdev->dev, "Only one device supported " |
339 | "(you have a strange motherboard, btw)\n"); | 343 | "(you have a strange motherboard, btw)\n"); |
@@ -405,6 +409,7 @@ static struct pci_driver amd756_driver = { | |||
405 | .id_table = amd756_ids, | 409 | .id_table = amd756_ids, |
406 | .probe = amd756_probe, | 410 | .probe = amd756_probe, |
407 | .remove = __devexit_p(amd756_remove), | 411 | .remove = __devexit_p(amd756_remove), |
412 | .dynids.use_driver_data = 1, | ||
408 | }; | 413 | }; |
409 | 414 | ||
410 | static int __init amd756_init(void) | 415 | static int __init amd756_init(void) |
diff --git a/drivers/i2c/busses/i2c-au1550.c b/drivers/i2c/busses/i2c-au1550.c index 2f684166c43d..1953b26da56a 100644 --- a/drivers/i2c/busses/i2c-au1550.c +++ b/drivers/i2c/busses/i2c-au1550.c | |||
@@ -30,14 +30,22 @@ | |||
30 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
33 | #include <linux/platform_device.h> | ||
33 | #include <linux/init.h> | 34 | #include <linux/init.h> |
34 | #include <linux/errno.h> | 35 | #include <linux/errno.h> |
35 | #include <linux/i2c.h> | 36 | #include <linux/i2c.h> |
37 | #include <linux/slab.h> | ||
36 | 38 | ||
37 | #include <asm/mach-au1x00/au1xxx.h> | 39 | #include <asm/mach-au1x00/au1xxx.h> |
38 | #include <asm/mach-au1x00/au1xxx_psc.h> | 40 | #include <asm/mach-au1x00/au1xxx_psc.h> |
39 | 41 | ||
40 | #include "i2c-au1550.h" | 42 | struct i2c_au1550_data { |
43 | u32 psc_base; | ||
44 | int xfer_timeout; | ||
45 | int ack_timeout; | ||
46 | struct i2c_adapter adap; | ||
47 | struct resource *ioarea; | ||
48 | }; | ||
41 | 49 | ||
42 | static int | 50 | static int |
43 | wait_xfer_done(struct i2c_au1550_data *adap) | 51 | wait_xfer_done(struct i2c_au1550_data *adap) |
@@ -105,7 +113,7 @@ wait_master_done(struct i2c_au1550_data *adap) | |||
105 | } | 113 | } |
106 | 114 | ||
107 | static int | 115 | static int |
108 | do_address(struct i2c_au1550_data *adap, unsigned int addr, int rd) | 116 | do_address(struct i2c_au1550_data *adap, unsigned int addr, int rd, int q) |
109 | { | 117 | { |
110 | volatile psc_smb_t *sp; | 118 | volatile psc_smb_t *sp; |
111 | u32 stat; | 119 | u32 stat; |
@@ -134,6 +142,10 @@ do_address(struct i2c_au1550_data *adap, unsigned int addr, int rd) | |||
134 | if (rd) | 142 | if (rd) |
135 | addr |= 1; | 143 | addr |= 1; |
136 | 144 | ||
145 | /* zero-byte xfers stop immediately */ | ||
146 | if (q) | ||
147 | addr |= PSC_SMBTXRX_STP; | ||
148 | |||
137 | /* Put byte into fifo, start up master. | 149 | /* Put byte into fifo, start up master. |
138 | */ | 150 | */ |
139 | sp->psc_smbtxrx = addr; | 151 | sp->psc_smbtxrx = addr; |
@@ -142,7 +154,7 @@ do_address(struct i2c_au1550_data *adap, unsigned int addr, int rd) | |||
142 | au_sync(); | 154 | au_sync(); |
143 | if (wait_ack(adap)) | 155 | if (wait_ack(adap)) |
144 | return -EIO; | 156 | return -EIO; |
145 | return 0; | 157 | return (q) ? wait_master_done(adap) : 0; |
146 | } | 158 | } |
147 | 159 | ||
148 | static u32 | 160 | static u32 |
@@ -262,7 +274,8 @@ au1550_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) | |||
262 | 274 | ||
263 | for (i = 0; !err && i < num; i++) { | 275 | for (i = 0; !err && i < num; i++) { |
264 | p = &msgs[i]; | 276 | p = &msgs[i]; |
265 | err = do_address(adap, p->addr, p->flags & I2C_M_RD); | 277 | err = do_address(adap, p->addr, p->flags & I2C_M_RD, |
278 | (p->len == 0)); | ||
266 | if (err || !p->len) | 279 | if (err || !p->len) |
267 | continue; | 280 | continue; |
268 | if (p->flags & I2C_M_RD) | 281 | if (p->flags & I2C_M_RD) |
@@ -294,18 +307,48 @@ static const struct i2c_algorithm au1550_algo = { | |||
294 | * Prior to calling us, the 50MHz clock frequency and routing | 307 | * Prior to calling us, the 50MHz clock frequency and routing |
295 | * must have been set up for the PSC indicated by the adapter. | 308 | * must have been set up for the PSC indicated by the adapter. |
296 | */ | 309 | */ |
297 | int | 310 | static int __devinit |
298 | i2c_au1550_add_bus(struct i2c_adapter *i2c_adap) | 311 | i2c_au1550_probe(struct platform_device *pdev) |
299 | { | 312 | { |
300 | struct i2c_au1550_data *adap = i2c_adap->algo_data; | 313 | struct i2c_au1550_data *priv; |
301 | volatile psc_smb_t *sp; | 314 | volatile psc_smb_t *sp; |
302 | u32 stat; | 315 | struct resource *r; |
316 | u32 stat; | ||
317 | int ret; | ||
318 | |||
319 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
320 | if (!r) { | ||
321 | ret = -ENODEV; | ||
322 | goto out; | ||
323 | } | ||
324 | |||
325 | priv = kzalloc(sizeof(struct i2c_au1550_data), GFP_KERNEL); | ||
326 | if (!priv) { | ||
327 | ret = -ENOMEM; | ||
328 | goto out; | ||
329 | } | ||
330 | |||
331 | priv->ioarea = request_mem_region(r->start, r->end - r->start + 1, | ||
332 | pdev->name); | ||
333 | if (!priv->ioarea) { | ||
334 | ret = -EBUSY; | ||
335 | goto out_mem; | ||
336 | } | ||
303 | 337 | ||
304 | i2c_adap->algo = &au1550_algo; | 338 | priv->psc_base = r->start; |
339 | priv->xfer_timeout = 200; | ||
340 | priv->ack_timeout = 200; | ||
341 | |||
342 | priv->adap.id = I2C_HW_AU1550_PSC; | ||
343 | priv->adap.nr = pdev->id; | ||
344 | priv->adap.algo = &au1550_algo; | ||
345 | priv->adap.algo_data = priv; | ||
346 | priv->adap.dev.parent = &pdev->dev; | ||
347 | strlcpy(priv->adap.name, "Au1xxx PSC I2C", sizeof(priv->adap.name)); | ||
305 | 348 | ||
306 | /* Now, set up the PSC for SMBus PIO mode. | 349 | /* Now, set up the PSC for SMBus PIO mode. |
307 | */ | 350 | */ |
308 | sp = (volatile psc_smb_t *)(adap->psc_base); | 351 | sp = (volatile psc_smb_t *)priv->psc_base; |
309 | sp->psc_ctrl = PSC_CTRL_DISABLE; | 352 | sp->psc_ctrl = PSC_CTRL_DISABLE; |
310 | au_sync(); | 353 | au_sync(); |
311 | sp->psc_sel = PSC_SEL_PS_SMBUSMODE; | 354 | sp->psc_sel = PSC_SEL_PS_SMBUSMODE; |
@@ -343,87 +386,87 @@ i2c_au1550_add_bus(struct i2c_adapter *i2c_adap) | |||
343 | au_sync(); | 386 | au_sync(); |
344 | } while ((stat & PSC_SMBSTAT_DR) == 0); | 387 | } while ((stat & PSC_SMBSTAT_DR) == 0); |
345 | 388 | ||
346 | return i2c_add_adapter(i2c_adap); | 389 | ret = i2c_add_numbered_adapter(&priv->adap); |
347 | } | 390 | if (ret == 0) { |
391 | platform_set_drvdata(pdev, priv); | ||
392 | return 0; | ||
393 | } | ||
348 | 394 | ||
395 | /* disable the PSC */ | ||
396 | sp->psc_smbcfg = 0; | ||
397 | sp->psc_ctrl = PSC_CTRL_DISABLE; | ||
398 | au_sync(); | ||
349 | 399 | ||
350 | int | 400 | release_resource(priv->ioarea); |
351 | i2c_au1550_del_bus(struct i2c_adapter *adap) | 401 | kfree(priv->ioarea); |
402 | out_mem: | ||
403 | kfree(priv); | ||
404 | out: | ||
405 | return ret; | ||
406 | } | ||
407 | |||
408 | static int __devexit | ||
409 | i2c_au1550_remove(struct platform_device *pdev) | ||
352 | { | 410 | { |
353 | return i2c_del_adapter(adap); | 411 | struct i2c_au1550_data *priv = platform_get_drvdata(pdev); |
412 | volatile psc_smb_t *sp = (volatile psc_smb_t *)priv->psc_base; | ||
413 | |||
414 | platform_set_drvdata(pdev, NULL); | ||
415 | i2c_del_adapter(&priv->adap); | ||
416 | sp->psc_smbcfg = 0; | ||
417 | sp->psc_ctrl = PSC_CTRL_DISABLE; | ||
418 | au_sync(); | ||
419 | release_resource(priv->ioarea); | ||
420 | kfree(priv->ioarea); | ||
421 | kfree(priv); | ||
422 | return 0; | ||
354 | } | 423 | } |
355 | 424 | ||
356 | static int | 425 | static int |
357 | pb1550_reg(struct i2c_client *client) | 426 | i2c_au1550_suspend(struct platform_device *pdev, pm_message_t state) |
358 | { | 427 | { |
428 | struct i2c_au1550_data *priv = platform_get_drvdata(pdev); | ||
429 | volatile psc_smb_t *sp = (volatile psc_smb_t *)priv->psc_base; | ||
430 | |||
431 | sp->psc_ctrl = PSC_CTRL_SUSPEND; | ||
432 | au_sync(); | ||
359 | return 0; | 433 | return 0; |
360 | } | 434 | } |
361 | 435 | ||
362 | static int | 436 | static int |
363 | pb1550_unreg(struct i2c_client *client) | 437 | i2c_au1550_resume(struct platform_device *pdev) |
364 | { | 438 | { |
439 | struct i2c_au1550_data *priv = platform_get_drvdata(pdev); | ||
440 | volatile psc_smb_t *sp = (volatile psc_smb_t *)priv->psc_base; | ||
441 | |||
442 | sp->psc_ctrl = PSC_CTRL_ENABLE; | ||
443 | au_sync(); | ||
444 | while (!(sp->psc_smbstat & PSC_SMBSTAT_SR)) | ||
445 | au_sync(); | ||
365 | return 0; | 446 | return 0; |
366 | } | 447 | } |
367 | 448 | ||
368 | static struct i2c_au1550_data pb1550_i2c_info = { | 449 | static struct platform_driver au1xpsc_smbus_driver = { |
369 | SMBUS_PSC_BASE, 200, 200 | 450 | .driver = { |
370 | }; | 451 | .name = "au1xpsc_smbus", |
371 | 452 | .owner = THIS_MODULE, | |
372 | static struct i2c_adapter pb1550_board_adapter = { | 453 | }, |
373 | name: "pb1550 adapter", | 454 | .probe = i2c_au1550_probe, |
374 | id: I2C_HW_AU1550_PSC, | 455 | .remove = __devexit_p(i2c_au1550_remove), |
375 | algo: NULL, | 456 | .suspend = i2c_au1550_suspend, |
376 | algo_data: &pb1550_i2c_info, | 457 | .resume = i2c_au1550_resume, |
377 | client_register: pb1550_reg, | ||
378 | client_unregister: pb1550_unreg, | ||
379 | }; | 458 | }; |
380 | 459 | ||
381 | /* BIG hack to support the control interface on the Wolfson WM8731 | ||
382 | * audio codec on the Pb1550 board. We get an address and two data | ||
383 | * bytes to write, create an i2c message, and send it across the | ||
384 | * i2c transfer function. We do this here because we have access to | ||
385 | * the i2c adapter structure. | ||
386 | */ | ||
387 | static struct i2c_msg wm_i2c_msg; /* We don't want this stuff on the stack */ | ||
388 | static u8 i2cbuf[2]; | ||
389 | |||
390 | int | ||
391 | pb1550_wm_codec_write(u8 addr, u8 reg, u8 val) | ||
392 | { | ||
393 | wm_i2c_msg.addr = addr; | ||
394 | wm_i2c_msg.flags = 0; | ||
395 | wm_i2c_msg.buf = i2cbuf; | ||
396 | wm_i2c_msg.len = 2; | ||
397 | i2cbuf[0] = reg; | ||
398 | i2cbuf[1] = val; | ||
399 | |||
400 | return pb1550_board_adapter.algo->master_xfer(&pb1550_board_adapter, &wm_i2c_msg, 1); | ||
401 | } | ||
402 | |||
403 | static int __init | 460 | static int __init |
404 | i2c_au1550_init(void) | 461 | i2c_au1550_init(void) |
405 | { | 462 | { |
406 | printk(KERN_INFO "Au1550 I2C: "); | 463 | return platform_driver_register(&au1xpsc_smbus_driver); |
407 | |||
408 | /* This is where we would set up a 50MHz clock source | ||
409 | * and routing. On the Pb1550, the SMBus is PSC2, which | ||
410 | * uses a shared clock with USB. This has been already | ||
411 | * configured by Yamon as a 48MHz clock, close enough | ||
412 | * for our work. | ||
413 | */ | ||
414 | if (i2c_au1550_add_bus(&pb1550_board_adapter) < 0) { | ||
415 | printk("failed to initialize.\n"); | ||
416 | return -ENODEV; | ||
417 | } | ||
418 | |||
419 | printk("initialized.\n"); | ||
420 | return 0; | ||
421 | } | 464 | } |
422 | 465 | ||
423 | static void __exit | 466 | static void __exit |
424 | i2c_au1550_exit(void) | 467 | i2c_au1550_exit(void) |
425 | { | 468 | { |
426 | i2c_au1550_del_bus(&pb1550_board_adapter); | 469 | platform_driver_unregister(&au1xpsc_smbus_driver); |
427 | } | 470 | } |
428 | 471 | ||
429 | MODULE_AUTHOR("Dan Malek, Embedded Edge, LLC."); | 472 | MODULE_AUTHOR("Dan Malek, Embedded Edge, LLC."); |
diff --git a/drivers/i2c/busses/i2c-au1550.h b/drivers/i2c/busses/i2c-au1550.h deleted file mode 100644 index fce15d161ae7..000000000000 --- a/drivers/i2c/busses/i2c-au1550.h +++ /dev/null | |||
@@ -1,32 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004 Embedded Edge, LLC <dan@embeddededge.com> | ||
3 | * 2.6 port by Matt Porter <mporter@kernel.crashing.org> | ||
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., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | */ | ||
19 | |||
20 | #ifndef I2C_AU1550_H | ||
21 | #define I2C_AU1550_H | ||
22 | |||
23 | struct i2c_au1550_data { | ||
24 | u32 psc_base; | ||
25 | int xfer_timeout; | ||
26 | int ack_timeout; | ||
27 | }; | ||
28 | |||
29 | int i2c_au1550_add_bus(struct i2c_adapter *); | ||
30 | int i2c_au1550_del_bus(struct i2c_adapter *); | ||
31 | |||
32 | #endif /* I2C_AU1550_H */ | ||
diff --git a/drivers/i2c/busses/i2c-bfin-twi.c b/drivers/i2c/busses/i2c-bfin-twi.c index 67224a424aba..7dbdaeb707a9 100644 --- a/drivers/i2c/busses/i2c-bfin-twi.c +++ b/drivers/i2c/busses/i2c-bfin-twi.c | |||
@@ -550,6 +550,7 @@ static int i2c_bfin_twi_probe(struct platform_device *dev) | |||
550 | 550 | ||
551 | p_adap = &iface->adap; | 551 | p_adap = &iface->adap; |
552 | p_adap->id = I2C_HW_BLACKFIN; | 552 | p_adap->id = I2C_HW_BLACKFIN; |
553 | p_adap->nr = dev->id; | ||
553 | strlcpy(p_adap->name, dev->name, sizeof(p_adap->name)); | 554 | strlcpy(p_adap->name, dev->name, sizeof(p_adap->name)); |
554 | p_adap->algo = &bfin_twi_algorithm; | 555 | p_adap->algo = &bfin_twi_algorithm; |
555 | p_adap->algo_data = iface; | 556 | p_adap->algo_data = iface; |
@@ -576,7 +577,7 @@ static int i2c_bfin_twi_probe(struct platform_device *dev) | |||
576 | bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() | TWI_ENA); | 577 | bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() | TWI_ENA); |
577 | SSYNC(); | 578 | SSYNC(); |
578 | 579 | ||
579 | rc = i2c_add_adapter(p_adap); | 580 | rc = i2c_add_numbered_adapter(p_adap); |
580 | if (rc < 0) | 581 | if (rc < 0) |
581 | free_irq(iface->irq, iface); | 582 | free_irq(iface->irq, iface); |
582 | else | 583 | else |
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 67679882ebef..cce5a614758d 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c | |||
@@ -510,7 +510,6 @@ static int davinci_i2c_probe(struct platform_device *pdev) | |||
510 | 510 | ||
511 | /* FIXME */ | 511 | /* FIXME */ |
512 | adap->timeout = 1; | 512 | adap->timeout = 1; |
513 | adap->retries = 1; | ||
514 | 513 | ||
515 | adap->nr = pdev->id; | 514 | adap->nr = pdev->id; |
516 | r = i2c_add_numbered_adapter(adap); | 515 | r = i2c_add_numbered_adapter(adap); |
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index ac27e5f84ebe..aa9157913b9a 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c | |||
@@ -4,6 +4,7 @@ | |||
4 | Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl>, | 4 | Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl>, |
5 | Philip Edelbrock <phil@netroedge.com>, and Mark D. Studebaker | 5 | Philip Edelbrock <phil@netroedge.com>, and Mark D. Studebaker |
6 | <mdsxyz123@yahoo.com> | 6 | <mdsxyz123@yahoo.com> |
7 | Copyright (C) 2007 Jean Delvare <khali@linux-fr.org> | ||
7 | 8 | ||
8 | 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 |
9 | 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 |
@@ -21,25 +22,34 @@ | |||
21 | */ | 22 | */ |
22 | 23 | ||
23 | /* | 24 | /* |
24 | SUPPORTED DEVICES PCI ID | 25 | Supports the following Intel I/O Controller Hubs (ICH): |
25 | 82801AA 2413 | 26 | |
26 | 82801AB 2423 | 27 | I/O Block I2C |
27 | 82801BA 2443 | 28 | region SMBus Block proc. block |
28 | 82801CA/CAM 2483 | 29 | Chip name PCI ID size PEC buffer call read |
29 | 82801DB 24C3 (HW PEC supported) | 30 | ---------------------------------------------------------------------- |
30 | 82801EB 24D3 (HW PEC supported) | 31 | 82801AA (ICH) 0x2413 16 no no no no |
31 | 6300ESB 25A4 | 32 | 82801AB (ICH0) 0x2423 16 no no no no |
32 | ICH6 266A | 33 | 82801BA (ICH2) 0x2443 16 no no no no |
33 | ICH7 27DA | 34 | 82801CA (ICH3) 0x2483 32 soft no no no |
34 | ESB2 269B | 35 | 82801DB (ICH4) 0x24c3 32 hard yes no no |
35 | ICH8 283E | 36 | 82801E (ICH5) 0x24d3 32 hard yes yes yes |
36 | ICH9 2930 | 37 | 6300ESB 0x25a4 32 hard yes yes yes |
37 | Tolapai 5032 | 38 | 82801F (ICH6) 0x266a 32 hard yes yes yes |
38 | This driver supports several versions of Intel's I/O Controller Hubs (ICH). | 39 | 6310ESB/6320ESB 0x269b 32 hard yes yes yes |
39 | For SMBus support, they are similar to the PIIX4 and are part | 40 | 82801G (ICH7) 0x27da 32 hard yes yes yes |
40 | of Intel's '810' and other chipsets. | 41 | 82801H (ICH8) 0x283e 32 hard yes yes yes |
41 | See the file Documentation/i2c/busses/i2c-i801 for details. | 42 | 82801I (ICH9) 0x2930 32 hard yes yes yes |
42 | I2C Block Read and Process Call are not supported. | 43 | Tolapai 0x5032 32 hard yes ? ? |
44 | |||
45 | Features supported by this driver: | ||
46 | Software PEC no | ||
47 | Hardware PEC yes | ||
48 | Block buffer yes | ||
49 | Block process call transaction no | ||
50 | I2C block read transaction yes (doesn't use the block buffer) | ||
51 | |||
52 | See the file Documentation/i2c/busses/i2c-i801 for details. | ||
43 | */ | 53 | */ |
44 | 54 | ||
45 | /* Note: we assume there can only be one I801, with one SMBus interface */ | 55 | /* Note: we assume there can only be one I801, with one SMBus interface */ |
@@ -62,9 +72,9 @@ | |||
62 | #define SMBHSTDAT0 (5 + i801_smba) | 72 | #define SMBHSTDAT0 (5 + i801_smba) |
63 | #define SMBHSTDAT1 (6 + i801_smba) | 73 | #define SMBHSTDAT1 (6 + i801_smba) |
64 | #define SMBBLKDAT (7 + i801_smba) | 74 | #define SMBBLKDAT (7 + i801_smba) |
65 | #define SMBPEC (8 + i801_smba) /* ICH4 only */ | 75 | #define SMBPEC (8 + i801_smba) /* ICH3 and later */ |
66 | #define SMBAUXSTS (12 + i801_smba) /* ICH4 only */ | 76 | #define SMBAUXSTS (12 + i801_smba) /* ICH4 and later */ |
67 | #define SMBAUXCTL (13 + i801_smba) /* ICH4 only */ | 77 | #define SMBAUXCTL (13 + i801_smba) /* ICH4 and later */ |
68 | 78 | ||
69 | /* PCI Address Constants */ | 79 | /* PCI Address Constants */ |
70 | #define SMBBAR 4 | 80 | #define SMBBAR 4 |
@@ -91,13 +101,13 @@ | |||
91 | #define I801_BYTE 0x04 | 101 | #define I801_BYTE 0x04 |
92 | #define I801_BYTE_DATA 0x08 | 102 | #define I801_BYTE_DATA 0x08 |
93 | #define I801_WORD_DATA 0x0C | 103 | #define I801_WORD_DATA 0x0C |
94 | #define I801_PROC_CALL 0x10 /* later chips only, unimplemented */ | 104 | #define I801_PROC_CALL 0x10 /* unimplemented */ |
95 | #define I801_BLOCK_DATA 0x14 | 105 | #define I801_BLOCK_DATA 0x14 |
96 | #define I801_I2C_BLOCK_DATA 0x18 /* unimplemented */ | 106 | #define I801_I2C_BLOCK_DATA 0x18 /* ICH5 and later */ |
97 | #define I801_BLOCK_LAST 0x34 | 107 | #define I801_BLOCK_LAST 0x34 |
98 | #define I801_I2C_BLOCK_LAST 0x38 /* unimplemented */ | 108 | #define I801_I2C_BLOCK_LAST 0x38 /* ICH5 and later */ |
99 | #define I801_START 0x40 | 109 | #define I801_START 0x40 |
100 | #define I801_PEC_EN 0x80 /* ICH4 only */ | 110 | #define I801_PEC_EN 0x80 /* ICH3 and later */ |
101 | 111 | ||
102 | /* I801 Hosts Status register bits */ | 112 | /* I801 Hosts Status register bits */ |
103 | #define SMBHSTSTS_BYTE_DONE 0x80 | 113 | #define SMBHSTSTS_BYTE_DONE 0x80 |
@@ -113,7 +123,12 @@ static unsigned long i801_smba; | |||
113 | static unsigned char i801_original_hstcfg; | 123 | static unsigned char i801_original_hstcfg; |
114 | static struct pci_driver i801_driver; | 124 | static struct pci_driver i801_driver; |
115 | static struct pci_dev *I801_dev; | 125 | static struct pci_dev *I801_dev; |
116 | static int isich4; | 126 | |
127 | #define FEATURE_SMBUS_PEC (1 << 0) | ||
128 | #define FEATURE_BLOCK_BUFFER (1 << 1) | ||
129 | #define FEATURE_BLOCK_PROC (1 << 2) | ||
130 | #define FEATURE_I2C_BLOCK_READ (1 << 3) | ||
131 | static unsigned int i801_features; | ||
117 | 132 | ||
118 | static int i801_transaction(int xact) | 133 | static int i801_transaction(int xact) |
119 | { | 134 | { |
@@ -242,7 +257,8 @@ static int i801_block_transaction_by_block(union i2c_smbus_data *data, | |||
242 | } | 257 | } |
243 | 258 | ||
244 | static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data, | 259 | static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data, |
245 | char read_write, int hwpec) | 260 | char read_write, int command, |
261 | int hwpec) | ||
246 | { | 262 | { |
247 | int i, len; | 263 | int i, len; |
248 | int smbcmd; | 264 | int smbcmd; |
@@ -259,16 +275,24 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data, | |||
259 | } | 275 | } |
260 | 276 | ||
261 | for (i = 1; i <= len; i++) { | 277 | for (i = 1; i <= len; i++) { |
262 | if (i == len && read_write == I2C_SMBUS_READ) | 278 | if (i == len && read_write == I2C_SMBUS_READ) { |
263 | smbcmd = I801_BLOCK_LAST; | 279 | if (command == I2C_SMBUS_I2C_BLOCK_DATA) |
264 | else | 280 | smbcmd = I801_I2C_BLOCK_LAST; |
265 | smbcmd = I801_BLOCK_DATA; | 281 | else |
282 | smbcmd = I801_BLOCK_LAST; | ||
283 | } else { | ||
284 | if (command == I2C_SMBUS_I2C_BLOCK_DATA | ||
285 | && read_write == I2C_SMBUS_READ) | ||
286 | smbcmd = I801_I2C_BLOCK_DATA; | ||
287 | else | ||
288 | smbcmd = I801_BLOCK_DATA; | ||
289 | } | ||
266 | outb_p(smbcmd | ENABLE_INT9, SMBHSTCNT); | 290 | outb_p(smbcmd | ENABLE_INT9, SMBHSTCNT); |
267 | 291 | ||
268 | dev_dbg(&I801_dev->dev, "Block (pre %d): CNT=%02x, CMD=%02x, " | 292 | dev_dbg(&I801_dev->dev, "Block (pre %d): CNT=%02x, CMD=%02x, " |
269 | "ADD=%02x, DAT0=%02x, BLKDAT=%02x\n", i, | 293 | "ADD=%02x, DAT0=%02x, DAT1=%02x, BLKDAT=%02x\n", i, |
270 | inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD), | 294 | inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD), |
271 | inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT)); | 295 | inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1), inb_p(SMBBLKDAT)); |
272 | 296 | ||
273 | /* Make sure the SMBus host is ready to start transmitting */ | 297 | /* Make sure the SMBus host is ready to start transmitting */ |
274 | temp = inb_p(SMBHSTSTS); | 298 | temp = inb_p(SMBHSTSTS); |
@@ -332,7 +356,8 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data, | |||
332 | dev_dbg(&I801_dev->dev, "Error: no response!\n"); | 356 | dev_dbg(&I801_dev->dev, "Error: no response!\n"); |
333 | } | 357 | } |
334 | 358 | ||
335 | if (i == 1 && read_write == I2C_SMBUS_READ) { | 359 | if (i == 1 && read_write == I2C_SMBUS_READ |
360 | && command != I2C_SMBUS_I2C_BLOCK_DATA) { | ||
336 | len = inb_p(SMBHSTDAT0); | 361 | len = inb_p(SMBHSTDAT0); |
337 | if (len < 1 || len > I2C_SMBUS_BLOCK_MAX) | 362 | if (len < 1 || len > I2C_SMBUS_BLOCK_MAX) |
338 | return -1; | 363 | return -1; |
@@ -353,9 +378,9 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data, | |||
353 | temp); | 378 | temp); |
354 | } | 379 | } |
355 | dev_dbg(&I801_dev->dev, "Block (post %d): CNT=%02x, CMD=%02x, " | 380 | dev_dbg(&I801_dev->dev, "Block (post %d): CNT=%02x, CMD=%02x, " |
356 | "ADD=%02x, DAT0=%02x, BLKDAT=%02x\n", i, | 381 | "ADD=%02x, DAT0=%02x, DAT1=%02x, BLKDAT=%02x\n", i, |
357 | inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD), | 382 | inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD), |
358 | inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT)); | 383 | inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1), inb_p(SMBBLKDAT)); |
359 | 384 | ||
360 | if (result < 0) | 385 | if (result < 0) |
361 | return result; | 386 | return result; |
@@ -384,33 +409,38 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write, | |||
384 | pci_read_config_byte(I801_dev, SMBHSTCFG, &hostc); | 409 | pci_read_config_byte(I801_dev, SMBHSTCFG, &hostc); |
385 | pci_write_config_byte(I801_dev, SMBHSTCFG, | 410 | pci_write_config_byte(I801_dev, SMBHSTCFG, |
386 | hostc | SMBHSTCFG_I2C_EN); | 411 | hostc | SMBHSTCFG_I2C_EN); |
387 | } else { | 412 | } else if (!(i801_features & FEATURE_I2C_BLOCK_READ)) { |
388 | dev_err(&I801_dev->dev, | 413 | dev_err(&I801_dev->dev, |
389 | "I2C_SMBUS_I2C_BLOCK_READ not DB!\n"); | 414 | "I2C block read is unsupported!\n"); |
390 | return -1; | 415 | return -1; |
391 | } | 416 | } |
392 | } | 417 | } |
393 | 418 | ||
394 | if (read_write == I2C_SMBUS_WRITE) { | 419 | if (read_write == I2C_SMBUS_WRITE |
420 | || command == I2C_SMBUS_I2C_BLOCK_DATA) { | ||
395 | if (data->block[0] < 1) | 421 | if (data->block[0] < 1) |
396 | data->block[0] = 1; | 422 | data->block[0] = 1; |
397 | if (data->block[0] > I2C_SMBUS_BLOCK_MAX) | 423 | if (data->block[0] > I2C_SMBUS_BLOCK_MAX) |
398 | data->block[0] = I2C_SMBUS_BLOCK_MAX; | 424 | data->block[0] = I2C_SMBUS_BLOCK_MAX; |
399 | } else { | 425 | } else { |
400 | data->block[0] = 32; /* max for reads */ | 426 | data->block[0] = 32; /* max for SMBus block reads */ |
401 | } | 427 | } |
402 | 428 | ||
403 | if (isich4 && i801_set_block_buffer_mode() == 0 ) | 429 | if ((i801_features & FEATURE_BLOCK_BUFFER) |
430 | && !(command == I2C_SMBUS_I2C_BLOCK_DATA | ||
431 | && read_write == I2C_SMBUS_READ) | ||
432 | && i801_set_block_buffer_mode() == 0) | ||
404 | result = i801_block_transaction_by_block(data, read_write, | 433 | result = i801_block_transaction_by_block(data, read_write, |
405 | hwpec); | 434 | hwpec); |
406 | else | 435 | else |
407 | result = i801_block_transaction_byte_by_byte(data, read_write, | 436 | result = i801_block_transaction_byte_by_byte(data, read_write, |
408 | hwpec); | 437 | command, hwpec); |
409 | 438 | ||
410 | if (result == 0 && hwpec) | 439 | if (result == 0 && hwpec) |
411 | i801_wait_hwpec(); | 440 | i801_wait_hwpec(); |
412 | 441 | ||
413 | if (command == I2C_SMBUS_I2C_BLOCK_DATA) { | 442 | if (command == I2C_SMBUS_I2C_BLOCK_DATA |
443 | && read_write == I2C_SMBUS_WRITE) { | ||
414 | /* restore saved configuration register value */ | 444 | /* restore saved configuration register value */ |
415 | pci_write_config_byte(I801_dev, SMBHSTCFG, hostc); | 445 | pci_write_config_byte(I801_dev, SMBHSTCFG, hostc); |
416 | } | 446 | } |
@@ -426,7 +456,7 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr, | |||
426 | int block = 0; | 456 | int block = 0; |
427 | int ret, xact = 0; | 457 | int ret, xact = 0; |
428 | 458 | ||
429 | hwpec = isich4 && (flags & I2C_CLIENT_PEC) | 459 | hwpec = (i801_features & FEATURE_SMBUS_PEC) && (flags & I2C_CLIENT_PEC) |
430 | && size != I2C_SMBUS_QUICK | 460 | && size != I2C_SMBUS_QUICK |
431 | && size != I2C_SMBUS_I2C_BLOCK_DATA; | 461 | && size != I2C_SMBUS_I2C_BLOCK_DATA; |
432 | 462 | ||
@@ -462,12 +492,23 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr, | |||
462 | xact = I801_WORD_DATA; | 492 | xact = I801_WORD_DATA; |
463 | break; | 493 | break; |
464 | case I2C_SMBUS_BLOCK_DATA: | 494 | case I2C_SMBUS_BLOCK_DATA: |
465 | case I2C_SMBUS_I2C_BLOCK_DATA: | ||
466 | outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), | 495 | outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), |
467 | SMBHSTADD); | 496 | SMBHSTADD); |
468 | outb_p(command, SMBHSTCMD); | 497 | outb_p(command, SMBHSTCMD); |
469 | block = 1; | 498 | block = 1; |
470 | break; | 499 | break; |
500 | case I2C_SMBUS_I2C_BLOCK_DATA: | ||
501 | /* NB: page 240 of ICH5 datasheet shows that the R/#W | ||
502 | * bit should be cleared here, even when reading */ | ||
503 | outb_p((addr & 0x7f) << 1, SMBHSTADD); | ||
504 | if (read_write == I2C_SMBUS_READ) { | ||
505 | /* NB: page 240 of ICH5 datasheet also shows | ||
506 | * that DATA1 is the cmd field when reading */ | ||
507 | outb_p(command, SMBHSTDAT1); | ||
508 | } else | ||
509 | outb_p(command, SMBHSTCMD); | ||
510 | block = 1; | ||
511 | break; | ||
471 | case I2C_SMBUS_PROC_CALL: | 512 | case I2C_SMBUS_PROC_CALL: |
472 | default: | 513 | default: |
473 | dev_err(&I801_dev->dev, "Unsupported transaction %d\n", size); | 514 | dev_err(&I801_dev->dev, "Unsupported transaction %d\n", size); |
@@ -487,7 +528,7 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr, | |||
487 | /* Some BIOSes don't like it when PEC is enabled at reboot or resume | 528 | /* Some BIOSes don't like it when PEC is enabled at reboot or resume |
488 | time, so we forcibly disable it after every transaction. Turn off | 529 | time, so we forcibly disable it after every transaction. Turn off |
489 | E32B for the same reason. */ | 530 | E32B for the same reason. */ |
490 | if (hwpec) | 531 | if (hwpec || block) |
491 | outb_p(inb_p(SMBAUXCTL) & ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), | 532 | outb_p(inb_p(SMBAUXCTL) & ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), |
492 | SMBAUXCTL); | 533 | SMBAUXCTL); |
493 | 534 | ||
@@ -514,9 +555,11 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr, | |||
514 | static u32 i801_func(struct i2c_adapter *adapter) | 555 | static u32 i801_func(struct i2c_adapter *adapter) |
515 | { | 556 | { |
516 | return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | | 557 | return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | |
517 | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | | 558 | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | |
518 | I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_WRITE_I2C_BLOCK | 559 | I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_WRITE_I2C_BLOCK | |
519 | | (isich4 ? I2C_FUNC_SMBUS_PEC : 0); | 560 | ((i801_features & FEATURE_SMBUS_PEC) ? I2C_FUNC_SMBUS_PEC : 0) | |
561 | ((i801_features & FEATURE_I2C_BLOCK_READ) ? | ||
562 | I2C_FUNC_SMBUS_READ_I2C_BLOCK : 0); | ||
520 | } | 563 | } |
521 | 564 | ||
522 | static const struct i2c_algorithm smbus_algorithm = { | 565 | static const struct i2c_algorithm smbus_algorithm = { |
@@ -556,8 +599,8 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id | |||
556 | int err; | 599 | int err; |
557 | 600 | ||
558 | I801_dev = dev; | 601 | I801_dev = dev; |
602 | i801_features = 0; | ||
559 | switch (dev->device) { | 603 | switch (dev->device) { |
560 | case PCI_DEVICE_ID_INTEL_82801DB_3: | ||
561 | case PCI_DEVICE_ID_INTEL_82801EB_3: | 604 | case PCI_DEVICE_ID_INTEL_82801EB_3: |
562 | case PCI_DEVICE_ID_INTEL_ESB_4: | 605 | case PCI_DEVICE_ID_INTEL_ESB_4: |
563 | case PCI_DEVICE_ID_INTEL_ICH6_16: | 606 | case PCI_DEVICE_ID_INTEL_ICH6_16: |
@@ -565,11 +608,13 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id | |||
565 | case PCI_DEVICE_ID_INTEL_ESB2_17: | 608 | case PCI_DEVICE_ID_INTEL_ESB2_17: |
566 | case PCI_DEVICE_ID_INTEL_ICH8_5: | 609 | case PCI_DEVICE_ID_INTEL_ICH8_5: |
567 | case PCI_DEVICE_ID_INTEL_ICH9_6: | 610 | case PCI_DEVICE_ID_INTEL_ICH9_6: |
611 | i801_features |= FEATURE_I2C_BLOCK_READ; | ||
612 | /* fall through */ | ||
613 | case PCI_DEVICE_ID_INTEL_82801DB_3: | ||
568 | case PCI_DEVICE_ID_INTEL_TOLAPAI_1: | 614 | case PCI_DEVICE_ID_INTEL_TOLAPAI_1: |
569 | isich4 = 1; | 615 | i801_features |= FEATURE_SMBUS_PEC; |
616 | i801_features |= FEATURE_BLOCK_BUFFER; | ||
570 | break; | 617 | break; |
571 | default: | ||
572 | isich4 = 0; | ||
573 | } | 618 | } |
574 | 619 | ||
575 | err = pci_enable_device(dev); | 620 | err = pci_enable_device(dev); |
@@ -610,6 +655,11 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id | |||
610 | else | 655 | else |
611 | dev_dbg(&dev->dev, "SMBus using PCI Interrupt\n"); | 656 | dev_dbg(&dev->dev, "SMBus using PCI Interrupt\n"); |
612 | 657 | ||
658 | /* Clear special mode bits */ | ||
659 | if (i801_features & (FEATURE_SMBUS_PEC | FEATURE_BLOCK_BUFFER)) | ||
660 | outb_p(inb_p(SMBAUXCTL) & ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), | ||
661 | SMBAUXCTL); | ||
662 | |||
613 | /* set up the sysfs linkage to our parent device */ | 663 | /* set up the sysfs linkage to our parent device */ |
614 | i801_adapter.dev.parent = &dev->dev; | 664 | i801_adapter.dev.parent = &dev->dev; |
615 | 665 | ||
@@ -678,9 +728,8 @@ static void __exit i2c_i801_exit(void) | |||
678 | pci_unregister_driver(&i801_driver); | 728 | pci_unregister_driver(&i801_driver); |
679 | } | 729 | } |
680 | 730 | ||
681 | MODULE_AUTHOR ("Frodo Looijaard <frodol@dds.nl>, " | 731 | MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>, " |
682 | "Philip Edelbrock <phil@netroedge.com>, " | 732 | "Jean Delvare <khali@linux-fr.org>"); |
683 | "and Mark D. Studebaker <mdsxyz123@yahoo.com>"); | ||
684 | MODULE_DESCRIPTION("I801 SMBus driver"); | 733 | MODULE_DESCRIPTION("I801 SMBus driver"); |
685 | MODULE_LICENSE("GPL"); | 734 | MODULE_LICENSE("GPL"); |
686 | 735 | ||
diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index 9b43ff7270d0..7c7eb0cfeceb 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * Copyright (c) 2003, 2004 Zultys Technologies. | 6 | * Copyright (c) 2003, 2004 Zultys Technologies. |
7 | * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net> | 7 | * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net> |
8 | * | 8 | * |
9 | * Based on original work by | 9 | * Based on original work by |
10 | * Ian DaSilva <idasilva@mvista.com> | 10 | * Ian DaSilva <idasilva@mvista.com> |
11 | * Armin Kuster <akuster@mvista.com> | 11 | * Armin Kuster <akuster@mvista.com> |
12 | * Matt Porter <mporter@mvista.com> | 12 | * Matt Porter <mporter@mvista.com> |
@@ -86,8 +86,8 @@ static void dump_iic_regs(const char* header, struct ibm_iic_private* dev) | |||
86 | KERN_DEBUG " sts = 0x%02x, extsts = 0x%02x\n" | 86 | KERN_DEBUG " sts = 0x%02x, extsts = 0x%02x\n" |
87 | KERN_DEBUG " clkdiv = 0x%02x, xfrcnt = 0x%02x\n" | 87 | KERN_DEBUG " clkdiv = 0x%02x, xfrcnt = 0x%02x\n" |
88 | KERN_DEBUG " xtcntlss = 0x%02x, directcntl = 0x%02x\n", | 88 | KERN_DEBUG " xtcntlss = 0x%02x, directcntl = 0x%02x\n", |
89 | in_8(&iic->cntl), in_8(&iic->mdcntl), in_8(&iic->sts), | 89 | in_8(&iic->cntl), in_8(&iic->mdcntl), in_8(&iic->sts), |
90 | in_8(&iic->extsts), in_8(&iic->clkdiv), in_8(&iic->xfrcnt), | 90 | in_8(&iic->extsts), in_8(&iic->clkdiv), in_8(&iic->xfrcnt), |
91 | in_8(&iic->xtcntlss), in_8(&iic->directcntl)); | 91 | in_8(&iic->xtcntlss), in_8(&iic->directcntl)); |
92 | } | 92 | } |
93 | # define DUMP_REGS(h,dev) dump_iic_regs((h),(dev)) | 93 | # define DUMP_REGS(h,dev) dump_iic_regs((h),(dev)) |
@@ -125,7 +125,7 @@ static inline void iic_interrupt_mode(struct ibm_iic_private* dev, int enable) | |||
125 | { | 125 | { |
126 | out_8(&dev->vaddr->intmsk, enable ? INTRMSK_EIMTC : 0); | 126 | out_8(&dev->vaddr->intmsk, enable ? INTRMSK_EIMTC : 0); |
127 | } | 127 | } |
128 | 128 | ||
129 | /* | 129 | /* |
130 | * Initialize IIC interface. | 130 | * Initialize IIC interface. |
131 | */ | 131 | */ |
@@ -134,7 +134,7 @@ static void iic_dev_init(struct ibm_iic_private* dev) | |||
134 | volatile struct iic_regs __iomem *iic = dev->vaddr; | 134 | volatile struct iic_regs __iomem *iic = dev->vaddr; |
135 | 135 | ||
136 | DBG("%d: init\n", dev->idx); | 136 | DBG("%d: init\n", dev->idx); |
137 | 137 | ||
138 | /* Clear master address */ | 138 | /* Clear master address */ |
139 | out_8(&iic->lmadr, 0); | 139 | out_8(&iic->lmadr, 0); |
140 | out_8(&iic->hmadr, 0); | 140 | out_8(&iic->hmadr, 0); |
@@ -160,7 +160,7 @@ static void iic_dev_init(struct ibm_iic_private* dev) | |||
160 | 160 | ||
161 | /* Clear control register */ | 161 | /* Clear control register */ |
162 | out_8(&iic->cntl, 0); | 162 | out_8(&iic->cntl, 0); |
163 | 163 | ||
164 | /* Enable interrupts if possible */ | 164 | /* Enable interrupts if possible */ |
165 | iic_interrupt_mode(dev, dev->irq >= 0); | 165 | iic_interrupt_mode(dev, dev->irq >= 0); |
166 | 166 | ||
@@ -171,7 +171,7 @@ static void iic_dev_init(struct ibm_iic_private* dev) | |||
171 | DUMP_REGS("iic_init", dev); | 171 | DUMP_REGS("iic_init", dev); |
172 | } | 172 | } |
173 | 173 | ||
174 | /* | 174 | /* |
175 | * Reset IIC interface | 175 | * Reset IIC interface |
176 | */ | 176 | */ |
177 | static void iic_dev_reset(struct ibm_iic_private* dev) | 177 | static void iic_dev_reset(struct ibm_iic_private* dev) |
@@ -179,42 +179,42 @@ static void iic_dev_reset(struct ibm_iic_private* dev) | |||
179 | volatile struct iic_regs __iomem *iic = dev->vaddr; | 179 | volatile struct iic_regs __iomem *iic = dev->vaddr; |
180 | int i; | 180 | int i; |
181 | u8 dc; | 181 | u8 dc; |
182 | 182 | ||
183 | DBG("%d: soft reset\n", dev->idx); | 183 | DBG("%d: soft reset\n", dev->idx); |
184 | DUMP_REGS("reset", dev); | 184 | DUMP_REGS("reset", dev); |
185 | 185 | ||
186 | /* Place chip in the reset state */ | 186 | /* Place chip in the reset state */ |
187 | out_8(&iic->xtcntlss, XTCNTLSS_SRST); | 187 | out_8(&iic->xtcntlss, XTCNTLSS_SRST); |
188 | 188 | ||
189 | /* Check if bus is free */ | 189 | /* Check if bus is free */ |
190 | dc = in_8(&iic->directcntl); | 190 | dc = in_8(&iic->directcntl); |
191 | if (!DIRCTNL_FREE(dc)){ | 191 | if (!DIRCTNL_FREE(dc)){ |
192 | DBG("%d: trying to regain bus control\n", dev->idx); | 192 | DBG("%d: trying to regain bus control\n", dev->idx); |
193 | 193 | ||
194 | /* Try to set bus free state */ | 194 | /* Try to set bus free state */ |
195 | out_8(&iic->directcntl, DIRCNTL_SDAC | DIRCNTL_SCC); | 195 | out_8(&iic->directcntl, DIRCNTL_SDAC | DIRCNTL_SCC); |
196 | 196 | ||
197 | /* Wait until we regain bus control */ | 197 | /* Wait until we regain bus control */ |
198 | for (i = 0; i < 100; ++i){ | 198 | for (i = 0; i < 100; ++i){ |
199 | dc = in_8(&iic->directcntl); | 199 | dc = in_8(&iic->directcntl); |
200 | if (DIRCTNL_FREE(dc)) | 200 | if (DIRCTNL_FREE(dc)) |
201 | break; | 201 | break; |
202 | 202 | ||
203 | /* Toggle SCL line */ | 203 | /* Toggle SCL line */ |
204 | dc ^= DIRCNTL_SCC; | 204 | dc ^= DIRCNTL_SCC; |
205 | out_8(&iic->directcntl, dc); | 205 | out_8(&iic->directcntl, dc); |
206 | udelay(10); | 206 | udelay(10); |
207 | dc ^= DIRCNTL_SCC; | 207 | dc ^= DIRCNTL_SCC; |
208 | out_8(&iic->directcntl, dc); | 208 | out_8(&iic->directcntl, dc); |
209 | 209 | ||
210 | /* be nice */ | 210 | /* be nice */ |
211 | cond_resched(); | 211 | cond_resched(); |
212 | } | 212 | } |
213 | } | 213 | } |
214 | 214 | ||
215 | /* Remove reset */ | 215 | /* Remove reset */ |
216 | out_8(&iic->xtcntlss, 0); | 216 | out_8(&iic->xtcntlss, 0); |
217 | 217 | ||
218 | /* Reinitialize interface */ | 218 | /* Reinitialize interface */ |
219 | iic_dev_init(dev); | 219 | iic_dev_init(dev); |
220 | } | 220 | } |
@@ -324,14 +324,14 @@ static irqreturn_t iic_handler(int irq, void *dev_id) | |||
324 | { | 324 | { |
325 | struct ibm_iic_private* dev = (struct ibm_iic_private*)dev_id; | 325 | struct ibm_iic_private* dev = (struct ibm_iic_private*)dev_id; |
326 | volatile struct iic_regs __iomem *iic = dev->vaddr; | 326 | volatile struct iic_regs __iomem *iic = dev->vaddr; |
327 | 327 | ||
328 | DBG2("%d: irq handler, STS = 0x%02x, EXTSTS = 0x%02x\n", | 328 | DBG2("%d: irq handler, STS = 0x%02x, EXTSTS = 0x%02x\n", |
329 | dev->idx, in_8(&iic->sts), in_8(&iic->extsts)); | 329 | dev->idx, in_8(&iic->sts), in_8(&iic->extsts)); |
330 | 330 | ||
331 | /* Acknowledge IRQ and wakeup iic_wait_for_tc */ | 331 | /* Acknowledge IRQ and wakeup iic_wait_for_tc */ |
332 | out_8(&iic->sts, STS_IRQA | STS_SCMP); | 332 | out_8(&iic->sts, STS_IRQA | STS_SCMP); |
333 | wake_up_interruptible(&dev->wq); | 333 | wake_up_interruptible(&dev->wq); |
334 | 334 | ||
335 | return IRQ_HANDLED; | 335 | return IRQ_HANDLED; |
336 | } | 336 | } |
337 | 337 | ||
@@ -341,19 +341,19 @@ static irqreturn_t iic_handler(int irq, void *dev_id) | |||
341 | */ | 341 | */ |
342 | static int iic_xfer_result(struct ibm_iic_private* dev) | 342 | static int iic_xfer_result(struct ibm_iic_private* dev) |
343 | { | 343 | { |
344 | volatile struct iic_regs __iomem *iic = dev->vaddr; | 344 | volatile struct iic_regs __iomem *iic = dev->vaddr; |
345 | 345 | ||
346 | if (unlikely(in_8(&iic->sts) & STS_ERR)){ | 346 | if (unlikely(in_8(&iic->sts) & STS_ERR)){ |
347 | DBG("%d: xfer error, EXTSTS = 0x%02x\n", dev->idx, | 347 | DBG("%d: xfer error, EXTSTS = 0x%02x\n", dev->idx, |
348 | in_8(&iic->extsts)); | 348 | in_8(&iic->extsts)); |
349 | 349 | ||
350 | /* Clear errors and possible pending IRQs */ | 350 | /* Clear errors and possible pending IRQs */ |
351 | out_8(&iic->extsts, EXTSTS_IRQP | EXTSTS_IRQD | | 351 | out_8(&iic->extsts, EXTSTS_IRQP | EXTSTS_IRQD | |
352 | EXTSTS_LA | EXTSTS_ICT | EXTSTS_XFRA); | 352 | EXTSTS_LA | EXTSTS_ICT | EXTSTS_XFRA); |
353 | 353 | ||
354 | /* Flush master data buffer */ | 354 | /* Flush master data buffer */ |
355 | out_8(&iic->mdcntl, in_8(&iic->mdcntl) | MDCNTL_FMDB); | 355 | out_8(&iic->mdcntl, in_8(&iic->mdcntl) | MDCNTL_FMDB); |
356 | 356 | ||
357 | /* Is bus free? | 357 | /* Is bus free? |
358 | * If error happened during combined xfer | 358 | * If error happened during combined xfer |
359 | * IIC interface is usually stuck in some strange | 359 | * IIC interface is usually stuck in some strange |
@@ -376,11 +376,11 @@ static void iic_abort_xfer(struct ibm_iic_private* dev) | |||
376 | { | 376 | { |
377 | volatile struct iic_regs __iomem *iic = dev->vaddr; | 377 | volatile struct iic_regs __iomem *iic = dev->vaddr; |
378 | unsigned long x; | 378 | unsigned long x; |
379 | 379 | ||
380 | DBG("%d: iic_abort_xfer\n", dev->idx); | 380 | DBG("%d: iic_abort_xfer\n", dev->idx); |
381 | 381 | ||
382 | out_8(&iic->cntl, CNTL_HMT); | 382 | out_8(&iic->cntl, CNTL_HMT); |
383 | 383 | ||
384 | /* | 384 | /* |
385 | * Wait for the abort command to complete. | 385 | * Wait for the abort command to complete. |
386 | * It's not worth to be optimized, just poll (timeout >= 1 tick) | 386 | * It's not worth to be optimized, just poll (timeout >= 1 tick) |
@@ -405,13 +405,13 @@ static void iic_abort_xfer(struct ibm_iic_private* dev) | |||
405 | * Returns the number of transferred bytes or error (<0) | 405 | * Returns the number of transferred bytes or error (<0) |
406 | */ | 406 | */ |
407 | static int iic_wait_for_tc(struct ibm_iic_private* dev){ | 407 | static int iic_wait_for_tc(struct ibm_iic_private* dev){ |
408 | 408 | ||
409 | volatile struct iic_regs __iomem *iic = dev->vaddr; | 409 | volatile struct iic_regs __iomem *iic = dev->vaddr; |
410 | int ret = 0; | 410 | int ret = 0; |
411 | 411 | ||
412 | if (dev->irq >= 0){ | 412 | if (dev->irq >= 0){ |
413 | /* Interrupt mode */ | 413 | /* Interrupt mode */ |
414 | ret = wait_event_interruptible_timeout(dev->wq, | 414 | ret = wait_event_interruptible_timeout(dev->wq, |
415 | !(in_8(&iic->sts) & STS_PT), dev->adap.timeout * HZ); | 415 | !(in_8(&iic->sts) & STS_PT), dev->adap.timeout * HZ); |
416 | 416 | ||
417 | if (unlikely(ret < 0)) | 417 | if (unlikely(ret < 0)) |
@@ -424,37 +424,37 @@ static int iic_wait_for_tc(struct ibm_iic_private* dev){ | |||
424 | else { | 424 | else { |
425 | /* Polling mode */ | 425 | /* Polling mode */ |
426 | unsigned long x = jiffies + dev->adap.timeout * HZ; | 426 | unsigned long x = jiffies + dev->adap.timeout * HZ; |
427 | 427 | ||
428 | while (in_8(&iic->sts) & STS_PT){ | 428 | while (in_8(&iic->sts) & STS_PT){ |
429 | if (unlikely(time_after(jiffies, x))){ | 429 | if (unlikely(time_after(jiffies, x))){ |
430 | DBG("%d: poll timeout\n", dev->idx); | 430 | DBG("%d: poll timeout\n", dev->idx); |
431 | ret = -ETIMEDOUT; | 431 | ret = -ETIMEDOUT; |
432 | break; | 432 | break; |
433 | } | 433 | } |
434 | 434 | ||
435 | if (unlikely(signal_pending(current))){ | 435 | if (unlikely(signal_pending(current))){ |
436 | DBG("%d: poll interrupted\n", dev->idx); | 436 | DBG("%d: poll interrupted\n", dev->idx); |
437 | ret = -ERESTARTSYS; | 437 | ret = -ERESTARTSYS; |
438 | break; | 438 | break; |
439 | } | 439 | } |
440 | schedule(); | 440 | schedule(); |
441 | } | 441 | } |
442 | } | 442 | } |
443 | 443 | ||
444 | if (unlikely(ret < 0)) | 444 | if (unlikely(ret < 0)) |
445 | iic_abort_xfer(dev); | 445 | iic_abort_xfer(dev); |
446 | else | 446 | else |
447 | ret = iic_xfer_result(dev); | 447 | ret = iic_xfer_result(dev); |
448 | 448 | ||
449 | DBG2("%d: iic_wait_for_tc -> %d\n", dev->idx, ret); | 449 | DBG2("%d: iic_wait_for_tc -> %d\n", dev->idx, ret); |
450 | 450 | ||
451 | return ret; | 451 | return ret; |
452 | } | 452 | } |
453 | 453 | ||
454 | /* | 454 | /* |
455 | * Low level master transfer routine | 455 | * Low level master transfer routine |
456 | */ | 456 | */ |
457 | static int iic_xfer_bytes(struct ibm_iic_private* dev, struct i2c_msg* pm, | 457 | static int iic_xfer_bytes(struct ibm_iic_private* dev, struct i2c_msg* pm, |
458 | int combined_xfer) | 458 | int combined_xfer) |
459 | { | 459 | { |
460 | volatile struct iic_regs __iomem *iic = dev->vaddr; | 460 | volatile struct iic_regs __iomem *iic = dev->vaddr; |
@@ -465,48 +465,48 @@ static int iic_xfer_bytes(struct ibm_iic_private* dev, struct i2c_msg* pm, | |||
465 | u8 cntl = (in_8(&iic->cntl) & CNTL_AMD) | CNTL_PT; | 465 | u8 cntl = (in_8(&iic->cntl) & CNTL_AMD) | CNTL_PT; |
466 | if (pm->flags & I2C_M_RD) | 466 | if (pm->flags & I2C_M_RD) |
467 | cntl |= CNTL_RW; | 467 | cntl |= CNTL_RW; |
468 | 468 | ||
469 | loops = (len + 3) / 4; | 469 | loops = (len + 3) / 4; |
470 | for (i = 0; i < loops; ++i, len -= 4){ | 470 | for (i = 0; i < loops; ++i, len -= 4){ |
471 | int count = len > 4 ? 4 : len; | 471 | int count = len > 4 ? 4 : len; |
472 | u8 cmd = cntl | ((count - 1) << CNTL_TCT_SHIFT); | 472 | u8 cmd = cntl | ((count - 1) << CNTL_TCT_SHIFT); |
473 | 473 | ||
474 | if (!(cntl & CNTL_RW)) | 474 | if (!(cntl & CNTL_RW)) |
475 | for (j = 0; j < count; ++j) | 475 | for (j = 0; j < count; ++j) |
476 | out_8((void __iomem *)&iic->mdbuf, *buf++); | 476 | out_8((void __iomem *)&iic->mdbuf, *buf++); |
477 | 477 | ||
478 | if (i < loops - 1) | 478 | if (i < loops - 1) |
479 | cmd |= CNTL_CHT; | 479 | cmd |= CNTL_CHT; |
480 | else if (combined_xfer) | 480 | else if (combined_xfer) |
481 | cmd |= CNTL_RPST; | 481 | cmd |= CNTL_RPST; |
482 | 482 | ||
483 | DBG2("%d: xfer_bytes, %d, CNTL = 0x%02x\n", dev->idx, count, cmd); | 483 | DBG2("%d: xfer_bytes, %d, CNTL = 0x%02x\n", dev->idx, count, cmd); |
484 | 484 | ||
485 | /* Start transfer */ | 485 | /* Start transfer */ |
486 | out_8(&iic->cntl, cmd); | 486 | out_8(&iic->cntl, cmd); |
487 | 487 | ||
488 | /* Wait for completion */ | 488 | /* Wait for completion */ |
489 | ret = iic_wait_for_tc(dev); | 489 | ret = iic_wait_for_tc(dev); |
490 | 490 | ||
491 | if (unlikely(ret < 0)) | 491 | if (unlikely(ret < 0)) |
492 | break; | 492 | break; |
493 | else if (unlikely(ret != count)){ | 493 | else if (unlikely(ret != count)){ |
494 | DBG("%d: xfer_bytes, requested %d, transfered %d\n", | 494 | DBG("%d: xfer_bytes, requested %d, transfered %d\n", |
495 | dev->idx, count, ret); | 495 | dev->idx, count, ret); |
496 | 496 | ||
497 | /* If it's not a last part of xfer, abort it */ | 497 | /* If it's not a last part of xfer, abort it */ |
498 | if (combined_xfer || (i < loops - 1)) | 498 | if (combined_xfer || (i < loops - 1)) |
499 | iic_abort_xfer(dev); | 499 | iic_abort_xfer(dev); |
500 | 500 | ||
501 | ret = -EREMOTEIO; | 501 | ret = -EREMOTEIO; |
502 | break; | 502 | break; |
503 | } | 503 | } |
504 | 504 | ||
505 | if (cntl & CNTL_RW) | 505 | if (cntl & CNTL_RW) |
506 | for (j = 0; j < count; ++j) | 506 | for (j = 0; j < count; ++j) |
507 | *buf++ = in_8((void __iomem *)&iic->mdbuf); | 507 | *buf++ = in_8((void __iomem *)&iic->mdbuf); |
508 | } | 508 | } |
509 | 509 | ||
510 | return ret > 0 ? 0 : ret; | 510 | return ret > 0 ? 0 : ret; |
511 | } | 511 | } |
512 | 512 | ||
@@ -517,10 +517,10 @@ static inline void iic_address(struct ibm_iic_private* dev, struct i2c_msg* msg) | |||
517 | { | 517 | { |
518 | volatile struct iic_regs __iomem *iic = dev->vaddr; | 518 | volatile struct iic_regs __iomem *iic = dev->vaddr; |
519 | u16 addr = msg->addr; | 519 | u16 addr = msg->addr; |
520 | 520 | ||
521 | DBG2("%d: iic_address, 0x%03x (%d-bit)\n", dev->idx, | 521 | DBG2("%d: iic_address, 0x%03x (%d-bit)\n", dev->idx, |
522 | addr, msg->flags & I2C_M_TEN ? 10 : 7); | 522 | addr, msg->flags & I2C_M_TEN ? 10 : 7); |
523 | 523 | ||
524 | if (msg->flags & I2C_M_TEN){ | 524 | if (msg->flags & I2C_M_TEN){ |
525 | out_8(&iic->cntl, CNTL_AMD); | 525 | out_8(&iic->cntl, CNTL_AMD); |
526 | out_8(&iic->lmadr, addr); | 526 | out_8(&iic->lmadr, addr); |
@@ -537,15 +537,15 @@ static inline int iic_invalid_address(const struct i2c_msg* p) | |||
537 | return (p->addr > 0x3ff) || (!(p->flags & I2C_M_TEN) && (p->addr > 0x7f)); | 537 | return (p->addr > 0x3ff) || (!(p->flags & I2C_M_TEN) && (p->addr > 0x7f)); |
538 | } | 538 | } |
539 | 539 | ||
540 | static inline int iic_address_neq(const struct i2c_msg* p1, | 540 | static inline int iic_address_neq(const struct i2c_msg* p1, |
541 | const struct i2c_msg* p2) | 541 | const struct i2c_msg* p2) |
542 | { | 542 | { |
543 | return (p1->addr != p2->addr) | 543 | return (p1->addr != p2->addr) |
544 | || ((p1->flags & I2C_M_TEN) != (p2->flags & I2C_M_TEN)); | 544 | || ((p1->flags & I2C_M_TEN) != (p2->flags & I2C_M_TEN)); |
545 | } | 545 | } |
546 | 546 | ||
547 | /* | 547 | /* |
548 | * Generic master transfer entrypoint. | 548 | * Generic master transfer entrypoint. |
549 | * Returns the number of processed messages or error (<0) | 549 | * Returns the number of processed messages or error (<0) |
550 | */ | 550 | */ |
551 | static int iic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | 551 | static int iic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) |
@@ -553,20 +553,20 @@ static int iic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | |||
553 | struct ibm_iic_private* dev = (struct ibm_iic_private*)(i2c_get_adapdata(adap)); | 553 | struct ibm_iic_private* dev = (struct ibm_iic_private*)(i2c_get_adapdata(adap)); |
554 | volatile struct iic_regs __iomem *iic = dev->vaddr; | 554 | volatile struct iic_regs __iomem *iic = dev->vaddr; |
555 | int i, ret = 0; | 555 | int i, ret = 0; |
556 | 556 | ||
557 | DBG2("%d: iic_xfer, %d msg(s)\n", dev->idx, num); | 557 | DBG2("%d: iic_xfer, %d msg(s)\n", dev->idx, num); |
558 | 558 | ||
559 | if (!num) | 559 | if (!num) |
560 | return 0; | 560 | return 0; |
561 | 561 | ||
562 | /* Check the sanity of the passed messages. | 562 | /* Check the sanity of the passed messages. |
563 | * Uhh, generic i2c layer is more suitable place for such code... | 563 | * Uhh, generic i2c layer is more suitable place for such code... |
564 | */ | 564 | */ |
565 | if (unlikely(iic_invalid_address(&msgs[0]))){ | 565 | if (unlikely(iic_invalid_address(&msgs[0]))){ |
566 | DBG("%d: invalid address 0x%03x (%d-bit)\n", dev->idx, | 566 | DBG("%d: invalid address 0x%03x (%d-bit)\n", dev->idx, |
567 | msgs[0].addr, msgs[0].flags & I2C_M_TEN ? 10 : 7); | 567 | msgs[0].addr, msgs[0].flags & I2C_M_TEN ? 10 : 7); |
568 | return -EINVAL; | 568 | return -EINVAL; |
569 | } | 569 | } |
570 | for (i = 0; i < num; ++i){ | 570 | for (i = 0; i < num; ++i){ |
571 | if (unlikely(msgs[i].len <= 0)){ | 571 | if (unlikely(msgs[i].len <= 0)){ |
572 | if (num == 1 && !msgs[0].len){ | 572 | if (num == 1 && !msgs[0].len){ |
@@ -576,7 +576,7 @@ static int iic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | |||
576 | */ | 576 | */ |
577 | return iic_smbus_quick(dev, &msgs[0]); | 577 | return iic_smbus_quick(dev, &msgs[0]); |
578 | } | 578 | } |
579 | DBG("%d: invalid len %d in msg[%d]\n", dev->idx, | 579 | DBG("%d: invalid len %d in msg[%d]\n", dev->idx, |
580 | msgs[i].len, i); | 580 | msgs[i].len, i); |
581 | return -EINVAL; | 581 | return -EINVAL; |
582 | } | 582 | } |
@@ -585,34 +585,34 @@ static int iic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | |||
585 | return -EINVAL; | 585 | return -EINVAL; |
586 | } | 586 | } |
587 | } | 587 | } |
588 | 588 | ||
589 | /* Check bus state */ | 589 | /* Check bus state */ |
590 | if (unlikely((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE)){ | 590 | if (unlikely((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE)){ |
591 | DBG("%d: iic_xfer, bus is not free\n", dev->idx); | 591 | DBG("%d: iic_xfer, bus is not free\n", dev->idx); |
592 | 592 | ||
593 | /* Usually it means something serious has happend. | 593 | /* Usually it means something serious has happend. |
594 | * We *cannot* have unfinished previous transfer | 594 | * We *cannot* have unfinished previous transfer |
595 | * so it doesn't make any sense to try to stop it. | 595 | * so it doesn't make any sense to try to stop it. |
596 | * Probably we were not able to recover from the | 596 | * Probably we were not able to recover from the |
597 | * previous error. | 597 | * previous error. |
598 | * The only *reasonable* thing I can think of here | 598 | * The only *reasonable* thing I can think of here |
599 | * is soft reset. --ebs | 599 | * is soft reset. --ebs |
600 | */ | 600 | */ |
601 | iic_dev_reset(dev); | 601 | iic_dev_reset(dev); |
602 | 602 | ||
603 | if ((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE){ | 603 | if ((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE){ |
604 | DBG("%d: iic_xfer, bus is still not free\n", dev->idx); | 604 | DBG("%d: iic_xfer, bus is still not free\n", dev->idx); |
605 | return -EREMOTEIO; | 605 | return -EREMOTEIO; |
606 | } | 606 | } |
607 | } | 607 | } |
608 | else { | 608 | else { |
609 | /* Flush master data buffer (just in case) */ | 609 | /* Flush master data buffer (just in case) */ |
610 | out_8(&iic->mdcntl, in_8(&iic->mdcntl) | MDCNTL_FMDB); | 610 | out_8(&iic->mdcntl, in_8(&iic->mdcntl) | MDCNTL_FMDB); |
611 | } | 611 | } |
612 | 612 | ||
613 | /* Load slave address */ | 613 | /* Load slave address */ |
614 | iic_address(dev, &msgs[0]); | 614 | iic_address(dev, &msgs[0]); |
615 | 615 | ||
616 | /* Do real transfer */ | 616 | /* Do real transfer */ |
617 | for (i = 0; i < num && !ret; ++i) | 617 | for (i = 0; i < num && !ret; ++i) |
618 | ret = iic_xfer_bytes(dev, &msgs[i], i < num - 1); | 618 | ret = iic_xfer_bytes(dev, &msgs[i], i < num - 1); |
@@ -648,7 +648,7 @@ static inline u8 iic_clckdiv(unsigned int opb) | |||
648 | 648 | ||
649 | /* Convert to MHz */ | 649 | /* Convert to MHz */ |
650 | opb /= 1000000; | 650 | opb /= 1000000; |
651 | 651 | ||
652 | if (opb < 20 || opb > 150){ | 652 | if (opb < 20 || opb > 150){ |
653 | printk(KERN_CRIT "ibm-iic: invalid OPB clock frequency %u MHz\n", | 653 | printk(KERN_CRIT "ibm-iic: invalid OPB clock frequency %u MHz\n", |
654 | opb); | 654 | opb); |
@@ -666,7 +666,7 @@ static int __devinit iic_probe(struct ocp_device *ocp){ | |||
666 | struct i2c_adapter* adap; | 666 | struct i2c_adapter* adap; |
667 | struct ocp_func_iic_data* iic_data = ocp->def->additions; | 667 | struct ocp_func_iic_data* iic_data = ocp->def->additions; |
668 | int ret; | 668 | int ret; |
669 | 669 | ||
670 | if (!iic_data) | 670 | if (!iic_data) |
671 | printk(KERN_WARNING"ibm-iic%d: missing additional data!\n", | 671 | printk(KERN_WARNING"ibm-iic%d: missing additional data!\n", |
672 | ocp->def->index); | 672 | ocp->def->index); |
@@ -679,7 +679,7 @@ static int __devinit iic_probe(struct ocp_device *ocp){ | |||
679 | 679 | ||
680 | dev->idx = ocp->def->index; | 680 | dev->idx = ocp->def->index; |
681 | ocp_set_drvdata(ocp, dev); | 681 | ocp_set_drvdata(ocp, dev); |
682 | 682 | ||
683 | if (!request_mem_region(ocp->def->paddr, sizeof(struct iic_regs), | 683 | if (!request_mem_region(ocp->def->paddr, sizeof(struct iic_regs), |
684 | "ibm_iic")) { | 684 | "ibm_iic")) { |
685 | ret = -EBUSY; | 685 | ret = -EBUSY; |
@@ -692,7 +692,7 @@ static int __devinit iic_probe(struct ocp_device *ocp){ | |||
692 | ret = -ENXIO; | 692 | ret = -ENXIO; |
693 | goto fail2; | 693 | goto fail2; |
694 | } | 694 | } |
695 | 695 | ||
696 | init_waitqueue_head(&dev->wq); | 696 | init_waitqueue_head(&dev->wq); |
697 | 697 | ||
698 | dev->irq = iic_force_poll ? -1 : ocp->def->irq; | 698 | dev->irq = iic_force_poll ? -1 : ocp->def->irq; |
@@ -702,29 +702,29 @@ static int __devinit iic_probe(struct ocp_device *ocp){ | |||
702 | */ | 702 | */ |
703 | iic_interrupt_mode(dev, 0); | 703 | iic_interrupt_mode(dev, 0); |
704 | if (request_irq(dev->irq, iic_handler, 0, "IBM IIC", dev)){ | 704 | if (request_irq(dev->irq, iic_handler, 0, "IBM IIC", dev)){ |
705 | printk(KERN_ERR "ibm-iic%d: request_irq %d failed\n", | 705 | printk(KERN_ERR "ibm-iic%d: request_irq %d failed\n", |
706 | dev->idx, dev->irq); | 706 | dev->idx, dev->irq); |
707 | /* Fallback to the polling mode */ | 707 | /* Fallback to the polling mode */ |
708 | dev->irq = -1; | 708 | dev->irq = -1; |
709 | } | 709 | } |
710 | } | 710 | } |
711 | 711 | ||
712 | if (dev->irq < 0) | 712 | if (dev->irq < 0) |
713 | printk(KERN_WARNING "ibm-iic%d: using polling mode\n", | 713 | printk(KERN_WARNING "ibm-iic%d: using polling mode\n", |
714 | dev->idx); | 714 | dev->idx); |
715 | 715 | ||
716 | /* Board specific settings */ | 716 | /* Board specific settings */ |
717 | dev->fast_mode = iic_force_fast ? 1 : (iic_data ? iic_data->fast_mode : 0); | 717 | dev->fast_mode = iic_force_fast ? 1 : (iic_data ? iic_data->fast_mode : 0); |
718 | 718 | ||
719 | /* clckdiv is the same for *all* IIC interfaces, | 719 | /* clckdiv is the same for *all* IIC interfaces, |
720 | * but I'd rather make a copy than introduce another global. --ebs | 720 | * but I'd rather make a copy than introduce another global. --ebs |
721 | */ | 721 | */ |
722 | dev->clckdiv = iic_clckdiv(ocp_sys_info.opb_bus_freq); | 722 | dev->clckdiv = iic_clckdiv(ocp_sys_info.opb_bus_freq); |
723 | DBG("%d: clckdiv = %d\n", dev->idx, dev->clckdiv); | 723 | DBG("%d: clckdiv = %d\n", dev->idx, dev->clckdiv); |
724 | 724 | ||
725 | /* Initialize IIC interface */ | 725 | /* Initialize IIC interface */ |
726 | iic_dev_init(dev); | 726 | iic_dev_init(dev); |
727 | 727 | ||
728 | /* Register it with i2c layer */ | 728 | /* Register it with i2c layer */ |
729 | adap = &dev->adap; | 729 | adap = &dev->adap; |
730 | adap->dev.parent = &ocp->dev; | 730 | adap->dev.parent = &ocp->dev; |
@@ -736,7 +736,6 @@ static int __devinit iic_probe(struct ocp_device *ocp){ | |||
736 | adap->client_register = NULL; | 736 | adap->client_register = NULL; |
737 | adap->client_unregister = NULL; | 737 | adap->client_unregister = NULL; |
738 | adap->timeout = 1; | 738 | adap->timeout = 1; |
739 | adap->retries = 1; | ||
740 | 739 | ||
741 | /* | 740 | /* |
742 | * If "dev->idx" is negative we consider it as zero. | 741 | * If "dev->idx" is negative we consider it as zero. |
@@ -750,24 +749,24 @@ static int __devinit iic_probe(struct ocp_device *ocp){ | |||
750 | dev->idx); | 749 | dev->idx); |
751 | goto fail; | 750 | goto fail; |
752 | } | 751 | } |
753 | 752 | ||
754 | printk(KERN_INFO "ibm-iic%d: using %s mode\n", dev->idx, | 753 | printk(KERN_INFO "ibm-iic%d: using %s mode\n", dev->idx, |
755 | dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)"); | 754 | dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)"); |
756 | 755 | ||
757 | return 0; | 756 | return 0; |
758 | 757 | ||
759 | fail: | 758 | fail: |
760 | if (dev->irq >= 0){ | 759 | if (dev->irq >= 0){ |
761 | iic_interrupt_mode(dev, 0); | 760 | iic_interrupt_mode(dev, 0); |
762 | free_irq(dev->irq, dev); | 761 | free_irq(dev->irq, dev); |
763 | } | 762 | } |
764 | 763 | ||
765 | iounmap(dev->vaddr); | 764 | iounmap(dev->vaddr); |
766 | fail2: | 765 | fail2: |
767 | release_mem_region(ocp->def->paddr, sizeof(struct iic_regs)); | 766 | release_mem_region(ocp->def->paddr, sizeof(struct iic_regs)); |
768 | fail1: | 767 | fail1: |
769 | ocp_set_drvdata(ocp, NULL); | 768 | ocp_set_drvdata(ocp, NULL); |
770 | kfree(dev); | 769 | kfree(dev); |
771 | return ret; | 770 | return ret; |
772 | } | 771 | } |
773 | 772 | ||
@@ -783,13 +782,13 @@ static void __devexit iic_remove(struct ocp_device *ocp) | |||
783 | dev->idx); | 782 | dev->idx); |
784 | /* That's *very* bad, just shutdown IRQ ... */ | 783 | /* That's *very* bad, just shutdown IRQ ... */ |
785 | if (dev->irq >= 0){ | 784 | if (dev->irq >= 0){ |
786 | iic_interrupt_mode(dev, 0); | 785 | iic_interrupt_mode(dev, 0); |
787 | free_irq(dev->irq, dev); | 786 | free_irq(dev->irq, dev); |
788 | dev->irq = -1; | 787 | dev->irq = -1; |
789 | } | 788 | } |
790 | } else { | 789 | } else { |
791 | if (dev->irq >= 0){ | 790 | if (dev->irq >= 0){ |
792 | iic_interrupt_mode(dev, 0); | 791 | iic_interrupt_mode(dev, 0); |
793 | free_irq(dev->irq, dev); | 792 | free_irq(dev->irq, dev); |
794 | } | 793 | } |
795 | iounmap(dev->vaddr); | 794 | iounmap(dev->vaddr); |
@@ -798,7 +797,7 @@ static void __devexit iic_remove(struct ocp_device *ocp) | |||
798 | } | 797 | } |
799 | } | 798 | } |
800 | 799 | ||
801 | static struct ocp_device_id ibm_iic_ids[] __devinitdata = | 800 | static struct ocp_device_id ibm_iic_ids[] __devinitdata = |
802 | { | 801 | { |
803 | { .vendor = OCP_VENDOR_IBM, .function = OCP_FUNC_IIC }, | 802 | { .vendor = OCP_VENDOR_IBM, .function = OCP_FUNC_IIC }, |
804 | { .vendor = OCP_VENDOR_INVALID } | 803 | { .vendor = OCP_VENDOR_INVALID } |
diff --git a/drivers/i2c/busses/i2c-ibm_iic.h b/drivers/i2c/busses/i2c-ibm_iic.h index 59d7b437f7ff..fdaa48292cb6 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.h +++ b/drivers/i2c/busses/i2c-ibm_iic.h | |||
@@ -2,11 +2,11 @@ | |||
2 | * drivers/i2c/busses/i2c-ibm_iic.h | 2 | * drivers/i2c/busses/i2c-ibm_iic.h |
3 | * | 3 | * |
4 | * Support for the IIC peripheral on IBM PPC 4xx | 4 | * Support for the IIC peripheral on IBM PPC 4xx |
5 | * | 5 | * |
6 | * Copyright (c) 2003 Zultys Technologies. | 6 | * Copyright (c) 2003 Zultys Technologies. |
7 | * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net> | 7 | * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net> |
8 | * | 8 | * |
9 | * Based on original work by | 9 | * Based on original work by |
10 | * Ian DaSilva <idasilva@mvista.com> | 10 | * Ian DaSilva <idasilva@mvista.com> |
11 | * Armin Kuster <akuster@mvista.com> | 11 | * Armin Kuster <akuster@mvista.com> |
12 | * Matt Porter <mporter@mvista.com> | 12 | * Matt Porter <mporter@mvista.com> |
@@ -22,7 +22,7 @@ | |||
22 | #ifndef __I2C_IBM_IIC_H_ | 22 | #ifndef __I2C_IBM_IIC_H_ |
23 | #define __I2C_IBM_IIC_H_ | 23 | #define __I2C_IBM_IIC_H_ |
24 | 24 | ||
25 | #include <linux/i2c.h> | 25 | #include <linux/i2c.h> |
26 | 26 | ||
27 | struct iic_regs { | 27 | struct iic_regs { |
28 | u16 mdbuf; | 28 | u16 mdbuf; |
@@ -58,7 +58,7 @@ struct ibm_iic_private { | |||
58 | #define CNTL_TCT_MASK 0x30 | 58 | #define CNTL_TCT_MASK 0x30 |
59 | #define CNTL_TCT_SHIFT 4 | 59 | #define CNTL_TCT_SHIFT 4 |
60 | #define CNTL_RPST 0x08 | 60 | #define CNTL_RPST 0x08 |
61 | #define CNTL_CHT 0x04 | 61 | #define CNTL_CHT 0x04 |
62 | #define CNTL_RW 0x02 | 62 | #define CNTL_RW 0x02 |
63 | #define CNTL_PT 0x01 | 63 | #define CNTL_PT 0x01 |
64 | 64 | ||
diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c index c70146e4c2c0..ab41400c883e 100644 --- a/drivers/i2c/busses/i2c-iop3xx.c +++ b/drivers/i2c/busses/i2c-iop3xx.c | |||
@@ -490,7 +490,6 @@ iop3xx_i2c_probe(struct platform_device *pdev) | |||
490 | * Default values...should these come in from board code? | 490 | * Default values...should these come in from board code? |
491 | */ | 491 | */ |
492 | new_adapter->timeout = 100; | 492 | new_adapter->timeout = 100; |
493 | new_adapter->retries = 3; | ||
494 | new_adapter->algo = &iop3xx_i2c_algo; | 493 | new_adapter->algo = &iop3xx_i2c_algo; |
495 | 494 | ||
496 | init_waitqueue_head(&adapter_data->waitq); | 495 | init_waitqueue_head(&adapter_data->waitq); |
diff --git a/drivers/i2c/busses/i2c-ixp4xx.c b/drivers/i2c/busses/i2c-ixp4xx.c deleted file mode 100644 index 069ed7f3b395..000000000000 --- a/drivers/i2c/busses/i2c-ixp4xx.c +++ /dev/null | |||
@@ -1,178 +0,0 @@ | |||
1 | /* | ||
2 | * drivers/i2c/busses/i2c-ixp4xx.c | ||
3 | * | ||
4 | * Intel's IXP4xx XScale NPU chipsets (IXP420, 421, 422, 425) do not have | ||
5 | * an on board I2C controller but provide 16 GPIO pins that are often | ||
6 | * used to create an I2C bus. This driver provides an i2c_adapter | ||
7 | * interface that plugs in under algo_bit and drives the GPIO pins | ||
8 | * as instructed by the alogorithm driver. | ||
9 | * | ||
10 | * Author: Deepak Saxena <dsaxena@plexity.net> | ||
11 | * | ||
12 | * Copyright (c) 2003-2004 MontaVista Software Inc. | ||
13 | * | ||
14 | * This file is licensed under the terms of the GNU General Public | ||
15 | * License version 2. This program is licensed "as is" without any | ||
16 | * warranty of any kind, whether express or implied. | ||
17 | * | ||
18 | * NOTE: Since different platforms will use different GPIO pins for | ||
19 | * I2C, this driver uses an IXP4xx-specific platform_data | ||
20 | * pointer to pass the GPIO numbers to the driver. This | ||
21 | * allows us to support all the different IXP4xx platforms | ||
22 | * w/o having to put #ifdefs in this driver. | ||
23 | * | ||
24 | * See arch/arm/mach-ixp4xx/ixdp425.c for an example of building a | ||
25 | * device list and filling in the ixp4xx_i2c_pins data structure | ||
26 | * that is passed as the platform_data to this driver. | ||
27 | */ | ||
28 | |||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/init.h> | ||
31 | #include <linux/platform_device.h> | ||
32 | #include <linux/module.h> | ||
33 | #include <linux/i2c.h> | ||
34 | #include <linux/i2c-algo-bit.h> | ||
35 | |||
36 | #include <asm/hardware.h> /* Pick up IXP4xx-specific bits */ | ||
37 | |||
38 | static inline int ixp4xx_scl_pin(void *data) | ||
39 | { | ||
40 | return ((struct ixp4xx_i2c_pins*)data)->scl_pin; | ||
41 | } | ||
42 | |||
43 | static inline int ixp4xx_sda_pin(void *data) | ||
44 | { | ||
45 | return ((struct ixp4xx_i2c_pins*)data)->sda_pin; | ||
46 | } | ||
47 | |||
48 | static void ixp4xx_bit_setscl(void *data, int val) | ||
49 | { | ||
50 | gpio_line_set(ixp4xx_scl_pin(data), 0); | ||
51 | gpio_line_config(ixp4xx_scl_pin(data), | ||
52 | val ? IXP4XX_GPIO_IN : IXP4XX_GPIO_OUT ); | ||
53 | } | ||
54 | |||
55 | static void ixp4xx_bit_setsda(void *data, int val) | ||
56 | { | ||
57 | gpio_line_set(ixp4xx_sda_pin(data), 0); | ||
58 | gpio_line_config(ixp4xx_sda_pin(data), | ||
59 | val ? IXP4XX_GPIO_IN : IXP4XX_GPIO_OUT ); | ||
60 | } | ||
61 | |||
62 | static int ixp4xx_bit_getscl(void *data) | ||
63 | { | ||
64 | int scl; | ||
65 | |||
66 | gpio_line_config(ixp4xx_scl_pin(data), IXP4XX_GPIO_IN ); | ||
67 | gpio_line_get(ixp4xx_scl_pin(data), &scl); | ||
68 | |||
69 | return scl; | ||
70 | } | ||
71 | |||
72 | static int ixp4xx_bit_getsda(void *data) | ||
73 | { | ||
74 | int sda; | ||
75 | |||
76 | gpio_line_config(ixp4xx_sda_pin(data), IXP4XX_GPIO_IN ); | ||
77 | gpio_line_get(ixp4xx_sda_pin(data), &sda); | ||
78 | |||
79 | return sda; | ||
80 | } | ||
81 | |||
82 | struct ixp4xx_i2c_data { | ||
83 | struct ixp4xx_i2c_pins *gpio_pins; | ||
84 | struct i2c_adapter adapter; | ||
85 | struct i2c_algo_bit_data algo_data; | ||
86 | }; | ||
87 | |||
88 | static int ixp4xx_i2c_remove(struct platform_device *plat_dev) | ||
89 | { | ||
90 | struct ixp4xx_i2c_data *drv_data = platform_get_drvdata(plat_dev); | ||
91 | |||
92 | platform_set_drvdata(plat_dev, NULL); | ||
93 | |||
94 | i2c_del_adapter(&drv_data->adapter); | ||
95 | |||
96 | kfree(drv_data); | ||
97 | |||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | static int ixp4xx_i2c_probe(struct platform_device *plat_dev) | ||
102 | { | ||
103 | int err; | ||
104 | struct ixp4xx_i2c_pins *gpio = plat_dev->dev.platform_data; | ||
105 | struct ixp4xx_i2c_data *drv_data = | ||
106 | kzalloc(sizeof(struct ixp4xx_i2c_data), GFP_KERNEL); | ||
107 | |||
108 | if(!drv_data) | ||
109 | return -ENOMEM; | ||
110 | |||
111 | drv_data->gpio_pins = gpio; | ||
112 | |||
113 | /* | ||
114 | * We could make a lot of these structures static, but | ||
115 | * certain platforms may have multiple GPIO-based I2C | ||
116 | * buses for various device domains, so we need per-device | ||
117 | * algo_data->data. | ||
118 | */ | ||
119 | drv_data->algo_data.data = gpio; | ||
120 | drv_data->algo_data.setsda = ixp4xx_bit_setsda; | ||
121 | drv_data->algo_data.setscl = ixp4xx_bit_setscl; | ||
122 | drv_data->algo_data.getsda = ixp4xx_bit_getsda; | ||
123 | drv_data->algo_data.getscl = ixp4xx_bit_getscl; | ||
124 | drv_data->algo_data.udelay = 10; | ||
125 | drv_data->algo_data.timeout = 100; | ||
126 | |||
127 | drv_data->adapter.id = I2C_HW_B_IXP4XX; | ||
128 | drv_data->adapter.class = I2C_CLASS_HWMON; | ||
129 | strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name, | ||
130 | sizeof(drv_data->adapter.name)); | ||
131 | drv_data->adapter.algo_data = &drv_data->algo_data; | ||
132 | |||
133 | drv_data->adapter.dev.parent = &plat_dev->dev; | ||
134 | |||
135 | gpio_line_config(gpio->scl_pin, IXP4XX_GPIO_IN); | ||
136 | gpio_line_config(gpio->sda_pin, IXP4XX_GPIO_IN); | ||
137 | gpio_line_set(gpio->scl_pin, 0); | ||
138 | gpio_line_set(gpio->sda_pin, 0); | ||
139 | |||
140 | err = i2c_bit_add_bus(&drv_data->adapter); | ||
141 | if (err) { | ||
142 | printk(KERN_ERR "ERROR: Could not install %s\n", plat_dev->dev.bus_id); | ||
143 | |||
144 | kfree(drv_data); | ||
145 | return err; | ||
146 | } | ||
147 | |||
148 | platform_set_drvdata(plat_dev, drv_data); | ||
149 | |||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | static struct platform_driver ixp4xx_i2c_driver = { | ||
154 | .probe = ixp4xx_i2c_probe, | ||
155 | .remove = ixp4xx_i2c_remove, | ||
156 | .driver = { | ||
157 | .name = "IXP4XX-I2C", | ||
158 | .owner = THIS_MODULE, | ||
159 | }, | ||
160 | }; | ||
161 | |||
162 | static int __init ixp4xx_i2c_init(void) | ||
163 | { | ||
164 | return platform_driver_register(&ixp4xx_i2c_driver); | ||
165 | } | ||
166 | |||
167 | static void __exit ixp4xx_i2c_exit(void) | ||
168 | { | ||
169 | platform_driver_unregister(&ixp4xx_i2c_driver); | ||
170 | } | ||
171 | |||
172 | module_init(ixp4xx_i2c_init); | ||
173 | module_exit(ixp4xx_i2c_exit); | ||
174 | |||
175 | MODULE_DESCRIPTION("GPIO-based I2C adapter for IXP4xx systems"); | ||
176 | MODULE_LICENSE("GPL"); | ||
177 | MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>"); | ||
178 | |||
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index d8de4ac88b7d..bbe787b243b7 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c | |||
@@ -180,7 +180,7 @@ static void mpc_i2c_stop(struct mpc_i2c *i2c) | |||
180 | static int mpc_write(struct mpc_i2c *i2c, int target, | 180 | static int mpc_write(struct mpc_i2c *i2c, int target, |
181 | const u8 * data, int length, int restart) | 181 | const u8 * data, int length, int restart) |
182 | { | 182 | { |
183 | int i; | 183 | int i, result; |
184 | unsigned timeout = i2c->adap.timeout; | 184 | unsigned timeout = i2c->adap.timeout; |
185 | u32 flags = restart ? CCR_RSTA : 0; | 185 | u32 flags = restart ? CCR_RSTA : 0; |
186 | 186 | ||
@@ -192,15 +192,17 @@ static int mpc_write(struct mpc_i2c *i2c, int target, | |||
192 | /* Write target byte */ | 192 | /* Write target byte */ |
193 | writeb((target << 1), i2c->base + MPC_I2C_DR); | 193 | writeb((target << 1), i2c->base + MPC_I2C_DR); |
194 | 194 | ||
195 | if (i2c_wait(i2c, timeout, 1) < 0) | 195 | result = i2c_wait(i2c, timeout, 1); |
196 | return -1; | 196 | if (result < 0) |
197 | return result; | ||
197 | 198 | ||
198 | for (i = 0; i < length; i++) { | 199 | for (i = 0; i < length; i++) { |
199 | /* Write data byte */ | 200 | /* Write data byte */ |
200 | writeb(data[i], i2c->base + MPC_I2C_DR); | 201 | writeb(data[i], i2c->base + MPC_I2C_DR); |
201 | 202 | ||
202 | if (i2c_wait(i2c, timeout, 1) < 0) | 203 | result = i2c_wait(i2c, timeout, 1); |
203 | return -1; | 204 | if (result < 0) |
205 | return result; | ||
204 | } | 206 | } |
205 | 207 | ||
206 | return 0; | 208 | return 0; |
@@ -210,7 +212,7 @@ static int mpc_read(struct mpc_i2c *i2c, int target, | |||
210 | u8 * data, int length, int restart) | 212 | u8 * data, int length, int restart) |
211 | { | 213 | { |
212 | unsigned timeout = i2c->adap.timeout; | 214 | unsigned timeout = i2c->adap.timeout; |
213 | int i; | 215 | int i, result; |
214 | u32 flags = restart ? CCR_RSTA : 0; | 216 | u32 flags = restart ? CCR_RSTA : 0; |
215 | 217 | ||
216 | /* Start with MEN */ | 218 | /* Start with MEN */ |
@@ -221,8 +223,9 @@ static int mpc_read(struct mpc_i2c *i2c, int target, | |||
221 | /* Write target address byte - this time with the read flag set */ | 223 | /* Write target address byte - this time with the read flag set */ |
222 | writeb((target << 1) | 1, i2c->base + MPC_I2C_DR); | 224 | writeb((target << 1) | 1, i2c->base + MPC_I2C_DR); |
223 | 225 | ||
224 | if (i2c_wait(i2c, timeout, 1) < 0) | 226 | result = i2c_wait(i2c, timeout, 1); |
225 | return -1; | 227 | if (result < 0) |
228 | return result; | ||
226 | 229 | ||
227 | if (length) { | 230 | if (length) { |
228 | if (length == 1) | 231 | if (length == 1) |
@@ -234,8 +237,9 @@ static int mpc_read(struct mpc_i2c *i2c, int target, | |||
234 | } | 237 | } |
235 | 238 | ||
236 | for (i = 0; i < length; i++) { | 239 | for (i = 0; i < length; i++) { |
237 | if (i2c_wait(i2c, timeout, 0) < 0) | 240 | result = i2c_wait(i2c, timeout, 0); |
238 | return -1; | 241 | if (result < 0) |
242 | return result; | ||
239 | 243 | ||
240 | /* Generate txack on next to last byte */ | 244 | /* Generate txack on next to last byte */ |
241 | if (i == length - 2) | 245 | if (i == length - 2) |
@@ -309,7 +313,6 @@ static struct i2c_adapter mpc_ops = { | |||
309 | .algo = &mpc_algo, | 313 | .algo = &mpc_algo, |
310 | .class = I2C_CLASS_HWMON, | 314 | .class = I2C_CLASS_HWMON, |
311 | .timeout = 1, | 315 | .timeout = 1, |
312 | .retries = 1 | ||
313 | }; | 316 | }; |
314 | 317 | ||
315 | static int fsl_i2c_probe(struct platform_device *pdev) | 318 | static int fsl_i2c_probe(struct platform_device *pdev) |
@@ -321,9 +324,9 @@ static int fsl_i2c_probe(struct platform_device *pdev) | |||
321 | 324 | ||
322 | pdata = (struct fsl_i2c_platform_data *) pdev->dev.platform_data; | 325 | pdata = (struct fsl_i2c_platform_data *) pdev->dev.platform_data; |
323 | 326 | ||
324 | if (!(i2c = kzalloc(sizeof(*i2c), GFP_KERNEL))) { | 327 | i2c = kzalloc(sizeof(*i2c), GFP_KERNEL); |
328 | if (!i2c) | ||
325 | return -ENOMEM; | 329 | return -ENOMEM; |
326 | } | ||
327 | 330 | ||
328 | i2c->irq = platform_get_irq(pdev, 0); | 331 | i2c->irq = platform_get_irq(pdev, 0); |
329 | if (i2c->irq < 0) { | 332 | if (i2c->irq < 0) { |
diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c index 1bf590c74166..3dac920e53ea 100644 --- a/drivers/i2c/busses/i2c-nforce2.c +++ b/drivers/i2c/busses/i2c-nforce2.c | |||
@@ -351,6 +351,7 @@ static int __devinit nforce2_probe(struct pci_dev *dev, const struct pci_device_ | |||
351 | pci_set_drvdata(dev, smbuses); | 351 | pci_set_drvdata(dev, smbuses); |
352 | 352 | ||
353 | switch(dev->device) { | 353 | switch(dev->device) { |
354 | case PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS: | ||
354 | case PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SMBUS: | 355 | case PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SMBUS: |
355 | case PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS: | 356 | case PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS: |
356 | smbuses[0].blockops = 1; | 357 | smbuses[0].blockops = 1; |
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index f2552b19ea60..da6639707ea3 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c | |||
@@ -362,8 +362,6 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) | |||
362 | 362 | ||
363 | omap_i2c_enable_clocks(dev); | 363 | omap_i2c_enable_clocks(dev); |
364 | 364 | ||
365 | /* REVISIT: initialize and use adap->retries. This is an optional | ||
366 | * feature */ | ||
367 | if ((r = omap_i2c_wait_for_bb(dev)) < 0) | 365 | if ((r = omap_i2c_wait_for_bb(dev)) < 0) |
368 | goto out; | 366 | goto out; |
369 | 367 | ||
diff --git a/drivers/i2c/busses/i2c-pasemi.c b/drivers/i2c/busses/i2c-pasemi.c index ca18e0be4901..1603c81e39d4 100644 --- a/drivers/i2c/busses/i2c-pasemi.c +++ b/drivers/i2c/busses/i2c-pasemi.c | |||
@@ -368,6 +368,7 @@ static int __devinit pasemi_smb_probe(struct pci_dev *dev, | |||
368 | smbus->adapter.class = I2C_CLASS_HWMON; | 368 | smbus->adapter.class = I2C_CLASS_HWMON; |
369 | smbus->adapter.algo = &smbus_algorithm; | 369 | smbus->adapter.algo = &smbus_algorithm; |
370 | smbus->adapter.algo_data = smbus; | 370 | smbus->adapter.algo_data = smbus; |
371 | smbus->adapter.nr = PCI_FUNC(dev->devfn); | ||
371 | 372 | ||
372 | /* set up the sysfs linkage to our parent device */ | 373 | /* set up the sysfs linkage to our parent device */ |
373 | smbus->adapter.dev.parent = &dev->dev; | 374 | smbus->adapter.dev.parent = &dev->dev; |
@@ -375,7 +376,7 @@ static int __devinit pasemi_smb_probe(struct pci_dev *dev, | |||
375 | reg_write(smbus, REG_CTL, (CTL_MTR | CTL_MRR | | 376 | reg_write(smbus, REG_CTL, (CTL_MTR | CTL_MRR | |
376 | (CLK_100K_DIV & CTL_CLK_M))); | 377 | (CLK_100K_DIV & CTL_CLK_M))); |
377 | 378 | ||
378 | error = i2c_add_adapter(&smbus->adapter); | 379 | error = i2c_add_numbered_adapter(&smbus->adapter); |
379 | if (error) | 380 | if (error) |
380 | goto out_release_region; | 381 | goto out_release_region; |
381 | 382 | ||
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 167e4137ee21..9bbe96cef719 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c | |||
@@ -121,10 +121,6 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, | |||
121 | { | 121 | { |
122 | unsigned char temp; | 122 | unsigned char temp; |
123 | 123 | ||
124 | /* match up the function */ | ||
125 | if (PCI_FUNC(PIIX4_dev->devfn) != id->driver_data) | ||
126 | return -ENODEV; | ||
127 | |||
128 | dev_info(&PIIX4_dev->dev, "Found %s device\n", pci_name(PIIX4_dev)); | 124 | dev_info(&PIIX4_dev->dev, "Found %s device\n", pci_name(PIIX4_dev)); |
129 | 125 | ||
130 | /* Don't access SMBus on IBM systems which get corrupted eeproms */ | 126 | /* Don't access SMBus on IBM systems which get corrupted eeproms */ |
@@ -389,28 +385,21 @@ static struct i2c_adapter piix4_adapter = { | |||
389 | }; | 385 | }; |
390 | 386 | ||
391 | static struct pci_device_id piix4_ids[] = { | 387 | static struct pci_device_id piix4_ids[] = { |
392 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3), | 388 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3) }, |
393 | .driver_data = 3 }, | 389 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3) }, |
394 | { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP200_SMBUS), | 390 | { PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_3) }, |
395 | .driver_data = 0 }, | 391 | { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP200_SMBUS) }, |
396 | { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_SMBUS), | 392 | { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_SMBUS) }, |
397 | .driver_data = 0 }, | 393 | { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_SMBUS) }, |
398 | { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_SMBUS), | 394 | { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS) }, |
399 | .driver_data = 0 }, | 395 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, |
400 | { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS), | 396 | PCI_DEVICE_ID_SERVERWORKS_OSB4) }, |
401 | .driver_data = 0 }, | 397 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, |
402 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4), | 398 | PCI_DEVICE_ID_SERVERWORKS_CSB5) }, |
403 | .driver_data = 0 }, | 399 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, |
404 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5), | 400 | PCI_DEVICE_ID_SERVERWORKS_CSB6) }, |
405 | .driver_data = 0 }, | 401 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, |
406 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6), | 402 | PCI_DEVICE_ID_SERVERWORKS_HT1000SB) }, |
407 | .driver_data = 0 }, | ||
408 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000SB), | ||
409 | .driver_data = 0 }, | ||
410 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3), | ||
411 | .driver_data = 3 }, | ||
412 | { PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_3), | ||
413 | .driver_data = 0 }, | ||
414 | { 0, } | 403 | { 0, } |
415 | }; | 404 | }; |
416 | 405 | ||
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 6426a61f8d4d..2598d29fd7a4 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c | |||
@@ -65,6 +65,7 @@ struct pxa_i2c { | |||
65 | unsigned long iosize; | 65 | unsigned long iosize; |
66 | 66 | ||
67 | int irq; | 67 | int irq; |
68 | int use_pio; | ||
68 | }; | 69 | }; |
69 | 70 | ||
70 | #define _IBMR(i2c) ((i2c)->reg_base + 0) | 71 | #define _IBMR(i2c) ((i2c)->reg_base + 0) |
@@ -163,6 +164,7 @@ static void i2c_pxa_show_state(struct pxa_i2c *i2c, int lno, const char *fname) | |||
163 | #define eedbg(lvl, x...) do { if ((lvl) < 1) { printk(KERN_DEBUG "" x); } } while(0) | 164 | #define eedbg(lvl, x...) do { if ((lvl) < 1) { printk(KERN_DEBUG "" x); } } while(0) |
164 | 165 | ||
165 | static void i2c_pxa_master_complete(struct pxa_i2c *i2c, int ret); | 166 | static void i2c_pxa_master_complete(struct pxa_i2c *i2c, int ret); |
167 | static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id); | ||
166 | 168 | ||
167 | static void i2c_pxa_scream_blue_murder(struct pxa_i2c *i2c, const char *why) | 169 | static void i2c_pxa_scream_blue_murder(struct pxa_i2c *i2c, const char *why) |
168 | { | 170 | { |
@@ -554,6 +556,71 @@ static inline void i2c_pxa_stop_message(struct pxa_i2c *i2c) | |||
554 | writel(icr, _ICR(i2c)); | 556 | writel(icr, _ICR(i2c)); |
555 | } | 557 | } |
556 | 558 | ||
559 | static int i2c_pxa_pio_set_master(struct pxa_i2c *i2c) | ||
560 | { | ||
561 | /* make timeout the same as for interrupt based functions */ | ||
562 | long timeout = 2 * DEF_TIMEOUT; | ||
563 | |||
564 | /* | ||
565 | * Wait for the bus to become free. | ||
566 | */ | ||
567 | while (timeout-- && readl(_ISR(i2c)) & (ISR_IBB | ISR_UB)) { | ||
568 | udelay(1000); | ||
569 | show_state(i2c); | ||
570 | } | ||
571 | |||
572 | if (timeout <= 0) { | ||
573 | show_state(i2c); | ||
574 | dev_err(&i2c->adap.dev, | ||
575 | "i2c_pxa: timeout waiting for bus free\n"); | ||
576 | return I2C_RETRY; | ||
577 | } | ||
578 | |||
579 | /* | ||
580 | * Set master mode. | ||
581 | */ | ||
582 | writel(readl(_ICR(i2c)) | ICR_SCLE, _ICR(i2c)); | ||
583 | |||
584 | return 0; | ||
585 | } | ||
586 | |||
587 | static int i2c_pxa_do_pio_xfer(struct pxa_i2c *i2c, | ||
588 | struct i2c_msg *msg, int num) | ||
589 | { | ||
590 | unsigned long timeout = 500000; /* 5 seconds */ | ||
591 | int ret = 0; | ||
592 | |||
593 | ret = i2c_pxa_pio_set_master(i2c); | ||
594 | if (ret) | ||
595 | goto out; | ||
596 | |||
597 | i2c->msg = msg; | ||
598 | i2c->msg_num = num; | ||
599 | i2c->msg_idx = 0; | ||
600 | i2c->msg_ptr = 0; | ||
601 | i2c->irqlogidx = 0; | ||
602 | |||
603 | i2c_pxa_start_message(i2c); | ||
604 | |||
605 | while (timeout-- && i2c->msg_num > 0) { | ||
606 | i2c_pxa_handler(0, i2c); | ||
607 | udelay(10); | ||
608 | } | ||
609 | |||
610 | i2c_pxa_stop_message(i2c); | ||
611 | |||
612 | /* | ||
613 | * We place the return code in i2c->msg_idx. | ||
614 | */ | ||
615 | ret = i2c->msg_idx; | ||
616 | |||
617 | out: | ||
618 | if (timeout == 0) | ||
619 | i2c_pxa_scream_blue_murder(i2c, "timeout"); | ||
620 | |||
621 | return ret; | ||
622 | } | ||
623 | |||
557 | /* | 624 | /* |
558 | * We are protected by the adapter bus mutex. | 625 | * We are protected by the adapter bus mutex. |
559 | */ | 626 | */ |
@@ -610,6 +677,35 @@ static int i2c_pxa_do_xfer(struct pxa_i2c *i2c, struct i2c_msg *msg, int num) | |||
610 | return ret; | 677 | return ret; |
611 | } | 678 | } |
612 | 679 | ||
680 | static int i2c_pxa_pio_xfer(struct i2c_adapter *adap, | ||
681 | struct i2c_msg msgs[], int num) | ||
682 | { | ||
683 | struct pxa_i2c *i2c = adap->algo_data; | ||
684 | int ret, i; | ||
685 | |||
686 | /* If the I2C controller is disabled we need to reset it | ||
687 | (probably due to a suspend/resume destroying state). We do | ||
688 | this here as we can then avoid worrying about resuming the | ||
689 | controller before its users. */ | ||
690 | if (!(readl(_ICR(i2c)) & ICR_IUE)) | ||
691 | i2c_pxa_reset(i2c); | ||
692 | |||
693 | for (i = adap->retries; i >= 0; i--) { | ||
694 | ret = i2c_pxa_do_pio_xfer(i2c, msgs, num); | ||
695 | if (ret != I2C_RETRY) | ||
696 | goto out; | ||
697 | |||
698 | if (i2c_debug) | ||
699 | dev_dbg(&adap->dev, "Retrying transmission\n"); | ||
700 | udelay(100); | ||
701 | } | ||
702 | i2c_pxa_scream_blue_murder(i2c, "exhausted retries"); | ||
703 | ret = -EREMOTEIO; | ||
704 | out: | ||
705 | i2c_pxa_set_slave(i2c, ret); | ||
706 | return ret; | ||
707 | } | ||
708 | |||
613 | /* | 709 | /* |
614 | * i2c_pxa_master_complete - complete the message and wake up. | 710 | * i2c_pxa_master_complete - complete the message and wake up. |
615 | */ | 711 | */ |
@@ -621,7 +717,8 @@ static void i2c_pxa_master_complete(struct pxa_i2c *i2c, int ret) | |||
621 | i2c->msg_num = 0; | 717 | i2c->msg_num = 0; |
622 | if (ret) | 718 | if (ret) |
623 | i2c->msg_idx = ret; | 719 | i2c->msg_idx = ret; |
624 | wake_up(&i2c->wait); | 720 | if (!i2c->use_pio) |
721 | wake_up(&i2c->wait); | ||
625 | } | 722 | } |
626 | 723 | ||
627 | static void i2c_pxa_irq_txempty(struct pxa_i2c *i2c, u32 isr) | 724 | static void i2c_pxa_irq_txempty(struct pxa_i2c *i2c, u32 isr) |
@@ -840,6 +937,37 @@ static const struct i2c_algorithm i2c_pxa_algorithm = { | |||
840 | .functionality = i2c_pxa_functionality, | 937 | .functionality = i2c_pxa_functionality, |
841 | }; | 938 | }; |
842 | 939 | ||
940 | static const struct i2c_algorithm i2c_pxa_pio_algorithm = { | ||
941 | .master_xfer = i2c_pxa_pio_xfer, | ||
942 | .functionality = i2c_pxa_functionality, | ||
943 | }; | ||
944 | |||
945 | static void i2c_pxa_enable(struct platform_device *dev) | ||
946 | { | ||
947 | if (cpu_is_pxa27x()) { | ||
948 | switch (dev->id) { | ||
949 | case 0: | ||
950 | pxa_gpio_mode(GPIO117_I2CSCL_MD); | ||
951 | pxa_gpio_mode(GPIO118_I2CSDA_MD); | ||
952 | break; | ||
953 | case 1: | ||
954 | local_irq_disable(); | ||
955 | PCFR |= PCFR_PI2CEN; | ||
956 | local_irq_enable(); | ||
957 | break; | ||
958 | } | ||
959 | } | ||
960 | } | ||
961 | |||
962 | static void i2c_pxa_disable(struct platform_device *dev) | ||
963 | { | ||
964 | if (cpu_is_pxa27x() && dev->id == 1) { | ||
965 | local_irq_disable(); | ||
966 | PCFR &= ~PCFR_PI2CEN; | ||
967 | local_irq_enable(); | ||
968 | } | ||
969 | } | ||
970 | |||
843 | #define res_len(r) ((r)->end - (r)->start + 1) | 971 | #define res_len(r) ((r)->end - (r)->start + 1) |
844 | static int i2c_pxa_probe(struct platform_device *dev) | 972 | static int i2c_pxa_probe(struct platform_device *dev) |
845 | { | 973 | { |
@@ -864,7 +992,6 @@ static int i2c_pxa_probe(struct platform_device *dev) | |||
864 | } | 992 | } |
865 | 993 | ||
866 | i2c->adap.owner = THIS_MODULE; | 994 | i2c->adap.owner = THIS_MODULE; |
867 | i2c->adap.algo = &i2c_pxa_algorithm; | ||
868 | i2c->adap.retries = 5; | 995 | i2c->adap.retries = 5; |
869 | 996 | ||
870 | spin_lock_init(&i2c->lock); | 997 | spin_lock_init(&i2c->lock); |
@@ -899,34 +1026,28 @@ static int i2c_pxa_probe(struct platform_device *dev) | |||
899 | #endif | 1026 | #endif |
900 | 1027 | ||
901 | clk_enable(i2c->clk); | 1028 | clk_enable(i2c->clk); |
902 | #ifdef CONFIG_PXA27x | 1029 | i2c_pxa_enable(dev); |
903 | switch (dev->id) { | ||
904 | case 0: | ||
905 | pxa_gpio_mode(GPIO117_I2CSCL_MD); | ||
906 | pxa_gpio_mode(GPIO118_I2CSDA_MD); | ||
907 | break; | ||
908 | case 1: | ||
909 | local_irq_disable(); | ||
910 | PCFR |= PCFR_PI2CEN; | ||
911 | local_irq_enable(); | ||
912 | } | ||
913 | #endif | ||
914 | 1030 | ||
915 | ret = request_irq(irq, i2c_pxa_handler, IRQF_DISABLED, | 1031 | if (plat) { |
916 | i2c->adap.name, i2c); | 1032 | i2c->adap.class = plat->class; |
917 | if (ret) | 1033 | i2c->use_pio = plat->use_pio; |
918 | goto ereqirq; | 1034 | } |
919 | 1035 | ||
1036 | if (i2c->use_pio) { | ||
1037 | i2c->adap.algo = &i2c_pxa_pio_algorithm; | ||
1038 | } else { | ||
1039 | i2c->adap.algo = &i2c_pxa_algorithm; | ||
1040 | ret = request_irq(irq, i2c_pxa_handler, IRQF_DISABLED, | ||
1041 | i2c->adap.name, i2c); | ||
1042 | if (ret) | ||
1043 | goto ereqirq; | ||
1044 | } | ||
920 | 1045 | ||
921 | i2c_pxa_reset(i2c); | 1046 | i2c_pxa_reset(i2c); |
922 | 1047 | ||
923 | i2c->adap.algo_data = i2c; | 1048 | i2c->adap.algo_data = i2c; |
924 | i2c->adap.dev.parent = &dev->dev; | 1049 | i2c->adap.dev.parent = &dev->dev; |
925 | 1050 | ||
926 | if (plat) { | ||
927 | i2c->adap.class = plat->class; | ||
928 | } | ||
929 | |||
930 | /* | 1051 | /* |
931 | * If "dev->id" is negative we consider it as zero. | 1052 | * If "dev->id" is negative we consider it as zero. |
932 | * The reason to do so is to avoid sysfs names that only make | 1053 | * The reason to do so is to avoid sysfs names that only make |
@@ -952,17 +1073,11 @@ static int i2c_pxa_probe(struct platform_device *dev) | |||
952 | return 0; | 1073 | return 0; |
953 | 1074 | ||
954 | eadapt: | 1075 | eadapt: |
955 | free_irq(irq, i2c); | 1076 | if (!i2c->use_pio) |
1077 | free_irq(irq, i2c); | ||
956 | ereqirq: | 1078 | ereqirq: |
957 | clk_disable(i2c->clk); | 1079 | clk_disable(i2c->clk); |
958 | 1080 | i2c_pxa_disable(dev); | |
959 | #ifdef CONFIG_PXA27x | ||
960 | if (dev->id == 1) { | ||
961 | local_irq_disable(); | ||
962 | PCFR &= ~PCFR_PI2CEN; | ||
963 | local_irq_enable(); | ||
964 | } | ||
965 | #endif | ||
966 | eremap: | 1081 | eremap: |
967 | clk_put(i2c->clk); | 1082 | clk_put(i2c->clk); |
968 | eclk: | 1083 | eclk: |
@@ -979,18 +1094,12 @@ static int i2c_pxa_remove(struct platform_device *dev) | |||
979 | platform_set_drvdata(dev, NULL); | 1094 | platform_set_drvdata(dev, NULL); |
980 | 1095 | ||
981 | i2c_del_adapter(&i2c->adap); | 1096 | i2c_del_adapter(&i2c->adap); |
982 | free_irq(i2c->irq, i2c); | 1097 | if (!i2c->use_pio) |
1098 | free_irq(i2c->irq, i2c); | ||
983 | 1099 | ||
984 | clk_disable(i2c->clk); | 1100 | clk_disable(i2c->clk); |
985 | clk_put(i2c->clk); | 1101 | clk_put(i2c->clk); |
986 | 1102 | i2c_pxa_disable(dev); | |
987 | #ifdef CONFIG_PXA27x | ||
988 | if (dev->id == 1) { | ||
989 | local_irq_disable(); | ||
990 | PCFR &= ~PCFR_PI2CEN; | ||
991 | local_irq_enable(); | ||
992 | } | ||
993 | #endif | ||
994 | 1103 | ||
995 | release_mem_region(i2c->iobase, i2c->iosize); | 1104 | release_mem_region(i2c->iobase, i2c->iosize); |
996 | kfree(i2c); | 1105 | kfree(i2c); |
diff --git a/drivers/i2c/busses/i2c-sibyte.c b/drivers/i2c/busses/i2c-sibyte.c index 503a134ec803..8fbbdb4c2f35 100644 --- a/drivers/i2c/busses/i2c-sibyte.c +++ b/drivers/i2c/busses/i2c-sibyte.c | |||
@@ -36,14 +36,6 @@ struct i2c_algo_sibyte_data { | |||
36 | /* ----- global defines ----------------------------------------------- */ | 36 | /* ----- global defines ----------------------------------------------- */ |
37 | #define SMB_CSR(a,r) ((long)(a->reg_base + r)) | 37 | #define SMB_CSR(a,r) ((long)(a->reg_base + r)) |
38 | 38 | ||
39 | /* ----- global variables --------------------------------------------- */ | ||
40 | |||
41 | /* module parameters: | ||
42 | */ | ||
43 | static int bit_scan; /* have a look at what's hanging 'round */ | ||
44 | module_param(bit_scan, int, 0); | ||
45 | MODULE_PARM_DESC(bit_scan, "Scan for active chips on the bus"); | ||
46 | |||
47 | 39 | ||
48 | static int smbus_xfer(struct i2c_adapter *i2c_adap, u16 addr, | 40 | static int smbus_xfer(struct i2c_adapter *i2c_adap, u16 addr, |
49 | unsigned short flags, char read_write, | 41 | unsigned short flags, char read_write, |
@@ -140,9 +132,8 @@ static const struct i2c_algorithm i2c_sibyte_algo = { | |||
140 | /* | 132 | /* |
141 | * registering functions to load algorithms at runtime | 133 | * registering functions to load algorithms at runtime |
142 | */ | 134 | */ |
143 | int i2c_sibyte_add_bus(struct i2c_adapter *i2c_adap, int speed) | 135 | int __init i2c_sibyte_add_bus(struct i2c_adapter *i2c_adap, int speed) |
144 | { | 136 | { |
145 | int i; | ||
146 | struct i2c_algo_sibyte_data *adap = i2c_adap->algo_data; | 137 | struct i2c_algo_sibyte_data *adap = i2c_adap->algo_data; |
147 | 138 | ||
148 | /* register new adapter to i2c module... */ | 139 | /* register new adapter to i2c module... */ |
@@ -152,24 +143,6 @@ int i2c_sibyte_add_bus(struct i2c_adapter *i2c_adap, int speed) | |||
152 | csr_out32(speed, SMB_CSR(adap,R_SMB_FREQ)); | 143 | csr_out32(speed, SMB_CSR(adap,R_SMB_FREQ)); |
153 | csr_out32(0, SMB_CSR(adap,R_SMB_CONTROL)); | 144 | csr_out32(0, SMB_CSR(adap,R_SMB_CONTROL)); |
154 | 145 | ||
155 | /* scan bus */ | ||
156 | if (bit_scan) { | ||
157 | union i2c_smbus_data data; | ||
158 | int rc; | ||
159 | printk(KERN_INFO " i2c-algo-sibyte.o: scanning bus %s.\n", | ||
160 | i2c_adap->name); | ||
161 | for (i = 0x00; i < 0x7f; i++) { | ||
162 | /* XXXKW is this a realistic probe? */ | ||
163 | rc = smbus_xfer(i2c_adap, i, 0, I2C_SMBUS_READ, 0, | ||
164 | I2C_SMBUS_BYTE_DATA, &data); | ||
165 | if (!rc) { | ||
166 | printk("(%02x)",i); | ||
167 | } else | ||
168 | printk("."); | ||
169 | } | ||
170 | printk("\n"); | ||
171 | } | ||
172 | |||
173 | return i2c_add_adapter(i2c_adap); | 146 | return i2c_add_adapter(i2c_adap); |
174 | } | 147 | } |
175 | 148 | ||
diff --git a/drivers/i2c/busses/i2c-stub.c b/drivers/i2c/busses/i2c-stub.c index 84df29da1ddc..c2a9f8c94f5e 100644 --- a/drivers/i2c/busses/i2c-stub.c +++ b/drivers/i2c/busses/i2c-stub.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | i2c-stub.c - Part of lm_sensors, Linux kernel modules for hardware | 2 | i2c-stub.c - I2C/SMBus chip emulator |
3 | monitoring | ||
4 | 3 | ||
5 | Copyright (c) 2004 Mark M. Hoffman <mhoffman@lightlink.com> | 4 | Copyright (c) 2004 Mark M. Hoffman <mhoffman@lightlink.com> |
5 | Copyright (C) 2007 Jean Delvare <khali@linux-fr.org> | ||
6 | 6 | ||
7 | This program is free software; you can redistribute it and/or modify | 7 | This program is free software; you can redistribute it and/or modify |
8 | it under the terms of the GNU General Public License as published by | 8 | it under the terms of the GNU General Public License as published by |
@@ -37,8 +37,8 @@ MODULE_PARM_DESC(chip_addr, | |||
37 | 37 | ||
38 | struct stub_chip { | 38 | struct stub_chip { |
39 | u8 pointer; | 39 | u8 pointer; |
40 | u8 bytes[256]; | 40 | u16 words[256]; /* Byte operations use the LSB as per SMBus |
41 | u16 words[256]; | 41 | specification */ |
42 | }; | 42 | }; |
43 | 43 | ||
44 | static struct stub_chip *stub_chips; | 44 | static struct stub_chip *stub_chips; |
@@ -75,7 +75,7 @@ static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags, | |||
75 | "wrote 0x%02x.\n", | 75 | "wrote 0x%02x.\n", |
76 | addr, command); | 76 | addr, command); |
77 | } else { | 77 | } else { |
78 | data->byte = chip->bytes[chip->pointer++]; | 78 | data->byte = chip->words[chip->pointer++] & 0xff; |
79 | dev_dbg(&adap->dev, "smbus byte - addr 0x%02x, " | 79 | dev_dbg(&adap->dev, "smbus byte - addr 0x%02x, " |
80 | "read 0x%02x.\n", | 80 | "read 0x%02x.\n", |
81 | addr, data->byte); | 81 | addr, data->byte); |
@@ -86,12 +86,13 @@ static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags, | |||
86 | 86 | ||
87 | case I2C_SMBUS_BYTE_DATA: | 87 | case I2C_SMBUS_BYTE_DATA: |
88 | if (read_write == I2C_SMBUS_WRITE) { | 88 | if (read_write == I2C_SMBUS_WRITE) { |
89 | chip->bytes[command] = data->byte; | 89 | chip->words[command] &= 0xff00; |
90 | chip->words[command] |= data->byte; | ||
90 | dev_dbg(&adap->dev, "smbus byte data - addr 0x%02x, " | 91 | dev_dbg(&adap->dev, "smbus byte data - addr 0x%02x, " |
91 | "wrote 0x%02x at 0x%02x.\n", | 92 | "wrote 0x%02x at 0x%02x.\n", |
92 | addr, data->byte, command); | 93 | addr, data->byte, command); |
93 | } else { | 94 | } else { |
94 | data->byte = chip->bytes[command]; | 95 | data->byte = chip->words[command] & 0xff; |
95 | dev_dbg(&adap->dev, "smbus byte data - addr 0x%02x, " | 96 | dev_dbg(&adap->dev, "smbus byte data - addr 0x%02x, " |
96 | "read 0x%02x at 0x%02x.\n", | 97 | "read 0x%02x at 0x%02x.\n", |
97 | addr, data->byte, command); | 98 | addr, data->byte, command); |
diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c index c9ce77f13c0e..77b13d027f86 100644 --- a/drivers/i2c/busses/i2c-viapro.c +++ b/drivers/i2c/busses/i2c-viapro.c | |||
@@ -4,7 +4,7 @@ | |||
4 | Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl>, | 4 | Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl>, |
5 | Philip Edelbrock <phil@netroedge.com>, Kyösti Mälkki <kmalkki@cc.hut.fi>, | 5 | Philip Edelbrock <phil@netroedge.com>, Kyösti Mälkki <kmalkki@cc.hut.fi>, |
6 | Mark D. Studebaker <mdsxyz123@yahoo.com> | 6 | Mark D. Studebaker <mdsxyz123@yahoo.com> |
7 | Copyright (C) 2005 - 2007 Jean Delvare <khali@linux-fr.org> | 7 | Copyright (C) 2005 - 2008 Jean Delvare <khali@linux-fr.org> |
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 |
@@ -35,6 +35,7 @@ | |||
35 | VT8235 0x3177 yes | 35 | VT8235 0x3177 yes |
36 | VT8237R 0x3227 yes | 36 | VT8237R 0x3227 yes |
37 | VT8237A 0x3337 yes | 37 | VT8237A 0x3337 yes |
38 | VT8237S 0x3372 yes | ||
38 | VT8251 0x3287 yes | 39 | VT8251 0x3287 yes |
39 | CX700 0x8324 yes | 40 | CX700 0x8324 yes |
40 | 41 | ||
@@ -318,6 +319,10 @@ static int __devinit vt596_probe(struct pci_dev *pdev, | |||
318 | unsigned char temp; | 319 | unsigned char temp; |
319 | int error = -ENODEV; | 320 | int error = -ENODEV; |
320 | 321 | ||
322 | /* driver_data might come from user-space, so check it */ | ||
323 | if (id->driver_data & 1 || id->driver_data > 0xff) | ||
324 | return -EINVAL; | ||
325 | |||
321 | /* Determine the address of the SMBus areas */ | 326 | /* Determine the address of the SMBus areas */ |
322 | if (force_addr) { | 327 | if (force_addr) { |
323 | vt596_smba = force_addr & 0xfff0; | 328 | vt596_smba = force_addr & 0xfff0; |
@@ -389,6 +394,7 @@ found: | |||
389 | case PCI_DEVICE_ID_VIA_8251: | 394 | case PCI_DEVICE_ID_VIA_8251: |
390 | case PCI_DEVICE_ID_VIA_8237: | 395 | case PCI_DEVICE_ID_VIA_8237: |
391 | case PCI_DEVICE_ID_VIA_8237A: | 396 | case PCI_DEVICE_ID_VIA_8237A: |
397 | case PCI_DEVICE_ID_VIA_8237S: | ||
392 | case PCI_DEVICE_ID_VIA_8235: | 398 | case PCI_DEVICE_ID_VIA_8235: |
393 | case PCI_DEVICE_ID_VIA_8233A: | 399 | case PCI_DEVICE_ID_VIA_8233A: |
394 | case PCI_DEVICE_ID_VIA_8233_0: | 400 | case PCI_DEVICE_ID_VIA_8233_0: |
@@ -440,6 +446,8 @@ static struct pci_device_id vt596_ids[] = { | |||
440 | .driver_data = SMBBA3 }, | 446 | .driver_data = SMBBA3 }, |
441 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237A), | 447 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237A), |
442 | .driver_data = SMBBA3 }, | 448 | .driver_data = SMBBA3 }, |
449 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237S), | ||
450 | .driver_data = SMBBA3 }, | ||
443 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4), | 451 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4), |
444 | .driver_data = SMBBA1 }, | 452 | .driver_data = SMBBA1 }, |
445 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8251), | 453 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8251), |
@@ -455,6 +463,7 @@ static struct pci_driver vt596_driver = { | |||
455 | .name = "vt596_smbus", | 463 | .name = "vt596_smbus", |
456 | .id_table = vt596_ids, | 464 | .id_table = vt596_ids, |
457 | .probe = vt596_probe, | 465 | .probe = vt596_probe, |
466 | .dynids.use_driver_data = 1, | ||
458 | }; | 467 | }; |
459 | 468 | ||
460 | static int __init i2c_vt596_init(void) | 469 | static int __init i2c_vt596_init(void) |
diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig index 2e1c24f671cf..bd7082c2443d 100644 --- a/drivers/i2c/chips/Kconfig +++ b/drivers/i2c/chips/Kconfig | |||
@@ -4,32 +4,6 @@ | |||
4 | 4 | ||
5 | menu "Miscellaneous I2C Chip support" | 5 | menu "Miscellaneous I2C Chip support" |
6 | 6 | ||
7 | config SENSORS_DS1337 | ||
8 | tristate "Dallas DS1337 and DS1339 Real Time Clock (DEPRECATED)" | ||
9 | depends on EXPERIMENTAL | ||
10 | help | ||
11 | If you say yes here you get support for Dallas Semiconductor | ||
12 | DS1337 and DS1339 real-time clock chips. | ||
13 | |||
14 | This driver can also be built as a module. If so, the module | ||
15 | will be called ds1337. | ||
16 | |||
17 | This driver is deprecated and will be dropped soon. Use | ||
18 | rtc-ds1307 instead. | ||
19 | |||
20 | config SENSORS_DS1374 | ||
21 | tristate "Dallas DS1374 Real Time Clock (DEPRECATED)" | ||
22 | depends on EXPERIMENTAL | ||
23 | help | ||
24 | If you say yes here you get support for Dallas Semiconductor | ||
25 | DS1374 real-time clock chips. | ||
26 | |||
27 | This driver can also be built as a module. If so, the module | ||
28 | will be called ds1374. | ||
29 | |||
30 | This driver is deprecated and will be dropped soon. Use | ||
31 | rtc-ds1374 instead. | ||
32 | |||
33 | config DS1682 | 7 | config DS1682 |
34 | tristate "Dallas DS1682 Total Elapsed Time Recorder with Alarm" | 8 | tristate "Dallas DS1682 Total Elapsed Time Recorder with Alarm" |
35 | depends on EXPERIMENTAL | 9 | depends on EXPERIMENTAL |
@@ -57,7 +31,7 @@ config SENSORS_PCF8574 | |||
57 | default n | 31 | default n |
58 | help | 32 | help |
59 | If you say yes here you get support for Philips PCF8574 and | 33 | If you say yes here you get support for Philips PCF8574 and |
60 | PCF8574A chips. | 34 | PCF8574A chips. These chips are 8-bit I/O expanders for the I2C bus. |
61 | 35 | ||
62 | This driver can also be built as a module. If so, the module | 36 | This driver can also be built as a module. If so, the module |
63 | will be called pcf8574. | 37 | will be called pcf8574. |
@@ -65,6 +39,20 @@ config SENSORS_PCF8574 | |||
65 | These devices are hard to detect and rarely found on mainstream | 39 | These devices are hard to detect and rarely found on mainstream |
66 | hardware. If unsure, say N. | 40 | hardware. If unsure, say N. |
67 | 41 | ||
42 | config PCF8575 | ||
43 | tristate "Philips PCF8575" | ||
44 | default n | ||
45 | help | ||
46 | If you say yes here you get support for Philips PCF8575 chip. | ||
47 | This chip is a 16-bit I/O expander for the I2C bus. Several other | ||
48 | chip manufacturers sell equivalent chips, e.g. Texas Instruments. | ||
49 | |||
50 | This driver can also be built as a module. If so, the module | ||
51 | will be called pcf8575. | ||
52 | |||
53 | This device is hard to detect and is rarely found on mainstream | ||
54 | hardware. If unsure, say N. | ||
55 | |||
68 | config SENSORS_PCA9539 | 56 | config SENSORS_PCA9539 |
69 | tristate "Philips PCA9539 16-bit I/O port" | 57 | tristate "Philips PCA9539 16-bit I/O port" |
70 | depends on EXPERIMENTAL | 58 | depends on EXPERIMENTAL |
@@ -100,12 +88,8 @@ config ISP1301_OMAP | |||
100 | This driver can also be built as a module. If so, the module | 88 | This driver can also be built as a module. If so, the module |
101 | will be called isp1301_omap. | 89 | will be called isp1301_omap. |
102 | 90 | ||
103 | # NOTE: This isn't really OMAP-specific, except for the current | ||
104 | # interface location in <include/asm-arm/arch-omap/tps65010.h> | ||
105 | # and having mostly OMAP-specific board support | ||
106 | config TPS65010 | 91 | config TPS65010 |
107 | tristate "TPS6501x Power Management chips" | 92 | tristate "TPS6501x Power Management chips" |
108 | depends on ARCH_OMAP | ||
109 | default y if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_OSK | 93 | default y if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_OSK |
110 | help | 94 | help |
111 | If you say yes here you get support for the TPS6501x series of | 95 | If you say yes here you get support for the TPS6501x series of |
@@ -116,18 +100,6 @@ config TPS65010 | |||
116 | This driver can also be built as a module. If so, the module | 100 | This driver can also be built as a module. If so, the module |
117 | will be called tps65010. | 101 | will be called tps65010. |
118 | 102 | ||
119 | config SENSORS_M41T00 | ||
120 | tristate "ST M41T00 RTC chip (DEPRECATED)" | ||
121 | depends on PPC32 | ||
122 | help | ||
123 | If you say yes here you get support for the ST M41T00 RTC chip. | ||
124 | |||
125 | This driver can also be built as a module. If so, the module | ||
126 | will be called m41t00. | ||
127 | |||
128 | This driver is deprecated and will be dropped soon. Use | ||
129 | rtc-ds1307 or rtc-m41t80 instead. | ||
130 | |||
131 | config SENSORS_MAX6875 | 103 | config SENSORS_MAX6875 |
132 | tristate "Maxim MAX6875 Power supply supervisor" | 104 | tristate "Maxim MAX6875 Power supply supervisor" |
133 | depends on EXPERIMENTAL | 105 | depends on EXPERIMENTAL |
diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile index ca924e105959..501f00cea782 100644 --- a/drivers/i2c/chips/Makefile +++ b/drivers/i2c/chips/Makefile | |||
@@ -2,14 +2,12 @@ | |||
2 | # Makefile for miscellaneous I2C chip drivers. | 2 | # Makefile for miscellaneous I2C chip drivers. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_SENSORS_DS1337) += ds1337.o | ||
6 | obj-$(CONFIG_SENSORS_DS1374) += ds1374.o | ||
7 | obj-$(CONFIG_DS1682) += ds1682.o | 5 | obj-$(CONFIG_DS1682) += ds1682.o |
8 | obj-$(CONFIG_SENSORS_EEPROM) += eeprom.o | 6 | obj-$(CONFIG_SENSORS_EEPROM) += eeprom.o |
9 | obj-$(CONFIG_SENSORS_MAX6875) += max6875.o | 7 | obj-$(CONFIG_SENSORS_MAX6875) += max6875.o |
10 | obj-$(CONFIG_SENSORS_M41T00) += m41t00.o | ||
11 | obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o | 8 | obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o |
12 | obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o | 9 | obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o |
10 | obj-$(CONFIG_PCF8575) += pcf8575.o | ||
13 | obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o | 11 | obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o |
14 | obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o | 12 | obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o |
15 | obj-$(CONFIG_TPS65010) += tps65010.o | 13 | obj-$(CONFIG_TPS65010) += tps65010.o |
diff --git a/drivers/i2c/chips/ds1337.c b/drivers/i2c/chips/ds1337.c deleted file mode 100644 index ec17d6b684a2..000000000000 --- a/drivers/i2c/chips/ds1337.c +++ /dev/null | |||
@@ -1,410 +0,0 @@ | |||
1 | /* | ||
2 | * linux/drivers/i2c/chips/ds1337.c | ||
3 | * | ||
4 | * Copyright (C) 2005 James Chapman <jchapman@katalix.com> | ||
5 | * | ||
6 | * based on linux/drivers/acorn/char/pcf8583.c | ||
7 | * Copyright (C) 2000 Russell King | ||
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 | * Driver for Dallas Semiconductor DS1337 and DS1339 real time clock chip | ||
14 | */ | ||
15 | |||
16 | #include <linux/module.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/slab.h> | ||
19 | #include <linux/i2c.h> | ||
20 | #include <linux/string.h> | ||
21 | #include <linux/rtc.h> /* get the user-level API */ | ||
22 | #include <linux/bcd.h> | ||
23 | #include <linux/list.h> | ||
24 | |||
25 | /* Device registers */ | ||
26 | #define DS1337_REG_HOUR 2 | ||
27 | #define DS1337_REG_DAY 3 | ||
28 | #define DS1337_REG_DATE 4 | ||
29 | #define DS1337_REG_MONTH 5 | ||
30 | #define DS1337_REG_CONTROL 14 | ||
31 | #define DS1337_REG_STATUS 15 | ||
32 | |||
33 | /* FIXME - how do we export these interface constants? */ | ||
34 | #define DS1337_GET_DATE 0 | ||
35 | #define DS1337_SET_DATE 1 | ||
36 | |||
37 | /* | ||
38 | * Functions declaration | ||
39 | */ | ||
40 | static unsigned short normal_i2c[] = { 0x68, I2C_CLIENT_END }; | ||
41 | |||
42 | I2C_CLIENT_INSMOD_1(ds1337); | ||
43 | |||
44 | static int ds1337_attach_adapter(struct i2c_adapter *adapter); | ||
45 | static int ds1337_detect(struct i2c_adapter *adapter, int address, int kind); | ||
46 | static void ds1337_init_client(struct i2c_client *client); | ||
47 | static int ds1337_detach_client(struct i2c_client *client); | ||
48 | static int ds1337_command(struct i2c_client *client, unsigned int cmd, | ||
49 | void *arg); | ||
50 | |||
51 | /* | ||
52 | * Driver data (common to all clients) | ||
53 | */ | ||
54 | static struct i2c_driver ds1337_driver = { | ||
55 | .driver = { | ||
56 | .name = "ds1337", | ||
57 | }, | ||
58 | .attach_adapter = ds1337_attach_adapter, | ||
59 | .detach_client = ds1337_detach_client, | ||
60 | .command = ds1337_command, | ||
61 | }; | ||
62 | |||
63 | /* | ||
64 | * Client data (each client gets its own) | ||
65 | */ | ||
66 | struct ds1337_data { | ||
67 | struct i2c_client client; | ||
68 | struct list_head list; | ||
69 | }; | ||
70 | |||
71 | /* | ||
72 | * Internal variables | ||
73 | */ | ||
74 | static LIST_HEAD(ds1337_clients); | ||
75 | |||
76 | static inline int ds1337_read(struct i2c_client *client, u8 reg, u8 *value) | ||
77 | { | ||
78 | s32 tmp = i2c_smbus_read_byte_data(client, reg); | ||
79 | |||
80 | if (tmp < 0) | ||
81 | return -EIO; | ||
82 | |||
83 | *value = tmp; | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | /* | ||
89 | * Chip access functions | ||
90 | */ | ||
91 | static int ds1337_get_datetime(struct i2c_client *client, struct rtc_time *dt) | ||
92 | { | ||
93 | int result; | ||
94 | u8 buf[7]; | ||
95 | u8 val; | ||
96 | struct i2c_msg msg[2]; | ||
97 | u8 offs = 0; | ||
98 | |||
99 | if (!dt) { | ||
100 | dev_dbg(&client->dev, "%s: EINVAL: dt=NULL\n", __FUNCTION__); | ||
101 | return -EINVAL; | ||
102 | } | ||
103 | |||
104 | msg[0].addr = client->addr; | ||
105 | msg[0].flags = 0; | ||
106 | msg[0].len = 1; | ||
107 | msg[0].buf = &offs; | ||
108 | |||
109 | msg[1].addr = client->addr; | ||
110 | msg[1].flags = I2C_M_RD; | ||
111 | msg[1].len = sizeof(buf); | ||
112 | msg[1].buf = &buf[0]; | ||
113 | |||
114 | result = i2c_transfer(client->adapter, msg, 2); | ||
115 | |||
116 | dev_dbg(&client->dev, "%s: [%d] %02x %02x %02x %02x %02x %02x %02x\n", | ||
117 | __FUNCTION__, result, buf[0], buf[1], buf[2], buf[3], | ||
118 | buf[4], buf[5], buf[6]); | ||
119 | |||
120 | if (result == 2) { | ||
121 | dt->tm_sec = BCD2BIN(buf[0]); | ||
122 | dt->tm_min = BCD2BIN(buf[1]); | ||
123 | val = buf[2] & 0x3f; | ||
124 | dt->tm_hour = BCD2BIN(val); | ||
125 | dt->tm_wday = BCD2BIN(buf[3]) - 1; | ||
126 | dt->tm_mday = BCD2BIN(buf[4]); | ||
127 | val = buf[5] & 0x7f; | ||
128 | dt->tm_mon = BCD2BIN(val) - 1; | ||
129 | dt->tm_year = BCD2BIN(buf[6]); | ||
130 | if (buf[5] & 0x80) | ||
131 | dt->tm_year += 100; | ||
132 | |||
133 | dev_dbg(&client->dev, "%s: secs=%d, mins=%d, " | ||
134 | "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", | ||
135 | __FUNCTION__, dt->tm_sec, dt->tm_min, | ||
136 | dt->tm_hour, dt->tm_mday, | ||
137 | dt->tm_mon, dt->tm_year, dt->tm_wday); | ||
138 | |||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | dev_err(&client->dev, "error reading data! %d\n", result); | ||
143 | return -EIO; | ||
144 | } | ||
145 | |||
146 | static int ds1337_set_datetime(struct i2c_client *client, struct rtc_time *dt) | ||
147 | { | ||
148 | int result; | ||
149 | u8 buf[8]; | ||
150 | u8 val; | ||
151 | struct i2c_msg msg[1]; | ||
152 | |||
153 | if (!dt) { | ||
154 | dev_dbg(&client->dev, "%s: EINVAL: dt=NULL\n", __FUNCTION__); | ||
155 | return -EINVAL; | ||
156 | } | ||
157 | |||
158 | dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, " | ||
159 | "mday=%d, mon=%d, year=%d, wday=%d\n", __FUNCTION__, | ||
160 | dt->tm_sec, dt->tm_min, dt->tm_hour, | ||
161 | dt->tm_mday, dt->tm_mon, dt->tm_year, dt->tm_wday); | ||
162 | |||
163 | buf[0] = 0; /* reg offset */ | ||
164 | buf[1] = BIN2BCD(dt->tm_sec); | ||
165 | buf[2] = BIN2BCD(dt->tm_min); | ||
166 | buf[3] = BIN2BCD(dt->tm_hour); | ||
167 | buf[4] = BIN2BCD(dt->tm_wday + 1); | ||
168 | buf[5] = BIN2BCD(dt->tm_mday); | ||
169 | buf[6] = BIN2BCD(dt->tm_mon + 1); | ||
170 | val = dt->tm_year; | ||
171 | if (val >= 100) { | ||
172 | val -= 100; | ||
173 | buf[6] |= (1 << 7); | ||
174 | } | ||
175 | buf[7] = BIN2BCD(val); | ||
176 | |||
177 | msg[0].addr = client->addr; | ||
178 | msg[0].flags = 0; | ||
179 | msg[0].len = sizeof(buf); | ||
180 | msg[0].buf = &buf[0]; | ||
181 | |||
182 | result = i2c_transfer(client->adapter, msg, 1); | ||
183 | if (result == 1) | ||
184 | return 0; | ||
185 | |||
186 | dev_err(&client->dev, "error writing data! %d\n", result); | ||
187 | return -EIO; | ||
188 | } | ||
189 | |||
190 | static int ds1337_command(struct i2c_client *client, unsigned int cmd, | ||
191 | void *arg) | ||
192 | { | ||
193 | dev_dbg(&client->dev, "%s: cmd=%d\n", __FUNCTION__, cmd); | ||
194 | |||
195 | switch (cmd) { | ||
196 | case DS1337_GET_DATE: | ||
197 | return ds1337_get_datetime(client, arg); | ||
198 | |||
199 | case DS1337_SET_DATE: | ||
200 | return ds1337_set_datetime(client, arg); | ||
201 | |||
202 | default: | ||
203 | return -EINVAL; | ||
204 | } | ||
205 | } | ||
206 | |||
207 | /* | ||
208 | * Public API for access to specific device. Useful for low-level | ||
209 | * RTC access from kernel code. | ||
210 | */ | ||
211 | int ds1337_do_command(int bus, int cmd, void *arg) | ||
212 | { | ||
213 | struct list_head *walk; | ||
214 | struct list_head *tmp; | ||
215 | struct ds1337_data *data; | ||
216 | |||
217 | list_for_each_safe(walk, tmp, &ds1337_clients) { | ||
218 | data = list_entry(walk, struct ds1337_data, list); | ||
219 | if (data->client.adapter->nr == bus) | ||
220 | return ds1337_command(&data->client, cmd, arg); | ||
221 | } | ||
222 | |||
223 | return -ENODEV; | ||
224 | } | ||
225 | |||
226 | static int ds1337_attach_adapter(struct i2c_adapter *adapter) | ||
227 | { | ||
228 | return i2c_probe(adapter, &addr_data, ds1337_detect); | ||
229 | } | ||
230 | |||
231 | /* | ||
232 | * The following function does more than just detection. If detection | ||
233 | * succeeds, it also registers the new chip. | ||
234 | */ | ||
235 | static int ds1337_detect(struct i2c_adapter *adapter, int address, int kind) | ||
236 | { | ||
237 | struct i2c_client *new_client; | ||
238 | struct ds1337_data *data; | ||
239 | int err = 0; | ||
240 | const char *name = ""; | ||
241 | |||
242 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | | ||
243 | I2C_FUNC_I2C)) | ||
244 | goto exit; | ||
245 | |||
246 | if (!(data = kzalloc(sizeof(struct ds1337_data), GFP_KERNEL))) { | ||
247 | err = -ENOMEM; | ||
248 | goto exit; | ||
249 | } | ||
250 | INIT_LIST_HEAD(&data->list); | ||
251 | |||
252 | /* The common I2C client data is placed right before the | ||
253 | * DS1337-specific data. | ||
254 | */ | ||
255 | new_client = &data->client; | ||
256 | i2c_set_clientdata(new_client, data); | ||
257 | new_client->addr = address; | ||
258 | new_client->adapter = adapter; | ||
259 | new_client->driver = &ds1337_driver; | ||
260 | new_client->flags = 0; | ||
261 | |||
262 | /* | ||
263 | * Now we do the remaining detection. A negative kind means that | ||
264 | * the driver was loaded with no force parameter (default), so we | ||
265 | * must both detect and identify the chip. A zero kind means that | ||
266 | * the driver was loaded with the force parameter, the detection | ||
267 | * step shall be skipped. A positive kind means that the driver | ||
268 | * was loaded with the force parameter and a given kind of chip is | ||
269 | * requested, so both the detection and the identification steps | ||
270 | * are skipped. | ||
271 | * | ||
272 | * For detection, we read registers that are most likely to cause | ||
273 | * detection failure, i.e. those that have more bits with fixed | ||
274 | * or reserved values. | ||
275 | */ | ||
276 | |||
277 | /* Default to an DS1337 if forced */ | ||
278 | if (kind == 0) | ||
279 | kind = ds1337; | ||
280 | |||
281 | if (kind < 0) { /* detection and identification */ | ||
282 | u8 data; | ||
283 | |||
284 | /* Check that status register bits 6-2 are zero */ | ||
285 | if ((ds1337_read(new_client, DS1337_REG_STATUS, &data) < 0) || | ||
286 | (data & 0x7c)) | ||
287 | goto exit_free; | ||
288 | |||
289 | /* Check for a valid day register value */ | ||
290 | if ((ds1337_read(new_client, DS1337_REG_DAY, &data) < 0) || | ||
291 | (data == 0) || (data & 0xf8)) | ||
292 | goto exit_free; | ||
293 | |||
294 | /* Check for a valid date register value */ | ||
295 | if ((ds1337_read(new_client, DS1337_REG_DATE, &data) < 0) || | ||
296 | (data == 0) || (data & 0xc0) || ((data & 0x0f) > 9) || | ||
297 | (data >= 0x32)) | ||
298 | goto exit_free; | ||
299 | |||
300 | /* Check for a valid month register value */ | ||
301 | if ((ds1337_read(new_client, DS1337_REG_MONTH, &data) < 0) || | ||
302 | (data == 0) || (data & 0x60) || ((data & 0x0f) > 9) || | ||
303 | ((data >= 0x13) && (data <= 0x19))) | ||
304 | goto exit_free; | ||
305 | |||
306 | /* Check that control register bits 6-5 are zero */ | ||
307 | if ((ds1337_read(new_client, DS1337_REG_CONTROL, &data) < 0) || | ||
308 | (data & 0x60)) | ||
309 | goto exit_free; | ||
310 | |||
311 | kind = ds1337; | ||
312 | } | ||
313 | |||
314 | if (kind == ds1337) | ||
315 | name = "ds1337"; | ||
316 | |||
317 | /* We can fill in the remaining client fields */ | ||
318 | strlcpy(new_client->name, name, I2C_NAME_SIZE); | ||
319 | |||
320 | /* Tell the I2C layer a new client has arrived */ | ||
321 | if ((err = i2c_attach_client(new_client))) | ||
322 | goto exit_free; | ||
323 | |||
324 | /* Initialize the DS1337 chip */ | ||
325 | ds1337_init_client(new_client); | ||
326 | |||
327 | /* Add client to local list */ | ||
328 | list_add(&data->list, &ds1337_clients); | ||
329 | |||
330 | return 0; | ||
331 | |||
332 | exit_free: | ||
333 | kfree(data); | ||
334 | exit: | ||
335 | return err; | ||
336 | } | ||
337 | |||
338 | static void ds1337_init_client(struct i2c_client *client) | ||
339 | { | ||
340 | u8 status, control; | ||
341 | |||
342 | /* On some boards, the RTC isn't configured by boot firmware. | ||
343 | * Handle that case by starting/configuring the RTC now. | ||
344 | */ | ||
345 | status = i2c_smbus_read_byte_data(client, DS1337_REG_STATUS); | ||
346 | control = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL); | ||
347 | |||
348 | if ((status & 0x80) || (control & 0x80)) { | ||
349 | /* RTC not running */ | ||
350 | u8 buf[1+16]; /* First byte is interpreted as address */ | ||
351 | struct i2c_msg msg[1]; | ||
352 | |||
353 | dev_dbg(&client->dev, "%s: RTC not running!\n", __FUNCTION__); | ||
354 | |||
355 | /* Initialize all, including STATUS and CONTROL to zero */ | ||
356 | memset(buf, 0, sizeof(buf)); | ||
357 | |||
358 | /* Write valid values in the date/time registers */ | ||
359 | buf[1+DS1337_REG_DAY] = 1; | ||
360 | buf[1+DS1337_REG_DATE] = 1; | ||
361 | buf[1+DS1337_REG_MONTH] = 1; | ||
362 | |||
363 | msg[0].addr = client->addr; | ||
364 | msg[0].flags = 0; | ||
365 | msg[0].len = sizeof(buf); | ||
366 | msg[0].buf = &buf[0]; | ||
367 | |||
368 | i2c_transfer(client->adapter, msg, 1); | ||
369 | } else { | ||
370 | /* Running: ensure that device is set in 24-hour mode */ | ||
371 | s32 val; | ||
372 | |||
373 | val = i2c_smbus_read_byte_data(client, DS1337_REG_HOUR); | ||
374 | if ((val >= 0) && (val & (1 << 6))) | ||
375 | i2c_smbus_write_byte_data(client, DS1337_REG_HOUR, | ||
376 | val & 0x3f); | ||
377 | } | ||
378 | } | ||
379 | |||
380 | static int ds1337_detach_client(struct i2c_client *client) | ||
381 | { | ||
382 | int err; | ||
383 | struct ds1337_data *data = i2c_get_clientdata(client); | ||
384 | |||
385 | if ((err = i2c_detach_client(client))) | ||
386 | return err; | ||
387 | |||
388 | list_del(&data->list); | ||
389 | kfree(data); | ||
390 | return 0; | ||
391 | } | ||
392 | |||
393 | static int __init ds1337_init(void) | ||
394 | { | ||
395 | return i2c_add_driver(&ds1337_driver); | ||
396 | } | ||
397 | |||
398 | static void __exit ds1337_exit(void) | ||
399 | { | ||
400 | i2c_del_driver(&ds1337_driver); | ||
401 | } | ||
402 | |||
403 | MODULE_AUTHOR("James Chapman <jchapman@katalix.com>"); | ||
404 | MODULE_DESCRIPTION("DS1337 RTC driver"); | ||
405 | MODULE_LICENSE("GPL"); | ||
406 | |||
407 | EXPORT_SYMBOL_GPL(ds1337_do_command); | ||
408 | |||
409 | module_init(ds1337_init); | ||
410 | module_exit(ds1337_exit); | ||
diff --git a/drivers/i2c/chips/ds1374.c b/drivers/i2c/chips/ds1374.c deleted file mode 100644 index 8a2ff0c114d9..000000000000 --- a/drivers/i2c/chips/ds1374.c +++ /dev/null | |||
@@ -1,267 +0,0 @@ | |||
1 | /* | ||
2 | * drivers/i2c/chips/ds1374.c | ||
3 | * | ||
4 | * I2C client/driver for the Maxim/Dallas DS1374 Real-Time Clock | ||
5 | * | ||
6 | * Author: Randy Vinson <rvinson@mvista.com> | ||
7 | * | ||
8 | * Based on the m41t00.c by Mark Greer <mgreer@mvista.com> | ||
9 | * | ||
10 | * 2005 (c) MontaVista Software, Inc. This file is licensed under | ||
11 | * the terms of the GNU General Public License version 2. This program | ||
12 | * is licensed "as is" without any warranty of any kind, whether express | ||
13 | * or implied. | ||
14 | */ | ||
15 | /* | ||
16 | * This i2c client/driver wedges between the drivers/char/genrtc.c RTC | ||
17 | * interface and the SMBus interface of the i2c subsystem. | ||
18 | * It would be more efficient to use i2c msgs/i2c_transfer directly but, as | ||
19 | * recommened in .../Documentation/i2c/writing-clients section | ||
20 | * "Sending and receiving", using SMBus level communication is preferred. | ||
21 | */ | ||
22 | |||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/i2c.h> | ||
27 | #include <linux/rtc.h> | ||
28 | #include <linux/bcd.h> | ||
29 | #include <linux/mutex.h> | ||
30 | #include <linux/workqueue.h> | ||
31 | |||
32 | #define DS1374_REG_TOD0 0x00 | ||
33 | #define DS1374_REG_TOD1 0x01 | ||
34 | #define DS1374_REG_TOD2 0x02 | ||
35 | #define DS1374_REG_TOD3 0x03 | ||
36 | #define DS1374_REG_WDALM0 0x04 | ||
37 | #define DS1374_REG_WDALM1 0x05 | ||
38 | #define DS1374_REG_WDALM2 0x06 | ||
39 | #define DS1374_REG_CR 0x07 | ||
40 | #define DS1374_REG_SR 0x08 | ||
41 | #define DS1374_REG_SR_OSF 0x80 | ||
42 | #define DS1374_REG_TCR 0x09 | ||
43 | |||
44 | #define DS1374_DRV_NAME "ds1374" | ||
45 | |||
46 | static DEFINE_MUTEX(ds1374_mutex); | ||
47 | |||
48 | static struct i2c_driver ds1374_driver; | ||
49 | static struct i2c_client *save_client; | ||
50 | |||
51 | static unsigned short ignore[] = { I2C_CLIENT_END }; | ||
52 | static unsigned short normal_addr[] = { 0x68, I2C_CLIENT_END }; | ||
53 | |||
54 | static struct i2c_client_address_data addr_data = { | ||
55 | .normal_i2c = normal_addr, | ||
56 | .probe = ignore, | ||
57 | .ignore = ignore, | ||
58 | }; | ||
59 | |||
60 | static ulong ds1374_read_rtc(void) | ||
61 | { | ||
62 | ulong time = 0; | ||
63 | int reg = DS1374_REG_WDALM0; | ||
64 | |||
65 | while (reg--) { | ||
66 | s32 tmp; | ||
67 | if ((tmp = i2c_smbus_read_byte_data(save_client, reg)) < 0) { | ||
68 | dev_warn(&save_client->dev, | ||
69 | "can't read from rtc chip\n"); | ||
70 | return 0; | ||
71 | } | ||
72 | time = (time << 8) | (tmp & 0xff); | ||
73 | } | ||
74 | return time; | ||
75 | } | ||
76 | |||
77 | static void ds1374_write_rtc(ulong time) | ||
78 | { | ||
79 | int reg; | ||
80 | |||
81 | for (reg = DS1374_REG_TOD0; reg < DS1374_REG_WDALM0; reg++) { | ||
82 | if (i2c_smbus_write_byte_data(save_client, reg, time & 0xff) | ||
83 | < 0) { | ||
84 | dev_warn(&save_client->dev, | ||
85 | "can't write to rtc chip\n"); | ||
86 | break; | ||
87 | } | ||
88 | time = time >> 8; | ||
89 | } | ||
90 | } | ||
91 | |||
92 | static void ds1374_check_rtc_status(void) | ||
93 | { | ||
94 | s32 tmp; | ||
95 | |||
96 | tmp = i2c_smbus_read_byte_data(save_client, DS1374_REG_SR); | ||
97 | if (tmp < 0) { | ||
98 | dev_warn(&save_client->dev, | ||
99 | "can't read status from rtc chip\n"); | ||
100 | return; | ||
101 | } | ||
102 | if (tmp & DS1374_REG_SR_OSF) { | ||
103 | dev_warn(&save_client->dev, | ||
104 | "oscillator discontinuity flagged, time unreliable\n"); | ||
105 | tmp &= ~DS1374_REG_SR_OSF; | ||
106 | tmp = i2c_smbus_write_byte_data(save_client, DS1374_REG_SR, | ||
107 | tmp & 0xff); | ||
108 | if (tmp < 0) | ||
109 | dev_warn(&save_client->dev, | ||
110 | "can't clear discontinuity notification\n"); | ||
111 | } | ||
112 | } | ||
113 | |||
114 | ulong ds1374_get_rtc_time(void) | ||
115 | { | ||
116 | ulong t1, t2; | ||
117 | int limit = 10; /* arbitrary retry limit */ | ||
118 | |||
119 | mutex_lock(&ds1374_mutex); | ||
120 | |||
121 | /* | ||
122 | * Since the reads are being performed one byte at a time using | ||
123 | * the SMBus vs a 4-byte i2c transfer, there is a chance that a | ||
124 | * carry will occur during the read. To detect this, 2 reads are | ||
125 | * performed and compared. | ||
126 | */ | ||
127 | do { | ||
128 | t1 = ds1374_read_rtc(); | ||
129 | t2 = ds1374_read_rtc(); | ||
130 | } while (t1 != t2 && limit--); | ||
131 | |||
132 | mutex_unlock(&ds1374_mutex); | ||
133 | |||
134 | if (t1 != t2) { | ||
135 | dev_warn(&save_client->dev, | ||
136 | "can't get consistent time from rtc chip\n"); | ||
137 | t1 = 0; | ||
138 | } | ||
139 | |||
140 | return t1; | ||
141 | } | ||
142 | |||
143 | static ulong new_time; | ||
144 | |||
145 | static void ds1374_set_work(struct work_struct *work) | ||
146 | { | ||
147 | ulong t1, t2; | ||
148 | int limit = 10; /* arbitrary retry limit */ | ||
149 | |||
150 | t1 = new_time; | ||
151 | |||
152 | mutex_lock(&ds1374_mutex); | ||
153 | |||
154 | /* | ||
155 | * Since the writes are being performed one byte at a time using | ||
156 | * the SMBus vs a 4-byte i2c transfer, there is a chance that a | ||
157 | * carry will occur during the write. To detect this, the write | ||
158 | * value is read back and compared. | ||
159 | */ | ||
160 | do { | ||
161 | ds1374_write_rtc(t1); | ||
162 | t2 = ds1374_read_rtc(); | ||
163 | } while (t1 != t2 && limit--); | ||
164 | |||
165 | mutex_unlock(&ds1374_mutex); | ||
166 | |||
167 | if (t1 != t2) | ||
168 | dev_warn(&save_client->dev, | ||
169 | "can't confirm time set from rtc chip\n"); | ||
170 | } | ||
171 | |||
172 | static struct workqueue_struct *ds1374_workqueue; | ||
173 | |||
174 | static DECLARE_WORK(ds1374_work, ds1374_set_work); | ||
175 | |||
176 | int ds1374_set_rtc_time(ulong nowtime) | ||
177 | { | ||
178 | new_time = nowtime; | ||
179 | |||
180 | if (in_interrupt()) | ||
181 | queue_work(ds1374_workqueue, &ds1374_work); | ||
182 | else | ||
183 | ds1374_set_work(NULL); | ||
184 | |||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | /* | ||
189 | ***************************************************************************** | ||
190 | * | ||
191 | * Driver Interface | ||
192 | * | ||
193 | ***************************************************************************** | ||
194 | */ | ||
195 | static int ds1374_probe(struct i2c_adapter *adap, int addr, int kind) | ||
196 | { | ||
197 | struct i2c_client *client; | ||
198 | int rc; | ||
199 | |||
200 | client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); | ||
201 | if (!client) | ||
202 | return -ENOMEM; | ||
203 | |||
204 | strncpy(client->name, DS1374_DRV_NAME, I2C_NAME_SIZE); | ||
205 | client->addr = addr; | ||
206 | client->adapter = adap; | ||
207 | client->driver = &ds1374_driver; | ||
208 | |||
209 | ds1374_workqueue = create_singlethread_workqueue("ds1374"); | ||
210 | if (!ds1374_workqueue) { | ||
211 | kfree(client); | ||
212 | return -ENOMEM; /* most expected reason */ | ||
213 | } | ||
214 | |||
215 | if ((rc = i2c_attach_client(client)) != 0) { | ||
216 | kfree(client); | ||
217 | return rc; | ||
218 | } | ||
219 | |||
220 | save_client = client; | ||
221 | |||
222 | ds1374_check_rtc_status(); | ||
223 | |||
224 | return 0; | ||
225 | } | ||
226 | |||
227 | static int ds1374_attach(struct i2c_adapter *adap) | ||
228 | { | ||
229 | return i2c_probe(adap, &addr_data, ds1374_probe); | ||
230 | } | ||
231 | |||
232 | static int ds1374_detach(struct i2c_client *client) | ||
233 | { | ||
234 | int rc; | ||
235 | |||
236 | if ((rc = i2c_detach_client(client)) == 0) { | ||
237 | kfree(i2c_get_clientdata(client)); | ||
238 | destroy_workqueue(ds1374_workqueue); | ||
239 | } | ||
240 | return rc; | ||
241 | } | ||
242 | |||
243 | static struct i2c_driver ds1374_driver = { | ||
244 | .driver = { | ||
245 | .name = DS1374_DRV_NAME, | ||
246 | }, | ||
247 | .id = I2C_DRIVERID_DS1374, | ||
248 | .attach_adapter = ds1374_attach, | ||
249 | .detach_client = ds1374_detach, | ||
250 | }; | ||
251 | |||
252 | static int __init ds1374_init(void) | ||
253 | { | ||
254 | return i2c_add_driver(&ds1374_driver); | ||
255 | } | ||
256 | |||
257 | static void __exit ds1374_exit(void) | ||
258 | { | ||
259 | i2c_del_driver(&ds1374_driver); | ||
260 | } | ||
261 | |||
262 | module_init(ds1374_init); | ||
263 | module_exit(ds1374_exit); | ||
264 | |||
265 | MODULE_AUTHOR("Randy Vinson <rvinson@mvista.com>"); | ||
266 | MODULE_DESCRIPTION("Maxim/Dallas DS1374 RTC I2C Client Driver"); | ||
267 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c index 1a7eeebac506..fde297b21ad7 100644 --- a/drivers/i2c/chips/eeprom.c +++ b/drivers/i2c/chips/eeprom.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include <linux/mutex.h> | 35 | #include <linux/mutex.h> |
36 | 36 | ||
37 | /* Addresses to scan */ | 37 | /* Addresses to scan */ |
38 | static unsigned short normal_i2c[] = { 0x50, 0x51, 0x52, 0x53, 0x54, | 38 | static const unsigned short normal_i2c[] = { 0x50, 0x51, 0x52, 0x53, 0x54, |
39 | 0x55, 0x56, 0x57, I2C_CLIENT_END }; | 39 | 0x55, 0x56, 0x57, I2C_CLIENT_END }; |
40 | 40 | ||
41 | /* Insmod parameters */ | 41 | /* Insmod parameters */ |
diff --git a/drivers/i2c/chips/isp1301_omap.c b/drivers/i2c/chips/isp1301_omap.c index ebfbb2947ae6..2a3160153f54 100644 --- a/drivers/i2c/chips/isp1301_omap.c +++ b/drivers/i2c/chips/isp1301_omap.c | |||
@@ -100,7 +100,7 @@ struct isp1301 { | |||
100 | 100 | ||
101 | #if defined(CONFIG_TPS65010) || defined(CONFIG_TPS65010_MODULE) | 101 | #if defined(CONFIG_TPS65010) || defined(CONFIG_TPS65010_MODULE) |
102 | 102 | ||
103 | #include <asm/arch/tps65010.h> | 103 | #include <linux/i2c/tps65010.h> |
104 | 104 | ||
105 | #else | 105 | #else |
106 | 106 | ||
diff --git a/drivers/i2c/chips/m41t00.c b/drivers/i2c/chips/m41t00.c deleted file mode 100644 index 3fcb646e2073..000000000000 --- a/drivers/i2c/chips/m41t00.c +++ /dev/null | |||
@@ -1,413 +0,0 @@ | |||
1 | /* | ||
2 | * I2C client/driver for the ST M41T00 family of i2c rtc chips. | ||
3 | * | ||
4 | * Author: Mark A. Greer <mgreer@mvista.com> | ||
5 | * | ||
6 | * 2005, 2006 (c) MontaVista Software, Inc. This file is licensed under | ||
7 | * the terms of the GNU General Public License version 2. This program | ||
8 | * is licensed "as is" without any warranty of any kind, whether express | ||
9 | * or implied. | ||
10 | */ | ||
11 | /* | ||
12 | * This i2c client/driver wedges between the drivers/char/genrtc.c RTC | ||
13 | * interface and the SMBus interface of the i2c subsystem. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/i2c.h> | ||
20 | #include <linux/rtc.h> | ||
21 | #include <linux/bcd.h> | ||
22 | #include <linux/workqueue.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/m41t00.h> | ||
25 | #include <asm/time.h> | ||
26 | #include <asm/rtc.h> | ||
27 | |||
28 | static struct i2c_driver m41t00_driver; | ||
29 | static struct i2c_client *save_client; | ||
30 | |||
31 | static unsigned short ignore[] = { I2C_CLIENT_END }; | ||
32 | static unsigned short normal_addr[] = { I2C_CLIENT_END, I2C_CLIENT_END }; | ||
33 | |||
34 | static struct i2c_client_address_data addr_data = { | ||
35 | .normal_i2c = normal_addr, | ||
36 | .probe = ignore, | ||
37 | .ignore = ignore, | ||
38 | }; | ||
39 | |||
40 | struct m41t00_chip_info { | ||
41 | u8 type; | ||
42 | char *name; | ||
43 | u8 read_limit; | ||
44 | u8 sec; /* Offsets for chip regs */ | ||
45 | u8 min; | ||
46 | u8 hour; | ||
47 | u8 day; | ||
48 | u8 mon; | ||
49 | u8 year; | ||
50 | u8 alarm_mon; | ||
51 | u8 alarm_hour; | ||
52 | u8 sqw; | ||
53 | u8 sqw_freq; | ||
54 | }; | ||
55 | |||
56 | static struct m41t00_chip_info m41t00_chip_info_tbl[] = { | ||
57 | { | ||
58 | .type = M41T00_TYPE_M41T00, | ||
59 | .name = "m41t00", | ||
60 | .read_limit = 5, | ||
61 | .sec = 0, | ||
62 | .min = 1, | ||
63 | .hour = 2, | ||
64 | .day = 4, | ||
65 | .mon = 5, | ||
66 | .year = 6, | ||
67 | }, | ||
68 | { | ||
69 | .type = M41T00_TYPE_M41T81, | ||
70 | .name = "m41t81", | ||
71 | .read_limit = 1, | ||
72 | .sec = 1, | ||
73 | .min = 2, | ||
74 | .hour = 3, | ||
75 | .day = 5, | ||
76 | .mon = 6, | ||
77 | .year = 7, | ||
78 | .alarm_mon = 0xa, | ||
79 | .alarm_hour = 0xc, | ||
80 | .sqw = 0x13, | ||
81 | }, | ||
82 | { | ||
83 | .type = M41T00_TYPE_M41T85, | ||
84 | .name = "m41t85", | ||
85 | .read_limit = 1, | ||
86 | .sec = 1, | ||
87 | .min = 2, | ||
88 | .hour = 3, | ||
89 | .day = 5, | ||
90 | .mon = 6, | ||
91 | .year = 7, | ||
92 | .alarm_mon = 0xa, | ||
93 | .alarm_hour = 0xc, | ||
94 | .sqw = 0x13, | ||
95 | }, | ||
96 | }; | ||
97 | static struct m41t00_chip_info *m41t00_chip; | ||
98 | |||
99 | ulong | ||
100 | m41t00_get_rtc_time(void) | ||
101 | { | ||
102 | s32 sec, min, hour, day, mon, year; | ||
103 | s32 sec1, min1, hour1, day1, mon1, year1; | ||
104 | u8 reads = 0; | ||
105 | u8 buf[8], msgbuf[1] = { 0 }; /* offset into rtc's regs */ | ||
106 | struct i2c_msg msgs[] = { | ||
107 | { | ||
108 | .addr = save_client->addr, | ||
109 | .flags = 0, | ||
110 | .len = 1, | ||
111 | .buf = msgbuf, | ||
112 | }, | ||
113 | { | ||
114 | .addr = save_client->addr, | ||
115 | .flags = I2C_M_RD, | ||
116 | .len = 8, | ||
117 | .buf = buf, | ||
118 | }, | ||
119 | }; | ||
120 | |||
121 | sec = min = hour = day = mon = year = 0; | ||
122 | |||
123 | do { | ||
124 | if (i2c_transfer(save_client->adapter, msgs, 2) < 0) | ||
125 | goto read_err; | ||
126 | |||
127 | sec1 = sec; | ||
128 | min1 = min; | ||
129 | hour1 = hour; | ||
130 | day1 = day; | ||
131 | mon1 = mon; | ||
132 | year1 = year; | ||
133 | |||
134 | sec = buf[m41t00_chip->sec] & 0x7f; | ||
135 | min = buf[m41t00_chip->min] & 0x7f; | ||
136 | hour = buf[m41t00_chip->hour] & 0x3f; | ||
137 | day = buf[m41t00_chip->day] & 0x3f; | ||
138 | mon = buf[m41t00_chip->mon] & 0x1f; | ||
139 | year = buf[m41t00_chip->year]; | ||
140 | } while ((++reads < m41t00_chip->read_limit) && ((sec != sec1) | ||
141 | || (min != min1) || (hour != hour1) || (day != day1) | ||
142 | || (mon != mon1) || (year != year1))); | ||
143 | |||
144 | if ((m41t00_chip->read_limit > 1) && ((sec != sec1) || (min != min1) | ||
145 | || (hour != hour1) || (day != day1) || (mon != mon1) | ||
146 | || (year != year1))) | ||
147 | goto read_err; | ||
148 | |||
149 | sec = BCD2BIN(sec); | ||
150 | min = BCD2BIN(min); | ||
151 | hour = BCD2BIN(hour); | ||
152 | day = BCD2BIN(day); | ||
153 | mon = BCD2BIN(mon); | ||
154 | year = BCD2BIN(year); | ||
155 | |||
156 | year += 1900; | ||
157 | if (year < 1970) | ||
158 | year += 100; | ||
159 | |||
160 | return mktime(year, mon, day, hour, min, sec); | ||
161 | |||
162 | read_err: | ||
163 | dev_err(&save_client->dev, "m41t00_get_rtc_time: Read error\n"); | ||
164 | return 0; | ||
165 | } | ||
166 | EXPORT_SYMBOL_GPL(m41t00_get_rtc_time); | ||
167 | |||
168 | static void | ||
169 | m41t00_set(void *arg) | ||
170 | { | ||
171 | struct rtc_time tm; | ||
172 | int nowtime = *(int *)arg; | ||
173 | s32 sec, min, hour, day, mon, year; | ||
174 | u8 wbuf[9], *buf = &wbuf[1], msgbuf[1] = { 0 }; | ||
175 | struct i2c_msg msgs[] = { | ||
176 | { | ||
177 | .addr = save_client->addr, | ||
178 | .flags = 0, | ||
179 | .len = 1, | ||
180 | .buf = msgbuf, | ||
181 | }, | ||
182 | { | ||
183 | .addr = save_client->addr, | ||
184 | .flags = I2C_M_RD, | ||
185 | .len = 8, | ||
186 | .buf = buf, | ||
187 | }, | ||
188 | }; | ||
189 | |||
190 | to_tm(nowtime, &tm); | ||
191 | tm.tm_year = (tm.tm_year - 1900) % 100; | ||
192 | |||
193 | sec = BIN2BCD(tm.tm_sec); | ||
194 | min = BIN2BCD(tm.tm_min); | ||
195 | hour = BIN2BCD(tm.tm_hour); | ||
196 | day = BIN2BCD(tm.tm_mday); | ||
197 | mon = BIN2BCD(tm.tm_mon); | ||
198 | year = BIN2BCD(tm.tm_year); | ||
199 | |||
200 | /* Read reg values into buf[0..7]/wbuf[1..8] */ | ||
201 | if (i2c_transfer(save_client->adapter, msgs, 2) < 0) { | ||
202 | dev_err(&save_client->dev, "m41t00_set: Read error\n"); | ||
203 | return; | ||
204 | } | ||
205 | |||
206 | wbuf[0] = 0; /* offset into rtc's regs */ | ||
207 | buf[m41t00_chip->sec] = (buf[m41t00_chip->sec] & ~0x7f) | (sec & 0x7f); | ||
208 | buf[m41t00_chip->min] = (buf[m41t00_chip->min] & ~0x7f) | (min & 0x7f); | ||
209 | buf[m41t00_chip->hour] = (buf[m41t00_chip->hour] & ~0x3f) | (hour& 0x3f); | ||
210 | buf[m41t00_chip->day] = (buf[m41t00_chip->day] & ~0x3f) | (day & 0x3f); | ||
211 | buf[m41t00_chip->mon] = (buf[m41t00_chip->mon] & ~0x1f) | (mon & 0x1f); | ||
212 | buf[m41t00_chip->year] = year; | ||
213 | |||
214 | if (i2c_master_send(save_client, wbuf, 9) < 0) | ||
215 | dev_err(&save_client->dev, "m41t00_set: Write error\n"); | ||
216 | } | ||
217 | |||
218 | static ulong new_time; | ||
219 | /* well, isn't this API just _lovely_? */ | ||
220 | static void | ||
221 | m41t00_barf(struct work_struct *unusable) | ||
222 | { | ||
223 | m41t00_set(&new_time); | ||
224 | } | ||
225 | |||
226 | static struct workqueue_struct *m41t00_wq; | ||
227 | static DECLARE_WORK(m41t00_work, m41t00_barf); | ||
228 | |||
229 | int | ||
230 | m41t00_set_rtc_time(ulong nowtime) | ||
231 | { | ||
232 | new_time = nowtime; | ||
233 | |||
234 | if (in_interrupt()) | ||
235 | queue_work(m41t00_wq, &m41t00_work); | ||
236 | else | ||
237 | m41t00_set(&new_time); | ||
238 | |||
239 | return 0; | ||
240 | } | ||
241 | EXPORT_SYMBOL_GPL(m41t00_set_rtc_time); | ||
242 | |||
243 | /* | ||
244 | ***************************************************************************** | ||
245 | * | ||
246 | * platform_data Driver Interface | ||
247 | * | ||
248 | ***************************************************************************** | ||
249 | */ | ||
250 | static int __init | ||
251 | m41t00_platform_probe(struct platform_device *pdev) | ||
252 | { | ||
253 | struct m41t00_platform_data *pdata; | ||
254 | int i; | ||
255 | |||
256 | if (pdev && (pdata = pdev->dev.platform_data)) { | ||
257 | normal_addr[0] = pdata->i2c_addr; | ||
258 | |||
259 | for (i=0; i<ARRAY_SIZE(m41t00_chip_info_tbl); i++) | ||
260 | if (m41t00_chip_info_tbl[i].type == pdata->type) { | ||
261 | m41t00_chip = &m41t00_chip_info_tbl[i]; | ||
262 | m41t00_chip->sqw_freq = pdata->sqw_freq; | ||
263 | return 0; | ||
264 | } | ||
265 | } | ||
266 | return -ENODEV; | ||
267 | } | ||
268 | |||
269 | static int __exit | ||
270 | m41t00_platform_remove(struct platform_device *pdev) | ||
271 | { | ||
272 | return 0; | ||
273 | } | ||
274 | |||
275 | static struct platform_driver m41t00_platform_driver = { | ||
276 | .probe = m41t00_platform_probe, | ||
277 | .remove = m41t00_platform_remove, | ||
278 | .driver = { | ||
279 | .owner = THIS_MODULE, | ||
280 | .name = M41T00_DRV_NAME, | ||
281 | }, | ||
282 | }; | ||
283 | |||
284 | /* | ||
285 | ***************************************************************************** | ||
286 | * | ||
287 | * Driver Interface | ||
288 | * | ||
289 | ***************************************************************************** | ||
290 | */ | ||
291 | static int | ||
292 | m41t00_probe(struct i2c_adapter *adap, int addr, int kind) | ||
293 | { | ||
294 | struct i2c_client *client; | ||
295 | int rc; | ||
296 | |||
297 | if (!i2c_check_functionality(adap, I2C_FUNC_I2C | ||
298 | | I2C_FUNC_SMBUS_BYTE_DATA)) | ||
299 | return 0; | ||
300 | |||
301 | client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); | ||
302 | if (!client) | ||
303 | return -ENOMEM; | ||
304 | |||
305 | strlcpy(client->name, m41t00_chip->name, I2C_NAME_SIZE); | ||
306 | client->addr = addr; | ||
307 | client->adapter = adap; | ||
308 | client->driver = &m41t00_driver; | ||
309 | |||
310 | if ((rc = i2c_attach_client(client))) | ||
311 | goto attach_err; | ||
312 | |||
313 | if (m41t00_chip->type != M41T00_TYPE_M41T00) { | ||
314 | /* If asked, disable SQW, set SQW frequency & re-enable */ | ||
315 | if (m41t00_chip->sqw_freq) | ||
316 | if (((rc = i2c_smbus_read_byte_data(client, | ||
317 | m41t00_chip->alarm_mon)) < 0) | ||
318 | || ((rc = i2c_smbus_write_byte_data(client, | ||
319 | m41t00_chip->alarm_mon, rc & ~0x40)) <0) | ||
320 | || ((rc = i2c_smbus_write_byte_data(client, | ||
321 | m41t00_chip->sqw, | ||
322 | m41t00_chip->sqw_freq)) < 0) | ||
323 | || ((rc = i2c_smbus_write_byte_data(client, | ||
324 | m41t00_chip->alarm_mon, rc | 0x40)) <0)) | ||
325 | goto sqw_err; | ||
326 | |||
327 | /* Make sure HT (Halt Update) bit is cleared */ | ||
328 | if ((rc = i2c_smbus_read_byte_data(client, | ||
329 | m41t00_chip->alarm_hour)) < 0) | ||
330 | goto ht_err; | ||
331 | |||
332 | if (rc & 0x40) | ||
333 | if ((rc = i2c_smbus_write_byte_data(client, | ||
334 | m41t00_chip->alarm_hour, rc & ~0x40))<0) | ||
335 | goto ht_err; | ||
336 | } | ||
337 | |||
338 | /* Make sure ST (stop) bit is cleared */ | ||
339 | if ((rc = i2c_smbus_read_byte_data(client, m41t00_chip->sec)) < 0) | ||
340 | goto st_err; | ||
341 | |||
342 | if (rc & 0x80) | ||
343 | if ((rc = i2c_smbus_write_byte_data(client, m41t00_chip->sec, | ||
344 | rc & ~0x80)) < 0) | ||
345 | goto st_err; | ||
346 | |||
347 | m41t00_wq = create_singlethread_workqueue(m41t00_chip->name); | ||
348 | save_client = client; | ||
349 | return 0; | ||
350 | |||
351 | st_err: | ||
352 | dev_err(&client->dev, "m41t00_probe: Can't clear ST bit\n"); | ||
353 | goto attach_err; | ||
354 | ht_err: | ||
355 | dev_err(&client->dev, "m41t00_probe: Can't clear HT bit\n"); | ||
356 | goto attach_err; | ||
357 | sqw_err: | ||
358 | dev_err(&client->dev, "m41t00_probe: Can't set SQW Frequency\n"); | ||
359 | attach_err: | ||
360 | kfree(client); | ||
361 | return rc; | ||
362 | } | ||
363 | |||
364 | static int | ||
365 | m41t00_attach(struct i2c_adapter *adap) | ||
366 | { | ||
367 | return i2c_probe(adap, &addr_data, m41t00_probe); | ||
368 | } | ||
369 | |||
370 | static int | ||
371 | m41t00_detach(struct i2c_client *client) | ||
372 | { | ||
373 | int rc; | ||
374 | |||
375 | if ((rc = i2c_detach_client(client)) == 0) { | ||
376 | kfree(client); | ||
377 | destroy_workqueue(m41t00_wq); | ||
378 | } | ||
379 | return rc; | ||
380 | } | ||
381 | |||
382 | static struct i2c_driver m41t00_driver = { | ||
383 | .driver = { | ||
384 | .name = M41T00_DRV_NAME, | ||
385 | }, | ||
386 | .id = I2C_DRIVERID_STM41T00, | ||
387 | .attach_adapter = m41t00_attach, | ||
388 | .detach_client = m41t00_detach, | ||
389 | }; | ||
390 | |||
391 | static int __init | ||
392 | m41t00_init(void) | ||
393 | { | ||
394 | int rc; | ||
395 | |||
396 | if (!(rc = platform_driver_register(&m41t00_platform_driver))) | ||
397 | rc = i2c_add_driver(&m41t00_driver); | ||
398 | return rc; | ||
399 | } | ||
400 | |||
401 | static void __exit | ||
402 | m41t00_exit(void) | ||
403 | { | ||
404 | i2c_del_driver(&m41t00_driver); | ||
405 | platform_driver_unregister(&m41t00_platform_driver); | ||
406 | } | ||
407 | |||
408 | module_init(m41t00_init); | ||
409 | module_exit(m41t00_exit); | ||
410 | |||
411 | MODULE_AUTHOR("Mark A. Greer <mgreer@mvista.com>"); | ||
412 | MODULE_DESCRIPTION("ST Microelectronics M41T00 RTC I2C Client Driver"); | ||
413 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/i2c/chips/max6875.c b/drivers/i2c/chips/max6875.c index 64692f666372..fb7ea5637eca 100644 --- a/drivers/i2c/chips/max6875.c +++ b/drivers/i2c/chips/max6875.c | |||
@@ -34,7 +34,7 @@ | |||
34 | #include <linux/mutex.h> | 34 | #include <linux/mutex.h> |
35 | 35 | ||
36 | /* Do not scan - the MAX6875 access method will write to some EEPROM chips */ | 36 | /* Do not scan - the MAX6875 access method will write to some EEPROM chips */ |
37 | static unsigned short normal_i2c[] = {I2C_CLIENT_END}; | 37 | static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; |
38 | 38 | ||
39 | /* Insmod parameters */ | 39 | /* Insmod parameters */ |
40 | I2C_CLIENT_INSMOD_1(max6875); | 40 | I2C_CLIENT_INSMOD_1(max6875); |
diff --git a/drivers/i2c/chips/pcf8574.c b/drivers/i2c/chips/pcf8574.c index 21c6dd69193c..b3b830ccf209 100644 --- a/drivers/i2c/chips/pcf8574.c +++ b/drivers/i2c/chips/pcf8574.c | |||
@@ -41,9 +41,11 @@ | |||
41 | #include <linux/i2c.h> | 41 | #include <linux/i2c.h> |
42 | 42 | ||
43 | /* Addresses to scan */ | 43 | /* Addresses to scan */ |
44 | static unsigned short normal_i2c[] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, | 44 | static const unsigned short normal_i2c[] = { |
45 | 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, | 45 | 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, |
46 | I2C_CLIENT_END }; | 46 | 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, |
47 | I2C_CLIENT_END | ||
48 | }; | ||
47 | 49 | ||
48 | /* Insmod parameters */ | 50 | /* Insmod parameters */ |
49 | I2C_CLIENT_INSMOD_2(pcf8574, pcf8574a); | 51 | I2C_CLIENT_INSMOD_2(pcf8574, pcf8574a); |
diff --git a/drivers/i2c/chips/pcf8575.c b/drivers/i2c/chips/pcf8575.c new file mode 100644 index 000000000000..3ea08ac0bfa3 --- /dev/null +++ b/drivers/i2c/chips/pcf8575.c | |||
@@ -0,0 +1,214 @@ | |||
1 | /* | ||
2 | pcf8575.c | ||
3 | |||
4 | About the PCF8575 chip: the PCF8575 is a 16-bit I/O expander for the I2C bus | ||
5 | produced by a.o. Philips Semiconductors. | ||
6 | |||
7 | Copyright (C) 2006 Michael Hennerich, Analog Devices Inc. | ||
8 | <hennerich@blackfin.uclinux.org> | ||
9 | Based on pcf8574.c. | ||
10 | |||
11 | Copyright (c) 2007 Bart Van Assche <bart.vanassche@gmail.com>. | ||
12 | Ported this driver from ucLinux to the mainstream Linux kernel. | ||
13 | |||
14 | This program is free software; you can redistribute it and/or modify | ||
15 | it under the terms of the GNU General Public License as published by | ||
16 | the Free Software Foundation; either version 2 of the License, or | ||
17 | (at your option) any later version. | ||
18 | |||
19 | This program is distributed in the hope that it will be useful, | ||
20 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | GNU General Public License for more details. | ||
23 | |||
24 | You should have received a copy of the GNU General Public License | ||
25 | along with this program; if not, write to the Free Software | ||
26 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
27 | */ | ||
28 | |||
29 | #include <linux/module.h> | ||
30 | #include <linux/init.h> | ||
31 | #include <linux/i2c.h> | ||
32 | #include <linux/slab.h> /* kzalloc() */ | ||
33 | #include <linux/sysfs.h> /* sysfs_create_group() */ | ||
34 | |||
35 | /* Addresses to scan */ | ||
36 | static const unsigned short normal_i2c[] = { | ||
37 | 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, | ||
38 | I2C_CLIENT_END | ||
39 | }; | ||
40 | |||
41 | /* Insmod parameters */ | ||
42 | I2C_CLIENT_INSMOD; | ||
43 | |||
44 | |||
45 | /* Each client has this additional data */ | ||
46 | struct pcf8575_data { | ||
47 | struct i2c_client client; | ||
48 | int write; /* last written value, or error code */ | ||
49 | }; | ||
50 | |||
51 | static int pcf8575_attach_adapter(struct i2c_adapter *adapter); | ||
52 | static int pcf8575_detect(struct i2c_adapter *adapter, int address, int kind); | ||
53 | static int pcf8575_detach_client(struct i2c_client *client); | ||
54 | |||
55 | /* This is the driver that will be inserted */ | ||
56 | static struct i2c_driver pcf8575_driver = { | ||
57 | .driver = { | ||
58 | .owner = THIS_MODULE, | ||
59 | .name = "pcf8575", | ||
60 | }, | ||
61 | .attach_adapter = pcf8575_attach_adapter, | ||
62 | .detach_client = pcf8575_detach_client, | ||
63 | }; | ||
64 | |||
65 | /* following are the sysfs callback functions */ | ||
66 | static ssize_t show_read(struct device *dev, struct device_attribute *attr, | ||
67 | char *buf) | ||
68 | { | ||
69 | struct i2c_client *client = to_i2c_client(dev); | ||
70 | u16 val; | ||
71 | u8 iopin_state[2]; | ||
72 | |||
73 | i2c_master_recv(client, iopin_state, 2); | ||
74 | |||
75 | val = iopin_state[0]; | ||
76 | val |= iopin_state[1] << 8; | ||
77 | |||
78 | return sprintf(buf, "%u\n", val); | ||
79 | } | ||
80 | |||
81 | static DEVICE_ATTR(read, S_IRUGO, show_read, NULL); | ||
82 | |||
83 | static ssize_t show_write(struct device *dev, struct device_attribute *attr, | ||
84 | char *buf) | ||
85 | { | ||
86 | struct pcf8575_data *data = dev_get_drvdata(dev); | ||
87 | if (data->write < 0) | ||
88 | return data->write; | ||
89 | return sprintf(buf, "%d\n", data->write); | ||
90 | } | ||
91 | |||
92 | static ssize_t set_write(struct device *dev, struct device_attribute *attr, | ||
93 | const char *buf, size_t count) | ||
94 | { | ||
95 | struct i2c_client *client = to_i2c_client(dev); | ||
96 | struct pcf8575_data *data = i2c_get_clientdata(client); | ||
97 | unsigned long val = simple_strtoul(buf, NULL, 10); | ||
98 | u8 iopin_state[2]; | ||
99 | |||
100 | if (val > 0xffff) | ||
101 | return -EINVAL; | ||
102 | |||
103 | data->write = val; | ||
104 | |||
105 | iopin_state[0] = val & 0xFF; | ||
106 | iopin_state[1] = val >> 8; | ||
107 | |||
108 | i2c_master_send(client, iopin_state, 2); | ||
109 | |||
110 | return count; | ||
111 | } | ||
112 | |||
113 | static DEVICE_ATTR(write, S_IWUSR | S_IRUGO, show_write, set_write); | ||
114 | |||
115 | static struct attribute *pcf8575_attributes[] = { | ||
116 | &dev_attr_read.attr, | ||
117 | &dev_attr_write.attr, | ||
118 | NULL | ||
119 | }; | ||
120 | |||
121 | static const struct attribute_group pcf8575_attr_group = { | ||
122 | .attrs = pcf8575_attributes, | ||
123 | }; | ||
124 | |||
125 | /* | ||
126 | * Real code | ||
127 | */ | ||
128 | |||
129 | static int pcf8575_attach_adapter(struct i2c_adapter *adapter) | ||
130 | { | ||
131 | return i2c_probe(adapter, &addr_data, pcf8575_detect); | ||
132 | } | ||
133 | |||
134 | /* This function is called by i2c_probe */ | ||
135 | static int pcf8575_detect(struct i2c_adapter *adapter, int address, int kind) | ||
136 | { | ||
137 | struct i2c_client *client; | ||
138 | struct pcf8575_data *data; | ||
139 | int err = 0; | ||
140 | |||
141 | if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) | ||
142 | goto exit; | ||
143 | |||
144 | /* OK. For now, we presume we have a valid client. We now create the | ||
145 | client structure, even though we cannot fill it completely yet. */ | ||
146 | data = kzalloc(sizeof(struct pcf8575_data), GFP_KERNEL); | ||
147 | if (!data) { | ||
148 | err = -ENOMEM; | ||
149 | goto exit; | ||
150 | } | ||
151 | |||
152 | client = &data->client; | ||
153 | i2c_set_clientdata(client, data); | ||
154 | client->addr = address; | ||
155 | client->adapter = adapter; | ||
156 | client->driver = &pcf8575_driver; | ||
157 | strlcpy(client->name, "pcf8575", I2C_NAME_SIZE); | ||
158 | data->write = -EAGAIN; | ||
159 | |||
160 | /* This is the place to detect whether the chip at the specified | ||
161 | address really is a PCF8575 chip. However, there is no method known | ||
162 | to detect whether an I2C chip is a PCF8575 or any other I2C chip. */ | ||
163 | |||
164 | /* Tell the I2C layer a new client has arrived */ | ||
165 | err = i2c_attach_client(client); | ||
166 | if (err) | ||
167 | goto exit_free; | ||
168 | |||
169 | /* Register sysfs hooks */ | ||
170 | err = sysfs_create_group(&client->dev.kobj, &pcf8575_attr_group); | ||
171 | if (err) | ||
172 | goto exit_detach; | ||
173 | |||
174 | return 0; | ||
175 | |||
176 | exit_detach: | ||
177 | i2c_detach_client(client); | ||
178 | exit_free: | ||
179 | kfree(data); | ||
180 | exit: | ||
181 | return err; | ||
182 | } | ||
183 | |||
184 | static int pcf8575_detach_client(struct i2c_client *client) | ||
185 | { | ||
186 | int err; | ||
187 | |||
188 | sysfs_remove_group(&client->dev.kobj, &pcf8575_attr_group); | ||
189 | |||
190 | err = i2c_detach_client(client); | ||
191 | if (err) | ||
192 | return err; | ||
193 | |||
194 | kfree(i2c_get_clientdata(client)); | ||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | static int __init pcf8575_init(void) | ||
199 | { | ||
200 | return i2c_add_driver(&pcf8575_driver); | ||
201 | } | ||
202 | |||
203 | static void __exit pcf8575_exit(void) | ||
204 | { | ||
205 | i2c_del_driver(&pcf8575_driver); | ||
206 | } | ||
207 | |||
208 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>, " | ||
209 | "Bart Van Assche <bart.vanassche@gmail.com>"); | ||
210 | MODULE_DESCRIPTION("pcf8575 driver"); | ||
211 | MODULE_LICENSE("GPL"); | ||
212 | |||
213 | module_init(pcf8575_init); | ||
214 | module_exit(pcf8575_exit); | ||
diff --git a/drivers/i2c/chips/pcf8591.c b/drivers/i2c/chips/pcf8591.c index 4dc36376eb32..865f4409c06b 100644 --- a/drivers/i2c/chips/pcf8591.c +++ b/drivers/i2c/chips/pcf8591.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include <linux/mutex.h> | 27 | #include <linux/mutex.h> |
28 | 28 | ||
29 | /* Addresses to scan */ | 29 | /* Addresses to scan */ |
30 | static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, | 30 | static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, |
31 | 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; | 31 | 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; |
32 | 32 | ||
33 | /* Insmod parameters */ | 33 | /* Insmod parameters */ |
diff --git a/drivers/i2c/chips/tps65010.c b/drivers/i2c/chips/tps65010.c index e320994b981c..4154a9108859 100644 --- a/drivers/i2c/chips/tps65010.c +++ b/drivers/i2c/chips/tps65010.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <linux/seq_file.h> | 31 | #include <linux/seq_file.h> |
32 | #include <linux/mutex.h> | 32 | #include <linux/mutex.h> |
33 | 33 | ||
34 | #include <asm/arch/tps65010.h> | 34 | #include <linux/i2c/tps65010.h> |
35 | 35 | ||
36 | /*-------------------------------------------------------------------------*/ | 36 | /*-------------------------------------------------------------------------*/ |
37 | 37 | ||
diff --git a/drivers/i2c/chips/tsl2550.c b/drivers/i2c/chips/tsl2550.c index 3de4b19ba08f..a10fd2791a69 100644 --- a/drivers/i2c/chips/tsl2550.c +++ b/drivers/i2c/chips/tsl2550.c | |||
@@ -432,11 +432,32 @@ static int __devexit tsl2550_remove(struct i2c_client *client) | |||
432 | return 0; | 432 | return 0; |
433 | } | 433 | } |
434 | 434 | ||
435 | #ifdef CONFIG_PM | ||
436 | |||
437 | static int tsl2550_suspend(struct i2c_client *client, pm_message_t mesg) | ||
438 | { | ||
439 | return tsl2550_set_power_state(client, 0); | ||
440 | } | ||
441 | |||
442 | static int tsl2550_resume(struct i2c_client *client) | ||
443 | { | ||
444 | return tsl2550_set_power_state(client, 1); | ||
445 | } | ||
446 | |||
447 | #else | ||
448 | |||
449 | #define tsl2550_suspend NULL | ||
450 | #define tsl2550_resume NULL | ||
451 | |||
452 | #endif /* CONFIG_PM */ | ||
453 | |||
435 | static struct i2c_driver tsl2550_driver = { | 454 | static struct i2c_driver tsl2550_driver = { |
436 | .driver = { | 455 | .driver = { |
437 | .name = TSL2550_DRV_NAME, | 456 | .name = TSL2550_DRV_NAME, |
438 | .owner = THIS_MODULE, | 457 | .owner = THIS_MODULE, |
439 | }, | 458 | }, |
459 | .suspend = tsl2550_suspend, | ||
460 | .resume = tsl2550_resume, | ||
440 | .probe = tsl2550_probe, | 461 | .probe = tsl2550_probe, |
441 | .remove = __devexit_p(tsl2550_remove), | 462 | .remove = __devexit_p(tsl2550_remove), |
442 | }; | 463 | }; |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index b5e13e405e72..96da22e9a5a4 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -33,14 +33,15 @@ | |||
33 | #include <linux/platform_device.h> | 33 | #include <linux/platform_device.h> |
34 | #include <linux/mutex.h> | 34 | #include <linux/mutex.h> |
35 | #include <linux/completion.h> | 35 | #include <linux/completion.h> |
36 | #include <linux/hardirq.h> | ||
37 | #include <linux/irqflags.h> | ||
36 | #include <asm/uaccess.h> | 38 | #include <asm/uaccess.h> |
39 | #include <asm/semaphore.h> | ||
37 | 40 | ||
38 | #include "i2c-core.h" | 41 | #include "i2c-core.h" |
39 | 42 | ||
40 | 43 | ||
41 | static LIST_HEAD(adapters); | 44 | static DEFINE_MUTEX(core_lock); |
42 | static LIST_HEAD(drivers); | ||
43 | static DEFINE_MUTEX(core_lists); | ||
44 | static DEFINE_IDR(i2c_adapter_idr); | 45 | static DEFINE_IDR(i2c_adapter_idr); |
45 | 46 | ||
46 | #define is_newstyle_driver(d) ((d)->probe || (d)->remove) | 47 | #define is_newstyle_driver(d) ((d)->probe || (d)->remove) |
@@ -198,6 +199,25 @@ static struct bus_type i2c_bus_type = { | |||
198 | .resume = i2c_device_resume, | 199 | .resume = i2c_device_resume, |
199 | }; | 200 | }; |
200 | 201 | ||
202 | |||
203 | /** | ||
204 | * i2c_verify_client - return parameter as i2c_client, or NULL | ||
205 | * @dev: device, probably from some driver model iterator | ||
206 | * | ||
207 | * When traversing the driver model tree, perhaps using driver model | ||
208 | * iterators like @device_for_each_child(), you can't assume very much | ||
209 | * about the nodes you find. Use this function to avoid oopses caused | ||
210 | * by wrongly treating some non-I2C device as an i2c_client. | ||
211 | */ | ||
212 | struct i2c_client *i2c_verify_client(struct device *dev) | ||
213 | { | ||
214 | return (dev->bus == &i2c_bus_type) | ||
215 | ? to_i2c_client(dev) | ||
216 | : NULL; | ||
217 | } | ||
218 | EXPORT_SYMBOL(i2c_verify_client); | ||
219 | |||
220 | |||
201 | /** | 221 | /** |
202 | * i2c_new_device - instantiate an i2c device for use with a new style driver | 222 | * i2c_new_device - instantiate an i2c device for use with a new style driver |
203 | * @adap: the adapter managing the device | 223 | * @adap: the adapter managing the device |
@@ -276,6 +296,50 @@ void i2c_unregister_device(struct i2c_client *client) | |||
276 | EXPORT_SYMBOL_GPL(i2c_unregister_device); | 296 | EXPORT_SYMBOL_GPL(i2c_unregister_device); |
277 | 297 | ||
278 | 298 | ||
299 | static int dummy_nop(struct i2c_client *client) | ||
300 | { | ||
301 | return 0; | ||
302 | } | ||
303 | |||
304 | static struct i2c_driver dummy_driver = { | ||
305 | .driver.name = "dummy", | ||
306 | .probe = dummy_nop, | ||
307 | .remove = dummy_nop, | ||
308 | }; | ||
309 | |||
310 | /** | ||
311 | * i2c_new_dummy - return a new i2c device bound to a dummy driver | ||
312 | * @adapter: the adapter managing the device | ||
313 | * @address: seven bit address to be used | ||
314 | * @type: optional label used for i2c_client.name | ||
315 | * Context: can sleep | ||
316 | * | ||
317 | * This returns an I2C client bound to the "dummy" driver, intended for use | ||
318 | * with devices that consume multiple addresses. Examples of such chips | ||
319 | * include various EEPROMS (like 24c04 and 24c08 models). | ||
320 | * | ||
321 | * These dummy devices have two main uses. First, most I2C and SMBus calls | ||
322 | * except i2c_transfer() need a client handle; the dummy will be that handle. | ||
323 | * And second, this prevents the specified address from being bound to a | ||
324 | * different driver. | ||
325 | * | ||
326 | * This returns the new i2c client, which should be saved for later use with | ||
327 | * i2c_unregister_device(); or NULL to indicate an error. | ||
328 | */ | ||
329 | struct i2c_client * | ||
330 | i2c_new_dummy(struct i2c_adapter *adapter, u16 address, const char *type) | ||
331 | { | ||
332 | struct i2c_board_info info = { | ||
333 | .driver_name = "dummy", | ||
334 | .addr = address, | ||
335 | }; | ||
336 | |||
337 | if (type) | ||
338 | strlcpy(info.type, type, sizeof info.type); | ||
339 | return i2c_new_device(adapter, &info); | ||
340 | } | ||
341 | EXPORT_SYMBOL_GPL(i2c_new_dummy); | ||
342 | |||
279 | /* ------------------------------------------------------------------------- */ | 343 | /* ------------------------------------------------------------------------- */ |
280 | 344 | ||
281 | /* I2C bus adapters -- one roots each I2C or SMBUS segment */ | 345 | /* I2C bus adapters -- one roots each I2C or SMBUS segment */ |
@@ -320,18 +384,27 @@ static void i2c_scan_static_board_info(struct i2c_adapter *adapter) | |||
320 | mutex_unlock(&__i2c_board_lock); | 384 | mutex_unlock(&__i2c_board_lock); |
321 | } | 385 | } |
322 | 386 | ||
387 | static int i2c_do_add_adapter(struct device_driver *d, void *data) | ||
388 | { | ||
389 | struct i2c_driver *driver = to_i2c_driver(d); | ||
390 | struct i2c_adapter *adap = data; | ||
391 | |||
392 | if (driver->attach_adapter) { | ||
393 | /* We ignore the return code; if it fails, too bad */ | ||
394 | driver->attach_adapter(adap); | ||
395 | } | ||
396 | return 0; | ||
397 | } | ||
398 | |||
323 | static int i2c_register_adapter(struct i2c_adapter *adap) | 399 | static int i2c_register_adapter(struct i2c_adapter *adap) |
324 | { | 400 | { |
325 | int res = 0; | 401 | int res = 0, dummy; |
326 | struct list_head *item; | ||
327 | struct i2c_driver *driver; | ||
328 | 402 | ||
329 | mutex_init(&adap->bus_lock); | 403 | mutex_init(&adap->bus_lock); |
330 | mutex_init(&adap->clist_lock); | 404 | mutex_init(&adap->clist_lock); |
331 | INIT_LIST_HEAD(&adap->clients); | 405 | INIT_LIST_HEAD(&adap->clients); |
332 | 406 | ||
333 | mutex_lock(&core_lists); | 407 | mutex_lock(&core_lock); |
334 | list_add_tail(&adap->list, &adapters); | ||
335 | 408 | ||
336 | /* Add the adapter to the driver core. | 409 | /* Add the adapter to the driver core. |
337 | * If the parent pointer is not set up, | 410 | * If the parent pointer is not set up, |
@@ -356,19 +429,14 @@ static int i2c_register_adapter(struct i2c_adapter *adap) | |||
356 | i2c_scan_static_board_info(adap); | 429 | i2c_scan_static_board_info(adap); |
357 | 430 | ||
358 | /* let legacy drivers scan this bus for matching devices */ | 431 | /* let legacy drivers scan this bus for matching devices */ |
359 | list_for_each(item,&drivers) { | 432 | dummy = bus_for_each_drv(&i2c_bus_type, NULL, adap, |
360 | driver = list_entry(item, struct i2c_driver, list); | 433 | i2c_do_add_adapter); |
361 | if (driver->attach_adapter) | ||
362 | /* We ignore the return code; if it fails, too bad */ | ||
363 | driver->attach_adapter(adap); | ||
364 | } | ||
365 | 434 | ||
366 | out_unlock: | 435 | out_unlock: |
367 | mutex_unlock(&core_lists); | 436 | mutex_unlock(&core_lock); |
368 | return res; | 437 | return res; |
369 | 438 | ||
370 | out_list: | 439 | out_list: |
371 | list_del(&adap->list); | ||
372 | idr_remove(&i2c_adapter_idr, adap->nr); | 440 | idr_remove(&i2c_adapter_idr, adap->nr); |
373 | goto out_unlock; | 441 | goto out_unlock; |
374 | } | 442 | } |
@@ -394,11 +462,11 @@ retry: | |||
394 | if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0) | 462 | if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0) |
395 | return -ENOMEM; | 463 | return -ENOMEM; |
396 | 464 | ||
397 | mutex_lock(&core_lists); | 465 | mutex_lock(&core_lock); |
398 | /* "above" here means "above or equal to", sigh */ | 466 | /* "above" here means "above or equal to", sigh */ |
399 | res = idr_get_new_above(&i2c_adapter_idr, adapter, | 467 | res = idr_get_new_above(&i2c_adapter_idr, adapter, |
400 | __i2c_first_dynamic_bus_num, &id); | 468 | __i2c_first_dynamic_bus_num, &id); |
401 | mutex_unlock(&core_lists); | 469 | mutex_unlock(&core_lock); |
402 | 470 | ||
403 | if (res < 0) { | 471 | if (res < 0) { |
404 | if (res == -EAGAIN) | 472 | if (res == -EAGAIN) |
@@ -443,7 +511,7 @@ retry: | |||
443 | if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0) | 511 | if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0) |
444 | return -ENOMEM; | 512 | return -ENOMEM; |
445 | 513 | ||
446 | mutex_lock(&core_lists); | 514 | mutex_lock(&core_lock); |
447 | /* "above" here means "above or equal to", sigh; | 515 | /* "above" here means "above or equal to", sigh; |
448 | * we need the "equal to" result to force the result | 516 | * we need the "equal to" result to force the result |
449 | */ | 517 | */ |
@@ -452,7 +520,7 @@ retry: | |||
452 | status = -EBUSY; | 520 | status = -EBUSY; |
453 | idr_remove(&i2c_adapter_idr, id); | 521 | idr_remove(&i2c_adapter_idr, id); |
454 | } | 522 | } |
455 | mutex_unlock(&core_lists); | 523 | mutex_unlock(&core_lock); |
456 | if (status == -EAGAIN) | 524 | if (status == -EAGAIN) |
457 | goto retry; | 525 | goto retry; |
458 | 526 | ||
@@ -462,6 +530,21 @@ retry: | |||
462 | } | 530 | } |
463 | EXPORT_SYMBOL_GPL(i2c_add_numbered_adapter); | 531 | EXPORT_SYMBOL_GPL(i2c_add_numbered_adapter); |
464 | 532 | ||
533 | static int i2c_do_del_adapter(struct device_driver *d, void *data) | ||
534 | { | ||
535 | struct i2c_driver *driver = to_i2c_driver(d); | ||
536 | struct i2c_adapter *adapter = data; | ||
537 | int res; | ||
538 | |||
539 | if (!driver->detach_adapter) | ||
540 | return 0; | ||
541 | res = driver->detach_adapter(adapter); | ||
542 | if (res) | ||
543 | dev_err(&adapter->dev, "detach_adapter failed (%d) " | ||
544 | "for driver [%s]\n", res, driver->driver.name); | ||
545 | return res; | ||
546 | } | ||
547 | |||
465 | /** | 548 | /** |
466 | * i2c_del_adapter - unregister I2C adapter | 549 | * i2c_del_adapter - unregister I2C adapter |
467 | * @adap: the adapter being unregistered | 550 | * @adap: the adapter being unregistered |
@@ -473,35 +556,24 @@ EXPORT_SYMBOL_GPL(i2c_add_numbered_adapter); | |||
473 | int i2c_del_adapter(struct i2c_adapter *adap) | 556 | int i2c_del_adapter(struct i2c_adapter *adap) |
474 | { | 557 | { |
475 | struct list_head *item, *_n; | 558 | struct list_head *item, *_n; |
476 | struct i2c_adapter *adap_from_list; | ||
477 | struct i2c_driver *driver; | ||
478 | struct i2c_client *client; | 559 | struct i2c_client *client; |
479 | int res = 0; | 560 | int res = 0; |
480 | 561 | ||
481 | mutex_lock(&core_lists); | 562 | mutex_lock(&core_lock); |
482 | 563 | ||
483 | /* First make sure that this adapter was ever added */ | 564 | /* First make sure that this adapter was ever added */ |
484 | list_for_each_entry(adap_from_list, &adapters, list) { | 565 | if (idr_find(&i2c_adapter_idr, adap->nr) != adap) { |
485 | if (adap_from_list == adap) | ||
486 | break; | ||
487 | } | ||
488 | if (adap_from_list != adap) { | ||
489 | pr_debug("i2c-core: attempting to delete unregistered " | 566 | pr_debug("i2c-core: attempting to delete unregistered " |
490 | "adapter [%s]\n", adap->name); | 567 | "adapter [%s]\n", adap->name); |
491 | res = -EINVAL; | 568 | res = -EINVAL; |
492 | goto out_unlock; | 569 | goto out_unlock; |
493 | } | 570 | } |
494 | 571 | ||
495 | list_for_each(item,&drivers) { | 572 | /* Tell drivers about this removal */ |
496 | driver = list_entry(item, struct i2c_driver, list); | 573 | res = bus_for_each_drv(&i2c_bus_type, NULL, adap, |
497 | if (driver->detach_adapter) | 574 | i2c_do_del_adapter); |
498 | if ((res = driver->detach_adapter(adap))) { | 575 | if (res) |
499 | dev_err(&adap->dev, "detach_adapter failed " | 576 | goto out_unlock; |
500 | "for driver [%s]\n", | ||
501 | driver->driver.name); | ||
502 | goto out_unlock; | ||
503 | } | ||
504 | } | ||
505 | 577 | ||
506 | /* detach any active clients. This must be done first, because | 578 | /* detach any active clients. This must be done first, because |
507 | * it can fail; in which case we give up. */ | 579 | * it can fail; in which case we give up. */ |
@@ -529,7 +601,6 @@ int i2c_del_adapter(struct i2c_adapter *adap) | |||
529 | /* clean up the sysfs representation */ | 601 | /* clean up the sysfs representation */ |
530 | init_completion(&adap->dev_released); | 602 | init_completion(&adap->dev_released); |
531 | device_unregister(&adap->dev); | 603 | device_unregister(&adap->dev); |
532 | list_del(&adap->list); | ||
533 | 604 | ||
534 | /* wait for sysfs to drop all references */ | 605 | /* wait for sysfs to drop all references */ |
535 | wait_for_completion(&adap->dev_released); | 606 | wait_for_completion(&adap->dev_released); |
@@ -540,7 +611,7 @@ int i2c_del_adapter(struct i2c_adapter *adap) | |||
540 | dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name); | 611 | dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name); |
541 | 612 | ||
542 | out_unlock: | 613 | out_unlock: |
543 | mutex_unlock(&core_lists); | 614 | mutex_unlock(&core_lock); |
544 | return res; | 615 | return res; |
545 | } | 616 | } |
546 | EXPORT_SYMBOL(i2c_del_adapter); | 617 | EXPORT_SYMBOL(i2c_del_adapter); |
@@ -583,21 +654,23 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver) | |||
583 | if (res) | 654 | if (res) |
584 | return res; | 655 | return res; |
585 | 656 | ||
586 | mutex_lock(&core_lists); | 657 | mutex_lock(&core_lock); |
587 | 658 | ||
588 | list_add_tail(&driver->list,&drivers); | ||
589 | pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name); | 659 | pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name); |
590 | 660 | ||
591 | /* legacy drivers scan i2c busses directly */ | 661 | /* legacy drivers scan i2c busses directly */ |
592 | if (driver->attach_adapter) { | 662 | if (driver->attach_adapter) { |
593 | struct i2c_adapter *adapter; | 663 | struct i2c_adapter *adapter; |
594 | 664 | ||
595 | list_for_each_entry(adapter, &adapters, list) { | 665 | down(&i2c_adapter_class.sem); |
666 | list_for_each_entry(adapter, &i2c_adapter_class.devices, | ||
667 | dev.node) { | ||
596 | driver->attach_adapter(adapter); | 668 | driver->attach_adapter(adapter); |
597 | } | 669 | } |
670 | up(&i2c_adapter_class.sem); | ||
598 | } | 671 | } |
599 | 672 | ||
600 | mutex_unlock(&core_lists); | 673 | mutex_unlock(&core_lock); |
601 | return 0; | 674 | return 0; |
602 | } | 675 | } |
603 | EXPORT_SYMBOL(i2c_register_driver); | 676 | EXPORT_SYMBOL(i2c_register_driver); |
@@ -609,11 +682,11 @@ EXPORT_SYMBOL(i2c_register_driver); | |||
609 | */ | 682 | */ |
610 | void i2c_del_driver(struct i2c_driver *driver) | 683 | void i2c_del_driver(struct i2c_driver *driver) |
611 | { | 684 | { |
612 | struct list_head *item1, *item2, *_n; | 685 | struct list_head *item2, *_n; |
613 | struct i2c_client *client; | 686 | struct i2c_client *client; |
614 | struct i2c_adapter *adap; | 687 | struct i2c_adapter *adap; |
615 | 688 | ||
616 | mutex_lock(&core_lists); | 689 | mutex_lock(&core_lock); |
617 | 690 | ||
618 | /* new-style driver? */ | 691 | /* new-style driver? */ |
619 | if (is_newstyle_driver(driver)) | 692 | if (is_newstyle_driver(driver)) |
@@ -623,8 +696,8 @@ void i2c_del_driver(struct i2c_driver *driver) | |||
623 | * attached. If so, detach them to be able to kill the driver | 696 | * attached. If so, detach them to be able to kill the driver |
624 | * afterwards. | 697 | * afterwards. |
625 | */ | 698 | */ |
626 | list_for_each(item1,&adapters) { | 699 | down(&i2c_adapter_class.sem); |
627 | adap = list_entry(item1, struct i2c_adapter, list); | 700 | list_for_each_entry(adap, &i2c_adapter_class.devices, dev.node) { |
628 | if (driver->detach_adapter) { | 701 | if (driver->detach_adapter) { |
629 | if (driver->detach_adapter(adap)) { | 702 | if (driver->detach_adapter(adap)) { |
630 | dev_err(&adap->dev, "detach_adapter failed " | 703 | dev_err(&adap->dev, "detach_adapter failed " |
@@ -648,40 +721,31 @@ void i2c_del_driver(struct i2c_driver *driver) | |||
648 | } | 721 | } |
649 | } | 722 | } |
650 | } | 723 | } |
724 | up(&i2c_adapter_class.sem); | ||
651 | 725 | ||
652 | unregister: | 726 | unregister: |
653 | driver_unregister(&driver->driver); | 727 | driver_unregister(&driver->driver); |
654 | list_del(&driver->list); | ||
655 | pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name); | 728 | pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name); |
656 | 729 | ||
657 | mutex_unlock(&core_lists); | 730 | mutex_unlock(&core_lock); |
658 | } | 731 | } |
659 | EXPORT_SYMBOL(i2c_del_driver); | 732 | EXPORT_SYMBOL(i2c_del_driver); |
660 | 733 | ||
661 | /* ------------------------------------------------------------------------- */ | 734 | /* ------------------------------------------------------------------------- */ |
662 | 735 | ||
663 | static int __i2c_check_addr(struct i2c_adapter *adapter, unsigned int addr) | 736 | static int __i2c_check_addr(struct device *dev, void *addrp) |
664 | { | 737 | { |
665 | struct list_head *item; | 738 | struct i2c_client *client = i2c_verify_client(dev); |
666 | struct i2c_client *client; | 739 | int addr = *(int *)addrp; |
667 | 740 | ||
668 | list_for_each(item,&adapter->clients) { | 741 | if (client && client->addr == addr) |
669 | client = list_entry(item, struct i2c_client, list); | 742 | return -EBUSY; |
670 | if (client->addr == addr) | ||
671 | return -EBUSY; | ||
672 | } | ||
673 | return 0; | 743 | return 0; |
674 | } | 744 | } |
675 | 745 | ||
676 | static int i2c_check_addr(struct i2c_adapter *adapter, int addr) | 746 | static int i2c_check_addr(struct i2c_adapter *adapter, int addr) |
677 | { | 747 | { |
678 | int rval; | 748 | return device_for_each_child(&adapter->dev, &addr, __i2c_check_addr); |
679 | |||
680 | mutex_lock(&adapter->clist_lock); | ||
681 | rval = __i2c_check_addr(adapter, addr); | ||
682 | mutex_unlock(&adapter->clist_lock); | ||
683 | |||
684 | return rval; | ||
685 | } | 749 | } |
686 | 750 | ||
687 | int i2c_attach_client(struct i2c_client *client) | 751 | int i2c_attach_client(struct i2c_client *client) |
@@ -689,15 +753,6 @@ int i2c_attach_client(struct i2c_client *client) | |||
689 | struct i2c_adapter *adapter = client->adapter; | 753 | struct i2c_adapter *adapter = client->adapter; |
690 | int res = 0; | 754 | int res = 0; |
691 | 755 | ||
692 | mutex_lock(&adapter->clist_lock); | ||
693 | if (__i2c_check_addr(client->adapter, client->addr)) { | ||
694 | res = -EBUSY; | ||
695 | goto out_unlock; | ||
696 | } | ||
697 | list_add_tail(&client->list,&adapter->clients); | ||
698 | |||
699 | client->usage_count = 0; | ||
700 | |||
701 | client->dev.parent = &client->adapter->dev; | 756 | client->dev.parent = &client->adapter->dev; |
702 | client->dev.bus = &i2c_bus_type; | 757 | client->dev.bus = &i2c_bus_type; |
703 | 758 | ||
@@ -712,13 +767,17 @@ int i2c_attach_client(struct i2c_client *client) | |||
712 | 767 | ||
713 | snprintf(&client->dev.bus_id[0], sizeof(client->dev.bus_id), | 768 | snprintf(&client->dev.bus_id[0], sizeof(client->dev.bus_id), |
714 | "%d-%04x", i2c_adapter_id(adapter), client->addr); | 769 | "%d-%04x", i2c_adapter_id(adapter), client->addr); |
715 | dev_dbg(&adapter->dev, "client [%s] registered with bus id %s\n", | ||
716 | client->name, client->dev.bus_id); | ||
717 | res = device_register(&client->dev); | 770 | res = device_register(&client->dev); |
718 | if (res) | 771 | if (res) |
719 | goto out_list; | 772 | goto out_err; |
773 | |||
774 | mutex_lock(&adapter->clist_lock); | ||
775 | list_add_tail(&client->list, &adapter->clients); | ||
720 | mutex_unlock(&adapter->clist_lock); | 776 | mutex_unlock(&adapter->clist_lock); |
721 | 777 | ||
778 | dev_dbg(&adapter->dev, "client [%s] registered with bus id %s\n", | ||
779 | client->name, client->dev.bus_id); | ||
780 | |||
722 | if (adapter->client_register) { | 781 | if (adapter->client_register) { |
723 | if (adapter->client_register(client)) { | 782 | if (adapter->client_register(client)) { |
724 | dev_dbg(&adapter->dev, "client_register " | 783 | dev_dbg(&adapter->dev, "client_register " |
@@ -729,12 +788,9 @@ int i2c_attach_client(struct i2c_client *client) | |||
729 | 788 | ||
730 | return 0; | 789 | return 0; |
731 | 790 | ||
732 | out_list: | 791 | out_err: |
733 | list_del(&client->list); | ||
734 | dev_err(&adapter->dev, "Failed to attach i2c client %s at 0x%02x " | 792 | dev_err(&adapter->dev, "Failed to attach i2c client %s at 0x%02x " |
735 | "(%d)\n", client->name, client->addr, res); | 793 | "(%d)\n", client->name, client->addr, res); |
736 | out_unlock: | ||
737 | mutex_unlock(&adapter->clist_lock); | ||
738 | return res; | 794 | return res; |
739 | } | 795 | } |
740 | EXPORT_SYMBOL(i2c_attach_client); | 796 | EXPORT_SYMBOL(i2c_attach_client); |
@@ -744,12 +800,6 @@ int i2c_detach_client(struct i2c_client *client) | |||
744 | struct i2c_adapter *adapter = client->adapter; | 800 | struct i2c_adapter *adapter = client->adapter; |
745 | int res = 0; | 801 | int res = 0; |
746 | 802 | ||
747 | if (client->usage_count > 0) { | ||
748 | dev_warn(&client->dev, "Client [%s] still busy, " | ||
749 | "can't detach\n", client->name); | ||
750 | return -EBUSY; | ||
751 | } | ||
752 | |||
753 | if (adapter->client_unregister) { | 803 | if (adapter->client_unregister) { |
754 | res = adapter->client_unregister(client); | 804 | res = adapter->client_unregister(client); |
755 | if (res) { | 805 | if (res) { |
@@ -762,9 +812,10 @@ int i2c_detach_client(struct i2c_client *client) | |||
762 | 812 | ||
763 | mutex_lock(&adapter->clist_lock); | 813 | mutex_lock(&adapter->clist_lock); |
764 | list_del(&client->list); | 814 | list_del(&client->list); |
815 | mutex_unlock(&adapter->clist_lock); | ||
816 | |||
765 | init_completion(&client->released); | 817 | init_completion(&client->released); |
766 | device_unregister(&client->dev); | 818 | device_unregister(&client->dev); |
767 | mutex_unlock(&adapter->clist_lock); | ||
768 | wait_for_completion(&client->released); | 819 | wait_for_completion(&client->released); |
769 | 820 | ||
770 | out: | 821 | out: |
@@ -772,72 +823,58 @@ int i2c_detach_client(struct i2c_client *client) | |||
772 | } | 823 | } |
773 | EXPORT_SYMBOL(i2c_detach_client); | 824 | EXPORT_SYMBOL(i2c_detach_client); |
774 | 825 | ||
775 | static int i2c_inc_use_client(struct i2c_client *client) | 826 | /** |
827 | * i2c_use_client - increments the reference count of the i2c client structure | ||
828 | * @client: the client being referenced | ||
829 | * | ||
830 | * Each live reference to a client should be refcounted. The driver model does | ||
831 | * that automatically as part of driver binding, so that most drivers don't | ||
832 | * need to do this explicitly: they hold a reference until they're unbound | ||
833 | * from the device. | ||
834 | * | ||
835 | * A pointer to the client with the incremented reference counter is returned. | ||
836 | */ | ||
837 | struct i2c_client *i2c_use_client(struct i2c_client *client) | ||
776 | { | 838 | { |
777 | 839 | get_device(&client->dev); | |
778 | if (!try_module_get(client->driver->driver.owner)) | 840 | return client; |
779 | return -ENODEV; | ||
780 | if (!try_module_get(client->adapter->owner)) { | ||
781 | module_put(client->driver->driver.owner); | ||
782 | return -ENODEV; | ||
783 | } | ||
784 | |||
785 | return 0; | ||
786 | } | 841 | } |
842 | EXPORT_SYMBOL(i2c_use_client); | ||
787 | 843 | ||
788 | static void i2c_dec_use_client(struct i2c_client *client) | 844 | /** |
845 | * i2c_release_client - release a use of the i2c client structure | ||
846 | * @client: the client being no longer referenced | ||
847 | * | ||
848 | * Must be called when a user of a client is finished with it. | ||
849 | */ | ||
850 | void i2c_release_client(struct i2c_client *client) | ||
789 | { | 851 | { |
790 | module_put(client->driver->driver.owner); | 852 | put_device(&client->dev); |
791 | module_put(client->adapter->owner); | ||
792 | } | 853 | } |
854 | EXPORT_SYMBOL(i2c_release_client); | ||
793 | 855 | ||
794 | int i2c_use_client(struct i2c_client *client) | 856 | struct i2c_cmd_arg { |
795 | { | 857 | unsigned cmd; |
796 | int ret; | 858 | void *arg; |
797 | 859 | }; | |
798 | ret = i2c_inc_use_client(client); | ||
799 | if (ret) | ||
800 | return ret; | ||
801 | |||
802 | client->usage_count++; | ||
803 | |||
804 | return 0; | ||
805 | } | ||
806 | EXPORT_SYMBOL(i2c_use_client); | ||
807 | 860 | ||
808 | int i2c_release_client(struct i2c_client *client) | 861 | static int i2c_cmd(struct device *dev, void *_arg) |
809 | { | 862 | { |
810 | if (!client->usage_count) { | 863 | struct i2c_client *client = i2c_verify_client(dev); |
811 | pr_debug("i2c-core: %s used one too many times\n", | 864 | struct i2c_cmd_arg *arg = _arg; |
812 | __FUNCTION__); | ||
813 | return -EPERM; | ||
814 | } | ||
815 | |||
816 | client->usage_count--; | ||
817 | i2c_dec_use_client(client); | ||
818 | 865 | ||
866 | if (client && client->driver && client->driver->command) | ||
867 | client->driver->command(client, arg->cmd, arg->arg); | ||
819 | return 0; | 868 | return 0; |
820 | } | 869 | } |
821 | EXPORT_SYMBOL(i2c_release_client); | ||
822 | 870 | ||
823 | void i2c_clients_command(struct i2c_adapter *adap, unsigned int cmd, void *arg) | 871 | void i2c_clients_command(struct i2c_adapter *adap, unsigned int cmd, void *arg) |
824 | { | 872 | { |
825 | struct list_head *item; | 873 | struct i2c_cmd_arg cmd_arg; |
826 | struct i2c_client *client; | ||
827 | 874 | ||
828 | mutex_lock(&adap->clist_lock); | 875 | cmd_arg.cmd = cmd; |
829 | list_for_each(item,&adap->clients) { | 876 | cmd_arg.arg = arg; |
830 | client = list_entry(item, struct i2c_client, list); | 877 | device_for_each_child(&adap->dev, &cmd_arg, i2c_cmd); |
831 | if (!try_module_get(client->driver->driver.owner)) | ||
832 | continue; | ||
833 | if (NULL != client->driver->command) { | ||
834 | mutex_unlock(&adap->clist_lock); | ||
835 | client->driver->command(client,cmd,arg); | ||
836 | mutex_lock(&adap->clist_lock); | ||
837 | } | ||
838 | module_put(client->driver->driver.owner); | ||
839 | } | ||
840 | mutex_unlock(&adap->clist_lock); | ||
841 | } | 878 | } |
842 | EXPORT_SYMBOL(i2c_clients_command); | 879 | EXPORT_SYMBOL(i2c_clients_command); |
843 | 880 | ||
@@ -848,11 +885,24 @@ static int __init i2c_init(void) | |||
848 | retval = bus_register(&i2c_bus_type); | 885 | retval = bus_register(&i2c_bus_type); |
849 | if (retval) | 886 | if (retval) |
850 | return retval; | 887 | return retval; |
851 | return class_register(&i2c_adapter_class); | 888 | retval = class_register(&i2c_adapter_class); |
889 | if (retval) | ||
890 | goto bus_err; | ||
891 | retval = i2c_add_driver(&dummy_driver); | ||
892 | if (retval) | ||
893 | goto class_err; | ||
894 | return 0; | ||
895 | |||
896 | class_err: | ||
897 | class_unregister(&i2c_adapter_class); | ||
898 | bus_err: | ||
899 | bus_unregister(&i2c_bus_type); | ||
900 | return retval; | ||
852 | } | 901 | } |
853 | 902 | ||
854 | static void __exit i2c_exit(void) | 903 | static void __exit i2c_exit(void) |
855 | { | 904 | { |
905 | i2c_del_driver(&dummy_driver); | ||
856 | class_unregister(&i2c_adapter_class); | 906 | class_unregister(&i2c_adapter_class); |
857 | bus_unregister(&i2c_bus_type); | 907 | bus_unregister(&i2c_bus_type); |
858 | } | 908 | } |
@@ -879,7 +929,15 @@ int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num) | |||
879 | } | 929 | } |
880 | #endif | 930 | #endif |
881 | 931 | ||
882 | mutex_lock_nested(&adap->bus_lock, adap->level); | 932 | if (in_atomic() || irqs_disabled()) { |
933 | ret = mutex_trylock(&adap->bus_lock); | ||
934 | if (!ret) | ||
935 | /* I2C activity is ongoing. */ | ||
936 | return -EAGAIN; | ||
937 | } else { | ||
938 | mutex_lock_nested(&adap->bus_lock, adap->level); | ||
939 | } | ||
940 | |||
883 | ret = adap->algo->master_xfer(adap,msgs,num); | 941 | ret = adap->algo->master_xfer(adap,msgs,num); |
884 | mutex_unlock(&adap->bus_lock); | 942 | mutex_unlock(&adap->bus_lock); |
885 | 943 | ||
@@ -978,7 +1036,7 @@ static int i2c_probe_address(struct i2c_adapter *adapter, int addr, int kind, | |||
978 | } | 1036 | } |
979 | 1037 | ||
980 | int i2c_probe(struct i2c_adapter *adapter, | 1038 | int i2c_probe(struct i2c_adapter *adapter, |
981 | struct i2c_client_address_data *address_data, | 1039 | const struct i2c_client_address_data *address_data, |
982 | int (*found_proc) (struct i2c_adapter *, int, int)) | 1040 | int (*found_proc) (struct i2c_adapter *, int, int)) |
983 | { | 1041 | { |
984 | int i, err; | 1042 | int i, err; |
@@ -987,7 +1045,7 @@ int i2c_probe(struct i2c_adapter *adapter, | |||
987 | /* Force entries are done first, and are not affected by ignore | 1045 | /* Force entries are done first, and are not affected by ignore |
988 | entries */ | 1046 | entries */ |
989 | if (address_data->forces) { | 1047 | if (address_data->forces) { |
990 | unsigned short **forces = address_data->forces; | 1048 | const unsigned short * const *forces = address_data->forces; |
991 | int kind; | 1049 | int kind; |
992 | 1050 | ||
993 | for (kind = 0; forces[kind]; kind++) { | 1051 | for (kind = 0; forces[kind]; kind++) { |
@@ -1085,7 +1143,6 @@ i2c_new_probed_device(struct i2c_adapter *adap, | |||
1085 | return NULL; | 1143 | return NULL; |
1086 | } | 1144 | } |
1087 | 1145 | ||
1088 | mutex_lock(&adap->clist_lock); | ||
1089 | for (i = 0; addr_list[i] != I2C_CLIENT_END; i++) { | 1146 | for (i = 0; addr_list[i] != I2C_CLIENT_END; i++) { |
1090 | /* Check address validity */ | 1147 | /* Check address validity */ |
1091 | if (addr_list[i] < 0x03 || addr_list[i] > 0x77) { | 1148 | if (addr_list[i] < 0x03 || addr_list[i] > 0x77) { |
@@ -1095,7 +1152,7 @@ i2c_new_probed_device(struct i2c_adapter *adap, | |||
1095 | } | 1152 | } |
1096 | 1153 | ||
1097 | /* Check address availability */ | 1154 | /* Check address availability */ |
1098 | if (__i2c_check_addr(adap, addr_list[i])) { | 1155 | if (i2c_check_addr(adap, addr_list[i])) { |
1099 | dev_dbg(&adap->dev, "Address 0x%02x already in " | 1156 | dev_dbg(&adap->dev, "Address 0x%02x already in " |
1100 | "use, not probing\n", addr_list[i]); | 1157 | "use, not probing\n", addr_list[i]); |
1101 | continue; | 1158 | continue; |
@@ -1123,7 +1180,6 @@ i2c_new_probed_device(struct i2c_adapter *adap, | |||
1123 | break; | 1180 | break; |
1124 | } | 1181 | } |
1125 | } | 1182 | } |
1126 | mutex_unlock(&adap->clist_lock); | ||
1127 | 1183 | ||
1128 | if (addr_list[i] == I2C_CLIENT_END) { | 1184 | if (addr_list[i] == I2C_CLIENT_END) { |
1129 | dev_dbg(&adap->dev, "Probing failed, no device found\n"); | 1185 | dev_dbg(&adap->dev, "Probing failed, no device found\n"); |
@@ -1139,12 +1195,12 @@ struct i2c_adapter* i2c_get_adapter(int id) | |||
1139 | { | 1195 | { |
1140 | struct i2c_adapter *adapter; | 1196 | struct i2c_adapter *adapter; |
1141 | 1197 | ||
1142 | mutex_lock(&core_lists); | 1198 | mutex_lock(&core_lock); |
1143 | adapter = (struct i2c_adapter *)idr_find(&i2c_adapter_idr, id); | 1199 | adapter = (struct i2c_adapter *)idr_find(&i2c_adapter_idr, id); |
1144 | if (adapter && !try_module_get(adapter->owner)) | 1200 | if (adapter && !try_module_get(adapter->owner)) |
1145 | adapter = NULL; | 1201 | adapter = NULL; |
1146 | 1202 | ||
1147 | mutex_unlock(&core_lists); | 1203 | mutex_unlock(&core_lock); |
1148 | return adapter; | 1204 | return adapter; |
1149 | } | 1205 | } |
1150 | EXPORT_SYMBOL(i2c_get_adapter); | 1206 | EXPORT_SYMBOL(i2c_get_adapter); |
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index df540d5dfaf4..393e679d9faa 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c | |||
@@ -182,27 +182,22 @@ static ssize_t i2cdev_write (struct file *file, const char __user *buf, size_t c | |||
182 | return ret; | 182 | return ret; |
183 | } | 183 | } |
184 | 184 | ||
185 | static int i2cdev_check(struct device *dev, void *addrp) | ||
186 | { | ||
187 | struct i2c_client *client = i2c_verify_client(dev); | ||
188 | |||
189 | if (!client || client->addr != *(unsigned int *)addrp) | ||
190 | return 0; | ||
191 | |||
192 | return dev->driver ? -EBUSY : 0; | ||
193 | } | ||
194 | |||
185 | /* This address checking function differs from the one in i2c-core | 195 | /* This address checking function differs from the one in i2c-core |
186 | in that it considers an address with a registered device, but no | 196 | in that it considers an address with a registered device, but no |
187 | bound driver, as NOT busy. */ | 197 | driver bound to it, as NOT busy. */ |
188 | static int i2cdev_check_addr(struct i2c_adapter *adapter, unsigned int addr) | 198 | static int i2cdev_check_addr(struct i2c_adapter *adapter, unsigned int addr) |
189 | { | 199 | { |
190 | struct list_head *item; | 200 | return device_for_each_child(&adapter->dev, &addr, i2cdev_check); |
191 | struct i2c_client *client; | ||
192 | int res = 0; | ||
193 | |||
194 | mutex_lock(&adapter->clist_lock); | ||
195 | list_for_each(item, &adapter->clients) { | ||
196 | client = list_entry(item, struct i2c_client, list); | ||
197 | if (client->addr == addr) { | ||
198 | if (client->driver) | ||
199 | res = -EBUSY; | ||
200 | break; | ||
201 | } | ||
202 | } | ||
203 | mutex_unlock(&adapter->clist_lock); | ||
204 | |||
205 | return res; | ||
206 | } | 201 | } |
207 | 202 | ||
208 | static int i2cdev_ioctl(struct inode *inode, struct file *file, | 203 | static int i2cdev_ioctl(struct inode *inode, struct file *file, |
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index ee01e273a537..64df55e20ab5 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig | |||
@@ -325,7 +325,7 @@ config BLK_DEV_PLATFORM | |||
325 | If unsure, say N. | 325 | If unsure, say N. |
326 | 326 | ||
327 | config BLK_DEV_CMD640 | 327 | config BLK_DEV_CMD640 |
328 | bool "CMD640 chipset bugfix/support" | 328 | tristate "CMD640 chipset bugfix/support" |
329 | depends on X86 | 329 | depends on X86 |
330 | ---help--- | 330 | ---help--- |
331 | The CMD-Technologies CMD640 IDE chip is used on many common 486 and | 331 | The CMD-Technologies CMD640 IDE chip is used on many common 486 and |
@@ -359,9 +359,8 @@ config BLK_DEV_CMD640_ENHANCED | |||
359 | Otherwise say N. | 359 | Otherwise say N. |
360 | 360 | ||
361 | config BLK_DEV_IDEPNP | 361 | config BLK_DEV_IDEPNP |
362 | bool "PNP EIDE support" | 362 | tristate "PNP EIDE support" |
363 | depends on PNP | 363 | depends on PNP |
364 | select IDE_GENERIC | ||
365 | help | 364 | help |
366 | If you have a PnP (Plug and Play) compatible EIDE card and | 365 | If you have a PnP (Plug and Play) compatible EIDE card and |
367 | would like the kernel to automatically detect and activate | 366 | would like the kernel to automatically detect and activate |
@@ -375,7 +374,19 @@ config BLK_DEV_IDEPCI | |||
375 | bool | 374 | bool |
376 | 375 | ||
377 | config IDEPCI_PCIBUS_ORDER | 376 | config IDEPCI_PCIBUS_ORDER |
378 | def_bool BLK_DEV_IDE=y && BLK_DEV_IDEPCI | 377 | bool "Probe IDE PCI devices in the PCI bus order (DEPRECATED)" |
378 | depends on BLK_DEV_IDE=y && BLK_DEV_IDEPCI | ||
379 | default y | ||
380 | help | ||
381 | Probe IDE PCI devices in the order in which they appear on the | ||
382 | PCI bus (i.e. 00:1f.1 PCI device before 02:01.0 PCI device) | ||
383 | instead of the order in which IDE PCI host drivers are loaded. | ||
384 | |||
385 | Please note that this method of assuring stable naming of | ||
386 | IDE devices is unreliable and use other means for achieving | ||
387 | it (i.e. udev). | ||
388 | |||
389 | If in doubt, say N. | ||
379 | 390 | ||
380 | # TODO: split it on per host driver config options (or module parameters) | 391 | # TODO: split it on per host driver config options (or module parameters) |
381 | config BLK_DEV_OFFBOARD | 392 | config BLK_DEV_OFFBOARD |
@@ -789,7 +800,7 @@ config BLK_DEV_CELLEB | |||
789 | endif | 800 | endif |
790 | 801 | ||
791 | config BLK_DEV_IDE_PMAC | 802 | config BLK_DEV_IDE_PMAC |
792 | bool "Builtin PowerMac IDE support" | 803 | tristate "Builtin PowerMac IDE support" |
793 | depends on PPC_PMAC && IDE=y && BLK_DEV_IDE=y | 804 | depends on PPC_PMAC && IDE=y && BLK_DEV_IDE=y |
794 | help | 805 | help |
795 | This driver provides support for the built-in IDE controller on | 806 | This driver provides support for the built-in IDE controller on |
@@ -843,8 +854,9 @@ config BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ | |||
843 | depends on BLK_DEV_IDE_AU1XXX | 854 | depends on BLK_DEV_IDE_AU1XXX |
844 | 855 | ||
845 | config IDE_ARM | 856 | config IDE_ARM |
846 | def_bool ARM && (ARCH_CLPS7500 || ARCH_RPC || ARCH_SHARK) | 857 | tristate "ARM IDE support" |
847 | select IDE_GENERIC | 858 | depends on ARM && (ARCH_CLPS7500 || ARCH_RPC || ARCH_SHARK) |
859 | default y | ||
848 | 860 | ||
849 | config BLK_DEV_IDE_ICSIDE | 861 | config BLK_DEV_IDE_ICSIDE |
850 | tristate "ICS IDE interface support" | 862 | tristate "ICS IDE interface support" |
@@ -876,10 +888,9 @@ config BLK_DEV_IDE_BAST | |||
876 | Simtec BAST or the Thorcom VR1000 | 888 | Simtec BAST or the Thorcom VR1000 |
877 | 889 | ||
878 | config ETRAX_IDE | 890 | config ETRAX_IDE |
879 | bool "ETRAX IDE support" | 891 | tristate "ETRAX IDE support" |
880 | depends on CRIS && BROKEN | 892 | depends on CRIS && BROKEN |
881 | select BLK_DEV_IDEDMA | 893 | select BLK_DEV_IDEDMA |
882 | select IDE_GENERIC | ||
883 | help | 894 | help |
884 | Enables the ETRAX IDE driver. | 895 | Enables the ETRAX IDE driver. |
885 | 896 | ||
@@ -911,17 +922,15 @@ config ETRAX_IDE_G27_RESET | |||
911 | endchoice | 922 | endchoice |
912 | 923 | ||
913 | config IDE_H8300 | 924 | config IDE_H8300 |
914 | bool "H8300 IDE support" | 925 | tristate "H8300 IDE support" |
915 | depends on H8300 | 926 | depends on H8300 |
916 | select IDE_GENERIC | ||
917 | default y | 927 | default y |
918 | help | 928 | help |
919 | Enables the H8300 IDE driver. | 929 | Enables the H8300 IDE driver. |
920 | 930 | ||
921 | config BLK_DEV_GAYLE | 931 | config BLK_DEV_GAYLE |
922 | bool "Amiga Gayle IDE interface support" | 932 | tristate "Amiga Gayle IDE interface support" |
923 | depends on AMIGA | 933 | depends on AMIGA |
924 | select IDE_GENERIC | ||
925 | help | 934 | help |
926 | This is the IDE driver for the Amiga Gayle IDE interface. It supports | 935 | This is the IDE driver for the Amiga Gayle IDE interface. It supports |
927 | both the `A1200 style' and `A4000 style' of the Gayle IDE interface, | 936 | both the `A1200 style' and `A4000 style' of the Gayle IDE interface, |
@@ -951,9 +960,8 @@ config BLK_DEV_IDEDOUBLER | |||
951 | runtime using the "ide=doubler" kernel boot parameter. | 960 | runtime using the "ide=doubler" kernel boot parameter. |
952 | 961 | ||
953 | config BLK_DEV_BUDDHA | 962 | config BLK_DEV_BUDDHA |
954 | bool "Buddha/Catweasel/X-Surf IDE interface support (EXPERIMENTAL)" | 963 | tristate "Buddha/Catweasel/X-Surf IDE interface support (EXPERIMENTAL)" |
955 | depends on ZORRO && EXPERIMENTAL | 964 | depends on ZORRO && EXPERIMENTAL |
956 | select IDE_GENERIC | ||
957 | help | 965 | help |
958 | This is the IDE driver for the IDE interfaces on the Buddha, | 966 | This is the IDE driver for the IDE interfaces on the Buddha, |
959 | Catweasel and X-Surf expansion boards. It supports up to two interfaces | 967 | Catweasel and X-Surf expansion boards. It supports up to two interfaces |
@@ -964,9 +972,8 @@ config BLK_DEV_BUDDHA | |||
964 | to one of its IDE interfaces. | 972 | to one of its IDE interfaces. |
965 | 973 | ||
966 | config BLK_DEV_FALCON_IDE | 974 | config BLK_DEV_FALCON_IDE |
967 | bool "Falcon IDE interface support" | 975 | tristate "Falcon IDE interface support" |
968 | depends on ATARI | 976 | depends on ATARI |
969 | select IDE_GENERIC | ||
970 | help | 977 | help |
971 | This is the IDE driver for the builtin IDE interface on the Atari | 978 | This is the IDE driver for the builtin IDE interface on the Atari |
972 | Falcon. Say Y if you have a Falcon and want to use IDE devices (hard | 979 | Falcon. Say Y if you have a Falcon and want to use IDE devices (hard |
@@ -974,9 +981,8 @@ config BLK_DEV_FALCON_IDE | |||
974 | interface. | 981 | interface. |
975 | 982 | ||
976 | config BLK_DEV_MAC_IDE | 983 | config BLK_DEV_MAC_IDE |
977 | bool "Macintosh Quadra/Powerbook IDE interface support" | 984 | tristate "Macintosh Quadra/Powerbook IDE interface support" |
978 | depends on MAC | 985 | depends on MAC |
979 | select IDE_GENERIC | ||
980 | help | 986 | help |
981 | This is the IDE driver for the builtin IDE interface on some m68k | 987 | This is the IDE driver for the builtin IDE interface on some m68k |
982 | Macintosh models. It supports both the `Quadra style' (used in | 988 | Macintosh models. It supports both the `Quadra style' (used in |
@@ -988,18 +994,16 @@ config BLK_DEV_MAC_IDE | |||
988 | builtin IDE interface. | 994 | builtin IDE interface. |
989 | 995 | ||
990 | config BLK_DEV_Q40IDE | 996 | config BLK_DEV_Q40IDE |
991 | bool "Q40/Q60 IDE interface support" | 997 | tristate "Q40/Q60 IDE interface support" |
992 | depends on Q40 | 998 | depends on Q40 |
993 | select IDE_GENERIC | ||
994 | help | 999 | help |
995 | Enable the on-board IDE controller in the Q40/Q60. This should | 1000 | Enable the on-board IDE controller in the Q40/Q60. This should |
996 | normally be on; disable it only if you are running a custom hard | 1001 | normally be on; disable it only if you are running a custom hard |
997 | drive subsystem through an expansion card. | 1002 | drive subsystem through an expansion card. |
998 | 1003 | ||
999 | config BLK_DEV_MPC8xx_IDE | 1004 | config BLK_DEV_MPC8xx_IDE |
1000 | bool "MPC8xx IDE support" | 1005 | tristate "MPC8xx IDE support" |
1001 | depends on 8xx && (LWMON || IVMS8 || IVML24 || TQM8xxL) && IDE=y && BLK_DEV_IDE=y && !PPC_MERGE | 1006 | depends on 8xx && (LWMON || IVMS8 || IVML24 || TQM8xxL) && IDE=y && BLK_DEV_IDE=y && !PPC_MERGE |
1002 | select IDE_GENERIC | ||
1003 | help | 1007 | help |
1004 | This option provides support for IDE on Motorola MPC8xx Systems. | 1008 | This option provides support for IDE on Motorola MPC8xx Systems. |
1005 | Please see 'Type of MPC8xx IDE interface' for details. | 1009 | Please see 'Type of MPC8xx IDE interface' for details. |
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index b181fc672057..0d2da89d15cf 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile | |||
@@ -7,41 +7,37 @@ | |||
7 | # Note : at this point, these files are compiled on all systems. | 7 | # Note : at this point, these files are compiled on all systems. |
8 | # In the future, some of these should be built conditionally. | 8 | # In the future, some of these should be built conditionally. |
9 | # | 9 | # |
10 | # First come modules that register themselves with the core | 10 | # link order is important here |
11 | 11 | ||
12 | EXTRA_CFLAGS += -Idrivers/ide | 12 | EXTRA_CFLAGS += -Idrivers/ide |
13 | 13 | ||
14 | obj-$(CONFIG_BLK_DEV_IDE) += pci/ | ||
15 | |||
16 | ide-core-y += ide.o ide-io.o ide-iops.o ide-lib.o ide-probe.o ide-taskfile.o | 14 | ide-core-y += ide.o ide-io.o ide-iops.o ide-lib.o ide-probe.o ide-taskfile.o |
17 | 15 | ||
18 | ide-core-$(CONFIG_BLK_DEV_CMD640) += pci/cmd640.o | 16 | # core IDE code |
19 | |||
20 | # Core IDE code - must come before legacy | ||
21 | ide-core-$(CONFIG_BLK_DEV_IDEPCI) += setup-pci.o | 17 | ide-core-$(CONFIG_BLK_DEV_IDEPCI) += setup-pci.o |
22 | ide-core-$(CONFIG_BLK_DEV_IDEDMA) += ide-dma.o | 18 | ide-core-$(CONFIG_BLK_DEV_IDEDMA) += ide-dma.o |
23 | ide-core-$(CONFIG_IDE_PROC_FS) += ide-proc.o | 19 | ide-core-$(CONFIG_IDE_PROC_FS) += ide-proc.o |
24 | ide-core-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp.o | ||
25 | ide-core-$(CONFIG_BLK_DEV_IDEACPI) += ide-acpi.o | 20 | ide-core-$(CONFIG_BLK_DEV_IDEACPI) += ide-acpi.o |
26 | 21 | ||
27 | # built-in only drivers from arm/ | 22 | obj-$(CONFIG_BLK_DEV_IDE) += ide-core.o |
28 | ide-core-$(CONFIG_IDE_ARM) += arm/ide_arm.o | ||
29 | 23 | ||
30 | # built-in only drivers from legacy/ | 24 | ifeq ($(CONFIG_IDE_ARM), y) |
31 | ide-core-$(CONFIG_BLK_DEV_BUDDHA) += legacy/buddha.o | 25 | ide-arm-core-y += arm/ide_arm.o |
32 | ide-core-$(CONFIG_BLK_DEV_FALCON_IDE) += legacy/falconide.o | 26 | obj-y += ide-arm-core.o |
33 | ide-core-$(CONFIG_BLK_DEV_GAYLE) += legacy/gayle.o | 27 | endif |
34 | ide-core-$(CONFIG_BLK_DEV_MAC_IDE) += legacy/macide.o | ||
35 | ide-core-$(CONFIG_BLK_DEV_Q40IDE) += legacy/q40ide.o | ||
36 | 28 | ||
37 | # built-in only drivers from ppc/ | 29 | obj-$(CONFIG_BLK_DEV_IDE) += legacy/ pci/ |
38 | ide-core-$(CONFIG_BLK_DEV_MPC8xx_IDE) += ppc/mpc8xx.o | ||
39 | ide-core-$(CONFIG_BLK_DEV_IDE_PMAC) += ppc/pmac.o | ||
40 | 30 | ||
41 | # built-in only drivers from h8300/ | 31 | obj-$(CONFIG_IDEPCI_PCIBUS_ORDER) += ide-scan-pci.o |
42 | ide-core-$(CONFIG_IDE_H8300) += h8300/ide-h8300.o | ||
43 | 32 | ||
44 | obj-$(CONFIG_BLK_DEV_IDE) += ide-core.o | 33 | ifeq ($(CONFIG_BLK_DEV_CMD640), y) |
34 | cmd640-core-y += pci/cmd640.o | ||
35 | obj-y += cmd640-core.o | ||
36 | endif | ||
37 | |||
38 | obj-$(CONFIG_BLK_DEV_IDE) += cris/ ppc/ | ||
39 | obj-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp.o | ||
40 | obj-$(CONFIG_IDE_H8300) += h8300/ | ||
45 | obj-$(CONFIG_IDE_GENERIC) += ide-generic.o | 41 | obj-$(CONFIG_IDE_GENERIC) += ide-generic.o |
46 | 42 | ||
47 | obj-$(CONFIG_BLK_DEV_IDEDISK) += ide-disk.o | 43 | obj-$(CONFIG_BLK_DEV_IDEDISK) += ide-disk.o |
@@ -49,6 +45,20 @@ obj-$(CONFIG_BLK_DEV_IDECD) += ide-cd.o | |||
49 | obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o | 45 | obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o |
50 | obj-$(CONFIG_BLK_DEV_IDEFLOPPY) += ide-floppy.o | 46 | obj-$(CONFIG_BLK_DEV_IDEFLOPPY) += ide-floppy.o |
51 | 47 | ||
52 | obj-$(CONFIG_BLK_DEV_IDE) += legacy/ arm/ mips/ | 48 | ifeq ($(CONFIG_BLK_DEV_IDECS), y) |
53 | obj-$(CONFIG_BLK_DEV_HD) += legacy/ | 49 | ide-cs-core-y += legacy/ide-cs.o |
54 | obj-$(CONFIG_ETRAX_IDE) += cris/ | 50 | obj-y += ide-cs-core.o |
51 | endif | ||
52 | |||
53 | ifeq ($(CONFIG_BLK_DEV_PLATFORM), y) | ||
54 | ide-platform-core-y += legacy/ide_platform.o | ||
55 | obj-y += ide-platform-core.o | ||
56 | endif | ||
57 | |||
58 | obj-$(CONFIG_BLK_DEV_IDE) += arm/ mips/ | ||
59 | |||
60 | # old hd driver must be last | ||
61 | ifeq ($(CONFIG_BLK_DEV_HD), y) | ||
62 | hd-core-y += legacy/hd.o | ||
63 | obj-y += hd-core.o | ||
64 | endif | ||
diff --git a/drivers/ide/arm/Makefile b/drivers/ide/arm/Makefile index 6a78f0755f26..5f63ad216862 100644 --- a/drivers/ide/arm/Makefile +++ b/drivers/ide/arm/Makefile | |||
@@ -3,4 +3,8 @@ obj-$(CONFIG_BLK_DEV_IDE_ICSIDE) += icside.o | |||
3 | obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapide.o | 3 | obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapide.o |
4 | obj-$(CONFIG_BLK_DEV_IDE_BAST) += bast-ide.o | 4 | obj-$(CONFIG_BLK_DEV_IDE_BAST) += bast-ide.o |
5 | 5 | ||
6 | ifeq ($(CONFIG_IDE_ARM), m) | ||
7 | obj-m += ide_arm.o | ||
8 | endif | ||
9 | |||
6 | EXTRA_CFLAGS := -Idrivers/ide | 10 | EXTRA_CFLAGS := -Idrivers/ide |
diff --git a/drivers/ide/arm/bast-ide.c b/drivers/ide/arm/bast-ide.c index 48db6167bb90..45bf9c825f2b 100644 --- a/drivers/ide/arm/bast-ide.c +++ b/drivers/ide/arm/bast-ide.c | |||
@@ -45,7 +45,7 @@ bastide_register(unsigned int base, unsigned int aux, int irq, | |||
45 | hw.io_ports[IDE_CONTROL_OFFSET] = aux + (6 * 0x20); | 45 | hw.io_ports[IDE_CONTROL_OFFSET] = aux + (6 * 0x20); |
46 | hw.irq = irq; | 46 | hw.irq = irq; |
47 | 47 | ||
48 | ide_register_hw(&hw, NULL, 0, hwif); | 48 | ide_register_hw(&hw, NULL, hwif); |
49 | 49 | ||
50 | return 0; | 50 | return 0; |
51 | } | 51 | } |
diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c index 673402f4a295..8a5c7205b77c 100644 --- a/drivers/ide/arm/icside.c +++ b/drivers/ide/arm/icside.c | |||
@@ -287,26 +287,10 @@ static void icside_set_dma_mode(ide_drive_t *drive, const u8 xfer_mode) | |||
287 | ide_xfer_verbose(xfer_mode), 2000 / drive->drive_data); | 287 | ide_xfer_verbose(xfer_mode), 2000 / drive->drive_data); |
288 | } | 288 | } |
289 | 289 | ||
290 | static void icside_dma_host_off(ide_drive_t *drive) | 290 | static void icside_dma_host_set(ide_drive_t *drive, int on) |
291 | { | 291 | { |
292 | } | 292 | } |
293 | 293 | ||
294 | static void icside_dma_off_quietly(ide_drive_t *drive) | ||
295 | { | ||
296 | drive->using_dma = 0; | ||
297 | } | ||
298 | |||
299 | static void icside_dma_host_on(ide_drive_t *drive) | ||
300 | { | ||
301 | } | ||
302 | |||
303 | static int icside_dma_on(ide_drive_t *drive) | ||
304 | { | ||
305 | drive->using_dma = 1; | ||
306 | |||
307 | return 0; | ||
308 | } | ||
309 | |||
310 | static int icside_dma_end(ide_drive_t *drive) | 294 | static int icside_dma_end(ide_drive_t *drive) |
311 | { | 295 | { |
312 | ide_hwif_t *hwif = HWIF(drive); | 296 | ide_hwif_t *hwif = HWIF(drive); |
@@ -422,10 +406,7 @@ static void icside_dma_init(ide_hwif_t *hwif) | |||
422 | hwif->dmatable_dma = 0; | 406 | hwif->dmatable_dma = 0; |
423 | hwif->set_dma_mode = icside_set_dma_mode; | 407 | hwif->set_dma_mode = icside_set_dma_mode; |
424 | 408 | ||
425 | hwif->dma_host_off = icside_dma_host_off; | 409 | hwif->dma_host_set = icside_dma_host_set; |
426 | hwif->dma_off_quietly = icside_dma_off_quietly; | ||
427 | hwif->dma_host_on = icside_dma_host_on; | ||
428 | hwif->ide_dma_on = icside_dma_on; | ||
429 | hwif->dma_setup = icside_dma_setup; | 410 | hwif->dma_setup = icside_dma_setup; |
430 | hwif->dma_exec_cmd = icside_dma_exec_cmd; | 411 | hwif->dma_exec_cmd = icside_dma_exec_cmd; |
431 | hwif->dma_start = icside_dma_start; | 412 | hwif->dma_start = icside_dma_start; |
diff --git a/drivers/ide/arm/ide_arm.c b/drivers/ide/arm/ide_arm.c index 8957cbadf5c2..60f2497542c0 100644 --- a/drivers/ide/arm/ide_arm.c +++ b/drivers/ide/arm/ide_arm.c | |||
@@ -24,12 +24,25 @@ | |||
24 | # define IDE_ARM_IRQ IRQ_HARDDISK | 24 | # define IDE_ARM_IRQ IRQ_HARDDISK |
25 | #endif | 25 | #endif |
26 | 26 | ||
27 | void __init ide_arm_init(void) | 27 | static int __init ide_arm_init(void) |
28 | { | 28 | { |
29 | ide_hwif_t *hwif; | ||
29 | hw_regs_t hw; | 30 | hw_regs_t hw; |
31 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; | ||
30 | 32 | ||
31 | memset(&hw, 0, sizeof(hw)); | 33 | memset(&hw, 0, sizeof(hw)); |
32 | ide_std_init_ports(&hw, IDE_ARM_IO, IDE_ARM_IO + 0x206); | 34 | ide_std_init_ports(&hw, IDE_ARM_IO, IDE_ARM_IO + 0x206); |
33 | hw.irq = IDE_ARM_IRQ; | 35 | hw.irq = IDE_ARM_IRQ; |
34 | ide_register_hw(&hw, NULL, 1, NULL); | 36 | |
37 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); | ||
38 | if (hwif) { | ||
39 | ide_init_port_hw(hwif, &hw); | ||
40 | idx[0] = hwif->index; | ||
41 | |||
42 | ide_device_add(idx); | ||
43 | } | ||
44 | |||
45 | return 0; | ||
35 | } | 46 | } |
47 | |||
48 | module_init(ide_arm_init); | ||
diff --git a/drivers/ide/arm/rapide.c b/drivers/ide/arm/rapide.c index 0775a3afef48..e6b56d1d48f4 100644 --- a/drivers/ide/arm/rapide.c +++ b/drivers/ide/arm/rapide.c | |||
@@ -13,26 +13,18 @@ | |||
13 | 13 | ||
14 | #include <asm/ecard.h> | 14 | #include <asm/ecard.h> |
15 | 15 | ||
16 | static ide_hwif_t * | 16 | static void rapide_setup_ports(hw_regs_t *hw, void __iomem *base, |
17 | rapide_locate_hwif(void __iomem *base, void __iomem *ctrl, unsigned int sz, int irq) | 17 | void __iomem *ctrl, unsigned int sz, int irq) |
18 | { | 18 | { |
19 | unsigned long port = (unsigned long)base; | 19 | unsigned long port = (unsigned long)base; |
20 | ide_hwif_t *hwif = ide_find_port(port); | ||
21 | int i; | 20 | int i; |
22 | 21 | ||
23 | if (hwif == NULL) | ||
24 | goto out; | ||
25 | |||
26 | for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { | 22 | for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { |
27 | hwif->io_ports[i] = port; | 23 | hw->io_ports[i] = port; |
28 | port += sz; | 24 | port += sz; |
29 | } | 25 | } |
30 | hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl; | 26 | hw->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl; |
31 | hwif->irq = irq; | 27 | hw->irq = irq; |
32 | hwif->mmio = 1; | ||
33 | default_hwif_mmiops(hwif); | ||
34 | out: | ||
35 | return hwif; | ||
36 | } | 28 | } |
37 | 29 | ||
38 | static int __devinit | 30 | static int __devinit |
@@ -42,6 +34,7 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id) | |||
42 | void __iomem *base; | 34 | void __iomem *base; |
43 | int ret; | 35 | int ret; |
44 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; | 36 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; |
37 | hw_regs_t hw; | ||
45 | 38 | ||
46 | ret = ecard_request_resources(ec); | 39 | ret = ecard_request_resources(ec); |
47 | if (ret) | 40 | if (ret) |
@@ -53,11 +46,17 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id) | |||
53 | goto release; | 46 | goto release; |
54 | } | 47 | } |
55 | 48 | ||
56 | hwif = rapide_locate_hwif(base, base + 0x818, 1 << 6, ec->irq); | 49 | hwif = ide_find_port((unsigned long)base); |
57 | if (hwif) { | 50 | if (hwif) { |
58 | hwif->hwif_data = base; | 51 | memset(&hw, 0, sizeof(hw)); |
59 | hwif->gendev.parent = &ec->dev; | 52 | rapide_setup_ports(&hw, base, base + 0x818, 1 << 6, ec->irq); |
60 | hwif->noprobe = 0; | 53 | hw.chipset = ide_generic; |
54 | hw.dev = &ec->dev; | ||
55 | |||
56 | ide_init_port_hw(hwif, &hw); | ||
57 | |||
58 | hwif->mmio = 1; | ||
59 | default_hwif_mmiops(hwif); | ||
61 | 60 | ||
62 | idx[0] = hwif->index; | 61 | idx[0] = hwif->index; |
63 | 62 | ||
diff --git a/drivers/ide/cris/Makefile b/drivers/ide/cris/Makefile index 6176e8d6b2e6..20b95960531f 100644 --- a/drivers/ide/cris/Makefile +++ b/drivers/ide/cris/Makefile | |||
@@ -1,3 +1,3 @@ | |||
1 | EXTRA_CFLAGS += -Idrivers/ide | 1 | EXTRA_CFLAGS += -Idrivers/ide |
2 | 2 | ||
3 | obj-y += ide-cris.o | 3 | obj-$(CONFIG_IDE_ETRAX) += ide-cris.o |
diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c index 325e608d9e62..8c3294c4d23e 100644 --- a/drivers/ide/cris/ide-cris.c +++ b/drivers/ide/cris/ide-cris.c | |||
@@ -673,9 +673,8 @@ static void cris_ide_input_data (ide_drive_t *drive, void *, unsigned int); | |||
673 | static void cris_ide_output_data (ide_drive_t *drive, void *, unsigned int); | 673 | static void cris_ide_output_data (ide_drive_t *drive, void *, unsigned int); |
674 | static void cris_atapi_input_bytes(ide_drive_t *drive, void *, unsigned int); | 674 | static void cris_atapi_input_bytes(ide_drive_t *drive, void *, unsigned int); |
675 | static void cris_atapi_output_bytes(ide_drive_t *drive, void *, unsigned int); | 675 | static void cris_atapi_output_bytes(ide_drive_t *drive, void *, unsigned int); |
676 | static int cris_dma_on (ide_drive_t *drive); | ||
677 | 676 | ||
678 | static void cris_dma_off(ide_drive_t *drive) | 677 | static void cris_dma_host_set(ide_drive_t *drive, int on) |
679 | { | 678 | { |
680 | } | 679 | } |
681 | 680 | ||
@@ -755,13 +754,11 @@ static void cris_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
755 | cris_ide_set_speed(TYPE_DMA, 0, strobe, hold); | 754 | cris_ide_set_speed(TYPE_DMA, 0, strobe, hold); |
756 | } | 755 | } |
757 | 756 | ||
758 | void __init | 757 | static int __init init_e100_ide(void) |
759 | init_e100_ide (void) | ||
760 | { | 758 | { |
761 | hw_regs_t hw; | 759 | hw_regs_t hw; |
762 | int ide_offsets[IDE_NR_PORTS]; | 760 | int ide_offsets[IDE_NR_PORTS], h, i; |
763 | int h; | 761 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; |
764 | int i; | ||
765 | 762 | ||
766 | printk("ide: ETRAX FS built-in ATA DMA controller\n"); | 763 | printk("ide: ETRAX FS built-in ATA DMA controller\n"); |
767 | 764 | ||
@@ -778,9 +775,11 @@ init_e100_ide (void) | |||
778 | ide_offsets, | 775 | ide_offsets, |
779 | 0, 0, cris_ide_ack_intr, | 776 | 0, 0, cris_ide_ack_intr, |
780 | ide_default_irq(0)); | 777 | ide_default_irq(0)); |
781 | ide_register_hw(&hw, NULL, 1, &hwif); | 778 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); |
782 | if (hwif == NULL) | 779 | if (hwif == NULL) |
783 | continue; | 780 | continue; |
781 | ide_init_port_data(hwif, hwif->index); | ||
782 | ide_init_port_hw(hwif, &hw); | ||
784 | hwif->mmio = 1; | 783 | hwif->mmio = 1; |
785 | hwif->chipset = ide_etrax100; | 784 | hwif->chipset = ide_etrax100; |
786 | hwif->set_pio_mode = &cris_set_pio_mode; | 785 | hwif->set_pio_mode = &cris_set_pio_mode; |
@@ -789,6 +788,7 @@ init_e100_ide (void) | |||
789 | hwif->ata_output_data = &cris_ide_output_data; | 788 | hwif->ata_output_data = &cris_ide_output_data; |
790 | hwif->atapi_input_bytes = &cris_atapi_input_bytes; | 789 | hwif->atapi_input_bytes = &cris_atapi_input_bytes; |
791 | hwif->atapi_output_bytes = &cris_atapi_output_bytes; | 790 | hwif->atapi_output_bytes = &cris_atapi_output_bytes; |
791 | hwif->dma_host_set = &cris_dma_host_set; | ||
792 | hwif->ide_dma_end = &cris_dma_end; | 792 | hwif->ide_dma_end = &cris_dma_end; |
793 | hwif->dma_setup = &cris_dma_setup; | 793 | hwif->dma_setup = &cris_dma_setup; |
794 | hwif->dma_exec_cmd = &cris_dma_exec_cmd; | 794 | hwif->dma_exec_cmd = &cris_dma_exec_cmd; |
@@ -799,9 +799,6 @@ init_e100_ide (void) | |||
799 | hwif->OUTBSYNC = &cris_ide_outbsync; | 799 | hwif->OUTBSYNC = &cris_ide_outbsync; |
800 | hwif->INB = &cris_ide_inb; | 800 | hwif->INB = &cris_ide_inb; |
801 | hwif->INW = &cris_ide_inw; | 801 | hwif->INW = &cris_ide_inw; |
802 | hwif->dma_host_off = &cris_dma_off; | ||
803 | hwif->dma_host_on = &cris_dma_on; | ||
804 | hwif->dma_off_quietly = &cris_dma_off; | ||
805 | hwif->cbl = ATA_CBL_PATA40; | 802 | hwif->cbl = ATA_CBL_PATA40; |
806 | hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA; | 803 | hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA; |
807 | hwif->pio_mask = ATA_PIO4, | 804 | hwif->pio_mask = ATA_PIO4, |
@@ -809,6 +806,8 @@ init_e100_ide (void) | |||
809 | hwif->drives[1].autotune = 1; | 806 | hwif->drives[1].autotune = 1; |
810 | hwif->ultra_mask = cris_ultra_mask; | 807 | hwif->ultra_mask = cris_ultra_mask; |
811 | hwif->mwdma_mask = 0x07; /* Multiword DMA 0-2 */ | 808 | hwif->mwdma_mask = 0x07; /* Multiword DMA 0-2 */ |
809 | |||
810 | idx[h] = hwif->index; | ||
812 | } | 811 | } |
813 | 812 | ||
814 | /* Reset pulse */ | 813 | /* Reset pulse */ |
@@ -821,14 +820,12 @@ init_e100_ide (void) | |||
821 | cris_ide_set_speed(TYPE_PIO, ATA_PIO4_SETUP, ATA_PIO4_STROBE, ATA_PIO4_HOLD); | 820 | cris_ide_set_speed(TYPE_PIO, ATA_PIO4_SETUP, ATA_PIO4_STROBE, ATA_PIO4_HOLD); |
822 | cris_ide_set_speed(TYPE_DMA, 0, ATA_DMA2_STROBE, ATA_DMA2_HOLD); | 821 | cris_ide_set_speed(TYPE_DMA, 0, ATA_DMA2_STROBE, ATA_DMA2_HOLD); |
823 | cris_ide_set_speed(TYPE_UDMA, ATA_UDMA2_CYC, ATA_UDMA2_DVS, 0); | 822 | cris_ide_set_speed(TYPE_UDMA, ATA_UDMA2_CYC, ATA_UDMA2_DVS, 0); |
824 | } | ||
825 | 823 | ||
826 | static int cris_dma_on (ide_drive_t *drive) | 824 | ide_device_add(idx); |
827 | { | 825 | |
828 | return 0; | 826 | return 0; |
829 | } | 827 | } |
830 | 828 | ||
831 | |||
832 | static cris_dma_descr_type mydescr __attribute__ ((__aligned__(16))); | 829 | static cris_dma_descr_type mydescr __attribute__ ((__aligned__(16))); |
833 | 830 | ||
834 | /* | 831 | /* |
@@ -1060,3 +1057,5 @@ static void cris_dma_start(ide_drive_t *drive) | |||
1060 | LED_DISK_READ(1); | 1057 | LED_DISK_READ(1); |
1061 | } | 1058 | } |
1062 | } | 1059 | } |
1060 | |||
1061 | module_init(init_e100_ide); | ||
diff --git a/drivers/ide/h8300/Makefile b/drivers/ide/h8300/Makefile new file mode 100644 index 000000000000..5eba16f423f4 --- /dev/null +++ b/drivers/ide/h8300/Makefile | |||
@@ -0,0 +1,2 @@ | |||
1 | |||
2 | obj-$(CONFIG_IDE_H8300) += ide-h8300.o | ||
diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/h8300/ide-h8300.c index 4a49b5c59acb..4f6d0191cf6c 100644 --- a/drivers/ide/h8300/ide-h8300.c +++ b/drivers/ide/h8300/ide-h8300.c | |||
@@ -84,11 +84,12 @@ static inline void hwif_setup(ide_hwif_t *hwif) | |||
84 | hwif->INSL = NULL; | 84 | hwif->INSL = NULL; |
85 | } | 85 | } |
86 | 86 | ||
87 | void __init h8300_ide_init(void) | 87 | static int __init h8300_ide_init(void) |
88 | { | 88 | { |
89 | hw_regs_t hw; | 89 | hw_regs_t hw; |
90 | ide_hwif_t *hwif; | 90 | ide_hwif_t *hwif; |
91 | int idx; | 91 | int index; |
92 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; | ||
92 | 93 | ||
93 | if (!request_region(CONFIG_H8300_IDE_BASE, H8300_IDE_GAP*8, "ide-h8300")) | 94 | if (!request_region(CONFIG_H8300_IDE_BASE, H8300_IDE_GAP*8, "ide-h8300")) |
94 | goto out_busy; | 95 | goto out_busy; |
@@ -100,16 +101,28 @@ void __init h8300_ide_init(void) | |||
100 | hw_setup(&hw); | 101 | hw_setup(&hw); |
101 | 102 | ||
102 | /* register if */ | 103 | /* register if */ |
103 | idx = ide_register_hw(&hw, NULL, 1, &hwif); | 104 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); |
104 | if (idx == -1) { | 105 | if (hwif == NULL) { |
105 | printk(KERN_ERR "ide-h8300: IDE I/F register failed\n"); | 106 | printk(KERN_ERR "ide-h8300: IDE I/F register failed\n"); |
106 | return; | 107 | return -ENOENT; |
107 | } | 108 | } |
108 | 109 | ||
110 | index = hwif->index; | ||
111 | ide_init_port_data(hwif, index); | ||
112 | ide_init_port_hw(hwif, &hw); | ||
109 | hwif_setup(hwif); | 113 | hwif_setup(hwif); |
110 | printk(KERN_INFO "ide%d: H8/300 generic IDE interface\n", idx); | 114 | printk(KERN_INFO "ide%d: H8/300 generic IDE interface\n", index); |
111 | return; | 115 | |
116 | idx[0] = index; | ||
117 | |||
118 | ide_device_add(idx); | ||
119 | |||
120 | return 0; | ||
112 | 121 | ||
113 | out_busy: | 122 | out_busy: |
114 | printk(KERN_ERR "ide-h8300: IDE I/F resource already used.\n"); | 123 | printk(KERN_ERR "ide-h8300: IDE I/F resource already used.\n"); |
124 | |||
125 | return -EBUSY; | ||
115 | } | 126 | } |
127 | |||
128 | module_init(h8300_ide_init); | ||
diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c index e0bb0cfa7bdd..e888fc35b27c 100644 --- a/drivers/ide/ide-acpi.c +++ b/drivers/ide/ide-acpi.c | |||
@@ -386,7 +386,7 @@ static int taskfile_load_raw(ide_drive_t *drive, | |||
386 | 386 | ||
387 | /* convert gtf to IDE Taskfile */ | 387 | /* convert gtf to IDE Taskfile */ |
388 | memcpy(&args.tf_array[7], >f->tfa, 7); | 388 | memcpy(&args.tf_array[7], >f->tfa, 7); |
389 | args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; | 389 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
390 | 390 | ||
391 | if (ide_noacpitfs) { | 391 | if (ide_noacpitfs) { |
392 | DEBPRINT("_GTF execution disabled\n"); | 392 | DEBPRINT("_GTF execution disabled\n"); |
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index d8fdd865dea9..717e114ced52 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c | |||
@@ -201,7 +201,7 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, | |||
201 | 201 | ||
202 | memset(&task, 0, sizeof(task)); | 202 | memset(&task, 0, sizeof(task)); |
203 | task.tf_flags = IDE_TFLAG_NO_SELECT_MASK; /* FIXME? */ | 203 | task.tf_flags = IDE_TFLAG_NO_SELECT_MASK; /* FIXME? */ |
204 | task.tf_flags |= (IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE); | 204 | task.tf_flags |= (IDE_TFLAG_TF | IDE_TFLAG_DEVICE); |
205 | 205 | ||
206 | if (drive->select.b.lba) { | 206 | if (drive->select.b.lba) { |
207 | if (lba48) { | 207 | if (lba48) { |
@@ -219,13 +219,8 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, | |||
219 | tf->lbal = (u8) block; | 219 | tf->lbal = (u8) block; |
220 | tf->lbam = (u8)(block >> 8); | 220 | tf->lbam = (u8)(block >> 8); |
221 | tf->lbah = (u8)(block >> 16); | 221 | tf->lbah = (u8)(block >> 16); |
222 | #ifdef DEBUG | 222 | |
223 | printk("%s: 0x%02x%02x 0x%02x%02x%02x%02x%02x%02x\n", | 223 | task.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB); |
224 | drive->name, tf->hob_nsect, tf->nsect, | ||
225 | tf->hob_lbah, tf->hob_lbam, tf->hob_lbal, | ||
226 | tf->lbah, tf->lbam, tf->lbal); | ||
227 | #endif | ||
228 | task.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_OUT_HOB); | ||
229 | } else { | 224 | } else { |
230 | tf->nsect = nsectors & 0xff; | 225 | tf->nsect = nsectors & 0xff; |
231 | tf->lbal = block; | 226 | tf->lbal = block; |
@@ -319,9 +314,9 @@ static u64 idedisk_read_native_max_address(ide_drive_t *drive, int lba48) | |||
319 | else | 314 | else |
320 | tf->command = WIN_READ_NATIVE_MAX; | 315 | tf->command = WIN_READ_NATIVE_MAX; |
321 | tf->device = ATA_LBA; | 316 | tf->device = ATA_LBA; |
322 | args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; | 317 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
323 | if (lba48) | 318 | if (lba48) |
324 | args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_OUT_HOB); | 319 | args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB); |
325 | /* submit command request */ | 320 | /* submit command request */ |
326 | ide_no_data_taskfile(drive, &args); | 321 | ide_no_data_taskfile(drive, &args); |
327 | 322 | ||
@@ -358,9 +353,9 @@ static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, int lba48) | |||
358 | tf->command = WIN_SET_MAX; | 353 | tf->command = WIN_SET_MAX; |
359 | } | 354 | } |
360 | tf->device |= ATA_LBA; | 355 | tf->device |= ATA_LBA; |
361 | args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; | 356 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
362 | if (lba48) | 357 | if (lba48) |
363 | args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_OUT_HOB); | 358 | args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB); |
364 | /* submit command request */ | 359 | /* submit command request */ |
365 | ide_no_data_taskfile(drive, &args); | 360 | ide_no_data_taskfile(drive, &args); |
366 | /* if OK, compute maximum address value */ | 361 | /* if OK, compute maximum address value */ |
@@ -500,7 +495,7 @@ static int smart_enable(ide_drive_t *drive) | |||
500 | tf->lbam = SMART_LCYL_PASS; | 495 | tf->lbam = SMART_LCYL_PASS; |
501 | tf->lbah = SMART_HCYL_PASS; | 496 | tf->lbah = SMART_HCYL_PASS; |
502 | tf->command = WIN_SMART; | 497 | tf->command = WIN_SMART; |
503 | args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; | 498 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
504 | return ide_no_data_taskfile(drive, &args); | 499 | return ide_no_data_taskfile(drive, &args); |
505 | } | 500 | } |
506 | 501 | ||
@@ -515,7 +510,7 @@ static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd) | |||
515 | tf->lbam = SMART_LCYL_PASS; | 510 | tf->lbam = SMART_LCYL_PASS; |
516 | tf->lbah = SMART_HCYL_PASS; | 511 | tf->lbah = SMART_HCYL_PASS; |
517 | tf->command = WIN_SMART; | 512 | tf->command = WIN_SMART; |
518 | args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; | 513 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
519 | args.data_phase = TASKFILE_IN; | 514 | args.data_phase = TASKFILE_IN; |
520 | (void) smart_enable(drive); | 515 | (void) smart_enable(drive); |
521 | return ide_raw_taskfile(drive, &args, buf, 1); | 516 | return ide_raw_taskfile(drive, &args, buf, 1); |
@@ -625,8 +620,10 @@ static int set_multcount(ide_drive_t *drive, int arg) | |||
625 | 620 | ||
626 | if (drive->special.b.set_multmode) | 621 | if (drive->special.b.set_multmode) |
627 | return -EBUSY; | 622 | return -EBUSY; |
623 | |||
628 | ide_init_drive_cmd (&rq); | 624 | ide_init_drive_cmd (&rq); |
629 | rq.cmd_type = REQ_TYPE_ATA_CMD; | 625 | rq.cmd_type = REQ_TYPE_ATA_TASKFILE; |
626 | |||
630 | drive->mult_req = arg; | 627 | drive->mult_req = arg; |
631 | drive->special.b.set_multmode = 1; | 628 | drive->special.b.set_multmode = 1; |
632 | (void) ide_do_drive_cmd (drive, &rq, ide_wait); | 629 | (void) ide_do_drive_cmd (drive, &rq, ide_wait); |
@@ -694,7 +691,7 @@ static int write_cache(ide_drive_t *drive, int arg) | |||
694 | args.tf.feature = arg ? | 691 | args.tf.feature = arg ? |
695 | SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE; | 692 | SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE; |
696 | args.tf.command = WIN_SETFEATURES; | 693 | args.tf.command = WIN_SETFEATURES; |
697 | args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; | 694 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
698 | err = ide_no_data_taskfile(drive, &args); | 695 | err = ide_no_data_taskfile(drive, &args); |
699 | if (err == 0) | 696 | if (err == 0) |
700 | drive->wcache = arg; | 697 | drive->wcache = arg; |
@@ -714,7 +711,7 @@ static int do_idedisk_flushcache (ide_drive_t *drive) | |||
714 | args.tf.command = WIN_FLUSH_CACHE_EXT; | 711 | args.tf.command = WIN_FLUSH_CACHE_EXT; |
715 | else | 712 | else |
716 | args.tf.command = WIN_FLUSH_CACHE; | 713 | args.tf.command = WIN_FLUSH_CACHE; |
717 | args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; | 714 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
718 | return ide_no_data_taskfile(drive, &args); | 715 | return ide_no_data_taskfile(drive, &args); |
719 | } | 716 | } |
720 | 717 | ||
@@ -729,7 +726,7 @@ static int set_acoustic (ide_drive_t *drive, int arg) | |||
729 | args.tf.feature = arg ? SETFEATURES_EN_AAM : SETFEATURES_DIS_AAM; | 726 | args.tf.feature = arg ? SETFEATURES_EN_AAM : SETFEATURES_DIS_AAM; |
730 | args.tf.nsect = arg; | 727 | args.tf.nsect = arg; |
731 | args.tf.command = WIN_SETFEATURES; | 728 | args.tf.command = WIN_SETFEATURES; |
732 | args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; | 729 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
733 | ide_no_data_taskfile(drive, &args); | 730 | ide_no_data_taskfile(drive, &args); |
734 | drive->acoustic = arg; | 731 | drive->acoustic = arg; |
735 | return 0; | 732 | return 0; |
@@ -766,7 +763,6 @@ static void idedisk_add_settings(ide_drive_t *drive) | |||
766 | ide_add_setting(drive, "bios_head", SETTING_RW, TYPE_BYTE, 0, 255, 1, 1, &drive->bios_head, NULL); | 763 | ide_add_setting(drive, "bios_head", SETTING_RW, TYPE_BYTE, 0, 255, 1, 1, &drive->bios_head, NULL); |
767 | ide_add_setting(drive, "bios_sect", SETTING_RW, TYPE_BYTE, 0, 63, 1, 1, &drive->bios_sect, NULL); | 764 | ide_add_setting(drive, "bios_sect", SETTING_RW, TYPE_BYTE, 0, 63, 1, 1, &drive->bios_sect, NULL); |
768 | ide_add_setting(drive, "address", SETTING_RW, TYPE_BYTE, 0, 2, 1, 1, &drive->addressing, set_lba_addressing); | 765 | ide_add_setting(drive, "address", SETTING_RW, TYPE_BYTE, 0, 2, 1, 1, &drive->addressing, set_lba_addressing); |
769 | ide_add_setting(drive, "bswap", SETTING_READ, TYPE_BYTE, 0, 1, 1, 1, &drive->bswap, NULL); | ||
770 | ide_add_setting(drive, "multcount", SETTING_RW, TYPE_BYTE, 0, id->max_multsect, 1, 1, &drive->mult_count, set_multcount); | 766 | ide_add_setting(drive, "multcount", SETTING_RW, TYPE_BYTE, 0, id->max_multsect, 1, 1, &drive->mult_count, set_multcount); |
771 | ide_add_setting(drive, "nowerr", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->nowerr, set_nowerr); | 767 | ide_add_setting(drive, "nowerr", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->nowerr, set_nowerr); |
772 | ide_add_setting(drive, "lun", SETTING_RW, TYPE_INT, 0, 7, 1, 1, &drive->lun, NULL); | 768 | ide_add_setting(drive, "lun", SETTING_RW, TYPE_INT, 0, 7, 1, 1, &drive->lun, NULL); |
@@ -975,6 +971,17 @@ static ide_driver_t idedisk_driver = { | |||
975 | #endif | 971 | #endif |
976 | }; | 972 | }; |
977 | 973 | ||
974 | static int idedisk_set_doorlock(ide_drive_t *drive, int on) | ||
975 | { | ||
976 | ide_task_t task; | ||
977 | |||
978 | memset(&task, 0, sizeof(task)); | ||
979 | task.tf.command = on ? WIN_DOORLOCK : WIN_DOORUNLOCK; | ||
980 | task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | ||
981 | |||
982 | return ide_no_data_taskfile(drive, &task); | ||
983 | } | ||
984 | |||
978 | static int idedisk_open(struct inode *inode, struct file *filp) | 985 | static int idedisk_open(struct inode *inode, struct file *filp) |
979 | { | 986 | { |
980 | struct gendisk *disk = inode->i_bdev->bd_disk; | 987 | struct gendisk *disk = inode->i_bdev->bd_disk; |
@@ -989,17 +996,13 @@ static int idedisk_open(struct inode *inode, struct file *filp) | |||
989 | idkp->openers++; | 996 | idkp->openers++; |
990 | 997 | ||
991 | if (drive->removable && idkp->openers == 1) { | 998 | if (drive->removable && idkp->openers == 1) { |
992 | ide_task_t args; | ||
993 | memset(&args, 0, sizeof(ide_task_t)); | ||
994 | args.tf.command = WIN_DOORLOCK; | ||
995 | args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; | ||
996 | check_disk_change(inode->i_bdev); | 999 | check_disk_change(inode->i_bdev); |
997 | /* | 1000 | /* |
998 | * Ignore the return code from door_lock, | 1001 | * Ignore the return code from door_lock, |
999 | * since the open() has already succeeded, | 1002 | * since the open() has already succeeded, |
1000 | * and the door_lock is irrelevant at this point. | 1003 | * and the door_lock is irrelevant at this point. |
1001 | */ | 1004 | */ |
1002 | if (drive->doorlocking && ide_no_data_taskfile(drive, &args)) | 1005 | if (drive->doorlocking && idedisk_set_doorlock(drive, 1)) |
1003 | drive->doorlocking = 0; | 1006 | drive->doorlocking = 0; |
1004 | } | 1007 | } |
1005 | return 0; | 1008 | return 0; |
@@ -1015,11 +1018,7 @@ static int idedisk_release(struct inode *inode, struct file *filp) | |||
1015 | ide_cacheflush_p(drive); | 1018 | ide_cacheflush_p(drive); |
1016 | 1019 | ||
1017 | if (drive->removable && idkp->openers == 1) { | 1020 | if (drive->removable && idkp->openers == 1) { |
1018 | ide_task_t args; | 1021 | if (drive->doorlocking && idedisk_set_doorlock(drive, 0)) |
1019 | memset(&args, 0, sizeof(ide_task_t)); | ||
1020 | args.tf.command = WIN_DOORUNLOCK; | ||
1021 | args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; | ||
1022 | if (drive->doorlocking && ide_no_data_taskfile(drive, &args)) | ||
1023 | drive->doorlocking = 0; | 1022 | drive->doorlocking = 0; |
1024 | } | 1023 | } |
1025 | 1024 | ||
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 18c78ad2b31e..5bf32038dc43 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c | |||
@@ -153,13 +153,7 @@ ide_startstop_t ide_dma_intr (ide_drive_t *drive) | |||
153 | if (!dma_stat) { | 153 | if (!dma_stat) { |
154 | struct request *rq = HWGROUP(drive)->rq; | 154 | struct request *rq = HWGROUP(drive)->rq; |
155 | 155 | ||
156 | if (rq->rq_disk) { | 156 | task_end_request(drive, rq, stat); |
157 | ide_driver_t *drv; | ||
158 | |||
159 | drv = *(ide_driver_t **)rq->rq_disk->private_data; | ||
160 | drv->end_request(drive, 1, rq->nr_sectors); | ||
161 | } else | ||
162 | ide_end_request(drive, 1, rq->nr_sectors); | ||
163 | return ide_stopped; | 157 | return ide_stopped; |
164 | } | 158 | } |
165 | printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n", | 159 | printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n", |
@@ -408,23 +402,29 @@ static int dma_timer_expiry (ide_drive_t *drive) | |||
408 | } | 402 | } |
409 | 403 | ||
410 | /** | 404 | /** |
411 | * ide_dma_host_off - Generic DMA kill | 405 | * ide_dma_host_set - Enable/disable DMA on a host |
412 | * @drive: drive to control | 406 | * @drive: drive to control |
413 | * | 407 | * |
414 | * Perform the generic IDE controller DMA off operation. This | 408 | * Enable/disable DMA on an IDE controller following generic |
415 | * works for most IDE bus mastering controllers | 409 | * bus-mastering IDE controller behaviour. |
416 | */ | 410 | */ |
417 | 411 | ||
418 | void ide_dma_host_off(ide_drive_t *drive) | 412 | void ide_dma_host_set(ide_drive_t *drive, int on) |
419 | { | 413 | { |
420 | ide_hwif_t *hwif = HWIF(drive); | 414 | ide_hwif_t *hwif = HWIF(drive); |
421 | u8 unit = (drive->select.b.unit & 0x01); | 415 | u8 unit = (drive->select.b.unit & 0x01); |
422 | u8 dma_stat = hwif->INB(hwif->dma_status); | 416 | u8 dma_stat = hwif->INB(hwif->dma_status); |
423 | 417 | ||
424 | hwif->OUTB((dma_stat & ~(1<<(5+unit))), hwif->dma_status); | 418 | if (on) |
419 | dma_stat |= (1 << (5 + unit)); | ||
420 | else | ||
421 | dma_stat &= ~(1 << (5 + unit)); | ||
422 | |||
423 | hwif->OUTB(dma_stat, hwif->dma_status); | ||
425 | } | 424 | } |
426 | 425 | ||
427 | EXPORT_SYMBOL(ide_dma_host_off); | 426 | EXPORT_SYMBOL_GPL(ide_dma_host_set); |
427 | #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ | ||
428 | 428 | ||
429 | /** | 429 | /** |
430 | * ide_dma_off_quietly - Generic DMA kill | 430 | * ide_dma_off_quietly - Generic DMA kill |
@@ -438,11 +438,10 @@ void ide_dma_off_quietly(ide_drive_t *drive) | |||
438 | drive->using_dma = 0; | 438 | drive->using_dma = 0; |
439 | ide_toggle_bounce(drive, 0); | 439 | ide_toggle_bounce(drive, 0); |
440 | 440 | ||
441 | drive->hwif->dma_host_off(drive); | 441 | drive->hwif->dma_host_set(drive, 0); |
442 | } | 442 | } |
443 | 443 | ||
444 | EXPORT_SYMBOL(ide_dma_off_quietly); | 444 | EXPORT_SYMBOL(ide_dma_off_quietly); |
445 | #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ | ||
446 | 445 | ||
447 | /** | 446 | /** |
448 | * ide_dma_off - disable DMA on a device | 447 | * ide_dma_off - disable DMA on a device |
@@ -455,52 +454,29 @@ EXPORT_SYMBOL(ide_dma_off_quietly); | |||
455 | void ide_dma_off(ide_drive_t *drive) | 454 | void ide_dma_off(ide_drive_t *drive) |
456 | { | 455 | { |
457 | printk(KERN_INFO "%s: DMA disabled\n", drive->name); | 456 | printk(KERN_INFO "%s: DMA disabled\n", drive->name); |
458 | drive->hwif->dma_off_quietly(drive); | 457 | ide_dma_off_quietly(drive); |
459 | } | 458 | } |
460 | 459 | ||
461 | EXPORT_SYMBOL(ide_dma_off); | 460 | EXPORT_SYMBOL(ide_dma_off); |
462 | 461 | ||
463 | #ifdef CONFIG_BLK_DEV_IDEDMA_PCI | ||
464 | /** | ||
465 | * ide_dma_host_on - Enable DMA on a host | ||
466 | * @drive: drive to enable for DMA | ||
467 | * | ||
468 | * Enable DMA on an IDE controller following generic bus mastering | ||
469 | * IDE controller behaviour | ||
470 | */ | ||
471 | |||
472 | void ide_dma_host_on(ide_drive_t *drive) | ||
473 | { | ||
474 | if (drive->using_dma) { | ||
475 | ide_hwif_t *hwif = HWIF(drive); | ||
476 | u8 unit = (drive->select.b.unit & 0x01); | ||
477 | u8 dma_stat = hwif->INB(hwif->dma_status); | ||
478 | |||
479 | hwif->OUTB((dma_stat|(1<<(5+unit))), hwif->dma_status); | ||
480 | } | ||
481 | } | ||
482 | |||
483 | EXPORT_SYMBOL(ide_dma_host_on); | ||
484 | |||
485 | /** | 462 | /** |
486 | * __ide_dma_on - Enable DMA on a device | 463 | * ide_dma_on - Enable DMA on a device |
487 | * @drive: drive to enable DMA on | 464 | * @drive: drive to enable DMA on |
488 | * | 465 | * |
489 | * Enable IDE DMA for a device on this IDE controller. | 466 | * Enable IDE DMA for a device on this IDE controller. |
490 | */ | 467 | */ |
491 | 468 | ||
492 | int __ide_dma_on (ide_drive_t *drive) | 469 | void ide_dma_on(ide_drive_t *drive) |
493 | { | 470 | { |
494 | drive->using_dma = 1; | 471 | drive->using_dma = 1; |
495 | ide_toggle_bounce(drive, 1); | 472 | ide_toggle_bounce(drive, 1); |
496 | 473 | ||
497 | drive->hwif->dma_host_on(drive); | 474 | drive->hwif->dma_host_set(drive, 1); |
498 | |||
499 | return 0; | ||
500 | } | 475 | } |
501 | 476 | ||
502 | EXPORT_SYMBOL(__ide_dma_on); | 477 | EXPORT_SYMBOL(ide_dma_on); |
503 | 478 | ||
479 | #ifdef CONFIG_BLK_DEV_IDEDMA_PCI | ||
504 | /** | 480 | /** |
505 | * ide_dma_setup - begin a DMA phase | 481 | * ide_dma_setup - begin a DMA phase |
506 | * @drive: target device | 482 | * @drive: target device |
@@ -755,6 +731,7 @@ EXPORT_SYMBOL_GPL(ide_find_dma_mode); | |||
755 | 731 | ||
756 | static int ide_tune_dma(ide_drive_t *drive) | 732 | static int ide_tune_dma(ide_drive_t *drive) |
757 | { | 733 | { |
734 | ide_hwif_t *hwif = drive->hwif; | ||
758 | u8 speed; | 735 | u8 speed; |
759 | 736 | ||
760 | if (noautodma || drive->nodma || (drive->id->capability & 1) == 0) | 737 | if (noautodma || drive->nodma || (drive->id->capability & 1) == 0) |
@@ -767,15 +744,21 @@ static int ide_tune_dma(ide_drive_t *drive) | |||
767 | if (ide_id_dma_bug(drive)) | 744 | if (ide_id_dma_bug(drive)) |
768 | return 0; | 745 | return 0; |
769 | 746 | ||
770 | if (drive->hwif->host_flags & IDE_HFLAG_TRUST_BIOS_FOR_DMA) | 747 | if (hwif->host_flags & IDE_HFLAG_TRUST_BIOS_FOR_DMA) |
771 | return config_drive_for_dma(drive); | 748 | return config_drive_for_dma(drive); |
772 | 749 | ||
773 | speed = ide_max_dma_mode(drive); | 750 | speed = ide_max_dma_mode(drive); |
774 | 751 | ||
775 | if (!speed) | 752 | if (!speed) { |
776 | return 0; | 753 | /* is this really correct/needed? */ |
754 | if ((hwif->host_flags & IDE_HFLAG_CY82C693) && | ||
755 | ide_dma_good_drive(drive)) | ||
756 | return 1; | ||
757 | else | ||
758 | return 0; | ||
759 | } | ||
777 | 760 | ||
778 | if (drive->hwif->host_flags & IDE_HFLAG_NO_SET_MODE) | 761 | if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE) |
779 | return 0; | 762 | return 0; |
780 | 763 | ||
781 | if (ide_set_dma_mode(drive, speed)) | 764 | if (ide_set_dma_mode(drive, speed)) |
@@ -820,7 +803,6 @@ err_out: | |||
820 | 803 | ||
821 | int ide_set_dma(ide_drive_t *drive) | 804 | int ide_set_dma(ide_drive_t *drive) |
822 | { | 805 | { |
823 | ide_hwif_t *hwif = drive->hwif; | ||
824 | int rc; | 806 | int rc; |
825 | 807 | ||
826 | /* | 808 | /* |
@@ -829,13 +811,15 @@ int ide_set_dma(ide_drive_t *drive) | |||
829 | * things, if not checked and cleared. | 811 | * things, if not checked and cleared. |
830 | * PARANOIA!!! | 812 | * PARANOIA!!! |
831 | */ | 813 | */ |
832 | hwif->dma_off_quietly(drive); | 814 | ide_dma_off_quietly(drive); |
833 | 815 | ||
834 | rc = ide_dma_check(drive); | 816 | rc = ide_dma_check(drive); |
835 | if (rc) | 817 | if (rc) |
836 | return rc; | 818 | return rc; |
837 | 819 | ||
838 | return hwif->ide_dma_on(drive); | 820 | ide_dma_on(drive); |
821 | |||
822 | return 0; | ||
839 | } | 823 | } |
840 | 824 | ||
841 | #ifdef CONFIG_BLK_DEV_IDEDMA_PCI | 825 | #ifdef CONFIG_BLK_DEV_IDEDMA_PCI |
@@ -972,14 +956,8 @@ void ide_setup_dma(ide_hwif_t *hwif, unsigned long base, unsigned num_ports) | |||
972 | if (!(hwif->dma_prdtable)) | 956 | if (!(hwif->dma_prdtable)) |
973 | hwif->dma_prdtable = (hwif->dma_base + 4); | 957 | hwif->dma_prdtable = (hwif->dma_base + 4); |
974 | 958 | ||
975 | if (!hwif->dma_off_quietly) | 959 | if (!hwif->dma_host_set) |
976 | hwif->dma_off_quietly = &ide_dma_off_quietly; | 960 | hwif->dma_host_set = &ide_dma_host_set; |
977 | if (!hwif->dma_host_off) | ||
978 | hwif->dma_host_off = &ide_dma_host_off; | ||
979 | if (!hwif->ide_dma_on) | ||
980 | hwif->ide_dma_on = &__ide_dma_on; | ||
981 | if (!hwif->dma_host_on) | ||
982 | hwif->dma_host_on = &ide_dma_host_on; | ||
983 | if (!hwif->dma_setup) | 961 | if (!hwif->dma_setup) |
984 | hwif->dma_setup = &ide_dma_setup; | 962 | hwif->dma_setup = &ide_dma_setup; |
985 | if (!hwif->dma_exec_cmd) | 963 | if (!hwif->dma_exec_cmd) |
diff --git a/drivers/ide/ide-generic.c b/drivers/ide/ide-generic.c index 0f72b98d727f..bb30c29f6ec0 100644 --- a/drivers/ide/ide-generic.c +++ b/drivers/ide/ide-generic.c | |||
@@ -14,10 +14,16 @@ | |||
14 | 14 | ||
15 | static int __init ide_generic_init(void) | 15 | static int __init ide_generic_init(void) |
16 | { | 16 | { |
17 | u8 idx[MAX_HWIFS]; | ||
18 | int i; | ||
19 | |||
17 | if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) | 20 | if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) |
18 | ide_get_lock(NULL, NULL); /* for atari only */ | 21 | ide_get_lock(NULL, NULL); /* for atari only */ |
19 | 22 | ||
20 | (void)ideprobe_init(); | 23 | for (i = 0; i < MAX_HWIFS; i++) |
24 | idx[i] = ide_hwifs[i].present ? 0xff : i; | ||
25 | |||
26 | ide_device_add_all(idx); | ||
21 | 27 | ||
22 | if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) | 28 | if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) |
23 | ide_release_lock(); /* for atari only */ | 29 | ide_release_lock(); /* for atari only */ |
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 2711b5a6962d..6f8f544392a8 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -75,7 +75,7 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq, | |||
75 | */ | 75 | */ |
76 | if (drive->state == DMA_PIO_RETRY && drive->retry_pio <= 3) { | 76 | if (drive->state == DMA_PIO_RETRY && drive->retry_pio <= 3) { |
77 | drive->state = 0; | 77 | drive->state = 0; |
78 | HWGROUP(drive)->hwif->ide_dma_on(drive); | 78 | ide_dma_on(drive); |
79 | } | 79 | } |
80 | 80 | ||
81 | if (!end_that_request_chunk(rq, uptodate, nr_bytes)) { | 81 | if (!end_that_request_chunk(rq, uptodate, nr_bytes)) { |
@@ -219,7 +219,7 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * | |||
219 | * we could be smarter and check for current xfer_speed | 219 | * we could be smarter and check for current xfer_speed |
220 | * in struct drive etc... | 220 | * in struct drive etc... |
221 | */ | 221 | */ |
222 | if (drive->hwif->ide_dma_on == NULL) | 222 | if (drive->hwif->dma_host_set == NULL) |
223 | break; | 223 | break; |
224 | /* | 224 | /* |
225 | * TODO: respect ->using_dma setting | 225 | * TODO: respect ->using_dma setting |
@@ -231,7 +231,7 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * | |||
231 | return ide_stopped; | 231 | return ide_stopped; |
232 | 232 | ||
233 | out_do_tf: | 233 | out_do_tf: |
234 | args->tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; | 234 | args->tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
235 | args->data_phase = TASKFILE_NO_DATA; | 235 | args->data_phase = TASKFILE_NO_DATA; |
236 | return do_rw_taskfile(drive, args); | 236 | return do_rw_taskfile(drive, args); |
237 | } | 237 | } |
@@ -354,7 +354,6 @@ void ide_tf_read(ide_drive_t *drive, ide_task_t *task) | |||
354 | 354 | ||
355 | void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) | 355 | void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) |
356 | { | 356 | { |
357 | ide_hwif_t *hwif = HWIF(drive); | ||
358 | unsigned long flags; | 357 | unsigned long flags; |
359 | struct request *rq; | 358 | struct request *rq; |
360 | 359 | ||
@@ -362,17 +361,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) | |||
362 | rq = HWGROUP(drive)->rq; | 361 | rq = HWGROUP(drive)->rq; |
363 | spin_unlock_irqrestore(&ide_lock, flags); | 362 | spin_unlock_irqrestore(&ide_lock, flags); |
364 | 363 | ||
365 | if (rq->cmd_type == REQ_TYPE_ATA_CMD) { | 364 | if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { |
366 | u8 *args = (u8 *) rq->buffer; | ||
367 | if (rq->errors == 0) | ||
368 | rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT); | ||
369 | |||
370 | if (args) { | ||
371 | args[0] = stat; | ||
372 | args[1] = err; | ||
373 | args[2] = hwif->INB(IDE_NSECTOR_REG); | ||
374 | } | ||
375 | } else if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { | ||
376 | ide_task_t *args = (ide_task_t *) rq->special; | 365 | ide_task_t *args = (ide_task_t *) rq->special; |
377 | if (rq->errors == 0) | 366 | if (rq->errors == 0) |
378 | rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT); | 367 | rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT); |
@@ -383,10 +372,6 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) | |||
383 | tf->error = err; | 372 | tf->error = err; |
384 | tf->status = stat; | 373 | tf->status = stat; |
385 | 374 | ||
386 | args->tf_flags |= (IDE_TFLAG_IN_TF|IDE_TFLAG_IN_DEVICE); | ||
387 | if (args->tf_flags & IDE_TFLAG_LBA48) | ||
388 | args->tf_flags |= IDE_TFLAG_IN_HOB; | ||
389 | |||
390 | ide_tf_read(drive, args); | 375 | ide_tf_read(drive, args); |
391 | } | 376 | } |
392 | } else if (blk_pm_request(rq)) { | 377 | } else if (blk_pm_request(rq)) { |
@@ -626,42 +611,6 @@ ide_startstop_t ide_abort(ide_drive_t *drive, const char *msg) | |||
626 | return __ide_abort(drive, rq); | 611 | return __ide_abort(drive, rq); |
627 | } | 612 | } |
628 | 613 | ||
629 | /** | ||
630 | * drive_cmd_intr - drive command completion interrupt | ||
631 | * @drive: drive the completion interrupt occurred on | ||
632 | * | ||
633 | * drive_cmd_intr() is invoked on completion of a special DRIVE_CMD. | ||
634 | * We do any necessary data reading and then wait for the drive to | ||
635 | * go non busy. At that point we may read the error data and complete | ||
636 | * the request | ||
637 | */ | ||
638 | |||
639 | static ide_startstop_t drive_cmd_intr (ide_drive_t *drive) | ||
640 | { | ||
641 | struct request *rq = HWGROUP(drive)->rq; | ||
642 | ide_hwif_t *hwif = HWIF(drive); | ||
643 | u8 *args = (u8 *) rq->buffer; | ||
644 | u8 stat = hwif->INB(IDE_STATUS_REG); | ||
645 | int retries = 10; | ||
646 | |||
647 | local_irq_enable_in_hardirq(); | ||
648 | if (rq->cmd_type == REQ_TYPE_ATA_CMD && | ||
649 | (stat & DRQ_STAT) && args && args[3]) { | ||
650 | u8 io_32bit = drive->io_32bit; | ||
651 | drive->io_32bit = 0; | ||
652 | hwif->ata_input_data(drive, &args[4], args[3] * SECTOR_WORDS); | ||
653 | drive->io_32bit = io_32bit; | ||
654 | while (((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) && retries--) | ||
655 | udelay(100); | ||
656 | } | ||
657 | |||
658 | if (!OK_STAT(stat, READY_STAT, BAD_STAT)) | ||
659 | return ide_error(drive, "drive_cmd", stat); | ||
660 | /* calls ide_end_drive_cmd */ | ||
661 | ide_end_drive_cmd(drive, stat, hwif->INB(IDE_ERROR_REG)); | ||
662 | return ide_stopped; | ||
663 | } | ||
664 | |||
665 | static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf) | 614 | static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf) |
666 | { | 615 | { |
667 | tf->nsect = drive->sect; | 616 | tf->nsect = drive->sect; |
@@ -710,7 +659,7 @@ static ide_startstop_t ide_disk_special(ide_drive_t *drive) | |||
710 | return ide_stopped; | 659 | return ide_stopped; |
711 | } | 660 | } |
712 | 661 | ||
713 | args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE | | 662 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE | |
714 | IDE_TFLAG_CUSTOM_HANDLER; | 663 | IDE_TFLAG_CUSTOM_HANDLER; |
715 | 664 | ||
716 | do_rw_taskfile(drive, &args); | 665 | do_rw_taskfile(drive, &args); |
@@ -787,7 +736,7 @@ static ide_startstop_t do_special (ide_drive_t *drive) | |||
787 | 736 | ||
788 | if (hwif->host_flags & IDE_HFLAG_SET_PIO_MODE_KEEP_DMA) { | 737 | if (hwif->host_flags & IDE_HFLAG_SET_PIO_MODE_KEEP_DMA) { |
789 | if (keep_dma) | 738 | if (keep_dma) |
790 | hwif->ide_dma_on(drive); | 739 | ide_dma_on(drive); |
791 | } | 740 | } |
792 | } | 741 | } |
793 | 742 | ||
@@ -847,16 +796,9 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, | |||
847 | struct request *rq) | 796 | struct request *rq) |
848 | { | 797 | { |
849 | ide_hwif_t *hwif = HWIF(drive); | 798 | ide_hwif_t *hwif = HWIF(drive); |
850 | u8 *args = rq->buffer; | 799 | ide_task_t *task = rq->special; |
851 | ide_task_t ltask; | ||
852 | struct ide_taskfile *tf = <ask.tf; | ||
853 | |||
854 | if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { | ||
855 | ide_task_t *task = rq->special; | ||
856 | |||
857 | if (task == NULL) | ||
858 | goto done; | ||
859 | 800 | ||
801 | if (task) { | ||
860 | hwif->data_phase = task->data_phase; | 802 | hwif->data_phase = task->data_phase; |
861 | 803 | ||
862 | switch (hwif->data_phase) { | 804 | switch (hwif->data_phase) { |
@@ -873,33 +815,6 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, | |||
873 | return do_rw_taskfile(drive, task); | 815 | return do_rw_taskfile(drive, task); |
874 | } | 816 | } |
875 | 817 | ||
876 | if (args == NULL) | ||
877 | goto done; | ||
878 | |||
879 | memset(<ask, 0, sizeof(ltask)); | ||
880 | if (rq->cmd_type == REQ_TYPE_ATA_CMD) { | ||
881 | #ifdef DEBUG | ||
882 | printk("%s: DRIVE_CMD\n", drive->name); | ||
883 | #endif | ||
884 | tf->feature = args[2]; | ||
885 | if (args[0] == WIN_SMART) { | ||
886 | tf->nsect = args[3]; | ||
887 | tf->lbal = args[1]; | ||
888 | tf->lbam = 0x4f; | ||
889 | tf->lbah = 0xc2; | ||
890 | ltask.tf_flags = IDE_TFLAG_OUT_TF; | ||
891 | } else { | ||
892 | tf->nsect = args[1]; | ||
893 | ltask.tf_flags = IDE_TFLAG_OUT_FEATURE | | ||
894 | IDE_TFLAG_OUT_NSECT; | ||
895 | } | ||
896 | } | ||
897 | tf->command = args[0]; | ||
898 | ide_tf_load(drive, <ask); | ||
899 | ide_execute_command(drive, args[0], &drive_cmd_intr, WAIT_WORSTCASE, NULL); | ||
900 | return ide_started; | ||
901 | |||
902 | done: | ||
903 | /* | 818 | /* |
904 | * NULL is actually a valid way of waiting for | 819 | * NULL is actually a valid way of waiting for |
905 | * all current requests to be flushed from the queue. | 820 | * all current requests to be flushed from the queue. |
@@ -939,8 +854,7 @@ static void ide_check_pm_state(ide_drive_t *drive, struct request *rq) | |||
939 | if (rc) | 854 | if (rc) |
940 | printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name); | 855 | printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name); |
941 | SELECT_DRIVE(drive); | 856 | SELECT_DRIVE(drive); |
942 | if (IDE_CONTROL_REG) | 857 | ide_set_irq(drive, 1); |
943 | HWIF(drive)->OUTB(drive->ctl, IDE_CONTROL_REG); | ||
944 | rc = ide_wait_not_busy(HWIF(drive), 100000); | 858 | rc = ide_wait_not_busy(HWIF(drive), 100000); |
945 | if (rc) | 859 | if (rc) |
946 | printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name); | 860 | printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name); |
@@ -1004,8 +918,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) | |||
1004 | if (drive->current_speed == 0xff) | 918 | if (drive->current_speed == 0xff) |
1005 | ide_config_drive_speed(drive, drive->desired_speed); | 919 | ide_config_drive_speed(drive, drive->desired_speed); |
1006 | 920 | ||
1007 | if (rq->cmd_type == REQ_TYPE_ATA_CMD || | 921 | if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) |
1008 | rq->cmd_type == REQ_TYPE_ATA_TASKFILE) | ||
1009 | return execute_drive_cmd(drive, rq); | 922 | return execute_drive_cmd(drive, rq); |
1010 | else if (blk_pm_request(rq)) { | 923 | else if (blk_pm_request(rq)) { |
1011 | struct request_pm_state *pm = rq->data; | 924 | struct request_pm_state *pm = rq->data; |
@@ -1213,15 +1126,13 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) | |||
1213 | } | 1126 | } |
1214 | again: | 1127 | again: |
1215 | hwif = HWIF(drive); | 1128 | hwif = HWIF(drive); |
1216 | if (hwgroup->hwif->sharing_irq && | 1129 | if (hwgroup->hwif->sharing_irq && hwif != hwgroup->hwif) { |
1217 | hwif != hwgroup->hwif && | ||
1218 | hwif->io_ports[IDE_CONTROL_OFFSET]) { | ||
1219 | /* | 1130 | /* |
1220 | * set nIEN for previous hwif, drives in the | 1131 | * set nIEN for previous hwif, drives in the |
1221 | * quirk_list may not like intr setups/cleanups | 1132 | * quirk_list may not like intr setups/cleanups |
1222 | */ | 1133 | */ |
1223 | if (drive->quirk_list != 1) | 1134 | if (drive->quirk_list != 1) |
1224 | hwif->OUTB(drive->ctl | 2, IDE_CONTROL_REG); | 1135 | ide_set_irq(drive, 0); |
1225 | } | 1136 | } |
1226 | hwgroup->hwif = hwif; | 1137 | hwgroup->hwif = hwif; |
1227 | hwgroup->drive = drive; | 1138 | hwgroup->drive = drive; |
@@ -1334,7 +1245,7 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) | |||
1334 | */ | 1245 | */ |
1335 | drive->retry_pio++; | 1246 | drive->retry_pio++; |
1336 | drive->state = DMA_PIO_RETRY; | 1247 | drive->state = DMA_PIO_RETRY; |
1337 | hwif->dma_off_quietly(drive); | 1248 | ide_dma_off_quietly(drive); |
1338 | 1249 | ||
1339 | /* | 1250 | /* |
1340 | * un-busy drive etc (hwgroup->busy is cleared on return) and | 1251 | * un-busy drive etc (hwgroup->busy is cleared on return) and |
@@ -1679,7 +1590,6 @@ irqreturn_t ide_intr (int irq, void *dev_id) | |||
1679 | void ide_init_drive_cmd (struct request *rq) | 1590 | void ide_init_drive_cmd (struct request *rq) |
1680 | { | 1591 | { |
1681 | memset(rq, 0, sizeof(*rq)); | 1592 | memset(rq, 0, sizeof(*rq)); |
1682 | rq->cmd_type = REQ_TYPE_ATA_CMD; | ||
1683 | rq->ref_count = 1; | 1593 | rq->ref_count = 1; |
1684 | } | 1594 | } |
1685 | 1595 | ||
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index c97c0719ddf1..e2a7e95e1636 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
@@ -619,7 +619,7 @@ no_80w: | |||
619 | int ide_ata66_check (ide_drive_t *drive, ide_task_t *args) | 619 | int ide_ata66_check (ide_drive_t *drive, ide_task_t *args) |
620 | { | 620 | { |
621 | if (args->tf.command == WIN_SETFEATURES && | 621 | if (args->tf.command == WIN_SETFEATURES && |
622 | args->tf.lbal > XFER_UDMA_2 && | 622 | args->tf.nsect > XFER_UDMA_2 && |
623 | args->tf.feature == SETFEATURES_XFER) { | 623 | args->tf.feature == SETFEATURES_XFER) { |
624 | if (eighty_ninty_three(drive) == 0) { | 624 | if (eighty_ninty_three(drive) == 0) { |
625 | printk(KERN_WARNING "%s: UDMA speeds >UDMA33 cannot " | 625 | printk(KERN_WARNING "%s: UDMA speeds >UDMA33 cannot " |
@@ -639,7 +639,7 @@ int ide_ata66_check (ide_drive_t *drive, ide_task_t *args) | |||
639 | int set_transfer (ide_drive_t *drive, ide_task_t *args) | 639 | int set_transfer (ide_drive_t *drive, ide_task_t *args) |
640 | { | 640 | { |
641 | if (args->tf.command == WIN_SETFEATURES && | 641 | if (args->tf.command == WIN_SETFEATURES && |
642 | args->tf.lbal >= XFER_SW_DMA_0 && | 642 | args->tf.nsect >= XFER_SW_DMA_0 && |
643 | args->tf.feature == SETFEATURES_XFER && | 643 | args->tf.feature == SETFEATURES_XFER && |
644 | (drive->id->dma_ultra || | 644 | (drive->id->dma_ultra || |
645 | drive->id->dma_mword || | 645 | drive->id->dma_mword || |
@@ -688,8 +688,7 @@ int ide_driveid_update(ide_drive_t *drive) | |||
688 | */ | 688 | */ |
689 | 689 | ||
690 | SELECT_MASK(drive, 1); | 690 | SELECT_MASK(drive, 1); |
691 | if (IDE_CONTROL_REG) | 691 | ide_set_irq(drive, 1); |
692 | hwif->OUTB(drive->ctl,IDE_CONTROL_REG); | ||
693 | msleep(50); | 692 | msleep(50); |
694 | hwif->OUTB(WIN_IDENTIFY, IDE_COMMAND_REG); | 693 | hwif->OUTB(WIN_IDENTIFY, IDE_COMMAND_REG); |
695 | timeout = jiffies + WAIT_WORSTCASE; | 694 | timeout = jiffies + WAIT_WORSTCASE; |
@@ -742,8 +741,8 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) | |||
742 | // msleep(50); | 741 | // msleep(50); |
743 | 742 | ||
744 | #ifdef CONFIG_BLK_DEV_IDEDMA | 743 | #ifdef CONFIG_BLK_DEV_IDEDMA |
745 | if (hwif->ide_dma_on) /* check if host supports DMA */ | 744 | if (hwif->dma_host_set) /* check if host supports DMA */ |
746 | hwif->dma_host_off(drive); | 745 | hwif->dma_host_set(drive, 0); |
747 | #endif | 746 | #endif |
748 | 747 | ||
749 | /* Skip setting PIO flow-control modes on pre-EIDE drives */ | 748 | /* Skip setting PIO flow-control modes on pre-EIDE drives */ |
@@ -772,13 +771,12 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) | |||
772 | SELECT_DRIVE(drive); | 771 | SELECT_DRIVE(drive); |
773 | SELECT_MASK(drive, 0); | 772 | SELECT_MASK(drive, 0); |
774 | udelay(1); | 773 | udelay(1); |
775 | if (IDE_CONTROL_REG) | 774 | ide_set_irq(drive, 0); |
776 | hwif->OUTB(drive->ctl | 2, IDE_CONTROL_REG); | ||
777 | hwif->OUTB(speed, IDE_NSECTOR_REG); | 775 | hwif->OUTB(speed, IDE_NSECTOR_REG); |
778 | hwif->OUTB(SETFEATURES_XFER, IDE_FEATURE_REG); | 776 | hwif->OUTB(SETFEATURES_XFER, IDE_FEATURE_REG); |
779 | hwif->OUTBSYNC(drive, WIN_SETFEATURES, IDE_COMMAND_REG); | 777 | hwif->OUTBSYNC(drive, WIN_SETFEATURES, IDE_COMMAND_REG); |
780 | if ((IDE_CONTROL_REG) && (drive->quirk_list == 2)) | 778 | if (drive->quirk_list == 2) |
781 | hwif->OUTB(drive->ctl, IDE_CONTROL_REG); | 779 | ide_set_irq(drive, 1); |
782 | 780 | ||
783 | error = __ide_wait_stat(drive, drive->ready_stat, | 781 | error = __ide_wait_stat(drive, drive->ready_stat, |
784 | BUSY_STAT|DRQ_STAT|ERR_STAT, | 782 | BUSY_STAT|DRQ_STAT|ERR_STAT, |
@@ -799,10 +797,11 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) | |||
799 | 797 | ||
800 | skip: | 798 | skip: |
801 | #ifdef CONFIG_BLK_DEV_IDEDMA | 799 | #ifdef CONFIG_BLK_DEV_IDEDMA |
802 | if (speed >= XFER_SW_DMA_0) | 800 | if ((speed >= XFER_SW_DMA_0 || (hwif->host_flags & IDE_HFLAG_VDMA)) && |
803 | hwif->dma_host_on(drive); | 801 | drive->using_dma) |
804 | else if (hwif->ide_dma_on) /* check if host supports DMA */ | 802 | hwif->dma_host_set(drive, 1); |
805 | hwif->dma_off_quietly(drive); | 803 | else if (hwif->dma_host_set) /* check if host supports DMA */ |
804 | ide_dma_off_quietly(drive); | ||
806 | #endif | 805 | #endif |
807 | 806 | ||
808 | switch(speed) { | 807 | switch(speed) { |
@@ -1012,10 +1011,10 @@ static void check_dma_crc(ide_drive_t *drive) | |||
1012 | { | 1011 | { |
1013 | #ifdef CONFIG_BLK_DEV_IDEDMA | 1012 | #ifdef CONFIG_BLK_DEV_IDEDMA |
1014 | if (drive->crc_count) { | 1013 | if (drive->crc_count) { |
1015 | drive->hwif->dma_off_quietly(drive); | 1014 | ide_dma_off_quietly(drive); |
1016 | ide_set_xfer_rate(drive, ide_auto_reduce_xfer(drive)); | 1015 | ide_set_xfer_rate(drive, ide_auto_reduce_xfer(drive)); |
1017 | if (drive->current_speed >= XFER_SW_DMA_0) | 1016 | if (drive->current_speed >= XFER_SW_DMA_0) |
1018 | (void) HWIF(drive)->ide_dma_on(drive); | 1017 | ide_dma_on(drive); |
1019 | } else | 1018 | } else |
1020 | ide_dma_off(drive); | 1019 | ide_dma_off(drive); |
1021 | #endif | 1020 | #endif |
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index a3bd8e8ed6b0..9b44fbdfe41f 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c | |||
@@ -454,8 +454,7 @@ int ide_set_xfer_rate(ide_drive_t *drive, u8 rate) | |||
454 | static void ide_dump_opcode(ide_drive_t *drive) | 454 | static void ide_dump_opcode(ide_drive_t *drive) |
455 | { | 455 | { |
456 | struct request *rq; | 456 | struct request *rq; |
457 | u8 opcode = 0; | 457 | ide_task_t *task = NULL; |
458 | int found = 0; | ||
459 | 458 | ||
460 | spin_lock(&ide_lock); | 459 | spin_lock(&ide_lock); |
461 | rq = NULL; | 460 | rq = NULL; |
@@ -464,25 +463,15 @@ static void ide_dump_opcode(ide_drive_t *drive) | |||
464 | spin_unlock(&ide_lock); | 463 | spin_unlock(&ide_lock); |
465 | if (!rq) | 464 | if (!rq) |
466 | return; | 465 | return; |
467 | if (rq->cmd_type == REQ_TYPE_ATA_CMD) { | 466 | |
468 | char *args = rq->buffer; | 467 | if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) |
469 | if (args) { | 468 | task = rq->special; |
470 | opcode = args[0]; | ||
471 | found = 1; | ||
472 | } | ||
473 | } else if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { | ||
474 | ide_task_t *args = rq->special; | ||
475 | if (args) { | ||
476 | opcode = args->tf.command; | ||
477 | found = 1; | ||
478 | } | ||
479 | } | ||
480 | 469 | ||
481 | printk("ide: failed opcode was: "); | 470 | printk("ide: failed opcode was: "); |
482 | if (!found) | 471 | if (task == NULL) |
483 | printk("unknown\n"); | 472 | printk(KERN_CONT "unknown\n"); |
484 | else | 473 | else |
485 | printk("0x%02x\n", opcode); | 474 | printk(KERN_CONT "0x%02x\n", task->tf.command); |
486 | } | 475 | } |
487 | 476 | ||
488 | u64 ide_get_lba_addr(struct ide_taskfile *tf, int lba48) | 477 | u64 ide_get_lba_addr(struct ide_taskfile *tf, int lba48) |
diff --git a/drivers/ide/ide-pnp.c b/drivers/ide/ide-pnp.c index e245521af7b5..cbbb0f75be92 100644 --- a/drivers/ide/ide-pnp.c +++ b/drivers/ide/ide-pnp.c | |||
@@ -31,7 +31,6 @@ static int idepnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id | |||
31 | { | 31 | { |
32 | hw_regs_t hw; | 32 | hw_regs_t hw; |
33 | ide_hwif_t *hwif; | 33 | ide_hwif_t *hwif; |
34 | int index; | ||
35 | 34 | ||
36 | if (!(pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && pnp_irq_valid(dev, 0))) | 35 | if (!(pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && pnp_irq_valid(dev, 0))) |
37 | return -1; | 36 | return -1; |
@@ -41,11 +40,19 @@ static int idepnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id | |||
41 | pnp_port_start(dev, 1)); | 40 | pnp_port_start(dev, 1)); |
42 | hw.irq = pnp_irq(dev, 0); | 41 | hw.irq = pnp_irq(dev, 0); |
43 | 42 | ||
44 | index = ide_register_hw(&hw, NULL, 1, &hwif); | 43 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); |
44 | if (hwif) { | ||
45 | u8 index = hwif->index; | ||
46 | u8 idx[4] = { index, 0xff, 0xff, 0xff }; | ||
47 | |||
48 | ide_init_port_data(hwif, index); | ||
49 | ide_init_port_hw(hwif, &hw); | ||
45 | 50 | ||
46 | if (index != -1) { | 51 | printk(KERN_INFO "ide%d: generic PnP IDE interface\n", index); |
47 | printk(KERN_INFO "ide%d: generic PnP IDE interface\n", index); | ||
48 | pnp_set_drvdata(dev,hwif); | 52 | pnp_set_drvdata(dev,hwif); |
53 | |||
54 | ide_device_add(idx); | ||
55 | |||
49 | return 0; | 56 | return 0; |
50 | } | 57 | } |
51 | 58 | ||
@@ -68,12 +75,15 @@ static struct pnp_driver idepnp_driver = { | |||
68 | .remove = idepnp_remove, | 75 | .remove = idepnp_remove, |
69 | }; | 76 | }; |
70 | 77 | ||
71 | void __init pnpide_init(void) | 78 | static int __init pnpide_init(void) |
72 | { | 79 | { |
73 | pnp_register_driver(&idepnp_driver); | 80 | return pnp_register_driver(&idepnp_driver); |
74 | } | 81 | } |
75 | 82 | ||
76 | void __exit pnpide_exit(void) | 83 | static void __exit pnpide_exit(void) |
77 | { | 84 | { |
78 | pnp_unregister_driver(&idepnp_driver); | 85 | pnp_unregister_driver(&idepnp_driver); |
79 | } | 86 | } |
87 | |||
88 | module_init(pnpide_init); | ||
89 | module_exit(pnpide_exit); | ||
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 0379d1f697cf..edf650b20c67 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
@@ -235,9 +235,6 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd) | |||
235 | drive->media = ide_disk; | 235 | drive->media = ide_disk; |
236 | printk("%s DISK drive\n", (id->config == 0x848a) ? "CFA" : "ATA" ); | 236 | printk("%s DISK drive\n", (id->config == 0x848a) ? "CFA" : "ATA" ); |
237 | 237 | ||
238 | if (hwif->quirkproc) | ||
239 | drive->quirk_list = hwif->quirkproc(drive); | ||
240 | |||
241 | return; | 238 | return; |
242 | 239 | ||
243 | err_misc: | 240 | err_misc: |
@@ -353,22 +350,19 @@ static int try_to_identify (ide_drive_t *drive, u8 cmd) | |||
353 | * the irq handler isn't expecting. | 350 | * the irq handler isn't expecting. |
354 | */ | 351 | */ |
355 | if (IDE_CONTROL_REG) { | 352 | if (IDE_CONTROL_REG) { |
356 | u8 ctl = drive->ctl | 2; | ||
357 | if (!hwif->irq) { | 353 | if (!hwif->irq) { |
358 | autoprobe = 1; | 354 | autoprobe = 1; |
359 | cookie = probe_irq_on(); | 355 | cookie = probe_irq_on(); |
360 | /* enable device irq */ | ||
361 | ctl &= ~2; | ||
362 | } | 356 | } |
363 | hwif->OUTB(ctl, IDE_CONTROL_REG); | 357 | ide_set_irq(drive, autoprobe); |
364 | } | 358 | } |
365 | 359 | ||
366 | retval = actual_try_to_identify(drive, cmd); | 360 | retval = actual_try_to_identify(drive, cmd); |
367 | 361 | ||
368 | if (autoprobe) { | 362 | if (autoprobe) { |
369 | int irq; | 363 | int irq; |
370 | /* mask device irq */ | 364 | |
371 | hwif->OUTB(drive->ctl|2, IDE_CONTROL_REG); | 365 | ide_set_irq(drive, 0); |
372 | /* clear drive IRQ */ | 366 | /* clear drive IRQ */ |
373 | (void) hwif->INB(IDE_STATUS_REG); | 367 | (void) hwif->INB(IDE_STATUS_REG); |
374 | udelay(5); | 368 | udelay(5); |
@@ -388,6 +382,20 @@ static int try_to_identify (ide_drive_t *drive, u8 cmd) | |||
388 | return retval; | 382 | return retval; |
389 | } | 383 | } |
390 | 384 | ||
385 | static int ide_busy_sleep(ide_hwif_t *hwif) | ||
386 | { | ||
387 | unsigned long timeout = jiffies + WAIT_WORSTCASE; | ||
388 | u8 stat; | ||
389 | |||
390 | do { | ||
391 | msleep(50); | ||
392 | stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]); | ||
393 | if ((stat & BUSY_STAT) == 0) | ||
394 | return 0; | ||
395 | } while (time_before(jiffies, timeout)); | ||
396 | |||
397 | return 1; | ||
398 | } | ||
391 | 399 | ||
392 | /** | 400 | /** |
393 | * do_probe - probe an IDE device | 401 | * do_probe - probe an IDE device |
@@ -456,7 +464,6 @@ static int do_probe (ide_drive_t *drive, u8 cmd) | |||
456 | if ((rc == 1 && cmd == WIN_PIDENTIFY) && | 464 | if ((rc == 1 && cmd == WIN_PIDENTIFY) && |
457 | ((drive->autotune == IDE_TUNE_DEFAULT) || | 465 | ((drive->autotune == IDE_TUNE_DEFAULT) || |
458 | (drive->autotune == IDE_TUNE_AUTO))) { | 466 | (drive->autotune == IDE_TUNE_AUTO))) { |
459 | unsigned long timeout; | ||
460 | printk("%s: no response (status = 0x%02x), " | 467 | printk("%s: no response (status = 0x%02x), " |
461 | "resetting drive\n", drive->name, | 468 | "resetting drive\n", drive->name, |
462 | hwif->INB(IDE_STATUS_REG)); | 469 | hwif->INB(IDE_STATUS_REG)); |
@@ -464,10 +471,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd) | |||
464 | hwif->OUTB(drive->select.all, IDE_SELECT_REG); | 471 | hwif->OUTB(drive->select.all, IDE_SELECT_REG); |
465 | msleep(50); | 472 | msleep(50); |
466 | hwif->OUTB(WIN_SRST, IDE_COMMAND_REG); | 473 | hwif->OUTB(WIN_SRST, IDE_COMMAND_REG); |
467 | timeout = jiffies; | 474 | (void)ide_busy_sleep(hwif); |
468 | while (((hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) && | ||
469 | time_before(jiffies, timeout + WAIT_WORSTCASE)) | ||
470 | msleep(50); | ||
471 | rc = try_to_identify(drive, cmd); | 475 | rc = try_to_identify(drive, cmd); |
472 | } | 476 | } |
473 | if (rc == 1) | 477 | if (rc == 1) |
@@ -495,20 +499,16 @@ static int do_probe (ide_drive_t *drive, u8 cmd) | |||
495 | static void enable_nest (ide_drive_t *drive) | 499 | static void enable_nest (ide_drive_t *drive) |
496 | { | 500 | { |
497 | ide_hwif_t *hwif = HWIF(drive); | 501 | ide_hwif_t *hwif = HWIF(drive); |
498 | unsigned long timeout; | ||
499 | 502 | ||
500 | printk("%s: enabling %s -- ", hwif->name, drive->id->model); | 503 | printk("%s: enabling %s -- ", hwif->name, drive->id->model); |
501 | SELECT_DRIVE(drive); | 504 | SELECT_DRIVE(drive); |
502 | msleep(50); | 505 | msleep(50); |
503 | hwif->OUTB(EXABYTE_ENABLE_NEST, IDE_COMMAND_REG); | 506 | hwif->OUTB(EXABYTE_ENABLE_NEST, IDE_COMMAND_REG); |
504 | timeout = jiffies + WAIT_WORSTCASE; | 507 | |
505 | do { | 508 | if (ide_busy_sleep(hwif)) { |
506 | if (time_after(jiffies, timeout)) { | 509 | printk(KERN_CONT "failed (timeout)\n"); |
507 | printk("failed (timeout)\n"); | 510 | return; |
508 | return; | 511 | } |
509 | } | ||
510 | msleep(50); | ||
511 | } while ((hwif->INB(IDE_STATUS_REG)) & BUSY_STAT); | ||
512 | 512 | ||
513 | msleep(50); | 513 | msleep(50); |
514 | 514 | ||
@@ -656,8 +656,7 @@ static int wait_hwif_ready(ide_hwif_t *hwif) | |||
656 | /* Ignore disks that we will not probe for later. */ | 656 | /* Ignore disks that we will not probe for later. */ |
657 | if (!drive->noprobe || drive->present) { | 657 | if (!drive->noprobe || drive->present) { |
658 | SELECT_DRIVE(drive); | 658 | SELECT_DRIVE(drive); |
659 | if (IDE_CONTROL_REG) | 659 | ide_set_irq(drive, 1); |
660 | hwif->OUTB(drive->ctl, IDE_CONTROL_REG); | ||
661 | mdelay(2); | 660 | mdelay(2); |
662 | rc = ide_wait_not_busy(hwif, 35000); | 661 | rc = ide_wait_not_busy(hwif, 35000); |
663 | if (rc) | 662 | if (rc) |
@@ -676,19 +675,18 @@ out: | |||
676 | 675 | ||
677 | /** | 676 | /** |
678 | * ide_undecoded_slave - look for bad CF adapters | 677 | * ide_undecoded_slave - look for bad CF adapters |
679 | * @hwif: interface | 678 | * @drive1: drive |
680 | * | 679 | * |
681 | * Analyse the drives on the interface and attempt to decide if we | 680 | * Analyse the drives on the interface and attempt to decide if we |
682 | * have the same drive viewed twice. This occurs with crap CF adapters | 681 | * have the same drive viewed twice. This occurs with crap CF adapters |
683 | * and PCMCIA sometimes. | 682 | * and PCMCIA sometimes. |
684 | */ | 683 | */ |
685 | 684 | ||
686 | void ide_undecoded_slave(ide_hwif_t *hwif) | 685 | void ide_undecoded_slave(ide_drive_t *drive1) |
687 | { | 686 | { |
688 | ide_drive_t *drive0 = &hwif->drives[0]; | 687 | ide_drive_t *drive0 = &drive1->hwif->drives[0]; |
689 | ide_drive_t *drive1 = &hwif->drives[1]; | ||
690 | 688 | ||
691 | if (drive0->present == 0 || drive1->present == 0) | 689 | if ((drive1->dn & 1) == 0 || drive0->present == 0) |
692 | return; | 690 | return; |
693 | 691 | ||
694 | /* If the models don't match they are not the same product */ | 692 | /* If the models don't match they are not the same product */ |
@@ -791,18 +789,11 @@ static void probe_hwif(ide_hwif_t *hwif) | |||
791 | } | 789 | } |
792 | } | 790 | } |
793 | if (hwif->io_ports[IDE_CONTROL_OFFSET] && hwif->reset) { | 791 | if (hwif->io_ports[IDE_CONTROL_OFFSET] && hwif->reset) { |
794 | unsigned long timeout = jiffies + WAIT_WORSTCASE; | ||
795 | u8 stat; | ||
796 | |||
797 | printk(KERN_WARNING "%s: reset\n", hwif->name); | 792 | printk(KERN_WARNING "%s: reset\n", hwif->name); |
798 | hwif->OUTB(12, hwif->io_ports[IDE_CONTROL_OFFSET]); | 793 | hwif->OUTB(12, hwif->io_ports[IDE_CONTROL_OFFSET]); |
799 | udelay(10); | 794 | udelay(10); |
800 | hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]); | 795 | hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]); |
801 | do { | 796 | (void)ide_busy_sleep(hwif); |
802 | msleep(50); | ||
803 | stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]); | ||
804 | } while ((stat & BUSY_STAT) && time_after(timeout, jiffies)); | ||
805 | |||
806 | } | 797 | } |
807 | local_irq_restore(flags); | 798 | local_irq_restore(flags); |
808 | /* | 799 | /* |
@@ -817,8 +808,12 @@ static void probe_hwif(ide_hwif_t *hwif) | |||
817 | return; | 808 | return; |
818 | } | 809 | } |
819 | 810 | ||
820 | if (hwif->fixup) | 811 | for (unit = 0; unit < MAX_DRIVES; unit++) { |
821 | hwif->fixup(hwif); | 812 | ide_drive_t *drive = &hwif->drives[unit]; |
813 | |||
814 | if (drive->present && hwif->quirkproc) | ||
815 | hwif->quirkproc(drive); | ||
816 | } | ||
822 | 817 | ||
823 | for (unit = 0; unit < MAX_DRIVES; ++unit) { | 818 | for (unit = 0; unit < MAX_DRIVES; ++unit) { |
824 | ide_drive_t *drive = &hwif->drives[unit]; | 819 | ide_drive_t *drive = &hwif->drives[unit]; |
@@ -833,7 +828,7 @@ static void probe_hwif(ide_hwif_t *hwif) | |||
833 | 828 | ||
834 | drive->nice1 = 1; | 829 | drive->nice1 = 1; |
835 | 830 | ||
836 | if (hwif->ide_dma_on) | 831 | if (hwif->dma_host_set) |
837 | ide_set_dma(drive); | 832 | ide_set_dma(drive); |
838 | } | 833 | } |
839 | } | 834 | } |
@@ -848,25 +843,6 @@ static void probe_hwif(ide_hwif_t *hwif) | |||
848 | } | 843 | } |
849 | } | 844 | } |
850 | 845 | ||
851 | static int hwif_init(ide_hwif_t *hwif); | ||
852 | static void hwif_register_devices(ide_hwif_t *hwif); | ||
853 | |||
854 | static int probe_hwif_init(ide_hwif_t *hwif) | ||
855 | { | ||
856 | probe_hwif(hwif); | ||
857 | |||
858 | if (!hwif_init(hwif)) { | ||
859 | printk(KERN_INFO "%s: failed to initialize IDE interface\n", | ||
860 | hwif->name); | ||
861 | return -1; | ||
862 | } | ||
863 | |||
864 | if (hwif->present) | ||
865 | hwif_register_devices(hwif); | ||
866 | |||
867 | return 0; | ||
868 | } | ||
869 | |||
870 | #if MAX_HWIFS > 1 | 846 | #if MAX_HWIFS > 1 |
871 | /* | 847 | /* |
872 | * save_match() is used to simplify logic in init_irq() below. | 848 | * save_match() is used to simplify logic in init_irq() below. |
@@ -1359,54 +1335,63 @@ static void hwif_register_devices(ide_hwif_t *hwif) | |||
1359 | } | 1335 | } |
1360 | } | 1336 | } |
1361 | 1337 | ||
1362 | int ideprobe_init (void) | 1338 | int ide_device_add_all(u8 *idx) |
1363 | { | 1339 | { |
1364 | unsigned int index; | 1340 | ide_hwif_t *hwif; |
1365 | int probe[MAX_HWIFS]; | 1341 | int i, rc = 0; |
1366 | 1342 | ||
1367 | memset(probe, 0, MAX_HWIFS * sizeof(int)); | 1343 | for (i = 0; i < MAX_HWIFS; i++) { |
1368 | for (index = 0; index < MAX_HWIFS; ++index) | 1344 | if (idx[i] == 0xff) |
1369 | probe[index] = !ide_hwifs[index].present; | 1345 | continue; |
1370 | 1346 | ||
1371 | for (index = 0; index < MAX_HWIFS; ++index) | 1347 | probe_hwif(&ide_hwifs[idx[i]]); |
1372 | if (probe[index]) | 1348 | } |
1373 | probe_hwif(&ide_hwifs[index]); | 1349 | |
1374 | for (index = 0; index < MAX_HWIFS; ++index) | 1350 | for (i = 0; i < MAX_HWIFS; i++) { |
1375 | if (probe[index]) | 1351 | if (idx[i] == 0xff) |
1376 | hwif_init(&ide_hwifs[index]); | 1352 | continue; |
1377 | for (index = 0; index < MAX_HWIFS; ++index) { | 1353 | |
1378 | if (probe[index]) { | 1354 | hwif = &ide_hwifs[idx[i]]; |
1379 | ide_hwif_t *hwif = &ide_hwifs[index]; | 1355 | |
1380 | if (!hwif->present) | 1356 | if (hwif_init(hwif) == 0) { |
1381 | continue; | 1357 | printk(KERN_INFO "%s: failed to initialize IDE " |
1382 | if (hwif->chipset == ide_unknown || hwif->chipset == ide_forced) | 1358 | "interface\n", hwif->name); |
1383 | hwif->chipset = ide_generic; | 1359 | rc = -1; |
1384 | hwif_register_devices(hwif); | 1360 | continue; |
1385 | } | 1361 | } |
1386 | } | 1362 | } |
1387 | for (index = 0; index < MAX_HWIFS; ++index) | ||
1388 | if (probe[index]) | ||
1389 | ide_proc_register_port(&ide_hwifs[index]); | ||
1390 | return 0; | ||
1391 | } | ||
1392 | 1363 | ||
1393 | EXPORT_SYMBOL_GPL(ideprobe_init); | 1364 | for (i = 0; i < MAX_HWIFS; i++) { |
1365 | if (idx[i] == 0xff) | ||
1366 | continue; | ||
1394 | 1367 | ||
1395 | int ide_device_add(u8 idx[4]) | 1368 | hwif = &ide_hwifs[idx[i]]; |
1396 | { | ||
1397 | int i, rc = 0; | ||
1398 | 1369 | ||
1399 | for (i = 0; i < 4; i++) { | 1370 | if (hwif->present) { |
1400 | if (idx[i] != 0xff) | 1371 | if (hwif->chipset == ide_unknown || |
1401 | rc |= probe_hwif_init(&ide_hwifs[idx[i]]); | 1372 | hwif->chipset == ide_forced) |
1373 | hwif->chipset = ide_generic; | ||
1374 | hwif_register_devices(hwif); | ||
1375 | } | ||
1402 | } | 1376 | } |
1403 | 1377 | ||
1404 | for (i = 0; i < 4; i++) { | 1378 | for (i = 0; i < MAX_HWIFS; i++) { |
1405 | if (idx[i] != 0xff) | 1379 | if (idx[i] != 0xff) |
1406 | ide_proc_register_port(&ide_hwifs[idx[i]]); | 1380 | ide_proc_register_port(&ide_hwifs[idx[i]]); |
1407 | } | 1381 | } |
1408 | 1382 | ||
1409 | return rc; | 1383 | return rc; |
1410 | } | 1384 | } |
1385 | EXPORT_SYMBOL_GPL(ide_device_add_all); | ||
1386 | |||
1387 | int ide_device_add(u8 idx[4]) | ||
1388 | { | ||
1389 | u8 idx_all[MAX_HWIFS]; | ||
1390 | int i; | ||
1411 | 1391 | ||
1392 | for (i = 0; i < MAX_HWIFS; i++) | ||
1393 | idx_all[i] = (i < 4) ? idx[i] : 0xff; | ||
1394 | |||
1395 | return ide_device_add_all(idx_all); | ||
1396 | } | ||
1412 | EXPORT_SYMBOL_GPL(ide_device_add); | 1397 | EXPORT_SYMBOL_GPL(ide_device_add); |
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index a4007d30da52..aa663e7f46f2 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c | |||
@@ -346,14 +346,20 @@ static int ide_write_setting(ide_drive_t *drive, ide_settings_t *setting, int va | |||
346 | 346 | ||
347 | static int set_xfer_rate (ide_drive_t *drive, int arg) | 347 | static int set_xfer_rate (ide_drive_t *drive, int arg) |
348 | { | 348 | { |
349 | ide_task_t task; | ||
349 | int err; | 350 | int err; |
350 | 351 | ||
351 | if (arg < 0 || arg > 70) | 352 | if (arg < 0 || arg > 70) |
352 | return -EINVAL; | 353 | return -EINVAL; |
353 | 354 | ||
354 | err = ide_wait_cmd(drive, | 355 | memset(&task, 0, sizeof(task)); |
355 | WIN_SETFEATURES, (u8) arg, | 356 | task.tf.command = WIN_SETFEATURES; |
356 | SETFEATURES_XFER, 0, NULL); | 357 | task.tf.feature = SETFEATURES_XFER; |
358 | task.tf.nsect = (u8)arg; | ||
359 | task.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT | | ||
360 | IDE_TFLAG_IN_NSECT; | ||
361 | |||
362 | err = ide_no_data_taskfile(drive, &task); | ||
357 | 363 | ||
358 | if (!err && arg) { | 364 | if (!err && arg) { |
359 | ide_set_xfer_rate(drive, (u8) arg); | 365 | ide_set_xfer_rate(drive, (u8) arg); |
diff --git a/drivers/ide/ide-scan-pci.c b/drivers/ide/ide-scan-pci.c new file mode 100644 index 000000000000..7ffa332d77ce --- /dev/null +++ b/drivers/ide/ide-scan-pci.c | |||
@@ -0,0 +1,121 @@ | |||
1 | /* | ||
2 | * support for probing IDE PCI devices in the PCI bus order | ||
3 | * | ||
4 | * Copyright (c) 1998-2000 Andre Hedrick <andre@linux-ide.org> | ||
5 | * Copyright (c) 1995-1998 Mark Lord | ||
6 | * | ||
7 | * May be copied or modified under the terms of the GNU General Public License | ||
8 | */ | ||
9 | |||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/ide.h> | ||
14 | |||
15 | /* | ||
16 | * Module interfaces | ||
17 | */ | ||
18 | |||
19 | static int pre_init = 1; /* Before first ordered IDE scan */ | ||
20 | static LIST_HEAD(ide_pci_drivers); | ||
21 | |||
22 | /* | ||
23 | * __ide_pci_register_driver - attach IDE driver | ||
24 | * @driver: pci driver | ||
25 | * @module: owner module of the driver | ||
26 | * | ||
27 | * Registers a driver with the IDE layer. The IDE layer arranges that | ||
28 | * boot time setup is done in the expected device order and then | ||
29 | * hands the controllers off to the core PCI code to do the rest of | ||
30 | * the work. | ||
31 | * | ||
32 | * Returns are the same as for pci_register_driver | ||
33 | */ | ||
34 | |||
35 | int __ide_pci_register_driver(struct pci_driver *driver, struct module *module, | ||
36 | const char *mod_name) | ||
37 | { | ||
38 | if (!pre_init) | ||
39 | return __pci_register_driver(driver, module, mod_name); | ||
40 | driver->driver.owner = module; | ||
41 | list_add_tail(&driver->node, &ide_pci_drivers); | ||
42 | return 0; | ||
43 | } | ||
44 | EXPORT_SYMBOL_GPL(__ide_pci_register_driver); | ||
45 | |||
46 | /** | ||
47 | * ide_scan_pcidev - find an IDE driver for a device | ||
48 | * @dev: PCI device to check | ||
49 | * | ||
50 | * Look for an IDE driver to handle the device we are considering. | ||
51 | * This is only used during boot up to get the ordering correct. After | ||
52 | * boot up the pci layer takes over the job. | ||
53 | */ | ||
54 | |||
55 | static int __init ide_scan_pcidev(struct pci_dev *dev) | ||
56 | { | ||
57 | struct list_head *l; | ||
58 | struct pci_driver *d; | ||
59 | |||
60 | list_for_each(l, &ide_pci_drivers) { | ||
61 | d = list_entry(l, struct pci_driver, node); | ||
62 | if (d->id_table) { | ||
63 | const struct pci_device_id *id = | ||
64 | pci_match_id(d->id_table, dev); | ||
65 | |||
66 | if (id != NULL && d->probe(dev, id) >= 0) { | ||
67 | dev->driver = d; | ||
68 | pci_dev_get(dev); | ||
69 | return 1; | ||
70 | } | ||
71 | } | ||
72 | } | ||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | /** | ||
77 | * ide_scan_pcibus - perform the initial IDE driver scan | ||
78 | * | ||
79 | * Perform the initial bus rather than driver ordered scan of the | ||
80 | * PCI drivers. After this all IDE pci handling becomes standard | ||
81 | * module ordering not traditionally ordered. | ||
82 | */ | ||
83 | |||
84 | int __init ide_scan_pcibus(void) | ||
85 | { | ||
86 | struct pci_dev *dev = NULL; | ||
87 | struct pci_driver *d; | ||
88 | struct list_head *l, *n; | ||
89 | |||
90 | pre_init = 0; | ||
91 | if (!ide_scan_direction) | ||
92 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev))) | ||
93 | ide_scan_pcidev(dev); | ||
94 | else | ||
95 | while ((dev = pci_get_device_reverse(PCI_ANY_ID, PCI_ANY_ID, | ||
96 | dev))) | ||
97 | ide_scan_pcidev(dev); | ||
98 | |||
99 | /* | ||
100 | * Hand the drivers over to the PCI layer now we | ||
101 | * are post init. | ||
102 | */ | ||
103 | |||
104 | list_for_each_safe(l, n, &ide_pci_drivers) { | ||
105 | list_del(l); | ||
106 | d = list_entry(l, struct pci_driver, node); | ||
107 | if (__pci_register_driver(d, d->driver.owner, | ||
108 | d->driver.mod_name)) | ||
109 | printk(KERN_ERR "%s: failed to register %s driver\n", | ||
110 | __FUNCTION__, d->driver.mod_name); | ||
111 | } | ||
112 | |||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | static int __init ide_scan_pci(void) | ||
117 | { | ||
118 | return ide_scan_pcibus(); | ||
119 | } | ||
120 | |||
121 | module_init(ide_scan_pci); | ||
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 3cbca3f4628a..d71a584f0765 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c | |||
@@ -1690,6 +1690,11 @@ static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects) | |||
1690 | if (error) | 1690 | if (error) |
1691 | tape->failed_pc = NULL; | 1691 | tape->failed_pc = NULL; |
1692 | 1692 | ||
1693 | if (!blk_special_request(rq)) { | ||
1694 | ide_end_request(drive, uptodate, nr_sects); | ||
1695 | return 0; | ||
1696 | } | ||
1697 | |||
1693 | spin_lock_irqsave(&tape->spinlock, flags); | 1698 | spin_lock_irqsave(&tape->spinlock, flags); |
1694 | 1699 | ||
1695 | /* The request was a pipelined data transfer request */ | 1700 | /* The request was a pipelined data transfer request */ |
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 2d63ea9ee61b..5eb6fa15dc4d 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c | |||
@@ -35,34 +35,6 @@ | |||
35 | #include <asm/uaccess.h> | 35 | #include <asm/uaccess.h> |
36 | #include <asm/io.h> | 36 | #include <asm/io.h> |
37 | 37 | ||
38 | static void ata_bswap_data (void *buffer, int wcount) | ||
39 | { | ||
40 | u16 *p = buffer; | ||
41 | |||
42 | while (wcount--) { | ||
43 | *p = *p << 8 | *p >> 8; p++; | ||
44 | *p = *p << 8 | *p >> 8; p++; | ||
45 | } | ||
46 | } | ||
47 | |||
48 | static void taskfile_input_data(ide_drive_t *drive, void *buffer, u32 wcount) | ||
49 | { | ||
50 | HWIF(drive)->ata_input_data(drive, buffer, wcount); | ||
51 | if (drive->bswap) | ||
52 | ata_bswap_data(buffer, wcount); | ||
53 | } | ||
54 | |||
55 | static void taskfile_output_data(ide_drive_t *drive, void *buffer, u32 wcount) | ||
56 | { | ||
57 | if (drive->bswap) { | ||
58 | ata_bswap_data(buffer, wcount); | ||
59 | HWIF(drive)->ata_output_data(drive, buffer, wcount); | ||
60 | ata_bswap_data(buffer, wcount); | ||
61 | } else { | ||
62 | HWIF(drive)->ata_output_data(drive, buffer, wcount); | ||
63 | } | ||
64 | } | ||
65 | |||
66 | void ide_tf_load(ide_drive_t *drive, ide_task_t *task) | 38 | void ide_tf_load(ide_drive_t *drive, ide_task_t *task) |
67 | { | 39 | { |
68 | ide_hwif_t *hwif = drive->hwif; | 40 | ide_hwif_t *hwif = drive->hwif; |
@@ -77,10 +49,13 @@ void ide_tf_load(ide_drive_t *drive, ide_task_t *task) | |||
77 | "lbam 0x%02x lbah 0x%02x dev 0x%02x cmd 0x%02x\n", | 49 | "lbam 0x%02x lbah 0x%02x dev 0x%02x cmd 0x%02x\n", |
78 | drive->name, tf->feature, tf->nsect, tf->lbal, | 50 | drive->name, tf->feature, tf->nsect, tf->lbal, |
79 | tf->lbam, tf->lbah, tf->device, tf->command); | 51 | tf->lbam, tf->lbah, tf->device, tf->command); |
52 | printk("%s: hob: nsect 0x%02x lbal 0x%02x " | ||
53 | "lbam 0x%02x lbah 0x%02x\n", | ||
54 | drive->name, tf->hob_nsect, tf->hob_lbal, | ||
55 | tf->hob_lbam, tf->hob_lbah); | ||
80 | #endif | 56 | #endif |
81 | 57 | ||
82 | if (IDE_CONTROL_REG) | 58 | ide_set_irq(drive, 1); |
83 | hwif->OUTB(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */ | ||
84 | 59 | ||
85 | if ((task->tf_flags & IDE_TFLAG_NO_SELECT_MASK) == 0) | 60 | if ((task->tf_flags & IDE_TFLAG_NO_SELECT_MASK) == 0) |
86 | SELECT_MASK(drive, 0); | 61 | SELECT_MASK(drive, 0); |
@@ -124,7 +99,7 @@ int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf) | |||
124 | args.tf.command = WIN_IDENTIFY; | 99 | args.tf.command = WIN_IDENTIFY; |
125 | else | 100 | else |
126 | args.tf.command = WIN_PIDENTIFY; | 101 | args.tf.command = WIN_PIDENTIFY; |
127 | args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; | 102 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
128 | args.data_phase = TASKFILE_IN; | 103 | args.data_phase = TASKFILE_IN; |
129 | return ide_raw_taskfile(drive, &args, buf, 1); | 104 | return ide_raw_taskfile(drive, &args, buf, 1); |
130 | } | 105 | } |
@@ -285,7 +260,7 @@ static ide_startstop_t task_no_data_intr(ide_drive_t *drive) | |||
285 | return ide_stopped; | 260 | return ide_stopped; |
286 | } | 261 | } |
287 | 262 | ||
288 | static u8 wait_drive_not_busy(ide_drive_t *drive) | 263 | u8 wait_drive_not_busy(ide_drive_t *drive) |
289 | { | 264 | { |
290 | ide_hwif_t *hwif = HWIF(drive); | 265 | ide_hwif_t *hwif = HWIF(drive); |
291 | int retries; | 266 | int retries; |
@@ -293,8 +268,7 @@ static u8 wait_drive_not_busy(ide_drive_t *drive) | |||
293 | 268 | ||
294 | /* | 269 | /* |
295 | * Last sector was transfered, wait until drive is ready. | 270 | * Last sector was transfered, wait until drive is ready. |
296 | * This can take up to 10 usec, but we will wait max 1 ms | 271 | * This can take up to 10 usec, but we will wait max 1 ms. |
297 | * (drive_cmd_intr() waits that long). | ||
298 | */ | 272 | */ |
299 | for (retries = 0; retries < 100; retries++) { | 273 | for (retries = 0; retries < 100; retries++) { |
300 | if ((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) | 274 | if ((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) |
@@ -349,9 +323,9 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write) | |||
349 | 323 | ||
350 | /* do the actual data transfer */ | 324 | /* do the actual data transfer */ |
351 | if (write) | 325 | if (write) |
352 | taskfile_output_data(drive, buf, SECTOR_WORDS); | 326 | hwif->ata_output_data(drive, buf, SECTOR_WORDS); |
353 | else | 327 | else |
354 | taskfile_input_data(drive, buf, SECTOR_WORDS); | 328 | hwif->ata_input_data(drive, buf, SECTOR_WORDS); |
355 | 329 | ||
356 | kunmap_atomic(buf, KM_BIO_SRC_IRQ); | 330 | kunmap_atomic(buf, KM_BIO_SRC_IRQ); |
357 | #ifdef CONFIG_HIGHMEM | 331 | #ifdef CONFIG_HIGHMEM |
@@ -371,9 +345,18 @@ static void ide_pio_multi(ide_drive_t *drive, unsigned int write) | |||
371 | static void ide_pio_datablock(ide_drive_t *drive, struct request *rq, | 345 | static void ide_pio_datablock(ide_drive_t *drive, struct request *rq, |
372 | unsigned int write) | 346 | unsigned int write) |
373 | { | 347 | { |
348 | u8 saved_io_32bit = drive->io_32bit; | ||
349 | |||
374 | if (rq->bio) /* fs request */ | 350 | if (rq->bio) /* fs request */ |
375 | rq->errors = 0; | 351 | rq->errors = 0; |
376 | 352 | ||
353 | if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { | ||
354 | ide_task_t *task = rq->special; | ||
355 | |||
356 | if (task->tf_flags & IDE_TFLAG_IO_16BIT) | ||
357 | drive->io_32bit = 0; | ||
358 | } | ||
359 | |||
377 | touch_softlockup_watchdog(); | 360 | touch_softlockup_watchdog(); |
378 | 361 | ||
379 | switch (drive->hwif->data_phase) { | 362 | switch (drive->hwif->data_phase) { |
@@ -385,6 +368,8 @@ static void ide_pio_datablock(ide_drive_t *drive, struct request *rq, | |||
385 | ide_pio_sector(drive, write); | 368 | ide_pio_sector(drive, write); |
386 | break; | 369 | break; |
387 | } | 370 | } |
371 | |||
372 | drive->io_32bit = saved_io_32bit; | ||
388 | } | 373 | } |
389 | 374 | ||
390 | static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq, | 375 | static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq, |
@@ -422,27 +407,22 @@ static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq, | |||
422 | return ide_error(drive, s, stat); | 407 | return ide_error(drive, s, stat); |
423 | } | 408 | } |
424 | 409 | ||
425 | static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat) | 410 | void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat) |
426 | { | 411 | { |
427 | HWIF(drive)->cursg = NULL; | ||
428 | |||
429 | if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { | 412 | if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { |
430 | ide_task_t *task = rq->special; | 413 | u8 err = drive->hwif->INB(IDE_ERROR_REG); |
431 | 414 | ||
432 | if (task->tf_flags & IDE_TFLAG_FLAGGED) { | 415 | ide_end_drive_cmd(drive, stat, err); |
433 | u8 err = drive->hwif->INB(IDE_ERROR_REG); | 416 | return; |
434 | ide_end_drive_cmd(drive, stat, err); | ||
435 | return; | ||
436 | } | ||
437 | } | 417 | } |
438 | 418 | ||
439 | if (rq->rq_disk) { | 419 | if (rq->rq_disk) { |
440 | ide_driver_t *drv; | 420 | ide_driver_t *drv; |
441 | 421 | ||
442 | drv = *(ide_driver_t **)rq->rq_disk->private_data;; | 422 | drv = *(ide_driver_t **)rq->rq_disk->private_data;; |
443 | drv->end_request(drive, 1, rq->hard_nr_sectors); | 423 | drv->end_request(drive, 1, rq->nr_sectors); |
444 | } else | 424 | } else |
445 | ide_end_request(drive, 1, rq->hard_nr_sectors); | 425 | ide_end_request(drive, 1, rq->nr_sectors); |
446 | } | 426 | } |
447 | 427 | ||
448 | /* | 428 | /* |
@@ -455,7 +435,7 @@ static ide_startstop_t task_in_intr(ide_drive_t *drive) | |||
455 | u8 stat = hwif->INB(IDE_STATUS_REG); | 435 | u8 stat = hwif->INB(IDE_STATUS_REG); |
456 | 436 | ||
457 | /* new way for dealing with premature shared PCI interrupts */ | 437 | /* new way for dealing with premature shared PCI interrupts */ |
458 | if (!OK_STAT(stat, DATA_READY, BAD_R_STAT)) { | 438 | if (!OK_STAT(stat, DRQ_STAT, BAD_R_STAT)) { |
459 | if (stat & (ERR_STAT | DRQ_STAT)) | 439 | if (stat & (ERR_STAT | DRQ_STAT)) |
460 | return task_error(drive, rq, __FUNCTION__, stat); | 440 | return task_error(drive, rq, __FUNCTION__, stat); |
461 | /* No data yet, so wait for another IRQ. */ | 441 | /* No data yet, so wait for another IRQ. */ |
@@ -468,7 +448,7 @@ static ide_startstop_t task_in_intr(ide_drive_t *drive) | |||
468 | /* If it was the last datablock check status and finish transfer. */ | 448 | /* If it was the last datablock check status and finish transfer. */ |
469 | if (!hwif->nleft) { | 449 | if (!hwif->nleft) { |
470 | stat = wait_drive_not_busy(drive); | 450 | stat = wait_drive_not_busy(drive); |
471 | if (!OK_STAT(stat, 0, BAD_R_STAT)) | 451 | if (!OK_STAT(stat, 0, BAD_STAT)) |
472 | return task_error(drive, rq, __FUNCTION__, stat); | 452 | return task_error(drive, rq, __FUNCTION__, stat); |
473 | task_end_request(drive, rq, stat); | 453 | task_end_request(drive, rq, stat); |
474 | return ide_stopped; | 454 | return ide_stopped; |
@@ -512,7 +492,7 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq) | |||
512 | { | 492 | { |
513 | ide_startstop_t startstop; | 493 | ide_startstop_t startstop; |
514 | 494 | ||
515 | if (ide_wait_stat(&startstop, drive, DATA_READY, | 495 | if (ide_wait_stat(&startstop, drive, DRQ_STAT, |
516 | drive->bad_wstat, WAIT_DRQ)) { | 496 | drive->bad_wstat, WAIT_DRQ)) { |
517 | printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n", | 497 | printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n", |
518 | drive->name, | 498 | drive->name, |
@@ -580,7 +560,6 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) | |||
580 | unsigned int taskin = 0; | 560 | unsigned int taskin = 0; |
581 | unsigned int taskout = 0; | 561 | unsigned int taskout = 0; |
582 | u16 nsect = 0; | 562 | u16 nsect = 0; |
583 | u8 io_32bit = drive->io_32bit; | ||
584 | char __user *buf = (char __user *)arg; | 563 | char __user *buf = (char __user *)arg; |
585 | 564 | ||
586 | // printk("IDE Taskfile ...\n"); | 565 | // printk("IDE Taskfile ...\n"); |
@@ -633,9 +612,10 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) | |||
633 | 612 | ||
634 | args.data_phase = req_task->data_phase; | 613 | args.data_phase = req_task->data_phase; |
635 | 614 | ||
636 | args.tf_flags = IDE_TFLAG_OUT_DEVICE; | 615 | args.tf_flags = IDE_TFLAG_IO_16BIT | IDE_TFLAG_DEVICE | |
616 | IDE_TFLAG_IN_TF; | ||
637 | if (drive->addressing == 1) | 617 | if (drive->addressing == 1) |
638 | args.tf_flags |= IDE_TFLAG_LBA48; | 618 | args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_IN_HOB); |
639 | 619 | ||
640 | if (req_task->out_flags.all) { | 620 | if (req_task->out_flags.all) { |
641 | args.tf_flags |= IDE_TFLAG_FLAGGED; | 621 | args.tf_flags |= IDE_TFLAG_FLAGGED; |
@@ -671,7 +651,6 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) | |||
671 | if (req_task->in_flags.b.data) | 651 | if (req_task->in_flags.b.data) |
672 | args.tf_flags |= IDE_TFLAG_IN_DATA; | 652 | args.tf_flags |= IDE_TFLAG_IN_DATA; |
673 | 653 | ||
674 | drive->io_32bit = 0; | ||
675 | switch(req_task->data_phase) { | 654 | switch(req_task->data_phase) { |
676 | case TASKFILE_MULTI_OUT: | 655 | case TASKFILE_MULTI_OUT: |
677 | if (!drive->mult_count) { | 656 | if (!drive->mult_count) { |
@@ -767,41 +746,24 @@ abort: | |||
767 | 746 | ||
768 | // printk("IDE Taskfile ioctl ended. rc = %i\n", err); | 747 | // printk("IDE Taskfile ioctl ended. rc = %i\n", err); |
769 | 748 | ||
770 | drive->io_32bit = io_32bit; | ||
771 | |||
772 | return err; | 749 | return err; |
773 | } | 750 | } |
774 | #endif | 751 | #endif |
775 | 752 | ||
776 | int ide_wait_cmd (ide_drive_t *drive, u8 cmd, u8 nsect, u8 feature, u8 sectors, u8 *buf) | ||
777 | { | ||
778 | struct request rq; | ||
779 | u8 buffer[4]; | ||
780 | |||
781 | if (!buf) | ||
782 | buf = buffer; | ||
783 | memset(buf, 0, 4 + SECTOR_WORDS * 4 * sectors); | ||
784 | ide_init_drive_cmd(&rq); | ||
785 | rq.buffer = buf; | ||
786 | *buf++ = cmd; | ||
787 | *buf++ = nsect; | ||
788 | *buf++ = feature; | ||
789 | *buf++ = sectors; | ||
790 | return ide_do_drive_cmd(drive, &rq, ide_wait); | ||
791 | } | ||
792 | |||
793 | int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) | 753 | int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) |
794 | { | 754 | { |
795 | int err = 0; | 755 | u8 *buf = NULL; |
796 | u8 args[4], *argbuf = args; | 756 | int bufsize = 0, err = 0; |
797 | u8 xfer_rate = 0; | 757 | u8 args[4], xfer_rate = 0; |
798 | int argsize = 4; | ||
799 | ide_task_t tfargs; | 758 | ide_task_t tfargs; |
800 | struct ide_taskfile *tf = &tfargs.tf; | 759 | struct ide_taskfile *tf = &tfargs.tf; |
801 | 760 | ||
802 | if (NULL == (void *) arg) { | 761 | if (NULL == (void *) arg) { |
803 | struct request rq; | 762 | struct request rq; |
763 | |||
804 | ide_init_drive_cmd(&rq); | 764 | ide_init_drive_cmd(&rq); |
765 | rq.cmd_type = REQ_TYPE_ATA_TASKFILE; | ||
766 | |||
805 | return ide_do_drive_cmd(drive, &rq, ide_wait); | 767 | return ide_do_drive_cmd(drive, &rq, ide_wait); |
806 | } | 768 | } |
807 | 769 | ||
@@ -810,23 +772,39 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) | |||
810 | 772 | ||
811 | memset(&tfargs, 0, sizeof(ide_task_t)); | 773 | memset(&tfargs, 0, sizeof(ide_task_t)); |
812 | tf->feature = args[2]; | 774 | tf->feature = args[2]; |
813 | tf->nsect = args[3]; | 775 | if (args[0] == WIN_SMART) { |
814 | tf->lbal = args[1]; | 776 | tf->nsect = args[3]; |
777 | tf->lbal = args[1]; | ||
778 | tf->lbam = 0x4f; | ||
779 | tf->lbah = 0xc2; | ||
780 | tfargs.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_IN_NSECT; | ||
781 | } else { | ||
782 | tf->nsect = args[1]; | ||
783 | tfargs.tf_flags = IDE_TFLAG_OUT_FEATURE | | ||
784 | IDE_TFLAG_OUT_NSECT | IDE_TFLAG_IN_NSECT; | ||
785 | } | ||
815 | tf->command = args[0]; | 786 | tf->command = args[0]; |
787 | tfargs.data_phase = args[3] ? TASKFILE_IN : TASKFILE_NO_DATA; | ||
816 | 788 | ||
817 | if (args[3]) { | 789 | if (args[3]) { |
818 | argsize = 4 + (SECTOR_WORDS * 4 * args[3]); | 790 | tfargs.tf_flags |= IDE_TFLAG_IO_16BIT; |
819 | argbuf = kzalloc(argsize, GFP_KERNEL); | 791 | bufsize = SECTOR_WORDS * 4 * args[3]; |
820 | if (argbuf == NULL) | 792 | buf = kzalloc(bufsize, GFP_KERNEL); |
793 | if (buf == NULL) | ||
821 | return -ENOMEM; | 794 | return -ENOMEM; |
822 | } | 795 | } |
796 | |||
823 | if (set_transfer(drive, &tfargs)) { | 797 | if (set_transfer(drive, &tfargs)) { |
824 | xfer_rate = args[1]; | 798 | xfer_rate = args[1]; |
825 | if (ide_ata66_check(drive, &tfargs)) | 799 | if (ide_ata66_check(drive, &tfargs)) |
826 | goto abort; | 800 | goto abort; |
827 | } | 801 | } |
828 | 802 | ||
829 | err = ide_wait_cmd(drive, args[0], args[1], args[2], args[3], argbuf); | 803 | err = ide_raw_taskfile(drive, &tfargs, buf, args[3]); |
804 | |||
805 | args[0] = tf->status; | ||
806 | args[1] = tf->error; | ||
807 | args[2] = tf->nsect; | ||
830 | 808 | ||
831 | if (!err && xfer_rate) { | 809 | if (!err && xfer_rate) { |
832 | /* active-retuning-calls future */ | 810 | /* active-retuning-calls future */ |
@@ -834,10 +812,13 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) | |||
834 | ide_driveid_update(drive); | 812 | ide_driveid_update(drive); |
835 | } | 813 | } |
836 | abort: | 814 | abort: |
837 | if (copy_to_user((void __user *)arg, argbuf, argsize)) | 815 | if (copy_to_user((void __user *)arg, &args, 4)) |
838 | err = -EFAULT; | 816 | err = -EFAULT; |
839 | if (argsize > 4) | 817 | if (buf) { |
840 | kfree(argbuf); | 818 | if (copy_to_user((void __user *)(arg + 4), buf, bufsize)) |
819 | err = -EFAULT; | ||
820 | kfree(buf); | ||
821 | } | ||
841 | return err; | 822 | return err; |
842 | } | 823 | } |
843 | 824 | ||
@@ -854,7 +835,7 @@ int ide_task_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) | |||
854 | memset(&task, 0, sizeof(task)); | 835 | memset(&task, 0, sizeof(task)); |
855 | memcpy(&task.tf_array[7], &args[1], 6); | 836 | memcpy(&task.tf_array[7], &args[1], 6); |
856 | task.tf.command = args[0]; | 837 | task.tf.command = args[0]; |
857 | task.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; | 838 | task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
858 | 839 | ||
859 | err = ide_no_data_taskfile(drive, &task); | 840 | err = ide_no_data_taskfile(drive, &task); |
860 | 841 | ||
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index c6d4f630e18a..97894abd9ebc 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
@@ -95,7 +95,7 @@ DEFINE_MUTEX(ide_cfg_mtx); | |||
95 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(ide_lock); | 95 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(ide_lock); |
96 | 96 | ||
97 | #ifdef CONFIG_IDEPCI_PCIBUS_ORDER | 97 | #ifdef CONFIG_IDEPCI_PCIBUS_ORDER |
98 | static int ide_scan_direction; /* THIS was formerly 2.2.x pci=reverse */ | 98 | int ide_scan_direction; /* THIS was formerly 2.2.x pci=reverse */ |
99 | #endif | 99 | #endif |
100 | 100 | ||
101 | int noautodma = 0; | 101 | int noautodma = 0; |
@@ -116,7 +116,7 @@ EXPORT_SYMBOL(ide_hwifs); | |||
116 | /* | 116 | /* |
117 | * Do not even *think* about calling this! | 117 | * Do not even *think* about calling this! |
118 | */ | 118 | */ |
119 | static void init_hwif_data(ide_hwif_t *hwif, unsigned int index) | 119 | void ide_init_port_data(ide_hwif_t *hwif, unsigned int index) |
120 | { | 120 | { |
121 | unsigned int unit; | 121 | unsigned int unit; |
122 | 122 | ||
@@ -159,6 +159,7 @@ static void init_hwif_data(ide_hwif_t *hwif, unsigned int index) | |||
159 | init_completion(&drive->gendev_rel_comp); | 159 | init_completion(&drive->gendev_rel_comp); |
160 | } | 160 | } |
161 | } | 161 | } |
162 | EXPORT_SYMBOL_GPL(ide_init_port_data); | ||
162 | 163 | ||
163 | static void init_hwif_default(ide_hwif_t *hwif, unsigned int index) | 164 | static void init_hwif_default(ide_hwif_t *hwif, unsigned int index) |
164 | { | 165 | { |
@@ -177,8 +178,6 @@ static void init_hwif_default(ide_hwif_t *hwif, unsigned int index) | |||
177 | #endif | 178 | #endif |
178 | } | 179 | } |
179 | 180 | ||
180 | extern void ide_arm_init(void); | ||
181 | |||
182 | /* | 181 | /* |
183 | * init_ide_data() sets reasonable default values into all fields | 182 | * init_ide_data() sets reasonable default values into all fields |
184 | * of all instances of the hwifs and drives, but only on the first call. | 183 | * of all instances of the hwifs and drives, but only on the first call. |
@@ -210,16 +209,13 @@ static void __init init_ide_data (void) | |||
210 | /* Initialise all interface structures */ | 209 | /* Initialise all interface structures */ |
211 | for (index = 0; index < MAX_HWIFS; ++index) { | 210 | for (index = 0; index < MAX_HWIFS; ++index) { |
212 | hwif = &ide_hwifs[index]; | 211 | hwif = &ide_hwifs[index]; |
213 | init_hwif_data(hwif, index); | 212 | ide_init_port_data(hwif, index); |
214 | init_hwif_default(hwif, index); | 213 | init_hwif_default(hwif, index); |
215 | #if !defined(CONFIG_PPC32) || !defined(CONFIG_PCI) | 214 | #if !defined(CONFIG_PPC32) || !defined(CONFIG_PCI) |
216 | hwif->irq = | 215 | hwif->irq = |
217 | ide_init_default_irq(hwif->io_ports[IDE_DATA_OFFSET]); | 216 | ide_init_default_irq(hwif->io_ports[IDE_DATA_OFFSET]); |
218 | #endif | 217 | #endif |
219 | } | 218 | } |
220 | #ifdef CONFIG_IDE_ARM | ||
221 | ide_arm_init(); | ||
222 | #endif | ||
223 | } | 219 | } |
224 | 220 | ||
225 | /** | 221 | /** |
@@ -414,8 +410,6 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif) | |||
414 | hwif->cds = tmp_hwif->cds; | 410 | hwif->cds = tmp_hwif->cds; |
415 | #endif | 411 | #endif |
416 | 412 | ||
417 | hwif->fixup = tmp_hwif->fixup; | ||
418 | |||
419 | hwif->set_pio_mode = tmp_hwif->set_pio_mode; | 413 | hwif->set_pio_mode = tmp_hwif->set_pio_mode; |
420 | hwif->set_dma_mode = tmp_hwif->set_dma_mode; | 414 | hwif->set_dma_mode = tmp_hwif->set_dma_mode; |
421 | hwif->mdma_filter = tmp_hwif->mdma_filter; | 415 | hwif->mdma_filter = tmp_hwif->mdma_filter; |
@@ -433,16 +427,13 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif) | |||
433 | hwif->atapi_input_bytes = tmp_hwif->atapi_input_bytes; | 427 | hwif->atapi_input_bytes = tmp_hwif->atapi_input_bytes; |
434 | hwif->atapi_output_bytes = tmp_hwif->atapi_output_bytes; | 428 | hwif->atapi_output_bytes = tmp_hwif->atapi_output_bytes; |
435 | 429 | ||
430 | hwif->dma_host_set = tmp_hwif->dma_host_set; | ||
436 | hwif->dma_setup = tmp_hwif->dma_setup; | 431 | hwif->dma_setup = tmp_hwif->dma_setup; |
437 | hwif->dma_exec_cmd = tmp_hwif->dma_exec_cmd; | 432 | hwif->dma_exec_cmd = tmp_hwif->dma_exec_cmd; |
438 | hwif->dma_start = tmp_hwif->dma_start; | 433 | hwif->dma_start = tmp_hwif->dma_start; |
439 | hwif->ide_dma_end = tmp_hwif->ide_dma_end; | 434 | hwif->ide_dma_end = tmp_hwif->ide_dma_end; |
440 | hwif->ide_dma_on = tmp_hwif->ide_dma_on; | ||
441 | hwif->dma_off_quietly = tmp_hwif->dma_off_quietly; | ||
442 | hwif->ide_dma_test_irq = tmp_hwif->ide_dma_test_irq; | 435 | hwif->ide_dma_test_irq = tmp_hwif->ide_dma_test_irq; |
443 | hwif->ide_dma_clear_irq = tmp_hwif->ide_dma_clear_irq; | 436 | hwif->ide_dma_clear_irq = tmp_hwif->ide_dma_clear_irq; |
444 | hwif->dma_host_on = tmp_hwif->dma_host_on; | ||
445 | hwif->dma_host_off = tmp_hwif->dma_host_off; | ||
446 | hwif->dma_lost_irq = tmp_hwif->dma_lost_irq; | 437 | hwif->dma_lost_irq = tmp_hwif->dma_lost_irq; |
447 | hwif->dma_timeout = tmp_hwif->dma_timeout; | 438 | hwif->dma_timeout = tmp_hwif->dma_timeout; |
448 | 439 | ||
@@ -614,7 +605,7 @@ void ide_unregister(unsigned int index) | |||
614 | tmp_hwif = *hwif; | 605 | tmp_hwif = *hwif; |
615 | 606 | ||
616 | /* restore hwif data to pristine status */ | 607 | /* restore hwif data to pristine status */ |
617 | init_hwif_data(hwif, index); | 608 | ide_init_port_data(hwif, index); |
618 | init_hwif_default(hwif, index); | 609 | init_hwif_default(hwif, index); |
619 | 610 | ||
620 | ide_hwif_restore(hwif, &tmp_hwif); | 611 | ide_hwif_restore(hwif, &tmp_hwif); |
@@ -680,24 +671,34 @@ void ide_setup_ports ( hw_regs_t *hw, | |||
680 | */ | 671 | */ |
681 | } | 672 | } |
682 | 673 | ||
674 | void ide_init_port_hw(ide_hwif_t *hwif, hw_regs_t *hw) | ||
675 | { | ||
676 | memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports)); | ||
677 | hwif->irq = hw->irq; | ||
678 | hwif->noprobe = 0; | ||
679 | hwif->chipset = hw->chipset; | ||
680 | hwif->gendev.parent = hw->dev; | ||
681 | hwif->ack_intr = hw->ack_intr; | ||
682 | } | ||
683 | EXPORT_SYMBOL_GPL(ide_init_port_hw); | ||
684 | |||
683 | /** | 685 | /** |
684 | * ide_register_hw - register IDE interface | 686 | * ide_register_hw - register IDE interface |
685 | * @hw: hardware registers | 687 | * @hw: hardware registers |
686 | * @fixup: fixup function | 688 | * @quirkproc: quirkproc function |
687 | * @initializing: set while initializing built-in drivers | ||
688 | * @hwifp: pointer to returned hwif | 689 | * @hwifp: pointer to returned hwif |
689 | * | 690 | * |
690 | * Register an IDE interface, specifying exactly the registers etc. | 691 | * Register an IDE interface, specifying exactly the registers etc. |
691 | * Set init=1 iff calling before probes have taken place. | ||
692 | * | 692 | * |
693 | * Returns -1 on error. | 693 | * Returns -1 on error. |
694 | */ | 694 | */ |
695 | 695 | ||
696 | int ide_register_hw(hw_regs_t *hw, void (*fixup)(ide_hwif_t *), | 696 | int ide_register_hw(hw_regs_t *hw, void (*quirkproc)(ide_drive_t *), |
697 | int initializing, ide_hwif_t **hwifp) | 697 | ide_hwif_t **hwifp) |
698 | { | 698 | { |
699 | int index, retry = 1; | 699 | int index, retry = 1; |
700 | ide_hwif_t *hwif; | 700 | ide_hwif_t *hwif; |
701 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; | ||
701 | 702 | ||
702 | do { | 703 | do { |
703 | for (index = 0; index < MAX_HWIFS; ++index) { | 704 | for (index = 0; index < MAX_HWIFS; ++index) { |
@@ -709,8 +710,7 @@ int ide_register_hw(hw_regs_t *hw, void (*fixup)(ide_hwif_t *), | |||
709 | hwif = &ide_hwifs[index]; | 710 | hwif = &ide_hwifs[index]; |
710 | if (hwif->hold) | 711 | if (hwif->hold) |
711 | continue; | 712 | continue; |
712 | if ((!hwif->present && !hwif->mate && !initializing) || | 713 | if (!hwif->present && hwif->mate == NULL) |
713 | (!hwif->io_ports[IDE_DATA_OFFSET] && initializing)) | ||
714 | goto found; | 714 | goto found; |
715 | } | 715 | } |
716 | for (index = 0; index < MAX_HWIFS; index++) | 716 | for (index = 0; index < MAX_HWIFS; index++) |
@@ -721,29 +721,23 @@ found: | |||
721 | if (hwif->present) | 721 | if (hwif->present) |
722 | ide_unregister(index); | 722 | ide_unregister(index); |
723 | else if (!hwif->hold) { | 723 | else if (!hwif->hold) { |
724 | init_hwif_data(hwif, index); | 724 | ide_init_port_data(hwif, index); |
725 | init_hwif_default(hwif, index); | 725 | init_hwif_default(hwif, index); |
726 | } | 726 | } |
727 | if (hwif->present) | 727 | if (hwif->present) |
728 | return -1; | 728 | return -1; |
729 | memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports)); | ||
730 | hwif->irq = hw->irq; | ||
731 | hwif->noprobe = 0; | ||
732 | hwif->fixup = fixup; | ||
733 | hwif->chipset = hw->chipset; | ||
734 | hwif->gendev.parent = hw->dev; | ||
735 | hwif->ack_intr = hw->ack_intr; | ||
736 | 729 | ||
737 | if (initializing == 0) { | 730 | ide_init_port_hw(hwif, hw); |
738 | u8 idx[4] = { index, 0xff, 0xff, 0xff }; | 731 | hwif->quirkproc = quirkproc; |
739 | 732 | ||
740 | ide_device_add(idx); | 733 | idx[0] = index; |
741 | } | 734 | |
735 | ide_device_add(idx); | ||
742 | 736 | ||
743 | if (hwifp) | 737 | if (hwifp) |
744 | *hwifp = hwif; | 738 | *hwifp = hwif; |
745 | 739 | ||
746 | return (initializing || hwif->present) ? index : -1; | 740 | return hwif->present ? index : -1; |
747 | } | 741 | } |
748 | 742 | ||
749 | EXPORT_SYMBOL(ide_register_hw); | 743 | EXPORT_SYMBOL(ide_register_hw); |
@@ -836,7 +830,7 @@ int set_using_dma(ide_drive_t *drive, int arg) | |||
836 | if (!drive->id || !(drive->id->capability & 1)) | 830 | if (!drive->id || !(drive->id->capability & 1)) |
837 | goto out; | 831 | goto out; |
838 | 832 | ||
839 | if (hwif->ide_dma_on == NULL) | 833 | if (hwif->dma_host_set == NULL) |
840 | goto out; | 834 | goto out; |
841 | 835 | ||
842 | err = -EBUSY; | 836 | err = -EBUSY; |
@@ -884,7 +878,10 @@ int set_pio_mode(ide_drive_t *drive, int arg) | |||
884 | 878 | ||
885 | if (drive->special.b.set_tune) | 879 | if (drive->special.b.set_tune) |
886 | return -EBUSY; | 880 | return -EBUSY; |
881 | |||
887 | ide_init_drive_cmd(&rq); | 882 | ide_init_drive_cmd(&rq); |
883 | rq.cmd_type = REQ_TYPE_ATA_TASKFILE; | ||
884 | |||
888 | drive->tune_req = (u8) arg; | 885 | drive->tune_req = (u8) arg; |
889 | drive->special.b.set_tune = 1; | 886 | drive->special.b.set_tune = 1; |
890 | (void) ide_do_drive_cmd(drive, &rq, ide_wait); | 887 | (void) ide_do_drive_cmd(drive, &rq, ide_wait); |
@@ -1066,7 +1063,7 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device | |||
1066 | ide_init_hwif_ports(&hw, (unsigned long) args[0], | 1063 | ide_init_hwif_ports(&hw, (unsigned long) args[0], |
1067 | (unsigned long) args[1], NULL); | 1064 | (unsigned long) args[1], NULL); |
1068 | hw.irq = args[2]; | 1065 | hw.irq = args[2]; |
1069 | if (ide_register_hw(&hw, NULL, 0, NULL) == -1) | 1066 | if (ide_register_hw(&hw, NULL, NULL) == -1) |
1070 | return -EIO; | 1067 | return -EIO; |
1071 | return 0; | 1068 | return 0; |
1072 | } | 1069 | } |
@@ -1227,26 +1224,12 @@ static int __init match_parm (char *s, const char *keywords[], int vals[], int m | |||
1227 | return 0; /* zero = nothing matched */ | 1224 | return 0; /* zero = nothing matched */ |
1228 | } | 1225 | } |
1229 | 1226 | ||
1230 | #ifdef CONFIG_BLK_DEV_ALI14XX | ||
1231 | extern int probe_ali14xx; | 1227 | extern int probe_ali14xx; |
1232 | extern int ali14xx_init(void); | ||
1233 | #endif | ||
1234 | #ifdef CONFIG_BLK_DEV_UMC8672 | ||
1235 | extern int probe_umc8672; | 1228 | extern int probe_umc8672; |
1236 | extern int umc8672_init(void); | ||
1237 | #endif | ||
1238 | #ifdef CONFIG_BLK_DEV_DTC2278 | ||
1239 | extern int probe_dtc2278; | 1229 | extern int probe_dtc2278; |
1240 | extern int dtc2278_init(void); | ||
1241 | #endif | ||
1242 | #ifdef CONFIG_BLK_DEV_HT6560B | ||
1243 | extern int probe_ht6560b; | 1230 | extern int probe_ht6560b; |
1244 | extern int ht6560b_init(void); | ||
1245 | #endif | ||
1246 | #ifdef CONFIG_BLK_DEV_QD65XX | ||
1247 | extern int probe_qd65xx; | 1231 | extern int probe_qd65xx; |
1248 | extern int qd65xx_init(void); | 1232 | extern int cmd640_vlb; |
1249 | #endif | ||
1250 | 1233 | ||
1251 | static int __initdata is_chipset_set[MAX_HWIFS]; | 1234 | static int __initdata is_chipset_set[MAX_HWIFS]; |
1252 | 1235 | ||
@@ -1323,7 +1306,7 @@ static int __init ide_setup(char *s) | |||
1323 | if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) { | 1306 | if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) { |
1324 | const char *hd_words[] = { | 1307 | const char *hd_words[] = { |
1325 | "none", "noprobe", "nowerr", "cdrom", "nodma", | 1308 | "none", "noprobe", "nowerr", "cdrom", "nodma", |
1326 | "autotune", "noautotune", "minus8", "swapdata", "bswap", | 1309 | "autotune", "noautotune", "-8", "-9", "-10", |
1327 | "noflush", "remap", "remap63", "scsi", NULL }; | 1310 | "noflush", "remap", "remap63", "scsi", NULL }; |
1328 | unit = s[2] - 'a'; | 1311 | unit = s[2] - 'a'; |
1329 | hw = unit / MAX_DRIVES; | 1312 | hw = unit / MAX_DRIVES; |
@@ -1359,10 +1342,6 @@ static int __init ide_setup(char *s) | |||
1359 | case -7: /* "noautotune" */ | 1342 | case -7: /* "noautotune" */ |
1360 | drive->autotune = IDE_TUNE_NOAUTO; | 1343 | drive->autotune = IDE_TUNE_NOAUTO; |
1361 | goto obsolete_option; | 1344 | goto obsolete_option; |
1362 | case -9: /* "swapdata" */ | ||
1363 | case -10: /* "bswap" */ | ||
1364 | drive->bswap = 1; | ||
1365 | goto done; | ||
1366 | case -11: /* noflush */ | 1345 | case -11: /* noflush */ |
1367 | drive->noflush = 1; | 1346 | drive->noflush = 1; |
1368 | goto done; | 1347 | goto done; |
@@ -1462,11 +1441,8 @@ static int __init ide_setup(char *s) | |||
1462 | #endif | 1441 | #endif |
1463 | #ifdef CONFIG_BLK_DEV_CMD640 | 1442 | #ifdef CONFIG_BLK_DEV_CMD640 |
1464 | case -14: /* "cmd640_vlb" */ | 1443 | case -14: /* "cmd640_vlb" */ |
1465 | { | ||
1466 | extern int cmd640_vlb; /* flag for cmd640.c */ | ||
1467 | cmd640_vlb = 1; | 1444 | cmd640_vlb = 1; |
1468 | goto done; | 1445 | goto done; |
1469 | } | ||
1470 | #endif | 1446 | #endif |
1471 | #ifdef CONFIG_BLK_DEV_HT6560B | 1447 | #ifdef CONFIG_BLK_DEV_HT6560B |
1472 | case -13: /* "ht6560b" */ | 1448 | case -13: /* "ht6560b" */ |
@@ -1556,79 +1532,6 @@ done: | |||
1556 | return 1; | 1532 | return 1; |
1557 | } | 1533 | } |
1558 | 1534 | ||
1559 | extern void __init pnpide_init(void); | ||
1560 | extern void __exit pnpide_exit(void); | ||
1561 | extern void __init h8300_ide_init(void); | ||
1562 | |||
1563 | /* | ||
1564 | * probe_for_hwifs() finds/initializes "known" IDE interfaces | ||
1565 | */ | ||
1566 | static void __init probe_for_hwifs (void) | ||
1567 | { | ||
1568 | #ifdef CONFIG_IDEPCI_PCIBUS_ORDER | ||
1569 | ide_scan_pcibus(ide_scan_direction); | ||
1570 | #endif | ||
1571 | |||
1572 | #ifdef CONFIG_ETRAX_IDE | ||
1573 | { | ||
1574 | extern void init_e100_ide(void); | ||
1575 | init_e100_ide(); | ||
1576 | } | ||
1577 | #endif /* CONFIG_ETRAX_IDE */ | ||
1578 | #ifdef CONFIG_BLK_DEV_CMD640 | ||
1579 | { | ||
1580 | extern void ide_probe_for_cmd640x(void); | ||
1581 | ide_probe_for_cmd640x(); | ||
1582 | } | ||
1583 | #endif /* CONFIG_BLK_DEV_CMD640 */ | ||
1584 | #ifdef CONFIG_BLK_DEV_IDE_PMAC | ||
1585 | { | ||
1586 | extern int pmac_ide_probe(void); | ||
1587 | (void)pmac_ide_probe(); | ||
1588 | } | ||
1589 | #endif /* CONFIG_BLK_DEV_IDE_PMAC */ | ||
1590 | #ifdef CONFIG_BLK_DEV_GAYLE | ||
1591 | { | ||
1592 | extern void gayle_init(void); | ||
1593 | gayle_init(); | ||
1594 | } | ||
1595 | #endif /* CONFIG_BLK_DEV_GAYLE */ | ||
1596 | #ifdef CONFIG_BLK_DEV_FALCON_IDE | ||
1597 | { | ||
1598 | extern void falconide_init(void); | ||
1599 | falconide_init(); | ||
1600 | } | ||
1601 | #endif /* CONFIG_BLK_DEV_FALCON_IDE */ | ||
1602 | #ifdef CONFIG_BLK_DEV_MAC_IDE | ||
1603 | { | ||
1604 | extern void macide_init(void); | ||
1605 | macide_init(); | ||
1606 | } | ||
1607 | #endif /* CONFIG_BLK_DEV_MAC_IDE */ | ||
1608 | #ifdef CONFIG_BLK_DEV_Q40IDE | ||
1609 | { | ||
1610 | extern void q40ide_init(void); | ||
1611 | q40ide_init(); | ||
1612 | } | ||
1613 | #endif /* CONFIG_BLK_DEV_Q40IDE */ | ||
1614 | #ifdef CONFIG_BLK_DEV_BUDDHA | ||
1615 | { | ||
1616 | extern void buddha_init(void); | ||
1617 | buddha_init(); | ||
1618 | } | ||
1619 | #endif /* CONFIG_BLK_DEV_BUDDHA */ | ||
1620 | #ifdef CONFIG_BLK_DEV_IDEPNP | ||
1621 | pnpide_init(); | ||
1622 | #endif | ||
1623 | #ifdef CONFIG_H8300 | ||
1624 | h8300_ide_init(); | ||
1625 | #endif | ||
1626 | } | ||
1627 | |||
1628 | /* | ||
1629 | * Probe module | ||
1630 | */ | ||
1631 | |||
1632 | EXPORT_SYMBOL(ide_lock); | 1535 | EXPORT_SYMBOL(ide_lock); |
1633 | 1536 | ||
1634 | static int ide_bus_match(struct device *dev, struct device_driver *drv) | 1537 | static int ide_bus_match(struct device *dev, struct device_driver *drv) |
@@ -1775,30 +1678,6 @@ static int __init ide_init(void) | |||
1775 | 1678 | ||
1776 | proc_ide_create(); | 1679 | proc_ide_create(); |
1777 | 1680 | ||
1778 | #ifdef CONFIG_BLK_DEV_ALI14XX | ||
1779 | if (probe_ali14xx) | ||
1780 | (void)ali14xx_init(); | ||
1781 | #endif | ||
1782 | #ifdef CONFIG_BLK_DEV_UMC8672 | ||
1783 | if (probe_umc8672) | ||
1784 | (void)umc8672_init(); | ||
1785 | #endif | ||
1786 | #ifdef CONFIG_BLK_DEV_DTC2278 | ||
1787 | if (probe_dtc2278) | ||
1788 | (void)dtc2278_init(); | ||
1789 | #endif | ||
1790 | #ifdef CONFIG_BLK_DEV_HT6560B | ||
1791 | if (probe_ht6560b) | ||
1792 | (void)ht6560b_init(); | ||
1793 | #endif | ||
1794 | #ifdef CONFIG_BLK_DEV_QD65XX | ||
1795 | if (probe_qd65xx) | ||
1796 | (void)qd65xx_init(); | ||
1797 | #endif | ||
1798 | |||
1799 | /* Probe for special PCI and other "known" interface chipsets. */ | ||
1800 | probe_for_hwifs(); | ||
1801 | |||
1802 | return 0; | 1681 | return 0; |
1803 | } | 1682 | } |
1804 | 1683 | ||
@@ -1834,10 +1713,6 @@ void __exit cleanup_module (void) | |||
1834 | for (index = 0; index < MAX_HWIFS; ++index) | 1713 | for (index = 0; index < MAX_HWIFS; ++index) |
1835 | ide_unregister(index); | 1714 | ide_unregister(index); |
1836 | 1715 | ||
1837 | #ifdef CONFIG_BLK_DEV_IDEPNP | ||
1838 | pnpide_exit(); | ||
1839 | #endif | ||
1840 | |||
1841 | proc_ide_destroy(); | 1716 | proc_ide_destroy(); |
1842 | 1717 | ||
1843 | bus_unregister(&ide_bus_type); | 1718 | bus_unregister(&ide_bus_type); |
diff --git a/drivers/ide/legacy/Makefile b/drivers/ide/legacy/Makefile index 409822349f10..7043ec7d1e05 100644 --- a/drivers/ide/legacy/Makefile +++ b/drivers/ide/legacy/Makefile | |||
@@ -1,15 +1,24 @@ | |||
1 | 1 | ||
2 | # link order is important here | ||
3 | |||
2 | obj-$(CONFIG_BLK_DEV_ALI14XX) += ali14xx.o | 4 | obj-$(CONFIG_BLK_DEV_ALI14XX) += ali14xx.o |
5 | obj-$(CONFIG_BLK_DEV_UMC8672) += umc8672.o | ||
3 | obj-$(CONFIG_BLK_DEV_DTC2278) += dtc2278.o | 6 | obj-$(CONFIG_BLK_DEV_DTC2278) += dtc2278.o |
4 | obj-$(CONFIG_BLK_DEV_HT6560B) += ht6560b.o | 7 | obj-$(CONFIG_BLK_DEV_HT6560B) += ht6560b.o |
5 | obj-$(CONFIG_BLK_DEV_QD65XX) += qd65xx.o | 8 | obj-$(CONFIG_BLK_DEV_QD65XX) += qd65xx.o |
6 | obj-$(CONFIG_BLK_DEV_UMC8672) += umc8672.o | ||
7 | 9 | ||
8 | obj-$(CONFIG_BLK_DEV_IDECS) += ide-cs.o | 10 | obj-$(CONFIG_BLK_DEV_GAYLE) += gayle.o |
11 | obj-$(CONFIG_BLK_DEV_FALCON_IDE) += falconide.o | ||
12 | obj-$(CONFIG_BLK_DEV_MAC_IDE) += macide.o | ||
13 | obj-$(CONFIG_BLK_DEV_Q40IDE) += q40ide.o | ||
14 | obj-$(CONFIG_BLK_DEV_BUDDHA) += buddha.o | ||
9 | 15 | ||
10 | obj-$(CONFIG_BLK_DEV_PLATFORM) += ide_platform.o | 16 | ifeq ($(CONFIG_BLK_DEV_IDECS), m) |
17 | obj-m += ide-cs.o | ||
18 | endif | ||
11 | 19 | ||
12 | # Last of all | 20 | ifeq ($(CONFIG_BLK_DEV_PLATFORM), m) |
13 | obj-$(CONFIG_BLK_DEV_HD) += hd.o | 21 | obj-m += ide_platform.o |
22 | endif | ||
14 | 23 | ||
15 | EXTRA_CFLAGS := -Idrivers/ide | 24 | EXTRA_CFLAGS := -Idrivers/ide |
diff --git a/drivers/ide/legacy/ali14xx.c b/drivers/ide/legacy/ali14xx.c index 38c3a6d63f30..5ec0be4cbad7 100644 --- a/drivers/ide/legacy/ali14xx.c +++ b/drivers/ide/legacy/ali14xx.c | |||
@@ -231,8 +231,7 @@ int probe_ali14xx = 0; | |||
231 | module_param_named(probe, probe_ali14xx, bool, 0); | 231 | module_param_named(probe, probe_ali14xx, bool, 0); |
232 | MODULE_PARM_DESC(probe, "probe for ALI M14xx chipsets"); | 232 | MODULE_PARM_DESC(probe, "probe for ALI M14xx chipsets"); |
233 | 233 | ||
234 | /* Can be called directly from ide.c. */ | 234 | static int __init ali14xx_init(void) |
235 | int __init ali14xx_init(void) | ||
236 | { | 235 | { |
237 | if (probe_ali14xx == 0) | 236 | if (probe_ali14xx == 0) |
238 | goto out; | 237 | goto out; |
@@ -248,9 +247,7 @@ out: | |||
248 | return -ENODEV; | 247 | return -ENODEV; |
249 | } | 248 | } |
250 | 249 | ||
251 | #ifdef MODULE | ||
252 | module_init(ali14xx_init); | 250 | module_init(ali14xx_init); |
253 | #endif | ||
254 | 251 | ||
255 | MODULE_AUTHOR("see local file"); | 252 | MODULE_AUTHOR("see local file"); |
256 | MODULE_DESCRIPTION("support of ALI 14XX IDE chipsets"); | 253 | MODULE_DESCRIPTION("support of ALI 14XX IDE chipsets"); |
diff --git a/drivers/ide/legacy/buddha.c b/drivers/ide/legacy/buddha.c index 4a0be251a05f..74d28e058f55 100644 --- a/drivers/ide/legacy/buddha.c +++ b/drivers/ide/legacy/buddha.c | |||
@@ -112,6 +112,7 @@ typedef enum BuddhaType_Enum { | |||
112 | BOARD_BUDDHA, BOARD_CATWEASEL, BOARD_XSURF | 112 | BOARD_BUDDHA, BOARD_CATWEASEL, BOARD_XSURF |
113 | } BuddhaType; | 113 | } BuddhaType; |
114 | 114 | ||
115 | static const char *buddha_board_name[] = { "Buddha", "Catweasel", "X-Surf" }; | ||
115 | 116 | ||
116 | /* | 117 | /* |
117 | * Check and acknowledge the interrupt status | 118 | * Check and acknowledge the interrupt status |
@@ -143,11 +144,11 @@ static int xsurf_ack_intr(ide_hwif_t *hwif) | |||
143 | * Probe for a Buddha or Catweasel IDE interface | 144 | * Probe for a Buddha or Catweasel IDE interface |
144 | */ | 145 | */ |
145 | 146 | ||
146 | void __init buddha_init(void) | 147 | static int __init buddha_init(void) |
147 | { | 148 | { |
148 | hw_regs_t hw; | 149 | hw_regs_t hw; |
149 | ide_hwif_t *hwif; | 150 | ide_hwif_t *hwif; |
150 | int i, index; | 151 | int i; |
151 | 152 | ||
152 | struct zorro_dev *z = NULL; | 153 | struct zorro_dev *z = NULL; |
153 | u_long buddha_board = 0; | 154 | u_long buddha_board = 0; |
@@ -156,6 +157,8 @@ void __init buddha_init(void) | |||
156 | 157 | ||
157 | while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { | 158 | while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { |
158 | unsigned long board; | 159 | unsigned long board; |
160 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; | ||
161 | |||
159 | if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA) { | 162 | if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA) { |
160 | buddha_num_hwifs = BUDDHA_NUM_HWIFS; | 163 | buddha_num_hwifs = BUDDHA_NUM_HWIFS; |
161 | type=BOARD_BUDDHA; | 164 | type=BOARD_BUDDHA; |
@@ -195,7 +198,10 @@ fail_base2: | |||
195 | /* X-Surf doesn't have this. IRQs are always on */ | 198 | /* X-Surf doesn't have this. IRQs are always on */ |
196 | if (type != BOARD_XSURF) | 199 | if (type != BOARD_XSURF) |
197 | z_writeb(0, buddha_board+BUDDHA_IRQ_MR); | 200 | z_writeb(0, buddha_board+BUDDHA_IRQ_MR); |
198 | 201 | ||
202 | printk(KERN_INFO "ide: %s IDE controller\n", | ||
203 | buddha_board_name[type]); | ||
204 | |||
199 | for(i=0;i<buddha_num_hwifs;i++) { | 205 | for(i=0;i<buddha_num_hwifs;i++) { |
200 | if(type != BOARD_XSURF) { | 206 | if(type != BOARD_XSURF) { |
201 | ide_setup_ports(&hw, (buddha_board+buddha_bases[i]), | 207 | ide_setup_ports(&hw, (buddha_board+buddha_bases[i]), |
@@ -213,23 +219,23 @@ fail_base2: | |||
213 | IRQ_AMIGA_PORTS); | 219 | IRQ_AMIGA_PORTS); |
214 | } | 220 | } |
215 | 221 | ||
216 | index = ide_register_hw(&hw, NULL, 1, &hwif); | 222 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); |
217 | if (index != -1) { | 223 | if (hwif) { |
224 | u8 index = hwif->index; | ||
225 | |||
226 | ide_init_port_data(hwif, index); | ||
227 | ide_init_port_hw(hwif, &hw); | ||
228 | |||
218 | hwif->mmio = 1; | 229 | hwif->mmio = 1; |
219 | printk("ide%d: ", index); | 230 | |
220 | switch(type) { | 231 | idx[i] = index; |
221 | case BOARD_BUDDHA: | 232 | } |
222 | printk("Buddha"); | ||
223 | break; | ||
224 | case BOARD_CATWEASEL: | ||
225 | printk("Catweasel"); | ||
226 | break; | ||
227 | case BOARD_XSURF: | ||
228 | printk("X-Surf"); | ||
229 | break; | ||
230 | } | ||
231 | printk(" IDE interface\n"); | ||
232 | } | ||
233 | } | 233 | } |
234 | |||
235 | ide_device_add(idx); | ||
234 | } | 236 | } |
237 | |||
238 | return 0; | ||
235 | } | 239 | } |
240 | |||
241 | module_init(buddha_init); | ||
diff --git a/drivers/ide/legacy/dtc2278.c b/drivers/ide/legacy/dtc2278.c index 24a845d45bd2..13eee6da2806 100644 --- a/drivers/ide/legacy/dtc2278.c +++ b/drivers/ide/legacy/dtc2278.c | |||
@@ -150,8 +150,7 @@ int probe_dtc2278 = 0; | |||
150 | module_param_named(probe, probe_dtc2278, bool, 0); | 150 | module_param_named(probe, probe_dtc2278, bool, 0); |
151 | MODULE_PARM_DESC(probe, "probe for DTC2278xx chipsets"); | 151 | MODULE_PARM_DESC(probe, "probe for DTC2278xx chipsets"); |
152 | 152 | ||
153 | /* Can be called directly from ide.c. */ | 153 | static int __init dtc2278_init(void) |
154 | int __init dtc2278_init(void) | ||
155 | { | 154 | { |
156 | if (probe_dtc2278 == 0) | 155 | if (probe_dtc2278 == 0) |
157 | return -ENODEV; | 156 | return -ENODEV; |
@@ -163,9 +162,7 @@ int __init dtc2278_init(void) | |||
163 | return 0; | 162 | return 0; |
164 | } | 163 | } |
165 | 164 | ||
166 | #ifdef MODULE | ||
167 | module_init(dtc2278_init); | 165 | module_init(dtc2278_init); |
168 | #endif | ||
169 | 166 | ||
170 | MODULE_AUTHOR("See Local File"); | 167 | MODULE_AUTHOR("See Local File"); |
171 | MODULE_DESCRIPTION("support of DTC-2278 VLB IDE chipsets"); | 168 | MODULE_DESCRIPTION("support of DTC-2278 VLB IDE chipsets"); |
diff --git a/drivers/ide/legacy/falconide.c b/drivers/ide/legacy/falconide.c index 7d7936f1b900..2860956bdcb0 100644 --- a/drivers/ide/legacy/falconide.c +++ b/drivers/ide/legacy/falconide.c | |||
@@ -62,19 +62,31 @@ EXPORT_SYMBOL(falconide_intr_lock); | |||
62 | * Probe for a Falcon IDE interface | 62 | * Probe for a Falcon IDE interface |
63 | */ | 63 | */ |
64 | 64 | ||
65 | void __init falconide_init(void) | 65 | static int __init falconide_init(void) |
66 | { | 66 | { |
67 | if (MACH_IS_ATARI && ATARIHW_PRESENT(IDE)) { | 67 | if (MACH_IS_ATARI && ATARIHW_PRESENT(IDE)) { |
68 | hw_regs_t hw; | 68 | hw_regs_t hw; |
69 | int index; | 69 | |
70 | printk(KERN_INFO "ide: Falcon IDE controller\n"); | ||
70 | 71 | ||
71 | ide_setup_ports(&hw, ATA_HD_BASE, falconide_offsets, | 72 | ide_setup_ports(&hw, ATA_HD_BASE, falconide_offsets, |
72 | 0, 0, NULL, | 73 | 0, 0, NULL, |
73 | // falconide_iops, | 74 | // falconide_iops, |
74 | IRQ_MFP_IDE); | 75 | IRQ_MFP_IDE); |
75 | index = ide_register_hw(&hw, NULL, 1, NULL); | ||
76 | 76 | ||
77 | if (index != -1) | 77 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); |
78 | printk("ide%d: Falcon IDE interface\n", index); | 78 | if (hwif) { |
79 | u8 index = hwif->index; | ||
80 | u8 idx[4] = { index, 0xff, 0xff, 0xff }; | ||
81 | |||
82 | ide_init_port_data(hwif, index); | ||
83 | ide_init_port_hw(hwif, &hw); | ||
84 | |||
85 | ide_device_add(idx); | ||
86 | } | ||
79 | } | 87 | } |
88 | |||
89 | return 0; | ||
80 | } | 90 | } |
91 | |||
92 | module_init(falconide_init); | ||
diff --git a/drivers/ide/legacy/gayle.c b/drivers/ide/legacy/gayle.c index 53331ee1e957..492fa047efc0 100644 --- a/drivers/ide/legacy/gayle.c +++ b/drivers/ide/legacy/gayle.c | |||
@@ -110,12 +110,13 @@ static int gayle_ack_intr_a1200(ide_hwif_t *hwif) | |||
110 | * Probe for a Gayle IDE interface (and optionally for an IDE doubler) | 110 | * Probe for a Gayle IDE interface (and optionally for an IDE doubler) |
111 | */ | 111 | */ |
112 | 112 | ||
113 | void __init gayle_init(void) | 113 | static int __init gayle_init(void) |
114 | { | 114 | { |
115 | int a4000, i; | 115 | int a4000, i; |
116 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; | ||
116 | 117 | ||
117 | if (!MACH_IS_AMIGA) | 118 | if (!MACH_IS_AMIGA) |
118 | return; | 119 | return -ENODEV; |
119 | 120 | ||
120 | if ((a4000 = AMIGAHW_PRESENT(A4000_IDE)) || AMIGAHW_PRESENT(A1200_IDE)) | 121 | if ((a4000 = AMIGAHW_PRESENT(A4000_IDE)) || AMIGAHW_PRESENT(A1200_IDE)) |
121 | goto found; | 122 | goto found; |
@@ -125,15 +126,21 @@ void __init gayle_init(void) | |||
125 | NULL)) | 126 | NULL)) |
126 | goto found; | 127 | goto found; |
127 | #endif | 128 | #endif |
128 | return; | 129 | return -ENODEV; |
129 | 130 | ||
130 | found: | 131 | found: |
132 | printk(KERN_INFO "ide: Gayle IDE controller (A%d style%s)\n", | ||
133 | a4000 ? 4000 : 1200, | ||
134 | #ifdef CONFIG_BLK_DEV_IDEDOUBLER | ||
135 | ide_doubler ? ", IDE doubler" : | ||
136 | #endif | ||
137 | ""); | ||
138 | |||
131 | for (i = 0; i < GAYLE_NUM_PROBE_HWIFS; i++) { | 139 | for (i = 0; i < GAYLE_NUM_PROBE_HWIFS; i++) { |
132 | unsigned long base, ctrlport, irqport; | 140 | unsigned long base, ctrlport, irqport; |
133 | ide_ack_intr_t *ack_intr; | 141 | ide_ack_intr_t *ack_intr; |
134 | hw_regs_t hw; | 142 | hw_regs_t hw; |
135 | ide_hwif_t *hwif; | 143 | ide_hwif_t *hwif; |
136 | int index; | ||
137 | unsigned long phys_base, res_start, res_n; | 144 | unsigned long phys_base, res_start, res_n; |
138 | 145 | ||
139 | if (a4000) { | 146 | if (a4000) { |
@@ -165,21 +172,23 @@ found: | |||
165 | // &gayle_iops, | 172 | // &gayle_iops, |
166 | IRQ_AMIGA_PORTS); | 173 | IRQ_AMIGA_PORTS); |
167 | 174 | ||
168 | index = ide_register_hw(&hw, NULL, 1, &hwif); | 175 | hwif = ide_find_port(base); |
169 | if (index != -1) { | 176 | if (hwif) { |
177 | u8 index = hwif->index; | ||
178 | |||
179 | ide_init_port_data(hwif, index); | ||
180 | ide_init_port_hw(hwif, &hw); | ||
181 | |||
170 | hwif->mmio = 1; | 182 | hwif->mmio = 1; |
171 | switch (i) { | 183 | |
172 | case 0: | 184 | idx[i] = index; |
173 | printk("ide%d: Gayle IDE interface (A%d style)\n", index, | ||
174 | a4000 ? 4000 : 1200); | ||
175 | break; | ||
176 | #ifdef CONFIG_BLK_DEV_IDEDOUBLER | ||
177 | case 1: | ||
178 | printk("ide%d: IDE doubler\n", index); | ||
179 | break; | ||
180 | #endif /* CONFIG_BLK_DEV_IDEDOUBLER */ | ||
181 | } | ||
182 | } else | 185 | } else |
183 | release_mem_region(res_start, res_n); | 186 | release_mem_region(res_start, res_n); |
184 | } | 187 | } |
188 | |||
189 | ide_device_add(idx); | ||
190 | |||
191 | return 0; | ||
185 | } | 192 | } |
193 | |||
194 | module_init(gayle_init); | ||
diff --git a/drivers/ide/legacy/ht6560b.c b/drivers/ide/legacy/ht6560b.c index a4245d13f11b..8da5031a6d05 100644 --- a/drivers/ide/legacy/ht6560b.c +++ b/drivers/ide/legacy/ht6560b.c | |||
@@ -307,8 +307,7 @@ int probe_ht6560b = 0; | |||
307 | module_param_named(probe, probe_ht6560b, bool, 0); | 307 | module_param_named(probe, probe_ht6560b, bool, 0); |
308 | MODULE_PARM_DESC(probe, "probe for HT6560B chipset"); | 308 | MODULE_PARM_DESC(probe, "probe for HT6560B chipset"); |
309 | 309 | ||
310 | /* Can be called directly from ide.c. */ | 310 | static int __init ht6560b_init(void) |
311 | int __init ht6560b_init(void) | ||
312 | { | 311 | { |
313 | ide_hwif_t *hwif, *mate; | 312 | ide_hwif_t *hwif, *mate; |
314 | static u8 idx[4] = { 0, 1, 0xff, 0xff }; | 313 | static u8 idx[4] = { 0, 1, 0xff, 0xff }; |
@@ -369,9 +368,7 @@ release_region: | |||
369 | return -ENODEV; | 368 | return -ENODEV; |
370 | } | 369 | } |
371 | 370 | ||
372 | #ifdef MODULE | ||
373 | module_init(ht6560b_init); | 371 | module_init(ht6560b_init); |
374 | #endif | ||
375 | 372 | ||
376 | MODULE_AUTHOR("See Local File"); | 373 | MODULE_AUTHOR("See Local File"); |
377 | MODULE_DESCRIPTION("HT-6560B EIDE-controller support"); | 374 | MODULE_DESCRIPTION("HT-6560B EIDE-controller support"); |
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index 03715c058664..f4ea15b32969 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/legacy/ide-cs.c | |||
@@ -153,7 +153,7 @@ static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq | |||
153 | hw.irq = irq; | 153 | hw.irq = irq; |
154 | hw.chipset = ide_pci; | 154 | hw.chipset = ide_pci; |
155 | hw.dev = &handle->dev; | 155 | hw.dev = &handle->dev; |
156 | return ide_register_hw(&hw, &ide_undecoded_slave, 0, NULL); | 156 | return ide_register_hw(&hw, &ide_undecoded_slave, NULL); |
157 | } | 157 | } |
158 | 158 | ||
159 | /*====================================================================== | 159 | /*====================================================================== |
diff --git a/drivers/ide/legacy/ide_platform.c b/drivers/ide/legacy/ide_platform.c index 7bb79f53dac8..69a0fb0e564f 100644 --- a/drivers/ide/legacy/ide_platform.c +++ b/drivers/ide/legacy/ide_platform.c | |||
@@ -28,39 +28,27 @@ static struct { | |||
28 | int index; | 28 | int index; |
29 | } hwif_prop; | 29 | } hwif_prop; |
30 | 30 | ||
31 | static ide_hwif_t *__devinit plat_ide_locate_hwif(void __iomem *base, | 31 | static void __devinit plat_ide_setup_ports(hw_regs_t *hw, |
32 | void __iomem *ctrl, struct pata_platform_info *pdata, int irq, | 32 | void __iomem *base, |
33 | int mmio) | 33 | void __iomem *ctrl, |
34 | struct pata_platform_info *pdata, | ||
35 | int irq) | ||
34 | { | 36 | { |
35 | unsigned long port = (unsigned long)base; | 37 | unsigned long port = (unsigned long)base; |
36 | ide_hwif_t *hwif = ide_find_port(port); | ||
37 | int i; | 38 | int i; |
38 | 39 | ||
39 | if (hwif == NULL) | 40 | hw->io_ports[IDE_DATA_OFFSET] = port; |
40 | goto out; | ||
41 | |||
42 | hwif->io_ports[IDE_DATA_OFFSET] = port; | ||
43 | 41 | ||
44 | port += (1 << pdata->ioport_shift); | 42 | port += (1 << pdata->ioport_shift); |
45 | for (i = IDE_ERROR_OFFSET; i <= IDE_STATUS_OFFSET; | 43 | for (i = IDE_ERROR_OFFSET; i <= IDE_STATUS_OFFSET; |
46 | i++, port += (1 << pdata->ioport_shift)) | 44 | i++, port += (1 << pdata->ioport_shift)) |
47 | hwif->io_ports[i] = port; | 45 | hw->io_ports[i] = port; |
48 | |||
49 | hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl; | ||
50 | 46 | ||
51 | hwif->irq = irq; | 47 | hw->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl; |
52 | 48 | ||
53 | hwif->chipset = ide_generic; | 49 | hw->irq = irq; |
54 | 50 | ||
55 | if (mmio) { | 51 | hw->chipset = ide_generic; |
56 | hwif->mmio = 1; | ||
57 | default_hwif_mmiops(hwif); | ||
58 | } | ||
59 | |||
60 | hwif_prop.hwif = hwif; | ||
61 | hwif_prop.index = hwif->index; | ||
62 | out: | ||
63 | return hwif; | ||
64 | } | 52 | } |
65 | 53 | ||
66 | static int __devinit plat_ide_probe(struct platform_device *pdev) | 54 | static int __devinit plat_ide_probe(struct platform_device *pdev) |
@@ -71,6 +59,7 @@ static int __devinit plat_ide_probe(struct platform_device *pdev) | |||
71 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; | 59 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; |
72 | int ret = 0; | 60 | int ret = 0; |
73 | int mmio = 0; | 61 | int mmio = 0; |
62 | hw_regs_t hw; | ||
74 | 63 | ||
75 | pdata = pdev->dev.platform_data; | 64 | pdata = pdev->dev.platform_data; |
76 | 65 | ||
@@ -106,15 +95,27 @@ static int __devinit plat_ide_probe(struct platform_device *pdev) | |||
106 | res_alt->start, res_alt->end - res_alt->start + 1); | 95 | res_alt->start, res_alt->end - res_alt->start + 1); |
107 | } | 96 | } |
108 | 97 | ||
109 | hwif = plat_ide_locate_hwif(hwif_prop.plat_ide_mapbase, | 98 | hwif = ide_find_port((unsigned long)hwif_prop.plat_ide_mapbase); |
110 | hwif_prop.plat_ide_alt_mapbase, pdata, res_irq->start, mmio); | ||
111 | |||
112 | if (!hwif) { | 99 | if (!hwif) { |
113 | ret = -ENODEV; | 100 | ret = -ENODEV; |
114 | goto out; | 101 | goto out; |
115 | } | 102 | } |
116 | hwif->gendev.parent = &pdev->dev; | 103 | |
117 | hwif->noprobe = 0; | 104 | memset(&hw, 0, sizeof(hw)); |
105 | plat_ide_setup_ports(&hw, hwif_prop.plat_ide_mapbase, | ||
106 | hwif_prop.plat_ide_alt_mapbase, | ||
107 | pdata, res_irq->start); | ||
108 | hw.dev = &pdev->dev; | ||
109 | |||
110 | ide_init_port_hw(hwif, &hw); | ||
111 | |||
112 | if (mmio) { | ||
113 | hwif->mmio = 1; | ||
114 | default_hwif_mmiops(hwif); | ||
115 | } | ||
116 | |||
117 | hwif_prop.hwif = hwif; | ||
118 | hwif_prop.index = hwif->index; | ||
118 | 119 | ||
119 | idx[0] = hwif->index; | 120 | idx[0] = hwif->index; |
120 | 121 | ||
diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c index 5c6aa77c2370..782d4c76c0e5 100644 --- a/drivers/ide/legacy/macide.c +++ b/drivers/ide/legacy/macide.c | |||
@@ -77,15 +77,17 @@ int macide_ack_intr(ide_hwif_t* hwif) | |||
77 | return 0; | 77 | return 0; |
78 | } | 78 | } |
79 | 79 | ||
80 | static const char *mac_ide_name[] = | ||
81 | { "Quadra", "Powerbook", "Powerbook Baboon" }; | ||
82 | |||
80 | /* | 83 | /* |
81 | * Probe for a Macintosh IDE interface | 84 | * Probe for a Macintosh IDE interface |
82 | */ | 85 | */ |
83 | 86 | ||
84 | void __init macide_init(void) | 87 | static int __init macide_init(void) |
85 | { | 88 | { |
86 | hw_regs_t hw; | 89 | hw_regs_t hw; |
87 | ide_hwif_t *hwif; | 90 | ide_hwif_t *hwif; |
88 | int index = -1; | ||
89 | 91 | ||
90 | switch (macintosh_config->ide_type) { | 92 | switch (macintosh_config->ide_type) { |
91 | case MAC_IDE_QUADRA: | 93 | case MAC_IDE_QUADRA: |
@@ -93,48 +95,50 @@ void __init macide_init(void) | |||
93 | 0, 0, macide_ack_intr, | 95 | 0, 0, macide_ack_intr, |
94 | // quadra_ide_iops, | 96 | // quadra_ide_iops, |
95 | IRQ_NUBUS_F); | 97 | IRQ_NUBUS_F); |
96 | index = ide_register_hw(&hw, NULL, 1, &hwif); | ||
97 | break; | 98 | break; |
98 | case MAC_IDE_PB: | 99 | case MAC_IDE_PB: |
99 | ide_setup_ports(&hw, IDE_BASE, macide_offsets, | 100 | ide_setup_ports(&hw, IDE_BASE, macide_offsets, |
100 | 0, 0, macide_ack_intr, | 101 | 0, 0, macide_ack_intr, |
101 | // macide_pb_iops, | 102 | // macide_pb_iops, |
102 | IRQ_NUBUS_C); | 103 | IRQ_NUBUS_C); |
103 | index = ide_register_hw(&hw, NULL, 1, &hwif); | ||
104 | break; | 104 | break; |
105 | case MAC_IDE_BABOON: | 105 | case MAC_IDE_BABOON: |
106 | ide_setup_ports(&hw, BABOON_BASE, macide_offsets, | 106 | ide_setup_ports(&hw, BABOON_BASE, macide_offsets, |
107 | 0, 0, NULL, | 107 | 0, 0, NULL, |
108 | // macide_baboon_iops, | 108 | // macide_baboon_iops, |
109 | IRQ_BABOON_1); | 109 | IRQ_BABOON_1); |
110 | index = ide_register_hw(&hw, NULL, 1, &hwif); | 110 | break; |
111 | if (index == -1) break; | 111 | default: |
112 | if (macintosh_config->ident == MAC_MODEL_PB190) { | 112 | return -ENODEV; |
113 | } | ||
114 | |||
115 | printk(KERN_INFO "ide: Macintosh %s IDE controller\n", | ||
116 | mac_ide_name[macintosh_config->ide_type - 1]); | ||
113 | 117 | ||
118 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); | ||
119 | if (hwif) { | ||
120 | u8 index = hwif->index; | ||
121 | u8 idx[4] = { index, 0xff, 0xff, 0xff }; | ||
122 | |||
123 | ide_init_port_data(hwif, index); | ||
124 | ide_init_port_hw(hwif, &hw); | ||
125 | |||
126 | if (macintosh_config->ide_type == MAC_IDE_BABOON && | ||
127 | macintosh_config->ident == MAC_MODEL_PB190) { | ||
114 | /* Fix breakage in ide-disk.c: drive capacity */ | 128 | /* Fix breakage in ide-disk.c: drive capacity */ |
115 | /* is not initialized for drives without a */ | 129 | /* is not initialized for drives without a */ |
116 | /* hardware ID, and we can't get that without */ | 130 | /* hardware ID, and we can't get that without */ |
117 | /* probing the drive which freezes a 190. */ | 131 | /* probing the drive which freezes a 190. */ |
118 | 132 | ide_drive_t *drive = &hwif->drives[0]; | |
119 | ide_drive_t *drive = &ide_hwifs[index].drives[0]; | ||
120 | drive->capacity64 = drive->cyl*drive->head*drive->sect; | 133 | drive->capacity64 = drive->cyl*drive->head*drive->sect; |
121 | |||
122 | } | 134 | } |
123 | break; | ||
124 | |||
125 | default: | ||
126 | return; | ||
127 | } | ||
128 | 135 | ||
129 | if (index != -1) { | ||
130 | hwif->mmio = 1; | 136 | hwif->mmio = 1; |
131 | if (macintosh_config->ide_type == MAC_IDE_QUADRA) | 137 | |
132 | printk(KERN_INFO "ide%d: Macintosh Quadra IDE interface\n", index); | 138 | ide_device_add(idx); |
133 | else if (macintosh_config->ide_type == MAC_IDE_PB) | ||
134 | printk(KERN_INFO "ide%d: Macintosh Powerbook IDE interface\n", index); | ||
135 | else if (macintosh_config->ide_type == MAC_IDE_BABOON) | ||
136 | printk(KERN_INFO "ide%d: Macintosh Powerbook Baboon IDE interface\n", index); | ||
137 | else | ||
138 | printk(KERN_INFO "ide%d: Unknown Macintosh IDE interface\n", index); | ||
139 | } | 139 | } |
140 | |||
141 | return 0; | ||
140 | } | 142 | } |
143 | |||
144 | module_init(macide_init); | ||
diff --git a/drivers/ide/legacy/q40ide.c b/drivers/ide/legacy/q40ide.c index 6ea46a6723e2..f5329730df99 100644 --- a/drivers/ide/legacy/q40ide.c +++ b/drivers/ide/legacy/q40ide.c | |||
@@ -111,15 +111,17 @@ static const char *q40_ide_names[Q40IDE_NUM_HWIFS]={ | |||
111 | * Probe for Q40 IDE interfaces | 111 | * Probe for Q40 IDE interfaces |
112 | */ | 112 | */ |
113 | 113 | ||
114 | void __init q40ide_init(void) | 114 | static int __init q40ide_init(void) |
115 | { | 115 | { |
116 | int i; | 116 | int i; |
117 | ide_hwif_t *hwif; | 117 | ide_hwif_t *hwif; |
118 | int index; | ||
119 | const char *name; | 118 | const char *name; |
119 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; | ||
120 | 120 | ||
121 | if (!MACH_IS_Q40) | 121 | if (!MACH_IS_Q40) |
122 | return ; | 122 | return -ENODEV; |
123 | |||
124 | printk(KERN_INFO "ide: Q40 IDE controller\n"); | ||
123 | 125 | ||
124 | for (i = 0; i < Q40IDE_NUM_HWIFS; i++) { | 126 | for (i = 0; i < Q40IDE_NUM_HWIFS; i++) { |
125 | hw_regs_t hw; | 127 | hw_regs_t hw; |
@@ -141,10 +143,20 @@ void __init q40ide_init(void) | |||
141 | 0, NULL, | 143 | 0, NULL, |
142 | // m68kide_iops, | 144 | // m68kide_iops, |
143 | q40ide_default_irq(pcide_bases[i])); | 145 | q40ide_default_irq(pcide_bases[i])); |
144 | index = ide_register_hw(&hw, NULL, 1, &hwif); | 146 | |
145 | // **FIXME** | 147 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); |
146 | if (index != -1) | 148 | if (hwif) { |
149 | ide_init_port_data(hwif, hwif->index); | ||
150 | ide_init_port_hw(hwif, &hw); | ||
147 | hwif->mmio = 1; | 151 | hwif->mmio = 1; |
152 | |||
153 | idx[i] = hwif->index; | ||
154 | } | ||
148 | } | 155 | } |
156 | |||
157 | ide_device_add(idx); | ||
158 | |||
159 | return 0; | ||
149 | } | 160 | } |
150 | 161 | ||
162 | module_init(q40ide_init); | ||
diff --git a/drivers/ide/legacy/qd65xx.c b/drivers/ide/legacy/qd65xx.c index 912e73853faa..2bac4c1a6532 100644 --- a/drivers/ide/legacy/qd65xx.c +++ b/drivers/ide/legacy/qd65xx.c | |||
@@ -478,8 +478,7 @@ int probe_qd65xx = 0; | |||
478 | module_param_named(probe, probe_qd65xx, bool, 0); | 478 | module_param_named(probe, probe_qd65xx, bool, 0); |
479 | MODULE_PARM_DESC(probe, "probe for QD65xx chipsets"); | 479 | MODULE_PARM_DESC(probe, "probe for QD65xx chipsets"); |
480 | 480 | ||
481 | /* Can be called directly from ide.c. */ | 481 | static int __init qd65xx_init(void) |
482 | int __init qd65xx_init(void) | ||
483 | { | 482 | { |
484 | if (probe_qd65xx == 0) | 483 | if (probe_qd65xx == 0) |
485 | return -ENODEV; | 484 | return -ENODEV; |
@@ -492,9 +491,7 @@ int __init qd65xx_init(void) | |||
492 | return 0; | 491 | return 0; |
493 | } | 492 | } |
494 | 493 | ||
495 | #ifdef MODULE | ||
496 | module_init(qd65xx_init); | 494 | module_init(qd65xx_init); |
497 | #endif | ||
498 | 495 | ||
499 | MODULE_AUTHOR("Samuel Thibault"); | 496 | MODULE_AUTHOR("Samuel Thibault"); |
500 | MODULE_DESCRIPTION("support of qd65xx vlb ide chipset"); | 497 | MODULE_DESCRIPTION("support of qd65xx vlb ide chipset"); |
diff --git a/drivers/ide/legacy/umc8672.c b/drivers/ide/legacy/umc8672.c index 79577b916874..a1ae1ae6699d 100644 --- a/drivers/ide/legacy/umc8672.c +++ b/drivers/ide/legacy/umc8672.c | |||
@@ -169,8 +169,7 @@ int probe_umc8672 = 0; | |||
169 | module_param_named(probe, probe_umc8672, bool, 0); | 169 | module_param_named(probe, probe_umc8672, bool, 0); |
170 | MODULE_PARM_DESC(probe, "probe for UMC8672 chipset"); | 170 | MODULE_PARM_DESC(probe, "probe for UMC8672 chipset"); |
171 | 171 | ||
172 | /* Can be called directly from ide.c. */ | 172 | static int __init umc8672_init(void) |
173 | int __init umc8672_init(void) | ||
174 | { | 173 | { |
175 | if (probe_umc8672 == 0) | 174 | if (probe_umc8672 == 0) |
176 | goto out; | 175 | goto out; |
@@ -181,9 +180,7 @@ out: | |||
181 | return -ENODEV;; | 180 | return -ENODEV;; |
182 | } | 181 | } |
183 | 182 | ||
184 | #ifdef MODULE | ||
185 | module_init(umc8672_init); | 183 | module_init(umc8672_init); |
186 | #endif | ||
187 | 184 | ||
188 | MODULE_AUTHOR("Wolfram Podien"); | 185 | MODULE_AUTHOR("Wolfram Podien"); |
189 | MODULE_DESCRIPTION("Support for UMC 8672 IDE chipset"); | 186 | MODULE_DESCRIPTION("Support for UMC 8672 IDE chipset"); |
diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c index a4d0d4ca73d0..2d3e5115b834 100644 --- a/drivers/ide/mips/au1xxx-ide.c +++ b/drivers/ide/mips/au1xxx-ide.c | |||
@@ -395,26 +395,10 @@ static int auide_dma_test_irq(ide_drive_t *drive) | |||
395 | return 0; | 395 | return 0; |
396 | } | 396 | } |
397 | 397 | ||
398 | static void auide_dma_host_on(ide_drive_t *drive) | 398 | static void auide_dma_host_set(ide_drive_t *drive, int on) |
399 | { | 399 | { |
400 | } | 400 | } |
401 | 401 | ||
402 | static int auide_dma_on(ide_drive_t *drive) | ||
403 | { | ||
404 | drive->using_dma = 1; | ||
405 | |||
406 | return 0; | ||
407 | } | ||
408 | |||
409 | static void auide_dma_host_off(ide_drive_t *drive) | ||
410 | { | ||
411 | } | ||
412 | |||
413 | static void auide_dma_off_quietly(ide_drive_t *drive) | ||
414 | { | ||
415 | drive->using_dma = 0; | ||
416 | } | ||
417 | |||
418 | static void auide_dma_lost_irq(ide_drive_t *drive) | 402 | static void auide_dma_lost_irq(ide_drive_t *drive) |
419 | { | 403 | { |
420 | printk(KERN_ERR "%s: IRQ lost\n", drive->name); | 404 | printk(KERN_ERR "%s: IRQ lost\n", drive->name); |
@@ -641,12 +625,13 @@ static int au_ide_probe(struct device *dev) | |||
641 | /* FIXME: This might possibly break PCMCIA IDE devices */ | 625 | /* FIXME: This might possibly break PCMCIA IDE devices */ |
642 | 626 | ||
643 | hwif = &ide_hwifs[pdev->id]; | 627 | hwif = &ide_hwifs[pdev->id]; |
644 | hwif->irq = ahwif->irq; | ||
645 | hwif->chipset = ide_au1xxx; | ||
646 | 628 | ||
647 | memset(&hw, 0, sizeof(hw)); | 629 | memset(&hw, 0, sizeof(hw)); |
648 | auide_setup_ports(&hw, ahwif); | 630 | auide_setup_ports(&hw, ahwif); |
649 | memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports)); | 631 | hw.irq = ahwif->irq; |
632 | hw.chipset = ide_au1xxx; | ||
633 | |||
634 | ide_init_port_hw(hwif, &hw); | ||
650 | 635 | ||
651 | hwif->ultra_mask = 0x0; /* Disable Ultra DMA */ | 636 | hwif->ultra_mask = 0x0; /* Disable Ultra DMA */ |
652 | #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA | 637 | #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA |
@@ -660,7 +645,6 @@ static int au_ide_probe(struct device *dev) | |||
660 | hwif->pio_mask = ATA_PIO4; | 645 | hwif->pio_mask = ATA_PIO4; |
661 | hwif->host_flags = IDE_HFLAG_POST_SET_MODE; | 646 | hwif->host_flags = IDE_HFLAG_POST_SET_MODE; |
662 | 647 | ||
663 | hwif->noprobe = 0; | ||
664 | hwif->drives[0].unmask = 1; | 648 | hwif->drives[0].unmask = 1; |
665 | hwif->drives[1].unmask = 1; | 649 | hwif->drives[1].unmask = 1; |
666 | 650 | ||
@@ -682,29 +666,25 @@ static int au_ide_probe(struct device *dev) | |||
682 | hwif->set_dma_mode = &auide_set_dma_mode; | 666 | hwif->set_dma_mode = &auide_set_dma_mode; |
683 | 667 | ||
684 | #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA | 668 | #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA |
685 | hwif->dma_off_quietly = &auide_dma_off_quietly; | ||
686 | hwif->dma_timeout = &auide_dma_timeout; | 669 | hwif->dma_timeout = &auide_dma_timeout; |
687 | 670 | ||
688 | hwif->mdma_filter = &auide_mdma_filter; | 671 | hwif->mdma_filter = &auide_mdma_filter; |
689 | 672 | ||
673 | hwif->dma_host_set = &auide_dma_host_set; | ||
690 | hwif->dma_exec_cmd = &auide_dma_exec_cmd; | 674 | hwif->dma_exec_cmd = &auide_dma_exec_cmd; |
691 | hwif->dma_start = &auide_dma_start; | 675 | hwif->dma_start = &auide_dma_start; |
692 | hwif->ide_dma_end = &auide_dma_end; | 676 | hwif->ide_dma_end = &auide_dma_end; |
693 | hwif->dma_setup = &auide_dma_setup; | 677 | hwif->dma_setup = &auide_dma_setup; |
694 | hwif->ide_dma_test_irq = &auide_dma_test_irq; | 678 | hwif->ide_dma_test_irq = &auide_dma_test_irq; |
695 | hwif->dma_host_off = &auide_dma_host_off; | ||
696 | hwif->dma_host_on = &auide_dma_host_on; | ||
697 | hwif->dma_lost_irq = &auide_dma_lost_irq; | 679 | hwif->dma_lost_irq = &auide_dma_lost_irq; |
698 | hwif->ide_dma_on = &auide_dma_on; | 680 | #endif |
699 | #else /* !CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */ | ||
700 | hwif->channel = 0; | 681 | hwif->channel = 0; |
701 | hwif->hold = 1; | ||
702 | hwif->select_data = 0; /* no chipset-specific code */ | 682 | hwif->select_data = 0; /* no chipset-specific code */ |
703 | hwif->config_data = 0; /* no chipset-specific code */ | 683 | hwif->config_data = 0; /* no chipset-specific code */ |
704 | 684 | ||
705 | hwif->drives[0].autotune = 1; /* 1=autotune, 2=noautotune, 0=default */ | 685 | hwif->drives[0].autotune = 1; /* 1=autotune, 2=noautotune, 0=default */ |
706 | hwif->drives[1].autotune = 1; | 686 | hwif->drives[1].autotune = 1; |
707 | #endif | 687 | |
708 | hwif->drives[0].no_io_32bit = 1; | 688 | hwif->drives[0].no_io_32bit = 1; |
709 | hwif->drives[1].no_io_32bit = 1; | 689 | hwif->drives[1].no_io_32bit = 1; |
710 | 690 | ||
diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c index 521edd41b572..8b3959dfa2b7 100644 --- a/drivers/ide/mips/swarm.c +++ b/drivers/ide/mips/swarm.c | |||
@@ -117,6 +117,7 @@ static int __devinit swarm_ide_probe(struct device *dev) | |||
117 | default_hwif_mmiops(hwif); | 117 | default_hwif_mmiops(hwif); |
118 | /* Prevent resource map manipulation. */ | 118 | /* Prevent resource map manipulation. */ |
119 | hwif->mmio = 1; | 119 | hwif->mmio = 1; |
120 | hwif->chipset = ide_generic; | ||
120 | hwif->noprobe = 0; | 121 | hwif->noprobe = 0; |
121 | 122 | ||
122 | for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) | 123 | for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) |
diff --git a/drivers/ide/pci/Makefile b/drivers/ide/pci/Makefile index 95d1ea8f1f14..94803253e8af 100644 --- a/drivers/ide/pci/Makefile +++ b/drivers/ide/pci/Makefile | |||
@@ -36,4 +36,8 @@ obj-$(CONFIG_BLK_DEV_VIA82CXXX) += via82cxxx.o | |||
36 | # Must appear at the end of the block | 36 | # Must appear at the end of the block |
37 | obj-$(CONFIG_BLK_DEV_GENERIC) += generic.o | 37 | obj-$(CONFIG_BLK_DEV_GENERIC) += generic.o |
38 | 38 | ||
39 | ifeq ($(CONFIG_BLK_DEV_CMD640), m) | ||
40 | obj-m += cmd640.o | ||
41 | endif | ||
42 | |||
39 | EXTRA_CFLAGS := -Idrivers/ide | 43 | EXTRA_CFLAGS := -Idrivers/ide |
diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c index 5ae26564fb72..491871984aaa 100644 --- a/drivers/ide/pci/atiixp.c +++ b/drivers/ide/pci/atiixp.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/ide/pci/atiixp.c Version 0.03 Aug 3 2007 | 2 | * linux/drivers/ide/pci/atiixp.c Version 0.05 Nov 9 2007 |
3 | * | 3 | * |
4 | * Copyright (C) 2003 ATI Inc. <hyu@ati.com> | 4 | * Copyright (C) 2003 ATI Inc. <hyu@ati.com> |
5 | * Copyright (C) 2004,2007 Bartlomiej Zolnierkiewicz | 5 | * Copyright (C) 2004,2007 Bartlomiej Zolnierkiewicz |
@@ -43,47 +43,8 @@ static atiixp_ide_timing mdma_timing[] = { | |||
43 | { 0x02, 0x00 }, | 43 | { 0x02, 0x00 }, |
44 | }; | 44 | }; |
45 | 45 | ||
46 | static int save_mdma_mode[4]; | ||
47 | |||
48 | static DEFINE_SPINLOCK(atiixp_lock); | 46 | static DEFINE_SPINLOCK(atiixp_lock); |
49 | 47 | ||
50 | static void atiixp_dma_host_on(ide_drive_t *drive) | ||
51 | { | ||
52 | struct pci_dev *dev = drive->hwif->pci_dev; | ||
53 | unsigned long flags; | ||
54 | u16 tmp16; | ||
55 | |||
56 | spin_lock_irqsave(&atiixp_lock, flags); | ||
57 | |||
58 | pci_read_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, &tmp16); | ||
59 | if (save_mdma_mode[drive->dn]) | ||
60 | tmp16 &= ~(1 << drive->dn); | ||
61 | else | ||
62 | tmp16 |= (1 << drive->dn); | ||
63 | pci_write_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, tmp16); | ||
64 | |||
65 | spin_unlock_irqrestore(&atiixp_lock, flags); | ||
66 | |||
67 | ide_dma_host_on(drive); | ||
68 | } | ||
69 | |||
70 | static void atiixp_dma_host_off(ide_drive_t *drive) | ||
71 | { | ||
72 | struct pci_dev *dev = drive->hwif->pci_dev; | ||
73 | unsigned long flags; | ||
74 | u16 tmp16; | ||
75 | |||
76 | spin_lock_irqsave(&atiixp_lock, flags); | ||
77 | |||
78 | pci_read_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, &tmp16); | ||
79 | tmp16 &= ~(1 << drive->dn); | ||
80 | pci_write_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, tmp16); | ||
81 | |||
82 | spin_unlock_irqrestore(&atiixp_lock, flags); | ||
83 | |||
84 | ide_dma_host_off(drive); | ||
85 | } | ||
86 | |||
87 | /** | 48 | /** |
88 | * atiixp_set_pio_mode - set host controller for PIO mode | 49 | * atiixp_set_pio_mode - set host controller for PIO mode |
89 | * @drive: drive | 50 | * @drive: drive |
@@ -132,26 +93,33 @@ static void atiixp_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
132 | int timing_shift = (drive->dn & 2) ? 16 : 0 + (drive->dn & 1) ? 0 : 8; | 93 | int timing_shift = (drive->dn & 2) ? 16 : 0 + (drive->dn & 1) ? 0 : 8; |
133 | u32 tmp32; | 94 | u32 tmp32; |
134 | u16 tmp16; | 95 | u16 tmp16; |
96 | u16 udma_ctl = 0; | ||
135 | 97 | ||
136 | spin_lock_irqsave(&atiixp_lock, flags); | 98 | spin_lock_irqsave(&atiixp_lock, flags); |
137 | 99 | ||
138 | save_mdma_mode[drive->dn] = 0; | 100 | pci_read_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, &udma_ctl); |
101 | |||
139 | if (speed >= XFER_UDMA_0) { | 102 | if (speed >= XFER_UDMA_0) { |
140 | pci_read_config_word(dev, ATIIXP_IDE_UDMA_MODE, &tmp16); | 103 | pci_read_config_word(dev, ATIIXP_IDE_UDMA_MODE, &tmp16); |
141 | tmp16 &= ~(0x07 << (drive->dn * 4)); | 104 | tmp16 &= ~(0x07 << (drive->dn * 4)); |
142 | tmp16 |= ((speed & 0x07) << (drive->dn * 4)); | 105 | tmp16 |= ((speed & 0x07) << (drive->dn * 4)); |
143 | pci_write_config_word(dev, ATIIXP_IDE_UDMA_MODE, tmp16); | 106 | pci_write_config_word(dev, ATIIXP_IDE_UDMA_MODE, tmp16); |
144 | } else { | 107 | |
145 | if ((speed >= XFER_MW_DMA_0) && (speed <= XFER_MW_DMA_2)) { | 108 | udma_ctl |= (1 << drive->dn); |
146 | save_mdma_mode[drive->dn] = speed; | 109 | } else if (speed >= XFER_MW_DMA_0) { |
147 | pci_read_config_dword(dev, ATIIXP_IDE_MDMA_TIMING, &tmp32); | 110 | u8 i = speed & 0x03; |
148 | tmp32 &= ~(0xff << timing_shift); | 111 | |
149 | tmp32 |= (mdma_timing[speed & 0x03].recover_width << timing_shift) | | 112 | pci_read_config_dword(dev, ATIIXP_IDE_MDMA_TIMING, &tmp32); |
150 | (mdma_timing[speed & 0x03].command_width << (timing_shift + 4)); | 113 | tmp32 &= ~(0xff << timing_shift); |
151 | pci_write_config_dword(dev, ATIIXP_IDE_MDMA_TIMING, tmp32); | 114 | tmp32 |= (mdma_timing[i].recover_width << timing_shift) | |
152 | } | 115 | (mdma_timing[i].command_width << (timing_shift + 4)); |
116 | pci_write_config_dword(dev, ATIIXP_IDE_MDMA_TIMING, tmp32); | ||
117 | |||
118 | udma_ctl &= ~(1 << drive->dn); | ||
153 | } | 119 | } |
154 | 120 | ||
121 | pci_write_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, udma_ctl); | ||
122 | |||
155 | spin_unlock_irqrestore(&atiixp_lock, flags); | 123 | spin_unlock_irqrestore(&atiixp_lock, flags); |
156 | } | 124 | } |
157 | 125 | ||
@@ -181,9 +149,6 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif) | |||
181 | hwif->cbl = ATA_CBL_PATA80; | 149 | hwif->cbl = ATA_CBL_PATA80; |
182 | else | 150 | else |
183 | hwif->cbl = ATA_CBL_PATA40; | 151 | hwif->cbl = ATA_CBL_PATA40; |
184 | |||
185 | hwif->dma_host_on = &atiixp_dma_host_on; | ||
186 | hwif->dma_host_off = &atiixp_dma_host_off; | ||
187 | } | 152 | } |
188 | 153 | ||
189 | static const struct ide_port_info atiixp_pci_info[] __devinitdata = { | 154 | static const struct ide_port_info atiixp_pci_info[] __devinitdata = { |
diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c index 4aa48104e0c1..da3565e0071f 100644 --- a/drivers/ide/pci/cmd640.c +++ b/drivers/ide/pci/cmd640.c | |||
@@ -706,9 +706,9 @@ static int pci_conf2(void) | |||
706 | } | 706 | } |
707 | 707 | ||
708 | /* | 708 | /* |
709 | * Probe for a cmd640 chipset, and initialize it if found. Called from ide.c | 709 | * Probe for a cmd640 chipset, and initialize it if found. |
710 | */ | 710 | */ |
711 | int __init ide_probe_for_cmd640x (void) | 711 | static int __init cmd640x_init(void) |
712 | { | 712 | { |
713 | #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED | 713 | #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED |
714 | int second_port_toggled = 0; | 714 | int second_port_toggled = 0; |
@@ -717,6 +717,7 @@ int __init ide_probe_for_cmd640x (void) | |||
717 | const char *bus_type, *port2; | 717 | const char *bus_type, *port2; |
718 | unsigned int index; | 718 | unsigned int index; |
719 | u8 b, cfr; | 719 | u8 b, cfr; |
720 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; | ||
720 | 721 | ||
721 | if (cmd640_vlb && probe_for_cmd640_vlb()) { | 722 | if (cmd640_vlb && probe_for_cmd640_vlb()) { |
722 | bus_type = "VLB"; | 723 | bus_type = "VLB"; |
@@ -769,6 +770,8 @@ int __init ide_probe_for_cmd640x (void) | |||
769 | cmd_hwif0->set_pio_mode = &cmd640_set_pio_mode; | 770 | cmd_hwif0->set_pio_mode = &cmd640_set_pio_mode; |
770 | #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ | 771 | #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ |
771 | 772 | ||
773 | idx[0] = cmd_hwif0->index; | ||
774 | |||
772 | /* | 775 | /* |
773 | * Ensure compatibility by always using the slowest timings | 776 | * Ensure compatibility by always using the slowest timings |
774 | * for access to the drive's command register block, | 777 | * for access to the drive's command register block, |
@@ -826,6 +829,8 @@ int __init ide_probe_for_cmd640x (void) | |||
826 | cmd_hwif1->pio_mask = ATA_PIO5; | 829 | cmd_hwif1->pio_mask = ATA_PIO5; |
827 | cmd_hwif1->set_pio_mode = &cmd640_set_pio_mode; | 830 | cmd_hwif1->set_pio_mode = &cmd640_set_pio_mode; |
828 | #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ | 831 | #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ |
832 | |||
833 | idx[1] = cmd_hwif1->index; | ||
829 | } | 834 | } |
830 | printk(KERN_INFO "%s: %sserialized, secondary interface %s\n", cmd_hwif1->name, | 835 | printk(KERN_INFO "%s: %sserialized, secondary interface %s\n", cmd_hwif1->name, |
831 | cmd_hwif0->serialized ? "" : "not ", port2); | 836 | cmd_hwif0->serialized ? "" : "not ", port2); |
@@ -872,6 +877,13 @@ int __init ide_probe_for_cmd640x (void) | |||
872 | #ifdef CMD640_DUMP_REGS | 877 | #ifdef CMD640_DUMP_REGS |
873 | cmd640_dump_regs(); | 878 | cmd640_dump_regs(); |
874 | #endif | 879 | #endif |
880 | |||
881 | ide_device_add(idx); | ||
882 | |||
875 | return 1; | 883 | return 1; |
876 | } | 884 | } |
877 | 885 | ||
886 | module_param_named(probe_vlb, cmd640_vlb, bool, 0); | ||
887 | MODULE_PARM_DESC(probe_vlb, "probe for VLB version of CMD640 chipset"); | ||
888 | |||
889 | module_init(cmd640x_init); | ||
diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c index 0b1e9479f019..cd4eb9def151 100644 --- a/drivers/ide/pci/cmd64x.c +++ b/drivers/ide/pci/cmd64x.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/ide/pci/cmd64x.c Version 1.52 Dec 24, 2007 | 2 | * linux/drivers/ide/pci/cmd64x.c Version 1.53 Dec 24, 2007 |
3 | * | 3 | * |
4 | * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines. | 4 | * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines. |
5 | * Due to massive hardware bugs, UltraDMA is only supported | 5 | * Due to massive hardware bugs, UltraDMA is only supported |
@@ -22,8 +22,6 @@ | |||
22 | 22 | ||
23 | #include <asm/io.h> | 23 | #include <asm/io.h> |
24 | 24 | ||
25 | #define DISPLAY_CMD64X_TIMINGS | ||
26 | |||
27 | #define CMD_DEBUG 0 | 25 | #define CMD_DEBUG 0 |
28 | 26 | ||
29 | #if CMD_DEBUG | 27 | #if CMD_DEBUG |
@@ -37,11 +35,6 @@ | |||
37 | */ | 35 | */ |
38 | #define CFR 0x50 | 36 | #define CFR 0x50 |
39 | #define CFR_INTR_CH0 0x04 | 37 | #define CFR_INTR_CH0 0x04 |
40 | #define CNTRL 0x51 | ||
41 | #define CNTRL_ENA_1ST 0x04 | ||
42 | #define CNTRL_ENA_2ND 0x08 | ||
43 | #define CNTRL_DIS_RA0 0x40 | ||
44 | #define CNTRL_DIS_RA1 0x80 | ||
45 | 38 | ||
46 | #define CMDTIM 0x52 | 39 | #define CMDTIM 0x52 |
47 | #define ARTTIM0 0x53 | 40 | #define ARTTIM0 0x53 |
@@ -60,108 +53,13 @@ | |||
60 | #define MRDMODE 0x71 | 53 | #define MRDMODE 0x71 |
61 | #define MRDMODE_INTR_CH0 0x04 | 54 | #define MRDMODE_INTR_CH0 0x04 |
62 | #define MRDMODE_INTR_CH1 0x08 | 55 | #define MRDMODE_INTR_CH1 0x08 |
63 | #define MRDMODE_BLK_CH0 0x10 | ||
64 | #define MRDMODE_BLK_CH1 0x20 | ||
65 | #define BMIDESR0 0x72 | ||
66 | #define UDIDETCR0 0x73 | 56 | #define UDIDETCR0 0x73 |
67 | #define DTPR0 0x74 | 57 | #define DTPR0 0x74 |
68 | #define BMIDECR1 0x78 | 58 | #define BMIDECR1 0x78 |
69 | #define BMIDECSR 0x79 | 59 | #define BMIDECSR 0x79 |
70 | #define BMIDESR1 0x7A | ||
71 | #define UDIDETCR1 0x7B | 60 | #define UDIDETCR1 0x7B |
72 | #define DTPR1 0x7C | 61 | #define DTPR1 0x7C |
73 | 62 | ||
74 | #if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_IDE_PROC_FS) | ||
75 | #include <linux/stat.h> | ||
76 | #include <linux/proc_fs.h> | ||
77 | |||
78 | static u8 cmd64x_proc = 0; | ||
79 | |||
80 | #define CMD_MAX_DEVS 5 | ||
81 | |||
82 | static struct pci_dev *cmd_devs[CMD_MAX_DEVS]; | ||
83 | static int n_cmd_devs; | ||
84 | |||
85 | static char * print_cmd64x_get_info (char *buf, struct pci_dev *dev, int index) | ||
86 | { | ||
87 | char *p = buf; | ||
88 | u8 reg72 = 0, reg73 = 0; /* primary */ | ||
89 | u8 reg7a = 0, reg7b = 0; /* secondary */ | ||
90 | u8 reg50 = 1, reg51 = 1, reg57 = 0, reg71 = 0; /* extra */ | ||
91 | |||
92 | p += sprintf(p, "\nController: %d\n", index); | ||
93 | p += sprintf(p, "PCI-%x Chipset.\n", dev->device); | ||
94 | |||
95 | (void) pci_read_config_byte(dev, CFR, ®50); | ||
96 | (void) pci_read_config_byte(dev, CNTRL, ®51); | ||
97 | (void) pci_read_config_byte(dev, ARTTIM23, ®57); | ||
98 | (void) pci_read_config_byte(dev, MRDMODE, ®71); | ||
99 | (void) pci_read_config_byte(dev, BMIDESR0, ®72); | ||
100 | (void) pci_read_config_byte(dev, UDIDETCR0, ®73); | ||
101 | (void) pci_read_config_byte(dev, BMIDESR1, ®7a); | ||
102 | (void) pci_read_config_byte(dev, UDIDETCR1, ®7b); | ||
103 | |||
104 | /* PCI0643/6 originally didn't have the primary channel enable bit */ | ||
105 | if ((dev->device == PCI_DEVICE_ID_CMD_643) || | ||
106 | (dev->device == PCI_DEVICE_ID_CMD_646 && dev->revision < 3)) | ||
107 | reg51 |= CNTRL_ENA_1ST; | ||
108 | |||
109 | p += sprintf(p, "---------------- Primary Channel " | ||
110 | "---------------- Secondary Channel ------------\n"); | ||
111 | p += sprintf(p, " %s %s\n", | ||
112 | (reg51 & CNTRL_ENA_1ST) ? "enabled " : "disabled", | ||
113 | (reg51 & CNTRL_ENA_2ND) ? "enabled " : "disabled"); | ||
114 | p += sprintf(p, "---------------- drive0 --------- drive1 " | ||
115 | "-------- drive0 --------- drive1 ------\n"); | ||
116 | p += sprintf(p, "DMA enabled: %s %s" | ||
117 | " %s %s\n", | ||
118 | (reg72 & 0x20) ? "yes" : "no ", (reg72 & 0x40) ? "yes" : "no ", | ||
119 | (reg7a & 0x20) ? "yes" : "no ", (reg7a & 0x40) ? "yes" : "no "); | ||
120 | p += sprintf(p, "UltraDMA mode: %s (%c) %s (%c)", | ||
121 | ( reg73 & 0x01) ? " on" : "off", | ||
122 | ((reg73 & 0x30) == 0x30) ? ((reg73 & 0x04) ? '3' : '0') : | ||
123 | ((reg73 & 0x30) == 0x20) ? ((reg73 & 0x04) ? '3' : '1') : | ||
124 | ((reg73 & 0x30) == 0x10) ? ((reg73 & 0x04) ? '4' : '2') : | ||
125 | ((reg73 & 0x30) == 0x00) ? ((reg73 & 0x04) ? '5' : '2') : '?', | ||
126 | ( reg73 & 0x02) ? " on" : "off", | ||
127 | ((reg73 & 0xC0) == 0xC0) ? ((reg73 & 0x08) ? '3' : '0') : | ||
128 | ((reg73 & 0xC0) == 0x80) ? ((reg73 & 0x08) ? '3' : '1') : | ||
129 | ((reg73 & 0xC0) == 0x40) ? ((reg73 & 0x08) ? '4' : '2') : | ||
130 | ((reg73 & 0xC0) == 0x00) ? ((reg73 & 0x08) ? '5' : '2') : '?'); | ||
131 | p += sprintf(p, " %s (%c) %s (%c)\n", | ||
132 | ( reg7b & 0x01) ? " on" : "off", | ||
133 | ((reg7b & 0x30) == 0x30) ? ((reg7b & 0x04) ? '3' : '0') : | ||
134 | ((reg7b & 0x30) == 0x20) ? ((reg7b & 0x04) ? '3' : '1') : | ||
135 | ((reg7b & 0x30) == 0x10) ? ((reg7b & 0x04) ? '4' : '2') : | ||
136 | ((reg7b & 0x30) == 0x00) ? ((reg7b & 0x04) ? '5' : '2') : '?', | ||
137 | ( reg7b & 0x02) ? " on" : "off", | ||
138 | ((reg7b & 0xC0) == 0xC0) ? ((reg7b & 0x08) ? '3' : '0') : | ||
139 | ((reg7b & 0xC0) == 0x80) ? ((reg7b & 0x08) ? '3' : '1') : | ||
140 | ((reg7b & 0xC0) == 0x40) ? ((reg7b & 0x08) ? '4' : '2') : | ||
141 | ((reg7b & 0xC0) == 0x00) ? ((reg7b & 0x08) ? '5' : '2') : '?'); | ||
142 | p += sprintf(p, "Interrupt: %s, %s %s, %s\n", | ||
143 | (reg71 & MRDMODE_BLK_CH0 ) ? "blocked" : "enabled", | ||
144 | (reg50 & CFR_INTR_CH0 ) ? "pending" : "clear ", | ||
145 | (reg71 & MRDMODE_BLK_CH1 ) ? "blocked" : "enabled", | ||
146 | (reg57 & ARTTIM23_INTR_CH1) ? "pending" : "clear "); | ||
147 | |||
148 | return (char *)p; | ||
149 | } | ||
150 | |||
151 | static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count) | ||
152 | { | ||
153 | char *p = buffer; | ||
154 | int i; | ||
155 | |||
156 | for (i = 0; i < n_cmd_devs; i++) { | ||
157 | struct pci_dev *dev = cmd_devs[i]; | ||
158 | p = print_cmd64x_get_info(p, dev, i); | ||
159 | } | ||
160 | return p-buffer; /* => must be less than 4k! */ | ||
161 | } | ||
162 | |||
163 | #endif /* defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_IDE_PROC_FS) */ | ||
164 | |||
165 | static u8 quantize_timing(int timing, int quant) | 63 | static u8 quantize_timing(int timing, int quant) |
166 | { | 64 | { |
167 | return (timing + quant - 1) / quant; | 65 | return (timing + quant - 1) / quant; |
@@ -472,16 +370,6 @@ static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const cha | |||
472 | mrdmode &= ~0x30; | 370 | mrdmode &= ~0x30; |
473 | (void) pci_write_config_byte(dev, MRDMODE, (mrdmode | 0x02)); | 371 | (void) pci_write_config_byte(dev, MRDMODE, (mrdmode | 0x02)); |
474 | 372 | ||
475 | #if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_IDE_PROC_FS) | ||
476 | |||
477 | cmd_devs[n_cmd_devs++] = dev; | ||
478 | |||
479 | if (!cmd64x_proc) { | ||
480 | cmd64x_proc = 1; | ||
481 | ide_pci_create_host_proc("cmd64x", cmd64x_get_info); | ||
482 | } | ||
483 | #endif /* DISPLAY_CMD64X_TIMINGS && CONFIG_IDE_PROC_FS */ | ||
484 | |||
485 | return 0; | 373 | return 0; |
486 | } | 374 | } |
487 | 375 | ||
diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c index d1a91bcb5b29..6ec00b8d7ec1 100644 --- a/drivers/ide/pci/cs5520.c +++ b/drivers/ide/pci/cs5520.c | |||
@@ -71,7 +71,6 @@ static void cs5520_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
71 | ide_hwif_t *hwif = HWIF(drive); | 71 | ide_hwif_t *hwif = HWIF(drive); |
72 | struct pci_dev *pdev = hwif->pci_dev; | 72 | struct pci_dev *pdev = hwif->pci_dev; |
73 | int controller = drive->dn > 1 ? 1 : 0; | 73 | int controller = drive->dn > 1 ? 1 : 0; |
74 | u8 reg; | ||
75 | 74 | ||
76 | /* FIXME: if DMA = 1 do we need to set the DMA bit here ? */ | 75 | /* FIXME: if DMA = 1 do we need to set the DMA bit here ? */ |
77 | 76 | ||
@@ -91,11 +90,6 @@ static void cs5520_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
91 | pci_write_config_byte(pdev, 0x66 + 4*controller + (drive->dn&1), | 90 | pci_write_config_byte(pdev, 0x66 + 4*controller + (drive->dn&1), |
92 | (cs5520_pio_clocks[pio].recovery << 4) | | 91 | (cs5520_pio_clocks[pio].recovery << 4) | |
93 | (cs5520_pio_clocks[pio].assert)); | 92 | (cs5520_pio_clocks[pio].assert)); |
94 | |||
95 | /* Set the DMA enable/disable flag */ | ||
96 | reg = inb(hwif->dma_base + 0x02 + 8*controller); | ||
97 | reg |= 1<<((drive->dn&1)+5); | ||
98 | outb(reg, hwif->dma_base + 0x02 + 8*controller); | ||
99 | } | 93 | } |
100 | 94 | ||
101 | static void cs5520_set_dma_mode(ide_drive_t *drive, const u8 speed) | 95 | static void cs5520_set_dma_mode(ide_drive_t *drive, const u8 speed) |
@@ -109,13 +103,14 @@ static void cs5520_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
109 | * We wrap the DMA activate to set the vdma flag. This is needed | 103 | * We wrap the DMA activate to set the vdma flag. This is needed |
110 | * so that the IDE DMA layer issues PIO not DMA commands over the | 104 | * so that the IDE DMA layer issues PIO not DMA commands over the |
111 | * DMA channel | 105 | * DMA channel |
106 | * | ||
107 | * ATAPI is harder so disable it for now using IDE_HFLAG_NO_ATAPI_DMA | ||
112 | */ | 108 | */ |
113 | 109 | ||
114 | static int cs5520_dma_on(ide_drive_t *drive) | 110 | static void cs5520_dma_host_set(ide_drive_t *drive, int on) |
115 | { | 111 | { |
116 | /* ATAPI is harder so leave it for now */ | 112 | drive->vdma = on; |
117 | drive->vdma = 1; | 113 | ide_dma_host_set(drive, on); |
118 | return 0; | ||
119 | } | 114 | } |
120 | 115 | ||
121 | static void __devinit init_hwif_cs5520(ide_hwif_t *hwif) | 116 | static void __devinit init_hwif_cs5520(ide_hwif_t *hwif) |
@@ -126,7 +121,7 @@ static void __devinit init_hwif_cs5520(ide_hwif_t *hwif) | |||
126 | if (hwif->dma_base == 0) | 121 | if (hwif->dma_base == 0) |
127 | return; | 122 | return; |
128 | 123 | ||
129 | hwif->ide_dma_on = &cs5520_dma_on; | 124 | hwif->dma_host_set = &cs5520_dma_host_set; |
130 | } | 125 | } |
131 | 126 | ||
132 | #define DECLARE_CS_DEV(name_str) \ | 127 | #define DECLARE_CS_DEV(name_str) \ |
diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c index 1cd4e9cb0521..3ec4c659a37d 100644 --- a/drivers/ide/pci/cy82c693.c +++ b/drivers/ide/pci/cy82c693.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/ide/pci/cy82c693.c Version 0.42 Oct 23, 2007 | 2 | * linux/drivers/ide/pci/cy82c693.c Version 0.44 Nov 8, 2007 |
3 | * | 3 | * |
4 | * Copyright (C) 1998-2000 Andreas S. Krebs (akrebs@altavista.net), Maintainer | 4 | * Copyright (C) 1998-2000 Andreas S. Krebs (akrebs@altavista.net), Maintainer |
5 | * Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>, Integrator | 5 | * Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>, Integrator |
@@ -176,17 +176,12 @@ static void compute_clocks (u8 pio, pio_clocks_t *p_pclk) | |||
176 | * set DMA mode a specific channel for CY82C693 | 176 | * set DMA mode a specific channel for CY82C693 |
177 | */ | 177 | */ |
178 | 178 | ||
179 | static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single) | 179 | static void cy82c693_set_dma_mode(ide_drive_t *drive, const u8 mode) |
180 | { | 180 | { |
181 | u8 index = 0, data = 0; | 181 | ide_hwif_t *hwif = drive->hwif; |
182 | u8 single = (mode & 0x10) >> 4, index = 0, data = 0; | ||
182 | 183 | ||
183 | if (mode>2) /* make sure we set a valid mode */ | 184 | index = hwif->channel ? CY82_INDEX_CHANNEL1 : CY82_INDEX_CHANNEL0; |
184 | mode = 2; | ||
185 | |||
186 | if (mode > drive->id->tDMA) /* to be absolutly sure we have a valid mode */ | ||
187 | mode = drive->id->tDMA; | ||
188 | |||
189 | index = (HWIF(drive)->channel==0) ? CY82_INDEX_CHANNEL0 : CY82_INDEX_CHANNEL1; | ||
190 | 185 | ||
191 | #if CY82C693_DEBUG_LOGS | 186 | #if CY82C693_DEBUG_LOGS |
192 | /* for debug let's show the previous values */ | 187 | /* for debug let's show the previous values */ |
@@ -199,7 +194,7 @@ static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single) | |||
199 | (data&0x3), ((data>>2)&1)); | 194 | (data&0x3), ((data>>2)&1)); |
200 | #endif /* CY82C693_DEBUG_LOGS */ | 195 | #endif /* CY82C693_DEBUG_LOGS */ |
201 | 196 | ||
202 | data = (u8)mode|(u8)(single<<2); | 197 | data = (mode & 3) | (single << 2); |
203 | 198 | ||
204 | outb(index, CY82_INDEX_PORT); | 199 | outb(index, CY82_INDEX_PORT); |
205 | outb(data, CY82_DATA_PORT); | 200 | outb(data, CY82_DATA_PORT); |
@@ -207,7 +202,7 @@ static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single) | |||
207 | #if CY82C693_DEBUG_INFO | 202 | #if CY82C693_DEBUG_INFO |
208 | printk(KERN_INFO "%s (ch=%d, dev=%d): set DMA mode to %d (single=%d)\n", | 203 | printk(KERN_INFO "%s (ch=%d, dev=%d): set DMA mode to %d (single=%d)\n", |
209 | drive->name, HWIF(drive)->channel, drive->select.b.unit, | 204 | drive->name, HWIF(drive)->channel, drive->select.b.unit, |
210 | mode, single); | 205 | mode & 3, single); |
211 | #endif /* CY82C693_DEBUG_INFO */ | 206 | #endif /* CY82C693_DEBUG_INFO */ |
212 | 207 | ||
213 | /* | 208 | /* |
@@ -230,39 +225,6 @@ static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single) | |||
230 | #endif /* CY82C693_DEBUG_INFO */ | 225 | #endif /* CY82C693_DEBUG_INFO */ |
231 | } | 226 | } |
232 | 227 | ||
233 | /* | ||
234 | * used to set DMA mode for CY82C693 (single and multi modes) | ||
235 | */ | ||
236 | static int cy82c693_ide_dma_on (ide_drive_t *drive) | ||
237 | { | ||
238 | struct hd_driveid *id = drive->id; | ||
239 | |||
240 | #if CY82C693_DEBUG_INFO | ||
241 | printk (KERN_INFO "dma_on: %s\n", drive->name); | ||
242 | #endif /* CY82C693_DEBUG_INFO */ | ||
243 | |||
244 | if (id != NULL) { | ||
245 | /* Enable DMA on any drive that has DMA | ||
246 | * (multi or single) enabled | ||
247 | */ | ||
248 | if (id->field_valid & 2) { /* regular DMA */ | ||
249 | int mmode, smode; | ||
250 | |||
251 | mmode = id->dma_mword & (id->dma_mword >> 8); | ||
252 | smode = id->dma_1word & (id->dma_1word >> 8); | ||
253 | |||
254 | if (mmode != 0) { | ||
255 | /* enable multi */ | ||
256 | cy82c693_dma_enable(drive, (mmode >> 1), 0); | ||
257 | } else if (smode != 0) { | ||
258 | /* enable single */ | ||
259 | cy82c693_dma_enable(drive, (smode >> 1), 1); | ||
260 | } | ||
261 | } | ||
262 | } | ||
263 | return __ide_dma_on(drive); | ||
264 | } | ||
265 | |||
266 | static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio) | 228 | static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio) |
267 | { | 229 | { |
268 | ide_hwif_t *hwif = HWIF(drive); | 230 | ide_hwif_t *hwif = HWIF(drive); |
@@ -429,11 +391,7 @@ static unsigned int __devinit init_chipset_cy82c693(struct pci_dev *dev, const c | |||
429 | static void __devinit init_hwif_cy82c693(ide_hwif_t *hwif) | 391 | static void __devinit init_hwif_cy82c693(ide_hwif_t *hwif) |
430 | { | 392 | { |
431 | hwif->set_pio_mode = &cy82c693_set_pio_mode; | 393 | hwif->set_pio_mode = &cy82c693_set_pio_mode; |
432 | 394 | hwif->set_dma_mode = &cy82c693_set_dma_mode; | |
433 | if (hwif->dma_base == 0) | ||
434 | return; | ||
435 | |||
436 | hwif->ide_dma_on = &cy82c693_ide_dma_on; | ||
437 | } | 395 | } |
438 | 396 | ||
439 | static void __devinit init_iops_cy82c693(ide_hwif_t *hwif) | 397 | static void __devinit init_iops_cy82c693(ide_hwif_t *hwif) |
@@ -454,11 +412,11 @@ static const struct ide_port_info cy82c693_chipset __devinitdata = { | |||
454 | .init_iops = init_iops_cy82c693, | 412 | .init_iops = init_iops_cy82c693, |
455 | .init_hwif = init_hwif_cy82c693, | 413 | .init_hwif = init_hwif_cy82c693, |
456 | .chipset = ide_cy82c693, | 414 | .chipset = ide_cy82c693, |
457 | .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_TRUST_BIOS_FOR_DMA | | 415 | .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_CY82C693 | |
458 | IDE_HFLAG_BOOTABLE, | 416 | IDE_HFLAG_BOOTABLE, |
459 | .pio_mask = ATA_PIO4, | 417 | .pio_mask = ATA_PIO4, |
460 | .swdma_mask = ATA_SWDMA2_ONLY, | 418 | .swdma_mask = ATA_SWDMA2, |
461 | .mwdma_mask = ATA_MWDMA2_ONLY, | 419 | .mwdma_mask = ATA_MWDMA2, |
462 | }; | 420 | }; |
463 | 421 | ||
464 | static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_device_id *id) | 422 | static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_device_id *id) |
diff --git a/drivers/ide/pci/delkin_cb.c b/drivers/ide/pci/delkin_cb.c index 83829081640a..26aa492071bb 100644 --- a/drivers/ide/pci/delkin_cb.c +++ b/drivers/ide/pci/delkin_cb.c | |||
@@ -80,7 +80,7 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id) | |||
80 | hw.irq = dev->irq; | 80 | hw.irq = dev->irq; |
81 | hw.chipset = ide_pci; /* this enables IRQ sharing */ | 81 | hw.chipset = ide_pci; /* this enables IRQ sharing */ |
82 | 82 | ||
83 | rc = ide_register_hw(&hw, &ide_undecoded_slave, 0, &hwif); | 83 | rc = ide_register_hw(&hw, &ide_undecoded_slave, &hwif); |
84 | if (rc < 0) { | 84 | if (rc < 0) { |
85 | printk(KERN_ERR "delkin_cb: ide_register_hw failed (%d)\n", rc); | 85 | printk(KERN_ERR "delkin_cb: ide_register_hw failed (%d)\n", rc); |
86 | pci_disable_device(dev); | 86 | pci_disable_device(dev); |
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index 3777fb8c8043..12685939a813 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c | |||
@@ -725,15 +725,18 @@ static void hpt3xx_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
725 | hpt3xx_set_mode(drive, XFER_PIO_0 + pio); | 725 | hpt3xx_set_mode(drive, XFER_PIO_0 + pio); |
726 | } | 726 | } |
727 | 727 | ||
728 | static int hpt3xx_quirkproc(ide_drive_t *drive) | 728 | static void hpt3xx_quirkproc(ide_drive_t *drive) |
729 | { | 729 | { |
730 | struct hd_driveid *id = drive->id; | 730 | struct hd_driveid *id = drive->id; |
731 | const char **list = quirk_drives; | 731 | const char **list = quirk_drives; |
732 | 732 | ||
733 | while (*list) | 733 | while (*list) |
734 | if (strstr(id->model, *list++)) | 734 | if (strstr(id->model, *list++)) { |
735 | return 1; | 735 | drive->quirk_list = 1; |
736 | return 0; | 736 | return; |
737 | } | ||
738 | |||
739 | drive->quirk_list = 0; | ||
737 | } | 740 | } |
738 | 741 | ||
739 | static void hpt3xx_maskproc(ide_drive_t *drive, int mask) | 742 | static void hpt3xx_maskproc(ide_drive_t *drive, int mask) |
diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c index 99b7d763b6c7..e610a5340fdc 100644 --- a/drivers/ide/pci/it821x.c +++ b/drivers/ide/pci/it821x.c | |||
@@ -431,33 +431,29 @@ static u8 __devinit ata66_it821x(ide_hwif_t *hwif) | |||
431 | } | 431 | } |
432 | 432 | ||
433 | /** | 433 | /** |
434 | * it821x_fixup - post init callback | 434 | * it821x_quirkproc - post init callback |
435 | * @hwif: interface | 435 | * @drive: drive |
436 | * | 436 | * |
437 | * This callback is run after the drives have been probed but | 437 | * This callback is run after the drive has been probed but |
438 | * before anything gets attached. It allows drivers to do any | 438 | * before anything gets attached. It allows drivers to do any |
439 | * final tuning that is needed, or fixups to work around bugs. | 439 | * final tuning that is needed, or fixups to work around bugs. |
440 | */ | 440 | */ |
441 | 441 | ||
442 | static void __devinit it821x_fixups(ide_hwif_t *hwif) | 442 | static void __devinit it821x_quirkproc(ide_drive_t *drive) |
443 | { | 443 | { |
444 | struct it821x_dev *itdev = ide_get_hwifdata(hwif); | 444 | struct it821x_dev *itdev = ide_get_hwifdata(drive->hwif); |
445 | int i; | 445 | struct hd_driveid *id = drive->id; |
446 | u16 *idbits = (u16 *)drive->id; | ||
446 | 447 | ||
447 | if(!itdev->smart) { | 448 | if (!itdev->smart) { |
448 | /* | 449 | /* |
449 | * If we are in pass through mode then not much | 450 | * If we are in pass through mode then not much |
450 | * needs to be done, but we do bother to clear the | 451 | * needs to be done, but we do bother to clear the |
451 | * IRQ mask as we may well be in PIO (eg rev 0x10) | 452 | * IRQ mask as we may well be in PIO (eg rev 0x10) |
452 | * for now and we know unmasking is safe on this chipset. | 453 | * for now and we know unmasking is safe on this chipset. |
453 | */ | 454 | */ |
454 | for (i = 0; i < 2; i++) { | 455 | drive->unmask = 1; |
455 | ide_drive_t *drive = &hwif->drives[i]; | 456 | } else { |
456 | if(drive->present) | ||
457 | drive->unmask = 1; | ||
458 | } | ||
459 | return; | ||
460 | } | ||
461 | /* | 457 | /* |
462 | * Perform fixups on smart mode. We need to "lose" some | 458 | * Perform fixups on smart mode. We need to "lose" some |
463 | * capabilities the firmware lacks but does not filter, and | 459 | * capabilities the firmware lacks but does not filter, and |
@@ -465,16 +461,6 @@ static void __devinit it821x_fixups(ide_hwif_t *hwif) | |||
465 | * in RAID mode. | 461 | * in RAID mode. |
466 | */ | 462 | */ |
467 | 463 | ||
468 | for(i = 0; i < 2; i++) { | ||
469 | ide_drive_t *drive = &hwif->drives[i]; | ||
470 | struct hd_driveid *id; | ||
471 | u16 *idbits; | ||
472 | |||
473 | if(!drive->present) | ||
474 | continue; | ||
475 | id = drive->id; | ||
476 | idbits = (u16 *)drive->id; | ||
477 | |||
478 | /* Check for RAID v native */ | 464 | /* Check for RAID v native */ |
479 | if(strstr(id->model, "Integrated Technology Express")) { | 465 | if(strstr(id->model, "Integrated Technology Express")) { |
480 | /* In raid mode the ident block is slightly buggy | 466 | /* In raid mode the ident block is slightly buggy |
@@ -537,6 +523,8 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif) | |||
537 | struct it821x_dev *idev = kzalloc(sizeof(struct it821x_dev), GFP_KERNEL); | 523 | struct it821x_dev *idev = kzalloc(sizeof(struct it821x_dev), GFP_KERNEL); |
538 | u8 conf; | 524 | u8 conf; |
539 | 525 | ||
526 | hwif->quirkproc = &it821x_quirkproc; | ||
527 | |||
540 | if (idev == NULL) { | 528 | if (idev == NULL) { |
541 | printk(KERN_ERR "it821x: out of memory, falling back to legacy behaviour.\n"); | 529 | printk(KERN_ERR "it821x: out of memory, falling back to legacy behaviour.\n"); |
542 | return; | 530 | return; |
@@ -633,7 +621,6 @@ static unsigned int __devinit init_chipset_it821x(struct pci_dev *dev, const cha | |||
633 | .name = name_str, \ | 621 | .name = name_str, \ |
634 | .init_chipset = init_chipset_it821x, \ | 622 | .init_chipset = init_chipset_it821x, \ |
635 | .init_hwif = init_hwif_it821x, \ | 623 | .init_hwif = init_hwif_it821x, \ |
636 | .fixup = it821x_fixups, \ | ||
637 | .host_flags = IDE_HFLAG_BOOTABLE, \ | 624 | .host_flags = IDE_HFLAG_BOOTABLE, \ |
638 | .pio_mask = ATA_PIO4, \ | 625 | .pio_mask = ATA_PIO4, \ |
639 | } | 626 | } |
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c index ef4a99b99d1f..89d2363a1ebd 100644 --- a/drivers/ide/pci/pdc202xx_new.c +++ b/drivers/ide/pci/pdc202xx_new.c | |||
@@ -203,14 +203,17 @@ static u8 pdcnew_cable_detect(ide_hwif_t *hwif) | |||
203 | return ATA_CBL_PATA80; | 203 | return ATA_CBL_PATA80; |
204 | } | 204 | } |
205 | 205 | ||
206 | static int pdcnew_quirkproc(ide_drive_t *drive) | 206 | static void pdcnew_quirkproc(ide_drive_t *drive) |
207 | { | 207 | { |
208 | const char **list, *model = drive->id->model; | 208 | const char **list, *model = drive->id->model; |
209 | 209 | ||
210 | for (list = pdc_quirk_drives; *list != NULL; list++) | 210 | for (list = pdc_quirk_drives; *list != NULL; list++) |
211 | if (strstr(model, *list) != NULL) | 211 | if (strstr(model, *list) != NULL) { |
212 | return 2; | 212 | drive->quirk_list = 2; |
213 | return 0; | 213 | return; |
214 | } | ||
215 | |||
216 | drive->quirk_list = 0; | ||
214 | } | 217 | } |
215 | 218 | ||
216 | static void pdcnew_reset(ide_drive_t *drive) | 219 | static void pdcnew_reset(ide_drive_t *drive) |
diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c index 67b2781e2213..3a1e081fe390 100644 --- a/drivers/ide/pci/pdc202xx_old.c +++ b/drivers/ide/pci/pdc202xx_old.c | |||
@@ -176,14 +176,17 @@ static void pdc_old_disable_66MHz_clock(ide_hwif_t *hwif) | |||
176 | outb(clock & ~(hwif->channel ? 0x08 : 0x02), clock_reg); | 176 | outb(clock & ~(hwif->channel ? 0x08 : 0x02), clock_reg); |
177 | } | 177 | } |
178 | 178 | ||
179 | static int pdc202xx_quirkproc (ide_drive_t *drive) | 179 | static void pdc202xx_quirkproc(ide_drive_t *drive) |
180 | { | 180 | { |
181 | const char **list, *model = drive->id->model; | 181 | const char **list, *model = drive->id->model; |
182 | 182 | ||
183 | for (list = pdc_quirk_drives; *list != NULL; list++) | 183 | for (list = pdc_quirk_drives; *list != NULL; list++) |
184 | if (strstr(model, *list) != NULL) | 184 | if (strstr(model, *list) != NULL) { |
185 | return 2; | 185 | drive->quirk_list = 2; |
186 | return 0; | 186 | return; |
187 | } | ||
188 | |||
189 | drive->quirk_list = 0; | ||
187 | } | 190 | } |
188 | 191 | ||
189 | static void pdc202xx_old_ide_dma_start(ide_drive_t *drive) | 192 | static void pdc202xx_old_ide_dma_start(ide_drive_t *drive) |
diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c index fef20bd4aa78..32fdf53379f5 100644 --- a/drivers/ide/pci/sc1200.c +++ b/drivers/ide/pci/sc1200.c | |||
@@ -220,9 +220,9 @@ static void sc1200_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
220 | } | 220 | } |
221 | if (mode != -1) { | 221 | if (mode != -1) { |
222 | printk("SC1200: %s: changing (U)DMA mode\n", drive->name); | 222 | printk("SC1200: %s: changing (U)DMA mode\n", drive->name); |
223 | hwif->dma_off_quietly(drive); | 223 | ide_dma_off_quietly(drive); |
224 | if (ide_set_dma_mode(drive, mode) == 0) | 224 | if (ide_set_dma_mode(drive, mode) == 0 && drive->using_dma) |
225 | hwif->dma_host_on(drive); | 225 | hwif->dma_host_set(drive, 1); |
226 | return; | 226 | return; |
227 | } | 227 | } |
228 | 228 | ||
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c index e9bd269547bb..877c09bf4829 100644 --- a/drivers/ide/pci/serverworks.c +++ b/drivers/ide/pci/serverworks.c | |||
@@ -164,25 +164,12 @@ static void svwks_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
164 | ultra_timing &= ~(0x0F << (4*unit)); | 164 | ultra_timing &= ~(0x0F << (4*unit)); |
165 | ultra_enable &= ~(0x01 << drive->dn); | 165 | ultra_enable &= ~(0x01 << drive->dn); |
166 | 166 | ||
167 | switch(speed) { | 167 | if (speed >= XFER_UDMA_0) { |
168 | case XFER_MW_DMA_2: | 168 | dma_timing |= dma_modes[2]; |
169 | case XFER_MW_DMA_1: | 169 | ultra_timing |= (udma_modes[speed - XFER_UDMA_0] << (4 * unit)); |
170 | case XFER_MW_DMA_0: | 170 | ultra_enable |= (0x01 << drive->dn); |
171 | dma_timing |= dma_modes[speed - XFER_MW_DMA_0]; | 171 | } else if (speed >= XFER_MW_DMA_0) |
172 | break; | 172 | dma_timing |= dma_modes[speed - XFER_MW_DMA_0]; |
173 | |||
174 | case XFER_UDMA_5: | ||
175 | case XFER_UDMA_4: | ||
176 | case XFER_UDMA_3: | ||
177 | case XFER_UDMA_2: | ||
178 | case XFER_UDMA_1: | ||
179 | case XFER_UDMA_0: | ||
180 | dma_timing |= dma_modes[2]; | ||
181 | ultra_timing |= ((udma_modes[speed - XFER_UDMA_0]) << (4*unit)); | ||
182 | ultra_enable |= (0x01 << drive->dn); | ||
183 | default: | ||
184 | break; | ||
185 | } | ||
186 | 173 | ||
187 | pci_write_config_byte(dev, drive_pci2[drive->dn], dma_timing); | 174 | pci_write_config_byte(dev, drive_pci2[drive->dn], dma_timing); |
188 | pci_write_config_byte(dev, (0x56|hwif->channel), ultra_timing); | 175 | pci_write_config_byte(dev, (0x56|hwif->channel), ultra_timing); |
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index 7e9dade5648d..9e0be7d54980 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c | |||
@@ -277,21 +277,6 @@ sgiioc4_ide_dma_end(ide_drive_t * drive) | |||
277 | return dma_stat; | 277 | return dma_stat; |
278 | } | 278 | } |
279 | 279 | ||
280 | static int | ||
281 | sgiioc4_ide_dma_on(ide_drive_t * drive) | ||
282 | { | ||
283 | drive->using_dma = 1; | ||
284 | |||
285 | return 0; | ||
286 | } | ||
287 | |||
288 | static void sgiioc4_dma_off_quietly(ide_drive_t *drive) | ||
289 | { | ||
290 | drive->using_dma = 0; | ||
291 | |||
292 | drive->hwif->dma_host_off(drive); | ||
293 | } | ||
294 | |||
295 | static void sgiioc4_set_dma_mode(ide_drive_t *drive, const u8 speed) | 280 | static void sgiioc4_set_dma_mode(ide_drive_t *drive, const u8 speed) |
296 | { | 281 | { |
297 | } | 282 | } |
@@ -303,13 +288,10 @@ sgiioc4_ide_dma_test_irq(ide_drive_t * drive) | |||
303 | return sgiioc4_checkirq(HWIF(drive)); | 288 | return sgiioc4_checkirq(HWIF(drive)); |
304 | } | 289 | } |
305 | 290 | ||
306 | static void sgiioc4_dma_host_on(ide_drive_t * drive) | 291 | static void sgiioc4_dma_host_set(ide_drive_t *drive, int on) |
307 | { | ||
308 | } | ||
309 | |||
310 | static void sgiioc4_dma_host_off(ide_drive_t * drive) | ||
311 | { | 292 | { |
312 | sgiioc4_clearirq(drive); | 293 | if (!on) |
294 | sgiioc4_clearirq(drive); | ||
313 | } | 295 | } |
314 | 296 | ||
315 | static void | 297 | static void |
@@ -593,14 +575,11 @@ ide_init_sgiioc4(ide_hwif_t * hwif) | |||
593 | 575 | ||
594 | hwif->mwdma_mask = ATA_MWDMA2_ONLY; | 576 | hwif->mwdma_mask = ATA_MWDMA2_ONLY; |
595 | 577 | ||
578 | hwif->dma_host_set = &sgiioc4_dma_host_set; | ||
596 | hwif->dma_setup = &sgiioc4_ide_dma_setup; | 579 | hwif->dma_setup = &sgiioc4_ide_dma_setup; |
597 | hwif->dma_start = &sgiioc4_ide_dma_start; | 580 | hwif->dma_start = &sgiioc4_ide_dma_start; |
598 | hwif->ide_dma_end = &sgiioc4_ide_dma_end; | 581 | hwif->ide_dma_end = &sgiioc4_ide_dma_end; |
599 | hwif->ide_dma_on = &sgiioc4_ide_dma_on; | ||
600 | hwif->dma_off_quietly = &sgiioc4_dma_off_quietly; | ||
601 | hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq; | 582 | hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq; |
602 | hwif->dma_host_on = &sgiioc4_dma_host_on; | ||
603 | hwif->dma_host_off = &sgiioc4_dma_host_off; | ||
604 | hwif->dma_lost_irq = &sgiioc4_dma_lost_irq; | 583 | hwif->dma_lost_irq = &sgiioc4_dma_lost_irq; |
605 | hwif->dma_timeout = &ide_dma_timeout; | 584 | hwif->dma_timeout = &ide_dma_timeout; |
606 | } | 585 | } |
@@ -614,6 +593,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev) | |||
614 | ide_hwif_t *hwif; | 593 | ide_hwif_t *hwif; |
615 | int h; | 594 | int h; |
616 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; | 595 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; |
596 | hw_regs_t hw; | ||
617 | 597 | ||
618 | /* | 598 | /* |
619 | * Find an empty HWIF; if none available, return -ENOMEM. | 599 | * Find an empty HWIF; if none available, return -ENOMEM. |
@@ -653,21 +633,16 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev) | |||
653 | return -ENOMEM; | 633 | return -ENOMEM; |
654 | } | 634 | } |
655 | 635 | ||
656 | if (hwif->io_ports[IDE_DATA_OFFSET] != cmd_base) { | 636 | /* Initialize the IO registers */ |
657 | hw_regs_t hw; | 637 | memset(&hw, 0, sizeof(hw)); |
658 | 638 | sgiioc4_init_hwif_ports(&hw, cmd_base, ctl, irqport); | |
659 | /* Initialize the IO registers */ | 639 | hw.irq = dev->irq; |
660 | memset(&hw, 0, sizeof(hw)); | 640 | hw.chipset = ide_pci; |
661 | sgiioc4_init_hwif_ports(&hw, cmd_base, ctl, irqport); | 641 | hw.dev = &dev->dev; |
662 | memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports)); | 642 | ide_init_port_hw(hwif, &hw); |
663 | hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET]; | ||
664 | } | ||
665 | 643 | ||
666 | hwif->irq = dev->irq; | ||
667 | hwif->chipset = ide_pci; | ||
668 | hwif->pci_dev = dev; | 644 | hwif->pci_dev = dev; |
669 | hwif->channel = 0; /* Single Channel chip */ | 645 | hwif->channel = 0; /* Single Channel chip */ |
670 | hwif->gendev.parent = &dev->dev;/* setup proper ancestral information */ | ||
671 | 646 | ||
672 | /* The IOC4 uses MMIO rather than Port IO. */ | 647 | /* The IOC4 uses MMIO rather than Port IO. */ |
673 | default_hwif_mmiops(hwif); | 648 | default_hwif_mmiops(hwif); |
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c index 7b45eaf5afd9..908f37b4e0ee 100644 --- a/drivers/ide/pci/siimage.c +++ b/drivers/ide/pci/siimage.c | |||
@@ -713,9 +713,6 @@ static int is_dev_seagate_sata(ide_drive_t *drive) | |||
713 | const char *s = &drive->id->model[0]; | 713 | const char *s = &drive->id->model[0]; |
714 | unsigned len; | 714 | unsigned len; |
715 | 715 | ||
716 | if (!drive->present) | ||
717 | return 0; | ||
718 | |||
719 | len = strnlen(s, sizeof(drive->id->model)); | 716 | len = strnlen(s, sizeof(drive->id->model)); |
720 | 717 | ||
721 | if ((len > 4) && (!memcmp(s, "ST", 2))) { | 718 | if ((len > 4) && (!memcmp(s, "ST", 2))) { |
@@ -730,18 +727,20 @@ static int is_dev_seagate_sata(ide_drive_t *drive) | |||
730 | } | 727 | } |
731 | 728 | ||
732 | /** | 729 | /** |
733 | * siimage_fixup - post probe fixups | 730 | * sil_quirkproc - post probe fixups |
734 | * @hwif: interface to fix up | 731 | * @drive: drive |
735 | * | 732 | * |
736 | * Called after drive probe we use this to decide whether the | 733 | * Called after drive probe we use this to decide whether the |
737 | * Seagate fixup must be applied. This used to be in init_iops but | 734 | * Seagate fixup must be applied. This used to be in init_iops but |
738 | * that can occur before we know what drives are present. | 735 | * that can occur before we know what drives are present. |
739 | */ | 736 | */ |
740 | 737 | ||
741 | static void __devinit siimage_fixup(ide_hwif_t *hwif) | 738 | static void __devinit sil_quirkproc(ide_drive_t *drive) |
742 | { | 739 | { |
740 | ide_hwif_t *hwif = drive->hwif; | ||
741 | |||
743 | /* Try and raise the rqsize */ | 742 | /* Try and raise the rqsize */ |
744 | if (!is_sata(hwif) || !is_dev_seagate_sata(&hwif->drives[0])) | 743 | if (!is_sata(hwif) || !is_dev_seagate_sata(drive)) |
745 | hwif->rqsize = 128; | 744 | hwif->rqsize = 128; |
746 | } | 745 | } |
747 | 746 | ||
@@ -804,6 +803,7 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif) | |||
804 | 803 | ||
805 | hwif->set_pio_mode = &sil_set_pio_mode; | 804 | hwif->set_pio_mode = &sil_set_pio_mode; |
806 | hwif->set_dma_mode = &sil_set_dma_mode; | 805 | hwif->set_dma_mode = &sil_set_dma_mode; |
806 | hwif->quirkproc = &sil_quirkproc; | ||
807 | 807 | ||
808 | if (sata) { | 808 | if (sata) { |
809 | static int first = 1; | 809 | static int first = 1; |
@@ -842,7 +842,6 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif) | |||
842 | .init_chipset = init_chipset_siimage, \ | 842 | .init_chipset = init_chipset_siimage, \ |
843 | .init_iops = init_iops_siimage, \ | 843 | .init_iops = init_iops_siimage, \ |
844 | .init_hwif = init_hwif_siimage, \ | 844 | .init_hwif = init_hwif_siimage, \ |
845 | .fixup = siimage_fixup, \ | ||
846 | .host_flags = IDE_HFLAG_BOOTABLE, \ | 845 | .host_flags = IDE_HFLAG_BOOTABLE, \ |
847 | .pio_mask = ATA_PIO4, \ | 846 | .pio_mask = ATA_PIO4, \ |
848 | .mwdma_mask = ATA_MWDMA2, \ | 847 | .mwdma_mask = ATA_MWDMA2, \ |
diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c index 069f104fdcea..c7a125b66c29 100644 --- a/drivers/ide/pci/sl82c105.c +++ b/drivers/ide/pci/sl82c105.c | |||
@@ -13,6 +13,7 @@ | |||
13 | * -- Benjamin Herrenschmidt (01/11/03) benh@kernel.crashing.org | 13 | * -- Benjamin Herrenschmidt (01/11/03) benh@kernel.crashing.org |
14 | * | 14 | * |
15 | * Copyright (C) 2006-2007 MontaVista Software, Inc. <source@mvista.com> | 15 | * Copyright (C) 2006-2007 MontaVista Software, Inc. <source@mvista.com> |
16 | * Copyright (C) 2007 Bartlomiej Zolnierkiewicz | ||
16 | */ | 17 | */ |
17 | 18 | ||
18 | #include <linux/types.h> | 19 | #include <linux/types.h> |
@@ -90,14 +91,8 @@ static void sl82c105_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
90 | drive->drive_data &= 0xffff0000; | 91 | drive->drive_data &= 0xffff0000; |
91 | drive->drive_data |= drv_ctrl; | 92 | drive->drive_data |= drv_ctrl; |
92 | 93 | ||
93 | if (!drive->using_dma) { | 94 | pci_write_config_word(dev, reg, drv_ctrl); |
94 | /* | 95 | pci_read_config_word (dev, reg, &drv_ctrl); |
95 | * If we are actually using MW DMA, then we can not | ||
96 | * reprogram the interface drive control register. | ||
97 | */ | ||
98 | pci_write_config_word(dev, reg, drv_ctrl); | ||
99 | pci_read_config_word (dev, reg, &drv_ctrl); | ||
100 | } | ||
101 | 96 | ||
102 | printk(KERN_DEBUG "%s: selected %s (%dns) (%04X)\n", drive->name, | 97 | printk(KERN_DEBUG "%s: selected %s (%dns) (%04X)\n", drive->name, |
103 | ide_xfer_verbose(pio + XFER_PIO_0), | 98 | ide_xfer_verbose(pio + XFER_PIO_0), |
@@ -123,17 +118,6 @@ static void sl82c105_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
123 | */ | 118 | */ |
124 | drive->drive_data &= 0x0000ffff; | 119 | drive->drive_data &= 0x0000ffff; |
125 | drive->drive_data |= (unsigned long)drv_ctrl << 16; | 120 | drive->drive_data |= (unsigned long)drv_ctrl << 16; |
126 | |||
127 | /* | ||
128 | * If we are already using DMA, we just reprogram | ||
129 | * the drive control register. | ||
130 | */ | ||
131 | if (drive->using_dma) { | ||
132 | struct pci_dev *dev = HWIF(drive)->pci_dev; | ||
133 | int reg = 0x44 + drive->dn * 4; | ||
134 | |||
135 | pci_write_config_word(dev, reg, drv_ctrl); | ||
136 | } | ||
137 | } | 121 | } |
138 | 122 | ||
139 | /* | 123 | /* |
@@ -201,6 +185,11 @@ static void sl82c105_dma_start(ide_drive_t *drive) | |||
201 | { | 185 | { |
202 | ide_hwif_t *hwif = HWIF(drive); | 186 | ide_hwif_t *hwif = HWIF(drive); |
203 | struct pci_dev *dev = hwif->pci_dev; | 187 | struct pci_dev *dev = hwif->pci_dev; |
188 | int reg = 0x44 + drive->dn * 4; | ||
189 | |||
190 | DBG(("%s(drive:%s)\n", __FUNCTION__, drive->name)); | ||
191 | |||
192 | pci_write_config_word(dev, reg, drive->drive_data >> 16); | ||
204 | 193 | ||
205 | sl82c105_reset_host(dev); | 194 | sl82c105_reset_host(dev); |
206 | ide_dma_start(drive); | 195 | ide_dma_start(drive); |
@@ -214,64 +203,24 @@ static void sl82c105_dma_timeout(ide_drive_t *drive) | |||
214 | ide_dma_timeout(drive); | 203 | ide_dma_timeout(drive); |
215 | } | 204 | } |
216 | 205 | ||
217 | static int sl82c105_ide_dma_on(ide_drive_t *drive) | 206 | static int sl82c105_dma_end(ide_drive_t *drive) |
218 | { | ||
219 | struct pci_dev *dev = HWIF(drive)->pci_dev; | ||
220 | int rc, reg = 0x44 + drive->dn * 4; | ||
221 | |||
222 | DBG(("sl82c105_ide_dma_on(drive:%s)\n", drive->name)); | ||
223 | |||
224 | rc = __ide_dma_on(drive); | ||
225 | if (rc == 0) { | ||
226 | pci_write_config_word(dev, reg, drive->drive_data >> 16); | ||
227 | |||
228 | printk(KERN_INFO "%s: DMA enabled\n", drive->name); | ||
229 | } | ||
230 | return rc; | ||
231 | } | ||
232 | |||
233 | static void sl82c105_dma_off_quietly(ide_drive_t *drive) | ||
234 | { | 207 | { |
235 | struct pci_dev *dev = HWIF(drive)->pci_dev; | 208 | struct pci_dev *dev = HWIF(drive)->pci_dev; |
236 | int reg = 0x44 + drive->dn * 4; | 209 | int reg = 0x44 + drive->dn * 4; |
210 | int ret; | ||
237 | 211 | ||
238 | DBG(("sl82c105_dma_off_quietly(drive:%s)\n", drive->name)); | 212 | DBG(("%s(drive:%s)\n", __FUNCTION__, drive->name)); |
239 | 213 | ||
240 | pci_write_config_word(dev, reg, drive->drive_data); | 214 | ret = __ide_dma_end(drive); |
241 | 215 | ||
242 | ide_dma_off_quietly(drive); | 216 | pci_write_config_word(dev, reg, drive->drive_data); |
243 | } | ||
244 | 217 | ||
245 | /* | 218 | return ret; |
246 | * Ok, that is nasty, but we must make sure the DMA timings | ||
247 | * won't be used for a PIO access. The solution here is | ||
248 | * to make sure the 16 bits mode is diabled on the channel | ||
249 | * when DMA is enabled, thus causing the chip to use PIO0 | ||
250 | * timings for those operations. | ||
251 | */ | ||
252 | static void sl82c105_selectproc(ide_drive_t *drive) | ||
253 | { | ||
254 | ide_hwif_t *hwif = HWIF(drive); | ||
255 | struct pci_dev *dev = hwif->pci_dev; | ||
256 | u32 val, old, mask; | ||
257 | |||
258 | //DBG(("sl82c105_selectproc(drive:%s)\n", drive->name)); | ||
259 | |||
260 | mask = hwif->channel ? CTRL_P1F16 : CTRL_P0F16; | ||
261 | old = val = (u32)pci_get_drvdata(dev); | ||
262 | if (drive->using_dma) | ||
263 | val &= ~mask; | ||
264 | else | ||
265 | val |= mask; | ||
266 | if (old != val) { | ||
267 | pci_write_config_dword(dev, 0x40, val); | ||
268 | pci_set_drvdata(dev, (void *)val); | ||
269 | } | ||
270 | } | 219 | } |
271 | 220 | ||
272 | /* | 221 | /* |
273 | * ATA reset will clear the 16 bits mode in the control | 222 | * ATA reset will clear the 16 bits mode in the control |
274 | * register, we need to update our cache | 223 | * register, we need to reprogram it |
275 | */ | 224 | */ |
276 | static void sl82c105_resetproc(ide_drive_t *drive) | 225 | static void sl82c105_resetproc(ide_drive_t *drive) |
277 | { | 226 | { |
@@ -281,7 +230,8 @@ static void sl82c105_resetproc(ide_drive_t *drive) | |||
281 | DBG(("sl82c105_resetproc(drive:%s)\n", drive->name)); | 230 | DBG(("sl82c105_resetproc(drive:%s)\n", drive->name)); |
282 | 231 | ||
283 | pci_read_config_dword(dev, 0x40, &val); | 232 | pci_read_config_dword(dev, 0x40, &val); |
284 | pci_set_drvdata(dev, (void *)val); | 233 | val |= (CTRL_P1F16 | CTRL_P0F16); |
234 | pci_write_config_dword(dev, 0x40, val); | ||
285 | } | 235 | } |
286 | 236 | ||
287 | /* | 237 | /* |
@@ -334,7 +284,6 @@ static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const c | |||
334 | pci_read_config_dword(dev, 0x40, &val); | 284 | pci_read_config_dword(dev, 0x40, &val); |
335 | val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16; | 285 | val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16; |
336 | pci_write_config_dword(dev, 0x40, val); | 286 | pci_write_config_dword(dev, 0x40, val); |
337 | pci_set_drvdata(dev, (void *)val); | ||
338 | 287 | ||
339 | return dev->irq; | 288 | return dev->irq; |
340 | } | 289 | } |
@@ -350,7 +299,6 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) | |||
350 | 299 | ||
351 | hwif->set_pio_mode = &sl82c105_set_pio_mode; | 300 | hwif->set_pio_mode = &sl82c105_set_pio_mode; |
352 | hwif->set_dma_mode = &sl82c105_set_dma_mode; | 301 | hwif->set_dma_mode = &sl82c105_set_dma_mode; |
353 | hwif->selectproc = &sl82c105_selectproc; | ||
354 | hwif->resetproc = &sl82c105_resetproc; | 302 | hwif->resetproc = &sl82c105_resetproc; |
355 | 303 | ||
356 | if (!hwif->dma_base) | 304 | if (!hwif->dma_base) |
@@ -369,10 +317,9 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) | |||
369 | 317 | ||
370 | hwif->mwdma_mask = ATA_MWDMA2; | 318 | hwif->mwdma_mask = ATA_MWDMA2; |
371 | 319 | ||
372 | hwif->ide_dma_on = &sl82c105_ide_dma_on; | ||
373 | hwif->dma_off_quietly = &sl82c105_dma_off_quietly; | ||
374 | hwif->dma_lost_irq = &sl82c105_dma_lost_irq; | 320 | hwif->dma_lost_irq = &sl82c105_dma_lost_irq; |
375 | hwif->dma_start = &sl82c105_dma_start; | 321 | hwif->dma_start = &sl82c105_dma_start; |
322 | hwif->ide_dma_end = &sl82c105_dma_end; | ||
376 | hwif->dma_timeout = &sl82c105_dma_timeout; | 323 | hwif->dma_timeout = &sl82c105_dma_timeout; |
377 | 324 | ||
378 | if (hwif->mate) | 325 | if (hwif->mate) |
diff --git a/drivers/ide/pci/trm290.c b/drivers/ide/pci/trm290.c index 0151d7fdfb8a..04cd893e1ab0 100644 --- a/drivers/ide/pci/trm290.c +++ b/drivers/ide/pci/trm290.c | |||
@@ -241,11 +241,7 @@ static int trm290_ide_dma_test_irq (ide_drive_t *drive) | |||
241 | return (status == 0x00ff); | 241 | return (status == 0x00ff); |
242 | } | 242 | } |
243 | 243 | ||
244 | static void trm290_dma_host_on(ide_drive_t *drive) | 244 | static void trm290_dma_host_set(ide_drive_t *drive, int on) |
245 | { | ||
246 | } | ||
247 | |||
248 | static void trm290_dma_host_off(ide_drive_t *drive) | ||
249 | { | 245 | { |
250 | } | 246 | } |
251 | 247 | ||
@@ -289,8 +285,7 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif) | |||
289 | 285 | ||
290 | ide_setup_dma(hwif, (hwif->config_data + 4) ^ (hwif->channel ? 0x0080 : 0x0000), 3); | 286 | ide_setup_dma(hwif, (hwif->config_data + 4) ^ (hwif->channel ? 0x0080 : 0x0000), 3); |
291 | 287 | ||
292 | hwif->dma_host_off = &trm290_dma_host_off; | 288 | hwif->dma_host_set = &trm290_dma_host_set; |
293 | hwif->dma_host_on = &trm290_dma_host_on; | ||
294 | hwif->dma_setup = &trm290_dma_setup; | 289 | hwif->dma_setup = &trm290_dma_setup; |
295 | hwif->dma_exec_cmd = &trm290_dma_exec_cmd; | 290 | hwif->dma_exec_cmd = &trm290_dma_exec_cmd; |
296 | hwif->dma_start = &trm290_dma_start; | 291 | hwif->dma_start = &trm290_dma_start; |
diff --git a/drivers/ide/ppc/Makefile b/drivers/ide/ppc/Makefile new file mode 100644 index 000000000000..65af5848b28c --- /dev/null +++ b/drivers/ide/ppc/Makefile | |||
@@ -0,0 +1,3 @@ | |||
1 | |||
2 | obj-$(CONFIG_BLK_DEV_IDE_PMAC) += pmac.o | ||
3 | obj-$(CONFIG_BLK_DEV_MPC8xx_IDE) += mpc8xx.o | ||
diff --git a/drivers/ide/ppc/mpc8xx.c b/drivers/ide/ppc/mpc8xx.c index 5f0da35ab5ad..3fd5d45b5e0e 100644 --- a/drivers/ide/ppc/mpc8xx.c +++ b/drivers/ide/ppc/mpc8xx.c | |||
@@ -838,3 +838,21 @@ void m8xx_ide_init(void) | |||
838 | ppc_ide_md.default_io_base = m8xx_ide_default_io_base; | 838 | ppc_ide_md.default_io_base = m8xx_ide_default_io_base; |
839 | ppc_ide_md.ide_init_hwif = m8xx_ide_init_hwif_ports; | 839 | ppc_ide_md.ide_init_hwif = m8xx_ide_init_hwif_ports; |
840 | } | 840 | } |
841 | |||
842 | static int __init mpc8xx_ide_probe(void) | ||
843 | { | ||
844 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; | ||
845 | |||
846 | #ifdef IDE0_BASE_OFFSET | ||
847 | idx[0] = 0; | ||
848 | #ifdef IDE1_BASE_OFFSET | ||
849 | idx[1] = 1; | ||
850 | #endif | ||
851 | #endif | ||
852 | |||
853 | ide_device_add(idx); | ||
854 | |||
855 | return 0; | ||
856 | } | ||
857 | |||
858 | module_init(mpc8xx_ide_probe); | ||
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index 3dce80092fff..736d12c8e68a 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c | |||
@@ -1012,12 +1012,11 @@ pmac_ide_do_resume(ide_hwif_t *hwif) | |||
1012 | * rare machines unfortunately, but it's better this way. | 1012 | * rare machines unfortunately, but it's better this way. |
1013 | */ | 1013 | */ |
1014 | static int | 1014 | static int |
1015 | pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) | 1015 | pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif, hw_regs_t *hw) |
1016 | { | 1016 | { |
1017 | struct device_node *np = pmif->node; | 1017 | struct device_node *np = pmif->node; |
1018 | const int *bidp; | 1018 | const int *bidp; |
1019 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; | 1019 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; |
1020 | hw_regs_t hw; | ||
1021 | 1020 | ||
1022 | pmif->cable_80 = 0; | 1021 | pmif->cable_80 = 0; |
1023 | pmif->broken_dma = pmif->broken_dma_warn = 0; | 1022 | pmif->broken_dma = pmif->broken_dma_warn = 0; |
@@ -1103,11 +1102,9 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) | |||
1103 | /* Tell common code _not_ to mess with resources */ | 1102 | /* Tell common code _not_ to mess with resources */ |
1104 | hwif->mmio = 1; | 1103 | hwif->mmio = 1; |
1105 | hwif->hwif_data = pmif; | 1104 | hwif->hwif_data = pmif; |
1106 | memset(&hw, 0, sizeof(hw)); | 1105 | hw->chipset = ide_pmac; |
1107 | pmac_ide_init_hwif_ports(&hw, pmif->regbase, 0, &hwif->irq); | 1106 | ide_init_port_hw(hwif, hw); |
1108 | memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports)); | 1107 | hwif->noprobe = pmif->mediabay; |
1109 | hwif->chipset = ide_pmac; | ||
1110 | hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET] || pmif->mediabay; | ||
1111 | hwif->hold = pmif->mediabay; | 1108 | hwif->hold = pmif->mediabay; |
1112 | hwif->cbl = pmif->cable_80 ? ATA_CBL_PATA80 : ATA_CBL_PATA40; | 1109 | hwif->cbl = pmif->cable_80 ? ATA_CBL_PATA80 : ATA_CBL_PATA40; |
1113 | hwif->drives[0].unmask = 1; | 1110 | hwif->drives[0].unmask = 1; |
@@ -1136,8 +1133,6 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) | |||
1136 | hwif->noprobe = 0; | 1133 | hwif->noprobe = 0; |
1137 | #endif /* CONFIG_PMAC_MEDIABAY */ | 1134 | #endif /* CONFIG_PMAC_MEDIABAY */ |
1138 | 1135 | ||
1139 | hwif->sg_max_nents = MAX_DCMDS; | ||
1140 | |||
1141 | #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC | 1136 | #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC |
1142 | /* has a DBDMA controller channel */ | 1137 | /* has a DBDMA controller channel */ |
1143 | if (pmif->dma_regs) | 1138 | if (pmif->dma_regs) |
@@ -1163,6 +1158,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) | |||
1163 | ide_hwif_t *hwif; | 1158 | ide_hwif_t *hwif; |
1164 | pmac_ide_hwif_t *pmif; | 1159 | pmac_ide_hwif_t *pmif; |
1165 | int i, rc; | 1160 | int i, rc; |
1161 | hw_regs_t hw; | ||
1166 | 1162 | ||
1167 | i = 0; | 1163 | i = 0; |
1168 | while (i < MAX_HWIFS && (ide_hwifs[i].io_ports[IDE_DATA_OFFSET] != 0 | 1164 | while (i < MAX_HWIFS && (ide_hwifs[i].io_ports[IDE_DATA_OFFSET] != 0 |
@@ -1205,7 +1201,6 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) | |||
1205 | regbase = (unsigned long) base; | 1201 | regbase = (unsigned long) base; |
1206 | 1202 | ||
1207 | hwif->pci_dev = mdev->bus->pdev; | 1203 | hwif->pci_dev = mdev->bus->pdev; |
1208 | hwif->gendev.parent = &mdev->ofdev.dev; | ||
1209 | 1204 | ||
1210 | pmif->mdev = mdev; | 1205 | pmif->mdev = mdev; |
1211 | pmif->node = mdev->ofdev.node; | 1206 | pmif->node = mdev->ofdev.node; |
@@ -1223,7 +1218,12 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) | |||
1223 | #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ | 1218 | #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ |
1224 | dev_set_drvdata(&mdev->ofdev.dev, hwif); | 1219 | dev_set_drvdata(&mdev->ofdev.dev, hwif); |
1225 | 1220 | ||
1226 | rc = pmac_ide_setup_device(pmif, hwif); | 1221 | memset(&hw, 0, sizeof(hw)); |
1222 | pmac_ide_init_hwif_ports(&hw, pmif->regbase, 0, NULL); | ||
1223 | hw.irq = irq; | ||
1224 | hw.dev = &mdev->ofdev.dev; | ||
1225 | |||
1226 | rc = pmac_ide_setup_device(pmif, hwif, &hw); | ||
1227 | if (rc != 0) { | 1227 | if (rc != 0) { |
1228 | /* The inteface is released to the common IDE layer */ | 1228 | /* The inteface is released to the common IDE layer */ |
1229 | dev_set_drvdata(&mdev->ofdev.dev, NULL); | 1229 | dev_set_drvdata(&mdev->ofdev.dev, NULL); |
@@ -1282,6 +1282,7 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1282 | void __iomem *base; | 1282 | void __iomem *base; |
1283 | unsigned long rbase, rlen; | 1283 | unsigned long rbase, rlen; |
1284 | int i, rc; | 1284 | int i, rc; |
1285 | hw_regs_t hw; | ||
1285 | 1286 | ||
1286 | np = pci_device_to_OF_node(pdev); | 1287 | np = pci_device_to_OF_node(pdev); |
1287 | if (np == NULL) { | 1288 | if (np == NULL) { |
@@ -1315,7 +1316,6 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1315 | } | 1316 | } |
1316 | 1317 | ||
1317 | hwif->pci_dev = pdev; | 1318 | hwif->pci_dev = pdev; |
1318 | hwif->gendev.parent = &pdev->dev; | ||
1319 | pmif->mdev = NULL; | 1319 | pmif->mdev = NULL; |
1320 | pmif->node = np; | 1320 | pmif->node = np; |
1321 | 1321 | ||
@@ -1332,7 +1332,12 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1332 | 1332 | ||
1333 | pci_set_drvdata(pdev, hwif); | 1333 | pci_set_drvdata(pdev, hwif); |
1334 | 1334 | ||
1335 | rc = pmac_ide_setup_device(pmif, hwif); | 1335 | memset(&hw, 0, sizeof(hw)); |
1336 | pmac_ide_init_hwif_ports(&hw, pmif->regbase, 0, NULL); | ||
1337 | hw.irq = pdev->irq; | ||
1338 | hw.dev = &pdev->dev; | ||
1339 | |||
1340 | rc = pmac_ide_setup_device(pmif, hwif, &hw); | ||
1336 | if (rc != 0) { | 1341 | if (rc != 0) { |
1337 | /* The inteface is released to the common IDE layer */ | 1342 | /* The inteface is released to the common IDE layer */ |
1338 | pci_set_drvdata(pdev, NULL); | 1343 | pci_set_drvdata(pdev, NULL); |
@@ -1698,11 +1703,7 @@ pmac_ide_dma_test_irq (ide_drive_t *drive) | |||
1698 | return 1; | 1703 | return 1; |
1699 | } | 1704 | } |
1700 | 1705 | ||
1701 | static void pmac_ide_dma_host_off(ide_drive_t *drive) | 1706 | static void pmac_ide_dma_host_set(ide_drive_t *drive, int on) |
1702 | { | ||
1703 | } | ||
1704 | |||
1705 | static void pmac_ide_dma_host_on(ide_drive_t *drive) | ||
1706 | { | 1707 | { |
1707 | } | 1708 | } |
1708 | 1709 | ||
@@ -1748,15 +1749,14 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) | |||
1748 | return; | 1749 | return; |
1749 | } | 1750 | } |
1750 | 1751 | ||
1751 | hwif->dma_off_quietly = &ide_dma_off_quietly; | 1752 | hwif->sg_max_nents = MAX_DCMDS; |
1752 | hwif->ide_dma_on = &__ide_dma_on; | 1753 | |
1754 | hwif->dma_host_set = &pmac_ide_dma_host_set; | ||
1753 | hwif->dma_setup = &pmac_ide_dma_setup; | 1755 | hwif->dma_setup = &pmac_ide_dma_setup; |
1754 | hwif->dma_exec_cmd = &pmac_ide_dma_exec_cmd; | 1756 | hwif->dma_exec_cmd = &pmac_ide_dma_exec_cmd; |
1755 | hwif->dma_start = &pmac_ide_dma_start; | 1757 | hwif->dma_start = &pmac_ide_dma_start; |
1756 | hwif->ide_dma_end = &pmac_ide_dma_end; | 1758 | hwif->ide_dma_end = &pmac_ide_dma_end; |
1757 | hwif->ide_dma_test_irq = &pmac_ide_dma_test_irq; | 1759 | hwif->ide_dma_test_irq = &pmac_ide_dma_test_irq; |
1758 | hwif->dma_host_off = &pmac_ide_dma_host_off; | ||
1759 | hwif->dma_host_on = &pmac_ide_dma_host_on; | ||
1760 | hwif->dma_timeout = &ide_dma_timeout; | 1760 | hwif->dma_timeout = &ide_dma_timeout; |
1761 | hwif->dma_lost_irq = &pmac_ide_dma_lost_irq; | 1761 | hwif->dma_lost_irq = &pmac_ide_dma_lost_irq; |
1762 | 1762 | ||
@@ -1786,3 +1786,5 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) | |||
1786 | } | 1786 | } |
1787 | 1787 | ||
1788 | #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ | 1788 | #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ |
1789 | |||
1790 | module_init(pmac_ide_probe); | ||
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index d2cd5a3d38f8..676c66e72881 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c | |||
@@ -165,13 +165,17 @@ static unsigned long ide_get_or_set_dma_base(const struct ide_port_info *d, ide_ | |||
165 | 165 | ||
166 | dma_base = pci_resource_start(dev, baridx); | 166 | dma_base = pci_resource_start(dev, baridx); |
167 | 167 | ||
168 | if (dma_base == 0) | 168 | if (dma_base == 0) { |
169 | printk(KERN_ERR "%s: DMA base is invalid\n", d->name); | 169 | printk(KERN_ERR "%s: DMA base is invalid\n", d->name); |
170 | return 0; | ||
171 | } | ||
170 | } | 172 | } |
171 | 173 | ||
172 | if ((d->host_flags & IDE_HFLAG_CS5520) == 0 && dma_base) { | 174 | if (hwif->channel) |
175 | dma_base += 8; | ||
176 | |||
177 | if ((d->host_flags & IDE_HFLAG_CS5520) == 0) { | ||
173 | u8 simplex_stat = 0; | 178 | u8 simplex_stat = 0; |
174 | dma_base += hwif->channel ? 8 : 0; | ||
175 | 179 | ||
176 | switch(dev->device) { | 180 | switch(dev->device) { |
177 | case PCI_DEVICE_ID_AL_M5219: | 181 | case PCI_DEVICE_ID_AL_M5219: |
@@ -359,6 +363,8 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, const struct ide_port | |||
359 | unsigned long ctl = 0, base = 0; | 363 | unsigned long ctl = 0, base = 0; |
360 | ide_hwif_t *hwif; | 364 | ide_hwif_t *hwif; |
361 | u8 bootable = (d->host_flags & IDE_HFLAG_BOOTABLE) ? 1 : 0; | 365 | u8 bootable = (d->host_flags & IDE_HFLAG_BOOTABLE) ? 1 : 0; |
366 | u8 oldnoprobe = 0; | ||
367 | struct hw_regs_s hw; | ||
362 | 368 | ||
363 | if ((d->host_flags & IDE_HFLAG_ISA_PORTS) == 0) { | 369 | if ((d->host_flags & IDE_HFLAG_ISA_PORTS) == 0) { |
364 | /* Possibly we should fail if these checks report true */ | 370 | /* Possibly we should fail if these checks report true */ |
@@ -381,26 +387,25 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, const struct ide_port | |||
381 | } | 387 | } |
382 | if ((hwif = ide_match_hwif(base, bootable, d->name)) == NULL) | 388 | if ((hwif = ide_match_hwif(base, bootable, d->name)) == NULL) |
383 | return NULL; /* no room in ide_hwifs[] */ | 389 | return NULL; /* no room in ide_hwifs[] */ |
384 | if (hwif->io_ports[IDE_DATA_OFFSET] != base || | 390 | |
385 | hwif->io_ports[IDE_CONTROL_OFFSET] != (ctl | 2)) { | 391 | memset(&hw, 0, sizeof(hw)); |
386 | hw_regs_t hw; | 392 | hw.irq = hwif->irq ? hwif->irq : irq; |
387 | 393 | hw.dev = &dev->dev; | |
388 | memset(&hw, 0, sizeof(hw)); | 394 | hw.chipset = d->chipset ? d->chipset : ide_pci; |
389 | #ifndef CONFIG_IDE_ARCH_OBSOLETE_INIT | 395 | ide_std_init_ports(&hw, base, ctl | 2); |
390 | ide_std_init_ports(&hw, base, ctl | 2); | 396 | |
391 | #else | 397 | if (hwif->io_ports[IDE_DATA_OFFSET] == base && |
392 | ide_init_hwif_ports(&hw, base, ctl | 2, NULL); | 398 | hwif->io_ports[IDE_CONTROL_OFFSET] == (ctl | 2)) |
393 | #endif | 399 | oldnoprobe = hwif->noprobe; |
394 | memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports)); | 400 | |
395 | hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET]; | 401 | ide_init_port_hw(hwif, &hw); |
396 | } | 402 | |
397 | hwif->chipset = d->chipset ? d->chipset : ide_pci; | 403 | hwif->noprobe = oldnoprobe; |
404 | |||
398 | hwif->pci_dev = dev; | 405 | hwif->pci_dev = dev; |
399 | hwif->cds = d; | 406 | hwif->cds = d; |
400 | hwif->channel = port; | 407 | hwif->channel = port; |
401 | 408 | ||
402 | if (!hwif->irq) | ||
403 | hwif->irq = irq; | ||
404 | if (mate) { | 409 | if (mate) { |
405 | hwif->mate = mate; | 410 | hwif->mate = mate; |
406 | mate->mate = hwif; | 411 | mate->mate = hwif; |
@@ -535,12 +540,8 @@ void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, int | |||
535 | if ((hwif = ide_hwif_configure(dev, d, mate, port, pciirq)) == NULL) | 540 | if ((hwif = ide_hwif_configure(dev, d, mate, port, pciirq)) == NULL) |
536 | continue; | 541 | continue; |
537 | 542 | ||
538 | /* setup proper ancestral information */ | ||
539 | hwif->gendev.parent = &dev->dev; | ||
540 | |||
541 | *(idx + port) = hwif->index; | 543 | *(idx + port) = hwif->index; |
542 | 544 | ||
543 | |||
544 | if (d->init_iops) | 545 | if (d->init_iops) |
545 | d->init_iops(hwif); | 546 | d->init_iops(hwif); |
546 | 547 | ||
@@ -551,8 +552,6 @@ void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, int | |||
551 | (d->host_flags & IDE_HFLAG_FORCE_LEGACY_IRQS)) | 552 | (d->host_flags & IDE_HFLAG_FORCE_LEGACY_IRQS)) |
552 | hwif->irq = port ? 15 : 14; | 553 | hwif->irq = port ? 15 : 14; |
553 | 554 | ||
554 | hwif->fixup = d->fixup; | ||
555 | |||
556 | hwif->host_flags = d->host_flags; | 555 | hwif->host_flags = d->host_flags; |
557 | hwif->pio_mask = d->pio_mask; | 556 | hwif->pio_mask = d->pio_mask; |
558 | 557 | ||
@@ -699,105 +698,3 @@ out: | |||
699 | } | 698 | } |
700 | 699 | ||
701 | EXPORT_SYMBOL_GPL(ide_setup_pci_devices); | 700 | EXPORT_SYMBOL_GPL(ide_setup_pci_devices); |
702 | |||
703 | #ifdef CONFIG_IDEPCI_PCIBUS_ORDER | ||
704 | /* | ||
705 | * Module interfaces | ||
706 | */ | ||
707 | |||
708 | static int pre_init = 1; /* Before first ordered IDE scan */ | ||
709 | static LIST_HEAD(ide_pci_drivers); | ||
710 | |||
711 | /* | ||
712 | * __ide_pci_register_driver - attach IDE driver | ||
713 | * @driver: pci driver | ||
714 | * @module: owner module of the driver | ||
715 | * | ||
716 | * Registers a driver with the IDE layer. The IDE layer arranges that | ||
717 | * boot time setup is done in the expected device order and then | ||
718 | * hands the controllers off to the core PCI code to do the rest of | ||
719 | * the work. | ||
720 | * | ||
721 | * Returns are the same as for pci_register_driver | ||
722 | */ | ||
723 | |||
724 | int __ide_pci_register_driver(struct pci_driver *driver, struct module *module, | ||
725 | const char *mod_name) | ||
726 | { | ||
727 | if (!pre_init) | ||
728 | return __pci_register_driver(driver, module, mod_name); | ||
729 | driver->driver.owner = module; | ||
730 | list_add_tail(&driver->node, &ide_pci_drivers); | ||
731 | return 0; | ||
732 | } | ||
733 | EXPORT_SYMBOL_GPL(__ide_pci_register_driver); | ||
734 | |||
735 | /** | ||
736 | * ide_scan_pcidev - find an IDE driver for a device | ||
737 | * @dev: PCI device to check | ||
738 | * | ||
739 | * Look for an IDE driver to handle the device we are considering. | ||
740 | * This is only used during boot up to get the ordering correct. After | ||
741 | * boot up the pci layer takes over the job. | ||
742 | */ | ||
743 | |||
744 | static int __init ide_scan_pcidev(struct pci_dev *dev) | ||
745 | { | ||
746 | struct list_head *l; | ||
747 | struct pci_driver *d; | ||
748 | |||
749 | list_for_each(l, &ide_pci_drivers) { | ||
750 | d = list_entry(l, struct pci_driver, node); | ||
751 | if (d->id_table) { | ||
752 | const struct pci_device_id *id = | ||
753 | pci_match_id(d->id_table, dev); | ||
754 | |||
755 | if (id != NULL && d->probe(dev, id) >= 0) { | ||
756 | dev->driver = d; | ||
757 | pci_dev_get(dev); | ||
758 | return 1; | ||
759 | } | ||
760 | } | ||
761 | } | ||
762 | return 0; | ||
763 | } | ||
764 | |||
765 | /** | ||
766 | * ide_scan_pcibus - perform the initial IDE driver scan | ||
767 | * @scan_direction: set for reverse order scanning | ||
768 | * | ||
769 | * Perform the initial bus rather than driver ordered scan of the | ||
770 | * PCI drivers. After this all IDE pci handling becomes standard | ||
771 | * module ordering not traditionally ordered. | ||
772 | */ | ||
773 | |||
774 | void __init ide_scan_pcibus (int scan_direction) | ||
775 | { | ||
776 | struct pci_dev *dev = NULL; | ||
777 | struct pci_driver *d; | ||
778 | struct list_head *l, *n; | ||
779 | |||
780 | pre_init = 0; | ||
781 | if (!scan_direction) | ||
782 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev))) | ||
783 | ide_scan_pcidev(dev); | ||
784 | else | ||
785 | while ((dev = pci_get_device_reverse(PCI_ANY_ID, PCI_ANY_ID, | ||
786 | dev))) | ||
787 | ide_scan_pcidev(dev); | ||
788 | |||
789 | /* | ||
790 | * Hand the drivers over to the PCI layer now we | ||
791 | * are post init. | ||
792 | */ | ||
793 | |||
794 | list_for_each_safe(l, n, &ide_pci_drivers) { | ||
795 | list_del(l); | ||
796 | d = list_entry(l, struct pci_driver, node); | ||
797 | if (__pci_register_driver(d, d->driver.owner, | ||
798 | d->driver.mod_name)) | ||
799 | printk(KERN_ERR "%s: failed to register %s driver\n", | ||
800 | __FUNCTION__, d->driver.mod_name); | ||
801 | } | ||
802 | } | ||
803 | #endif | ||
diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c index 48d647abea46..eaba4a9b231e 100644 --- a/drivers/macintosh/mediabay.c +++ b/drivers/macintosh/mediabay.c | |||
@@ -563,7 +563,8 @@ static void media_bay_step(int i) | |||
563 | ide_init_hwif_ports(&hw, (unsigned long) bay->cd_base, (unsigned long) 0, NULL); | 563 | ide_init_hwif_ports(&hw, (unsigned long) bay->cd_base, (unsigned long) 0, NULL); |
564 | hw.irq = bay->cd_irq; | 564 | hw.irq = bay->cd_irq; |
565 | hw.chipset = ide_pmac; | 565 | hw.chipset = ide_pmac; |
566 | bay->cd_index = ide_register_hw(&hw, NULL, 0, NULL); | 566 | bay->cd_index = |
567 | ide_register_hw(&hw, NULL, NULL); | ||
567 | pmu_resume(); | 568 | pmu_resume(); |
568 | } | 569 | } |
569 | if (bay->cd_index == -1) { | 570 | if (bay->cd_index == -1) { |
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c index 5452da1bb1a5..b66da74caa55 100644 --- a/drivers/macintosh/therm_windtunnel.c +++ b/drivers/macintosh/therm_windtunnel.c | |||
@@ -47,12 +47,10 @@ | |||
47 | 47 | ||
48 | #define LOG_TEMP 0 /* continously log temperature */ | 48 | #define LOG_TEMP 0 /* continously log temperature */ |
49 | 49 | ||
50 | #define I2C_DRIVERID_G4FAN 0x9001 /* fixme */ | ||
51 | |||
52 | static int do_probe( struct i2c_adapter *adapter, int addr, int kind); | 50 | static int do_probe( struct i2c_adapter *adapter, int addr, int kind); |
53 | 51 | ||
54 | /* scan 0x48-0x4f (DS1775) and 0x2c-2x2f (ADM1030) */ | 52 | /* scan 0x48-0x4f (DS1775) and 0x2c-2x2f (ADM1030) */ |
55 | static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, | 53 | static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, |
56 | 0x4c, 0x4d, 0x4e, 0x4f, | 54 | 0x4c, 0x4d, 0x4e, 0x4f, |
57 | 0x2c, 0x2d, 0x2e, 0x2f, | 55 | 0x2c, 0x2d, 0x2e, 0x2f, |
58 | I2C_CLIENT_END }; | 56 | I2C_CLIENT_END }; |
@@ -357,7 +355,6 @@ static struct i2c_driver g4fan_driver = { | |||
357 | .driver = { | 355 | .driver = { |
358 | .name = "therm_windtunnel", | 356 | .name = "therm_windtunnel", |
359 | }, | 357 | }, |
360 | .id = I2C_DRIVERID_G4FAN, | ||
361 | .attach_adapter = do_attach, | 358 | .attach_adapter = do_attach, |
362 | .detach_client = do_detach, | 359 | .detach_client = do_detach, |
363 | }; | 360 | }; |
diff --git a/drivers/media/video/dpc7146.c b/drivers/media/video/dpc7146.c index 255dae303708..566e479e2629 100644 --- a/drivers/media/video/dpc7146.c +++ b/drivers/media/video/dpc7146.c | |||
@@ -87,11 +87,24 @@ struct dpc | |||
87 | int cur_input; /* current input */ | 87 | int cur_input; /* current input */ |
88 | }; | 88 | }; |
89 | 89 | ||
90 | static int dpc_check_clients(struct device *dev, void *data) | ||
91 | { | ||
92 | struct dpc* dpc = data; | ||
93 | struct i2c_client *client = i2c_verify_client(dev); | ||
94 | |||
95 | if( !client ) | ||
96 | return 0; | ||
97 | |||
98 | if( I2C_SAA7111A == client->addr ) | ||
99 | dpc->saa7111a = client; | ||
100 | |||
101 | return 0; | ||
102 | } | ||
103 | |||
90 | /* fixme: add vbi stuff here */ | 104 | /* fixme: add vbi stuff here */ |
91 | static int dpc_probe(struct saa7146_dev* dev) | 105 | static int dpc_probe(struct saa7146_dev* dev) |
92 | { | 106 | { |
93 | struct dpc* dpc = NULL; | 107 | struct dpc* dpc = NULL; |
94 | struct i2c_client *client; | ||
95 | 108 | ||
96 | dpc = kzalloc(sizeof(struct dpc), GFP_KERNEL); | 109 | dpc = kzalloc(sizeof(struct dpc), GFP_KERNEL); |
97 | if( NULL == dpc ) { | 110 | if( NULL == dpc ) { |
@@ -115,9 +128,7 @@ static int dpc_probe(struct saa7146_dev* dev) | |||
115 | } | 128 | } |
116 | 129 | ||
117 | /* loop through all i2c-devices on the bus and look who is there */ | 130 | /* loop through all i2c-devices on the bus and look who is there */ |
118 | list_for_each_entry(client, &dpc->i2c_adapter.clients, list) | 131 | device_for_each_child(&dpc->i2c_adapter.dev, dpc, dpc_check_clients); |
119 | if( I2C_SAA7111A == client->addr ) | ||
120 | dpc->saa7111a = client; | ||
121 | 132 | ||
122 | /* check if all devices are present */ | 133 | /* check if all devices are present */ |
123 | if( 0 == dpc->saa7111a ) { | 134 | if( 0 == dpc->saa7111a ) { |
diff --git a/drivers/media/video/ks0127.c b/drivers/media/video/ks0127.c index b6cd21e6dab9..4895540be195 100644 --- a/drivers/media/video/ks0127.c +++ b/drivers/media/video/ks0127.c | |||
@@ -764,7 +764,6 @@ static struct i2c_client ks0127_client_tmpl = | |||
764 | .addr = 0, | 764 | .addr = 0, |
765 | .adapter = NULL, | 765 | .adapter = NULL, |
766 | .driver = &i2c_driver_ks0127, | 766 | .driver = &i2c_driver_ks0127, |
767 | .usage_count = 0 | ||
768 | }; | 767 | }; |
769 | 768 | ||
770 | static int ks0127_found_proc(struct i2c_adapter *adapter, int addr, int kind) | 769 | static int ks0127_found_proc(struct i2c_adapter *adapter, int addr, int kind) |
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c index 98ad3092a079..add6d0d680be 100644 --- a/drivers/media/video/mxb.c +++ b/drivers/media/video/mxb.c | |||
@@ -149,10 +149,33 @@ struct mxb | |||
149 | 149 | ||
150 | static struct saa7146_extension extension; | 150 | static struct saa7146_extension extension; |
151 | 151 | ||
152 | static int mxb_check_clients(struct device *dev, void *data) | ||
153 | { | ||
154 | struct mxb* mxb = data; | ||
155 | struct i2c_client *client = i2c_verify_client(dev); | ||
156 | |||
157 | if( !client ) | ||
158 | return 0; | ||
159 | |||
160 | if( I2C_ADDR_TEA6420_1 == client->addr ) | ||
161 | mxb->tea6420_1 = client; | ||
162 | if( I2C_ADDR_TEA6420_2 == client->addr ) | ||
163 | mxb->tea6420_2 = client; | ||
164 | if( I2C_TEA6415C_2 == client->addr ) | ||
165 | mxb->tea6415c = client; | ||
166 | if( I2C_ADDR_TDA9840 == client->addr ) | ||
167 | mxb->tda9840 = client; | ||
168 | if( I2C_SAA7111 == client->addr ) | ||
169 | mxb->saa7111a = client; | ||
170 | if( 0x60 == client->addr ) | ||
171 | mxb->tuner = client; | ||
172 | |||
173 | return 0; | ||
174 | } | ||
175 | |||
152 | static int mxb_probe(struct saa7146_dev* dev) | 176 | static int mxb_probe(struct saa7146_dev* dev) |
153 | { | 177 | { |
154 | struct mxb* mxb = NULL; | 178 | struct mxb* mxb = NULL; |
155 | struct i2c_client *client; | ||
156 | int result; | 179 | int result; |
157 | 180 | ||
158 | if ((result = request_module("saa7111")) < 0) { | 181 | if ((result = request_module("saa7111")) < 0) { |
@@ -195,20 +218,7 @@ static int mxb_probe(struct saa7146_dev* dev) | |||
195 | } | 218 | } |
196 | 219 | ||
197 | /* loop through all i2c-devices on the bus and look who is there */ | 220 | /* loop through all i2c-devices on the bus and look who is there */ |
198 | list_for_each_entry(client, &mxb->i2c_adapter.clients, list) { | 221 | device_for_each_child(&mxb->i2c_adapter.dev, mxb, mxb_check_clients); |
199 | if( I2C_ADDR_TEA6420_1 == client->addr ) | ||
200 | mxb->tea6420_1 = client; | ||
201 | if( I2C_ADDR_TEA6420_2 == client->addr ) | ||
202 | mxb->tea6420_2 = client; | ||
203 | if( I2C_TEA6415C_2 == client->addr ) | ||
204 | mxb->tea6415c = client; | ||
205 | if( I2C_ADDR_TDA9840 == client->addr ) | ||
206 | mxb->tda9840 = client; | ||
207 | if( I2C_SAA7111 == client->addr ) | ||
208 | mxb->saa7111a = client; | ||
209 | if( 0x60 == client->addr ) | ||
210 | mxb->tuner = client; | ||
211 | } | ||
212 | 222 | ||
213 | /* check if all devices are present */ | 223 | /* check if all devices are present */ |
214 | if( 0 == mxb->tea6420_1 || 0 == mxb->tea6420_2 || 0 == mxb->tea6415c | 224 | if( 0 == mxb->tea6420_1 || 0 == mxb->tea6420_2 || 0 == mxb->tea6415c |
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c index 9a03dc82c6ca..5bb75294b5aa 100644 --- a/drivers/media/video/vino.c +++ b/drivers/media/video/vino.c | |||
@@ -2589,11 +2589,7 @@ static int vino_acquire_input(struct vino_channel_settings *vcs) | |||
2589 | /* First try D1 and then SAA7191 */ | 2589 | /* First try D1 and then SAA7191 */ |
2590 | if (vino_drvdata->camera.driver | 2590 | if (vino_drvdata->camera.driver |
2591 | && (vino_drvdata->camera.owner == VINO_NO_CHANNEL)) { | 2591 | && (vino_drvdata->camera.owner == VINO_NO_CHANNEL)) { |
2592 | if (i2c_use_client(vino_drvdata->camera.driver)) { | 2592 | i2c_use_client(vino_drvdata->camera.driver); |
2593 | ret = -ENODEV; | ||
2594 | goto out; | ||
2595 | } | ||
2596 | |||
2597 | vino_drvdata->camera.owner = vcs->channel; | 2593 | vino_drvdata->camera.owner = vcs->channel; |
2598 | vcs->input = VINO_INPUT_D1; | 2594 | vcs->input = VINO_INPUT_D1; |
2599 | vcs->data_norm = VINO_DATA_NORM_D1; | 2595 | vcs->data_norm = VINO_DATA_NORM_D1; |
@@ -2602,11 +2598,7 @@ static int vino_acquire_input(struct vino_channel_settings *vcs) | |||
2602 | int input, data_norm; | 2598 | int input, data_norm; |
2603 | int saa7191_input; | 2599 | int saa7191_input; |
2604 | 2600 | ||
2605 | if (i2c_use_client(vino_drvdata->decoder.driver)) { | 2601 | i2c_use_client(vino_drvdata->decoder.driver); |
2606 | ret = -ENODEV; | ||
2607 | goto out; | ||
2608 | } | ||
2609 | |||
2610 | input = VINO_INPUT_COMPOSITE; | 2602 | input = VINO_INPUT_COMPOSITE; |
2611 | 2603 | ||
2612 | saa7191_input = vino_get_saa7191_input(input); | 2604 | saa7191_input = vino_get_saa7191_input(input); |
@@ -2688,10 +2680,7 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input) | |||
2688 | } | 2680 | } |
2689 | 2681 | ||
2690 | if (vino_drvdata->decoder.owner == VINO_NO_CHANNEL) { | 2682 | if (vino_drvdata->decoder.owner == VINO_NO_CHANNEL) { |
2691 | if (i2c_use_client(vino_drvdata->decoder.driver)) { | 2683 | i2c_use_client(vino_drvdata->decoder.driver); |
2692 | ret = -ENODEV; | ||
2693 | goto out; | ||
2694 | } | ||
2695 | vino_drvdata->decoder.owner = vcs->channel; | 2684 | vino_drvdata->decoder.owner = vcs->channel; |
2696 | } | 2685 | } |
2697 | 2686 | ||
@@ -2759,10 +2748,7 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input) | |||
2759 | } | 2748 | } |
2760 | 2749 | ||
2761 | if (vino_drvdata->camera.owner == VINO_NO_CHANNEL) { | 2750 | if (vino_drvdata->camera.owner == VINO_NO_CHANNEL) { |
2762 | if (i2c_use_client(vino_drvdata->camera.driver)) { | 2751 | i2c_use_client(vino_drvdata->camera.driver); |
2763 | ret = -ENODEV; | ||
2764 | goto out; | ||
2765 | } | ||
2766 | vino_drvdata->camera.owner = vcs->channel; | 2752 | vino_drvdata->camera.owner = vcs->channel; |
2767 | } | 2753 | } |
2768 | 2754 | ||
diff --git a/drivers/mfd/ucb1x00-assabet.c b/drivers/mfd/ucb1x00-assabet.c index b7c8e7813865..61aeaf79640d 100644 --- a/drivers/mfd/ucb1x00-assabet.c +++ b/drivers/mfd/ucb1x00-assabet.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include "ucb1x00.h" | 20 | #include "ucb1x00.h" |
21 | 21 | ||
22 | #define UCB1X00_ATTR(name,input)\ | 22 | #define UCB1X00_ATTR(name,input)\ |
23 | static ssize_t name##_show(struct device *dev, struct device_attribute *attr, | 23 | static ssize_t name##_show(struct device *dev, struct device_attribute *attr, \ |
24 | char *buf) \ | 24 | char *buf) \ |
25 | { \ | 25 | { \ |
26 | struct ucb1x00 *ucb = classdev_to_ucb1x00(dev); \ | 26 | struct ucb1x00 *ucb = classdev_to_ucb1x00(dev); \ |
@@ -38,17 +38,17 @@ UCB1X00_ATTR(batt_temp, UCB_ADC_INP_AD2); | |||
38 | 38 | ||
39 | static int ucb1x00_assabet_add(struct ucb1x00_dev *dev) | 39 | static int ucb1x00_assabet_add(struct ucb1x00_dev *dev) |
40 | { | 40 | { |
41 | device_create_file(&dev->ucb->dev, &device_attr_vbatt); | 41 | device_create_file(&dev->ucb->dev, &dev_attr_vbatt); |
42 | device_create_file(&dev->ucb->dev, &device_attr_vcharger); | 42 | device_create_file(&dev->ucb->dev, &dev_attr_vcharger); |
43 | device_create_file(&dev->ucb->dev, &device_attr_batt_temp); | 43 | device_create_file(&dev->ucb->dev, &dev_attr_batt_temp); |
44 | return 0; | 44 | return 0; |
45 | } | 45 | } |
46 | 46 | ||
47 | static void ucb1x00_assabet_remove(struct ucb1x00_dev *dev) | 47 | static void ucb1x00_assabet_remove(struct ucb1x00_dev *dev) |
48 | { | 48 | { |
49 | device_remove_file(&dev->ucb->cdev, &device_attr_batt_temp); | 49 | device_remove_file(&dev->ucb->dev, &dev_attr_batt_temp); |
50 | device_remove_file(&dev->ucb->cdev, &device_attr_vcharger); | 50 | device_remove_file(&dev->ucb->dev, &dev_attr_vcharger); |
51 | device_remove_file(&dev->ucb->cdev, &device_attr_vbatt); | 51 | device_remove_file(&dev->ucb->dev, &dev_attr_vbatt); |
52 | } | 52 | } |
53 | 53 | ||
54 | static struct ucb1x00_driver ucb1x00_assabet_driver = { | 54 | static struct ucb1x00_driver ucb1x00_assabet_driver = { |
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index 971e18b91f4a..c9dfeb15b487 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/mmc/card.h> | 25 | #include <linux/mmc/card.h> |
26 | #include <linux/clk.h> | 26 | #include <linux/clk.h> |
27 | #include <linux/scatterlist.h> | 27 | #include <linux/scatterlist.h> |
28 | #include <linux/i2c/tps65010.h> | ||
28 | 29 | ||
29 | #include <asm/io.h> | 30 | #include <asm/io.h> |
30 | #include <asm/irq.h> | 31 | #include <asm/irq.h> |
@@ -35,7 +36,6 @@ | |||
35 | #include <asm/arch/dma.h> | 36 | #include <asm/arch/dma.h> |
36 | #include <asm/arch/mux.h> | 37 | #include <asm/arch/mux.h> |
37 | #include <asm/arch/fpga.h> | 38 | #include <asm/arch/fpga.h> |
38 | #include <asm/arch/tps65010.h> | ||
39 | 39 | ||
40 | #define OMAP_MMC_REG_CMD 0x00 | 40 | #define OMAP_MMC_REG_CMD 0x00 |
41 | #define OMAP_MMC_REG_ARGL 0x04 | 41 | #define OMAP_MMC_REG_ARGL 0x04 |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 9af05a2f4af3..a6728661c416 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -212,7 +212,7 @@ config MII | |||
212 | 212 | ||
213 | config MACB | 213 | config MACB |
214 | tristate "Atmel MACB support" | 214 | tristate "Atmel MACB support" |
215 | depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 | 215 | depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 || ARCH_AT91CAP9 |
216 | select PHYLIB | 216 | select PHYLIB |
217 | help | 217 | help |
218 | The Atmel MACB ethernet interface is found on many AT32 and AT91 | 218 | The Atmel MACB ethernet interface is found on many AT32 and AT91 |
diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c index dfef1637bfb8..e0900ca678ec 100644 --- a/drivers/rtc/rtc-ds1672.c +++ b/drivers/rtc/rtc-ds1672.c | |||
@@ -16,7 +16,7 @@ | |||
16 | #define DRV_VERSION "0.3" | 16 | #define DRV_VERSION "0.3" |
17 | 17 | ||
18 | /* Addresses to scan: none. This chip cannot be detected. */ | 18 | /* Addresses to scan: none. This chip cannot be detected. */ |
19 | static unsigned short normal_i2c[] = { I2C_CLIENT_END }; | 19 | static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; |
20 | 20 | ||
21 | /* Insmod parameters */ | 21 | /* Insmod parameters */ |
22 | I2C_CLIENT_INSMOD; | 22 | I2C_CLIENT_INSMOD; |
diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index 1c743641b73b..725b0c73c333 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c | |||
@@ -61,7 +61,7 @@ | |||
61 | /* i2c configuration */ | 61 | /* i2c configuration */ |
62 | #define ISL1208_I2C_ADDR 0xde | 62 | #define ISL1208_I2C_ADDR 0xde |
63 | 63 | ||
64 | static unsigned short normal_i2c[] = { | 64 | static const unsigned short normal_i2c[] = { |
65 | ISL1208_I2C_ADDR>>1, I2C_CLIENT_END | 65 | ISL1208_I2C_ADDR>>1, I2C_CLIENT_END |
66 | }; | 66 | }; |
67 | I2C_CLIENT_INSMOD; /* defines addr_data */ | 67 | I2C_CLIENT_INSMOD; /* defines addr_data */ |
diff --git a/drivers/rtc/rtc-max6900.c b/drivers/rtc/rtc-max6900.c index a1cd448639c9..7683412970c4 100644 --- a/drivers/rtc/rtc-max6900.c +++ b/drivers/rtc/rtc-max6900.c | |||
@@ -54,7 +54,7 @@ | |||
54 | 54 | ||
55 | #define MAX6900_I2C_ADDR 0xa0 | 55 | #define MAX6900_I2C_ADDR 0xa0 |
56 | 56 | ||
57 | static unsigned short normal_i2c[] = { | 57 | static const unsigned short normal_i2c[] = { |
58 | MAX6900_I2C_ADDR >> 1, | 58 | MAX6900_I2C_ADDR >> 1, |
59 | I2C_CLIENT_END | 59 | I2C_CLIENT_END |
60 | }; | 60 | }; |
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index 0242d803ebe5..b3317fcc16c3 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c | |||
@@ -25,7 +25,7 @@ | |||
25 | * located at 0x51 will pass the validation routine due to | 25 | * located at 0x51 will pass the validation routine due to |
26 | * the way the registers are implemented. | 26 | * the way the registers are implemented. |
27 | */ | 27 | */ |
28 | static unsigned short normal_i2c[] = { I2C_CLIENT_END }; | 28 | static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; |
29 | 29 | ||
30 | /* Module parameters */ | 30 | /* Module parameters */ |
31 | I2C_CLIENT_INSMOD; | 31 | I2C_CLIENT_INSMOD; |
diff --git a/drivers/rtc/rtc-pcf8583.c b/drivers/rtc/rtc-pcf8583.c index 556d0e7da35b..c973ba94c422 100644 --- a/drivers/rtc/rtc-pcf8583.c +++ b/drivers/rtc/rtc-pcf8583.c | |||
@@ -40,7 +40,7 @@ struct pcf8583 { | |||
40 | #define CTRL_ALARM 0x02 | 40 | #define CTRL_ALARM 0x02 |
41 | #define CTRL_TIMER 0x01 | 41 | #define CTRL_TIMER 0x01 |
42 | 42 | ||
43 | static unsigned short normal_i2c[] = { 0x50, I2C_CLIENT_END }; | 43 | static const unsigned short normal_i2c[] = { 0x50, I2C_CLIENT_END }; |
44 | 44 | ||
45 | /* Module parameters */ | 45 | /* Module parameters */ |
46 | I2C_CLIENT_INSMOD; | 46 | I2C_CLIENT_INSMOD; |
diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c index b3fae357ca49..b90fb1866ce9 100644 --- a/drivers/rtc/rtc-x1205.c +++ b/drivers/rtc/rtc-x1205.c | |||
@@ -32,7 +32,7 @@ | |||
32 | * unknown chips, the user must explicitly set the probe parameter. | 32 | * unknown chips, the user must explicitly set the probe parameter. |
33 | */ | 33 | */ |
34 | 34 | ||
35 | static unsigned short normal_i2c[] = { I2C_CLIENT_END }; | 35 | static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; |
36 | 36 | ||
37 | /* Insmod parameters */ | 37 | /* Insmod parameters */ |
38 | I2C_CLIENT_INSMOD; | 38 | I2C_CLIENT_INSMOD; |
diff --git a/drivers/s390/block/Makefile b/drivers/s390/block/Makefile index be9f22d52fd8..0a89e080b389 100644 --- a/drivers/s390/block/Makefile +++ b/drivers/s390/block/Makefile | |||
@@ -2,8 +2,8 @@ | |||
2 | # S/390 block devices | 2 | # S/390 block devices |
3 | # | 3 | # |
4 | 4 | ||
5 | dasd_eckd_mod-objs := dasd_eckd.o dasd_3990_erp.o dasd_9343_erp.o | 5 | dasd_eckd_mod-objs := dasd_eckd.o dasd_3990_erp.o dasd_alias.o |
6 | dasd_fba_mod-objs := dasd_fba.o dasd_3370_erp.o dasd_9336_erp.o | 6 | dasd_fba_mod-objs := dasd_fba.o |
7 | dasd_diag_mod-objs := dasd_diag.o | 7 | dasd_diag_mod-objs := dasd_diag.o |
8 | dasd_mod-objs := dasd.o dasd_ioctl.o dasd_proc.o dasd_devmap.o \ | 8 | dasd_mod-objs := dasd.o dasd_ioctl.o dasd_proc.o dasd_devmap.o \ |
9 | dasd_genhd.o dasd_erp.o | 9 | dasd_genhd.o dasd_erp.o |
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index e6bfce690ca3..1db15f3e5d20 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -48,13 +48,15 @@ MODULE_LICENSE("GPL"); | |||
48 | /* | 48 | /* |
49 | * SECTION: prototypes for static functions of dasd.c | 49 | * SECTION: prototypes for static functions of dasd.c |
50 | */ | 50 | */ |
51 | static int dasd_alloc_queue(struct dasd_device * device); | 51 | static int dasd_alloc_queue(struct dasd_block *); |
52 | static void dasd_setup_queue(struct dasd_device * device); | 52 | static void dasd_setup_queue(struct dasd_block *); |
53 | static void dasd_free_queue(struct dasd_device * device); | 53 | static void dasd_free_queue(struct dasd_block *); |
54 | static void dasd_flush_request_queue(struct dasd_device *); | 54 | static void dasd_flush_request_queue(struct dasd_block *); |
55 | static int dasd_flush_ccw_queue(struct dasd_device *, int); | 55 | static int dasd_flush_block_queue(struct dasd_block *); |
56 | static void dasd_tasklet(struct dasd_device *); | 56 | static void dasd_device_tasklet(struct dasd_device *); |
57 | static void dasd_block_tasklet(struct dasd_block *); | ||
57 | static void do_kick_device(struct work_struct *); | 58 | static void do_kick_device(struct work_struct *); |
59 | static void dasd_return_cqr_cb(struct dasd_ccw_req *, void *); | ||
58 | 60 | ||
59 | /* | 61 | /* |
60 | * SECTION: Operations on the device structure. | 62 | * SECTION: Operations on the device structure. |
@@ -65,26 +67,23 @@ static wait_queue_head_t dasd_flush_wq; | |||
65 | /* | 67 | /* |
66 | * Allocate memory for a new device structure. | 68 | * Allocate memory for a new device structure. |
67 | */ | 69 | */ |
68 | struct dasd_device * | 70 | struct dasd_device *dasd_alloc_device(void) |
69 | dasd_alloc_device(void) | ||
70 | { | 71 | { |
71 | struct dasd_device *device; | 72 | struct dasd_device *device; |
72 | 73 | ||
73 | device = kzalloc(sizeof (struct dasd_device), GFP_ATOMIC); | 74 | device = kzalloc(sizeof(struct dasd_device), GFP_ATOMIC); |
74 | if (device == NULL) | 75 | if (!device) |
75 | return ERR_PTR(-ENOMEM); | 76 | return ERR_PTR(-ENOMEM); |
76 | /* open_count = 0 means device online but not in use */ | ||
77 | atomic_set(&device->open_count, -1); | ||
78 | 77 | ||
79 | /* Get two pages for normal block device operations. */ | 78 | /* Get two pages for normal block device operations. */ |
80 | device->ccw_mem = (void *) __get_free_pages(GFP_ATOMIC | GFP_DMA, 1); | 79 | device->ccw_mem = (void *) __get_free_pages(GFP_ATOMIC | GFP_DMA, 1); |
81 | if (device->ccw_mem == NULL) { | 80 | if (!device->ccw_mem) { |
82 | kfree(device); | 81 | kfree(device); |
83 | return ERR_PTR(-ENOMEM); | 82 | return ERR_PTR(-ENOMEM); |
84 | } | 83 | } |
85 | /* Get one page for error recovery. */ | 84 | /* Get one page for error recovery. */ |
86 | device->erp_mem = (void *) get_zeroed_page(GFP_ATOMIC | GFP_DMA); | 85 | device->erp_mem = (void *) get_zeroed_page(GFP_ATOMIC | GFP_DMA); |
87 | if (device->erp_mem == NULL) { | 86 | if (!device->erp_mem) { |
88 | free_pages((unsigned long) device->ccw_mem, 1); | 87 | free_pages((unsigned long) device->ccw_mem, 1); |
89 | kfree(device); | 88 | kfree(device); |
90 | return ERR_PTR(-ENOMEM); | 89 | return ERR_PTR(-ENOMEM); |
@@ -93,10 +92,9 @@ dasd_alloc_device(void) | |||
93 | dasd_init_chunklist(&device->ccw_chunks, device->ccw_mem, PAGE_SIZE*2); | 92 | dasd_init_chunklist(&device->ccw_chunks, device->ccw_mem, PAGE_SIZE*2); |
94 | dasd_init_chunklist(&device->erp_chunks, device->erp_mem, PAGE_SIZE); | 93 | dasd_init_chunklist(&device->erp_chunks, device->erp_mem, PAGE_SIZE); |
95 | spin_lock_init(&device->mem_lock); | 94 | spin_lock_init(&device->mem_lock); |
96 | spin_lock_init(&device->request_queue_lock); | 95 | atomic_set(&device->tasklet_scheduled, 0); |
97 | atomic_set (&device->tasklet_scheduled, 0); | ||
98 | tasklet_init(&device->tasklet, | 96 | tasklet_init(&device->tasklet, |
99 | (void (*)(unsigned long)) dasd_tasklet, | 97 | (void (*)(unsigned long)) dasd_device_tasklet, |
100 | (unsigned long) device); | 98 | (unsigned long) device); |
101 | INIT_LIST_HEAD(&device->ccw_queue); | 99 | INIT_LIST_HEAD(&device->ccw_queue); |
102 | init_timer(&device->timer); | 100 | init_timer(&device->timer); |
@@ -110,8 +108,7 @@ dasd_alloc_device(void) | |||
110 | /* | 108 | /* |
111 | * Free memory of a device structure. | 109 | * Free memory of a device structure. |
112 | */ | 110 | */ |
113 | void | 111 | void dasd_free_device(struct dasd_device *device) |
114 | dasd_free_device(struct dasd_device *device) | ||
115 | { | 112 | { |
116 | kfree(device->private); | 113 | kfree(device->private); |
117 | free_page((unsigned long) device->erp_mem); | 114 | free_page((unsigned long) device->erp_mem); |
@@ -120,10 +117,42 @@ dasd_free_device(struct dasd_device *device) | |||
120 | } | 117 | } |
121 | 118 | ||
122 | /* | 119 | /* |
120 | * Allocate memory for a new device structure. | ||
121 | */ | ||
122 | struct dasd_block *dasd_alloc_block(void) | ||
123 | { | ||
124 | struct dasd_block *block; | ||
125 | |||
126 | block = kzalloc(sizeof(*block), GFP_ATOMIC); | ||
127 | if (!block) | ||
128 | return ERR_PTR(-ENOMEM); | ||
129 | /* open_count = 0 means device online but not in use */ | ||
130 | atomic_set(&block->open_count, -1); | ||
131 | |||
132 | spin_lock_init(&block->request_queue_lock); | ||
133 | atomic_set(&block->tasklet_scheduled, 0); | ||
134 | tasklet_init(&block->tasklet, | ||
135 | (void (*)(unsigned long)) dasd_block_tasklet, | ||
136 | (unsigned long) block); | ||
137 | INIT_LIST_HEAD(&block->ccw_queue); | ||
138 | spin_lock_init(&block->queue_lock); | ||
139 | init_timer(&block->timer); | ||
140 | |||
141 | return block; | ||
142 | } | ||
143 | |||
144 | /* | ||
145 | * Free memory of a device structure. | ||
146 | */ | ||
147 | void dasd_free_block(struct dasd_block *block) | ||
148 | { | ||
149 | kfree(block); | ||
150 | } | ||
151 | |||
152 | /* | ||
123 | * Make a new device known to the system. | 153 | * Make a new device known to the system. |
124 | */ | 154 | */ |
125 | static int | 155 | static int dasd_state_new_to_known(struct dasd_device *device) |
126 | dasd_state_new_to_known(struct dasd_device *device) | ||
127 | { | 156 | { |
128 | int rc; | 157 | int rc; |
129 | 158 | ||
@@ -133,12 +162,13 @@ dasd_state_new_to_known(struct dasd_device *device) | |||
133 | */ | 162 | */ |
134 | dasd_get_device(device); | 163 | dasd_get_device(device); |
135 | 164 | ||
136 | rc = dasd_alloc_queue(device); | 165 | if (device->block) { |
137 | if (rc) { | 166 | rc = dasd_alloc_queue(device->block); |
138 | dasd_put_device(device); | 167 | if (rc) { |
139 | return rc; | 168 | dasd_put_device(device); |
169 | return rc; | ||
170 | } | ||
140 | } | 171 | } |
141 | |||
142 | device->state = DASD_STATE_KNOWN; | 172 | device->state = DASD_STATE_KNOWN; |
143 | return 0; | 173 | return 0; |
144 | } | 174 | } |
@@ -146,21 +176,24 @@ dasd_state_new_to_known(struct dasd_device *device) | |||
146 | /* | 176 | /* |
147 | * Let the system forget about a device. | 177 | * Let the system forget about a device. |
148 | */ | 178 | */ |
149 | static int | 179 | static int dasd_state_known_to_new(struct dasd_device *device) |
150 | dasd_state_known_to_new(struct dasd_device * device) | ||
151 | { | 180 | { |
152 | /* Disable extended error reporting for this device. */ | 181 | /* Disable extended error reporting for this device. */ |
153 | dasd_eer_disable(device); | 182 | dasd_eer_disable(device); |
154 | /* Forget the discipline information. */ | 183 | /* Forget the discipline information. */ |
155 | if (device->discipline) | 184 | if (device->discipline) { |
185 | if (device->discipline->uncheck_device) | ||
186 | device->discipline->uncheck_device(device); | ||
156 | module_put(device->discipline->owner); | 187 | module_put(device->discipline->owner); |
188 | } | ||
157 | device->discipline = NULL; | 189 | device->discipline = NULL; |
158 | if (device->base_discipline) | 190 | if (device->base_discipline) |
159 | module_put(device->base_discipline->owner); | 191 | module_put(device->base_discipline->owner); |
160 | device->base_discipline = NULL; | 192 | device->base_discipline = NULL; |
161 | device->state = DASD_STATE_NEW; | 193 | device->state = DASD_STATE_NEW; |
162 | 194 | ||
163 | dasd_free_queue(device); | 195 | if (device->block) |
196 | dasd_free_queue(device->block); | ||
164 | 197 | ||
165 | /* Give up reference we took in dasd_state_new_to_known. */ | 198 | /* Give up reference we took in dasd_state_new_to_known. */ |
166 | dasd_put_device(device); | 199 | dasd_put_device(device); |
@@ -170,19 +203,19 @@ dasd_state_known_to_new(struct dasd_device * device) | |||
170 | /* | 203 | /* |
171 | * Request the irq line for the device. | 204 | * Request the irq line for the device. |
172 | */ | 205 | */ |
173 | static int | 206 | static int dasd_state_known_to_basic(struct dasd_device *device) |
174 | dasd_state_known_to_basic(struct dasd_device * device) | ||
175 | { | 207 | { |
176 | int rc; | 208 | int rc; |
177 | 209 | ||
178 | /* Allocate and register gendisk structure. */ | 210 | /* Allocate and register gendisk structure. */ |
179 | rc = dasd_gendisk_alloc(device); | 211 | if (device->block) { |
180 | if (rc) | 212 | rc = dasd_gendisk_alloc(device->block); |
181 | return rc; | 213 | if (rc) |
182 | 214 | return rc; | |
215 | } | ||
183 | /* register 'device' debug area, used for all DBF_DEV_XXX calls */ | 216 | /* register 'device' debug area, used for all DBF_DEV_XXX calls */ |
184 | device->debug_area = debug_register(device->cdev->dev.bus_id, 1, 2, | 217 | device->debug_area = debug_register(device->cdev->dev.bus_id, 1, 1, |
185 | 8 * sizeof (long)); | 218 | 8 * sizeof(long)); |
186 | debug_register_view(device->debug_area, &debug_sprintf_view); | 219 | debug_register_view(device->debug_area, &debug_sprintf_view); |
187 | debug_set_level(device->debug_area, DBF_WARNING); | 220 | debug_set_level(device->debug_area, DBF_WARNING); |
188 | DBF_DEV_EVENT(DBF_EMERG, device, "%s", "debug area created"); | 221 | DBF_DEV_EVENT(DBF_EMERG, device, "%s", "debug area created"); |
@@ -194,16 +227,17 @@ dasd_state_known_to_basic(struct dasd_device * device) | |||
194 | /* | 227 | /* |
195 | * Release the irq line for the device. Terminate any running i/o. | 228 | * Release the irq line for the device. Terminate any running i/o. |
196 | */ | 229 | */ |
197 | static int | 230 | static int dasd_state_basic_to_known(struct dasd_device *device) |
198 | dasd_state_basic_to_known(struct dasd_device * device) | ||
199 | { | 231 | { |
200 | int rc; | 232 | int rc; |
201 | 233 | if (device->block) { | |
202 | dasd_gendisk_free(device); | 234 | dasd_gendisk_free(device->block); |
203 | rc = dasd_flush_ccw_queue(device, 1); | 235 | dasd_block_clear_timer(device->block); |
236 | } | ||
237 | rc = dasd_flush_device_queue(device); | ||
204 | if (rc) | 238 | if (rc) |
205 | return rc; | 239 | return rc; |
206 | dasd_clear_timer(device); | 240 | dasd_device_clear_timer(device); |
207 | 241 | ||
208 | DBF_DEV_EVENT(DBF_EMERG, device, "%p debug area deleted", device); | 242 | DBF_DEV_EVENT(DBF_EMERG, device, "%p debug area deleted", device); |
209 | if (device->debug_area != NULL) { | 243 | if (device->debug_area != NULL) { |
@@ -228,26 +262,32 @@ dasd_state_basic_to_known(struct dasd_device * device) | |||
228 | * In case the analysis returns an error, the device setup is stopped | 262 | * In case the analysis returns an error, the device setup is stopped |
229 | * (a fake disk was already added to allow formatting). | 263 | * (a fake disk was already added to allow formatting). |
230 | */ | 264 | */ |
231 | static int | 265 | static int dasd_state_basic_to_ready(struct dasd_device *device) |
232 | dasd_state_basic_to_ready(struct dasd_device * device) | ||
233 | { | 266 | { |
234 | int rc; | 267 | int rc; |
268 | struct dasd_block *block; | ||
235 | 269 | ||
236 | rc = 0; | 270 | rc = 0; |
237 | if (device->discipline->do_analysis != NULL) | 271 | block = device->block; |
238 | rc = device->discipline->do_analysis(device); | ||
239 | if (rc) { | ||
240 | if (rc != -EAGAIN) | ||
241 | device->state = DASD_STATE_UNFMT; | ||
242 | return rc; | ||
243 | } | ||
244 | /* make disk known with correct capacity */ | 272 | /* make disk known with correct capacity */ |
245 | dasd_setup_queue(device); | 273 | if (block) { |
246 | set_capacity(device->gdp, device->blocks << device->s2b_shift); | 274 | if (block->base->discipline->do_analysis != NULL) |
247 | device->state = DASD_STATE_READY; | 275 | rc = block->base->discipline->do_analysis(block); |
248 | rc = dasd_scan_partitions(device); | 276 | if (rc) { |
249 | if (rc) | 277 | if (rc != -EAGAIN) |
250 | device->state = DASD_STATE_BASIC; | 278 | device->state = DASD_STATE_UNFMT; |
279 | return rc; | ||
280 | } | ||
281 | dasd_setup_queue(block); | ||
282 | set_capacity(block->gdp, | ||
283 | block->blocks << block->s2b_shift); | ||
284 | device->state = DASD_STATE_READY; | ||
285 | rc = dasd_scan_partitions(block); | ||
286 | if (rc) | ||
287 | device->state = DASD_STATE_BASIC; | ||
288 | } else { | ||
289 | device->state = DASD_STATE_READY; | ||
290 | } | ||
251 | return rc; | 291 | return rc; |
252 | } | 292 | } |
253 | 293 | ||
@@ -256,28 +296,31 @@ dasd_state_basic_to_ready(struct dasd_device * device) | |||
256 | * Forget format information. Check if the target level is basic | 296 | * Forget format information. Check if the target level is basic |
257 | * and if it is create fake disk for formatting. | 297 | * and if it is create fake disk for formatting. |
258 | */ | 298 | */ |
259 | static int | 299 | static int dasd_state_ready_to_basic(struct dasd_device *device) |
260 | dasd_state_ready_to_basic(struct dasd_device * device) | ||
261 | { | 300 | { |
262 | int rc; | 301 | int rc; |
263 | 302 | ||
264 | rc = dasd_flush_ccw_queue(device, 0); | ||
265 | if (rc) | ||
266 | return rc; | ||
267 | dasd_destroy_partitions(device); | ||
268 | dasd_flush_request_queue(device); | ||
269 | device->blocks = 0; | ||
270 | device->bp_block = 0; | ||
271 | device->s2b_shift = 0; | ||
272 | device->state = DASD_STATE_BASIC; | 303 | device->state = DASD_STATE_BASIC; |
304 | if (device->block) { | ||
305 | struct dasd_block *block = device->block; | ||
306 | rc = dasd_flush_block_queue(block); | ||
307 | if (rc) { | ||
308 | device->state = DASD_STATE_READY; | ||
309 | return rc; | ||
310 | } | ||
311 | dasd_destroy_partitions(block); | ||
312 | dasd_flush_request_queue(block); | ||
313 | block->blocks = 0; | ||
314 | block->bp_block = 0; | ||
315 | block->s2b_shift = 0; | ||
316 | } | ||
273 | return 0; | 317 | return 0; |
274 | } | 318 | } |
275 | 319 | ||
276 | /* | 320 | /* |
277 | * Back to basic. | 321 | * Back to basic. |
278 | */ | 322 | */ |
279 | static int | 323 | static int dasd_state_unfmt_to_basic(struct dasd_device *device) |
280 | dasd_state_unfmt_to_basic(struct dasd_device * device) | ||
281 | { | 324 | { |
282 | device->state = DASD_STATE_BASIC; | 325 | device->state = DASD_STATE_BASIC; |
283 | return 0; | 326 | return 0; |
@@ -291,17 +334,31 @@ dasd_state_unfmt_to_basic(struct dasd_device * device) | |||
291 | static int | 334 | static int |
292 | dasd_state_ready_to_online(struct dasd_device * device) | 335 | dasd_state_ready_to_online(struct dasd_device * device) |
293 | { | 336 | { |
337 | int rc; | ||
338 | |||
339 | if (device->discipline->ready_to_online) { | ||
340 | rc = device->discipline->ready_to_online(device); | ||
341 | if (rc) | ||
342 | return rc; | ||
343 | } | ||
294 | device->state = DASD_STATE_ONLINE; | 344 | device->state = DASD_STATE_ONLINE; |
295 | dasd_schedule_bh(device); | 345 | if (device->block) |
346 | dasd_schedule_block_bh(device->block); | ||
296 | return 0; | 347 | return 0; |
297 | } | 348 | } |
298 | 349 | ||
299 | /* | 350 | /* |
300 | * Stop the requeueing of requests again. | 351 | * Stop the requeueing of requests again. |
301 | */ | 352 | */ |
302 | static int | 353 | static int dasd_state_online_to_ready(struct dasd_device *device) |
303 | dasd_state_online_to_ready(struct dasd_device * device) | ||
304 | { | 354 | { |
355 | int rc; | ||
356 | |||
357 | if (device->discipline->online_to_ready) { | ||
358 | rc = device->discipline->online_to_ready(device); | ||
359 | if (rc) | ||
360 | return rc; | ||
361 | } | ||
305 | device->state = DASD_STATE_READY; | 362 | device->state = DASD_STATE_READY; |
306 | return 0; | 363 | return 0; |
307 | } | 364 | } |
@@ -309,8 +366,7 @@ dasd_state_online_to_ready(struct dasd_device * device) | |||
309 | /* | 366 | /* |
310 | * Device startup state changes. | 367 | * Device startup state changes. |
311 | */ | 368 | */ |
312 | static int | 369 | static int dasd_increase_state(struct dasd_device *device) |
313 | dasd_increase_state(struct dasd_device *device) | ||
314 | { | 370 | { |
315 | int rc; | 371 | int rc; |
316 | 372 | ||
@@ -345,8 +401,7 @@ dasd_increase_state(struct dasd_device *device) | |||
345 | /* | 401 | /* |
346 | * Device shutdown state changes. | 402 | * Device shutdown state changes. |
347 | */ | 403 | */ |
348 | static int | 404 | static int dasd_decrease_state(struct dasd_device *device) |
349 | dasd_decrease_state(struct dasd_device *device) | ||
350 | { | 405 | { |
351 | int rc; | 406 | int rc; |
352 | 407 | ||
@@ -381,8 +436,7 @@ dasd_decrease_state(struct dasd_device *device) | |||
381 | /* | 436 | /* |
382 | * This is the main startup/shutdown routine. | 437 | * This is the main startup/shutdown routine. |
383 | */ | 438 | */ |
384 | static void | 439 | static void dasd_change_state(struct dasd_device *device) |
385 | dasd_change_state(struct dasd_device *device) | ||
386 | { | 440 | { |
387 | int rc; | 441 | int rc; |
388 | 442 | ||
@@ -409,17 +463,15 @@ dasd_change_state(struct dasd_device *device) | |||
409 | * dasd_kick_device will schedule a call do do_kick_device to the kernel | 463 | * dasd_kick_device will schedule a call do do_kick_device to the kernel |
410 | * event daemon. | 464 | * event daemon. |
411 | */ | 465 | */ |
412 | static void | 466 | static void do_kick_device(struct work_struct *work) |
413 | do_kick_device(struct work_struct *work) | ||
414 | { | 467 | { |
415 | struct dasd_device *device = container_of(work, struct dasd_device, kick_work); | 468 | struct dasd_device *device = container_of(work, struct dasd_device, kick_work); |
416 | dasd_change_state(device); | 469 | dasd_change_state(device); |
417 | dasd_schedule_bh(device); | 470 | dasd_schedule_device_bh(device); |
418 | dasd_put_device(device); | 471 | dasd_put_device(device); |
419 | } | 472 | } |
420 | 473 | ||
421 | void | 474 | void dasd_kick_device(struct dasd_device *device) |
422 | dasd_kick_device(struct dasd_device *device) | ||
423 | { | 475 | { |
424 | dasd_get_device(device); | 476 | dasd_get_device(device); |
425 | /* queue call to dasd_kick_device to the kernel event daemon. */ | 477 | /* queue call to dasd_kick_device to the kernel event daemon. */ |
@@ -429,8 +481,7 @@ dasd_kick_device(struct dasd_device *device) | |||
429 | /* | 481 | /* |
430 | * Set the target state for a device and starts the state change. | 482 | * Set the target state for a device and starts the state change. |
431 | */ | 483 | */ |
432 | void | 484 | void dasd_set_target_state(struct dasd_device *device, int target) |
433 | dasd_set_target_state(struct dasd_device *device, int target) | ||
434 | { | 485 | { |
435 | /* If we are in probeonly mode stop at DASD_STATE_READY. */ | 486 | /* If we are in probeonly mode stop at DASD_STATE_READY. */ |
436 | if (dasd_probeonly && target > DASD_STATE_READY) | 487 | if (dasd_probeonly && target > DASD_STATE_READY) |
@@ -447,14 +498,12 @@ dasd_set_target_state(struct dasd_device *device, int target) | |||
447 | /* | 498 | /* |
448 | * Enable devices with device numbers in [from..to]. | 499 | * Enable devices with device numbers in [from..to]. |
449 | */ | 500 | */ |
450 | static inline int | 501 | static inline int _wait_for_device(struct dasd_device *device) |
451 | _wait_for_device(struct dasd_device *device) | ||
452 | { | 502 | { |
453 | return (device->state == device->target); | 503 | return (device->state == device->target); |
454 | } | 504 | } |
455 | 505 | ||
456 | void | 506 | void dasd_enable_device(struct dasd_device *device) |
457 | dasd_enable_device(struct dasd_device *device) | ||
458 | { | 507 | { |
459 | dasd_set_target_state(device, DASD_STATE_ONLINE); | 508 | dasd_set_target_state(device, DASD_STATE_ONLINE); |
460 | if (device->state <= DASD_STATE_KNOWN) | 509 | if (device->state <= DASD_STATE_KNOWN) |
@@ -475,20 +524,20 @@ unsigned int dasd_profile_level = DASD_PROFILE_OFF; | |||
475 | /* | 524 | /* |
476 | * Increments counter in global and local profiling structures. | 525 | * Increments counter in global and local profiling structures. |
477 | */ | 526 | */ |
478 | #define dasd_profile_counter(value, counter, device) \ | 527 | #define dasd_profile_counter(value, counter, block) \ |
479 | { \ | 528 | { \ |
480 | int index; \ | 529 | int index; \ |
481 | for (index = 0; index < 31 && value >> (2+index); index++); \ | 530 | for (index = 0; index < 31 && value >> (2+index); index++); \ |
482 | dasd_global_profile.counter[index]++; \ | 531 | dasd_global_profile.counter[index]++; \ |
483 | device->profile.counter[index]++; \ | 532 | block->profile.counter[index]++; \ |
484 | } | 533 | } |
485 | 534 | ||
486 | /* | 535 | /* |
487 | * Add profiling information for cqr before execution. | 536 | * Add profiling information for cqr before execution. |
488 | */ | 537 | */ |
489 | static void | 538 | static void dasd_profile_start(struct dasd_block *block, |
490 | dasd_profile_start(struct dasd_device *device, struct dasd_ccw_req * cqr, | 539 | struct dasd_ccw_req *cqr, |
491 | struct request *req) | 540 | struct request *req) |
492 | { | 541 | { |
493 | struct list_head *l; | 542 | struct list_head *l; |
494 | unsigned int counter; | 543 | unsigned int counter; |
@@ -498,19 +547,19 @@ dasd_profile_start(struct dasd_device *device, struct dasd_ccw_req * cqr, | |||
498 | 547 | ||
499 | /* count the length of the chanq for statistics */ | 548 | /* count the length of the chanq for statistics */ |
500 | counter = 0; | 549 | counter = 0; |
501 | list_for_each(l, &device->ccw_queue) | 550 | list_for_each(l, &block->ccw_queue) |
502 | if (++counter >= 31) | 551 | if (++counter >= 31) |
503 | break; | 552 | break; |
504 | dasd_global_profile.dasd_io_nr_req[counter]++; | 553 | dasd_global_profile.dasd_io_nr_req[counter]++; |
505 | device->profile.dasd_io_nr_req[counter]++; | 554 | block->profile.dasd_io_nr_req[counter]++; |
506 | } | 555 | } |
507 | 556 | ||
508 | /* | 557 | /* |
509 | * Add profiling information for cqr after execution. | 558 | * Add profiling information for cqr after execution. |
510 | */ | 559 | */ |
511 | static void | 560 | static void dasd_profile_end(struct dasd_block *block, |
512 | dasd_profile_end(struct dasd_device *device, struct dasd_ccw_req * cqr, | 561 | struct dasd_ccw_req *cqr, |
513 | struct request *req) | 562 | struct request *req) |
514 | { | 563 | { |
515 | long strtime, irqtime, endtime, tottime; /* in microseconds */ | 564 | long strtime, irqtime, endtime, tottime; /* in microseconds */ |
516 | long tottimeps, sectors; | 565 | long tottimeps, sectors; |
@@ -532,27 +581,27 @@ dasd_profile_end(struct dasd_device *device, struct dasd_ccw_req * cqr, | |||
532 | 581 | ||
533 | if (!dasd_global_profile.dasd_io_reqs) | 582 | if (!dasd_global_profile.dasd_io_reqs) |
534 | memset(&dasd_global_profile, 0, | 583 | memset(&dasd_global_profile, 0, |
535 | sizeof (struct dasd_profile_info_t)); | 584 | sizeof(struct dasd_profile_info_t)); |
536 | dasd_global_profile.dasd_io_reqs++; | 585 | dasd_global_profile.dasd_io_reqs++; |
537 | dasd_global_profile.dasd_io_sects += sectors; | 586 | dasd_global_profile.dasd_io_sects += sectors; |
538 | 587 | ||
539 | if (!device->profile.dasd_io_reqs) | 588 | if (!block->profile.dasd_io_reqs) |
540 | memset(&device->profile, 0, | 589 | memset(&block->profile, 0, |
541 | sizeof (struct dasd_profile_info_t)); | 590 | sizeof(struct dasd_profile_info_t)); |
542 | device->profile.dasd_io_reqs++; | 591 | block->profile.dasd_io_reqs++; |
543 | device->profile.dasd_io_sects += sectors; | 592 | block->profile.dasd_io_sects += sectors; |
544 | 593 | ||
545 | dasd_profile_counter(sectors, dasd_io_secs, device); | 594 | dasd_profile_counter(sectors, dasd_io_secs, block); |
546 | dasd_profile_counter(tottime, dasd_io_times, device); | 595 | dasd_profile_counter(tottime, dasd_io_times, block); |
547 | dasd_profile_counter(tottimeps, dasd_io_timps, device); | 596 | dasd_profile_counter(tottimeps, dasd_io_timps, block); |
548 | dasd_profile_counter(strtime, dasd_io_time1, device); | 597 | dasd_profile_counter(strtime, dasd_io_time1, block); |
549 | dasd_profile_counter(irqtime, dasd_io_time2, device); | 598 | dasd_profile_counter(irqtime, dasd_io_time2, block); |
550 | dasd_profile_counter(irqtime / sectors, dasd_io_time2ps, device); | 599 | dasd_profile_counter(irqtime / sectors, dasd_io_time2ps, block); |
551 | dasd_profile_counter(endtime, dasd_io_time3, device); | 600 | dasd_profile_counter(endtime, dasd_io_time3, block); |
552 | } | 601 | } |
553 | #else | 602 | #else |
554 | #define dasd_profile_start(device, cqr, req) do {} while (0) | 603 | #define dasd_profile_start(block, cqr, req) do {} while (0) |
555 | #define dasd_profile_end(device, cqr, req) do {} while (0) | 604 | #define dasd_profile_end(block, cqr, req) do {} while (0) |
556 | #endif /* CONFIG_DASD_PROFILE */ | 605 | #endif /* CONFIG_DASD_PROFILE */ |
557 | 606 | ||
558 | /* | 607 | /* |
@@ -562,9 +611,9 @@ dasd_profile_end(struct dasd_device *device, struct dasd_ccw_req * cqr, | |||
562 | * memory and 2) dasd_smalloc_request uses the static ccw memory | 611 | * memory and 2) dasd_smalloc_request uses the static ccw memory |
563 | * that gets allocated for each device. | 612 | * that gets allocated for each device. |
564 | */ | 613 | */ |
565 | struct dasd_ccw_req * | 614 | struct dasd_ccw_req *dasd_kmalloc_request(char *magic, int cplength, |
566 | dasd_kmalloc_request(char *magic, int cplength, int datasize, | 615 | int datasize, |
567 | struct dasd_device * device) | 616 | struct dasd_device *device) |
568 | { | 617 | { |
569 | struct dasd_ccw_req *cqr; | 618 | struct dasd_ccw_req *cqr; |
570 | 619 | ||
@@ -600,9 +649,9 @@ dasd_kmalloc_request(char *magic, int cplength, int datasize, | |||
600 | return cqr; | 649 | return cqr; |
601 | } | 650 | } |
602 | 651 | ||
603 | struct dasd_ccw_req * | 652 | struct dasd_ccw_req *dasd_smalloc_request(char *magic, int cplength, |
604 | dasd_smalloc_request(char *magic, int cplength, int datasize, | 653 | int datasize, |
605 | struct dasd_device * device) | 654 | struct dasd_device *device) |
606 | { | 655 | { |
607 | unsigned long flags; | 656 | unsigned long flags; |
608 | struct dasd_ccw_req *cqr; | 657 | struct dasd_ccw_req *cqr; |
@@ -649,8 +698,7 @@ dasd_smalloc_request(char *magic, int cplength, int datasize, | |||
649 | * idal lists that might have been created by dasd_set_cda and the | 698 | * idal lists that might have been created by dasd_set_cda and the |
650 | * struct dasd_ccw_req itself. | 699 | * struct dasd_ccw_req itself. |
651 | */ | 700 | */ |
652 | void | 701 | void dasd_kfree_request(struct dasd_ccw_req *cqr, struct dasd_device *device) |
653 | dasd_kfree_request(struct dasd_ccw_req * cqr, struct dasd_device * device) | ||
654 | { | 702 | { |
655 | #ifdef CONFIG_64BIT | 703 | #ifdef CONFIG_64BIT |
656 | struct ccw1 *ccw; | 704 | struct ccw1 *ccw; |
@@ -667,8 +715,7 @@ dasd_kfree_request(struct dasd_ccw_req * cqr, struct dasd_device * device) | |||
667 | dasd_put_device(device); | 715 | dasd_put_device(device); |
668 | } | 716 | } |
669 | 717 | ||
670 | void | 718 | void dasd_sfree_request(struct dasd_ccw_req *cqr, struct dasd_device *device) |
671 | dasd_sfree_request(struct dasd_ccw_req * cqr, struct dasd_device * device) | ||
672 | { | 719 | { |
673 | unsigned long flags; | 720 | unsigned long flags; |
674 | 721 | ||
@@ -681,14 +728,13 @@ dasd_sfree_request(struct dasd_ccw_req * cqr, struct dasd_device * device) | |||
681 | /* | 728 | /* |
682 | * Check discipline magic in cqr. | 729 | * Check discipline magic in cqr. |
683 | */ | 730 | */ |
684 | static inline int | 731 | static inline int dasd_check_cqr(struct dasd_ccw_req *cqr) |
685 | dasd_check_cqr(struct dasd_ccw_req *cqr) | ||
686 | { | 732 | { |
687 | struct dasd_device *device; | 733 | struct dasd_device *device; |
688 | 734 | ||
689 | if (cqr == NULL) | 735 | if (cqr == NULL) |
690 | return -EINVAL; | 736 | return -EINVAL; |
691 | device = cqr->device; | 737 | device = cqr->startdev; |
692 | if (strncmp((char *) &cqr->magic, device->discipline->ebcname, 4)) { | 738 | if (strncmp((char *) &cqr->magic, device->discipline->ebcname, 4)) { |
693 | DEV_MESSAGE(KERN_WARNING, device, | 739 | DEV_MESSAGE(KERN_WARNING, device, |
694 | " dasd_ccw_req 0x%08x magic doesn't match" | 740 | " dasd_ccw_req 0x%08x magic doesn't match" |
@@ -706,8 +752,7 @@ dasd_check_cqr(struct dasd_ccw_req *cqr) | |||
706 | * ccw_device_clear can fail if the i/o subsystem | 752 | * ccw_device_clear can fail if the i/o subsystem |
707 | * is in a bad mood. | 753 | * is in a bad mood. |
708 | */ | 754 | */ |
709 | int | 755 | int dasd_term_IO(struct dasd_ccw_req *cqr) |
710 | dasd_term_IO(struct dasd_ccw_req * cqr) | ||
711 | { | 756 | { |
712 | struct dasd_device *device; | 757 | struct dasd_device *device; |
713 | int retries, rc; | 758 | int retries, rc; |
@@ -717,13 +762,13 @@ dasd_term_IO(struct dasd_ccw_req * cqr) | |||
717 | if (rc) | 762 | if (rc) |
718 | return rc; | 763 | return rc; |
719 | retries = 0; | 764 | retries = 0; |
720 | device = (struct dasd_device *) cqr->device; | 765 | device = (struct dasd_device *) cqr->startdev; |
721 | while ((retries < 5) && (cqr->status == DASD_CQR_IN_IO)) { | 766 | while ((retries < 5) && (cqr->status == DASD_CQR_IN_IO)) { |
722 | rc = ccw_device_clear(device->cdev, (long) cqr); | 767 | rc = ccw_device_clear(device->cdev, (long) cqr); |
723 | switch (rc) { | 768 | switch (rc) { |
724 | case 0: /* termination successful */ | 769 | case 0: /* termination successful */ |
725 | cqr->retries--; | 770 | cqr->retries--; |
726 | cqr->status = DASD_CQR_CLEAR; | 771 | cqr->status = DASD_CQR_CLEAR_PENDING; |
727 | cqr->stopclk = get_clock(); | 772 | cqr->stopclk = get_clock(); |
728 | cqr->starttime = 0; | 773 | cqr->starttime = 0; |
729 | DBF_DEV_EVENT(DBF_DEBUG, device, | 774 | DBF_DEV_EVENT(DBF_DEBUG, device, |
@@ -753,7 +798,7 @@ dasd_term_IO(struct dasd_ccw_req * cqr) | |||
753 | } | 798 | } |
754 | retries++; | 799 | retries++; |
755 | } | 800 | } |
756 | dasd_schedule_bh(device); | 801 | dasd_schedule_device_bh(device); |
757 | return rc; | 802 | return rc; |
758 | } | 803 | } |
759 | 804 | ||
@@ -761,8 +806,7 @@ dasd_term_IO(struct dasd_ccw_req * cqr) | |||
761 | * Start the i/o. This start_IO can fail if the channel is really busy. | 806 | * Start the i/o. This start_IO can fail if the channel is really busy. |
762 | * In that case set up a timer to start the request later. | 807 | * In that case set up a timer to start the request later. |
763 | */ | 808 | */ |
764 | int | 809 | int dasd_start_IO(struct dasd_ccw_req *cqr) |
765 | dasd_start_IO(struct dasd_ccw_req * cqr) | ||
766 | { | 810 | { |
767 | struct dasd_device *device; | 811 | struct dasd_device *device; |
768 | int rc; | 812 | int rc; |
@@ -771,12 +815,12 @@ dasd_start_IO(struct dasd_ccw_req * cqr) | |||
771 | rc = dasd_check_cqr(cqr); | 815 | rc = dasd_check_cqr(cqr); |
772 | if (rc) | 816 | if (rc) |
773 | return rc; | 817 | return rc; |
774 | device = (struct dasd_device *) cqr->device; | 818 | device = (struct dasd_device *) cqr->startdev; |
775 | if (cqr->retries < 0) { | 819 | if (cqr->retries < 0) { |
776 | DEV_MESSAGE(KERN_DEBUG, device, | 820 | DEV_MESSAGE(KERN_DEBUG, device, |
777 | "start_IO: request %p (%02x/%i) - no retry left.", | 821 | "start_IO: request %p (%02x/%i) - no retry left.", |
778 | cqr, cqr->status, cqr->retries); | 822 | cqr, cqr->status, cqr->retries); |
779 | cqr->status = DASD_CQR_FAILED; | 823 | cqr->status = DASD_CQR_ERROR; |
780 | return -EIO; | 824 | return -EIO; |
781 | } | 825 | } |
782 | cqr->startclk = get_clock(); | 826 | cqr->startclk = get_clock(); |
@@ -833,8 +877,7 @@ dasd_start_IO(struct dasd_ccw_req * cqr) | |||
833 | * The head of the ccw queue will have status DASD_CQR_IN_IO for 1), | 877 | * The head of the ccw queue will have status DASD_CQR_IN_IO for 1), |
834 | * DASD_CQR_QUEUED for 2) and 3). | 878 | * DASD_CQR_QUEUED for 2) and 3). |
835 | */ | 879 | */ |
836 | static void | 880 | static void dasd_device_timeout(unsigned long ptr) |
837 | dasd_timeout_device(unsigned long ptr) | ||
838 | { | 881 | { |
839 | unsigned long flags; | 882 | unsigned long flags; |
840 | struct dasd_device *device; | 883 | struct dasd_device *device; |
@@ -844,14 +887,13 @@ dasd_timeout_device(unsigned long ptr) | |||
844 | /* re-activate request queue */ | 887 | /* re-activate request queue */ |
845 | device->stopped &= ~DASD_STOPPED_PENDING; | 888 | device->stopped &= ~DASD_STOPPED_PENDING; |
846 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); | 889 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); |
847 | dasd_schedule_bh(device); | 890 | dasd_schedule_device_bh(device); |
848 | } | 891 | } |
849 | 892 | ||
850 | /* | 893 | /* |
851 | * Setup timeout for a device in jiffies. | 894 | * Setup timeout for a device in jiffies. |
852 | */ | 895 | */ |
853 | void | 896 | void dasd_device_set_timer(struct dasd_device *device, int expires) |
854 | dasd_set_timer(struct dasd_device *device, int expires) | ||
855 | { | 897 | { |
856 | if (expires == 0) { | 898 | if (expires == 0) { |
857 | if (timer_pending(&device->timer)) | 899 | if (timer_pending(&device->timer)) |
@@ -862,7 +904,7 @@ dasd_set_timer(struct dasd_device *device, int expires) | |||
862 | if (mod_timer(&device->timer, jiffies + expires)) | 904 | if (mod_timer(&device->timer, jiffies + expires)) |
863 | return; | 905 | return; |
864 | } | 906 | } |
865 | device->timer.function = dasd_timeout_device; | 907 | device->timer.function = dasd_device_timeout; |
866 | device->timer.data = (unsigned long) device; | 908 | device->timer.data = (unsigned long) device; |
867 | device->timer.expires = jiffies + expires; | 909 | device->timer.expires = jiffies + expires; |
868 | add_timer(&device->timer); | 910 | add_timer(&device->timer); |
@@ -871,15 +913,14 @@ dasd_set_timer(struct dasd_device *device, int expires) | |||
871 | /* | 913 | /* |
872 | * Clear timeout for a device. | 914 | * Clear timeout for a device. |
873 | */ | 915 | */ |
874 | void | 916 | void dasd_device_clear_timer(struct dasd_device *device) |
875 | dasd_clear_timer(struct dasd_device *device) | ||
876 | { | 917 | { |
877 | if (timer_pending(&device->timer)) | 918 | if (timer_pending(&device->timer)) |
878 | del_timer(&device->timer); | 919 | del_timer(&device->timer); |
879 | } | 920 | } |
880 | 921 | ||
881 | static void | 922 | static void dasd_handle_killed_request(struct ccw_device *cdev, |
882 | dasd_handle_killed_request(struct ccw_device *cdev, unsigned long intparm) | 923 | unsigned long intparm) |
883 | { | 924 | { |
884 | struct dasd_ccw_req *cqr; | 925 | struct dasd_ccw_req *cqr; |
885 | struct dasd_device *device; | 926 | struct dasd_device *device; |
@@ -893,7 +934,7 @@ dasd_handle_killed_request(struct ccw_device *cdev, unsigned long intparm) | |||
893 | return; | 934 | return; |
894 | } | 935 | } |
895 | 936 | ||
896 | device = (struct dasd_device *) cqr->device; | 937 | device = (struct dasd_device *) cqr->startdev; |
897 | if (device == NULL || | 938 | if (device == NULL || |
898 | device != dasd_device_from_cdev_locked(cdev) || | 939 | device != dasd_device_from_cdev_locked(cdev) || |
899 | strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) { | 940 | strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) { |
@@ -905,46 +946,32 @@ dasd_handle_killed_request(struct ccw_device *cdev, unsigned long intparm) | |||
905 | /* Schedule request to be retried. */ | 946 | /* Schedule request to be retried. */ |
906 | cqr->status = DASD_CQR_QUEUED; | 947 | cqr->status = DASD_CQR_QUEUED; |
907 | 948 | ||
908 | dasd_clear_timer(device); | 949 | dasd_device_clear_timer(device); |
909 | dasd_schedule_bh(device); | 950 | dasd_schedule_device_bh(device); |
910 | dasd_put_device(device); | 951 | dasd_put_device(device); |
911 | } | 952 | } |
912 | 953 | ||
913 | static void | 954 | void dasd_generic_handle_state_change(struct dasd_device *device) |
914 | dasd_handle_state_change_pending(struct dasd_device *device) | ||
915 | { | 955 | { |
916 | struct dasd_ccw_req *cqr; | ||
917 | struct list_head *l, *n; | ||
918 | |||
919 | /* First of all start sense subsystem status request. */ | 956 | /* First of all start sense subsystem status request. */ |
920 | dasd_eer_snss(device); | 957 | dasd_eer_snss(device); |
921 | 958 | ||
922 | device->stopped &= ~DASD_STOPPED_PENDING; | 959 | device->stopped &= ~DASD_STOPPED_PENDING; |
923 | 960 | dasd_schedule_device_bh(device); | |
924 | /* restart all 'running' IO on queue */ | 961 | if (device->block) |
925 | list_for_each_safe(l, n, &device->ccw_queue) { | 962 | dasd_schedule_block_bh(device->block); |
926 | cqr = list_entry(l, struct dasd_ccw_req, list); | ||
927 | if (cqr->status == DASD_CQR_IN_IO) { | ||
928 | cqr->status = DASD_CQR_QUEUED; | ||
929 | } | ||
930 | } | ||
931 | dasd_clear_timer(device); | ||
932 | dasd_schedule_bh(device); | ||
933 | } | 963 | } |
934 | 964 | ||
935 | /* | 965 | /* |
936 | * Interrupt handler for "normal" ssch-io based dasd devices. | 966 | * Interrupt handler for "normal" ssch-io based dasd devices. |
937 | */ | 967 | */ |
938 | void | 968 | void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, |
939 | dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, | 969 | struct irb *irb) |
940 | struct irb *irb) | ||
941 | { | 970 | { |
942 | struct dasd_ccw_req *cqr, *next; | 971 | struct dasd_ccw_req *cqr, *next; |
943 | struct dasd_device *device; | 972 | struct dasd_device *device; |
944 | unsigned long long now; | 973 | unsigned long long now; |
945 | int expires; | 974 | int expires; |
946 | dasd_era_t era; | ||
947 | char mask; | ||
948 | 975 | ||
949 | if (IS_ERR(irb)) { | 976 | if (IS_ERR(irb)) { |
950 | switch (PTR_ERR(irb)) { | 977 | switch (PTR_ERR(irb)) { |
@@ -969,29 +996,25 @@ dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, | |||
969 | cdev->dev.bus_id, ((irb->scsw.cstat<<8)|irb->scsw.dstat), | 996 | cdev->dev.bus_id, ((irb->scsw.cstat<<8)|irb->scsw.dstat), |
970 | (unsigned int) intparm); | 997 | (unsigned int) intparm); |
971 | 998 | ||
972 | /* first of all check for state change pending interrupt */ | 999 | /* check for unsolicited interrupts */ |
973 | mask = DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP; | 1000 | cqr = (struct dasd_ccw_req *) intparm; |
974 | if ((irb->scsw.dstat & mask) == mask) { | 1001 | if (!cqr || ((irb->scsw.cc == 1) && |
1002 | (irb->scsw.fctl & SCSW_FCTL_START_FUNC) && | ||
1003 | (irb->scsw.stctl & SCSW_STCTL_STATUS_PEND)) ) { | ||
1004 | if (cqr && cqr->status == DASD_CQR_IN_IO) | ||
1005 | cqr->status = DASD_CQR_QUEUED; | ||
975 | device = dasd_device_from_cdev_locked(cdev); | 1006 | device = dasd_device_from_cdev_locked(cdev); |
976 | if (!IS_ERR(device)) { | 1007 | if (!IS_ERR(device)) { |
977 | dasd_handle_state_change_pending(device); | 1008 | dasd_device_clear_timer(device); |
1009 | device->discipline->handle_unsolicited_interrupt(device, | ||
1010 | irb); | ||
978 | dasd_put_device(device); | 1011 | dasd_put_device(device); |
979 | } | 1012 | } |
980 | return; | 1013 | return; |
981 | } | 1014 | } |
982 | 1015 | ||
983 | cqr = (struct dasd_ccw_req *) intparm; | 1016 | device = (struct dasd_device *) cqr->startdev; |
984 | 1017 | if (!device || | |
985 | /* check for unsolicited interrupts */ | ||
986 | if (cqr == NULL) { | ||
987 | MESSAGE(KERN_DEBUG, | ||
988 | "unsolicited interrupt received: bus_id %s", | ||
989 | cdev->dev.bus_id); | ||
990 | return; | ||
991 | } | ||
992 | |||
993 | device = (struct dasd_device *) cqr->device; | ||
994 | if (device == NULL || | ||
995 | strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) { | 1018 | strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) { |
996 | MESSAGE(KERN_DEBUG, "invalid device in request: bus_id %s", | 1019 | MESSAGE(KERN_DEBUG, "invalid device in request: bus_id %s", |
997 | cdev->dev.bus_id); | 1020 | cdev->dev.bus_id); |
@@ -999,12 +1022,12 @@ dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, | |||
999 | } | 1022 | } |
1000 | 1023 | ||
1001 | /* Check for clear pending */ | 1024 | /* Check for clear pending */ |
1002 | if (cqr->status == DASD_CQR_CLEAR && | 1025 | if (cqr->status == DASD_CQR_CLEAR_PENDING && |
1003 | irb->scsw.fctl & SCSW_FCTL_CLEAR_FUNC) { | 1026 | irb->scsw.fctl & SCSW_FCTL_CLEAR_FUNC) { |
1004 | cqr->status = DASD_CQR_QUEUED; | 1027 | cqr->status = DASD_CQR_CLEARED; |
1005 | dasd_clear_timer(device); | 1028 | dasd_device_clear_timer(device); |
1006 | wake_up(&dasd_flush_wq); | 1029 | wake_up(&dasd_flush_wq); |
1007 | dasd_schedule_bh(device); | 1030 | dasd_schedule_device_bh(device); |
1008 | return; | 1031 | return; |
1009 | } | 1032 | } |
1010 | 1033 | ||
@@ -1017,277 +1040,170 @@ dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, | |||
1017 | } | 1040 | } |
1018 | DBF_DEV_EVENT(DBF_DEBUG, device, "Int: CS/DS 0x%04x for cqr %p", | 1041 | DBF_DEV_EVENT(DBF_DEBUG, device, "Int: CS/DS 0x%04x for cqr %p", |
1019 | ((irb->scsw.cstat << 8) | irb->scsw.dstat), cqr); | 1042 | ((irb->scsw.cstat << 8) | irb->scsw.dstat), cqr); |
1020 | 1043 | next = NULL; | |
1021 | /* Find out the appropriate era_action. */ | ||
1022 | if (irb->scsw.fctl & SCSW_FCTL_HALT_FUNC) | ||
1023 | era = dasd_era_fatal; | ||
1024 | else if (irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) && | ||
1025 | irb->scsw.cstat == 0 && | ||
1026 | !irb->esw.esw0.erw.cons) | ||
1027 | era = dasd_era_none; | ||
1028 | else if (irb->esw.esw0.erw.cons) | ||
1029 | era = device->discipline->examine_error(cqr, irb); | ||
1030 | else | ||
1031 | era = dasd_era_recover; | ||
1032 | |||
1033 | DBF_DEV_EVENT(DBF_DEBUG, device, "era_code %d", era); | ||
1034 | expires = 0; | 1044 | expires = 0; |
1035 | if (era == dasd_era_none) { | 1045 | if (irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) && |
1036 | cqr->status = DASD_CQR_DONE; | 1046 | irb->scsw.cstat == 0 && !irb->esw.esw0.erw.cons) { |
1047 | /* request was completed successfully */ | ||
1048 | cqr->status = DASD_CQR_SUCCESS; | ||
1037 | cqr->stopclk = now; | 1049 | cqr->stopclk = now; |
1038 | /* Start first request on queue if possible -> fast_io. */ | 1050 | /* Start first request on queue if possible -> fast_io. */ |
1039 | if (cqr->list.next != &device->ccw_queue) { | 1051 | if (cqr->devlist.next != &device->ccw_queue) { |
1040 | next = list_entry(cqr->list.next, | 1052 | next = list_entry(cqr->devlist.next, |
1041 | struct dasd_ccw_req, list); | 1053 | struct dasd_ccw_req, devlist); |
1042 | if ((next->status == DASD_CQR_QUEUED) && | ||
1043 | (!device->stopped)) { | ||
1044 | if (device->discipline->start_IO(next) == 0) | ||
1045 | expires = next->expires; | ||
1046 | else | ||
1047 | DEV_MESSAGE(KERN_DEBUG, device, "%s", | ||
1048 | "Interrupt fastpath " | ||
1049 | "failed!"); | ||
1050 | } | ||
1051 | } | 1054 | } |
1052 | } else { /* error */ | 1055 | } else { /* error */ |
1053 | memcpy(&cqr->irb, irb, sizeof (struct irb)); | 1056 | memcpy(&cqr->irb, irb, sizeof(struct irb)); |
1054 | if (device->features & DASD_FEATURE_ERPLOG) { | 1057 | if (device->features & DASD_FEATURE_ERPLOG) { |
1055 | /* dump sense data */ | ||
1056 | dasd_log_sense(cqr, irb); | 1058 | dasd_log_sense(cqr, irb); |
1057 | } | 1059 | } |
1058 | switch (era) { | 1060 | /* If we have no sense data, or we just don't want complex ERP |
1059 | case dasd_era_fatal: | 1061 | * for this request, but if we have retries left, then just |
1060 | cqr->status = DASD_CQR_FAILED; | 1062 | * reset this request and retry it in the fastpath |
1061 | cqr->stopclk = now; | 1063 | */ |
1062 | break; | 1064 | if (!(cqr->irb.esw.esw0.erw.cons && |
1063 | case dasd_era_recover: | 1065 | test_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags)) && |
1066 | cqr->retries > 0) { | ||
1067 | DEV_MESSAGE(KERN_DEBUG, device, | ||
1068 | "default ERP in fastpath (%i retries left)", | ||
1069 | cqr->retries); | ||
1070 | cqr->lpm = LPM_ANYPATH; | ||
1071 | cqr->status = DASD_CQR_QUEUED; | ||
1072 | next = cqr; | ||
1073 | } else | ||
1064 | cqr->status = DASD_CQR_ERROR; | 1074 | cqr->status = DASD_CQR_ERROR; |
1065 | break; | 1075 | } |
1066 | default: | 1076 | if (next && (next->status == DASD_CQR_QUEUED) && |
1067 | BUG(); | 1077 | (!device->stopped)) { |
1068 | } | 1078 | if (device->discipline->start_IO(next) == 0) |
1079 | expires = next->expires; | ||
1080 | else | ||
1081 | DEV_MESSAGE(KERN_DEBUG, device, "%s", | ||
1082 | "Interrupt fastpath " | ||
1083 | "failed!"); | ||
1069 | } | 1084 | } |
1070 | if (expires != 0) | 1085 | if (expires != 0) |
1071 | dasd_set_timer(device, expires); | 1086 | dasd_device_set_timer(device, expires); |
1072 | else | 1087 | else |
1073 | dasd_clear_timer(device); | 1088 | dasd_device_clear_timer(device); |
1074 | dasd_schedule_bh(device); | 1089 | dasd_schedule_device_bh(device); |
1075 | } | 1090 | } |
1076 | 1091 | ||
1077 | /* | 1092 | /* |
1078 | * posts the buffer_cache about a finalized request | 1093 | * If we have an error on a dasd_block layer request then we cancel |
1094 | * and return all further requests from the same dasd_block as well. | ||
1079 | */ | 1095 | */ |
1080 | static inline void | 1096 | static void __dasd_device_recovery(struct dasd_device *device, |
1081 | dasd_end_request(struct request *req, int uptodate) | 1097 | struct dasd_ccw_req *ref_cqr) |
1082 | { | 1098 | { |
1083 | if (end_that_request_first(req, uptodate, req->hard_nr_sectors)) | 1099 | struct list_head *l, *n; |
1084 | BUG(); | 1100 | struct dasd_ccw_req *cqr; |
1085 | add_disk_randomness(req->rq_disk); | ||
1086 | end_that_request_last(req, uptodate); | ||
1087 | } | ||
1088 | 1101 | ||
1089 | /* | 1102 | /* |
1090 | * Process finished error recovery ccw. | 1103 | * only requeue request that came from the dasd_block layer |
1091 | */ | 1104 | */ |
1092 | static inline void | 1105 | if (!ref_cqr->block) |
1093 | __dasd_process_erp(struct dasd_device *device, struct dasd_ccw_req *cqr) | 1106 | return; |
1094 | { | ||
1095 | dasd_erp_fn_t erp_fn; | ||
1096 | 1107 | ||
1097 | if (cqr->status == DASD_CQR_DONE) | 1108 | list_for_each_safe(l, n, &device->ccw_queue) { |
1098 | DBF_DEV_EVENT(DBF_NOTICE, device, "%s", "ERP successful"); | 1109 | cqr = list_entry(l, struct dasd_ccw_req, devlist); |
1099 | else | 1110 | if (cqr->status == DASD_CQR_QUEUED && |
1100 | DEV_MESSAGE(KERN_ERR, device, "%s", "ERP unsuccessful"); | 1111 | ref_cqr->block == cqr->block) { |
1101 | erp_fn = device->discipline->erp_postaction(cqr); | 1112 | cqr->status = DASD_CQR_CLEARED; |
1102 | erp_fn(cqr); | 1113 | } |
1103 | } | 1114 | } |
1115 | }; | ||
1104 | 1116 | ||
1105 | /* | 1117 | /* |
1106 | * Process ccw request queue. | 1118 | * Remove those ccw requests from the queue that need to be returned |
1119 | * to the upper layer. | ||
1107 | */ | 1120 | */ |
1108 | static void | 1121 | static void __dasd_device_process_ccw_queue(struct dasd_device *device, |
1109 | __dasd_process_ccw_queue(struct dasd_device * device, | 1122 | struct list_head *final_queue) |
1110 | struct list_head *final_queue) | ||
1111 | { | 1123 | { |
1112 | struct list_head *l, *n; | 1124 | struct list_head *l, *n; |
1113 | struct dasd_ccw_req *cqr; | 1125 | struct dasd_ccw_req *cqr; |
1114 | dasd_erp_fn_t erp_fn; | ||
1115 | 1126 | ||
1116 | restart: | ||
1117 | /* Process request with final status. */ | 1127 | /* Process request with final status. */ |
1118 | list_for_each_safe(l, n, &device->ccw_queue) { | 1128 | list_for_each_safe(l, n, &device->ccw_queue) { |
1119 | cqr = list_entry(l, struct dasd_ccw_req, list); | 1129 | cqr = list_entry(l, struct dasd_ccw_req, devlist); |
1130 | |||
1120 | /* Stop list processing at the first non-final request. */ | 1131 | /* Stop list processing at the first non-final request. */ |
1121 | if (cqr->status != DASD_CQR_DONE && | 1132 | if (cqr->status == DASD_CQR_QUEUED || |
1122 | cqr->status != DASD_CQR_FAILED && | 1133 | cqr->status == DASD_CQR_IN_IO || |
1123 | cqr->status != DASD_CQR_ERROR) | 1134 | cqr->status == DASD_CQR_CLEAR_PENDING) |
1124 | break; | 1135 | break; |
1125 | /* Process requests with DASD_CQR_ERROR */ | ||
1126 | if (cqr->status == DASD_CQR_ERROR) { | 1136 | if (cqr->status == DASD_CQR_ERROR) { |
1127 | if (cqr->irb.scsw.fctl & SCSW_FCTL_HALT_FUNC) { | 1137 | __dasd_device_recovery(device, cqr); |
1128 | cqr->status = DASD_CQR_FAILED; | ||
1129 | cqr->stopclk = get_clock(); | ||
1130 | } else { | ||
1131 | if (cqr->irb.esw.esw0.erw.cons && | ||
1132 | test_bit(DASD_CQR_FLAGS_USE_ERP, | ||
1133 | &cqr->flags)) { | ||
1134 | erp_fn = device->discipline-> | ||
1135 | erp_action(cqr); | ||
1136 | erp_fn(cqr); | ||
1137 | } else | ||
1138 | dasd_default_erp_action(cqr); | ||
1139 | } | ||
1140 | goto restart; | ||
1141 | } | ||
1142 | |||
1143 | /* First of all call extended error reporting. */ | ||
1144 | if (dasd_eer_enabled(device) && | ||
1145 | cqr->status == DASD_CQR_FAILED) { | ||
1146 | dasd_eer_write(device, cqr, DASD_EER_FATALERROR); | ||
1147 | |||
1148 | /* restart request */ | ||
1149 | cqr->status = DASD_CQR_QUEUED; | ||
1150 | cqr->retries = 255; | ||
1151 | device->stopped |= DASD_STOPPED_QUIESCE; | ||
1152 | goto restart; | ||
1153 | } | 1138 | } |
1154 | |||
1155 | /* Process finished ERP request. */ | ||
1156 | if (cqr->refers) { | ||
1157 | __dasd_process_erp(device, cqr); | ||
1158 | goto restart; | ||
1159 | } | ||
1160 | |||
1161 | /* Rechain finished requests to final queue */ | 1139 | /* Rechain finished requests to final queue */ |
1162 | cqr->endclk = get_clock(); | 1140 | list_move_tail(&cqr->devlist, final_queue); |
1163 | list_move_tail(&cqr->list, final_queue); | ||
1164 | } | 1141 | } |
1165 | } | 1142 | } |
1166 | 1143 | ||
1167 | static void | ||
1168 | dasd_end_request_cb(struct dasd_ccw_req * cqr, void *data) | ||
1169 | { | ||
1170 | struct request *req; | ||
1171 | struct dasd_device *device; | ||
1172 | int status; | ||
1173 | |||
1174 | req = (struct request *) data; | ||
1175 | device = cqr->device; | ||
1176 | dasd_profile_end(device, cqr, req); | ||
1177 | status = cqr->device->discipline->free_cp(cqr,req); | ||
1178 | spin_lock_irq(&device->request_queue_lock); | ||
1179 | dasd_end_request(req, status); | ||
1180 | spin_unlock_irq(&device->request_queue_lock); | ||
1181 | } | ||
1182 | |||
1183 | |||
1184 | /* | 1144 | /* |
1185 | * Fetch requests from the block device queue. | 1145 | * the cqrs from the final queue are returned to the upper layer |
1146 | * by setting a dasd_block state and calling the callback function | ||
1186 | */ | 1147 | */ |
1187 | static void | 1148 | static void __dasd_device_process_final_queue(struct dasd_device *device, |
1188 | __dasd_process_blk_queue(struct dasd_device * device) | 1149 | struct list_head *final_queue) |
1189 | { | 1150 | { |
1190 | struct request_queue *queue; | 1151 | struct list_head *l, *n; |
1191 | struct request *req; | ||
1192 | struct dasd_ccw_req *cqr; | 1152 | struct dasd_ccw_req *cqr; |
1193 | int nr_queued; | ||
1194 | |||
1195 | queue = device->request_queue; | ||
1196 | /* No queue ? Then there is nothing to do. */ | ||
1197 | if (queue == NULL) | ||
1198 | return; | ||
1199 | |||
1200 | /* | ||
1201 | * We requeue request from the block device queue to the ccw | ||
1202 | * queue only in two states. In state DASD_STATE_READY the | ||
1203 | * partition detection is done and we need to requeue requests | ||
1204 | * for that. State DASD_STATE_ONLINE is normal block device | ||
1205 | * operation. | ||
1206 | */ | ||
1207 | if (device->state != DASD_STATE_READY && | ||
1208 | device->state != DASD_STATE_ONLINE) | ||
1209 | return; | ||
1210 | nr_queued = 0; | ||
1211 | /* Now we try to fetch requests from the request queue */ | ||
1212 | list_for_each_entry(cqr, &device->ccw_queue, list) | ||
1213 | if (cqr->status == DASD_CQR_QUEUED) | ||
1214 | nr_queued++; | ||
1215 | while (!blk_queue_plugged(queue) && | ||
1216 | elv_next_request(queue) && | ||
1217 | nr_queued < DASD_CHANQ_MAX_SIZE) { | ||
1218 | req = elv_next_request(queue); | ||
1219 | 1153 | ||
1220 | if (device->features & DASD_FEATURE_READONLY && | 1154 | list_for_each_safe(l, n, final_queue) { |
1221 | rq_data_dir(req) == WRITE) { | 1155 | cqr = list_entry(l, struct dasd_ccw_req, devlist); |
1222 | DBF_DEV_EVENT(DBF_ERR, device, | 1156 | list_del_init(&cqr->devlist); |
1223 | "Rejecting write request %p", | 1157 | if (cqr->block) |
1224 | req); | 1158 | spin_lock_bh(&cqr->block->queue_lock); |
1225 | blkdev_dequeue_request(req); | 1159 | switch (cqr->status) { |
1226 | dasd_end_request(req, 0); | 1160 | case DASD_CQR_SUCCESS: |
1227 | continue; | 1161 | cqr->status = DASD_CQR_DONE; |
1228 | } | 1162 | break; |
1229 | if (device->stopped & DASD_STOPPED_DC_EIO) { | 1163 | case DASD_CQR_ERROR: |
1230 | blkdev_dequeue_request(req); | 1164 | cqr->status = DASD_CQR_NEED_ERP; |
1231 | dasd_end_request(req, 0); | 1165 | break; |
1232 | continue; | 1166 | case DASD_CQR_CLEARED: |
1233 | } | 1167 | cqr->status = DASD_CQR_TERMINATED; |
1234 | cqr = device->discipline->build_cp(device, req); | 1168 | break; |
1235 | if (IS_ERR(cqr)) { | 1169 | default: |
1236 | if (PTR_ERR(cqr) == -ENOMEM) | 1170 | DEV_MESSAGE(KERN_ERR, device, |
1237 | break; /* terminate request queue loop */ | 1171 | "wrong cqr status in __dasd_process_final_queue " |
1238 | if (PTR_ERR(cqr) == -EAGAIN) { | 1172 | "for cqr %p, status %x", |
1239 | /* | 1173 | cqr, cqr->status); |
1240 | * The current request cannot be build right | 1174 | BUG(); |
1241 | * now, we have to try later. If this request | ||
1242 | * is the head-of-queue we stop the device | ||
1243 | * for 1/2 second. | ||
1244 | */ | ||
1245 | if (!list_empty(&device->ccw_queue)) | ||
1246 | break; | ||
1247 | device->stopped |= DASD_STOPPED_PENDING; | ||
1248 | dasd_set_timer(device, HZ/2); | ||
1249 | break; | ||
1250 | } | ||
1251 | DBF_DEV_EVENT(DBF_ERR, device, | ||
1252 | "CCW creation failed (rc=%ld) " | ||
1253 | "on request %p", | ||
1254 | PTR_ERR(cqr), req); | ||
1255 | blkdev_dequeue_request(req); | ||
1256 | dasd_end_request(req, 0); | ||
1257 | continue; | ||
1258 | } | 1175 | } |
1259 | cqr->callback = dasd_end_request_cb; | 1176 | if (cqr->block) |
1260 | cqr->callback_data = (void *) req; | 1177 | spin_unlock_bh(&cqr->block->queue_lock); |
1261 | cqr->status = DASD_CQR_QUEUED; | 1178 | if (cqr->callback != NULL) |
1262 | blkdev_dequeue_request(req); | 1179 | (cqr->callback)(cqr, cqr->callback_data); |
1263 | list_add_tail(&cqr->list, &device->ccw_queue); | ||
1264 | dasd_profile_start(device, cqr, req); | ||
1265 | nr_queued++; | ||
1266 | } | 1180 | } |
1267 | } | 1181 | } |
1268 | 1182 | ||
1183 | |||
1184 | |||
1269 | /* | 1185 | /* |
1270 | * Take a look at the first request on the ccw queue and check | 1186 | * Take a look at the first request on the ccw queue and check |
1271 | * if it reached its expire time. If so, terminate the IO. | 1187 | * if it reached its expire time. If so, terminate the IO. |
1272 | */ | 1188 | */ |
1273 | static void | 1189 | static void __dasd_device_check_expire(struct dasd_device *device) |
1274 | __dasd_check_expire(struct dasd_device * device) | ||
1275 | { | 1190 | { |
1276 | struct dasd_ccw_req *cqr; | 1191 | struct dasd_ccw_req *cqr; |
1277 | 1192 | ||
1278 | if (list_empty(&device->ccw_queue)) | 1193 | if (list_empty(&device->ccw_queue)) |
1279 | return; | 1194 | return; |
1280 | cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list); | 1195 | cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, devlist); |
1281 | if ((cqr->status == DASD_CQR_IN_IO && cqr->expires != 0) && | 1196 | if ((cqr->status == DASD_CQR_IN_IO && cqr->expires != 0) && |
1282 | (time_after_eq(jiffies, cqr->expires + cqr->starttime))) { | 1197 | (time_after_eq(jiffies, cqr->expires + cqr->starttime))) { |
1283 | if (device->discipline->term_IO(cqr) != 0) { | 1198 | if (device->discipline->term_IO(cqr) != 0) { |
1284 | /* Hmpf, try again in 5 sec */ | 1199 | /* Hmpf, try again in 5 sec */ |
1285 | dasd_set_timer(device, 5*HZ); | ||
1286 | DEV_MESSAGE(KERN_ERR, device, | 1200 | DEV_MESSAGE(KERN_ERR, device, |
1287 | "internal error - timeout (%is) expired " | 1201 | "internal error - timeout (%is) expired " |
1288 | "for cqr %p, termination failed, " | 1202 | "for cqr %p, termination failed, " |
1289 | "retrying in 5s", | 1203 | "retrying in 5s", |
1290 | (cqr->expires/HZ), cqr); | 1204 | (cqr->expires/HZ), cqr); |
1205 | cqr->expires += 5*HZ; | ||
1206 | dasd_device_set_timer(device, 5*HZ); | ||
1291 | } else { | 1207 | } else { |
1292 | DEV_MESSAGE(KERN_ERR, device, | 1208 | DEV_MESSAGE(KERN_ERR, device, |
1293 | "internal error - timeout (%is) expired " | 1209 | "internal error - timeout (%is) expired " |
@@ -1301,77 +1217,53 @@ __dasd_check_expire(struct dasd_device * device) | |||
1301 | * Take a look at the first request on the ccw queue and check | 1217 | * Take a look at the first request on the ccw queue and check |
1302 | * if it needs to be started. | 1218 | * if it needs to be started. |
1303 | */ | 1219 | */ |
1304 | static void | 1220 | static void __dasd_device_start_head(struct dasd_device *device) |
1305 | __dasd_start_head(struct dasd_device * device) | ||
1306 | { | 1221 | { |
1307 | struct dasd_ccw_req *cqr; | 1222 | struct dasd_ccw_req *cqr; |
1308 | int rc; | 1223 | int rc; |
1309 | 1224 | ||
1310 | if (list_empty(&device->ccw_queue)) | 1225 | if (list_empty(&device->ccw_queue)) |
1311 | return; | 1226 | return; |
1312 | cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list); | 1227 | cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, devlist); |
1313 | if (cqr->status != DASD_CQR_QUEUED) | 1228 | if (cqr->status != DASD_CQR_QUEUED) |
1314 | return; | 1229 | return; |
1315 | /* Non-temporary stop condition will trigger fail fast */ | 1230 | /* when device is stopped, return request to previous layer */ |
1316 | if (device->stopped & ~DASD_STOPPED_PENDING && | 1231 | if (device->stopped) { |
1317 | test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) && | 1232 | cqr->status = DASD_CQR_CLEARED; |
1318 | (!dasd_eer_enabled(device))) { | 1233 | dasd_schedule_device_bh(device); |
1319 | cqr->status = DASD_CQR_FAILED; | ||
1320 | dasd_schedule_bh(device); | ||
1321 | return; | 1234 | return; |
1322 | } | 1235 | } |
1323 | /* Don't try to start requests if device is stopped */ | ||
1324 | if (device->stopped) | ||
1325 | return; | ||
1326 | 1236 | ||
1327 | rc = device->discipline->start_IO(cqr); | 1237 | rc = device->discipline->start_IO(cqr); |
1328 | if (rc == 0) | 1238 | if (rc == 0) |
1329 | dasd_set_timer(device, cqr->expires); | 1239 | dasd_device_set_timer(device, cqr->expires); |
1330 | else if (rc == -EACCES) { | 1240 | else if (rc == -EACCES) { |
1331 | dasd_schedule_bh(device); | 1241 | dasd_schedule_device_bh(device); |
1332 | } else | 1242 | } else |
1333 | /* Hmpf, try again in 1/2 sec */ | 1243 | /* Hmpf, try again in 1/2 sec */ |
1334 | dasd_set_timer(device, 50); | 1244 | dasd_device_set_timer(device, 50); |
1335 | } | ||
1336 | |||
1337 | static inline int | ||
1338 | _wait_for_clear(struct dasd_ccw_req *cqr) | ||
1339 | { | ||
1340 | return (cqr->status == DASD_CQR_QUEUED); | ||
1341 | } | 1245 | } |
1342 | 1246 | ||
1343 | /* | 1247 | /* |
1344 | * Remove all requests from the ccw queue (all = '1') or only block device | 1248 | * Go through all request on the dasd_device request queue, |
1345 | * requests in case all = '0'. | 1249 | * terminate them on the cdev if necessary, and return them to the |
1346 | * Take care of the erp-chain (chained via cqr->refers) and remove either | 1250 | * submitting layer via callback. |
1347 | * the whole erp-chain or none of the erp-requests. | 1251 | * Note: |
1348 | * If a request is currently running, term_IO is called and the request | 1252 | * Make sure that all 'submitting layers' still exist when |
1349 | * is re-queued. Prior to removing the terminated request we need to wait | 1253 | * this function is called!. In other words, when 'device' is a base |
1350 | * for the clear-interrupt. | 1254 | * device then all block layer requests must have been removed before |
1351 | * In case termination is not possible we stop processing and just finishing | 1255 | * via dasd_flush_block_queue. |
1352 | * the already moved requests. | ||
1353 | */ | 1256 | */ |
1354 | static int | 1257 | int dasd_flush_device_queue(struct dasd_device *device) |
1355 | dasd_flush_ccw_queue(struct dasd_device * device, int all) | ||
1356 | { | 1258 | { |
1357 | struct dasd_ccw_req *cqr, *orig, *n; | 1259 | struct dasd_ccw_req *cqr, *n; |
1358 | int rc, i; | 1260 | int rc; |
1359 | |||
1360 | struct list_head flush_queue; | 1261 | struct list_head flush_queue; |
1361 | 1262 | ||
1362 | INIT_LIST_HEAD(&flush_queue); | 1263 | INIT_LIST_HEAD(&flush_queue); |
1363 | spin_lock_irq(get_ccwdev_lock(device->cdev)); | 1264 | spin_lock_irq(get_ccwdev_lock(device->cdev)); |
1364 | rc = 0; | 1265 | rc = 0; |
1365 | restart: | 1266 | list_for_each_entry_safe(cqr, n, &device->ccw_queue, devlist) { |
1366 | list_for_each_entry_safe(cqr, n, &device->ccw_queue, list) { | ||
1367 | /* get original request of erp request-chain */ | ||
1368 | for (orig = cqr; orig->refers != NULL; orig = orig->refers); | ||
1369 | |||
1370 | /* Flush all request or only block device requests? */ | ||
1371 | if (all == 0 && cqr->callback != dasd_end_request_cb && | ||
1372 | orig->callback != dasd_end_request_cb) { | ||
1373 | continue; | ||
1374 | } | ||
1375 | /* Check status and move request to flush_queue */ | 1267 | /* Check status and move request to flush_queue */ |
1376 | switch (cqr->status) { | 1268 | switch (cqr->status) { |
1377 | case DASD_CQR_IN_IO: | 1269 | case DASD_CQR_IN_IO: |
@@ -1387,90 +1279,60 @@ restart: | |||
1387 | } | 1279 | } |
1388 | break; | 1280 | break; |
1389 | case DASD_CQR_QUEUED: | 1281 | case DASD_CQR_QUEUED: |
1390 | case DASD_CQR_ERROR: | ||
1391 | /* set request to FAILED */ | ||
1392 | cqr->stopclk = get_clock(); | 1282 | cqr->stopclk = get_clock(); |
1393 | cqr->status = DASD_CQR_FAILED; | 1283 | cqr->status = DASD_CQR_CLEARED; |
1394 | break; | 1284 | break; |
1395 | default: /* do not touch the others */ | 1285 | default: /* no need to modify the others */ |
1396 | break; | 1286 | break; |
1397 | } | 1287 | } |
1398 | /* Rechain request (including erp chain) */ | 1288 | list_move_tail(&cqr->devlist, &flush_queue); |
1399 | for (i = 0; cqr != NULL; cqr = cqr->refers, i++) { | ||
1400 | cqr->endclk = get_clock(); | ||
1401 | list_move_tail(&cqr->list, &flush_queue); | ||
1402 | } | ||
1403 | if (i > 1) | ||
1404 | /* moved more than one request - need to restart */ | ||
1405 | goto restart; | ||
1406 | } | 1289 | } |
1407 | |||
1408 | finished: | 1290 | finished: |
1409 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); | 1291 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); |
1410 | /* Now call the callback function of flushed requests */ | 1292 | /* |
1411 | restart_cb: | 1293 | * After this point all requests must be in state CLEAR_PENDING, |
1412 | list_for_each_entry_safe(cqr, n, &flush_queue, list) { | 1294 | * CLEARED, SUCCESS or ERROR. Now wait for CLEAR_PENDING to become |
1413 | if (cqr->status == DASD_CQR_CLEAR) { | 1295 | * one of the others. |
1414 | /* wait for clear interrupt! */ | 1296 | */ |
1415 | wait_event(dasd_flush_wq, _wait_for_clear(cqr)); | 1297 | list_for_each_entry_safe(cqr, n, &flush_queue, devlist) |
1416 | cqr->status = DASD_CQR_FAILED; | 1298 | wait_event(dasd_flush_wq, |
1417 | } | 1299 | (cqr->status != DASD_CQR_CLEAR_PENDING)); |
1418 | /* Process finished ERP request. */ | 1300 | /* |
1419 | if (cqr->refers) { | 1301 | * Now set each request back to TERMINATED, DONE or NEED_ERP |
1420 | __dasd_process_erp(device, cqr); | 1302 | * and call the callback function of flushed requests |
1421 | /* restart list_for_xx loop since dasd_process_erp | 1303 | */ |
1422 | * might remove multiple elements */ | 1304 | __dasd_device_process_final_queue(device, &flush_queue); |
1423 | goto restart_cb; | ||
1424 | } | ||
1425 | /* call the callback function */ | ||
1426 | cqr->endclk = get_clock(); | ||
1427 | if (cqr->callback != NULL) | ||
1428 | (cqr->callback)(cqr, cqr->callback_data); | ||
1429 | } | ||
1430 | return rc; | 1305 | return rc; |
1431 | } | 1306 | } |
1432 | 1307 | ||
1433 | /* | 1308 | /* |
1434 | * Acquire the device lock and process queues for the device. | 1309 | * Acquire the device lock and process queues for the device. |
1435 | */ | 1310 | */ |
1436 | static void | 1311 | static void dasd_device_tasklet(struct dasd_device *device) |
1437 | dasd_tasklet(struct dasd_device * device) | ||
1438 | { | 1312 | { |
1439 | struct list_head final_queue; | 1313 | struct list_head final_queue; |
1440 | struct list_head *l, *n; | ||
1441 | struct dasd_ccw_req *cqr; | ||
1442 | 1314 | ||
1443 | atomic_set (&device->tasklet_scheduled, 0); | 1315 | atomic_set (&device->tasklet_scheduled, 0); |
1444 | INIT_LIST_HEAD(&final_queue); | 1316 | INIT_LIST_HEAD(&final_queue); |
1445 | spin_lock_irq(get_ccwdev_lock(device->cdev)); | 1317 | spin_lock_irq(get_ccwdev_lock(device->cdev)); |
1446 | /* Check expire time of first request on the ccw queue. */ | 1318 | /* Check expire time of first request on the ccw queue. */ |
1447 | __dasd_check_expire(device); | 1319 | __dasd_device_check_expire(device); |
1448 | /* Finish off requests on ccw queue */ | 1320 | /* find final requests on ccw queue */ |
1449 | __dasd_process_ccw_queue(device, &final_queue); | 1321 | __dasd_device_process_ccw_queue(device, &final_queue); |
1450 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); | 1322 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); |
1451 | /* Now call the callback function of requests with final status */ | 1323 | /* Now call the callback function of requests with final status */ |
1452 | list_for_each_safe(l, n, &final_queue) { | 1324 | __dasd_device_process_final_queue(device, &final_queue); |
1453 | cqr = list_entry(l, struct dasd_ccw_req, list); | 1325 | spin_lock_irq(get_ccwdev_lock(device->cdev)); |
1454 | list_del_init(&cqr->list); | ||
1455 | if (cqr->callback != NULL) | ||
1456 | (cqr->callback)(cqr, cqr->callback_data); | ||
1457 | } | ||
1458 | spin_lock_irq(&device->request_queue_lock); | ||
1459 | spin_lock(get_ccwdev_lock(device->cdev)); | ||
1460 | /* Get new request from the block device request queue */ | ||
1461 | __dasd_process_blk_queue(device); | ||
1462 | /* Now check if the head of the ccw queue needs to be started. */ | 1326 | /* Now check if the head of the ccw queue needs to be started. */ |
1463 | __dasd_start_head(device); | 1327 | __dasd_device_start_head(device); |
1464 | spin_unlock(get_ccwdev_lock(device->cdev)); | 1328 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); |
1465 | spin_unlock_irq(&device->request_queue_lock); | ||
1466 | dasd_put_device(device); | 1329 | dasd_put_device(device); |
1467 | } | 1330 | } |
1468 | 1331 | ||
1469 | /* | 1332 | /* |
1470 | * Schedules a call to dasd_tasklet over the device tasklet. | 1333 | * Schedules a call to dasd_tasklet over the device tasklet. |
1471 | */ | 1334 | */ |
1472 | void | 1335 | void dasd_schedule_device_bh(struct dasd_device *device) |
1473 | dasd_schedule_bh(struct dasd_device * device) | ||
1474 | { | 1336 | { |
1475 | /* Protect against rescheduling. */ | 1337 | /* Protect against rescheduling. */ |
1476 | if (atomic_cmpxchg (&device->tasklet_scheduled, 0, 1) != 0) | 1338 | if (atomic_cmpxchg (&device->tasklet_scheduled, 0, 1) != 0) |
@@ -1480,160 +1342,109 @@ dasd_schedule_bh(struct dasd_device * device) | |||
1480 | } | 1342 | } |
1481 | 1343 | ||
1482 | /* | 1344 | /* |
1483 | * Queue a request to the head of the ccw_queue. Start the I/O if | 1345 | * Queue a request to the head of the device ccw_queue. |
1484 | * possible. | 1346 | * Start the I/O if possible. |
1485 | */ | 1347 | */ |
1486 | void | 1348 | void dasd_add_request_head(struct dasd_ccw_req *cqr) |
1487 | dasd_add_request_head(struct dasd_ccw_req *req) | ||
1488 | { | 1349 | { |
1489 | struct dasd_device *device; | 1350 | struct dasd_device *device; |
1490 | unsigned long flags; | 1351 | unsigned long flags; |
1491 | 1352 | ||
1492 | device = req->device; | 1353 | device = cqr->startdev; |
1493 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | 1354 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); |
1494 | req->status = DASD_CQR_QUEUED; | 1355 | cqr->status = DASD_CQR_QUEUED; |
1495 | req->device = device; | 1356 | list_add(&cqr->devlist, &device->ccw_queue); |
1496 | list_add(&req->list, &device->ccw_queue); | ||
1497 | /* let the bh start the request to keep them in order */ | 1357 | /* let the bh start the request to keep them in order */ |
1498 | dasd_schedule_bh(device); | 1358 | dasd_schedule_device_bh(device); |
1499 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); | 1359 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); |
1500 | } | 1360 | } |
1501 | 1361 | ||
1502 | /* | 1362 | /* |
1503 | * Queue a request to the tail of the ccw_queue. Start the I/O if | 1363 | * Queue a request to the tail of the device ccw_queue. |
1504 | * possible. | 1364 | * Start the I/O if possible. |
1505 | */ | 1365 | */ |
1506 | void | 1366 | void dasd_add_request_tail(struct dasd_ccw_req *cqr) |
1507 | dasd_add_request_tail(struct dasd_ccw_req *req) | ||
1508 | { | 1367 | { |
1509 | struct dasd_device *device; | 1368 | struct dasd_device *device; |
1510 | unsigned long flags; | 1369 | unsigned long flags; |
1511 | 1370 | ||
1512 | device = req->device; | 1371 | device = cqr->startdev; |
1513 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | 1372 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); |
1514 | req->status = DASD_CQR_QUEUED; | 1373 | cqr->status = DASD_CQR_QUEUED; |
1515 | req->device = device; | 1374 | list_add_tail(&cqr->devlist, &device->ccw_queue); |
1516 | list_add_tail(&req->list, &device->ccw_queue); | ||
1517 | /* let the bh start the request to keep them in order */ | 1375 | /* let the bh start the request to keep them in order */ |
1518 | dasd_schedule_bh(device); | 1376 | dasd_schedule_device_bh(device); |
1519 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); | 1377 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); |
1520 | } | 1378 | } |
1521 | 1379 | ||
1522 | /* | 1380 | /* |
1523 | * Wakeup callback. | 1381 | * Wakeup helper for the 'sleep_on' functions. |
1524 | */ | 1382 | */ |
1525 | static void | 1383 | static void dasd_wakeup_cb(struct dasd_ccw_req *cqr, void *data) |
1526 | dasd_wakeup_cb(struct dasd_ccw_req *cqr, void *data) | ||
1527 | { | 1384 | { |
1528 | wake_up((wait_queue_head_t *) data); | 1385 | wake_up((wait_queue_head_t *) data); |
1529 | } | 1386 | } |
1530 | 1387 | ||
1531 | static inline int | 1388 | static inline int _wait_for_wakeup(struct dasd_ccw_req *cqr) |
1532 | _wait_for_wakeup(struct dasd_ccw_req *cqr) | ||
1533 | { | 1389 | { |
1534 | struct dasd_device *device; | 1390 | struct dasd_device *device; |
1535 | int rc; | 1391 | int rc; |
1536 | 1392 | ||
1537 | device = cqr->device; | 1393 | device = cqr->startdev; |
1538 | spin_lock_irq(get_ccwdev_lock(device->cdev)); | 1394 | spin_lock_irq(get_ccwdev_lock(device->cdev)); |
1539 | rc = ((cqr->status == DASD_CQR_DONE || | 1395 | rc = ((cqr->status == DASD_CQR_DONE || |
1540 | cqr->status == DASD_CQR_FAILED) && | 1396 | cqr->status == DASD_CQR_NEED_ERP || |
1541 | list_empty(&cqr->list)); | 1397 | cqr->status == DASD_CQR_TERMINATED) && |
1398 | list_empty(&cqr->devlist)); | ||
1542 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); | 1399 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); |
1543 | return rc; | 1400 | return rc; |
1544 | } | 1401 | } |
1545 | 1402 | ||
1546 | /* | 1403 | /* |
1547 | * Attempts to start a special ccw queue and waits for its completion. | 1404 | * Queue a request to the tail of the device ccw_queue and wait for |
1405 | * it's completion. | ||
1548 | */ | 1406 | */ |
1549 | int | 1407 | int dasd_sleep_on(struct dasd_ccw_req *cqr) |
1550 | dasd_sleep_on(struct dasd_ccw_req * cqr) | ||
1551 | { | 1408 | { |
1552 | wait_queue_head_t wait_q; | 1409 | wait_queue_head_t wait_q; |
1553 | struct dasd_device *device; | 1410 | struct dasd_device *device; |
1554 | int rc; | 1411 | int rc; |
1555 | 1412 | ||
1556 | device = cqr->device; | 1413 | device = cqr->startdev; |
1557 | spin_lock_irq(get_ccwdev_lock(device->cdev)); | ||
1558 | 1414 | ||
1559 | init_waitqueue_head (&wait_q); | 1415 | init_waitqueue_head (&wait_q); |
1560 | cqr->callback = dasd_wakeup_cb; | 1416 | cqr->callback = dasd_wakeup_cb; |
1561 | cqr->callback_data = (void *) &wait_q; | 1417 | cqr->callback_data = (void *) &wait_q; |
1562 | cqr->status = DASD_CQR_QUEUED; | 1418 | dasd_add_request_tail(cqr); |
1563 | list_add_tail(&cqr->list, &device->ccw_queue); | ||
1564 | |||
1565 | /* let the bh start the request to keep them in order */ | ||
1566 | dasd_schedule_bh(device); | ||
1567 | |||
1568 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); | ||
1569 | |||
1570 | wait_event(wait_q, _wait_for_wakeup(cqr)); | 1419 | wait_event(wait_q, _wait_for_wakeup(cqr)); |
1571 | 1420 | ||
1572 | /* Request status is either done or failed. */ | 1421 | /* Request status is either done or failed. */ |
1573 | rc = (cqr->status == DASD_CQR_FAILED) ? -EIO : 0; | 1422 | rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO; |
1574 | return rc; | 1423 | return rc; |
1575 | } | 1424 | } |
1576 | 1425 | ||
1577 | /* | 1426 | /* |
1578 | * Attempts to start a special ccw queue and wait interruptible | 1427 | * Queue a request to the tail of the device ccw_queue and wait |
1579 | * for its completion. | 1428 | * interruptible for it's completion. |
1580 | */ | 1429 | */ |
1581 | int | 1430 | int dasd_sleep_on_interruptible(struct dasd_ccw_req *cqr) |
1582 | dasd_sleep_on_interruptible(struct dasd_ccw_req * cqr) | ||
1583 | { | 1431 | { |
1584 | wait_queue_head_t wait_q; | 1432 | wait_queue_head_t wait_q; |
1585 | struct dasd_device *device; | 1433 | struct dasd_device *device; |
1586 | int rc, finished; | 1434 | int rc; |
1587 | |||
1588 | device = cqr->device; | ||
1589 | spin_lock_irq(get_ccwdev_lock(device->cdev)); | ||
1590 | 1435 | ||
1436 | device = cqr->startdev; | ||
1591 | init_waitqueue_head (&wait_q); | 1437 | init_waitqueue_head (&wait_q); |
1592 | cqr->callback = dasd_wakeup_cb; | 1438 | cqr->callback = dasd_wakeup_cb; |
1593 | cqr->callback_data = (void *) &wait_q; | 1439 | cqr->callback_data = (void *) &wait_q; |
1594 | cqr->status = DASD_CQR_QUEUED; | 1440 | dasd_add_request_tail(cqr); |
1595 | list_add_tail(&cqr->list, &device->ccw_queue); | 1441 | rc = wait_event_interruptible(wait_q, _wait_for_wakeup(cqr)); |
1596 | 1442 | if (rc == -ERESTARTSYS) { | |
1597 | /* let the bh start the request to keep them in order */ | 1443 | dasd_cancel_req(cqr); |
1598 | dasd_schedule_bh(device); | 1444 | /* wait (non-interruptible) for final status */ |
1599 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); | 1445 | wait_event(wait_q, _wait_for_wakeup(cqr)); |
1600 | |||
1601 | finished = 0; | ||
1602 | while (!finished) { | ||
1603 | rc = wait_event_interruptible(wait_q, _wait_for_wakeup(cqr)); | ||
1604 | if (rc != -ERESTARTSYS) { | ||
1605 | /* Request is final (done or failed) */ | ||
1606 | rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO; | ||
1607 | break; | ||
1608 | } | ||
1609 | spin_lock_irq(get_ccwdev_lock(device->cdev)); | ||
1610 | switch (cqr->status) { | ||
1611 | case DASD_CQR_IN_IO: | ||
1612 | /* terminate runnig cqr */ | ||
1613 | if (device->discipline->term_IO) { | ||
1614 | cqr->retries = -1; | ||
1615 | device->discipline->term_IO(cqr); | ||
1616 | /* wait (non-interruptible) for final status | ||
1617 | * because signal ist still pending */ | ||
1618 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); | ||
1619 | wait_event(wait_q, _wait_for_wakeup(cqr)); | ||
1620 | spin_lock_irq(get_ccwdev_lock(device->cdev)); | ||
1621 | rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO; | ||
1622 | finished = 1; | ||
1623 | } | ||
1624 | break; | ||
1625 | case DASD_CQR_QUEUED: | ||
1626 | /* request */ | ||
1627 | list_del_init(&cqr->list); | ||
1628 | rc = -EIO; | ||
1629 | finished = 1; | ||
1630 | break; | ||
1631 | default: | ||
1632 | /* cqr with 'non-interruptable' status - just wait */ | ||
1633 | break; | ||
1634 | } | ||
1635 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); | ||
1636 | } | 1446 | } |
1447 | rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO; | ||
1637 | return rc; | 1448 | return rc; |
1638 | } | 1449 | } |
1639 | 1450 | ||
@@ -1643,25 +1454,23 @@ dasd_sleep_on_interruptible(struct dasd_ccw_req * cqr) | |||
1643 | * and be put back to status queued, before the special request is added | 1454 | * and be put back to status queued, before the special request is added |
1644 | * to the head of the queue. Then the special request is waited on normally. | 1455 | * to the head of the queue. Then the special request is waited on normally. |
1645 | */ | 1456 | */ |
1646 | static inline int | 1457 | static inline int _dasd_term_running_cqr(struct dasd_device *device) |
1647 | _dasd_term_running_cqr(struct dasd_device *device) | ||
1648 | { | 1458 | { |
1649 | struct dasd_ccw_req *cqr; | 1459 | struct dasd_ccw_req *cqr; |
1650 | 1460 | ||
1651 | if (list_empty(&device->ccw_queue)) | 1461 | if (list_empty(&device->ccw_queue)) |
1652 | return 0; | 1462 | return 0; |
1653 | cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list); | 1463 | cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, devlist); |
1654 | return device->discipline->term_IO(cqr); | 1464 | return device->discipline->term_IO(cqr); |
1655 | } | 1465 | } |
1656 | 1466 | ||
1657 | int | 1467 | int dasd_sleep_on_immediatly(struct dasd_ccw_req *cqr) |
1658 | dasd_sleep_on_immediatly(struct dasd_ccw_req * cqr) | ||
1659 | { | 1468 | { |
1660 | wait_queue_head_t wait_q; | 1469 | wait_queue_head_t wait_q; |
1661 | struct dasd_device *device; | 1470 | struct dasd_device *device; |
1662 | int rc; | 1471 | int rc; |
1663 | 1472 | ||
1664 | device = cqr->device; | 1473 | device = cqr->startdev; |
1665 | spin_lock_irq(get_ccwdev_lock(device->cdev)); | 1474 | spin_lock_irq(get_ccwdev_lock(device->cdev)); |
1666 | rc = _dasd_term_running_cqr(device); | 1475 | rc = _dasd_term_running_cqr(device); |
1667 | if (rc) { | 1476 | if (rc) { |
@@ -1673,17 +1482,17 @@ dasd_sleep_on_immediatly(struct dasd_ccw_req * cqr) | |||
1673 | cqr->callback = dasd_wakeup_cb; | 1482 | cqr->callback = dasd_wakeup_cb; |
1674 | cqr->callback_data = (void *) &wait_q; | 1483 | cqr->callback_data = (void *) &wait_q; |
1675 | cqr->status = DASD_CQR_QUEUED; | 1484 | cqr->status = DASD_CQR_QUEUED; |
1676 | list_add(&cqr->list, &device->ccw_queue); | 1485 | list_add(&cqr->devlist, &device->ccw_queue); |
1677 | 1486 | ||
1678 | /* let the bh start the request to keep them in order */ | 1487 | /* let the bh start the request to keep them in order */ |
1679 | dasd_schedule_bh(device); | 1488 | dasd_schedule_device_bh(device); |
1680 | 1489 | ||
1681 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); | 1490 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); |
1682 | 1491 | ||
1683 | wait_event(wait_q, _wait_for_wakeup(cqr)); | 1492 | wait_event(wait_q, _wait_for_wakeup(cqr)); |
1684 | 1493 | ||
1685 | /* Request status is either done or failed. */ | 1494 | /* Request status is either done or failed. */ |
1686 | rc = (cqr->status == DASD_CQR_FAILED) ? -EIO : 0; | 1495 | rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO; |
1687 | return rc; | 1496 | return rc; |
1688 | } | 1497 | } |
1689 | 1498 | ||
@@ -1692,11 +1501,14 @@ dasd_sleep_on_immediatly(struct dasd_ccw_req * cqr) | |||
1692 | * This is useful to timeout requests. The request will be | 1501 | * This is useful to timeout requests. The request will be |
1693 | * terminated if it is currently in i/o. | 1502 | * terminated if it is currently in i/o. |
1694 | * Returns 1 if the request has been terminated. | 1503 | * Returns 1 if the request has been terminated. |
1504 | * 0 if there was no need to terminate the request (not started yet) | ||
1505 | * negative error code if termination failed | ||
1506 | * Cancellation of a request is an asynchronous operation! The calling | ||
1507 | * function has to wait until the request is properly returned via callback. | ||
1695 | */ | 1508 | */ |
1696 | int | 1509 | int dasd_cancel_req(struct dasd_ccw_req *cqr) |
1697 | dasd_cancel_req(struct dasd_ccw_req *cqr) | ||
1698 | { | 1510 | { |
1699 | struct dasd_device *device = cqr->device; | 1511 | struct dasd_device *device = cqr->startdev; |
1700 | unsigned long flags; | 1512 | unsigned long flags; |
1701 | int rc; | 1513 | int rc; |
1702 | 1514 | ||
@@ -1704,74 +1516,453 @@ dasd_cancel_req(struct dasd_ccw_req *cqr) | |||
1704 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | 1516 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); |
1705 | switch (cqr->status) { | 1517 | switch (cqr->status) { |
1706 | case DASD_CQR_QUEUED: | 1518 | case DASD_CQR_QUEUED: |
1707 | /* request was not started - just set to failed */ | 1519 | /* request was not started - just set to cleared */ |
1708 | cqr->status = DASD_CQR_FAILED; | 1520 | cqr->status = DASD_CQR_CLEARED; |
1709 | break; | 1521 | break; |
1710 | case DASD_CQR_IN_IO: | 1522 | case DASD_CQR_IN_IO: |
1711 | /* request in IO - terminate IO and release again */ | 1523 | /* request in IO - terminate IO and release again */ |
1712 | if (device->discipline->term_IO(cqr) != 0) | 1524 | rc = device->discipline->term_IO(cqr); |
1713 | /* what to do if unable to terminate ?????? | 1525 | if (rc) { |
1714 | e.g. not _IN_IO */ | 1526 | DEV_MESSAGE(KERN_ERR, device, |
1715 | cqr->status = DASD_CQR_FAILED; | 1527 | "dasd_cancel_req is unable " |
1716 | cqr->stopclk = get_clock(); | 1528 | " to terminate request %p, rc = %d", |
1717 | rc = 1; | 1529 | cqr, rc); |
1530 | } else { | ||
1531 | cqr->stopclk = get_clock(); | ||
1532 | rc = 1; | ||
1533 | } | ||
1718 | break; | 1534 | break; |
1719 | case DASD_CQR_DONE: | 1535 | default: /* already finished or clear pending - do nothing */ |
1720 | case DASD_CQR_FAILED: | ||
1721 | /* already finished - do nothing */ | ||
1722 | break; | 1536 | break; |
1723 | default: | 1537 | } |
1724 | DEV_MESSAGE(KERN_ALERT, device, | 1538 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); |
1725 | "invalid status %02x in request", | 1539 | dasd_schedule_device_bh(device); |
1726 | cqr->status); | 1540 | return rc; |
1541 | } | ||
1542 | |||
1543 | |||
1544 | /* | ||
1545 | * SECTION: Operations of the dasd_block layer. | ||
1546 | */ | ||
1547 | |||
1548 | /* | ||
1549 | * Timeout function for dasd_block. This is used when the block layer | ||
1550 | * is waiting for something that may not come reliably, (e.g. a state | ||
1551 | * change interrupt) | ||
1552 | */ | ||
1553 | static void dasd_block_timeout(unsigned long ptr) | ||
1554 | { | ||
1555 | unsigned long flags; | ||
1556 | struct dasd_block *block; | ||
1557 | |||
1558 | block = (struct dasd_block *) ptr; | ||
1559 | spin_lock_irqsave(get_ccwdev_lock(block->base->cdev), flags); | ||
1560 | /* re-activate request queue */ | ||
1561 | block->base->stopped &= ~DASD_STOPPED_PENDING; | ||
1562 | spin_unlock_irqrestore(get_ccwdev_lock(block->base->cdev), flags); | ||
1563 | dasd_schedule_block_bh(block); | ||
1564 | } | ||
1565 | |||
1566 | /* | ||
1567 | * Setup timeout for a dasd_block in jiffies. | ||
1568 | */ | ||
1569 | void dasd_block_set_timer(struct dasd_block *block, int expires) | ||
1570 | { | ||
1571 | if (expires == 0) { | ||
1572 | if (timer_pending(&block->timer)) | ||
1573 | del_timer(&block->timer); | ||
1574 | return; | ||
1575 | } | ||
1576 | if (timer_pending(&block->timer)) { | ||
1577 | if (mod_timer(&block->timer, jiffies + expires)) | ||
1578 | return; | ||
1579 | } | ||
1580 | block->timer.function = dasd_block_timeout; | ||
1581 | block->timer.data = (unsigned long) block; | ||
1582 | block->timer.expires = jiffies + expires; | ||
1583 | add_timer(&block->timer); | ||
1584 | } | ||
1585 | |||
1586 | /* | ||
1587 | * Clear timeout for a dasd_block. | ||
1588 | */ | ||
1589 | void dasd_block_clear_timer(struct dasd_block *block) | ||
1590 | { | ||
1591 | if (timer_pending(&block->timer)) | ||
1592 | del_timer(&block->timer); | ||
1593 | } | ||
1594 | |||
1595 | /* | ||
1596 | * posts the buffer_cache about a finalized request | ||
1597 | */ | ||
1598 | static inline void dasd_end_request(struct request *req, int uptodate) | ||
1599 | { | ||
1600 | if (end_that_request_first(req, uptodate, req->hard_nr_sectors)) | ||
1727 | BUG(); | 1601 | BUG(); |
1602 | add_disk_randomness(req->rq_disk); | ||
1603 | end_that_request_last(req, uptodate); | ||
1604 | } | ||
1605 | |||
1606 | /* | ||
1607 | * Process finished error recovery ccw. | ||
1608 | */ | ||
1609 | static inline void __dasd_block_process_erp(struct dasd_block *block, | ||
1610 | struct dasd_ccw_req *cqr) | ||
1611 | { | ||
1612 | dasd_erp_fn_t erp_fn; | ||
1613 | struct dasd_device *device = block->base; | ||
1728 | 1614 | ||
1615 | if (cqr->status == DASD_CQR_DONE) | ||
1616 | DBF_DEV_EVENT(DBF_NOTICE, device, "%s", "ERP successful"); | ||
1617 | else | ||
1618 | DEV_MESSAGE(KERN_ERR, device, "%s", "ERP unsuccessful"); | ||
1619 | erp_fn = device->discipline->erp_postaction(cqr); | ||
1620 | erp_fn(cqr); | ||
1621 | } | ||
1622 | |||
1623 | /* | ||
1624 | * Fetch requests from the block device queue. | ||
1625 | */ | ||
1626 | static void __dasd_process_request_queue(struct dasd_block *block) | ||
1627 | { | ||
1628 | struct request_queue *queue; | ||
1629 | struct request *req; | ||
1630 | struct dasd_ccw_req *cqr; | ||
1631 | struct dasd_device *basedev; | ||
1632 | unsigned long flags; | ||
1633 | queue = block->request_queue; | ||
1634 | basedev = block->base; | ||
1635 | /* No queue ? Then there is nothing to do. */ | ||
1636 | if (queue == NULL) | ||
1637 | return; | ||
1638 | |||
1639 | /* | ||
1640 | * We requeue request from the block device queue to the ccw | ||
1641 | * queue only in two states. In state DASD_STATE_READY the | ||
1642 | * partition detection is done and we need to requeue requests | ||
1643 | * for that. State DASD_STATE_ONLINE is normal block device | ||
1644 | * operation. | ||
1645 | */ | ||
1646 | if (basedev->state < DASD_STATE_READY) | ||
1647 | return; | ||
1648 | /* Now we try to fetch requests from the request queue */ | ||
1649 | while (!blk_queue_plugged(queue) && | ||
1650 | elv_next_request(queue)) { | ||
1651 | |||
1652 | req = elv_next_request(queue); | ||
1653 | |||
1654 | if (basedev->features & DASD_FEATURE_READONLY && | ||
1655 | rq_data_dir(req) == WRITE) { | ||
1656 | DBF_DEV_EVENT(DBF_ERR, basedev, | ||
1657 | "Rejecting write request %p", | ||
1658 | req); | ||
1659 | blkdev_dequeue_request(req); | ||
1660 | dasd_end_request(req, 0); | ||
1661 | continue; | ||
1662 | } | ||
1663 | cqr = basedev->discipline->build_cp(basedev, block, req); | ||
1664 | if (IS_ERR(cqr)) { | ||
1665 | if (PTR_ERR(cqr) == -EBUSY) | ||
1666 | break; /* normal end condition */ | ||
1667 | if (PTR_ERR(cqr) == -ENOMEM) | ||
1668 | break; /* terminate request queue loop */ | ||
1669 | if (PTR_ERR(cqr) == -EAGAIN) { | ||
1670 | /* | ||
1671 | * The current request cannot be build right | ||
1672 | * now, we have to try later. If this request | ||
1673 | * is the head-of-queue we stop the device | ||
1674 | * for 1/2 second. | ||
1675 | */ | ||
1676 | if (!list_empty(&block->ccw_queue)) | ||
1677 | break; | ||
1678 | spin_lock_irqsave(get_ccwdev_lock(basedev->cdev), flags); | ||
1679 | basedev->stopped |= DASD_STOPPED_PENDING; | ||
1680 | spin_unlock_irqrestore(get_ccwdev_lock(basedev->cdev), flags); | ||
1681 | dasd_block_set_timer(block, HZ/2); | ||
1682 | break; | ||
1683 | } | ||
1684 | DBF_DEV_EVENT(DBF_ERR, basedev, | ||
1685 | "CCW creation failed (rc=%ld) " | ||
1686 | "on request %p", | ||
1687 | PTR_ERR(cqr), req); | ||
1688 | blkdev_dequeue_request(req); | ||
1689 | dasd_end_request(req, 0); | ||
1690 | continue; | ||
1691 | } | ||
1692 | /* | ||
1693 | * Note: callback is set to dasd_return_cqr_cb in | ||
1694 | * __dasd_block_start_head to cover erp requests as well | ||
1695 | */ | ||
1696 | cqr->callback_data = (void *) req; | ||
1697 | cqr->status = DASD_CQR_FILLED; | ||
1698 | blkdev_dequeue_request(req); | ||
1699 | list_add_tail(&cqr->blocklist, &block->ccw_queue); | ||
1700 | dasd_profile_start(block, cqr, req); | ||
1701 | } | ||
1702 | } | ||
1703 | |||
1704 | static void __dasd_cleanup_cqr(struct dasd_ccw_req *cqr) | ||
1705 | { | ||
1706 | struct request *req; | ||
1707 | int status; | ||
1708 | |||
1709 | req = (struct request *) cqr->callback_data; | ||
1710 | dasd_profile_end(cqr->block, cqr, req); | ||
1711 | status = cqr->memdev->discipline->free_cp(cqr, req); | ||
1712 | dasd_end_request(req, status); | ||
1713 | } | ||
1714 | |||
1715 | /* | ||
1716 | * Process ccw request queue. | ||
1717 | */ | ||
1718 | static void __dasd_process_block_ccw_queue(struct dasd_block *block, | ||
1719 | struct list_head *final_queue) | ||
1720 | { | ||
1721 | struct list_head *l, *n; | ||
1722 | struct dasd_ccw_req *cqr; | ||
1723 | dasd_erp_fn_t erp_fn; | ||
1724 | unsigned long flags; | ||
1725 | struct dasd_device *base = block->base; | ||
1726 | |||
1727 | restart: | ||
1728 | /* Process request with final status. */ | ||
1729 | list_for_each_safe(l, n, &block->ccw_queue) { | ||
1730 | cqr = list_entry(l, struct dasd_ccw_req, blocklist); | ||
1731 | if (cqr->status != DASD_CQR_DONE && | ||
1732 | cqr->status != DASD_CQR_FAILED && | ||
1733 | cqr->status != DASD_CQR_NEED_ERP && | ||
1734 | cqr->status != DASD_CQR_TERMINATED) | ||
1735 | continue; | ||
1736 | |||
1737 | if (cqr->status == DASD_CQR_TERMINATED) { | ||
1738 | base->discipline->handle_terminated_request(cqr); | ||
1739 | goto restart; | ||
1740 | } | ||
1741 | |||
1742 | /* Process requests that may be recovered */ | ||
1743 | if (cqr->status == DASD_CQR_NEED_ERP) { | ||
1744 | if (cqr->irb.esw.esw0.erw.cons && | ||
1745 | test_bit(DASD_CQR_FLAGS_USE_ERP, | ||
1746 | &cqr->flags)) { | ||
1747 | erp_fn = base->discipline->erp_action(cqr); | ||
1748 | erp_fn(cqr); | ||
1749 | } | ||
1750 | goto restart; | ||
1751 | } | ||
1752 | |||
1753 | /* First of all call extended error reporting. */ | ||
1754 | if (dasd_eer_enabled(base) && | ||
1755 | cqr->status == DASD_CQR_FAILED) { | ||
1756 | dasd_eer_write(base, cqr, DASD_EER_FATALERROR); | ||
1757 | |||
1758 | /* restart request */ | ||
1759 | cqr->status = DASD_CQR_FILLED; | ||
1760 | cqr->retries = 255; | ||
1761 | spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags); | ||
1762 | base->stopped |= DASD_STOPPED_QUIESCE; | ||
1763 | spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), | ||
1764 | flags); | ||
1765 | goto restart; | ||
1766 | } | ||
1767 | |||
1768 | /* Process finished ERP request. */ | ||
1769 | if (cqr->refers) { | ||
1770 | __dasd_block_process_erp(block, cqr); | ||
1771 | goto restart; | ||
1772 | } | ||
1773 | |||
1774 | /* Rechain finished requests to final queue */ | ||
1775 | cqr->endclk = get_clock(); | ||
1776 | list_move_tail(&cqr->blocklist, final_queue); | ||
1777 | } | ||
1778 | } | ||
1779 | |||
1780 | static void dasd_return_cqr_cb(struct dasd_ccw_req *cqr, void *data) | ||
1781 | { | ||
1782 | dasd_schedule_block_bh(cqr->block); | ||
1783 | } | ||
1784 | |||
1785 | static void __dasd_block_start_head(struct dasd_block *block) | ||
1786 | { | ||
1787 | struct dasd_ccw_req *cqr; | ||
1788 | |||
1789 | if (list_empty(&block->ccw_queue)) | ||
1790 | return; | ||
1791 | /* We allways begin with the first requests on the queue, as some | ||
1792 | * of previously started requests have to be enqueued on a | ||
1793 | * dasd_device again for error recovery. | ||
1794 | */ | ||
1795 | list_for_each_entry(cqr, &block->ccw_queue, blocklist) { | ||
1796 | if (cqr->status != DASD_CQR_FILLED) | ||
1797 | continue; | ||
1798 | /* Non-temporary stop condition will trigger fail fast */ | ||
1799 | if (block->base->stopped & ~DASD_STOPPED_PENDING && | ||
1800 | test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) && | ||
1801 | (!dasd_eer_enabled(block->base))) { | ||
1802 | cqr->status = DASD_CQR_FAILED; | ||
1803 | dasd_schedule_block_bh(block); | ||
1804 | continue; | ||
1805 | } | ||
1806 | /* Don't try to start requests if device is stopped */ | ||
1807 | if (block->base->stopped) | ||
1808 | return; | ||
1809 | |||
1810 | /* just a fail safe check, should not happen */ | ||
1811 | if (!cqr->startdev) | ||
1812 | cqr->startdev = block->base; | ||
1813 | |||
1814 | /* make sure that the requests we submit find their way back */ | ||
1815 | cqr->callback = dasd_return_cqr_cb; | ||
1816 | |||
1817 | dasd_add_request_tail(cqr); | ||
1818 | } | ||
1819 | } | ||
1820 | |||
1821 | /* | ||
1822 | * Central dasd_block layer routine. Takes requests from the generic | ||
1823 | * block layer request queue, creates ccw requests, enqueues them on | ||
1824 | * a dasd_device and processes ccw requests that have been returned. | ||
1825 | */ | ||
1826 | static void dasd_block_tasklet(struct dasd_block *block) | ||
1827 | { | ||
1828 | struct list_head final_queue; | ||
1829 | struct list_head *l, *n; | ||
1830 | struct dasd_ccw_req *cqr; | ||
1831 | |||
1832 | atomic_set(&block->tasklet_scheduled, 0); | ||
1833 | INIT_LIST_HEAD(&final_queue); | ||
1834 | spin_lock(&block->queue_lock); | ||
1835 | /* Finish off requests on ccw queue */ | ||
1836 | __dasd_process_block_ccw_queue(block, &final_queue); | ||
1837 | spin_unlock(&block->queue_lock); | ||
1838 | /* Now call the callback function of requests with final status */ | ||
1839 | spin_lock_irq(&block->request_queue_lock); | ||
1840 | list_for_each_safe(l, n, &final_queue) { | ||
1841 | cqr = list_entry(l, struct dasd_ccw_req, blocklist); | ||
1842 | list_del_init(&cqr->blocklist); | ||
1843 | __dasd_cleanup_cqr(cqr); | ||
1844 | } | ||
1845 | spin_lock(&block->queue_lock); | ||
1846 | /* Get new request from the block device request queue */ | ||
1847 | __dasd_process_request_queue(block); | ||
1848 | /* Now check if the head of the ccw queue needs to be started. */ | ||
1849 | __dasd_block_start_head(block); | ||
1850 | spin_unlock(&block->queue_lock); | ||
1851 | spin_unlock_irq(&block->request_queue_lock); | ||
1852 | dasd_put_device(block->base); | ||
1853 | } | ||
1854 | |||
1855 | static void _dasd_wake_block_flush_cb(struct dasd_ccw_req *cqr, void *data) | ||
1856 | { | ||
1857 | wake_up(&dasd_flush_wq); | ||
1858 | } | ||
1859 | |||
1860 | /* | ||
1861 | * Go through all request on the dasd_block request queue, cancel them | ||
1862 | * on the respective dasd_device, and return them to the generic | ||
1863 | * block layer. | ||
1864 | */ | ||
1865 | static int dasd_flush_block_queue(struct dasd_block *block) | ||
1866 | { | ||
1867 | struct dasd_ccw_req *cqr, *n; | ||
1868 | int rc, i; | ||
1869 | struct list_head flush_queue; | ||
1870 | |||
1871 | INIT_LIST_HEAD(&flush_queue); | ||
1872 | spin_lock_bh(&block->queue_lock); | ||
1873 | rc = 0; | ||
1874 | restart: | ||
1875 | list_for_each_entry_safe(cqr, n, &block->ccw_queue, blocklist) { | ||
1876 | /* if this request currently owned by a dasd_device cancel it */ | ||
1877 | if (cqr->status >= DASD_CQR_QUEUED) | ||
1878 | rc = dasd_cancel_req(cqr); | ||
1879 | if (rc < 0) | ||
1880 | break; | ||
1881 | /* Rechain request (including erp chain) so it won't be | ||
1882 | * touched by the dasd_block_tasklet anymore. | ||
1883 | * Replace the callback so we notice when the request | ||
1884 | * is returned from the dasd_device layer. | ||
1885 | */ | ||
1886 | cqr->callback = _dasd_wake_block_flush_cb; | ||
1887 | for (i = 0; cqr != NULL; cqr = cqr->refers, i++) | ||
1888 | list_move_tail(&cqr->blocklist, &flush_queue); | ||
1889 | if (i > 1) | ||
1890 | /* moved more than one request - need to restart */ | ||
1891 | goto restart; | ||
1892 | } | ||
1893 | spin_unlock_bh(&block->queue_lock); | ||
1894 | /* Now call the callback function of flushed requests */ | ||
1895 | restart_cb: | ||
1896 | list_for_each_entry_safe(cqr, n, &flush_queue, blocklist) { | ||
1897 | wait_event(dasd_flush_wq, (cqr->status < DASD_CQR_QUEUED)); | ||
1898 | /* Process finished ERP request. */ | ||
1899 | if (cqr->refers) { | ||
1900 | __dasd_block_process_erp(block, cqr); | ||
1901 | /* restart list_for_xx loop since dasd_process_erp | ||
1902 | * might remove multiple elements */ | ||
1903 | goto restart_cb; | ||
1904 | } | ||
1905 | /* call the callback function */ | ||
1906 | cqr->endclk = get_clock(); | ||
1907 | list_del_init(&cqr->blocklist); | ||
1908 | __dasd_cleanup_cqr(cqr); | ||
1729 | } | 1909 | } |
1730 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); | ||
1731 | dasd_schedule_bh(device); | ||
1732 | return rc; | 1910 | return rc; |
1733 | } | 1911 | } |
1734 | 1912 | ||
1735 | /* | 1913 | /* |
1736 | * SECTION: Block device operations (request queue, partitions, open, release). | 1914 | * Schedules a call to dasd_tasklet over the device tasklet. |
1915 | */ | ||
1916 | void dasd_schedule_block_bh(struct dasd_block *block) | ||
1917 | { | ||
1918 | /* Protect against rescheduling. */ | ||
1919 | if (atomic_cmpxchg(&block->tasklet_scheduled, 0, 1) != 0) | ||
1920 | return; | ||
1921 | /* life cycle of block is bound to it's base device */ | ||
1922 | dasd_get_device(block->base); | ||
1923 | tasklet_hi_schedule(&block->tasklet); | ||
1924 | } | ||
1925 | |||
1926 | |||
1927 | /* | ||
1928 | * SECTION: external block device operations | ||
1929 | * (request queue handling, open, release, etc.) | ||
1737 | */ | 1930 | */ |
1738 | 1931 | ||
1739 | /* | 1932 | /* |
1740 | * Dasd request queue function. Called from ll_rw_blk.c | 1933 | * Dasd request queue function. Called from ll_rw_blk.c |
1741 | */ | 1934 | */ |
1742 | static void | 1935 | static void do_dasd_request(struct request_queue *queue) |
1743 | do_dasd_request(struct request_queue * queue) | ||
1744 | { | 1936 | { |
1745 | struct dasd_device *device; | 1937 | struct dasd_block *block; |
1746 | 1938 | ||
1747 | device = (struct dasd_device *) queue->queuedata; | 1939 | block = queue->queuedata; |
1748 | spin_lock(get_ccwdev_lock(device->cdev)); | 1940 | spin_lock(&block->queue_lock); |
1749 | /* Get new request from the block device request queue */ | 1941 | /* Get new request from the block device request queue */ |
1750 | __dasd_process_blk_queue(device); | 1942 | __dasd_process_request_queue(block); |
1751 | /* Now check if the head of the ccw queue needs to be started. */ | 1943 | /* Now check if the head of the ccw queue needs to be started. */ |
1752 | __dasd_start_head(device); | 1944 | __dasd_block_start_head(block); |
1753 | spin_unlock(get_ccwdev_lock(device->cdev)); | 1945 | spin_unlock(&block->queue_lock); |
1754 | } | 1946 | } |
1755 | 1947 | ||
1756 | /* | 1948 | /* |
1757 | * Allocate and initialize request queue and default I/O scheduler. | 1949 | * Allocate and initialize request queue and default I/O scheduler. |
1758 | */ | 1950 | */ |
1759 | static int | 1951 | static int dasd_alloc_queue(struct dasd_block *block) |
1760 | dasd_alloc_queue(struct dasd_device * device) | ||
1761 | { | 1952 | { |
1762 | int rc; | 1953 | int rc; |
1763 | 1954 | ||
1764 | device->request_queue = blk_init_queue(do_dasd_request, | 1955 | block->request_queue = blk_init_queue(do_dasd_request, |
1765 | &device->request_queue_lock); | 1956 | &block->request_queue_lock); |
1766 | if (device->request_queue == NULL) | 1957 | if (block->request_queue == NULL) |
1767 | return -ENOMEM; | 1958 | return -ENOMEM; |
1768 | 1959 | ||
1769 | device->request_queue->queuedata = device; | 1960 | block->request_queue->queuedata = block; |
1770 | 1961 | ||
1771 | elevator_exit(device->request_queue->elevator); | 1962 | elevator_exit(block->request_queue->elevator); |
1772 | rc = elevator_init(device->request_queue, "deadline"); | 1963 | rc = elevator_init(block->request_queue, "deadline"); |
1773 | if (rc) { | 1964 | if (rc) { |
1774 | blk_cleanup_queue(device->request_queue); | 1965 | blk_cleanup_queue(block->request_queue); |
1775 | return rc; | 1966 | return rc; |
1776 | } | 1967 | } |
1777 | return 0; | 1968 | return 0; |
@@ -1780,79 +1971,76 @@ dasd_alloc_queue(struct dasd_device * device) | |||
1780 | /* | 1971 | /* |
1781 | * Allocate and initialize request queue. | 1972 | * Allocate and initialize request queue. |
1782 | */ | 1973 | */ |
1783 | static void | 1974 | static void dasd_setup_queue(struct dasd_block *block) |
1784 | dasd_setup_queue(struct dasd_device * device) | ||
1785 | { | 1975 | { |
1786 | int max; | 1976 | int max; |
1787 | 1977 | ||
1788 | blk_queue_hardsect_size(device->request_queue, device->bp_block); | 1978 | blk_queue_hardsect_size(block->request_queue, block->bp_block); |
1789 | max = device->discipline->max_blocks << device->s2b_shift; | 1979 | max = block->base->discipline->max_blocks << block->s2b_shift; |
1790 | blk_queue_max_sectors(device->request_queue, max); | 1980 | blk_queue_max_sectors(block->request_queue, max); |
1791 | blk_queue_max_phys_segments(device->request_queue, -1L); | 1981 | blk_queue_max_phys_segments(block->request_queue, -1L); |
1792 | blk_queue_max_hw_segments(device->request_queue, -1L); | 1982 | blk_queue_max_hw_segments(block->request_queue, -1L); |
1793 | blk_queue_max_segment_size(device->request_queue, -1L); | 1983 | blk_queue_max_segment_size(block->request_queue, -1L); |
1794 | blk_queue_segment_boundary(device->request_queue, -1L); | 1984 | blk_queue_segment_boundary(block->request_queue, -1L); |
1795 | blk_queue_ordered(device->request_queue, QUEUE_ORDERED_TAG, NULL); | 1985 | blk_queue_ordered(block->request_queue, QUEUE_ORDERED_DRAIN, NULL); |
1796 | } | 1986 | } |
1797 | 1987 | ||
1798 | /* | 1988 | /* |
1799 | * Deactivate and free request queue. | 1989 | * Deactivate and free request queue. |
1800 | */ | 1990 | */ |
1801 | static void | 1991 | static void dasd_free_queue(struct dasd_block *block) |
1802 | dasd_free_queue(struct dasd_device * device) | ||
1803 | { | 1992 | { |
1804 | if (device->request_queue) { | 1993 | if (block->request_queue) { |
1805 | blk_cleanup_queue(device->request_queue); | 1994 | blk_cleanup_queue(block->request_queue); |
1806 | device->request_queue = NULL; | 1995 | block->request_queue = NULL; |
1807 | } | 1996 | } |
1808 | } | 1997 | } |
1809 | 1998 | ||
1810 | /* | 1999 | /* |
1811 | * Flush request on the request queue. | 2000 | * Flush request on the request queue. |
1812 | */ | 2001 | */ |
1813 | static void | 2002 | static void dasd_flush_request_queue(struct dasd_block *block) |
1814 | dasd_flush_request_queue(struct dasd_device * device) | ||
1815 | { | 2003 | { |
1816 | struct request *req; | 2004 | struct request *req; |
1817 | 2005 | ||
1818 | if (!device->request_queue) | 2006 | if (!block->request_queue) |
1819 | return; | 2007 | return; |
1820 | 2008 | ||
1821 | spin_lock_irq(&device->request_queue_lock); | 2009 | spin_lock_irq(&block->request_queue_lock); |
1822 | while ((req = elv_next_request(device->request_queue))) { | 2010 | while ((req = elv_next_request(block->request_queue))) { |
1823 | blkdev_dequeue_request(req); | 2011 | blkdev_dequeue_request(req); |
1824 | dasd_end_request(req, 0); | 2012 | dasd_end_request(req, 0); |
1825 | } | 2013 | } |
1826 | spin_unlock_irq(&device->request_queue_lock); | 2014 | spin_unlock_irq(&block->request_queue_lock); |
1827 | } | 2015 | } |
1828 | 2016 | ||
1829 | static int | 2017 | static int dasd_open(struct inode *inp, struct file *filp) |
1830 | dasd_open(struct inode *inp, struct file *filp) | ||
1831 | { | 2018 | { |
1832 | struct gendisk *disk = inp->i_bdev->bd_disk; | 2019 | struct gendisk *disk = inp->i_bdev->bd_disk; |
1833 | struct dasd_device *device = disk->private_data; | 2020 | struct dasd_block *block = disk->private_data; |
2021 | struct dasd_device *base = block->base; | ||
1834 | int rc; | 2022 | int rc; |
1835 | 2023 | ||
1836 | atomic_inc(&device->open_count); | 2024 | atomic_inc(&block->open_count); |
1837 | if (test_bit(DASD_FLAG_OFFLINE, &device->flags)) { | 2025 | if (test_bit(DASD_FLAG_OFFLINE, &base->flags)) { |
1838 | rc = -ENODEV; | 2026 | rc = -ENODEV; |
1839 | goto unlock; | 2027 | goto unlock; |
1840 | } | 2028 | } |
1841 | 2029 | ||
1842 | if (!try_module_get(device->discipline->owner)) { | 2030 | if (!try_module_get(base->discipline->owner)) { |
1843 | rc = -EINVAL; | 2031 | rc = -EINVAL; |
1844 | goto unlock; | 2032 | goto unlock; |
1845 | } | 2033 | } |
1846 | 2034 | ||
1847 | if (dasd_probeonly) { | 2035 | if (dasd_probeonly) { |
1848 | DEV_MESSAGE(KERN_INFO, device, "%s", | 2036 | DEV_MESSAGE(KERN_INFO, base, "%s", |
1849 | "No access to device due to probeonly mode"); | 2037 | "No access to device due to probeonly mode"); |
1850 | rc = -EPERM; | 2038 | rc = -EPERM; |
1851 | goto out; | 2039 | goto out; |
1852 | } | 2040 | } |
1853 | 2041 | ||
1854 | if (device->state <= DASD_STATE_BASIC) { | 2042 | if (base->state <= DASD_STATE_BASIC) { |
1855 | DBF_DEV_EVENT(DBF_ERR, device, " %s", | 2043 | DBF_DEV_EVENT(DBF_ERR, base, " %s", |
1856 | " Cannot open unrecognized device"); | 2044 | " Cannot open unrecognized device"); |
1857 | rc = -ENODEV; | 2045 | rc = -ENODEV; |
1858 | goto out; | 2046 | goto out; |
@@ -1861,41 +2049,41 @@ dasd_open(struct inode *inp, struct file *filp) | |||
1861 | return 0; | 2049 | return 0; |
1862 | 2050 | ||
1863 | out: | 2051 | out: |
1864 | module_put(device->discipline->owner); | 2052 | module_put(base->discipline->owner); |
1865 | unlock: | 2053 | unlock: |
1866 | atomic_dec(&device->open_count); | 2054 | atomic_dec(&block->open_count); |
1867 | return rc; | 2055 | return rc; |
1868 | } | 2056 | } |
1869 | 2057 | ||
1870 | static int | 2058 | static int dasd_release(struct inode *inp, struct file *filp) |
1871 | dasd_release(struct inode *inp, struct file *filp) | ||
1872 | { | 2059 | { |
1873 | struct gendisk *disk = inp->i_bdev->bd_disk; | 2060 | struct gendisk *disk = inp->i_bdev->bd_disk; |
1874 | struct dasd_device *device = disk->private_data; | 2061 | struct dasd_block *block = disk->private_data; |
1875 | 2062 | ||
1876 | atomic_dec(&device->open_count); | 2063 | atomic_dec(&block->open_count); |
1877 | module_put(device->discipline->owner); | 2064 | module_put(block->base->discipline->owner); |
1878 | return 0; | 2065 | return 0; |
1879 | } | 2066 | } |
1880 | 2067 | ||
1881 | /* | 2068 | /* |
1882 | * Return disk geometry. | 2069 | * Return disk geometry. |
1883 | */ | 2070 | */ |
1884 | static int | 2071 | static int dasd_getgeo(struct block_device *bdev, struct hd_geometry *geo) |
1885 | dasd_getgeo(struct block_device *bdev, struct hd_geometry *geo) | ||
1886 | { | 2072 | { |
1887 | struct dasd_device *device; | 2073 | struct dasd_block *block; |
2074 | struct dasd_device *base; | ||
1888 | 2075 | ||
1889 | device = bdev->bd_disk->private_data; | 2076 | block = bdev->bd_disk->private_data; |
1890 | if (!device) | 2077 | base = block->base; |
2078 | if (!block) | ||
1891 | return -ENODEV; | 2079 | return -ENODEV; |
1892 | 2080 | ||
1893 | if (!device->discipline || | 2081 | if (!base->discipline || |
1894 | !device->discipline->fill_geometry) | 2082 | !base->discipline->fill_geometry) |
1895 | return -EINVAL; | 2083 | return -EINVAL; |
1896 | 2084 | ||
1897 | device->discipline->fill_geometry(device, geo); | 2085 | base->discipline->fill_geometry(block, geo); |
1898 | geo->start = get_start_sect(bdev) >> device->s2b_shift; | 2086 | geo->start = get_start_sect(bdev) >> block->s2b_shift; |
1899 | return 0; | 2087 | return 0; |
1900 | } | 2088 | } |
1901 | 2089 | ||
@@ -1909,6 +2097,9 @@ dasd_device_operations = { | |||
1909 | .getgeo = dasd_getgeo, | 2097 | .getgeo = dasd_getgeo, |
1910 | }; | 2098 | }; |
1911 | 2099 | ||
2100 | /******************************************************************************* | ||
2101 | * end of block device operations | ||
2102 | */ | ||
1912 | 2103 | ||
1913 | static void | 2104 | static void |
1914 | dasd_exit(void) | 2105 | dasd_exit(void) |
@@ -1937,9 +2128,8 @@ dasd_exit(void) | |||
1937 | * Initial attempt at a probe function. this can be simplified once | 2128 | * Initial attempt at a probe function. this can be simplified once |
1938 | * the other detection code is gone. | 2129 | * the other detection code is gone. |
1939 | */ | 2130 | */ |
1940 | int | 2131 | int dasd_generic_probe(struct ccw_device *cdev, |
1941 | dasd_generic_probe (struct ccw_device *cdev, | 2132 | struct dasd_discipline *discipline) |
1942 | struct dasd_discipline *discipline) | ||
1943 | { | 2133 | { |
1944 | int ret; | 2134 | int ret; |
1945 | 2135 | ||
@@ -1969,19 +2159,20 @@ dasd_generic_probe (struct ccw_device *cdev, | |||
1969 | ret = ccw_device_set_online(cdev); | 2159 | ret = ccw_device_set_online(cdev); |
1970 | if (ret) | 2160 | if (ret) |
1971 | printk(KERN_WARNING | 2161 | printk(KERN_WARNING |
1972 | "dasd_generic_probe: could not initially online " | 2162 | "dasd_generic_probe: could not initially " |
1973 | "ccw-device %s\n", cdev->dev.bus_id); | 2163 | "online ccw-device %s; return code: %d\n", |
1974 | return ret; | 2164 | cdev->dev.bus_id, ret); |
2165 | return 0; | ||
1975 | } | 2166 | } |
1976 | 2167 | ||
1977 | /* | 2168 | /* |
1978 | * This will one day be called from a global not_oper handler. | 2169 | * This will one day be called from a global not_oper handler. |
1979 | * It is also used by driver_unregister during module unload. | 2170 | * It is also used by driver_unregister during module unload. |
1980 | */ | 2171 | */ |
1981 | void | 2172 | void dasd_generic_remove(struct ccw_device *cdev) |
1982 | dasd_generic_remove (struct ccw_device *cdev) | ||
1983 | { | 2173 | { |
1984 | struct dasd_device *device; | 2174 | struct dasd_device *device; |
2175 | struct dasd_block *block; | ||
1985 | 2176 | ||
1986 | cdev->handler = NULL; | 2177 | cdev->handler = NULL; |
1987 | 2178 | ||
@@ -2001,7 +2192,15 @@ dasd_generic_remove (struct ccw_device *cdev) | |||
2001 | */ | 2192 | */ |
2002 | dasd_set_target_state(device, DASD_STATE_NEW); | 2193 | dasd_set_target_state(device, DASD_STATE_NEW); |
2003 | /* dasd_delete_device destroys the device reference. */ | 2194 | /* dasd_delete_device destroys the device reference. */ |
2195 | block = device->block; | ||
2196 | device->block = NULL; | ||
2004 | dasd_delete_device(device); | 2197 | dasd_delete_device(device); |
2198 | /* | ||
2199 | * life cycle of block is bound to device, so delete it after | ||
2200 | * device was safely removed | ||
2201 | */ | ||
2202 | if (block) | ||
2203 | dasd_free_block(block); | ||
2005 | } | 2204 | } |
2006 | 2205 | ||
2007 | /* | 2206 | /* |
@@ -2009,10 +2208,8 @@ dasd_generic_remove (struct ccw_device *cdev) | |||
2009 | * the device is detected for the first time and is supposed to be used | 2208 | * the device is detected for the first time and is supposed to be used |
2010 | * or the user has started activation through sysfs. | 2209 | * or the user has started activation through sysfs. |
2011 | */ | 2210 | */ |
2012 | int | 2211 | int dasd_generic_set_online(struct ccw_device *cdev, |
2013 | dasd_generic_set_online (struct ccw_device *cdev, | 2212 | struct dasd_discipline *base_discipline) |
2014 | struct dasd_discipline *base_discipline) | ||
2015 | |||
2016 | { | 2213 | { |
2017 | struct dasd_discipline *discipline; | 2214 | struct dasd_discipline *discipline; |
2018 | struct dasd_device *device; | 2215 | struct dasd_device *device; |
@@ -2048,6 +2245,7 @@ dasd_generic_set_online (struct ccw_device *cdev, | |||
2048 | device->base_discipline = base_discipline; | 2245 | device->base_discipline = base_discipline; |
2049 | device->discipline = discipline; | 2246 | device->discipline = discipline; |
2050 | 2247 | ||
2248 | /* check_device will allocate block device if necessary */ | ||
2051 | rc = discipline->check_device(device); | 2249 | rc = discipline->check_device(device); |
2052 | if (rc) { | 2250 | if (rc) { |
2053 | printk (KERN_WARNING | 2251 | printk (KERN_WARNING |
@@ -2067,6 +2265,8 @@ dasd_generic_set_online (struct ccw_device *cdev, | |||
2067 | cdev->dev.bus_id); | 2265 | cdev->dev.bus_id); |
2068 | rc = -ENODEV; | 2266 | rc = -ENODEV; |
2069 | dasd_set_target_state(device, DASD_STATE_NEW); | 2267 | dasd_set_target_state(device, DASD_STATE_NEW); |
2268 | if (device->block) | ||
2269 | dasd_free_block(device->block); | ||
2070 | dasd_delete_device(device); | 2270 | dasd_delete_device(device); |
2071 | } else | 2271 | } else |
2072 | pr_debug("dasd_generic device %s found\n", | 2272 | pr_debug("dasd_generic device %s found\n", |
@@ -2081,10 +2281,10 @@ dasd_generic_set_online (struct ccw_device *cdev, | |||
2081 | return rc; | 2281 | return rc; |
2082 | } | 2282 | } |
2083 | 2283 | ||
2084 | int | 2284 | int dasd_generic_set_offline(struct ccw_device *cdev) |
2085 | dasd_generic_set_offline (struct ccw_device *cdev) | ||
2086 | { | 2285 | { |
2087 | struct dasd_device *device; | 2286 | struct dasd_device *device; |
2287 | struct dasd_block *block; | ||
2088 | int max_count, open_count; | 2288 | int max_count, open_count; |
2089 | 2289 | ||
2090 | device = dasd_device_from_cdev(cdev); | 2290 | device = dasd_device_from_cdev(cdev); |
@@ -2101,30 +2301,39 @@ dasd_generic_set_offline (struct ccw_device *cdev) | |||
2101 | * the blkdev_get in dasd_scan_partitions. We are only interested | 2301 | * the blkdev_get in dasd_scan_partitions. We are only interested |
2102 | * in the other openers. | 2302 | * in the other openers. |
2103 | */ | 2303 | */ |
2104 | max_count = device->bdev ? 0 : -1; | 2304 | if (device->block) { |
2105 | open_count = (int) atomic_read(&device->open_count); | 2305 | struct dasd_block *block = device->block; |
2106 | if (open_count > max_count) { | 2306 | max_count = block->bdev ? 0 : -1; |
2107 | if (open_count > 0) | 2307 | open_count = (int) atomic_read(&block->open_count); |
2108 | printk (KERN_WARNING "Can't offline dasd device with " | 2308 | if (open_count > max_count) { |
2109 | "open count = %i.\n", | 2309 | if (open_count > 0) |
2110 | open_count); | 2310 | printk(KERN_WARNING "Can't offline dasd " |
2111 | else | 2311 | "device with open count = %i.\n", |
2112 | printk (KERN_WARNING "%s", | 2312 | open_count); |
2113 | "Can't offline dasd device due to internal " | 2313 | else |
2114 | "use\n"); | 2314 | printk(KERN_WARNING "%s", |
2115 | clear_bit(DASD_FLAG_OFFLINE, &device->flags); | 2315 | "Can't offline dasd device due " |
2116 | dasd_put_device(device); | 2316 | "to internal use\n"); |
2117 | return -EBUSY; | 2317 | clear_bit(DASD_FLAG_OFFLINE, &device->flags); |
2318 | dasd_put_device(device); | ||
2319 | return -EBUSY; | ||
2320 | } | ||
2118 | } | 2321 | } |
2119 | dasd_set_target_state(device, DASD_STATE_NEW); | 2322 | dasd_set_target_state(device, DASD_STATE_NEW); |
2120 | /* dasd_delete_device destroys the device reference. */ | 2323 | /* dasd_delete_device destroys the device reference. */ |
2324 | block = device->block; | ||
2325 | device->block = NULL; | ||
2121 | dasd_delete_device(device); | 2326 | dasd_delete_device(device); |
2122 | 2327 | /* | |
2328 | * life cycle of block is bound to device, so delete it after | ||
2329 | * device was safely removed | ||
2330 | */ | ||
2331 | if (block) | ||
2332 | dasd_free_block(block); | ||
2123 | return 0; | 2333 | return 0; |
2124 | } | 2334 | } |
2125 | 2335 | ||
2126 | int | 2336 | int dasd_generic_notify(struct ccw_device *cdev, int event) |
2127 | dasd_generic_notify(struct ccw_device *cdev, int event) | ||
2128 | { | 2337 | { |
2129 | struct dasd_device *device; | 2338 | struct dasd_device *device; |
2130 | struct dasd_ccw_req *cqr; | 2339 | struct dasd_ccw_req *cqr; |
@@ -2145,27 +2354,22 @@ dasd_generic_notify(struct ccw_device *cdev, int event) | |||
2145 | if (device->state < DASD_STATE_BASIC) | 2354 | if (device->state < DASD_STATE_BASIC) |
2146 | break; | 2355 | break; |
2147 | /* Device is active. We want to keep it. */ | 2356 | /* Device is active. We want to keep it. */ |
2148 | if (test_bit(DASD_FLAG_DSC_ERROR, &device->flags)) { | 2357 | list_for_each_entry(cqr, &device->ccw_queue, devlist) |
2149 | list_for_each_entry(cqr, &device->ccw_queue, list) | 2358 | if (cqr->status == DASD_CQR_IN_IO) { |
2150 | if (cqr->status == DASD_CQR_IN_IO) | 2359 | cqr->status = DASD_CQR_QUEUED; |
2151 | cqr->status = DASD_CQR_FAILED; | 2360 | cqr->retries++; |
2152 | device->stopped |= DASD_STOPPED_DC_EIO; | 2361 | } |
2153 | } else { | 2362 | device->stopped |= DASD_STOPPED_DC_WAIT; |
2154 | list_for_each_entry(cqr, &device->ccw_queue, list) | 2363 | dasd_device_clear_timer(device); |
2155 | if (cqr->status == DASD_CQR_IN_IO) { | 2364 | dasd_schedule_device_bh(device); |
2156 | cqr->status = DASD_CQR_QUEUED; | ||
2157 | cqr->retries++; | ||
2158 | } | ||
2159 | device->stopped |= DASD_STOPPED_DC_WAIT; | ||
2160 | dasd_set_timer(device, 0); | ||
2161 | } | ||
2162 | dasd_schedule_bh(device); | ||
2163 | ret = 1; | 2365 | ret = 1; |
2164 | break; | 2366 | break; |
2165 | case CIO_OPER: | 2367 | case CIO_OPER: |
2166 | /* FIXME: add a sanity check. */ | 2368 | /* FIXME: add a sanity check. */ |
2167 | device->stopped &= ~(DASD_STOPPED_DC_WAIT|DASD_STOPPED_DC_EIO); | 2369 | device->stopped &= ~DASD_STOPPED_DC_WAIT; |
2168 | dasd_schedule_bh(device); | 2370 | dasd_schedule_device_bh(device); |
2371 | if (device->block) | ||
2372 | dasd_schedule_block_bh(device->block); | ||
2169 | ret = 1; | 2373 | ret = 1; |
2170 | break; | 2374 | break; |
2171 | } | 2375 | } |
@@ -2195,7 +2399,8 @@ static struct dasd_ccw_req *dasd_generic_build_rdc(struct dasd_device *device, | |||
2195 | ccw->cda = (__u32)(addr_t)rdc_buffer; | 2399 | ccw->cda = (__u32)(addr_t)rdc_buffer; |
2196 | ccw->count = rdc_buffer_size; | 2400 | ccw->count = rdc_buffer_size; |
2197 | 2401 | ||
2198 | cqr->device = device; | 2402 | cqr->startdev = device; |
2403 | cqr->memdev = device; | ||
2199 | cqr->expires = 10*HZ; | 2404 | cqr->expires = 10*HZ; |
2200 | clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); | 2405 | clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); |
2201 | cqr->retries = 2; | 2406 | cqr->retries = 2; |
@@ -2217,13 +2422,12 @@ int dasd_generic_read_dev_chars(struct dasd_device *device, char *magic, | |||
2217 | return PTR_ERR(cqr); | 2422 | return PTR_ERR(cqr); |
2218 | 2423 | ||
2219 | ret = dasd_sleep_on(cqr); | 2424 | ret = dasd_sleep_on(cqr); |
2220 | dasd_sfree_request(cqr, cqr->device); | 2425 | dasd_sfree_request(cqr, cqr->memdev); |
2221 | return ret; | 2426 | return ret; |
2222 | } | 2427 | } |
2223 | EXPORT_SYMBOL_GPL(dasd_generic_read_dev_chars); | 2428 | EXPORT_SYMBOL_GPL(dasd_generic_read_dev_chars); |
2224 | 2429 | ||
2225 | static int __init | 2430 | static int __init dasd_init(void) |
2226 | dasd_init(void) | ||
2227 | { | 2431 | { |
2228 | int rc; | 2432 | int rc; |
2229 | 2433 | ||
@@ -2231,7 +2435,7 @@ dasd_init(void) | |||
2231 | init_waitqueue_head(&dasd_flush_wq); | 2435 | init_waitqueue_head(&dasd_flush_wq); |
2232 | 2436 | ||
2233 | /* register 'common' DASD debug area, used for all DBF_XXX calls */ | 2437 | /* register 'common' DASD debug area, used for all DBF_XXX calls */ |
2234 | dasd_debug_area = debug_register("dasd", 1, 2, 8 * sizeof (long)); | 2438 | dasd_debug_area = debug_register("dasd", 1, 1, 8 * sizeof(long)); |
2235 | if (dasd_debug_area == NULL) { | 2439 | if (dasd_debug_area == NULL) { |
2236 | rc = -ENOMEM; | 2440 | rc = -ENOMEM; |
2237 | goto failed; | 2441 | goto failed; |
@@ -2277,15 +2481,18 @@ EXPORT_SYMBOL(dasd_diag_discipline_pointer); | |||
2277 | EXPORT_SYMBOL(dasd_add_request_head); | 2481 | EXPORT_SYMBOL(dasd_add_request_head); |
2278 | EXPORT_SYMBOL(dasd_add_request_tail); | 2482 | EXPORT_SYMBOL(dasd_add_request_tail); |
2279 | EXPORT_SYMBOL(dasd_cancel_req); | 2483 | EXPORT_SYMBOL(dasd_cancel_req); |
2280 | EXPORT_SYMBOL(dasd_clear_timer); | 2484 | EXPORT_SYMBOL(dasd_device_clear_timer); |
2485 | EXPORT_SYMBOL(dasd_block_clear_timer); | ||
2281 | EXPORT_SYMBOL(dasd_enable_device); | 2486 | EXPORT_SYMBOL(dasd_enable_device); |
2282 | EXPORT_SYMBOL(dasd_int_handler); | 2487 | EXPORT_SYMBOL(dasd_int_handler); |
2283 | EXPORT_SYMBOL(dasd_kfree_request); | 2488 | EXPORT_SYMBOL(dasd_kfree_request); |
2284 | EXPORT_SYMBOL(dasd_kick_device); | 2489 | EXPORT_SYMBOL(dasd_kick_device); |
2285 | EXPORT_SYMBOL(dasd_kmalloc_request); | 2490 | EXPORT_SYMBOL(dasd_kmalloc_request); |
2286 | EXPORT_SYMBOL(dasd_schedule_bh); | 2491 | EXPORT_SYMBOL(dasd_schedule_device_bh); |
2492 | EXPORT_SYMBOL(dasd_schedule_block_bh); | ||
2287 | EXPORT_SYMBOL(dasd_set_target_state); | 2493 | EXPORT_SYMBOL(dasd_set_target_state); |
2288 | EXPORT_SYMBOL(dasd_set_timer); | 2494 | EXPORT_SYMBOL(dasd_device_set_timer); |
2495 | EXPORT_SYMBOL(dasd_block_set_timer); | ||
2289 | EXPORT_SYMBOL(dasd_sfree_request); | 2496 | EXPORT_SYMBOL(dasd_sfree_request); |
2290 | EXPORT_SYMBOL(dasd_sleep_on); | 2497 | EXPORT_SYMBOL(dasd_sleep_on); |
2291 | EXPORT_SYMBOL(dasd_sleep_on_immediatly); | 2498 | EXPORT_SYMBOL(dasd_sleep_on_immediatly); |
@@ -2299,4 +2506,7 @@ EXPORT_SYMBOL_GPL(dasd_generic_remove); | |||
2299 | EXPORT_SYMBOL_GPL(dasd_generic_notify); | 2506 | EXPORT_SYMBOL_GPL(dasd_generic_notify); |
2300 | EXPORT_SYMBOL_GPL(dasd_generic_set_online); | 2507 | EXPORT_SYMBOL_GPL(dasd_generic_set_online); |
2301 | EXPORT_SYMBOL_GPL(dasd_generic_set_offline); | 2508 | EXPORT_SYMBOL_GPL(dasd_generic_set_offline); |
2302 | 2509 | EXPORT_SYMBOL_GPL(dasd_generic_handle_state_change); | |
2510 | EXPORT_SYMBOL_GPL(dasd_flush_device_queue); | ||
2511 | EXPORT_SYMBOL_GPL(dasd_alloc_block); | ||
2512 | EXPORT_SYMBOL_GPL(dasd_free_block); | ||
diff --git a/drivers/s390/block/dasd_3370_erp.c b/drivers/s390/block/dasd_3370_erp.c deleted file mode 100644 index 1ddab8991d92..000000000000 --- a/drivers/s390/block/dasd_3370_erp.c +++ /dev/null | |||
@@ -1,84 +0,0 @@ | |||
1 | /* | ||
2 | * File...........: linux/drivers/s390/block/dasd_3370_erp.c | ||
3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> | ||
4 | * Bugreports.to..: <Linux390@de.ibm.com> | ||
5 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000 | ||
6 | * | ||
7 | */ | ||
8 | |||
9 | #define PRINTK_HEADER "dasd_erp(3370)" | ||
10 | |||
11 | #include "dasd_int.h" | ||
12 | |||
13 | |||
14 | /* | ||
15 | * DASD_3370_ERP_EXAMINE | ||
16 | * | ||
17 | * DESCRIPTION | ||
18 | * Checks only for fatal/no/recover error. | ||
19 | * A detailed examination of the sense data is done later outside | ||
20 | * the interrupt handler. | ||
21 | * | ||
22 | * The logic is based on the 'IBM 3880 Storage Control Reference' manual | ||
23 | * 'Chapter 7. 3370 Sense Data'. | ||
24 | * | ||
25 | * RETURN VALUES | ||
26 | * dasd_era_none no error | ||
27 | * dasd_era_fatal for all fatal (unrecoverable errors) | ||
28 | * dasd_era_recover for all others. | ||
29 | */ | ||
30 | dasd_era_t | ||
31 | dasd_3370_erp_examine(struct dasd_ccw_req * cqr, struct irb * irb) | ||
32 | { | ||
33 | char *sense = irb->ecw; | ||
34 | |||
35 | /* check for successful execution first */ | ||
36 | if (irb->scsw.cstat == 0x00 && | ||
37 | irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END)) | ||
38 | return dasd_era_none; | ||
39 | if (sense[0] & 0x80) { /* CMD reject */ | ||
40 | return dasd_era_fatal; | ||
41 | } | ||
42 | if (sense[0] & 0x40) { /* Drive offline */ | ||
43 | return dasd_era_recover; | ||
44 | } | ||
45 | if (sense[0] & 0x20) { /* Bus out parity */ | ||
46 | return dasd_era_recover; | ||
47 | } | ||
48 | if (sense[0] & 0x10) { /* equipment check */ | ||
49 | if (sense[1] & 0x80) { | ||
50 | return dasd_era_fatal; | ||
51 | } | ||
52 | return dasd_era_recover; | ||
53 | } | ||
54 | if (sense[0] & 0x08) { /* data check */ | ||
55 | if (sense[1] & 0x80) { | ||
56 | return dasd_era_fatal; | ||
57 | } | ||
58 | return dasd_era_recover; | ||
59 | } | ||
60 | if (sense[0] & 0x04) { /* overrun */ | ||
61 | if (sense[1] & 0x80) { | ||
62 | return dasd_era_fatal; | ||
63 | } | ||
64 | return dasd_era_recover; | ||
65 | } | ||
66 | if (sense[1] & 0x40) { /* invalid blocksize */ | ||
67 | return dasd_era_fatal; | ||
68 | } | ||
69 | if (sense[1] & 0x04) { /* file protected */ | ||
70 | return dasd_era_recover; | ||
71 | } | ||
72 | if (sense[1] & 0x01) { /* operation incomplete */ | ||
73 | return dasd_era_recover; | ||
74 | } | ||
75 | if (sense[2] & 0x80) { /* check data erroor */ | ||
76 | return dasd_era_recover; | ||
77 | } | ||
78 | if (sense[2] & 0x10) { /* Env. data present */ | ||
79 | return dasd_era_recover; | ||
80 | } | ||
81 | /* examine the 24 byte sense data */ | ||
82 | return dasd_era_recover; | ||
83 | |||
84 | } /* END dasd_3370_erp_examine */ | ||
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c index 5b7385e430ea..c361ab69ec00 100644 --- a/drivers/s390/block/dasd_3990_erp.c +++ b/drivers/s390/block/dasd_3990_erp.c | |||
@@ -26,158 +26,6 @@ struct DCTL_data { | |||
26 | 26 | ||
27 | /* | 27 | /* |
28 | ***************************************************************************** | 28 | ***************************************************************************** |
29 | * SECTION ERP EXAMINATION | ||
30 | ***************************************************************************** | ||
31 | */ | ||
32 | |||
33 | /* | ||
34 | * DASD_3990_ERP_EXAMINE_24 | ||
35 | * | ||
36 | * DESCRIPTION | ||
37 | * Checks only for fatal (unrecoverable) error. | ||
38 | * A detailed examination of the sense data is done later outside | ||
39 | * the interrupt handler. | ||
40 | * | ||
41 | * Each bit configuration leading to an action code 2 (Exit with | ||
42 | * programming error or unusual condition indication) | ||
43 | * are handled as fatal errors. | ||
44 | * | ||
45 | * All other configurations are handled as recoverable errors. | ||
46 | * | ||
47 | * RETURN VALUES | ||
48 | * dasd_era_fatal for all fatal (unrecoverable errors) | ||
49 | * dasd_era_recover for all others. | ||
50 | */ | ||
51 | static dasd_era_t | ||
52 | dasd_3990_erp_examine_24(struct dasd_ccw_req * cqr, char *sense) | ||
53 | { | ||
54 | |||
55 | struct dasd_device *device = cqr->device; | ||
56 | |||
57 | /* check for 'Command Reject' */ | ||
58 | if ((sense[0] & SNS0_CMD_REJECT) && | ||
59 | (!(sense[2] & SNS2_ENV_DATA_PRESENT))) { | ||
60 | |||
61 | DEV_MESSAGE(KERN_ERR, device, "%s", | ||
62 | "EXAMINE 24: Command Reject detected - " | ||
63 | "fatal error"); | ||
64 | |||
65 | return dasd_era_fatal; | ||
66 | } | ||
67 | |||
68 | /* check for 'Invalid Track Format' */ | ||
69 | if ((sense[1] & SNS1_INV_TRACK_FORMAT) && | ||
70 | (!(sense[2] & SNS2_ENV_DATA_PRESENT))) { | ||
71 | |||
72 | DEV_MESSAGE(KERN_ERR, device, "%s", | ||
73 | "EXAMINE 24: Invalid Track Format detected " | ||
74 | "- fatal error"); | ||
75 | |||
76 | return dasd_era_fatal; | ||
77 | } | ||
78 | |||
79 | /* check for 'No Record Found' */ | ||
80 | if (sense[1] & SNS1_NO_REC_FOUND) { | ||
81 | |||
82 | /* FIXME: fatal error ?!? */ | ||
83 | DEV_MESSAGE(KERN_ERR, device, | ||
84 | "EXAMINE 24: No Record Found detected %s", | ||
85 | device->state <= DASD_STATE_BASIC ? | ||
86 | " " : "- fatal error"); | ||
87 | |||
88 | return dasd_era_fatal; | ||
89 | } | ||
90 | |||
91 | /* return recoverable for all others */ | ||
92 | return dasd_era_recover; | ||
93 | } /* END dasd_3990_erp_examine_24 */ | ||
94 | |||
95 | /* | ||
96 | * DASD_3990_ERP_EXAMINE_32 | ||
97 | * | ||
98 | * DESCRIPTION | ||
99 | * Checks only for fatal/no/recoverable error. | ||
100 | * A detailed examination of the sense data is done later outside | ||
101 | * the interrupt handler. | ||
102 | * | ||
103 | * RETURN VALUES | ||
104 | * dasd_era_none no error | ||
105 | * dasd_era_fatal for all fatal (unrecoverable errors) | ||
106 | * dasd_era_recover for recoverable others. | ||
107 | */ | ||
108 | static dasd_era_t | ||
109 | dasd_3990_erp_examine_32(struct dasd_ccw_req * cqr, char *sense) | ||
110 | { | ||
111 | |||
112 | struct dasd_device *device = cqr->device; | ||
113 | |||
114 | switch (sense[25]) { | ||
115 | case 0x00: | ||
116 | return dasd_era_none; | ||
117 | |||
118 | case 0x01: | ||
119 | DEV_MESSAGE(KERN_ERR, device, "%s", "EXAMINE 32: fatal error"); | ||
120 | |||
121 | return dasd_era_fatal; | ||
122 | |||
123 | default: | ||
124 | |||
125 | return dasd_era_recover; | ||
126 | } | ||
127 | |||
128 | } /* end dasd_3990_erp_examine_32 */ | ||
129 | |||
130 | /* | ||
131 | * DASD_3990_ERP_EXAMINE | ||
132 | * | ||
133 | * DESCRIPTION | ||
134 | * Checks only for fatal/no/recover error. | ||
135 | * A detailed examination of the sense data is done later outside | ||
136 | * the interrupt handler. | ||
137 | * | ||
138 | * The logic is based on the 'IBM 3990 Storage Control Reference' manual | ||
139 | * 'Chapter 7. Error Recovery Procedures'. | ||
140 | * | ||
141 | * RETURN VALUES | ||
142 | * dasd_era_none no error | ||
143 | * dasd_era_fatal for all fatal (unrecoverable errors) | ||
144 | * dasd_era_recover for all others. | ||
145 | */ | ||
146 | dasd_era_t | ||
147 | dasd_3990_erp_examine(struct dasd_ccw_req * cqr, struct irb * irb) | ||
148 | { | ||
149 | |||
150 | char *sense = irb->ecw; | ||
151 | dasd_era_t era = dasd_era_recover; | ||
152 | struct dasd_device *device = cqr->device; | ||
153 | |||
154 | /* check for successful execution first */ | ||
155 | if (irb->scsw.cstat == 0x00 && | ||
156 | irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END)) | ||
157 | return dasd_era_none; | ||
158 | |||
159 | /* distinguish between 24 and 32 byte sense data */ | ||
160 | if (sense[27] & DASD_SENSE_BIT_0) { | ||
161 | |||
162 | era = dasd_3990_erp_examine_24(cqr, sense); | ||
163 | |||
164 | } else { | ||
165 | |||
166 | era = dasd_3990_erp_examine_32(cqr, sense); | ||
167 | |||
168 | } | ||
169 | |||
170 | /* log the erp chain if fatal error occurred */ | ||
171 | if ((era == dasd_era_fatal) && (device->state >= DASD_STATE_READY)) { | ||
172 | dasd_log_sense(cqr, irb); | ||
173 | } | ||
174 | |||
175 | return era; | ||
176 | |||
177 | } /* END dasd_3990_erp_examine */ | ||
178 | |||
179 | /* | ||
180 | ***************************************************************************** | ||
181 | * SECTION ERP HANDLING | 29 | * SECTION ERP HANDLING |
182 | ***************************************************************************** | 30 | ***************************************************************************** |
183 | */ | 31 | */ |
@@ -206,7 +54,7 @@ dasd_3990_erp_cleanup(struct dasd_ccw_req * erp, char final_status) | |||
206 | { | 54 | { |
207 | struct dasd_ccw_req *cqr = erp->refers; | 55 | struct dasd_ccw_req *cqr = erp->refers; |
208 | 56 | ||
209 | dasd_free_erp_request(erp, erp->device); | 57 | dasd_free_erp_request(erp, erp->memdev); |
210 | cqr->status = final_status; | 58 | cqr->status = final_status; |
211 | return cqr; | 59 | return cqr; |
212 | 60 | ||
@@ -224,15 +72,17 @@ static void | |||
224 | dasd_3990_erp_block_queue(struct dasd_ccw_req * erp, int expires) | 72 | dasd_3990_erp_block_queue(struct dasd_ccw_req * erp, int expires) |
225 | { | 73 | { |
226 | 74 | ||
227 | struct dasd_device *device = erp->device; | 75 | struct dasd_device *device = erp->startdev; |
76 | unsigned long flags; | ||
228 | 77 | ||
229 | DEV_MESSAGE(KERN_INFO, device, | 78 | DEV_MESSAGE(KERN_INFO, device, |
230 | "blocking request queue for %is", expires/HZ); | 79 | "blocking request queue for %is", expires/HZ); |
231 | 80 | ||
81 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | ||
232 | device->stopped |= DASD_STOPPED_PENDING; | 82 | device->stopped |= DASD_STOPPED_PENDING; |
233 | erp->status = DASD_CQR_QUEUED; | 83 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); |
234 | 84 | erp->status = DASD_CQR_FILLED; | |
235 | dasd_set_timer(device, expires); | 85 | dasd_block_set_timer(device->block, expires); |
236 | } | 86 | } |
237 | 87 | ||
238 | /* | 88 | /* |
@@ -251,7 +101,7 @@ static struct dasd_ccw_req * | |||
251 | dasd_3990_erp_int_req(struct dasd_ccw_req * erp) | 101 | dasd_3990_erp_int_req(struct dasd_ccw_req * erp) |
252 | { | 102 | { |
253 | 103 | ||
254 | struct dasd_device *device = erp->device; | 104 | struct dasd_device *device = erp->startdev; |
255 | 105 | ||
256 | /* first time set initial retry counter and erp_function */ | 106 | /* first time set initial retry counter and erp_function */ |
257 | /* and retry once without blocking queue */ | 107 | /* and retry once without blocking queue */ |
@@ -292,11 +142,14 @@ dasd_3990_erp_int_req(struct dasd_ccw_req * erp) | |||
292 | static void | 142 | static void |
293 | dasd_3990_erp_alternate_path(struct dasd_ccw_req * erp) | 143 | dasd_3990_erp_alternate_path(struct dasd_ccw_req * erp) |
294 | { | 144 | { |
295 | struct dasd_device *device = erp->device; | 145 | struct dasd_device *device = erp->startdev; |
296 | __u8 opm; | 146 | __u8 opm; |
147 | unsigned long flags; | ||
297 | 148 | ||
298 | /* try alternate valid path */ | 149 | /* try alternate valid path */ |
150 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | ||
299 | opm = ccw_device_get_path_mask(device->cdev); | 151 | opm = ccw_device_get_path_mask(device->cdev); |
152 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); | ||
300 | //FIXME: start with get_opm ? | 153 | //FIXME: start with get_opm ? |
301 | if (erp->lpm == 0) | 154 | if (erp->lpm == 0) |
302 | erp->lpm = LPM_ANYPATH & ~(erp->irb.esw.esw0.sublog.lpum); | 155 | erp->lpm = LPM_ANYPATH & ~(erp->irb.esw.esw0.sublog.lpum); |
@@ -309,9 +162,8 @@ dasd_3990_erp_alternate_path(struct dasd_ccw_req * erp) | |||
309 | "try alternate lpm=%x (lpum=%x / opm=%x)", | 162 | "try alternate lpm=%x (lpum=%x / opm=%x)", |
310 | erp->lpm, erp->irb.esw.esw0.sublog.lpum, opm); | 163 | erp->lpm, erp->irb.esw.esw0.sublog.lpum, opm); |
311 | 164 | ||
312 | /* reset status to queued to handle the request again... */ | 165 | /* reset status to submit the request again... */ |
313 | if (erp->status > DASD_CQR_QUEUED) | 166 | erp->status = DASD_CQR_FILLED; |
314 | erp->status = DASD_CQR_QUEUED; | ||
315 | erp->retries = 1; | 167 | erp->retries = 1; |
316 | } else { | 168 | } else { |
317 | DEV_MESSAGE(KERN_ERR, device, | 169 | DEV_MESSAGE(KERN_ERR, device, |
@@ -320,8 +172,7 @@ dasd_3990_erp_alternate_path(struct dasd_ccw_req * erp) | |||
320 | erp->irb.esw.esw0.sublog.lpum, opm); | 172 | erp->irb.esw.esw0.sublog.lpum, opm); |
321 | 173 | ||
322 | /* post request with permanent error */ | 174 | /* post request with permanent error */ |
323 | if (erp->status > DASD_CQR_QUEUED) | 175 | erp->status = DASD_CQR_FAILED; |
324 | erp->status = DASD_CQR_FAILED; | ||
325 | } | 176 | } |
326 | } /* end dasd_3990_erp_alternate_path */ | 177 | } /* end dasd_3990_erp_alternate_path */ |
327 | 178 | ||
@@ -344,14 +195,14 @@ static struct dasd_ccw_req * | |||
344 | dasd_3990_erp_DCTL(struct dasd_ccw_req * erp, char modifier) | 195 | dasd_3990_erp_DCTL(struct dasd_ccw_req * erp, char modifier) |
345 | { | 196 | { |
346 | 197 | ||
347 | struct dasd_device *device = erp->device; | 198 | struct dasd_device *device = erp->startdev; |
348 | struct DCTL_data *DCTL_data; | 199 | struct DCTL_data *DCTL_data; |
349 | struct ccw1 *ccw; | 200 | struct ccw1 *ccw; |
350 | struct dasd_ccw_req *dctl_cqr; | 201 | struct dasd_ccw_req *dctl_cqr; |
351 | 202 | ||
352 | dctl_cqr = dasd_alloc_erp_request((char *) &erp->magic, 1, | 203 | dctl_cqr = dasd_alloc_erp_request((char *) &erp->magic, 1, |
353 | sizeof (struct DCTL_data), | 204 | sizeof(struct DCTL_data), |
354 | erp->device); | 205 | device); |
355 | if (IS_ERR(dctl_cqr)) { | 206 | if (IS_ERR(dctl_cqr)) { |
356 | DEV_MESSAGE(KERN_ERR, device, "%s", | 207 | DEV_MESSAGE(KERN_ERR, device, "%s", |
357 | "Unable to allocate DCTL-CQR"); | 208 | "Unable to allocate DCTL-CQR"); |
@@ -365,13 +216,14 @@ dasd_3990_erp_DCTL(struct dasd_ccw_req * erp, char modifier) | |||
365 | DCTL_data->modifier = modifier; | 216 | DCTL_data->modifier = modifier; |
366 | 217 | ||
367 | ccw = dctl_cqr->cpaddr; | 218 | ccw = dctl_cqr->cpaddr; |
368 | memset(ccw, 0, sizeof (struct ccw1)); | 219 | memset(ccw, 0, sizeof(struct ccw1)); |
369 | ccw->cmd_code = CCW_CMD_DCTL; | 220 | ccw->cmd_code = CCW_CMD_DCTL; |
370 | ccw->count = 4; | 221 | ccw->count = 4; |
371 | ccw->cda = (__u32)(addr_t) DCTL_data; | 222 | ccw->cda = (__u32)(addr_t) DCTL_data; |
372 | dctl_cqr->function = dasd_3990_erp_DCTL; | 223 | dctl_cqr->function = dasd_3990_erp_DCTL; |
373 | dctl_cqr->refers = erp; | 224 | dctl_cqr->refers = erp; |
374 | dctl_cqr->device = erp->device; | 225 | dctl_cqr->startdev = device; |
226 | dctl_cqr->memdev = device; | ||
375 | dctl_cqr->magic = erp->magic; | 227 | dctl_cqr->magic = erp->magic; |
376 | dctl_cqr->expires = 5 * 60 * HZ; | 228 | dctl_cqr->expires = 5 * 60 * HZ; |
377 | dctl_cqr->retries = 2; | 229 | dctl_cqr->retries = 2; |
@@ -435,7 +287,7 @@ static struct dasd_ccw_req * | |||
435 | dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense) | 287 | dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense) |
436 | { | 288 | { |
437 | 289 | ||
438 | struct dasd_device *device = erp->device; | 290 | struct dasd_device *device = erp->startdev; |
439 | 291 | ||
440 | /* first time set initial retry counter and erp_function */ | 292 | /* first time set initial retry counter and erp_function */ |
441 | /* and retry once without waiting for state change pending */ | 293 | /* and retry once without waiting for state change pending */ |
@@ -472,7 +324,7 @@ dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense) | |||
472 | "redriving request immediately, " | 324 | "redriving request immediately, " |
473 | "%d retries left", | 325 | "%d retries left", |
474 | erp->retries); | 326 | erp->retries); |
475 | erp->status = DASD_CQR_QUEUED; | 327 | erp->status = DASD_CQR_FILLED; |
476 | } | 328 | } |
477 | } | 329 | } |
478 | 330 | ||
@@ -530,7 +382,7 @@ static void | |||
530 | dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense) | 382 | dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense) |
531 | { | 383 | { |
532 | 384 | ||
533 | struct dasd_device *device = erp->device; | 385 | struct dasd_device *device = erp->startdev; |
534 | char msg_format = (sense[7] & 0xF0); | 386 | char msg_format = (sense[7] & 0xF0); |
535 | char msg_no = (sense[7] & 0x0F); | 387 | char msg_no = (sense[7] & 0x0F); |
536 | 388 | ||
@@ -1157,7 +1009,7 @@ static struct dasd_ccw_req * | |||
1157 | dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense) | 1009 | dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense) |
1158 | { | 1010 | { |
1159 | 1011 | ||
1160 | struct dasd_device *device = erp->device; | 1012 | struct dasd_device *device = erp->startdev; |
1161 | 1013 | ||
1162 | erp->function = dasd_3990_erp_com_rej; | 1014 | erp->function = dasd_3990_erp_com_rej; |
1163 | 1015 | ||
@@ -1198,7 +1050,7 @@ static struct dasd_ccw_req * | |||
1198 | dasd_3990_erp_bus_out(struct dasd_ccw_req * erp) | 1050 | dasd_3990_erp_bus_out(struct dasd_ccw_req * erp) |
1199 | { | 1051 | { |
1200 | 1052 | ||
1201 | struct dasd_device *device = erp->device; | 1053 | struct dasd_device *device = erp->startdev; |
1202 | 1054 | ||
1203 | /* first time set initial retry counter and erp_function */ | 1055 | /* first time set initial retry counter and erp_function */ |
1204 | /* and retry once without blocking queue */ | 1056 | /* and retry once without blocking queue */ |
@@ -1237,7 +1089,7 @@ static struct dasd_ccw_req * | |||
1237 | dasd_3990_erp_equip_check(struct dasd_ccw_req * erp, char *sense) | 1089 | dasd_3990_erp_equip_check(struct dasd_ccw_req * erp, char *sense) |
1238 | { | 1090 | { |
1239 | 1091 | ||
1240 | struct dasd_device *device = erp->device; | 1092 | struct dasd_device *device = erp->startdev; |
1241 | 1093 | ||
1242 | erp->function = dasd_3990_erp_equip_check; | 1094 | erp->function = dasd_3990_erp_equip_check; |
1243 | 1095 | ||
@@ -1279,7 +1131,6 @@ dasd_3990_erp_equip_check(struct dasd_ccw_req * erp, char *sense) | |||
1279 | 1131 | ||
1280 | erp = dasd_3990_erp_action_5(erp); | 1132 | erp = dasd_3990_erp_action_5(erp); |
1281 | } | 1133 | } |
1282 | |||
1283 | return erp; | 1134 | return erp; |
1284 | 1135 | ||
1285 | } /* end dasd_3990_erp_equip_check */ | 1136 | } /* end dasd_3990_erp_equip_check */ |
@@ -1299,7 +1150,7 @@ static struct dasd_ccw_req * | |||
1299 | dasd_3990_erp_data_check(struct dasd_ccw_req * erp, char *sense) | 1150 | dasd_3990_erp_data_check(struct dasd_ccw_req * erp, char *sense) |
1300 | { | 1151 | { |
1301 | 1152 | ||
1302 | struct dasd_device *device = erp->device; | 1153 | struct dasd_device *device = erp->startdev; |
1303 | 1154 | ||
1304 | erp->function = dasd_3990_erp_data_check; | 1155 | erp->function = dasd_3990_erp_data_check; |
1305 | 1156 | ||
@@ -1358,7 +1209,7 @@ static struct dasd_ccw_req * | |||
1358 | dasd_3990_erp_overrun(struct dasd_ccw_req * erp, char *sense) | 1209 | dasd_3990_erp_overrun(struct dasd_ccw_req * erp, char *sense) |
1359 | { | 1210 | { |
1360 | 1211 | ||
1361 | struct dasd_device *device = erp->device; | 1212 | struct dasd_device *device = erp->startdev; |
1362 | 1213 | ||
1363 | erp->function = dasd_3990_erp_overrun; | 1214 | erp->function = dasd_3990_erp_overrun; |
1364 | 1215 | ||
@@ -1387,7 +1238,7 @@ static struct dasd_ccw_req * | |||
1387 | dasd_3990_erp_inv_format(struct dasd_ccw_req * erp, char *sense) | 1238 | dasd_3990_erp_inv_format(struct dasd_ccw_req * erp, char *sense) |
1388 | { | 1239 | { |
1389 | 1240 | ||
1390 | struct dasd_device *device = erp->device; | 1241 | struct dasd_device *device = erp->startdev; |
1391 | 1242 | ||
1392 | erp->function = dasd_3990_erp_inv_format; | 1243 | erp->function = dasd_3990_erp_inv_format; |
1393 | 1244 | ||
@@ -1403,8 +1254,7 @@ dasd_3990_erp_inv_format(struct dasd_ccw_req * erp, char *sense) | |||
1403 | 1254 | ||
1404 | } else { | 1255 | } else { |
1405 | DEV_MESSAGE(KERN_ERR, device, "%s", | 1256 | DEV_MESSAGE(KERN_ERR, device, "%s", |
1406 | "Invalid Track Format - Fatal error should have " | 1257 | "Invalid Track Format - Fatal error"); |
1407 | "been handled within the interrupt handler"); | ||
1408 | 1258 | ||
1409 | erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED); | 1259 | erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED); |
1410 | } | 1260 | } |
@@ -1428,7 +1278,7 @@ static struct dasd_ccw_req * | |||
1428 | dasd_3990_erp_EOC(struct dasd_ccw_req * default_erp, char *sense) | 1278 | dasd_3990_erp_EOC(struct dasd_ccw_req * default_erp, char *sense) |
1429 | { | 1279 | { |
1430 | 1280 | ||
1431 | struct dasd_device *device = default_erp->device; | 1281 | struct dasd_device *device = default_erp->startdev; |
1432 | 1282 | ||
1433 | DEV_MESSAGE(KERN_ERR, device, "%s", | 1283 | DEV_MESSAGE(KERN_ERR, device, "%s", |
1434 | "End-of-Cylinder - must never happen"); | 1284 | "End-of-Cylinder - must never happen"); |
@@ -1453,7 +1303,7 @@ static struct dasd_ccw_req * | |||
1453 | dasd_3990_erp_env_data(struct dasd_ccw_req * erp, char *sense) | 1303 | dasd_3990_erp_env_data(struct dasd_ccw_req * erp, char *sense) |
1454 | { | 1304 | { |
1455 | 1305 | ||
1456 | struct dasd_device *device = erp->device; | 1306 | struct dasd_device *device = erp->startdev; |
1457 | 1307 | ||
1458 | erp->function = dasd_3990_erp_env_data; | 1308 | erp->function = dasd_3990_erp_env_data; |
1459 | 1309 | ||
@@ -1463,11 +1313,9 @@ dasd_3990_erp_env_data(struct dasd_ccw_req * erp, char *sense) | |||
1463 | 1313 | ||
1464 | /* don't retry on disabled interface */ | 1314 | /* don't retry on disabled interface */ |
1465 | if (sense[7] != 0x0F) { | 1315 | if (sense[7] != 0x0F) { |
1466 | |||
1467 | erp = dasd_3990_erp_action_4(erp, sense); | 1316 | erp = dasd_3990_erp_action_4(erp, sense); |
1468 | } else { | 1317 | } else { |
1469 | 1318 | erp->status = DASD_CQR_FILLED; | |
1470 | erp = dasd_3990_erp_cleanup(erp, DASD_CQR_IN_IO); | ||
1471 | } | 1319 | } |
1472 | 1320 | ||
1473 | return erp; | 1321 | return erp; |
@@ -1490,11 +1338,10 @@ static struct dasd_ccw_req * | |||
1490 | dasd_3990_erp_no_rec(struct dasd_ccw_req * default_erp, char *sense) | 1338 | dasd_3990_erp_no_rec(struct dasd_ccw_req * default_erp, char *sense) |
1491 | { | 1339 | { |
1492 | 1340 | ||
1493 | struct dasd_device *device = default_erp->device; | 1341 | struct dasd_device *device = default_erp->startdev; |
1494 | 1342 | ||
1495 | DEV_MESSAGE(KERN_ERR, device, "%s", | 1343 | DEV_MESSAGE(KERN_ERR, device, "%s", |
1496 | "No Record Found - Fatal error should " | 1344 | "No Record Found - Fatal error "); |
1497 | "have been handled within the interrupt handler"); | ||
1498 | 1345 | ||
1499 | return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED); | 1346 | return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED); |
1500 | 1347 | ||
@@ -1517,7 +1364,7 @@ static struct dasd_ccw_req * | |||
1517 | dasd_3990_erp_file_prot(struct dasd_ccw_req * erp) | 1364 | dasd_3990_erp_file_prot(struct dasd_ccw_req * erp) |
1518 | { | 1365 | { |
1519 | 1366 | ||
1520 | struct dasd_device *device = erp->device; | 1367 | struct dasd_device *device = erp->startdev; |
1521 | 1368 | ||
1522 | DEV_MESSAGE(KERN_ERR, device, "%s", "File Protected"); | 1369 | DEV_MESSAGE(KERN_ERR, device, "%s", "File Protected"); |
1523 | 1370 | ||
@@ -1526,6 +1373,43 @@ dasd_3990_erp_file_prot(struct dasd_ccw_req * erp) | |||
1526 | } /* end dasd_3990_erp_file_prot */ | 1373 | } /* end dasd_3990_erp_file_prot */ |
1527 | 1374 | ||
1528 | /* | 1375 | /* |
1376 | * DASD_3990_ERP_INSPECT_ALIAS | ||
1377 | * | ||
1378 | * DESCRIPTION | ||
1379 | * Checks if the original request was started on an alias device. | ||
1380 | * If yes, it modifies the original and the erp request so that | ||
1381 | * the erp request can be started on a base device. | ||
1382 | * | ||
1383 | * PARAMETER | ||
1384 | * erp pointer to the currently created default ERP | ||
1385 | * | ||
1386 | * RETURN VALUES | ||
1387 | * erp pointer to the modified ERP, or NULL | ||
1388 | */ | ||
1389 | |||
1390 | static struct dasd_ccw_req *dasd_3990_erp_inspect_alias( | ||
1391 | struct dasd_ccw_req *erp) | ||
1392 | { | ||
1393 | struct dasd_ccw_req *cqr = erp->refers; | ||
1394 | |||
1395 | if (cqr->block && | ||
1396 | (cqr->block->base != cqr->startdev)) { | ||
1397 | if (cqr->startdev->features & DASD_FEATURE_ERPLOG) { | ||
1398 | DEV_MESSAGE(KERN_ERR, cqr->startdev, | ||
1399 | "ERP on alias device for request %p," | ||
1400 | " recover on base device %s", cqr, | ||
1401 | cqr->block->base->cdev->dev.bus_id); | ||
1402 | } | ||
1403 | dasd_eckd_reset_ccw_to_base_io(cqr); | ||
1404 | erp->startdev = cqr->block->base; | ||
1405 | erp->function = dasd_3990_erp_inspect_alias; | ||
1406 | return erp; | ||
1407 | } else | ||
1408 | return NULL; | ||
1409 | } | ||
1410 | |||
1411 | |||
1412 | /* | ||
1529 | * DASD_3990_ERP_INSPECT_24 | 1413 | * DASD_3990_ERP_INSPECT_24 |
1530 | * | 1414 | * |
1531 | * DESCRIPTION | 1415 | * DESCRIPTION |
@@ -1623,7 +1507,7 @@ static struct dasd_ccw_req * | |||
1623 | dasd_3990_erp_action_10_32(struct dasd_ccw_req * erp, char *sense) | 1507 | dasd_3990_erp_action_10_32(struct dasd_ccw_req * erp, char *sense) |
1624 | { | 1508 | { |
1625 | 1509 | ||
1626 | struct dasd_device *device = erp->device; | 1510 | struct dasd_device *device = erp->startdev; |
1627 | 1511 | ||
1628 | erp->retries = 256; | 1512 | erp->retries = 256; |
1629 | erp->function = dasd_3990_erp_action_10_32; | 1513 | erp->function = dasd_3990_erp_action_10_32; |
@@ -1657,13 +1541,14 @@ static struct dasd_ccw_req * | |||
1657 | dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense) | 1541 | dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense) |
1658 | { | 1542 | { |
1659 | 1543 | ||
1660 | struct dasd_device *device = default_erp->device; | 1544 | struct dasd_device *device = default_erp->startdev; |
1661 | __u32 cpa = 0; | 1545 | __u32 cpa = 0; |
1662 | struct dasd_ccw_req *cqr; | 1546 | struct dasd_ccw_req *cqr; |
1663 | struct dasd_ccw_req *erp; | 1547 | struct dasd_ccw_req *erp; |
1664 | struct DE_eckd_data *DE_data; | 1548 | struct DE_eckd_data *DE_data; |
1549 | struct PFX_eckd_data *PFX_data; | ||
1665 | char *LO_data; /* LO_eckd_data_t */ | 1550 | char *LO_data; /* LO_eckd_data_t */ |
1666 | struct ccw1 *ccw; | 1551 | struct ccw1 *ccw, *oldccw; |
1667 | 1552 | ||
1668 | DEV_MESSAGE(KERN_DEBUG, device, "%s", | 1553 | DEV_MESSAGE(KERN_DEBUG, device, "%s", |
1669 | "Write not finished because of unexpected condition"); | 1554 | "Write not finished because of unexpected condition"); |
@@ -1702,8 +1587,8 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense) | |||
1702 | /* Build new ERP request including DE/LO */ | 1587 | /* Build new ERP request including DE/LO */ |
1703 | erp = dasd_alloc_erp_request((char *) &cqr->magic, | 1588 | erp = dasd_alloc_erp_request((char *) &cqr->magic, |
1704 | 2 + 1,/* DE/LO + TIC */ | 1589 | 2 + 1,/* DE/LO + TIC */ |
1705 | sizeof (struct DE_eckd_data) + | 1590 | sizeof(struct DE_eckd_data) + |
1706 | sizeof (struct LO_eckd_data), device); | 1591 | sizeof(struct LO_eckd_data), device); |
1707 | 1592 | ||
1708 | if (IS_ERR(erp)) { | 1593 | if (IS_ERR(erp)) { |
1709 | DEV_MESSAGE(KERN_ERR, device, "%s", "Unable to allocate ERP"); | 1594 | DEV_MESSAGE(KERN_ERR, device, "%s", "Unable to allocate ERP"); |
@@ -1712,10 +1597,16 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense) | |||
1712 | 1597 | ||
1713 | /* use original DE */ | 1598 | /* use original DE */ |
1714 | DE_data = erp->data; | 1599 | DE_data = erp->data; |
1715 | memcpy(DE_data, cqr->data, sizeof (struct DE_eckd_data)); | 1600 | oldccw = cqr->cpaddr; |
1601 | if (oldccw->cmd_code == DASD_ECKD_CCW_PFX) { | ||
1602 | PFX_data = cqr->data; | ||
1603 | memcpy(DE_data, &PFX_data->define_extend, | ||
1604 | sizeof(struct DE_eckd_data)); | ||
1605 | } else | ||
1606 | memcpy(DE_data, cqr->data, sizeof(struct DE_eckd_data)); | ||
1716 | 1607 | ||
1717 | /* create LO */ | 1608 | /* create LO */ |
1718 | LO_data = erp->data + sizeof (struct DE_eckd_data); | 1609 | LO_data = erp->data + sizeof(struct DE_eckd_data); |
1719 | 1610 | ||
1720 | if ((sense[3] == 0x01) && (LO_data[1] & 0x01)) { | 1611 | if ((sense[3] == 0x01) && (LO_data[1] & 0x01)) { |
1721 | 1612 | ||
@@ -1748,7 +1639,7 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense) | |||
1748 | 1639 | ||
1749 | /* create DE ccw */ | 1640 | /* create DE ccw */ |
1750 | ccw = erp->cpaddr; | 1641 | ccw = erp->cpaddr; |
1751 | memset(ccw, 0, sizeof (struct ccw1)); | 1642 | memset(ccw, 0, sizeof(struct ccw1)); |
1752 | ccw->cmd_code = DASD_ECKD_CCW_DEFINE_EXTENT; | 1643 | ccw->cmd_code = DASD_ECKD_CCW_DEFINE_EXTENT; |
1753 | ccw->flags = CCW_FLAG_CC; | 1644 | ccw->flags = CCW_FLAG_CC; |
1754 | ccw->count = 16; | 1645 | ccw->count = 16; |
@@ -1756,7 +1647,7 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense) | |||
1756 | 1647 | ||
1757 | /* create LO ccw */ | 1648 | /* create LO ccw */ |
1758 | ccw++; | 1649 | ccw++; |
1759 | memset(ccw, 0, sizeof (struct ccw1)); | 1650 | memset(ccw, 0, sizeof(struct ccw1)); |
1760 | ccw->cmd_code = DASD_ECKD_CCW_LOCATE_RECORD; | 1651 | ccw->cmd_code = DASD_ECKD_CCW_LOCATE_RECORD; |
1761 | ccw->flags = CCW_FLAG_CC; | 1652 | ccw->flags = CCW_FLAG_CC; |
1762 | ccw->count = 16; | 1653 | ccw->count = 16; |
@@ -1770,7 +1661,8 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense) | |||
1770 | /* fill erp related fields */ | 1661 | /* fill erp related fields */ |
1771 | erp->function = dasd_3990_erp_action_1B_32; | 1662 | erp->function = dasd_3990_erp_action_1B_32; |
1772 | erp->refers = default_erp->refers; | 1663 | erp->refers = default_erp->refers; |
1773 | erp->device = device; | 1664 | erp->startdev = device; |
1665 | erp->memdev = device; | ||
1774 | erp->magic = default_erp->magic; | 1666 | erp->magic = default_erp->magic; |
1775 | erp->expires = 0; | 1667 | erp->expires = 0; |
1776 | erp->retries = 256; | 1668 | erp->retries = 256; |
@@ -1803,7 +1695,7 @@ static struct dasd_ccw_req * | |||
1803 | dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense) | 1695 | dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense) |
1804 | { | 1696 | { |
1805 | 1697 | ||
1806 | struct dasd_device *device = previous_erp->device; | 1698 | struct dasd_device *device = previous_erp->startdev; |
1807 | __u32 cpa = 0; | 1699 | __u32 cpa = 0; |
1808 | struct dasd_ccw_req *cqr; | 1700 | struct dasd_ccw_req *cqr; |
1809 | struct dasd_ccw_req *erp; | 1701 | struct dasd_ccw_req *erp; |
@@ -1827,7 +1719,7 @@ dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense) | |||
1827 | DEV_MESSAGE(KERN_DEBUG, device, "%s", | 1719 | DEV_MESSAGE(KERN_DEBUG, device, "%s", |
1828 | "Imprecise ending is set - just retry"); | 1720 | "Imprecise ending is set - just retry"); |
1829 | 1721 | ||
1830 | previous_erp->status = DASD_CQR_QUEUED; | 1722 | previous_erp->status = DASD_CQR_FILLED; |
1831 | 1723 | ||
1832 | return previous_erp; | 1724 | return previous_erp; |
1833 | } | 1725 | } |
@@ -1850,7 +1742,7 @@ dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense) | |||
1850 | erp = previous_erp; | 1742 | erp = previous_erp; |
1851 | 1743 | ||
1852 | /* update the LO with the new returned sense data */ | 1744 | /* update the LO with the new returned sense data */ |
1853 | LO_data = erp->data + sizeof (struct DE_eckd_data); | 1745 | LO_data = erp->data + sizeof(struct DE_eckd_data); |
1854 | 1746 | ||
1855 | if ((sense[3] == 0x01) && (LO_data[1] & 0x01)) { | 1747 | if ((sense[3] == 0x01) && (LO_data[1] & 0x01)) { |
1856 | 1748 | ||
@@ -1889,7 +1781,7 @@ dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense) | |||
1889 | ccw++; /* addr of TIC ccw */ | 1781 | ccw++; /* addr of TIC ccw */ |
1890 | ccw->cda = cpa; | 1782 | ccw->cda = cpa; |
1891 | 1783 | ||
1892 | erp->status = DASD_CQR_QUEUED; | 1784 | erp->status = DASD_CQR_FILLED; |
1893 | 1785 | ||
1894 | return erp; | 1786 | return erp; |
1895 | 1787 | ||
@@ -1968,9 +1860,7 @@ dasd_3990_erp_compound_path(struct dasd_ccw_req * erp, char *sense) | |||
1968 | * try further actions. */ | 1860 | * try further actions. */ |
1969 | 1861 | ||
1970 | erp->lpm = 0; | 1862 | erp->lpm = 0; |
1971 | 1863 | erp->status = DASD_CQR_NEED_ERP; | |
1972 | erp->status = DASD_CQR_ERROR; | ||
1973 | |||
1974 | } | 1864 | } |
1975 | } | 1865 | } |
1976 | 1866 | ||
@@ -2047,7 +1937,7 @@ dasd_3990_erp_compound_config(struct dasd_ccw_req * erp, char *sense) | |||
2047 | if ((sense[25] & DASD_SENSE_BIT_1) && (sense[26] & DASD_SENSE_BIT_2)) { | 1937 | if ((sense[25] & DASD_SENSE_BIT_1) && (sense[26] & DASD_SENSE_BIT_2)) { |
2048 | 1938 | ||
2049 | /* set to suspended duplex state then restart */ | 1939 | /* set to suspended duplex state then restart */ |
2050 | struct dasd_device *device = erp->device; | 1940 | struct dasd_device *device = erp->startdev; |
2051 | 1941 | ||
2052 | DEV_MESSAGE(KERN_ERR, device, "%s", | 1942 | DEV_MESSAGE(KERN_ERR, device, "%s", |
2053 | "Set device to suspended duplex state should be " | 1943 | "Set device to suspended duplex state should be " |
@@ -2081,28 +1971,26 @@ dasd_3990_erp_compound(struct dasd_ccw_req * erp, char *sense) | |||
2081 | { | 1971 | { |
2082 | 1972 | ||
2083 | if ((erp->function == dasd_3990_erp_compound_retry) && | 1973 | if ((erp->function == dasd_3990_erp_compound_retry) && |
2084 | (erp->status == DASD_CQR_ERROR)) { | 1974 | (erp->status == DASD_CQR_NEED_ERP)) { |
2085 | 1975 | ||
2086 | dasd_3990_erp_compound_path(erp, sense); | 1976 | dasd_3990_erp_compound_path(erp, sense); |
2087 | } | 1977 | } |
2088 | 1978 | ||
2089 | if ((erp->function == dasd_3990_erp_compound_path) && | 1979 | if ((erp->function == dasd_3990_erp_compound_path) && |
2090 | (erp->status == DASD_CQR_ERROR)) { | 1980 | (erp->status == DASD_CQR_NEED_ERP)) { |
2091 | 1981 | ||
2092 | erp = dasd_3990_erp_compound_code(erp, sense); | 1982 | erp = dasd_3990_erp_compound_code(erp, sense); |
2093 | } | 1983 | } |
2094 | 1984 | ||
2095 | if ((erp->function == dasd_3990_erp_compound_code) && | 1985 | if ((erp->function == dasd_3990_erp_compound_code) && |
2096 | (erp->status == DASD_CQR_ERROR)) { | 1986 | (erp->status == DASD_CQR_NEED_ERP)) { |
2097 | 1987 | ||
2098 | dasd_3990_erp_compound_config(erp, sense); | 1988 | dasd_3990_erp_compound_config(erp, sense); |
2099 | } | 1989 | } |
2100 | 1990 | ||
2101 | /* if no compound action ERP specified, the request failed */ | 1991 | /* if no compound action ERP specified, the request failed */ |
2102 | if (erp->status == DASD_CQR_ERROR) { | 1992 | if (erp->status == DASD_CQR_NEED_ERP) |
2103 | |||
2104 | erp->status = DASD_CQR_FAILED; | 1993 | erp->status = DASD_CQR_FAILED; |
2105 | } | ||
2106 | 1994 | ||
2107 | return erp; | 1995 | return erp; |
2108 | 1996 | ||
@@ -2127,7 +2015,7 @@ static struct dasd_ccw_req * | |||
2127 | dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense) | 2015 | dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense) |
2128 | { | 2016 | { |
2129 | 2017 | ||
2130 | struct dasd_device *device = erp->device; | 2018 | struct dasd_device *device = erp->startdev; |
2131 | 2019 | ||
2132 | erp->function = dasd_3990_erp_inspect_32; | 2020 | erp->function = dasd_3990_erp_inspect_32; |
2133 | 2021 | ||
@@ -2149,8 +2037,7 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense) | |||
2149 | 2037 | ||
2150 | case 0x01: /* fatal error */ | 2038 | case 0x01: /* fatal error */ |
2151 | DEV_MESSAGE(KERN_ERR, device, "%s", | 2039 | DEV_MESSAGE(KERN_ERR, device, "%s", |
2152 | "Fatal error should have been " | 2040 | "Retry not recommended - Fatal error"); |
2153 | "handled within the interrupt handler"); | ||
2154 | 2041 | ||
2155 | erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED); | 2042 | erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED); |
2156 | break; | 2043 | break; |
@@ -2253,6 +2140,11 @@ dasd_3990_erp_inspect(struct dasd_ccw_req * erp) | |||
2253 | /* already set up new ERP ! */ | 2140 | /* already set up new ERP ! */ |
2254 | char *sense = erp->refers->irb.ecw; | 2141 | char *sense = erp->refers->irb.ecw; |
2255 | 2142 | ||
2143 | /* if this problem occured on an alias retry on base */ | ||
2144 | erp_new = dasd_3990_erp_inspect_alias(erp); | ||
2145 | if (erp_new) | ||
2146 | return erp_new; | ||
2147 | |||
2256 | /* distinguish between 24 and 32 byte sense data */ | 2148 | /* distinguish between 24 and 32 byte sense data */ |
2257 | if (sense[27] & DASD_SENSE_BIT_0) { | 2149 | if (sense[27] & DASD_SENSE_BIT_0) { |
2258 | 2150 | ||
@@ -2287,13 +2179,13 @@ static struct dasd_ccw_req * | |||
2287 | dasd_3990_erp_add_erp(struct dasd_ccw_req * cqr) | 2179 | dasd_3990_erp_add_erp(struct dasd_ccw_req * cqr) |
2288 | { | 2180 | { |
2289 | 2181 | ||
2290 | struct dasd_device *device = cqr->device; | 2182 | struct dasd_device *device = cqr->startdev; |
2291 | struct ccw1 *ccw; | 2183 | struct ccw1 *ccw; |
2292 | 2184 | ||
2293 | /* allocate additional request block */ | 2185 | /* allocate additional request block */ |
2294 | struct dasd_ccw_req *erp; | 2186 | struct dasd_ccw_req *erp; |
2295 | 2187 | ||
2296 | erp = dasd_alloc_erp_request((char *) &cqr->magic, 2, 0, cqr->device); | 2188 | erp = dasd_alloc_erp_request((char *) &cqr->magic, 2, 0, device); |
2297 | if (IS_ERR(erp)) { | 2189 | if (IS_ERR(erp)) { |
2298 | if (cqr->retries <= 0) { | 2190 | if (cqr->retries <= 0) { |
2299 | DEV_MESSAGE(KERN_ERR, device, "%s", | 2191 | DEV_MESSAGE(KERN_ERR, device, "%s", |
@@ -2305,7 +2197,7 @@ dasd_3990_erp_add_erp(struct dasd_ccw_req * cqr) | |||
2305 | "Unable to allocate ERP request " | 2197 | "Unable to allocate ERP request " |
2306 | "(%i retries left)", | 2198 | "(%i retries left)", |
2307 | cqr->retries); | 2199 | cqr->retries); |
2308 | dasd_set_timer(device, (HZ << 3)); | 2200 | dasd_block_set_timer(device->block, (HZ << 3)); |
2309 | } | 2201 | } |
2310 | return cqr; | 2202 | return cqr; |
2311 | } | 2203 | } |
@@ -2319,7 +2211,9 @@ dasd_3990_erp_add_erp(struct dasd_ccw_req * cqr) | |||
2319 | ccw->cda = (long)(cqr->cpaddr); | 2211 | ccw->cda = (long)(cqr->cpaddr); |
2320 | erp->function = dasd_3990_erp_add_erp; | 2212 | erp->function = dasd_3990_erp_add_erp; |
2321 | erp->refers = cqr; | 2213 | erp->refers = cqr; |
2322 | erp->device = cqr->device; | 2214 | erp->startdev = device; |
2215 | erp->memdev = device; | ||
2216 | erp->block = cqr->block; | ||
2323 | erp->magic = cqr->magic; | 2217 | erp->magic = cqr->magic; |
2324 | erp->expires = 0; | 2218 | erp->expires = 0; |
2325 | erp->retries = 256; | 2219 | erp->retries = 256; |
@@ -2466,7 +2360,7 @@ static struct dasd_ccw_req * | |||
2466 | dasd_3990_erp_further_erp(struct dasd_ccw_req *erp) | 2360 | dasd_3990_erp_further_erp(struct dasd_ccw_req *erp) |
2467 | { | 2361 | { |
2468 | 2362 | ||
2469 | struct dasd_device *device = erp->device; | 2363 | struct dasd_device *device = erp->startdev; |
2470 | char *sense = erp->irb.ecw; | 2364 | char *sense = erp->irb.ecw; |
2471 | 2365 | ||
2472 | /* check for 24 byte sense ERP */ | 2366 | /* check for 24 byte sense ERP */ |
@@ -2557,7 +2451,7 @@ dasd_3990_erp_handle_match_erp(struct dasd_ccw_req *erp_head, | |||
2557 | struct dasd_ccw_req *erp) | 2451 | struct dasd_ccw_req *erp) |
2558 | { | 2452 | { |
2559 | 2453 | ||
2560 | struct dasd_device *device = erp_head->device; | 2454 | struct dasd_device *device = erp_head->startdev; |
2561 | struct dasd_ccw_req *erp_done = erp_head; /* finished req */ | 2455 | struct dasd_ccw_req *erp_done = erp_head; /* finished req */ |
2562 | struct dasd_ccw_req *erp_free = NULL; /* req to be freed */ | 2456 | struct dasd_ccw_req *erp_free = NULL; /* req to be freed */ |
2563 | 2457 | ||
@@ -2569,13 +2463,13 @@ dasd_3990_erp_handle_match_erp(struct dasd_ccw_req *erp_head, | |||
2569 | "original request was lost\n"); | 2463 | "original request was lost\n"); |
2570 | 2464 | ||
2571 | /* remove the request from the device queue */ | 2465 | /* remove the request from the device queue */ |
2572 | list_del(&erp_done->list); | 2466 | list_del(&erp_done->blocklist); |
2573 | 2467 | ||
2574 | erp_free = erp_done; | 2468 | erp_free = erp_done; |
2575 | erp_done = erp_done->refers; | 2469 | erp_done = erp_done->refers; |
2576 | 2470 | ||
2577 | /* free the finished erp request */ | 2471 | /* free the finished erp request */ |
2578 | dasd_free_erp_request(erp_free, erp_free->device); | 2472 | dasd_free_erp_request(erp_free, erp_free->memdev); |
2579 | 2473 | ||
2580 | } /* end while */ | 2474 | } /* end while */ |
2581 | 2475 | ||
@@ -2603,7 +2497,7 @@ dasd_3990_erp_handle_match_erp(struct dasd_ccw_req *erp_head, | |||
2603 | erp->retries, erp); | 2497 | erp->retries, erp); |
2604 | 2498 | ||
2605 | /* handle the request again... */ | 2499 | /* handle the request again... */ |
2606 | erp->status = DASD_CQR_QUEUED; | 2500 | erp->status = DASD_CQR_FILLED; |
2607 | } | 2501 | } |
2608 | 2502 | ||
2609 | } else { | 2503 | } else { |
@@ -2620,7 +2514,7 @@ dasd_3990_erp_handle_match_erp(struct dasd_ccw_req *erp_head, | |||
2620 | * DASD_3990_ERP_ACTION | 2514 | * DASD_3990_ERP_ACTION |
2621 | * | 2515 | * |
2622 | * DESCRIPTION | 2516 | * DESCRIPTION |
2623 | * controll routine for 3990 erp actions. | 2517 | * control routine for 3990 erp actions. |
2624 | * Has to be called with the queue lock (namely the s390_irq_lock) acquired. | 2518 | * Has to be called with the queue lock (namely the s390_irq_lock) acquired. |
2625 | * | 2519 | * |
2626 | * PARAMETER | 2520 | * PARAMETER |
@@ -2636,9 +2530,8 @@ dasd_3990_erp_handle_match_erp(struct dasd_ccw_req *erp_head, | |||
2636 | struct dasd_ccw_req * | 2530 | struct dasd_ccw_req * |
2637 | dasd_3990_erp_action(struct dasd_ccw_req * cqr) | 2531 | dasd_3990_erp_action(struct dasd_ccw_req * cqr) |
2638 | { | 2532 | { |
2639 | |||
2640 | struct dasd_ccw_req *erp = NULL; | 2533 | struct dasd_ccw_req *erp = NULL; |
2641 | struct dasd_device *device = cqr->device; | 2534 | struct dasd_device *device = cqr->startdev; |
2642 | struct dasd_ccw_req *temp_erp = NULL; | 2535 | struct dasd_ccw_req *temp_erp = NULL; |
2643 | 2536 | ||
2644 | if (device->features & DASD_FEATURE_ERPLOG) { | 2537 | if (device->features & DASD_FEATURE_ERPLOG) { |
@@ -2704,10 +2597,11 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr) | |||
2704 | } | 2597 | } |
2705 | } | 2598 | } |
2706 | 2599 | ||
2707 | /* enqueue added ERP request */ | 2600 | /* enqueue ERP request if it's a new one */ |
2708 | if (erp->status == DASD_CQR_FILLED) { | 2601 | if (list_empty(&erp->blocklist)) { |
2709 | erp->status = DASD_CQR_QUEUED; | 2602 | cqr->status = DASD_CQR_IN_ERP; |
2710 | list_add(&erp->list, &device->ccw_queue); | 2603 | /* add erp request before the cqr */ |
2604 | list_add_tail(&erp->blocklist, &cqr->blocklist); | ||
2711 | } | 2605 | } |
2712 | 2606 | ||
2713 | return erp; | 2607 | return erp; |
diff --git a/drivers/s390/block/dasd_9336_erp.c b/drivers/s390/block/dasd_9336_erp.c deleted file mode 100644 index 6e082688475a..000000000000 --- a/drivers/s390/block/dasd_9336_erp.c +++ /dev/null | |||
@@ -1,41 +0,0 @@ | |||
1 | /* | ||
2 | * File...........: linux/drivers/s390/block/dasd_9336_erp.c | ||
3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> | ||
4 | * Bugreports.to..: <Linux390@de.ibm.com> | ||
5 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000 | ||
6 | * | ||
7 | */ | ||
8 | |||
9 | #define PRINTK_HEADER "dasd_erp(9336)" | ||
10 | |||
11 | #include "dasd_int.h" | ||
12 | |||
13 | |||
14 | /* | ||
15 | * DASD_9336_ERP_EXAMINE | ||
16 | * | ||
17 | * DESCRIPTION | ||
18 | * Checks only for fatal/no/recover error. | ||
19 | * A detailed examination of the sense data is done later outside | ||
20 | * the interrupt handler. | ||
21 | * | ||
22 | * The logic is based on the 'IBM 3880 Storage Control Reference' manual | ||
23 | * 'Chapter 7. 9336 Sense Data'. | ||
24 | * | ||
25 | * RETURN VALUES | ||
26 | * dasd_era_none no error | ||
27 | * dasd_era_fatal for all fatal (unrecoverable errors) | ||
28 | * dasd_era_recover for all others. | ||
29 | */ | ||
30 | dasd_era_t | ||
31 | dasd_9336_erp_examine(struct dasd_ccw_req * cqr, struct irb * irb) | ||
32 | { | ||
33 | /* check for successful execution first */ | ||
34 | if (irb->scsw.cstat == 0x00 && | ||
35 | irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END)) | ||
36 | return dasd_era_none; | ||
37 | |||
38 | /* examine the 24 byte sense data */ | ||
39 | return dasd_era_recover; | ||
40 | |||
41 | } /* END dasd_9336_erp_examine */ | ||
diff --git a/drivers/s390/block/dasd_9343_erp.c b/drivers/s390/block/dasd_9343_erp.c deleted file mode 100644 index ddecb9808ed4..000000000000 --- a/drivers/s390/block/dasd_9343_erp.c +++ /dev/null | |||
@@ -1,21 +0,0 @@ | |||
1 | /* | ||
2 | * File...........: linux/drivers/s390/block/dasd_9345_erp.c | ||
3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> | ||
4 | * Bugreports.to..: <Linux390@de.ibm.com> | ||
5 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000 | ||
6 | * | ||
7 | */ | ||
8 | |||
9 | #define PRINTK_HEADER "dasd_erp(9343)" | ||
10 | |||
11 | #include "dasd_int.h" | ||
12 | |||
13 | dasd_era_t | ||
14 | dasd_9343_erp_examine(struct dasd_ccw_req * cqr, struct irb * irb) | ||
15 | { | ||
16 | if (irb->scsw.cstat == 0x00 && | ||
17 | irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END)) | ||
18 | return dasd_era_none; | ||
19 | |||
20 | return dasd_era_recover; | ||
21 | } | ||
diff --git a/drivers/s390/block/dasd_alias.c b/drivers/s390/block/dasd_alias.c new file mode 100644 index 000000000000..3a40bee9d358 --- /dev/null +++ b/drivers/s390/block/dasd_alias.c | |||
@@ -0,0 +1,903 @@ | |||
1 | /* | ||
2 | * PAV alias management for the DASD ECKD discipline | ||
3 | * | ||
4 | * Copyright IBM Corporation, 2007 | ||
5 | * Author(s): Stefan Weinhuber <wein@de.ibm.com> | ||
6 | */ | ||
7 | |||
8 | #include <linux/list.h> | ||
9 | #include <asm/ebcdic.h> | ||
10 | #include "dasd_int.h" | ||
11 | #include "dasd_eckd.h" | ||
12 | |||
13 | #ifdef PRINTK_HEADER | ||
14 | #undef PRINTK_HEADER | ||
15 | #endif /* PRINTK_HEADER */ | ||
16 | #define PRINTK_HEADER "dasd(eckd):" | ||
17 | |||
18 | |||
19 | /* | ||
20 | * General concept of alias management: | ||
21 | * - PAV and DASD alias management is specific to the eckd discipline. | ||
22 | * - A device is connected to an lcu as long as the device exists. | ||
23 | * dasd_alias_make_device_known_to_lcu will be called wenn the | ||
24 | * device is checked by the eckd discipline and | ||
25 | * dasd_alias_disconnect_device_from_lcu will be called | ||
26 | * before the device is deleted. | ||
27 | * - The dasd_alias_add_device / dasd_alias_remove_device | ||
28 | * functions mark the point when a device is 'ready for service'. | ||
29 | * - A summary unit check is a rare occasion, but it is mandatory to | ||
30 | * support it. It requires some complex recovery actions before the | ||
31 | * devices can be used again (see dasd_alias_handle_summary_unit_check). | ||
32 | * - dasd_alias_get_start_dev will find an alias device that can be used | ||
33 | * instead of the base device and does some (very simple) load balancing. | ||
34 | * This is the function that gets called for each I/O, so when improving | ||
35 | * something, this function should get faster or better, the rest has just | ||
36 | * to be correct. | ||
37 | */ | ||
38 | |||
39 | |||
40 | static void summary_unit_check_handling_work(struct work_struct *); | ||
41 | static void lcu_update_work(struct work_struct *); | ||
42 | static int _schedule_lcu_update(struct alias_lcu *, struct dasd_device *); | ||
43 | |||
44 | static struct alias_root aliastree = { | ||
45 | .serverlist = LIST_HEAD_INIT(aliastree.serverlist), | ||
46 | .lock = __SPIN_LOCK_UNLOCKED(aliastree.lock), | ||
47 | }; | ||
48 | |||
49 | static struct alias_server *_find_server(struct dasd_uid *uid) | ||
50 | { | ||
51 | struct alias_server *pos; | ||
52 | list_for_each_entry(pos, &aliastree.serverlist, server) { | ||
53 | if (!strncmp(pos->uid.vendor, uid->vendor, | ||
54 | sizeof(uid->vendor)) | ||
55 | && !strncmp(pos->uid.serial, uid->serial, | ||
56 | sizeof(uid->serial))) | ||
57 | return pos; | ||
58 | }; | ||
59 | return NULL; | ||
60 | } | ||
61 | |||
62 | static struct alias_lcu *_find_lcu(struct alias_server *server, | ||
63 | struct dasd_uid *uid) | ||
64 | { | ||
65 | struct alias_lcu *pos; | ||
66 | list_for_each_entry(pos, &server->lculist, lcu) { | ||
67 | if (pos->uid.ssid == uid->ssid) | ||
68 | return pos; | ||
69 | }; | ||
70 | return NULL; | ||
71 | } | ||
72 | |||
73 | static struct alias_pav_group *_find_group(struct alias_lcu *lcu, | ||
74 | struct dasd_uid *uid) | ||
75 | { | ||
76 | struct alias_pav_group *pos; | ||
77 | __u8 search_unit_addr; | ||
78 | |||
79 | /* for hyper pav there is only one group */ | ||
80 | if (lcu->pav == HYPER_PAV) { | ||
81 | if (list_empty(&lcu->grouplist)) | ||
82 | return NULL; | ||
83 | else | ||
84 | return list_first_entry(&lcu->grouplist, | ||
85 | struct alias_pav_group, group); | ||
86 | } | ||
87 | |||
88 | /* for base pav we have to find the group that matches the base */ | ||
89 | if (uid->type == UA_BASE_DEVICE) | ||
90 | search_unit_addr = uid->real_unit_addr; | ||
91 | else | ||
92 | search_unit_addr = uid->base_unit_addr; | ||
93 | list_for_each_entry(pos, &lcu->grouplist, group) { | ||
94 | if (pos->uid.base_unit_addr == search_unit_addr) | ||
95 | return pos; | ||
96 | }; | ||
97 | return NULL; | ||
98 | } | ||
99 | |||
100 | static struct alias_server *_allocate_server(struct dasd_uid *uid) | ||
101 | { | ||
102 | struct alias_server *server; | ||
103 | |||
104 | server = kzalloc(sizeof(*server), GFP_KERNEL); | ||
105 | if (!server) | ||
106 | return ERR_PTR(-ENOMEM); | ||
107 | memcpy(server->uid.vendor, uid->vendor, sizeof(uid->vendor)); | ||
108 | memcpy(server->uid.serial, uid->serial, sizeof(uid->serial)); | ||
109 | INIT_LIST_HEAD(&server->server); | ||
110 | INIT_LIST_HEAD(&server->lculist); | ||
111 | return server; | ||
112 | } | ||
113 | |||
114 | static void _free_server(struct alias_server *server) | ||
115 | { | ||
116 | kfree(server); | ||
117 | } | ||
118 | |||
119 | static struct alias_lcu *_allocate_lcu(struct dasd_uid *uid) | ||
120 | { | ||
121 | struct alias_lcu *lcu; | ||
122 | |||
123 | lcu = kzalloc(sizeof(*lcu), GFP_KERNEL); | ||
124 | if (!lcu) | ||
125 | return ERR_PTR(-ENOMEM); | ||
126 | lcu->uac = kzalloc(sizeof(*(lcu->uac)), GFP_KERNEL | GFP_DMA); | ||
127 | if (!lcu->uac) | ||
128 | goto out_err1; | ||
129 | lcu->rsu_cqr = kzalloc(sizeof(*lcu->rsu_cqr), GFP_KERNEL | GFP_DMA); | ||
130 | if (!lcu->rsu_cqr) | ||
131 | goto out_err2; | ||
132 | lcu->rsu_cqr->cpaddr = kzalloc(sizeof(struct ccw1), | ||
133 | GFP_KERNEL | GFP_DMA); | ||
134 | if (!lcu->rsu_cqr->cpaddr) | ||
135 | goto out_err3; | ||
136 | lcu->rsu_cqr->data = kzalloc(16, GFP_KERNEL | GFP_DMA); | ||
137 | if (!lcu->rsu_cqr->data) | ||
138 | goto out_err4; | ||
139 | |||
140 | memcpy(lcu->uid.vendor, uid->vendor, sizeof(uid->vendor)); | ||
141 | memcpy(lcu->uid.serial, uid->serial, sizeof(uid->serial)); | ||
142 | lcu->uid.ssid = uid->ssid; | ||
143 | lcu->pav = NO_PAV; | ||
144 | lcu->flags = NEED_UAC_UPDATE | UPDATE_PENDING; | ||
145 | INIT_LIST_HEAD(&lcu->lcu); | ||
146 | INIT_LIST_HEAD(&lcu->inactive_devices); | ||
147 | INIT_LIST_HEAD(&lcu->active_devices); | ||
148 | INIT_LIST_HEAD(&lcu->grouplist); | ||
149 | INIT_WORK(&lcu->suc_data.worker, summary_unit_check_handling_work); | ||
150 | INIT_DELAYED_WORK(&lcu->ruac_data.dwork, lcu_update_work); | ||
151 | spin_lock_init(&lcu->lock); | ||
152 | return lcu; | ||
153 | |||
154 | out_err4: | ||
155 | kfree(lcu->rsu_cqr->cpaddr); | ||
156 | out_err3: | ||
157 | kfree(lcu->rsu_cqr); | ||
158 | out_err2: | ||
159 | kfree(lcu->uac); | ||
160 | out_err1: | ||
161 | kfree(lcu); | ||
162 | return ERR_PTR(-ENOMEM); | ||
163 | } | ||
164 | |||
165 | static void _free_lcu(struct alias_lcu *lcu) | ||
166 | { | ||
167 | kfree(lcu->rsu_cqr->data); | ||
168 | kfree(lcu->rsu_cqr->cpaddr); | ||
169 | kfree(lcu->rsu_cqr); | ||
170 | kfree(lcu->uac); | ||
171 | kfree(lcu); | ||
172 | } | ||
173 | |||
174 | /* | ||
175 | * This is the function that will allocate all the server and lcu data, | ||
176 | * so this function must be called first for a new device. | ||
177 | * If the return value is 1, the lcu was already known before, if it | ||
178 | * is 0, this is a new lcu. | ||
179 | * Negative return code indicates that something went wrong (e.g. -ENOMEM) | ||
180 | */ | ||
181 | int dasd_alias_make_device_known_to_lcu(struct dasd_device *device) | ||
182 | { | ||
183 | struct dasd_eckd_private *private; | ||
184 | unsigned long flags; | ||
185 | struct alias_server *server, *newserver; | ||
186 | struct alias_lcu *lcu, *newlcu; | ||
187 | int is_lcu_known; | ||
188 | struct dasd_uid *uid; | ||
189 | |||
190 | private = (struct dasd_eckd_private *) device->private; | ||
191 | uid = &private->uid; | ||
192 | spin_lock_irqsave(&aliastree.lock, flags); | ||
193 | is_lcu_known = 1; | ||
194 | server = _find_server(uid); | ||
195 | if (!server) { | ||
196 | spin_unlock_irqrestore(&aliastree.lock, flags); | ||
197 | newserver = _allocate_server(uid); | ||
198 | if (IS_ERR(newserver)) | ||
199 | return PTR_ERR(newserver); | ||
200 | spin_lock_irqsave(&aliastree.lock, flags); | ||
201 | server = _find_server(uid); | ||
202 | if (!server) { | ||
203 | list_add(&newserver->server, &aliastree.serverlist); | ||
204 | server = newserver; | ||
205 | is_lcu_known = 0; | ||
206 | } else { | ||
207 | /* someone was faster */ | ||
208 | _free_server(newserver); | ||
209 | } | ||
210 | } | ||
211 | |||
212 | lcu = _find_lcu(server, uid); | ||
213 | if (!lcu) { | ||
214 | spin_unlock_irqrestore(&aliastree.lock, flags); | ||
215 | newlcu = _allocate_lcu(uid); | ||
216 | if (IS_ERR(newlcu)) | ||
217 | return PTR_ERR(lcu); | ||
218 | spin_lock_irqsave(&aliastree.lock, flags); | ||
219 | lcu = _find_lcu(server, uid); | ||
220 | if (!lcu) { | ||
221 | list_add(&newlcu->lcu, &server->lculist); | ||
222 | lcu = newlcu; | ||
223 | is_lcu_known = 0; | ||
224 | } else { | ||
225 | /* someone was faster */ | ||
226 | _free_lcu(newlcu); | ||
227 | } | ||
228 | is_lcu_known = 0; | ||
229 | } | ||
230 | spin_lock(&lcu->lock); | ||
231 | list_add(&device->alias_list, &lcu->inactive_devices); | ||
232 | private->lcu = lcu; | ||
233 | spin_unlock(&lcu->lock); | ||
234 | spin_unlock_irqrestore(&aliastree.lock, flags); | ||
235 | |||
236 | return is_lcu_known; | ||
237 | } | ||
238 | |||
239 | /* | ||
240 | * This function removes a device from the scope of alias management. | ||
241 | * The complicated part is to make sure that it is not in use by | ||
242 | * any of the workers. If necessary cancel the work. | ||
243 | */ | ||
244 | void dasd_alias_disconnect_device_from_lcu(struct dasd_device *device) | ||
245 | { | ||
246 | struct dasd_eckd_private *private; | ||
247 | unsigned long flags; | ||
248 | struct alias_lcu *lcu; | ||
249 | struct alias_server *server; | ||
250 | int was_pending; | ||
251 | |||
252 | private = (struct dasd_eckd_private *) device->private; | ||
253 | lcu = private->lcu; | ||
254 | spin_lock_irqsave(&lcu->lock, flags); | ||
255 | list_del_init(&device->alias_list); | ||
256 | /* make sure that the workers don't use this device */ | ||
257 | if (device == lcu->suc_data.device) { | ||
258 | spin_unlock_irqrestore(&lcu->lock, flags); | ||
259 | cancel_work_sync(&lcu->suc_data.worker); | ||
260 | spin_lock_irqsave(&lcu->lock, flags); | ||
261 | if (device == lcu->suc_data.device) | ||
262 | lcu->suc_data.device = NULL; | ||
263 | } | ||
264 | was_pending = 0; | ||
265 | if (device == lcu->ruac_data.device) { | ||
266 | spin_unlock_irqrestore(&lcu->lock, flags); | ||
267 | was_pending = 1; | ||
268 | cancel_delayed_work_sync(&lcu->ruac_data.dwork); | ||
269 | spin_lock_irqsave(&lcu->lock, flags); | ||
270 | if (device == lcu->ruac_data.device) | ||
271 | lcu->ruac_data.device = NULL; | ||
272 | } | ||
273 | private->lcu = NULL; | ||
274 | spin_unlock_irqrestore(&lcu->lock, flags); | ||
275 | |||
276 | spin_lock_irqsave(&aliastree.lock, flags); | ||
277 | spin_lock(&lcu->lock); | ||
278 | if (list_empty(&lcu->grouplist) && | ||
279 | list_empty(&lcu->active_devices) && | ||
280 | list_empty(&lcu->inactive_devices)) { | ||
281 | list_del(&lcu->lcu); | ||
282 | spin_unlock(&lcu->lock); | ||
283 | _free_lcu(lcu); | ||
284 | lcu = NULL; | ||
285 | } else { | ||
286 | if (was_pending) | ||
287 | _schedule_lcu_update(lcu, NULL); | ||
288 | spin_unlock(&lcu->lock); | ||
289 | } | ||
290 | server = _find_server(&private->uid); | ||
291 | if (server && list_empty(&server->lculist)) { | ||
292 | list_del(&server->server); | ||
293 | _free_server(server); | ||
294 | } | ||
295 | spin_unlock_irqrestore(&aliastree.lock, flags); | ||
296 | } | ||
297 | |||
298 | /* | ||
299 | * This function assumes that the unit address configuration stored | ||
300 | * in the lcu is up to date and will update the device uid before | ||
301 | * adding it to a pav group. | ||
302 | */ | ||
303 | static int _add_device_to_lcu(struct alias_lcu *lcu, | ||
304 | struct dasd_device *device) | ||
305 | { | ||
306 | |||
307 | struct dasd_eckd_private *private; | ||
308 | struct alias_pav_group *group; | ||
309 | struct dasd_uid *uid; | ||
310 | |||
311 | private = (struct dasd_eckd_private *) device->private; | ||
312 | uid = &private->uid; | ||
313 | uid->type = lcu->uac->unit[uid->real_unit_addr].ua_type; | ||
314 | uid->base_unit_addr = lcu->uac->unit[uid->real_unit_addr].base_ua; | ||
315 | dasd_set_uid(device->cdev, &private->uid); | ||
316 | |||
317 | /* if we have no PAV anyway, we don't need to bother with PAV groups */ | ||
318 | if (lcu->pav == NO_PAV) { | ||
319 | list_move(&device->alias_list, &lcu->active_devices); | ||
320 | return 0; | ||
321 | } | ||
322 | |||
323 | group = _find_group(lcu, uid); | ||
324 | if (!group) { | ||
325 | group = kzalloc(sizeof(*group), GFP_ATOMIC); | ||
326 | if (!group) | ||
327 | return -ENOMEM; | ||
328 | memcpy(group->uid.vendor, uid->vendor, sizeof(uid->vendor)); | ||
329 | memcpy(group->uid.serial, uid->serial, sizeof(uid->serial)); | ||
330 | group->uid.ssid = uid->ssid; | ||
331 | if (uid->type == UA_BASE_DEVICE) | ||
332 | group->uid.base_unit_addr = uid->real_unit_addr; | ||
333 | else | ||
334 | group->uid.base_unit_addr = uid->base_unit_addr; | ||
335 | INIT_LIST_HEAD(&group->group); | ||
336 | INIT_LIST_HEAD(&group->baselist); | ||
337 | INIT_LIST_HEAD(&group->aliaslist); | ||
338 | list_add(&group->group, &lcu->grouplist); | ||
339 | } | ||
340 | if (uid->type == UA_BASE_DEVICE) | ||
341 | list_move(&device->alias_list, &group->baselist); | ||
342 | else | ||
343 | list_move(&device->alias_list, &group->aliaslist); | ||
344 | private->pavgroup = group; | ||
345 | return 0; | ||
346 | }; | ||
347 | |||
348 | static void _remove_device_from_lcu(struct alias_lcu *lcu, | ||
349 | struct dasd_device *device) | ||
350 | { | ||
351 | struct dasd_eckd_private *private; | ||
352 | struct alias_pav_group *group; | ||
353 | |||
354 | private = (struct dasd_eckd_private *) device->private; | ||
355 | list_move(&device->alias_list, &lcu->inactive_devices); | ||
356 | group = private->pavgroup; | ||
357 | if (!group) | ||
358 | return; | ||
359 | private->pavgroup = NULL; | ||
360 | if (list_empty(&group->baselist) && list_empty(&group->aliaslist)) { | ||
361 | list_del(&group->group); | ||
362 | kfree(group); | ||
363 | return; | ||
364 | } | ||
365 | if (group->next == device) | ||
366 | group->next = NULL; | ||
367 | }; | ||
368 | |||
369 | static int read_unit_address_configuration(struct dasd_device *device, | ||
370 | struct alias_lcu *lcu) | ||
371 | { | ||
372 | struct dasd_psf_prssd_data *prssdp; | ||
373 | struct dasd_ccw_req *cqr; | ||
374 | struct ccw1 *ccw; | ||
375 | int rc; | ||
376 | unsigned long flags; | ||
377 | |||
378 | cqr = dasd_kmalloc_request("ECKD", | ||
379 | 1 /* PSF */ + 1 /* RSSD */ , | ||
380 | (sizeof(struct dasd_psf_prssd_data)), | ||
381 | device); | ||
382 | if (IS_ERR(cqr)) | ||
383 | return PTR_ERR(cqr); | ||
384 | cqr->startdev = device; | ||
385 | cqr->memdev = device; | ||
386 | clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); | ||
387 | cqr->retries = 10; | ||
388 | cqr->expires = 20 * HZ; | ||
389 | |||
390 | /* Prepare for Read Subsystem Data */ | ||
391 | prssdp = (struct dasd_psf_prssd_data *) cqr->data; | ||
392 | memset(prssdp, 0, sizeof(struct dasd_psf_prssd_data)); | ||
393 | prssdp->order = PSF_ORDER_PRSSD; | ||
394 | prssdp->suborder = 0x0e; /* Read unit address configuration */ | ||
395 | /* all other bytes of prssdp must be zero */ | ||
396 | |||
397 | ccw = cqr->cpaddr; | ||
398 | ccw->cmd_code = DASD_ECKD_CCW_PSF; | ||
399 | ccw->count = sizeof(struct dasd_psf_prssd_data); | ||
400 | ccw->flags |= CCW_FLAG_CC; | ||
401 | ccw->cda = (__u32)(addr_t) prssdp; | ||
402 | |||
403 | /* Read Subsystem Data - feature codes */ | ||
404 | memset(lcu->uac, 0, sizeof(*(lcu->uac))); | ||
405 | |||
406 | ccw++; | ||
407 | ccw->cmd_code = DASD_ECKD_CCW_RSSD; | ||
408 | ccw->count = sizeof(*(lcu->uac)); | ||
409 | ccw->cda = (__u32)(addr_t) lcu->uac; | ||
410 | |||
411 | cqr->buildclk = get_clock(); | ||
412 | cqr->status = DASD_CQR_FILLED; | ||
413 | |||
414 | /* need to unset flag here to detect race with summary unit check */ | ||
415 | spin_lock_irqsave(&lcu->lock, flags); | ||
416 | lcu->flags &= ~NEED_UAC_UPDATE; | ||
417 | spin_unlock_irqrestore(&lcu->lock, flags); | ||
418 | |||
419 | do { | ||
420 | rc = dasd_sleep_on(cqr); | ||
421 | } while (rc && (cqr->retries > 0)); | ||
422 | if (rc) { | ||
423 | spin_lock_irqsave(&lcu->lock, flags); | ||
424 | lcu->flags |= NEED_UAC_UPDATE; | ||
425 | spin_unlock_irqrestore(&lcu->lock, flags); | ||
426 | } | ||
427 | dasd_kfree_request(cqr, cqr->memdev); | ||
428 | return rc; | ||
429 | } | ||
430 | |||
431 | static int _lcu_update(struct dasd_device *refdev, struct alias_lcu *lcu) | ||
432 | { | ||
433 | unsigned long flags; | ||
434 | struct alias_pav_group *pavgroup, *tempgroup; | ||
435 | struct dasd_device *device, *tempdev; | ||
436 | int i, rc; | ||
437 | struct dasd_eckd_private *private; | ||
438 | |||
439 | spin_lock_irqsave(&lcu->lock, flags); | ||
440 | list_for_each_entry_safe(pavgroup, tempgroup, &lcu->grouplist, group) { | ||
441 | list_for_each_entry_safe(device, tempdev, &pavgroup->baselist, | ||
442 | alias_list) { | ||
443 | list_move(&device->alias_list, &lcu->active_devices); | ||
444 | private = (struct dasd_eckd_private *) device->private; | ||
445 | private->pavgroup = NULL; | ||
446 | } | ||
447 | list_for_each_entry_safe(device, tempdev, &pavgroup->aliaslist, | ||
448 | alias_list) { | ||
449 | list_move(&device->alias_list, &lcu->active_devices); | ||
450 | private = (struct dasd_eckd_private *) device->private; | ||
451 | private->pavgroup = NULL; | ||
452 | } | ||
453 | list_del(&pavgroup->group); | ||
454 | kfree(pavgroup); | ||
455 | } | ||
456 | spin_unlock_irqrestore(&lcu->lock, flags); | ||
457 | |||
458 | rc = read_unit_address_configuration(refdev, lcu); | ||
459 | if (rc) | ||
460 | return rc; | ||
461 | |||
462 | spin_lock_irqsave(&lcu->lock, flags); | ||
463 | lcu->pav = NO_PAV; | ||
464 | for (i = 0; i < MAX_DEVICES_PER_LCU; ++i) { | ||
465 | switch (lcu->uac->unit[i].ua_type) { | ||
466 | case UA_BASE_PAV_ALIAS: | ||
467 | lcu->pav = BASE_PAV; | ||
468 | break; | ||
469 | case UA_HYPER_PAV_ALIAS: | ||
470 | lcu->pav = HYPER_PAV; | ||
471 | break; | ||
472 | } | ||
473 | if (lcu->pav != NO_PAV) | ||
474 | break; | ||
475 | } | ||
476 | |||
477 | list_for_each_entry_safe(device, tempdev, &lcu->active_devices, | ||
478 | alias_list) { | ||
479 | _add_device_to_lcu(lcu, device); | ||
480 | } | ||
481 | spin_unlock_irqrestore(&lcu->lock, flags); | ||
482 | return 0; | ||
483 | } | ||
484 | |||
485 | static void lcu_update_work(struct work_struct *work) | ||
486 | { | ||
487 | struct alias_lcu *lcu; | ||
488 | struct read_uac_work_data *ruac_data; | ||
489 | struct dasd_device *device; | ||
490 | unsigned long flags; | ||
491 | int rc; | ||
492 | |||
493 | ruac_data = container_of(work, struct read_uac_work_data, dwork.work); | ||
494 | lcu = container_of(ruac_data, struct alias_lcu, ruac_data); | ||
495 | device = ruac_data->device; | ||
496 | rc = _lcu_update(device, lcu); | ||
497 | /* | ||
498 | * Need to check flags again, as there could have been another | ||
499 | * prepare_update or a new device a new device while we were still | ||
500 | * processing the data | ||
501 | */ | ||
502 | spin_lock_irqsave(&lcu->lock, flags); | ||
503 | if (rc || (lcu->flags & NEED_UAC_UPDATE)) { | ||
504 | DEV_MESSAGE(KERN_WARNING, device, "could not update" | ||
505 | " alias data in lcu (rc = %d), retry later", rc); | ||
506 | schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ); | ||
507 | } else { | ||
508 | lcu->ruac_data.device = NULL; | ||
509 | lcu->flags &= ~UPDATE_PENDING; | ||
510 | } | ||
511 | spin_unlock_irqrestore(&lcu->lock, flags); | ||
512 | } | ||
513 | |||
514 | static int _schedule_lcu_update(struct alias_lcu *lcu, | ||
515 | struct dasd_device *device) | ||
516 | { | ||
517 | struct dasd_device *usedev = NULL; | ||
518 | struct alias_pav_group *group; | ||
519 | |||
520 | lcu->flags |= NEED_UAC_UPDATE; | ||
521 | if (lcu->ruac_data.device) { | ||
522 | /* already scheduled or running */ | ||
523 | return 0; | ||
524 | } | ||
525 | if (device && !list_empty(&device->alias_list)) | ||
526 | usedev = device; | ||
527 | |||
528 | if (!usedev && !list_empty(&lcu->grouplist)) { | ||
529 | group = list_first_entry(&lcu->grouplist, | ||
530 | struct alias_pav_group, group); | ||
531 | if (!list_empty(&group->baselist)) | ||
532 | usedev = list_first_entry(&group->baselist, | ||
533 | struct dasd_device, | ||
534 | alias_list); | ||
535 | else if (!list_empty(&group->aliaslist)) | ||
536 | usedev = list_first_entry(&group->aliaslist, | ||
537 | struct dasd_device, | ||
538 | alias_list); | ||
539 | } | ||
540 | if (!usedev && !list_empty(&lcu->active_devices)) { | ||
541 | usedev = list_first_entry(&lcu->active_devices, | ||
542 | struct dasd_device, alias_list); | ||
543 | } | ||
544 | /* | ||
545 | * if we haven't found a proper device yet, give up for now, the next | ||
546 | * device that will be set active will trigger an lcu update | ||
547 | */ | ||
548 | if (!usedev) | ||
549 | return -EINVAL; | ||
550 | lcu->ruac_data.device = usedev; | ||
551 | schedule_delayed_work(&lcu->ruac_data.dwork, 0); | ||
552 | return 0; | ||
553 | } | ||
554 | |||
555 | int dasd_alias_add_device(struct dasd_device *device) | ||
556 | { | ||
557 | struct dasd_eckd_private *private; | ||
558 | struct alias_lcu *lcu; | ||
559 | unsigned long flags; | ||
560 | int rc; | ||
561 | |||
562 | private = (struct dasd_eckd_private *) device->private; | ||
563 | lcu = private->lcu; | ||
564 | rc = 0; | ||
565 | spin_lock_irqsave(&lcu->lock, flags); | ||
566 | if (!(lcu->flags & UPDATE_PENDING)) { | ||
567 | rc = _add_device_to_lcu(lcu, device); | ||
568 | if (rc) | ||
569 | lcu->flags |= UPDATE_PENDING; | ||
570 | } | ||
571 | if (lcu->flags & UPDATE_PENDING) { | ||
572 | list_move(&device->alias_list, &lcu->active_devices); | ||
573 | _schedule_lcu_update(lcu, device); | ||
574 | } | ||
575 | spin_unlock_irqrestore(&lcu->lock, flags); | ||
576 | return rc; | ||
577 | } | ||
578 | |||
579 | int dasd_alias_remove_device(struct dasd_device *device) | ||
580 | { | ||
581 | struct dasd_eckd_private *private; | ||
582 | struct alias_lcu *lcu; | ||
583 | unsigned long flags; | ||
584 | |||
585 | private = (struct dasd_eckd_private *) device->private; | ||
586 | lcu = private->lcu; | ||
587 | spin_lock_irqsave(&lcu->lock, flags); | ||
588 | _remove_device_from_lcu(lcu, device); | ||
589 | spin_unlock_irqrestore(&lcu->lock, flags); | ||
590 | return 0; | ||
591 | } | ||
592 | |||
593 | struct dasd_device *dasd_alias_get_start_dev(struct dasd_device *base_device) | ||
594 | { | ||
595 | |||
596 | struct dasd_device *alias_device; | ||
597 | struct alias_pav_group *group; | ||
598 | struct alias_lcu *lcu; | ||
599 | struct dasd_eckd_private *private, *alias_priv; | ||
600 | unsigned long flags; | ||
601 | |||
602 | private = (struct dasd_eckd_private *) base_device->private; | ||
603 | group = private->pavgroup; | ||
604 | lcu = private->lcu; | ||
605 | if (!group || !lcu) | ||
606 | return NULL; | ||
607 | if (lcu->pav == NO_PAV || | ||
608 | lcu->flags & (NEED_UAC_UPDATE | UPDATE_PENDING)) | ||
609 | return NULL; | ||
610 | |||
611 | spin_lock_irqsave(&lcu->lock, flags); | ||
612 | alias_device = group->next; | ||
613 | if (!alias_device) { | ||
614 | if (list_empty(&group->aliaslist)) { | ||
615 | spin_unlock_irqrestore(&lcu->lock, flags); | ||
616 | return NULL; | ||
617 | } else { | ||
618 | alias_device = list_first_entry(&group->aliaslist, | ||
619 | struct dasd_device, | ||
620 | alias_list); | ||
621 | } | ||
622 | } | ||
623 | if (list_is_last(&alias_device->alias_list, &group->aliaslist)) | ||
624 | group->next = list_first_entry(&group->aliaslist, | ||
625 | struct dasd_device, alias_list); | ||
626 | else | ||
627 | group->next = list_first_entry(&alias_device->alias_list, | ||
628 | struct dasd_device, alias_list); | ||
629 | spin_unlock_irqrestore(&lcu->lock, flags); | ||
630 | alias_priv = (struct dasd_eckd_private *) alias_device->private; | ||
631 | if ((alias_priv->count < private->count) && !alias_device->stopped) | ||
632 | return alias_device; | ||
633 | else | ||
634 | return NULL; | ||
635 | } | ||
636 | |||
637 | /* | ||
638 | * Summary unit check handling depends on the way alias devices | ||
639 | * are handled so it is done here rather then in dasd_eckd.c | ||
640 | */ | ||
641 | static int reset_summary_unit_check(struct alias_lcu *lcu, | ||
642 | struct dasd_device *device, | ||
643 | char reason) | ||
644 | { | ||
645 | struct dasd_ccw_req *cqr; | ||
646 | int rc = 0; | ||
647 | |||
648 | cqr = lcu->rsu_cqr; | ||
649 | strncpy((char *) &cqr->magic, "ECKD", 4); | ||
650 | ASCEBC((char *) &cqr->magic, 4); | ||
651 | cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RSCK; | ||
652 | cqr->cpaddr->flags = 0 ; | ||
653 | cqr->cpaddr->count = 16; | ||
654 | cqr->cpaddr->cda = (__u32)(addr_t) cqr->data; | ||
655 | ((char *)cqr->data)[0] = reason; | ||
656 | |||
657 | clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); | ||
658 | cqr->retries = 255; /* set retry counter to enable basic ERP */ | ||
659 | cqr->startdev = device; | ||
660 | cqr->memdev = device; | ||
661 | cqr->block = NULL; | ||
662 | cqr->expires = 5 * HZ; | ||
663 | cqr->buildclk = get_clock(); | ||
664 | cqr->status = DASD_CQR_FILLED; | ||
665 | |||
666 | rc = dasd_sleep_on_immediatly(cqr); | ||
667 | return rc; | ||
668 | } | ||
669 | |||
670 | static void _restart_all_base_devices_on_lcu(struct alias_lcu *lcu) | ||
671 | { | ||
672 | struct alias_pav_group *pavgroup; | ||
673 | struct dasd_device *device; | ||
674 | struct dasd_eckd_private *private; | ||
675 | |||
676 | /* active and inactive list can contain alias as well as base devices */ | ||
677 | list_for_each_entry(device, &lcu->active_devices, alias_list) { | ||
678 | private = (struct dasd_eckd_private *) device->private; | ||
679 | if (private->uid.type != UA_BASE_DEVICE) | ||
680 | continue; | ||
681 | dasd_schedule_block_bh(device->block); | ||
682 | dasd_schedule_device_bh(device); | ||
683 | } | ||
684 | list_for_each_entry(device, &lcu->inactive_devices, alias_list) { | ||
685 | private = (struct dasd_eckd_private *) device->private; | ||
686 | if (private->uid.type != UA_BASE_DEVICE) | ||
687 | continue; | ||
688 | dasd_schedule_block_bh(device->block); | ||
689 | dasd_schedule_device_bh(device); | ||
690 | } | ||
691 | list_for_each_entry(pavgroup, &lcu->grouplist, group) { | ||
692 | list_for_each_entry(device, &pavgroup->baselist, alias_list) { | ||
693 | dasd_schedule_block_bh(device->block); | ||
694 | dasd_schedule_device_bh(device); | ||
695 | } | ||
696 | } | ||
697 | } | ||
698 | |||
699 | static void flush_all_alias_devices_on_lcu(struct alias_lcu *lcu) | ||
700 | { | ||
701 | struct alias_pav_group *pavgroup; | ||
702 | struct dasd_device *device, *temp; | ||
703 | struct dasd_eckd_private *private; | ||
704 | int rc; | ||
705 | unsigned long flags; | ||
706 | LIST_HEAD(active); | ||
707 | |||
708 | /* | ||
709 | * Problem here ist that dasd_flush_device_queue may wait | ||
710 | * for termination of a request to complete. We can't keep | ||
711 | * the lcu lock during that time, so we must assume that | ||
712 | * the lists may have changed. | ||
713 | * Idea: first gather all active alias devices in a separate list, | ||
714 | * then flush the first element of this list unlocked, and afterwards | ||
715 | * check if it is still on the list before moving it to the | ||
716 | * active_devices list. | ||
717 | */ | ||
718 | |||
719 | spin_lock_irqsave(&lcu->lock, flags); | ||
720 | list_for_each_entry_safe(device, temp, &lcu->active_devices, | ||
721 | alias_list) { | ||
722 | private = (struct dasd_eckd_private *) device->private; | ||
723 | if (private->uid.type == UA_BASE_DEVICE) | ||
724 | continue; | ||
725 | list_move(&device->alias_list, &active); | ||
726 | } | ||
727 | |||
728 | list_for_each_entry(pavgroup, &lcu->grouplist, group) { | ||
729 | list_splice_init(&pavgroup->aliaslist, &active); | ||
730 | } | ||
731 | while (!list_empty(&active)) { | ||
732 | device = list_first_entry(&active, struct dasd_device, | ||
733 | alias_list); | ||
734 | spin_unlock_irqrestore(&lcu->lock, flags); | ||
735 | rc = dasd_flush_device_queue(device); | ||
736 | spin_lock_irqsave(&lcu->lock, flags); | ||
737 | /* | ||
738 | * only move device around if it wasn't moved away while we | ||
739 | * were waiting for the flush | ||
740 | */ | ||
741 | if (device == list_first_entry(&active, | ||
742 | struct dasd_device, alias_list)) | ||
743 | list_move(&device->alias_list, &lcu->active_devices); | ||
744 | } | ||
745 | spin_unlock_irqrestore(&lcu->lock, flags); | ||
746 | } | ||
747 | |||
748 | /* | ||
749 | * This function is called in interrupt context, so the | ||
750 | * cdev lock for device is already locked! | ||
751 | */ | ||
752 | static void _stop_all_devices_on_lcu(struct alias_lcu *lcu, | ||
753 | struct dasd_device *device) | ||
754 | { | ||
755 | struct alias_pav_group *pavgroup; | ||
756 | struct dasd_device *pos; | ||
757 | |||
758 | list_for_each_entry(pos, &lcu->active_devices, alias_list) { | ||
759 | if (pos != device) | ||
760 | spin_lock(get_ccwdev_lock(pos->cdev)); | ||
761 | pos->stopped |= DASD_STOPPED_SU; | ||
762 | if (pos != device) | ||
763 | spin_unlock(get_ccwdev_lock(pos->cdev)); | ||
764 | } | ||
765 | list_for_each_entry(pos, &lcu->inactive_devices, alias_list) { | ||
766 | if (pos != device) | ||
767 | spin_lock(get_ccwdev_lock(pos->cdev)); | ||
768 | pos->stopped |= DASD_STOPPED_SU; | ||
769 | if (pos != device) | ||
770 | spin_unlock(get_ccwdev_lock(pos->cdev)); | ||
771 | } | ||
772 | list_for_each_entry(pavgroup, &lcu->grouplist, group) { | ||
773 | list_for_each_entry(pos, &pavgroup->baselist, alias_list) { | ||
774 | if (pos != device) | ||
775 | spin_lock(get_ccwdev_lock(pos->cdev)); | ||
776 | pos->stopped |= DASD_STOPPED_SU; | ||
777 | if (pos != device) | ||
778 | spin_unlock(get_ccwdev_lock(pos->cdev)); | ||
779 | } | ||
780 | list_for_each_entry(pos, &pavgroup->aliaslist, alias_list) { | ||
781 | if (pos != device) | ||
782 | spin_lock(get_ccwdev_lock(pos->cdev)); | ||
783 | pos->stopped |= DASD_STOPPED_SU; | ||
784 | if (pos != device) | ||
785 | spin_unlock(get_ccwdev_lock(pos->cdev)); | ||
786 | } | ||
787 | } | ||
788 | } | ||
789 | |||
790 | static void _unstop_all_devices_on_lcu(struct alias_lcu *lcu) | ||
791 | { | ||
792 | struct alias_pav_group *pavgroup; | ||
793 | struct dasd_device *device; | ||
794 | unsigned long flags; | ||
795 | |||
796 | list_for_each_entry(device, &lcu->active_devices, alias_list) { | ||
797 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | ||
798 | device->stopped &= ~DASD_STOPPED_SU; | ||
799 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); | ||
800 | } | ||
801 | |||
802 | list_for_each_entry(device, &lcu->inactive_devices, alias_list) { | ||
803 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | ||
804 | device->stopped &= ~DASD_STOPPED_SU; | ||
805 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); | ||
806 | } | ||
807 | |||
808 | list_for_each_entry(pavgroup, &lcu->grouplist, group) { | ||
809 | list_for_each_entry(device, &pavgroup->baselist, alias_list) { | ||
810 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | ||
811 | device->stopped &= ~DASD_STOPPED_SU; | ||
812 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), | ||
813 | flags); | ||
814 | } | ||
815 | list_for_each_entry(device, &pavgroup->aliaslist, alias_list) { | ||
816 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | ||
817 | device->stopped &= ~DASD_STOPPED_SU; | ||
818 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), | ||
819 | flags); | ||
820 | } | ||
821 | } | ||
822 | } | ||
823 | |||
824 | static void summary_unit_check_handling_work(struct work_struct *work) | ||
825 | { | ||
826 | struct alias_lcu *lcu; | ||
827 | struct summary_unit_check_work_data *suc_data; | ||
828 | unsigned long flags; | ||
829 | struct dasd_device *device; | ||
830 | |||
831 | suc_data = container_of(work, struct summary_unit_check_work_data, | ||
832 | worker); | ||
833 | lcu = container_of(suc_data, struct alias_lcu, suc_data); | ||
834 | device = suc_data->device; | ||
835 | |||
836 | /* 1. flush alias devices */ | ||
837 | flush_all_alias_devices_on_lcu(lcu); | ||
838 | |||
839 | /* 2. reset summary unit check */ | ||
840 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | ||
841 | device->stopped &= ~(DASD_STOPPED_SU | DASD_STOPPED_PENDING); | ||
842 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); | ||
843 | reset_summary_unit_check(lcu, device, suc_data->reason); | ||
844 | |||
845 | spin_lock_irqsave(&lcu->lock, flags); | ||
846 | _unstop_all_devices_on_lcu(lcu); | ||
847 | _restart_all_base_devices_on_lcu(lcu); | ||
848 | /* 3. read new alias configuration */ | ||
849 | _schedule_lcu_update(lcu, device); | ||
850 | lcu->suc_data.device = NULL; | ||
851 | spin_unlock_irqrestore(&lcu->lock, flags); | ||
852 | } | ||
853 | |||
854 | /* | ||
855 | * note: this will be called from int handler context (cdev locked) | ||
856 | */ | ||
857 | void dasd_alias_handle_summary_unit_check(struct dasd_device *device, | ||
858 | struct irb *irb) | ||
859 | { | ||
860 | struct alias_lcu *lcu; | ||
861 | char reason; | ||
862 | struct dasd_eckd_private *private; | ||
863 | |||
864 | private = (struct dasd_eckd_private *) device->private; | ||
865 | |||
866 | reason = irb->ecw[8]; | ||
867 | DEV_MESSAGE(KERN_WARNING, device, "%s %x", | ||
868 | "eckd handle summary unit check: reason", reason); | ||
869 | |||
870 | lcu = private->lcu; | ||
871 | if (!lcu) { | ||
872 | DEV_MESSAGE(KERN_WARNING, device, "%s", | ||
873 | "device not ready to handle summary" | ||
874 | " unit check (no lcu structure)"); | ||
875 | return; | ||
876 | } | ||
877 | spin_lock(&lcu->lock); | ||
878 | _stop_all_devices_on_lcu(lcu, device); | ||
879 | /* prepare for lcu_update */ | ||
880 | private->lcu->flags |= NEED_UAC_UPDATE | UPDATE_PENDING; | ||
881 | /* If this device is about to be removed just return and wait for | ||
882 | * the next interrupt on a different device | ||
883 | */ | ||
884 | if (list_empty(&device->alias_list)) { | ||
885 | DEV_MESSAGE(KERN_WARNING, device, "%s", | ||
886 | "device is in offline processing," | ||
887 | " don't do summary unit check handling"); | ||
888 | spin_unlock(&lcu->lock); | ||
889 | return; | ||
890 | } | ||
891 | if (lcu->suc_data.device) { | ||
892 | /* already scheduled or running */ | ||
893 | DEV_MESSAGE(KERN_WARNING, device, "%s", | ||
894 | "previous instance of summary unit check worker" | ||
895 | " still pending"); | ||
896 | spin_unlock(&lcu->lock); | ||
897 | return ; | ||
898 | } | ||
899 | lcu->suc_data.reason = reason; | ||
900 | lcu->suc_data.device = device; | ||
901 | spin_unlock(&lcu->lock); | ||
902 | schedule_work(&lcu->suc_data.worker); | ||
903 | }; | ||
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index 0c67258fb9ec..f4fb40257348 100644 --- a/drivers/s390/block/dasd_devmap.c +++ b/drivers/s390/block/dasd_devmap.c | |||
@@ -49,22 +49,6 @@ struct dasd_devmap { | |||
49 | }; | 49 | }; |
50 | 50 | ||
51 | /* | 51 | /* |
52 | * dasd_server_ssid_map contains a globally unique storage server subsystem ID. | ||
53 | * dasd_server_ssid_list contains the list of all subsystem IDs accessed by | ||
54 | * the DASD device driver. | ||
55 | */ | ||
56 | struct dasd_server_ssid_map { | ||
57 | struct list_head list; | ||
58 | struct system_id { | ||
59 | char vendor[4]; | ||
60 | char serial[15]; | ||
61 | __u16 ssid; | ||
62 | } sid; | ||
63 | }; | ||
64 | |||
65 | static struct list_head dasd_server_ssid_list; | ||
66 | |||
67 | /* | ||
68 | * Parameter parsing functions for dasd= parameter. The syntax is: | 52 | * Parameter parsing functions for dasd= parameter. The syntax is: |
69 | * <devno> : (0x)?[0-9a-fA-F]+ | 53 | * <devno> : (0x)?[0-9a-fA-F]+ |
70 | * <busid> : [0-0a-f]\.[0-9a-f]\.(0x)?[0-9a-fA-F]+ | 54 | * <busid> : [0-0a-f]\.[0-9a-f]\.(0x)?[0-9a-fA-F]+ |
@@ -721,8 +705,9 @@ dasd_ro_store(struct device *dev, struct device_attribute *attr, | |||
721 | devmap->features &= ~DASD_FEATURE_READONLY; | 705 | devmap->features &= ~DASD_FEATURE_READONLY; |
722 | if (devmap->device) | 706 | if (devmap->device) |
723 | devmap->device->features = devmap->features; | 707 | devmap->device->features = devmap->features; |
724 | if (devmap->device && devmap->device->gdp) | 708 | if (devmap->device && devmap->device->block |
725 | set_disk_ro(devmap->device->gdp, val); | 709 | && devmap->device->block->gdp) |
710 | set_disk_ro(devmap->device->block->gdp, val); | ||
726 | spin_unlock(&dasd_devmap_lock); | 711 | spin_unlock(&dasd_devmap_lock); |
727 | return count; | 712 | return count; |
728 | } | 713 | } |
@@ -893,12 +878,16 @@ dasd_alias_show(struct device *dev, struct device_attribute *attr, char *buf) | |||
893 | 878 | ||
894 | devmap = dasd_find_busid(dev->bus_id); | 879 | devmap = dasd_find_busid(dev->bus_id); |
895 | spin_lock(&dasd_devmap_lock); | 880 | spin_lock(&dasd_devmap_lock); |
896 | if (!IS_ERR(devmap)) | 881 | if (IS_ERR(devmap) || strlen(devmap->uid.vendor) == 0) { |
897 | alias = devmap->uid.alias; | 882 | spin_unlock(&dasd_devmap_lock); |
883 | return sprintf(buf, "0\n"); | ||
884 | } | ||
885 | if (devmap->uid.type == UA_BASE_PAV_ALIAS || | ||
886 | devmap->uid.type == UA_HYPER_PAV_ALIAS) | ||
887 | alias = 1; | ||
898 | else | 888 | else |
899 | alias = 0; | 889 | alias = 0; |
900 | spin_unlock(&dasd_devmap_lock); | 890 | spin_unlock(&dasd_devmap_lock); |
901 | |||
902 | return sprintf(buf, alias ? "1\n" : "0\n"); | 891 | return sprintf(buf, alias ? "1\n" : "0\n"); |
903 | } | 892 | } |
904 | 893 | ||
@@ -930,19 +919,36 @@ static ssize_t | |||
930 | dasd_uid_show(struct device *dev, struct device_attribute *attr, char *buf) | 919 | dasd_uid_show(struct device *dev, struct device_attribute *attr, char *buf) |
931 | { | 920 | { |
932 | struct dasd_devmap *devmap; | 921 | struct dasd_devmap *devmap; |
933 | char uid[UID_STRLEN]; | 922 | char uid_string[UID_STRLEN]; |
923 | char ua_string[3]; | ||
924 | struct dasd_uid *uid; | ||
934 | 925 | ||
935 | devmap = dasd_find_busid(dev->bus_id); | 926 | devmap = dasd_find_busid(dev->bus_id); |
936 | spin_lock(&dasd_devmap_lock); | 927 | spin_lock(&dasd_devmap_lock); |
937 | if (!IS_ERR(devmap) && strlen(devmap->uid.vendor) > 0) | 928 | if (IS_ERR(devmap) || strlen(devmap->uid.vendor) == 0) { |
938 | snprintf(uid, sizeof(uid), "%s.%s.%04x.%02x", | 929 | spin_unlock(&dasd_devmap_lock); |
939 | devmap->uid.vendor, devmap->uid.serial, | 930 | return sprintf(buf, "\n"); |
940 | devmap->uid.ssid, devmap->uid.unit_addr); | 931 | } |
941 | else | 932 | uid = &devmap->uid; |
942 | uid[0] = 0; | 933 | switch (uid->type) { |
934 | case UA_BASE_DEVICE: | ||
935 | sprintf(ua_string, "%02x", uid->real_unit_addr); | ||
936 | break; | ||
937 | case UA_BASE_PAV_ALIAS: | ||
938 | sprintf(ua_string, "%02x", uid->base_unit_addr); | ||
939 | break; | ||
940 | case UA_HYPER_PAV_ALIAS: | ||
941 | sprintf(ua_string, "xx"); | ||
942 | break; | ||
943 | default: | ||
944 | /* should not happen, treat like base device */ | ||
945 | sprintf(ua_string, "%02x", uid->real_unit_addr); | ||
946 | break; | ||
947 | } | ||
948 | snprintf(uid_string, sizeof(uid_string), "%s.%s.%04x.%s", | ||
949 | uid->vendor, uid->serial, uid->ssid, ua_string); | ||
943 | spin_unlock(&dasd_devmap_lock); | 950 | spin_unlock(&dasd_devmap_lock); |
944 | 951 | return snprintf(buf, PAGE_SIZE, "%s\n", uid_string); | |
945 | return snprintf(buf, PAGE_SIZE, "%s\n", uid); | ||
946 | } | 952 | } |
947 | 953 | ||
948 | static DEVICE_ATTR(uid, 0444, dasd_uid_show, NULL); | 954 | static DEVICE_ATTR(uid, 0444, dasd_uid_show, NULL); |
@@ -1040,39 +1046,16 @@ int | |||
1040 | dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid) | 1046 | dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid) |
1041 | { | 1047 | { |
1042 | struct dasd_devmap *devmap; | 1048 | struct dasd_devmap *devmap; |
1043 | struct dasd_server_ssid_map *srv, *tmp; | ||
1044 | 1049 | ||
1045 | devmap = dasd_find_busid(cdev->dev.bus_id); | 1050 | devmap = dasd_find_busid(cdev->dev.bus_id); |
1046 | if (IS_ERR(devmap)) | 1051 | if (IS_ERR(devmap)) |
1047 | return PTR_ERR(devmap); | 1052 | return PTR_ERR(devmap); |
1048 | 1053 | ||
1049 | /* generate entry for server_ssid_map */ | ||
1050 | srv = (struct dasd_server_ssid_map *) | ||
1051 | kzalloc(sizeof(struct dasd_server_ssid_map), GFP_KERNEL); | ||
1052 | if (!srv) | ||
1053 | return -ENOMEM; | ||
1054 | strncpy(srv->sid.vendor, uid->vendor, sizeof(srv->sid.vendor) - 1); | ||
1055 | strncpy(srv->sid.serial, uid->serial, sizeof(srv->sid.serial) - 1); | ||
1056 | srv->sid.ssid = uid->ssid; | ||
1057 | |||
1058 | /* server is already contained ? */ | ||
1059 | spin_lock(&dasd_devmap_lock); | 1054 | spin_lock(&dasd_devmap_lock); |
1060 | devmap->uid = *uid; | 1055 | devmap->uid = *uid; |
1061 | list_for_each_entry(tmp, &dasd_server_ssid_list, list) { | ||
1062 | if (!memcmp(&srv->sid, &tmp->sid, | ||
1063 | sizeof(struct system_id))) { | ||
1064 | kfree(srv); | ||
1065 | srv = NULL; | ||
1066 | break; | ||
1067 | } | ||
1068 | } | ||
1069 | |||
1070 | /* add servermap to serverlist */ | ||
1071 | if (srv) | ||
1072 | list_add(&srv->list, &dasd_server_ssid_list); | ||
1073 | spin_unlock(&dasd_devmap_lock); | 1056 | spin_unlock(&dasd_devmap_lock); |
1074 | 1057 | ||
1075 | return (srv ? 1 : 0); | 1058 | return 0; |
1076 | } | 1059 | } |
1077 | EXPORT_SYMBOL_GPL(dasd_set_uid); | 1060 | EXPORT_SYMBOL_GPL(dasd_set_uid); |
1078 | 1061 | ||
@@ -1138,9 +1121,6 @@ dasd_devmap_init(void) | |||
1138 | dasd_max_devindex = 0; | 1121 | dasd_max_devindex = 0; |
1139 | for (i = 0; i < 256; i++) | 1122 | for (i = 0; i < 256; i++) |
1140 | INIT_LIST_HEAD(&dasd_hashlists[i]); | 1123 | INIT_LIST_HEAD(&dasd_hashlists[i]); |
1141 | |||
1142 | /* Initialize servermap structure. */ | ||
1143 | INIT_LIST_HEAD(&dasd_server_ssid_list); | ||
1144 | return 0; | 1124 | return 0; |
1145 | } | 1125 | } |
1146 | 1126 | ||
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c index 571320ab9e1a..d91df38ee4f7 100644 --- a/drivers/s390/block/dasd_diag.c +++ b/drivers/s390/block/dasd_diag.c | |||
@@ -142,7 +142,7 @@ dasd_diag_erp(struct dasd_device *device) | |||
142 | int rc; | 142 | int rc; |
143 | 143 | ||
144 | mdsk_term_io(device); | 144 | mdsk_term_io(device); |
145 | rc = mdsk_init_io(device, device->bp_block, 0, NULL); | 145 | rc = mdsk_init_io(device, device->block->bp_block, 0, NULL); |
146 | if (rc) | 146 | if (rc) |
147 | DEV_MESSAGE(KERN_WARNING, device, "DIAG ERP unsuccessful, " | 147 | DEV_MESSAGE(KERN_WARNING, device, "DIAG ERP unsuccessful, " |
148 | "rc=%d", rc); | 148 | "rc=%d", rc); |
@@ -158,11 +158,11 @@ dasd_start_diag(struct dasd_ccw_req * cqr) | |||
158 | struct dasd_diag_req *dreq; | 158 | struct dasd_diag_req *dreq; |
159 | int rc; | 159 | int rc; |
160 | 160 | ||
161 | device = cqr->device; | 161 | device = cqr->startdev; |
162 | if (cqr->retries < 0) { | 162 | if (cqr->retries < 0) { |
163 | DEV_MESSAGE(KERN_WARNING, device, "DIAG start_IO: request %p " | 163 | DEV_MESSAGE(KERN_WARNING, device, "DIAG start_IO: request %p " |
164 | "- no retry left)", cqr); | 164 | "- no retry left)", cqr); |
165 | cqr->status = DASD_CQR_FAILED; | 165 | cqr->status = DASD_CQR_ERROR; |
166 | return -EIO; | 166 | return -EIO; |
167 | } | 167 | } |
168 | private = (struct dasd_diag_private *) device->private; | 168 | private = (struct dasd_diag_private *) device->private; |
@@ -184,7 +184,7 @@ dasd_start_diag(struct dasd_ccw_req * cqr) | |||
184 | switch (rc) { | 184 | switch (rc) { |
185 | case 0: /* Synchronous I/O finished successfully */ | 185 | case 0: /* Synchronous I/O finished successfully */ |
186 | cqr->stopclk = get_clock(); | 186 | cqr->stopclk = get_clock(); |
187 | cqr->status = DASD_CQR_DONE; | 187 | cqr->status = DASD_CQR_SUCCESS; |
188 | /* Indicate to calling function that only a dasd_schedule_bh() | 188 | /* Indicate to calling function that only a dasd_schedule_bh() |
189 | and no timer is needed */ | 189 | and no timer is needed */ |
190 | rc = -EACCES; | 190 | rc = -EACCES; |
@@ -209,12 +209,12 @@ dasd_diag_term_IO(struct dasd_ccw_req * cqr) | |||
209 | { | 209 | { |
210 | struct dasd_device *device; | 210 | struct dasd_device *device; |
211 | 211 | ||
212 | device = cqr->device; | 212 | device = cqr->startdev; |
213 | mdsk_term_io(device); | 213 | mdsk_term_io(device); |
214 | mdsk_init_io(device, device->bp_block, 0, NULL); | 214 | mdsk_init_io(device, device->block->bp_block, 0, NULL); |
215 | cqr->status = DASD_CQR_CLEAR; | 215 | cqr->status = DASD_CQR_CLEAR_PENDING; |
216 | cqr->stopclk = get_clock(); | 216 | cqr->stopclk = get_clock(); |
217 | dasd_schedule_bh(device); | 217 | dasd_schedule_device_bh(device); |
218 | return 0; | 218 | return 0; |
219 | } | 219 | } |
220 | 220 | ||
@@ -247,7 +247,7 @@ dasd_ext_handler(__u16 code) | |||
247 | return; | 247 | return; |
248 | } | 248 | } |
249 | cqr = (struct dasd_ccw_req *) ip; | 249 | cqr = (struct dasd_ccw_req *) ip; |
250 | device = (struct dasd_device *) cqr->device; | 250 | device = (struct dasd_device *) cqr->startdev; |
251 | if (strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) { | 251 | if (strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) { |
252 | DEV_MESSAGE(KERN_WARNING, device, | 252 | DEV_MESSAGE(KERN_WARNING, device, |
253 | " magic number of dasd_ccw_req 0x%08X doesn't" | 253 | " magic number of dasd_ccw_req 0x%08X doesn't" |
@@ -260,10 +260,10 @@ dasd_ext_handler(__u16 code) | |||
260 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | 260 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); |
261 | 261 | ||
262 | /* Check for a pending clear operation */ | 262 | /* Check for a pending clear operation */ |
263 | if (cqr->status == DASD_CQR_CLEAR) { | 263 | if (cqr->status == DASD_CQR_CLEAR_PENDING) { |
264 | cqr->status = DASD_CQR_QUEUED; | 264 | cqr->status = DASD_CQR_CLEARED; |
265 | dasd_clear_timer(device); | 265 | dasd_device_clear_timer(device); |
266 | dasd_schedule_bh(device); | 266 | dasd_schedule_device_bh(device); |
267 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); | 267 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); |
268 | return; | 268 | return; |
269 | } | 269 | } |
@@ -272,11 +272,11 @@ dasd_ext_handler(__u16 code) | |||
272 | 272 | ||
273 | expires = 0; | 273 | expires = 0; |
274 | if (status == 0) { | 274 | if (status == 0) { |
275 | cqr->status = DASD_CQR_DONE; | 275 | cqr->status = DASD_CQR_SUCCESS; |
276 | /* Start first request on queue if possible -> fast_io. */ | 276 | /* Start first request on queue if possible -> fast_io. */ |
277 | if (!list_empty(&device->ccw_queue)) { | 277 | if (!list_empty(&device->ccw_queue)) { |
278 | next = list_entry(device->ccw_queue.next, | 278 | next = list_entry(device->ccw_queue.next, |
279 | struct dasd_ccw_req, list); | 279 | struct dasd_ccw_req, devlist); |
280 | if (next->status == DASD_CQR_QUEUED) { | 280 | if (next->status == DASD_CQR_QUEUED) { |
281 | rc = dasd_start_diag(next); | 281 | rc = dasd_start_diag(next); |
282 | if (rc == 0) | 282 | if (rc == 0) |
@@ -296,10 +296,10 @@ dasd_ext_handler(__u16 code) | |||
296 | } | 296 | } |
297 | 297 | ||
298 | if (expires != 0) | 298 | if (expires != 0) |
299 | dasd_set_timer(device, expires); | 299 | dasd_device_set_timer(device, expires); |
300 | else | 300 | else |
301 | dasd_clear_timer(device); | 301 | dasd_device_clear_timer(device); |
302 | dasd_schedule_bh(device); | 302 | dasd_schedule_device_bh(device); |
303 | 303 | ||
304 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); | 304 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); |
305 | } | 305 | } |
@@ -309,6 +309,7 @@ dasd_ext_handler(__u16 code) | |||
309 | static int | 309 | static int |
310 | dasd_diag_check_device(struct dasd_device *device) | 310 | dasd_diag_check_device(struct dasd_device *device) |
311 | { | 311 | { |
312 | struct dasd_block *block; | ||
312 | struct dasd_diag_private *private; | 313 | struct dasd_diag_private *private; |
313 | struct dasd_diag_characteristics *rdc_data; | 314 | struct dasd_diag_characteristics *rdc_data; |
314 | struct dasd_diag_bio bio; | 315 | struct dasd_diag_bio bio; |
@@ -328,6 +329,16 @@ dasd_diag_check_device(struct dasd_device *device) | |||
328 | ccw_device_get_id(device->cdev, &private->dev_id); | 329 | ccw_device_get_id(device->cdev, &private->dev_id); |
329 | device->private = (void *) private; | 330 | device->private = (void *) private; |
330 | } | 331 | } |
332 | block = dasd_alloc_block(); | ||
333 | if (IS_ERR(block)) { | ||
334 | DEV_MESSAGE(KERN_WARNING, device, "%s", | ||
335 | "could not allocate dasd block structure"); | ||
336 | kfree(device->private); | ||
337 | return PTR_ERR(block); | ||
338 | } | ||
339 | device->block = block; | ||
340 | block->base = device; | ||
341 | |||
331 | /* Read Device Characteristics */ | 342 | /* Read Device Characteristics */ |
332 | rdc_data = (void *) &(private->rdc_data); | 343 | rdc_data = (void *) &(private->rdc_data); |
333 | rdc_data->dev_nr = private->dev_id.devno; | 344 | rdc_data->dev_nr = private->dev_id.devno; |
@@ -409,14 +420,14 @@ dasd_diag_check_device(struct dasd_device *device) | |||
409 | sizeof(DASD_DIAG_CMS1)) == 0) { | 420 | sizeof(DASD_DIAG_CMS1)) == 0) { |
410 | /* get formatted blocksize from label block */ | 421 | /* get formatted blocksize from label block */ |
411 | bsize = (unsigned int) label->block_size; | 422 | bsize = (unsigned int) label->block_size; |
412 | device->blocks = (unsigned long) label->block_count; | 423 | block->blocks = (unsigned long) label->block_count; |
413 | } else | 424 | } else |
414 | device->blocks = end_block; | 425 | block->blocks = end_block; |
415 | device->bp_block = bsize; | 426 | block->bp_block = bsize; |
416 | device->s2b_shift = 0; /* bits to shift 512 to get a block */ | 427 | block->s2b_shift = 0; /* bits to shift 512 to get a block */ |
417 | for (sb = 512; sb < bsize; sb = sb << 1) | 428 | for (sb = 512; sb < bsize; sb = sb << 1) |
418 | device->s2b_shift++; | 429 | block->s2b_shift++; |
419 | rc = mdsk_init_io(device, device->bp_block, 0, NULL); | 430 | rc = mdsk_init_io(device, block->bp_block, 0, NULL); |
420 | if (rc) { | 431 | if (rc) { |
421 | DEV_MESSAGE(KERN_WARNING, device, "DIAG initialization " | 432 | DEV_MESSAGE(KERN_WARNING, device, "DIAG initialization " |
422 | "failed (rc=%d)", rc); | 433 | "failed (rc=%d)", rc); |
@@ -424,9 +435,9 @@ dasd_diag_check_device(struct dasd_device *device) | |||
424 | } else { | 435 | } else { |
425 | DEV_MESSAGE(KERN_INFO, device, | 436 | DEV_MESSAGE(KERN_INFO, device, |
426 | "(%ld B/blk): %ldkB", | 437 | "(%ld B/blk): %ldkB", |
427 | (unsigned long) device->bp_block, | 438 | (unsigned long) block->bp_block, |
428 | (unsigned long) (device->blocks << | 439 | (unsigned long) (block->blocks << |
429 | device->s2b_shift) >> 1); | 440 | block->s2b_shift) >> 1); |
430 | } | 441 | } |
431 | out: | 442 | out: |
432 | free_page((long) label); | 443 | free_page((long) label); |
@@ -436,22 +447,16 @@ out: | |||
436 | /* Fill in virtual disk geometry for device. Return zero on success, non-zero | 447 | /* Fill in virtual disk geometry for device. Return zero on success, non-zero |
437 | * otherwise. */ | 448 | * otherwise. */ |
438 | static int | 449 | static int |
439 | dasd_diag_fill_geometry(struct dasd_device *device, struct hd_geometry *geo) | 450 | dasd_diag_fill_geometry(struct dasd_block *block, struct hd_geometry *geo) |
440 | { | 451 | { |
441 | if (dasd_check_blocksize(device->bp_block) != 0) | 452 | if (dasd_check_blocksize(block->bp_block) != 0) |
442 | return -EINVAL; | 453 | return -EINVAL; |
443 | geo->cylinders = (device->blocks << device->s2b_shift) >> 10; | 454 | geo->cylinders = (block->blocks << block->s2b_shift) >> 10; |
444 | geo->heads = 16; | 455 | geo->heads = 16; |
445 | geo->sectors = 128 >> device->s2b_shift; | 456 | geo->sectors = 128 >> block->s2b_shift; |
446 | return 0; | 457 | return 0; |
447 | } | 458 | } |
448 | 459 | ||
449 | static dasd_era_t | ||
450 | dasd_diag_examine_error(struct dasd_ccw_req * cqr, struct irb * stat) | ||
451 | { | ||
452 | return dasd_era_fatal; | ||
453 | } | ||
454 | |||
455 | static dasd_erp_fn_t | 460 | static dasd_erp_fn_t |
456 | dasd_diag_erp_action(struct dasd_ccw_req * cqr) | 461 | dasd_diag_erp_action(struct dasd_ccw_req * cqr) |
457 | { | 462 | { |
@@ -466,8 +471,9 @@ dasd_diag_erp_postaction(struct dasd_ccw_req * cqr) | |||
466 | 471 | ||
467 | /* Create DASD request from block device request. Return pointer to new | 472 | /* Create DASD request from block device request. Return pointer to new |
468 | * request on success, ERR_PTR otherwise. */ | 473 | * request on success, ERR_PTR otherwise. */ |
469 | static struct dasd_ccw_req * | 474 | static struct dasd_ccw_req *dasd_diag_build_cp(struct dasd_device *memdev, |
470 | dasd_diag_build_cp(struct dasd_device * device, struct request *req) | 475 | struct dasd_block *block, |
476 | struct request *req) | ||
471 | { | 477 | { |
472 | struct dasd_ccw_req *cqr; | 478 | struct dasd_ccw_req *cqr; |
473 | struct dasd_diag_req *dreq; | 479 | struct dasd_diag_req *dreq; |
@@ -486,17 +492,17 @@ dasd_diag_build_cp(struct dasd_device * device, struct request *req) | |||
486 | rw_cmd = MDSK_WRITE_REQ; | 492 | rw_cmd = MDSK_WRITE_REQ; |
487 | else | 493 | else |
488 | return ERR_PTR(-EINVAL); | 494 | return ERR_PTR(-EINVAL); |
489 | blksize = device->bp_block; | 495 | blksize = block->bp_block; |
490 | /* Calculate record id of first and last block. */ | 496 | /* Calculate record id of first and last block. */ |
491 | first_rec = req->sector >> device->s2b_shift; | 497 | first_rec = req->sector >> block->s2b_shift; |
492 | last_rec = (req->sector + req->nr_sectors - 1) >> device->s2b_shift; | 498 | last_rec = (req->sector + req->nr_sectors - 1) >> block->s2b_shift; |
493 | /* Check struct bio and count the number of blocks for the request. */ | 499 | /* Check struct bio and count the number of blocks for the request. */ |
494 | count = 0; | 500 | count = 0; |
495 | rq_for_each_segment(bv, req, iter) { | 501 | rq_for_each_segment(bv, req, iter) { |
496 | if (bv->bv_len & (blksize - 1)) | 502 | if (bv->bv_len & (blksize - 1)) |
497 | /* Fba can only do full blocks. */ | 503 | /* Fba can only do full blocks. */ |
498 | return ERR_PTR(-EINVAL); | 504 | return ERR_PTR(-EINVAL); |
499 | count += bv->bv_len >> (device->s2b_shift + 9); | 505 | count += bv->bv_len >> (block->s2b_shift + 9); |
500 | } | 506 | } |
501 | /* Paranoia. */ | 507 | /* Paranoia. */ |
502 | if (count != last_rec - first_rec + 1) | 508 | if (count != last_rec - first_rec + 1) |
@@ -505,7 +511,7 @@ dasd_diag_build_cp(struct dasd_device * device, struct request *req) | |||
505 | datasize = sizeof(struct dasd_diag_req) + | 511 | datasize = sizeof(struct dasd_diag_req) + |
506 | count*sizeof(struct dasd_diag_bio); | 512 | count*sizeof(struct dasd_diag_bio); |
507 | cqr = dasd_smalloc_request(dasd_diag_discipline.name, 0, | 513 | cqr = dasd_smalloc_request(dasd_diag_discipline.name, 0, |
508 | datasize, device); | 514 | datasize, memdev); |
509 | if (IS_ERR(cqr)) | 515 | if (IS_ERR(cqr)) |
510 | return cqr; | 516 | return cqr; |
511 | 517 | ||
@@ -529,7 +535,9 @@ dasd_diag_build_cp(struct dasd_device * device, struct request *req) | |||
529 | cqr->buildclk = get_clock(); | 535 | cqr->buildclk = get_clock(); |
530 | if (req->cmd_flags & REQ_FAILFAST) | 536 | if (req->cmd_flags & REQ_FAILFAST) |
531 | set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); | 537 | set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); |
532 | cqr->device = device; | 538 | cqr->startdev = memdev; |
539 | cqr->memdev = memdev; | ||
540 | cqr->block = block; | ||
533 | cqr->expires = DIAG_TIMEOUT; | 541 | cqr->expires = DIAG_TIMEOUT; |
534 | cqr->status = DASD_CQR_FILLED; | 542 | cqr->status = DASD_CQR_FILLED; |
535 | return cqr; | 543 | return cqr; |
@@ -543,10 +551,15 @@ dasd_diag_free_cp(struct dasd_ccw_req *cqr, struct request *req) | |||
543 | int status; | 551 | int status; |
544 | 552 | ||
545 | status = cqr->status == DASD_CQR_DONE; | 553 | status = cqr->status == DASD_CQR_DONE; |
546 | dasd_sfree_request(cqr, cqr->device); | 554 | dasd_sfree_request(cqr, cqr->memdev); |
547 | return status; | 555 | return status; |
548 | } | 556 | } |
549 | 557 | ||
558 | static void dasd_diag_handle_terminated_request(struct dasd_ccw_req *cqr) | ||
559 | { | ||
560 | cqr->status = DASD_CQR_FILLED; | ||
561 | }; | ||
562 | |||
550 | /* Fill in IOCTL data for device. */ | 563 | /* Fill in IOCTL data for device. */ |
551 | static int | 564 | static int |
552 | dasd_diag_fill_info(struct dasd_device * device, | 565 | dasd_diag_fill_info(struct dasd_device * device, |
@@ -583,7 +596,7 @@ static struct dasd_discipline dasd_diag_discipline = { | |||
583 | .fill_geometry = dasd_diag_fill_geometry, | 596 | .fill_geometry = dasd_diag_fill_geometry, |
584 | .start_IO = dasd_start_diag, | 597 | .start_IO = dasd_start_diag, |
585 | .term_IO = dasd_diag_term_IO, | 598 | .term_IO = dasd_diag_term_IO, |
586 | .examine_error = dasd_diag_examine_error, | 599 | .handle_terminated_request = dasd_diag_handle_terminated_request, |
587 | .erp_action = dasd_diag_erp_action, | 600 | .erp_action = dasd_diag_erp_action, |
588 | .erp_postaction = dasd_diag_erp_postaction, | 601 | .erp_postaction = dasd_diag_erp_postaction, |
589 | .build_cp = dasd_diag_build_cp, | 602 | .build_cp = dasd_diag_build_cp, |
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 44adf8496bda..61f16937c1e0 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
@@ -52,16 +52,6 @@ MODULE_LICENSE("GPL"); | |||
52 | 52 | ||
53 | static struct dasd_discipline dasd_eckd_discipline; | 53 | static struct dasd_discipline dasd_eckd_discipline; |
54 | 54 | ||
55 | struct dasd_eckd_private { | ||
56 | struct dasd_eckd_characteristics rdc_data; | ||
57 | struct dasd_eckd_confdata conf_data; | ||
58 | struct dasd_eckd_path path_data; | ||
59 | struct eckd_count count_area[5]; | ||
60 | int init_cqr_status; | ||
61 | int uses_cdl; | ||
62 | struct attrib_data_t attrib; /* e.g. cache operations */ | ||
63 | }; | ||
64 | |||
65 | /* The ccw bus type uses this table to find devices that it sends to | 55 | /* The ccw bus type uses this table to find devices that it sends to |
66 | * dasd_eckd_probe */ | 56 | * dasd_eckd_probe */ |
67 | static struct ccw_device_id dasd_eckd_ids[] = { | 57 | static struct ccw_device_id dasd_eckd_ids[] = { |
@@ -188,7 +178,7 @@ check_XRC (struct ccw1 *de_ccw, | |||
188 | if (rc == -ENOSYS || rc == -EACCES) | 178 | if (rc == -ENOSYS || rc == -EACCES) |
189 | rc = 0; | 179 | rc = 0; |
190 | 180 | ||
191 | de_ccw->count = sizeof (struct DE_eckd_data); | 181 | de_ccw->count = sizeof(struct DE_eckd_data); |
192 | de_ccw->flags |= CCW_FLAG_SLI; | 182 | de_ccw->flags |= CCW_FLAG_SLI; |
193 | return rc; | 183 | return rc; |
194 | } | 184 | } |
@@ -208,7 +198,7 @@ define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk, | |||
208 | ccw->count = 16; | 198 | ccw->count = 16; |
209 | ccw->cda = (__u32) __pa(data); | 199 | ccw->cda = (__u32) __pa(data); |
210 | 200 | ||
211 | memset(data, 0, sizeof (struct DE_eckd_data)); | 201 | memset(data, 0, sizeof(struct DE_eckd_data)); |
212 | switch (cmd) { | 202 | switch (cmd) { |
213 | case DASD_ECKD_CCW_READ_HOME_ADDRESS: | 203 | case DASD_ECKD_CCW_READ_HOME_ADDRESS: |
214 | case DASD_ECKD_CCW_READ_RECORD_ZERO: | 204 | case DASD_ECKD_CCW_READ_RECORD_ZERO: |
@@ -280,6 +270,132 @@ define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk, | |||
280 | return rc; | 270 | return rc; |
281 | } | 271 | } |
282 | 272 | ||
273 | static int check_XRC_on_prefix(struct PFX_eckd_data *pfxdata, | ||
274 | struct dasd_device *device) | ||
275 | { | ||
276 | struct dasd_eckd_private *private; | ||
277 | int rc; | ||
278 | |||
279 | private = (struct dasd_eckd_private *) device->private; | ||
280 | if (!private->rdc_data.facilities.XRC_supported) | ||
281 | return 0; | ||
282 | |||
283 | /* switch on System Time Stamp - needed for XRC Support */ | ||
284 | pfxdata->define_extend.ga_extended |= 0x08; /* 'Time Stamp Valid' */ | ||
285 | pfxdata->define_extend.ga_extended |= 0x02; /* 'Extended Parameter' */ | ||
286 | pfxdata->validity.time_stamp = 1; /* 'Time Stamp Valid' */ | ||
287 | |||
288 | rc = get_sync_clock(&pfxdata->define_extend.ep_sys_time); | ||
289 | /* Ignore return code if sync clock is switched off. */ | ||
290 | if (rc == -ENOSYS || rc == -EACCES) | ||
291 | rc = 0; | ||
292 | return rc; | ||
293 | } | ||
294 | |||
295 | static int prefix(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata, int trk, | ||
296 | int totrk, int cmd, struct dasd_device *basedev, | ||
297 | struct dasd_device *startdev) | ||
298 | { | ||
299 | struct dasd_eckd_private *basepriv, *startpriv; | ||
300 | struct DE_eckd_data *data; | ||
301 | struct ch_t geo, beg, end; | ||
302 | int rc = 0; | ||
303 | |||
304 | basepriv = (struct dasd_eckd_private *) basedev->private; | ||
305 | startpriv = (struct dasd_eckd_private *) startdev->private; | ||
306 | data = &pfxdata->define_extend; | ||
307 | |||
308 | ccw->cmd_code = DASD_ECKD_CCW_PFX; | ||
309 | ccw->flags = 0; | ||
310 | ccw->count = sizeof(*pfxdata); | ||
311 | ccw->cda = (__u32) __pa(pfxdata); | ||
312 | |||
313 | memset(pfxdata, 0, sizeof(*pfxdata)); | ||
314 | /* prefix data */ | ||
315 | pfxdata->format = 0; | ||
316 | pfxdata->base_address = basepriv->conf_data.ned1.unit_addr; | ||
317 | pfxdata->base_lss = basepriv->conf_data.ned1.ID; | ||
318 | pfxdata->validity.define_extend = 1; | ||
319 | |||
320 | /* private uid is kept up to date, conf_data may be outdated */ | ||
321 | if (startpriv->uid.type != UA_BASE_DEVICE) { | ||
322 | pfxdata->validity.verify_base = 1; | ||
323 | if (startpriv->uid.type == UA_HYPER_PAV_ALIAS) | ||
324 | pfxdata->validity.hyper_pav = 1; | ||
325 | } | ||
326 | |||
327 | /* define extend data (mostly)*/ | ||
328 | switch (cmd) { | ||
329 | case DASD_ECKD_CCW_READ_HOME_ADDRESS: | ||
330 | case DASD_ECKD_CCW_READ_RECORD_ZERO: | ||
331 | case DASD_ECKD_CCW_READ: | ||
332 | case DASD_ECKD_CCW_READ_MT: | ||
333 | case DASD_ECKD_CCW_READ_CKD: | ||
334 | case DASD_ECKD_CCW_READ_CKD_MT: | ||
335 | case DASD_ECKD_CCW_READ_KD: | ||
336 | case DASD_ECKD_CCW_READ_KD_MT: | ||
337 | case DASD_ECKD_CCW_READ_COUNT: | ||
338 | data->mask.perm = 0x1; | ||
339 | data->attributes.operation = basepriv->attrib.operation; | ||
340 | break; | ||
341 | case DASD_ECKD_CCW_WRITE: | ||
342 | case DASD_ECKD_CCW_WRITE_MT: | ||
343 | case DASD_ECKD_CCW_WRITE_KD: | ||
344 | case DASD_ECKD_CCW_WRITE_KD_MT: | ||
345 | data->mask.perm = 0x02; | ||
346 | data->attributes.operation = basepriv->attrib.operation; | ||
347 | rc = check_XRC_on_prefix(pfxdata, basedev); | ||
348 | break; | ||
349 | case DASD_ECKD_CCW_WRITE_CKD: | ||
350 | case DASD_ECKD_CCW_WRITE_CKD_MT: | ||
351 | data->attributes.operation = DASD_BYPASS_CACHE; | ||
352 | rc = check_XRC_on_prefix(pfxdata, basedev); | ||
353 | break; | ||
354 | case DASD_ECKD_CCW_ERASE: | ||
355 | case DASD_ECKD_CCW_WRITE_HOME_ADDRESS: | ||
356 | case DASD_ECKD_CCW_WRITE_RECORD_ZERO: | ||
357 | data->mask.perm = 0x3; | ||
358 | data->mask.auth = 0x1; | ||
359 | data->attributes.operation = DASD_BYPASS_CACHE; | ||
360 | rc = check_XRC_on_prefix(pfxdata, basedev); | ||
361 | break; | ||
362 | default: | ||
363 | DEV_MESSAGE(KERN_ERR, basedev, "unknown opcode 0x%x", cmd); | ||
364 | break; | ||
365 | } | ||
366 | |||
367 | data->attributes.mode = 0x3; /* ECKD */ | ||
368 | |||
369 | if ((basepriv->rdc_data.cu_type == 0x2105 || | ||
370 | basepriv->rdc_data.cu_type == 0x2107 || | ||
371 | basepriv->rdc_data.cu_type == 0x1750) | ||
372 | && !(basepriv->uses_cdl && trk < 2)) | ||
373 | data->ga_extended |= 0x40; /* Regular Data Format Mode */ | ||
374 | |||
375 | geo.cyl = basepriv->rdc_data.no_cyl; | ||
376 | geo.head = basepriv->rdc_data.trk_per_cyl; | ||
377 | beg.cyl = trk / geo.head; | ||
378 | beg.head = trk % geo.head; | ||
379 | end.cyl = totrk / geo.head; | ||
380 | end.head = totrk % geo.head; | ||
381 | |||
382 | /* check for sequential prestage - enhance cylinder range */ | ||
383 | if (data->attributes.operation == DASD_SEQ_PRESTAGE || | ||
384 | data->attributes.operation == DASD_SEQ_ACCESS) { | ||
385 | |||
386 | if (end.cyl + basepriv->attrib.nr_cyl < geo.cyl) | ||
387 | end.cyl += basepriv->attrib.nr_cyl; | ||
388 | else | ||
389 | end.cyl = (geo.cyl - 1); | ||
390 | } | ||
391 | |||
392 | data->beg_ext.cyl = beg.cyl; | ||
393 | data->beg_ext.head = beg.head; | ||
394 | data->end_ext.cyl = end.cyl; | ||
395 | data->end_ext.head = end.head; | ||
396 | return rc; | ||
397 | } | ||
398 | |||
283 | static void | 399 | static void |
284 | locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, int trk, | 400 | locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, int trk, |
285 | int rec_on_trk, int no_rec, int cmd, | 401 | int rec_on_trk, int no_rec, int cmd, |
@@ -300,7 +416,7 @@ locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, int trk, | |||
300 | ccw->count = 16; | 416 | ccw->count = 16; |
301 | ccw->cda = (__u32) __pa(data); | 417 | ccw->cda = (__u32) __pa(data); |
302 | 418 | ||
303 | memset(data, 0, sizeof (struct LO_eckd_data)); | 419 | memset(data, 0, sizeof(struct LO_eckd_data)); |
304 | sector = 0; | 420 | sector = 0; |
305 | if (rec_on_trk) { | 421 | if (rec_on_trk) { |
306 | switch (private->rdc_data.dev_type) { | 422 | switch (private->rdc_data.dev_type) { |
@@ -441,12 +557,15 @@ dasd_eckd_generate_uid(struct dasd_device *device, struct dasd_uid *uid) | |||
441 | sizeof(uid->serial) - 1); | 557 | sizeof(uid->serial) - 1); |
442 | EBCASC(uid->serial, sizeof(uid->serial) - 1); | 558 | EBCASC(uid->serial, sizeof(uid->serial) - 1); |
443 | uid->ssid = confdata->neq.subsystemID; | 559 | uid->ssid = confdata->neq.subsystemID; |
444 | if (confdata->ned2.sneq.flags == 0x40) { | 560 | uid->real_unit_addr = confdata->ned1.unit_addr; |
445 | uid->alias = 1; | 561 | if (confdata->ned2.sneq.flags == 0x40 && |
446 | uid->unit_addr = confdata->ned2.sneq.base_unit_addr; | 562 | confdata->ned2.sneq.format == 0x0001) { |
447 | } else | 563 | uid->type = confdata->ned2.sneq.sua_flags; |
448 | uid->unit_addr = confdata->ned1.unit_addr; | 564 | if (uid->type == UA_BASE_PAV_ALIAS) |
449 | 565 | uid->base_unit_addr = confdata->ned2.sneq.base_unit_addr; | |
566 | } else { | ||
567 | uid->type = UA_BASE_DEVICE; | ||
568 | } | ||
450 | return 0; | 569 | return 0; |
451 | } | 570 | } |
452 | 571 | ||
@@ -470,7 +589,9 @@ static struct dasd_ccw_req *dasd_eckd_build_rcd_lpm(struct dasd_device *device, | |||
470 | ccw->cda = (__u32)(addr_t)rcd_buffer; | 589 | ccw->cda = (__u32)(addr_t)rcd_buffer; |
471 | ccw->count = ciw->count; | 590 | ccw->count = ciw->count; |
472 | 591 | ||
473 | cqr->device = device; | 592 | cqr->startdev = device; |
593 | cqr->memdev = device; | ||
594 | cqr->block = NULL; | ||
474 | cqr->expires = 10*HZ; | 595 | cqr->expires = 10*HZ; |
475 | cqr->lpm = lpm; | 596 | cqr->lpm = lpm; |
476 | clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); | 597 | clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); |
@@ -511,7 +632,7 @@ static int dasd_eckd_read_conf_lpm(struct dasd_device *device, | |||
511 | /* | 632 | /* |
512 | * on success we update the user input parms | 633 | * on success we update the user input parms |
513 | */ | 634 | */ |
514 | dasd_sfree_request(cqr, cqr->device); | 635 | dasd_sfree_request(cqr, cqr->memdev); |
515 | if (ret) | 636 | if (ret) |
516 | goto out_error; | 637 | goto out_error; |
517 | 638 | ||
@@ -557,19 +678,19 @@ dasd_eckd_read_conf(struct dasd_device *device) | |||
557 | "data retrieved"); | 678 | "data retrieved"); |
558 | continue; /* no error */ | 679 | continue; /* no error */ |
559 | } | 680 | } |
560 | if (conf_len != sizeof (struct dasd_eckd_confdata)) { | 681 | if (conf_len != sizeof(struct dasd_eckd_confdata)) { |
561 | MESSAGE(KERN_WARNING, | 682 | MESSAGE(KERN_WARNING, |
562 | "sizes of configuration data mismatch" | 683 | "sizes of configuration data mismatch" |
563 | "%d (read) vs %ld (expected)", | 684 | "%d (read) vs %ld (expected)", |
564 | conf_len, | 685 | conf_len, |
565 | sizeof (struct dasd_eckd_confdata)); | 686 | sizeof(struct dasd_eckd_confdata)); |
566 | kfree(conf_data); | 687 | kfree(conf_data); |
567 | continue; /* no error */ | 688 | continue; /* no error */ |
568 | } | 689 | } |
569 | /* save first valid configuration data */ | 690 | /* save first valid configuration data */ |
570 | if (!conf_data_saved){ | 691 | if (!conf_data_saved){ |
571 | memcpy(&private->conf_data, conf_data, | 692 | memcpy(&private->conf_data, conf_data, |
572 | sizeof (struct dasd_eckd_confdata)); | 693 | sizeof(struct dasd_eckd_confdata)); |
573 | conf_data_saved++; | 694 | conf_data_saved++; |
574 | } | 695 | } |
575 | switch (((char *)conf_data)[242] & 0x07){ | 696 | switch (((char *)conf_data)[242] & 0x07){ |
@@ -586,39 +707,104 @@ dasd_eckd_read_conf(struct dasd_device *device) | |||
586 | return 0; | 707 | return 0; |
587 | } | 708 | } |
588 | 709 | ||
710 | static int dasd_eckd_read_features(struct dasd_device *device) | ||
711 | { | ||
712 | struct dasd_psf_prssd_data *prssdp; | ||
713 | struct dasd_rssd_features *features; | ||
714 | struct dasd_ccw_req *cqr; | ||
715 | struct ccw1 *ccw; | ||
716 | int rc; | ||
717 | struct dasd_eckd_private *private; | ||
718 | |||
719 | private = (struct dasd_eckd_private *) device->private; | ||
720 | cqr = dasd_smalloc_request(dasd_eckd_discipline.name, | ||
721 | 1 /* PSF */ + 1 /* RSSD */ , | ||
722 | (sizeof(struct dasd_psf_prssd_data) + | ||
723 | sizeof(struct dasd_rssd_features)), | ||
724 | device); | ||
725 | if (IS_ERR(cqr)) { | ||
726 | DEV_MESSAGE(KERN_WARNING, device, "%s", | ||
727 | "Could not allocate initialization request"); | ||
728 | return PTR_ERR(cqr); | ||
729 | } | ||
730 | cqr->startdev = device; | ||
731 | cqr->memdev = device; | ||
732 | cqr->block = NULL; | ||
733 | clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); | ||
734 | cqr->retries = 5; | ||
735 | cqr->expires = 10 * HZ; | ||
736 | |||
737 | /* Prepare for Read Subsystem Data */ | ||
738 | prssdp = (struct dasd_psf_prssd_data *) cqr->data; | ||
739 | memset(prssdp, 0, sizeof(struct dasd_psf_prssd_data)); | ||
740 | prssdp->order = PSF_ORDER_PRSSD; | ||
741 | prssdp->suborder = 0x41; /* Read Feature Codes */ | ||
742 | /* all other bytes of prssdp must be zero */ | ||
743 | |||
744 | ccw = cqr->cpaddr; | ||
745 | ccw->cmd_code = DASD_ECKD_CCW_PSF; | ||
746 | ccw->count = sizeof(struct dasd_psf_prssd_data); | ||
747 | ccw->flags |= CCW_FLAG_CC; | ||
748 | ccw->cda = (__u32)(addr_t) prssdp; | ||
749 | |||
750 | /* Read Subsystem Data - feature codes */ | ||
751 | features = (struct dasd_rssd_features *) (prssdp + 1); | ||
752 | memset(features, 0, sizeof(struct dasd_rssd_features)); | ||
753 | |||
754 | ccw++; | ||
755 | ccw->cmd_code = DASD_ECKD_CCW_RSSD; | ||
756 | ccw->count = sizeof(struct dasd_rssd_features); | ||
757 | ccw->cda = (__u32)(addr_t) features; | ||
758 | |||
759 | cqr->buildclk = get_clock(); | ||
760 | cqr->status = DASD_CQR_FILLED; | ||
761 | rc = dasd_sleep_on(cqr); | ||
762 | if (rc == 0) { | ||
763 | prssdp = (struct dasd_psf_prssd_data *) cqr->data; | ||
764 | features = (struct dasd_rssd_features *) (prssdp + 1); | ||
765 | memcpy(&private->features, features, | ||
766 | sizeof(struct dasd_rssd_features)); | ||
767 | } | ||
768 | dasd_sfree_request(cqr, cqr->memdev); | ||
769 | return rc; | ||
770 | } | ||
771 | |||
772 | |||
589 | /* | 773 | /* |
590 | * Build CP for Perform Subsystem Function - SSC. | 774 | * Build CP for Perform Subsystem Function - SSC. |
591 | */ | 775 | */ |
592 | static struct dasd_ccw_req * | 776 | static struct dasd_ccw_req *dasd_eckd_build_psf_ssc(struct dasd_device *device) |
593 | dasd_eckd_build_psf_ssc(struct dasd_device *device) | ||
594 | { | 777 | { |
595 | struct dasd_ccw_req *cqr; | 778 | struct dasd_ccw_req *cqr; |
596 | struct dasd_psf_ssc_data *psf_ssc_data; | 779 | struct dasd_psf_ssc_data *psf_ssc_data; |
597 | struct ccw1 *ccw; | 780 | struct ccw1 *ccw; |
598 | 781 | ||
599 | cqr = dasd_smalloc_request("ECKD", 1 /* PSF */ , | 782 | cqr = dasd_smalloc_request("ECKD", 1 /* PSF */ , |
600 | sizeof(struct dasd_psf_ssc_data), | 783 | sizeof(struct dasd_psf_ssc_data), |
601 | device); | 784 | device); |
602 | 785 | ||
603 | if (IS_ERR(cqr)) { | 786 | if (IS_ERR(cqr)) { |
604 | DEV_MESSAGE(KERN_WARNING, device, "%s", | 787 | DEV_MESSAGE(KERN_WARNING, device, "%s", |
605 | "Could not allocate PSF-SSC request"); | 788 | "Could not allocate PSF-SSC request"); |
606 | return cqr; | 789 | return cqr; |
607 | } | 790 | } |
608 | psf_ssc_data = (struct dasd_psf_ssc_data *)cqr->data; | 791 | psf_ssc_data = (struct dasd_psf_ssc_data *)cqr->data; |
609 | psf_ssc_data->order = PSF_ORDER_SSC; | 792 | psf_ssc_data->order = PSF_ORDER_SSC; |
610 | psf_ssc_data->suborder = 0x08; | 793 | psf_ssc_data->suborder = 0x88; |
611 | 794 | psf_ssc_data->reserved[0] = 0x88; | |
612 | ccw = cqr->cpaddr; | 795 | |
613 | ccw->cmd_code = DASD_ECKD_CCW_PSF; | 796 | ccw = cqr->cpaddr; |
614 | ccw->cda = (__u32)(addr_t)psf_ssc_data; | 797 | ccw->cmd_code = DASD_ECKD_CCW_PSF; |
615 | ccw->count = 66; | 798 | ccw->cda = (__u32)(addr_t)psf_ssc_data; |
616 | 799 | ccw->count = 66; | |
617 | cqr->device = device; | 800 | |
618 | cqr->expires = 10*HZ; | 801 | cqr->startdev = device; |
619 | cqr->buildclk = get_clock(); | 802 | cqr->memdev = device; |
620 | cqr->status = DASD_CQR_FILLED; | 803 | cqr->block = NULL; |
621 | return cqr; | 804 | cqr->expires = 10*HZ; |
805 | cqr->buildclk = get_clock(); | ||
806 | cqr->status = DASD_CQR_FILLED; | ||
807 | return cqr; | ||
622 | } | 808 | } |
623 | 809 | ||
624 | /* | 810 | /* |
@@ -629,28 +815,28 @@ dasd_eckd_build_psf_ssc(struct dasd_device *device) | |||
629 | static int | 815 | static int |
630 | dasd_eckd_psf_ssc(struct dasd_device *device) | 816 | dasd_eckd_psf_ssc(struct dasd_device *device) |
631 | { | 817 | { |
632 | struct dasd_ccw_req *cqr; | 818 | struct dasd_ccw_req *cqr; |
633 | int rc; | 819 | int rc; |
634 | 820 | ||
635 | cqr = dasd_eckd_build_psf_ssc(device); | 821 | cqr = dasd_eckd_build_psf_ssc(device); |
636 | if (IS_ERR(cqr)) | 822 | if (IS_ERR(cqr)) |
637 | return PTR_ERR(cqr); | 823 | return PTR_ERR(cqr); |
638 | 824 | ||
639 | rc = dasd_sleep_on(cqr); | 825 | rc = dasd_sleep_on(cqr); |
640 | if (!rc) | 826 | if (!rc) |
641 | /* trigger CIO to reprobe devices */ | 827 | /* trigger CIO to reprobe devices */ |
642 | css_schedule_reprobe(); | 828 | css_schedule_reprobe(); |
643 | dasd_sfree_request(cqr, cqr->device); | 829 | dasd_sfree_request(cqr, cqr->memdev); |
644 | return rc; | 830 | return rc; |
645 | } | 831 | } |
646 | 832 | ||
647 | /* | 833 | /* |
648 | * Valide storage server of current device. | 834 | * Valide storage server of current device. |
649 | */ | 835 | */ |
650 | static int | 836 | static int dasd_eckd_validate_server(struct dasd_device *device) |
651 | dasd_eckd_validate_server(struct dasd_device *device, struct dasd_uid *uid) | ||
652 | { | 837 | { |
653 | int rc; | 838 | int rc; |
839 | struct dasd_eckd_private *private; | ||
654 | 840 | ||
655 | /* Currently PAV is the only reason to 'validate' server on LPAR */ | 841 | /* Currently PAV is the only reason to 'validate' server on LPAR */ |
656 | if (dasd_nopav || MACHINE_IS_VM) | 842 | if (dasd_nopav || MACHINE_IS_VM) |
@@ -659,9 +845,11 @@ dasd_eckd_validate_server(struct dasd_device *device, struct dasd_uid *uid) | |||
659 | rc = dasd_eckd_psf_ssc(device); | 845 | rc = dasd_eckd_psf_ssc(device); |
660 | /* may be requested feature is not available on server, | 846 | /* may be requested feature is not available on server, |
661 | * therefore just report error and go ahead */ | 847 | * therefore just report error and go ahead */ |
848 | private = (struct dasd_eckd_private *) device->private; | ||
662 | DEV_MESSAGE(KERN_INFO, device, | 849 | DEV_MESSAGE(KERN_INFO, device, |
663 | "PSF-SSC on storage subsystem %s.%s.%04x returned rc=%d", | 850 | "PSF-SSC on storage subsystem %s.%s.%04x returned rc=%d", |
664 | uid->vendor, uid->serial, uid->ssid, rc); | 851 | private->uid.vendor, private->uid.serial, |
852 | private->uid.ssid, rc); | ||
665 | /* RE-Read Configuration Data */ | 853 | /* RE-Read Configuration Data */ |
666 | return dasd_eckd_read_conf(device); | 854 | return dasd_eckd_read_conf(device); |
667 | } | 855 | } |
@@ -674,9 +862,9 @@ static int | |||
674 | dasd_eckd_check_characteristics(struct dasd_device *device) | 862 | dasd_eckd_check_characteristics(struct dasd_device *device) |
675 | { | 863 | { |
676 | struct dasd_eckd_private *private; | 864 | struct dasd_eckd_private *private; |
677 | struct dasd_uid uid; | 865 | struct dasd_block *block; |
678 | void *rdc_data; | 866 | void *rdc_data; |
679 | int rc; | 867 | int is_known, rc; |
680 | 868 | ||
681 | private = (struct dasd_eckd_private *) device->private; | 869 | private = (struct dasd_eckd_private *) device->private; |
682 | if (private == NULL) { | 870 | if (private == NULL) { |
@@ -699,27 +887,54 @@ dasd_eckd_check_characteristics(struct dasd_device *device) | |||
699 | /* Read Configuration Data */ | 887 | /* Read Configuration Data */ |
700 | rc = dasd_eckd_read_conf(device); | 888 | rc = dasd_eckd_read_conf(device); |
701 | if (rc) | 889 | if (rc) |
702 | return rc; | 890 | goto out_err1; |
703 | 891 | ||
704 | /* Generate device unique id and register in devmap */ | 892 | /* Generate device unique id and register in devmap */ |
705 | rc = dasd_eckd_generate_uid(device, &uid); | 893 | rc = dasd_eckd_generate_uid(device, &private->uid); |
706 | if (rc) | 894 | if (rc) |
707 | return rc; | 895 | goto out_err1; |
708 | rc = dasd_set_uid(device->cdev, &uid); | 896 | dasd_set_uid(device->cdev, &private->uid); |
709 | if (rc == 1) /* new server found */ | 897 | |
710 | rc = dasd_eckd_validate_server(device, &uid); | 898 | if (private->uid.type == UA_BASE_DEVICE) { |
899 | block = dasd_alloc_block(); | ||
900 | if (IS_ERR(block)) { | ||
901 | DEV_MESSAGE(KERN_WARNING, device, "%s", | ||
902 | "could not allocate dasd block structure"); | ||
903 | rc = PTR_ERR(block); | ||
904 | goto out_err1; | ||
905 | } | ||
906 | device->block = block; | ||
907 | block->base = device; | ||
908 | } | ||
909 | |||
910 | /* register lcu with alias handling, enable PAV if this is a new lcu */ | ||
911 | is_known = dasd_alias_make_device_known_to_lcu(device); | ||
912 | if (is_known < 0) { | ||
913 | rc = is_known; | ||
914 | goto out_err2; | ||
915 | } | ||
916 | if (!is_known) { | ||
917 | /* new lcu found */ | ||
918 | rc = dasd_eckd_validate_server(device); /* will switch pav on */ | ||
919 | if (rc) | ||
920 | goto out_err3; | ||
921 | } | ||
922 | |||
923 | /* Read Feature Codes */ | ||
924 | rc = dasd_eckd_read_features(device); | ||
711 | if (rc) | 925 | if (rc) |
712 | return rc; | 926 | goto out_err3; |
713 | 927 | ||
714 | /* Read Device Characteristics */ | 928 | /* Read Device Characteristics */ |
715 | rdc_data = (void *) &(private->rdc_data); | 929 | rdc_data = (void *) &(private->rdc_data); |
716 | memset(rdc_data, 0, sizeof(rdc_data)); | 930 | memset(rdc_data, 0, sizeof(rdc_data)); |
717 | rc = dasd_generic_read_dev_chars(device, "ECKD", &rdc_data, 64); | 931 | rc = dasd_generic_read_dev_chars(device, "ECKD", &rdc_data, 64); |
718 | if (rc) | 932 | if (rc) { |
719 | DEV_MESSAGE(KERN_WARNING, device, | 933 | DEV_MESSAGE(KERN_WARNING, device, |
720 | "Read device characteristics returned " | 934 | "Read device characteristics returned " |
721 | "rc=%d", rc); | 935 | "rc=%d", rc); |
722 | 936 | goto out_err3; | |
937 | } | ||
723 | DEV_MESSAGE(KERN_INFO, device, | 938 | DEV_MESSAGE(KERN_INFO, device, |
724 | "%04X/%02X(CU:%04X/%02X) Cyl:%d Head:%d Sec:%d", | 939 | "%04X/%02X(CU:%04X/%02X) Cyl:%d Head:%d Sec:%d", |
725 | private->rdc_data.dev_type, | 940 | private->rdc_data.dev_type, |
@@ -729,9 +944,24 @@ dasd_eckd_check_characteristics(struct dasd_device *device) | |||
729 | private->rdc_data.no_cyl, | 944 | private->rdc_data.no_cyl, |
730 | private->rdc_data.trk_per_cyl, | 945 | private->rdc_data.trk_per_cyl, |
731 | private->rdc_data.sec_per_trk); | 946 | private->rdc_data.sec_per_trk); |
947 | return 0; | ||
948 | |||
949 | out_err3: | ||
950 | dasd_alias_disconnect_device_from_lcu(device); | ||
951 | out_err2: | ||
952 | dasd_free_block(device->block); | ||
953 | device->block = NULL; | ||
954 | out_err1: | ||
955 | kfree(device->private); | ||
956 | device->private = NULL; | ||
732 | return rc; | 957 | return rc; |
733 | } | 958 | } |
734 | 959 | ||
960 | static void dasd_eckd_uncheck_device(struct dasd_device *device) | ||
961 | { | ||
962 | dasd_alias_disconnect_device_from_lcu(device); | ||
963 | } | ||
964 | |||
735 | static struct dasd_ccw_req * | 965 | static struct dasd_ccw_req * |
736 | dasd_eckd_analysis_ccw(struct dasd_device *device) | 966 | dasd_eckd_analysis_ccw(struct dasd_device *device) |
737 | { | 967 | { |
@@ -755,7 +985,7 @@ dasd_eckd_analysis_ccw(struct dasd_device *device) | |||
755 | /* Define extent for the first 3 tracks. */ | 985 | /* Define extent for the first 3 tracks. */ |
756 | define_extent(ccw++, cqr->data, 0, 2, | 986 | define_extent(ccw++, cqr->data, 0, 2, |
757 | DASD_ECKD_CCW_READ_COUNT, device); | 987 | DASD_ECKD_CCW_READ_COUNT, device); |
758 | LO_data = cqr->data + sizeof (struct DE_eckd_data); | 988 | LO_data = cqr->data + sizeof(struct DE_eckd_data); |
759 | /* Locate record for the first 4 records on track 0. */ | 989 | /* Locate record for the first 4 records on track 0. */ |
760 | ccw[-1].flags |= CCW_FLAG_CC; | 990 | ccw[-1].flags |= CCW_FLAG_CC; |
761 | locate_record(ccw++, LO_data++, 0, 0, 4, | 991 | locate_record(ccw++, LO_data++, 0, 0, 4, |
@@ -783,7 +1013,9 @@ dasd_eckd_analysis_ccw(struct dasd_device *device) | |||
783 | ccw->count = 8; | 1013 | ccw->count = 8; |
784 | ccw->cda = (__u32)(addr_t) count_data; | 1014 | ccw->cda = (__u32)(addr_t) count_data; |
785 | 1015 | ||
786 | cqr->device = device; | 1016 | cqr->block = NULL; |
1017 | cqr->startdev = device; | ||
1018 | cqr->memdev = device; | ||
787 | cqr->retries = 0; | 1019 | cqr->retries = 0; |
788 | cqr->buildclk = get_clock(); | 1020 | cqr->buildclk = get_clock(); |
789 | cqr->status = DASD_CQR_FILLED; | 1021 | cqr->status = DASD_CQR_FILLED; |
@@ -803,7 +1035,7 @@ dasd_eckd_analysis_callback(struct dasd_ccw_req *init_cqr, void *data) | |||
803 | struct dasd_eckd_private *private; | 1035 | struct dasd_eckd_private *private; |
804 | struct dasd_device *device; | 1036 | struct dasd_device *device; |
805 | 1037 | ||
806 | device = init_cqr->device; | 1038 | device = init_cqr->startdev; |
807 | private = (struct dasd_eckd_private *) device->private; | 1039 | private = (struct dasd_eckd_private *) device->private; |
808 | private->init_cqr_status = init_cqr->status; | 1040 | private->init_cqr_status = init_cqr->status; |
809 | dasd_sfree_request(init_cqr, device); | 1041 | dasd_sfree_request(init_cqr, device); |
@@ -811,13 +1043,13 @@ dasd_eckd_analysis_callback(struct dasd_ccw_req *init_cqr, void *data) | |||
811 | } | 1043 | } |
812 | 1044 | ||
813 | static int | 1045 | static int |
814 | dasd_eckd_start_analysis(struct dasd_device *device) | 1046 | dasd_eckd_start_analysis(struct dasd_block *block) |
815 | { | 1047 | { |
816 | struct dasd_eckd_private *private; | 1048 | struct dasd_eckd_private *private; |
817 | struct dasd_ccw_req *init_cqr; | 1049 | struct dasd_ccw_req *init_cqr; |
818 | 1050 | ||
819 | private = (struct dasd_eckd_private *) device->private; | 1051 | private = (struct dasd_eckd_private *) block->base->private; |
820 | init_cqr = dasd_eckd_analysis_ccw(device); | 1052 | init_cqr = dasd_eckd_analysis_ccw(block->base); |
821 | if (IS_ERR(init_cqr)) | 1053 | if (IS_ERR(init_cqr)) |
822 | return PTR_ERR(init_cqr); | 1054 | return PTR_ERR(init_cqr); |
823 | init_cqr->callback = dasd_eckd_analysis_callback; | 1055 | init_cqr->callback = dasd_eckd_analysis_callback; |
@@ -828,13 +1060,15 @@ dasd_eckd_start_analysis(struct dasd_device *device) | |||
828 | } | 1060 | } |
829 | 1061 | ||
830 | static int | 1062 | static int |
831 | dasd_eckd_end_analysis(struct dasd_device *device) | 1063 | dasd_eckd_end_analysis(struct dasd_block *block) |
832 | { | 1064 | { |
1065 | struct dasd_device *device; | ||
833 | struct dasd_eckd_private *private; | 1066 | struct dasd_eckd_private *private; |
834 | struct eckd_count *count_area; | 1067 | struct eckd_count *count_area; |
835 | unsigned int sb, blk_per_trk; | 1068 | unsigned int sb, blk_per_trk; |
836 | int status, i; | 1069 | int status, i; |
837 | 1070 | ||
1071 | device = block->base; | ||
838 | private = (struct dasd_eckd_private *) device->private; | 1072 | private = (struct dasd_eckd_private *) device->private; |
839 | status = private->init_cqr_status; | 1073 | status = private->init_cqr_status; |
840 | private->init_cqr_status = -1; | 1074 | private->init_cqr_status = -1; |
@@ -846,7 +1080,7 @@ dasd_eckd_end_analysis(struct dasd_device *device) | |||
846 | 1080 | ||
847 | private->uses_cdl = 1; | 1081 | private->uses_cdl = 1; |
848 | /* Calculate number of blocks/records per track. */ | 1082 | /* Calculate number of blocks/records per track. */ |
849 | blk_per_trk = recs_per_track(&private->rdc_data, 0, device->bp_block); | 1083 | blk_per_trk = recs_per_track(&private->rdc_data, 0, block->bp_block); |
850 | /* Check Track 0 for Compatible Disk Layout */ | 1084 | /* Check Track 0 for Compatible Disk Layout */ |
851 | count_area = NULL; | 1085 | count_area = NULL; |
852 | for (i = 0; i < 3; i++) { | 1086 | for (i = 0; i < 3; i++) { |
@@ -876,56 +1110,65 @@ dasd_eckd_end_analysis(struct dasd_device *device) | |||
876 | if (count_area != NULL && count_area->kl == 0) { | 1110 | if (count_area != NULL && count_area->kl == 0) { |
877 | /* we found notthing violating our disk layout */ | 1111 | /* we found notthing violating our disk layout */ |
878 | if (dasd_check_blocksize(count_area->dl) == 0) | 1112 | if (dasd_check_blocksize(count_area->dl) == 0) |
879 | device->bp_block = count_area->dl; | 1113 | block->bp_block = count_area->dl; |
880 | } | 1114 | } |
881 | if (device->bp_block == 0) { | 1115 | if (block->bp_block == 0) { |
882 | DEV_MESSAGE(KERN_WARNING, device, "%s", | 1116 | DEV_MESSAGE(KERN_WARNING, device, "%s", |
883 | "Volume has incompatible disk layout"); | 1117 | "Volume has incompatible disk layout"); |
884 | return -EMEDIUMTYPE; | 1118 | return -EMEDIUMTYPE; |
885 | } | 1119 | } |
886 | device->s2b_shift = 0; /* bits to shift 512 to get a block */ | 1120 | block->s2b_shift = 0; /* bits to shift 512 to get a block */ |
887 | for (sb = 512; sb < device->bp_block; sb = sb << 1) | 1121 | for (sb = 512; sb < block->bp_block; sb = sb << 1) |
888 | device->s2b_shift++; | 1122 | block->s2b_shift++; |
889 | 1123 | ||
890 | blk_per_trk = recs_per_track(&private->rdc_data, 0, device->bp_block); | 1124 | blk_per_trk = recs_per_track(&private->rdc_data, 0, block->bp_block); |
891 | device->blocks = (private->rdc_data.no_cyl * | 1125 | block->blocks = (private->rdc_data.no_cyl * |
892 | private->rdc_data.trk_per_cyl * | 1126 | private->rdc_data.trk_per_cyl * |
893 | blk_per_trk); | 1127 | blk_per_trk); |
894 | 1128 | ||
895 | DEV_MESSAGE(KERN_INFO, device, | 1129 | DEV_MESSAGE(KERN_INFO, device, |
896 | "(%dkB blks): %dkB at %dkB/trk %s", | 1130 | "(%dkB blks): %dkB at %dkB/trk %s", |
897 | (device->bp_block >> 10), | 1131 | (block->bp_block >> 10), |
898 | ((private->rdc_data.no_cyl * | 1132 | ((private->rdc_data.no_cyl * |
899 | private->rdc_data.trk_per_cyl * | 1133 | private->rdc_data.trk_per_cyl * |
900 | blk_per_trk * (device->bp_block >> 9)) >> 1), | 1134 | blk_per_trk * (block->bp_block >> 9)) >> 1), |
901 | ((blk_per_trk * device->bp_block) >> 10), | 1135 | ((blk_per_trk * block->bp_block) >> 10), |
902 | private->uses_cdl ? | 1136 | private->uses_cdl ? |
903 | "compatible disk layout" : "linux disk layout"); | 1137 | "compatible disk layout" : "linux disk layout"); |
904 | 1138 | ||
905 | return 0; | 1139 | return 0; |
906 | } | 1140 | } |
907 | 1141 | ||
908 | static int | 1142 | static int dasd_eckd_do_analysis(struct dasd_block *block) |
909 | dasd_eckd_do_analysis(struct dasd_device *device) | ||
910 | { | 1143 | { |
911 | struct dasd_eckd_private *private; | 1144 | struct dasd_eckd_private *private; |
912 | 1145 | ||
913 | private = (struct dasd_eckd_private *) device->private; | 1146 | private = (struct dasd_eckd_private *) block->base->private; |
914 | if (private->init_cqr_status < 0) | 1147 | if (private->init_cqr_status < 0) |
915 | return dasd_eckd_start_analysis(device); | 1148 | return dasd_eckd_start_analysis(block); |
916 | else | 1149 | else |
917 | return dasd_eckd_end_analysis(device); | 1150 | return dasd_eckd_end_analysis(block); |
918 | } | 1151 | } |
919 | 1152 | ||
1153 | static int dasd_eckd_ready_to_online(struct dasd_device *device) | ||
1154 | { | ||
1155 | return dasd_alias_add_device(device); | ||
1156 | }; | ||
1157 | |||
1158 | static int dasd_eckd_online_to_ready(struct dasd_device *device) | ||
1159 | { | ||
1160 | return dasd_alias_remove_device(device); | ||
1161 | }; | ||
1162 | |||
920 | static int | 1163 | static int |
921 | dasd_eckd_fill_geometry(struct dasd_device *device, struct hd_geometry *geo) | 1164 | dasd_eckd_fill_geometry(struct dasd_block *block, struct hd_geometry *geo) |
922 | { | 1165 | { |
923 | struct dasd_eckd_private *private; | 1166 | struct dasd_eckd_private *private; |
924 | 1167 | ||
925 | private = (struct dasd_eckd_private *) device->private; | 1168 | private = (struct dasd_eckd_private *) block->base->private; |
926 | if (dasd_check_blocksize(device->bp_block) == 0) { | 1169 | if (dasd_check_blocksize(block->bp_block) == 0) { |
927 | geo->sectors = recs_per_track(&private->rdc_data, | 1170 | geo->sectors = recs_per_track(&private->rdc_data, |
928 | 0, device->bp_block); | 1171 | 0, block->bp_block); |
929 | } | 1172 | } |
930 | geo->cylinders = private->rdc_data.no_cyl; | 1173 | geo->cylinders = private->rdc_data.no_cyl; |
931 | geo->heads = private->rdc_data.trk_per_cyl; | 1174 | geo->heads = private->rdc_data.trk_per_cyl; |
@@ -1037,7 +1280,7 @@ dasd_eckd_format_device(struct dasd_device * device, | |||
1037 | locate_record(ccw++, (struct LO_eckd_data *) data, | 1280 | locate_record(ccw++, (struct LO_eckd_data *) data, |
1038 | fdata->start_unit, 0, rpt + 1, | 1281 | fdata->start_unit, 0, rpt + 1, |
1039 | DASD_ECKD_CCW_WRITE_RECORD_ZERO, device, | 1282 | DASD_ECKD_CCW_WRITE_RECORD_ZERO, device, |
1040 | device->bp_block); | 1283 | device->block->bp_block); |
1041 | data += sizeof(struct LO_eckd_data); | 1284 | data += sizeof(struct LO_eckd_data); |
1042 | break; | 1285 | break; |
1043 | case 0x04: /* Invalidate track. */ | 1286 | case 0x04: /* Invalidate track. */ |
@@ -1110,43 +1353,28 @@ dasd_eckd_format_device(struct dasd_device * device, | |||
1110 | ccw++; | 1353 | ccw++; |
1111 | } | 1354 | } |
1112 | } | 1355 | } |
1113 | fcp->device = device; | 1356 | fcp->startdev = device; |
1114 | fcp->retries = 2; /* set retry counter to enable ERP */ | 1357 | fcp->memdev = device; |
1358 | clear_bit(DASD_CQR_FLAGS_USE_ERP, &fcp->flags); | ||
1359 | fcp->retries = 5; /* set retry counter to enable default ERP */ | ||
1115 | fcp->buildclk = get_clock(); | 1360 | fcp->buildclk = get_clock(); |
1116 | fcp->status = DASD_CQR_FILLED; | 1361 | fcp->status = DASD_CQR_FILLED; |
1117 | return fcp; | 1362 | return fcp; |
1118 | } | 1363 | } |
1119 | 1364 | ||
1120 | static dasd_era_t | 1365 | static void dasd_eckd_handle_terminated_request(struct dasd_ccw_req *cqr) |
1121 | dasd_eckd_examine_error(struct dasd_ccw_req * cqr, struct irb * irb) | ||
1122 | { | 1366 | { |
1123 | struct dasd_device *device = (struct dasd_device *) cqr->device; | 1367 | cqr->status = DASD_CQR_FILLED; |
1124 | struct ccw_device *cdev = device->cdev; | 1368 | if (cqr->block && (cqr->startdev != cqr->block->base)) { |
1125 | 1369 | dasd_eckd_reset_ccw_to_base_io(cqr); | |
1126 | if (irb->scsw.cstat == 0x00 && | 1370 | cqr->startdev = cqr->block->base; |
1127 | irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END)) | ||
1128 | return dasd_era_none; | ||
1129 | |||
1130 | switch (cdev->id.cu_type) { | ||
1131 | case 0x3990: | ||
1132 | case 0x2105: | ||
1133 | case 0x2107: | ||
1134 | case 0x1750: | ||
1135 | return dasd_3990_erp_examine(cqr, irb); | ||
1136 | case 0x9343: | ||
1137 | return dasd_9343_erp_examine(cqr, irb); | ||
1138 | case 0x3880: | ||
1139 | default: | ||
1140 | DEV_MESSAGE(KERN_WARNING, device, "%s", | ||
1141 | "default (unknown CU type) - RECOVERABLE return"); | ||
1142 | return dasd_era_recover; | ||
1143 | } | 1371 | } |
1144 | } | 1372 | }; |
1145 | 1373 | ||
1146 | static dasd_erp_fn_t | 1374 | static dasd_erp_fn_t |
1147 | dasd_eckd_erp_action(struct dasd_ccw_req * cqr) | 1375 | dasd_eckd_erp_action(struct dasd_ccw_req * cqr) |
1148 | { | 1376 | { |
1149 | struct dasd_device *device = (struct dasd_device *) cqr->device; | 1377 | struct dasd_device *device = (struct dasd_device *) cqr->startdev; |
1150 | struct ccw_device *cdev = device->cdev; | 1378 | struct ccw_device *cdev = device->cdev; |
1151 | 1379 | ||
1152 | switch (cdev->id.cu_type) { | 1380 | switch (cdev->id.cu_type) { |
@@ -1168,8 +1396,37 @@ dasd_eckd_erp_postaction(struct dasd_ccw_req * cqr) | |||
1168 | return dasd_default_erp_postaction; | 1396 | return dasd_default_erp_postaction; |
1169 | } | 1397 | } |
1170 | 1398 | ||
1171 | static struct dasd_ccw_req * | 1399 | |
1172 | dasd_eckd_build_cp(struct dasd_device * device, struct request *req) | 1400 | static void dasd_eckd_handle_unsolicited_interrupt(struct dasd_device *device, |
1401 | struct irb *irb) | ||
1402 | { | ||
1403 | char mask; | ||
1404 | |||
1405 | /* first of all check for state change pending interrupt */ | ||
1406 | mask = DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP; | ||
1407 | if ((irb->scsw.dstat & mask) == mask) { | ||
1408 | dasd_generic_handle_state_change(device); | ||
1409 | return; | ||
1410 | } | ||
1411 | |||
1412 | /* summary unit check */ | ||
1413 | if ((irb->scsw.dstat & DEV_STAT_UNIT_CHECK) && irb->ecw[7] == 0x0D) { | ||
1414 | dasd_alias_handle_summary_unit_check(device, irb); | ||
1415 | return; | ||
1416 | } | ||
1417 | |||
1418 | /* just report other unsolicited interrupts */ | ||
1419 | DEV_MESSAGE(KERN_DEBUG, device, "%s", | ||
1420 | "unsolicited interrupt received"); | ||
1421 | device->discipline->dump_sense(device, NULL, irb); | ||
1422 | dasd_schedule_device_bh(device); | ||
1423 | |||
1424 | return; | ||
1425 | }; | ||
1426 | |||
1427 | static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev, | ||
1428 | struct dasd_block *block, | ||
1429 | struct request *req) | ||
1173 | { | 1430 | { |
1174 | struct dasd_eckd_private *private; | 1431 | struct dasd_eckd_private *private; |
1175 | unsigned long *idaws; | 1432 | unsigned long *idaws; |
@@ -1185,8 +1442,11 @@ dasd_eckd_build_cp(struct dasd_device * device, struct request *req) | |||
1185 | sector_t first_trk, last_trk; | 1442 | sector_t first_trk, last_trk; |
1186 | unsigned int first_offs, last_offs; | 1443 | unsigned int first_offs, last_offs; |
1187 | unsigned char cmd, rcmd; | 1444 | unsigned char cmd, rcmd; |
1445 | int use_prefix; | ||
1446 | struct dasd_device *basedev; | ||
1188 | 1447 | ||
1189 | private = (struct dasd_eckd_private *) device->private; | 1448 | basedev = block->base; |
1449 | private = (struct dasd_eckd_private *) basedev->private; | ||
1190 | if (rq_data_dir(req) == READ) | 1450 | if (rq_data_dir(req) == READ) |
1191 | cmd = DASD_ECKD_CCW_READ_MT; | 1451 | cmd = DASD_ECKD_CCW_READ_MT; |
1192 | else if (rq_data_dir(req) == WRITE) | 1452 | else if (rq_data_dir(req) == WRITE) |
@@ -1194,13 +1454,13 @@ dasd_eckd_build_cp(struct dasd_device * device, struct request *req) | |||
1194 | else | 1454 | else |
1195 | return ERR_PTR(-EINVAL); | 1455 | return ERR_PTR(-EINVAL); |
1196 | /* Calculate number of blocks/records per track. */ | 1456 | /* Calculate number of blocks/records per track. */ |
1197 | blksize = device->bp_block; | 1457 | blksize = block->bp_block; |
1198 | blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize); | 1458 | blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize); |
1199 | /* Calculate record id of first and last block. */ | 1459 | /* Calculate record id of first and last block. */ |
1200 | first_rec = first_trk = req->sector >> device->s2b_shift; | 1460 | first_rec = first_trk = req->sector >> block->s2b_shift; |
1201 | first_offs = sector_div(first_trk, blk_per_trk); | 1461 | first_offs = sector_div(first_trk, blk_per_trk); |
1202 | last_rec = last_trk = | 1462 | last_rec = last_trk = |
1203 | (req->sector + req->nr_sectors - 1) >> device->s2b_shift; | 1463 | (req->sector + req->nr_sectors - 1) >> block->s2b_shift; |
1204 | last_offs = sector_div(last_trk, blk_per_trk); | 1464 | last_offs = sector_div(last_trk, blk_per_trk); |
1205 | /* Check struct bio and count the number of blocks for the request. */ | 1465 | /* Check struct bio and count the number of blocks for the request. */ |
1206 | count = 0; | 1466 | count = 0; |
@@ -1209,20 +1469,33 @@ dasd_eckd_build_cp(struct dasd_device * device, struct request *req) | |||
1209 | if (bv->bv_len & (blksize - 1)) | 1469 | if (bv->bv_len & (blksize - 1)) |
1210 | /* Eckd can only do full blocks. */ | 1470 | /* Eckd can only do full blocks. */ |
1211 | return ERR_PTR(-EINVAL); | 1471 | return ERR_PTR(-EINVAL); |
1212 | count += bv->bv_len >> (device->s2b_shift + 9); | 1472 | count += bv->bv_len >> (block->s2b_shift + 9); |
1213 | #if defined(CONFIG_64BIT) | 1473 | #if defined(CONFIG_64BIT) |
1214 | if (idal_is_needed (page_address(bv->bv_page), bv->bv_len)) | 1474 | if (idal_is_needed (page_address(bv->bv_page), bv->bv_len)) |
1215 | cidaw += bv->bv_len >> (device->s2b_shift + 9); | 1475 | cidaw += bv->bv_len >> (block->s2b_shift + 9); |
1216 | #endif | 1476 | #endif |
1217 | } | 1477 | } |
1218 | /* Paranoia. */ | 1478 | /* Paranoia. */ |
1219 | if (count != last_rec - first_rec + 1) | 1479 | if (count != last_rec - first_rec + 1) |
1220 | return ERR_PTR(-EINVAL); | 1480 | return ERR_PTR(-EINVAL); |
1221 | /* 1x define extent + 1x locate record + number of blocks */ | 1481 | |
1222 | cplength = 2 + count; | 1482 | /* use the prefix command if available */ |
1223 | /* 1x define extent + 1x locate record + cidaws*sizeof(long) */ | 1483 | use_prefix = private->features.feature[8] & 0x01; |
1224 | datasize = sizeof(struct DE_eckd_data) + sizeof(struct LO_eckd_data) + | 1484 | if (use_prefix) { |
1225 | cidaw * sizeof(unsigned long); | 1485 | /* 1x prefix + number of blocks */ |
1486 | cplength = 2 + count; | ||
1487 | /* 1x prefix + cidaws*sizeof(long) */ | ||
1488 | datasize = sizeof(struct PFX_eckd_data) + | ||
1489 | sizeof(struct LO_eckd_data) + | ||
1490 | cidaw * sizeof(unsigned long); | ||
1491 | } else { | ||
1492 | /* 1x define extent + 1x locate record + number of blocks */ | ||
1493 | cplength = 2 + count; | ||
1494 | /* 1x define extent + 1x locate record + cidaws*sizeof(long) */ | ||
1495 | datasize = sizeof(struct DE_eckd_data) + | ||
1496 | sizeof(struct LO_eckd_data) + | ||
1497 | cidaw * sizeof(unsigned long); | ||
1498 | } | ||
1226 | /* Find out the number of additional locate record ccws for cdl. */ | 1499 | /* Find out the number of additional locate record ccws for cdl. */ |
1227 | if (private->uses_cdl && first_rec < 2*blk_per_trk) { | 1500 | if (private->uses_cdl && first_rec < 2*blk_per_trk) { |
1228 | if (last_rec >= 2*blk_per_trk) | 1501 | if (last_rec >= 2*blk_per_trk) |
@@ -1232,26 +1505,42 @@ dasd_eckd_build_cp(struct dasd_device * device, struct request *req) | |||
1232 | } | 1505 | } |
1233 | /* Allocate the ccw request. */ | 1506 | /* Allocate the ccw request. */ |
1234 | cqr = dasd_smalloc_request(dasd_eckd_discipline.name, | 1507 | cqr = dasd_smalloc_request(dasd_eckd_discipline.name, |
1235 | cplength, datasize, device); | 1508 | cplength, datasize, startdev); |
1236 | if (IS_ERR(cqr)) | 1509 | if (IS_ERR(cqr)) |
1237 | return cqr; | 1510 | return cqr; |
1238 | ccw = cqr->cpaddr; | 1511 | ccw = cqr->cpaddr; |
1239 | /* First ccw is define extent. */ | 1512 | /* First ccw is define extent or prefix. */ |
1240 | if (define_extent(ccw++, cqr->data, first_trk, | 1513 | if (use_prefix) { |
1241 | last_trk, cmd, device) == -EAGAIN) { | 1514 | if (prefix(ccw++, cqr->data, first_trk, |
1242 | /* Clock not in sync and XRC is enabled. Try again later. */ | 1515 | last_trk, cmd, basedev, startdev) == -EAGAIN) { |
1243 | dasd_sfree_request(cqr, device); | 1516 | /* Clock not in sync and XRC is enabled. |
1244 | return ERR_PTR(-EAGAIN); | 1517 | * Try again later. |
1518 | */ | ||
1519 | dasd_sfree_request(cqr, startdev); | ||
1520 | return ERR_PTR(-EAGAIN); | ||
1521 | } | ||
1522 | idaws = (unsigned long *) (cqr->data + | ||
1523 | sizeof(struct PFX_eckd_data)); | ||
1524 | } else { | ||
1525 | if (define_extent(ccw++, cqr->data, first_trk, | ||
1526 | last_trk, cmd, startdev) == -EAGAIN) { | ||
1527 | /* Clock not in sync and XRC is enabled. | ||
1528 | * Try again later. | ||
1529 | */ | ||
1530 | dasd_sfree_request(cqr, startdev); | ||
1531 | return ERR_PTR(-EAGAIN); | ||
1532 | } | ||
1533 | idaws = (unsigned long *) (cqr->data + | ||
1534 | sizeof(struct DE_eckd_data)); | ||
1245 | } | 1535 | } |
1246 | /* Build locate_record+read/write/ccws. */ | 1536 | /* Build locate_record+read/write/ccws. */ |
1247 | idaws = (unsigned long *) (cqr->data + sizeof(struct DE_eckd_data)); | ||
1248 | LO_data = (struct LO_eckd_data *) (idaws + cidaw); | 1537 | LO_data = (struct LO_eckd_data *) (idaws + cidaw); |
1249 | recid = first_rec; | 1538 | recid = first_rec; |
1250 | if (private->uses_cdl == 0 || recid > 2*blk_per_trk) { | 1539 | if (private->uses_cdl == 0 || recid > 2*blk_per_trk) { |
1251 | /* Only standard blocks so there is just one locate record. */ | 1540 | /* Only standard blocks so there is just one locate record. */ |
1252 | ccw[-1].flags |= CCW_FLAG_CC; | 1541 | ccw[-1].flags |= CCW_FLAG_CC; |
1253 | locate_record(ccw++, LO_data++, first_trk, first_offs + 1, | 1542 | locate_record(ccw++, LO_data++, first_trk, first_offs + 1, |
1254 | last_rec - recid + 1, cmd, device, blksize); | 1543 | last_rec - recid + 1, cmd, basedev, blksize); |
1255 | } | 1544 | } |
1256 | rq_for_each_segment(bv, req, iter) { | 1545 | rq_for_each_segment(bv, req, iter) { |
1257 | dst = page_address(bv->bv_page) + bv->bv_offset; | 1546 | dst = page_address(bv->bv_page) + bv->bv_offset; |
@@ -1281,7 +1570,7 @@ dasd_eckd_build_cp(struct dasd_device * device, struct request *req) | |||
1281 | ccw[-1].flags |= CCW_FLAG_CC; | 1570 | ccw[-1].flags |= CCW_FLAG_CC; |
1282 | locate_record(ccw++, LO_data++, | 1571 | locate_record(ccw++, LO_data++, |
1283 | trkid, recoffs + 1, | 1572 | trkid, recoffs + 1, |
1284 | 1, rcmd, device, count); | 1573 | 1, rcmd, basedev, count); |
1285 | } | 1574 | } |
1286 | /* Locate record for standard blocks ? */ | 1575 | /* Locate record for standard blocks ? */ |
1287 | if (private->uses_cdl && recid == 2*blk_per_trk) { | 1576 | if (private->uses_cdl && recid == 2*blk_per_trk) { |
@@ -1289,7 +1578,7 @@ dasd_eckd_build_cp(struct dasd_device * device, struct request *req) | |||
1289 | locate_record(ccw++, LO_data++, | 1578 | locate_record(ccw++, LO_data++, |
1290 | trkid, recoffs + 1, | 1579 | trkid, recoffs + 1, |
1291 | last_rec - recid + 1, | 1580 | last_rec - recid + 1, |
1292 | cmd, device, count); | 1581 | cmd, basedev, count); |
1293 | } | 1582 | } |
1294 | /* Read/write ccw. */ | 1583 | /* Read/write ccw. */ |
1295 | ccw[-1].flags |= CCW_FLAG_CC; | 1584 | ccw[-1].flags |= CCW_FLAG_CC; |
@@ -1310,7 +1599,9 @@ dasd_eckd_build_cp(struct dasd_device * device, struct request *req) | |||
1310 | } | 1599 | } |
1311 | if (req->cmd_flags & REQ_FAILFAST) | 1600 | if (req->cmd_flags & REQ_FAILFAST) |
1312 | set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); | 1601 | set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); |
1313 | cqr->device = device; | 1602 | cqr->startdev = startdev; |
1603 | cqr->memdev = startdev; | ||
1604 | cqr->block = block; | ||
1314 | cqr->expires = 5 * 60 * HZ; /* 5 minutes */ | 1605 | cqr->expires = 5 * 60 * HZ; /* 5 minutes */ |
1315 | cqr->lpm = private->path_data.ppm; | 1606 | cqr->lpm = private->path_data.ppm; |
1316 | cqr->retries = 256; | 1607 | cqr->retries = 256; |
@@ -1333,10 +1624,10 @@ dasd_eckd_free_cp(struct dasd_ccw_req *cqr, struct request *req) | |||
1333 | 1624 | ||
1334 | if (!dasd_page_cache) | 1625 | if (!dasd_page_cache) |
1335 | goto out; | 1626 | goto out; |
1336 | private = (struct dasd_eckd_private *) cqr->device->private; | 1627 | private = (struct dasd_eckd_private *) cqr->block->base->private; |
1337 | blksize = cqr->device->bp_block; | 1628 | blksize = cqr->block->bp_block; |
1338 | blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize); | 1629 | blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize); |
1339 | recid = req->sector >> cqr->device->s2b_shift; | 1630 | recid = req->sector >> cqr->block->s2b_shift; |
1340 | ccw = cqr->cpaddr; | 1631 | ccw = cqr->cpaddr; |
1341 | /* Skip over define extent & locate record. */ | 1632 | /* Skip over define extent & locate record. */ |
1342 | ccw++; | 1633 | ccw++; |
@@ -1367,10 +1658,71 @@ dasd_eckd_free_cp(struct dasd_ccw_req *cqr, struct request *req) | |||
1367 | } | 1658 | } |
1368 | out: | 1659 | out: |
1369 | status = cqr->status == DASD_CQR_DONE; | 1660 | status = cqr->status == DASD_CQR_DONE; |
1370 | dasd_sfree_request(cqr, cqr->device); | 1661 | dasd_sfree_request(cqr, cqr->memdev); |
1371 | return status; | 1662 | return status; |
1372 | } | 1663 | } |
1373 | 1664 | ||
1665 | /* | ||
1666 | * Modify ccw chain in cqr so it can be started on a base device. | ||
1667 | * | ||
1668 | * Note that this is not enough to restart the cqr! | ||
1669 | * Either reset cqr->startdev as well (summary unit check handling) | ||
1670 | * or restart via separate cqr (as in ERP handling). | ||
1671 | */ | ||
1672 | void dasd_eckd_reset_ccw_to_base_io(struct dasd_ccw_req *cqr) | ||
1673 | { | ||
1674 | struct ccw1 *ccw; | ||
1675 | struct PFX_eckd_data *pfxdata; | ||
1676 | |||
1677 | ccw = cqr->cpaddr; | ||
1678 | pfxdata = cqr->data; | ||
1679 | |||
1680 | if (ccw->cmd_code == DASD_ECKD_CCW_PFX) { | ||
1681 | pfxdata->validity.verify_base = 0; | ||
1682 | pfxdata->validity.hyper_pav = 0; | ||
1683 | } | ||
1684 | } | ||
1685 | |||
1686 | #define DASD_ECKD_CHANQ_MAX_SIZE 4 | ||
1687 | |||
1688 | static struct dasd_ccw_req *dasd_eckd_build_alias_cp(struct dasd_device *base, | ||
1689 | struct dasd_block *block, | ||
1690 | struct request *req) | ||
1691 | { | ||
1692 | struct dasd_eckd_private *private; | ||
1693 | struct dasd_device *startdev; | ||
1694 | unsigned long flags; | ||
1695 | struct dasd_ccw_req *cqr; | ||
1696 | |||
1697 | startdev = dasd_alias_get_start_dev(base); | ||
1698 | if (!startdev) | ||
1699 | startdev = base; | ||
1700 | private = (struct dasd_eckd_private *) startdev->private; | ||
1701 | if (private->count >= DASD_ECKD_CHANQ_MAX_SIZE) | ||
1702 | return ERR_PTR(-EBUSY); | ||
1703 | |||
1704 | spin_lock_irqsave(get_ccwdev_lock(startdev->cdev), flags); | ||
1705 | private->count++; | ||
1706 | cqr = dasd_eckd_build_cp(startdev, block, req); | ||
1707 | if (IS_ERR(cqr)) | ||
1708 | private->count--; | ||
1709 | spin_unlock_irqrestore(get_ccwdev_lock(startdev->cdev), flags); | ||
1710 | return cqr; | ||
1711 | } | ||
1712 | |||
1713 | static int dasd_eckd_free_alias_cp(struct dasd_ccw_req *cqr, | ||
1714 | struct request *req) | ||
1715 | { | ||
1716 | struct dasd_eckd_private *private; | ||
1717 | unsigned long flags; | ||
1718 | |||
1719 | spin_lock_irqsave(get_ccwdev_lock(cqr->memdev->cdev), flags); | ||
1720 | private = (struct dasd_eckd_private *) cqr->memdev->private; | ||
1721 | private->count--; | ||
1722 | spin_unlock_irqrestore(get_ccwdev_lock(cqr->memdev->cdev), flags); | ||
1723 | return dasd_eckd_free_cp(cqr, req); | ||
1724 | } | ||
1725 | |||
1374 | static int | 1726 | static int |
1375 | dasd_eckd_fill_info(struct dasd_device * device, | 1727 | dasd_eckd_fill_info(struct dasd_device * device, |
1376 | struct dasd_information2_t * info) | 1728 | struct dasd_information2_t * info) |
@@ -1384,9 +1736,9 @@ dasd_eckd_fill_info(struct dasd_device * device, | |||
1384 | info->characteristics_size = sizeof(struct dasd_eckd_characteristics); | 1736 | info->characteristics_size = sizeof(struct dasd_eckd_characteristics); |
1385 | memcpy(info->characteristics, &private->rdc_data, | 1737 | memcpy(info->characteristics, &private->rdc_data, |
1386 | sizeof(struct dasd_eckd_characteristics)); | 1738 | sizeof(struct dasd_eckd_characteristics)); |
1387 | info->confdata_size = sizeof (struct dasd_eckd_confdata); | 1739 | info->confdata_size = sizeof(struct dasd_eckd_confdata); |
1388 | memcpy(info->configuration_data, &private->conf_data, | 1740 | memcpy(info->configuration_data, &private->conf_data, |
1389 | sizeof (struct dasd_eckd_confdata)); | 1741 | sizeof(struct dasd_eckd_confdata)); |
1390 | return 0; | 1742 | return 0; |
1391 | } | 1743 | } |
1392 | 1744 | ||
@@ -1419,7 +1771,8 @@ dasd_eckd_release(struct dasd_device *device) | |||
1419 | cqr->cpaddr->flags |= CCW_FLAG_SLI; | 1771 | cqr->cpaddr->flags |= CCW_FLAG_SLI; |
1420 | cqr->cpaddr->count = 32; | 1772 | cqr->cpaddr->count = 32; |
1421 | cqr->cpaddr->cda = (__u32)(addr_t) cqr->data; | 1773 | cqr->cpaddr->cda = (__u32)(addr_t) cqr->data; |
1422 | cqr->device = device; | 1774 | cqr->startdev = device; |
1775 | cqr->memdev = device; | ||
1423 | clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); | 1776 | clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); |
1424 | set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); | 1777 | set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); |
1425 | cqr->retries = 2; /* set retry counter to enable basic ERP */ | 1778 | cqr->retries = 2; /* set retry counter to enable basic ERP */ |
@@ -1429,7 +1782,7 @@ dasd_eckd_release(struct dasd_device *device) | |||
1429 | 1782 | ||
1430 | rc = dasd_sleep_on_immediatly(cqr); | 1783 | rc = dasd_sleep_on_immediatly(cqr); |
1431 | 1784 | ||
1432 | dasd_sfree_request(cqr, cqr->device); | 1785 | dasd_sfree_request(cqr, cqr->memdev); |
1433 | return rc; | 1786 | return rc; |
1434 | } | 1787 | } |
1435 | 1788 | ||
@@ -1459,7 +1812,8 @@ dasd_eckd_reserve(struct dasd_device *device) | |||
1459 | cqr->cpaddr->flags |= CCW_FLAG_SLI; | 1812 | cqr->cpaddr->flags |= CCW_FLAG_SLI; |
1460 | cqr->cpaddr->count = 32; | 1813 | cqr->cpaddr->count = 32; |
1461 | cqr->cpaddr->cda = (__u32)(addr_t) cqr->data; | 1814 | cqr->cpaddr->cda = (__u32)(addr_t) cqr->data; |
1462 | cqr->device = device; | 1815 | cqr->startdev = device; |
1816 | cqr->memdev = device; | ||
1463 | clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); | 1817 | clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); |
1464 | set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); | 1818 | set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); |
1465 | cqr->retries = 2; /* set retry counter to enable basic ERP */ | 1819 | cqr->retries = 2; /* set retry counter to enable basic ERP */ |
@@ -1469,7 +1823,7 @@ dasd_eckd_reserve(struct dasd_device *device) | |||
1469 | 1823 | ||
1470 | rc = dasd_sleep_on_immediatly(cqr); | 1824 | rc = dasd_sleep_on_immediatly(cqr); |
1471 | 1825 | ||
1472 | dasd_sfree_request(cqr, cqr->device); | 1826 | dasd_sfree_request(cqr, cqr->memdev); |
1473 | return rc; | 1827 | return rc; |
1474 | } | 1828 | } |
1475 | 1829 | ||
@@ -1498,7 +1852,8 @@ dasd_eckd_steal_lock(struct dasd_device *device) | |||
1498 | cqr->cpaddr->flags |= CCW_FLAG_SLI; | 1852 | cqr->cpaddr->flags |= CCW_FLAG_SLI; |
1499 | cqr->cpaddr->count = 32; | 1853 | cqr->cpaddr->count = 32; |
1500 | cqr->cpaddr->cda = (__u32)(addr_t) cqr->data; | 1854 | cqr->cpaddr->cda = (__u32)(addr_t) cqr->data; |
1501 | cqr->device = device; | 1855 | cqr->startdev = device; |
1856 | cqr->memdev = device; | ||
1502 | clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); | 1857 | clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); |
1503 | set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); | 1858 | set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); |
1504 | cqr->retries = 2; /* set retry counter to enable basic ERP */ | 1859 | cqr->retries = 2; /* set retry counter to enable basic ERP */ |
@@ -1508,7 +1863,7 @@ dasd_eckd_steal_lock(struct dasd_device *device) | |||
1508 | 1863 | ||
1509 | rc = dasd_sleep_on_immediatly(cqr); | 1864 | rc = dasd_sleep_on_immediatly(cqr); |
1510 | 1865 | ||
1511 | dasd_sfree_request(cqr, cqr->device); | 1866 | dasd_sfree_request(cqr, cqr->memdev); |
1512 | return rc; | 1867 | return rc; |
1513 | } | 1868 | } |
1514 | 1869 | ||
@@ -1526,52 +1881,52 @@ dasd_eckd_performance(struct dasd_device *device, void __user *argp) | |||
1526 | 1881 | ||
1527 | cqr = dasd_smalloc_request(dasd_eckd_discipline.name, | 1882 | cqr = dasd_smalloc_request(dasd_eckd_discipline.name, |
1528 | 1 /* PSF */ + 1 /* RSSD */ , | 1883 | 1 /* PSF */ + 1 /* RSSD */ , |
1529 | (sizeof (struct dasd_psf_prssd_data) + | 1884 | (sizeof(struct dasd_psf_prssd_data) + |
1530 | sizeof (struct dasd_rssd_perf_stats_t)), | 1885 | sizeof(struct dasd_rssd_perf_stats_t)), |
1531 | device); | 1886 | device); |
1532 | if (IS_ERR(cqr)) { | 1887 | if (IS_ERR(cqr)) { |
1533 | DEV_MESSAGE(KERN_WARNING, device, "%s", | 1888 | DEV_MESSAGE(KERN_WARNING, device, "%s", |
1534 | "Could not allocate initialization request"); | 1889 | "Could not allocate initialization request"); |
1535 | return PTR_ERR(cqr); | 1890 | return PTR_ERR(cqr); |
1536 | } | 1891 | } |
1537 | cqr->device = device; | 1892 | cqr->startdev = device; |
1893 | cqr->memdev = device; | ||
1538 | cqr->retries = 0; | 1894 | cqr->retries = 0; |
1539 | cqr->expires = 10 * HZ; | 1895 | cqr->expires = 10 * HZ; |
1540 | 1896 | ||
1541 | /* Prepare for Read Subsystem Data */ | 1897 | /* Prepare for Read Subsystem Data */ |
1542 | prssdp = (struct dasd_psf_prssd_data *) cqr->data; | 1898 | prssdp = (struct dasd_psf_prssd_data *) cqr->data; |
1543 | memset(prssdp, 0, sizeof (struct dasd_psf_prssd_data)); | 1899 | memset(prssdp, 0, sizeof(struct dasd_psf_prssd_data)); |
1544 | prssdp->order = PSF_ORDER_PRSSD; | 1900 | prssdp->order = PSF_ORDER_PRSSD; |
1545 | prssdp->suborder = 0x01; /* Perfomance Statistics */ | 1901 | prssdp->suborder = 0x01; /* Performance Statistics */ |
1546 | prssdp->varies[1] = 0x01; /* Perf Statistics for the Subsystem */ | 1902 | prssdp->varies[1] = 0x01; /* Perf Statistics for the Subsystem */ |
1547 | 1903 | ||
1548 | ccw = cqr->cpaddr; | 1904 | ccw = cqr->cpaddr; |
1549 | ccw->cmd_code = DASD_ECKD_CCW_PSF; | 1905 | ccw->cmd_code = DASD_ECKD_CCW_PSF; |
1550 | ccw->count = sizeof (struct dasd_psf_prssd_data); | 1906 | ccw->count = sizeof(struct dasd_psf_prssd_data); |
1551 | ccw->flags |= CCW_FLAG_CC; | 1907 | ccw->flags |= CCW_FLAG_CC; |
1552 | ccw->cda = (__u32)(addr_t) prssdp; | 1908 | ccw->cda = (__u32)(addr_t) prssdp; |
1553 | 1909 | ||
1554 | /* Read Subsystem Data - Performance Statistics */ | 1910 | /* Read Subsystem Data - Performance Statistics */ |
1555 | stats = (struct dasd_rssd_perf_stats_t *) (prssdp + 1); | 1911 | stats = (struct dasd_rssd_perf_stats_t *) (prssdp + 1); |
1556 | memset(stats, 0, sizeof (struct dasd_rssd_perf_stats_t)); | 1912 | memset(stats, 0, sizeof(struct dasd_rssd_perf_stats_t)); |
1557 | 1913 | ||
1558 | ccw++; | 1914 | ccw++; |
1559 | ccw->cmd_code = DASD_ECKD_CCW_RSSD; | 1915 | ccw->cmd_code = DASD_ECKD_CCW_RSSD; |
1560 | ccw->count = sizeof (struct dasd_rssd_perf_stats_t); | 1916 | ccw->count = sizeof(struct dasd_rssd_perf_stats_t); |
1561 | ccw->cda = (__u32)(addr_t) stats; | 1917 | ccw->cda = (__u32)(addr_t) stats; |
1562 | 1918 | ||
1563 | cqr->buildclk = get_clock(); | 1919 | cqr->buildclk = get_clock(); |
1564 | cqr->status = DASD_CQR_FILLED; | 1920 | cqr->status = DASD_CQR_FILLED; |
1565 | rc = dasd_sleep_on(cqr); | 1921 | rc = dasd_sleep_on(cqr); |
1566 | if (rc == 0) { | 1922 | if (rc == 0) { |
1567 | /* Prepare for Read Subsystem Data */ | ||
1568 | prssdp = (struct dasd_psf_prssd_data *) cqr->data; | 1923 | prssdp = (struct dasd_psf_prssd_data *) cqr->data; |
1569 | stats = (struct dasd_rssd_perf_stats_t *) (prssdp + 1); | 1924 | stats = (struct dasd_rssd_perf_stats_t *) (prssdp + 1); |
1570 | if (copy_to_user(argp, stats, | 1925 | if (copy_to_user(argp, stats, |
1571 | sizeof(struct dasd_rssd_perf_stats_t))) | 1926 | sizeof(struct dasd_rssd_perf_stats_t))) |
1572 | rc = -EFAULT; | 1927 | rc = -EFAULT; |
1573 | } | 1928 | } |
1574 | dasd_sfree_request(cqr, cqr->device); | 1929 | dasd_sfree_request(cqr, cqr->memdev); |
1575 | return rc; | 1930 | return rc; |
1576 | } | 1931 | } |
1577 | 1932 | ||
@@ -1594,7 +1949,7 @@ dasd_eckd_get_attrib(struct dasd_device *device, void __user *argp) | |||
1594 | 1949 | ||
1595 | rc = 0; | 1950 | rc = 0; |
1596 | if (copy_to_user(argp, (long *) &attrib, | 1951 | if (copy_to_user(argp, (long *) &attrib, |
1597 | sizeof (struct attrib_data_t))) | 1952 | sizeof(struct attrib_data_t))) |
1598 | rc = -EFAULT; | 1953 | rc = -EFAULT; |
1599 | 1954 | ||
1600 | return rc; | 1955 | return rc; |
@@ -1627,8 +1982,10 @@ dasd_eckd_set_attrib(struct dasd_device *device, void __user *argp) | |||
1627 | } | 1982 | } |
1628 | 1983 | ||
1629 | static int | 1984 | static int |
1630 | dasd_eckd_ioctl(struct dasd_device *device, unsigned int cmd, void __user *argp) | 1985 | dasd_eckd_ioctl(struct dasd_block *block, unsigned int cmd, void __user *argp) |
1631 | { | 1986 | { |
1987 | struct dasd_device *device = block->base; | ||
1988 | |||
1632 | switch (cmd) { | 1989 | switch (cmd) { |
1633 | case BIODASDGATTR: | 1990 | case BIODASDGATTR: |
1634 | return dasd_eckd_get_attrib(device, argp); | 1991 | return dasd_eckd_get_attrib(device, argp); |
@@ -1685,9 +2042,8 @@ dasd_eckd_dump_ccw_range(struct ccw1 *from, struct ccw1 *to, char *page) | |||
1685 | * Print sense data and related channel program. | 2042 | * Print sense data and related channel program. |
1686 | * Parts are printed because printk buffer is only 1024 bytes. | 2043 | * Parts are printed because printk buffer is only 1024 bytes. |
1687 | */ | 2044 | */ |
1688 | static void | 2045 | static void dasd_eckd_dump_sense(struct dasd_device *device, |
1689 | dasd_eckd_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req, | 2046 | struct dasd_ccw_req *req, struct irb *irb) |
1690 | struct irb *irb) | ||
1691 | { | 2047 | { |
1692 | char *page; | 2048 | char *page; |
1693 | struct ccw1 *first, *last, *fail, *from, *to; | 2049 | struct ccw1 *first, *last, *fail, *from, *to; |
@@ -1743,37 +2099,40 @@ dasd_eckd_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req, | |||
1743 | } | 2099 | } |
1744 | printk("%s", page); | 2100 | printk("%s", page); |
1745 | 2101 | ||
1746 | /* dump the Channel Program (max 140 Bytes per line) */ | 2102 | if (req) { |
1747 | /* Count CCW and print first CCWs (maximum 1024 % 140 = 7) */ | 2103 | /* req == NULL for unsolicited interrupts */ |
1748 | first = req->cpaddr; | 2104 | /* dump the Channel Program (max 140 Bytes per line) */ |
1749 | for (last = first; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++); | 2105 | /* Count CCW and print first CCWs (maximum 1024 % 140 = 7) */ |
1750 | to = min(first + 6, last); | 2106 | first = req->cpaddr; |
1751 | len = sprintf(page, KERN_ERR PRINTK_HEADER | 2107 | for (last = first; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++); |
1752 | " Related CP in req: %p\n", req); | 2108 | to = min(first + 6, last); |
1753 | dasd_eckd_dump_ccw_range(first, to, page + len); | 2109 | len = sprintf(page, KERN_ERR PRINTK_HEADER |
1754 | printk("%s", page); | 2110 | " Related CP in req: %p\n", req); |
2111 | dasd_eckd_dump_ccw_range(first, to, page + len); | ||
2112 | printk("%s", page); | ||
1755 | 2113 | ||
1756 | /* print failing CCW area (maximum 4) */ | 2114 | /* print failing CCW area (maximum 4) */ |
1757 | /* scsw->cda is either valid or zero */ | 2115 | /* scsw->cda is either valid or zero */ |
1758 | len = 0; | 2116 | len = 0; |
1759 | from = ++to; | 2117 | from = ++to; |
1760 | fail = (struct ccw1 *)(addr_t) irb->scsw.cpa; /* failing CCW */ | 2118 | fail = (struct ccw1 *)(addr_t) irb->scsw.cpa; /* failing CCW */ |
1761 | if (from < fail - 2) { | 2119 | if (from < fail - 2) { |
1762 | from = fail - 2; /* there is a gap - print header */ | 2120 | from = fail - 2; /* there is a gap - print header */ |
1763 | len += sprintf(page, KERN_ERR PRINTK_HEADER "......\n"); | 2121 | len += sprintf(page, KERN_ERR PRINTK_HEADER "......\n"); |
1764 | } | 2122 | } |
1765 | to = min(fail + 1, last); | 2123 | to = min(fail + 1, last); |
1766 | len += dasd_eckd_dump_ccw_range(from, to, page + len); | 2124 | len += dasd_eckd_dump_ccw_range(from, to, page + len); |
1767 | 2125 | ||
1768 | /* print last CCWs (maximum 2) */ | 2126 | /* print last CCWs (maximum 2) */ |
1769 | from = max(from, ++to); | 2127 | from = max(from, ++to); |
1770 | if (from < last - 1) { | 2128 | if (from < last - 1) { |
1771 | from = last - 1; /* there is a gap - print header */ | 2129 | from = last - 1; /* there is a gap - print header */ |
1772 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n"); | 2130 | len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n"); |
2131 | } | ||
2132 | len += dasd_eckd_dump_ccw_range(from, last, page + len); | ||
2133 | if (len > 0) | ||
2134 | printk("%s", page); | ||
1773 | } | 2135 | } |
1774 | len += dasd_eckd_dump_ccw_range(from, last, page + len); | ||
1775 | if (len > 0) | ||
1776 | printk("%s", page); | ||
1777 | free_page((unsigned long) page); | 2136 | free_page((unsigned long) page); |
1778 | } | 2137 | } |
1779 | 2138 | ||
@@ -1796,16 +2155,20 @@ static struct dasd_discipline dasd_eckd_discipline = { | |||
1796 | .ebcname = "ECKD", | 2155 | .ebcname = "ECKD", |
1797 | .max_blocks = 240, | 2156 | .max_blocks = 240, |
1798 | .check_device = dasd_eckd_check_characteristics, | 2157 | .check_device = dasd_eckd_check_characteristics, |
2158 | .uncheck_device = dasd_eckd_uncheck_device, | ||
1799 | .do_analysis = dasd_eckd_do_analysis, | 2159 | .do_analysis = dasd_eckd_do_analysis, |
2160 | .ready_to_online = dasd_eckd_ready_to_online, | ||
2161 | .online_to_ready = dasd_eckd_online_to_ready, | ||
1800 | .fill_geometry = dasd_eckd_fill_geometry, | 2162 | .fill_geometry = dasd_eckd_fill_geometry, |
1801 | .start_IO = dasd_start_IO, | 2163 | .start_IO = dasd_start_IO, |
1802 | .term_IO = dasd_term_IO, | 2164 | .term_IO = dasd_term_IO, |
2165 | .handle_terminated_request = dasd_eckd_handle_terminated_request, | ||
1803 | .format_device = dasd_eckd_format_device, | 2166 | .format_device = dasd_eckd_format_device, |
1804 | .examine_error = dasd_eckd_examine_error, | ||
1805 | .erp_action = dasd_eckd_erp_action, | 2167 | .erp_action = dasd_eckd_erp_action, |
1806 | .erp_postaction = dasd_eckd_erp_postaction, | 2168 | .erp_postaction = dasd_eckd_erp_postaction, |
1807 | .build_cp = dasd_eckd_build_cp, | 2169 | .handle_unsolicited_interrupt = dasd_eckd_handle_unsolicited_interrupt, |
1808 | .free_cp = dasd_eckd_free_cp, | 2170 | .build_cp = dasd_eckd_build_alias_cp, |
2171 | .free_cp = dasd_eckd_free_alias_cp, | ||
1809 | .dump_sense = dasd_eckd_dump_sense, | 2172 | .dump_sense = dasd_eckd_dump_sense, |
1810 | .fill_info = dasd_eckd_fill_info, | 2173 | .fill_info = dasd_eckd_fill_info, |
1811 | .ioctl = dasd_eckd_ioctl, | 2174 | .ioctl = dasd_eckd_ioctl, |
diff --git a/drivers/s390/block/dasd_eckd.h b/drivers/s390/block/dasd_eckd.h index 712ff1650134..fc2509c939bc 100644 --- a/drivers/s390/block/dasd_eckd.h +++ b/drivers/s390/block/dasd_eckd.h | |||
@@ -39,6 +39,8 @@ | |||
39 | #define DASD_ECKD_CCW_READ_CKD_MT 0x9e | 39 | #define DASD_ECKD_CCW_READ_CKD_MT 0x9e |
40 | #define DASD_ECKD_CCW_WRITE_CKD_MT 0x9d | 40 | #define DASD_ECKD_CCW_WRITE_CKD_MT 0x9d |
41 | #define DASD_ECKD_CCW_RESERVE 0xB4 | 41 | #define DASD_ECKD_CCW_RESERVE 0xB4 |
42 | #define DASD_ECKD_CCW_PFX 0xE7 | ||
43 | #define DASD_ECKD_CCW_RSCK 0xF9 | ||
42 | 44 | ||
43 | /* | 45 | /* |
44 | * Perform Subsystem Function / Sub-Orders | 46 | * Perform Subsystem Function / Sub-Orders |
@@ -137,6 +139,25 @@ struct LO_eckd_data { | |||
137 | __u16 length; | 139 | __u16 length; |
138 | } __attribute__ ((packed)); | 140 | } __attribute__ ((packed)); |
139 | 141 | ||
142 | /* Prefix data for format 0x00 and 0x01 */ | ||
143 | struct PFX_eckd_data { | ||
144 | unsigned char format; | ||
145 | struct { | ||
146 | unsigned char define_extend:1; | ||
147 | unsigned char time_stamp:1; | ||
148 | unsigned char verify_base:1; | ||
149 | unsigned char hyper_pav:1; | ||
150 | unsigned char reserved:4; | ||
151 | } __attribute__ ((packed)) validity; | ||
152 | __u8 base_address; | ||
153 | __u8 aux; | ||
154 | __u8 base_lss; | ||
155 | __u8 reserved[7]; | ||
156 | struct DE_eckd_data define_extend; | ||
157 | struct LO_eckd_data locate_record; | ||
158 | __u8 LO_extended_data[4]; | ||
159 | } __attribute__ ((packed)); | ||
160 | |||
140 | struct dasd_eckd_characteristics { | 161 | struct dasd_eckd_characteristics { |
141 | __u16 cu_type; | 162 | __u16 cu_type; |
142 | struct { | 163 | struct { |
@@ -254,7 +275,9 @@ struct dasd_eckd_confdata { | |||
254 | } __attribute__ ((packed)) ned; | 275 | } __attribute__ ((packed)) ned; |
255 | struct { | 276 | struct { |
256 | unsigned char flags; /* byte 0 */ | 277 | unsigned char flags; /* byte 0 */ |
257 | unsigned char res2[7]; /* byte 1- 7 */ | 278 | unsigned char res1; /* byte 1 */ |
279 | __u16 format; /* byte 2-3 */ | ||
280 | unsigned char res2[4]; /* byte 4-7 */ | ||
258 | unsigned char sua_flags; /* byte 8 */ | 281 | unsigned char sua_flags; /* byte 8 */ |
259 | __u8 base_unit_addr; /* byte 9 */ | 282 | __u8 base_unit_addr; /* byte 9 */ |
260 | unsigned char res3[22]; /* byte 10-31 */ | 283 | unsigned char res3[22]; /* byte 10-31 */ |
@@ -343,6 +366,11 @@ struct dasd_eckd_path { | |||
343 | __u8 npm; | 366 | __u8 npm; |
344 | }; | 367 | }; |
345 | 368 | ||
369 | struct dasd_rssd_features { | ||
370 | char feature[256]; | ||
371 | } __attribute__((packed)); | ||
372 | |||
373 | |||
346 | /* | 374 | /* |
347 | * Perform Subsystem Function - Prepare for Read Subsystem Data | 375 | * Perform Subsystem Function - Prepare for Read Subsystem Data |
348 | */ | 376 | */ |
@@ -365,4 +393,99 @@ struct dasd_psf_ssc_data { | |||
365 | unsigned char reserved[59]; | 393 | unsigned char reserved[59]; |
366 | } __attribute__((packed)); | 394 | } __attribute__((packed)); |
367 | 395 | ||
396 | |||
397 | /* | ||
398 | * some structures and definitions for alias handling | ||
399 | */ | ||
400 | struct dasd_unit_address_configuration { | ||
401 | struct { | ||
402 | char ua_type; | ||
403 | char base_ua; | ||
404 | } unit[256]; | ||
405 | } __attribute__((packed)); | ||
406 | |||
407 | |||
408 | #define MAX_DEVICES_PER_LCU 256 | ||
409 | |||
410 | /* flags on the LCU */ | ||
411 | #define NEED_UAC_UPDATE 0x01 | ||
412 | #define UPDATE_PENDING 0x02 | ||
413 | |||
414 | enum pavtype {NO_PAV, BASE_PAV, HYPER_PAV}; | ||
415 | |||
416 | |||
417 | struct alias_root { | ||
418 | struct list_head serverlist; | ||
419 | spinlock_t lock; | ||
420 | }; | ||
421 | |||
422 | struct alias_server { | ||
423 | struct list_head server; | ||
424 | struct dasd_uid uid; | ||
425 | struct list_head lculist; | ||
426 | }; | ||
427 | |||
428 | struct summary_unit_check_work_data { | ||
429 | char reason; | ||
430 | struct dasd_device *device; | ||
431 | struct work_struct worker; | ||
432 | }; | ||
433 | |||
434 | struct read_uac_work_data { | ||
435 | struct dasd_device *device; | ||
436 | struct delayed_work dwork; | ||
437 | }; | ||
438 | |||
439 | struct alias_lcu { | ||
440 | struct list_head lcu; | ||
441 | struct dasd_uid uid; | ||
442 | enum pavtype pav; | ||
443 | char flags; | ||
444 | spinlock_t lock; | ||
445 | struct list_head grouplist; | ||
446 | struct list_head active_devices; | ||
447 | struct list_head inactive_devices; | ||
448 | struct dasd_unit_address_configuration *uac; | ||
449 | struct summary_unit_check_work_data suc_data; | ||
450 | struct read_uac_work_data ruac_data; | ||
451 | struct dasd_ccw_req *rsu_cqr; | ||
452 | }; | ||
453 | |||
454 | struct alias_pav_group { | ||
455 | struct list_head group; | ||
456 | struct dasd_uid uid; | ||
457 | struct alias_lcu *lcu; | ||
458 | struct list_head baselist; | ||
459 | struct list_head aliaslist; | ||
460 | struct dasd_device *next; | ||
461 | }; | ||
462 | |||
463 | |||
464 | struct dasd_eckd_private { | ||
465 | struct dasd_eckd_characteristics rdc_data; | ||
466 | struct dasd_eckd_confdata conf_data; | ||
467 | struct dasd_eckd_path path_data; | ||
468 | struct eckd_count count_area[5]; | ||
469 | int init_cqr_status; | ||
470 | int uses_cdl; | ||
471 | struct attrib_data_t attrib; /* e.g. cache operations */ | ||
472 | struct dasd_rssd_features features; | ||
473 | |||
474 | /* alias managemnet */ | ||
475 | struct dasd_uid uid; | ||
476 | struct alias_pav_group *pavgroup; | ||
477 | struct alias_lcu *lcu; | ||
478 | int count; | ||
479 | }; | ||
480 | |||
481 | |||
482 | |||
483 | int dasd_alias_make_device_known_to_lcu(struct dasd_device *); | ||
484 | void dasd_alias_disconnect_device_from_lcu(struct dasd_device *); | ||
485 | int dasd_alias_add_device(struct dasd_device *); | ||
486 | int dasd_alias_remove_device(struct dasd_device *); | ||
487 | struct dasd_device *dasd_alias_get_start_dev(struct dasd_device *); | ||
488 | void dasd_alias_handle_summary_unit_check(struct dasd_device *, struct irb *); | ||
489 | void dasd_eckd_reset_ccw_to_base_io(struct dasd_ccw_req *); | ||
490 | |||
368 | #endif /* DASD_ECKD_H */ | 491 | #endif /* DASD_ECKD_H */ |
diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c index 0c081a664ee8..6e53ab606e97 100644 --- a/drivers/s390/block/dasd_eer.c +++ b/drivers/s390/block/dasd_eer.c | |||
@@ -336,7 +336,7 @@ static void dasd_eer_write_snss_trigger(struct dasd_device *device, | |||
336 | unsigned long flags; | 336 | unsigned long flags; |
337 | struct eerbuffer *eerb; | 337 | struct eerbuffer *eerb; |
338 | 338 | ||
339 | snss_rc = (cqr->status == DASD_CQR_FAILED) ? -EIO : 0; | 339 | snss_rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO; |
340 | if (snss_rc) | 340 | if (snss_rc) |
341 | data_size = 0; | 341 | data_size = 0; |
342 | else | 342 | else |
@@ -404,10 +404,11 @@ void dasd_eer_snss(struct dasd_device *device) | |||
404 | set_bit(DASD_FLAG_EER_SNSS, &device->flags); | 404 | set_bit(DASD_FLAG_EER_SNSS, &device->flags); |
405 | return; | 405 | return; |
406 | } | 406 | } |
407 | /* cdev is already locked, can't use dasd_add_request_head */ | ||
407 | clear_bit(DASD_FLAG_EER_SNSS, &device->flags); | 408 | clear_bit(DASD_FLAG_EER_SNSS, &device->flags); |
408 | cqr->status = DASD_CQR_QUEUED; | 409 | cqr->status = DASD_CQR_QUEUED; |
409 | list_add(&cqr->list, &device->ccw_queue); | 410 | list_add(&cqr->devlist, &device->ccw_queue); |
410 | dasd_schedule_bh(device); | 411 | dasd_schedule_device_bh(device); |
411 | } | 412 | } |
412 | 413 | ||
413 | /* | 414 | /* |
@@ -415,7 +416,7 @@ void dasd_eer_snss(struct dasd_device *device) | |||
415 | */ | 416 | */ |
416 | static void dasd_eer_snss_cb(struct dasd_ccw_req *cqr, void *data) | 417 | static void dasd_eer_snss_cb(struct dasd_ccw_req *cqr, void *data) |
417 | { | 418 | { |
418 | struct dasd_device *device = cqr->device; | 419 | struct dasd_device *device = cqr->startdev; |
419 | unsigned long flags; | 420 | unsigned long flags; |
420 | 421 | ||
421 | dasd_eer_write(device, cqr, DASD_EER_STATECHANGE); | 422 | dasd_eer_write(device, cqr, DASD_EER_STATECHANGE); |
@@ -458,7 +459,7 @@ int dasd_eer_enable(struct dasd_device *device) | |||
458 | if (!cqr) | 459 | if (!cqr) |
459 | return -ENOMEM; | 460 | return -ENOMEM; |
460 | 461 | ||
461 | cqr->device = device; | 462 | cqr->startdev = device; |
462 | cqr->retries = 255; | 463 | cqr->retries = 255; |
463 | cqr->expires = 10 * HZ; | 464 | cqr->expires = 10 * HZ; |
464 | clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); | 465 | clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); |
diff --git a/drivers/s390/block/dasd_erp.c b/drivers/s390/block/dasd_erp.c index caa5d91420f8..8f10000851a3 100644 --- a/drivers/s390/block/dasd_erp.c +++ b/drivers/s390/block/dasd_erp.c | |||
@@ -46,6 +46,8 @@ dasd_alloc_erp_request(char *magic, int cplength, int datasize, | |||
46 | if (cqr == NULL) | 46 | if (cqr == NULL) |
47 | return ERR_PTR(-ENOMEM); | 47 | return ERR_PTR(-ENOMEM); |
48 | memset(cqr, 0, sizeof(struct dasd_ccw_req)); | 48 | memset(cqr, 0, sizeof(struct dasd_ccw_req)); |
49 | INIT_LIST_HEAD(&cqr->devlist); | ||
50 | INIT_LIST_HEAD(&cqr->blocklist); | ||
49 | data = (char *) cqr + ((sizeof(struct dasd_ccw_req) + 7L) & -8L); | 51 | data = (char *) cqr + ((sizeof(struct dasd_ccw_req) + 7L) & -8L); |
50 | cqr->cpaddr = NULL; | 52 | cqr->cpaddr = NULL; |
51 | if (cplength > 0) { | 53 | if (cplength > 0) { |
@@ -66,7 +68,7 @@ dasd_alloc_erp_request(char *magic, int cplength, int datasize, | |||
66 | } | 68 | } |
67 | 69 | ||
68 | void | 70 | void |
69 | dasd_free_erp_request(struct dasd_ccw_req * cqr, struct dasd_device * device) | 71 | dasd_free_erp_request(struct dasd_ccw_req *cqr, struct dasd_device * device) |
70 | { | 72 | { |
71 | unsigned long flags; | 73 | unsigned long flags; |
72 | 74 | ||
@@ -81,11 +83,11 @@ dasd_free_erp_request(struct dasd_ccw_req * cqr, struct dasd_device * device) | |||
81 | * dasd_default_erp_action just retries the current cqr | 83 | * dasd_default_erp_action just retries the current cqr |
82 | */ | 84 | */ |
83 | struct dasd_ccw_req * | 85 | struct dasd_ccw_req * |
84 | dasd_default_erp_action(struct dasd_ccw_req * cqr) | 86 | dasd_default_erp_action(struct dasd_ccw_req *cqr) |
85 | { | 87 | { |
86 | struct dasd_device *device; | 88 | struct dasd_device *device; |
87 | 89 | ||
88 | device = cqr->device; | 90 | device = cqr->startdev; |
89 | 91 | ||
90 | /* just retry - there is nothing to save ... I got no sense data.... */ | 92 | /* just retry - there is nothing to save ... I got no sense data.... */ |
91 | if (cqr->retries > 0) { | 93 | if (cqr->retries > 0) { |
@@ -93,12 +95,12 @@ dasd_default_erp_action(struct dasd_ccw_req * cqr) | |||
93 | "default ERP called (%i retries left)", | 95 | "default ERP called (%i retries left)", |
94 | cqr->retries); | 96 | cqr->retries); |
95 | cqr->lpm = LPM_ANYPATH; | 97 | cqr->lpm = LPM_ANYPATH; |
96 | cqr->status = DASD_CQR_QUEUED; | 98 | cqr->status = DASD_CQR_FILLED; |
97 | } else { | 99 | } else { |
98 | DEV_MESSAGE (KERN_WARNING, device, "%s", | 100 | DEV_MESSAGE (KERN_WARNING, device, "%s", |
99 | "default ERP called (NO retry left)"); | 101 | "default ERP called (NO retry left)"); |
100 | cqr->status = DASD_CQR_FAILED; | 102 | cqr->status = DASD_CQR_FAILED; |
101 | cqr->stopclk = get_clock (); | 103 | cqr->stopclk = get_clock(); |
102 | } | 104 | } |
103 | return cqr; | 105 | return cqr; |
104 | } /* end dasd_default_erp_action */ | 106 | } /* end dasd_default_erp_action */ |
@@ -117,15 +119,12 @@ dasd_default_erp_action(struct dasd_ccw_req * cqr) | |||
117 | * RETURN VALUES | 119 | * RETURN VALUES |
118 | * cqr pointer to the original CQR | 120 | * cqr pointer to the original CQR |
119 | */ | 121 | */ |
120 | struct dasd_ccw_req * | 122 | struct dasd_ccw_req *dasd_default_erp_postaction(struct dasd_ccw_req *cqr) |
121 | dasd_default_erp_postaction(struct dasd_ccw_req * cqr) | ||
122 | { | 123 | { |
123 | struct dasd_device *device; | ||
124 | int success; | 124 | int success; |
125 | 125 | ||
126 | BUG_ON(cqr->refers == NULL || cqr->function == NULL); | 126 | BUG_ON(cqr->refers == NULL || cqr->function == NULL); |
127 | 127 | ||
128 | device = cqr->device; | ||
129 | success = cqr->status == DASD_CQR_DONE; | 128 | success = cqr->status == DASD_CQR_DONE; |
130 | 129 | ||
131 | /* free all ERPs - but NOT the original cqr */ | 130 | /* free all ERPs - but NOT the original cqr */ |
@@ -133,10 +132,10 @@ dasd_default_erp_postaction(struct dasd_ccw_req * cqr) | |||
133 | struct dasd_ccw_req *refers; | 132 | struct dasd_ccw_req *refers; |
134 | 133 | ||
135 | refers = cqr->refers; | 134 | refers = cqr->refers; |
136 | /* remove the request from the device queue */ | 135 | /* remove the request from the block queue */ |
137 | list_del(&cqr->list); | 136 | list_del(&cqr->blocklist); |
138 | /* free the finished erp request */ | 137 | /* free the finished erp request */ |
139 | dasd_free_erp_request(cqr, device); | 138 | dasd_free_erp_request(cqr, cqr->memdev); |
140 | cqr = refers; | 139 | cqr = refers; |
141 | } | 140 | } |
142 | 141 | ||
@@ -157,7 +156,7 @@ dasd_log_sense(struct dasd_ccw_req *cqr, struct irb *irb) | |||
157 | { | 156 | { |
158 | struct dasd_device *device; | 157 | struct dasd_device *device; |
159 | 158 | ||
160 | device = cqr->device; | 159 | device = cqr->startdev; |
161 | /* dump sense data */ | 160 | /* dump sense data */ |
162 | if (device->discipline && device->discipline->dump_sense) | 161 | if (device->discipline && device->discipline->dump_sense) |
163 | device->discipline->dump_sense(device, cqr, irb); | 162 | device->discipline->dump_sense(device, cqr, irb); |
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c index 1d95822e0b8e..d13ea05089a7 100644 --- a/drivers/s390/block/dasd_fba.c +++ b/drivers/s390/block/dasd_fba.c | |||
@@ -117,6 +117,7 @@ locate_record(struct ccw1 * ccw, struct LO_fba_data *data, int rw, | |||
117 | static int | 117 | static int |
118 | dasd_fba_check_characteristics(struct dasd_device *device) | 118 | dasd_fba_check_characteristics(struct dasd_device *device) |
119 | { | 119 | { |
120 | struct dasd_block *block; | ||
120 | struct dasd_fba_private *private; | 121 | struct dasd_fba_private *private; |
121 | struct ccw_device *cdev = device->cdev; | 122 | struct ccw_device *cdev = device->cdev; |
122 | void *rdc_data; | 123 | void *rdc_data; |
@@ -133,6 +134,16 @@ dasd_fba_check_characteristics(struct dasd_device *device) | |||
133 | } | 134 | } |
134 | device->private = (void *) private; | 135 | device->private = (void *) private; |
135 | } | 136 | } |
137 | block = dasd_alloc_block(); | ||
138 | if (IS_ERR(block)) { | ||
139 | DEV_MESSAGE(KERN_WARNING, device, "%s", | ||
140 | "could not allocate dasd block structure"); | ||
141 | kfree(device->private); | ||
142 | return PTR_ERR(block); | ||
143 | } | ||
144 | device->block = block; | ||
145 | block->base = device; | ||
146 | |||
136 | /* Read Device Characteristics */ | 147 | /* Read Device Characteristics */ |
137 | rdc_data = (void *) &(private->rdc_data); | 148 | rdc_data = (void *) &(private->rdc_data); |
138 | rc = dasd_generic_read_dev_chars(device, "FBA ", &rdc_data, 32); | 149 | rc = dasd_generic_read_dev_chars(device, "FBA ", &rdc_data, 32); |
@@ -155,60 +166,37 @@ dasd_fba_check_characteristics(struct dasd_device *device) | |||
155 | return 0; | 166 | return 0; |
156 | } | 167 | } |
157 | 168 | ||
158 | static int | 169 | static int dasd_fba_do_analysis(struct dasd_block *block) |
159 | dasd_fba_do_analysis(struct dasd_device *device) | ||
160 | { | 170 | { |
161 | struct dasd_fba_private *private; | 171 | struct dasd_fba_private *private; |
162 | int sb, rc; | 172 | int sb, rc; |
163 | 173 | ||
164 | private = (struct dasd_fba_private *) device->private; | 174 | private = (struct dasd_fba_private *) block->base->private; |
165 | rc = dasd_check_blocksize(private->rdc_data.blk_size); | 175 | rc = dasd_check_blocksize(private->rdc_data.blk_size); |
166 | if (rc) { | 176 | if (rc) { |
167 | DEV_MESSAGE(KERN_INFO, device, "unknown blocksize %d", | 177 | DEV_MESSAGE(KERN_INFO, block->base, "unknown blocksize %d", |
168 | private->rdc_data.blk_size); | 178 | private->rdc_data.blk_size); |
169 | return rc; | 179 | return rc; |
170 | } | 180 | } |
171 | device->blocks = private->rdc_data.blk_bdsa; | 181 | block->blocks = private->rdc_data.blk_bdsa; |
172 | device->bp_block = private->rdc_data.blk_size; | 182 | block->bp_block = private->rdc_data.blk_size; |
173 | device->s2b_shift = 0; /* bits to shift 512 to get a block */ | 183 | block->s2b_shift = 0; /* bits to shift 512 to get a block */ |
174 | for (sb = 512; sb < private->rdc_data.blk_size; sb = sb << 1) | 184 | for (sb = 512; sb < private->rdc_data.blk_size; sb = sb << 1) |
175 | device->s2b_shift++; | 185 | block->s2b_shift++; |
176 | return 0; | 186 | return 0; |
177 | } | 187 | } |
178 | 188 | ||
179 | static int | 189 | static int dasd_fba_fill_geometry(struct dasd_block *block, |
180 | dasd_fba_fill_geometry(struct dasd_device *device, struct hd_geometry *geo) | 190 | struct hd_geometry *geo) |
181 | { | 191 | { |
182 | if (dasd_check_blocksize(device->bp_block) != 0) | 192 | if (dasd_check_blocksize(block->bp_block) != 0) |
183 | return -EINVAL; | 193 | return -EINVAL; |
184 | geo->cylinders = (device->blocks << device->s2b_shift) >> 10; | 194 | geo->cylinders = (block->blocks << block->s2b_shift) >> 10; |
185 | geo->heads = 16; | 195 | geo->heads = 16; |
186 | geo->sectors = 128 >> device->s2b_shift; | 196 | geo->sectors = 128 >> block->s2b_shift; |
187 | return 0; | 197 | return 0; |
188 | } | 198 | } |
189 | 199 | ||
190 | static dasd_era_t | ||
191 | dasd_fba_examine_error(struct dasd_ccw_req * cqr, struct irb * irb) | ||
192 | { | ||
193 | struct dasd_device *device; | ||
194 | struct ccw_device *cdev; | ||
195 | |||
196 | device = (struct dasd_device *) cqr->device; | ||
197 | if (irb->scsw.cstat == 0x00 && | ||
198 | irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END)) | ||
199 | return dasd_era_none; | ||
200 | |||
201 | cdev = device->cdev; | ||
202 | switch (cdev->id.dev_type) { | ||
203 | case 0x3370: | ||
204 | return dasd_3370_erp_examine(cqr, irb); | ||
205 | case 0x9336: | ||
206 | return dasd_9336_erp_examine(cqr, irb); | ||
207 | default: | ||
208 | return dasd_era_recover; | ||
209 | } | ||
210 | } | ||
211 | |||
212 | static dasd_erp_fn_t | 200 | static dasd_erp_fn_t |
213 | dasd_fba_erp_action(struct dasd_ccw_req * cqr) | 201 | dasd_fba_erp_action(struct dasd_ccw_req * cqr) |
214 | { | 202 | { |
@@ -221,13 +209,34 @@ dasd_fba_erp_postaction(struct dasd_ccw_req * cqr) | |||
221 | if (cqr->function == dasd_default_erp_action) | 209 | if (cqr->function == dasd_default_erp_action) |
222 | return dasd_default_erp_postaction; | 210 | return dasd_default_erp_postaction; |
223 | 211 | ||
224 | DEV_MESSAGE(KERN_WARNING, cqr->device, "unknown ERP action %p", | 212 | DEV_MESSAGE(KERN_WARNING, cqr->startdev, "unknown ERP action %p", |
225 | cqr->function); | 213 | cqr->function); |
226 | return NULL; | 214 | return NULL; |
227 | } | 215 | } |
228 | 216 | ||
229 | static struct dasd_ccw_req * | 217 | static void dasd_fba_handle_unsolicited_interrupt(struct dasd_device *device, |
230 | dasd_fba_build_cp(struct dasd_device * device, struct request *req) | 218 | struct irb *irb) |
219 | { | ||
220 | char mask; | ||
221 | |||
222 | /* first of all check for state change pending interrupt */ | ||
223 | mask = DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP; | ||
224 | if ((irb->scsw.dstat & mask) == mask) { | ||
225 | dasd_generic_handle_state_change(device); | ||
226 | return; | ||
227 | } | ||
228 | |||
229 | /* check for unsolicited interrupts */ | ||
230 | DEV_MESSAGE(KERN_DEBUG, device, "%s", | ||
231 | "unsolicited interrupt received"); | ||
232 | device->discipline->dump_sense(device, NULL, irb); | ||
233 | dasd_schedule_device_bh(device); | ||
234 | return; | ||
235 | }; | ||
236 | |||
237 | static struct dasd_ccw_req *dasd_fba_build_cp(struct dasd_device * memdev, | ||
238 | struct dasd_block *block, | ||
239 | struct request *req) | ||
231 | { | 240 | { |
232 | struct dasd_fba_private *private; | 241 | struct dasd_fba_private *private; |
233 | unsigned long *idaws; | 242 | unsigned long *idaws; |
@@ -242,17 +251,17 @@ dasd_fba_build_cp(struct dasd_device * device, struct request *req) | |||
242 | unsigned int blksize, off; | 251 | unsigned int blksize, off; |
243 | unsigned char cmd; | 252 | unsigned char cmd; |
244 | 253 | ||
245 | private = (struct dasd_fba_private *) device->private; | 254 | private = (struct dasd_fba_private *) block->base->private; |
246 | if (rq_data_dir(req) == READ) { | 255 | if (rq_data_dir(req) == READ) { |
247 | cmd = DASD_FBA_CCW_READ; | 256 | cmd = DASD_FBA_CCW_READ; |
248 | } else if (rq_data_dir(req) == WRITE) { | 257 | } else if (rq_data_dir(req) == WRITE) { |
249 | cmd = DASD_FBA_CCW_WRITE; | 258 | cmd = DASD_FBA_CCW_WRITE; |
250 | } else | 259 | } else |
251 | return ERR_PTR(-EINVAL); | 260 | return ERR_PTR(-EINVAL); |
252 | blksize = device->bp_block; | 261 | blksize = block->bp_block; |
253 | /* Calculate record id of first and last block. */ | 262 | /* Calculate record id of first and last block. */ |
254 | first_rec = req->sector >> device->s2b_shift; | 263 | first_rec = req->sector >> block->s2b_shift; |
255 | last_rec = (req->sector + req->nr_sectors - 1) >> device->s2b_shift; | 264 | last_rec = (req->sector + req->nr_sectors - 1) >> block->s2b_shift; |
256 | /* Check struct bio and count the number of blocks for the request. */ | 265 | /* Check struct bio and count the number of blocks for the request. */ |
257 | count = 0; | 266 | count = 0; |
258 | cidaw = 0; | 267 | cidaw = 0; |
@@ -260,7 +269,7 @@ dasd_fba_build_cp(struct dasd_device * device, struct request *req) | |||
260 | if (bv->bv_len & (blksize - 1)) | 269 | if (bv->bv_len & (blksize - 1)) |
261 | /* Fba can only do full blocks. */ | 270 | /* Fba can only do full blocks. */ |
262 | return ERR_PTR(-EINVAL); | 271 | return ERR_PTR(-EINVAL); |
263 | count += bv->bv_len >> (device->s2b_shift + 9); | 272 | count += bv->bv_len >> (block->s2b_shift + 9); |
264 | #if defined(CONFIG_64BIT) | 273 | #if defined(CONFIG_64BIT) |
265 | if (idal_is_needed (page_address(bv->bv_page), bv->bv_len)) | 274 | if (idal_is_needed (page_address(bv->bv_page), bv->bv_len)) |
266 | cidaw += bv->bv_len / blksize; | 275 | cidaw += bv->bv_len / blksize; |
@@ -284,13 +293,13 @@ dasd_fba_build_cp(struct dasd_device * device, struct request *req) | |||
284 | } | 293 | } |
285 | /* Allocate the ccw request. */ | 294 | /* Allocate the ccw request. */ |
286 | cqr = dasd_smalloc_request(dasd_fba_discipline.name, | 295 | cqr = dasd_smalloc_request(dasd_fba_discipline.name, |
287 | cplength, datasize, device); | 296 | cplength, datasize, memdev); |
288 | if (IS_ERR(cqr)) | 297 | if (IS_ERR(cqr)) |
289 | return cqr; | 298 | return cqr; |
290 | ccw = cqr->cpaddr; | 299 | ccw = cqr->cpaddr; |
291 | /* First ccw is define extent. */ | 300 | /* First ccw is define extent. */ |
292 | define_extent(ccw++, cqr->data, rq_data_dir(req), | 301 | define_extent(ccw++, cqr->data, rq_data_dir(req), |
293 | device->bp_block, req->sector, req->nr_sectors); | 302 | block->bp_block, req->sector, req->nr_sectors); |
294 | /* Build locate_record + read/write ccws. */ | 303 | /* Build locate_record + read/write ccws. */ |
295 | idaws = (unsigned long *) (cqr->data + sizeof(struct DE_fba_data)); | 304 | idaws = (unsigned long *) (cqr->data + sizeof(struct DE_fba_data)); |
296 | LO_data = (struct LO_fba_data *) (idaws + cidaw); | 305 | LO_data = (struct LO_fba_data *) (idaws + cidaw); |
@@ -326,7 +335,7 @@ dasd_fba_build_cp(struct dasd_device * device, struct request *req) | |||
326 | ccw[-1].flags |= CCW_FLAG_CC; | 335 | ccw[-1].flags |= CCW_FLAG_CC; |
327 | } | 336 | } |
328 | ccw->cmd_code = cmd; | 337 | ccw->cmd_code = cmd; |
329 | ccw->count = device->bp_block; | 338 | ccw->count = block->bp_block; |
330 | if (idal_is_needed(dst, blksize)) { | 339 | if (idal_is_needed(dst, blksize)) { |
331 | ccw->cda = (__u32)(addr_t) idaws; | 340 | ccw->cda = (__u32)(addr_t) idaws; |
332 | ccw->flags = CCW_FLAG_IDA; | 341 | ccw->flags = CCW_FLAG_IDA; |
@@ -342,7 +351,9 @@ dasd_fba_build_cp(struct dasd_device * device, struct request *req) | |||
342 | } | 351 | } |
343 | if (req->cmd_flags & REQ_FAILFAST) | 352 | if (req->cmd_flags & REQ_FAILFAST) |
344 | set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); | 353 | set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); |
345 | cqr->device = device; | 354 | cqr->startdev = memdev; |
355 | cqr->memdev = memdev; | ||
356 | cqr->block = block; | ||
346 | cqr->expires = 5 * 60 * HZ; /* 5 minutes */ | 357 | cqr->expires = 5 * 60 * HZ; /* 5 minutes */ |
347 | cqr->retries = 32; | 358 | cqr->retries = 32; |
348 | cqr->buildclk = get_clock(); | 359 | cqr->buildclk = get_clock(); |
@@ -363,8 +374,8 @@ dasd_fba_free_cp(struct dasd_ccw_req *cqr, struct request *req) | |||
363 | 374 | ||
364 | if (!dasd_page_cache) | 375 | if (!dasd_page_cache) |
365 | goto out; | 376 | goto out; |
366 | private = (struct dasd_fba_private *) cqr->device->private; | 377 | private = (struct dasd_fba_private *) cqr->block->base->private; |
367 | blksize = cqr->device->bp_block; | 378 | blksize = cqr->block->bp_block; |
368 | ccw = cqr->cpaddr; | 379 | ccw = cqr->cpaddr; |
369 | /* Skip over define extent & locate record. */ | 380 | /* Skip over define extent & locate record. */ |
370 | ccw++; | 381 | ccw++; |
@@ -394,10 +405,15 @@ dasd_fba_free_cp(struct dasd_ccw_req *cqr, struct request *req) | |||
394 | } | 405 | } |
395 | out: | 406 | out: |
396 | status = cqr->status == DASD_CQR_DONE; | 407 | status = cqr->status == DASD_CQR_DONE; |
397 | dasd_sfree_request(cqr, cqr->device); | 408 | dasd_sfree_request(cqr, cqr->memdev); |
398 | return status; | 409 | return status; |
399 | } | 410 | } |
400 | 411 | ||
412 | static void dasd_fba_handle_terminated_request(struct dasd_ccw_req *cqr) | ||
413 | { | ||
414 | cqr->status = DASD_CQR_FILLED; | ||
415 | }; | ||
416 | |||
401 | static int | 417 | static int |
402 | dasd_fba_fill_info(struct dasd_device * device, | 418 | dasd_fba_fill_info(struct dasd_device * device, |
403 | struct dasd_information2_t * info) | 419 | struct dasd_information2_t * info) |
@@ -546,9 +562,10 @@ static struct dasd_discipline dasd_fba_discipline = { | |||
546 | .fill_geometry = dasd_fba_fill_geometry, | 562 | .fill_geometry = dasd_fba_fill_geometry, |
547 | .start_IO = dasd_start_IO, | 563 | .start_IO = dasd_start_IO, |
548 | .term_IO = dasd_term_IO, | 564 | .term_IO = dasd_term_IO, |
549 | .examine_error = dasd_fba_examine_error, | 565 | .handle_terminated_request = dasd_fba_handle_terminated_request, |
550 | .erp_action = dasd_fba_erp_action, | 566 | .erp_action = dasd_fba_erp_action, |
551 | .erp_postaction = dasd_fba_erp_postaction, | 567 | .erp_postaction = dasd_fba_erp_postaction, |
568 | .handle_unsolicited_interrupt = dasd_fba_handle_unsolicited_interrupt, | ||
552 | .build_cp = dasd_fba_build_cp, | 569 | .build_cp = dasd_fba_build_cp, |
553 | .free_cp = dasd_fba_free_cp, | 570 | .free_cp = dasd_fba_free_cp, |
554 | .dump_sense = dasd_fba_dump_sense, | 571 | .dump_sense = dasd_fba_dump_sense, |
diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c index 47ba4462708d..aee6565aaf98 100644 --- a/drivers/s390/block/dasd_genhd.c +++ b/drivers/s390/block/dasd_genhd.c | |||
@@ -25,14 +25,15 @@ | |||
25 | /* | 25 | /* |
26 | * Allocate and register gendisk structure for device. | 26 | * Allocate and register gendisk structure for device. |
27 | */ | 27 | */ |
28 | int | 28 | int dasd_gendisk_alloc(struct dasd_block *block) |
29 | dasd_gendisk_alloc(struct dasd_device *device) | ||
30 | { | 29 | { |
31 | struct gendisk *gdp; | 30 | struct gendisk *gdp; |
31 | struct dasd_device *base; | ||
32 | int len; | 32 | int len; |
33 | 33 | ||
34 | /* Make sure the minor for this device exists. */ | 34 | /* Make sure the minor for this device exists. */ |
35 | if (device->devindex >= DASD_PER_MAJOR) | 35 | base = block->base; |
36 | if (base->devindex >= DASD_PER_MAJOR) | ||
36 | return -EBUSY; | 37 | return -EBUSY; |
37 | 38 | ||
38 | gdp = alloc_disk(1 << DASD_PARTN_BITS); | 39 | gdp = alloc_disk(1 << DASD_PARTN_BITS); |
@@ -41,9 +42,9 @@ dasd_gendisk_alloc(struct dasd_device *device) | |||
41 | 42 | ||
42 | /* Initialize gendisk structure. */ | 43 | /* Initialize gendisk structure. */ |
43 | gdp->major = DASD_MAJOR; | 44 | gdp->major = DASD_MAJOR; |
44 | gdp->first_minor = device->devindex << DASD_PARTN_BITS; | 45 | gdp->first_minor = base->devindex << DASD_PARTN_BITS; |
45 | gdp->fops = &dasd_device_operations; | 46 | gdp->fops = &dasd_device_operations; |
46 | gdp->driverfs_dev = &device->cdev->dev; | 47 | gdp->driverfs_dev = &base->cdev->dev; |
47 | 48 | ||
48 | /* | 49 | /* |
49 | * Set device name. | 50 | * Set device name. |
@@ -53,53 +54,51 @@ dasd_gendisk_alloc(struct dasd_device *device) | |||
53 | * dasdaaaa - dasdzzzz : 456976 devices, added up = 475252 | 54 | * dasdaaaa - dasdzzzz : 456976 devices, added up = 475252 |
54 | */ | 55 | */ |
55 | len = sprintf(gdp->disk_name, "dasd"); | 56 | len = sprintf(gdp->disk_name, "dasd"); |
56 | if (device->devindex > 25) { | 57 | if (base->devindex > 25) { |
57 | if (device->devindex > 701) { | 58 | if (base->devindex > 701) { |
58 | if (device->devindex > 18277) | 59 | if (base->devindex > 18277) |
59 | len += sprintf(gdp->disk_name + len, "%c", | 60 | len += sprintf(gdp->disk_name + len, "%c", |
60 | 'a'+(((device->devindex-18278) | 61 | 'a'+(((base->devindex-18278) |
61 | /17576)%26)); | 62 | /17576)%26)); |
62 | len += sprintf(gdp->disk_name + len, "%c", | 63 | len += sprintf(gdp->disk_name + len, "%c", |
63 | 'a'+(((device->devindex-702)/676)%26)); | 64 | 'a'+(((base->devindex-702)/676)%26)); |
64 | } | 65 | } |
65 | len += sprintf(gdp->disk_name + len, "%c", | 66 | len += sprintf(gdp->disk_name + len, "%c", |
66 | 'a'+(((device->devindex-26)/26)%26)); | 67 | 'a'+(((base->devindex-26)/26)%26)); |
67 | } | 68 | } |
68 | len += sprintf(gdp->disk_name + len, "%c", 'a'+(device->devindex%26)); | 69 | len += sprintf(gdp->disk_name + len, "%c", 'a'+(base->devindex%26)); |
69 | 70 | ||
70 | if (device->features & DASD_FEATURE_READONLY) | 71 | if (block->base->features & DASD_FEATURE_READONLY) |
71 | set_disk_ro(gdp, 1); | 72 | set_disk_ro(gdp, 1); |
72 | gdp->private_data = device; | 73 | gdp->private_data = block; |
73 | gdp->queue = device->request_queue; | 74 | gdp->queue = block->request_queue; |
74 | device->gdp = gdp; | 75 | block->gdp = gdp; |
75 | set_capacity(device->gdp, 0); | 76 | set_capacity(block->gdp, 0); |
76 | add_disk(device->gdp); | 77 | add_disk(block->gdp); |
77 | return 0; | 78 | return 0; |
78 | } | 79 | } |
79 | 80 | ||
80 | /* | 81 | /* |
81 | * Unregister and free gendisk structure for device. | 82 | * Unregister and free gendisk structure for device. |
82 | */ | 83 | */ |
83 | void | 84 | void dasd_gendisk_free(struct dasd_block *block) |
84 | dasd_gendisk_free(struct dasd_device *device) | ||
85 | { | 85 | { |
86 | if (device->gdp) { | 86 | if (block->gdp) { |
87 | del_gendisk(device->gdp); | 87 | del_gendisk(block->gdp); |
88 | device->gdp->queue = NULL; | 88 | block->gdp->queue = NULL; |
89 | put_disk(device->gdp); | 89 | put_disk(block->gdp); |
90 | device->gdp = NULL; | 90 | block->gdp = NULL; |
91 | } | 91 | } |
92 | } | 92 | } |
93 | 93 | ||
94 | /* | 94 | /* |
95 | * Trigger a partition detection. | 95 | * Trigger a partition detection. |
96 | */ | 96 | */ |
97 | int | 97 | int dasd_scan_partitions(struct dasd_block *block) |
98 | dasd_scan_partitions(struct dasd_device * device) | ||
99 | { | 98 | { |
100 | struct block_device *bdev; | 99 | struct block_device *bdev; |
101 | 100 | ||
102 | bdev = bdget_disk(device->gdp, 0); | 101 | bdev = bdget_disk(block->gdp, 0); |
103 | if (!bdev || blkdev_get(bdev, FMODE_READ, 1) < 0) | 102 | if (!bdev || blkdev_get(bdev, FMODE_READ, 1) < 0) |
104 | return -ENODEV; | 103 | return -ENODEV; |
105 | /* | 104 | /* |
@@ -117,7 +116,7 @@ dasd_scan_partitions(struct dasd_device * device) | |||
117 | * is why the assignment to device->bdev is done AFTER | 116 | * is why the assignment to device->bdev is done AFTER |
118 | * the BLKRRPART ioctl. | 117 | * the BLKRRPART ioctl. |
119 | */ | 118 | */ |
120 | device->bdev = bdev; | 119 | block->bdev = bdev; |
121 | return 0; | 120 | return 0; |
122 | } | 121 | } |
123 | 122 | ||
@@ -125,8 +124,7 @@ dasd_scan_partitions(struct dasd_device * device) | |||
125 | * Remove all inodes in the system for a device, delete the | 124 | * Remove all inodes in the system for a device, delete the |
126 | * partitions and make device unusable by setting its size to zero. | 125 | * partitions and make device unusable by setting its size to zero. |
127 | */ | 126 | */ |
128 | void | 127 | void dasd_destroy_partitions(struct dasd_block *block) |
129 | dasd_destroy_partitions(struct dasd_device * device) | ||
130 | { | 128 | { |
131 | /* The two structs have 168/176 byte on 31/64 bit. */ | 129 | /* The two structs have 168/176 byte on 31/64 bit. */ |
132 | struct blkpg_partition bpart; | 130 | struct blkpg_partition bpart; |
@@ -137,8 +135,8 @@ dasd_destroy_partitions(struct dasd_device * device) | |||
137 | * Get the bdev pointer from the device structure and clear | 135 | * Get the bdev pointer from the device structure and clear |
138 | * device->bdev to lower the offline open_count limit again. | 136 | * device->bdev to lower the offline open_count limit again. |
139 | */ | 137 | */ |
140 | bdev = device->bdev; | 138 | bdev = block->bdev; |
141 | device->bdev = NULL; | 139 | block->bdev = NULL; |
142 | 140 | ||
143 | /* | 141 | /* |
144 | * See fs/partition/check.c:delete_partition | 142 | * See fs/partition/check.c:delete_partition |
@@ -149,17 +147,16 @@ dasd_destroy_partitions(struct dasd_device * device) | |||
149 | memset(&barg, 0, sizeof(struct blkpg_ioctl_arg)); | 147 | memset(&barg, 0, sizeof(struct blkpg_ioctl_arg)); |
150 | barg.data = (void __force __user *) &bpart; | 148 | barg.data = (void __force __user *) &bpart; |
151 | barg.op = BLKPG_DEL_PARTITION; | 149 | barg.op = BLKPG_DEL_PARTITION; |
152 | for (bpart.pno = device->gdp->minors - 1; bpart.pno > 0; bpart.pno--) | 150 | for (bpart.pno = block->gdp->minors - 1; bpart.pno > 0; bpart.pno--) |
153 | ioctl_by_bdev(bdev, BLKPG, (unsigned long) &barg); | 151 | ioctl_by_bdev(bdev, BLKPG, (unsigned long) &barg); |
154 | 152 | ||
155 | invalidate_partition(device->gdp, 0); | 153 | invalidate_partition(block->gdp, 0); |
156 | /* Matching blkdev_put to the blkdev_get in dasd_scan_partitions. */ | 154 | /* Matching blkdev_put to the blkdev_get in dasd_scan_partitions. */ |
157 | blkdev_put(bdev); | 155 | blkdev_put(bdev); |
158 | set_capacity(device->gdp, 0); | 156 | set_capacity(block->gdp, 0); |
159 | } | 157 | } |
160 | 158 | ||
161 | int | 159 | int dasd_gendisk_init(void) |
162 | dasd_gendisk_init(void) | ||
163 | { | 160 | { |
164 | int rc; | 161 | int rc; |
165 | 162 | ||
@@ -174,8 +171,7 @@ dasd_gendisk_init(void) | |||
174 | return 0; | 171 | return 0; |
175 | } | 172 | } |
176 | 173 | ||
177 | void | 174 | void dasd_gendisk_exit(void) |
178 | dasd_gendisk_exit(void) | ||
179 | { | 175 | { |
180 | unregister_blkdev(DASD_MAJOR, "dasd"); | 176 | unregister_blkdev(DASD_MAJOR, "dasd"); |
181 | } | 177 | } |
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index d427daeef511..44b2984dfbee 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h | |||
@@ -64,13 +64,7 @@ | |||
64 | * SECTION: Type definitions | 64 | * SECTION: Type definitions |
65 | */ | 65 | */ |
66 | struct dasd_device; | 66 | struct dasd_device; |
67 | 67 | struct dasd_block; | |
68 | typedef enum { | ||
69 | dasd_era_fatal = -1, /* no chance to recover */ | ||
70 | dasd_era_none = 0, /* don't recover, everything alright */ | ||
71 | dasd_era_msg = 1, /* don't recover, just report... */ | ||
72 | dasd_era_recover = 2 /* recovery action recommended */ | ||
73 | } dasd_era_t; | ||
74 | 68 | ||
75 | /* BIT DEFINITIONS FOR SENSE DATA */ | 69 | /* BIT DEFINITIONS FOR SENSE DATA */ |
76 | #define DASD_SENSE_BIT_0 0x80 | 70 | #define DASD_SENSE_BIT_0 0x80 |
@@ -151,19 +145,22 @@ do { \ | |||
151 | 145 | ||
152 | struct dasd_ccw_req { | 146 | struct dasd_ccw_req { |
153 | unsigned int magic; /* Eye catcher */ | 147 | unsigned int magic; /* Eye catcher */ |
154 | struct list_head list; /* list_head for request queueing. */ | 148 | struct list_head devlist; /* for dasd_device request queue */ |
149 | struct list_head blocklist; /* for dasd_block request queue */ | ||
155 | 150 | ||
156 | /* Where to execute what... */ | 151 | /* Where to execute what... */ |
157 | struct dasd_device *device; /* device the request is for */ | 152 | struct dasd_block *block; /* the originating block device */ |
153 | struct dasd_device *memdev; /* the device used to allocate this */ | ||
154 | struct dasd_device *startdev; /* device the request is started on */ | ||
158 | struct ccw1 *cpaddr; /* address of channel program */ | 155 | struct ccw1 *cpaddr; /* address of channel program */ |
159 | char status; /* status of this request */ | 156 | char status; /* status of this request */ |
160 | short retries; /* A retry counter */ | 157 | short retries; /* A retry counter */ |
161 | unsigned long flags; /* flags of this request */ | 158 | unsigned long flags; /* flags of this request */ |
162 | 159 | ||
163 | /* ... and how */ | 160 | /* ... and how */ |
164 | unsigned long starttime; /* jiffies time of request start */ | 161 | unsigned long starttime; /* jiffies time of request start */ |
165 | int expires; /* expiration period in jiffies */ | 162 | int expires; /* expiration period in jiffies */ |
166 | char lpm; /* logical path mask */ | 163 | char lpm; /* logical path mask */ |
167 | void *data; /* pointer to data area */ | 164 | void *data; /* pointer to data area */ |
168 | 165 | ||
169 | /* these are important for recovering erroneous requests */ | 166 | /* these are important for recovering erroneous requests */ |
@@ -178,20 +175,27 @@ struct dasd_ccw_req { | |||
178 | unsigned long long endclk; /* TOD-clock of request termination */ | 175 | unsigned long long endclk; /* TOD-clock of request termination */ |
179 | 176 | ||
180 | /* Callback that is called after reaching final status. */ | 177 | /* Callback that is called after reaching final status. */ |
181 | void (*callback)(struct dasd_ccw_req *, void *data); | 178 | void (*callback)(struct dasd_ccw_req *, void *data); |
182 | void *callback_data; | 179 | void *callback_data; |
183 | }; | 180 | }; |
184 | 181 | ||
185 | /* | 182 | /* |
186 | * dasd_ccw_req -> status can be: | 183 | * dasd_ccw_req -> status can be: |
187 | */ | 184 | */ |
188 | #define DASD_CQR_FILLED 0x00 /* request is ready to be processed */ | 185 | #define DASD_CQR_FILLED 0x00 /* request is ready to be processed */ |
189 | #define DASD_CQR_QUEUED 0x01 /* request is queued to be processed */ | 186 | #define DASD_CQR_DONE 0x01 /* request is completed successfully */ |
190 | #define DASD_CQR_IN_IO 0x02 /* request is currently in IO */ | 187 | #define DASD_CQR_NEED_ERP 0x02 /* request needs recovery action */ |
191 | #define DASD_CQR_DONE 0x03 /* request is completed successfully */ | 188 | #define DASD_CQR_IN_ERP 0x03 /* request is in recovery */ |
192 | #define DASD_CQR_ERROR 0x04 /* request is completed with error */ | 189 | #define DASD_CQR_FAILED 0x04 /* request is finally failed */ |
193 | #define DASD_CQR_FAILED 0x05 /* request is finally failed */ | 190 | #define DASD_CQR_TERMINATED 0x05 /* request was stopped by driver */ |
194 | #define DASD_CQR_CLEAR 0x06 /* request is clear pending */ | 191 | |
192 | #define DASD_CQR_QUEUED 0x80 /* request is queued to be processed */ | ||
193 | #define DASD_CQR_IN_IO 0x81 /* request is currently in IO */ | ||
194 | #define DASD_CQR_ERROR 0x82 /* request is completed with error */ | ||
195 | #define DASD_CQR_CLEAR_PENDING 0x83 /* request is clear pending */ | ||
196 | #define DASD_CQR_CLEARED 0x84 /* request was cleared */ | ||
197 | #define DASD_CQR_SUCCESS 0x85 /* request was successfull */ | ||
198 | |||
195 | 199 | ||
196 | /* per dasd_ccw_req flags */ | 200 | /* per dasd_ccw_req flags */ |
197 | #define DASD_CQR_FLAGS_USE_ERP 0 /* use ERP for this request */ | 201 | #define DASD_CQR_FLAGS_USE_ERP 0 /* use ERP for this request */ |
@@ -214,52 +218,71 @@ struct dasd_discipline { | |||
214 | 218 | ||
215 | struct list_head list; /* used for list of disciplines */ | 219 | struct list_head list; /* used for list of disciplines */ |
216 | 220 | ||
217 | /* | 221 | /* |
218 | * Device recognition functions. check_device is used to verify | 222 | * Device recognition functions. check_device is used to verify |
219 | * the sense data and the information returned by read device | 223 | * the sense data and the information returned by read device |
220 | * characteristics. It returns 0 if the discipline can be used | 224 | * characteristics. It returns 0 if the discipline can be used |
221 | * for the device in question. | 225 | * for the device in question. uncheck_device is called during |
222 | * do_analysis is used in the step from device state "basic" to | 226 | * device shutdown to deregister a device from its discipline. |
223 | * state "accept". It returns 0 if the device can be made ready, | 227 | */ |
224 | * it returns -EMEDIUMTYPE if the device can't be made ready or | 228 | int (*check_device) (struct dasd_device *); |
225 | * -EAGAIN if do_analysis started a ccw that needs to complete | 229 | void (*uncheck_device) (struct dasd_device *); |
226 | * before the analysis may be repeated. | 230 | |
227 | */ | 231 | /* |
228 | int (*check_device)(struct dasd_device *); | 232 | * do_analysis is used in the step from device state "basic" to |
229 | int (*do_analysis) (struct dasd_device *); | 233 | * state "accept". It returns 0 if the device can be made ready, |
230 | 234 | * it returns -EMEDIUMTYPE if the device can't be made ready or | |
231 | /* | 235 | * -EAGAIN if do_analysis started a ccw that needs to complete |
232 | * Device operation functions. build_cp creates a ccw chain for | 236 | * before the analysis may be repeated. |
233 | * a block device request, start_io starts the request and | 237 | */ |
234 | * term_IO cancels it (e.g. in case of a timeout). format_device | 238 | int (*do_analysis) (struct dasd_block *); |
235 | * returns a ccw chain to be used to format the device. | 239 | |
236 | */ | 240 | /* |
241 | * Last things to do when a device is set online, and first things | ||
242 | * when it is set offline. | ||
243 | */ | ||
244 | int (*ready_to_online) (struct dasd_device *); | ||
245 | int (*online_to_ready) (struct dasd_device *); | ||
246 | |||
247 | /* | ||
248 | * Device operation functions. build_cp creates a ccw chain for | ||
249 | * a block device request, start_io starts the request and | ||
250 | * term_IO cancels it (e.g. in case of a timeout). format_device | ||
251 | * returns a ccw chain to be used to format the device. | ||
252 | * handle_terminated_request allows to examine a cqr and prepare | ||
253 | * it for retry. | ||
254 | */ | ||
237 | struct dasd_ccw_req *(*build_cp) (struct dasd_device *, | 255 | struct dasd_ccw_req *(*build_cp) (struct dasd_device *, |
256 | struct dasd_block *, | ||
238 | struct request *); | 257 | struct request *); |
239 | int (*start_IO) (struct dasd_ccw_req *); | 258 | int (*start_IO) (struct dasd_ccw_req *); |
240 | int (*term_IO) (struct dasd_ccw_req *); | 259 | int (*term_IO) (struct dasd_ccw_req *); |
260 | void (*handle_terminated_request) (struct dasd_ccw_req *); | ||
241 | struct dasd_ccw_req *(*format_device) (struct dasd_device *, | 261 | struct dasd_ccw_req *(*format_device) (struct dasd_device *, |
242 | struct format_data_t *); | 262 | struct format_data_t *); |
243 | int (*free_cp) (struct dasd_ccw_req *, struct request *); | 263 | int (*free_cp) (struct dasd_ccw_req *, struct request *); |
244 | /* | 264 | |
245 | * Error recovery functions. examine_error() returns a value that | 265 | /* |
246 | * indicates what to do for an error condition. If examine_error() | 266 | * Error recovery functions. examine_error() returns a value that |
267 | * indicates what to do for an error condition. If examine_error() | ||
247 | * returns 'dasd_era_recover' erp_action() is called to create a | 268 | * returns 'dasd_era_recover' erp_action() is called to create a |
248 | * special error recovery ccw. erp_postaction() is called after | 269 | * special error recovery ccw. erp_postaction() is called after |
249 | * an error recovery ccw has finished its execution. dump_sense | 270 | * an error recovery ccw has finished its execution. dump_sense |
250 | * is called for every error condition to print the sense data | 271 | * is called for every error condition to print the sense data |
251 | * to the console. | 272 | * to the console. |
252 | */ | 273 | */ |
253 | dasd_era_t(*examine_error) (struct dasd_ccw_req *, struct irb *); | ||
254 | dasd_erp_fn_t(*erp_action) (struct dasd_ccw_req *); | 274 | dasd_erp_fn_t(*erp_action) (struct dasd_ccw_req *); |
255 | dasd_erp_fn_t(*erp_postaction) (struct dasd_ccw_req *); | 275 | dasd_erp_fn_t(*erp_postaction) (struct dasd_ccw_req *); |
256 | void (*dump_sense) (struct dasd_device *, struct dasd_ccw_req *, | 276 | void (*dump_sense) (struct dasd_device *, struct dasd_ccw_req *, |
257 | struct irb *); | 277 | struct irb *); |
258 | 278 | ||
279 | void (*handle_unsolicited_interrupt) (struct dasd_device *, | ||
280 | struct irb *); | ||
281 | |||
259 | /* i/o control functions. */ | 282 | /* i/o control functions. */ |
260 | int (*fill_geometry) (struct dasd_device *, struct hd_geometry *); | 283 | int (*fill_geometry) (struct dasd_block *, struct hd_geometry *); |
261 | int (*fill_info) (struct dasd_device *, struct dasd_information2_t *); | 284 | int (*fill_info) (struct dasd_device *, struct dasd_information2_t *); |
262 | int (*ioctl) (struct dasd_device *, unsigned int, void __user *); | 285 | int (*ioctl) (struct dasd_block *, unsigned int, void __user *); |
263 | }; | 286 | }; |
264 | 287 | ||
265 | extern struct dasd_discipline *dasd_diag_discipline_pointer; | 288 | extern struct dasd_discipline *dasd_diag_discipline_pointer; |
@@ -267,12 +290,18 @@ extern struct dasd_discipline *dasd_diag_discipline_pointer; | |||
267 | /* | 290 | /* |
268 | * Unique identifier for dasd device. | 291 | * Unique identifier for dasd device. |
269 | */ | 292 | */ |
293 | #define UA_NOT_CONFIGURED 0x00 | ||
294 | #define UA_BASE_DEVICE 0x01 | ||
295 | #define UA_BASE_PAV_ALIAS 0x02 | ||
296 | #define UA_HYPER_PAV_ALIAS 0x03 | ||
297 | |||
270 | struct dasd_uid { | 298 | struct dasd_uid { |
271 | __u8 alias; | 299 | __u8 type; |
272 | char vendor[4]; | 300 | char vendor[4]; |
273 | char serial[15]; | 301 | char serial[15]; |
274 | __u16 ssid; | 302 | __u16 ssid; |
275 | __u8 unit_addr; | 303 | __u8 real_unit_addr; |
304 | __u8 base_unit_addr; | ||
276 | }; | 305 | }; |
277 | 306 | ||
278 | /* | 307 | /* |
@@ -293,14 +322,9 @@ struct dasd_uid { | |||
293 | 322 | ||
294 | struct dasd_device { | 323 | struct dasd_device { |
295 | /* Block device stuff. */ | 324 | /* Block device stuff. */ |
296 | struct gendisk *gdp; | 325 | struct dasd_block *block; |
297 | struct request_queue *request_queue; | 326 | |
298 | spinlock_t request_queue_lock; | ||
299 | struct block_device *bdev; | ||
300 | unsigned int devindex; | 327 | unsigned int devindex; |
301 | unsigned long blocks; /* size of volume in blocks */ | ||
302 | unsigned int bp_block; /* bytes per block */ | ||
303 | unsigned int s2b_shift; /* log2 (bp_block/512) */ | ||
304 | unsigned long flags; /* per device flags */ | 328 | unsigned long flags; /* per device flags */ |
305 | unsigned short features; /* copy of devmap-features (read-only!) */ | 329 | unsigned short features; /* copy of devmap-features (read-only!) */ |
306 | 330 | ||
@@ -316,9 +340,8 @@ struct dasd_device { | |||
316 | int state, target; | 340 | int state, target; |
317 | int stopped; /* device (ccw_device_start) was stopped */ | 341 | int stopped; /* device (ccw_device_start) was stopped */ |
318 | 342 | ||
319 | /* Open and reference count. */ | 343 | /* reference count. */ |
320 | atomic_t ref_count; | 344 | atomic_t ref_count; |
321 | atomic_t open_count; | ||
322 | 345 | ||
323 | /* ccw queue and memory for static ccw/erp buffers. */ | 346 | /* ccw queue and memory for static ccw/erp buffers. */ |
324 | struct list_head ccw_queue; | 347 | struct list_head ccw_queue; |
@@ -337,20 +360,45 @@ struct dasd_device { | |||
337 | 360 | ||
338 | struct ccw_device *cdev; | 361 | struct ccw_device *cdev; |
339 | 362 | ||
363 | /* hook for alias management */ | ||
364 | struct list_head alias_list; | ||
365 | }; | ||
366 | |||
367 | struct dasd_block { | ||
368 | /* Block device stuff. */ | ||
369 | struct gendisk *gdp; | ||
370 | struct request_queue *request_queue; | ||
371 | spinlock_t request_queue_lock; | ||
372 | struct block_device *bdev; | ||
373 | atomic_t open_count; | ||
374 | |||
375 | unsigned long blocks; /* size of volume in blocks */ | ||
376 | unsigned int bp_block; /* bytes per block */ | ||
377 | unsigned int s2b_shift; /* log2 (bp_block/512) */ | ||
378 | |||
379 | struct dasd_device *base; | ||
380 | struct list_head ccw_queue; | ||
381 | spinlock_t queue_lock; | ||
382 | |||
383 | atomic_t tasklet_scheduled; | ||
384 | struct tasklet_struct tasklet; | ||
385 | struct timer_list timer; | ||
386 | |||
340 | #ifdef CONFIG_DASD_PROFILE | 387 | #ifdef CONFIG_DASD_PROFILE |
341 | struct dasd_profile_info_t profile; | 388 | struct dasd_profile_info_t profile; |
342 | #endif | 389 | #endif |
343 | }; | 390 | }; |
344 | 391 | ||
392 | |||
393 | |||
345 | /* reasons why device (ccw_device_start) was stopped */ | 394 | /* reasons why device (ccw_device_start) was stopped */ |
346 | #define DASD_STOPPED_NOT_ACC 1 /* not accessible */ | 395 | #define DASD_STOPPED_NOT_ACC 1 /* not accessible */ |
347 | #define DASD_STOPPED_QUIESCE 2 /* Quiesced */ | 396 | #define DASD_STOPPED_QUIESCE 2 /* Quiesced */ |
348 | #define DASD_STOPPED_PENDING 4 /* long busy */ | 397 | #define DASD_STOPPED_PENDING 4 /* long busy */ |
349 | #define DASD_STOPPED_DC_WAIT 8 /* disconnected, wait */ | 398 | #define DASD_STOPPED_DC_WAIT 8 /* disconnected, wait */ |
350 | #define DASD_STOPPED_DC_EIO 16 /* disconnected, return -EIO */ | 399 | #define DASD_STOPPED_SU 16 /* summary unit check handling */ |
351 | 400 | ||
352 | /* per device flags */ | 401 | /* per device flags */ |
353 | #define DASD_FLAG_DSC_ERROR 2 /* return -EIO when disconnected */ | ||
354 | #define DASD_FLAG_OFFLINE 3 /* device is in offline processing */ | 402 | #define DASD_FLAG_OFFLINE 3 /* device is in offline processing */ |
355 | #define DASD_FLAG_EER_SNSS 4 /* A SNSS is required */ | 403 | #define DASD_FLAG_EER_SNSS 4 /* A SNSS is required */ |
356 | #define DASD_FLAG_EER_IN_USE 5 /* A SNSS request is running */ | 404 | #define DASD_FLAG_EER_IN_USE 5 /* A SNSS request is running */ |
@@ -489,6 +537,9 @@ dasd_kmalloc_set_cda(struct ccw1 *ccw, void *cda, struct dasd_device *device) | |||
489 | struct dasd_device *dasd_alloc_device(void); | 537 | struct dasd_device *dasd_alloc_device(void); |
490 | void dasd_free_device(struct dasd_device *); | 538 | void dasd_free_device(struct dasd_device *); |
491 | 539 | ||
540 | struct dasd_block *dasd_alloc_block(void); | ||
541 | void dasd_free_block(struct dasd_block *); | ||
542 | |||
492 | void dasd_enable_device(struct dasd_device *); | 543 | void dasd_enable_device(struct dasd_device *); |
493 | void dasd_set_target_state(struct dasd_device *, int); | 544 | void dasd_set_target_state(struct dasd_device *, int); |
494 | void dasd_kick_device(struct dasd_device *); | 545 | void dasd_kick_device(struct dasd_device *); |
@@ -497,18 +548,23 @@ void dasd_add_request_head(struct dasd_ccw_req *); | |||
497 | void dasd_add_request_tail(struct dasd_ccw_req *); | 548 | void dasd_add_request_tail(struct dasd_ccw_req *); |
498 | int dasd_start_IO(struct dasd_ccw_req *); | 549 | int dasd_start_IO(struct dasd_ccw_req *); |
499 | int dasd_term_IO(struct dasd_ccw_req *); | 550 | int dasd_term_IO(struct dasd_ccw_req *); |
500 | void dasd_schedule_bh(struct dasd_device *); | 551 | void dasd_schedule_device_bh(struct dasd_device *); |
552 | void dasd_schedule_block_bh(struct dasd_block *); | ||
501 | int dasd_sleep_on(struct dasd_ccw_req *); | 553 | int dasd_sleep_on(struct dasd_ccw_req *); |
502 | int dasd_sleep_on_immediatly(struct dasd_ccw_req *); | 554 | int dasd_sleep_on_immediatly(struct dasd_ccw_req *); |
503 | int dasd_sleep_on_interruptible(struct dasd_ccw_req *); | 555 | int dasd_sleep_on_interruptible(struct dasd_ccw_req *); |
504 | void dasd_set_timer(struct dasd_device *, int); | 556 | void dasd_device_set_timer(struct dasd_device *, int); |
505 | void dasd_clear_timer(struct dasd_device *); | 557 | void dasd_device_clear_timer(struct dasd_device *); |
558 | void dasd_block_set_timer(struct dasd_block *, int); | ||
559 | void dasd_block_clear_timer(struct dasd_block *); | ||
506 | int dasd_cancel_req(struct dasd_ccw_req *); | 560 | int dasd_cancel_req(struct dasd_ccw_req *); |
561 | int dasd_flush_device_queue(struct dasd_device *); | ||
507 | int dasd_generic_probe (struct ccw_device *, struct dasd_discipline *); | 562 | int dasd_generic_probe (struct ccw_device *, struct dasd_discipline *); |
508 | void dasd_generic_remove (struct ccw_device *cdev); | 563 | void dasd_generic_remove (struct ccw_device *cdev); |
509 | int dasd_generic_set_online(struct ccw_device *, struct dasd_discipline *); | 564 | int dasd_generic_set_online(struct ccw_device *, struct dasd_discipline *); |
510 | int dasd_generic_set_offline (struct ccw_device *cdev); | 565 | int dasd_generic_set_offline (struct ccw_device *cdev); |
511 | int dasd_generic_notify(struct ccw_device *, int); | 566 | int dasd_generic_notify(struct ccw_device *, int); |
567 | void dasd_generic_handle_state_change(struct dasd_device *); | ||
512 | 568 | ||
513 | int dasd_generic_read_dev_chars(struct dasd_device *, char *, void **, int); | 569 | int dasd_generic_read_dev_chars(struct dasd_device *, char *, void **, int); |
514 | 570 | ||
@@ -542,10 +598,10 @@ int dasd_busid_known(char *); | |||
542 | /* externals in dasd_gendisk.c */ | 598 | /* externals in dasd_gendisk.c */ |
543 | int dasd_gendisk_init(void); | 599 | int dasd_gendisk_init(void); |
544 | void dasd_gendisk_exit(void); | 600 | void dasd_gendisk_exit(void); |
545 | int dasd_gendisk_alloc(struct dasd_device *); | 601 | int dasd_gendisk_alloc(struct dasd_block *); |
546 | void dasd_gendisk_free(struct dasd_device *); | 602 | void dasd_gendisk_free(struct dasd_block *); |
547 | int dasd_scan_partitions(struct dasd_device *); | 603 | int dasd_scan_partitions(struct dasd_block *); |
548 | void dasd_destroy_partitions(struct dasd_device *); | 604 | void dasd_destroy_partitions(struct dasd_block *); |
549 | 605 | ||
550 | /* externals in dasd_ioctl.c */ | 606 | /* externals in dasd_ioctl.c */ |
551 | int dasd_ioctl(struct inode *, struct file *, unsigned int, unsigned long); | 607 | int dasd_ioctl(struct inode *, struct file *, unsigned int, unsigned long); |
@@ -563,20 +619,9 @@ struct dasd_ccw_req *dasd_alloc_erp_request(char *, int, int, | |||
563 | void dasd_free_erp_request(struct dasd_ccw_req *, struct dasd_device *); | 619 | void dasd_free_erp_request(struct dasd_ccw_req *, struct dasd_device *); |
564 | void dasd_log_sense(struct dasd_ccw_req *, struct irb *); | 620 | void dasd_log_sense(struct dasd_ccw_req *, struct irb *); |
565 | 621 | ||
566 | /* externals in dasd_3370_erp.c */ | ||
567 | dasd_era_t dasd_3370_erp_examine(struct dasd_ccw_req *, struct irb *); | ||
568 | |||
569 | /* externals in dasd_3990_erp.c */ | 622 | /* externals in dasd_3990_erp.c */ |
570 | dasd_era_t dasd_3990_erp_examine(struct dasd_ccw_req *, struct irb *); | ||
571 | struct dasd_ccw_req *dasd_3990_erp_action(struct dasd_ccw_req *); | 623 | struct dasd_ccw_req *dasd_3990_erp_action(struct dasd_ccw_req *); |
572 | 624 | ||
573 | /* externals in dasd_9336_erp.c */ | ||
574 | dasd_era_t dasd_9336_erp_examine(struct dasd_ccw_req *, struct irb *); | ||
575 | |||
576 | /* externals in dasd_9336_erp.c */ | ||
577 | dasd_era_t dasd_9343_erp_examine(struct dasd_ccw_req *, struct irb *); | ||
578 | struct dasd_ccw_req *dasd_9343_erp_action(struct dasd_ccw_req *); | ||
579 | |||
580 | /* externals in dasd_eer.c */ | 625 | /* externals in dasd_eer.c */ |
581 | #ifdef CONFIG_DASD_EER | 626 | #ifdef CONFIG_DASD_EER |
582 | int dasd_eer_init(void); | 627 | int dasd_eer_init(void); |
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index 672eb0a3dd0b..91a64630cb0f 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c | |||
@@ -38,15 +38,15 @@ dasd_ioctl_api_version(void __user *argp) | |||
38 | static int | 38 | static int |
39 | dasd_ioctl_enable(struct block_device *bdev) | 39 | dasd_ioctl_enable(struct block_device *bdev) |
40 | { | 40 | { |
41 | struct dasd_device *device = bdev->bd_disk->private_data; | 41 | struct dasd_block *block = bdev->bd_disk->private_data; |
42 | 42 | ||
43 | if (!capable(CAP_SYS_ADMIN)) | 43 | if (!capable(CAP_SYS_ADMIN)) |
44 | return -EACCES; | 44 | return -EACCES; |
45 | 45 | ||
46 | dasd_enable_device(device); | 46 | dasd_enable_device(block->base); |
47 | /* Formatting the dasd device can change the capacity. */ | 47 | /* Formatting the dasd device can change the capacity. */ |
48 | mutex_lock(&bdev->bd_mutex); | 48 | mutex_lock(&bdev->bd_mutex); |
49 | i_size_write(bdev->bd_inode, (loff_t)get_capacity(device->gdp) << 9); | 49 | i_size_write(bdev->bd_inode, (loff_t)get_capacity(block->gdp) << 9); |
50 | mutex_unlock(&bdev->bd_mutex); | 50 | mutex_unlock(&bdev->bd_mutex); |
51 | return 0; | 51 | return 0; |
52 | } | 52 | } |
@@ -58,7 +58,7 @@ dasd_ioctl_enable(struct block_device *bdev) | |||
58 | static int | 58 | static int |
59 | dasd_ioctl_disable(struct block_device *bdev) | 59 | dasd_ioctl_disable(struct block_device *bdev) |
60 | { | 60 | { |
61 | struct dasd_device *device = bdev->bd_disk->private_data; | 61 | struct dasd_block *block = bdev->bd_disk->private_data; |
62 | 62 | ||
63 | if (!capable(CAP_SYS_ADMIN)) | 63 | if (!capable(CAP_SYS_ADMIN)) |
64 | return -EACCES; | 64 | return -EACCES; |
@@ -71,7 +71,7 @@ dasd_ioctl_disable(struct block_device *bdev) | |||
71 | * using the BIODASDFMT ioctl. Therefore the correct state for the | 71 | * using the BIODASDFMT ioctl. Therefore the correct state for the |
72 | * device is DASD_STATE_BASIC that allows to do basic i/o. | 72 | * device is DASD_STATE_BASIC that allows to do basic i/o. |
73 | */ | 73 | */ |
74 | dasd_set_target_state(device, DASD_STATE_BASIC); | 74 | dasd_set_target_state(block->base, DASD_STATE_BASIC); |
75 | /* | 75 | /* |
76 | * Set i_size to zero, since read, write, etc. check against this | 76 | * Set i_size to zero, since read, write, etc. check against this |
77 | * value. | 77 | * value. |
@@ -85,19 +85,19 @@ dasd_ioctl_disable(struct block_device *bdev) | |||
85 | /* | 85 | /* |
86 | * Quiesce device. | 86 | * Quiesce device. |
87 | */ | 87 | */ |
88 | static int | 88 | static int dasd_ioctl_quiesce(struct dasd_block *block) |
89 | dasd_ioctl_quiesce(struct dasd_device *device) | ||
90 | { | 89 | { |
91 | unsigned long flags; | 90 | unsigned long flags; |
91 | struct dasd_device *base; | ||
92 | 92 | ||
93 | base = block->base; | ||
93 | if (!capable (CAP_SYS_ADMIN)) | 94 | if (!capable (CAP_SYS_ADMIN)) |
94 | return -EACCES; | 95 | return -EACCES; |
95 | 96 | ||
96 | DEV_MESSAGE (KERN_DEBUG, device, "%s", | 97 | DEV_MESSAGE(KERN_DEBUG, base, "%s", "Quiesce IO on device"); |
97 | "Quiesce IO on device"); | 98 | spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags); |
98 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | 99 | base->stopped |= DASD_STOPPED_QUIESCE; |
99 | device->stopped |= DASD_STOPPED_QUIESCE; | 100 | spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags); |
100 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); | ||
101 | return 0; | 101 | return 0; |
102 | } | 102 | } |
103 | 103 | ||
@@ -105,22 +105,21 @@ dasd_ioctl_quiesce(struct dasd_device *device) | |||
105 | /* | 105 | /* |
106 | * Quiesce device. | 106 | * Quiesce device. |
107 | */ | 107 | */ |
108 | static int | 108 | static int dasd_ioctl_resume(struct dasd_block *block) |
109 | dasd_ioctl_resume(struct dasd_device *device) | ||
110 | { | 109 | { |
111 | unsigned long flags; | 110 | unsigned long flags; |
111 | struct dasd_device *base; | ||
112 | 112 | ||
113 | base = block->base; | ||
113 | if (!capable (CAP_SYS_ADMIN)) | 114 | if (!capable (CAP_SYS_ADMIN)) |
114 | return -EACCES; | 115 | return -EACCES; |
115 | 116 | ||
116 | DEV_MESSAGE (KERN_DEBUG, device, "%s", | 117 | DEV_MESSAGE(KERN_DEBUG, base, "%s", "resume IO on device"); |
117 | "resume IO on device"); | 118 | spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags); |
118 | 119 | base->stopped &= ~DASD_STOPPED_QUIESCE; | |
119 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | 120 | spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags); |
120 | device->stopped &= ~DASD_STOPPED_QUIESCE; | ||
121 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); | ||
122 | 121 | ||
123 | dasd_schedule_bh (device); | 122 | dasd_schedule_block_bh(block); |
124 | return 0; | 123 | return 0; |
125 | } | 124 | } |
126 | 125 | ||
@@ -130,22 +129,23 @@ dasd_ioctl_resume(struct dasd_device *device) | |||
130 | * commands to format a single unit of the device. In terms of the ECKD | 129 | * commands to format a single unit of the device. In terms of the ECKD |
131 | * devices this means CCWs are generated to format a single track. | 130 | * devices this means CCWs are generated to format a single track. |
132 | */ | 131 | */ |
133 | static int | 132 | static int dasd_format(struct dasd_block *block, struct format_data_t *fdata) |
134 | dasd_format(struct dasd_device * device, struct format_data_t * fdata) | ||
135 | { | 133 | { |
136 | struct dasd_ccw_req *cqr; | 134 | struct dasd_ccw_req *cqr; |
135 | struct dasd_device *base; | ||
137 | int rc; | 136 | int rc; |
138 | 137 | ||
139 | if (device->discipline->format_device == NULL) | 138 | base = block->base; |
139 | if (base->discipline->format_device == NULL) | ||
140 | return -EPERM; | 140 | return -EPERM; |
141 | 141 | ||
142 | if (device->state != DASD_STATE_BASIC) { | 142 | if (base->state != DASD_STATE_BASIC) { |
143 | DEV_MESSAGE(KERN_WARNING, device, "%s", | 143 | DEV_MESSAGE(KERN_WARNING, base, "%s", |
144 | "dasd_format: device is not disabled! "); | 144 | "dasd_format: device is not disabled! "); |
145 | return -EBUSY; | 145 | return -EBUSY; |
146 | } | 146 | } |
147 | 147 | ||
148 | DBF_DEV_EVENT(DBF_NOTICE, device, | 148 | DBF_DEV_EVENT(DBF_NOTICE, base, |
149 | "formatting units %d to %d (%d B blocks) flags %d", | 149 | "formatting units %d to %d (%d B blocks) flags %d", |
150 | fdata->start_unit, | 150 | fdata->start_unit, |
151 | fdata->stop_unit, fdata->blksize, fdata->intensity); | 151 | fdata->stop_unit, fdata->blksize, fdata->intensity); |
@@ -156,20 +156,20 @@ dasd_format(struct dasd_device * device, struct format_data_t * fdata) | |||
156 | * enabling the device later. | 156 | * enabling the device later. |
157 | */ | 157 | */ |
158 | if (fdata->start_unit == 0) { | 158 | if (fdata->start_unit == 0) { |
159 | struct block_device *bdev = bdget_disk(device->gdp, 0); | 159 | struct block_device *bdev = bdget_disk(block->gdp, 0); |
160 | bdev->bd_inode->i_blkbits = blksize_bits(fdata->blksize); | 160 | bdev->bd_inode->i_blkbits = blksize_bits(fdata->blksize); |
161 | bdput(bdev); | 161 | bdput(bdev); |
162 | } | 162 | } |
163 | 163 | ||
164 | while (fdata->start_unit <= fdata->stop_unit) { | 164 | while (fdata->start_unit <= fdata->stop_unit) { |
165 | cqr = device->discipline->format_device(device, fdata); | 165 | cqr = base->discipline->format_device(base, fdata); |
166 | if (IS_ERR(cqr)) | 166 | if (IS_ERR(cqr)) |
167 | return PTR_ERR(cqr); | 167 | return PTR_ERR(cqr); |
168 | rc = dasd_sleep_on_interruptible(cqr); | 168 | rc = dasd_sleep_on_interruptible(cqr); |
169 | dasd_sfree_request(cqr, cqr->device); | 169 | dasd_sfree_request(cqr, cqr->memdev); |
170 | if (rc) { | 170 | if (rc) { |
171 | if (rc != -ERESTARTSYS) | 171 | if (rc != -ERESTARTSYS) |
172 | DEV_MESSAGE(KERN_ERR, device, | 172 | DEV_MESSAGE(KERN_ERR, base, |
173 | " Formatting of unit %d failed " | 173 | " Formatting of unit %d failed " |
174 | "with rc = %d", | 174 | "with rc = %d", |
175 | fdata->start_unit, rc); | 175 | fdata->start_unit, rc); |
@@ -186,7 +186,7 @@ dasd_format(struct dasd_device * device, struct format_data_t * fdata) | |||
186 | static int | 186 | static int |
187 | dasd_ioctl_format(struct block_device *bdev, void __user *argp) | 187 | dasd_ioctl_format(struct block_device *bdev, void __user *argp) |
188 | { | 188 | { |
189 | struct dasd_device *device = bdev->bd_disk->private_data; | 189 | struct dasd_block *block = bdev->bd_disk->private_data; |
190 | struct format_data_t fdata; | 190 | struct format_data_t fdata; |
191 | 191 | ||
192 | if (!capable(CAP_SYS_ADMIN)) | 192 | if (!capable(CAP_SYS_ADMIN)) |
@@ -194,51 +194,47 @@ dasd_ioctl_format(struct block_device *bdev, void __user *argp) | |||
194 | if (!argp) | 194 | if (!argp) |
195 | return -EINVAL; | 195 | return -EINVAL; |
196 | 196 | ||
197 | if (device->features & DASD_FEATURE_READONLY) | 197 | if (block->base->features & DASD_FEATURE_READONLY) |
198 | return -EROFS; | 198 | return -EROFS; |
199 | if (copy_from_user(&fdata, argp, sizeof(struct format_data_t))) | 199 | if (copy_from_user(&fdata, argp, sizeof(struct format_data_t))) |
200 | return -EFAULT; | 200 | return -EFAULT; |
201 | if (bdev != bdev->bd_contains) { | 201 | if (bdev != bdev->bd_contains) { |
202 | DEV_MESSAGE(KERN_WARNING, device, "%s", | 202 | DEV_MESSAGE(KERN_WARNING, block->base, "%s", |
203 | "Cannot low-level format a partition"); | 203 | "Cannot low-level format a partition"); |
204 | return -EINVAL; | 204 | return -EINVAL; |
205 | } | 205 | } |
206 | return dasd_format(device, &fdata); | 206 | return dasd_format(block, &fdata); |
207 | } | 207 | } |
208 | 208 | ||
209 | #ifdef CONFIG_DASD_PROFILE | 209 | #ifdef CONFIG_DASD_PROFILE |
210 | /* | 210 | /* |
211 | * Reset device profile information | 211 | * Reset device profile information |
212 | */ | 212 | */ |
213 | static int | 213 | static int dasd_ioctl_reset_profile(struct dasd_block *block) |
214 | dasd_ioctl_reset_profile(struct dasd_device *device) | ||
215 | { | 214 | { |
216 | memset(&device->profile, 0, sizeof (struct dasd_profile_info_t)); | 215 | memset(&block->profile, 0, sizeof(struct dasd_profile_info_t)); |
217 | return 0; | 216 | return 0; |
218 | } | 217 | } |
219 | 218 | ||
220 | /* | 219 | /* |
221 | * Return device profile information | 220 | * Return device profile information |
222 | */ | 221 | */ |
223 | static int | 222 | static int dasd_ioctl_read_profile(struct dasd_block *block, void __user *argp) |
224 | dasd_ioctl_read_profile(struct dasd_device *device, void __user *argp) | ||
225 | { | 223 | { |
226 | if (dasd_profile_level == DASD_PROFILE_OFF) | 224 | if (dasd_profile_level == DASD_PROFILE_OFF) |
227 | return -EIO; | 225 | return -EIO; |
228 | if (copy_to_user(argp, &device->profile, | 226 | if (copy_to_user(argp, &block->profile, |
229 | sizeof (struct dasd_profile_info_t))) | 227 | sizeof(struct dasd_profile_info_t))) |
230 | return -EFAULT; | 228 | return -EFAULT; |
231 | return 0; | 229 | return 0; |
232 | } | 230 | } |
233 | #else | 231 | #else |
234 | static int | 232 | static int dasd_ioctl_reset_profile(struct dasd_block *block) |
235 | dasd_ioctl_reset_profile(struct dasd_device *device) | ||
236 | { | 233 | { |
237 | return -ENOSYS; | 234 | return -ENOSYS; |
238 | } | 235 | } |
239 | 236 | ||
240 | static int | 237 | static int dasd_ioctl_read_profile(struct dasd_block *block, void __user *argp) |
241 | dasd_ioctl_read_profile(struct dasd_device *device, void __user *argp) | ||
242 | { | 238 | { |
243 | return -ENOSYS; | 239 | return -ENOSYS; |
244 | } | 240 | } |
@@ -247,87 +243,88 @@ dasd_ioctl_read_profile(struct dasd_device *device, void __user *argp) | |||
247 | /* | 243 | /* |
248 | * Return dasd information. Used for BIODASDINFO and BIODASDINFO2. | 244 | * Return dasd information. Used for BIODASDINFO and BIODASDINFO2. |
249 | */ | 245 | */ |
250 | static int | 246 | static int dasd_ioctl_information(struct dasd_block *block, |
251 | dasd_ioctl_information(struct dasd_device *device, | 247 | unsigned int cmd, void __user *argp) |
252 | unsigned int cmd, void __user *argp) | ||
253 | { | 248 | { |
254 | struct dasd_information2_t *dasd_info; | 249 | struct dasd_information2_t *dasd_info; |
255 | unsigned long flags; | 250 | unsigned long flags; |
256 | int rc; | 251 | int rc; |
252 | struct dasd_device *base; | ||
257 | struct ccw_device *cdev; | 253 | struct ccw_device *cdev; |
258 | struct ccw_dev_id dev_id; | 254 | struct ccw_dev_id dev_id; |
259 | 255 | ||
260 | if (!device->discipline->fill_info) | 256 | base = block->base; |
257 | if (!base->discipline->fill_info) | ||
261 | return -EINVAL; | 258 | return -EINVAL; |
262 | 259 | ||
263 | dasd_info = kzalloc(sizeof(struct dasd_information2_t), GFP_KERNEL); | 260 | dasd_info = kzalloc(sizeof(struct dasd_information2_t), GFP_KERNEL); |
264 | if (dasd_info == NULL) | 261 | if (dasd_info == NULL) |
265 | return -ENOMEM; | 262 | return -ENOMEM; |
266 | 263 | ||
267 | rc = device->discipline->fill_info(device, dasd_info); | 264 | rc = base->discipline->fill_info(base, dasd_info); |
268 | if (rc) { | 265 | if (rc) { |
269 | kfree(dasd_info); | 266 | kfree(dasd_info); |
270 | return rc; | 267 | return rc; |
271 | } | 268 | } |
272 | 269 | ||
273 | cdev = device->cdev; | 270 | cdev = base->cdev; |
274 | ccw_device_get_id(cdev, &dev_id); | 271 | ccw_device_get_id(cdev, &dev_id); |
275 | 272 | ||
276 | dasd_info->devno = dev_id.devno; | 273 | dasd_info->devno = dev_id.devno; |
277 | dasd_info->schid = _ccw_device_get_subchannel_number(device->cdev); | 274 | dasd_info->schid = _ccw_device_get_subchannel_number(base->cdev); |
278 | dasd_info->cu_type = cdev->id.cu_type; | 275 | dasd_info->cu_type = cdev->id.cu_type; |
279 | dasd_info->cu_model = cdev->id.cu_model; | 276 | dasd_info->cu_model = cdev->id.cu_model; |
280 | dasd_info->dev_type = cdev->id.dev_type; | 277 | dasd_info->dev_type = cdev->id.dev_type; |
281 | dasd_info->dev_model = cdev->id.dev_model; | 278 | dasd_info->dev_model = cdev->id.dev_model; |
282 | dasd_info->status = device->state; | 279 | dasd_info->status = base->state; |
283 | /* | 280 | /* |
284 | * The open_count is increased for every opener, that includes | 281 | * The open_count is increased for every opener, that includes |
285 | * the blkdev_get in dasd_scan_partitions. | 282 | * the blkdev_get in dasd_scan_partitions. |
286 | * This must be hidden from user-space. | 283 | * This must be hidden from user-space. |
287 | */ | 284 | */ |
288 | dasd_info->open_count = atomic_read(&device->open_count); | 285 | dasd_info->open_count = atomic_read(&block->open_count); |
289 | if (!device->bdev) | 286 | if (!block->bdev) |
290 | dasd_info->open_count++; | 287 | dasd_info->open_count++; |
291 | 288 | ||
292 | /* | 289 | /* |
293 | * check if device is really formatted | 290 | * check if device is really formatted |
294 | * LDL / CDL was returned by 'fill_info' | 291 | * LDL / CDL was returned by 'fill_info' |
295 | */ | 292 | */ |
296 | if ((device->state < DASD_STATE_READY) || | 293 | if ((base->state < DASD_STATE_READY) || |
297 | (dasd_check_blocksize(device->bp_block))) | 294 | (dasd_check_blocksize(block->bp_block))) |
298 | dasd_info->format = DASD_FORMAT_NONE; | 295 | dasd_info->format = DASD_FORMAT_NONE; |
299 | 296 | ||
300 | dasd_info->features |= | 297 | dasd_info->features |= |
301 | ((device->features & DASD_FEATURE_READONLY) != 0); | 298 | ((base->features & DASD_FEATURE_READONLY) != 0); |
302 | 299 | ||
303 | if (device->discipline) | 300 | if (base->discipline) |
304 | memcpy(dasd_info->type, device->discipline->name, 4); | 301 | memcpy(dasd_info->type, base->discipline->name, 4); |
305 | else | 302 | else |
306 | memcpy(dasd_info->type, "none", 4); | 303 | memcpy(dasd_info->type, "none", 4); |
307 | 304 | ||
308 | if (device->request_queue->request_fn) { | 305 | if (block->request_queue->request_fn) { |
309 | struct list_head *l; | 306 | struct list_head *l; |
310 | #ifdef DASD_EXTENDED_PROFILING | 307 | #ifdef DASD_EXTENDED_PROFILING |
311 | { | 308 | { |
312 | struct list_head *l; | 309 | struct list_head *l; |
313 | spin_lock_irqsave(&device->lock, flags); | 310 | spin_lock_irqsave(&block->lock, flags); |
314 | list_for_each(l, &device->request_queue->queue_head) | 311 | list_for_each(l, &block->request_queue->queue_head) |
315 | dasd_info->req_queue_len++; | 312 | dasd_info->req_queue_len++; |
316 | spin_unlock_irqrestore(&device->lock, flags); | 313 | spin_unlock_irqrestore(&block->lock, flags); |
317 | } | 314 | } |
318 | #endif /* DASD_EXTENDED_PROFILING */ | 315 | #endif /* DASD_EXTENDED_PROFILING */ |
319 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | 316 | spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags); |
320 | list_for_each(l, &device->ccw_queue) | 317 | list_for_each(l, &base->ccw_queue) |
321 | dasd_info->chanq_len++; | 318 | dasd_info->chanq_len++; |
322 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), | 319 | spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), |
323 | flags); | 320 | flags); |
324 | } | 321 | } |
325 | 322 | ||
326 | rc = 0; | 323 | rc = 0; |
327 | if (copy_to_user(argp, dasd_info, | 324 | if (copy_to_user(argp, dasd_info, |
328 | ((cmd == (unsigned int) BIODASDINFO2) ? | 325 | ((cmd == (unsigned int) BIODASDINFO2) ? |
329 | sizeof (struct dasd_information2_t) : | 326 | sizeof(struct dasd_information2_t) : |
330 | sizeof (struct dasd_information_t)))) | 327 | sizeof(struct dasd_information_t)))) |
331 | rc = -EFAULT; | 328 | rc = -EFAULT; |
332 | kfree(dasd_info); | 329 | kfree(dasd_info); |
333 | return rc; | 330 | return rc; |
@@ -339,7 +336,7 @@ dasd_ioctl_information(struct dasd_device *device, | |||
339 | static int | 336 | static int |
340 | dasd_ioctl_set_ro(struct block_device *bdev, void __user *argp) | 337 | dasd_ioctl_set_ro(struct block_device *bdev, void __user *argp) |
341 | { | 338 | { |
342 | struct dasd_device *device = bdev->bd_disk->private_data; | 339 | struct dasd_block *block = bdev->bd_disk->private_data; |
343 | int intval; | 340 | int intval; |
344 | 341 | ||
345 | if (!capable(CAP_SYS_ADMIN)) | 342 | if (!capable(CAP_SYS_ADMIN)) |
@@ -351,11 +348,10 @@ dasd_ioctl_set_ro(struct block_device *bdev, void __user *argp) | |||
351 | return -EFAULT; | 348 | return -EFAULT; |
352 | 349 | ||
353 | set_disk_ro(bdev->bd_disk, intval); | 350 | set_disk_ro(bdev->bd_disk, intval); |
354 | return dasd_set_feature(device->cdev, DASD_FEATURE_READONLY, intval); | 351 | return dasd_set_feature(block->base->cdev, DASD_FEATURE_READONLY, intval); |
355 | } | 352 | } |
356 | 353 | ||
357 | static int | 354 | static int dasd_ioctl_readall_cmb(struct dasd_block *block, unsigned int cmd, |
358 | dasd_ioctl_readall_cmb(struct dasd_device *device, unsigned int cmd, | ||
359 | unsigned long arg) | 355 | unsigned long arg) |
360 | { | 356 | { |
361 | struct cmbdata __user *argp = (void __user *) arg; | 357 | struct cmbdata __user *argp = (void __user *) arg; |
@@ -363,7 +359,7 @@ dasd_ioctl_readall_cmb(struct dasd_device *device, unsigned int cmd, | |||
363 | struct cmbdata data; | 359 | struct cmbdata data; |
364 | int ret; | 360 | int ret; |
365 | 361 | ||
366 | ret = cmf_readall(device->cdev, &data); | 362 | ret = cmf_readall(block->base->cdev, &data); |
367 | if (!ret && copy_to_user(argp, &data, min(size, sizeof(*argp)))) | 363 | if (!ret && copy_to_user(argp, &data, min(size, sizeof(*argp)))) |
368 | return -EFAULT; | 364 | return -EFAULT; |
369 | return ret; | 365 | return ret; |
@@ -374,10 +370,10 @@ dasd_ioctl(struct inode *inode, struct file *file, | |||
374 | unsigned int cmd, unsigned long arg) | 370 | unsigned int cmd, unsigned long arg) |
375 | { | 371 | { |
376 | struct block_device *bdev = inode->i_bdev; | 372 | struct block_device *bdev = inode->i_bdev; |
377 | struct dasd_device *device = bdev->bd_disk->private_data; | 373 | struct dasd_block *block = bdev->bd_disk->private_data; |
378 | void __user *argp = (void __user *)arg; | 374 | void __user *argp = (void __user *)arg; |
379 | 375 | ||
380 | if (!device) | 376 | if (!block) |
381 | return -ENODEV; | 377 | return -ENODEV; |
382 | 378 | ||
383 | if ((_IOC_DIR(cmd) != _IOC_NONE) && !arg) { | 379 | if ((_IOC_DIR(cmd) != _IOC_NONE) && !arg) { |
@@ -391,33 +387,33 @@ dasd_ioctl(struct inode *inode, struct file *file, | |||
391 | case BIODASDENABLE: | 387 | case BIODASDENABLE: |
392 | return dasd_ioctl_enable(bdev); | 388 | return dasd_ioctl_enable(bdev); |
393 | case BIODASDQUIESCE: | 389 | case BIODASDQUIESCE: |
394 | return dasd_ioctl_quiesce(device); | 390 | return dasd_ioctl_quiesce(block); |
395 | case BIODASDRESUME: | 391 | case BIODASDRESUME: |
396 | return dasd_ioctl_resume(device); | 392 | return dasd_ioctl_resume(block); |
397 | case BIODASDFMT: | 393 | case BIODASDFMT: |
398 | return dasd_ioctl_format(bdev, argp); | 394 | return dasd_ioctl_format(bdev, argp); |
399 | case BIODASDINFO: | 395 | case BIODASDINFO: |
400 | return dasd_ioctl_information(device, cmd, argp); | 396 | return dasd_ioctl_information(block, cmd, argp); |
401 | case BIODASDINFO2: | 397 | case BIODASDINFO2: |
402 | return dasd_ioctl_information(device, cmd, argp); | 398 | return dasd_ioctl_information(block, cmd, argp); |
403 | case BIODASDPRRD: | 399 | case BIODASDPRRD: |
404 | return dasd_ioctl_read_profile(device, argp); | 400 | return dasd_ioctl_read_profile(block, argp); |
405 | case BIODASDPRRST: | 401 | case BIODASDPRRST: |
406 | return dasd_ioctl_reset_profile(device); | 402 | return dasd_ioctl_reset_profile(block); |
407 | case BLKROSET: | 403 | case BLKROSET: |
408 | return dasd_ioctl_set_ro(bdev, argp); | 404 | return dasd_ioctl_set_ro(bdev, argp); |
409 | case DASDAPIVER: | 405 | case DASDAPIVER: |
410 | return dasd_ioctl_api_version(argp); | 406 | return dasd_ioctl_api_version(argp); |
411 | case BIODASDCMFENABLE: | 407 | case BIODASDCMFENABLE: |
412 | return enable_cmf(device->cdev); | 408 | return enable_cmf(block->base->cdev); |
413 | case BIODASDCMFDISABLE: | 409 | case BIODASDCMFDISABLE: |
414 | return disable_cmf(device->cdev); | 410 | return disable_cmf(block->base->cdev); |
415 | case BIODASDREADALLCMB: | 411 | case BIODASDREADALLCMB: |
416 | return dasd_ioctl_readall_cmb(device, cmd, arg); | 412 | return dasd_ioctl_readall_cmb(block, cmd, arg); |
417 | default: | 413 | default: |
418 | /* if the discipline has an ioctl method try it. */ | 414 | /* if the discipline has an ioctl method try it. */ |
419 | if (device->discipline->ioctl) { | 415 | if (block->base->discipline->ioctl) { |
420 | int rval = device->discipline->ioctl(device, cmd, argp); | 416 | int rval = block->base->discipline->ioctl(block, cmd, argp); |
421 | if (rval != -ENOIOCTLCMD) | 417 | if (rval != -ENOIOCTLCMD) |
422 | return rval; | 418 | return rval; |
423 | } | 419 | } |
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c index ac7e8ef504cb..28a86f070048 100644 --- a/drivers/s390/block/dasd_proc.c +++ b/drivers/s390/block/dasd_proc.c | |||
@@ -54,11 +54,16 @@ static int | |||
54 | dasd_devices_show(struct seq_file *m, void *v) | 54 | dasd_devices_show(struct seq_file *m, void *v) |
55 | { | 55 | { |
56 | struct dasd_device *device; | 56 | struct dasd_device *device; |
57 | struct dasd_block *block; | ||
57 | char *substr; | 58 | char *substr; |
58 | 59 | ||
59 | device = dasd_device_from_devindex((unsigned long) v - 1); | 60 | device = dasd_device_from_devindex((unsigned long) v - 1); |
60 | if (IS_ERR(device)) | 61 | if (IS_ERR(device)) |
61 | return 0; | 62 | return 0; |
63 | if (device->block) | ||
64 | block = device->block; | ||
65 | else | ||
66 | return 0; | ||
62 | /* Print device number. */ | 67 | /* Print device number. */ |
63 | seq_printf(m, "%s", device->cdev->dev.bus_id); | 68 | seq_printf(m, "%s", device->cdev->dev.bus_id); |
64 | /* Print discipline string. */ | 69 | /* Print discipline string. */ |
@@ -67,14 +72,14 @@ dasd_devices_show(struct seq_file *m, void *v) | |||
67 | else | 72 | else |
68 | seq_printf(m, "(none)"); | 73 | seq_printf(m, "(none)"); |
69 | /* Print kdev. */ | 74 | /* Print kdev. */ |
70 | if (device->gdp) | 75 | if (block->gdp) |
71 | seq_printf(m, " at (%3d:%6d)", | 76 | seq_printf(m, " at (%3d:%6d)", |
72 | device->gdp->major, device->gdp->first_minor); | 77 | block->gdp->major, block->gdp->first_minor); |
73 | else | 78 | else |
74 | seq_printf(m, " at (???:??????)"); | 79 | seq_printf(m, " at (???:??????)"); |
75 | /* Print device name. */ | 80 | /* Print device name. */ |
76 | if (device->gdp) | 81 | if (block->gdp) |
77 | seq_printf(m, " is %-8s", device->gdp->disk_name); | 82 | seq_printf(m, " is %-8s", block->gdp->disk_name); |
78 | else | 83 | else |
79 | seq_printf(m, " is ????????"); | 84 | seq_printf(m, " is ????????"); |
80 | /* Print devices features. */ | 85 | /* Print devices features. */ |
@@ -100,14 +105,14 @@ dasd_devices_show(struct seq_file *m, void *v) | |||
100 | case DASD_STATE_READY: | 105 | case DASD_STATE_READY: |
101 | case DASD_STATE_ONLINE: | 106 | case DASD_STATE_ONLINE: |
102 | seq_printf(m, "active "); | 107 | seq_printf(m, "active "); |
103 | if (dasd_check_blocksize(device->bp_block)) | 108 | if (dasd_check_blocksize(block->bp_block)) |
104 | seq_printf(m, "n/f "); | 109 | seq_printf(m, "n/f "); |
105 | else | 110 | else |
106 | seq_printf(m, | 111 | seq_printf(m, |
107 | "at blocksize: %d, %ld blocks, %ld MB", | 112 | "at blocksize: %d, %ld blocks, %ld MB", |
108 | device->bp_block, device->blocks, | 113 | block->bp_block, block->blocks, |
109 | ((device->bp_block >> 9) * | 114 | ((block->bp_block >> 9) * |
110 | device->blocks) >> 11); | 115 | block->blocks) >> 11); |
111 | break; | 116 | break; |
112 | default: | 117 | default: |
113 | seq_printf(m, "no stat"); | 118 | seq_printf(m, "no stat"); |
@@ -137,7 +142,7 @@ static void dasd_devices_stop(struct seq_file *m, void *v) | |||
137 | { | 142 | { |
138 | } | 143 | } |
139 | 144 | ||
140 | static struct seq_operations dasd_devices_seq_ops = { | 145 | static const struct seq_operations dasd_devices_seq_ops = { |
141 | .start = dasd_devices_start, | 146 | .start = dasd_devices_start, |
142 | .next = dasd_devices_next, | 147 | .next = dasd_devices_next, |
143 | .stop = dasd_devices_stop, | 148 | .stop = dasd_devices_stop, |
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index 15a5789b7734..7779bfce1c31 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c | |||
@@ -82,7 +82,7 @@ struct dcssblk_dev_info { | |||
82 | struct request_queue *dcssblk_queue; | 82 | struct request_queue *dcssblk_queue; |
83 | }; | 83 | }; |
84 | 84 | ||
85 | static struct list_head dcssblk_devices = LIST_HEAD_INIT(dcssblk_devices); | 85 | static LIST_HEAD(dcssblk_devices); |
86 | static struct rw_semaphore dcssblk_devices_sem; | 86 | static struct rw_semaphore dcssblk_devices_sem; |
87 | 87 | ||
88 | /* | 88 | /* |
diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile index 130de19916f2..7e73e39a1741 100644 --- a/drivers/s390/char/Makefile +++ b/drivers/s390/char/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += ctrlchar.o keyboard.o defkeymap.o sclp.o sclp_rw.o sclp_quiesce.o \ | 5 | obj-y += ctrlchar.o keyboard.o defkeymap.o sclp.o sclp_rw.o sclp_quiesce.o \ |
6 | sclp_info.o sclp_config.o sclp_chp.o | 6 | sclp_cmd.o sclp_config.o sclp_cpi_sys.o |
7 | 7 | ||
8 | obj-$(CONFIG_TN3270) += raw3270.o | 8 | obj-$(CONFIG_TN3270) += raw3270.o |
9 | obj-$(CONFIG_TN3270_CONSOLE) += con3270.o | 9 | obj-$(CONFIG_TN3270_CONSOLE) += con3270.o |
diff --git a/drivers/s390/char/monwriter.c b/drivers/s390/char/monwriter.c index 20442fbf9346..a86c0534cd49 100644 --- a/drivers/s390/char/monwriter.c +++ b/drivers/s390/char/monwriter.c | |||
@@ -295,7 +295,7 @@ module_init(mon_init); | |||
295 | module_exit(mon_exit); | 295 | module_exit(mon_exit); |
296 | 296 | ||
297 | module_param_named(max_bufs, mon_max_bufs, int, 0644); | 297 | module_param_named(max_bufs, mon_max_bufs, int, 0644); |
298 | MODULE_PARM_DESC(max_bufs, "Maximum number of sample monitor data buffers" | 298 | MODULE_PARM_DESC(max_bufs, "Maximum number of sample monitor data buffers " |
299 | "that can be active at one time"); | 299 | "that can be active at one time"); |
300 | 300 | ||
301 | MODULE_AUTHOR("Melissa Howland <Melissa.Howland@us.ibm.com>"); | 301 | MODULE_AUTHOR("Melissa Howland <Melissa.Howland@us.ibm.com>"); |
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index 8d1c64a24dec..0d98f1ff2edd 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c | |||
@@ -66,7 +66,7 @@ struct raw3270 { | |||
66 | static DEFINE_MUTEX(raw3270_mutex); | 66 | static DEFINE_MUTEX(raw3270_mutex); |
67 | 67 | ||
68 | /* List of 3270 devices. */ | 68 | /* List of 3270 devices. */ |
69 | static struct list_head raw3270_devices = LIST_HEAD_INIT(raw3270_devices); | 69 | static LIST_HEAD(raw3270_devices); |
70 | 70 | ||
71 | /* | 71 | /* |
72 | * Flag to indicate if the driver has been registered. Some operations | 72 | * Flag to indicate if the driver has been registered. Some operations |
@@ -1210,7 +1210,7 @@ struct raw3270_notifier { | |||
1210 | void (*notifier)(int, int); | 1210 | void (*notifier)(int, int); |
1211 | }; | 1211 | }; |
1212 | 1212 | ||
1213 | static struct list_head raw3270_notifier = LIST_HEAD_INIT(raw3270_notifier); | 1213 | static LIST_HEAD(raw3270_notifier); |
1214 | 1214 | ||
1215 | int raw3270_register_notifier(void (*notifier)(int, int)) | 1215 | int raw3270_register_notifier(void (*notifier)(int, int)) |
1216 | { | 1216 | { |
diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h index c7318a125852..aa8186d18aee 100644 --- a/drivers/s390/char/sclp.h +++ b/drivers/s390/char/sclp.h | |||
@@ -56,8 +56,6 @@ typedef unsigned int sclp_cmdw_t; | |||
56 | #define SCLP_CMDW_READ_EVENT_DATA 0x00770005 | 56 | #define SCLP_CMDW_READ_EVENT_DATA 0x00770005 |
57 | #define SCLP_CMDW_WRITE_EVENT_DATA 0x00760005 | 57 | #define SCLP_CMDW_WRITE_EVENT_DATA 0x00760005 |
58 | #define SCLP_CMDW_WRITE_EVENT_MASK 0x00780005 | 58 | #define SCLP_CMDW_WRITE_EVENT_MASK 0x00780005 |
59 | #define SCLP_CMDW_READ_SCP_INFO 0x00020001 | ||
60 | #define SCLP_CMDW_READ_SCP_INFO_FORCED 0x00120001 | ||
61 | 59 | ||
62 | #define GDS_ID_MDSMU 0x1310 | 60 | #define GDS_ID_MDSMU 0x1310 |
63 | #define GDS_ID_MDSROUTEINFO 0x1311 | 61 | #define GDS_ID_MDSROUTEINFO 0x1311 |
@@ -83,6 +81,8 @@ extern u64 sclp_facilities; | |||
83 | 81 | ||
84 | #define SCLP_HAS_CHP_INFO (sclp_facilities & 0x8000000000000000ULL) | 82 | #define SCLP_HAS_CHP_INFO (sclp_facilities & 0x8000000000000000ULL) |
85 | #define SCLP_HAS_CHP_RECONFIG (sclp_facilities & 0x2000000000000000ULL) | 83 | #define SCLP_HAS_CHP_RECONFIG (sclp_facilities & 0x2000000000000000ULL) |
84 | #define SCLP_HAS_CPU_INFO (sclp_facilities & 0x0800000000000000ULL) | ||
85 | #define SCLP_HAS_CPU_RECONFIG (sclp_facilities & 0x0400000000000000ULL) | ||
86 | 86 | ||
87 | struct gds_subvector { | 87 | struct gds_subvector { |
88 | u8 length; | 88 | u8 length; |
diff --git a/drivers/s390/char/sclp_chp.c b/drivers/s390/char/sclp_chp.c deleted file mode 100644 index c68f5e7e63a0..000000000000 --- a/drivers/s390/char/sclp_chp.c +++ /dev/null | |||
@@ -1,200 +0,0 @@ | |||
1 | /* | ||
2 | * drivers/s390/char/sclp_chp.c | ||
3 | * | ||
4 | * Copyright IBM Corp. 2007 | ||
5 | * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com> | ||
6 | */ | ||
7 | |||
8 | #include <linux/types.h> | ||
9 | #include <linux/gfp.h> | ||
10 | #include <linux/errno.h> | ||
11 | #include <linux/completion.h> | ||
12 | #include <asm/sclp.h> | ||
13 | #include <asm/chpid.h> | ||
14 | |||
15 | #include "sclp.h" | ||
16 | |||
17 | #define TAG "sclp_chp: " | ||
18 | |||
19 | #define SCLP_CMDW_CONFIGURE_CHANNEL_PATH 0x000f0001 | ||
20 | #define SCLP_CMDW_DECONFIGURE_CHANNEL_PATH 0x000e0001 | ||
21 | #define SCLP_CMDW_READ_CHANNEL_PATH_INFORMATION 0x00030001 | ||
22 | |||
23 | static inline sclp_cmdw_t get_configure_cmdw(struct chp_id chpid) | ||
24 | { | ||
25 | return SCLP_CMDW_CONFIGURE_CHANNEL_PATH | chpid.id << 8; | ||
26 | } | ||
27 | |||
28 | static inline sclp_cmdw_t get_deconfigure_cmdw(struct chp_id chpid) | ||
29 | { | ||
30 | return SCLP_CMDW_DECONFIGURE_CHANNEL_PATH | chpid.id << 8; | ||
31 | } | ||
32 | |||
33 | static void chp_callback(struct sclp_req *req, void *data) | ||
34 | { | ||
35 | struct completion *completion = data; | ||
36 | |||
37 | complete(completion); | ||
38 | } | ||
39 | |||
40 | struct chp_cfg_sccb { | ||
41 | struct sccb_header header; | ||
42 | u8 ccm; | ||
43 | u8 reserved[6]; | ||
44 | u8 cssid; | ||
45 | } __attribute__((packed)); | ||
46 | |||
47 | struct chp_cfg_data { | ||
48 | struct chp_cfg_sccb sccb; | ||
49 | struct sclp_req req; | ||
50 | struct completion completion; | ||
51 | } __attribute__((packed)); | ||
52 | |||
53 | static int do_configure(sclp_cmdw_t cmd) | ||
54 | { | ||
55 | struct chp_cfg_data *data; | ||
56 | int rc; | ||
57 | |||
58 | if (!SCLP_HAS_CHP_RECONFIG) | ||
59 | return -EOPNOTSUPP; | ||
60 | /* Prepare sccb. */ | ||
61 | data = (struct chp_cfg_data *) get_zeroed_page(GFP_KERNEL | GFP_DMA); | ||
62 | if (!data) | ||
63 | return -ENOMEM; | ||
64 | data->sccb.header.length = sizeof(struct chp_cfg_sccb); | ||
65 | data->req.command = cmd; | ||
66 | data->req.sccb = &(data->sccb); | ||
67 | data->req.status = SCLP_REQ_FILLED; | ||
68 | data->req.callback = chp_callback; | ||
69 | data->req.callback_data = &(data->completion); | ||
70 | init_completion(&data->completion); | ||
71 | |||
72 | /* Perform sclp request. */ | ||
73 | rc = sclp_add_request(&(data->req)); | ||
74 | if (rc) | ||
75 | goto out; | ||
76 | wait_for_completion(&data->completion); | ||
77 | |||
78 | /* Check response .*/ | ||
79 | if (data->req.status != SCLP_REQ_DONE) { | ||
80 | printk(KERN_WARNING TAG "configure channel-path request failed " | ||
81 | "(status=0x%02x)\n", data->req.status); | ||
82 | rc = -EIO; | ||
83 | goto out; | ||
84 | } | ||
85 | switch (data->sccb.header.response_code) { | ||
86 | case 0x0020: | ||
87 | case 0x0120: | ||
88 | case 0x0440: | ||
89 | case 0x0450: | ||
90 | break; | ||
91 | default: | ||
92 | printk(KERN_WARNING TAG "configure channel-path failed " | ||
93 | "(cmd=0x%08x, response=0x%04x)\n", cmd, | ||
94 | data->sccb.header.response_code); | ||
95 | rc = -EIO; | ||
96 | break; | ||
97 | } | ||
98 | out: | ||
99 | free_page((unsigned long) data); | ||
100 | |||
101 | return rc; | ||
102 | } | ||
103 | |||
104 | /** | ||
105 | * sclp_chp_configure - perform configure channel-path sclp command | ||
106 | * @chpid: channel-path ID | ||
107 | * | ||
108 | * Perform configure channel-path command sclp command for specified chpid. | ||
109 | * Return 0 after command successfully finished, non-zero otherwise. | ||
110 | */ | ||
111 | int sclp_chp_configure(struct chp_id chpid) | ||
112 | { | ||
113 | return do_configure(get_configure_cmdw(chpid)); | ||
114 | } | ||
115 | |||
116 | /** | ||
117 | * sclp_chp_deconfigure - perform deconfigure channel-path sclp command | ||
118 | * @chpid: channel-path ID | ||
119 | * | ||
120 | * Perform deconfigure channel-path command sclp command for specified chpid | ||
121 | * and wait for completion. On success return 0. Return non-zero otherwise. | ||
122 | */ | ||
123 | int sclp_chp_deconfigure(struct chp_id chpid) | ||
124 | { | ||
125 | return do_configure(get_deconfigure_cmdw(chpid)); | ||
126 | } | ||
127 | |||
128 | struct chp_info_sccb { | ||
129 | struct sccb_header header; | ||
130 | u8 recognized[SCLP_CHP_INFO_MASK_SIZE]; | ||
131 | u8 standby[SCLP_CHP_INFO_MASK_SIZE]; | ||
132 | u8 configured[SCLP_CHP_INFO_MASK_SIZE]; | ||
133 | u8 ccm; | ||
134 | u8 reserved[6]; | ||
135 | u8 cssid; | ||
136 | } __attribute__((packed)); | ||
137 | |||
138 | struct chp_info_data { | ||
139 | struct chp_info_sccb sccb; | ||
140 | struct sclp_req req; | ||
141 | struct completion completion; | ||
142 | } __attribute__((packed)); | ||
143 | |||
144 | /** | ||
145 | * sclp_chp_read_info - perform read channel-path information sclp command | ||
146 | * @info: resulting channel-path information data | ||
147 | * | ||
148 | * Perform read channel-path information sclp command and wait for completion. | ||
149 | * On success, store channel-path information in @info and return 0. Return | ||
150 | * non-zero otherwise. | ||
151 | */ | ||
152 | int sclp_chp_read_info(struct sclp_chp_info *info) | ||
153 | { | ||
154 | struct chp_info_data *data; | ||
155 | int rc; | ||
156 | |||
157 | if (!SCLP_HAS_CHP_INFO) | ||
158 | return -EOPNOTSUPP; | ||
159 | /* Prepare sccb. */ | ||
160 | data = (struct chp_info_data *) get_zeroed_page(GFP_KERNEL | GFP_DMA); | ||
161 | if (!data) | ||
162 | return -ENOMEM; | ||
163 | data->sccb.header.length = sizeof(struct chp_info_sccb); | ||
164 | data->req.command = SCLP_CMDW_READ_CHANNEL_PATH_INFORMATION; | ||
165 | data->req.sccb = &(data->sccb); | ||
166 | data->req.status = SCLP_REQ_FILLED; | ||
167 | data->req.callback = chp_callback; | ||
168 | data->req.callback_data = &(data->completion); | ||
169 | init_completion(&data->completion); | ||
170 | |||
171 | /* Perform sclp request. */ | ||
172 | rc = sclp_add_request(&(data->req)); | ||
173 | if (rc) | ||
174 | goto out; | ||
175 | wait_for_completion(&data->completion); | ||
176 | |||
177 | /* Check response .*/ | ||
178 | if (data->req.status != SCLP_REQ_DONE) { | ||
179 | printk(KERN_WARNING TAG "read channel-path info request failed " | ||
180 | "(status=0x%02x)\n", data->req.status); | ||
181 | rc = -EIO; | ||
182 | goto out; | ||
183 | } | ||
184 | if (data->sccb.header.response_code != 0x0010) { | ||
185 | printk(KERN_WARNING TAG "read channel-path info failed " | ||
186 | "(response=0x%04x)\n", data->sccb.header.response_code); | ||
187 | rc = -EIO; | ||
188 | goto out; | ||
189 | } | ||
190 | memcpy(info->recognized, data->sccb.recognized, | ||
191 | SCLP_CHP_INFO_MASK_SIZE); | ||
192 | memcpy(info->standby, data->sccb.standby, | ||
193 | SCLP_CHP_INFO_MASK_SIZE); | ||
194 | memcpy(info->configured, data->sccb.configured, | ||
195 | SCLP_CHP_INFO_MASK_SIZE); | ||
196 | out: | ||
197 | free_page((unsigned long) data); | ||
198 | |||
199 | return rc; | ||
200 | } | ||
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c new file mode 100644 index 000000000000..b5c23396f8fe --- /dev/null +++ b/drivers/s390/char/sclp_cmd.c | |||
@@ -0,0 +1,398 @@ | |||
1 | /* | ||
2 | * drivers/s390/char/sclp_cmd.c | ||
3 | * | ||
4 | * Copyright IBM Corp. 2007 | ||
5 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>, | ||
6 | * Peter Oberparleiter <peter.oberparleiter@de.ibm.com> | ||
7 | */ | ||
8 | |||
9 | #include <linux/completion.h> | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/errno.h> | ||
12 | #include <linux/slab.h> | ||
13 | #include <linux/string.h> | ||
14 | #include <asm/chpid.h> | ||
15 | #include <asm/sclp.h> | ||
16 | #include "sclp.h" | ||
17 | |||
18 | #define TAG "sclp_cmd: " | ||
19 | |||
20 | #define SCLP_CMDW_READ_SCP_INFO 0x00020001 | ||
21 | #define SCLP_CMDW_READ_SCP_INFO_FORCED 0x00120001 | ||
22 | |||
23 | struct read_info_sccb { | ||
24 | struct sccb_header header; /* 0-7 */ | ||
25 | u16 rnmax; /* 8-9 */ | ||
26 | u8 rnsize; /* 10 */ | ||
27 | u8 _reserved0[24 - 11]; /* 11-15 */ | ||
28 | u8 loadparm[8]; /* 24-31 */ | ||
29 | u8 _reserved1[48 - 32]; /* 32-47 */ | ||
30 | u64 facilities; /* 48-55 */ | ||
31 | u8 _reserved2[84 - 56]; /* 56-83 */ | ||
32 | u8 fac84; /* 84 */ | ||
33 | u8 _reserved3[91 - 85]; /* 85-90 */ | ||
34 | u8 flags; /* 91 */ | ||
35 | u8 _reserved4[100 - 92]; /* 92-99 */ | ||
36 | u32 rnsize2; /* 100-103 */ | ||
37 | u64 rnmax2; /* 104-111 */ | ||
38 | u8 _reserved5[4096 - 112]; /* 112-4095 */ | ||
39 | } __attribute__((packed, aligned(PAGE_SIZE))); | ||
40 | |||
41 | static struct read_info_sccb __initdata early_read_info_sccb; | ||
42 | static int __initdata early_read_info_sccb_valid; | ||
43 | |||
44 | u64 sclp_facilities; | ||
45 | static u8 sclp_fac84; | ||
46 | |||
47 | static int __init sclp_cmd_sync_early(sclp_cmdw_t cmd, void *sccb) | ||
48 | { | ||
49 | int rc; | ||
50 | |||
51 | __ctl_set_bit(0, 9); | ||
52 | rc = sclp_service_call(cmd, sccb); | ||
53 | if (rc) | ||
54 | goto out; | ||
55 | __load_psw_mask(PSW_BASE_BITS | PSW_MASK_EXT | | ||
56 | PSW_MASK_WAIT | PSW_DEFAULT_KEY); | ||
57 | local_irq_disable(); | ||
58 | out: | ||
59 | /* Contents of the sccb might have changed. */ | ||
60 | barrier(); | ||
61 | __ctl_clear_bit(0, 9); | ||
62 | return rc; | ||
63 | } | ||
64 | |||
65 | void __init sclp_read_info_early(void) | ||
66 | { | ||
67 | int rc; | ||
68 | int i; | ||
69 | struct read_info_sccb *sccb; | ||
70 | sclp_cmdw_t commands[] = {SCLP_CMDW_READ_SCP_INFO_FORCED, | ||
71 | SCLP_CMDW_READ_SCP_INFO}; | ||
72 | |||
73 | sccb = &early_read_info_sccb; | ||
74 | for (i = 0; i < ARRAY_SIZE(commands); i++) { | ||
75 | do { | ||
76 | memset(sccb, 0, sizeof(*sccb)); | ||
77 | sccb->header.length = sizeof(*sccb); | ||
78 | sccb->header.control_mask[2] = 0x80; | ||
79 | rc = sclp_cmd_sync_early(commands[i], sccb); | ||
80 | } while (rc == -EBUSY); | ||
81 | |||
82 | if (rc) | ||
83 | break; | ||
84 | if (sccb->header.response_code == 0x10) { | ||
85 | early_read_info_sccb_valid = 1; | ||
86 | break; | ||
87 | } | ||
88 | if (sccb->header.response_code != 0x1f0) | ||
89 | break; | ||
90 | } | ||
91 | } | ||
92 | |||
93 | void __init sclp_facilities_detect(void) | ||
94 | { | ||
95 | if (!early_read_info_sccb_valid) | ||
96 | return; | ||
97 | sclp_facilities = early_read_info_sccb.facilities; | ||
98 | sclp_fac84 = early_read_info_sccb.fac84; | ||
99 | } | ||
100 | |||
101 | unsigned long long __init sclp_memory_detect(void) | ||
102 | { | ||
103 | unsigned long long memsize; | ||
104 | struct read_info_sccb *sccb; | ||
105 | |||
106 | if (!early_read_info_sccb_valid) | ||
107 | return 0; | ||
108 | sccb = &early_read_info_sccb; | ||
109 | if (sccb->rnsize) | ||
110 | memsize = sccb->rnsize << 20; | ||
111 | else | ||
112 | memsize = sccb->rnsize2 << 20; | ||
113 | if (sccb->rnmax) | ||
114 | memsize *= sccb->rnmax; | ||
115 | else | ||
116 | memsize *= sccb->rnmax2; | ||
117 | return memsize; | ||
118 | } | ||
119 | |||
120 | /* | ||
121 | * This function will be called after sclp_memory_detect(), which gets called | ||
122 | * early from early.c code. Therefore the sccb should have valid contents. | ||
123 | */ | ||
124 | void __init sclp_get_ipl_info(struct sclp_ipl_info *info) | ||
125 | { | ||
126 | struct read_info_sccb *sccb; | ||
127 | |||
128 | if (!early_read_info_sccb_valid) | ||
129 | return; | ||
130 | sccb = &early_read_info_sccb; | ||
131 | info->is_valid = 1; | ||
132 | if (sccb->flags & 0x2) | ||
133 | info->has_dump = 1; | ||
134 | memcpy(&info->loadparm, &sccb->loadparm, LOADPARM_LEN); | ||
135 | } | ||
136 | |||
137 | static void sclp_sync_callback(struct sclp_req *req, void *data) | ||
138 | { | ||
139 | struct completion *completion = data; | ||
140 | |||
141 | complete(completion); | ||
142 | } | ||
143 | |||
144 | static int do_sync_request(sclp_cmdw_t cmd, void *sccb) | ||
145 | { | ||
146 | struct completion completion; | ||
147 | struct sclp_req *request; | ||
148 | int rc; | ||
149 | |||
150 | request = kzalloc(sizeof(*request), GFP_KERNEL); | ||
151 | if (!request) | ||
152 | return -ENOMEM; | ||
153 | request->command = cmd; | ||
154 | request->sccb = sccb; | ||
155 | request->status = SCLP_REQ_FILLED; | ||
156 | request->callback = sclp_sync_callback; | ||
157 | request->callback_data = &completion; | ||
158 | init_completion(&completion); | ||
159 | |||
160 | /* Perform sclp request. */ | ||
161 | rc = sclp_add_request(request); | ||
162 | if (rc) | ||
163 | goto out; | ||
164 | wait_for_completion(&completion); | ||
165 | |||
166 | /* Check response. */ | ||
167 | if (request->status != SCLP_REQ_DONE) { | ||
168 | printk(KERN_WARNING TAG "sync request failed " | ||
169 | "(cmd=0x%08x, status=0x%02x)\n", cmd, request->status); | ||
170 | rc = -EIO; | ||
171 | } | ||
172 | out: | ||
173 | kfree(request); | ||
174 | return rc; | ||
175 | } | ||
176 | |||
177 | /* | ||
178 | * CPU configuration related functions. | ||
179 | */ | ||
180 | |||
181 | #define SCLP_CMDW_READ_CPU_INFO 0x00010001 | ||
182 | #define SCLP_CMDW_CONFIGURE_CPU 0x00110001 | ||
183 | #define SCLP_CMDW_DECONFIGURE_CPU 0x00100001 | ||
184 | |||
185 | struct read_cpu_info_sccb { | ||
186 | struct sccb_header header; | ||
187 | u16 nr_configured; | ||
188 | u16 offset_configured; | ||
189 | u16 nr_standby; | ||
190 | u16 offset_standby; | ||
191 | u8 reserved[4096 - 16]; | ||
192 | } __attribute__((packed, aligned(PAGE_SIZE))); | ||
193 | |||
194 | static void sclp_fill_cpu_info(struct sclp_cpu_info *info, | ||
195 | struct read_cpu_info_sccb *sccb) | ||
196 | { | ||
197 | char *page = (char *) sccb; | ||
198 | |||
199 | memset(info, 0, sizeof(*info)); | ||
200 | info->configured = sccb->nr_configured; | ||
201 | info->standby = sccb->nr_standby; | ||
202 | info->combined = sccb->nr_configured + sccb->nr_standby; | ||
203 | info->has_cpu_type = sclp_fac84 & 0x1; | ||
204 | memcpy(&info->cpu, page + sccb->offset_configured, | ||
205 | info->combined * sizeof(struct sclp_cpu_entry)); | ||
206 | } | ||
207 | |||
208 | int sclp_get_cpu_info(struct sclp_cpu_info *info) | ||
209 | { | ||
210 | int rc; | ||
211 | struct read_cpu_info_sccb *sccb; | ||
212 | |||
213 | if (!SCLP_HAS_CPU_INFO) | ||
214 | return -EOPNOTSUPP; | ||
215 | sccb = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA); | ||
216 | if (!sccb) | ||
217 | return -ENOMEM; | ||
218 | sccb->header.length = sizeof(*sccb); | ||
219 | rc = do_sync_request(SCLP_CMDW_READ_CPU_INFO, sccb); | ||
220 | if (rc) | ||
221 | goto out; | ||
222 | if (sccb->header.response_code != 0x0010) { | ||
223 | printk(KERN_WARNING TAG "readcpuinfo failed " | ||
224 | "(response=0x%04x)\n", sccb->header.response_code); | ||
225 | rc = -EIO; | ||
226 | goto out; | ||
227 | } | ||
228 | sclp_fill_cpu_info(info, sccb); | ||
229 | out: | ||
230 | free_page((unsigned long) sccb); | ||
231 | return rc; | ||
232 | } | ||
233 | |||
234 | struct cpu_configure_sccb { | ||
235 | struct sccb_header header; | ||
236 | } __attribute__((packed, aligned(8))); | ||
237 | |||
238 | static int do_cpu_configure(sclp_cmdw_t cmd) | ||
239 | { | ||
240 | struct cpu_configure_sccb *sccb; | ||
241 | int rc; | ||
242 | |||
243 | if (!SCLP_HAS_CPU_RECONFIG) | ||
244 | return -EOPNOTSUPP; | ||
245 | /* | ||
246 | * This is not going to cross a page boundary since we force | ||
247 | * kmalloc to have a minimum alignment of 8 bytes on s390. | ||
248 | */ | ||
249 | sccb = kzalloc(sizeof(*sccb), GFP_KERNEL | GFP_DMA); | ||
250 | if (!sccb) | ||
251 | return -ENOMEM; | ||
252 | sccb->header.length = sizeof(*sccb); | ||
253 | rc = do_sync_request(cmd, sccb); | ||
254 | if (rc) | ||
255 | goto out; | ||
256 | switch (sccb->header.response_code) { | ||
257 | case 0x0020: | ||
258 | case 0x0120: | ||
259 | break; | ||
260 | default: | ||
261 | printk(KERN_WARNING TAG "configure cpu failed (cmd=0x%08x, " | ||
262 | "response=0x%04x)\n", cmd, sccb->header.response_code); | ||
263 | rc = -EIO; | ||
264 | break; | ||
265 | } | ||
266 | out: | ||
267 | kfree(sccb); | ||
268 | return rc; | ||
269 | } | ||
270 | |||
271 | int sclp_cpu_configure(u8 cpu) | ||
272 | { | ||
273 | return do_cpu_configure(SCLP_CMDW_CONFIGURE_CPU | cpu << 8); | ||
274 | } | ||
275 | |||
276 | int sclp_cpu_deconfigure(u8 cpu) | ||
277 | { | ||
278 | return do_cpu_configure(SCLP_CMDW_DECONFIGURE_CPU | cpu << 8); | ||
279 | } | ||
280 | |||
281 | /* | ||
282 | * Channel path configuration related functions. | ||
283 | */ | ||
284 | |||
285 | #define SCLP_CMDW_CONFIGURE_CHPATH 0x000f0001 | ||
286 | #define SCLP_CMDW_DECONFIGURE_CHPATH 0x000e0001 | ||
287 | #define SCLP_CMDW_READ_CHPATH_INFORMATION 0x00030001 | ||
288 | |||
289 | struct chp_cfg_sccb { | ||
290 | struct sccb_header header; | ||
291 | u8 ccm; | ||
292 | u8 reserved[6]; | ||
293 | u8 cssid; | ||
294 | } __attribute__((packed)); | ||
295 | |||
296 | static int do_chp_configure(sclp_cmdw_t cmd) | ||
297 | { | ||
298 | struct chp_cfg_sccb *sccb; | ||
299 | int rc; | ||
300 | |||
301 | if (!SCLP_HAS_CHP_RECONFIG) | ||
302 | return -EOPNOTSUPP; | ||
303 | /* Prepare sccb. */ | ||
304 | sccb = (struct chp_cfg_sccb *) get_zeroed_page(GFP_KERNEL | GFP_DMA); | ||
305 | if (!sccb) | ||
306 | return -ENOMEM; | ||
307 | sccb->header.length = sizeof(*sccb); | ||
308 | rc = do_sync_request(cmd, sccb); | ||
309 | if (rc) | ||
310 | goto out; | ||
311 | switch (sccb->header.response_code) { | ||
312 | case 0x0020: | ||
313 | case 0x0120: | ||
314 | case 0x0440: | ||
315 | case 0x0450: | ||
316 | break; | ||
317 | default: | ||
318 | printk(KERN_WARNING TAG "configure channel-path failed " | ||
319 | "(cmd=0x%08x, response=0x%04x)\n", cmd, | ||
320 | sccb->header.response_code); | ||
321 | rc = -EIO; | ||
322 | break; | ||
323 | } | ||
324 | out: | ||
325 | free_page((unsigned long) sccb); | ||
326 | return rc; | ||
327 | } | ||
328 | |||
329 | /** | ||
330 | * sclp_chp_configure - perform configure channel-path sclp command | ||
331 | * @chpid: channel-path ID | ||
332 | * | ||
333 | * Perform configure channel-path command sclp command for specified chpid. | ||
334 | * Return 0 after command successfully finished, non-zero otherwise. | ||
335 | */ | ||
336 | int sclp_chp_configure(struct chp_id chpid) | ||
337 | { | ||
338 | return do_chp_configure(SCLP_CMDW_CONFIGURE_CHPATH | chpid.id << 8); | ||
339 | } | ||
340 | |||
341 | /** | ||
342 | * sclp_chp_deconfigure - perform deconfigure channel-path sclp command | ||
343 | * @chpid: channel-path ID | ||
344 | * | ||
345 | * Perform deconfigure channel-path command sclp command for specified chpid | ||
346 | * and wait for completion. On success return 0. Return non-zero otherwise. | ||
347 | */ | ||
348 | int sclp_chp_deconfigure(struct chp_id chpid) | ||
349 | { | ||
350 | return do_chp_configure(SCLP_CMDW_DECONFIGURE_CHPATH | chpid.id << 8); | ||
351 | } | ||
352 | |||
353 | struct chp_info_sccb { | ||
354 | struct sccb_header header; | ||
355 | u8 recognized[SCLP_CHP_INFO_MASK_SIZE]; | ||
356 | u8 standby[SCLP_CHP_INFO_MASK_SIZE]; | ||
357 | u8 configured[SCLP_CHP_INFO_MASK_SIZE]; | ||
358 | u8 ccm; | ||
359 | u8 reserved[6]; | ||
360 | u8 cssid; | ||
361 | } __attribute__((packed)); | ||
362 | |||
363 | /** | ||
364 | * sclp_chp_read_info - perform read channel-path information sclp command | ||
365 | * @info: resulting channel-path information data | ||
366 | * | ||
367 | * Perform read channel-path information sclp command and wait for completion. | ||
368 | * On success, store channel-path information in @info and return 0. Return | ||
369 | * non-zero otherwise. | ||
370 | */ | ||
371 | int sclp_chp_read_info(struct sclp_chp_info *info) | ||
372 | { | ||
373 | struct chp_info_sccb *sccb; | ||
374 | int rc; | ||
375 | |||
376 | if (!SCLP_HAS_CHP_INFO) | ||
377 | return -EOPNOTSUPP; | ||
378 | /* Prepare sccb. */ | ||
379 | sccb = (struct chp_info_sccb *) get_zeroed_page(GFP_KERNEL | GFP_DMA); | ||
380 | if (!sccb) | ||
381 | return -ENOMEM; | ||
382 | sccb->header.length = sizeof(*sccb); | ||
383 | rc = do_sync_request(SCLP_CMDW_READ_CHPATH_INFORMATION, sccb); | ||
384 | if (rc) | ||
385 | goto out; | ||
386 | if (sccb->header.response_code != 0x0010) { | ||
387 | printk(KERN_WARNING TAG "read channel-path info failed " | ||
388 | "(response=0x%04x)\n", sccb->header.response_code); | ||
389 | rc = -EIO; | ||
390 | goto out; | ||
391 | } | ||
392 | memcpy(info->recognized, sccb->recognized, SCLP_CHP_INFO_MASK_SIZE); | ||
393 | memcpy(info->standby, sccb->standby, SCLP_CHP_INFO_MASK_SIZE); | ||
394 | memcpy(info->configured, sccb->configured, SCLP_CHP_INFO_MASK_SIZE); | ||
395 | out: | ||
396 | free_page((unsigned long) sccb); | ||
397 | return rc; | ||
398 | } | ||
diff --git a/drivers/s390/char/sclp_cpi.c b/drivers/s390/char/sclp_cpi.c index 82a13d9fdfe4..5716487b8c9d 100644 --- a/drivers/s390/char/sclp_cpi.c +++ b/drivers/s390/char/sclp_cpi.c | |||
@@ -1,255 +1,41 @@ | |||
1 | /* | 1 | /* |
2 | * Author: Martin Peschke <mpeschke@de.ibm.com> | 2 | * drivers/s390/char/sclp_cpi.c |
3 | * Copyright (C) 2001 IBM Entwicklung GmbH, IBM Corporation | 3 | * SCLP control programm identification |
4 | * | 4 | * |
5 | * SCLP Control-Program Identification. | 5 | * Copyright IBM Corp. 2001, 2007 |
6 | * Author(s): Martin Peschke <mpeschke@de.ibm.com> | ||
7 | * Michael Ernst <mernst@de.ibm.com> | ||
6 | */ | 8 | */ |
7 | 9 | ||
8 | #include <linux/version.h> | ||
9 | #include <linux/kmod.h> | 10 | #include <linux/kmod.h> |
10 | #include <linux/module.h> | 11 | #include <linux/module.h> |
11 | #include <linux/moduleparam.h> | 12 | #include <linux/moduleparam.h> |
12 | #include <linux/init.h> | 13 | #include <linux/version.h> |
13 | #include <linux/timer.h> | 14 | #include "sclp_cpi_sys.h" |
14 | #include <linux/string.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <asm/ebcdic.h> | ||
18 | #include <asm/semaphore.h> | ||
19 | |||
20 | #include "sclp.h" | ||
21 | #include "sclp_rw.h" | ||
22 | |||
23 | #define CPI_LENGTH_SYSTEM_TYPE 8 | ||
24 | #define CPI_LENGTH_SYSTEM_NAME 8 | ||
25 | #define CPI_LENGTH_SYSPLEX_NAME 8 | ||
26 | |||
27 | struct cpi_evbuf { | ||
28 | struct evbuf_header header; | ||
29 | u8 id_format; | ||
30 | u8 reserved0; | ||
31 | u8 system_type[CPI_LENGTH_SYSTEM_TYPE]; | ||
32 | u64 reserved1; | ||
33 | u8 system_name[CPI_LENGTH_SYSTEM_NAME]; | ||
34 | u64 reserved2; | ||
35 | u64 system_level; | ||
36 | u64 reserved3; | ||
37 | u8 sysplex_name[CPI_LENGTH_SYSPLEX_NAME]; | ||
38 | u8 reserved4[16]; | ||
39 | } __attribute__((packed)); | ||
40 | |||
41 | struct cpi_sccb { | ||
42 | struct sccb_header header; | ||
43 | struct cpi_evbuf cpi_evbuf; | ||
44 | } __attribute__((packed)); | ||
45 | |||
46 | /* Event type structure for write message and write priority message */ | ||
47 | static struct sclp_register sclp_cpi_event = | ||
48 | { | ||
49 | .send_mask = EVTYP_CTLPROGIDENT_MASK | ||
50 | }; | ||
51 | 15 | ||
52 | MODULE_LICENSE("GPL"); | 16 | MODULE_LICENSE("GPL"); |
17 | MODULE_DESCRIPTION("Identify this operating system instance " | ||
18 | "to the System z hardware"); | ||
19 | MODULE_AUTHOR("Martin Peschke <mpeschke@de.ibm.com>, " | ||
20 | "Michael Ernst <mernst@de.ibm.com>"); | ||
53 | 21 | ||
54 | MODULE_AUTHOR( | 22 | static char *system_name = ""; |
55 | "Martin Peschke, IBM Deutschland Entwicklung GmbH " | 23 | static char *sysplex_name = ""; |
56 | "<mpeschke@de.ibm.com>"); | ||
57 | |||
58 | MODULE_DESCRIPTION( | ||
59 | "identify this operating system instance to the S/390 " | ||
60 | "or zSeries hardware"); | ||
61 | 24 | ||
62 | static char *system_name = NULL; | ||
63 | module_param(system_name, charp, 0); | 25 | module_param(system_name, charp, 0); |
64 | MODULE_PARM_DESC(system_name, "e.g. hostname - max. 8 characters"); | 26 | MODULE_PARM_DESC(system_name, "e.g. hostname - max. 8 characters"); |
65 | |||
66 | static char *sysplex_name = NULL; | ||
67 | #ifdef ALLOW_SYSPLEX_NAME | ||
68 | module_param(sysplex_name, charp, 0); | 27 | module_param(sysplex_name, charp, 0); |
69 | MODULE_PARM_DESC(sysplex_name, "if applicable - max. 8 characters"); | 28 | MODULE_PARM_DESC(sysplex_name, "if applicable - max. 8 characters"); |
70 | #endif | ||
71 | |||
72 | /* use default value for this field (as well as for system level) */ | ||
73 | static char *system_type = "LINUX"; | ||
74 | 29 | ||
75 | static int | 30 | static int __init cpi_module_init(void) |
76 | cpi_check_parms(void) | ||
77 | { | 31 | { |
78 | /* reject if no system type specified */ | 32 | return sclp_cpi_set_data(system_name, sysplex_name, "LINUX", |
79 | if (!system_type) { | 33 | LINUX_VERSION_CODE); |
80 | printk("cpi: bug: no system type specified\n"); | ||
81 | return -EINVAL; | ||
82 | } | ||
83 | |||
84 | /* reject if system type larger than 8 characters */ | ||
85 | if (strlen(system_type) > CPI_LENGTH_SYSTEM_NAME) { | ||
86 | printk("cpi: bug: system type has length of %li characters - " | ||
87 | "only %i characters supported\n", | ||
88 | strlen(system_type), CPI_LENGTH_SYSTEM_TYPE); | ||
89 | return -EINVAL; | ||
90 | } | ||
91 | |||
92 | /* reject if no system name specified */ | ||
93 | if (!system_name) { | ||
94 | printk("cpi: no system name specified\n"); | ||
95 | return -EINVAL; | ||
96 | } | ||
97 | |||
98 | /* reject if system name larger than 8 characters */ | ||
99 | if (strlen(system_name) > CPI_LENGTH_SYSTEM_NAME) { | ||
100 | printk("cpi: system name has length of %li characters - " | ||
101 | "only %i characters supported\n", | ||
102 | strlen(system_name), CPI_LENGTH_SYSTEM_NAME); | ||
103 | return -EINVAL; | ||
104 | } | ||
105 | |||
106 | /* reject if specified sysplex name larger than 8 characters */ | ||
107 | if (sysplex_name && strlen(sysplex_name) > CPI_LENGTH_SYSPLEX_NAME) { | ||
108 | printk("cpi: sysplex name has length of %li characters" | ||
109 | " - only %i characters supported\n", | ||
110 | strlen(sysplex_name), CPI_LENGTH_SYSPLEX_NAME); | ||
111 | return -EINVAL; | ||
112 | } | ||
113 | return 0; | ||
114 | } | 34 | } |
115 | 35 | ||
116 | static void | ||
117 | cpi_callback(struct sclp_req *req, void *data) | ||
118 | { | ||
119 | struct semaphore *sem; | ||
120 | |||
121 | sem = (struct semaphore *) data; | ||
122 | up(sem); | ||
123 | } | ||
124 | |||
125 | static struct sclp_req * | ||
126 | cpi_prepare_req(void) | ||
127 | { | ||
128 | struct sclp_req *req; | ||
129 | struct cpi_sccb *sccb; | ||
130 | struct cpi_evbuf *evb; | ||
131 | |||
132 | req = kmalloc(sizeof(struct sclp_req), GFP_KERNEL); | ||
133 | if (req == NULL) | ||
134 | return ERR_PTR(-ENOMEM); | ||
135 | sccb = (struct cpi_sccb *) __get_free_page(GFP_KERNEL | GFP_DMA); | ||
136 | if (sccb == NULL) { | ||
137 | kfree(req); | ||
138 | return ERR_PTR(-ENOMEM); | ||
139 | } | ||
140 | memset(sccb, 0, sizeof(struct cpi_sccb)); | ||
141 | |||
142 | /* setup SCCB for Control-Program Identification */ | ||
143 | sccb->header.length = sizeof(struct cpi_sccb); | ||
144 | sccb->cpi_evbuf.header.length = sizeof(struct cpi_evbuf); | ||
145 | sccb->cpi_evbuf.header.type = 0x0B; | ||
146 | evb = &sccb->cpi_evbuf; | ||
147 | |||
148 | /* set system type */ | ||
149 | memset(evb->system_type, ' ', CPI_LENGTH_SYSTEM_TYPE); | ||
150 | memcpy(evb->system_type, system_type, strlen(system_type)); | ||
151 | sclp_ascebc_str(evb->system_type, CPI_LENGTH_SYSTEM_TYPE); | ||
152 | EBC_TOUPPER(evb->system_type, CPI_LENGTH_SYSTEM_TYPE); | ||
153 | |||
154 | /* set system name */ | ||
155 | memset(evb->system_name, ' ', CPI_LENGTH_SYSTEM_NAME); | ||
156 | memcpy(evb->system_name, system_name, strlen(system_name)); | ||
157 | sclp_ascebc_str(evb->system_name, CPI_LENGTH_SYSTEM_NAME); | ||
158 | EBC_TOUPPER(evb->system_name, CPI_LENGTH_SYSTEM_NAME); | ||
159 | |||
160 | /* set system level */ | ||
161 | evb->system_level = LINUX_VERSION_CODE; | ||
162 | |||
163 | /* set sysplex name */ | ||
164 | if (sysplex_name) { | ||
165 | memset(evb->sysplex_name, ' ', CPI_LENGTH_SYSPLEX_NAME); | ||
166 | memcpy(evb->sysplex_name, sysplex_name, strlen(sysplex_name)); | ||
167 | sclp_ascebc_str(evb->sysplex_name, CPI_LENGTH_SYSPLEX_NAME); | ||
168 | EBC_TOUPPER(evb->sysplex_name, CPI_LENGTH_SYSPLEX_NAME); | ||
169 | } | ||
170 | |||
171 | /* prepare request data structure presented to SCLP driver */ | ||
172 | req->command = SCLP_CMDW_WRITE_EVENT_DATA; | ||
173 | req->sccb = sccb; | ||
174 | req->status = SCLP_REQ_FILLED; | ||
175 | req->callback = cpi_callback; | ||
176 | return req; | ||
177 | } | ||
178 | |||
179 | static void | ||
180 | cpi_free_req(struct sclp_req *req) | ||
181 | { | ||
182 | free_page((unsigned long) req->sccb); | ||
183 | kfree(req); | ||
184 | } | ||
185 | |||
186 | static int __init | ||
187 | cpi_module_init(void) | ||
188 | { | ||
189 | struct semaphore sem; | ||
190 | struct sclp_req *req; | ||
191 | int rc; | ||
192 | |||
193 | rc = cpi_check_parms(); | ||
194 | if (rc) | ||
195 | return rc; | ||
196 | |||
197 | rc = sclp_register(&sclp_cpi_event); | ||
198 | if (rc) { | ||
199 | /* could not register sclp event. Die. */ | ||
200 | printk(KERN_WARNING "cpi: could not register to hardware " | ||
201 | "console.\n"); | ||
202 | return -EINVAL; | ||
203 | } | ||
204 | if (!(sclp_cpi_event.sclp_send_mask & EVTYP_CTLPROGIDENT_MASK)) { | ||
205 | printk(KERN_WARNING "cpi: no control program identification " | ||
206 | "support\n"); | ||
207 | sclp_unregister(&sclp_cpi_event); | ||
208 | return -EOPNOTSUPP; | ||
209 | } | ||
210 | |||
211 | req = cpi_prepare_req(); | ||
212 | if (IS_ERR(req)) { | ||
213 | printk(KERN_WARNING "cpi: couldn't allocate request\n"); | ||
214 | sclp_unregister(&sclp_cpi_event); | ||
215 | return PTR_ERR(req); | ||
216 | } | ||
217 | |||
218 | /* Prepare semaphore */ | ||
219 | sema_init(&sem, 0); | ||
220 | req->callback_data = &sem; | ||
221 | /* Add request to sclp queue */ | ||
222 | rc = sclp_add_request(req); | ||
223 | if (rc) { | ||
224 | printk(KERN_WARNING "cpi: could not start request\n"); | ||
225 | cpi_free_req(req); | ||
226 | sclp_unregister(&sclp_cpi_event); | ||
227 | return rc; | ||
228 | } | ||
229 | /* make "insmod" sleep until callback arrives */ | ||
230 | down(&sem); | ||
231 | |||
232 | rc = ((struct cpi_sccb *) req->sccb)->header.response_code; | ||
233 | if (rc != 0x0020) { | ||
234 | printk(KERN_WARNING "cpi: failed with response code 0x%x\n", | ||
235 | rc); | ||
236 | rc = -ECOMM; | ||
237 | } else | ||
238 | rc = 0; | ||
239 | |||
240 | cpi_free_req(req); | ||
241 | sclp_unregister(&sclp_cpi_event); | ||
242 | |||
243 | return rc; | ||
244 | } | ||
245 | |||
246 | |||
247 | static void __exit cpi_module_exit(void) | 36 | static void __exit cpi_module_exit(void) |
248 | { | 37 | { |
249 | } | 38 | } |
250 | 39 | ||
251 | |||
252 | /* declare driver module init/cleanup functions */ | ||
253 | module_init(cpi_module_init); | 40 | module_init(cpi_module_init); |
254 | module_exit(cpi_module_exit); | 41 | module_exit(cpi_module_exit); |
255 | |||
diff --git a/drivers/s390/char/sclp_cpi_sys.c b/drivers/s390/char/sclp_cpi_sys.c new file mode 100644 index 000000000000..41617032afdc --- /dev/null +++ b/drivers/s390/char/sclp_cpi_sys.c | |||
@@ -0,0 +1,400 @@ | |||
1 | /* | ||
2 | * drivers/s390/char/sclp_cpi_sys.c | ||
3 | * SCLP control program identification sysfs interface | ||
4 | * | ||
5 | * Copyright IBM Corp. 2001, 2007 | ||
6 | * Author(s): Martin Peschke <mpeschke@de.ibm.com> | ||
7 | * Michael Ernst <mernst@de.ibm.com> | ||
8 | */ | ||
9 | |||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/stat.h> | ||
13 | #include <linux/device.h> | ||
14 | #include <linux/string.h> | ||
15 | #include <linux/ctype.h> | ||
16 | #include <linux/kmod.h> | ||
17 | #include <linux/timer.h> | ||
18 | #include <linux/err.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/completion.h> | ||
21 | #include <asm/ebcdic.h> | ||
22 | #include <asm/sclp.h> | ||
23 | #include "sclp.h" | ||
24 | #include "sclp_rw.h" | ||
25 | #include "sclp_cpi_sys.h" | ||
26 | |||
27 | #define CPI_LENGTH_NAME 8 | ||
28 | #define CPI_LENGTH_LEVEL 16 | ||
29 | |||
30 | struct cpi_evbuf { | ||
31 | struct evbuf_header header; | ||
32 | u8 id_format; | ||
33 | u8 reserved0; | ||
34 | u8 system_type[CPI_LENGTH_NAME]; | ||
35 | u64 reserved1; | ||
36 | u8 system_name[CPI_LENGTH_NAME]; | ||
37 | u64 reserved2; | ||
38 | u64 system_level; | ||
39 | u64 reserved3; | ||
40 | u8 sysplex_name[CPI_LENGTH_NAME]; | ||
41 | u8 reserved4[16]; | ||
42 | } __attribute__((packed)); | ||
43 | |||
44 | struct cpi_sccb { | ||
45 | struct sccb_header header; | ||
46 | struct cpi_evbuf cpi_evbuf; | ||
47 | } __attribute__((packed)); | ||
48 | |||
49 | static struct sclp_register sclp_cpi_event = { | ||
50 | .send_mask = EVTYP_CTLPROGIDENT_MASK, | ||
51 | }; | ||
52 | |||
53 | static char system_name[CPI_LENGTH_NAME + 1]; | ||
54 | static char sysplex_name[CPI_LENGTH_NAME + 1]; | ||
55 | static char system_type[CPI_LENGTH_NAME + 1]; | ||
56 | static u64 system_level; | ||
57 | |||
58 | static void set_data(char *field, char *data) | ||
59 | { | ||
60 | memset(field, ' ', CPI_LENGTH_NAME); | ||
61 | memcpy(field, data, strlen(data)); | ||
62 | sclp_ascebc_str(field, CPI_LENGTH_NAME); | ||
63 | } | ||
64 | |||
65 | static void cpi_callback(struct sclp_req *req, void *data) | ||
66 | { | ||
67 | struct completion *completion = data; | ||
68 | |||
69 | complete(completion); | ||
70 | } | ||
71 | |||
72 | static struct sclp_req *cpi_prepare_req(void) | ||
73 | { | ||
74 | struct sclp_req *req; | ||
75 | struct cpi_sccb *sccb; | ||
76 | struct cpi_evbuf *evb; | ||
77 | |||
78 | req = kzalloc(sizeof(struct sclp_req), GFP_KERNEL); | ||
79 | if (!req) | ||
80 | return ERR_PTR(-ENOMEM); | ||
81 | sccb = (struct cpi_sccb *) get_zeroed_page(GFP_KERNEL | GFP_DMA); | ||
82 | if (!sccb) { | ||
83 | kfree(req); | ||
84 | return ERR_PTR(-ENOMEM); | ||
85 | } | ||
86 | |||
87 | /* setup SCCB for Control-Program Identification */ | ||
88 | sccb->header.length = sizeof(struct cpi_sccb); | ||
89 | sccb->cpi_evbuf.header.length = sizeof(struct cpi_evbuf); | ||
90 | sccb->cpi_evbuf.header.type = 0x0b; | ||
91 | evb = &sccb->cpi_evbuf; | ||
92 | |||
93 | /* set system type */ | ||
94 | set_data(evb->system_type, system_type); | ||
95 | |||
96 | /* set system name */ | ||
97 | set_data(evb->system_name, system_name); | ||
98 | |||
99 | /* set sytem level */ | ||
100 | evb->system_level = system_level; | ||
101 | |||
102 | /* set sysplex name */ | ||
103 | set_data(evb->sysplex_name, sysplex_name); | ||
104 | |||
105 | /* prepare request data structure presented to SCLP driver */ | ||
106 | req->command = SCLP_CMDW_WRITE_EVENT_DATA; | ||
107 | req->sccb = sccb; | ||
108 | req->status = SCLP_REQ_FILLED; | ||
109 | req->callback = cpi_callback; | ||
110 | return req; | ||
111 | } | ||
112 | |||
113 | static void cpi_free_req(struct sclp_req *req) | ||
114 | { | ||
115 | free_page((unsigned long) req->sccb); | ||
116 | kfree(req); | ||
117 | } | ||
118 | |||
119 | static int cpi_req(void) | ||
120 | { | ||
121 | struct completion completion; | ||
122 | struct sclp_req *req; | ||
123 | int rc; | ||
124 | int response; | ||
125 | |||
126 | rc = sclp_register(&sclp_cpi_event); | ||
127 | if (rc) { | ||
128 | printk(KERN_WARNING "cpi: could not register " | ||
129 | "to hardware console.\n"); | ||
130 | goto out; | ||
131 | } | ||
132 | if (!(sclp_cpi_event.sclp_send_mask & EVTYP_CTLPROGIDENT_MASK)) { | ||
133 | printk(KERN_WARNING "cpi: no control program " | ||
134 | "identification support\n"); | ||
135 | rc = -EOPNOTSUPP; | ||
136 | goto out_unregister; | ||
137 | } | ||
138 | |||
139 | req = cpi_prepare_req(); | ||
140 | if (IS_ERR(req)) { | ||
141 | printk(KERN_WARNING "cpi: could not allocate request\n"); | ||
142 | rc = PTR_ERR(req); | ||
143 | goto out_unregister; | ||
144 | } | ||
145 | |||
146 | init_completion(&completion); | ||
147 | req->callback_data = &completion; | ||
148 | |||
149 | /* Add request to sclp queue */ | ||
150 | rc = sclp_add_request(req); | ||
151 | if (rc) { | ||
152 | printk(KERN_WARNING "cpi: could not start request\n"); | ||
153 | goto out_free_req; | ||
154 | } | ||
155 | |||
156 | wait_for_completion(&completion); | ||
157 | |||
158 | if (req->status != SCLP_REQ_DONE) { | ||
159 | printk(KERN_WARNING "cpi: request failed (status=0x%02x)\n", | ||
160 | req->status); | ||
161 | rc = -EIO; | ||
162 | goto out_free_req; | ||
163 | } | ||
164 | |||
165 | response = ((struct cpi_sccb *) req->sccb)->header.response_code; | ||
166 | if (response != 0x0020) { | ||
167 | printk(KERN_WARNING "cpi: failed with " | ||
168 | "response code 0x%x\n", response); | ||
169 | rc = -EIO; | ||
170 | } | ||
171 | |||
172 | out_free_req: | ||
173 | cpi_free_req(req); | ||
174 | |||
175 | out_unregister: | ||
176 | sclp_unregister(&sclp_cpi_event); | ||
177 | |||
178 | out: | ||
179 | return rc; | ||
180 | } | ||
181 | |||
182 | static int check_string(const char *attr, const char *str) | ||
183 | { | ||
184 | size_t len; | ||
185 | size_t i; | ||
186 | |||
187 | len = strlen(str); | ||
188 | |||
189 | if ((len > 0) && (str[len - 1] == '\n')) | ||
190 | len--; | ||
191 | |||
192 | if (len > CPI_LENGTH_NAME) | ||
193 | return -EINVAL; | ||
194 | |||
195 | for (i = 0; i < len ; i++) { | ||
196 | if (isalpha(str[i]) || isdigit(str[i]) || | ||
197 | strchr("$@# ", str[i])) | ||
198 | continue; | ||
199 | return -EINVAL; | ||
200 | } | ||
201 | |||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | static void set_string(char *attr, const char *value) | ||
206 | { | ||
207 | size_t len; | ||
208 | size_t i; | ||
209 | |||
210 | len = strlen(value); | ||
211 | |||
212 | if ((len > 0) && (value[len - 1] == '\n')) | ||
213 | len--; | ||
214 | |||
215 | for (i = 0; i < CPI_LENGTH_NAME; i++) { | ||
216 | if (i < len) | ||
217 | attr[i] = toupper(value[i]); | ||
218 | else | ||
219 | attr[i] = ' '; | ||
220 | } | ||
221 | } | ||
222 | |||
223 | static ssize_t system_name_show(struct kobject *kobj, | ||
224 | struct kobj_attribute *attr, char *page) | ||
225 | { | ||
226 | return snprintf(page, PAGE_SIZE, "%s\n", system_name); | ||
227 | } | ||
228 | |||
229 | static ssize_t system_name_store(struct kobject *kobj, | ||
230 | struct kobj_attribute *attr, | ||
231 | const char *buf, | ||
232 | size_t len) | ||
233 | { | ||
234 | int rc; | ||
235 | |||
236 | rc = check_string("system_name", buf); | ||
237 | if (rc) | ||
238 | return rc; | ||
239 | |||
240 | set_string(system_name, buf); | ||
241 | |||
242 | return len; | ||
243 | } | ||
244 | |||
245 | static struct kobj_attribute system_name_attr = | ||
246 | __ATTR(system_name, 0644, system_name_show, system_name_store); | ||
247 | |||
248 | static ssize_t sysplex_name_show(struct kobject *kobj, | ||
249 | struct kobj_attribute *attr, char *page) | ||
250 | { | ||
251 | return snprintf(page, PAGE_SIZE, "%s\n", sysplex_name); | ||
252 | } | ||
253 | |||
254 | static ssize_t sysplex_name_store(struct kobject *kobj, | ||
255 | struct kobj_attribute *attr, | ||
256 | const char *buf, | ||
257 | size_t len) | ||
258 | { | ||
259 | int rc; | ||
260 | |||
261 | rc = check_string("sysplex_name", buf); | ||
262 | if (rc) | ||
263 | return rc; | ||
264 | |||
265 | set_string(sysplex_name, buf); | ||
266 | |||
267 | return len; | ||
268 | } | ||
269 | |||
270 | static struct kobj_attribute sysplex_name_attr = | ||
271 | __ATTR(sysplex_name, 0644, sysplex_name_show, sysplex_name_store); | ||
272 | |||
273 | static ssize_t system_type_show(struct kobject *kobj, | ||
274 | struct kobj_attribute *attr, char *page) | ||
275 | { | ||
276 | return snprintf(page, PAGE_SIZE, "%s\n", system_type); | ||
277 | } | ||
278 | |||
279 | static ssize_t system_type_store(struct kobject *kobj, | ||
280 | struct kobj_attribute *attr, | ||
281 | const char *buf, | ||
282 | size_t len) | ||
283 | { | ||
284 | int rc; | ||
285 | |||
286 | rc = check_string("system_type", buf); | ||
287 | if (rc) | ||
288 | return rc; | ||
289 | |||
290 | set_string(system_type, buf); | ||
291 | |||
292 | return len; | ||
293 | } | ||
294 | |||
295 | static struct kobj_attribute system_type_attr = | ||
296 | __ATTR(system_type, 0644, system_type_show, system_type_store); | ||
297 | |||
298 | static ssize_t system_level_show(struct kobject *kobj, | ||
299 | struct kobj_attribute *attr, char *page) | ||
300 | { | ||
301 | unsigned long long level = system_level; | ||
302 | |||
303 | return snprintf(page, PAGE_SIZE, "%#018llx\n", level); | ||
304 | } | ||
305 | |||
306 | static ssize_t system_level_store(struct kobject *kobj, | ||
307 | struct kobj_attribute *attr, | ||
308 | const char *buf, | ||
309 | size_t len) | ||
310 | { | ||
311 | unsigned long long level; | ||
312 | char *endp; | ||
313 | |||
314 | level = simple_strtoull(buf, &endp, 16); | ||
315 | |||
316 | if (endp == buf) | ||
317 | return -EINVAL; | ||
318 | if (*endp == '\n') | ||
319 | endp++; | ||
320 | if (*endp) | ||
321 | return -EINVAL; | ||
322 | |||
323 | system_level = level; | ||
324 | |||
325 | return len; | ||
326 | } | ||
327 | |||
328 | static struct kobj_attribute system_level_attr = | ||
329 | __ATTR(system_level, 0644, system_level_show, system_level_store); | ||
330 | |||
331 | static ssize_t set_store(struct kobject *kobj, | ||
332 | struct kobj_attribute *attr, | ||
333 | const char *buf, size_t len) | ||
334 | { | ||
335 | int rc; | ||
336 | |||
337 | rc = cpi_req(); | ||
338 | if (rc) | ||
339 | return rc; | ||
340 | |||
341 | return len; | ||
342 | } | ||
343 | |||
344 | static struct kobj_attribute set_attr = __ATTR(set, 0200, NULL, set_store); | ||
345 | |||
346 | static struct attribute *cpi_attrs[] = { | ||
347 | &system_name_attr.attr, | ||
348 | &sysplex_name_attr.attr, | ||
349 | &system_type_attr.attr, | ||
350 | &system_level_attr.attr, | ||
351 | &set_attr.attr, | ||
352 | NULL, | ||
353 | }; | ||
354 | |||
355 | static struct attribute_group cpi_attr_group = { | ||
356 | .attrs = cpi_attrs, | ||
357 | }; | ||
358 | |||
359 | static struct kset *cpi_kset; | ||
360 | |||
361 | int sclp_cpi_set_data(const char *system, const char *sysplex, const char *type, | ||
362 | const u64 level) | ||
363 | { | ||
364 | int rc; | ||
365 | |||
366 | rc = check_string("system_name", system); | ||
367 | if (rc) | ||
368 | return rc; | ||
369 | rc = check_string("sysplex_name", sysplex); | ||
370 | if (rc) | ||
371 | return rc; | ||
372 | rc = check_string("system_type", type); | ||
373 | if (rc) | ||
374 | return rc; | ||
375 | |||
376 | set_string(system_name, system); | ||
377 | set_string(sysplex_name, sysplex); | ||
378 | set_string(system_type, type); | ||
379 | system_level = level; | ||
380 | |||
381 | return cpi_req(); | ||
382 | } | ||
383 | EXPORT_SYMBOL(sclp_cpi_set_data); | ||
384 | |||
385 | static int __init cpi_init(void) | ||
386 | { | ||
387 | int rc; | ||
388 | |||
389 | cpi_kset = kset_create_and_add("cpi", NULL, firmware_kobj); | ||
390 | if (!cpi_kset) | ||
391 | return -ENOMEM; | ||
392 | |||
393 | rc = sysfs_create_group(&cpi_kset->kobj, &cpi_attr_group); | ||
394 | if (rc) | ||
395 | kset_unregister(cpi_kset); | ||
396 | |||
397 | return rc; | ||
398 | } | ||
399 | |||
400 | __initcall(cpi_init); | ||
diff --git a/drivers/s390/char/sclp_cpi_sys.h b/drivers/s390/char/sclp_cpi_sys.h new file mode 100644 index 000000000000..deef3e6ff496 --- /dev/null +++ b/drivers/s390/char/sclp_cpi_sys.h | |||
@@ -0,0 +1,15 @@ | |||
1 | /* | ||
2 | * drivers/s390/char/sclp_cpi_sys.h | ||
3 | * SCLP control program identification sysfs interface | ||
4 | * | ||
5 | * Copyright IBM Corp. 2007 | ||
6 | * Author(s): Michael Ernst <mernst@de.ibm.com> | ||
7 | */ | ||
8 | |||
9 | #ifndef __SCLP_CPI_SYS_H__ | ||
10 | #define __SCLP_CPI_SYS_H__ | ||
11 | |||
12 | int sclp_cpi_set_data(const char *system, const char *sysplex, | ||
13 | const char *type, u64 level); | ||
14 | |||
15 | #endif /* __SCLP_CPI_SYS_H__ */ | ||
diff --git a/drivers/s390/char/sclp_info.c b/drivers/s390/char/sclp_info.c deleted file mode 100644 index a1136e052750..000000000000 --- a/drivers/s390/char/sclp_info.c +++ /dev/null | |||
@@ -1,116 +0,0 @@ | |||
1 | /* | ||
2 | * drivers/s390/char/sclp_info.c | ||
3 | * | ||
4 | * Copyright IBM Corp. 2007 | ||
5 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> | ||
6 | */ | ||
7 | |||
8 | #include <linux/init.h> | ||
9 | #include <linux/errno.h> | ||
10 | #include <linux/string.h> | ||
11 | #include <asm/sclp.h> | ||
12 | #include "sclp.h" | ||
13 | |||
14 | struct sclp_readinfo_sccb { | ||
15 | struct sccb_header header; /* 0-7 */ | ||
16 | u16 rnmax; /* 8-9 */ | ||
17 | u8 rnsize; /* 10 */ | ||
18 | u8 _reserved0[24 - 11]; /* 11-23 */ | ||
19 | u8 loadparm[8]; /* 24-31 */ | ||
20 | u8 _reserved1[48 - 32]; /* 32-47 */ | ||
21 | u64 facilities; /* 48-55 */ | ||
22 | u8 _reserved2[91 - 56]; /* 56-90 */ | ||
23 | u8 flags; /* 91 */ | ||
24 | u8 _reserved3[100 - 92]; /* 92-99 */ | ||
25 | u32 rnsize2; /* 100-103 */ | ||
26 | u64 rnmax2; /* 104-111 */ | ||
27 | u8 _reserved4[4096 - 112]; /* 112-4095 */ | ||
28 | } __attribute__((packed, aligned(4096))); | ||
29 | |||
30 | static struct sclp_readinfo_sccb __initdata early_readinfo_sccb; | ||
31 | static int __initdata early_readinfo_sccb_valid; | ||
32 | |||
33 | u64 sclp_facilities; | ||
34 | |||
35 | void __init sclp_readinfo_early(void) | ||
36 | { | ||
37 | int ret; | ||
38 | int i; | ||
39 | struct sclp_readinfo_sccb *sccb; | ||
40 | sclp_cmdw_t commands[] = {SCLP_CMDW_READ_SCP_INFO_FORCED, | ||
41 | SCLP_CMDW_READ_SCP_INFO}; | ||
42 | |||
43 | /* Enable service signal subclass mask. */ | ||
44 | __ctl_set_bit(0, 9); | ||
45 | sccb = &early_readinfo_sccb; | ||
46 | for (i = 0; i < ARRAY_SIZE(commands); i++) { | ||
47 | do { | ||
48 | memset(sccb, 0, sizeof(*sccb)); | ||
49 | sccb->header.length = sizeof(*sccb); | ||
50 | sccb->header.control_mask[2] = 0x80; | ||
51 | ret = sclp_service_call(commands[i], sccb); | ||
52 | } while (ret == -EBUSY); | ||
53 | |||
54 | if (ret) | ||
55 | break; | ||
56 | __load_psw_mask(PSW_BASE_BITS | PSW_MASK_EXT | | ||
57 | PSW_MASK_WAIT | PSW_DEFAULT_KEY); | ||
58 | local_irq_disable(); | ||
59 | /* | ||
60 | * Contents of the sccb might have changed | ||
61 | * therefore a barrier is needed. | ||
62 | */ | ||
63 | barrier(); | ||
64 | if (sccb->header.response_code == 0x10) { | ||
65 | early_readinfo_sccb_valid = 1; | ||
66 | break; | ||
67 | } | ||
68 | if (sccb->header.response_code != 0x1f0) | ||
69 | break; | ||
70 | } | ||
71 | /* Disable service signal subclass mask again. */ | ||
72 | __ctl_clear_bit(0, 9); | ||
73 | } | ||
74 | |||
75 | void __init sclp_facilities_detect(void) | ||
76 | { | ||
77 | if (!early_readinfo_sccb_valid) | ||
78 | return; | ||
79 | sclp_facilities = early_readinfo_sccb.facilities; | ||
80 | } | ||
81 | |||
82 | unsigned long long __init sclp_memory_detect(void) | ||
83 | { | ||
84 | unsigned long long memsize; | ||
85 | struct sclp_readinfo_sccb *sccb; | ||
86 | |||
87 | if (!early_readinfo_sccb_valid) | ||
88 | return 0; | ||
89 | sccb = &early_readinfo_sccb; | ||
90 | if (sccb->rnsize) | ||
91 | memsize = sccb->rnsize << 20; | ||
92 | else | ||
93 | memsize = sccb->rnsize2 << 20; | ||
94 | if (sccb->rnmax) | ||
95 | memsize *= sccb->rnmax; | ||
96 | else | ||
97 | memsize *= sccb->rnmax2; | ||
98 | return memsize; | ||
99 | } | ||
100 | |||
101 | /* | ||
102 | * This function will be called after sclp_memory_detect(), which gets called | ||
103 | * early from early.c code. Therefore the sccb should have valid contents. | ||
104 | */ | ||
105 | void __init sclp_get_ipl_info(struct sclp_ipl_info *info) | ||
106 | { | ||
107 | struct sclp_readinfo_sccb *sccb; | ||
108 | |||
109 | if (!early_readinfo_sccb_valid) | ||
110 | return; | ||
111 | sccb = &early_readinfo_sccb; | ||
112 | info->is_valid = 1; | ||
113 | if (sccb->flags & 0x2) | ||
114 | info->has_dump = 1; | ||
115 | memcpy(&info->loadparm, &sccb->loadparm, LOADPARM_LEN); | ||
116 | } | ||
diff --git a/drivers/s390/char/sclp_rw.c b/drivers/s390/char/sclp_rw.c index d6b06ab81188..ad7195d3de0c 100644 --- a/drivers/s390/char/sclp_rw.c +++ b/drivers/s390/char/sclp_rw.c | |||
@@ -76,7 +76,7 @@ sclp_make_buffer(void *page, unsigned short columns, unsigned short htab) | |||
76 | } | 76 | } |
77 | 77 | ||
78 | /* | 78 | /* |
79 | * Return a pointer to the orignal page that has been used to create | 79 | * Return a pointer to the original page that has been used to create |
80 | * the buffer. | 80 | * the buffer. |
81 | */ | 81 | */ |
82 | void * | 82 | void * |
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c index da25f8e24152..8246ef3ab095 100644 --- a/drivers/s390/char/tape_3590.c +++ b/drivers/s390/char/tape_3590.c | |||
@@ -1495,7 +1495,7 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request, | |||
1495 | device->cdev->dev.bus_id); | 1495 | device->cdev->dev.bus_id); |
1496 | return tape_3590_erp_basic(device, request, irb, -EPERM); | 1496 | return tape_3590_erp_basic(device, request, irb, -EPERM); |
1497 | case 0x8013: | 1497 | case 0x8013: |
1498 | PRINT_WARN("(%s): Another host has priviliged access to the " | 1498 | PRINT_WARN("(%s): Another host has privileged access to the " |
1499 | "tape device\n", device->cdev->dev.bus_id); | 1499 | "tape device\n", device->cdev->dev.bus_id); |
1500 | PRINT_WARN("(%s): To solve the problem unload the current " | 1500 | PRINT_WARN("(%s): To solve the problem unload the current " |
1501 | "cartridge!\n", device->cdev->dev.bus_id); | 1501 | "cartridge!\n", device->cdev->dev.bus_id); |
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index 2fae6338ee1c..7ad8cf157641 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c | |||
@@ -37,7 +37,7 @@ static void tape_long_busy_timeout(unsigned long data); | |||
37 | * we can assign the devices to minor numbers of the same major | 37 | * we can assign the devices to minor numbers of the same major |
38 | * The list is protected by the rwlock | 38 | * The list is protected by the rwlock |
39 | */ | 39 | */ |
40 | static struct list_head tape_device_list = LIST_HEAD_INIT(tape_device_list); | 40 | static LIST_HEAD(tape_device_list); |
41 | static DEFINE_RWLOCK(tape_device_lock); | 41 | static DEFINE_RWLOCK(tape_device_lock); |
42 | 42 | ||
43 | /* | 43 | /* |
diff --git a/drivers/s390/char/tape_proc.c b/drivers/s390/char/tape_proc.c index cea49f001f89..c9b96d51b28f 100644 --- a/drivers/s390/char/tape_proc.c +++ b/drivers/s390/char/tape_proc.c | |||
@@ -97,7 +97,7 @@ static void tape_proc_stop(struct seq_file *m, void *v) | |||
97 | { | 97 | { |
98 | } | 98 | } |
99 | 99 | ||
100 | static struct seq_operations tape_proc_seq = { | 100 | static const struct seq_operations tape_proc_seq = { |
101 | .start = tape_proc_start, | 101 | .start = tape_proc_start, |
102 | .next = tape_proc_next, | 102 | .next = tape_proc_next, |
103 | .stop = tape_proc_stop, | 103 | .stop = tape_proc_stop, |
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index e0c4c508e121..d364e0bfae12 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c | |||
@@ -683,7 +683,7 @@ static int vmlogrdr_register_driver(void) | |||
683 | /* Register with iucv driver */ | 683 | /* Register with iucv driver */ |
684 | ret = iucv_register(&vmlogrdr_iucv_handler, 1); | 684 | ret = iucv_register(&vmlogrdr_iucv_handler, 1); |
685 | if (ret) { | 685 | if (ret) { |
686 | printk (KERN_ERR "vmlogrdr: failed to register with" | 686 | printk (KERN_ERR "vmlogrdr: failed to register with " |
687 | "iucv driver\n"); | 687 | "iucv driver\n"); |
688 | goto out; | 688 | goto out; |
689 | } | 689 | } |
diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c index d70a6e65bf14..7689b500a104 100644 --- a/drivers/s390/char/vmur.c +++ b/drivers/s390/char/vmur.c | |||
@@ -759,7 +759,7 @@ static loff_t ur_llseek(struct file *file, loff_t offset, int whence) | |||
759 | return newpos; | 759 | return newpos; |
760 | } | 760 | } |
761 | 761 | ||
762 | static struct file_operations ur_fops = { | 762 | static const struct file_operations ur_fops = { |
763 | .owner = THIS_MODULE, | 763 | .owner = THIS_MODULE, |
764 | .open = ur_open, | 764 | .open = ur_open, |
765 | .release = ur_release, | 765 | .release = ur_release, |
diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index 7073daf77981..f523501e6e6c 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c | |||
@@ -470,7 +470,7 @@ static loff_t zcore_lseek(struct file *file, loff_t offset, int orig) | |||
470 | return rc; | 470 | return rc; |
471 | } | 471 | } |
472 | 472 | ||
473 | static struct file_operations zcore_fops = { | 473 | static const struct file_operations zcore_fops = { |
474 | .owner = THIS_MODULE, | 474 | .owner = THIS_MODULE, |
475 | .llseek = zcore_lseek, | 475 | .llseek = zcore_lseek, |
476 | .read = zcore_read, | 476 | .read = zcore_read, |
diff --git a/drivers/s390/cio/airq.c b/drivers/s390/cio/airq.c index 5287631fbfc8..b7a07a866291 100644 --- a/drivers/s390/cio/airq.c +++ b/drivers/s390/cio/airq.c | |||
@@ -1,12 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/s390/cio/airq.c | 2 | * drivers/s390/cio/airq.c |
3 | * S/390 common I/O routines -- support for adapter interruptions | 3 | * Support for adapter interruptions |
4 | * | 4 | * |
5 | * Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH, | 5 | * Copyright IBM Corp. 1999,2007 |
6 | * IBM Corporation | 6 | * Author(s): Ingo Adlung <adlung@de.ibm.com> |
7 | * Author(s): Ingo Adlung (adlung@de.ibm.com) | 7 | * Cornelia Huck <cornelia.huck@de.ibm.com> |
8 | * Cornelia Huck (cornelia.huck@de.ibm.com) | 8 | * Arnd Bergmann <arndb@de.ibm.com> |
9 | * Arnd Bergmann (arndb@de.ibm.com) | 9 | * Peter Oberparleiter <peter.oberparleiter@de.ibm.com> |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
@@ -14,72 +14,131 @@ | |||
14 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
15 | #include <linux/rcupdate.h> | 15 | #include <linux/rcupdate.h> |
16 | 16 | ||
17 | #include <asm/airq.h> | ||
18 | |||
19 | #include "cio.h" | ||
17 | #include "cio_debug.h" | 20 | #include "cio_debug.h" |
18 | #include "airq.h" | ||
19 | 21 | ||
20 | static adapter_int_handler_t adapter_handler; | 22 | #define NR_AIRQS 32 |
23 | #define NR_AIRQS_PER_WORD sizeof(unsigned long) | ||
24 | #define NR_AIRQ_WORDS (NR_AIRQS / NR_AIRQS_PER_WORD) | ||
21 | 25 | ||
22 | /* | 26 | union indicator_t { |
23 | * register for adapter interrupts | 27 | unsigned long word[NR_AIRQ_WORDS]; |
24 | * | 28 | unsigned char byte[NR_AIRQS]; |
25 | * With HiperSockets the zSeries architecture provides for | 29 | } __attribute__((packed)); |
26 | * means of adapter interrups, pseudo I/O interrupts that are | ||
27 | * not tied to an I/O subchannel, but to an adapter. However, | ||
28 | * it doesn't disclose the info how to enable/disable them, but | ||
29 | * to recognize them only. Perhaps we should consider them | ||
30 | * being shared interrupts, and thus build a linked list | ||
31 | * of adapter handlers ... to be evaluated ... | ||
32 | */ | ||
33 | int | ||
34 | s390_register_adapter_interrupt (adapter_int_handler_t handler) | ||
35 | { | ||
36 | int ret; | ||
37 | char dbf_txt[15]; | ||
38 | 30 | ||
39 | CIO_TRACE_EVENT (4, "rgaint"); | 31 | struct airq_t { |
32 | adapter_int_handler_t handler; | ||
33 | void *drv_data; | ||
34 | }; | ||
40 | 35 | ||
41 | if (handler == NULL) | 36 | static union indicator_t indicators; |
42 | ret = -EINVAL; | 37 | static struct airq_t *airqs[NR_AIRQS]; |
43 | else | ||
44 | ret = (cmpxchg(&adapter_handler, NULL, handler) ? -EBUSY : 0); | ||
45 | if (!ret) | ||
46 | synchronize_sched(); /* Allow interrupts to complete. */ | ||
47 | 38 | ||
48 | sprintf (dbf_txt, "ret:%d", ret); | 39 | static int register_airq(struct airq_t *airq) |
49 | CIO_TRACE_EVENT (4, dbf_txt); | 40 | { |
41 | int i; | ||
50 | 42 | ||
51 | return ret; | 43 | for (i = 0; i < NR_AIRQS; i++) |
44 | if (!cmpxchg(&airqs[i], NULL, airq)) | ||
45 | return i; | ||
46 | return -ENOMEM; | ||
52 | } | 47 | } |
53 | 48 | ||
54 | int | 49 | /** |
55 | s390_unregister_adapter_interrupt (adapter_int_handler_t handler) | 50 | * s390_register_adapter_interrupt() - register adapter interrupt handler |
51 | * @handler: adapter handler to be registered | ||
52 | * @drv_data: driver data passed with each call to the handler | ||
53 | * | ||
54 | * Returns: | ||
55 | * Pointer to the indicator to be used on success | ||
56 | * ERR_PTR() if registration failed | ||
57 | */ | ||
58 | void *s390_register_adapter_interrupt(adapter_int_handler_t handler, | ||
59 | void *drv_data) | ||
56 | { | 60 | { |
61 | struct airq_t *airq; | ||
62 | char dbf_txt[16]; | ||
57 | int ret; | 63 | int ret; |
58 | char dbf_txt[15]; | ||
59 | 64 | ||
60 | CIO_TRACE_EVENT (4, "urgaint"); | 65 | airq = kmalloc(sizeof(struct airq_t), GFP_KERNEL); |
61 | 66 | if (!airq) { | |
62 | if (handler == NULL) | 67 | ret = -ENOMEM; |
63 | ret = -EINVAL; | 68 | goto out; |
64 | else { | ||
65 | adapter_handler = NULL; | ||
66 | synchronize_sched(); /* Allow interrupts to complete. */ | ||
67 | ret = 0; | ||
68 | } | 69 | } |
69 | sprintf (dbf_txt, "ret:%d", ret); | 70 | airq->handler = handler; |
70 | CIO_TRACE_EVENT (4, dbf_txt); | 71 | airq->drv_data = drv_data; |
71 | 72 | ret = register_airq(airq); | |
72 | return ret; | 73 | if (ret < 0) |
74 | kfree(airq); | ||
75 | out: | ||
76 | snprintf(dbf_txt, sizeof(dbf_txt), "rairq:%d", ret); | ||
77 | CIO_TRACE_EVENT(4, dbf_txt); | ||
78 | if (ret < 0) | ||
79 | return ERR_PTR(ret); | ||
80 | else | ||
81 | return &indicators.byte[ret]; | ||
73 | } | 82 | } |
83 | EXPORT_SYMBOL(s390_register_adapter_interrupt); | ||
74 | 84 | ||
75 | void | 85 | /** |
76 | do_adapter_IO (void) | 86 | * s390_unregister_adapter_interrupt - unregister adapter interrupt handler |
87 | * @ind: indicator for which the handler is to be unregistered | ||
88 | */ | ||
89 | void s390_unregister_adapter_interrupt(void *ind) | ||
77 | { | 90 | { |
78 | CIO_TRACE_EVENT (6, "doaio"); | 91 | struct airq_t *airq; |
92 | char dbf_txt[16]; | ||
93 | int i; | ||
79 | 94 | ||
80 | if (adapter_handler) | 95 | i = (int) ((addr_t) ind) - ((addr_t) &indicators.byte[0]); |
81 | (*adapter_handler) (); | 96 | snprintf(dbf_txt, sizeof(dbf_txt), "urairq:%d", i); |
97 | CIO_TRACE_EVENT(4, dbf_txt); | ||
98 | indicators.byte[i] = 0; | ||
99 | airq = xchg(&airqs[i], NULL); | ||
100 | /* | ||
101 | * Allow interrupts to complete. This will ensure that the airq handle | ||
102 | * is no longer referenced by any interrupt handler. | ||
103 | */ | ||
104 | synchronize_sched(); | ||
105 | kfree(airq); | ||
82 | } | 106 | } |
107 | EXPORT_SYMBOL(s390_unregister_adapter_interrupt); | ||
108 | |||
109 | #define INDICATOR_MASK (0xffUL << ((NR_AIRQS_PER_WORD - 1) * 8)) | ||
83 | 110 | ||
84 | EXPORT_SYMBOL (s390_register_adapter_interrupt); | 111 | void do_adapter_IO(void) |
85 | EXPORT_SYMBOL (s390_unregister_adapter_interrupt); | 112 | { |
113 | int w; | ||
114 | int i; | ||
115 | unsigned long word; | ||
116 | struct airq_t *airq; | ||
117 | |||
118 | /* | ||
119 | * Access indicator array in word-sized chunks to minimize storage | ||
120 | * fetch operations. | ||
121 | */ | ||
122 | for (w = 0; w < NR_AIRQ_WORDS; w++) { | ||
123 | word = indicators.word[w]; | ||
124 | i = w * NR_AIRQS_PER_WORD; | ||
125 | /* | ||
126 | * Check bytes within word for active indicators. | ||
127 | */ | ||
128 | while (word) { | ||
129 | if (word & INDICATOR_MASK) { | ||
130 | airq = airqs[i]; | ||
131 | if (likely(airq)) | ||
132 | airq->handler(&indicators.byte[i], | ||
133 | airq->drv_data); | ||
134 | else | ||
135 | /* | ||
136 | * Reset ill-behaved indicator. | ||
137 | */ | ||
138 | indicators.byte[i] = 0; | ||
139 | } | ||
140 | word <<= 8; | ||
141 | i++; | ||
142 | } | ||
143 | } | ||
144 | } | ||
diff --git a/drivers/s390/cio/airq.h b/drivers/s390/cio/airq.h deleted file mode 100644 index 7d6be3fdcd66..000000000000 --- a/drivers/s390/cio/airq.h +++ /dev/null | |||
@@ -1,10 +0,0 @@ | |||
1 | #ifndef S390_AINTERRUPT_H | ||
2 | #define S390_AINTERRUPT_H | ||
3 | |||
4 | typedef int (*adapter_int_handler_t)(void); | ||
5 | |||
6 | extern int s390_register_adapter_interrupt(adapter_int_handler_t handler); | ||
7 | extern int s390_unregister_adapter_interrupt(adapter_int_handler_t handler); | ||
8 | extern void do_adapter_IO (void); | ||
9 | |||
10 | #endif | ||
diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c index bd5f16f80bf8..e8597ec92247 100644 --- a/drivers/s390/cio/blacklist.c +++ b/drivers/s390/cio/blacklist.c | |||
@@ -348,7 +348,7 @@ cio_ignore_write(struct file *file, const char __user *user_buf, | |||
348 | return user_len; | 348 | return user_len; |
349 | } | 349 | } |
350 | 350 | ||
351 | static struct seq_operations cio_ignore_proc_seq_ops = { | 351 | static const struct seq_operations cio_ignore_proc_seq_ops = { |
352 | .start = cio_ignore_proc_seq_start, | 352 | .start = cio_ignore_proc_seq_start, |
353 | .stop = cio_ignore_proc_seq_stop, | 353 | .stop = cio_ignore_proc_seq_stop, |
354 | .next = cio_ignore_proc_seq_next, | 354 | .next = cio_ignore_proc_seq_next, |
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index 5baa517c3b66..3964056a9a47 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c | |||
@@ -35,8 +35,8 @@ ccwgroup_bus_match (struct device * dev, struct device_driver * drv) | |||
35 | struct ccwgroup_device *gdev; | 35 | struct ccwgroup_device *gdev; |
36 | struct ccwgroup_driver *gdrv; | 36 | struct ccwgroup_driver *gdrv; |
37 | 37 | ||
38 | gdev = container_of(dev, struct ccwgroup_device, dev); | 38 | gdev = to_ccwgroupdev(dev); |
39 | gdrv = container_of(drv, struct ccwgroup_driver, driver); | 39 | gdrv = to_ccwgroupdrv(drv); |
40 | 40 | ||
41 | if (gdev->creator_id == gdrv->driver_id) | 41 | if (gdev->creator_id == gdrv->driver_id) |
42 | return 1; | 42 | return 1; |
@@ -75,8 +75,10 @@ static void ccwgroup_ungroup_callback(struct device *dev) | |||
75 | struct ccwgroup_device *gdev = to_ccwgroupdev(dev); | 75 | struct ccwgroup_device *gdev = to_ccwgroupdev(dev); |
76 | 76 | ||
77 | mutex_lock(&gdev->reg_mutex); | 77 | mutex_lock(&gdev->reg_mutex); |
78 | __ccwgroup_remove_symlinks(gdev); | 78 | if (device_is_registered(&gdev->dev)) { |
79 | device_unregister(dev); | 79 | __ccwgroup_remove_symlinks(gdev); |
80 | device_unregister(dev); | ||
81 | } | ||
80 | mutex_unlock(&gdev->reg_mutex); | 82 | mutex_unlock(&gdev->reg_mutex); |
81 | } | 83 | } |
82 | 84 | ||
@@ -111,7 +113,7 @@ ccwgroup_release (struct device *dev) | |||
111 | gdev = to_ccwgroupdev(dev); | 113 | gdev = to_ccwgroupdev(dev); |
112 | 114 | ||
113 | for (i = 0; i < gdev->count; i++) { | 115 | for (i = 0; i < gdev->count; i++) { |
114 | gdev->cdev[i]->dev.driver_data = NULL; | 116 | dev_set_drvdata(&gdev->cdev[i]->dev, NULL); |
115 | put_device(&gdev->cdev[i]->dev); | 117 | put_device(&gdev->cdev[i]->dev); |
116 | } | 118 | } |
117 | kfree(gdev); | 119 | kfree(gdev); |
@@ -196,11 +198,11 @@ int ccwgroup_create(struct device *root, unsigned int creator_id, | |||
196 | goto error; | 198 | goto error; |
197 | } | 199 | } |
198 | /* Don't allow a device to belong to more than one group. */ | 200 | /* Don't allow a device to belong to more than one group. */ |
199 | if (gdev->cdev[i]->dev.driver_data) { | 201 | if (dev_get_drvdata(&gdev->cdev[i]->dev)) { |
200 | rc = -EINVAL; | 202 | rc = -EINVAL; |
201 | goto error; | 203 | goto error; |
202 | } | 204 | } |
203 | gdev->cdev[i]->dev.driver_data = gdev; | 205 | dev_set_drvdata(&gdev->cdev[i]->dev, gdev); |
204 | } | 206 | } |
205 | 207 | ||
206 | gdev->creator_id = creator_id; | 208 | gdev->creator_id = creator_id; |
@@ -234,8 +236,8 @@ int ccwgroup_create(struct device *root, unsigned int creator_id, | |||
234 | error: | 236 | error: |
235 | for (i = 0; i < argc; i++) | 237 | for (i = 0; i < argc; i++) |
236 | if (gdev->cdev[i]) { | 238 | if (gdev->cdev[i]) { |
237 | if (gdev->cdev[i]->dev.driver_data == gdev) | 239 | if (dev_get_drvdata(&gdev->cdev[i]->dev) == gdev) |
238 | gdev->cdev[i]->dev.driver_data = NULL; | 240 | dev_set_drvdata(&gdev->cdev[i]->dev, NULL); |
239 | put_device(&gdev->cdev[i]->dev); | 241 | put_device(&gdev->cdev[i]->dev); |
240 | } | 242 | } |
241 | mutex_unlock(&gdev->reg_mutex); | 243 | mutex_unlock(&gdev->reg_mutex); |
@@ -408,6 +410,7 @@ int ccwgroup_driver_register(struct ccwgroup_driver *cdriver) | |||
408 | /* register our new driver with the core */ | 410 | /* register our new driver with the core */ |
409 | cdriver->driver.bus = &ccwgroup_bus_type; | 411 | cdriver->driver.bus = &ccwgroup_bus_type; |
410 | cdriver->driver.name = cdriver->name; | 412 | cdriver->driver.name = cdriver->name; |
413 | cdriver->driver.owner = cdriver->owner; | ||
411 | 414 | ||
412 | return driver_register(&cdriver->driver); | 415 | return driver_register(&cdriver->driver); |
413 | } | 416 | } |
@@ -463,8 +466,8 @@ __ccwgroup_get_gdev_by_cdev(struct ccw_device *cdev) | |||
463 | { | 466 | { |
464 | struct ccwgroup_device *gdev; | 467 | struct ccwgroup_device *gdev; |
465 | 468 | ||
466 | if (cdev->dev.driver_data) { | 469 | gdev = dev_get_drvdata(&cdev->dev); |
467 | gdev = (struct ccwgroup_device *)cdev->dev.driver_data; | 470 | if (gdev) { |
468 | if (get_device(&gdev->dev)) { | 471 | if (get_device(&gdev->dev)) { |
469 | mutex_lock(&gdev->reg_mutex); | 472 | mutex_lock(&gdev->reg_mutex); |
470 | if (device_is_registered(&gdev->dev)) | 473 | if (device_is_registered(&gdev->dev)) |
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 597c0c76a2ad..e7ba16a74ef7 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c | |||
@@ -89,7 +89,8 @@ int chsc_get_ssd_info(struct subchannel_id schid, struct chsc_ssd_info *ssd) | |||
89 | /* Copy data */ | 89 | /* Copy data */ |
90 | ret = 0; | 90 | ret = 0; |
91 | memset(ssd, 0, sizeof(struct chsc_ssd_info)); | 91 | memset(ssd, 0, sizeof(struct chsc_ssd_info)); |
92 | if ((ssd_area->st != 0) && (ssd_area->st != 2)) | 92 | if ((ssd_area->st != SUBCHANNEL_TYPE_IO) && |
93 | (ssd_area->st != SUBCHANNEL_TYPE_MSG)) | ||
93 | goto out_free; | 94 | goto out_free; |
94 | ssd->path_mask = ssd_area->path_mask; | 95 | ssd->path_mask = ssd_area->path_mask; |
95 | ssd->fla_valid_mask = ssd_area->fla_valid_mask; | 96 | ssd->fla_valid_mask = ssd_area->fla_valid_mask; |
@@ -132,20 +133,16 @@ static void terminate_internal_io(struct subchannel *sch) | |||
132 | device_set_intretry(sch); | 133 | device_set_intretry(sch); |
133 | /* Call handler. */ | 134 | /* Call handler. */ |
134 | if (sch->driver && sch->driver->termination) | 135 | if (sch->driver && sch->driver->termination) |
135 | sch->driver->termination(&sch->dev); | 136 | sch->driver->termination(sch); |
136 | } | 137 | } |
137 | 138 | ||
138 | static int | 139 | static int s390_subchannel_remove_chpid(struct subchannel *sch, void *data) |
139 | s390_subchannel_remove_chpid(struct device *dev, void *data) | ||
140 | { | 140 | { |
141 | int j; | 141 | int j; |
142 | int mask; | 142 | int mask; |
143 | struct subchannel *sch; | 143 | struct chp_id *chpid = data; |
144 | struct chp_id *chpid; | ||
145 | struct schib schib; | 144 | struct schib schib; |
146 | 145 | ||
147 | sch = to_subchannel(dev); | ||
148 | chpid = data; | ||
149 | for (j = 0; j < 8; j++) { | 146 | for (j = 0; j < 8; j++) { |
150 | mask = 0x80 >> j; | 147 | mask = 0x80 >> j; |
151 | if ((sch->schib.pmcw.pim & mask) && | 148 | if ((sch->schib.pmcw.pim & mask) && |
@@ -158,7 +155,7 @@ s390_subchannel_remove_chpid(struct device *dev, void *data) | |||
158 | spin_lock_irq(sch->lock); | 155 | spin_lock_irq(sch->lock); |
159 | 156 | ||
160 | stsch(sch->schid, &schib); | 157 | stsch(sch->schid, &schib); |
161 | if (!schib.pmcw.dnv) | 158 | if (!css_sch_is_valid(&schib)) |
162 | goto out_unreg; | 159 | goto out_unreg; |
163 | memcpy(&sch->schib, &schib, sizeof(struct schib)); | 160 | memcpy(&sch->schib, &schib, sizeof(struct schib)); |
164 | /* Check for single path devices. */ | 161 | /* Check for single path devices. */ |
@@ -172,12 +169,12 @@ s390_subchannel_remove_chpid(struct device *dev, void *data) | |||
172 | terminate_internal_io(sch); | 169 | terminate_internal_io(sch); |
173 | /* Re-start path verification. */ | 170 | /* Re-start path verification. */ |
174 | if (sch->driver && sch->driver->verify) | 171 | if (sch->driver && sch->driver->verify) |
175 | sch->driver->verify(&sch->dev); | 172 | sch->driver->verify(sch); |
176 | } | 173 | } |
177 | } else { | 174 | } else { |
178 | /* trigger path verification. */ | 175 | /* trigger path verification. */ |
179 | if (sch->driver && sch->driver->verify) | 176 | if (sch->driver && sch->driver->verify) |
180 | sch->driver->verify(&sch->dev); | 177 | sch->driver->verify(sch); |
181 | else if (sch->lpm == mask) | 178 | else if (sch->lpm == mask) |
182 | goto out_unreg; | 179 | goto out_unreg; |
183 | } | 180 | } |
@@ -201,12 +198,10 @@ void chsc_chp_offline(struct chp_id chpid) | |||
201 | 198 | ||
202 | if (chp_get_status(chpid) <= 0) | 199 | if (chp_get_status(chpid) <= 0) |
203 | return; | 200 | return; |
204 | bus_for_each_dev(&css_bus_type, NULL, &chpid, | 201 | for_each_subchannel_staged(s390_subchannel_remove_chpid, NULL, &chpid); |
205 | s390_subchannel_remove_chpid); | ||
206 | } | 202 | } |
207 | 203 | ||
208 | static int | 204 | static int s390_process_res_acc_new_sch(struct subchannel_id schid, void *data) |
209 | s390_process_res_acc_new_sch(struct subchannel_id schid) | ||
210 | { | 205 | { |
211 | struct schib schib; | 206 | struct schib schib; |
212 | /* | 207 | /* |
@@ -252,18 +247,10 @@ static int get_res_chpid_mask(struct chsc_ssd_info *ssd, | |||
252 | return 0; | 247 | return 0; |
253 | } | 248 | } |
254 | 249 | ||
255 | static int | 250 | static int __s390_process_res_acc(struct subchannel *sch, void *data) |
256 | __s390_process_res_acc(struct subchannel_id schid, void *data) | ||
257 | { | 251 | { |
258 | int chp_mask, old_lpm; | 252 | int chp_mask, old_lpm; |
259 | struct res_acc_data *res_data; | 253 | struct res_acc_data *res_data = data; |
260 | struct subchannel *sch; | ||
261 | |||
262 | res_data = data; | ||
263 | sch = get_subchannel_by_schid(schid); | ||
264 | if (!sch) | ||
265 | /* Check if a subchannel is newly available. */ | ||
266 | return s390_process_res_acc_new_sch(schid); | ||
267 | 254 | ||
268 | spin_lock_irq(sch->lock); | 255 | spin_lock_irq(sch->lock); |
269 | chp_mask = get_res_chpid_mask(&sch->ssd_info, res_data); | 256 | chp_mask = get_res_chpid_mask(&sch->ssd_info, res_data); |
@@ -279,10 +266,10 @@ __s390_process_res_acc(struct subchannel_id schid, void *data) | |||
279 | if (!old_lpm && sch->lpm) | 266 | if (!old_lpm && sch->lpm) |
280 | device_trigger_reprobe(sch); | 267 | device_trigger_reprobe(sch); |
281 | else if (sch->driver && sch->driver->verify) | 268 | else if (sch->driver && sch->driver->verify) |
282 | sch->driver->verify(&sch->dev); | 269 | sch->driver->verify(sch); |
283 | out: | 270 | out: |
284 | spin_unlock_irq(sch->lock); | 271 | spin_unlock_irq(sch->lock); |
285 | put_device(&sch->dev); | 272 | |
286 | return 0; | 273 | return 0; |
287 | } | 274 | } |
288 | 275 | ||
@@ -305,7 +292,8 @@ static void s390_process_res_acc (struct res_acc_data *res_data) | |||
305 | * The more information we have (info), the less scanning | 292 | * The more information we have (info), the less scanning |
306 | * will we have to do. | 293 | * will we have to do. |
307 | */ | 294 | */ |
308 | for_each_subchannel(__s390_process_res_acc, res_data); | 295 | for_each_subchannel_staged(__s390_process_res_acc, |
296 | s390_process_res_acc_new_sch, res_data); | ||
309 | } | 297 | } |
310 | 298 | ||
311 | static int | 299 | static int |
@@ -499,8 +487,7 @@ void chsc_process_crw(void) | |||
499 | } while (sei_area->flags & 0x80); | 487 | } while (sei_area->flags & 0x80); |
500 | } | 488 | } |
501 | 489 | ||
502 | static int | 490 | static int __chp_add_new_sch(struct subchannel_id schid, void *data) |
503 | __chp_add_new_sch(struct subchannel_id schid) | ||
504 | { | 491 | { |
505 | struct schib schib; | 492 | struct schib schib; |
506 | 493 | ||
@@ -514,45 +501,37 @@ __chp_add_new_sch(struct subchannel_id schid) | |||
514 | } | 501 | } |
515 | 502 | ||
516 | 503 | ||
517 | static int | 504 | static int __chp_add(struct subchannel *sch, void *data) |
518 | __chp_add(struct subchannel_id schid, void *data) | ||
519 | { | 505 | { |
520 | int i, mask; | 506 | int i, mask; |
521 | struct chp_id *chpid; | 507 | struct chp_id *chpid = data; |
522 | struct subchannel *sch; | 508 | |
523 | |||
524 | chpid = data; | ||
525 | sch = get_subchannel_by_schid(schid); | ||
526 | if (!sch) | ||
527 | /* Check if the subchannel is now available. */ | ||
528 | return __chp_add_new_sch(schid); | ||
529 | spin_lock_irq(sch->lock); | 509 | spin_lock_irq(sch->lock); |
530 | for (i=0; i<8; i++) { | 510 | for (i=0; i<8; i++) { |
531 | mask = 0x80 >> i; | 511 | mask = 0x80 >> i; |
532 | if ((sch->schib.pmcw.pim & mask) && | 512 | if ((sch->schib.pmcw.pim & mask) && |
533 | (sch->schib.pmcw.chpid[i] == chpid->id)) { | 513 | (sch->schib.pmcw.chpid[i] == chpid->id)) |
534 | if (stsch(sch->schid, &sch->schib) != 0) { | ||
535 | /* Endgame. */ | ||
536 | spin_unlock_irq(sch->lock); | ||
537 | return -ENXIO; | ||
538 | } | ||
539 | break; | 514 | break; |
540 | } | ||
541 | } | 515 | } |
542 | if (i==8) { | 516 | if (i==8) { |
543 | spin_unlock_irq(sch->lock); | 517 | spin_unlock_irq(sch->lock); |
544 | return 0; | 518 | return 0; |
545 | } | 519 | } |
520 | if (stsch(sch->schid, &sch->schib)) { | ||
521 | spin_unlock_irq(sch->lock); | ||
522 | css_schedule_eval(sch->schid); | ||
523 | return 0; | ||
524 | } | ||
546 | sch->lpm = ((sch->schib.pmcw.pim & | 525 | sch->lpm = ((sch->schib.pmcw.pim & |
547 | sch->schib.pmcw.pam & | 526 | sch->schib.pmcw.pam & |
548 | sch->schib.pmcw.pom) | 527 | sch->schib.pmcw.pom) |
549 | | mask) & sch->opm; | 528 | | mask) & sch->opm; |
550 | 529 | ||
551 | if (sch->driver && sch->driver->verify) | 530 | if (sch->driver && sch->driver->verify) |
552 | sch->driver->verify(&sch->dev); | 531 | sch->driver->verify(sch); |
553 | 532 | ||
554 | spin_unlock_irq(sch->lock); | 533 | spin_unlock_irq(sch->lock); |
555 | put_device(&sch->dev); | 534 | |
556 | return 0; | 535 | return 0; |
557 | } | 536 | } |
558 | 537 | ||
@@ -564,7 +543,8 @@ void chsc_chp_online(struct chp_id chpid) | |||
564 | CIO_TRACE_EVENT(2, dbf_txt); | 543 | CIO_TRACE_EVENT(2, dbf_txt); |
565 | 544 | ||
566 | if (chp_get_status(chpid) != 0) | 545 | if (chp_get_status(chpid) != 0) |
567 | for_each_subchannel(__chp_add, &chpid); | 546 | for_each_subchannel_staged(__chp_add, __chp_add_new_sch, |
547 | &chpid); | ||
568 | } | 548 | } |
569 | 549 | ||
570 | static void __s390_subchannel_vary_chpid(struct subchannel *sch, | 550 | static void __s390_subchannel_vary_chpid(struct subchannel *sch, |
@@ -589,7 +569,7 @@ static void __s390_subchannel_vary_chpid(struct subchannel *sch, | |||
589 | if (!old_lpm) | 569 | if (!old_lpm) |
590 | device_trigger_reprobe(sch); | 570 | device_trigger_reprobe(sch); |
591 | else if (sch->driver && sch->driver->verify) | 571 | else if (sch->driver && sch->driver->verify) |
592 | sch->driver->verify(&sch->dev); | 572 | sch->driver->verify(sch); |
593 | break; | 573 | break; |
594 | } | 574 | } |
595 | sch->opm &= ~mask; | 575 | sch->opm &= ~mask; |
@@ -603,37 +583,29 @@ static void __s390_subchannel_vary_chpid(struct subchannel *sch, | |||
603 | terminate_internal_io(sch); | 583 | terminate_internal_io(sch); |
604 | /* Re-start path verification. */ | 584 | /* Re-start path verification. */ |
605 | if (sch->driver && sch->driver->verify) | 585 | if (sch->driver && sch->driver->verify) |
606 | sch->driver->verify(&sch->dev); | 586 | sch->driver->verify(sch); |
607 | } | 587 | } |
608 | } else if (!sch->lpm) { | 588 | } else if (!sch->lpm) { |
609 | if (device_trigger_verify(sch) != 0) | 589 | if (device_trigger_verify(sch) != 0) |
610 | css_schedule_eval(sch->schid); | 590 | css_schedule_eval(sch->schid); |
611 | } else if (sch->driver && sch->driver->verify) | 591 | } else if (sch->driver && sch->driver->verify) |
612 | sch->driver->verify(&sch->dev); | 592 | sch->driver->verify(sch); |
613 | break; | 593 | break; |
614 | } | 594 | } |
615 | spin_unlock_irqrestore(sch->lock, flags); | 595 | spin_unlock_irqrestore(sch->lock, flags); |
616 | } | 596 | } |
617 | 597 | ||
618 | static int s390_subchannel_vary_chpid_off(struct device *dev, void *data) | 598 | static int s390_subchannel_vary_chpid_off(struct subchannel *sch, void *data) |
619 | { | 599 | { |
620 | struct subchannel *sch; | 600 | struct chp_id *chpid = data; |
621 | struct chp_id *chpid; | ||
622 | |||
623 | sch = to_subchannel(dev); | ||
624 | chpid = data; | ||
625 | 601 | ||
626 | __s390_subchannel_vary_chpid(sch, *chpid, 0); | 602 | __s390_subchannel_vary_chpid(sch, *chpid, 0); |
627 | return 0; | 603 | return 0; |
628 | } | 604 | } |
629 | 605 | ||
630 | static int s390_subchannel_vary_chpid_on(struct device *dev, void *data) | 606 | static int s390_subchannel_vary_chpid_on(struct subchannel *sch, void *data) |
631 | { | 607 | { |
632 | struct subchannel *sch; | 608 | struct chp_id *chpid = data; |
633 | struct chp_id *chpid; | ||
634 | |||
635 | sch = to_subchannel(dev); | ||
636 | chpid = data; | ||
637 | 609 | ||
638 | __s390_subchannel_vary_chpid(sch, *chpid, 1); | 610 | __s390_subchannel_vary_chpid(sch, *chpid, 1); |
639 | return 0; | 611 | return 0; |
@@ -643,13 +615,7 @@ static int | |||
643 | __s390_vary_chpid_on(struct subchannel_id schid, void *data) | 615 | __s390_vary_chpid_on(struct subchannel_id schid, void *data) |
644 | { | 616 | { |
645 | struct schib schib; | 617 | struct schib schib; |
646 | struct subchannel *sch; | ||
647 | 618 | ||
648 | sch = get_subchannel_by_schid(schid); | ||
649 | if (sch) { | ||
650 | put_device(&sch->dev); | ||
651 | return 0; | ||
652 | } | ||
653 | if (stsch_err(schid, &schib)) | 619 | if (stsch_err(schid, &schib)) |
654 | /* We're through */ | 620 | /* We're through */ |
655 | return -ENXIO; | 621 | return -ENXIO; |
@@ -669,12 +635,13 @@ int chsc_chp_vary(struct chp_id chpid, int on) | |||
669 | * Redo PathVerification on the devices the chpid connects to | 635 | * Redo PathVerification on the devices the chpid connects to |
670 | */ | 636 | */ |
671 | 637 | ||
672 | bus_for_each_dev(&css_bus_type, NULL, &chpid, on ? | ||
673 | s390_subchannel_vary_chpid_on : | ||
674 | s390_subchannel_vary_chpid_off); | ||
675 | if (on) | 638 | if (on) |
676 | /* Scan for new devices on varied on path. */ | 639 | for_each_subchannel_staged(s390_subchannel_vary_chpid_on, |
677 | for_each_subchannel(__s390_vary_chpid_on, NULL); | 640 | __s390_vary_chpid_on, &chpid); |
641 | else | ||
642 | for_each_subchannel_staged(s390_subchannel_vary_chpid_off, | ||
643 | NULL, &chpid); | ||
644 | |||
678 | return 0; | 645 | return 0; |
679 | } | 646 | } |
680 | 647 | ||
@@ -1075,7 +1042,7 @@ chsc_determine_css_characteristics(void) | |||
1075 | 1042 | ||
1076 | scsc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); | 1043 | scsc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); |
1077 | if (!scsc_area) { | 1044 | if (!scsc_area) { |
1078 | CIO_MSG_EVENT(0, "Was not able to determine available" | 1045 | CIO_MSG_EVENT(0, "Was not able to determine available " |
1079 | "CHSCs due to no memory.\n"); | 1046 | "CHSCs due to no memory.\n"); |
1080 | return -ENOMEM; | 1047 | return -ENOMEM; |
1081 | } | 1048 | } |
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 46905345159e..60590a12d529 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
@@ -23,11 +23,12 @@ | |||
23 | #include <asm/reset.h> | 23 | #include <asm/reset.h> |
24 | #include <asm/ipl.h> | 24 | #include <asm/ipl.h> |
25 | #include <asm/chpid.h> | 25 | #include <asm/chpid.h> |
26 | #include "airq.h" | 26 | #include <asm/airq.h> |
27 | #include "cio.h" | 27 | #include "cio.h" |
28 | #include "css.h" | 28 | #include "css.h" |
29 | #include "chsc.h" | 29 | #include "chsc.h" |
30 | #include "ioasm.h" | 30 | #include "ioasm.h" |
31 | #include "io_sch.h" | ||
31 | #include "blacklist.h" | 32 | #include "blacklist.h" |
32 | #include "cio_debug.h" | 33 | #include "cio_debug.h" |
33 | #include "chp.h" | 34 | #include "chp.h" |
@@ -56,39 +57,37 @@ __setup ("cio_msg=", cio_setup); | |||
56 | 57 | ||
57 | /* | 58 | /* |
58 | * Function: cio_debug_init | 59 | * Function: cio_debug_init |
59 | * Initializes three debug logs (under /proc/s390dbf) for common I/O: | 60 | * Initializes three debug logs for common I/O: |
60 | * - cio_msg logs the messages which are printk'ed when CONFIG_DEBUG_IO is on | 61 | * - cio_msg logs generic cio messages |
61 | * - cio_trace logs the calling of different functions | 62 | * - cio_trace logs the calling of different functions |
62 | * - cio_crw logs the messages which are printk'ed when CONFIG_DEBUG_CRW is on | 63 | * - cio_crw logs machine check related cio messages |
63 | * debug levels depend on CONFIG_DEBUG_IO resp. CONFIG_DEBUG_CRW | ||
64 | */ | 64 | */ |
65 | static int __init | 65 | static int __init cio_debug_init(void) |
66 | cio_debug_init (void) | ||
67 | { | 66 | { |
68 | cio_debug_msg_id = debug_register ("cio_msg", 16, 4, 16*sizeof (long)); | 67 | cio_debug_msg_id = debug_register("cio_msg", 16, 1, 16 * sizeof(long)); |
69 | if (!cio_debug_msg_id) | 68 | if (!cio_debug_msg_id) |
70 | goto out_unregister; | 69 | goto out_unregister; |
71 | debug_register_view (cio_debug_msg_id, &debug_sprintf_view); | 70 | debug_register_view(cio_debug_msg_id, &debug_sprintf_view); |
72 | debug_set_level (cio_debug_msg_id, 2); | 71 | debug_set_level(cio_debug_msg_id, 2); |
73 | cio_debug_trace_id = debug_register ("cio_trace", 16, 4, 16); | 72 | cio_debug_trace_id = debug_register("cio_trace", 16, 1, 16); |
74 | if (!cio_debug_trace_id) | 73 | if (!cio_debug_trace_id) |
75 | goto out_unregister; | 74 | goto out_unregister; |
76 | debug_register_view (cio_debug_trace_id, &debug_hex_ascii_view); | 75 | debug_register_view(cio_debug_trace_id, &debug_hex_ascii_view); |
77 | debug_set_level (cio_debug_trace_id, 2); | 76 | debug_set_level(cio_debug_trace_id, 2); |
78 | cio_debug_crw_id = debug_register ("cio_crw", 4, 4, 16*sizeof (long)); | 77 | cio_debug_crw_id = debug_register("cio_crw", 16, 1, 16 * sizeof(long)); |
79 | if (!cio_debug_crw_id) | 78 | if (!cio_debug_crw_id) |
80 | goto out_unregister; | 79 | goto out_unregister; |
81 | debug_register_view (cio_debug_crw_id, &debug_sprintf_view); | 80 | debug_register_view(cio_debug_crw_id, &debug_sprintf_view); |
82 | debug_set_level (cio_debug_crw_id, 2); | 81 | debug_set_level(cio_debug_crw_id, 4); |
83 | return 0; | 82 | return 0; |
84 | 83 | ||
85 | out_unregister: | 84 | out_unregister: |
86 | if (cio_debug_msg_id) | 85 | if (cio_debug_msg_id) |
87 | debug_unregister (cio_debug_msg_id); | 86 | debug_unregister(cio_debug_msg_id); |
88 | if (cio_debug_trace_id) | 87 | if (cio_debug_trace_id) |
89 | debug_unregister (cio_debug_trace_id); | 88 | debug_unregister(cio_debug_trace_id); |
90 | if (cio_debug_crw_id) | 89 | if (cio_debug_crw_id) |
91 | debug_unregister (cio_debug_crw_id); | 90 | debug_unregister(cio_debug_crw_id); |
92 | printk(KERN_WARNING"cio: could not initialize debugging\n"); | 91 | printk(KERN_WARNING"cio: could not initialize debugging\n"); |
93 | return -1; | 92 | return -1; |
94 | } | 93 | } |
@@ -147,7 +146,7 @@ cio_tpi(void) | |||
147 | spin_lock(sch->lock); | 146 | spin_lock(sch->lock); |
148 | memcpy (&sch->schib.scsw, &irb->scsw, sizeof (struct scsw)); | 147 | memcpy (&sch->schib.scsw, &irb->scsw, sizeof (struct scsw)); |
149 | if (sch->driver && sch->driver->irq) | 148 | if (sch->driver && sch->driver->irq) |
150 | sch->driver->irq(&sch->dev); | 149 | sch->driver->irq(sch); |
151 | spin_unlock(sch->lock); | 150 | spin_unlock(sch->lock); |
152 | irq_exit (); | 151 | irq_exit (); |
153 | _local_bh_enable(); | 152 | _local_bh_enable(); |
@@ -184,33 +183,35 @@ cio_start_key (struct subchannel *sch, /* subchannel structure */ | |||
184 | { | 183 | { |
185 | char dbf_txt[15]; | 184 | char dbf_txt[15]; |
186 | int ccode; | 185 | int ccode; |
186 | struct orb *orb; | ||
187 | 187 | ||
188 | CIO_TRACE_EVENT (4, "stIO"); | 188 | CIO_TRACE_EVENT(4, "stIO"); |
189 | CIO_TRACE_EVENT (4, sch->dev.bus_id); | 189 | CIO_TRACE_EVENT(4, sch->dev.bus_id); |
190 | 190 | ||
191 | orb = &to_io_private(sch)->orb; | ||
191 | /* sch is always under 2G. */ | 192 | /* sch is always under 2G. */ |
192 | sch->orb.intparm = (__u32)(unsigned long)sch; | 193 | orb->intparm = (u32)(addr_t)sch; |
193 | sch->orb.fmt = 1; | 194 | orb->fmt = 1; |
194 | 195 | ||
195 | sch->orb.pfch = sch->options.prefetch == 0; | 196 | orb->pfch = sch->options.prefetch == 0; |
196 | sch->orb.spnd = sch->options.suspend; | 197 | orb->spnd = sch->options.suspend; |
197 | sch->orb.ssic = sch->options.suspend && sch->options.inter; | 198 | orb->ssic = sch->options.suspend && sch->options.inter; |
198 | sch->orb.lpm = (lpm != 0) ? lpm : sch->lpm; | 199 | orb->lpm = (lpm != 0) ? lpm : sch->lpm; |
199 | #ifdef CONFIG_64BIT | 200 | #ifdef CONFIG_64BIT |
200 | /* | 201 | /* |
201 | * for 64 bit we always support 64 bit IDAWs with 4k page size only | 202 | * for 64 bit we always support 64 bit IDAWs with 4k page size only |
202 | */ | 203 | */ |
203 | sch->orb.c64 = 1; | 204 | orb->c64 = 1; |
204 | sch->orb.i2k = 0; | 205 | orb->i2k = 0; |
205 | #endif | 206 | #endif |
206 | sch->orb.key = key >> 4; | 207 | orb->key = key >> 4; |
207 | /* issue "Start Subchannel" */ | 208 | /* issue "Start Subchannel" */ |
208 | sch->orb.cpa = (__u32) __pa (cpa); | 209 | orb->cpa = (__u32) __pa(cpa); |
209 | ccode = ssch (sch->schid, &sch->orb); | 210 | ccode = ssch(sch->schid, orb); |
210 | 211 | ||
211 | /* process condition code */ | 212 | /* process condition code */ |
212 | sprintf (dbf_txt, "ccode:%d", ccode); | 213 | sprintf(dbf_txt, "ccode:%d", ccode); |
213 | CIO_TRACE_EVENT (4, dbf_txt); | 214 | CIO_TRACE_EVENT(4, dbf_txt); |
214 | 215 | ||
215 | switch (ccode) { | 216 | switch (ccode) { |
216 | case 0: | 217 | case 0: |
@@ -405,8 +406,8 @@ cio_modify (struct subchannel *sch) | |||
405 | /* | 406 | /* |
406 | * Enable subchannel. | 407 | * Enable subchannel. |
407 | */ | 408 | */ |
408 | int | 409 | int cio_enable_subchannel(struct subchannel *sch, unsigned int isc, |
409 | cio_enable_subchannel (struct subchannel *sch, unsigned int isc) | 410 | u32 intparm) |
410 | { | 411 | { |
411 | char dbf_txt[15]; | 412 | char dbf_txt[15]; |
412 | int ccode; | 413 | int ccode; |
@@ -425,7 +426,7 @@ cio_enable_subchannel (struct subchannel *sch, unsigned int isc) | |||
425 | for (retry = 5, ret = 0; retry > 0; retry--) { | 426 | for (retry = 5, ret = 0; retry > 0; retry--) { |
426 | sch->schib.pmcw.ena = 1; | 427 | sch->schib.pmcw.ena = 1; |
427 | sch->schib.pmcw.isc = isc; | 428 | sch->schib.pmcw.isc = isc; |
428 | sch->schib.pmcw.intparm = (__u32)(unsigned long)sch; | 429 | sch->schib.pmcw.intparm = intparm; |
429 | ret = cio_modify(sch); | 430 | ret = cio_modify(sch); |
430 | if (ret == -ENODEV) | 431 | if (ret == -ENODEV) |
431 | break; | 432 | break; |
@@ -567,7 +568,7 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid) | |||
567 | */ | 568 | */ |
568 | if (sch->st != 0) { | 569 | if (sch->st != 0) { |
569 | CIO_DEBUG(KERN_INFO, 0, | 570 | CIO_DEBUG(KERN_INFO, 0, |
570 | "cio: Subchannel 0.%x.%04x reports " | 571 | "Subchannel 0.%x.%04x reports " |
571 | "non-I/O subchannel type %04X\n", | 572 | "non-I/O subchannel type %04X\n", |
572 | sch->schid.ssid, sch->schid.sch_no, sch->st); | 573 | sch->schid.ssid, sch->schid.sch_no, sch->st); |
573 | /* We stop here for non-io subchannels. */ | 574 | /* We stop here for non-io subchannels. */ |
@@ -576,11 +577,11 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid) | |||
576 | } | 577 | } |
577 | 578 | ||
578 | /* Initialization for io subchannels. */ | 579 | /* Initialization for io subchannels. */ |
579 | if (!sch->schib.pmcw.dnv) { | 580 | if (!css_sch_is_valid(&sch->schib)) { |
580 | /* io subchannel but device number is invalid. */ | ||
581 | err = -ENODEV; | 581 | err = -ENODEV; |
582 | goto out; | 582 | goto out; |
583 | } | 583 | } |
584 | |||
584 | /* Devno is valid. */ | 585 | /* Devno is valid. */ |
585 | if (is_blacklisted (sch->schid.ssid, sch->schib.pmcw.dev)) { | 586 | if (is_blacklisted (sch->schid.ssid, sch->schib.pmcw.dev)) { |
586 | /* | 587 | /* |
@@ -600,7 +601,7 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid) | |||
600 | sch->lpm = sch->schib.pmcw.pam & sch->opm; | 601 | sch->lpm = sch->schib.pmcw.pam & sch->opm; |
601 | 602 | ||
602 | CIO_DEBUG(KERN_INFO, 0, | 603 | CIO_DEBUG(KERN_INFO, 0, |
603 | "cio: Detected device %04x on subchannel 0.%x.%04X" | 604 | "Detected device %04x on subchannel 0.%x.%04X" |
604 | " - PIM = %02X, PAM = %02X, POM = %02X\n", | 605 | " - PIM = %02X, PAM = %02X, POM = %02X\n", |
605 | sch->schib.pmcw.dev, sch->schid.ssid, | 606 | sch->schib.pmcw.dev, sch->schid.ssid, |
606 | sch->schid.sch_no, sch->schib.pmcw.pim, | 607 | sch->schid.sch_no, sch->schib.pmcw.pim, |
@@ -680,7 +681,7 @@ do_IRQ (struct pt_regs *regs) | |||
680 | sizeof (irb->scsw)); | 681 | sizeof (irb->scsw)); |
681 | /* Call interrupt handler if there is one. */ | 682 | /* Call interrupt handler if there is one. */ |
682 | if (sch->driver && sch->driver->irq) | 683 | if (sch->driver && sch->driver->irq) |
683 | sch->driver->irq(&sch->dev); | 684 | sch->driver->irq(sch); |
684 | } | 685 | } |
685 | if (sch) | 686 | if (sch) |
686 | spin_unlock(sch->lock); | 687 | spin_unlock(sch->lock); |
@@ -698,8 +699,14 @@ do_IRQ (struct pt_regs *regs) | |||
698 | 699 | ||
699 | #ifdef CONFIG_CCW_CONSOLE | 700 | #ifdef CONFIG_CCW_CONSOLE |
700 | static struct subchannel console_subchannel; | 701 | static struct subchannel console_subchannel; |
702 | static struct io_subchannel_private console_priv; | ||
701 | static int console_subchannel_in_use; | 703 | static int console_subchannel_in_use; |
702 | 704 | ||
705 | void *cio_get_console_priv(void) | ||
706 | { | ||
707 | return &console_priv; | ||
708 | } | ||
709 | |||
703 | /* | 710 | /* |
704 | * busy wait for the next interrupt on the console | 711 | * busy wait for the next interrupt on the console |
705 | */ | 712 | */ |
@@ -738,9 +745,9 @@ cio_test_for_console(struct subchannel_id schid, void *data) | |||
738 | { | 745 | { |
739 | if (stsch_err(schid, &console_subchannel.schib) != 0) | 746 | if (stsch_err(schid, &console_subchannel.schib) != 0) |
740 | return -ENXIO; | 747 | return -ENXIO; |
741 | if (console_subchannel.schib.pmcw.dnv && | 748 | if ((console_subchannel.schib.pmcw.st == SUBCHANNEL_TYPE_IO) && |
742 | console_subchannel.schib.pmcw.dev == | 749 | console_subchannel.schib.pmcw.dnv && |
743 | console_devno) { | 750 | (console_subchannel.schib.pmcw.dev == console_devno)) { |
744 | console_irq = schid.sch_no; | 751 | console_irq = schid.sch_no; |
745 | return 1; /* found */ | 752 | return 1; /* found */ |
746 | } | 753 | } |
@@ -758,6 +765,7 @@ cio_get_console_sch_no(void) | |||
758 | /* VM provided us with the irq number of the console. */ | 765 | /* VM provided us with the irq number of the console. */ |
759 | schid.sch_no = console_irq; | 766 | schid.sch_no = console_irq; |
760 | if (stsch(schid, &console_subchannel.schib) != 0 || | 767 | if (stsch(schid, &console_subchannel.schib) != 0 || |
768 | (console_subchannel.schib.pmcw.st != SUBCHANNEL_TYPE_IO) || | ||
761 | !console_subchannel.schib.pmcw.dnv) | 769 | !console_subchannel.schib.pmcw.dnv) |
762 | return -1; | 770 | return -1; |
763 | console_devno = console_subchannel.schib.pmcw.dev; | 771 | console_devno = console_subchannel.schib.pmcw.dev; |
@@ -804,7 +812,7 @@ cio_probe_console(void) | |||
804 | ctl_set_bit(6, 24); | 812 | ctl_set_bit(6, 24); |
805 | console_subchannel.schib.pmcw.isc = 7; | 813 | console_subchannel.schib.pmcw.isc = 7; |
806 | console_subchannel.schib.pmcw.intparm = | 814 | console_subchannel.schib.pmcw.intparm = |
807 | (__u32)(unsigned long)&console_subchannel; | 815 | (u32)(addr_t)&console_subchannel; |
808 | ret = cio_modify(&console_subchannel); | 816 | ret = cio_modify(&console_subchannel); |
809 | if (ret) { | 817 | if (ret) { |
810 | console_subchannel_in_use = 0; | 818 | console_subchannel_in_use = 0; |
@@ -1022,7 +1030,7 @@ static int __reipl_subchannel_match(struct subchannel_id schid, void *data) | |||
1022 | 1030 | ||
1023 | if (stsch_reset(schid, &schib)) | 1031 | if (stsch_reset(schid, &schib)) |
1024 | return -ENXIO; | 1032 | return -ENXIO; |
1025 | if (schib.pmcw.dnv && | 1033 | if ((schib.pmcw.st == SUBCHANNEL_TYPE_IO) && schib.pmcw.dnv && |
1026 | (schib.pmcw.dev == match_id->devid.devno) && | 1034 | (schib.pmcw.dev == match_id->devid.devno) && |
1027 | (schid.ssid == match_id->devid.ssid)) { | 1035 | (schid.ssid == match_id->devid.ssid)) { |
1028 | match_id->schid = schid; | 1036 | match_id->schid = schid; |
@@ -1068,6 +1076,8 @@ int __init cio_get_iplinfo(struct cio_iplinfo *iplinfo) | |||
1068 | return -ENODEV; | 1076 | return -ENODEV; |
1069 | if (stsch(schid, &schib)) | 1077 | if (stsch(schid, &schib)) |
1070 | return -ENODEV; | 1078 | return -ENODEV; |
1079 | if (schib.pmcw.st != SUBCHANNEL_TYPE_IO) | ||
1080 | return -ENODEV; | ||
1071 | if (!schib.pmcw.dnv) | 1081 | if (!schib.pmcw.dnv) |
1072 | return -ENODEV; | 1082 | return -ENODEV; |
1073 | iplinfo->devno = schib.pmcw.dev; | 1083 | iplinfo->devno = schib.pmcw.dev; |
diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h index 7446c39951a7..52afa4c784de 100644 --- a/drivers/s390/cio/cio.h +++ b/drivers/s390/cio/cio.h | |||
@@ -11,32 +11,32 @@ | |||
11 | * path management control word | 11 | * path management control word |
12 | */ | 12 | */ |
13 | struct pmcw { | 13 | struct pmcw { |
14 | __u32 intparm; /* interruption parameter */ | 14 | u32 intparm; /* interruption parameter */ |
15 | __u32 qf : 1; /* qdio facility */ | 15 | u32 qf : 1; /* qdio facility */ |
16 | __u32 res0 : 1; /* reserved zeros */ | 16 | u32 res0 : 1; /* reserved zeros */ |
17 | __u32 isc : 3; /* interruption sublass */ | 17 | u32 isc : 3; /* interruption sublass */ |
18 | __u32 res5 : 3; /* reserved zeros */ | 18 | u32 res5 : 3; /* reserved zeros */ |
19 | __u32 ena : 1; /* enabled */ | 19 | u32 ena : 1; /* enabled */ |
20 | __u32 lm : 2; /* limit mode */ | 20 | u32 lm : 2; /* limit mode */ |
21 | __u32 mme : 2; /* measurement-mode enable */ | 21 | u32 mme : 2; /* measurement-mode enable */ |
22 | __u32 mp : 1; /* multipath mode */ | 22 | u32 mp : 1; /* multipath mode */ |
23 | __u32 tf : 1; /* timing facility */ | 23 | u32 tf : 1; /* timing facility */ |
24 | __u32 dnv : 1; /* device number valid */ | 24 | u32 dnv : 1; /* device number valid */ |
25 | __u32 dev : 16; /* device number */ | 25 | u32 dev : 16; /* device number */ |
26 | __u8 lpm; /* logical path mask */ | 26 | u8 lpm; /* logical path mask */ |
27 | __u8 pnom; /* path not operational mask */ | 27 | u8 pnom; /* path not operational mask */ |
28 | __u8 lpum; /* last path used mask */ | 28 | u8 lpum; /* last path used mask */ |
29 | __u8 pim; /* path installed mask */ | 29 | u8 pim; /* path installed mask */ |
30 | __u16 mbi; /* measurement-block index */ | 30 | u16 mbi; /* measurement-block index */ |
31 | __u8 pom; /* path operational mask */ | 31 | u8 pom; /* path operational mask */ |
32 | __u8 pam; /* path available mask */ | 32 | u8 pam; /* path available mask */ |
33 | __u8 chpid[8]; /* CHPID 0-7 (if available) */ | 33 | u8 chpid[8]; /* CHPID 0-7 (if available) */ |
34 | __u32 unused1 : 8; /* reserved zeros */ | 34 | u32 unused1 : 8; /* reserved zeros */ |
35 | __u32 st : 3; /* subchannel type */ | 35 | u32 st : 3; /* subchannel type */ |
36 | __u32 unused2 : 18; /* reserved zeros */ | 36 | u32 unused2 : 18; /* reserved zeros */ |
37 | __u32 mbfc : 1; /* measurement block format control */ | 37 | u32 mbfc : 1; /* measurement block format control */ |
38 | __u32 xmwme : 1; /* extended measurement word mode enable */ | 38 | u32 xmwme : 1; /* extended measurement word mode enable */ |
39 | __u32 csense : 1; /* concurrent sense; can be enabled ...*/ | 39 | u32 csense : 1; /* concurrent sense; can be enabled ...*/ |
40 | /* ... per MSCH, however, if facility */ | 40 | /* ... per MSCH, however, if facility */ |
41 | /* ... is not installed, this results */ | 41 | /* ... is not installed, this results */ |
42 | /* ... in an operand exception. */ | 42 | /* ... in an operand exception. */ |
@@ -52,31 +52,6 @@ struct schib { | |||
52 | __u8 mda[4]; /* model dependent area */ | 52 | __u8 mda[4]; /* model dependent area */ |
53 | } __attribute__ ((packed,aligned(4))); | 53 | } __attribute__ ((packed,aligned(4))); |
54 | 54 | ||
55 | /* | ||
56 | * operation request block | ||
57 | */ | ||
58 | struct orb { | ||
59 | __u32 intparm; /* interruption parameter */ | ||
60 | __u32 key : 4; /* flags, like key, suspend control, etc. */ | ||
61 | __u32 spnd : 1; /* suspend control */ | ||
62 | __u32 res1 : 1; /* reserved */ | ||
63 | __u32 mod : 1; /* modification control */ | ||
64 | __u32 sync : 1; /* synchronize control */ | ||
65 | __u32 fmt : 1; /* format control */ | ||
66 | __u32 pfch : 1; /* prefetch control */ | ||
67 | __u32 isic : 1; /* initial-status-interruption control */ | ||
68 | __u32 alcc : 1; /* address-limit-checking control */ | ||
69 | __u32 ssic : 1; /* suppress-suspended-interr. control */ | ||
70 | __u32 res2 : 1; /* reserved */ | ||
71 | __u32 c64 : 1; /* IDAW/QDIO 64 bit control */ | ||
72 | __u32 i2k : 1; /* IDAW 2/4kB block size control */ | ||
73 | __u32 lpm : 8; /* logical path mask */ | ||
74 | __u32 ils : 1; /* incorrect length */ | ||
75 | __u32 zero : 6; /* reserved zeros */ | ||
76 | __u32 orbx : 1; /* ORB extension control */ | ||
77 | __u32 cpa; /* channel program address */ | ||
78 | } __attribute__ ((packed,aligned(4))); | ||
79 | |||
80 | /* subchannel data structure used by I/O subroutines */ | 55 | /* subchannel data structure used by I/O subroutines */ |
81 | struct subchannel { | 56 | struct subchannel { |
82 | struct subchannel_id schid; | 57 | struct subchannel_id schid; |
@@ -85,7 +60,7 @@ struct subchannel { | |||
85 | enum { | 60 | enum { |
86 | SUBCHANNEL_TYPE_IO = 0, | 61 | SUBCHANNEL_TYPE_IO = 0, |
87 | SUBCHANNEL_TYPE_CHSC = 1, | 62 | SUBCHANNEL_TYPE_CHSC = 1, |
88 | SUBCHANNEL_TYPE_MESSAGE = 2, | 63 | SUBCHANNEL_TYPE_MSG = 2, |
89 | SUBCHANNEL_TYPE_ADM = 3, | 64 | SUBCHANNEL_TYPE_ADM = 3, |
90 | } st; /* subchannel type */ | 65 | } st; /* subchannel type */ |
91 | 66 | ||
@@ -99,11 +74,10 @@ struct subchannel { | |||
99 | __u8 lpm; /* logical path mask */ | 74 | __u8 lpm; /* logical path mask */ |
100 | __u8 opm; /* operational path mask */ | 75 | __u8 opm; /* operational path mask */ |
101 | struct schib schib; /* subchannel information block */ | 76 | struct schib schib; /* subchannel information block */ |
102 | struct orb orb; /* operation request block */ | ||
103 | struct ccw1 sense_ccw; /* static ccw for sense command */ | ||
104 | struct chsc_ssd_info ssd_info; /* subchannel description */ | 77 | struct chsc_ssd_info ssd_info; /* subchannel description */ |
105 | struct device dev; /* entry in device tree */ | 78 | struct device dev; /* entry in device tree */ |
106 | struct css_driver *driver; | 79 | struct css_driver *driver; |
80 | void *private; /* private per subchannel type data */ | ||
107 | } __attribute__ ((aligned(8))); | 81 | } __attribute__ ((aligned(8))); |
108 | 82 | ||
109 | #define IO_INTERRUPT_TYPE 0 /* I/O interrupt type */ | 83 | #define IO_INTERRUPT_TYPE 0 /* I/O interrupt type */ |
@@ -111,7 +85,7 @@ struct subchannel { | |||
111 | #define to_subchannel(n) container_of(n, struct subchannel, dev) | 85 | #define to_subchannel(n) container_of(n, struct subchannel, dev) |
112 | 86 | ||
113 | extern int cio_validate_subchannel (struct subchannel *, struct subchannel_id); | 87 | extern int cio_validate_subchannel (struct subchannel *, struct subchannel_id); |
114 | extern int cio_enable_subchannel (struct subchannel *, unsigned int); | 88 | extern int cio_enable_subchannel(struct subchannel *, unsigned int, u32); |
115 | extern int cio_disable_subchannel (struct subchannel *); | 89 | extern int cio_disable_subchannel (struct subchannel *); |
116 | extern int cio_cancel (struct subchannel *); | 90 | extern int cio_cancel (struct subchannel *); |
117 | extern int cio_clear (struct subchannel *); | 91 | extern int cio_clear (struct subchannel *); |
@@ -125,6 +99,7 @@ extern int cio_get_options (struct subchannel *); | |||
125 | extern int cio_modify (struct subchannel *); | 99 | extern int cio_modify (struct subchannel *); |
126 | 100 | ||
127 | int cio_create_sch_lock(struct subchannel *); | 101 | int cio_create_sch_lock(struct subchannel *); |
102 | void do_adapter_IO(void); | ||
128 | 103 | ||
129 | /* Use with care. */ | 104 | /* Use with care. */ |
130 | #ifdef CONFIG_CCW_CONSOLE | 105 | #ifdef CONFIG_CCW_CONSOLE |
@@ -133,10 +108,12 @@ extern void cio_release_console(void); | |||
133 | extern int cio_is_console(struct subchannel_id); | 108 | extern int cio_is_console(struct subchannel_id); |
134 | extern struct subchannel *cio_get_console_subchannel(void); | 109 | extern struct subchannel *cio_get_console_subchannel(void); |
135 | extern spinlock_t * cio_get_console_lock(void); | 110 | extern spinlock_t * cio_get_console_lock(void); |
111 | extern void *cio_get_console_priv(void); | ||
136 | #else | 112 | #else |
137 | #define cio_is_console(schid) 0 | 113 | #define cio_is_console(schid) 0 |
138 | #define cio_get_console_subchannel() NULL | 114 | #define cio_get_console_subchannel() NULL |
139 | #define cio_get_console_lock() NULL; | 115 | #define cio_get_console_lock() NULL |
116 | #define cio_get_console_priv() NULL | ||
140 | #endif | 117 | #endif |
141 | 118 | ||
142 | extern int cio_show_msg; | 119 | extern int cio_show_msg; |
diff --git a/drivers/s390/cio/cio_debug.h b/drivers/s390/cio/cio_debug.h index c9bf8989930f..d7429ef6c666 100644 --- a/drivers/s390/cio/cio_debug.h +++ b/drivers/s390/cio/cio_debug.h | |||
@@ -8,20 +8,19 @@ extern debug_info_t *cio_debug_msg_id; | |||
8 | extern debug_info_t *cio_debug_trace_id; | 8 | extern debug_info_t *cio_debug_trace_id; |
9 | extern debug_info_t *cio_debug_crw_id; | 9 | extern debug_info_t *cio_debug_crw_id; |
10 | 10 | ||
11 | #define CIO_TRACE_EVENT(imp, txt) do { \ | 11 | #define CIO_TRACE_EVENT(imp, txt) do { \ |
12 | debug_text_event(cio_debug_trace_id, imp, txt); \ | 12 | debug_text_event(cio_debug_trace_id, imp, txt); \ |
13 | } while (0) | 13 | } while (0) |
14 | 14 | ||
15 | #define CIO_MSG_EVENT(imp, args...) do { \ | 15 | #define CIO_MSG_EVENT(imp, args...) do { \ |
16 | debug_sprintf_event(cio_debug_msg_id, imp , ##args); \ | 16 | debug_sprintf_event(cio_debug_msg_id, imp , ##args); \ |
17 | } while (0) | 17 | } while (0) |
18 | 18 | ||
19 | #define CIO_CRW_EVENT(imp, args...) do { \ | 19 | #define CIO_CRW_EVENT(imp, args...) do { \ |
20 | debug_sprintf_event(cio_debug_crw_id, imp , ##args); \ | 20 | debug_sprintf_event(cio_debug_crw_id, imp , ##args); \ |
21 | } while (0) | 21 | } while (0) |
22 | 22 | ||
23 | static inline void | 23 | static inline void CIO_HEX_EVENT(int level, void *data, int length) |
24 | CIO_HEX_EVENT(int level, void *data, int length) | ||
25 | { | 24 | { |
26 | if (unlikely(!cio_debug_trace_id)) | 25 | if (unlikely(!cio_debug_trace_id)) |
27 | return; | 26 | return; |
@@ -32,9 +31,10 @@ CIO_HEX_EVENT(int level, void *data, int length) | |||
32 | } | 31 | } |
33 | } | 32 | } |
34 | 33 | ||
35 | #define CIO_DEBUG(printk_level,event_level,msg...) ({ \ | 34 | #define CIO_DEBUG(printk_level, event_level, msg...) do { \ |
36 | if (cio_show_msg) printk(printk_level msg); \ | 35 | if (cio_show_msg) \ |
37 | CIO_MSG_EVENT (event_level, msg); \ | 36 | printk(printk_level "cio: " msg); \ |
38 | }) | 37 | CIO_MSG_EVENT(event_level, msg); \ |
38 | } while (0) | ||
39 | 39 | ||
40 | #endif | 40 | #endif |
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index c3df2cd009a4..3b45bbe6cce0 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c | |||
@@ -51,6 +51,62 @@ for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *data) | |||
51 | return ret; | 51 | return ret; |
52 | } | 52 | } |
53 | 53 | ||
54 | struct cb_data { | ||
55 | void *data; | ||
56 | struct idset *set; | ||
57 | int (*fn_known_sch)(struct subchannel *, void *); | ||
58 | int (*fn_unknown_sch)(struct subchannel_id, void *); | ||
59 | }; | ||
60 | |||
61 | static int call_fn_known_sch(struct device *dev, void *data) | ||
62 | { | ||
63 | struct subchannel *sch = to_subchannel(dev); | ||
64 | struct cb_data *cb = data; | ||
65 | int rc = 0; | ||
66 | |||
67 | idset_sch_del(cb->set, sch->schid); | ||
68 | if (cb->fn_known_sch) | ||
69 | rc = cb->fn_known_sch(sch, cb->data); | ||
70 | return rc; | ||
71 | } | ||
72 | |||
73 | static int call_fn_unknown_sch(struct subchannel_id schid, void *data) | ||
74 | { | ||
75 | struct cb_data *cb = data; | ||
76 | int rc = 0; | ||
77 | |||
78 | if (idset_sch_contains(cb->set, schid)) | ||
79 | rc = cb->fn_unknown_sch(schid, cb->data); | ||
80 | return rc; | ||
81 | } | ||
82 | |||
83 | int for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *), | ||
84 | int (*fn_unknown)(struct subchannel_id, | ||
85 | void *), void *data) | ||
86 | { | ||
87 | struct cb_data cb; | ||
88 | int rc; | ||
89 | |||
90 | cb.set = idset_sch_new(); | ||
91 | if (!cb.set) | ||
92 | return -ENOMEM; | ||
93 | idset_fill(cb.set); | ||
94 | cb.data = data; | ||
95 | cb.fn_known_sch = fn_known; | ||
96 | cb.fn_unknown_sch = fn_unknown; | ||
97 | /* Process registered subchannels. */ | ||
98 | rc = bus_for_each_dev(&css_bus_type, NULL, &cb, call_fn_known_sch); | ||
99 | if (rc) | ||
100 | goto out; | ||
101 | /* Process unregistered subchannels. */ | ||
102 | if (fn_unknown) | ||
103 | rc = for_each_subchannel(call_fn_unknown_sch, &cb); | ||
104 | out: | ||
105 | idset_free(cb.set); | ||
106 | |||
107 | return rc; | ||
108 | } | ||
109 | |||
54 | static struct subchannel * | 110 | static struct subchannel * |
55 | css_alloc_subchannel(struct subchannel_id schid) | 111 | css_alloc_subchannel(struct subchannel_id schid) |
56 | { | 112 | { |
@@ -77,7 +133,7 @@ css_alloc_subchannel(struct subchannel_id schid) | |||
77 | * This is fine even on 64bit since the subchannel is always located | 133 | * This is fine even on 64bit since the subchannel is always located |
78 | * under 2G. | 134 | * under 2G. |
79 | */ | 135 | */ |
80 | sch->schib.pmcw.intparm = (__u32)(unsigned long)sch; | 136 | sch->schib.pmcw.intparm = (u32)(addr_t)sch; |
81 | ret = cio_modify(sch); | 137 | ret = cio_modify(sch); |
82 | if (ret) { | 138 | if (ret) { |
83 | kfree(sch->lock); | 139 | kfree(sch->lock); |
@@ -237,11 +293,25 @@ get_subchannel_by_schid(struct subchannel_id schid) | |||
237 | return dev ? to_subchannel(dev) : NULL; | 293 | return dev ? to_subchannel(dev) : NULL; |
238 | } | 294 | } |
239 | 295 | ||
296 | /** | ||
297 | * css_sch_is_valid() - check if a subchannel is valid | ||
298 | * @schib: subchannel information block for the subchannel | ||
299 | */ | ||
300 | int css_sch_is_valid(struct schib *schib) | ||
301 | { | ||
302 | if ((schib->pmcw.st == SUBCHANNEL_TYPE_IO) && !schib->pmcw.dnv) | ||
303 | return 0; | ||
304 | return 1; | ||
305 | } | ||
306 | EXPORT_SYMBOL_GPL(css_sch_is_valid); | ||
307 | |||
240 | static int css_get_subchannel_status(struct subchannel *sch) | 308 | static int css_get_subchannel_status(struct subchannel *sch) |
241 | { | 309 | { |
242 | struct schib schib; | 310 | struct schib schib; |
243 | 311 | ||
244 | if (stsch(sch->schid, &schib) || !schib.pmcw.dnv) | 312 | if (stsch(sch->schid, &schib)) |
313 | return CIO_GONE; | ||
314 | if (!css_sch_is_valid(&schib)) | ||
245 | return CIO_GONE; | 315 | return CIO_GONE; |
246 | if (sch->schib.pmcw.dnv && (schib.pmcw.dev != sch->schib.pmcw.dev)) | 316 | if (sch->schib.pmcw.dnv && (schib.pmcw.dev != sch->schib.pmcw.dev)) |
247 | return CIO_REVALIDATE; | 317 | return CIO_REVALIDATE; |
@@ -293,7 +363,7 @@ static int css_evaluate_known_subchannel(struct subchannel *sch, int slow) | |||
293 | action = UNREGISTER; | 363 | action = UNREGISTER; |
294 | if (sch->driver && sch->driver->notify) { | 364 | if (sch->driver && sch->driver->notify) { |
295 | spin_unlock_irqrestore(sch->lock, flags); | 365 | spin_unlock_irqrestore(sch->lock, flags); |
296 | ret = sch->driver->notify(&sch->dev, event); | 366 | ret = sch->driver->notify(sch, event); |
297 | spin_lock_irqsave(sch->lock, flags); | 367 | spin_lock_irqsave(sch->lock, flags); |
298 | if (ret) | 368 | if (ret) |
299 | action = NONE; | 369 | action = NONE; |
@@ -349,7 +419,7 @@ static int css_evaluate_new_subchannel(struct subchannel_id schid, int slow) | |||
349 | /* Will be done on the slow path. */ | 419 | /* Will be done on the slow path. */ |
350 | return -EAGAIN; | 420 | return -EAGAIN; |
351 | } | 421 | } |
352 | if (stsch_err(schid, &schib) || !schib.pmcw.dnv) { | 422 | if (stsch_err(schid, &schib) || !css_sch_is_valid(&schib)) { |
353 | /* Unusable - ignore. */ | 423 | /* Unusable - ignore. */ |
354 | return 0; | 424 | return 0; |
355 | } | 425 | } |
@@ -388,20 +458,56 @@ static int __init slow_subchannel_init(void) | |||
388 | return 0; | 458 | return 0; |
389 | } | 459 | } |
390 | 460 | ||
391 | static void css_slow_path_func(struct work_struct *unused) | 461 | static int slow_eval_known_fn(struct subchannel *sch, void *data) |
392 | { | 462 | { |
393 | struct subchannel_id schid; | 463 | int eval; |
464 | int rc; | ||
394 | 465 | ||
395 | CIO_TRACE_EVENT(4, "slowpath"); | ||
396 | spin_lock_irq(&slow_subchannel_lock); | 466 | spin_lock_irq(&slow_subchannel_lock); |
397 | init_subchannel_id(&schid); | 467 | eval = idset_sch_contains(slow_subchannel_set, sch->schid); |
398 | while (idset_sch_get_first(slow_subchannel_set, &schid)) { | 468 | idset_sch_del(slow_subchannel_set, sch->schid); |
399 | idset_sch_del(slow_subchannel_set, schid); | 469 | spin_unlock_irq(&slow_subchannel_lock); |
400 | spin_unlock_irq(&slow_subchannel_lock); | 470 | if (eval) { |
401 | css_evaluate_subchannel(schid, 1); | 471 | rc = css_evaluate_known_subchannel(sch, 1); |
402 | spin_lock_irq(&slow_subchannel_lock); | 472 | if (rc == -EAGAIN) |
473 | css_schedule_eval(sch->schid); | ||
403 | } | 474 | } |
475 | return 0; | ||
476 | } | ||
477 | |||
478 | static int slow_eval_unknown_fn(struct subchannel_id schid, void *data) | ||
479 | { | ||
480 | int eval; | ||
481 | int rc = 0; | ||
482 | |||
483 | spin_lock_irq(&slow_subchannel_lock); | ||
484 | eval = idset_sch_contains(slow_subchannel_set, schid); | ||
485 | idset_sch_del(slow_subchannel_set, schid); | ||
404 | spin_unlock_irq(&slow_subchannel_lock); | 486 | spin_unlock_irq(&slow_subchannel_lock); |
487 | if (eval) { | ||
488 | rc = css_evaluate_new_subchannel(schid, 1); | ||
489 | switch (rc) { | ||
490 | case -EAGAIN: | ||
491 | css_schedule_eval(schid); | ||
492 | rc = 0; | ||
493 | break; | ||
494 | case -ENXIO: | ||
495 | case -ENOMEM: | ||
496 | case -EIO: | ||
497 | /* These should abort looping */ | ||
498 | break; | ||
499 | default: | ||
500 | rc = 0; | ||
501 | } | ||
502 | } | ||
503 | return rc; | ||
504 | } | ||
505 | |||
506 | static void css_slow_path_func(struct work_struct *unused) | ||
507 | { | ||
508 | CIO_TRACE_EVENT(4, "slowpath"); | ||
509 | for_each_subchannel_staged(slow_eval_known_fn, slow_eval_unknown_fn, | ||
510 | NULL); | ||
405 | } | 511 | } |
406 | 512 | ||
407 | static DECLARE_WORK(slow_path_work, css_slow_path_func); | 513 | static DECLARE_WORK(slow_path_work, css_slow_path_func); |
@@ -430,7 +536,6 @@ void css_schedule_eval_all(void) | |||
430 | /* Reprobe subchannel if unregistered. */ | 536 | /* Reprobe subchannel if unregistered. */ |
431 | static int reprobe_subchannel(struct subchannel_id schid, void *data) | 537 | static int reprobe_subchannel(struct subchannel_id schid, void *data) |
432 | { | 538 | { |
433 | struct subchannel *sch; | ||
434 | int ret; | 539 | int ret; |
435 | 540 | ||
436 | CIO_MSG_EVENT(6, "cio: reprobe 0.%x.%04x\n", | 541 | CIO_MSG_EVENT(6, "cio: reprobe 0.%x.%04x\n", |
@@ -438,13 +543,6 @@ static int reprobe_subchannel(struct subchannel_id schid, void *data) | |||
438 | if (need_reprobe) | 543 | if (need_reprobe) |
439 | return -EAGAIN; | 544 | return -EAGAIN; |
440 | 545 | ||
441 | sch = get_subchannel_by_schid(schid); | ||
442 | if (sch) { | ||
443 | /* Already known. */ | ||
444 | put_device(&sch->dev); | ||
445 | return 0; | ||
446 | } | ||
447 | |||
448 | ret = css_probe_device(schid); | 546 | ret = css_probe_device(schid); |
449 | switch (ret) { | 547 | switch (ret) { |
450 | case 0: | 548 | case 0: |
@@ -472,7 +570,7 @@ static void reprobe_all(struct work_struct *unused) | |||
472 | /* Make sure initial subchannel scan is done. */ | 570 | /* Make sure initial subchannel scan is done. */ |
473 | wait_event(ccw_device_init_wq, | 571 | wait_event(ccw_device_init_wq, |
474 | atomic_read(&ccw_device_init_count) == 0); | 572 | atomic_read(&ccw_device_init_count) == 0); |
475 | ret = for_each_subchannel(reprobe_subchannel, NULL); | 573 | ret = for_each_subchannel_staged(NULL, reprobe_subchannel, NULL); |
476 | 574 | ||
477 | CIO_MSG_EVENT(2, "reprobe done (rc=%d, need_reprobe=%d)\n", ret, | 575 | CIO_MSG_EVENT(2, "reprobe done (rc=%d, need_reprobe=%d)\n", ret, |
478 | need_reprobe); | 576 | need_reprobe); |
@@ -787,8 +885,8 @@ int sch_is_pseudo_sch(struct subchannel *sch) | |||
787 | static int | 885 | static int |
788 | css_bus_match (struct device *dev, struct device_driver *drv) | 886 | css_bus_match (struct device *dev, struct device_driver *drv) |
789 | { | 887 | { |
790 | struct subchannel *sch = container_of (dev, struct subchannel, dev); | 888 | struct subchannel *sch = to_subchannel(dev); |
791 | struct css_driver *driver = container_of (drv, struct css_driver, drv); | 889 | struct css_driver *driver = to_cssdriver(drv); |
792 | 890 | ||
793 | if (sch->st == driver->subchannel_type) | 891 | if (sch->st == driver->subchannel_type) |
794 | return 1; | 892 | return 1; |
@@ -796,32 +894,36 @@ css_bus_match (struct device *dev, struct device_driver *drv) | |||
796 | return 0; | 894 | return 0; |
797 | } | 895 | } |
798 | 896 | ||
799 | static int | 897 | static int css_probe(struct device *dev) |
800 | css_probe (struct device *dev) | ||
801 | { | 898 | { |
802 | struct subchannel *sch; | 899 | struct subchannel *sch; |
900 | int ret; | ||
803 | 901 | ||
804 | sch = to_subchannel(dev); | 902 | sch = to_subchannel(dev); |
805 | sch->driver = container_of (dev->driver, struct css_driver, drv); | 903 | sch->driver = to_cssdriver(dev->driver); |
806 | return (sch->driver->probe ? sch->driver->probe(sch) : 0); | 904 | ret = sch->driver->probe ? sch->driver->probe(sch) : 0; |
905 | if (ret) | ||
906 | sch->driver = NULL; | ||
907 | return ret; | ||
807 | } | 908 | } |
808 | 909 | ||
809 | static int | 910 | static int css_remove(struct device *dev) |
810 | css_remove (struct device *dev) | ||
811 | { | 911 | { |
812 | struct subchannel *sch; | 912 | struct subchannel *sch; |
913 | int ret; | ||
813 | 914 | ||
814 | sch = to_subchannel(dev); | 915 | sch = to_subchannel(dev); |
815 | return (sch->driver->remove ? sch->driver->remove(sch) : 0); | 916 | ret = sch->driver->remove ? sch->driver->remove(sch) : 0; |
917 | sch->driver = NULL; | ||
918 | return ret; | ||
816 | } | 919 | } |
817 | 920 | ||
818 | static void | 921 | static void css_shutdown(struct device *dev) |
819 | css_shutdown (struct device *dev) | ||
820 | { | 922 | { |
821 | struct subchannel *sch; | 923 | struct subchannel *sch; |
822 | 924 | ||
823 | sch = to_subchannel(dev); | 925 | sch = to_subchannel(dev); |
824 | if (sch->driver->shutdown) | 926 | if (sch->driver && sch->driver->shutdown) |
825 | sch->driver->shutdown(sch); | 927 | sch->driver->shutdown(sch); |
826 | } | 928 | } |
827 | 929 | ||
@@ -833,6 +935,34 @@ struct bus_type css_bus_type = { | |||
833 | .shutdown = css_shutdown, | 935 | .shutdown = css_shutdown, |
834 | }; | 936 | }; |
835 | 937 | ||
938 | /** | ||
939 | * css_driver_register - register a css driver | ||
940 | * @cdrv: css driver to register | ||
941 | * | ||
942 | * This is mainly a wrapper around driver_register that sets name | ||
943 | * and bus_type in the embedded struct device_driver correctly. | ||
944 | */ | ||
945 | int css_driver_register(struct css_driver *cdrv) | ||
946 | { | ||
947 | cdrv->drv.name = cdrv->name; | ||
948 | cdrv->drv.bus = &css_bus_type; | ||
949 | cdrv->drv.owner = cdrv->owner; | ||
950 | return driver_register(&cdrv->drv); | ||
951 | } | ||
952 | EXPORT_SYMBOL_GPL(css_driver_register); | ||
953 | |||
954 | /** | ||
955 | * css_driver_unregister - unregister a css driver | ||
956 | * @cdrv: css driver to unregister | ||
957 | * | ||
958 | * This is a wrapper around driver_unregister. | ||
959 | */ | ||
960 | void css_driver_unregister(struct css_driver *cdrv) | ||
961 | { | ||
962 | driver_unregister(&cdrv->drv); | ||
963 | } | ||
964 | EXPORT_SYMBOL_GPL(css_driver_unregister); | ||
965 | |||
836 | subsys_initcall(init_channel_subsystem); | 966 | subsys_initcall(init_channel_subsystem); |
837 | 967 | ||
838 | MODULE_LICENSE("GPL"); | 968 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h index 81215ef32435..b70554523552 100644 --- a/drivers/s390/cio/css.h +++ b/drivers/s390/cio/css.h | |||
@@ -58,64 +58,6 @@ struct pgid { | |||
58 | __u32 tod_high; /* high word TOD clock */ | 58 | __u32 tod_high; /* high word TOD clock */ |
59 | } __attribute__ ((packed)); | 59 | } __attribute__ ((packed)); |
60 | 60 | ||
61 | #define MAX_CIWS 8 | ||
62 | |||
63 | /* | ||
64 | * sense-id response buffer layout | ||
65 | */ | ||
66 | struct senseid { | ||
67 | /* common part */ | ||
68 | __u8 reserved; /* always 0x'FF' */ | ||
69 | __u16 cu_type; /* control unit type */ | ||
70 | __u8 cu_model; /* control unit model */ | ||
71 | __u16 dev_type; /* device type */ | ||
72 | __u8 dev_model; /* device model */ | ||
73 | __u8 unused; /* padding byte */ | ||
74 | /* extended part */ | ||
75 | struct ciw ciw[MAX_CIWS]; /* variable # of CIWs */ | ||
76 | } __attribute__ ((packed,aligned(4))); | ||
77 | |||
78 | struct ccw_device_private { | ||
79 | struct ccw_device *cdev; | ||
80 | struct subchannel *sch; | ||
81 | int state; /* device state */ | ||
82 | atomic_t onoff; | ||
83 | unsigned long registered; | ||
84 | struct ccw_dev_id dev_id; /* device id */ | ||
85 | struct subchannel_id schid; /* subchannel number */ | ||
86 | __u8 imask; /* lpm mask for SNID/SID/SPGID */ | ||
87 | int iretry; /* retry counter SNID/SID/SPGID */ | ||
88 | struct { | ||
89 | unsigned int fast:1; /* post with "channel end" */ | ||
90 | unsigned int repall:1; /* report every interrupt status */ | ||
91 | unsigned int pgroup:1; /* do path grouping */ | ||
92 | unsigned int force:1; /* allow forced online */ | ||
93 | } __attribute__ ((packed)) options; | ||
94 | struct { | ||
95 | unsigned int pgid_single:1; /* use single path for Set PGID */ | ||
96 | unsigned int esid:1; /* Ext. SenseID supported by HW */ | ||
97 | unsigned int dosense:1; /* delayed SENSE required */ | ||
98 | unsigned int doverify:1; /* delayed path verification */ | ||
99 | unsigned int donotify:1; /* call notify function */ | ||
100 | unsigned int recog_done:1; /* dev. recog. complete */ | ||
101 | unsigned int fake_irb:1; /* deliver faked irb */ | ||
102 | unsigned int intretry:1; /* retry internal operation */ | ||
103 | } __attribute__((packed)) flags; | ||
104 | unsigned long intparm; /* user interruption parameter */ | ||
105 | struct qdio_irq *qdio_data; | ||
106 | struct irb irb; /* device status */ | ||
107 | struct senseid senseid; /* SenseID info */ | ||
108 | struct pgid pgid[8]; /* path group IDs per chpid*/ | ||
109 | struct ccw1 iccws[2]; /* ccws for SNID/SID/SPGID commands */ | ||
110 | struct work_struct kick_work; | ||
111 | wait_queue_head_t wait_q; | ||
112 | struct timer_list timer; | ||
113 | void *cmb; /* measurement information */ | ||
114 | struct list_head cmb_list; /* list of measured devices */ | ||
115 | u64 cmb_start_time; /* clock value of cmb reset */ | ||
116 | void *cmb_wait; /* deferred cmb enable/disable */ | ||
117 | }; | ||
118 | |||
119 | /* | 61 | /* |
120 | * A css driver handles all subchannels of one type. | 62 | * A css driver handles all subchannels of one type. |
121 | * Currently, we only care about I/O subchannels (type 0), these | 63 | * Currently, we only care about I/O subchannels (type 0), these |
@@ -123,25 +65,35 @@ struct ccw_device_private { | |||
123 | */ | 65 | */ |
124 | struct subchannel; | 66 | struct subchannel; |
125 | struct css_driver { | 67 | struct css_driver { |
68 | struct module *owner; | ||
126 | unsigned int subchannel_type; | 69 | unsigned int subchannel_type; |
127 | struct device_driver drv; | 70 | struct device_driver drv; |
128 | void (*irq)(struct device *); | 71 | void (*irq)(struct subchannel *); |
129 | int (*notify)(struct device *, int); | 72 | int (*notify)(struct subchannel *, int); |
130 | void (*verify)(struct device *); | 73 | void (*verify)(struct subchannel *); |
131 | void (*termination)(struct device *); | 74 | void (*termination)(struct subchannel *); |
132 | int (*probe)(struct subchannel *); | 75 | int (*probe)(struct subchannel *); |
133 | int (*remove)(struct subchannel *); | 76 | int (*remove)(struct subchannel *); |
134 | void (*shutdown)(struct subchannel *); | 77 | void (*shutdown)(struct subchannel *); |
78 | const char *name; | ||
135 | }; | 79 | }; |
136 | 80 | ||
81 | #define to_cssdriver(n) container_of(n, struct css_driver, drv) | ||
82 | |||
137 | /* | 83 | /* |
138 | * all css_drivers have the css_bus_type | 84 | * all css_drivers have the css_bus_type |
139 | */ | 85 | */ |
140 | extern struct bus_type css_bus_type; | 86 | extern struct bus_type css_bus_type; |
141 | 87 | ||
88 | extern int css_driver_register(struct css_driver *); | ||
89 | extern void css_driver_unregister(struct css_driver *); | ||
90 | |||
142 | extern void css_sch_device_unregister(struct subchannel *); | 91 | extern void css_sch_device_unregister(struct subchannel *); |
143 | extern struct subchannel * get_subchannel_by_schid(struct subchannel_id); | 92 | extern struct subchannel * get_subchannel_by_schid(struct subchannel_id); |
144 | extern int css_init_done; | 93 | extern int css_init_done; |
94 | int for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *), | ||
95 | int (*fn_unknown)(struct subchannel_id, | ||
96 | void *), void *data); | ||
145 | extern int for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *); | 97 | extern int for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *); |
146 | extern void css_process_crw(int, int); | 98 | extern void css_process_crw(int, int); |
147 | extern void css_reiterate_subchannels(void); | 99 | extern void css_reiterate_subchannels(void); |
@@ -188,6 +140,8 @@ void css_schedule_eval(struct subchannel_id schid); | |||
188 | void css_schedule_eval_all(void); | 140 | void css_schedule_eval_all(void); |
189 | 141 | ||
190 | int sch_is_pseudo_sch(struct subchannel *); | 142 | int sch_is_pseudo_sch(struct subchannel *); |
143 | struct schib; | ||
144 | int css_sch_is_valid(struct schib *); | ||
191 | 145 | ||
192 | extern struct workqueue_struct *slow_path_wq; | 146 | extern struct workqueue_struct *slow_path_wq; |
193 | 147 | ||
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 74f6b539974a..d35dc3f25d06 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/list.h> | 17 | #include <linux/list.h> |
18 | #include <linux/device.h> | 18 | #include <linux/device.h> |
19 | #include <linux/workqueue.h> | 19 | #include <linux/workqueue.h> |
20 | #include <linux/timer.h> | ||
20 | 21 | ||
21 | #include <asm/ccwdev.h> | 22 | #include <asm/ccwdev.h> |
22 | #include <asm/cio.h> | 23 | #include <asm/cio.h> |
@@ -28,6 +29,12 @@ | |||
28 | #include "css.h" | 29 | #include "css.h" |
29 | #include "device.h" | 30 | #include "device.h" |
30 | #include "ioasm.h" | 31 | #include "ioasm.h" |
32 | #include "io_sch.h" | ||
33 | |||
34 | static struct timer_list recovery_timer; | ||
35 | static spinlock_t recovery_lock; | ||
36 | static int recovery_phase; | ||
37 | static const unsigned long recovery_delay[] = { 3, 30, 300 }; | ||
31 | 38 | ||
32 | /******************* bus type handling ***********************/ | 39 | /******************* bus type handling ***********************/ |
33 | 40 | ||
@@ -115,19 +122,18 @@ static int ccw_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
115 | 122 | ||
116 | struct bus_type ccw_bus_type; | 123 | struct bus_type ccw_bus_type; |
117 | 124 | ||
118 | static int io_subchannel_probe (struct subchannel *); | 125 | static void io_subchannel_irq(struct subchannel *); |
119 | static int io_subchannel_remove (struct subchannel *); | 126 | static int io_subchannel_probe(struct subchannel *); |
120 | static int io_subchannel_notify(struct device *, int); | 127 | static int io_subchannel_remove(struct subchannel *); |
121 | static void io_subchannel_verify(struct device *); | 128 | static int io_subchannel_notify(struct subchannel *, int); |
122 | static void io_subchannel_ioterm(struct device *); | 129 | static void io_subchannel_verify(struct subchannel *); |
130 | static void io_subchannel_ioterm(struct subchannel *); | ||
123 | static void io_subchannel_shutdown(struct subchannel *); | 131 | static void io_subchannel_shutdown(struct subchannel *); |
124 | 132 | ||
125 | static struct css_driver io_subchannel_driver = { | 133 | static struct css_driver io_subchannel_driver = { |
134 | .owner = THIS_MODULE, | ||
126 | .subchannel_type = SUBCHANNEL_TYPE_IO, | 135 | .subchannel_type = SUBCHANNEL_TYPE_IO, |
127 | .drv = { | 136 | .name = "io_subchannel", |
128 | .name = "io_subchannel", | ||
129 | .bus = &css_bus_type, | ||
130 | }, | ||
131 | .irq = io_subchannel_irq, | 137 | .irq = io_subchannel_irq, |
132 | .notify = io_subchannel_notify, | 138 | .notify = io_subchannel_notify, |
133 | .verify = io_subchannel_verify, | 139 | .verify = io_subchannel_verify, |
@@ -142,6 +148,8 @@ struct workqueue_struct *ccw_device_notify_work; | |||
142 | wait_queue_head_t ccw_device_init_wq; | 148 | wait_queue_head_t ccw_device_init_wq; |
143 | atomic_t ccw_device_init_count; | 149 | atomic_t ccw_device_init_count; |
144 | 150 | ||
151 | static void recovery_func(unsigned long data); | ||
152 | |||
145 | static int __init | 153 | static int __init |
146 | init_ccw_bus_type (void) | 154 | init_ccw_bus_type (void) |
147 | { | 155 | { |
@@ -149,6 +157,7 @@ init_ccw_bus_type (void) | |||
149 | 157 | ||
150 | init_waitqueue_head(&ccw_device_init_wq); | 158 | init_waitqueue_head(&ccw_device_init_wq); |
151 | atomic_set(&ccw_device_init_count, 0); | 159 | atomic_set(&ccw_device_init_count, 0); |
160 | setup_timer(&recovery_timer, recovery_func, 0); | ||
152 | 161 | ||
153 | ccw_device_work = create_singlethread_workqueue("cio"); | 162 | ccw_device_work = create_singlethread_workqueue("cio"); |
154 | if (!ccw_device_work) | 163 | if (!ccw_device_work) |
@@ -166,7 +175,8 @@ init_ccw_bus_type (void) | |||
166 | if ((ret = bus_register (&ccw_bus_type))) | 175 | if ((ret = bus_register (&ccw_bus_type))) |
167 | goto out_err; | 176 | goto out_err; |
168 | 177 | ||
169 | if ((ret = driver_register(&io_subchannel_driver.drv))) | 178 | ret = css_driver_register(&io_subchannel_driver); |
179 | if (ret) | ||
170 | goto out_err; | 180 | goto out_err; |
171 | 181 | ||
172 | wait_event(ccw_device_init_wq, | 182 | wait_event(ccw_device_init_wq, |
@@ -186,7 +196,7 @@ out_err: | |||
186 | static void __exit | 196 | static void __exit |
187 | cleanup_ccw_bus_type (void) | 197 | cleanup_ccw_bus_type (void) |
188 | { | 198 | { |
189 | driver_unregister(&io_subchannel_driver.drv); | 199 | css_driver_unregister(&io_subchannel_driver); |
190 | bus_unregister(&ccw_bus_type); | 200 | bus_unregister(&ccw_bus_type); |
191 | destroy_workqueue(ccw_device_notify_work); | 201 | destroy_workqueue(ccw_device_notify_work); |
192 | destroy_workqueue(ccw_device_work); | 202 | destroy_workqueue(ccw_device_work); |
@@ -773,7 +783,7 @@ static void sch_attach_device(struct subchannel *sch, | |||
773 | { | 783 | { |
774 | css_update_ssd_info(sch); | 784 | css_update_ssd_info(sch); |
775 | spin_lock_irq(sch->lock); | 785 | spin_lock_irq(sch->lock); |
776 | sch->dev.driver_data = cdev; | 786 | sch_set_cdev(sch, cdev); |
777 | cdev->private->schid = sch->schid; | 787 | cdev->private->schid = sch->schid; |
778 | cdev->ccwlock = sch->lock; | 788 | cdev->ccwlock = sch->lock; |
779 | device_trigger_reprobe(sch); | 789 | device_trigger_reprobe(sch); |
@@ -795,7 +805,7 @@ static void sch_attach_disconnected_device(struct subchannel *sch, | |||
795 | put_device(&other_sch->dev); | 805 | put_device(&other_sch->dev); |
796 | return; | 806 | return; |
797 | } | 807 | } |
798 | other_sch->dev.driver_data = NULL; | 808 | sch_set_cdev(other_sch, NULL); |
799 | /* No need to keep a subchannel without ccw device around. */ | 809 | /* No need to keep a subchannel without ccw device around. */ |
800 | css_sch_device_unregister(other_sch); | 810 | css_sch_device_unregister(other_sch); |
801 | put_device(&other_sch->dev); | 811 | put_device(&other_sch->dev); |
@@ -831,12 +841,12 @@ static void sch_create_and_recog_new_device(struct subchannel *sch) | |||
831 | return; | 841 | return; |
832 | } | 842 | } |
833 | spin_lock_irq(sch->lock); | 843 | spin_lock_irq(sch->lock); |
834 | sch->dev.driver_data = cdev; | 844 | sch_set_cdev(sch, cdev); |
835 | spin_unlock_irq(sch->lock); | 845 | spin_unlock_irq(sch->lock); |
836 | /* Start recognition for the new ccw device. */ | 846 | /* Start recognition for the new ccw device. */ |
837 | if (io_subchannel_recog(cdev, sch)) { | 847 | if (io_subchannel_recog(cdev, sch)) { |
838 | spin_lock_irq(sch->lock); | 848 | spin_lock_irq(sch->lock); |
839 | sch->dev.driver_data = NULL; | 849 | sch_set_cdev(sch, NULL); |
840 | spin_unlock_irq(sch->lock); | 850 | spin_unlock_irq(sch->lock); |
841 | if (cdev->dev.release) | 851 | if (cdev->dev.release) |
842 | cdev->dev.release(&cdev->dev); | 852 | cdev->dev.release(&cdev->dev); |
@@ -940,7 +950,7 @@ io_subchannel_register(struct work_struct *work) | |||
940 | cdev->private->dev_id.devno, ret); | 950 | cdev->private->dev_id.devno, ret); |
941 | put_device(&cdev->dev); | 951 | put_device(&cdev->dev); |
942 | spin_lock_irqsave(sch->lock, flags); | 952 | spin_lock_irqsave(sch->lock, flags); |
943 | sch->dev.driver_data = NULL; | 953 | sch_set_cdev(sch, NULL); |
944 | spin_unlock_irqrestore(sch->lock, flags); | 954 | spin_unlock_irqrestore(sch->lock, flags); |
945 | kfree (cdev->private); | 955 | kfree (cdev->private); |
946 | kfree (cdev); | 956 | kfree (cdev); |
@@ -1022,7 +1032,7 @@ io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch) | |||
1022 | int rc; | 1032 | int rc; |
1023 | struct ccw_device_private *priv; | 1033 | struct ccw_device_private *priv; |
1024 | 1034 | ||
1025 | sch->dev.driver_data = cdev; | 1035 | sch_set_cdev(sch, cdev); |
1026 | sch->driver = &io_subchannel_driver; | 1036 | sch->driver = &io_subchannel_driver; |
1027 | cdev->ccwlock = sch->lock; | 1037 | cdev->ccwlock = sch->lock; |
1028 | 1038 | ||
@@ -1082,7 +1092,7 @@ static void ccw_device_move_to_sch(struct work_struct *work) | |||
1082 | } | 1092 | } |
1083 | if (former_parent) { | 1093 | if (former_parent) { |
1084 | spin_lock_irq(former_parent->lock); | 1094 | spin_lock_irq(former_parent->lock); |
1085 | former_parent->dev.driver_data = NULL; | 1095 | sch_set_cdev(former_parent, NULL); |
1086 | spin_unlock_irq(former_parent->lock); | 1096 | spin_unlock_irq(former_parent->lock); |
1087 | css_sch_device_unregister(former_parent); | 1097 | css_sch_device_unregister(former_parent); |
1088 | /* Reset intparm to zeroes. */ | 1098 | /* Reset intparm to zeroes. */ |
@@ -1096,6 +1106,18 @@ out: | |||
1096 | put_device(&cdev->dev); | 1106 | put_device(&cdev->dev); |
1097 | } | 1107 | } |
1098 | 1108 | ||
1109 | static void io_subchannel_irq(struct subchannel *sch) | ||
1110 | { | ||
1111 | struct ccw_device *cdev; | ||
1112 | |||
1113 | cdev = sch_get_cdev(sch); | ||
1114 | |||
1115 | CIO_TRACE_EVENT(3, "IRQ"); | ||
1116 | CIO_TRACE_EVENT(3, sch->dev.bus_id); | ||
1117 | if (cdev) | ||
1118 | dev_fsm_event(cdev, DEV_EVENT_INTERRUPT); | ||
1119 | } | ||
1120 | |||
1099 | static int | 1121 | static int |
1100 | io_subchannel_probe (struct subchannel *sch) | 1122 | io_subchannel_probe (struct subchannel *sch) |
1101 | { | 1123 | { |
@@ -1104,13 +1126,13 @@ io_subchannel_probe (struct subchannel *sch) | |||
1104 | unsigned long flags; | 1126 | unsigned long flags; |
1105 | struct ccw_dev_id dev_id; | 1127 | struct ccw_dev_id dev_id; |
1106 | 1128 | ||
1107 | if (sch->dev.driver_data) { | 1129 | cdev = sch_get_cdev(sch); |
1130 | if (cdev) { | ||
1108 | /* | 1131 | /* |
1109 | * This subchannel already has an associated ccw_device. | 1132 | * This subchannel already has an associated ccw_device. |
1110 | * Register it and exit. This happens for all early | 1133 | * Register it and exit. This happens for all early |
1111 | * device, e.g. the console. | 1134 | * device, e.g. the console. |
1112 | */ | 1135 | */ |
1113 | cdev = sch->dev.driver_data; | ||
1114 | cdev->dev.groups = ccwdev_attr_groups; | 1136 | cdev->dev.groups = ccwdev_attr_groups; |
1115 | device_initialize(&cdev->dev); | 1137 | device_initialize(&cdev->dev); |
1116 | ccw_device_register(cdev); | 1138 | ccw_device_register(cdev); |
@@ -1132,6 +1154,11 @@ io_subchannel_probe (struct subchannel *sch) | |||
1132 | */ | 1154 | */ |
1133 | dev_id.devno = sch->schib.pmcw.dev; | 1155 | dev_id.devno = sch->schib.pmcw.dev; |
1134 | dev_id.ssid = sch->schid.ssid; | 1156 | dev_id.ssid = sch->schid.ssid; |
1157 | /* Allocate I/O subchannel private data. */ | ||
1158 | sch->private = kzalloc(sizeof(struct io_subchannel_private), | ||
1159 | GFP_KERNEL | GFP_DMA); | ||
1160 | if (!sch->private) | ||
1161 | return -ENOMEM; | ||
1135 | cdev = get_disc_ccwdev_by_dev_id(&dev_id, NULL); | 1162 | cdev = get_disc_ccwdev_by_dev_id(&dev_id, NULL); |
1136 | if (!cdev) | 1163 | if (!cdev) |
1137 | cdev = get_orphaned_ccwdev_by_dev_id(to_css(sch->dev.parent), | 1164 | cdev = get_orphaned_ccwdev_by_dev_id(to_css(sch->dev.parent), |
@@ -1149,16 +1176,18 @@ io_subchannel_probe (struct subchannel *sch) | |||
1149 | return 0; | 1176 | return 0; |
1150 | } | 1177 | } |
1151 | cdev = io_subchannel_create_ccwdev(sch); | 1178 | cdev = io_subchannel_create_ccwdev(sch); |
1152 | if (IS_ERR(cdev)) | 1179 | if (IS_ERR(cdev)) { |
1180 | kfree(sch->private); | ||
1153 | return PTR_ERR(cdev); | 1181 | return PTR_ERR(cdev); |
1154 | 1182 | } | |
1155 | rc = io_subchannel_recog(cdev, sch); | 1183 | rc = io_subchannel_recog(cdev, sch); |
1156 | if (rc) { | 1184 | if (rc) { |
1157 | spin_lock_irqsave(sch->lock, flags); | 1185 | spin_lock_irqsave(sch->lock, flags); |
1158 | sch->dev.driver_data = NULL; | 1186 | sch_set_cdev(sch, NULL); |
1159 | spin_unlock_irqrestore(sch->lock, flags); | 1187 | spin_unlock_irqrestore(sch->lock, flags); |
1160 | if (cdev->dev.release) | 1188 | if (cdev->dev.release) |
1161 | cdev->dev.release(&cdev->dev); | 1189 | cdev->dev.release(&cdev->dev); |
1190 | kfree(sch->private); | ||
1162 | } | 1191 | } |
1163 | 1192 | ||
1164 | return rc; | 1193 | return rc; |
@@ -1170,25 +1199,25 @@ io_subchannel_remove (struct subchannel *sch) | |||
1170 | struct ccw_device *cdev; | 1199 | struct ccw_device *cdev; |
1171 | unsigned long flags; | 1200 | unsigned long flags; |
1172 | 1201 | ||
1173 | if (!sch->dev.driver_data) | 1202 | cdev = sch_get_cdev(sch); |
1203 | if (!cdev) | ||
1174 | return 0; | 1204 | return 0; |
1175 | cdev = sch->dev.driver_data; | ||
1176 | /* Set ccw device to not operational and drop reference. */ | 1205 | /* Set ccw device to not operational and drop reference. */ |
1177 | spin_lock_irqsave(cdev->ccwlock, flags); | 1206 | spin_lock_irqsave(cdev->ccwlock, flags); |
1178 | sch->dev.driver_data = NULL; | 1207 | sch_set_cdev(sch, NULL); |
1179 | cdev->private->state = DEV_STATE_NOT_OPER; | 1208 | cdev->private->state = DEV_STATE_NOT_OPER; |
1180 | spin_unlock_irqrestore(cdev->ccwlock, flags); | 1209 | spin_unlock_irqrestore(cdev->ccwlock, flags); |
1181 | ccw_device_unregister(cdev); | 1210 | ccw_device_unregister(cdev); |
1182 | put_device(&cdev->dev); | 1211 | put_device(&cdev->dev); |
1212 | kfree(sch->private); | ||
1183 | return 0; | 1213 | return 0; |
1184 | } | 1214 | } |
1185 | 1215 | ||
1186 | static int | 1216 | static int io_subchannel_notify(struct subchannel *sch, int event) |
1187 | io_subchannel_notify(struct device *dev, int event) | ||
1188 | { | 1217 | { |
1189 | struct ccw_device *cdev; | 1218 | struct ccw_device *cdev; |
1190 | 1219 | ||
1191 | cdev = dev->driver_data; | 1220 | cdev = sch_get_cdev(sch); |
1192 | if (!cdev) | 1221 | if (!cdev) |
1193 | return 0; | 1222 | return 0; |
1194 | if (!cdev->drv) | 1223 | if (!cdev->drv) |
@@ -1198,22 +1227,20 @@ io_subchannel_notify(struct device *dev, int event) | |||
1198 | return cdev->drv->notify ? cdev->drv->notify(cdev, event) : 0; | 1227 | return cdev->drv->notify ? cdev->drv->notify(cdev, event) : 0; |
1199 | } | 1228 | } |
1200 | 1229 | ||
1201 | static void | 1230 | static void io_subchannel_verify(struct subchannel *sch) |
1202 | io_subchannel_verify(struct device *dev) | ||
1203 | { | 1231 | { |
1204 | struct ccw_device *cdev; | 1232 | struct ccw_device *cdev; |
1205 | 1233 | ||
1206 | cdev = dev->driver_data; | 1234 | cdev = sch_get_cdev(sch); |
1207 | if (cdev) | 1235 | if (cdev) |
1208 | dev_fsm_event(cdev, DEV_EVENT_VERIFY); | 1236 | dev_fsm_event(cdev, DEV_EVENT_VERIFY); |
1209 | } | 1237 | } |
1210 | 1238 | ||
1211 | static void | 1239 | static void io_subchannel_ioterm(struct subchannel *sch) |
1212 | io_subchannel_ioterm(struct device *dev) | ||
1213 | { | 1240 | { |
1214 | struct ccw_device *cdev; | 1241 | struct ccw_device *cdev; |
1215 | 1242 | ||
1216 | cdev = dev->driver_data; | 1243 | cdev = sch_get_cdev(sch); |
1217 | if (!cdev) | 1244 | if (!cdev) |
1218 | return; | 1245 | return; |
1219 | /* Internal I/O will be retried by the interrupt handler. */ | 1246 | /* Internal I/O will be retried by the interrupt handler. */ |
@@ -1231,7 +1258,7 @@ io_subchannel_shutdown(struct subchannel *sch) | |||
1231 | struct ccw_device *cdev; | 1258 | struct ccw_device *cdev; |
1232 | int ret; | 1259 | int ret; |
1233 | 1260 | ||
1234 | cdev = sch->dev.driver_data; | 1261 | cdev = sch_get_cdev(sch); |
1235 | 1262 | ||
1236 | if (cio_is_console(sch->schid)) | 1263 | if (cio_is_console(sch->schid)) |
1237 | return; | 1264 | return; |
@@ -1271,6 +1298,9 @@ ccw_device_console_enable (struct ccw_device *cdev, struct subchannel *sch) | |||
1271 | { | 1298 | { |
1272 | int rc; | 1299 | int rc; |
1273 | 1300 | ||
1301 | /* Attach subchannel private data. */ | ||
1302 | sch->private = cio_get_console_priv(); | ||
1303 | memset(sch->private, 0, sizeof(struct io_subchannel_private)); | ||
1274 | /* Initialize the ccw_device structure. */ | 1304 | /* Initialize the ccw_device structure. */ |
1275 | cdev->dev.parent= &sch->dev; | 1305 | cdev->dev.parent= &sch->dev; |
1276 | rc = io_subchannel_recog(cdev, sch); | 1306 | rc = io_subchannel_recog(cdev, sch); |
@@ -1456,6 +1486,7 @@ int ccw_driver_register(struct ccw_driver *cdriver) | |||
1456 | 1486 | ||
1457 | drv->bus = &ccw_bus_type; | 1487 | drv->bus = &ccw_bus_type; |
1458 | drv->name = cdriver->name; | 1488 | drv->name = cdriver->name; |
1489 | drv->owner = cdriver->owner; | ||
1459 | 1490 | ||
1460 | return driver_register(drv); | 1491 | return driver_register(drv); |
1461 | } | 1492 | } |
@@ -1481,6 +1512,60 @@ ccw_device_get_subchannel_id(struct ccw_device *cdev) | |||
1481 | return sch->schid; | 1512 | return sch->schid; |
1482 | } | 1513 | } |
1483 | 1514 | ||
1515 | static int recovery_check(struct device *dev, void *data) | ||
1516 | { | ||
1517 | struct ccw_device *cdev = to_ccwdev(dev); | ||
1518 | int *redo = data; | ||
1519 | |||
1520 | spin_lock_irq(cdev->ccwlock); | ||
1521 | switch (cdev->private->state) { | ||
1522 | case DEV_STATE_DISCONNECTED: | ||
1523 | CIO_MSG_EVENT(3, "recovery: trigger 0.%x.%04x\n", | ||
1524 | cdev->private->dev_id.ssid, | ||
1525 | cdev->private->dev_id.devno); | ||
1526 | dev_fsm_event(cdev, DEV_EVENT_VERIFY); | ||
1527 | *redo = 1; | ||
1528 | break; | ||
1529 | case DEV_STATE_DISCONNECTED_SENSE_ID: | ||
1530 | *redo = 1; | ||
1531 | break; | ||
1532 | } | ||
1533 | spin_unlock_irq(cdev->ccwlock); | ||
1534 | |||
1535 | return 0; | ||
1536 | } | ||
1537 | |||
1538 | static void recovery_func(unsigned long data) | ||
1539 | { | ||
1540 | int redo = 0; | ||
1541 | |||
1542 | bus_for_each_dev(&ccw_bus_type, NULL, &redo, recovery_check); | ||
1543 | if (redo) { | ||
1544 | spin_lock_irq(&recovery_lock); | ||
1545 | if (!timer_pending(&recovery_timer)) { | ||
1546 | if (recovery_phase < ARRAY_SIZE(recovery_delay) - 1) | ||
1547 | recovery_phase++; | ||
1548 | mod_timer(&recovery_timer, jiffies + | ||
1549 | recovery_delay[recovery_phase] * HZ); | ||
1550 | } | ||
1551 | spin_unlock_irq(&recovery_lock); | ||
1552 | } else | ||
1553 | CIO_MSG_EVENT(2, "recovery: end\n"); | ||
1554 | } | ||
1555 | |||
1556 | void ccw_device_schedule_recovery(void) | ||
1557 | { | ||
1558 | unsigned long flags; | ||
1559 | |||
1560 | CIO_MSG_EVENT(2, "recovery: schedule\n"); | ||
1561 | spin_lock_irqsave(&recovery_lock, flags); | ||
1562 | if (!timer_pending(&recovery_timer) || (recovery_phase != 0)) { | ||
1563 | recovery_phase = 0; | ||
1564 | mod_timer(&recovery_timer, jiffies + recovery_delay[0] * HZ); | ||
1565 | } | ||
1566 | spin_unlock_irqrestore(&recovery_lock, flags); | ||
1567 | } | ||
1568 | |||
1484 | MODULE_LICENSE("GPL"); | 1569 | MODULE_LICENSE("GPL"); |
1485 | EXPORT_SYMBOL(ccw_device_set_online); | 1570 | EXPORT_SYMBOL(ccw_device_set_online); |
1486 | EXPORT_SYMBOL(ccw_device_set_offline); | 1571 | EXPORT_SYMBOL(ccw_device_set_offline); |
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h index 0d4089600439..d40a2ffaa000 100644 --- a/drivers/s390/cio/device.h +++ b/drivers/s390/cio/device.h | |||
@@ -5,6 +5,8 @@ | |||
5 | #include <asm/atomic.h> | 5 | #include <asm/atomic.h> |
6 | #include <linux/wait.h> | 6 | #include <linux/wait.h> |
7 | 7 | ||
8 | #include "io_sch.h" | ||
9 | |||
8 | /* | 10 | /* |
9 | * states of the device statemachine | 11 | * states of the device statemachine |
10 | */ | 12 | */ |
@@ -74,7 +76,6 @@ extern struct workqueue_struct *ccw_device_notify_work; | |||
74 | extern wait_queue_head_t ccw_device_init_wq; | 76 | extern wait_queue_head_t ccw_device_init_wq; |
75 | extern atomic_t ccw_device_init_count; | 77 | extern atomic_t ccw_device_init_count; |
76 | 78 | ||
77 | void io_subchannel_irq (struct device *pdev); | ||
78 | void io_subchannel_recog_done(struct ccw_device *cdev); | 79 | void io_subchannel_recog_done(struct ccw_device *cdev); |
79 | 80 | ||
80 | int ccw_device_cancel_halt_clear(struct ccw_device *); | 81 | int ccw_device_cancel_halt_clear(struct ccw_device *); |
@@ -87,6 +88,8 @@ int ccw_device_recognition(struct ccw_device *); | |||
87 | int ccw_device_online(struct ccw_device *); | 88 | int ccw_device_online(struct ccw_device *); |
88 | int ccw_device_offline(struct ccw_device *); | 89 | int ccw_device_offline(struct ccw_device *); |
89 | 90 | ||
91 | void ccw_device_schedule_recovery(void); | ||
92 | |||
90 | /* Function prototypes for device status and basic sense stuff. */ | 93 | /* Function prototypes for device status and basic sense stuff. */ |
91 | void ccw_device_accumulate_irb(struct ccw_device *, struct irb *); | 94 | void ccw_device_accumulate_irb(struct ccw_device *, struct irb *); |
92 | void ccw_device_accumulate_basic_sense(struct ccw_device *, struct irb *); | 95 | void ccw_device_accumulate_basic_sense(struct ccw_device *, struct irb *); |
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index bfad421cda66..4b92c84fb438 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c | |||
@@ -25,14 +25,16 @@ | |||
25 | #include "ioasm.h" | 25 | #include "ioasm.h" |
26 | #include "chp.h" | 26 | #include "chp.h" |
27 | 27 | ||
28 | static int timeout_log_enabled; | ||
29 | |||
28 | int | 30 | int |
29 | device_is_online(struct subchannel *sch) | 31 | device_is_online(struct subchannel *sch) |
30 | { | 32 | { |
31 | struct ccw_device *cdev; | 33 | struct ccw_device *cdev; |
32 | 34 | ||
33 | if (!sch->dev.driver_data) | 35 | cdev = sch_get_cdev(sch); |
36 | if (!cdev) | ||
34 | return 0; | 37 | return 0; |
35 | cdev = sch->dev.driver_data; | ||
36 | return (cdev->private->state == DEV_STATE_ONLINE); | 38 | return (cdev->private->state == DEV_STATE_ONLINE); |
37 | } | 39 | } |
38 | 40 | ||
@@ -41,9 +43,9 @@ device_is_disconnected(struct subchannel *sch) | |||
41 | { | 43 | { |
42 | struct ccw_device *cdev; | 44 | struct ccw_device *cdev; |
43 | 45 | ||
44 | if (!sch->dev.driver_data) | 46 | cdev = sch_get_cdev(sch); |
47 | if (!cdev) | ||
45 | return 0; | 48 | return 0; |
46 | cdev = sch->dev.driver_data; | ||
47 | return (cdev->private->state == DEV_STATE_DISCONNECTED || | 49 | return (cdev->private->state == DEV_STATE_DISCONNECTED || |
48 | cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID); | 50 | cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID); |
49 | } | 51 | } |
@@ -53,19 +55,21 @@ device_set_disconnected(struct subchannel *sch) | |||
53 | { | 55 | { |
54 | struct ccw_device *cdev; | 56 | struct ccw_device *cdev; |
55 | 57 | ||
56 | if (!sch->dev.driver_data) | 58 | cdev = sch_get_cdev(sch); |
59 | if (!cdev) | ||
57 | return; | 60 | return; |
58 | cdev = sch->dev.driver_data; | ||
59 | ccw_device_set_timeout(cdev, 0); | 61 | ccw_device_set_timeout(cdev, 0); |
60 | cdev->private->flags.fake_irb = 0; | 62 | cdev->private->flags.fake_irb = 0; |
61 | cdev->private->state = DEV_STATE_DISCONNECTED; | 63 | cdev->private->state = DEV_STATE_DISCONNECTED; |
64 | if (cdev->online) | ||
65 | ccw_device_schedule_recovery(); | ||
62 | } | 66 | } |
63 | 67 | ||
64 | void device_set_intretry(struct subchannel *sch) | 68 | void device_set_intretry(struct subchannel *sch) |
65 | { | 69 | { |
66 | struct ccw_device *cdev; | 70 | struct ccw_device *cdev; |
67 | 71 | ||
68 | cdev = sch->dev.driver_data; | 72 | cdev = sch_get_cdev(sch); |
69 | if (!cdev) | 73 | if (!cdev) |
70 | return; | 74 | return; |
71 | cdev->private->flags.intretry = 1; | 75 | cdev->private->flags.intretry = 1; |
@@ -75,13 +79,62 @@ int device_trigger_verify(struct subchannel *sch) | |||
75 | { | 79 | { |
76 | struct ccw_device *cdev; | 80 | struct ccw_device *cdev; |
77 | 81 | ||
78 | cdev = sch->dev.driver_data; | 82 | cdev = sch_get_cdev(sch); |
79 | if (!cdev || !cdev->online) | 83 | if (!cdev || !cdev->online) |
80 | return -EINVAL; | 84 | return -EINVAL; |
81 | dev_fsm_event(cdev, DEV_EVENT_VERIFY); | 85 | dev_fsm_event(cdev, DEV_EVENT_VERIFY); |
82 | return 0; | 86 | return 0; |
83 | } | 87 | } |
84 | 88 | ||
89 | static int __init ccw_timeout_log_setup(char *unused) | ||
90 | { | ||
91 | timeout_log_enabled = 1; | ||
92 | return 1; | ||
93 | } | ||
94 | |||
95 | __setup("ccw_timeout_log", ccw_timeout_log_setup); | ||
96 | |||
97 | static void ccw_timeout_log(struct ccw_device *cdev) | ||
98 | { | ||
99 | struct schib schib; | ||
100 | struct subchannel *sch; | ||
101 | struct io_subchannel_private *private; | ||
102 | int cc; | ||
103 | |||
104 | sch = to_subchannel(cdev->dev.parent); | ||
105 | private = to_io_private(sch); | ||
106 | cc = stsch(sch->schid, &schib); | ||
107 | |||
108 | printk(KERN_WARNING "cio: ccw device timeout occurred at %llx, " | ||
109 | "device information:\n", get_clock()); | ||
110 | printk(KERN_WARNING "cio: orb:\n"); | ||
111 | print_hex_dump(KERN_WARNING, "cio: ", DUMP_PREFIX_NONE, 16, 1, | ||
112 | &private->orb, sizeof(private->orb), 0); | ||
113 | printk(KERN_WARNING "cio: ccw device bus id: %s\n", cdev->dev.bus_id); | ||
114 | printk(KERN_WARNING "cio: subchannel bus id: %s\n", sch->dev.bus_id); | ||
115 | printk(KERN_WARNING "cio: subchannel lpm: %02x, opm: %02x, " | ||
116 | "vpm: %02x\n", sch->lpm, sch->opm, sch->vpm); | ||
117 | |||
118 | if ((void *)(addr_t)private->orb.cpa == &private->sense_ccw || | ||
119 | (void *)(addr_t)private->orb.cpa == cdev->private->iccws) | ||
120 | printk(KERN_WARNING "cio: last channel program (intern):\n"); | ||
121 | else | ||
122 | printk(KERN_WARNING "cio: last channel program:\n"); | ||
123 | |||
124 | print_hex_dump(KERN_WARNING, "cio: ", DUMP_PREFIX_NONE, 16, 1, | ||
125 | (void *)(addr_t)private->orb.cpa, | ||
126 | sizeof(struct ccw1), 0); | ||
127 | printk(KERN_WARNING "cio: ccw device state: %d\n", | ||
128 | cdev->private->state); | ||
129 | printk(KERN_WARNING "cio: store subchannel returned: cc=%d\n", cc); | ||
130 | printk(KERN_WARNING "cio: schib:\n"); | ||
131 | print_hex_dump(KERN_WARNING, "cio: ", DUMP_PREFIX_NONE, 16, 1, | ||
132 | &schib, sizeof(schib), 0); | ||
133 | printk(KERN_WARNING "cio: ccw device flags:\n"); | ||
134 | print_hex_dump(KERN_WARNING, "cio: ", DUMP_PREFIX_NONE, 16, 1, | ||
135 | &cdev->private->flags, sizeof(cdev->private->flags), 0); | ||
136 | } | ||
137 | |||
85 | /* | 138 | /* |
86 | * Timeout function. It just triggers a DEV_EVENT_TIMEOUT. | 139 | * Timeout function. It just triggers a DEV_EVENT_TIMEOUT. |
87 | */ | 140 | */ |
@@ -92,6 +145,8 @@ ccw_device_timeout(unsigned long data) | |||
92 | 145 | ||
93 | cdev = (struct ccw_device *) data; | 146 | cdev = (struct ccw_device *) data; |
94 | spin_lock_irq(cdev->ccwlock); | 147 | spin_lock_irq(cdev->ccwlock); |
148 | if (timeout_log_enabled) | ||
149 | ccw_timeout_log(cdev); | ||
95 | dev_fsm_event(cdev, DEV_EVENT_TIMEOUT); | 150 | dev_fsm_event(cdev, DEV_EVENT_TIMEOUT); |
96 | spin_unlock_irq(cdev->ccwlock); | 151 | spin_unlock_irq(cdev->ccwlock); |
97 | } | 152 | } |
@@ -122,9 +177,9 @@ device_kill_pending_timer(struct subchannel *sch) | |||
122 | { | 177 | { |
123 | struct ccw_device *cdev; | 178 | struct ccw_device *cdev; |
124 | 179 | ||
125 | if (!sch->dev.driver_data) | 180 | cdev = sch_get_cdev(sch); |
181 | if (!cdev) | ||
126 | return; | 182 | return; |
127 | cdev = sch->dev.driver_data; | ||
128 | ccw_device_set_timeout(cdev, 0); | 183 | ccw_device_set_timeout(cdev, 0); |
129 | } | 184 | } |
130 | 185 | ||
@@ -268,7 +323,7 @@ ccw_device_recog_done(struct ccw_device *cdev, int state) | |||
268 | switch (state) { | 323 | switch (state) { |
269 | case DEV_STATE_NOT_OPER: | 324 | case DEV_STATE_NOT_OPER: |
270 | CIO_DEBUG(KERN_WARNING, 2, | 325 | CIO_DEBUG(KERN_WARNING, 2, |
271 | "cio: SenseID : unknown device %04x on subchannel " | 326 | "SenseID : unknown device %04x on subchannel " |
272 | "0.%x.%04x\n", cdev->private->dev_id.devno, | 327 | "0.%x.%04x\n", cdev->private->dev_id.devno, |
273 | sch->schid.ssid, sch->schid.sch_no); | 328 | sch->schid.ssid, sch->schid.sch_no); |
274 | break; | 329 | break; |
@@ -294,7 +349,7 @@ ccw_device_recog_done(struct ccw_device *cdev, int state) | |||
294 | } | 349 | } |
295 | /* Issue device info message. */ | 350 | /* Issue device info message. */ |
296 | CIO_DEBUG(KERN_INFO, 2, | 351 | CIO_DEBUG(KERN_INFO, 2, |
297 | "cio: SenseID : device 0.%x.%04x reports: " | 352 | "SenseID : device 0.%x.%04x reports: " |
298 | "CU Type/Mod = %04X/%02X, Dev Type/Mod = " | 353 | "CU Type/Mod = %04X/%02X, Dev Type/Mod = " |
299 | "%04X/%02X\n", | 354 | "%04X/%02X\n", |
300 | cdev->private->dev_id.ssid, | 355 | cdev->private->dev_id.ssid, |
@@ -304,7 +359,7 @@ ccw_device_recog_done(struct ccw_device *cdev, int state) | |||
304 | break; | 359 | break; |
305 | case DEV_STATE_BOXED: | 360 | case DEV_STATE_BOXED: |
306 | CIO_DEBUG(KERN_WARNING, 2, | 361 | CIO_DEBUG(KERN_WARNING, 2, |
307 | "cio: SenseID : boxed device %04x on subchannel " | 362 | "SenseID : boxed device %04x on subchannel " |
308 | "0.%x.%04x\n", cdev->private->dev_id.devno, | 363 | "0.%x.%04x\n", cdev->private->dev_id.devno, |
309 | sch->schid.ssid, sch->schid.sch_no); | 364 | sch->schid.ssid, sch->schid.sch_no); |
310 | break; | 365 | break; |
@@ -349,7 +404,7 @@ ccw_device_oper_notify(struct work_struct *work) | |||
349 | sch = to_subchannel(cdev->dev.parent); | 404 | sch = to_subchannel(cdev->dev.parent); |
350 | if (sch->driver && sch->driver->notify) { | 405 | if (sch->driver && sch->driver->notify) { |
351 | spin_unlock_irqrestore(cdev->ccwlock, flags); | 406 | spin_unlock_irqrestore(cdev->ccwlock, flags); |
352 | ret = sch->driver->notify(&sch->dev, CIO_OPER); | 407 | ret = sch->driver->notify(sch, CIO_OPER); |
353 | spin_lock_irqsave(cdev->ccwlock, flags); | 408 | spin_lock_irqsave(cdev->ccwlock, flags); |
354 | } else | 409 | } else |
355 | ret = 0; | 410 | ret = 0; |
@@ -389,7 +444,7 @@ ccw_device_done(struct ccw_device *cdev, int state) | |||
389 | 444 | ||
390 | if (state == DEV_STATE_BOXED) | 445 | if (state == DEV_STATE_BOXED) |
391 | CIO_DEBUG(KERN_WARNING, 2, | 446 | CIO_DEBUG(KERN_WARNING, 2, |
392 | "cio: Boxed device %04x on subchannel %04x\n", | 447 | "Boxed device %04x on subchannel %04x\n", |
393 | cdev->private->dev_id.devno, sch->schid.sch_no); | 448 | cdev->private->dev_id.devno, sch->schid.sch_no); |
394 | 449 | ||
395 | if (cdev->private->flags.donotify) { | 450 | if (cdev->private->flags.donotify) { |
@@ -500,7 +555,8 @@ ccw_device_recognition(struct ccw_device *cdev) | |||
500 | (cdev->private->state != DEV_STATE_BOXED)) | 555 | (cdev->private->state != DEV_STATE_BOXED)) |
501 | return -EINVAL; | 556 | return -EINVAL; |
502 | sch = to_subchannel(cdev->dev.parent); | 557 | sch = to_subchannel(cdev->dev.parent); |
503 | ret = cio_enable_subchannel(sch, sch->schib.pmcw.isc); | 558 | ret = cio_enable_subchannel(sch, sch->schib.pmcw.isc, |
559 | (u32)(addr_t)sch); | ||
504 | if (ret != 0) | 560 | if (ret != 0) |
505 | /* Couldn't enable the subchannel for i/o. Sick device. */ | 561 | /* Couldn't enable the subchannel for i/o. Sick device. */ |
506 | return ret; | 562 | return ret; |
@@ -587,9 +643,10 @@ ccw_device_verify_done(struct ccw_device *cdev, int err) | |||
587 | default: | 643 | default: |
588 | /* Reset oper notify indication after verify error. */ | 644 | /* Reset oper notify indication after verify error. */ |
589 | cdev->private->flags.donotify = 0; | 645 | cdev->private->flags.donotify = 0; |
590 | if (cdev->online) | 646 | if (cdev->online) { |
647 | ccw_device_set_timeout(cdev, 0); | ||
591 | dev_fsm_event(cdev, DEV_EVENT_NOTOPER); | 648 | dev_fsm_event(cdev, DEV_EVENT_NOTOPER); |
592 | else | 649 | } else |
593 | ccw_device_done(cdev, DEV_STATE_NOT_OPER); | 650 | ccw_device_done(cdev, DEV_STATE_NOT_OPER); |
594 | break; | 651 | break; |
595 | } | 652 | } |
@@ -610,7 +667,8 @@ ccw_device_online(struct ccw_device *cdev) | |||
610 | sch = to_subchannel(cdev->dev.parent); | 667 | sch = to_subchannel(cdev->dev.parent); |
611 | if (css_init_done && !get_device(&cdev->dev)) | 668 | if (css_init_done && !get_device(&cdev->dev)) |
612 | return -ENODEV; | 669 | return -ENODEV; |
613 | ret = cio_enable_subchannel(sch, sch->schib.pmcw.isc); | 670 | ret = cio_enable_subchannel(sch, sch->schib.pmcw.isc, |
671 | (u32)(addr_t)sch); | ||
614 | if (ret != 0) { | 672 | if (ret != 0) { |
615 | /* Couldn't enable the subchannel for i/o. Sick device. */ | 673 | /* Couldn't enable the subchannel for i/o. Sick device. */ |
616 | if (ret == -ENODEV) | 674 | if (ret == -ENODEV) |
@@ -937,7 +995,7 @@ void device_kill_io(struct subchannel *sch) | |||
937 | int ret; | 995 | int ret; |
938 | struct ccw_device *cdev; | 996 | struct ccw_device *cdev; |
939 | 997 | ||
940 | cdev = sch->dev.driver_data; | 998 | cdev = sch_get_cdev(sch); |
941 | ret = ccw_device_cancel_halt_clear(cdev); | 999 | ret = ccw_device_cancel_halt_clear(cdev); |
942 | if (ret == -EBUSY) { | 1000 | if (ret == -EBUSY) { |
943 | ccw_device_set_timeout(cdev, 3*HZ); | 1001 | ccw_device_set_timeout(cdev, 3*HZ); |
@@ -990,7 +1048,8 @@ ccw_device_start_id(struct ccw_device *cdev, enum dev_event dev_event) | |||
990 | struct subchannel *sch; | 1048 | struct subchannel *sch; |
991 | 1049 | ||
992 | sch = to_subchannel(cdev->dev.parent); | 1050 | sch = to_subchannel(cdev->dev.parent); |
993 | if (cio_enable_subchannel(sch, sch->schib.pmcw.isc) != 0) | 1051 | if (cio_enable_subchannel(sch, sch->schib.pmcw.isc, |
1052 | (u32)(addr_t)sch) != 0) | ||
994 | /* Couldn't enable the subchannel for i/o. Sick device. */ | 1053 | /* Couldn't enable the subchannel for i/o. Sick device. */ |
995 | return; | 1054 | return; |
996 | 1055 | ||
@@ -1006,9 +1065,9 @@ device_trigger_reprobe(struct subchannel *sch) | |||
1006 | { | 1065 | { |
1007 | struct ccw_device *cdev; | 1066 | struct ccw_device *cdev; |
1008 | 1067 | ||
1009 | if (!sch->dev.driver_data) | 1068 | cdev = sch_get_cdev(sch); |
1069 | if (!cdev) | ||
1010 | return; | 1070 | return; |
1011 | cdev = sch->dev.driver_data; | ||
1012 | if (cdev->private->state != DEV_STATE_DISCONNECTED) | 1071 | if (cdev->private->state != DEV_STATE_DISCONNECTED) |
1013 | return; | 1072 | return; |
1014 | 1073 | ||
@@ -1028,7 +1087,7 @@ device_trigger_reprobe(struct subchannel *sch) | |||
1028 | sch->schib.pmcw.ena = 0; | 1087 | sch->schib.pmcw.ena = 0; |
1029 | if ((sch->lpm & (sch->lpm - 1)) != 0) | 1088 | if ((sch->lpm & (sch->lpm - 1)) != 0) |
1030 | sch->schib.pmcw.mp = 1; | 1089 | sch->schib.pmcw.mp = 1; |
1031 | sch->schib.pmcw.intparm = (__u32)(unsigned long)sch; | 1090 | sch->schib.pmcw.intparm = (u32)(addr_t)sch; |
1032 | /* We should also udate ssd info, but this has to wait. */ | 1091 | /* We should also udate ssd info, but this has to wait. */ |
1033 | /* Check if this is another device which appeared on the same sch. */ | 1092 | /* Check if this is another device which appeared on the same sch. */ |
1034 | if (sch->schib.pmcw.dev != cdev->private->dev_id.devno) { | 1093 | if (sch->schib.pmcw.dev != cdev->private->dev_id.devno) { |
@@ -1223,21 +1282,4 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = { | |||
1223 | }, | 1282 | }, |
1224 | }; | 1283 | }; |
1225 | 1284 | ||
1226 | /* | ||
1227 | * io_subchannel_irq is called for "real" interrupts or for status | ||
1228 | * pending conditions on msch. | ||
1229 | */ | ||
1230 | void | ||
1231 | io_subchannel_irq (struct device *pdev) | ||
1232 | { | ||
1233 | struct ccw_device *cdev; | ||
1234 | |||
1235 | cdev = to_subchannel(pdev)->dev.driver_data; | ||
1236 | |||
1237 | CIO_TRACE_EVENT (3, "IRQ"); | ||
1238 | CIO_TRACE_EVENT (3, pdev->bus_id); | ||
1239 | if (cdev) | ||
1240 | dev_fsm_event(cdev, DEV_EVENT_INTERRUPT); | ||
1241 | } | ||
1242 | |||
1243 | EXPORT_SYMBOL_GPL(ccw_device_set_timeout); | 1285 | EXPORT_SYMBOL_GPL(ccw_device_set_timeout); |
diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c index 156f3f9786b5..918b8b89cf9a 100644 --- a/drivers/s390/cio/device_id.c +++ b/drivers/s390/cio/device_id.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include "css.h" | 24 | #include "css.h" |
25 | #include "device.h" | 25 | #include "device.h" |
26 | #include "ioasm.h" | 26 | #include "ioasm.h" |
27 | #include "io_sch.h" | ||
27 | 28 | ||
28 | /* | 29 | /* |
29 | * Input : | 30 | * Input : |
@@ -219,11 +220,13 @@ ccw_device_check_sense_id(struct ccw_device *cdev) | |||
219 | return -EAGAIN; | 220 | return -EAGAIN; |
220 | } | 221 | } |
221 | if (irb->scsw.cc == 3) { | 222 | if (irb->scsw.cc == 3) { |
222 | if ((sch->orb.lpm & | 223 | u8 lpm; |
223 | sch->schib.pmcw.pim & sch->schib.pmcw.pam) != 0) | 224 | |
225 | lpm = to_io_private(sch)->orb.lpm; | ||
226 | if ((lpm & sch->schib.pmcw.pim & sch->schib.pmcw.pam) != 0) | ||
224 | CIO_MSG_EVENT(2, "SenseID : path %02X for device %04x " | 227 | CIO_MSG_EVENT(2, "SenseID : path %02X for device %04x " |
225 | "on subchannel 0.%x.%04x is " | 228 | "on subchannel 0.%x.%04x is " |
226 | "'not operational'\n", sch->orb.lpm, | 229 | "'not operational'\n", lpm, |
227 | cdev->private->dev_id.devno, | 230 | cdev->private->dev_id.devno, |
228 | sch->schid.ssid, sch->schid.sch_no); | 231 | sch->schid.ssid, sch->schid.sch_no); |
229 | return -EACCES; | 232 | return -EACCES; |
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c index 7fd2dadc3297..49b58eb0fab8 100644 --- a/drivers/s390/cio/device_ops.c +++ b/drivers/s390/cio/device_ops.c | |||
@@ -501,7 +501,7 @@ ccw_device_stlck(struct ccw_device *cdev) | |||
501 | return -ENOMEM; | 501 | return -ENOMEM; |
502 | } | 502 | } |
503 | spin_lock_irqsave(sch->lock, flags); | 503 | spin_lock_irqsave(sch->lock, flags); |
504 | ret = cio_enable_subchannel(sch, 3); | 504 | ret = cio_enable_subchannel(sch, 3, (u32)(addr_t)sch); |
505 | if (ret) | 505 | if (ret) |
506 | goto out_unlock; | 506 | goto out_unlock; |
507 | /* | 507 | /* |
diff --git a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c index cb1879a96818..c52449a1f9fc 100644 --- a/drivers/s390/cio/device_pgid.c +++ b/drivers/s390/cio/device_pgid.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include "css.h" | 22 | #include "css.h" |
23 | #include "device.h" | 23 | #include "device.h" |
24 | #include "ioasm.h" | 24 | #include "ioasm.h" |
25 | #include "io_sch.h" | ||
25 | 26 | ||
26 | /* | 27 | /* |
27 | * Helper function called from interrupt context to decide whether an | 28 | * Helper function called from interrupt context to decide whether an |
@@ -155,10 +156,13 @@ __ccw_device_check_sense_pgid(struct ccw_device *cdev) | |||
155 | return -EAGAIN; | 156 | return -EAGAIN; |
156 | } | 157 | } |
157 | if (irb->scsw.cc == 3) { | 158 | if (irb->scsw.cc == 3) { |
159 | u8 lpm; | ||
160 | |||
161 | lpm = to_io_private(sch)->orb.lpm; | ||
158 | CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel 0.%x.%04x," | 162 | CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel 0.%x.%04x," |
159 | " lpm %02X, became 'not operational'\n", | 163 | " lpm %02X, became 'not operational'\n", |
160 | cdev->private->dev_id.devno, sch->schid.ssid, | 164 | cdev->private->dev_id.devno, sch->schid.ssid, |
161 | sch->schid.sch_no, sch->orb.lpm); | 165 | sch->schid.sch_no, lpm); |
162 | return -EACCES; | 166 | return -EACCES; |
163 | } | 167 | } |
164 | i = 8 - ffs(cdev->private->imask); | 168 | i = 8 - ffs(cdev->private->imask); |
diff --git a/drivers/s390/cio/device_status.c b/drivers/s390/cio/device_status.c index aa96e6752592..ebe0848cfe33 100644 --- a/drivers/s390/cio/device_status.c +++ b/drivers/s390/cio/device_status.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include "css.h" | 20 | #include "css.h" |
21 | #include "device.h" | 21 | #include "device.h" |
22 | #include "ioasm.h" | 22 | #include "ioasm.h" |
23 | #include "io_sch.h" | ||
23 | 24 | ||
24 | /* | 25 | /* |
25 | * Check for any kind of channel or interface control check but don't | 26 | * Check for any kind of channel or interface control check but don't |
@@ -310,6 +311,7 @@ int | |||
310 | ccw_device_do_sense(struct ccw_device *cdev, struct irb *irb) | 311 | ccw_device_do_sense(struct ccw_device *cdev, struct irb *irb) |
311 | { | 312 | { |
312 | struct subchannel *sch; | 313 | struct subchannel *sch; |
314 | struct ccw1 *sense_ccw; | ||
313 | 315 | ||
314 | sch = to_subchannel(cdev->dev.parent); | 316 | sch = to_subchannel(cdev->dev.parent); |
315 | 317 | ||
@@ -326,15 +328,16 @@ ccw_device_do_sense(struct ccw_device *cdev, struct irb *irb) | |||
326 | /* | 328 | /* |
327 | * We have ending status but no sense information. Do a basic sense. | 329 | * We have ending status but no sense information. Do a basic sense. |
328 | */ | 330 | */ |
329 | sch->sense_ccw.cmd_code = CCW_CMD_BASIC_SENSE; | 331 | sense_ccw = &to_io_private(sch)->sense_ccw; |
330 | sch->sense_ccw.cda = (__u32) __pa(cdev->private->irb.ecw); | 332 | sense_ccw->cmd_code = CCW_CMD_BASIC_SENSE; |
331 | sch->sense_ccw.count = SENSE_MAX_COUNT; | 333 | sense_ccw->cda = (__u32) __pa(cdev->private->irb.ecw); |
332 | sch->sense_ccw.flags = CCW_FLAG_SLI; | 334 | sense_ccw->count = SENSE_MAX_COUNT; |
335 | sense_ccw->flags = CCW_FLAG_SLI; | ||
333 | 336 | ||
334 | /* Reset internal retry indication. */ | 337 | /* Reset internal retry indication. */ |
335 | cdev->private->flags.intretry = 0; | 338 | cdev->private->flags.intretry = 0; |
336 | 339 | ||
337 | return cio_start (sch, &sch->sense_ccw, 0xff); | 340 | return cio_start(sch, sense_ccw, 0xff); |
338 | } | 341 | } |
339 | 342 | ||
340 | /* | 343 | /* |
diff --git a/drivers/s390/cio/io_sch.h b/drivers/s390/cio/io_sch.h new file mode 100644 index 000000000000..8c613160bfce --- /dev/null +++ b/drivers/s390/cio/io_sch.h | |||
@@ -0,0 +1,163 @@ | |||
1 | #ifndef S390_IO_SCH_H | ||
2 | #define S390_IO_SCH_H | ||
3 | |||
4 | #include "schid.h" | ||
5 | |||
6 | /* | ||
7 | * operation request block | ||
8 | */ | ||
9 | struct orb { | ||
10 | u32 intparm; /* interruption parameter */ | ||
11 | u32 key : 4; /* flags, like key, suspend control, etc. */ | ||
12 | u32 spnd : 1; /* suspend control */ | ||
13 | u32 res1 : 1; /* reserved */ | ||
14 | u32 mod : 1; /* modification control */ | ||
15 | u32 sync : 1; /* synchronize control */ | ||
16 | u32 fmt : 1; /* format control */ | ||
17 | u32 pfch : 1; /* prefetch control */ | ||
18 | u32 isic : 1; /* initial-status-interruption control */ | ||
19 | u32 alcc : 1; /* address-limit-checking control */ | ||
20 | u32 ssic : 1; /* suppress-suspended-interr. control */ | ||
21 | u32 res2 : 1; /* reserved */ | ||
22 | u32 c64 : 1; /* IDAW/QDIO 64 bit control */ | ||
23 | u32 i2k : 1; /* IDAW 2/4kB block size control */ | ||
24 | u32 lpm : 8; /* logical path mask */ | ||
25 | u32 ils : 1; /* incorrect length */ | ||
26 | u32 zero : 6; /* reserved zeros */ | ||
27 | u32 orbx : 1; /* ORB extension control */ | ||
28 | u32 cpa; /* channel program address */ | ||
29 | } __attribute__ ((packed, aligned(4))); | ||
30 | |||
31 | struct io_subchannel_private { | ||
32 | struct orb orb; /* operation request block */ | ||
33 | struct ccw1 sense_ccw; /* static ccw for sense command */ | ||
34 | } __attribute__ ((aligned(8))); | ||
35 | |||
36 | #define to_io_private(n) ((struct io_subchannel_private *)n->private) | ||
37 | #define sch_get_cdev(n) (dev_get_drvdata(&n->dev)) | ||
38 | #define sch_set_cdev(n, c) (dev_set_drvdata(&n->dev, c)) | ||
39 | |||
40 | #define MAX_CIWS 8 | ||
41 | |||
42 | /* | ||
43 | * sense-id response buffer layout | ||
44 | */ | ||
45 | struct senseid { | ||
46 | /* common part */ | ||
47 | u8 reserved; /* always 0x'FF' */ | ||
48 | u16 cu_type; /* control unit type */ | ||
49 | u8 cu_model; /* control unit model */ | ||
50 | u16 dev_type; /* device type */ | ||
51 | u8 dev_model; /* device model */ | ||
52 | u8 unused; /* padding byte */ | ||
53 | /* extended part */ | ||
54 | struct ciw ciw[MAX_CIWS]; /* variable # of CIWs */ | ||
55 | } __attribute__ ((packed, aligned(4))); | ||
56 | |||
57 | struct ccw_device_private { | ||
58 | struct ccw_device *cdev; | ||
59 | struct subchannel *sch; | ||
60 | int state; /* device state */ | ||
61 | atomic_t onoff; | ||
62 | unsigned long registered; | ||
63 | struct ccw_dev_id dev_id; /* device id */ | ||
64 | struct subchannel_id schid; /* subchannel number */ | ||
65 | u8 imask; /* lpm mask for SNID/SID/SPGID */ | ||
66 | int iretry; /* retry counter SNID/SID/SPGID */ | ||
67 | struct { | ||
68 | unsigned int fast:1; /* post with "channel end" */ | ||
69 | unsigned int repall:1; /* report every interrupt status */ | ||
70 | unsigned int pgroup:1; /* do path grouping */ | ||
71 | unsigned int force:1; /* allow forced online */ | ||
72 | } __attribute__ ((packed)) options; | ||
73 | struct { | ||
74 | unsigned int pgid_single:1; /* use single path for Set PGID */ | ||
75 | unsigned int esid:1; /* Ext. SenseID supported by HW */ | ||
76 | unsigned int dosense:1; /* delayed SENSE required */ | ||
77 | unsigned int doverify:1; /* delayed path verification */ | ||
78 | unsigned int donotify:1; /* call notify function */ | ||
79 | unsigned int recog_done:1; /* dev. recog. complete */ | ||
80 | unsigned int fake_irb:1; /* deliver faked irb */ | ||
81 | unsigned int intretry:1; /* retry internal operation */ | ||
82 | } __attribute__((packed)) flags; | ||
83 | unsigned long intparm; /* user interruption parameter */ | ||
84 | struct qdio_irq *qdio_data; | ||
85 | struct irb irb; /* device status */ | ||
86 | struct senseid senseid; /* SenseID info */ | ||
87 | struct pgid pgid[8]; /* path group IDs per chpid*/ | ||
88 | struct ccw1 iccws[2]; /* ccws for SNID/SID/SPGID commands */ | ||
89 | struct work_struct kick_work; | ||
90 | wait_queue_head_t wait_q; | ||
91 | struct timer_list timer; | ||
92 | void *cmb; /* measurement information */ | ||
93 | struct list_head cmb_list; /* list of measured devices */ | ||
94 | u64 cmb_start_time; /* clock value of cmb reset */ | ||
95 | void *cmb_wait; /* deferred cmb enable/disable */ | ||
96 | }; | ||
97 | |||
98 | static inline int ssch(struct subchannel_id schid, volatile struct orb *addr) | ||
99 | { | ||
100 | register struct subchannel_id reg1 asm("1") = schid; | ||
101 | int ccode; | ||
102 | |||
103 | asm volatile( | ||
104 | " ssch 0(%2)\n" | ||
105 | " ipm %0\n" | ||
106 | " srl %0,28" | ||
107 | : "=d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc"); | ||
108 | return ccode; | ||
109 | } | ||
110 | |||
111 | static inline int rsch(struct subchannel_id schid) | ||
112 | { | ||
113 | register struct subchannel_id reg1 asm("1") = schid; | ||
114 | int ccode; | ||
115 | |||
116 | asm volatile( | ||
117 | " rsch\n" | ||
118 | " ipm %0\n" | ||
119 | " srl %0,28" | ||
120 | : "=d" (ccode) : "d" (reg1) : "cc"); | ||
121 | return ccode; | ||
122 | } | ||
123 | |||
124 | static inline int csch(struct subchannel_id schid) | ||
125 | { | ||
126 | register struct subchannel_id reg1 asm("1") = schid; | ||
127 | int ccode; | ||
128 | |||
129 | asm volatile( | ||
130 | " csch\n" | ||
131 | " ipm %0\n" | ||
132 | " srl %0,28" | ||
133 | : "=d" (ccode) : "d" (reg1) : "cc"); | ||
134 | return ccode; | ||
135 | } | ||
136 | |||
137 | static inline int hsch(struct subchannel_id schid) | ||
138 | { | ||
139 | register struct subchannel_id reg1 asm("1") = schid; | ||
140 | int ccode; | ||
141 | |||
142 | asm volatile( | ||
143 | " hsch\n" | ||
144 | " ipm %0\n" | ||
145 | " srl %0,28" | ||
146 | : "=d" (ccode) : "d" (reg1) : "cc"); | ||
147 | return ccode; | ||
148 | } | ||
149 | |||
150 | static inline int xsch(struct subchannel_id schid) | ||
151 | { | ||
152 | register struct subchannel_id reg1 asm("1") = schid; | ||
153 | int ccode; | ||
154 | |||
155 | asm volatile( | ||
156 | " .insn rre,0xb2760000,%1,0\n" | ||
157 | " ipm %0\n" | ||
158 | " srl %0,28" | ||
159 | : "=d" (ccode) : "d" (reg1) : "cc"); | ||
160 | return ccode; | ||
161 | } | ||
162 | |||
163 | #endif | ||
diff --git a/drivers/s390/cio/ioasm.h b/drivers/s390/cio/ioasm.h index 7153dd959082..652ea3625f9d 100644 --- a/drivers/s390/cio/ioasm.h +++ b/drivers/s390/cio/ioasm.h | |||
@@ -109,72 +109,6 @@ static inline int tpi( volatile struct tpi_info *addr) | |||
109 | return ccode; | 109 | return ccode; |
110 | } | 110 | } |
111 | 111 | ||
112 | static inline int ssch(struct subchannel_id schid, | ||
113 | volatile struct orb *addr) | ||
114 | { | ||
115 | register struct subchannel_id reg1 asm ("1") = schid; | ||
116 | int ccode; | ||
117 | |||
118 | asm volatile( | ||
119 | " ssch 0(%2)\n" | ||
120 | " ipm %0\n" | ||
121 | " srl %0,28" | ||
122 | : "=d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc"); | ||
123 | return ccode; | ||
124 | } | ||
125 | |||
126 | static inline int rsch(struct subchannel_id schid) | ||
127 | { | ||
128 | register struct subchannel_id reg1 asm ("1") = schid; | ||
129 | int ccode; | ||
130 | |||
131 | asm volatile( | ||
132 | " rsch\n" | ||
133 | " ipm %0\n" | ||
134 | " srl %0,28" | ||
135 | : "=d" (ccode) : "d" (reg1) : "cc"); | ||
136 | return ccode; | ||
137 | } | ||
138 | |||
139 | static inline int csch(struct subchannel_id schid) | ||
140 | { | ||
141 | register struct subchannel_id reg1 asm ("1") = schid; | ||
142 | int ccode; | ||
143 | |||
144 | asm volatile( | ||
145 | " csch\n" | ||
146 | " ipm %0\n" | ||
147 | " srl %0,28" | ||
148 | : "=d" (ccode) : "d" (reg1) : "cc"); | ||
149 | return ccode; | ||
150 | } | ||
151 | |||
152 | static inline int hsch(struct subchannel_id schid) | ||
153 | { | ||
154 | register struct subchannel_id reg1 asm ("1") = schid; | ||
155 | int ccode; | ||
156 | |||
157 | asm volatile( | ||
158 | " hsch\n" | ||
159 | " ipm %0\n" | ||
160 | " srl %0,28" | ||
161 | : "=d" (ccode) : "d" (reg1) : "cc"); | ||
162 | return ccode; | ||
163 | } | ||
164 | |||
165 | static inline int xsch(struct subchannel_id schid) | ||
166 | { | ||
167 | register struct subchannel_id reg1 asm ("1") = schid; | ||
168 | int ccode; | ||
169 | |||
170 | asm volatile( | ||
171 | " .insn rre,0xb2760000,%1,0\n" | ||
172 | " ipm %0\n" | ||
173 | " srl %0,28" | ||
174 | : "=d" (ccode) : "d" (reg1) : "cc"); | ||
175 | return ccode; | ||
176 | } | ||
177 | |||
178 | static inline int chsc(void *chsc_area) | 112 | static inline int chsc(void *chsc_area) |
179 | { | 113 | { |
180 | typedef struct { char _[4096]; } addr_type; | 114 | typedef struct { char _[4096]; } addr_type; |
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c index 40a3208c7cf3..e2a781b6b21d 100644 --- a/drivers/s390/cio/qdio.c +++ b/drivers/s390/cio/qdio.c | |||
@@ -48,11 +48,11 @@ | |||
48 | #include <asm/debug.h> | 48 | #include <asm/debug.h> |
49 | #include <asm/s390_rdev.h> | 49 | #include <asm/s390_rdev.h> |
50 | #include <asm/qdio.h> | 50 | #include <asm/qdio.h> |
51 | #include <asm/airq.h> | ||
51 | 52 | ||
52 | #include "cio.h" | 53 | #include "cio.h" |
53 | #include "css.h" | 54 | #include "css.h" |
54 | #include "device.h" | 55 | #include "device.h" |
55 | #include "airq.h" | ||
56 | #include "qdio.h" | 56 | #include "qdio.h" |
57 | #include "ioasm.h" | 57 | #include "ioasm.h" |
58 | #include "chsc.h" | 58 | #include "chsc.h" |
@@ -96,7 +96,7 @@ static debug_info_t *qdio_dbf_slsb_in; | |||
96 | static volatile struct qdio_q *tiq_list=NULL; /* volatile as it could change | 96 | static volatile struct qdio_q *tiq_list=NULL; /* volatile as it could change |
97 | during a while loop */ | 97 | during a while loop */ |
98 | static DEFINE_SPINLOCK(ttiq_list_lock); | 98 | static DEFINE_SPINLOCK(ttiq_list_lock); |
99 | static int register_thinint_result; | 99 | static void *tiqdio_ind; |
100 | static void tiqdio_tl(unsigned long); | 100 | static void tiqdio_tl(unsigned long); |
101 | static DECLARE_TASKLET(tiqdio_tasklet,tiqdio_tl,0); | 101 | static DECLARE_TASKLET(tiqdio_tasklet,tiqdio_tl,0); |
102 | 102 | ||
@@ -399,7 +399,7 @@ qdio_get_indicator(void) | |||
399 | { | 399 | { |
400 | int i; | 400 | int i; |
401 | 401 | ||
402 | for (i=1;i<INDICATORS_PER_CACHELINE;i++) | 402 | for (i = 0; i < INDICATORS_PER_CACHELINE; i++) |
403 | if (!indicator_used[i]) { | 403 | if (!indicator_used[i]) { |
404 | indicator_used[i]=1; | 404 | indicator_used[i]=1; |
405 | return indicators+i; | 405 | return indicators+i; |
@@ -1408,8 +1408,7 @@ __tiqdio_inbound_processing(struct qdio_q *q, int spare_ind_was_set) | |||
1408 | if (q->hydra_gives_outbound_pcis) { | 1408 | if (q->hydra_gives_outbound_pcis) { |
1409 | if (!q->siga_sync_done_on_thinints) { | 1409 | if (!q->siga_sync_done_on_thinints) { |
1410 | SYNC_MEMORY_ALL; | 1410 | SYNC_MEMORY_ALL; |
1411 | } else if ((!q->siga_sync_done_on_outb_tis)&& | 1411 | } else if (!q->siga_sync_done_on_outb_tis) { |
1412 | (q->hydra_gives_outbound_pcis)) { | ||
1413 | SYNC_MEMORY_ALL_OUTB; | 1412 | SYNC_MEMORY_ALL_OUTB; |
1414 | } | 1413 | } |
1415 | } else { | 1414 | } else { |
@@ -1911,8 +1910,7 @@ qdio_fill_thresholds(struct qdio_irq *irq_ptr, | |||
1911 | } | 1910 | } |
1912 | } | 1911 | } |
1913 | 1912 | ||
1914 | static int | 1913 | static void tiqdio_thinint_handler(void *ind, void *drv_data) |
1915 | tiqdio_thinint_handler(void) | ||
1916 | { | 1914 | { |
1917 | QDIO_DBF_TEXT4(0,trace,"thin_int"); | 1915 | QDIO_DBF_TEXT4(0,trace,"thin_int"); |
1918 | 1916 | ||
@@ -1925,7 +1923,6 @@ tiqdio_thinint_handler(void) | |||
1925 | tiqdio_clear_global_summary(); | 1923 | tiqdio_clear_global_summary(); |
1926 | 1924 | ||
1927 | tiqdio_inbound_checks(); | 1925 | tiqdio_inbound_checks(); |
1928 | return 0; | ||
1929 | } | 1926 | } |
1930 | 1927 | ||
1931 | static void | 1928 | static void |
@@ -2445,7 +2442,7 @@ tiqdio_set_subchannel_ind(struct qdio_irq *irq_ptr, int reset_to_zero) | |||
2445 | real_addr_dev_st_chg_ind=0; | 2442 | real_addr_dev_st_chg_ind=0; |
2446 | } else { | 2443 | } else { |
2447 | real_addr_local_summary_bit= | 2444 | real_addr_local_summary_bit= |
2448 | virt_to_phys((volatile void *)indicators); | 2445 | virt_to_phys((volatile void *)tiqdio_ind); |
2449 | real_addr_dev_st_chg_ind= | 2446 | real_addr_dev_st_chg_ind= |
2450 | virt_to_phys((volatile void *)irq_ptr->dev_st_chg_ind); | 2447 | virt_to_phys((volatile void *)irq_ptr->dev_st_chg_ind); |
2451 | } | 2448 | } |
@@ -3740,23 +3737,25 @@ static void | |||
3740 | tiqdio_register_thinints(void) | 3737 | tiqdio_register_thinints(void) |
3741 | { | 3738 | { |
3742 | char dbf_text[20]; | 3739 | char dbf_text[20]; |
3743 | register_thinint_result= | 3740 | |
3744 | s390_register_adapter_interrupt(&tiqdio_thinint_handler); | 3741 | tiqdio_ind = |
3745 | if (register_thinint_result) { | 3742 | s390_register_adapter_interrupt(&tiqdio_thinint_handler, NULL); |
3746 | sprintf(dbf_text,"regthn%x",(register_thinint_result&0xff)); | 3743 | if (IS_ERR(tiqdio_ind)) { |
3744 | sprintf(dbf_text, "regthn%lx", PTR_ERR(tiqdio_ind)); | ||
3747 | QDIO_DBF_TEXT0(0,setup,dbf_text); | 3745 | QDIO_DBF_TEXT0(0,setup,dbf_text); |
3748 | QDIO_PRINT_ERR("failed to register adapter handler " \ | 3746 | QDIO_PRINT_ERR("failed to register adapter handler " \ |
3749 | "(rc=%i).\nAdapter interrupts might " \ | 3747 | "(rc=%li).\nAdapter interrupts might " \ |
3750 | "not work. Continuing.\n", | 3748 | "not work. Continuing.\n", |
3751 | register_thinint_result); | 3749 | PTR_ERR(tiqdio_ind)); |
3750 | tiqdio_ind = NULL; | ||
3752 | } | 3751 | } |
3753 | } | 3752 | } |
3754 | 3753 | ||
3755 | static void | 3754 | static void |
3756 | tiqdio_unregister_thinints(void) | 3755 | tiqdio_unregister_thinints(void) |
3757 | { | 3756 | { |
3758 | if (!register_thinint_result) | 3757 | if (tiqdio_ind) |
3759 | s390_unregister_adapter_interrupt(&tiqdio_thinint_handler); | 3758 | s390_unregister_adapter_interrupt(tiqdio_ind); |
3760 | } | 3759 | } |
3761 | 3760 | ||
3762 | static int | 3761 | static int |
@@ -3768,8 +3767,8 @@ qdio_get_qdio_memory(void) | |||
3768 | for (i=1;i<INDICATORS_PER_CACHELINE;i++) | 3767 | for (i=1;i<INDICATORS_PER_CACHELINE;i++) |
3769 | indicator_used[i]=0; | 3768 | indicator_used[i]=0; |
3770 | indicators = kzalloc(sizeof(__u32)*(INDICATORS_PER_CACHELINE), | 3769 | indicators = kzalloc(sizeof(__u32)*(INDICATORS_PER_CACHELINE), |
3771 | GFP_KERNEL); | 3770 | GFP_KERNEL); |
3772 | if (!indicators) | 3771 | if (!indicators) |
3773 | return -ENOMEM; | 3772 | return -ENOMEM; |
3774 | return 0; | 3773 | return 0; |
3775 | } | 3774 | } |
@@ -3780,7 +3779,6 @@ qdio_release_qdio_memory(void) | |||
3780 | kfree(indicators); | 3779 | kfree(indicators); |
3781 | } | 3780 | } |
3782 | 3781 | ||
3783 | |||
3784 | static void | 3782 | static void |
3785 | qdio_unregister_dbf_views(void) | 3783 | qdio_unregister_dbf_views(void) |
3786 | { | 3784 | { |
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h index 6d7aad18f6f0..37870e4e938e 100644 --- a/drivers/s390/cio/qdio.h +++ b/drivers/s390/cio/qdio.h | |||
@@ -57,7 +57,7 @@ | |||
57 | of the queue to 0 */ | 57 | of the queue to 0 */ |
58 | 58 | ||
59 | #define QDIO_ESTABLISH_TIMEOUT (1*HZ) | 59 | #define QDIO_ESTABLISH_TIMEOUT (1*HZ) |
60 | #define QDIO_ACTIVATE_TIMEOUT ((5*HZ)>>10) | 60 | #define QDIO_ACTIVATE_TIMEOUT (5*HZ) |
61 | #define QDIO_CLEANUP_CLEAR_TIMEOUT (20*HZ) | 61 | #define QDIO_CLEANUP_CLEAR_TIMEOUT (20*HZ) |
62 | #define QDIO_CLEANUP_HALT_TIMEOUT (10*HZ) | 62 | #define QDIO_CLEANUP_HALT_TIMEOUT (10*HZ) |
63 | #define QDIO_FORCE_CHECK_TIMEOUT (10*HZ) | 63 | #define QDIO_FORCE_CHECK_TIMEOUT (10*HZ) |
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c index 3561982749e3..c3076217871e 100644 --- a/drivers/s390/net/claw.c +++ b/drivers/s390/net/claw.c | |||
@@ -2416,7 +2416,7 @@ init_ccw_bk(struct net_device *dev) | |||
2416 | privptr->p_buff_pages_perwrite); | 2416 | privptr->p_buff_pages_perwrite); |
2417 | #endif | 2417 | #endif |
2418 | if (p_buff==NULL) { | 2418 | if (p_buff==NULL) { |
2419 | printk(KERN_INFO "%s:%s __get_free_pages" | 2419 | printk(KERN_INFO "%s:%s __get_free_pages " |
2420 | "for writes buf failed : get is for %d pages\n", | 2420 | "for writes buf failed : get is for %d pages\n", |
2421 | dev->name, | 2421 | dev->name, |
2422 | __FUNCTION__, | 2422 | __FUNCTION__, |
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index 0fd663b23d76..7bfe8d707a34 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c | |||
@@ -1115,7 +1115,7 @@ list_modified: | |||
1115 | rc = lcs_send_setipm(card, ipm); | 1115 | rc = lcs_send_setipm(card, ipm); |
1116 | spin_lock_irqsave(&card->ipm_lock, flags); | 1116 | spin_lock_irqsave(&card->ipm_lock, flags); |
1117 | if (rc) { | 1117 | if (rc) { |
1118 | PRINT_INFO("Adding multicast address failed." | 1118 | PRINT_INFO("Adding multicast address failed. " |
1119 | "Table possibly full!\n"); | 1119 | "Table possibly full!\n"); |
1120 | /* store ipm in failed list -> will be added | 1120 | /* store ipm in failed list -> will be added |
1121 | * to ipm_list again, so a retry will be done | 1121 | * to ipm_list again, so a retry will be done |
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c index d6e93f15440e..f3d893cfe61d 100644 --- a/drivers/s390/net/netiucv.c +++ b/drivers/s390/net/netiucv.c | |||
@@ -198,8 +198,7 @@ struct iucv_connection { | |||
198 | /** | 198 | /** |
199 | * Linked list of all connection structs. | 199 | * Linked list of all connection structs. |
200 | */ | 200 | */ |
201 | static struct list_head iucv_connection_list = | 201 | static LIST_HEAD(iucv_connection_list); |
202 | LIST_HEAD_INIT(iucv_connection_list); | ||
203 | static DEFINE_RWLOCK(iucv_connection_rwlock); | 202 | static DEFINE_RWLOCK(iucv_connection_rwlock); |
204 | 203 | ||
205 | /** | 204 | /** |
diff --git a/drivers/s390/net/qeth_proc.c b/drivers/s390/net/qeth_proc.c index f1ff165a5e05..46ecd03a597e 100644 --- a/drivers/s390/net/qeth_proc.c +++ b/drivers/s390/net/qeth_proc.c | |||
@@ -146,7 +146,7 @@ qeth_procfile_seq_show(struct seq_file *s, void *it) | |||
146 | return 0; | 146 | return 0; |
147 | } | 147 | } |
148 | 148 | ||
149 | static struct seq_operations qeth_procfile_seq_ops = { | 149 | static const struct seq_operations qeth_procfile_seq_ops = { |
150 | .start = qeth_procfile_seq_start, | 150 | .start = qeth_procfile_seq_start, |
151 | .stop = qeth_procfile_seq_stop, | 151 | .stop = qeth_procfile_seq_stop, |
152 | .next = qeth_procfile_seq_next, | 152 | .next = qeth_procfile_seq_next, |
@@ -264,7 +264,7 @@ qeth_perf_procfile_seq_show(struct seq_file *s, void *it) | |||
264 | return 0; | 264 | return 0; |
265 | } | 265 | } |
266 | 266 | ||
267 | static struct seq_operations qeth_perf_procfile_seq_ops = { | 267 | static const struct seq_operations qeth_perf_procfile_seq_ops = { |
268 | .start = qeth_procfile_seq_start, | 268 | .start = qeth_procfile_seq_start, |
269 | .stop = qeth_procfile_seq_stop, | 269 | .stop = qeth_procfile_seq_stop, |
270 | .next = qeth_procfile_seq_next, | 270 | .next = qeth_procfile_seq_next, |
diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c index 47bb47b48581..8735a415a116 100644 --- a/drivers/s390/net/smsgiucv.c +++ b/drivers/s390/net/smsgiucv.c | |||
@@ -42,7 +42,7 @@ MODULE_DESCRIPTION ("Linux for S/390 IUCV special message driver"); | |||
42 | static struct iucv_path *smsg_path; | 42 | static struct iucv_path *smsg_path; |
43 | 43 | ||
44 | static DEFINE_SPINLOCK(smsg_list_lock); | 44 | static DEFINE_SPINLOCK(smsg_list_lock); |
45 | static struct list_head smsg_list = LIST_HEAD_INIT(smsg_list); | 45 | static LIST_HEAD(smsg_list); |
46 | 46 | ||
47 | static int smsg_path_pending(struct iucv_path *, u8 ipvmid[8], u8 ipuser[16]); | 47 | static int smsg_path_pending(struct iucv_path *, u8 ipvmid[8], u8 ipuser[16]); |
48 | static void smsg_message_pending(struct iucv_path *, struct iucv_message *); | 48 | static void smsg_message_pending(struct iucv_path *, struct iucv_message *); |
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 4f86c0e12961..2dc8110ebf74 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c | |||
@@ -1286,7 +1286,7 @@ zfcp_erp_strategy_do_action(struct zfcp_erp_action *erp_action) | |||
1286 | * note: no lock in subsequent strategy routines | 1286 | * note: no lock in subsequent strategy routines |
1287 | * (this allows these routine to call schedule, e.g. | 1287 | * (this allows these routine to call schedule, e.g. |
1288 | * kmalloc with such flags or qdio_initialize & friends) | 1288 | * kmalloc with such flags or qdio_initialize & friends) |
1289 | * Note: in case of timeout, the seperate strategies will fail | 1289 | * Note: in case of timeout, the separate strategies will fail |
1290 | * anyhow. No need for a special action. Even worse, a nameserver | 1290 | * anyhow. No need for a special action. Even worse, a nameserver |
1291 | * failure would not wake up waiting ports without the call. | 1291 | * failure would not wake up waiting ports without the call. |
1292 | */ | 1292 | */ |
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index fe57941ab55d..e45f85f7c7ed 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
@@ -502,7 +502,7 @@ zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *fsf_req) | |||
502 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 502 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
503 | break; | 503 | break; |
504 | case FSF_SQ_NO_RECOM: | 504 | case FSF_SQ_NO_RECOM: |
505 | ZFCP_LOG_NORMAL("bug: No recommendation could be given for a" | 505 | ZFCP_LOG_NORMAL("bug: No recommendation could be given for a " |
506 | "problem on the adapter %s " | 506 | "problem on the adapter %s " |
507 | "Stopping all operations on this adapter. ", | 507 | "Stopping all operations on this adapter. ", |
508 | zfcp_get_busid_by_adapter(fsf_req->adapter)); | 508 | zfcp_get_busid_by_adapter(fsf_req->adapter)); |
@@ -813,7 +813,7 @@ zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *fsf_req) | |||
813 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); | 813 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); |
814 | 814 | ||
815 | if (!port || (port->d_id != (status_buffer->d_id & ZFCP_DID_MASK))) { | 815 | if (!port || (port->d_id != (status_buffer->d_id & ZFCP_DID_MASK))) { |
816 | ZFCP_LOG_NORMAL("bug: Reopen port indication received for" | 816 | ZFCP_LOG_NORMAL("bug: Reopen port indication received for " |
817 | "nonexisting port with d_id 0x%06x on " | 817 | "nonexisting port with d_id 0x%06x on " |
818 | "adapter %s. Ignored.\n", | 818 | "adapter %s. Ignored.\n", |
819 | status_buffer->d_id & ZFCP_DID_MASK, | 819 | status_buffer->d_id & ZFCP_DID_MASK, |
@@ -2281,7 +2281,7 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action) | |||
2281 | &lock_flags, &fsf_req); | 2281 | &lock_flags, &fsf_req); |
2282 | if (retval) { | 2282 | if (retval) { |
2283 | ZFCP_LOG_INFO("error: Out of resources. Could not create an " | 2283 | ZFCP_LOG_INFO("error: Out of resources. Could not create an " |
2284 | "exchange port data request for" | 2284 | "exchange port data request for " |
2285 | "the adapter %s.\n", | 2285 | "the adapter %s.\n", |
2286 | zfcp_get_busid_by_adapter(adapter)); | 2286 | zfcp_get_busid_by_adapter(adapter)); |
2287 | write_unlock_irqrestore(&adapter->request_queue.queue_lock, | 2287 | write_unlock_irqrestore(&adapter->request_queue.queue_lock, |
@@ -2340,7 +2340,7 @@ zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter, | |||
2340 | 0, NULL, &lock_flags, &fsf_req); | 2340 | 0, NULL, &lock_flags, &fsf_req); |
2341 | if (retval) { | 2341 | if (retval) { |
2342 | ZFCP_LOG_INFO("error: Out of resources. Could not create an " | 2342 | ZFCP_LOG_INFO("error: Out of resources. Could not create an " |
2343 | "exchange port data request for" | 2343 | "exchange port data request for " |
2344 | "the adapter %s.\n", | 2344 | "the adapter %s.\n", |
2345 | zfcp_get_busid_by_adapter(adapter)); | 2345 | zfcp_get_busid_by_adapter(adapter)); |
2346 | write_unlock_irqrestore(&adapter->request_queue.queue_lock, | 2346 | write_unlock_irqrestore(&adapter->request_queue.queue_lock, |
@@ -4725,7 +4725,7 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags, | |||
4725 | /* allocate new FSF request */ | 4725 | /* allocate new FSF request */ |
4726 | fsf_req = zfcp_fsf_req_alloc(pool, req_flags); | 4726 | fsf_req = zfcp_fsf_req_alloc(pool, req_flags); |
4727 | if (unlikely(NULL == fsf_req)) { | 4727 | if (unlikely(NULL == fsf_req)) { |
4728 | ZFCP_LOG_DEBUG("error: Could not put an FSF request into" | 4728 | ZFCP_LOG_DEBUG("error: Could not put an FSF request into " |
4729 | "the outbound (send) queue.\n"); | 4729 | "the outbound (send) queue.\n"); |
4730 | ret = -ENOMEM; | 4730 | ret = -ENOMEM; |
4731 | goto failed_fsf_req; | 4731 | goto failed_fsf_req; |
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index 51d92b196ee7..22fdc17e0d0e 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c | |||
@@ -529,7 +529,7 @@ zfcp_qdio_sbals_wipe(struct zfcp_fsf_req *fsf_req) | |||
529 | 529 | ||
530 | 530 | ||
531 | /** | 531 | /** |
532 | * zfcp_qdio_sbale_fill - set address and lenght in current SBALE | 532 | * zfcp_qdio_sbale_fill - set address and length in current SBALE |
533 | * on request_queue | 533 | * on request_queue |
534 | */ | 534 | */ |
535 | static void | 535 | static void |
diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c index facb67855619..6a48dfa1efe8 100644 --- a/drivers/serial/21285.c +++ b/drivers/serial/21285.c | |||
@@ -277,6 +277,8 @@ serial21285_set_termios(struct uart_port *port, struct ktermios *termios, | |||
277 | if (termios->c_iflag & INPCK) | 277 | if (termios->c_iflag & INPCK) |
278 | port->read_status_mask |= RXSTAT_FRAME | RXSTAT_PARITY; | 278 | port->read_status_mask |= RXSTAT_FRAME | RXSTAT_PARITY; |
279 | 279 | ||
280 | tty_encode_baud_rate(tty, baud, baud); | ||
281 | |||
280 | /* | 282 | /* |
281 | * Which character status flags should we ignore? | 283 | * Which character status flags should we ignore? |
282 | */ | 284 | */ |
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index 6f475b609864..ac2a3ef28d55 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c | |||
@@ -442,7 +442,8 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart) | |||
442 | set_bfin_dma_config(DIR_READ, DMA_FLOW_STOP, | 442 | set_bfin_dma_config(DIR_READ, DMA_FLOW_STOP, |
443 | INTR_ON_BUF, | 443 | INTR_ON_BUF, |
444 | DIMENSION_LINEAR, | 444 | DIMENSION_LINEAR, |
445 | DATA_SIZE_8)); | 445 | DATA_SIZE_8, |
446 | DMA_SYNC_RESTART)); | ||
446 | set_dma_start_addr(uart->tx_dma_channel, (unsigned long)(xmit->buf+xmit->tail)); | 447 | set_dma_start_addr(uart->tx_dma_channel, (unsigned long)(xmit->buf+xmit->tail)); |
447 | set_dma_x_count(uart->tx_dma_channel, uart->tx_count); | 448 | set_dma_x_count(uart->tx_dma_channel, uart->tx_count); |
448 | set_dma_x_modify(uart->tx_dma_channel, 1); | 449 | set_dma_x_modify(uart->tx_dma_channel, 1); |
@@ -689,7 +690,8 @@ static int bfin_serial_startup(struct uart_port *port) | |||
689 | set_dma_config(uart->rx_dma_channel, | 690 | set_dma_config(uart->rx_dma_channel, |
690 | set_bfin_dma_config(DIR_WRITE, DMA_FLOW_AUTO, | 691 | set_bfin_dma_config(DIR_WRITE, DMA_FLOW_AUTO, |
691 | INTR_ON_ROW, DIMENSION_2D, | 692 | INTR_ON_ROW, DIMENSION_2D, |
692 | DATA_SIZE_8)); | 693 | DATA_SIZE_8, |
694 | DMA_SYNC_RESTART)); | ||
693 | set_dma_x_count(uart->rx_dma_channel, DMA_RX_XCOUNT); | 695 | set_dma_x_count(uart->rx_dma_channel, DMA_RX_XCOUNT); |
694 | set_dma_x_modify(uart->rx_dma_channel, 1); | 696 | set_dma_x_modify(uart->rx_dma_channel, 1); |
695 | set_dma_y_count(uart->rx_dma_channel, DMA_RX_YCOUNT); | 697 | set_dma_y_count(uart->rx_dma_channel, DMA_RX_YCOUNT); |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index f81d08d6538b..77a3759d6fc7 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -308,7 +308,7 @@ config USB_S3C2410_DEBUG | |||
308 | 308 | ||
309 | config USB_GADGET_AT91 | 309 | config USB_GADGET_AT91 |
310 | boolean "AT91 USB Device Port" | 310 | boolean "AT91 USB Device Port" |
311 | depends on ARCH_AT91 && !ARCH_AT91SAM9RL | 311 | depends on ARCH_AT91 && !ARCH_AT91SAM9RL && !ARCH_AT91CAP9 |
312 | select USB_GADGET_SELECTED | 312 | select USB_GADGET_SELECTED |
313 | help | 313 | help |
314 | Many Atmel AT91 processors (such as the AT91RM2000) have a | 314 | Many Atmel AT91 processors (such as the AT91RM2000) have a |
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index 5cfa3d1c4413..74e1f4be10bb 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c | |||
@@ -47,7 +47,7 @@ | |||
47 | #endif | 47 | #endif |
48 | 48 | ||
49 | #ifdef CONFIG_TPS65010 | 49 | #ifdef CONFIG_TPS65010 |
50 | #include <asm/arch/tps65010.h> | 50 | #include <linux/i2c/tps65010.h> |
51 | #else | 51 | #else |
52 | 52 | ||
53 | #define LOW 0 | 53 | #define LOW 0 |
diff --git a/drivers/usb/host/ohci-pnx4008.c b/drivers/usb/host/ohci-pnx4008.c index ca2a6abbc117..6c52c66b659f 100644 --- a/drivers/usb/host/ohci-pnx4008.c +++ b/drivers/usb/host/ohci-pnx4008.c | |||
@@ -112,9 +112,9 @@ static int isp1301_detach(struct i2c_client *client); | |||
112 | static int isp1301_command(struct i2c_client *client, unsigned int cmd, | 112 | static int isp1301_command(struct i2c_client *client, unsigned int cmd, |
113 | void *arg); | 113 | void *arg); |
114 | 114 | ||
115 | static unsigned short normal_i2c[] = | 115 | static const unsigned short normal_i2c[] = |
116 | { ISP1301_I2C_ADDR, ISP1301_I2C_ADDR + 1, I2C_CLIENT_END }; | 116 | { ISP1301_I2C_ADDR, ISP1301_I2C_ADDR + 1, I2C_CLIENT_END }; |
117 | static unsigned short dummy_i2c_addrlist[] = { I2C_CLIENT_END }; | 117 | static const unsigned short dummy_i2c_addrlist[] = { I2C_CLIENT_END }; |
118 | 118 | ||
119 | static struct i2c_client_address_data addr_data = { | 119 | static struct i2c_client_address_data addr_data = { |
120 | .normal_i2c = normal_i2c, | 120 | .normal_i2c = normal_i2c, |
@@ -123,7 +123,6 @@ static struct i2c_client_address_data addr_data = { | |||
123 | }; | 123 | }; |
124 | 124 | ||
125 | struct i2c_driver isp1301_driver = { | 125 | struct i2c_driver isp1301_driver = { |
126 | .id = I2C_DRIVERID_I2CDEV, /* Fake Id */ | ||
127 | .class = I2C_CLASS_HWMON, | 126 | .class = I2C_CLASS_HWMON, |
128 | .attach_adapter = isp1301_probe, | 127 | .attach_adapter = isp1301_probe, |
129 | .detach_client = isp1301_detach, | 128 | .detach_client = isp1301_detach, |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 5b3dbcfcda48..758435f8a6f8 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -889,7 +889,7 @@ config FB_S1D13XXX | |||
889 | 889 | ||
890 | config FB_ATMEL | 890 | config FB_ATMEL |
891 | tristate "AT91/AT32 LCD Controller support" | 891 | tristate "AT91/AT32 LCD Controller support" |
892 | depends on FB && (ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || AVR32) | 892 | depends on FB && (ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || AVR32) |
893 | select FB_CFB_FILLRECT | 893 | select FB_CFB_FILLRECT |
894 | select FB_CFB_COPYAREA | 894 | select FB_CFB_COPYAREA |
895 | select FB_CFB_IMAGEBLIT | 895 | select FB_CFB_IMAGEBLIT |
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 7c30cc8df71e..f8e711147501 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #define ATMEL_LCDC_CVAL_DEFAULT 0xc8 | 30 | #define ATMEL_LCDC_CVAL_DEFAULT 0xc8 |
31 | #define ATMEL_LCDC_DMA_BURST_LEN 8 | 31 | #define ATMEL_LCDC_DMA_BURST_LEN 8 |
32 | 32 | ||
33 | #if defined(CONFIG_ARCH_AT91SAM9263) | 33 | #if defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91CAP9) |
34 | #define ATMEL_LCDC_FIFO_SIZE 2048 | 34 | #define ATMEL_LCDC_FIFO_SIZE 2048 |
35 | #else | 35 | #else |
36 | #define ATMEL_LCDC_FIFO_SIZE 512 | 36 | #define ATMEL_LCDC_FIFO_SIZE 512 |
diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c index 74d11c318987..c8e7427a0bc8 100644 --- a/drivers/video/bf54x-lq043fb.c +++ b/drivers/video/bf54x-lq043fb.c | |||
@@ -224,7 +224,8 @@ static int config_dma(struct bfin_bf54xfb_info *fbi) | |||
224 | set_dma_config(CH_EPPI0, | 224 | set_dma_config(CH_EPPI0, |
225 | set_bfin_dma_config(DIR_READ, DMA_FLOW_AUTO, | 225 | set_bfin_dma_config(DIR_READ, DMA_FLOW_AUTO, |
226 | INTR_DISABLE, DIMENSION_2D, | 226 | INTR_DISABLE, DIMENSION_2D, |
227 | DATA_SIZE_32)); | 227 | DATA_SIZE_32, |
228 | DMA_NOSYNC_KEEP_DMA_BUF)); | ||
228 | set_dma_x_count(CH_EPPI0, (LCD_X_RES * LCD_BPP) / DMA_BUS_SIZE); | 229 | set_dma_x_count(CH_EPPI0, (LCD_X_RES * LCD_BPP) / DMA_BUS_SIZE); |
229 | set_dma_x_modify(CH_EPPI0, DMA_BUS_SIZE / 8); | 230 | set_dma_x_modify(CH_EPPI0, DMA_BUS_SIZE / 8); |
230 | set_dma_y_count(CH_EPPI0, LCD_Y_RES); | 231 | set_dma_y_count(CH_EPPI0, LCD_Y_RES); |
@@ -263,8 +264,7 @@ static int request_ports(struct bfin_bf54xfb_info *fbi) | |||
263 | } | 264 | } |
264 | } | 265 | } |
265 | 266 | ||
266 | gpio_direction_output(disp); | 267 | gpio_direction_output(disp, 1); |
267 | gpio_set_value(disp, 1); | ||
268 | 268 | ||
269 | return 0; | 269 | return 0; |
270 | } | 270 | } |
diff --git a/drivers/video/matrox/matroxfb_maven.c b/drivers/video/matrox/matroxfb_maven.c index 49cd53e46c0a..0cd58f84fb46 100644 --- a/drivers/video/matrox/matroxfb_maven.c +++ b/drivers/video/matrox/matroxfb_maven.c | |||
@@ -1232,7 +1232,7 @@ static int maven_shutdown_client(struct i2c_client* clnt) { | |||
1232 | return 0; | 1232 | return 0; |
1233 | } | 1233 | } |
1234 | 1234 | ||
1235 | static unsigned short normal_i2c[] = { MAVEN_I2CID, I2C_CLIENT_END }; | 1235 | static const unsigned short normal_i2c[] = { MAVEN_I2CID, I2C_CLIENT_END }; |
1236 | I2C_CLIENT_INSMOD; | 1236 | I2C_CLIENT_INSMOD; |
1237 | 1237 | ||
1238 | static struct i2c_driver maven_driver; | 1238 | static struct i2c_driver maven_driver; |
diff --git a/drivers/video/omap/lcd_h3.c b/drivers/video/omap/lcd_h3.c index c604d935c188..31e978349a80 100644 --- a/drivers/video/omap/lcd_h3.c +++ b/drivers/video/omap/lcd_h3.c | |||
@@ -21,9 +21,9 @@ | |||
21 | 21 | ||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
24 | #include <linux/i2c/tps65010.h> | ||
24 | 25 | ||
25 | #include <asm/arch/gpio.h> | 26 | #include <asm/arch/gpio.h> |
26 | #include <asm/arch/tps65010.h> | ||
27 | #include <asm/arch/omapfb.h> | 27 | #include <asm/arch/omapfb.h> |
28 | 28 | ||
29 | #define MODULE_NAME "omapfb-lcd_h3" | 29 | #define MODULE_NAME "omapfb-lcd_h3" |
diff --git a/drivers/w1/masters/ds2482.c b/drivers/w1/masters/ds2482.c index d93eb626b2f0..0fd5820d5c61 100644 --- a/drivers/w1/masters/ds2482.c +++ b/drivers/w1/masters/ds2482.c | |||
@@ -29,7 +29,7 @@ | |||
29 | * However, the chip cannot be detected without doing an i2c write, | 29 | * However, the chip cannot be detected without doing an i2c write, |
30 | * so use the force module parameter. | 30 | * so use the force module parameter. |
31 | */ | 31 | */ |
32 | static unsigned short normal_i2c[] = {I2C_CLIENT_END}; | 32 | static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; |
33 | 33 | ||
34 | /** | 34 | /** |
35 | * Insmod parameters | 35 | * Insmod parameters |
diff --git a/fs/Kconfig b/fs/Kconfig index b6df18f1f677..9656139d2e99 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
@@ -1899,13 +1899,15 @@ config CIFS | |||
1899 | file servers such as Windows 2000 (including Windows 2003, NT 4 | 1899 | file servers such as Windows 2000 (including Windows 2003, NT 4 |
1900 | and Windows XP) as well by Samba (which provides excellent CIFS | 1900 | and Windows XP) as well by Samba (which provides excellent CIFS |
1901 | server support for Linux and many other operating systems). Limited | 1901 | server support for Linux and many other operating systems). Limited |
1902 | support for OS/2 and Windows ME and similar servers is provided as well. | 1902 | support for OS/2 and Windows ME and similar servers is provided as |
1903 | 1903 | well. | |
1904 | The intent of the cifs module is to provide an advanced | 1904 | |
1905 | network file system client for mounting to CIFS compliant servers, | 1905 | The cifs module provides an advanced network file system |
1906 | including support for dfs (hierarchical name space), secure per-user | 1906 | client for mounting to CIFS compliant servers. It includes |
1907 | session establishment, safe distributed caching (oplock), optional | 1907 | support for DFS (hierarchical name space), secure per-user |
1908 | packet signing, Unicode and other internationalization improvements. | 1908 | session establishment via Kerberos or NTLM or NTLMv2, |
1909 | safe distributed caching (oplock), optional packet | ||
1910 | signing, Unicode and other internationalization improvements. | ||
1909 | If you need to mount to Samba or Windows from this machine, say Y. | 1911 | If you need to mount to Samba or Windows from this machine, say Y. |
1910 | 1912 | ||
1911 | config CIFS_STATS | 1913 | config CIFS_STATS |
@@ -1937,7 +1939,8 @@ config CIFS_WEAK_PW_HASH | |||
1937 | (since 1997) support stronger NTLM (and even NTLMv2 and Kerberos) | 1939 | (since 1997) support stronger NTLM (and even NTLMv2 and Kerberos) |
1938 | security mechanisms. These hash the password more securely | 1940 | security mechanisms. These hash the password more securely |
1939 | than the mechanisms used in the older LANMAN version of the | 1941 | than the mechanisms used in the older LANMAN version of the |
1940 | SMB protocol needed to establish sessions with old SMB servers. | 1942 | SMB protocol but LANMAN based authentication is needed to |
1943 | establish sessions with some old SMB servers. | ||
1941 | 1944 | ||
1942 | Enabling this option allows the cifs module to mount to older | 1945 | Enabling this option allows the cifs module to mount to older |
1943 | LANMAN based servers such as OS/2 and Windows 95, but such | 1946 | LANMAN based servers such as OS/2 and Windows 95, but such |
@@ -1945,8 +1948,8 @@ config CIFS_WEAK_PW_HASH | |||
1945 | security mechanisms if you are on a public network. Unless you | 1948 | security mechanisms if you are on a public network. Unless you |
1946 | have a need to access old SMB servers (and are on a private | 1949 | have a need to access old SMB servers (and are on a private |
1947 | network) you probably want to say N. Even if this support | 1950 | network) you probably want to say N. Even if this support |
1948 | is enabled in the kernel build, they will not be used | 1951 | is enabled in the kernel build, LANMAN authentication will not be |
1949 | automatically. At runtime LANMAN mounts are disabled but | 1952 | used automatically. At runtime LANMAN mounts are disabled but |
1950 | can be set to required (or optional) either in | 1953 | can be set to required (or optional) either in |
1951 | /proc/fs/cifs (see fs/cifs/README for more detail) or via an | 1954 | /proc/fs/cifs (see fs/cifs/README for more detail) or via an |
1952 | option on the mount command. This support is disabled by | 1955 | option on the mount command. This support is disabled by |
@@ -2012,12 +2015,22 @@ config CIFS_UPCALL | |||
2012 | depends on CIFS_EXPERIMENTAL | 2015 | depends on CIFS_EXPERIMENTAL |
2013 | depends on KEYS | 2016 | depends on KEYS |
2014 | help | 2017 | help |
2015 | Enables an upcall mechanism for CIFS which will be used to contact | 2018 | Enables an upcall mechanism for CIFS which accesses |
2016 | userspace helper utilities to provide SPNEGO packaged Kerberos | 2019 | userspace helper utilities to provide SPNEGO packaged (RFC 4178) |
2017 | tickets which are needed to mount to certain secure servers | 2020 | Kerberos tickets which are needed to mount to certain secure servers |
2018 | (for which more secure Kerberos authentication is required). If | 2021 | (for which more secure Kerberos authentication is required). If |
2019 | unsure, say N. | 2022 | unsure, say N. |
2020 | 2023 | ||
2024 | config CIFS_DFS_UPCALL | ||
2025 | bool "DFS feature support (EXPERIMENTAL)" | ||
2026 | depends on CIFS_EXPERIMENTAL | ||
2027 | depends on KEYS | ||
2028 | help | ||
2029 | Enables an upcall mechanism for CIFS which contacts userspace | ||
2030 | helper utilities to provide server name resolution (host names to | ||
2031 | IP addresses) which is needed for implicit mounts of DFS junction | ||
2032 | points. If unsure, say N. | ||
2033 | |||
2021 | config NCP_FS | 2034 | config NCP_FS |
2022 | tristate "NCP file system support (to mount NetWare volumes)" | 2035 | tristate "NCP file system support (to mount NetWare volumes)" |
2023 | depends on IPX!=n || INET | 2036 | depends on IPX!=n || INET |
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index a609599287aa..edd248367b36 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES | |||
@@ -3,7 +3,10 @@ Version 1.52 | |||
3 | Fix oops on second mount to server when null auth is used. | 3 | Fix oops on second mount to server when null auth is used. |
4 | Enable experimental Kerberos support. Return writebehind errors on flush | 4 | Enable experimental Kerberos support. Return writebehind errors on flush |
5 | and sync so that events like out of disk space get reported properly on | 5 | and sync so that events like out of disk space get reported properly on |
6 | cached files. | 6 | cached files. Fix setxattr failure to certain Samba versions. Fix mount |
7 | of second share to disconnected server session (autoreconnect on this). | ||
8 | Add ability to modify cifs acls for handling chmod (when mounted with | ||
9 | cifsacl flag). | ||
7 | 10 | ||
8 | Version 1.51 | 11 | Version 1.51 |
9 | ------------ | 12 | ------------ |
diff --git a/fs/cifs/Makefile b/fs/cifs/Makefile index 45e42fb97c19..6ba43fb346fb 100644 --- a/fs/cifs/Makefile +++ b/fs/cifs/Makefile | |||
@@ -9,3 +9,5 @@ cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \ | |||
9 | readdir.o ioctl.o sess.o export.o cifsacl.o | 9 | readdir.o ioctl.o sess.o export.o cifsacl.o |
10 | 10 | ||
11 | cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o | 11 | cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o |
12 | |||
13 | cifs-$(CONFIG_CIFS_DFS_UPCALL) += dns_resolve.o cifs_dfs_ref.o | ||
diff --git a/fs/cifs/README b/fs/cifs/README index bf11329ac784..c623e2f9c5db 100644 --- a/fs/cifs/README +++ b/fs/cifs/README | |||
@@ -56,7 +56,8 @@ the CIFS VFS web site) copy it to the same directory in which mount.smbfs and | |||
56 | similar files reside (usually /sbin). Although the helper software is not | 56 | similar files reside (usually /sbin). Although the helper software is not |
57 | required, mount.cifs is recommended. Eventually the Samba 3.0 utility program | 57 | required, mount.cifs is recommended. Eventually the Samba 3.0 utility program |
58 | "net" may also be helpful since it may someday provide easier mount syntax for | 58 | "net" may also be helpful since it may someday provide easier mount syntax for |
59 | users who are used to Windows e.g. net use <mount point> <UNC name or cifs URL> | 59 | users who are used to Windows e.g. |
60 | net use <mount point> <UNC name or cifs URL> | ||
60 | Note that running the Winbind pam/nss module (logon service) on all of your | 61 | Note that running the Winbind pam/nss module (logon service) on all of your |
61 | Linux clients is useful in mapping Uids and Gids consistently across the | 62 | Linux clients is useful in mapping Uids and Gids consistently across the |
62 | domain to the proper network user. The mount.cifs mount helper can be | 63 | domain to the proper network user. The mount.cifs mount helper can be |
@@ -248,7 +249,7 @@ A partial list of the supported mount options follows: | |||
248 | the CIFS session. | 249 | the CIFS session. |
249 | password The user password. If the mount helper is | 250 | password The user password. If the mount helper is |
250 | installed, the user will be prompted for password | 251 | installed, the user will be prompted for password |
251 | if it is not supplied. | 252 | if not supplied. |
252 | ip The ip address of the target server | 253 | ip The ip address of the target server |
253 | unc The target server Universal Network Name (export) to | 254 | unc The target server Universal Network Name (export) to |
254 | mount. | 255 | mount. |
@@ -283,7 +284,7 @@ A partial list of the supported mount options follows: | |||
283 | can be enabled by specifying file_mode and dir_mode on | 284 | can be enabled by specifying file_mode and dir_mode on |
284 | the client. Note that the mount.cifs helper must be | 285 | the client. Note that the mount.cifs helper must be |
285 | at version 1.10 or higher to support specifying the uid | 286 | at version 1.10 or higher to support specifying the uid |
286 | (or gid) in non-numberic form. | 287 | (or gid) in non-numeric form. |
287 | gid Set the default gid for inodes (similar to above). | 288 | gid Set the default gid for inodes (similar to above). |
288 | file_mode If CIFS Unix extensions are not supported by the server | 289 | file_mode If CIFS Unix extensions are not supported by the server |
289 | this overrides the default mode for file inodes. | 290 | this overrides the default mode for file inodes. |
@@ -417,9 +418,10 @@ A partial list of the supported mount options follows: | |||
417 | acl Allow setfacl and getfacl to manage posix ACLs if server | 418 | acl Allow setfacl and getfacl to manage posix ACLs if server |
418 | supports them. (default) | 419 | supports them. (default) |
419 | noacl Do not allow setfacl and getfacl calls on this mount | 420 | noacl Do not allow setfacl and getfacl calls on this mount |
420 | user_xattr Allow getting and setting user xattrs as OS/2 EAs (extended | 421 | user_xattr Allow getting and setting user xattrs (those attributes whose |
421 | attributes) to the server (default) e.g. via setfattr | 422 | name begins with "user." or "os2.") as OS/2 EAs (extended |
422 | and getfattr utilities. | 423 | attributes) to the server. This allows support of the |
424 | setfattr and getfattr utilities. (default) | ||
423 | nouser_xattr Do not allow getfattr/setfattr to get/set/list xattrs | 425 | nouser_xattr Do not allow getfattr/setfattr to get/set/list xattrs |
424 | mapchars Translate six of the seven reserved characters (not backslash) | 426 | mapchars Translate six of the seven reserved characters (not backslash) |
425 | *?<>|: | 427 | *?<>|: |
@@ -434,6 +436,7 @@ A partial list of the supported mount options follows: | |||
434 | nomapchars Do not translate any of these seven characters (default). | 436 | nomapchars Do not translate any of these seven characters (default). |
435 | nocase Request case insensitive path name matching (case | 437 | nocase Request case insensitive path name matching (case |
436 | sensitive is the default if the server suports it). | 438 | sensitive is the default if the server suports it). |
439 | (mount option "ignorecase" is identical to "nocase") | ||
437 | posixpaths If CIFS Unix extensions are supported, attempt to | 440 | posixpaths If CIFS Unix extensions are supported, attempt to |
438 | negotiate posix path name support which allows certain | 441 | negotiate posix path name support which allows certain |
439 | characters forbidden in typical CIFS filenames, without | 442 | characters forbidden in typical CIFS filenames, without |
@@ -485,6 +488,9 @@ A partial list of the supported mount options follows: | |||
485 | ntlmv2i Use NTLMv2 password hashing with packet signing | 488 | ntlmv2i Use NTLMv2 password hashing with packet signing |
486 | lanman (if configured in kernel config) use older | 489 | lanman (if configured in kernel config) use older |
487 | lanman hash | 490 | lanman hash |
491 | hard Retry file operations if server is not responding | ||
492 | soft Limit retries to unresponsive servers (usually only | ||
493 | one retry) before returning an error. (default) | ||
488 | 494 | ||
489 | The mount.cifs mount helper also accepts a few mount options before -o | 495 | The mount.cifs mount helper also accepts a few mount options before -o |
490 | including: | 496 | including: |
@@ -535,8 +541,8 @@ SecurityFlags Flags which control security negotiation and | |||
535 | must use NTLM 0x02002 | 541 | must use NTLM 0x02002 |
536 | may use NTLMv2 0x00004 | 542 | may use NTLMv2 0x00004 |
537 | must use NTLMv2 0x04004 | 543 | must use NTLMv2 0x04004 |
538 | may use Kerberos security (not implemented yet) 0x00008 | 544 | may use Kerberos security 0x00008 |
539 | must use Kerberos (not implemented yet) 0x08008 | 545 | must use Kerberos 0x08008 |
540 | may use lanman (weak) password hash 0x00010 | 546 | may use lanman (weak) password hash 0x00010 |
541 | must use lanman password hash 0x10010 | 547 | must use lanman password hash 0x10010 |
542 | may use plaintext passwords 0x00020 | 548 | may use plaintext passwords 0x00020 |
@@ -626,6 +632,6 @@ returned success. | |||
626 | 632 | ||
627 | Also note that "cat /proc/fs/cifs/DebugData" will display information about | 633 | Also note that "cat /proc/fs/cifs/DebugData" will display information about |
628 | the active sessions and the shares that are mounted. | 634 | the active sessions and the shares that are mounted. |
629 | Enabling Kerberos (extended security) works when CONFIG_CIFS_EXPERIMENTAL is enabled | 635 | Enabling Kerberos (extended security) works when CONFIG_CIFS_EXPERIMENTAL is |
630 | but requires a user space helper (from the Samba project). NTLM and NTLMv2 and | 636 | on but requires a user space helper (from the Samba project). NTLM and NTLMv2 and |
631 | LANMAN support do not require this helpr. | 637 | LANMAN support do not require this helper. |
diff --git a/fs/cifs/TODO b/fs/cifs/TODO index a8852c200728..92c9feac440f 100644 --- a/fs/cifs/TODO +++ b/fs/cifs/TODO | |||
@@ -1,4 +1,4 @@ | |||
1 | Version 1.49 April 26, 2007 | 1 | Version 1.52 January 3, 2008 |
2 | 2 | ||
3 | A Partial List of Missing Features | 3 | A Partial List of Missing Features |
4 | ================================== | 4 | ================================== |
@@ -16,16 +16,14 @@ SecurityDescriptors | |||
16 | c) Better pam/winbind integration (e.g. to handle uid mapping | 16 | c) Better pam/winbind integration (e.g. to handle uid mapping |
17 | better) | 17 | better) |
18 | 18 | ||
19 | d) Verify that Kerberos signing works | 19 | d) Cleanup now unneeded SessSetup code in |
20 | |||
21 | e) Cleanup now unneeded SessSetup code in | ||
22 | fs/cifs/connect.c and add back in NTLMSSP code if any servers | 20 | fs/cifs/connect.c and add back in NTLMSSP code if any servers |
23 | need it | 21 | need it |
24 | 22 | ||
25 | f) MD5-HMAC signing SMB PDUs when SPNEGO style SessionSetup | 23 | e) ms-dfs and ms-dfs host name resolution cleanup |
26 | used (Kerberos or NTLMSSP). Signing alreadyimplemented for NTLM | 24 | |
27 | and raw NTLMSSP already. This is important when enabling | 25 | f) fix NTLMv2 signing when two mounts with different users to same |
28 | extended security and mounting to Windows 2003 Servers | 26 | server. |
29 | 27 | ||
30 | g) Directory entry caching relies on a 1 second timer, rather than | 28 | g) Directory entry caching relies on a 1 second timer, rather than |
31 | using FindNotify or equivalent. - (started) | 29 | using FindNotify or equivalent. - (started) |
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c new file mode 100644 index 000000000000..413ee2349d1a --- /dev/null +++ b/fs/cifs/cifs_dfs_ref.c | |||
@@ -0,0 +1,377 @@ | |||
1 | /* | ||
2 | * Contains the CIFS DFS referral mounting routines used for handling | ||
3 | * traversal via DFS junction point | ||
4 | * | ||
5 | * Copyright (c) 2007 Igor Mammedov | ||
6 | * Copyright (C) International Business Machines Corp., 2008 | ||
7 | * Author(s): Igor Mammedov (niallain@gmail.com) | ||
8 | * Steve French (sfrench@us.ibm.com) | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License | ||
11 | * as published by the Free Software Foundation; either version | ||
12 | * 2 of the License, or (at your option) any later version. | ||
13 | */ | ||
14 | |||
15 | #include <linux/dcache.h> | ||
16 | #include <linux/mount.h> | ||
17 | #include <linux/namei.h> | ||
18 | #include <linux/vfs.h> | ||
19 | #include <linux/fs.h> | ||
20 | #include "cifsglob.h" | ||
21 | #include "cifsproto.h" | ||
22 | #include "cifsfs.h" | ||
23 | #include "dns_resolve.h" | ||
24 | #include "cifs_debug.h" | ||
25 | |||
26 | LIST_HEAD(cifs_dfs_automount_list); | ||
27 | |||
28 | /* | ||
29 | * DFS functions | ||
30 | */ | ||
31 | |||
32 | void dfs_shrink_umount_helper(struct vfsmount *vfsmnt) | ||
33 | { | ||
34 | mark_mounts_for_expiry(&cifs_dfs_automount_list); | ||
35 | mark_mounts_for_expiry(&cifs_dfs_automount_list); | ||
36 | shrink_submounts(vfsmnt, &cifs_dfs_automount_list); | ||
37 | } | ||
38 | |||
39 | /** | ||
40 | * cifs_get_share_name - extracts share name from UNC | ||
41 | * @node_name: pointer to UNC string | ||
42 | * | ||
43 | * Extracts sharename form full UNC. | ||
44 | * i.e. strips from UNC trailing path that is not part of share | ||
45 | * name and fixup missing '\' in the begining of DFS node refferal | ||
46 | * if neccessary. | ||
47 | * Returns pointer to share name on success or NULL on error. | ||
48 | * Caller is responsible for freeing returned string. | ||
49 | */ | ||
50 | static char *cifs_get_share_name(const char *node_name) | ||
51 | { | ||
52 | int len; | ||
53 | char *UNC; | ||
54 | char *pSep; | ||
55 | |||
56 | len = strlen(node_name); | ||
57 | UNC = kmalloc(len+2 /*for term null and additional \ if it's missed */, | ||
58 | GFP_KERNEL); | ||
59 | if (!UNC) | ||
60 | return NULL; | ||
61 | |||
62 | /* get share name and server name */ | ||
63 | if (node_name[1] != '\\') { | ||
64 | UNC[0] = '\\'; | ||
65 | strncpy(UNC+1, node_name, len); | ||
66 | len++; | ||
67 | UNC[len] = 0; | ||
68 | } else { | ||
69 | strncpy(UNC, node_name, len); | ||
70 | UNC[len] = 0; | ||
71 | } | ||
72 | |||
73 | /* find server name end */ | ||
74 | pSep = memchr(UNC+2, '\\', len-2); | ||
75 | if (!pSep) { | ||
76 | cERROR(1, ("%s: no server name end in node name: %s", | ||
77 | __FUNCTION__, node_name)); | ||
78 | kfree(UNC); | ||
79 | return NULL; | ||
80 | } | ||
81 | |||
82 | /* find sharename end */ | ||
83 | pSep++; | ||
84 | pSep = memchr(UNC+(pSep-UNC), '\\', len-(pSep-UNC)); | ||
85 | if (!pSep) { | ||
86 | cERROR(1, ("%s:2 cant find share name in node name: %s", | ||
87 | __FUNCTION__, node_name)); | ||
88 | kfree(UNC); | ||
89 | return NULL; | ||
90 | } | ||
91 | /* trim path up to sharename end | ||
92 | * * now we have share name in UNC */ | ||
93 | *pSep = 0; | ||
94 | |||
95 | return UNC; | ||
96 | } | ||
97 | |||
98 | |||
99 | /** | ||
100 | * compose_mount_options - creates mount options for refferral | ||
101 | * @sb_mountdata: parent/root DFS mount options (template) | ||
102 | * @ref_unc: refferral server UNC | ||
103 | * @devname: pointer for saving device name | ||
104 | * | ||
105 | * creates mount options for submount based on template options sb_mountdata | ||
106 | * and replacing unc,ip,prefixpath options with ones we've got form ref_unc. | ||
107 | * | ||
108 | * Returns: pointer to new mount options or ERR_PTR. | ||
109 | * Caller is responcible for freeing retunrned value if it is not error. | ||
110 | */ | ||
111 | static char *compose_mount_options(const char *sb_mountdata, | ||
112 | const char *ref_unc, | ||
113 | char **devname) | ||
114 | { | ||
115 | int rc; | ||
116 | char *mountdata; | ||
117 | int md_len; | ||
118 | char *tkn_e; | ||
119 | char *srvIP = NULL; | ||
120 | char sep = ','; | ||
121 | int off, noff; | ||
122 | |||
123 | if (sb_mountdata == NULL) | ||
124 | return ERR_PTR(-EINVAL); | ||
125 | |||
126 | *devname = cifs_get_share_name(ref_unc); | ||
127 | rc = dns_resolve_server_name_to_ip(*devname, &srvIP); | ||
128 | if (rc != 0) { | ||
129 | cERROR(1, ("%s: Failed to resolve server part of %s to IP", | ||
130 | __FUNCTION__, *devname)); | ||
131 | mountdata = ERR_PTR(rc); | ||
132 | goto compose_mount_options_out; | ||
133 | } | ||
134 | md_len = strlen(sb_mountdata) + strlen(srvIP) + strlen(ref_unc) + 3; | ||
135 | mountdata = kzalloc(md_len+1, GFP_KERNEL); | ||
136 | if (mountdata == NULL) { | ||
137 | mountdata = ERR_PTR(-ENOMEM); | ||
138 | goto compose_mount_options_out; | ||
139 | } | ||
140 | |||
141 | /* copy all options except of unc,ip,prefixpath */ | ||
142 | off = 0; | ||
143 | if (strncmp(sb_mountdata, "sep=", 4) == 0) { | ||
144 | sep = sb_mountdata[4]; | ||
145 | strncpy(mountdata, sb_mountdata, 5); | ||
146 | off += 5; | ||
147 | } | ||
148 | while ((tkn_e = strchr(sb_mountdata+off, sep))) { | ||
149 | noff = (tkn_e - (sb_mountdata+off)) + 1; | ||
150 | if (strnicmp(sb_mountdata+off, "unc=", 4) == 0) { | ||
151 | off += noff; | ||
152 | continue; | ||
153 | } | ||
154 | if (strnicmp(sb_mountdata+off, "ip=", 3) == 0) { | ||
155 | off += noff; | ||
156 | continue; | ||
157 | } | ||
158 | if (strnicmp(sb_mountdata+off, "prefixpath=", 3) == 0) { | ||
159 | off += noff; | ||
160 | continue; | ||
161 | } | ||
162 | strncat(mountdata, sb_mountdata+off, noff); | ||
163 | off += noff; | ||
164 | } | ||
165 | strcat(mountdata, sb_mountdata+off); | ||
166 | mountdata[md_len] = '\0'; | ||
167 | |||
168 | /* copy new IP and ref share name */ | ||
169 | strcat(mountdata, ",ip="); | ||
170 | strcat(mountdata, srvIP); | ||
171 | strcat(mountdata, ",unc="); | ||
172 | strcat(mountdata, *devname); | ||
173 | |||
174 | /* find & copy prefixpath */ | ||
175 | tkn_e = strchr(ref_unc+2, '\\'); | ||
176 | if (tkn_e) { | ||
177 | tkn_e = strchr(tkn_e+1, '\\'); | ||
178 | if (tkn_e) { | ||
179 | strcat(mountdata, ",prefixpath="); | ||
180 | strcat(mountdata, tkn_e); | ||
181 | } | ||
182 | } | ||
183 | |||
184 | /*cFYI(1,("%s: parent mountdata: %s", __FUNCTION__,sb_mountdata));*/ | ||
185 | /*cFYI(1, ("%s: submount mountdata: %s", __FUNCTION__, mountdata ));*/ | ||
186 | |||
187 | compose_mount_options_out: | ||
188 | kfree(srvIP); | ||
189 | return mountdata; | ||
190 | } | ||
191 | |||
192 | |||
193 | static struct vfsmount *cifs_dfs_do_refmount(const struct vfsmount *mnt_parent, | ||
194 | struct dentry *dentry, char *ref_unc) | ||
195 | { | ||
196 | struct cifs_sb_info *cifs_sb; | ||
197 | struct vfsmount *mnt; | ||
198 | char *mountdata; | ||
199 | char *devname = NULL; | ||
200 | |||
201 | cifs_sb = CIFS_SB(dentry->d_inode->i_sb); | ||
202 | mountdata = compose_mount_options(cifs_sb->mountdata, | ||
203 | ref_unc, &devname); | ||
204 | |||
205 | if (IS_ERR(mountdata)) | ||
206 | return (struct vfsmount *)mountdata; | ||
207 | |||
208 | mnt = vfs_kern_mount(&cifs_fs_type, 0, devname, mountdata); | ||
209 | kfree(mountdata); | ||
210 | kfree(devname); | ||
211 | return mnt; | ||
212 | |||
213 | } | ||
214 | |||
215 | static char *build_full_dfs_path_from_dentry(struct dentry *dentry) | ||
216 | { | ||
217 | char *full_path = NULL; | ||
218 | char *search_path; | ||
219 | char *tmp_path; | ||
220 | size_t l_max_len; | ||
221 | struct cifs_sb_info *cifs_sb; | ||
222 | |||
223 | if (dentry->d_inode == NULL) | ||
224 | return NULL; | ||
225 | |||
226 | cifs_sb = CIFS_SB(dentry->d_inode->i_sb); | ||
227 | |||
228 | if (cifs_sb->tcon == NULL) | ||
229 | return NULL; | ||
230 | |||
231 | search_path = build_path_from_dentry(dentry); | ||
232 | if (search_path == NULL) | ||
233 | return NULL; | ||
234 | |||
235 | if (cifs_sb->tcon->Flags & SMB_SHARE_IS_IN_DFS) { | ||
236 | /* we should use full path name to correct working with DFS */ | ||
237 | l_max_len = strnlen(cifs_sb->tcon->treeName, MAX_TREE_SIZE+1) + | ||
238 | strnlen(search_path, MAX_PATHCONF) + 1; | ||
239 | tmp_path = kmalloc(l_max_len, GFP_KERNEL); | ||
240 | if (tmp_path == NULL) { | ||
241 | kfree(search_path); | ||
242 | return NULL; | ||
243 | } | ||
244 | strncpy(tmp_path, cifs_sb->tcon->treeName, l_max_len); | ||
245 | strcat(tmp_path, search_path); | ||
246 | tmp_path[l_max_len-1] = 0; | ||
247 | full_path = tmp_path; | ||
248 | kfree(search_path); | ||
249 | } else { | ||
250 | full_path = search_path; | ||
251 | } | ||
252 | return full_path; | ||
253 | } | ||
254 | |||
255 | static int add_mount_helper(struct vfsmount *newmnt, struct nameidata *nd, | ||
256 | struct list_head *mntlist) | ||
257 | { | ||
258 | /* stolen from afs code */ | ||
259 | int err; | ||
260 | |||
261 | mntget(newmnt); | ||
262 | err = do_add_mount(newmnt, nd, nd->mnt->mnt_flags, mntlist); | ||
263 | switch (err) { | ||
264 | case 0: | ||
265 | dput(nd->dentry); | ||
266 | mntput(nd->mnt); | ||
267 | nd->mnt = newmnt; | ||
268 | nd->dentry = dget(newmnt->mnt_root); | ||
269 | break; | ||
270 | case -EBUSY: | ||
271 | /* someone else made a mount here whilst we were busy */ | ||
272 | while (d_mountpoint(nd->dentry) && | ||
273 | follow_down(&nd->mnt, &nd->dentry)) | ||
274 | ; | ||
275 | err = 0; | ||
276 | default: | ||
277 | mntput(newmnt); | ||
278 | break; | ||
279 | } | ||
280 | return err; | ||
281 | } | ||
282 | |||
283 | static void dump_referral(const struct dfs_info3_param *ref) | ||
284 | { | ||
285 | cFYI(1, ("DFS: ref path: %s", ref->path_name)); | ||
286 | cFYI(1, ("DFS: node path: %s", ref->node_name)); | ||
287 | cFYI(1, ("DFS: fl: %hd, srv_type: %hd", ref->flags, ref->server_type)); | ||
288 | cFYI(1, ("DFS: ref_flags: %hd, path_consumed: %hd", ref->ref_flag, | ||
289 | ref->PathConsumed)); | ||
290 | } | ||
291 | |||
292 | |||
293 | static void* | ||
294 | cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) | ||
295 | { | ||
296 | struct dfs_info3_param *referrals = NULL; | ||
297 | unsigned int num_referrals = 0; | ||
298 | struct cifs_sb_info *cifs_sb; | ||
299 | struct cifsSesInfo *ses; | ||
300 | char *full_path = NULL; | ||
301 | int xid, i; | ||
302 | int rc = 0; | ||
303 | struct vfsmount *mnt = ERR_PTR(-ENOENT); | ||
304 | |||
305 | cFYI(1, ("in %s", __FUNCTION__)); | ||
306 | BUG_ON(IS_ROOT(dentry)); | ||
307 | |||
308 | xid = GetXid(); | ||
309 | |||
310 | dput(nd->dentry); | ||
311 | nd->dentry = dget(dentry); | ||
312 | |||
313 | cifs_sb = CIFS_SB(dentry->d_inode->i_sb); | ||
314 | ses = cifs_sb->tcon->ses; | ||
315 | |||
316 | if (!ses) { | ||
317 | rc = -EINVAL; | ||
318 | goto out_err; | ||
319 | } | ||
320 | |||
321 | full_path = build_full_dfs_path_from_dentry(dentry); | ||
322 | if (full_path == NULL) { | ||
323 | rc = -ENOMEM; | ||
324 | goto out_err; | ||
325 | } | ||
326 | |||
327 | rc = get_dfs_path(xid, ses , full_path, cifs_sb->local_nls, | ||
328 | &num_referrals, &referrals, | ||
329 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
330 | |||
331 | for (i = 0; i < num_referrals; i++) { | ||
332 | dump_referral(referrals+i); | ||
333 | /* connect to a storage node */ | ||
334 | if (referrals[i].flags & DFSREF_STORAGE_SERVER) { | ||
335 | int len; | ||
336 | len = strlen(referrals[i].node_name); | ||
337 | if (len < 2) { | ||
338 | cERROR(1, ("%s: Net Address path too short: %s", | ||
339 | __FUNCTION__, referrals[i].node_name)); | ||
340 | rc = -EINVAL; | ||
341 | goto out_err; | ||
342 | } | ||
343 | mnt = cifs_dfs_do_refmount(nd->mnt, nd->dentry, | ||
344 | referrals[i].node_name); | ||
345 | cFYI(1, ("%s: cifs_dfs_do_refmount:%s , mnt:%p", | ||
346 | __FUNCTION__, | ||
347 | referrals[i].node_name, mnt)); | ||
348 | |||
349 | /* complete mount procedure if we accured submount */ | ||
350 | if (!IS_ERR(mnt)) | ||
351 | break; | ||
352 | } | ||
353 | } | ||
354 | |||
355 | /* we need it cause for() above could exit without valid submount */ | ||
356 | rc = PTR_ERR(mnt); | ||
357 | if (IS_ERR(mnt)) | ||
358 | goto out_err; | ||
359 | |||
360 | nd->mnt->mnt_flags |= MNT_SHRINKABLE; | ||
361 | rc = add_mount_helper(mnt, nd, &cifs_dfs_automount_list); | ||
362 | |||
363 | out: | ||
364 | FreeXid(xid); | ||
365 | free_dfs_info_array(referrals, num_referrals); | ||
366 | kfree(full_path); | ||
367 | cFYI(1, ("leaving %s" , __FUNCTION__)); | ||
368 | return ERR_PTR(rc); | ||
369 | out_err: | ||
370 | path_release(nd); | ||
371 | goto out; | ||
372 | } | ||
373 | |||
374 | struct inode_operations cifs_dfs_referral_inode_operations = { | ||
375 | .follow_link = cifs_dfs_follow_mountpoint, | ||
376 | }; | ||
377 | |||
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index 34af556cdd8d..8ad2330ba061 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h | |||
@@ -43,6 +43,9 @@ struct cifs_sb_info { | |||
43 | mode_t mnt_dir_mode; | 43 | mode_t mnt_dir_mode; |
44 | int mnt_cifs_flags; | 44 | int mnt_cifs_flags; |
45 | int prepathlen; | 45 | int prepathlen; |
46 | char *prepath; | 46 | char *prepath; /* relative path under the share to mount to */ |
47 | #ifdef CONFIG_CIFS_DFS_UPCALL | ||
48 | char *mountdata; /* mount options received at mount time */ | ||
49 | #endif | ||
47 | }; | 50 | }; |
48 | #endif /* _CIFS_FS_SB_H */ | 51 | #endif /* _CIFS_FS_SB_H */ |
diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c index 1529d2b12e9c..d543accc10dd 100644 --- a/fs/cifs/cifs_spnego.c +++ b/fs/cifs/cifs_spnego.c | |||
@@ -122,11 +122,13 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo) | |||
122 | cFYI(1, ("key description = %s", description)); | 122 | cFYI(1, ("key description = %s", description)); |
123 | spnego_key = request_key(&cifs_spnego_key_type, description, ""); | 123 | spnego_key = request_key(&cifs_spnego_key_type, description, ""); |
124 | 124 | ||
125 | #ifdef CONFIG_CIFS_DEBUG2 | ||
125 | if (cifsFYI && !IS_ERR(spnego_key)) { | 126 | if (cifsFYI && !IS_ERR(spnego_key)) { |
126 | struct cifs_spnego_msg *msg = spnego_key->payload.data; | 127 | struct cifs_spnego_msg *msg = spnego_key->payload.data; |
127 | cifs_dump_mem("SPNEGO reply blob:", msg->data, | 128 | cifs_dump_mem("SPNEGO reply blob:", msg->data, min(1024, |
128 | msg->secblob_len + msg->sesskey_len); | 129 | msg->secblob_len + msg->sesskey_len)); |
129 | } | 130 | } |
131 | #endif /* CONFIG_CIFS_DEBUG2 */ | ||
130 | 132 | ||
131 | out: | 133 | out: |
132 | kfree(description); | 134 | kfree(description); |
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index c312adcba4fc..a7035bd18e4e 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c | |||
@@ -129,6 +129,54 @@ int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid) | |||
129 | return (1); /* sids compare/match */ | 129 | return (1); /* sids compare/match */ |
130 | } | 130 | } |
131 | 131 | ||
132 | |||
133 | /* copy ntsd, owner sid, and group sid from a security descriptor to another */ | ||
134 | static void copy_sec_desc(const struct cifs_ntsd *pntsd, | ||
135 | struct cifs_ntsd *pnntsd, __u32 sidsoffset) | ||
136 | { | ||
137 | int i; | ||
138 | |||
139 | struct cifs_sid *owner_sid_ptr, *group_sid_ptr; | ||
140 | struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr; | ||
141 | |||
142 | /* copy security descriptor control portion */ | ||
143 | pnntsd->revision = pntsd->revision; | ||
144 | pnntsd->type = pntsd->type; | ||
145 | pnntsd->dacloffset = cpu_to_le32(sizeof(struct cifs_ntsd)); | ||
146 | pnntsd->sacloffset = 0; | ||
147 | pnntsd->osidoffset = cpu_to_le32(sidsoffset); | ||
148 | pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct cifs_sid)); | ||
149 | |||
150 | /* copy owner sid */ | ||
151 | owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + | ||
152 | le32_to_cpu(pntsd->osidoffset)); | ||
153 | nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset); | ||
154 | |||
155 | nowner_sid_ptr->revision = owner_sid_ptr->revision; | ||
156 | nowner_sid_ptr->num_subauth = owner_sid_ptr->num_subauth; | ||
157 | for (i = 0; i < 6; i++) | ||
158 | nowner_sid_ptr->authority[i] = owner_sid_ptr->authority[i]; | ||
159 | for (i = 0; i < 5; i++) | ||
160 | nowner_sid_ptr->sub_auth[i] = owner_sid_ptr->sub_auth[i]; | ||
161 | |||
162 | /* copy group sid */ | ||
163 | group_sid_ptr = (struct cifs_sid *)((char *)pntsd + | ||
164 | le32_to_cpu(pntsd->gsidoffset)); | ||
165 | ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset + | ||
166 | sizeof(struct cifs_sid)); | ||
167 | |||
168 | ngroup_sid_ptr->revision = group_sid_ptr->revision; | ||
169 | ngroup_sid_ptr->num_subauth = group_sid_ptr->num_subauth; | ||
170 | for (i = 0; i < 6; i++) | ||
171 | ngroup_sid_ptr->authority[i] = group_sid_ptr->authority[i]; | ||
172 | for (i = 0; i < 5; i++) | ||
173 | ngroup_sid_ptr->sub_auth[i] = | ||
174 | cpu_to_le32(group_sid_ptr->sub_auth[i]); | ||
175 | |||
176 | return; | ||
177 | } | ||
178 | |||
179 | |||
132 | /* | 180 | /* |
133 | change posix mode to reflect permissions | 181 | change posix mode to reflect permissions |
134 | pmode is the existing mode (we only want to overwrite part of this | 182 | pmode is the existing mode (we only want to overwrite part of this |
@@ -220,6 +268,33 @@ static void mode_to_access_flags(umode_t mode, umode_t bits_to_use, | |||
220 | return; | 268 | return; |
221 | } | 269 | } |
222 | 270 | ||
271 | static __le16 fill_ace_for_sid(struct cifs_ace *pntace, | ||
272 | const struct cifs_sid *psid, __u64 nmode, umode_t bits) | ||
273 | { | ||
274 | int i; | ||
275 | __u16 size = 0; | ||
276 | __u32 access_req = 0; | ||
277 | |||
278 | pntace->type = ACCESS_ALLOWED; | ||
279 | pntace->flags = 0x0; | ||
280 | mode_to_access_flags(nmode, bits, &access_req); | ||
281 | if (!access_req) | ||
282 | access_req = SET_MINIMUM_RIGHTS; | ||
283 | pntace->access_req = cpu_to_le32(access_req); | ||
284 | |||
285 | pntace->sid.revision = psid->revision; | ||
286 | pntace->sid.num_subauth = psid->num_subauth; | ||
287 | for (i = 0; i < 6; i++) | ||
288 | pntace->sid.authority[i] = psid->authority[i]; | ||
289 | for (i = 0; i < psid->num_subauth; i++) | ||
290 | pntace->sid.sub_auth[i] = psid->sub_auth[i]; | ||
291 | |||
292 | size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4); | ||
293 | pntace->size = cpu_to_le16(size); | ||
294 | |||
295 | return (size); | ||
296 | } | ||
297 | |||
223 | 298 | ||
224 | #ifdef CONFIG_CIFS_DEBUG2 | 299 | #ifdef CONFIG_CIFS_DEBUG2 |
225 | static void dump_ace(struct cifs_ace *pace, char *end_of_acl) | 300 | static void dump_ace(struct cifs_ace *pace, char *end_of_acl) |
@@ -243,7 +318,7 @@ static void dump_ace(struct cifs_ace *pace, char *end_of_acl) | |||
243 | int i; | 318 | int i; |
244 | cFYI(1, ("ACE revision %d num_auth %d type %d flags %d size %d", | 319 | cFYI(1, ("ACE revision %d num_auth %d type %d flags %d size %d", |
245 | pace->sid.revision, pace->sid.num_subauth, pace->type, | 320 | pace->sid.revision, pace->sid.num_subauth, pace->type, |
246 | pace->flags, pace->size)); | 321 | pace->flags, le16_to_cpu(pace->size))); |
247 | for (i = 0; i < num_subauth; ++i) { | 322 | for (i = 0; i < num_subauth; ++i) { |
248 | cFYI(1, ("ACE sub_auth[%d]: 0x%x", i, | 323 | cFYI(1, ("ACE sub_auth[%d]: 0x%x", i, |
249 | le32_to_cpu(pace->sid.sub_auth[i]))); | 324 | le32_to_cpu(pace->sid.sub_auth[i]))); |
@@ -346,6 +421,28 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, | |||
346 | } | 421 | } |
347 | 422 | ||
348 | 423 | ||
424 | static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid, | ||
425 | struct cifs_sid *pgrpsid, __u64 nmode) | ||
426 | { | ||
427 | __le16 size = 0; | ||
428 | struct cifs_acl *pnndacl; | ||
429 | |||
430 | pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl)); | ||
431 | |||
432 | size += fill_ace_for_sid((struct cifs_ace *) ((char *)pnndacl + size), | ||
433 | pownersid, nmode, S_IRWXU); | ||
434 | size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size), | ||
435 | pgrpsid, nmode, S_IRWXG); | ||
436 | size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size), | ||
437 | &sid_everyone, nmode, S_IRWXO); | ||
438 | |||
439 | pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl)); | ||
440 | pndacl->num_aces = 3; | ||
441 | |||
442 | return (0); | ||
443 | } | ||
444 | |||
445 | |||
349 | static int parse_sid(struct cifs_sid *psid, char *end_of_acl) | 446 | static int parse_sid(struct cifs_sid *psid, char *end_of_acl) |
350 | { | 447 | { |
351 | /* BB need to add parm so we can store the SID BB */ | 448 | /* BB need to add parm so we can store the SID BB */ |
@@ -432,6 +529,46 @@ static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len, | |||
432 | } | 529 | } |
433 | 530 | ||
434 | 531 | ||
532 | /* Convert permission bits from mode to equivalent CIFS ACL */ | ||
533 | static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, | ||
534 | int acl_len, struct inode *inode, __u64 nmode) | ||
535 | { | ||
536 | int rc = 0; | ||
537 | __u32 dacloffset; | ||
538 | __u32 ndacloffset; | ||
539 | __u32 sidsoffset; | ||
540 | struct cifs_sid *owner_sid_ptr, *group_sid_ptr; | ||
541 | struct cifs_acl *dacl_ptr = NULL; /* no need for SACL ptr */ | ||
542 | struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */ | ||
543 | |||
544 | if ((inode == NULL) || (pntsd == NULL) || (pnntsd == NULL)) | ||
545 | return (-EIO); | ||
546 | |||
547 | owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + | ||
548 | le32_to_cpu(pntsd->osidoffset)); | ||
549 | group_sid_ptr = (struct cifs_sid *)((char *)pntsd + | ||
550 | le32_to_cpu(pntsd->gsidoffset)); | ||
551 | |||
552 | dacloffset = le32_to_cpu(pntsd->dacloffset); | ||
553 | dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset); | ||
554 | |||
555 | ndacloffset = sizeof(struct cifs_ntsd); | ||
556 | ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset); | ||
557 | ndacl_ptr->revision = dacl_ptr->revision; | ||
558 | ndacl_ptr->size = 0; | ||
559 | ndacl_ptr->num_aces = 0; | ||
560 | |||
561 | rc = set_chmod_dacl(ndacl_ptr, owner_sid_ptr, group_sid_ptr, nmode); | ||
562 | |||
563 | sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size); | ||
564 | |||
565 | /* copy security descriptor control portion and owner and group sid */ | ||
566 | copy_sec_desc(pntsd, pnntsd, sidsoffset); | ||
567 | |||
568 | return (rc); | ||
569 | } | ||
570 | |||
571 | |||
435 | /* Retrieve an ACL from the server */ | 572 | /* Retrieve an ACL from the server */ |
436 | static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode, | 573 | static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode, |
437 | const char *path) | 574 | const char *path) |
@@ -487,6 +624,64 @@ static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode, | |||
487 | return pntsd; | 624 | return pntsd; |
488 | } | 625 | } |
489 | 626 | ||
627 | /* Set an ACL on the server */ | ||
628 | static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, | ||
629 | struct inode *inode, const char *path) | ||
630 | { | ||
631 | struct cifsFileInfo *open_file; | ||
632 | int unlock_file = FALSE; | ||
633 | int xid; | ||
634 | int rc = -EIO; | ||
635 | __u16 fid; | ||
636 | struct super_block *sb; | ||
637 | struct cifs_sb_info *cifs_sb; | ||
638 | |||
639 | #ifdef CONFIG_CIFS_DEBUG2 | ||
640 | cFYI(1, ("set ACL for %s from mode 0x%x", path, inode->i_mode)); | ||
641 | #endif | ||
642 | |||
643 | if (!inode) | ||
644 | return (rc); | ||
645 | |||
646 | sb = inode->i_sb; | ||
647 | if (sb == NULL) | ||
648 | return (rc); | ||
649 | |||
650 | cifs_sb = CIFS_SB(sb); | ||
651 | xid = GetXid(); | ||
652 | |||
653 | open_file = find_readable_file(CIFS_I(inode)); | ||
654 | if (open_file) { | ||
655 | unlock_file = TRUE; | ||
656 | fid = open_file->netfid; | ||
657 | } else { | ||
658 | int oplock = FALSE; | ||
659 | /* open file */ | ||
660 | rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, | ||
661 | WRITE_DAC, 0, &fid, &oplock, NULL, | ||
662 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & | ||
663 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
664 | if (rc != 0) { | ||
665 | cERROR(1, ("Unable to open file to set ACL")); | ||
666 | FreeXid(xid); | ||
667 | return (rc); | ||
668 | } | ||
669 | } | ||
670 | |||
671 | rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen); | ||
672 | #ifdef CONFIG_CIFS_DEBUG2 | ||
673 | cFYI(1, ("SetCIFSACL rc = %d", rc)); | ||
674 | #endif | ||
675 | if (unlock_file == TRUE) | ||
676 | atomic_dec(&open_file->wrtPending); | ||
677 | else | ||
678 | CIFSSMBClose(xid, cifs_sb->tcon, fid); | ||
679 | |||
680 | FreeXid(xid); | ||
681 | |||
682 | return (rc); | ||
683 | } | ||
684 | |||
490 | /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */ | 685 | /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */ |
491 | void acl_to_uid_mode(struct inode *inode, const char *path) | 686 | void acl_to_uid_mode(struct inode *inode, const char *path) |
492 | { | 687 | { |
@@ -510,24 +705,53 @@ void acl_to_uid_mode(struct inode *inode, const char *path) | |||
510 | } | 705 | } |
511 | 706 | ||
512 | /* Convert mode bits to an ACL so we can update the ACL on the server */ | 707 | /* Convert mode bits to an ACL so we can update the ACL on the server */ |
513 | int mode_to_acl(struct inode *inode, const char *path) | 708 | int mode_to_acl(struct inode *inode, const char *path, __u64 nmode) |
514 | { | 709 | { |
515 | int rc = 0; | 710 | int rc = 0; |
516 | __u32 acllen = 0; | 711 | __u32 acllen = 0; |
517 | struct cifs_ntsd *pntsd = NULL; | 712 | struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */ |
713 | struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */ | ||
518 | 714 | ||
715 | #ifdef CONFIG_CIFS_DEBUG2 | ||
519 | cFYI(1, ("set ACL from mode for %s", path)); | 716 | cFYI(1, ("set ACL from mode for %s", path)); |
717 | #endif | ||
520 | 718 | ||
521 | /* Get the security descriptor */ | 719 | /* Get the security descriptor */ |
522 | pntsd = get_cifs_acl(&acllen, inode, path); | 720 | pntsd = get_cifs_acl(&acllen, inode, path); |
523 | 721 | ||
524 | /* Add/Modify the three ACEs for owner, group, everyone | 722 | /* Add three ACEs for owner, group, everyone getting rid of |
525 | while retaining the other ACEs */ | 723 | other ACEs as chmod disables ACEs and set the security descriptor */ |
526 | 724 | ||
527 | /* Set the security descriptor */ | 725 | if (pntsd) { |
726 | /* allocate memory for the smb header, | ||
727 | set security descriptor request security descriptor | ||
728 | parameters, and secuirty descriptor itself */ | ||
528 | 729 | ||
730 | pnntsd = kmalloc(acllen, GFP_KERNEL); | ||
731 | if (!pnntsd) { | ||
732 | cERROR(1, ("Unable to allocate security descriptor")); | ||
733 | kfree(pntsd); | ||
734 | return (-ENOMEM); | ||
735 | } | ||
529 | 736 | ||
530 | kfree(pntsd); | 737 | rc = build_sec_desc(pntsd, pnntsd, acllen, inode, nmode); |
531 | return rc; | 738 | |
739 | #ifdef CONFIG_CIFS_DEBUG2 | ||
740 | cFYI(1, ("build_sec_desc rc: %d", rc)); | ||
741 | #endif | ||
742 | |||
743 | if (!rc) { | ||
744 | /* Set the security descriptor */ | ||
745 | rc = set_cifs_acl(pnntsd, acllen, inode, path); | ||
746 | #ifdef CONFIG_CIFS_DEBUG2 | ||
747 | cFYI(1, ("set_cifs_acl rc: %d", rc)); | ||
748 | #endif | ||
749 | } | ||
750 | |||
751 | kfree(pnntsd); | ||
752 | kfree(pntsd); | ||
753 | } | ||
754 | |||
755 | return (rc); | ||
532 | } | 756 | } |
533 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | 757 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 093beaa3900d..e9f4ec701092 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include "cifs_fs_sb.h" | 44 | #include "cifs_fs_sb.h" |
45 | #include <linux/mm.h> | 45 | #include <linux/mm.h> |
46 | #include <linux/key-type.h> | 46 | #include <linux/key-type.h> |
47 | #include "dns_resolve.h" | ||
47 | #include "cifs_spnego.h" | 48 | #include "cifs_spnego.h" |
48 | #define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDUs */ | 49 | #define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDUs */ |
49 | 50 | ||
@@ -96,6 +97,9 @@ cifs_read_super(struct super_block *sb, void *data, | |||
96 | { | 97 | { |
97 | struct inode *inode; | 98 | struct inode *inode; |
98 | struct cifs_sb_info *cifs_sb; | 99 | struct cifs_sb_info *cifs_sb; |
100 | #ifdef CONFIG_CIFS_DFS_UPCALL | ||
101 | int len; | ||
102 | #endif | ||
99 | int rc = 0; | 103 | int rc = 0; |
100 | 104 | ||
101 | /* BB should we make this contingent on mount parm? */ | 105 | /* BB should we make this contingent on mount parm? */ |
@@ -105,6 +109,25 @@ cifs_read_super(struct super_block *sb, void *data, | |||
105 | if (cifs_sb == NULL) | 109 | if (cifs_sb == NULL) |
106 | return -ENOMEM; | 110 | return -ENOMEM; |
107 | 111 | ||
112 | #ifdef CONFIG_CIFS_DFS_UPCALL | ||
113 | /* copy mount params to sb for use in submounts */ | ||
114 | /* BB: should we move this after the mount so we | ||
115 | * do not have to do the copy on failed mounts? | ||
116 | * BB: May be it is better to do simple copy before | ||
117 | * complex operation (mount), and in case of fail | ||
118 | * just exit instead of doing mount and attempting | ||
119 | * undo it if this copy fails?*/ | ||
120 | len = strlen(data); | ||
121 | cifs_sb->mountdata = kzalloc(len + 1, GFP_KERNEL); | ||
122 | if (cifs_sb->mountdata == NULL) { | ||
123 | kfree(sb->s_fs_info); | ||
124 | sb->s_fs_info = NULL; | ||
125 | return -ENOMEM; | ||
126 | } | ||
127 | strncpy(cifs_sb->mountdata, data, len + 1); | ||
128 | cifs_sb->mountdata[len] = '\0'; | ||
129 | #endif | ||
130 | |||
108 | rc = cifs_mount(sb, cifs_sb, data, devname); | 131 | rc = cifs_mount(sb, cifs_sb, data, devname); |
109 | 132 | ||
110 | if (rc) { | 133 | if (rc) { |
@@ -154,6 +177,12 @@ out_no_root: | |||
154 | 177 | ||
155 | out_mount_failed: | 178 | out_mount_failed: |
156 | if (cifs_sb) { | 179 | if (cifs_sb) { |
180 | #ifdef CONFIG_CIFS_DFS_UPCALL | ||
181 | if (cifs_sb->mountdata) { | ||
182 | kfree(cifs_sb->mountdata); | ||
183 | cifs_sb->mountdata = NULL; | ||
184 | } | ||
185 | #endif | ||
157 | if (cifs_sb->local_nls) | 186 | if (cifs_sb->local_nls) |
158 | unload_nls(cifs_sb->local_nls); | 187 | unload_nls(cifs_sb->local_nls); |
159 | kfree(cifs_sb); | 188 | kfree(cifs_sb); |
@@ -177,6 +206,13 @@ cifs_put_super(struct super_block *sb) | |||
177 | if (rc) { | 206 | if (rc) { |
178 | cERROR(1, ("cifs_umount failed with return code %d", rc)); | 207 | cERROR(1, ("cifs_umount failed with return code %d", rc)); |
179 | } | 208 | } |
209 | #ifdef CONFIG_CIFS_DFS_UPCALL | ||
210 | if (cifs_sb->mountdata) { | ||
211 | kfree(cifs_sb->mountdata); | ||
212 | cifs_sb->mountdata = NULL; | ||
213 | } | ||
214 | #endif | ||
215 | |||
180 | unload_nls(cifs_sb->local_nls); | 216 | unload_nls(cifs_sb->local_nls); |
181 | kfree(cifs_sb); | 217 | kfree(cifs_sb); |
182 | return; | 218 | return; |
@@ -435,6 +471,10 @@ static void cifs_umount_begin(struct vfsmount *vfsmnt, int flags) | |||
435 | struct cifs_sb_info *cifs_sb; | 471 | struct cifs_sb_info *cifs_sb; |
436 | struct cifsTconInfo *tcon; | 472 | struct cifsTconInfo *tcon; |
437 | 473 | ||
474 | #ifdef CONFIG_CIFS_DFS_UPCALL | ||
475 | dfs_shrink_umount_helper(vfsmnt); | ||
476 | #endif /* CONFIG CIFS_DFS_UPCALL */ | ||
477 | |||
438 | if (!(flags & MNT_FORCE)) | 478 | if (!(flags & MNT_FORCE)) |
439 | return; | 479 | return; |
440 | cifs_sb = CIFS_SB(vfsmnt->mnt_sb); | 480 | cifs_sb = CIFS_SB(vfsmnt->mnt_sb); |
@@ -552,7 +592,7 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int origin) | |||
552 | return remote_llseek(file, offset, origin); | 592 | return remote_llseek(file, offset, origin); |
553 | } | 593 | } |
554 | 594 | ||
555 | static struct file_system_type cifs_fs_type = { | 595 | struct file_system_type cifs_fs_type = { |
556 | .owner = THIS_MODULE, | 596 | .owner = THIS_MODULE, |
557 | .name = "cifs", | 597 | .name = "cifs", |
558 | .get_sb = cifs_get_sb, | 598 | .get_sb = cifs_get_sb, |
@@ -1015,11 +1055,16 @@ init_cifs(void) | |||
1015 | if (rc) | 1055 | if (rc) |
1016 | goto out_unregister_filesystem; | 1056 | goto out_unregister_filesystem; |
1017 | #endif | 1057 | #endif |
1058 | #ifdef CONFIG_CIFS_DFS_UPCALL | ||
1059 | rc = register_key_type(&key_type_dns_resolver); | ||
1060 | if (rc) | ||
1061 | goto out_unregister_key_type; | ||
1062 | #endif | ||
1018 | oplockThread = kthread_run(cifs_oplock_thread, NULL, "cifsoplockd"); | 1063 | oplockThread = kthread_run(cifs_oplock_thread, NULL, "cifsoplockd"); |
1019 | if (IS_ERR(oplockThread)) { | 1064 | if (IS_ERR(oplockThread)) { |
1020 | rc = PTR_ERR(oplockThread); | 1065 | rc = PTR_ERR(oplockThread); |
1021 | cERROR(1, ("error %d create oplock thread", rc)); | 1066 | cERROR(1, ("error %d create oplock thread", rc)); |
1022 | goto out_unregister_key_type; | 1067 | goto out_unregister_dfs_key_type; |
1023 | } | 1068 | } |
1024 | 1069 | ||
1025 | dnotifyThread = kthread_run(cifs_dnotify_thread, NULL, "cifsdnotifyd"); | 1070 | dnotifyThread = kthread_run(cifs_dnotify_thread, NULL, "cifsdnotifyd"); |
@@ -1033,7 +1078,11 @@ init_cifs(void) | |||
1033 | 1078 | ||
1034 | out_stop_oplock_thread: | 1079 | out_stop_oplock_thread: |
1035 | kthread_stop(oplockThread); | 1080 | kthread_stop(oplockThread); |
1081 | out_unregister_dfs_key_type: | ||
1082 | #ifdef CONFIG_CIFS_DFS_UPCALL | ||
1083 | unregister_key_type(&key_type_dns_resolver); | ||
1036 | out_unregister_key_type: | 1084 | out_unregister_key_type: |
1085 | #endif | ||
1037 | #ifdef CONFIG_CIFS_UPCALL | 1086 | #ifdef CONFIG_CIFS_UPCALL |
1038 | unregister_key_type(&cifs_spnego_key_type); | 1087 | unregister_key_type(&cifs_spnego_key_type); |
1039 | out_unregister_filesystem: | 1088 | out_unregister_filesystem: |
@@ -1059,6 +1108,9 @@ exit_cifs(void) | |||
1059 | #ifdef CONFIG_PROC_FS | 1108 | #ifdef CONFIG_PROC_FS |
1060 | cifs_proc_clean(); | 1109 | cifs_proc_clean(); |
1061 | #endif | 1110 | #endif |
1111 | #ifdef CONFIG_CIFS_DFS_UPCALL | ||
1112 | unregister_key_type(&key_type_dns_resolver); | ||
1113 | #endif | ||
1062 | #ifdef CONFIG_CIFS_UPCALL | 1114 | #ifdef CONFIG_CIFS_UPCALL |
1063 | unregister_key_type(&cifs_spnego_key_type); | 1115 | unregister_key_type(&cifs_spnego_key_type); |
1064 | #endif | 1116 | #endif |
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 2a21dc66f0de..195b14de5567 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
@@ -32,6 +32,7 @@ | |||
32 | #define TRUE 1 | 32 | #define TRUE 1 |
33 | #endif | 33 | #endif |
34 | 34 | ||
35 | extern struct file_system_type cifs_fs_type; | ||
35 | extern const struct address_space_operations cifs_addr_ops; | 36 | extern const struct address_space_operations cifs_addr_ops; |
36 | extern const struct address_space_operations cifs_addr_ops_smallbuf; | 37 | extern const struct address_space_operations cifs_addr_ops_smallbuf; |
37 | 38 | ||
@@ -60,6 +61,10 @@ extern int cifs_setattr(struct dentry *, struct iattr *); | |||
60 | 61 | ||
61 | extern const struct inode_operations cifs_file_inode_ops; | 62 | extern const struct inode_operations cifs_file_inode_ops; |
62 | extern const struct inode_operations cifs_symlink_inode_ops; | 63 | extern const struct inode_operations cifs_symlink_inode_ops; |
64 | extern struct list_head cifs_dfs_automount_list; | ||
65 | extern struct inode_operations cifs_dfs_referral_inode_operations; | ||
66 | |||
67 | |||
63 | 68 | ||
64 | /* Functions related to files and directories */ | 69 | /* Functions related to files and directories */ |
65 | extern const struct file_operations cifs_file_ops; | 70 | extern const struct file_operations cifs_file_ops; |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 1fde2197ad76..5d32d8ddc82e 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * fs/cifs/cifsglob.h | 2 | * fs/cifs/cifsglob.h |
3 | * | 3 | * |
4 | * Copyright (C) International Business Machines Corp., 2002,2007 | 4 | * Copyright (C) International Business Machines Corp., 2002,2008 |
5 | * Author(s): Steve French (sfrench@us.ibm.com) | 5 | * Author(s): Steve French (sfrench@us.ibm.com) |
6 | * Jeremy Allison (jra@samba.org) | 6 | * Jeremy Allison (jra@samba.org) |
7 | * | 7 | * |
@@ -70,14 +70,6 @@ | |||
70 | #endif | 70 | #endif |
71 | 71 | ||
72 | /* | 72 | /* |
73 | * This information is kept on every Server we know about. | ||
74 | * | ||
75 | * Some things to note: | ||
76 | * | ||
77 | */ | ||
78 | #define SERVER_NAME_LEN_WITH_NULL (SERVER_NAME_LENGTH + 1) | ||
79 | |||
80 | /* | ||
81 | * CIFS vfs client Status information (based on what we know.) | 73 | * CIFS vfs client Status information (based on what we know.) |
82 | */ | 74 | */ |
83 | 75 | ||
@@ -460,6 +452,37 @@ struct dir_notify_req { | |||
460 | struct file *pfile; | 452 | struct file *pfile; |
461 | }; | 453 | }; |
462 | 454 | ||
455 | struct dfs_info3_param { | ||
456 | int flags; /* DFSREF_REFERRAL_SERVER, DFSREF_STORAGE_SERVER*/ | ||
457 | int PathConsumed; | ||
458 | int server_type; | ||
459 | int ref_flag; | ||
460 | char *path_name; | ||
461 | char *node_name; | ||
462 | }; | ||
463 | |||
464 | static inline void free_dfs_info_param(struct dfs_info3_param *param) | ||
465 | { | ||
466 | if (param) { | ||
467 | kfree(param->path_name); | ||
468 | kfree(param->node_name); | ||
469 | kfree(param); | ||
470 | } | ||
471 | } | ||
472 | |||
473 | static inline void free_dfs_info_array(struct dfs_info3_param *param, | ||
474 | int number_of_items) | ||
475 | { | ||
476 | int i; | ||
477 | if ((number_of_items == 0) || (param == NULL)) | ||
478 | return; | ||
479 | for (i = 0; i < number_of_items; i++) { | ||
480 | kfree(param[i].path_name); | ||
481 | kfree(param[i].node_name); | ||
482 | } | ||
483 | kfree(param); | ||
484 | } | ||
485 | |||
463 | #define MID_FREE 0 | 486 | #define MID_FREE 0 |
464 | #define MID_REQUEST_ALLOCATED 1 | 487 | #define MID_REQUEST_ALLOCATED 1 |
465 | #define MID_REQUEST_SUBMITTED 2 | 488 | #define MID_REQUEST_SUBMITTED 2 |
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index dbe6b846f37f..47f79504f57b 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h | |||
@@ -237,6 +237,9 @@ | |||
237 | | DELETE | READ_CONTROL | WRITE_DAC \ | 237 | | DELETE | READ_CONTROL | WRITE_DAC \ |
238 | | WRITE_OWNER | SYNCHRONIZE) | 238 | | WRITE_OWNER | SYNCHRONIZE) |
239 | 239 | ||
240 | #define SET_MINIMUM_RIGHTS (FILE_READ_EA | FILE_READ_ATTRIBUTES \ | ||
241 | | READ_CONTROL | SYNCHRONIZE) | ||
242 | |||
240 | 243 | ||
241 | /* | 244 | /* |
242 | * Invalid readdir handle | 245 | * Invalid readdir handle |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 8350eec49663..2f09f565a3d9 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * fs/cifs/cifsproto.h | 2 | * fs/cifs/cifsproto.h |
3 | * | 3 | * |
4 | * Copyright (c) International Business Machines Corp., 2002,2007 | 4 | * Copyright (c) International Business Machines Corp., 2002,2008 |
5 | * Author(s): Steve French (sfrench@us.ibm.com) | 5 | * Author(s): Steve French (sfrench@us.ibm.com) |
6 | * | 6 | * |
7 | * This library is free software; you can redistribute it and/or modify | 7 | * This library is free software; you can redistribute it and/or modify |
@@ -97,11 +97,14 @@ extern int cifs_get_inode_info_unix(struct inode **pinode, | |||
97 | const unsigned char *search_path, | 97 | const unsigned char *search_path, |
98 | struct super_block *sb, int xid); | 98 | struct super_block *sb, int xid); |
99 | extern void acl_to_uid_mode(struct inode *inode, const char *search_path); | 99 | extern void acl_to_uid_mode(struct inode *inode, const char *search_path); |
100 | extern int mode_to_acl(struct inode *inode, const char *path); | 100 | extern int mode_to_acl(struct inode *inode, const char *path, __u64); |
101 | 101 | ||
102 | extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *, | 102 | extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *, |
103 | const char *); | 103 | const char *); |
104 | extern int cifs_umount(struct super_block *, struct cifs_sb_info *); | 104 | extern int cifs_umount(struct super_block *, struct cifs_sb_info *); |
105 | #ifdef CONFIG_CIFS_DFS_UPCALL | ||
106 | extern void dfs_shrink_umount_helper(struct vfsmount *vfsmnt); | ||
107 | #endif | ||
105 | void cifs_proc_init(void); | 108 | void cifs_proc_init(void); |
106 | void cifs_proc_clean(void); | 109 | void cifs_proc_clean(void); |
107 | 110 | ||
@@ -153,7 +156,7 @@ extern int get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, | |||
153 | const char *old_path, | 156 | const char *old_path, |
154 | const struct nls_table *nls_codepage, | 157 | const struct nls_table *nls_codepage, |
155 | unsigned int *pnum_referrals, | 158 | unsigned int *pnum_referrals, |
156 | unsigned char **preferrals, | 159 | struct dfs_info3_param **preferrals, |
157 | int remap); | 160 | int remap); |
158 | extern void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, | 161 | extern void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, |
159 | struct super_block *sb, struct smb_vol *vol); | 162 | struct super_block *sb, struct smb_vol *vol); |
@@ -342,6 +345,8 @@ extern int CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, | |||
342 | const struct nls_table *nls_codepage, int remap_special_chars); | 345 | const struct nls_table *nls_codepage, int remap_special_chars); |
343 | extern int CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, | 346 | extern int CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, |
344 | __u16 fid, struct cifs_ntsd **acl_inf, __u32 *buflen); | 347 | __u16 fid, struct cifs_ntsd **acl_inf, __u32 *buflen); |
348 | extern int CIFSSMBSetCIFSACL(const int, struct cifsTconInfo *, __u16, | ||
349 | struct cifs_ntsd *, __u32); | ||
345 | extern int CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon, | 350 | extern int CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon, |
346 | const unsigned char *searchName, | 351 | const unsigned char *searchName, |
347 | char *acl_inf, const int buflen, const int acl_type, | 352 | char *acl_inf, const int buflen, const int acl_type, |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 9e8a6bef029a..9409524e4bf8 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -3156,6 +3156,71 @@ qsec_out: | |||
3156 | /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */ | 3156 | /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */ |
3157 | return rc; | 3157 | return rc; |
3158 | } | 3158 | } |
3159 | |||
3160 | int | ||
3161 | CIFSSMBSetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, | ||
3162 | struct cifs_ntsd *pntsd, __u32 acllen) | ||
3163 | { | ||
3164 | __u16 byte_count, param_count, data_count, param_offset, data_offset; | ||
3165 | int rc = 0; | ||
3166 | int bytes_returned = 0; | ||
3167 | SET_SEC_DESC_REQ *pSMB = NULL; | ||
3168 | NTRANSACT_RSP *pSMBr = NULL; | ||
3169 | |||
3170 | setCifsAclRetry: | ||
3171 | rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, | ||
3172 | (void **) &pSMBr); | ||
3173 | if (rc) | ||
3174 | return (rc); | ||
3175 | |||
3176 | pSMB->MaxSetupCount = 0; | ||
3177 | pSMB->Reserved = 0; | ||
3178 | |||
3179 | param_count = 8; | ||
3180 | param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4; | ||
3181 | data_count = acllen; | ||
3182 | data_offset = param_offset + param_count; | ||
3183 | byte_count = 3 /* pad */ + param_count; | ||
3184 | |||
3185 | pSMB->DataCount = cpu_to_le32(data_count); | ||
3186 | pSMB->TotalDataCount = pSMB->DataCount; | ||
3187 | pSMB->MaxParameterCount = cpu_to_le32(4); | ||
3188 | pSMB->MaxDataCount = cpu_to_le32(16384); | ||
3189 | pSMB->ParameterCount = cpu_to_le32(param_count); | ||
3190 | pSMB->ParameterOffset = cpu_to_le32(param_offset); | ||
3191 | pSMB->TotalParameterCount = pSMB->ParameterCount; | ||
3192 | pSMB->DataOffset = cpu_to_le32(data_offset); | ||
3193 | pSMB->SetupCount = 0; | ||
3194 | pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC); | ||
3195 | pSMB->ByteCount = cpu_to_le16(byte_count+data_count); | ||
3196 | |||
3197 | pSMB->Fid = fid; /* file handle always le */ | ||
3198 | pSMB->Reserved2 = 0; | ||
3199 | pSMB->AclFlags = cpu_to_le32(CIFS_ACL_DACL); | ||
3200 | |||
3201 | if (pntsd && acllen) { | ||
3202 | memcpy((char *) &pSMBr->hdr.Protocol + data_offset, | ||
3203 | (char *) pntsd, | ||
3204 | acllen); | ||
3205 | pSMB->hdr.smb_buf_length += (byte_count + data_count); | ||
3206 | |||
3207 | } else | ||
3208 | pSMB->hdr.smb_buf_length += byte_count; | ||
3209 | |||
3210 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, | ||
3211 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | ||
3212 | |||
3213 | cFYI(1, ("SetCIFSACL bytes_returned: %d, rc: %d", bytes_returned, rc)); | ||
3214 | if (rc) | ||
3215 | cFYI(1, ("Set CIFS ACL returned %d", rc)); | ||
3216 | cifs_buf_release(pSMB); | ||
3217 | |||
3218 | if (rc == -EAGAIN) | ||
3219 | goto setCifsAclRetry; | ||
3220 | |||
3221 | return (rc); | ||
3222 | } | ||
3223 | |||
3159 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | 3224 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ |
3160 | 3225 | ||
3161 | /* Legacy Query Path Information call for lookup to old servers such | 3226 | /* Legacy Query Path Information call for lookup to old servers such |
@@ -5499,7 +5564,7 @@ SetEARetry: | |||
5499 | else | 5564 | else |
5500 | name_len = strnlen(ea_name, 255); | 5565 | name_len = strnlen(ea_name, 255); |
5501 | 5566 | ||
5502 | count = sizeof(*parm_data) + ea_value_len + name_len + 1; | 5567 | count = sizeof(*parm_data) + ea_value_len + name_len; |
5503 | pSMB->MaxParameterCount = cpu_to_le16(2); | 5568 | pSMB->MaxParameterCount = cpu_to_le16(2); |
5504 | pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB size from sess */ | 5569 | pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB size from sess */ |
5505 | pSMB->MaxSetupCount = 0; | 5570 | pSMB->MaxSetupCount = 0; |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index fd9147cdb5a9..65d0ba72e78f 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * fs/cifs/connect.c | 2 | * fs/cifs/connect.c |
3 | * | 3 | * |
4 | * Copyright (C) International Business Machines Corp., 2002,2007 | 4 | * Copyright (C) International Business Machines Corp., 2002,2008 |
5 | * Author(s): Steve French (sfrench@us.ibm.com) | 5 | * Author(s): Steve French (sfrench@us.ibm.com) |
6 | * | 6 | * |
7 | * This library is free software; you can redistribute it and/or modify | 7 | * This library is free software; you can redistribute it and/or modify |
@@ -1410,7 +1410,7 @@ connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo, | |||
1410 | const char *old_path, const struct nls_table *nls_codepage, | 1410 | const char *old_path, const struct nls_table *nls_codepage, |
1411 | int remap) | 1411 | int remap) |
1412 | { | 1412 | { |
1413 | unsigned char *referrals = NULL; | 1413 | struct dfs_info3_param *referrals = NULL; |
1414 | unsigned int num_referrals; | 1414 | unsigned int num_referrals; |
1415 | int rc = 0; | 1415 | int rc = 0; |
1416 | 1416 | ||
@@ -1429,12 +1429,14 @@ connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo, | |||
1429 | int | 1429 | int |
1430 | get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path, | 1430 | get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path, |
1431 | const struct nls_table *nls_codepage, unsigned int *pnum_referrals, | 1431 | const struct nls_table *nls_codepage, unsigned int *pnum_referrals, |
1432 | unsigned char **preferrals, int remap) | 1432 | struct dfs_info3_param **preferrals, int remap) |
1433 | { | 1433 | { |
1434 | char *temp_unc; | 1434 | char *temp_unc; |
1435 | int rc = 0; | 1435 | int rc = 0; |
1436 | unsigned char *targetUNCs; | ||
1436 | 1437 | ||
1437 | *pnum_referrals = 0; | 1438 | *pnum_referrals = 0; |
1439 | *preferrals = NULL; | ||
1438 | 1440 | ||
1439 | if (pSesInfo->ipc_tid == 0) { | 1441 | if (pSesInfo->ipc_tid == 0) { |
1440 | temp_unc = kmalloc(2 /* for slashes */ + | 1442 | temp_unc = kmalloc(2 /* for slashes */ + |
@@ -1454,8 +1456,10 @@ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path, | |||
1454 | kfree(temp_unc); | 1456 | kfree(temp_unc); |
1455 | } | 1457 | } |
1456 | if (rc == 0) | 1458 | if (rc == 0) |
1457 | rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals, | 1459 | rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, &targetUNCs, |
1458 | pnum_referrals, nls_codepage, remap); | 1460 | pnum_referrals, nls_codepage, remap); |
1461 | /* BB map targetUNCs to dfs_info3 structures, here or | ||
1462 | in CIFSGetDFSRefer BB */ | ||
1459 | 1463 | ||
1460 | return rc; | 1464 | return rc; |
1461 | } | 1465 | } |
@@ -1964,7 +1968,15 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
1964 | 1968 | ||
1965 | if (existingCifsSes) { | 1969 | if (existingCifsSes) { |
1966 | pSesInfo = existingCifsSes; | 1970 | pSesInfo = existingCifsSes; |
1967 | cFYI(1, ("Existing smb sess found")); | 1971 | cFYI(1, ("Existing smb sess found (status=%d)", |
1972 | pSesInfo->status)); | ||
1973 | down(&pSesInfo->sesSem); | ||
1974 | if (pSesInfo->status == CifsNeedReconnect) { | ||
1975 | cFYI(1, ("Session needs reconnect")); | ||
1976 | rc = cifs_setup_session(xid, pSesInfo, | ||
1977 | cifs_sb->local_nls); | ||
1978 | } | ||
1979 | up(&pSesInfo->sesSem); | ||
1968 | } else if (!rc) { | 1980 | } else if (!rc) { |
1969 | cFYI(1, ("Existing smb sess not found")); | 1981 | cFYI(1, ("Existing smb sess not found")); |
1970 | pSesInfo = sesInfoAlloc(); | 1982 | pSesInfo = sesInfoAlloc(); |
@@ -3514,7 +3526,7 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) | |||
3514 | sesInfoFree(ses); | 3526 | sesInfoFree(ses); |
3515 | 3527 | ||
3516 | FreeXid(xid); | 3528 | FreeXid(xid); |
3517 | return rc; /* BB check if we should always return zero here */ | 3529 | return rc; |
3518 | } | 3530 | } |
3519 | 3531 | ||
3520 | int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, | 3532 | int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 37dc97af1487..699ec1198409 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -517,12 +517,10 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
517 | d_add(direntry, NULL); | 517 | d_add(direntry, NULL); |
518 | /* if it was once a directory (but how can we tell?) we could do | 518 | /* if it was once a directory (but how can we tell?) we could do |
519 | shrink_dcache_parent(direntry); */ | 519 | shrink_dcache_parent(direntry); */ |
520 | } else { | 520 | } else if (rc != -EACCES) { |
521 | cERROR(1, ("Error 0x%x on cifs_get_inode_info in lookup of %s", | 521 | cERROR(1, ("Unexpected lookup error %d", rc)); |
522 | rc, full_path)); | 522 | /* We special case check for Access Denied - since that |
523 | /* BB special case check for Access Denied - watch security | 523 | is a common return code */ |
524 | exposure of returning dir info implicitly via different rc | ||
525 | if file exists or not but no access BB */ | ||
526 | } | 524 | } |
527 | 525 | ||
528 | kfree(full_path); | 526 | kfree(full_path); |
diff --git a/fs/cifs/dns_resolve.c b/fs/cifs/dns_resolve.c new file mode 100644 index 000000000000..ef7f43824347 --- /dev/null +++ b/fs/cifs/dns_resolve.c | |||
@@ -0,0 +1,124 @@ | |||
1 | /* | ||
2 | * fs/cifs/dns_resolve.c | ||
3 | * | ||
4 | * Copyright (c) 2007 Igor Mammedov | ||
5 | * Author(s): Igor Mammedov (niallain@gmail.com) | ||
6 | * Steve French (sfrench@us.ibm.com) | ||
7 | * | ||
8 | * Contains the CIFS DFS upcall routines used for hostname to | ||
9 | * IP address translation. | ||
10 | * | ||
11 | * This library is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU Lesser General Public License as published | ||
13 | * by the Free Software Foundation; either version 2.1 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This library is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See | ||
19 | * the GNU Lesser General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU Lesser General Public License | ||
22 | * along with this library; if not, write to the Free Software | ||
23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
24 | */ | ||
25 | |||
26 | #include <keys/user-type.h> | ||
27 | #include "dns_resolve.h" | ||
28 | #include "cifsglob.h" | ||
29 | #include "cifsproto.h" | ||
30 | #include "cifs_debug.h" | ||
31 | |||
32 | static int dns_resolver_instantiate(struct key *key, const void *data, | ||
33 | size_t datalen) | ||
34 | { | ||
35 | int rc = 0; | ||
36 | char *ip; | ||
37 | |||
38 | ip = kmalloc(datalen+1, GFP_KERNEL); | ||
39 | if (!ip) | ||
40 | return -ENOMEM; | ||
41 | |||
42 | memcpy(ip, data, datalen); | ||
43 | ip[datalen] = '\0'; | ||
44 | |||
45 | rcu_assign_pointer(key->payload.data, ip); | ||
46 | |||
47 | return rc; | ||
48 | } | ||
49 | |||
50 | struct key_type key_type_dns_resolver = { | ||
51 | .name = "dns_resolver", | ||
52 | .def_datalen = sizeof(struct in_addr), | ||
53 | .describe = user_describe, | ||
54 | .instantiate = dns_resolver_instantiate, | ||
55 | .match = user_match, | ||
56 | }; | ||
57 | |||
58 | |||
59 | /* Resolves server name to ip address. | ||
60 | * input: | ||
61 | * unc - server UNC | ||
62 | * output: | ||
63 | * *ip_addr - pointer to server ip, caller responcible for freeing it. | ||
64 | * return 0 on success | ||
65 | */ | ||
66 | int | ||
67 | dns_resolve_server_name_to_ip(const char *unc, char **ip_addr) | ||
68 | { | ||
69 | int rc = -EAGAIN; | ||
70 | struct key *rkey; | ||
71 | char *name; | ||
72 | int len; | ||
73 | |||
74 | if (!ip_addr || !unc) | ||
75 | return -EINVAL; | ||
76 | |||
77 | /* search for server name delimiter */ | ||
78 | len = strlen(unc); | ||
79 | if (len < 3) { | ||
80 | cFYI(1, ("%s: unc is too short: %s", __FUNCTION__, unc)); | ||
81 | return -EINVAL; | ||
82 | } | ||
83 | len -= 2; | ||
84 | name = memchr(unc+2, '\\', len); | ||
85 | if (!name) { | ||
86 | cFYI(1, ("%s: probably server name is whole unc: %s", | ||
87 | __FUNCTION__, unc)); | ||
88 | } else { | ||
89 | len = (name - unc) - 2/* leading // */; | ||
90 | } | ||
91 | |||
92 | name = kmalloc(len+1, GFP_KERNEL); | ||
93 | if (!name) { | ||
94 | rc = -ENOMEM; | ||
95 | return rc; | ||
96 | } | ||
97 | memcpy(name, unc+2, len); | ||
98 | name[len] = 0; | ||
99 | |||
100 | rkey = request_key(&key_type_dns_resolver, name, ""); | ||
101 | if (!IS_ERR(rkey)) { | ||
102 | len = strlen(rkey->payload.data); | ||
103 | *ip_addr = kmalloc(len+1, GFP_KERNEL); | ||
104 | if (*ip_addr) { | ||
105 | memcpy(*ip_addr, rkey->payload.data, len); | ||
106 | (*ip_addr)[len] = '\0'; | ||
107 | cFYI(1, ("%s: resolved: %s to %s", __FUNCTION__, | ||
108 | rkey->description, | ||
109 | *ip_addr | ||
110 | )); | ||
111 | rc = 0; | ||
112 | } else { | ||
113 | rc = -ENOMEM; | ||
114 | } | ||
115 | key_put(rkey); | ||
116 | } else { | ||
117 | cERROR(1, ("%s: unable to resolve: %s", __FUNCTION__, name)); | ||
118 | } | ||
119 | |||
120 | kfree(name); | ||
121 | return rc; | ||
122 | } | ||
123 | |||
124 | |||
diff --git a/fs/cifs/dns_resolve.h b/fs/cifs/dns_resolve.h new file mode 100644 index 000000000000..073fdc3db419 --- /dev/null +++ b/fs/cifs/dns_resolve.h | |||
@@ -0,0 +1,32 @@ | |||
1 | /* | ||
2 | * fs/cifs/dns_resolve.h -- DNS Resolver upcall management for CIFS DFS | ||
3 | * Handles host name to IP address resolution | ||
4 | * | ||
5 | * Copyright (c) International Business Machines Corp., 2008 | ||
6 | * Author(s): Steve French (sfrench@us.ibm.com) | ||
7 | * | ||
8 | * This library is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU Lesser General Public License as published | ||
10 | * by the Free Software Foundation; either version 2.1 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This library 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 | ||
16 | * the GNU Lesser General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU Lesser General Public License | ||
19 | * along with this library; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | |||
23 | #ifndef _DNS_RESOLVE_H | ||
24 | #define _DNS_RESOLVE_H | ||
25 | |||
26 | #ifdef __KERNEL__ | ||
27 | #include <linux/key-type.h> | ||
28 | extern struct key_type key_type_dns_resolver; | ||
29 | extern int dns_resolve_server_name_to_ip(const char *unc, char **ip_addr); | ||
30 | #endif /* KERNEL */ | ||
31 | |||
32 | #endif /* _DNS_RESOLVE_H */ | ||
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index dd26e2759b17..5f7c374ae89c 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -1179,12 +1179,10 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) | |||
1179 | atomic_dec(&open_file->wrtPending); | 1179 | atomic_dec(&open_file->wrtPending); |
1180 | /* Does mm or vfs already set times? */ | 1180 | /* Does mm or vfs already set times? */ |
1181 | inode->i_atime = inode->i_mtime = current_fs_time(inode->i_sb); | 1181 | inode->i_atime = inode->i_mtime = current_fs_time(inode->i_sb); |
1182 | if ((bytes_written > 0) && (offset)) { | 1182 | if ((bytes_written > 0) && (offset)) |
1183 | rc = 0; | 1183 | rc = 0; |
1184 | } else if (bytes_written < 0) { | 1184 | else if (bytes_written < 0) |
1185 | if (rc != -EBADF) | 1185 | rc = bytes_written; |
1186 | rc = bytes_written; | ||
1187 | } | ||
1188 | } else { | 1186 | } else { |
1189 | cFYI(1, ("No writeable filehandles for inode")); | 1187 | cFYI(1, ("No writeable filehandles for inode")); |
1190 | rc = -EIO; | 1188 | rc = -EIO; |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index e915eb1d2e66..d9567ba2960b 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -54,9 +54,9 @@ int cifs_get_inode_info_unix(struct inode **pinode, | |||
54 | MAX_TREE_SIZE + 1) + | 54 | MAX_TREE_SIZE + 1) + |
55 | strnlen(search_path, MAX_PATHCONF) + 1, | 55 | strnlen(search_path, MAX_PATHCONF) + 1, |
56 | GFP_KERNEL); | 56 | GFP_KERNEL); |
57 | if (tmp_path == NULL) { | 57 | if (tmp_path == NULL) |
58 | return -ENOMEM; | 58 | return -ENOMEM; |
59 | } | 59 | |
60 | /* have to skip first of the double backslash of | 60 | /* have to skip first of the double backslash of |
61 | UNC name */ | 61 | UNC name */ |
62 | strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE); | 62 | strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE); |
@@ -511,7 +511,8 @@ int cifs_get_inode_info(struct inode **pinode, | |||
511 | } | 511 | } |
512 | 512 | ||
513 | spin_lock(&inode->i_lock); | 513 | spin_lock(&inode->i_lock); |
514 | if (is_size_safe_to_change(cifsInfo, le64_to_cpu(pfindData->EndOfFile))) { | 514 | if (is_size_safe_to_change(cifsInfo, |
515 | le64_to_cpu(pfindData->EndOfFile))) { | ||
515 | /* can not safely shrink the file size here if the | 516 | /* can not safely shrink the file size here if the |
516 | client is writing to it due to potential races */ | 517 | client is writing to it due to potential races */ |
517 | i_size_write(inode, le64_to_cpu(pfindData->EndOfFile)); | 518 | i_size_write(inode, le64_to_cpu(pfindData->EndOfFile)); |
@@ -931,7 +932,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) | |||
931 | (CIFS_UNIX_POSIX_PATH_OPS_CAP & | 932 | (CIFS_UNIX_POSIX_PATH_OPS_CAP & |
932 | le64_to_cpu(pTcon->fsUnixInfo.Capability))) { | 933 | le64_to_cpu(pTcon->fsUnixInfo.Capability))) { |
933 | u32 oplock = 0; | 934 | u32 oplock = 0; |
934 | FILE_UNIX_BASIC_INFO * pInfo = | 935 | FILE_UNIX_BASIC_INFO *pInfo = |
935 | kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL); | 936 | kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL); |
936 | if (pInfo == NULL) { | 937 | if (pInfo == NULL) { |
937 | rc = -ENOMEM; | 938 | rc = -ENOMEM; |
@@ -1607,7 +1608,14 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | |||
1607 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 1608 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
1608 | else if (attrs->ia_valid & ATTR_MODE) { | 1609 | else if (attrs->ia_valid & ATTR_MODE) { |
1609 | rc = 0; | 1610 | rc = 0; |
1610 | if ((mode & S_IWUGO) == 0) /* not writeable */ { | 1611 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
1612 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) | ||
1613 | rc = mode_to_acl(direntry->d_inode, full_path, mode); | ||
1614 | else if ((mode & S_IWUGO) == 0) { | ||
1615 | #else | ||
1616 | if ((mode & S_IWUGO) == 0) { | ||
1617 | #endif | ||
1618 | /* not writeable */ | ||
1611 | if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) { | 1619 | if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) { |
1612 | set_dosattr = TRUE; | 1620 | set_dosattr = TRUE; |
1613 | time_buf.Attributes = | 1621 | time_buf.Attributes = |
@@ -1626,10 +1634,10 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | |||
1626 | if (time_buf.Attributes == 0) | 1634 | if (time_buf.Attributes == 0) |
1627 | time_buf.Attributes |= cpu_to_le32(ATTR_NORMAL); | 1635 | time_buf.Attributes |= cpu_to_le32(ATTR_NORMAL); |
1628 | } | 1636 | } |
1629 | /* BB to be implemented - | 1637 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
1630 | via Windows security descriptors or streams */ | 1638 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) |
1631 | /* CIFSSMBWinSetPerms(xid, pTcon, full_path, mode, uid, gid, | 1639 | mode_to_acl(direntry->d_inode, full_path, mode); |
1632 | cifs_sb->local_nls); */ | 1640 | #endif |
1633 | } | 1641 | } |
1634 | 1642 | ||
1635 | if (attrs->ia_valid & ATTR_ATIME) { | 1643 | if (attrs->ia_valid & ATTR_ATIME) { |
diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 11f265726db7..1d6fb01b8e6d 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * fs/cifs/link.c | 2 | * fs/cifs/link.c |
3 | * | 3 | * |
4 | * Copyright (C) International Business Machines Corp., 2002,2003 | 4 | * Copyright (C) International Business Machines Corp., 2002,2008 |
5 | * Author(s): Steve French (sfrench@us.ibm.com) | 5 | * Author(s): Steve French (sfrench@us.ibm.com) |
6 | * | 6 | * |
7 | * This library is free software; you can redistribute it and/or modify | 7 | * This library is free software; you can redistribute it and/or modify |
@@ -236,8 +236,6 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen) | |||
236 | char *full_path = NULL; | 236 | char *full_path = NULL; |
237 | char *tmp_path = NULL; | 237 | char *tmp_path = NULL; |
238 | char *tmpbuffer; | 238 | char *tmpbuffer; |
239 | unsigned char *referrals = NULL; | ||
240 | unsigned int num_referrals = 0; | ||
241 | int len; | 239 | int len; |
242 | __u16 fid; | 240 | __u16 fid; |
243 | 241 | ||
@@ -297,8 +295,11 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen) | |||
297 | cFYI(1, ("Error closing junction point " | 295 | cFYI(1, ("Error closing junction point " |
298 | "(open for ioctl)")); | 296 | "(open for ioctl)")); |
299 | } | 297 | } |
298 | /* BB unwind this long, nested function, or remove BB */ | ||
300 | if (rc == -EIO) { | 299 | if (rc == -EIO) { |
301 | /* Query if DFS Junction */ | 300 | /* Query if DFS Junction */ |
301 | unsigned int num_referrals = 0; | ||
302 | struct dfs_info3_param *refs = NULL; | ||
302 | tmp_path = | 303 | tmp_path = |
303 | kmalloc(MAX_TREE_SIZE + MAX_PATHCONF + 1, | 304 | kmalloc(MAX_TREE_SIZE + MAX_PATHCONF + 1, |
304 | GFP_KERNEL); | 305 | GFP_KERNEL); |
@@ -310,7 +311,7 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen) | |||
310 | rc = get_dfs_path(xid, pTcon->ses, | 311 | rc = get_dfs_path(xid, pTcon->ses, |
311 | tmp_path, | 312 | tmp_path, |
312 | cifs_sb->local_nls, | 313 | cifs_sb->local_nls, |
313 | &num_referrals, &referrals, | 314 | &num_referrals, &refs, |
314 | cifs_sb->mnt_cifs_flags & | 315 | cifs_sb->mnt_cifs_flags & |
315 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 316 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
316 | cFYI(1, ("Get DFS for %s rc = %d ", | 317 | cFYI(1, ("Get DFS for %s rc = %d ", |
@@ -320,14 +321,13 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen) | |||
320 | else { | 321 | else { |
321 | cFYI(1, ("num referral: %d", | 322 | cFYI(1, ("num referral: %d", |
322 | num_referrals)); | 323 | num_referrals)); |
323 | if (referrals) { | 324 | if (refs && refs->path_name) { |
324 | cFYI(1,("referral string: %s", referrals)); | ||
325 | strncpy(tmpbuffer, | 325 | strncpy(tmpbuffer, |
326 | referrals, | 326 | refs->path_name, |
327 | len-1); | 327 | len-1); |
328 | } | 328 | } |
329 | } | 329 | } |
330 | kfree(referrals); | 330 | kfree(refs); |
331 | kfree(tmp_path); | 331 | kfree(tmp_path); |
332 | } | 332 | } |
333 | /* BB add code like else decode referrals | 333 | /* BB add code like else decode referrals |
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index d0cb469daab7..d2153abcba6d 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c | |||
@@ -528,9 +528,11 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, | |||
528 | rc = -EOVERFLOW; | 528 | rc = -EOVERFLOW; |
529 | goto ssetup_exit; | 529 | goto ssetup_exit; |
530 | } | 530 | } |
531 | ses->server->mac_signing_key.len = msg->sesskey_len; | 531 | if (first_time) { |
532 | memcpy(ses->server->mac_signing_key.data.krb5, msg->data, | 532 | ses->server->mac_signing_key.len = msg->sesskey_len; |
533 | msg->sesskey_len); | 533 | memcpy(ses->server->mac_signing_key.data.krb5, |
534 | msg->data, msg->sesskey_len); | ||
535 | } | ||
534 | pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; | 536 | pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; |
535 | capabilities |= CAP_EXTENDED_SECURITY; | 537 | capabilities |= CAP_EXTENDED_SECURITY; |
536 | pSMB->req.Capabilities = cpu_to_le32(capabilities); | 538 | pSMB->req.Capabilities = cpu_to_le32(capabilities); |
@@ -540,7 +542,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, | |||
540 | 542 | ||
541 | if (ses->capabilities & CAP_UNICODE) { | 543 | if (ses->capabilities & CAP_UNICODE) { |
542 | /* unicode strings must be word aligned */ | 544 | /* unicode strings must be word aligned */ |
543 | if (iov[0].iov_len % 2) { | 545 | if ((iov[0].iov_len + iov[1].iov_len) % 2) { |
544 | *bcc_ptr = 0; | 546 | *bcc_ptr = 0; |
545 | bcc_ptr++; | 547 | bcc_ptr++; |
546 | } | 548 | } |
diff --git a/include/asm-arm/arch-at91/at91_lcdc.h b/include/asm-arm/arch-at91/at91_lcdc.h deleted file mode 100644 index ab040a40d37b..000000000000 --- a/include/asm-arm/arch-at91/at91_lcdc.h +++ /dev/null | |||
@@ -1,148 +0,0 @@ | |||
1 | /* | ||
2 | * include/asm-arm/arch-at91/at91_lcdc.h | ||
3 | * | ||
4 | * LCD Controller (LCDC). | ||
5 | * Based on AT91SAM9261 datasheet revision E. | ||
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 as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | */ | ||
12 | |||
13 | #ifndef AT91_LCDC_H | ||
14 | #define AT91_LCDC_H | ||
15 | |||
16 | #define AT91_LCDC_DMABADDR1 0x00 /* DMA Base Address Register 1 */ | ||
17 | #define AT91_LCDC_DMABADDR2 0x04 /* DMA Base Address Register 2 */ | ||
18 | #define AT91_LCDC_DMAFRMPT1 0x08 /* DMA Frame Pointer Register 1 */ | ||
19 | #define AT91_LCDC_DMAFRMPT2 0x0c /* DMA Frame Pointer Register 2 */ | ||
20 | #define AT91_LCDC_DMAFRMADD1 0x10 /* DMA Frame Address Register 1 */ | ||
21 | #define AT91_LCDC_DMAFRMADD2 0x14 /* DMA Frame Address Register 2 */ | ||
22 | |||
23 | #define AT91_LCDC_DMAFRMCFG 0x18 /* DMA Frame Configuration Register */ | ||
24 | #define AT91_LCDC_FRSIZE (0x7fffff << 0) /* Frame Size */ | ||
25 | #define AT91_LCDC_BLENGTH (0x7f << 24) /* Burst Length */ | ||
26 | |||
27 | #define AT91_LCDC_DMACON 0x1c /* DMA Control Register */ | ||
28 | #define AT91_LCDC_DMAEN (0x1 << 0) /* DMA Enable */ | ||
29 | #define AT91_LCDC_DMARST (0x1 << 1) /* DMA Reset */ | ||
30 | #define AT91_LCDC_DMABUSY (0x1 << 2) /* DMA Busy */ | ||
31 | |||
32 | #define AT91_LCDC_LCDCON1 0x0800 /* LCD Control Register 1 */ | ||
33 | #define AT91_LCDC_BYPASS (1 << 0) /* Bypass lcd_dotck divider */ | ||
34 | #define AT91_LCDC_CLKVAL (0x1ff << 12) /* Clock Divider */ | ||
35 | #define AT91_LCDC_LINCNT (0x7ff << 21) /* Line Counter */ | ||
36 | |||
37 | #define AT91_LCDC_LCDCON2 0x0804 /* LCD Control Register 2 */ | ||
38 | #define AT91_LCDC_DISTYPE (3 << 0) /* Display Type */ | ||
39 | #define AT91_LCDC_DISTYPE_STNMONO (0 << 0) | ||
40 | #define AT91_LCDC_DISTYPE_STNCOLOR (1 << 0) | ||
41 | #define AT91_LCDC_DISTYPE_TFT (2 << 0) | ||
42 | #define AT91_LCDC_SCANMOD (1 << 2) /* Scan Mode */ | ||
43 | #define AT91_LCDC_SCANMOD_SINGLE (0 << 2) | ||
44 | #define AT91_LCDC_SCANMOD_DUAL (1 << 2) | ||
45 | #define AT91_LCDC_IFWIDTH (3 << 3) /*Interface Width */ | ||
46 | #define AT91_LCDC_IFWIDTH_4 (0 << 3) | ||
47 | #define AT91_LCDC_IFWIDTH_8 (1 << 3) | ||
48 | #define AT91_LCDC_IFWIDTH_16 (2 << 3) | ||
49 | #define AT91_LCDC_PIXELSIZE (7 << 5) /* Bits per pixel */ | ||
50 | #define AT91_LCDC_PIXELSIZE_1 (0 << 5) | ||
51 | #define AT91_LCDC_PIXELSIZE_2 (1 << 5) | ||
52 | #define AT91_LCDC_PIXELSIZE_4 (2 << 5) | ||
53 | #define AT91_LCDC_PIXELSIZE_8 (3 << 5) | ||
54 | #define AT91_LCDC_PIXELSIZE_16 (4 << 5) | ||
55 | #define AT91_LCDC_PIXELSIZE_24 (5 << 5) | ||
56 | #define AT91_LCDC_INVVD (1 << 8) /* LCD Data polarity */ | ||
57 | #define AT91_LCDC_INVVD_NORMAL (0 << 8) | ||
58 | #define AT91_LCDC_INVVD_INVERTED (1 << 8) | ||
59 | #define AT91_LCDC_INVFRAME (1 << 9 ) /* LCD VSync polarity */ | ||
60 | #define AT91_LCDC_INVFRAME_NORMAL (0 << 9) | ||
61 | #define AT91_LCDC_INVFRAME_INVERTED (1 << 9) | ||
62 | #define AT91_LCDC_INVLINE (1 << 10) /* LCD HSync polarity */ | ||
63 | #define AT91_LCDC_INVLINE_NORMAL (0 << 10) | ||
64 | #define AT91_LCDC_INVLINE_INVERTED (1 << 10) | ||
65 | #define AT91_LCDC_INVCLK (1 << 11) /* LCD dotclk polarity */ | ||
66 | #define AT91_LCDC_INVCLK_NORMAL (0 << 11) | ||
67 | #define AT91_LCDC_INVCLK_INVERTED (1 << 11) | ||
68 | #define AT91_LCDC_INVDVAL (1 << 12) /* LCD dval polarity */ | ||
69 | #define AT91_LCDC_INVDVAL_NORMAL (0 << 12) | ||
70 | #define AT91_LCDC_INVDVAL_INVERTED (1 << 12) | ||
71 | #define AT91_LCDC_CLKMOD (1 << 15) /* LCD dotclk mode */ | ||
72 | #define AT91_LCDC_CLKMOD_ACTIVEDISPLAY (0 << 15) | ||
73 | #define AT91_LCDC_CLKMOD_ALWAYSACTIVE (1 << 15) | ||
74 | #define AT91_LCDC_MEMOR (1 << 31) /* Memory Ordering Format */ | ||
75 | #define AT91_LCDC_MEMOR_BIG (0 << 31) | ||
76 | #define AT91_LCDC_MEMOR_LITTLE (1 << 31) | ||
77 | |||
78 | #define AT91_LCDC_TIM1 0x0808 /* LCD Timing Register 1 */ | ||
79 | #define AT91_LCDC_VFP (0xff << 0) /* Vertical Front Porch */ | ||
80 | #define AT91_LCDC_VBP (0xff << 8) /* Vertical Back Porch */ | ||
81 | #define AT91_LCDC_VPW (0x3f << 16) /* Vertical Synchronization Pulse Width */ | ||
82 | #define AT91_LCDC_VHDLY (0xf << 24) /* Vertical to Horizontal Delay */ | ||
83 | |||
84 | #define AT91_LCDC_TIM2 0x080c /* LCD Timing Register 2 */ | ||
85 | #define AT91_LCDC_HBP (0xff << 0) /* Horizontal Back Porch */ | ||
86 | #define AT91_LCDC_HPW (0x3f << 8) /* Horizontal Synchronization Pulse Width */ | ||
87 | #define AT91_LCDC_HFP (0x7ff << 21) /* Horizontal Front Porch */ | ||
88 | |||
89 | #define AT91_LCDC_LCDFRMCFG 0x0810 /* LCD Frame Configuration Register */ | ||
90 | #define AT91_LCDC_LINEVAL (0x7ff << 0) /* Vertical Size of LCD Module */ | ||
91 | #define AT91_LCDC_HOZVAL (0x7ff << 21) /* Horizontal Size of LCD Module */ | ||
92 | |||
93 | #define AT91_LCDC_FIFO 0x0814 /* LCD FIFO Register */ | ||
94 | #define AT91_LCDC_FIFOTH (0xffff) /* FIFO Threshold */ | ||
95 | |||
96 | #define AT91_LCDC_DP1_2 0x081c /* Dithering Pattern DP1_2 Register */ | ||
97 | #define AT91_LCDC_DP4_7 0x0820 /* Dithering Pattern DP4_7 Register */ | ||
98 | #define AT91_LCDC_DP3_5 0x0824 /* Dithering Pattern DP3_5 Register */ | ||
99 | #define AT91_LCDC_DP2_3 0x0828 /* Dithering Pattern DP2_3 Register */ | ||
100 | #define AT91_LCDC_DP5_7 0x082c /* Dithering Pattern DP5_7 Register */ | ||
101 | #define AT91_LCDC_DP3_4 0x0830 /* Dithering Pattern DP3_4 Register */ | ||
102 | #define AT91_LCDC_DP4_5 0x0834 /* Dithering Pattern DP4_5 Register */ | ||
103 | #define AT91_LCDC_DP6_7 0x0838 /* Dithering Pattern DP6_7 Register */ | ||
104 | #define AT91_LCDC_DP1_2_VAL (0xff) | ||
105 | #define AT91_LCDC_DP4_7_VAL (0xfffffff) | ||
106 | #define AT91_LCDC_DP3_5_VAL (0xfffff) | ||
107 | #define AT91_LCDC_DP2_3_VAL (0xfff) | ||
108 | #define AT91_LCDC_DP5_7_VAL (0xfffffff) | ||
109 | #define AT91_LCDC_DP3_4_VAL (0xffff) | ||
110 | #define AT91_LCDC_DP4_5_VAL (0xfffff) | ||
111 | #define AT91_LCDC_DP6_7_VAL (0xfffffff) | ||
112 | |||
113 | #define AT91_LCDC_PWRCON 0x083c /* Power Control Register */ | ||
114 | #define AT91_LCDC_PWR (1 << 0) /* LCD Module Power Control */ | ||
115 | #define AT91_LCDC_GUARDT (0x7f << 1) /* Delay in Frame Period */ | ||
116 | #define AT91_LCDC_BUSY (1 << 31) /* LCD Busy */ | ||
117 | |||
118 | #define AT91_LCDC_CONTRAST_CTR 0x0840 /* Contrast Control Register */ | ||
119 | #define AT91_LCDC_PS (3 << 0) /* Contrast Counter Prescaler */ | ||
120 | #define AT91_LCDC_PS_DIV1 (0 << 0) | ||
121 | #define AT91_LCDC_PS_DIV2 (1 << 0) | ||
122 | #define AT91_LCDC_PS_DIV4 (2 << 0) | ||
123 | #define AT91_LCDC_PS_DIV8 (3 << 0) | ||
124 | #define AT91_LCDC_POL (1 << 2) /* Polarity of output Pulse */ | ||
125 | #define AT91_LCDC_POL_NEGATIVE (0 << 2) | ||
126 | #define AT91_LCDC_POL_POSITIVE (1 << 2) | ||
127 | #define AT91_LCDC_ENA (1 << 3) /* PWM generator Control */ | ||
128 | #define AT91_LCDC_ENA_PWMDISABLE (0 << 3) | ||
129 | #define AT91_LCDC_ENA_PWMENABLE (1 << 3) | ||
130 | |||
131 | #define AT91_LCDC_CONTRAST_VAL 0x0844 /* Contrast Value Register */ | ||
132 | #define AT91_LCDC_CVAL (0xff) /* PWM compare value */ | ||
133 | |||
134 | #define AT91_LCDC_IER 0x0848 /* Interrupt Enable Register */ | ||
135 | #define AT91_LCDC_IDR 0x084c /* Interrupt Disable Register */ | ||
136 | #define AT91_LCDC_IMR 0x0850 /* Interrupt Mask Register */ | ||
137 | #define AT91_LCDC_ISR 0x0854 /* Interrupt Enable Register */ | ||
138 | #define AT91_LCDC_ICR 0x0858 /* Interrupt Clear Register */ | ||
139 | #define AT91_LCDC_LNI (1 << 0) /* Line Interrupt */ | ||
140 | #define AT91_LCDC_LSTLNI (1 << 1) /* Last Line Interrupt */ | ||
141 | #define AT91_LCDC_EOFI (1 << 2) /* DMA End Of Frame Interrupt */ | ||
142 | #define AT91_LCDC_UFLWI (1 << 4) /* FIFO Underflow Interrupt */ | ||
143 | #define AT91_LCDC_OWRI (1 << 5) /* FIFO Overwrite Interrupt */ | ||
144 | #define AT91_LCDC_MERI (1 << 6) /* DMA Memory Error Interrupt */ | ||
145 | |||
146 | #define AT91_LCDC_LUT_(n) (0x0c00 + ((n)*4)) /* Palette Entry 0..255 */ | ||
147 | |||
148 | #endif | ||
diff --git a/include/asm-arm/arch-at91/at91_pmc.h b/include/asm-arm/arch-at91/at91_pmc.h index 33ff5b6798ee..52cd8e5dabc9 100644 --- a/include/asm-arm/arch-at91/at91_pmc.h +++ b/include/asm-arm/arch-at91/at91_pmc.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #define AT91RM9200_PMC_MCKUDP (1 << 2) /* USB Device Port Master Clock Automatic Disable on Suspend [AT91RM9200 only] */ | 25 | #define AT91RM9200_PMC_MCKUDP (1 << 2) /* USB Device Port Master Clock Automatic Disable on Suspend [AT91RM9200 only] */ |
26 | #define AT91RM9200_PMC_UHP (1 << 4) /* USB Host Port Clock [AT91RM9200 only] */ | 26 | #define AT91RM9200_PMC_UHP (1 << 4) /* USB Host Port Clock [AT91RM9200 only] */ |
27 | #define AT91SAM926x_PMC_UHP (1 << 6) /* USB Host Port Clock [AT91SAM926x only] */ | 27 | #define AT91SAM926x_PMC_UHP (1 << 6) /* USB Host Port Clock [AT91SAM926x only] */ |
28 | #define AT91CAP9_PMC_UHP (1 << 6) /* USB Host Port Clock [AT91CAP9 only] */ | ||
28 | #define AT91SAM926x_PMC_UDP (1 << 7) /* USB Devcice Port Clock [AT91SAM926x only] */ | 29 | #define AT91SAM926x_PMC_UDP (1 << 7) /* USB Devcice Port Clock [AT91SAM926x only] */ |
29 | #define AT91_PMC_PCK0 (1 << 8) /* Programmable Clock 0 */ | 30 | #define AT91_PMC_PCK0 (1 << 8) /* Programmable Clock 0 */ |
30 | #define AT91_PMC_PCK1 (1 << 9) /* Programmable Clock 1 */ | 31 | #define AT91_PMC_PCK1 (1 << 9) /* Programmable Clock 1 */ |
@@ -37,7 +38,9 @@ | |||
37 | #define AT91_PMC_PCDR (AT91_PMC + 0x14) /* Peripheral Clock Disable Register */ | 38 | #define AT91_PMC_PCDR (AT91_PMC + 0x14) /* Peripheral Clock Disable Register */ |
38 | #define AT91_PMC_PCSR (AT91_PMC + 0x18) /* Peripheral Clock Status Register */ | 39 | #define AT91_PMC_PCSR (AT91_PMC + 0x18) /* Peripheral Clock Status Register */ |
39 | 40 | ||
40 | #define AT91_CKGR_MOR (AT91_PMC + 0x20) /* Main Oscillator Register */ | 41 | #define AT91_CKGR_UCKR (AT91_PMC + 0x1C) /* UTMI Clock Register [SAM9RL, CAP9] */ |
42 | |||
43 | #define AT91_CKGR_MOR (AT91_PMC + 0x20) /* Main Oscillator Register [not on SAM9RL] */ | ||
41 | #define AT91_PMC_MOSCEN (1 << 0) /* Main Oscillator Enable */ | 44 | #define AT91_PMC_MOSCEN (1 << 0) /* Main Oscillator Enable */ |
42 | #define AT91_PMC_OSCBYPASS (1 << 1) /* Oscillator Bypass [AT91SAM926x only] */ | 45 | #define AT91_PMC_OSCBYPASS (1 << 1) /* Oscillator Bypass [AT91SAM926x only] */ |
43 | #define AT91_PMC_OSCOUNT (0xff << 8) /* Main Oscillator Start-up Time */ | 46 | #define AT91_PMC_OSCOUNT (0xff << 8) /* Main Oscillator Start-up Time */ |
@@ -52,6 +55,10 @@ | |||
52 | #define AT91_PMC_PLLCOUNT (0x3f << 8) /* PLL Counter */ | 55 | #define AT91_PMC_PLLCOUNT (0x3f << 8) /* PLL Counter */ |
53 | #define AT91_PMC_OUT (3 << 14) /* PLL Clock Frequency Range */ | 56 | #define AT91_PMC_OUT (3 << 14) /* PLL Clock Frequency Range */ |
54 | #define AT91_PMC_MUL (0x7ff << 16) /* PLL Multiplier */ | 57 | #define AT91_PMC_MUL (0x7ff << 16) /* PLL Multiplier */ |
58 | #define AT91_PMC_USBDIV (3 << 28) /* USB Divisor (PLLB only) */ | ||
59 | #define AT91_PMC_USBDIV_1 (0 << 28) | ||
60 | #define AT91_PMC_USBDIV_2 (1 << 28) | ||
61 | #define AT91_PMC_USBDIV_4 (2 << 28) | ||
55 | #define AT91_PMC_USB96M (1 << 28) /* Divider by 2 Enable (PLLB only) */ | 62 | #define AT91_PMC_USB96M (1 << 28) /* Divider by 2 Enable (PLLB only) */ |
56 | 63 | ||
57 | #define AT91_PMC_MCKR (AT91_PMC + 0x30) /* Master Clock Register */ | 64 | #define AT91_PMC_MCKR (AT91_PMC + 0x30) /* Master Clock Register */ |
diff --git a/include/asm-arm/arch-at91/at91_rtt.h b/include/asm-arm/arch-at91/at91_rtt.h index bae1103fbbb2..39a32633b275 100644 --- a/include/asm-arm/arch-at91/at91_rtt.h +++ b/include/asm-arm/arch-at91/at91_rtt.h | |||
@@ -13,19 +13,19 @@ | |||
13 | #ifndef AT91_RTT_H | 13 | #ifndef AT91_RTT_H |
14 | #define AT91_RTT_H | 14 | #define AT91_RTT_H |
15 | 15 | ||
16 | #define AT91_RTT_MR (AT91_RTT + 0x00) /* Real-time Mode Register */ | 16 | #define AT91_RTT_MR 0x00 /* Real-time Mode Register */ |
17 | #define AT91_RTT_RTPRES (0xffff << 0) /* Real-time Timer Prescaler Value */ | 17 | #define AT91_RTT_RTPRES (0xffff << 0) /* Real-time Timer Prescaler Value */ |
18 | #define AT91_RTT_ALMIEN (1 << 16) /* Alarm Interrupt Enable */ | 18 | #define AT91_RTT_ALMIEN (1 << 16) /* Alarm Interrupt Enable */ |
19 | #define AT91_RTT_RTTINCIEN (1 << 17) /* Real Time Timer Increment Interrupt Enable */ | 19 | #define AT91_RTT_RTTINCIEN (1 << 17) /* Real Time Timer Increment Interrupt Enable */ |
20 | #define AT91_RTT_RTTRST (1 << 18) /* Real Time Timer Restart */ | 20 | #define AT91_RTT_RTTRST (1 << 18) /* Real Time Timer Restart */ |
21 | 21 | ||
22 | #define AT91_RTT_AR (AT91_RTT + 0x04) /* Real-time Alarm Register */ | 22 | #define AT91_RTT_AR 0x04 /* Real-time Alarm Register */ |
23 | #define AT91_RTT_ALMV (0xffffffff) /* Alarm Value */ | 23 | #define AT91_RTT_ALMV (0xffffffff) /* Alarm Value */ |
24 | 24 | ||
25 | #define AT91_RTT_VR (AT91_RTT + 0x08) /* Real-time Value Register */ | 25 | #define AT91_RTT_VR 0x08 /* Real-time Value Register */ |
26 | #define AT91_RTT_CRTV (0xffffffff) /* Current Real-time Value */ | 26 | #define AT91_RTT_CRTV (0xffffffff) /* Current Real-time Value */ |
27 | 27 | ||
28 | #define AT91_RTT_SR (AT91_RTT + 0x0c) /* Real-time Status Register */ | 28 | #define AT91_RTT_SR 0x0c /* Real-time Status Register */ |
29 | #define AT91_RTT_ALMS (1 << 0) /* Real-time Alarm Status */ | 29 | #define AT91_RTT_ALMS (1 << 0) /* Real-time Alarm Status */ |
30 | #define AT91_RTT_RTTINC (1 << 1) /* Real-time Timer Increment */ | 30 | #define AT91_RTT_RTTINC (1 << 1) /* Real-time Timer Increment */ |
31 | 31 | ||
diff --git a/include/asm-arm/arch-at91/at91_twi.h b/include/asm-arm/arch-at91/at91_twi.h index ca9a90733456..f9f2e3cd95c5 100644 --- a/include/asm-arm/arch-at91/at91_twi.h +++ b/include/asm-arm/arch-at91/at91_twi.h | |||
@@ -21,6 +21,8 @@ | |||
21 | #define AT91_TWI_STOP (1 << 1) /* Send a Stop Condition */ | 21 | #define AT91_TWI_STOP (1 << 1) /* Send a Stop Condition */ |
22 | #define AT91_TWI_MSEN (1 << 2) /* Master Transfer Enable */ | 22 | #define AT91_TWI_MSEN (1 << 2) /* Master Transfer Enable */ |
23 | #define AT91_TWI_MSDIS (1 << 3) /* Master Transfer Disable */ | 23 | #define AT91_TWI_MSDIS (1 << 3) /* Master Transfer Disable */ |
24 | #define AT91_TWI_SVEN (1 << 4) /* Slave Transfer Enable [SAM9260 only] */ | ||
25 | #define AT91_TWI_SVDIS (1 << 5) /* Slave Transfer Disable [SAM9260 only] */ | ||
24 | #define AT91_TWI_SWRST (1 << 7) /* Software Reset */ | 26 | #define AT91_TWI_SWRST (1 << 7) /* Software Reset */ |
25 | 27 | ||
26 | #define AT91_TWI_MMR 0x04 /* Master Mode Register */ | 28 | #define AT91_TWI_MMR 0x04 /* Master Mode Register */ |
@@ -32,6 +34,9 @@ | |||
32 | #define AT91_TWI_MREAD (1 << 12) /* Master Read Direction */ | 34 | #define AT91_TWI_MREAD (1 << 12) /* Master Read Direction */ |
33 | #define AT91_TWI_DADR (0x7f << 16) /* Device Address */ | 35 | #define AT91_TWI_DADR (0x7f << 16) /* Device Address */ |
34 | 36 | ||
37 | #define AT91_TWI_SMR 0x08 /* Slave Mode Register [SAM9260 only] */ | ||
38 | #define AT91_TWI_SADR (0x7f << 16) /* Slave Address */ | ||
39 | |||
35 | #define AT91_TWI_IADR 0x0c /* Internal Address Register */ | 40 | #define AT91_TWI_IADR 0x0c /* Internal Address Register */ |
36 | 41 | ||
37 | #define AT91_TWI_CWGR 0x10 /* Clock Waveform Generator Register */ | 42 | #define AT91_TWI_CWGR 0x10 /* Clock Waveform Generator Register */ |
@@ -43,9 +48,15 @@ | |||
43 | #define AT91_TWI_TXCOMP (1 << 0) /* Transmission Complete */ | 48 | #define AT91_TWI_TXCOMP (1 << 0) /* Transmission Complete */ |
44 | #define AT91_TWI_RXRDY (1 << 1) /* Receive Holding Register Ready */ | 49 | #define AT91_TWI_RXRDY (1 << 1) /* Receive Holding Register Ready */ |
45 | #define AT91_TWI_TXRDY (1 << 2) /* Transmit Holding Register Ready */ | 50 | #define AT91_TWI_TXRDY (1 << 2) /* Transmit Holding Register Ready */ |
51 | #define AT91_TWI_SVREAD (1 << 3) /* Slave Read [SAM9260 only] */ | ||
52 | #define AT91_TWI_SVACC (1 << 4) /* Slave Access [SAM9260 only] */ | ||
53 | #define AT91_TWI_GACC (1 << 5) /* General Call Access [SAM9260 only] */ | ||
46 | #define AT91_TWI_OVRE (1 << 6) /* Overrun Error [AT91RM9200 only] */ | 54 | #define AT91_TWI_OVRE (1 << 6) /* Overrun Error [AT91RM9200 only] */ |
47 | #define AT91_TWI_UNRE (1 << 7) /* Underrun Error [AT91RM9200 only] */ | 55 | #define AT91_TWI_UNRE (1 << 7) /* Underrun Error [AT91RM9200 only] */ |
48 | #define AT91_TWI_NACK (1 << 8) /* Not Acknowledged */ | 56 | #define AT91_TWI_NACK (1 << 8) /* Not Acknowledged */ |
57 | #define AT91_TWI_ARBLST (1 << 9) /* Arbitration Lost [SAM9260 only] */ | ||
58 | #define AT91_TWI_SCLWS (1 << 10) /* Clock Wait State [SAM9260 only] */ | ||
59 | #define AT91_TWI_EOSACC (1 << 11) /* End of Slave Address [SAM9260 only] */ | ||
49 | 60 | ||
50 | #define AT91_TWI_IER 0x24 /* Interrupt Enable Register */ | 61 | #define AT91_TWI_IER 0x24 /* Interrupt Enable Register */ |
51 | #define AT91_TWI_IDR 0x28 /* Interrupt Disable Register */ | 62 | #define AT91_TWI_IDR 0x28 /* Interrupt Disable Register */ |
diff --git a/include/asm-arm/arch-at91/at91cap9.h b/include/asm-arm/arch-at91/at91cap9.h new file mode 100644 index 000000000000..73e1fcf4a0aa --- /dev/null +++ b/include/asm-arm/arch-at91/at91cap9.h | |||
@@ -0,0 +1,121 @@ | |||
1 | /* | ||
2 | * include/asm-arm/arch-at91/at91cap9.h | ||
3 | * | ||
4 | * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com> | ||
5 | * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com> | ||
6 | * Copyright (C) 2007 Atmel Corporation. | ||
7 | * | ||
8 | * Common definitions. | ||
9 | * Based on AT91CAP9 datasheet revision B (Preliminary). | ||
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 as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | */ | ||
16 | |||
17 | #ifndef AT91CAP9_H | ||
18 | #define AT91CAP9_H | ||
19 | |||
20 | /* | ||
21 | * Peripheral identifiers/interrupts. | ||
22 | */ | ||
23 | #define AT91_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ | ||
24 | #define AT91_ID_SYS 1 /* System Peripherals */ | ||
25 | #define AT91CAP9_ID_PIOABCD 2 /* Parallel IO Controller A, B, C and D */ | ||
26 | #define AT91CAP9_ID_MPB0 3 /* MP Block Peripheral 0 */ | ||
27 | #define AT91CAP9_ID_MPB1 4 /* MP Block Peripheral 1 */ | ||
28 | #define AT91CAP9_ID_MPB2 5 /* MP Block Peripheral 2 */ | ||
29 | #define AT91CAP9_ID_MPB3 6 /* MP Block Peripheral 3 */ | ||
30 | #define AT91CAP9_ID_MPB4 7 /* MP Block Peripheral 4 */ | ||
31 | #define AT91CAP9_ID_US0 8 /* USART 0 */ | ||
32 | #define AT91CAP9_ID_US1 9 /* USART 1 */ | ||
33 | #define AT91CAP9_ID_US2 10 /* USART 2 */ | ||
34 | #define AT91CAP9_ID_MCI0 11 /* Multimedia Card Interface 0 */ | ||
35 | #define AT91CAP9_ID_MCI1 12 /* Multimedia Card Interface 1 */ | ||
36 | #define AT91CAP9_ID_CAN 13 /* CAN */ | ||
37 | #define AT91CAP9_ID_TWI 14 /* Two-Wire Interface */ | ||
38 | #define AT91CAP9_ID_SPI0 15 /* Serial Peripheral Interface 0 */ | ||
39 | #define AT91CAP9_ID_SPI1 16 /* Serial Peripheral Interface 0 */ | ||
40 | #define AT91CAP9_ID_SSC0 17 /* Serial Synchronous Controller 0 */ | ||
41 | #define AT91CAP9_ID_SSC1 18 /* Serial Synchronous Controller 1 */ | ||
42 | #define AT91CAP9_ID_AC97C 19 /* AC97 Controller */ | ||
43 | #define AT91CAP9_ID_TCB 20 /* Timer Counter 0, 1 and 2 */ | ||
44 | #define AT91CAP9_ID_PWMC 21 /* Pulse Width Modulation Controller */ | ||
45 | #define AT91CAP9_ID_EMAC 22 /* Ethernet */ | ||
46 | #define AT91CAP9_ID_AESTDES 23 /* Advanced Encryption Standard, Triple DES */ | ||
47 | #define AT91CAP9_ID_ADC 24 /* Analog-to-Digital Converter */ | ||
48 | #define AT91CAP9_ID_ISI 25 /* Image Sensor Interface */ | ||
49 | #define AT91CAP9_ID_LCDC 26 /* LCD Controller */ | ||
50 | #define AT91CAP9_ID_DMA 27 /* DMA Controller */ | ||
51 | #define AT91CAP9_ID_UDPHS 28 /* USB High Speed Device Port */ | ||
52 | #define AT91CAP9_ID_UHP 29 /* USB Host Port */ | ||
53 | #define AT91CAP9_ID_IRQ0 30 /* Advanced Interrupt Controller (IRQ0) */ | ||
54 | #define AT91CAP9_ID_IRQ1 31 /* Advanced Interrupt Controller (IRQ1) */ | ||
55 | |||
56 | /* | ||
57 | * User Peripheral physical base addresses. | ||
58 | */ | ||
59 | #define AT91CAP9_BASE_UDPHS 0xfff78000 | ||
60 | #define AT91CAP9_BASE_TCB0 0xfff7c000 | ||
61 | #define AT91CAP9_BASE_TC0 0xfff7c000 | ||
62 | #define AT91CAP9_BASE_TC1 0xfff7c040 | ||
63 | #define AT91CAP9_BASE_TC2 0xfff7c080 | ||
64 | #define AT91CAP9_BASE_MCI0 0xfff80000 | ||
65 | #define AT91CAP9_BASE_MCI1 0xfff84000 | ||
66 | #define AT91CAP9_BASE_TWI 0xfff88000 | ||
67 | #define AT91CAP9_BASE_US0 0xfff8c000 | ||
68 | #define AT91CAP9_BASE_US1 0xfff90000 | ||
69 | #define AT91CAP9_BASE_US2 0xfff94000 | ||
70 | #define AT91CAP9_BASE_SSC0 0xfff98000 | ||
71 | #define AT91CAP9_BASE_SSC1 0xfff9c000 | ||
72 | #define AT91CAP9_BASE_AC97C 0xfffa0000 | ||
73 | #define AT91CAP9_BASE_SPI0 0xfffa4000 | ||
74 | #define AT91CAP9_BASE_SPI1 0xfffa8000 | ||
75 | #define AT91CAP9_BASE_CAN 0xfffac000 | ||
76 | #define AT91CAP9_BASE_PWMC 0xfffb8000 | ||
77 | #define AT91CAP9_BASE_EMAC 0xfffbc000 | ||
78 | #define AT91CAP9_BASE_ADC 0xfffc0000 | ||
79 | #define AT91CAP9_BASE_ISI 0xfffc4000 | ||
80 | #define AT91_BASE_SYS 0xffffe200 | ||
81 | |||
82 | /* | ||
83 | * System Peripherals (offset from AT91_BASE_SYS) | ||
84 | */ | ||
85 | #define AT91_ECC (0xffffe200 - AT91_BASE_SYS) | ||
86 | #define AT91_BCRAMC (0xffffe400 - AT91_BASE_SYS) | ||
87 | #define AT91_DDRSDRC (0xffffe600 - AT91_BASE_SYS) | ||
88 | #define AT91_SMC (0xffffe800 - AT91_BASE_SYS) | ||
89 | #define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) | ||
90 | #define AT91_CCFG (0xffffeb10 - AT91_BASE_SYS) | ||
91 | #define AT91_DMA (0xffffec00 - AT91_BASE_SYS) | ||
92 | #define AT91_DBGU (0xffffee00 - AT91_BASE_SYS) | ||
93 | #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) | ||
94 | #define AT91_PIOA (0xfffff200 - AT91_BASE_SYS) | ||
95 | #define AT91_PIOB (0xfffff400 - AT91_BASE_SYS) | ||
96 | #define AT91_PIOC (0xfffff600 - AT91_BASE_SYS) | ||
97 | #define AT91_PIOD (0xfffff800 - AT91_BASE_SYS) | ||
98 | #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) | ||
99 | #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) | ||
100 | #define AT91_SHDC (0xfffffd10 - AT91_BASE_SYS) | ||
101 | #define AT91_RTT (0xfffffd20 - AT91_BASE_SYS) | ||
102 | #define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) | ||
103 | #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) | ||
104 | #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) | ||
105 | |||
106 | /* | ||
107 | * Internal Memory. | ||
108 | */ | ||
109 | #define AT91CAP9_SRAM_BASE 0x00100000 /* Internal SRAM base address */ | ||
110 | #define AT91CAP9_SRAM_SIZE (32 * SZ_1K) /* Internal SRAM size (32Kb) */ | ||
111 | |||
112 | #define AT91CAP9_ROM_BASE 0x00400000 /* Internal ROM base address */ | ||
113 | #define AT91CAP9_ROM_SIZE (32 * SZ_1K) /* Internal ROM size (32Kb) */ | ||
114 | |||
115 | #define AT91CAP9_LCDC_BASE 0x00500000 /* LCD Controller */ | ||
116 | #define AT91CAP9_UDPHS_BASE 0x00600000 /* USB High Speed Device Port */ | ||
117 | #define AT91CAP9_UHP_BASE 0x00700000 /* USB Host controller */ | ||
118 | |||
119 | #define CONFIG_DRAM_BASE AT91_CHIPSELECT_6 | ||
120 | |||
121 | #endif | ||
diff --git a/include/asm-arm/arch-at91/at91cap9_matrix.h b/include/asm-arm/arch-at91/at91cap9_matrix.h new file mode 100644 index 000000000000..a641686b6c3d --- /dev/null +++ b/include/asm-arm/arch-at91/at91cap9_matrix.h | |||
@@ -0,0 +1,132 @@ | |||
1 | /* | ||
2 | * include/asm-arm/arch-at91/at91cap9_matrix.h | ||
3 | * | ||
4 | * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com> | ||
5 | * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com> | ||
6 | * Copyright (C) 2006 Atmel Corporation. | ||
7 | * | ||
8 | * Memory Controllers (MATRIX, EBI) - System peripherals registers. | ||
9 | * Based on AT91CAP9 datasheet revision B (Preliminary). | ||
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 as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | */ | ||
16 | |||
17 | #ifndef AT91CAP9_MATRIX_H | ||
18 | #define AT91CAP9_MATRIX_H | ||
19 | |||
20 | #define AT91_MATRIX_MCFG0 (AT91_MATRIX + 0x00) /* Master Configuration Register 0 */ | ||
21 | #define AT91_MATRIX_MCFG1 (AT91_MATRIX + 0x04) /* Master Configuration Register 1 */ | ||
22 | #define AT91_MATRIX_MCFG2 (AT91_MATRIX + 0x08) /* Master Configuration Register 2 */ | ||
23 | #define AT91_MATRIX_MCFG3 (AT91_MATRIX + 0x0C) /* Master Configuration Register 3 */ | ||
24 | #define AT91_MATRIX_MCFG4 (AT91_MATRIX + 0x10) /* Master Configuration Register 4 */ | ||
25 | #define AT91_MATRIX_MCFG5 (AT91_MATRIX + 0x14) /* Master Configuration Register 5 */ | ||
26 | #define AT91_MATRIX_MCFG6 (AT91_MATRIX + 0x18) /* Master Configuration Register 6 */ | ||
27 | #define AT91_MATRIX_MCFG7 (AT91_MATRIX + 0x1C) /* Master Configuration Register 7 */ | ||
28 | #define AT91_MATRIX_MCFG8 (AT91_MATRIX + 0x20) /* Master Configuration Register 8 */ | ||
29 | #define AT91_MATRIX_MCFG9 (AT91_MATRIX + 0x24) /* Master Configuration Register 9 */ | ||
30 | #define AT91_MATRIX_MCFG10 (AT91_MATRIX + 0x28) /* Master Configuration Register 10 */ | ||
31 | #define AT91_MATRIX_MCFG11 (AT91_MATRIX + 0x2C) /* Master Configuration Register 11 */ | ||
32 | #define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */ | ||
33 | #define AT91_MATRIX_ULBT_INFINITE (0 << 0) | ||
34 | #define AT91_MATRIX_ULBT_SINGLE (1 << 0) | ||
35 | #define AT91_MATRIX_ULBT_FOUR (2 << 0) | ||
36 | #define AT91_MATRIX_ULBT_EIGHT (3 << 0) | ||
37 | #define AT91_MATRIX_ULBT_SIXTEEN (4 << 0) | ||
38 | |||
39 | #define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x40) /* Slave Configuration Register 0 */ | ||
40 | #define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x44) /* Slave Configuration Register 1 */ | ||
41 | #define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x48) /* Slave Configuration Register 2 */ | ||
42 | #define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x4C) /* Slave Configuration Register 3 */ | ||
43 | #define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x50) /* Slave Configuration Register 4 */ | ||
44 | #define AT91_MATRIX_SCFG5 (AT91_MATRIX + 0x54) /* Slave Configuration Register 5 */ | ||
45 | #define AT91_MATRIX_SCFG6 (AT91_MATRIX + 0x58) /* Slave Configuration Register 6 */ | ||
46 | #define AT91_MATRIX_SCFG7 (AT91_MATRIX + 0x5C) /* Slave Configuration Register 7 */ | ||
47 | #define AT91_MATRIX_SCFG8 (AT91_MATRIX + 0x60) /* Slave Configuration Register 8 */ | ||
48 | #define AT91_MATRIX_SCFG9 (AT91_MATRIX + 0x64) /* Slave Configuration Register 9 */ | ||
49 | #define AT91_MATRIX_SLOT_CYCLE (0xff << 0) /* Maximum Number of Allowed Cycles for a Burst */ | ||
50 | #define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */ | ||
51 | #define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) | ||
52 | #define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16) | ||
53 | #define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) | ||
54 | #define AT91_MATRIX_FIXED_DEFMSTR (0xf << 18) /* Fixed Index of Default Master */ | ||
55 | #define AT91_MATRIX_ARBT (3 << 24) /* Arbitration Type */ | ||
56 | #define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24) | ||
57 | #define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24) | ||
58 | |||
59 | #define AT91_MATRIX_PRAS0 (AT91_MATRIX + 0x80) /* Priority Register A for Slave 0 */ | ||
60 | #define AT91_MATRIX_PRBS0 (AT91_MATRIX + 0x84) /* Priority Register B for Slave 0 */ | ||
61 | #define AT91_MATRIX_PRAS1 (AT91_MATRIX + 0x88) /* Priority Register A for Slave 1 */ | ||
62 | #define AT91_MATRIX_PRBS1 (AT91_MATRIX + 0x8C) /* Priority Register B for Slave 1 */ | ||
63 | #define AT91_MATRIX_PRAS2 (AT91_MATRIX + 0x90) /* Priority Register A for Slave 2 */ | ||
64 | #define AT91_MATRIX_PRBS2 (AT91_MATRIX + 0x94) /* Priority Register B for Slave 2 */ | ||
65 | #define AT91_MATRIX_PRAS3 (AT91_MATRIX + 0x98) /* Priority Register A for Slave 3 */ | ||
66 | #define AT91_MATRIX_PRBS3 (AT91_MATRIX + 0x9C) /* Priority Register B for Slave 3 */ | ||
67 | #define AT91_MATRIX_PRAS4 (AT91_MATRIX + 0xA0) /* Priority Register A for Slave 4 */ | ||
68 | #define AT91_MATRIX_PRBS4 (AT91_MATRIX + 0xA4) /* Priority Register B for Slave 4 */ | ||
69 | #define AT91_MATRIX_PRAS5 (AT91_MATRIX + 0xA8) /* Priority Register A for Slave 5 */ | ||
70 | #define AT91_MATRIX_PRBS5 (AT91_MATRIX + 0xAC) /* Priority Register B for Slave 5 */ | ||
71 | #define AT91_MATRIX_PRAS6 (AT91_MATRIX + 0xB0) /* Priority Register A for Slave 6 */ | ||
72 | #define AT91_MATRIX_PRBS6 (AT91_MATRIX + 0xB4) /* Priority Register B for Slave 6 */ | ||
73 | #define AT91_MATRIX_PRAS7 (AT91_MATRIX + 0xB8) /* Priority Register A for Slave 7 */ | ||
74 | #define AT91_MATRIX_PRBS7 (AT91_MATRIX + 0xBC) /* Priority Register B for Slave 7 */ | ||
75 | #define AT91_MATRIX_PRAS8 (AT91_MATRIX + 0xC0) /* Priority Register A for Slave 8 */ | ||
76 | #define AT91_MATRIX_PRBS8 (AT91_MATRIX + 0xC4) /* Priority Register B for Slave 8 */ | ||
77 | #define AT91_MATRIX_PRAS9 (AT91_MATRIX + 0xC8) /* Priority Register A for Slave 9 */ | ||
78 | #define AT91_MATRIX_PRBS9 (AT91_MATRIX + 0xCC) /* Priority Register B for Slave 9 */ | ||
79 | #define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */ | ||
80 | #define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */ | ||
81 | #define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */ | ||
82 | #define AT91_MATRIX_M3PR (3 << 12) /* Master 3 Priority */ | ||
83 | #define AT91_MATRIX_M4PR (3 << 16) /* Master 4 Priority */ | ||
84 | #define AT91_MATRIX_M5PR (3 << 20) /* Master 5 Priority */ | ||
85 | #define AT91_MATRIX_M6PR (3 << 24) /* Master 6 Priority */ | ||
86 | #define AT91_MATRIX_M7PR (3 << 28) /* Master 7 Priority */ | ||
87 | #define AT91_MATRIX_M8PR (3 << 0) /* Master 8 Priority (in Register B) */ | ||
88 | #define AT91_MATRIX_M9PR (3 << 4) /* Master 9 Priority (in Register B) */ | ||
89 | #define AT91_MATRIX_M10PR (3 << 8) /* Master 10 Priority (in Register B) */ | ||
90 | #define AT91_MATRIX_M11PR (3 << 12) /* Master 11 Priority (in Register B) */ | ||
91 | |||
92 | #define AT91_MATRIX_MRCR (AT91_MATRIX + 0x100) /* Master Remap Control Register */ | ||
93 | #define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */ | ||
94 | #define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ | ||
95 | #define AT91_MATRIX_RCB2 (1 << 2) | ||
96 | #define AT91_MATRIX_RCB3 (1 << 3) | ||
97 | #define AT91_MATRIX_RCB4 (1 << 4) | ||
98 | #define AT91_MATRIX_RCB5 (1 << 5) | ||
99 | #define AT91_MATRIX_RCB6 (1 << 6) | ||
100 | #define AT91_MATRIX_RCB7 (1 << 7) | ||
101 | #define AT91_MATRIX_RCB8 (1 << 8) | ||
102 | #define AT91_MATRIX_RCB9 (1 << 9) | ||
103 | #define AT91_MATRIX_RCB10 (1 << 10) | ||
104 | #define AT91_MATRIX_RCB11 (1 << 11) | ||
105 | |||
106 | #define AT91_MPBS0_SFR (AT91_MATRIX + 0x114) /* MPBlock Slave 0 Special Function Register */ | ||
107 | #define AT91_MPBS1_SFR (AT91_MATRIX + 0x11C) /* MPBlock Slave 1 Special Function Register */ | ||
108 | |||
109 | #define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x120) /* EBI Chip Select Assignment Register */ | ||
110 | #define AT91_MATRIX_EBI_CS1A (1 << 1) /* Chip Select 1 Assignment */ | ||
111 | #define AT91_MATRIX_EBI_CS1A_SMC (0 << 1) | ||
112 | #define AT91_MATRIX_EBI_CS1A_BCRAMC (1 << 1) | ||
113 | #define AT91_MATRIX_EBI_CS3A (1 << 3) /* Chip Select 3 Assignment */ | ||
114 | #define AT91_MATRIX_EBI_CS3A_SMC (0 << 3) | ||
115 | #define AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA (1 << 3) | ||
116 | #define AT91_MATRIX_EBI_CS4A (1 << 4) /* Chip Select 4 Assignment */ | ||
117 | #define AT91_MATRIX_EBI_CS4A_SMC (0 << 4) | ||
118 | #define AT91_MATRIX_EBI_CS4A_SMC_CF1 (1 << 4) | ||
119 | #define AT91_MATRIX_EBI_CS5A (1 << 5) /* Chip Select 5 Assignment */ | ||
120 | #define AT91_MATRIX_EBI_CS5A_SMC (0 << 5) | ||
121 | #define AT91_MATRIX_EBI_CS5A_SMC_CF2 (1 << 5) | ||
122 | #define AT91_MATRIX_EBI_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */ | ||
123 | #define AT91_MATRIX_EBI_DQSPDC (1 << 9) /* Data Qualifier Strobe Pull-Down Configuration */ | ||
124 | #define AT91_MATRIX_EBI_VDDIOMSEL (1 << 16) /* Memory voltage selection */ | ||
125 | #define AT91_MATRIX_EBI_VDDIOMSEL_1_8V (0 << 16) | ||
126 | #define AT91_MATRIX_EBI_VDDIOMSEL_3_3V (1 << 16) | ||
127 | |||
128 | #define AT91_MPBS2_SFR (AT91_MATRIX + 0x12C) /* MPBlock Slave 2 Special Function Register */ | ||
129 | #define AT91_MPBS3_SFR (AT91_MATRIX + 0x130) /* MPBlock Slave 3 Special Function Register */ | ||
130 | #define AT91_APB_SFR (AT91_MATRIX + 0x134) /* APB Bridge Special Function Register */ | ||
131 | |||
132 | #endif | ||
diff --git a/include/asm-arm/arch-at91/at91sam9260_matrix.h b/include/asm-arm/arch-at91/at91sam9260_matrix.h index aacb1e976422..a8e9fec6c735 100644 --- a/include/asm-arm/arch-at91/at91sam9260_matrix.h +++ b/include/asm-arm/arch-at91/at91sam9260_matrix.h | |||
@@ -67,7 +67,7 @@ | |||
67 | #define AT91_MATRIX_CS4A (1 << 4) /* Chip Select 4 Assignment */ | 67 | #define AT91_MATRIX_CS4A (1 << 4) /* Chip Select 4 Assignment */ |
68 | #define AT91_MATRIX_CS4A_SMC (0 << 4) | 68 | #define AT91_MATRIX_CS4A_SMC (0 << 4) |
69 | #define AT91_MATRIX_CS4A_SMC_CF1 (1 << 4) | 69 | #define AT91_MATRIX_CS4A_SMC_CF1 (1 << 4) |
70 | #define AT91_MATRIX_CS5A (1 << 5 ) /* Chip Select 5 Assignment */ | 70 | #define AT91_MATRIX_CS5A (1 << 5) /* Chip Select 5 Assignment */ |
71 | #define AT91_MATRIX_CS5A_SMC (0 << 5) | 71 | #define AT91_MATRIX_CS5A_SMC (0 << 5) |
72 | #define AT91_MATRIX_CS5A_SMC_CF2 (1 << 5) | 72 | #define AT91_MATRIX_CS5A_SMC_CF2 (1 << 5) |
73 | #define AT91_MATRIX_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */ | 73 | #define AT91_MATRIX_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */ |
diff --git a/include/asm-arm/arch-at91/at91sam9263_matrix.h b/include/asm-arm/arch-at91/at91sam9263_matrix.h index 6fc6e4be624e..72f6e668e414 100644 --- a/include/asm-arm/arch-at91/at91sam9263_matrix.h +++ b/include/asm-arm/arch-at91/at91sam9263_matrix.h | |||
@@ -44,7 +44,7 @@ | |||
44 | #define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) | 44 | #define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) |
45 | #define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16) | 45 | #define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16) |
46 | #define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) | 46 | #define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) |
47 | #define AT91_MATRIX_FIXED_DEFMSTR (7 << 18) /* Fixed Index of Default Master */ | 47 | #define AT91_MATRIX_FIXED_DEFMSTR (0xf << 18) /* Fixed Index of Default Master */ |
48 | #define AT91_MATRIX_ARBT (3 << 24) /* Arbitration Type */ | 48 | #define AT91_MATRIX_ARBT (3 << 24) /* Arbitration Type */ |
49 | #define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24) | 49 | #define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24) |
50 | #define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24) | 50 | #define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24) |
diff --git a/include/asm-arm/arch-at91/at91sam9rl_matrix.h b/include/asm-arm/arch-at91/at91sam9rl_matrix.h index b15f11b7c08d..84224174e6a1 100644 --- a/include/asm-arm/arch-at91/at91sam9rl_matrix.h +++ b/include/asm-arm/arch-at91/at91sam9rl_matrix.h | |||
@@ -38,7 +38,7 @@ | |||
38 | #define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) | 38 | #define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) |
39 | #define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16) | 39 | #define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16) |
40 | #define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) | 40 | #define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) |
41 | #define AT91_MATRIX_FIXED_DEFMSTR (7 << 18) /* Fixed Index of Default Master */ | 41 | #define AT91_MATRIX_FIXED_DEFMSTR (0xf << 18) /* Fixed Index of Default Master */ |
42 | #define AT91_MATRIX_ARBT (3 << 24) /* Arbitration Type */ | 42 | #define AT91_MATRIX_ARBT (3 << 24) /* Arbitration Type */ |
43 | #define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24) | 43 | #define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24) |
44 | #define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24) | 44 | #define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24) |
diff --git a/include/asm-arm/arch-at91/board.h b/include/asm-arm/arch-at91/board.h index 79054965baa6..55b07bd5316c 100644 --- a/include/asm-arm/arch-at91/board.h +++ b/include/asm-arm/arch-at91/board.h | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/mtd/partitions.h> | 34 | #include <linux/mtd/partitions.h> |
35 | #include <linux/device.h> | 35 | #include <linux/device.h> |
36 | #include <linux/i2c.h> | 36 | #include <linux/i2c.h> |
37 | #include <linux/leds.h> | ||
37 | #include <linux/spi/spi.h> | 38 | #include <linux/spi/spi.h> |
38 | 39 | ||
39 | /* USB Device */ | 40 | /* USB Device */ |
@@ -71,7 +72,7 @@ struct at91_eth_data { | |||
71 | }; | 72 | }; |
72 | extern void __init at91_add_device_eth(struct at91_eth_data *data); | 73 | extern void __init at91_add_device_eth(struct at91_eth_data *data); |
73 | 74 | ||
74 | #if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263) | 75 | #if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91CAP9) |
75 | #define eth_platform_data at91_eth_data | 76 | #define eth_platform_data at91_eth_data |
76 | #endif | 77 | #endif |
77 | 78 | ||
@@ -101,13 +102,23 @@ extern void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_de | |||
101 | extern void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices); | 102 | extern void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices); |
102 | 103 | ||
103 | /* Serial */ | 104 | /* Serial */ |
105 | #define ATMEL_UART_CTS 0x01 | ||
106 | #define ATMEL_UART_RTS 0x02 | ||
107 | #define ATMEL_UART_DSR 0x04 | ||
108 | #define ATMEL_UART_DTR 0x08 | ||
109 | #define ATMEL_UART_DCD 0x10 | ||
110 | #define ATMEL_UART_RI 0x20 | ||
111 | |||
112 | extern void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins); | ||
113 | extern void __init at91_set_serial_console(unsigned portnr); | ||
114 | |||
104 | struct at91_uart_config { | 115 | struct at91_uart_config { |
105 | unsigned short console_tty; /* tty number of serial console */ | 116 | unsigned short console_tty; /* tty number of serial console */ |
106 | unsigned short nr_tty; /* number of serial tty's */ | 117 | unsigned short nr_tty; /* number of serial tty's */ |
107 | short tty_map[]; /* map UART to tty number */ | 118 | short tty_map[]; /* map UART to tty number */ |
108 | }; | 119 | }; |
109 | extern struct platform_device *atmel_default_console_device; | 120 | extern struct platform_device *atmel_default_console_device; |
110 | extern void __init at91_init_serial(struct at91_uart_config *config); | 121 | extern void __init __deprecated at91_init_serial(struct at91_uart_config *config); |
111 | 122 | ||
112 | struct atmel_uart_data { | 123 | struct atmel_uart_data { |
113 | short use_dma_tx; /* use transmit DMA? */ | 124 | short use_dma_tx; /* use transmit DMA? */ |
@@ -116,6 +127,23 @@ struct atmel_uart_data { | |||
116 | }; | 127 | }; |
117 | extern void __init at91_add_device_serial(void); | 128 | extern void __init at91_add_device_serial(void); |
118 | 129 | ||
130 | /* | ||
131 | * SSC -- accessed through ssc_request(id). Drivers don't bind to SSC | ||
132 | * platform devices. Their SSC ID is part of their configuration data, | ||
133 | * along with information about which SSC signals they should use. | ||
134 | */ | ||
135 | #define ATMEL_SSC_TK 0x01 | ||
136 | #define ATMEL_SSC_TF 0x02 | ||
137 | #define ATMEL_SSC_TD 0x04 | ||
138 | #define ATMEL_SSC_TX (ATMEL_SSC_TK | ATMEL_SSC_TF | ATMEL_SSC_TD) | ||
139 | |||
140 | #define ATMEL_SSC_RK 0x10 | ||
141 | #define ATMEL_SSC_RF 0x20 | ||
142 | #define ATMEL_SSC_RD 0x40 | ||
143 | #define ATMEL_SSC_RX (ATMEL_SSC_RK | ATMEL_SSC_RF | ATMEL_SSC_RD) | ||
144 | |||
145 | extern void __init at91_add_device_ssc(unsigned id, unsigned pins); | ||
146 | |||
119 | /* LCD Controller */ | 147 | /* LCD Controller */ |
120 | struct atmel_lcdfb_info; | 148 | struct atmel_lcdfb_info; |
121 | extern void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data); | 149 | extern void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data); |
@@ -126,10 +154,12 @@ struct atmel_ac97_data { | |||
126 | }; | 154 | }; |
127 | extern void __init at91_add_device_ac97(struct atmel_ac97_data *data); | 155 | extern void __init at91_add_device_ac97(struct atmel_ac97_data *data); |
128 | 156 | ||
157 | /* ISI */ | ||
158 | extern void __init at91_add_device_isi(void); | ||
159 | |||
129 | /* LEDs */ | 160 | /* LEDs */ |
130 | extern u8 at91_leds_cpu; | ||
131 | extern u8 at91_leds_timer; | ||
132 | extern void __init at91_init_leds(u8 cpu_led, u8 timer_led); | 161 | extern void __init at91_init_leds(u8 cpu_led, u8 timer_led); |
162 | extern void __init at91_gpio_leds(struct gpio_led *leds, int nr); | ||
133 | 163 | ||
134 | /* FIXME: this needs a better location, but gets stuff building again */ | 164 | /* FIXME: this needs a better location, but gets stuff building again */ |
135 | extern int at91_suspend_entering_slow_clock(void); | 165 | extern int at91_suspend_entering_slow_clock(void); |
diff --git a/include/asm-arm/arch-at91/cpu.h b/include/asm-arm/arch-at91/cpu.h index 080cbb401a87..7145166826a2 100644 --- a/include/asm-arm/arch-at91/cpu.h +++ b/include/asm-arm/arch-at91/cpu.h | |||
@@ -21,13 +21,13 @@ | |||
21 | #define ARCH_ID_AT91SAM9260 0x019803a0 | 21 | #define ARCH_ID_AT91SAM9260 0x019803a0 |
22 | #define ARCH_ID_AT91SAM9261 0x019703a0 | 22 | #define ARCH_ID_AT91SAM9261 0x019703a0 |
23 | #define ARCH_ID_AT91SAM9263 0x019607a0 | 23 | #define ARCH_ID_AT91SAM9263 0x019607a0 |
24 | #define ARCH_ID_AT91SAM9RL64 0x019b03a0 | ||
25 | #define ARCH_ID_AT91CAP9 0x039A03A0 | ||
24 | 26 | ||
25 | #define ARCH_ID_AT91SAM9XE128 0x329973a0 | 27 | #define ARCH_ID_AT91SAM9XE128 0x329973a0 |
26 | #define ARCH_ID_AT91SAM9XE256 0x329a93a0 | 28 | #define ARCH_ID_AT91SAM9XE256 0x329a93a0 |
27 | #define ARCH_ID_AT91SAM9XE512 0x329aa3a0 | 29 | #define ARCH_ID_AT91SAM9XE512 0x329aa3a0 |
28 | 30 | ||
29 | #define ARCH_ID_AT91SAM9RL64 0x019b03a0 | ||
30 | |||
31 | #define ARCH_ID_AT91M40800 0x14080044 | 31 | #define ARCH_ID_AT91M40800 0x14080044 |
32 | #define ARCH_ID_AT91R40807 0x44080746 | 32 | #define ARCH_ID_AT91R40807 0x44080746 |
33 | #define ARCH_ID_AT91M40807 0x14080745 | 33 | #define ARCH_ID_AT91M40807 0x14080745 |
@@ -81,6 +81,11 @@ static inline unsigned long at91_arch_identify(void) | |||
81 | #define cpu_is_at91sam9rl() (0) | 81 | #define cpu_is_at91sam9rl() (0) |
82 | #endif | 82 | #endif |
83 | 83 | ||
84 | #ifdef CONFIG_ARCH_AT91CAP9 | ||
85 | #define cpu_is_at91cap9() (at91_cpu_identify() == ARCH_ID_AT91CAP9) | ||
86 | #else | ||
87 | #define cpu_is_at91cap9() (0) | ||
88 | #endif | ||
84 | 89 | ||
85 | /* | 90 | /* |
86 | * Since this is ARM, we will never run on any AVR32 CPU. But these | 91 | * Since this is ARM, we will never run on any AVR32 CPU. But these |
diff --git a/include/asm-arm/arch-at91/entry-macro.S b/include/asm-arm/arch-at91/entry-macro.S index cc1d850a0788..1005eee6219b 100644 --- a/include/asm-arm/arch-at91/entry-macro.S +++ b/include/asm-arm/arch-at91/entry-macro.S | |||
@@ -17,13 +17,13 @@ | |||
17 | .endm | 17 | .endm |
18 | 18 | ||
19 | .macro get_irqnr_preamble, base, tmp | 19 | .macro get_irqnr_preamble, base, tmp |
20 | ldr \base, =(AT91_VA_BASE_SYS + AT91_AIC) @ base virtual address of AIC peripheral | ||
20 | .endm | 21 | .endm |
21 | 22 | ||
22 | .macro arch_ret_to_user, tmp1, tmp2 | 23 | .macro arch_ret_to_user, tmp1, tmp2 |
23 | .endm | 24 | .endm |
24 | 25 | ||
25 | .macro get_irqnr_and_base, irqnr, irqstat, base, tmp | 26 | .macro get_irqnr_and_base, irqnr, irqstat, base, tmp |
26 | ldr \base, =(AT91_VA_BASE_SYS + AT91_AIC) @ base virtual address of AIC peripheral | ||
27 | ldr \irqnr, [\base, #(AT91_AIC_IVR - AT91_AIC)] @ read IRQ vector register: de-asserts nIRQ to processor (and clears interrupt) | 27 | ldr \irqnr, [\base, #(AT91_AIC_IVR - AT91_AIC)] @ read IRQ vector register: de-asserts nIRQ to processor (and clears interrupt) |
28 | ldr \irqstat, [\base, #(AT91_AIC_ISR - AT91_AIC)] @ read interrupt source number | 28 | ldr \irqstat, [\base, #(AT91_AIC_ISR - AT91_AIC)] @ read interrupt source number |
29 | teq \irqstat, #0 @ ISR is 0 when no current interrupt, or spurious interrupt | 29 | teq \irqstat, #0 @ ISR is 0 when no current interrupt, or spurious interrupt |
diff --git a/include/asm-arm/arch-at91/hardware.h b/include/asm-arm/arch-at91/hardware.h index 8f1cdd38a969..2c826d8247a3 100644 --- a/include/asm-arm/arch-at91/hardware.h +++ b/include/asm-arm/arch-at91/hardware.h | |||
@@ -26,6 +26,8 @@ | |||
26 | #include <asm/arch/at91sam9263.h> | 26 | #include <asm/arch/at91sam9263.h> |
27 | #elif defined(CONFIG_ARCH_AT91SAM9RL) | 27 | #elif defined(CONFIG_ARCH_AT91SAM9RL) |
28 | #include <asm/arch/at91sam9rl.h> | 28 | #include <asm/arch/at91sam9rl.h> |
29 | #elif defined(CONFIG_ARCH_AT91CAP9) | ||
30 | #include <asm/arch/at91cap9.h> | ||
29 | #elif defined(CONFIG_ARCH_AT91X40) | 31 | #elif defined(CONFIG_ARCH_AT91X40) |
30 | #include <asm/arch/at91x40.h> | 32 | #include <asm/arch/at91x40.h> |
31 | #else | 33 | #else |
diff --git a/include/asm-arm/arch-at91/timex.h b/include/asm-arm/arch-at91/timex.h index a310698fb4da..f1933b0fa43f 100644 --- a/include/asm-arm/arch-at91/timex.h +++ b/include/asm-arm/arch-at91/timex.h | |||
@@ -42,6 +42,11 @@ | |||
42 | #define AT91SAM9_MASTER_CLOCK 100000000 | 42 | #define AT91SAM9_MASTER_CLOCK 100000000 |
43 | #define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) | 43 | #define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) |
44 | 44 | ||
45 | #elif defined(CONFIG_ARCH_AT91CAP9) | ||
46 | |||
47 | #define AT91CAP9_MASTER_CLOCK 100000000 | ||
48 | #define CLOCK_TICK_RATE (AT91CAP9_MASTER_CLOCK/16) | ||
49 | |||
45 | #elif defined(CONFIG_ARCH_AT91X40) | 50 | #elif defined(CONFIG_ARCH_AT91X40) |
46 | 51 | ||
47 | #define AT91X40_MASTER_CLOCK 40000000 | 52 | #define AT91X40_MASTER_CLOCK 40000000 |
diff --git a/include/asm-arm/arch-ep93xx/gpio.h b/include/asm-arm/arch-ep93xx/gpio.h index 1ee14a14cba0..9b1864bbd9a8 100644 --- a/include/asm-arm/arch-ep93xx/gpio.h +++ b/include/asm-arm/arch-ep93xx/gpio.h | |||
@@ -5,16 +5,6 @@ | |||
5 | #ifndef __ASM_ARCH_GPIO_H | 5 | #ifndef __ASM_ARCH_GPIO_H |
6 | #define __ASM_ARCH_GPIO_H | 6 | #define __ASM_ARCH_GPIO_H |
7 | 7 | ||
8 | #define GPIO_IN 0 | ||
9 | #define GPIO_OUT 1 | ||
10 | |||
11 | #define EP93XX_GPIO_LOW 0 | ||
12 | #define EP93XX_GPIO_HIGH 1 | ||
13 | |||
14 | extern void gpio_line_config(int line, int direction); | ||
15 | extern int gpio_line_get(int line); | ||
16 | extern void gpio_line_set(int line, int value); | ||
17 | |||
18 | /* GPIO port A. */ | 8 | /* GPIO port A. */ |
19 | #define EP93XX_GPIO_LINE_A(x) ((x) + 0) | 9 | #define EP93XX_GPIO_LINE_A(x) ((x) + 0) |
20 | #define EP93XX_GPIO_LINE_EGPIO0 EP93XX_GPIO_LINE_A(0) | 10 | #define EP93XX_GPIO_LINE_EGPIO0 EP93XX_GPIO_LINE_A(0) |
@@ -38,7 +28,7 @@ extern void gpio_line_set(int line, int value); | |||
38 | #define EP93XX_GPIO_LINE_EGPIO15 EP93XX_GPIO_LINE_B(7) | 28 | #define EP93XX_GPIO_LINE_EGPIO15 EP93XX_GPIO_LINE_B(7) |
39 | 29 | ||
40 | /* GPIO port C. */ | 30 | /* GPIO port C. */ |
41 | #define EP93XX_GPIO_LINE_C(x) ((x) + 16) | 31 | #define EP93XX_GPIO_LINE_C(x) ((x) + 40) |
42 | #define EP93XX_GPIO_LINE_ROW0 EP93XX_GPIO_LINE_C(0) | 32 | #define EP93XX_GPIO_LINE_ROW0 EP93XX_GPIO_LINE_C(0) |
43 | #define EP93XX_GPIO_LINE_ROW1 EP93XX_GPIO_LINE_C(1) | 33 | #define EP93XX_GPIO_LINE_ROW1 EP93XX_GPIO_LINE_C(1) |
44 | #define EP93XX_GPIO_LINE_ROW2 EP93XX_GPIO_LINE_C(2) | 34 | #define EP93XX_GPIO_LINE_ROW2 EP93XX_GPIO_LINE_C(2) |
@@ -71,7 +61,7 @@ extern void gpio_line_set(int line, int value); | |||
71 | #define EP93XX_GPIO_LINE_IDEDA2 EP93XX_GPIO_LINE_E(7) | 61 | #define EP93XX_GPIO_LINE_IDEDA2 EP93XX_GPIO_LINE_E(7) |
72 | 62 | ||
73 | /* GPIO port F. */ | 63 | /* GPIO port F. */ |
74 | #define EP93XX_GPIO_LINE_F(x) ((x) + 40) | 64 | #define EP93XX_GPIO_LINE_F(x) ((x) + 16) |
75 | #define EP93XX_GPIO_LINE_WP EP93XX_GPIO_LINE_F(0) | 65 | #define EP93XX_GPIO_LINE_WP EP93XX_GPIO_LINE_F(0) |
76 | #define EP93XX_GPIO_LINE_MCCD1 EP93XX_GPIO_LINE_F(1) | 66 | #define EP93XX_GPIO_LINE_MCCD1 EP93XX_GPIO_LINE_F(1) |
77 | #define EP93XX_GPIO_LINE_MCCD2 EP93XX_GPIO_LINE_F(2) | 67 | #define EP93XX_GPIO_LINE_MCCD2 EP93XX_GPIO_LINE_F(2) |
@@ -103,5 +93,49 @@ extern void gpio_line_set(int line, int value); | |||
103 | #define EP93XX_GPIO_LINE_DD6 EP93XX_GPIO_LINE_H(6) | 93 | #define EP93XX_GPIO_LINE_DD6 EP93XX_GPIO_LINE_H(6) |
104 | #define EP93XX_GPIO_LINE_DD7 EP93XX_GPIO_LINE_H(7) | 94 | #define EP93XX_GPIO_LINE_DD7 EP93XX_GPIO_LINE_H(7) |
105 | 95 | ||
96 | /* maximum value for gpio line identifiers */ | ||
97 | #define EP93XX_GPIO_LINE_MAX EP93XX_GPIO_LINE_H(7) | ||
98 | |||
99 | /* maximum value for irq capable line identifiers */ | ||
100 | #define EP93XX_GPIO_LINE_MAX_IRQ EP93XX_GPIO_LINE_F(7) | ||
101 | |||
102 | /* new generic GPIO API - see Documentation/gpio.txt */ | ||
103 | |||
104 | static inline int gpio_request(unsigned gpio, const char *label) | ||
105 | { | ||
106 | if (gpio > EP93XX_GPIO_LINE_MAX) | ||
107 | return -EINVAL; | ||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | static inline void gpio_free(unsigned gpio) | ||
112 | { | ||
113 | } | ||
114 | |||
115 | int gpio_direction_input(unsigned gpio); | ||
116 | int gpio_direction_output(unsigned gpio, int value); | ||
117 | int gpio_get_value(unsigned gpio); | ||
118 | void gpio_set_value(unsigned gpio, int value); | ||
119 | |||
120 | #include <asm-generic/gpio.h> /* cansleep wrappers */ | ||
121 | |||
122 | /* | ||
123 | * Map GPIO A0..A7 (0..7) to irq 64..71, | ||
124 | * B0..B7 (7..15) to irq 72..79, and | ||
125 | * F0..F7 (16..24) to irq 80..87. | ||
126 | */ | ||
127 | |||
128 | static inline int gpio_to_irq(unsigned gpio) | ||
129 | { | ||
130 | if (gpio <= EP93XX_GPIO_LINE_MAX_IRQ) | ||
131 | return 64 + gpio; | ||
132 | |||
133 | return -EINVAL; | ||
134 | } | ||
135 | |||
136 | static inline int irq_to_gpio(unsigned irq) | ||
137 | { | ||
138 | return irq - gpio_to_irq(0); | ||
139 | } | ||
106 | 140 | ||
107 | #endif | 141 | #endif |
diff --git a/include/asm-arm/arch-ep93xx/irqs.h b/include/asm-arm/arch-ep93xx/irqs.h index 2a8c63638c5e..53d4a68bfc88 100644 --- a/include/asm-arm/arch-ep93xx/irqs.h +++ b/include/asm-arm/arch-ep93xx/irqs.h | |||
@@ -67,12 +67,6 @@ | |||
67 | #define IRQ_EP93XX_SAI 60 | 67 | #define IRQ_EP93XX_SAI 60 |
68 | #define EP93XX_VIC2_VALID_IRQ_MASK 0x1fffffff | 68 | #define EP93XX_VIC2_VALID_IRQ_MASK 0x1fffffff |
69 | 69 | ||
70 | /* | ||
71 | * Map GPIO A0..A7 to irq 64..71, B0..B7 to 72..79, and | ||
72 | * F0..F7 to 80..87. | ||
73 | */ | ||
74 | #define IRQ_EP93XX_GPIO(x) (64 + (((x) + (((x) >> 2) & 8)) & 0x1f)) | ||
75 | |||
76 | #define NR_EP93XX_IRQS (64 + 24) | 70 | #define NR_EP93XX_IRQS (64 + 24) |
77 | 71 | ||
78 | #define EP93XX_BOARD_IRQ(x) (NR_EP93XX_IRQS + (x)) | 72 | #define EP93XX_BOARD_IRQ(x) (NR_EP93XX_IRQS + (x)) |
diff --git a/include/asm-arm/arch-ixp4xx/io.h b/include/asm-arm/arch-ixp4xx/io.h index eeeea90cd5a9..9c5d2357aff3 100644 --- a/include/asm-arm/arch-ixp4xx/io.h +++ b/include/asm-arm/arch-ixp4xx/io.h | |||
@@ -61,13 +61,13 @@ __ixp4xx_ioremap(unsigned long addr, size_t size, unsigned int mtype) | |||
61 | if((addr < PCIBIOS_MIN_MEM) || (addr > 0x4fffffff)) | 61 | if((addr < PCIBIOS_MIN_MEM) || (addr > 0x4fffffff)) |
62 | return __arm_ioremap(addr, size, mtype); | 62 | return __arm_ioremap(addr, size, mtype); |
63 | 63 | ||
64 | return (void *)addr; | 64 | return (void __iomem *)addr; |
65 | } | 65 | } |
66 | 66 | ||
67 | static inline void | 67 | static inline void |
68 | __ixp4xx_iounmap(void __iomem *addr) | 68 | __ixp4xx_iounmap(void __iomem *addr) |
69 | { | 69 | { |
70 | if ((u32)addr >= VMALLOC_START) | 70 | if ((__force u32)addr >= VMALLOC_START) |
71 | __iounmap(addr); | 71 | __iounmap(addr); |
72 | } | 72 | } |
73 | 73 | ||
@@ -141,9 +141,9 @@ __ixp4xx_writesw(volatile void __iomem *bus_addr, const u16 *vaddr, int count) | |||
141 | static inline void | 141 | static inline void |
142 | __ixp4xx_writel(u32 value, volatile void __iomem *p) | 142 | __ixp4xx_writel(u32 value, volatile void __iomem *p) |
143 | { | 143 | { |
144 | u32 addr = (u32)p; | 144 | u32 addr = (__force u32)p; |
145 | if (addr >= VMALLOC_START) { | 145 | if (addr >= VMALLOC_START) { |
146 | __raw_writel(value, addr); | 146 | __raw_writel(value, p); |
147 | return; | 147 | return; |
148 | } | 148 | } |
149 | 149 | ||
@@ -208,11 +208,11 @@ __ixp4xx_readsw(const volatile void __iomem *bus_addr, u16 *vaddr, u32 count) | |||
208 | static inline unsigned long | 208 | static inline unsigned long |
209 | __ixp4xx_readl(const volatile void __iomem *p) | 209 | __ixp4xx_readl(const volatile void __iomem *p) |
210 | { | 210 | { |
211 | u32 addr = (u32)p; | 211 | u32 addr = (__force u32)p; |
212 | u32 data; | 212 | u32 data; |
213 | 213 | ||
214 | if (addr >= VMALLOC_START) | 214 | if (addr >= VMALLOC_START) |
215 | return __raw_readl(addr); | 215 | return __raw_readl(p); |
216 | 216 | ||
217 | if (ixp4xx_pci_read(addr, NP_CMD_MEMREAD, &data)) | 217 | if (ixp4xx_pci_read(addr, NP_CMD_MEMREAD, &data)) |
218 | return 0xffffffff; | 218 | return 0xffffffff; |
@@ -438,7 +438,7 @@ __ixp4xx_ioread32(const void __iomem *addr) | |||
438 | return (unsigned int)__ixp4xx_inl(port & PIO_MASK); | 438 | return (unsigned int)__ixp4xx_inl(port & PIO_MASK); |
439 | else { | 439 | else { |
440 | #ifndef CONFIG_IXP4XX_INDIRECT_PCI | 440 | #ifndef CONFIG_IXP4XX_INDIRECT_PCI |
441 | return le32_to_cpu(__raw_readl((u32)port)); | 441 | return le32_to_cpu((__force __le32)__raw_readl(addr)); |
442 | #else | 442 | #else |
443 | return (unsigned int)__ixp4xx_readl(addr); | 443 | return (unsigned int)__ixp4xx_readl(addr); |
444 | #endif | 444 | #endif |
@@ -523,7 +523,7 @@ __ixp4xx_iowrite32(u32 value, void __iomem *addr) | |||
523 | __ixp4xx_outl(value, port & PIO_MASK); | 523 | __ixp4xx_outl(value, port & PIO_MASK); |
524 | else | 524 | else |
525 | #ifndef CONFIG_IXP4XX_INDIRECT_PCI | 525 | #ifndef CONFIG_IXP4XX_INDIRECT_PCI |
526 | __raw_writel(cpu_to_le32(value), port); | 526 | __raw_writel((u32 __force)cpu_to_le32(value), addr); |
527 | #else | 527 | #else |
528 | __ixp4xx_writel(value, addr); | 528 | __ixp4xx_writel(value, addr); |
529 | #endif | 529 | #endif |
diff --git a/include/asm-arm/arch-ixp4xx/platform.h b/include/asm-arm/arch-ixp4xx/platform.h index 2a44d3d67980..2ce28e3fd325 100644 --- a/include/asm-arm/arch-ixp4xx/platform.h +++ b/include/asm-arm/arch-ixp4xx/platform.h | |||
@@ -76,17 +76,6 @@ extern unsigned long ixp4xx_exp_bus_size; | |||
76 | #define IXP4XX_UART_XTAL 14745600 | 76 | #define IXP4XX_UART_XTAL 14745600 |
77 | 77 | ||
78 | /* | 78 | /* |
79 | * The IXP4xx chips do not have an I2C unit, so GPIO lines are just | ||
80 | * used to | ||
81 | * Used as platform_data to provide GPIO pin information to the ixp42x | ||
82 | * I2C driver. | ||
83 | */ | ||
84 | struct ixp4xx_i2c_pins { | ||
85 | unsigned long sda_pin; | ||
86 | unsigned long scl_pin; | ||
87 | }; | ||
88 | |||
89 | /* | ||
90 | * This structure provide a means for the board setup code | 79 | * This structure provide a means for the board setup code |
91 | * to give information to th pata_ixp4xx driver. It is | 80 | * to give information to th pata_ixp4xx driver. It is |
92 | * passed as platform_data. | 81 | * passed as platform_data. |
diff --git a/include/asm-arm/arch-msm/board.h b/include/asm-arm/arch-msm/board.h new file mode 100644 index 000000000000..763051f8ba14 --- /dev/null +++ b/include/asm-arm/arch-msm/board.h | |||
@@ -0,0 +1,37 @@ | |||
1 | /* linux/include/asm-arm/arch-msm/board.h | ||
2 | * | ||
3 | * Copyright (C) 2007 Google, Inc. | ||
4 | * Author: Brian Swetland <swetland@google.com> | ||
5 | * | ||
6 | * This software is licensed under the terms of the GNU General Public | ||
7 | * License version 2, as published by the Free Software Foundation, and | ||
8 | * may be copied, distributed, and modified under those terms. | ||
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 | */ | ||
16 | |||
17 | #ifndef __ASM_ARCH_MSM_BOARD_H | ||
18 | #define __ASM_ARCH_MSM_BOARD_H | ||
19 | |||
20 | #include <linux/types.h> | ||
21 | |||
22 | /* platform device data structures */ | ||
23 | |||
24 | struct msm_mddi_platform_data | ||
25 | { | ||
26 | void (*panel_power)(int on); | ||
27 | unsigned has_vsync_irq:1; | ||
28 | }; | ||
29 | |||
30 | /* common init routines for use by arch/arm/mach-msm/board-*.c */ | ||
31 | |||
32 | void __init msm_add_devices(void); | ||
33 | void __init msm_map_common_io(void); | ||
34 | void __init msm_init_irq(void); | ||
35 | void __init msm_init_gpio(void); | ||
36 | |||
37 | #endif | ||
diff --git a/include/asm-arm/arch-msm/debug-macro.S b/include/asm-arm/arch-msm/debug-macro.S new file mode 100644 index 000000000000..393d5272e506 --- /dev/null +++ b/include/asm-arm/arch-msm/debug-macro.S | |||
@@ -0,0 +1,40 @@ | |||
1 | /* include/asm-arm/arch-msm7200/debug-macro.S | ||
2 | * | ||
3 | * Copyright (C) 2007 Google, Inc. | ||
4 | * Author: Brian Swetland <swetland@google.com> | ||
5 | * | ||
6 | * This software is licensed under the terms of the GNU General Public | ||
7 | * License version 2, as published by the Free Software Foundation, and | ||
8 | * may be copied, distributed, and modified under those terms. | ||
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 | */ | ||
16 | |||
17 | #include <asm/hardware.h> | ||
18 | #include <asm/arch/msm_iomap.h> | ||
19 | |||
20 | .macro addruart,rx | ||
21 | @ see if the MMU is enabled and select appropriate base address | ||
22 | mrc p15, 0, \rx, c1, c0 | ||
23 | tst \rx, #1 | ||
24 | ldreq \rx, =MSM_UART1_PHYS | ||
25 | ldrne \rx, =MSM_UART1_BASE | ||
26 | .endm | ||
27 | |||
28 | .macro senduart,rd,rx | ||
29 | str \rd, [\rx, #0x0C] | ||
30 | .endm | ||
31 | |||
32 | .macro waituart,rd,rx | ||
33 | @ wait for TX_READY | ||
34 | 1: ldr \rd, [\rx, #0x08] | ||
35 | tst \rd, #0x04 | ||
36 | beq 1b | ||
37 | .endm | ||
38 | |||
39 | .macro busyuart,rd,rx | ||
40 | .endm | ||
diff --git a/include/asm-arm/arch-msm/dma.h b/include/asm-arm/arch-msm/dma.h new file mode 100644 index 000000000000..e4b565b27b35 --- /dev/null +++ b/include/asm-arm/arch-msm/dma.h | |||
@@ -0,0 +1,151 @@ | |||
1 | /* linux/include/asm-arm/arch-msm/dma.h | ||
2 | * | ||
3 | * Copyright (C) 2007 Google, Inc. | ||
4 | * | ||
5 | * This software is licensed under the terms of the GNU General Public | ||
6 | * License version 2, as published by the Free Software Foundation, and | ||
7 | * may be copied, distributed, and modified under those terms. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #ifndef __ASM_ARCH_MSM_DMA_H | ||
17 | |||
18 | #include <linux/list.h> | ||
19 | #include <asm/arch/msm_iomap.h> | ||
20 | |||
21 | struct msm_dmov_cmd { | ||
22 | struct list_head list; | ||
23 | unsigned int cmdptr; | ||
24 | void (*complete_func)(struct msm_dmov_cmd *cmd, unsigned int result); | ||
25 | /* void (*user_result_func)(struct msm_dmov_cmd *cmd); */ | ||
26 | }; | ||
27 | |||
28 | void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd); | ||
29 | void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd); | ||
30 | int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr); | ||
31 | /* int msm_dmov_exec_cmd_etc(unsigned id, unsigned int cmdptr, int timeout, int interruptible); */ | ||
32 | |||
33 | |||
34 | |||
35 | #define DMOV_SD0(off, ch) (MSM_DMOV_BASE + 0x0000 + (off) + ((ch) << 2)) | ||
36 | #define DMOV_SD1(off, ch) (MSM_DMOV_BASE + 0x0400 + (off) + ((ch) << 2)) | ||
37 | #define DMOV_SD2(off, ch) (MSM_DMOV_BASE + 0x0800 + (off) + ((ch) << 2)) | ||
38 | #define DMOV_SD3(off, ch) (MSM_DMOV_BASE + 0x0C00 + (off) + ((ch) << 2)) | ||
39 | |||
40 | /* only security domain 3 is available to the ARM11 | ||
41 | * SD0 -> mARM trusted, SD1 -> mARM nontrusted, SD2 -> aDSP, SD3 -> aARM | ||
42 | */ | ||
43 | |||
44 | #define DMOV_CMD_PTR(ch) DMOV_SD3(0x000, ch) | ||
45 | #define DMOV_CMD_LIST (0 << 29) /* does not work */ | ||
46 | #define DMOV_CMD_PTR_LIST (1 << 29) /* works */ | ||
47 | #define DMOV_CMD_INPUT_CFG (2 << 29) /* untested */ | ||
48 | #define DMOV_CMD_OUTPUT_CFG (3 << 29) /* untested */ | ||
49 | #define DMOV_CMD_ADDR(addr) ((addr) >> 3) | ||
50 | |||
51 | #define DMOV_RSLT(ch) DMOV_SD3(0x040, ch) | ||
52 | #define DMOV_RSLT_VALID (1 << 31) /* 0 == host has empties result fifo */ | ||
53 | #define DMOV_RSLT_ERROR (1 << 3) | ||
54 | #define DMOV_RSLT_FLUSH (1 << 2) | ||
55 | #define DMOV_RSLT_DONE (1 << 1) /* top pointer done */ | ||
56 | #define DMOV_RSLT_USER (1 << 0) /* command with FR force result */ | ||
57 | |||
58 | #define DMOV_FLUSH0(ch) DMOV_SD3(0x080, ch) | ||
59 | #define DMOV_FLUSH1(ch) DMOV_SD3(0x0C0, ch) | ||
60 | #define DMOV_FLUSH2(ch) DMOV_SD3(0x100, ch) | ||
61 | #define DMOV_FLUSH3(ch) DMOV_SD3(0x140, ch) | ||
62 | #define DMOV_FLUSH4(ch) DMOV_SD3(0x180, ch) | ||
63 | #define DMOV_FLUSH5(ch) DMOV_SD3(0x1C0, ch) | ||
64 | |||
65 | #define DMOV_STATUS(ch) DMOV_SD3(0x200, ch) | ||
66 | #define DMOV_STATUS_RSLT_COUNT(n) (((n) >> 29)) | ||
67 | #define DMOV_STATUS_CMD_COUNT(n) (((n) >> 27) & 3) | ||
68 | #define DMOV_STATUS_RSLT_VALID (1 << 1) | ||
69 | #define DMOV_STATUS_CMD_PTR_RDY (1 << 0) | ||
70 | |||
71 | #define DMOV_ISR DMOV_SD3(0x380, 0) | ||
72 | |||
73 | #define DMOV_CONFIG(ch) DMOV_SD3(0x300, ch) | ||
74 | #define DMOV_CONFIG_FORCE_TOP_PTR_RSLT (1 << 2) | ||
75 | #define DMOV_CONFIG_FORCE_FLUSH_RSLT (1 << 1) | ||
76 | #define DMOV_CONFIG_IRQ_EN (1 << 0) | ||
77 | |||
78 | /* channel assignments */ | ||
79 | |||
80 | #define DMOV_NAND_CHAN 7 | ||
81 | #define DMOV_NAND_CRCI_CMD 5 | ||
82 | #define DMOV_NAND_CRCI_DATA 4 | ||
83 | |||
84 | #define DMOV_SDC1_CHAN 8 | ||
85 | #define DMOV_SDC1_CRCI 6 | ||
86 | |||
87 | #define DMOV_SDC2_CHAN 8 | ||
88 | #define DMOV_SDC2_CRCI 7 | ||
89 | |||
90 | #define DMOV_TSIF_CHAN 10 | ||
91 | #define DMOV_TSIF_CRCI 10 | ||
92 | |||
93 | #define DMOV_USB_CHAN 11 | ||
94 | |||
95 | /* no client rate control ifc (eg, ram) */ | ||
96 | #define DMOV_NONE_CRCI 0 | ||
97 | |||
98 | |||
99 | /* If the CMD_PTR register has CMD_PTR_LIST selected, the data mover | ||
100 | * is going to walk a list of 32bit pointers as described below. Each | ||
101 | * pointer points to a *array* of dmov_s, etc structs. The last pointer | ||
102 | * in the list is marked with CMD_PTR_LP. The last struct in each array | ||
103 | * is marked with CMD_LC (see below). | ||
104 | */ | ||
105 | #define CMD_PTR_ADDR(addr) ((addr) >> 3) | ||
106 | #define CMD_PTR_LP (1 << 31) /* last pointer */ | ||
107 | #define CMD_PTR_PT (3 << 29) /* ? */ | ||
108 | |||
109 | /* Single Item Mode */ | ||
110 | typedef struct { | ||
111 | unsigned cmd; | ||
112 | unsigned src; | ||
113 | unsigned dst; | ||
114 | unsigned len; | ||
115 | } dmov_s; | ||
116 | |||
117 | /* Scatter/Gather Mode */ | ||
118 | typedef struct { | ||
119 | unsigned cmd; | ||
120 | unsigned src_dscr; | ||
121 | unsigned dst_dscr; | ||
122 | unsigned _reserved; | ||
123 | } dmov_sg; | ||
124 | |||
125 | /* bits for the cmd field of the above structures */ | ||
126 | |||
127 | #define CMD_LC (1 << 31) /* last command */ | ||
128 | #define CMD_FR (1 << 22) /* force result -- does not work? */ | ||
129 | #define CMD_OCU (1 << 21) /* other channel unblock */ | ||
130 | #define CMD_OCB (1 << 20) /* other channel block */ | ||
131 | #define CMD_TCB (1 << 19) /* ? */ | ||
132 | #define CMD_DAH (1 << 18) /* destination address hold -- does not work?*/ | ||
133 | #define CMD_SAH (1 << 17) /* source address hold -- does not work? */ | ||
134 | |||
135 | #define CMD_MODE_SINGLE (0 << 0) /* dmov_s structure used */ | ||
136 | #define CMD_MODE_SG (1 << 0) /* untested */ | ||
137 | #define CMD_MODE_IND_SG (2 << 0) /* untested */ | ||
138 | #define CMD_MODE_BOX (3 << 0) /* untested */ | ||
139 | |||
140 | #define CMD_DST_SWAP_BYTES (1 << 14) /* exchange each byte n with byte n+1 */ | ||
141 | #define CMD_DST_SWAP_SHORTS (1 << 15) /* exchange each short n with short n+1 */ | ||
142 | #define CMD_DST_SWAP_WORDS (1 << 16) /* exchange each word n with word n+1 */ | ||
143 | |||
144 | #define CMD_SRC_SWAP_BYTES (1 << 11) /* exchange each byte n with byte n+1 */ | ||
145 | #define CMD_SRC_SWAP_SHORTS (1 << 12) /* exchange each short n with short n+1 */ | ||
146 | #define CMD_SRC_SWAP_WORDS (1 << 13) /* exchange each word n with word n+1 */ | ||
147 | |||
148 | #define CMD_DST_CRCI(n) (((n) & 15) << 7) | ||
149 | #define CMD_SRC_CRCI(n) (((n) & 15) << 3) | ||
150 | |||
151 | #endif | ||
diff --git a/include/asm-arm/arch-msm/entry-macro.S b/include/asm-arm/arch-msm/entry-macro.S new file mode 100644 index 000000000000..ee24aece4cb0 --- /dev/null +++ b/include/asm-arm/arch-msm/entry-macro.S | |||
@@ -0,0 +1,38 @@ | |||
1 | /* include/asm-arm/arch-msm7200/entry-macro.S | ||
2 | * | ||
3 | * Copyright (C) 2007 Google, Inc. | ||
4 | * Author: Brian Swetland <swetland@google.com> | ||
5 | * | ||
6 | * This software is licensed under the terms of the GNU General Public | ||
7 | * License version 2, as published by the Free Software Foundation, and | ||
8 | * may be copied, distributed, and modified under those terms. | ||
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 | */ | ||
16 | |||
17 | #include <asm/arch/msm_iomap.h> | ||
18 | |||
19 | .macro disable_fiq | ||
20 | .endm | ||
21 | |||
22 | .macro get_irqnr_preamble, base, tmp | ||
23 | @ enable imprecise aborts | ||
24 | cpsie a | ||
25 | mov \base, #MSM_VIC_BASE | ||
26 | .endm | ||
27 | |||
28 | .macro arch_ret_to_user, tmp1, tmp2 | ||
29 | .endm | ||
30 | |||
31 | .macro get_irqnr_and_base, irqnr, irqstat, base, tmp | ||
32 | @ 0xD0 has irq# or old irq# if the irq has been handled | ||
33 | @ 0xD4 has irq# or -1 if none pending *but* if you just | ||
34 | @ read 0xD4 you never get the first irq for some reason | ||
35 | ldr \irqnr, [\base, #0xD0] | ||
36 | ldr \irqnr, [\base, #0xD4] | ||
37 | cmp \irqnr, #0xffffffff | ||
38 | .endm | ||
diff --git a/include/asm-arm/arch-msm/hardware.h b/include/asm-arm/arch-msm/hardware.h new file mode 100644 index 000000000000..89af2b70182f --- /dev/null +++ b/include/asm-arm/arch-msm/hardware.h | |||
@@ -0,0 +1,18 @@ | |||
1 | /* linux/include/asm-arm/arch-msm/hardware.h | ||
2 | * | ||
3 | * Copyright (C) 2007 Google, Inc. | ||
4 | * | ||
5 | * This software is licensed under the terms of the GNU General Public | ||
6 | * License version 2, as published by the Free Software Foundation, and | ||
7 | * may be copied, distributed, and modified under those terms. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #ifndef __ASM_ARCH_MSM_HARDWARE_H | ||
17 | |||
18 | #endif | ||
diff --git a/include/asm-arm/arch-msm/io.h b/include/asm-arm/arch-msm/io.h new file mode 100644 index 000000000000..4645ae26b62a --- /dev/null +++ b/include/asm-arm/arch-msm/io.h | |||
@@ -0,0 +1,33 @@ | |||
1 | /* include/asm-arm/arch-msm/io.h | ||
2 | * | ||
3 | * Copyright (C) 2007 Google, Inc. | ||
4 | * | ||
5 | * This software is licensed under the terms of the GNU General Public | ||
6 | * License version 2, as published by the Free Software Foundation, and | ||
7 | * may be copied, distributed, and modified under those terms. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #ifndef __ASM_ARM_ARCH_IO_H | ||
17 | #define __ASM_ARM_ARCH_IO_H | ||
18 | |||
19 | #define IO_SPACE_LIMIT 0xffffffff | ||
20 | |||
21 | #define __arch_ioremap __msm_ioremap | ||
22 | #define __arch_iounmap __iounmap | ||
23 | |||
24 | void __iomem *__msm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype); | ||
25 | |||
26 | static inline void __iomem *__io(unsigned long addr) | ||
27 | { | ||
28 | return (void __iomem *)addr; | ||
29 | } | ||
30 | #define __io(a) __io(a) | ||
31 | #define __mem_pci(a) (a) | ||
32 | |||
33 | #endif | ||
diff --git a/include/asm-arm/arch-msm/irqs.h b/include/asm-arm/arch-msm/irqs.h new file mode 100644 index 000000000000..565430cfaa7e --- /dev/null +++ b/include/asm-arm/arch-msm/irqs.h | |||
@@ -0,0 +1,89 @@ | |||
1 | /* linux/include/asm-arm/arch-msm/irqs.h | ||
2 | * | ||
3 | * Copyright (C) 2007 Google, Inc. | ||
4 | * Author: Brian Swetland <swetland@google.com> | ||
5 | * | ||
6 | * This software is licensed under the terms of the GNU General Public | ||
7 | * License version 2, as published by the Free Software Foundation, and | ||
8 | * may be copied, distributed, and modified under those terms. | ||
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 | */ | ||
16 | |||
17 | #ifndef __ASM_ARCH_MSM_IRQS_H | ||
18 | |||
19 | /* MSM ARM11 Interrupt Numbers */ | ||
20 | /* See 80-VE113-1 A, pp219-221 */ | ||
21 | |||
22 | #define INT_A9_M2A_0 0 | ||
23 | #define INT_A9_M2A_1 1 | ||
24 | #define INT_A9_M2A_2 2 | ||
25 | #define INT_A9_M2A_3 3 | ||
26 | #define INT_A9_M2A_4 4 | ||
27 | #define INT_A9_M2A_5 5 | ||
28 | #define INT_A9_M2A_6 6 | ||
29 | #define INT_GP_TIMER_EXP 7 | ||
30 | #define INT_DEBUG_TIMER_EXP 8 | ||
31 | #define INT_UART1 9 | ||
32 | #define INT_UART2 10 | ||
33 | #define INT_UART3 11 | ||
34 | #define INT_UART1_RX 12 | ||
35 | #define INT_UART2_RX 13 | ||
36 | #define INT_UART3_RX 14 | ||
37 | #define INT_USB_OTG 15 | ||
38 | #define INT_MDDI_PRI 16 | ||
39 | #define INT_MDDI_EXT 17 | ||
40 | #define INT_MDDI_CLIENT 18 | ||
41 | #define INT_MDP 19 | ||
42 | #define INT_GRAPHICS 20 | ||
43 | #define INT_ADM_AARM 21 | ||
44 | #define INT_ADSP_A11 22 | ||
45 | #define INT_ADSP_A9_A11 23 | ||
46 | #define INT_SDC1_0 24 | ||
47 | #define INT_SDC1_1 25 | ||
48 | #define INT_SDC2_0 26 | ||
49 | #define INT_SDC2_1 27 | ||
50 | #define INT_KEYSENSE 28 | ||
51 | #define INT_TCHSCRN_SSBI 29 | ||
52 | #define INT_TCHSCRN1 30 | ||
53 | #define INT_TCHSCRN2 31 | ||
54 | |||
55 | #define INT_GPIO_GROUP1 (32 + 0) | ||
56 | #define INT_GPIO_GROUP2 (32 + 1) | ||
57 | #define INT_PWB_I2C (32 + 2) | ||
58 | #define INT_SOFTRESET (32 + 3) | ||
59 | #define INT_NAND_WR_ER_DONE (32 + 4) | ||
60 | #define INT_NAND_OP_DONE (32 + 5) | ||
61 | #define INT_PBUS_ARM11 (32 + 6) | ||
62 | #define INT_AXI_MPU_SMI (32 + 7) | ||
63 | #define INT_AXI_MPU_EBI1 (32 + 8) | ||
64 | #define INT_AD_HSSD (32 + 9) | ||
65 | #define INT_ARM11_PMU (32 + 10) | ||
66 | #define INT_ARM11_DMA (32 + 11) | ||
67 | #define INT_TSIF_IRQ (32 + 12) | ||
68 | #define INT_UART1DM_IRQ (32 + 13) | ||
69 | #define INT_UART1DM_RX (32 + 14) | ||
70 | #define INT_USB_HS (32 + 15) | ||
71 | #define INT_SDC3_0 (32 + 16) | ||
72 | #define INT_SDC3_1 (32 + 17) | ||
73 | #define INT_SDC4_0 (32 + 18) | ||
74 | #define INT_SDC4_1 (32 + 19) | ||
75 | #define INT_UART2DM_RX (32 + 20) | ||
76 | #define INT_UART2DM_IRQ (32 + 21) | ||
77 | |||
78 | /* 22-31 are reserved */ | ||
79 | |||
80 | #define MSM_IRQ_BIT(irq) (1 << ((irq) & 31)) | ||
81 | |||
82 | #define NR_MSM_IRQS 64 | ||
83 | #define NR_GPIO_IRQS 122 | ||
84 | #define NR_BOARD_IRQS 64 | ||
85 | #define NR_IRQS (NR_MSM_IRQS + NR_GPIO_IRQS + NR_BOARD_IRQS) | ||
86 | |||
87 | #define MSM_GPIO_TO_INT(n) (NR_MSM_IRQS + (n)) | ||
88 | |||
89 | #endif | ||
diff --git a/include/asm-arm/arch-msm/memory.h b/include/asm-arm/arch-msm/memory.h new file mode 100644 index 000000000000..b5ce0e9ac86d --- /dev/null +++ b/include/asm-arm/arch-msm/memory.h | |||
@@ -0,0 +1,27 @@ | |||
1 | /* linux/include/asm-arm/arch-msm/memory.h | ||
2 | * | ||
3 | * Copyright (C) 2007 Google, Inc. | ||
4 | * | ||
5 | * This software is licensed under the terms of the GNU General Public | ||
6 | * License version 2, as published by the Free Software Foundation, and | ||
7 | * may be copied, distributed, and modified under those terms. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #ifndef __ASM_ARCH_MEMORY_H | ||
17 | #define __ASM_ARCH_MEMORY_H | ||
18 | |||
19 | /* physical offset of RAM */ | ||
20 | #define PHYS_OFFSET UL(0x10000000) | ||
21 | |||
22 | /* bus address and physical addresses are identical */ | ||
23 | #define __virt_to_bus(x) __virt_to_phys(x) | ||
24 | #define __bus_to_virt(x) __phys_to_virt(x) | ||
25 | |||
26 | #endif | ||
27 | |||
diff --git a/include/asm-arm/arch-msm/msm_iomap.h b/include/asm-arm/arch-msm/msm_iomap.h new file mode 100644 index 000000000000..b8955cc26fec --- /dev/null +++ b/include/asm-arm/arch-msm/msm_iomap.h | |||
@@ -0,0 +1,104 @@ | |||
1 | /* linux/include/asm-arm/arch-msm/msm_iomap.h | ||
2 | * | ||
3 | * Copyright (C) 2007 Google, Inc. | ||
4 | * Author: Brian Swetland <swetland@google.com> | ||
5 | * | ||
6 | * This software is licensed under the terms of the GNU General Public | ||
7 | * License version 2, as published by the Free Software Foundation, and | ||
8 | * may be copied, distributed, and modified under those terms. | ||
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 | * | ||
16 | * The MSM peripherals are spread all over across 768MB of physical | ||
17 | * space, which makes just having a simple IO_ADDRESS macro to slide | ||
18 | * them into the right virtual location rough. Instead, we will | ||
19 | * provide a master phys->virt mapping for peripherals here. | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #ifndef __ASM_ARCH_MSM_IOMAP_H | ||
24 | #define __ASM_ARCH_MSM_IOMAP_H | ||
25 | |||
26 | #include <asm/sizes.h> | ||
27 | |||
28 | /* Physical base address and size of peripherals. | ||
29 | * Ordered by the virtual base addresses they will be mapped at. | ||
30 | * | ||
31 | * MSM_VIC_BASE must be an value that can be loaded via a "mov" | ||
32 | * instruction, otherwise entry-macro.S will not compile. | ||
33 | * | ||
34 | * If you add or remove entries here, you'll want to edit the | ||
35 | * msm_io_desc array in arch/arm/mach-msm/io.c to reflect your | ||
36 | * changes. | ||
37 | * | ||
38 | */ | ||
39 | |||
40 | #define MSM_VIC_BASE 0xE0000000 | ||
41 | #define MSM_VIC_PHYS 0xC0000000 | ||
42 | #define MSM_VIC_SIZE SZ_4K | ||
43 | |||
44 | #define MSM_CSR_BASE 0xE0001000 | ||
45 | #define MSM_CSR_PHYS 0xC0100000 | ||
46 | #define MSM_CSR_SIZE SZ_4K | ||
47 | |||
48 | #define MSM_GPT_PHYS MSM_CSR_PHYS | ||
49 | #define MSM_GPT_BASE MSM_CSR_BASE | ||
50 | #define MSM_GPT_SIZE SZ_4K | ||
51 | |||
52 | #define MSM_DMOV_BASE 0xE0002000 | ||
53 | #define MSM_DMOV_PHYS 0xA9700000 | ||
54 | #define MSM_DMOV_SIZE SZ_4K | ||
55 | |||
56 | #define MSM_UART1_BASE 0xE0003000 | ||
57 | #define MSM_UART1_PHYS 0xA9A00000 | ||
58 | #define MSM_UART1_SIZE SZ_4K | ||
59 | |||
60 | #define MSM_UART2_BASE 0xE0004000 | ||
61 | #define MSM_UART2_PHYS 0xA9B00000 | ||
62 | #define MSM_UART2_SIZE SZ_4K | ||
63 | |||
64 | #define MSM_UART3_BASE 0xE0005000 | ||
65 | #define MSM_UART3_PHYS 0xA9C00000 | ||
66 | #define MSM_UART3_SIZE SZ_4K | ||
67 | |||
68 | #define MSM_I2C_BASE 0xE0006000 | ||
69 | #define MSM_I2C_PHYS 0xA9900000 | ||
70 | #define MSM_I2C_SIZE SZ_4K | ||
71 | |||
72 | #define MSM_GPIO1_BASE 0xE0007000 | ||
73 | #define MSM_GPIO1_PHYS 0xA9200000 | ||
74 | #define MSM_GPIO1_SIZE SZ_4K | ||
75 | |||
76 | #define MSM_GPIO2_BASE 0xE0008000 | ||
77 | #define MSM_GPIO2_PHYS 0xA9300000 | ||
78 | #define MSM_GPIO2_SIZE SZ_4K | ||
79 | |||
80 | #define MSM_HSUSB_BASE 0xE0009000 | ||
81 | #define MSM_HSUSB_PHYS 0xA0800000 | ||
82 | #define MSM_HSUSB_SIZE SZ_4K | ||
83 | |||
84 | #define MSM_CLK_CTL_BASE 0xE000A000 | ||
85 | #define MSM_CLK_CTL_PHYS 0xA8600000 | ||
86 | #define MSM_CLK_CTL_SIZE SZ_4K | ||
87 | |||
88 | #define MSM_PMDH_BASE 0xE000B000 | ||
89 | #define MSM_PMDH_PHYS 0xAA600000 | ||
90 | #define MSM_PMDH_SIZE SZ_4K | ||
91 | |||
92 | #define MSM_EMDH_BASE 0xE000C000 | ||
93 | #define MSM_EMDH_PHYS 0xAA700000 | ||
94 | #define MSM_EMDH_SIZE SZ_4K | ||
95 | |||
96 | #define MSM_MDP_BASE 0xE0010000 | ||
97 | #define MSM_MDP_PHYS 0xAA200000 | ||
98 | #define MSM_MDP_SIZE 0x000F0000 | ||
99 | |||
100 | #define MSM_SHARED_RAM_BASE 0xE0100000 | ||
101 | #define MSM_SHARED_RAM_PHYS 0x01F00000 | ||
102 | #define MSM_SHARED_RAM_SIZE SZ_1M | ||
103 | |||
104 | #endif | ||
diff --git a/include/asm-arm/arch-msm/system.h b/include/asm-arm/arch-msm/system.h new file mode 100644 index 000000000000..7c5544bdd0c7 --- /dev/null +++ b/include/asm-arm/arch-msm/system.h | |||
@@ -0,0 +1,23 @@ | |||
1 | /* linux/include/asm-arm/arch-msm/system.h | ||
2 | * | ||
3 | * Copyright (C) 2007 Google, Inc. | ||
4 | * | ||
5 | * This software is licensed under the terms of the GNU General Public | ||
6 | * License version 2, as published by the Free Software Foundation, and | ||
7 | * may be copied, distributed, and modified under those terms. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <asm/hardware.h> | ||
17 | |||
18 | void arch_idle(void); | ||
19 | |||
20 | static inline void arch_reset(char mode) | ||
21 | { | ||
22 | for (;;) ; /* depends on IPC w/ other core */ | ||
23 | } | ||
diff --git a/include/asm-arm/arch-msm/timex.h b/include/asm-arm/arch-msm/timex.h new file mode 100644 index 000000000000..154b23fb3599 --- /dev/null +++ b/include/asm-arm/arch-msm/timex.h | |||
@@ -0,0 +1,20 @@ | |||
1 | /* linux/include/asm-arm/arch-msm/timex.h | ||
2 | * | ||
3 | * Copyright (C) 2007 Google, Inc. | ||
4 | * | ||
5 | * This software is licensed under the terms of the GNU General Public | ||
6 | * License version 2, as published by the Free Software Foundation, and | ||
7 | * may be copied, distributed, and modified under those terms. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #ifndef __ASM_ARCH_MSM_TIMEX_H | ||
17 | |||
18 | #define CLOCK_TICK_RATE 1000000 | ||
19 | |||
20 | #endif | ||
diff --git a/include/asm-arm/arch-msm/uncompress.h b/include/asm-arm/arch-msm/uncompress.h new file mode 100644 index 000000000000..e91ed786ffec --- /dev/null +++ b/include/asm-arm/arch-msm/uncompress.h | |||
@@ -0,0 +1,36 @@ | |||
1 | /* linux/include/asm-arm/arch-msm/uncompress.h | ||
2 | * | ||
3 | * Copyright (C) 2007 Google, Inc. | ||
4 | * | ||
5 | * This software is licensed under the terms of the GNU General Public | ||
6 | * License version 2, as published by the Free Software Foundation, and | ||
7 | * may be copied, distributed, and modified under those terms. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #ifndef __ASM_ARCH_MSM_UNCOMPRESS_H | ||
17 | |||
18 | #include "hardware.h" | ||
19 | |||
20 | static void putc(int c) | ||
21 | { | ||
22 | } | ||
23 | |||
24 | static inline void flush(void) | ||
25 | { | ||
26 | } | ||
27 | |||
28 | static inline void arch_decomp_setup(void) | ||
29 | { | ||
30 | } | ||
31 | |||
32 | static inline void arch_decomp_wdog(void) | ||
33 | { | ||
34 | } | ||
35 | |||
36 | #endif | ||
diff --git a/include/asm-arm/arch-msm/vmalloc.h b/include/asm-arm/arch-msm/vmalloc.h new file mode 100644 index 000000000000..60f8d910e825 --- /dev/null +++ b/include/asm-arm/arch-msm/vmalloc.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* linux/include/asm-arm/arch-msm/vmalloc.h | ||
2 | * | ||
3 | * Copyright (C) 2007 Google, Inc. | ||
4 | * | ||
5 | * This software is licensed under the terms of the GNU General Public | ||
6 | * License version 2, as published by the Free Software Foundation, and | ||
7 | * may be copied, distributed, and modified under those terms. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #ifndef __ASM_ARCH_MSM_VMALLOC_H | ||
17 | #define __ASM_ARCH_MSM_VMALLOC_H | ||
18 | |||
19 | #define VMALLOC_END (PAGE_OFFSET + 0x10000000) | ||
20 | |||
21 | #endif | ||
22 | |||
diff --git a/include/asm-arm/arch-pxa/i2c.h b/include/asm-arm/arch-pxa/i2c.h index e404b233d8a8..80596b013443 100644 --- a/include/asm-arm/arch-pxa/i2c.h +++ b/include/asm-arm/arch-pxa/i2c.h | |||
@@ -65,7 +65,13 @@ struct i2c_pxa_platform_data { | |||
65 | unsigned int slave_addr; | 65 | unsigned int slave_addr; |
66 | struct i2c_slave_client *slave; | 66 | struct i2c_slave_client *slave; |
67 | unsigned int class; | 67 | unsigned int class; |
68 | int use_pio; | ||
68 | }; | 69 | }; |
69 | 70 | ||
70 | extern void pxa_set_i2c_info(struct i2c_pxa_platform_data *info); | 71 | extern void pxa_set_i2c_info(struct i2c_pxa_platform_data *info); |
72 | |||
73 | #ifdef CONFIG_PXA27x | ||
74 | extern void pxa_set_i2c_power_info(struct i2c_pxa_platform_data *info); | ||
75 | #endif | ||
76 | |||
71 | #endif | 77 | #endif |
diff --git a/include/asm-arm/arch-s3c2410/debug-macro.S b/include/asm-arm/arch-s3c2410/debug-macro.S index 9c8cd9abb82b..89076c322726 100644 --- a/include/asm-arm/arch-s3c2410/debug-macro.S +++ b/include/asm-arm/arch-s3c2410/debug-macro.S | |||
@@ -92,11 +92,9 @@ | |||
92 | #if defined(CONFIG_CPU_LLSERIAL_S3C2410_ONLY) | 92 | #if defined(CONFIG_CPU_LLSERIAL_S3C2410_ONLY) |
93 | #define fifo_full fifo_full_s3c2410 | 93 | #define fifo_full fifo_full_s3c2410 |
94 | #define fifo_level fifo_level_s3c2410 | 94 | #define fifo_level fifo_level_s3c2410 |
95 | #warning 2410only | ||
96 | #elif !defined(CONFIG_CPU_LLSERIAL_S3C2440_ONLY) | 95 | #elif !defined(CONFIG_CPU_LLSERIAL_S3C2440_ONLY) |
97 | #define fifo_full fifo_full_s3c24xx | 96 | #define fifo_full fifo_full_s3c24xx |
98 | #define fifo_level fifo_level_s3c24xx | 97 | #define fifo_level fifo_level_s3c24xx |
99 | #warning generic | ||
100 | #endif | 98 | #endif |
101 | 99 | ||
102 | /* include the reset of the code which will do the work */ | 100 | /* include the reset of the code which will do the work */ |
diff --git a/include/asm-arm/arch-s3c2410/dma.h b/include/asm-arm/arch-s3c2410/dma.h index c6e8d8f64938..4f291d9b7d93 100644 --- a/include/asm-arm/arch-s3c2410/dma.h +++ b/include/asm-arm/arch-s3c2410/dma.h | |||
@@ -214,6 +214,7 @@ struct s3c2410_dma_chan { | |||
214 | unsigned long dev_addr; | 214 | unsigned long dev_addr; |
215 | unsigned long load_timeout; | 215 | unsigned long load_timeout; |
216 | unsigned int flags; /* channel flags */ | 216 | unsigned int flags; /* channel flags */ |
217 | unsigned int hw_cfg; /* last hw config */ | ||
217 | 218 | ||
218 | struct s3c24xx_dma_map *map; /* channel hw maps */ | 219 | struct s3c24xx_dma_map *map; /* channel hw maps */ |
219 | 220 | ||
diff --git a/include/asm-arm/arch-s3c2410/hardware.h b/include/asm-arm/arch-s3c2410/hardware.h index 6dadf58ff984..29592c3ebf22 100644 --- a/include/asm-arm/arch-s3c2410/hardware.h +++ b/include/asm-arm/arch-s3c2410/hardware.h | |||
@@ -50,6 +50,17 @@ extern unsigned int s3c2410_gpio_getcfg(unsigned int pin); | |||
50 | 50 | ||
51 | extern int s3c2410_gpio_getirq(unsigned int pin); | 51 | extern int s3c2410_gpio_getirq(unsigned int pin); |
52 | 52 | ||
53 | /* s3c2410_gpio_irq2pin | ||
54 | * | ||
55 | * turn the given irq number into the corresponding GPIO number | ||
56 | * | ||
57 | * returns: | ||
58 | * < 0 = no pin | ||
59 | * >=0 = gpio pin number | ||
60 | */ | ||
61 | |||
62 | extern int s3c2410_gpio_irq2pin(unsigned int irq); | ||
63 | |||
53 | #ifdef CONFIG_CPU_S3C2400 | 64 | #ifdef CONFIG_CPU_S3C2400 |
54 | 65 | ||
55 | extern int s3c2400_gpio_getirq(unsigned int pin); | 66 | extern int s3c2400_gpio_getirq(unsigned int pin); |
@@ -87,6 +98,18 @@ extern int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on, | |||
87 | 98 | ||
88 | extern void s3c2410_gpio_pullup(unsigned int pin, unsigned int to); | 99 | extern void s3c2410_gpio_pullup(unsigned int pin, unsigned int to); |
89 | 100 | ||
101 | /* s3c2410_gpio_getpull | ||
102 | * | ||
103 | * Read the state of the pull-up on a given pin | ||
104 | * | ||
105 | * return: | ||
106 | * < 0 => error code | ||
107 | * 0 => enabled | ||
108 | * 1 => disabled | ||
109 | */ | ||
110 | |||
111 | extern int s3c2410_gpio_getpull(unsigned int pin); | ||
112 | |||
90 | extern void s3c2410_gpio_setpin(unsigned int pin, unsigned int to); | 113 | extern void s3c2410_gpio_setpin(unsigned int pin, unsigned int to); |
91 | 114 | ||
92 | extern unsigned int s3c2410_gpio_getpin(unsigned int pin); | 115 | extern unsigned int s3c2410_gpio_getpin(unsigned int pin); |
@@ -99,6 +122,11 @@ extern int s3c2440_set_dsc(unsigned int pin, unsigned int value); | |||
99 | 122 | ||
100 | #endif /* CONFIG_CPU_S3C2440 */ | 123 | #endif /* CONFIG_CPU_S3C2440 */ |
101 | 124 | ||
125 | #ifdef CONFIG_CPU_S3C2412 | ||
126 | |||
127 | extern int s3c2412_gpio_set_sleepcfg(unsigned int pin, unsigned int state); | ||
128 | |||
129 | #endif /* CONFIG_CPU_S3C2412 */ | ||
102 | 130 | ||
103 | #endif /* __ASSEMBLY__ */ | 131 | #endif /* __ASSEMBLY__ */ |
104 | 132 | ||
diff --git a/include/asm-arm/arch-s3c2410/irqs.h b/include/asm-arm/arch-s3c2410/irqs.h index 996f65488d2d..d858b3eb5547 100644 --- a/include/asm-arm/arch-s3c2410/irqs.h +++ b/include/asm-arm/arch-s3c2410/irqs.h | |||
@@ -160,4 +160,7 @@ | |||
160 | #define NR_IRQS (IRQ_S3C2440_AC97+1) | 160 | #define NR_IRQS (IRQ_S3C2440_AC97+1) |
161 | #endif | 161 | #endif |
162 | 162 | ||
163 | /* Our FIQs are routable from IRQ_EINT0 to IRQ_ADCPARENT */ | ||
164 | #define FIQ_START IRQ_EINT0 | ||
165 | |||
163 | #endif /* __ASM_ARCH_IRQ_H */ | 166 | #endif /* __ASM_ARCH_IRQ_H */ |
diff --git a/include/asm-arm/arch-s3c2410/regs-clock.h b/include/asm-arm/arch-s3c2410/regs-clock.h index e39656b7a086..dba9df9d8713 100644 --- a/include/asm-arm/arch-s3c2410/regs-clock.h +++ b/include/asm-arm/arch-s3c2410/regs-clock.h | |||
@@ -138,6 +138,8 @@ s3c2410_get_pll(unsigned int pllval, unsigned int baseclk) | |||
138 | #define S3C2412_CLKDIVN_PDIVN (1<<2) | 138 | #define S3C2412_CLKDIVN_PDIVN (1<<2) |
139 | #define S3C2412_CLKDIVN_HDIVN_MASK (3<<0) | 139 | #define S3C2412_CLKDIVN_HDIVN_MASK (3<<0) |
140 | #define S3C2421_CLKDIVN_ARMDIVN (1<<3) | 140 | #define S3C2421_CLKDIVN_ARMDIVN (1<<3) |
141 | #define S3C2412_CLKDIVN_DVSEN (1<<4) | ||
142 | #define S3C2412_CLKDIVN_HALFHCLK (1<<5) | ||
141 | #define S3C2412_CLKDIVN_USB48DIV (1<<6) | 143 | #define S3C2412_CLKDIVN_USB48DIV (1<<6) |
142 | #define S3C2412_CLKDIVN_UARTDIV_MASK (15<<8) | 144 | #define S3C2412_CLKDIVN_UARTDIV_MASK (15<<8) |
143 | #define S3C2412_CLKDIVN_UARTDIV_SHIFT (8) | 145 | #define S3C2412_CLKDIVN_UARTDIV_SHIFT (8) |
diff --git a/include/asm-arm/arch-s3c2410/regs-dsc.h b/include/asm-arm/arch-s3c2410/regs-dsc.h index c0748511edbc..1235df70f34e 100644 --- a/include/asm-arm/arch-s3c2410/regs-dsc.h +++ b/include/asm-arm/arch-s3c2410/regs-dsc.h | |||
@@ -19,7 +19,7 @@ | |||
19 | #define S3C2412_DSC1 S3C2410_GPIOREG(0xe0) | 19 | #define S3C2412_DSC1 S3C2410_GPIOREG(0xe0) |
20 | #endif | 20 | #endif |
21 | 21 | ||
22 | #if defined(CONFIG_CPU_S3C2440) | 22 | #if defined(CONFIG_CPU_S3C244X) |
23 | 23 | ||
24 | #define S3C2440_DSC0 S3C2410_GPIOREG(0xc4) | 24 | #define S3C2440_DSC0 S3C2410_GPIOREG(0xc4) |
25 | #define S3C2440_DSC1 S3C2410_GPIOREG(0xc8) | 25 | #define S3C2440_DSC1 S3C2410_GPIOREG(0xc8) |
diff --git a/include/asm-arm/arch-s3c2410/regs-gpio.h b/include/asm-arm/arch-s3c2410/regs-gpio.h index b693158b2d3c..0ad75d716ded 100644 --- a/include/asm-arm/arch-s3c2410/regs-gpio.h +++ b/include/asm-arm/arch-s3c2410/regs-gpio.h | |||
@@ -1133,12 +1133,16 @@ | |||
1133 | #define S3C2412_GPBSLPCON S3C2410_GPIOREG(0x1C) | 1133 | #define S3C2412_GPBSLPCON S3C2410_GPIOREG(0x1C) |
1134 | #define S3C2412_GPCSLPCON S3C2410_GPIOREG(0x2C) | 1134 | #define S3C2412_GPCSLPCON S3C2410_GPIOREG(0x2C) |
1135 | #define S3C2412_GPDSLPCON S3C2410_GPIOREG(0x3C) | 1135 | #define S3C2412_GPDSLPCON S3C2410_GPIOREG(0x3C) |
1136 | #define S3C2412_GPESLPCON S3C2410_GPIOREG(0x4C) | ||
1137 | #define S3C2412_GPFSLPCON S3C2410_GPIOREG(0x5C) | 1136 | #define S3C2412_GPFSLPCON S3C2410_GPIOREG(0x5C) |
1138 | #define S3C2412_GPGSLPCON S3C2410_GPIOREG(0x6C) | 1137 | #define S3C2412_GPGSLPCON S3C2410_GPIOREG(0x6C) |
1139 | #define S3C2412_GPHSLPCON S3C2410_GPIOREG(0x7C) | 1138 | #define S3C2412_GPHSLPCON S3C2410_GPIOREG(0x7C) |
1140 | 1139 | ||
1141 | /* definitions for each pin bit */ | 1140 | /* definitions for each pin bit */ |
1141 | #define S3C2412_GPIO_SLPCON_LOW ( 0x00 ) | ||
1142 | #define S3C2412_GPIO_SLPCON_HIGH ( 0x01 ) | ||
1143 | #define S3C2412_GPIO_SLPCON_IN ( 0x02 ) | ||
1144 | #define S3C2412_GPIO_SLPCON_PULL ( 0x03 ) | ||
1145 | |||
1142 | #define S3C2412_SLPCON_LOW(x) ( 0x00 << ((x) * 2)) | 1146 | #define S3C2412_SLPCON_LOW(x) ( 0x00 << ((x) * 2)) |
1143 | #define S3C2412_SLPCON_HIGH(x) ( 0x01 << ((x) * 2)) | 1147 | #define S3C2412_SLPCON_HIGH(x) ( 0x01 << ((x) * 2)) |
1144 | #define S3C2412_SLPCON_IN(x) ( 0x02 << ((x) * 2)) | 1148 | #define S3C2412_SLPCON_IN(x) ( 0x02 << ((x) * 2)) |
diff --git a/include/asm-arm/arch-s3c2410/regs-mem.h b/include/asm-arm/arch-s3c2410/regs-mem.h index e4d82341f7ba..312ff93b63c6 100644 --- a/include/asm-arm/arch-s3c2410/regs-mem.h +++ b/include/asm-arm/arch-s3c2410/regs-mem.h | |||
@@ -98,16 +98,19 @@ | |||
98 | #define S3C2410_BANKCON_Tacp3 (0x1 << 2) | 98 | #define S3C2410_BANKCON_Tacp3 (0x1 << 2) |
99 | #define S3C2410_BANKCON_Tacp4 (0x2 << 2) | 99 | #define S3C2410_BANKCON_Tacp4 (0x2 << 2) |
100 | #define S3C2410_BANKCON_Tacp6 (0x3 << 2) | 100 | #define S3C2410_BANKCON_Tacp6 (0x3 << 2) |
101 | #define S3C2410_BANKCON_Tacp_SHIFT (2) | ||
101 | 102 | ||
102 | #define S3C2410_BANKCON_Tcah0 (0x0 << 4) | 103 | #define S3C2410_BANKCON_Tcah0 (0x0 << 4) |
103 | #define S3C2410_BANKCON_Tcah1 (0x1 << 4) | 104 | #define S3C2410_BANKCON_Tcah1 (0x1 << 4) |
104 | #define S3C2410_BANKCON_Tcah2 (0x2 << 4) | 105 | #define S3C2410_BANKCON_Tcah2 (0x2 << 4) |
105 | #define S3C2410_BANKCON_Tcah4 (0x3 << 4) | 106 | #define S3C2410_BANKCON_Tcah4 (0x3 << 4) |
107 | #define S3C2410_BANKCON_Tcah_SHIFT (4) | ||
106 | 108 | ||
107 | #define S3C2410_BANKCON_Tcoh0 (0x0 << 6) | 109 | #define S3C2410_BANKCON_Tcoh0 (0x0 << 6) |
108 | #define S3C2410_BANKCON_Tcoh1 (0x1 << 6) | 110 | #define S3C2410_BANKCON_Tcoh1 (0x1 << 6) |
109 | #define S3C2410_BANKCON_Tcoh2 (0x2 << 6) | 111 | #define S3C2410_BANKCON_Tcoh2 (0x2 << 6) |
110 | #define S3C2410_BANKCON_Tcoh4 (0x3 << 6) | 112 | #define S3C2410_BANKCON_Tcoh4 (0x3 << 6) |
113 | #define S3C2410_BANKCON_Tcoh_SHIFT (6) | ||
111 | 114 | ||
112 | #define S3C2410_BANKCON_Tacc1 (0x0 << 8) | 115 | #define S3C2410_BANKCON_Tacc1 (0x0 << 8) |
113 | #define S3C2410_BANKCON_Tacc2 (0x1 << 8) | 116 | #define S3C2410_BANKCON_Tacc2 (0x1 << 8) |
@@ -117,16 +120,19 @@ | |||
117 | #define S3C2410_BANKCON_Tacc8 (0x5 << 8) | 120 | #define S3C2410_BANKCON_Tacc8 (0x5 << 8) |
118 | #define S3C2410_BANKCON_Tacc10 (0x6 << 8) | 121 | #define S3C2410_BANKCON_Tacc10 (0x6 << 8) |
119 | #define S3C2410_BANKCON_Tacc14 (0x7 << 8) | 122 | #define S3C2410_BANKCON_Tacc14 (0x7 << 8) |
123 | #define S3C2410_BANKCON_Tacc_SHIFT (8) | ||
120 | 124 | ||
121 | #define S3C2410_BANKCON_Tcos0 (0x0 << 11) | 125 | #define S3C2410_BANKCON_Tcos0 (0x0 << 11) |
122 | #define S3C2410_BANKCON_Tcos1 (0x1 << 11) | 126 | #define S3C2410_BANKCON_Tcos1 (0x1 << 11) |
123 | #define S3C2410_BANKCON_Tcos2 (0x2 << 11) | 127 | #define S3C2410_BANKCON_Tcos2 (0x2 << 11) |
124 | #define S3C2410_BANKCON_Tcos4 (0x3 << 11) | 128 | #define S3C2410_BANKCON_Tcos4 (0x3 << 11) |
129 | #define S3C2410_BANKCON_Tcos_SHIFT (11) | ||
125 | 130 | ||
126 | #define S3C2410_BANKCON_Tacs0 (0x0 << 13) | 131 | #define S3C2410_BANKCON_Tacs0 (0x0 << 13) |
127 | #define S3C2410_BANKCON_Tacs1 (0x1 << 13) | 132 | #define S3C2410_BANKCON_Tacs1 (0x1 << 13) |
128 | #define S3C2410_BANKCON_Tacs2 (0x2 << 13) | 133 | #define S3C2410_BANKCON_Tacs2 (0x2 << 13) |
129 | #define S3C2410_BANKCON_Tacs4 (0x3 << 13) | 134 | #define S3C2410_BANKCON_Tacs4 (0x3 << 13) |
135 | #define S3C2410_BANKCON_Tacs_SHIFT (13) | ||
130 | 136 | ||
131 | #define S3C2410_BANKCON_SRAM (0x0 << 15) | 137 | #define S3C2410_BANKCON_SRAM (0x0 << 15) |
132 | #define S3C2400_BANKCON_EDODRAM (0x2 << 15) | 138 | #define S3C2400_BANKCON_EDODRAM (0x2 << 15) |
diff --git a/include/asm-arm/arch-s3c2410/regs-power.h b/include/asm-arm/arch-s3c2410/regs-power.h index f79987be55e8..13d13b7cfe98 100644 --- a/include/asm-arm/arch-s3c2410/regs-power.h +++ b/include/asm-arm/arch-s3c2410/regs-power.h | |||
@@ -23,7 +23,8 @@ | |||
23 | #define S3C2412_INFORM2 S3C24XX_PWRREG(0x78) | 23 | #define S3C2412_INFORM2 S3C24XX_PWRREG(0x78) |
24 | #define S3C2412_INFORM3 S3C24XX_PWRREG(0x7C) | 24 | #define S3C2412_INFORM3 S3C24XX_PWRREG(0x7C) |
25 | 25 | ||
26 | #define S3C2412_PWRCFG_BATF_IGNORE (0<<0) | 26 | #define S3C2412_PWRCFG_BATF_IRQ (1<<0) |
27 | #define S3C2412_PWRCFG_BATF_IGNORE (2<<0) | ||
27 | #define S3C2412_PWRCFG_BATF_SLEEP (3<<0) | 28 | #define S3C2412_PWRCFG_BATF_SLEEP (3<<0) |
28 | #define S3C2412_PWRCFG_BATF_MASK (3<<0) | 29 | #define S3C2412_PWRCFG_BATF_MASK (3<<0) |
29 | 30 | ||
diff --git a/include/asm-arm/arch-s3c2410/system.h b/include/asm-arm/arch-s3c2410/system.h index 63891786dfa0..14de4e596f87 100644 --- a/include/asm-arm/arch-s3c2410/system.h +++ b/include/asm-arm/arch-s3c2410/system.h | |||
@@ -20,6 +20,9 @@ | |||
20 | #include <asm/plat-s3c/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 | #include <linux/clk.h> | ||
24 | #include <linux/err.h> | ||
25 | |||
23 | void (*s3c24xx_idle)(void); | 26 | void (*s3c24xx_idle)(void); |
24 | void (*s3c24xx_reset_hook)(void); | 27 | void (*s3c24xx_reset_hook)(void); |
25 | 28 | ||
@@ -59,6 +62,8 @@ static void arch_idle(void) | |||
59 | static void | 62 | static void |
60 | arch_reset(char mode) | 63 | arch_reset(char mode) |
61 | { | 64 | { |
65 | struct clk *wdtclk; | ||
66 | |||
62 | if (mode == 's') { | 67 | if (mode == 's') { |
63 | cpu_reset(0); | 68 | cpu_reset(0); |
64 | } | 69 | } |
@@ -70,19 +75,28 @@ arch_reset(char mode) | |||
70 | 75 | ||
71 | __raw_writel(0, S3C2410_WTCON); /* disable watchdog, to be safe */ | 76 | __raw_writel(0, S3C2410_WTCON); /* disable watchdog, to be safe */ |
72 | 77 | ||
78 | wdtclk = clk_get(NULL, "watchdog"); | ||
79 | if (!IS_ERR(wdtclk)) { | ||
80 | clk_enable(wdtclk); | ||
81 | } else | ||
82 | printk(KERN_WARNING "%s: warning: cannot get watchdog clock\n", __func__); | ||
83 | |||
73 | /* put initial values into count and data */ | 84 | /* put initial values into count and data */ |
74 | __raw_writel(0x100, S3C2410_WTCNT); | 85 | __raw_writel(0x80, S3C2410_WTCNT); |
75 | __raw_writel(0x100, S3C2410_WTDAT); | 86 | __raw_writel(0x80, S3C2410_WTDAT); |
76 | 87 | ||
77 | /* set the watchdog to go and reset... */ | 88 | /* set the watchdog to go and reset... */ |
78 | __raw_writel(S3C2410_WTCON_ENABLE|S3C2410_WTCON_DIV16|S3C2410_WTCON_RSTEN | | 89 | __raw_writel(S3C2410_WTCON_ENABLE|S3C2410_WTCON_DIV16|S3C2410_WTCON_RSTEN | |
79 | S3C2410_WTCON_PRESCALE(0x20), S3C2410_WTCON); | 90 | S3C2410_WTCON_PRESCALE(0x20), S3C2410_WTCON); |
80 | 91 | ||
81 | /* wait for reset to assert... */ | 92 | /* wait for reset to assert... */ |
82 | mdelay(5000); | 93 | mdelay(500); |
83 | 94 | ||
84 | printk(KERN_ERR "Watchdog reset failed to assert reset\n"); | 95 | printk(KERN_ERR "Watchdog reset failed to assert reset\n"); |
85 | 96 | ||
97 | /* delay to allow the serial port to show the message */ | ||
98 | mdelay(50); | ||
99 | |||
86 | /* we'll take a jump through zero as a poor second */ | 100 | /* we'll take a jump through zero as a poor second */ |
87 | cpu_reset(0); | 101 | cpu_reset(0); |
88 | } | 102 | } |
diff --git a/include/asm-arm/fpstate.h b/include/asm-arm/fpstate.h index f31cda5a55ee..392eb5332323 100644 --- a/include/asm-arm/fpstate.h +++ b/include/asm-arm/fpstate.h | |||
@@ -17,14 +17,18 @@ | |||
17 | /* | 17 | /* |
18 | * VFP storage area has: | 18 | * VFP storage area has: |
19 | * - FPEXC, FPSCR, FPINST and FPINST2. | 19 | * - FPEXC, FPSCR, FPINST and FPINST2. |
20 | * - 16 double precision data registers | 20 | * - 16 or 32 double precision data registers |
21 | * - an implementation-dependant word of state for FLDMX/FSTMX | 21 | * - an implementation-dependant word of state for FLDMX/FSTMX (pre-ARMv6) |
22 | * | 22 | * |
23 | * FPEXC will always be non-zero once the VFP has been used in this process. | 23 | * FPEXC will always be non-zero once the VFP has been used in this process. |
24 | */ | 24 | */ |
25 | 25 | ||
26 | struct vfp_hard_struct { | 26 | struct vfp_hard_struct { |
27 | #ifdef CONFIG_VFPv3 | ||
28 | __u64 fpregs[32]; | ||
29 | #else | ||
27 | __u64 fpregs[16]; | 30 | __u64 fpregs[16]; |
31 | #endif | ||
28 | #if __LINUX_ARM_ARCH__ < 6 | 32 | #if __LINUX_ARM_ARCH__ < 6 |
29 | __u32 fpmx_state; | 33 | __u32 fpmx_state; |
30 | #endif | 34 | #endif |
@@ -35,6 +39,7 @@ struct vfp_hard_struct { | |||
35 | */ | 39 | */ |
36 | __u32 fpinst; | 40 | __u32 fpinst; |
37 | __u32 fpinst2; | 41 | __u32 fpinst2; |
42 | |||
38 | #ifdef CONFIG_SMP | 43 | #ifdef CONFIG_SMP |
39 | __u32 cpu; | 44 | __u32 cpu; |
40 | #endif | 45 | #endif |
diff --git a/include/asm-arm/kprobes.h b/include/asm-arm/kprobes.h new file mode 100644 index 000000000000..4e7bd32288ae --- /dev/null +++ b/include/asm-arm/kprobes.h | |||
@@ -0,0 +1,79 @@ | |||
1 | /* | ||
2 | * include/asm-arm/kprobes.h | ||
3 | * | ||
4 | * Copyright (C) 2006, 2007 Motorola Inc. | ||
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 | * 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 GNU | ||
13 | * General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #ifndef _ARM_KPROBES_H | ||
17 | #define _ARM_KPROBES_H | ||
18 | |||
19 | #include <linux/types.h> | ||
20 | #include <linux/ptrace.h> | ||
21 | #include <linux/percpu.h> | ||
22 | |||
23 | #define ARCH_SUPPORTS_KRETPROBES | ||
24 | #define __ARCH_WANT_KPROBES_INSN_SLOT | ||
25 | #define MAX_INSN_SIZE 2 | ||
26 | #define MAX_STACK_SIZE 64 /* 32 would probably be OK */ | ||
27 | |||
28 | /* | ||
29 | * This undefined instruction must be unique and | ||
30 | * reserved solely for kprobes' use. | ||
31 | */ | ||
32 | #define KPROBE_BREAKPOINT_INSTRUCTION 0xe7f001f8 | ||
33 | |||
34 | #define regs_return_value(regs) ((regs)->ARM_r0) | ||
35 | #define flush_insn_slot(p) do { } while (0) | ||
36 | #define kretprobe_blacklist_size 0 | ||
37 | |||
38 | typedef u32 kprobe_opcode_t; | ||
39 | |||
40 | struct kprobe; | ||
41 | typedef void (kprobe_insn_handler_t)(struct kprobe *, struct pt_regs *); | ||
42 | |||
43 | /* Architecture specific copy of original instruction. */ | ||
44 | struct arch_specific_insn { | ||
45 | kprobe_opcode_t *insn; | ||
46 | kprobe_insn_handler_t *insn_handler; | ||
47 | }; | ||
48 | |||
49 | struct prev_kprobe { | ||
50 | struct kprobe *kp; | ||
51 | unsigned int status; | ||
52 | }; | ||
53 | |||
54 | /* per-cpu kprobe control block */ | ||
55 | struct kprobe_ctlblk { | ||
56 | unsigned int kprobe_status; | ||
57 | struct prev_kprobe prev_kprobe; | ||
58 | struct pt_regs jprobe_saved_regs; | ||
59 | char jprobes_stack[MAX_STACK_SIZE]; | ||
60 | }; | ||
61 | |||
62 | void arch_remove_kprobe(struct kprobe *); | ||
63 | |||
64 | int kprobe_trap_handler(struct pt_regs *regs, unsigned int instr); | ||
65 | int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr); | ||
66 | int kprobe_exceptions_notify(struct notifier_block *self, | ||
67 | unsigned long val, void *data); | ||
68 | |||
69 | enum kprobe_insn { | ||
70 | INSN_REJECTED, | ||
71 | INSN_GOOD, | ||
72 | INSN_GOOD_NO_SLOT | ||
73 | }; | ||
74 | |||
75 | enum kprobe_insn arm_kprobe_decode_insn(kprobe_opcode_t, | ||
76 | struct arch_specific_insn *); | ||
77 | void __init arm_kprobe_decode_init(void); | ||
78 | |||
79 | #endif /* _ARM_KPROBES_H */ | ||
diff --git a/include/asm-arm/plat-s3c24xx/dma.h b/include/asm-arm/plat-s3c24xx/dma.h index 2c59406435e5..c78efe316fc8 100644 --- a/include/asm-arm/plat-s3c24xx/dma.h +++ b/include/asm-arm/plat-s3c24xx/dma.h | |||
@@ -32,6 +32,7 @@ struct s3c24xx_dma_map { | |||
32 | struct s3c24xx_dma_addr hw_addr; | 32 | struct s3c24xx_dma_addr hw_addr; |
33 | 33 | ||
34 | unsigned long channels[S3C2410_DMA_CHANNELS]; | 34 | unsigned long channels[S3C2410_DMA_CHANNELS]; |
35 | unsigned long channels_rx[S3C2410_DMA_CHANNELS]; | ||
35 | }; | 36 | }; |
36 | 37 | ||
37 | struct s3c24xx_dma_selection { | 38 | struct s3c24xx_dma_selection { |
@@ -41,6 +42,10 @@ struct s3c24xx_dma_selection { | |||
41 | 42 | ||
42 | void (*select)(struct s3c2410_dma_chan *chan, | 43 | void (*select)(struct s3c2410_dma_chan *chan, |
43 | struct s3c24xx_dma_map *map); | 44 | struct s3c24xx_dma_map *map); |
45 | |||
46 | void (*direction)(struct s3c2410_dma_chan *chan, | ||
47 | struct s3c24xx_dma_map *map, | ||
48 | enum s3c2410_dmasrc dir); | ||
44 | }; | 49 | }; |
45 | 50 | ||
46 | extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel); | 51 | extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel); |
diff --git a/include/asm-arm/plat-s3c24xx/irq.h b/include/asm-arm/plat-s3c24xx/irq.h index 8af6d9579b31..45746a995343 100644 --- a/include/asm-arm/plat-s3c24xx/irq.h +++ b/include/asm-arm/plat-s3c24xx/irq.h | |||
@@ -15,7 +15,9 @@ | |||
15 | 15 | ||
16 | #define EXTINT_OFF (IRQ_EINT4 - 4) | 16 | #define EXTINT_OFF (IRQ_EINT4 - 4) |
17 | 17 | ||
18 | /* these are exported for arch/arm/mach-* usage */ | ||
18 | extern struct irq_chip s3c_irq_level_chip; | 19 | extern struct irq_chip s3c_irq_level_chip; |
20 | extern struct irq_chip s3c_irq_chip; | ||
19 | 21 | ||
20 | static inline void | 22 | static inline void |
21 | s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit, | 23 | s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit, |
diff --git a/include/asm-arm/plat-s3c24xx/regs-s3c2412-iis.h b/include/asm-arm/plat-s3c24xx/regs-s3c2412-iis.h new file mode 100644 index 000000000000..25d4058bcfed --- /dev/null +++ b/include/asm-arm/plat-s3c24xx/regs-s3c2412-iis.h | |||
@@ -0,0 +1,72 @@ | |||
1 | /* linux/include/asm-arm/plat-s3c24xx/regs-s3c2412-iis.h | ||
2 | * | ||
3 | * Copyright 2007 Simtec Electronics <linux@simtec.co.uk> | ||
4 | * http://armlinux.simtec.co.uk/ | ||
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 | * S3C2412 IIS register definition | ||
11 | */ | ||
12 | |||
13 | #ifndef __ASM_ARCH_REGS_S3C2412_IIS_H | ||
14 | #define __ASM_ARCH_REGS_S3C2412_IIS_H | ||
15 | |||
16 | #define S3C2412_IISCON (0x00) | ||
17 | #define S3C2412_IISMOD (0x04) | ||
18 | #define S3C2412_IISFIC (0x08) | ||
19 | #define S3C2412_IISPSR (0x0C) | ||
20 | #define S3C2412_IISTXD (0x10) | ||
21 | #define S3C2412_IISRXD (0x14) | ||
22 | |||
23 | #define S3C2412_IISCON_LRINDEX (1 << 11) | ||
24 | #define S3C2412_IISCON_TXFIFO_EMPTY (1 << 10) | ||
25 | #define S3C2412_IISCON_RXFIFO_EMPTY (1 << 9) | ||
26 | #define S3C2412_IISCON_TXFIFO_FULL (1 << 8) | ||
27 | #define S3C2412_IISCON_RXFIFO_FULL (1 << 7) | ||
28 | #define S3C2412_IISCON_TXDMA_PAUSE (1 << 6) | ||
29 | #define S3C2412_IISCON_RXDMA_PAUSE (1 << 5) | ||
30 | #define S3C2412_IISCON_TXCH_PAUSE (1 << 4) | ||
31 | #define S3C2412_IISCON_RXCH_PAUSE (1 << 3) | ||
32 | #define S3C2412_IISCON_TXDMA_ACTIVE (1 << 2) | ||
33 | #define S3C2412_IISCON_RXDMA_ACTIVE (1 << 1) | ||
34 | #define S3C2412_IISCON_IIS_ACTIVE (1 << 0) | ||
35 | |||
36 | #define S3C2412_IISMOD_MASTER_INTERNAL (0 << 10) | ||
37 | #define S3C2412_IISMOD_MASTER_EXTERNAL (1 << 10) | ||
38 | #define S3C2412_IISMOD_SLAVE (2 << 10) | ||
39 | #define S3C2412_IISMOD_MASTER_MASK (3 << 10) | ||
40 | #define S3C2412_IISMOD_MODE_TXONLY (0 << 8) | ||
41 | #define S3C2412_IISMOD_MODE_RXONLY (1 << 8) | ||
42 | #define S3C2412_IISMOD_MODE_TXRX (2 << 8) | ||
43 | #define S3C2412_IISMOD_MODE_MASK (3 << 8) | ||
44 | #define S3C2412_IISMOD_LR_LLOW (0 << 7) | ||
45 | #define S3C2412_IISMOD_LR_RLOW (1 << 7) | ||
46 | #define S3C2412_IISMOD_SDF_IIS (0 << 5) | ||
47 | #define S3C2412_IISMOD_SDF_MSB (0 << 5) | ||
48 | #define S3C2412_IISMOD_SDF_LSB (0 << 5) | ||
49 | #define S3C2412_IISMOD_SDF_MASK (3 << 5) | ||
50 | #define S3C2412_IISMOD_RCLK_256FS (0 << 3) | ||
51 | #define S3C2412_IISMOD_RCLK_512FS (1 << 3) | ||
52 | #define S3C2412_IISMOD_RCLK_384FS (2 << 3) | ||
53 | #define S3C2412_IISMOD_RCLK_768FS (3 << 3) | ||
54 | #define S3C2412_IISMOD_RCLK_MASK (3 << 3) | ||
55 | #define S3C2412_IISMOD_BCLK_32FS (0 << 1) | ||
56 | #define S3C2412_IISMOD_BCLK_48FS (1 << 1) | ||
57 | #define S3C2412_IISMOD_BCLK_16FS (2 << 1) | ||
58 | #define S3C2412_IISMOD_BCLK_24FS (3 << 1) | ||
59 | #define S3C2412_IISMOD_BCLK_MASK (3 << 1) | ||
60 | #define S3C2412_IISMOD_8BIT (1 << 0) | ||
61 | |||
62 | #define S3C2412_IISPSR_PSREN (1 << 15) | ||
63 | |||
64 | #define S3C2412_IISFIC_TXFLUSH (1 << 15) | ||
65 | #define S3C2412_IISFIC_RXFLUSH (1 << 7) | ||
66 | #define S3C2412_IISFIC_TXCOUNT(x) (((x) >> 8) & 0xf) | ||
67 | #define S3C2412_IISFIC_RXCOUNT(x) (((x) >> 0) & 0xf) | ||
68 | |||
69 | |||
70 | |||
71 | #endif /* __ASM_ARCH_REGS_S3C2412_IIS_H */ | ||
72 | |||
diff --git a/include/asm-arm/plat-s3c24xx/regs-spi.h b/include/asm-arm/plat-s3c24xx/regs-spi.h index 4a499a138256..ea565b007d04 100644 --- a/include/asm-arm/plat-s3c24xx/regs-spi.h +++ b/include/asm-arm/plat-s3c24xx/regs-spi.h | |||
@@ -17,6 +17,21 @@ | |||
17 | 17 | ||
18 | #define S3C2410_SPCON (0x00) | 18 | #define S3C2410_SPCON (0x00) |
19 | 19 | ||
20 | #define S3C2412_SPCON_RXFIFO_RB2 (0<<14) | ||
21 | #define S3C2412_SPCON_RXFIFO_RB4 (1<<14) | ||
22 | #define S3C2412_SPCON_RXFIFO_RB12 (2<<14) | ||
23 | #define S3C2412_SPCON_RXFIFO_RB14 (3<<14) | ||
24 | #define S3C2412_SPCON_TXFIFO_RB2 (0<<12) | ||
25 | #define S3C2412_SPCON_TXFIFO_RB4 (1<<12) | ||
26 | #define S3C2412_SPCON_TXFIFO_RB12 (2<<12) | ||
27 | #define S3C2412_SPCON_TXFIFO_RB14 (3<<12) | ||
28 | #define S3C2412_SPCON_RXFIFO_RESET (1<<11) /* RxFIFO reset */ | ||
29 | #define S3C2412_SPCON_TXFIFO_RESET (1<<10) /* TxFIFO reset */ | ||
30 | #define S3C2412_SPCON_RXFIFO_EN (1<<9) /* RxFIFO Enable */ | ||
31 | #define S3C2412_SPCON_TXFIFO_EN (1<<8) /* TxFIFO Enable */ | ||
32 | |||
33 | #define S3C2412_SPCON_DIRC_RX (1<<7) | ||
34 | |||
20 | #define S3C2410_SPCON_SMOD_DMA (2<<5) /* DMA mode */ | 35 | #define S3C2410_SPCON_SMOD_DMA (2<<5) /* DMA mode */ |
21 | #define S3C2410_SPCON_SMOD_INT (1<<5) /* interrupt mode */ | 36 | #define S3C2410_SPCON_SMOD_INT (1<<5) /* interrupt mode */ |
22 | #define S3C2410_SPCON_SMOD_POLL (0<<5) /* polling mode */ | 37 | #define S3C2410_SPCON_SMOD_POLL (0<<5) /* polling mode */ |
@@ -34,10 +49,19 @@ | |||
34 | 49 | ||
35 | #define S3C2410_SPSTA (0x04) | 50 | #define S3C2410_SPSTA (0x04) |
36 | 51 | ||
52 | #define S3C2412_SPSTA_RXFIFO_AE (1<<11) | ||
53 | #define S3C2412_SPSTA_TXFIFO_AE (1<<10) | ||
54 | #define S3C2412_SPSTA_RXFIFO_ERROR (1<<9) | ||
55 | #define S3C2412_SPSTA_TXFIFO_ERROR (1<<8) | ||
56 | #define S3C2412_SPSTA_RXFIFO_FIFO (1<<7) | ||
57 | #define S3C2412_SPSTA_RXFIFO_EMPTY (1<<6) | ||
58 | #define S3C2412_SPSTA_TXFIFO_NFULL (1<<5) | ||
59 | #define S3C2412_SPSTA_TXFIFO_EMPTY (1<<4) | ||
60 | |||
37 | #define S3C2410_SPSTA_DCOL (1<<2) /* Data Collision Error */ | 61 | #define S3C2410_SPSTA_DCOL (1<<2) /* Data Collision Error */ |
38 | #define S3C2410_SPSTA_MULD (1<<1) /* Multi Master Error */ | 62 | #define S3C2410_SPSTA_MULD (1<<1) /* Multi Master Error */ |
39 | #define S3C2410_SPSTA_READY (1<<0) /* Data Tx/Rx ready */ | 63 | #define S3C2410_SPSTA_READY (1<<0) /* Data Tx/Rx ready */ |
40 | 64 | #define S3C2412_SPSTA_READY_ORG (1<<3) | |
41 | 65 | ||
42 | #define S3C2410_SPPIN (0x08) | 66 | #define S3C2410_SPPIN (0x08) |
43 | 67 | ||
@@ -46,9 +70,13 @@ | |||
46 | #define S3C2400_SPPIN_nCS (1<<1) /* SPI Card Select */ | 70 | #define S3C2400_SPPIN_nCS (1<<1) /* SPI Card Select */ |
47 | #define S3C2410_SPPIN_KEEP (1<<0) /* Master Out keep */ | 71 | #define S3C2410_SPPIN_KEEP (1<<0) /* Master Out keep */ |
48 | 72 | ||
49 | |||
50 | #define S3C2410_SPPRE (0x0C) | 73 | #define S3C2410_SPPRE (0x0C) |
51 | #define S3C2410_SPTDAT (0x10) | 74 | #define S3C2410_SPTDAT (0x10) |
52 | #define S3C2410_SPRDAT (0x14) | 75 | #define S3C2410_SPRDAT (0x14) |
53 | 76 | ||
77 | #define S3C2412_TXFIFO (0x18) | ||
78 | #define S3C2412_RXFIFO (0x18) | ||
79 | #define S3C2412_SPFIC (0x24) | ||
80 | |||
81 | |||
54 | #endif /* __ASM_ARCH_REGS_SPI_H */ | 82 | #endif /* __ASM_ARCH_REGS_SPI_H */ |
diff --git a/include/asm-arm/traps.h b/include/asm-arm/traps.h index d4f34dc83eb0..f1541afcf85c 100644 --- a/include/asm-arm/traps.h +++ b/include/asm-arm/traps.h | |||
@@ -15,4 +15,13 @@ struct undef_hook { | |||
15 | void register_undef_hook(struct undef_hook *hook); | 15 | void register_undef_hook(struct undef_hook *hook); |
16 | void unregister_undef_hook(struct undef_hook *hook); | 16 | void unregister_undef_hook(struct undef_hook *hook); |
17 | 17 | ||
18 | static inline int in_exception_text(unsigned long ptr) | ||
19 | { | ||
20 | extern char __exception_text_start[]; | ||
21 | extern char __exception_text_end[]; | ||
22 | |||
23 | return ptr >= (unsigned long)&__exception_text_start && | ||
24 | ptr < (unsigned long)&__exception_text_end; | ||
25 | } | ||
26 | |||
18 | #endif | 27 | #endif |
diff --git a/include/asm-arm/vfp.h b/include/asm-arm/vfp.h index bd6be9d7f772..5f9a2cb3d452 100644 --- a/include/asm-arm/vfp.h +++ b/include/asm-arm/vfp.h | |||
@@ -7,7 +7,11 @@ | |||
7 | 7 | ||
8 | #define FPSID cr0 | 8 | #define FPSID cr0 |
9 | #define FPSCR cr1 | 9 | #define FPSCR cr1 |
10 | #define MVFR1 cr6 | ||
11 | #define MVFR0 cr7 | ||
10 | #define FPEXC cr8 | 12 | #define FPEXC cr8 |
13 | #define FPINST cr9 | ||
14 | #define FPINST2 cr10 | ||
11 | 15 | ||
12 | /* FPSID bits */ | 16 | /* FPSID bits */ |
13 | #define FPSID_IMPLEMENTER_BIT (24) | 17 | #define FPSID_IMPLEMENTER_BIT (24) |
@@ -28,6 +32,19 @@ | |||
28 | /* FPEXC bits */ | 32 | /* FPEXC bits */ |
29 | #define FPEXC_EX (1 << 31) | 33 | #define FPEXC_EX (1 << 31) |
30 | #define FPEXC_EN (1 << 30) | 34 | #define FPEXC_EN (1 << 30) |
35 | #define FPEXC_DEX (1 << 29) | ||
36 | #define FPEXC_FP2V (1 << 28) | ||
37 | #define FPEXC_VV (1 << 27) | ||
38 | #define FPEXC_TFV (1 << 26) | ||
39 | #define FPEXC_LENGTH_BIT (8) | ||
40 | #define FPEXC_LENGTH_MASK (7 << FPEXC_LENGTH_BIT) | ||
41 | #define FPEXC_IDF (1 << 7) | ||
42 | #define FPEXC_IXF (1 << 4) | ||
43 | #define FPEXC_UFF (1 << 3) | ||
44 | #define FPEXC_OFF (1 << 2) | ||
45 | #define FPEXC_DZF (1 << 1) | ||
46 | #define FPEXC_IOF (1 << 0) | ||
47 | #define FPEXC_TRAP_MASK (FPEXC_IDF|FPEXC_IXF|FPEXC_UFF|FPEXC_OFF|FPEXC_DZF|FPEXC_IOF) | ||
31 | 48 | ||
32 | /* FPSCR bits */ | 49 | /* FPSCR bits */ |
33 | #define FPSCR_DEFAULT_NAN (1<<25) | 50 | #define FPSCR_DEFAULT_NAN (1<<25) |
@@ -55,20 +72,9 @@ | |||
55 | #define FPSCR_IXC (1<<4) | 72 | #define FPSCR_IXC (1<<4) |
56 | #define FPSCR_IDC (1<<7) | 73 | #define FPSCR_IDC (1<<7) |
57 | 74 | ||
58 | /* | 75 | /* MVFR0 bits */ |
59 | * VFP9-S specific. | 76 | #define MVFR0_A_SIMD_BIT (0) |
60 | */ | 77 | #define MVFR0_A_SIMD_MASK (0xf << MVFR0_A_SIMD_BIT) |
61 | #define FPINST cr9 | ||
62 | #define FPINST2 cr10 | ||
63 | |||
64 | /* FPEXC bits */ | ||
65 | #define FPEXC_FPV2 (1<<28) | ||
66 | #define FPEXC_LENGTH_BIT (8) | ||
67 | #define FPEXC_LENGTH_MASK (7 << FPEXC_LENGTH_BIT) | ||
68 | #define FPEXC_INV (1 << 7) | ||
69 | #define FPEXC_UFC (1 << 3) | ||
70 | #define FPEXC_OFC (1 << 2) | ||
71 | #define FPEXC_IOC (1 << 0) | ||
72 | 78 | ||
73 | /* Bit patterns for decoding the packaged operation descriptors */ | 79 | /* Bit patterns for decoding the packaged operation descriptors */ |
74 | #define VFPOPDESC_LENGTH_BIT (9) | 80 | #define VFPOPDESC_LENGTH_BIT (9) |
diff --git a/include/asm-arm/vfpmacros.h b/include/asm-arm/vfpmacros.h index 27fe028b4e72..cccb3892e73c 100644 --- a/include/asm-arm/vfpmacros.h +++ b/include/asm-arm/vfpmacros.h | |||
@@ -15,19 +15,33 @@ | |||
15 | .endm | 15 | .endm |
16 | 16 | ||
17 | @ read all the working registers back into the VFP | 17 | @ read all the working registers back into the VFP |
18 | .macro VFPFLDMIA, base | 18 | .macro VFPFLDMIA, base, tmp |
19 | #if __LINUX_ARM_ARCH__ < 6 | 19 | #if __LINUX_ARM_ARCH__ < 6 |
20 | LDC p11, cr0, [\base],#33*4 @ FLDMIAX \base!, {d0-d15} | 20 | LDC p11, cr0, [\base],#33*4 @ FLDMIAX \base!, {d0-d15} |
21 | #else | 21 | #else |
22 | LDC p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d0-d15} | 22 | LDC p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d0-d15} |
23 | #endif | 23 | #endif |
24 | #ifdef CONFIG_VFPv3 | ||
25 | VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0 | ||
26 | and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field | ||
27 | cmp \tmp, #2 @ 32 x 64bit registers? | ||
28 | ldceql p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31} | ||
29 | addne \base, \base, #32*4 @ step over unused register space | ||
30 | #endif | ||
24 | .endm | 31 | .endm |
25 | 32 | ||
26 | @ write all the working registers out of the VFP | 33 | @ write all the working registers out of the VFP |
27 | .macro VFPFSTMIA, base | 34 | .macro VFPFSTMIA, base, tmp |
28 | #if __LINUX_ARM_ARCH__ < 6 | 35 | #if __LINUX_ARM_ARCH__ < 6 |
29 | STC p11, cr0, [\base],#33*4 @ FSTMIAX \base!, {d0-d15} | 36 | STC p11, cr0, [\base],#33*4 @ FSTMIAX \base!, {d0-d15} |
30 | #else | 37 | #else |
31 | STC p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d0-d15} | 38 | STC p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d0-d15} |
32 | #endif | 39 | #endif |
40 | #ifdef CONFIG_VFPv3 | ||
41 | VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0 | ||
42 | and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field | ||
43 | cmp \tmp, #2 @ 32 x 64bit registers? | ||
44 | stceql p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31} | ||
45 | addne \base, \base, #32*4 @ step over unused register space | ||
46 | #endif | ||
33 | .endm | 47 | .endm |
diff --git a/include/asm-avr32/arch-at32ap/cpu.h b/include/asm-avr32/arch-at32ap/cpu.h index 0dc20261c1ea..44d0bfa1f409 100644 --- a/include/asm-avr32/arch-at32ap/cpu.h +++ b/include/asm-avr32/arch-at32ap/cpu.h | |||
@@ -30,5 +30,6 @@ | |||
30 | #define cpu_is_at91sam9261() (0) | 30 | #define cpu_is_at91sam9261() (0) |
31 | #define cpu_is_at91sam9263() (0) | 31 | #define cpu_is_at91sam9263() (0) |
32 | #define cpu_is_at91sam9rl() (0) | 32 | #define cpu_is_at91sam9rl() (0) |
33 | #define cpu_is_at91cap9() (0) | ||
33 | 34 | ||
34 | #endif /* __ASM_ARCH_CPU_H */ | 35 | #endif /* __ASM_ARCH_CPU_H */ |
diff --git a/include/asm-blackfin/bfin-global.h b/include/asm-blackfin/bfin-global.h index 39bdd86871cf..6ae0619d7696 100644 --- a/include/asm-blackfin/bfin-global.h +++ b/include/asm-blackfin/bfin-global.h | |||
@@ -51,7 +51,7 @@ extern unsigned long sclk_to_usecs(unsigned long sclk); | |||
51 | extern unsigned long usecs_to_sclk(unsigned long usecs); | 51 | extern unsigned long usecs_to_sclk(unsigned long usecs); |
52 | 52 | ||
53 | extern void dump_bfin_process(struct pt_regs *regs); | 53 | extern void dump_bfin_process(struct pt_regs *regs); |
54 | extern void dump_bfin_mem(void *retaddr); | 54 | extern void dump_bfin_mem(struct pt_regs *regs); |
55 | extern void dump_bfin_trace_buffer(void); | 55 | extern void dump_bfin_trace_buffer(void); |
56 | 56 | ||
57 | extern int init_arch_irq(void); | 57 | extern int init_arch_irq(void); |
diff --git a/include/asm-blackfin/cplb-mpu.h b/include/asm-blackfin/cplb-mpu.h new file mode 100644 index 000000000000..75c67b99d607 --- /dev/null +++ b/include/asm-blackfin/cplb-mpu.h | |||
@@ -0,0 +1,61 @@ | |||
1 | /* | ||
2 | * File: include/asm-blackfin/cplbinit.h | ||
3 | * Based on: | ||
4 | * Author: | ||
5 | * | ||
6 | * Created: | ||
7 | * Description: | ||
8 | * | ||
9 | * Modified: | ||
10 | * Copyright 2004-2006 Analog Devices Inc. | ||
11 | * | ||
12 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License as published by | ||
16 | * the Free Software Foundation; either version 2 of the License, or | ||
17 | * (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, see the file COPYING, or write | ||
26 | * to the Free Software Foundation, Inc., | ||
27 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
28 | */ | ||
29 | #ifndef __ASM_BFIN_CPLB_MPU_H | ||
30 | #define __ASM_BFIN_CPLB_MPU_H | ||
31 | |||
32 | struct cplb_entry { | ||
33 | unsigned long data, addr; | ||
34 | }; | ||
35 | |||
36 | struct mem_region { | ||
37 | unsigned long start, end; | ||
38 | unsigned long dcplb_data; | ||
39 | unsigned long icplb_data; | ||
40 | }; | ||
41 | |||
42 | extern struct cplb_entry dcplb_tbl[MAX_CPLBS]; | ||
43 | extern struct cplb_entry icplb_tbl[MAX_CPLBS]; | ||
44 | extern int first_switched_icplb; | ||
45 | extern int first_mask_dcplb; | ||
46 | extern int first_switched_dcplb; | ||
47 | |||
48 | extern int nr_dcplb_miss, nr_icplb_miss, nr_icplb_supv_miss, nr_dcplb_prot; | ||
49 | extern int nr_cplb_flush; | ||
50 | |||
51 | extern int page_mask_order; | ||
52 | extern int page_mask_nelts; | ||
53 | |||
54 | extern unsigned long *current_rwx_mask; | ||
55 | |||
56 | extern void flush_switched_cplbs(void); | ||
57 | extern void set_mask_dcplbs(unsigned long *); | ||
58 | |||
59 | extern void __noreturn panic_cplb_error(int seqstat, struct pt_regs *); | ||
60 | |||
61 | #endif /* __ASM_BFIN_CPLB_MPU_H */ | ||
diff --git a/include/asm-blackfin/cplb.h b/include/asm-blackfin/cplb.h index 06828d77a58f..654375c2b746 100644 --- a/include/asm-blackfin/cplb.h +++ b/include/asm-blackfin/cplb.h | |||
@@ -65,7 +65,11 @@ | |||
65 | #define SIZE_1M 0x00100000 /* 1M */ | 65 | #define SIZE_1M 0x00100000 /* 1M */ |
66 | #define SIZE_4M 0x00400000 /* 4M */ | 66 | #define SIZE_4M 0x00400000 /* 4M */ |
67 | 67 | ||
68 | #ifdef CONFIG_MPU | ||
69 | #define MAX_CPLBS 16 | ||
70 | #else | ||
68 | #define MAX_CPLBS (16 * 2) | 71 | #define MAX_CPLBS (16 * 2) |
72 | #endif | ||
69 | 73 | ||
70 | #define ASYNC_MEMORY_CPLB_COVERAGE ((ASYNC_BANK0_SIZE + ASYNC_BANK1_SIZE + \ | 74 | #define ASYNC_MEMORY_CPLB_COVERAGE ((ASYNC_BANK0_SIZE + ASYNC_BANK1_SIZE + \ |
71 | ASYNC_BANK2_SIZE + ASYNC_BANK3_SIZE) / SIZE_4M) | 75 | ASYNC_BANK2_SIZE + ASYNC_BANK3_SIZE) / SIZE_4M) |
diff --git a/include/asm-blackfin/cplbinit.h b/include/asm-blackfin/cplbinit.h index c4d0596e8e9f..0eb1c1b685a7 100644 --- a/include/asm-blackfin/cplbinit.h +++ b/include/asm-blackfin/cplbinit.h | |||
@@ -33,6 +33,12 @@ | |||
33 | #include <asm/blackfin.h> | 33 | #include <asm/blackfin.h> |
34 | #include <asm/cplb.h> | 34 | #include <asm/cplb.h> |
35 | 35 | ||
36 | #ifdef CONFIG_MPU | ||
37 | |||
38 | #include <asm/cplb-mpu.h> | ||
39 | |||
40 | #else | ||
41 | |||
36 | #define INITIAL_T 0x1 | 42 | #define INITIAL_T 0x1 |
37 | #define SWITCH_T 0x2 | 43 | #define SWITCH_T 0x2 |
38 | #define I_CPLB 0x4 | 44 | #define I_CPLB 0x4 |
@@ -79,6 +85,8 @@ extern u_long ipdt_swapcount_table[]; | |||
79 | extern u_long dpdt_swapcount_table[]; | 85 | extern u_long dpdt_swapcount_table[]; |
80 | #endif | 86 | #endif |
81 | 87 | ||
88 | #endif /* CONFIG_MPU */ | ||
89 | |||
82 | extern unsigned long reserved_mem_dcache_on; | 90 | extern unsigned long reserved_mem_dcache_on; |
83 | extern unsigned long reserved_mem_icache_on; | 91 | extern unsigned long reserved_mem_icache_on; |
84 | 92 | ||
diff --git a/include/asm-blackfin/dma.h b/include/asm-blackfin/dma.h index b469505af364..5abaa2cee8db 100644 --- a/include/asm-blackfin/dma.h +++ b/include/asm-blackfin/dma.h | |||
@@ -76,6 +76,9 @@ enum dma_chan_status { | |||
76 | #define INTR_ON_BUF 2 | 76 | #define INTR_ON_BUF 2 |
77 | #define INTR_ON_ROW 3 | 77 | #define INTR_ON_ROW 3 |
78 | 78 | ||
79 | #define DMA_NOSYNC_KEEP_DMA_BUF 0 | ||
80 | #define DMA_SYNC_RESTART 1 | ||
81 | |||
79 | struct dmasg { | 82 | struct dmasg { |
80 | unsigned long next_desc_addr; | 83 | unsigned long next_desc_addr; |
81 | unsigned long start_addr; | 84 | unsigned long start_addr; |
@@ -157,7 +160,8 @@ void set_dma_y_count(unsigned int channel, unsigned short y_count); | |||
157 | void set_dma_y_modify(unsigned int channel, short y_modify); | 160 | void set_dma_y_modify(unsigned int channel, short y_modify); |
158 | void set_dma_config(unsigned int channel, unsigned short config); | 161 | void set_dma_config(unsigned int channel, unsigned short config); |
159 | unsigned short set_bfin_dma_config(char direction, char flow_mode, | 162 | unsigned short set_bfin_dma_config(char direction, char flow_mode, |
160 | char intr_mode, char dma_mode, char width); | 163 | char intr_mode, char dma_mode, char width, |
164 | char syncmode); | ||
161 | void set_dma_curr_addr(unsigned int channel, unsigned long addr); | 165 | void set_dma_curr_addr(unsigned int channel, unsigned long addr); |
162 | 166 | ||
163 | /* get curr status for polling */ | 167 | /* get curr status for polling */ |
diff --git a/include/asm-blackfin/gpio.h b/include/asm-blackfin/gpio.h index 33ce98ef7e0f..d0426c108262 100644 --- a/include/asm-blackfin/gpio.h +++ b/include/asm-blackfin/gpio.h | |||
@@ -7,7 +7,7 @@ | |||
7 | * Description: | 7 | * Description: |
8 | * | 8 | * |
9 | * Modified: | 9 | * Modified: |
10 | * Copyright 2004-2006 Analog Devices Inc. | 10 | * Copyright 2004-2008 Analog Devices Inc. |
11 | * | 11 | * |
12 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | 12 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ |
13 | * | 13 | * |
@@ -304,39 +304,39 @@ | |||
304 | **************************************************************/ | 304 | **************************************************************/ |
305 | 305 | ||
306 | #ifndef BF548_FAMILY | 306 | #ifndef BF548_FAMILY |
307 | void set_gpio_dir(unsigned short, unsigned short); | 307 | void set_gpio_dir(unsigned, unsigned short); |
308 | void set_gpio_inen(unsigned short, unsigned short); | 308 | void set_gpio_inen(unsigned, unsigned short); |
309 | void set_gpio_polar(unsigned short, unsigned short); | 309 | void set_gpio_polar(unsigned, unsigned short); |
310 | void set_gpio_edge(unsigned short, unsigned short); | 310 | void set_gpio_edge(unsigned, unsigned short); |
311 | void set_gpio_both(unsigned short, unsigned short); | 311 | void set_gpio_both(unsigned, unsigned short); |
312 | void set_gpio_data(unsigned short, unsigned short); | 312 | void set_gpio_data(unsigned, unsigned short); |
313 | void set_gpio_maska(unsigned short, unsigned short); | 313 | void set_gpio_maska(unsigned, unsigned short); |
314 | void set_gpio_maskb(unsigned short, unsigned short); | 314 | void set_gpio_maskb(unsigned, unsigned short); |
315 | void set_gpio_toggle(unsigned short); | 315 | void set_gpio_toggle(unsigned); |
316 | void set_gpiop_dir(unsigned short, unsigned short); | 316 | void set_gpiop_dir(unsigned, unsigned short); |
317 | void set_gpiop_inen(unsigned short, unsigned short); | 317 | void set_gpiop_inen(unsigned, unsigned short); |
318 | void set_gpiop_polar(unsigned short, unsigned short); | 318 | void set_gpiop_polar(unsigned, unsigned short); |
319 | void set_gpiop_edge(unsigned short, unsigned short); | 319 | void set_gpiop_edge(unsigned, unsigned short); |
320 | void set_gpiop_both(unsigned short, unsigned short); | 320 | void set_gpiop_both(unsigned, unsigned short); |
321 | void set_gpiop_data(unsigned short, unsigned short); | 321 | void set_gpiop_data(unsigned, unsigned short); |
322 | void set_gpiop_maska(unsigned short, unsigned short); | 322 | void set_gpiop_maska(unsigned, unsigned short); |
323 | void set_gpiop_maskb(unsigned short, unsigned short); | 323 | void set_gpiop_maskb(unsigned, unsigned short); |
324 | unsigned short get_gpio_dir(unsigned short); | 324 | unsigned short get_gpio_dir(unsigned); |
325 | unsigned short get_gpio_inen(unsigned short); | 325 | unsigned short get_gpio_inen(unsigned); |
326 | unsigned short get_gpio_polar(unsigned short); | 326 | unsigned short get_gpio_polar(unsigned); |
327 | unsigned short get_gpio_edge(unsigned short); | 327 | unsigned short get_gpio_edge(unsigned); |
328 | unsigned short get_gpio_both(unsigned short); | 328 | unsigned short get_gpio_both(unsigned); |
329 | unsigned short get_gpio_maska(unsigned short); | 329 | unsigned short get_gpio_maska(unsigned); |
330 | unsigned short get_gpio_maskb(unsigned short); | 330 | unsigned short get_gpio_maskb(unsigned); |
331 | unsigned short get_gpio_data(unsigned short); | 331 | unsigned short get_gpio_data(unsigned); |
332 | unsigned short get_gpiop_dir(unsigned short); | 332 | unsigned short get_gpiop_dir(unsigned); |
333 | unsigned short get_gpiop_inen(unsigned short); | 333 | unsigned short get_gpiop_inen(unsigned); |
334 | unsigned short get_gpiop_polar(unsigned short); | 334 | unsigned short get_gpiop_polar(unsigned); |
335 | unsigned short get_gpiop_edge(unsigned short); | 335 | unsigned short get_gpiop_edge(unsigned); |
336 | unsigned short get_gpiop_both(unsigned short); | 336 | unsigned short get_gpiop_both(unsigned); |
337 | unsigned short get_gpiop_maska(unsigned short); | 337 | unsigned short get_gpiop_maska(unsigned); |
338 | unsigned short get_gpiop_maskb(unsigned short); | 338 | unsigned short get_gpiop_maskb(unsigned); |
339 | unsigned short get_gpiop_data(unsigned short); | 339 | unsigned short get_gpiop_data(unsigned); |
340 | 340 | ||
341 | struct gpio_port_t { | 341 | struct gpio_port_t { |
342 | unsigned short data; | 342 | unsigned short data; |
@@ -382,8 +382,8 @@ struct gpio_port_t { | |||
382 | #define PM_WAKE_LOW 0x8 | 382 | #define PM_WAKE_LOW 0x8 |
383 | #define PM_WAKE_BOTH_EDGES (PM_WAKE_RISING | PM_WAKE_FALLING) | 383 | #define PM_WAKE_BOTH_EDGES (PM_WAKE_RISING | PM_WAKE_FALLING) |
384 | 384 | ||
385 | int gpio_pm_wakeup_request(unsigned short gpio, unsigned char type); | 385 | int gpio_pm_wakeup_request(unsigned gpio, unsigned char type); |
386 | void gpio_pm_wakeup_free(unsigned short gpio); | 386 | void gpio_pm_wakeup_free(unsigned gpio); |
387 | unsigned int gpio_pm_setup(void); | 387 | unsigned int gpio_pm_setup(void); |
388 | void gpio_pm_restore(void); | 388 | void gpio_pm_restore(void); |
389 | 389 | ||
@@ -426,19 +426,19 @@ struct gpio_port_s { | |||
426 | * MODIFICATION HISTORY : | 426 | * MODIFICATION HISTORY : |
427 | **************************************************************/ | 427 | **************************************************************/ |
428 | 428 | ||
429 | int gpio_request(unsigned short, const char *); | 429 | int gpio_request(unsigned, const char *); |
430 | void gpio_free(unsigned short); | 430 | void gpio_free(unsigned); |
431 | 431 | ||
432 | void gpio_set_value(unsigned short gpio, unsigned short arg); | 432 | void gpio_set_value(unsigned gpio, int arg); |
433 | unsigned short gpio_get_value(unsigned short gpio); | 433 | int gpio_get_value(unsigned gpio); |
434 | 434 | ||
435 | #ifndef BF548_FAMILY | 435 | #ifndef BF548_FAMILY |
436 | #define gpio_get_value(gpio) get_gpio_data(gpio) | 436 | #define gpio_get_value(gpio) get_gpio_data(gpio) |
437 | #define gpio_set_value(gpio, value) set_gpio_data(gpio, value) | 437 | #define gpio_set_value(gpio, value) set_gpio_data(gpio, value) |
438 | #endif | 438 | #endif |
439 | 439 | ||
440 | void gpio_direction_input(unsigned short gpio); | 440 | int gpio_direction_input(unsigned gpio); |
441 | void gpio_direction_output(unsigned short gpio); | 441 | int gpio_direction_output(unsigned gpio, int value); |
442 | 442 | ||
443 | #include <asm-generic/gpio.h> /* cansleep wrappers */ | 443 | #include <asm-generic/gpio.h> /* cansleep wrappers */ |
444 | #include <asm/irq.h> | 444 | #include <asm/irq.h> |
diff --git a/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h index 0b867e6a76c4..15dbc21eed8b 100644 --- a/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h | |||
@@ -146,7 +146,7 @@ static void bfin_serial_hw_init(struct bfin_serial_port *uart) | |||
146 | 146 | ||
147 | if (uart->rts_pin >= 0) { | 147 | if (uart->rts_pin >= 0) { |
148 | gpio_request(uart->rts_pin, DRIVER_NAME); | 148 | gpio_request(uart->rts_pin, DRIVER_NAME); |
149 | gpio_direction_output(uart->rts_pin); | 149 | gpio_direction_output(uart->rts_pin, 0); |
150 | } | 150 | } |
151 | #endif | 151 | #endif |
152 | } | 152 | } |
diff --git a/include/asm-blackfin/mach-bf527/portmux.h b/include/asm-blackfin/mach-bf527/portmux.h index dcf001adc63c..ae4d205bfcf5 100644 --- a/include/asm-blackfin/mach-bf527/portmux.h +++ b/include/asm-blackfin/mach-bf527/portmux.h | |||
@@ -1,6 +1,8 @@ | |||
1 | #ifndef _MACH_PORTMUX_H_ | 1 | #ifndef _MACH_PORTMUX_H_ |
2 | #define _MACH_PORTMUX_H_ | 2 | #define _MACH_PORTMUX_H_ |
3 | 3 | ||
4 | #define MAX_RESOURCES MAX_BLACKFIN_GPIOS | ||
5 | |||
4 | #define P_PPI0_D0 (P_DEFINED | P_IDENT(GPIO_PF0) | P_FUNCT(0)) | 6 | #define P_PPI0_D0 (P_DEFINED | P_IDENT(GPIO_PF0) | P_FUNCT(0)) |
5 | #define P_PPI0_D1 (P_DEFINED | P_IDENT(GPIO_PF1) | P_FUNCT(0)) | 7 | #define P_PPI0_D1 (P_DEFINED | P_IDENT(GPIO_PF1) | P_FUNCT(0)) |
6 | #define P_PPI0_D2 (P_DEFINED | P_IDENT(GPIO_PF2) | P_FUNCT(0)) | 8 | #define P_PPI0_D2 (P_DEFINED | P_IDENT(GPIO_PF2) | P_FUNCT(0)) |
diff --git a/include/asm-blackfin/mach-bf533/anomaly.h b/include/asm-blackfin/mach-bf533/anomaly.h index f36ff5af1b91..98209d40abba 100644 --- a/include/asm-blackfin/mach-bf533/anomaly.h +++ b/include/asm-blackfin/mach-bf533/anomaly.h | |||
@@ -7,9 +7,7 @@ | |||
7 | */ | 7 | */ |
8 | 8 | ||
9 | /* This file shoule be up to date with: | 9 | /* This file shoule be up to date with: |
10 | * - Revision X, March 23, 2007; ADSP-BF533 Blackfin Processor Anomaly List | 10 | * - Revision B, 12/10/2007; ADSP-BF531/BF532/BF533 Blackfin Processor Anomaly List |
11 | * - Revision AB, March 23, 2007; ADSP-BF532 Blackfin Processor Anomaly List | ||
12 | * - Revision W, March 23, 2007; ADSP-BF531 Blackfin Processor Anomaly List | ||
13 | */ | 11 | */ |
14 | 12 | ||
15 | #ifndef _MACH_ANOMALY_H_ | 13 | #ifndef _MACH_ANOMALY_H_ |
@@ -17,7 +15,7 @@ | |||
17 | 15 | ||
18 | /* We do not support 0.1 or 0.2 silicon - sorry */ | 16 | /* We do not support 0.1 or 0.2 silicon - sorry */ |
19 | #if __SILICON_REVISION__ < 3 | 17 | #if __SILICON_REVISION__ < 3 |
20 | # error Kernel will not work on BF533 silicon version 0.0, 0.1, or 0.2 | 18 | # error will not work on BF533 silicon version 0.0, 0.1, or 0.2 |
21 | #endif | 19 | #endif |
22 | 20 | ||
23 | #if defined(__ADSPBF531__) | 21 | #if defined(__ADSPBF531__) |
@@ -251,6 +249,12 @@ | |||
251 | #define ANOMALY_05000192 (__SILICON_REVISION__ < 3) | 249 | #define ANOMALY_05000192 (__SILICON_REVISION__ < 3) |
252 | /* Internal Voltage Regulator may not start up */ | 250 | /* Internal Voltage Regulator may not start up */ |
253 | #define ANOMALY_05000206 (__SILICON_REVISION__ < 3) | 251 | #define ANOMALY_05000206 (__SILICON_REVISION__ < 3) |
252 | /* Serial Port (SPORT) Multichannel Transmit Failure when Channel 0 Is Disabled */ | ||
253 | #define ANOMALY_05000357 (1) | ||
254 | /* PPI Underflow Error Goes Undetected in ITU-R 656 Mode */ | ||
255 | #define ANOMALY_05000366 (1) | ||
256 | /* Possible RETS Register Corruption when Subroutine Is under 5 Cycles in Duration */ | ||
257 | #define ANOMALY_05000371 (1) | ||
254 | 258 | ||
255 | /* Anomalies that don't exist on this proc */ | 259 | /* Anomalies that don't exist on this proc */ |
256 | #define ANOMALY_05000266 (0) | 260 | #define ANOMALY_05000266 (0) |
diff --git a/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h index 69b9f8e120e9..7871d4313f49 100644 --- a/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h | |||
@@ -111,7 +111,7 @@ static void bfin_serial_hw_init(struct bfin_serial_port *uart) | |||
111 | } | 111 | } |
112 | if (uart->rts_pin >= 0) { | 112 | if (uart->rts_pin >= 0) { |
113 | gpio_request(uart->rts_pin, DRIVER_NAME); | 113 | gpio_request(uart->rts_pin, DRIVER_NAME); |
114 | gpio_direction_input(uart->rts_pin); | 114 | gpio_direction_input(uart->rts_pin, 0); |
115 | } | 115 | } |
116 | #endif | 116 | #endif |
117 | } | 117 | } |
diff --git a/include/asm-blackfin/mach-bf533/portmux.h b/include/asm-blackfin/mach-bf533/portmux.h index 137f4884acfe..685a2651dcda 100644 --- a/include/asm-blackfin/mach-bf533/portmux.h +++ b/include/asm-blackfin/mach-bf533/portmux.h | |||
@@ -1,6 +1,8 @@ | |||
1 | #ifndef _MACH_PORTMUX_H_ | 1 | #ifndef _MACH_PORTMUX_H_ |
2 | #define _MACH_PORTMUX_H_ | 2 | #define _MACH_PORTMUX_H_ |
3 | 3 | ||
4 | #define MAX_RESOURCES MAX_BLACKFIN_GPIOS | ||
5 | |||
4 | #define P_PPI0_CLK (P_DONTCARE) | 6 | #define P_PPI0_CLK (P_DONTCARE) |
5 | #define P_PPI0_FS1 (P_DONTCARE) | 7 | #define P_PPI0_FS1 (P_DONTCARE) |
6 | #define P_PPI0_FS2 (P_DONTCARE) | 8 | #define P_PPI0_FS2 (P_DONTCARE) |
diff --git a/include/asm-blackfin/mach-bf537/anomaly.h b/include/asm-blackfin/mach-bf537/anomaly.h index 2b66ecf489f7..746a794b3119 100644 --- a/include/asm-blackfin/mach-bf537/anomaly.h +++ b/include/asm-blackfin/mach-bf537/anomaly.h | |||
@@ -7,9 +7,7 @@ | |||
7 | */ | 7 | */ |
8 | 8 | ||
9 | /* This file shoule be up to date with: | 9 | /* This file shoule be up to date with: |
10 | * - Revision M, March 13, 2007; ADSP-BF537 Blackfin Processor Anomaly List | 10 | * - Revision A, 09/04/2007; ADSP-BF534/ADSP-BF536/ADSP-BF537 Blackfin Processor Anomaly List |
11 | * - Revision L, March 13, 2007; ADSP-BF536 Blackfin Processor Anomaly List | ||
12 | * - Revision M, March 13, 2007; ADSP-BF534 Blackfin Processor Anomaly List | ||
13 | */ | 11 | */ |
14 | 12 | ||
15 | #ifndef _MACH_ANOMALY_H_ | 13 | #ifndef _MACH_ANOMALY_H_ |
@@ -17,7 +15,7 @@ | |||
17 | 15 | ||
18 | /* We do not support 0.1 silicon - sorry */ | 16 | /* We do not support 0.1 silicon - sorry */ |
19 | #if __SILICON_REVISION__ < 2 | 17 | #if __SILICON_REVISION__ < 2 |
20 | # error Kernel will not work on BF537 silicon version 0.0 or 0.1 | 18 | # error will not work on BF537 silicon version 0.0 or 0.1 |
21 | #endif | 19 | #endif |
22 | 20 | ||
23 | #if defined(__ADSPBF534__) | 21 | #if defined(__ADSPBF534__) |
@@ -44,6 +42,8 @@ | |||
44 | #define ANOMALY_05000122 (1) | 42 | #define ANOMALY_05000122 (1) |
45 | /* Killed 32-bit MMR write leads to next system MMR access thinking it should be 32-bit */ | 43 | /* Killed 32-bit MMR write leads to next system MMR access thinking it should be 32-bit */ |
46 | #define ANOMALY_05000157 (__SILICON_REVISION__ < 2) | 44 | #define ANOMALY_05000157 (__SILICON_REVISION__ < 2) |
45 | /* Turning SPORTs on while External Frame Sync Is Active May Corrupt Data */ | ||
46 | #define ANOMALY_05000167 (1) | ||
47 | /* PPI_DELAY not functional in PPI modes with 0 frame syncs */ | 47 | /* PPI_DELAY not functional in PPI modes with 0 frame syncs */ |
48 | #define ANOMALY_05000180 (1) | 48 | #define ANOMALY_05000180 (1) |
49 | /* Instruction Cache Is Not Functional */ | 49 | /* Instruction Cache Is Not Functional */ |
@@ -130,6 +130,12 @@ | |||
130 | #define ANOMALY_05000321 (__SILICON_REVISION__ < 3) | 130 | #define ANOMALY_05000321 (__SILICON_REVISION__ < 3) |
131 | /* EMAC RMII mode at 10-Base-T speed: RX frames not received properly */ | 131 | /* EMAC RMII mode at 10-Base-T speed: RX frames not received properly */ |
132 | #define ANOMALY_05000322 (1) | 132 | #define ANOMALY_05000322 (1) |
133 | /* Ethernet MAC MDIO Reads Do Not Meet IEEE Specification */ | ||
134 | #define ANOMALY_05000341 (__SILICON_REVISION__ >= 3) | ||
135 | /* Serial Port (SPORT) Multichannel Transmit Failure when Channel 0 Is Disabled */ | ||
136 | #define ANOMALY_05000357 (1) | ||
137 | /* DMAs that Go Urgent during Tight Core Writes to External Memory Are Blocked */ | ||
138 | #define ANOMALY_05000359 (1) | ||
133 | 139 | ||
134 | /* Anomalies that don't exist on this proc */ | 140 | /* Anomalies that don't exist on this proc */ |
135 | #define ANOMALY_05000125 (0) | 141 | #define ANOMALY_05000125 (0) |
diff --git a/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h index 6fb328f5186a..86e45c379838 100644 --- a/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h | |||
@@ -146,7 +146,7 @@ static void bfin_serial_hw_init(struct bfin_serial_port *uart) | |||
146 | 146 | ||
147 | if (uart->rts_pin >= 0) { | 147 | if (uart->rts_pin >= 0) { |
148 | gpio_request(uart->rts_pin, DRIVER_NAME); | 148 | gpio_request(uart->rts_pin, DRIVER_NAME); |
149 | gpio_direction_output(uart->rts_pin); | 149 | gpio_direction_output(uart->rts_pin, 0); |
150 | } | 150 | } |
151 | #endif | 151 | #endif |
152 | } | 152 | } |
diff --git a/include/asm-blackfin/mach-bf537/portmux.h b/include/asm-blackfin/mach-bf537/portmux.h index 5a3f7d3bf73d..78fee6e0f237 100644 --- a/include/asm-blackfin/mach-bf537/portmux.h +++ b/include/asm-blackfin/mach-bf537/portmux.h | |||
@@ -1,6 +1,8 @@ | |||
1 | #ifndef _MACH_PORTMUX_H_ | 1 | #ifndef _MACH_PORTMUX_H_ |
2 | #define _MACH_PORTMUX_H_ | 2 | #define _MACH_PORTMUX_H_ |
3 | 3 | ||
4 | #define MAX_RESOURCES (MAX_BLACKFIN_GPIOS + GPIO_BANKSIZE) /* We additionally handle PORTJ */ | ||
5 | |||
4 | #define P_UART0_TX (P_DEFINED | P_IDENT(GPIO_PF0) | P_FUNCT(0)) | 6 | #define P_UART0_TX (P_DEFINED | P_IDENT(GPIO_PF0) | P_FUNCT(0)) |
5 | #define P_UART0_RX (P_DEFINED | P_IDENT(GPIO_PF1) | P_FUNCT(0)) | 7 | #define P_UART0_RX (P_DEFINED | P_IDENT(GPIO_PF1) | P_FUNCT(0)) |
6 | #define P_UART1_TX (P_DEFINED | P_IDENT(GPIO_PF2) | P_FUNCT(0)) | 8 | #define P_UART1_TX (P_DEFINED | P_IDENT(GPIO_PF2) | P_FUNCT(0)) |
diff --git a/include/asm-blackfin/mach-bf548/anomaly.h b/include/asm-blackfin/mach-bf548/anomaly.h index c5b63759cdee..850dc12eb7f2 100644 --- a/include/asm-blackfin/mach-bf548/anomaly.h +++ b/include/asm-blackfin/mach-bf548/anomaly.h | |||
@@ -7,7 +7,7 @@ | |||
7 | */ | 7 | */ |
8 | 8 | ||
9 | /* This file shoule be up to date with: | 9 | /* This file shoule be up to date with: |
10 | * - Revision C, July 16, 2007; ADSP-BF549 Silicon Anomaly List | 10 | * - Revision E, 11/28/2007; ADSP-BF542/BF544/BF547/BF548/BF549 Blackfin Processor Anomaly List |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #ifndef _MACH_ANOMALY_H_ | 13 | #ifndef _MACH_ANOMALY_H_ |
@@ -26,47 +26,59 @@ | |||
26 | /* Certain Data Cache Writethrough Modes Fail for Vddint <= 0.9V */ | 26 | /* Certain Data Cache Writethrough Modes Fail for Vddint <= 0.9V */ |
27 | #define ANOMALY_05000272 (1) | 27 | #define ANOMALY_05000272 (1) |
28 | /* False Hardware Error Exception when ISR context is not restored */ | 28 | /* False Hardware Error Exception when ISR context is not restored */ |
29 | #define ANOMALY_05000281 (1) | 29 | #define ANOMALY_05000281 (__SILICON_REVISION__ < 1) |
30 | /* SSYNCs After Writes To CAN/DMA MMR Registers Are Not Always Handled Correctly */ | 30 | /* SSYNCs After Writes To CAN/DMA MMR Registers Are Not Always Handled Correctly */ |
31 | #define ANOMALY_05000304 (1) | 31 | #define ANOMALY_05000304 (__SILICON_REVISION__ < 1) |
32 | /* False Hardware Errors Caused by Fetches at the Boundary of Reserved Memory */ | 32 | /* False Hardware Errors Caused by Fetches at the Boundary of Reserved Memory */ |
33 | #define ANOMALY_05000310 (1) | 33 | #define ANOMALY_05000310 (1) |
34 | /* Errors When SSYNC, CSYNC, or Loads to LT, LB and LC Registers Are Interrupted */ | 34 | /* Errors When SSYNC, CSYNC, or Loads to LT, LB and LC Registers Are Interrupted */ |
35 | #define ANOMALY_05000312 (1) | 35 | #define ANOMALY_05000312 (__SILICON_REVISION__ < 1) |
36 | /* TWI Slave Boot Mode Is Not Functional */ | 36 | /* TWI Slave Boot Mode Is Not Functional */ |
37 | #define ANOMALY_05000324 (1) | 37 | #define ANOMALY_05000324 (__SILICON_REVISION__ < 1) |
38 | /* External FIFO Boot Mode Is Not Functional */ | 38 | /* External FIFO Boot Mode Is Not Functional */ |
39 | #define ANOMALY_05000325 (1) | 39 | #define ANOMALY_05000325 (__SILICON_REVISION__ < 1) |
40 | /* Data Lost When Core and DMA Accesses Are Made to the USB FIFO Simultaneously */ | 40 | /* Data Lost When Core and DMA Accesses Are Made to the USB FIFO Simultaneously */ |
41 | #define ANOMALY_05000327 (1) | 41 | #define ANOMALY_05000327 (__SILICON_REVISION__ < 1) |
42 | /* Incorrect Access of OTP_STATUS During otp_write() Function */ | 42 | /* Incorrect Access of OTP_STATUS During otp_write() Function */ |
43 | #define ANOMALY_05000328 (1) | 43 | #define ANOMALY_05000328 (__SILICON_REVISION__ < 1) |
44 | /* Synchronous Burst Flash Boot Mode Is Not Functional */ | 44 | /* Synchronous Burst Flash Boot Mode Is Not Functional */ |
45 | #define ANOMALY_05000329 (1) | 45 | #define ANOMALY_05000329 (__SILICON_REVISION__ < 1) |
46 | /* Host DMA Boot Mode Is Not Functional */ | 46 | /* Host DMA Boot Mode Is Not Functional */ |
47 | #define ANOMALY_05000330 (1) | 47 | #define ANOMALY_05000330 (__SILICON_REVISION__ < 1) |
48 | /* Inadequate Timing Margins on DDR DQS to DQ and DQM Skew */ | 48 | /* Inadequate Timing Margins on DDR DQS to DQ and DQM Skew */ |
49 | #define ANOMALY_05000334 (1) | 49 | #define ANOMALY_05000334 (__SILICON_REVISION__ < 1) |
50 | /* Inadequate Rotary Debounce Logic Duration */ | 50 | /* Inadequate Rotary Debounce Logic Duration */ |
51 | #define ANOMALY_05000335 (1) | 51 | #define ANOMALY_05000335 (__SILICON_REVISION__ < 1) |
52 | /* Phantom Interrupt Occurs After First Configuration of Host DMA Port */ | 52 | /* Phantom Interrupt Occurs After First Configuration of Host DMA Port */ |
53 | #define ANOMALY_05000336 (1) | 53 | #define ANOMALY_05000336 (__SILICON_REVISION__ < 1) |
54 | /* Disallowed Configuration Prevents Subsequent Allowed Configuration on Host DMA Port */ | 54 | /* Disallowed Configuration Prevents Subsequent Allowed Configuration on Host DMA Port */ |
55 | #define ANOMALY_05000337 (1) | 55 | #define ANOMALY_05000337 (__SILICON_REVISION__ < 1) |
56 | /* Slave-Mode SPI0 MISO Failure With CPHA = 0 */ | 56 | /* Slave-Mode SPI0 MISO Failure With CPHA = 0 */ |
57 | #define ANOMALY_05000338 (1) | 57 | #define ANOMALY_05000338 (__SILICON_REVISION__ < 1) |
58 | /* If Memory Reads Are Enabled on SDH or HOSTDP, Other DMAC1 Peripherals Cannot Read */ | 58 | /* If Memory Reads Are Enabled on SDH or HOSTDP, Other DMAC1 Peripherals Cannot Read */ |
59 | #define ANOMALY_05000340 (1) | 59 | #define ANOMALY_05000340 (__SILICON_REVISION__ < 1) |
60 | /* Boot Host Wait (HWAIT) and Boot Host Wait Alternate (HWAITA) Signals Are Swapped */ | 60 | /* Boot Host Wait (HWAIT) and Boot Host Wait Alternate (HWAITA) Signals Are Swapped */ |
61 | #define ANOMALY_05000344 (1) | 61 | #define ANOMALY_05000344 (__SILICON_REVISION__ < 1) |
62 | /* USB Calibration Value Is Not Intialized */ | 62 | /* USB Calibration Value Is Not Intialized */ |
63 | #define ANOMALY_05000346 (1) | 63 | #define ANOMALY_05000346 (__SILICON_REVISION__ < 1) |
64 | /* Boot ROM Kernel Incorrectly Alters Reset Value of USB Register */ | 64 | /* Boot ROM Kernel Incorrectly Alters Reset Value of USB Register */ |
65 | #define ANOMALY_05000347 (1) | 65 | #define ANOMALY_05000347 (__SILICON_REVISION__ < 1) |
66 | /* Data Lost when Core Reads SDH Data FIFO */ | 66 | /* Data Lost when Core Reads SDH Data FIFO */ |
67 | #define ANOMALY_05000349 (1) | 67 | #define ANOMALY_05000349 (__SILICON_REVISION__ < 1) |
68 | /* PLL Status Register Is Inaccurate */ | 68 | /* PLL Status Register Is Inaccurate */ |
69 | #define ANOMALY_05000351 (1) | 69 | #define ANOMALY_05000351 (__SILICON_REVISION__ < 1) |
70 | /* Serial Port (SPORT) Multichannel Transmit Failure when Channel 0 Is Disabled */ | ||
71 | #define ANOMALY_05000357 (1) | ||
72 | /* External Memory Read Access Hangs Core With PLL Bypass */ | ||
73 | #define ANOMALY_05000360 (1) | ||
74 | /* DMAs that Go Urgent during Tight Core Writes to External Memory Are Blocked */ | ||
75 | #define ANOMALY_05000365 (1) | ||
76 | /* Addressing Conflict between Boot ROM and Asynchronous Memory */ | ||
77 | #define ANOMALY_05000369 (1) | ||
78 | /* Mobile DDR Operation Not Functional */ | ||
79 | #define ANOMALY_05000377 (1) | ||
80 | /* Security/Authentication Speedpath Causes Authentication To Fail To Initiate */ | ||
81 | #define ANOMALY_05000378 (1) | ||
70 | 82 | ||
71 | /* Anomalies that don't exist on this proc */ | 83 | /* Anomalies that don't exist on this proc */ |
72 | #define ANOMALY_05000125 (0) | 84 | #define ANOMALY_05000125 (0) |
diff --git a/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h index f21a1620e6bd..3770aa38ee9f 100644 --- a/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h | |||
@@ -186,7 +186,7 @@ static void bfin_serial_hw_init(struct bfin_serial_port *uart) | |||
186 | 186 | ||
187 | if (uart->rts_pin >= 0) { | 187 | if (uart->rts_pin >= 0) { |
188 | gpio_request(uart->rts_pin, DRIVER_NAME); | 188 | gpio_request(uart->rts_pin, DRIVER_NAME); |
189 | gpio_direction_output(uart->rts_pin); | 189 | gpio_direction_output(uart->rts_pin, 0); |
190 | } | 190 | } |
191 | #endif | 191 | #endif |
192 | } | 192 | } |
diff --git a/include/asm-blackfin/mach-bf548/cdefBF54x_base.h b/include/asm-blackfin/mach-bf548/cdefBF54x_base.h index aefab3f618c1..19ddcd83c71f 100644 --- a/include/asm-blackfin/mach-bf548/cdefBF54x_base.h +++ b/include/asm-blackfin/mach-bf548/cdefBF54x_base.h | |||
@@ -244,39 +244,6 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val) | |||
244 | #define bfin_read_TWI0_RCV_DATA16() bfin_read16(TWI0_RCV_DATA16) | 244 | #define bfin_read_TWI0_RCV_DATA16() bfin_read16(TWI0_RCV_DATA16) |
245 | #define bfin_write_TWI0_RCV_DATA16(val) bfin_write16(TWI0_RCV_DATA16, val) | 245 | #define bfin_write_TWI0_RCV_DATA16(val) bfin_write16(TWI0_RCV_DATA16, val) |
246 | 246 | ||
247 | #define bfin_read_TWI_CLKDIV() bfin_read16(TWI0_CLKDIV) | ||
248 | #define bfin_write_TWI_CLKDIV(val) bfin_write16(TWI0_CLKDIV, val) | ||
249 | #define bfin_read_TWI_CONTROL() bfin_read16(TWI0_CONTROL) | ||
250 | #define bfin_write_TWI_CONTROL(val) bfin_write16(TWI0_CONTROL, val) | ||
251 | #define bfin_read_TWI_SLAVE_CTRL() bfin_read16(TWI0_SLAVE_CTRL) | ||
252 | #define bfin_write_TWI_SLAVE_CTRL(val) bfin_write16(TWI0_SLAVE_CTRL, val) | ||
253 | #define bfin_read_TWI_SLAVE_STAT() bfin_read16(TWI0_SLAVE_STAT) | ||
254 | #define bfin_write_TWI_SLAVE_STAT(val) bfin_write16(TWI0_SLAVE_STAT, val) | ||
255 | #define bfin_read_TWI_SLAVE_ADDR() bfin_read16(TWI0_SLAVE_ADDR) | ||
256 | #define bfin_write_TWI_SLAVE_ADDR(val) bfin_write16(TWI0_SLAVE_ADDR, val) | ||
257 | #define bfin_read_TWI_MASTER_CTL() bfin_read16(TWI0_MASTER_CTRL) | ||
258 | #define bfin_write_TWI_MASTER_CTL(val) bfin_write16(TWI0_MASTER_CTRL, val) | ||
259 | #define bfin_read_TWI_MASTER_STAT() bfin_read16(TWI0_MASTER_STAT) | ||
260 | #define bfin_write_TWI_MASTER_STAT(val) bfin_write16(TWI0_MASTER_STAT, val) | ||
261 | #define bfin_read_TWI_MASTER_ADDR() bfin_read16(TWI0_MASTER_ADDR) | ||
262 | #define bfin_write_TWI_MASTER_ADDR(val) bfin_write16(TWI0_MASTER_ADDR, val) | ||
263 | #define bfin_read_TWI_INT_STAT() bfin_read16(TWI0_INT_STAT) | ||
264 | #define bfin_write_TWI_INT_STAT(val) bfin_write16(TWI0_INT_STAT, val) | ||
265 | #define bfin_read_TWI_INT_MASK() bfin_read16(TWI0_INT_MASK) | ||
266 | #define bfin_write_TWI_INT_MASK(val) bfin_write16(TWI0_INT_MASK, val) | ||
267 | #define bfin_read_TWI_FIFO_CTL() bfin_read16(TWI0_FIFO_CTRL) | ||
268 | #define bfin_write_TWI_FIFO_CTL(val) bfin_write16(TWI0_FIFO_CTRL, val) | ||
269 | #define bfin_read_TWI_FIFO_STAT() bfin_read16(TWI0_FIFO_STAT) | ||
270 | #define bfin_write_TWI_FIFO_STAT(val) bfin_write16(TWI0_FIFO_STAT, val) | ||
271 | #define bfin_read_TWI_XMT_DATA8() bfin_read16(TWI0_XMT_DATA8) | ||
272 | #define bfin_write_TWI_XMT_DATA8(val) bfin_write16(TWI0_XMT_DATA8, val) | ||
273 | #define bfin_read_TWI_XMT_DATA16() bfin_read16(TWI0_XMT_DATA16) | ||
274 | #define bfin_write_TWI_XMT_DATA16(val) bfin_write16(TWI0_XMT_DATA16, val) | ||
275 | #define bfin_read_TWI_RCV_DATA8() bfin_read16(TWI0_RCV_DATA8) | ||
276 | #define bfin_write_TWI_RCV_DATA8(val) bfin_write16(TWI0_RCV_DATA8, val) | ||
277 | #define bfin_read_TWI_RCV_DATA16() bfin_read16(TWI0_RCV_DATA16) | ||
278 | #define bfin_write_TWI_RCV_DATA16(val) bfin_write16(TWI0_RCV_DATA16, val) | ||
279 | |||
280 | /* SPORT0 is not defined in the shared file because it is not available on the ADSP-BF542 and ADSP-BF544 bfin_read_()rocessors */ | 247 | /* SPORT0 is not defined in the shared file because it is not available on the ADSP-BF542 and ADSP-BF544 bfin_read_()rocessors */ |
281 | 248 | ||
282 | /* SPORT1 Registers */ | 249 | /* SPORT1 Registers */ |
diff --git a/include/asm-blackfin/mach-bf548/defBF542.h b/include/asm-blackfin/mach-bf548/defBF542.h index 32d07130200c..a7c809f29ede 100644 --- a/include/asm-blackfin/mach-bf548/defBF542.h +++ b/include/asm-blackfin/mach-bf548/defBF542.h | |||
@@ -432,8 +432,8 @@ | |||
432 | 432 | ||
433 | #define CMD_CRC_FAIL 0x1 /* CMD CRC Fail */ | 433 | #define CMD_CRC_FAIL 0x1 /* CMD CRC Fail */ |
434 | #define DAT_CRC_FAIL 0x2 /* Data CRC Fail */ | 434 | #define DAT_CRC_FAIL 0x2 /* Data CRC Fail */ |
435 | #define CMD_TIMEOUT 0x4 /* CMD Time Out */ | 435 | #define CMD_TIME_OUT 0x4 /* CMD Time Out */ |
436 | #define DAT_TIMEOUT 0x8 /* Data Time Out */ | 436 | #define DAT_TIME_OUT 0x8 /* Data Time Out */ |
437 | #define TX_UNDERRUN 0x10 /* Transmit Underrun */ | 437 | #define TX_UNDERRUN 0x10 /* Transmit Underrun */ |
438 | #define RX_OVERRUN 0x20 /* Receive Overrun */ | 438 | #define RX_OVERRUN 0x20 /* Receive Overrun */ |
439 | #define CMD_RESP_END 0x40 /* CMD Response End */ | 439 | #define CMD_RESP_END 0x40 /* CMD Response End */ |
diff --git a/include/asm-blackfin/mach-bf548/defBF548.h b/include/asm-blackfin/mach-bf548/defBF548.h index ecbca952985c..e46f56891e6a 100644 --- a/include/asm-blackfin/mach-bf548/defBF548.h +++ b/include/asm-blackfin/mach-bf548/defBF548.h | |||
@@ -1095,8 +1095,8 @@ | |||
1095 | 1095 | ||
1096 | #define CMD_CRC_FAIL 0x1 /* CMD CRC Fail */ | 1096 | #define CMD_CRC_FAIL 0x1 /* CMD CRC Fail */ |
1097 | #define DAT_CRC_FAIL 0x2 /* Data CRC Fail */ | 1097 | #define DAT_CRC_FAIL 0x2 /* Data CRC Fail */ |
1098 | #define CMD_TIMEOUT 0x4 /* CMD Time Out */ | 1098 | #define CMD_TIME_OUT 0x4 /* CMD Time Out */ |
1099 | #define DAT_TIMEOUT 0x8 /* Data Time Out */ | 1099 | #define DAT_TIME_OUT 0x8 /* Data Time Out */ |
1100 | #define TX_UNDERRUN 0x10 /* Transmit Underrun */ | 1100 | #define TX_UNDERRUN 0x10 /* Transmit Underrun */ |
1101 | #define RX_OVERRUN 0x20 /* Receive Overrun */ | 1101 | #define RX_OVERRUN 0x20 /* Receive Overrun */ |
1102 | #define CMD_RESP_END 0x40 /* CMD Response End */ | 1102 | #define CMD_RESP_END 0x40 /* CMD Response End */ |
diff --git a/include/asm-blackfin/mach-bf548/defBF54x_base.h b/include/asm-blackfin/mach-bf548/defBF54x_base.h index 319a48590c9c..08f90c21fe8a 100644 --- a/include/asm-blackfin/mach-bf548/defBF54x_base.h +++ b/include/asm-blackfin/mach-bf548/defBF54x_base.h | |||
@@ -1772,17 +1772,36 @@ | |||
1772 | #define TRP 0x3c0000 /* Pre charge-to-active command period */ | 1772 | #define TRP 0x3c0000 /* Pre charge-to-active command period */ |
1773 | #define TRAS 0x3c00000 /* Min Active-to-pre charge time */ | 1773 | #define TRAS 0x3c00000 /* Min Active-to-pre charge time */ |
1774 | #define TRC 0x3c000000 /* Active-to-active time */ | 1774 | #define TRC 0x3c000000 /* Active-to-active time */ |
1775 | #define DDR_TRAS(x) ((x<<22)&TRAS) /* DDR tRAS = (1~15) cycles */ | ||
1776 | #define DDR_TRP(x) ((x<<18)&TRP) /* DDR tRP = (1~15) cycles */ | ||
1777 | #define DDR_TRC(x) ((x<<26)&TRC) /* DDR tRC = (1~15) cycles */ | ||
1778 | #define DDR_TRFC(x) ((x<<14)&TRFC) /* DDR tRFC = (1~15) cycles */ | ||
1779 | #define DDR_TREFI(x) (x&TREFI) /* DDR tRFC = (1~15) cycles */ | ||
1775 | 1780 | ||
1776 | /* Bit masks for EBIU_DDRCTL1 */ | 1781 | /* Bit masks for EBIU_DDRCTL1 */ |
1777 | 1782 | ||
1778 | #define TRCD 0xf /* Active-to-Read/write delay */ | 1783 | #define TRCD 0xf /* Active-to-Read/write delay */ |
1779 | #define MRD 0xf0 /* Mode register set to active */ | 1784 | #define TMRD 0xf0 /* Mode register set to active */ |
1780 | #define TWR 0x300 /* Write Recovery time */ | 1785 | #define TWR 0x300 /* Write Recovery time */ |
1781 | #define DDRDATWIDTH 0x3000 /* DDR data width */ | 1786 | #define DDRDATWIDTH 0x3000 /* DDR data width */ |
1782 | #define EXTBANKS 0xc000 /* External banks */ | 1787 | #define EXTBANKS 0xc000 /* External banks */ |
1783 | #define DDRDEVWIDTH 0x30000 /* DDR device width */ | 1788 | #define DDRDEVWIDTH 0x30000 /* DDR device width */ |
1784 | #define DDRDEVSIZE 0xc0000 /* DDR device size */ | 1789 | #define DDRDEVSIZE 0xc0000 /* DDR device size */ |
1785 | #define TWWTR 0xf0000000 /* Write-to-read delay */ | 1790 | #define TWTR 0xf0000000 /* Write-to-read delay */ |
1791 | #define DDR_TWTR(x) ((x<<28)&TWTR) /* DDR tWTR = (1~15) cycles */ | ||
1792 | #define DDR_TMRD(x) ((x<<4)&TMRD) /* DDR tMRD = (1~15) cycles */ | ||
1793 | #define DDR_TWR(x) ((x<<8)&TWR) /* DDR tWR = (1~15) cycles */ | ||
1794 | #define DDR_TRCD(x) (x&TRCD) /* DDR tRCD = (1~15) cycles */ | ||
1795 | #define DDR_DATWIDTH 0x2000 /* DDR data width */ | ||
1796 | #define EXTBANK_1 0 /* 1 external bank */ | ||
1797 | #define EXTBANK_2 0x4000 /* 2 external banks */ | ||
1798 | #define DEVSZ_64 0x40000 /* DDR External Bank Size = 64MB */ | ||
1799 | #define DEVSZ_128 0x80000 /* DDR External Bank Size = 128MB */ | ||
1800 | #define DEVSZ_256 0xc0000 /* DDR External Bank Size = 256MB */ | ||
1801 | #define DEVSZ_512 0 /* DDR External Bank Size = 512MB */ | ||
1802 | #define DEVWD_4 0 /* DDR Device Width = 4 Bits */ | ||
1803 | #define DEVWD_8 0x10000 /* DDR Device Width = 8 Bits */ | ||
1804 | #define DEVWD_16 0x20000 /* DDR Device Width = 16 Bits */ | ||
1786 | 1805 | ||
1787 | /* Bit masks for EBIU_DDRCTL2 */ | 1806 | /* Bit masks for EBIU_DDRCTL2 */ |
1788 | 1807 | ||
@@ -1790,6 +1809,10 @@ | |||
1790 | #define CASLATENCY 0x70 /* CAS latency */ | 1809 | #define CASLATENCY 0x70 /* CAS latency */ |
1791 | #define DLLRESET 0x100 /* DLL Reset */ | 1810 | #define DLLRESET 0x100 /* DLL Reset */ |
1792 | #define REGE 0x1000 /* Register mode enable */ | 1811 | #define REGE 0x1000 /* Register mode enable */ |
1812 | #define CL_1_5 0x50 /* DDR CAS Latency = 1.5 cycles */ | ||
1813 | #define CL_2 0x20 /* DDR CAS Latency = 2 cycles */ | ||
1814 | #define CL_2_5 0x60 /* DDR CAS Latency = 2.5 cycles */ | ||
1815 | #define CL_3 0x30 /* DDR CAS Latency = 3 cycles */ | ||
1793 | 1816 | ||
1794 | /* Bit masks for EBIU_DDRCTL3 */ | 1817 | /* Bit masks for EBIU_DDRCTL3 */ |
1795 | 1818 | ||
@@ -2257,6 +2280,10 @@ | |||
2257 | 2280 | ||
2258 | #define CSEL 0x30 /* Core Select */ | 2281 | #define CSEL 0x30 /* Core Select */ |
2259 | #define SSEL 0xf /* System Select */ | 2282 | #define SSEL 0xf /* System Select */ |
2283 | #define CSEL_DIV1 0x0000 /* CCLK = VCO / 1 */ | ||
2284 | #define CSEL_DIV2 0x0010 /* CCLK = VCO / 2 */ | ||
2285 | #define CSEL_DIV4 0x0020 /* CCLK = VCO / 4 */ | ||
2286 | #define CSEL_DIV8 0x0030 /* CCLK = VCO / 8 */ | ||
2260 | 2287 | ||
2261 | /* Bit masks for PLL_CTL */ | 2288 | /* Bit masks for PLL_CTL */ |
2262 | 2289 | ||
diff --git a/include/asm-blackfin/mach-bf548/irq.h b/include/asm-blackfin/mach-bf548/irq.h index 9fb7bc5399a8..c34507a3f1df 100644 --- a/include/asm-blackfin/mach-bf548/irq.h +++ b/include/asm-blackfin/mach-bf548/irq.h | |||
@@ -88,7 +88,7 @@ Events (highest priority) EMU 0 | |||
88 | #define IRQ_PINT1 BFIN_IRQ(20) /* PINT1 Interrupt */ | 88 | #define IRQ_PINT1 BFIN_IRQ(20) /* PINT1 Interrupt */ |
89 | #define IRQ_MDMAS0 BFIN_IRQ(21) /* MDMA Stream 0 Interrupt */ | 89 | #define IRQ_MDMAS0 BFIN_IRQ(21) /* MDMA Stream 0 Interrupt */ |
90 | #define IRQ_MDMAS1 BFIN_IRQ(22) /* MDMA Stream 1 Interrupt */ | 90 | #define IRQ_MDMAS1 BFIN_IRQ(22) /* MDMA Stream 1 Interrupt */ |
91 | #define IRQ_WATCHDOG BFIN_IRQ(23) /* Watchdog Interrupt */ | 91 | #define IRQ_WATCH BFIN_IRQ(23) /* Watchdog Interrupt */ |
92 | #define IRQ_DMAC1_ERROR BFIN_IRQ(24) /* DMAC1 Status (Error) Interrupt */ | 92 | #define IRQ_DMAC1_ERROR BFIN_IRQ(24) /* DMAC1 Status (Error) Interrupt */ |
93 | #define IRQ_SPORT2_ERROR BFIN_IRQ(25) /* SPORT2 Error Interrupt */ | 93 | #define IRQ_SPORT2_ERROR BFIN_IRQ(25) /* SPORT2 Error Interrupt */ |
94 | #define IRQ_SPORT3_ERROR BFIN_IRQ(26) /* SPORT3 Error Interrupt */ | 94 | #define IRQ_SPORT3_ERROR BFIN_IRQ(26) /* SPORT3 Error Interrupt */ |
@@ -406,7 +406,7 @@ Events (highest priority) EMU 0 | |||
406 | #define IRQ_PINT1_POS 16 | 406 | #define IRQ_PINT1_POS 16 |
407 | #define IRQ_MDMAS0_POS 20 | 407 | #define IRQ_MDMAS0_POS 20 |
408 | #define IRQ_MDMAS1_POS 24 | 408 | #define IRQ_MDMAS1_POS 24 |
409 | #define IRQ_WATCHDOG_POS 28 | 409 | #define IRQ_WATCH_POS 28 |
410 | 410 | ||
411 | /* IAR3 BIT FIELDS */ | 411 | /* IAR3 BIT FIELDS */ |
412 | #define IRQ_DMAC1_ERR_POS 0 | 412 | #define IRQ_DMAC1_ERR_POS 0 |
diff --git a/include/asm-blackfin/mach-bf548/mem_init.h b/include/asm-blackfin/mach-bf548/mem_init.h index 0cb279e973d7..befc2903d5a5 100644 --- a/include/asm-blackfin/mach-bf548/mem_init.h +++ b/include/asm-blackfin/mach-bf548/mem_init.h | |||
@@ -28,8 +28,68 @@ | |||
28 | * If not, write to the Free Software Foundation, | 28 | * If not, write to the Free Software Foundation, |
29 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 29 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
30 | */ | 30 | */ |
31 | #define MIN_DDR_SCLK(x) (x*(CONFIG_SCLK_HZ/1000/1000)/1000 + 1) | ||
32 | |||
33 | #if (CONFIG_MEM_MT46V32M16_6T) | ||
34 | #define DDR_SIZE DEVSZ_512 | ||
35 | #define DDR_WIDTH DEVWD_16 | ||
36 | |||
37 | #define DDR_tRC DDR_TRC(MIN_DDR_SCLK(60)) | ||
38 | #define DDR_tRAS DDR_TRAS(MIN_DDR_SCLK(42)) | ||
39 | #define DDR_tRP DDR_TRP(MIN_DDR_SCLK(15)) | ||
40 | #define DDR_tRFC DDR_TRFC(MIN_DDR_SCLK(72)) | ||
41 | #define DDR_tREFI DDR_TREFI(MIN_DDR_SCLK(7800)) | ||
42 | |||
43 | #define DDR_tRCD DDR_TRCD(MIN_DDR_SCLK(15)) | ||
44 | #define DDR_tWTR DDR_TWTR(1) | ||
45 | #define DDR_tMRD DDR_TMRD(MIN_DDR_SCLK(12)) | ||
46 | #define DDR_tWR DDR_TWR(MIN_DDR_SCLK(15)) | ||
47 | #endif | ||
48 | |||
49 | #if (CONFIG_MEM_MT46V32M16_5B) | ||
50 | #define DDR_SIZE DEVSZ_512 | ||
51 | #define DDR_WIDTH DEVWD_16 | ||
52 | |||
53 | #define DDR_tRC DDR_TRC(MIN_DDR_SCLK(55)) | ||
54 | #define DDR_tRAS DDR_TRAS(MIN_DDR_SCLK(40)) | ||
55 | #define DDR_tRP DDR_TRP(MIN_DDR_SCLK(15)) | ||
56 | #define DDR_tRFC DDR_TRFC(MIN_DDR_SCLK(70)) | ||
57 | #define DDR_tREFI DDR_TREFI(MIN_DDR_SCLK(7800)) | ||
58 | |||
59 | #define DDR_tRCD DDR_TRCD(MIN_DDR_SCLK(15)) | ||
60 | #define DDR_tWTR DDR_TWTR(2) | ||
61 | #define DDR_tMRD DDR_TMRD(MIN_DDR_SCLK(10)) | ||
62 | #define DDR_tWR DDR_TWR(MIN_DDR_SCLK(15)) | ||
63 | #endif | ||
64 | |||
65 | #if (CONFIG_MEM_GENERIC_BOARD) | ||
66 | #define DDR_SIZE DEVSZ_512 | ||
67 | #define DDR_WIDTH DEVWD_16 | ||
68 | |||
69 | #define DDR_tRCD DDR_TRCD(3) | ||
70 | #define DDR_tWTR DDR_TWTR(2) | ||
71 | #define DDR_tWR DDR_TWR(2) | ||
72 | #define DDR_tMRD DDR_TMRD(2) | ||
73 | #define DDR_tRP DDR_TRP(3) | ||
74 | #define DDR_tRAS DDR_TRAS(7) | ||
75 | #define DDR_tRC DDR_TRC(10) | ||
76 | #define DDR_tRFC DDR_TRFC(12) | ||
77 | #define DDR_tREFI DDR_TREFI(1288) | ||
78 | #endif | ||
79 | |||
80 | #if (CONFIG_SCLK_HZ <= 133333333) | ||
81 | #define DDR_CL CL_2 | ||
82 | #elif (CONFIG_SCLK_HZ <= 166666666) | ||
83 | #define DDR_CL CL_2_5 | ||
84 | #else | ||
85 | #define DDR_CL CL_3 | ||
86 | #endif | ||
87 | |||
88 | #define mem_DDRCTL0 (DDR_tRP | DDR_tRAS | DDR_tRC | DDR_tRFC | DDR_tREFI) | ||
89 | #define mem_DDRCTL1 (DDR_DATWIDTH | EXTBANK_1 | DDR_SIZE | DDR_WIDTH | DDR_tWTR \ | ||
90 | | DDR_tMRD | DDR_tWR | DDR_tRCD) | ||
91 | #define mem_DDRCTL2 DDR_CL | ||
31 | 92 | ||
32 | #if (CONFIG_MEM_MT46V32M16) | ||
33 | 93 | ||
34 | #if defined CONFIG_CLKIN_HALF | 94 | #if defined CONFIG_CLKIN_HALF |
35 | #define CLKIN_HALF 1 | 95 | #define CLKIN_HALF 1 |
diff --git a/include/asm-blackfin/mach-bf548/portmux.h b/include/asm-blackfin/mach-bf548/portmux.h index 6b485120015f..8177a567dcdb 100644 --- a/include/asm-blackfin/mach-bf548/portmux.h +++ b/include/asm-blackfin/mach-bf548/portmux.h | |||
@@ -1,6 +1,8 @@ | |||
1 | #ifndef _MACH_PORTMUX_H_ | 1 | #ifndef _MACH_PORTMUX_H_ |
2 | #define _MACH_PORTMUX_H_ | 2 | #define _MACH_PORTMUX_H_ |
3 | 3 | ||
4 | #define MAX_RESOURCES MAX_BLACKFIN_GPIOS | ||
5 | |||
4 | #define P_SPORT2_TFS (P_DEFINED | P_IDENT(GPIO_PA0) | P_FUNCT(0)) | 6 | #define P_SPORT2_TFS (P_DEFINED | P_IDENT(GPIO_PA0) | P_FUNCT(0)) |
5 | #define P_SPORT2_DTSEC (P_DEFINED | P_IDENT(GPIO_PA1) | P_FUNCT(0)) | 7 | #define P_SPORT2_DTSEC (P_DEFINED | P_IDENT(GPIO_PA1) | P_FUNCT(0)) |
6 | #define P_SPORT2_DTPRI (P_DEFINED | P_IDENT(GPIO_PA2) | P_FUNCT(0)) | 8 | #define P_SPORT2_DTPRI (P_DEFINED | P_IDENT(GPIO_PA2) | P_FUNCT(0)) |
diff --git a/include/asm-blackfin/mach-bf561/anomaly.h b/include/asm-blackfin/mach-bf561/anomaly.h index bed956456884..0c1d46193939 100644 --- a/include/asm-blackfin/mach-bf561/anomaly.h +++ b/include/asm-blackfin/mach-bf561/anomaly.h | |||
@@ -7,7 +7,7 @@ | |||
7 | */ | 7 | */ |
8 | 8 | ||
9 | /* This file shoule be up to date with: | 9 | /* This file shoule be up to date with: |
10 | * - Revision N, March 28, 2007; ADSP-BF561 Silicon Anomaly List | 10 | * - Revision O, 11/15/2007; ADSP-BF561 Blackfin Processor Anomaly List |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #ifndef _MACH_ANOMALY_H_ | 13 | #ifndef _MACH_ANOMALY_H_ |
@@ -15,7 +15,7 @@ | |||
15 | 15 | ||
16 | /* We do not support 0.1, 0.2, or 0.4 silicon - sorry */ | 16 | /* We do not support 0.1, 0.2, or 0.4 silicon - sorry */ |
17 | #if __SILICON_REVISION__ < 3 || __SILICON_REVISION__ == 4 | 17 | #if __SILICON_REVISION__ < 3 || __SILICON_REVISION__ == 4 |
18 | # error Kernel will not work on BF561 silicon version 0.0, 0.1, 0.2, or 0.4 | 18 | # error will not work on BF561 silicon version 0.0, 0.1, 0.2, or 0.4 |
19 | #endif | 19 | #endif |
20 | 20 | ||
21 | /* Multi-Issue Instruction with dsp32shiftimm in slot1 and P-reg Store in slot 2 Not Supported */ | 21 | /* Multi-Issue Instruction with dsp32shiftimm in slot1 and P-reg Store in slot 2 Not Supported */ |
@@ -208,6 +208,8 @@ | |||
208 | #define ANOMALY_05000275 (__SILICON_REVISION__ > 2) | 208 | #define ANOMALY_05000275 (__SILICON_REVISION__ > 2) |
209 | /* Timing Requirements Change for External Frame Sync PPI Modes with Non-Zero PPI_DELAY */ | 209 | /* Timing Requirements Change for External Frame Sync PPI Modes with Non-Zero PPI_DELAY */ |
210 | #define ANOMALY_05000276 (__SILICON_REVISION__ < 5) | 210 | #define ANOMALY_05000276 (__SILICON_REVISION__ < 5) |
211 | /* Writes to an I/O data register one SCLK cycle after an edge is detected may clear interrupt */ | ||
212 | #define ANOMALY_05000277 (__SILICON_REVISION__ < 3) | ||
211 | /* Disabling Peripherals with DMA Running May Cause DMA System Instability */ | 213 | /* Disabling Peripherals with DMA Running May Cause DMA System Instability */ |
212 | #define ANOMALY_05000278 (__SILICON_REVISION__ < 5) | 214 | #define ANOMALY_05000278 (__SILICON_REVISION__ < 5) |
213 | /* False Hardware Error Exception When ISR Context Is Not Restored */ | 215 | /* False Hardware Error Exception When ISR Context Is Not Restored */ |
@@ -246,6 +248,18 @@ | |||
246 | #define ANOMALY_05000332 (__SILICON_REVISION__ < 5) | 248 | #define ANOMALY_05000332 (__SILICON_REVISION__ < 5) |
247 | /* Flag Data Register Writes One SCLK Cycle After Edge Is Detected May Clear Interrupt Status */ | 249 | /* Flag Data Register Writes One SCLK Cycle After Edge Is Detected May Clear Interrupt Status */ |
248 | #define ANOMALY_05000333 (__SILICON_REVISION__ < 5) | 250 | #define ANOMALY_05000333 (__SILICON_REVISION__ < 5) |
251 | /* New Feature: Additional PPI Frame Sync Sampling Options (Not Available on Older Silicon) */ | ||
252 | #define ANOMALY_05000339 (__SILICON_REVISION__ < 5) | ||
253 | /* Memory DMA FIFO Causes Throughput Degradation on Writes to External Memory */ | ||
254 | #define ANOMALY_05000343 (__SILICON_REVISION__ < 5) | ||
255 | /* Serial Port (SPORT) Multichannel Transmit Failure when Channel 0 Is Disabled */ | ||
256 | #define ANOMALY_05000357 (1) | ||
257 | /* Conflicting Column Address Widths Causes SDRAM Errors */ | ||
258 | #define ANOMALY_05000362 (1) | ||
259 | /* PPI Underflow Error Goes Undetected in ITU-R 656 Mode */ | ||
260 | #define ANOMALY_05000366 (1) | ||
261 | /* Possible RETS Register Corruption when Subroutine Is under 5 Cycles in Duration */ | ||
262 | #define ANOMALY_05000371 (1) | ||
249 | 263 | ||
250 | /* Anomalies that don't exist on this proc */ | 264 | /* Anomalies that don't exist on this proc */ |
251 | #define ANOMALY_05000158 (0) | 265 | #define ANOMALY_05000158 (0) |
diff --git a/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h index 69b9f8e120e9..7871d4313f49 100644 --- a/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h | |||
@@ -111,7 +111,7 @@ static void bfin_serial_hw_init(struct bfin_serial_port *uart) | |||
111 | } | 111 | } |
112 | if (uart->rts_pin >= 0) { | 112 | if (uart->rts_pin >= 0) { |
113 | gpio_request(uart->rts_pin, DRIVER_NAME); | 113 | gpio_request(uart->rts_pin, DRIVER_NAME); |
114 | gpio_direction_input(uart->rts_pin); | 114 | gpio_direction_input(uart->rts_pin, 0); |
115 | } | 115 | } |
116 | #endif | 116 | #endif |
117 | } | 117 | } |
diff --git a/include/asm-blackfin/mach-bf561/portmux.h b/include/asm-blackfin/mach-bf561/portmux.h index 132ad31665e3..a6ee8206efb6 100644 --- a/include/asm-blackfin/mach-bf561/portmux.h +++ b/include/asm-blackfin/mach-bf561/portmux.h | |||
@@ -1,6 +1,8 @@ | |||
1 | #ifndef _MACH_PORTMUX_H_ | 1 | #ifndef _MACH_PORTMUX_H_ |
2 | #define _MACH_PORTMUX_H_ | 2 | #define _MACH_PORTMUX_H_ |
3 | 3 | ||
4 | #define MAX_RESOURCES MAX_BLACKFIN_GPIOS | ||
5 | |||
4 | #define P_PPI0_CLK (P_DONTCARE) | 6 | #define P_PPI0_CLK (P_DONTCARE) |
5 | #define P_PPI0_FS1 (P_DONTCARE) | 7 | #define P_PPI0_FS1 (P_DONTCARE) |
6 | #define P_PPI0_FS2 (P_DONTCARE) | 8 | #define P_PPI0_FS2 (P_DONTCARE) |
diff --git a/include/asm-blackfin/mmu.h b/include/asm-blackfin/mmu.h index 11d52f1167d0..757e43906ed4 100644 --- a/include/asm-blackfin/mmu.h +++ b/include/asm-blackfin/mmu.h | |||
@@ -24,7 +24,9 @@ typedef struct { | |||
24 | unsigned long exec_fdpic_loadmap; | 24 | unsigned long exec_fdpic_loadmap; |
25 | unsigned long interp_fdpic_loadmap; | 25 | unsigned long interp_fdpic_loadmap; |
26 | #endif | 26 | #endif |
27 | 27 | #ifdef CONFIG_MPU | |
28 | unsigned long *page_rwx_mask; | ||
29 | #endif | ||
28 | } mm_context_t; | 30 | } mm_context_t; |
29 | 31 | ||
30 | #endif | 32 | #endif |
diff --git a/include/asm-blackfin/mmu_context.h b/include/asm-blackfin/mmu_context.h index c5c71a6aaf19..b5eb67596ad5 100644 --- a/include/asm-blackfin/mmu_context.h +++ b/include/asm-blackfin/mmu_context.h | |||
@@ -30,9 +30,12 @@ | |||
30 | #ifndef __BLACKFIN_MMU_CONTEXT_H__ | 30 | #ifndef __BLACKFIN_MMU_CONTEXT_H__ |
31 | #define __BLACKFIN_MMU_CONTEXT_H__ | 31 | #define __BLACKFIN_MMU_CONTEXT_H__ |
32 | 32 | ||
33 | #include <linux/gfp.h> | ||
34 | #include <linux/sched.h> | ||
33 | #include <asm/setup.h> | 35 | #include <asm/setup.h> |
34 | #include <asm/page.h> | 36 | #include <asm/page.h> |
35 | #include <asm/pgalloc.h> | 37 | #include <asm/pgalloc.h> |
38 | #include <asm/cplbinit.h> | ||
36 | 39 | ||
37 | extern void *current_l1_stack_save; | 40 | extern void *current_l1_stack_save; |
38 | extern int nr_l1stack_tasks; | 41 | extern int nr_l1stack_tasks; |
@@ -50,6 +53,12 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) | |||
50 | static inline int | 53 | static inline int |
51 | init_new_context(struct task_struct *tsk, struct mm_struct *mm) | 54 | init_new_context(struct task_struct *tsk, struct mm_struct *mm) |
52 | { | 55 | { |
56 | #ifdef CONFIG_MPU | ||
57 | unsigned long p = __get_free_pages(GFP_KERNEL, page_mask_order); | ||
58 | mm->context.page_rwx_mask = (unsigned long *)p; | ||
59 | memset(mm->context.page_rwx_mask, 0, | ||
60 | page_mask_nelts * 3 * sizeof(long)); | ||
61 | #endif | ||
53 | return 0; | 62 | return 0; |
54 | } | 63 | } |
55 | 64 | ||
@@ -73,6 +82,11 @@ static inline void destroy_context(struct mm_struct *mm) | |||
73 | sram_free(tmp->addr); | 82 | sram_free(tmp->addr); |
74 | kfree(tmp); | 83 | kfree(tmp); |
75 | } | 84 | } |
85 | #ifdef CONFIG_MPU | ||
86 | if (current_rwx_mask == mm->context.page_rwx_mask) | ||
87 | current_rwx_mask = NULL; | ||
88 | free_pages((unsigned long)mm->context.page_rwx_mask, page_mask_order); | ||
89 | #endif | ||
76 | } | 90 | } |
77 | 91 | ||
78 | static inline unsigned long | 92 | static inline unsigned long |
@@ -106,9 +120,21 @@ activate_l1stack(struct mm_struct *mm, unsigned long sp_base) | |||
106 | 120 | ||
107 | #define deactivate_mm(tsk,mm) do { } while (0) | 121 | #define deactivate_mm(tsk,mm) do { } while (0) |
108 | 122 | ||
109 | static inline void activate_mm(struct mm_struct *prev_mm, | 123 | #define activate_mm(prev, next) switch_mm(prev, next, NULL) |
110 | struct mm_struct *next_mm) | 124 | |
125 | static inline void switch_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm, | ||
126 | struct task_struct *tsk) | ||
111 | { | 127 | { |
128 | if (prev_mm == next_mm) | ||
129 | return; | ||
130 | #ifdef CONFIG_MPU | ||
131 | if (prev_mm->context.page_rwx_mask == current_rwx_mask) { | ||
132 | flush_switched_cplbs(); | ||
133 | set_mask_dcplbs(next_mm->context.page_rwx_mask); | ||
134 | } | ||
135 | #endif | ||
136 | |||
137 | /* L1 stack switching. */ | ||
112 | if (!next_mm->context.l1_stack_save) | 138 | if (!next_mm->context.l1_stack_save) |
113 | return; | 139 | return; |
114 | if (next_mm->context.l1_stack_save == current_l1_stack_save) | 140 | if (next_mm->context.l1_stack_save == current_l1_stack_save) |
@@ -120,10 +146,36 @@ static inline void activate_mm(struct mm_struct *prev_mm, | |||
120 | memcpy(l1_stack_base, current_l1_stack_save, l1_stack_len); | 146 | memcpy(l1_stack_base, current_l1_stack_save, l1_stack_len); |
121 | } | 147 | } |
122 | 148 | ||
123 | static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, | 149 | #ifdef CONFIG_MPU |
124 | struct task_struct *tsk) | 150 | static inline void protect_page(struct mm_struct *mm, unsigned long addr, |
151 | unsigned long flags) | ||
152 | { | ||
153 | unsigned long *mask = mm->context.page_rwx_mask; | ||
154 | unsigned long page = addr >> 12; | ||
155 | unsigned long idx = page >> 5; | ||
156 | unsigned long bit = 1 << (page & 31); | ||
157 | |||
158 | if (flags & VM_MAYREAD) | ||
159 | mask[idx] |= bit; | ||
160 | else | ||
161 | mask[idx] &= ~bit; | ||
162 | mask += page_mask_nelts; | ||
163 | if (flags & VM_MAYWRITE) | ||
164 | mask[idx] |= bit; | ||
165 | else | ||
166 | mask[idx] &= ~bit; | ||
167 | mask += page_mask_nelts; | ||
168 | if (flags & VM_MAYEXEC) | ||
169 | mask[idx] |= bit; | ||
170 | else | ||
171 | mask[idx] &= ~bit; | ||
172 | } | ||
173 | |||
174 | static inline void update_protections(struct mm_struct *mm) | ||
125 | { | 175 | { |
126 | activate_mm(prev, next); | 176 | flush_switched_cplbs(); |
177 | set_mask_dcplbs(mm->context.page_rwx_mask); | ||
127 | } | 178 | } |
179 | #endif | ||
128 | 180 | ||
129 | #endif | 181 | #endif |
diff --git a/include/asm-blackfin/traps.h b/include/asm-blackfin/traps.h index ee1cbf73a9ab..f0e5f940d9ca 100644 --- a/include/asm-blackfin/traps.h +++ b/include/asm-blackfin/traps.h | |||
@@ -45,6 +45,10 @@ | |||
45 | #define VEC_CPLB_I_M (44) | 45 | #define VEC_CPLB_I_M (44) |
46 | #define VEC_CPLB_I_MHIT (45) | 46 | #define VEC_CPLB_I_MHIT (45) |
47 | #define VEC_ILL_RES (46) /* including unvalid supervisor mode insn */ | 47 | #define VEC_ILL_RES (46) /* including unvalid supervisor mode insn */ |
48 | /* The hardware reserves (63) for future use - we use it to tell our | ||
49 | * normal exception handling code we have a hardware error | ||
50 | */ | ||
51 | #define VEC_HWERR (63) | ||
48 | 52 | ||
49 | #ifndef __ASSEMBLY__ | 53 | #ifndef __ASSEMBLY__ |
50 | 54 | ||
diff --git a/include/asm-blackfin/uaccess.h b/include/asm-blackfin/uaccess.h index 2233f8f9314d..22a410b8003b 100644 --- a/include/asm-blackfin/uaccess.h +++ b/include/asm-blackfin/uaccess.h | |||
@@ -31,7 +31,7 @@ static inline void set_fs(mm_segment_t fs) | |||
31 | #define VERIFY_READ 0 | 31 | #define VERIFY_READ 0 |
32 | #define VERIFY_WRITE 1 | 32 | #define VERIFY_WRITE 1 |
33 | 33 | ||
34 | #define access_ok(type,addr,size) _access_ok((unsigned long)(addr),(size)) | 34 | #define access_ok(type, addr, size) _access_ok((unsigned long)(addr), (size)) |
35 | 35 | ||
36 | static inline int is_in_rom(unsigned long addr) | 36 | static inline int is_in_rom(unsigned long addr) |
37 | { | 37 | { |
diff --git a/include/asm-blackfin/unistd.h b/include/asm-blackfin/unistd.h index 07ffe8b718c5..e98167358d26 100644 --- a/include/asm-blackfin/unistd.h +++ b/include/asm-blackfin/unistd.h | |||
@@ -369,8 +369,9 @@ | |||
369 | #define __NR_set_robust_list 354 | 369 | #define __NR_set_robust_list 354 |
370 | #define __NR_get_robust_list 355 | 370 | #define __NR_get_robust_list 355 |
371 | #define __NR_fallocate 356 | 371 | #define __NR_fallocate 356 |
372 | #define __NR_semtimedop 357 | ||
372 | 373 | ||
373 | #define __NR_syscall 357 | 374 | #define __NR_syscall 358 |
374 | #define NR_syscalls __NR_syscall | 375 | #define NR_syscalls __NR_syscall |
375 | 376 | ||
376 | /* Old optional stuff no one actually uses */ | 377 | /* Old optional stuff no one actually uses */ |
diff --git a/include/asm-s390/airq.h b/include/asm-s390/airq.h new file mode 100644 index 000000000000..41d028cb52a4 --- /dev/null +++ b/include/asm-s390/airq.h | |||
@@ -0,0 +1,19 @@ | |||
1 | /* | ||
2 | * include/asm-s390/airq.h | ||
3 | * | ||
4 | * Copyright IBM Corp. 2002,2007 | ||
5 | * Author(s): Ingo Adlung <adlung@de.ibm.com> | ||
6 | * Cornelia Huck <cornelia.huck@de.ibm.com> | ||
7 | * Arnd Bergmann <arndb@de.ibm.com> | ||
8 | * Peter Oberparleiter <peter.oberparleiter@de.ibm.com> | ||
9 | */ | ||
10 | |||
11 | #ifndef _ASM_S390_AIRQ_H | ||
12 | #define _ASM_S390_AIRQ_H | ||
13 | |||
14 | typedef void (*adapter_int_handler_t)(void *, void *); | ||
15 | |||
16 | void *s390_register_adapter_interrupt(adapter_int_handler_t, void *); | ||
17 | void s390_unregister_adapter_interrupt(void *); | ||
18 | |||
19 | #endif /* _ASM_S390_AIRQ_H */ | ||
diff --git a/include/asm-s390/cio.h b/include/asm-s390/cio.h index 2f08c16e44ad..123b557c3ff4 100644 --- a/include/asm-s390/cio.h +++ b/include/asm-s390/cio.h | |||
@@ -24,8 +24,8 @@ | |||
24 | * @fmt: format | 24 | * @fmt: format |
25 | * @pfch: prefetch | 25 | * @pfch: prefetch |
26 | * @isic: initial-status interruption control | 26 | * @isic: initial-status interruption control |
27 | * @alcc: adress-limit checking control | 27 | * @alcc: address-limit checking control |
28 | * @ssi: supress-suspended interruption | 28 | * @ssi: suppress-suspended interruption |
29 | * @zcc: zero condition code | 29 | * @zcc: zero condition code |
30 | * @ectl: extended control | 30 | * @ectl: extended control |
31 | * @pno: path not operational | 31 | * @pno: path not operational |
diff --git a/include/asm-s390/dasd.h b/include/asm-s390/dasd.h index 604f68fa6f56..3f002e13d024 100644 --- a/include/asm-s390/dasd.h +++ b/include/asm-s390/dasd.h | |||
@@ -105,7 +105,7 @@ typedef struct dasd_information_t { | |||
105 | } dasd_information_t; | 105 | } dasd_information_t; |
106 | 106 | ||
107 | /* | 107 | /* |
108 | * Read Subsystem Data - Perfomance Statistics | 108 | * Read Subsystem Data - Performance Statistics |
109 | */ | 109 | */ |
110 | typedef struct dasd_rssd_perf_stats_t { | 110 | typedef struct dasd_rssd_perf_stats_t { |
111 | unsigned char invalid:1; | 111 | unsigned char invalid:1; |
diff --git a/include/asm-s390/ipl.h b/include/asm-s390/ipl.h index 2c40fd3a137f..c1b2e50392bb 100644 --- a/include/asm-s390/ipl.h +++ b/include/asm-s390/ipl.h | |||
@@ -83,6 +83,8 @@ extern u32 dump_prefix_page; | |||
83 | extern unsigned int zfcpdump_prefix_array[]; | 83 | extern unsigned int zfcpdump_prefix_array[]; |
84 | 84 | ||
85 | extern void do_reipl(void); | 85 | extern void do_reipl(void); |
86 | extern void do_halt(void); | ||
87 | extern void do_poff(void); | ||
86 | extern void ipl_save_parameters(void); | 88 | extern void ipl_save_parameters(void); |
87 | 89 | ||
88 | enum { | 90 | enum { |
@@ -118,7 +120,7 @@ struct ipl_info | |||
118 | }; | 120 | }; |
119 | 121 | ||
120 | extern struct ipl_info ipl_info; | 122 | extern struct ipl_info ipl_info; |
121 | extern void setup_ipl_info(void); | 123 | extern void setup_ipl(void); |
122 | 124 | ||
123 | /* | 125 | /* |
124 | * DIAG 308 support | 126 | * DIAG 308 support |
@@ -141,6 +143,10 @@ enum diag308_opt { | |||
141 | DIAG308_IPL_OPT_DUMP = 0x20, | 143 | DIAG308_IPL_OPT_DUMP = 0x20, |
142 | }; | 144 | }; |
143 | 145 | ||
146 | enum diag308_flags { | ||
147 | DIAG308_FLAGS_LP_VALID = 0x80, | ||
148 | }; | ||
149 | |||
144 | enum diag308_rc { | 150 | enum diag308_rc { |
145 | DIAG308_RC_OK = 1, | 151 | DIAG308_RC_OK = 1, |
146 | }; | 152 | }; |
diff --git a/include/asm-s390/mmu_context.h b/include/asm-s390/mmu_context.h index 05b842126b99..a77d4ba3c8eb 100644 --- a/include/asm-s390/mmu_context.h +++ b/include/asm-s390/mmu_context.h | |||
@@ -12,10 +12,15 @@ | |||
12 | #include <asm/pgalloc.h> | 12 | #include <asm/pgalloc.h> |
13 | #include <asm-generic/mm_hooks.h> | 13 | #include <asm-generic/mm_hooks.h> |
14 | 14 | ||
15 | /* | 15 | static inline int init_new_context(struct task_struct *tsk, |
16 | * get a new mmu context.. S390 don't know about contexts. | 16 | struct mm_struct *mm) |
17 | */ | 17 | { |
18 | #define init_new_context(tsk,mm) 0 | 18 | mm->context = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS; |
19 | #ifdef CONFIG_64BIT | ||
20 | mm->context |= _ASCE_TYPE_REGION3; | ||
21 | #endif | ||
22 | return 0; | ||
23 | } | ||
19 | 24 | ||
20 | #define destroy_context(mm) do { } while (0) | 25 | #define destroy_context(mm) do { } while (0) |
21 | 26 | ||
@@ -27,19 +32,11 @@ | |||
27 | 32 | ||
28 | static inline void update_mm(struct mm_struct *mm, struct task_struct *tsk) | 33 | static inline void update_mm(struct mm_struct *mm, struct task_struct *tsk) |
29 | { | 34 | { |
30 | pgd_t *pgd = mm->pgd; | 35 | S390_lowcore.user_asce = mm->context | __pa(mm->pgd); |
31 | unsigned long asce_bits; | ||
32 | |||
33 | /* Calculate asce bits from the first pgd table entry. */ | ||
34 | asce_bits = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS; | ||
35 | #ifdef CONFIG_64BIT | ||
36 | asce_bits |= _ASCE_TYPE_REGION3; | ||
37 | #endif | ||
38 | S390_lowcore.user_asce = asce_bits | __pa(pgd); | ||
39 | if (switch_amode) { | 36 | if (switch_amode) { |
40 | /* Load primary space page table origin. */ | 37 | /* Load primary space page table origin. */ |
41 | pgd_t *shadow_pgd = get_shadow_table(pgd) ? : pgd; | 38 | pgd_t *shadow_pgd = get_shadow_table(mm->pgd) ? : mm->pgd; |
42 | S390_lowcore.user_exec_asce = asce_bits | __pa(shadow_pgd); | 39 | S390_lowcore.user_exec_asce = mm->context | __pa(shadow_pgd); |
43 | asm volatile(LCTL_OPCODE" 1,1,%0\n" | 40 | asm volatile(LCTL_OPCODE" 1,1,%0\n" |
44 | : : "m" (S390_lowcore.user_exec_asce) ); | 41 | : : "m" (S390_lowcore.user_exec_asce) ); |
45 | } else | 42 | } else |
diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h index 1f530f8a6280..79b9eab1a0c7 100644 --- a/include/asm-s390/pgtable.h +++ b/include/asm-s390/pgtable.h | |||
@@ -104,41 +104,27 @@ extern char empty_zero_page[PAGE_SIZE]; | |||
104 | 104 | ||
105 | #ifndef __ASSEMBLY__ | 105 | #ifndef __ASSEMBLY__ |
106 | /* | 106 | /* |
107 | * Just any arbitrary offset to the start of the vmalloc VM area: the | 107 | * The vmalloc area will always be on the topmost area of the kernel |
108 | * current 8MB value just means that there will be a 8MB "hole" after the | 108 | * mapping. We reserve 96MB (31bit) / 1GB (64bit) for vmalloc, |
109 | * physical memory until the kernel virtual memory starts. That means that | 109 | * which should be enough for any sane case. |
110 | * any out-of-bounds memory accesses will hopefully be caught. | 110 | * By putting vmalloc at the top, we maximise the gap between physical |
111 | * The vmalloc() routines leaves a hole of 4kB between each vmalloced | 111 | * memory and vmalloc to catch misplaced memory accesses. As a side |
112 | * area for the same reason. ;) | 112 | * effect, this also makes sure that 64 bit module code cannot be used |
113 | * vmalloc area starts at 4GB to prevent syscall table entry exchanging | 113 | * as system call address. |
114 | * from modules. | ||
115 | */ | ||
116 | extern unsigned long vmalloc_end; | ||
117 | |||
118 | #ifdef CONFIG_64BIT | ||
119 | #define VMALLOC_ADDR (max(0x100000000UL, (unsigned long) high_memory)) | ||
120 | #else | ||
121 | #define VMALLOC_ADDR ((unsigned long) high_memory) | ||
122 | #endif | ||
123 | #define VMALLOC_OFFSET (8*1024*1024) | ||
124 | #define VMALLOC_START ((VMALLOC_ADDR + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) | ||
125 | #define VMALLOC_END vmalloc_end | ||
126 | |||
127 | /* | ||
128 | * We need some free virtual space to be able to do vmalloc. | ||
129 | * VMALLOC_MIN_SIZE defines the minimum size of the vmalloc | ||
130 | * area. On a machine with 2GB memory we make sure that we | ||
131 | * have at least 128MB free space for vmalloc. On a machine | ||
132 | * with 4TB we make sure we have at least 128GB. | ||
133 | */ | 114 | */ |
134 | #ifndef __s390x__ | 115 | #ifndef __s390x__ |
135 | #define VMALLOC_MIN_SIZE 0x8000000UL | 116 | #define VMALLOC_START 0x78000000UL |
136 | #define VMALLOC_END_INIT 0x80000000UL | 117 | #define VMALLOC_END 0x7e000000UL |
118 | #define VMEM_MAP_MAX 0x80000000UL | ||
137 | #else /* __s390x__ */ | 119 | #else /* __s390x__ */ |
138 | #define VMALLOC_MIN_SIZE 0x2000000000UL | 120 | #define VMALLOC_START 0x3e000000000UL |
139 | #define VMALLOC_END_INIT 0x40000000000UL | 121 | #define VMALLOC_END 0x3e040000000UL |
122 | #define VMEM_MAP_MAX 0x40000000000UL | ||
140 | #endif /* __s390x__ */ | 123 | #endif /* __s390x__ */ |
141 | 124 | ||
125 | #define VMEM_MAP ((struct page *) VMALLOC_END) | ||
126 | #define VMEM_MAP_SIZE ((VMALLOC_START / PAGE_SIZE) * sizeof(struct page)) | ||
127 | |||
142 | /* | 128 | /* |
143 | * A 31 bit pagetable entry of S390 has following format: | 129 | * A 31 bit pagetable entry of S390 has following format: |
144 | * | PFRA | | OS | | 130 | * | PFRA | | OS | |
diff --git a/include/asm-s390/processor.h b/include/asm-s390/processor.h index 21d40a19355e..c86b982aef5a 100644 --- a/include/asm-s390/processor.h +++ b/include/asm-s390/processor.h | |||
@@ -59,9 +59,6 @@ extern void s390_adjust_jiffies(void); | |||
59 | extern void print_cpu_info(struct cpuinfo_S390 *); | 59 | extern void print_cpu_info(struct cpuinfo_S390 *); |
60 | extern int get_cpu_capability(unsigned int *); | 60 | extern int get_cpu_capability(unsigned int *); |
61 | 61 | ||
62 | /* Lazy FPU handling on uni-processor */ | ||
63 | extern struct task_struct *last_task_used_math; | ||
64 | |||
65 | /* | 62 | /* |
66 | * User space process size: 2GB for 31 bit, 4TB for 64 bit. | 63 | * User space process size: 2GB for 31 bit, 4TB for 64 bit. |
67 | */ | 64 | */ |
@@ -95,7 +92,6 @@ struct thread_struct { | |||
95 | unsigned long ksp; /* kernel stack pointer */ | 92 | unsigned long ksp; /* kernel stack pointer */ |
96 | mm_segment_t mm_segment; | 93 | mm_segment_t mm_segment; |
97 | unsigned long prot_addr; /* address of protection-excep. */ | 94 | unsigned long prot_addr; /* address of protection-excep. */ |
98 | unsigned int error_code; /* error-code of last prog-excep. */ | ||
99 | unsigned int trap_no; | 95 | unsigned int trap_no; |
100 | per_struct per_info; | 96 | per_struct per_info; |
101 | /* Used to give failing instruction back to user for ieee exceptions */ | 97 | /* Used to give failing instruction back to user for ieee exceptions */ |
diff --git a/include/asm-s390/ptrace.h b/include/asm-s390/ptrace.h index 332ee73688fc..61f6952f2e35 100644 --- a/include/asm-s390/ptrace.h +++ b/include/asm-s390/ptrace.h | |||
@@ -465,6 +465,14 @@ struct user_regs_struct | |||
465 | #ifdef __KERNEL__ | 465 | #ifdef __KERNEL__ |
466 | #define __ARCH_SYS_PTRACE 1 | 466 | #define __ARCH_SYS_PTRACE 1 |
467 | 467 | ||
468 | /* | ||
469 | * These are defined as per linux/ptrace.h, which see. | ||
470 | */ | ||
471 | #define arch_has_single_step() (1) | ||
472 | struct task_struct; | ||
473 | extern void user_enable_single_step(struct task_struct *); | ||
474 | extern void user_disable_single_step(struct task_struct *); | ||
475 | |||
468 | #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0) | 476 | #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0) |
469 | #define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN) | 477 | #define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN) |
470 | #define regs_return_value(regs)((regs)->gprs[2]) | 478 | #define regs_return_value(regs)((regs)->gprs[2]) |
diff --git a/include/asm-s390/qdio.h b/include/asm-s390/qdio.h index 74db1dc10a7d..4b8ff55f680e 100644 --- a/include/asm-s390/qdio.h +++ b/include/asm-s390/qdio.h | |||
@@ -184,7 +184,7 @@ struct qdr { | |||
184 | #endif /* QDIO_32_BIT */ | 184 | #endif /* QDIO_32_BIT */ |
185 | unsigned long qiba; /* queue-information-block address */ | 185 | unsigned long qiba; /* queue-information-block address */ |
186 | unsigned int res8; /* reserved */ | 186 | unsigned int res8; /* reserved */ |
187 | unsigned int qkey : 4; /* queue-informatio-block key */ | 187 | unsigned int qkey : 4; /* queue-information-block key */ |
188 | unsigned int res9 : 28; /* reserved */ | 188 | unsigned int res9 : 28; /* reserved */ |
189 | /* union _qd {*/ /* why this? */ | 189 | /* union _qd {*/ /* why this? */ |
190 | struct qdesfmt0 qdf0[126]; | 190 | struct qdesfmt0 qdf0[126]; |
diff --git a/include/asm-s390/rwsem.h b/include/asm-s390/rwsem.h index 90f4eccaa290..9d2a17971805 100644 --- a/include/asm-s390/rwsem.h +++ b/include/asm-s390/rwsem.h | |||
@@ -91,8 +91,8 @@ struct rw_semaphore { | |||
91 | #endif | 91 | #endif |
92 | 92 | ||
93 | #define __RWSEM_INITIALIZER(name) \ | 93 | #define __RWSEM_INITIALIZER(name) \ |
94 | { RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, LIST_HEAD_INIT((name).wait_list) \ | 94 | { RWSEM_UNLOCKED_VALUE, __SPIN_LOCK_UNLOCKED((name).wait.lock), \ |
95 | __RWSEM_DEP_MAP_INIT(name) } | 95 | LIST_HEAD_INIT((name).wait_list) __RWSEM_DEP_MAP_INIT(name) } |
96 | 96 | ||
97 | #define DECLARE_RWSEM(name) \ | 97 | #define DECLARE_RWSEM(name) \ |
98 | struct rw_semaphore name = __RWSEM_INITIALIZER(name) | 98 | struct rw_semaphore name = __RWSEM_INITIALIZER(name) |
diff --git a/include/asm-s390/sclp.h b/include/asm-s390/sclp.h index cb9faf1ea5cf..b5f2843013a3 100644 --- a/include/asm-s390/sclp.h +++ b/include/asm-s390/sclp.h | |||
@@ -27,7 +27,25 @@ struct sclp_ipl_info { | |||
27 | char loadparm[LOADPARM_LEN]; | 27 | char loadparm[LOADPARM_LEN]; |
28 | }; | 28 | }; |
29 | 29 | ||
30 | void sclp_readinfo_early(void); | 30 | struct sclp_cpu_entry { |
31 | u8 address; | ||
32 | u8 reserved0[13]; | ||
33 | u8 type; | ||
34 | u8 reserved1; | ||
35 | } __attribute__((packed)); | ||
36 | |||
37 | struct sclp_cpu_info { | ||
38 | unsigned int configured; | ||
39 | unsigned int standby; | ||
40 | unsigned int combined; | ||
41 | int has_cpu_type; | ||
42 | struct sclp_cpu_entry cpu[255]; | ||
43 | }; | ||
44 | |||
45 | int sclp_get_cpu_info(struct sclp_cpu_info *info); | ||
46 | int sclp_cpu_configure(u8 cpu); | ||
47 | int sclp_cpu_deconfigure(u8 cpu); | ||
48 | void sclp_read_info_early(void); | ||
31 | void sclp_facilities_detect(void); | 49 | void sclp_facilities_detect(void); |
32 | unsigned long long sclp_memory_detect(void); | 50 | unsigned long long sclp_memory_detect(void); |
33 | int sclp_sdias_blk_count(void); | 51 | int sclp_sdias_blk_count(void); |
diff --git a/include/asm-s390/smp.h b/include/asm-s390/smp.h index 07708c07701e..c7b74326a527 100644 --- a/include/asm-s390/smp.h +++ b/include/asm-s390/smp.h | |||
@@ -35,8 +35,6 @@ extern void machine_restart_smp(char *); | |||
35 | extern void machine_halt_smp(void); | 35 | extern void machine_halt_smp(void); |
36 | extern void machine_power_off_smp(void); | 36 | extern void machine_power_off_smp(void); |
37 | 37 | ||
38 | extern void smp_setup_cpu_possible_map(void); | ||
39 | |||
40 | #define NO_PROC_ID 0xFF /* No processor magic marker */ | 38 | #define NO_PROC_ID 0xFF /* No processor magic marker */ |
41 | 39 | ||
42 | /* | 40 | /* |
@@ -92,6 +90,8 @@ extern void __cpu_die (unsigned int cpu); | |||
92 | extern void cpu_die (void) __attribute__ ((noreturn)); | 90 | extern void cpu_die (void) __attribute__ ((noreturn)); |
93 | extern int __cpu_up (unsigned int cpu); | 91 | extern int __cpu_up (unsigned int cpu); |
94 | 92 | ||
93 | extern int smp_call_function_mask(cpumask_t mask, void (*func)(void *), | ||
94 | void *info, int wait); | ||
95 | #endif | 95 | #endif |
96 | 96 | ||
97 | #ifndef CONFIG_SMP | 97 | #ifndef CONFIG_SMP |
@@ -103,7 +103,6 @@ static inline void smp_send_stop(void) | |||
103 | 103 | ||
104 | #define hard_smp_processor_id() 0 | 104 | #define hard_smp_processor_id() 0 |
105 | #define smp_cpu_not_running(cpu) 1 | 105 | #define smp_cpu_not_running(cpu) 1 |
106 | #define smp_setup_cpu_possible_map() do { } while (0) | ||
107 | #endif | 106 | #endif |
108 | 107 | ||
109 | extern union save_area *zfcpdump_save_areas[NR_CPUS + 1]; | 108 | extern union save_area *zfcpdump_save_areas[NR_CPUS + 1]; |
diff --git a/include/asm-s390/spinlock.h b/include/asm-s390/spinlock.h index 3fd43826fd0b..df84ae96915f 100644 --- a/include/asm-s390/spinlock.h +++ b/include/asm-s390/spinlock.h | |||
@@ -53,44 +53,48 @@ _raw_compare_and_swap(volatile unsigned int *lock, | |||
53 | */ | 53 | */ |
54 | 54 | ||
55 | #define __raw_spin_is_locked(x) ((x)->owner_cpu != 0) | 55 | #define __raw_spin_is_locked(x) ((x)->owner_cpu != 0) |
56 | #define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) | ||
57 | #define __raw_spin_unlock_wait(lock) \ | 56 | #define __raw_spin_unlock_wait(lock) \ |
58 | do { while (__raw_spin_is_locked(lock)) \ | 57 | do { while (__raw_spin_is_locked(lock)) \ |
59 | _raw_spin_relax(lock); } while (0) | 58 | _raw_spin_relax(lock); } while (0) |
60 | 59 | ||
61 | extern void _raw_spin_lock_wait(raw_spinlock_t *, unsigned int pc); | 60 | extern void _raw_spin_lock_wait(raw_spinlock_t *); |
62 | extern int _raw_spin_trylock_retry(raw_spinlock_t *, unsigned int pc); | 61 | extern void _raw_spin_lock_wait_flags(raw_spinlock_t *, unsigned long flags); |
62 | extern int _raw_spin_trylock_retry(raw_spinlock_t *); | ||
63 | extern void _raw_spin_relax(raw_spinlock_t *lock); | 63 | extern void _raw_spin_relax(raw_spinlock_t *lock); |
64 | 64 | ||
65 | static inline void __raw_spin_lock(raw_spinlock_t *lp) | 65 | static inline void __raw_spin_lock(raw_spinlock_t *lp) |
66 | { | 66 | { |
67 | unsigned long pc = 1 | (unsigned long) __builtin_return_address(0); | ||
68 | int old; | 67 | int old; |
69 | 68 | ||
70 | old = _raw_compare_and_swap(&lp->owner_cpu, 0, ~smp_processor_id()); | 69 | old = _raw_compare_and_swap(&lp->owner_cpu, 0, ~smp_processor_id()); |
71 | if (likely(old == 0)) { | 70 | if (likely(old == 0)) |
72 | lp->owner_pc = pc; | ||
73 | return; | 71 | return; |
74 | } | 72 | _raw_spin_lock_wait(lp); |
75 | _raw_spin_lock_wait(lp, pc); | 73 | } |
74 | |||
75 | static inline void __raw_spin_lock_flags(raw_spinlock_t *lp, | ||
76 | unsigned long flags) | ||
77 | { | ||
78 | int old; | ||
79 | |||
80 | old = _raw_compare_and_swap(&lp->owner_cpu, 0, ~smp_processor_id()); | ||
81 | if (likely(old == 0)) | ||
82 | return; | ||
83 | _raw_spin_lock_wait_flags(lp, flags); | ||
76 | } | 84 | } |
77 | 85 | ||
78 | static inline int __raw_spin_trylock(raw_spinlock_t *lp) | 86 | static inline int __raw_spin_trylock(raw_spinlock_t *lp) |
79 | { | 87 | { |
80 | unsigned long pc = 1 | (unsigned long) __builtin_return_address(0); | ||
81 | int old; | 88 | int old; |
82 | 89 | ||
83 | old = _raw_compare_and_swap(&lp->owner_cpu, 0, ~smp_processor_id()); | 90 | old = _raw_compare_and_swap(&lp->owner_cpu, 0, ~smp_processor_id()); |
84 | if (likely(old == 0)) { | 91 | if (likely(old == 0)) |
85 | lp->owner_pc = pc; | ||
86 | return 1; | 92 | return 1; |
87 | } | 93 | return _raw_spin_trylock_retry(lp); |
88 | return _raw_spin_trylock_retry(lp, pc); | ||
89 | } | 94 | } |
90 | 95 | ||
91 | static inline void __raw_spin_unlock(raw_spinlock_t *lp) | 96 | static inline void __raw_spin_unlock(raw_spinlock_t *lp) |
92 | { | 97 | { |
93 | lp->owner_pc = 0; | ||
94 | _raw_compare_and_swap(&lp->owner_cpu, lp->owner_cpu, 0); | 98 | _raw_compare_and_swap(&lp->owner_cpu, lp->owner_cpu, 0); |
95 | } | 99 | } |
96 | 100 | ||
diff --git a/include/asm-s390/spinlock_types.h b/include/asm-s390/spinlock_types.h index b7ac13f7aa37..654abc40de04 100644 --- a/include/asm-s390/spinlock_types.h +++ b/include/asm-s390/spinlock_types.h | |||
@@ -7,7 +7,6 @@ | |||
7 | 7 | ||
8 | typedef struct { | 8 | typedef struct { |
9 | volatile unsigned int owner_cpu; | 9 | volatile unsigned int owner_cpu; |
10 | volatile unsigned int owner_pc; | ||
11 | } __attribute__ ((aligned (4))) raw_spinlock_t; | 10 | } __attribute__ ((aligned (4))) raw_spinlock_t; |
12 | 11 | ||
13 | #define __RAW_SPIN_LOCK_UNLOCKED { 0 } | 12 | #define __RAW_SPIN_LOCK_UNLOCKED { 0 } |
diff --git a/include/asm-s390/tlbflush.h b/include/asm-s390/tlbflush.h index a69bd2490d52..70fa5ae58180 100644 --- a/include/asm-s390/tlbflush.h +++ b/include/asm-s390/tlbflush.h | |||
@@ -42,11 +42,11 @@ static inline void __tlb_flush_global(void) | |||
42 | /* | 42 | /* |
43 | * Flush all tlb entries of a page table on all cpus. | 43 | * Flush all tlb entries of a page table on all cpus. |
44 | */ | 44 | */ |
45 | static inline void __tlb_flush_idte(pgd_t *pgd) | 45 | static inline void __tlb_flush_idte(unsigned long asce) |
46 | { | 46 | { |
47 | asm volatile( | 47 | asm volatile( |
48 | " .insn rrf,0xb98e0000,0,%0,%1,0" | 48 | " .insn rrf,0xb98e0000,0,%0,%1,0" |
49 | : : "a" (2048), "a" (__pa(pgd) & PAGE_MASK) : "cc" ); | 49 | : : "a" (2048), "a" (asce) : "cc" ); |
50 | } | 50 | } |
51 | 51 | ||
52 | static inline void __tlb_flush_mm(struct mm_struct * mm) | 52 | static inline void __tlb_flush_mm(struct mm_struct * mm) |
@@ -61,11 +61,11 @@ static inline void __tlb_flush_mm(struct mm_struct * mm) | |||
61 | * only ran on the local cpu. | 61 | * only ran on the local cpu. |
62 | */ | 62 | */ |
63 | if (MACHINE_HAS_IDTE) { | 63 | if (MACHINE_HAS_IDTE) { |
64 | pgd_t *shadow_pgd = get_shadow_table(mm->pgd); | 64 | pgd_t *shadow = get_shadow_table(mm->pgd); |
65 | 65 | ||
66 | if (shadow_pgd) | 66 | if (shadow) |
67 | __tlb_flush_idte(shadow_pgd); | 67 | __tlb_flush_idte((unsigned long) shadow | mm->context); |
68 | __tlb_flush_idte(mm->pgd); | 68 | __tlb_flush_idte((unsigned long) mm->pgd | mm->context); |
69 | return; | 69 | return; |
70 | } | 70 | } |
71 | preempt_disable(); | 71 | preempt_disable(); |
@@ -106,9 +106,23 @@ static inline void __tlb_flush_mm_cond(struct mm_struct * mm) | |||
106 | */ | 106 | */ |
107 | #define flush_tlb() do { } while (0) | 107 | #define flush_tlb() do { } while (0) |
108 | #define flush_tlb_all() do { } while (0) | 108 | #define flush_tlb_all() do { } while (0) |
109 | #define flush_tlb_mm(mm) __tlb_flush_mm_cond(mm) | ||
110 | #define flush_tlb_page(vma, addr) do { } while (0) | 109 | #define flush_tlb_page(vma, addr) do { } while (0) |
111 | #define flush_tlb_range(vma, start, end) __tlb_flush_mm_cond(mm) | 110 | |
112 | #define flush_tlb_kernel_range(start, end) __tlb_flush_mm(&init_mm) | 111 | static inline void flush_tlb_mm(struct mm_struct *mm) |
112 | { | ||
113 | __tlb_flush_mm_cond(mm); | ||
114 | } | ||
115 | |||
116 | static inline void flush_tlb_range(struct vm_area_struct *vma, | ||
117 | unsigned long start, unsigned long end) | ||
118 | { | ||
119 | __tlb_flush_mm_cond(vma->vm_mm); | ||
120 | } | ||
121 | |||
122 | static inline void flush_tlb_kernel_range(unsigned long start, | ||
123 | unsigned long end) | ||
124 | { | ||
125 | __tlb_flush_mm(&init_mm); | ||
126 | } | ||
113 | 127 | ||
114 | #endif /* _S390_TLBFLUSH_H */ | 128 | #endif /* _S390_TLBFLUSH_H */ |
diff --git a/include/asm-s390/zcrypt.h b/include/asm-s390/zcrypt.h index a5dada617751..f228f1b86877 100644 --- a/include/asm-s390/zcrypt.h +++ b/include/asm-s390/zcrypt.h | |||
@@ -117,7 +117,7 @@ struct CPRBX { | |||
117 | unsigned char padx004[16 - sizeof (char *)]; | 117 | unsigned char padx004[16 - sizeof (char *)]; |
118 | unsigned char * req_extb; /* request extension block 'addr'*/ | 118 | unsigned char * req_extb; /* request extension block 'addr'*/ |
119 | unsigned char padx005[16 - sizeof (char *)]; | 119 | unsigned char padx005[16 - sizeof (char *)]; |
120 | unsigned char * rpl_extb; /* reply extension block 'addres'*/ | 120 | unsigned char * rpl_extb; /* reply extension block 'address'*/ |
121 | unsigned short ccp_rtcode; /* server return code */ | 121 | unsigned short ccp_rtcode; /* server return code */ |
122 | unsigned short ccp_rscode; /* server reason code */ | 122 | unsigned short ccp_rscode; /* server reason code */ |
123 | unsigned int mac_data_len; /* Mac Data Length */ | 123 | unsigned int mac_data_len; /* Mac Data Length */ |
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index bd20a4e8663a..49b7a4c31a6d 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -143,7 +143,6 @@ enum rq_cmd_type_bits { | |||
143 | * use REQ_TYPE_SPECIAL and use rq->cmd[0] with the range of driver | 143 | * use REQ_TYPE_SPECIAL and use rq->cmd[0] with the range of driver |
144 | * private REQ_LB opcodes to differentiate what type of request this is | 144 | * private REQ_LB opcodes to differentiate what type of request this is |
145 | */ | 145 | */ |
146 | REQ_TYPE_ATA_CMD, | ||
147 | REQ_TYPE_ATA_TASKFILE, | 146 | REQ_TYPE_ATA_TASKFILE, |
148 | REQ_TYPE_ATA_PC, | 147 | REQ_TYPE_ATA_PC, |
149 | }; | 148 | }; |
diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h index c7a51a196f51..f922b060158b 100644 --- a/include/linux/i2c-id.h +++ b/include/linux/i2c-id.h | |||
@@ -33,23 +33,13 @@ | |||
33 | 33 | ||
34 | #define I2C_DRIVERID_MSP3400 1 | 34 | #define I2C_DRIVERID_MSP3400 1 |
35 | #define I2C_DRIVERID_TUNER 2 | 35 | #define I2C_DRIVERID_TUNER 2 |
36 | #define I2C_DRIVERID_VIDEOTEX 3 /* please rename */ | ||
37 | #define I2C_DRIVERID_TDA8425 4 /* stereo sound processor */ | 36 | #define I2C_DRIVERID_TDA8425 4 /* stereo sound processor */ |
38 | #define I2C_DRIVERID_TEA6420 5 /* audio matrix switch */ | 37 | #define I2C_DRIVERID_TEA6420 5 /* audio matrix switch */ |
39 | #define I2C_DRIVERID_TEA6415C 6 /* video matrix switch */ | 38 | #define I2C_DRIVERID_TEA6415C 6 /* video matrix switch */ |
40 | #define I2C_DRIVERID_TDA9840 7 /* stereo sound processor */ | 39 | #define I2C_DRIVERID_TDA9840 7 /* stereo sound processor */ |
41 | #define I2C_DRIVERID_SAA7111A 8 /* video input processor */ | 40 | #define I2C_DRIVERID_SAA7111A 8 /* video input processor */ |
42 | #define I2C_DRIVERID_SAA5281 9 /* videotext decoder */ | ||
43 | #define I2C_DRIVERID_SAA7112 10 /* video decoder, image scaler */ | ||
44 | #define I2C_DRIVERID_SAA7120 11 /* video encoder */ | ||
45 | #define I2C_DRIVERID_SAA7121 12 /* video encoder */ | ||
46 | #define I2C_DRIVERID_SAA7185B 13 /* video encoder */ | 41 | #define I2C_DRIVERID_SAA7185B 13 /* video encoder */ |
47 | #define I2C_DRIVERID_CH7003 14 /* digital pc to tv encoder */ | ||
48 | #define I2C_DRIVERID_PCF8574A 15 /* i2c expander - 8 bit in/out */ | ||
49 | #define I2C_DRIVERID_PCF8582C 16 /* eeprom */ | ||
50 | #define I2C_DRIVERID_AT24Cxx 17 /* eeprom 1/2/4/8/16 K */ | ||
51 | #define I2C_DRIVERID_TEA6300 18 /* audio mixer */ | 42 | #define I2C_DRIVERID_TEA6300 18 /* audio mixer */ |
52 | #define I2C_DRIVERID_BT829 19 /* pc to tv encoder */ | ||
53 | #define I2C_DRIVERID_TDA9850 20 /* audio mixer */ | 43 | #define I2C_DRIVERID_TDA9850 20 /* audio mixer */ |
54 | #define I2C_DRIVERID_TDA9855 21 /* audio mixer */ | 44 | #define I2C_DRIVERID_TDA9855 21 /* audio mixer */ |
55 | #define I2C_DRIVERID_SAA7110 22 /* video decoder */ | 45 | #define I2C_DRIVERID_SAA7110 22 /* video decoder */ |
@@ -60,42 +50,19 @@ | |||
60 | #define I2C_DRIVERID_TDA7432 27 /* Stereo sound processor */ | 50 | #define I2C_DRIVERID_TDA7432 27 /* Stereo sound processor */ |
61 | #define I2C_DRIVERID_TVMIXER 28 /* Mixer driver for tv cards */ | 51 | #define I2C_DRIVERID_TVMIXER 28 /* Mixer driver for tv cards */ |
62 | #define I2C_DRIVERID_TVAUDIO 29 /* Generic TV sound driver */ | 52 | #define I2C_DRIVERID_TVAUDIO 29 /* Generic TV sound driver */ |
63 | #define I2C_DRIVERID_DPL3518 30 /* Dolby decoder chip */ | ||
64 | #define I2C_DRIVERID_TDA9873 31 /* TV sound decoder chip */ | 53 | #define I2C_DRIVERID_TDA9873 31 /* TV sound decoder chip */ |
65 | #define I2C_DRIVERID_TDA9875 32 /* TV sound decoder chip */ | 54 | #define I2C_DRIVERID_TDA9875 32 /* TV sound decoder chip */ |
66 | #define I2C_DRIVERID_PIC16C54_PV9 33 /* Audio mux/ir receiver */ | 55 | #define I2C_DRIVERID_PIC16C54_PV9 33 /* Audio mux/ir receiver */ |
67 | |||
68 | #define I2C_DRIVERID_SBATT 34 /* Smart Battery Device */ | ||
69 | #define I2C_DRIVERID_SBS 35 /* SB System Manager */ | ||
70 | #define I2C_DRIVERID_VES1893 36 /* VLSI DVB-S decoder */ | ||
71 | #define I2C_DRIVERID_VES1820 37 /* VLSI DVB-C decoder */ | ||
72 | #define I2C_DRIVERID_SAA7113 38 /* video decoder */ | ||
73 | #define I2C_DRIVERID_TDA8444 39 /* octuple 6-bit DAC */ | ||
74 | #define I2C_DRIVERID_BT819 40 /* video decoder */ | 56 | #define I2C_DRIVERID_BT819 40 /* video decoder */ |
75 | #define I2C_DRIVERID_BT856 41 /* video encoder */ | 57 | #define I2C_DRIVERID_BT856 41 /* video encoder */ |
76 | #define I2C_DRIVERID_VPX3220 42 /* video decoder+vbi/vtxt */ | 58 | #define I2C_DRIVERID_VPX3220 42 /* video decoder+vbi/vtxt */ |
77 | #define I2C_DRIVERID_DRP3510 43 /* ADR decoder (Astra Radio) */ | ||
78 | #define I2C_DRIVERID_SP5055 44 /* Satellite tuner */ | ||
79 | #define I2C_DRIVERID_STV0030 45 /* Multipurpose switch */ | ||
80 | #define I2C_DRIVERID_SAA7108 46 /* video decoder, image scaler */ | ||
81 | #define I2C_DRIVERID_DS1307 47 /* DS1307 real time clock */ | ||
82 | #define I2C_DRIVERID_ADV7175 48 /* ADV 7175/7176 video encoder */ | 59 | #define I2C_DRIVERID_ADV7175 48 /* ADV 7175/7176 video encoder */ |
83 | #define I2C_DRIVERID_SAA7114 49 /* video decoder */ | 60 | #define I2C_DRIVERID_SAA7114 49 /* video decoder */ |
84 | #define I2C_DRIVERID_ZR36120 50 /* Zoran 36120 video encoder */ | ||
85 | #define I2C_DRIVERID_24LC32A 51 /* Microchip 24LC32A 32k EEPROM */ | ||
86 | #define I2C_DRIVERID_STM41T00 52 /* real time clock */ | ||
87 | #define I2C_DRIVERID_UDA1342 53 /* UDA1342 audio codec */ | ||
88 | #define I2C_DRIVERID_ADV7170 54 /* video encoder */ | 61 | #define I2C_DRIVERID_ADV7170 54 /* video encoder */ |
89 | #define I2C_DRIVERID_MAX1617 56 /* temp sensor */ | ||
90 | #define I2C_DRIVERID_SAA7191 57 /* video decoder */ | 62 | #define I2C_DRIVERID_SAA7191 57 /* video decoder */ |
91 | #define I2C_DRIVERID_INDYCAM 58 /* SGI IndyCam */ | 63 | #define I2C_DRIVERID_INDYCAM 58 /* SGI IndyCam */ |
92 | #define I2C_DRIVERID_BT832 59 /* CMOS camera video processor */ | ||
93 | #define I2C_DRIVERID_TDA9887 60 /* TDA988x IF-PLL demodulator */ | ||
94 | #define I2C_DRIVERID_OVCAMCHIP 61 /* OmniVision CMOS image sens. */ | 64 | #define I2C_DRIVERID_OVCAMCHIP 61 /* OmniVision CMOS image sens. */ |
95 | #define I2C_DRIVERID_TDA7313 62 /* TDA7313 audio processor */ | ||
96 | #define I2C_DRIVERID_MAX6900 63 /* MAX6900 real-time clock */ | 65 | #define I2C_DRIVERID_MAX6900 63 /* MAX6900 real-time clock */ |
97 | #define I2C_DRIVERID_SAA7114H 64 /* video decoder */ | ||
98 | #define I2C_DRIVERID_DS1374 65 /* DS1374 real time clock */ | ||
99 | #define I2C_DRIVERID_TDA9874 66 /* TV sound decoder */ | 66 | #define I2C_DRIVERID_TDA9874 66 /* TV sound decoder */ |
100 | #define I2C_DRIVERID_SAA6752HS 67 /* MPEG2 encoder */ | 67 | #define I2C_DRIVERID_SAA6752HS 67 /* MPEG2 encoder */ |
101 | #define I2C_DRIVERID_TVEEPROM 68 /* TV EEPROM */ | 68 | #define I2C_DRIVERID_TVEEPROM 68 /* TV EEPROM */ |
@@ -114,7 +81,6 @@ | |||
114 | #define I2C_DRIVERID_DS1672 81 /* Dallas/Maxim DS1672 RTC */ | 81 | #define I2C_DRIVERID_DS1672 81 /* Dallas/Maxim DS1672 RTC */ |
115 | #define I2C_DRIVERID_X1205 82 /* Xicor/Intersil X1205 RTC */ | 82 | #define I2C_DRIVERID_X1205 82 /* Xicor/Intersil X1205 RTC */ |
116 | #define I2C_DRIVERID_PCF8563 83 /* Philips PCF8563 RTC */ | 83 | #define I2C_DRIVERID_PCF8563 83 /* Philips PCF8563 RTC */ |
117 | #define I2C_DRIVERID_RS5C372 84 /* Ricoh RS5C372 RTC */ | ||
118 | #define I2C_DRIVERID_BT866 85 /* Conexant bt866 video encoder */ | 84 | #define I2C_DRIVERID_BT866 85 /* Conexant bt866 video encoder */ |
119 | #define I2C_DRIVERID_KS0127 86 /* Samsung ks0127 video decoder */ | 85 | #define I2C_DRIVERID_KS0127 86 /* Samsung ks0127 video decoder */ |
120 | #define I2C_DRIVERID_TLV320AIC23B 87 /* TI TLV320AIC23B audio codec */ | 86 | #define I2C_DRIVERID_TLV320AIC23B 87 /* TI TLV320AIC23B audio codec */ |
@@ -129,8 +95,6 @@ | |||
129 | #define I2C_DRIVERID_CS5345 96 /* cs5345 audio processor */ | 95 | #define I2C_DRIVERID_CS5345 96 /* cs5345 audio processor */ |
130 | 96 | ||
131 | #define I2C_DRIVERID_I2CDEV 900 | 97 | #define I2C_DRIVERID_I2CDEV 900 |
132 | #define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */ | ||
133 | #define I2C_DRIVERID_ALERT 903 /* SMBus Alert Responder Client */ | ||
134 | 98 | ||
135 | /* IDs -- Use DRIVERIDs 1000-1999 for sensors. | 99 | /* IDs -- Use DRIVERIDs 1000-1999 for sensors. |
136 | These were originally in sensors.h in the lm_sensors package */ | 100 | These were originally in sensors.h in the lm_sensors package */ |
@@ -176,24 +140,16 @@ | |||
176 | 140 | ||
177 | /* --- Bit algorithm adapters */ | 141 | /* --- Bit algorithm adapters */ |
178 | #define I2C_HW_B_LP 0x010000 /* Parallel port Philips style */ | 142 | #define I2C_HW_B_LP 0x010000 /* Parallel port Philips style */ |
179 | #define I2C_HW_B_SER 0x010002 /* Serial line interface */ | ||
180 | #define I2C_HW_B_BT848 0x010005 /* BT848 video boards */ | 143 | #define I2C_HW_B_BT848 0x010005 /* BT848 video boards */ |
181 | #define I2C_HW_B_WNV 0x010006 /* Winnov Videums */ | ||
182 | #define I2C_HW_B_VIA 0x010007 /* Via vt82c586b */ | 144 | #define I2C_HW_B_VIA 0x010007 /* Via vt82c586b */ |
183 | #define I2C_HW_B_HYDRA 0x010008 /* Apple Hydra Mac I/O */ | 145 | #define I2C_HW_B_HYDRA 0x010008 /* Apple Hydra Mac I/O */ |
184 | #define I2C_HW_B_G400 0x010009 /* Matrox G400 */ | 146 | #define I2C_HW_B_G400 0x010009 /* Matrox G400 */ |
185 | #define I2C_HW_B_I810 0x01000a /* Intel I810 */ | 147 | #define I2C_HW_B_I810 0x01000a /* Intel I810 */ |
186 | #define I2C_HW_B_VOO 0x01000b /* 3dfx Voodoo 3 / Banshee */ | 148 | #define I2C_HW_B_VOO 0x01000b /* 3dfx Voodoo 3 / Banshee */ |
187 | #define I2C_HW_B_PPORT 0x01000c /* Primitive parallel port adapter */ | ||
188 | #define I2C_HW_B_SAVG 0x01000d /* Savage 4 */ | ||
189 | #define I2C_HW_B_SCX200 0x01000e /* Nat'l Semi SCx200 I2C */ | 149 | #define I2C_HW_B_SCX200 0x01000e /* Nat'l Semi SCx200 I2C */ |
190 | #define I2C_HW_B_RIVA 0x010010 /* Riva based graphics cards */ | 150 | #define I2C_HW_B_RIVA 0x010010 /* Riva based graphics cards */ |
191 | #define I2C_HW_B_IOC 0x010011 /* IOC bit-wiggling */ | 151 | #define I2C_HW_B_IOC 0x010011 /* IOC bit-wiggling */ |
192 | #define I2C_HW_B_TSUNA 0x010012 /* DEC Tsunami chipset */ | ||
193 | #define I2C_HW_B_OMAHA 0x010014 /* Omaha I2C interface (ARM) */ | ||
194 | #define I2C_HW_B_GUIDE 0x010015 /* Guide bit-basher */ | ||
195 | #define I2C_HW_B_IXP2000 0x010016 /* GPIO on IXP2000 systems */ | 152 | #define I2C_HW_B_IXP2000 0x010016 /* GPIO on IXP2000 systems */ |
196 | #define I2C_HW_B_IXP4XX 0x010017 /* GPIO on IXP4XX systems */ | ||
197 | #define I2C_HW_B_S3VIA 0x010018 /* S3Via ProSavage adapter */ | 153 | #define I2C_HW_B_S3VIA 0x010018 /* S3Via ProSavage adapter */ |
198 | #define I2C_HW_B_ZR36067 0x010019 /* Zoran-36057/36067 based boards */ | 154 | #define I2C_HW_B_ZR36067 0x010019 /* Zoran-36057/36067 based boards */ |
199 | #define I2C_HW_B_PCILYNX 0x01001a /* TI PCILynx I2C adapter */ | 155 | #define I2C_HW_B_PCILYNX 0x01001a /* TI PCILynx I2C adapter */ |
@@ -207,22 +163,11 @@ | |||
207 | #define I2C_HW_B_CX23885 0x010022 /* conexant 23885 based tv cards (bus1) */ | 163 | #define I2C_HW_B_CX23885 0x010022 /* conexant 23885 based tv cards (bus1) */ |
208 | 164 | ||
209 | /* --- PCF 8584 based algorithms */ | 165 | /* --- PCF 8584 based algorithms */ |
210 | #define I2C_HW_P_LP 0x020000 /* Parallel port interface */ | ||
211 | #define I2C_HW_P_ISA 0x020001 /* generic ISA Bus inteface card */ | ||
212 | #define I2C_HW_P_ELEK 0x020002 /* Elektor ISA Bus inteface card */ | 166 | #define I2C_HW_P_ELEK 0x020002 /* Elektor ISA Bus inteface card */ |
213 | 167 | ||
214 | /* --- PCA 9564 based algorithms */ | 168 | /* --- PCA 9564 based algorithms */ |
215 | #define I2C_HW_A_ISA 0x1a0000 /* generic ISA Bus interface card */ | 169 | #define I2C_HW_A_ISA 0x1a0000 /* generic ISA Bus interface card */ |
216 | 170 | ||
217 | /* --- ACPI Embedded controller algorithms */ | ||
218 | #define I2C_HW_ACPI_EC 0x1f0000 | ||
219 | |||
220 | /* --- MPC824x PowerPC adapters */ | ||
221 | #define I2C_HW_MPC824X 0x100001 /* Motorola 8240 / 8245 */ | ||
222 | |||
223 | /* --- MPC8xx PowerPC adapters */ | ||
224 | #define I2C_HW_MPC8XX_EPON 0x110000 /* Eponymous MPC8xx I2C adapter */ | ||
225 | |||
226 | /* --- PowerPC on-chip adapters */ | 171 | /* --- PowerPC on-chip adapters */ |
227 | #define I2C_HW_OCP 0x120000 /* IBM on-chip I2C adapter */ | 172 | #define I2C_HW_OCP 0x120000 /* IBM on-chip I2C adapter */ |
228 | 173 | ||
@@ -231,7 +176,6 @@ | |||
231 | 176 | ||
232 | /* --- SGI adapters */ | 177 | /* --- SGI adapters */ |
233 | #define I2C_HW_SGI_VINO 0x160000 | 178 | #define I2C_HW_SGI_VINO 0x160000 |
234 | #define I2C_HW_SGI_MACE 0x160001 | ||
235 | 179 | ||
236 | /* --- XSCALE on-chip adapters */ | 180 | /* --- XSCALE on-chip adapters */ |
237 | #define I2C_HW_IOP3XX 0x140000 | 181 | #define I2C_HW_IOP3XX 0x140000 |
@@ -255,17 +199,10 @@ | |||
255 | #define I2C_HW_SMBUS_W9968CF 0x04000d | 199 | #define I2C_HW_SMBUS_W9968CF 0x04000d |
256 | #define I2C_HW_SMBUS_OV511 0x04000e /* OV511(+) USB 1.1 webcam ICs */ | 200 | #define I2C_HW_SMBUS_OV511 0x04000e /* OV511(+) USB 1.1 webcam ICs */ |
257 | #define I2C_HW_SMBUS_OV518 0x04000f /* OV518(+) USB 1.1 webcam ICs */ | 201 | #define I2C_HW_SMBUS_OV518 0x04000f /* OV518(+) USB 1.1 webcam ICs */ |
258 | #define I2C_HW_SMBUS_OV519 0x040010 /* OV519 USB 1.1 webcam IC */ | ||
259 | #define I2C_HW_SMBUS_OVFX2 0x040011 /* Cypress/OmniVision FX2 webcam */ | 202 | #define I2C_HW_SMBUS_OVFX2 0x040011 /* Cypress/OmniVision FX2 webcam */ |
260 | #define I2C_HW_SMBUS_CAFE 0x040012 /* Marvell 88ALP01 "CAFE" cam */ | 203 | #define I2C_HW_SMBUS_CAFE 0x040012 /* Marvell 88ALP01 "CAFE" cam */ |
261 | #define I2C_HW_SMBUS_ALI1563 0x040013 | 204 | #define I2C_HW_SMBUS_ALI1563 0x040013 |
262 | 205 | ||
263 | /* --- ISA pseudo-adapter */ | ||
264 | #define I2C_HW_ISA 0x050000 | ||
265 | |||
266 | /* --- IPMB adapter */ | ||
267 | #define I2C_HW_IPMB 0x0c0000 | ||
268 | |||
269 | /* --- MCP107 adapter */ | 206 | /* --- MCP107 adapter */ |
270 | #define I2C_HW_MPC107 0x0d0000 | 207 | #define I2C_HW_MPC107 0x0d0000 |
271 | 208 | ||
diff --git a/include/linux/i2c.h b/include/linux/i2c.h index a100c9f8eb7c..76014f8f3c60 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h | |||
@@ -140,7 +140,6 @@ struct i2c_driver { | |||
140 | int (*command)(struct i2c_client *client,unsigned int cmd, void *arg); | 140 | int (*command)(struct i2c_client *client,unsigned int cmd, void *arg); |
141 | 141 | ||
142 | struct device_driver driver; | 142 | struct device_driver driver; |
143 | struct list_head list; | ||
144 | }; | 143 | }; |
145 | #define to_i2c_driver(d) container_of(d, struct i2c_driver, driver) | 144 | #define to_i2c_driver(d) container_of(d, struct i2c_driver, driver) |
146 | 145 | ||
@@ -155,12 +154,11 @@ struct i2c_driver { | |||
155 | * generic enough to hide second-sourcing and compatible revisions. | 154 | * generic enough to hide second-sourcing and compatible revisions. |
156 | * @adapter: manages the bus segment hosting this I2C device | 155 | * @adapter: manages the bus segment hosting this I2C device |
157 | * @driver: device's driver, hence pointer to access routines | 156 | * @driver: device's driver, hence pointer to access routines |
158 | * @usage_count: counts current number of users of this client | ||
159 | * @dev: Driver model device node for the slave. | 157 | * @dev: Driver model device node for the slave. |
160 | * @irq: indicates the IRQ generated by this device (if any) | 158 | * @irq: indicates the IRQ generated by this device (if any) |
161 | * @driver_name: Identifies new-style driver used with this device; also | 159 | * @driver_name: Identifies new-style driver used with this device; also |
162 | * used as the module name for hotplug/coldplug modprobe support. | 160 | * used as the module name for hotplug/coldplug modprobe support. |
163 | * @list: list of active/busy clients | 161 | * @list: list of active/busy clients (DEPRECATED) |
164 | * @released: used to synchronize client releases & detaches and references | 162 | * @released: used to synchronize client releases & detaches and references |
165 | * | 163 | * |
166 | * An i2c_client identifies a single device (i.e. chip) connected to an | 164 | * An i2c_client identifies a single device (i.e. chip) connected to an |
@@ -175,16 +173,16 @@ struct i2c_client { | |||
175 | char name[I2C_NAME_SIZE]; | 173 | char name[I2C_NAME_SIZE]; |
176 | struct i2c_adapter *adapter; /* the adapter we sit on */ | 174 | struct i2c_adapter *adapter; /* the adapter we sit on */ |
177 | struct i2c_driver *driver; /* and our access routines */ | 175 | struct i2c_driver *driver; /* and our access routines */ |
178 | int usage_count; /* How many accesses currently */ | ||
179 | /* to the client */ | ||
180 | struct device dev; /* the device structure */ | 176 | struct device dev; /* the device structure */ |
181 | int irq; /* irq issued by device (or -1) */ | 177 | int irq; /* irq issued by device (or -1) */ |
182 | char driver_name[KOBJ_NAME_LEN]; | 178 | char driver_name[KOBJ_NAME_LEN]; |
183 | struct list_head list; | 179 | struct list_head list; /* DEPRECATED */ |
184 | struct completion released; | 180 | struct completion released; |
185 | }; | 181 | }; |
186 | #define to_i2c_client(d) container_of(d, struct i2c_client, dev) | 182 | #define to_i2c_client(d) container_of(d, struct i2c_client, dev) |
187 | 183 | ||
184 | extern struct i2c_client *i2c_verify_client(struct device *dev); | ||
185 | |||
188 | static inline struct i2c_client *kobj_to_i2c_client(struct kobject *kobj) | 186 | static inline struct i2c_client *kobj_to_i2c_client(struct kobject *kobj) |
189 | { | 187 | { |
190 | struct device * const dev = container_of(kobj, struct device, kobj); | 188 | struct device * const dev = container_of(kobj, struct device, kobj); |
@@ -261,6 +259,12 @@ i2c_new_probed_device(struct i2c_adapter *adap, | |||
261 | struct i2c_board_info *info, | 259 | struct i2c_board_info *info, |
262 | unsigned short const *addr_list); | 260 | unsigned short const *addr_list); |
263 | 261 | ||
262 | /* For devices that use several addresses, use i2c_new_dummy() to make | ||
263 | * client handles for the extra addresses. | ||
264 | */ | ||
265 | extern struct i2c_client * | ||
266 | i2c_new_dummy(struct i2c_adapter *adap, u16 address, const char *type); | ||
267 | |||
264 | extern void i2c_unregister_device(struct i2c_client *); | 268 | extern void i2c_unregister_device(struct i2c_client *); |
265 | 269 | ||
266 | /* Mainboard arch_initcall() code should register all its I2C devices. | 270 | /* Mainboard arch_initcall() code should register all its I2C devices. |
@@ -319,8 +323,7 @@ struct i2c_adapter { | |||
319 | struct device dev; /* the adapter device */ | 323 | struct device dev; /* the adapter device */ |
320 | 324 | ||
321 | int nr; | 325 | int nr; |
322 | struct list_head clients; | 326 | struct list_head clients; /* DEPRECATED */ |
323 | struct list_head list; | ||
324 | char name[48]; | 327 | char name[48]; |
325 | struct completion dev_released; | 328 | struct completion dev_released; |
326 | }; | 329 | }; |
@@ -357,10 +360,10 @@ static inline void i2c_set_adapdata (struct i2c_adapter *dev, void *data) | |||
357 | * command line | 360 | * command line |
358 | */ | 361 | */ |
359 | struct i2c_client_address_data { | 362 | struct i2c_client_address_data { |
360 | unsigned short *normal_i2c; | 363 | const unsigned short *normal_i2c; |
361 | unsigned short *probe; | 364 | const unsigned short *probe; |
362 | unsigned short *ignore; | 365 | const unsigned short *ignore; |
363 | unsigned short **forces; | 366 | const unsigned short * const *forces; |
364 | }; | 367 | }; |
365 | 368 | ||
366 | /* Internal numbers to terminate lists */ | 369 | /* Internal numbers to terminate lists */ |
@@ -389,11 +392,8 @@ static inline int i2c_add_driver(struct i2c_driver *driver) | |||
389 | extern int i2c_attach_client(struct i2c_client *); | 392 | extern int i2c_attach_client(struct i2c_client *); |
390 | extern int i2c_detach_client(struct i2c_client *); | 393 | extern int i2c_detach_client(struct i2c_client *); |
391 | 394 | ||
392 | /* Should be used to make sure that client-struct is valid and that it | 395 | extern struct i2c_client *i2c_use_client(struct i2c_client *client); |
393 | is okay to access the i2c-client. | 396 | extern void i2c_release_client(struct i2c_client *client); |
394 | returns -ENODEV if client has gone in the meantime */ | ||
395 | extern int i2c_use_client(struct i2c_client *); | ||
396 | extern int i2c_release_client(struct i2c_client *); | ||
397 | 397 | ||
398 | /* call the i2c_client->command() of all attached clients with | 398 | /* call the i2c_client->command() of all attached clients with |
399 | * the given arguments */ | 399 | * the given arguments */ |
@@ -405,7 +405,7 @@ extern void i2c_clients_command(struct i2c_adapter *adap, | |||
405 | * specific address (unless a 'force' matched); | 405 | * specific address (unless a 'force' matched); |
406 | */ | 406 | */ |
407 | extern int i2c_probe(struct i2c_adapter *adapter, | 407 | extern int i2c_probe(struct i2c_adapter *adapter, |
408 | struct i2c_client_address_data *address_data, | 408 | const struct i2c_client_address_data *address_data, |
409 | int (*found_proc) (struct i2c_adapter *, int, int)); | 409 | int (*found_proc) (struct i2c_adapter *, int, int)); |
410 | 410 | ||
411 | extern struct i2c_adapter* i2c_get_adapter(int id); | 411 | extern struct i2c_adapter* i2c_get_adapter(int id); |
@@ -598,104 +598,93 @@ I2C_CLIENT_MODULE_PARM(probe, "List of adapter,address pairs to scan " \ | |||
598 | "additionally"); \ | 598 | "additionally"); \ |
599 | I2C_CLIENT_MODULE_PARM(ignore, "List of adapter,address pairs not to " \ | 599 | I2C_CLIENT_MODULE_PARM(ignore, "List of adapter,address pairs not to " \ |
600 | "scan"); \ | 600 | "scan"); \ |
601 | static struct i2c_client_address_data addr_data = { \ | 601 | const static struct i2c_client_address_data addr_data = { \ |
602 | .normal_i2c = normal_i2c, \ | 602 | .normal_i2c = normal_i2c, \ |
603 | .probe = probe, \ | 603 | .probe = probe, \ |
604 | .ignore = ignore, \ | 604 | .ignore = ignore, \ |
605 | .forces = forces, \ | 605 | .forces = forces, \ |
606 | } | 606 | } |
607 | 607 | ||
608 | #define I2C_CLIENT_FORCE_TEXT \ | ||
609 | "List of adapter,address pairs to boldly assume to be present" | ||
610 | |||
608 | /* These are the ones you want to use in your own drivers. Pick the one | 611 | /* These are the ones you want to use in your own drivers. Pick the one |
609 | which matches the number of devices the driver differenciates between. */ | 612 | which matches the number of devices the driver differenciates between. */ |
610 | #define I2C_CLIENT_INSMOD \ | 613 | #define I2C_CLIENT_INSMOD \ |
611 | I2C_CLIENT_MODULE_PARM(force, \ | 614 | I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ |
612 | "List of adapter,address pairs to boldly assume " \ | 615 | static const unsigned short * const forces[] = { force, NULL }; \ |
613 | "to be present"); \ | ||
614 | static unsigned short *forces[] = { \ | ||
615 | force, \ | ||
616 | NULL \ | ||
617 | }; \ | ||
618 | I2C_CLIENT_INSMOD_COMMON | 616 | I2C_CLIENT_INSMOD_COMMON |
619 | 617 | ||
620 | #define I2C_CLIENT_INSMOD_1(chip1) \ | 618 | #define I2C_CLIENT_INSMOD_1(chip1) \ |
621 | enum chips { any_chip, chip1 }; \ | 619 | enum chips { any_chip, chip1 }; \ |
622 | I2C_CLIENT_MODULE_PARM(force, "List of adapter,address pairs to " \ | 620 | I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ |
623 | "boldly assume to be present"); \ | ||
624 | I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ | 621 | I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ |
625 | static unsigned short *forces[] = { force, force_##chip1, NULL }; \ | 622 | static const unsigned short * const forces[] = { force, \ |
623 | force_##chip1, NULL }; \ | ||
626 | I2C_CLIENT_INSMOD_COMMON | 624 | I2C_CLIENT_INSMOD_COMMON |
627 | 625 | ||
628 | #define I2C_CLIENT_INSMOD_2(chip1, chip2) \ | 626 | #define I2C_CLIENT_INSMOD_2(chip1, chip2) \ |
629 | enum chips { any_chip, chip1, chip2 }; \ | 627 | enum chips { any_chip, chip1, chip2 }; \ |
630 | I2C_CLIENT_MODULE_PARM(force, "List of adapter,address pairs to " \ | 628 | I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ |
631 | "boldly assume to be present"); \ | ||
632 | I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ | 629 | I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ |
633 | I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ | 630 | I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ |
634 | static unsigned short *forces[] = { force, force_##chip1, \ | 631 | static const unsigned short * const forces[] = { force, \ |
635 | force_##chip2, NULL }; \ | 632 | force_##chip1, force_##chip2, NULL }; \ |
636 | I2C_CLIENT_INSMOD_COMMON | 633 | I2C_CLIENT_INSMOD_COMMON |
637 | 634 | ||
638 | #define I2C_CLIENT_INSMOD_3(chip1, chip2, chip3) \ | 635 | #define I2C_CLIENT_INSMOD_3(chip1, chip2, chip3) \ |
639 | enum chips { any_chip, chip1, chip2, chip3 }; \ | 636 | enum chips { any_chip, chip1, chip2, chip3 }; \ |
640 | I2C_CLIENT_MODULE_PARM(force, "List of adapter,address pairs to " \ | 637 | I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ |
641 | "boldly assume to be present"); \ | ||
642 | I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ | 638 | I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ |
643 | I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ | 639 | I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ |
644 | I2C_CLIENT_MODULE_PARM_FORCE(chip3); \ | 640 | I2C_CLIENT_MODULE_PARM_FORCE(chip3); \ |
645 | static unsigned short *forces[] = { force, force_##chip1, \ | 641 | static const unsigned short * const forces[] = { force, \ |
646 | force_##chip2, force_##chip3, \ | 642 | force_##chip1, force_##chip2, force_##chip3, NULL }; \ |
647 | NULL }; \ | ||
648 | I2C_CLIENT_INSMOD_COMMON | 643 | I2C_CLIENT_INSMOD_COMMON |
649 | 644 | ||
650 | #define I2C_CLIENT_INSMOD_4(chip1, chip2, chip3, chip4) \ | 645 | #define I2C_CLIENT_INSMOD_4(chip1, chip2, chip3, chip4) \ |
651 | enum chips { any_chip, chip1, chip2, chip3, chip4 }; \ | 646 | enum chips { any_chip, chip1, chip2, chip3, chip4 }; \ |
652 | I2C_CLIENT_MODULE_PARM(force, "List of adapter,address pairs to " \ | 647 | I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ |
653 | "boldly assume to be present"); \ | ||
654 | I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ | 648 | I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ |
655 | I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ | 649 | I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ |
656 | I2C_CLIENT_MODULE_PARM_FORCE(chip3); \ | 650 | I2C_CLIENT_MODULE_PARM_FORCE(chip3); \ |
657 | I2C_CLIENT_MODULE_PARM_FORCE(chip4); \ | 651 | I2C_CLIENT_MODULE_PARM_FORCE(chip4); \ |
658 | static unsigned short *forces[] = { force, force_##chip1, \ | 652 | static const unsigned short * const forces[] = { force, \ |
659 | force_##chip2, force_##chip3, \ | 653 | force_##chip1, force_##chip2, force_##chip3, \ |
660 | force_##chip4, NULL}; \ | 654 | force_##chip4, NULL}; \ |
661 | I2C_CLIENT_INSMOD_COMMON | 655 | I2C_CLIENT_INSMOD_COMMON |
662 | 656 | ||
663 | #define I2C_CLIENT_INSMOD_5(chip1, chip2, chip3, chip4, chip5) \ | 657 | #define I2C_CLIENT_INSMOD_5(chip1, chip2, chip3, chip4, chip5) \ |
664 | enum chips { any_chip, chip1, chip2, chip3, chip4, chip5 }; \ | 658 | enum chips { any_chip, chip1, chip2, chip3, chip4, chip5 }; \ |
665 | I2C_CLIENT_MODULE_PARM(force, "List of adapter,address pairs to " \ | 659 | I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ |
666 | "boldly assume to be present"); \ | ||
667 | I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ | 660 | I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ |
668 | I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ | 661 | I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ |
669 | I2C_CLIENT_MODULE_PARM_FORCE(chip3); \ | 662 | I2C_CLIENT_MODULE_PARM_FORCE(chip3); \ |
670 | I2C_CLIENT_MODULE_PARM_FORCE(chip4); \ | 663 | I2C_CLIENT_MODULE_PARM_FORCE(chip4); \ |
671 | I2C_CLIENT_MODULE_PARM_FORCE(chip5); \ | 664 | I2C_CLIENT_MODULE_PARM_FORCE(chip5); \ |
672 | static unsigned short *forces[] = { force, force_##chip1, \ | 665 | static const unsigned short * const forces[] = { force, \ |
673 | force_##chip2, force_##chip3, \ | 666 | force_##chip1, force_##chip2, force_##chip3, \ |
674 | force_##chip4, force_##chip5, \ | 667 | force_##chip4, force_##chip5, NULL }; \ |
675 | NULL }; \ | ||
676 | I2C_CLIENT_INSMOD_COMMON | 668 | I2C_CLIENT_INSMOD_COMMON |
677 | 669 | ||
678 | #define I2C_CLIENT_INSMOD_6(chip1, chip2, chip3, chip4, chip5, chip6) \ | 670 | #define I2C_CLIENT_INSMOD_6(chip1, chip2, chip3, chip4, chip5, chip6) \ |
679 | enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6 }; \ | 671 | enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6 }; \ |
680 | I2C_CLIENT_MODULE_PARM(force, "List of adapter,address pairs to " \ | 672 | I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ |
681 | "boldly assume to be present"); \ | ||
682 | I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ | 673 | I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ |
683 | I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ | 674 | I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ |
684 | I2C_CLIENT_MODULE_PARM_FORCE(chip3); \ | 675 | I2C_CLIENT_MODULE_PARM_FORCE(chip3); \ |
685 | I2C_CLIENT_MODULE_PARM_FORCE(chip4); \ | 676 | I2C_CLIENT_MODULE_PARM_FORCE(chip4); \ |
686 | I2C_CLIENT_MODULE_PARM_FORCE(chip5); \ | 677 | I2C_CLIENT_MODULE_PARM_FORCE(chip5); \ |
687 | I2C_CLIENT_MODULE_PARM_FORCE(chip6); \ | 678 | I2C_CLIENT_MODULE_PARM_FORCE(chip6); \ |
688 | static unsigned short *forces[] = { force, force_##chip1, \ | 679 | static const unsigned short * const forces[] = { force, \ |
689 | force_##chip2, force_##chip3, \ | 680 | force_##chip1, force_##chip2, force_##chip3, \ |
690 | force_##chip4, force_##chip5, \ | 681 | force_##chip4, force_##chip5, force_##chip6, NULL }; \ |
691 | force_##chip6, NULL }; \ | ||
692 | I2C_CLIENT_INSMOD_COMMON | 682 | I2C_CLIENT_INSMOD_COMMON |
693 | 683 | ||
694 | #define I2C_CLIENT_INSMOD_7(chip1, chip2, chip3, chip4, chip5, chip6, chip7) \ | 684 | #define I2C_CLIENT_INSMOD_7(chip1, chip2, chip3, chip4, chip5, chip6, chip7) \ |
695 | enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6, \ | 685 | enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6, \ |
696 | chip7 }; \ | 686 | chip7 }; \ |
697 | I2C_CLIENT_MODULE_PARM(force, "List of adapter,address pairs to " \ | 687 | I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ |
698 | "boldly assume to be present"); \ | ||
699 | I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ | 688 | I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ |
700 | I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ | 689 | I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ |
701 | I2C_CLIENT_MODULE_PARM_FORCE(chip3); \ | 690 | I2C_CLIENT_MODULE_PARM_FORCE(chip3); \ |
@@ -703,18 +692,16 @@ I2C_CLIENT_MODULE_PARM_FORCE(chip4); \ | |||
703 | I2C_CLIENT_MODULE_PARM_FORCE(chip5); \ | 692 | I2C_CLIENT_MODULE_PARM_FORCE(chip5); \ |
704 | I2C_CLIENT_MODULE_PARM_FORCE(chip6); \ | 693 | I2C_CLIENT_MODULE_PARM_FORCE(chip6); \ |
705 | I2C_CLIENT_MODULE_PARM_FORCE(chip7); \ | 694 | I2C_CLIENT_MODULE_PARM_FORCE(chip7); \ |
706 | static unsigned short *forces[] = { force, force_##chip1, \ | 695 | static const unsigned short * const forces[] = { force, \ |
707 | force_##chip2, force_##chip3, \ | 696 | force_##chip1, force_##chip2, force_##chip3, \ |
708 | force_##chip4, force_##chip5, \ | 697 | force_##chip4, force_##chip5, force_##chip6, \ |
709 | force_##chip6, force_##chip7, \ | 698 | force_##chip7, NULL }; \ |
710 | NULL }; \ | ||
711 | I2C_CLIENT_INSMOD_COMMON | 699 | I2C_CLIENT_INSMOD_COMMON |
712 | 700 | ||
713 | #define I2C_CLIENT_INSMOD_8(chip1, chip2, chip3, chip4, chip5, chip6, chip7, chip8) \ | 701 | #define I2C_CLIENT_INSMOD_8(chip1, chip2, chip3, chip4, chip5, chip6, chip7, chip8) \ |
714 | enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6, \ | 702 | enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6, \ |
715 | chip7, chip8 }; \ | 703 | chip7, chip8 }; \ |
716 | I2C_CLIENT_MODULE_PARM(force, "List of adapter,address pairs to " \ | 704 | I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ |
717 | "boldly assume to be present"); \ | ||
718 | I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ | 705 | I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ |
719 | I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ | 706 | I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ |
720 | I2C_CLIENT_MODULE_PARM_FORCE(chip3); \ | 707 | I2C_CLIENT_MODULE_PARM_FORCE(chip3); \ |
@@ -723,11 +710,10 @@ I2C_CLIENT_MODULE_PARM_FORCE(chip5); \ | |||
723 | I2C_CLIENT_MODULE_PARM_FORCE(chip6); \ | 710 | I2C_CLIENT_MODULE_PARM_FORCE(chip6); \ |
724 | I2C_CLIENT_MODULE_PARM_FORCE(chip7); \ | 711 | I2C_CLIENT_MODULE_PARM_FORCE(chip7); \ |
725 | I2C_CLIENT_MODULE_PARM_FORCE(chip8); \ | 712 | I2C_CLIENT_MODULE_PARM_FORCE(chip8); \ |
726 | static unsigned short *forces[] = { force, force_##chip1, \ | 713 | static const unsigned short * const forces[] = { force, \ |
727 | force_##chip2, force_##chip3, \ | 714 | force_##chip1, force_##chip2, force_##chip3, \ |
728 | force_##chip4, force_##chip5, \ | 715 | force_##chip4, force_##chip5, force_##chip6, \ |
729 | force_##chip6, force_##chip7, \ | 716 | force_##chip7, force_##chip8, NULL }; \ |
730 | force_##chip8, NULL }; \ | ||
731 | I2C_CLIENT_INSMOD_COMMON | 717 | I2C_CLIENT_INSMOD_COMMON |
732 | #endif /* __KERNEL__ */ | 718 | #endif /* __KERNEL__ */ |
733 | #endif /* _LINUX_I2C_H */ | 719 | #endif /* _LINUX_I2C_H */ |
diff --git a/include/asm-arm/arch-omap/tps65010.h b/include/linux/i2c/tps65010.h index b9aa2b3a3909..7021635ed6a0 100644 --- a/include/asm-arm/arch-omap/tps65010.h +++ b/include/linux/i2c/tps65010.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* linux/include/asm-arm/arch-omap/tps65010.h | 1 | /* linux/i2c/tps65010.h |
2 | * | 2 | * |
3 | * Functions to access TPS65010 power management device. | 3 | * Functions to access TPS65010 power management device. |
4 | * | 4 | * |
@@ -25,8 +25,8 @@ | |||
25 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 25 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | #ifndef __ASM_ARCH_TPS65010_H | 28 | #ifndef __LINUX_I2C_TPS65010_H |
29 | #define __ASM_ARCH_TPS65010_H | 29 | #define __LINUX_I2C_TPS65010_H |
30 | 30 | ||
31 | /* | 31 | /* |
32 | * ---------------------------------------------------------------------------- | 32 | * ---------------------------------------------------------------------------- |
@@ -152,5 +152,5 @@ extern int tps65010_config_vregs1(unsigned value); | |||
152 | */ | 152 | */ |
153 | extern int tps65013_set_low_pwr(unsigned mode); | 153 | extern int tps65013_set_low_pwr(unsigned mode); |
154 | 154 | ||
155 | #endif /* __ASM_ARCH_TPS65010_H */ | 155 | #endif /* __LINUX_I2C_TPS65010_H */ |
156 | 156 | ||
diff --git a/include/linux/ide.h b/include/linux/ide.h index 1e4409937ec3..27cb39de2ae2 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
@@ -107,7 +107,6 @@ typedef unsigned char byte; /* used everywhere */ | |||
107 | #define BAD_W_STAT (BAD_R_STAT | WRERR_STAT) | 107 | #define BAD_W_STAT (BAD_R_STAT | WRERR_STAT) |
108 | #define BAD_STAT (BAD_R_STAT | DRQ_STAT) | 108 | #define BAD_STAT (BAD_R_STAT | DRQ_STAT) |
109 | #define DRIVE_READY (READY_STAT | SEEK_STAT) | 109 | #define DRIVE_READY (READY_STAT | SEEK_STAT) |
110 | #define DATA_READY (DRQ_STAT) | ||
111 | 110 | ||
112 | #define BAD_CRC (ABRT_ERR | ICRC_ERR) | 111 | #define BAD_CRC (ABRT_ERR | ICRC_ERR) |
113 | 112 | ||
@@ -198,8 +197,11 @@ typedef struct hw_regs_s { | |||
198 | } hw_regs_t; | 197 | } hw_regs_t; |
199 | 198 | ||
200 | struct hwif_s * ide_find_port(unsigned long); | 199 | struct hwif_s * ide_find_port(unsigned long); |
200 | void ide_init_port_data(struct hwif_s *, unsigned int); | ||
201 | void ide_init_port_hw(struct hwif_s *, hw_regs_t *); | ||
201 | 202 | ||
202 | int ide_register_hw(hw_regs_t *, void (*)(struct hwif_s *), int, | 203 | struct ide_drive_s; |
204 | int ide_register_hw(hw_regs_t *, void (*)(struct ide_drive_s *), | ||
203 | struct hwif_s **); | 205 | struct hwif_s **); |
204 | 206 | ||
205 | void ide_setup_ports( hw_regs_t *hw, | 207 | void ide_setup_ports( hw_regs_t *hw, |
@@ -391,7 +393,6 @@ typedef struct ide_drive_s { | |||
391 | u8 state; /* retry state */ | 393 | u8 state; /* retry state */ |
392 | u8 waiting_for_dma; /* dma currently in progress */ | 394 | u8 waiting_for_dma; /* dma currently in progress */ |
393 | u8 unmask; /* okay to unmask other irqs */ | 395 | u8 unmask; /* okay to unmask other irqs */ |
394 | u8 bswap; /* byte swap data */ | ||
395 | u8 noflush; /* don't attempt flushes */ | 396 | u8 noflush; /* don't attempt flushes */ |
396 | u8 dsc_overlap; /* DSC overlap */ | 397 | u8 dsc_overlap; /* DSC overlap */ |
397 | u8 nice1; /* give potential excess bandwidth */ | 398 | u8 nice1; /* give potential excess bandwidth */ |
@@ -527,31 +528,26 @@ typedef struct hwif_s { | |||
527 | /* special host masking for drive selection */ | 528 | /* special host masking for drive selection */ |
528 | void (*maskproc)(ide_drive_t *, int); | 529 | void (*maskproc)(ide_drive_t *, int); |
529 | /* check host's drive quirk list */ | 530 | /* check host's drive quirk list */ |
530 | int (*quirkproc)(ide_drive_t *); | 531 | void (*quirkproc)(ide_drive_t *); |
531 | /* driver soft-power interface */ | 532 | /* driver soft-power interface */ |
532 | int (*busproc)(ide_drive_t *, int); | 533 | int (*busproc)(ide_drive_t *, int); |
533 | #endif | 534 | #endif |
534 | u8 (*mdma_filter)(ide_drive_t *); | 535 | u8 (*mdma_filter)(ide_drive_t *); |
535 | u8 (*udma_filter)(ide_drive_t *); | 536 | u8 (*udma_filter)(ide_drive_t *); |
536 | 537 | ||
537 | void (*fixup)(struct hwif_s *); | ||
538 | |||
539 | void (*ata_input_data)(ide_drive_t *, void *, u32); | 538 | void (*ata_input_data)(ide_drive_t *, void *, u32); |
540 | void (*ata_output_data)(ide_drive_t *, void *, u32); | 539 | void (*ata_output_data)(ide_drive_t *, void *, u32); |
541 | 540 | ||
542 | void (*atapi_input_bytes)(ide_drive_t *, void *, u32); | 541 | void (*atapi_input_bytes)(ide_drive_t *, void *, u32); |
543 | void (*atapi_output_bytes)(ide_drive_t *, void *, u32); | 542 | void (*atapi_output_bytes)(ide_drive_t *, void *, u32); |
544 | 543 | ||
544 | void (*dma_host_set)(ide_drive_t *, int); | ||
545 | int (*dma_setup)(ide_drive_t *); | 545 | int (*dma_setup)(ide_drive_t *); |
546 | void (*dma_exec_cmd)(ide_drive_t *, u8); | 546 | void (*dma_exec_cmd)(ide_drive_t *, u8); |
547 | void (*dma_start)(ide_drive_t *); | 547 | void (*dma_start)(ide_drive_t *); |
548 | int (*ide_dma_end)(ide_drive_t *drive); | 548 | int (*ide_dma_end)(ide_drive_t *drive); |
549 | int (*ide_dma_on)(ide_drive_t *drive); | ||
550 | void (*dma_off_quietly)(ide_drive_t *drive); | ||
551 | int (*ide_dma_test_irq)(ide_drive_t *drive); | 549 | int (*ide_dma_test_irq)(ide_drive_t *drive); |
552 | void (*ide_dma_clear_irq)(ide_drive_t *drive); | 550 | void (*ide_dma_clear_irq)(ide_drive_t *drive); |
553 | void (*dma_host_on)(ide_drive_t *drive); | ||
554 | void (*dma_host_off)(ide_drive_t *drive); | ||
555 | void (*dma_lost_irq)(ide_drive_t *drive); | 551 | void (*dma_lost_irq)(ide_drive_t *drive); |
556 | void (*dma_timeout)(ide_drive_t *drive); | 552 | void (*dma_timeout)(ide_drive_t *drive); |
557 | 553 | ||
@@ -874,14 +870,6 @@ extern int ide_do_drive_cmd(ide_drive_t *, struct request *, ide_action_t); | |||
874 | 870 | ||
875 | extern void ide_end_drive_cmd(ide_drive_t *, u8, u8); | 871 | extern void ide_end_drive_cmd(ide_drive_t *, u8, u8); |
876 | 872 | ||
877 | /* | ||
878 | * Issue ATA command and wait for completion. | ||
879 | * Use for implementing commands in kernel | ||
880 | * | ||
881 | * (ide_drive_t *drive, u8 cmd, u8 nsect, u8 feature, u8 sectors, u8 *buf) | ||
882 | */ | ||
883 | extern int ide_wait_cmd(ide_drive_t *, u8, u8, u8, u8, u8 *); | ||
884 | |||
885 | enum { | 873 | enum { |
886 | IDE_TFLAG_LBA48 = (1 << 0), | 874 | IDE_TFLAG_LBA48 = (1 << 0), |
887 | IDE_TFLAG_NO_SELECT_MASK = (1 << 1), | 875 | IDE_TFLAG_NO_SELECT_MASK = (1 << 1), |
@@ -934,6 +922,14 @@ enum { | |||
934 | IDE_TFLAG_IN_TF = IDE_TFLAG_IN_NSECT | | 922 | IDE_TFLAG_IN_TF = IDE_TFLAG_IN_NSECT | |
935 | IDE_TFLAG_IN_LBA, | 923 | IDE_TFLAG_IN_LBA, |
936 | IDE_TFLAG_IN_DEVICE = (1 << 29), | 924 | IDE_TFLAG_IN_DEVICE = (1 << 29), |
925 | IDE_TFLAG_HOB = IDE_TFLAG_OUT_HOB | | ||
926 | IDE_TFLAG_IN_HOB, | ||
927 | IDE_TFLAG_TF = IDE_TFLAG_OUT_TF | | ||
928 | IDE_TFLAG_IN_TF, | ||
929 | IDE_TFLAG_DEVICE = IDE_TFLAG_OUT_DEVICE | | ||
930 | IDE_TFLAG_IN_DEVICE, | ||
931 | /* force 16-bit I/O operations */ | ||
932 | IDE_TFLAG_IO_16BIT = (1 << 30), | ||
937 | }; | 933 | }; |
938 | 934 | ||
939 | struct ide_taskfile { | 935 | struct ide_taskfile { |
@@ -988,6 +984,10 @@ void ide_pktcmd_tf_load(ide_drive_t *, u32, u16, u8); | |||
988 | 984 | ||
989 | ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *); | 985 | ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *); |
990 | 986 | ||
987 | void task_end_request(ide_drive_t *, struct request *, u8); | ||
988 | |||
989 | u8 wait_drive_not_busy(ide_drive_t *); | ||
990 | |||
991 | int ide_raw_taskfile(ide_drive_t *, ide_task_t *, u8 *, u16); | 991 | int ide_raw_taskfile(ide_drive_t *, ide_task_t *, u8 *, u16); |
992 | int ide_no_data_taskfile(ide_drive_t *, ide_task_t *); | 992 | int ide_no_data_taskfile(ide_drive_t *, ide_task_t *); |
993 | 993 | ||
@@ -1015,10 +1015,9 @@ extern void do_ide_request(struct request_queue *); | |||
1015 | 1015 | ||
1016 | void ide_init_disk(struct gendisk *, ide_drive_t *); | 1016 | void ide_init_disk(struct gendisk *, ide_drive_t *); |
1017 | 1017 | ||
1018 | extern int ideprobe_init(void); | ||
1019 | |||
1020 | #ifdef CONFIG_IDEPCI_PCIBUS_ORDER | 1018 | #ifdef CONFIG_IDEPCI_PCIBUS_ORDER |
1021 | extern void ide_scan_pcibus(int scan_direction) __init; | 1019 | extern int ide_scan_direction; |
1020 | int __init ide_scan_pcibus(void); | ||
1022 | extern int __ide_pci_register_driver(struct pci_driver *driver, struct module *owner, const char *mod_name); | 1021 | extern int __ide_pci_register_driver(struct pci_driver *driver, struct module *owner, const char *mod_name); |
1023 | #define ide_pci_register_driver(d) __ide_pci_register_driver(d, THIS_MODULE, KBUILD_MODNAME) | 1022 | #define ide_pci_register_driver(d) __ide_pci_register_driver(d, THIS_MODULE, KBUILD_MODNAME) |
1024 | #else | 1023 | #else |
@@ -1095,6 +1094,8 @@ enum { | |||
1095 | /* unmask IRQs */ | 1094 | /* unmask IRQs */ |
1096 | IDE_HFLAG_UNMASK_IRQS = (1 << 25), | 1095 | IDE_HFLAG_UNMASK_IRQS = (1 << 25), |
1097 | IDE_HFLAG_ABUSE_SET_DMA_MODE = (1 << 26), | 1096 | IDE_HFLAG_ABUSE_SET_DMA_MODE = (1 << 26), |
1097 | /* host is CY82C693 */ | ||
1098 | IDE_HFLAG_CY82C693 = (1 << 27), | ||
1098 | }; | 1099 | }; |
1099 | 1100 | ||
1100 | #ifdef CONFIG_BLK_DEV_OFFBOARD | 1101 | #ifdef CONFIG_BLK_DEV_OFFBOARD |
@@ -1109,7 +1110,6 @@ struct ide_port_info { | |||
1109 | void (*init_iops)(ide_hwif_t *); | 1110 | void (*init_iops)(ide_hwif_t *); |
1110 | void (*init_hwif)(ide_hwif_t *); | 1111 | void (*init_hwif)(ide_hwif_t *); |
1111 | void (*init_dma)(ide_hwif_t *, unsigned long); | 1112 | void (*init_dma)(ide_hwif_t *, unsigned long); |
1112 | void (*fixup)(ide_hwif_t *); | ||
1113 | ide_pci_enablebit_t enablebits[2]; | 1113 | ide_pci_enablebit_t enablebits[2]; |
1114 | hwif_chipset_t chipset; | 1114 | hwif_chipset_t chipset; |
1115 | u8 extra; | 1115 | u8 extra; |
@@ -1147,7 +1147,9 @@ static inline u8 ide_max_dma_mode(ide_drive_t *drive) | |||
1147 | return ide_find_dma_mode(drive, XFER_UDMA_6); | 1147 | return ide_find_dma_mode(drive, XFER_UDMA_6); |
1148 | } | 1148 | } |
1149 | 1149 | ||
1150 | void ide_dma_off_quietly(ide_drive_t *); | ||
1150 | void ide_dma_off(ide_drive_t *); | 1151 | void ide_dma_off(ide_drive_t *); |
1152 | void ide_dma_on(ide_drive_t *); | ||
1151 | int ide_set_dma(ide_drive_t *); | 1153 | int ide_set_dma(ide_drive_t *); |
1152 | ide_startstop_t ide_dma_intr(ide_drive_t *); | 1154 | ide_startstop_t ide_dma_intr(ide_drive_t *); |
1153 | 1155 | ||
@@ -1158,10 +1160,7 @@ extern void ide_destroy_dmatable(ide_drive_t *); | |||
1158 | extern int ide_release_dma(ide_hwif_t *); | 1160 | extern int ide_release_dma(ide_hwif_t *); |
1159 | extern void ide_setup_dma(ide_hwif_t *, unsigned long, unsigned int); | 1161 | extern void ide_setup_dma(ide_hwif_t *, unsigned long, unsigned int); |
1160 | 1162 | ||
1161 | void ide_dma_host_off(ide_drive_t *); | 1163 | void ide_dma_host_set(ide_drive_t *, int); |
1162 | void ide_dma_off_quietly(ide_drive_t *); | ||
1163 | void ide_dma_host_on(ide_drive_t *); | ||
1164 | extern int __ide_dma_on(ide_drive_t *); | ||
1165 | extern int ide_dma_setup(ide_drive_t *); | 1164 | extern int ide_dma_setup(ide_drive_t *); |
1166 | extern void ide_dma_start(ide_drive_t *); | 1165 | extern void ide_dma_start(ide_drive_t *); |
1167 | extern int __ide_dma_end(ide_drive_t *); | 1166 | extern int __ide_dma_end(ide_drive_t *); |
@@ -1173,7 +1172,9 @@ extern void ide_dma_timeout(ide_drive_t *); | |||
1173 | static inline int ide_id_dma_bug(ide_drive_t *drive) { return 0; } | 1172 | static inline int ide_id_dma_bug(ide_drive_t *drive) { return 0; } |
1174 | static inline u8 ide_find_dma_mode(ide_drive_t *drive, u8 speed) { return 0; } | 1173 | static inline u8 ide_find_dma_mode(ide_drive_t *drive, u8 speed) { return 0; } |
1175 | static inline u8 ide_max_dma_mode(ide_drive_t *drive) { return 0; } | 1174 | static inline u8 ide_max_dma_mode(ide_drive_t *drive) { return 0; } |
1175 | static inline void ide_dma_off_quietly(ide_drive_t *drive) { ; } | ||
1176 | static inline void ide_dma_off(ide_drive_t *drive) { ; } | 1176 | static inline void ide_dma_off(ide_drive_t *drive) { ; } |
1177 | static inline void ide_dma_on(ide_drive_t *drive) { ; } | ||
1177 | static inline void ide_dma_verbose(ide_drive_t *drive) { ; } | 1178 | static inline void ide_dma_verbose(ide_drive_t *drive) { ; } |
1178 | static inline int ide_set_dma(ide_drive_t *drive) { return 1; } | 1179 | static inline int ide_set_dma(ide_drive_t *drive) { return 1; } |
1179 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | 1180 | #endif /* CONFIG_BLK_DEV_IDEDMA */ |
@@ -1203,8 +1204,9 @@ extern void ide_unregister (unsigned int index); | |||
1203 | void ide_register_region(struct gendisk *); | 1204 | void ide_register_region(struct gendisk *); |
1204 | void ide_unregister_region(struct gendisk *); | 1205 | void ide_unregister_region(struct gendisk *); |
1205 | 1206 | ||
1206 | void ide_undecoded_slave(ide_hwif_t *); | 1207 | void ide_undecoded_slave(ide_drive_t *); |
1207 | 1208 | ||
1209 | int ide_device_add_all(u8 *idx); | ||
1208 | int ide_device_add(u8 idx[4]); | 1210 | int ide_device_add(u8 idx[4]); |
1209 | 1211 | ||
1210 | static inline void *ide_get_hwifdata (ide_hwif_t * hwif) | 1212 | static inline void *ide_get_hwifdata (ide_hwif_t * hwif) |
@@ -1302,4 +1304,9 @@ static inline ide_drive_t *ide_get_paired_drive(ide_drive_t *drive) | |||
1302 | return &hwif->drives[(drive->dn ^ 1) & 1]; | 1304 | return &hwif->drives[(drive->dn ^ 1) & 1]; |
1303 | } | 1305 | } |
1304 | 1306 | ||
1307 | static inline void ide_set_irq(ide_drive_t *drive, int on) | ||
1308 | { | ||
1309 | drive->hwif->OUTB(drive->ctl | (on ? 0 : 2), IDE_CONTROL_REG); | ||
1310 | } | ||
1311 | |||
1305 | #endif /* _IDE_H */ | 1312 | #endif /* _IDE_H */ |
diff --git a/include/linux/m41t00.h b/include/linux/m41t00.h deleted file mode 100644 index b423360ca38e..000000000000 --- a/include/linux/m41t00.h +++ /dev/null | |||
@@ -1,50 +0,0 @@ | |||
1 | /* | ||
2 | * Definitions for the ST M41T00 family of i2c rtc chips. | ||
3 | * | ||
4 | * Author: Mark A. Greer <mgreer@mvista.com> | ||
5 | * | ||
6 | * 2005, 2006 (c) MontaVista Software, Inc. This file is licensed under | ||
7 | * the terms of the GNU General Public License version 2. This program | ||
8 | * is licensed "as is" without any warranty of any kind, whether express | ||
9 | * or implied. | ||
10 | */ | ||
11 | |||
12 | #ifndef _M41T00_H | ||
13 | #define _M41T00_H | ||
14 | |||
15 | #define M41T00_DRV_NAME "m41t00" | ||
16 | #define M41T00_I2C_ADDR 0x68 | ||
17 | |||
18 | #define M41T00_TYPE_M41T00 0 | ||
19 | #define M41T00_TYPE_M41T81 81 | ||
20 | #define M41T00_TYPE_M41T85 85 | ||
21 | |||
22 | struct m41t00_platform_data { | ||
23 | u8 type; | ||
24 | u8 i2c_addr; | ||
25 | u8 sqw_freq; | ||
26 | }; | ||
27 | |||
28 | /* SQW output disabled, this is default value by power on */ | ||
29 | #define M41T00_SQW_DISABLE (0) | ||
30 | |||
31 | #define M41T00_SQW_32KHZ (1<<4) /* 32.768 KHz */ | ||
32 | #define M41T00_SQW_8KHZ (2<<4) /* 8.192 KHz */ | ||
33 | #define M41T00_SQW_4KHZ (3<<4) /* 4.096 KHz */ | ||
34 | #define M41T00_SQW_2KHZ (4<<4) /* 2.048 KHz */ | ||
35 | #define M41T00_SQW_1KHZ (5<<4) /* 1.024 KHz */ | ||
36 | #define M41T00_SQW_512HZ (6<<4) /* 512 Hz */ | ||
37 | #define M41T00_SQW_256HZ (7<<4) /* 256 Hz */ | ||
38 | #define M41T00_SQW_128HZ (8<<4) /* 128 Hz */ | ||
39 | #define M41T00_SQW_64HZ (9<<4) /* 64 Hz */ | ||
40 | #define M41T00_SQW_32HZ (10<<4) /* 32 Hz */ | ||
41 | #define M41T00_SQW_16HZ (11<<4) /* 16 Hz */ | ||
42 | #define M41T00_SQW_8HZ (12<<4) /* 8 Hz */ | ||
43 | #define M41T00_SQW_4HZ (13<<4) /* 4 Hz */ | ||
44 | #define M41T00_SQW_2HZ (14<<4) /* 2 Hz */ | ||
45 | #define M41T00_SQW_1HZ (15<<4) /* 1 Hz */ | ||
46 | |||
47 | extern ulong m41t00_get_rtc_time(void); | ||
48 | extern int m41t00_set_rtc_time(ulong nowtime); | ||
49 | |||
50 | #endif /* _M41T00_H */ | ||
diff --git a/include/media/v4l2-i2c-drv-legacy.h b/include/media/v4l2-i2c-drv-legacy.h index 241854229d6f..e7645578fc22 100644 --- a/include/media/v4l2-i2c-drv-legacy.h +++ b/include/media/v4l2-i2c-drv-legacy.h | |||
@@ -34,7 +34,7 @@ struct v4l2_i2c_driver_data { | |||
34 | }; | 34 | }; |
35 | 35 | ||
36 | static struct v4l2_i2c_driver_data v4l2_i2c_data; | 36 | static struct v4l2_i2c_driver_data v4l2_i2c_data; |
37 | static struct i2c_client_address_data addr_data; | 37 | static const struct i2c_client_address_data addr_data; |
38 | static struct i2c_driver v4l2_i2c_driver_legacy; | 38 | static struct i2c_driver v4l2_i2c_driver_legacy; |
39 | static char v4l2_i2c_drv_name_legacy[32]; | 39 | static char v4l2_i2c_drv_name_legacy[32]; |
40 | 40 | ||
diff --git a/kernel/printk.c b/kernel/printk.c index 423a8c765a57..3b7c968d0ef9 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
@@ -702,9 +702,7 @@ asmlinkage int vprintk(const char *fmt, va_list args) | |||
702 | loglev_char = default_message_loglevel | 702 | loglev_char = default_message_loglevel |
703 | + '0'; | 703 | + '0'; |
704 | } | 704 | } |
705 | t = 0; | 705 | t = cpu_clock(printk_cpu); |
706 | if (system_state != SYSTEM_BOOTING) | ||
707 | t = ktime_to_ns(ktime_get()); | ||
708 | nanosec_rem = do_div(t, 1000000000); | 706 | nanosec_rem = do_div(t, 1000000000); |
709 | tlen = sprintf(tbuf, | 707 | tlen = sprintf(tbuf, |
710 | "<%c>[%5lu.%06lu] ", | 708 | "<%c>[%5lu.%06lu] ", |
diff --git a/kernel/sysctl_check.c b/kernel/sysctl_check.c index a68425a5cc1d..d8a5558a47b4 100644 --- a/kernel/sysctl_check.c +++ b/kernel/sysctl_check.c | |||
@@ -1,6 +1,5 @@ | |||
1 | #include <linux/stat.h> | 1 | #include <linux/stat.h> |
2 | #include <linux/sysctl.h> | 2 | #include <linux/sysctl.h> |
3 | #include "../arch/s390/appldata/appldata.h" | ||
4 | #include "../fs/xfs/linux-2.6/xfs_sysctl.h" | 3 | #include "../fs/xfs/linux-2.6/xfs_sysctl.h" |
5 | #include <linux/sunrpc/debug.h> | 4 | #include <linux/sunrpc/debug.h> |
6 | #include <linux/string.h> | 5 | #include <linux/string.h> |
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index f83b19daed16..4bf715d4cf29 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -1744,6 +1744,9 @@ int security_genfs_sid(const char *fstype, | |||
1744 | struct ocontext *c; | 1744 | struct ocontext *c; |
1745 | int rc = 0, cmp = 0; | 1745 | int rc = 0, cmp = 0; |
1746 | 1746 | ||
1747 | while (path[0] == '/' && path[1] == '/') | ||
1748 | path++; | ||
1749 | |||
1747 | POLICY_RDLOCK; | 1750 | POLICY_RDLOCK; |
1748 | 1751 | ||
1749 | for (genfs = policydb.genfs; genfs; genfs = genfs->next) { | 1752 | for (genfs = policydb.genfs; genfs; genfs = genfs->next) { |
diff --git a/sound/oss/waveartist.c b/sound/oss/waveartist.c index b48c72923a13..88490418f932 100644 --- a/sound/oss/waveartist.c +++ b/sound/oss/waveartist.c | |||
@@ -835,7 +835,7 @@ static struct audio_driver waveartist_audio_driver = { | |||
835 | static irqreturn_t | 835 | static irqreturn_t |
836 | waveartist_intr(int irq, void *dev_id) | 836 | waveartist_intr(int irq, void *dev_id) |
837 | { | 837 | { |
838 | wavnc_info *devc = (wavnc_info *)dev_id; | 838 | wavnc_info *devc = dev_id; |
839 | int irqstatus, status; | 839 | int irqstatus, status; |
840 | 840 | ||
841 | spin_lock(&waveartist_lock); | 841 | spin_lock(&waveartist_lock); |
diff --git a/sound/ppc/keywest.c b/sound/ppc/keywest.c index 272ae38e9b18..bb7d744faff5 100644 --- a/sound/ppc/keywest.c +++ b/sound/ppc/keywest.c | |||
@@ -34,8 +34,6 @@ | |||
34 | static struct pmac_keywest *keywest_ctx; | 34 | static struct pmac_keywest *keywest_ctx; |
35 | 35 | ||
36 | 36 | ||
37 | #define I2C_DRIVERID_KEYWEST 0xFEBA | ||
38 | |||
39 | static int keywest_attach_adapter(struct i2c_adapter *adapter); | 37 | static int keywest_attach_adapter(struct i2c_adapter *adapter); |
40 | static int keywest_detach_client(struct i2c_client *client); | 38 | static int keywest_detach_client(struct i2c_client *client); |
41 | 39 | ||
@@ -43,7 +41,6 @@ struct i2c_driver keywest_driver = { | |||
43 | .driver = { | 41 | .driver = { |
44 | .name = "PMac Keywest Audio", | 42 | .name = "PMac Keywest Audio", |
45 | }, | 43 | }, |
46 | .id = I2C_DRIVERID_KEYWEST, | ||
47 | .attach_adapter = &keywest_attach_adapter, | 44 | .attach_adapter = &keywest_attach_adapter, |
48 | .detach_client = &keywest_detach_client, | 45 | .detach_client = &keywest_detach_client, |
49 | }; | 46 | }; |
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index abac62866da8..dab22cc97ead 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c | |||
@@ -234,7 +234,7 @@ static int cs4270_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, | |||
234 | * lower three bits are determined via the AD2, AD1, and AD0 pins | 234 | * lower three bits are determined via the AD2, AD1, and AD0 pins |
235 | * (respectively). | 235 | * (respectively). |
236 | */ | 236 | */ |
237 | static unsigned short normal_i2c[] = { | 237 | static const unsigned short normal_i2c[] = { |
238 | 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, I2C_CLIENT_END | 238 | 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, I2C_CLIENT_END |
239 | }; | 239 | }; |
240 | I2C_CLIENT_INSMOD; | 240 | I2C_CLIENT_INSMOD; |
diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c index d5a8fc2cf8d6..f1f6b9478af9 100644 --- a/sound/soc/s3c24xx/neo1973_wm8753.c +++ b/sound/soc/s3c24xx/neo1973_wm8753.c | |||
@@ -573,7 +573,7 @@ static struct snd_soc_device neo1973_snd_devdata = { | |||
573 | 573 | ||
574 | static struct i2c_client client_template; | 574 | static struct i2c_client client_template; |
575 | 575 | ||
576 | static unsigned short normal_i2c[] = { 0x7C, I2C_CLIENT_END }; | 576 | static const unsigned short normal_i2c[] = { 0x7C, I2C_CLIENT_END }; |
577 | 577 | ||
578 | /* Magic definition of all other variables and things */ | 578 | /* Magic definition of all other variables and things */ |
579 | I2C_CLIENT_INSMOD; | 579 | I2C_CLIENT_INSMOD; |