diff options
310 files changed, 16945 insertions, 3011 deletions
@@ -2212,13 +2212,13 @@ S: 2300 Copenhagen S | |||
2212 | S: Denmark | 2212 | S: Denmark |
2213 | 2213 | ||
2214 | N: Claudio S. Matsuoka | 2214 | N: Claudio S. Matsuoka |
2215 | E: claudio@conectiva.com | 2215 | E: cmatsuoka@gmail.com |
2216 | E: claudio@helllabs.org | 2216 | E: claudio@mandriva.com |
2217 | W: http://helllabs.org/~claudio | 2217 | W: http://helllabs.org/~claudio |
2218 | D: V4L, OV511 driver hacks | 2218 | D: V4L, OV511 and HDA-codec hacks |
2219 | S: Conectiva S.A. | 2219 | S: Conectiva S.A. |
2220 | S: R. Tocantins 89 | 2220 | S: Souza Naves 1250 |
2221 | S: 80050-430 Curitiba PR | 2221 | S: 80050-040 Curitiba PR |
2222 | S: Brazil | 2222 | S: Brazil |
2223 | 2223 | ||
2224 | N: Heinz Mauelshagen | 2224 | N: Heinz Mauelshagen |
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 355ff0a2bb7c..241e26c4ff92 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt | |||
@@ -467,7 +467,12 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
467 | above explicitly. | 467 | above explicitly. |
468 | 468 | ||
469 | The power-management is supported. | 469 | The power-management is supported. |
470 | 470 | ||
471 | Module snd-cs5530 | ||
472 | _________________ | ||
473 | |||
474 | Module for Cyrix/NatSemi Geode 5530 chip. | ||
475 | |||
471 | Module snd-cs5535audio | 476 | Module snd-cs5535audio |
472 | ---------------------- | 477 | ---------------------- |
473 | 478 | ||
@@ -759,6 +764,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
759 | 764 | ||
760 | model - force the model name | 765 | model - force the model name |
761 | position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size) | 766 | position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size) |
767 | probe_mask - Bitmask to probe codecs (default = -1, meaning all slots) | ||
762 | single_cmd - Use single immediate commands to communicate with | 768 | single_cmd - Use single immediate commands to communicate with |
763 | codecs (for debugging only) | 769 | codecs (for debugging only) |
764 | enable_msi - Enable Message Signaled Interrupt (MSI) (default = off) | 770 | enable_msi - Enable Message Signaled Interrupt (MSI) (default = off) |
@@ -803,6 +809,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
803 | hp-3013 HP machines (3013-variant) | 809 | hp-3013 HP machines (3013-variant) |
804 | fujitsu Fujitsu S7020 | 810 | fujitsu Fujitsu S7020 |
805 | acer Acer TravelMate | 811 | acer Acer TravelMate |
812 | will Will laptops (PB V7900) | ||
813 | replacer Replacer 672V | ||
806 | basic fixed pin assignment (old default model) | 814 | basic fixed pin assignment (old default model) |
807 | auto auto-config reading BIOS (default) | 815 | auto auto-config reading BIOS (default) |
808 | 816 | ||
@@ -811,16 +819,31 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
811 | hp-bpc HP xw4400/6400/8400/9400 laptops | 819 | hp-bpc HP xw4400/6400/8400/9400 laptops |
812 | hp-bpc-d7000 HP BPC D7000 | 820 | hp-bpc-d7000 HP BPC D7000 |
813 | benq Benq ED8 | 821 | benq Benq ED8 |
822 | benq-t31 Benq T31 | ||
814 | hippo Hippo (ATI) with jack detection, Sony UX-90s | 823 | hippo Hippo (ATI) with jack detection, Sony UX-90s |
815 | hippo_1 Hippo (Benq) with jack detection | 824 | hippo_1 Hippo (Benq) with jack detection |
825 | sony-assamd Sony ASSAMD | ||
816 | basic fixed pin assignment w/o SPDIF | 826 | basic fixed pin assignment w/o SPDIF |
817 | auto auto-config reading BIOS (default) | 827 | auto auto-config reading BIOS (default) |
818 | 828 | ||
829 | ALC268 | ||
830 | 3stack 3-stack model | ||
831 | auto auto-config reading BIOS (default) | ||
832 | |||
833 | ALC662 | ||
834 | 3stack-dig 3-stack (2-channel) with SPDIF | ||
835 | 3stack-6ch 3-stack (6-channel) | ||
836 | 3stack-6ch-dig 3-stack (6-channel) with SPDIF | ||
837 | 6stack-dig 6-stack with SPDIF | ||
838 | lenovo-101e Lenovo laptop | ||
839 | auto auto-config reading BIOS (default) | ||
840 | |||
819 | ALC882/885 | 841 | ALC882/885 |
820 | 3stack-dig 3-jack with SPDIF I/O | 842 | 3stack-dig 3-jack with SPDIF I/O |
821 | 6stack-dig 6-jack digital with SPDIF I/O | 843 | 6stack-dig 6-jack digital with SPDIF I/O |
822 | arima Arima W820Di1 | 844 | arima Arima W820Di1 |
823 | macpro MacPro support | 845 | macpro MacPro support |
846 | imac24 iMac 24'' with jack detection | ||
824 | w2jc ASUS W2JC | 847 | w2jc ASUS W2JC |
825 | auto auto-config reading BIOS (default) | 848 | auto auto-config reading BIOS (default) |
826 | 849 | ||
@@ -832,9 +855,15 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
832 | 6stack-dig-demo 6-jack digital for Intel demo board | 855 | 6stack-dig-demo 6-jack digital for Intel demo board |
833 | acer Acer laptops (Travelmate 3012WTMi, Aspire 5600, etc) | 856 | acer Acer laptops (Travelmate 3012WTMi, Aspire 5600, etc) |
834 | medion Medion Laptops | 857 | medion Medion Laptops |
858 | medion-md2 Medion MD2 | ||
835 | targa-dig Targa/MSI | 859 | targa-dig Targa/MSI |
836 | targa-2ch-dig Targs/MSI with 2-channel | 860 | targa-2ch-dig Targs/MSI with 2-channel |
837 | laptop-eapd 3-jack with SPDIF I/O and EAPD (Clevo M540JE, M550JE) | 861 | laptop-eapd 3-jack with SPDIF I/O and EAPD (Clevo M540JE, M550JE) |
862 | lenovo-101e Lenovo 101E | ||
863 | lenovo-nb0763 Lenovo NB0763 | ||
864 | lenovo-ms7195-dig Lenovo MS7195 | ||
865 | 6stack-hp HP machines with 6stack (Nettle boards) | ||
866 | 3stack-hp HP machines with 3stack (Lucknow, Samba boards) | ||
838 | auto auto-config reading BIOS (default) | 867 | auto auto-config reading BIOS (default) |
839 | 868 | ||
840 | ALC861/660 | 869 | ALC861/660 |
@@ -853,7 +882,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
853 | 3stack-dig 3-jack with SPDIF OUT | 882 | 3stack-dig 3-jack with SPDIF OUT |
854 | 6stack-dig 6-jack with SPDIF OUT | 883 | 6stack-dig 6-jack with SPDIF OUT |
855 | 3stack-660 3-jack (for ALC660VD) | 884 | 3stack-660 3-jack (for ALC660VD) |
885 | 3stack-660-digout 3-jack with SPDIF OUT (for ALC660VD) | ||
856 | lenovo Lenovo 3000 C200 | 886 | lenovo Lenovo 3000 C200 |
887 | dallas Dallas laptops | ||
857 | auto auto-config reading BIOS (default) | 888 | auto auto-config reading BIOS (default) |
858 | 889 | ||
859 | CMI9880 | 890 | CMI9880 |
@@ -864,12 +895,26 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
864 | allout 5-jack in back, 2-jack in front, SPDIF out | 895 | allout 5-jack in back, 2-jack in front, SPDIF out |
865 | auto auto-config reading BIOS (default) | 896 | auto auto-config reading BIOS (default) |
866 | 897 | ||
898 | AD1882 | ||
899 | 3stack 3-stack mode (default) | ||
900 | 6stack 6-stack mode | ||
901 | |||
902 | AD1884 | ||
903 | N/A | ||
904 | |||
867 | AD1981 | 905 | AD1981 |
868 | basic 3-jack (default) | 906 | basic 3-jack (default) |
869 | hp HP nx6320 | 907 | hp HP nx6320 |
870 | thinkpad Lenovo Thinkpad T60/X60/Z60 | 908 | thinkpad Lenovo Thinkpad T60/X60/Z60 |
871 | toshiba Toshiba U205 | 909 | toshiba Toshiba U205 |
872 | 910 | ||
911 | AD1983 | ||
912 | N/A | ||
913 | |||
914 | AD1984 | ||
915 | basic default configuration | ||
916 | thinkpad Lenovo Thinkpad T61/X61 | ||
917 | |||
873 | AD1986A | 918 | AD1986A |
874 | 6stack 6-jack, separate surrounds (default) | 919 | 6stack 6-jack, separate surrounds (default) |
875 | 3stack 3-stack, shared surrounds | 920 | 3stack 3-stack, shared surrounds |
@@ -907,11 +952,18 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
907 | ref Reference board | 952 | ref Reference board |
908 | 3stack D945 3stack | 953 | 3stack D945 3stack |
909 | 5stack D945 5stack + SPDIF | 954 | 5stack D945 5stack + SPDIF |
910 | macmini Intel Mac Mini | 955 | dell Dell XPS M1210 |
911 | macbook Intel Mac Book | 956 | intel-mac-v1 Intel Mac Type 1 |
912 | macbook-pro-v1 Intel Mac Book Pro 1st generation | 957 | intel-mac-v2 Intel Mac Type 2 |
913 | macbook-pro Intel Mac Book Pro 2nd generation | 958 | intel-mac-v3 Intel Mac Type 3 |
914 | imac-intel Intel iMac | 959 | intel-mac-v4 Intel Mac Type 4 |
960 | intel-mac-v5 Intel Mac Type 5 | ||
961 | macmini Intel Mac Mini (equivalent with type 3) | ||
962 | macbook Intel Mac Book (eq. type 5) | ||
963 | macbook-pro-v1 Intel Mac Book Pro 1st generation (eq. type 3) | ||
964 | macbook-pro Intel Mac Book Pro 2nd generation (eq. type 3) | ||
965 | imac-intel Intel iMac (eq. type 2) | ||
966 | imac-intel-20 Intel iMac (newer version) (eq. type 3) | ||
915 | 967 | ||
916 | STAC9202/9250/9251 | 968 | STAC9202/9250/9251 |
917 | ref Reference board, base config | 969 | ref Reference board, base config |
@@ -956,6 +1008,17 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
956 | from the irq. Remember this is a last resort, and should be | 1008 | from the irq. Remember this is a last resort, and should be |
957 | avoided as much as possible... | 1009 | avoided as much as possible... |
958 | 1010 | ||
1011 | MORE NOTES ON "azx_get_response timeout" PROBLEMS: | ||
1012 | On some hardwares, you may need to add a proper probe_mask option | ||
1013 | to avoid the "azx_get_response timeout" problem above, instead. | ||
1014 | This occurs when the access to non-existing or non-working codec slot | ||
1015 | (likely a modem one) causes a stall of the communication via HD-audio | ||
1016 | bus. You can see which codec slots are probed by enabling | ||
1017 | CONFIG_SND_DEBUG_DETECT, or simply from the file name of the codec | ||
1018 | proc files. Then limit the slots to probe by probe_mask option. | ||
1019 | For example, probe_mask=1 means to probe only the first slot, and | ||
1020 | probe_mask=4 means only the third slot. | ||
1021 | |||
959 | The power-management is supported. | 1022 | The power-management is supported. |
960 | 1023 | ||
961 | Module snd-hdsp | 1024 | Module snd-hdsp |
diff --git a/Documentation/sound/alsa/Audiophile-Usb.txt b/Documentation/sound/alsa/Audiophile-Usb.txt index e40cce83327c..2ad5e6306c44 100644 --- a/Documentation/sound/alsa/Audiophile-Usb.txt +++ b/Documentation/sound/alsa/Audiophile-Usb.txt | |||
@@ -1,4 +1,4 @@ | |||
1 | Guide to using M-Audio Audiophile USB with ALSA and Jack v1.3 | 1 | Guide to using M-Audio Audiophile USB with ALSA and Jack v1.5 |
2 | ======================================================== | 2 | ======================================================== |
3 | 3 | ||
4 | Thibault Le Meur <Thibault.LeMeur@supelec.fr> | 4 | Thibault Le Meur <Thibault.LeMeur@supelec.fr> |
@@ -6,8 +6,19 @@ | |||
6 | This document is a guide to using the M-Audio Audiophile USB (tm) device with | 6 | This document is a guide to using the M-Audio Audiophile USB (tm) device with |
7 | ALSA and JACK. | 7 | ALSA and JACK. |
8 | 8 | ||
9 | History | ||
10 | ======= | ||
11 | * v1.4 - Thibault Le Meur (2007-07-11) | ||
12 | - Added Low Endianness nature of 16bits-modes | ||
13 | found by Hakan Lennestal <Hakan.Lennestal@brfsodrahamn.se> | ||
14 | - Modifying document structure | ||
15 | * v1.5 - Thibault Le Meur (2007-07-12) | ||
16 | - Added AC3/DTS passthru info | ||
17 | |||
18 | |||
9 | 1 - Audiophile USB Specs and correct usage | 19 | 1 - Audiophile USB Specs and correct usage |
10 | ========================================== | 20 | ========================================== |
21 | |||
11 | This part is a reminder of important facts about the functions and limitations | 22 | This part is a reminder of important facts about the functions and limitations |
12 | of the device. | 23 | of the device. |
13 | 24 | ||
@@ -25,18 +36,18 @@ The device has 4 audio interfaces, and 2 MIDI ports: | |||
25 | The internal DAC/ADC has the following characteristics: | 36 | The internal DAC/ADC has the following characteristics: |
26 | * sample depth of 16 or 24 bits | 37 | * sample depth of 16 or 24 bits |
27 | * sample rate from 8kHz to 96kHz | 38 | * sample rate from 8kHz to 96kHz |
28 | * Two ports can't use different sample depths at the same time. Moreover, the | 39 | * Two interfaces can't use different sample depths at the same time. |
29 | Audiophile USB documentation gives the following Warning: "Please exit any | 40 | Moreover, the Audiophile USB documentation gives the following Warning: |
30 | audio application running before switching between bit depths" | 41 | "Please exit any audio application running before switching between bit depths" |
31 | 42 | ||
32 | Due to the USB 1.1 bandwidth limitation, a limited number of interfaces can be | 43 | Due to the USB 1.1 bandwidth limitation, a limited number of interfaces can be |
33 | activated at the same time depending on the audio mode selected: | 44 | activated at the same time depending on the audio mode selected: |
34 | * 16-bit/48kHz ==> 4 channels in/4 channels out | 45 | * 16-bit/48kHz ==> 4 channels in + 4 channels out |
35 | - Ai+Ao+Di+Do | 46 | - Ai+Ao+Di+Do |
36 | * 24-bit/48kHz ==> 4 channels in/2 channels out, | 47 | * 24-bit/48kHz ==> 4 channels in + 2 channels out, |
37 | or 2 channels in/4 channels out | 48 | or 2 channels in + 4 channels out |
38 | - Ai+Ao+Do or Ai+Di+Ao or Ai+Di+Do or Di+Ao+Do | 49 | - Ai+Ao+Do or Ai+Di+Ao or Ai+Di+Do or Di+Ao+Do |
39 | * 24-bit/96kHz ==> 2 channels in, or 2 channels out (half duplex only) | 50 | * 24-bit/96kHz ==> 2 channels in _or_ 2 channels out (half duplex only) |
40 | - Ai or Ao or Di or Do | 51 | - Ai or Ao or Di or Do |
41 | 52 | ||
42 | Important facts about the Digital interface: | 53 | Important facts about the Digital interface: |
@@ -52,44 +63,56 @@ source is connected | |||
52 | synchronization error (for instance sound played at an odd sample rate) | 63 | synchronization error (for instance sound played at an odd sample rate) |
53 | 64 | ||
54 | 65 | ||
55 | 2 - Audiophile USB support in ALSA | 66 | 2 - Audiophile USB MIDI support in ALSA |
56 | ================================== | 67 | ======================================= |
57 | 68 | ||
58 | 2.1 - MIDI ports | 69 | The Audiophile USB MIDI ports will be automatically supported once the |
59 | ---------------- | ||
60 | The Audiophile USB MIDI ports will be automatically supported once the | ||
61 | following modules have been loaded: | 70 | following modules have been loaded: |
62 | * snd-usb-audio | 71 | * snd-usb-audio |
63 | * snd-seq-midi | 72 | * snd-seq-midi |
64 | 73 | ||
65 | No additional setting is required. | 74 | No additional setting is required. |
66 | 75 | ||
67 | 2.2 - Audio ports | 76 | |
68 | ----------------- | 77 | 3 - Audiophile USB Audio support in ALSA |
78 | ======================================== | ||
69 | 79 | ||
70 | Audio functions of the Audiophile USB device are handled by the snd-usb-audio | 80 | Audio functions of the Audiophile USB device are handled by the snd-usb-audio |
71 | module. This module can work in a default mode (without any device-specific | 81 | module. This module can work in a default mode (without any device-specific |
72 | parameter), or in an "advanced" mode with the device-specific parameter called | 82 | parameter), or in an "advanced" mode with the device-specific parameter called |
73 | "device_setup". | 83 | "device_setup". |
74 | 84 | ||
75 | 2.2.1 - Default Alsa driver mode | 85 | 3.1 - Default Alsa driver mode |
76 | 86 | ------------------------------ | |
77 | The default behavior of the snd-usb-audio driver is to parse the device | 87 | |
78 | capabilities at startup and enable all functions inside the device (including | 88 | The default behavior of the snd-usb-audio driver is to list the device |
79 | all ports at any supported sample rates and sample depths). This approach | 89 | capabilities at startup and activate the required mode when required |
80 | has the advantage to let the driver easily switch from sample rates/depths | 90 | by the applications: for instance if the user is recording in a |
81 | automatically according to the need of the application claiming the device. | 91 | 24bit-depth-mode and immediately after wants to switch to a 16bit-depth mode, |
82 | 92 | the snd-usb-audio module will reconfigure the device on the fly. | |
83 | In this case the Audiophile ports are mapped to alsa pcm devices in the | 93 | |
84 | following way (I suppose the device's index is 1): | 94 | This approach has the advantage to let the driver automatically switch from sample |
95 | rates/depths automatically according to the user's needs. However, those who | ||
96 | are using the device under windows know that this is not how the device is meant to | ||
97 | work: under windows applications must be closed before using the m-audio control | ||
98 | panel to switch the device working mode. Thus as we'll see in next section, this | ||
99 | Default Alsa driver mode can lead to device misconfigurations. | ||
100 | |||
101 | Let's get back to the Default Alsa driver mode for now. In this case the | ||
102 | Audiophile interfaces are mapped to alsa pcm devices in the following | ||
103 | way (I suppose the device's index is 1): | ||
85 | * hw:1,0 is Ao in playback and Di in capture | 104 | * hw:1,0 is Ao in playback and Di in capture |
86 | * hw:1,1 is Do in playback and Ai in capture | 105 | * hw:1,1 is Do in playback and Ai in capture |
87 | * hw:1,2 is Do in AC3/DTS passthrough mode | 106 | * hw:1,2 is Do in AC3/DTS passthrough mode |
88 | 107 | ||
89 | You must note as well that the device uses Big Endian byte encoding so that | 108 | In this mode, the device uses Big Endian byte-encoding so that |
90 | supported audio format are S16_BE for 16-bit depth modes and S24_3BE for | 109 | supported audio format are S16_BE for 16-bit depth modes and S24_3BE for |
91 | 24-bits depth mode. One exception is the hw:1,2 port which is Little Endian | 110 | 24-bits depth mode. |
92 | compliant and thus uses S16_LE. | 111 | |
112 | One exception is the hw:1,2 port which was reported to be Little Endian | ||
113 | compliant (supposedly supporting S16_LE) but processes in fact only S16_BE streams. | ||
114 | This has been fixed in kernel 2.6.23 and above and now the hw:1,2 interface | ||
115 | is reported to be big endian in this default driver mode. | ||
93 | 116 | ||
94 | Examples: | 117 | Examples: |
95 | * playing a S24_3BE encoded raw file to the Ao port | 118 | * playing a S24_3BE encoded raw file to the Ao port |
@@ -98,22 +121,26 @@ Examples: | |||
98 | % arecord -D hw:1,1 -c2 -t raw -r48000 -fS24_3BE test.raw | 121 | % arecord -D hw:1,1 -c2 -t raw -r48000 -fS24_3BE test.raw |
99 | * playing a S16_BE encoded raw file to the Do port | 122 | * playing a S16_BE encoded raw file to the Do port |
100 | % aplay -D hw:1,1 -c2 -t raw -r48000 -fS16_BE test.raw | 123 | % aplay -D hw:1,1 -c2 -t raw -r48000 -fS16_BE test.raw |
124 | * playing an ac3 sample file to the Do port | ||
125 | % aplay -D hw:1,2 --channels=6 ac3_S16_BE_encoded_file.raw | ||
101 | 126 | ||
102 | If you're happy with the default Alsa driver setup and don't experience any | 127 | If you're happy with the default Alsa driver mode and don't experience any |
103 | issue with this mode, then you can skip the following chapter. | 128 | issue with this mode, then you can skip the following chapter. |
104 | 129 | ||
105 | 2.2.2 - Advanced module setup | 130 | 3.2 - Advanced module setup |
131 | --------------------------- | ||
106 | 132 | ||
107 | Due to the hardware constraints described above, the device initialization made | 133 | Due to the hardware constraints described above, the device initialization made |
108 | by the Alsa driver in default mode may result in a corrupted state of the | 134 | by the Alsa driver in default mode may result in a corrupted state of the |
109 | device. For instance, a particularly annoying issue is that the sound captured | 135 | device. For instance, a particularly annoying issue is that the sound captured |
110 | from the Ai port sounds distorted (as if boosted with an excessive high volume | 136 | from the Ai interface sounds distorted (as if boosted with an excessive high |
111 | gain). | 137 | volume gain). |
112 | 138 | ||
113 | For people having this problem, the snd-usb-audio module has a new module | 139 | For people having this problem, the snd-usb-audio module has a new module |
114 | parameter called "device_setup". | 140 | parameter called "device_setup" (this parameter was introduced in kernel |
141 | release 2.6.17) | ||
115 | 142 | ||
116 | 2.2.2.1 - Initializing the working mode of the Audiophile USB | 143 | 3.2.1 - Initializing the working mode of the Audiophile USB |
117 | 144 | ||
118 | As far as the Audiophile USB device is concerned, this value let the user | 145 | As far as the Audiophile USB device is concerned, this value let the user |
119 | specify: | 146 | specify: |
@@ -121,33 +148,57 @@ specify: | |||
121 | * the sample rate | 148 | * the sample rate |
122 | * whether the Di port is used or not | 149 | * whether the Di port is used or not |
123 | 150 | ||
124 | Here is a list of supported device_setup values for this device: | 151 | When initialized with "device_setup=0x00", the snd-usb-audio module has |
125 | * device_setup=0x00 (or omitted) | 152 | the same behaviour as when the parameter is omitted (see paragraph "Default |
126 | - Alsa driver default mode | 153 | Alsa driver mode" above) |
127 | - maintains backward compatibility with setups that do not use this | 154 | |
128 | parameter by not introducing any change | 155 | Others modes are described in the following subsections. |
129 | - results sometimes in corrupted sound as described earlier | 156 | |
157 | 3.2.1.1 - 16-bit modes | ||
158 | |||
159 | The two supported modes are: | ||
160 | |||
130 | * device_setup=0x01 | 161 | * device_setup=0x01 |
131 | - 16bits 48kHz mode with Di disabled | 162 | - 16bits 48kHz mode with Di disabled |
132 | - Ai,Ao,Do can be used at the same time | 163 | - Ai,Ao,Do can be used at the same time |
133 | - hw:1,0 is not available in capture mode | 164 | - hw:1,0 is not available in capture mode |
134 | - hw:1,2 is not available | 165 | - hw:1,2 is not available |
166 | |||
135 | * device_setup=0x11 | 167 | * device_setup=0x11 |
136 | - 16bits 48kHz mode with Di enabled | 168 | - 16bits 48kHz mode with Di enabled |
137 | - Ai,Ao,Di,Do can be used at the same time | 169 | - Ai,Ao,Di,Do can be used at the same time |
138 | - hw:1,0 is available in capture mode | 170 | - hw:1,0 is available in capture mode |
139 | - hw:1,2 is not available | 171 | - hw:1,2 is not available |
172 | |||
173 | In this modes the device operates only at 16bits-modes. Before kernel 2.6.23, | ||
174 | the devices where reported to be Big-Endian when in fact they were Little-Endian | ||
175 | so that playing a file was a matter of using: | ||
176 | % aplay -D hw:1,1 -c2 -t raw -r48000 -fS16_BE test_S16_LE.raw | ||
177 | where "test_S16_LE.raw" was in fact a little-endian sample file. | ||
178 | |||
179 | Thanks to Hakan Lennestal (who discovered the Little-Endiannes of the device in | ||
180 | these modes) a fix has been committed (expected in kernel 2.6.23) and | ||
181 | Alsa now reports Little-Endian interfaces. Thus playing a file now is as simple as | ||
182 | using: | ||
183 | % aplay -D hw:1,1 -c2 -t raw -r48000 -fS16_LE test_S16_LE.raw | ||
184 | |||
185 | 3.2.1.2 - 24-bit modes | ||
186 | |||
187 | The three supported modes are: | ||
188 | |||
140 | * device_setup=0x09 | 189 | * device_setup=0x09 |
141 | - 24bits 48kHz mode with Di disabled | 190 | - 24bits 48kHz mode with Di disabled |
142 | - Ai,Ao,Do can be used at the same time | 191 | - Ai,Ao,Do can be used at the same time |
143 | - hw:1,0 is not available in capture mode | 192 | - hw:1,0 is not available in capture mode |
144 | - hw:1,2 is not available | 193 | - hw:1,2 is not available |
194 | |||
145 | * device_setup=0x19 | 195 | * device_setup=0x19 |
146 | - 24bits 48kHz mode with Di enabled | 196 | - 24bits 48kHz mode with Di enabled |
147 | - 3 ports from {Ai,Ao,Di,Do} can be used at the same time | 197 | - 3 ports from {Ai,Ao,Di,Do} can be used at the same time |
148 | - hw:1,0 is available in capture mode and an active digital source must be | 198 | - hw:1,0 is available in capture mode and an active digital source must be |
149 | connected to Di | 199 | connected to Di |
150 | - hw:1,2 is not available | 200 | - hw:1,2 is not available |
201 | |||
151 | * device_setup=0x0D or 0x10 | 202 | * device_setup=0x0D or 0x10 |
152 | - 24bits 96kHz mode | 203 | - 24bits 96kHz mode |
153 | - Di is enabled by default for this mode but does not need to be connected | 204 | - Di is enabled by default for this mode but does not need to be connected |
@@ -155,34 +206,64 @@ Here is a list of supported device_setup values for this device: | |||
155 | - Only 1 port from {Ai,Ao,Di,Do} can be used at the same time | 206 | - Only 1 port from {Ai,Ao,Di,Do} can be used at the same time |
156 | - hw:1,0 is available in captured mode | 207 | - hw:1,0 is available in captured mode |
157 | - hw:1,2 is not available | 208 | - hw:1,2 is not available |
209 | |||
210 | In these modes the device is only Big-Endian compliant (see "Default Alsa driver | ||
211 | mode" above for an aplay command example) | ||
212 | |||
213 | 3.2.1.3 - AC3 w/ DTS passthru mode | ||
214 | |||
215 | Thanks to Hakan Lennestal, I now have a report saying that this mode works. | ||
216 | |||
158 | * device_setup=0x03 | 217 | * device_setup=0x03 |
159 | - 16bits 48kHz mode with only the Do port enabled | 218 | - 16bits 48kHz mode with only the Do port enabled |
160 | - AC3 with DTS passthru (not tested) | 219 | - AC3 with DTS passthru |
161 | - Caution with this setup the Do port is mapped to the pcm device hw:1,0 | 220 | - Caution with this setup the Do port is mapped to the pcm device hw:1,0 |
162 | 221 | ||
163 | 2.2.2.2 - Setting and switching configurations with the device_setup parameter | 222 | The command line used to playback the AC3/DTS encoded .wav-files in this mode: |
223 | % aplay -D hw:1,0 --channels=6 ac3_S16_LE_encoded_file.raw | ||
224 | |||
225 | 3.2.2 - How to use the device_setup parameter | ||
226 | ---------------------------------------------- | ||
164 | 227 | ||
165 | The parameter can be given: | 228 | The parameter can be given: |
229 | |||
166 | * By manually probing the device (as root): | 230 | * By manually probing the device (as root): |
167 | # modprobe -r snd-usb-audio | 231 | # modprobe -r snd-usb-audio |
168 | # modprobe snd-usb-audio index=1 device_setup=0x09 | 232 | # modprobe snd-usb-audio index=1 device_setup=0x09 |
233 | |||
169 | * Or while configuring the modules options in your modules configuration file | 234 | * Or while configuring the modules options in your modules configuration file |
170 | - For Fedora distributions, edit the /etc/modprobe.conf file: | 235 | - For Fedora distributions, edit the /etc/modprobe.conf file: |
171 | alias snd-card-1 snd-usb-audio | 236 | alias snd-card-1 snd-usb-audio |
172 | options snd-usb-audio index=1 device_setup=0x09 | 237 | options snd-usb-audio index=1 device_setup=0x09 |
173 | 238 | ||
174 | IMPORTANT NOTE WHEN SWITCHING CONFIGURATION: | 239 | CAUTION when initializaing the device |
175 | ------------------------------------------- | 240 | ------------------------------------- |
176 | * You may need to _first_ initialize the module with the correct device_setup | 241 | |
177 | parameter and _only_after_ turn on the Audiophile USB device | 242 | * Correct initialization on the device requires that device_setup is given to |
178 | * This is especially true when switching the sample depth: | 243 | the module BEFORE the device is turned on. So, if you use the "manual probing" |
244 | method described above, take care to power-on the device AFTER this initialization. | ||
245 | |||
246 | * Failing to respect this will lead in a misconfiguration of the device. In this case | ||
247 | turn off the device, unproble the snd-usb-audio module, then probe it again with | ||
248 | correct device_setup parameter and then (and only then) turn on the device again. | ||
249 | |||
250 | * If you've correctly initialized the device in a valid mode and then want to switch | ||
251 | to another mode (possibly with another sample-depth), please use also the following | ||
252 | procedure: | ||
179 | - first turn off the device | 253 | - first turn off the device |
180 | - de-register the snd-usb-audio module (modprobe -r) | 254 | - de-register the snd-usb-audio module (modprobe -r) |
181 | - change the device_setup parameter by changing the device_setup | 255 | - change the device_setup parameter by changing the device_setup |
182 | option in /etc/modprobe.conf | 256 | option in /etc/modprobe.conf |
183 | - turn on the device | 257 | - turn on the device |
258 | * A workaround for this last issue has been applied to kernel 2.6.23, but it may not | ||
259 | be enough to ensure the 'stability' of the device initialization. | ||
184 | 260 | ||
185 | 2.2.2.3 - Audiophile USB's device_setup structure | 261 | 3.2.3 - Technical details for hackers |
262 | ------------------------------------- | ||
263 | This section is for hackers, wanting to understand details about the device | ||
264 | internals and how Alsa supports it. | ||
265 | |||
266 | 3.2.3.1 - Audiophile USB's device_setup structure | ||
186 | 267 | ||
187 | If you want to understand the device_setup magic numbers for the Audiophile | 268 | If you want to understand the device_setup magic numbers for the Audiophile |
188 | USB, you need some very basic understanding of binary computation. However, | 269 | USB, you need some very basic understanding of binary computation. However, |
@@ -228,12 +309,12 @@ Caution: | |||
228 | - choosing b2 will prepare all interfaces for 24bits/96kHz but you'll | 309 | - choosing b2 will prepare all interfaces for 24bits/96kHz but you'll |
229 | only be able to use one at the same time | 310 | only be able to use one at the same time |
230 | 311 | ||
231 | 2.2.3 - USB implementation details for this device | 312 | 3.2.3.2 - USB implementation details for this device |
232 | 313 | ||
233 | You may safely skip this section if you're not interested in driver | 314 | You may safely skip this section if you're not interested in driver |
234 | development. | 315 | hacking. |
235 | 316 | ||
236 | This section describes some internal aspects of the device and summarize the | 317 | This section describes some internal aspects of the device and summarizes the |
237 | data I got by usb-snooping the windows and Linux drivers. | 318 | data I got by usb-snooping the windows and Linux drivers. |
238 | 319 | ||
239 | The M-Audio Audiophile USB has 7 USB Interfaces: | 320 | The M-Audio Audiophile USB has 7 USB Interfaces: |
@@ -293,43 +374,45 @@ parse_audio_endpoints function uses a quirk called | |||
293 | "audiophile_skip_setting_quirk" in order to prevent AltSettings not | 374 | "audiophile_skip_setting_quirk" in order to prevent AltSettings not |
294 | corresponding to device_setup from being registered in the driver. | 375 | corresponding to device_setup from being registered in the driver. |
295 | 376 | ||
296 | 3 - Audiophile USB and Jack support | 377 | 4 - Audiophile USB and Jack support |
297 | =================================== | 378 | =================================== |
298 | 379 | ||
299 | This section deals with support of the Audiophile USB device in Jack. | 380 | This section deals with support of the Audiophile USB device in Jack. |
300 | The main issue regarding this support is that the device is Big Endian | ||
301 | compliant. | ||
302 | 381 | ||
303 | 3.1 - Using the plug alsa plugin | 382 | There are 2 main potential issues when using Jackd with the device: |
304 | -------------------------------- | 383 | * support for Big-Endian devices in 24-bit modes |
384 | * support for 4-in / 4-out channels | ||
385 | |||
386 | 4.1 - Direct support in Jackd | ||
387 | ----------------------------- | ||
305 | 388 | ||
306 | Jack doesn't directly support big endian devices. Thus, one way to have support | 389 | Jack supports big endian devices only in recent versions (thanks to |
307 | for this device with Alsa is to use the Alsa "plug" converter. | 390 | Andreas Steinmetz for his first big-endian patch). I can't remember |
391 | extacly when this support was released into jackd, let's just say that | ||
392 | with jackd version 0.103.0 it's almost ok (just a small bug is affecting | ||
393 | 16bits Big-Endian devices, but since you've read carefully the above | ||
394 | paragraphs, you're now using kernel >= 2.6.23 and your 16bits devices | ||
395 | are now Little Endians ;-) ). | ||
396 | |||
397 | You can run jackd with the following command for playback with Ao and | ||
398 | record with Ai: | ||
399 | % jackd -R -dalsa -Phw:1,0 -r48000 -p128 -n2 -D -Chw:1,1 | ||
400 | |||
401 | 4.2 - Using Alsa plughw | ||
402 | ----------------------- | ||
403 | If you don't have a recent Jackd installed, you can downgrade to using | ||
404 | the Alsa "plug" converter. | ||
308 | 405 | ||
309 | For instance here is one way to run Jack with 2 playback channels on Ao and 2 | 406 | For instance here is one way to run Jack with 2 playback channels on Ao and 2 |
310 | capture channels from Ai: | 407 | capture channels from Ai: |
311 | % jackd -R -dalsa -dplughw:1 -r48000 -p256 -n2 -D -Cplughw:1,1 | 408 | % jackd -R -dalsa -dplughw:1 -r48000 -p256 -n2 -D -Cplughw:1,1 |
312 | 409 | ||
313 | |||
314 | However you may see the following warning message: | 410 | However you may see the following warning message: |
315 | "You appear to be using the ALSA software "plug" layer, probably a result of | 411 | "You appear to be using the ALSA software "plug" layer, probably a result of |
316 | using the "default" ALSA device. This is less efficient than it could be. | 412 | using the "default" ALSA device. This is less efficient than it could be. |
317 | Consider using a hardware device instead rather than using the plug layer." | 413 | Consider using a hardware device instead rather than using the plug layer." |
318 | 414 | ||
319 | 3.2 - Patching alsa to use direct pcm device | 415 | 4.3 - Getting 2 input and/or output interfaces in Jack |
320 | -------------------------------------------- | ||
321 | A patch for Jack by Andreas Steinmetz adds support for Big Endian devices. | ||
322 | However it has not been included in the CVS tree. | ||
323 | |||
324 | You can find it at the following URL: | ||
325 | http://sourceforge.net/tracker/index.php?func=detail&aid=1289682&group_id=39687& | ||
326 | atid=425939 | ||
327 | |||
328 | After having applied the patch you can run jackd with the following command | ||
329 | line: | ||
330 | % jackd -R -dalsa -Phw:1,0 -r48000 -p128 -n2 -D -Chw:1,1 | ||
331 | |||
332 | 3.2 - Getting 2 input and/or output interfaces in Jack | ||
333 | ------------------------------------------------------ | 416 | ------------------------------------------------------ |
334 | 417 | ||
335 | As you can see, starting the Jack server this way will only enable 1 stereo | 418 | As you can see, starting the Jack server this way will only enable 1 stereo |
@@ -339,6 +422,7 @@ This is due to the following restrictions: | |||
339 | * Jack can only open one capture device and one playback device at a time | 422 | * Jack can only open one capture device and one playback device at a time |
340 | * The Audiophile USB is seen as 2 (or three) Alsa devices: hw:1,0, hw:1,1 | 423 | * The Audiophile USB is seen as 2 (or three) Alsa devices: hw:1,0, hw:1,1 |
341 | (and optionally hw:1,2) | 424 | (and optionally hw:1,2) |
425 | |||
342 | If you want to get Ai+Di and/or Ao+Do support with Jack, you would need to | 426 | If you want to get Ai+Di and/or Ao+Do support with Jack, you would need to |
343 | combine the Alsa devices into one logical "complex" device. | 427 | combine the Alsa devices into one logical "complex" device. |
344 | 428 | ||
@@ -348,13 +432,11 @@ It is related to another device (ice1712) but can be adapted to suit | |||
348 | the Audiophile USB. | 432 | the Audiophile USB. |
349 | 433 | ||
350 | Enabling multiple Audiophile USB interfaces for Jackd will certainly require: | 434 | Enabling multiple Audiophile USB interfaces for Jackd will certainly require: |
351 | * patching Jack with the previously mentioned "Big Endian" patch | 435 | * Making sure your Jackd version has the MMAP_COMPLEX patch (see the ice1712 page) |
352 | * patching Jackd with the MMAP_COMPLEX patch (see the ice1712 page) | 436 | * (maybe) patching the alsa-lib/src/pcm/pcm_multi.c file (see the ice1712 page) |
353 | * patching the alsa-lib/src/pcm/pcm_multi.c file (see the ice1712 page) | ||
354 | * define a multi device (combination of hw:1,0 and hw:1,1) in your .asoundrc | 437 | * define a multi device (combination of hw:1,0 and hw:1,1) in your .asoundrc |
355 | file | 438 | file |
356 | * start jackd with this device | 439 | * start jackd with this device |
357 | 440 | ||
358 | I had no success in testing this for now, but this may be due to my OS | 441 | I had no success in testing this for now, if you have any success with this kind |
359 | configuration. If you have any success with this kind of setup, please | 442 | of setup, please drop me an email. |
360 | drop me an email. | ||
diff --git a/Documentation/sound/alsa/OSS-Emulation.txt b/Documentation/sound/alsa/OSS-Emulation.txt index ec2a02541d5b..bfa0c9aacb4b 100644 --- a/Documentation/sound/alsa/OSS-Emulation.txt +++ b/Documentation/sound/alsa/OSS-Emulation.txt | |||
@@ -278,6 +278,21 @@ current mixer configuration by reading and writing the whole file | |||
278 | image. | 278 | image. |
279 | 279 | ||
280 | 280 | ||
281 | Duplex Streams | ||
282 | ============== | ||
283 | |||
284 | Note that when attempting to use a single device file for playback and | ||
285 | capture, the OSS API provides no way to set the format, sample rate or | ||
286 | number of channels different in each direction. Thus | ||
287 | io_handle = open("device", O_RDWR) | ||
288 | will only function correctly if the values are the same in each direction. | ||
289 | |||
290 | To use different values in the two directions, use both | ||
291 | input_handle = open("device", O_RDONLY) | ||
292 | output_handle = open("device", O_WRONLY) | ||
293 | and set the values for the corresponding handle. | ||
294 | |||
295 | |||
281 | Unsupported Features | 296 | Unsupported Features |
282 | ==================== | 297 | ==================== |
283 | 298 | ||
diff --git a/MAINTAINERS b/MAINTAINERS index fbe0dca1c0ed..f49c5563f060 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -329,6 +329,12 @@ P: Ivan Kokshaysky | |||
329 | M: ink@jurassic.park.msu.ru | 329 | M: ink@jurassic.park.msu.ru |
330 | S: Maintained for 2.4; PCI support for 2.6. | 330 | S: Maintained for 2.4; PCI support for 2.6. |
331 | 331 | ||
332 | AMD GEODE CS5536 USB DEVICE CONTROLLER DRIVER | ||
333 | P: Thomas Dahlmann | ||
334 | M: thomas.dahlmann@amd.com | ||
335 | L: info-linux@geode.amd.com | ||
336 | S: Supported | ||
337 | |||
332 | AMD GEODE PROCESSOR/CHIPSET SUPPORT | 338 | AMD GEODE PROCESSOR/CHIPSET SUPPORT |
333 | P: Jordan Crouse | 339 | P: Jordan Crouse |
334 | M: info-linux@geode.amd.com | 340 | M: info-linux@geode.amd.com |
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index c04124a095cf..846cce48e2b7 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c | |||
@@ -145,8 +145,8 @@ void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |||
145 | __do_kernel_fault(mm, addr, fsr, regs); | 145 | __do_kernel_fault(mm, addr, fsr, regs); |
146 | } | 146 | } |
147 | 147 | ||
148 | #define VM_FAULT_BADMAP (-20) | 148 | #define VM_FAULT_BADMAP 0x010000 |
149 | #define VM_FAULT_BADACCESS (-21) | 149 | #define VM_FAULT_BADACCESS 0x020000 |
150 | 150 | ||
151 | static int | 151 | static int |
152 | __do_page_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr, | 152 | __do_page_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr, |
@@ -249,7 +249,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |||
249 | /* | 249 | /* |
250 | * Handle the "normal" case first - VM_FAULT_MAJOR / VM_FAULT_MINOR | 250 | * Handle the "normal" case first - VM_FAULT_MAJOR / VM_FAULT_MINOR |
251 | */ | 251 | */ |
252 | if (likely(!(fault & VM_FAULT_ERROR))) | 252 | if (likely(!(fault & (VM_FAULT_ERROR | VM_FAULT_BADMAP | VM_FAULT_BADACCESS)))) |
253 | return 0; | 253 | return 0; |
254 | 254 | ||
255 | /* | 255 | /* |
diff --git a/arch/i386/boot/compressed/relocs.c b/arch/i386/boot/compressed/relocs.c index b0e21c3cee5c..2d77ee728f92 100644 --- a/arch/i386/boot/compressed/relocs.c +++ b/arch/i386/boot/compressed/relocs.c | |||
@@ -31,6 +31,7 @@ static const char* safe_abs_relocs[] = { | |||
31 | "__kernel_rt_sigreturn", | 31 | "__kernel_rt_sigreturn", |
32 | "__kernel_sigreturn", | 32 | "__kernel_sigreturn", |
33 | "SYSENTER_RETURN", | 33 | "SYSENTER_RETURN", |
34 | "VDSO_NOTE_MASK", | ||
34 | "xen_irq_disable_direct_reloc", | 35 | "xen_irq_disable_direct_reloc", |
35 | "xen_save_fl_direct_reloc", | 36 | "xen_save_fl_direct_reloc", |
36 | }; | 37 | }; |
diff --git a/arch/i386/kernel/vsyscall-note.S b/arch/i386/kernel/vsyscall-note.S index 271f16a8ca01..07c0daf78237 100644 --- a/arch/i386/kernel/vsyscall-note.S +++ b/arch/i386/kernel/vsyscall-note.S | |||
@@ -14,7 +14,6 @@ ELFNOTE_START(Linux, 0, "a") | |||
14 | ELFNOTE_END | 14 | ELFNOTE_END |
15 | 15 | ||
16 | #ifdef CONFIG_XEN | 16 | #ifdef CONFIG_XEN |
17 | |||
18 | /* | 17 | /* |
19 | * Add a special note telling glibc's dynamic linker a fake hardware | 18 | * Add a special note telling glibc's dynamic linker a fake hardware |
20 | * flavor that it will use to choose the search path for libraries in the | 19 | * flavor that it will use to choose the search path for libraries in the |
@@ -28,15 +27,19 @@ ELFNOTE_END | |||
28 | * It should contain: | 27 | * It should contain: |
29 | * hwcap 1 nosegneg | 28 | * hwcap 1 nosegneg |
30 | * to match the mapping of bit to name that we give here. | 29 | * to match the mapping of bit to name that we give here. |
30 | * | ||
31 | * At runtime, the fake hardware feature will be considered to be present | ||
32 | * if its bit is set in the mask word. So, we start with the mask 0, and | ||
33 | * at boot time we set VDSO_NOTE_NONEGSEG_BIT if running under Xen. | ||
31 | */ | 34 | */ |
32 | 35 | ||
33 | /* Bit used for the pseudo-hwcap for non-negative segments. We use | 36 | #include "../xen/vdso.h" /* Defines VDSO_NOTE_NONEGSEG_BIT. */ |
34 | bit 1 to avoid bugs in some versions of glibc when bit 0 is | ||
35 | used; the choice is otherwise arbitrary. */ | ||
36 | #define VDSO_NOTE_NONEGSEG_BIT 1 | ||
37 | 37 | ||
38 | .globl VDSO_NOTE_MASK | ||
38 | ELFNOTE_START(GNU, 2, "a") | 39 | ELFNOTE_START(GNU, 2, "a") |
39 | .long 1, 1<<VDSO_NOTE_NONEGSEG_BIT /* ncaps, mask */ | 40 | .long 1 /* ncaps */ |
41 | VDSO_NOTE_MASK: | ||
42 | .long 0 /* mask */ | ||
40 | .byte VDSO_NOTE_NONEGSEG_BIT; .asciz "nosegneg" /* bit, name */ | 43 | .byte VDSO_NOTE_NONEGSEG_BIT; .asciz "nosegneg" /* bit, name */ |
41 | ELFNOTE_END | 44 | ELFNOTE_END |
42 | #endif | 45 | #endif |
diff --git a/arch/i386/xen/events.c b/arch/i386/xen/events.c index 8904acc20f8c..da1b173547a1 100644 --- a/arch/i386/xen/events.c +++ b/arch/i386/xen/events.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <asm/irq.h> | 31 | #include <asm/irq.h> |
32 | #include <asm/sync_bitops.h> | 32 | #include <asm/sync_bitops.h> |
33 | #include <asm/xen/hypercall.h> | 33 | #include <asm/xen/hypercall.h> |
34 | #include <asm/xen/hypervisor.h> | ||
34 | 35 | ||
35 | #include <xen/events.h> | 36 | #include <xen/events.h> |
36 | #include <xen/interface/xen.h> | 37 | #include <xen/interface/xen.h> |
diff --git a/arch/i386/xen/setup.c b/arch/i386/xen/setup.c index 2fe6eac510f0..f84e77226646 100644 --- a/arch/i386/xen/setup.c +++ b/arch/i386/xen/setup.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <xen/features.h> | 19 | #include <xen/features.h> |
20 | 20 | ||
21 | #include "xen-ops.h" | 21 | #include "xen-ops.h" |
22 | #include "vdso.h" | ||
22 | 23 | ||
23 | /* These are code, but not functions. Defined in entry.S */ | 24 | /* These are code, but not functions. Defined in entry.S */ |
24 | extern const char xen_hypervisor_callback[]; | 25 | extern const char xen_hypervisor_callback[]; |
@@ -55,6 +56,18 @@ static void xen_idle(void) | |||
55 | } | 56 | } |
56 | } | 57 | } |
57 | 58 | ||
59 | /* | ||
60 | * Set the bit indicating "nosegneg" library variants should be used. | ||
61 | */ | ||
62 | static void fiddle_vdso(void) | ||
63 | { | ||
64 | extern u32 VDSO_NOTE_MASK; /* See ../kernel/vsyscall-note.S. */ | ||
65 | extern char vsyscall_int80_start; | ||
66 | u32 *mask = (u32 *) ((unsigned long) &VDSO_NOTE_MASK - VDSO_PRELINK + | ||
67 | &vsyscall_int80_start); | ||
68 | *mask |= 1 << VDSO_NOTE_NONEGSEG_BIT; | ||
69 | } | ||
70 | |||
58 | void __init xen_arch_setup(void) | 71 | void __init xen_arch_setup(void) |
59 | { | 72 | { |
60 | struct physdev_set_iopl set_iopl; | 73 | struct physdev_set_iopl set_iopl; |
@@ -93,4 +106,6 @@ void __init xen_arch_setup(void) | |||
93 | #endif | 106 | #endif |
94 | 107 | ||
95 | paravirt_disable_iospace(); | 108 | paravirt_disable_iospace(); |
109 | |||
110 | fiddle_vdso(); | ||
96 | } | 111 | } |
diff --git a/arch/i386/xen/vdso.h b/arch/i386/xen/vdso.h new file mode 100644 index 000000000000..861fedfe5230 --- /dev/null +++ b/arch/i386/xen/vdso.h | |||
@@ -0,0 +1,4 @@ | |||
1 | /* Bit used for the pseudo-hwcap for non-negative segments. We use | ||
2 | bit 1 to avoid bugs in some versions of glibc when bit 0 is | ||
3 | used; the choice is otherwise arbitrary. */ | ||
4 | #define VDSO_NOTE_NONEGSEG_BIT 1 | ||
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index a86e2e9a639f..20a9c08e59c3 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig | |||
@@ -37,6 +37,10 @@ config TIME_LOW_RES | |||
37 | bool | 37 | bool |
38 | default y | 38 | default y |
39 | 39 | ||
40 | config GENERIC_IOMAP | ||
41 | bool | ||
42 | default y | ||
43 | |||
40 | config ARCH_MAY_HAVE_PC_FDC | 44 | config ARCH_MAY_HAVE_PC_FDC |
41 | bool | 45 | bool |
42 | depends on Q40 || (BROKEN && SUN3X) | 46 | depends on Q40 || (BROKEN && SUN3X) |
@@ -45,6 +49,9 @@ config ARCH_MAY_HAVE_PC_FDC | |||
45 | config NO_IOPORT | 49 | config NO_IOPORT |
46 | def_bool y | 50 | def_bool y |
47 | 51 | ||
52 | config NO_DMA | ||
53 | def_bool SUN3 | ||
54 | |||
48 | mainmenu "Linux/68k Kernel Configuration" | 55 | mainmenu "Linux/68k Kernel Configuration" |
49 | 56 | ||
50 | source "init/Kconfig" | 57 | source "init/Kconfig" |
diff --git a/arch/m68k/apollo/config.c b/arch/m68k/apollo/config.c index cb8e7609df4c..78df98f2029a 100644 --- a/arch/m68k/apollo/config.c +++ b/arch/m68k/apollo/config.c | |||
@@ -148,8 +148,8 @@ void dn_serial_print (const char *str) | |||
148 | } | 148 | } |
149 | } | 149 | } |
150 | 150 | ||
151 | void config_apollo(void) { | 151 | void __init config_apollo(void) |
152 | 152 | { | |
153 | int i; | 153 | int i; |
154 | 154 | ||
155 | dn_setup_model(); | 155 | dn_setup_model(); |
diff --git a/arch/m68k/apollo/dn_ints.c b/arch/m68k/apollo/dn_ints.c index 13bd41bed28e..5d47f3aa3810 100644 --- a/arch/m68k/apollo/dn_ints.c +++ b/arch/m68k/apollo/dn_ints.c | |||
@@ -37,7 +37,7 @@ static struct irq_controller apollo_irq_controller = { | |||
37 | }; | 37 | }; |
38 | 38 | ||
39 | 39 | ||
40 | void dn_init_IRQ(void) | 40 | void __init dn_init_IRQ(void) |
41 | { | 41 | { |
42 | m68k_setup_user_interrupt(VEC_USER + 96, 16, dn_process_int); | 42 | m68k_setup_user_interrupt(VEC_USER + 96, 16, dn_process_int); |
43 | m68k_setup_irq_controller(&apollo_irq_controller, IRQ_APOLLO, 16); | 43 | m68k_setup_irq_controller(&apollo_irq_controller, IRQ_APOLLO, 16); |
diff --git a/arch/m68k/atari/atakeyb.c b/arch/m68k/atari/atakeyb.c index 1c29603b16b3..2b5f64726a2e 100644 --- a/arch/m68k/atari/atakeyb.c +++ b/arch/m68k/atari/atakeyb.c | |||
@@ -13,6 +13,7 @@ | |||
13 | * enhanced by Bjoern Brauel and Roman Hodek | 13 | * enhanced by Bjoern Brauel and Roman Hodek |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/module.h> | ||
16 | #include <linux/sched.h> | 17 | #include <linux/sched.h> |
17 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
18 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
@@ -42,6 +43,9 @@ void (*atari_mouse_interrupt_hook) (char *); | |||
42 | void (*atari_input_keyboard_interrupt_hook) (unsigned char, char); | 43 | void (*atari_input_keyboard_interrupt_hook) (unsigned char, char); |
43 | /* Hook for mouse inputdev driver */ | 44 | /* Hook for mouse inputdev driver */ |
44 | void (*atari_input_mouse_interrupt_hook) (char *); | 45 | void (*atari_input_mouse_interrupt_hook) (char *); |
46 | EXPORT_SYMBOL(atari_mouse_interrupt_hook); | ||
47 | EXPORT_SYMBOL(atari_input_keyboard_interrupt_hook); | ||
48 | EXPORT_SYMBOL(atari_input_mouse_interrupt_hook); | ||
45 | 49 | ||
46 | /* variables for IKBD self test: */ | 50 | /* variables for IKBD self test: */ |
47 | 51 | ||
@@ -429,6 +433,7 @@ void ikbd_mouse_rel_pos(void) | |||
429 | 433 | ||
430 | ikbd_write(cmd, 1); | 434 | ikbd_write(cmd, 1); |
431 | } | 435 | } |
436 | EXPORT_SYMBOL(ikbd_mouse_rel_pos); | ||
432 | 437 | ||
433 | /* Set absolute mouse position reporting */ | 438 | /* Set absolute mouse position reporting */ |
434 | void ikbd_mouse_abs_pos(int xmax, int ymax) | 439 | void ikbd_mouse_abs_pos(int xmax, int ymax) |
@@ -453,6 +458,7 @@ void ikbd_mouse_thresh(int x, int y) | |||
453 | 458 | ||
454 | ikbd_write(cmd, 3); | 459 | ikbd_write(cmd, 3); |
455 | } | 460 | } |
461 | EXPORT_SYMBOL(ikbd_mouse_thresh); | ||
456 | 462 | ||
457 | /* Set mouse scale */ | 463 | /* Set mouse scale */ |
458 | void ikbd_mouse_scale(int x, int y) | 464 | void ikbd_mouse_scale(int x, int y) |
@@ -495,6 +501,7 @@ void ikbd_mouse_y0_top(void) | |||
495 | 501 | ||
496 | ikbd_write(cmd, 1); | 502 | ikbd_write(cmd, 1); |
497 | } | 503 | } |
504 | EXPORT_SYMBOL(ikbd_mouse_y0_top); | ||
498 | 505 | ||
499 | /* Resume */ | 506 | /* Resume */ |
500 | void ikbd_resume(void) | 507 | void ikbd_resume(void) |
@@ -511,6 +518,7 @@ void ikbd_mouse_disable(void) | |||
511 | 518 | ||
512 | ikbd_write(cmd, 1); | 519 | ikbd_write(cmd, 1); |
513 | } | 520 | } |
521 | EXPORT_SYMBOL(ikbd_mouse_disable); | ||
514 | 522 | ||
515 | /* Pause output */ | 523 | /* Pause output */ |
516 | void ikbd_pause(void) | 524 | void ikbd_pause(void) |
@@ -696,7 +704,6 @@ int __init atari_keyb_init(void) | |||
696 | return 0; | 704 | return 0; |
697 | } | 705 | } |
698 | 706 | ||
699 | |||
700 | int atari_kbdrate(struct kbd_repeat *k) | 707 | int atari_kbdrate(struct kbd_repeat *k) |
701 | { | 708 | { |
702 | if (k->delay > 0) { | 709 | if (k->delay > 0) { |
diff --git a/arch/m68k/bvme6000/config.c b/arch/m68k/bvme6000/config.c index 896ae3d3d919..9433a88a33c4 100644 --- a/arch/m68k/bvme6000/config.c +++ b/arch/m68k/bvme6000/config.c | |||
@@ -97,7 +97,7 @@ static int bvme6000_get_hardware_list(char *buffer) | |||
97 | * This function is called during kernel startup to initialize | 97 | * This function is called during kernel startup to initialize |
98 | * the bvme6000 IRQ handling routines. | 98 | * the bvme6000 IRQ handling routines. |
99 | */ | 99 | */ |
100 | static void bvme6000_init_IRQ(void) | 100 | static void __init bvme6000_init_IRQ(void) |
101 | { | 101 | { |
102 | m68k_setup_user_interrupt(VEC_USER, 192, NULL); | 102 | m68k_setup_user_interrupt(VEC_USER, 192, NULL); |
103 | } | 103 | } |
diff --git a/arch/m68k/kernel/head.S b/arch/m68k/kernel/head.S index 05741f233567..faa6764f1d13 100644 --- a/arch/m68k/kernel/head.S +++ b/arch/m68k/kernel/head.S | |||
@@ -577,7 +577,7 @@ func_define putn,1 | |||
577 | #endif | 577 | #endif |
578 | .endm | 578 | .endm |
579 | 579 | ||
580 | .text | 580 | .section ".text.head","ax" |
581 | ENTRY(_stext) | 581 | ENTRY(_stext) |
582 | /* | 582 | /* |
583 | * Version numbers of the bootinfo interface | 583 | * Version numbers of the bootinfo interface |
diff --git a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c index 215c7bd43924..7e6d5fb75390 100644 --- a/arch/m68k/kernel/setup.c +++ b/arch/m68k/kernel/setup.c | |||
@@ -58,6 +58,7 @@ extern int end; | |||
58 | extern unsigned long availmem; | 58 | extern unsigned long availmem; |
59 | 59 | ||
60 | int m68k_num_memory; | 60 | int m68k_num_memory; |
61 | EXPORT_SYMBOL(m68k_num_memory); | ||
61 | int m68k_realnum_memory; | 62 | int m68k_realnum_memory; |
62 | EXPORT_SYMBOL(m68k_realnum_memory); | 63 | EXPORT_SYMBOL(m68k_realnum_memory); |
63 | unsigned long m68k_memoffset; | 64 | unsigned long m68k_memoffset; |
diff --git a/arch/m68k/kernel/sun3-head.S b/arch/m68k/kernel/sun3-head.S index 4b5f050204e8..aad01592dbbc 100644 --- a/arch/m68k/kernel/sun3-head.S +++ b/arch/m68k/kernel/sun3-head.S | |||
@@ -29,7 +29,7 @@ kernel_pmd_table: .skip 0x2000 | |||
29 | .globl kernel_pg_dir | 29 | .globl kernel_pg_dir |
30 | .equ kernel_pg_dir,kernel_pmd_table | 30 | .equ kernel_pg_dir,kernel_pmd_table |
31 | 31 | ||
32 | .section .head | 32 | .section .text.head |
33 | ENTRY(_stext) | 33 | ENTRY(_stext) |
34 | ENTRY(_start) | 34 | ENTRY(_start) |
35 | 35 | ||
diff --git a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c index 4c065f9ceffc..7db41594d7b6 100644 --- a/arch/m68k/kernel/time.c +++ b/arch/m68k/kernel/time.c | |||
@@ -72,7 +72,7 @@ static irqreturn_t timer_interrupt(int irq, void *dummy) | |||
72 | return IRQ_HANDLED; | 72 | return IRQ_HANDLED; |
73 | } | 73 | } |
74 | 74 | ||
75 | void time_init(void) | 75 | void __init time_init(void) |
76 | { | 76 | { |
77 | struct rtc_time time; | 77 | struct rtc_time time; |
78 | 78 | ||
diff --git a/arch/m68k/kernel/vmlinux-std.lds b/arch/m68k/kernel/vmlinux-std.lds index 40f02b128f22..c42245775a4d 100644 --- a/arch/m68k/kernel/vmlinux-std.lds +++ b/arch/m68k/kernel/vmlinux-std.lds | |||
@@ -11,6 +11,7 @@ SECTIONS | |||
11 | . = 0x1000; | 11 | . = 0x1000; |
12 | _text = .; /* Text and read-only data */ | 12 | _text = .; /* Text and read-only data */ |
13 | .text : { | 13 | .text : { |
14 | *(.text.head) | ||
14 | TEXT_TEXT | 15 | TEXT_TEXT |
15 | SCHED_TEXT | 16 | SCHED_TEXT |
16 | LOCK_TEXT | 17 | LOCK_TEXT |
diff --git a/arch/m68k/kernel/vmlinux-sun3.lds b/arch/m68k/kernel/vmlinux-sun3.lds index f06425b6d206..4adffefb5c48 100644 --- a/arch/m68k/kernel/vmlinux-sun3.lds +++ b/arch/m68k/kernel/vmlinux-sun3.lds | |||
@@ -11,7 +11,7 @@ SECTIONS | |||
11 | . = 0xE002000; | 11 | . = 0xE002000; |
12 | _text = .; /* Text and read-only data */ | 12 | _text = .; /* Text and read-only data */ |
13 | .text : { | 13 | .text : { |
14 | *(.head) | 14 | *(.text.head) |
15 | TEXT_TEXT | 15 | TEXT_TEXT |
16 | SCHED_TEXT | 16 | SCHED_TEXT |
17 | LOCK_TEXT | 17 | LOCK_TEXT |
diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c index 5fd413246f89..8547dbc5e8d7 100644 --- a/arch/m68k/mac/config.c +++ b/arch/m68k/mac/config.c | |||
@@ -49,6 +49,7 @@ struct mac_booter_data mac_bi_data; | |||
49 | int mac_bisize = sizeof mac_bi_data; | 49 | int mac_bisize = sizeof mac_bi_data; |
50 | 50 | ||
51 | struct mac_hw_present mac_hw_present; | 51 | struct mac_hw_present mac_hw_present; |
52 | EXPORT_SYMBOL(mac_hw_present); | ||
52 | 53 | ||
53 | /* New m68k bootinfo stuff and videobase */ | 54 | /* New m68k bootinfo stuff and videobase */ |
54 | 55 | ||
@@ -84,7 +85,7 @@ extern void nubus_sweep_video(void); | |||
84 | 85 | ||
85 | static void mac_get_model(char *str); | 86 | static void mac_get_model(char *str); |
86 | 87 | ||
87 | static void mac_sched_init(irq_handler_t vector) | 88 | static void __init mac_sched_init(irq_handler_t vector) |
88 | { | 89 | { |
89 | via_init_clock(vector); | 90 | via_init_clock(vector); |
90 | } | 91 | } |
@@ -769,7 +770,7 @@ static struct mac_model mac_data_table[] = { | |||
769 | } | 770 | } |
770 | }; | 771 | }; |
771 | 772 | ||
772 | void mac_identify(void) | 773 | void __init mac_identify(void) |
773 | { | 774 | { |
774 | struct mac_model *m; | 775 | struct mac_model *m; |
775 | 776 | ||
@@ -846,7 +847,7 @@ void mac_identify(void) | |||
846 | baboon_init(); | 847 | baboon_init(); |
847 | } | 848 | } |
848 | 849 | ||
849 | void mac_report_hardware(void) | 850 | void __init mac_report_hardware(void) |
850 | { | 851 | { |
851 | printk(KERN_INFO "Apple Macintosh %s\n", macintosh_config->name); | 852 | printk(KERN_INFO "Apple Macintosh %s\n", macintosh_config->name); |
852 | } | 853 | } |
diff --git a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c index 0fc72d8f786e..ecddac4a02b9 100644 --- a/arch/m68k/mac/macints.c +++ b/arch/m68k/mac/macints.c | |||
@@ -114,6 +114,7 @@ | |||
114 | * | 114 | * |
115 | */ | 115 | */ |
116 | 116 | ||
117 | #include <linux/module.h> | ||
117 | #include <linux/types.h> | 118 | #include <linux/types.h> |
118 | #include <linux/kernel.h> | 119 | #include <linux/kernel.h> |
119 | #include <linux/sched.h> | 120 | #include <linux/sched.h> |
@@ -224,7 +225,7 @@ static struct irq_controller mac_irq_controller = { | |||
224 | .disable = mac_disable_irq, | 225 | .disable = mac_disable_irq, |
225 | }; | 226 | }; |
226 | 227 | ||
227 | void mac_init_IRQ(void) | 228 | void __init mac_init_IRQ(void) |
228 | { | 229 | { |
229 | #ifdef DEBUG_MACINTS | 230 | #ifdef DEBUG_MACINTS |
230 | printk("mac_init_IRQ(): Setting things up...\n"); | 231 | printk("mac_init_IRQ(): Setting things up...\n"); |
@@ -391,6 +392,7 @@ int mac_irq_pending(unsigned int irq) | |||
391 | } | 392 | } |
392 | return 0; | 393 | return 0; |
393 | } | 394 | } |
395 | EXPORT_SYMBOL(mac_irq_pending); | ||
394 | 396 | ||
395 | static int num_debug[8]; | 397 | static int num_debug[8]; |
396 | 398 | ||
diff --git a/arch/m68k/mm/init.c b/arch/m68k/mm/init.c index f1de19e1dde6..f42caa79e4e8 100644 --- a/arch/m68k/mm/init.c +++ b/arch/m68k/mm/init.c | |||
@@ -44,7 +44,7 @@ pg_data_t *pg_data_table[65]; | |||
44 | EXPORT_SYMBOL(pg_data_table); | 44 | EXPORT_SYMBOL(pg_data_table); |
45 | #endif | 45 | #endif |
46 | 46 | ||
47 | void m68k_setup_node(int node) | 47 | void __init m68k_setup_node(int node) |
48 | { | 48 | { |
49 | #ifndef CONFIG_SINGLE_MEMORY_CHUNK | 49 | #ifndef CONFIG_SINGLE_MEMORY_CHUNK |
50 | struct mem_info *info = m68k_memory + node; | 50 | struct mem_info *info = m68k_memory + node; |
diff --git a/arch/m68k/mm/sun3kmap.c b/arch/m68k/mm/sun3kmap.c index 1af24cb5bfe1..3dc41158c05e 100644 --- a/arch/m68k/mm/sun3kmap.c +++ b/arch/m68k/mm/sun3kmap.c | |||
@@ -105,6 +105,7 @@ void __iomem *sun3_ioremap(unsigned long phys, unsigned long size, | |||
105 | return (void __iomem *)ret; | 105 | return (void __iomem *)ret; |
106 | 106 | ||
107 | } | 107 | } |
108 | EXPORT_SYMBOL(sun3_ioremap); | ||
108 | 109 | ||
109 | 110 | ||
110 | void __iomem *__ioremap(unsigned long phys, unsigned long size, int cache) | 111 | void __iomem *__ioremap(unsigned long phys, unsigned long size, int cache) |
@@ -157,3 +158,4 @@ int sun3_map_test(unsigned long addr, char *val) | |||
157 | 158 | ||
158 | return ret; | 159 | return ret; |
159 | } | 160 | } |
161 | EXPORT_SYMBOL(sun3_map_test); | ||
diff --git a/arch/m68k/mvme147/config.c b/arch/m68k/mvme147/config.c index 4a7df9c3f85a..92fe50714112 100644 --- a/arch/m68k/mvme147/config.c +++ b/arch/m68k/mvme147/config.c | |||
@@ -89,7 +89,7 @@ static int mvme147_get_hardware_list(char *buffer) | |||
89 | * the mvme147 IRQ handling routines. | 89 | * the mvme147 IRQ handling routines. |
90 | */ | 90 | */ |
91 | 91 | ||
92 | void mvme147_init_IRQ(void) | 92 | void __init mvme147_init_IRQ(void) |
93 | { | 93 | { |
94 | m68k_setup_user_interrupt(VEC_USER, 192, NULL); | 94 | m68k_setup_user_interrupt(VEC_USER, 192, NULL); |
95 | } | 95 | } |
diff --git a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c index c829ebb6b1af..daa785161401 100644 --- a/arch/m68k/mvme16x/config.c +++ b/arch/m68k/mvme16x/config.c | |||
@@ -119,7 +119,7 @@ static int mvme16x_get_hardware_list(char *buffer) | |||
119 | * that the base vectors for the VMEChip2 and PCCChip2 are valid. | 119 | * that the base vectors for the VMEChip2 and PCCChip2 are valid. |
120 | */ | 120 | */ |
121 | 121 | ||
122 | static void mvme16x_init_IRQ (void) | 122 | static void __init mvme16x_init_IRQ (void) |
123 | { | 123 | { |
124 | m68k_setup_user_interrupt(VEC_USER, 192, NULL); | 124 | m68k_setup_user_interrupt(VEC_USER, 192, NULL); |
125 | } | 125 | } |
diff --git a/arch/m68k/q40/q40ints.c b/arch/m68k/q40/q40ints.c index 2fb25ae46a8a..ad3ed1fb8879 100644 --- a/arch/m68k/q40/q40ints.c +++ b/arch/m68k/q40/q40ints.c | |||
@@ -79,7 +79,7 @@ static struct irq_controller q40_irq_controller = { | |||
79 | 79 | ||
80 | static int disabled; | 80 | static int disabled; |
81 | 81 | ||
82 | void q40_init_IRQ(void) | 82 | void __init q40_init_IRQ(void) |
83 | { | 83 | { |
84 | m68k_setup_irq_controller(&q40_irq_controller, 1, Q40_IRQ_MAX); | 84 | m68k_setup_irq_controller(&q40_irq_controller, 1, Q40_IRQ_MAX); |
85 | 85 | ||
diff --git a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c index 50df34bf80e3..cf93481adb1d 100644 --- a/arch/m68k/sun3/sun3ints.c +++ b/arch/m68k/sun3/sun3ints.c | |||
@@ -97,7 +97,7 @@ static struct irq_controller sun3_irq_controller = { | |||
97 | .disable = sun3_disable_irq, | 97 | .disable = sun3_disable_irq, |
98 | }; | 98 | }; |
99 | 99 | ||
100 | void sun3_init_IRQ(void) | 100 | void __init sun3_init_IRQ(void) |
101 | { | 101 | { |
102 | *sun3_intreg = 1; | 102 | *sun3_intreg = 1; |
103 | 103 | ||
diff --git a/arch/m68k/sun3x/prom.c b/arch/m68k/sun3x/prom.c index 48f8eb7b1565..a7b7e818d627 100644 --- a/arch/m68k/sun3x/prom.c +++ b/arch/m68k/sun3x/prom.c | |||
@@ -92,7 +92,7 @@ static struct console sun3x_debug = { | |||
92 | .index = -1, | 92 | .index = -1, |
93 | }; | 93 | }; |
94 | 94 | ||
95 | void sun3x_prom_init(void) | 95 | void __init sun3x_prom_init(void) |
96 | { | 96 | { |
97 | /* Read the vector table */ | 97 | /* Read the vector table */ |
98 | 98 | ||
diff --git a/arch/m68knommu/kernel/setup.c b/arch/m68knommu/kernel/setup.c index 80f4e9d74ac1..2203f694f26b 100644 --- a/arch/m68knommu/kernel/setup.c +++ b/arch/m68knommu/kernel/setup.c | |||
@@ -231,32 +231,33 @@ void setup_arch(char **cmdline_p) | |||
231 | /* | 231 | /* |
232 | * Get CPU information for use by the procfs. | 232 | * Get CPU information for use by the procfs. |
233 | */ | 233 | */ |
234 | |||
235 | static int show_cpuinfo(struct seq_file *m, void *v) | 234 | static int show_cpuinfo(struct seq_file *m, void *v) |
236 | { | 235 | { |
237 | char *cpu, *mmu, *fpu; | 236 | char *cpu, *mmu, *fpu; |
238 | u_long clockfreq; | 237 | u_long clockfreq; |
239 | 238 | ||
240 | cpu = CPU; | 239 | cpu = CPU; |
241 | mmu = "none"; | 240 | mmu = "none"; |
242 | fpu = "none"; | 241 | fpu = "none"; |
243 | 242 | ||
244 | #ifdef CONFIG_COLDFIRE | 243 | #ifdef CONFIG_COLDFIRE |
245 | clockfreq = (loops_per_jiffy*HZ)*3; | 244 | clockfreq = (loops_per_jiffy * HZ) * 3; |
246 | #else | 245 | #else |
247 | clockfreq = (loops_per_jiffy*HZ)*16; | 246 | clockfreq = (loops_per_jiffy * HZ) * 16; |
248 | #endif | 247 | #endif |
249 | 248 | ||
250 | seq_printf(m, "CPU:\t\t%s\n" | 249 | seq_printf(m, "CPU:\t\t%s\n" |
251 | "MMU:\t\t%s\n" | 250 | "MMU:\t\t%s\n" |
252 | "FPU:\t\t%s\n" | 251 | "FPU:\t\t%s\n" |
253 | "Clocking:\t%lu.%1luMHz\n" | 252 | "Clocking:\t%lu.%1luMHz\n" |
254 | "BogoMips:\t%lu.%02lu\n" | 253 | "BogoMips:\t%lu.%02lu\n" |
255 | "Calibration:\t%lu loops\n", | 254 | "Calibration:\t%lu loops\n", |
256 | cpu, mmu, fpu, | 255 | cpu, mmu, fpu, |
257 | clockfreq/1000000,(clockfreq/100000)%10, | 256 | clockfreq / 1000000, |
258 | (loops_per_jiffy*HZ)/500000,((loops_per_jiffy*HZ)/5000)%100, | 257 | (clockfreq / 100000) % 10, |
259 | (loops_per_jiffy*HZ)); | 258 | (loops_per_jiffy * HZ) / 500000, |
259 | ((loops_per_jiffy * HZ) / 5000) % 100, | ||
260 | (loops_per_jiffy * HZ)); | ||
260 | 261 | ||
261 | return 0; | 262 | return 0; |
262 | } | 263 | } |
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index d8ed6676ae86..f87f429e0b24 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig | |||
@@ -178,6 +178,9 @@ config CPU_HAS_PINT_IRQ | |||
178 | config CPU_HAS_MASKREG_IRQ | 178 | config CPU_HAS_MASKREG_IRQ |
179 | bool | 179 | bool |
180 | 180 | ||
181 | config CPU_HAS_INTC_IRQ | ||
182 | bool | ||
183 | |||
181 | config CPU_HAS_INTC2_IRQ | 184 | config CPU_HAS_INTC2_IRQ |
182 | bool | 185 | bool |
183 | 186 | ||
@@ -209,6 +212,7 @@ config SOLUTION_ENGINE | |||
209 | config SH_SOLUTION_ENGINE | 212 | config SH_SOLUTION_ENGINE |
210 | bool "SolutionEngine" | 213 | bool "SolutionEngine" |
211 | select SOLUTION_ENGINE | 214 | select SOLUTION_ENGINE |
215 | select CPU_HAS_IPR_IRQ | ||
212 | depends on CPU_SUBTYPE_SH7709 || CPU_SUBTYPE_SH7750 | 216 | depends on CPU_SUBTYPE_SH7709 || CPU_SUBTYPE_SH7750 |
213 | help | 217 | help |
214 | Select SolutionEngine if configuring for a Hitachi SH7709 | 218 | Select SolutionEngine if configuring for a Hitachi SH7709 |
@@ -241,6 +245,7 @@ config SH_7722_SOLUTION_ENGINE | |||
241 | config SH_7751_SOLUTION_ENGINE | 245 | config SH_7751_SOLUTION_ENGINE |
242 | bool "SolutionEngine7751" | 246 | bool "SolutionEngine7751" |
243 | select SOLUTION_ENGINE | 247 | select SOLUTION_ENGINE |
248 | select CPU_HAS_IPR_IRQ | ||
244 | depends on CPU_SUBTYPE_SH7751 | 249 | depends on CPU_SUBTYPE_SH7751 |
245 | help | 250 | help |
246 | Select 7751 SolutionEngine if configuring for a Hitachi SH7751 | 251 | Select 7751 SolutionEngine if configuring for a Hitachi SH7751 |
@@ -250,6 +255,7 @@ config SH_7780_SOLUTION_ENGINE | |||
250 | bool "SolutionEngine7780" | 255 | bool "SolutionEngine7780" |
251 | select SOLUTION_ENGINE | 256 | select SOLUTION_ENGINE |
252 | select SYS_SUPPORTS_PCI | 257 | select SYS_SUPPORTS_PCI |
258 | select CPU_HAS_INTC2_IRQ | ||
253 | depends on CPU_SUBTYPE_SH7780 | 259 | depends on CPU_SUBTYPE_SH7780 |
254 | help | 260 | help |
255 | Select 7780 SolutionEngine if configuring for a Renesas SH7780 | 261 | Select 7780 SolutionEngine if configuring for a Renesas SH7780 |
@@ -317,6 +323,7 @@ config SH_MPC1211 | |||
317 | config SH_SH03 | 323 | config SH_SH03 |
318 | bool "Interface CTP/PCI-SH03" | 324 | bool "Interface CTP/PCI-SH03" |
319 | depends on CPU_SUBTYPE_SH7751 && BROKEN | 325 | depends on CPU_SUBTYPE_SH7751 && BROKEN |
326 | select CPU_HAS_IPR_IRQ | ||
320 | select SYS_SUPPORTS_PCI | 327 | select SYS_SUPPORTS_PCI |
321 | help | 328 | help |
322 | CTP/PCI-SH03 is a CPU module computer that is produced | 329 | CTP/PCI-SH03 is a CPU module computer that is produced |
@@ -326,6 +333,7 @@ config SH_SH03 | |||
326 | config SH_SECUREEDGE5410 | 333 | config SH_SECUREEDGE5410 |
327 | bool "SecureEdge5410" | 334 | bool "SecureEdge5410" |
328 | depends on CPU_SUBTYPE_SH7751R | 335 | depends on CPU_SUBTYPE_SH7751R |
336 | select CPU_HAS_IPR_IRQ | ||
329 | select SYS_SUPPORTS_PCI | 337 | select SYS_SUPPORTS_PCI |
330 | help | 338 | help |
331 | Select SecureEdge5410 if configuring for a SnapGear SH board. | 339 | Select SecureEdge5410 if configuring for a SnapGear SH board. |
@@ -380,6 +388,7 @@ config SH_LANDISK | |||
380 | config SH_TITAN | 388 | config SH_TITAN |
381 | bool "TITAN" | 389 | bool "TITAN" |
382 | depends on CPU_SUBTYPE_SH7751R | 390 | depends on CPU_SUBTYPE_SH7751R |
391 | select CPU_HAS_IPR_IRQ | ||
383 | select SYS_SUPPORTS_PCI | 392 | select SYS_SUPPORTS_PCI |
384 | help | 393 | help |
385 | Select Titan if you are configuring for a Nimble Microsystems | 394 | Select Titan if you are configuring for a Nimble Microsystems |
@@ -388,6 +397,7 @@ config SH_TITAN | |||
388 | config SH_SHMIN | 397 | config SH_SHMIN |
389 | bool "SHMIN" | 398 | bool "SHMIN" |
390 | depends on CPU_SUBTYPE_SH7706 | 399 | depends on CPU_SUBTYPE_SH7706 |
400 | select CPU_HAS_IPR_IRQ | ||
391 | help | 401 | help |
392 | Select SHMIN if configuring for the SHMIN board. | 402 | Select SHMIN if configuring for the SHMIN board. |
393 | 403 | ||
diff --git a/arch/sh/Makefile b/arch/sh/Makefile index 77fecc62a056..0016609d1eba 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile | |||
@@ -121,8 +121,7 @@ core-y += $(addprefix arch/sh/boards/, \ | |||
121 | endif | 121 | endif |
122 | 122 | ||
123 | # Companion chips | 123 | # Companion chips |
124 | core-$(CONFIG_HD64461) += arch/sh/cchips/hd6446x/hd64461/ | 124 | core-$(CONFIG_HD6446X_SERIES) += arch/sh/cchips/hd6446x/ |
125 | core-$(CONFIG_HD64465) += arch/sh/cchips/hd6446x/hd64465/ | ||
126 | core-$(CONFIG_VOYAGERGX) += arch/sh/cchips/voyagergx/ | 125 | core-$(CONFIG_VOYAGERGX) += arch/sh/cchips/voyagergx/ |
127 | 126 | ||
128 | cpuincdir-$(CONFIG_CPU_SH2) := cpu-sh2 | 127 | cpuincdir-$(CONFIG_CPU_SH2) := cpu-sh2 |
diff --git a/arch/sh/boards/mpc1211/pci.c b/arch/sh/boards/mpc1211/pci.c index 4ed1a95c6d56..23849f70f133 100644 --- a/arch/sh/boards/mpc1211/pci.c +++ b/arch/sh/boards/mpc1211/pci.c | |||
@@ -187,7 +187,7 @@ char * __devinit pcibios_setup(char *str) | |||
187 | * are examined. | 187 | * are examined. |
188 | */ | 188 | */ |
189 | 189 | ||
190 | void __init pcibios_fixup_bus(struct pci_bus *b) | 190 | void __devinit pcibios_fixup_bus(struct pci_bus *b) |
191 | { | 191 | { |
192 | pci_read_bridge_bases(b); | 192 | pci_read_bridge_bases(b); |
193 | } | 193 | } |
diff --git a/arch/sh/boards/renesas/r7780rp/setup.c b/arch/sh/boards/renesas/r7780rp/setup.c index 5afb864a1ec5..adb529d01bae 100644 --- a/arch/sh/boards/renesas/r7780rp/setup.c +++ b/arch/sh/boards/renesas/r7780rp/setup.c | |||
@@ -21,6 +21,58 @@ | |||
21 | #include <asm/clock.h> | 21 | #include <asm/clock.h> |
22 | #include <asm/io.h> | 22 | #include <asm/io.h> |
23 | 23 | ||
24 | static struct resource r8a66597_usb_host_resources[] = { | ||
25 | [0] = { | ||
26 | .name = "r8a66597_hcd", | ||
27 | .start = 0xA4200000, | ||
28 | .end = 0xA42000FF, | ||
29 | .flags = IORESOURCE_MEM, | ||
30 | }, | ||
31 | [1] = { | ||
32 | .name = "r8a66597_hcd", | ||
33 | .start = 11, /* irq number */ | ||
34 | .end = 11, | ||
35 | .flags = IORESOURCE_IRQ, | ||
36 | }, | ||
37 | }; | ||
38 | |||
39 | static struct platform_device r8a66597_usb_host_device = { | ||
40 | .name = "r8a66597_hcd", | ||
41 | .id = -1, | ||
42 | .dev = { | ||
43 | .dma_mask = NULL, /* don't use dma */ | ||
44 | .coherent_dma_mask = 0xffffffff, | ||
45 | }, | ||
46 | .num_resources = ARRAY_SIZE(r8a66597_usb_host_resources), | ||
47 | .resource = r8a66597_usb_host_resources, | ||
48 | }; | ||
49 | |||
50 | static struct resource m66592_usb_peripheral_resources[] = { | ||
51 | [0] = { | ||
52 | .name = "m66592_udc", | ||
53 | .start = 0xb0000000, | ||
54 | .end = 0xb00000FF, | ||
55 | .flags = IORESOURCE_MEM, | ||
56 | }, | ||
57 | [1] = { | ||
58 | .name = "m66592_udc", | ||
59 | .start = 9, /* irq number */ | ||
60 | .end = 9, | ||
61 | .flags = IORESOURCE_IRQ, | ||
62 | }, | ||
63 | }; | ||
64 | |||
65 | static struct platform_device m66592_usb_peripheral_device = { | ||
66 | .name = "m66592_udc", | ||
67 | .id = -1, | ||
68 | .dev = { | ||
69 | .dma_mask = NULL, /* don't use dma */ | ||
70 | .coherent_dma_mask = 0xffffffff, | ||
71 | }, | ||
72 | .num_resources = ARRAY_SIZE(m66592_usb_peripheral_resources), | ||
73 | .resource = m66592_usb_peripheral_resources, | ||
74 | }; | ||
75 | |||
24 | static struct resource cf_ide_resources[] = { | 76 | static struct resource cf_ide_resources[] = { |
25 | [0] = { | 77 | [0] = { |
26 | .start = PA_AREA5_IO + 0x1000, | 78 | .start = PA_AREA5_IO + 0x1000, |
@@ -81,6 +133,8 @@ static struct platform_device heartbeat_device = { | |||
81 | }; | 133 | }; |
82 | 134 | ||
83 | static struct platform_device *r7780rp_devices[] __initdata = { | 135 | static struct platform_device *r7780rp_devices[] __initdata = { |
136 | &r8a66597_usb_host_device, | ||
137 | &m66592_usb_peripheral_device, | ||
84 | &cf_ide_device, | 138 | &cf_ide_device, |
85 | &heartbeat_device, | 139 | &heartbeat_device, |
86 | }; | 140 | }; |
diff --git a/arch/sh/boards/renesas/rts7751r2d/setup.c b/arch/sh/boards/renesas/rts7751r2d/setup.c index 656fda30ef70..e165d85c03b5 100644 --- a/arch/sh/boards/renesas/rts7751r2d/setup.c +++ b/arch/sh/boards/renesas/rts7751r2d/setup.c | |||
@@ -86,7 +86,8 @@ static struct plat_serial8250_port uart_platform_data[] = { | |||
86 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, | 86 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, |
87 | .regshift = 2, | 87 | .regshift = 2, |
88 | .uartclk = (9600 * 16), | 88 | .uartclk = (9600 * 16), |
89 | } | 89 | }, |
90 | { 0 }, | ||
90 | }; | 91 | }; |
91 | 92 | ||
92 | static struct platform_device uart_device = { | 93 | static struct platform_device uart_device = { |
diff --git a/arch/sh/boards/se/7722/irq.c b/arch/sh/boards/se/7722/irq.c index 26cff0efda40..0b03f3f610b8 100644 --- a/arch/sh/boards/se/7722/irq.c +++ b/arch/sh/boards/se/7722/irq.c | |||
@@ -16,95 +16,61 @@ | |||
16 | #include <asm/io.h> | 16 | #include <asm/io.h> |
17 | #include <asm/se7722.h> | 17 | #include <asm/se7722.h> |
18 | 18 | ||
19 | #define INTC_INTMSK0 0xFFD00044 | ||
20 | #define INTC_INTMSKCLR0 0xFFD00064 | ||
21 | |||
22 | struct se7722_data { | ||
23 | unsigned char irq; | ||
24 | unsigned char ipr_idx; | ||
25 | unsigned char shift; | ||
26 | unsigned short priority; | ||
27 | unsigned long addr; | ||
28 | }; | ||
29 | |||
30 | |||
31 | static void disable_se7722_irq(unsigned int irq) | 19 | static void disable_se7722_irq(unsigned int irq) |
32 | { | 20 | { |
33 | struct se7722_data *p = get_irq_chip_data(irq); | 21 | unsigned int bit = irq - SE7722_FPGA_IRQ_BASE; |
34 | ctrl_outw( ctrl_inw( p->addr ) | p->priority , p->addr ); | 22 | ctrl_outw(ctrl_inw(IRQ01_MASK) | 1 << bit, IRQ01_MASK); |
35 | } | 23 | } |
36 | 24 | ||
37 | static void enable_se7722_irq(unsigned int irq) | 25 | static void enable_se7722_irq(unsigned int irq) |
38 | { | 26 | { |
39 | struct se7722_data *p = get_irq_chip_data(irq); | 27 | unsigned int bit = irq - SE7722_FPGA_IRQ_BASE; |
40 | ctrl_outw( ctrl_inw( p->addr ) & ~p->priority , p->addr ); | 28 | ctrl_outw(ctrl_inw(IRQ01_MASK) & ~(1 << bit), IRQ01_MASK); |
41 | } | 29 | } |
42 | 30 | ||
43 | static struct irq_chip se7722_irq_chip __read_mostly = { | 31 | static struct irq_chip se7722_irq_chip __read_mostly = { |
44 | .name = "SE7722", | 32 | .name = "SE7722-FPGA", |
45 | .mask = disable_se7722_irq, | 33 | .mask = disable_se7722_irq, |
46 | .unmask = enable_se7722_irq, | 34 | .unmask = enable_se7722_irq, |
47 | .mask_ack = disable_se7722_irq, | 35 | .mask_ack = disable_se7722_irq, |
48 | }; | 36 | }; |
49 | 37 | ||
50 | static struct se7722_data ipr_irq_table[] = { | 38 | static void se7722_irq_demux(unsigned int irq, struct irq_desc *desc) |
51 | /* irq ,idx,sft, priority , addr */ | ||
52 | { MRSHPC_IRQ0 , 0 , 0 , MRSHPC_BIT0 , IRQ01_MASK } , | ||
53 | { MRSHPC_IRQ1 , 0 , 0 , MRSHPC_BIT1 , IRQ01_MASK } , | ||
54 | { MRSHPC_IRQ2 , 0 , 0 , MRSHPC_BIT2 , IRQ01_MASK } , | ||
55 | { MRSHPC_IRQ3 , 0 , 0 , MRSHPC_BIT3 , IRQ01_MASK } , | ||
56 | { SMC_IRQ , 0 , 0 , SMC_BIT , IRQ01_MASK } , | ||
57 | { EXT_IRQ , 0 , 0 , EXT_BIT , IRQ01_MASK } , | ||
58 | }; | ||
59 | |||
60 | int se7722_irq_demux(int irq) | ||
61 | { | 39 | { |
40 | unsigned short intv = ctrl_inw(IRQ01_STS); | ||
41 | struct irq_desc *ext_desc; | ||
42 | unsigned int ext_irq = SE7722_FPGA_IRQ_BASE; | ||
43 | |||
44 | intv &= (1 << SE7722_FPGA_IRQ_NR) - 1; | ||
62 | 45 | ||
63 | if ((irq == IRQ0_IRQ)||(irq == IRQ1_IRQ)) { | 46 | while (intv) { |
64 | volatile unsigned short intv = | 47 | if (intv & 1) { |
65 | *(volatile unsigned short *)IRQ01_STS; | 48 | ext_desc = irq_desc + ext_irq; |
66 | if (irq == IRQ0_IRQ){ | 49 | handle_level_irq(ext_irq, ext_desc); |
67 | if(intv & SMC_BIT ) { | ||
68 | return SMC_IRQ; | ||
69 | } else if(intv & USB_BIT) { | ||
70 | return USB_IRQ; | ||
71 | } else { | ||
72 | printk("intv =%04x\n", intv); | ||
73 | return SMC_IRQ; | ||
74 | } | ||
75 | } else if(irq == IRQ1_IRQ){ | ||
76 | if(intv & MRSHPC_BIT0) { | ||
77 | return MRSHPC_IRQ0; | ||
78 | } else if(intv & MRSHPC_BIT1) { | ||
79 | return MRSHPC_IRQ1; | ||
80 | } else if(intv & MRSHPC_BIT2) { | ||
81 | return MRSHPC_IRQ2; | ||
82 | } else if(intv & MRSHPC_BIT3) { | ||
83 | return MRSHPC_IRQ3; | ||
84 | } else { | ||
85 | printk("BIT_EXTENTION =%04x\n", intv); | ||
86 | return EXT_IRQ; | ||
87 | } | ||
88 | } | 50 | } |
51 | intv >>= 1; | ||
52 | ext_irq++; | ||
89 | } | 53 | } |
90 | return irq; | ||
91 | |||
92 | } | 54 | } |
55 | |||
93 | /* | 56 | /* |
94 | * Initialize IRQ setting | 57 | * Initialize IRQ setting |
95 | */ | 58 | */ |
96 | void __init init_se7722_IRQ(void) | 59 | void __init init_se7722_IRQ(void) |
97 | { | 60 | { |
98 | int i = 0; | 61 | int i; |
62 | |||
63 | ctrl_outw(0, IRQ01_MASK); /* disable all irqs */ | ||
99 | ctrl_outw(0x2000, 0xb03fffec); /* mrshpc irq enable */ | 64 | ctrl_outw(0x2000, 0xb03fffec); /* mrshpc irq enable */ |
100 | ctrl_outl((3 << ((7 - 0) * 4))|(3 << ((7 - 1) * 4)), INTC_INTPRI0); /* irq0 pri=3,irq1,pri=3 */ | ||
101 | ctrl_outw((2 << ((7 - 0) * 2))|(2 << ((7 - 1) * 2)), INTC_ICR1); /* irq0,1 low-level irq */ | ||
102 | 65 | ||
103 | for (i = 0; i < ARRAY_SIZE(ipr_irq_table); i++) { | 66 | for (i = 0; i < SE7722_FPGA_IRQ_NR; i++) |
104 | disable_irq_nosync(ipr_irq_table[i].irq); | 67 | set_irq_chip_and_handler_name(SE7722_FPGA_IRQ_BASE + i, |
105 | set_irq_chip_and_handler_name( ipr_irq_table[i].irq, &se7722_irq_chip, | 68 | &se7722_irq_chip, |
106 | handle_level_irq, "level"); | 69 | handle_level_irq, "level"); |
107 | set_irq_chip_data( ipr_irq_table[i].irq, &ipr_irq_table[i] ); | 70 | |
108 | disable_se7722_irq(ipr_irq_table[i].irq); | 71 | set_irq_chained_handler(IRQ0_IRQ, se7722_irq_demux); |
109 | } | 72 | set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW); |
73 | |||
74 | set_irq_chained_handler(IRQ1_IRQ, se7722_irq_demux); | ||
75 | set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW); | ||
110 | } | 76 | } |
diff --git a/arch/sh/boards/se/7722/setup.c b/arch/sh/boards/se/7722/setup.c index 6cca6cbc8069..495fc7e2b60f 100644 --- a/arch/sh/boards/se/7722/setup.c +++ b/arch/sh/boards/se/7722/setup.c | |||
@@ -77,6 +77,7 @@ static struct resource cf_ide_resources[] = { | |||
77 | }, | 77 | }, |
78 | [2] = { | 78 | [2] = { |
79 | .start = MRSHPC_IRQ0, | 79 | .start = MRSHPC_IRQ0, |
80 | .end = MRSHPC_IRQ0, | ||
80 | .flags = IORESOURCE_IRQ, | 81 | .flags = IORESOURCE_IRQ, |
81 | }, | 82 | }, |
82 | }; | 83 | }; |
@@ -140,8 +141,6 @@ static void __init se7722_setup(char **cmdline_p) | |||
140 | static struct sh_machine_vector mv_se7722 __initmv = { | 141 | static struct sh_machine_vector mv_se7722 __initmv = { |
141 | .mv_name = "Solution Engine 7722" , | 142 | .mv_name = "Solution Engine 7722" , |
142 | .mv_setup = se7722_setup , | 143 | .mv_setup = se7722_setup , |
143 | .mv_nr_irqs = 109 , | 144 | .mv_nr_irqs = SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_NR, |
144 | .mv_init_irq = init_se7722_IRQ, | 145 | .mv_init_irq = init_se7722_IRQ, |
145 | .mv_irq_demux = se7722_irq_demux, | ||
146 | |||
147 | }; | 146 | }; |
diff --git a/arch/sh/cchips/hd6446x/Makefile b/arch/sh/cchips/hd6446x/Makefile new file mode 100644 index 000000000000..a106dd9db986 --- /dev/null +++ b/arch/sh/cchips/hd6446x/Makefile | |||
@@ -0,0 +1,2 @@ | |||
1 | obj-$(CONFIG_HD64461) += hd64461.o | ||
2 | obj-$(CONFIG_HD64465) += hd64465/ | ||
diff --git a/arch/sh/cchips/hd6446x/hd64461/setup.c b/arch/sh/cchips/hd6446x/hd64461.c index 4d49b5cbcc13..97f6512aa1b7 100644 --- a/arch/sh/cchips/hd6446x/hd64461/setup.c +++ b/arch/sh/cchips/hd6446x/hd64461.c | |||
@@ -1,5 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: setup.c,v 1.5 2004/03/16 00:07:50 lethal Exp $ | ||
3 | * Copyright (C) 2000 YAEGASHI Takeshi | 2 | * Copyright (C) 2000 YAEGASHI Takeshi |
4 | * Hitachi HD64461 companion chip support | 3 | * Hitachi HD64461 companion chip support |
5 | */ | 4 | */ |
diff --git a/arch/sh/cchips/hd6446x/hd64461/Makefile b/arch/sh/cchips/hd6446x/hd64461/Makefile deleted file mode 100644 index bff4b92e388c..000000000000 --- a/arch/sh/cchips/hd6446x/hd64461/Makefile +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | # | ||
2 | # Makefile for the HD64461 | ||
3 | # | ||
4 | |||
5 | obj-y := setup.o io.o | ||
6 | |||
diff --git a/arch/sh/cchips/hd6446x/hd64461/io.c b/arch/sh/cchips/hd6446x/hd64461/io.c deleted file mode 100644 index 7909a1b7b512..000000000000 --- a/arch/sh/cchips/hd6446x/hd64461/io.c +++ /dev/null | |||
@@ -1,150 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000 YAEGASHI Takeshi | ||
3 | * Typical I/O routines for HD64461 system. | ||
4 | */ | ||
5 | |||
6 | #include <asm/io.h> | ||
7 | #include <asm/hd64461.h> | ||
8 | |||
9 | #define MEM_BASE (CONFIG_HD64461_IOBASE - HD64461_STBCR) | ||
10 | |||
11 | static __inline__ unsigned long PORT2ADDR(unsigned long port) | ||
12 | { | ||
13 | /* 16550A: HD64461 internal */ | ||
14 | if (0x3f8<=port && port<=0x3ff) | ||
15 | return CONFIG_HD64461_IOBASE + 0x8000 + ((port-0x3f8)<<1); | ||
16 | if (0x2f8<=port && port<=0x2ff) | ||
17 | return CONFIG_HD64461_IOBASE + 0x7000 + ((port-0x2f8)<<1); | ||
18 | |||
19 | #ifdef CONFIG_HD64461_ENABLER | ||
20 | /* NE2000: HD64461 PCMCIA channel 0 (I/O) */ | ||
21 | if (0x300<=port && port<=0x31f) | ||
22 | return 0xba000000 + port; | ||
23 | |||
24 | /* ide0: HD64461 PCMCIA channel 1 (memory) */ | ||
25 | /* On HP690, CF in slot 1 is configured as a memory card | ||
26 | device. See CF+ and CompactFlash Specification for the | ||
27 | detail of CF's memory mapped addressing. */ | ||
28 | if (0x1f0<=port && port<=0x1f7) return 0xb5000000 + port; | ||
29 | if (port == 0x3f6) return 0xb50001fe; | ||
30 | if (port == 0x3f7) return 0xb50001ff; | ||
31 | |||
32 | /* ide1 */ | ||
33 | if (0x170<=port && port<=0x177) return 0xba000000 + port; | ||
34 | if (port == 0x376) return 0xba000376; | ||
35 | if (port == 0x377) return 0xba000377; | ||
36 | #endif | ||
37 | |||
38 | /* ??? */ | ||
39 | if (port < 0xf000) return 0xa0000000 + port; | ||
40 | /* PCMCIA channel 0, I/O (0xba000000) */ | ||
41 | if (port < 0x10000) return 0xba000000 + port - 0xf000; | ||
42 | |||
43 | /* HD64461 internal devices (0xb0000000) */ | ||
44 | if (port < 0x20000) return CONFIG_HD64461_IOBASE + port - 0x10000; | ||
45 | |||
46 | /* PCMCIA channel 0, I/O (0xba000000) */ | ||
47 | if (port < 0x30000) return 0xba000000 + port - 0x20000; | ||
48 | |||
49 | /* PCMCIA channel 1, memory (0xb5000000) */ | ||
50 | if (port < 0x40000) return 0xb5000000 + port - 0x30000; | ||
51 | |||
52 | /* Whole physical address space (0xa0000000) */ | ||
53 | return 0xa0000000 + (port & 0x1fffffff); | ||
54 | } | ||
55 | |||
56 | unsigned char hd64461_inb(unsigned long port) | ||
57 | { | ||
58 | return *(volatile unsigned char*)PORT2ADDR(port); | ||
59 | } | ||
60 | |||
61 | unsigned char hd64461_inb_p(unsigned long port) | ||
62 | { | ||
63 | unsigned long v = *(volatile unsigned char*)PORT2ADDR(port); | ||
64 | ctrl_delay(); | ||
65 | return v; | ||
66 | } | ||
67 | |||
68 | unsigned short hd64461_inw(unsigned long port) | ||
69 | { | ||
70 | return *(volatile unsigned short*)PORT2ADDR(port); | ||
71 | } | ||
72 | |||
73 | unsigned int hd64461_inl(unsigned long port) | ||
74 | { | ||
75 | return *(volatile unsigned long*)PORT2ADDR(port); | ||
76 | } | ||
77 | |||
78 | void hd64461_outb(unsigned char b, unsigned long port) | ||
79 | { | ||
80 | *(volatile unsigned char*)PORT2ADDR(port) = b; | ||
81 | } | ||
82 | |||
83 | void hd64461_outb_p(unsigned char b, unsigned long port) | ||
84 | { | ||
85 | *(volatile unsigned char*)PORT2ADDR(port) = b; | ||
86 | ctrl_delay(); | ||
87 | } | ||
88 | |||
89 | void hd64461_outw(unsigned short b, unsigned long port) | ||
90 | { | ||
91 | *(volatile unsigned short*)PORT2ADDR(port) = b; | ||
92 | } | ||
93 | |||
94 | void hd64461_outl(unsigned int b, unsigned long port) | ||
95 | { | ||
96 | *(volatile unsigned long*)PORT2ADDR(port) = b; | ||
97 | } | ||
98 | |||
99 | void hd64461_insb(unsigned long port, void *buffer, unsigned long count) | ||
100 | { | ||
101 | volatile unsigned char* addr=(volatile unsigned char*)PORT2ADDR(port); | ||
102 | unsigned char *buf=buffer; | ||
103 | while(count--) *buf++=*addr; | ||
104 | } | ||
105 | |||
106 | void hd64461_insw(unsigned long port, void *buffer, unsigned long count) | ||
107 | { | ||
108 | volatile unsigned short* addr=(volatile unsigned short*)PORT2ADDR(port); | ||
109 | unsigned short *buf=buffer; | ||
110 | while(count--) *buf++=*addr; | ||
111 | } | ||
112 | |||
113 | void hd64461_insl(unsigned long port, void *buffer, unsigned long count) | ||
114 | { | ||
115 | volatile unsigned long* addr=(volatile unsigned long*)PORT2ADDR(port); | ||
116 | unsigned long *buf=buffer; | ||
117 | while(count--) *buf++=*addr; | ||
118 | } | ||
119 | |||
120 | void hd64461_outsb(unsigned long port, const void *buffer, unsigned long count) | ||
121 | { | ||
122 | volatile unsigned char* addr=(volatile unsigned char*)PORT2ADDR(port); | ||
123 | const unsigned char *buf=buffer; | ||
124 | while(count--) *addr=*buf++; | ||
125 | } | ||
126 | |||
127 | void hd64461_outsw(unsigned long port, const void *buffer, unsigned long count) | ||
128 | { | ||
129 | volatile unsigned short* addr=(volatile unsigned short*)PORT2ADDR(port); | ||
130 | const unsigned short *buf=buffer; | ||
131 | while(count--) *addr=*buf++; | ||
132 | } | ||
133 | |||
134 | void hd64461_outsl(unsigned long port, const void *buffer, unsigned long count) | ||
135 | { | ||
136 | volatile unsigned long* addr=(volatile unsigned long*)PORT2ADDR(port); | ||
137 | const unsigned long *buf=buffer; | ||
138 | while(count--) *addr=*buf++; | ||
139 | } | ||
140 | |||
141 | unsigned short hd64461_readw(void __iomem *addr) | ||
142 | { | ||
143 | return ctrl_inw(MEM_BASE+(unsigned long __force)addr); | ||
144 | } | ||
145 | |||
146 | void hd64461_writew(unsigned short b, void __iomem *addr) | ||
147 | { | ||
148 | ctrl_outw(b, MEM_BASE+(unsigned long __force)addr); | ||
149 | } | ||
150 | |||
diff --git a/arch/sh/configs/landisk_defconfig b/arch/sh/configs/landisk_defconfig index e7f8ddb0ada4..07310fa03250 100644 --- a/arch/sh/configs/landisk_defconfig +++ b/arch/sh/configs/landisk_defconfig | |||
@@ -217,7 +217,7 @@ CONFIG_SH_FPU=y | |||
217 | # CONFIG_SH_DSP is not set | 217 | # CONFIG_SH_DSP is not set |
218 | # CONFIG_SH_STORE_QUEUES is not set | 218 | # CONFIG_SH_STORE_QUEUES is not set |
219 | CONFIG_CPU_HAS_INTEVT=y | 219 | CONFIG_CPU_HAS_INTEVT=y |
220 | CONFIG_CPU_HAS_IPR_IRQ=y | 220 | CONFIG_CPU_HAS_INTC_IRQ=y |
221 | CONFIG_CPU_HAS_SR_RB=y | 221 | CONFIG_CPU_HAS_SR_RB=y |
222 | CONFIG_CPU_HAS_PTEA=y | 222 | CONFIG_CPU_HAS_PTEA=y |
223 | 223 | ||
diff --git a/arch/sh/configs/lboxre2_defconfig b/arch/sh/configs/lboxre2_defconfig index be86414dcc87..fa09d68d057a 100644 --- a/arch/sh/configs/lboxre2_defconfig +++ b/arch/sh/configs/lboxre2_defconfig | |||
@@ -222,7 +222,7 @@ CONFIG_SH_FPU=y | |||
222 | # CONFIG_SH_DSP is not set | 222 | # CONFIG_SH_DSP is not set |
223 | # CONFIG_SH_STORE_QUEUES is not set | 223 | # CONFIG_SH_STORE_QUEUES is not set |
224 | CONFIG_CPU_HAS_INTEVT=y | 224 | CONFIG_CPU_HAS_INTEVT=y |
225 | CONFIG_CPU_HAS_IPR_IRQ=y | 225 | CONFIG_CPU_HAS_INTC_IRQ=y |
226 | CONFIG_CPU_HAS_SR_RB=y | 226 | CONFIG_CPU_HAS_SR_RB=y |
227 | CONFIG_CPU_HAS_PTEA=y | 227 | CONFIG_CPU_HAS_PTEA=y |
228 | 228 | ||
diff --git a/arch/sh/configs/r7780mp_defconfig b/arch/sh/configs/r7780mp_defconfig index 17f7402b31d8..ac4de4973b60 100644 --- a/arch/sh/configs/r7780mp_defconfig +++ b/arch/sh/configs/r7780mp_defconfig | |||
@@ -191,7 +191,7 @@ CONFIG_SH_FPU=y | |||
191 | CONFIG_SH_STORE_QUEUES=y | 191 | CONFIG_SH_STORE_QUEUES=y |
192 | CONFIG_SPECULATIVE_EXECUTION=y | 192 | CONFIG_SPECULATIVE_EXECUTION=y |
193 | CONFIG_CPU_HAS_INTEVT=y | 193 | CONFIG_CPU_HAS_INTEVT=y |
194 | CONFIG_CPU_HAS_INTC2_IRQ=y | 194 | CONFIG_CPU_HAS_INTC_IRQ=y |
195 | CONFIG_CPU_HAS_SR_RB=y | 195 | CONFIG_CPU_HAS_SR_RB=y |
196 | 196 | ||
197 | # | 197 | # |
diff --git a/arch/sh/configs/r7780rp_defconfig b/arch/sh/configs/r7780rp_defconfig index 48c6a2194c98..12cc01910cf8 100644 --- a/arch/sh/configs/r7780rp_defconfig +++ b/arch/sh/configs/r7780rp_defconfig | |||
@@ -241,7 +241,7 @@ CONFIG_SH_FPU=y | |||
241 | CONFIG_SH_STORE_QUEUES=y | 241 | CONFIG_SH_STORE_QUEUES=y |
242 | CONFIG_SPECULATIVE_EXECUTION=y | 242 | CONFIG_SPECULATIVE_EXECUTION=y |
243 | CONFIG_CPU_HAS_INTEVT=y | 243 | CONFIG_CPU_HAS_INTEVT=y |
244 | CONFIG_CPU_HAS_INTC2_IRQ=y | 244 | CONFIG_CPU_HAS_INTC_IRQ=y |
245 | CONFIG_CPU_HAS_SR_RB=y | 245 | CONFIG_CPU_HAS_SR_RB=y |
246 | 246 | ||
247 | # | 247 | # |
diff --git a/arch/sh/configs/rts7751r2d_defconfig b/arch/sh/configs/rts7751r2d_defconfig index a59bb78bd071..f1e979b1e495 100644 --- a/arch/sh/configs/rts7751r2d_defconfig +++ b/arch/sh/configs/rts7751r2d_defconfig | |||
@@ -155,7 +155,7 @@ CONFIG_CPU_SH4=y | |||
155 | # CONFIG_CPU_SUBTYPE_SH7091 is not set | 155 | # CONFIG_CPU_SUBTYPE_SH7091 is not set |
156 | # CONFIG_CPU_SUBTYPE_SH7750R is not set | 156 | # CONFIG_CPU_SUBTYPE_SH7750R is not set |
157 | # CONFIG_CPU_SUBTYPE_SH7750S is not set | 157 | # CONFIG_CPU_SUBTYPE_SH7750S is not set |
158 | CONFIG_CPU_SUBTYPE_SH7751=y | 158 | # CONFIG_CPU_SUBTYPE_SH7751 is not set |
159 | CONFIG_CPU_SUBTYPE_SH7751R=y | 159 | CONFIG_CPU_SUBTYPE_SH7751R=y |
160 | # CONFIG_CPU_SUBTYPE_SH7760 is not set | 160 | # CONFIG_CPU_SUBTYPE_SH7760 is not set |
161 | # CONFIG_CPU_SUBTYPE_SH4_202 is not set | 161 | # CONFIG_CPU_SUBTYPE_SH4_202 is not set |
@@ -218,7 +218,7 @@ CONFIG_SH_FPU=y | |||
218 | # CONFIG_SH_DSP is not set | 218 | # CONFIG_SH_DSP is not set |
219 | # CONFIG_SH_STORE_QUEUES is not set | 219 | # CONFIG_SH_STORE_QUEUES is not set |
220 | CONFIG_CPU_HAS_INTEVT=y | 220 | CONFIG_CPU_HAS_INTEVT=y |
221 | CONFIG_CPU_HAS_IPR_IRQ=y | 221 | CONFIG_CPU_HAS_INTC_IRQ=y |
222 | CONFIG_CPU_HAS_SR_RB=y | 222 | CONFIG_CPU_HAS_SR_RB=y |
223 | CONFIG_CPU_HAS_PTEA=y | 223 | CONFIG_CPU_HAS_PTEA=y |
224 | 224 | ||
@@ -280,7 +280,7 @@ CONFIG_ZERO_PAGE_OFFSET=0x00010000 | |||
280 | CONFIG_BOOT_LINK_OFFSET=0x00800000 | 280 | CONFIG_BOOT_LINK_OFFSET=0x00800000 |
281 | # CONFIG_UBC_WAKEUP is not set | 281 | # CONFIG_UBC_WAKEUP is not set |
282 | CONFIG_CMDLINE_BOOL=y | 282 | CONFIG_CMDLINE_BOOL=y |
283 | CONFIG_CMDLINE="console=tty0 console=ttySC0,115200 root=/dev/sda1" | 283 | CONFIG_CMDLINE="console=tty0 console=ttySC0,115200 root=/dev/sda1 earlyprintk=bios" |
284 | 284 | ||
285 | # | 285 | # |
286 | # Bus options | 286 | # Bus options |
@@ -1323,7 +1323,7 @@ CONFIG_ENABLE_MUST_CHECK=y | |||
1323 | # CONFIG_DEBUG_KERNEL is not set | 1323 | # CONFIG_DEBUG_KERNEL is not set |
1324 | CONFIG_LOG_BUF_SHIFT=14 | 1324 | CONFIG_LOG_BUF_SHIFT=14 |
1325 | # CONFIG_DEBUG_BUGVERBOSE is not set | 1325 | # CONFIG_DEBUG_BUGVERBOSE is not set |
1326 | # CONFIG_SH_STANDARD_BIOS is not set | 1326 | CONFIG_SH_STANDARD_BIOS=y |
1327 | CONFIG_EARLY_SCIF_CONSOLE=y | 1327 | CONFIG_EARLY_SCIF_CONSOLE=y |
1328 | CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffe80000 | 1328 | CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffe80000 |
1329 | CONFIG_EARLY_PRINTK=y | 1329 | CONFIG_EARLY_PRINTK=y |
diff --git a/arch/sh/configs/se7722_defconfig b/arch/sh/configs/se7722_defconfig index 764b813c4051..8e6a6baf5d27 100644 --- a/arch/sh/configs/se7722_defconfig +++ b/arch/sh/configs/se7722_defconfig | |||
@@ -200,7 +200,7 @@ CONFIG_CPU_LITTLE_ENDIAN=y | |||
200 | CONFIG_SH_DSP=y | 200 | CONFIG_SH_DSP=y |
201 | CONFIG_SH_STORE_QUEUES=y | 201 | CONFIG_SH_STORE_QUEUES=y |
202 | CONFIG_CPU_HAS_INTEVT=y | 202 | CONFIG_CPU_HAS_INTEVT=y |
203 | CONFIG_CPU_HAS_IPR_IRQ=y | 203 | CONFIG_CPU_HAS_INTC_IRQ=y |
204 | CONFIG_CPU_HAS_SR_RB=y | 204 | CONFIG_CPU_HAS_SR_RB=y |
205 | CONFIG_CPU_HAS_PTEA=y | 205 | CONFIG_CPU_HAS_PTEA=y |
206 | 206 | ||
@@ -565,7 +565,7 @@ CONFIG_SERIO_LIBPS2=y | |||
565 | # Non-8250 serial port support | 565 | # Non-8250 serial port support |
566 | # | 566 | # |
567 | CONFIG_SERIAL_SH_SCI=y | 567 | CONFIG_SERIAL_SH_SCI=y |
568 | CONFIG_SERIAL_SH_SCI_NR_UARTS=2 | 568 | CONFIG_SERIAL_SH_SCI_NR_UARTS=3 |
569 | CONFIG_SERIAL_SH_SCI_CONSOLE=y | 569 | CONFIG_SERIAL_SH_SCI_CONSOLE=y |
570 | CONFIG_SERIAL_CORE=y | 570 | CONFIG_SERIAL_CORE=y |
571 | CONFIG_SERIAL_CORE_CONSOLE=y | 571 | CONFIG_SERIAL_CORE_CONSOLE=y |
diff --git a/arch/sh/configs/se7750_defconfig b/arch/sh/configs/se7750_defconfig index 4e6e77fa4ce7..c60b6fd4fc42 100644 --- a/arch/sh/configs/se7750_defconfig +++ b/arch/sh/configs/se7750_defconfig | |||
@@ -226,7 +226,7 @@ CONFIG_SH_FPU=y | |||
226 | # CONFIG_SH_DSP is not set | 226 | # CONFIG_SH_DSP is not set |
227 | # CONFIG_SH_STORE_QUEUES is not set | 227 | # CONFIG_SH_STORE_QUEUES is not set |
228 | CONFIG_CPU_HAS_INTEVT=y | 228 | CONFIG_CPU_HAS_INTEVT=y |
229 | CONFIG_CPU_HAS_IPR_IRQ=y | 229 | CONFIG_CPU_HAS_INTC_IRQ=y |
230 | CONFIG_CPU_HAS_SR_RB=y | 230 | CONFIG_CPU_HAS_SR_RB=y |
231 | CONFIG_CPU_HAS_PTEA=y | 231 | CONFIG_CPU_HAS_PTEA=y |
232 | 232 | ||
diff --git a/arch/sh/configs/se7780_defconfig b/arch/sh/configs/se7780_defconfig index 538661e98793..f68743dc3931 100644 --- a/arch/sh/configs/se7780_defconfig +++ b/arch/sh/configs/se7780_defconfig | |||
@@ -218,6 +218,7 @@ CONFIG_SH_FPU=y | |||
218 | # CONFIG_SH_STORE_QUEUES is not set | 218 | # CONFIG_SH_STORE_QUEUES is not set |
219 | CONFIG_CPU_HAS_INTEVT=y | 219 | CONFIG_CPU_HAS_INTEVT=y |
220 | CONFIG_CPU_HAS_INTC2_IRQ=y | 220 | CONFIG_CPU_HAS_INTC2_IRQ=y |
221 | CONFIG_CPU_HAS_INTC_IRQ=y | ||
221 | CONFIG_CPU_HAS_SR_RB=y | 222 | CONFIG_CPU_HAS_SR_RB=y |
222 | 223 | ||
223 | # | 224 | # |
diff --git a/arch/sh/drivers/dma/Kconfig b/arch/sh/drivers/dma/Kconfig index 333898077c7c..ee711431e504 100644 --- a/arch/sh/drivers/dma/Kconfig +++ b/arch/sh/drivers/dma/Kconfig | |||
@@ -5,12 +5,13 @@ config SH_DMA_API | |||
5 | 5 | ||
6 | config SH_DMA | 6 | config SH_DMA |
7 | bool "SuperH on-chip DMA controller (DMAC) support" | 7 | bool "SuperH on-chip DMA controller (DMAC) support" |
8 | depends on CPU_SH3 || CPU_SH4 | ||
8 | select SH_DMA_API | 9 | select SH_DMA_API |
9 | default n | 10 | default n |
10 | 11 | ||
11 | config NR_ONCHIP_DMA_CHANNELS | 12 | config NR_ONCHIP_DMA_CHANNELS |
13 | int | ||
12 | depends on SH_DMA | 14 | depends on SH_DMA |
13 | int "Number of on-chip DMAC channels" | ||
14 | default "8" if CPU_SUBTYPE_SH7750R || CPU_SUBTYPE_SH7751R | 15 | default "8" if CPU_SUBTYPE_SH7750R || CPU_SUBTYPE_SH7751R |
15 | default "12" if CPU_SUBTYPE_SH7780 | 16 | default "12" if CPU_SUBTYPE_SH7780 |
16 | default "4" | 17 | default "4" |
diff --git a/arch/sh/drivers/heartbeat.c b/arch/sh/drivers/heartbeat.c index 23dd6080422f..10c1828c9ff5 100644 --- a/arch/sh/drivers/heartbeat.c +++ b/arch/sh/drivers/heartbeat.c | |||
@@ -78,7 +78,7 @@ static int heartbeat_drv_probe(struct platform_device *pdev) | |||
78 | hd->bit_pos[i] = i; | 78 | hd->bit_pos[i] = i; |
79 | } | 79 | } |
80 | 80 | ||
81 | hd->base = (void __iomem *)res->start; | 81 | hd->base = (void __iomem *)(unsigned long)res->start; |
82 | 82 | ||
83 | setup_timer(&hd->timer, heartbeat_timer, (unsigned long)hd); | 83 | setup_timer(&hd->timer, heartbeat_timer, (unsigned long)hd); |
84 | platform_set_drvdata(pdev, hd); | 84 | platform_set_drvdata(pdev, hd); |
diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile index 0e9b532b9fbc..2f65ac72f48a 100644 --- a/arch/sh/drivers/pci/Makefile +++ b/arch/sh/drivers/pci/Makefile | |||
@@ -7,6 +7,7 @@ obj-$(CONFIG_PCI_AUTO) += pci-auto.o | |||
7 | 7 | ||
8 | obj-$(CONFIG_CPU_SUBTYPE_ST40STB1) += pci-st40.o | 8 | obj-$(CONFIG_CPU_SUBTYPE_ST40STB1) += pci-st40.o |
9 | obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o ops-sh4.o | 9 | obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o ops-sh4.o |
10 | obj-$(CONFIG_CPU_SUBTYPE_SH7751R) += pci-sh7751.o ops-sh4.o | ||
10 | obj-$(CONFIG_CPU_SUBTYPE_SH7780) += pci-sh7780.o ops-sh4.o | 11 | obj-$(CONFIG_CPU_SUBTYPE_SH7780) += pci-sh7780.o ops-sh4.o |
11 | obj-$(CONFIG_CPU_SUBTYPE_SH7785) += pci-sh7780.o ops-sh4.o | 12 | obj-$(CONFIG_CPU_SUBTYPE_SH7785) += pci-sh7780.o ops-sh4.o |
12 | 13 | ||
diff --git a/arch/sh/drivers/pci/ops-sh4.c b/arch/sh/drivers/pci/ops-sh4.c index 54232f13e406..710a3b0306e5 100644 --- a/arch/sh/drivers/pci/ops-sh4.c +++ b/arch/sh/drivers/pci/ops-sh4.c | |||
@@ -153,7 +153,7 @@ static void __init pci_fixup_ide_bases(struct pci_dev *d) | |||
153 | } | 153 | } |
154 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); | 154 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); |
155 | 155 | ||
156 | char * __init pcibios_setup(char *str) | 156 | char * __devinit pcibios_setup(char *str) |
157 | { | 157 | { |
158 | if (!strcmp(str, "off")) { | 158 | if (!strcmp(str, "off")) { |
159 | pci_probe = 0; | 159 | pci_probe = 0; |
diff --git a/arch/sh/drivers/pci/pci-st40.c b/arch/sh/drivers/pci/pci-st40.c index 543417ff8314..1502a14386b6 100644 --- a/arch/sh/drivers/pci/pci-st40.c +++ b/arch/sh/drivers/pci/pci-st40.c | |||
@@ -328,7 +328,7 @@ int __init st40pci_init(unsigned memStart, unsigned memSize) | |||
328 | return 1; | 328 | return 1; |
329 | } | 329 | } |
330 | 330 | ||
331 | char * __init pcibios_setup(char *str) | 331 | char * __devinit pcibios_setup(char *str) |
332 | { | 332 | { |
333 | return str; | 333 | return str; |
334 | } | 334 | } |
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index d439336d2e18..ccaba368ac9b 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c | |||
@@ -71,7 +71,7 @@ subsys_initcall(pcibios_init); | |||
71 | * Called after each bus is probed, but before its children | 71 | * Called after each bus is probed, but before its children |
72 | * are examined. | 72 | * are examined. |
73 | */ | 73 | */ |
74 | void __init pcibios_fixup_bus(struct pci_bus *bus) | 74 | void __devinit pcibios_fixup_bus(struct pci_bus *bus) |
75 | { | 75 | { |
76 | pci_read_bridge_bases(bus); | 76 | pci_read_bridge_bases(bus); |
77 | } | 77 | } |
diff --git a/arch/sh/drivers/push-switch.c b/arch/sh/drivers/push-switch.c index b3d20c0e021f..725be6de589b 100644 --- a/arch/sh/drivers/push-switch.c +++ b/arch/sh/drivers/push-switch.c | |||
@@ -138,4 +138,4 @@ module_exit(switch_exit); | |||
138 | 138 | ||
139 | MODULE_VERSION(DRV_VERSION); | 139 | MODULE_VERSION(DRV_VERSION); |
140 | MODULE_AUTHOR("Paul Mundt"); | 140 | MODULE_AUTHOR("Paul Mundt"); |
141 | MODULE_LICENSE("GPLv2"); | 141 | MODULE_LICENSE("GPL v2"); |
diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index 63251549e9a8..92807ffa8e20 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c | |||
@@ -229,6 +229,22 @@ void clk_recalc_rate(struct clk *clk) | |||
229 | } | 229 | } |
230 | EXPORT_SYMBOL_GPL(clk_recalc_rate); | 230 | EXPORT_SYMBOL_GPL(clk_recalc_rate); |
231 | 231 | ||
232 | long clk_round_rate(struct clk *clk, unsigned long rate) | ||
233 | { | ||
234 | if (likely(clk->ops && clk->ops->round_rate)) { | ||
235 | unsigned long flags, rounded; | ||
236 | |||
237 | spin_lock_irqsave(&clock_lock, flags); | ||
238 | rounded = clk->ops->round_rate(clk, rate); | ||
239 | spin_unlock_irqrestore(&clock_lock, flags); | ||
240 | |||
241 | return rounded; | ||
242 | } | ||
243 | |||
244 | return clk_get_rate(clk); | ||
245 | } | ||
246 | EXPORT_SYMBOL_GPL(clk_round_rate); | ||
247 | |||
232 | /* | 248 | /* |
233 | * Returns a clock. Note that we first try to use device id on the bus | 249 | * Returns a clock. Note that we first try to use device id on the bus |
234 | * and clock name. If this fails, we try to use clock name only. | 250 | * and clock name. If this fails, we try to use clock name only. |
diff --git a/arch/sh/kernel/cpu/irq/Makefile b/arch/sh/kernel/cpu/irq/Makefile index 1c23308cfc25..9ddb446ac930 100644 --- a/arch/sh/kernel/cpu/irq/Makefile +++ b/arch/sh/kernel/cpu/irq/Makefile | |||
@@ -6,4 +6,5 @@ obj-y += imask.o | |||
6 | obj-$(CONFIG_CPU_HAS_IPR_IRQ) += ipr.o | 6 | obj-$(CONFIG_CPU_HAS_IPR_IRQ) += ipr.o |
7 | obj-$(CONFIG_CPU_HAS_PINT_IRQ) += pint.o | 7 | obj-$(CONFIG_CPU_HAS_PINT_IRQ) += pint.o |
8 | obj-$(CONFIG_CPU_HAS_MASKREG_IRQ) += maskreg.o | 8 | obj-$(CONFIG_CPU_HAS_MASKREG_IRQ) += maskreg.o |
9 | obj-$(CONFIG_CPU_HAS_INTC_IRQ) += intc.o | ||
9 | obj-$(CONFIG_CPU_HAS_INTC2_IRQ) += intc2.o | 10 | obj-$(CONFIG_CPU_HAS_INTC2_IRQ) += intc2.o |
diff --git a/arch/sh/kernel/cpu/irq/intc.c b/arch/sh/kernel/cpu/irq/intc.c new file mode 100644 index 000000000000..9345a7130e9e --- /dev/null +++ b/arch/sh/kernel/cpu/irq/intc.c | |||
@@ -0,0 +1,405 @@ | |||
1 | /* | ||
2 | * Shared interrupt handling code for IPR and INTC2 types of IRQs. | ||
3 | * | ||
4 | * Copyright (C) 2007 Magnus Damm | ||
5 | * | ||
6 | * Based on intc2.c and ipr.c | ||
7 | * | ||
8 | * Copyright (C) 1999 Niibe Yutaka & Takeshi Yaegashi | ||
9 | * Copyright (C) 2000 Kazumoto Kojima | ||
10 | * Copyright (C) 2001 David J. Mckay (david.mckay@st.com) | ||
11 | * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp> | ||
12 | * Copyright (C) 2005, 2006 Paul Mundt | ||
13 | * | ||
14 | * This file is subject to the terms and conditions of the GNU General Public | ||
15 | * License. See the file "COPYING" in the main directory of this archive | ||
16 | * for more details. | ||
17 | */ | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/irq.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/io.h> | ||
22 | #include <linux/interrupt.h> | ||
23 | |||
24 | #define _INTC_MK(fn, idx, bit, value) \ | ||
25 | ((fn) << 24 | ((value) << 16) | ((idx) << 8) | (bit)) | ||
26 | #define _INTC_FN(h) (h >> 24) | ||
27 | #define _INTC_VALUE(h) ((h >> 16) & 0xff) | ||
28 | #define _INTC_IDX(h) ((h >> 8) & 0xff) | ||
29 | #define _INTC_BIT(h) (h & 0xff) | ||
30 | |||
31 | #define _INTC_PTR(desc, member, data) \ | ||
32 | (desc->member + _INTC_IDX(data)) | ||
33 | |||
34 | static inline struct intc_desc *get_intc_desc(unsigned int irq) | ||
35 | { | ||
36 | struct irq_chip *chip = get_irq_chip(irq); | ||
37 | return (void *)((char *)chip - offsetof(struct intc_desc, chip)); | ||
38 | } | ||
39 | |||
40 | static inline unsigned int set_field(unsigned int value, | ||
41 | unsigned int field_value, | ||
42 | unsigned int width, | ||
43 | unsigned int shift) | ||
44 | { | ||
45 | value &= ~(((1 << width) - 1) << shift); | ||
46 | value |= field_value << shift; | ||
47 | return value; | ||
48 | } | ||
49 | |||
50 | static inline unsigned int set_prio_field(struct intc_desc *desc, | ||
51 | unsigned int value, | ||
52 | unsigned int priority, | ||
53 | unsigned int data) | ||
54 | { | ||
55 | unsigned int width = _INTC_PTR(desc, prio_regs, data)->field_width; | ||
56 | |||
57 | return set_field(value, priority, width, _INTC_BIT(data)); | ||
58 | } | ||
59 | |||
60 | static void disable_prio_16(struct intc_desc *desc, unsigned int data) | ||
61 | { | ||
62 | unsigned long addr = _INTC_PTR(desc, prio_regs, data)->reg; | ||
63 | |||
64 | ctrl_outw(set_prio_field(desc, ctrl_inw(addr), 0, data), addr); | ||
65 | } | ||
66 | |||
67 | static void enable_prio_16(struct intc_desc *desc, unsigned int data) | ||
68 | { | ||
69 | unsigned long addr = _INTC_PTR(desc, prio_regs, data)->reg; | ||
70 | unsigned int prio = _INTC_VALUE(data); | ||
71 | |||
72 | ctrl_outw(set_prio_field(desc, ctrl_inw(addr), prio, data), addr); | ||
73 | } | ||
74 | |||
75 | static void disable_prio_32(struct intc_desc *desc, unsigned int data) | ||
76 | { | ||
77 | unsigned long addr = _INTC_PTR(desc, prio_regs, data)->reg; | ||
78 | |||
79 | ctrl_outl(set_prio_field(desc, ctrl_inl(addr), 0, data), addr); | ||
80 | } | ||
81 | |||
82 | static void enable_prio_32(struct intc_desc *desc, unsigned int data) | ||
83 | { | ||
84 | unsigned long addr = _INTC_PTR(desc, prio_regs, data)->reg; | ||
85 | unsigned int prio = _INTC_VALUE(data); | ||
86 | |||
87 | ctrl_outl(set_prio_field(desc, ctrl_inl(addr), prio, data), addr); | ||
88 | } | ||
89 | |||
90 | static void disable_mask_8(struct intc_desc *desc, unsigned int data) | ||
91 | { | ||
92 | ctrl_outb(1 << _INTC_BIT(data), | ||
93 | _INTC_PTR(desc, mask_regs, data)->set_reg); | ||
94 | } | ||
95 | |||
96 | static void enable_mask_8(struct intc_desc *desc, unsigned int data) | ||
97 | { | ||
98 | ctrl_outb(1 << _INTC_BIT(data), | ||
99 | _INTC_PTR(desc, mask_regs, data)->clr_reg); | ||
100 | } | ||
101 | |||
102 | static void disable_mask_32(struct intc_desc *desc, unsigned int data) | ||
103 | { | ||
104 | ctrl_outl(1 << _INTC_BIT(data), | ||
105 | _INTC_PTR(desc, mask_regs, data)->set_reg); | ||
106 | } | ||
107 | |||
108 | static void enable_mask_32(struct intc_desc *desc, unsigned int data) | ||
109 | { | ||
110 | ctrl_outl(1 << _INTC_BIT(data), | ||
111 | _INTC_PTR(desc, mask_regs, data)->clr_reg); | ||
112 | } | ||
113 | |||
114 | enum { REG_FN_ERROR=0, | ||
115 | REG_FN_MASK_8, REG_FN_MASK_32, | ||
116 | REG_FN_PRIO_16, REG_FN_PRIO_32 }; | ||
117 | |||
118 | static struct { | ||
119 | void (*enable)(struct intc_desc *, unsigned int); | ||
120 | void (*disable)(struct intc_desc *, unsigned int); | ||
121 | } intc_reg_fns[] = { | ||
122 | [REG_FN_MASK_8] = { enable_mask_8, disable_mask_8 }, | ||
123 | [REG_FN_MASK_32] = { enable_mask_32, disable_mask_32 }, | ||
124 | [REG_FN_PRIO_16] = { enable_prio_16, disable_prio_16 }, | ||
125 | [REG_FN_PRIO_32] = { enable_prio_32, disable_prio_32 }, | ||
126 | }; | ||
127 | |||
128 | static void intc_enable(unsigned int irq) | ||
129 | { | ||
130 | struct intc_desc *desc = get_intc_desc(irq); | ||
131 | unsigned int data = (unsigned int) get_irq_chip_data(irq); | ||
132 | |||
133 | intc_reg_fns[_INTC_FN(data)].enable(desc, data); | ||
134 | } | ||
135 | |||
136 | static void intc_disable(unsigned int irq) | ||
137 | { | ||
138 | struct intc_desc *desc = get_intc_desc(irq); | ||
139 | unsigned int data = (unsigned int) get_irq_chip_data(irq); | ||
140 | |||
141 | intc_reg_fns[_INTC_FN(data)].disable(desc, data); | ||
142 | } | ||
143 | |||
144 | static void set_sense_16(struct intc_desc *desc, unsigned int data) | ||
145 | { | ||
146 | unsigned long addr = _INTC_PTR(desc, sense_regs, data)->reg; | ||
147 | unsigned int width = _INTC_PTR(desc, sense_regs, data)->field_width; | ||
148 | unsigned int bit = _INTC_BIT(data); | ||
149 | unsigned int value = _INTC_VALUE(data); | ||
150 | |||
151 | ctrl_outw(set_field(ctrl_inw(addr), value, width, bit), addr); | ||
152 | } | ||
153 | |||
154 | static void set_sense_32(struct intc_desc *desc, unsigned int data) | ||
155 | { | ||
156 | unsigned long addr = _INTC_PTR(desc, sense_regs, data)->reg; | ||
157 | unsigned int width = _INTC_PTR(desc, sense_regs, data)->field_width; | ||
158 | unsigned int bit = _INTC_BIT(data); | ||
159 | unsigned int value = _INTC_VALUE(data); | ||
160 | |||
161 | ctrl_outl(set_field(ctrl_inl(addr), value, width, bit), addr); | ||
162 | } | ||
163 | |||
164 | #define VALID(x) (x | 0x80) | ||
165 | |||
166 | static unsigned char intc_irq_sense_table[IRQ_TYPE_SENSE_MASK + 1] = { | ||
167 | [IRQ_TYPE_EDGE_FALLING] = VALID(0), | ||
168 | [IRQ_TYPE_EDGE_RISING] = VALID(1), | ||
169 | [IRQ_TYPE_LEVEL_LOW] = VALID(2), | ||
170 | [IRQ_TYPE_LEVEL_HIGH] = VALID(3), | ||
171 | }; | ||
172 | |||
173 | static int intc_set_sense(unsigned int irq, unsigned int type) | ||
174 | { | ||
175 | struct intc_desc *desc = get_intc_desc(irq); | ||
176 | unsigned char value = intc_irq_sense_table[type & IRQ_TYPE_SENSE_MASK]; | ||
177 | unsigned int i, j, data, bit; | ||
178 | intc_enum enum_id = 0; | ||
179 | |||
180 | for (i = 0; i < desc->nr_vectors; i++) { | ||
181 | struct intc_vect *vect = desc->vectors + i; | ||
182 | |||
183 | if (evt2irq(vect->vect) != irq) | ||
184 | continue; | ||
185 | |||
186 | enum_id = vect->enum_id; | ||
187 | break; | ||
188 | } | ||
189 | |||
190 | if (!enum_id || !value) | ||
191 | return -EINVAL; | ||
192 | |||
193 | value ^= VALID(0); | ||
194 | |||
195 | for (i = 0; i < desc->nr_sense_regs; i++) { | ||
196 | struct intc_sense_reg *sr = desc->sense_regs + i; | ||
197 | |||
198 | for (j = 0; j < ARRAY_SIZE(sr->enum_ids); j++) { | ||
199 | if (sr->enum_ids[j] != enum_id) | ||
200 | continue; | ||
201 | |||
202 | bit = sr->reg_width - ((j + 1) * sr->field_width); | ||
203 | data = _INTC_MK(0, i, bit, value); | ||
204 | |||
205 | switch(sr->reg_width) { | ||
206 | case 16: | ||
207 | set_sense_16(desc, data); | ||
208 | break; | ||
209 | case 32: | ||
210 | set_sense_32(desc, data); | ||
211 | break; | ||
212 | } | ||
213 | |||
214 | return 0; | ||
215 | } | ||
216 | } | ||
217 | |||
218 | return -EINVAL; | ||
219 | } | ||
220 | |||
221 | static unsigned int __init intc_find_mask_handler(unsigned int width) | ||
222 | { | ||
223 | switch (width) { | ||
224 | case 8: | ||
225 | return REG_FN_MASK_8; | ||
226 | case 32: | ||
227 | return REG_FN_MASK_32; | ||
228 | } | ||
229 | |||
230 | BUG(); | ||
231 | return REG_FN_ERROR; | ||
232 | } | ||
233 | |||
234 | static unsigned int __init intc_find_prio_handler(unsigned int width) | ||
235 | { | ||
236 | switch (width) { | ||
237 | case 16: | ||
238 | return REG_FN_PRIO_16; | ||
239 | case 32: | ||
240 | return REG_FN_PRIO_32; | ||
241 | } | ||
242 | |||
243 | BUG(); | ||
244 | return REG_FN_ERROR; | ||
245 | } | ||
246 | |||
247 | static intc_enum __init intc_grp_id(struct intc_desc *desc, intc_enum enum_id) | ||
248 | { | ||
249 | struct intc_group *g = desc->groups; | ||
250 | unsigned int i, j; | ||
251 | |||
252 | for (i = 0; g && enum_id && i < desc->nr_groups; i++) { | ||
253 | g = desc->groups + i; | ||
254 | |||
255 | for (j = 0; g->enum_ids[j]; j++) { | ||
256 | if (g->enum_ids[j] != enum_id) | ||
257 | continue; | ||
258 | |||
259 | return g->enum_id; | ||
260 | } | ||
261 | } | ||
262 | |||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | static unsigned int __init intc_prio_value(struct intc_desc *desc, | ||
267 | intc_enum enum_id, int do_grps) | ||
268 | { | ||
269 | struct intc_prio *p = desc->priorities; | ||
270 | unsigned int i; | ||
271 | |||
272 | for (i = 0; p && enum_id && i < desc->nr_priorities; i++) { | ||
273 | p = desc->priorities + i; | ||
274 | |||
275 | if (p->enum_id != enum_id) | ||
276 | continue; | ||
277 | |||
278 | return p->priority; | ||
279 | } | ||
280 | |||
281 | if (do_grps) | ||
282 | return intc_prio_value(desc, intc_grp_id(desc, enum_id), 0); | ||
283 | |||
284 | /* default to the lowest priority possible if no priority is set | ||
285 | * - this needs to be at least 2 for 5-bit priorities on 7780 | ||
286 | */ | ||
287 | |||
288 | return 2; | ||
289 | } | ||
290 | |||
291 | static unsigned int __init intc_mask_data(struct intc_desc *desc, | ||
292 | intc_enum enum_id, int do_grps) | ||
293 | { | ||
294 | struct intc_mask_reg *mr = desc->mask_regs; | ||
295 | unsigned int i, j, fn; | ||
296 | |||
297 | for (i = 0; mr && enum_id && i < desc->nr_mask_regs; i++) { | ||
298 | mr = desc->mask_regs + i; | ||
299 | |||
300 | for (j = 0; j < ARRAY_SIZE(mr->enum_ids); j++) { | ||
301 | if (mr->enum_ids[j] != enum_id) | ||
302 | continue; | ||
303 | |||
304 | fn = intc_find_mask_handler(mr->reg_width); | ||
305 | if (fn == REG_FN_ERROR) | ||
306 | return 0; | ||
307 | |||
308 | return _INTC_MK(fn, i, (mr->reg_width - 1) - j, 0); | ||
309 | } | ||
310 | } | ||
311 | |||
312 | if (do_grps) | ||
313 | return intc_mask_data(desc, intc_grp_id(desc, enum_id), 0); | ||
314 | |||
315 | return 0; | ||
316 | } | ||
317 | |||
318 | static unsigned int __init intc_prio_data(struct intc_desc *desc, | ||
319 | intc_enum enum_id, int do_grps) | ||
320 | { | ||
321 | struct intc_prio_reg *pr = desc->prio_regs; | ||
322 | unsigned int i, j, fn, bit, prio; | ||
323 | |||
324 | for (i = 0; pr && enum_id && i < desc->nr_prio_regs; i++) { | ||
325 | pr = desc->prio_regs + i; | ||
326 | |||
327 | for (j = 0; j < ARRAY_SIZE(pr->enum_ids); j++) { | ||
328 | if (pr->enum_ids[j] != enum_id) | ||
329 | continue; | ||
330 | |||
331 | fn = intc_find_prio_handler(pr->reg_width); | ||
332 | if (fn == REG_FN_ERROR) | ||
333 | return 0; | ||
334 | |||
335 | prio = intc_prio_value(desc, enum_id, 1); | ||
336 | bit = pr->reg_width - ((j + 1) * pr->field_width); | ||
337 | |||
338 | BUG_ON(bit < 0); | ||
339 | |||
340 | return _INTC_MK(fn, i, bit, prio); | ||
341 | } | ||
342 | } | ||
343 | |||
344 | if (do_grps) | ||
345 | return intc_prio_data(desc, intc_grp_id(desc, enum_id), 0); | ||
346 | |||
347 | return 0; | ||
348 | } | ||
349 | |||
350 | static void __init intc_register_irq(struct intc_desc *desc, intc_enum enum_id, | ||
351 | unsigned int irq) | ||
352 | { | ||
353 | unsigned int data[2], primary; | ||
354 | |||
355 | /* Prefer single interrupt source bitmap over other combinations: | ||
356 | * 1. bitmap, single interrupt source | ||
357 | * 2. priority, single interrupt source | ||
358 | * 3. bitmap, multiple interrupt sources (groups) | ||
359 | * 4. priority, multiple interrupt sources (groups) | ||
360 | */ | ||
361 | |||
362 | data[0] = intc_mask_data(desc, enum_id, 0); | ||
363 | data[1] = intc_prio_data(desc, enum_id, 0); | ||
364 | |||
365 | primary = 0; | ||
366 | if (!data[0] && data[1]) | ||
367 | primary = 1; | ||
368 | |||
369 | data[0] = data[0] ? data[0] : intc_mask_data(desc, enum_id, 1); | ||
370 | data[1] = data[1] ? data[1] : intc_prio_data(desc, enum_id, 1); | ||
371 | |||
372 | if (!data[primary]) | ||
373 | primary ^= 1; | ||
374 | |||
375 | BUG_ON(!data[primary]); /* must have primary masking method */ | ||
376 | |||
377 | disable_irq_nosync(irq); | ||
378 | set_irq_chip_and_handler_name(irq, &desc->chip, | ||
379 | handle_level_irq, "level"); | ||
380 | set_irq_chip_data(irq, (void *)data[primary]); | ||
381 | |||
382 | /* enable secondary masking method if present */ | ||
383 | if (data[!primary]) | ||
384 | intc_reg_fns[_INTC_FN(data[!primary])].enable(desc, | ||
385 | data[!primary]); | ||
386 | |||
387 | /* irq should be disabled by default */ | ||
388 | desc->chip.mask(irq); | ||
389 | } | ||
390 | |||
391 | void __init register_intc_controller(struct intc_desc *desc) | ||
392 | { | ||
393 | unsigned int i; | ||
394 | |||
395 | desc->chip.mask = intc_disable; | ||
396 | desc->chip.unmask = intc_enable; | ||
397 | desc->chip.mask_ack = intc_disable; | ||
398 | desc->chip.set_type = intc_set_sense; | ||
399 | |||
400 | for (i = 0; i < desc->nr_vectors; i++) { | ||
401 | struct intc_vect *vect = desc->vectors + i; | ||
402 | |||
403 | intc_register_irq(desc, vect->enum_id, evt2irq(vect->vect)); | ||
404 | } | ||
405 | } | ||
diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c index 1a107fe22dde..a979b981e6a3 100644 --- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c +++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c | |||
@@ -88,7 +88,7 @@ static struct ipr_desc ipr_irq_desc = { | |||
88 | }, | 88 | }, |
89 | }; | 89 | }; |
90 | 90 | ||
91 | void __init init_IRQ_ipr(void) | 91 | void __init plat_irq_setup(void) |
92 | { | 92 | { |
93 | register_ipr_controller(&ipr_irq_desc); | 93 | register_ipr_controller(&ipr_irq_desc); |
94 | } | 94 | } |
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c index b6e3a6351fa6..deab16500167 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c | |||
@@ -107,7 +107,7 @@ static struct ipr_desc ipr_irq_desc = { | |||
107 | }, | 107 | }, |
108 | }; | 108 | }; |
109 | 109 | ||
110 | void __init init_IRQ_ipr(void) | 110 | void __init plat_irq_setup(void) |
111 | { | 111 | { |
112 | register_ipr_controller(&ipr_irq_desc); | 112 | register_ipr_controller(&ipr_irq_desc); |
113 | } | 113 | } |
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c index a55b8ce2c54c..ebd9d06d8bdd 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c | |||
@@ -92,7 +92,7 @@ static struct ipr_desc ipr_irq_desc = { | |||
92 | }, | 92 | }, |
93 | }; | 93 | }; |
94 | 94 | ||
95 | void __init init_IRQ_ipr(void) | 95 | void __init plat_irq_setup(void) |
96 | { | 96 | { |
97 | register_ipr_controller(&ipr_irq_desc); | 97 | register_ipr_controller(&ipr_irq_desc); |
98 | } | 98 | } |
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7709.c b/arch/sh/kernel/cpu/sh3/setup-sh7709.c index d79ec0c0522f..086f8e2545af 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7709.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7709.c | |||
@@ -139,7 +139,7 @@ static struct ipr_desc ipr_irq_desc = { | |||
139 | }, | 139 | }, |
140 | }; | 140 | }; |
141 | 141 | ||
142 | void __init init_IRQ_ipr(void) | 142 | void __init plat_irq_setup(void) |
143 | { | 143 | { |
144 | register_ipr_controller(&ipr_irq_desc); | 144 | register_ipr_controller(&ipr_irq_desc); |
145 | } | 145 | } |
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c index f40e6dac337d..132284893373 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c | |||
@@ -101,7 +101,7 @@ static struct ipr_desc ipr_irq_desc = { | |||
101 | }, | 101 | }, |
102 | }; | 102 | }; |
103 | 103 | ||
104 | void __init init_IRQ_ipr(void) | 104 | void __init plat_irq_setup(void) |
105 | { | 105 | { |
106 | register_ipr_controller(&ipr_irq_desc); | 106 | register_ipr_controller(&ipr_irq_desc); |
107 | } | 107 | } |
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index da153bcdfeb2..f2286de22bd5 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c | |||
@@ -82,88 +82,213 @@ static int __init sh7750_devices_setup(void) | |||
82 | } | 82 | } |
83 | __initcall(sh7750_devices_setup); | 83 | __initcall(sh7750_devices_setup); |
84 | 84 | ||
85 | static struct ipr_data ipr_irq_table[] = { | 85 | enum { |
86 | /* IRQ, IPR-idx, shift, priority */ | 86 | UNUSED = 0, |
87 | { 16, 0, 12, 2 }, /* TMU0 TUNI*/ | 87 | |
88 | { 17, 0, 12, 2 }, /* TMU1 TUNI */ | 88 | /* interrupt sources */ |
89 | { 18, 0, 4, 2 }, /* TMU2 TUNI */ | 89 | IRL0, IRL1, IRL2, IRL3, /* only IRLM mode supported */ |
90 | { 19, 0, 4, 2 }, /* TMU2 TIPCI */ | 90 | HUDI, GPIOI, |
91 | { 27, 1, 12, 2 }, /* WDT ITI */ | 91 | DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, DMAC_DMTE3, |
92 | { 20, 0, 0, 2 }, /* RTC ATI (alarm) */ | 92 | DMAC_DMTE4, DMAC_DMTE5, DMAC_DMTE6, DMAC_DMTE7, |
93 | { 21, 0, 0, 2 }, /* RTC PRI (period) */ | 93 | DMAC_DMAE, |
94 | { 22, 0, 0, 2 }, /* RTC CUI (carry) */ | 94 | PCIC0_PCISERR, PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON, |
95 | { 23, 1, 4, 3 }, /* SCI ERI */ | 95 | PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3, |
96 | { 24, 1, 4, 3 }, /* SCI RXI */ | 96 | TMU3, TMU4, TMU0, TMU1, TMU2_TUNI, TMU2_TICPI, |
97 | { 25, 1, 4, 3 }, /* SCI TXI */ | 97 | RTC_ATI, RTC_PRI, RTC_CUI, |
98 | { 40, 2, 4, 3 }, /* SCIF ERI */ | 98 | SCI1_ERI, SCI1_RXI, SCI1_TXI, SCI1_TEI, |
99 | { 41, 2, 4, 3 }, /* SCIF RXI */ | 99 | SCIF_ERI, SCIF_RXI, SCIF_BRI, SCIF_TXI, |
100 | { 42, 2, 4, 3 }, /* SCIF BRI */ | 100 | WDT, |
101 | { 43, 2, 4, 3 }, /* SCIF TXI */ | 101 | REF_RCMI, REF_ROVI, |
102 | { 34, 2, 8, 7 }, /* DMAC DMTE0 */ | 102 | |
103 | { 35, 2, 8, 7 }, /* DMAC DMTE1 */ | 103 | /* interrupt groups */ |
104 | { 36, 2, 8, 7 }, /* DMAC DMTE2 */ | 104 | DMAC, PCIC1, TMU2, RTC, SCI1, SCIF, REF, |
105 | { 37, 2, 8, 7 }, /* DMAC DMTE3 */ | ||
106 | { 38, 2, 8, 7 }, /* DMAC DMAE */ | ||
107 | }; | ||
108 | |||
109 | static unsigned long ipr_offsets[] = { | ||
110 | 0xffd00004UL, /* 0: IPRA */ | ||
111 | 0xffd00008UL, /* 1: IPRB */ | ||
112 | 0xffd0000cUL, /* 2: IPRC */ | ||
113 | 0xffd00010UL, /* 3: IPRD */ | ||
114 | }; | ||
115 | |||
116 | static struct ipr_desc ipr_irq_desc = { | ||
117 | .ipr_offsets = ipr_offsets, | ||
118 | .nr_offsets = ARRAY_SIZE(ipr_offsets), | ||
119 | |||
120 | .ipr_data = ipr_irq_table, | ||
121 | .nr_irqs = ARRAY_SIZE(ipr_irq_table), | ||
122 | |||
123 | .chip = { | ||
124 | .name = "IPR-sh7750", | ||
125 | }, | ||
126 | }; | 105 | }; |
127 | 106 | ||
128 | #ifdef CONFIG_CPU_SUBTYPE_SH7751 | 107 | static struct intc_vect vectors[] = { |
129 | static struct ipr_data ipr_irq_table_sh7751[] = { | 108 | INTC_VECT(HUDI, 0x600), INTC_VECT(GPIOI, 0x620), |
130 | { 44, 2, 8, 7 }, /* DMAC DMTE4 */ | 109 | INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420), |
131 | { 45, 2, 8, 7 }, /* DMAC DMTE5 */ | 110 | INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460), |
132 | { 46, 2, 8, 7 }, /* DMAC DMTE6 */ | 111 | INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0), |
133 | { 47, 2, 8, 7 }, /* DMAC DMTE7 */ | 112 | INTC_VECT(RTC_CUI, 0x4c0), |
134 | /* The following use INTC_INPRI00 for masking, which is a 32-bit | 113 | INTC_VECT(SCI1_ERI, 0x4e0), INTC_VECT(SCI1_RXI, 0x500), |
135 | register, not a 16-bit register like the IPRx registers, so it | 114 | INTC_VECT(SCI1_TXI, 0x520), INTC_VECT(SCI1_TEI, 0x540), |
136 | would need special support */ | 115 | INTC_VECT(SCIF_ERI, 0x700), INTC_VECT(SCIF_RXI, 0x720), |
137 | /*{ 72, INTPRI00, 8, ? },*/ /* TMU3 TUNI */ | 116 | INTC_VECT(SCIF_BRI, 0x740), INTC_VECT(SCIF_TXI, 0x760), |
138 | /*{ 76, INTPRI00, 12, ? },*/ /* TMU4 TUNI */ | 117 | INTC_VECT(WDT, 0x560), |
118 | INTC_VECT(REF_RCMI, 0x580), INTC_VECT(REF_ROVI, 0x5a0), | ||
139 | }; | 119 | }; |
140 | 120 | ||
141 | static struct ipr_desc ipr_irq_desc_sh7751 = { | 121 | static struct intc_group groups[] = { |
142 | .ipr_offsets = ipr_offsets, | 122 | INTC_GROUP(TMU2, TMU2_TUNI, TMU2_TICPI), |
143 | .nr_offsets = ARRAY_SIZE(ipr_offsets), | 123 | INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI), |
124 | INTC_GROUP(SCI1, SCI1_ERI, SCI1_RXI, SCI1_TXI, SCI1_TEI), | ||
125 | INTC_GROUP(SCIF, SCIF_ERI, SCIF_RXI, SCIF_BRI, SCIF_TXI), | ||
126 | INTC_GROUP(REF, REF_RCMI, REF_ROVI), | ||
127 | }; | ||
144 | 128 | ||
145 | .ipr_data = ipr_irq_table_sh7751, | 129 | static struct intc_prio priorities[] = { |
146 | .nr_irqs = ARRAY_SIZE(ipr_irq_table_sh7751), | 130 | INTC_PRIO(SCIF, 3), |
131 | INTC_PRIO(SCI1, 3), | ||
132 | INTC_PRIO(DMAC, 7), | ||
133 | }; | ||
147 | 134 | ||
148 | .chip = { | 135 | static struct intc_prio_reg prio_registers[] = { |
149 | .name = "IPR-sh7751", | 136 | { 0xffd00004, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, |
150 | }, | 137 | { 0xffd00008, 16, 4, /* IPRB */ { WDT, REF, SCI1, 0 } }, |
138 | { 0xffd0000c, 16, 4, /* IPRC */ { GPIOI, DMAC, SCIF, HUDI } }, | ||
139 | { 0xffd00010, 16, 4, /* IPRD */ { IRL0, IRL1, IRL2, IRL3 } }, | ||
140 | { 0xfe080000, 32, 4, /* INTPRI00 */ { 0, 0, 0, 0, | ||
141 | TMU4, TMU3, | ||
142 | PCIC1, PCIC0_PCISERR } }, | ||
143 | }; | ||
144 | |||
145 | static DECLARE_INTC_DESC(intc_desc, "sh7750", vectors, groups, | ||
146 | priorities, NULL, prio_registers, NULL); | ||
147 | |||
148 | /* SH7750, SH7750S, SH7751 and SH7091 all have 4-channel DMA controllers */ | ||
149 | #if defined(CONFIG_CPU_SUBTYPE_SH7750) || \ | ||
150 | defined(CONFIG_CPU_SUBTYPE_SH7750S) || \ | ||
151 | defined(CONFIG_CPU_SUBTYPE_SH7751) || \ | ||
152 | defined(CONFIG_CPU_SUBTYPE_SH7091) | ||
153 | static struct intc_vect vectors_dma4[] = { | ||
154 | INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660), | ||
155 | INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0), | ||
156 | INTC_VECT(DMAC_DMAE, 0x6c0), | ||
157 | }; | ||
158 | |||
159 | static struct intc_group groups_dma4[] = { | ||
160 | INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, | ||
161 | DMAC_DMTE3, DMAC_DMAE), | ||
162 | }; | ||
163 | |||
164 | static DECLARE_INTC_DESC(intc_desc_dma4, "sh7750_dma4", | ||
165 | vectors_dma4, groups_dma4, | ||
166 | priorities, NULL, prio_registers, NULL); | ||
167 | #endif | ||
168 | |||
169 | /* SH7750R and SH7751R both have 8-channel DMA controllers */ | ||
170 | #if defined(CONFIG_CPU_SUBTYPE_SH7750R) || defined(CONFIG_CPU_SUBTYPE_SH7751R) | ||
171 | static struct intc_vect vectors_dma8[] = { | ||
172 | INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660), | ||
173 | INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0), | ||
174 | INTC_VECT(DMAC_DMTE4, 0x780), INTC_VECT(DMAC_DMTE5, 0x7a0), | ||
175 | INTC_VECT(DMAC_DMTE6, 0x7c0), INTC_VECT(DMAC_DMTE7, 0x7e0), | ||
176 | INTC_VECT(DMAC_DMAE, 0x6c0), | ||
177 | }; | ||
178 | |||
179 | static struct intc_group groups_dma8[] = { | ||
180 | INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, | ||
181 | DMAC_DMTE3, DMAC_DMTE4, DMAC_DMTE5, | ||
182 | DMAC_DMTE6, DMAC_DMTE7, DMAC_DMAE), | ||
183 | }; | ||
184 | |||
185 | static DECLARE_INTC_DESC(intc_desc_dma8, "sh7750_dma8", | ||
186 | vectors_dma8, groups_dma8, | ||
187 | priorities, NULL, prio_registers, NULL); | ||
188 | #endif | ||
189 | |||
190 | /* SH7750R, SH7751 and SH7751R all have two extra timer channels */ | ||
191 | #if defined(CONFIG_CPU_SUBTYPE_SH7750R) || \ | ||
192 | defined(CONFIG_CPU_SUBTYPE_SH7751) || \ | ||
193 | defined(CONFIG_CPU_SUBTYPE_SH7751R) | ||
194 | static struct intc_vect vectors_tmu34[] = { | ||
195 | INTC_VECT(TMU3, 0xb00), INTC_VECT(TMU4, 0xb80), | ||
151 | }; | 196 | }; |
197 | |||
198 | static struct intc_mask_reg mask_registers[] = { | ||
199 | { 0xfe080040, 0xfe080060, 32, /* INTMSK00 / INTMSKCLR00 */ | ||
200 | { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
201 | 0, 0, 0, 0, 0, 0, TMU4, TMU3, | ||
202 | PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON, | ||
203 | PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, | ||
204 | PCIC1_PCIDMA3, PCIC0_PCISERR } }, | ||
205 | }; | ||
206 | |||
207 | static DECLARE_INTC_DESC(intc_desc_tmu34, "sh7750_tmu34", | ||
208 | vectors_tmu34, NULL, priorities, | ||
209 | mask_registers, prio_registers, NULL); | ||
152 | #endif | 210 | #endif |
153 | 211 | ||
154 | void __init init_IRQ_ipr(void) | 212 | /* SH7750S, SH7750R, SH7751 and SH7751R all have IRLM priority registers */ |
213 | static struct intc_vect vectors_irlm[] = { | ||
214 | INTC_VECT(IRL0, 0x240), INTC_VECT(IRL1, 0x2a0), | ||
215 | INTC_VECT(IRL2, 0x300), INTC_VECT(IRL3, 0x360), | ||
216 | }; | ||
217 | |||
218 | static DECLARE_INTC_DESC(intc_desc_irlm, "sh7750_irlm", vectors_irlm, NULL, | ||
219 | priorities, NULL, prio_registers, NULL); | ||
220 | |||
221 | /* SH7751 and SH7751R both have PCI */ | ||
222 | #if defined(CONFIG_CPU_SUBTYPE_SH7751) || defined(CONFIG_CPU_SUBTYPE_SH7751R) | ||
223 | static struct intc_vect vectors_pci[] = { | ||
224 | INTC_VECT(PCIC0_PCISERR, 0xa00), INTC_VECT(PCIC1_PCIERR, 0xae0), | ||
225 | INTC_VECT(PCIC1_PCIPWDWN, 0xac0), INTC_VECT(PCIC1_PCIPWON, 0xaa0), | ||
226 | INTC_VECT(PCIC1_PCIDMA0, 0xa80), INTC_VECT(PCIC1_PCIDMA1, 0xa60), | ||
227 | INTC_VECT(PCIC1_PCIDMA2, 0xa40), INTC_VECT(PCIC1_PCIDMA3, 0xa20), | ||
228 | }; | ||
229 | |||
230 | static struct intc_group groups_pci[] = { | ||
231 | INTC_GROUP(PCIC1, PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON, | ||
232 | PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3), | ||
233 | }; | ||
234 | |||
235 | static DECLARE_INTC_DESC(intc_desc_pci, "sh7750_pci", vectors_pci, groups_pci, | ||
236 | priorities, mask_registers, prio_registers, NULL); | ||
237 | #endif | ||
238 | |||
239 | #if defined(CONFIG_CPU_SUBTYPE_SH7750) || \ | ||
240 | defined(CONFIG_CPU_SUBTYPE_SH7750S) || \ | ||
241 | defined(CONFIG_CPU_SUBTYPE_SH7091) | ||
242 | void __init plat_irq_setup(void) | ||
155 | { | 243 | { |
156 | register_ipr_controller(&ipr_irq_desc); | 244 | /* |
157 | #ifdef CONFIG_CPU_SUBTYPE_SH7751 | 245 | * same vectors for SH7750, SH7750S and SH7091 except for IRLM, |
158 | register_ipr_controller(&ipr_irq_desc_sh7751); | 246 | * see below.. |
247 | */ | ||
248 | register_intc_controller(&intc_desc); | ||
249 | register_intc_controller(&intc_desc_dma4); | ||
250 | } | ||
159 | #endif | 251 | #endif |
252 | |||
253 | #if defined(CONFIG_CPU_SUBTYPE_SH7750R) | ||
254 | void __init plat_irq_setup(void) | ||
255 | { | ||
256 | register_intc_controller(&intc_desc); | ||
257 | register_intc_controller(&intc_desc_dma8); | ||
258 | register_intc_controller(&intc_desc_tmu34); | ||
160 | } | 259 | } |
260 | #endif | ||
261 | |||
262 | #if defined(CONFIG_CPU_SUBTYPE_SH7751) | ||
263 | void __init plat_irq_setup(void) | ||
264 | { | ||
265 | register_intc_controller(&intc_desc); | ||
266 | register_intc_controller(&intc_desc_dma4); | ||
267 | register_intc_controller(&intc_desc_tmu34); | ||
268 | register_intc_controller(&intc_desc_pci); | ||
269 | } | ||
270 | #endif | ||
271 | |||
272 | #if defined(CONFIG_CPU_SUBTYPE_SH7751R) | ||
273 | void __init plat_irq_setup(void) | ||
274 | { | ||
275 | register_intc_controller(&intc_desc); | ||
276 | register_intc_controller(&intc_desc_dma8); | ||
277 | register_intc_controller(&intc_desc_tmu34); | ||
278 | register_intc_controller(&intc_desc_pci); | ||
279 | } | ||
280 | #endif | ||
161 | 281 | ||
162 | #define INTC_ICR 0xffd00000UL | 282 | #define INTC_ICR 0xffd00000UL |
163 | #define INTC_ICR_IRLM (1<<7) | 283 | #define INTC_ICR_IRLM (1<<7) |
164 | 284 | ||
165 | /* enable individual interrupt mode for external interupts */ | 285 | /* enable individual interrupt mode for external interupts */ |
166 | void ipr_irq_enable_irlm(void) | 286 | void __init ipr_irq_enable_irlm(void) |
167 | { | 287 | { |
288 | #if defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7091) | ||
289 | BUG(); /* impossible to mask interrupts on SH7750 and SH7091 */ | ||
290 | #endif | ||
291 | register_intc_controller(&intc_desc_irlm); | ||
292 | |||
168 | ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); | 293 | ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); |
169 | } | 294 | } |
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c index 3df169755673..47fa27056253 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c | |||
@@ -109,11 +109,6 @@ static struct intc2_desc intc2_irq_desc __read_mostly = { | |||
109 | }, | 109 | }, |
110 | }; | 110 | }; |
111 | 111 | ||
112 | void __init init_IRQ_intc2(void) | ||
113 | { | ||
114 | register_intc2_controller(&intc2_irq_desc); | ||
115 | } | ||
116 | |||
117 | static struct ipr_data ipr_irq_table[] = { | 112 | static struct ipr_data ipr_irq_table[] = { |
118 | /* IRQ, IPR-idx, shift, priority */ | 113 | /* IRQ, IPR-idx, shift, priority */ |
119 | { 16, 0, 12, 2 }, /* TMU0 TUNI*/ | 114 | { 16, 0, 12, 2 }, /* TMU0 TUNI*/ |
@@ -163,7 +158,8 @@ static struct ipr_desc ipr_irq_desc = { | |||
163 | }, | 158 | }, |
164 | }; | 159 | }; |
165 | 160 | ||
166 | void __init init_IRQ_ipr(void) | 161 | void __init plat_irq_setup(void) |
167 | { | 162 | { |
163 | register_intc2_controller(&intc2_irq_desc); | ||
168 | register_ipr_controller(&ipr_irq_desc); | 164 | register_ipr_controller(&ipr_irq_desc); |
169 | } | 165 | } |
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index 51b386d454de..a0fd8bb21f7c 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c | |||
@@ -387,9 +387,24 @@ out_err: | |||
387 | return err; | 387 | return err; |
388 | } | 388 | } |
389 | 389 | ||
390 | static long sh7722_frqcr_round_rate(struct clk *clk, unsigned long rate) | ||
391 | { | ||
392 | unsigned long parent_rate = clk->parent->rate; | ||
393 | int div; | ||
394 | |||
395 | /* look for multiplier/divisor pair */ | ||
396 | div = sh7722_find_divisors(parent_rate, rate); | ||
397 | if (div < 0) | ||
398 | return clk->rate; | ||
399 | |||
400 | /* calculate new value of clock rate */ | ||
401 | return parent_rate * 2 / div; | ||
402 | } | ||
403 | |||
390 | static struct clk_ops sh7722_frqcr_clk_ops = { | 404 | static struct clk_ops sh7722_frqcr_clk_ops = { |
391 | .recalc = sh7722_frqcr_recalc, | 405 | .recalc = sh7722_frqcr_recalc, |
392 | .set_rate = sh7722_frqcr_set_rate, | 406 | .set_rate = sh7722_frqcr_set_rate, |
407 | .round_rate = sh7722_frqcr_round_rate, | ||
393 | }; | 408 | }; |
394 | 409 | ||
395 | /* | 410 | /* |
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index a3e159ef6dfe..25b913e07e2c 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c | |||
@@ -19,8 +19,21 @@ static struct plat_sci_port sci_platform_data[] = { | |||
19 | .mapbase = 0xffe00000, | 19 | .mapbase = 0xffe00000, |
20 | .flags = UPF_BOOT_AUTOCONF, | 20 | .flags = UPF_BOOT_AUTOCONF, |
21 | .type = PORT_SCIF, | 21 | .type = PORT_SCIF, |
22 | .irqs = { 80, 81, 83, 82 }, | 22 | .irqs = { 80, 80, 80, 80 }, |
23 | }, { | 23 | }, |
24 | { | ||
25 | .mapbase = 0xffe10000, | ||
26 | .flags = UPF_BOOT_AUTOCONF, | ||
27 | .type = PORT_SCIF, | ||
28 | .irqs = { 81, 81, 81, 81 }, | ||
29 | }, | ||
30 | { | ||
31 | .mapbase = 0xffe20000, | ||
32 | .flags = UPF_BOOT_AUTOCONF, | ||
33 | .type = PORT_SCIF, | ||
34 | .irqs = { 82, 82, 82, 82 }, | ||
35 | }, | ||
36 | { | ||
24 | .flags = 0, | 37 | .flags = 0, |
25 | } | 38 | } |
26 | }; | 39 | }; |
@@ -44,46 +57,145 @@ static int __init sh7722_devices_setup(void) | |||
44 | } | 57 | } |
45 | __initcall(sh7722_devices_setup); | 58 | __initcall(sh7722_devices_setup); |
46 | 59 | ||
47 | static struct ipr_data ipr_irq_table[] = { | 60 | enum { |
48 | /* IRQ, IPR-idx, shift, prio */ | 61 | UNUSED=0, |
49 | { 16, 0, 12, 2 }, /* TMU0 */ | 62 | |
50 | { 17, 0, 8, 2 }, /* TMU1 */ | 63 | /* interrupt sources */ |
51 | { 80, 6, 12, 3 }, /* SCIF ERI */ | 64 | IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, |
52 | { 81, 6, 12, 3 }, /* SCIF RXI */ | 65 | HUDI, |
53 | { 82, 6, 12, 3 }, /* SCIF BRI */ | 66 | SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEI, |
54 | { 83, 6, 12, 3 }, /* SCIF TXI */ | 67 | RTC_ATI, RTC_PRI, RTC_CUI, |
68 | DMAC0, DMAC1, DMAC2, DMAC3, | ||
69 | VIO_CEUI, VIO_BEUI, VIO_VEUI, VOU, | ||
70 | VPU, TPU, | ||
71 | USB_USBI0, USB_USBI1, | ||
72 | DMAC4, DMAC5, DMAC_DADERR, | ||
73 | KEYSC, | ||
74 | SCIF0, SCIF1, SCIF2, SIOF0, SIOF1, SIO, | ||
75 | FLCTL_FLSTEI, FLCTL_FLENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I, | ||
76 | I2C_ALI, I2C_TACKI, I2C_WAITI, I2C_DTEI, | ||
77 | SDHI0, SDHI1, SDHI2, SDHI3, | ||
78 | CMT, TSIF, SIU, TWODG, | ||
79 | TMU0, TMU1, TMU2, | ||
80 | IRDA, JPU, LCDC, | ||
81 | |||
82 | /* interrupt groups */ | ||
83 | |||
84 | SIM, RTC, DMAC0123, VIOVOU, USB, DMAC45, FLCTL, I2C, SDHI, | ||
55 | }; | 85 | }; |
56 | 86 | ||
57 | static unsigned long ipr_offsets[] = { | 87 | static struct intc_vect vectors[] = { |
58 | 0xa4080000, /* 0: IPRA */ | 88 | INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620), |
59 | 0xa4080004, /* 1: IPRB */ | 89 | INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660), |
60 | 0xa4080008, /* 2: IPRC */ | 90 | INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0), |
61 | 0xa408000c, /* 3: IPRD */ | 91 | INTC_VECT(IRQ6, 0x6c0), INTC_VECT(IRQ7, 0x6e0), |
62 | 0xa4080010, /* 4: IPRE */ | 92 | INTC_VECT(SIM_ERI, 0x700), INTC_VECT(SIM_RXI, 0x720), |
63 | 0xa4080014, /* 5: IPRF */ | 93 | INTC_VECT(SIM_TXI, 0x740), INTC_VECT(SIM_TEI, 0x760), |
64 | 0xa4080018, /* 6: IPRG */ | 94 | INTC_VECT(RTC_ATI, 0x780), INTC_VECT(RTC_PRI, 0x7a0), |
65 | 0xa408001c, /* 7: IPRH */ | 95 | INTC_VECT(RTC_CUI, 0x7c0), |
66 | 0xa4080020, /* 8: IPRI */ | 96 | INTC_VECT(DMAC0, 0x800), INTC_VECT(DMAC1, 0x820), |
67 | 0xa4080024, /* 9: IPRJ */ | 97 | INTC_VECT(DMAC2, 0x840), INTC_VECT(DMAC3, 0x860), |
68 | 0xa4080028, /* 10: IPRK */ | 98 | INTC_VECT(VIO_CEUI, 0x880), INTC_VECT(VIO_BEUI, 0x8a0), |
69 | 0xa408002c, /* 11: IPRL */ | 99 | INTC_VECT(VIO_VEUI, 0x8c0), INTC_VECT(VOU, 0x8e0), |
100 | INTC_VECT(VPU, 0x980), INTC_VECT(TPU, 0x9a0), | ||
101 | INTC_VECT(USB_USBI0, 0xa20), INTC_VECT(USB_USBI1, 0xa40), | ||
102 | INTC_VECT(DMAC4, 0xb80), INTC_VECT(DMAC5, 0xba0), | ||
103 | INTC_VECT(DMAC_DADERR, 0xbc0), INTC_VECT(KEYSC, 0xbe0), | ||
104 | INTC_VECT(SCIF0, 0xc00), INTC_VECT(SCIF1, 0xc20), | ||
105 | INTC_VECT(SCIF2, 0xc40), INTC_VECT(SIOF0, 0xc80), | ||
106 | INTC_VECT(SIOF1, 0xca0), INTC_VECT(SIO, 0xd00), | ||
107 | INTC_VECT(FLCTL_FLSTEI, 0xd80), INTC_VECT(FLCTL_FLENDI, 0xda0), | ||
108 | INTC_VECT(FLCTL_FLTREQ0I, 0xdc0), INTC_VECT(FLCTL_FLTREQ1I, 0xde0), | ||
109 | INTC_VECT(I2C_ALI, 0xe00), INTC_VECT(I2C_TACKI, 0xe20), | ||
110 | INTC_VECT(I2C_WAITI, 0xe40), INTC_VECT(I2C_DTEI, 0xe60), | ||
111 | INTC_VECT(SDHI0, 0xe80), INTC_VECT(SDHI1, 0xea0), | ||
112 | INTC_VECT(SDHI2, 0xec0), INTC_VECT(SDHI3, 0xee0), | ||
113 | INTC_VECT(CMT, 0xf00), INTC_VECT(TSIF, 0xf20), | ||
114 | INTC_VECT(SIU, 0xf80), INTC_VECT(TWODG, 0xfa0), | ||
115 | INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420), | ||
116 | INTC_VECT(TMU2, 0x440), INTC_VECT(IRDA, 0x480), | ||
117 | INTC_VECT(JPU, 0x560), INTC_VECT(LCDC, 0x580), | ||
70 | }; | 118 | }; |
71 | 119 | ||
72 | static struct ipr_desc ipr_irq_desc = { | 120 | static struct intc_group groups[] = { |
73 | .ipr_offsets = ipr_offsets, | 121 | INTC_GROUP(SIM, SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEI), |
74 | .nr_offsets = ARRAY_SIZE(ipr_offsets), | 122 | INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI), |
123 | INTC_GROUP(DMAC0123, DMAC0, DMAC1, DMAC2, DMAC3), | ||
124 | INTC_GROUP(VIOVOU, VIO_CEUI, VIO_BEUI, VIO_VEUI, VOU), | ||
125 | INTC_GROUP(USB, USB_USBI0, USB_USBI1), | ||
126 | INTC_GROUP(DMAC45, DMAC4, DMAC5, DMAC_DADERR), | ||
127 | INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLENDI, | ||
128 | FLCTL_FLTREQ0I, FLCTL_FLTREQ1I), | ||
129 | INTC_GROUP(I2C, I2C_ALI, I2C_TACKI, I2C_WAITI, I2C_DTEI), | ||
130 | INTC_GROUP(SDHI, SDHI0, SDHI1, SDHI2, SDHI3), | ||
131 | }; | ||
75 | 132 | ||
76 | .ipr_data = ipr_irq_table, | 133 | static struct intc_prio priorities[] = { |
77 | .nr_irqs = ARRAY_SIZE(ipr_irq_table), | 134 | INTC_PRIO(SCIF0, 3), |
135 | INTC_PRIO(SCIF1, 3), | ||
136 | INTC_PRIO(SCIF2, 3), | ||
137 | INTC_PRIO(TMU0, 2), | ||
138 | INTC_PRIO(TMU1, 2), | ||
139 | }; | ||
78 | 140 | ||
79 | .chip = { | 141 | static struct intc_mask_reg mask_registers[] = { |
80 | .name = "IPR-sh7722", | 142 | { 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */ |
81 | }, | 143 | { } }, |
144 | { 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */ | ||
145 | { VOU, VIO_VEUI, VIO_BEUI, VIO_CEUI, DMAC3, DMAC2, DMAC1, DMAC0 } }, | ||
146 | { 0xa4080088, 0xa40800c8, 8, /* IMR2 / IMCR2 */ | ||
147 | { 0, 0, 0, VPU, } }, | ||
148 | { 0xa408008c, 0xa40800cc, 8, /* IMR3 / IMCR3 */ | ||
149 | { SIM_TEI, SIM_TXI, SIM_RXI, SIM_ERI, 0, 0, 0, IRDA } }, | ||
150 | { 0xa4080090, 0xa40800d0, 8, /* IMR4 / IMCR4 */ | ||
151 | { 0, TMU2, TMU1, TMU0, JPU, 0, 0, LCDC } }, | ||
152 | { 0xa4080094, 0xa40800d4, 8, /* IMR5 / IMCR5 */ | ||
153 | { KEYSC, DMAC_DADERR, DMAC5, DMAC4, 0, SCIF2, SCIF1, SCIF0 } }, | ||
154 | { 0xa4080098, 0xa40800d8, 8, /* IMR6 / IMCR6 */ | ||
155 | { 0, 0, 0, SIO, 0, 0, SIOF1, SIOF0 } }, | ||
156 | { 0xa408009c, 0xa40800dc, 8, /* IMR7 / IMCR7 */ | ||
157 | { I2C_DTEI, I2C_WAITI, I2C_TACKI, I2C_ALI, | ||
158 | FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLENDI, FLCTL_FLSTEI } }, | ||
159 | { 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */ | ||
160 | { SDHI3, SDHI2, SDHI1, SDHI0, 0, 0, TWODG, SIU } }, | ||
161 | { 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */ | ||
162 | { 0, 0, 0, CMT, 0, USB_USBI1, USB_USBI0, } }, | ||
163 | { 0xa40800a8, 0xa40800e8, 8, /* IMR10 / IMCR10 */ | ||
164 | { } }, | ||
165 | { 0xa40800ac, 0xa40800ec, 8, /* IMR11 / IMCR11 */ | ||
166 | { 0, RTC_CUI, RTC_PRI, RTC_ATI, 0, TPU, 0, TSIF } }, | ||
167 | { 0xa4140044, 0xa4140064, 8, /* INTMSK00 / INTMSKCLR00 */ | ||
168 | { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, | ||
82 | }; | 169 | }; |
83 | 170 | ||
84 | void __init init_IRQ_ipr(void) | 171 | static struct intc_prio_reg prio_registers[] = { |
172 | { 0xa4080000, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, IRDA } }, | ||
173 | { 0xa4080004, 16, 4, /* IPRB */ { JPU, LCDC, SIM } }, | ||
174 | { 0xa4080008, 16, 4, /* IPRC */ { } }, | ||
175 | { 0xa408000c, 16, 4, /* IPRD */ { } }, | ||
176 | { 0xa4080010, 16, 4, /* IPRE */ { DMAC0123, VIOVOU, 0, VPU } }, | ||
177 | { 0xa4080014, 16, 4, /* IPRF */ { KEYSC, DMAC45, USB, CMT } }, | ||
178 | { 0xa4080018, 16, 4, /* IPRG */ { SCIF0, SCIF1, SCIF2 } }, | ||
179 | { 0xa408001c, 16, 4, /* IPRH */ { SIOF0, SIOF1, FLCTL, I2C } }, | ||
180 | { 0xa4080020, 16, 4, /* IPRI */ { SIO, 0, TSIF, RTC } }, | ||
181 | { 0xa4080024, 16, 4, /* IPRJ */ { 0, 0, SIU } }, | ||
182 | { 0xa4080028, 16, 4, /* IPRK */ { 0, 0, 0, SDHI } }, | ||
183 | { 0xa408002c, 16, 4, /* IPRL */ { TWODG, 0, TPU } }, | ||
184 | { 0xa4140010, 32, 4, /* INTPRI00 */ | ||
185 | { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, | ||
186 | }; | ||
187 | |||
188 | static struct intc_sense_reg sense_registers[] = { | ||
189 | { 0xa414001c, 16, 2, /* ICR1 */ | ||
190 | { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, | ||
191 | }; | ||
192 | |||
193 | static DECLARE_INTC_DESC(intc_desc, "sh7722", vectors, groups, priorities, | ||
194 | mask_registers, prio_registers, sense_registers); | ||
195 | |||
196 | void __init plat_irq_setup(void) | ||
85 | { | 197 | { |
86 | register_ipr_controller(&ipr_irq_desc); | 198 | register_intc_controller(&intc_desc); |
87 | } | 199 | } |
88 | 200 | ||
89 | void __init plat_mem_setup(void) | 201 | void __init plat_mem_setup(void) |
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index b57c760bffde..a4127ec15203 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c | |||
@@ -30,7 +30,7 @@ static struct resource rtc_resources[] = { | |||
30 | }, | 30 | }, |
31 | [3] = { | 31 | [3] = { |
32 | /* Alarm IRQ */ | 32 | /* Alarm IRQ */ |
33 | .start = 23, | 33 | .start = 20, |
34 | .flags = IORESOURCE_IRQ, | 34 | .flags = IORESOURCE_IRQ, |
35 | }, | 35 | }, |
36 | }; | 36 | }; |
@@ -78,44 +78,205 @@ static int __init sh7780_devices_setup(void) | |||
78 | } | 78 | } |
79 | __initcall(sh7780_devices_setup); | 79 | __initcall(sh7780_devices_setup); |
80 | 80 | ||
81 | static struct intc2_data intc2_irq_table[] = { | 81 | enum { |
82 | { 28, 0, 24, 0, 0, 2 }, /* TMU0 */ | 82 | UNUSED = 0, |
83 | 83 | ||
84 | { 21, 1, 0, 0, 2, 2 }, | 84 | /* interrupt sources */ |
85 | { 22, 1, 1, 0, 2, 2 }, | ||
86 | { 23, 1, 2, 0, 2, 2 }, | ||
87 | 85 | ||
88 | { 40, 8, 24, 0, 3, 3 }, /* SCIF0 ERI */ | 86 | IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH, |
89 | { 41, 8, 24, 0, 3, 3 }, /* SCIF0 RXI */ | 87 | IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH, |
90 | { 42, 8, 24, 0, 3, 3 }, /* SCIF0 BRI */ | 88 | IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH, |
91 | { 43, 8, 24, 0, 3, 3 }, /* SCIF0 TXI */ | 89 | IRL_HHLL, IRL_HHLH, IRL_HHHL, |
92 | 90 | ||
93 | { 76, 8, 16, 0, 4, 3 }, /* SCIF1 ERI */ | 91 | IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, |
94 | { 77, 8, 16, 0, 4, 3 }, /* SCIF1 RXI */ | 92 | RTC_ATI, RTC_PRI, RTC_CUI, |
95 | { 78, 8, 16, 0, 4, 3 }, /* SCIF1 BRI */ | 93 | WDT, |
96 | { 79, 8, 16, 0, 4, 3 }, /* SCIF1 TXI */ | 94 | TMU0, TMU1, TMU2, TMU2_TICPI, |
95 | HUDI, | ||
96 | DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, DMAC0_DMINT3, DMAC0_DMAE, | ||
97 | SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI, | ||
98 | DMAC0_DMINT4, DMAC0_DMINT5, DMAC1_DMINT6, DMAC1_DMINT7, | ||
99 | CMT, HAC, | ||
100 | PCISERR, PCIINTA, PCIINTB, PCIINTC, PCIINTD, | ||
101 | PCIERR, PCIPWD3, PCIPWD2, PCIPWD1, PCIPWD0, | ||
102 | SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI, | ||
103 | SIOF, HSPI, | ||
104 | MMCIF_FSTAT, MMCIF_TRAN, MMCIF_ERR, MMCIF_FRDY, | ||
105 | DMAC1_DMINT8, DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11, | ||
106 | TMU3, TMU4, TMU5, | ||
107 | SSI, | ||
108 | FLCTL_FLSTE, FLCTL_FLEND, FLCTL_FLTRQ0, FLCTL_FLTRQ1, | ||
109 | GPIOI0, GPIOI1, GPIOI2, GPIOI3, | ||
97 | 110 | ||
98 | { 64, 0x10, 8, 0, 14, 2 }, /* PCIC0 */ | 111 | /* interrupt groups */ |
99 | { 65, 0x10, 0, 0, 15, 2 }, /* PCIC1 */ | 112 | |
100 | { 66, 0x14, 24, 0, 16, 2 }, /* PCIC2 */ | 113 | RTC, TMU012, DMAC0, SCIF0, DMAC45, DMAC1, |
101 | { 67, 0x14, 16, 0, 17, 2 }, /* PCIC3 */ | 114 | PCIC5, SCIF1, MMCIF, TMU345, FLCTL, GPIO, |
102 | { 68, 0x14, 8, 0, 18, 2 }, /* PCIC4 */ | ||
103 | }; | 115 | }; |
104 | 116 | ||
105 | static struct intc2_desc intc2_irq_desc __read_mostly = { | 117 | static struct intc_vect vectors[] = { |
106 | .prio_base = 0xffd40000, | 118 | INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0), |
107 | .msk_base = 0xffd40038, | 119 | INTC_VECT(RTC_CUI, 0x4c0), |
108 | .mskclr_base = 0xffd4003c, | 120 | INTC_VECT(WDT, 0x560), |
121 | INTC_VECT(TMU0, 0x580), INTC_VECT(TMU1, 0x5a0), | ||
122 | INTC_VECT(TMU2, 0x5c0), INTC_VECT(TMU2_TICPI, 0x5e0), | ||
123 | INTC_VECT(HUDI, 0x600), | ||
124 | INTC_VECT(DMAC0_DMINT0, 0x640), INTC_VECT(DMAC0_DMINT1, 0x660), | ||
125 | INTC_VECT(DMAC0_DMINT2, 0x680), INTC_VECT(DMAC0_DMINT3, 0x6a0), | ||
126 | INTC_VECT(DMAC0_DMAE, 0x6c0), | ||
127 | INTC_VECT(SCIF0_ERI, 0x700), INTC_VECT(SCIF0_RXI, 0x720), | ||
128 | INTC_VECT(SCIF0_BRI, 0x740), INTC_VECT(SCIF0_TXI, 0x760), | ||
129 | INTC_VECT(DMAC0_DMINT4, 0x780), INTC_VECT(DMAC0_DMINT5, 0x7a0), | ||
130 | INTC_VECT(DMAC1_DMINT6, 0x7c0), INTC_VECT(DMAC1_DMINT7, 0x7e0), | ||
131 | INTC_VECT(CMT, 0x900), INTC_VECT(HAC, 0x980), | ||
132 | INTC_VECT(PCISERR, 0xa00), INTC_VECT(PCIINTA, 0xa20), | ||
133 | INTC_VECT(PCIINTB, 0xa40), INTC_VECT(PCIINTC, 0xa60), | ||
134 | INTC_VECT(PCIINTD, 0xa80), INTC_VECT(PCIERR, 0xaa0), | ||
135 | INTC_VECT(PCIPWD3, 0xac0), INTC_VECT(PCIPWD2, 0xae0), | ||
136 | INTC_VECT(PCIPWD1, 0xb00), INTC_VECT(PCIPWD0, 0xb20), | ||
137 | INTC_VECT(SCIF1_ERI, 0xb80), INTC_VECT(SCIF1_RXI, 0xba0), | ||
138 | INTC_VECT(SCIF1_BRI, 0xbc0), INTC_VECT(SCIF1_TXI, 0xbe0), | ||
139 | INTC_VECT(SIOF, 0xc00), INTC_VECT(HSPI, 0xc80), | ||
140 | INTC_VECT(MMCIF_FSTAT, 0xd00), INTC_VECT(MMCIF_TRAN, 0xd20), | ||
141 | INTC_VECT(MMCIF_ERR, 0xd40), INTC_VECT(MMCIF_FRDY, 0xd60), | ||
142 | INTC_VECT(DMAC1_DMINT8, 0xd80), INTC_VECT(DMAC1_DMINT9, 0xda0), | ||
143 | INTC_VECT(DMAC1_DMINT10, 0xdc0), INTC_VECT(DMAC1_DMINT11, 0xde0), | ||
144 | INTC_VECT(TMU3, 0xe00), INTC_VECT(TMU4, 0xe20), | ||
145 | INTC_VECT(TMU5, 0xe40), | ||
146 | INTC_VECT(SSI, 0xe80), | ||
147 | INTC_VECT(FLCTL_FLSTE, 0xf00), INTC_VECT(FLCTL_FLEND, 0xf20), | ||
148 | INTC_VECT(FLCTL_FLTRQ0, 0xf40), INTC_VECT(FLCTL_FLTRQ1, 0xf60), | ||
149 | INTC_VECT(GPIOI0, 0xf80), INTC_VECT(GPIOI1, 0xfa0), | ||
150 | INTC_VECT(GPIOI2, 0xfc0), INTC_VECT(GPIOI3, 0xfe0), | ||
151 | }; | ||
109 | 152 | ||
110 | .intc2_data = intc2_irq_table, | 153 | static struct intc_group groups[] = { |
111 | .nr_irqs = ARRAY_SIZE(intc2_irq_table), | 154 | INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI), |
155 | INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI), | ||
156 | INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, | ||
157 | DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE), | ||
158 | INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI), | ||
159 | INTC_GROUP(DMAC1, DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8, | ||
160 | DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11), | ||
161 | INTC_GROUP(PCIC5, PCIERR, PCIPWD3, PCIPWD2, PCIPWD1, PCIPWD0), | ||
162 | INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI), | ||
163 | INTC_GROUP(MMCIF, MMCIF_FSTAT, MMCIF_TRAN, MMCIF_ERR, MMCIF_FRDY), | ||
164 | INTC_GROUP(TMU345, TMU3, TMU4, TMU5), | ||
165 | INTC_GROUP(FLCTL, FLCTL_FLSTE, FLCTL_FLEND, | ||
166 | FLCTL_FLTRQ0, FLCTL_FLTRQ1), | ||
167 | INTC_GROUP(GPIO, GPIOI0, GPIOI1, GPIOI2, GPIOI3), | ||
168 | }; | ||
112 | 169 | ||
113 | .chip = { | 170 | static struct intc_prio priorities[] = { |
114 | .name = "INTC2-sh7780", | 171 | INTC_PRIO(SCIF0, 3), |
115 | }, | 172 | INTC_PRIO(SCIF1, 3), |
173 | }; | ||
174 | |||
175 | static struct intc_mask_reg mask_registers[] = { | ||
176 | { 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */ | ||
177 | { 0, 0, 0, 0, 0, 0, GPIO, FLCTL, | ||
178 | SSI, MMCIF, HSPI, SIOF, PCIC5, PCIINTD, PCIINTC, PCIINTB, | ||
179 | PCIINTA, PCISERR, HAC, CMT, 0, 0, DMAC1, DMAC0, | ||
180 | HUDI, 0, WDT, SCIF1, SCIF0, RTC, TMU345, TMU012 } }, | ||
181 | }; | ||
182 | |||
183 | static struct intc_prio_reg prio_registers[] = { | ||
184 | { 0xffd40000, 32, 8, /* INT2PRI0 */ { TMU0, TMU1, TMU2, TMU2_TICPI } }, | ||
185 | { 0xffd40004, 32, 8, /* INT2PRI1 */ { TMU3, TMU4, TMU5, RTC } }, | ||
186 | { 0xffd40008, 32, 8, /* INT2PRI2 */ { SCIF0, SCIF1, WDT } }, | ||
187 | { 0xffd4000c, 32, 8, /* INT2PRI3 */ { HUDI, DMAC0, DMAC1 } }, | ||
188 | { 0xffd40010, 32, 8, /* INT2PRI4 */ { CMT, HAC, PCISERR, PCIINTA, } }, | ||
189 | { 0xffd40014, 32, 8, /* INT2PRI5 */ { PCIINTB, PCIINTC, | ||
190 | PCIINTD, PCIC5 } }, | ||
191 | { 0xffd40018, 32, 8, /* INT2PRI6 */ { SIOF, HSPI, MMCIF, SSI } }, | ||
192 | { 0xffd4001c, 32, 8, /* INT2PRI7 */ { FLCTL, GPIO } }, | ||
193 | }; | ||
194 | |||
195 | static DECLARE_INTC_DESC(intc_desc, "sh7780", vectors, groups, priorities, | ||
196 | mask_registers, prio_registers, NULL); | ||
197 | |||
198 | /* Support for external interrupt pins in IRQ mode */ | ||
199 | |||
200 | static struct intc_vect irq_vectors[] = { | ||
201 | INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280), | ||
202 | INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300), | ||
203 | INTC_VECT(IRQ4, 0x340), INTC_VECT(IRQ5, 0x380), | ||
204 | INTC_VECT(IRQ6, 0x3c0), INTC_VECT(IRQ7, 0x200), | ||
205 | }; | ||
206 | |||
207 | static struct intc_mask_reg irq_mask_registers[] = { | ||
208 | { 0xffd00044, 0xffd00064, 32, /* INTMSK0 / INTMSKCLR0 */ | ||
209 | { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, | ||
210 | }; | ||
211 | |||
212 | static struct intc_prio_reg irq_prio_registers[] = { | ||
213 | { 0xffd00010, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3, | ||
214 | IRQ4, IRQ5, IRQ6, IRQ7 } }, | ||
116 | }; | 215 | }; |
117 | 216 | ||
118 | void __init init_IRQ_intc2(void) | 217 | static struct intc_sense_reg irq_sense_registers[] = { |
218 | { 0xffd0001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3, | ||
219 | IRQ4, IRQ5, IRQ6, IRQ7 } }, | ||
220 | }; | ||
221 | |||
222 | static DECLARE_INTC_DESC(intc_irq_desc, "sh7780-irq", irq_vectors, | ||
223 | NULL, NULL, irq_mask_registers, irq_prio_registers, | ||
224 | irq_sense_registers); | ||
225 | |||
226 | /* External interrupt pins in IRL mode */ | ||
227 | |||
228 | static struct intc_vect irl_vectors[] = { | ||
229 | INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220), | ||
230 | INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260), | ||
231 | INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0), | ||
232 | INTC_VECT(IRL_LHHL, 0x2c0), INTC_VECT(IRL_LHHH, 0x2e0), | ||
233 | INTC_VECT(IRL_HLLL, 0x300), INTC_VECT(IRL_HLLH, 0x320), | ||
234 | INTC_VECT(IRL_HLHL, 0x340), INTC_VECT(IRL_HLHH, 0x360), | ||
235 | INTC_VECT(IRL_HHLL, 0x380), INTC_VECT(IRL_HHLH, 0x3a0), | ||
236 | INTC_VECT(IRL_HHHL, 0x3c0), | ||
237 | }; | ||
238 | |||
239 | static struct intc_mask_reg irl3210_mask_registers[] = { | ||
240 | { 0xffd00080, 0xffd00084, 32, /* INTMSK2 / INTMSKCLR2 */ | ||
241 | { IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH, | ||
242 | IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH, | ||
243 | IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH, | ||
244 | IRL_HHLL, IRL_HHLH, IRL_HHHL, } }, | ||
245 | }; | ||
246 | |||
247 | static struct intc_mask_reg irl7654_mask_registers[] = { | ||
248 | { 0xffd00080, 0xffd00084, 32, /* INTMSK2 / INTMSKCLR2 */ | ||
249 | { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
250 | IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH, | ||
251 | IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH, | ||
252 | IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH, | ||
253 | IRL_HHLL, IRL_HHLH, IRL_HHHL, } }, | ||
254 | }; | ||
255 | |||
256 | static DECLARE_INTC_DESC(intc_irl7654_desc, "sh7780-irl7654", irl_vectors, | ||
257 | NULL, NULL, irl7654_mask_registers, NULL, NULL); | ||
258 | |||
259 | static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7780-irl3210", irl_vectors, | ||
260 | NULL, NULL, irl3210_mask_registers, NULL, NULL); | ||
261 | |||
262 | void __init plat_irq_setup(void) | ||
119 | { | 263 | { |
120 | register_intc2_controller(&intc2_irq_desc); | 264 | register_intc_controller(&intc_desc); |
265 | } | ||
266 | |||
267 | void __init plat_irq_setup_pins(int mode) | ||
268 | { | ||
269 | switch (mode) { | ||
270 | case IRQ_MODE_IRQ: | ||
271 | register_intc_controller(&intc_irq_desc); | ||
272 | break; | ||
273 | case IRQ_MODE_IRL7654: | ||
274 | register_intc_controller(&intc_irl7654_desc); | ||
275 | break; | ||
276 | case IRQ_MODE_IRL3210: | ||
277 | register_intc_controller(&intc_irl3210_desc); | ||
278 | break; | ||
279 | default: | ||
280 | BUG(); | ||
281 | } | ||
121 | } | 282 | } |
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index ce10ec5d6914..cf047562e43f 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c | |||
@@ -110,7 +110,7 @@ static struct intc2_desc intc2_irq_desc __read_mostly = { | |||
110 | }, | 110 | }, |
111 | }; | 111 | }; |
112 | 112 | ||
113 | void __init init_IRQ_intc2(void) | 113 | void __init plat_irq_setup(void) |
114 | { | 114 | { |
115 | register_intc2_controller(&intc2_irq_desc); | 115 | register_intc2_controller(&intc2_irq_desc); |
116 | } | 116 | } |
diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c index 70683ea12b83..704c064f70dc 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c | |||
@@ -79,7 +79,7 @@ static struct intc2_desc intc2_irq_desc __read_mostly = { | |||
79 | }, | 79 | }, |
80 | }; | 80 | }; |
81 | 81 | ||
82 | void __init init_IRQ_intc2(void) | 82 | void __init plat_irq_setup(void) |
83 | { | 83 | { |
84 | register_intc2_controller(&intc2_irq_desc); | 84 | register_intc2_controller(&intc2_irq_desc); |
85 | } | 85 | } |
diff --git a/arch/sh/kernel/cpufreq.c b/arch/sh/kernel/cpufreq.c index 47abf6e49dfb..e61890217c50 100644 --- a/arch/sh/kernel/cpufreq.c +++ b/arch/sh/kernel/cpufreq.c | |||
@@ -3,89 +3,46 @@ | |||
3 | * | 3 | * |
4 | * cpufreq driver for the SuperH processors. | 4 | * cpufreq driver for the SuperH processors. |
5 | * | 5 | * |
6 | * Copyright (C) 2002, 2003, 2004, 2005 Paul Mundt | 6 | * Copyright (C) 2002 - 2007 Paul Mundt |
7 | * Copyright (C) 2002 M. R. Brown | 7 | * Copyright (C) 2002 M. R. Brown |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify it | 9 | * Clock framework bits from arch/avr32/mach-at32ap/cpufreq.c |
10 | * under the terms of the GNU General Public License as published by the | 10 | * |
11 | * Free Software Foundation; either version 2 of the License, or (at your | 11 | * Copyright (C) 2004-2007 Atmel Corporation |
12 | * option) any later version. | 12 | * |
13 | * This file is subject to the terms and conditions of the GNU General Public | ||
14 | * License. See the file "COPYING" in the main directory of this archive | ||
15 | * for more details. | ||
13 | */ | 16 | */ |
14 | #include <linux/types.h> | 17 | #include <linux/types.h> |
15 | #include <linux/cpufreq.h> | 18 | #include <linux/cpufreq.h> |
16 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
17 | #include <linux/module.h> | 20 | #include <linux/module.h> |
18 | #include <linux/slab.h> | ||
19 | #include <linux/init.h> | 21 | #include <linux/init.h> |
20 | #include <linux/delay.h> | 22 | #include <linux/err.h> |
21 | #include <linux/cpumask.h> | 23 | #include <linux/cpumask.h> |
22 | #include <linux/smp.h> | 24 | #include <linux/smp.h> |
23 | #include <linux/sched.h> /* set_cpus_allowed() */ | 25 | #include <linux/sched.h> /* set_cpus_allowed() */ |
26 | #include <linux/clk.h> | ||
24 | 27 | ||
25 | #include <asm/processor.h> | 28 | static struct clk *cpuclk; |
26 | #include <asm/watchdog.h> | ||
27 | #include <asm/freq.h> | ||
28 | #include <asm/io.h> | ||
29 | |||
30 | /* | ||
31 | * For SuperH, each policy change requires that we change the IFC, BFC, and | ||
32 | * PFC at the same time. Here we define sane values that won't trash the | ||
33 | * system. | ||
34 | * | ||
35 | * Note the max set is computed at runtime, we use the divisors that we booted | ||
36 | * with to setup our maximum operating frequencies. | ||
37 | */ | ||
38 | struct clock_set { | ||
39 | unsigned int ifc; | ||
40 | unsigned int bfc; | ||
41 | unsigned int pfc; | ||
42 | } clock_sets[] = { | ||
43 | #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH2) | ||
44 | { 0, 0, 0 }, /* not implemented yet */ | ||
45 | #elif defined(CONFIG_CPU_SH4) | ||
46 | { 4, 8, 8 }, /* min - IFC: 1/4, BFC: 1/8, PFC: 1/8 */ | ||
47 | { 1, 2, 2 }, /* max - IFC: 1, BFC: 1/2, PFC: 1/2 */ | ||
48 | #endif | ||
49 | }; | ||
50 | |||
51 | #define MIN_CLOCK_SET 0 | ||
52 | #define MAX_CLOCK_SET (ARRAY_SIZE(clock_sets) - 1) | ||
53 | |||
54 | /* | ||
55 | * For the time being, we only support two frequencies, which in turn are | ||
56 | * aimed at the POWERSAVE and PERFORMANCE policies, which in turn are derived | ||
57 | * directly from the respective min/max clock sets. Technically we could | ||
58 | * support a wider range of frequencies, but these vary far too much for each | ||
59 | * CPU subtype (and we'd have to construct a frequency table for each subtype). | ||
60 | * | ||
61 | * Maybe something to implement in the future.. | ||
62 | */ | ||
63 | #define SH_FREQ_MAX 0 | ||
64 | #define SH_FREQ_MIN 1 | ||
65 | |||
66 | static struct cpufreq_frequency_table sh_freqs[] = { | ||
67 | { SH_FREQ_MAX, 0 }, | ||
68 | { SH_FREQ_MIN, 0 }, | ||
69 | { 0, CPUFREQ_TABLE_END }, | ||
70 | }; | ||
71 | 29 | ||
72 | static void sh_cpufreq_update_clocks(unsigned int set) | 30 | static unsigned int sh_cpufreq_get(unsigned int cpu) |
73 | { | 31 | { |
74 | current_cpu_data.cpu_clock = current_cpu_data.master_clock / clock_sets[set].ifc; | 32 | return (clk_get_rate(cpuclk) + 500) / 1000; |
75 | current_cpu_data.bus_clock = current_cpu_data.master_clock / clock_sets[set].bfc; | ||
76 | current_cpu_data.module_clock = current_cpu_data.master_clock / clock_sets[set].pfc; | ||
77 | current_cpu_data.loops_per_jiffy = loops_per_jiffy; | ||
78 | } | 33 | } |
79 | 34 | ||
80 | /* XXX: This needs to be split out per CPU and CPU subtype. */ | ||
81 | /* | 35 | /* |
82 | * Here we notify other drivers of the proposed change and the final change. | 36 | * Here we notify other drivers of the proposed change and the final change. |
83 | */ | 37 | */ |
84 | static int sh_cpufreq_setstate(unsigned int cpu, unsigned int set) | 38 | static int sh_cpufreq_target(struct cpufreq_policy *policy, |
39 | unsigned int target_freq, | ||
40 | unsigned int relation) | ||
85 | { | 41 | { |
86 | unsigned short frqcr = ctrl_inw(FRQCR); | 42 | unsigned int cpu = policy->cpu; |
87 | cpumask_t cpus_allowed; | 43 | cpumask_t cpus_allowed; |
88 | struct cpufreq_freqs freqs; | 44 | struct cpufreq_freqs freqs; |
45 | long freq; | ||
89 | 46 | ||
90 | if (!cpu_online(cpu)) | 47 | if (!cpu_online(cpu)) |
91 | return -ENODEV; | 48 | return -ENODEV; |
@@ -95,125 +52,109 @@ static int sh_cpufreq_setstate(unsigned int cpu, unsigned int set) | |||
95 | 52 | ||
96 | BUG_ON(smp_processor_id() != cpu); | 53 | BUG_ON(smp_processor_id() != cpu); |
97 | 54 | ||
98 | freqs.cpu = cpu; | 55 | /* Convert target_freq from kHz to Hz */ |
99 | freqs.old = current_cpu_data.cpu_clock / 1000; | 56 | freq = clk_round_rate(cpuclk, target_freq * 1000); |
100 | freqs.new = (current_cpu_data.master_clock / clock_sets[set].ifc) / 1000; | ||
101 | 57 | ||
102 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | 58 | if (freq < (policy->min * 1000) || freq > (policy->max * 1000)) |
103 | #if defined(CONFIG_CPU_SH3) | 59 | return -EINVAL; |
104 | frqcr |= (newstate & 0x4000) << 14; | 60 | |
105 | frqcr |= (newstate & 0x000c) << 2; | 61 | pr_debug("cpufreq: requested frequency %u Hz\n", target_freq * 1000); |
106 | #elif defined(CONFIG_CPU_SH4) | ||
107 | /* | ||
108 | * FRQCR.PLL2EN is 1, we need to allow the PLL to stabilize by | ||
109 | * initializing the WDT. | ||
110 | */ | ||
111 | if (frqcr & (1 << 9)) { | ||
112 | __u8 csr; | ||
113 | |||
114 | /* | ||
115 | * Set the overflow period to the highest available, | ||
116 | * in this case a 1/4096 division ratio yields a 5.25ms | ||
117 | * overflow period. See asm-sh/watchdog.h for more | ||
118 | * information and a range of other divisors. | ||
119 | */ | ||
120 | csr = sh_wdt_read_csr(); | ||
121 | csr |= WTCSR_CKS_4096; | ||
122 | sh_wdt_write_csr(csr); | ||
123 | |||
124 | sh_wdt_write_cnt(0); | ||
125 | } | ||
126 | frqcr &= 0x0e00; /* Clear ifc, bfc, pfc */ | ||
127 | frqcr |= get_ifc_value(clock_sets[set].ifc) << 6; | ||
128 | frqcr |= get_bfc_value(clock_sets[set].bfc) << 3; | ||
129 | frqcr |= get_pfc_value(clock_sets[set].pfc); | ||
130 | #endif | ||
131 | ctrl_outw(frqcr, FRQCR); | ||
132 | sh_cpufreq_update_clocks(set); | ||
133 | 62 | ||
63 | freqs.cpu = cpu; | ||
64 | freqs.old = sh_cpufreq_get(cpu); | ||
65 | freqs.new = (freq + 500) / 1000; | ||
66 | freqs.flags = 0; | ||
67 | |||
68 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | ||
134 | set_cpus_allowed(current, cpus_allowed); | 69 | set_cpus_allowed(current, cpus_allowed); |
70 | clk_set_rate(cpuclk, freq); | ||
135 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | 71 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); |
136 | 72 | ||
73 | pr_debug("cpufreq: set frequency %lu Hz\n", freq); | ||
74 | |||
137 | return 0; | 75 | return 0; |
138 | } | 76 | } |
139 | 77 | ||
140 | static int sh_cpufreq_cpu_init(struct cpufreq_policy *policy) | 78 | static int sh_cpufreq_cpu_init(struct cpufreq_policy *policy) |
141 | { | 79 | { |
142 | unsigned int min_freq, max_freq; | 80 | printk(KERN_INFO "cpufreq: SuperH CPU frequency driver.\n"); |
143 | unsigned int ifc, bfc, pfc; | ||
144 | 81 | ||
145 | if (!cpu_online(policy->cpu)) | 82 | if (!cpu_online(policy->cpu)) |
146 | return -ENODEV; | 83 | return -ENODEV; |
147 | 84 | ||
148 | /* Update our maximum clock set */ | 85 | cpuclk = clk_get(NULL, "cpu_clk"); |
149 | get_current_frequency_divisors(&ifc, &bfc, &pfc); | 86 | if (IS_ERR(cpuclk)) { |
150 | clock_sets[MAX_CLOCK_SET].ifc = ifc; | 87 | printk(KERN_ERR "cpufreq: couldn't get CPU clk\n"); |
151 | clock_sets[MAX_CLOCK_SET].bfc = bfc; | 88 | return PTR_ERR(cpuclk); |
152 | clock_sets[MAX_CLOCK_SET].pfc = pfc; | 89 | } |
153 | |||
154 | /* Convert from Hz to kHz */ | ||
155 | max_freq = current_cpu_data.cpu_clock / 1000; | ||
156 | min_freq = (current_cpu_data.master_clock / clock_sets[MIN_CLOCK_SET].ifc) / 1000; | ||
157 | |||
158 | sh_freqs[SH_FREQ_MAX].frequency = max_freq; | ||
159 | sh_freqs[SH_FREQ_MIN].frequency = min_freq; | ||
160 | 90 | ||
161 | /* cpuinfo and default policy values */ | 91 | /* cpuinfo and default policy values */ |
162 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; | 92 | policy->cpuinfo.min_freq = (clk_round_rate(cpuclk, 1) + 500) / 1000; |
93 | policy->cpuinfo.max_freq = (clk_round_rate(cpuclk, ~0UL) + 500) / 1000; | ||
163 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; | 94 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; |
164 | policy->cur = max_freq; | ||
165 | 95 | ||
166 | return cpufreq_frequency_table_cpuinfo(policy, &sh_freqs[0]); | 96 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; |
167 | } | 97 | policy->cur = sh_cpufreq_get(policy->cpu); |
98 | policy->min = policy->cpuinfo.min_freq; | ||
99 | policy->max = policy->cpuinfo.max_freq; | ||
168 | 100 | ||
169 | static int sh_cpufreq_verify(struct cpufreq_policy *policy) | ||
170 | { | ||
171 | return cpufreq_frequency_table_verify(policy, &sh_freqs[0]); | ||
172 | } | ||
173 | 101 | ||
174 | static int sh_cpufreq_target(struct cpufreq_policy *policy, | 102 | /* |
175 | unsigned int target_freq, | 103 | * Catch the cases where the clock framework hasn't been wired up |
176 | unsigned int relation) | 104 | * properly to support scaling. |
177 | { | 105 | */ |
178 | unsigned int set, idx = 0; | 106 | if (unlikely(policy->min == policy->max)) { |
107 | printk(KERN_ERR "cpufreq: clock framework rate rounding " | ||
108 | "not supported on this CPU.\n"); | ||
179 | 109 | ||
180 | if (cpufreq_frequency_table_target(policy, &sh_freqs[0], target_freq, relation, &idx)) | 110 | clk_put(cpuclk); |
181 | return -EINVAL; | 111 | return -EINVAL; |
112 | } | ||
182 | 113 | ||
183 | set = (idx == SH_FREQ_MIN) ? MIN_CLOCK_SET : MAX_CLOCK_SET; | 114 | printk(KERN_INFO "cpufreq: Frequencies - Minimum %u.%03u MHz, " |
115 | "Maximum %u.%03u MHz.\n", | ||
116 | policy->min / 1000, policy->min % 1000, | ||
117 | policy->max / 1000, policy->max % 1000); | ||
184 | 118 | ||
185 | sh_cpufreq_setstate(policy->cpu, set); | 119 | return 0; |
120 | } | ||
186 | 121 | ||
122 | static int sh_cpufreq_verify(struct cpufreq_policy *policy) | ||
123 | { | ||
124 | cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, | ||
125 | policy->cpuinfo.max_freq); | ||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int sh_cpufreq_exit(struct cpufreq_policy *policy) | ||
130 | { | ||
131 | clk_put(cpuclk); | ||
187 | return 0; | 132 | return 0; |
188 | } | 133 | } |
189 | 134 | ||
190 | static struct cpufreq_driver sh_cpufreq_driver = { | 135 | static struct cpufreq_driver sh_cpufreq_driver = { |
191 | .owner = THIS_MODULE, | 136 | .owner = THIS_MODULE, |
192 | .name = "SH cpufreq", | 137 | .name = "sh", |
193 | .init = sh_cpufreq_cpu_init, | 138 | .init = sh_cpufreq_cpu_init, |
194 | .verify = sh_cpufreq_verify, | 139 | .verify = sh_cpufreq_verify, |
195 | .target = sh_cpufreq_target, | 140 | .target = sh_cpufreq_target, |
141 | .get = sh_cpufreq_get, | ||
142 | .exit = sh_cpufreq_exit, | ||
196 | }; | 143 | }; |
197 | 144 | ||
198 | static int __init sh_cpufreq_init(void) | 145 | static int __init sh_cpufreq_module_init(void) |
199 | { | 146 | { |
200 | if (!current_cpu_data.cpu_clock) | 147 | return cpufreq_register_driver(&sh_cpufreq_driver); |
201 | return -EINVAL; | ||
202 | if (cpufreq_register_driver(&sh_cpufreq_driver)) | ||
203 | return -EINVAL; | ||
204 | |||
205 | return 0; | ||
206 | } | 148 | } |
207 | 149 | ||
208 | static void __exit sh_cpufreq_exit(void) | 150 | static void __exit sh_cpufreq_module_exit(void) |
209 | { | 151 | { |
210 | cpufreq_unregister_driver(&sh_cpufreq_driver); | 152 | cpufreq_unregister_driver(&sh_cpufreq_driver); |
211 | } | 153 | } |
212 | 154 | ||
213 | module_init(sh_cpufreq_init); | 155 | module_init(sh_cpufreq_module_init); |
214 | module_exit(sh_cpufreq_exit); | 156 | module_exit(sh_cpufreq_module_exit); |
215 | 157 | ||
216 | MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>"); | 158 | MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>"); |
217 | MODULE_DESCRIPTION("cpufreq driver for SuperH"); | 159 | MODULE_DESCRIPTION("cpufreq driver for SuperH"); |
218 | MODULE_LICENSE("GPL"); | 160 | MODULE_LICENSE("GPL"); |
219 | |||
diff --git a/arch/sh/kernel/head.S b/arch/sh/kernel/head.S index 71a3ad7d283e..0bccc0ca5a0f 100644 --- a/arch/sh/kernel/head.S +++ b/arch/sh/kernel/head.S | |||
@@ -36,7 +36,8 @@ ENTRY(empty_zero_page) | |||
36 | 1: | 36 | 1: |
37 | .skip PAGE_SIZE - empty_zero_page - 1b | 37 | .skip PAGE_SIZE - empty_zero_page - 1b |
38 | 38 | ||
39 | .text | 39 | .section .text.head, "ax" |
40 | |||
40 | /* | 41 | /* |
41 | * Condition at the entry of _stext: | 42 | * Condition at the entry of _stext: |
42 | * | 43 | * |
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index 27897798867a..03404987528d 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c | |||
@@ -253,14 +253,7 @@ void __init init_IRQ(void) | |||
253 | #ifdef CONFIG_CPU_HAS_PINT_IRQ | 253 | #ifdef CONFIG_CPU_HAS_PINT_IRQ |
254 | init_IRQ_pint(); | 254 | init_IRQ_pint(); |
255 | #endif | 255 | #endif |
256 | 256 | plat_irq_setup(); | |
257 | #ifdef CONFIG_CPU_HAS_INTC2_IRQ | ||
258 | init_IRQ_intc2(); | ||
259 | #endif | ||
260 | |||
261 | #ifdef CONFIG_CPU_HAS_IPR_IRQ | ||
262 | init_IRQ_ipr(); | ||
263 | #endif | ||
264 | 257 | ||
265 | /* Perform the machine specific initialisation */ | 258 | /* Perform the machine specific initialisation */ |
266 | if (sh_mv.mv_init_irq) | 259 | if (sh_mv.mv_init_irq) |
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index de8e6e2f2c87..c14a3e95d0b1 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/fs.h> | 21 | #include <linux/fs.h> |
22 | #include <linux/mm.h> | 22 | #include <linux/mm.h> |
23 | #include <linux/kexec.h> | 23 | #include <linux/kexec.h> |
24 | #include <linux/module.h> | ||
24 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
25 | #include <asm/io.h> | 26 | #include <asm/io.h> |
26 | #include <asm/page.h> | 27 | #include <asm/page.h> |
@@ -78,7 +79,11 @@ static char __initdata command_line[COMMAND_LINE_SIZE] = { 0, }; | |||
78 | static struct resource code_resource = { .name = "Kernel code", }; | 79 | static struct resource code_resource = { .name = "Kernel code", }; |
79 | static struct resource data_resource = { .name = "Kernel data", }; | 80 | static struct resource data_resource = { .name = "Kernel data", }; |
80 | 81 | ||
81 | unsigned long memory_start, memory_end; | 82 | unsigned long memory_start; |
83 | EXPORT_SYMBOL(memory_start); | ||
84 | |||
85 | unsigned long memory_end; | ||
86 | EXPORT_SYMBOL(memory_end); | ||
82 | 87 | ||
83 | static int __init early_parse_mem(char *p) | 88 | static int __init early_parse_mem(char *p) |
84 | { | 89 | { |
diff --git a/arch/sh/kernel/sh_bios.c b/arch/sh/kernel/sh_bios.c index 5b53e10bb9cd..d1bcac4fa269 100644 --- a/arch/sh/kernel/sh_bios.c +++ b/arch/sh/kernel/sh_bios.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * Copyright (C) 2000 Greg Banks, Mitch Davis | 5 | * Copyright (C) 2000 Greg Banks, Mitch Davis |
6 | * | 6 | * |
7 | */ | 7 | */ |
8 | 8 | #include <linux/module.h> | |
9 | #include <asm/sh_bios.h> | 9 | #include <asm/sh_bios.h> |
10 | 10 | ||
11 | #define BIOS_CALL_CONSOLE_WRITE 0 | 11 | #define BIOS_CALL_CONSOLE_WRITE 0 |
@@ -63,6 +63,7 @@ void sh_bios_gdb_detach(void) | |||
63 | { | 63 | { |
64 | sh_bios_call(BIOS_CALL_GDB_DETACH, 0, 0, 0, 0); | 64 | sh_bios_call(BIOS_CALL_GDB_DETACH, 0, 0, 0, 0); |
65 | } | 65 | } |
66 | EXPORT_SYMBOL(sh_bios_gdb_detach); | ||
66 | 67 | ||
67 | void sh_bios_get_node_addr (unsigned char *node_addr) | 68 | void sh_bios_get_node_addr (unsigned char *node_addr) |
68 | { | 69 | { |
diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c index c968dcf09eee..37aef0a85197 100644 --- a/arch/sh/kernel/sh_ksyms.c +++ b/arch/sh/kernel/sh_ksyms.c | |||
@@ -63,10 +63,43 @@ EXPORT_SYMBOL(__const_udelay); | |||
63 | /* These symbols are generated by the compiler itself */ | 63 | /* These symbols are generated by the compiler itself */ |
64 | DECLARE_EXPORT(__udivsi3); | 64 | DECLARE_EXPORT(__udivsi3); |
65 | DECLARE_EXPORT(__sdivsi3); | 65 | DECLARE_EXPORT(__sdivsi3); |
66 | DECLARE_EXPORT(__ashrsi3); | ||
67 | DECLARE_EXPORT(__ashlsi3); | ||
66 | DECLARE_EXPORT(__ashrdi3); | 68 | DECLARE_EXPORT(__ashrdi3); |
67 | DECLARE_EXPORT(__ashldi3); | 69 | DECLARE_EXPORT(__ashldi3); |
70 | DECLARE_EXPORT(__ashiftrt_r4_6); | ||
71 | DECLARE_EXPORT(__ashiftrt_r4_7); | ||
72 | DECLARE_EXPORT(__ashiftrt_r4_8); | ||
73 | DECLARE_EXPORT(__ashiftrt_r4_9); | ||
74 | DECLARE_EXPORT(__ashiftrt_r4_10); | ||
75 | DECLARE_EXPORT(__ashiftrt_r4_11); | ||
76 | DECLARE_EXPORT(__ashiftrt_r4_12); | ||
77 | DECLARE_EXPORT(__ashiftrt_r4_13); | ||
78 | DECLARE_EXPORT(__ashiftrt_r4_14); | ||
79 | DECLARE_EXPORT(__ashiftrt_r4_15); | ||
80 | DECLARE_EXPORT(__ashiftrt_r4_20); | ||
81 | DECLARE_EXPORT(__ashiftrt_r4_21); | ||
82 | DECLARE_EXPORT(__ashiftrt_r4_22); | ||
83 | DECLARE_EXPORT(__ashiftrt_r4_23); | ||
84 | DECLARE_EXPORT(__ashiftrt_r4_24); | ||
85 | DECLARE_EXPORT(__ashiftrt_r4_27); | ||
86 | DECLARE_EXPORT(__ashiftrt_r4_30); | ||
87 | DECLARE_EXPORT(__lshrsi3); | ||
68 | DECLARE_EXPORT(__lshrdi3); | 88 | DECLARE_EXPORT(__lshrdi3); |
89 | DECLARE_EXPORT(__movstrSI8); | ||
90 | DECLARE_EXPORT(__movstrSI12); | ||
69 | DECLARE_EXPORT(__movstrSI16); | 91 | DECLARE_EXPORT(__movstrSI16); |
92 | DECLARE_EXPORT(__movstrSI20); | ||
93 | DECLARE_EXPORT(__movstrSI24); | ||
94 | DECLARE_EXPORT(__movstrSI28); | ||
95 | DECLARE_EXPORT(__movstrSI32); | ||
96 | DECLARE_EXPORT(__movstrSI36); | ||
97 | DECLARE_EXPORT(__movstrSI40); | ||
98 | DECLARE_EXPORT(__movstrSI44); | ||
99 | DECLARE_EXPORT(__movstrSI48); | ||
100 | DECLARE_EXPORT(__movstrSI52); | ||
101 | DECLARE_EXPORT(__movstrSI56); | ||
102 | DECLARE_EXPORT(__movstrSI60); | ||
70 | #if __GNUC__ == 4 | 103 | #if __GNUC__ == 4 |
71 | DECLARE_EXPORT(__movmem); | 104 | DECLARE_EXPORT(__movmem); |
72 | #else | 105 | #else |
@@ -115,7 +148,9 @@ EXPORT_SYMBOL(synchronize_irq); | |||
115 | #endif | 148 | #endif |
116 | 149 | ||
117 | EXPORT_SYMBOL(csum_partial); | 150 | EXPORT_SYMBOL(csum_partial); |
151 | EXPORT_SYMBOL(csum_partial_copy_generic); | ||
118 | #ifdef CONFIG_IPV6 | 152 | #ifdef CONFIG_IPV6 |
119 | EXPORT_SYMBOL(csum_ipv6_magic); | 153 | EXPORT_SYMBOL(csum_ipv6_magic); |
120 | #endif | 154 | #endif |
121 | EXPORT_SYMBOL(clear_page); | 155 | EXPORT_SYMBOL(clear_page); |
156 | EXPORT_SYMBOL(__clear_user); | ||
diff --git a/arch/sh/kernel/syscalls.S b/arch/sh/kernel/syscalls.S index ff5656e60c05..91fb7024e06f 100644 --- a/arch/sh/kernel/syscalls.S +++ b/arch/sh/kernel/syscalls.S | |||
@@ -358,3 +358,4 @@ ENTRY(sys_call_table) | |||
358 | .long sys_signalfd | 358 | .long sys_signalfd |
359 | .long sys_timerfd | 359 | .long sys_timerfd |
360 | .long sys_eventfd | 360 | .long sys_eventfd |
361 | .long sys_fallocate | ||
diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S index 5ba216180b30..9cb95af7b090 100644 --- a/arch/sh/kernel/vmlinux.lds.S +++ b/arch/sh/kernel/vmlinux.lds.S | |||
@@ -22,6 +22,7 @@ SECTIONS | |||
22 | *(.empty_zero_page) | 22 | *(.empty_zero_page) |
23 | } = 0 | 23 | } = 0 |
24 | .text : { | 24 | .text : { |
25 | *(.text.head) | ||
25 | TEXT_TEXT | 26 | TEXT_TEXT |
26 | SCHED_TEXT | 27 | SCHED_TEXT |
27 | LOCK_TEXT | 28 | LOCK_TEXT |
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 28d79a474cde..70da1c8d407e 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig | |||
@@ -120,14 +120,14 @@ config CPU_SUBTYPE_SH7712 | |||
120 | config CPU_SUBTYPE_SH7750 | 120 | config CPU_SUBTYPE_SH7750 |
121 | bool "Support SH7750 processor" | 121 | bool "Support SH7750 processor" |
122 | select CPU_SH4 | 122 | select CPU_SH4 |
123 | select CPU_HAS_IPR_IRQ | 123 | select CPU_HAS_INTC_IRQ |
124 | help | 124 | help |
125 | Select SH7750 if you have a 200 Mhz SH-4 HD6417750 CPU. | 125 | Select SH7750 if you have a 200 Mhz SH-4 HD6417750 CPU. |
126 | 126 | ||
127 | config CPU_SUBTYPE_SH7091 | 127 | config CPU_SUBTYPE_SH7091 |
128 | bool "Support SH7091 processor" | 128 | bool "Support SH7091 processor" |
129 | select CPU_SH4 | 129 | select CPU_SH4 |
130 | select CPU_HAS_IPR_IRQ | 130 | select CPU_HAS_INTC_IRQ |
131 | help | 131 | help |
132 | Select SH7091 if you have an SH-4 based Sega device (such as | 132 | Select SH7091 if you have an SH-4 based Sega device (such as |
133 | the Dreamcast, Naomi, and Naomi 2). | 133 | the Dreamcast, Naomi, and Naomi 2). |
@@ -135,17 +135,17 @@ config CPU_SUBTYPE_SH7091 | |||
135 | config CPU_SUBTYPE_SH7750R | 135 | config CPU_SUBTYPE_SH7750R |
136 | bool "Support SH7750R processor" | 136 | bool "Support SH7750R processor" |
137 | select CPU_SH4 | 137 | select CPU_SH4 |
138 | select CPU_HAS_IPR_IRQ | 138 | select CPU_HAS_INTC_IRQ |
139 | 139 | ||
140 | config CPU_SUBTYPE_SH7750S | 140 | config CPU_SUBTYPE_SH7750S |
141 | bool "Support SH7750S processor" | 141 | bool "Support SH7750S processor" |
142 | select CPU_SH4 | 142 | select CPU_SH4 |
143 | select CPU_HAS_IPR_IRQ | 143 | select CPU_HAS_INTC_IRQ |
144 | 144 | ||
145 | config CPU_SUBTYPE_SH7751 | 145 | config CPU_SUBTYPE_SH7751 |
146 | bool "Support SH7751 processor" | 146 | bool "Support SH7751 processor" |
147 | select CPU_SH4 | 147 | select CPU_SH4 |
148 | select CPU_HAS_IPR_IRQ | 148 | select CPU_HAS_INTC_IRQ |
149 | help | 149 | help |
150 | Select SH7751 if you have a 166 Mhz SH-4 HD6417751 CPU, | 150 | Select SH7751 if you have a 166 Mhz SH-4 HD6417751 CPU, |
151 | or if you have a HD6417751R CPU. | 151 | or if you have a HD6417751R CPU. |
@@ -153,7 +153,7 @@ config CPU_SUBTYPE_SH7751 | |||
153 | config CPU_SUBTYPE_SH7751R | 153 | config CPU_SUBTYPE_SH7751R |
154 | bool "Support SH7751R processor" | 154 | bool "Support SH7751R processor" |
155 | select CPU_SH4 | 155 | select CPU_SH4 |
156 | select CPU_HAS_IPR_IRQ | 156 | select CPU_HAS_INTC_IRQ |
157 | 157 | ||
158 | config CPU_SUBTYPE_SH7760 | 158 | config CPU_SUBTYPE_SH7760 |
159 | bool "Support SH7760 processor" | 159 | bool "Support SH7760 processor" |
@@ -189,7 +189,7 @@ config CPU_SUBTYPE_SH7770 | |||
189 | config CPU_SUBTYPE_SH7780 | 189 | config CPU_SUBTYPE_SH7780 |
190 | bool "Support SH7780 processor" | 190 | bool "Support SH7780 processor" |
191 | select CPU_SH4A | 191 | select CPU_SH4A |
192 | select CPU_HAS_INTC2_IRQ | 192 | select CPU_HAS_INTC_IRQ |
193 | 193 | ||
194 | config CPU_SUBTYPE_SH7785 | 194 | config CPU_SUBTYPE_SH7785 |
195 | bool "Support SH7785 processor" | 195 | bool "Support SH7785 processor" |
@@ -217,7 +217,7 @@ config CPU_SUBTYPE_SH7722 | |||
217 | bool "Support SH7722 processor" | 217 | bool "Support SH7722 processor" |
218 | select CPU_SH4AL_DSP | 218 | select CPU_SH4AL_DSP |
219 | select CPU_SHX2 | 219 | select CPU_SHX2 |
220 | select CPU_HAS_IPR_IRQ | 220 | select CPU_HAS_INTC_IRQ |
221 | select ARCH_SPARSEMEM_ENABLE | 221 | select ARCH_SPARSEMEM_ENABLE |
222 | select SYS_SUPPORTS_NUMA | 222 | select SYS_SUPPORTS_NUMA |
223 | 223 | ||
diff --git a/arch/sh64/configs/cayman_defconfig b/arch/sh64/configs/cayman_defconfig index ed035084b053..784434143343 100644 --- a/arch/sh64/configs/cayman_defconfig +++ b/arch/sh64/configs/cayman_defconfig | |||
@@ -1,11 +1,12 @@ | |||
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-rc1 | 3 | # Linux kernel version: 2.6.22 |
4 | # Mon May 14 08:43:31 2007 | 4 | # Fri Jul 20 12:28:34 2007 |
5 | # | 5 | # |
6 | CONFIG_SUPERH=y | 6 | CONFIG_SUPERH=y |
7 | CONFIG_SUPERH64=y | 7 | CONFIG_SUPERH64=y |
8 | CONFIG_MMU=y | 8 | CONFIG_MMU=y |
9 | CONFIG_QUICKLIST=y | ||
9 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | 10 | CONFIG_RWSEM_GENERIC_SPINLOCK=y |
10 | CONFIG_GENERIC_FIND_NEXT_BIT=y | 11 | CONFIG_GENERIC_FIND_NEXT_BIT=y |
11 | CONFIG_GENERIC_HWEIGHT=y | 12 | CONFIG_GENERIC_HWEIGHT=y |
@@ -32,7 +33,7 @@ CONFIG_SWAP=y | |||
32 | CONFIG_POSIX_MQUEUE=y | 33 | CONFIG_POSIX_MQUEUE=y |
33 | # CONFIG_BSD_PROCESS_ACCT is not set | 34 | # CONFIG_BSD_PROCESS_ACCT is not set |
34 | # CONFIG_TASKSTATS is not set | 35 | # CONFIG_TASKSTATS is not set |
35 | # CONFIG_UTS_NS is not set | 36 | # CONFIG_USER_NS is not set |
36 | # CONFIG_AUDIT is not set | 37 | # CONFIG_AUDIT is not set |
37 | # CONFIG_IKCONFIG is not set | 38 | # CONFIG_IKCONFIG is not set |
38 | CONFIG_LOG_BUF_SHIFT=14 | 39 | CONFIG_LOG_BUF_SHIFT=14 |
@@ -66,19 +67,12 @@ CONFIG_SLAB=y | |||
66 | CONFIG_RT_MUTEXES=y | 67 | CONFIG_RT_MUTEXES=y |
67 | # CONFIG_TINY_SHMEM is not set | 68 | # CONFIG_TINY_SHMEM is not set |
68 | CONFIG_BASE_SMALL=0 | 69 | CONFIG_BASE_SMALL=0 |
69 | |||
70 | # | ||
71 | # Loadable module support | ||
72 | # | ||
73 | # CONFIG_MODULES is not set | 70 | # CONFIG_MODULES is not set |
74 | |||
75 | # | ||
76 | # Block layer | ||
77 | # | ||
78 | CONFIG_BLOCK=y | 71 | CONFIG_BLOCK=y |
79 | # CONFIG_LBD is not set | 72 | # CONFIG_LBD is not set |
80 | # CONFIG_BLK_DEV_IO_TRACE is not set | 73 | # CONFIG_BLK_DEV_IO_TRACE is not set |
81 | # CONFIG_LSF is not set | 74 | # CONFIG_LSF is not set |
75 | # CONFIG_BLK_DEV_BSG is not set | ||
82 | 76 | ||
83 | # | 77 | # |
84 | # IO Schedulers | 78 | # IO Schedulers |
@@ -156,6 +150,8 @@ CONFIG_FLAT_NODE_MEM_MAP=y | |||
156 | CONFIG_SPLIT_PTLOCK_CPUS=4 | 150 | CONFIG_SPLIT_PTLOCK_CPUS=4 |
157 | # CONFIG_RESOURCES_64BIT is not set | 151 | # CONFIG_RESOURCES_64BIT is not set |
158 | CONFIG_ZONE_DMA_FLAG=0 | 152 | CONFIG_ZONE_DMA_FLAG=0 |
153 | CONFIG_NR_QUICK=1 | ||
154 | CONFIG_VIRT_TO_BUS=y | ||
159 | 155 | ||
160 | # | 156 | # |
161 | # Bus options (PCI, PCMCIA, EISA, MCA, ISA) | 157 | # Bus options (PCI, PCMCIA, EISA, MCA, ISA) |
@@ -175,7 +171,6 @@ CONFIG_SH_PCIDMA_NONCOHERENT=y | |||
175 | # Executable file formats | 171 | # Executable file formats |
176 | # | 172 | # |
177 | CONFIG_BINFMT_ELF=y | 173 | CONFIG_BINFMT_ELF=y |
178 | # CONFIG_BINFMT_FLAT is not set | ||
179 | # CONFIG_BINFMT_MISC is not set | 174 | # CONFIG_BINFMT_MISC is not set |
180 | 175 | ||
181 | # | 176 | # |
@@ -225,20 +220,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic" | |||
225 | # CONFIG_INET6_TUNNEL is not set | 220 | # CONFIG_INET6_TUNNEL is not set |
226 | # CONFIG_NETWORK_SECMARK is not set | 221 | # CONFIG_NETWORK_SECMARK is not set |
227 | # CONFIG_NETFILTER is not set | 222 | # CONFIG_NETFILTER is not set |
228 | |||
229 | # | ||
230 | # DCCP Configuration (EXPERIMENTAL) | ||
231 | # | ||
232 | # CONFIG_IP_DCCP is not set | 223 | # CONFIG_IP_DCCP is not set |
233 | |||
234 | # | ||
235 | # SCTP Configuration (EXPERIMENTAL) | ||
236 | # | ||
237 | # CONFIG_IP_SCTP is not set | 224 | # CONFIG_IP_SCTP is not set |
238 | |||
239 | # | ||
240 | # TIPC Configuration (EXPERIMENTAL) | ||
241 | # | ||
242 | # CONFIG_TIPC is not set | 225 | # CONFIG_TIPC is not set |
243 | # CONFIG_ATM is not set | 226 | # CONFIG_ATM is not set |
244 | # CONFIG_BRIDGE is not set | 227 | # CONFIG_BRIDGE is not set |
@@ -274,6 +257,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" | |||
274 | # CONFIG_MAC80211 is not set | 257 | # CONFIG_MAC80211 is not set |
275 | # CONFIG_IEEE80211 is not set | 258 | # CONFIG_IEEE80211 is not set |
276 | # CONFIG_RFKILL is not set | 259 | # CONFIG_RFKILL is not set |
260 | # CONFIG_NET_9P is not set | ||
277 | 261 | ||
278 | # | 262 | # |
279 | # Device Drivers | 263 | # Device Drivers |
@@ -288,26 +272,10 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y | |||
288 | # CONFIG_DEBUG_DRIVER is not set | 272 | # CONFIG_DEBUG_DRIVER is not set |
289 | # CONFIG_DEBUG_DEVRES is not set | 273 | # CONFIG_DEBUG_DEVRES is not set |
290 | # CONFIG_SYS_HYPERVISOR is not set | 274 | # CONFIG_SYS_HYPERVISOR is not set |
291 | |||
292 | # | ||
293 | # Connector - unified userspace <-> kernelspace linker | ||
294 | # | ||
295 | # CONFIG_CONNECTOR is not set | 275 | # CONFIG_CONNECTOR is not set |
296 | # CONFIG_MTD is not set | 276 | # CONFIG_MTD is not set |
297 | |||
298 | # | ||
299 | # Parallel port support | ||
300 | # | ||
301 | # CONFIG_PARPORT is not set | 277 | # CONFIG_PARPORT is not set |
302 | 278 | CONFIG_BLK_DEV=y | |
303 | # | ||
304 | # Plug and Play support | ||
305 | # | ||
306 | # CONFIG_PNPACPI is not set | ||
307 | |||
308 | # | ||
309 | # Block devices | ||
310 | # | ||
311 | # CONFIG_BLK_CPQ_DA is not set | 279 | # CONFIG_BLK_CPQ_DA is not set |
312 | # CONFIG_BLK_CPQ_CISS_DA is not set | 280 | # CONFIG_BLK_CPQ_CISS_DA is not set |
313 | # CONFIG_BLK_DEV_DAC960 is not set | 281 | # CONFIG_BLK_DEV_DAC960 is not set |
@@ -323,18 +291,11 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 | |||
323 | CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 | 291 | CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 |
324 | # CONFIG_CDROM_PKTCDVD is not set | 292 | # CONFIG_CDROM_PKTCDVD is not set |
325 | # CONFIG_ATA_OVER_ETH is not set | 293 | # CONFIG_ATA_OVER_ETH is not set |
326 | 294 | CONFIG_MISC_DEVICES=y | |
327 | # | ||
328 | # Misc devices | ||
329 | # | ||
330 | # CONFIG_PHANTOM is not set | 295 | # CONFIG_PHANTOM is not set |
296 | # CONFIG_EEPROM_93CX6 is not set | ||
331 | # CONFIG_SGI_IOC4 is not set | 297 | # CONFIG_SGI_IOC4 is not set |
332 | # CONFIG_TIFM_CORE is not set | 298 | # CONFIG_TIFM_CORE is not set |
333 | # CONFIG_BLINK is not set | ||
334 | |||
335 | # | ||
336 | # ATA/ATAPI/MFM/RLL support | ||
337 | # | ||
338 | # CONFIG_IDE is not set | 299 | # CONFIG_IDE is not set |
339 | 300 | ||
340 | # | 301 | # |
@@ -342,6 +303,7 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 | |||
342 | # | 303 | # |
343 | # CONFIG_RAID_ATTRS is not set | 304 | # CONFIG_RAID_ATTRS is not set |
344 | CONFIG_SCSI=y | 305 | CONFIG_SCSI=y |
306 | CONFIG_SCSI_DMA=y | ||
345 | # CONFIG_SCSI_TGT is not set | 307 | # CONFIG_SCSI_TGT is not set |
346 | # CONFIG_SCSI_NETLINK is not set | 308 | # CONFIG_SCSI_NETLINK is not set |
347 | CONFIG_SCSI_PROC_FS=y | 309 | CONFIG_SCSI_PROC_FS=y |
@@ -410,13 +372,8 @@ CONFIG_SCSI_SYM53C8XX_MMIO=y | |||
410 | # CONFIG_SCSI_DC390T is not set | 372 | # CONFIG_SCSI_DC390T is not set |
411 | # CONFIG_SCSI_NSP32 is not set | 373 | # CONFIG_SCSI_NSP32 is not set |
412 | # CONFIG_SCSI_DEBUG is not set | 374 | # CONFIG_SCSI_DEBUG is not set |
413 | # CONFIG_SCSI_ESP_CORE is not set | ||
414 | # CONFIG_SCSI_SRP is not set | 375 | # CONFIG_SCSI_SRP is not set |
415 | # CONFIG_ATA is not set | 376 | # CONFIG_ATA is not set |
416 | |||
417 | # | ||
418 | # Multi-device support (RAID and LVM) | ||
419 | # | ||
420 | # CONFIG_MD is not set | 377 | # CONFIG_MD is not set |
421 | 378 | ||
422 | # | 379 | # |
@@ -432,30 +389,16 @@ CONFIG_SCSI_SYM53C8XX_MMIO=y | |||
432 | # | 389 | # |
433 | # CONFIG_FIREWIRE is not set | 390 | # CONFIG_FIREWIRE is not set |
434 | # CONFIG_IEEE1394 is not set | 391 | # CONFIG_IEEE1394 is not set |
435 | |||
436 | # | ||
437 | # I2O device support | ||
438 | # | ||
439 | # CONFIG_I2O is not set | 392 | # CONFIG_I2O is not set |
440 | |||
441 | # | ||
442 | # Network device support | ||
443 | # | ||
444 | CONFIG_NETDEVICES=y | 393 | CONFIG_NETDEVICES=y |
394 | # CONFIG_NETDEVICES_MULTIQUEUE is not set | ||
445 | # CONFIG_DUMMY is not set | 395 | # CONFIG_DUMMY is not set |
446 | # CONFIG_BONDING is not set | 396 | # CONFIG_BONDING is not set |
397 | # CONFIG_MACVLAN is not set | ||
447 | # CONFIG_EQUALIZER is not set | 398 | # CONFIG_EQUALIZER is not set |
448 | # CONFIG_TUN is not set | 399 | # CONFIG_TUN is not set |
449 | |||
450 | # | ||
451 | # ARCnet devices | ||
452 | # | ||
453 | # CONFIG_ARCNET is not set | 400 | # CONFIG_ARCNET is not set |
454 | # CONFIG_PHYLIB is not set | 401 | # CONFIG_PHYLIB is not set |
455 | |||
456 | # | ||
457 | # Ethernet (10 or 100Mbit) | ||
458 | # | ||
459 | CONFIG_NET_ETHERNET=y | 402 | CONFIG_NET_ETHERNET=y |
460 | # CONFIG_MII is not set | 403 | # CONFIG_MII is not set |
461 | # CONFIG_STNIC is not set | 404 | # CONFIG_STNIC is not set |
@@ -464,10 +407,6 @@ CONFIG_NET_ETHERNET=y | |||
464 | # CONFIG_CASSINI is not set | 407 | # CONFIG_CASSINI is not set |
465 | # CONFIG_NET_VENDOR_3COM is not set | 408 | # CONFIG_NET_VENDOR_3COM is not set |
466 | # CONFIG_SMC91X is not set | 409 | # CONFIG_SMC91X is not set |
467 | |||
468 | # | ||
469 | # Tulip family network device support | ||
470 | # | ||
471 | CONFIG_NET_TULIP=y | 410 | CONFIG_NET_TULIP=y |
472 | # CONFIG_DE2104X is not set | 411 | # CONFIG_DE2104X is not set |
473 | CONFIG_TULIP=y | 412 | CONFIG_TULIP=y |
@@ -510,7 +449,6 @@ CONFIG_NETDEV_1000=y | |||
510 | # CONFIG_SIS190 is not set | 449 | # CONFIG_SIS190 is not set |
511 | # CONFIG_SKGE is not set | 450 | # CONFIG_SKGE is not set |
512 | # CONFIG_SKY2 is not set | 451 | # CONFIG_SKY2 is not set |
513 | # CONFIG_SK98LIN is not set | ||
514 | # CONFIG_VIA_VELOCITY is not set | 452 | # CONFIG_VIA_VELOCITY is not set |
515 | # CONFIG_TIGON3 is not set | 453 | # CONFIG_TIGON3 is not set |
516 | # CONFIG_BNX2 is not set | 454 | # CONFIG_BNX2 is not set |
@@ -524,11 +462,6 @@ CONFIG_NETDEV_10000=y | |||
524 | # CONFIG_MYRI10GE is not set | 462 | # CONFIG_MYRI10GE is not set |
525 | # CONFIG_NETXEN_NIC is not set | 463 | # CONFIG_NETXEN_NIC is not set |
526 | # CONFIG_MLX4_CORE is not set | 464 | # CONFIG_MLX4_CORE is not set |
527 | CONFIG_MLX4_DEBUG=y | ||
528 | |||
529 | # | ||
530 | # Token Ring devices | ||
531 | # | ||
532 | # CONFIG_TR is not set | 465 | # CONFIG_TR is not set |
533 | 466 | ||
534 | # | 467 | # |
@@ -546,15 +479,7 @@ CONFIG_MLX4_DEBUG=y | |||
546 | # CONFIG_NETCONSOLE is not set | 479 | # CONFIG_NETCONSOLE is not set |
547 | # CONFIG_NETPOLL is not set | 480 | # CONFIG_NETPOLL is not set |
548 | # CONFIG_NET_POLL_CONTROLLER is not set | 481 | # CONFIG_NET_POLL_CONTROLLER is not set |
549 | |||
550 | # | ||
551 | # ISDN subsystem | ||
552 | # | ||
553 | # CONFIG_ISDN is not set | 482 | # CONFIG_ISDN is not set |
554 | |||
555 | # | ||
556 | # Telephony Support | ||
557 | # | ||
558 | # CONFIG_PHONE is not set | 483 | # CONFIG_PHONE is not set |
559 | 484 | ||
560 | # | 485 | # |
@@ -562,6 +487,7 @@ CONFIG_MLX4_DEBUG=y | |||
562 | # | 487 | # |
563 | CONFIG_INPUT=y | 488 | CONFIG_INPUT=y |
564 | # CONFIG_INPUT_FF_MEMLESS is not set | 489 | # CONFIG_INPUT_FF_MEMLESS is not set |
490 | # CONFIG_INPUT_POLLDEV is not set | ||
565 | 491 | ||
566 | # | 492 | # |
567 | # Userland interfaces | 493 | # Userland interfaces |
@@ -638,10 +564,6 @@ CONFIG_SERIAL_CORE_CONSOLE=y | |||
638 | CONFIG_UNIX98_PTYS=y | 564 | CONFIG_UNIX98_PTYS=y |
639 | CONFIG_LEGACY_PTYS=y | 565 | CONFIG_LEGACY_PTYS=y |
640 | CONFIG_LEGACY_PTY_COUNT=256 | 566 | CONFIG_LEGACY_PTY_COUNT=256 |
641 | |||
642 | # | ||
643 | # IPMI | ||
644 | # | ||
645 | # CONFIG_IPMI_HANDLER is not set | 567 | # CONFIG_IPMI_HANDLER is not set |
646 | CONFIG_WATCHDOG=y | 568 | CONFIG_WATCHDOG=y |
647 | # CONFIG_WATCHDOG_NOWAYOUT is not set | 569 | # CONFIG_WATCHDOG_NOWAYOUT is not set |
@@ -658,15 +580,10 @@ CONFIG_WATCHDOG=y | |||
658 | # CONFIG_PCIPCWATCHDOG is not set | 580 | # CONFIG_PCIPCWATCHDOG is not set |
659 | # CONFIG_WDTPCI is not set | 581 | # CONFIG_WDTPCI is not set |
660 | CONFIG_HW_RANDOM=y | 582 | CONFIG_HW_RANDOM=y |
661 | # CONFIG_GEN_RTC is not set | ||
662 | # CONFIG_R3964 is not set | 583 | # CONFIG_R3964 is not set |
663 | # CONFIG_APPLICOM is not set | 584 | # CONFIG_APPLICOM is not set |
664 | # CONFIG_DRM is not set | 585 | # CONFIG_DRM is not set |
665 | # CONFIG_RAW_DRIVER is not set | 586 | # CONFIG_RAW_DRIVER is not set |
666 | |||
667 | # | ||
668 | # TPM devices | ||
669 | # | ||
670 | # CONFIG_TCG_TPM is not set | 587 | # CONFIG_TCG_TPM is not set |
671 | CONFIG_DEVPORT=y | 588 | CONFIG_DEVPORT=y |
672 | # CONFIG_I2C is not set | 589 | # CONFIG_I2C is not set |
@@ -676,20 +593,24 @@ CONFIG_DEVPORT=y | |||
676 | # | 593 | # |
677 | # CONFIG_SPI is not set | 594 | # CONFIG_SPI is not set |
678 | # CONFIG_SPI_MASTER is not set | 595 | # CONFIG_SPI_MASTER is not set |
679 | |||
680 | # | ||
681 | # Dallas's 1-wire bus | ||
682 | # | ||
683 | # CONFIG_W1 is not set | 596 | # CONFIG_W1 is not set |
597 | # CONFIG_POWER_SUPPLY is not set | ||
684 | CONFIG_HWMON=y | 598 | CONFIG_HWMON=y |
685 | # CONFIG_HWMON_VID is not set | 599 | # CONFIG_HWMON_VID is not set |
686 | # CONFIG_SENSORS_ABITUGURU is not set | 600 | # CONFIG_SENSORS_ABITUGURU is not set |
601 | # CONFIG_SENSORS_ABITUGURU3 is not set | ||
687 | # CONFIG_SENSORS_F71805F is not set | 602 | # CONFIG_SENSORS_F71805F is not set |
603 | # CONFIG_SENSORS_IT87 is not set | ||
604 | # CONFIG_SENSORS_PC87360 is not set | ||
688 | # CONFIG_SENSORS_PC87427 is not set | 605 | # CONFIG_SENSORS_PC87427 is not set |
606 | # CONFIG_SENSORS_SIS5595 is not set | ||
689 | # CONFIG_SENSORS_SMSC47M1 is not set | 607 | # CONFIG_SENSORS_SMSC47M1 is not set |
690 | # CONFIG_SENSORS_SMSC47B397 is not set | 608 | # CONFIG_SENSORS_SMSC47B397 is not set |
609 | # CONFIG_SENSORS_VIA686A is not set | ||
691 | # CONFIG_SENSORS_VT1211 is not set | 610 | # CONFIG_SENSORS_VT1211 is not set |
611 | # CONFIG_SENSORS_VT8231 is not set | ||
692 | # CONFIG_SENSORS_W83627HF is not set | 612 | # CONFIG_SENSORS_W83627HF is not set |
613 | # CONFIG_SENSORS_W83627EHF is not set | ||
693 | # CONFIG_HWMON_DEBUG_CHIP is not set | 614 | # CONFIG_HWMON_DEBUG_CHIP is not set |
694 | 615 | ||
695 | # | 616 | # |
@@ -739,7 +660,6 @@ CONFIG_FB_MODE_HELPERS=y | |||
739 | # CONFIG_FB_CYBER2000 is not set | 660 | # CONFIG_FB_CYBER2000 is not set |
740 | # CONFIG_FB_ASILIANT is not set | 661 | # CONFIG_FB_ASILIANT is not set |
741 | # CONFIG_FB_IMSTT is not set | 662 | # CONFIG_FB_IMSTT is not set |
742 | # CONFIG_FB_EPSON1355 is not set | ||
743 | # CONFIG_FB_S1D13XXX is not set | 663 | # CONFIG_FB_S1D13XXX is not set |
744 | # CONFIG_FB_NVIDIA is not set | 664 | # CONFIG_FB_NVIDIA is not set |
745 | # CONFIG_FB_RIVA is not set | 665 | # CONFIG_FB_RIVA is not set |
@@ -765,6 +685,7 @@ CONFIG_FB_KYRO=y | |||
765 | # | 685 | # |
766 | CONFIG_DUMMY_CONSOLE=y | 686 | CONFIG_DUMMY_CONSOLE=y |
767 | CONFIG_FRAMEBUFFER_CONSOLE=y | 687 | CONFIG_FRAMEBUFFER_CONSOLE=y |
688 | # CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set | ||
768 | # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set | 689 | # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set |
769 | CONFIG_FONTS=y | 690 | CONFIG_FONTS=y |
770 | # CONFIG_FONT_8x8 is not set | 691 | # CONFIG_FONT_8x8 is not set |
@@ -789,16 +710,10 @@ CONFIG_LOGO_SUPERH_CLUT224=y | |||
789 | # Sound | 710 | # Sound |
790 | # | 711 | # |
791 | # CONFIG_SOUND is not set | 712 | # CONFIG_SOUND is not set |
792 | 713 | CONFIG_HID_SUPPORT=y | |
793 | # | ||
794 | # HID Devices | ||
795 | # | ||
796 | CONFIG_HID=y | 714 | CONFIG_HID=y |
797 | # CONFIG_HID_DEBUG is not set | 715 | # CONFIG_HID_DEBUG is not set |
798 | 716 | CONFIG_USB_SUPPORT=y | |
799 | # | ||
800 | # USB support | ||
801 | # | ||
802 | CONFIG_USB_ARCH_HAS_HCD=y | 717 | CONFIG_USB_ARCH_HAS_HCD=y |
803 | CONFIG_USB_ARCH_HAS_OHCI=y | 718 | CONFIG_USB_ARCH_HAS_OHCI=y |
804 | CONFIG_USB_ARCH_HAS_EHCI=y | 719 | CONFIG_USB_ARCH_HAS_EHCI=y |
@@ -826,17 +741,9 @@ CONFIG_USB_ARCH_HAS_EHCI=y | |||
826 | # | 741 | # |
827 | # LED Triggers | 742 | # LED Triggers |
828 | # | 743 | # |
829 | |||
830 | # | ||
831 | # InfiniBand support | ||
832 | # | ||
833 | # CONFIG_INFINIBAND is not set | 744 | # CONFIG_INFINIBAND is not set |
834 | 745 | ||
835 | # | 746 | # |
836 | # EDAC - error detection and reporting (RAS) (EXPERIMENTAL) | ||
837 | # | ||
838 | |||
839 | # | ||
840 | # Real Time Clock | 747 | # Real Time Clock |
841 | # | 748 | # |
842 | # CONFIG_RTC_CLASS is not set | 749 | # CONFIG_RTC_CLASS is not set |
@@ -855,6 +762,11 @@ CONFIG_USB_ARCH_HAS_EHCI=y | |||
855 | # | 762 | # |
856 | 763 | ||
857 | # | 764 | # |
765 | # Userspace I/O | ||
766 | # | ||
767 | # CONFIG_UIO is not set | ||
768 | |||
769 | # | ||
858 | # File systems | 770 | # File systems |
859 | # | 771 | # |
860 | CONFIG_EXT2_FS=y | 772 | CONFIG_EXT2_FS=y |
@@ -950,7 +862,6 @@ CONFIG_SUNRPC=y | |||
950 | # CONFIG_NCP_FS is not set | 862 | # CONFIG_NCP_FS is not set |
951 | # CONFIG_CODA_FS is not set | 863 | # CONFIG_CODA_FS is not set |
952 | # CONFIG_AFS_FS is not set | 864 | # CONFIG_AFS_FS is not set |
953 | # CONFIG_9P_FS is not set | ||
954 | 865 | ||
955 | # | 866 | # |
956 | # Partition Types | 867 | # Partition Types |
@@ -1001,6 +912,7 @@ CONFIG_DEBUG_FS=y | |||
1001 | CONFIG_DEBUG_KERNEL=y | 912 | CONFIG_DEBUG_KERNEL=y |
1002 | # CONFIG_DEBUG_SHIRQ is not set | 913 | # CONFIG_DEBUG_SHIRQ is not set |
1003 | CONFIG_DETECT_SOFTLOCKUP=y | 914 | CONFIG_DETECT_SOFTLOCKUP=y |
915 | CONFIG_SCHED_DEBUG=y | ||
1004 | CONFIG_SCHEDSTATS=y | 916 | CONFIG_SCHEDSTATS=y |
1005 | # CONFIG_TIMER_STATS is not set | 917 | # CONFIG_TIMER_STATS is not set |
1006 | # CONFIG_DEBUG_SLAB is not set | 918 | # CONFIG_DEBUG_SLAB is not set |
@@ -1017,7 +929,6 @@ CONFIG_DEBUG_BUGVERBOSE=y | |||
1017 | # CONFIG_DEBUG_LIST is not set | 929 | # CONFIG_DEBUG_LIST is not set |
1018 | CONFIG_FRAME_POINTER=y | 930 | CONFIG_FRAME_POINTER=y |
1019 | CONFIG_FORCED_INLINING=y | 931 | CONFIG_FORCED_INLINING=y |
1020 | # CONFIG_RCU_TORTURE_TEST is not set | ||
1021 | # CONFIG_FAULT_INJECTION is not set | 932 | # CONFIG_FAULT_INJECTION is not set |
1022 | # CONFIG_EARLY_PRINTK is not set | 933 | # CONFIG_EARLY_PRINTK is not set |
1023 | # CONFIG_DEBUG_KERNEL_WITH_GDB_STUB is not set | 934 | # CONFIG_DEBUG_KERNEL_WITH_GDB_STUB is not set |
@@ -1033,10 +944,6 @@ CONFIG_SH64_SR_WATCH=y | |||
1033 | # | 944 | # |
1034 | # CONFIG_KEYS is not set | 945 | # CONFIG_KEYS is not set |
1035 | # CONFIG_SECURITY is not set | 946 | # CONFIG_SECURITY is not set |
1036 | |||
1037 | # | ||
1038 | # Cryptographic options | ||
1039 | # | ||
1040 | # CONFIG_CRYPTO is not set | 947 | # CONFIG_CRYPTO is not set |
1041 | 948 | ||
1042 | # | 949 | # |
@@ -1047,6 +954,7 @@ CONFIG_BITREVERSE=y | |||
1047 | # CONFIG_CRC16 is not set | 954 | # CONFIG_CRC16 is not set |
1048 | # CONFIG_CRC_ITU_T is not set | 955 | # CONFIG_CRC_ITU_T is not set |
1049 | CONFIG_CRC32=y | 956 | CONFIG_CRC32=y |
957 | # CONFIG_CRC7 is not set | ||
1050 | # CONFIG_LIBCRC32C is not set | 958 | # CONFIG_LIBCRC32C is not set |
1051 | CONFIG_PLIST=y | 959 | CONFIG_PLIST=y |
1052 | CONFIG_HAS_IOMEM=y | 960 | CONFIG_HAS_IOMEM=y |
diff --git a/arch/sh64/kernel/head.S b/arch/sh64/kernel/head.S index f3740ddbc471..186406d3ad9c 100644 --- a/arch/sh64/kernel/head.S +++ b/arch/sh64/kernel/head.S | |||
@@ -124,7 +124,7 @@ empty_bad_pte_table: | |||
124 | fpu_in_use: .quad 0 | 124 | fpu_in_use: .quad 0 |
125 | 125 | ||
126 | 126 | ||
127 | .section .text, "ax" | 127 | .section .text.head, "ax" |
128 | .balign L1_CACHE_BYTES | 128 | .balign L1_CACHE_BYTES |
129 | /* | 129 | /* |
130 | * Condition at the entry of __stext: | 130 | * Condition at the entry of __stext: |
diff --git a/arch/sh64/kernel/pci_sh5.c b/arch/sh64/kernel/pci_sh5.c index 3334f99b5835..388bb711f1b0 100644 --- a/arch/sh64/kernel/pci_sh5.c +++ b/arch/sh64/kernel/pci_sh5.c | |||
@@ -48,7 +48,7 @@ static void __init pci_fixup_ide_bases(struct pci_dev *d) | |||
48 | } | 48 | } |
49 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); | 49 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); |
50 | 50 | ||
51 | char * __init pcibios_setup(char *str) | 51 | char * __devinit pcibios_setup(char *str) |
52 | { | 52 | { |
53 | return str; | 53 | return str; |
54 | } | 54 | } |
@@ -497,7 +497,7 @@ static int __init pcibios_init(void) | |||
497 | 497 | ||
498 | subsys_initcall(pcibios_init); | 498 | subsys_initcall(pcibios_init); |
499 | 499 | ||
500 | void __init pcibios_fixup_bus(struct pci_bus *bus) | 500 | void __devinit pcibios_fixup_bus(struct pci_bus *bus) |
501 | { | 501 | { |
502 | struct pci_dev *dev = bus->self; | 502 | struct pci_dev *dev = bus->self; |
503 | int i; | 503 | int i; |
diff --git a/arch/sh64/kernel/syscalls.S b/arch/sh64/kernel/syscalls.S index a5c680d29384..abb94c05d07a 100644 --- a/arch/sh64/kernel/syscalls.S +++ b/arch/sh64/kernel/syscalls.S | |||
@@ -378,3 +378,4 @@ sys_call_table: | |||
378 | .long sys_signalfd | 378 | .long sys_signalfd |
379 | .long sys_timerfd /* 350 */ | 379 | .long sys_timerfd /* 350 */ |
380 | .long sys_eventfd | 380 | .long sys_eventfd |
381 | .long sys_fallocate | ||
diff --git a/arch/sh64/kernel/vmlinux.lds.S b/arch/sh64/kernel/vmlinux.lds.S index 8ac9c7c5f848..267b4f9af2e1 100644 --- a/arch/sh64/kernel/vmlinux.lds.S +++ b/arch/sh64/kernel/vmlinux.lds.S | |||
@@ -54,6 +54,7 @@ SECTIONS | |||
54 | } = 0 | 54 | } = 0 |
55 | 55 | ||
56 | .text : C_PHYS(.text) { | 56 | .text : C_PHYS(.text) { |
57 | *(.text.head) | ||
57 | TEXT_TEXT | 58 | TEXT_TEXT |
58 | *(.text64) | 59 | *(.text64) |
59 | *(.text..SHmedia32) | 60 | *(.text..SHmedia32) |
diff --git a/arch/sh64/mm/ioremap.c b/arch/sh64/mm/ioremap.c index ff26c02511aa..990857756d44 100644 --- a/arch/sh64/mm/ioremap.c +++ b/arch/sh64/mm/ioremap.c | |||
@@ -242,7 +242,7 @@ static void shmedia_free_io(struct resource *res) | |||
242 | release_resource(res); | 242 | release_resource(res); |
243 | } | 243 | } |
244 | 244 | ||
245 | static void *sh64_get_page(void) | 245 | static __init_refok void *sh64_get_page(void) |
246 | { | 246 | { |
247 | extern int after_bootmem; | 247 | extern int after_bootmem; |
248 | void *page; | 248 | void *page; |
diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S index 90b52d4dab9a..55722840859c 100644 --- a/arch/sparc/kernel/systbls.S +++ b/arch/sparc/kernel/systbls.S | |||
@@ -1,8 +1,7 @@ | |||
1 | /* $Id: systbls.S,v 1.103 2002/02/08 03:57:14 davem Exp $ | 1 | /* systbls.S: System call entry point tables for OS compatibility. |
2 | * systbls.S: System call entry point tables for OS compatibility. | ||
3 | * The native Linux system call table lives here also. | 2 | * The native Linux system call table lives here also. |
4 | * | 3 | * |
5 | * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) | 4 | * Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net) |
6 | * | 5 | * |
7 | * Based upon preliminary work which is: | 6 | * Based upon preliminary work which is: |
8 | * | 7 | * |
@@ -80,7 +79,7 @@ sys_call_table: | |||
80 | /*295*/ .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare | 79 | /*295*/ .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare |
81 | /*300*/ .long sys_set_robust_list, sys_get_robust_list, sys_migrate_pages, sys_mbind, sys_get_mempolicy | 80 | /*300*/ .long sys_set_robust_list, sys_get_robust_list, sys_migrate_pages, sys_mbind, sys_get_mempolicy |
82 | /*305*/ .long sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait | 81 | /*305*/ .long sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait |
83 | /*310*/ .long sys_utimensat, sys_signalfd, sys_timerfd, sys_eventfd | 82 | /*310*/ .long sys_utimensat, sys_signalfd, sys_timerfd, sys_eventfd, sys_fallocate |
84 | 83 | ||
85 | #ifdef CONFIG_SUNOS_EMUL | 84 | #ifdef CONFIG_SUNOS_EMUL |
86 | /* Now the SunOS syscall table. */ | 85 | /* Now the SunOS syscall table. */ |
@@ -198,6 +197,6 @@ sunos_sys_table: | |||
198 | .long sunos_nosys, sunos_nosys, sunos_nosys | 197 | .long sunos_nosys, sunos_nosys, sunos_nosys |
199 | .long sunos_nosys | 198 | .long sunos_nosys |
200 | /*310*/ .long sunos_nosys, sunos_nosys, sunos_nosys | 199 | /*310*/ .long sunos_nosys, sunos_nosys, sunos_nosys |
201 | .long sunos_nosys | 200 | .long sunos_nosys, sunos_nosys |
202 | 201 | ||
203 | #endif | 202 | #endif |
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index 45ebf91a280c..10e301970a44 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/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.22 |
4 | # Tue Jul 17 01:19:52 2007 | 4 | # Thu Jul 19 21:30:37 2007 |
5 | # | 5 | # |
6 | CONFIG_SPARC=y | 6 | CONFIG_SPARC=y |
7 | CONFIG_SPARC64=y | 7 | CONFIG_SPARC64=y |
@@ -16,6 +16,7 @@ CONFIG_ARCH_MAY_HAVE_PC_FDC=y | |||
16 | # CONFIG_ARCH_HAS_ILOG2_U32 is not set | 16 | # CONFIG_ARCH_HAS_ILOG2_U32 is not set |
17 | # CONFIG_ARCH_HAS_ILOG2_U64 is not set | 17 | # CONFIG_ARCH_HAS_ILOG2_U64 is not set |
18 | CONFIG_AUDIT_ARCH=y | 18 | CONFIG_AUDIT_ARCH=y |
19 | CONFIG_ARCH_NO_VIRT_TO_BUS=y | ||
19 | CONFIG_SPARC64_PAGE_SIZE_8KB=y | 20 | CONFIG_SPARC64_PAGE_SIZE_8KB=y |
20 | # CONFIG_SPARC64_PAGE_SIZE_64KB is not set | 21 | # CONFIG_SPARC64_PAGE_SIZE_64KB is not set |
21 | # CONFIG_SPARC64_PAGE_SIZE_512KB is not set | 22 | # CONFIG_SPARC64_PAGE_SIZE_512KB is not set |
@@ -148,7 +149,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 | |||
148 | CONFIG_RESOURCES_64BIT=y | 149 | CONFIG_RESOURCES_64BIT=y |
149 | CONFIG_ZONE_DMA_FLAG=0 | 150 | CONFIG_ZONE_DMA_FLAG=0 |
150 | CONFIG_NR_QUICK=1 | 151 | CONFIG_NR_QUICK=1 |
151 | CONFIG_VIRT_TO_BUS=y | ||
152 | CONFIG_SBUS=y | 152 | CONFIG_SBUS=y |
153 | CONFIG_SBUSCHAR=y | 153 | CONFIG_SBUSCHAR=y |
154 | CONFIG_SUN_AUXIO=y | 154 | CONFIG_SUN_AUXIO=y |
@@ -317,7 +317,6 @@ CONFIG_CONNECTOR=m | |||
317 | # CONFIG_PARPORT is not set | 317 | # CONFIG_PARPORT is not set |
318 | CONFIG_BLK_DEV=y | 318 | CONFIG_BLK_DEV=y |
319 | # CONFIG_BLK_DEV_FD is not set | 319 | # CONFIG_BLK_DEV_FD is not set |
320 | # CONFIG_BLK_CPQ_DA is not set | ||
321 | # CONFIG_BLK_CPQ_CISS_DA is not set | 320 | # CONFIG_BLK_CPQ_CISS_DA is not set |
322 | # CONFIG_BLK_DEV_DAC960 is not set | 321 | # CONFIG_BLK_DEV_DAC960 is not set |
323 | # CONFIG_BLK_DEV_UMEM is not set | 322 | # CONFIG_BLK_DEV_UMEM is not set |
@@ -470,10 +469,6 @@ CONFIG_ISCSI_TCP=m | |||
470 | # CONFIG_SCSI_SUNESP is not set | 469 | # CONFIG_SCSI_SUNESP is not set |
471 | # CONFIG_SCSI_SRP is not set | 470 | # CONFIG_SCSI_SRP is not set |
472 | # CONFIG_ATA is not set | 471 | # CONFIG_ATA is not set |
473 | |||
474 | # | ||
475 | # Multi-device support (RAID and LVM) | ||
476 | # | ||
477 | CONFIG_MD=y | 472 | CONFIG_MD=y |
478 | CONFIG_BLK_DEV_MD=m | 473 | CONFIG_BLK_DEV_MD=m |
479 | CONFIG_MD_LINEAR=m | 474 | CONFIG_MD_LINEAR=m |
@@ -610,10 +605,6 @@ CONFIG_SLHC=m | |||
610 | # CONFIG_NETCONSOLE is not set | 605 | # CONFIG_NETCONSOLE is not set |
611 | # CONFIG_NETPOLL is not set | 606 | # CONFIG_NETPOLL is not set |
612 | # CONFIG_NET_POLL_CONTROLLER is not set | 607 | # CONFIG_NET_POLL_CONTROLLER is not set |
613 | |||
614 | # | ||
615 | # ISDN subsystem | ||
616 | # | ||
617 | # CONFIG_ISDN is not set | 608 | # CONFIG_ISDN is not set |
618 | # CONFIG_PHONE is not set | 609 | # CONFIG_PHONE is not set |
619 | 610 | ||
@@ -782,6 +773,7 @@ CONFIG_I2C_ALGOBIT=y | |||
782 | CONFIG_HWMON=y | 773 | CONFIG_HWMON=y |
783 | # CONFIG_HWMON_VID is not set | 774 | # CONFIG_HWMON_VID is not set |
784 | # CONFIG_SENSORS_ABITUGURU is not set | 775 | # CONFIG_SENSORS_ABITUGURU is not set |
776 | # CONFIG_SENSORS_ABITUGURU3 is not set | ||
785 | # CONFIG_SENSORS_AD7418 is not set | 777 | # CONFIG_SENSORS_AD7418 is not set |
786 | # CONFIG_SENSORS_ADM1021 is not set | 778 | # CONFIG_SENSORS_ADM1021 is not set |
787 | # CONFIG_SENSORS_ADM1025 is not set | 779 | # CONFIG_SENSORS_ADM1025 is not set |
@@ -808,11 +800,13 @@ CONFIG_HWMON=y | |||
808 | # CONFIG_SENSORS_LM87 is not set | 800 | # CONFIG_SENSORS_LM87 is not set |
809 | # CONFIG_SENSORS_LM90 is not set | 801 | # CONFIG_SENSORS_LM90 is not set |
810 | # CONFIG_SENSORS_LM92 is not set | 802 | # CONFIG_SENSORS_LM92 is not set |
803 | # CONFIG_SENSORS_LM93 is not set | ||
811 | # CONFIG_SENSORS_MAX1619 is not set | 804 | # CONFIG_SENSORS_MAX1619 is not set |
812 | # CONFIG_SENSORS_MAX6650 is not set | 805 | # CONFIG_SENSORS_MAX6650 is not set |
813 | # CONFIG_SENSORS_PC87360 is not set | 806 | # CONFIG_SENSORS_PC87360 is not set |
814 | # CONFIG_SENSORS_PC87427 is not set | 807 | # CONFIG_SENSORS_PC87427 is not set |
815 | # CONFIG_SENSORS_SIS5595 is not set | 808 | # CONFIG_SENSORS_SIS5595 is not set |
809 | # CONFIG_SENSORS_DME1737 is not set | ||
816 | # CONFIG_SENSORS_SMSC47M1 is not set | 810 | # CONFIG_SENSORS_SMSC47M1 is not set |
817 | # CONFIG_SENSORS_SMSC47M192 is not set | 811 | # CONFIG_SENSORS_SMSC47M192 is not set |
818 | # CONFIG_SENSORS_SMSC47B397 is not set | 812 | # CONFIG_SENSORS_SMSC47B397 is not set |
@@ -906,6 +900,7 @@ CONFIG_FB_RADEON_I2C=y | |||
906 | # CONFIG_PROM_CONSOLE is not set | 900 | # CONFIG_PROM_CONSOLE is not set |
907 | CONFIG_DUMMY_CONSOLE=y | 901 | CONFIG_DUMMY_CONSOLE=y |
908 | CONFIG_FRAMEBUFFER_CONSOLE=y | 902 | CONFIG_FRAMEBUFFER_CONSOLE=y |
903 | CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y | ||
909 | # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set | 904 | # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set |
910 | CONFIG_FONTS=y | 905 | CONFIG_FONTS=y |
911 | # CONFIG_FONT_8x8 is not set | 906 | # CONFIG_FONT_8x8 is not set |
@@ -1196,6 +1191,11 @@ CONFIG_USB_STORAGE=m | |||
1196 | # | 1191 | # |
1197 | 1192 | ||
1198 | # | 1193 | # |
1194 | # Userspace I/O | ||
1195 | # | ||
1196 | # CONFIG_UIO is not set | ||
1197 | |||
1198 | # | ||
1199 | # Misc Linux/SPARC drivers | 1199 | # Misc Linux/SPARC drivers |
1200 | # | 1200 | # |
1201 | CONFIG_SUN_OPENPROMIO=m | 1201 | CONFIG_SUN_OPENPROMIO=m |
@@ -1385,6 +1385,7 @@ CONFIG_SCHEDSTATS=y | |||
1385 | # CONFIG_DEBUG_MUTEXES is not set | 1385 | # CONFIG_DEBUG_MUTEXES is not set |
1386 | # CONFIG_DEBUG_LOCK_ALLOC is not set | 1386 | # CONFIG_DEBUG_LOCK_ALLOC is not set |
1387 | # CONFIG_PROVE_LOCKING is not set | 1387 | # CONFIG_PROVE_LOCKING is not set |
1388 | # CONFIG_LOCK_STAT is not set | ||
1388 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | 1389 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set |
1389 | # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set | 1390 | # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set |
1390 | # CONFIG_DEBUG_KOBJECT is not set | 1391 | # CONFIG_DEBUG_KOBJECT is not set |
@@ -1461,6 +1462,7 @@ CONFIG_CRC_CCITT=m | |||
1461 | CONFIG_CRC16=m | 1462 | CONFIG_CRC16=m |
1462 | # CONFIG_CRC_ITU_T is not set | 1463 | # CONFIG_CRC_ITU_T is not set |
1463 | CONFIG_CRC32=y | 1464 | CONFIG_CRC32=y |
1465 | # CONFIG_CRC7 is not set | ||
1464 | CONFIG_LIBCRC32C=m | 1466 | CONFIG_LIBCRC32C=m |
1465 | CONFIG_ZLIB_INFLATE=y | 1467 | CONFIG_ZLIB_INFLATE=y |
1466 | CONFIG_ZLIB_DEFLATE=y | 1468 | CONFIG_ZLIB_DEFLATE=y |
diff --git a/arch/sparc64/kernel/ds.c b/arch/sparc64/kernel/ds.c index fa1f04d756a2..1a2062ecb0bc 100644 --- a/arch/sparc64/kernel/ds.c +++ b/arch/sparc64/kernel/ds.c | |||
@@ -13,11 +13,11 @@ | |||
13 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
14 | #include <linux/mutex.h> | 14 | #include <linux/mutex.h> |
15 | #include <linux/kthread.h> | 15 | #include <linux/kthread.h> |
16 | #include <linux/reboot.h> | ||
16 | #include <linux/cpu.h> | 17 | #include <linux/cpu.h> |
17 | 18 | ||
18 | #include <asm/ldc.h> | 19 | #include <asm/ldc.h> |
19 | #include <asm/vio.h> | 20 | #include <asm/vio.h> |
20 | #include <asm/power.h> | ||
21 | #include <asm/mdesc.h> | 21 | #include <asm/mdesc.h> |
22 | #include <asm/head.h> | 22 | #include <asm/head.h> |
23 | #include <asm/irq.h> | 23 | #include <asm/irq.h> |
@@ -328,7 +328,7 @@ static void domain_shutdown_data(struct ldc_channel *lp, | |||
328 | 328 | ||
329 | ds_send(lp, &pkt, sizeof(pkt)); | 329 | ds_send(lp, &pkt, sizeof(pkt)); |
330 | 330 | ||
331 | wake_up_powerd(); | 331 | orderly_poweroff(true); |
332 | } | 332 | } |
333 | 333 | ||
334 | struct ds_panic_req { | 334 | struct ds_panic_req { |
@@ -1133,8 +1133,6 @@ static int __devinit ds_probe(struct vio_dev *vdev, | |||
1133 | 1133 | ||
1134 | ds_info = dp; | 1134 | ds_info = dp; |
1135 | 1135 | ||
1136 | start_powerd(); | ||
1137 | |||
1138 | return err; | 1136 | return err; |
1139 | 1137 | ||
1140 | out_free_ldc: | 1138 | out_free_ldc: |
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S index 77259526cb15..35feacb6b8ec 100644 --- a/arch/sparc64/kernel/head.S +++ b/arch/sparc64/kernel/head.S | |||
@@ -458,7 +458,6 @@ tlb_fixup_done: | |||
458 | or %g6, %lo(init_thread_union), %g6 | 458 | or %g6, %lo(init_thread_union), %g6 |
459 | ldx [%g6 + TI_TASK], %g4 | 459 | ldx [%g6 + TI_TASK], %g4 |
460 | mov %sp, %l6 | 460 | mov %sp, %l6 |
461 | mov %o4, %l7 | ||
462 | 461 | ||
463 | wr %g0, ASI_P, %asi | 462 | wr %g0, ASI_P, %asi |
464 | mov 1, %g1 | 463 | mov 1, %g1 |
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index 8cb3358674f5..c72795666a62 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c | |||
@@ -701,10 +701,10 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) | |||
701 | { | 701 | { |
702 | unsigned long sysino, hv_err; | 702 | unsigned long sysino, hv_err; |
703 | 703 | ||
704 | BUG_ON(devhandle & ~IMAP_IGN); | 704 | BUG_ON(devhandle & devino); |
705 | BUG_ON(devino & ~IMAP_INO); | ||
706 | 705 | ||
707 | sysino = devhandle | devino; | 706 | sysino = devhandle | devino; |
707 | BUG_ON(sysino & ~(IMAP_IGN | IMAP_INO)); | ||
708 | 708 | ||
709 | hv_err = sun4v_vintr_set_cookie(devhandle, devino, sysino); | 709 | hv_err = sun4v_vintr_set_cookie(devhandle, devino, sysino); |
710 | if (hv_err) { | 710 | if (hv_err) { |
diff --git a/arch/sparc64/kernel/mdesc.c b/arch/sparc64/kernel/mdesc.c index 302ba5e5a0bb..13a79fe5115b 100644 --- a/arch/sparc64/kernel/mdesc.c +++ b/arch/sparc64/kernel/mdesc.c | |||
@@ -231,6 +231,25 @@ void mdesc_register_notifier(struct mdesc_notifier_client *client) | |||
231 | mutex_unlock(&mdesc_mutex); | 231 | mutex_unlock(&mdesc_mutex); |
232 | } | 232 | } |
233 | 233 | ||
234 | static const u64 *parent_cfg_handle(struct mdesc_handle *hp, u64 node) | ||
235 | { | ||
236 | const u64 *id; | ||
237 | u64 a; | ||
238 | |||
239 | id = NULL; | ||
240 | mdesc_for_each_arc(a, hp, node, MDESC_ARC_TYPE_BACK) { | ||
241 | u64 target; | ||
242 | |||
243 | target = mdesc_arc_target(hp, a); | ||
244 | id = mdesc_get_property(hp, target, | ||
245 | "cfg-handle", NULL); | ||
246 | if (id) | ||
247 | break; | ||
248 | } | ||
249 | |||
250 | return id; | ||
251 | } | ||
252 | |||
234 | /* Run 'func' on nodes which are in A but not in B. */ | 253 | /* Run 'func' on nodes which are in A but not in B. */ |
235 | static void invoke_on_missing(const char *name, | 254 | static void invoke_on_missing(const char *name, |
236 | struct mdesc_handle *a, | 255 | struct mdesc_handle *a, |
@@ -240,13 +259,42 @@ static void invoke_on_missing(const char *name, | |||
240 | u64 node; | 259 | u64 node; |
241 | 260 | ||
242 | mdesc_for_each_node_by_name(a, node, name) { | 261 | mdesc_for_each_node_by_name(a, node, name) { |
243 | const u64 *id = mdesc_get_property(a, node, "id", NULL); | 262 | int found = 0, is_vdc_port = 0; |
244 | int found = 0; | 263 | const char *name_prop; |
264 | const u64 *id; | ||
245 | u64 fnode; | 265 | u64 fnode; |
246 | 266 | ||
267 | name_prop = mdesc_get_property(a, node, "name", NULL); | ||
268 | if (name_prop && !strcmp(name_prop, "vdc-port")) { | ||
269 | is_vdc_port = 1; | ||
270 | id = parent_cfg_handle(a, node); | ||
271 | } else | ||
272 | id = mdesc_get_property(a, node, "id", NULL); | ||
273 | |||
274 | if (!id) { | ||
275 | printk(KERN_ERR "MD: Cannot find ID for %s node.\n", | ||
276 | (name_prop ? name_prop : name)); | ||
277 | continue; | ||
278 | } | ||
279 | |||
247 | mdesc_for_each_node_by_name(b, fnode, name) { | 280 | mdesc_for_each_node_by_name(b, fnode, name) { |
248 | const u64 *fid = mdesc_get_property(b, fnode, | 281 | const u64 *fid; |
249 | "id", NULL); | 282 | |
283 | if (is_vdc_port) { | ||
284 | name_prop = mdesc_get_property(b, fnode, | ||
285 | "name", NULL); | ||
286 | if (!name_prop || | ||
287 | strcmp(name_prop, "vdc-port")) | ||
288 | continue; | ||
289 | fid = parent_cfg_handle(b, fnode); | ||
290 | if (!fid) { | ||
291 | printk(KERN_ERR "MD: Cannot find ID " | ||
292 | "for vdc-port node.\n"); | ||
293 | continue; | ||
294 | } | ||
295 | } else | ||
296 | fid = mdesc_get_property(b, fnode, | ||
297 | "id", NULL); | ||
250 | 298 | ||
251 | if (*id == *fid) { | 299 | if (*id == *fid) { |
252 | found = 1; | 300 | found = 1; |
diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c index fdc0d0b5a910..b00feb01c16f 100644 --- a/arch/sparc64/kernel/power.c +++ b/arch/sparc64/kernel/power.c | |||
@@ -12,13 +12,13 @@ | |||
12 | #include <linux/interrupt.h> | 12 | #include <linux/interrupt.h> |
13 | #include <linux/pm.h> | 13 | #include <linux/pm.h> |
14 | #include <linux/syscalls.h> | 14 | #include <linux/syscalls.h> |
15 | #include <linux/reboot.h> | ||
15 | 16 | ||
16 | #include <asm/system.h> | 17 | #include <asm/system.h> |
17 | #include <asm/auxio.h> | 18 | #include <asm/auxio.h> |
18 | #include <asm/prom.h> | 19 | #include <asm/prom.h> |
19 | #include <asm/of_device.h> | 20 | #include <asm/of_device.h> |
20 | #include <asm/io.h> | 21 | #include <asm/io.h> |
21 | #include <asm/power.h> | ||
22 | #include <asm/sstate.h> | 22 | #include <asm/sstate.h> |
23 | 23 | ||
24 | #include <linux/unistd.h> | 24 | #include <linux/unistd.h> |
@@ -31,20 +31,9 @@ int scons_pwroff = 1; | |||
31 | 31 | ||
32 | static void __iomem *power_reg; | 32 | static void __iomem *power_reg; |
33 | 33 | ||
34 | static DECLARE_WAIT_QUEUE_HEAD(powerd_wait); | ||
35 | static int button_pressed; | ||
36 | |||
37 | void wake_up_powerd(void) | ||
38 | { | ||
39 | if (button_pressed == 0) { | ||
40 | button_pressed = 1; | ||
41 | wake_up(&powerd_wait); | ||
42 | } | ||
43 | } | ||
44 | |||
45 | static irqreturn_t power_handler(int irq, void *dev_id) | 34 | static irqreturn_t power_handler(int irq, void *dev_id) |
46 | { | 35 | { |
47 | wake_up_powerd(); | 36 | orderly_poweroff(true); |
48 | 37 | ||
49 | /* FIXME: Check registers for status... */ | 38 | /* FIXME: Check registers for status... */ |
50 | return IRQ_HANDLED; | 39 | return IRQ_HANDLED; |
@@ -77,48 +66,6 @@ void machine_power_off(void) | |||
77 | void (*pm_power_off)(void) = machine_power_off; | 66 | void (*pm_power_off)(void) = machine_power_off; |
78 | EXPORT_SYMBOL(pm_power_off); | 67 | EXPORT_SYMBOL(pm_power_off); |
79 | 68 | ||
80 | static int powerd(void *__unused) | ||
81 | { | ||
82 | static char *envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL }; | ||
83 | char *argv[] = { "/sbin/shutdown", "-h", "now", NULL }; | ||
84 | DECLARE_WAITQUEUE(wait, current); | ||
85 | |||
86 | daemonize("powerd"); | ||
87 | |||
88 | add_wait_queue(&powerd_wait, &wait); | ||
89 | |||
90 | for (;;) { | ||
91 | set_task_state(current, TASK_INTERRUPTIBLE); | ||
92 | if (button_pressed) | ||
93 | break; | ||
94 | flush_signals(current); | ||
95 | schedule(); | ||
96 | } | ||
97 | __set_current_state(TASK_RUNNING); | ||
98 | remove_wait_queue(&powerd_wait, &wait); | ||
99 | |||
100 | /* Ok, down we go... */ | ||
101 | button_pressed = 0; | ||
102 | if (kernel_execve("/sbin/shutdown", argv, envp) < 0) { | ||
103 | printk(KERN_ERR "powerd: shutdown execution failed\n"); | ||
104 | machine_power_off(); | ||
105 | } | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | int start_powerd(void) | ||
110 | { | ||
111 | int err; | ||
112 | |||
113 | err = kernel_thread(powerd, NULL, CLONE_FS); | ||
114 | if (err < 0) | ||
115 | printk(KERN_ERR "power: Failed to start power daemon.\n"); | ||
116 | else | ||
117 | printk(KERN_INFO "power: powerd running.\n"); | ||
118 | |||
119 | return err; | ||
120 | } | ||
121 | |||
122 | static int __init has_button_interrupt(unsigned int irq, struct device_node *dp) | 69 | static int __init has_button_interrupt(unsigned int irq, struct device_node *dp) |
123 | { | 70 | { |
124 | if (irq == 0xffffffff) | 71 | if (irq == 0xffffffff) |
@@ -136,20 +83,15 @@ static int __devinit power_probe(struct of_device *op, const struct of_device_id | |||
136 | 83 | ||
137 | power_reg = of_ioremap(res, 0, 0x4, "power"); | 84 | power_reg = of_ioremap(res, 0, 0x4, "power"); |
138 | 85 | ||
139 | printk("%s: Control reg at %lx ... ", | 86 | printk(KERN_INFO "%s: Control reg at %lx\n", |
140 | op->node->name, res->start); | 87 | op->node->name, res->start); |
141 | 88 | ||
142 | poweroff_method = machine_halt; /* able to use the standard halt */ | 89 | poweroff_method = machine_halt; /* able to use the standard halt */ |
143 | 90 | ||
144 | if (has_button_interrupt(irq, op->node)) { | 91 | if (has_button_interrupt(irq, op->node)) { |
145 | if (start_powerd() < 0) | ||
146 | return 0; | ||
147 | |||
148 | if (request_irq(irq, | 92 | if (request_irq(irq, |
149 | power_handler, 0, "power", NULL) < 0) | 93 | power_handler, 0, "power", NULL) < 0) |
150 | printk(KERN_ERR "power: Cannot setup IRQ handler.\n"); | 94 | printk(KERN_ERR "power: Cannot setup IRQ handler.\n"); |
151 | } else { | ||
152 | printk(KERN_INFO "power: Not using powerd.\n"); | ||
153 | } | 95 | } |
154 | 96 | ||
155 | return 0; | 97 | return 0; |
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c index abd83129b2e7..e8dce90d05d4 100644 --- a/arch/sparc64/kernel/sys_sparc32.c +++ b/arch/sparc64/kernel/sys_sparc32.c | |||
@@ -1,8 +1,7 @@ | |||
1 | /* $Id: sys_sparc32.c,v 1.184 2002/02/09 19:49:31 davem Exp $ | 1 | /* sys_sparc32.c: Conversion between 32bit and 64bit native syscalls. |
2 | * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls. | ||
3 | * | 2 | * |
4 | * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) | 3 | * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) |
5 | * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) | 4 | * Copyright (C) 1997, 2007 David S. Miller (davem@davemloft.net) |
6 | * | 5 | * |
7 | * These routines maintain argument size conversion between 32bit and 64bit | 6 | * These routines maintain argument size conversion between 32bit and 64bit |
8 | * environment. | 7 | * environment. |
@@ -1028,3 +1027,10 @@ long compat_sync_file_range(int fd, unsigned long off_high, unsigned long off_lo | |||
1028 | (nb_high << 32) | nb_low, | 1027 | (nb_high << 32) | nb_low, |
1029 | flags); | 1028 | flags); |
1030 | } | 1029 | } |
1030 | |||
1031 | asmlinkage long compat_sys_fallocate(int fd, int mode, u32 offhi, u32 offlo, | ||
1032 | u32 lenhi, u32 lenlo) | ||
1033 | { | ||
1034 | return sys_fallocate(fd, mode, ((loff_t)offhi << 32) | offlo, | ||
1035 | ((loff_t)lenhi << 32) | lenlo); | ||
1036 | } | ||
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index 8765e32155a0..06d10907d8ce 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S | |||
@@ -1,8 +1,7 @@ | |||
1 | /* $Id: systbls.S,v 1.81 2002/02/08 03:57:14 davem Exp $ | 1 | /* systbls.S: System call entry point tables for OS compatibility. |
2 | * systbls.S: System call entry point tables for OS compatibility. | ||
3 | * The native Linux system call table lives here also. | 2 | * The native Linux system call table lives here also. |
4 | * | 3 | * |
5 | * Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu) | 4 | * Copyright (C) 1995, 1996, 2007 David S. Miller (davem@davemloft.net) |
6 | * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) | 5 | * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) |
7 | * | 6 | * |
8 | * Based upon preliminary work which is: | 7 | * Based upon preliminary work which is: |
@@ -81,7 +80,7 @@ sys_call_table32: | |||
81 | .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare | 80 | .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare |
82 | /*300*/ .word compat_sys_set_robust_list, compat_sys_get_robust_list, compat_sys_migrate_pages, compat_sys_mbind, compat_sys_get_mempolicy | 81 | /*300*/ .word compat_sys_set_robust_list, compat_sys_get_robust_list, compat_sys_migrate_pages, compat_sys_mbind, compat_sys_get_mempolicy |
83 | .word compat_sys_set_mempolicy, compat_sys_kexec_load, compat_sys_move_pages, sys_getcpu, compat_sys_epoll_pwait | 82 | .word compat_sys_set_mempolicy, compat_sys_kexec_load, compat_sys_move_pages, sys_getcpu, compat_sys_epoll_pwait |
84 | /*310*/ .word compat_sys_utimensat, compat_sys_signalfd, compat_sys_timerfd, sys_eventfd | 83 | /*310*/ .word compat_sys_utimensat, compat_sys_signalfd, compat_sys_timerfd, sys_eventfd, compat_sys_fallocate |
85 | 84 | ||
86 | #endif /* CONFIG_COMPAT */ | 85 | #endif /* CONFIG_COMPAT */ |
87 | 86 | ||
@@ -153,7 +152,7 @@ sys_call_table: | |||
153 | .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare | 152 | .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare |
154 | /*300*/ .word sys_set_robust_list, sys_get_robust_list, sys_migrate_pages, sys_mbind, sys_get_mempolicy | 153 | /*300*/ .word sys_set_robust_list, sys_get_robust_list, sys_migrate_pages, sys_mbind, sys_get_mempolicy |
155 | .word sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait | 154 | .word sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait |
156 | /*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd, sys_eventfd | 155 | /*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd, sys_eventfd, sys_fallocate |
157 | 156 | ||
158 | #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ | 157 | #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ |
159 | defined(CONFIG_SOLARIS_EMUL_MODULE) | 158 | defined(CONFIG_SOLARIS_EMUL_MODULE) |
@@ -272,6 +271,6 @@ sunos_sys_table: | |||
272 | .word sunos_nosys, sunos_nosys, sunos_nosys | 271 | .word sunos_nosys, sunos_nosys, sunos_nosys |
273 | .word sunos_nosys | 272 | .word sunos_nosys |
274 | /*310*/ .word sunos_nosys, sunos_nosys, sunos_nosys | 273 | /*310*/ .word sunos_nosys, sunos_nosys, sunos_nosys |
275 | .word sunos_nosys | 274 | .word sunos_nosys, sunos_nosys |
276 | 275 | ||
277 | #endif | 276 | #endif |
diff --git a/arch/sparc64/kernel/vio.c b/arch/sparc64/kernel/vio.c index 8d3cc4fdb557..491223a6628f 100644 --- a/arch/sparc64/kernel/vio.c +++ b/arch/sparc64/kernel/vio.c | |||
@@ -103,9 +103,9 @@ static ssize_t devspec_show(struct device *dev, | |||
103 | struct vio_dev *vdev = to_vio_dev(dev); | 103 | struct vio_dev *vdev = to_vio_dev(dev); |
104 | const char *str = "none"; | 104 | const char *str = "none"; |
105 | 105 | ||
106 | if (!strcmp(vdev->type, "network")) | 106 | if (!strcmp(vdev->type, "vnet-port")) |
107 | str = "vnet"; | 107 | str = "vnet"; |
108 | else if (!strcmp(vdev->type, "block")) | 108 | else if (!strcmp(vdev->type, "vdc-port")) |
109 | str = "vdisk"; | 109 | str = "vdisk"; |
110 | 110 | ||
111 | return sprintf(buf, "%s\n", str); | 111 | return sprintf(buf, "%s\n", str); |
@@ -221,6 +221,27 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp, | |||
221 | return NULL; | 221 | return NULL; |
222 | } | 222 | } |
223 | 223 | ||
224 | if (!strcmp(type, "vdc-port")) { | ||
225 | u64 a; | ||
226 | |||
227 | id = NULL; | ||
228 | mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_BACK) { | ||
229 | u64 target; | ||
230 | |||
231 | target = mdesc_arc_target(hp, a); | ||
232 | id = mdesc_get_property(hp, target, | ||
233 | "cfg-handle", NULL); | ||
234 | if (id) | ||
235 | break; | ||
236 | } | ||
237 | if (!id) { | ||
238 | printk(KERN_ERR "VIO: vdc-port lacks parent " | ||
239 | "cfg-handle.\n"); | ||
240 | return NULL; | ||
241 | } | ||
242 | } else | ||
243 | id = mdesc_get_property(hp, mp, "id", NULL); | ||
244 | |||
224 | bus_id_name = type; | 245 | bus_id_name = type; |
225 | if (!strcmp(type, "domain-services-port")) | 246 | if (!strcmp(type, "domain-services-port")) |
226 | bus_id_name = "ds"; | 247 | bus_id_name = "ds"; |
@@ -260,13 +281,15 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp, | |||
260 | 281 | ||
261 | vio_fill_channel_info(hp, mp, vdev); | 282 | vio_fill_channel_info(hp, mp, vdev); |
262 | 283 | ||
263 | id = mdesc_get_property(hp, mp, "id", NULL); | 284 | if (!id) { |
264 | if (!id) | ||
265 | snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s", | 285 | snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s", |
266 | bus_id_name); | 286 | bus_id_name); |
267 | else | 287 | vdev->dev_no = ~(u64)0; |
288 | } else { | ||
268 | snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s-%lu", | 289 | snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s-%lu", |
269 | bus_id_name, *id); | 290 | bus_id_name, *id); |
291 | vdev->dev_no = *id; | ||
292 | } | ||
270 | 293 | ||
271 | vdev->dev.parent = parent; | 294 | vdev->dev.parent = parent; |
272 | vdev->dev.bus = &vio_bus_type; | 295 | vdev->dev.bus = &vio_bus_type; |
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 9755a3cfad26..d148ccbc36d1 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
@@ -92,7 +92,11 @@ struct cfq_data { | |||
92 | struct cfq_queue *active_queue; | 92 | struct cfq_queue *active_queue; |
93 | struct cfq_io_context *active_cic; | 93 | struct cfq_io_context *active_cic; |
94 | 94 | ||
95 | struct cfq_queue *async_cfqq[IOPRIO_BE_NR]; | 95 | /* |
96 | * async queue for each priority case | ||
97 | */ | ||
98 | struct cfq_queue *async_cfqq[2][IOPRIO_BE_NR]; | ||
99 | struct cfq_queue *async_idle_cfqq; | ||
96 | 100 | ||
97 | struct timer_list idle_class_timer; | 101 | struct timer_list idle_class_timer; |
98 | 102 | ||
@@ -111,9 +115,6 @@ struct cfq_data { | |||
111 | unsigned int cfq_slice_idle; | 115 | unsigned int cfq_slice_idle; |
112 | 116 | ||
113 | struct list_head cic_list; | 117 | struct list_head cic_list; |
114 | |||
115 | sector_t new_seek_mean; | ||
116 | u64 new_seek_total; | ||
117 | }; | 118 | }; |
118 | 119 | ||
119 | /* | 120 | /* |
@@ -153,8 +154,6 @@ struct cfq_queue { | |||
153 | 154 | ||
154 | /* various state flags, see below */ | 155 | /* various state flags, see below */ |
155 | unsigned int flags; | 156 | unsigned int flags; |
156 | |||
157 | sector_t last_request_pos; | ||
158 | }; | 157 | }; |
159 | 158 | ||
160 | enum cfqq_state_flags { | 159 | enum cfqq_state_flags { |
@@ -1414,24 +1413,44 @@ out: | |||
1414 | return cfqq; | 1413 | return cfqq; |
1415 | } | 1414 | } |
1416 | 1415 | ||
1416 | static struct cfq_queue ** | ||
1417 | cfq_async_queue_prio(struct cfq_data *cfqd, int ioprio_class, int ioprio) | ||
1418 | { | ||
1419 | switch(ioprio_class) { | ||
1420 | case IOPRIO_CLASS_RT: | ||
1421 | return &cfqd->async_cfqq[0][ioprio]; | ||
1422 | case IOPRIO_CLASS_BE: | ||
1423 | return &cfqd->async_cfqq[1][ioprio]; | ||
1424 | case IOPRIO_CLASS_IDLE: | ||
1425 | return &cfqd->async_idle_cfqq; | ||
1426 | default: | ||
1427 | BUG(); | ||
1428 | } | ||
1429 | } | ||
1430 | |||
1417 | static struct cfq_queue * | 1431 | static struct cfq_queue * |
1418 | cfq_get_queue(struct cfq_data *cfqd, int is_sync, struct task_struct *tsk, | 1432 | cfq_get_queue(struct cfq_data *cfqd, int is_sync, struct task_struct *tsk, |
1419 | gfp_t gfp_mask) | 1433 | gfp_t gfp_mask) |
1420 | { | 1434 | { |
1421 | const int ioprio = task_ioprio(tsk); | 1435 | const int ioprio = task_ioprio(tsk); |
1436 | const int ioprio_class = task_ioprio_class(tsk); | ||
1437 | struct cfq_queue **async_cfqq = NULL; | ||
1422 | struct cfq_queue *cfqq = NULL; | 1438 | struct cfq_queue *cfqq = NULL; |
1423 | 1439 | ||
1424 | if (!is_sync) | 1440 | if (!is_sync) { |
1425 | cfqq = cfqd->async_cfqq[ioprio]; | 1441 | async_cfqq = cfq_async_queue_prio(cfqd, ioprio_class, ioprio); |
1442 | cfqq = *async_cfqq; | ||
1443 | } | ||
1444 | |||
1426 | if (!cfqq) | 1445 | if (!cfqq) |
1427 | cfqq = cfq_find_alloc_queue(cfqd, is_sync, tsk, gfp_mask); | 1446 | cfqq = cfq_find_alloc_queue(cfqd, is_sync, tsk, gfp_mask); |
1428 | 1447 | ||
1429 | /* | 1448 | /* |
1430 | * pin the queue now that it's allocated, scheduler exit will prune it | 1449 | * pin the queue now that it's allocated, scheduler exit will prune it |
1431 | */ | 1450 | */ |
1432 | if (!is_sync && !cfqd->async_cfqq[ioprio]) { | 1451 | if (!is_sync && !(*async_cfqq)) { |
1433 | atomic_inc(&cfqq->ref); | 1452 | atomic_inc(&cfqq->ref); |
1434 | cfqd->async_cfqq[ioprio] = cfqq; | 1453 | *async_cfqq = cfqq; |
1435 | } | 1454 | } |
1436 | 1455 | ||
1437 | atomic_inc(&cfqq->ref); | 1456 | atomic_inc(&cfqq->ref); |
@@ -1597,11 +1616,6 @@ cfq_update_io_seektime(struct cfq_data *cfqd, struct cfq_io_context *cic, | |||
1597 | else | 1616 | else |
1598 | sdist = cic->last_request_pos - rq->sector; | 1617 | sdist = cic->last_request_pos - rq->sector; |
1599 | 1618 | ||
1600 | if (!cic->seek_samples) { | ||
1601 | cfqd->new_seek_total = (7*cic->seek_total + (u64)256*sdist) / 8; | ||
1602 | cfqd->new_seek_mean = cfqd->new_seek_total / 256; | ||
1603 | } | ||
1604 | |||
1605 | /* | 1619 | /* |
1606 | * Don't allow the seek distance to get too large from the | 1620 | * Don't allow the seek distance to get too large from the |
1607 | * odd fragment, pagein, etc | 1621 | * odd fragment, pagein, etc |
@@ -1737,7 +1751,6 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, | |||
1737 | cfq_update_idle_window(cfqd, cfqq, cic); | 1751 | cfq_update_idle_window(cfqd, cfqq, cic); |
1738 | 1752 | ||
1739 | cic->last_request_pos = rq->sector + rq->nr_sectors; | 1753 | cic->last_request_pos = rq->sector + rq->nr_sectors; |
1740 | cfqq->last_request_pos = cic->last_request_pos; | ||
1741 | 1754 | ||
1742 | if (cfqq == cfqd->active_queue) { | 1755 | if (cfqq == cfqd->active_queue) { |
1743 | /* | 1756 | /* |
@@ -2042,11 +2055,24 @@ static void cfq_shutdown_timer_wq(struct cfq_data *cfqd) | |||
2042 | blk_sync_queue(cfqd->queue); | 2055 | blk_sync_queue(cfqd->queue); |
2043 | } | 2056 | } |
2044 | 2057 | ||
2058 | static void cfq_put_async_queues(struct cfq_data *cfqd) | ||
2059 | { | ||
2060 | int i; | ||
2061 | |||
2062 | for (i = 0; i < IOPRIO_BE_NR; i++) { | ||
2063 | if (cfqd->async_cfqq[0][i]) | ||
2064 | cfq_put_queue(cfqd->async_cfqq[0][i]); | ||
2065 | if (cfqd->async_cfqq[1][i]) | ||
2066 | cfq_put_queue(cfqd->async_cfqq[1][i]); | ||
2067 | if (cfqd->async_idle_cfqq) | ||
2068 | cfq_put_queue(cfqd->async_idle_cfqq); | ||
2069 | } | ||
2070 | } | ||
2071 | |||
2045 | static void cfq_exit_queue(elevator_t *e) | 2072 | static void cfq_exit_queue(elevator_t *e) |
2046 | { | 2073 | { |
2047 | struct cfq_data *cfqd = e->elevator_data; | 2074 | struct cfq_data *cfqd = e->elevator_data; |
2048 | request_queue_t *q = cfqd->queue; | 2075 | request_queue_t *q = cfqd->queue; |
2049 | int i; | ||
2050 | 2076 | ||
2051 | cfq_shutdown_timer_wq(cfqd); | 2077 | cfq_shutdown_timer_wq(cfqd); |
2052 | 2078 | ||
@@ -2063,12 +2089,7 @@ static void cfq_exit_queue(elevator_t *e) | |||
2063 | __cfq_exit_single_io_context(cfqd, cic); | 2089 | __cfq_exit_single_io_context(cfqd, cic); |
2064 | } | 2090 | } |
2065 | 2091 | ||
2066 | /* | 2092 | cfq_put_async_queues(cfqd); |
2067 | * Put the async queues | ||
2068 | */ | ||
2069 | for (i = 0; i < IOPRIO_BE_NR; i++) | ||
2070 | if (cfqd->async_cfqq[i]) | ||
2071 | cfq_put_queue(cfqd->async_cfqq[i]); | ||
2072 | 2093 | ||
2073 | spin_unlock_irq(q->queue_lock); | 2094 | spin_unlock_irq(q->queue_lock); |
2074 | 2095 | ||
diff --git a/crypto/async_tx/async_memcpy.c b/crypto/async_tx/async_memcpy.c index a973f4ef897d..047e533fcc5b 100644 --- a/crypto/async_tx/async_memcpy.c +++ b/crypto/async_tx/async_memcpy.c | |||
@@ -36,7 +36,6 @@ | |||
36 | * @offset: offset in pages to start transaction | 36 | * @offset: offset in pages to start transaction |
37 | * @len: length in bytes | 37 | * @len: length in bytes |
38 | * @flags: ASYNC_TX_ASSUME_COHERENT, ASYNC_TX_ACK, ASYNC_TX_DEP_ACK, | 38 | * @flags: ASYNC_TX_ASSUME_COHERENT, ASYNC_TX_ACK, ASYNC_TX_DEP_ACK, |
39 | * ASYNC_TX_KMAP_SRC, ASYNC_TX_KMAP_DST | ||
40 | * @depend_tx: memcpy depends on the result of this transaction | 39 | * @depend_tx: memcpy depends on the result of this transaction |
41 | * @cb_fn: function to call when the memcpy completes | 40 | * @cb_fn: function to call when the memcpy completes |
42 | * @cb_param: parameter to pass to the callback routine | 41 | * @cb_param: parameter to pass to the callback routine |
@@ -88,23 +87,13 @@ async_memcpy(struct page *dest, struct page *src, unsigned int dest_offset, | |||
88 | __FUNCTION__); | 87 | __FUNCTION__); |
89 | } | 88 | } |
90 | 89 | ||
91 | if (flags & ASYNC_TX_KMAP_DST) | 90 | dest_buf = kmap_atomic(dest, KM_USER0) + dest_offset; |
92 | dest_buf = kmap_atomic(dest, KM_USER0) + dest_offset; | 91 | src_buf = kmap_atomic(src, KM_USER1) + src_offset; |
93 | else | ||
94 | dest_buf = page_address(dest) + dest_offset; | ||
95 | |||
96 | if (flags & ASYNC_TX_KMAP_SRC) | ||
97 | src_buf = kmap_atomic(src, KM_USER0) + src_offset; | ||
98 | else | ||
99 | src_buf = page_address(src) + src_offset; | ||
100 | 92 | ||
101 | memcpy(dest_buf, src_buf, len); | 93 | memcpy(dest_buf, src_buf, len); |
102 | 94 | ||
103 | if (flags & ASYNC_TX_KMAP_DST) | 95 | kunmap_atomic(dest_buf, KM_USER0); |
104 | kunmap_atomic(dest_buf, KM_USER0); | 96 | kunmap_atomic(src_buf, KM_USER1); |
105 | |||
106 | if (flags & ASYNC_TX_KMAP_SRC) | ||
107 | kunmap_atomic(src_buf, KM_USER0); | ||
108 | 97 | ||
109 | async_tx_sync_epilog(flags, depend_tx, cb_fn, cb_param); | 98 | async_tx_sync_epilog(flags, depend_tx, cb_fn, cb_param); |
110 | } | 99 | } |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 11e4eb9f304e..06f212ff2b4f 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -99,6 +99,7 @@ enum { | |||
99 | HOST_CAP_SSC = (1 << 14), /* Slumber capable */ | 99 | HOST_CAP_SSC = (1 << 14), /* Slumber capable */ |
100 | HOST_CAP_CLO = (1 << 24), /* Command List Override support */ | 100 | HOST_CAP_CLO = (1 << 24), /* Command List Override support */ |
101 | HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */ | 101 | HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */ |
102 | HOST_CAP_SNTF = (1 << 29), /* SNotification register */ | ||
102 | HOST_CAP_NCQ = (1 << 30), /* Native Command Queueing */ | 103 | HOST_CAP_NCQ = (1 << 30), /* Native Command Queueing */ |
103 | HOST_CAP_64 = (1 << 31), /* PCI DAC (64-bit DMA) support */ | 104 | HOST_CAP_64 = (1 << 31), /* PCI DAC (64-bit DMA) support */ |
104 | 105 | ||
@@ -113,11 +114,11 @@ enum { | |||
113 | PORT_TFDATA = 0x20, /* taskfile data */ | 114 | PORT_TFDATA = 0x20, /* taskfile data */ |
114 | PORT_SIG = 0x24, /* device TF signature */ | 115 | PORT_SIG = 0x24, /* device TF signature */ |
115 | PORT_CMD_ISSUE = 0x38, /* command issue */ | 116 | PORT_CMD_ISSUE = 0x38, /* command issue */ |
116 | PORT_SCR = 0x28, /* SATA phy register block */ | ||
117 | PORT_SCR_STAT = 0x28, /* SATA phy register: SStatus */ | 117 | PORT_SCR_STAT = 0x28, /* SATA phy register: SStatus */ |
118 | PORT_SCR_CTL = 0x2c, /* SATA phy register: SControl */ | 118 | PORT_SCR_CTL = 0x2c, /* SATA phy register: SControl */ |
119 | PORT_SCR_ERR = 0x30, /* SATA phy register: SError */ | 119 | PORT_SCR_ERR = 0x30, /* SATA phy register: SError */ |
120 | PORT_SCR_ACT = 0x34, /* SATA phy register: SActive */ | 120 | PORT_SCR_ACT = 0x34, /* SATA phy register: SActive */ |
121 | PORT_SCR_NTF = 0x3c, /* SATA phy register: SNotification */ | ||
121 | 122 | ||
122 | /* PORT_IRQ_{STAT,MASK} bits */ | 123 | /* PORT_IRQ_{STAT,MASK} bits */ |
123 | PORT_IRQ_COLD_PRES = (1 << 31), /* cold presence detect */ | 124 | PORT_IRQ_COLD_PRES = (1 << 31), /* cold presence detect */ |
@@ -216,8 +217,8 @@ struct ahci_port_priv { | |||
216 | unsigned int ncq_saw_sdb:1; | 217 | unsigned int ncq_saw_sdb:1; |
217 | }; | 218 | }; |
218 | 219 | ||
219 | static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg); | 220 | static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); |
220 | static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); | 221 | static int ahci_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); |
221 | static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); | 222 | static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); |
222 | static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc); | 223 | static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc); |
223 | static void ahci_irq_clear(struct ata_port *ap); | 224 | static void ahci_irq_clear(struct ata_port *ap); |
@@ -417,7 +418,10 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
417 | 418 | ||
418 | /* ATI */ | 419 | /* ATI */ |
419 | { PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 */ | 420 | { PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 */ |
420 | { PCI_VDEVICE(ATI, 0x4390), board_ahci_sb600 }, /* ATI SB700 */ | 421 | { PCI_VDEVICE(ATI, 0x4390), board_ahci_sb600 }, /* ATI SB700 IDE */ |
422 | { PCI_VDEVICE(ATI, 0x4391), board_ahci_sb600 }, /* ATI SB700 AHCI */ | ||
423 | { PCI_VDEVICE(ATI, 0x4392), board_ahci_sb600 }, /* ATI SB700 nraid5 */ | ||
424 | { PCI_VDEVICE(ATI, 0x4393), board_ahci_sb600 }, /* ATI SB700 raid5 */ | ||
421 | 425 | ||
422 | /* VIA */ | 426 | /* VIA */ |
423 | { PCI_VDEVICE(VIA, 0x3349), board_ahci_vt8251 }, /* VIA VT8251 */ | 427 | { PCI_VDEVICE(VIA, 0x3349), board_ahci_vt8251 }, /* VIA VT8251 */ |
@@ -545,13 +549,19 @@ static void ahci_save_initial_config(struct pci_dev *pdev, | |||
545 | hpriv->saved_cap = cap = readl(mmio + HOST_CAP); | 549 | hpriv->saved_cap = cap = readl(mmio + HOST_CAP); |
546 | hpriv->saved_port_map = port_map = readl(mmio + HOST_PORTS_IMPL); | 550 | hpriv->saved_port_map = port_map = readl(mmio + HOST_PORTS_IMPL); |
547 | 551 | ||
548 | /* some chips lie about 64bit support */ | 552 | /* some chips have errata preventing 64bit use */ |
549 | if ((cap & HOST_CAP_64) && (pi->flags & AHCI_FLAG_32BIT_ONLY)) { | 553 | if ((cap & HOST_CAP_64) && (pi->flags & AHCI_FLAG_32BIT_ONLY)) { |
550 | dev_printk(KERN_INFO, &pdev->dev, | 554 | dev_printk(KERN_INFO, &pdev->dev, |
551 | "controller can't do 64bit DMA, forcing 32bit\n"); | 555 | "controller can't do 64bit DMA, forcing 32bit\n"); |
552 | cap &= ~HOST_CAP_64; | 556 | cap &= ~HOST_CAP_64; |
553 | } | 557 | } |
554 | 558 | ||
559 | if ((cap & HOST_CAP_NCQ) && (pi->flags & AHCI_FLAG_NO_NCQ)) { | ||
560 | dev_printk(KERN_INFO, &pdev->dev, | ||
561 | "controller can't do NCQ, turning off CAP_NCQ\n"); | ||
562 | cap &= ~HOST_CAP_NCQ; | ||
563 | } | ||
564 | |||
555 | /* fixup zero port_map */ | 565 | /* fixup zero port_map */ |
556 | if (!port_map) { | 566 | if (!port_map) { |
557 | port_map = (1 << ahci_nr_ports(cap)) - 1; | 567 | port_map = (1 << ahci_nr_ports(cap)) - 1; |
@@ -625,38 +635,45 @@ static void ahci_restore_initial_config(struct ata_host *host) | |||
625 | (void) readl(mmio + HOST_PORTS_IMPL); /* flush */ | 635 | (void) readl(mmio + HOST_PORTS_IMPL); /* flush */ |
626 | } | 636 | } |
627 | 637 | ||
628 | static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in) | 638 | static unsigned ahci_scr_offset(struct ata_port *ap, unsigned int sc_reg) |
629 | { | 639 | { |
630 | unsigned int sc_reg; | 640 | static const int offset[] = { |
631 | 641 | [SCR_STATUS] = PORT_SCR_STAT, | |
632 | switch (sc_reg_in) { | 642 | [SCR_CONTROL] = PORT_SCR_CTL, |
633 | case SCR_STATUS: sc_reg = 0; break; | 643 | [SCR_ERROR] = PORT_SCR_ERR, |
634 | case SCR_CONTROL: sc_reg = 1; break; | 644 | [SCR_ACTIVE] = PORT_SCR_ACT, |
635 | case SCR_ERROR: sc_reg = 2; break; | 645 | [SCR_NOTIFICATION] = PORT_SCR_NTF, |
636 | case SCR_ACTIVE: sc_reg = 3; break; | 646 | }; |
637 | default: | 647 | struct ahci_host_priv *hpriv = ap->host->private_data; |
638 | return 0xffffffffU; | ||
639 | } | ||
640 | 648 | ||
641 | return readl(ap->ioaddr.scr_addr + (sc_reg * 4)); | 649 | if (sc_reg < ARRAY_SIZE(offset) && |
650 | (sc_reg != SCR_NOTIFICATION || (hpriv->cap & HOST_CAP_SNTF))) | ||
651 | return offset[sc_reg]; | ||
652 | return 0; | ||
642 | } | 653 | } |
643 | 654 | ||
644 | 655 | static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) | |
645 | static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg_in, | ||
646 | u32 val) | ||
647 | { | 656 | { |
648 | unsigned int sc_reg; | 657 | void __iomem *port_mmio = ahci_port_base(ap); |
649 | 658 | int offset = ahci_scr_offset(ap, sc_reg); | |
650 | switch (sc_reg_in) { | 659 | |
651 | case SCR_STATUS: sc_reg = 0; break; | 660 | if (offset) { |
652 | case SCR_CONTROL: sc_reg = 1; break; | 661 | *val = readl(port_mmio + offset); |
653 | case SCR_ERROR: sc_reg = 2; break; | 662 | return 0; |
654 | case SCR_ACTIVE: sc_reg = 3; break; | ||
655 | default: | ||
656 | return; | ||
657 | } | 663 | } |
664 | return -EINVAL; | ||
665 | } | ||
658 | 666 | ||
659 | writel(val, ap->ioaddr.scr_addr + (sc_reg * 4)); | 667 | static int ahci_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) |
668 | { | ||
669 | void __iomem *port_mmio = ahci_port_base(ap); | ||
670 | int offset = ahci_scr_offset(ap, sc_reg); | ||
671 | |||
672 | if (offset) { | ||
673 | writel(val, port_mmio + offset); | ||
674 | return 0; | ||
675 | } | ||
676 | return -EINVAL; | ||
660 | } | 677 | } |
661 | 678 | ||
662 | static void ahci_start_engine(struct ata_port *ap) | 679 | static void ahci_start_engine(struct ata_port *ap) |
@@ -948,37 +965,87 @@ static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, | |||
948 | pp->cmd_slot[tag].tbl_addr_hi = cpu_to_le32((cmd_tbl_dma >> 16) >> 16); | 965 | pp->cmd_slot[tag].tbl_addr_hi = cpu_to_le32((cmd_tbl_dma >> 16) >> 16); |
949 | } | 966 | } |
950 | 967 | ||
951 | static int ahci_clo(struct ata_port *ap) | 968 | static int ahci_kick_engine(struct ata_port *ap, int force_restart) |
952 | { | 969 | { |
953 | void __iomem *port_mmio = ap->ioaddr.cmd_addr; | 970 | void __iomem *port_mmio = ap->ioaddr.cmd_addr; |
954 | struct ahci_host_priv *hpriv = ap->host->private_data; | 971 | struct ahci_host_priv *hpriv = ap->host->private_data; |
955 | u32 tmp; | 972 | u32 tmp; |
973 | int busy, rc; | ||
974 | |||
975 | /* do we need to kick the port? */ | ||
976 | busy = ahci_check_status(ap) & (ATA_BUSY | ATA_DRQ); | ||
977 | if (!busy && !force_restart) | ||
978 | return 0; | ||
979 | |||
980 | /* stop engine */ | ||
981 | rc = ahci_stop_engine(ap); | ||
982 | if (rc) | ||
983 | goto out_restart; | ||
956 | 984 | ||
957 | if (!(hpriv->cap & HOST_CAP_CLO)) | 985 | /* need to do CLO? */ |
958 | return -EOPNOTSUPP; | 986 | if (!busy) { |
987 | rc = 0; | ||
988 | goto out_restart; | ||
989 | } | ||
959 | 990 | ||
991 | if (!(hpriv->cap & HOST_CAP_CLO)) { | ||
992 | rc = -EOPNOTSUPP; | ||
993 | goto out_restart; | ||
994 | } | ||
995 | |||
996 | /* perform CLO */ | ||
960 | tmp = readl(port_mmio + PORT_CMD); | 997 | tmp = readl(port_mmio + PORT_CMD); |
961 | tmp |= PORT_CMD_CLO; | 998 | tmp |= PORT_CMD_CLO; |
962 | writel(tmp, port_mmio + PORT_CMD); | 999 | writel(tmp, port_mmio + PORT_CMD); |
963 | 1000 | ||
1001 | rc = 0; | ||
964 | tmp = ata_wait_register(port_mmio + PORT_CMD, | 1002 | tmp = ata_wait_register(port_mmio + PORT_CMD, |
965 | PORT_CMD_CLO, PORT_CMD_CLO, 1, 500); | 1003 | PORT_CMD_CLO, PORT_CMD_CLO, 1, 500); |
966 | if (tmp & PORT_CMD_CLO) | 1004 | if (tmp & PORT_CMD_CLO) |
967 | return -EIO; | 1005 | rc = -EIO; |
968 | 1006 | ||
969 | return 0; | 1007 | /* restart engine */ |
1008 | out_restart: | ||
1009 | ahci_start_engine(ap); | ||
1010 | return rc; | ||
970 | } | 1011 | } |
971 | 1012 | ||
972 | static int ahci_softreset(struct ata_port *ap, unsigned int *class, | 1013 | static int ahci_exec_polled_cmd(struct ata_port *ap, int pmp, |
973 | unsigned long deadline) | 1014 | struct ata_taskfile *tf, int is_cmd, u16 flags, |
1015 | unsigned long timeout_msec) | ||
974 | { | 1016 | { |
1017 | const u32 cmd_fis_len = 5; /* five dwords */ | ||
975 | struct ahci_port_priv *pp = ap->private_data; | 1018 | struct ahci_port_priv *pp = ap->private_data; |
976 | void __iomem *port_mmio = ahci_port_base(ap); | 1019 | void __iomem *port_mmio = ahci_port_base(ap); |
977 | const u32 cmd_fis_len = 5; /* five dwords */ | 1020 | u8 *fis = pp->cmd_tbl; |
1021 | u32 tmp; | ||
1022 | |||
1023 | /* prep the command */ | ||
1024 | ata_tf_to_fis(tf, pmp, is_cmd, fis); | ||
1025 | ahci_fill_cmd_slot(pp, 0, cmd_fis_len | flags | (pmp << 12)); | ||
1026 | |||
1027 | /* issue & wait */ | ||
1028 | writel(1, port_mmio + PORT_CMD_ISSUE); | ||
1029 | |||
1030 | if (timeout_msec) { | ||
1031 | tmp = ata_wait_register(port_mmio + PORT_CMD_ISSUE, 0x1, 0x1, | ||
1032 | 1, timeout_msec); | ||
1033 | if (tmp & 0x1) { | ||
1034 | ahci_kick_engine(ap, 1); | ||
1035 | return -EBUSY; | ||
1036 | } | ||
1037 | } else | ||
1038 | readl(port_mmio + PORT_CMD_ISSUE); /* flush */ | ||
1039 | |||
1040 | return 0; | ||
1041 | } | ||
1042 | |||
1043 | static int ahci_do_softreset(struct ata_port *ap, unsigned int *class, | ||
1044 | int pmp, unsigned long deadline) | ||
1045 | { | ||
978 | const char *reason = NULL; | 1046 | const char *reason = NULL; |
1047 | unsigned long now, msecs; | ||
979 | struct ata_taskfile tf; | 1048 | struct ata_taskfile tf; |
980 | u32 tmp; | ||
981 | u8 *fis; | ||
982 | int rc; | 1049 | int rc; |
983 | 1050 | ||
984 | DPRINTK("ENTER\n"); | 1051 | DPRINTK("ENTER\n"); |
@@ -990,43 +1057,22 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class, | |||
990 | } | 1057 | } |
991 | 1058 | ||
992 | /* prepare for SRST (AHCI-1.1 10.4.1) */ | 1059 | /* prepare for SRST (AHCI-1.1 10.4.1) */ |
993 | rc = ahci_stop_engine(ap); | 1060 | rc = ahci_kick_engine(ap, 1); |
994 | if (rc) { | 1061 | if (rc) |
995 | reason = "failed to stop engine"; | 1062 | ata_port_printk(ap, KERN_WARNING, |
996 | goto fail_restart; | 1063 | "failed to reset engine (errno=%d)", rc); |
997 | } | ||
998 | |||
999 | /* check BUSY/DRQ, perform Command List Override if necessary */ | ||
1000 | if (ahci_check_status(ap) & (ATA_BUSY | ATA_DRQ)) { | ||
1001 | rc = ahci_clo(ap); | ||
1002 | |||
1003 | if (rc == -EOPNOTSUPP) { | ||
1004 | reason = "port busy but CLO unavailable"; | ||
1005 | goto fail_restart; | ||
1006 | } else if (rc) { | ||
1007 | reason = "port busy but CLO failed"; | ||
1008 | goto fail_restart; | ||
1009 | } | ||
1010 | } | ||
1011 | |||
1012 | /* restart engine */ | ||
1013 | ahci_start_engine(ap); | ||
1014 | 1064 | ||
1015 | ata_tf_init(ap->device, &tf); | 1065 | ata_tf_init(ap->device, &tf); |
1016 | fis = pp->cmd_tbl; | ||
1017 | 1066 | ||
1018 | /* issue the first D2H Register FIS */ | 1067 | /* issue the first D2H Register FIS */ |
1019 | ahci_fill_cmd_slot(pp, 0, | 1068 | msecs = 0; |
1020 | cmd_fis_len | AHCI_CMD_RESET | AHCI_CMD_CLR_BUSY); | 1069 | now = jiffies; |
1070 | if (time_after(now, deadline)) | ||
1071 | msecs = jiffies_to_msecs(deadline - now); | ||
1021 | 1072 | ||
1022 | tf.ctl |= ATA_SRST; | 1073 | tf.ctl |= ATA_SRST; |
1023 | ata_tf_to_fis(&tf, fis, 0); | 1074 | if (ahci_exec_polled_cmd(ap, pmp, &tf, 0, |
1024 | fis[1] &= ~(1 << 7); /* turn off Command FIS bit */ | 1075 | AHCI_CMD_RESET | AHCI_CMD_CLR_BUSY, msecs)) { |
1025 | |||
1026 | writel(1, port_mmio + PORT_CMD_ISSUE); | ||
1027 | |||
1028 | tmp = ata_wait_register(port_mmio + PORT_CMD_ISSUE, 0x1, 0x1, 1, 500); | ||
1029 | if (tmp & 0x1) { | ||
1030 | rc = -EIO; | 1076 | rc = -EIO; |
1031 | reason = "1st FIS failed"; | 1077 | reason = "1st FIS failed"; |
1032 | goto fail; | 1078 | goto fail; |
@@ -1036,14 +1082,8 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class, | |||
1036 | msleep(1); | 1082 | msleep(1); |
1037 | 1083 | ||
1038 | /* issue the second D2H Register FIS */ | 1084 | /* issue the second D2H Register FIS */ |
1039 | ahci_fill_cmd_slot(pp, 0, cmd_fis_len); | ||
1040 | |||
1041 | tf.ctl &= ~ATA_SRST; | 1085 | tf.ctl &= ~ATA_SRST; |
1042 | ata_tf_to_fis(&tf, fis, 0); | 1086 | ahci_exec_polled_cmd(ap, pmp, &tf, 0, 0, 0); |
1043 | fis[1] &= ~(1 << 7); /* turn off Command FIS bit */ | ||
1044 | |||
1045 | writel(1, port_mmio + PORT_CMD_ISSUE); | ||
1046 | readl(port_mmio + PORT_CMD_ISSUE); /* flush */ | ||
1047 | 1087 | ||
1048 | /* spec mandates ">= 2ms" before checking status. | 1088 | /* spec mandates ">= 2ms" before checking status. |
1049 | * We wait 150ms, because that was the magic delay used for | 1089 | * We wait 150ms, because that was the magic delay used for |
@@ -1066,13 +1106,17 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class, | |||
1066 | DPRINTK("EXIT, class=%u\n", *class); | 1106 | DPRINTK("EXIT, class=%u\n", *class); |
1067 | return 0; | 1107 | return 0; |
1068 | 1108 | ||
1069 | fail_restart: | ||
1070 | ahci_start_engine(ap); | ||
1071 | fail: | 1109 | fail: |
1072 | ata_port_printk(ap, KERN_ERR, "softreset failed (%s)\n", reason); | 1110 | ata_port_printk(ap, KERN_ERR, "softreset failed (%s)\n", reason); |
1073 | return rc; | 1111 | return rc; |
1074 | } | 1112 | } |
1075 | 1113 | ||
1114 | static int ahci_softreset(struct ata_port *ap, unsigned int *class, | ||
1115 | unsigned long deadline) | ||
1116 | { | ||
1117 | return ahci_do_softreset(ap, class, 0, deadline); | ||
1118 | } | ||
1119 | |||
1076 | static int ahci_hardreset(struct ata_port *ap, unsigned int *class, | 1120 | static int ahci_hardreset(struct ata_port *ap, unsigned int *class, |
1077 | unsigned long deadline) | 1121 | unsigned long deadline) |
1078 | { | 1122 | { |
@@ -1088,7 +1132,7 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class, | |||
1088 | /* clear D2H reception area to properly wait for D2H FIS */ | 1132 | /* clear D2H reception area to properly wait for D2H FIS */ |
1089 | ata_tf_init(ap->device, &tf); | 1133 | ata_tf_init(ap->device, &tf); |
1090 | tf.command = 0x80; | 1134 | tf.command = 0x80; |
1091 | ata_tf_to_fis(&tf, d2h_fis, 0); | 1135 | ata_tf_to_fis(&tf, 0, 0, d2h_fis); |
1092 | 1136 | ||
1093 | rc = sata_std_hardreset(ap, class, deadline); | 1137 | rc = sata_std_hardreset(ap, class, deadline); |
1094 | 1138 | ||
@@ -1106,6 +1150,7 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class, | |||
1106 | static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class, | 1150 | static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class, |
1107 | unsigned long deadline) | 1151 | unsigned long deadline) |
1108 | { | 1152 | { |
1153 | u32 serror; | ||
1109 | int rc; | 1154 | int rc; |
1110 | 1155 | ||
1111 | DPRINTK("ENTER\n"); | 1156 | DPRINTK("ENTER\n"); |
@@ -1116,7 +1161,8 @@ static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class, | |||
1116 | deadline); | 1161 | deadline); |
1117 | 1162 | ||
1118 | /* vt8251 needs SError cleared for the port to operate */ | 1163 | /* vt8251 needs SError cleared for the port to operate */ |
1119 | ahci_scr_write(ap, SCR_ERROR, ahci_scr_read(ap, SCR_ERROR)); | 1164 | ahci_scr_read(ap, SCR_ERROR, &serror); |
1165 | ahci_scr_write(ap, SCR_ERROR, serror); | ||
1120 | 1166 | ||
1121 | ahci_start_engine(ap); | 1167 | ahci_start_engine(ap); |
1122 | 1168 | ||
@@ -1205,7 +1251,7 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc) | |||
1205 | */ | 1251 | */ |
1206 | cmd_tbl = pp->cmd_tbl + qc->tag * AHCI_CMD_TBL_SZ; | 1252 | cmd_tbl = pp->cmd_tbl + qc->tag * AHCI_CMD_TBL_SZ; |
1207 | 1253 | ||
1208 | ata_tf_to_fis(&qc->tf, cmd_tbl, 0); | 1254 | ata_tf_to_fis(&qc->tf, 0, 1, cmd_tbl); |
1209 | if (is_atapi) { | 1255 | if (is_atapi) { |
1210 | memset(cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32); | 1256 | memset(cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32); |
1211 | memcpy(cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, qc->dev->cdb_len); | 1257 | memcpy(cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, qc->dev->cdb_len); |
@@ -1238,7 +1284,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) | |||
1238 | ata_ehi_clear_desc(ehi); | 1284 | ata_ehi_clear_desc(ehi); |
1239 | 1285 | ||
1240 | /* AHCI needs SError cleared; otherwise, it might lock up */ | 1286 | /* AHCI needs SError cleared; otherwise, it might lock up */ |
1241 | serror = ahci_scr_read(ap, SCR_ERROR); | 1287 | ahci_scr_read(ap, SCR_ERROR, &serror); |
1242 | ahci_scr_write(ap, SCR_ERROR, serror); | 1288 | ahci_scr_write(ap, SCR_ERROR, serror); |
1243 | 1289 | ||
1244 | /* analyze @irq_stat */ | 1290 | /* analyze @irq_stat */ |
@@ -1262,12 +1308,12 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) | |||
1262 | if (irq_stat & PORT_IRQ_IF_ERR) { | 1308 | if (irq_stat & PORT_IRQ_IF_ERR) { |
1263 | err_mask |= AC_ERR_ATA_BUS; | 1309 | err_mask |= AC_ERR_ATA_BUS; |
1264 | action |= ATA_EH_SOFTRESET; | 1310 | action |= ATA_EH_SOFTRESET; |
1265 | ata_ehi_push_desc(ehi, ", interface fatal error"); | 1311 | ata_ehi_push_desc(ehi, "interface fatal error"); |
1266 | } | 1312 | } |
1267 | 1313 | ||
1268 | if (irq_stat & (PORT_IRQ_CONNECT | PORT_IRQ_PHYRDY)) { | 1314 | if (irq_stat & (PORT_IRQ_CONNECT | PORT_IRQ_PHYRDY)) { |
1269 | ata_ehi_hotplugged(ehi); | 1315 | ata_ehi_hotplugged(ehi); |
1270 | ata_ehi_push_desc(ehi, ", %s", irq_stat & PORT_IRQ_CONNECT ? | 1316 | ata_ehi_push_desc(ehi, "%s", irq_stat & PORT_IRQ_CONNECT ? |
1271 | "connection status changed" : "PHY RDY changed"); | 1317 | "connection status changed" : "PHY RDY changed"); |
1272 | } | 1318 | } |
1273 | 1319 | ||
@@ -1276,7 +1322,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) | |||
1276 | 1322 | ||
1277 | err_mask |= AC_ERR_HSM; | 1323 | err_mask |= AC_ERR_HSM; |
1278 | action |= ATA_EH_SOFTRESET; | 1324 | action |= ATA_EH_SOFTRESET; |
1279 | ata_ehi_push_desc(ehi, ", unknown FIS %08x %08x %08x %08x", | 1325 | ata_ehi_push_desc(ehi, "unknown FIS %08x %08x %08x %08x", |
1280 | unk[0], unk[1], unk[2], unk[3]); | 1326 | unk[0], unk[1], unk[2], unk[3]); |
1281 | } | 1327 | } |
1282 | 1328 | ||
@@ -1512,11 +1558,17 @@ static void ahci_post_internal_cmd(struct ata_queued_cmd *qc) | |||
1512 | { | 1558 | { |
1513 | struct ata_port *ap = qc->ap; | 1559 | struct ata_port *ap = qc->ap; |
1514 | 1560 | ||
1515 | if (qc->flags & ATA_QCFLAG_FAILED) { | 1561 | /* make DMA engine forget about the failed command */ |
1516 | /* make DMA engine forget about the failed command */ | 1562 | if (qc->flags & ATA_QCFLAG_FAILED) |
1517 | ahci_stop_engine(ap); | 1563 | ahci_kick_engine(ap, 1); |
1518 | ahci_start_engine(ap); | 1564 | } |
1519 | } | 1565 | |
1566 | static int ahci_port_resume(struct ata_port *ap) | ||
1567 | { | ||
1568 | ahci_power_up(ap); | ||
1569 | ahci_start_port(ap); | ||
1570 | |||
1571 | return 0; | ||
1520 | } | 1572 | } |
1521 | 1573 | ||
1522 | #ifdef CONFIG_PM | 1574 | #ifdef CONFIG_PM |
@@ -1536,14 +1588,6 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg) | |||
1536 | return rc; | 1588 | return rc; |
1537 | } | 1589 | } |
1538 | 1590 | ||
1539 | static int ahci_port_resume(struct ata_port *ap) | ||
1540 | { | ||
1541 | ahci_power_up(ap); | ||
1542 | ahci_start_port(ap); | ||
1543 | |||
1544 | return 0; | ||
1545 | } | ||
1546 | |||
1547 | static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) | 1591 | static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) |
1548 | { | 1592 | { |
1549 | struct ata_host *host = dev_get_drvdata(&pdev->dev); | 1593 | struct ata_host *host = dev_get_drvdata(&pdev->dev); |
@@ -1734,12 +1778,13 @@ static void ahci_print_info(struct ata_host *host) | |||
1734 | 1778 | ||
1735 | dev_printk(KERN_INFO, &pdev->dev, | 1779 | dev_printk(KERN_INFO, &pdev->dev, |
1736 | "flags: " | 1780 | "flags: " |
1737 | "%s%s%s%s%s%s" | 1781 | "%s%s%s%s%s%s%s" |
1738 | "%s%s%s%s%s%s%s\n" | 1782 | "%s%s%s%s%s%s%s\n" |
1739 | , | 1783 | , |
1740 | 1784 | ||
1741 | cap & (1 << 31) ? "64bit " : "", | 1785 | cap & (1 << 31) ? "64bit " : "", |
1742 | cap & (1 << 30) ? "ncq " : "", | 1786 | cap & (1 << 30) ? "ncq " : "", |
1787 | cap & (1 << 29) ? "sntf " : "", | ||
1743 | cap & (1 << 28) ? "ilck " : "", | 1788 | cap & (1 << 28) ? "ilck " : "", |
1744 | cap & (1 << 27) ? "stag " : "", | 1789 | cap & (1 << 27) ? "stag " : "", |
1745 | cap & (1 << 26) ? "pm " : "", | 1790 | cap & (1 << 26) ? "pm " : "", |
@@ -1794,7 +1839,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1794 | ahci_save_initial_config(pdev, &pi, hpriv); | 1839 | ahci_save_initial_config(pdev, &pi, hpriv); |
1795 | 1840 | ||
1796 | /* prepare host */ | 1841 | /* prepare host */ |
1797 | if (!(pi.flags & AHCI_FLAG_NO_NCQ) && (hpriv->cap & HOST_CAP_NCQ)) | 1842 | if (hpriv->cap & HOST_CAP_NCQ) |
1798 | pi.flags |= ATA_FLAG_NCQ; | 1843 | pi.flags |= ATA_FLAG_NCQ; |
1799 | 1844 | ||
1800 | host = ata_host_alloc_pinfo(&pdev->dev, ppi, fls(hpriv->port_map)); | 1845 | host = ata_host_alloc_pinfo(&pdev->dev, ppi, fls(hpriv->port_map)); |
@@ -1808,10 +1853,8 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1808 | void __iomem *port_mmio = ahci_port_base(ap); | 1853 | void __iomem *port_mmio = ahci_port_base(ap); |
1809 | 1854 | ||
1810 | /* standard SATA port setup */ | 1855 | /* standard SATA port setup */ |
1811 | if (hpriv->port_map & (1 << i)) { | 1856 | if (hpriv->port_map & (1 << i)) |
1812 | ap->ioaddr.cmd_addr = port_mmio; | 1857 | ap->ioaddr.cmd_addr = port_mmio; |
1813 | ap->ioaddr.scr_addr = port_mmio + PORT_SCR; | ||
1814 | } | ||
1815 | 1858 | ||
1816 | /* disabled/not-implemented port */ | 1859 | /* disabled/not-implemented port */ |
1817 | else | 1860 | else |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 88e2dd0983b5..6001aae0b884 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -111,8 +111,9 @@ MODULE_VERSION(DRV_VERSION); | |||
111 | /** | 111 | /** |
112 | * ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure | 112 | * ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure |
113 | * @tf: Taskfile to convert | 113 | * @tf: Taskfile to convert |
114 | * @fis: Buffer into which data will output | ||
115 | * @pmp: Port multiplier port | 114 | * @pmp: Port multiplier port |
115 | * @is_cmd: This FIS is for command | ||
116 | * @fis: Buffer into which data will output | ||
116 | * | 117 | * |
117 | * Converts a standard ATA taskfile to a Serial ATA | 118 | * Converts a standard ATA taskfile to a Serial ATA |
118 | * FIS structure (Register - Host to Device). | 119 | * FIS structure (Register - Host to Device). |
@@ -120,12 +121,13 @@ MODULE_VERSION(DRV_VERSION); | |||
120 | * LOCKING: | 121 | * LOCKING: |
121 | * Inherited from caller. | 122 | * Inherited from caller. |
122 | */ | 123 | */ |
123 | 124 | void ata_tf_to_fis(const struct ata_taskfile *tf, u8 pmp, int is_cmd, u8 *fis) | |
124 | void ata_tf_to_fis(const struct ata_taskfile *tf, u8 *fis, u8 pmp) | ||
125 | { | 125 | { |
126 | fis[0] = 0x27; /* Register - Host to Device FIS */ | 126 | fis[0] = 0x27; /* Register - Host to Device FIS */ |
127 | fis[1] = (pmp & 0xf) | (1 << 7); /* Port multiplier number, | 127 | fis[1] = pmp & 0xf; /* Port multiplier number*/ |
128 | bit 7 indicates Command FIS */ | 128 | if (is_cmd) |
129 | fis[1] |= (1 << 7); /* bit 7 indicates Command FIS */ | ||
130 | |||
129 | fis[2] = tf->command; | 131 | fis[2] = tf->command; |
130 | fis[3] = tf->feature; | 132 | fis[3] = tf->feature; |
131 | 133 | ||
@@ -2387,21 +2389,35 @@ int sata_down_spd_limit(struct ata_port *ap) | |||
2387 | u32 sstatus, spd, mask; | 2389 | u32 sstatus, spd, mask; |
2388 | int rc, highbit; | 2390 | int rc, highbit; |
2389 | 2391 | ||
2392 | if (!sata_scr_valid(ap)) | ||
2393 | return -EOPNOTSUPP; | ||
2394 | |||
2395 | /* If SCR can be read, use it to determine the current SPD. | ||
2396 | * If not, use cached value in ap->sata_spd. | ||
2397 | */ | ||
2390 | rc = sata_scr_read(ap, SCR_STATUS, &sstatus); | 2398 | rc = sata_scr_read(ap, SCR_STATUS, &sstatus); |
2391 | if (rc) | 2399 | if (rc == 0) |
2392 | return rc; | 2400 | spd = (sstatus >> 4) & 0xf; |
2401 | else | ||
2402 | spd = ap->sata_spd; | ||
2393 | 2403 | ||
2394 | mask = ap->sata_spd_limit; | 2404 | mask = ap->sata_spd_limit; |
2395 | if (mask <= 1) | 2405 | if (mask <= 1) |
2396 | return -EINVAL; | 2406 | return -EINVAL; |
2407 | |||
2408 | /* unconditionally mask off the highest bit */ | ||
2397 | highbit = fls(mask) - 1; | 2409 | highbit = fls(mask) - 1; |
2398 | mask &= ~(1 << highbit); | 2410 | mask &= ~(1 << highbit); |
2399 | 2411 | ||
2400 | spd = (sstatus >> 4) & 0xf; | 2412 | /* Mask off all speeds higher than or equal to the current |
2401 | if (spd <= 1) | 2413 | * one. Force 1.5Gbps if current SPD is not available. |
2402 | return -EINVAL; | 2414 | */ |
2403 | spd--; | 2415 | if (spd > 1) |
2404 | mask &= (1 << spd) - 1; | 2416 | mask &= (1 << (spd - 1)) - 1; |
2417 | else | ||
2418 | mask &= 1; | ||
2419 | |||
2420 | /* were we already at the bottom? */ | ||
2405 | if (!mask) | 2421 | if (!mask) |
2406 | return -EINVAL; | 2422 | return -EINVAL; |
2407 | 2423 | ||
@@ -3251,9 +3267,11 @@ int sata_phy_debounce(struct ata_port *ap, const unsigned long *params, | |||
3251 | last = cur; | 3267 | last = cur; |
3252 | last_jiffies = jiffies; | 3268 | last_jiffies = jiffies; |
3253 | 3269 | ||
3254 | /* check deadline */ | 3270 | /* Check deadline. If debouncing failed, return |
3271 | * -EPIPE to tell upper layer to lower link speed. | ||
3272 | */ | ||
3255 | if (time_after(jiffies, deadline)) | 3273 | if (time_after(jiffies, deadline)) |
3256 | return -EBUSY; | 3274 | return -EPIPE; |
3257 | } | 3275 | } |
3258 | } | 3276 | } |
3259 | 3277 | ||
@@ -3769,6 +3787,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { | |||
3769 | { "Hitachi HTS541616J9SA00", "SB4OC70P", ATA_HORKAGE_NONCQ, }, | 3787 | { "Hitachi HTS541616J9SA00", "SB4OC70P", ATA_HORKAGE_NONCQ, }, |
3770 | { "WDC WD740ADFD-00NLR1", NULL, ATA_HORKAGE_NONCQ, }, | 3788 | { "WDC WD740ADFD-00NLR1", NULL, ATA_HORKAGE_NONCQ, }, |
3771 | { "FUJITSU MHV2080BH", "00840028", ATA_HORKAGE_NONCQ, }, | 3789 | { "FUJITSU MHV2080BH", "00840028", ATA_HORKAGE_NONCQ, }, |
3790 | { "ST9160821AS", "3.CLF", ATA_HORKAGE_NONCQ, }, | ||
3772 | 3791 | ||
3773 | /* Devices with NCQ limits */ | 3792 | /* Devices with NCQ limits */ |
3774 | 3793 | ||
@@ -5729,10 +5748,8 @@ int sata_scr_valid(struct ata_port *ap) | |||
5729 | */ | 5748 | */ |
5730 | int sata_scr_read(struct ata_port *ap, int reg, u32 *val) | 5749 | int sata_scr_read(struct ata_port *ap, int reg, u32 *val) |
5731 | { | 5750 | { |
5732 | if (sata_scr_valid(ap)) { | 5751 | if (sata_scr_valid(ap)) |
5733 | *val = ap->ops->scr_read(ap, reg); | 5752 | return ap->ops->scr_read(ap, reg, val); |
5734 | return 0; | ||
5735 | } | ||
5736 | return -EOPNOTSUPP; | 5753 | return -EOPNOTSUPP; |
5737 | } | 5754 | } |
5738 | 5755 | ||
@@ -5754,10 +5771,8 @@ int sata_scr_read(struct ata_port *ap, int reg, u32 *val) | |||
5754 | */ | 5771 | */ |
5755 | int sata_scr_write(struct ata_port *ap, int reg, u32 val) | 5772 | int sata_scr_write(struct ata_port *ap, int reg, u32 val) |
5756 | { | 5773 | { |
5757 | if (sata_scr_valid(ap)) { | 5774 | if (sata_scr_valid(ap)) |
5758 | ap->ops->scr_write(ap, reg, val); | 5775 | return ap->ops->scr_write(ap, reg, val); |
5759 | return 0; | ||
5760 | } | ||
5761 | return -EOPNOTSUPP; | 5776 | return -EOPNOTSUPP; |
5762 | } | 5777 | } |
5763 | 5778 | ||
@@ -5778,10 +5793,13 @@ int sata_scr_write(struct ata_port *ap, int reg, u32 val) | |||
5778 | */ | 5793 | */ |
5779 | int sata_scr_write_flush(struct ata_port *ap, int reg, u32 val) | 5794 | int sata_scr_write_flush(struct ata_port *ap, int reg, u32 val) |
5780 | { | 5795 | { |
5796 | int rc; | ||
5797 | |||
5781 | if (sata_scr_valid(ap)) { | 5798 | if (sata_scr_valid(ap)) { |
5782 | ap->ops->scr_write(ap, reg, val); | 5799 | rc = ap->ops->scr_write(ap, reg, val); |
5783 | ap->ops->scr_read(ap, reg); | 5800 | if (rc == 0) |
5784 | return 0; | 5801 | rc = ap->ops->scr_read(ap, reg, &val); |
5802 | return rc; | ||
5785 | } | 5803 | } |
5786 | return -EOPNOTSUPP; | 5804 | return -EOPNOTSUPP; |
5787 | } | 5805 | } |
@@ -5993,6 +6011,7 @@ void ata_dev_init(struct ata_device *dev) | |||
5993 | 6011 | ||
5994 | /* SATA spd limit is bound to the first device */ | 6012 | /* SATA spd limit is bound to the first device */ |
5995 | ap->sata_spd_limit = ap->hw_sata_spd_limit; | 6013 | ap->sata_spd_limit = ap->hw_sata_spd_limit; |
6014 | ap->sata_spd = 0; | ||
5996 | 6015 | ||
5997 | /* High bits of dev->flags are used to record warm plug | 6016 | /* High bits of dev->flags are used to record warm plug |
5998 | * requests which occur asynchronously. Synchronize using | 6017 | * requests which occur asynchronously. Synchronize using |
@@ -6058,6 +6077,9 @@ struct ata_port *ata_port_alloc(struct ata_host *host) | |||
6058 | INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan); | 6077 | INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan); |
6059 | INIT_LIST_HEAD(&ap->eh_done_q); | 6078 | INIT_LIST_HEAD(&ap->eh_done_q); |
6060 | init_waitqueue_head(&ap->eh_wait_q); | 6079 | init_waitqueue_head(&ap->eh_wait_q); |
6080 | init_timer_deferrable(&ap->fastdrain_timer); | ||
6081 | ap->fastdrain_timer.function = ata_eh_fastdrain_timerfn; | ||
6082 | ap->fastdrain_timer.data = (unsigned long)ap; | ||
6061 | 6083 | ||
6062 | ap->cbl = ATA_CBL_NONE; | 6084 | ap->cbl = ATA_CBL_NONE; |
6063 | 6085 | ||
@@ -6434,7 +6456,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) | |||
6434 | for (i = 0; i < host->n_ports; i++) { | 6456 | for (i = 0; i < host->n_ports; i++) { |
6435 | struct ata_port *ap = host->ports[i]; | 6457 | struct ata_port *ap = host->ports[i]; |
6436 | 6458 | ||
6437 | ata_scsi_scan_host(ap); | 6459 | ata_scsi_scan_host(ap, 1); |
6438 | } | 6460 | } |
6439 | 6461 | ||
6440 | return 0; | 6462 | return 0; |
@@ -6942,6 +6964,9 @@ EXPORT_SYMBOL_GPL(ata_pci_default_filter); | |||
6942 | EXPORT_SYMBOL_GPL(ata_pci_clear_simplex); | 6964 | EXPORT_SYMBOL_GPL(ata_pci_clear_simplex); |
6943 | #endif /* CONFIG_PCI */ | 6965 | #endif /* CONFIG_PCI */ |
6944 | 6966 | ||
6967 | EXPORT_SYMBOL_GPL(__ata_ehi_push_desc); | ||
6968 | EXPORT_SYMBOL_GPL(ata_ehi_push_desc); | ||
6969 | EXPORT_SYMBOL_GPL(ata_ehi_clear_desc); | ||
6945 | EXPORT_SYMBOL_GPL(ata_eng_timeout); | 6970 | EXPORT_SYMBOL_GPL(ata_eng_timeout); |
6946 | EXPORT_SYMBOL_GPL(ata_port_schedule_eh); | 6971 | EXPORT_SYMBOL_GPL(ata_port_schedule_eh); |
6947 | EXPORT_SYMBOL_GPL(ata_port_abort); | 6972 | EXPORT_SYMBOL_GPL(ata_port_abort); |
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 9aa62a0754f6..ac6ceed4bb60 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
@@ -56,6 +56,7 @@ enum { | |||
56 | */ | 56 | */ |
57 | enum { | 57 | enum { |
58 | ATA_EH_PRERESET_TIMEOUT = 10 * HZ, | 58 | ATA_EH_PRERESET_TIMEOUT = 10 * HZ, |
59 | ATA_EH_FASTDRAIN_INTERVAL = 3 * HZ, | ||
59 | }; | 60 | }; |
60 | 61 | ||
61 | /* The following table determines how we sequence resets. Each entry | 62 | /* The following table determines how we sequence resets. Each entry |
@@ -85,6 +86,71 @@ static void ata_eh_handle_port_resume(struct ata_port *ap) | |||
85 | { } | 86 | { } |
86 | #endif /* CONFIG_PM */ | 87 | #endif /* CONFIG_PM */ |
87 | 88 | ||
89 | static void __ata_ehi_pushv_desc(struct ata_eh_info *ehi, const char *fmt, | ||
90 | va_list args) | ||
91 | { | ||
92 | ehi->desc_len += vscnprintf(ehi->desc + ehi->desc_len, | ||
93 | ATA_EH_DESC_LEN - ehi->desc_len, | ||
94 | fmt, args); | ||
95 | } | ||
96 | |||
97 | /** | ||
98 | * __ata_ehi_push_desc - push error description without adding separator | ||
99 | * @ehi: target EHI | ||
100 | * @fmt: printf format string | ||
101 | * | ||
102 | * Format string according to @fmt and append it to @ehi->desc. | ||
103 | * | ||
104 | * LOCKING: | ||
105 | * spin_lock_irqsave(host lock) | ||
106 | */ | ||
107 | void __ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...) | ||
108 | { | ||
109 | va_list args; | ||
110 | |||
111 | va_start(args, fmt); | ||
112 | __ata_ehi_pushv_desc(ehi, fmt, args); | ||
113 | va_end(args); | ||
114 | } | ||
115 | |||
116 | /** | ||
117 | * ata_ehi_push_desc - push error description with separator | ||
118 | * @ehi: target EHI | ||
119 | * @fmt: printf format string | ||
120 | * | ||
121 | * Format string according to @fmt and append it to @ehi->desc. | ||
122 | * If @ehi->desc is not empty, ", " is added in-between. | ||
123 | * | ||
124 | * LOCKING: | ||
125 | * spin_lock_irqsave(host lock) | ||
126 | */ | ||
127 | void ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...) | ||
128 | { | ||
129 | va_list args; | ||
130 | |||
131 | if (ehi->desc_len) | ||
132 | __ata_ehi_push_desc(ehi, ", "); | ||
133 | |||
134 | va_start(args, fmt); | ||
135 | __ata_ehi_pushv_desc(ehi, fmt, args); | ||
136 | va_end(args); | ||
137 | } | ||
138 | |||
139 | /** | ||
140 | * ata_ehi_clear_desc - clean error description | ||
141 | * @ehi: target EHI | ||
142 | * | ||
143 | * Clear @ehi->desc. | ||
144 | * | ||
145 | * LOCKING: | ||
146 | * spin_lock_irqsave(host lock) | ||
147 | */ | ||
148 | void ata_ehi_clear_desc(struct ata_eh_info *ehi) | ||
149 | { | ||
150 | ehi->desc[0] = '\0'; | ||
151 | ehi->desc_len = 0; | ||
152 | } | ||
153 | |||
88 | static void ata_ering_record(struct ata_ering *ering, int is_io, | 154 | static void ata_ering_record(struct ata_ering *ering, int is_io, |
89 | unsigned int err_mask) | 155 | unsigned int err_mask) |
90 | { | 156 | { |
@@ -296,6 +362,9 @@ void ata_scsi_error(struct Scsi_Host *host) | |||
296 | repeat: | 362 | repeat: |
297 | /* invoke error handler */ | 363 | /* invoke error handler */ |
298 | if (ap->ops->error_handler) { | 364 | if (ap->ops->error_handler) { |
365 | /* kill fast drain timer */ | ||
366 | del_timer_sync(&ap->fastdrain_timer); | ||
367 | |||
299 | /* process port resume request */ | 368 | /* process port resume request */ |
300 | ata_eh_handle_port_resume(ap); | 369 | ata_eh_handle_port_resume(ap); |
301 | 370 | ||
@@ -511,6 +580,94 @@ void ata_eng_timeout(struct ata_port *ap) | |||
511 | DPRINTK("EXIT\n"); | 580 | DPRINTK("EXIT\n"); |
512 | } | 581 | } |
513 | 582 | ||
583 | static int ata_eh_nr_in_flight(struct ata_port *ap) | ||
584 | { | ||
585 | unsigned int tag; | ||
586 | int nr = 0; | ||
587 | |||
588 | /* count only non-internal commands */ | ||
589 | for (tag = 0; tag < ATA_MAX_QUEUE - 1; tag++) | ||
590 | if (ata_qc_from_tag(ap, tag)) | ||
591 | nr++; | ||
592 | |||
593 | return nr; | ||
594 | } | ||
595 | |||
596 | void ata_eh_fastdrain_timerfn(unsigned long arg) | ||
597 | { | ||
598 | struct ata_port *ap = (void *)arg; | ||
599 | unsigned long flags; | ||
600 | int cnt; | ||
601 | |||
602 | spin_lock_irqsave(ap->lock, flags); | ||
603 | |||
604 | cnt = ata_eh_nr_in_flight(ap); | ||
605 | |||
606 | /* are we done? */ | ||
607 | if (!cnt) | ||
608 | goto out_unlock; | ||
609 | |||
610 | if (cnt == ap->fastdrain_cnt) { | ||
611 | unsigned int tag; | ||
612 | |||
613 | /* No progress during the last interval, tag all | ||
614 | * in-flight qcs as timed out and freeze the port. | ||
615 | */ | ||
616 | for (tag = 0; tag < ATA_MAX_QUEUE - 1; tag++) { | ||
617 | struct ata_queued_cmd *qc = ata_qc_from_tag(ap, tag); | ||
618 | if (qc) | ||
619 | qc->err_mask |= AC_ERR_TIMEOUT; | ||
620 | } | ||
621 | |||
622 | ata_port_freeze(ap); | ||
623 | } else { | ||
624 | /* some qcs have finished, give it another chance */ | ||
625 | ap->fastdrain_cnt = cnt; | ||
626 | ap->fastdrain_timer.expires = | ||
627 | jiffies + ATA_EH_FASTDRAIN_INTERVAL; | ||
628 | add_timer(&ap->fastdrain_timer); | ||
629 | } | ||
630 | |||
631 | out_unlock: | ||
632 | spin_unlock_irqrestore(ap->lock, flags); | ||
633 | } | ||
634 | |||
635 | /** | ||
636 | * ata_eh_set_pending - set ATA_PFLAG_EH_PENDING and activate fast drain | ||
637 | * @ap: target ATA port | ||
638 | * @fastdrain: activate fast drain | ||
639 | * | ||
640 | * Set ATA_PFLAG_EH_PENDING and activate fast drain if @fastdrain | ||
641 | * is non-zero and EH wasn't pending before. Fast drain ensures | ||
642 | * that EH kicks in in timely manner. | ||
643 | * | ||
644 | * LOCKING: | ||
645 | * spin_lock_irqsave(host lock) | ||
646 | */ | ||
647 | static void ata_eh_set_pending(struct ata_port *ap, int fastdrain) | ||
648 | { | ||
649 | int cnt; | ||
650 | |||
651 | /* already scheduled? */ | ||
652 | if (ap->pflags & ATA_PFLAG_EH_PENDING) | ||
653 | return; | ||
654 | |||
655 | ap->pflags |= ATA_PFLAG_EH_PENDING; | ||
656 | |||
657 | if (!fastdrain) | ||
658 | return; | ||
659 | |||
660 | /* do we have in-flight qcs? */ | ||
661 | cnt = ata_eh_nr_in_flight(ap); | ||
662 | if (!cnt) | ||
663 | return; | ||
664 | |||
665 | /* activate fast drain */ | ||
666 | ap->fastdrain_cnt = cnt; | ||
667 | ap->fastdrain_timer.expires = jiffies + ATA_EH_FASTDRAIN_INTERVAL; | ||
668 | add_timer(&ap->fastdrain_timer); | ||
669 | } | ||
670 | |||
514 | /** | 671 | /** |
515 | * ata_qc_schedule_eh - schedule qc for error handling | 672 | * ata_qc_schedule_eh - schedule qc for error handling |
516 | * @qc: command to schedule error handling for | 673 | * @qc: command to schedule error handling for |
@@ -528,7 +685,7 @@ void ata_qc_schedule_eh(struct ata_queued_cmd *qc) | |||
528 | WARN_ON(!ap->ops->error_handler); | 685 | WARN_ON(!ap->ops->error_handler); |
529 | 686 | ||
530 | qc->flags |= ATA_QCFLAG_FAILED; | 687 | qc->flags |= ATA_QCFLAG_FAILED; |
531 | qc->ap->pflags |= ATA_PFLAG_EH_PENDING; | 688 | ata_eh_set_pending(ap, 1); |
532 | 689 | ||
533 | /* The following will fail if timeout has already expired. | 690 | /* The following will fail if timeout has already expired. |
534 | * ata_scsi_error() takes care of such scmds on EH entry. | 691 | * ata_scsi_error() takes care of such scmds on EH entry. |
@@ -555,7 +712,7 @@ void ata_port_schedule_eh(struct ata_port *ap) | |||
555 | if (ap->pflags & ATA_PFLAG_INITIALIZING) | 712 | if (ap->pflags & ATA_PFLAG_INITIALIZING) |
556 | return; | 713 | return; |
557 | 714 | ||
558 | ap->pflags |= ATA_PFLAG_EH_PENDING; | 715 | ata_eh_set_pending(ap, 1); |
559 | scsi_schedule_eh(ap->scsi_host); | 716 | scsi_schedule_eh(ap->scsi_host); |
560 | 717 | ||
561 | DPRINTK("port EH scheduled\n"); | 718 | DPRINTK("port EH scheduled\n"); |
@@ -579,6 +736,9 @@ int ata_port_abort(struct ata_port *ap) | |||
579 | 736 | ||
580 | WARN_ON(!ap->ops->error_handler); | 737 | WARN_ON(!ap->ops->error_handler); |
581 | 738 | ||
739 | /* we're gonna abort all commands, no need for fast drain */ | ||
740 | ata_eh_set_pending(ap, 0); | ||
741 | |||
582 | for (tag = 0; tag < ATA_MAX_QUEUE; tag++) { | 742 | for (tag = 0; tag < ATA_MAX_QUEUE; tag++) { |
583 | struct ata_queued_cmd *qc = ata_qc_from_tag(ap, tag); | 743 | struct ata_queued_cmd *qc = ata_qc_from_tag(ap, tag); |
584 | 744 | ||
@@ -1130,7 +1290,7 @@ static void ata_eh_analyze_ncq_error(struct ata_port *ap) | |||
1130 | /* we've got the perpetrator, condemn it */ | 1290 | /* we've got the perpetrator, condemn it */ |
1131 | qc = __ata_qc_from_tag(ap, tag); | 1291 | qc = __ata_qc_from_tag(ap, tag); |
1132 | memcpy(&qc->result_tf, &tf, sizeof(tf)); | 1292 | memcpy(&qc->result_tf, &tf, sizeof(tf)); |
1133 | qc->err_mask |= AC_ERR_DEV; | 1293 | qc->err_mask |= AC_ERR_DEV | AC_ERR_NCQ; |
1134 | ehc->i.err_mask &= ~AC_ERR_DEV; | 1294 | ehc->i.err_mask &= ~AC_ERR_DEV; |
1135 | } | 1295 | } |
1136 | 1296 | ||
@@ -1413,8 +1573,12 @@ static void ata_eh_autopsy(struct ata_port *ap) | |||
1413 | if (rc == 0) { | 1573 | if (rc == 0) { |
1414 | ehc->i.serror |= serror; | 1574 | ehc->i.serror |= serror; |
1415 | ata_eh_analyze_serror(ap); | 1575 | ata_eh_analyze_serror(ap); |
1416 | } else if (rc != -EOPNOTSUPP) | 1576 | } else if (rc != -EOPNOTSUPP) { |
1577 | /* SError read failed, force hardreset and probing */ | ||
1578 | ata_ehi_schedule_probe(&ehc->i); | ||
1417 | ehc->i.action |= ATA_EH_HARDRESET; | 1579 | ehc->i.action |= ATA_EH_HARDRESET; |
1580 | ehc->i.err_mask |= AC_ERR_OTHER; | ||
1581 | } | ||
1418 | 1582 | ||
1419 | /* analyze NCQ failure */ | 1583 | /* analyze NCQ failure */ |
1420 | ata_eh_analyze_ncq_error(ap); | 1584 | ata_eh_analyze_ncq_error(ap); |
@@ -1524,14 +1688,14 @@ static void ata_eh_report(struct ata_port *ap) | |||
1524 | ehc->i.err_mask, ap->sactive, ehc->i.serror, | 1688 | ehc->i.err_mask, ap->sactive, ehc->i.serror, |
1525 | ehc->i.action, frozen); | 1689 | ehc->i.action, frozen); |
1526 | if (desc) | 1690 | if (desc) |
1527 | ata_dev_printk(ehc->i.dev, KERN_ERR, "(%s)\n", desc); | 1691 | ata_dev_printk(ehc->i.dev, KERN_ERR, "%s\n", desc); |
1528 | } else { | 1692 | } else { |
1529 | ata_port_printk(ap, KERN_ERR, "exception Emask 0x%x " | 1693 | ata_port_printk(ap, KERN_ERR, "exception Emask 0x%x " |
1530 | "SAct 0x%x SErr 0x%x action 0x%x%s\n", | 1694 | "SAct 0x%x SErr 0x%x action 0x%x%s\n", |
1531 | ehc->i.err_mask, ap->sactive, ehc->i.serror, | 1695 | ehc->i.err_mask, ap->sactive, ehc->i.serror, |
1532 | ehc->i.action, frozen); | 1696 | ehc->i.action, frozen); |
1533 | if (desc) | 1697 | if (desc) |
1534 | ata_port_printk(ap, KERN_ERR, "(%s)\n", desc); | 1698 | ata_port_printk(ap, KERN_ERR, "%s\n", desc); |
1535 | } | 1699 | } |
1536 | 1700 | ||
1537 | for (tag = 0; tag < ATA_MAX_QUEUE; tag++) { | 1701 | for (tag = 0; tag < ATA_MAX_QUEUE; tag++) { |
@@ -1551,7 +1715,7 @@ static void ata_eh_report(struct ata_port *ap) | |||
1551 | "cmd %02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x " | 1715 | "cmd %02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x " |
1552 | "tag %d cdb 0x%x data %u %s\n " | 1716 | "tag %d cdb 0x%x data %u %s\n " |
1553 | "res %02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x " | 1717 | "res %02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x " |
1554 | "Emask 0x%x (%s)\n", | 1718 | "Emask 0x%x (%s)%s\n", |
1555 | cmd->command, cmd->feature, cmd->nsect, | 1719 | cmd->command, cmd->feature, cmd->nsect, |
1556 | cmd->lbal, cmd->lbam, cmd->lbah, | 1720 | cmd->lbal, cmd->lbam, cmd->lbah, |
1557 | cmd->hob_feature, cmd->hob_nsect, | 1721 | cmd->hob_feature, cmd->hob_nsect, |
@@ -1562,7 +1726,8 @@ static void ata_eh_report(struct ata_port *ap) | |||
1562 | res->lbal, res->lbam, res->lbah, | 1726 | res->lbal, res->lbam, res->lbah, |
1563 | res->hob_feature, res->hob_nsect, | 1727 | res->hob_feature, res->hob_nsect, |
1564 | res->hob_lbal, res->hob_lbam, res->hob_lbah, | 1728 | res->hob_lbal, res->hob_lbam, res->hob_lbah, |
1565 | res->device, qc->err_mask, ata_err_string(qc->err_mask)); | 1729 | res->device, qc->err_mask, ata_err_string(qc->err_mask), |
1730 | qc->err_mask & AC_ERR_NCQ ? " <F>" : ""); | ||
1566 | } | 1731 | } |
1567 | } | 1732 | } |
1568 | 1733 | ||
@@ -1648,7 +1813,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, | |||
1648 | } else | 1813 | } else |
1649 | ata_port_printk(ap, KERN_ERR, | 1814 | ata_port_printk(ap, KERN_ERR, |
1650 | "prereset failed (errno=%d)\n", rc); | 1815 | "prereset failed (errno=%d)\n", rc); |
1651 | return rc; | 1816 | goto out; |
1652 | } | 1817 | } |
1653 | } | 1818 | } |
1654 | 1819 | ||
@@ -1661,7 +1826,8 @@ static int ata_eh_reset(struct ata_port *ap, int classify, | |||
1661 | /* prereset told us not to reset, bang classes and return */ | 1826 | /* prereset told us not to reset, bang classes and return */ |
1662 | for (i = 0; i < ATA_MAX_DEVICES; i++) | 1827 | for (i = 0; i < ATA_MAX_DEVICES; i++) |
1663 | classes[i] = ATA_DEV_NONE; | 1828 | classes[i] = ATA_DEV_NONE; |
1664 | return 0; | 1829 | rc = 0; |
1830 | goto out; | ||
1665 | } | 1831 | } |
1666 | 1832 | ||
1667 | /* did prereset() screw up? if so, fix up to avoid oopsing */ | 1833 | /* did prereset() screw up? if so, fix up to avoid oopsing */ |
@@ -1697,7 +1863,8 @@ static int ata_eh_reset(struct ata_port *ap, int classify, | |||
1697 | ata_port_printk(ap, KERN_ERR, | 1863 | ata_port_printk(ap, KERN_ERR, |
1698 | "follow-up softreset required " | 1864 | "follow-up softreset required " |
1699 | "but no softreset avaliable\n"); | 1865 | "but no softreset avaliable\n"); |
1700 | return -EINVAL; | 1866 | rc = -EINVAL; |
1867 | goto out; | ||
1701 | } | 1868 | } |
1702 | 1869 | ||
1703 | ata_eh_about_to_do(ap, NULL, ATA_EH_RESET_MASK); | 1870 | ata_eh_about_to_do(ap, NULL, ATA_EH_RESET_MASK); |
@@ -1707,7 +1874,8 @@ static int ata_eh_reset(struct ata_port *ap, int classify, | |||
1707 | classes[0] == ATA_DEV_UNKNOWN) { | 1874 | classes[0] == ATA_DEV_UNKNOWN) { |
1708 | ata_port_printk(ap, KERN_ERR, | 1875 | ata_port_printk(ap, KERN_ERR, |
1709 | "classification failed\n"); | 1876 | "classification failed\n"); |
1710 | return -EINVAL; | 1877 | rc = -EINVAL; |
1878 | goto out; | ||
1711 | } | 1879 | } |
1712 | } | 1880 | } |
1713 | 1881 | ||
@@ -1724,7 +1892,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, | |||
1724 | schedule_timeout_uninterruptible(delta); | 1892 | schedule_timeout_uninterruptible(delta); |
1725 | } | 1893 | } |
1726 | 1894 | ||
1727 | if (reset == hardreset && | 1895 | if (rc == -EPIPE || |
1728 | try == ARRAY_SIZE(ata_eh_reset_timeouts) - 1) | 1896 | try == ARRAY_SIZE(ata_eh_reset_timeouts) - 1) |
1729 | sata_down_spd_limit(ap); | 1897 | sata_down_spd_limit(ap); |
1730 | if (hardreset) | 1898 | if (hardreset) |
@@ -1733,12 +1901,18 @@ static int ata_eh_reset(struct ata_port *ap, int classify, | |||
1733 | } | 1901 | } |
1734 | 1902 | ||
1735 | if (rc == 0) { | 1903 | if (rc == 0) { |
1904 | u32 sstatus; | ||
1905 | |||
1736 | /* After the reset, the device state is PIO 0 and the | 1906 | /* After the reset, the device state is PIO 0 and the |
1737 | * controller state is undefined. Record the mode. | 1907 | * controller state is undefined. Record the mode. |
1738 | */ | 1908 | */ |
1739 | for (i = 0; i < ATA_MAX_DEVICES; i++) | 1909 | for (i = 0; i < ATA_MAX_DEVICES; i++) |
1740 | ap->device[i].pio_mode = XFER_PIO_0; | 1910 | ap->device[i].pio_mode = XFER_PIO_0; |
1741 | 1911 | ||
1912 | /* record current link speed */ | ||
1913 | if (sata_scr_read(ap, SCR_STATUS, &sstatus) == 0) | ||
1914 | ap->sata_spd = (sstatus >> 4) & 0xf; | ||
1915 | |||
1742 | if (postreset) | 1916 | if (postreset) |
1743 | postreset(ap, classes); | 1917 | postreset(ap, classes); |
1744 | 1918 | ||
@@ -1746,7 +1920,9 @@ static int ata_eh_reset(struct ata_port *ap, int classify, | |||
1746 | ata_eh_done(ap, NULL, ehc->i.action & ATA_EH_RESET_MASK); | 1920 | ata_eh_done(ap, NULL, ehc->i.action & ATA_EH_RESET_MASK); |
1747 | ehc->i.action |= ATA_EH_REVALIDATE; | 1921 | ehc->i.action |= ATA_EH_REVALIDATE; |
1748 | } | 1922 | } |
1749 | 1923 | out: | |
1924 | /* clear hotplug flag */ | ||
1925 | ehc->i.flags &= ~ATA_EHI_HOTPLUGGED; | ||
1750 | return rc; | 1926 | return rc; |
1751 | } | 1927 | } |
1752 | 1928 | ||
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index cfde22da07ac..12ac0b511f79 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -2947,17 +2947,22 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht) | |||
2947 | return rc; | 2947 | return rc; |
2948 | } | 2948 | } |
2949 | 2949 | ||
2950 | void ata_scsi_scan_host(struct ata_port *ap) | 2950 | void ata_scsi_scan_host(struct ata_port *ap, int sync) |
2951 | { | 2951 | { |
2952 | int tries = 5; | ||
2953 | struct ata_device *last_failed_dev = NULL; | ||
2954 | struct ata_device *dev; | ||
2952 | unsigned int i; | 2955 | unsigned int i; |
2953 | 2956 | ||
2954 | if (ap->flags & ATA_FLAG_DISABLED) | 2957 | if (ap->flags & ATA_FLAG_DISABLED) |
2955 | return; | 2958 | return; |
2956 | 2959 | ||
2960 | repeat: | ||
2957 | for (i = 0; i < ATA_MAX_DEVICES; i++) { | 2961 | for (i = 0; i < ATA_MAX_DEVICES; i++) { |
2958 | struct ata_device *dev = &ap->device[i]; | ||
2959 | struct scsi_device *sdev; | 2962 | struct scsi_device *sdev; |
2960 | 2963 | ||
2964 | dev = &ap->device[i]; | ||
2965 | |||
2961 | if (!ata_dev_enabled(dev) || dev->sdev) | 2966 | if (!ata_dev_enabled(dev) || dev->sdev) |
2962 | continue; | 2967 | continue; |
2963 | 2968 | ||
@@ -2967,6 +2972,45 @@ void ata_scsi_scan_host(struct ata_port *ap) | |||
2967 | scsi_device_put(sdev); | 2972 | scsi_device_put(sdev); |
2968 | } | 2973 | } |
2969 | } | 2974 | } |
2975 | |||
2976 | /* If we scanned while EH was in progress or allocation | ||
2977 | * failure occurred, scan would have failed silently. Check | ||
2978 | * whether all devices are attached. | ||
2979 | */ | ||
2980 | for (i = 0; i < ATA_MAX_DEVICES; i++) { | ||
2981 | dev = &ap->device[i]; | ||
2982 | if (ata_dev_enabled(dev) && !dev->sdev) | ||
2983 | break; | ||
2984 | } | ||
2985 | if (i == ATA_MAX_DEVICES) | ||
2986 | return; | ||
2987 | |||
2988 | /* we're missing some SCSI devices */ | ||
2989 | if (sync) { | ||
2990 | /* If caller requested synchrnous scan && we've made | ||
2991 | * any progress, sleep briefly and repeat. | ||
2992 | */ | ||
2993 | if (dev != last_failed_dev) { | ||
2994 | msleep(100); | ||
2995 | last_failed_dev = dev; | ||
2996 | goto repeat; | ||
2997 | } | ||
2998 | |||
2999 | /* We might be failing to detect boot device, give it | ||
3000 | * a few more chances. | ||
3001 | */ | ||
3002 | if (--tries) { | ||
3003 | msleep(100); | ||
3004 | goto repeat; | ||
3005 | } | ||
3006 | |||
3007 | ata_port_printk(ap, KERN_ERR, "WARNING: synchronous SCSI scan " | ||
3008 | "failed without making any progress,\n" | ||
3009 | " switching to async\n"); | ||
3010 | } | ||
3011 | |||
3012 | queue_delayed_work(ata_aux_wq, &ap->hotplug_task, | ||
3013 | round_jiffies_relative(HZ)); | ||
2970 | } | 3014 | } |
2971 | 3015 | ||
2972 | /** | 3016 | /** |
@@ -3093,20 +3137,7 @@ void ata_scsi_hotplug(struct work_struct *work) | |||
3093 | } | 3137 | } |
3094 | 3138 | ||
3095 | /* scan for new ones */ | 3139 | /* scan for new ones */ |
3096 | ata_scsi_scan_host(ap); | 3140 | ata_scsi_scan_host(ap, 0); |
3097 | |||
3098 | /* If we scanned while EH was in progress, scan would have | ||
3099 | * failed silently. Requeue if there are enabled but | ||
3100 | * unattached devices. | ||
3101 | */ | ||
3102 | for (i = 0; i < ATA_MAX_DEVICES; i++) { | ||
3103 | struct ata_device *dev = &ap->device[i]; | ||
3104 | if (ata_dev_enabled(dev) && !dev->sdev) { | ||
3105 | queue_delayed_work(ata_aux_wq, &ap->hotplug_task, | ||
3106 | round_jiffies_relative(HZ)); | ||
3107 | break; | ||
3108 | } | ||
3109 | } | ||
3110 | 3141 | ||
3111 | DPRINTK("EXIT\n"); | 3142 | DPRINTK("EXIT\n"); |
3112 | } | 3143 | } |
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index ca7d2245d684..6c289c7b1322 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * libata-bmdma.c - helper library for PCI IDE BMDMA | 2 | * libata-sff.c - helper library for PCI IDE BMDMA |
3 | * | 3 | * |
4 | * Maintained by: Jeff Garzik <jgarzik@pobox.com> | 4 | * Maintained by: Jeff Garzik <jgarzik@pobox.com> |
5 | * Please ALWAYS copy linux-ide@vger.kernel.org | 5 | * Please ALWAYS copy linux-ide@vger.kernel.org |
@@ -211,6 +211,8 @@ void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) | |||
211 | tf->hob_lbal = ioread8(ioaddr->lbal_addr); | 211 | tf->hob_lbal = ioread8(ioaddr->lbal_addr); |
212 | tf->hob_lbam = ioread8(ioaddr->lbam_addr); | 212 | tf->hob_lbam = ioread8(ioaddr->lbam_addr); |
213 | tf->hob_lbah = ioread8(ioaddr->lbah_addr); | 213 | tf->hob_lbah = ioread8(ioaddr->lbah_addr); |
214 | iowrite8(tf->ctl, ioaddr->ctl_addr); | ||
215 | ap->last_ctl = tf->ctl; | ||
214 | } | 216 | } |
215 | } | 217 | } |
216 | 218 | ||
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index ba17fc5f2e99..564cd234c805 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h | |||
@@ -112,7 +112,7 @@ static inline int ata_acpi_on_devcfg(struct ata_device *adev) { return 0; } | |||
112 | /* libata-scsi.c */ | 112 | /* libata-scsi.c */ |
113 | extern int ata_scsi_add_hosts(struct ata_host *host, | 113 | extern int ata_scsi_add_hosts(struct ata_host *host, |
114 | struct scsi_host_template *sht); | 114 | struct scsi_host_template *sht); |
115 | extern void ata_scsi_scan_host(struct ata_port *ap); | 115 | extern void ata_scsi_scan_host(struct ata_port *ap, int sync); |
116 | extern int ata_scsi_offline_dev(struct ata_device *dev); | 116 | extern int ata_scsi_offline_dev(struct ata_device *dev); |
117 | extern void ata_scsi_hotplug(struct work_struct *work); | 117 | extern void ata_scsi_hotplug(struct work_struct *work); |
118 | extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf, | 118 | extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf, |
@@ -151,6 +151,7 @@ extern int ata_bus_probe(struct ata_port *ap); | |||
151 | extern enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd); | 151 | extern enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd); |
152 | extern void ata_scsi_error(struct Scsi_Host *host); | 152 | extern void ata_scsi_error(struct Scsi_Host *host); |
153 | extern void ata_port_wait_eh(struct ata_port *ap); | 153 | extern void ata_port_wait_eh(struct ata_port *ap); |
154 | extern void ata_eh_fastdrain_timerfn(unsigned long arg); | ||
154 | extern void ata_qc_schedule_eh(struct ata_queued_cmd *qc); | 155 | extern void ata_qc_schedule_eh(struct ata_queued_cmd *qc); |
155 | 156 | ||
156 | /* libata-sff.c */ | 157 | /* libata-sff.c */ |
diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c index 6bf037d82b5a..7dc76e71bd55 100644 --- a/drivers/ata/pata_cs5520.c +++ b/drivers/ata/pata_cs5520.c | |||
@@ -275,7 +275,7 @@ static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_devi | |||
275 | 275 | ||
276 | for (i = 0; i < 2; i++) { | 276 | for (i = 0; i < 2; i++) { |
277 | static const int irq[] = { 14, 15 }; | 277 | static const int irq[] = { 14, 15 }; |
278 | struct ata_port *ap = host->ports[0]; | 278 | struct ata_port *ap = host->ports[i]; |
279 | 279 | ||
280 | if (ata_port_is_dummy(ap)) | 280 | if (ata_port_is_dummy(ap)) |
281 | continue; | 281 | continue; |
diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c index 79f841bca593..a909f793ffc1 100644 --- a/drivers/ata/pata_platform.c +++ b/drivers/ata/pata_platform.c | |||
@@ -213,8 +213,9 @@ static int __devinit pata_platform_probe(struct platform_device *pdev) | |||
213 | pata_platform_setup_port(&ap->ioaddr, pp_info); | 213 | pata_platform_setup_port(&ap->ioaddr, pp_info); |
214 | 214 | ||
215 | /* activate */ | 215 | /* activate */ |
216 | return ata_host_activate(host, platform_get_irq(pdev, 0), ata_interrupt, | 216 | return ata_host_activate(host, platform_get_irq(pdev, 0), |
217 | pp_info->irq_flags, &pata_platform_sht); | 217 | ata_interrupt, pp_info ? pp_info->irq_flags |
218 | : 0, &pata_platform_sht); | ||
218 | } | 219 | } |
219 | 220 | ||
220 | /** | 221 | /** |
diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index c55667e0eb65..36cdbd2b0bd5 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c | |||
@@ -238,12 +238,6 @@ static void scc_set_dmamode (struct ata_port *ap, struct ata_device *adev) | |||
238 | else | 238 | else |
239 | offset = 0; /* 100MHz */ | 239 | offset = 0; /* 100MHz */ |
240 | 240 | ||
241 | /* errata A308 workaround: limit ATAPI UDMA mode to UDMA4 */ | ||
242 | if (adev->class == ATA_DEV_ATAPI && speed > XFER_UDMA_4) { | ||
243 | printk(KERN_INFO "%s: limit ATAPI UDMA to UDMA4\n", DRV_NAME); | ||
244 | speed = XFER_UDMA_4; | ||
245 | } | ||
246 | |||
247 | if (speed >= XFER_UDMA_0) | 241 | if (speed >= XFER_UDMA_0) |
248 | idx = speed - XFER_UDMA_0; | 242 | idx = speed - XFER_UDMA_0; |
249 | else | 243 | else |
@@ -264,6 +258,17 @@ static void scc_set_dmamode (struct ata_port *ap, struct ata_device *adev) | |||
264 | JCTSStbl[offset][idx] << 16 | JCENVTtbl[offset][idx]); | 258 | JCTSStbl[offset][idx] << 16 | JCENVTtbl[offset][idx]); |
265 | } | 259 | } |
266 | 260 | ||
261 | unsigned long scc_mode_filter(struct ata_device *adev, unsigned long mask) | ||
262 | { | ||
263 | /* errata A308 workaround: limit ATAPI UDMA mode to UDMA4 */ | ||
264 | if (adev->class == ATA_DEV_ATAPI && | ||
265 | (mask & (0xE0 << ATA_SHIFT_UDMA))) { | ||
266 | printk(KERN_INFO "%s: limit ATAPI UDMA to UDMA4\n", DRV_NAME); | ||
267 | mask &= ~(0xE0 << ATA_SHIFT_UDMA); | ||
268 | } | ||
269 | return ata_pci_default_filter(adev, mask); | ||
270 | } | ||
271 | |||
267 | /** | 272 | /** |
268 | * scc_tf_load - send taskfile registers to host controller | 273 | * scc_tf_load - send taskfile registers to host controller |
269 | * @ap: Port to which output is sent | 274 | * @ap: Port to which output is sent |
@@ -358,6 +363,8 @@ static void scc_tf_read (struct ata_port *ap, struct ata_taskfile *tf) | |||
358 | tf->hob_lbal = in_be32(ioaddr->lbal_addr); | 363 | tf->hob_lbal = in_be32(ioaddr->lbal_addr); |
359 | tf->hob_lbam = in_be32(ioaddr->lbam_addr); | 364 | tf->hob_lbam = in_be32(ioaddr->lbam_addr); |
360 | tf->hob_lbah = in_be32(ioaddr->lbah_addr); | 365 | tf->hob_lbah = in_be32(ioaddr->lbah_addr); |
366 | out_be32(ioaddr->ctl_addr, tf->ctl); | ||
367 | ap->last_ctl = tf->ctl; | ||
361 | } | 368 | } |
362 | } | 369 | } |
363 | 370 | ||
@@ -741,7 +748,7 @@ static u8 scc_bmdma_status (struct ata_port *ap) | |||
741 | return host_stat; | 748 | return host_stat; |
742 | 749 | ||
743 | /* errata A252,A308 workaround: Step4 */ | 750 | /* errata A252,A308 workaround: Step4 */ |
744 | if (ata_altstatus(ap) & ATA_ERR && int_status & INTSTS_INTRQ) | 751 | if ((ata_altstatus(ap) & ATA_ERR) && (int_status & INTSTS_INTRQ)) |
745 | return (host_stat | ATA_DMA_INTR); | 752 | return (host_stat | ATA_DMA_INTR); |
746 | 753 | ||
747 | /* errata A308 workaround Step5 */ | 754 | /* errata A308 workaround Step5 */ |
@@ -752,11 +759,11 @@ static u8 scc_bmdma_status (struct ata_port *ap) | |||
752 | if ((qc->tf.protocol == ATA_PROT_DMA && | 759 | if ((qc->tf.protocol == ATA_PROT_DMA && |
753 | qc->dev->xfer_mode > XFER_UDMA_4)) { | 760 | qc->dev->xfer_mode > XFER_UDMA_4)) { |
754 | if (!(int_status & INTSTS_ACTEINT)) { | 761 | if (!(int_status & INTSTS_ACTEINT)) { |
755 | printk(KERN_WARNING "ata%u: data lost occurred. (ACTEINT==0, retry:%d)\n", | 762 | printk(KERN_WARNING "ata%u: operation failed (transfer data loss)\n", |
756 | ap->print_id, retry); | 763 | ap->print_id); |
757 | host_stat |= ATA_DMA_ERR; | 764 | host_stat |= ATA_DMA_ERR; |
758 | if (retry++) | 765 | if (retry++) |
759 | ap->udma_mask >>= 1; | 766 | ap->udma_mask &= ~(1 << qc->dev->xfer_mode); |
760 | } else | 767 | } else |
761 | retry = 0; | 768 | retry = 0; |
762 | } | 769 | } |
@@ -1016,7 +1023,7 @@ static const struct ata_port_operations scc_pata_ops = { | |||
1016 | .port_disable = ata_port_disable, | 1023 | .port_disable = ata_port_disable, |
1017 | .set_piomode = scc_set_piomode, | 1024 | .set_piomode = scc_set_piomode, |
1018 | .set_dmamode = scc_set_dmamode, | 1025 | .set_dmamode = scc_set_dmamode, |
1019 | .mode_filter = ata_pci_default_filter, | 1026 | .mode_filter = scc_mode_filter, |
1020 | 1027 | ||
1021 | .tf_load = scc_tf_load, | 1028 | .tf_load = scc_tf_load, |
1022 | .tf_read = scc_tf_read, | 1029 | .tf_read = scc_tf_read, |
diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c index 3de183461c3c..a9c948d7604a 100644 --- a/drivers/ata/sata_inic162x.c +++ b/drivers/ata/sata_inic162x.c | |||
@@ -190,34 +190,34 @@ static void inic_reset_port(void __iomem *port_base) | |||
190 | writew(ctl, idma_ctl); | 190 | writew(ctl, idma_ctl); |
191 | } | 191 | } |
192 | 192 | ||
193 | static u32 inic_scr_read(struct ata_port *ap, unsigned sc_reg) | 193 | static int inic_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val) |
194 | { | 194 | { |
195 | void __iomem *scr_addr = ap->ioaddr.scr_addr; | 195 | void __iomem *scr_addr = ap->ioaddr.scr_addr; |
196 | void __iomem *addr; | 196 | void __iomem *addr; |
197 | u32 val; | ||
198 | 197 | ||
199 | if (unlikely(sc_reg >= ARRAY_SIZE(scr_map))) | 198 | if (unlikely(sc_reg >= ARRAY_SIZE(scr_map))) |
200 | return 0xffffffffU; | 199 | return -EINVAL; |
201 | 200 | ||
202 | addr = scr_addr + scr_map[sc_reg] * 4; | 201 | addr = scr_addr + scr_map[sc_reg] * 4; |
203 | val = readl(scr_addr + scr_map[sc_reg] * 4); | 202 | *val = readl(scr_addr + scr_map[sc_reg] * 4); |
204 | 203 | ||
205 | /* this controller has stuck DIAG.N, ignore it */ | 204 | /* this controller has stuck DIAG.N, ignore it */ |
206 | if (sc_reg == SCR_ERROR) | 205 | if (sc_reg == SCR_ERROR) |
207 | val &= ~SERR_PHYRDY_CHG; | 206 | *val &= ~SERR_PHYRDY_CHG; |
208 | return val; | 207 | return 0; |
209 | } | 208 | } |
210 | 209 | ||
211 | static void inic_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val) | 210 | static int inic_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val) |
212 | { | 211 | { |
213 | void __iomem *scr_addr = ap->ioaddr.scr_addr; | 212 | void __iomem *scr_addr = ap->ioaddr.scr_addr; |
214 | void __iomem *addr; | 213 | void __iomem *addr; |
215 | 214 | ||
216 | if (unlikely(sc_reg >= ARRAY_SIZE(scr_map))) | 215 | if (unlikely(sc_reg >= ARRAY_SIZE(scr_map))) |
217 | return; | 216 | return -EINVAL; |
218 | 217 | ||
219 | addr = scr_addr + scr_map[sc_reg] * 4; | 218 | addr = scr_addr + scr_map[sc_reg] * 4; |
220 | writel(val, scr_addr + scr_map[sc_reg] * 4); | 219 | writel(val, scr_addr + scr_map[sc_reg] * 4); |
220 | return 0; | ||
221 | } | 221 | } |
222 | 222 | ||
223 | /* | 223 | /* |
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index fb8a749423ca..8ec520885b95 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -35,8 +35,6 @@ | |||
35 | 35 | ||
36 | 6) Add port multiplier support (intermediate) | 36 | 6) Add port multiplier support (intermediate) |
37 | 37 | ||
38 | 7) Test and verify 3.0 Gbps support | ||
39 | |||
40 | 8) Develop a low-power-consumption strategy, and implement it. | 38 | 8) Develop a low-power-consumption strategy, and implement it. |
41 | 39 | ||
42 | 9) [Experiment, low priority] See if ATAPI can be supported using | 40 | 9) [Experiment, low priority] See if ATAPI can be supported using |
@@ -227,26 +225,26 @@ enum { | |||
227 | 225 | ||
228 | EDMA_ERR_IRQ_CAUSE_OFS = 0x8, | 226 | EDMA_ERR_IRQ_CAUSE_OFS = 0x8, |
229 | EDMA_ERR_IRQ_MASK_OFS = 0xc, | 227 | EDMA_ERR_IRQ_MASK_OFS = 0xc, |
230 | EDMA_ERR_D_PAR = (1 << 0), | 228 | EDMA_ERR_D_PAR = (1 << 0), /* UDMA data parity err */ |
231 | EDMA_ERR_PRD_PAR = (1 << 1), | 229 | EDMA_ERR_PRD_PAR = (1 << 1), /* UDMA PRD parity err */ |
232 | EDMA_ERR_DEV = (1 << 2), | 230 | EDMA_ERR_DEV = (1 << 2), /* device error */ |
233 | EDMA_ERR_DEV_DCON = (1 << 3), | 231 | EDMA_ERR_DEV_DCON = (1 << 3), /* device disconnect */ |
234 | EDMA_ERR_DEV_CON = (1 << 4), | 232 | EDMA_ERR_DEV_CON = (1 << 4), /* device connected */ |
235 | EDMA_ERR_SERR = (1 << 5), | 233 | EDMA_ERR_SERR = (1 << 5), /* SError bits [WBDST] raised */ |
236 | EDMA_ERR_SELF_DIS = (1 << 7), /* Gen II/IIE self-disable */ | 234 | EDMA_ERR_SELF_DIS = (1 << 7), /* Gen II/IIE self-disable */ |
237 | EDMA_ERR_SELF_DIS_5 = (1 << 8), /* Gen I self-disable */ | 235 | EDMA_ERR_SELF_DIS_5 = (1 << 8), /* Gen I self-disable */ |
238 | EDMA_ERR_BIST_ASYNC = (1 << 8), | 236 | EDMA_ERR_BIST_ASYNC = (1 << 8), /* BIST FIS or Async Notify */ |
239 | EDMA_ERR_TRANS_IRQ_7 = (1 << 8), /* Gen IIE transprt layer irq */ | 237 | EDMA_ERR_TRANS_IRQ_7 = (1 << 8), /* Gen IIE transprt layer irq */ |
240 | EDMA_ERR_CRBQ_PAR = (1 << 9), | 238 | EDMA_ERR_CRQB_PAR = (1 << 9), /* CRQB parity error */ |
241 | EDMA_ERR_CRPB_PAR = (1 << 10), | 239 | EDMA_ERR_CRPB_PAR = (1 << 10), /* CRPB parity error */ |
242 | EDMA_ERR_INTRL_PAR = (1 << 11), | 240 | EDMA_ERR_INTRL_PAR = (1 << 11), /* internal parity error */ |
243 | EDMA_ERR_IORDY = (1 << 12), | 241 | EDMA_ERR_IORDY = (1 << 12), /* IORdy timeout */ |
244 | EDMA_ERR_LNK_CTRL_RX = (0xf << 13), | 242 | EDMA_ERR_LNK_CTRL_RX = (0xf << 13), /* link ctrl rx error */ |
245 | EDMA_ERR_LNK_CTRL_RX_2 = (1 << 15), | 243 | EDMA_ERR_LNK_CTRL_RX_2 = (1 << 15), |
246 | EDMA_ERR_LNK_DATA_RX = (0xf << 17), | 244 | EDMA_ERR_LNK_DATA_RX = (0xf << 17), /* link data rx error */ |
247 | EDMA_ERR_LNK_CTRL_TX = (0x1f << 21), | 245 | EDMA_ERR_LNK_CTRL_TX = (0x1f << 21), /* link ctrl tx error */ |
248 | EDMA_ERR_LNK_DATA_TX = (0x1f << 26), | 246 | EDMA_ERR_LNK_DATA_TX = (0x1f << 26), /* link data tx error */ |
249 | EDMA_ERR_TRANS_PROTO = (1 << 31), | 247 | EDMA_ERR_TRANS_PROTO = (1 << 31), /* transport protocol error */ |
250 | EDMA_ERR_OVERRUN_5 = (1 << 5), | 248 | EDMA_ERR_OVERRUN_5 = (1 << 5), |
251 | EDMA_ERR_UNDERRUN_5 = (1 << 6), | 249 | EDMA_ERR_UNDERRUN_5 = (1 << 6), |
252 | EDMA_EH_FREEZE = EDMA_ERR_D_PAR | | 250 | EDMA_EH_FREEZE = EDMA_ERR_D_PAR | |
@@ -255,7 +253,7 @@ enum { | |||
255 | EDMA_ERR_DEV_CON | | 253 | EDMA_ERR_DEV_CON | |
256 | EDMA_ERR_SERR | | 254 | EDMA_ERR_SERR | |
257 | EDMA_ERR_SELF_DIS | | 255 | EDMA_ERR_SELF_DIS | |
258 | EDMA_ERR_CRBQ_PAR | | 256 | EDMA_ERR_CRQB_PAR | |
259 | EDMA_ERR_CRPB_PAR | | 257 | EDMA_ERR_CRPB_PAR | |
260 | EDMA_ERR_INTRL_PAR | | 258 | EDMA_ERR_INTRL_PAR | |
261 | EDMA_ERR_IORDY | | 259 | EDMA_ERR_IORDY | |
@@ -270,7 +268,7 @@ enum { | |||
270 | EDMA_ERR_OVERRUN_5 | | 268 | EDMA_ERR_OVERRUN_5 | |
271 | EDMA_ERR_UNDERRUN_5 | | 269 | EDMA_ERR_UNDERRUN_5 | |
272 | EDMA_ERR_SELF_DIS_5 | | 270 | EDMA_ERR_SELF_DIS_5 | |
273 | EDMA_ERR_CRBQ_PAR | | 271 | EDMA_ERR_CRQB_PAR | |
274 | EDMA_ERR_CRPB_PAR | | 272 | EDMA_ERR_CRPB_PAR | |
275 | EDMA_ERR_INTRL_PAR | | 273 | EDMA_ERR_INTRL_PAR | |
276 | EDMA_ERR_IORDY, | 274 | EDMA_ERR_IORDY, |
@@ -286,10 +284,10 @@ enum { | |||
286 | EDMA_RSP_Q_OUT_PTR_OFS = 0x24, /* also contains BASE_LO */ | 284 | EDMA_RSP_Q_OUT_PTR_OFS = 0x24, /* also contains BASE_LO */ |
287 | EDMA_RSP_Q_PTR_SHIFT = 3, | 285 | EDMA_RSP_Q_PTR_SHIFT = 3, |
288 | 286 | ||
289 | EDMA_CMD_OFS = 0x28, | 287 | EDMA_CMD_OFS = 0x28, /* EDMA command register */ |
290 | EDMA_EN = (1 << 0), | 288 | EDMA_EN = (1 << 0), /* enable EDMA */ |
291 | EDMA_DS = (1 << 1), | 289 | EDMA_DS = (1 << 1), /* disable EDMA; self-negated */ |
292 | ATA_RST = (1 << 2), | 290 | ATA_RST = (1 << 2), /* reset trans/link/phy */ |
293 | 291 | ||
294 | EDMA_IORDY_TMOUT = 0x34, | 292 | EDMA_IORDY_TMOUT = 0x34, |
295 | EDMA_ARB_CFG = 0x38, | 293 | EDMA_ARB_CFG = 0x38, |
@@ -301,14 +299,13 @@ enum { | |||
301 | MV_HP_ERRATA_60X1B2 = (1 << 3), | 299 | MV_HP_ERRATA_60X1B2 = (1 << 3), |
302 | MV_HP_ERRATA_60X1C0 = (1 << 4), | 300 | MV_HP_ERRATA_60X1C0 = (1 << 4), |
303 | MV_HP_ERRATA_XX42A0 = (1 << 5), | 301 | MV_HP_ERRATA_XX42A0 = (1 << 5), |
304 | MV_HP_GEN_I = (1 << 6), | 302 | MV_HP_GEN_I = (1 << 6), /* Generation I: 50xx */ |
305 | MV_HP_GEN_II = (1 << 7), | 303 | MV_HP_GEN_II = (1 << 7), /* Generation II: 60xx */ |
306 | MV_HP_GEN_IIE = (1 << 8), | 304 | MV_HP_GEN_IIE = (1 << 8), /* Generation IIE: 6042/7042 */ |
307 | 305 | ||
308 | /* Port private flags (pp_flags) */ | 306 | /* Port private flags (pp_flags) */ |
309 | MV_PP_FLAG_EDMA_EN = (1 << 0), | 307 | MV_PP_FLAG_EDMA_EN = (1 << 0), /* is EDMA engine enabled? */ |
310 | MV_PP_FLAG_EDMA_DS_ACT = (1 << 1), | 308 | MV_PP_FLAG_HAD_A_RESET = (1 << 2), /* 1st hard reset complete? */ |
311 | MV_PP_FLAG_HAD_A_RESET = (1 << 2), | ||
312 | }; | 309 | }; |
313 | 310 | ||
314 | #define IS_GEN_I(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_I) | 311 | #define IS_GEN_I(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_I) |
@@ -318,8 +315,12 @@ enum { | |||
318 | enum { | 315 | enum { |
319 | MV_DMA_BOUNDARY = 0xffffffffU, | 316 | MV_DMA_BOUNDARY = 0xffffffffU, |
320 | 317 | ||
318 | /* mask of register bits containing lower 32 bits | ||
319 | * of EDMA request queue DMA address | ||
320 | */ | ||
321 | EDMA_REQ_Q_BASE_LO_MASK = 0xfffffc00U, | 321 | EDMA_REQ_Q_BASE_LO_MASK = 0xfffffc00U, |
322 | 322 | ||
323 | /* ditto, for response queue */ | ||
323 | EDMA_RSP_Q_BASE_LO_MASK = 0xffffff00U, | 324 | EDMA_RSP_Q_BASE_LO_MASK = 0xffffff00U, |
324 | }; | 325 | }; |
325 | 326 | ||
@@ -403,10 +404,10 @@ struct mv_host_priv { | |||
403 | }; | 404 | }; |
404 | 405 | ||
405 | static void mv_irq_clear(struct ata_port *ap); | 406 | static void mv_irq_clear(struct ata_port *ap); |
406 | static u32 mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in); | 407 | static int mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val); |
407 | static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val); | 408 | static int mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val); |
408 | static u32 mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in); | 409 | static int mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val); |
409 | static void mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val); | 410 | static int mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val); |
410 | static int mv_port_start(struct ata_port *ap); | 411 | static int mv_port_start(struct ata_port *ap); |
411 | static void mv_port_stop(struct ata_port *ap); | 412 | static void mv_port_stop(struct ata_port *ap); |
412 | static void mv_qc_prep(struct ata_queued_cmd *qc); | 413 | static void mv_qc_prep(struct ata_queued_cmd *qc); |
@@ -823,7 +824,7 @@ static void mv_start_dma(void __iomem *base, struct mv_host_priv *hpriv, | |||
823 | } | 824 | } |
824 | 825 | ||
825 | /** | 826 | /** |
826 | * mv_stop_dma - Disable eDMA engine | 827 | * __mv_stop_dma - Disable eDMA engine |
827 | * @ap: ATA channel to manipulate | 828 | * @ap: ATA channel to manipulate |
828 | * | 829 | * |
829 | * Verify the local cache of the eDMA state is accurate with a | 830 | * Verify the local cache of the eDMA state is accurate with a |
@@ -832,7 +833,7 @@ static void mv_start_dma(void __iomem *base, struct mv_host_priv *hpriv, | |||
832 | * LOCKING: | 833 | * LOCKING: |
833 | * Inherited from caller. | 834 | * Inherited from caller. |
834 | */ | 835 | */ |
835 | static int mv_stop_dma(struct ata_port *ap) | 836 | static int __mv_stop_dma(struct ata_port *ap) |
836 | { | 837 | { |
837 | void __iomem *port_mmio = mv_ap_base(ap); | 838 | void __iomem *port_mmio = mv_ap_base(ap); |
838 | struct mv_port_priv *pp = ap->private_data; | 839 | struct mv_port_priv *pp = ap->private_data; |
@@ -865,6 +866,18 @@ static int mv_stop_dma(struct ata_port *ap) | |||
865 | return err; | 866 | return err; |
866 | } | 867 | } |
867 | 868 | ||
869 | static int mv_stop_dma(struct ata_port *ap) | ||
870 | { | ||
871 | unsigned long flags; | ||
872 | int rc; | ||
873 | |||
874 | spin_lock_irqsave(&ap->host->lock, flags); | ||
875 | rc = __mv_stop_dma(ap); | ||
876 | spin_unlock_irqrestore(&ap->host->lock, flags); | ||
877 | |||
878 | return rc; | ||
879 | } | ||
880 | |||
868 | #ifdef ATA_DEBUG | 881 | #ifdef ATA_DEBUG |
869 | static void mv_dump_mem(void __iomem *start, unsigned bytes) | 882 | static void mv_dump_mem(void __iomem *start, unsigned bytes) |
870 | { | 883 | { |
@@ -961,22 +974,26 @@ static unsigned int mv_scr_offset(unsigned int sc_reg_in) | |||
961 | return ofs; | 974 | return ofs; |
962 | } | 975 | } |
963 | 976 | ||
964 | static u32 mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in) | 977 | static int mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val) |
965 | { | 978 | { |
966 | unsigned int ofs = mv_scr_offset(sc_reg_in); | 979 | unsigned int ofs = mv_scr_offset(sc_reg_in); |
967 | 980 | ||
968 | if (0xffffffffU != ofs) | 981 | if (ofs != 0xffffffffU) { |
969 | return readl(mv_ap_base(ap) + ofs); | 982 | *val = readl(mv_ap_base(ap) + ofs); |
970 | else | 983 | return 0; |
971 | return (u32) ofs; | 984 | } else |
985 | return -EINVAL; | ||
972 | } | 986 | } |
973 | 987 | ||
974 | static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val) | 988 | static int mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val) |
975 | { | 989 | { |
976 | unsigned int ofs = mv_scr_offset(sc_reg_in); | 990 | unsigned int ofs = mv_scr_offset(sc_reg_in); |
977 | 991 | ||
978 | if (0xffffffffU != ofs) | 992 | if (ofs != 0xffffffffU) { |
979 | writelfl(val, mv_ap_base(ap) + ofs); | 993 | writelfl(val, mv_ap_base(ap) + ofs); |
994 | return 0; | ||
995 | } else | ||
996 | return -EINVAL; | ||
980 | } | 997 | } |
981 | 998 | ||
982 | static void mv_edma_cfg(struct ata_port *ap, struct mv_host_priv *hpriv, | 999 | static void mv_edma_cfg(struct ata_port *ap, struct mv_host_priv *hpriv, |
@@ -1029,6 +1046,7 @@ static int mv_port_start(struct ata_port *ap) | |||
1029 | void __iomem *port_mmio = mv_ap_base(ap); | 1046 | void __iomem *port_mmio = mv_ap_base(ap); |
1030 | void *mem; | 1047 | void *mem; |
1031 | dma_addr_t mem_dma; | 1048 | dma_addr_t mem_dma; |
1049 | unsigned long flags; | ||
1032 | int rc; | 1050 | int rc; |
1033 | 1051 | ||
1034 | pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL); | 1052 | pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL); |
@@ -1067,10 +1085,14 @@ static int mv_port_start(struct ata_port *ap) | |||
1067 | pp->sg_tbl = mem; | 1085 | pp->sg_tbl = mem; |
1068 | pp->sg_tbl_dma = mem_dma; | 1086 | pp->sg_tbl_dma = mem_dma; |
1069 | 1087 | ||
1088 | spin_lock_irqsave(&ap->host->lock, flags); | ||
1089 | |||
1070 | mv_edma_cfg(ap, hpriv, port_mmio); | 1090 | mv_edma_cfg(ap, hpriv, port_mmio); |
1071 | 1091 | ||
1072 | mv_set_edma_ptrs(port_mmio, hpriv, pp); | 1092 | mv_set_edma_ptrs(port_mmio, hpriv, pp); |
1073 | 1093 | ||
1094 | spin_unlock_irqrestore(&ap->host->lock, flags); | ||
1095 | |||
1074 | /* Don't turn on EDMA here...do it before DMA commands only. Else | 1096 | /* Don't turn on EDMA here...do it before DMA commands only. Else |
1075 | * we'll be unable to send non-data, PIO, etc due to restricted access | 1097 | * we'll be unable to send non-data, PIO, etc due to restricted access |
1076 | * to shadow regs. | 1098 | * to shadow regs. |
@@ -1090,11 +1112,7 @@ static int mv_port_start(struct ata_port *ap) | |||
1090 | */ | 1112 | */ |
1091 | static void mv_port_stop(struct ata_port *ap) | 1113 | static void mv_port_stop(struct ata_port *ap) |
1092 | { | 1114 | { |
1093 | unsigned long flags; | ||
1094 | |||
1095 | spin_lock_irqsave(&ap->host->lock, flags); | ||
1096 | mv_stop_dma(ap); | 1115 | mv_stop_dma(ap); |
1097 | spin_unlock_irqrestore(&ap->host->lock, flags); | ||
1098 | } | 1116 | } |
1099 | 1117 | ||
1100 | /** | 1118 | /** |
@@ -1325,7 +1343,7 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) | |||
1325 | * port. Turn off EDMA so there won't be problems accessing | 1343 | * port. Turn off EDMA so there won't be problems accessing |
1326 | * shadow block, etc registers. | 1344 | * shadow block, etc registers. |
1327 | */ | 1345 | */ |
1328 | mv_stop_dma(ap); | 1346 | __mv_stop_dma(ap); |
1329 | return ata_qc_issue_prot(qc); | 1347 | return ata_qc_issue_prot(qc); |
1330 | } | 1348 | } |
1331 | 1349 | ||
@@ -1393,16 +1411,16 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc) | |||
1393 | if (edma_err_cause & EDMA_ERR_DEV) | 1411 | if (edma_err_cause & EDMA_ERR_DEV) |
1394 | err_mask |= AC_ERR_DEV; | 1412 | err_mask |= AC_ERR_DEV; |
1395 | if (edma_err_cause & (EDMA_ERR_D_PAR | EDMA_ERR_PRD_PAR | | 1413 | if (edma_err_cause & (EDMA_ERR_D_PAR | EDMA_ERR_PRD_PAR | |
1396 | EDMA_ERR_CRBQ_PAR | EDMA_ERR_CRPB_PAR | | 1414 | EDMA_ERR_CRQB_PAR | EDMA_ERR_CRPB_PAR | |
1397 | EDMA_ERR_INTRL_PAR)) { | 1415 | EDMA_ERR_INTRL_PAR)) { |
1398 | err_mask |= AC_ERR_ATA_BUS; | 1416 | err_mask |= AC_ERR_ATA_BUS; |
1399 | action |= ATA_EH_HARDRESET; | 1417 | action |= ATA_EH_HARDRESET; |
1400 | ata_ehi_push_desc(ehi, ", parity error"); | 1418 | ata_ehi_push_desc(ehi, "parity error"); |
1401 | } | 1419 | } |
1402 | if (edma_err_cause & (EDMA_ERR_DEV_DCON | EDMA_ERR_DEV_CON)) { | 1420 | if (edma_err_cause & (EDMA_ERR_DEV_DCON | EDMA_ERR_DEV_CON)) { |
1403 | ata_ehi_hotplugged(ehi); | 1421 | ata_ehi_hotplugged(ehi); |
1404 | ata_ehi_push_desc(ehi, edma_err_cause & EDMA_ERR_DEV_DCON ? | 1422 | ata_ehi_push_desc(ehi, edma_err_cause & EDMA_ERR_DEV_DCON ? |
1405 | ", dev disconnect" : ", dev connect"); | 1423 | "dev disconnect" : "dev connect"); |
1406 | } | 1424 | } |
1407 | 1425 | ||
1408 | if (IS_GEN_I(hpriv)) { | 1426 | if (IS_GEN_I(hpriv)) { |
@@ -1411,7 +1429,7 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc) | |||
1411 | if (edma_err_cause & EDMA_ERR_SELF_DIS_5) { | 1429 | if (edma_err_cause & EDMA_ERR_SELF_DIS_5) { |
1412 | struct mv_port_priv *pp = ap->private_data; | 1430 | struct mv_port_priv *pp = ap->private_data; |
1413 | pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN; | 1431 | pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN; |
1414 | ata_ehi_push_desc(ehi, ", EDMA self-disable"); | 1432 | ata_ehi_push_desc(ehi, "EDMA self-disable"); |
1415 | } | 1433 | } |
1416 | } else { | 1434 | } else { |
1417 | eh_freeze_mask = EDMA_EH_FREEZE; | 1435 | eh_freeze_mask = EDMA_EH_FREEZE; |
@@ -1419,7 +1437,7 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc) | |||
1419 | if (edma_err_cause & EDMA_ERR_SELF_DIS) { | 1437 | if (edma_err_cause & EDMA_ERR_SELF_DIS) { |
1420 | struct mv_port_priv *pp = ap->private_data; | 1438 | struct mv_port_priv *pp = ap->private_data; |
1421 | pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN; | 1439 | pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN; |
1422 | ata_ehi_push_desc(ehi, ", EDMA self-disable"); | 1440 | ata_ehi_push_desc(ehi, "EDMA self-disable"); |
1423 | } | 1441 | } |
1424 | 1442 | ||
1425 | if (edma_err_cause & EDMA_ERR_SERR) { | 1443 | if (edma_err_cause & EDMA_ERR_SERR) { |
@@ -1489,33 +1507,30 @@ static void mv_intr_edma(struct ata_port *ap) | |||
1489 | 1507 | ||
1490 | while (1) { | 1508 | while (1) { |
1491 | u16 status; | 1509 | u16 status; |
1510 | unsigned int tag; | ||
1492 | 1511 | ||
1493 | /* get s/w response queue last-read pointer, and compare */ | 1512 | /* get s/w response queue last-read pointer, and compare */ |
1494 | out_index = pp->resp_idx & MV_MAX_Q_DEPTH_MASK; | 1513 | out_index = pp->resp_idx & MV_MAX_Q_DEPTH_MASK; |
1495 | if (in_index == out_index) | 1514 | if (in_index == out_index) |
1496 | break; | 1515 | break; |
1497 | 1516 | ||
1498 | |||
1499 | /* 50xx: get active ATA command */ | 1517 | /* 50xx: get active ATA command */ |
1500 | if (IS_GEN_I(hpriv)) | 1518 | if (IS_GEN_I(hpriv)) |
1501 | qc = ata_qc_from_tag(ap, ap->active_tag); | 1519 | tag = ap->active_tag; |
1502 | 1520 | ||
1503 | /* 60xx: get active ATA command via tag, to enable support | 1521 | /* Gen II/IIE: get active ATA command via tag, to enable |
1504 | * for queueing. this works transparently for queued and | 1522 | * support for queueing. this works transparently for |
1505 | * non-queued modes. | 1523 | * queued and non-queued modes. |
1506 | */ | 1524 | */ |
1507 | else { | 1525 | else if (IS_GEN_II(hpriv)) |
1508 | unsigned int tag; | 1526 | tag = (le16_to_cpu(pp->crpb[out_index].id) |
1527 | >> CRPB_IOID_SHIFT_6) & 0x3f; | ||
1509 | 1528 | ||
1510 | if (IS_GEN_II(hpriv)) | 1529 | else /* IS_GEN_IIE */ |
1511 | tag = (le16_to_cpu(pp->crpb[out_index].id) | 1530 | tag = (le16_to_cpu(pp->crpb[out_index].id) |
1512 | >> CRPB_IOID_SHIFT_6) & 0x3f; | 1531 | >> CRPB_IOID_SHIFT_7) & 0x3f; |
1513 | else | ||
1514 | tag = (le16_to_cpu(pp->crpb[out_index].id) | ||
1515 | >> CRPB_IOID_SHIFT_7) & 0x3f; | ||
1516 | 1532 | ||
1517 | qc = ata_qc_from_tag(ap, tag); | 1533 | qc = ata_qc_from_tag(ap, tag); |
1518 | } | ||
1519 | 1534 | ||
1520 | /* lower 8 bits of status are EDMA_ERR_IRQ_CAUSE_OFS | 1535 | /* lower 8 bits of status are EDMA_ERR_IRQ_CAUSE_OFS |
1521 | * bits (WARNING: might not necessarily be associated | 1536 | * bits (WARNING: might not necessarily be associated |
@@ -1535,7 +1550,7 @@ static void mv_intr_edma(struct ata_port *ap) | |||
1535 | ata_qc_complete(qc); | 1550 | ata_qc_complete(qc); |
1536 | } | 1551 | } |
1537 | 1552 | ||
1538 | /* advance software response queue pointer, to | 1553 | /* advance software response queue pointer, to |
1539 | * indicate (after the loop completes) to hardware | 1554 | * indicate (after the loop completes) to hardware |
1540 | * that we have consumed a response queue entry. | 1555 | * that we have consumed a response queue entry. |
1541 | */ | 1556 | */ |
@@ -1741,26 +1756,30 @@ static unsigned int mv5_scr_offset(unsigned int sc_reg_in) | |||
1741 | return ofs; | 1756 | return ofs; |
1742 | } | 1757 | } |
1743 | 1758 | ||
1744 | static u32 mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in) | 1759 | static int mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val) |
1745 | { | 1760 | { |
1746 | void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR]; | 1761 | void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR]; |
1747 | void __iomem *addr = mv5_phy_base(mmio, ap->port_no); | 1762 | void __iomem *addr = mv5_phy_base(mmio, ap->port_no); |
1748 | unsigned int ofs = mv5_scr_offset(sc_reg_in); | 1763 | unsigned int ofs = mv5_scr_offset(sc_reg_in); |
1749 | 1764 | ||
1750 | if (ofs != 0xffffffffU) | 1765 | if (ofs != 0xffffffffU) { |
1751 | return readl(addr + ofs); | 1766 | *val = readl(addr + ofs); |
1752 | else | 1767 | return 0; |
1753 | return (u32) ofs; | 1768 | } else |
1769 | return -EINVAL; | ||
1754 | } | 1770 | } |
1755 | 1771 | ||
1756 | static void mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val) | 1772 | static int mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val) |
1757 | { | 1773 | { |
1758 | void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR]; | 1774 | void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR]; |
1759 | void __iomem *addr = mv5_phy_base(mmio, ap->port_no); | 1775 | void __iomem *addr = mv5_phy_base(mmio, ap->port_no); |
1760 | unsigned int ofs = mv5_scr_offset(sc_reg_in); | 1776 | unsigned int ofs = mv5_scr_offset(sc_reg_in); |
1761 | 1777 | ||
1762 | if (ofs != 0xffffffffU) | 1778 | if (ofs != 0xffffffffU) { |
1763 | writelfl(val, addr + ofs); | 1779 | writelfl(val, addr + ofs); |
1780 | return 0; | ||
1781 | } else | ||
1782 | return -EINVAL; | ||
1764 | } | 1783 | } |
1765 | 1784 | ||
1766 | static void mv5_reset_bus(struct pci_dev *pdev, void __iomem *mmio) | 1785 | static void mv5_reset_bus(struct pci_dev *pdev, void __iomem *mmio) |
@@ -2138,9 +2157,17 @@ static void mv_phy_reset(struct ata_port *ap, unsigned int *class, | |||
2138 | 2157 | ||
2139 | VPRINTK("ENTER, port %u, mmio 0x%p\n", ap->port_no, port_mmio); | 2158 | VPRINTK("ENTER, port %u, mmio 0x%p\n", ap->port_no, port_mmio); |
2140 | 2159 | ||
2141 | DPRINTK("S-regs after ATA_RST: SStat 0x%08x SErr 0x%08x " | 2160 | #ifdef DEBUG |
2142 | "SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS), | 2161 | { |
2143 | mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL)); | 2162 | u32 sstatus, serror, scontrol; |
2163 | |||
2164 | mv_scr_read(ap, SCR_STATUS, &sstatus); | ||
2165 | mv_scr_read(ap, SCR_ERROR, &serror); | ||
2166 | mv_scr_read(ap, SCR_CONTROL, &scontrol); | ||
2167 | DPRINTK("S-regs after ATA_RST: SStat 0x%08x SErr 0x%08x " | ||
2168 | "SCtrl 0x%08x\n", status, serror, scontrol); | ||
2169 | } | ||
2170 | #endif | ||
2144 | 2171 | ||
2145 | /* Issue COMRESET via SControl */ | 2172 | /* Issue COMRESET via SControl */ |
2146 | comreset_retry: | 2173 | comreset_retry: |
@@ -2164,9 +2191,17 @@ comreset_retry: | |||
2164 | (retry-- > 0)) | 2191 | (retry-- > 0)) |
2165 | goto comreset_retry; | 2192 | goto comreset_retry; |
2166 | 2193 | ||
2167 | DPRINTK("S-regs after PHY wake: SStat 0x%08x SErr 0x%08x " | 2194 | #ifdef DEBUG |
2168 | "SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS), | 2195 | { |
2169 | mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL)); | 2196 | u32 sstatus, serror, scontrol; |
2197 | |||
2198 | mv_scr_read(ap, SCR_STATUS, &sstatus); | ||
2199 | mv_scr_read(ap, SCR_ERROR, &serror); | ||
2200 | mv_scr_read(ap, SCR_CONTROL, &scontrol); | ||
2201 | DPRINTK("S-regs after PHY wake: SStat 0x%08x SErr 0x%08x " | ||
2202 | "SCtrl 0x%08x\n", sstatus, serror, scontrol); | ||
2203 | } | ||
2204 | #endif | ||
2170 | 2205 | ||
2171 | if (ata_port_offline(ap)) { | 2206 | if (ata_port_offline(ap)) { |
2172 | *class = ATA_DEV_NONE; | 2207 | *class = ATA_DEV_NONE; |
@@ -2209,7 +2244,7 @@ static int mv_prereset(struct ata_port *ap, unsigned long deadline) | |||
2209 | struct mv_port_priv *pp = ap->private_data; | 2244 | struct mv_port_priv *pp = ap->private_data; |
2210 | struct ata_eh_context *ehc = &ap->eh_context; | 2245 | struct ata_eh_context *ehc = &ap->eh_context; |
2211 | int rc; | 2246 | int rc; |
2212 | 2247 | ||
2213 | rc = mv_stop_dma(ap); | 2248 | rc = mv_stop_dma(ap); |
2214 | if (rc) | 2249 | if (rc) |
2215 | ehc->i.action |= ATA_EH_HARDRESET; | 2250 | ehc->i.action |= ATA_EH_HARDRESET; |
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index db81e3efa5ec..0b58c4df6fd2 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c | |||
@@ -236,8 +236,8 @@ static void nv_ck804_host_stop(struct ata_host *host); | |||
236 | static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance); | 236 | static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance); |
237 | static irqreturn_t nv_nf2_interrupt(int irq, void *dev_instance); | 237 | static irqreturn_t nv_nf2_interrupt(int irq, void *dev_instance); |
238 | static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance); | 238 | static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance); |
239 | static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg); | 239 | static int nv_scr_read (struct ata_port *ap, unsigned int sc_reg, u32 *val); |
240 | static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); | 240 | static int nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); |
241 | 241 | ||
242 | static void nv_nf2_freeze(struct ata_port *ap); | 242 | static void nv_nf2_freeze(struct ata_port *ap); |
243 | static void nv_nf2_thaw(struct ata_port *ap); | 243 | static void nv_nf2_thaw(struct ata_port *ap); |
@@ -715,19 +715,20 @@ static int nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err) | |||
715 | int freeze = 0; | 715 | int freeze = 0; |
716 | 716 | ||
717 | ata_ehi_clear_desc(ehi); | 717 | ata_ehi_clear_desc(ehi); |
718 | ata_ehi_push_desc(ehi, "CPB resp_flags 0x%x", flags ); | 718 | __ata_ehi_push_desc(ehi, "CPB resp_flags 0x%x: ", flags ); |
719 | if (flags & NV_CPB_RESP_ATA_ERR) { | 719 | if (flags & NV_CPB_RESP_ATA_ERR) { |
720 | ata_ehi_push_desc(ehi, ": ATA error"); | 720 | ata_ehi_push_desc(ehi, "ATA error"); |
721 | ehi->err_mask |= AC_ERR_DEV; | 721 | ehi->err_mask |= AC_ERR_DEV; |
722 | } else if (flags & NV_CPB_RESP_CMD_ERR) { | 722 | } else if (flags & NV_CPB_RESP_CMD_ERR) { |
723 | ata_ehi_push_desc(ehi, ": CMD error"); | 723 | ata_ehi_push_desc(ehi, "CMD error"); |
724 | ehi->err_mask |= AC_ERR_DEV; | 724 | ehi->err_mask |= AC_ERR_DEV; |
725 | } else if (flags & NV_CPB_RESP_CPB_ERR) { | 725 | } else if (flags & NV_CPB_RESP_CPB_ERR) { |
726 | ata_ehi_push_desc(ehi, ": CPB error"); | 726 | ata_ehi_push_desc(ehi, "CPB error"); |
727 | ehi->err_mask |= AC_ERR_SYSTEM; | 727 | ehi->err_mask |= AC_ERR_SYSTEM; |
728 | freeze = 1; | 728 | freeze = 1; |
729 | } else { | 729 | } else { |
730 | /* notifier error, but no error in CPB flags? */ | 730 | /* notifier error, but no error in CPB flags? */ |
731 | ata_ehi_push_desc(ehi, "unknown"); | ||
731 | ehi->err_mask |= AC_ERR_OTHER; | 732 | ehi->err_mask |= AC_ERR_OTHER; |
732 | freeze = 1; | 733 | freeze = 1; |
733 | } | 734 | } |
@@ -854,20 +855,21 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance) | |||
854 | struct ata_eh_info *ehi = &ap->eh_info; | 855 | struct ata_eh_info *ehi = &ap->eh_info; |
855 | 856 | ||
856 | ata_ehi_clear_desc(ehi); | 857 | ata_ehi_clear_desc(ehi); |
857 | ata_ehi_push_desc(ehi, "ADMA status 0x%08x", status ); | 858 | __ata_ehi_push_desc(ehi, "ADMA status 0x%08x: ", status ); |
858 | if (status & NV_ADMA_STAT_TIMEOUT) { | 859 | if (status & NV_ADMA_STAT_TIMEOUT) { |
859 | ehi->err_mask |= AC_ERR_SYSTEM; | 860 | ehi->err_mask |= AC_ERR_SYSTEM; |
860 | ata_ehi_push_desc(ehi, ": timeout"); | 861 | ata_ehi_push_desc(ehi, "timeout"); |
861 | } else if (status & NV_ADMA_STAT_HOTPLUG) { | 862 | } else if (status & NV_ADMA_STAT_HOTPLUG) { |
862 | ata_ehi_hotplugged(ehi); | 863 | ata_ehi_hotplugged(ehi); |
863 | ata_ehi_push_desc(ehi, ": hotplug"); | 864 | ata_ehi_push_desc(ehi, "hotplug"); |
864 | } else if (status & NV_ADMA_STAT_HOTUNPLUG) { | 865 | } else if (status & NV_ADMA_STAT_HOTUNPLUG) { |
865 | ata_ehi_hotplugged(ehi); | 866 | ata_ehi_hotplugged(ehi); |
866 | ata_ehi_push_desc(ehi, ": hot unplug"); | 867 | ata_ehi_push_desc(ehi, "hot unplug"); |
867 | } else if (status & NV_ADMA_STAT_SERROR) { | 868 | } else if (status & NV_ADMA_STAT_SERROR) { |
868 | /* let libata analyze SError and figure out the cause */ | 869 | /* let libata analyze SError and figure out the cause */ |
869 | ata_ehi_push_desc(ehi, ": SError"); | 870 | ata_ehi_push_desc(ehi, "SError"); |
870 | } | 871 | } else |
872 | ata_ehi_push_desc(ehi, "unknown"); | ||
871 | ata_port_freeze(ap); | 873 | ata_port_freeze(ap); |
872 | continue; | 874 | continue; |
873 | } | 875 | } |
@@ -1391,20 +1393,22 @@ static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance) | |||
1391 | return ret; | 1393 | return ret; |
1392 | } | 1394 | } |
1393 | 1395 | ||
1394 | static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg) | 1396 | static int nv_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) |
1395 | { | 1397 | { |
1396 | if (sc_reg > SCR_CONTROL) | 1398 | if (sc_reg > SCR_CONTROL) |
1397 | return 0xffffffffU; | 1399 | return -EINVAL; |
1398 | 1400 | ||
1399 | return ioread32(ap->ioaddr.scr_addr + (sc_reg * 4)); | 1401 | *val = ioread32(ap->ioaddr.scr_addr + (sc_reg * 4)); |
1402 | return 0; | ||
1400 | } | 1403 | } |
1401 | 1404 | ||
1402 | static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) | 1405 | static int nv_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) |
1403 | { | 1406 | { |
1404 | if (sc_reg > SCR_CONTROL) | 1407 | if (sc_reg > SCR_CONTROL) |
1405 | return; | 1408 | return -EINVAL; |
1406 | 1409 | ||
1407 | iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4)); | 1410 | iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4)); |
1411 | return 0; | ||
1408 | } | 1412 | } |
1409 | 1413 | ||
1410 | static void nv_nf2_freeze(struct ata_port *ap) | 1414 | static void nv_nf2_freeze(struct ata_port *ap) |
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index d2fcb9a6bec2..d39ebc23c4a9 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c | |||
@@ -128,8 +128,8 @@ struct pdc_port_priv { | |||
128 | dma_addr_t pkt_dma; | 128 | dma_addr_t pkt_dma; |
129 | }; | 129 | }; |
130 | 130 | ||
131 | static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg); | 131 | static int pdc_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); |
132 | static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); | 132 | static int pdc_sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); |
133 | static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); | 133 | static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); |
134 | static int pdc_common_port_start(struct ata_port *ap); | 134 | static int pdc_common_port_start(struct ata_port *ap); |
135 | static int pdc_sata_port_start(struct ata_port *ap); | 135 | static int pdc_sata_port_start(struct ata_port *ap); |
@@ -427,19 +427,20 @@ static int pdc_sata_cable_detect(struct ata_port *ap) | |||
427 | return ATA_CBL_SATA; | 427 | return ATA_CBL_SATA; |
428 | } | 428 | } |
429 | 429 | ||
430 | static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) | 430 | static int pdc_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) |
431 | { | 431 | { |
432 | if (sc_reg > SCR_CONTROL) | 432 | if (sc_reg > SCR_CONTROL) |
433 | return 0xffffffffU; | 433 | return -EINVAL; |
434 | return readl(ap->ioaddr.scr_addr + (sc_reg * 4)); | 434 | *val = readl(ap->ioaddr.scr_addr + (sc_reg * 4)); |
435 | return 0; | ||
435 | } | 436 | } |
436 | 437 | ||
437 | static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, | 438 | static int pdc_sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) |
438 | u32 val) | ||
439 | { | 439 | { |
440 | if (sc_reg > SCR_CONTROL) | 440 | if (sc_reg > SCR_CONTROL) |
441 | return; | 441 | return -EINVAL; |
442 | writel(val, ap->ioaddr.scr_addr + (sc_reg * 4)); | 442 | writel(val, ap->ioaddr.scr_addr + (sc_reg * 4)); |
443 | return 0; | ||
443 | } | 444 | } |
444 | 445 | ||
445 | static void pdc_atapi_pkt(struct ata_queued_cmd *qc) | 446 | static void pdc_atapi_pkt(struct ata_queued_cmd *qc) |
@@ -642,8 +643,12 @@ static void pdc_error_intr(struct ata_port *ap, struct ata_queued_cmd *qc, | |||
642 | | PDC_PCI_SYS_ERR | PDC1_PCI_PARITY_ERR)) | 643 | | PDC_PCI_SYS_ERR | PDC1_PCI_PARITY_ERR)) |
643 | ac_err_mask |= AC_ERR_HOST_BUS; | 644 | ac_err_mask |= AC_ERR_HOST_BUS; |
644 | 645 | ||
645 | if (sata_scr_valid(ap)) | 646 | if (sata_scr_valid(ap)) { |
646 | ehi->serror |= pdc_sata_scr_read(ap, SCR_ERROR); | 647 | u32 serror; |
648 | |||
649 | pdc_sata_scr_read(ap, SCR_ERROR, &serror); | ||
650 | ehi->serror |= serror; | ||
651 | } | ||
647 | 652 | ||
648 | qc->err_mask |= ac_err_mask; | 653 | qc->err_mask |= ac_err_mask; |
649 | 654 | ||
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c index 9ab554da89bf..c8f9242e7f44 100644 --- a/drivers/ata/sata_qstor.c +++ b/drivers/ata/sata_qstor.c | |||
@@ -111,8 +111,8 @@ struct qs_port_priv { | |||
111 | qs_state_t state; | 111 | qs_state_t state; |
112 | }; | 112 | }; |
113 | 113 | ||
114 | static u32 qs_scr_read (struct ata_port *ap, unsigned int sc_reg); | 114 | static int qs_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); |
115 | static void qs_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); | 115 | static int qs_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); |
116 | static int qs_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); | 116 | static int qs_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); |
117 | static int qs_port_start(struct ata_port *ap); | 117 | static int qs_port_start(struct ata_port *ap); |
118 | static void qs_host_stop(struct ata_host *host); | 118 | static void qs_host_stop(struct ata_host *host); |
@@ -255,18 +255,20 @@ static void qs_eng_timeout(struct ata_port *ap) | |||
255 | ata_eng_timeout(ap); | 255 | ata_eng_timeout(ap); |
256 | } | 256 | } |
257 | 257 | ||
258 | static u32 qs_scr_read (struct ata_port *ap, unsigned int sc_reg) | 258 | static int qs_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) |
259 | { | 259 | { |
260 | if (sc_reg > SCR_CONTROL) | 260 | if (sc_reg > SCR_CONTROL) |
261 | return ~0U; | 261 | return -EINVAL; |
262 | return readl(ap->ioaddr.scr_addr + (sc_reg * 8)); | 262 | *val = readl(ap->ioaddr.scr_addr + (sc_reg * 8)); |
263 | return 0; | ||
263 | } | 264 | } |
264 | 265 | ||
265 | static void qs_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) | 266 | static int qs_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) |
266 | { | 267 | { |
267 | if (sc_reg > SCR_CONTROL) | 268 | if (sc_reg > SCR_CONTROL) |
268 | return; | 269 | return -EINVAL; |
269 | writel(val, ap->ioaddr.scr_addr + (sc_reg * 8)); | 270 | writel(val, ap->ioaddr.scr_addr + (sc_reg * 8)); |
271 | return 0; | ||
270 | } | 272 | } |
271 | 273 | ||
272 | static unsigned int qs_fill_sg(struct ata_queued_cmd *qc) | 274 | static unsigned int qs_fill_sg(struct ata_queued_cmd *qc) |
@@ -337,7 +339,7 @@ static void qs_qc_prep(struct ata_queued_cmd *qc) | |||
337 | buf[28] = dflags; | 339 | buf[28] = dflags; |
338 | 340 | ||
339 | /* frame information structure (FIS) */ | 341 | /* frame information structure (FIS) */ |
340 | ata_tf_to_fis(&qc->tf, &buf[32], 0); | 342 | ata_tf_to_fis(&qc->tf, 0, 1, &buf[32]); |
341 | } | 343 | } |
342 | 344 | ||
343 | static inline void qs_packet_start(struct ata_queued_cmd *qc) | 345 | static inline void qs_packet_start(struct ata_queued_cmd *qc) |
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c index 2a86dc4598d0..db6763758952 100644 --- a/drivers/ata/sata_sil.c +++ b/drivers/ata/sata_sil.c | |||
@@ -115,8 +115,8 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); | |||
115 | static int sil_pci_device_resume(struct pci_dev *pdev); | 115 | static int sil_pci_device_resume(struct pci_dev *pdev); |
116 | #endif | 116 | #endif |
117 | static void sil_dev_config(struct ata_device *dev); | 117 | static void sil_dev_config(struct ata_device *dev); |
118 | static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg); | 118 | static int sil_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); |
119 | static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); | 119 | static int sil_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); |
120 | static int sil_set_mode (struct ata_port *ap, struct ata_device **r_failed); | 120 | static int sil_set_mode (struct ata_port *ap, struct ata_device **r_failed); |
121 | static void sil_freeze(struct ata_port *ap); | 121 | static void sil_freeze(struct ata_port *ap); |
122 | static void sil_thaw(struct ata_port *ap); | 122 | static void sil_thaw(struct ata_port *ap); |
@@ -350,19 +350,26 @@ static inline void __iomem *sil_scr_addr(struct ata_port *ap, unsigned int sc_re | |||
350 | return NULL; | 350 | return NULL; |
351 | } | 351 | } |
352 | 352 | ||
353 | static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg) | 353 | static int sil_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) |
354 | { | 354 | { |
355 | void __iomem *mmio = sil_scr_addr(ap, sc_reg); | 355 | void __iomem *mmio = sil_scr_addr(ap, sc_reg); |
356 | if (mmio) | 356 | |
357 | return readl(mmio); | 357 | if (mmio) { |
358 | return 0xffffffffU; | 358 | *val = readl(mmio); |
359 | return 0; | ||
360 | } | ||
361 | return -EINVAL; | ||
359 | } | 362 | } |
360 | 363 | ||
361 | static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) | 364 | static int sil_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) |
362 | { | 365 | { |
363 | void __iomem *mmio = sil_scr_addr(ap, sc_reg); | 366 | void __iomem *mmio = sil_scr_addr(ap, sc_reg); |
364 | if (mmio) | 367 | |
368 | if (mmio) { | ||
365 | writel(val, mmio); | 369 | writel(val, mmio); |
370 | return 0; | ||
371 | } | ||
372 | return -EINVAL; | ||
366 | } | 373 | } |
367 | 374 | ||
368 | static void sil_host_intr(struct ata_port *ap, u32 bmdma2) | 375 | static void sil_host_intr(struct ata_port *ap, u32 bmdma2) |
@@ -378,7 +385,7 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2) | |||
378 | * controllers continue to assert IRQ as long as | 385 | * controllers continue to assert IRQ as long as |
379 | * SError bits are pending. Clear SError immediately. | 386 | * SError bits are pending. Clear SError immediately. |
380 | */ | 387 | */ |
381 | serror = sil_scr_read(ap, SCR_ERROR); | 388 | sil_scr_read(ap, SCR_ERROR, &serror); |
382 | sil_scr_write(ap, SCR_ERROR, serror); | 389 | sil_scr_write(ap, SCR_ERROR, serror); |
383 | 390 | ||
384 | /* Trigger hotplug and accumulate SError only if the | 391 | /* Trigger hotplug and accumulate SError only if the |
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index ac43a30ebe29..46fbbe7f121c 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c | |||
@@ -326,8 +326,8 @@ struct sil24_port_priv { | |||
326 | 326 | ||
327 | static void sil24_dev_config(struct ata_device *dev); | 327 | static void sil24_dev_config(struct ata_device *dev); |
328 | static u8 sil24_check_status(struct ata_port *ap); | 328 | static u8 sil24_check_status(struct ata_port *ap); |
329 | static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg); | 329 | static int sil24_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val); |
330 | static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val); | 330 | static int sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val); |
331 | static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf); | 331 | static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf); |
332 | static void sil24_qc_prep(struct ata_queued_cmd *qc); | 332 | static void sil24_qc_prep(struct ata_queued_cmd *qc); |
333 | static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc); | 333 | static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc); |
@@ -464,15 +464,15 @@ static void sil24_dev_config(struct ata_device *dev) | |||
464 | writel(PORT_CS_CDB16, port + PORT_CTRL_CLR); | 464 | writel(PORT_CS_CDB16, port + PORT_CTRL_CLR); |
465 | } | 465 | } |
466 | 466 | ||
467 | static inline void sil24_update_tf(struct ata_port *ap) | 467 | static void sil24_read_tf(struct ata_port *ap, int tag, struct ata_taskfile *tf) |
468 | { | 468 | { |
469 | struct sil24_port_priv *pp = ap->private_data; | ||
470 | void __iomem *port = ap->ioaddr.cmd_addr; | 469 | void __iomem *port = ap->ioaddr.cmd_addr; |
471 | struct sil24_prb __iomem *prb = port; | 470 | struct sil24_prb __iomem *prb; |
472 | u8 fis[6 * 4]; | 471 | u8 fis[6 * 4]; |
473 | 472 | ||
474 | memcpy_fromio(fis, prb->fis, 6 * 4); | 473 | prb = port + PORT_LRAM + sil24_tag(tag) * PORT_LRAM_SLOT_SZ; |
475 | ata_tf_from_fis(fis, &pp->tf); | 474 | memcpy_fromio(fis, prb->fis, sizeof(fis)); |
475 | ata_tf_from_fis(fis, tf); | ||
476 | } | 476 | } |
477 | 477 | ||
478 | static u8 sil24_check_status(struct ata_port *ap) | 478 | static u8 sil24_check_status(struct ata_port *ap) |
@@ -488,25 +488,30 @@ static int sil24_scr_map[] = { | |||
488 | [SCR_ACTIVE] = 3, | 488 | [SCR_ACTIVE] = 3, |
489 | }; | 489 | }; |
490 | 490 | ||
491 | static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg) | 491 | static int sil24_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val) |
492 | { | 492 | { |
493 | void __iomem *scr_addr = ap->ioaddr.scr_addr; | 493 | void __iomem *scr_addr = ap->ioaddr.scr_addr; |
494 | |||
494 | if (sc_reg < ARRAY_SIZE(sil24_scr_map)) { | 495 | if (sc_reg < ARRAY_SIZE(sil24_scr_map)) { |
495 | void __iomem *addr; | 496 | void __iomem *addr; |
496 | addr = scr_addr + sil24_scr_map[sc_reg] * 4; | 497 | addr = scr_addr + sil24_scr_map[sc_reg] * 4; |
497 | return readl(scr_addr + sil24_scr_map[sc_reg] * 4); | 498 | *val = readl(scr_addr + sil24_scr_map[sc_reg] * 4); |
499 | return 0; | ||
498 | } | 500 | } |
499 | return 0xffffffffU; | 501 | return -EINVAL; |
500 | } | 502 | } |
501 | 503 | ||
502 | static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val) | 504 | static int sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val) |
503 | { | 505 | { |
504 | void __iomem *scr_addr = ap->ioaddr.scr_addr; | 506 | void __iomem *scr_addr = ap->ioaddr.scr_addr; |
507 | |||
505 | if (sc_reg < ARRAY_SIZE(sil24_scr_map)) { | 508 | if (sc_reg < ARRAY_SIZE(sil24_scr_map)) { |
506 | void __iomem *addr; | 509 | void __iomem *addr; |
507 | addr = scr_addr + sil24_scr_map[sc_reg] * 4; | 510 | addr = scr_addr + sil24_scr_map[sc_reg] * 4; |
508 | writel(val, scr_addr + sil24_scr_map[sc_reg] * 4); | 511 | writel(val, scr_addr + sil24_scr_map[sc_reg] * 4); |
512 | return 0; | ||
509 | } | 513 | } |
514 | return -EINVAL; | ||
510 | } | 515 | } |
511 | 516 | ||
512 | static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf) | 517 | static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf) |
@@ -531,15 +536,60 @@ static int sil24_init_port(struct ata_port *ap) | |||
531 | return 0; | 536 | return 0; |
532 | } | 537 | } |
533 | 538 | ||
534 | static int sil24_softreset(struct ata_port *ap, unsigned int *class, | 539 | static int sil24_exec_polled_cmd(struct ata_port *ap, int pmp, |
535 | unsigned long deadline) | 540 | const struct ata_taskfile *tf, |
541 | int is_cmd, u32 ctrl, | ||
542 | unsigned long timeout_msec) | ||
536 | { | 543 | { |
537 | void __iomem *port = ap->ioaddr.cmd_addr; | 544 | void __iomem *port = ap->ioaddr.cmd_addr; |
538 | struct sil24_port_priv *pp = ap->private_data; | 545 | struct sil24_port_priv *pp = ap->private_data; |
539 | struct sil24_prb *prb = &pp->cmd_block[0].ata.prb; | 546 | struct sil24_prb *prb = &pp->cmd_block[0].ata.prb; |
540 | dma_addr_t paddr = pp->cmd_block_dma; | 547 | dma_addr_t paddr = pp->cmd_block_dma; |
541 | u32 mask, irq_stat; | 548 | u32 irq_enabled, irq_mask, irq_stat; |
549 | int rc; | ||
550 | |||
551 | prb->ctrl = cpu_to_le16(ctrl); | ||
552 | ata_tf_to_fis(tf, pmp, is_cmd, prb->fis); | ||
553 | |||
554 | /* temporarily plug completion and error interrupts */ | ||
555 | irq_enabled = readl(port + PORT_IRQ_ENABLE_SET); | ||
556 | writel(PORT_IRQ_COMPLETE | PORT_IRQ_ERROR, port + PORT_IRQ_ENABLE_CLR); | ||
557 | |||
558 | writel((u32)paddr, port + PORT_CMD_ACTIVATE); | ||
559 | writel((u64)paddr >> 32, port + PORT_CMD_ACTIVATE + 4); | ||
560 | |||
561 | irq_mask = (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR) << PORT_IRQ_RAW_SHIFT; | ||
562 | irq_stat = ata_wait_register(port + PORT_IRQ_STAT, irq_mask, 0x0, | ||
563 | 10, timeout_msec); | ||
564 | |||
565 | writel(irq_mask, port + PORT_IRQ_STAT); /* clear IRQs */ | ||
566 | irq_stat >>= PORT_IRQ_RAW_SHIFT; | ||
567 | |||
568 | if (irq_stat & PORT_IRQ_COMPLETE) | ||
569 | rc = 0; | ||
570 | else { | ||
571 | /* force port into known state */ | ||
572 | sil24_init_port(ap); | ||
573 | |||
574 | if (irq_stat & PORT_IRQ_ERROR) | ||
575 | rc = -EIO; | ||
576 | else | ||
577 | rc = -EBUSY; | ||
578 | } | ||
579 | |||
580 | /* restore IRQ enabled */ | ||
581 | writel(irq_enabled, port + PORT_IRQ_ENABLE_SET); | ||
582 | |||
583 | return rc; | ||
584 | } | ||
585 | |||
586 | static int sil24_do_softreset(struct ata_port *ap, unsigned int *class, | ||
587 | int pmp, unsigned long deadline) | ||
588 | { | ||
589 | unsigned long timeout_msec = 0; | ||
590 | struct ata_taskfile tf; | ||
542 | const char *reason; | 591 | const char *reason; |
592 | int rc; | ||
543 | 593 | ||
544 | DPRINTK("ENTER\n"); | 594 | DPRINTK("ENTER\n"); |
545 | 595 | ||
@@ -556,29 +606,22 @@ static int sil24_softreset(struct ata_port *ap, unsigned int *class, | |||
556 | } | 606 | } |
557 | 607 | ||
558 | /* do SRST */ | 608 | /* do SRST */ |
559 | prb->ctrl = cpu_to_le16(PRB_CTRL_SRST); | 609 | if (time_after(deadline, jiffies)) |
560 | prb->fis[1] = 0; /* no PMP yet */ | 610 | timeout_msec = jiffies_to_msecs(deadline - jiffies); |
561 | 611 | ||
562 | writel((u32)paddr, port + PORT_CMD_ACTIVATE); | 612 | ata_tf_init(ap->device, &tf); /* doesn't really matter */ |
563 | writel((u64)paddr >> 32, port + PORT_CMD_ACTIVATE + 4); | 613 | rc = sil24_exec_polled_cmd(ap, pmp, &tf, 0, PRB_CTRL_SRST, |
564 | 614 | timeout_msec); | |
565 | mask = (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR) << PORT_IRQ_RAW_SHIFT; | 615 | if (rc == -EBUSY) { |
566 | irq_stat = ata_wait_register(port + PORT_IRQ_STAT, mask, 0x0, | 616 | reason = "timeout"; |
567 | 100, jiffies_to_msecs(deadline - jiffies)); | 617 | goto err; |
568 | 618 | } else if (rc) { | |
569 | writel(irq_stat, port + PORT_IRQ_STAT); /* clear IRQs */ | 619 | reason = "SRST command error"; |
570 | irq_stat >>= PORT_IRQ_RAW_SHIFT; | ||
571 | |||
572 | if (!(irq_stat & PORT_IRQ_COMPLETE)) { | ||
573 | if (irq_stat & PORT_IRQ_ERROR) | ||
574 | reason = "SRST command error"; | ||
575 | else | ||
576 | reason = "timeout"; | ||
577 | goto err; | 620 | goto err; |
578 | } | 621 | } |
579 | 622 | ||
580 | sil24_update_tf(ap); | 623 | sil24_read_tf(ap, 0, &tf); |
581 | *class = ata_dev_classify(&pp->tf); | 624 | *class = ata_dev_classify(&tf); |
582 | 625 | ||
583 | if (*class == ATA_DEV_UNKNOWN) | 626 | if (*class == ATA_DEV_UNKNOWN) |
584 | *class = ATA_DEV_NONE; | 627 | *class = ATA_DEV_NONE; |
@@ -592,6 +635,12 @@ static int sil24_softreset(struct ata_port *ap, unsigned int *class, | |||
592 | return -EIO; | 635 | return -EIO; |
593 | } | 636 | } |
594 | 637 | ||
638 | static int sil24_softreset(struct ata_port *ap, unsigned int *class, | ||
639 | unsigned long deadline) | ||
640 | { | ||
641 | return sil24_do_softreset(ap, class, 0, deadline); | ||
642 | } | ||
643 | |||
595 | static int sil24_hardreset(struct ata_port *ap, unsigned int *class, | 644 | static int sil24_hardreset(struct ata_port *ap, unsigned int *class, |
596 | unsigned long deadline) | 645 | unsigned long deadline) |
597 | { | 646 | { |
@@ -699,7 +748,7 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc) | |||
699 | } | 748 | } |
700 | 749 | ||
701 | prb->ctrl = cpu_to_le16(ctrl); | 750 | prb->ctrl = cpu_to_le16(ctrl); |
702 | ata_tf_to_fis(&qc->tf, prb->fis, 0); | 751 | ata_tf_to_fis(&qc->tf, 0, 1, prb->fis); |
703 | 752 | ||
704 | if (qc->flags & ATA_QCFLAG_DMAMAP) | 753 | if (qc->flags & ATA_QCFLAG_DMAMAP) |
705 | sil24_fill_sg(qc, sge); | 754 | sil24_fill_sg(qc, sge); |
@@ -754,6 +803,7 @@ static void sil24_thaw(struct ata_port *ap) | |||
754 | static void sil24_error_intr(struct ata_port *ap) | 803 | static void sil24_error_intr(struct ata_port *ap) |
755 | { | 804 | { |
756 | void __iomem *port = ap->ioaddr.cmd_addr; | 805 | void __iomem *port = ap->ioaddr.cmd_addr; |
806 | struct sil24_port_priv *pp = ap->private_data; | ||
757 | struct ata_eh_info *ehi = &ap->eh_info; | 807 | struct ata_eh_info *ehi = &ap->eh_info; |
758 | int freeze = 0; | 808 | int freeze = 0; |
759 | u32 irq_stat; | 809 | u32 irq_stat; |
@@ -769,16 +819,16 @@ static void sil24_error_intr(struct ata_port *ap) | |||
769 | 819 | ||
770 | if (irq_stat & (PORT_IRQ_PHYRDY_CHG | PORT_IRQ_DEV_XCHG)) { | 820 | if (irq_stat & (PORT_IRQ_PHYRDY_CHG | PORT_IRQ_DEV_XCHG)) { |
771 | ata_ehi_hotplugged(ehi); | 821 | ata_ehi_hotplugged(ehi); |
772 | ata_ehi_push_desc(ehi, ", %s", | 822 | ata_ehi_push_desc(ehi, "%s", |
773 | irq_stat & PORT_IRQ_PHYRDY_CHG ? | 823 | irq_stat & PORT_IRQ_PHYRDY_CHG ? |
774 | "PHY RDY changed" : "device exchanged"); | 824 | "PHY RDY changed" : "device exchanged"); |
775 | freeze = 1; | 825 | freeze = 1; |
776 | } | 826 | } |
777 | 827 | ||
778 | if (irq_stat & PORT_IRQ_UNK_FIS) { | 828 | if (irq_stat & PORT_IRQ_UNK_FIS) { |
779 | ehi->err_mask |= AC_ERR_HSM; | 829 | ehi->err_mask |= AC_ERR_HSM; |
780 | ehi->action |= ATA_EH_SOFTRESET; | 830 | ehi->action |= ATA_EH_SOFTRESET; |
781 | ata_ehi_push_desc(ehi , ", unknown FIS"); | 831 | ata_ehi_push_desc(ehi, "unknown FIS"); |
782 | freeze = 1; | 832 | freeze = 1; |
783 | } | 833 | } |
784 | 834 | ||
@@ -797,18 +847,18 @@ static void sil24_error_intr(struct ata_port *ap) | |||
797 | if (ci && ci->desc) { | 847 | if (ci && ci->desc) { |
798 | err_mask |= ci->err_mask; | 848 | err_mask |= ci->err_mask; |
799 | action |= ci->action; | 849 | action |= ci->action; |
800 | ata_ehi_push_desc(ehi, ", %s", ci->desc); | 850 | ata_ehi_push_desc(ehi, "%s", ci->desc); |
801 | } else { | 851 | } else { |
802 | err_mask |= AC_ERR_OTHER; | 852 | err_mask |= AC_ERR_OTHER; |
803 | action |= ATA_EH_SOFTRESET; | 853 | action |= ATA_EH_SOFTRESET; |
804 | ata_ehi_push_desc(ehi, ", unknown command error %d", | 854 | ata_ehi_push_desc(ehi, "unknown command error %d", |
805 | cerr); | 855 | cerr); |
806 | } | 856 | } |
807 | 857 | ||
808 | /* record error info */ | 858 | /* record error info */ |
809 | qc = ata_qc_from_tag(ap, ap->active_tag); | 859 | qc = ata_qc_from_tag(ap, ap->active_tag); |
810 | if (qc) { | 860 | if (qc) { |
811 | sil24_update_tf(ap); | 861 | sil24_read_tf(ap, qc->tag, &pp->tf); |
812 | qc->err_mask |= err_mask; | 862 | qc->err_mask |= err_mask; |
813 | } else | 863 | } else |
814 | ehi->err_mask |= err_mask; | 864 | ehi->err_mask |= err_mask; |
@@ -825,8 +875,11 @@ static void sil24_error_intr(struct ata_port *ap) | |||
825 | 875 | ||
826 | static void sil24_finish_qc(struct ata_queued_cmd *qc) | 876 | static void sil24_finish_qc(struct ata_queued_cmd *qc) |
827 | { | 877 | { |
878 | struct ata_port *ap = qc->ap; | ||
879 | struct sil24_port_priv *pp = ap->private_data; | ||
880 | |||
828 | if (qc->flags & ATA_QCFLAG_RESULT_TF) | 881 | if (qc->flags & ATA_QCFLAG_RESULT_TF) |
829 | sil24_update_tf(qc->ap); | 882 | sil24_read_tf(ap, qc->tag, &pp->tf); |
830 | } | 883 | } |
831 | 884 | ||
832 | static inline void sil24_host_intr(struct ata_port *ap) | 885 | static inline void sil24_host_intr(struct ata_port *ap) |
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c index 33716b00c6b7..31a2f55aae66 100644 --- a/drivers/ata/sata_sis.c +++ b/drivers/ata/sata_sis.c | |||
@@ -64,8 +64,8 @@ enum { | |||
64 | }; | 64 | }; |
65 | 65 | ||
66 | static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); | 66 | static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); |
67 | static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg); | 67 | static int sis_scr_read (struct ata_port *ap, unsigned int sc_reg, u32 *val); |
68 | static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); | 68 | static int sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); |
69 | 69 | ||
70 | static const struct pci_device_id sis_pci_tbl[] = { | 70 | static const struct pci_device_id sis_pci_tbl[] = { |
71 | { PCI_VDEVICE(SI, 0x0180), sis_180 }, /* SiS 964/180 */ | 71 | { PCI_VDEVICE(SI, 0x0180), sis_180 }, /* SiS 964/180 */ |
@@ -207,36 +207,37 @@ static void sis_scr_cfg_write (struct ata_port *ap, unsigned int sc_reg, u32 val | |||
207 | pci_write_config_dword(pdev, cfg_addr+0x10, val); | 207 | pci_write_config_dword(pdev, cfg_addr+0x10, val); |
208 | } | 208 | } |
209 | 209 | ||
210 | static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg) | 210 | static int sis_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) |
211 | { | 211 | { |
212 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | 212 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
213 | u32 val, val2 = 0; | ||
214 | u8 pmr; | 213 | u8 pmr; |
215 | 214 | ||
216 | if (sc_reg > SCR_CONTROL) | 215 | if (sc_reg > SCR_CONTROL) |
217 | return 0xffffffffU; | 216 | return -EINVAL; |
218 | 217 | ||
219 | if (ap->flags & SIS_FLAG_CFGSCR) | 218 | if (ap->flags & SIS_FLAG_CFGSCR) |
220 | return sis_scr_cfg_read(ap, sc_reg); | 219 | return sis_scr_cfg_read(ap, sc_reg); |
221 | 220 | ||
222 | pci_read_config_byte(pdev, SIS_PMR, &pmr); | 221 | pci_read_config_byte(pdev, SIS_PMR, &pmr); |
223 | 222 | ||
224 | val = ioread32(ap->ioaddr.scr_addr + (sc_reg * 4)); | 223 | *val = ioread32(ap->ioaddr.scr_addr + (sc_reg * 4)); |
225 | 224 | ||
226 | if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || | 225 | if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || |
227 | (pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED)) | 226 | (pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED)) |
228 | val2 = ioread32(ap->ioaddr.scr_addr + (sc_reg * 4) + 0x10); | 227 | *val |= ioread32(ap->ioaddr.scr_addr + (sc_reg * 4) + 0x10); |
228 | |||
229 | *val &= 0xfffffffb; | ||
229 | 230 | ||
230 | return (val | val2) & 0xfffffffb; | 231 | return 0; |
231 | } | 232 | } |
232 | 233 | ||
233 | static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) | 234 | static int sis_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) |
234 | { | 235 | { |
235 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | 236 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
236 | u8 pmr; | 237 | u8 pmr; |
237 | 238 | ||
238 | if (sc_reg > SCR_CONTROL) | 239 | if (sc_reg > SCR_CONTROL) |
239 | return; | 240 | return -EINVAL; |
240 | 241 | ||
241 | pci_read_config_byte(pdev, SIS_PMR, &pmr); | 242 | pci_read_config_byte(pdev, SIS_PMR, &pmr); |
242 | 243 | ||
@@ -248,6 +249,7 @@ static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) | |||
248 | (pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED)) | 249 | (pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED)) |
249 | iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4)+0x10); | 250 | iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4)+0x10); |
250 | } | 251 | } |
252 | return 0; | ||
251 | } | 253 | } |
252 | 254 | ||
253 | static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | 255 | static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) |
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c index 63fe99afd59f..92e877075037 100644 --- a/drivers/ata/sata_svw.c +++ b/drivers/ata/sata_svw.c | |||
@@ -103,20 +103,21 @@ static int k2_sata_check_atapi_dma(struct ata_queued_cmd *qc) | |||
103 | return 0; | 103 | return 0; |
104 | } | 104 | } |
105 | 105 | ||
106 | static u32 k2_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) | 106 | static int k2_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) |
107 | { | 107 | { |
108 | if (sc_reg > SCR_CONTROL) | 108 | if (sc_reg > SCR_CONTROL) |
109 | return 0xffffffffU; | 109 | return -EINVAL; |
110 | return readl(ap->ioaddr.scr_addr + (sc_reg * 4)); | 110 | *val = readl(ap->ioaddr.scr_addr + (sc_reg * 4)); |
111 | return 0; | ||
111 | } | 112 | } |
112 | 113 | ||
113 | 114 | ||
114 | static void k2_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, | 115 | static int k2_sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) |
115 | u32 val) | ||
116 | { | 116 | { |
117 | if (sc_reg > SCR_CONTROL) | 117 | if (sc_reg > SCR_CONTROL) |
118 | return; | 118 | return -EINVAL; |
119 | writel(val, ap->ioaddr.scr_addr + (sc_reg * 4)); | 119 | writel(val, ap->ioaddr.scr_addr + (sc_reg * 4)); |
120 | return 0; | ||
120 | } | 121 | } |
121 | 122 | ||
122 | 123 | ||
diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c index b52f83ab056a..78c28512f01c 100644 --- a/drivers/ata/sata_uli.c +++ b/drivers/ata/sata_uli.c | |||
@@ -57,8 +57,8 @@ struct uli_priv { | |||
57 | }; | 57 | }; |
58 | 58 | ||
59 | static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); | 59 | static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); |
60 | static u32 uli_scr_read (struct ata_port *ap, unsigned int sc_reg); | 60 | static int uli_scr_read (struct ata_port *ap, unsigned int sc_reg, u32 *val); |
61 | static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); | 61 | static int uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); |
62 | 62 | ||
63 | static const struct pci_device_id uli_pci_tbl[] = { | 63 | static const struct pci_device_id uli_pci_tbl[] = { |
64 | { PCI_VDEVICE(AL, 0x5289), uli_5289 }, | 64 | { PCI_VDEVICE(AL, 0x5289), uli_5289 }, |
@@ -164,20 +164,22 @@ static void uli_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val) | |||
164 | pci_write_config_dword(pdev, cfg_addr, val); | 164 | pci_write_config_dword(pdev, cfg_addr, val); |
165 | } | 165 | } |
166 | 166 | ||
167 | static u32 uli_scr_read (struct ata_port *ap, unsigned int sc_reg) | 167 | static int uli_scr_read (struct ata_port *ap, unsigned int sc_reg, u32 *val) |
168 | { | 168 | { |
169 | if (sc_reg > SCR_CONTROL) | 169 | if (sc_reg > SCR_CONTROL) |
170 | return 0xffffffffU; | 170 | return -EINVAL; |
171 | 171 | ||
172 | return uli_scr_cfg_read(ap, sc_reg); | 172 | *val = uli_scr_cfg_read(ap, sc_reg); |
173 | return 0; | ||
173 | } | 174 | } |
174 | 175 | ||
175 | static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) | 176 | static int uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) |
176 | { | 177 | { |
177 | if (sc_reg > SCR_CONTROL) //SCR_CONTROL=2, SCR_ERROR=1, SCR_STATUS=0 | 178 | if (sc_reg > SCR_CONTROL) //SCR_CONTROL=2, SCR_ERROR=1, SCR_STATUS=0 |
178 | return; | 179 | return -EINVAL; |
179 | 180 | ||
180 | uli_scr_cfg_write(ap, sc_reg, val); | 181 | uli_scr_cfg_write(ap, sc_reg, val); |
182 | return 0; | ||
181 | } | 183 | } |
182 | 184 | ||
183 | static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | 185 | static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) |
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index c4124475f754..86b7bfc17324 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c | |||
@@ -72,8 +72,8 @@ enum { | |||
72 | }; | 72 | }; |
73 | 73 | ||
74 | static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); | 74 | static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); |
75 | static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg); | 75 | static int svia_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); |
76 | static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); | 76 | static int svia_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); |
77 | static void svia_noop_freeze(struct ata_port *ap); | 77 | static void svia_noop_freeze(struct ata_port *ap); |
78 | static void vt6420_error_handler(struct ata_port *ap); | 78 | static void vt6420_error_handler(struct ata_port *ap); |
79 | static int vt6421_pata_cable_detect(struct ata_port *ap); | 79 | static int vt6421_pata_cable_detect(struct ata_port *ap); |
@@ -249,18 +249,20 @@ MODULE_LICENSE("GPL"); | |||
249 | MODULE_DEVICE_TABLE(pci, svia_pci_tbl); | 249 | MODULE_DEVICE_TABLE(pci, svia_pci_tbl); |
250 | MODULE_VERSION(DRV_VERSION); | 250 | MODULE_VERSION(DRV_VERSION); |
251 | 251 | ||
252 | static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg) | 252 | static int svia_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) |
253 | { | 253 | { |
254 | if (sc_reg > SCR_CONTROL) | 254 | if (sc_reg > SCR_CONTROL) |
255 | return 0xffffffffU; | 255 | return -EINVAL; |
256 | return ioread32(ap->ioaddr.scr_addr + (4 * sc_reg)); | 256 | *val = ioread32(ap->ioaddr.scr_addr + (4 * sc_reg)); |
257 | return 0; | ||
257 | } | 258 | } |
258 | 259 | ||
259 | static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) | 260 | static int svia_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) |
260 | { | 261 | { |
261 | if (sc_reg > SCR_CONTROL) | 262 | if (sc_reg > SCR_CONTROL) |
262 | return; | 263 | return -EINVAL; |
263 | iowrite32(val, ap->ioaddr.scr_addr + (4 * sc_reg)); | 264 | iowrite32(val, ap->ioaddr.scr_addr + (4 * sc_reg)); |
265 | return 0; | ||
264 | } | 266 | } |
265 | 267 | ||
266 | static void svia_noop_freeze(struct ata_port *ap) | 268 | static void svia_noop_freeze(struct ata_port *ap) |
@@ -305,18 +307,19 @@ static int vt6420_prereset(struct ata_port *ap, unsigned long deadline) | |||
305 | 307 | ||
306 | /* Resume phy. This is the old SATA resume sequence */ | 308 | /* Resume phy. This is the old SATA resume sequence */ |
307 | svia_scr_write(ap, SCR_CONTROL, 0x300); | 309 | svia_scr_write(ap, SCR_CONTROL, 0x300); |
308 | svia_scr_read(ap, SCR_CONTROL); /* flush */ | 310 | svia_scr_read(ap, SCR_CONTROL, &scontrol); /* flush */ |
309 | 311 | ||
310 | /* wait for phy to become ready, if necessary */ | 312 | /* wait for phy to become ready, if necessary */ |
311 | do { | 313 | do { |
312 | msleep(200); | 314 | msleep(200); |
313 | if ((svia_scr_read(ap, SCR_STATUS) & 0xf) != 1) | 315 | svia_scr_read(ap, SCR_STATUS, &sstatus); |
316 | if ((sstatus & 0xf) != 1) | ||
314 | break; | 317 | break; |
315 | } while (time_before(jiffies, timeout)); | 318 | } while (time_before(jiffies, timeout)); |
316 | 319 | ||
317 | /* open code sata_print_link_status() */ | 320 | /* open code sata_print_link_status() */ |
318 | sstatus = svia_scr_read(ap, SCR_STATUS); | 321 | svia_scr_read(ap, SCR_STATUS, &sstatus); |
319 | scontrol = svia_scr_read(ap, SCR_CONTROL); | 322 | svia_scr_read(ap, SCR_CONTROL, &scontrol); |
320 | 323 | ||
321 | online = (sstatus & 0xf) == 0x3; | 324 | online = (sstatus & 0xf) == 0x3; |
322 | 325 | ||
@@ -325,7 +328,7 @@ static int vt6420_prereset(struct ata_port *ap, unsigned long deadline) | |||
325 | online ? "up" : "down", sstatus, scontrol); | 328 | online ? "up" : "down", sstatus, scontrol); |
326 | 329 | ||
327 | /* SStatus is read one more time */ | 330 | /* SStatus is read one more time */ |
328 | svia_scr_read(ap, SCR_STATUS); | 331 | svia_scr_read(ap, SCR_STATUS, &sstatus); |
329 | 332 | ||
330 | if (!online) { | 333 | if (!online) { |
331 | /* tell EH to bail */ | 334 | /* tell EH to bail */ |
diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c index 1b5d81faa102..24344d0d0575 100644 --- a/drivers/ata/sata_vsc.c +++ b/drivers/ata/sata_vsc.c | |||
@@ -98,20 +98,21 @@ enum { | |||
98 | VSC_SATA_INT_PHY_CHANGE), | 98 | VSC_SATA_INT_PHY_CHANGE), |
99 | }; | 99 | }; |
100 | 100 | ||
101 | static u32 vsc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) | 101 | static int vsc_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) |
102 | { | 102 | { |
103 | if (sc_reg > SCR_CONTROL) | 103 | if (sc_reg > SCR_CONTROL) |
104 | return 0xffffffffU; | 104 | return -EINVAL; |
105 | return readl(ap->ioaddr.scr_addr + (sc_reg * 4)); | 105 | *val = readl(ap->ioaddr.scr_addr + (sc_reg * 4)); |
106 | return 0; | ||
106 | } | 107 | } |
107 | 108 | ||
108 | 109 | ||
109 | static void vsc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, | 110 | static int vsc_sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) |
110 | u32 val) | ||
111 | { | 111 | { |
112 | if (sc_reg > SCR_CONTROL) | 112 | if (sc_reg > SCR_CONTROL) |
113 | return; | 113 | return -EINVAL; |
114 | writel(val, ap->ioaddr.scr_addr + (sc_reg * 4)); | 114 | writel(val, ap->ioaddr.scr_addr + (sc_reg * 4)); |
115 | return 0; | ||
115 | } | 116 | } |
116 | 117 | ||
117 | 118 | ||
diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c index 2288b55d916f..d50b82381155 100644 --- a/drivers/block/sunvdc.c +++ b/drivers/block/sunvdc.c | |||
@@ -64,7 +64,6 @@ struct vdc_port { | |||
64 | u64 operations; | 64 | u64 operations; |
65 | u32 vdisk_size; | 65 | u32 vdisk_size; |
66 | u8 vdisk_type; | 66 | u8 vdisk_type; |
67 | u8 dev_no; | ||
68 | 67 | ||
69 | char disk_name[32]; | 68 | char disk_name[32]; |
70 | 69 | ||
@@ -703,7 +702,7 @@ static int probe_disk(struct vdc_port *port) | |||
703 | blk_queue_max_phys_segments(q, port->ring_cookies); | 702 | blk_queue_max_phys_segments(q, port->ring_cookies); |
704 | blk_queue_max_sectors(q, port->max_xfer_size); | 703 | blk_queue_max_sectors(q, port->max_xfer_size); |
705 | g->major = vdc_major; | 704 | g->major = vdc_major; |
706 | g->first_minor = port->dev_no << PARTITION_SHIFT; | 705 | g->first_minor = port->vio.vdev->dev_no << PARTITION_SHIFT; |
707 | strcpy(g->disk_name, port->disk_name); | 706 | strcpy(g->disk_name, port->disk_name); |
708 | 707 | ||
709 | g->fops = &vdc_fops; | 708 | g->fops = &vdc_fops; |
@@ -747,21 +746,16 @@ static int __devinit vdc_port_probe(struct vio_dev *vdev, | |||
747 | { | 746 | { |
748 | struct mdesc_handle *hp; | 747 | struct mdesc_handle *hp; |
749 | struct vdc_port *port; | 748 | struct vdc_port *port; |
750 | const u64 *port_id; | ||
751 | int err; | 749 | int err; |
752 | 750 | ||
753 | print_version(); | 751 | print_version(); |
754 | 752 | ||
755 | hp = mdesc_grab(); | 753 | hp = mdesc_grab(); |
756 | 754 | ||
757 | port_id = mdesc_get_property(hp, vdev->mp, "id", NULL); | ||
758 | err = -ENODEV; | 755 | err = -ENODEV; |
759 | if (!port_id) { | 756 | if ((vdev->dev_no << PARTITION_SHIFT) & ~(u64)MINORMASK) { |
760 | printk(KERN_ERR PFX "Port lacks id property.\n"); | 757 | printk(KERN_ERR PFX "Port id [%lu] too large.\n", |
761 | goto err_out_release_mdesc; | 758 | vdev->dev_no); |
762 | } | ||
763 | if ((*port_id << PARTITION_SHIFT) & ~(u64)MINORMASK) { | ||
764 | printk(KERN_ERR PFX "Port id [%lu] too large.\n", *port_id); | ||
765 | goto err_out_release_mdesc; | 759 | goto err_out_release_mdesc; |
766 | } | 760 | } |
767 | 761 | ||
@@ -772,16 +766,14 @@ static int __devinit vdc_port_probe(struct vio_dev *vdev, | |||
772 | goto err_out_release_mdesc; | 766 | goto err_out_release_mdesc; |
773 | } | 767 | } |
774 | 768 | ||
775 | port->dev_no = *port_id; | 769 | if (vdev->dev_no >= 26) |
776 | |||
777 | if (port->dev_no >= 26) | ||
778 | snprintf(port->disk_name, sizeof(port->disk_name), | 770 | snprintf(port->disk_name, sizeof(port->disk_name), |
779 | VDCBLK_NAME "%c%c", | 771 | VDCBLK_NAME "%c%c", |
780 | 'a' + (port->dev_no / 26) - 1, | 772 | 'a' + ((int)vdev->dev_no / 26) - 1, |
781 | 'a' + (port->dev_no % 26)); | 773 | 'a' + ((int)vdev->dev_no % 26)); |
782 | else | 774 | else |
783 | snprintf(port->disk_name, sizeof(port->disk_name), | 775 | snprintf(port->disk_name, sizeof(port->disk_name), |
784 | VDCBLK_NAME "%c", 'a' + (port->dev_no % 26)); | 776 | VDCBLK_NAME "%c", 'a' + ((int)vdev->dev_no % 26)); |
785 | 777 | ||
786 | err = vio_driver_init(&port->vio, vdev, VDEV_DISK, | 778 | err = vio_driver_init(&port->vio, vdev, VDEV_DISK, |
787 | vdc_versions, ARRAY_SIZE(vdc_versions), | 779 | vdc_versions, ARRAY_SIZE(vdc_versions), |
@@ -849,7 +841,7 @@ static struct vio_device_id vdc_port_match[] = { | |||
849 | }, | 841 | }, |
850 | {}, | 842 | {}, |
851 | }; | 843 | }; |
852 | MODULE_DEVICE_TABLE(vio, vdc_match); | 844 | MODULE_DEVICE_TABLE(vio, vdc_port_match); |
853 | 845 | ||
854 | static struct vio_driver vdc_port_driver = { | 846 | static struct vio_driver vdc_port_driver = { |
855 | .id_table = vdc_port_match, | 847 | .id_table = vdc_port_match, |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 9e8f21410d2d..4373d7cdc5d2 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -185,7 +185,7 @@ config ESPSERIAL | |||
185 | 185 | ||
186 | config MOXA_INTELLIO | 186 | config MOXA_INTELLIO |
187 | tristate "Moxa Intellio support" | 187 | tristate "Moxa Intellio support" |
188 | depends on SERIAL_NONSTANDARD | 188 | depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI) |
189 | help | 189 | help |
190 | Say Y here if you have a Moxa Intellio multiport serial card. | 190 | Say Y here if you have a Moxa Intellio multiport serial card. |
191 | 191 | ||
@@ -241,7 +241,7 @@ config SYNCLINK | |||
241 | 241 | ||
242 | config SYNCLINKMP | 242 | config SYNCLINKMP |
243 | tristate "SyncLink Multiport support" | 243 | tristate "SyncLink Multiport support" |
244 | depends on SERIAL_NONSTANDARD | 244 | depends on SERIAL_NONSTANDARD && PCI |
245 | help | 245 | help |
246 | Enable support for the SyncLink Multiport (2 or 4 ports) | 246 | Enable support for the SyncLink Multiport (2 or 4 ports) |
247 | serial adapter, running asynchronous and HDLC communications up | 247 | serial adapter, running asynchronous and HDLC communications up |
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c index c585b4738f86..f1497cecffd8 100644 --- a/drivers/char/serial167.c +++ b/drivers/char/serial167.c | |||
@@ -2573,16 +2573,10 @@ static struct tty_driver *serial167_console_device(struct console *c, | |||
2573 | return cy_serial_driver; | 2573 | return cy_serial_driver; |
2574 | } | 2574 | } |
2575 | 2575 | ||
2576 | static int __init serial167_console_setup(struct console *co, char *options) | ||
2577 | { | ||
2578 | return 0; | ||
2579 | } | ||
2580 | |||
2581 | static struct console sercons = { | 2576 | static struct console sercons = { |
2582 | .name = "ttyS", | 2577 | .name = "ttyS", |
2583 | .write = serial167_console_write, | 2578 | .write = serial167_console_write, |
2584 | .device = serial167_console_device, | 2579 | .device = serial167_console_device, |
2585 | .setup = serial167_console_setup, | ||
2586 | .flags = CON_PRINTBUFFER, | 2580 | .flags = CON_PRINTBUFFER, |
2587 | .index = -1, | 2581 | .index = -1, |
2588 | }; | 2582 | }; |
diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c index 4eba32b23b29..4b26ce48189b 100644 --- a/drivers/char/tpm/tpm_bios.c +++ b/drivers/char/tpm/tpm_bios.c | |||
@@ -427,7 +427,7 @@ static int tpm_ascii_bios_measurements_open(struct inode *inode, | |||
427 | return -ENOMEM; | 427 | return -ENOMEM; |
428 | 428 | ||
429 | if ((err = read_log(log))) | 429 | if ((err = read_log(log))) |
430 | return err; | 430 | goto out_free; |
431 | 431 | ||
432 | /* now register seq file */ | 432 | /* now register seq file */ |
433 | err = seq_open(file, &tpm_ascii_b_measurments_seqops); | 433 | err = seq_open(file, &tpm_ascii_b_measurments_seqops); |
@@ -435,10 +435,15 @@ static int tpm_ascii_bios_measurements_open(struct inode *inode, | |||
435 | seq = file->private_data; | 435 | seq = file->private_data; |
436 | seq->private = log; | 436 | seq->private = log; |
437 | } else { | 437 | } else { |
438 | kfree(log->bios_event_log); | 438 | goto out_free; |
439 | kfree(log); | ||
440 | } | 439 | } |
440 | |||
441 | out: | ||
441 | return err; | 442 | return err; |
443 | out_free: | ||
444 | kfree(log->bios_event_log); | ||
445 | kfree(log); | ||
446 | goto out; | ||
442 | } | 447 | } |
443 | 448 | ||
444 | const struct file_operations tpm_ascii_bios_measurements_ops = { | 449 | const struct file_operations tpm_ascii_bios_measurements_ops = { |
diff --git a/drivers/char/vme_scc.c b/drivers/char/vme_scc.c index bef6d886d4fb..e122a0e87bb0 100644 --- a/drivers/char/vme_scc.c +++ b/drivers/char/vme_scc.c | |||
@@ -1013,18 +1013,10 @@ static struct tty_driver *scc_console_device(struct console *c, int *index) | |||
1013 | return scc_driver; | 1013 | return scc_driver; |
1014 | } | 1014 | } |
1015 | 1015 | ||
1016 | |||
1017 | static int __init scc_console_setup(struct console *co, char *options) | ||
1018 | { | ||
1019 | return 0; | ||
1020 | } | ||
1021 | |||
1022 | |||
1023 | static struct console sercons = { | 1016 | static struct console sercons = { |
1024 | .name = "ttyS", | 1017 | .name = "ttyS", |
1025 | .write = scc_console_write, | 1018 | .write = scc_console_write, |
1026 | .device = scc_console_device, | 1019 | .device = scc_console_device, |
1027 | .setup = scc_console_setup, | ||
1028 | .flags = CON_PRINTBUFFER, | 1020 | .flags = CON_PRINTBUFFER, |
1029 | .index = -1, | 1021 | .index = -1, |
1030 | }; | 1022 | }; |
diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig index 2f48ba329961..ad5cc5f6862f 100644 --- a/drivers/char/watchdog/Kconfig +++ b/drivers/char/watchdog/Kconfig | |||
@@ -602,7 +602,7 @@ config ZVM_WATCHDOG | |||
602 | 602 | ||
603 | config SH_WDT | 603 | config SH_WDT |
604 | tristate "SuperH Watchdog" | 604 | tristate "SuperH Watchdog" |
605 | depends on SUPERH | 605 | depends on SUPERH && (CPU_SH3 || CPU_SH4) |
606 | help | 606 | help |
607 | This driver adds watchdog support for the integrated watchdog in the | 607 | This driver adds watchdog support for the integrated watchdog in the |
608 | SuperH processors. If you have one of these processors and wish | 608 | SuperH processors. If you have one of these processors and wish |
diff --git a/drivers/ide/legacy/falconide.c b/drivers/ide/legacy/falconide.c index e1e9d9d6893f..f0829b83e970 100644 --- a/drivers/ide/legacy/falconide.c +++ b/drivers/ide/legacy/falconide.c | |||
@@ -8,6 +8,7 @@ | |||
8 | * more details. | 8 | * more details. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/module.h> | ||
11 | #include <linux/types.h> | 12 | #include <linux/types.h> |
12 | #include <linux/mm.h> | 13 | #include <linux/mm.h> |
13 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
@@ -54,6 +55,7 @@ static int falconide_offsets[IDE_NR_PORTS] __initdata = { | |||
54 | */ | 55 | */ |
55 | 56 | ||
56 | int falconide_intr_lock; | 57 | int falconide_intr_lock; |
58 | EXPORT_SYMBOL(falconide_intr_lock); | ||
57 | 59 | ||
58 | 60 | ||
59 | /* | 61 | /* |
diff --git a/drivers/input/input.c b/drivers/input/input.c index 75b4d2a83dd9..5fe755586623 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -471,37 +471,16 @@ static unsigned int input_proc_devices_poll(struct file *file, poll_table *wait) | |||
471 | return 0; | 471 | return 0; |
472 | } | 472 | } |
473 | 473 | ||
474 | static struct list_head *list_get_nth_element(struct list_head *list, loff_t *pos) | ||
475 | { | ||
476 | struct list_head *node; | ||
477 | loff_t i = 0; | ||
478 | |||
479 | list_for_each(node, list) | ||
480 | if (i++ == *pos) | ||
481 | return node; | ||
482 | |||
483 | return NULL; | ||
484 | } | ||
485 | |||
486 | static struct list_head *list_get_next_element(struct list_head *list, struct list_head *element, loff_t *pos) | ||
487 | { | ||
488 | if (element->next == list) | ||
489 | return NULL; | ||
490 | |||
491 | ++(*pos); | ||
492 | return element->next; | ||
493 | } | ||
494 | |||
495 | static void *input_devices_seq_start(struct seq_file *seq, loff_t *pos) | 474 | static void *input_devices_seq_start(struct seq_file *seq, loff_t *pos) |
496 | { | 475 | { |
497 | /* acquire lock here ... Yes, we do need locking, I knowi, I know... */ | 476 | /* acquire lock here ... Yes, we do need locking, I knowi, I know... */ |
498 | 477 | ||
499 | return list_get_nth_element(&input_dev_list, pos); | 478 | return seq_list_start(&input_dev_list, *pos); |
500 | } | 479 | } |
501 | 480 | ||
502 | static void *input_devices_seq_next(struct seq_file *seq, void *v, loff_t *pos) | 481 | static void *input_devices_seq_next(struct seq_file *seq, void *v, loff_t *pos) |
503 | { | 482 | { |
504 | return list_get_next_element(&input_dev_list, v, pos); | 483 | return seq_list_next(v, &input_dev_list, pos); |
505 | } | 484 | } |
506 | 485 | ||
507 | static void input_devices_seq_stop(struct seq_file *seq, void *v) | 486 | static void input_devices_seq_stop(struct seq_file *seq, void *v) |
@@ -592,13 +571,13 @@ static void *input_handlers_seq_start(struct seq_file *seq, loff_t *pos) | |||
592 | { | 571 | { |
593 | /* acquire lock here ... Yes, we do need locking, I knowi, I know... */ | 572 | /* acquire lock here ... Yes, we do need locking, I knowi, I know... */ |
594 | seq->private = (void *)(unsigned long)*pos; | 573 | seq->private = (void *)(unsigned long)*pos; |
595 | return list_get_nth_element(&input_handler_list, pos); | 574 | return seq_list_start(&input_handler_list, *pos); |
596 | } | 575 | } |
597 | 576 | ||
598 | static void *input_handlers_seq_next(struct seq_file *seq, void *v, loff_t *pos) | 577 | static void *input_handlers_seq_next(struct seq_file *seq, void *v, loff_t *pos) |
599 | { | 578 | { |
600 | seq->private = (void *)(unsigned long)(*pos + 1); | 579 | seq->private = (void *)(unsigned long)(*pos + 1); |
601 | return list_get_next_element(&input_handler_list, v, pos); | 580 | return seq_list_next(v, &input_handler_list, pos); |
602 | } | 581 | } |
603 | 582 | ||
604 | static void input_handlers_seq_stop(struct seq_file *seq, void *v) | 583 | static void input_handlers_seq_stop(struct seq_file *seq, void *v) |
diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig index 12db72d83ea0..e2abe18e575d 100644 --- a/drivers/input/joystick/Kconfig +++ b/drivers/input/joystick/Kconfig | |||
@@ -275,4 +275,11 @@ config JOYSTICK_XPAD_FF | |||
275 | ---help--- | 275 | ---help--- |
276 | Say Y here if you want to take advantage of xbox 360 rumble features. | 276 | Say Y here if you want to take advantage of xbox 360 rumble features. |
277 | 277 | ||
278 | config JOYSTICK_XPAD_LEDS | ||
279 | bool "LED Support for Xbox360 controller 'BigX' LED" | ||
280 | depends on LEDS_CLASS && JOYSTICK_XPAD | ||
281 | ---help--- | ||
282 | This option enables support for the LED which surrounds the Big X on | ||
283 | XBox 360 controller. | ||
284 | |||
278 | endif | 285 | endif |
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 244089c52650..28080395899c 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c | |||
@@ -191,13 +191,18 @@ struct usb_xpad { | |||
191 | unsigned char *idata; /* input data */ | 191 | unsigned char *idata; /* input data */ |
192 | dma_addr_t idata_dma; | 192 | dma_addr_t idata_dma; |
193 | 193 | ||
194 | #ifdef CONFIG_JOYSTICK_XPAD_FF | 194 | #if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS) |
195 | struct urb *irq_out; /* urb for interrupt out report */ | 195 | struct urb *irq_out; /* urb for interrupt out report */ |
196 | unsigned char *odata; /* output data */ | 196 | unsigned char *odata; /* output data */ |
197 | dma_addr_t odata_dma; | 197 | dma_addr_t odata_dma; |
198 | struct mutex odata_mutex; | ||
199 | #endif | ||
200 | |||
201 | #if defined(CONFIG_JOYSTICK_XPAD_LEDS) | ||
202 | struct xpad_led *led; | ||
198 | #endif | 203 | #endif |
199 | 204 | ||
200 | char phys[65]; /* physical device path */ | 205 | char phys[64]; /* physical device path */ |
201 | 206 | ||
202 | int dpad_mapping; /* map d-pad to buttons or to axes */ | 207 | int dpad_mapping; /* map d-pad to buttons or to axes */ |
203 | int xtype; /* type of xbox device */ | 208 | int xtype; /* type of xbox device */ |
@@ -349,7 +354,7 @@ exit: | |||
349 | __FUNCTION__, retval); | 354 | __FUNCTION__, retval); |
350 | } | 355 | } |
351 | 356 | ||
352 | #ifdef CONFIG_JOYSTICK_XPAD_FF | 357 | #if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS) |
353 | static void xpad_irq_out(struct urb *urb) | 358 | static void xpad_irq_out(struct urb *urb) |
354 | { | 359 | { |
355 | int retval; | 360 | int retval; |
@@ -376,29 +381,7 @@ exit: | |||
376 | __FUNCTION__, retval); | 381 | __FUNCTION__, retval); |
377 | } | 382 | } |
378 | 383 | ||
379 | static int xpad_play_effect(struct input_dev *dev, void *data, | 384 | static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) |
380 | struct ff_effect *effect) | ||
381 | { | ||
382 | struct usb_xpad *xpad = input_get_drvdata(dev); | ||
383 | |||
384 | if (effect->type == FF_RUMBLE) { | ||
385 | __u16 strong = effect->u.rumble.strong_magnitude; | ||
386 | __u16 weak = effect->u.rumble.weak_magnitude; | ||
387 | xpad->odata[0] = 0x00; | ||
388 | xpad->odata[1] = 0x08; | ||
389 | xpad->odata[2] = 0x00; | ||
390 | xpad->odata[3] = strong / 256; | ||
391 | xpad->odata[4] = weak / 256; | ||
392 | xpad->odata[5] = 0x00; | ||
393 | xpad->odata[6] = 0x00; | ||
394 | xpad->odata[7] = 0x00; | ||
395 | usb_submit_urb(xpad->irq_out, GFP_KERNEL); | ||
396 | } | ||
397 | |||
398 | return 0; | ||
399 | } | ||
400 | |||
401 | static int xpad_init_ff(struct usb_interface *intf, struct usb_xpad *xpad) | ||
402 | { | 385 | { |
403 | struct usb_endpoint_descriptor *ep_irq_out; | 386 | struct usb_endpoint_descriptor *ep_irq_out; |
404 | int error = -ENOMEM; | 387 | int error = -ENOMEM; |
@@ -411,6 +394,8 @@ static int xpad_init_ff(struct usb_interface *intf, struct usb_xpad *xpad) | |||
411 | if (!xpad->odata) | 394 | if (!xpad->odata) |
412 | goto fail1; | 395 | goto fail1; |
413 | 396 | ||
397 | mutex_init(&xpad->odata_mutex); | ||
398 | |||
414 | xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL); | 399 | xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL); |
415 | if (!xpad->irq_out) | 400 | if (!xpad->irq_out) |
416 | goto fail2; | 401 | goto fail2; |
@@ -423,25 +408,19 @@ static int xpad_init_ff(struct usb_interface *intf, struct usb_xpad *xpad) | |||
423 | xpad->irq_out->transfer_dma = xpad->odata_dma; | 408 | xpad->irq_out->transfer_dma = xpad->odata_dma; |
424 | xpad->irq_out->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 409 | xpad->irq_out->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
425 | 410 | ||
426 | input_set_capability(xpad->dev, EV_FF, FF_RUMBLE); | ||
427 | |||
428 | error = input_ff_create_memless(xpad->dev, NULL, xpad_play_effect); | ||
429 | if (error) | ||
430 | goto fail2; | ||
431 | |||
432 | return 0; | 411 | return 0; |
433 | 412 | ||
434 | fail2: usb_buffer_free(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma); | 413 | fail2: usb_buffer_free(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma); |
435 | fail1: return error; | 414 | fail1: return error; |
436 | } | 415 | } |
437 | 416 | ||
438 | static void xpad_stop_ff(struct usb_xpad *xpad) | 417 | static void xpad_stop_output(struct usb_xpad *xpad) |
439 | { | 418 | { |
440 | if (xpad->xtype == XTYPE_XBOX360) | 419 | if (xpad->xtype == XTYPE_XBOX360) |
441 | usb_kill_urb(xpad->irq_out); | 420 | usb_kill_urb(xpad->irq_out); |
442 | } | 421 | } |
443 | 422 | ||
444 | static void xpad_deinit_ff(struct usb_xpad *xpad) | 423 | static void xpad_deinit_output(struct usb_xpad *xpad) |
445 | { | 424 | { |
446 | if (xpad->xtype == XTYPE_XBOX360) { | 425 | if (xpad->xtype == XTYPE_XBOX360) { |
447 | usb_free_urb(xpad->irq_out); | 426 | usb_free_urb(xpad->irq_out); |
@@ -449,13 +428,130 @@ static void xpad_deinit_ff(struct usb_xpad *xpad) | |||
449 | xpad->odata, xpad->odata_dma); | 428 | xpad->odata, xpad->odata_dma); |
450 | } | 429 | } |
451 | } | 430 | } |
431 | #else | ||
432 | static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) { return 0; } | ||
433 | static void xpad_deinit_output(struct usb_xpad *xpad) {} | ||
434 | static void xpad_stop_output(struct usb_xpad *xpad) {} | ||
435 | #endif | ||
436 | |||
437 | #ifdef CONFIG_JOYSTICK_XPAD_FF | ||
438 | static int xpad_play_effect(struct input_dev *dev, void *data, | ||
439 | struct ff_effect *effect) | ||
440 | { | ||
441 | struct usb_xpad *xpad = input_get_drvdata(dev); | ||
452 | 442 | ||
443 | if (effect->type == FF_RUMBLE) { | ||
444 | __u16 strong = effect->u.rumble.strong_magnitude; | ||
445 | __u16 weak = effect->u.rumble.weak_magnitude; | ||
446 | xpad->odata[0] = 0x00; | ||
447 | xpad->odata[1] = 0x08; | ||
448 | xpad->odata[2] = 0x00; | ||
449 | xpad->odata[3] = strong / 256; | ||
450 | xpad->odata[4] = weak / 256; | ||
451 | xpad->odata[5] = 0x00; | ||
452 | xpad->odata[6] = 0x00; | ||
453 | xpad->odata[7] = 0x00; | ||
454 | usb_submit_urb(xpad->irq_out, GFP_KERNEL); | ||
455 | } | ||
456 | |||
457 | return 0; | ||
458 | } | ||
459 | |||
460 | static int xpad_init_ff(struct usb_xpad *xpad) | ||
461 | { | ||
462 | input_set_capability(xpad->dev, EV_FF, FF_RUMBLE); | ||
463 | |||
464 | return input_ff_create_memless(xpad->dev, NULL, xpad_play_effect); | ||
465 | } | ||
466 | |||
467 | #else | ||
468 | static int xpad_init_ff(struct usb_xpad *xpad) { return 0; } | ||
469 | #endif | ||
470 | |||
471 | #if defined(CONFIG_JOYSTICK_XPAD_LEDS) | ||
472 | #include <linux/leds.h> | ||
473 | |||
474 | struct xpad_led { | ||
475 | char name[16]; | ||
476 | struct led_classdev led_cdev; | ||
477 | struct usb_xpad *xpad; | ||
478 | }; | ||
479 | |||
480 | static void xpad_send_led_command(struct usb_xpad *xpad, int command) | ||
481 | { | ||
482 | if (command >= 0 && command < 14) { | ||
483 | mutex_lock(&xpad->odata_mutex); | ||
484 | xpad->odata[0] = 0x01; | ||
485 | xpad->odata[1] = 0x03; | ||
486 | xpad->odata[2] = command; | ||
487 | usb_submit_urb(xpad->irq_out, GFP_KERNEL); | ||
488 | mutex_unlock(&xpad->odata_mutex); | ||
489 | } | ||
490 | } | ||
491 | |||
492 | static void xpad_led_set(struct led_classdev *led_cdev, | ||
493 | enum led_brightness value) | ||
494 | { | ||
495 | struct xpad_led *xpad_led = container_of(led_cdev, | ||
496 | struct xpad_led, led_cdev); | ||
497 | |||
498 | xpad_send_led_command(xpad_led->xpad, value); | ||
499 | } | ||
500 | |||
501 | static int xpad_led_probe(struct usb_xpad *xpad) | ||
502 | { | ||
503 | static atomic_t led_seq = ATOMIC_INIT(0); | ||
504 | long led_no; | ||
505 | struct xpad_led *led; | ||
506 | struct led_classdev *led_cdev; | ||
507 | int error; | ||
508 | |||
509 | if (xpad->xtype != XTYPE_XBOX360) | ||
510 | return 0; | ||
511 | |||
512 | xpad->led = led = kzalloc(sizeof(struct xpad_led), GFP_KERNEL); | ||
513 | if (!led) | ||
514 | return -ENOMEM; | ||
515 | |||
516 | led_no = (long)atomic_inc_return(&led_seq) - 1; | ||
517 | |||
518 | snprintf(led->name, sizeof(led->name), "xpad%ld", led_no); | ||
519 | led->xpad = xpad; | ||
520 | |||
521 | led_cdev = &led->led_cdev; | ||
522 | led_cdev->name = led->name; | ||
523 | led_cdev->brightness_set = xpad_led_set; | ||
524 | |||
525 | error = led_classdev_register(&xpad->udev->dev, led_cdev); | ||
526 | if (error) { | ||
527 | kfree(led); | ||
528 | xpad->led = NULL; | ||
529 | return error; | ||
530 | } | ||
531 | |||
532 | /* | ||
533 | * Light up the segment corresponding to controller number | ||
534 | */ | ||
535 | xpad_send_led_command(xpad, (led_no % 4) + 2); | ||
536 | |||
537 | return 0; | ||
538 | } | ||
539 | |||
540 | static void xpad_led_disconnect(struct usb_xpad *xpad) | ||
541 | { | ||
542 | struct xpad_led *xpad_led = xpad->led; | ||
543 | |||
544 | if (xpad_led) { | ||
545 | led_classdev_unregister(&xpad_led->led_cdev); | ||
546 | kfree(xpad_led->name); | ||
547 | } | ||
548 | } | ||
453 | #else | 549 | #else |
454 | static int xpad_init_ff(struct usb_interface *intf, struct usb_xpad *xpad) { return 0; } | 550 | static int xpad_led_probe(struct usb_xpad *xpad) { return 0; } |
455 | static void xpad_stop_ff(struct usb_xpad *xpad) { } | 551 | static void xpad_led_disconnect(struct usb_xpad *xpad) { } |
456 | static void xpad_deinit_ff(struct usb_xpad *xpad) { } | ||
457 | #endif | 552 | #endif |
458 | 553 | ||
554 | |||
459 | static int xpad_open(struct input_dev *dev) | 555 | static int xpad_open(struct input_dev *dev) |
460 | { | 556 | { |
461 | struct usb_xpad *xpad = input_get_drvdata(dev); | 557 | struct usb_xpad *xpad = input_get_drvdata(dev); |
@@ -472,7 +568,7 @@ static void xpad_close(struct input_dev *dev) | |||
472 | struct usb_xpad *xpad = input_get_drvdata(dev); | 568 | struct usb_xpad *xpad = input_get_drvdata(dev); |
473 | 569 | ||
474 | usb_kill_urb(xpad->irq_in); | 570 | usb_kill_urb(xpad->irq_in); |
475 | xpad_stop_ff(xpad); | 571 | xpad_stop_output(xpad); |
476 | } | 572 | } |
477 | 573 | ||
478 | static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs) | 574 | static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs) |
@@ -564,10 +660,18 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
564 | for (i = 0; xpad_abs_pad[i] >= 0; i++) | 660 | for (i = 0; xpad_abs_pad[i] >= 0; i++) |
565 | xpad_set_up_abs(input_dev, xpad_abs_pad[i]); | 661 | xpad_set_up_abs(input_dev, xpad_abs_pad[i]); |
566 | 662 | ||
567 | error = xpad_init_ff(intf, xpad); | 663 | error = xpad_init_output(intf, xpad); |
568 | if (error) | 664 | if (error) |
569 | goto fail2; | 665 | goto fail2; |
570 | 666 | ||
667 | error = xpad_init_ff(xpad); | ||
668 | if (error) | ||
669 | goto fail3; | ||
670 | |||
671 | error = xpad_led_probe(xpad); | ||
672 | if (error) | ||
673 | goto fail3; | ||
674 | |||
571 | ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; | 675 | ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; |
572 | usb_fill_int_urb(xpad->irq_in, udev, | 676 | usb_fill_int_urb(xpad->irq_in, udev, |
573 | usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), | 677 | usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), |
@@ -578,12 +682,13 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
578 | 682 | ||
579 | error = input_register_device(xpad->dev); | 683 | error = input_register_device(xpad->dev); |
580 | if (error) | 684 | if (error) |
581 | goto fail3; | 685 | goto fail4; |
582 | 686 | ||
583 | usb_set_intfdata(intf, xpad); | 687 | usb_set_intfdata(intf, xpad); |
584 | return 0; | 688 | return 0; |
585 | 689 | ||
586 | fail3: usb_free_urb(xpad->irq_in); | 690 | fail4: usb_free_urb(xpad->irq_in); |
691 | fail3: xpad_deinit_output(xpad); | ||
587 | fail2: usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); | 692 | fail2: usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); |
588 | fail1: input_free_device(input_dev); | 693 | fail1: input_free_device(input_dev); |
589 | kfree(xpad); | 694 | kfree(xpad); |
@@ -597,8 +702,9 @@ static void xpad_disconnect(struct usb_interface *intf) | |||
597 | 702 | ||
598 | usb_set_intfdata(intf, NULL); | 703 | usb_set_intfdata(intf, NULL); |
599 | if (xpad) { | 704 | if (xpad) { |
705 | xpad_led_disconnect(xpad); | ||
600 | input_unregister_device(xpad->dev); | 706 | input_unregister_device(xpad->dev); |
601 | xpad_deinit_ff(xpad); | 707 | xpad_deinit_output(xpad); |
602 | usb_free_urb(xpad->irq_in); | 708 | usb_free_urb(xpad->irq_in); |
603 | usb_buffer_free(xpad->udev, XPAD_PKT_LEN, | 709 | usb_buffer_free(xpad->udev, XPAD_PKT_LEN, |
604 | xpad->idata, xpad->idata_dma); | 710 | xpad->idata, xpad->idata_dma); |
diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c index e3215267db11..2bea1b2c631c 100644 --- a/drivers/input/mouse/appletouch.c +++ b/drivers/input/mouse/appletouch.c | |||
@@ -155,6 +155,8 @@ struct atp { | |||
155 | int xy_acc[ATP_XSENSORS + ATP_YSENSORS]; | 155 | int xy_acc[ATP_XSENSORS + ATP_YSENSORS]; |
156 | int overflowwarn; /* overflow warning printed? */ | 156 | int overflowwarn; /* overflow warning printed? */ |
157 | int datalen; /* size of an USB urb transfer */ | 157 | int datalen; /* size of an USB urb transfer */ |
158 | int idlecount; /* number of empty packets */ | ||
159 | struct work_struct work; | ||
158 | }; | 160 | }; |
159 | 161 | ||
160 | #define dbg_dump(msg, tab) \ | 162 | #define dbg_dump(msg, tab) \ |
@@ -208,6 +210,55 @@ static inline int atp_is_geyser_3(struct atp *dev) | |||
208 | (productId == GEYSER4_JIS_PRODUCT_ID); | 210 | (productId == GEYSER4_JIS_PRODUCT_ID); |
209 | } | 211 | } |
210 | 212 | ||
213 | /* | ||
214 | * By default Geyser 3 device sends standard USB HID mouse | ||
215 | * packets (Report ID 2). This code changes device mode, so it | ||
216 | * sends raw sensor reports (Report ID 5). | ||
217 | */ | ||
218 | static int atp_geyser3_init(struct usb_device *udev) | ||
219 | { | ||
220 | char data[8]; | ||
221 | int size; | ||
222 | |||
223 | size = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), | ||
224 | ATP_GEYSER3_MODE_READ_REQUEST_ID, | ||
225 | USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | ||
226 | ATP_GEYSER3_MODE_REQUEST_VALUE, | ||
227 | ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000); | ||
228 | |||
229 | if (size != 8) { | ||
230 | err("Could not do mode read request from device" | ||
231 | " (Geyser 3 mode)"); | ||
232 | return -EIO; | ||
233 | } | ||
234 | |||
235 | /* Apply the mode switch */ | ||
236 | data[0] = ATP_GEYSER3_MODE_VENDOR_VALUE; | ||
237 | |||
238 | size = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
239 | ATP_GEYSER3_MODE_WRITE_REQUEST_ID, | ||
240 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | ||
241 | ATP_GEYSER3_MODE_REQUEST_VALUE, | ||
242 | ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000); | ||
243 | |||
244 | if (size != 8) { | ||
245 | err("Could not do mode write request to device" | ||
246 | " (Geyser 3 mode)"); | ||
247 | return -EIO; | ||
248 | } | ||
249 | return 0; | ||
250 | } | ||
251 | |||
252 | /* Reinitialise the device if it's a geyser 3 */ | ||
253 | static void atp_reinit(struct work_struct *work) | ||
254 | { | ||
255 | struct atp *dev = container_of(work, struct atp, work); | ||
256 | struct usb_device *udev = dev->udev; | ||
257 | |||
258 | dev->idlecount = 0; | ||
259 | atp_geyser3_init(udev); | ||
260 | } | ||
261 | |||
211 | static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact, | 262 | static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact, |
212 | int *z, int *fingers) | 263 | int *z, int *fingers) |
213 | { | 264 | { |
@@ -439,8 +490,8 @@ static void atp_complete(struct urb* urb) | |||
439 | } | 490 | } |
440 | dev->x_old = x; | 491 | dev->x_old = x; |
441 | dev->y_old = y; | 492 | dev->y_old = y; |
442 | } | 493 | |
443 | else if (!x && !y) { | 494 | } else if (!x && !y) { |
444 | 495 | ||
445 | dev->x_old = dev->y_old = -1; | 496 | dev->x_old = dev->y_old = -1; |
446 | input_report_key(dev->input, BTN_TOUCH, 0); | 497 | input_report_key(dev->input, BTN_TOUCH, 0); |
@@ -449,11 +500,21 @@ static void atp_complete(struct urb* urb) | |||
449 | 500 | ||
450 | /* reset the accumulator on release */ | 501 | /* reset the accumulator on release */ |
451 | memset(dev->xy_acc, 0, sizeof(dev->xy_acc)); | 502 | memset(dev->xy_acc, 0, sizeof(dev->xy_acc)); |
452 | } | ||
453 | 503 | ||
454 | input_report_key(dev->input, BTN_LEFT, | 504 | /* Geyser 3 will continue to send packets continually after |
455 | !!dev->data[dev->datalen - 1]); | 505 | the first touch unless reinitialised. Do so if it's been |
506 | idle for a while in order to avoid waking the kernel up | ||
507 | several hundred times a second */ | ||
508 | if (atp_is_geyser_3(dev)) { | ||
509 | dev->idlecount++; | ||
510 | if (dev->idlecount == 10) { | ||
511 | dev->valid = 0; | ||
512 | schedule_work(&dev->work); | ||
513 | } | ||
514 | } | ||
515 | } | ||
456 | 516 | ||
517 | input_report_key(dev->input, BTN_LEFT, dev->data[dev->datalen - 1] & 1); | ||
457 | input_sync(dev->input); | 518 | input_sync(dev->input); |
458 | 519 | ||
459 | exit: | 520 | exit: |
@@ -480,6 +541,7 @@ static void atp_close(struct input_dev *input) | |||
480 | struct atp *dev = input_get_drvdata(input); | 541 | struct atp *dev = input_get_drvdata(input); |
481 | 542 | ||
482 | usb_kill_urb(dev->urb); | 543 | usb_kill_urb(dev->urb); |
544 | cancel_work_sync(&dev->work); | ||
483 | dev->open = 0; | 545 | dev->open = 0; |
484 | } | 546 | } |
485 | 547 | ||
@@ -528,40 +590,10 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id | |||
528 | dev->datalen = 81; | 590 | dev->datalen = 81; |
529 | 591 | ||
530 | if (atp_is_geyser_3(dev)) { | 592 | if (atp_is_geyser_3(dev)) { |
531 | /* | 593 | /* switch to raw sensor mode */ |
532 | * By default Geyser 3 device sends standard USB HID mouse | 594 | if (atp_geyser3_init(udev)) |
533 | * packets (Report ID 2). This code changes device mode, so it | ||
534 | * sends raw sensor reports (Report ID 5). | ||
535 | */ | ||
536 | char data[8]; | ||
537 | int size; | ||
538 | |||
539 | size = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), | ||
540 | ATP_GEYSER3_MODE_READ_REQUEST_ID, | ||
541 | USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | ||
542 | ATP_GEYSER3_MODE_REQUEST_VALUE, | ||
543 | ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000); | ||
544 | |||
545 | if (size != 8) { | ||
546 | err("Could not do mode read request from device" | ||
547 | " (Geyser 3 mode)"); | ||
548 | goto err_free_devs; | 595 | goto err_free_devs; |
549 | } | ||
550 | |||
551 | /* Apply the mode switch */ | ||
552 | data[0] = ATP_GEYSER3_MODE_VENDOR_VALUE; | ||
553 | |||
554 | size = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
555 | ATP_GEYSER3_MODE_WRITE_REQUEST_ID, | ||
556 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | ||
557 | ATP_GEYSER3_MODE_REQUEST_VALUE, | ||
558 | ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000); | ||
559 | 596 | ||
560 | if (size != 8) { | ||
561 | err("Could not do mode write request to device" | ||
562 | " (Geyser 3 mode)"); | ||
563 | goto err_free_devs; | ||
564 | } | ||
565 | printk("appletouch Geyser 3 inited.\n"); | 597 | printk("appletouch Geyser 3 inited.\n"); |
566 | } | 598 | } |
567 | 599 | ||
@@ -636,6 +668,8 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id | |||
636 | /* save our data pointer in this interface device */ | 668 | /* save our data pointer in this interface device */ |
637 | usb_set_intfdata(iface, dev); | 669 | usb_set_intfdata(iface, dev); |
638 | 670 | ||
671 | INIT_WORK(&dev->work, atp_reinit); | ||
672 | |||
639 | return 0; | 673 | return 0; |
640 | 674 | ||
641 | err_free_buffer: | 675 | err_free_buffer: |
@@ -669,14 +703,17 @@ static void atp_disconnect(struct usb_interface *iface) | |||
669 | static int atp_suspend(struct usb_interface *iface, pm_message_t message) | 703 | static int atp_suspend(struct usb_interface *iface, pm_message_t message) |
670 | { | 704 | { |
671 | struct atp *dev = usb_get_intfdata(iface); | 705 | struct atp *dev = usb_get_intfdata(iface); |
706 | |||
672 | usb_kill_urb(dev->urb); | 707 | usb_kill_urb(dev->urb); |
673 | dev->valid = 0; | 708 | dev->valid = 0; |
709 | |||
674 | return 0; | 710 | return 0; |
675 | } | 711 | } |
676 | 712 | ||
677 | static int atp_resume(struct usb_interface *iface) | 713 | static int atp_resume(struct usb_interface *iface) |
678 | { | 714 | { |
679 | struct atp *dev = usb_get_intfdata(iface); | 715 | struct atp *dev = usb_get_intfdata(iface); |
716 | |||
680 | if (dev->open && usb_submit_urb(dev->urb, GFP_ATOMIC)) | 717 | if (dev->open && usb_submit_urb(dev->urb, GFP_ATOMIC)) |
681 | return -EIO; | 718 | return -EIO; |
682 | 719 | ||
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c index 1740cadd9594..91109b49fde1 100644 --- a/drivers/input/mouse/lifebook.c +++ b/drivers/input/mouse/lifebook.c | |||
@@ -109,7 +109,7 @@ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) | |||
109 | { | 109 | { |
110 | struct lifebook_data *priv = psmouse->private; | 110 | struct lifebook_data *priv = psmouse->private; |
111 | struct input_dev *dev1 = psmouse->dev; | 111 | struct input_dev *dev1 = psmouse->dev; |
112 | struct input_dev *dev2 = priv->dev2; | 112 | struct input_dev *dev2 = priv ? priv->dev2 : NULL; |
113 | unsigned char *packet = psmouse->packet; | 113 | unsigned char *packet = psmouse->packet; |
114 | int relative_packet = packet[0] & 0x08; | 114 | int relative_packet = packet[0] & 0x08; |
115 | 115 | ||
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 4fca1e7f2678..702a526cf45b 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
@@ -366,6 +366,7 @@ static void i8042_pnp_exit(void) | |||
366 | static int __init i8042_pnp_init(void) | 366 | static int __init i8042_pnp_init(void) |
367 | { | 367 | { |
368 | char kbd_irq_str[4] = { 0 }, aux_irq_str[4] = { 0 }; | 368 | char kbd_irq_str[4] = { 0 }, aux_irq_str[4] = { 0 }; |
369 | int pnp_data_busted = 0; | ||
369 | int err; | 370 | int err; |
370 | 371 | ||
371 | if (i8042_nopnp) { | 372 | if (i8042_nopnp) { |
@@ -413,27 +414,48 @@ static int __init i8042_pnp_init(void) | |||
413 | #endif | 414 | #endif |
414 | 415 | ||
415 | if (((i8042_pnp_data_reg & ~0xf) == (i8042_data_reg & ~0xf) && | 416 | if (((i8042_pnp_data_reg & ~0xf) == (i8042_data_reg & ~0xf) && |
416 | i8042_pnp_data_reg != i8042_data_reg) || !i8042_pnp_data_reg) { | 417 | i8042_pnp_data_reg != i8042_data_reg) || |
417 | printk(KERN_WARNING "PNP: PS/2 controller has invalid data port %#x; using default %#x\n", | 418 | !i8042_pnp_data_reg) { |
419 | printk(KERN_WARNING | ||
420 | "PNP: PS/2 controller has invalid data port %#x; " | ||
421 | "using default %#x\n", | ||
418 | i8042_pnp_data_reg, i8042_data_reg); | 422 | i8042_pnp_data_reg, i8042_data_reg); |
419 | i8042_pnp_data_reg = i8042_data_reg; | 423 | i8042_pnp_data_reg = i8042_data_reg; |
424 | pnp_data_busted = 1; | ||
420 | } | 425 | } |
421 | 426 | ||
422 | if (((i8042_pnp_command_reg & ~0xf) == (i8042_command_reg & ~0xf) && | 427 | if (((i8042_pnp_command_reg & ~0xf) == (i8042_command_reg & ~0xf) && |
423 | i8042_pnp_command_reg != i8042_command_reg) || !i8042_pnp_command_reg) { | 428 | i8042_pnp_command_reg != i8042_command_reg) || |
424 | printk(KERN_WARNING "PNP: PS/2 controller has invalid command port %#x; using default %#x\n", | 429 | !i8042_pnp_command_reg) { |
430 | printk(KERN_WARNING | ||
431 | "PNP: PS/2 controller has invalid command port %#x; " | ||
432 | "using default %#x\n", | ||
425 | i8042_pnp_command_reg, i8042_command_reg); | 433 | i8042_pnp_command_reg, i8042_command_reg); |
426 | i8042_pnp_command_reg = i8042_command_reg; | 434 | i8042_pnp_command_reg = i8042_command_reg; |
435 | pnp_data_busted = 1; | ||
427 | } | 436 | } |
428 | 437 | ||
429 | if (!i8042_nokbd && !i8042_pnp_kbd_irq) { | 438 | if (!i8042_nokbd && !i8042_pnp_kbd_irq) { |
430 | printk(KERN_WARNING "PNP: PS/2 controller doesn't have KBD irq; using default %d\n", i8042_kbd_irq); | 439 | printk(KERN_WARNING |
440 | "PNP: PS/2 controller doesn't have KBD irq; " | ||
441 | "using default %d\n", i8042_kbd_irq); | ||
431 | i8042_pnp_kbd_irq = i8042_kbd_irq; | 442 | i8042_pnp_kbd_irq = i8042_kbd_irq; |
443 | pnp_data_busted = 1; | ||
432 | } | 444 | } |
433 | 445 | ||
434 | if (!i8042_noaux && !i8042_pnp_aux_irq) { | 446 | if (!i8042_noaux && !i8042_pnp_aux_irq) { |
435 | printk(KERN_WARNING "PNP: PS/2 controller doesn't have AUX irq; using default %d\n", i8042_aux_irq); | 447 | if (!pnp_data_busted && i8042_pnp_kbd_irq) { |
436 | i8042_pnp_aux_irq = i8042_aux_irq; | 448 | printk(KERN_WARNING |
449 | "PNP: PS/2 appears to have AUX port disabled, " | ||
450 | "if this is incorrect please boot with " | ||
451 | "i8042.nopnp\n"); | ||
452 | i8042_noaux = 1; | ||
453 | } else { | ||
454 | printk(KERN_WARNING | ||
455 | "PNP: PS/2 controller doesn't have AUX irq; " | ||
456 | "using default %d\n", i8042_aux_irq); | ||
457 | i8042_pnp_aux_irq = i8042_aux_irq; | ||
458 | } | ||
437 | } | 459 | } |
438 | 460 | ||
439 | i8042_data_reg = i8042_pnp_data_reg; | 461 | i8042_data_reg = i8042_pnp_data_reg; |
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 69371779806a..f929fcdbae2e 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
@@ -54,6 +54,19 @@ config TOUCHSCREEN_CORGI | |||
54 | To compile this driver as a module, choose M here: the | 54 | To compile this driver as a module, choose M here: the |
55 | module will be called corgi_ts. | 55 | module will be called corgi_ts. |
56 | 56 | ||
57 | config TOUCHSCREEN_FUJITSU | ||
58 | tristate "Fujitsu serial touchscreen" | ||
59 | select SERIO | ||
60 | help | ||
61 | Say Y here if you have the Fujitsu touchscreen (such as one | ||
62 | installed in Lifebook P series laptop) connected to your | ||
63 | system. | ||
64 | |||
65 | If unsure, say N. | ||
66 | |||
67 | To compile this driver as a module, choose M here: the | ||
68 | module will be called fujitsu-ts. | ||
69 | |||
57 | config TOUCHSCREEN_GUNZE | 70 | config TOUCHSCREEN_GUNZE |
58 | tristate "Gunze AHL-51S touchscreen" | 71 | tristate "Gunze AHL-51S touchscreen" |
59 | select SERIO | 72 | select SERIO |
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 2f86d6ad06d3..5de8933c4993 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile | |||
@@ -9,6 +9,7 @@ obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o | |||
9 | obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o | 9 | obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o |
10 | obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o | 10 | obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o |
11 | obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o | 11 | obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o |
12 | obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o | ||
12 | obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o | 13 | obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o |
13 | obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o | 14 | obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o |
14 | obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o | 15 | obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o |
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 1c9069cd3bae..96581d08774f 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
@@ -95,7 +95,7 @@ struct ads7846 { | |||
95 | u16 dummy; /* for the pwrdown read */ | 95 | u16 dummy; /* for the pwrdown read */ |
96 | struct ts_event tc; | 96 | struct ts_event tc; |
97 | 97 | ||
98 | struct spi_transfer xfer[10]; | 98 | struct spi_transfer xfer[18]; |
99 | struct spi_message msg[5]; | 99 | struct spi_message msg[5]; |
100 | struct spi_message *last_msg; | 100 | struct spi_message *last_msg; |
101 | int msg_idx; | 101 | int msg_idx; |
@@ -107,6 +107,8 @@ struct ads7846 { | |||
107 | u16 debounce_tol; | 107 | u16 debounce_tol; |
108 | u16 debounce_rep; | 108 | u16 debounce_rep; |
109 | 109 | ||
110 | u16 penirq_recheck_delay_usecs; | ||
111 | |||
110 | spinlock_t lock; | 112 | spinlock_t lock; |
111 | struct hrtimer timer; | 113 | struct hrtimer timer; |
112 | unsigned pendown:1; /* P: lock */ | 114 | unsigned pendown:1; /* P: lock */ |
@@ -553,6 +555,15 @@ static void ads7846_rx(void *ads) | |||
553 | return; | 555 | return; |
554 | } | 556 | } |
555 | 557 | ||
558 | /* Maybe check the pendown state before reporting. This discards | ||
559 | * false readings when the pen is lifted. | ||
560 | */ | ||
561 | if (ts->penirq_recheck_delay_usecs) { | ||
562 | udelay(ts->penirq_recheck_delay_usecs); | ||
563 | if (!ts->get_pendown_state()) | ||
564 | Rt = 0; | ||
565 | } | ||
566 | |||
556 | /* NOTE: We can't rely on the pressure to determine the pen down | 567 | /* NOTE: We can't rely on the pressure to determine the pen down |
557 | * state, even this controller has a pressure sensor. The pressure | 568 | * state, even this controller has a pressure sensor. The pressure |
558 | * value can fluctuate for quite a while after lifting the pen and | 569 | * value can fluctuate for quite a while after lifting the pen and |
@@ -896,6 +907,10 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
896 | ts->filter = ads7846_no_filter; | 907 | ts->filter = ads7846_no_filter; |
897 | ts->get_pendown_state = pdata->get_pendown_state; | 908 | ts->get_pendown_state = pdata->get_pendown_state; |
898 | 909 | ||
910 | if (pdata->penirq_recheck_delay_usecs) | ||
911 | ts->penirq_recheck_delay_usecs = | ||
912 | pdata->penirq_recheck_delay_usecs; | ||
913 | |||
899 | snprintf(ts->phys, sizeof(ts->phys), "%s/input0", spi->dev.bus_id); | 914 | snprintf(ts->phys, sizeof(ts->phys), "%s/input0", spi->dev.bus_id); |
900 | 915 | ||
901 | input_dev->name = "ADS784x Touchscreen"; | 916 | input_dev->name = "ADS784x Touchscreen"; |
@@ -936,6 +951,24 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
936 | x->len = 2; | 951 | x->len = 2; |
937 | spi_message_add_tail(x, m); | 952 | spi_message_add_tail(x, m); |
938 | 953 | ||
954 | /* the first sample after switching drivers can be low quality; | ||
955 | * optionally discard it, using a second one after the signals | ||
956 | * have had enough time to stabilize. | ||
957 | */ | ||
958 | if (pdata->settle_delay_usecs) { | ||
959 | x->delay_usecs = pdata->settle_delay_usecs; | ||
960 | |||
961 | x++; | ||
962 | x->tx_buf = &ts->read_y; | ||
963 | x->len = 1; | ||
964 | spi_message_add_tail(x, m); | ||
965 | |||
966 | x++; | ||
967 | x->rx_buf = &ts->tc.y; | ||
968 | x->len = 2; | ||
969 | spi_message_add_tail(x, m); | ||
970 | } | ||
971 | |||
939 | m->complete = ads7846_rx_val; | 972 | m->complete = ads7846_rx_val; |
940 | m->context = ts; | 973 | m->context = ts; |
941 | 974 | ||
@@ -954,6 +987,21 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
954 | x->len = 2; | 987 | x->len = 2; |
955 | spi_message_add_tail(x, m); | 988 | spi_message_add_tail(x, m); |
956 | 989 | ||
990 | /* ... maybe discard first sample ... */ | ||
991 | if (pdata->settle_delay_usecs) { | ||
992 | x->delay_usecs = pdata->settle_delay_usecs; | ||
993 | |||
994 | x++; | ||
995 | x->tx_buf = &ts->read_x; | ||
996 | x->len = 1; | ||
997 | spi_message_add_tail(x, m); | ||
998 | |||
999 | x++; | ||
1000 | x->rx_buf = &ts->tc.x; | ||
1001 | x->len = 2; | ||
1002 | spi_message_add_tail(x, m); | ||
1003 | } | ||
1004 | |||
957 | m->complete = ads7846_rx_val; | 1005 | m->complete = ads7846_rx_val; |
958 | m->context = ts; | 1006 | m->context = ts; |
959 | 1007 | ||
@@ -973,6 +1021,21 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
973 | x->len = 2; | 1021 | x->len = 2; |
974 | spi_message_add_tail(x, m); | 1022 | spi_message_add_tail(x, m); |
975 | 1023 | ||
1024 | /* ... maybe discard first sample ... */ | ||
1025 | if (pdata->settle_delay_usecs) { | ||
1026 | x->delay_usecs = pdata->settle_delay_usecs; | ||
1027 | |||
1028 | x++; | ||
1029 | x->tx_buf = &ts->read_z1; | ||
1030 | x->len = 1; | ||
1031 | spi_message_add_tail(x, m); | ||
1032 | |||
1033 | x++; | ||
1034 | x->rx_buf = &ts->tc.z1; | ||
1035 | x->len = 2; | ||
1036 | spi_message_add_tail(x, m); | ||
1037 | } | ||
1038 | |||
976 | m->complete = ads7846_rx_val; | 1039 | m->complete = ads7846_rx_val; |
977 | m->context = ts; | 1040 | m->context = ts; |
978 | 1041 | ||
@@ -990,6 +1053,21 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
990 | x->len = 2; | 1053 | x->len = 2; |
991 | spi_message_add_tail(x, m); | 1054 | spi_message_add_tail(x, m); |
992 | 1055 | ||
1056 | /* ... maybe discard first sample ... */ | ||
1057 | if (pdata->settle_delay_usecs) { | ||
1058 | x->delay_usecs = pdata->settle_delay_usecs; | ||
1059 | |||
1060 | x++; | ||
1061 | x->tx_buf = &ts->read_z2; | ||
1062 | x->len = 1; | ||
1063 | spi_message_add_tail(x, m); | ||
1064 | |||
1065 | x++; | ||
1066 | x->rx_buf = &ts->tc.z2; | ||
1067 | x->len = 2; | ||
1068 | spi_message_add_tail(x, m); | ||
1069 | } | ||
1070 | |||
993 | m->complete = ads7846_rx_val; | 1071 | m->complete = ads7846_rx_val; |
994 | m->context = ts; | 1072 | m->context = ts; |
995 | } | 1073 | } |
diff --git a/drivers/input/touchscreen/fujitsu_ts.c b/drivers/input/touchscreen/fujitsu_ts.c new file mode 100644 index 000000000000..daf7a4afc935 --- /dev/null +++ b/drivers/input/touchscreen/fujitsu_ts.c | |||
@@ -0,0 +1,189 @@ | |||
1 | /* | ||
2 | * Fujitsu serial touchscreen driver | ||
3 | * | ||
4 | * Copyright (c) Dmitry Torokhov <dtor@mail.ru> | ||
5 | */ | ||
6 | |||
7 | /* | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License version 2 as published | ||
10 | * by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/errno.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <linux/input.h> | ||
18 | #include <linux/serio.h> | ||
19 | #include <linux/init.h> | ||
20 | |||
21 | #define DRIVER_DESC "Fujitsu serial touchscreen driver" | ||
22 | |||
23 | MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>"); | ||
24 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
25 | MODULE_LICENSE("GPL"); | ||
26 | |||
27 | #define FUJITSU_LENGTH 5 | ||
28 | |||
29 | /* | ||
30 | * Per-touchscreen data. | ||
31 | */ | ||
32 | struct fujitsu { | ||
33 | struct input_dev *dev; | ||
34 | struct serio *serio; | ||
35 | int idx; | ||
36 | unsigned char data[FUJITSU_LENGTH]; | ||
37 | char phys[32]; | ||
38 | }; | ||
39 | |||
40 | /* | ||
41 | * Decode serial data (5 bytes per packet) | ||
42 | * First byte | ||
43 | * 1 C 0 0 R S S S | ||
44 | * Where C is 1 while in calibration mode (which we don't use) | ||
45 | * R is 1 when no coordinate corection was done. | ||
46 | * S are button state | ||
47 | */ | ||
48 | static irqreturn_t fujitsu_interrupt(struct serio *serio, | ||
49 | unsigned char data, unsigned int flags) | ||
50 | { | ||
51 | struct fujitsu *fujitsu = serio_get_drvdata(serio); | ||
52 | struct input_dev *dev = fujitsu->dev; | ||
53 | |||
54 | if (fujitsu->idx == 0) { | ||
55 | /* resync skip until start of frame */ | ||
56 | if ((data & 0xf0) != 0x80) | ||
57 | return IRQ_HANDLED; | ||
58 | } else { | ||
59 | /* resync skip garbage */ | ||
60 | if (data & 0x80) { | ||
61 | fujitsu->idx = 0; | ||
62 | return IRQ_HANDLED; | ||
63 | } | ||
64 | } | ||
65 | |||
66 | fujitsu->data[fujitsu->idx++] = data; | ||
67 | if (fujitsu->idx == FUJITSU_LENGTH) { | ||
68 | input_report_abs(dev, ABS_X, | ||
69 | (fujitsu->data[2] << 7) | fujitsu->data[1]); | ||
70 | input_report_abs(dev, ABS_Y, | ||
71 | (fujitsu->data[4] << 7) | fujitsu->data[3]); | ||
72 | input_report_key(dev, BTN_TOUCH, | ||
73 | (fujitsu->data[0] & 0x03) != 2); | ||
74 | input_sync(dev); | ||
75 | fujitsu->idx = 0; | ||
76 | } | ||
77 | |||
78 | return IRQ_HANDLED; | ||
79 | } | ||
80 | |||
81 | /* | ||
82 | * fujitsu_disconnect() is the opposite of fujitsu_connect() | ||
83 | */ | ||
84 | static void fujitsu_disconnect(struct serio *serio) | ||
85 | { | ||
86 | struct fujitsu *fujitsu = serio_get_drvdata(serio); | ||
87 | |||
88 | input_get_device(fujitsu->dev); | ||
89 | input_unregister_device(fujitsu->dev); | ||
90 | serio_close(serio); | ||
91 | serio_set_drvdata(serio, NULL); | ||
92 | input_put_device(fujitsu->dev); | ||
93 | kfree(fujitsu); | ||
94 | } | ||
95 | |||
96 | /* | ||
97 | * fujitsu_connect() is the routine that is called when someone adds a | ||
98 | * new serio device that supports the Fujitsu protocol and registers it | ||
99 | * as input device. | ||
100 | */ | ||
101 | static int fujitsu_connect(struct serio *serio, struct serio_driver *drv) | ||
102 | { | ||
103 | struct fujitsu *fujitsu; | ||
104 | struct input_dev *input_dev; | ||
105 | int err; | ||
106 | |||
107 | fujitsu = kzalloc(sizeof(struct fujitsu), GFP_KERNEL); | ||
108 | input_dev = input_allocate_device(); | ||
109 | if (!fujitsu || !input_dev) { | ||
110 | err = -ENOMEM; | ||
111 | goto fail1; | ||
112 | } | ||
113 | |||
114 | fujitsu->serio = serio; | ||
115 | fujitsu->dev = input_dev; | ||
116 | snprintf(fujitsu->phys, sizeof(fujitsu->phys), | ||
117 | "%s/input0", serio->phys); | ||
118 | |||
119 | input_dev->name = "Fujitsu Serial Touchscreen"; | ||
120 | input_dev->phys = fujitsu->phys; | ||
121 | input_dev->id.bustype = BUS_RS232; | ||
122 | input_dev->id.vendor = SERIO_FUJITSU; | ||
123 | input_dev->id.product = 0; | ||
124 | input_dev->id.version = 0x0100; | ||
125 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | ||
126 | input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); | ||
127 | |||
128 | input_set_abs_params(input_dev, ABS_X, 0, 4096, 0, 0); | ||
129 | input_set_abs_params(input_dev, ABS_Y, 0, 4096, 0, 0); | ||
130 | serio_set_drvdata(serio, fujitsu); | ||
131 | |||
132 | err = serio_open(serio, drv); | ||
133 | if (err) | ||
134 | goto fail2; | ||
135 | |||
136 | err = input_register_device(fujitsu->dev); | ||
137 | if (err) | ||
138 | goto fail3; | ||
139 | |||
140 | return 0; | ||
141 | |||
142 | fail3: | ||
143 | serio_close(serio); | ||
144 | fail2: | ||
145 | serio_set_drvdata(serio, NULL); | ||
146 | fail1: | ||
147 | input_free_device(input_dev); | ||
148 | kfree(fujitsu); | ||
149 | return err; | ||
150 | } | ||
151 | |||
152 | /* | ||
153 | * The serio driver structure. | ||
154 | */ | ||
155 | static struct serio_device_id fujitsu_serio_ids[] = { | ||
156 | { | ||
157 | .type = SERIO_RS232, | ||
158 | .proto = SERIO_FUJITSU, | ||
159 | .id = SERIO_ANY, | ||
160 | .extra = SERIO_ANY, | ||
161 | }, | ||
162 | { 0 } | ||
163 | }; | ||
164 | |||
165 | MODULE_DEVICE_TABLE(serio, fujitsu_serio_ids); | ||
166 | |||
167 | static struct serio_driver fujitsu_drv = { | ||
168 | .driver = { | ||
169 | .name = "fujitsu_ts", | ||
170 | }, | ||
171 | .description = DRIVER_DESC, | ||
172 | .id_table = fujitsu_serio_ids, | ||
173 | .interrupt = fujitsu_interrupt, | ||
174 | .connect = fujitsu_connect, | ||
175 | .disconnect = fujitsu_disconnect, | ||
176 | }; | ||
177 | |||
178 | static int __init fujitsu_init(void) | ||
179 | { | ||
180 | return serio_register_driver(&fujitsu_drv); | ||
181 | } | ||
182 | |||
183 | static void __exit fujitsu_exit(void) | ||
184 | { | ||
185 | serio_unregister_driver(&fujitsu_drv); | ||
186 | } | ||
187 | |||
188 | module_init(fujitsu_init); | ||
189 | module_exit(fujitsu_exit); | ||
diff --git a/drivers/lguest/interrupts_and_traps.c b/drivers/lguest/interrupts_and_traps.c index d9de5bbc613f..bee029bb2c7b 100644 --- a/drivers/lguest/interrupts_and_traps.c +++ b/drivers/lguest/interrupts_and_traps.c | |||
@@ -38,12 +38,12 @@ static void set_guest_interrupt(struct lguest *lg, u32 lo, u32 hi, int has_err) | |||
38 | ss = lg->regs->ss; | 38 | ss = lg->regs->ss; |
39 | } | 39 | } |
40 | 40 | ||
41 | /* We use IF bit in eflags to indicate whether irqs were disabled | 41 | /* We use IF bit in eflags to indicate whether irqs were enabled |
42 | (it's always 0, since irqs are enabled when guest is running). */ | 42 | (it's always 1, since irqs are enabled when guest is running). */ |
43 | eflags = lg->regs->eflags; | 43 | eflags = lg->regs->eflags; |
44 | if (get_user(irq_enable, &lg->lguest_data->irq_enabled)) | 44 | if (get_user(irq_enable, &lg->lguest_data->irq_enabled) == 0 |
45 | irq_enable = 0; | 45 | && !(irq_enable & X86_EFLAGS_IF)) |
46 | eflags |= (irq_enable & X86_EFLAGS_IF); | 46 | eflags &= ~X86_EFLAGS_IF; |
47 | 47 | ||
48 | push_guest_stack(lg, &gstack, eflags); | 48 | push_guest_stack(lg, &gstack, eflags); |
49 | push_guest_stack(lg, &gstack, lg->regs->cs); | 49 | push_guest_stack(lg, &gstack, lg->regs->cs); |
diff --git a/drivers/lguest/io.c b/drivers/lguest/io.c index 06bdba2337ef..c8eb79266991 100644 --- a/drivers/lguest/io.c +++ b/drivers/lguest/io.c | |||
@@ -187,7 +187,7 @@ static u32 copy_data(struct lguest *srclg, | |||
187 | /* FIXME: This is not completely portable, since | 187 | /* FIXME: This is not completely portable, since |
188 | archs do different things for copy_to_user_page. */ | 188 | archs do different things for copy_to_user_page. */ |
189 | if (copy_from_user(maddr + (dst->addr[di] + dstoff)%PAGE_SIZE, | 189 | if (copy_from_user(maddr + (dst->addr[di] + dstoff)%PAGE_SIZE, |
190 | (void *__user)src->addr[si], len) != 0) { | 190 | (void __user *)src->addr[si], len) != 0) { |
191 | kill_guest(srclg, "bad address in sending DMA"); | 191 | kill_guest(srclg, "bad address in sending DMA"); |
192 | totlen = 0; | 192 | totlen = 0; |
193 | break; | 193 | break; |
diff --git a/drivers/lguest/lguest.c b/drivers/lguest/lguest.c index b9a58b78c990..434fea1e82f7 100644 --- a/drivers/lguest/lguest.c +++ b/drivers/lguest/lguest.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #include <asm/e820.h> | 39 | #include <asm/e820.h> |
40 | #include <asm/mce.h> | 40 | #include <asm/mce.h> |
41 | #include <asm/io.h> | 41 | #include <asm/io.h> |
42 | //#include <asm/sched-clock.h> | ||
43 | 42 | ||
44 | /* Declarations for definitions in lguest_guest.S */ | 43 | /* Declarations for definitions in lguest_guest.S */ |
45 | extern char lguest_noirq_start[], lguest_noirq_end[]; | 44 | extern char lguest_noirq_start[], lguest_noirq_end[]; |
@@ -57,6 +56,7 @@ struct lguest_data lguest_data = { | |||
57 | .blocked_interrupts = { 1 }, /* Block timer interrupts */ | 56 | .blocked_interrupts = { 1 }, /* Block timer interrupts */ |
58 | }; | 57 | }; |
59 | struct lguest_device_desc *lguest_devices; | 58 | struct lguest_device_desc *lguest_devices; |
59 | static cycle_t clock_base; | ||
60 | 60 | ||
61 | static enum paravirt_lazy_mode lazy_mode; | 61 | static enum paravirt_lazy_mode lazy_mode; |
62 | static void lguest_lazy_mode(enum paravirt_lazy_mode mode) | 62 | static void lguest_lazy_mode(enum paravirt_lazy_mode mode) |
@@ -363,6 +363,11 @@ static struct clocksource lguest_clock = { | |||
363 | .read = lguest_clock_read, | 363 | .read = lguest_clock_read, |
364 | }; | 364 | }; |
365 | 365 | ||
366 | static unsigned long long lguest_sched_clock(void) | ||
367 | { | ||
368 | return cyc2ns(&lguest_clock, lguest_clock_read() - clock_base); | ||
369 | } | ||
370 | |||
366 | /* We also need a "struct clock_event_device": Linux asks us to set it to go | 371 | /* We also need a "struct clock_event_device": Linux asks us to set it to go |
367 | * off some time in the future. Actually, James Morris figured all this out, I | 372 | * off some time in the future. Actually, James Morris figured all this out, I |
368 | * just applied the patch. */ | 373 | * just applied the patch. */ |
@@ -439,6 +444,7 @@ static void lguest_time_init(void) | |||
439 | lguest_clock.mult = (((u64)NSEC_PER_SEC<<8)/ACTHZ) << 8; | 444 | lguest_clock.mult = (((u64)NSEC_PER_SEC<<8)/ACTHZ) << 8; |
440 | lguest_clock.mask = CLOCKSOURCE_MASK(32); | 445 | lguest_clock.mask = CLOCKSOURCE_MASK(32); |
441 | } | 446 | } |
447 | clock_base = lguest_clock_read(); | ||
442 | clocksource_register(&lguest_clock); | 448 | clocksource_register(&lguest_clock); |
443 | 449 | ||
444 | /* We can't set cpumask in the initializer: damn C limitations! */ | 450 | /* We can't set cpumask in the initializer: damn C limitations! */ |
@@ -584,6 +590,7 @@ __init void lguest_init(void *boot) | |||
584 | paravirt_ops.time_init = lguest_time_init; | 590 | paravirt_ops.time_init = lguest_time_init; |
585 | paravirt_ops.set_lazy_mode = lguest_lazy_mode; | 591 | paravirt_ops.set_lazy_mode = lguest_lazy_mode; |
586 | paravirt_ops.wbinvd = lguest_wbinvd; | 592 | paravirt_ops.wbinvd = lguest_wbinvd; |
593 | paravirt_ops.sched_clock = lguest_sched_clock; | ||
587 | 594 | ||
588 | hcall(LHCALL_LGUEST_INIT, __pa(&lguest_data), 0, 0); | 595 | hcall(LHCALL_LGUEST_INIT, __pa(&lguest_data), 0, 0); |
589 | 596 | ||
diff --git a/drivers/lguest/lguest_asm.S b/drivers/lguest/lguest_asm.S index 00046c57b5ba..a3dbf22ee365 100644 --- a/drivers/lguest/lguest_asm.S +++ b/drivers/lguest/lguest_asm.S | |||
@@ -2,9 +2,7 @@ | |||
2 | #include <linux/lguest.h> | 2 | #include <linux/lguest.h> |
3 | #include <asm/asm-offsets.h> | 3 | #include <asm/asm-offsets.h> |
4 | #include <asm/thread_info.h> | 4 | #include <asm/thread_info.h> |
5 | 5 | #include <asm/processor-flags.h> | |
6 | /* FIXME: Once asm/processor-flags.h goes in, include that */ | ||
7 | #define X86_EFLAGS_IF 0x00000200 | ||
8 | 6 | ||
9 | /* | 7 | /* |
10 | * This is where we begin: we have a magic signature which the launcher looks | 8 | * This is where we begin: we have a magic signature which the launcher looks |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index c8dfdb302916..d90ee145effe 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -493,12 +493,12 @@ async_copy_data(int frombio, struct bio *bio, struct page *page, | |||
493 | if (frombio) | 493 | if (frombio) |
494 | tx = async_memcpy(page, bio_page, page_offset, | 494 | tx = async_memcpy(page, bio_page, page_offset, |
495 | b_offset, clen, | 495 | b_offset, clen, |
496 | ASYNC_TX_DEP_ACK | ASYNC_TX_KMAP_SRC, | 496 | ASYNC_TX_DEP_ACK, |
497 | tx, NULL, NULL); | 497 | tx, NULL, NULL); |
498 | else | 498 | else |
499 | tx = async_memcpy(bio_page, page, b_offset, | 499 | tx = async_memcpy(bio_page, page, b_offset, |
500 | page_offset, clen, | 500 | page_offset, clen, |
501 | ASYNC_TX_DEP_ACK | ASYNC_TX_KMAP_DST, | 501 | ASYNC_TX_DEP_ACK, |
502 | tx, NULL, NULL); | 502 | tx, NULL, NULL); |
503 | } | 503 | } |
504 | if (clen < len) /* hit end of page */ | 504 | if (clen < len) /* hit end of page */ |
diff --git a/drivers/net/mac89x0.c b/drivers/net/mac89x0.c index 26a3b45a4a34..62c1c6262feb 100644 --- a/drivers/net/mac89x0.c +++ b/drivers/net/mac89x0.c | |||
@@ -608,7 +608,7 @@ module_param(debug, int, 0); | |||
608 | MODULE_PARM_DESC(debug, "CS89[02]0 debug level (0-5)"); | 608 | MODULE_PARM_DESC(debug, "CS89[02]0 debug level (0-5)"); |
609 | MODULE_LICENSE("GPL"); | 609 | MODULE_LICENSE("GPL"); |
610 | 610 | ||
611 | int | 611 | int __init |
612 | init_module(void) | 612 | init_module(void) |
613 | { | 613 | { |
614 | net_debug = debug; | 614 | net_debug = debug; |
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index a2f32151559e..13f08a390e1f 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -692,6 +692,7 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) | |||
692 | { | 692 | { |
693 | struct sky2_port *sky2 = netdev_priv(hw->dev[port]); | 693 | struct sky2_port *sky2 = netdev_priv(hw->dev[port]); |
694 | u16 reg; | 694 | u16 reg; |
695 | u32 rx_reg; | ||
695 | int i; | 696 | int i; |
696 | const u8 *addr = hw->dev[port]->dev_addr; | 697 | const u8 *addr = hw->dev[port]->dev_addr; |
697 | 698 | ||
@@ -768,11 +769,11 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) | |||
768 | 769 | ||
769 | /* Configure Rx MAC FIFO */ | 770 | /* Configure Rx MAC FIFO */ |
770 | sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); | 771 | sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); |
771 | reg = GMF_OPER_ON | GMF_RX_F_FL_ON; | 772 | rx_reg = GMF_OPER_ON | GMF_RX_F_FL_ON; |
772 | if (hw->chip_id == CHIP_ID_YUKON_EX) | 773 | if (hw->chip_id == CHIP_ID_YUKON_EX) |
773 | reg |= GMF_RX_OVER_ON; | 774 | rx_reg |= GMF_RX_OVER_ON; |
774 | 775 | ||
775 | sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), reg); | 776 | sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), rx_reg); |
776 | 777 | ||
777 | /* Flush Rx MAC FIFO on any flow control or error */ | 778 | /* Flush Rx MAC FIFO on any flow control or error */ |
778 | sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR); | 779 | sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR); |
diff --git a/drivers/net/sunvnet.c b/drivers/net/sunvnet.c index b801e3b3a11a..ef0066bab2cf 100644 --- a/drivers/net/sunvnet.c +++ b/drivers/net/sunvnet.c | |||
@@ -1136,7 +1136,7 @@ static struct vio_device_id vnet_port_match[] = { | |||
1136 | }, | 1136 | }, |
1137 | {}, | 1137 | {}, |
1138 | }; | 1138 | }; |
1139 | MODULE_DEVICE_TABLE(vio, vnet_match); | 1139 | MODULE_DEVICE_TABLE(vio, vnet_port_match); |
1140 | 1140 | ||
1141 | static struct vio_driver vnet_port_driver = { | 1141 | static struct vio_driver vnet_port_driver = { |
1142 | .id_table = vnet_port_match, | 1142 | .id_table = vnet_port_match, |
diff --git a/drivers/parport/Kconfig b/drivers/parport/Kconfig index 09c93ff932b1..d449b150930e 100644 --- a/drivers/parport/Kconfig +++ b/drivers/parport/Kconfig | |||
@@ -35,7 +35,7 @@ if PARPORT | |||
35 | 35 | ||
36 | config PARPORT_PC | 36 | config PARPORT_PC |
37 | tristate "PC-style hardware" | 37 | tristate "PC-style hardware" |
38 | depends on (!SPARC64 || PCI) && !SPARC32 && !M32R && !FRV | 38 | depends on (!SPARC64 || PCI) && !SPARC32 && !M32R && !FRV && (!M68K || ISA) |
39 | ---help--- | 39 | ---help--- |
40 | You should say Y here if you have a PC-style parallel port. All | 40 | You should say Y here if you have a PC-style parallel port. All |
41 | IBM PC compatible computers and some Alphas have PC-style | 41 | IBM PC compatible computers and some Alphas have PC-style |
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index cea401feb0f3..35f34665e3c4 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -394,7 +394,7 @@ config RTC_DRV_SA1100 | |||
394 | 394 | ||
395 | config RTC_DRV_SH | 395 | config RTC_DRV_SH |
396 | tristate "SuperH On-Chip RTC" | 396 | tristate "SuperH On-Chip RTC" |
397 | depends on RTC_CLASS && SUPERH | 397 | depends on RTC_CLASS && SUPERH && (CPU_SH3 || CPU_SH4) |
398 | help | 398 | help |
399 | Say Y here to enable support for the on-chip RTC found in | 399 | Say Y here to enable support for the on-chip RTC found in |
400 | most SuperH processors. | 400 | most SuperH processors. |
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 372723161c97..a947257b8964 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig | |||
@@ -483,7 +483,7 @@ source "drivers/scsi/aic94xx/Kconfig" | |||
483 | # All the I2O code and drivers do not seem to be 64bit safe. | 483 | # All the I2O code and drivers do not seem to be 64bit safe. |
484 | config SCSI_DPT_I2O | 484 | config SCSI_DPT_I2O |
485 | tristate "Adaptec I2O RAID support " | 485 | tristate "Adaptec I2O RAID support " |
486 | depends on !64BIT && SCSI && PCI | 486 | depends on !64BIT && SCSI && PCI && VIRT_TO_BUS |
487 | help | 487 | help |
488 | This driver supports all of Adaptec's I2O based RAID controllers as | 488 | This driver supports all of Adaptec's I2O based RAID controllers as |
489 | well as the DPT SmartRaid V cards. This is an Adaptec maintained | 489 | well as the DPT SmartRaid V cards. This is an Adaptec maintained |
diff --git a/drivers/scsi/NCR53C9x.c b/drivers/scsi/NCR53C9x.c index 773d11dd9953..79b4df158140 100644 --- a/drivers/scsi/NCR53C9x.c +++ b/drivers/scsi/NCR53C9x.c | |||
@@ -95,6 +95,8 @@ enum { | |||
95 | /* The master ring of all esp hosts we are managing in this driver. */ | 95 | /* The master ring of all esp hosts we are managing in this driver. */ |
96 | static struct NCR_ESP *espchain; | 96 | static struct NCR_ESP *espchain; |
97 | int nesps = 0, esps_in_use = 0, esps_running = 0; | 97 | int nesps = 0, esps_in_use = 0, esps_running = 0; |
98 | EXPORT_SYMBOL(nesps); | ||
99 | EXPORT_SYMBOL(esps_running); | ||
98 | 100 | ||
99 | irqreturn_t esp_intr(int irq, void *dev_id); | 101 | irqreturn_t esp_intr(int irq, void *dev_id); |
100 | 102 | ||
@@ -524,6 +526,7 @@ void esp_bootup_reset(struct NCR_ESP *esp, struct ESP_regs *eregs) | |||
524 | /* Eat any bitrot in the chip and we are done... */ | 526 | /* Eat any bitrot in the chip and we are done... */ |
525 | trash = esp_read(eregs->esp_intrpt); | 527 | trash = esp_read(eregs->esp_intrpt); |
526 | } | 528 | } |
529 | EXPORT_SYMBOL(esp_bootup_reset); | ||
527 | 530 | ||
528 | /* Allocate structure and insert basic data such as SCSI chip frequency | 531 | /* Allocate structure and insert basic data such as SCSI chip frequency |
529 | * data and a pointer to the device | 532 | * data and a pointer to the device |
@@ -772,6 +775,7 @@ const char *esp_info(struct Scsi_Host *host) | |||
772 | panic("Bogon ESP revision"); | 775 | panic("Bogon ESP revision"); |
773 | }; | 776 | }; |
774 | } | 777 | } |
778 | EXPORT_SYMBOL(esp_info); | ||
775 | 779 | ||
776 | /* From Wolfgang Stanglmeier's NCR scsi driver. */ | 780 | /* From Wolfgang Stanglmeier's NCR scsi driver. */ |
777 | struct info_str | 781 | struct info_str |
@@ -902,6 +906,7 @@ int esp_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t off | |||
902 | *start = buffer; | 906 | *start = buffer; |
903 | return esp_host_info(esp, buffer, offset, length); | 907 | return esp_host_info(esp, buffer, offset, length); |
904 | } | 908 | } |
909 | EXPORT_SYMBOL(esp_proc_info); | ||
905 | 910 | ||
906 | static void esp_get_dmabufs(struct NCR_ESP *esp, Scsi_Cmnd *sp) | 911 | static void esp_get_dmabufs(struct NCR_ESP *esp, Scsi_Cmnd *sp) |
907 | { | 912 | { |
@@ -3535,6 +3540,7 @@ state_machine: | |||
3535 | if(esp->dma_irq_exit) | 3540 | if(esp->dma_irq_exit) |
3536 | esp->dma_irq_exit(esp); | 3541 | esp->dma_irq_exit(esp); |
3537 | } | 3542 | } |
3543 | EXPORT_SYMBOL(esp_handle); | ||
3538 | 3544 | ||
3539 | #ifndef CONFIG_SMP | 3545 | #ifndef CONFIG_SMP |
3540 | irqreturn_t esp_intr(int irq, void *dev_id) | 3546 | irqreturn_t esp_intr(int irq, void *dev_id) |
@@ -3631,6 +3637,7 @@ void esp_release(void) | |||
3631 | esps_in_use--; | 3637 | esps_in_use--; |
3632 | esps_running = esps_in_use; | 3638 | esps_running = esps_in_use; |
3633 | } | 3639 | } |
3640 | EXPORT_SYMBOL(esp_release); | ||
3634 | #endif | 3641 | #endif |
3635 | 3642 | ||
3636 | EXPORT_SYMBOL(esp_abort); | 3643 | EXPORT_SYMBOL(esp_abort); |
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index aebcd5fcdc55..7829ab1e2fb4 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c | |||
@@ -1885,7 +1885,7 @@ static int iscsi_tcp_get_addr(struct iscsi_conn *conn, struct socket *sock, | |||
1885 | struct sockaddr_in *sin; | 1885 | struct sockaddr_in *sin; |
1886 | int rc = 0, len; | 1886 | int rc = 0, len; |
1887 | 1887 | ||
1888 | addr = kmalloc(GFP_KERNEL, sizeof(*addr)); | 1888 | addr = kmalloc(sizeof(*addr), GFP_KERNEL); |
1889 | if (!addr) | 1889 | if (!addr) |
1890 | return -ENOMEM; | 1890 | return -ENOMEM; |
1891 | 1891 | ||
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index 1bc884051e0f..02c52f8d5dbf 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c | |||
@@ -456,7 +456,7 @@ static int cxacru_start_wait_urb(struct urb *urb, struct completion *done, | |||
456 | int* actual_length) | 456 | int* actual_length) |
457 | { | 457 | { |
458 | struct timer_list timer; | 458 | struct timer_list timer; |
459 | int status; | 459 | int status = urb->status; |
460 | 460 | ||
461 | init_timer(&timer); | 461 | init_timer(&timer); |
462 | timer.expires = jiffies + msecs_to_jiffies(CMD_TIMEOUT); | 462 | timer.expires = jiffies + msecs_to_jiffies(CMD_TIMEOUT); |
@@ -464,7 +464,6 @@ static int cxacru_start_wait_urb(struct urb *urb, struct completion *done, | |||
464 | timer.function = cxacru_timeout_kill; | 464 | timer.function = cxacru_timeout_kill; |
465 | add_timer(&timer); | 465 | add_timer(&timer); |
466 | wait_for_completion(done); | 466 | wait_for_completion(done); |
467 | status = urb->status; | ||
468 | del_timer_sync(&timer); | 467 | del_timer_sync(&timer); |
469 | 468 | ||
470 | if (actual_length) | 469 | if (actual_length) |
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index 638b8009b3bc..eb0615abff68 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c | |||
@@ -612,7 +612,8 @@ static void speedtch_handle_int(struct urb *int_urb) | |||
612 | struct speedtch_instance_data *instance = int_urb->context; | 612 | struct speedtch_instance_data *instance = int_urb->context; |
613 | struct usbatm_data *usbatm = instance->usbatm; | 613 | struct usbatm_data *usbatm = instance->usbatm; |
614 | unsigned int count = int_urb->actual_length; | 614 | unsigned int count = int_urb->actual_length; |
615 | int ret = int_urb->status; | 615 | int status = int_urb->status; |
616 | int ret; | ||
616 | 617 | ||
617 | /* The magic interrupt for "up state" */ | 618 | /* The magic interrupt for "up state" */ |
618 | static const unsigned char up_int[6] = { 0xa1, 0x00, 0x01, 0x00, 0x00, 0x00 }; | 619 | static const unsigned char up_int[6] = { 0xa1, 0x00, 0x01, 0x00, 0x00, 0x00 }; |
@@ -621,8 +622,8 @@ static void speedtch_handle_int(struct urb *int_urb) | |||
621 | 622 | ||
622 | atm_dbg(usbatm, "%s entered\n", __func__); | 623 | atm_dbg(usbatm, "%s entered\n", __func__); |
623 | 624 | ||
624 | if (ret < 0) { | 625 | if (status < 0) { |
625 | atm_dbg(usbatm, "%s: nonzero urb status %d!\n", __func__, ret); | 626 | atm_dbg(usbatm, "%s: nonzero urb status %d!\n", __func__, status); |
626 | goto fail; | 627 | goto fail; |
627 | } | 628 | } |
628 | 629 | ||
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index 8f046659b4e9..a1a1c9d467e0 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c | |||
@@ -1308,11 +1308,13 @@ static void uea_intr(struct urb *urb) | |||
1308 | { | 1308 | { |
1309 | struct uea_softc *sc = urb->context; | 1309 | struct uea_softc *sc = urb->context; |
1310 | struct intr_pkt *intr = urb->transfer_buffer; | 1310 | struct intr_pkt *intr = urb->transfer_buffer; |
1311 | int status = urb->status; | ||
1312 | |||
1311 | uea_enters(INS_TO_USBDEV(sc)); | 1313 | uea_enters(INS_TO_USBDEV(sc)); |
1312 | 1314 | ||
1313 | if (unlikely(urb->status < 0)) { | 1315 | if (unlikely(status < 0)) { |
1314 | uea_err(INS_TO_USBDEV(sc), "uea_intr() failed with %d\n", | 1316 | uea_err(INS_TO_USBDEV(sc), "uea_intr() failed with %d\n", |
1315 | urb->status); | 1317 | status); |
1316 | return; | 1318 | return; |
1317 | } | 1319 | } |
1318 | 1320 | ||
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index 11e9b15ca45a..e717f5b1caee 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c | |||
@@ -257,9 +257,10 @@ static void usbatm_complete(struct urb *urb) | |||
257 | { | 257 | { |
258 | struct usbatm_channel *channel = urb->context; | 258 | struct usbatm_channel *channel = urb->context; |
259 | unsigned long flags; | 259 | unsigned long flags; |
260 | int status = urb->status; | ||
260 | 261 | ||
261 | vdbg("%s: urb 0x%p, status %d, actual_length %d", | 262 | vdbg("%s: urb 0x%p, status %d, actual_length %d", |
262 | __func__, urb, urb->status, urb->actual_length); | 263 | __func__, urb, status, urb->actual_length); |
263 | 264 | ||
264 | /* usually in_interrupt(), but not always */ | 265 | /* usually in_interrupt(), but not always */ |
265 | spin_lock_irqsave(&channel->lock, flags); | 266 | spin_lock_irqsave(&channel->lock, flags); |
@@ -269,16 +270,16 @@ static void usbatm_complete(struct urb *urb) | |||
269 | 270 | ||
270 | spin_unlock_irqrestore(&channel->lock, flags); | 271 | spin_unlock_irqrestore(&channel->lock, flags); |
271 | 272 | ||
272 | if (unlikely(urb->status) && | 273 | if (unlikely(status) && |
273 | (!(channel->usbatm->flags & UDSL_IGNORE_EILSEQ) || | 274 | (!(channel->usbatm->flags & UDSL_IGNORE_EILSEQ) || |
274 | urb->status != -EILSEQ )) | 275 | status != -EILSEQ )) |
275 | { | 276 | { |
276 | if (urb->status == -ESHUTDOWN) | 277 | if (status == -ESHUTDOWN) |
277 | return; | 278 | return; |
278 | 279 | ||
279 | if (printk_ratelimit()) | 280 | if (printk_ratelimit()) |
280 | atm_warn(channel->usbatm, "%s: urb 0x%p failed (%d)!\n", | 281 | atm_warn(channel->usbatm, "%s: urb 0x%p failed (%d)!\n", |
281 | __func__, urb, urb->status); | 282 | __func__, urb, status); |
282 | /* throttle processing in case of an error */ | 283 | /* throttle processing in case of an error */ |
283 | mod_timer(&channel->delay, jiffies + msecs_to_jiffies(THROTTLE_MSECS)); | 284 | mod_timer(&channel->delay, jiffies + msecs_to_jiffies(THROTTLE_MSECS)); |
284 | } else | 285 | } else |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index cd51520c7e72..fe940e0536e0 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -257,9 +257,10 @@ static void acm_ctrl_irq(struct urb *urb) | |||
257 | struct usb_cdc_notification *dr = urb->transfer_buffer; | 257 | struct usb_cdc_notification *dr = urb->transfer_buffer; |
258 | unsigned char *data; | 258 | unsigned char *data; |
259 | int newctrl; | 259 | int newctrl; |
260 | int status; | 260 | int retval; |
261 | int status = urb->status; | ||
261 | 262 | ||
262 | switch (urb->status) { | 263 | switch (status) { |
263 | case 0: | 264 | case 0: |
264 | /* success */ | 265 | /* success */ |
265 | break; | 266 | break; |
@@ -267,10 +268,10 @@ static void acm_ctrl_irq(struct urb *urb) | |||
267 | case -ENOENT: | 268 | case -ENOENT: |
268 | case -ESHUTDOWN: | 269 | case -ESHUTDOWN: |
269 | /* this urb is terminated, clean up */ | 270 | /* this urb is terminated, clean up */ |
270 | dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); | 271 | dbg("%s - urb shutting down with status: %d", __FUNCTION__, status); |
271 | return; | 272 | return; |
272 | default: | 273 | default: |
273 | dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); | 274 | dbg("%s - nonzero urb status received: %d", __FUNCTION__, status); |
274 | goto exit; | 275 | goto exit; |
275 | } | 276 | } |
276 | 277 | ||
@@ -311,10 +312,10 @@ static void acm_ctrl_irq(struct urb *urb) | |||
311 | break; | 312 | break; |
312 | } | 313 | } |
313 | exit: | 314 | exit: |
314 | status = usb_submit_urb (urb, GFP_ATOMIC); | 315 | retval = usb_submit_urb (urb, GFP_ATOMIC); |
315 | if (status) | 316 | if (retval) |
316 | err ("%s - usb_submit_urb failed with result %d", | 317 | err ("%s - usb_submit_urb failed with result %d", |
317 | __FUNCTION__, status); | 318 | __FUNCTION__, retval); |
318 | } | 319 | } |
319 | 320 | ||
320 | /* data interface returns incoming bytes, or we got unthrottled */ | 321 | /* data interface returns incoming bytes, or we got unthrottled */ |
@@ -324,7 +325,8 @@ static void acm_read_bulk(struct urb *urb) | |||
324 | struct acm_ru *rcv = urb->context; | 325 | struct acm_ru *rcv = urb->context; |
325 | struct acm *acm = rcv->instance; | 326 | struct acm *acm = rcv->instance; |
326 | int status = urb->status; | 327 | int status = urb->status; |
327 | dbg("Entering acm_read_bulk with status %d", urb->status); | 328 | |
329 | dbg("Entering acm_read_bulk with status %d", status); | ||
328 | 330 | ||
329 | if (!ACM_READY(acm)) | 331 | if (!ACM_READY(acm)) |
330 | return; | 332 | return; |
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 9a1478972bf5..5192cd9356de 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c | |||
@@ -289,16 +289,17 @@ static int proto_bias = -1; | |||
289 | static void usblp_bulk_read(struct urb *urb) | 289 | static void usblp_bulk_read(struct urb *urb) |
290 | { | 290 | { |
291 | struct usblp *usblp = urb->context; | 291 | struct usblp *usblp = urb->context; |
292 | int status = urb->status; | ||
292 | 293 | ||
293 | if (usblp->present && usblp->used) { | 294 | if (usblp->present && usblp->used) { |
294 | if (urb->status) | 295 | if (status) |
295 | printk(KERN_WARNING "usblp%d: " | 296 | printk(KERN_WARNING "usblp%d: " |
296 | "nonzero read bulk status received: %d\n", | 297 | "nonzero read bulk status received: %d\n", |
297 | usblp->minor, urb->status); | 298 | usblp->minor, status); |
298 | } | 299 | } |
299 | spin_lock(&usblp->lock); | 300 | spin_lock(&usblp->lock); |
300 | if (urb->status < 0) | 301 | if (status < 0) |
301 | usblp->rstatus = urb->status; | 302 | usblp->rstatus = status; |
302 | else | 303 | else |
303 | usblp->rstatus = urb->actual_length; | 304 | usblp->rstatus = urb->actual_length; |
304 | usblp->rcomplete = 1; | 305 | usblp->rcomplete = 1; |
@@ -311,16 +312,17 @@ static void usblp_bulk_read(struct urb *urb) | |||
311 | static void usblp_bulk_write(struct urb *urb) | 312 | static void usblp_bulk_write(struct urb *urb) |
312 | { | 313 | { |
313 | struct usblp *usblp = urb->context; | 314 | struct usblp *usblp = urb->context; |
315 | int status = urb->status; | ||
314 | 316 | ||
315 | if (usblp->present && usblp->used) { | 317 | if (usblp->present && usblp->used) { |
316 | if (urb->status) | 318 | if (status) |
317 | printk(KERN_WARNING "usblp%d: " | 319 | printk(KERN_WARNING "usblp%d: " |
318 | "nonzero write bulk status received: %d\n", | 320 | "nonzero write bulk status received: %d\n", |
319 | usblp->minor, urb->status); | 321 | usblp->minor, status); |
320 | } | 322 | } |
321 | spin_lock(&usblp->lock); | 323 | spin_lock(&usblp->lock); |
322 | if (urb->status < 0) | 324 | if (status < 0) |
323 | usblp->wstatus = urb->status; | 325 | usblp->wstatus = status; |
324 | else | 326 | else |
325 | usblp->wstatus = urb->actual_length; | 327 | usblp->wstatus = urb->actual_length; |
326 | usblp->wcomplete = 1; | 328 | usblp->wcomplete = 1; |
@@ -741,10 +743,11 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t | |||
741 | */ | 743 | */ |
742 | rv = usblp_wwait(usblp, !!(file->f_flags&O_NONBLOCK)); | 744 | rv = usblp_wwait(usblp, !!(file->f_flags&O_NONBLOCK)); |
743 | if (rv < 0) { | 745 | if (rv < 0) { |
744 | /* | 746 | if (rv == -EAGAIN) { |
745 | * If interrupted, we simply leave the URB to dangle, | 747 | /* Presume that it's going to complete well. */ |
746 | * so the ->release will call usb_kill_urb(). | 748 | writecount += transfer_length; |
747 | */ | 749 | } |
750 | /* Leave URB dangling, to be cleaned on close. */ | ||
748 | goto collect_error; | 751 | goto collect_error; |
749 | } | 752 | } |
750 | 753 | ||
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 963520fbef90..42ef1d5f6c8a 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -99,12 +99,17 @@ EXPORT_SYMBOL_GPL (usb_bus_list_lock); | |||
99 | /* used for controlling access to virtual root hubs */ | 99 | /* used for controlling access to virtual root hubs */ |
100 | static DEFINE_SPINLOCK(hcd_root_hub_lock); | 100 | static DEFINE_SPINLOCK(hcd_root_hub_lock); |
101 | 101 | ||
102 | /* used when updating hcd data */ | 102 | /* used when updating an endpoint's URB list */ |
103 | static DEFINE_SPINLOCK(hcd_data_lock); | 103 | static DEFINE_SPINLOCK(hcd_urb_list_lock); |
104 | 104 | ||
105 | /* wait queue for synchronous unlinks */ | 105 | /* wait queue for synchronous unlinks */ |
106 | DECLARE_WAIT_QUEUE_HEAD(usb_kill_urb_queue); | 106 | DECLARE_WAIT_QUEUE_HEAD(usb_kill_urb_queue); |
107 | 107 | ||
108 | static inline int is_root_hub(struct usb_device *udev) | ||
109 | { | ||
110 | return (udev->parent == NULL); | ||
111 | } | ||
112 | |||
108 | /*-------------------------------------------------------------------------*/ | 113 | /*-------------------------------------------------------------------------*/ |
109 | 114 | ||
110 | /* | 115 | /* |
@@ -906,14 +911,13 @@ EXPORT_SYMBOL (usb_calc_bus_time); | |||
906 | static void urb_unlink(struct usb_hcd *hcd, struct urb *urb) | 911 | static void urb_unlink(struct usb_hcd *hcd, struct urb *urb) |
907 | { | 912 | { |
908 | unsigned long flags; | 913 | unsigned long flags; |
909 | int at_root_hub = (urb->dev == hcd->self.root_hub); | ||
910 | 914 | ||
911 | /* clear all state linking urb to this dev (and hcd) */ | 915 | /* clear all state linking urb to this dev (and hcd) */ |
912 | spin_lock_irqsave (&hcd_data_lock, flags); | 916 | spin_lock_irqsave(&hcd_urb_list_lock, flags); |
913 | list_del_init (&urb->urb_list); | 917 | list_del_init (&urb->urb_list); |
914 | spin_unlock_irqrestore (&hcd_data_lock, flags); | 918 | spin_unlock_irqrestore(&hcd_urb_list_lock, flags); |
915 | 919 | ||
916 | if (hcd->self.uses_dma && !at_root_hub) { | 920 | if (hcd->self.uses_dma && !is_root_hub(urb->dev)) { |
917 | if (usb_pipecontrol (urb->pipe) | 921 | if (usb_pipecontrol (urb->pipe) |
918 | && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) | 922 | && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) |
919 | dma_unmap_single (hcd->self.controller, urb->setup_dma, | 923 | dma_unmap_single (hcd->self.controller, urb->setup_dma, |
@@ -955,7 +959,7 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags) | |||
955 | 959 | ||
956 | // FIXME: verify that quiescing hc works right (RH cleans up) | 960 | // FIXME: verify that quiescing hc works right (RH cleans up) |
957 | 961 | ||
958 | spin_lock_irqsave (&hcd_data_lock, flags); | 962 | spin_lock_irqsave(&hcd_urb_list_lock, flags); |
959 | ep = (usb_pipein(urb->pipe) ? urb->dev->ep_in : urb->dev->ep_out) | 963 | ep = (usb_pipein(urb->pipe) ? urb->dev->ep_in : urb->dev->ep_out) |
960 | [usb_pipeendpoint(urb->pipe)]; | 964 | [usb_pipeendpoint(urb->pipe)]; |
961 | if (unlikely (!ep)) | 965 | if (unlikely (!ep)) |
@@ -972,7 +976,7 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags) | |||
972 | status = -ESHUTDOWN; | 976 | status = -ESHUTDOWN; |
973 | break; | 977 | break; |
974 | } | 978 | } |
975 | spin_unlock_irqrestore (&hcd_data_lock, flags); | 979 | spin_unlock_irqrestore(&hcd_urb_list_lock, flags); |
976 | if (status) { | 980 | if (status) { |
977 | INIT_LIST_HEAD (&urb->urb_list); | 981 | INIT_LIST_HEAD (&urb->urb_list); |
978 | usbmon_urb_submit_error(&hcd->self, urb, status); | 982 | usbmon_urb_submit_error(&hcd->self, urb, status); |
@@ -986,7 +990,7 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags) | |||
986 | urb = usb_get_urb (urb); | 990 | urb = usb_get_urb (urb); |
987 | atomic_inc (&urb->use_count); | 991 | atomic_inc (&urb->use_count); |
988 | 992 | ||
989 | if (urb->dev == hcd->self.root_hub) { | 993 | if (is_root_hub(urb->dev)) { |
990 | /* NOTE: requirement on hub callers (usbfs and the hub | 994 | /* NOTE: requirement on hub callers (usbfs and the hub |
991 | * driver, for now) that URBs' urb->transfer_buffer be | 995 | * driver, for now) that URBs' urb->transfer_buffer be |
992 | * valid and usb_buffer_{sync,unmap}() not be needed, since | 996 | * valid and usb_buffer_{sync,unmap}() not be needed, since |
@@ -1033,18 +1037,6 @@ done: | |||
1033 | 1037 | ||
1034 | /*-------------------------------------------------------------------------*/ | 1038 | /*-------------------------------------------------------------------------*/ |
1035 | 1039 | ||
1036 | /* called in any context */ | ||
1037 | int usb_hcd_get_frame_number (struct usb_device *udev) | ||
1038 | { | ||
1039 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); | ||
1040 | |||
1041 | if (!HC_IS_RUNNING (hcd->state)) | ||
1042 | return -ESHUTDOWN; | ||
1043 | return hcd->driver->get_frame_number (hcd); | ||
1044 | } | ||
1045 | |||
1046 | /*-------------------------------------------------------------------------*/ | ||
1047 | |||
1048 | /* this makes the hcd giveback() the urb more quickly, by kicking it | 1040 | /* this makes the hcd giveback() the urb more quickly, by kicking it |
1049 | * off hardware queues (which may take a while) and returning it as | 1041 | * off hardware queues (which may take a while) and returning it as |
1050 | * soon as practical. we've already set up the urb's return status, | 1042 | * soon as practical. we've already set up the urb's return status, |
@@ -1055,7 +1047,7 @@ unlink1 (struct usb_hcd *hcd, struct urb *urb) | |||
1055 | { | 1047 | { |
1056 | int value; | 1048 | int value; |
1057 | 1049 | ||
1058 | if (urb->dev == hcd->self.root_hub) | 1050 | if (is_root_hub(urb->dev)) |
1059 | value = usb_rh_urb_dequeue (hcd, urb); | 1051 | value = usb_rh_urb_dequeue (hcd, urb); |
1060 | else { | 1052 | else { |
1061 | 1053 | ||
@@ -1103,11 +1095,11 @@ int usb_hcd_unlink_urb (struct urb *urb, int status) | |||
1103 | * that it was submitted. But as a rule it can't know whether or | 1095 | * that it was submitted. But as a rule it can't know whether or |
1104 | * not it's already been unlinked ... so we respect the reversed | 1096 | * not it's already been unlinked ... so we respect the reversed |
1105 | * lock sequence needed for the usb_hcd_giveback_urb() code paths | 1097 | * lock sequence needed for the usb_hcd_giveback_urb() code paths |
1106 | * (urb lock, then hcd_data_lock) in case some other CPU is now | 1098 | * (urb lock, then hcd_urb_list_lock) in case some other CPU is now |
1107 | * unlinking it. | 1099 | * unlinking it. |
1108 | */ | 1100 | */ |
1109 | spin_lock_irqsave (&urb->lock, flags); | 1101 | spin_lock_irqsave (&urb->lock, flags); |
1110 | spin_lock (&hcd_data_lock); | 1102 | spin_lock(&hcd_urb_list_lock); |
1111 | 1103 | ||
1112 | sys = &urb->dev->dev; | 1104 | sys = &urb->dev->dev; |
1113 | hcd = bus_to_hcd(urb->dev->bus); | 1105 | hcd = bus_to_hcd(urb->dev->bus); |
@@ -1139,17 +1131,16 @@ int usb_hcd_unlink_urb (struct urb *urb, int status) | |||
1139 | * finish unlinking the initial failed usb_set_address() | 1131 | * finish unlinking the initial failed usb_set_address() |
1140 | * or device descriptor fetch. | 1132 | * or device descriptor fetch. |
1141 | */ | 1133 | */ |
1142 | if (!test_bit(HCD_FLAG_SAW_IRQ, &hcd->flags) | 1134 | if (!test_bit(HCD_FLAG_SAW_IRQ, &hcd->flags) && |
1143 | && hcd->self.root_hub != urb->dev) { | 1135 | !is_root_hub(urb->dev)) { |
1144 | dev_warn (hcd->self.controller, "Unlink after no-IRQ? " | 1136 | dev_warn (hcd->self.controller, "Unlink after no-IRQ? " |
1145 | "Controller is probably using the wrong IRQ." | 1137 | "Controller is probably using the wrong IRQ.\n"); |
1146 | "\n"); | ||
1147 | set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); | 1138 | set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); |
1148 | } | 1139 | } |
1149 | 1140 | ||
1150 | urb->status = status; | 1141 | urb->status = status; |
1151 | 1142 | ||
1152 | spin_unlock (&hcd_data_lock); | 1143 | spin_unlock(&hcd_urb_list_lock); |
1153 | spin_unlock_irqrestore (&urb->lock, flags); | 1144 | spin_unlock_irqrestore (&urb->lock, flags); |
1154 | 1145 | ||
1155 | retval = unlink1 (hcd, urb); | 1146 | retval = unlink1 (hcd, urb); |
@@ -1158,7 +1149,7 @@ int usb_hcd_unlink_urb (struct urb *urb, int status) | |||
1158 | return retval; | 1149 | return retval; |
1159 | 1150 | ||
1160 | done: | 1151 | done: |
1161 | spin_unlock (&hcd_data_lock); | 1152 | spin_unlock(&hcd_urb_list_lock); |
1162 | spin_unlock_irqrestore (&urb->lock, flags); | 1153 | spin_unlock_irqrestore (&urb->lock, flags); |
1163 | if (retval != -EIDRM && sys && sys->driver) | 1154 | if (retval != -EIDRM && sys && sys->driver) |
1164 | dev_dbg (sys, "hcd_unlink_urb %p fail %d\n", urb, retval); | 1155 | dev_dbg (sys, "hcd_unlink_urb %p fail %d\n", urb, retval); |
@@ -1167,6 +1158,35 @@ done: | |||
1167 | 1158 | ||
1168 | /*-------------------------------------------------------------------------*/ | 1159 | /*-------------------------------------------------------------------------*/ |
1169 | 1160 | ||
1161 | /** | ||
1162 | * usb_hcd_giveback_urb - return URB from HCD to device driver | ||
1163 | * @hcd: host controller returning the URB | ||
1164 | * @urb: urb being returned to the USB device driver. | ||
1165 | * Context: in_interrupt() | ||
1166 | * | ||
1167 | * This hands the URB from HCD to its USB device driver, using its | ||
1168 | * completion function. The HCD has freed all per-urb resources | ||
1169 | * (and is done using urb->hcpriv). It also released all HCD locks; | ||
1170 | * the device driver won't cause problems if it frees, modifies, | ||
1171 | * or resubmits this URB. | ||
1172 | */ | ||
1173 | void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb) | ||
1174 | { | ||
1175 | urb_unlink(hcd, urb); | ||
1176 | usbmon_urb_complete (&hcd->self, urb); | ||
1177 | usb_unanchor_urb(urb); | ||
1178 | |||
1179 | /* pass ownership to the completion handler */ | ||
1180 | urb->complete (urb); | ||
1181 | atomic_dec (&urb->use_count); | ||
1182 | if (unlikely (urb->reject)) | ||
1183 | wake_up (&usb_kill_urb_queue); | ||
1184 | usb_put_urb (urb); | ||
1185 | } | ||
1186 | EXPORT_SYMBOL (usb_hcd_giveback_urb); | ||
1187 | |||
1188 | /*-------------------------------------------------------------------------*/ | ||
1189 | |||
1170 | /* disables the endpoint: cancels any pending urbs, then synchronizes with | 1190 | /* disables the endpoint: cancels any pending urbs, then synchronizes with |
1171 | * the hcd to make sure all endpoint state is gone from hardware, and then | 1191 | * the hcd to make sure all endpoint state is gone from hardware, and then |
1172 | * waits until the endpoint's queue is completely drained. use for | 1192 | * waits until the endpoint's queue is completely drained. use for |
@@ -1186,7 +1206,7 @@ void usb_hcd_endpoint_disable (struct usb_device *udev, | |||
1186 | 1206 | ||
1187 | /* ep is already gone from udev->ep_{in,out}[]; no more submits */ | 1207 | /* ep is already gone from udev->ep_{in,out}[]; no more submits */ |
1188 | rescan: | 1208 | rescan: |
1189 | spin_lock (&hcd_data_lock); | 1209 | spin_lock(&hcd_urb_list_lock); |
1190 | list_for_each_entry (urb, &ep->urb_list, urb_list) { | 1210 | list_for_each_entry (urb, &ep->urb_list, urb_list) { |
1191 | int tmp; | 1211 | int tmp; |
1192 | 1212 | ||
@@ -1194,7 +1214,7 @@ rescan: | |||
1194 | if (urb->status != -EINPROGRESS) | 1214 | if (urb->status != -EINPROGRESS) |
1195 | continue; | 1215 | continue; |
1196 | usb_get_urb (urb); | 1216 | usb_get_urb (urb); |
1197 | spin_unlock (&hcd_data_lock); | 1217 | spin_unlock(&hcd_urb_list_lock); |
1198 | 1218 | ||
1199 | spin_lock (&urb->lock); | 1219 | spin_lock (&urb->lock); |
1200 | tmp = urb->status; | 1220 | tmp = urb->status; |
@@ -1223,7 +1243,7 @@ rescan: | |||
1223 | /* list contents may have changed */ | 1243 | /* list contents may have changed */ |
1224 | goto rescan; | 1244 | goto rescan; |
1225 | } | 1245 | } |
1226 | spin_unlock (&hcd_data_lock); | 1246 | spin_unlock(&hcd_urb_list_lock); |
1227 | local_irq_enable (); | 1247 | local_irq_enable (); |
1228 | 1248 | ||
1229 | /* synchronize with the hardware, so old configuration state | 1249 | /* synchronize with the hardware, so old configuration state |
@@ -1240,7 +1260,7 @@ rescan: | |||
1240 | * endpoint_disable methods. | 1260 | * endpoint_disable methods. |
1241 | */ | 1261 | */ |
1242 | while (!list_empty (&ep->urb_list)) { | 1262 | while (!list_empty (&ep->urb_list)) { |
1243 | spin_lock_irq (&hcd_data_lock); | 1263 | spin_lock_irq(&hcd_urb_list_lock); |
1244 | 1264 | ||
1245 | /* The list may have changed while we acquired the spinlock */ | 1265 | /* The list may have changed while we acquired the spinlock */ |
1246 | urb = NULL; | 1266 | urb = NULL; |
@@ -1249,7 +1269,7 @@ rescan: | |||
1249 | urb_list); | 1269 | urb_list); |
1250 | usb_get_urb (urb); | 1270 | usb_get_urb (urb); |
1251 | } | 1271 | } |
1252 | spin_unlock_irq (&hcd_data_lock); | 1272 | spin_unlock_irq(&hcd_urb_list_lock); |
1253 | 1273 | ||
1254 | if (urb) { | 1274 | if (urb) { |
1255 | usb_kill_urb (urb); | 1275 | usb_kill_urb (urb); |
@@ -1260,6 +1280,18 @@ rescan: | |||
1260 | 1280 | ||
1261 | /*-------------------------------------------------------------------------*/ | 1281 | /*-------------------------------------------------------------------------*/ |
1262 | 1282 | ||
1283 | /* called in any context */ | ||
1284 | int usb_hcd_get_frame_number (struct usb_device *udev) | ||
1285 | { | ||
1286 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); | ||
1287 | |||
1288 | if (!HC_IS_RUNNING (hcd->state)) | ||
1289 | return -ESHUTDOWN; | ||
1290 | return hcd->driver->get_frame_number (hcd); | ||
1291 | } | ||
1292 | |||
1293 | /*-------------------------------------------------------------------------*/ | ||
1294 | |||
1263 | #ifdef CONFIG_PM | 1295 | #ifdef CONFIG_PM |
1264 | 1296 | ||
1265 | int hcd_bus_suspend(struct usb_device *rhdev) | 1297 | int hcd_bus_suspend(struct usb_device *rhdev) |
@@ -1395,35 +1427,6 @@ EXPORT_SYMBOL (usb_bus_start_enum); | |||
1395 | /*-------------------------------------------------------------------------*/ | 1427 | /*-------------------------------------------------------------------------*/ |
1396 | 1428 | ||
1397 | /** | 1429 | /** |
1398 | * usb_hcd_giveback_urb - return URB from HCD to device driver | ||
1399 | * @hcd: host controller returning the URB | ||
1400 | * @urb: urb being returned to the USB device driver. | ||
1401 | * Context: in_interrupt() | ||
1402 | * | ||
1403 | * This hands the URB from HCD to its USB device driver, using its | ||
1404 | * completion function. The HCD has freed all per-urb resources | ||
1405 | * (and is done using urb->hcpriv). It also released all HCD locks; | ||
1406 | * the device driver won't cause problems if it frees, modifies, | ||
1407 | * or resubmits this URB. | ||
1408 | */ | ||
1409 | void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb) | ||
1410 | { | ||
1411 | urb_unlink(hcd, urb); | ||
1412 | usbmon_urb_complete (&hcd->self, urb); | ||
1413 | usb_unanchor_urb(urb); | ||
1414 | |||
1415 | /* pass ownership to the completion handler */ | ||
1416 | urb->complete (urb); | ||
1417 | atomic_dec (&urb->use_count); | ||
1418 | if (unlikely (urb->reject)) | ||
1419 | wake_up (&usb_kill_urb_queue); | ||
1420 | usb_put_urb (urb); | ||
1421 | } | ||
1422 | EXPORT_SYMBOL (usb_hcd_giveback_urb); | ||
1423 | |||
1424 | /*-------------------------------------------------------------------------*/ | ||
1425 | |||
1426 | /** | ||
1427 | * usb_hcd_irq - hook IRQs to HCD framework (bus glue) | 1430 | * usb_hcd_irq - hook IRQs to HCD framework (bus glue) |
1428 | * @irq: the IRQ being raised | 1431 | * @irq: the IRQ being raised |
1429 | * @__hcd: pointer to the HCD whose IRQ is being signaled | 1432 | * @__hcd: pointer to the HCD whose IRQ is being signaled |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index fd74c50b1804..e341a1da517f 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -1335,6 +1335,10 @@ int usb_new_device(struct usb_device *udev) | |||
1335 | udev->dev.devt = MKDEV(USB_DEVICE_MAJOR, | 1335 | udev->dev.devt = MKDEV(USB_DEVICE_MAJOR, |
1336 | (((udev->bus->busnum-1) * 128) + (udev->devnum-1))); | 1336 | (((udev->bus->busnum-1) * 128) + (udev->devnum-1))); |
1337 | 1337 | ||
1338 | /* Increment the parent's count of unsuspended children */ | ||
1339 | if (udev->parent) | ||
1340 | usb_autoresume_device(udev->parent); | ||
1341 | |||
1338 | /* Register the device. The device driver is responsible | 1342 | /* Register the device. The device driver is responsible |
1339 | * for adding the device files to sysfs and for configuring | 1343 | * for adding the device files to sysfs and for configuring |
1340 | * the device. | 1344 | * the device. |
@@ -1342,13 +1346,11 @@ int usb_new_device(struct usb_device *udev) | |||
1342 | err = device_add(&udev->dev); | 1346 | err = device_add(&udev->dev); |
1343 | if (err) { | 1347 | if (err) { |
1344 | dev_err(&udev->dev, "can't device_add, error %d\n", err); | 1348 | dev_err(&udev->dev, "can't device_add, error %d\n", err); |
1349 | if (udev->parent) | ||
1350 | usb_autosuspend_device(udev->parent); | ||
1345 | goto fail; | 1351 | goto fail; |
1346 | } | 1352 | } |
1347 | 1353 | ||
1348 | /* Increment the parent's count of unsuspended children */ | ||
1349 | if (udev->parent) | ||
1350 | usb_autoresume_device(udev->parent); | ||
1351 | |||
1352 | exit: | 1354 | exit: |
1353 | return err; | 1355 | return err; |
1354 | 1356 | ||
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 530e854961ce..25f63f1096b4 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -34,13 +34,14 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length) | |||
34 | { | 34 | { |
35 | struct completion done; | 35 | struct completion done; |
36 | unsigned long expire; | 36 | unsigned long expire; |
37 | int status; | 37 | int retval; |
38 | int status = urb->status; | ||
38 | 39 | ||
39 | init_completion(&done); | 40 | init_completion(&done); |
40 | urb->context = &done; | 41 | urb->context = &done; |
41 | urb->actual_length = 0; | 42 | urb->actual_length = 0; |
42 | status = usb_submit_urb(urb, GFP_NOIO); | 43 | retval = usb_submit_urb(urb, GFP_NOIO); |
43 | if (unlikely(status)) | 44 | if (unlikely(retval)) |
44 | goto out; | 45 | goto out; |
45 | 46 | ||
46 | expire = timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT; | 47 | expire = timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT; |
@@ -55,15 +56,15 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length) | |||
55 | urb->transfer_buffer_length); | 56 | urb->transfer_buffer_length); |
56 | 57 | ||
57 | usb_kill_urb(urb); | 58 | usb_kill_urb(urb); |
58 | status = urb->status == -ENOENT ? -ETIMEDOUT : urb->status; | 59 | retval = status == -ENOENT ? -ETIMEDOUT : status; |
59 | } else | 60 | } else |
60 | status = urb->status; | 61 | retval = status; |
61 | out: | 62 | out: |
62 | if (actual_length) | 63 | if (actual_length) |
63 | *actual_length = urb->actual_length; | 64 | *actual_length = urb->actual_length; |
64 | 65 | ||
65 | usb_free_urb(urb); | 66 | usb_free_urb(urb); |
66 | return status; | 67 | return retval; |
67 | } | 68 | } |
68 | 69 | ||
69 | /*-------------------------------------------------------------------*/ | 70 | /*-------------------------------------------------------------------*/ |
@@ -250,6 +251,7 @@ static void sg_clean (struct usb_sg_request *io) | |||
250 | static void sg_complete (struct urb *urb) | 251 | static void sg_complete (struct urb *urb) |
251 | { | 252 | { |
252 | struct usb_sg_request *io = urb->context; | 253 | struct usb_sg_request *io = urb->context; |
254 | int status = urb->status; | ||
253 | 255 | ||
254 | spin_lock (&io->lock); | 256 | spin_lock (&io->lock); |
255 | 257 | ||
@@ -265,21 +267,21 @@ static void sg_complete (struct urb *urb) | |||
265 | */ | 267 | */ |
266 | if (io->status | 268 | if (io->status |
267 | && (io->status != -ECONNRESET | 269 | && (io->status != -ECONNRESET |
268 | || urb->status != -ECONNRESET) | 270 | || status != -ECONNRESET) |
269 | && urb->actual_length) { | 271 | && urb->actual_length) { |
270 | dev_err (io->dev->bus->controller, | 272 | dev_err (io->dev->bus->controller, |
271 | "dev %s ep%d%s scatterlist error %d/%d\n", | 273 | "dev %s ep%d%s scatterlist error %d/%d\n", |
272 | io->dev->devpath, | 274 | io->dev->devpath, |
273 | usb_pipeendpoint (urb->pipe), | 275 | usb_pipeendpoint (urb->pipe), |
274 | usb_pipein (urb->pipe) ? "in" : "out", | 276 | usb_pipein (urb->pipe) ? "in" : "out", |
275 | urb->status, io->status); | 277 | status, io->status); |
276 | // BUG (); | 278 | // BUG (); |
277 | } | 279 | } |
278 | 280 | ||
279 | if (io->status == 0 && urb->status && urb->status != -ECONNRESET) { | 281 | if (io->status == 0 && status && status != -ECONNRESET) { |
280 | int i, found, status; | 282 | int i, found, retval; |
281 | 283 | ||
282 | io->status = urb->status; | 284 | io->status = status; |
283 | 285 | ||
284 | /* the previous urbs, and this one, completed already. | 286 | /* the previous urbs, and this one, completed already. |
285 | * unlink pending urbs so they won't rx/tx bad data. | 287 | * unlink pending urbs so they won't rx/tx bad data. |
@@ -290,13 +292,13 @@ static void sg_complete (struct urb *urb) | |||
290 | if (!io->urbs [i] || !io->urbs [i]->dev) | 292 | if (!io->urbs [i] || !io->urbs [i]->dev) |
291 | continue; | 293 | continue; |
292 | if (found) { | 294 | if (found) { |
293 | status = usb_unlink_urb (io->urbs [i]); | 295 | retval = usb_unlink_urb (io->urbs [i]); |
294 | if (status != -EINPROGRESS | 296 | if (retval != -EINPROGRESS && |
295 | && status != -ENODEV | 297 | retval != -ENODEV && |
296 | && status != -EBUSY) | 298 | retval != -EBUSY) |
297 | dev_err (&io->dev->dev, | 299 | dev_err (&io->dev->dev, |
298 | "%s, unlink --> %d\n", | 300 | "%s, unlink --> %d\n", |
299 | __FUNCTION__, status); | 301 | __FUNCTION__, retval); |
300 | } else if (urb == io->urbs [i]) | 302 | } else if (urb == io->urbs [i]) |
301 | found = 1; | 303 | found = 1; |
302 | } | 304 | } |
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index d47ae89154a7..2ab222be8fd1 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
@@ -441,6 +441,54 @@ static struct attribute_group dev_attr_grp = { | |||
441 | .attrs = dev_attrs, | 441 | .attrs = dev_attrs, |
442 | }; | 442 | }; |
443 | 443 | ||
444 | /* Binary descriptors */ | ||
445 | |||
446 | static ssize_t | ||
447 | read_descriptors(struct kobject *kobj, struct bin_attribute *attr, | ||
448 | char *buf, loff_t off, size_t count) | ||
449 | { | ||
450 | struct usb_device *udev = to_usb_device( | ||
451 | container_of(kobj, struct device, kobj)); | ||
452 | size_t nleft = count; | ||
453 | size_t srclen, n; | ||
454 | |||
455 | usb_lock_device(udev); | ||
456 | |||
457 | /* The binary attribute begins with the device descriptor */ | ||
458 | srclen = sizeof(struct usb_device_descriptor); | ||
459 | if (off < srclen) { | ||
460 | n = min_t(size_t, nleft, srclen - off); | ||
461 | memcpy(buf, off + (char *) &udev->descriptor, n); | ||
462 | nleft -= n; | ||
463 | buf += n; | ||
464 | off = 0; | ||
465 | } else { | ||
466 | off -= srclen; | ||
467 | } | ||
468 | |||
469 | /* Then follows the raw descriptor entry for the current | ||
470 | * configuration (config plus subsidiary descriptors). | ||
471 | */ | ||
472 | if (udev->actconfig) { | ||
473 | int cfgno = udev->actconfig - udev->config; | ||
474 | |||
475 | srclen = __le16_to_cpu(udev->actconfig->desc.wTotalLength); | ||
476 | if (off < srclen) { | ||
477 | n = min_t(size_t, nleft, srclen - off); | ||
478 | memcpy(buf, off + udev->rawdescriptors[cfgno], n); | ||
479 | nleft -= n; | ||
480 | } | ||
481 | } | ||
482 | usb_unlock_device(udev); | ||
483 | return count - nleft; | ||
484 | } | ||
485 | |||
486 | static struct bin_attribute dev_bin_attr_descriptors = { | ||
487 | .attr = {.name = "descriptors", .mode = 0444}, | ||
488 | .read = read_descriptors, | ||
489 | .size = 18 + 65535, /* dev descr + max-size raw descriptor */ | ||
490 | }; | ||
491 | |||
444 | int usb_create_sysfs_dev_files(struct usb_device *udev) | 492 | int usb_create_sysfs_dev_files(struct usb_device *udev) |
445 | { | 493 | { |
446 | struct device *dev = &udev->dev; | 494 | struct device *dev = &udev->dev; |
@@ -450,6 +498,10 @@ int usb_create_sysfs_dev_files(struct usb_device *udev) | |||
450 | if (retval) | 498 | if (retval) |
451 | return retval; | 499 | return retval; |
452 | 500 | ||
501 | retval = device_create_bin_file(dev, &dev_bin_attr_descriptors); | ||
502 | if (retval) | ||
503 | goto error; | ||
504 | |||
453 | retval = add_persist_attributes(dev); | 505 | retval = add_persist_attributes(dev); |
454 | if (retval) | 506 | if (retval) |
455 | goto error; | 507 | goto error; |
@@ -492,6 +544,7 @@ void usb_remove_sysfs_dev_files(struct usb_device *udev) | |||
492 | device_remove_file(dev, &dev_attr_serial); | 544 | device_remove_file(dev, &dev_attr_serial); |
493 | remove_power_attributes(dev); | 545 | remove_power_attributes(dev); |
494 | remove_persist_attributes(dev); | 546 | remove_persist_attributes(dev); |
547 | device_remove_bin_file(dev, &dev_bin_attr_descriptors); | ||
495 | sysfs_remove_group(&dev->kobj, &dev_attr_grp); | 548 | sysfs_remove_group(&dev->kobj, &dev_attr_grp); |
496 | } | 549 | } |
497 | 550 | ||
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 52ec44b828f3..be630228461c 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c | |||
@@ -440,55 +440,57 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
440 | * @urb: pointer to urb describing a previously submitted request, | 440 | * @urb: pointer to urb describing a previously submitted request, |
441 | * may be NULL | 441 | * may be NULL |
442 | * | 442 | * |
443 | * This routine cancels an in-progress request. URBs complete only | 443 | * This routine cancels an in-progress request. URBs complete only once |
444 | * once per submission, and may be canceled only once per submission. | 444 | * per submission, and may be canceled only once per submission. |
445 | * Successful cancellation means the requests's completion handler will | 445 | * Successful cancellation means termination of @urb will be expedited |
446 | * be called with a status code indicating that the request has been | 446 | * and the completion handler will be called with a status code |
447 | * canceled (rather than any other code) and will quickly be removed | 447 | * indicating that the request has been canceled (rather than any other |
448 | * from host controller data structures. | 448 | * code). |
449 | * | 449 | * |
450 | * This request is always asynchronous. | 450 | * This request is always asynchronous. Success is indicated by |
451 | * Success is indicated by returning -EINPROGRESS, | 451 | * returning -EINPROGRESS, at which time the URB will probably not yet |
452 | * at which time the URB will normally have been unlinked but not yet | 452 | * have been given back to the device driver. When it is eventually |
453 | * given back to the device driver. When it is called, the completion | 453 | * called, the completion function will see @urb->status == -ECONNRESET. |
454 | * function will see urb->status == -ECONNRESET. Failure is indicated | 454 | * Failure is indicated by usb_unlink_urb() returning any other value. |
455 | * by any other return value. Unlinking will fail when the URB is not | 455 | * Unlinking will fail when @urb is not currently "linked" (i.e., it was |
456 | * currently "linked" (i.e., it was never submitted, or it was unlinked | 456 | * never submitted, or it was unlinked before, or the hardware is already |
457 | * before, or the hardware is already finished with it), even if the | 457 | * finished with it), even if the completion handler has not yet run. |
458 | * completion handler has not yet run. | ||
459 | * | 458 | * |
460 | * Unlinking and Endpoint Queues: | 459 | * Unlinking and Endpoint Queues: |
461 | * | 460 | * |
461 | * [The behaviors and guarantees described below do not apply to virtual | ||
462 | * root hubs but only to endpoint queues for physical USB devices.] | ||
463 | * | ||
462 | * Host Controller Drivers (HCDs) place all the URBs for a particular | 464 | * Host Controller Drivers (HCDs) place all the URBs for a particular |
463 | * endpoint in a queue. Normally the queue advances as the controller | 465 | * endpoint in a queue. Normally the queue advances as the controller |
464 | * hardware processes each request. But when an URB terminates with an | 466 | * hardware processes each request. But when an URB terminates with an |
465 | * error its queue stops, at least until that URB's completion routine | 467 | * error its queue generally stops (see below), at least until that URB's |
466 | * returns. It is guaranteed that the queue will not restart until all | 468 | * completion routine returns. It is guaranteed that a stopped queue |
467 | * its unlinked URBs have been fully retired, with their completion | 469 | * will not restart until all its unlinked URBs have been fully retired, |
468 | * routines run, even if that's not until some time after the original | 470 | * with their completion routines run, even if that's not until some time |
469 | * completion handler returns. Normally the same behavior and guarantees | 471 | * after the original completion handler returns. The same behavior and |
470 | * apply when an URB terminates because it was unlinked; however if an | 472 | * guarantee apply when an URB terminates because it was unlinked. |
471 | * URB is unlinked before the hardware has started to execute it, then | 473 | * |
472 | * its queue is not guaranteed to stop until all the preceding URBs have | 474 | * Bulk and interrupt endpoint queues are guaranteed to stop whenever an |
473 | * completed. | 475 | * URB terminates with any sort of error, including -ECONNRESET, -ENOENT, |
474 | * | 476 | * and -EREMOTEIO. Control endpoint queues behave the same way except |
475 | * This means that USB device drivers can safely build deep queues for | 477 | * that they are not guaranteed to stop for -EREMOTEIO errors. Queues |
476 | * large or complex transfers, and clean them up reliably after any sort | 478 | * for isochronous endpoints are treated differently, because they must |
477 | * of aborted transfer by unlinking all pending URBs at the first fault. | 479 | * advance at fixed rates. Such queues do not stop when an URB |
478 | * | 480 | * encounters an error or is unlinked. An unlinked isochronous URB may |
479 | * Note that an URB terminating early because a short packet was received | 481 | * leave a gap in the stream of packets; it is undefined whether such |
480 | * will count as an error if and only if the URB_SHORT_NOT_OK flag is set. | 482 | * gaps can be filled in. |
481 | * Also, that all unlinks performed in any URB completion handler must | 483 | * |
482 | * be asynchronous. | 484 | * Note that early termination of an URB because a short packet was |
483 | * | 485 | * received will generate a -EREMOTEIO error if and only if the |
484 | * Queues for isochronous endpoints are treated differently, because they | 486 | * URB_SHORT_NOT_OK flag is set. By setting this flag, USB device |
485 | * advance at fixed rates. Such queues do not stop when an URB is unlinked. | 487 | * drivers can build deep queues for large or complex bulk transfers |
486 | * An unlinked URB may leave a gap in the stream of packets. It is undefined | 488 | * and clean them up reliably after any sort of aborted transfer by |
487 | * whether such gaps can be filled in. | 489 | * unlinking all pending URBs at the first fault. |
488 | * | 490 | * |
489 | * When a control URB terminates with an error, it is likely that the | 491 | * When a control URB terminates with an error other than -EREMOTEIO, it |
490 | * status stage of the transfer will not take place, even if it is merely | 492 | * is quite likely that the status stage of the transfer will not take |
491 | * a soft error resulting from a short-packet with URB_SHORT_NOT_OK set. | 493 | * place. |
492 | */ | 494 | */ |
493 | int usb_unlink_urb(struct urb *urb) | 495 | int usb_unlink_urb(struct urb *urb) |
494 | { | 496 | { |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 45e01e289455..767aed5b4bea 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -82,6 +82,27 @@ choice | |||
82 | Many controller drivers are platform-specific; these | 82 | Many controller drivers are platform-specific; these |
83 | often need board-specific hooks. | 83 | often need board-specific hooks. |
84 | 84 | ||
85 | config USB_GADGET_AMD5536UDC | ||
86 | boolean "AMD5536 UDC" | ||
87 | depends on PCI | ||
88 | select USB_GADGET_DUALSPEED | ||
89 | help | ||
90 | The AMD5536 UDC is part of the AMD Geode CS5536, an x86 southbridge. | ||
91 | It is a USB Highspeed DMA capable USB device controller. Beside ep0 | ||
92 | it provides 4 IN and 4 OUT endpoints (bulk or interrupt type). | ||
93 | The UDC port supports OTG operation, and may be used as a host port | ||
94 | if it's not being used to implement peripheral or OTG roles. | ||
95 | |||
96 | Say "y" to link the driver statically, or "m" to build a | ||
97 | dynamically linked module called "amd5536udc" and force all | ||
98 | gadget drivers to also be dynamically linked. | ||
99 | |||
100 | config USB_AMD5536UDC | ||
101 | tristate | ||
102 | depends on USB_GADGET_AMD5536UDC | ||
103 | default USB_GADGET | ||
104 | select USB_GADGET_SELECTED | ||
105 | |||
85 | config USB_GADGET_FSL_USB2 | 106 | config USB_GADGET_FSL_USB2 |
86 | boolean "Freescale Highspeed USB DR Peripheral Controller" | 107 | boolean "Freescale Highspeed USB DR Peripheral Controller" |
87 | depends on MPC834x || PPC_MPC831x | 108 | depends on MPC834x || PPC_MPC831x |
@@ -156,6 +177,24 @@ config USB_PXA2XX_SMALL | |||
156 | default y if USB_ETH | 177 | default y if USB_ETH |
157 | default y if USB_G_SERIAL | 178 | default y if USB_G_SERIAL |
158 | 179 | ||
180 | config USB_GADGET_M66592 | ||
181 | boolean "Renesas M66592 USB Peripheral Controller" | ||
182 | select USB_GADGET_DUALSPEED | ||
183 | help | ||
184 | M66592 is a discrete USB peripheral controller chip that | ||
185 | supports both full and high speed USB 2.0 data transfers. | ||
186 | It has seven configurable endpoints, and endpoint zero. | ||
187 | |||
188 | Say "y" to link the driver statically, or "m" to build a | ||
189 | dynamically linked module called "m66592_udc" and force all | ||
190 | gadget drivers to also be dynamically linked. | ||
191 | |||
192 | config USB_M66592 | ||
193 | tristate | ||
194 | depends on USB_GADGET_M66592 | ||
195 | default USB_GADGET | ||
196 | select USB_GADGET_SELECTED | ||
197 | |||
159 | config USB_GADGET_GOKU | 198 | config USB_GADGET_GOKU |
160 | boolean "Toshiba TC86C001 'Goku-S'" | 199 | boolean "Toshiba TC86C001 'Goku-S'" |
161 | depends on PCI | 200 | depends on PCI |
@@ -261,24 +300,6 @@ config USB_AT91 | |||
261 | depends on USB_GADGET_AT91 | 300 | depends on USB_GADGET_AT91 |
262 | default USB_GADGET | 301 | default USB_GADGET |
263 | 302 | ||
264 | config USB_GADGET_M66592 | ||
265 | boolean "M66592 driver" | ||
266 | select USB_GADGET_DUALSPEED | ||
267 | help | ||
268 | M66592 is a USB 2.0 peripheral controller. | ||
269 | |||
270 | It has seven configurable endpoints, and endpoint zero. | ||
271 | |||
272 | Say "y" to link the driver statically, or "m" to build a | ||
273 | dynamically linked module called "m66592_udc" and force all | ||
274 | gadget drivers to also be dynamically linked. | ||
275 | |||
276 | config USB_M66592 | ||
277 | tristate | ||
278 | depends on USB_GADGET_M66592 | ||
279 | default USB_GADGET | ||
280 | select USB_GADGET_SELECTED | ||
281 | |||
282 | config USB_GADGET_DUMMY_HCD | 303 | config USB_GADGET_DUMMY_HCD |
283 | boolean "Dummy HCD (DEVELOPMENT)" | 304 | boolean "Dummy HCD (DEVELOPMENT)" |
284 | depends on (USB=y || (USB=m && USB_GADGET=m)) && EXPERIMENTAL | 305 | depends on (USB=y || (USB=m && USB_GADGET=m)) && EXPERIMENTAL |
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 8ae76f738635..1bc0f03550ce 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile | |||
@@ -7,6 +7,7 @@ endif | |||
7 | 7 | ||
8 | obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o | 8 | obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o |
9 | obj-$(CONFIG_USB_NET2280) += net2280.o | 9 | obj-$(CONFIG_USB_NET2280) += net2280.o |
10 | obj-$(CONFIG_USB_AMD5536UDC) += amd5536udc.o | ||
10 | obj-$(CONFIG_USB_PXA2XX) += pxa2xx_udc.o | 11 | obj-$(CONFIG_USB_PXA2XX) += pxa2xx_udc.o |
11 | obj-$(CONFIG_USB_GOKU) += goku_udc.o | 12 | obj-$(CONFIG_USB_GOKU) += goku_udc.o |
12 | obj-$(CONFIG_USB_OMAP) += omap_udc.o | 13 | obj-$(CONFIG_USB_OMAP) += omap_udc.o |
diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c new file mode 100644 index 000000000000..714156ca8fe4 --- /dev/null +++ b/drivers/usb/gadget/amd5536udc.c | |||
@@ -0,0 +1,3454 @@ | |||
1 | /* | ||
2 | * amd5536.c -- AMD 5536 UDC high/full speed USB device controller | ||
3 | * | ||
4 | * Copyright (C) 2005-2007 AMD (http://www.amd.com) | ||
5 | * Author: Thomas Dahlmann | ||
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 | * 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 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | /* | ||
23 | * The AMD5536 UDC is part of the x86 southbridge AMD Geode CS5536. | ||
24 | * It is a USB Highspeed DMA capable USB device controller. Beside ep0 it | ||
25 | * provides 4 IN and 4 OUT endpoints (bulk or interrupt type). | ||
26 | * | ||
27 | * Make sure that UDC is assigned to port 4 by BIOS settings (port can also | ||
28 | * be used as host port) and UOC bits PAD_EN and APU are set (should be done | ||
29 | * by BIOS init). | ||
30 | * | ||
31 | * UDC DMA requires 32-bit aligned buffers so DMA with gadget ether does not | ||
32 | * work without updating NET_IP_ALIGN. Or PIO mode (module param "use_dma=0") | ||
33 | * can be used with gadget ether. | ||
34 | */ | ||
35 | |||
36 | /* debug control */ | ||
37 | /* #define UDC_VERBOSE */ | ||
38 | |||
39 | /* Driver strings */ | ||
40 | #define UDC_MOD_DESCRIPTION "AMD 5536 UDC - USB Device Controller" | ||
41 | #define UDC_DRIVER_VERSION_STRING "01.00.0206 - $Revision: #3 $" | ||
42 | |||
43 | /* system */ | ||
44 | #include <linux/module.h> | ||
45 | #include <linux/pci.h> | ||
46 | #include <linux/kernel.h> | ||
47 | #include <linux/version.h> | ||
48 | #include <linux/delay.h> | ||
49 | #include <linux/ioport.h> | ||
50 | #include <linux/sched.h> | ||
51 | #include <linux/slab.h> | ||
52 | #include <linux/smp_lock.h> | ||
53 | #include <linux/errno.h> | ||
54 | #include <linux/init.h> | ||
55 | #include <linux/timer.h> | ||
56 | #include <linux/list.h> | ||
57 | #include <linux/interrupt.h> | ||
58 | #include <linux/ioctl.h> | ||
59 | #include <linux/fs.h> | ||
60 | #include <linux/dmapool.h> | ||
61 | #include <linux/moduleparam.h> | ||
62 | #include <linux/device.h> | ||
63 | #include <linux/io.h> | ||
64 | #include <linux/irq.h> | ||
65 | |||
66 | #include <asm/byteorder.h> | ||
67 | #include <asm/system.h> | ||
68 | #include <asm/unaligned.h> | ||
69 | |||
70 | /* gadget stack */ | ||
71 | #include <linux/usb/ch9.h> | ||
72 | #include <linux/usb_gadget.h> | ||
73 | |||
74 | /* udc specific */ | ||
75 | #include "amd5536udc.h" | ||
76 | |||
77 | |||
78 | static void udc_tasklet_disconnect(unsigned long); | ||
79 | static void empty_req_queue(struct udc_ep *); | ||
80 | static int udc_probe(struct udc *dev); | ||
81 | static void udc_basic_init(struct udc *dev); | ||
82 | static void udc_setup_endpoints(struct udc *dev); | ||
83 | static void udc_soft_reset(struct udc *dev); | ||
84 | static struct udc_request *udc_alloc_bna_dummy(struct udc_ep *ep); | ||
85 | static void udc_free_request(struct usb_ep *usbep, struct usb_request *usbreq); | ||
86 | static int udc_free_dma_chain(struct udc *dev, struct udc_request *req); | ||
87 | static int udc_create_dma_chain(struct udc_ep *ep, struct udc_request *req, | ||
88 | unsigned long buf_len, gfp_t gfp_flags); | ||
89 | static int udc_remote_wakeup(struct udc *dev); | ||
90 | static int udc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id); | ||
91 | static void udc_pci_remove(struct pci_dev *pdev); | ||
92 | |||
93 | /* description */ | ||
94 | static const char mod_desc[] = UDC_MOD_DESCRIPTION; | ||
95 | static const char name[] = "amd5536udc"; | ||
96 | |||
97 | /* structure to hold endpoint function pointers */ | ||
98 | static const struct usb_ep_ops udc_ep_ops; | ||
99 | |||
100 | /* received setup data */ | ||
101 | static union udc_setup_data setup_data; | ||
102 | |||
103 | /* pointer to device object */ | ||
104 | static struct udc *udc; | ||
105 | |||
106 | /* irq spin lock for soft reset */ | ||
107 | static DEFINE_SPINLOCK(udc_irq_spinlock); | ||
108 | /* stall spin lock */ | ||
109 | static DEFINE_SPINLOCK(udc_stall_spinlock); | ||
110 | |||
111 | /* | ||
112 | * slave mode: pending bytes in rx fifo after nyet, | ||
113 | * used if EPIN irq came but no req was available | ||
114 | */ | ||
115 | static unsigned int udc_rxfifo_pending; | ||
116 | |||
117 | /* count soft resets after suspend to avoid loop */ | ||
118 | static int soft_reset_occured; | ||
119 | static int soft_reset_after_usbreset_occured; | ||
120 | |||
121 | /* timer */ | ||
122 | static struct timer_list udc_timer; | ||
123 | static int stop_timer; | ||
124 | |||
125 | /* set_rde -- Is used to control enabling of RX DMA. Problem is | ||
126 | * that UDC has only one bit (RDE) to enable/disable RX DMA for | ||
127 | * all OUT endpoints. So we have to handle race conditions like | ||
128 | * when OUT data reaches the fifo but no request was queued yet. | ||
129 | * This cannot be solved by letting the RX DMA disabled until a | ||
130 | * request gets queued because there may be other OUT packets | ||
131 | * in the FIFO (important for not blocking control traffic). | ||
132 | * The value of set_rde controls the correspondig timer. | ||
133 | * | ||
134 | * set_rde -1 == not used, means it is alloed to be set to 0 or 1 | ||
135 | * set_rde 0 == do not touch RDE, do no start the RDE timer | ||
136 | * set_rde 1 == timer function will look whether FIFO has data | ||
137 | * set_rde 2 == set by timer function to enable RX DMA on next call | ||
138 | */ | ||
139 | static int set_rde = -1; | ||
140 | |||
141 | static DECLARE_COMPLETION(on_exit); | ||
142 | static struct timer_list udc_pollstall_timer; | ||
143 | static int stop_pollstall_timer; | ||
144 | static DECLARE_COMPLETION(on_pollstall_exit); | ||
145 | |||
146 | /* tasklet for usb disconnect */ | ||
147 | static DECLARE_TASKLET(disconnect_tasklet, udc_tasklet_disconnect, | ||
148 | (unsigned long) &udc); | ||
149 | |||
150 | |||
151 | /* endpoint names used for print */ | ||
152 | static const char ep0_string[] = "ep0in"; | ||
153 | static const char *ep_string[] = { | ||
154 | ep0_string, | ||
155 | "ep1in-int", "ep2in-bulk", "ep3in-bulk", "ep4in-bulk", "ep5in-bulk", | ||
156 | "ep6in-bulk", "ep7in-bulk", "ep8in-bulk", "ep9in-bulk", "ep10in-bulk", | ||
157 | "ep11in-bulk", "ep12in-bulk", "ep13in-bulk", "ep14in-bulk", | ||
158 | "ep15in-bulk", "ep0out", "ep1out-bulk", "ep2out-bulk", "ep3out-bulk", | ||
159 | "ep4out-bulk", "ep5out-bulk", "ep6out-bulk", "ep7out-bulk", | ||
160 | "ep8out-bulk", "ep9out-bulk", "ep10out-bulk", "ep11out-bulk", | ||
161 | "ep12out-bulk", "ep13out-bulk", "ep14out-bulk", "ep15out-bulk" | ||
162 | }; | ||
163 | |||
164 | /* DMA usage flag */ | ||
165 | static int use_dma = 1; | ||
166 | /* packet per buffer dma */ | ||
167 | static int use_dma_ppb = 1; | ||
168 | /* with per descr. update */ | ||
169 | static int use_dma_ppb_du; | ||
170 | /* buffer fill mode */ | ||
171 | static int use_dma_bufferfill_mode; | ||
172 | /* full speed only mode */ | ||
173 | static int use_fullspeed; | ||
174 | /* tx buffer size for high speed */ | ||
175 | static unsigned long hs_tx_buf = UDC_EPIN_BUFF_SIZE; | ||
176 | |||
177 | /* module parameters */ | ||
178 | module_param(use_dma, bool, S_IRUGO); | ||
179 | MODULE_PARM_DESC(use_dma, "true for DMA"); | ||
180 | module_param(use_dma_ppb, bool, S_IRUGO); | ||
181 | MODULE_PARM_DESC(use_dma_ppb, "true for DMA in packet per buffer mode"); | ||
182 | module_param(use_dma_ppb_du, bool, S_IRUGO); | ||
183 | MODULE_PARM_DESC(use_dma_ppb_du, | ||
184 | "true for DMA in packet per buffer mode with descriptor update"); | ||
185 | module_param(use_fullspeed, bool, S_IRUGO); | ||
186 | MODULE_PARM_DESC(use_fullspeed, "true for fullspeed only"); | ||
187 | |||
188 | /*---------------------------------------------------------------------------*/ | ||
189 | /* Prints UDC device registers and endpoint irq registers */ | ||
190 | static void print_regs(struct udc *dev) | ||
191 | { | ||
192 | DBG(dev, "------- Device registers -------\n"); | ||
193 | DBG(dev, "dev config = %08x\n", readl(&dev->regs->cfg)); | ||
194 | DBG(dev, "dev control = %08x\n", readl(&dev->regs->ctl)); | ||
195 | DBG(dev, "dev status = %08x\n", readl(&dev->regs->sts)); | ||
196 | DBG(dev, "\n"); | ||
197 | DBG(dev, "dev int's = %08x\n", readl(&dev->regs->irqsts)); | ||
198 | DBG(dev, "dev intmask = %08x\n", readl(&dev->regs->irqmsk)); | ||
199 | DBG(dev, "\n"); | ||
200 | DBG(dev, "dev ep int's = %08x\n", readl(&dev->regs->ep_irqsts)); | ||
201 | DBG(dev, "dev ep intmask = %08x\n", readl(&dev->regs->ep_irqmsk)); | ||
202 | DBG(dev, "\n"); | ||
203 | DBG(dev, "USE DMA = %d\n", use_dma); | ||
204 | if (use_dma && use_dma_ppb && !use_dma_ppb_du) { | ||
205 | DBG(dev, "DMA mode = PPBNDU (packet per buffer " | ||
206 | "WITHOUT desc. update)\n"); | ||
207 | dev_info(&dev->pdev->dev, "DMA mode (%s)\n", "PPBNDU"); | ||
208 | } else if (use_dma && use_dma_ppb_du && use_dma_ppb_du) { | ||
209 | DBG(dev, "DMA mode = PPBDU (packet per buffer " | ||
210 | "WITH desc. update)\n"); | ||
211 | dev_info(&dev->pdev->dev, "DMA mode (%s)\n", "PPBDU"); | ||
212 | } | ||
213 | if (use_dma && use_dma_bufferfill_mode) { | ||
214 | DBG(dev, "DMA mode = BF (buffer fill mode)\n"); | ||
215 | dev_info(&dev->pdev->dev, "DMA mode (%s)\n", "BF"); | ||
216 | } | ||
217 | if (!use_dma) { | ||
218 | dev_info(&dev->pdev->dev, "FIFO mode\n"); | ||
219 | } | ||
220 | DBG(dev, "-------------------------------------------------------\n"); | ||
221 | } | ||
222 | |||
223 | /* Masks unused interrupts */ | ||
224 | static int udc_mask_unused_interrupts(struct udc *dev) | ||
225 | { | ||
226 | u32 tmp; | ||
227 | |||
228 | /* mask all dev interrupts */ | ||
229 | tmp = AMD_BIT(UDC_DEVINT_SVC) | | ||
230 | AMD_BIT(UDC_DEVINT_ENUM) | | ||
231 | AMD_BIT(UDC_DEVINT_US) | | ||
232 | AMD_BIT(UDC_DEVINT_UR) | | ||
233 | AMD_BIT(UDC_DEVINT_ES) | | ||
234 | AMD_BIT(UDC_DEVINT_SI) | | ||
235 | AMD_BIT(UDC_DEVINT_SOF)| | ||
236 | AMD_BIT(UDC_DEVINT_SC); | ||
237 | writel(tmp, &dev->regs->irqmsk); | ||
238 | |||
239 | /* mask all ep interrupts */ | ||
240 | writel(UDC_EPINT_MSK_DISABLE_ALL, &dev->regs->ep_irqmsk); | ||
241 | |||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | /* Enables endpoint 0 interrupts */ | ||
246 | static int udc_enable_ep0_interrupts(struct udc *dev) | ||
247 | { | ||
248 | u32 tmp; | ||
249 | |||
250 | DBG(dev, "udc_enable_ep0_interrupts()\n"); | ||
251 | |||
252 | /* read irq mask */ | ||
253 | tmp = readl(&dev->regs->ep_irqmsk); | ||
254 | /* enable ep0 irq's */ | ||
255 | tmp &= AMD_UNMASK_BIT(UDC_EPINT_IN_EP0) | ||
256 | & AMD_UNMASK_BIT(UDC_EPINT_OUT_EP0); | ||
257 | writel(tmp, &dev->regs->ep_irqmsk); | ||
258 | |||
259 | return 0; | ||
260 | } | ||
261 | |||
262 | /* Enables device interrupts for SET_INTF and SET_CONFIG */ | ||
263 | static int udc_enable_dev_setup_interrupts(struct udc *dev) | ||
264 | { | ||
265 | u32 tmp; | ||
266 | |||
267 | DBG(dev, "enable device interrupts for setup data\n"); | ||
268 | |||
269 | /* read irq mask */ | ||
270 | tmp = readl(&dev->regs->irqmsk); | ||
271 | |||
272 | /* enable SET_INTERFACE, SET_CONFIG and other needed irq's */ | ||
273 | tmp &= AMD_UNMASK_BIT(UDC_DEVINT_SI) | ||
274 | & AMD_UNMASK_BIT(UDC_DEVINT_SC) | ||
275 | & AMD_UNMASK_BIT(UDC_DEVINT_UR) | ||
276 | & AMD_UNMASK_BIT(UDC_DEVINT_SVC) | ||
277 | & AMD_UNMASK_BIT(UDC_DEVINT_ENUM); | ||
278 | writel(tmp, &dev->regs->irqmsk); | ||
279 | |||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | /* Calculates fifo start of endpoint based on preceeding endpoints */ | ||
284 | static int udc_set_txfifo_addr(struct udc_ep *ep) | ||
285 | { | ||
286 | struct udc *dev; | ||
287 | u32 tmp; | ||
288 | int i; | ||
289 | |||
290 | if (!ep || !(ep->in)) | ||
291 | return -EINVAL; | ||
292 | |||
293 | dev = ep->dev; | ||
294 | ep->txfifo = dev->txfifo; | ||
295 | |||
296 | /* traverse ep's */ | ||
297 | for (i = 0; i < ep->num; i++) { | ||
298 | if (dev->ep[i].regs) { | ||
299 | /* read fifo size */ | ||
300 | tmp = readl(&dev->ep[i].regs->bufin_framenum); | ||
301 | tmp = AMD_GETBITS(tmp, UDC_EPIN_BUFF_SIZE); | ||
302 | ep->txfifo += tmp; | ||
303 | } | ||
304 | } | ||
305 | return 0; | ||
306 | } | ||
307 | |||
308 | /* CNAK pending field: bit0 = ep0in, bit16 = ep0out */ | ||
309 | static u32 cnak_pending; | ||
310 | |||
311 | static void UDC_QUEUE_CNAK(struct udc_ep *ep, unsigned num) | ||
312 | { | ||
313 | if (readl(&ep->regs->ctl) & AMD_BIT(UDC_EPCTL_NAK)) { | ||
314 | DBG(ep->dev, "NAK could not be cleared for ep%d\n", num); | ||
315 | cnak_pending |= 1 << (num); | ||
316 | ep->naking = 1; | ||
317 | } else | ||
318 | cnak_pending = cnak_pending & (~(1 << (num))); | ||
319 | } | ||
320 | |||
321 | |||
322 | /* Enables endpoint, is called by gadget driver */ | ||
323 | static int | ||
324 | udc_ep_enable(struct usb_ep *usbep, const struct usb_endpoint_descriptor *desc) | ||
325 | { | ||
326 | struct udc_ep *ep; | ||
327 | struct udc *dev; | ||
328 | u32 tmp; | ||
329 | unsigned long iflags; | ||
330 | u8 udc_csr_epix; | ||
331 | |||
332 | if (!usbep | ||
333 | || usbep->name == ep0_string | ||
334 | || !desc | ||
335 | || desc->bDescriptorType != USB_DT_ENDPOINT) | ||
336 | return -EINVAL; | ||
337 | |||
338 | ep = container_of(usbep, struct udc_ep, ep); | ||
339 | dev = ep->dev; | ||
340 | |||
341 | DBG(dev, "udc_ep_enable() ep %d\n", ep->num); | ||
342 | |||
343 | if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
344 | return -ESHUTDOWN; | ||
345 | |||
346 | spin_lock_irqsave(&dev->lock, iflags); | ||
347 | ep->desc = desc; | ||
348 | |||
349 | ep->halted = 0; | ||
350 | |||
351 | /* set traffic type */ | ||
352 | tmp = readl(&dev->ep[ep->num].regs->ctl); | ||
353 | tmp = AMD_ADDBITS(tmp, desc->bmAttributes, UDC_EPCTL_ET); | ||
354 | writel(tmp, &dev->ep[ep->num].regs->ctl); | ||
355 | |||
356 | /* set max packet size */ | ||
357 | tmp = readl(&dev->ep[ep->num].regs->bufout_maxpkt); | ||
358 | tmp = AMD_ADDBITS(tmp, desc->wMaxPacketSize, UDC_EP_MAX_PKT_SIZE); | ||
359 | ep->ep.maxpacket = desc->wMaxPacketSize; | ||
360 | writel(tmp, &dev->ep[ep->num].regs->bufout_maxpkt); | ||
361 | |||
362 | /* IN ep */ | ||
363 | if (ep->in) { | ||
364 | |||
365 | /* ep ix in UDC CSR register space */ | ||
366 | udc_csr_epix = ep->num; | ||
367 | |||
368 | /* set buffer size (tx fifo entries) */ | ||
369 | tmp = readl(&dev->ep[ep->num].regs->bufin_framenum); | ||
370 | /* double buffering: fifo size = 2 x max packet size */ | ||
371 | tmp = AMD_ADDBITS( | ||
372 | tmp, | ||
373 | desc->wMaxPacketSize * UDC_EPIN_BUFF_SIZE_MULT | ||
374 | / UDC_DWORD_BYTES, | ||
375 | UDC_EPIN_BUFF_SIZE); | ||
376 | writel(tmp, &dev->ep[ep->num].regs->bufin_framenum); | ||
377 | |||
378 | /* calc. tx fifo base addr */ | ||
379 | udc_set_txfifo_addr(ep); | ||
380 | |||
381 | /* flush fifo */ | ||
382 | tmp = readl(&ep->regs->ctl); | ||
383 | tmp |= AMD_BIT(UDC_EPCTL_F); | ||
384 | writel(tmp, &ep->regs->ctl); | ||
385 | |||
386 | /* OUT ep */ | ||
387 | } else { | ||
388 | /* ep ix in UDC CSR register space */ | ||
389 | udc_csr_epix = ep->num - UDC_CSR_EP_OUT_IX_OFS; | ||
390 | |||
391 | /* set max packet size UDC CSR */ | ||
392 | tmp = readl(&dev->csr->ne[ep->num - UDC_CSR_EP_OUT_IX_OFS]); | ||
393 | tmp = AMD_ADDBITS(tmp, desc->wMaxPacketSize, | ||
394 | UDC_CSR_NE_MAX_PKT); | ||
395 | writel(tmp, &dev->csr->ne[ep->num - UDC_CSR_EP_OUT_IX_OFS]); | ||
396 | |||
397 | if (use_dma && !ep->in) { | ||
398 | /* alloc and init BNA dummy request */ | ||
399 | ep->bna_dummy_req = udc_alloc_bna_dummy(ep); | ||
400 | ep->bna_occurred = 0; | ||
401 | } | ||
402 | |||
403 | if (ep->num != UDC_EP0OUT_IX) | ||
404 | dev->data_ep_enabled = 1; | ||
405 | } | ||
406 | |||
407 | /* set ep values */ | ||
408 | tmp = readl(&dev->csr->ne[udc_csr_epix]); | ||
409 | /* max packet */ | ||
410 | tmp = AMD_ADDBITS(tmp, desc->wMaxPacketSize, UDC_CSR_NE_MAX_PKT); | ||
411 | /* ep number */ | ||
412 | tmp = AMD_ADDBITS(tmp, desc->bEndpointAddress, UDC_CSR_NE_NUM); | ||
413 | /* ep direction */ | ||
414 | tmp = AMD_ADDBITS(tmp, ep->in, UDC_CSR_NE_DIR); | ||
415 | /* ep type */ | ||
416 | tmp = AMD_ADDBITS(tmp, desc->bmAttributes, UDC_CSR_NE_TYPE); | ||
417 | /* ep config */ | ||
418 | tmp = AMD_ADDBITS(tmp, ep->dev->cur_config, UDC_CSR_NE_CFG); | ||
419 | /* ep interface */ | ||
420 | tmp = AMD_ADDBITS(tmp, ep->dev->cur_intf, UDC_CSR_NE_INTF); | ||
421 | /* ep alt */ | ||
422 | tmp = AMD_ADDBITS(tmp, ep->dev->cur_alt, UDC_CSR_NE_ALT); | ||
423 | /* write reg */ | ||
424 | writel(tmp, &dev->csr->ne[udc_csr_epix]); | ||
425 | |||
426 | /* enable ep irq */ | ||
427 | tmp = readl(&dev->regs->ep_irqmsk); | ||
428 | tmp &= AMD_UNMASK_BIT(ep->num); | ||
429 | writel(tmp, &dev->regs->ep_irqmsk); | ||
430 | |||
431 | /* | ||
432 | * clear NAK by writing CNAK | ||
433 | * avoid BNA for OUT DMA, don't clear NAK until DMA desc. written | ||
434 | */ | ||
435 | if (!use_dma || ep->in) { | ||
436 | tmp = readl(&ep->regs->ctl); | ||
437 | tmp |= AMD_BIT(UDC_EPCTL_CNAK); | ||
438 | writel(tmp, &ep->regs->ctl); | ||
439 | ep->naking = 0; | ||
440 | UDC_QUEUE_CNAK(ep, ep->num); | ||
441 | } | ||
442 | tmp = desc->bEndpointAddress; | ||
443 | DBG(dev, "%s enabled\n", usbep->name); | ||
444 | |||
445 | spin_unlock_irqrestore(&dev->lock, iflags); | ||
446 | return 0; | ||
447 | } | ||
448 | |||
449 | /* Resets endpoint */ | ||
450 | static void ep_init(struct udc_regs __iomem *regs, struct udc_ep *ep) | ||
451 | { | ||
452 | u32 tmp; | ||
453 | |||
454 | VDBG(ep->dev, "ep-%d reset\n", ep->num); | ||
455 | ep->desc = NULL; | ||
456 | ep->ep.ops = &udc_ep_ops; | ||
457 | INIT_LIST_HEAD(&ep->queue); | ||
458 | |||
459 | ep->ep.maxpacket = (u16) ~0; | ||
460 | /* set NAK */ | ||
461 | tmp = readl(&ep->regs->ctl); | ||
462 | tmp |= AMD_BIT(UDC_EPCTL_SNAK); | ||
463 | writel(tmp, &ep->regs->ctl); | ||
464 | ep->naking = 1; | ||
465 | |||
466 | /* disable interrupt */ | ||
467 | tmp = readl(®s->ep_irqmsk); | ||
468 | tmp |= AMD_BIT(ep->num); | ||
469 | writel(tmp, ®s->ep_irqmsk); | ||
470 | |||
471 | if (ep->in) { | ||
472 | /* unset P and IN bit of potential former DMA */ | ||
473 | tmp = readl(&ep->regs->ctl); | ||
474 | tmp &= AMD_UNMASK_BIT(UDC_EPCTL_P); | ||
475 | writel(tmp, &ep->regs->ctl); | ||
476 | |||
477 | tmp = readl(&ep->regs->sts); | ||
478 | tmp |= AMD_BIT(UDC_EPSTS_IN); | ||
479 | writel(tmp, &ep->regs->sts); | ||
480 | |||
481 | /* flush the fifo */ | ||
482 | tmp = readl(&ep->regs->ctl); | ||
483 | tmp |= AMD_BIT(UDC_EPCTL_F); | ||
484 | writel(tmp, &ep->regs->ctl); | ||
485 | |||
486 | } | ||
487 | /* reset desc pointer */ | ||
488 | writel(0, &ep->regs->desptr); | ||
489 | } | ||
490 | |||
491 | /* Disables endpoint, is called by gadget driver */ | ||
492 | static int udc_ep_disable(struct usb_ep *usbep) | ||
493 | { | ||
494 | struct udc_ep *ep = NULL; | ||
495 | unsigned long iflags; | ||
496 | |||
497 | if (!usbep) | ||
498 | return -EINVAL; | ||
499 | |||
500 | ep = container_of(usbep, struct udc_ep, ep); | ||
501 | if (usbep->name == ep0_string || !ep->desc) | ||
502 | return -EINVAL; | ||
503 | |||
504 | DBG(ep->dev, "Disable ep-%d\n", ep->num); | ||
505 | |||
506 | spin_lock_irqsave(&ep->dev->lock, iflags); | ||
507 | udc_free_request(&ep->ep, &ep->bna_dummy_req->req); | ||
508 | empty_req_queue(ep); | ||
509 | ep_init(ep->dev->regs, ep); | ||
510 | spin_unlock_irqrestore(&ep->dev->lock, iflags); | ||
511 | |||
512 | return 0; | ||
513 | } | ||
514 | |||
515 | /* Allocates request packet, called by gadget driver */ | ||
516 | static struct usb_request * | ||
517 | udc_alloc_request(struct usb_ep *usbep, gfp_t gfp) | ||
518 | { | ||
519 | struct udc_request *req; | ||
520 | struct udc_data_dma *dma_desc; | ||
521 | struct udc_ep *ep; | ||
522 | |||
523 | if (!usbep) | ||
524 | return NULL; | ||
525 | |||
526 | ep = container_of(usbep, struct udc_ep, ep); | ||
527 | |||
528 | VDBG(ep->dev, "udc_alloc_req(): ep%d\n", ep->num); | ||
529 | req = kzalloc(sizeof(struct udc_request), gfp); | ||
530 | if (!req) | ||
531 | return NULL; | ||
532 | |||
533 | req->req.dma = DMA_DONT_USE; | ||
534 | INIT_LIST_HEAD(&req->queue); | ||
535 | |||
536 | if (ep->dma) { | ||
537 | /* ep0 in requests are allocated from data pool here */ | ||
538 | dma_desc = pci_pool_alloc(ep->dev->data_requests, gfp, | ||
539 | &req->td_phys); | ||
540 | if (!dma_desc) { | ||
541 | kfree(req); | ||
542 | return NULL; | ||
543 | } | ||
544 | |||
545 | VDBG(ep->dev, "udc_alloc_req: req = %p dma_desc = %p, " | ||
546 | "td_phys = %lx\n", | ||
547 | req, dma_desc, | ||
548 | (unsigned long)req->td_phys); | ||
549 | /* prevent from using desc. - set HOST BUSY */ | ||
550 | dma_desc->status = AMD_ADDBITS(dma_desc->status, | ||
551 | UDC_DMA_STP_STS_BS_HOST_BUSY, | ||
552 | UDC_DMA_STP_STS_BS); | ||
553 | dma_desc->bufptr = __constant_cpu_to_le32(DMA_DONT_USE); | ||
554 | req->td_data = dma_desc; | ||
555 | req->td_data_last = NULL; | ||
556 | req->chain_len = 1; | ||
557 | } | ||
558 | |||
559 | return &req->req; | ||
560 | } | ||
561 | |||
562 | /* Frees request packet, called by gadget driver */ | ||
563 | static void | ||
564 | udc_free_request(struct usb_ep *usbep, struct usb_request *usbreq) | ||
565 | { | ||
566 | struct udc_ep *ep; | ||
567 | struct udc_request *req; | ||
568 | |||
569 | if (!usbep || !usbreq) | ||
570 | return; | ||
571 | |||
572 | ep = container_of(usbep, struct udc_ep, ep); | ||
573 | req = container_of(usbreq, struct udc_request, req); | ||
574 | VDBG(ep->dev, "free_req req=%p\n", req); | ||
575 | BUG_ON(!list_empty(&req->queue)); | ||
576 | if (req->td_data) { | ||
577 | VDBG(ep->dev, "req->td_data=%p\n", req->td_data); | ||
578 | |||
579 | /* free dma chain if created */ | ||
580 | if (req->chain_len > 1) { | ||
581 | udc_free_dma_chain(ep->dev, req); | ||
582 | } | ||
583 | |||
584 | pci_pool_free(ep->dev->data_requests, req->td_data, | ||
585 | req->td_phys); | ||
586 | } | ||
587 | kfree(req); | ||
588 | } | ||
589 | |||
590 | /* Init BNA dummy descriptor for HOST BUSY and pointing to itself */ | ||
591 | static void udc_init_bna_dummy(struct udc_request *req) | ||
592 | { | ||
593 | if (req) { | ||
594 | /* set last bit */ | ||
595 | req->td_data->status |= AMD_BIT(UDC_DMA_IN_STS_L); | ||
596 | /* set next pointer to itself */ | ||
597 | req->td_data->next = req->td_phys; | ||
598 | /* set HOST BUSY */ | ||
599 | req->td_data->status | ||
600 | = AMD_ADDBITS(req->td_data->status, | ||
601 | UDC_DMA_STP_STS_BS_DMA_DONE, | ||
602 | UDC_DMA_STP_STS_BS); | ||
603 | #ifdef UDC_VERBOSE | ||
604 | pr_debug("bna desc = %p, sts = %08x\n", | ||
605 | req->td_data, req->td_data->status); | ||
606 | #endif | ||
607 | } | ||
608 | } | ||
609 | |||
610 | /* Allocate BNA dummy descriptor */ | ||
611 | static struct udc_request *udc_alloc_bna_dummy(struct udc_ep *ep) | ||
612 | { | ||
613 | struct udc_request *req = NULL; | ||
614 | struct usb_request *_req = NULL; | ||
615 | |||
616 | /* alloc the dummy request */ | ||
617 | _req = udc_alloc_request(&ep->ep, GFP_ATOMIC); | ||
618 | if (_req) { | ||
619 | req = container_of(_req, struct udc_request, req); | ||
620 | ep->bna_dummy_req = req; | ||
621 | udc_init_bna_dummy(req); | ||
622 | } | ||
623 | return req; | ||
624 | } | ||
625 | |||
626 | /* Write data to TX fifo for IN packets */ | ||
627 | static void | ||
628 | udc_txfifo_write(struct udc_ep *ep, struct usb_request *req) | ||
629 | { | ||
630 | u8 *req_buf; | ||
631 | u32 *buf; | ||
632 | int i, j; | ||
633 | unsigned bytes = 0; | ||
634 | unsigned remaining = 0; | ||
635 | |||
636 | if (!req || !ep) | ||
637 | return; | ||
638 | |||
639 | req_buf = req->buf + req->actual; | ||
640 | prefetch(req_buf); | ||
641 | remaining = req->length - req->actual; | ||
642 | |||
643 | buf = (u32 *) req_buf; | ||
644 | |||
645 | bytes = ep->ep.maxpacket; | ||
646 | if (bytes > remaining) | ||
647 | bytes = remaining; | ||
648 | |||
649 | /* dwords first */ | ||
650 | for (i = 0; i < bytes / UDC_DWORD_BYTES; i++) { | ||
651 | writel(*(buf + i), ep->txfifo); | ||
652 | } | ||
653 | |||
654 | /* remaining bytes must be written by byte access */ | ||
655 | for (j = 0; j < bytes % UDC_DWORD_BYTES; j++) { | ||
656 | writeb((u8)(*(buf + i) >> (j << UDC_BITS_PER_BYTE_SHIFT)), | ||
657 | ep->txfifo); | ||
658 | } | ||
659 | |||
660 | /* dummy write confirm */ | ||
661 | writel(0, &ep->regs->confirm); | ||
662 | } | ||
663 | |||
664 | /* Read dwords from RX fifo for OUT transfers */ | ||
665 | static int udc_rxfifo_read_dwords(struct udc *dev, u32 *buf, int dwords) | ||
666 | { | ||
667 | int i; | ||
668 | |||
669 | VDBG(dev, "udc_read_dwords(): %d dwords\n", dwords); | ||
670 | |||
671 | for (i = 0; i < dwords; i++) { | ||
672 | *(buf + i) = readl(dev->rxfifo); | ||
673 | } | ||
674 | return 0; | ||
675 | } | ||
676 | |||
677 | /* Read bytes from RX fifo for OUT transfers */ | ||
678 | static int udc_rxfifo_read_bytes(struct udc *dev, u8 *buf, int bytes) | ||
679 | { | ||
680 | int i, j; | ||
681 | u32 tmp; | ||
682 | |||
683 | VDBG(dev, "udc_read_bytes(): %d bytes\n", bytes); | ||
684 | |||
685 | /* dwords first */ | ||
686 | for (i = 0; i < bytes / UDC_DWORD_BYTES; i++) { | ||
687 | *((u32 *)(buf + (i<<2))) = readl(dev->rxfifo); | ||
688 | } | ||
689 | |||
690 | /* remaining bytes must be read by byte access */ | ||
691 | if (bytes % UDC_DWORD_BYTES) { | ||
692 | tmp = readl(dev->rxfifo); | ||
693 | for (j = 0; j < bytes % UDC_DWORD_BYTES; j++) { | ||
694 | *(buf + (i<<2) + j) = (u8)(tmp & UDC_BYTE_MASK); | ||
695 | tmp = tmp >> UDC_BITS_PER_BYTE; | ||
696 | } | ||
697 | } | ||
698 | |||
699 | return 0; | ||
700 | } | ||
701 | |||
702 | /* Read data from RX fifo for OUT transfers */ | ||
703 | static int | ||
704 | udc_rxfifo_read(struct udc_ep *ep, struct udc_request *req) | ||
705 | { | ||
706 | u8 *buf; | ||
707 | unsigned buf_space; | ||
708 | unsigned bytes = 0; | ||
709 | unsigned finished = 0; | ||
710 | |||
711 | /* received number bytes */ | ||
712 | bytes = readl(&ep->regs->sts); | ||
713 | bytes = AMD_GETBITS(bytes, UDC_EPSTS_RX_PKT_SIZE); | ||
714 | |||
715 | buf_space = req->req.length - req->req.actual; | ||
716 | buf = req->req.buf + req->req.actual; | ||
717 | if (bytes > buf_space) { | ||
718 | if ((buf_space % ep->ep.maxpacket) != 0) { | ||
719 | DBG(ep->dev, | ||
720 | "%s: rx %d bytes, rx-buf space = %d bytesn\n", | ||
721 | ep->ep.name, bytes, buf_space); | ||
722 | req->req.status = -EOVERFLOW; | ||
723 | } | ||
724 | bytes = buf_space; | ||
725 | } | ||
726 | req->req.actual += bytes; | ||
727 | |||
728 | /* last packet ? */ | ||
729 | if (((bytes % ep->ep.maxpacket) != 0) || (!bytes) | ||
730 | || ((req->req.actual == req->req.length) && !req->req.zero)) | ||
731 | finished = 1; | ||
732 | |||
733 | /* read rx fifo bytes */ | ||
734 | VDBG(ep->dev, "ep %s: rxfifo read %d bytes\n", ep->ep.name, bytes); | ||
735 | udc_rxfifo_read_bytes(ep->dev, buf, bytes); | ||
736 | |||
737 | return finished; | ||
738 | } | ||
739 | |||
740 | /* create/re-init a DMA descriptor or a DMA descriptor chain */ | ||
741 | static int prep_dma(struct udc_ep *ep, struct udc_request *req, gfp_t gfp) | ||
742 | { | ||
743 | int retval = 0; | ||
744 | u32 tmp; | ||
745 | |||
746 | VDBG(ep->dev, "prep_dma\n"); | ||
747 | VDBG(ep->dev, "prep_dma ep%d req->td_data=%p\n", | ||
748 | ep->num, req->td_data); | ||
749 | |||
750 | /* set buffer pointer */ | ||
751 | req->td_data->bufptr = req->req.dma; | ||
752 | |||
753 | /* set last bit */ | ||
754 | req->td_data->status |= AMD_BIT(UDC_DMA_IN_STS_L); | ||
755 | |||
756 | /* build/re-init dma chain if maxpkt scatter mode, not for EP0 */ | ||
757 | if (use_dma_ppb) { | ||
758 | |||
759 | retval = udc_create_dma_chain(ep, req, ep->ep.maxpacket, gfp); | ||
760 | if (retval != 0) { | ||
761 | if (retval == -ENOMEM) | ||
762 | DBG(ep->dev, "Out of DMA memory\n"); | ||
763 | return retval; | ||
764 | } | ||
765 | if (ep->in) { | ||
766 | if (req->req.length == ep->ep.maxpacket) { | ||
767 | /* write tx bytes */ | ||
768 | req->td_data->status = | ||
769 | AMD_ADDBITS(req->td_data->status, | ||
770 | ep->ep.maxpacket, | ||
771 | UDC_DMA_IN_STS_TXBYTES); | ||
772 | |||
773 | } | ||
774 | } | ||
775 | |||
776 | } | ||
777 | |||
778 | if (ep->in) { | ||
779 | VDBG(ep->dev, "IN: use_dma_ppb=%d req->req.len=%d " | ||
780 | "maxpacket=%d ep%d\n", | ||
781 | use_dma_ppb, req->req.length, | ||
782 | ep->ep.maxpacket, ep->num); | ||
783 | /* | ||
784 | * if bytes < max packet then tx bytes must | ||
785 | * be written in packet per buffer mode | ||
786 | */ | ||
787 | if (!use_dma_ppb || req->req.length < ep->ep.maxpacket | ||
788 | || ep->num == UDC_EP0OUT_IX | ||
789 | || ep->num == UDC_EP0IN_IX) { | ||
790 | /* write tx bytes */ | ||
791 | req->td_data->status = | ||
792 | AMD_ADDBITS(req->td_data->status, | ||
793 | req->req.length, | ||
794 | UDC_DMA_IN_STS_TXBYTES); | ||
795 | /* reset frame num */ | ||
796 | req->td_data->status = | ||
797 | AMD_ADDBITS(req->td_data->status, | ||
798 | 0, | ||
799 | UDC_DMA_IN_STS_FRAMENUM); | ||
800 | } | ||
801 | /* set HOST BUSY */ | ||
802 | req->td_data->status = | ||
803 | AMD_ADDBITS(req->td_data->status, | ||
804 | UDC_DMA_STP_STS_BS_HOST_BUSY, | ||
805 | UDC_DMA_STP_STS_BS); | ||
806 | } else { | ||
807 | VDBG(ep->dev, "OUT set host ready\n"); | ||
808 | /* set HOST READY */ | ||
809 | req->td_data->status = | ||
810 | AMD_ADDBITS(req->td_data->status, | ||
811 | UDC_DMA_STP_STS_BS_HOST_READY, | ||
812 | UDC_DMA_STP_STS_BS); | ||
813 | |||
814 | |||
815 | /* clear NAK by writing CNAK */ | ||
816 | if (ep->naking) { | ||
817 | tmp = readl(&ep->regs->ctl); | ||
818 | tmp |= AMD_BIT(UDC_EPCTL_CNAK); | ||
819 | writel(tmp, &ep->regs->ctl); | ||
820 | ep->naking = 0; | ||
821 | UDC_QUEUE_CNAK(ep, ep->num); | ||
822 | } | ||
823 | |||
824 | } | ||
825 | |||
826 | return retval; | ||
827 | } | ||
828 | |||
829 | /* Completes request packet ... caller MUST hold lock */ | ||
830 | static void | ||
831 | complete_req(struct udc_ep *ep, struct udc_request *req, int sts) | ||
832 | __releases(ep->dev->lock) | ||
833 | __acquires(ep->dev->lock) | ||
834 | { | ||
835 | struct udc *dev; | ||
836 | unsigned halted; | ||
837 | |||
838 | VDBG(ep->dev, "complete_req(): ep%d\n", ep->num); | ||
839 | |||
840 | dev = ep->dev; | ||
841 | /* unmap DMA */ | ||
842 | if (req->dma_mapping) { | ||
843 | if (ep->in) | ||
844 | pci_unmap_single(dev->pdev, | ||
845 | req->req.dma, | ||
846 | req->req.length, | ||
847 | PCI_DMA_TODEVICE); | ||
848 | else | ||
849 | pci_unmap_single(dev->pdev, | ||
850 | req->req.dma, | ||
851 | req->req.length, | ||
852 | PCI_DMA_FROMDEVICE); | ||
853 | req->dma_mapping = 0; | ||
854 | req->req.dma = DMA_DONT_USE; | ||
855 | } | ||
856 | |||
857 | halted = ep->halted; | ||
858 | ep->halted = 1; | ||
859 | |||
860 | /* set new status if pending */ | ||
861 | if (req->req.status == -EINPROGRESS) | ||
862 | req->req.status = sts; | ||
863 | |||
864 | /* remove from ep queue */ | ||
865 | list_del_init(&req->queue); | ||
866 | |||
867 | VDBG(ep->dev, "req %p => complete %d bytes at %s with sts %d\n", | ||
868 | &req->req, req->req.length, ep->ep.name, sts); | ||
869 | |||
870 | spin_unlock(&dev->lock); | ||
871 | req->req.complete(&ep->ep, &req->req); | ||
872 | spin_lock(&dev->lock); | ||
873 | ep->halted = halted; | ||
874 | } | ||
875 | |||
876 | /* frees pci pool descriptors of a DMA chain */ | ||
877 | static int udc_free_dma_chain(struct udc *dev, struct udc_request *req) | ||
878 | { | ||
879 | |||
880 | int ret_val = 0; | ||
881 | struct udc_data_dma *td; | ||
882 | struct udc_data_dma *td_last = NULL; | ||
883 | unsigned int i; | ||
884 | |||
885 | DBG(dev, "free chain req = %p\n", req); | ||
886 | |||
887 | /* do not free first desc., will be done by free for request */ | ||
888 | td_last = req->td_data; | ||
889 | td = phys_to_virt(td_last->next); | ||
890 | |||
891 | for (i = 1; i < req->chain_len; i++) { | ||
892 | |||
893 | pci_pool_free(dev->data_requests, td, | ||
894 | (dma_addr_t) td_last->next); | ||
895 | td_last = td; | ||
896 | td = phys_to_virt(td_last->next); | ||
897 | } | ||
898 | |||
899 | return ret_val; | ||
900 | } | ||
901 | |||
902 | /* Iterates to the end of a DMA chain and returns last descriptor */ | ||
903 | static struct udc_data_dma *udc_get_last_dma_desc(struct udc_request *req) | ||
904 | { | ||
905 | struct udc_data_dma *td; | ||
906 | |||
907 | td = req->td_data; | ||
908 | while (td && !(td->status & AMD_BIT(UDC_DMA_IN_STS_L))) { | ||
909 | td = phys_to_virt(td->next); | ||
910 | } | ||
911 | |||
912 | return td; | ||
913 | |||
914 | } | ||
915 | |||
916 | /* Iterates to the end of a DMA chain and counts bytes received */ | ||
917 | static u32 udc_get_ppbdu_rxbytes(struct udc_request *req) | ||
918 | { | ||
919 | struct udc_data_dma *td; | ||
920 | u32 count; | ||
921 | |||
922 | td = req->td_data; | ||
923 | /* received number bytes */ | ||
924 | count = AMD_GETBITS(td->status, UDC_DMA_OUT_STS_RXBYTES); | ||
925 | |||
926 | while (td && !(td->status & AMD_BIT(UDC_DMA_IN_STS_L))) { | ||
927 | td = phys_to_virt(td->next); | ||
928 | /* received number bytes */ | ||
929 | if (td) { | ||
930 | count += AMD_GETBITS(td->status, | ||
931 | UDC_DMA_OUT_STS_RXBYTES); | ||
932 | } | ||
933 | } | ||
934 | |||
935 | return count; | ||
936 | |||
937 | } | ||
938 | |||
939 | /* Creates or re-inits a DMA chain */ | ||
940 | static int udc_create_dma_chain( | ||
941 | struct udc_ep *ep, | ||
942 | struct udc_request *req, | ||
943 | unsigned long buf_len, gfp_t gfp_flags | ||
944 | ) | ||
945 | { | ||
946 | unsigned long bytes = req->req.length; | ||
947 | unsigned int i; | ||
948 | dma_addr_t dma_addr; | ||
949 | struct udc_data_dma *td = NULL; | ||
950 | struct udc_data_dma *last = NULL; | ||
951 | unsigned long txbytes; | ||
952 | unsigned create_new_chain = 0; | ||
953 | unsigned len; | ||
954 | |||
955 | VDBG(ep->dev, "udc_create_dma_chain: bytes=%ld buf_len=%ld\n", | ||
956 | bytes, buf_len); | ||
957 | dma_addr = DMA_DONT_USE; | ||
958 | |||
959 | /* unset L bit in first desc for OUT */ | ||
960 | if (!ep->in) { | ||
961 | req->td_data->status &= AMD_CLEAR_BIT(UDC_DMA_IN_STS_L); | ||
962 | } | ||
963 | |||
964 | /* alloc only new desc's if not already available */ | ||
965 | len = req->req.length / ep->ep.maxpacket; | ||
966 | if (req->req.length % ep->ep.maxpacket) { | ||
967 | len++; | ||
968 | } | ||
969 | |||
970 | if (len > req->chain_len) { | ||
971 | /* shorter chain already allocated before */ | ||
972 | if (req->chain_len > 1) { | ||
973 | udc_free_dma_chain(ep->dev, req); | ||
974 | } | ||
975 | req->chain_len = len; | ||
976 | create_new_chain = 1; | ||
977 | } | ||
978 | |||
979 | td = req->td_data; | ||
980 | /* gen. required number of descriptors and buffers */ | ||
981 | for (i = buf_len; i < bytes; i += buf_len) { | ||
982 | /* create or determine next desc. */ | ||
983 | if (create_new_chain) { | ||
984 | |||
985 | td = pci_pool_alloc(ep->dev->data_requests, | ||
986 | gfp_flags, &dma_addr); | ||
987 | if (!td) | ||
988 | return -ENOMEM; | ||
989 | |||
990 | td->status = 0; | ||
991 | } else if (i == buf_len) { | ||
992 | /* first td */ | ||
993 | td = (struct udc_data_dma *) phys_to_virt( | ||
994 | req->td_data->next); | ||
995 | td->status = 0; | ||
996 | } else { | ||
997 | td = (struct udc_data_dma *) phys_to_virt(last->next); | ||
998 | td->status = 0; | ||
999 | } | ||
1000 | |||
1001 | |||
1002 | if (td) | ||
1003 | td->bufptr = req->req.dma + i; /* assign buffer */ | ||
1004 | else | ||
1005 | break; | ||
1006 | |||
1007 | /* short packet ? */ | ||
1008 | if ((bytes - i) >= buf_len) { | ||
1009 | txbytes = buf_len; | ||
1010 | } else { | ||
1011 | /* short packet */ | ||
1012 | txbytes = bytes - i; | ||
1013 | } | ||
1014 | |||
1015 | /* link td and assign tx bytes */ | ||
1016 | if (i == buf_len) { | ||
1017 | if (create_new_chain) { | ||
1018 | req->td_data->next = dma_addr; | ||
1019 | } else { | ||
1020 | /* req->td_data->next = virt_to_phys(td); */ | ||
1021 | } | ||
1022 | /* write tx bytes */ | ||
1023 | if (ep->in) { | ||
1024 | /* first desc */ | ||
1025 | req->td_data->status = | ||
1026 | AMD_ADDBITS(req->td_data->status, | ||
1027 | ep->ep.maxpacket, | ||
1028 | UDC_DMA_IN_STS_TXBYTES); | ||
1029 | /* second desc */ | ||
1030 | td->status = AMD_ADDBITS(td->status, | ||
1031 | txbytes, | ||
1032 | UDC_DMA_IN_STS_TXBYTES); | ||
1033 | } | ||
1034 | } else { | ||
1035 | if (create_new_chain) { | ||
1036 | last->next = dma_addr; | ||
1037 | } else { | ||
1038 | /* last->next = virt_to_phys(td); */ | ||
1039 | } | ||
1040 | if (ep->in) { | ||
1041 | /* write tx bytes */ | ||
1042 | td->status = AMD_ADDBITS(td->status, | ||
1043 | txbytes, | ||
1044 | UDC_DMA_IN_STS_TXBYTES); | ||
1045 | } | ||
1046 | } | ||
1047 | last = td; | ||
1048 | } | ||
1049 | /* set last bit */ | ||
1050 | if (td) { | ||
1051 | td->status |= AMD_BIT(UDC_DMA_IN_STS_L); | ||
1052 | /* last desc. points to itself */ | ||
1053 | req->td_data_last = td; | ||
1054 | } | ||
1055 | |||
1056 | return 0; | ||
1057 | } | ||
1058 | |||
1059 | /* Enabling RX DMA */ | ||
1060 | static void udc_set_rde(struct udc *dev) | ||
1061 | { | ||
1062 | u32 tmp; | ||
1063 | |||
1064 | VDBG(dev, "udc_set_rde()\n"); | ||
1065 | /* stop RDE timer */ | ||
1066 | if (timer_pending(&udc_timer)) { | ||
1067 | set_rde = 0; | ||
1068 | mod_timer(&udc_timer, jiffies - 1); | ||
1069 | } | ||
1070 | /* set RDE */ | ||
1071 | tmp = readl(&dev->regs->ctl); | ||
1072 | tmp |= AMD_BIT(UDC_DEVCTL_RDE); | ||
1073 | writel(tmp, &dev->regs->ctl); | ||
1074 | } | ||
1075 | |||
1076 | /* Queues a request packet, called by gadget driver */ | ||
1077 | static int | ||
1078 | udc_queue(struct usb_ep *usbep, struct usb_request *usbreq, gfp_t gfp) | ||
1079 | { | ||
1080 | int retval = 0; | ||
1081 | u8 open_rxfifo = 0; | ||
1082 | unsigned long iflags; | ||
1083 | struct udc_ep *ep; | ||
1084 | struct udc_request *req; | ||
1085 | struct udc *dev; | ||
1086 | u32 tmp; | ||
1087 | |||
1088 | /* check the inputs */ | ||
1089 | req = container_of(usbreq, struct udc_request, req); | ||
1090 | |||
1091 | if (!usbep || !usbreq || !usbreq->complete || !usbreq->buf | ||
1092 | || !list_empty(&req->queue)) | ||
1093 | return -EINVAL; | ||
1094 | |||
1095 | ep = container_of(usbep, struct udc_ep, ep); | ||
1096 | if (!ep->desc && (ep->num != 0 && ep->num != UDC_EP0OUT_IX)) | ||
1097 | return -EINVAL; | ||
1098 | |||
1099 | VDBG(ep->dev, "udc_queue(): ep%d-in=%d\n", ep->num, ep->in); | ||
1100 | dev = ep->dev; | ||
1101 | |||
1102 | if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
1103 | return -ESHUTDOWN; | ||
1104 | |||
1105 | /* map dma (usually done before) */ | ||
1106 | if (ep->dma && usbreq->length != 0 | ||
1107 | && (usbreq->dma == DMA_DONT_USE || usbreq->dma == 0)) { | ||
1108 | VDBG(dev, "DMA map req %p\n", req); | ||
1109 | if (ep->in) | ||
1110 | usbreq->dma = pci_map_single(dev->pdev, | ||
1111 | usbreq->buf, | ||
1112 | usbreq->length, | ||
1113 | PCI_DMA_TODEVICE); | ||
1114 | else | ||
1115 | usbreq->dma = pci_map_single(dev->pdev, | ||
1116 | usbreq->buf, | ||
1117 | usbreq->length, | ||
1118 | PCI_DMA_FROMDEVICE); | ||
1119 | req->dma_mapping = 1; | ||
1120 | } | ||
1121 | |||
1122 | VDBG(dev, "%s queue req %p, len %d req->td_data=%p buf %p\n", | ||
1123 | usbep->name, usbreq, usbreq->length, | ||
1124 | req->td_data, usbreq->buf); | ||
1125 | |||
1126 | spin_lock_irqsave(&dev->lock, iflags); | ||
1127 | usbreq->actual = 0; | ||
1128 | usbreq->status = -EINPROGRESS; | ||
1129 | req->dma_done = 0; | ||
1130 | |||
1131 | /* on empty queue just do first transfer */ | ||
1132 | if (list_empty(&ep->queue)) { | ||
1133 | /* zlp */ | ||
1134 | if (usbreq->length == 0) { | ||
1135 | /* IN zlp's are handled by hardware */ | ||
1136 | complete_req(ep, req, 0); | ||
1137 | VDBG(dev, "%s: zlp\n", ep->ep.name); | ||
1138 | /* | ||
1139 | * if set_config or set_intf is waiting for ack by zlp | ||
1140 | * then set CSR_DONE | ||
1141 | */ | ||
1142 | if (dev->set_cfg_not_acked) { | ||
1143 | tmp = readl(&dev->regs->ctl); | ||
1144 | tmp |= AMD_BIT(UDC_DEVCTL_CSR_DONE); | ||
1145 | writel(tmp, &dev->regs->ctl); | ||
1146 | dev->set_cfg_not_acked = 0; | ||
1147 | } | ||
1148 | /* setup command is ACK'ed now by zlp */ | ||
1149 | if (dev->waiting_zlp_ack_ep0in) { | ||
1150 | /* clear NAK by writing CNAK in EP0_IN */ | ||
1151 | tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->ctl); | ||
1152 | tmp |= AMD_BIT(UDC_EPCTL_CNAK); | ||
1153 | writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->ctl); | ||
1154 | dev->ep[UDC_EP0IN_IX].naking = 0; | ||
1155 | UDC_QUEUE_CNAK(&dev->ep[UDC_EP0IN_IX], | ||
1156 | UDC_EP0IN_IX); | ||
1157 | dev->waiting_zlp_ack_ep0in = 0; | ||
1158 | } | ||
1159 | goto finished; | ||
1160 | } | ||
1161 | if (ep->dma) { | ||
1162 | retval = prep_dma(ep, req, gfp); | ||
1163 | if (retval != 0) | ||
1164 | goto finished; | ||
1165 | /* write desc pointer to enable DMA */ | ||
1166 | if (ep->in) { | ||
1167 | /* set HOST READY */ | ||
1168 | req->td_data->status = | ||
1169 | AMD_ADDBITS(req->td_data->status, | ||
1170 | UDC_DMA_IN_STS_BS_HOST_READY, | ||
1171 | UDC_DMA_IN_STS_BS); | ||
1172 | } | ||
1173 | |||
1174 | /* disabled rx dma while descriptor update */ | ||
1175 | if (!ep->in) { | ||
1176 | /* stop RDE timer */ | ||
1177 | if (timer_pending(&udc_timer)) { | ||
1178 | set_rde = 0; | ||
1179 | mod_timer(&udc_timer, jiffies - 1); | ||
1180 | } | ||
1181 | /* clear RDE */ | ||
1182 | tmp = readl(&dev->regs->ctl); | ||
1183 | tmp &= AMD_UNMASK_BIT(UDC_DEVCTL_RDE); | ||
1184 | writel(tmp, &dev->regs->ctl); | ||
1185 | open_rxfifo = 1; | ||
1186 | |||
1187 | /* | ||
1188 | * if BNA occurred then let BNA dummy desc. | ||
1189 | * point to current desc. | ||
1190 | */ | ||
1191 | if (ep->bna_occurred) { | ||
1192 | VDBG(dev, "copy to BNA dummy desc.\n"); | ||
1193 | memcpy(ep->bna_dummy_req->td_data, | ||
1194 | req->td_data, | ||
1195 | sizeof(struct udc_data_dma)); | ||
1196 | } | ||
1197 | } | ||
1198 | /* write desc pointer */ | ||
1199 | writel(req->td_phys, &ep->regs->desptr); | ||
1200 | |||
1201 | /* clear NAK by writing CNAK */ | ||
1202 | if (ep->naking) { | ||
1203 | tmp = readl(&ep->regs->ctl); | ||
1204 | tmp |= AMD_BIT(UDC_EPCTL_CNAK); | ||
1205 | writel(tmp, &ep->regs->ctl); | ||
1206 | ep->naking = 0; | ||
1207 | UDC_QUEUE_CNAK(ep, ep->num); | ||
1208 | } | ||
1209 | |||
1210 | if (ep->in) { | ||
1211 | /* enable ep irq */ | ||
1212 | tmp = readl(&dev->regs->ep_irqmsk); | ||
1213 | tmp &= AMD_UNMASK_BIT(ep->num); | ||
1214 | writel(tmp, &dev->regs->ep_irqmsk); | ||
1215 | } | ||
1216 | } | ||
1217 | |||
1218 | } else if (ep->dma) { | ||
1219 | |||
1220 | /* | ||
1221 | * prep_dma not used for OUT ep's, this is not possible | ||
1222 | * for PPB modes, because of chain creation reasons | ||
1223 | */ | ||
1224 | if (ep->in) { | ||
1225 | retval = prep_dma(ep, req, gfp); | ||
1226 | if (retval != 0) | ||
1227 | goto finished; | ||
1228 | } | ||
1229 | } | ||
1230 | VDBG(dev, "list_add\n"); | ||
1231 | /* add request to ep queue */ | ||
1232 | if (req) { | ||
1233 | |||
1234 | list_add_tail(&req->queue, &ep->queue); | ||
1235 | |||
1236 | /* open rxfifo if out data queued */ | ||
1237 | if (open_rxfifo) { | ||
1238 | /* enable DMA */ | ||
1239 | req->dma_going = 1; | ||
1240 | udc_set_rde(dev); | ||
1241 | if (ep->num != UDC_EP0OUT_IX) | ||
1242 | dev->data_ep_queued = 1; | ||
1243 | } | ||
1244 | /* stop OUT naking */ | ||
1245 | if (!ep->in) { | ||
1246 | if (!use_dma && udc_rxfifo_pending) { | ||
1247 | DBG(dev, "udc_queue(): pending bytes in" | ||
1248 | "rxfifo after nyet\n"); | ||
1249 | /* | ||
1250 | * read pending bytes afer nyet: | ||
1251 | * referring to isr | ||
1252 | */ | ||
1253 | if (udc_rxfifo_read(ep, req)) { | ||
1254 | /* finish */ | ||
1255 | complete_req(ep, req, 0); | ||
1256 | } | ||
1257 | udc_rxfifo_pending = 0; | ||
1258 | |||
1259 | } | ||
1260 | } | ||
1261 | } | ||
1262 | |||
1263 | finished: | ||
1264 | spin_unlock_irqrestore(&dev->lock, iflags); | ||
1265 | return retval; | ||
1266 | } | ||
1267 | |||
1268 | /* Empty request queue of an endpoint; caller holds spinlock */ | ||
1269 | static void empty_req_queue(struct udc_ep *ep) | ||
1270 | { | ||
1271 | struct udc_request *req; | ||
1272 | |||
1273 | ep->halted = 1; | ||
1274 | while (!list_empty(&ep->queue)) { | ||
1275 | req = list_entry(ep->queue.next, | ||
1276 | struct udc_request, | ||
1277 | queue); | ||
1278 | complete_req(ep, req, -ESHUTDOWN); | ||
1279 | } | ||
1280 | } | ||
1281 | |||
1282 | /* Dequeues a request packet, called by gadget driver */ | ||
1283 | static int udc_dequeue(struct usb_ep *usbep, struct usb_request *usbreq) | ||
1284 | { | ||
1285 | struct udc_ep *ep; | ||
1286 | struct udc_request *req; | ||
1287 | unsigned halted; | ||
1288 | unsigned long iflags; | ||
1289 | |||
1290 | ep = container_of(usbep, struct udc_ep, ep); | ||
1291 | if (!usbep || !usbreq || (!ep->desc && (ep->num != 0 | ||
1292 | && ep->num != UDC_EP0OUT_IX))) | ||
1293 | return -EINVAL; | ||
1294 | |||
1295 | req = container_of(usbreq, struct udc_request, req); | ||
1296 | |||
1297 | spin_lock_irqsave(&ep->dev->lock, iflags); | ||
1298 | halted = ep->halted; | ||
1299 | ep->halted = 1; | ||
1300 | /* request in processing or next one */ | ||
1301 | if (ep->queue.next == &req->queue) { | ||
1302 | if (ep->dma && req->dma_going) { | ||
1303 | if (ep->in) | ||
1304 | ep->cancel_transfer = 1; | ||
1305 | else { | ||
1306 | u32 tmp; | ||
1307 | u32 dma_sts; | ||
1308 | /* stop potential receive DMA */ | ||
1309 | tmp = readl(&udc->regs->ctl); | ||
1310 | writel(tmp & AMD_UNMASK_BIT(UDC_DEVCTL_RDE), | ||
1311 | &udc->regs->ctl); | ||
1312 | /* | ||
1313 | * Cancel transfer later in ISR | ||
1314 | * if descriptor was touched. | ||
1315 | */ | ||
1316 | dma_sts = AMD_GETBITS(req->td_data->status, | ||
1317 | UDC_DMA_OUT_STS_BS); | ||
1318 | if (dma_sts != UDC_DMA_OUT_STS_BS_HOST_READY) | ||
1319 | ep->cancel_transfer = 1; | ||
1320 | else { | ||
1321 | udc_init_bna_dummy(ep->req); | ||
1322 | writel(ep->bna_dummy_req->td_phys, | ||
1323 | &ep->regs->desptr); | ||
1324 | } | ||
1325 | writel(tmp, &udc->regs->ctl); | ||
1326 | } | ||
1327 | } | ||
1328 | } | ||
1329 | complete_req(ep, req, -ECONNRESET); | ||
1330 | ep->halted = halted; | ||
1331 | |||
1332 | spin_unlock_irqrestore(&ep->dev->lock, iflags); | ||
1333 | return 0; | ||
1334 | } | ||
1335 | |||
1336 | /* Halt or clear halt of endpoint */ | ||
1337 | static int | ||
1338 | udc_set_halt(struct usb_ep *usbep, int halt) | ||
1339 | { | ||
1340 | struct udc_ep *ep; | ||
1341 | u32 tmp; | ||
1342 | unsigned long iflags; | ||
1343 | int retval = 0; | ||
1344 | |||
1345 | if (!usbep) | ||
1346 | return -EINVAL; | ||
1347 | |||
1348 | pr_debug("set_halt %s: halt=%d\n", usbep->name, halt); | ||
1349 | |||
1350 | ep = container_of(usbep, struct udc_ep, ep); | ||
1351 | if (!ep->desc && (ep->num != 0 && ep->num != UDC_EP0OUT_IX)) | ||
1352 | return -EINVAL; | ||
1353 | if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
1354 | return -ESHUTDOWN; | ||
1355 | |||
1356 | spin_lock_irqsave(&udc_stall_spinlock, iflags); | ||
1357 | /* halt or clear halt */ | ||
1358 | if (halt) { | ||
1359 | if (ep->num == 0) | ||
1360 | ep->dev->stall_ep0in = 1; | ||
1361 | else { | ||
1362 | /* | ||
1363 | * set STALL | ||
1364 | * rxfifo empty not taken into acount | ||
1365 | */ | ||
1366 | tmp = readl(&ep->regs->ctl); | ||
1367 | tmp |= AMD_BIT(UDC_EPCTL_S); | ||
1368 | writel(tmp, &ep->regs->ctl); | ||
1369 | ep->halted = 1; | ||
1370 | |||
1371 | /* setup poll timer */ | ||
1372 | if (!timer_pending(&udc_pollstall_timer)) { | ||
1373 | udc_pollstall_timer.expires = jiffies + | ||
1374 | HZ * UDC_POLLSTALL_TIMER_USECONDS | ||
1375 | / (1000 * 1000); | ||
1376 | if (!stop_pollstall_timer) { | ||
1377 | DBG(ep->dev, "start polltimer\n"); | ||
1378 | add_timer(&udc_pollstall_timer); | ||
1379 | } | ||
1380 | } | ||
1381 | } | ||
1382 | } else { | ||
1383 | /* ep is halted by set_halt() before */ | ||
1384 | if (ep->halted) { | ||
1385 | tmp = readl(&ep->regs->ctl); | ||
1386 | /* clear stall bit */ | ||
1387 | tmp = tmp & AMD_CLEAR_BIT(UDC_EPCTL_S); | ||
1388 | /* clear NAK by writing CNAK */ | ||
1389 | tmp |= AMD_BIT(UDC_EPCTL_CNAK); | ||
1390 | writel(tmp, &ep->regs->ctl); | ||
1391 | ep->halted = 0; | ||
1392 | UDC_QUEUE_CNAK(ep, ep->num); | ||
1393 | } | ||
1394 | } | ||
1395 | spin_unlock_irqrestore(&udc_stall_spinlock, iflags); | ||
1396 | return retval; | ||
1397 | } | ||
1398 | |||
1399 | /* gadget interface */ | ||
1400 | static const struct usb_ep_ops udc_ep_ops = { | ||
1401 | .enable = udc_ep_enable, | ||
1402 | .disable = udc_ep_disable, | ||
1403 | |||
1404 | .alloc_request = udc_alloc_request, | ||
1405 | .free_request = udc_free_request, | ||
1406 | |||
1407 | .queue = udc_queue, | ||
1408 | .dequeue = udc_dequeue, | ||
1409 | |||
1410 | .set_halt = udc_set_halt, | ||
1411 | /* fifo ops not implemented */ | ||
1412 | }; | ||
1413 | |||
1414 | /*-------------------------------------------------------------------------*/ | ||
1415 | |||
1416 | /* Get frame counter (not implemented) */ | ||
1417 | static int udc_get_frame(struct usb_gadget *gadget) | ||
1418 | { | ||
1419 | return -EOPNOTSUPP; | ||
1420 | } | ||
1421 | |||
1422 | /* Remote wakeup gadget interface */ | ||
1423 | static int udc_wakeup(struct usb_gadget *gadget) | ||
1424 | { | ||
1425 | struct udc *dev; | ||
1426 | |||
1427 | if (!gadget) | ||
1428 | return -EINVAL; | ||
1429 | dev = container_of(gadget, struct udc, gadget); | ||
1430 | udc_remote_wakeup(dev); | ||
1431 | |||
1432 | return 0; | ||
1433 | } | ||
1434 | |||
1435 | /* gadget operations */ | ||
1436 | static const struct usb_gadget_ops udc_ops = { | ||
1437 | .wakeup = udc_wakeup, | ||
1438 | .get_frame = udc_get_frame, | ||
1439 | }; | ||
1440 | |||
1441 | /* Setups endpoint parameters, adds endpoints to linked list */ | ||
1442 | static void make_ep_lists(struct udc *dev) | ||
1443 | { | ||
1444 | /* make gadget ep lists */ | ||
1445 | INIT_LIST_HEAD(&dev->gadget.ep_list); | ||
1446 | list_add_tail(&dev->ep[UDC_EPIN_STATUS_IX].ep.ep_list, | ||
1447 | &dev->gadget.ep_list); | ||
1448 | list_add_tail(&dev->ep[UDC_EPIN_IX].ep.ep_list, | ||
1449 | &dev->gadget.ep_list); | ||
1450 | list_add_tail(&dev->ep[UDC_EPOUT_IX].ep.ep_list, | ||
1451 | &dev->gadget.ep_list); | ||
1452 | |||
1453 | /* fifo config */ | ||
1454 | dev->ep[UDC_EPIN_STATUS_IX].fifo_depth = UDC_EPIN_SMALLINT_BUFF_SIZE; | ||
1455 | if (dev->gadget.speed == USB_SPEED_FULL) | ||
1456 | dev->ep[UDC_EPIN_IX].fifo_depth = UDC_FS_EPIN_BUFF_SIZE; | ||
1457 | else if (dev->gadget.speed == USB_SPEED_HIGH) | ||
1458 | dev->ep[UDC_EPIN_IX].fifo_depth = hs_tx_buf; | ||
1459 | dev->ep[UDC_EPOUT_IX].fifo_depth = UDC_RXFIFO_SIZE; | ||
1460 | } | ||
1461 | |||
1462 | /* init registers at driver load time */ | ||
1463 | static int startup_registers(struct udc *dev) | ||
1464 | { | ||
1465 | u32 tmp; | ||
1466 | |||
1467 | /* init controller by soft reset */ | ||
1468 | udc_soft_reset(dev); | ||
1469 | |||
1470 | /* mask not needed interrupts */ | ||
1471 | udc_mask_unused_interrupts(dev); | ||
1472 | |||
1473 | /* put into initial config */ | ||
1474 | udc_basic_init(dev); | ||
1475 | /* link up all endpoints */ | ||
1476 | udc_setup_endpoints(dev); | ||
1477 | |||
1478 | /* program speed */ | ||
1479 | tmp = readl(&dev->regs->cfg); | ||
1480 | if (use_fullspeed) { | ||
1481 | tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_FS, UDC_DEVCFG_SPD); | ||
1482 | } else { | ||
1483 | tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_HS, UDC_DEVCFG_SPD); | ||
1484 | } | ||
1485 | writel(tmp, &dev->regs->cfg); | ||
1486 | |||
1487 | return 0; | ||
1488 | } | ||
1489 | |||
1490 | /* Inits UDC context */ | ||
1491 | static void udc_basic_init(struct udc *dev) | ||
1492 | { | ||
1493 | u32 tmp; | ||
1494 | |||
1495 | DBG(dev, "udc_basic_init()\n"); | ||
1496 | |||
1497 | dev->gadget.speed = USB_SPEED_UNKNOWN; | ||
1498 | |||
1499 | /* stop RDE timer */ | ||
1500 | if (timer_pending(&udc_timer)) { | ||
1501 | set_rde = 0; | ||
1502 | mod_timer(&udc_timer, jiffies - 1); | ||
1503 | } | ||
1504 | /* stop poll stall timer */ | ||
1505 | if (timer_pending(&udc_pollstall_timer)) { | ||
1506 | mod_timer(&udc_pollstall_timer, jiffies - 1); | ||
1507 | } | ||
1508 | /* disable DMA */ | ||
1509 | tmp = readl(&dev->regs->ctl); | ||
1510 | tmp &= AMD_UNMASK_BIT(UDC_DEVCTL_RDE); | ||
1511 | tmp &= AMD_UNMASK_BIT(UDC_DEVCTL_TDE); | ||
1512 | writel(tmp, &dev->regs->ctl); | ||
1513 | |||
1514 | /* enable dynamic CSR programming */ | ||
1515 | tmp = readl(&dev->regs->cfg); | ||
1516 | tmp |= AMD_BIT(UDC_DEVCFG_CSR_PRG); | ||
1517 | /* set self powered */ | ||
1518 | tmp |= AMD_BIT(UDC_DEVCFG_SP); | ||
1519 | /* set remote wakeupable */ | ||
1520 | tmp |= AMD_BIT(UDC_DEVCFG_RWKP); | ||
1521 | writel(tmp, &dev->regs->cfg); | ||
1522 | |||
1523 | make_ep_lists(dev); | ||
1524 | |||
1525 | dev->data_ep_enabled = 0; | ||
1526 | dev->data_ep_queued = 0; | ||
1527 | } | ||
1528 | |||
1529 | /* Sets initial endpoint parameters */ | ||
1530 | static void udc_setup_endpoints(struct udc *dev) | ||
1531 | { | ||
1532 | struct udc_ep *ep; | ||
1533 | u32 tmp; | ||
1534 | u32 reg; | ||
1535 | |||
1536 | DBG(dev, "udc_setup_endpoints()\n"); | ||
1537 | |||
1538 | /* read enum speed */ | ||
1539 | tmp = readl(&dev->regs->sts); | ||
1540 | tmp = AMD_GETBITS(tmp, UDC_DEVSTS_ENUM_SPEED); | ||
1541 | if (tmp == UDC_DEVSTS_ENUM_SPEED_HIGH) { | ||
1542 | dev->gadget.speed = USB_SPEED_HIGH; | ||
1543 | } else if (tmp == UDC_DEVSTS_ENUM_SPEED_FULL) { | ||
1544 | dev->gadget.speed = USB_SPEED_FULL; | ||
1545 | } | ||
1546 | |||
1547 | /* set basic ep parameters */ | ||
1548 | for (tmp = 0; tmp < UDC_EP_NUM; tmp++) { | ||
1549 | ep = &dev->ep[tmp]; | ||
1550 | ep->dev = dev; | ||
1551 | ep->ep.name = ep_string[tmp]; | ||
1552 | ep->num = tmp; | ||
1553 | /* txfifo size is calculated at enable time */ | ||
1554 | ep->txfifo = dev->txfifo; | ||
1555 | |||
1556 | /* fifo size */ | ||
1557 | if (tmp < UDC_EPIN_NUM) { | ||
1558 | ep->fifo_depth = UDC_TXFIFO_SIZE; | ||
1559 | ep->in = 1; | ||
1560 | } else { | ||
1561 | ep->fifo_depth = UDC_RXFIFO_SIZE; | ||
1562 | ep->in = 0; | ||
1563 | |||
1564 | } | ||
1565 | ep->regs = &dev->ep_regs[tmp]; | ||
1566 | /* | ||
1567 | * ep will be reset only if ep was not enabled before to avoid | ||
1568 | * disabling ep interrupts when ENUM interrupt occurs but ep is | ||
1569 | * not enabled by gadget driver | ||
1570 | */ | ||
1571 | if (!ep->desc) { | ||
1572 | ep_init(dev->regs, ep); | ||
1573 | } | ||
1574 | |||
1575 | if (use_dma) { | ||
1576 | /* | ||
1577 | * ep->dma is not really used, just to indicate that | ||
1578 | * DMA is active: remove this | ||
1579 | * dma regs = dev control regs | ||
1580 | */ | ||
1581 | ep->dma = &dev->regs->ctl; | ||
1582 | |||
1583 | /* nak OUT endpoints until enable - not for ep0 */ | ||
1584 | if (tmp != UDC_EP0IN_IX && tmp != UDC_EP0OUT_IX | ||
1585 | && tmp > UDC_EPIN_NUM) { | ||
1586 | /* set NAK */ | ||
1587 | reg = readl(&dev->ep[tmp].regs->ctl); | ||
1588 | reg |= AMD_BIT(UDC_EPCTL_SNAK); | ||
1589 | writel(reg, &dev->ep[tmp].regs->ctl); | ||
1590 | dev->ep[tmp].naking = 1; | ||
1591 | |||
1592 | } | ||
1593 | } | ||
1594 | } | ||
1595 | /* EP0 max packet */ | ||
1596 | if (dev->gadget.speed == USB_SPEED_FULL) { | ||
1597 | dev->ep[UDC_EP0IN_IX].ep.maxpacket = UDC_FS_EP0IN_MAX_PKT_SIZE; | ||
1598 | dev->ep[UDC_EP0OUT_IX].ep.maxpacket = | ||
1599 | UDC_FS_EP0OUT_MAX_PKT_SIZE; | ||
1600 | } else if (dev->gadget.speed == USB_SPEED_HIGH) { | ||
1601 | dev->ep[UDC_EP0IN_IX].ep.maxpacket = UDC_EP0IN_MAX_PKT_SIZE; | ||
1602 | dev->ep[UDC_EP0OUT_IX].ep.maxpacket = UDC_EP0OUT_MAX_PKT_SIZE; | ||
1603 | } | ||
1604 | |||
1605 | /* | ||
1606 | * with suspend bug workaround, ep0 params for gadget driver | ||
1607 | * are set at gadget driver bind() call | ||
1608 | */ | ||
1609 | dev->gadget.ep0 = &dev->ep[UDC_EP0IN_IX].ep; | ||
1610 | dev->ep[UDC_EP0IN_IX].halted = 0; | ||
1611 | INIT_LIST_HEAD(&dev->gadget.ep0->ep_list); | ||
1612 | |||
1613 | /* init cfg/alt/int */ | ||
1614 | dev->cur_config = 0; | ||
1615 | dev->cur_intf = 0; | ||
1616 | dev->cur_alt = 0; | ||
1617 | } | ||
1618 | |||
1619 | /* Bringup after Connect event, initial bringup to be ready for ep0 events */ | ||
1620 | static void usb_connect(struct udc *dev) | ||
1621 | { | ||
1622 | |||
1623 | dev_info(&dev->pdev->dev, "USB Connect\n"); | ||
1624 | |||
1625 | dev->connected = 1; | ||
1626 | |||
1627 | /* put into initial config */ | ||
1628 | udc_basic_init(dev); | ||
1629 | |||
1630 | /* enable device setup interrupts */ | ||
1631 | udc_enable_dev_setup_interrupts(dev); | ||
1632 | } | ||
1633 | |||
1634 | /* | ||
1635 | * Calls gadget with disconnect event and resets the UDC and makes | ||
1636 | * initial bringup to be ready for ep0 events | ||
1637 | */ | ||
1638 | static void usb_disconnect(struct udc *dev) | ||
1639 | { | ||
1640 | |||
1641 | dev_info(&dev->pdev->dev, "USB Disconnect\n"); | ||
1642 | |||
1643 | dev->connected = 0; | ||
1644 | |||
1645 | /* mask interrupts */ | ||
1646 | udc_mask_unused_interrupts(dev); | ||
1647 | |||
1648 | /* REVISIT there doesn't seem to be a point to having this | ||
1649 | * talk to a tasklet ... do it directly, we already hold | ||
1650 | * the spinlock needed to process the disconnect. | ||
1651 | */ | ||
1652 | |||
1653 | tasklet_schedule(&disconnect_tasklet); | ||
1654 | } | ||
1655 | |||
1656 | /* Tasklet for disconnect to be outside of interrupt context */ | ||
1657 | static void udc_tasklet_disconnect(unsigned long par) | ||
1658 | { | ||
1659 | struct udc *dev = (struct udc *)(*((struct udc **) par)); | ||
1660 | u32 tmp; | ||
1661 | |||
1662 | DBG(dev, "Tasklet disconnect\n"); | ||
1663 | spin_lock_irq(&dev->lock); | ||
1664 | |||
1665 | if (dev->driver) { | ||
1666 | spin_unlock(&dev->lock); | ||
1667 | dev->driver->disconnect(&dev->gadget); | ||
1668 | spin_lock(&dev->lock); | ||
1669 | |||
1670 | /* empty queues */ | ||
1671 | for (tmp = 0; tmp < UDC_EP_NUM; tmp++) { | ||
1672 | empty_req_queue(&dev->ep[tmp]); | ||
1673 | } | ||
1674 | |||
1675 | } | ||
1676 | |||
1677 | /* disable ep0 */ | ||
1678 | ep_init(dev->regs, | ||
1679 | &dev->ep[UDC_EP0IN_IX]); | ||
1680 | |||
1681 | |||
1682 | if (!soft_reset_occured) { | ||
1683 | /* init controller by soft reset */ | ||
1684 | udc_soft_reset(dev); | ||
1685 | soft_reset_occured++; | ||
1686 | } | ||
1687 | |||
1688 | /* re-enable dev interrupts */ | ||
1689 | udc_enable_dev_setup_interrupts(dev); | ||
1690 | /* back to full speed ? */ | ||
1691 | if (use_fullspeed) { | ||
1692 | tmp = readl(&dev->regs->cfg); | ||
1693 | tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_FS, UDC_DEVCFG_SPD); | ||
1694 | writel(tmp, &dev->regs->cfg); | ||
1695 | } | ||
1696 | |||
1697 | spin_unlock_irq(&dev->lock); | ||
1698 | } | ||
1699 | |||
1700 | /* Reset the UDC core */ | ||
1701 | static void udc_soft_reset(struct udc *dev) | ||
1702 | { | ||
1703 | unsigned long flags; | ||
1704 | |||
1705 | DBG(dev, "Soft reset\n"); | ||
1706 | /* | ||
1707 | * reset possible waiting interrupts, because int. | ||
1708 | * status is lost after soft reset, | ||
1709 | * ep int. status reset | ||
1710 | */ | ||
1711 | writel(UDC_EPINT_MSK_DISABLE_ALL, &dev->regs->ep_irqsts); | ||
1712 | /* device int. status reset */ | ||
1713 | writel(UDC_DEV_MSK_DISABLE, &dev->regs->irqsts); | ||
1714 | |||
1715 | spin_lock_irqsave(&udc_irq_spinlock, flags); | ||
1716 | writel(AMD_BIT(UDC_DEVCFG_SOFTRESET), &dev->regs->cfg); | ||
1717 | readl(&dev->regs->cfg); | ||
1718 | spin_unlock_irqrestore(&udc_irq_spinlock, flags); | ||
1719 | |||
1720 | } | ||
1721 | |||
1722 | /* RDE timer callback to set RDE bit */ | ||
1723 | static void udc_timer_function(unsigned long v) | ||
1724 | { | ||
1725 | u32 tmp; | ||
1726 | |||
1727 | spin_lock_irq(&udc_irq_spinlock); | ||
1728 | |||
1729 | if (set_rde > 0) { | ||
1730 | /* | ||
1731 | * open the fifo if fifo was filled on last timer call | ||
1732 | * conditionally | ||
1733 | */ | ||
1734 | if (set_rde > 1) { | ||
1735 | /* set RDE to receive setup data */ | ||
1736 | tmp = readl(&udc->regs->ctl); | ||
1737 | tmp |= AMD_BIT(UDC_DEVCTL_RDE); | ||
1738 | writel(tmp, &udc->regs->ctl); | ||
1739 | set_rde = -1; | ||
1740 | } else if (readl(&udc->regs->sts) | ||
1741 | & AMD_BIT(UDC_DEVSTS_RXFIFO_EMPTY)) { | ||
1742 | /* | ||
1743 | * if fifo empty setup polling, do not just | ||
1744 | * open the fifo | ||
1745 | */ | ||
1746 | udc_timer.expires = jiffies + HZ/UDC_RDE_TIMER_DIV; | ||
1747 | if (!stop_timer) { | ||
1748 | add_timer(&udc_timer); | ||
1749 | } | ||
1750 | } else { | ||
1751 | /* | ||
1752 | * fifo contains data now, setup timer for opening | ||
1753 | * the fifo when timer expires to be able to receive | ||
1754 | * setup packets, when data packets gets queued by | ||
1755 | * gadget layer then timer will forced to expire with | ||
1756 | * set_rde=0 (RDE is set in udc_queue()) | ||
1757 | */ | ||
1758 | set_rde++; | ||
1759 | /* debug: lhadmot_timer_start = 221070 */ | ||
1760 | udc_timer.expires = jiffies + HZ*UDC_RDE_TIMER_SECONDS; | ||
1761 | if (!stop_timer) { | ||
1762 | add_timer(&udc_timer); | ||
1763 | } | ||
1764 | } | ||
1765 | |||
1766 | } else | ||
1767 | set_rde = -1; /* RDE was set by udc_queue() */ | ||
1768 | spin_unlock_irq(&udc_irq_spinlock); | ||
1769 | if (stop_timer) | ||
1770 | complete(&on_exit); | ||
1771 | |||
1772 | } | ||
1773 | |||
1774 | /* Handle halt state, used in stall poll timer */ | ||
1775 | static void udc_handle_halt_state(struct udc_ep *ep) | ||
1776 | { | ||
1777 | u32 tmp; | ||
1778 | /* set stall as long not halted */ | ||
1779 | if (ep->halted == 1) { | ||
1780 | tmp = readl(&ep->regs->ctl); | ||
1781 | /* STALL cleared ? */ | ||
1782 | if (!(tmp & AMD_BIT(UDC_EPCTL_S))) { | ||
1783 | /* | ||
1784 | * FIXME: MSC spec requires that stall remains | ||
1785 | * even on receivng of CLEAR_FEATURE HALT. So | ||
1786 | * we would set STALL again here to be compliant. | ||
1787 | * But with current mass storage drivers this does | ||
1788 | * not work (would produce endless host retries). | ||
1789 | * So we clear halt on CLEAR_FEATURE. | ||
1790 | * | ||
1791 | DBG(ep->dev, "ep %d: set STALL again\n", ep->num); | ||
1792 | tmp |= AMD_BIT(UDC_EPCTL_S); | ||
1793 | writel(tmp, &ep->regs->ctl);*/ | ||
1794 | |||
1795 | /* clear NAK by writing CNAK */ | ||
1796 | tmp |= AMD_BIT(UDC_EPCTL_CNAK); | ||
1797 | writel(tmp, &ep->regs->ctl); | ||
1798 | ep->halted = 0; | ||
1799 | UDC_QUEUE_CNAK(ep, ep->num); | ||
1800 | } | ||
1801 | } | ||
1802 | } | ||
1803 | |||
1804 | /* Stall timer callback to poll S bit and set it again after */ | ||
1805 | static void udc_pollstall_timer_function(unsigned long v) | ||
1806 | { | ||
1807 | struct udc_ep *ep; | ||
1808 | int halted = 0; | ||
1809 | |||
1810 | spin_lock_irq(&udc_stall_spinlock); | ||
1811 | /* | ||
1812 | * only one IN and OUT endpoints are handled | ||
1813 | * IN poll stall | ||
1814 | */ | ||
1815 | ep = &udc->ep[UDC_EPIN_IX]; | ||
1816 | udc_handle_halt_state(ep); | ||
1817 | if (ep->halted) | ||
1818 | halted = 1; | ||
1819 | /* OUT poll stall */ | ||
1820 | ep = &udc->ep[UDC_EPOUT_IX]; | ||
1821 | udc_handle_halt_state(ep); | ||
1822 | if (ep->halted) | ||
1823 | halted = 1; | ||
1824 | |||
1825 | /* setup timer again when still halted */ | ||
1826 | if (!stop_pollstall_timer && halted) { | ||
1827 | udc_pollstall_timer.expires = jiffies + | ||
1828 | HZ * UDC_POLLSTALL_TIMER_USECONDS | ||
1829 | / (1000 * 1000); | ||
1830 | add_timer(&udc_pollstall_timer); | ||
1831 | } | ||
1832 | spin_unlock_irq(&udc_stall_spinlock); | ||
1833 | |||
1834 | if (stop_pollstall_timer) | ||
1835 | complete(&on_pollstall_exit); | ||
1836 | } | ||
1837 | |||
1838 | /* Inits endpoint 0 so that SETUP packets are processed */ | ||
1839 | static void activate_control_endpoints(struct udc *dev) | ||
1840 | { | ||
1841 | u32 tmp; | ||
1842 | |||
1843 | DBG(dev, "activate_control_endpoints\n"); | ||
1844 | |||
1845 | /* flush fifo */ | ||
1846 | tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->ctl); | ||
1847 | tmp |= AMD_BIT(UDC_EPCTL_F); | ||
1848 | writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->ctl); | ||
1849 | |||
1850 | /* set ep0 directions */ | ||
1851 | dev->ep[UDC_EP0IN_IX].in = 1; | ||
1852 | dev->ep[UDC_EP0OUT_IX].in = 0; | ||
1853 | |||
1854 | /* set buffer size (tx fifo entries) of EP0_IN */ | ||
1855 | tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->bufin_framenum); | ||
1856 | if (dev->gadget.speed == USB_SPEED_FULL) | ||
1857 | tmp = AMD_ADDBITS(tmp, UDC_FS_EPIN0_BUFF_SIZE, | ||
1858 | UDC_EPIN_BUFF_SIZE); | ||
1859 | else if (dev->gadget.speed == USB_SPEED_HIGH) | ||
1860 | tmp = AMD_ADDBITS(tmp, UDC_EPIN0_BUFF_SIZE, | ||
1861 | UDC_EPIN_BUFF_SIZE); | ||
1862 | writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->bufin_framenum); | ||
1863 | |||
1864 | /* set max packet size of EP0_IN */ | ||
1865 | tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->bufout_maxpkt); | ||
1866 | if (dev->gadget.speed == USB_SPEED_FULL) | ||
1867 | tmp = AMD_ADDBITS(tmp, UDC_FS_EP0IN_MAX_PKT_SIZE, | ||
1868 | UDC_EP_MAX_PKT_SIZE); | ||
1869 | else if (dev->gadget.speed == USB_SPEED_HIGH) | ||
1870 | tmp = AMD_ADDBITS(tmp, UDC_EP0IN_MAX_PKT_SIZE, | ||
1871 | UDC_EP_MAX_PKT_SIZE); | ||
1872 | writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->bufout_maxpkt); | ||
1873 | |||
1874 | /* set max packet size of EP0_OUT */ | ||
1875 | tmp = readl(&dev->ep[UDC_EP0OUT_IX].regs->bufout_maxpkt); | ||
1876 | if (dev->gadget.speed == USB_SPEED_FULL) | ||
1877 | tmp = AMD_ADDBITS(tmp, UDC_FS_EP0OUT_MAX_PKT_SIZE, | ||
1878 | UDC_EP_MAX_PKT_SIZE); | ||
1879 | else if (dev->gadget.speed == USB_SPEED_HIGH) | ||
1880 | tmp = AMD_ADDBITS(tmp, UDC_EP0OUT_MAX_PKT_SIZE, | ||
1881 | UDC_EP_MAX_PKT_SIZE); | ||
1882 | writel(tmp, &dev->ep[UDC_EP0OUT_IX].regs->bufout_maxpkt); | ||
1883 | |||
1884 | /* set max packet size of EP0 in UDC CSR */ | ||
1885 | tmp = readl(&dev->csr->ne[0]); | ||
1886 | if (dev->gadget.speed == USB_SPEED_FULL) | ||
1887 | tmp = AMD_ADDBITS(tmp, UDC_FS_EP0OUT_MAX_PKT_SIZE, | ||
1888 | UDC_CSR_NE_MAX_PKT); | ||
1889 | else if (dev->gadget.speed == USB_SPEED_HIGH) | ||
1890 | tmp = AMD_ADDBITS(tmp, UDC_EP0OUT_MAX_PKT_SIZE, | ||
1891 | UDC_CSR_NE_MAX_PKT); | ||
1892 | writel(tmp, &dev->csr->ne[0]); | ||
1893 | |||
1894 | if (use_dma) { | ||
1895 | dev->ep[UDC_EP0OUT_IX].td->status |= | ||
1896 | AMD_BIT(UDC_DMA_OUT_STS_L); | ||
1897 | /* write dma desc address */ | ||
1898 | writel(dev->ep[UDC_EP0OUT_IX].td_stp_dma, | ||
1899 | &dev->ep[UDC_EP0OUT_IX].regs->subptr); | ||
1900 | writel(dev->ep[UDC_EP0OUT_IX].td_phys, | ||
1901 | &dev->ep[UDC_EP0OUT_IX].regs->desptr); | ||
1902 | /* stop RDE timer */ | ||
1903 | if (timer_pending(&udc_timer)) { | ||
1904 | set_rde = 0; | ||
1905 | mod_timer(&udc_timer, jiffies - 1); | ||
1906 | } | ||
1907 | /* stop pollstall timer */ | ||
1908 | if (timer_pending(&udc_pollstall_timer)) { | ||
1909 | mod_timer(&udc_pollstall_timer, jiffies - 1); | ||
1910 | } | ||
1911 | /* enable DMA */ | ||
1912 | tmp = readl(&dev->regs->ctl); | ||
1913 | tmp |= AMD_BIT(UDC_DEVCTL_MODE) | ||
1914 | | AMD_BIT(UDC_DEVCTL_RDE) | ||
1915 | | AMD_BIT(UDC_DEVCTL_TDE); | ||
1916 | if (use_dma_bufferfill_mode) { | ||
1917 | tmp |= AMD_BIT(UDC_DEVCTL_BF); | ||
1918 | } else if (use_dma_ppb_du) { | ||
1919 | tmp |= AMD_BIT(UDC_DEVCTL_DU); | ||
1920 | } | ||
1921 | writel(tmp, &dev->regs->ctl); | ||
1922 | } | ||
1923 | |||
1924 | /* clear NAK by writing CNAK for EP0IN */ | ||
1925 | tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->ctl); | ||
1926 | tmp |= AMD_BIT(UDC_EPCTL_CNAK); | ||
1927 | writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->ctl); | ||
1928 | dev->ep[UDC_EP0IN_IX].naking = 0; | ||
1929 | UDC_QUEUE_CNAK(&dev->ep[UDC_EP0IN_IX], UDC_EP0IN_IX); | ||
1930 | |||
1931 | /* clear NAK by writing CNAK for EP0OUT */ | ||
1932 | tmp = readl(&dev->ep[UDC_EP0OUT_IX].regs->ctl); | ||
1933 | tmp |= AMD_BIT(UDC_EPCTL_CNAK); | ||
1934 | writel(tmp, &dev->ep[UDC_EP0OUT_IX].regs->ctl); | ||
1935 | dev->ep[UDC_EP0OUT_IX].naking = 0; | ||
1936 | UDC_QUEUE_CNAK(&dev->ep[UDC_EP0OUT_IX], UDC_EP0OUT_IX); | ||
1937 | } | ||
1938 | |||
1939 | /* Make endpoint 0 ready for control traffic */ | ||
1940 | static int setup_ep0(struct udc *dev) | ||
1941 | { | ||
1942 | activate_control_endpoints(dev); | ||
1943 | /* enable ep0 interrupts */ | ||
1944 | udc_enable_ep0_interrupts(dev); | ||
1945 | /* enable device setup interrupts */ | ||
1946 | udc_enable_dev_setup_interrupts(dev); | ||
1947 | |||
1948 | return 0; | ||
1949 | } | ||
1950 | |||
1951 | /* Called by gadget driver to register itself */ | ||
1952 | int usb_gadget_register_driver(struct usb_gadget_driver *driver) | ||
1953 | { | ||
1954 | struct udc *dev = udc; | ||
1955 | int retval; | ||
1956 | u32 tmp; | ||
1957 | |||
1958 | if (!driver || !driver->bind || !driver->setup | ||
1959 | || driver->speed != USB_SPEED_HIGH) | ||
1960 | return -EINVAL; | ||
1961 | if (!dev) | ||
1962 | return -ENODEV; | ||
1963 | if (dev->driver) | ||
1964 | return -EBUSY; | ||
1965 | |||
1966 | driver->driver.bus = NULL; | ||
1967 | dev->driver = driver; | ||
1968 | dev->gadget.dev.driver = &driver->driver; | ||
1969 | |||
1970 | retval = driver->bind(&dev->gadget); | ||
1971 | |||
1972 | /* Some gadget drivers use both ep0 directions. | ||
1973 | * NOTE: to gadget driver, ep0 is just one endpoint... | ||
1974 | */ | ||
1975 | dev->ep[UDC_EP0OUT_IX].ep.driver_data = | ||
1976 | dev->ep[UDC_EP0IN_IX].ep.driver_data; | ||
1977 | |||
1978 | if (retval) { | ||
1979 | DBG(dev, "binding to %s returning %d\n", | ||
1980 | driver->driver.name, retval); | ||
1981 | dev->driver = NULL; | ||
1982 | dev->gadget.dev.driver = NULL; | ||
1983 | return retval; | ||
1984 | } | ||
1985 | |||
1986 | /* get ready for ep0 traffic */ | ||
1987 | setup_ep0(dev); | ||
1988 | |||
1989 | /* clear SD */ | ||
1990 | tmp = readl(&dev->regs->ctl); | ||
1991 | tmp = tmp & AMD_CLEAR_BIT(UDC_DEVCTL_SD); | ||
1992 | writel(tmp, &dev->regs->ctl); | ||
1993 | |||
1994 | usb_connect(dev); | ||
1995 | |||
1996 | return 0; | ||
1997 | } | ||
1998 | EXPORT_SYMBOL(usb_gadget_register_driver); | ||
1999 | |||
2000 | /* shutdown requests and disconnect from gadget */ | ||
2001 | static void | ||
2002 | shutdown(struct udc *dev, struct usb_gadget_driver *driver) | ||
2003 | __releases(dev->lock) | ||
2004 | __acquires(dev->lock) | ||
2005 | { | ||
2006 | int tmp; | ||
2007 | |||
2008 | /* empty queues and init hardware */ | ||
2009 | udc_basic_init(dev); | ||
2010 | for (tmp = 0; tmp < UDC_EP_NUM; tmp++) { | ||
2011 | empty_req_queue(&dev->ep[tmp]); | ||
2012 | } | ||
2013 | |||
2014 | if (dev->gadget.speed != USB_SPEED_UNKNOWN) { | ||
2015 | spin_unlock(&dev->lock); | ||
2016 | driver->disconnect(&dev->gadget); | ||
2017 | spin_lock(&dev->lock); | ||
2018 | } | ||
2019 | /* init */ | ||
2020 | udc_setup_endpoints(dev); | ||
2021 | } | ||
2022 | |||
2023 | /* Called by gadget driver to unregister itself */ | ||
2024 | int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | ||
2025 | { | ||
2026 | struct udc *dev = udc; | ||
2027 | unsigned long flags; | ||
2028 | u32 tmp; | ||
2029 | |||
2030 | if (!dev) | ||
2031 | return -ENODEV; | ||
2032 | if (!driver || driver != dev->driver || !driver->unbind) | ||
2033 | return -EINVAL; | ||
2034 | |||
2035 | spin_lock_irqsave(&dev->lock, flags); | ||
2036 | udc_mask_unused_interrupts(dev); | ||
2037 | shutdown(dev, driver); | ||
2038 | spin_unlock_irqrestore(&dev->lock, flags); | ||
2039 | |||
2040 | driver->unbind(&dev->gadget); | ||
2041 | dev->driver = NULL; | ||
2042 | |||
2043 | /* set SD */ | ||
2044 | tmp = readl(&dev->regs->ctl); | ||
2045 | tmp |= AMD_BIT(UDC_DEVCTL_SD); | ||
2046 | writel(tmp, &dev->regs->ctl); | ||
2047 | |||
2048 | |||
2049 | DBG(dev, "%s: unregistered\n", driver->driver.name); | ||
2050 | |||
2051 | return 0; | ||
2052 | } | ||
2053 | EXPORT_SYMBOL(usb_gadget_unregister_driver); | ||
2054 | |||
2055 | |||
2056 | /* Clear pending NAK bits */ | ||
2057 | static void udc_process_cnak_queue(struct udc *dev) | ||
2058 | { | ||
2059 | u32 tmp; | ||
2060 | u32 reg; | ||
2061 | |||
2062 | /* check epin's */ | ||
2063 | DBG(dev, "CNAK pending queue processing\n"); | ||
2064 | for (tmp = 0; tmp < UDC_EPIN_NUM_USED; tmp++) { | ||
2065 | if (cnak_pending & (1 << tmp)) { | ||
2066 | DBG(dev, "CNAK pending for ep%d\n", tmp); | ||
2067 | /* clear NAK by writing CNAK */ | ||
2068 | reg = readl(&dev->ep[tmp].regs->ctl); | ||
2069 | reg |= AMD_BIT(UDC_EPCTL_CNAK); | ||
2070 | writel(reg, &dev->ep[tmp].regs->ctl); | ||
2071 | dev->ep[tmp].naking = 0; | ||
2072 | UDC_QUEUE_CNAK(&dev->ep[tmp], dev->ep[tmp].num); | ||
2073 | } | ||
2074 | } | ||
2075 | /* ... and ep0out */ | ||
2076 | if (cnak_pending & (1 << UDC_EP0OUT_IX)) { | ||
2077 | DBG(dev, "CNAK pending for ep%d\n", UDC_EP0OUT_IX); | ||
2078 | /* clear NAK by writing CNAK */ | ||
2079 | reg = readl(&dev->ep[UDC_EP0OUT_IX].regs->ctl); | ||
2080 | reg |= AMD_BIT(UDC_EPCTL_CNAK); | ||
2081 | writel(reg, &dev->ep[UDC_EP0OUT_IX].regs->ctl); | ||
2082 | dev->ep[UDC_EP0OUT_IX].naking = 0; | ||
2083 | UDC_QUEUE_CNAK(&dev->ep[UDC_EP0OUT_IX], | ||
2084 | dev->ep[UDC_EP0OUT_IX].num); | ||
2085 | } | ||
2086 | } | ||
2087 | |||
2088 | /* Enabling RX DMA after setup packet */ | ||
2089 | static void udc_ep0_set_rde(struct udc *dev) | ||
2090 | { | ||
2091 | if (use_dma) { | ||
2092 | /* | ||
2093 | * only enable RXDMA when no data endpoint enabled | ||
2094 | * or data is queued | ||
2095 | */ | ||
2096 | if (!dev->data_ep_enabled || dev->data_ep_queued) { | ||
2097 | udc_set_rde(dev); | ||
2098 | } else { | ||
2099 | /* | ||
2100 | * setup timer for enabling RDE (to not enable | ||
2101 | * RXFIFO DMA for data endpoints to early) | ||
2102 | */ | ||
2103 | if (set_rde != 0 && !timer_pending(&udc_timer)) { | ||
2104 | udc_timer.expires = | ||
2105 | jiffies + HZ/UDC_RDE_TIMER_DIV; | ||
2106 | set_rde = 1; | ||
2107 | if (!stop_timer) { | ||
2108 | add_timer(&udc_timer); | ||
2109 | } | ||
2110 | } | ||
2111 | } | ||
2112 | } | ||
2113 | } | ||
2114 | |||
2115 | |||
2116 | /* Interrupt handler for data OUT traffic */ | ||
2117 | static irqreturn_t udc_data_out_isr(struct udc *dev, int ep_ix) | ||
2118 | { | ||
2119 | irqreturn_t ret_val = IRQ_NONE; | ||
2120 | u32 tmp; | ||
2121 | struct udc_ep *ep; | ||
2122 | struct udc_request *req; | ||
2123 | unsigned int count; | ||
2124 | struct udc_data_dma *td = NULL; | ||
2125 | unsigned dma_done; | ||
2126 | |||
2127 | VDBG(dev, "ep%d irq\n", ep_ix); | ||
2128 | ep = &dev->ep[ep_ix]; | ||
2129 | |||
2130 | tmp = readl(&ep->regs->sts); | ||
2131 | if (use_dma) { | ||
2132 | /* BNA event ? */ | ||
2133 | if (tmp & AMD_BIT(UDC_EPSTS_BNA)) { | ||
2134 | DBG(dev, "BNA ep%dout occured - DESPTR = %x \n", | ||
2135 | ep->num, readl(&ep->regs->desptr)); | ||
2136 | /* clear BNA */ | ||
2137 | writel(tmp | AMD_BIT(UDC_EPSTS_BNA), &ep->regs->sts); | ||
2138 | if (!ep->cancel_transfer) | ||
2139 | ep->bna_occurred = 1; | ||
2140 | else | ||
2141 | ep->cancel_transfer = 0; | ||
2142 | ret_val = IRQ_HANDLED; | ||
2143 | goto finished; | ||
2144 | } | ||
2145 | } | ||
2146 | /* HE event ? */ | ||
2147 | if (tmp & AMD_BIT(UDC_EPSTS_HE)) { | ||
2148 | dev_err(&dev->pdev->dev, "HE ep%dout occured\n", ep->num); | ||
2149 | |||
2150 | /* clear HE */ | ||
2151 | writel(tmp | AMD_BIT(UDC_EPSTS_HE), &ep->regs->sts); | ||
2152 | ret_val = IRQ_HANDLED; | ||
2153 | goto finished; | ||
2154 | } | ||
2155 | |||
2156 | if (!list_empty(&ep->queue)) { | ||
2157 | |||
2158 | /* next request */ | ||
2159 | req = list_entry(ep->queue.next, | ||
2160 | struct udc_request, queue); | ||
2161 | } else { | ||
2162 | req = NULL; | ||
2163 | udc_rxfifo_pending = 1; | ||
2164 | } | ||
2165 | VDBG(dev, "req = %p\n", req); | ||
2166 | /* fifo mode */ | ||
2167 | if (!use_dma) { | ||
2168 | |||
2169 | /* read fifo */ | ||
2170 | if (req && udc_rxfifo_read(ep, req)) { | ||
2171 | ret_val = IRQ_HANDLED; | ||
2172 | |||
2173 | /* finish */ | ||
2174 | complete_req(ep, req, 0); | ||
2175 | /* next request */ | ||
2176 | if (!list_empty(&ep->queue) && !ep->halted) { | ||
2177 | req = list_entry(ep->queue.next, | ||
2178 | struct udc_request, queue); | ||
2179 | } else | ||
2180 | req = NULL; | ||
2181 | } | ||
2182 | |||
2183 | /* DMA */ | ||
2184 | } else if (!ep->cancel_transfer && req != NULL) { | ||
2185 | ret_val = IRQ_HANDLED; | ||
2186 | |||
2187 | /* check for DMA done */ | ||
2188 | if (!use_dma_ppb) { | ||
2189 | dma_done = AMD_GETBITS(req->td_data->status, | ||
2190 | UDC_DMA_OUT_STS_BS); | ||
2191 | /* packet per buffer mode - rx bytes */ | ||
2192 | } else { | ||
2193 | /* | ||
2194 | * if BNA occurred then recover desc. from | ||
2195 | * BNA dummy desc. | ||
2196 | */ | ||
2197 | if (ep->bna_occurred) { | ||
2198 | VDBG(dev, "Recover desc. from BNA dummy\n"); | ||
2199 | memcpy(req->td_data, ep->bna_dummy_req->td_data, | ||
2200 | sizeof(struct udc_data_dma)); | ||
2201 | ep->bna_occurred = 0; | ||
2202 | udc_init_bna_dummy(ep->req); | ||
2203 | } | ||
2204 | td = udc_get_last_dma_desc(req); | ||
2205 | dma_done = AMD_GETBITS(td->status, UDC_DMA_OUT_STS_BS); | ||
2206 | } | ||
2207 | if (dma_done == UDC_DMA_OUT_STS_BS_DMA_DONE) { | ||
2208 | /* buffer fill mode - rx bytes */ | ||
2209 | if (!use_dma_ppb) { | ||
2210 | /* received number bytes */ | ||
2211 | count = AMD_GETBITS(req->td_data->status, | ||
2212 | UDC_DMA_OUT_STS_RXBYTES); | ||
2213 | VDBG(dev, "rx bytes=%u\n", count); | ||
2214 | /* packet per buffer mode - rx bytes */ | ||
2215 | } else { | ||
2216 | VDBG(dev, "req->td_data=%p\n", req->td_data); | ||
2217 | VDBG(dev, "last desc = %p\n", td); | ||
2218 | /* received number bytes */ | ||
2219 | if (use_dma_ppb_du) { | ||
2220 | /* every desc. counts bytes */ | ||
2221 | count = udc_get_ppbdu_rxbytes(req); | ||
2222 | } else { | ||
2223 | /* last desc. counts bytes */ | ||
2224 | count = AMD_GETBITS(td->status, | ||
2225 | UDC_DMA_OUT_STS_RXBYTES); | ||
2226 | if (!count && req->req.length | ||
2227 | == UDC_DMA_MAXPACKET) { | ||
2228 | /* | ||
2229 | * on 64k packets the RXBYTES | ||
2230 | * field is zero | ||
2231 | */ | ||
2232 | count = UDC_DMA_MAXPACKET; | ||
2233 | } | ||
2234 | } | ||
2235 | VDBG(dev, "last desc rx bytes=%u\n", count); | ||
2236 | } | ||
2237 | |||
2238 | tmp = req->req.length - req->req.actual; | ||
2239 | if (count > tmp) { | ||
2240 | if ((tmp % ep->ep.maxpacket) != 0) { | ||
2241 | DBG(dev, "%s: rx %db, space=%db\n", | ||
2242 | ep->ep.name, count, tmp); | ||
2243 | req->req.status = -EOVERFLOW; | ||
2244 | } | ||
2245 | count = tmp; | ||
2246 | } | ||
2247 | req->req.actual += count; | ||
2248 | req->dma_going = 0; | ||
2249 | /* complete request */ | ||
2250 | complete_req(ep, req, 0); | ||
2251 | |||
2252 | /* next request */ | ||
2253 | if (!list_empty(&ep->queue) && !ep->halted) { | ||
2254 | req = list_entry(ep->queue.next, | ||
2255 | struct udc_request, | ||
2256 | queue); | ||
2257 | /* | ||
2258 | * DMA may be already started by udc_queue() | ||
2259 | * called by gadget drivers completion | ||
2260 | * routine. This happens when queue | ||
2261 | * holds one request only. | ||
2262 | */ | ||
2263 | if (req->dma_going == 0) { | ||
2264 | /* next dma */ | ||
2265 | if (prep_dma(ep, req, GFP_ATOMIC) != 0) | ||
2266 | goto finished; | ||
2267 | /* write desc pointer */ | ||
2268 | writel(req->td_phys, | ||
2269 | &ep->regs->desptr); | ||
2270 | req->dma_going = 1; | ||
2271 | /* enable DMA */ | ||
2272 | udc_set_rde(dev); | ||
2273 | } | ||
2274 | } else { | ||
2275 | /* | ||
2276 | * implant BNA dummy descriptor to allow | ||
2277 | * RXFIFO opening by RDE | ||
2278 | */ | ||
2279 | if (ep->bna_dummy_req) { | ||
2280 | /* write desc pointer */ | ||
2281 | writel(ep->bna_dummy_req->td_phys, | ||
2282 | &ep->regs->desptr); | ||
2283 | ep->bna_occurred = 0; | ||
2284 | } | ||
2285 | |||
2286 | /* | ||
2287 | * schedule timer for setting RDE if queue | ||
2288 | * remains empty to allow ep0 packets pass | ||
2289 | * through | ||
2290 | */ | ||
2291 | if (set_rde != 0 | ||
2292 | && !timer_pending(&udc_timer)) { | ||
2293 | udc_timer.expires = | ||
2294 | jiffies | ||
2295 | + HZ*UDC_RDE_TIMER_SECONDS; | ||
2296 | set_rde = 1; | ||
2297 | if (!stop_timer) { | ||
2298 | add_timer(&udc_timer); | ||
2299 | } | ||
2300 | } | ||
2301 | if (ep->num != UDC_EP0OUT_IX) | ||
2302 | dev->data_ep_queued = 0; | ||
2303 | } | ||
2304 | |||
2305 | } else { | ||
2306 | /* | ||
2307 | * RX DMA must be reenabled for each desc in PPBDU mode | ||
2308 | * and must be enabled for PPBNDU mode in case of BNA | ||
2309 | */ | ||
2310 | udc_set_rde(dev); | ||
2311 | } | ||
2312 | |||
2313 | } else if (ep->cancel_transfer) { | ||
2314 | ret_val = IRQ_HANDLED; | ||
2315 | ep->cancel_transfer = 0; | ||
2316 | } | ||
2317 | |||
2318 | /* check pending CNAKS */ | ||
2319 | if (cnak_pending) { | ||
2320 | /* CNAk processing when rxfifo empty only */ | ||
2321 | if (readl(&dev->regs->sts) & AMD_BIT(UDC_DEVSTS_RXFIFO_EMPTY)) { | ||
2322 | udc_process_cnak_queue(dev); | ||
2323 | } | ||
2324 | } | ||
2325 | |||
2326 | /* clear OUT bits in ep status */ | ||
2327 | writel(UDC_EPSTS_OUT_CLEAR, &ep->regs->sts); | ||
2328 | finished: | ||
2329 | return ret_val; | ||
2330 | } | ||
2331 | |||
2332 | /* Interrupt handler for data IN traffic */ | ||
2333 | static irqreturn_t udc_data_in_isr(struct udc *dev, int ep_ix) | ||
2334 | { | ||
2335 | irqreturn_t ret_val = IRQ_NONE; | ||
2336 | u32 tmp; | ||
2337 | u32 epsts; | ||
2338 | struct udc_ep *ep; | ||
2339 | struct udc_request *req; | ||
2340 | struct udc_data_dma *td; | ||
2341 | unsigned dma_done; | ||
2342 | unsigned len; | ||
2343 | |||
2344 | ep = &dev->ep[ep_ix]; | ||
2345 | |||
2346 | epsts = readl(&ep->regs->sts); | ||
2347 | if (use_dma) { | ||
2348 | /* BNA ? */ | ||
2349 | if (epsts & AMD_BIT(UDC_EPSTS_BNA)) { | ||
2350 | dev_err(&dev->pdev->dev, | ||
2351 | "BNA ep%din occured - DESPTR = %08lx \n", | ||
2352 | ep->num, | ||
2353 | (unsigned long) readl(&ep->regs->desptr)); | ||
2354 | |||
2355 | /* clear BNA */ | ||
2356 | writel(epsts, &ep->regs->sts); | ||
2357 | ret_val = IRQ_HANDLED; | ||
2358 | goto finished; | ||
2359 | } | ||
2360 | } | ||
2361 | /* HE event ? */ | ||
2362 | if (epsts & AMD_BIT(UDC_EPSTS_HE)) { | ||
2363 | dev_err(&dev->pdev->dev, | ||
2364 | "HE ep%dn occured - DESPTR = %08lx \n", | ||
2365 | ep->num, (unsigned long) readl(&ep->regs->desptr)); | ||
2366 | |||
2367 | /* clear HE */ | ||
2368 | writel(epsts | AMD_BIT(UDC_EPSTS_HE), &ep->regs->sts); | ||
2369 | ret_val = IRQ_HANDLED; | ||
2370 | goto finished; | ||
2371 | } | ||
2372 | |||
2373 | /* DMA completion */ | ||
2374 | if (epsts & AMD_BIT(UDC_EPSTS_TDC)) { | ||
2375 | VDBG(dev, "TDC set- completion\n"); | ||
2376 | ret_val = IRQ_HANDLED; | ||
2377 | if (!ep->cancel_transfer && !list_empty(&ep->queue)) { | ||
2378 | req = list_entry(ep->queue.next, | ||
2379 | struct udc_request, queue); | ||
2380 | if (req) { | ||
2381 | /* | ||
2382 | * length bytes transfered | ||
2383 | * check dma done of last desc. in PPBDU mode | ||
2384 | */ | ||
2385 | if (use_dma_ppb_du) { | ||
2386 | td = udc_get_last_dma_desc(req); | ||
2387 | if (td) { | ||
2388 | dma_done = | ||
2389 | AMD_GETBITS(td->status, | ||
2390 | UDC_DMA_IN_STS_BS); | ||
2391 | /* don't care DMA done */ | ||
2392 | req->req.actual = | ||
2393 | req->req.length; | ||
2394 | } | ||
2395 | } else { | ||
2396 | /* assume all bytes transferred */ | ||
2397 | req->req.actual = req->req.length; | ||
2398 | } | ||
2399 | |||
2400 | if (req->req.actual == req->req.length) { | ||
2401 | /* complete req */ | ||
2402 | complete_req(ep, req, 0); | ||
2403 | req->dma_going = 0; | ||
2404 | /* further request available ? */ | ||
2405 | if (list_empty(&ep->queue)) { | ||
2406 | /* disable interrupt */ | ||
2407 | tmp = readl( | ||
2408 | &dev->regs->ep_irqmsk); | ||
2409 | tmp |= AMD_BIT(ep->num); | ||
2410 | writel(tmp, | ||
2411 | &dev->regs->ep_irqmsk); | ||
2412 | } | ||
2413 | |||
2414 | } | ||
2415 | } | ||
2416 | } | ||
2417 | ep->cancel_transfer = 0; | ||
2418 | |||
2419 | } | ||
2420 | /* | ||
2421 | * status reg has IN bit set and TDC not set (if TDC was handled, | ||
2422 | * IN must not be handled (UDC defect) ? | ||
2423 | */ | ||
2424 | if ((epsts & AMD_BIT(UDC_EPSTS_IN)) | ||
2425 | && !(epsts & AMD_BIT(UDC_EPSTS_TDC))) { | ||
2426 | ret_val = IRQ_HANDLED; | ||
2427 | if (!list_empty(&ep->queue)) { | ||
2428 | /* next request */ | ||
2429 | req = list_entry(ep->queue.next, | ||
2430 | struct udc_request, queue); | ||
2431 | /* FIFO mode */ | ||
2432 | if (!use_dma) { | ||
2433 | /* write fifo */ | ||
2434 | udc_txfifo_write(ep, &req->req); | ||
2435 | len = req->req.length - req->req.actual; | ||
2436 | if (len > ep->ep.maxpacket) | ||
2437 | len = ep->ep.maxpacket; | ||
2438 | req->req.actual += len; | ||
2439 | if (req->req.actual == req->req.length | ||
2440 | || (len != ep->ep.maxpacket)) { | ||
2441 | /* complete req */ | ||
2442 | complete_req(ep, req, 0); | ||
2443 | } | ||
2444 | /* DMA */ | ||
2445 | } else if (req && !req->dma_going) { | ||
2446 | VDBG(dev, "IN DMA : req=%p req->td_data=%p\n", | ||
2447 | req, req->td_data); | ||
2448 | if (req->td_data) { | ||
2449 | |||
2450 | req->dma_going = 1; | ||
2451 | |||
2452 | /* | ||
2453 | * unset L bit of first desc. | ||
2454 | * for chain | ||
2455 | */ | ||
2456 | if (use_dma_ppb && req->req.length > | ||
2457 | ep->ep.maxpacket) { | ||
2458 | req->td_data->status &= | ||
2459 | AMD_CLEAR_BIT( | ||
2460 | UDC_DMA_IN_STS_L); | ||
2461 | } | ||
2462 | |||
2463 | /* write desc pointer */ | ||
2464 | writel(req->td_phys, &ep->regs->desptr); | ||
2465 | |||
2466 | /* set HOST READY */ | ||
2467 | req->td_data->status = | ||
2468 | AMD_ADDBITS( | ||
2469 | req->td_data->status, | ||
2470 | UDC_DMA_IN_STS_BS_HOST_READY, | ||
2471 | UDC_DMA_IN_STS_BS); | ||
2472 | |||
2473 | /* set poll demand bit */ | ||
2474 | tmp = readl(&ep->regs->ctl); | ||
2475 | tmp |= AMD_BIT(UDC_EPCTL_P); | ||
2476 | writel(tmp, &ep->regs->ctl); | ||
2477 | } | ||
2478 | } | ||
2479 | |||
2480 | } | ||
2481 | } | ||
2482 | /* clear status bits */ | ||
2483 | writel(epsts, &ep->regs->sts); | ||
2484 | |||
2485 | finished: | ||
2486 | return ret_val; | ||
2487 | |||
2488 | } | ||
2489 | |||
2490 | /* Interrupt handler for Control OUT traffic */ | ||
2491 | static irqreturn_t udc_control_out_isr(struct udc *dev) | ||
2492 | __releases(dev->lock) | ||
2493 | __acquires(dev->lock) | ||
2494 | { | ||
2495 | irqreturn_t ret_val = IRQ_NONE; | ||
2496 | u32 tmp; | ||
2497 | int setup_supported; | ||
2498 | u32 count; | ||
2499 | int set = 0; | ||
2500 | struct udc_ep *ep; | ||
2501 | struct udc_ep *ep_tmp; | ||
2502 | |||
2503 | ep = &dev->ep[UDC_EP0OUT_IX]; | ||
2504 | |||
2505 | /* clear irq */ | ||
2506 | writel(AMD_BIT(UDC_EPINT_OUT_EP0), &dev->regs->ep_irqsts); | ||
2507 | |||
2508 | tmp = readl(&dev->ep[UDC_EP0OUT_IX].regs->sts); | ||
2509 | /* check BNA and clear if set */ | ||
2510 | if (tmp & AMD_BIT(UDC_EPSTS_BNA)) { | ||
2511 | VDBG(dev, "ep0: BNA set\n"); | ||
2512 | writel(AMD_BIT(UDC_EPSTS_BNA), | ||
2513 | &dev->ep[UDC_EP0OUT_IX].regs->sts); | ||
2514 | ep->bna_occurred = 1; | ||
2515 | ret_val = IRQ_HANDLED; | ||
2516 | goto finished; | ||
2517 | } | ||
2518 | |||
2519 | /* type of data: SETUP or DATA 0 bytes */ | ||
2520 | tmp = AMD_GETBITS(tmp, UDC_EPSTS_OUT); | ||
2521 | VDBG(dev, "data_typ = %x\n", tmp); | ||
2522 | |||
2523 | /* setup data */ | ||
2524 | if (tmp == UDC_EPSTS_OUT_SETUP) { | ||
2525 | ret_val = IRQ_HANDLED; | ||
2526 | |||
2527 | ep->dev->stall_ep0in = 0; | ||
2528 | dev->waiting_zlp_ack_ep0in = 0; | ||
2529 | |||
2530 | /* set NAK for EP0_IN */ | ||
2531 | tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->ctl); | ||
2532 | tmp |= AMD_BIT(UDC_EPCTL_SNAK); | ||
2533 | writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->ctl); | ||
2534 | dev->ep[UDC_EP0IN_IX].naking = 1; | ||
2535 | /* get setup data */ | ||
2536 | if (use_dma) { | ||
2537 | |||
2538 | /* clear OUT bits in ep status */ | ||
2539 | writel(UDC_EPSTS_OUT_CLEAR, | ||
2540 | &dev->ep[UDC_EP0OUT_IX].regs->sts); | ||
2541 | |||
2542 | setup_data.data[0] = | ||
2543 | dev->ep[UDC_EP0OUT_IX].td_stp->data12; | ||
2544 | setup_data.data[1] = | ||
2545 | dev->ep[UDC_EP0OUT_IX].td_stp->data34; | ||
2546 | /* set HOST READY */ | ||
2547 | dev->ep[UDC_EP0OUT_IX].td_stp->status = | ||
2548 | UDC_DMA_STP_STS_BS_HOST_READY; | ||
2549 | } else { | ||
2550 | /* read fifo */ | ||
2551 | udc_rxfifo_read_dwords(dev, setup_data.data, 2); | ||
2552 | } | ||
2553 | |||
2554 | /* determine direction of control data */ | ||
2555 | if ((setup_data.request.bRequestType & USB_DIR_IN) != 0) { | ||
2556 | dev->gadget.ep0 = &dev->ep[UDC_EP0IN_IX].ep; | ||
2557 | /* enable RDE */ | ||
2558 | udc_ep0_set_rde(dev); | ||
2559 | set = 0; | ||
2560 | } else { | ||
2561 | dev->gadget.ep0 = &dev->ep[UDC_EP0OUT_IX].ep; | ||
2562 | /* | ||
2563 | * implant BNA dummy descriptor to allow RXFIFO opening | ||
2564 | * by RDE | ||
2565 | */ | ||
2566 | if (ep->bna_dummy_req) { | ||
2567 | /* write desc pointer */ | ||
2568 | writel(ep->bna_dummy_req->td_phys, | ||
2569 | &dev->ep[UDC_EP0OUT_IX].regs->desptr); | ||
2570 | ep->bna_occurred = 0; | ||
2571 | } | ||
2572 | |||
2573 | set = 1; | ||
2574 | dev->ep[UDC_EP0OUT_IX].naking = 1; | ||
2575 | /* | ||
2576 | * setup timer for enabling RDE (to not enable | ||
2577 | * RXFIFO DMA for data to early) | ||
2578 | */ | ||
2579 | set_rde = 1; | ||
2580 | if (!timer_pending(&udc_timer)) { | ||
2581 | udc_timer.expires = jiffies + | ||
2582 | HZ/UDC_RDE_TIMER_DIV; | ||
2583 | if (!stop_timer) { | ||
2584 | add_timer(&udc_timer); | ||
2585 | } | ||
2586 | } | ||
2587 | } | ||
2588 | |||
2589 | /* | ||
2590 | * mass storage reset must be processed here because | ||
2591 | * next packet may be a CLEAR_FEATURE HALT which would not | ||
2592 | * clear the stall bit when no STALL handshake was received | ||
2593 | * before (autostall can cause this) | ||
2594 | */ | ||
2595 | if (setup_data.data[0] == UDC_MSCRES_DWORD0 | ||
2596 | && setup_data.data[1] == UDC_MSCRES_DWORD1) { | ||
2597 | DBG(dev, "MSC Reset\n"); | ||
2598 | /* | ||
2599 | * clear stall bits | ||
2600 | * only one IN and OUT endpoints are handled | ||
2601 | */ | ||
2602 | ep_tmp = &udc->ep[UDC_EPIN_IX]; | ||
2603 | udc_set_halt(&ep_tmp->ep, 0); | ||
2604 | ep_tmp = &udc->ep[UDC_EPOUT_IX]; | ||
2605 | udc_set_halt(&ep_tmp->ep, 0); | ||
2606 | } | ||
2607 | |||
2608 | /* call gadget with setup data received */ | ||
2609 | spin_unlock(&dev->lock); | ||
2610 | setup_supported = dev->driver->setup(&dev->gadget, | ||
2611 | &setup_data.request); | ||
2612 | spin_lock(&dev->lock); | ||
2613 | |||
2614 | tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->ctl); | ||
2615 | /* ep0 in returns data (not zlp) on IN phase */ | ||
2616 | if (setup_supported >= 0 && setup_supported < | ||
2617 | UDC_EP0IN_MAXPACKET) { | ||
2618 | /* clear NAK by writing CNAK in EP0_IN */ | ||
2619 | tmp |= AMD_BIT(UDC_EPCTL_CNAK); | ||
2620 | writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->ctl); | ||
2621 | dev->ep[UDC_EP0IN_IX].naking = 0; | ||
2622 | UDC_QUEUE_CNAK(&dev->ep[UDC_EP0IN_IX], UDC_EP0IN_IX); | ||
2623 | |||
2624 | /* if unsupported request then stall */ | ||
2625 | } else if (setup_supported < 0) { | ||
2626 | tmp |= AMD_BIT(UDC_EPCTL_S); | ||
2627 | writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->ctl); | ||
2628 | } else | ||
2629 | dev->waiting_zlp_ack_ep0in = 1; | ||
2630 | |||
2631 | |||
2632 | /* clear NAK by writing CNAK in EP0_OUT */ | ||
2633 | if (!set) { | ||
2634 | tmp = readl(&dev->ep[UDC_EP0OUT_IX].regs->ctl); | ||
2635 | tmp |= AMD_BIT(UDC_EPCTL_CNAK); | ||
2636 | writel(tmp, &dev->ep[UDC_EP0OUT_IX].regs->ctl); | ||
2637 | dev->ep[UDC_EP0OUT_IX].naking = 0; | ||
2638 | UDC_QUEUE_CNAK(&dev->ep[UDC_EP0OUT_IX], UDC_EP0OUT_IX); | ||
2639 | } | ||
2640 | |||
2641 | if (!use_dma) { | ||
2642 | /* clear OUT bits in ep status */ | ||
2643 | writel(UDC_EPSTS_OUT_CLEAR, | ||
2644 | &dev->ep[UDC_EP0OUT_IX].regs->sts); | ||
2645 | } | ||
2646 | |||
2647 | /* data packet 0 bytes */ | ||
2648 | } else if (tmp == UDC_EPSTS_OUT_DATA) { | ||
2649 | /* clear OUT bits in ep status */ | ||
2650 | writel(UDC_EPSTS_OUT_CLEAR, &dev->ep[UDC_EP0OUT_IX].regs->sts); | ||
2651 | |||
2652 | /* get setup data: only 0 packet */ | ||
2653 | if (use_dma) { | ||
2654 | /* no req if 0 packet, just reactivate */ | ||
2655 | if (list_empty(&dev->ep[UDC_EP0OUT_IX].queue)) { | ||
2656 | VDBG(dev, "ZLP\n"); | ||
2657 | |||
2658 | /* set HOST READY */ | ||
2659 | dev->ep[UDC_EP0OUT_IX].td->status = | ||
2660 | AMD_ADDBITS( | ||
2661 | dev->ep[UDC_EP0OUT_IX].td->status, | ||
2662 | UDC_DMA_OUT_STS_BS_HOST_READY, | ||
2663 | UDC_DMA_OUT_STS_BS); | ||
2664 | /* enable RDE */ | ||
2665 | udc_ep0_set_rde(dev); | ||
2666 | ret_val = IRQ_HANDLED; | ||
2667 | |||
2668 | } else { | ||
2669 | /* control write */ | ||
2670 | ret_val |= udc_data_out_isr(dev, UDC_EP0OUT_IX); | ||
2671 | /* re-program desc. pointer for possible ZLPs */ | ||
2672 | writel(dev->ep[UDC_EP0OUT_IX].td_phys, | ||
2673 | &dev->ep[UDC_EP0OUT_IX].regs->desptr); | ||
2674 | /* enable RDE */ | ||
2675 | udc_ep0_set_rde(dev); | ||
2676 | } | ||
2677 | } else { | ||
2678 | |||
2679 | /* received number bytes */ | ||
2680 | count = readl(&dev->ep[UDC_EP0OUT_IX].regs->sts); | ||
2681 | count = AMD_GETBITS(count, UDC_EPSTS_RX_PKT_SIZE); | ||
2682 | /* out data for fifo mode not working */ | ||
2683 | count = 0; | ||
2684 | |||
2685 | /* 0 packet or real data ? */ | ||
2686 | if (count != 0) { | ||
2687 | ret_val |= udc_data_out_isr(dev, UDC_EP0OUT_IX); | ||
2688 | } else { | ||
2689 | /* dummy read confirm */ | ||
2690 | readl(&dev->ep[UDC_EP0OUT_IX].regs->confirm); | ||
2691 | ret_val = IRQ_HANDLED; | ||
2692 | } | ||
2693 | } | ||
2694 | } | ||
2695 | |||
2696 | /* check pending CNAKS */ | ||
2697 | if (cnak_pending) { | ||
2698 | /* CNAk processing when rxfifo empty only */ | ||
2699 | if (readl(&dev->regs->sts) & AMD_BIT(UDC_DEVSTS_RXFIFO_EMPTY)) { | ||
2700 | udc_process_cnak_queue(dev); | ||
2701 | } | ||
2702 | } | ||
2703 | |||
2704 | finished: | ||
2705 | return ret_val; | ||
2706 | } | ||
2707 | |||
2708 | /* Interrupt handler for Control IN traffic */ | ||
2709 | static irqreturn_t udc_control_in_isr(struct udc *dev) | ||
2710 | { | ||
2711 | irqreturn_t ret_val = IRQ_NONE; | ||
2712 | u32 tmp; | ||
2713 | struct udc_ep *ep; | ||
2714 | struct udc_request *req; | ||
2715 | unsigned len; | ||
2716 | |||
2717 | ep = &dev->ep[UDC_EP0IN_IX]; | ||
2718 | |||
2719 | /* clear irq */ | ||
2720 | writel(AMD_BIT(UDC_EPINT_IN_EP0), &dev->regs->ep_irqsts); | ||
2721 | |||
2722 | tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->sts); | ||
2723 | /* DMA completion */ | ||
2724 | if (tmp & AMD_BIT(UDC_EPSTS_TDC)) { | ||
2725 | VDBG(dev, "isr: TDC clear \n"); | ||
2726 | ret_val = IRQ_HANDLED; | ||
2727 | |||
2728 | /* clear TDC bit */ | ||
2729 | writel(AMD_BIT(UDC_EPSTS_TDC), | ||
2730 | &dev->ep[UDC_EP0IN_IX].regs->sts); | ||
2731 | |||
2732 | /* status reg has IN bit set ? */ | ||
2733 | } else if (tmp & AMD_BIT(UDC_EPSTS_IN)) { | ||
2734 | ret_val = IRQ_HANDLED; | ||
2735 | |||
2736 | if (ep->dma) { | ||
2737 | /* clear IN bit */ | ||
2738 | writel(AMD_BIT(UDC_EPSTS_IN), | ||
2739 | &dev->ep[UDC_EP0IN_IX].regs->sts); | ||
2740 | } | ||
2741 | if (dev->stall_ep0in) { | ||
2742 | DBG(dev, "stall ep0in\n"); | ||
2743 | /* halt ep0in */ | ||
2744 | tmp = readl(&ep->regs->ctl); | ||
2745 | tmp |= AMD_BIT(UDC_EPCTL_S); | ||
2746 | writel(tmp, &ep->regs->ctl); | ||
2747 | } else { | ||
2748 | if (!list_empty(&ep->queue)) { | ||
2749 | /* next request */ | ||
2750 | req = list_entry(ep->queue.next, | ||
2751 | struct udc_request, queue); | ||
2752 | |||
2753 | if (ep->dma) { | ||
2754 | /* write desc pointer */ | ||
2755 | writel(req->td_phys, &ep->regs->desptr); | ||
2756 | /* set HOST READY */ | ||
2757 | req->td_data->status = | ||
2758 | AMD_ADDBITS( | ||
2759 | req->td_data->status, | ||
2760 | UDC_DMA_STP_STS_BS_HOST_READY, | ||
2761 | UDC_DMA_STP_STS_BS); | ||
2762 | |||
2763 | /* set poll demand bit */ | ||
2764 | tmp = | ||
2765 | readl(&dev->ep[UDC_EP0IN_IX].regs->ctl); | ||
2766 | tmp |= AMD_BIT(UDC_EPCTL_P); | ||
2767 | writel(tmp, | ||
2768 | &dev->ep[UDC_EP0IN_IX].regs->ctl); | ||
2769 | |||
2770 | /* all bytes will be transferred */ | ||
2771 | req->req.actual = req->req.length; | ||
2772 | |||
2773 | /* complete req */ | ||
2774 | complete_req(ep, req, 0); | ||
2775 | |||
2776 | } else { | ||
2777 | /* write fifo */ | ||
2778 | udc_txfifo_write(ep, &req->req); | ||
2779 | |||
2780 | /* lengh bytes transfered */ | ||
2781 | len = req->req.length - req->req.actual; | ||
2782 | if (len > ep->ep.maxpacket) | ||
2783 | len = ep->ep.maxpacket; | ||
2784 | |||
2785 | req->req.actual += len; | ||
2786 | if (req->req.actual == req->req.length | ||
2787 | || (len != ep->ep.maxpacket)) { | ||
2788 | /* complete req */ | ||
2789 | complete_req(ep, req, 0); | ||
2790 | } | ||
2791 | } | ||
2792 | |||
2793 | } | ||
2794 | } | ||
2795 | ep->halted = 0; | ||
2796 | dev->stall_ep0in = 0; | ||
2797 | if (!ep->dma) { | ||
2798 | /* clear IN bit */ | ||
2799 | writel(AMD_BIT(UDC_EPSTS_IN), | ||
2800 | &dev->ep[UDC_EP0IN_IX].regs->sts); | ||
2801 | } | ||
2802 | } | ||
2803 | |||
2804 | return ret_val; | ||
2805 | } | ||
2806 | |||
2807 | |||
2808 | /* Interrupt handler for global device events */ | ||
2809 | static irqreturn_t udc_dev_isr(struct udc *dev, u32 dev_irq) | ||
2810 | __releases(dev->lock) | ||
2811 | __acquires(dev->lock) | ||
2812 | { | ||
2813 | irqreturn_t ret_val = IRQ_NONE; | ||
2814 | u32 tmp; | ||
2815 | u32 cfg; | ||
2816 | struct udc_ep *ep; | ||
2817 | u16 i; | ||
2818 | u8 udc_csr_epix; | ||
2819 | |||
2820 | /* SET_CONFIG irq ? */ | ||
2821 | if (dev_irq & AMD_BIT(UDC_DEVINT_SC)) { | ||
2822 | ret_val = IRQ_HANDLED; | ||
2823 | |||
2824 | /* read config value */ | ||
2825 | tmp = readl(&dev->regs->sts); | ||
2826 | cfg = AMD_GETBITS(tmp, UDC_DEVSTS_CFG); | ||
2827 | DBG(dev, "SET_CONFIG interrupt: config=%d\n", cfg); | ||
2828 | dev->cur_config = cfg; | ||
2829 | dev->set_cfg_not_acked = 1; | ||
2830 | |||
2831 | /* make usb request for gadget driver */ | ||
2832 | memset(&setup_data, 0 , sizeof(union udc_setup_data)); | ||
2833 | setup_data.request.bRequest = USB_REQ_SET_CONFIGURATION; | ||
2834 | setup_data.request.wValue = dev->cur_config; | ||
2835 | |||
2836 | /* programm the NE registers */ | ||
2837 | for (i = 0; i < UDC_EP_NUM; i++) { | ||
2838 | ep = &dev->ep[i]; | ||
2839 | if (ep->in) { | ||
2840 | |||
2841 | /* ep ix in UDC CSR register space */ | ||
2842 | udc_csr_epix = ep->num; | ||
2843 | |||
2844 | |||
2845 | /* OUT ep */ | ||
2846 | } else { | ||
2847 | /* ep ix in UDC CSR register space */ | ||
2848 | udc_csr_epix = ep->num - UDC_CSR_EP_OUT_IX_OFS; | ||
2849 | } | ||
2850 | |||
2851 | tmp = readl(&dev->csr->ne[udc_csr_epix]); | ||
2852 | /* ep cfg */ | ||
2853 | tmp = AMD_ADDBITS(tmp, ep->dev->cur_config, | ||
2854 | UDC_CSR_NE_CFG); | ||
2855 | /* write reg */ | ||
2856 | writel(tmp, &dev->csr->ne[udc_csr_epix]); | ||
2857 | |||
2858 | /* clear stall bits */ | ||
2859 | ep->halted = 0; | ||
2860 | tmp = readl(&ep->regs->ctl); | ||
2861 | tmp = tmp & AMD_CLEAR_BIT(UDC_EPCTL_S); | ||
2862 | writel(tmp, &ep->regs->ctl); | ||
2863 | } | ||
2864 | /* call gadget zero with setup data received */ | ||
2865 | spin_unlock(&dev->lock); | ||
2866 | tmp = dev->driver->setup(&dev->gadget, &setup_data.request); | ||
2867 | spin_lock(&dev->lock); | ||
2868 | |||
2869 | } /* SET_INTERFACE ? */ | ||
2870 | if (dev_irq & AMD_BIT(UDC_DEVINT_SI)) { | ||
2871 | ret_val = IRQ_HANDLED; | ||
2872 | |||
2873 | dev->set_cfg_not_acked = 1; | ||
2874 | /* read interface and alt setting values */ | ||
2875 | tmp = readl(&dev->regs->sts); | ||
2876 | dev->cur_alt = AMD_GETBITS(tmp, UDC_DEVSTS_ALT); | ||
2877 | dev->cur_intf = AMD_GETBITS(tmp, UDC_DEVSTS_INTF); | ||
2878 | |||
2879 | /* make usb request for gadget driver */ | ||
2880 | memset(&setup_data, 0 , sizeof(union udc_setup_data)); | ||
2881 | setup_data.request.bRequest = USB_REQ_SET_INTERFACE; | ||
2882 | setup_data.request.bRequestType = USB_RECIP_INTERFACE; | ||
2883 | setup_data.request.wValue = dev->cur_alt; | ||
2884 | setup_data.request.wIndex = dev->cur_intf; | ||
2885 | |||
2886 | DBG(dev, "SET_INTERFACE interrupt: alt=%d intf=%d\n", | ||
2887 | dev->cur_alt, dev->cur_intf); | ||
2888 | |||
2889 | /* programm the NE registers */ | ||
2890 | for (i = 0; i < UDC_EP_NUM; i++) { | ||
2891 | ep = &dev->ep[i]; | ||
2892 | if (ep->in) { | ||
2893 | |||
2894 | /* ep ix in UDC CSR register space */ | ||
2895 | udc_csr_epix = ep->num; | ||
2896 | |||
2897 | |||
2898 | /* OUT ep */ | ||
2899 | } else { | ||
2900 | /* ep ix in UDC CSR register space */ | ||
2901 | udc_csr_epix = ep->num - UDC_CSR_EP_OUT_IX_OFS; | ||
2902 | } | ||
2903 | |||
2904 | /* UDC CSR reg */ | ||
2905 | /* set ep values */ | ||
2906 | tmp = readl(&dev->csr->ne[udc_csr_epix]); | ||
2907 | /* ep interface */ | ||
2908 | tmp = AMD_ADDBITS(tmp, ep->dev->cur_intf, | ||
2909 | UDC_CSR_NE_INTF); | ||
2910 | /* tmp = AMD_ADDBITS(tmp, 2, UDC_CSR_NE_INTF); */ | ||
2911 | /* ep alt */ | ||
2912 | tmp = AMD_ADDBITS(tmp, ep->dev->cur_alt, | ||
2913 | UDC_CSR_NE_ALT); | ||
2914 | /* write reg */ | ||
2915 | writel(tmp, &dev->csr->ne[udc_csr_epix]); | ||
2916 | |||
2917 | /* clear stall bits */ | ||
2918 | ep->halted = 0; | ||
2919 | tmp = readl(&ep->regs->ctl); | ||
2920 | tmp = tmp & AMD_CLEAR_BIT(UDC_EPCTL_S); | ||
2921 | writel(tmp, &ep->regs->ctl); | ||
2922 | } | ||
2923 | |||
2924 | /* call gadget zero with setup data received */ | ||
2925 | spin_unlock(&dev->lock); | ||
2926 | tmp = dev->driver->setup(&dev->gadget, &setup_data.request); | ||
2927 | spin_lock(&dev->lock); | ||
2928 | |||
2929 | } /* USB reset */ | ||
2930 | if (dev_irq & AMD_BIT(UDC_DEVINT_UR)) { | ||
2931 | DBG(dev, "USB Reset interrupt\n"); | ||
2932 | ret_val = IRQ_HANDLED; | ||
2933 | |||
2934 | /* allow soft reset when suspend occurs */ | ||
2935 | soft_reset_occured = 0; | ||
2936 | |||
2937 | dev->waiting_zlp_ack_ep0in = 0; | ||
2938 | dev->set_cfg_not_acked = 0; | ||
2939 | |||
2940 | /* mask not needed interrupts */ | ||
2941 | udc_mask_unused_interrupts(dev); | ||
2942 | |||
2943 | /* call gadget to resume and reset configs etc. */ | ||
2944 | spin_unlock(&dev->lock); | ||
2945 | if (dev->sys_suspended && dev->driver->resume) { | ||
2946 | dev->driver->resume(&dev->gadget); | ||
2947 | dev->sys_suspended = 0; | ||
2948 | } | ||
2949 | dev->driver->disconnect(&dev->gadget); | ||
2950 | spin_lock(&dev->lock); | ||
2951 | |||
2952 | /* disable ep0 to empty req queue */ | ||
2953 | empty_req_queue(&dev->ep[UDC_EP0IN_IX]); | ||
2954 | ep_init(dev->regs, &dev->ep[UDC_EP0IN_IX]); | ||
2955 | |||
2956 | /* soft reset when rxfifo not empty */ | ||
2957 | tmp = readl(&dev->regs->sts); | ||
2958 | if (!(tmp & AMD_BIT(UDC_DEVSTS_RXFIFO_EMPTY)) | ||
2959 | && !soft_reset_after_usbreset_occured) { | ||
2960 | udc_soft_reset(dev); | ||
2961 | soft_reset_after_usbreset_occured++; | ||
2962 | } | ||
2963 | |||
2964 | /* | ||
2965 | * DMA reset to kill potential old DMA hw hang, | ||
2966 | * POLL bit is already reset by ep_init() through | ||
2967 | * disconnect() | ||
2968 | */ | ||
2969 | DBG(dev, "DMA machine reset\n"); | ||
2970 | tmp = readl(&dev->regs->cfg); | ||
2971 | writel(tmp | AMD_BIT(UDC_DEVCFG_DMARST), &dev->regs->cfg); | ||
2972 | writel(tmp, &dev->regs->cfg); | ||
2973 | |||
2974 | /* put into initial config */ | ||
2975 | udc_basic_init(dev); | ||
2976 | |||
2977 | /* enable device setup interrupts */ | ||
2978 | udc_enable_dev_setup_interrupts(dev); | ||
2979 | |||
2980 | /* enable suspend interrupt */ | ||
2981 | tmp = readl(&dev->regs->irqmsk); | ||
2982 | tmp &= AMD_UNMASK_BIT(UDC_DEVINT_US); | ||
2983 | writel(tmp, &dev->regs->irqmsk); | ||
2984 | |||
2985 | } /* USB suspend */ | ||
2986 | if (dev_irq & AMD_BIT(UDC_DEVINT_US)) { | ||
2987 | DBG(dev, "USB Suspend interrupt\n"); | ||
2988 | ret_val = IRQ_HANDLED; | ||
2989 | if (dev->driver->suspend) { | ||
2990 | spin_unlock(&dev->lock); | ||
2991 | dev->sys_suspended = 1; | ||
2992 | dev->driver->suspend(&dev->gadget); | ||
2993 | spin_lock(&dev->lock); | ||
2994 | } | ||
2995 | } /* new speed ? */ | ||
2996 | if (dev_irq & AMD_BIT(UDC_DEVINT_ENUM)) { | ||
2997 | DBG(dev, "ENUM interrupt\n"); | ||
2998 | ret_val = IRQ_HANDLED; | ||
2999 | soft_reset_after_usbreset_occured = 0; | ||
3000 | |||
3001 | /* disable ep0 to empty req queue */ | ||
3002 | empty_req_queue(&dev->ep[UDC_EP0IN_IX]); | ||
3003 | ep_init(dev->regs, &dev->ep[UDC_EP0IN_IX]); | ||
3004 | |||
3005 | /* link up all endpoints */ | ||
3006 | udc_setup_endpoints(dev); | ||
3007 | if (dev->gadget.speed == USB_SPEED_HIGH) { | ||
3008 | dev_info(&dev->pdev->dev, "Connect: speed = %s\n", | ||
3009 | "high"); | ||
3010 | } else if (dev->gadget.speed == USB_SPEED_FULL) { | ||
3011 | dev_info(&dev->pdev->dev, "Connect: speed = %s\n", | ||
3012 | "full"); | ||
3013 | } | ||
3014 | |||
3015 | /* init ep 0 */ | ||
3016 | activate_control_endpoints(dev); | ||
3017 | |||
3018 | /* enable ep0 interrupts */ | ||
3019 | udc_enable_ep0_interrupts(dev); | ||
3020 | } | ||
3021 | /* session valid change interrupt */ | ||
3022 | if (dev_irq & AMD_BIT(UDC_DEVINT_SVC)) { | ||
3023 | DBG(dev, "USB SVC interrupt\n"); | ||
3024 | ret_val = IRQ_HANDLED; | ||
3025 | |||
3026 | /* check that session is not valid to detect disconnect */ | ||
3027 | tmp = readl(&dev->regs->sts); | ||
3028 | if (!(tmp & AMD_BIT(UDC_DEVSTS_SESSVLD))) { | ||
3029 | /* disable suspend interrupt */ | ||
3030 | tmp = readl(&dev->regs->irqmsk); | ||
3031 | tmp |= AMD_BIT(UDC_DEVINT_US); | ||
3032 | writel(tmp, &dev->regs->irqmsk); | ||
3033 | DBG(dev, "USB Disconnect (session valid low)\n"); | ||
3034 | /* cleanup on disconnect */ | ||
3035 | usb_disconnect(udc); | ||
3036 | } | ||
3037 | |||
3038 | } | ||
3039 | |||
3040 | return ret_val; | ||
3041 | } | ||
3042 | |||
3043 | /* Interrupt Service Routine, see Linux Kernel Doc for parameters */ | ||
3044 | static irqreturn_t udc_irq(int irq, void *pdev) | ||
3045 | { | ||
3046 | struct udc *dev = pdev; | ||
3047 | u32 reg; | ||
3048 | u16 i; | ||
3049 | u32 ep_irq; | ||
3050 | irqreturn_t ret_val = IRQ_NONE; | ||
3051 | |||
3052 | spin_lock(&dev->lock); | ||
3053 | |||
3054 | /* check for ep irq */ | ||
3055 | reg = readl(&dev->regs->ep_irqsts); | ||
3056 | if (reg) { | ||
3057 | if (reg & AMD_BIT(UDC_EPINT_OUT_EP0)) | ||
3058 | ret_val |= udc_control_out_isr(dev); | ||
3059 | if (reg & AMD_BIT(UDC_EPINT_IN_EP0)) | ||
3060 | ret_val |= udc_control_in_isr(dev); | ||
3061 | |||
3062 | /* | ||
3063 | * data endpoint | ||
3064 | * iterate ep's | ||
3065 | */ | ||
3066 | for (i = 1; i < UDC_EP_NUM; i++) { | ||
3067 | ep_irq = 1 << i; | ||
3068 | if (!(reg & ep_irq) || i == UDC_EPINT_OUT_EP0) | ||
3069 | continue; | ||
3070 | |||
3071 | /* clear irq status */ | ||
3072 | writel(ep_irq, &dev->regs->ep_irqsts); | ||
3073 | |||
3074 | /* irq for out ep ? */ | ||
3075 | if (i > UDC_EPIN_NUM) | ||
3076 | ret_val |= udc_data_out_isr(dev, i); | ||
3077 | else | ||
3078 | ret_val |= udc_data_in_isr(dev, i); | ||
3079 | } | ||
3080 | |||
3081 | } | ||
3082 | |||
3083 | |||
3084 | /* check for dev irq */ | ||
3085 | reg = readl(&dev->regs->irqsts); | ||
3086 | if (reg) { | ||
3087 | /* clear irq */ | ||
3088 | writel(reg, &dev->regs->irqsts); | ||
3089 | ret_val |= udc_dev_isr(dev, reg); | ||
3090 | } | ||
3091 | |||
3092 | |||
3093 | spin_unlock(&dev->lock); | ||
3094 | return ret_val; | ||
3095 | } | ||
3096 | |||
3097 | /* Tears down device */ | ||
3098 | static void gadget_release(struct device *pdev) | ||
3099 | { | ||
3100 | struct amd5536udc *dev = dev_get_drvdata(pdev); | ||
3101 | kfree(dev); | ||
3102 | } | ||
3103 | |||
3104 | /* Cleanup on device remove */ | ||
3105 | static void udc_remove(struct udc *dev) | ||
3106 | { | ||
3107 | /* remove timer */ | ||
3108 | stop_timer++; | ||
3109 | if (timer_pending(&udc_timer)) | ||
3110 | wait_for_completion(&on_exit); | ||
3111 | if (udc_timer.data) | ||
3112 | del_timer_sync(&udc_timer); | ||
3113 | /* remove pollstall timer */ | ||
3114 | stop_pollstall_timer++; | ||
3115 | if (timer_pending(&udc_pollstall_timer)) | ||
3116 | wait_for_completion(&on_pollstall_exit); | ||
3117 | if (udc_pollstall_timer.data) | ||
3118 | del_timer_sync(&udc_pollstall_timer); | ||
3119 | udc = NULL; | ||
3120 | } | ||
3121 | |||
3122 | /* Reset all pci context */ | ||
3123 | static void udc_pci_remove(struct pci_dev *pdev) | ||
3124 | { | ||
3125 | struct udc *dev; | ||
3126 | |||
3127 | dev = pci_get_drvdata(pdev); | ||
3128 | |||
3129 | /* gadget driver must not be registered */ | ||
3130 | BUG_ON(dev->driver != NULL); | ||
3131 | |||
3132 | /* dma pool cleanup */ | ||
3133 | if (dev->data_requests) | ||
3134 | pci_pool_destroy(dev->data_requests); | ||
3135 | |||
3136 | if (dev->stp_requests) { | ||
3137 | /* cleanup DMA desc's for ep0in */ | ||
3138 | pci_pool_free(dev->stp_requests, | ||
3139 | dev->ep[UDC_EP0OUT_IX].td_stp, | ||
3140 | dev->ep[UDC_EP0OUT_IX].td_stp_dma); | ||
3141 | pci_pool_free(dev->stp_requests, | ||
3142 | dev->ep[UDC_EP0OUT_IX].td, | ||
3143 | dev->ep[UDC_EP0OUT_IX].td_phys); | ||
3144 | |||
3145 | pci_pool_destroy(dev->stp_requests); | ||
3146 | } | ||
3147 | |||
3148 | /* reset controller */ | ||
3149 | writel(AMD_BIT(UDC_DEVCFG_SOFTRESET), &dev->regs->cfg); | ||
3150 | if (dev->irq_registered) | ||
3151 | free_irq(pdev->irq, dev); | ||
3152 | if (dev->regs) | ||
3153 | iounmap(dev->regs); | ||
3154 | if (dev->mem_region) | ||
3155 | release_mem_region(pci_resource_start(pdev, 0), | ||
3156 | pci_resource_len(pdev, 0)); | ||
3157 | if (dev->active) | ||
3158 | pci_disable_device(pdev); | ||
3159 | |||
3160 | device_unregister(&dev->gadget.dev); | ||
3161 | pci_set_drvdata(pdev, NULL); | ||
3162 | |||
3163 | udc_remove(dev); | ||
3164 | } | ||
3165 | |||
3166 | /* create dma pools on init */ | ||
3167 | static int init_dma_pools(struct udc *dev) | ||
3168 | { | ||
3169 | struct udc_stp_dma *td_stp; | ||
3170 | struct udc_data_dma *td_data; | ||
3171 | int retval; | ||
3172 | |||
3173 | /* consistent DMA mode setting ? */ | ||
3174 | if (use_dma_ppb) { | ||
3175 | use_dma_bufferfill_mode = 0; | ||
3176 | } else { | ||
3177 | use_dma_ppb_du = 0; | ||
3178 | use_dma_bufferfill_mode = 1; | ||
3179 | } | ||
3180 | |||
3181 | /* DMA setup */ | ||
3182 | dev->data_requests = dma_pool_create("data_requests", NULL, | ||
3183 | sizeof(struct udc_data_dma), 0, 0); | ||
3184 | if (!dev->data_requests) { | ||
3185 | DBG(dev, "can't get request data pool\n"); | ||
3186 | retval = -ENOMEM; | ||
3187 | goto finished; | ||
3188 | } | ||
3189 | |||
3190 | /* EP0 in dma regs = dev control regs */ | ||
3191 | dev->ep[UDC_EP0IN_IX].dma = &dev->regs->ctl; | ||
3192 | |||
3193 | /* dma desc for setup data */ | ||
3194 | dev->stp_requests = dma_pool_create("setup requests", NULL, | ||
3195 | sizeof(struct udc_stp_dma), 0, 0); | ||
3196 | if (!dev->stp_requests) { | ||
3197 | DBG(dev, "can't get stp request pool\n"); | ||
3198 | retval = -ENOMEM; | ||
3199 | goto finished; | ||
3200 | } | ||
3201 | /* setup */ | ||
3202 | td_stp = dma_pool_alloc(dev->stp_requests, GFP_KERNEL, | ||
3203 | &dev->ep[UDC_EP0OUT_IX].td_stp_dma); | ||
3204 | if (td_stp == NULL) { | ||
3205 | retval = -ENOMEM; | ||
3206 | goto finished; | ||
3207 | } | ||
3208 | dev->ep[UDC_EP0OUT_IX].td_stp = td_stp; | ||
3209 | |||
3210 | /* data: 0 packets !? */ | ||
3211 | td_data = dma_pool_alloc(dev->stp_requests, GFP_KERNEL, | ||
3212 | &dev->ep[UDC_EP0OUT_IX].td_phys); | ||
3213 | if (td_data == NULL) { | ||
3214 | retval = -ENOMEM; | ||
3215 | goto finished; | ||
3216 | } | ||
3217 | dev->ep[UDC_EP0OUT_IX].td = td_data; | ||
3218 | return 0; | ||
3219 | |||
3220 | finished: | ||
3221 | return retval; | ||
3222 | } | ||
3223 | |||
3224 | /* Called by pci bus driver to init pci context */ | ||
3225 | static int udc_pci_probe( | ||
3226 | struct pci_dev *pdev, | ||
3227 | const struct pci_device_id *id | ||
3228 | ) | ||
3229 | { | ||
3230 | struct udc *dev; | ||
3231 | unsigned long resource; | ||
3232 | unsigned long len; | ||
3233 | int retval = 0; | ||
3234 | |||
3235 | /* one udc only */ | ||
3236 | if (udc) { | ||
3237 | dev_dbg(&pdev->dev, "already probed\n"); | ||
3238 | return -EBUSY; | ||
3239 | } | ||
3240 | |||
3241 | /* init */ | ||
3242 | dev = kzalloc(sizeof(struct udc), GFP_KERNEL); | ||
3243 | if (!dev) { | ||
3244 | retval = -ENOMEM; | ||
3245 | goto finished; | ||
3246 | } | ||
3247 | memset(dev, 0, sizeof(struct udc)); | ||
3248 | |||
3249 | /* pci setup */ | ||
3250 | if (pci_enable_device(pdev) < 0) { | ||
3251 | retval = -ENODEV; | ||
3252 | goto finished; | ||
3253 | } | ||
3254 | dev->active = 1; | ||
3255 | |||
3256 | /* PCI resource allocation */ | ||
3257 | resource = pci_resource_start(pdev, 0); | ||
3258 | len = pci_resource_len(pdev, 0); | ||
3259 | |||
3260 | if (!request_mem_region(resource, len, name)) { | ||
3261 | dev_dbg(&pdev->dev, "pci device used already\n"); | ||
3262 | retval = -EBUSY; | ||
3263 | goto finished; | ||
3264 | } | ||
3265 | dev->mem_region = 1; | ||
3266 | |||
3267 | dev->virt_addr = ioremap_nocache(resource, len); | ||
3268 | if (dev->virt_addr == NULL) { | ||
3269 | dev_dbg(&pdev->dev, "start address cannot be mapped\n"); | ||
3270 | retval = -EFAULT; | ||
3271 | goto finished; | ||
3272 | } | ||
3273 | |||
3274 | if (!pdev->irq) { | ||
3275 | dev_err(&dev->pdev->dev, "irq not set\n"); | ||
3276 | retval = -ENODEV; | ||
3277 | goto finished; | ||
3278 | } | ||
3279 | |||
3280 | if (request_irq(pdev->irq, udc_irq, IRQF_SHARED, name, dev) != 0) { | ||
3281 | dev_dbg(&dev->pdev->dev, "request_irq(%d) fail\n", pdev->irq); | ||
3282 | retval = -EBUSY; | ||
3283 | goto finished; | ||
3284 | } | ||
3285 | dev->irq_registered = 1; | ||
3286 | |||
3287 | pci_set_drvdata(pdev, dev); | ||
3288 | |||
3289 | /* chip revision */ | ||
3290 | dev->chiprev = 0; | ||
3291 | |||
3292 | pci_set_master(pdev); | ||
3293 | pci_set_mwi(pdev); | ||
3294 | |||
3295 | /* chip rev for Hs AMD5536 */ | ||
3296 | pci_read_config_byte(pdev, PCI_REVISION_ID, (u8 *) &dev->chiprev); | ||
3297 | /* init dma pools */ | ||
3298 | if (use_dma) { | ||
3299 | retval = init_dma_pools(dev); | ||
3300 | if (retval != 0) | ||
3301 | goto finished; | ||
3302 | } | ||
3303 | |||
3304 | dev->phys_addr = resource; | ||
3305 | dev->irq = pdev->irq; | ||
3306 | dev->pdev = pdev; | ||
3307 | dev->gadget.dev.parent = &pdev->dev; | ||
3308 | dev->gadget.dev.dma_mask = pdev->dev.dma_mask; | ||
3309 | |||
3310 | /* general probing */ | ||
3311 | if (udc_probe(dev) == 0) | ||
3312 | return 0; | ||
3313 | |||
3314 | finished: | ||
3315 | if (dev) | ||
3316 | udc_pci_remove(pdev); | ||
3317 | return retval; | ||
3318 | } | ||
3319 | |||
3320 | /* general probe */ | ||
3321 | static int udc_probe(struct udc *dev) | ||
3322 | { | ||
3323 | char tmp[128]; | ||
3324 | u32 reg; | ||
3325 | int retval; | ||
3326 | |||
3327 | /* mark timer as not initialized */ | ||
3328 | udc_timer.data = 0; | ||
3329 | udc_pollstall_timer.data = 0; | ||
3330 | |||
3331 | /* device struct setup */ | ||
3332 | spin_lock_init(&dev->lock); | ||
3333 | dev->gadget.ops = &udc_ops; | ||
3334 | |||
3335 | strcpy(dev->gadget.dev.bus_id, "gadget"); | ||
3336 | dev->gadget.dev.release = gadget_release; | ||
3337 | dev->gadget.name = name; | ||
3338 | dev->gadget.name = name; | ||
3339 | dev->gadget.is_dualspeed = 1; | ||
3340 | |||
3341 | /* udc csr registers base */ | ||
3342 | dev->csr = dev->virt_addr + UDC_CSR_ADDR; | ||
3343 | /* dev registers base */ | ||
3344 | dev->regs = dev->virt_addr + UDC_DEVCFG_ADDR; | ||
3345 | /* ep registers base */ | ||
3346 | dev->ep_regs = dev->virt_addr + UDC_EPREGS_ADDR; | ||
3347 | /* fifo's base */ | ||
3348 | dev->rxfifo = (u32 __iomem *)(dev->virt_addr + UDC_RXFIFO_ADDR); | ||
3349 | dev->txfifo = (u32 __iomem *)(dev->virt_addr + UDC_TXFIFO_ADDR); | ||
3350 | |||
3351 | /* init registers, interrupts, ... */ | ||
3352 | startup_registers(dev); | ||
3353 | |||
3354 | dev_info(&dev->pdev->dev, "%s\n", mod_desc); | ||
3355 | |||
3356 | snprintf(tmp, sizeof tmp, "%d", dev->irq); | ||
3357 | dev_info(&dev->pdev->dev, | ||
3358 | "irq %s, pci mem %08lx, chip rev %02x(Geode5536 %s)\n", | ||
3359 | tmp, dev->phys_addr, dev->chiprev, | ||
3360 | (dev->chiprev == UDC_HSA0_REV) ? "A0" : "B1"); | ||
3361 | strcpy(tmp, UDC_DRIVER_VERSION_STRING); | ||
3362 | if (dev->chiprev == UDC_HSA0_REV) { | ||
3363 | dev_err(&dev->pdev->dev, "chip revision is A0; too old\n"); | ||
3364 | retval = -ENODEV; | ||
3365 | goto finished; | ||
3366 | } | ||
3367 | dev_info(&dev->pdev->dev, | ||
3368 | "driver version: %s(for Geode5536 B1)\n", tmp); | ||
3369 | udc = dev; | ||
3370 | |||
3371 | retval = device_register(&dev->gadget.dev); | ||
3372 | if (retval) | ||
3373 | goto finished; | ||
3374 | |||
3375 | /* timer init */ | ||
3376 | init_timer(&udc_timer); | ||
3377 | udc_timer.function = udc_timer_function; | ||
3378 | udc_timer.data = 1; | ||
3379 | /* timer pollstall init */ | ||
3380 | init_timer(&udc_pollstall_timer); | ||
3381 | udc_pollstall_timer.function = udc_pollstall_timer_function; | ||
3382 | udc_pollstall_timer.data = 1; | ||
3383 | |||
3384 | /* set SD */ | ||
3385 | reg = readl(&dev->regs->ctl); | ||
3386 | reg |= AMD_BIT(UDC_DEVCTL_SD); | ||
3387 | writel(reg, &dev->regs->ctl); | ||
3388 | |||
3389 | /* print dev register info */ | ||
3390 | print_regs(dev); | ||
3391 | |||
3392 | return 0; | ||
3393 | |||
3394 | finished: | ||
3395 | return retval; | ||
3396 | } | ||
3397 | |||
3398 | /* Initiates a remote wakeup */ | ||
3399 | static int udc_remote_wakeup(struct udc *dev) | ||
3400 | { | ||
3401 | unsigned long flags; | ||
3402 | u32 tmp; | ||
3403 | |||
3404 | DBG(dev, "UDC initiates remote wakeup\n"); | ||
3405 | |||
3406 | spin_lock_irqsave(&dev->lock, flags); | ||
3407 | |||
3408 | tmp = readl(&dev->regs->ctl); | ||
3409 | tmp |= AMD_BIT(UDC_DEVCTL_RES); | ||
3410 | writel(tmp, &dev->regs->ctl); | ||
3411 | tmp &= AMD_CLEAR_BIT(UDC_DEVCTL_RES); | ||
3412 | writel(tmp, &dev->regs->ctl); | ||
3413 | |||
3414 | spin_unlock_irqrestore(&dev->lock, flags); | ||
3415 | return 0; | ||
3416 | } | ||
3417 | |||
3418 | /* PCI device parameters */ | ||
3419 | static const struct pci_device_id pci_id[] = { | ||
3420 | { | ||
3421 | PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x2096), | ||
3422 | .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe, | ||
3423 | .class_mask = 0xffffffff, | ||
3424 | }, | ||
3425 | {}, | ||
3426 | }; | ||
3427 | MODULE_DEVICE_TABLE(pci, pci_id); | ||
3428 | |||
3429 | /* PCI functions */ | ||
3430 | static struct pci_driver udc_pci_driver = { | ||
3431 | .name = (char *) name, | ||
3432 | .id_table = pci_id, | ||
3433 | .probe = udc_pci_probe, | ||
3434 | .remove = udc_pci_remove, | ||
3435 | }; | ||
3436 | |||
3437 | /* Inits driver */ | ||
3438 | static int __init init(void) | ||
3439 | { | ||
3440 | return pci_register_driver(&udc_pci_driver); | ||
3441 | } | ||
3442 | module_init(init); | ||
3443 | |||
3444 | /* Cleans driver */ | ||
3445 | static void __exit cleanup(void) | ||
3446 | { | ||
3447 | pci_unregister_driver(&udc_pci_driver); | ||
3448 | } | ||
3449 | module_exit(cleanup); | ||
3450 | |||
3451 | MODULE_DESCRIPTION(UDC_MOD_DESCRIPTION); | ||
3452 | MODULE_AUTHOR("Thomas Dahlmann"); | ||
3453 | MODULE_LICENSE("GPL"); | ||
3454 | |||
diff --git a/drivers/usb/gadget/amd5536udc.h b/drivers/usb/gadget/amd5536udc.h new file mode 100644 index 000000000000..4bbabbbfc93f --- /dev/null +++ b/drivers/usb/gadget/amd5536udc.h | |||
@@ -0,0 +1,626 @@ | |||
1 | /* | ||
2 | * amd5536.h -- header for AMD 5536 UDC high/full speed USB device controller | ||
3 | * | ||
4 | * Copyright (C) 2007 AMD (http://www.amd.com) | ||
5 | * Author: Thomas Dahlmann | ||
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 | * 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 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #ifndef AMD5536UDC_H | ||
23 | #define AMD5536UDC_H | ||
24 | |||
25 | /* various constants */ | ||
26 | #define UDC_RDE_TIMER_SECONDS 1 | ||
27 | #define UDC_RDE_TIMER_DIV 10 | ||
28 | #define UDC_POLLSTALL_TIMER_USECONDS 500 | ||
29 | |||
30 | /* Hs AMD5536 chip rev. */ | ||
31 | #define UDC_HSA0_REV 1 | ||
32 | #define UDC_HSB1_REV 2 | ||
33 | |||
34 | /* | ||
35 | * SETUP usb commands | ||
36 | * needed, because some SETUP's are handled in hw, but must be passed to | ||
37 | * gadget driver above | ||
38 | * SET_CONFIG | ||
39 | */ | ||
40 | #define UDC_SETCONFIG_DWORD0 0x00000900 | ||
41 | #define UDC_SETCONFIG_DWORD0_VALUE_MASK 0xffff0000 | ||
42 | #define UDC_SETCONFIG_DWORD0_VALUE_OFS 16 | ||
43 | |||
44 | #define UDC_SETCONFIG_DWORD1 0x00000000 | ||
45 | |||
46 | /* SET_INTERFACE */ | ||
47 | #define UDC_SETINTF_DWORD0 0x00000b00 | ||
48 | #define UDC_SETINTF_DWORD0_ALT_MASK 0xffff0000 | ||
49 | #define UDC_SETINTF_DWORD0_ALT_OFS 16 | ||
50 | |||
51 | #define UDC_SETINTF_DWORD1 0x00000000 | ||
52 | #define UDC_SETINTF_DWORD1_INTF_MASK 0x0000ffff | ||
53 | #define UDC_SETINTF_DWORD1_INTF_OFS 0 | ||
54 | |||
55 | /* Mass storage reset */ | ||
56 | #define UDC_MSCRES_DWORD0 0x0000ff21 | ||
57 | #define UDC_MSCRES_DWORD1 0x00000000 | ||
58 | |||
59 | /* Global CSR's -------------------------------------------------------------*/ | ||
60 | #define UDC_CSR_ADDR 0x500 | ||
61 | |||
62 | /* EP NE bits */ | ||
63 | /* EP number */ | ||
64 | #define UDC_CSR_NE_NUM_MASK 0x0000000f | ||
65 | #define UDC_CSR_NE_NUM_OFS 0 | ||
66 | /* EP direction */ | ||
67 | #define UDC_CSR_NE_DIR_MASK 0x00000010 | ||
68 | #define UDC_CSR_NE_DIR_OFS 4 | ||
69 | /* EP type */ | ||
70 | #define UDC_CSR_NE_TYPE_MASK 0x00000060 | ||
71 | #define UDC_CSR_NE_TYPE_OFS 5 | ||
72 | /* EP config number */ | ||
73 | #define UDC_CSR_NE_CFG_MASK 0x00000780 | ||
74 | #define UDC_CSR_NE_CFG_OFS 7 | ||
75 | /* EP interface number */ | ||
76 | #define UDC_CSR_NE_INTF_MASK 0x00007800 | ||
77 | #define UDC_CSR_NE_INTF_OFS 11 | ||
78 | /* EP alt setting */ | ||
79 | #define UDC_CSR_NE_ALT_MASK 0x00078000 | ||
80 | #define UDC_CSR_NE_ALT_OFS 15 | ||
81 | |||
82 | /* max pkt */ | ||
83 | #define UDC_CSR_NE_MAX_PKT_MASK 0x3ff80000 | ||
84 | #define UDC_CSR_NE_MAX_PKT_OFS 19 | ||
85 | |||
86 | /* Device Config Register ---------------------------------------------------*/ | ||
87 | #define UDC_DEVCFG_ADDR 0x400 | ||
88 | |||
89 | #define UDC_DEVCFG_SOFTRESET 31 | ||
90 | #define UDC_DEVCFG_HNPSFEN 30 | ||
91 | #define UDC_DEVCFG_DMARST 29 | ||
92 | #define UDC_DEVCFG_SET_DESC 18 | ||
93 | #define UDC_DEVCFG_CSR_PRG 17 | ||
94 | #define UDC_DEVCFG_STATUS 7 | ||
95 | #define UDC_DEVCFG_DIR 6 | ||
96 | #define UDC_DEVCFG_PI 5 | ||
97 | #define UDC_DEVCFG_SS 4 | ||
98 | #define UDC_DEVCFG_SP 3 | ||
99 | #define UDC_DEVCFG_RWKP 2 | ||
100 | |||
101 | #define UDC_DEVCFG_SPD_MASK 0x3 | ||
102 | #define UDC_DEVCFG_SPD_OFS 0 | ||
103 | #define UDC_DEVCFG_SPD_HS 0x0 | ||
104 | #define UDC_DEVCFG_SPD_FS 0x1 | ||
105 | #define UDC_DEVCFG_SPD_LS 0x2 | ||
106 | /*#define UDC_DEVCFG_SPD_FS 0x3*/ | ||
107 | |||
108 | |||
109 | /* Device Control Register --------------------------------------------------*/ | ||
110 | #define UDC_DEVCTL_ADDR 0x404 | ||
111 | |||
112 | #define UDC_DEVCTL_THLEN_MASK 0xff000000 | ||
113 | #define UDC_DEVCTL_THLEN_OFS 24 | ||
114 | |||
115 | #define UDC_DEVCTL_BRLEN_MASK 0x00ff0000 | ||
116 | #define UDC_DEVCTL_BRLEN_OFS 16 | ||
117 | |||
118 | #define UDC_DEVCTL_CSR_DONE 13 | ||
119 | #define UDC_DEVCTL_DEVNAK 12 | ||
120 | #define UDC_DEVCTL_SD 10 | ||
121 | #define UDC_DEVCTL_MODE 9 | ||
122 | #define UDC_DEVCTL_BREN 8 | ||
123 | #define UDC_DEVCTL_THE 7 | ||
124 | #define UDC_DEVCTL_BF 6 | ||
125 | #define UDC_DEVCTL_BE 5 | ||
126 | #define UDC_DEVCTL_DU 4 | ||
127 | #define UDC_DEVCTL_TDE 3 | ||
128 | #define UDC_DEVCTL_RDE 2 | ||
129 | #define UDC_DEVCTL_RES 0 | ||
130 | |||
131 | |||
132 | /* Device Status Register ---------------------------------------------------*/ | ||
133 | #define UDC_DEVSTS_ADDR 0x408 | ||
134 | |||
135 | #define UDC_DEVSTS_TS_MASK 0xfffc0000 | ||
136 | #define UDC_DEVSTS_TS_OFS 18 | ||
137 | |||
138 | #define UDC_DEVSTS_SESSVLD 17 | ||
139 | #define UDC_DEVSTS_PHY_ERROR 16 | ||
140 | #define UDC_DEVSTS_RXFIFO_EMPTY 15 | ||
141 | |||
142 | #define UDC_DEVSTS_ENUM_SPEED_MASK 0x00006000 | ||
143 | #define UDC_DEVSTS_ENUM_SPEED_OFS 13 | ||
144 | #define UDC_DEVSTS_ENUM_SPEED_FULL 1 | ||
145 | #define UDC_DEVSTS_ENUM_SPEED_HIGH 0 | ||
146 | |||
147 | #define UDC_DEVSTS_SUSP 12 | ||
148 | |||
149 | #define UDC_DEVSTS_ALT_MASK 0x00000f00 | ||
150 | #define UDC_DEVSTS_ALT_OFS 8 | ||
151 | |||
152 | #define UDC_DEVSTS_INTF_MASK 0x000000f0 | ||
153 | #define UDC_DEVSTS_INTF_OFS 4 | ||
154 | |||
155 | #define UDC_DEVSTS_CFG_MASK 0x0000000f | ||
156 | #define UDC_DEVSTS_CFG_OFS 0 | ||
157 | |||
158 | |||
159 | /* Device Interrupt Register ------------------------------------------------*/ | ||
160 | #define UDC_DEVINT_ADDR 0x40c | ||
161 | |||
162 | #define UDC_DEVINT_SVC 7 | ||
163 | #define UDC_DEVINT_ENUM 6 | ||
164 | #define UDC_DEVINT_SOF 5 | ||
165 | #define UDC_DEVINT_US 4 | ||
166 | #define UDC_DEVINT_UR 3 | ||
167 | #define UDC_DEVINT_ES 2 | ||
168 | #define UDC_DEVINT_SI 1 | ||
169 | #define UDC_DEVINT_SC 0 | ||
170 | |||
171 | /* Device Interrupt Mask Register -------------------------------------------*/ | ||
172 | #define UDC_DEVINT_MSK_ADDR 0x410 | ||
173 | |||
174 | #define UDC_DEVINT_MSK 0x7f | ||
175 | |||
176 | /* Endpoint Interrupt Register ----------------------------------------------*/ | ||
177 | #define UDC_EPINT_ADDR 0x414 | ||
178 | |||
179 | #define UDC_EPINT_OUT_MASK 0xffff0000 | ||
180 | #define UDC_EPINT_OUT_OFS 16 | ||
181 | #define UDC_EPINT_IN_MASK 0x0000ffff | ||
182 | #define UDC_EPINT_IN_OFS 0 | ||
183 | |||
184 | #define UDC_EPINT_IN_EP0 0 | ||
185 | #define UDC_EPINT_IN_EP1 1 | ||
186 | #define UDC_EPINT_IN_EP2 2 | ||
187 | #define UDC_EPINT_IN_EP3 3 | ||
188 | #define UDC_EPINT_OUT_EP0 16 | ||
189 | #define UDC_EPINT_OUT_EP1 17 | ||
190 | #define UDC_EPINT_OUT_EP2 18 | ||
191 | #define UDC_EPINT_OUT_EP3 19 | ||
192 | |||
193 | #define UDC_EPINT_EP0_ENABLE_MSK 0x001e001e | ||
194 | |||
195 | /* Endpoint Interrupt Mask Register -----------------------------------------*/ | ||
196 | #define UDC_EPINT_MSK_ADDR 0x418 | ||
197 | |||
198 | #define UDC_EPINT_OUT_MSK_MASK 0xffff0000 | ||
199 | #define UDC_EPINT_OUT_MSK_OFS 16 | ||
200 | #define UDC_EPINT_IN_MSK_MASK 0x0000ffff | ||
201 | #define UDC_EPINT_IN_MSK_OFS 0 | ||
202 | |||
203 | #define UDC_EPINT_MSK_DISABLE_ALL 0xffffffff | ||
204 | /* mask non-EP0 endpoints */ | ||
205 | #define UDC_EPDATAINT_MSK_DISABLE 0xfffefffe | ||
206 | /* mask all dev interrupts */ | ||
207 | #define UDC_DEV_MSK_DISABLE 0x7f | ||
208 | |||
209 | /* Endpoint-specific CSR's --------------------------------------------------*/ | ||
210 | #define UDC_EPREGS_ADDR 0x0 | ||
211 | #define UDC_EPIN_REGS_ADDR 0x0 | ||
212 | #define UDC_EPOUT_REGS_ADDR 0x200 | ||
213 | |||
214 | #define UDC_EPCTL_ADDR 0x0 | ||
215 | |||
216 | #define UDC_EPCTL_RRDY 9 | ||
217 | #define UDC_EPCTL_CNAK 8 | ||
218 | #define UDC_EPCTL_SNAK 7 | ||
219 | #define UDC_EPCTL_NAK 6 | ||
220 | |||
221 | #define UDC_EPCTL_ET_MASK 0x00000030 | ||
222 | #define UDC_EPCTL_ET_OFS 4 | ||
223 | #define UDC_EPCTL_ET_CONTROL 0 | ||
224 | #define UDC_EPCTL_ET_ISO 1 | ||
225 | #define UDC_EPCTL_ET_BULK 2 | ||
226 | #define UDC_EPCTL_ET_INTERRUPT 3 | ||
227 | |||
228 | #define UDC_EPCTL_P 3 | ||
229 | #define UDC_EPCTL_SN 2 | ||
230 | #define UDC_EPCTL_F 1 | ||
231 | #define UDC_EPCTL_S 0 | ||
232 | |||
233 | /* Endpoint Status Registers ------------------------------------------------*/ | ||
234 | #define UDC_EPSTS_ADDR 0x4 | ||
235 | |||
236 | #define UDC_EPSTS_RX_PKT_SIZE_MASK 0x007ff800 | ||
237 | #define UDC_EPSTS_RX_PKT_SIZE_OFS 11 | ||
238 | |||
239 | #define UDC_EPSTS_TDC 10 | ||
240 | #define UDC_EPSTS_HE 9 | ||
241 | #define UDC_EPSTS_BNA 7 | ||
242 | #define UDC_EPSTS_IN 6 | ||
243 | |||
244 | #define UDC_EPSTS_OUT_MASK 0x00000030 | ||
245 | #define UDC_EPSTS_OUT_OFS 4 | ||
246 | #define UDC_EPSTS_OUT_DATA 1 | ||
247 | #define UDC_EPSTS_OUT_DATA_CLEAR 0x10 | ||
248 | #define UDC_EPSTS_OUT_SETUP 2 | ||
249 | #define UDC_EPSTS_OUT_SETUP_CLEAR 0x20 | ||
250 | #define UDC_EPSTS_OUT_CLEAR 0x30 | ||
251 | |||
252 | /* Endpoint Buffer Size IN/ Receive Packet Frame Number OUT Registers ------*/ | ||
253 | #define UDC_EPIN_BUFF_SIZE_ADDR 0x8 | ||
254 | #define UDC_EPOUT_FRAME_NUMBER_ADDR 0x8 | ||
255 | |||
256 | #define UDC_EPIN_BUFF_SIZE_MASK 0x0000ffff | ||
257 | #define UDC_EPIN_BUFF_SIZE_OFS 0 | ||
258 | /* EP0in txfifo = 128 bytes*/ | ||
259 | #define UDC_EPIN0_BUFF_SIZE 32 | ||
260 | /* EP0in fullspeed txfifo = 128 bytes*/ | ||
261 | #define UDC_FS_EPIN0_BUFF_SIZE 32 | ||
262 | |||
263 | /* fifo size mult = fifo size / max packet */ | ||
264 | #define UDC_EPIN_BUFF_SIZE_MULT 2 | ||
265 | |||
266 | /* EPin data fifo size = 1024 bytes DOUBLE BUFFERING */ | ||
267 | #define UDC_EPIN_BUFF_SIZE 256 | ||
268 | /* EPin small INT data fifo size = 128 bytes */ | ||
269 | #define UDC_EPIN_SMALLINT_BUFF_SIZE 32 | ||
270 | |||
271 | /* EPin fullspeed data fifo size = 128 bytes DOUBLE BUFFERING */ | ||
272 | #define UDC_FS_EPIN_BUFF_SIZE 32 | ||
273 | |||
274 | #define UDC_EPOUT_FRAME_NUMBER_MASK 0x0000ffff | ||
275 | #define UDC_EPOUT_FRAME_NUMBER_OFS 0 | ||
276 | |||
277 | /* Endpoint Buffer Size OUT/Max Packet Size Registers -----------------------*/ | ||
278 | #define UDC_EPOUT_BUFF_SIZE_ADDR 0x0c | ||
279 | #define UDC_EP_MAX_PKT_SIZE_ADDR 0x0c | ||
280 | |||
281 | #define UDC_EPOUT_BUFF_SIZE_MASK 0xffff0000 | ||
282 | #define UDC_EPOUT_BUFF_SIZE_OFS 16 | ||
283 | #define UDC_EP_MAX_PKT_SIZE_MASK 0x0000ffff | ||
284 | #define UDC_EP_MAX_PKT_SIZE_OFS 0 | ||
285 | /* EP0in max packet size = 64 bytes */ | ||
286 | #define UDC_EP0IN_MAX_PKT_SIZE 64 | ||
287 | /* EP0out max packet size = 64 bytes */ | ||
288 | #define UDC_EP0OUT_MAX_PKT_SIZE 64 | ||
289 | /* EP0in fullspeed max packet size = 64 bytes */ | ||
290 | #define UDC_FS_EP0IN_MAX_PKT_SIZE 64 | ||
291 | /* EP0out fullspeed max packet size = 64 bytes */ | ||
292 | #define UDC_FS_EP0OUT_MAX_PKT_SIZE 64 | ||
293 | |||
294 | /* | ||
295 | * Endpoint dma descriptors ------------------------------------------------ | ||
296 | * | ||
297 | * Setup data, Status dword | ||
298 | */ | ||
299 | #define UDC_DMA_STP_STS_CFG_MASK 0x0fff0000 | ||
300 | #define UDC_DMA_STP_STS_CFG_OFS 16 | ||
301 | #define UDC_DMA_STP_STS_CFG_ALT_MASK 0x000f0000 | ||
302 | #define UDC_DMA_STP_STS_CFG_ALT_OFS 16 | ||
303 | #define UDC_DMA_STP_STS_CFG_INTF_MASK 0x00f00000 | ||
304 | #define UDC_DMA_STP_STS_CFG_INTF_OFS 20 | ||
305 | #define UDC_DMA_STP_STS_CFG_NUM_MASK 0x0f000000 | ||
306 | #define UDC_DMA_STP_STS_CFG_NUM_OFS 24 | ||
307 | #define UDC_DMA_STP_STS_RX_MASK 0x30000000 | ||
308 | #define UDC_DMA_STP_STS_RX_OFS 28 | ||
309 | #define UDC_DMA_STP_STS_BS_MASK 0xc0000000 | ||
310 | #define UDC_DMA_STP_STS_BS_OFS 30 | ||
311 | #define UDC_DMA_STP_STS_BS_HOST_READY 0 | ||
312 | #define UDC_DMA_STP_STS_BS_DMA_BUSY 1 | ||
313 | #define UDC_DMA_STP_STS_BS_DMA_DONE 2 | ||
314 | #define UDC_DMA_STP_STS_BS_HOST_BUSY 3 | ||
315 | /* IN data, Status dword */ | ||
316 | #define UDC_DMA_IN_STS_TXBYTES_MASK 0x0000ffff | ||
317 | #define UDC_DMA_IN_STS_TXBYTES_OFS 0 | ||
318 | #define UDC_DMA_IN_STS_FRAMENUM_MASK 0x07ff0000 | ||
319 | #define UDC_DMA_IN_STS_FRAMENUM_OFS 0 | ||
320 | #define UDC_DMA_IN_STS_L 27 | ||
321 | #define UDC_DMA_IN_STS_TX_MASK 0x30000000 | ||
322 | #define UDC_DMA_IN_STS_TX_OFS 28 | ||
323 | #define UDC_DMA_IN_STS_BS_MASK 0xc0000000 | ||
324 | #define UDC_DMA_IN_STS_BS_OFS 30 | ||
325 | #define UDC_DMA_IN_STS_BS_HOST_READY 0 | ||
326 | #define UDC_DMA_IN_STS_BS_DMA_BUSY 1 | ||
327 | #define UDC_DMA_IN_STS_BS_DMA_DONE 2 | ||
328 | #define UDC_DMA_IN_STS_BS_HOST_BUSY 3 | ||
329 | /* OUT data, Status dword */ | ||
330 | #define UDC_DMA_OUT_STS_RXBYTES_MASK 0x0000ffff | ||
331 | #define UDC_DMA_OUT_STS_RXBYTES_OFS 0 | ||
332 | #define UDC_DMA_OUT_STS_FRAMENUM_MASK 0x07ff0000 | ||
333 | #define UDC_DMA_OUT_STS_FRAMENUM_OFS 0 | ||
334 | #define UDC_DMA_OUT_STS_L 27 | ||
335 | #define UDC_DMA_OUT_STS_RX_MASK 0x30000000 | ||
336 | #define UDC_DMA_OUT_STS_RX_OFS 28 | ||
337 | #define UDC_DMA_OUT_STS_BS_MASK 0xc0000000 | ||
338 | #define UDC_DMA_OUT_STS_BS_OFS 30 | ||
339 | #define UDC_DMA_OUT_STS_BS_HOST_READY 0 | ||
340 | #define UDC_DMA_OUT_STS_BS_DMA_BUSY 1 | ||
341 | #define UDC_DMA_OUT_STS_BS_DMA_DONE 2 | ||
342 | #define UDC_DMA_OUT_STS_BS_HOST_BUSY 3 | ||
343 | /* max ep0in packet */ | ||
344 | #define UDC_EP0IN_MAXPACKET 1000 | ||
345 | /* max dma packet */ | ||
346 | #define UDC_DMA_MAXPACKET 65536 | ||
347 | |||
348 | /* un-usable DMA address */ | ||
349 | #define DMA_DONT_USE (~(dma_addr_t) 0 ) | ||
350 | |||
351 | /* other Endpoint register addresses and values-----------------------------*/ | ||
352 | #define UDC_EP_SUBPTR_ADDR 0x10 | ||
353 | #define UDC_EP_DESPTR_ADDR 0x14 | ||
354 | #define UDC_EP_WRITE_CONFIRM_ADDR 0x1c | ||
355 | |||
356 | /* EP number as layouted in AHB space */ | ||
357 | #define UDC_EP_NUM 32 | ||
358 | #define UDC_EPIN_NUM 16 | ||
359 | #define UDC_EPIN_NUM_USED 5 | ||
360 | #define UDC_EPOUT_NUM 16 | ||
361 | /* EP number of EP's really used = EP0 + 8 data EP's */ | ||
362 | #define UDC_USED_EP_NUM 9 | ||
363 | /* UDC CSR regs are aligned but AHB regs not - offset for OUT EP's */ | ||
364 | #define UDC_CSR_EP_OUT_IX_OFS 12 | ||
365 | |||
366 | #define UDC_EP0OUT_IX 16 | ||
367 | #define UDC_EP0IN_IX 0 | ||
368 | |||
369 | /* Rx fifo address and size = 1k -------------------------------------------*/ | ||
370 | #define UDC_RXFIFO_ADDR 0x800 | ||
371 | #define UDC_RXFIFO_SIZE 0x400 | ||
372 | |||
373 | /* Tx fifo address and size = 1.5k -----------------------------------------*/ | ||
374 | #define UDC_TXFIFO_ADDR 0xc00 | ||
375 | #define UDC_TXFIFO_SIZE 0x600 | ||
376 | |||
377 | /* default data endpoints --------------------------------------------------*/ | ||
378 | #define UDC_EPIN_STATUS_IX 1 | ||
379 | #define UDC_EPIN_IX 2 | ||
380 | #define UDC_EPOUT_IX 18 | ||
381 | |||
382 | /* general constants -------------------------------------------------------*/ | ||
383 | #define UDC_DWORD_BYTES 4 | ||
384 | #define UDC_BITS_PER_BYTE_SHIFT 3 | ||
385 | #define UDC_BYTE_MASK 0xff | ||
386 | #define UDC_BITS_PER_BYTE 8 | ||
387 | |||
388 | /*---------------------------------------------------------------------------*/ | ||
389 | /* UDC CSR's */ | ||
390 | struct udc_csrs { | ||
391 | |||
392 | /* sca - setup command address */ | ||
393 | u32 sca; | ||
394 | |||
395 | /* ep ne's */ | ||
396 | u32 ne[UDC_USED_EP_NUM]; | ||
397 | } __attribute__ ((packed)); | ||
398 | |||
399 | /* AHB subsystem CSR registers */ | ||
400 | struct udc_regs { | ||
401 | |||
402 | /* device configuration */ | ||
403 | u32 cfg; | ||
404 | |||
405 | /* device control */ | ||
406 | u32 ctl; | ||
407 | |||
408 | /* device status */ | ||
409 | u32 sts; | ||
410 | |||
411 | /* device interrupt */ | ||
412 | u32 irqsts; | ||
413 | |||
414 | /* device interrupt mask */ | ||
415 | u32 irqmsk; | ||
416 | |||
417 | /* endpoint interrupt */ | ||
418 | u32 ep_irqsts; | ||
419 | |||
420 | /* endpoint interrupt mask */ | ||
421 | u32 ep_irqmsk; | ||
422 | } __attribute__ ((packed)); | ||
423 | |||
424 | /* endpoint specific registers */ | ||
425 | struct udc_ep_regs { | ||
426 | |||
427 | /* endpoint control */ | ||
428 | u32 ctl; | ||
429 | |||
430 | /* endpoint status */ | ||
431 | u32 sts; | ||
432 | |||
433 | /* endpoint buffer size in/ receive packet frame number out */ | ||
434 | u32 bufin_framenum; | ||
435 | |||
436 | /* endpoint buffer size out/max packet size */ | ||
437 | u32 bufout_maxpkt; | ||
438 | |||
439 | /* endpoint setup buffer pointer */ | ||
440 | u32 subptr; | ||
441 | |||
442 | /* endpoint data descriptor pointer */ | ||
443 | u32 desptr; | ||
444 | |||
445 | /* reserverd */ | ||
446 | u32 reserved; | ||
447 | |||
448 | /* write/read confirmation */ | ||
449 | u32 confirm; | ||
450 | |||
451 | } __attribute__ ((packed)); | ||
452 | |||
453 | /* control data DMA desc */ | ||
454 | struct udc_stp_dma { | ||
455 | /* status quadlet */ | ||
456 | u32 status; | ||
457 | /* reserved */ | ||
458 | u32 _reserved; | ||
459 | /* first setup word */ | ||
460 | u32 data12; | ||
461 | /* second setup word */ | ||
462 | u32 data34; | ||
463 | } __attribute__ ((aligned (16))); | ||
464 | |||
465 | /* normal data DMA desc */ | ||
466 | struct udc_data_dma { | ||
467 | /* status quadlet */ | ||
468 | u32 status; | ||
469 | /* reserved */ | ||
470 | u32 _reserved; | ||
471 | /* buffer pointer */ | ||
472 | u32 bufptr; | ||
473 | /* next descriptor pointer */ | ||
474 | u32 next; | ||
475 | } __attribute__ ((aligned (16))); | ||
476 | |||
477 | /* request packet */ | ||
478 | struct udc_request { | ||
479 | /* embedded gadget ep */ | ||
480 | struct usb_request req; | ||
481 | |||
482 | /* flags */ | ||
483 | unsigned dma_going : 1, | ||
484 | dma_mapping : 1, | ||
485 | dma_done : 1; | ||
486 | /* phys. address */ | ||
487 | dma_addr_t td_phys; | ||
488 | /* first dma desc. of chain */ | ||
489 | struct udc_data_dma *td_data; | ||
490 | /* last dma desc. of chain */ | ||
491 | struct udc_data_dma *td_data_last; | ||
492 | struct list_head queue; | ||
493 | |||
494 | /* chain length */ | ||
495 | unsigned chain_len; | ||
496 | |||
497 | }; | ||
498 | |||
499 | /* UDC specific endpoint parameters */ | ||
500 | struct udc_ep { | ||
501 | struct usb_ep ep; | ||
502 | struct udc_ep_regs __iomem *regs; | ||
503 | u32 __iomem *txfifo; | ||
504 | u32 __iomem *dma; | ||
505 | dma_addr_t td_phys; | ||
506 | dma_addr_t td_stp_dma; | ||
507 | struct udc_stp_dma *td_stp; | ||
508 | struct udc_data_dma *td; | ||
509 | /* temp request */ | ||
510 | struct udc_request *req; | ||
511 | unsigned req_used; | ||
512 | unsigned req_completed; | ||
513 | /* dummy DMA desc for BNA dummy */ | ||
514 | struct udc_request *bna_dummy_req; | ||
515 | unsigned bna_occurred; | ||
516 | |||
517 | /* NAK state */ | ||
518 | unsigned naking; | ||
519 | |||
520 | struct udc *dev; | ||
521 | |||
522 | /* queue for requests */ | ||
523 | struct list_head queue; | ||
524 | const struct usb_endpoint_descriptor *desc; | ||
525 | unsigned halted; | ||
526 | unsigned cancel_transfer; | ||
527 | unsigned num : 5, | ||
528 | fifo_depth : 14, | ||
529 | in : 1; | ||
530 | }; | ||
531 | |||
532 | /* device struct */ | ||
533 | struct udc { | ||
534 | struct usb_gadget gadget; | ||
535 | spinlock_t lock; /* protects all state */ | ||
536 | /* all endpoints */ | ||
537 | struct udc_ep ep[UDC_EP_NUM]; | ||
538 | struct usb_gadget_driver *driver; | ||
539 | /* operational flags */ | ||
540 | unsigned active : 1, | ||
541 | stall_ep0in : 1, | ||
542 | waiting_zlp_ack_ep0in : 1, | ||
543 | set_cfg_not_acked : 1, | ||
544 | irq_registered : 1, | ||
545 | data_ep_enabled : 1, | ||
546 | data_ep_queued : 1, | ||
547 | mem_region : 1, | ||
548 | sys_suspended : 1, | ||
549 | connected; | ||
550 | |||
551 | u16 chiprev; | ||
552 | |||
553 | /* registers */ | ||
554 | struct pci_dev *pdev; | ||
555 | struct udc_csrs __iomem *csr; | ||
556 | struct udc_regs __iomem *regs; | ||
557 | struct udc_ep_regs __iomem *ep_regs; | ||
558 | u32 __iomem *rxfifo; | ||
559 | u32 __iomem *txfifo; | ||
560 | |||
561 | /* DMA desc pools */ | ||
562 | struct pci_pool *data_requests; | ||
563 | struct pci_pool *stp_requests; | ||
564 | |||
565 | /* device data */ | ||
566 | unsigned long phys_addr; | ||
567 | void __iomem *virt_addr; | ||
568 | unsigned irq; | ||
569 | |||
570 | /* states */ | ||
571 | u16 cur_config; | ||
572 | u16 cur_intf; | ||
573 | u16 cur_alt; | ||
574 | }; | ||
575 | |||
576 | /* setup request data */ | ||
577 | union udc_setup_data { | ||
578 | u32 data[2]; | ||
579 | struct usb_ctrlrequest request; | ||
580 | }; | ||
581 | |||
582 | /* | ||
583 | *--------------------------------------------------------------------------- | ||
584 | * SET and GET bitfields in u32 values | ||
585 | * via constants for mask/offset: | ||
586 | * <bit_field_stub_name> is the text between | ||
587 | * UDC_ and _MASK|_OFS of appropiate | ||
588 | * constant | ||
589 | * | ||
590 | * set bitfield value in u32 u32Val | ||
591 | */ | ||
592 | #define AMD_ADDBITS(u32Val, bitfield_val, bitfield_stub_name) \ | ||
593 | (((u32Val) & (((u32) ~((u32) bitfield_stub_name##_MASK)))) \ | ||
594 | | (((bitfield_val) << ((u32) bitfield_stub_name##_OFS)) \ | ||
595 | & ((u32) bitfield_stub_name##_MASK))) | ||
596 | |||
597 | /* | ||
598 | * set bitfield value in zero-initialized u32 u32Val | ||
599 | * => bitfield bits in u32Val are all zero | ||
600 | */ | ||
601 | #define AMD_INIT_SETBITS(u32Val, bitfield_val, bitfield_stub_name) \ | ||
602 | ((u32Val) \ | ||
603 | | (((bitfield_val) << ((u32) bitfield_stub_name##_OFS)) \ | ||
604 | & ((u32) bitfield_stub_name##_MASK))) | ||
605 | |||
606 | /* get bitfield value from u32 u32Val */ | ||
607 | #define AMD_GETBITS(u32Val, bitfield_stub_name) \ | ||
608 | ((u32Val & ((u32) bitfield_stub_name##_MASK)) \ | ||
609 | >> ((u32) bitfield_stub_name##_OFS)) | ||
610 | |||
611 | /* SET and GET bits in u32 values ------------------------------------------*/ | ||
612 | #define AMD_BIT(bit_stub_name) (1 << bit_stub_name) | ||
613 | #define AMD_UNMASK_BIT(bit_stub_name) (~AMD_BIT(bit_stub_name)) | ||
614 | #define AMD_CLEAR_BIT(bit_stub_name) (~AMD_BIT(bit_stub_name)) | ||
615 | |||
616 | /* debug macros ------------------------------------------------------------*/ | ||
617 | |||
618 | #define DBG(udc , args...) dev_dbg(&(udc)->pdev->dev, args) | ||
619 | |||
620 | #ifdef UDC_VERBOSE | ||
621 | #define VDBG DBG | ||
622 | #else | ||
623 | #define VDBG(udc , args...) do {} while (0) | ||
624 | #endif | ||
625 | |||
626 | #endif /* #ifdef AMD5536UDC_H */ | ||
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index dbaf867436df..a3376739a81b 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c | |||
@@ -305,6 +305,10 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address"); | |||
305 | #define DEV_CONFIG_CDC | 305 | #define DEV_CONFIG_CDC |
306 | #endif | 306 | #endif |
307 | 307 | ||
308 | #ifdef CONFIG_USB_GADGET_AMD5536UDC | ||
309 | #define DEV_CONFIG_CDC | ||
310 | #endif | ||
311 | |||
308 | 312 | ||
309 | /*-------------------------------------------------------------------------*/ | 313 | /*-------------------------------------------------------------------------*/ |
310 | 314 | ||
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h index 53e9139ba388..f7f159c1002b 100644 --- a/drivers/usb/gadget/gadget_chips.h +++ b/drivers/usb/gadget/gadget_chips.h | |||
@@ -17,6 +17,12 @@ | |||
17 | #define gadget_is_net2280(g) 0 | 17 | #define gadget_is_net2280(g) 0 |
18 | #endif | 18 | #endif |
19 | 19 | ||
20 | #ifdef CONFIG_USB_GADGET_AMD5536UDC | ||
21 | #define gadget_is_amd5536udc(g) !strcmp("amd5536udc", (g)->name) | ||
22 | #else | ||
23 | #define gadget_is_amd5536udc(g) 0 | ||
24 | #endif | ||
25 | |||
20 | #ifdef CONFIG_USB_GADGET_DUMMY_HCD | 26 | #ifdef CONFIG_USB_GADGET_DUMMY_HCD |
21 | #define gadget_is_dummy(g) !strcmp("dummy_udc", (g)->name) | 27 | #define gadget_is_dummy(g) !strcmp("dummy_udc", (g)->name) |
22 | #else | 28 | #else |
@@ -202,7 +208,9 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget) | |||
202 | return 0x18; | 208 | return 0x18; |
203 | else if (gadget_is_fsl_usb2(gadget)) | 209 | else if (gadget_is_fsl_usb2(gadget)) |
204 | return 0x19; | 210 | return 0x19; |
205 | else if (gadget_is_m66592(gadget)) | 211 | else if (gadget_is_amd5536udc(gadget)) |
206 | return 0x20; | 212 | return 0x20; |
213 | else if (gadget_is_m66592(gadget)) | ||
214 | return 0x21; | ||
207 | return -ENOENT; | 215 | return -ENOENT; |
208 | } | 216 | } |
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index 0174a322e007..700dda8a9157 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c | |||
@@ -21,26 +21,18 @@ | |||
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/kernel.h> | ||
25 | #include <linux/sched.h> | ||
26 | #include <linux/smp_lock.h> | ||
27 | #include <linux/errno.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/timer.h> | ||
30 | #include <linux/delay.h> | ||
31 | #include <linux/list.h> | ||
32 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
25 | #include <linux/delay.h> | ||
26 | #include <linux/io.h> | ||
33 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
28 | |||
34 | #include <linux/usb/ch9.h> | 29 | #include <linux/usb/ch9.h> |
35 | #include <linux/usb_gadget.h> | 30 | #include <linux/usb_gadget.h> |
36 | 31 | ||
37 | #include <asm/io.h> | ||
38 | #include <asm/irq.h> | ||
39 | #include <asm/system.h> | ||
40 | |||
41 | #include "m66592-udc.h" | 32 | #include "m66592-udc.h" |
42 | 33 | ||
43 | MODULE_DESCRIPTION("M66592 USB gadget driiver"); | 34 | |
35 | MODULE_DESCRIPTION("M66592 USB gadget driver"); | ||
44 | MODULE_LICENSE("GPL"); | 36 | MODULE_LICENSE("GPL"); |
45 | MODULE_AUTHOR("Yoshihiro Shimoda"); | 37 | MODULE_AUTHOR("Yoshihiro Shimoda"); |
46 | 38 | ||
@@ -49,16 +41,21 @@ MODULE_AUTHOR("Yoshihiro Shimoda"); | |||
49 | /* module parameters */ | 41 | /* module parameters */ |
50 | static unsigned short clock = M66592_XTAL24; | 42 | static unsigned short clock = M66592_XTAL24; |
51 | module_param(clock, ushort, 0644); | 43 | module_param(clock, ushort, 0644); |
52 | MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0(default=16384)"); | 44 | MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 " |
45 | "(default=16384)"); | ||
46 | |||
53 | static unsigned short vif = M66592_LDRV; | 47 | static unsigned short vif = M66592_LDRV; |
54 | module_param(vif, ushort, 0644); | 48 | module_param(vif, ushort, 0644); |
55 | MODULE_PARM_DESC(vif, "input VIF: 3.3V=32768, 1.5V=0(default=32768)"); | 49 | MODULE_PARM_DESC(vif, "input VIF: 3.3V=32768, 1.5V=0 (default=32768)"); |
56 | static unsigned short endian = 0; | 50 | |
51 | static unsigned short endian; | ||
57 | module_param(endian, ushort, 0644); | 52 | module_param(endian, ushort, 0644); |
58 | MODULE_PARM_DESC(endian, "data endian: big=256, little=0(default=0)"); | 53 | MODULE_PARM_DESC(endian, "data endian: big=256, little=0 (default=0)"); |
54 | |||
59 | static unsigned short irq_sense = M66592_INTL; | 55 | static unsigned short irq_sense = M66592_INTL; |
60 | module_param(irq_sense, ushort, 0644); | 56 | module_param(irq_sense, ushort, 0644); |
61 | MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=2, falling edge=0(default=2)"); | 57 | MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=2, falling edge=0 " |
58 | "(default=2)"); | ||
62 | 59 | ||
63 | static const char udc_name[] = "m66592_udc"; | 60 | static const char udc_name[] = "m66592_udc"; |
64 | static const char *m66592_ep_name[] = { | 61 | static const char *m66592_ep_name[] = { |
@@ -72,8 +69,8 @@ static int m66592_queue(struct usb_ep *_ep, struct usb_request *_req, | |||
72 | gfp_t gfp_flags); | 69 | gfp_t gfp_flags); |
73 | 70 | ||
74 | static void transfer_complete(struct m66592_ep *ep, | 71 | static void transfer_complete(struct m66592_ep *ep, |
75 | struct m66592_request *req, | 72 | struct m66592_request *req, int status); |
76 | int status); | 73 | |
77 | /*-------------------------------------------------------------------------*/ | 74 | /*-------------------------------------------------------------------------*/ |
78 | static inline u16 get_usb_speed(struct m66592 *m66592) | 75 | static inline u16 get_usb_speed(struct m66592 *m66592) |
79 | { | 76 | { |
@@ -81,25 +78,25 @@ static inline u16 get_usb_speed(struct m66592 *m66592) | |||
81 | } | 78 | } |
82 | 79 | ||
83 | static void enable_pipe_irq(struct m66592 *m66592, u16 pipenum, | 80 | static void enable_pipe_irq(struct m66592 *m66592, u16 pipenum, |
84 | unsigned long reg) | 81 | unsigned long reg) |
85 | { | 82 | { |
86 | u16 tmp; | 83 | u16 tmp; |
87 | 84 | ||
88 | tmp = m66592_read(m66592, M66592_INTENB0); | 85 | tmp = m66592_read(m66592, M66592_INTENB0); |
89 | m66592_bclr(m66592, M66592_BEMPE | M66592_NRDYE | M66592_BRDYE, | 86 | m66592_bclr(m66592, M66592_BEMPE | M66592_NRDYE | M66592_BRDYE, |
90 | M66592_INTENB0); | 87 | M66592_INTENB0); |
91 | m66592_bset(m66592, (1 << pipenum), reg); | 88 | m66592_bset(m66592, (1 << pipenum), reg); |
92 | m66592_write(m66592, tmp, M66592_INTENB0); | 89 | m66592_write(m66592, tmp, M66592_INTENB0); |
93 | } | 90 | } |
94 | 91 | ||
95 | static void disable_pipe_irq(struct m66592 *m66592, u16 pipenum, | 92 | static void disable_pipe_irq(struct m66592 *m66592, u16 pipenum, |
96 | unsigned long reg) | 93 | unsigned long reg) |
97 | { | 94 | { |
98 | u16 tmp; | 95 | u16 tmp; |
99 | 96 | ||
100 | tmp = m66592_read(m66592, M66592_INTENB0); | 97 | tmp = m66592_read(m66592, M66592_INTENB0); |
101 | m66592_bclr(m66592, M66592_BEMPE | M66592_NRDYE | M66592_BRDYE, | 98 | m66592_bclr(m66592, M66592_BEMPE | M66592_NRDYE | M66592_BRDYE, |
102 | M66592_INTENB0); | 99 | M66592_INTENB0); |
103 | m66592_bclr(m66592, (1 << pipenum), reg); | 100 | m66592_bclr(m66592, (1 << pipenum), reg); |
104 | m66592_write(m66592, tmp, M66592_INTENB0); | 101 | m66592_write(m66592, tmp, M66592_INTENB0); |
105 | } | 102 | } |
@@ -108,17 +105,19 @@ static void m66592_usb_connect(struct m66592 *m66592) | |||
108 | { | 105 | { |
109 | m66592_bset(m66592, M66592_CTRE, M66592_INTENB0); | 106 | m66592_bset(m66592, M66592_CTRE, M66592_INTENB0); |
110 | m66592_bset(m66592, M66592_WDST | M66592_RDST | M66592_CMPL, | 107 | m66592_bset(m66592, M66592_WDST | M66592_RDST | M66592_CMPL, |
111 | M66592_INTENB0); | 108 | M66592_INTENB0); |
112 | m66592_bset(m66592, M66592_BEMPE | M66592_BRDYE, M66592_INTENB0); | 109 | m66592_bset(m66592, M66592_BEMPE | M66592_BRDYE, M66592_INTENB0); |
113 | 110 | ||
114 | m66592_bset(m66592, M66592_DPRPU, M66592_SYSCFG); | 111 | m66592_bset(m66592, M66592_DPRPU, M66592_SYSCFG); |
115 | } | 112 | } |
116 | 113 | ||
117 | static void m66592_usb_disconnect(struct m66592 *m66592) | 114 | static void m66592_usb_disconnect(struct m66592 *m66592) |
115 | __releases(m66592->lock) | ||
116 | __acquires(m66592->lock) | ||
118 | { | 117 | { |
119 | m66592_bclr(m66592, M66592_CTRE, M66592_INTENB0); | 118 | m66592_bclr(m66592, M66592_CTRE, M66592_INTENB0); |
120 | m66592_bclr(m66592, M66592_WDST | M66592_RDST | M66592_CMPL, | 119 | m66592_bclr(m66592, M66592_WDST | M66592_RDST | M66592_CMPL, |
121 | M66592_INTENB0); | 120 | M66592_INTENB0); |
122 | m66592_bclr(m66592, M66592_BEMPE | M66592_BRDYE, M66592_INTENB0); | 121 | m66592_bclr(m66592, M66592_BEMPE | M66592_BRDYE, M66592_INTENB0); |
123 | m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG); | 122 | m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG); |
124 | 123 | ||
@@ -148,7 +147,7 @@ static inline u16 control_reg_get_pid(struct m66592 *m66592, u16 pipenum) | |||
148 | } | 147 | } |
149 | 148 | ||
150 | static inline void control_reg_set_pid(struct m66592 *m66592, u16 pipenum, | 149 | static inline void control_reg_set_pid(struct m66592 *m66592, u16 pipenum, |
151 | u16 pid) | 150 | u16 pid) |
152 | { | 151 | { |
153 | unsigned long offset; | 152 | unsigned long offset; |
154 | 153 | ||
@@ -250,7 +249,7 @@ static inline void pipe_change(struct m66592 *m66592, u16 pipenum) | |||
250 | } | 249 | } |
251 | 250 | ||
252 | static int pipe_buffer_setting(struct m66592 *m66592, | 251 | static int pipe_buffer_setting(struct m66592 *m66592, |
253 | struct m66592_pipe_info *info) | 252 | struct m66592_pipe_info *info) |
254 | { | 253 | { |
255 | u16 bufnum = 0, buf_bsize = 0; | 254 | u16 bufnum = 0, buf_bsize = 0; |
256 | u16 pipecfg = 0; | 255 | u16 pipecfg = 0; |
@@ -287,7 +286,7 @@ static int pipe_buffer_setting(struct m66592 *m66592, | |||
287 | } | 286 | } |
288 | if (m66592->bi_bufnum > M66592_MAX_BUFNUM) { | 287 | if (m66592->bi_bufnum > M66592_MAX_BUFNUM) { |
289 | printk(KERN_ERR "m66592 pipe memory is insufficient(%d)\n", | 288 | printk(KERN_ERR "m66592 pipe memory is insufficient(%d)\n", |
290 | m66592->bi_bufnum); | 289 | m66592->bi_bufnum); |
291 | return -ENOMEM; | 290 | return -ENOMEM; |
292 | } | 291 | } |
293 | 292 | ||
@@ -328,7 +327,7 @@ static void pipe_buffer_release(struct m66592 *m66592, | |||
328 | m66592->bulk--; | 327 | m66592->bulk--; |
329 | } else | 328 | } else |
330 | printk(KERN_ERR "ep_release: unexpect pipenum (%d)\n", | 329 | printk(KERN_ERR "ep_release: unexpect pipenum (%d)\n", |
331 | info->pipe); | 330 | info->pipe); |
332 | } | 331 | } |
333 | 332 | ||
334 | static void pipe_initialize(struct m66592_ep *ep) | 333 | static void pipe_initialize(struct m66592_ep *ep) |
@@ -350,8 +349,8 @@ static void pipe_initialize(struct m66592_ep *ep) | |||
350 | } | 349 | } |
351 | 350 | ||
352 | static void m66592_ep_setting(struct m66592 *m66592, struct m66592_ep *ep, | 351 | static void m66592_ep_setting(struct m66592 *m66592, struct m66592_ep *ep, |
353 | const struct usb_endpoint_descriptor *desc, | 352 | const struct usb_endpoint_descriptor *desc, |
354 | u16 pipenum, int dma) | 353 | u16 pipenum, int dma) |
355 | { | 354 | { |
356 | if ((pipenum != 0) && dma) { | 355 | if ((pipenum != 0) && dma) { |
357 | if (m66592->num_dma == 0) { | 356 | if (m66592->num_dma == 0) { |
@@ -385,7 +384,7 @@ static void m66592_ep_setting(struct m66592 *m66592, struct m66592_ep *ep, | |||
385 | 384 | ||
386 | ep->pipectr = get_pipectr_addr(pipenum); | 385 | ep->pipectr = get_pipectr_addr(pipenum); |
387 | ep->pipenum = pipenum; | 386 | ep->pipenum = pipenum; |
388 | ep->ep.maxpacket = desc->wMaxPacketSize; | 387 | ep->ep.maxpacket = le16_to_cpu(desc->wMaxPacketSize); |
389 | m66592->pipenum2ep[pipenum] = ep; | 388 | m66592->pipenum2ep[pipenum] = ep; |
390 | m66592->epaddr2ep[desc->bEndpointAddress&USB_ENDPOINT_NUMBER_MASK] = ep; | 389 | m66592->epaddr2ep[desc->bEndpointAddress&USB_ENDPOINT_NUMBER_MASK] = ep; |
391 | INIT_LIST_HEAD(&ep->queue); | 390 | INIT_LIST_HEAD(&ep->queue); |
@@ -407,7 +406,7 @@ static void m66592_ep_release(struct m66592_ep *ep) | |||
407 | } | 406 | } |
408 | 407 | ||
409 | static int alloc_pipe_config(struct m66592_ep *ep, | 408 | static int alloc_pipe_config(struct m66592_ep *ep, |
410 | const struct usb_endpoint_descriptor *desc) | 409 | const struct usb_endpoint_descriptor *desc) |
411 | { | 410 | { |
412 | struct m66592 *m66592 = ep->m66592; | 411 | struct m66592 *m66592 = ep->m66592; |
413 | struct m66592_pipe_info info; | 412 | struct m66592_pipe_info info; |
@@ -419,15 +418,15 @@ static int alloc_pipe_config(struct m66592_ep *ep, | |||
419 | 418 | ||
420 | BUG_ON(ep->pipenum); | 419 | BUG_ON(ep->pipenum); |
421 | 420 | ||
422 | switch(desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { | 421 | switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { |
423 | case USB_ENDPOINT_XFER_BULK: | 422 | case USB_ENDPOINT_XFER_BULK: |
424 | if (m66592->bulk >= M66592_MAX_NUM_BULK) { | 423 | if (m66592->bulk >= M66592_MAX_NUM_BULK) { |
425 | if (m66592->isochronous >= M66592_MAX_NUM_ISOC) { | 424 | if (m66592->isochronous >= M66592_MAX_NUM_ISOC) { |
426 | printk(KERN_ERR "bulk pipe is insufficient\n"); | 425 | printk(KERN_ERR "bulk pipe is insufficient\n"); |
427 | return -ENODEV; | 426 | return -ENODEV; |
428 | } else { | 427 | } else { |
429 | info.pipe = M66592_BASE_PIPENUM_ISOC + | 428 | info.pipe = M66592_BASE_PIPENUM_ISOC |
430 | m66592->isochronous; | 429 | + m66592->isochronous; |
431 | counter = &m66592->isochronous; | 430 | counter = &m66592->isochronous; |
432 | } | 431 | } |
433 | } else { | 432 | } else { |
@@ -462,7 +461,7 @@ static int alloc_pipe_config(struct m66592_ep *ep, | |||
462 | ep->type = info.type; | 461 | ep->type = info.type; |
463 | 462 | ||
464 | info.epnum = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; | 463 | info.epnum = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; |
465 | info.maxpacket = desc->wMaxPacketSize; | 464 | info.maxpacket = le16_to_cpu(desc->wMaxPacketSize); |
466 | info.interval = desc->bInterval; | 465 | info.interval = desc->bInterval; |
467 | if (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) | 466 | if (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) |
468 | info.dir_in = 1; | 467 | info.dir_in = 1; |
@@ -525,8 +524,8 @@ static void start_ep0_write(struct m66592_ep *ep, struct m66592_request *req) | |||
525 | 524 | ||
526 | pipe_change(m66592, ep->pipenum); | 525 | pipe_change(m66592, ep->pipenum); |
527 | m66592_mdfy(m66592, M66592_ISEL | M66592_PIPE0, | 526 | m66592_mdfy(m66592, M66592_ISEL | M66592_PIPE0, |
528 | (M66592_ISEL | M66592_CURPIPE), | 527 | (M66592_ISEL | M66592_CURPIPE), |
529 | M66592_CFIFOSEL); | 528 | M66592_CFIFOSEL); |
530 | m66592_write(m66592, M66592_BCLR, ep->fifoctr); | 529 | m66592_write(m66592, M66592_BCLR, ep->fifoctr); |
531 | if (req->req.length == 0) { | 530 | if (req->req.length == 0) { |
532 | m66592_bset(m66592, M66592_BVAL, ep->fifoctr); | 531 | m66592_bset(m66592, M66592_BVAL, ep->fifoctr); |
@@ -561,8 +560,8 @@ static void start_packet_read(struct m66592_ep *ep, struct m66592_request *req) | |||
561 | 560 | ||
562 | if (ep->pipenum == 0) { | 561 | if (ep->pipenum == 0) { |
563 | m66592_mdfy(m66592, M66592_PIPE0, | 562 | m66592_mdfy(m66592, M66592_PIPE0, |
564 | (M66592_ISEL | M66592_CURPIPE), | 563 | (M66592_ISEL | M66592_CURPIPE), |
565 | M66592_CFIFOSEL); | 564 | M66592_CFIFOSEL); |
566 | m66592_write(m66592, M66592_BCLR, ep->fifoctr); | 565 | m66592_write(m66592, M66592_BCLR, ep->fifoctr); |
567 | pipe_start(m66592, pipenum); | 566 | pipe_start(m66592, pipenum); |
568 | pipe_irq_enable(m66592, pipenum); | 567 | pipe_irq_enable(m66592, pipenum); |
@@ -572,8 +571,9 @@ static void start_packet_read(struct m66592_ep *ep, struct m66592_request *req) | |||
572 | pipe_change(m66592, pipenum); | 571 | pipe_change(m66592, pipenum); |
573 | m66592_bset(m66592, M66592_TRENB, ep->fifosel); | 572 | m66592_bset(m66592, M66592_TRENB, ep->fifosel); |
574 | m66592_write(m66592, | 573 | m66592_write(m66592, |
575 | (req->req.length + ep->ep.maxpacket - 1) / | 574 | (req->req.length + ep->ep.maxpacket - 1) |
576 | ep->ep.maxpacket, ep->fifotrn); | 575 | / ep->ep.maxpacket, |
576 | ep->fifotrn); | ||
577 | } | 577 | } |
578 | pipe_start(m66592, pipenum); /* trigger once */ | 578 | pipe_start(m66592, pipenum); /* trigger once */ |
579 | pipe_irq_enable(m66592, pipenum); | 579 | pipe_irq_enable(m66592, pipenum); |
@@ -614,7 +614,7 @@ static void start_ep0(struct m66592_ep *ep, struct m66592_request *req) | |||
614 | static void init_controller(struct m66592 *m66592) | 614 | static void init_controller(struct m66592 *m66592) |
615 | { | 615 | { |
616 | m66592_bset(m66592, (vif & M66592_LDRV) | (endian & M66592_BIGEND), | 616 | m66592_bset(m66592, (vif & M66592_LDRV) | (endian & M66592_BIGEND), |
617 | M66592_PINCFG); | 617 | M66592_PINCFG); |
618 | m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */ | 618 | m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */ |
619 | m66592_mdfy(m66592, clock & M66592_XTAL, M66592_XTAL, M66592_SYSCFG); | 619 | m66592_mdfy(m66592, clock & M66592_XTAL, M66592_XTAL, M66592_SYSCFG); |
620 | 620 | ||
@@ -634,7 +634,7 @@ static void init_controller(struct m66592 *m66592) | |||
634 | 634 | ||
635 | m66592_bset(m66592, irq_sense & M66592_INTL, M66592_INTENB1); | 635 | m66592_bset(m66592, irq_sense & M66592_INTL, M66592_INTENB1); |
636 | m66592_write(m66592, M66592_BURST | M66592_CPU_ADR_RD_WR, | 636 | m66592_write(m66592, M66592_BURST | M66592_CPU_ADR_RD_WR, |
637 | M66592_DMA0CFG); | 637 | M66592_DMA0CFG); |
638 | } | 638 | } |
639 | 639 | ||
640 | static void disable_controller(struct m66592 *m66592) | 640 | static void disable_controller(struct m66592 *m66592) |
@@ -659,8 +659,9 @@ static void m66592_start_xclock(struct m66592 *m66592) | |||
659 | 659 | ||
660 | /*-------------------------------------------------------------------------*/ | 660 | /*-------------------------------------------------------------------------*/ |
661 | static void transfer_complete(struct m66592_ep *ep, | 661 | static void transfer_complete(struct m66592_ep *ep, |
662 | struct m66592_request *req, | 662 | struct m66592_request *req, int status) |
663 | int status) | 663 | __releases(m66592->lock) |
664 | __acquires(m66592->lock) | ||
664 | { | 665 | { |
665 | int restart = 0; | 666 | int restart = 0; |
666 | 667 | ||
@@ -680,8 +681,9 @@ static void transfer_complete(struct m66592_ep *ep, | |||
680 | if (!list_empty(&ep->queue)) | 681 | if (!list_empty(&ep->queue)) |
681 | restart = 1; | 682 | restart = 1; |
682 | 683 | ||
683 | if (likely(req->req.complete)) | 684 | spin_unlock(&ep->m66592->lock); |
684 | req->req.complete(&ep->ep, &req->req); | 685 | req->req.complete(&ep->ep, &req->req); |
686 | spin_lock(&ep->m66592->lock); | ||
685 | 687 | ||
686 | if (restart) { | 688 | if (restart) { |
687 | req = list_entry(ep->queue.next, struct m66592_request, queue); | 689 | req = list_entry(ep->queue.next, struct m66592_request, queue); |
@@ -693,7 +695,7 @@ static void transfer_complete(struct m66592_ep *ep, | |||
693 | static void irq_ep0_write(struct m66592_ep *ep, struct m66592_request *req) | 695 | static void irq_ep0_write(struct m66592_ep *ep, struct m66592_request *req) |
694 | { | 696 | { |
695 | int i; | 697 | int i; |
696 | volatile u16 tmp; | 698 | u16 tmp; |
697 | unsigned bufsize; | 699 | unsigned bufsize; |
698 | size_t size; | 700 | size_t size; |
699 | void *buf; | 701 | void *buf; |
@@ -731,8 +733,9 @@ static void irq_ep0_write(struct m66592_ep *ep, struct m66592_request *req) | |||
731 | req->req.actual += size; | 733 | req->req.actual += size; |
732 | 734 | ||
733 | /* check transfer finish */ | 735 | /* check transfer finish */ |
734 | if ((!req->req.zero && (req->req.actual == req->req.length)) || | 736 | if ((!req->req.zero && (req->req.actual == req->req.length)) |
735 | (size % ep->ep.maxpacket) || (size == 0)) { | 737 | || (size % ep->ep.maxpacket) |
738 | || (size == 0)) { | ||
736 | disable_irq_ready(m66592, pipenum); | 739 | disable_irq_ready(m66592, pipenum); |
737 | disable_irq_empty(m66592, pipenum); | 740 | disable_irq_empty(m66592, pipenum); |
738 | } else { | 741 | } else { |
@@ -768,16 +771,19 @@ static void irq_packet_write(struct m66592_ep *ep, struct m66592_request *req) | |||
768 | /* write fifo */ | 771 | /* write fifo */ |
769 | if (req->req.buf) { | 772 | if (req->req.buf) { |
770 | m66592_write_fifo(m66592, ep->fifoaddr, buf, size); | 773 | m66592_write_fifo(m66592, ep->fifoaddr, buf, size); |
771 | if ((size == 0) || ((size % ep->ep.maxpacket) != 0) || | 774 | if ((size == 0) |
772 | ((bufsize != ep->ep.maxpacket) && (bufsize > size))) | 775 | || ((size % ep->ep.maxpacket) != 0) |
776 | || ((bufsize != ep->ep.maxpacket) | ||
777 | && (bufsize > size))) | ||
773 | m66592_bset(m66592, M66592_BVAL, ep->fifoctr); | 778 | m66592_bset(m66592, M66592_BVAL, ep->fifoctr); |
774 | } | 779 | } |
775 | 780 | ||
776 | /* update parameters */ | 781 | /* update parameters */ |
777 | req->req.actual += size; | 782 | req->req.actual += size; |
778 | /* check transfer finish */ | 783 | /* check transfer finish */ |
779 | if ((!req->req.zero && (req->req.actual == req->req.length)) || | 784 | if ((!req->req.zero && (req->req.actual == req->req.length)) |
780 | (size % ep->ep.maxpacket) || (size == 0)) { | 785 | || (size % ep->ep.maxpacket) |
786 | || (size == 0)) { | ||
781 | disable_irq_ready(m66592, pipenum); | 787 | disable_irq_ready(m66592, pipenum); |
782 | enable_irq_empty(m66592, pipenum); | 788 | enable_irq_empty(m66592, pipenum); |
783 | } else { | 789 | } else { |
@@ -821,8 +827,9 @@ static void irq_packet_read(struct m66592_ep *ep, struct m66592_request *req) | |||
821 | req->req.actual += size; | 827 | req->req.actual += size; |
822 | 828 | ||
823 | /* check transfer finish */ | 829 | /* check transfer finish */ |
824 | if ((!req->req.zero && (req->req.actual == req->req.length)) || | 830 | if ((!req->req.zero && (req->req.actual == req->req.length)) |
825 | (size % ep->ep.maxpacket) || (size == 0)) { | 831 | || (size % ep->ep.maxpacket) |
832 | || (size == 0)) { | ||
826 | pipe_stop(m66592, pipenum); | 833 | pipe_stop(m66592, pipenum); |
827 | pipe_irq_disable(m66592, pipenum); | 834 | pipe_irq_disable(m66592, pipenum); |
828 | finish = 1; | 835 | finish = 1; |
@@ -850,7 +857,7 @@ static void irq_pipe_ready(struct m66592 *m66592, u16 status, u16 enb) | |||
850 | if ((status & M66592_BRDY0) && (enb & M66592_BRDY0)) { | 857 | if ((status & M66592_BRDY0) && (enb & M66592_BRDY0)) { |
851 | m66592_write(m66592, ~M66592_BRDY0, M66592_BRDYSTS); | 858 | m66592_write(m66592, ~M66592_BRDY0, M66592_BRDYSTS); |
852 | m66592_mdfy(m66592, M66592_PIPE0, M66592_CURPIPE, | 859 | m66592_mdfy(m66592, M66592_PIPE0, M66592_CURPIPE, |
853 | M66592_CFIFOSEL); | 860 | M66592_CFIFOSEL); |
854 | 861 | ||
855 | ep = &m66592->ep[0]; | 862 | ep = &m66592->ep[0]; |
856 | req = list_entry(ep->queue.next, struct m66592_request, queue); | 863 | req = list_entry(ep->queue.next, struct m66592_request, queue); |
@@ -909,23 +916,26 @@ static void irq_pipe_empty(struct m66592 *m66592, u16 status, u16 enb) | |||
909 | } | 916 | } |
910 | 917 | ||
911 | static void get_status(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) | 918 | static void get_status(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) |
919 | __releases(m66592->lock) | ||
920 | __acquires(m66592->lock) | ||
912 | { | 921 | { |
913 | struct m66592_ep *ep; | 922 | struct m66592_ep *ep; |
914 | u16 pid; | 923 | u16 pid; |
915 | u16 status = 0; | 924 | u16 status = 0; |
925 | u16 w_index = le16_to_cpu(ctrl->wIndex); | ||
916 | 926 | ||
917 | switch (ctrl->bRequestType & USB_RECIP_MASK) { | 927 | switch (ctrl->bRequestType & USB_RECIP_MASK) { |
918 | case USB_RECIP_DEVICE: | 928 | case USB_RECIP_DEVICE: |
919 | status = 1; /* selfpower */ | 929 | status = 1 << USB_DEVICE_SELF_POWERED; |
920 | break; | 930 | break; |
921 | case USB_RECIP_INTERFACE: | 931 | case USB_RECIP_INTERFACE: |
922 | status = 0; | 932 | status = 0; |
923 | break; | 933 | break; |
924 | case USB_RECIP_ENDPOINT: | 934 | case USB_RECIP_ENDPOINT: |
925 | ep = m66592->epaddr2ep[ctrl->wIndex&USB_ENDPOINT_NUMBER_MASK]; | 935 | ep = m66592->epaddr2ep[w_index & USB_ENDPOINT_NUMBER_MASK]; |
926 | pid = control_reg_get_pid(m66592, ep->pipenum); | 936 | pid = control_reg_get_pid(m66592, ep->pipenum); |
927 | if (pid == M66592_PID_STALL) | 937 | if (pid == M66592_PID_STALL) |
928 | status = 1; | 938 | status = 1 << USB_ENDPOINT_HALT; |
929 | else | 939 | else |
930 | status = 0; | 940 | status = 0; |
931 | break; | 941 | break; |
@@ -934,11 +944,13 @@ static void get_status(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) | |||
934 | return; /* exit */ | 944 | return; /* exit */ |
935 | } | 945 | } |
936 | 946 | ||
937 | *m66592->ep0_buf = status; | 947 | m66592->ep0_data = cpu_to_le16(status); |
938 | m66592->ep0_req->buf = m66592->ep0_buf; | 948 | m66592->ep0_req->buf = &m66592->ep0_data; |
939 | m66592->ep0_req->length = 2; | 949 | m66592->ep0_req->length = 2; |
940 | /* AV: what happens if we get called again before that gets through? */ | 950 | /* AV: what happens if we get called again before that gets through? */ |
951 | spin_unlock(&m66592->lock); | ||
941 | m66592_queue(m66592->gadget.ep0, m66592->ep0_req, GFP_KERNEL); | 952 | m66592_queue(m66592->gadget.ep0, m66592->ep0_req, GFP_KERNEL); |
953 | spin_lock(&m66592->lock); | ||
942 | } | 954 | } |
943 | 955 | ||
944 | static void clear_feature(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) | 956 | static void clear_feature(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) |
@@ -953,8 +965,9 @@ static void clear_feature(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) | |||
953 | case USB_RECIP_ENDPOINT: { | 965 | case USB_RECIP_ENDPOINT: { |
954 | struct m66592_ep *ep; | 966 | struct m66592_ep *ep; |
955 | struct m66592_request *req; | 967 | struct m66592_request *req; |
968 | u16 w_index = le16_to_cpu(ctrl->wIndex); | ||
956 | 969 | ||
957 | ep = m66592->epaddr2ep[ctrl->wIndex&USB_ENDPOINT_NUMBER_MASK]; | 970 | ep = m66592->epaddr2ep[w_index & USB_ENDPOINT_NUMBER_MASK]; |
958 | pipe_stop(m66592, ep->pipenum); | 971 | pipe_stop(m66592, ep->pipenum); |
959 | control_reg_sqclr(m66592, ep->pipenum); | 972 | control_reg_sqclr(m66592, ep->pipenum); |
960 | 973 | ||
@@ -989,8 +1002,9 @@ static void set_feature(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) | |||
989 | break; | 1002 | break; |
990 | case USB_RECIP_ENDPOINT: { | 1003 | case USB_RECIP_ENDPOINT: { |
991 | struct m66592_ep *ep; | 1004 | struct m66592_ep *ep; |
1005 | u16 w_index = le16_to_cpu(ctrl->wIndex); | ||
992 | 1006 | ||
993 | ep = m66592->epaddr2ep[ctrl->wIndex&USB_ENDPOINT_NUMBER_MASK]; | 1007 | ep = m66592->epaddr2ep[w_index & USB_ENDPOINT_NUMBER_MASK]; |
994 | pipe_stall(m66592, ep->pipenum); | 1008 | pipe_stall(m66592, ep->pipenum); |
995 | 1009 | ||
996 | control_end(m66592, 1); | 1010 | control_end(m66592, 1); |
@@ -1066,14 +1080,16 @@ static void irq_device_state(struct m66592 *m66592) | |||
1066 | } | 1080 | } |
1067 | if (m66592->old_dvsq == M66592_DS_CNFG && dvsq != M66592_DS_CNFG) | 1081 | if (m66592->old_dvsq == M66592_DS_CNFG && dvsq != M66592_DS_CNFG) |
1068 | m66592_update_usb_speed(m66592); | 1082 | m66592_update_usb_speed(m66592); |
1069 | if ((dvsq == M66592_DS_CNFG || dvsq == M66592_DS_ADDS) && | 1083 | if ((dvsq == M66592_DS_CNFG || dvsq == M66592_DS_ADDS) |
1070 | m66592->gadget.speed == USB_SPEED_UNKNOWN) | 1084 | && m66592->gadget.speed == USB_SPEED_UNKNOWN) |
1071 | m66592_update_usb_speed(m66592); | 1085 | m66592_update_usb_speed(m66592); |
1072 | 1086 | ||
1073 | m66592->old_dvsq = dvsq; | 1087 | m66592->old_dvsq = dvsq; |
1074 | } | 1088 | } |
1075 | 1089 | ||
1076 | static void irq_control_stage(struct m66592 *m66592) | 1090 | static void irq_control_stage(struct m66592 *m66592) |
1091 | __releases(m66592->lock) | ||
1092 | __acquires(m66592->lock) | ||
1077 | { | 1093 | { |
1078 | struct usb_ctrlrequest ctrl; | 1094 | struct usb_ctrlrequest ctrl; |
1079 | u16 ctsq; | 1095 | u16 ctsq; |
@@ -1095,8 +1111,10 @@ static void irq_control_stage(struct m66592 *m66592) | |||
1095 | case M66592_CS_WRDS: | 1111 | case M66592_CS_WRDS: |
1096 | case M66592_CS_WRND: | 1112 | case M66592_CS_WRND: |
1097 | if (setup_packet(m66592, &ctrl)) { | 1113 | if (setup_packet(m66592, &ctrl)) { |
1114 | spin_unlock(&m66592->lock); | ||
1098 | if (m66592->driver->setup(&m66592->gadget, &ctrl) < 0) | 1115 | if (m66592->driver->setup(&m66592->gadget, &ctrl) < 0) |
1099 | pipe_stall(m66592, 0); | 1116 | pipe_stall(m66592, 0); |
1117 | spin_lock(&m66592->lock); | ||
1100 | } | 1118 | } |
1101 | break; | 1119 | break; |
1102 | case M66592_CS_RDSS: | 1120 | case M66592_CS_RDSS: |
@@ -1119,6 +1137,8 @@ static irqreturn_t m66592_irq(int irq, void *_m66592) | |||
1119 | u16 savepipe; | 1137 | u16 savepipe; |
1120 | u16 mask0; | 1138 | u16 mask0; |
1121 | 1139 | ||
1140 | spin_lock(&m66592->lock); | ||
1141 | |||
1122 | intsts0 = m66592_read(m66592, M66592_INTSTS0); | 1142 | intsts0 = m66592_read(m66592, M66592_INTSTS0); |
1123 | intenb0 = m66592_read(m66592, M66592_INTENB0); | 1143 | intenb0 = m66592_read(m66592, M66592_INTENB0); |
1124 | 1144 | ||
@@ -1134,27 +1154,27 @@ static irqreturn_t m66592_irq(int irq, void *_m66592) | |||
1134 | bempenb = m66592_read(m66592, M66592_BEMPENB); | 1154 | bempenb = m66592_read(m66592, M66592_BEMPENB); |
1135 | 1155 | ||
1136 | if (mask0 & M66592_VBINT) { | 1156 | if (mask0 & M66592_VBINT) { |
1137 | m66592_write(m66592, (u16)~M66592_VBINT, | 1157 | m66592_write(m66592, 0xffff & ~M66592_VBINT, |
1138 | M66592_INTSTS0); | 1158 | M66592_INTSTS0); |
1139 | m66592_start_xclock(m66592); | 1159 | m66592_start_xclock(m66592); |
1140 | 1160 | ||
1141 | /* start vbus sampling */ | 1161 | /* start vbus sampling */ |
1142 | m66592->old_vbus = m66592_read(m66592, M66592_INTSTS0) | 1162 | m66592->old_vbus = m66592_read(m66592, M66592_INTSTS0) |
1143 | & M66592_VBSTS; | 1163 | & M66592_VBSTS; |
1144 | m66592->scount = M66592_MAX_SAMPLING; | 1164 | m66592->scount = M66592_MAX_SAMPLING; |
1145 | 1165 | ||
1146 | mod_timer(&m66592->timer, | 1166 | mod_timer(&m66592->timer, |
1147 | jiffies + msecs_to_jiffies(50)); | 1167 | jiffies + msecs_to_jiffies(50)); |
1148 | } | 1168 | } |
1149 | if (intsts0 & M66592_DVSQ) | 1169 | if (intsts0 & M66592_DVSQ) |
1150 | irq_device_state(m66592); | 1170 | irq_device_state(m66592); |
1151 | 1171 | ||
1152 | if ((intsts0 & M66592_BRDY) && (intenb0 & M66592_BRDYE) && | 1172 | if ((intsts0 & M66592_BRDY) && (intenb0 & M66592_BRDYE) |
1153 | (brdysts & brdyenb)) { | 1173 | && (brdysts & brdyenb)) { |
1154 | irq_pipe_ready(m66592, brdysts, brdyenb); | 1174 | irq_pipe_ready(m66592, brdysts, brdyenb); |
1155 | } | 1175 | } |
1156 | if ((intsts0 & M66592_BEMP) && (intenb0 & M66592_BEMPE) && | 1176 | if ((intsts0 & M66592_BEMP) && (intenb0 & M66592_BEMPE) |
1157 | (bempsts & bempenb)) { | 1177 | && (bempsts & bempenb)) { |
1158 | irq_pipe_empty(m66592, bempsts, bempenb); | 1178 | irq_pipe_empty(m66592, bempsts, bempenb); |
1159 | } | 1179 | } |
1160 | 1180 | ||
@@ -1164,6 +1184,7 @@ static irqreturn_t m66592_irq(int irq, void *_m66592) | |||
1164 | 1184 | ||
1165 | m66592_write(m66592, savepipe, M66592_CFIFOSEL); | 1185 | m66592_write(m66592, savepipe, M66592_CFIFOSEL); |
1166 | 1186 | ||
1187 | spin_unlock(&m66592->lock); | ||
1167 | return IRQ_HANDLED; | 1188 | return IRQ_HANDLED; |
1168 | } | 1189 | } |
1169 | 1190 | ||
@@ -1191,13 +1212,13 @@ static void m66592_timer(unsigned long _m66592) | |||
1191 | m66592_usb_disconnect(m66592); | 1212 | m66592_usb_disconnect(m66592); |
1192 | } else { | 1213 | } else { |
1193 | mod_timer(&m66592->timer, | 1214 | mod_timer(&m66592->timer, |
1194 | jiffies + msecs_to_jiffies(50)); | 1215 | jiffies + msecs_to_jiffies(50)); |
1195 | } | 1216 | } |
1196 | } else { | 1217 | } else { |
1197 | m66592->scount = M66592_MAX_SAMPLING; | 1218 | m66592->scount = M66592_MAX_SAMPLING; |
1198 | m66592->old_vbus = tmp; | 1219 | m66592->old_vbus = tmp; |
1199 | mod_timer(&m66592->timer, | 1220 | mod_timer(&m66592->timer, |
1200 | jiffies + msecs_to_jiffies(50)); | 1221 | jiffies + msecs_to_jiffies(50)); |
1201 | } | 1222 | } |
1202 | } | 1223 | } |
1203 | spin_unlock_irqrestore(&m66592->lock, flags); | 1224 | spin_unlock_irqrestore(&m66592->lock, flags); |
@@ -1335,11 +1356,6 @@ out: | |||
1335 | return ret; | 1356 | return ret; |
1336 | } | 1357 | } |
1337 | 1358 | ||
1338 | static int m66592_fifo_status(struct usb_ep *_ep) | ||
1339 | { | ||
1340 | return -EOPNOTSUPP; | ||
1341 | } | ||
1342 | |||
1343 | static void m66592_fifo_flush(struct usb_ep *_ep) | 1359 | static void m66592_fifo_flush(struct usb_ep *_ep) |
1344 | { | 1360 | { |
1345 | struct m66592_ep *ep; | 1361 | struct m66592_ep *ep; |
@@ -1365,7 +1381,6 @@ static struct usb_ep_ops m66592_ep_ops = { | |||
1365 | .dequeue = m66592_dequeue, | 1381 | .dequeue = m66592_dequeue, |
1366 | 1382 | ||
1367 | .set_halt = m66592_set_halt, | 1383 | .set_halt = m66592_set_halt, |
1368 | .fifo_status = m66592_fifo_status, | ||
1369 | .fifo_flush = m66592_fifo_flush, | 1384 | .fifo_flush = m66592_fifo_flush, |
1370 | }; | 1385 | }; |
1371 | 1386 | ||
@@ -1377,11 +1392,10 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
1377 | struct m66592 *m66592 = the_controller; | 1392 | struct m66592 *m66592 = the_controller; |
1378 | int retval; | 1393 | int retval; |
1379 | 1394 | ||
1380 | if (!driver || | 1395 | if (!driver |
1381 | driver->speed != USB_SPEED_HIGH || | 1396 | || driver->speed != USB_SPEED_HIGH |
1382 | !driver->bind || | 1397 | || !driver->bind |
1383 | !driver->unbind || | 1398 | || !driver->setup) |
1384 | !driver->setup) | ||
1385 | return -EINVAL; | 1399 | return -EINVAL; |
1386 | if (!m66592) | 1400 | if (!m66592) |
1387 | return -ENODEV; | 1401 | return -ENODEV; |
@@ -1413,8 +1427,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
1413 | m66592->old_vbus = m66592_read(m66592, | 1427 | m66592->old_vbus = m66592_read(m66592, |
1414 | M66592_INTSTS0) & M66592_VBSTS; | 1428 | M66592_INTSTS0) & M66592_VBSTS; |
1415 | m66592->scount = M66592_MAX_SAMPLING; | 1429 | m66592->scount = M66592_MAX_SAMPLING; |
1416 | mod_timer(&m66592->timer, | 1430 | mod_timer(&m66592->timer, jiffies + msecs_to_jiffies(50)); |
1417 | jiffies + msecs_to_jiffies(50)); | ||
1418 | } | 1431 | } |
1419 | 1432 | ||
1420 | return 0; | 1433 | return 0; |
@@ -1432,6 +1445,9 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
1432 | struct m66592 *m66592 = the_controller; | 1445 | struct m66592 *m66592 = the_controller; |
1433 | unsigned long flags; | 1446 | unsigned long flags; |
1434 | 1447 | ||
1448 | if (driver != m66592->driver || !driver->unbind) | ||
1449 | return -EINVAL; | ||
1450 | |||
1435 | spin_lock_irqsave(&m66592->lock, flags); | 1451 | spin_lock_irqsave(&m66592->lock, flags); |
1436 | if (m66592->gadget.speed != USB_SPEED_UNKNOWN) | 1452 | if (m66592->gadget.speed != USB_SPEED_UNKNOWN) |
1437 | m66592_usb_disconnect(m66592); | 1453 | m66592_usb_disconnect(m66592); |
@@ -1461,46 +1477,35 @@ static struct usb_gadget_ops m66592_gadget_ops = { | |||
1461 | .get_frame = m66592_get_frame, | 1477 | .get_frame = m66592_get_frame, |
1462 | }; | 1478 | }; |
1463 | 1479 | ||
1464 | #if defined(CONFIG_PM) | 1480 | static int __exit m66592_remove(struct platform_device *pdev) |
1465 | static int m66592_suspend(struct platform_device *pdev, pm_message_t state) | ||
1466 | { | ||
1467 | pdev->dev.power.power_state = state; | ||
1468 | return 0; | ||
1469 | } | ||
1470 | |||
1471 | static int m66592_resume(struct platform_device *pdev) | ||
1472 | { | ||
1473 | pdev->dev.power.power_state = PMSG_ON; | ||
1474 | return 0; | ||
1475 | } | ||
1476 | #else /* if defined(CONFIG_PM) */ | ||
1477 | #define m66592_suspend NULL | ||
1478 | #define m66592_resume NULL | ||
1479 | #endif | ||
1480 | |||
1481 | static int __init_or_module m66592_remove(struct platform_device *pdev) | ||
1482 | { | 1481 | { |
1483 | struct m66592 *m66592 = dev_get_drvdata(&pdev->dev); | 1482 | struct m66592 *m66592 = dev_get_drvdata(&pdev->dev); |
1484 | 1483 | ||
1485 | del_timer_sync(&m66592->timer); | 1484 | del_timer_sync(&m66592->timer); |
1486 | iounmap(m66592->reg); | 1485 | iounmap(m66592->reg); |
1487 | free_irq(platform_get_irq(pdev, 0), m66592); | 1486 | free_irq(platform_get_irq(pdev, 0), m66592); |
1487 | m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req); | ||
1488 | kfree(m66592); | 1488 | kfree(m66592); |
1489 | return 0; | 1489 | return 0; |
1490 | } | 1490 | } |
1491 | 1491 | ||
1492 | static void nop_completion(struct usb_ep *ep, struct usb_request *r) | ||
1493 | { | ||
1494 | } | ||
1495 | |||
1492 | #define resource_len(r) (((r)->end - (r)->start) + 1) | 1496 | #define resource_len(r) (((r)->end - (r)->start) + 1) |
1497 | |||
1493 | static int __init m66592_probe(struct platform_device *pdev) | 1498 | static int __init m66592_probe(struct platform_device *pdev) |
1494 | { | 1499 | { |
1495 | struct resource *res = NULL; | 1500 | struct resource *res; |
1496 | int irq = -1; | 1501 | int irq; |
1497 | void __iomem *reg = NULL; | 1502 | void __iomem *reg = NULL; |
1498 | struct m66592 *m66592 = NULL; | 1503 | struct m66592 *m66592 = NULL; |
1499 | int ret = 0; | 1504 | int ret = 0; |
1500 | int i; | 1505 | int i; |
1501 | 1506 | ||
1502 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | 1507 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, |
1503 | (char *)udc_name); | 1508 | (char *)udc_name); |
1504 | if (!res) { | 1509 | if (!res) { |
1505 | ret = -ENODEV; | 1510 | ret = -ENODEV; |
1506 | printk(KERN_ERR "platform_get_resource_byname error.\n"); | 1511 | printk(KERN_ERR "platform_get_resource_byname error.\n"); |
@@ -1548,7 +1553,7 @@ static int __init m66592_probe(struct platform_device *pdev) | |||
1548 | m66592->bi_bufnum = M66592_BASE_BUFNUM; | 1553 | m66592->bi_bufnum = M66592_BASE_BUFNUM; |
1549 | 1554 | ||
1550 | ret = request_irq(irq, m66592_irq, IRQF_DISABLED | IRQF_SHARED, | 1555 | ret = request_irq(irq, m66592_irq, IRQF_DISABLED | IRQF_SHARED, |
1551 | udc_name, m66592); | 1556 | udc_name, m66592); |
1552 | if (ret < 0) { | 1557 | if (ret < 0) { |
1553 | printk(KERN_ERR "request_irq error (%d)\n", ret); | 1558 | printk(KERN_ERR "request_irq error (%d)\n", ret); |
1554 | goto clean_up; | 1559 | goto clean_up; |
@@ -1563,7 +1568,7 @@ static int __init m66592_probe(struct platform_device *pdev) | |||
1563 | if (i != 0) { | 1568 | if (i != 0) { |
1564 | INIT_LIST_HEAD(&m66592->ep[i].ep.ep_list); | 1569 | INIT_LIST_HEAD(&m66592->ep[i].ep.ep_list); |
1565 | list_add_tail(&m66592->ep[i].ep.ep_list, | 1570 | list_add_tail(&m66592->ep[i].ep.ep_list, |
1566 | &m66592->gadget.ep_list); | 1571 | &m66592->gadget.ep_list); |
1567 | } | 1572 | } |
1568 | ep->m66592 = m66592; | 1573 | ep->m66592 = m66592; |
1569 | INIT_LIST_HEAD(&ep->queue); | 1574 | INIT_LIST_HEAD(&ep->queue); |
@@ -1583,20 +1588,18 @@ static int __init m66592_probe(struct platform_device *pdev) | |||
1583 | 1588 | ||
1584 | the_controller = m66592; | 1589 | the_controller = m66592; |
1585 | 1590 | ||
1586 | /* AV: leaks */ | ||
1587 | m66592->ep0_req = m66592_alloc_request(&m66592->ep[0].ep, GFP_KERNEL); | 1591 | m66592->ep0_req = m66592_alloc_request(&m66592->ep[0].ep, GFP_KERNEL); |
1588 | if (m66592->ep0_req == NULL) | 1592 | if (m66592->ep0_req == NULL) |
1589 | goto clean_up; | 1593 | goto clean_up2; |
1590 | /* AV: leaks, and do we really need it separately allocated? */ | 1594 | m66592->ep0_req->complete = nop_completion; |
1591 | m66592->ep0_buf = kzalloc(2, GFP_KERNEL); | ||
1592 | if (m66592->ep0_buf == NULL) | ||
1593 | goto clean_up; | ||
1594 | 1595 | ||
1595 | init_controller(m66592); | 1596 | init_controller(m66592); |
1596 | 1597 | ||
1597 | printk("driver %s, %s\n", udc_name, DRIVER_VERSION); | 1598 | dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION); |
1598 | return 0; | 1599 | return 0; |
1599 | 1600 | ||
1601 | clean_up2: | ||
1602 | free_irq(irq, m66592); | ||
1600 | clean_up: | 1603 | clean_up: |
1601 | if (m66592) { | 1604 | if (m66592) { |
1602 | if (m66592->ep0_req) | 1605 | if (m66592->ep0_req) |
@@ -1611,10 +1614,7 @@ clean_up: | |||
1611 | 1614 | ||
1612 | /*-------------------------------------------------------------------------*/ | 1615 | /*-------------------------------------------------------------------------*/ |
1613 | static struct platform_driver m66592_driver = { | 1616 | static struct platform_driver m66592_driver = { |
1614 | .probe = m66592_probe, | 1617 | .remove = __exit_p(m66592_remove), |
1615 | .remove = m66592_remove, | ||
1616 | .suspend = m66592_suspend, | ||
1617 | .resume = m66592_resume, | ||
1618 | .driver = { | 1618 | .driver = { |
1619 | .name = (char *) udc_name, | 1619 | .name = (char *) udc_name, |
1620 | }, | 1620 | }, |
@@ -1622,7 +1622,7 @@ static struct platform_driver m66592_driver = { | |||
1622 | 1622 | ||
1623 | static int __init m66592_udc_init(void) | 1623 | static int __init m66592_udc_init(void) |
1624 | { | 1624 | { |
1625 | return platform_driver_register(&m66592_driver); | 1625 | return platform_driver_probe(&m66592_driver, m66592_probe); |
1626 | } | 1626 | } |
1627 | module_init(m66592_udc_init); | 1627 | module_init(m66592_udc_init); |
1628 | 1628 | ||
@@ -1631,4 +1631,3 @@ static void __exit m66592_udc_cleanup(void) | |||
1631 | platform_driver_unregister(&m66592_driver); | 1631 | platform_driver_unregister(&m66592_driver); |
1632 | } | 1632 | } |
1633 | module_exit(m66592_udc_cleanup); | 1633 | module_exit(m66592_udc_cleanup); |
1634 | |||
diff --git a/drivers/usb/gadget/m66592-udc.h b/drivers/usb/gadget/m66592-udc.h index 26b54f8b8945..bfa0c645f229 100644 --- a/drivers/usb/gadget/m66592-udc.h +++ b/drivers/usb/gadget/m66592-udc.h | |||
@@ -24,73 +24,73 @@ | |||
24 | #define __M66592_UDC_H__ | 24 | #define __M66592_UDC_H__ |
25 | 25 | ||
26 | #define M66592_SYSCFG 0x00 | 26 | #define M66592_SYSCFG 0x00 |
27 | #define M66592_XTAL 0xC000 /* b15-14: Crystal selection */ | 27 | #define M66592_XTAL 0xC000 /* b15-14: Crystal selection */ |
28 | #define M66592_XTAL48 0x8000 /* 48MHz */ | 28 | #define M66592_XTAL48 0x8000 /* 48MHz */ |
29 | #define M66592_XTAL24 0x4000 /* 24MHz */ | 29 | #define M66592_XTAL24 0x4000 /* 24MHz */ |
30 | #define M66592_XTAL12 0x0000 /* 12MHz */ | 30 | #define M66592_XTAL12 0x0000 /* 12MHz */ |
31 | #define M66592_XCKE 0x2000 /* b13: External clock enable */ | 31 | #define M66592_XCKE 0x2000 /* b13: External clock enable */ |
32 | #define M66592_RCKE 0x1000 /* b12: Register clock enable */ | 32 | #define M66592_RCKE 0x1000 /* b12: Register clock enable */ |
33 | #define M66592_PLLC 0x0800 /* b11: PLL control */ | 33 | #define M66592_PLLC 0x0800 /* b11: PLL control */ |
34 | #define M66592_SCKE 0x0400 /* b10: USB clock enable */ | 34 | #define M66592_SCKE 0x0400 /* b10: USB clock enable */ |
35 | #define M66592_ATCKM 0x0100 /* b8: Automatic supply functional enable */ | 35 | #define M66592_ATCKM 0x0100 /* b8: Automatic clock supply */ |
36 | #define M66592_HSE 0x0080 /* b7: Hi-speed enable */ | 36 | #define M66592_HSE 0x0080 /* b7: Hi-speed enable */ |
37 | #define M66592_DCFM 0x0040 /* b6: Controller function select */ | 37 | #define M66592_DCFM 0x0040 /* b6: Controller function select */ |
38 | #define M66592_DMRPD 0x0020 /* b5: D- pull down control */ | 38 | #define M66592_DMRPD 0x0020 /* b5: D- pull down control */ |
39 | #define M66592_DPRPU 0x0010 /* b4: D+ pull up control */ | 39 | #define M66592_DPRPU 0x0010 /* b4: D+ pull up control */ |
40 | #define M66592_FSRPC 0x0004 /* b2: Full-speed receiver enable */ | 40 | #define M66592_FSRPC 0x0004 /* b2: Full-speed receiver enable */ |
41 | #define M66592_PCUT 0x0002 /* b1: Low power sleep enable */ | 41 | #define M66592_PCUT 0x0002 /* b1: Low power sleep enable */ |
42 | #define M66592_USBE 0x0001 /* b0: USB module operation enable */ | 42 | #define M66592_USBE 0x0001 /* b0: USB module operation enable */ |
43 | 43 | ||
44 | #define M66592_SYSSTS 0x02 | 44 | #define M66592_SYSSTS 0x02 |
45 | #define M66592_LNST 0x0003 /* b1-0: D+, D- line status */ | 45 | #define M66592_LNST 0x0003 /* b1-0: D+, D- line status */ |
46 | #define M66592_SE1 0x0003 /* SE1 */ | 46 | #define M66592_SE1 0x0003 /* SE1 */ |
47 | #define M66592_KSTS 0x0002 /* K State */ | 47 | #define M66592_KSTS 0x0002 /* K State */ |
48 | #define M66592_JSTS 0x0001 /* J State */ | 48 | #define M66592_JSTS 0x0001 /* J State */ |
49 | #define M66592_SE0 0x0000 /* SE0 */ | 49 | #define M66592_SE0 0x0000 /* SE0 */ |
50 | 50 | ||
51 | #define M66592_DVSTCTR 0x04 | 51 | #define M66592_DVSTCTR 0x04 |
52 | #define M66592_WKUP 0x0100 /* b8: Remote wakeup */ | 52 | #define M66592_WKUP 0x0100 /* b8: Remote wakeup */ |
53 | #define M66592_RWUPE 0x0080 /* b7: Remote wakeup sense */ | 53 | #define M66592_RWUPE 0x0080 /* b7: Remote wakeup sense */ |
54 | #define M66592_USBRST 0x0040 /* b6: USB reset enable */ | 54 | #define M66592_USBRST 0x0040 /* b6: USB reset enable */ |
55 | #define M66592_RESUME 0x0020 /* b5: Resume enable */ | 55 | #define M66592_RESUME 0x0020 /* b5: Resume enable */ |
56 | #define M66592_UACT 0x0010 /* b4: USB bus enable */ | 56 | #define M66592_UACT 0x0010 /* b4: USB bus enable */ |
57 | #define M66592_RHST 0x0003 /* b1-0: Reset handshake status */ | 57 | #define M66592_RHST 0x0003 /* b1-0: Reset handshake status */ |
58 | #define M66592_HSMODE 0x0003 /* Hi-Speed mode */ | 58 | #define M66592_HSMODE 0x0003 /* Hi-Speed mode */ |
59 | #define M66592_FSMODE 0x0002 /* Full-Speed mode */ | 59 | #define M66592_FSMODE 0x0002 /* Full-Speed mode */ |
60 | #define M66592_HSPROC 0x0001 /* HS handshake is processing */ | 60 | #define M66592_HSPROC 0x0001 /* HS handshake is processing */ |
61 | 61 | ||
62 | #define M66592_TESTMODE 0x06 | 62 | #define M66592_TESTMODE 0x06 |
63 | #define M66592_UTST 0x000F /* b4-0: Test select */ | 63 | #define M66592_UTST 0x000F /* b4-0: Test select */ |
64 | #define M66592_H_TST_PACKET 0x000C /* HOST TEST Packet */ | 64 | #define M66592_H_TST_PACKET 0x000C /* HOST TEST Packet */ |
65 | #define M66592_H_TST_SE0_NAK 0x000B /* HOST TEST SE0 NAK */ | 65 | #define M66592_H_TST_SE0_NAK 0x000B /* HOST TEST SE0 NAK */ |
66 | #define M66592_H_TST_K 0x000A /* HOST TEST K */ | 66 | #define M66592_H_TST_K 0x000A /* HOST TEST K */ |
67 | #define M66592_H_TST_J 0x0009 /* HOST TEST J */ | 67 | #define M66592_H_TST_J 0x0009 /* HOST TEST J */ |
68 | #define M66592_H_TST_NORMAL 0x0000 /* HOST Normal Mode */ | 68 | #define M66592_H_TST_NORMAL 0x0000 /* HOST Normal Mode */ |
69 | #define M66592_P_TST_PACKET 0x0004 /* PERI TEST Packet */ | 69 | #define M66592_P_TST_PACKET 0x0004 /* PERI TEST Packet */ |
70 | #define M66592_P_TST_SE0_NAK 0x0003 /* PERI TEST SE0 NAK */ | 70 | #define M66592_P_TST_SE0_NAK 0x0003 /* PERI TEST SE0 NAK */ |
71 | #define M66592_P_TST_K 0x0002 /* PERI TEST K */ | 71 | #define M66592_P_TST_K 0x0002 /* PERI TEST K */ |
72 | #define M66592_P_TST_J 0x0001 /* PERI TEST J */ | 72 | #define M66592_P_TST_J 0x0001 /* PERI TEST J */ |
73 | #define M66592_P_TST_NORMAL 0x0000 /* PERI Normal Mode */ | 73 | #define M66592_P_TST_NORMAL 0x0000 /* PERI Normal Mode */ |
74 | 74 | ||
75 | #define M66592_PINCFG 0x0A | 75 | #define M66592_PINCFG 0x0A |
76 | #define M66592_LDRV 0x8000 /* b15: Drive Current Adjust */ | 76 | #define M66592_LDRV 0x8000 /* b15: Drive Current Adjust */ |
77 | #define M66592_BIGEND 0x0100 /* b8: Big endian mode */ | 77 | #define M66592_BIGEND 0x0100 /* b8: Big endian mode */ |
78 | 78 | ||
79 | #define M66592_DMA0CFG 0x0C | 79 | #define M66592_DMA0CFG 0x0C |
80 | #define M66592_DMA1CFG 0x0E | 80 | #define M66592_DMA1CFG 0x0E |
81 | #define M66592_DREQA 0x4000 /* b14: Dreq active select */ | 81 | #define M66592_DREQA 0x4000 /* b14: Dreq active select */ |
82 | #define M66592_BURST 0x2000 /* b13: Burst mode */ | 82 | #define M66592_BURST 0x2000 /* b13: Burst mode */ |
83 | #define M66592_DACKA 0x0400 /* b10: Dack active select */ | 83 | #define M66592_DACKA 0x0400 /* b10: Dack active select */ |
84 | #define M66592_DFORM 0x0380 /* b9-7: DMA mode select */ | 84 | #define M66592_DFORM 0x0380 /* b9-7: DMA mode select */ |
85 | #define M66592_CPU_ADR_RD_WR 0x0000 /* Address + RD/WR mode (CPU bus) */ | 85 | #define M66592_CPU_ADR_RD_WR 0x0000 /* Address + RD/WR mode (CPU bus) */ |
86 | #define M66592_CPU_DACK_RD_WR 0x0100 /* DACK + RD/WR mode (CPU bus) */ | 86 | #define M66592_CPU_DACK_RD_WR 0x0100 /* DACK + RD/WR mode (CPU bus) */ |
87 | #define M66592_CPU_DACK_ONLY 0x0180 /* DACK only mode (CPU bus) */ | 87 | #define M66592_CPU_DACK_ONLY 0x0180 /* DACK only mode (CPU bus) */ |
88 | #define M66592_SPLIT_DACK_ONLY 0x0200 /* DACK only mode (SPLIT bus) */ | 88 | #define M66592_SPLIT_DACK_ONLY 0x0200 /* DACK only mode (SPLIT bus) */ |
89 | #define M66592_SPLIT_DACK_DSTB 0x0300 /* DACK + DSTB0 mode (SPLIT bus) */ | 89 | #define M66592_SPLIT_DACK_DSTB 0x0300 /* DACK + DSTB0 mode (SPLIT bus) */ |
90 | #define M66592_DENDA 0x0040 /* b6: Dend active select */ | 90 | #define M66592_DENDA 0x0040 /* b6: Dend active select */ |
91 | #define M66592_PKTM 0x0020 /* b5: Packet mode */ | 91 | #define M66592_PKTM 0x0020 /* b5: Packet mode */ |
92 | #define M66592_DENDE 0x0010 /* b4: Dend enable */ | 92 | #define M66592_DENDE 0x0010 /* b4: Dend enable */ |
93 | #define M66592_OBUS 0x0004 /* b2: OUTbus mode */ | 93 | #define M66592_OBUS 0x0004 /* b2: OUTbus mode */ |
94 | 94 | ||
95 | #define M66592_CFIFO 0x10 | 95 | #define M66592_CFIFO 0x10 |
96 | #define M66592_D0FIFO 0x14 | 96 | #define M66592_D0FIFO 0x14 |
@@ -99,300 +99,300 @@ | |||
99 | #define M66592_CFIFOSEL 0x1E | 99 | #define M66592_CFIFOSEL 0x1E |
100 | #define M66592_D0FIFOSEL 0x24 | 100 | #define M66592_D0FIFOSEL 0x24 |
101 | #define M66592_D1FIFOSEL 0x2A | 101 | #define M66592_D1FIFOSEL 0x2A |
102 | #define M66592_RCNT 0x8000 /* b15: Read count mode */ | 102 | #define M66592_RCNT 0x8000 /* b15: Read count mode */ |
103 | #define M66592_REW 0x4000 /* b14: Buffer rewind */ | 103 | #define M66592_REW 0x4000 /* b14: Buffer rewind */ |
104 | #define M66592_DCLRM 0x2000 /* b13: DMA buffer clear mode */ | 104 | #define M66592_DCLRM 0x2000 /* b13: DMA buffer clear mode */ |
105 | #define M66592_DREQE 0x1000 /* b12: DREQ output enable */ | 105 | #define M66592_DREQE 0x1000 /* b12: DREQ output enable */ |
106 | #define M66592_MBW 0x0400 /* b10: Maximum bit width for FIFO access */ | 106 | #define M66592_MBW 0x0400 /* b10: Maximum bit width for FIFO */ |
107 | #define M66592_MBW_8 0x0000 /* 8bit */ | 107 | #define M66592_MBW_8 0x0000 /* 8bit */ |
108 | #define M66592_MBW_16 0x0400 /* 16bit */ | 108 | #define M66592_MBW_16 0x0400 /* 16bit */ |
109 | #define M66592_TRENB 0x0200 /* b9: Transaction counter enable */ | 109 | #define M66592_TRENB 0x0200 /* b9: Transaction counter enable */ |
110 | #define M66592_TRCLR 0x0100 /* b8: Transaction counter clear */ | 110 | #define M66592_TRCLR 0x0100 /* b8: Transaction counter clear */ |
111 | #define M66592_DEZPM 0x0080 /* b7: Zero-length packet additional mode */ | 111 | #define M66592_DEZPM 0x0080 /* b7: Zero-length packet mode */ |
112 | #define M66592_ISEL 0x0020 /* b5: DCP FIFO port direction select */ | 112 | #define M66592_ISEL 0x0020 /* b5: DCP FIFO port direction select */ |
113 | #define M66592_CURPIPE 0x0007 /* b2-0: PIPE select */ | 113 | #define M66592_CURPIPE 0x0007 /* b2-0: PIPE select */ |
114 | 114 | ||
115 | #define M66592_CFIFOCTR 0x20 | 115 | #define M66592_CFIFOCTR 0x20 |
116 | #define M66592_D0FIFOCTR 0x26 | 116 | #define M66592_D0FIFOCTR 0x26 |
117 | #define M66592_D1FIFOCTR 0x2c | 117 | #define M66592_D1FIFOCTR 0x2c |
118 | #define M66592_BVAL 0x8000 /* b15: Buffer valid flag */ | 118 | #define M66592_BVAL 0x8000 /* b15: Buffer valid flag */ |
119 | #define M66592_BCLR 0x4000 /* b14: Buffer clear */ | 119 | #define M66592_BCLR 0x4000 /* b14: Buffer clear */ |
120 | #define M66592_FRDY 0x2000 /* b13: FIFO ready */ | 120 | #define M66592_FRDY 0x2000 /* b13: FIFO ready */ |
121 | #define M66592_DTLN 0x0FFF /* b11-0: FIFO received data length */ | 121 | #define M66592_DTLN 0x0FFF /* b11-0: FIFO received data length */ |
122 | 122 | ||
123 | #define M66592_CFIFOSIE 0x22 | 123 | #define M66592_CFIFOSIE 0x22 |
124 | #define M66592_TGL 0x8000 /* b15: Buffer toggle */ | 124 | #define M66592_TGL 0x8000 /* b15: Buffer toggle */ |
125 | #define M66592_SCLR 0x4000 /* b14: Buffer clear */ | 125 | #define M66592_SCLR 0x4000 /* b14: Buffer clear */ |
126 | #define M66592_SBUSY 0x2000 /* b13: SIE_FIFO busy */ | 126 | #define M66592_SBUSY 0x2000 /* b13: SIE_FIFO busy */ |
127 | 127 | ||
128 | #define M66592_D0FIFOTRN 0x28 | 128 | #define M66592_D0FIFOTRN 0x28 |
129 | #define M66592_D1FIFOTRN 0x2E | 129 | #define M66592_D1FIFOTRN 0x2E |
130 | #define M66592_TRNCNT 0xFFFF /* b15-0: Transaction counter */ | 130 | #define M66592_TRNCNT 0xFFFF /* b15-0: Transaction counter */ |
131 | 131 | ||
132 | #define M66592_INTENB0 0x30 | 132 | #define M66592_INTENB0 0x30 |
133 | #define M66592_VBSE 0x8000 /* b15: VBUS interrupt */ | 133 | #define M66592_VBSE 0x8000 /* b15: VBUS interrupt */ |
134 | #define M66592_RSME 0x4000 /* b14: Resume interrupt */ | 134 | #define M66592_RSME 0x4000 /* b14: Resume interrupt */ |
135 | #define M66592_SOFE 0x2000 /* b13: Frame update interrupt */ | 135 | #define M66592_SOFE 0x2000 /* b13: Frame update interrupt */ |
136 | #define M66592_DVSE 0x1000 /* b12: Device state transition interrupt */ | 136 | #define M66592_DVSE 0x1000 /* b12: Device state transition interrupt */ |
137 | #define M66592_CTRE 0x0800 /* b11: Control transfer stage transition interrupt */ | 137 | #define M66592_CTRE 0x0800 /* b11: Control transfer stage transition irq */ |
138 | #define M66592_BEMPE 0x0400 /* b10: Buffer empty interrupt */ | 138 | #define M66592_BEMPE 0x0400 /* b10: Buffer empty interrupt */ |
139 | #define M66592_NRDYE 0x0200 /* b9: Buffer not ready interrupt */ | 139 | #define M66592_NRDYE 0x0200 /* b9: Buffer not ready interrupt */ |
140 | #define M66592_BRDYE 0x0100 /* b8: Buffer ready interrupt */ | 140 | #define M66592_BRDYE 0x0100 /* b8: Buffer ready interrupt */ |
141 | #define M66592_URST 0x0080 /* b7: USB reset detected interrupt */ | 141 | #define M66592_URST 0x0080 /* b7: USB reset detected interrupt */ |
142 | #define M66592_SADR 0x0040 /* b6: Set address executed interrupt */ | 142 | #define M66592_SADR 0x0040 /* b6: Set address executed interrupt */ |
143 | #define M66592_SCFG 0x0020 /* b5: Set configuration executed interrupt */ | 143 | #define M66592_SCFG 0x0020 /* b5: Set configuration executed interrupt */ |
144 | #define M66592_SUSP 0x0010 /* b4: Suspend detected interrupt */ | 144 | #define M66592_SUSP 0x0010 /* b4: Suspend detected interrupt */ |
145 | #define M66592_WDST 0x0008 /* b3: Control write data stage completed interrupt */ | 145 | #define M66592_WDST 0x0008 /* b3: Control write data stage completed irq */ |
146 | #define M66592_RDST 0x0004 /* b2: Control read data stage completed interrupt */ | 146 | #define M66592_RDST 0x0004 /* b2: Control read data stage completed irq */ |
147 | #define M66592_CMPL 0x0002 /* b1: Control transfer complete interrupt */ | 147 | #define M66592_CMPL 0x0002 /* b1: Control transfer complete interrupt */ |
148 | #define M66592_SERR 0x0001 /* b0: Sequence error interrupt */ | 148 | #define M66592_SERR 0x0001 /* b0: Sequence error interrupt */ |
149 | 149 | ||
150 | #define M66592_INTENB1 0x32 | 150 | #define M66592_INTENB1 0x32 |
151 | #define M66592_BCHGE 0x4000 /* b14: USB us chenge interrupt */ | 151 | #define M66592_BCHGE 0x4000 /* b14: USB us chenge interrupt */ |
152 | #define M66592_DTCHE 0x1000 /* b12: Detach sense interrupt */ | 152 | #define M66592_DTCHE 0x1000 /* b12: Detach sense interrupt */ |
153 | #define M66592_SIGNE 0x0020 /* b5: SETUP IGNORE interrupt */ | 153 | #define M66592_SIGNE 0x0020 /* b5: SETUP IGNORE interrupt */ |
154 | #define M66592_SACKE 0x0010 /* b4: SETUP ACK interrupt */ | 154 | #define M66592_SACKE 0x0010 /* b4: SETUP ACK interrupt */ |
155 | #define M66592_BRDYM 0x0004 /* b2: BRDY clear timing */ | 155 | #define M66592_BRDYM 0x0004 /* b2: BRDY clear timing */ |
156 | #define M66592_INTL 0x0002 /* b1: Interrupt sense select */ | 156 | #define M66592_INTL 0x0002 /* b1: Interrupt sense select */ |
157 | #define M66592_PCSE 0x0001 /* b0: PCUT enable by CS assert */ | 157 | #define M66592_PCSE 0x0001 /* b0: PCUT enable by CS assert */ |
158 | 158 | ||
159 | #define M66592_BRDYENB 0x36 | 159 | #define M66592_BRDYENB 0x36 |
160 | #define M66592_BRDYSTS 0x46 | 160 | #define M66592_BRDYSTS 0x46 |
161 | #define M66592_BRDY7 0x0080 /* b7: PIPE7 */ | 161 | #define M66592_BRDY7 0x0080 /* b7: PIPE7 */ |
162 | #define M66592_BRDY6 0x0040 /* b6: PIPE6 */ | 162 | #define M66592_BRDY6 0x0040 /* b6: PIPE6 */ |
163 | #define M66592_BRDY5 0x0020 /* b5: PIPE5 */ | 163 | #define M66592_BRDY5 0x0020 /* b5: PIPE5 */ |
164 | #define M66592_BRDY4 0x0010 /* b4: PIPE4 */ | 164 | #define M66592_BRDY4 0x0010 /* b4: PIPE4 */ |
165 | #define M66592_BRDY3 0x0008 /* b3: PIPE3 */ | 165 | #define M66592_BRDY3 0x0008 /* b3: PIPE3 */ |
166 | #define M66592_BRDY2 0x0004 /* b2: PIPE2 */ | 166 | #define M66592_BRDY2 0x0004 /* b2: PIPE2 */ |
167 | #define M66592_BRDY1 0x0002 /* b1: PIPE1 */ | 167 | #define M66592_BRDY1 0x0002 /* b1: PIPE1 */ |
168 | #define M66592_BRDY0 0x0001 /* b1: PIPE0 */ | 168 | #define M66592_BRDY0 0x0001 /* b1: PIPE0 */ |
169 | 169 | ||
170 | #define M66592_NRDYENB 0x38 | 170 | #define M66592_NRDYENB 0x38 |
171 | #define M66592_NRDYSTS 0x48 | 171 | #define M66592_NRDYSTS 0x48 |
172 | #define M66592_NRDY7 0x0080 /* b7: PIPE7 */ | 172 | #define M66592_NRDY7 0x0080 /* b7: PIPE7 */ |
173 | #define M66592_NRDY6 0x0040 /* b6: PIPE6 */ | 173 | #define M66592_NRDY6 0x0040 /* b6: PIPE6 */ |
174 | #define M66592_NRDY5 0x0020 /* b5: PIPE5 */ | 174 | #define M66592_NRDY5 0x0020 /* b5: PIPE5 */ |
175 | #define M66592_NRDY4 0x0010 /* b4: PIPE4 */ | 175 | #define M66592_NRDY4 0x0010 /* b4: PIPE4 */ |
176 | #define M66592_NRDY3 0x0008 /* b3: PIPE3 */ | 176 | #define M66592_NRDY3 0x0008 /* b3: PIPE3 */ |
177 | #define M66592_NRDY2 0x0004 /* b2: PIPE2 */ | 177 | #define M66592_NRDY2 0x0004 /* b2: PIPE2 */ |
178 | #define M66592_NRDY1 0x0002 /* b1: PIPE1 */ | 178 | #define M66592_NRDY1 0x0002 /* b1: PIPE1 */ |
179 | #define M66592_NRDY0 0x0001 /* b1: PIPE0 */ | 179 | #define M66592_NRDY0 0x0001 /* b1: PIPE0 */ |
180 | 180 | ||
181 | #define M66592_BEMPENB 0x3A | 181 | #define M66592_BEMPENB 0x3A |
182 | #define M66592_BEMPSTS 0x4A | 182 | #define M66592_BEMPSTS 0x4A |
183 | #define M66592_BEMP7 0x0080 /* b7: PIPE7 */ | 183 | #define M66592_BEMP7 0x0080 /* b7: PIPE7 */ |
184 | #define M66592_BEMP6 0x0040 /* b6: PIPE6 */ | 184 | #define M66592_BEMP6 0x0040 /* b6: PIPE6 */ |
185 | #define M66592_BEMP5 0x0020 /* b5: PIPE5 */ | 185 | #define M66592_BEMP5 0x0020 /* b5: PIPE5 */ |
186 | #define M66592_BEMP4 0x0010 /* b4: PIPE4 */ | 186 | #define M66592_BEMP4 0x0010 /* b4: PIPE4 */ |
187 | #define M66592_BEMP3 0x0008 /* b3: PIPE3 */ | 187 | #define M66592_BEMP3 0x0008 /* b3: PIPE3 */ |
188 | #define M66592_BEMP2 0x0004 /* b2: PIPE2 */ | 188 | #define M66592_BEMP2 0x0004 /* b2: PIPE2 */ |
189 | #define M66592_BEMP1 0x0002 /* b1: PIPE1 */ | 189 | #define M66592_BEMP1 0x0002 /* b1: PIPE1 */ |
190 | #define M66592_BEMP0 0x0001 /* b0: PIPE0 */ | 190 | #define M66592_BEMP0 0x0001 /* b0: PIPE0 */ |
191 | 191 | ||
192 | #define M66592_SOFCFG 0x3C | 192 | #define M66592_SOFCFG 0x3C |
193 | #define M66592_SOFM 0x000C /* b3-2: SOF palse mode */ | 193 | #define M66592_SOFM 0x000C /* b3-2: SOF palse mode */ |
194 | #define M66592_SOF_125US 0x0008 /* SOF OUT 125us uFrame Signal */ | 194 | #define M66592_SOF_125US 0x0008 /* SOF OUT 125us uFrame Signal */ |
195 | #define M66592_SOF_1MS 0x0004 /* SOF OUT 1ms Frame Signal */ | 195 | #define M66592_SOF_1MS 0x0004 /* SOF OUT 1ms Frame Signal */ |
196 | #define M66592_SOF_DISABLE 0x0000 /* SOF OUT Disable */ | 196 | #define M66592_SOF_DISABLE 0x0000 /* SOF OUT Disable */ |
197 | 197 | ||
198 | #define M66592_INTSTS0 0x40 | 198 | #define M66592_INTSTS0 0x40 |
199 | #define M66592_VBINT 0x8000 /* b15: VBUS interrupt */ | 199 | #define M66592_VBINT 0x8000 /* b15: VBUS interrupt */ |
200 | #define M66592_RESM 0x4000 /* b14: Resume interrupt */ | 200 | #define M66592_RESM 0x4000 /* b14: Resume interrupt */ |
201 | #define M66592_SOFR 0x2000 /* b13: SOF frame update interrupt */ | 201 | #define M66592_SOFR 0x2000 /* b13: SOF frame update interrupt */ |
202 | #define M66592_DVST 0x1000 /* b12: Device state transition interrupt */ | 202 | #define M66592_DVST 0x1000 /* b12: Device state transition */ |
203 | #define M66592_CTRT 0x0800 /* b11: Control transfer stage transition interrupt */ | 203 | #define M66592_CTRT 0x0800 /* b11: Control stage transition */ |
204 | #define M66592_BEMP 0x0400 /* b10: Buffer empty interrupt */ | 204 | #define M66592_BEMP 0x0400 /* b10: Buffer empty interrupt */ |
205 | #define M66592_NRDY 0x0200 /* b9: Buffer not ready interrupt */ | 205 | #define M66592_NRDY 0x0200 /* b9: Buffer not ready interrupt */ |
206 | #define M66592_BRDY 0x0100 /* b8: Buffer ready interrupt */ | 206 | #define M66592_BRDY 0x0100 /* b8: Buffer ready interrupt */ |
207 | #define M66592_VBSTS 0x0080 /* b7: VBUS input port */ | 207 | #define M66592_VBSTS 0x0080 /* b7: VBUS input port */ |
208 | #define M66592_DVSQ 0x0070 /* b6-4: Device state */ | 208 | #define M66592_DVSQ 0x0070 /* b6-4: Device state */ |
209 | #define M66592_DS_SPD_CNFG 0x0070 /* Suspend Configured */ | 209 | #define M66592_DS_SPD_CNFG 0x0070 /* Suspend Configured */ |
210 | #define M66592_DS_SPD_ADDR 0x0060 /* Suspend Address */ | 210 | #define M66592_DS_SPD_ADDR 0x0060 /* Suspend Address */ |
211 | #define M66592_DS_SPD_DFLT 0x0050 /* Suspend Default */ | 211 | #define M66592_DS_SPD_DFLT 0x0050 /* Suspend Default */ |
212 | #define M66592_DS_SPD_POWR 0x0040 /* Suspend Powered */ | 212 | #define M66592_DS_SPD_POWR 0x0040 /* Suspend Powered */ |
213 | #define M66592_DS_SUSP 0x0040 /* Suspend */ | 213 | #define M66592_DS_SUSP 0x0040 /* Suspend */ |
214 | #define M66592_DS_CNFG 0x0030 /* Configured */ | 214 | #define M66592_DS_CNFG 0x0030 /* Configured */ |
215 | #define M66592_DS_ADDS 0x0020 /* Address */ | 215 | #define M66592_DS_ADDS 0x0020 /* Address */ |
216 | #define M66592_DS_DFLT 0x0010 /* Default */ | 216 | #define M66592_DS_DFLT 0x0010 /* Default */ |
217 | #define M66592_DS_POWR 0x0000 /* Powered */ | 217 | #define M66592_DS_POWR 0x0000 /* Powered */ |
218 | #define M66592_DVSQS 0x0030 /* b5-4: Device state */ | 218 | #define M66592_DVSQS 0x0030 /* b5-4: Device state */ |
219 | #define M66592_VALID 0x0008 /* b3: Setup packet detected flag */ | 219 | #define M66592_VALID 0x0008 /* b3: Setup packet detected flag */ |
220 | #define M66592_CTSQ 0x0007 /* b2-0: Control transfer stage */ | 220 | #define M66592_CTSQ 0x0007 /* b2-0: Control transfer stage */ |
221 | #define M66592_CS_SQER 0x0006 /* Sequence error */ | 221 | #define M66592_CS_SQER 0x0006 /* Sequence error */ |
222 | #define M66592_CS_WRND 0x0005 /* Control write nodata status stage */ | 222 | #define M66592_CS_WRND 0x0005 /* Control write nodata status */ |
223 | #define M66592_CS_WRSS 0x0004 /* Control write status stage */ | 223 | #define M66592_CS_WRSS 0x0004 /* Control write status stage */ |
224 | #define M66592_CS_WRDS 0x0003 /* Control write data stage */ | 224 | #define M66592_CS_WRDS 0x0003 /* Control write data stage */ |
225 | #define M66592_CS_RDSS 0x0002 /* Control read status stage */ | 225 | #define M66592_CS_RDSS 0x0002 /* Control read status stage */ |
226 | #define M66592_CS_RDDS 0x0001 /* Control read data stage */ | 226 | #define M66592_CS_RDDS 0x0001 /* Control read data stage */ |
227 | #define M66592_CS_IDST 0x0000 /* Idle or setup stage */ | 227 | #define M66592_CS_IDST 0x0000 /* Idle or setup stage */ |
228 | 228 | ||
229 | #define M66592_INTSTS1 0x42 | 229 | #define M66592_INTSTS1 0x42 |
230 | #define M66592_BCHG 0x4000 /* b14: USB bus chenge interrupt */ | 230 | #define M66592_BCHG 0x4000 /* b14: USB bus chenge interrupt */ |
231 | #define M66592_DTCH 0x1000 /* b12: Detach sense interrupt */ | 231 | #define M66592_DTCH 0x1000 /* b12: Detach sense interrupt */ |
232 | #define M66592_SIGN 0x0020 /* b5: SETUP IGNORE interrupt */ | 232 | #define M66592_SIGN 0x0020 /* b5: SETUP IGNORE interrupt */ |
233 | #define M66592_SACK 0x0010 /* b4: SETUP ACK interrupt */ | 233 | #define M66592_SACK 0x0010 /* b4: SETUP ACK interrupt */ |
234 | 234 | ||
235 | #define M66592_FRMNUM 0x4C | 235 | #define M66592_FRMNUM 0x4C |
236 | #define M66592_OVRN 0x8000 /* b15: Overrun error */ | 236 | #define M66592_OVRN 0x8000 /* b15: Overrun error */ |
237 | #define M66592_CRCE 0x4000 /* b14: Received data error */ | 237 | #define M66592_CRCE 0x4000 /* b14: Received data error */ |
238 | #define M66592_SOFRM 0x0800 /* b11: SOF output mode */ | 238 | #define M66592_SOFRM 0x0800 /* b11: SOF output mode */ |
239 | #define M66592_FRNM 0x07FF /* b10-0: Frame number */ | 239 | #define M66592_FRNM 0x07FF /* b10-0: Frame number */ |
240 | 240 | ||
241 | #define M66592_UFRMNUM 0x4E | 241 | #define M66592_UFRMNUM 0x4E |
242 | #define M66592_UFRNM 0x0007 /* b2-0: Micro frame number */ | 242 | #define M66592_UFRNM 0x0007 /* b2-0: Micro frame number */ |
243 | 243 | ||
244 | #define M66592_RECOVER 0x50 | 244 | #define M66592_RECOVER 0x50 |
245 | #define M66592_STSRECOV 0x0700 /* Status recovery */ | 245 | #define M66592_STSRECOV 0x0700 /* Status recovery */ |
246 | #define M66592_STSR_HI 0x0400 /* FULL(0) or HI(1) Speed */ | 246 | #define M66592_STSR_HI 0x0400 /* FULL(0) or HI(1) Speed */ |
247 | #define M66592_STSR_DEFAULT 0x0100 /* Default state */ | 247 | #define M66592_STSR_DEFAULT 0x0100 /* Default state */ |
248 | #define M66592_STSR_ADDRESS 0x0200 /* Address state */ | 248 | #define M66592_STSR_ADDRESS 0x0200 /* Address state */ |
249 | #define M66592_STSR_CONFIG 0x0300 /* Configured state */ | 249 | #define M66592_STSR_CONFIG 0x0300 /* Configured state */ |
250 | #define M66592_USBADDR 0x007F /* b6-0: USB address */ | 250 | #define M66592_USBADDR 0x007F /* b6-0: USB address */ |
251 | 251 | ||
252 | #define M66592_USBREQ 0x54 | 252 | #define M66592_USBREQ 0x54 |
253 | #define M66592_bRequest 0xFF00 /* b15-8: bRequest */ | 253 | #define M66592_bRequest 0xFF00 /* b15-8: bRequest */ |
254 | #define M66592_GET_STATUS 0x0000 | 254 | #define M66592_GET_STATUS 0x0000 |
255 | #define M66592_CLEAR_FEATURE 0x0100 | 255 | #define M66592_CLEAR_FEATURE 0x0100 |
256 | #define M66592_ReqRESERVED 0x0200 | 256 | #define M66592_ReqRESERVED 0x0200 |
257 | #define M66592_SET_FEATURE 0x0300 | 257 | #define M66592_SET_FEATURE 0x0300 |
258 | #define M66592_ReqRESERVED1 0x0400 | 258 | #define M66592_ReqRESERVED1 0x0400 |
259 | #define M66592_SET_ADDRESS 0x0500 | 259 | #define M66592_SET_ADDRESS 0x0500 |
260 | #define M66592_GET_DESCRIPTOR 0x0600 | 260 | #define M66592_GET_DESCRIPTOR 0x0600 |
261 | #define M66592_SET_DESCRIPTOR 0x0700 | 261 | #define M66592_SET_DESCRIPTOR 0x0700 |
262 | #define M66592_GET_CONFIGURATION 0x0800 | 262 | #define M66592_GET_CONFIGURATION 0x0800 |
263 | #define M66592_SET_CONFIGURATION 0x0900 | 263 | #define M66592_SET_CONFIGURATION 0x0900 |
264 | #define M66592_GET_INTERFACE 0x0A00 | 264 | #define M66592_GET_INTERFACE 0x0A00 |
265 | #define M66592_SET_INTERFACE 0x0B00 | 265 | #define M66592_SET_INTERFACE 0x0B00 |
266 | #define M66592_SYNCH_FRAME 0x0C00 | 266 | #define M66592_SYNCH_FRAME 0x0C00 |
267 | #define M66592_bmRequestType 0x00FF /* b7-0: bmRequestType */ | 267 | #define M66592_bmRequestType 0x00FF /* b7-0: bmRequestType */ |
268 | #define M66592_bmRequestTypeDir 0x0080 /* b7 : Data transfer direction */ | 268 | #define M66592_bmRequestTypeDir 0x0080 /* b7 : Data direction */ |
269 | #define M66592_HOST_TO_DEVICE 0x0000 | 269 | #define M66592_HOST_TO_DEVICE 0x0000 |
270 | #define M66592_DEVICE_TO_HOST 0x0080 | 270 | #define M66592_DEVICE_TO_HOST 0x0080 |
271 | #define M66592_bmRequestTypeType 0x0060 /* b6-5: Type */ | 271 | #define M66592_bmRequestTypeType 0x0060 /* b6-5: Type */ |
272 | #define M66592_STANDARD 0x0000 | 272 | #define M66592_STANDARD 0x0000 |
273 | #define M66592_CLASS 0x0020 | 273 | #define M66592_CLASS 0x0020 |
274 | #define M66592_VENDOR 0x0040 | 274 | #define M66592_VENDOR 0x0040 |
275 | #define M66592_bmRequestTypeRecip 0x001F /* b4-0: Recipient */ | 275 | #define M66592_bmRequestTypeRecip 0x001F /* b4-0: Recipient */ |
276 | #define M66592_DEVICE 0x0000 | 276 | #define M66592_DEVICE 0x0000 |
277 | #define M66592_INTERFACE 0x0001 | 277 | #define M66592_INTERFACE 0x0001 |
278 | #define M66592_ENDPOINT 0x0002 | 278 | #define M66592_ENDPOINT 0x0002 |
279 | 279 | ||
280 | #define M66592_USBVAL 0x56 | 280 | #define M66592_USBVAL 0x56 |
281 | #define M66592_wValue 0xFFFF /* b15-0: wValue */ | 281 | #define M66592_wValue 0xFFFF /* b15-0: wValue */ |
282 | /* Standard Feature Selector */ | 282 | /* Standard Feature Selector */ |
283 | #define M66592_ENDPOINT_HALT 0x0000 | 283 | #define M66592_ENDPOINT_HALT 0x0000 |
284 | #define M66592_DEVICE_REMOTE_WAKEUP 0x0001 | 284 | #define M66592_DEVICE_REMOTE_WAKEUP 0x0001 |
285 | #define M66592_TEST_MODE 0x0002 | 285 | #define M66592_TEST_MODE 0x0002 |
286 | /* Descriptor Types */ | 286 | /* Descriptor Types */ |
287 | #define M66592_DT_TYPE 0xFF00 | 287 | #define M66592_DT_TYPE 0xFF00 |
288 | #define M66592_GET_DT_TYPE(v) (((v) & DT_TYPE) >> 8) | 288 | #define M66592_GET_DT_TYPE(v) (((v) & DT_TYPE) >> 8) |
289 | #define M66592_DT_DEVICE 0x01 | 289 | #define M66592_DT_DEVICE 0x01 |
290 | #define M66592_DT_CONFIGURATION 0x02 | 290 | #define M66592_DT_CONFIGURATION 0x02 |
291 | #define M66592_DT_STRING 0x03 | 291 | #define M66592_DT_STRING 0x03 |
292 | #define M66592_DT_INTERFACE 0x04 | 292 | #define M66592_DT_INTERFACE 0x04 |
293 | #define M66592_DT_ENDPOINT 0x05 | 293 | #define M66592_DT_ENDPOINT 0x05 |
294 | #define M66592_DT_DEVICE_QUALIFIER 0x06 | 294 | #define M66592_DT_DEVICE_QUALIFIER 0x06 |
295 | #define M66592_DT_OTHER_SPEED_CONFIGURATION 0x07 | 295 | #define M66592_DT_OTHER_SPEED_CONFIGURATION 0x07 |
296 | #define M66592_DT_INTERFACE_POWER 0x08 | 296 | #define M66592_DT_INTERFACE_POWER 0x08 |
297 | #define M66592_DT_INDEX 0x00FF | 297 | #define M66592_DT_INDEX 0x00FF |
298 | #define M66592_CONF_NUM 0x00FF | 298 | #define M66592_CONF_NUM 0x00FF |
299 | #define M66592_ALT_SET 0x00FF | 299 | #define M66592_ALT_SET 0x00FF |
300 | 300 | ||
301 | #define M66592_USBINDEX 0x58 | 301 | #define M66592_USBINDEX 0x58 |
302 | #define M66592_wIndex 0xFFFF /* b15-0: wIndex */ | 302 | #define M66592_wIndex 0xFFFF /* b15-0: wIndex */ |
303 | #define M66592_TEST_SELECT 0xFF00 /* b15-b8: Test Mode Selectors */ | 303 | #define M66592_TEST_SELECT 0xFF00 /* b15-b8: Test Mode */ |
304 | #define M66592_TEST_J 0x0100 /* Test_J */ | 304 | #define M66592_TEST_J 0x0100 /* Test_J */ |
305 | #define M66592_TEST_K 0x0200 /* Test_K */ | 305 | #define M66592_TEST_K 0x0200 /* Test_K */ |
306 | #define M66592_TEST_SE0_NAK 0x0300 /* Test_SE0_NAK */ | 306 | #define M66592_TEST_SE0_NAK 0x0300 /* Test_SE0_NAK */ |
307 | #define M66592_TEST_PACKET 0x0400 /* Test_Packet */ | 307 | #define M66592_TEST_PACKET 0x0400 /* Test_Packet */ |
308 | #define M66592_TEST_FORCE_ENABLE 0x0500 /* Test_Force_Enable */ | 308 | #define M66592_TEST_FORCE_ENABLE 0x0500 /* Test_Force_Enable */ |
309 | #define M66592_TEST_STSelectors 0x0600 /* Standard test selectors */ | 309 | #define M66592_TEST_STSelectors 0x0600 /* Standard test selectors */ |
310 | #define M66592_TEST_Reserved 0x4000 /* Reserved */ | 310 | #define M66592_TEST_Reserved 0x4000 /* Reserved */ |
311 | #define M66592_TEST_VSTModes 0xC000 /* Vendor-specific test modes */ | 311 | #define M66592_TEST_VSTModes 0xC000 /* Vendor-specific tests */ |
312 | #define M66592_EP_DIR 0x0080 /* b7: Endpoint Direction */ | 312 | #define M66592_EP_DIR 0x0080 /* b7: Endpoint Direction */ |
313 | #define M66592_EP_DIR_IN 0x0080 | 313 | #define M66592_EP_DIR_IN 0x0080 |
314 | #define M66592_EP_DIR_OUT 0x0000 | 314 | #define M66592_EP_DIR_OUT 0x0000 |
315 | 315 | ||
316 | #define M66592_USBLENG 0x5A | 316 | #define M66592_USBLENG 0x5A |
317 | #define M66592_wLength 0xFFFF /* b15-0: wLength */ | 317 | #define M66592_wLength 0xFFFF /* b15-0: wLength */ |
318 | 318 | ||
319 | #define M66592_DCPCFG 0x5C | 319 | #define M66592_DCPCFG 0x5C |
320 | #define M66592_CNTMD 0x0100 /* b8: Continuous transfer mode select */ | 320 | #define M66592_CNTMD 0x0100 /* b8: Continuous transfer mode */ |
321 | #define M66592_DIR 0x0010 /* b4: Control transfer DIR select */ | 321 | #define M66592_DIR 0x0010 /* b4: Control transfer DIR select */ |
322 | 322 | ||
323 | #define M66592_DCPMAXP 0x5E | 323 | #define M66592_DCPMAXP 0x5E |
324 | #define M66592_DEVSEL 0xC000 /* b15-14: Device address select */ | 324 | #define M66592_DEVSEL 0xC000 /* b15-14: Device address select */ |
325 | #define M66592_DEVICE_0 0x0000 /* Device address 0 */ | 325 | #define M66592_DEVICE_0 0x0000 /* Device address 0 */ |
326 | #define M66592_DEVICE_1 0x4000 /* Device address 1 */ | 326 | #define M66592_DEVICE_1 0x4000 /* Device address 1 */ |
327 | #define M66592_DEVICE_2 0x8000 /* Device address 2 */ | 327 | #define M66592_DEVICE_2 0x8000 /* Device address 2 */ |
328 | #define M66592_DEVICE_3 0xC000 /* Device address 3 */ | 328 | #define M66592_DEVICE_3 0xC000 /* Device address 3 */ |
329 | #define M66592_MAXP 0x007F /* b6-0: Maxpacket size of default control pipe */ | 329 | #define M66592_MAXP 0x007F /* b6-0: Maxpacket size of ep0 */ |
330 | 330 | ||
331 | #define M66592_DCPCTR 0x60 | 331 | #define M66592_DCPCTR 0x60 |
332 | #define M66592_BSTS 0x8000 /* b15: Buffer status */ | 332 | #define M66592_BSTS 0x8000 /* b15: Buffer status */ |
333 | #define M66592_SUREQ 0x4000 /* b14: Send USB request */ | 333 | #define M66592_SUREQ 0x4000 /* b14: Send USB request */ |
334 | #define M66592_SQCLR 0x0100 /* b8: Sequence toggle bit clear */ | 334 | #define M66592_SQCLR 0x0100 /* b8: Sequence toggle bit clear */ |
335 | #define M66592_SQSET 0x0080 /* b7: Sequence toggle bit set */ | 335 | #define M66592_SQSET 0x0080 /* b7: Sequence toggle bit set */ |
336 | #define M66592_SQMON 0x0040 /* b6: Sequence toggle bit monitor */ | 336 | #define M66592_SQMON 0x0040 /* b6: Sequence toggle bit monitor */ |
337 | #define M66592_CCPL 0x0004 /* b2: Enable control transfer complete */ | 337 | #define M66592_CCPL 0x0004 /* b2: control transfer complete */ |
338 | #define M66592_PID 0x0003 /* b1-0: Response PID */ | 338 | #define M66592_PID 0x0003 /* b1-0: Response PID */ |
339 | #define M66592_PID_STALL 0x0002 /* STALL */ | 339 | #define M66592_PID_STALL 0x0002 /* STALL */ |
340 | #define M66592_PID_BUF 0x0001 /* BUF */ | 340 | #define M66592_PID_BUF 0x0001 /* BUF */ |
341 | #define M66592_PID_NAK 0x0000 /* NAK */ | 341 | #define M66592_PID_NAK 0x0000 /* NAK */ |
342 | 342 | ||
343 | #define M66592_PIPESEL 0x64 | 343 | #define M66592_PIPESEL 0x64 |
344 | #define M66592_PIPENM 0x0007 /* b2-0: Pipe select */ | 344 | #define M66592_PIPENM 0x0007 /* b2-0: Pipe select */ |
345 | #define M66592_PIPE0 0x0000 /* PIPE 0 */ | 345 | #define M66592_PIPE0 0x0000 /* PIPE 0 */ |
346 | #define M66592_PIPE1 0x0001 /* PIPE 1 */ | 346 | #define M66592_PIPE1 0x0001 /* PIPE 1 */ |
347 | #define M66592_PIPE2 0x0002 /* PIPE 2 */ | 347 | #define M66592_PIPE2 0x0002 /* PIPE 2 */ |
348 | #define M66592_PIPE3 0x0003 /* PIPE 3 */ | 348 | #define M66592_PIPE3 0x0003 /* PIPE 3 */ |
349 | #define M66592_PIPE4 0x0004 /* PIPE 4 */ | 349 | #define M66592_PIPE4 0x0004 /* PIPE 4 */ |
350 | #define M66592_PIPE5 0x0005 /* PIPE 5 */ | 350 | #define M66592_PIPE5 0x0005 /* PIPE 5 */ |
351 | #define M66592_PIPE6 0x0006 /* PIPE 6 */ | 351 | #define M66592_PIPE6 0x0006 /* PIPE 6 */ |
352 | #define M66592_PIPE7 0x0007 /* PIPE 7 */ | 352 | #define M66592_PIPE7 0x0007 /* PIPE 7 */ |
353 | 353 | ||
354 | #define M66592_PIPECFG 0x66 | 354 | #define M66592_PIPECFG 0x66 |
355 | #define M66592_TYP 0xC000 /* b15-14: Transfer type */ | 355 | #define M66592_TYP 0xC000 /* b15-14: Transfer type */ |
356 | #define M66592_ISO 0xC000 /* Isochronous */ | 356 | #define M66592_ISO 0xC000 /* Isochronous */ |
357 | #define M66592_INT 0x8000 /* Interrupt */ | 357 | #define M66592_INT 0x8000 /* Interrupt */ |
358 | #define M66592_BULK 0x4000 /* Bulk */ | 358 | #define M66592_BULK 0x4000 /* Bulk */ |
359 | #define M66592_BFRE 0x0400 /* b10: Buffer ready interrupt mode select */ | 359 | #define M66592_BFRE 0x0400 /* b10: Buffer ready interrupt mode */ |
360 | #define M66592_DBLB 0x0200 /* b9: Double buffer mode select */ | 360 | #define M66592_DBLB 0x0200 /* b9: Double buffer mode select */ |
361 | #define M66592_CNTMD 0x0100 /* b8: Continuous transfer mode select */ | 361 | #define M66592_CNTMD 0x0100 /* b8: Continuous transfer mode */ |
362 | #define M66592_SHTNAK 0x0080 /* b7: Transfer end NAK */ | 362 | #define M66592_SHTNAK 0x0080 /* b7: Transfer end NAK */ |
363 | #define M66592_DIR 0x0010 /* b4: Transfer direction select */ | 363 | #define M66592_DIR 0x0010 /* b4: Transfer direction select */ |
364 | #define M66592_DIR_H_OUT 0x0010 /* HOST OUT */ | 364 | #define M66592_DIR_H_OUT 0x0010 /* HOST OUT */ |
365 | #define M66592_DIR_P_IN 0x0010 /* PERI IN */ | 365 | #define M66592_DIR_P_IN 0x0010 /* PERI IN */ |
366 | #define M66592_DIR_H_IN 0x0000 /* HOST IN */ | 366 | #define M66592_DIR_H_IN 0x0000 /* HOST IN */ |
367 | #define M66592_DIR_P_OUT 0x0000 /* PERI OUT */ | 367 | #define M66592_DIR_P_OUT 0x0000 /* PERI OUT */ |
368 | #define M66592_EPNUM 0x000F /* b3-0: Eendpoint number select */ | 368 | #define M66592_EPNUM 0x000F /* b3-0: Eendpoint number select */ |
369 | #define M66592_EP1 0x0001 | 369 | #define M66592_EP1 0x0001 |
370 | #define M66592_EP2 0x0002 | 370 | #define M66592_EP2 0x0002 |
371 | #define M66592_EP3 0x0003 | 371 | #define M66592_EP3 0x0003 |
372 | #define M66592_EP4 0x0004 | 372 | #define M66592_EP4 0x0004 |
373 | #define M66592_EP5 0x0005 | 373 | #define M66592_EP5 0x0005 |
374 | #define M66592_EP6 0x0006 | 374 | #define M66592_EP6 0x0006 |
375 | #define M66592_EP7 0x0007 | 375 | #define M66592_EP7 0x0007 |
376 | #define M66592_EP8 0x0008 | 376 | #define M66592_EP8 0x0008 |
377 | #define M66592_EP9 0x0009 | 377 | #define M66592_EP9 0x0009 |
378 | #define M66592_EP10 0x000A | 378 | #define M66592_EP10 0x000A |
379 | #define M66592_EP11 0x000B | 379 | #define M66592_EP11 0x000B |
380 | #define M66592_EP12 0x000C | 380 | #define M66592_EP12 0x000C |
381 | #define M66592_EP13 0x000D | 381 | #define M66592_EP13 0x000D |
382 | #define M66592_EP14 0x000E | 382 | #define M66592_EP14 0x000E |
383 | #define M66592_EP15 0x000F | 383 | #define M66592_EP15 0x000F |
384 | 384 | ||
385 | #define M66592_PIPEBUF 0x68 | 385 | #define M66592_PIPEBUF 0x68 |
386 | #define M66592_BUFSIZE 0x7C00 /* b14-10: Pipe buffer size */ | 386 | #define M66592_BUFSIZE 0x7C00 /* b14-10: Pipe buffer size */ |
387 | #define M66592_BUF_SIZE(x) ((((x) / 64) - 1) << 10) | 387 | #define M66592_BUF_SIZE(x) ((((x) / 64) - 1) << 10) |
388 | #define M66592_BUFNMB 0x00FF /* b7-0: Pipe buffer number */ | 388 | #define M66592_BUFNMB 0x00FF /* b7-0: Pipe buffer number */ |
389 | 389 | ||
390 | #define M66592_PIPEMAXP 0x6A | 390 | #define M66592_PIPEMAXP 0x6A |
391 | #define M66592_MXPS 0x07FF /* b10-0: Maxpacket size */ | 391 | #define M66592_MXPS 0x07FF /* b10-0: Maxpacket size */ |
392 | 392 | ||
393 | #define M66592_PIPEPERI 0x6C | 393 | #define M66592_PIPEPERI 0x6C |
394 | #define M66592_IFIS 0x1000 /* b12: Isochronous in-buffer flush mode select */ | 394 | #define M66592_IFIS 0x1000 /* b12: ISO in-buffer flush mode */ |
395 | #define M66592_IITV 0x0007 /* b2-0: Isochronous interval */ | 395 | #define M66592_IITV 0x0007 /* b2-0: ISO interval */ |
396 | 396 | ||
397 | #define M66592_PIPE1CTR 0x70 | 397 | #define M66592_PIPE1CTR 0x70 |
398 | #define M66592_PIPE2CTR 0x72 | 398 | #define M66592_PIPE2CTR 0x72 |
@@ -401,19 +401,17 @@ | |||
401 | #define M66592_PIPE5CTR 0x78 | 401 | #define M66592_PIPE5CTR 0x78 |
402 | #define M66592_PIPE6CTR 0x7A | 402 | #define M66592_PIPE6CTR 0x7A |
403 | #define M66592_PIPE7CTR 0x7C | 403 | #define M66592_PIPE7CTR 0x7C |
404 | #define M66592_BSTS 0x8000 /* b15: Buffer status */ | 404 | #define M66592_BSTS 0x8000 /* b15: Buffer status */ |
405 | #define M66592_INBUFM 0x4000 /* b14: IN buffer monitor (Only for PIPE1 to 5) */ | 405 | #define M66592_INBUFM 0x4000 /* b14: IN buffer monitor (PIPE 1-5) */ |
406 | #define M66592_ACLRM 0x0200 /* b9: Out buffer auto clear mode */ | 406 | #define M66592_ACLRM 0x0200 /* b9: Out buffer auto clear mode */ |
407 | #define M66592_SQCLR 0x0100 /* b8: Sequence toggle bit clear */ | 407 | #define M66592_SQCLR 0x0100 /* b8: Sequence toggle bit clear */ |
408 | #define M66592_SQSET 0x0080 /* b7: Sequence toggle bit set */ | 408 | #define M66592_SQSET 0x0080 /* b7: Sequence toggle bit set */ |
409 | #define M66592_SQMON 0x0040 /* b6: Sequence toggle bit monitor */ | 409 | #define M66592_SQMON 0x0040 /* b6: Sequence toggle bit monitor */ |
410 | #define M66592_PID 0x0003 /* b1-0: Response PID */ | 410 | #define M66592_PID 0x0003 /* b1-0: Response PID */ |
411 | 411 | ||
412 | #define M66592_INVALID_REG 0x7E | 412 | #define M66592_INVALID_REG 0x7E |
413 | 413 | ||
414 | 414 | ||
415 | #define __iomem | ||
416 | |||
417 | #define get_pipectr_addr(pipenum) (M66592_PIPE1CTR + (pipenum - 1) * 2) | 415 | #define get_pipectr_addr(pipenum) (M66592_PIPE1CTR + (pipenum - 1) * 2) |
418 | 416 | ||
419 | #define M66592_MAX_SAMPLING 10 | 417 | #define M66592_MAX_SAMPLING 10 |
@@ -449,7 +447,7 @@ struct m66592_ep { | |||
449 | struct m66592 *m66592; | 447 | struct m66592 *m66592; |
450 | 448 | ||
451 | struct list_head queue; | 449 | struct list_head queue; |
452 | unsigned busy:1; | 450 | unsigned busy:1; |
453 | unsigned internal_ccpl:1; /* use only control */ | 451 | unsigned internal_ccpl:1; /* use only control */ |
454 | 452 | ||
455 | /* this member can able to after m66592_enable */ | 453 | /* this member can able to after m66592_enable */ |
@@ -477,7 +475,7 @@ struct m66592 { | |||
477 | struct m66592_ep *epaddr2ep[16]; | 475 | struct m66592_ep *epaddr2ep[16]; |
478 | 476 | ||
479 | struct usb_request *ep0_req; /* for internal request */ | 477 | struct usb_request *ep0_req; /* for internal request */ |
480 | u16 *ep0_buf; /* for internal request */ | 478 | u16 ep0_data; /* for internal request */ |
481 | 479 | ||
482 | struct timer_list timer; | 480 | struct timer_list timer; |
483 | 481 | ||
@@ -527,8 +525,8 @@ static inline u16 m66592_read(struct m66592 *m66592, unsigned long offset) | |||
527 | } | 525 | } |
528 | 526 | ||
529 | static inline void m66592_read_fifo(struct m66592 *m66592, | 527 | static inline void m66592_read_fifo(struct m66592 *m66592, |
530 | unsigned long offset, | 528 | unsigned long offset, |
531 | void *buf, unsigned long len) | 529 | void *buf, unsigned long len) |
532 | { | 530 | { |
533 | unsigned long fifoaddr = (unsigned long)m66592->reg + offset; | 531 | unsigned long fifoaddr = (unsigned long)m66592->reg + offset; |
534 | 532 | ||
@@ -543,8 +541,8 @@ static inline void m66592_write(struct m66592 *m66592, u16 val, | |||
543 | } | 541 | } |
544 | 542 | ||
545 | static inline void m66592_write_fifo(struct m66592 *m66592, | 543 | static inline void m66592_write_fifo(struct m66592 *m66592, |
546 | unsigned long offset, | 544 | unsigned long offset, |
547 | void *buf, unsigned long len) | 545 | void *buf, unsigned long len) |
548 | { | 546 | { |
549 | unsigned long fifoaddr = (unsigned long)m66592->reg + offset; | 547 | unsigned long fifoaddr = (unsigned long)m66592->reg + offset; |
550 | unsigned long odd = len & 0x0001; | 548 | unsigned long odd = len & 0x0001; |
@@ -558,7 +556,7 @@ static inline void m66592_write_fifo(struct m66592 *m66592, | |||
558 | } | 556 | } |
559 | 557 | ||
560 | static inline void m66592_mdfy(struct m66592 *m66592, u16 val, u16 pat, | 558 | static inline void m66592_mdfy(struct m66592 *m66592, u16 val, u16 pat, |
561 | unsigned long offset) | 559 | unsigned long offset) |
562 | { | 560 | { |
563 | u16 tmp; | 561 | u16 tmp; |
564 | tmp = m66592_read(m66592, offset); | 562 | tmp = m66592_read(m66592, offset); |
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index 38138bb9ddb0..9cd98e73dc1d 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/device.h> | 33 | #include <linux/device.h> |
34 | #include <linux/tty.h> | 34 | #include <linux/tty.h> |
35 | #include <linux/tty_flip.h> | 35 | #include <linux/tty_flip.h> |
36 | #include <linux/mutex.h> | ||
36 | 37 | ||
37 | #include <asm/byteorder.h> | 38 | #include <asm/byteorder.h> |
38 | #include <asm/io.h> | 39 | #include <asm/io.h> |
@@ -258,7 +259,7 @@ static const char *EP_IN_NAME; | |||
258 | static const char *EP_OUT_NAME; | 259 | static const char *EP_OUT_NAME; |
259 | static const char *EP_NOTIFY_NAME; | 260 | static const char *EP_NOTIFY_NAME; |
260 | 261 | ||
261 | static struct semaphore gs_open_close_sem[GS_NUM_PORTS]; | 262 | static struct mutex gs_open_close_lock[GS_NUM_PORTS]; |
262 | 263 | ||
263 | static unsigned int read_q_size = GS_DEFAULT_READ_Q_SIZE; | 264 | static unsigned int read_q_size = GS_DEFAULT_READ_Q_SIZE; |
264 | static unsigned int write_q_size = GS_DEFAULT_WRITE_Q_SIZE; | 265 | static unsigned int write_q_size = GS_DEFAULT_WRITE_Q_SIZE; |
@@ -595,7 +596,7 @@ static int __init gs_module_init(void) | |||
595 | tty_set_operations(gs_tty_driver, &gs_tty_ops); | 596 | tty_set_operations(gs_tty_driver, &gs_tty_ops); |
596 | 597 | ||
597 | for (i=0; i < GS_NUM_PORTS; i++) | 598 | for (i=0; i < GS_NUM_PORTS; i++) |
598 | sema_init(&gs_open_close_sem[i], 1); | 599 | mutex_init(&gs_open_close_lock[i]); |
599 | 600 | ||
600 | retval = tty_register_driver(gs_tty_driver); | 601 | retval = tty_register_driver(gs_tty_driver); |
601 | if (retval) { | 602 | if (retval) { |
@@ -635,7 +636,7 @@ static int gs_open(struct tty_struct *tty, struct file *file) | |||
635 | struct gs_port *port; | 636 | struct gs_port *port; |
636 | struct gs_dev *dev; | 637 | struct gs_dev *dev; |
637 | struct gs_buf *buf; | 638 | struct gs_buf *buf; |
638 | struct semaphore *sem; | 639 | struct mutex *mtx; |
639 | int ret; | 640 | int ret; |
640 | 641 | ||
641 | port_num = tty->index; | 642 | port_num = tty->index; |
@@ -656,10 +657,10 @@ static int gs_open(struct tty_struct *tty, struct file *file) | |||
656 | return -ENODEV; | 657 | return -ENODEV; |
657 | } | 658 | } |
658 | 659 | ||
659 | sem = &gs_open_close_sem[port_num]; | 660 | mtx = &gs_open_close_lock[port_num]; |
660 | if (down_interruptible(sem)) { | 661 | if (mutex_lock_interruptible(mtx)) { |
661 | printk(KERN_ERR | 662 | printk(KERN_ERR |
662 | "gs_open: (%d,%p,%p) interrupted waiting for semaphore\n", | 663 | "gs_open: (%d,%p,%p) interrupted waiting for mutex\n", |
663 | port_num, tty, file); | 664 | port_num, tty, file); |
664 | return -ERESTARTSYS; | 665 | return -ERESTARTSYS; |
665 | } | 666 | } |
@@ -754,12 +755,12 @@ static int gs_open(struct tty_struct *tty, struct file *file) | |||
754 | 755 | ||
755 | exit_unlock_port: | 756 | exit_unlock_port: |
756 | spin_unlock_irqrestore(&port->port_lock, flags); | 757 | spin_unlock_irqrestore(&port->port_lock, flags); |
757 | up(sem); | 758 | mutex_unlock(mtx); |
758 | return ret; | 759 | return ret; |
759 | 760 | ||
760 | exit_unlock_dev: | 761 | exit_unlock_dev: |
761 | spin_unlock_irqrestore(&dev->dev_lock, flags); | 762 | spin_unlock_irqrestore(&dev->dev_lock, flags); |
762 | up(sem); | 763 | mutex_unlock(mtx); |
763 | return ret; | 764 | return ret; |
764 | 765 | ||
765 | } | 766 | } |
@@ -781,7 +782,7 @@ exit_unlock_dev: | |||
781 | static void gs_close(struct tty_struct *tty, struct file *file) | 782 | static void gs_close(struct tty_struct *tty, struct file *file) |
782 | { | 783 | { |
783 | struct gs_port *port = tty->driver_data; | 784 | struct gs_port *port = tty->driver_data; |
784 | struct semaphore *sem; | 785 | struct mutex *mtx; |
785 | 786 | ||
786 | if (port == NULL) { | 787 | if (port == NULL) { |
787 | printk(KERN_ERR "gs_close: NULL port pointer\n"); | 788 | printk(KERN_ERR "gs_close: NULL port pointer\n"); |
@@ -790,8 +791,8 @@ static void gs_close(struct tty_struct *tty, struct file *file) | |||
790 | 791 | ||
791 | gs_debug("gs_close: (%d,%p,%p)\n", port->port_num, tty, file); | 792 | gs_debug("gs_close: (%d,%p,%p)\n", port->port_num, tty, file); |
792 | 793 | ||
793 | sem = &gs_open_close_sem[port->port_num]; | 794 | mtx = &gs_open_close_lock[port->port_num]; |
794 | down(sem); | 795 | mutex_lock(mtx); |
795 | 796 | ||
796 | spin_lock_irq(&port->port_lock); | 797 | spin_lock_irq(&port->port_lock); |
797 | 798 | ||
@@ -846,7 +847,7 @@ static void gs_close(struct tty_struct *tty, struct file *file) | |||
846 | 847 | ||
847 | exit: | 848 | exit: |
848 | spin_unlock_irq(&port->port_lock); | 849 | spin_unlock_irq(&port->port_lock); |
849 | up(sem); | 850 | mutex_unlock(mtx); |
850 | } | 851 | } |
851 | 852 | ||
852 | /* | 853 | /* |
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 46873f2534b5..5c851a36de72 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c | |||
@@ -228,7 +228,6 @@ static void preproc_atl_queue(struct isp116x *isp116x) | |||
228 | struct urb, urb_list); | 228 | struct urb, urb_list); |
229 | ptd = &ep->ptd; | 229 | ptd = &ep->ptd; |
230 | len = ep->length; | 230 | len = ep->length; |
231 | spin_lock(&urb->lock); | ||
232 | ep->data = (unsigned char *)urb->transfer_buffer | 231 | ep->data = (unsigned char *)urb->transfer_buffer |
233 | + urb->actual_length; | 232 | + urb->actual_length; |
234 | 233 | ||
@@ -264,7 +263,6 @@ static void preproc_atl_queue(struct isp116x *isp116x) | |||
264 | | PTD_EP(ep->epnum); | 263 | | PTD_EP(ep->epnum); |
265 | ptd->len = PTD_LEN(len) | PTD_DIR(dir); | 264 | ptd->len = PTD_LEN(len) | PTD_DIR(dir); |
266 | ptd->faddr = PTD_FA(usb_pipedevice(urb->pipe)); | 265 | ptd->faddr = PTD_FA(usb_pipedevice(urb->pipe)); |
267 | spin_unlock(&urb->lock); | ||
268 | if (!ep->active) { | 266 | if (!ep->active) { |
269 | ptd->mps |= PTD_LAST_MSK; | 267 | ptd->mps |= PTD_LAST_MSK; |
270 | isp116x->atl_last_dir = dir; | 268 | isp116x->atl_last_dir = dir; |
@@ -275,6 +273,61 @@ static void preproc_atl_queue(struct isp116x *isp116x) | |||
275 | } | 273 | } |
276 | 274 | ||
277 | /* | 275 | /* |
276 | Take done or failed requests out of schedule. Give back | ||
277 | processed urbs. | ||
278 | */ | ||
279 | static void finish_request(struct isp116x *isp116x, struct isp116x_ep *ep, | ||
280 | struct urb *urb) | ||
281 | __releases(isp116x->lock) __acquires(isp116x->lock) | ||
282 | { | ||
283 | unsigned i; | ||
284 | |||
285 | urb->hcpriv = NULL; | ||
286 | ep->error_count = 0; | ||
287 | |||
288 | if (usb_pipecontrol(urb->pipe)) | ||
289 | ep->nextpid = USB_PID_SETUP; | ||
290 | |||
291 | urb_dbg(urb, "Finish"); | ||
292 | |||
293 | spin_unlock(&isp116x->lock); | ||
294 | usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb); | ||
295 | spin_lock(&isp116x->lock); | ||
296 | |||
297 | /* take idle endpoints out of the schedule */ | ||
298 | if (!list_empty(&ep->hep->urb_list)) | ||
299 | return; | ||
300 | |||
301 | /* async deschedule */ | ||
302 | if (!list_empty(&ep->schedule)) { | ||
303 | list_del_init(&ep->schedule); | ||
304 | return; | ||
305 | } | ||
306 | |||
307 | /* periodic deschedule */ | ||
308 | DBG("deschedule qh%d/%p branch %d\n", ep->period, ep, ep->branch); | ||
309 | for (i = ep->branch; i < PERIODIC_SIZE; i += ep->period) { | ||
310 | struct isp116x_ep *temp; | ||
311 | struct isp116x_ep **prev = &isp116x->periodic[i]; | ||
312 | |||
313 | while (*prev && ((temp = *prev) != ep)) | ||
314 | prev = &temp->next; | ||
315 | if (*prev) | ||
316 | *prev = ep->next; | ||
317 | isp116x->load[i] -= ep->load; | ||
318 | } | ||
319 | ep->branch = PERIODIC_SIZE; | ||
320 | isp116x_to_hcd(isp116x)->self.bandwidth_allocated -= | ||
321 | ep->load / ep->period; | ||
322 | |||
323 | /* switch irq type? */ | ||
324 | if (!--isp116x->periodic_count) { | ||
325 | isp116x->irqenb &= ~HCuPINT_SOF; | ||
326 | isp116x->irqenb |= HCuPINT_ATL; | ||
327 | } | ||
328 | } | ||
329 | |||
330 | /* | ||
278 | Analyze transfer results, handle partial transfers and errors | 331 | Analyze transfer results, handle partial transfers and errors |
279 | */ | 332 | */ |
280 | static void postproc_atl_queue(struct isp116x *isp116x) | 333 | static void postproc_atl_queue(struct isp116x *isp116x) |
@@ -284,6 +337,7 @@ static void postproc_atl_queue(struct isp116x *isp116x) | |||
284 | struct usb_device *udev; | 337 | struct usb_device *udev; |
285 | struct ptd *ptd; | 338 | struct ptd *ptd; |
286 | int short_not_ok; | 339 | int short_not_ok; |
340 | int status; | ||
287 | u8 cc; | 341 | u8 cc; |
288 | 342 | ||
289 | for (ep = isp116x->atl_active; ep; ep = ep->active) { | 343 | for (ep = isp116x->atl_active; ep; ep = ep->active) { |
@@ -294,7 +348,7 @@ static void postproc_atl_queue(struct isp116x *isp116x) | |||
294 | ptd = &ep->ptd; | 348 | ptd = &ep->ptd; |
295 | cc = PTD_GET_CC(ptd); | 349 | cc = PTD_GET_CC(ptd); |
296 | short_not_ok = 1; | 350 | short_not_ok = 1; |
297 | spin_lock(&urb->lock); | 351 | status = -EINPROGRESS; |
298 | 352 | ||
299 | /* Data underrun is special. For allowed underrun | 353 | /* Data underrun is special. For allowed underrun |
300 | we clear the error and continue as normal. For | 354 | we clear the error and continue as normal. For |
@@ -302,47 +356,36 @@ static void postproc_atl_queue(struct isp116x *isp116x) | |||
302 | immediately while for control transfer, | 356 | immediately while for control transfer, |
303 | we do a STATUS stage. */ | 357 | we do a STATUS stage. */ |
304 | if (cc == TD_DATAUNDERRUN) { | 358 | if (cc == TD_DATAUNDERRUN) { |
305 | if (!(urb->transfer_flags & URB_SHORT_NOT_OK)) { | 359 | if (!(urb->transfer_flags & URB_SHORT_NOT_OK) || |
306 | DBG("Allowed data underrun\n"); | 360 | usb_pipecontrol(urb->pipe)) { |
361 | DBG("Allowed or control data underrun\n"); | ||
307 | cc = TD_CC_NOERROR; | 362 | cc = TD_CC_NOERROR; |
308 | short_not_ok = 0; | 363 | short_not_ok = 0; |
309 | } else { | 364 | } else { |
310 | ep->error_count = 1; | 365 | ep->error_count = 1; |
311 | if (usb_pipecontrol(urb->pipe)) | 366 | usb_settoggle(udev, ep->epnum, |
312 | ep->nextpid = USB_PID_ACK; | 367 | ep->nextpid == USB_PID_OUT, |
313 | else | 368 | PTD_GET_TOGGLE(ptd)); |
314 | usb_settoggle(udev, ep->epnum, | ||
315 | ep->nextpid == | ||
316 | USB_PID_OUT, | ||
317 | PTD_GET_TOGGLE(ptd)); | ||
318 | urb->actual_length += PTD_GET_COUNT(ptd); | 369 | urb->actual_length += PTD_GET_COUNT(ptd); |
319 | urb->status = cc_to_error[TD_DATAUNDERRUN]; | 370 | status = cc_to_error[TD_DATAUNDERRUN]; |
320 | spin_unlock(&urb->lock); | 371 | goto done; |
321 | continue; | ||
322 | } | 372 | } |
323 | } | 373 | } |
324 | /* Keep underrun error through the STATUS stage */ | ||
325 | if (urb->status == cc_to_error[TD_DATAUNDERRUN]) | ||
326 | cc = TD_DATAUNDERRUN; | ||
327 | 374 | ||
328 | if (cc != TD_CC_NOERROR && cc != TD_NOTACCESSED | 375 | if (cc != TD_CC_NOERROR && cc != TD_NOTACCESSED |
329 | && (++ep->error_count >= 3 || cc == TD_CC_STALL | 376 | && (++ep->error_count >= 3 || cc == TD_CC_STALL |
330 | || cc == TD_DATAOVERRUN)) { | 377 | || cc == TD_DATAOVERRUN)) { |
331 | if (urb->status == -EINPROGRESS) | 378 | status = cc_to_error[cc]; |
332 | urb->status = cc_to_error[cc]; | ||
333 | if (ep->nextpid == USB_PID_ACK) | 379 | if (ep->nextpid == USB_PID_ACK) |
334 | ep->nextpid = 0; | 380 | ep->nextpid = 0; |
335 | spin_unlock(&urb->lock); | 381 | goto done; |
336 | continue; | ||
337 | } | 382 | } |
338 | /* According to usb spec, zero-length Int transfer signals | 383 | /* According to usb spec, zero-length Int transfer signals |
339 | finishing of the urb. Hey, does this apply only | 384 | finishing of the urb. Hey, does this apply only |
340 | for IN endpoints? */ | 385 | for IN endpoints? */ |
341 | if (usb_pipeint(urb->pipe) && !PTD_GET_LEN(ptd)) { | 386 | if (usb_pipeint(urb->pipe) && !PTD_GET_LEN(ptd)) { |
342 | if (urb->status == -EINPROGRESS) | 387 | status = 0; |
343 | urb->status = 0; | 388 | goto done; |
344 | spin_unlock(&urb->lock); | ||
345 | continue; | ||
346 | } | 389 | } |
347 | 390 | ||
348 | /* Relax after previously failed, but later succeeded | 391 | /* Relax after previously failed, but later succeeded |
@@ -381,8 +424,8 @@ static void postproc_atl_queue(struct isp116x *isp116x) | |||
381 | /* All data for this URB is transferred, let's finish */ | 424 | /* All data for this URB is transferred, let's finish */ |
382 | if (usb_pipecontrol(urb->pipe)) | 425 | if (usb_pipecontrol(urb->pipe)) |
383 | ep->nextpid = USB_PID_ACK; | 426 | ep->nextpid = USB_PID_ACK; |
384 | else if (urb->status == -EINPROGRESS) | 427 | else |
385 | urb->status = 0; | 428 | status = 0; |
386 | break; | 429 | break; |
387 | case USB_PID_SETUP: | 430 | case USB_PID_SETUP: |
388 | if (PTD_GET_ACTIVE(ptd) | 431 | if (PTD_GET_ACTIVE(ptd) |
@@ -402,69 +445,27 @@ static void postproc_atl_queue(struct isp116x *isp116x) | |||
402 | if (PTD_GET_ACTIVE(ptd) | 445 | if (PTD_GET_ACTIVE(ptd) |
403 | || (cc != TD_CC_NOERROR && cc < 0x0E)) | 446 | || (cc != TD_CC_NOERROR && cc < 0x0E)) |
404 | break; | 447 | break; |
405 | if (urb->status == -EINPROGRESS) | 448 | if ((urb->transfer_flags & URB_SHORT_NOT_OK) && |
406 | urb->status = 0; | 449 | urb->actual_length < |
450 | urb->transfer_buffer_length) | ||
451 | status = -EREMOTEIO; | ||
452 | else | ||
453 | status = 0; | ||
407 | ep->nextpid = 0; | 454 | ep->nextpid = 0; |
408 | break; | 455 | break; |
409 | default: | 456 | default: |
410 | BUG(); | 457 | BUG(); |
411 | } | 458 | } |
412 | spin_unlock(&urb->lock); | ||
413 | } | ||
414 | } | ||
415 | |||
416 | /* | ||
417 | Take done or failed requests out of schedule. Give back | ||
418 | processed urbs. | ||
419 | */ | ||
420 | static void finish_request(struct isp116x *isp116x, struct isp116x_ep *ep, | ||
421 | struct urb *urb) | ||
422 | __releases(isp116x->lock) __acquires(isp116x->lock) | ||
423 | { | ||
424 | unsigned i; | ||
425 | |||
426 | urb->hcpriv = NULL; | ||
427 | ep->error_count = 0; | ||
428 | |||
429 | if (usb_pipecontrol(urb->pipe)) | ||
430 | ep->nextpid = USB_PID_SETUP; | ||
431 | |||
432 | urb_dbg(urb, "Finish"); | ||
433 | |||
434 | spin_unlock(&isp116x->lock); | ||
435 | usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb); | ||
436 | spin_lock(&isp116x->lock); | ||
437 | |||
438 | /* take idle endpoints out of the schedule */ | ||
439 | if (!list_empty(&ep->hep->urb_list)) | ||
440 | return; | ||
441 | |||
442 | /* async deschedule */ | ||
443 | if (!list_empty(&ep->schedule)) { | ||
444 | list_del_init(&ep->schedule); | ||
445 | return; | ||
446 | } | ||
447 | 459 | ||
448 | /* periodic deschedule */ | 460 | done: |
449 | DBG("deschedule qh%d/%p branch %d\n", ep->period, ep, ep->branch); | 461 | if (status != -EINPROGRESS) { |
450 | for (i = ep->branch; i < PERIODIC_SIZE; i += ep->period) { | 462 | spin_lock(&urb->lock); |
451 | struct isp116x_ep *temp; | 463 | if (urb->status == -EINPROGRESS) |
452 | struct isp116x_ep **prev = &isp116x->periodic[i]; | 464 | urb->status = status; |
453 | 465 | spin_unlock(&urb->lock); | |
454 | while (*prev && ((temp = *prev) != ep)) | 466 | } |
455 | prev = &temp->next; | 467 | if (urb->status != -EINPROGRESS) |
456 | if (*prev) | 468 | finish_request(isp116x, ep, urb); |
457 | *prev = ep->next; | ||
458 | isp116x->load[i] -= ep->load; | ||
459 | } | ||
460 | ep->branch = PERIODIC_SIZE; | ||
461 | isp116x_to_hcd(isp116x)->self.bandwidth_allocated -= | ||
462 | ep->load / ep->period; | ||
463 | |||
464 | /* switch irq type? */ | ||
465 | if (!--isp116x->periodic_count) { | ||
466 | isp116x->irqenb &= ~HCuPINT_SOF; | ||
467 | isp116x->irqenb |= HCuPINT_ATL; | ||
468 | } | 469 | } |
469 | } | 470 | } |
470 | 471 | ||
@@ -570,9 +571,6 @@ static void start_atl_transfers(struct isp116x *isp116x) | |||
570 | */ | 571 | */ |
571 | static void finish_atl_transfers(struct isp116x *isp116x) | 572 | static void finish_atl_transfers(struct isp116x *isp116x) |
572 | { | 573 | { |
573 | struct isp116x_ep *ep; | ||
574 | struct urb *urb; | ||
575 | |||
576 | if (!isp116x->atl_active) | 574 | if (!isp116x->atl_active) |
577 | return; | 575 | return; |
578 | /* Fifo not ready? */ | 576 | /* Fifo not ready? */ |
@@ -582,16 +580,6 @@ static void finish_atl_transfers(struct isp116x *isp116x) | |||
582 | atomic_inc(&isp116x->atl_finishing); | 580 | atomic_inc(&isp116x->atl_finishing); |
583 | unpack_fifo(isp116x); | 581 | unpack_fifo(isp116x); |
584 | postproc_atl_queue(isp116x); | 582 | postproc_atl_queue(isp116x); |
585 | for (ep = isp116x->atl_active; ep; ep = ep->active) { | ||
586 | urb = | ||
587 | container_of(ep->hep->urb_list.next, struct urb, urb_list); | ||
588 | /* USB_PID_ACK check here avoids finishing of | ||
589 | control transfers, for which TD_DATAUNDERRUN | ||
590 | occured, while URB_SHORT_NOT_OK was set */ | ||
591 | if (urb && urb->status != -EINPROGRESS | ||
592 | && ep->nextpid != USB_PID_ACK) | ||
593 | finish_request(isp116x, ep, urb); | ||
594 | } | ||
595 | atomic_dec(&isp116x->atl_finishing); | 583 | atomic_dec(&isp116x->atl_finishing); |
596 | } | 584 | } |
597 | 585 | ||
@@ -821,15 +809,12 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd, | |||
821 | } | 809 | } |
822 | 810 | ||
823 | /* in case of unlink-during-submit */ | 811 | /* in case of unlink-during-submit */ |
824 | spin_lock(&urb->lock); | ||
825 | if (urb->status != -EINPROGRESS) { | 812 | if (urb->status != -EINPROGRESS) { |
826 | spin_unlock(&urb->lock); | ||
827 | finish_request(isp116x, ep, urb); | 813 | finish_request(isp116x, ep, urb); |
828 | ret = 0; | 814 | ret = 0; |
829 | goto fail; | 815 | goto fail; |
830 | } | 816 | } |
831 | urb->hcpriv = hep; | 817 | urb->hcpriv = hep; |
832 | spin_unlock(&urb->lock); | ||
833 | start_atl_transfers(isp116x); | 818 | start_atl_transfers(isp116x); |
834 | 819 | ||
835 | fail: | 820 | fail: |
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index a7a7070c6e2a..d60f1985320c 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c | |||
@@ -35,10 +35,8 @@ | |||
35 | #include <linux/interrupt.h> | 35 | #include <linux/interrupt.h> |
36 | #include <linux/usb.h> | 36 | #include <linux/usb.h> |
37 | #include <linux/platform_device.h> | 37 | #include <linux/platform_device.h> |
38 | 38 | #include <linux/io.h> | |
39 | #include <asm/io.h> | 39 | #include <linux/irq.h> |
40 | #include <asm/irq.h> | ||
41 | #include <asm/system.h> | ||
42 | 40 | ||
43 | #include "../core/hcd.h" | 41 | #include "../core/hcd.h" |
44 | #include "r8a66597.h" | 42 | #include "r8a66597.h" |
@@ -54,16 +52,21 @@ static const char hcd_name[] = "r8a66597_hcd"; | |||
54 | /* module parameters */ | 52 | /* module parameters */ |
55 | static unsigned short clock = XTAL12; | 53 | static unsigned short clock = XTAL12; |
56 | module_param(clock, ushort, 0644); | 54 | module_param(clock, ushort, 0644); |
57 | MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0(default=0)"); | 55 | MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 " |
56 | "(default=0)"); | ||
57 | |||
58 | static unsigned short vif = LDRV; | 58 | static unsigned short vif = LDRV; |
59 | module_param(vif, ushort, 0644); | 59 | module_param(vif, ushort, 0644); |
60 | MODULE_PARM_DESC(vif, "input VIF: 3.3V=32768, 1.5V=0(default=32768)"); | 60 | MODULE_PARM_DESC(vif, "input VIF: 3.3V=32768, 1.5V=0(default=32768)"); |
61 | static unsigned short endian = 0; | 61 | |
62 | static unsigned short endian; | ||
62 | module_param(endian, ushort, 0644); | 63 | module_param(endian, ushort, 0644); |
63 | MODULE_PARM_DESC(endian, "data endian: big=256, little=0(default=0)"); | 64 | MODULE_PARM_DESC(endian, "data endian: big=256, little=0 (default=0)"); |
65 | |||
64 | static unsigned short irq_sense = INTL; | 66 | static unsigned short irq_sense = INTL; |
65 | module_param(irq_sense, ushort, 0644); | 67 | module_param(irq_sense, ushort, 0644); |
66 | MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=32, falling edge=0(default=32)"); | 68 | MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=32, falling edge=0 " |
69 | "(default=32)"); | ||
67 | 70 | ||
68 | static void packet_write(struct r8a66597 *r8a66597, u16 pipenum); | 71 | static void packet_write(struct r8a66597 *r8a66597, u16 pipenum); |
69 | static int r8a66597_get_frame(struct usb_hcd *hcd); | 72 | static int r8a66597_get_frame(struct usb_hcd *hcd); |
@@ -308,7 +311,7 @@ static int make_r8a66597_device(struct r8a66597 *r8a66597, | |||
308 | struct r8a66597_device *dev; | 311 | struct r8a66597_device *dev; |
309 | int usb_address = urb->setup_packet[2]; /* urb->pipe is address 0 */ | 312 | int usb_address = urb->setup_packet[2]; /* urb->pipe is address 0 */ |
310 | 313 | ||
311 | dev = kzalloc(sizeof(struct r8a66597_device), GFP_KERNEL); | 314 | dev = kzalloc(sizeof(struct r8a66597_device), GFP_ATOMIC); |
312 | if (dev == NULL) | 315 | if (dev == NULL) |
313 | return -ENOMEM; | 316 | return -ENOMEM; |
314 | 317 | ||
@@ -611,33 +614,33 @@ static u16 get_empty_pipenum(struct r8a66597 *r8a66597, | |||
611 | u16 array[R8A66597_MAX_NUM_PIPE], i = 0, min; | 614 | u16 array[R8A66597_MAX_NUM_PIPE], i = 0, min; |
612 | 615 | ||
613 | memset(array, 0, sizeof(array)); | 616 | memset(array, 0, sizeof(array)); |
614 | switch(ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { | 617 | switch (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { |
615 | case USB_ENDPOINT_XFER_BULK: | 618 | case USB_ENDPOINT_XFER_BULK: |
616 | if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) | 619 | if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) |
617 | array[i++] = 4; | 620 | array[i++] = 4; |
618 | else { | 621 | else { |
619 | array[i++] = 3; | 622 | array[i++] = 3; |
620 | array[i++] = 5; | 623 | array[i++] = 5; |
621 | } | 624 | } |
622 | break; | 625 | break; |
623 | case USB_ENDPOINT_XFER_INT: | 626 | case USB_ENDPOINT_XFER_INT: |
624 | if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) { | 627 | if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) { |
625 | array[i++] = 6; | 628 | array[i++] = 6; |
626 | array[i++] = 7; | 629 | array[i++] = 7; |
627 | array[i++] = 8; | 630 | array[i++] = 8; |
628 | } else | 631 | } else |
629 | array[i++] = 9; | 632 | array[i++] = 9; |
630 | break; | 633 | break; |
631 | case USB_ENDPOINT_XFER_ISOC: | 634 | case USB_ENDPOINT_XFER_ISOC: |
632 | if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) | 635 | if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) |
633 | array[i++] = 2; | 636 | array[i++] = 2; |
634 | else | 637 | else |
635 | array[i++] = 1; | 638 | array[i++] = 1; |
636 | break; | 639 | break; |
637 | default: | 640 | default: |
638 | err("Illegal type"); | 641 | err("Illegal type"); |
639 | return 0; | 642 | return 0; |
640 | } | 643 | } |
641 | 644 | ||
642 | i = 1; | 645 | i = 1; |
643 | min = array[0]; | 646 | min = array[0]; |
@@ -654,7 +657,7 @@ static u16 get_r8a66597_type(__u8 type) | |||
654 | { | 657 | { |
655 | u16 r8a66597_type; | 658 | u16 r8a66597_type; |
656 | 659 | ||
657 | switch(type) { | 660 | switch (type) { |
658 | case USB_ENDPOINT_XFER_BULK: | 661 | case USB_ENDPOINT_XFER_BULK: |
659 | r8a66597_type = R8A66597_BULK; | 662 | r8a66597_type = R8A66597_BULK; |
660 | break; | 663 | break; |
@@ -874,7 +877,7 @@ static void r8a66597_usb_preconnect(struct r8a66597 *r8a66597, int port) | |||
874 | { | 877 | { |
875 | r8a66597->root_hub[port].port |= (1 << USB_PORT_FEAT_CONNECTION) | 878 | r8a66597->root_hub[port].port |= (1 << USB_PORT_FEAT_CONNECTION) |
876 | | (1 << USB_PORT_FEAT_C_CONNECTION); | 879 | | (1 << USB_PORT_FEAT_C_CONNECTION); |
877 | r8a66597_write(r8a66597, (u16)~DTCH, get_intsts_reg(port)); | 880 | r8a66597_write(r8a66597, ~DTCH, get_intsts_reg(port)); |
878 | r8a66597_bset(r8a66597, DTCHE, get_intenb_reg(port)); | 881 | r8a66597_bset(r8a66597, DTCHE, get_intenb_reg(port)); |
879 | } | 882 | } |
880 | 883 | ||
@@ -917,7 +920,7 @@ static void prepare_setup_packet(struct r8a66597 *r8a66597, | |||
917 | 920 | ||
918 | r8a66597_write(r8a66597, make_devsel(td->address) | td->maxpacket, | 921 | r8a66597_write(r8a66597, make_devsel(td->address) | td->maxpacket, |
919 | DCPMAXP); | 922 | DCPMAXP); |
920 | r8a66597_write(r8a66597, (u16)~(SIGN | SACK), INTSTS1); | 923 | r8a66597_write(r8a66597, ~(SIGN | SACK), INTSTS1); |
921 | 924 | ||
922 | for (i = 0; i < 4; i++) { | 925 | for (i = 0; i < 4; i++) { |
923 | r8a66597_write(r8a66597, p[i], setup_addr); | 926 | r8a66597_write(r8a66597, p[i], setup_addr); |
@@ -948,19 +951,18 @@ static void prepare_packet_read(struct r8a66597 *r8a66597, | |||
948 | pipe_irq_disable(r8a66597, td->pipenum); | 951 | pipe_irq_disable(r8a66597, td->pipenum); |
949 | pipe_setting(r8a66597, td); | 952 | pipe_setting(r8a66597, td); |
950 | pipe_stop(r8a66597, td->pipe); | 953 | pipe_stop(r8a66597, td->pipe); |
951 | r8a66597_write(r8a66597, (u16)~(1 << td->pipenum), | 954 | r8a66597_write(r8a66597, ~(1 << td->pipenum), BRDYSTS); |
952 | BRDYSTS); | ||
953 | 955 | ||
954 | if (td->pipe->pipetre) { | 956 | if (td->pipe->pipetre) { |
955 | r8a66597_write(r8a66597, TRCLR, | 957 | r8a66597_write(r8a66597, TRCLR, |
956 | td->pipe->pipetre); | 958 | td->pipe->pipetre); |
957 | r8a66597_write(r8a66597, | 959 | r8a66597_write(r8a66597, |
958 | (urb->transfer_buffer_length | 960 | (urb->transfer_buffer_length |
959 | + td->maxpacket - 1) | 961 | + td->maxpacket - 1) |
960 | / td->maxpacket, | 962 | / td->maxpacket, |
961 | td->pipe->pipetrn); | 963 | td->pipe->pipetrn); |
962 | r8a66597_bset(r8a66597, TRENB, | 964 | r8a66597_bset(r8a66597, TRENB, |
963 | td->pipe->pipetre); | 965 | td->pipe->pipetre); |
964 | } | 966 | } |
965 | 967 | ||
966 | pipe_start(r8a66597, td->pipe); | 968 | pipe_start(r8a66597, td->pipe); |
@@ -991,7 +993,7 @@ static void prepare_packet_write(struct r8a66597 *r8a66597, | |||
991 | if (td->pipe->pipetre) | 993 | if (td->pipe->pipetre) |
992 | r8a66597_bclr(r8a66597, TRENB, td->pipe->pipetre); | 994 | r8a66597_bclr(r8a66597, TRENB, td->pipe->pipetre); |
993 | } | 995 | } |
994 | r8a66597_write(r8a66597, (u16)~(1 << td->pipenum), BRDYSTS); | 996 | r8a66597_write(r8a66597, ~(1 << td->pipenum), BRDYSTS); |
995 | 997 | ||
996 | fifo_change_from_pipe(r8a66597, td->pipe); | 998 | fifo_change_from_pipe(r8a66597, td->pipe); |
997 | tmp = r8a66597_read(r8a66597, td->pipe->fifoctr); | 999 | tmp = r8a66597_read(r8a66597, td->pipe->fifoctr); |
@@ -1009,21 +1011,21 @@ static void prepare_status_packet(struct r8a66597 *r8a66597, | |||
1009 | struct urb *urb = td->urb; | 1011 | struct urb *urb = td->urb; |
1010 | 1012 | ||
1011 | r8a66597_pipe_toggle(r8a66597, td->pipe, 1); | 1013 | r8a66597_pipe_toggle(r8a66597, td->pipe, 1); |
1014 | pipe_stop(r8a66597, td->pipe); | ||
1012 | 1015 | ||
1013 | if (urb->setup_packet[0] & USB_ENDPOINT_DIR_MASK) { | 1016 | if (urb->setup_packet[0] & USB_ENDPOINT_DIR_MASK) { |
1014 | r8a66597_bset(r8a66597, R8A66597_DIR, DCPCFG); | 1017 | r8a66597_bset(r8a66597, R8A66597_DIR, DCPCFG); |
1015 | r8a66597_mdfy(r8a66597, ISEL, ISEL | CURPIPE, CFIFOSEL); | 1018 | r8a66597_mdfy(r8a66597, ISEL, ISEL | CURPIPE, CFIFOSEL); |
1016 | r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0); | 1019 | r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0); |
1017 | r8a66597_write(r8a66597, BVAL | BCLR, CFIFOCTR); | 1020 | r8a66597_write(r8a66597, ~BEMP0, BEMPSTS); |
1018 | r8a66597_write(r8a66597, (u16)~BEMP0, BEMPSTS); | 1021 | r8a66597_write(r8a66597, BCLR, CFIFOCTR); |
1022 | r8a66597_write(r8a66597, BVAL, CFIFOCTR); | ||
1019 | enable_irq_empty(r8a66597, 0); | 1023 | enable_irq_empty(r8a66597, 0); |
1020 | } else { | 1024 | } else { |
1021 | r8a66597_bclr(r8a66597, R8A66597_DIR, DCPCFG); | 1025 | r8a66597_bclr(r8a66597, R8A66597_DIR, DCPCFG); |
1022 | r8a66597_mdfy(r8a66597, 0, ISEL | CURPIPE, CFIFOSEL); | 1026 | r8a66597_mdfy(r8a66597, 0, ISEL | CURPIPE, CFIFOSEL); |
1023 | r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0); | 1027 | r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0); |
1024 | r8a66597_write(r8a66597, BCLR, CFIFOCTR); | 1028 | r8a66597_write(r8a66597, BCLR, CFIFOCTR); |
1025 | r8a66597_write(r8a66597, (u16)~BRDY0, BRDYSTS); | ||
1026 | r8a66597_write(r8a66597, (u16)~BEMP0, BEMPSTS); | ||
1027 | enable_irq_ready(r8a66597, 0); | 1029 | enable_irq_ready(r8a66597, 0); |
1028 | } | 1030 | } |
1029 | enable_irq_nrdy(r8a66597, 0); | 1031 | enable_irq_nrdy(r8a66597, 0); |
@@ -1269,7 +1271,7 @@ static void packet_write(struct r8a66597 *r8a66597, u16 pipenum) | |||
1269 | 1271 | ||
1270 | /* write fifo */ | 1272 | /* write fifo */ |
1271 | if (pipenum > 0) | 1273 | if (pipenum > 0) |
1272 | r8a66597_write(r8a66597, (u16)~(1 << pipenum), BEMPSTS); | 1274 | r8a66597_write(r8a66597, ~(1 << pipenum), BEMPSTS); |
1273 | if (urb->transfer_buffer) { | 1275 | if (urb->transfer_buffer) { |
1274 | r8a66597_write_fifo(r8a66597, td->pipe->fifoaddr, buf, size); | 1276 | r8a66597_write_fifo(r8a66597, td->pipe->fifoaddr, buf, size); |
1275 | if (!usb_pipebulk(urb->pipe) || td->maxpacket != size) | 1277 | if (!usb_pipebulk(urb->pipe) || td->maxpacket != size) |
@@ -1362,7 +1364,7 @@ static void irq_pipe_ready(struct r8a66597 *r8a66597) | |||
1362 | 1364 | ||
1363 | mask = r8a66597_read(r8a66597, BRDYSTS) | 1365 | mask = r8a66597_read(r8a66597, BRDYSTS) |
1364 | & r8a66597_read(r8a66597, BRDYENB); | 1366 | & r8a66597_read(r8a66597, BRDYENB); |
1365 | r8a66597_write(r8a66597, (u16)~mask, BRDYSTS); | 1367 | r8a66597_write(r8a66597, ~mask, BRDYSTS); |
1366 | if (mask & BRDY0) { | 1368 | if (mask & BRDY0) { |
1367 | td = r8a66597_get_td(r8a66597, 0); | 1369 | td = r8a66597_get_td(r8a66597, 0); |
1368 | if (td && td->type == USB_PID_IN) | 1370 | if (td && td->type == USB_PID_IN) |
@@ -1397,7 +1399,7 @@ static void irq_pipe_empty(struct r8a66597 *r8a66597) | |||
1397 | 1399 | ||
1398 | mask = r8a66597_read(r8a66597, BEMPSTS) | 1400 | mask = r8a66597_read(r8a66597, BEMPSTS) |
1399 | & r8a66597_read(r8a66597, BEMPENB); | 1401 | & r8a66597_read(r8a66597, BEMPENB); |
1400 | r8a66597_write(r8a66597, (u16)~mask, BEMPSTS); | 1402 | r8a66597_write(r8a66597, ~mask, BEMPSTS); |
1401 | if (mask & BEMP0) { | 1403 | if (mask & BEMP0) { |
1402 | cfifo_change(r8a66597, 0); | 1404 | cfifo_change(r8a66597, 0); |
1403 | td = r8a66597_get_td(r8a66597, 0); | 1405 | td = r8a66597_get_td(r8a66597, 0); |
@@ -1434,7 +1436,7 @@ static void irq_pipe_nrdy(struct r8a66597 *r8a66597) | |||
1434 | 1436 | ||
1435 | mask = r8a66597_read(r8a66597, NRDYSTS) | 1437 | mask = r8a66597_read(r8a66597, NRDYSTS) |
1436 | & r8a66597_read(r8a66597, NRDYENB); | 1438 | & r8a66597_read(r8a66597, NRDYENB); |
1437 | r8a66597_write(r8a66597, (u16)~mask, NRDYSTS); | 1439 | r8a66597_write(r8a66597, ~mask, NRDYSTS); |
1438 | if (mask & NRDY0) { | 1440 | if (mask & NRDY0) { |
1439 | cfifo_change(r8a66597, 0); | 1441 | cfifo_change(r8a66597, 0); |
1440 | set_urb_error(r8a66597, 0); | 1442 | set_urb_error(r8a66597, 0); |
@@ -1488,14 +1490,14 @@ static irqreturn_t r8a66597_irq(struct usb_hcd *hcd) | |||
1488 | mask0 = intsts0 & intenb0 & (BEMP | NRDY | BRDY); | 1490 | mask0 = intsts0 & intenb0 & (BEMP | NRDY | BRDY); |
1489 | if (mask2) { | 1491 | if (mask2) { |
1490 | if (mask2 & ATTCH) { | 1492 | if (mask2 & ATTCH) { |
1491 | r8a66597_write(r8a66597, (u16)~ATTCH, INTSTS2); | 1493 | r8a66597_write(r8a66597, ~ATTCH, INTSTS2); |
1492 | r8a66597_bclr(r8a66597, ATTCHE, INTENB2); | 1494 | r8a66597_bclr(r8a66597, ATTCHE, INTENB2); |
1493 | 1495 | ||
1494 | /* start usb bus sampling */ | 1496 | /* start usb bus sampling */ |
1495 | start_root_hub_sampling(r8a66597, 1); | 1497 | start_root_hub_sampling(r8a66597, 1); |
1496 | } | 1498 | } |
1497 | if (mask2 & DTCH) { | 1499 | if (mask2 & DTCH) { |
1498 | r8a66597_write(r8a66597, (u16)~DTCH, INTSTS2); | 1500 | r8a66597_write(r8a66597, ~DTCH, INTSTS2); |
1499 | r8a66597_bclr(r8a66597, DTCHE, INTENB2); | 1501 | r8a66597_bclr(r8a66597, DTCHE, INTENB2); |
1500 | r8a66597_usb_disconnect(r8a66597, 1); | 1502 | r8a66597_usb_disconnect(r8a66597, 1); |
1501 | } | 1503 | } |
@@ -1503,24 +1505,24 @@ static irqreturn_t r8a66597_irq(struct usb_hcd *hcd) | |||
1503 | 1505 | ||
1504 | if (mask1) { | 1506 | if (mask1) { |
1505 | if (mask1 & ATTCH) { | 1507 | if (mask1 & ATTCH) { |
1506 | r8a66597_write(r8a66597, (u16)~ATTCH, INTSTS1); | 1508 | r8a66597_write(r8a66597, ~ATTCH, INTSTS1); |
1507 | r8a66597_bclr(r8a66597, ATTCHE, INTENB1); | 1509 | r8a66597_bclr(r8a66597, ATTCHE, INTENB1); |
1508 | 1510 | ||
1509 | /* start usb bus sampling */ | 1511 | /* start usb bus sampling */ |
1510 | start_root_hub_sampling(r8a66597, 0); | 1512 | start_root_hub_sampling(r8a66597, 0); |
1511 | } | 1513 | } |
1512 | if (mask1 & DTCH) { | 1514 | if (mask1 & DTCH) { |
1513 | r8a66597_write(r8a66597, (u16)~DTCH, INTSTS1); | 1515 | r8a66597_write(r8a66597, ~DTCH, INTSTS1); |
1514 | r8a66597_bclr(r8a66597, DTCHE, INTENB1); | 1516 | r8a66597_bclr(r8a66597, DTCHE, INTENB1); |
1515 | r8a66597_usb_disconnect(r8a66597, 0); | 1517 | r8a66597_usb_disconnect(r8a66597, 0); |
1516 | } | 1518 | } |
1517 | if (mask1 & SIGN) { | 1519 | if (mask1 & SIGN) { |
1518 | r8a66597_write(r8a66597, (u16)~SIGN, INTSTS1); | 1520 | r8a66597_write(r8a66597, ~SIGN, INTSTS1); |
1519 | set_urb_error(r8a66597, 0); | 1521 | set_urb_error(r8a66597, 0); |
1520 | check_next_phase(r8a66597); | 1522 | check_next_phase(r8a66597); |
1521 | } | 1523 | } |
1522 | if (mask1 & SACK) { | 1524 | if (mask1 & SACK) { |
1523 | r8a66597_write(r8a66597, (u16)~SACK, INTSTS1); | 1525 | r8a66597_write(r8a66597, ~SACK, INTSTS1); |
1524 | check_next_phase(r8a66597); | 1526 | check_next_phase(r8a66597); |
1525 | } | 1527 | } |
1526 | } | 1528 | } |
@@ -1663,13 +1665,9 @@ static int check_pipe_config(struct r8a66597 *r8a66597, struct urb *urb) | |||
1663 | static int r8a66597_start(struct usb_hcd *hcd) | 1665 | static int r8a66597_start(struct usb_hcd *hcd) |
1664 | { | 1666 | { |
1665 | struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd); | 1667 | struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd); |
1666 | int ret; | ||
1667 | 1668 | ||
1668 | hcd->state = HC_STATE_RUNNING; | 1669 | hcd->state = HC_STATE_RUNNING; |
1669 | if ((ret = enable_controller(r8a66597)) < 0) | 1670 | return enable_controller(r8a66597); |
1670 | return ret; | ||
1671 | |||
1672 | return 0; | ||
1673 | } | 1671 | } |
1674 | 1672 | ||
1675 | static void r8a66597_stop(struct usb_hcd *hcd) | 1673 | static void r8a66597_stop(struct usb_hcd *hcd) |
@@ -1696,13 +1694,12 @@ static void set_address_zero(struct r8a66597 *r8a66597, struct urb *urb) | |||
1696 | 1694 | ||
1697 | static struct r8a66597_td *r8a66597_make_td(struct r8a66597 *r8a66597, | 1695 | static struct r8a66597_td *r8a66597_make_td(struct r8a66597 *r8a66597, |
1698 | struct urb *urb, | 1696 | struct urb *urb, |
1699 | struct usb_host_endpoint *hep, | 1697 | struct usb_host_endpoint *hep) |
1700 | gfp_t mem_flags) | ||
1701 | { | 1698 | { |
1702 | struct r8a66597_td *td; | 1699 | struct r8a66597_td *td; |
1703 | u16 pipenum; | 1700 | u16 pipenum; |
1704 | 1701 | ||
1705 | td = kzalloc(sizeof(struct r8a66597_td), mem_flags); | 1702 | td = kzalloc(sizeof(struct r8a66597_td), GFP_ATOMIC); |
1706 | if (td == NULL) | 1703 | if (td == NULL) |
1707 | return NULL; | 1704 | return NULL; |
1708 | 1705 | ||
@@ -1741,7 +1738,8 @@ static int r8a66597_urb_enqueue(struct usb_hcd *hcd, | |||
1741 | } | 1738 | } |
1742 | 1739 | ||
1743 | if (!hep->hcpriv) { | 1740 | if (!hep->hcpriv) { |
1744 | hep->hcpriv = kzalloc(sizeof(struct r8a66597_pipe), mem_flags); | 1741 | hep->hcpriv = kzalloc(sizeof(struct r8a66597_pipe), |
1742 | GFP_ATOMIC); | ||
1745 | if (!hep->hcpriv) { | 1743 | if (!hep->hcpriv) { |
1746 | ret = -ENOMEM; | 1744 | ret = -ENOMEM; |
1747 | goto error; | 1745 | goto error; |
@@ -1755,7 +1753,7 @@ static int r8a66597_urb_enqueue(struct usb_hcd *hcd, | |||
1755 | init_pipe_config(r8a66597, urb); | 1753 | init_pipe_config(r8a66597, urb); |
1756 | 1754 | ||
1757 | set_address_zero(r8a66597, urb); | 1755 | set_address_zero(r8a66597, urb); |
1758 | td = r8a66597_make_td(r8a66597, urb, hep, mem_flags); | 1756 | td = r8a66597_make_td(r8a66597, urb, hep); |
1759 | if (td == NULL) { | 1757 | if (td == NULL) { |
1760 | ret = -ENOMEM; | 1758 | ret = -ENOMEM; |
1761 | goto error; | 1759 | goto error; |
diff --git a/drivers/usb/host/r8a66597.h b/drivers/usb/host/r8a66597.h index 97c2a71ac7a1..fe9ceb077d9b 100644 --- a/drivers/usb/host/r8a66597.h +++ b/drivers/usb/host/r8a66597.h | |||
@@ -203,14 +203,14 @@ | |||
203 | #define DTLN 0x0FFF /* b11-0: FIFO received data length */ | 203 | #define DTLN 0x0FFF /* b11-0: FIFO received data length */ |
204 | 204 | ||
205 | /* Interrupt Enable Register 0 */ | 205 | /* Interrupt Enable Register 0 */ |
206 | #define VBSE 0x8000 /* b15: VBUS interrupt */ | 206 | #define VBSE 0x8000 /* b15: VBUS interrupt */ |
207 | #define RSME 0x4000 /* b14: Resume interrupt */ | 207 | #define RSME 0x4000 /* b14: Resume interrupt */ |
208 | #define SOFE 0x2000 /* b13: Frame update interrupt */ | 208 | #define SOFE 0x2000 /* b13: Frame update interrupt */ |
209 | #define DVSE 0x1000 /* b12: Device state transition interrupt */ | 209 | #define DVSE 0x1000 /* b12: Device state transition interrupt */ |
210 | #define CTRE 0x0800 /* b11: Control transfer stage transition interrupt */ | 210 | #define CTRE 0x0800 /* b11: Control transfer stage transition interrupt */ |
211 | #define BEMPE 0x0400 /* b10: Buffer empty interrupt */ | 211 | #define BEMPE 0x0400 /* b10: Buffer empty interrupt */ |
212 | #define NRDYE 0x0200 /* b9: Buffer not ready interrupt */ | 212 | #define NRDYE 0x0200 /* b9: Buffer not ready interrupt */ |
213 | #define BRDYE 0x0100 /* b8: Buffer ready interrupt */ | 213 | #define BRDYE 0x0100 /* b8: Buffer ready interrupt */ |
214 | 214 | ||
215 | /* Interrupt Enable Register 1 */ | 215 | /* Interrupt Enable Register 1 */ |
216 | #define OVRCRE 0x8000 /* b15: Over-current interrupt */ | 216 | #define OVRCRE 0x8000 /* b15: Over-current interrupt */ |
@@ -268,16 +268,16 @@ | |||
268 | #define SOF_DISABLE 0x0000 /* SOF OUT Disable */ | 268 | #define SOF_DISABLE 0x0000 /* SOF OUT Disable */ |
269 | 269 | ||
270 | /* Interrupt Status Register 0 */ | 270 | /* Interrupt Status Register 0 */ |
271 | #define VBINT 0x8000 /* b15: VBUS interrupt */ | 271 | #define VBINT 0x8000 /* b15: VBUS interrupt */ |
272 | #define RESM 0x4000 /* b14: Resume interrupt */ | 272 | #define RESM 0x4000 /* b14: Resume interrupt */ |
273 | #define SOFR 0x2000 /* b13: SOF frame update interrupt */ | 273 | #define SOFR 0x2000 /* b13: SOF frame update interrupt */ |
274 | #define DVST 0x1000 /* b12: Device state transition interrupt */ | 274 | #define DVST 0x1000 /* b12: Device state transition interrupt */ |
275 | #define CTRT 0x0800 /* b11: Control transfer stage transition interrupt */ | 275 | #define CTRT 0x0800 /* b11: Control transfer stage transition interrupt */ |
276 | #define BEMP 0x0400 /* b10: Buffer empty interrupt */ | 276 | #define BEMP 0x0400 /* b10: Buffer empty interrupt */ |
277 | #define NRDY 0x0200 /* b9: Buffer not ready interrupt */ | 277 | #define NRDY 0x0200 /* b9: Buffer not ready interrupt */ |
278 | #define BRDY 0x0100 /* b8: Buffer ready interrupt */ | 278 | #define BRDY 0x0100 /* b8: Buffer ready interrupt */ |
279 | #define VBSTS 0x0080 /* b7: VBUS input port */ | 279 | #define VBSTS 0x0080 /* b7: VBUS input port */ |
280 | #define DVSQ 0x0070 /* b6-4: Device state */ | 280 | #define DVSQ 0x0070 /* b6-4: Device state */ |
281 | #define DS_SPD_CNFG 0x0070 /* Suspend Configured */ | 281 | #define DS_SPD_CNFG 0x0070 /* Suspend Configured */ |
282 | #define DS_SPD_ADDR 0x0060 /* Suspend Address */ | 282 | #define DS_SPD_ADDR 0x0060 /* Suspend Address */ |
283 | #define DS_SPD_DFLT 0x0050 /* Suspend Default */ | 283 | #define DS_SPD_DFLT 0x0050 /* Suspend Default */ |
@@ -315,13 +315,10 @@ | |||
315 | /* Micro Frame Number Register */ | 315 | /* Micro Frame Number Register */ |
316 | #define UFRNM 0x0007 /* b2-0: Micro frame number */ | 316 | #define UFRNM 0x0007 /* b2-0: Micro frame number */ |
317 | 317 | ||
318 | /* USB Address / Low Power Status Recovery Register */ | ||
319 | //#define USBADDR 0x007F /* b6-0: USB address */ | ||
320 | |||
321 | /* Default Control Pipe Maxpacket Size Register */ | 318 | /* Default Control Pipe Maxpacket Size Register */ |
322 | /* Pipe Maxpacket Size Register */ | 319 | /* Pipe Maxpacket Size Register */ |
323 | #define DEVSEL 0xF000 /* b15-14: Device address select */ | 320 | #define DEVSEL 0xF000 /* b15-14: Device address select */ |
324 | #define MAXP 0x007F /* b6-0: Maxpacket size of default control pipe */ | 321 | #define MAXP 0x007F /* b6-0: Maxpacket size of default control pipe */ |
325 | 322 | ||
326 | /* Default Control Pipe Control Register */ | 323 | /* Default Control Pipe Control Register */ |
327 | #define BSTS 0x8000 /* b15: Buffer status */ | 324 | #define BSTS 0x8000 /* b15: Buffer status */ |
@@ -366,21 +363,21 @@ | |||
366 | #define MXPS 0x07FF /* b10-0: Maxpacket size */ | 363 | #define MXPS 0x07FF /* b10-0: Maxpacket size */ |
367 | 364 | ||
368 | /* Pipe Cycle Configuration Register */ | 365 | /* Pipe Cycle Configuration Register */ |
369 | #define IFIS 0x1000 /* b12: Isochronous in-buffer flush mode select */ | 366 | #define IFIS 0x1000 /* b12: Isochronous in-buffer flush mode select */ |
370 | #define IITV 0x0007 /* b2-0: Isochronous interval */ | 367 | #define IITV 0x0007 /* b2-0: Isochronous interval */ |
371 | 368 | ||
372 | /* Pipex Control Register */ | 369 | /* Pipex Control Register */ |
373 | #define BSTS 0x8000 /* b15: Buffer status */ | 370 | #define BSTS 0x8000 /* b15: Buffer status */ |
374 | #define INBUFM 0x4000 /* b14: IN buffer monitor (Only for PIPE1 to 5) */ | 371 | #define INBUFM 0x4000 /* b14: IN buffer monitor (Only for PIPE1 to 5) */ |
375 | #define CSCLR 0x2000 /* b13: complete-split status clear */ | 372 | #define CSCLR 0x2000 /* b13: complete-split status clear */ |
376 | #define CSSTS 0x1000 /* b12: complete-split status */ | 373 | #define CSSTS 0x1000 /* b12: complete-split status */ |
377 | #define ATREPM 0x0400 /* b10: Auto repeat mode */ | 374 | #define ATREPM 0x0400 /* b10: Auto repeat mode */ |
378 | #define ACLRM 0x0200 /* b9: Out buffer auto clear mode */ | 375 | #define ACLRM 0x0200 /* b9: Out buffer auto clear mode */ |
379 | #define SQCLR 0x0100 /* b8: Sequence toggle bit clear */ | 376 | #define SQCLR 0x0100 /* b8: Sequence toggle bit clear */ |
380 | #define SQSET 0x0080 /* b7: Sequence toggle bit set */ | 377 | #define SQSET 0x0080 /* b7: Sequence toggle bit set */ |
381 | #define SQMON 0x0040 /* b6: Sequence toggle bit monitor */ | 378 | #define SQMON 0x0040 /* b6: Sequence toggle bit monitor */ |
382 | #define PBUSY 0x0020 /* b5: pipe busy */ | 379 | #define PBUSY 0x0020 /* b5: pipe busy */ |
383 | #define PID 0x0003 /* b1-0: Response PID */ | 380 | #define PID 0x0003 /* b1-0: Response PID */ |
384 | 381 | ||
385 | /* PIPExTRE */ | 382 | /* PIPExTRE */ |
386 | #define TRENB 0x0200 /* b9: Transaction counter enable */ | 383 | #define TRENB 0x0200 /* b9: Transaction counter enable */ |
@@ -407,15 +404,15 @@ | |||
407 | #define make_devsel(addr) (addr << 12) | 404 | #define make_devsel(addr) (addr << 12) |
408 | 405 | ||
409 | struct r8a66597_pipe_info { | 406 | struct r8a66597_pipe_info { |
410 | u16 pipenum; | 407 | u16 pipenum; |
411 | u16 address; /* R8A66597 HCD usb addres */ | 408 | u16 address; /* R8A66597 HCD usb addres */ |
412 | u16 epnum; | 409 | u16 epnum; |
413 | u16 maxpacket; | 410 | u16 maxpacket; |
414 | u16 type; | 411 | u16 type; |
415 | u16 bufnum; | 412 | u16 bufnum; |
416 | u16 buf_bsize; | 413 | u16 buf_bsize; |
417 | u16 interval; | 414 | u16 interval; |
418 | u16 dir_in; | 415 | u16 dir_in; |
419 | }; | 416 | }; |
420 | 417 | ||
421 | struct r8a66597_pipe { | 418 | struct r8a66597_pipe { |
diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index e98df2ee9901..7f765ec038cd 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include <linux/workqueue.h> | 52 | #include <linux/workqueue.h> |
53 | #include <linux/platform_device.h> | 53 | #include <linux/platform_device.h> |
54 | #include <linux/pci_ids.h> | 54 | #include <linux/pci_ids.h> |
55 | #include <linux/mutex.h> | ||
55 | #include <asm/io.h> | 56 | #include <asm/io.h> |
56 | #include <asm/irq.h> | 57 | #include <asm/irq.h> |
57 | #include <asm/system.h> | 58 | #include <asm/system.h> |
@@ -83,7 +84,7 @@ static DECLARE_WAIT_QUEUE_HEAD(u132_hcd_wait); | |||
83 | * u132_module_lock exists to protect access to global variables | 84 | * u132_module_lock exists to protect access to global variables |
84 | * | 85 | * |
85 | */ | 86 | */ |
86 | static struct semaphore u132_module_lock; | 87 | static struct mutex u132_module_lock; |
87 | static int u132_exiting = 0; | 88 | static int u132_exiting = 0; |
88 | static int u132_instances = 0; | 89 | static int u132_instances = 0; |
89 | static struct list_head u132_static_list; | 90 | static struct list_head u132_static_list; |
@@ -258,10 +259,10 @@ static void u132_hcd_delete(struct kref *kref) | |||
258 | struct platform_device *pdev = u132->platform_dev; | 259 | struct platform_device *pdev = u132->platform_dev; |
259 | struct usb_hcd *hcd = u132_to_hcd(u132); | 260 | struct usb_hcd *hcd = u132_to_hcd(u132); |
260 | u132->going += 1; | 261 | u132->going += 1; |
261 | down(&u132_module_lock); | 262 | mutex_lock(&u132_module_lock); |
262 | list_del_init(&u132->u132_list); | 263 | list_del_init(&u132->u132_list); |
263 | u132_instances -= 1; | 264 | u132_instances -= 1; |
264 | up(&u132_module_lock); | 265 | mutex_unlock(&u132_module_lock); |
265 | dev_warn(&u132->platform_dev->dev, "FREEING the hcd=%p and thus the u13" | 266 | dev_warn(&u132->platform_dev->dev, "FREEING the hcd=%p and thus the u13" |
266 | "2=%p going=%d pdev=%p\n", hcd, u132, u132->going, pdev); | 267 | "2=%p going=%d pdev=%p\n", hcd, u132, u132->going, pdev); |
267 | usb_put_hcd(hcd); | 268 | usb_put_hcd(hcd); |
@@ -3111,10 +3112,10 @@ static int __devinit u132_probe(struct platform_device *pdev) | |||
3111 | int retval = 0; | 3112 | int retval = 0; |
3112 | struct u132 *u132 = hcd_to_u132(hcd); | 3113 | struct u132 *u132 = hcd_to_u132(hcd); |
3113 | hcd->rsrc_start = 0; | 3114 | hcd->rsrc_start = 0; |
3114 | down(&u132_module_lock); | 3115 | mutex_lock(&u132_module_lock); |
3115 | list_add_tail(&u132->u132_list, &u132_static_list); | 3116 | list_add_tail(&u132->u132_list, &u132_static_list); |
3116 | u132->sequence_num = ++u132_instances; | 3117 | u132->sequence_num = ++u132_instances; |
3117 | up(&u132_module_lock); | 3118 | mutex_unlock(&u132_module_lock); |
3118 | u132_u132_init_kref(u132); | 3119 | u132_u132_init_kref(u132); |
3119 | u132_initialise(u132, pdev); | 3120 | u132_initialise(u132, pdev); |
3120 | hcd->product_desc = "ELAN U132 Host Controller"; | 3121 | hcd->product_desc = "ELAN U132 Host Controller"; |
@@ -3216,7 +3217,7 @@ static int __init u132_hcd_init(void) | |||
3216 | INIT_LIST_HEAD(&u132_static_list); | 3217 | INIT_LIST_HEAD(&u132_static_list); |
3217 | u132_instances = 0; | 3218 | u132_instances = 0; |
3218 | u132_exiting = 0; | 3219 | u132_exiting = 0; |
3219 | init_MUTEX(&u132_module_lock); | 3220 | mutex_init(&u132_module_lock); |
3220 | if (usb_disabled()) | 3221 | if (usb_disabled()) |
3221 | return -ENODEV; | 3222 | return -ENODEV; |
3222 | printk(KERN_INFO "driver %s built at %s on %s\n", hcd_name, __TIME__, | 3223 | printk(KERN_INFO "driver %s built at %s on %s\n", hcd_name, __TIME__, |
@@ -3232,9 +3233,9 @@ static void __exit u132_hcd_exit(void) | |||
3232 | { | 3233 | { |
3233 | struct u132 *u132; | 3234 | struct u132 *u132; |
3234 | struct u132 *temp; | 3235 | struct u132 *temp; |
3235 | down(&u132_module_lock); | 3236 | mutex_lock(&u132_module_lock); |
3236 | u132_exiting += 1; | 3237 | u132_exiting += 1; |
3237 | up(&u132_module_lock); | 3238 | mutex_unlock(&u132_module_lock); |
3238 | list_for_each_entry_safe(u132, temp, &u132_static_list, u132_list) { | 3239 | list_for_each_entry_safe(u132, temp, &u132_static_list, u132_list) { |
3239 | platform_device_unregister(u132->platform_dev); | 3240 | platform_device_unregister(u132->platform_dev); |
3240 | } platform_driver_unregister(&u132_platform_driver); | 3241 | } platform_driver_unregister(&u132_platform_driver); |
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index 4aed305982ec..3bb908ca38e9 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c | |||
@@ -827,8 +827,10 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, | |||
827 | * If direction is "send", change the packet ID from SETUP (0x2D) | 827 | * If direction is "send", change the packet ID from SETUP (0x2D) |
828 | * to OUT (0xE1). Else change it from SETUP to IN (0x69) and | 828 | * to OUT (0xE1). Else change it from SETUP to IN (0x69) and |
829 | * set Short Packet Detect (SPD) for all data packets. | 829 | * set Short Packet Detect (SPD) for all data packets. |
830 | * | ||
831 | * 0-length transfers always get treated as "send". | ||
830 | */ | 832 | */ |
831 | if (usb_pipeout(urb->pipe)) | 833 | if (usb_pipeout(urb->pipe) || len == 0) |
832 | destination ^= (USB_PID_SETUP ^ USB_PID_OUT); | 834 | destination ^= (USB_PID_SETUP ^ USB_PID_OUT); |
833 | else { | 835 | else { |
834 | destination ^= (USB_PID_SETUP ^ USB_PID_IN); | 836 | destination ^= (USB_PID_SETUP ^ USB_PID_IN); |
@@ -839,7 +841,12 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, | |||
839 | * Build the DATA TDs | 841 | * Build the DATA TDs |
840 | */ | 842 | */ |
841 | while (len > 0) { | 843 | while (len > 0) { |
842 | int pktsze = min(len, maxsze); | 844 | int pktsze = maxsze; |
845 | |||
846 | if (len <= pktsze) { /* The last data packet */ | ||
847 | pktsze = len; | ||
848 | status &= ~TD_CTRL_SPD; | ||
849 | } | ||
843 | 850 | ||
844 | td = uhci_alloc_td(uhci); | 851 | td = uhci_alloc_td(uhci); |
845 | if (!td) | 852 | if (!td) |
@@ -866,20 +873,10 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, | |||
866 | goto nomem; | 873 | goto nomem; |
867 | *plink = LINK_TO_TD(td); | 874 | *plink = LINK_TO_TD(td); |
868 | 875 | ||
869 | /* | 876 | /* Change direction for the status transaction */ |
870 | * It's IN if the pipe is an output pipe or we're not expecting | 877 | destination ^= (USB_PID_IN ^ USB_PID_OUT); |
871 | * data back. | ||
872 | */ | ||
873 | destination &= ~TD_TOKEN_PID_MASK; | ||
874 | if (usb_pipeout(urb->pipe) || !urb->transfer_buffer_length) | ||
875 | destination |= USB_PID_IN; | ||
876 | else | ||
877 | destination |= USB_PID_OUT; | ||
878 | |||
879 | destination |= TD_TOKEN_TOGGLE; /* End in Data1 */ | 878 | destination |= TD_TOKEN_TOGGLE; /* End in Data1 */ |
880 | 879 | ||
881 | status &= ~TD_CTRL_SPD; | ||
882 | |||
883 | uhci_add_td_to_urbp(td, urbp); | 880 | uhci_add_td_to_urbp(td, urbp); |
884 | uhci_fill_td(td, status | TD_CTRL_IOC, | 881 | uhci_fill_td(td, status | TD_CTRL_IOC, |
885 | destination | uhci_explen(0), 0); | 882 | destination | uhci_explen(0), 0); |
@@ -1185,10 +1182,18 @@ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb) | |||
1185 | } | 1182 | } |
1186 | } | 1183 | } |
1187 | 1184 | ||
1185 | /* Did we receive a short packet? */ | ||
1188 | } else if (len < uhci_expected_length(td_token(td))) { | 1186 | } else if (len < uhci_expected_length(td_token(td))) { |
1189 | 1187 | ||
1190 | /* We received a short packet */ | 1188 | /* For control transfers, go to the status TD if |
1191 | if (urb->transfer_flags & URB_SHORT_NOT_OK) | 1189 | * this isn't already the last data TD */ |
1190 | if (qh->type == USB_ENDPOINT_XFER_CONTROL) { | ||
1191 | if (td->list.next != urbp->td_list.prev) | ||
1192 | ret = 1; | ||
1193 | } | ||
1194 | |||
1195 | /* For bulk and interrupt, this may be an error */ | ||
1196 | else if (urb->transfer_flags & URB_SHORT_NOT_OK) | ||
1192 | ret = -EREMOTEIO; | 1197 | ret = -EREMOTEIO; |
1193 | 1198 | ||
1194 | /* Fixup needed only if this isn't the URB's last TD */ | 1199 | /* Fixup needed only if this isn't the URB's last TD */ |
@@ -1208,10 +1213,6 @@ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb) | |||
1208 | 1213 | ||
1209 | err: | 1214 | err: |
1210 | if (ret < 0) { | 1215 | if (ret < 0) { |
1211 | /* In case a control transfer gets an error | ||
1212 | * during the setup stage */ | ||
1213 | urb->actual_length = max(urb->actual_length, 0); | ||
1214 | |||
1215 | /* Note that the queue has stopped and save | 1216 | /* Note that the queue has stopped and save |
1216 | * the next toggle value */ | 1217 | * the next toggle value */ |
1217 | qh->element = UHCI_PTR_TERM; | 1218 | qh->element = UHCI_PTR_TERM; |
@@ -1489,9 +1490,25 @@ __acquires(uhci->lock) | |||
1489 | { | 1490 | { |
1490 | struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; | 1491 | struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; |
1491 | 1492 | ||
1493 | if (qh->type == USB_ENDPOINT_XFER_CONTROL) { | ||
1494 | |||
1495 | /* urb->actual_length < 0 means the setup transaction didn't | ||
1496 | * complete successfully. Either it failed or the URB was | ||
1497 | * unlinked first. Regardless, don't confuse people with a | ||
1498 | * negative length. */ | ||
1499 | urb->actual_length = max(urb->actual_length, 0); | ||
1500 | |||
1501 | /* Report erroneous short transfers */ | ||
1502 | if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) && | ||
1503 | urb->actual_length < | ||
1504 | urb->transfer_buffer_length && | ||
1505 | urb->status == 0)) | ||
1506 | urb->status = -EREMOTEIO; | ||
1507 | } | ||
1508 | |||
1492 | /* When giving back the first URB in an Isochronous queue, | 1509 | /* When giving back the first URB in an Isochronous queue, |
1493 | * reinitialize the QH's iso-related members for the next URB. */ | 1510 | * reinitialize the QH's iso-related members for the next URB. */ |
1494 | if (qh->type == USB_ENDPOINT_XFER_ISOC && | 1511 | else if (qh->type == USB_ENDPOINT_XFER_ISOC && |
1495 | urbp->node.prev == &qh->queue && | 1512 | urbp->node.prev == &qh->queue && |
1496 | urbp->node.next != &qh->queue) { | 1513 | urbp->node.next != &qh->queue) { |
1497 | struct urb *nurb = list_entry(urbp->node.next, | 1514 | struct urb *nurb = list_entry(urbp->node.next, |
diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index 36502a06f73a..d1131a87a5b1 100644 --- a/drivers/usb/image/mdc800.c +++ b/drivers/usb/image/mdc800.c | |||
@@ -284,9 +284,9 @@ static void mdc800_usb_irq (struct urb *urb) | |||
284 | int data_received=0, wake_up; | 284 | int data_received=0, wake_up; |
285 | unsigned char* b=urb->transfer_buffer; | 285 | unsigned char* b=urb->transfer_buffer; |
286 | struct mdc800_data* mdc800=urb->context; | 286 | struct mdc800_data* mdc800=urb->context; |
287 | int status = urb->status; | ||
287 | 288 | ||
288 | if (urb->status >= 0) | 289 | if (status >= 0) { |
289 | { | ||
290 | 290 | ||
291 | //dbg ("%i %i %i %i %i %i %i %i \n",b[0],b[1],b[2],b[3],b[4],b[5],b[6],b[7]); | 291 | //dbg ("%i %i %i %i %i %i %i %i \n",b[0],b[1],b[2],b[3],b[4],b[5],b[6],b[7]); |
292 | 292 | ||
@@ -324,7 +324,7 @@ static void mdc800_usb_irq (struct urb *urb) | |||
324 | || | 324 | || |
325 | ((mdc800->camera_request_ready == 3) && (mdc800->camera_busy)) | 325 | ((mdc800->camera_request_ready == 3) && (mdc800->camera_busy)) |
326 | || | 326 | || |
327 | (urb->status < 0) | 327 | (status < 0) |
328 | ); | 328 | ); |
329 | 329 | ||
330 | if (wake_up) | 330 | if (wake_up) |
@@ -376,15 +376,12 @@ static int mdc800_usb_waitForIRQ (int mode, int msec) | |||
376 | static void mdc800_usb_write_notify (struct urb *urb) | 376 | static void mdc800_usb_write_notify (struct urb *urb) |
377 | { | 377 | { |
378 | struct mdc800_data* mdc800=urb->context; | 378 | struct mdc800_data* mdc800=urb->context; |
379 | int status = urb->status; | ||
379 | 380 | ||
380 | if (urb->status != 0) | 381 | if (status != 0) |
381 | { | 382 | err ("writing command fails (status=%i)", status); |
382 | err ("writing command fails (status=%i)", urb->status); | ||
383 | } | ||
384 | else | 383 | else |
385 | { | ||
386 | mdc800->state=READY; | 384 | mdc800->state=READY; |
387 | } | ||
388 | mdc800->written = 1; | 385 | mdc800->written = 1; |
389 | wake_up (&mdc800->write_wait); | 386 | wake_up (&mdc800->write_wait); |
390 | } | 387 | } |
@@ -396,9 +393,9 @@ static void mdc800_usb_write_notify (struct urb *urb) | |||
396 | static void mdc800_usb_download_notify (struct urb *urb) | 393 | static void mdc800_usb_download_notify (struct urb *urb) |
397 | { | 394 | { |
398 | struct mdc800_data* mdc800=urb->context; | 395 | struct mdc800_data* mdc800=urb->context; |
396 | int status = urb->status; | ||
399 | 397 | ||
400 | if (urb->status == 0) | 398 | if (status == 0) { |
401 | { | ||
402 | /* Fill output buffer with these data */ | 399 | /* Fill output buffer with these data */ |
403 | memcpy (mdc800->out, urb->transfer_buffer, 64); | 400 | memcpy (mdc800->out, urb->transfer_buffer, 64); |
404 | mdc800->out_count=64; | 401 | mdc800->out_count=64; |
@@ -408,10 +405,8 @@ static void mdc800_usb_download_notify (struct urb *urb) | |||
408 | { | 405 | { |
409 | mdc800->state=READY; | 406 | mdc800->state=READY; |
410 | } | 407 | } |
411 | } | 408 | } else { |
412 | else | 409 | err ("request bytes fails (status:%i)", status); |
413 | { | ||
414 | err ("request bytes fails (status:%i)", urb->status); | ||
415 | } | 410 | } |
416 | mdc800->downloaded = 1; | 411 | mdc800->downloaded = 1; |
417 | wake_up (&mdc800->download_wait); | 412 | wake_up (&mdc800->download_wait); |
@@ -649,9 +644,9 @@ static int mdc800_device_open (struct inode* inode, struct file *file) | |||
649 | 644 | ||
650 | retval=0; | 645 | retval=0; |
651 | mdc800->irq_urb->dev = mdc800->dev; | 646 | mdc800->irq_urb->dev = mdc800->dev; |
652 | if (usb_submit_urb (mdc800->irq_urb, GFP_KERNEL)) | 647 | retval = usb_submit_urb (mdc800->irq_urb, GFP_KERNEL); |
653 | { | 648 | if (retval) { |
654 | err ("request USB irq fails (submit_retval=%i urb_status=%i).",retval, mdc800->irq_urb->status); | 649 | err ("request USB irq fails (submit_retval=%i).", retval); |
655 | errn = -EIO; | 650 | errn = -EIO; |
656 | goto error_out; | 651 | goto error_out; |
657 | } | 652 | } |
@@ -698,6 +693,7 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l | |||
698 | { | 693 | { |
699 | size_t left=len, sts=len; /* single transfer size */ | 694 | size_t left=len, sts=len; /* single transfer size */ |
700 | char __user *ptr = buf; | 695 | char __user *ptr = buf; |
696 | int retval; | ||
701 | 697 | ||
702 | mutex_lock(&mdc800->io_lock); | 698 | mutex_lock(&mdc800->io_lock); |
703 | if (mdc800->state == NOT_CONNECTED) | 699 | if (mdc800->state == NOT_CONNECTED) |
@@ -737,9 +733,9 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l | |||
737 | 733 | ||
738 | /* Download -> Request new bytes */ | 734 | /* Download -> Request new bytes */ |
739 | mdc800->download_urb->dev = mdc800->dev; | 735 | mdc800->download_urb->dev = mdc800->dev; |
740 | if (usb_submit_urb (mdc800->download_urb, GFP_KERNEL)) | 736 | retval = usb_submit_urb (mdc800->download_urb, GFP_KERNEL); |
741 | { | 737 | if (retval) { |
742 | err ("Can't submit download urb (status=%i)",mdc800->download_urb->status); | 738 | err ("Can't submit download urb (retval=%i)",retval); |
743 | mutex_unlock(&mdc800->io_lock); | 739 | mutex_unlock(&mdc800->io_lock); |
744 | return len-left; | 740 | return len-left; |
745 | } | 741 | } |
@@ -788,6 +784,7 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l | |||
788 | static ssize_t mdc800_device_write (struct file *file, const char __user *buf, size_t len, loff_t *pos) | 784 | static ssize_t mdc800_device_write (struct file *file, const char __user *buf, size_t len, loff_t *pos) |
789 | { | 785 | { |
790 | size_t i=0; | 786 | size_t i=0; |
787 | int retval; | ||
791 | 788 | ||
792 | mutex_lock(&mdc800->io_lock); | 789 | mutex_lock(&mdc800->io_lock); |
793 | if (mdc800->state != READY) | 790 | if (mdc800->state != READY) |
@@ -854,9 +851,9 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s | |||
854 | mdc800->state=WORKING; | 851 | mdc800->state=WORKING; |
855 | memcpy (mdc800->write_urb->transfer_buffer, mdc800->in,8); | 852 | memcpy (mdc800->write_urb->transfer_buffer, mdc800->in,8); |
856 | mdc800->write_urb->dev = mdc800->dev; | 853 | mdc800->write_urb->dev = mdc800->dev; |
857 | if (usb_submit_urb (mdc800->write_urb, GFP_KERNEL)) | 854 | retval = usb_submit_urb (mdc800->write_urb, GFP_KERNEL); |
858 | { | 855 | if (retval) { |
859 | err ("submitting write urb fails (status=%i)", mdc800->write_urb->status); | 856 | err ("submitting write urb fails (retval=%i)", retval); |
860 | mutex_unlock(&mdc800->io_lock); | 857 | mutex_unlock(&mdc800->io_lock); |
861 | return -EIO; | 858 | return -EIO; |
862 | } | 859 | } |
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index 51bd80d2b8cc..768b2c11a231 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c | |||
@@ -189,7 +189,7 @@ static struct usb_driver mts_usb_driver = { | |||
189 | #define MTS_DEBUG_INT() \ | 189 | #define MTS_DEBUG_INT() \ |
190 | do { MTS_DEBUG_GOT_HERE(); \ | 190 | do { MTS_DEBUG_GOT_HERE(); \ |
191 | MTS_DEBUG("transfer = 0x%x context = 0x%x\n",(int)transfer,(int)context ); \ | 191 | MTS_DEBUG("transfer = 0x%x context = 0x%x\n",(int)transfer,(int)context ); \ |
192 | MTS_DEBUG("status = 0x%x data-length = 0x%x sent = 0x%x\n",(int)transfer->status,(int)context->data_length, (int)transfer->actual_length ); \ | 192 | MTS_DEBUG("status = 0x%x data-length = 0x%x sent = 0x%x\n",transfer->status,(int)context->data_length, (int)transfer->actual_length ); \ |
193 | mts_debug_dump(context->instance);\ | 193 | mts_debug_dump(context->instance);\ |
194 | } while(0) | 194 | } while(0) |
195 | #else | 195 | #else |
@@ -393,8 +393,6 @@ void mts_int_submit_urb (struct urb* transfer, | |||
393 | context | 393 | context |
394 | ); | 394 | ); |
395 | 395 | ||
396 | transfer->status = 0; | ||
397 | |||
398 | res = usb_submit_urb( transfer, GFP_ATOMIC ); | 396 | res = usb_submit_urb( transfer, GFP_ATOMIC ); |
399 | if ( unlikely(res) ) { | 397 | if ( unlikely(res) ) { |
400 | MTS_INT_ERROR( "could not submit URB! Error was %d\n",(int)res ); | 398 | MTS_INT_ERROR( "could not submit URB! Error was %d\n",(int)res ); |
@@ -444,12 +442,13 @@ static void mts_get_status( struct urb *transfer ) | |||
444 | static void mts_data_done( struct urb* transfer ) | 442 | static void mts_data_done( struct urb* transfer ) |
445 | /* Interrupt context! */ | 443 | /* Interrupt context! */ |
446 | { | 444 | { |
445 | int status = transfer->status; | ||
447 | MTS_INT_INIT(); | 446 | MTS_INT_INIT(); |
448 | 447 | ||
449 | if ( context->data_length != transfer->actual_length ) { | 448 | if ( context->data_length != transfer->actual_length ) { |
450 | context->srb->resid = context->data_length - transfer->actual_length; | 449 | context->srb->resid = context->data_length - transfer->actual_length; |
451 | } else if ( unlikely(transfer->status) ) { | 450 | } else if ( unlikely(status) ) { |
452 | context->srb->result = (transfer->status == -ENOENT ? DID_ABORT : DID_ERROR)<<16; | 451 | context->srb->result = (status == -ENOENT ? DID_ABORT : DID_ERROR)<<16; |
453 | } | 452 | } |
454 | 453 | ||
455 | mts_get_status(transfer); | 454 | mts_get_status(transfer); |
@@ -461,10 +460,11 @@ static void mts_data_done( struct urb* transfer ) | |||
461 | static void mts_command_done( struct urb *transfer ) | 460 | static void mts_command_done( struct urb *transfer ) |
462 | /* Interrupt context! */ | 461 | /* Interrupt context! */ |
463 | { | 462 | { |
463 | int status = transfer->status; | ||
464 | MTS_INT_INIT(); | 464 | MTS_INT_INIT(); |
465 | 465 | ||
466 | if ( unlikely(transfer->status) ) { | 466 | if ( unlikely(status) ) { |
467 | if (transfer->status == -ENOENT) { | 467 | if (status == -ENOENT) { |
468 | /* We are being killed */ | 468 | /* We are being killed */ |
469 | MTS_DEBUG_GOT_HERE(); | 469 | MTS_DEBUG_GOT_HERE(); |
470 | context->srb->result = DID_ABORT<<16; | 470 | context->srb->result = DID_ABORT<<16; |
@@ -502,12 +502,13 @@ static void mts_command_done( struct urb *transfer ) | |||
502 | static void mts_do_sg (struct urb* transfer) | 502 | static void mts_do_sg (struct urb* transfer) |
503 | { | 503 | { |
504 | struct scatterlist * sg; | 504 | struct scatterlist * sg; |
505 | int status = transfer->status; | ||
505 | MTS_INT_INIT(); | 506 | MTS_INT_INIT(); |
506 | 507 | ||
507 | MTS_DEBUG("Processing fragment %d of %d\n", context->fragment,context->srb->use_sg); | 508 | MTS_DEBUG("Processing fragment %d of %d\n", context->fragment,context->srb->use_sg); |
508 | 509 | ||
509 | if (unlikely(transfer->status)) { | 510 | if (unlikely(status)) { |
510 | context->srb->result = (transfer->status == -ENOENT ? DID_ABORT : DID_ERROR)<<16; | 511 | context->srb->result = (status == -ENOENT ? DID_ABORT : DID_ERROR)<<16; |
511 | mts_transfer_cleanup(transfer); | 512 | mts_transfer_cleanup(transfer); |
512 | } | 513 | } |
513 | 514 | ||
diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c index d72c42e5f22d..e9fdbc8997b3 100644 --- a/drivers/usb/misc/adutux.c +++ b/drivers/usb/misc/adutux.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/usb.h> | 26 | #include <linux/usb.h> |
27 | #include <linux/mutex.h> | ||
27 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
28 | 29 | ||
29 | #ifdef CONFIG_USB_DEBUG | 30 | #ifdef CONFIG_USB_DEBUG |
@@ -80,7 +81,7 @@ MODULE_DEVICE_TABLE(usb, device_table); | |||
80 | 81 | ||
81 | /* Structure to hold all of our device specific stuff */ | 82 | /* Structure to hold all of our device specific stuff */ |
82 | struct adu_device { | 83 | struct adu_device { |
83 | struct semaphore sem; /* locks this structure */ | 84 | struct mutex mtx; /* locks this structure */ |
84 | struct usb_device* udev; /* save off the usb device pointer */ | 85 | struct usb_device* udev; /* save off the usb device pointer */ |
85 | struct usb_interface* interface; | 86 | struct usb_interface* interface; |
86 | unsigned char minor; /* the starting minor number for this device */ | 87 | unsigned char minor; /* the starting minor number for this device */ |
@@ -178,17 +179,18 @@ static void adu_delete(struct adu_device *dev) | |||
178 | static void adu_interrupt_in_callback(struct urb *urb) | 179 | static void adu_interrupt_in_callback(struct urb *urb) |
179 | { | 180 | { |
180 | struct adu_device *dev = urb->context; | 181 | struct adu_device *dev = urb->context; |
182 | int status = urb->status; | ||
181 | 183 | ||
182 | dbg(4," %s : enter, status %d", __FUNCTION__, urb->status); | 184 | dbg(4," %s : enter, status %d", __FUNCTION__, status); |
183 | adu_debug_data(5, __FUNCTION__, urb->actual_length, | 185 | adu_debug_data(5, __FUNCTION__, urb->actual_length, |
184 | urb->transfer_buffer); | 186 | urb->transfer_buffer); |
185 | 187 | ||
186 | spin_lock(&dev->buflock); | 188 | spin_lock(&dev->buflock); |
187 | 189 | ||
188 | if (urb->status != 0) { | 190 | if (status != 0) { |
189 | if ((urb->status != -ENOENT) && (urb->status != -ECONNRESET)) { | 191 | if ((status != -ENOENT) && (status != -ECONNRESET)) { |
190 | dbg(1," %s : nonzero status received: %d", | 192 | dbg(1," %s : nonzero status received: %d", |
191 | __FUNCTION__, urb->status); | 193 | __FUNCTION__, status); |
192 | } | 194 | } |
193 | goto exit; | 195 | goto exit; |
194 | } | 196 | } |
@@ -216,21 +218,22 @@ exit: | |||
216 | wake_up_interruptible(&dev->read_wait); | 218 | wake_up_interruptible(&dev->read_wait); |
217 | adu_debug_data(5, __FUNCTION__, urb->actual_length, | 219 | adu_debug_data(5, __FUNCTION__, urb->actual_length, |
218 | urb->transfer_buffer); | 220 | urb->transfer_buffer); |
219 | dbg(4," %s : leave, status %d", __FUNCTION__, urb->status); | 221 | dbg(4," %s : leave, status %d", __FUNCTION__, status); |
220 | } | 222 | } |
221 | 223 | ||
222 | static void adu_interrupt_out_callback(struct urb *urb) | 224 | static void adu_interrupt_out_callback(struct urb *urb) |
223 | { | 225 | { |
224 | struct adu_device *dev = urb->context; | 226 | struct adu_device *dev = urb->context; |
227 | int status = urb->status; | ||
225 | 228 | ||
226 | dbg(4," %s : enter, status %d", __FUNCTION__, urb->status); | 229 | dbg(4," %s : enter, status %d", __FUNCTION__, status); |
227 | adu_debug_data(5,__FUNCTION__, urb->actual_length, urb->transfer_buffer); | 230 | adu_debug_data(5,__FUNCTION__, urb->actual_length, urb->transfer_buffer); |
228 | 231 | ||
229 | if (urb->status != 0) { | 232 | if (status != 0) { |
230 | if ((urb->status != -ENOENT) && | 233 | if ((status != -ENOENT) && |
231 | (urb->status != -ECONNRESET)) { | 234 | (status != -ECONNRESET)) { |
232 | dbg(1, " %s :nonzero status received: %d", | 235 | dbg(1, " %s :nonzero status received: %d", |
233 | __FUNCTION__, urb->status); | 236 | __FUNCTION__, status); |
234 | } | 237 | } |
235 | goto exit; | 238 | goto exit; |
236 | } | 239 | } |
@@ -240,7 +243,7 @@ exit: | |||
240 | 243 | ||
241 | adu_debug_data(5, __FUNCTION__, urb->actual_length, | 244 | adu_debug_data(5, __FUNCTION__, urb->actual_length, |
242 | urb->transfer_buffer); | 245 | urb->transfer_buffer); |
243 | dbg(4," %s : leave, status %d", __FUNCTION__, urb->status); | 246 | dbg(4," %s : leave, status %d", __FUNCTION__, status); |
244 | } | 247 | } |
245 | 248 | ||
246 | static int adu_open(struct inode *inode, struct file *file) | 249 | static int adu_open(struct inode *inode, struct file *file) |
@@ -269,8 +272,8 @@ static int adu_open(struct inode *inode, struct file *file) | |||
269 | } | 272 | } |
270 | 273 | ||
271 | /* lock this device */ | 274 | /* lock this device */ |
272 | if ((retval = down_interruptible(&dev->sem))) { | 275 | if ((retval = mutex_lock_interruptible(&dev->mtx))) { |
273 | dbg(2, "%s : sem down failed", __FUNCTION__); | 276 | dbg(2, "%s : mutex lock failed", __FUNCTION__); |
274 | goto exit_no_device; | 277 | goto exit_no_device; |
275 | } | 278 | } |
276 | 279 | ||
@@ -299,7 +302,7 @@ static int adu_open(struct inode *inode, struct file *file) | |||
299 | if (retval) | 302 | if (retval) |
300 | --dev->open_count; | 303 | --dev->open_count; |
301 | } | 304 | } |
302 | up(&dev->sem); | 305 | mutex_unlock(&dev->mtx); |
303 | 306 | ||
304 | exit_no_device: | 307 | exit_no_device: |
305 | dbg(2,"%s : leave, return value %d ", __FUNCTION__, retval); | 308 | dbg(2,"%s : leave, return value %d ", __FUNCTION__, retval); |
@@ -347,7 +350,7 @@ static int adu_release(struct inode *inode, struct file *file) | |||
347 | } | 350 | } |
348 | 351 | ||
349 | /* lock our device */ | 352 | /* lock our device */ |
350 | down(&dev->sem); /* not interruptible */ | 353 | mutex_lock(&dev->mtx); /* not interruptible */ |
351 | 354 | ||
352 | if (dev->open_count <= 0) { | 355 | if (dev->open_count <= 0) { |
353 | dbg(1," %s : device not opened", __FUNCTION__); | 356 | dbg(1," %s : device not opened", __FUNCTION__); |
@@ -357,7 +360,7 @@ static int adu_release(struct inode *inode, struct file *file) | |||
357 | 360 | ||
358 | if (dev->udev == NULL) { | 361 | if (dev->udev == NULL) { |
359 | /* the device was unplugged before the file was released */ | 362 | /* the device was unplugged before the file was released */ |
360 | up(&dev->sem); | 363 | mutex_unlock(&dev->mtx); |
361 | adu_delete(dev); | 364 | adu_delete(dev); |
362 | dev = NULL; | 365 | dev = NULL; |
363 | } else { | 366 | } else { |
@@ -367,7 +370,7 @@ static int adu_release(struct inode *inode, struct file *file) | |||
367 | 370 | ||
368 | exit: | 371 | exit: |
369 | if (dev) | 372 | if (dev) |
370 | up(&dev->sem); | 373 | mutex_unlock(&dev->mtx); |
371 | dbg(2," %s : leave, return value %d", __FUNCTION__, retval); | 374 | dbg(2," %s : leave, return value %d", __FUNCTION__, retval); |
372 | return retval; | 375 | return retval; |
373 | } | 376 | } |
@@ -390,7 +393,7 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count, | |||
390 | dev = file->private_data; | 393 | dev = file->private_data; |
391 | dbg(2," %s : dev=%p", __FUNCTION__, dev); | 394 | dbg(2," %s : dev=%p", __FUNCTION__, dev); |
392 | /* lock this object */ | 395 | /* lock this object */ |
393 | if (down_interruptible(&dev->sem)) | 396 | if (mutex_lock_interruptible(&dev->mtx)) |
394 | return -ERESTARTSYS; | 397 | return -ERESTARTSYS; |
395 | 398 | ||
396 | /* verify that the device wasn't unplugged */ | 399 | /* verify that the device wasn't unplugged */ |
@@ -522,7 +525,7 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count, | |||
522 | 525 | ||
523 | exit: | 526 | exit: |
524 | /* unlock the device */ | 527 | /* unlock the device */ |
525 | up(&dev->sem); | 528 | mutex_unlock(&dev->mtx); |
526 | 529 | ||
527 | dbg(2," %s : leave, return value %d", __FUNCTION__, retval); | 530 | dbg(2," %s : leave, return value %d", __FUNCTION__, retval); |
528 | return retval; | 531 | return retval; |
@@ -543,7 +546,7 @@ static ssize_t adu_write(struct file *file, const __user char *buffer, | |||
543 | dev = file->private_data; | 546 | dev = file->private_data; |
544 | 547 | ||
545 | /* lock this object */ | 548 | /* lock this object */ |
546 | retval = down_interruptible(&dev->sem); | 549 | retval = mutex_lock_interruptible(&dev->mtx); |
547 | if (retval) | 550 | if (retval) |
548 | goto exit_nolock; | 551 | goto exit_nolock; |
549 | 552 | ||
@@ -571,9 +574,9 @@ static ssize_t adu_write(struct file *file, const __user char *buffer, | |||
571 | retval = -EINTR; | 574 | retval = -EINTR; |
572 | goto exit; | 575 | goto exit; |
573 | } | 576 | } |
574 | up(&dev->sem); | 577 | mutex_unlock(&dev->mtx); |
575 | timeout = interruptible_sleep_on_timeout(&dev->write_wait, timeout); | 578 | timeout = interruptible_sleep_on_timeout(&dev->write_wait, timeout); |
576 | retval = down_interruptible(&dev->sem); | 579 | retval = mutex_lock_interruptible(&dev->mtx); |
577 | if (retval) { | 580 | if (retval) { |
578 | retval = bytes_written ? bytes_written : retval; | 581 | retval = bytes_written ? bytes_written : retval; |
579 | goto exit_nolock; | 582 | goto exit_nolock; |
@@ -638,7 +641,7 @@ static ssize_t adu_write(struct file *file, const __user char *buffer, | |||
638 | 641 | ||
639 | exit: | 642 | exit: |
640 | /* unlock the device */ | 643 | /* unlock the device */ |
641 | up(&dev->sem); | 644 | mutex_unlock(&dev->mtx); |
642 | exit_nolock: | 645 | exit_nolock: |
643 | 646 | ||
644 | dbg(2," %s : leave, return value %d", __FUNCTION__, retval); | 647 | dbg(2," %s : leave, return value %d", __FUNCTION__, retval); |
@@ -698,7 +701,7 @@ static int adu_probe(struct usb_interface *interface, | |||
698 | goto exit; | 701 | goto exit; |
699 | } | 702 | } |
700 | 703 | ||
701 | init_MUTEX(&dev->sem); | 704 | mutex_init(&dev->mtx); |
702 | spin_lock_init(&dev->buflock); | 705 | spin_lock_init(&dev->buflock); |
703 | dev->udev = udev; | 706 | dev->udev = udev; |
704 | init_waitqueue_head(&dev->read_wait); | 707 | init_waitqueue_head(&dev->read_wait); |
@@ -835,16 +838,16 @@ static void adu_disconnect(struct usb_interface *interface) | |||
835 | usb_deregister_dev(interface, &adu_class); | 838 | usb_deregister_dev(interface, &adu_class); |
836 | dev->minor = 0; | 839 | dev->minor = 0; |
837 | 840 | ||
838 | down(&dev->sem); /* not interruptible */ | 841 | mutex_lock(&dev->mtx); /* not interruptible */ |
839 | 842 | ||
840 | /* if the device is not opened, then we clean up right now */ | 843 | /* if the device is not opened, then we clean up right now */ |
841 | dbg(2," %s : open count %d", __FUNCTION__, dev->open_count); | 844 | dbg(2," %s : open count %d", __FUNCTION__, dev->open_count); |
842 | if (!dev->open_count) { | 845 | if (!dev->open_count) { |
843 | up(&dev->sem); | 846 | mutex_unlock(&dev->mtx); |
844 | adu_delete(dev); | 847 | adu_delete(dev); |
845 | } else { | 848 | } else { |
846 | dev->udev = NULL; | 849 | dev->udev = NULL; |
847 | up(&dev->sem); | 850 | mutex_unlock(&dev->mtx); |
848 | } | 851 | } |
849 | 852 | ||
850 | dev_info(&interface->dev, "ADU device adutux%d now disconnected", | 853 | dev_info(&interface->dev, "ADU device adutux%d now disconnected", |
diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c index cf70c16f0e3f..b09c83568c1a 100644 --- a/drivers/usb/misc/appledisplay.c +++ b/drivers/usb/misc/appledisplay.c | |||
@@ -88,9 +88,10 @@ static void appledisplay_complete(struct urb *urb) | |||
88 | { | 88 | { |
89 | struct appledisplay *pdata = urb->context; | 89 | struct appledisplay *pdata = urb->context; |
90 | unsigned long flags; | 90 | unsigned long flags; |
91 | int status = urb->status; | ||
91 | int retval; | 92 | int retval; |
92 | 93 | ||
93 | switch (urb->status) { | 94 | switch (status) { |
94 | case 0: | 95 | case 0: |
95 | /* success */ | 96 | /* success */ |
96 | break; | 97 | break; |
@@ -102,12 +103,12 @@ static void appledisplay_complete(struct urb *urb) | |||
102 | case -ENOENT: | 103 | case -ENOENT: |
103 | case -ESHUTDOWN: | 104 | case -ESHUTDOWN: |
104 | /* This urb is terminated, clean up */ | 105 | /* This urb is terminated, clean up */ |
105 | dbg("%s - urb shutting down with status: %d", | 106 | dbg("%s - urb shuttingdown with status: %d", |
106 | __FUNCTION__, urb->status); | 107 | __FUNCTION__, status); |
107 | return; | 108 | return; |
108 | default: | 109 | default: |
109 | dbg("%s - nonzero urb status received: %d", | 110 | dbg("%s - nonzero urb status received: %d", |
110 | __FUNCTION__, urb->status); | 111 | __FUNCTION__, status); |
111 | goto exit; | 112 | goto exit; |
112 | } | 113 | } |
113 | 114 | ||
diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c index 42d4e6454a77..df7e1ecc810a 100644 --- a/drivers/usb/misc/auerswald.c +++ b/drivers/usb/misc/auerswald.c | |||
@@ -862,14 +862,16 @@ static void auerswald_ctrlread_wretcomplete (struct urb * urb) | |||
862 | pauerbuf_t bp = (pauerbuf_t) urb->context; | 862 | pauerbuf_t bp = (pauerbuf_t) urb->context; |
863 | pauerswald_t cp; | 863 | pauerswald_t cp; |
864 | int ret; | 864 | int ret; |
865 | int status = urb->status; | ||
866 | |||
865 | dbg ("auerswald_ctrlread_wretcomplete called"); | 867 | dbg ("auerswald_ctrlread_wretcomplete called"); |
866 | dbg ("complete with status: %d", urb->status); | 868 | dbg ("complete with status: %d", status); |
867 | cp = ((pauerswald_t)((char *)(bp->list)-(unsigned long)(&((pauerswald_t)0)->bufctl))); | 869 | cp = ((pauerswald_t)((char *)(bp->list)-(unsigned long)(&((pauerswald_t)0)->bufctl))); |
868 | 870 | ||
869 | /* check if it is possible to advance */ | 871 | /* check if it is possible to advance */ |
870 | if (!auerswald_status_retry (urb->status) || !cp->usbdev) { | 872 | if (!auerswald_status_retry(status) || !cp->usbdev) { |
871 | /* reuse the buffer */ | 873 | /* reuse the buffer */ |
872 | err ("control dummy: transmission error %d, can not retry", urb->status); | 874 | err ("control dummy: transmission error %d, can not retry", status); |
873 | auerbuf_releasebuf (bp); | 875 | auerbuf_releasebuf (bp); |
874 | /* Wake up all processes waiting for a buffer */ | 876 | /* Wake up all processes waiting for a buffer */ |
875 | wake_up (&cp->bufferwait); | 877 | wake_up (&cp->bufferwait); |
@@ -902,21 +904,23 @@ static void auerswald_ctrlread_complete (struct urb * urb) | |||
902 | pauerswald_t cp; | 904 | pauerswald_t cp; |
903 | pauerscon_t scp; | 905 | pauerscon_t scp; |
904 | pauerbuf_t bp = (pauerbuf_t) urb->context; | 906 | pauerbuf_t bp = (pauerbuf_t) urb->context; |
907 | int status = urb->status; | ||
905 | int ret; | 908 | int ret; |
909 | |||
906 | dbg ("auerswald_ctrlread_complete called"); | 910 | dbg ("auerswald_ctrlread_complete called"); |
907 | 911 | ||
908 | cp = ((pauerswald_t)((char *)(bp->list)-(unsigned long)(&((pauerswald_t)0)->bufctl))); | 912 | cp = ((pauerswald_t)((char *)(bp->list)-(unsigned long)(&((pauerswald_t)0)->bufctl))); |
909 | 913 | ||
910 | /* check if there is valid data in this urb */ | 914 | /* check if there is valid data in this urb */ |
911 | if (urb->status) { | 915 | if (status) { |
912 | dbg ("complete with non-zero status: %d", urb->status); | 916 | dbg ("complete with non-zero status: %d", status); |
913 | /* should we do a retry? */ | 917 | /* should we do a retry? */ |
914 | if (!auerswald_status_retry (urb->status) | 918 | if (!auerswald_status_retry(status) |
915 | || !cp->usbdev | 919 | || !cp->usbdev |
916 | || (cp->version < AUV_RETRY) | 920 | || (cp->version < AUV_RETRY) |
917 | || (bp->retries >= AU_RETRIES)) { | 921 | || (bp->retries >= AU_RETRIES)) { |
918 | /* reuse the buffer */ | 922 | /* reuse the buffer */ |
919 | err ("control read: transmission error %d, can not retry", urb->status); | 923 | err ("control read: transmission error %d, can not retry", status); |
920 | auerbuf_releasebuf (bp); | 924 | auerbuf_releasebuf (bp); |
921 | /* Wake up all processes waiting for a buffer */ | 925 | /* Wake up all processes waiting for a buffer */ |
922 | wake_up (&cp->bufferwait); | 926 | wake_up (&cp->bufferwait); |
@@ -974,12 +978,13 @@ static void auerswald_int_complete (struct urb * urb) | |||
974 | unsigned int channelid; | 978 | unsigned int channelid; |
975 | unsigned int bytecount; | 979 | unsigned int bytecount; |
976 | int ret; | 980 | int ret; |
981 | int status = urb->status; | ||
977 | pauerbuf_t bp = NULL; | 982 | pauerbuf_t bp = NULL; |
978 | pauerswald_t cp = (pauerswald_t) urb->context; | 983 | pauerswald_t cp = (pauerswald_t) urb->context; |
979 | 984 | ||
980 | dbg ("%s called", __FUNCTION__); | 985 | dbg ("%s called", __FUNCTION__); |
981 | 986 | ||
982 | switch (urb->status) { | 987 | switch (status) { |
983 | case 0: | 988 | case 0: |
984 | /* success */ | 989 | /* success */ |
985 | break; | 990 | break; |
@@ -987,10 +992,10 @@ static void auerswald_int_complete (struct urb * urb) | |||
987 | case -ENOENT: | 992 | case -ENOENT: |
988 | case -ESHUTDOWN: | 993 | case -ESHUTDOWN: |
989 | /* this urb is terminated, clean up */ | 994 | /* this urb is terminated, clean up */ |
990 | dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); | 995 | dbg("%s - urb shutting down with status: %d", __FUNCTION__, status); |
991 | return; | 996 | return; |
992 | default: | 997 | default: |
993 | dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); | 998 | dbg("%s - nonzero urb status received: %d", __FUNCTION__, status); |
994 | goto exit; | 999 | goto exit; |
995 | } | 1000 | } |
996 | 1001 | ||
diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c index e0f122e131d7..538b535e955b 100644 --- a/drivers/usb/misc/ftdi-elan.c +++ b/drivers/usb/misc/ftdi-elan.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <linux/slab.h> | 44 | #include <linux/slab.h> |
45 | #include <linux/module.h> | 45 | #include <linux/module.h> |
46 | #include <linux/kref.h> | 46 | #include <linux/kref.h> |
47 | #include <linux/mutex.h> | ||
47 | #include <asm/uaccess.h> | 48 | #include <asm/uaccess.h> |
48 | #include <linux/usb.h> | 49 | #include <linux/usb.h> |
49 | #include <linux/workqueue.h> | 50 | #include <linux/workqueue.h> |
@@ -64,7 +65,7 @@ static struct workqueue_struct *respond_queue; | |||
64 | * ftdi_module_lock exists to protect access to global variables | 65 | * ftdi_module_lock exists to protect access to global variables |
65 | * | 66 | * |
66 | */ | 67 | */ |
67 | static struct semaphore ftdi_module_lock; | 68 | static struct mutex ftdi_module_lock; |
68 | static int ftdi_instances = 0; | 69 | static int ftdi_instances = 0; |
69 | static struct list_head ftdi_static_list; | 70 | static struct list_head ftdi_static_list; |
70 | /* | 71 | /* |
@@ -199,10 +200,10 @@ static void ftdi_elan_delete(struct kref *kref) | |||
199 | dev_warn(&ftdi->udev->dev, "FREEING ftdi=%p\n", ftdi); | 200 | dev_warn(&ftdi->udev->dev, "FREEING ftdi=%p\n", ftdi); |
200 | usb_put_dev(ftdi->udev); | 201 | usb_put_dev(ftdi->udev); |
201 | ftdi->disconnected += 1; | 202 | ftdi->disconnected += 1; |
202 | down(&ftdi_module_lock); | 203 | mutex_lock(&ftdi_module_lock); |
203 | list_del_init(&ftdi->ftdi_list); | 204 | list_del_init(&ftdi->ftdi_list); |
204 | ftdi_instances -= 1; | 205 | ftdi_instances -= 1; |
205 | up(&ftdi_module_lock); | 206 | mutex_unlock(&ftdi_module_lock); |
206 | kfree(ftdi->bulk_in_buffer); | 207 | kfree(ftdi->bulk_in_buffer); |
207 | ftdi->bulk_in_buffer = NULL; | 208 | ftdi->bulk_in_buffer = NULL; |
208 | } | 209 | } |
@@ -746,10 +747,12 @@ static ssize_t ftdi_elan_read(struct file *file, char __user *buffer, | |||
746 | static void ftdi_elan_write_bulk_callback(struct urb *urb) | 747 | static void ftdi_elan_write_bulk_callback(struct urb *urb) |
747 | { | 748 | { |
748 | struct usb_ftdi *ftdi = (struct usb_ftdi *)urb->context; | 749 | struct usb_ftdi *ftdi = (struct usb_ftdi *)urb->context; |
749 | if (urb->status && !(urb->status == -ENOENT || urb->status == | 750 | int status = urb->status; |
750 | -ECONNRESET || urb->status == -ESHUTDOWN)) { | 751 | |
752 | if (status && !(status == -ENOENT || status == -ECONNRESET || | ||
753 | status == -ESHUTDOWN)) { | ||
751 | dev_err(&ftdi->udev->dev, "urb=%p write bulk status received: %" | 754 | dev_err(&ftdi->udev->dev, "urb=%p write bulk status received: %" |
752 | "d\n", urb, urb->status); | 755 | "d\n", urb, status); |
753 | } | 756 | } |
754 | usb_buffer_free(urb->dev, urb->transfer_buffer_length, | 757 | usb_buffer_free(urb->dev, urb->transfer_buffer_length, |
755 | urb->transfer_buffer, urb->transfer_dma); | 758 | urb->transfer_buffer, urb->transfer_dma); |
@@ -2780,10 +2783,10 @@ static int ftdi_elan_probe(struct usb_interface *interface, | |||
2780 | return -ENOMEM; | 2783 | return -ENOMEM; |
2781 | } | 2784 | } |
2782 | memset(ftdi, 0x00, sizeof(struct usb_ftdi)); | 2785 | memset(ftdi, 0x00, sizeof(struct usb_ftdi)); |
2783 | down(&ftdi_module_lock); | 2786 | mutex_lock(&ftdi_module_lock); |
2784 | list_add_tail(&ftdi->ftdi_list, &ftdi_static_list); | 2787 | list_add_tail(&ftdi->ftdi_list, &ftdi_static_list); |
2785 | ftdi->sequence_num = ++ftdi_instances; | 2788 | ftdi->sequence_num = ++ftdi_instances; |
2786 | up(&ftdi_module_lock); | 2789 | mutex_unlock(&ftdi_module_lock); |
2787 | ftdi_elan_init_kref(ftdi); | 2790 | ftdi_elan_init_kref(ftdi); |
2788 | init_MUTEX(&ftdi->sw_lock); | 2791 | init_MUTEX(&ftdi->sw_lock); |
2789 | ftdi->udev = usb_get_dev(interface_to_usbdev(interface)); | 2792 | ftdi->udev = usb_get_dev(interface_to_usbdev(interface)); |
@@ -2909,7 +2912,7 @@ static int __init ftdi_elan_init(void) | |||
2909 | int result; | 2912 | int result; |
2910 | printk(KERN_INFO "driver %s built at %s on %s\n", ftdi_elan_driver.name, | 2913 | printk(KERN_INFO "driver %s built at %s on %s\n", ftdi_elan_driver.name, |
2911 | __TIME__, __DATE__); | 2914 | __TIME__, __DATE__); |
2912 | init_MUTEX(&ftdi_module_lock); | 2915 | mutex_init(&ftdi_module_lock); |
2913 | INIT_LIST_HEAD(&ftdi_static_list); | 2916 | INIT_LIST_HEAD(&ftdi_static_list); |
2914 | status_queue = create_singlethread_workqueue("ftdi-status-control"); | 2917 | status_queue = create_singlethread_workqueue("ftdi-status-control"); |
2915 | if (!status_queue) | 2918 | if (!status_queue) |
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index 28548d186712..46d9f27ec173 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c | |||
@@ -158,9 +158,10 @@ static void iowarrior_callback(struct urb *urb) | |||
158 | int read_idx; | 158 | int read_idx; |
159 | int aux_idx; | 159 | int aux_idx; |
160 | int offset; | 160 | int offset; |
161 | int status; | 161 | int status = urb->status; |
162 | int retval; | ||
162 | 163 | ||
163 | switch (urb->status) { | 164 | switch (status) { |
164 | case 0: | 165 | case 0: |
165 | /* success */ | 166 | /* success */ |
166 | break; | 167 | break; |
@@ -213,10 +214,10 @@ static void iowarrior_callback(struct urb *urb) | |||
213 | wake_up_interruptible(&dev->read_wait); | 214 | wake_up_interruptible(&dev->read_wait); |
214 | 215 | ||
215 | exit: | 216 | exit: |
216 | status = usb_submit_urb(urb, GFP_ATOMIC); | 217 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
217 | if (status) | 218 | if (retval) |
218 | dev_err(&dev->interface->dev, "%s - usb_submit_urb failed with result %d", | 219 | dev_err(&dev->interface->dev, "%s - usb_submit_urb failed with result %d", |
219 | __FUNCTION__, status); | 220 | __FUNCTION__, retval); |
220 | 221 | ||
221 | } | 222 | } |
222 | 223 | ||
@@ -226,13 +227,15 @@ exit: | |||
226 | static void iowarrior_write_callback(struct urb *urb) | 227 | static void iowarrior_write_callback(struct urb *urb) |
227 | { | 228 | { |
228 | struct iowarrior *dev; | 229 | struct iowarrior *dev; |
230 | int status = urb->status; | ||
231 | |||
229 | dev = (struct iowarrior *)urb->context; | 232 | dev = (struct iowarrior *)urb->context; |
230 | /* sync/async unlink faults aren't errors */ | 233 | /* sync/async unlink faults aren't errors */ |
231 | if (urb->status && | 234 | if (status && |
232 | !(urb->status == -ENOENT || | 235 | !(status == -ENOENT || |
233 | urb->status == -ECONNRESET || urb->status == -ESHUTDOWN)) { | 236 | status == -ECONNRESET || status == -ESHUTDOWN)) { |
234 | dbg("%s - nonzero write bulk status received: %d", | 237 | dbg("%s - nonzero write bulk status received: %d", |
235 | __func__, urb->status); | 238 | __func__, status); |
236 | } | 239 | } |
237 | /* free up our allocated buffer */ | 240 | /* free up our allocated buffer */ |
238 | usb_buffer_free(urb->dev, urb->transfer_buffer_length, | 241 | usb_buffer_free(urb->dev, urb->transfer_buffer_length, |
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index 5e950b90c541..8208496dfc63 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c | |||
@@ -219,16 +219,17 @@ static void ld_usb_interrupt_in_callback(struct urb *urb) | |||
219 | struct ld_usb *dev = urb->context; | 219 | struct ld_usb *dev = urb->context; |
220 | size_t *actual_buffer; | 220 | size_t *actual_buffer; |
221 | unsigned int next_ring_head; | 221 | unsigned int next_ring_head; |
222 | int status = urb->status; | ||
222 | int retval; | 223 | int retval; |
223 | 224 | ||
224 | if (urb->status) { | 225 | if (status) { |
225 | if (urb->status == -ENOENT || | 226 | if (status == -ENOENT || |
226 | urb->status == -ECONNRESET || | 227 | status == -ECONNRESET || |
227 | urb->status == -ESHUTDOWN) { | 228 | status == -ESHUTDOWN) { |
228 | goto exit; | 229 | goto exit; |
229 | } else { | 230 | } else { |
230 | dbg_info(&dev->intf->dev, "%s: nonzero status received: %d\n", | 231 | dbg_info(&dev->intf->dev, "%s: nonzero status received: %d\n", |
231 | __FUNCTION__, urb->status); | 232 | __FUNCTION__, status); |
232 | spin_lock(&dev->rbsl); | 233 | spin_lock(&dev->rbsl); |
233 | goto resubmit; /* maybe we can recover */ | 234 | goto resubmit; /* maybe we can recover */ |
234 | } | 235 | } |
@@ -275,14 +276,15 @@ exit: | |||
275 | static void ld_usb_interrupt_out_callback(struct urb *urb) | 276 | static void ld_usb_interrupt_out_callback(struct urb *urb) |
276 | { | 277 | { |
277 | struct ld_usb *dev = urb->context; | 278 | struct ld_usb *dev = urb->context; |
279 | int status = urb->status; | ||
278 | 280 | ||
279 | /* sync/async unlink faults aren't errors */ | 281 | /* sync/async unlink faults aren't errors */ |
280 | if (urb->status && !(urb->status == -ENOENT || | 282 | if (status && !(status == -ENOENT || |
281 | urb->status == -ECONNRESET || | 283 | status == -ECONNRESET || |
282 | urb->status == -ESHUTDOWN)) | 284 | status == -ESHUTDOWN)) |
283 | dbg_info(&dev->intf->dev, | 285 | dbg_info(&dev->intf->dev, |
284 | "%s - nonzero write interrupt status received: %d\n", | 286 | "%s - nonzero write interrupt status received: %d\n", |
285 | __FUNCTION__, urb->status); | 287 | __FUNCTION__, status); |
286 | 288 | ||
287 | dev->interrupt_out_busy = 0; | 289 | dev->interrupt_out_busy = 0; |
288 | wake_up_interruptible(&dev->write_wait); | 290 | wake_up_interruptible(&dev->write_wait); |
diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c index 2ed0daea894c..561970b889a5 100644 --- a/drivers/usb/misc/legousbtower.c +++ b/drivers/usb/misc/legousbtower.c | |||
@@ -742,19 +742,20 @@ exit: | |||
742 | static void tower_interrupt_in_callback (struct urb *urb) | 742 | static void tower_interrupt_in_callback (struct urb *urb) |
743 | { | 743 | { |
744 | struct lego_usb_tower *dev = (struct lego_usb_tower *)urb->context; | 744 | struct lego_usb_tower *dev = (struct lego_usb_tower *)urb->context; |
745 | int status = urb->status; | ||
745 | int retval; | 746 | int retval; |
746 | 747 | ||
747 | dbg(4, "%s: enter, status %d", __FUNCTION__, urb->status); | 748 | dbg(4, "%s: enter, status %d", __FUNCTION__, status); |
748 | 749 | ||
749 | lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); | 750 | lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); |
750 | 751 | ||
751 | if (urb->status) { | 752 | if (status) { |
752 | if (urb->status == -ENOENT || | 753 | if (status == -ENOENT || |
753 | urb->status == -ECONNRESET || | 754 | status == -ECONNRESET || |
754 | urb->status == -ESHUTDOWN) { | 755 | status == -ESHUTDOWN) { |
755 | goto exit; | 756 | goto exit; |
756 | } else { | 757 | } else { |
757 | dbg(1, "%s: nonzero status received: %d", __FUNCTION__, urb->status); | 758 | dbg(1, "%s: nonzero status received: %d", __FUNCTION__, status); |
758 | goto resubmit; /* maybe we can recover */ | 759 | goto resubmit; /* maybe we can recover */ |
759 | } | 760 | } |
760 | } | 761 | } |
@@ -788,7 +789,7 @@ exit: | |||
788 | wake_up_interruptible (&dev->read_wait); | 789 | wake_up_interruptible (&dev->read_wait); |
789 | 790 | ||
790 | lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); | 791 | lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); |
791 | dbg(4, "%s: leave, status %d", __FUNCTION__, urb->status); | 792 | dbg(4, "%s: leave, status %d", __FUNCTION__, status); |
792 | } | 793 | } |
793 | 794 | ||
794 | 795 | ||
@@ -798,23 +799,24 @@ exit: | |||
798 | static void tower_interrupt_out_callback (struct urb *urb) | 799 | static void tower_interrupt_out_callback (struct urb *urb) |
799 | { | 800 | { |
800 | struct lego_usb_tower *dev = (struct lego_usb_tower *)urb->context; | 801 | struct lego_usb_tower *dev = (struct lego_usb_tower *)urb->context; |
802 | int status = urb->status; | ||
801 | 803 | ||
802 | dbg(4, "%s: enter, status %d", __FUNCTION__, urb->status); | 804 | dbg(4, "%s: enter, status %d", __FUNCTION__, status); |
803 | lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); | 805 | lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); |
804 | 806 | ||
805 | /* sync/async unlink faults aren't errors */ | 807 | /* sync/async unlink faults aren't errors */ |
806 | if (urb->status && !(urb->status == -ENOENT || | 808 | if (status && !(status == -ENOENT || |
807 | urb->status == -ECONNRESET || | 809 | status == -ECONNRESET || |
808 | urb->status == -ESHUTDOWN)) { | 810 | status == -ESHUTDOWN)) { |
809 | dbg(1, "%s - nonzero write bulk status received: %d", | 811 | dbg(1, "%s - nonzero write bulk status received: %d", |
810 | __FUNCTION__, urb->status); | 812 | __FUNCTION__, status); |
811 | } | 813 | } |
812 | 814 | ||
813 | dev->interrupt_out_busy = 0; | 815 | dev->interrupt_out_busy = 0; |
814 | wake_up_interruptible(&dev->write_wait); | 816 | wake_up_interruptible(&dev->write_wait); |
815 | 817 | ||
816 | lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); | 818 | lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); |
817 | dbg(4, "%s: leave, status %d", __FUNCTION__, urb->status); | 819 | dbg(4, "%s: leave, status %d", __FUNCTION__, status); |
818 | } | 820 | } |
819 | 821 | ||
820 | 822 | ||
diff --git a/drivers/usb/misc/phidgetkit.c b/drivers/usb/misc/phidgetkit.c index 371bf2b1197d..aa9bcceabe74 100644 --- a/drivers/usb/misc/phidgetkit.c +++ b/drivers/usb/misc/phidgetkit.c | |||
@@ -305,9 +305,10 @@ static void interfacekit_irq(struct urb *urb) | |||
305 | struct interfacekit *kit = urb->context; | 305 | struct interfacekit *kit = urb->context; |
306 | unsigned char *buffer = kit->data; | 306 | unsigned char *buffer = kit->data; |
307 | int i, level, sensor; | 307 | int i, level, sensor; |
308 | int status; | 308 | int retval; |
309 | int status = urb->status; | ||
309 | 310 | ||
310 | switch (urb->status) { | 311 | switch (status) { |
311 | case 0: /* success */ | 312 | case 0: /* success */ |
312 | break; | 313 | break; |
313 | case -ECONNRESET: /* unlink */ | 314 | case -ECONNRESET: /* unlink */ |
@@ -377,11 +378,11 @@ static void interfacekit_irq(struct urb *urb) | |||
377 | schedule_delayed_work(&kit->do_notify, 0); | 378 | schedule_delayed_work(&kit->do_notify, 0); |
378 | 379 | ||
379 | resubmit: | 380 | resubmit: |
380 | status = usb_submit_urb(urb, GFP_ATOMIC); | 381 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
381 | if (status) | 382 | if (retval) |
382 | err("can't resubmit intr, %s-%s/interfacekit0, status %d", | 383 | err("can't resubmit intr, %s-%s/interfacekit0, retval %d", |
383 | kit->udev->bus->bus_name, | 384 | kit->udev->bus->bus_name, |
384 | kit->udev->devpath, status); | 385 | kit->udev->devpath, retval); |
385 | } | 386 | } |
386 | 387 | ||
387 | static void do_notify(struct work_struct *work) | 388 | static void do_notify(struct work_struct *work) |
diff --git a/drivers/usb/misc/phidgetmotorcontrol.c b/drivers/usb/misc/phidgetmotorcontrol.c index 5727e1ea2f91..df0ebcdb9d6a 100644 --- a/drivers/usb/misc/phidgetmotorcontrol.c +++ b/drivers/usb/misc/phidgetmotorcontrol.c | |||
@@ -95,9 +95,10 @@ static void motorcontrol_irq(struct urb *urb) | |||
95 | struct motorcontrol *mc = urb->context; | 95 | struct motorcontrol *mc = urb->context; |
96 | unsigned char *buffer = mc->data; | 96 | unsigned char *buffer = mc->data; |
97 | int i, level; | 97 | int i, level; |
98 | int status; | 98 | int retval; |
99 | int status = urb->status;; | ||
99 | 100 | ||
100 | switch (urb->status) { | 101 | switch (status) { |
101 | case 0: /* success */ | 102 | case 0: /* success */ |
102 | break; | 103 | break; |
103 | case -ECONNRESET: /* unlink */ | 104 | case -ECONNRESET: /* unlink */ |
@@ -151,12 +152,12 @@ static void motorcontrol_irq(struct urb *urb) | |||
151 | schedule_delayed_work(&mc->do_notify, 0); | 152 | schedule_delayed_work(&mc->do_notify, 0); |
152 | 153 | ||
153 | resubmit: | 154 | resubmit: |
154 | status = usb_submit_urb(urb, GFP_ATOMIC); | 155 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
155 | if (status) | 156 | if (retval) |
156 | dev_err(&mc->intf->dev, | 157 | dev_err(&mc->intf->dev, |
157 | "can't resubmit intr, %s-%s/motorcontrol0, status %d", | 158 | "can't resubmit intr, %s-%s/motorcontrol0, retval %d", |
158 | mc->udev->bus->bus_name, | 159 | mc->udev->bus->bus_name, |
159 | mc->udev->devpath, status); | 160 | mc->udev->devpath, retval); |
160 | } | 161 | } |
161 | 162 | ||
162 | static void do_notify(struct work_struct *work) | 163 | static void do_notify(struct work_struct *work) |
diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c index 504f7221b0d0..719842032712 100644 --- a/drivers/usb/misc/usblcd.c +++ b/drivers/usb/misc/usblcd.c | |||
@@ -176,16 +176,17 @@ static int lcd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u | |||
176 | static void lcd_write_bulk_callback(struct urb *urb) | 176 | static void lcd_write_bulk_callback(struct urb *urb) |
177 | { | 177 | { |
178 | struct usb_lcd *dev; | 178 | struct usb_lcd *dev; |
179 | int status = urb->status; | ||
179 | 180 | ||
180 | dev = (struct usb_lcd *)urb->context; | 181 | dev = (struct usb_lcd *)urb->context; |
181 | 182 | ||
182 | /* sync/async unlink faults aren't errors */ | 183 | /* sync/async unlink faults aren't errors */ |
183 | if (urb->status && | 184 | if (status && |
184 | !(urb->status == -ENOENT || | 185 | !(status == -ENOENT || |
185 | urb->status == -ECONNRESET || | 186 | status == -ECONNRESET || |
186 | urb->status == -ESHUTDOWN)) { | 187 | status == -ESHUTDOWN)) { |
187 | dbg("USBLCD: %s - nonzero write bulk status received: %d", | 188 | dbg("USBLCD: %s - nonzero write bulk status received: %d", |
188 | __FUNCTION__, urb->status); | 189 | __FUNCTION__, status); |
189 | } | 190 | } |
190 | 191 | ||
191 | /* free up our allocated buffer */ | 192 | /* free up our allocated buffer */ |
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index fb321864a92d..e901d31e051b 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c | |||
@@ -768,8 +768,8 @@ static void ctrl_complete (struct urb *urb) | |||
768 | 768 | ||
769 | /* some faults are allowed, not required */ | 769 | /* some faults are allowed, not required */ |
770 | if (subcase->expected > 0 && ( | 770 | if (subcase->expected > 0 && ( |
771 | ((urb->status == -subcase->expected /* happened */ | 771 | ((status == -subcase->expected /* happened */ |
772 | || urb->status == 0)))) /* didn't */ | 772 | || status == 0)))) /* didn't */ |
773 | status = 0; | 773 | status = 0; |
774 | /* sometimes more than one fault is allowed */ | 774 | /* sometimes more than one fault is allowed */ |
775 | else if (subcase->number == 12 && status == -EPIPE) | 775 | else if (subcase->number == 12 && status == -EPIPE) |
diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c index 1a60f9c473ad..2734fe2b9c43 100644 --- a/drivers/usb/misc/uss720.c +++ b/drivers/usb/misc/uss720.c | |||
@@ -111,12 +111,13 @@ static void async_complete(struct urb *urb) | |||
111 | struct uss720_async_request *rq; | 111 | struct uss720_async_request *rq; |
112 | struct parport *pp; | 112 | struct parport *pp; |
113 | struct parport_uss720_private *priv; | 113 | struct parport_uss720_private *priv; |
114 | int status = urb->status; | ||
114 | 115 | ||
115 | rq = urb->context; | 116 | rq = urb->context; |
116 | priv = rq->priv; | 117 | priv = rq->priv; |
117 | pp = priv->pp; | 118 | pp = priv->pp; |
118 | if (urb->status) { | 119 | if (status) { |
119 | err("async_complete: urb error %d", urb->status); | 120 | err("async_complete: urb error %d", status); |
120 | } else if (rq->dr.bRequest == 3) { | 121 | } else if (rq->dr.bRequest == 3) { |
121 | memcpy(priv->reg, rq->reg, sizeof(priv->reg)); | 122 | memcpy(priv->reg, rq->reg, sizeof(priv->reg)); |
122 | #if 0 | 123 | #if 0 |
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 0d3903691e8c..b8670905bc3a 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c | |||
@@ -2794,16 +2794,14 @@ static void edge_shutdown (struct usb_serial *serial) | |||
2794 | 2794 | ||
2795 | dbg ("%s", __FUNCTION__); | 2795 | dbg ("%s", __FUNCTION__); |
2796 | 2796 | ||
2797 | for (i=0; i < serial->num_ports; ++i) { | 2797 | for (i = 0; i < serial->num_ports; ++i) { |
2798 | edge_port = usb_get_serial_port_data(serial->port[i]); | 2798 | edge_port = usb_get_serial_port_data(serial->port[i]); |
2799 | edge_remove_sysfs_attrs(edge_port->port); | 2799 | edge_remove_sysfs_attrs(edge_port->port); |
2800 | if (edge_port) { | 2800 | edge_buf_free(edge_port->ep_out_buf); |
2801 | edge_buf_free(edge_port->ep_out_buf); | 2801 | kfree(edge_port); |
2802 | kfree(edge_port); | ||
2803 | } | ||
2804 | usb_set_serial_port_data(serial->port[i], NULL); | 2802 | usb_set_serial_port_data(serial->port[i], NULL); |
2805 | } | 2803 | } |
2806 | kfree (usb_get_serial_data(serial)); | 2804 | kfree(usb_get_serial_data(serial)); |
2807 | usb_set_serial_data(serial, NULL); | 2805 | usb_set_serial_data(serial, NULL); |
2808 | } | 2806 | } |
2809 | 2807 | ||
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 231b584f6d0f..01e811becec4 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c | |||
@@ -110,11 +110,6 @@ static void mos7720_interrupt_callback(struct urb *urb) | |||
110 | 110 | ||
111 | dbg("%s"," : Entering\n"); | 111 | dbg("%s"," : Entering\n"); |
112 | 112 | ||
113 | if (!urb) { | ||
114 | dbg("%s","Invalid Pointer !!!!:\n"); | ||
115 | return; | ||
116 | } | ||
117 | |||
118 | switch (status) { | 113 | switch (status) { |
119 | case 0: | 114 | case 0: |
120 | /* success */ | 115 | /* success */ |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 37f41f576d3d..f76480f1455d 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -436,11 +436,6 @@ static void mos7840_control_callback(struct urb *urb) | |||
436 | int result = 0; | 436 | int result = 0; |
437 | int status = urb->status; | 437 | int status = urb->status; |
438 | 438 | ||
439 | if (!urb) { | ||
440 | dbg("%s", "Invalid Pointer !!!!:\n"); | ||
441 | return; | ||
442 | } | ||
443 | |||
444 | mos7840_port = (struct moschip_port *)urb->context; | 439 | mos7840_port = (struct moschip_port *)urb->context; |
445 | 440 | ||
446 | switch (status) { | 441 | switch (status) { |
@@ -525,10 +520,6 @@ static void mos7840_interrupt_callback(struct urb *urb) | |||
525 | int status = urb->status; | 520 | int status = urb->status; |
526 | 521 | ||
527 | dbg("%s", " : Entering\n"); | 522 | dbg("%s", " : Entering\n"); |
528 | if (!urb) { | ||
529 | dbg("%s", "Invalid Pointer !!!!:\n"); | ||
530 | return; | ||
531 | } | ||
532 | 523 | ||
533 | switch (status) { | 524 | switch (status) { |
534 | case 0: | 525 | case 0: |
@@ -676,11 +667,6 @@ static void mos7840_bulk_in_callback(struct urb *urb) | |||
676 | struct tty_struct *tty; | 667 | struct tty_struct *tty; |
677 | int status = urb->status; | 668 | int status = urb->status; |
678 | 669 | ||
679 | if (!urb) { | ||
680 | dbg("%s", "Invalid Pointer !!!!:\n"); | ||
681 | return; | ||
682 | } | ||
683 | |||
684 | if (status) { | 670 | if (status) { |
685 | dbg("nonzero read bulk status received: %d", status); | 671 | dbg("nonzero read bulk status received: %d", status); |
686 | return; | 672 | return; |
@@ -753,11 +739,6 @@ static void mos7840_bulk_out_data_callback(struct urb *urb) | |||
753 | int status = urb->status; | 739 | int status = urb->status; |
754 | int i; | 740 | int i; |
755 | 741 | ||
756 | if (!urb) { | ||
757 | dbg("%s", "Invalid Pointer !!!!:\n"); | ||
758 | return; | ||
759 | } | ||
760 | |||
761 | mos7840_port = (struct moschip_port *)urb->context; | 742 | mos7840_port = (struct moschip_port *)urb->context; |
762 | spin_lock(&mos7840_port->pool_lock); | 743 | spin_lock(&mos7840_port->pool_lock); |
763 | for (i = 0; i < NUM_URBS; i++) { | 744 | for (i = 0; i < NUM_URBS; i++) { |
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index e7db20343d1a..0794ccdebfd4 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | USB Driver for Sierra Wireless | 2 | USB Driver for Sierra Wireless |
3 | 3 | ||
4 | Copyright (C) 2006 Kevin Lloyd <linux@sierrawireless.com> | 4 | Copyright (C) 2006, 2007 Kevin Lloyd <linux@sierrawireless.com> |
5 | 5 | ||
6 | IMPORTANT DISCLAIMER: This driver is not commercially supported by | 6 | IMPORTANT DISCLAIMER: This driver is not commercially supported by |
7 | Sierra Wireless. Use at your own risk. | 7 | Sierra Wireless. Use at your own risk. |
@@ -12,10 +12,9 @@ | |||
12 | 12 | ||
13 | Portions based on the option driver by Matthias Urlichs <smurf@smurf.noris.de> | 13 | Portions based on the option driver by Matthias Urlichs <smurf@smurf.noris.de> |
14 | Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org> | 14 | Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org> |
15 | |||
16 | */ | 15 | */ |
17 | 16 | ||
18 | #define DRIVER_VERSION "v.1.0.6" | 17 | #define DRIVER_VERSION "v.1.2.5b" |
19 | #define DRIVER_AUTHOR "Kevin Lloyd <linux@sierrawireless.com>" | 18 | #define DRIVER_AUTHOR "Kevin Lloyd <linux@sierrawireless.com>" |
20 | #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" | 19 | #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" |
21 | 20 | ||
@@ -28,23 +27,98 @@ | |||
28 | #include <linux/usb.h> | 27 | #include <linux/usb.h> |
29 | #include <linux/usb/serial.h> | 28 | #include <linux/usb/serial.h> |
30 | 29 | ||
30 | #define SWIMS_USB_REQUEST_SetMode 0x0B | ||
31 | #define SWIMS_USB_REQUEST_TYPE_SetMode 0x40 | ||
32 | #define SWIMS_USB_INDEX_SetMode 0x0000 | ||
33 | #define SWIMS_SET_MODE_Modem 0x0001 | ||
34 | |||
35 | /* per port private data */ | ||
36 | #define N_IN_URB 4 | ||
37 | #define N_OUT_URB 4 | ||
38 | #define IN_BUFLEN 4096 | ||
39 | |||
40 | static int debug; | ||
41 | |||
42 | enum devicetype { | ||
43 | DEVICE_3_PORT = 0, | ||
44 | DEVICE_1_PORT = 1, | ||
45 | DEVICE_INSTALLER = 2, | ||
46 | }; | ||
47 | |||
48 | int sierra_set_power_state(struct usb_device *udev, __u16 swiState) | ||
49 | { | ||
50 | int result; | ||
51 | dev_dbg(&udev->dev, "%s", "SET POWER STATE"); | ||
52 | result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
53 | 0x00, /* __u8 request */ | ||
54 | 0x40, /* __u8 request type */ | ||
55 | swiState, /* __u16 value */ | ||
56 | 0, /* __u16 index */ | ||
57 | NULL, /* void *data */ | ||
58 | 0, /* __u16 size */ | ||
59 | USB_CTRL_SET_TIMEOUT); /* int timeout */ | ||
60 | return result; | ||
61 | } | ||
62 | |||
63 | int sierra_set_ms_mode(struct usb_device *udev, __u16 eSocMode) | ||
64 | { | ||
65 | int result; | ||
66 | dev_dbg(&udev->dev, "%s", "DEVICE MODE SWITCH"); | ||
67 | result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
68 | SWIMS_USB_REQUEST_SetMode, /* __u8 request */ | ||
69 | SWIMS_USB_REQUEST_TYPE_SetMode, /* __u8 request type */ | ||
70 | eSocMode, /* __u16 value */ | ||
71 | SWIMS_USB_INDEX_SetMode, /* __u16 index */ | ||
72 | NULL, /* void *data */ | ||
73 | 0, /* __u16 size */ | ||
74 | USB_CTRL_SET_TIMEOUT); /* int timeout */ | ||
75 | return result; | ||
76 | } | ||
77 | |||
78 | int sierra_probe(struct usb_interface *iface, const struct usb_device_id *id) | ||
79 | { | ||
80 | int result; | ||
81 | struct usb_device *udev; | ||
82 | |||
83 | udev = usb_get_dev(interface_to_usbdev(iface)); | ||
84 | |||
85 | /* Check if in installer mode */ | ||
86 | if (id->driver_info == DEVICE_INSTALLER) { | ||
87 | dev_dbg(&udev->dev, "%s", "FOUND DEVICE(SW)\n"); | ||
88 | result = sierra_set_ms_mode(udev, SWIMS_SET_MODE_Modem); | ||
89 | /*We do not want to bind to the device when in installer mode*/ | ||
90 | return -EIO; | ||
91 | } | ||
92 | |||
93 | return usb_serial_probe(iface, id); | ||
94 | } | ||
31 | 95 | ||
32 | static struct usb_device_id id_table [] = { | 96 | static struct usb_device_id id_table [] = { |
33 | { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ | 97 | { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ |
34 | { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ | 98 | { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ |
35 | { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ | 99 | { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ |
100 | { USB_DEVICE(0x0f30, 0x1b1d) }, /* Sierra Wireless MC5720 */ | ||
36 | { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ | 101 | { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ |
37 | { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ | 102 | { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ |
38 | { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless AirCard 595U */ | ||
39 | { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ | 103 | { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ |
104 | { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */ | ||
105 | |||
40 | { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ | 106 | { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ |
41 | { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ | 107 | { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ |
42 | { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ | 108 | { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ |
43 | { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */ | 109 | { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */ |
44 | { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ | 110 | { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ |
111 | { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780*/ | ||
112 | { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781*/ | ||
113 | { USB_DEVICE(0x1199, 0x6850) }, /* Sierra Wireless AirCard 880 */ | ||
114 | { USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */ | ||
115 | { USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880 E */ | ||
116 | { USB_DEVICE(0x1199, 0x6853) }, /* Sierra Wireless AirCard 881 E */ | ||
45 | 117 | ||
46 | { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */ | 118 | { USB_DEVICE(0x1199, 0x0112), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 580 */ |
47 | { USB_DEVICE(0x0F3D, 0x0112) }, /* AirPrime/Sierra PC 5220 */ | 119 | { USB_DEVICE(0x0F3D, 0x0112), .driver_info = DEVICE_1_PORT }, /* Airprime/Sierra PC 5220 */ |
120 | |||
121 | { USB_DEVICE(0x1199, 0x0FFF), .driver_info = DEVICE_INSTALLER}, | ||
48 | { } | 122 | { } |
49 | }; | 123 | }; |
50 | MODULE_DEVICE_TABLE(usb, id_table); | 124 | MODULE_DEVICE_TABLE(usb, id_table); |
@@ -58,35 +132,36 @@ static struct usb_device_id id_table_1port [] = { | |||
58 | static struct usb_device_id id_table_3port [] = { | 132 | static struct usb_device_id id_table_3port [] = { |
59 | { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ | 133 | { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ |
60 | { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ | 134 | { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ |
135 | { USB_DEVICE(0x0f30, 0x1b1d) }, /* Sierra Wireless MC5720 */ | ||
61 | { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ | 136 | { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ |
62 | { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ | 137 | { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ |
63 | { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ | 138 | { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ |
64 | { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless AirCard 595U */ | ||
65 | { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ | 139 | { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ |
140 | { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U*/ | ||
141 | |||
66 | { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ | 142 | { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ |
67 | { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ | 143 | { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ |
68 | { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ | 144 | { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ |
69 | { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */ | 145 | { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */ |
70 | { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ | 146 | { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ |
147 | { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780*/ | ||
148 | { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781*/ | ||
149 | { USB_DEVICE(0x1199, 0x6850) }, /* Sierra Wireless AirCard 880 */ | ||
150 | { USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */ | ||
151 | { USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880E */ | ||
152 | { USB_DEVICE(0x1199, 0x6853) }, /* Sierra Wireless AirCard 881E */ | ||
71 | { } | 153 | { } |
72 | }; | 154 | }; |
73 | 155 | ||
74 | static struct usb_driver sierra_driver = { | 156 | static struct usb_driver sierra_driver = { |
75 | .name = "sierra", | 157 | .name = "sierra", |
76 | .probe = usb_serial_probe, | 158 | .probe = sierra_probe, |
77 | .disconnect = usb_serial_disconnect, | 159 | .disconnect = usb_serial_disconnect, |
78 | .id_table = id_table, | 160 | .id_table = id_table, |
79 | .no_dynamic_id = 1, | 161 | .no_dynamic_id = 1, |
80 | }; | 162 | }; |
81 | 163 | ||
82 | 164 | ||
83 | static int debug; | ||
84 | |||
85 | /* per port private data */ | ||
86 | #define N_IN_URB 4 | ||
87 | #define N_OUT_URB 4 | ||
88 | #define IN_BUFLEN 4096 | ||
89 | |||
90 | struct sierra_port_private { | 165 | struct sierra_port_private { |
91 | spinlock_t lock; /* lock the structure */ | 166 | spinlock_t lock; /* lock the structure */ |
92 | int outstanding_urbs; /* number of out urbs in flight */ | 167 | int outstanding_urbs; /* number of out urbs in flight */ |
@@ -421,7 +496,6 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp) | |||
421 | int i; | 496 | int i; |
422 | struct urb *urb; | 497 | struct urb *urb; |
423 | int result; | 498 | int result; |
424 | __u16 set_mode_dzero = 0x0000; | ||
425 | 499 | ||
426 | portdata = usb_get_serial_port_data(port); | 500 | portdata = usb_get_serial_port_data(port); |
427 | 501 | ||
@@ -457,12 +531,6 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp) | |||
457 | 531 | ||
458 | port->tty->low_latency = 1; | 532 | port->tty->low_latency = 1; |
459 | 533 | ||
460 | /* set mode to D0 */ | ||
461 | result = usb_control_msg(serial->dev, | ||
462 | usb_rcvctrlpipe(serial->dev, 0), | ||
463 | 0x00, 0x40, set_mode_dzero, 0, NULL, | ||
464 | 0, USB_CTRL_SET_TIMEOUT); | ||
465 | |||
466 | sierra_send_setup(port); | 534 | sierra_send_setup(port); |
467 | 535 | ||
468 | /* start up the interrupt endpoint if we have one */ | 536 | /* start up the interrupt endpoint if we have one */ |
@@ -510,6 +578,9 @@ static int sierra_startup(struct usb_serial *serial) | |||
510 | 578 | ||
511 | dbg("%s", __FUNCTION__); | 579 | dbg("%s", __FUNCTION__); |
512 | 580 | ||
581 | /*Set Device mode to D0 */ | ||
582 | sierra_set_power_state(serial->dev, 0x0000); | ||
583 | |||
513 | /* Now setup per port private data */ | 584 | /* Now setup per port private data */ |
514 | for (i = 0; i < serial->num_ports; i++) { | 585 | for (i = 0; i < serial->num_ports; i++) { |
515 | port = serial->port[i]; | 586 | port = serial->port[i]; |
diff --git a/drivers/usb/storage/dpcm.c b/drivers/usb/storage/dpcm.c index 1628cb258562..9a410b5a6e5b 100644 --- a/drivers/usb/storage/dpcm.c +++ b/drivers/usb/storage/dpcm.c | |||
@@ -46,43 +46,43 @@ | |||
46 | */ | 46 | */ |
47 | int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us) | 47 | int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us) |
48 | { | 48 | { |
49 | int ret; | 49 | int ret; |
50 | 50 | ||
51 | if(srb == NULL) | 51 | if (srb == NULL) |
52 | return USB_STOR_TRANSPORT_ERROR; | 52 | return USB_STOR_TRANSPORT_ERROR; |
53 | 53 | ||
54 | US_DEBUGP("dpcm_transport: LUN=%d\n", srb->device->lun); | 54 | US_DEBUGP("dpcm_transport: LUN=%d\n", srb->device->lun); |
55 | 55 | ||
56 | switch(srb->device->lun) { | 56 | switch (srb->device->lun) { |
57 | case 0: | 57 | case 0: |
58 | 58 | ||
59 | /* | 59 | /* |
60 | * LUN 0 corresponds to the CompactFlash card reader. | 60 | * LUN 0 corresponds to the CompactFlash card reader. |
61 | */ | 61 | */ |
62 | ret = usb_stor_CB_transport(srb, us); | 62 | ret = usb_stor_CB_transport(srb, us); |
63 | break; | 63 | break; |
64 | 64 | ||
65 | #ifdef CONFIG_USB_STORAGE_SDDR09 | 65 | #ifdef CONFIG_USB_STORAGE_SDDR09 |
66 | case 1: | 66 | case 1: |
67 | 67 | ||
68 | /* | 68 | /* |
69 | * LUN 1 corresponds to the SmartMedia card reader. | 69 | * LUN 1 corresponds to the SmartMedia card reader. |
70 | */ | 70 | */ |
71 | 71 | ||
72 | /* | 72 | /* |
73 | * Set the LUN to 0 (just in case). | 73 | * Set the LUN to 0 (just in case). |
74 | */ | 74 | */ |
75 | srb->device->lun = 0; us->srb->device->lun = 0; | 75 | srb->device->lun = 0; us->srb->device->lun = 0; |
76 | ret = sddr09_transport(srb, us); | 76 | ret = sddr09_transport(srb, us); |
77 | srb->device->lun = 1; us->srb->device->lun = 1; | 77 | srb->device->lun = 1; us->srb->device->lun = 1; |
78 | break; | 78 | break; |
79 | 79 | ||
80 | #endif | 80 | #endif |
81 | 81 | ||
82 | default: | 82 | default: |
83 | US_DEBUGP("dpcm_transport: Invalid LUN %d\n", srb->device->lun); | 83 | US_DEBUGP("dpcm_transport: Invalid LUN %d\n", srb->device->lun); |
84 | ret = USB_STOR_TRANSPORT_ERROR; | 84 | ret = USB_STOR_TRANSPORT_ERROR; |
85 | break; | 85 | break; |
86 | } | 86 | } |
87 | return ret; | 87 | return ret; |
88 | } | 88 | } |
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c index d35369392fed..dfd42fe9e5f0 100644 --- a/drivers/usb/storage/onetouch.c +++ b/drivers/usb/storage/onetouch.c | |||
@@ -57,9 +57,10 @@ static void usb_onetouch_irq(struct urb *urb) | |||
57 | struct usb_onetouch *onetouch = urb->context; | 57 | struct usb_onetouch *onetouch = urb->context; |
58 | signed char *data = onetouch->data; | 58 | signed char *data = onetouch->data; |
59 | struct input_dev *dev = onetouch->dev; | 59 | struct input_dev *dev = onetouch->dev; |
60 | int status; | 60 | int status = urb->status; |
61 | int retval; | ||
61 | 62 | ||
62 | switch (urb->status) { | 63 | switch (status) { |
63 | case 0: /* success */ | 64 | case 0: /* success */ |
64 | break; | 65 | break; |
65 | case -ECONNRESET: /* unlink */ | 66 | case -ECONNRESET: /* unlink */ |
@@ -75,11 +76,11 @@ static void usb_onetouch_irq(struct urb *urb) | |||
75 | input_sync(dev); | 76 | input_sync(dev); |
76 | 77 | ||
77 | resubmit: | 78 | resubmit: |
78 | status = usb_submit_urb (urb, GFP_ATOMIC); | 79 | retval = usb_submit_urb (urb, GFP_ATOMIC); |
79 | if (status) | 80 | if (retval) |
80 | err ("can't resubmit intr, %s-%s/input0, status %d", | 81 | err ("can't resubmit intr, %s-%s/input0, retval %d", |
81 | onetouch->udev->bus->bus_name, | 82 | onetouch->udev->bus->bus_name, |
82 | onetouch->udev->devpath, status); | 83 | onetouch->udev->devpath, retval); |
83 | } | 84 | } |
84 | 85 | ||
85 | static int usb_onetouch_open(struct input_dev *dev) | 86 | static int usb_onetouch_open(struct input_dev *dev) |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index b6bf31a97b60..a624e72f81dc 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -313,6 +313,13 @@ UNUSUAL_DEV( 0x04b0, 0x0301, 0x0010, 0x0010, | |||
313 | US_SC_DEVICE, US_PR_DEVICE,NULL, | 313 | US_SC_DEVICE, US_PR_DEVICE,NULL, |
314 | US_FL_NOT_LOCKABLE ), | 314 | US_FL_NOT_LOCKABLE ), |
315 | 315 | ||
316 | /* Reported by Stefan de Konink <skinkie@xs4all.nl> */ | ||
317 | UNUSUAL_DEV( 0x04b0, 0x0401, 0x0200, 0x0200, | ||
318 | "NIKON", | ||
319 | "NIKON DSC D100", | ||
320 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
321 | US_FL_FIX_CAPACITY), | ||
322 | |||
316 | /* Reported by Andreas Bockhold <andreas@bockionline.de> */ | 323 | /* Reported by Andreas Bockhold <andreas@bockionline.de> */ |
317 | UNUSUAL_DEV( 0x04b0, 0x0405, 0x0100, 0x0100, | 324 | UNUSUAL_DEV( 0x04b0, 0x0405, 0x0100, 0x0100, |
318 | "NIKON", | 325 | "NIKON", |
@@ -1384,6 +1391,17 @@ UNUSUAL_DEV( 0x1019, 0x0c55, 0x0000, 0x0110, | |||
1384 | US_SC_DEVICE, US_PR_DEVICE, usb_stor_ucr61s2b_init, | 1391 | US_SC_DEVICE, US_PR_DEVICE, usb_stor_ucr61s2b_init, |
1385 | 0 ), | 1392 | 0 ), |
1386 | 1393 | ||
1394 | /* Reported by Kevin Lloyd <linux@sierrawireless.com> | ||
1395 | * Entry is needed for the initializer function override, | ||
1396 | * which instructs the device to load as a modem | ||
1397 | * device. | ||
1398 | */ | ||
1399 | UNUSUAL_DEV( 0x1199, 0x0fff, 0x0000, 0x9999, | ||
1400 | "Sierra Wireless", | ||
1401 | "USB MMC Storage", | ||
1402 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1403 | US_FL_IGNORE_DEVICE), | ||
1404 | |||
1387 | /* Reported by Jaco Kroon <jaco@kroon.co.za> | 1405 | /* Reported by Jaco Kroon <jaco@kroon.co.za> |
1388 | * The usb-storage module found on the Digitech GNX4 (and supposedly other | 1406 | * The usb-storage module found on the Digitech GNX4 (and supposedly other |
1389 | * devices) misbehaves and causes a bunch of invalid I/O errors. | 1407 | * devices) misbehaves and causes a bunch of invalid I/O errors. |
diff --git a/drivers/video/backlight/cr_bllcd.c b/drivers/video/backlight/cr_bllcd.c index e9bbc3455c94..1b3f6586bc9f 100644 --- a/drivers/video/backlight/cr_bllcd.c +++ b/drivers/video/backlight/cr_bllcd.c | |||
@@ -174,7 +174,7 @@ static int cr_backlight_probe(struct platform_device *pdev) | |||
174 | struct cr_panel *crp; | 174 | struct cr_panel *crp; |
175 | u8 dev_en; | 175 | u8 dev_en; |
176 | 176 | ||
177 | crp = kzalloc(sizeof(crp), GFP_KERNEL); | 177 | crp = kzalloc(sizeof(*crp), GFP_KERNEL); |
178 | if (crp == NULL) | 178 | if (crp == NULL) |
179 | return -ENOMEM; | 179 | return -ENOMEM; |
180 | 180 | ||
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c index 1b36f45076ad..8ccee9ee1d9d 100644 --- a/fs/afs/rxrpc.c +++ b/fs/afs/rxrpc.c | |||
@@ -792,6 +792,7 @@ void afs_send_simple_reply(struct afs_call *call, const void *buf, size_t len) | |||
792 | { | 792 | { |
793 | struct msghdr msg; | 793 | struct msghdr msg; |
794 | struct iovec iov[1]; | 794 | struct iovec iov[1]; |
795 | int n; | ||
795 | 796 | ||
796 | _enter(""); | 797 | _enter(""); |
797 | 798 | ||
@@ -806,22 +807,20 @@ void afs_send_simple_reply(struct afs_call *call, const void *buf, size_t len) | |||
806 | msg.msg_flags = 0; | 807 | msg.msg_flags = 0; |
807 | 808 | ||
808 | call->state = AFS_CALL_AWAIT_ACK; | 809 | call->state = AFS_CALL_AWAIT_ACK; |
809 | switch (rxrpc_kernel_send_data(call->rxcall, &msg, len)) { | 810 | n = rxrpc_kernel_send_data(call->rxcall, &msg, len); |
810 | case 0: | 811 | if (n >= 0) { |
811 | _leave(" [replied]"); | 812 | _leave(" [replied]"); |
812 | return; | 813 | return; |
813 | 814 | } | |
814 | case -ENOMEM: | 815 | if (n == -ENOMEM) { |
815 | _debug("oom"); | 816 | _debug("oom"); |
816 | rxrpc_kernel_abort_call(call->rxcall, RX_USER_ABORT); | 817 | rxrpc_kernel_abort_call(call->rxcall, RX_USER_ABORT); |
817 | default: | ||
818 | rxrpc_kernel_end_call(call->rxcall); | ||
819 | call->rxcall = NULL; | ||
820 | call->type->destructor(call); | ||
821 | afs_free_call(call); | ||
822 | _leave(" [error]"); | ||
823 | return; | ||
824 | } | 818 | } |
819 | rxrpc_kernel_end_call(call->rxcall); | ||
820 | call->rxcall = NULL; | ||
821 | call->type->destructor(call); | ||
822 | afs_free_call(call); | ||
823 | _leave(" [error]"); | ||
825 | } | 824 | } |
826 | 825 | ||
827 | /* | 826 | /* |
diff --git a/fs/buffer.c b/fs/buffer.c index 02ebb1f1d3b0..0e5ec371ce72 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -2221,7 +2221,7 @@ block_page_mkwrite(struct vm_area_struct *vma, struct page *page, | |||
2221 | lock_page(page); | 2221 | lock_page(page); |
2222 | size = i_size_read(inode); | 2222 | size = i_size_read(inode); |
2223 | if ((page->mapping != inode->i_mapping) || | 2223 | if ((page->mapping != inode->i_mapping) || |
2224 | ((page->index << PAGE_CACHE_SHIFT) > size)) { | 2224 | (page_offset(page) > size)) { |
2225 | /* page got truncated out from underneath us */ | 2225 | /* page got truncated out from underneath us */ |
2226 | goto out_unlock; | 2226 | goto out_unlock; |
2227 | } | 2227 | } |
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index 7d5a43cb0d5c..e4ab7bc14efe 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c | |||
@@ -409,8 +409,7 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page, | |||
409 | if (!PageUptodate(page)) | 409 | if (!PageUptodate(page)) |
410 | rc = ecryptfs_do_readpage(file, page, page->index); | 410 | rc = ecryptfs_do_readpage(file, page, page->index); |
411 | if (page->index != 0) { | 411 | if (page->index != 0) { |
412 | loff_t end_of_prev_pg_pos = | 412 | loff_t end_of_prev_pg_pos = page_offset(page) - 1; |
413 | (((loff_t)page->index << PAGE_CACHE_SHIFT) - 1); | ||
414 | 413 | ||
415 | if (end_of_prev_pg_pos > i_size_read(page->mapping->host)) { | 414 | if (end_of_prev_pg_pos > i_size_read(page->mapping->host)) { |
416 | rc = ecryptfs_truncate(file->f_path.dentry, | 415 | rc = ecryptfs_truncate(file->f_path.dentry, |
@@ -736,7 +735,7 @@ static int ecryptfs_commit_write(struct file *file, struct page *page, | |||
736 | goto out; | 735 | goto out; |
737 | } | 736 | } |
738 | inode->i_blocks = lower_inode->i_blocks; | 737 | inode->i_blocks = lower_inode->i_blocks; |
739 | pos = (page->index << PAGE_CACHE_SHIFT) + to; | 738 | pos = page_offset(page) + to; |
740 | if (pos > i_size_read(inode)) { | 739 | if (pos > i_size_read(inode)) { |
741 | i_size_write(inode, pos); | 740 | i_size_write(inode, pos); |
742 | ecryptfs_printk(KERN_DEBUG, "Expanded file size to " | 741 | ecryptfs_printk(KERN_DEBUG, "Expanded file size to " |
diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c index ee64749e2eeb..98756156d298 100644 --- a/fs/ocfs2/mmap.c +++ b/fs/ocfs2/mmap.c | |||
@@ -89,7 +89,7 @@ static int __ocfs2_page_mkwrite(struct inode *inode, struct buffer_head *di_bh, | |||
89 | { | 89 | { |
90 | int ret; | 90 | int ret; |
91 | struct address_space *mapping = inode->i_mapping; | 91 | struct address_space *mapping = inode->i_mapping; |
92 | loff_t pos = page->index << PAGE_CACHE_SHIFT; | 92 | loff_t pos = page_offset(page); |
93 | unsigned int len = PAGE_CACHE_SIZE; | 93 | unsigned int len = PAGE_CACHE_SIZE; |
94 | pgoff_t last_index; | 94 | pgoff_t last_index; |
95 | struct page *locked_page = NULL; | 95 | struct page *locked_page = NULL; |
diff --git a/fs/splice.c b/fs/splice.c index 22496d2a73fa..0a0973218084 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -594,7 +594,7 @@ find_page: | |||
594 | ret = add_to_page_cache_lru(page, mapping, index, | 594 | ret = add_to_page_cache_lru(page, mapping, index, |
595 | GFP_KERNEL); | 595 | GFP_KERNEL); |
596 | if (unlikely(ret)) | 596 | if (unlikely(ret)) |
597 | goto out; | 597 | goto out_release; |
598 | } | 598 | } |
599 | 599 | ||
600 | ret = mapping->a_ops->prepare_write(file, page, offset, offset+this_len); | 600 | ret = mapping->a_ops->prepare_write(file, page, offset, offset+this_len); |
@@ -650,8 +650,9 @@ find_page: | |||
650 | */ | 650 | */ |
651 | mark_page_accessed(page); | 651 | mark_page_accessed(page); |
652 | out: | 652 | out: |
653 | page_cache_release(page); | ||
654 | unlock_page(page); | 653 | unlock_page(page); |
654 | out_release: | ||
655 | page_cache_release(page); | ||
655 | out_ret: | 656 | out_ret: |
656 | return ret; | 657 | return ret; |
657 | } | 658 | } |
diff --git a/include/asm-m68k/io.h b/include/asm-m68k/io.h index 5e0fcf41804d..47bb9cf107b7 100644 --- a/include/asm-m68k/io.h +++ b/include/asm-m68k/io.h | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <asm/raw_io.h> | 27 | #include <asm/raw_io.h> |
28 | #include <asm/virtconvert.h> | 28 | #include <asm/virtconvert.h> |
29 | 29 | ||
30 | #include <asm-generic/iomap.h> | ||
30 | 31 | ||
31 | #ifdef CONFIG_ATARI | 32 | #ifdef CONFIG_ATARI |
32 | #include <asm/atarihw.h> | 33 | #include <asm/atarihw.h> |
@@ -152,6 +153,16 @@ static inline u16 __iomem *isa_itw(unsigned long addr) | |||
152 | default: return NULL; /* avoid warnings, just in case */ | 153 | default: return NULL; /* avoid warnings, just in case */ |
153 | } | 154 | } |
154 | } | 155 | } |
156 | static inline u32 __iomem *isa_itl(unsigned long addr) | ||
157 | { | ||
158 | switch(ISA_TYPE) | ||
159 | { | ||
160 | #ifdef CONFIG_AMIGA_PCMCIA | ||
161 | case AG_ISA: return (u32 __iomem *)AG_ISA_IO_W(addr); | ||
162 | #endif | ||
163 | default: return 0; /* avoid warnings, just in case */ | ||
164 | } | ||
165 | } | ||
155 | static inline u8 __iomem *isa_mtb(unsigned long addr) | 166 | static inline u8 __iomem *isa_mtb(unsigned long addr) |
156 | { | 167 | { |
157 | switch(ISA_TYPE) | 168 | switch(ISA_TYPE) |
@@ -188,8 +199,10 @@ static inline u16 __iomem *isa_mtw(unsigned long addr) | |||
188 | 199 | ||
189 | #define isa_inb(port) in_8(isa_itb(port)) | 200 | #define isa_inb(port) in_8(isa_itb(port)) |
190 | #define isa_inw(port) (ISA_SEX ? in_be16(isa_itw(port)) : in_le16(isa_itw(port))) | 201 | #define isa_inw(port) (ISA_SEX ? in_be16(isa_itw(port)) : in_le16(isa_itw(port))) |
202 | #define isa_inl(port) (ISA_SEX ? in_be32(isa_itl(port)) : in_le32(isa_itl(port))) | ||
191 | #define isa_outb(val,port) out_8(isa_itb(port),(val)) | 203 | #define isa_outb(val,port) out_8(isa_itb(port),(val)) |
192 | #define isa_outw(val,port) (ISA_SEX ? out_be16(isa_itw(port),(val)) : out_le16(isa_itw(port),(val))) | 204 | #define isa_outw(val,port) (ISA_SEX ? out_be16(isa_itw(port),(val)) : out_le16(isa_itw(port),(val))) |
205 | #define isa_outl(val,port) (ISA_SEX ? out_be32(isa_itl(port),(val)) : out_le32(isa_itl(port),(val))) | ||
193 | 206 | ||
194 | #define isa_readb(p) in_8(isa_mtb((unsigned long)(p))) | 207 | #define isa_readb(p) in_8(isa_mtb((unsigned long)(p))) |
195 | #define isa_readw(p) \ | 208 | #define isa_readw(p) \ |
@@ -234,6 +247,15 @@ static inline void isa_delay(void) | |||
234 | #define isa_outsw(port, buf, nr) \ | 247 | #define isa_outsw(port, buf, nr) \ |
235 | (ISA_SEX ? raw_outsw(isa_itw(port), (u16 *)(buf), (nr)) : \ | 248 | (ISA_SEX ? raw_outsw(isa_itw(port), (u16 *)(buf), (nr)) : \ |
236 | raw_outsw_swapw(isa_itw(port), (u16 *)(buf), (nr))) | 249 | raw_outsw_swapw(isa_itw(port), (u16 *)(buf), (nr))) |
250 | |||
251 | #define isa_insl(port, buf, nr) \ | ||
252 | (ISA_SEX ? raw_insl(isa_itl(port), (u32 *)(buf), (nr)) : \ | ||
253 | raw_insw_swapw(isa_itw(port), (u16 *)(buf), (nr)<<1)) | ||
254 | |||
255 | #define isa_outsl(port, buf, nr) \ | ||
256 | (ISA_SEX ? raw_outsl(isa_itl(port), (u32 *)(buf), (nr)) : \ | ||
257 | raw_outsw_swapw(isa_itw(port), (u16 *)(buf), (nr)<<1)) | ||
258 | |||
237 | #endif /* CONFIG_ISA */ | 259 | #endif /* CONFIG_ISA */ |
238 | 260 | ||
239 | 261 | ||
@@ -246,14 +268,16 @@ static inline void isa_delay(void) | |||
246 | #define inw_p isa_inw_p | 268 | #define inw_p isa_inw_p |
247 | #define outw isa_outw | 269 | #define outw isa_outw |
248 | #define outw_p isa_outw_p | 270 | #define outw_p isa_outw_p |
249 | #define inl isa_inw | 271 | #define inl isa_inl |
250 | #define inl_p isa_inw_p | 272 | #define inl_p isa_inl_p |
251 | #define outl isa_outw | 273 | #define outl isa_outl |
252 | #define outl_p isa_outw_p | 274 | #define outl_p isa_outl_p |
253 | #define insb isa_insb | 275 | #define insb isa_insb |
254 | #define insw isa_insw | 276 | #define insw isa_insw |
277 | #define insl isa_insl | ||
255 | #define outsb isa_outsb | 278 | #define outsb isa_outsb |
256 | #define outsw isa_outsw | 279 | #define outsw isa_outsw |
280 | #define outsl isa_outsl | ||
257 | #define readb isa_readb | 281 | #define readb isa_readb |
258 | #define readw isa_readw | 282 | #define readw isa_readw |
259 | #define writeb isa_writeb | 283 | #define writeb isa_writeb |
@@ -262,8 +286,6 @@ static inline void isa_delay(void) | |||
262 | 286 | ||
263 | #if defined(CONFIG_PCI) | 287 | #if defined(CONFIG_PCI) |
264 | 288 | ||
265 | #define inl(port) in_le32(port) | ||
266 | #define outl(val,port) out_le32((port),(val)) | ||
267 | #define readl(addr) in_le32(addr) | 289 | #define readl(addr) in_le32(addr) |
268 | #define writel(val,addr) out_le32((addr),(val)) | 290 | #define writel(val,addr) out_le32((addr),(val)) |
269 | 291 | ||
@@ -282,6 +304,8 @@ static inline void isa_delay(void) | |||
282 | #define outb(val,port) out_8((port),(val)) | 304 | #define outb(val,port) out_8((port),(val)) |
283 | #define inw(port) in_le16(port) | 305 | #define inw(port) in_le16(port) |
284 | #define outw(val,port) out_le16((port),(val)) | 306 | #define outw(val,port) out_le16((port),(val)) |
307 | #define inl(port) in_le32(port) | ||
308 | #define outl(val,port) out_le32((port),(val)) | ||
285 | 309 | ||
286 | #else | 310 | #else |
287 | /* | 311 | /* |
@@ -306,20 +330,35 @@ static inline void isa_delay(void) | |||
306 | #endif | 330 | #endif |
307 | #endif /* CONFIG_PCI */ | 331 | #endif /* CONFIG_PCI */ |
308 | 332 | ||
309 | #if !defined(CONFIG_ISA) && !defined(CONFIG_PCI) && defined(CONFIG_HP300) | 333 | #if !defined(CONFIG_ISA) && !defined(CONFIG_PCI) |
310 | /* | 334 | /* |
311 | * We need to define dummy functions otherwise drivers/serial/8250.c doesn't link | 335 | * We need to define dummy functions for GENERIC_IOMAP support. |
312 | */ | 336 | */ |
313 | #define inb(port) 0xff | 337 | #define inb(port) 0xff |
314 | #define inb_p(port) 0xff | 338 | #define inb_p(port) 0xff |
315 | #define outb(val,port) do { } while (0) | 339 | #define outb(val,port) ((void)0) |
316 | #define outb_p(val,port) do { } while (0) | 340 | #define outb_p(val,port) ((void)0) |
341 | #define inw(port) 0xffff | ||
342 | #define outw(val,port) ((void)0) | ||
343 | #define inl(port) 0xffffffffUL | ||
344 | #define outl(val,port) ((void)0) | ||
345 | |||
346 | #define insb(port,buf,nr) ((void)0) | ||
347 | #define outsb(port,buf,nr) ((void)0) | ||
348 | #define insw(port,buf,nr) ((void)0) | ||
349 | #define outsw(port,buf,nr) ((void)0) | ||
350 | #define insl(port,buf,nr) ((void)0) | ||
351 | #define outsl(port,buf,nr) ((void)0) | ||
317 | 352 | ||
318 | /* | 353 | /* |
319 | * These should be valid on any ioremap()ed region | 354 | * These should be valid on any ioremap()ed region |
320 | */ | 355 | */ |
321 | #define readb(addr) in_8(addr) | 356 | #define readb(addr) in_8(addr) |
322 | #define writeb(val,addr) out_8((addr),(val)) | 357 | #define writeb(val,addr) out_8((addr),(val)) |
358 | #define readw(addr) in_le16(addr) | ||
359 | #define writew(val,addr) out_le16((addr),(val)) | ||
360 | #endif | ||
361 | #if !defined(CONFIG_PCI) | ||
323 | #define readl(addr) in_le32(addr) | 362 | #define readl(addr) in_le32(addr) |
324 | #define writel(val,addr) out_le32((addr),(val)) | 363 | #define writel(val,addr) out_le32((addr),(val)) |
325 | #endif | 364 | #endif |
@@ -351,6 +390,18 @@ extern void dma_cache_wback_inv(unsigned long start, unsigned long size); | |||
351 | extern void dma_cache_wback(unsigned long start, unsigned long size); | 390 | extern void dma_cache_wback(unsigned long start, unsigned long size); |
352 | extern void dma_cache_inv(unsigned long start, unsigned long size); | 391 | extern void dma_cache_inv(unsigned long start, unsigned long size); |
353 | 392 | ||
393 | static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count) | ||
394 | { | ||
395 | __builtin_memset((void __force *) addr, val, count); | ||
396 | } | ||
397 | static inline void memcpy_fromio(void *dst, const volatile void __iomem *src, int count) | ||
398 | { | ||
399 | __builtin_memcpy(dst, (void __force *) src, count); | ||
400 | } | ||
401 | static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int count) | ||
402 | { | ||
403 | __builtin_memcpy((void __force *) dst, src, count); | ||
404 | } | ||
354 | 405 | ||
355 | #ifndef CONFIG_SUN3 | 406 | #ifndef CONFIG_SUN3 |
356 | #define IO_SPACE_LIMIT 0xffff | 407 | #define IO_SPACE_LIMIT 0xffff |
diff --git a/include/asm-m68k/raw_io.h b/include/asm-m68k/raw_io.h index 811ccd25d4a6..91c623f0994c 100644 --- a/include/asm-m68k/raw_io.h +++ b/include/asm-m68k/raw_io.h | |||
@@ -49,10 +49,16 @@ extern void __iounmap(void *addr, unsigned long size); | |||
49 | #define raw_inb in_8 | 49 | #define raw_inb in_8 |
50 | #define raw_inw in_be16 | 50 | #define raw_inw in_be16 |
51 | #define raw_inl in_be32 | 51 | #define raw_inl in_be32 |
52 | #define __raw_readb in_8 | ||
53 | #define __raw_readw in_be16 | ||
54 | #define __raw_readl in_be32 | ||
52 | 55 | ||
53 | #define raw_outb(val,port) out_8((port),(val)) | 56 | #define raw_outb(val,port) out_8((port),(val)) |
54 | #define raw_outw(val,port) out_be16((port),(val)) | 57 | #define raw_outw(val,port) out_be16((port),(val)) |
55 | #define raw_outl(val,port) out_be32((port),(val)) | 58 | #define raw_outl(val,port) out_be32((port),(val)) |
59 | #define __raw_writeb(val,addr) out_8((addr),(val)) | ||
60 | #define __raw_writew(val,addr) out_be16((addr),(val)) | ||
61 | #define __raw_writel(val,addr) out_be32((addr),(val)) | ||
56 | 62 | ||
57 | static inline void raw_insb(volatile u8 __iomem *port, u8 *buf, unsigned int len) | 63 | static inline void raw_insb(volatile u8 __iomem *port, u8 *buf, unsigned int len) |
58 | { | 64 | { |
@@ -336,8 +342,6 @@ static inline void raw_outsw_swapw(volatile u16 __iomem *port, const u16 *buf, | |||
336 | : "d0", "a0", "a1", "d6"); | 342 | : "d0", "a0", "a1", "d6"); |
337 | } | 343 | } |
338 | 344 | ||
339 | #define __raw_writel raw_outl | ||
340 | |||
341 | #endif /* __KERNEL__ */ | 345 | #endif /* __KERNEL__ */ |
342 | 346 | ||
343 | #endif /* _RAW_IO_H */ | 347 | #endif /* _RAW_IO_H */ |
diff --git a/include/asm-sh/clock.h b/include/asm-sh/clock.h index 386d797d86b7..b550a27a7042 100644 --- a/include/asm-sh/clock.h +++ b/include/asm-sh/clock.h | |||
@@ -14,6 +14,7 @@ struct clk_ops { | |||
14 | void (*disable)(struct clk *clk); | 14 | void (*disable)(struct clk *clk); |
15 | void (*recalc)(struct clk *clk); | 15 | void (*recalc)(struct clk *clk); |
16 | int (*set_rate)(struct clk *clk, unsigned long rate, int algo_id); | 16 | int (*set_rate)(struct clk *clk, unsigned long rate, int algo_id); |
17 | long (*round_rate)(struct clk *clk, unsigned long rate); | ||
17 | }; | 18 | }; |
18 | 19 | ||
19 | struct clk { | 20 | struct clk { |
diff --git a/include/asm-sh/hw_irq.h b/include/asm-sh/hw_irq.h index 4ca3f765bacc..20d42959f52a 100644 --- a/include/asm-sh/hw_irq.h +++ b/include/asm-sh/hw_irq.h | |||
@@ -1,6 +1,7 @@ | |||
1 | #ifndef __ASM_SH_HW_IRQ_H | 1 | #ifndef __ASM_SH_HW_IRQ_H |
2 | #define __ASM_SH_HW_IRQ_H | 2 | #define __ASM_SH_HW_IRQ_H |
3 | 3 | ||
4 | #include <linux/init.h> | ||
4 | #include <asm/atomic.h> | 5 | #include <asm/atomic.h> |
5 | 6 | ||
6 | extern atomic_t irq_err_count; | 7 | extern atomic_t irq_err_count; |
@@ -22,7 +23,6 @@ struct intc2_desc { | |||
22 | }; | 23 | }; |
23 | 24 | ||
24 | void register_intc2_controller(struct intc2_desc *); | 25 | void register_intc2_controller(struct intc2_desc *); |
25 | void init_IRQ_intc2(void); | ||
26 | 26 | ||
27 | struct ipr_data { | 27 | struct ipr_data { |
28 | unsigned char irq; | 28 | unsigned char irq; |
@@ -40,11 +40,82 @@ struct ipr_desc { | |||
40 | }; | 40 | }; |
41 | 41 | ||
42 | void register_ipr_controller(struct ipr_desc *); | 42 | void register_ipr_controller(struct ipr_desc *); |
43 | void init_IRQ_ipr(void); | ||
44 | 43 | ||
45 | /* | 44 | /* |
46 | * Enable individual interrupt mode for external IPR IRQs. | 45 | * Enable individual interrupt mode for external IPR IRQs. |
47 | */ | 46 | */ |
48 | void ipr_irq_enable_irlm(void); | 47 | void __init ipr_irq_enable_irlm(void); |
48 | |||
49 | typedef unsigned char intc_enum; | ||
50 | |||
51 | struct intc_vect { | ||
52 | intc_enum enum_id; | ||
53 | unsigned short vect; | ||
54 | }; | ||
55 | |||
56 | #define INTC_VECT(enum_id, vect) { enum_id, vect } | ||
57 | |||
58 | struct intc_prio { | ||
59 | intc_enum enum_id; | ||
60 | unsigned char priority; | ||
61 | }; | ||
62 | |||
63 | #define INTC_PRIO(enum_id, prio) { enum_id, prio } | ||
64 | |||
65 | struct intc_group { | ||
66 | intc_enum enum_id; | ||
67 | intc_enum *enum_ids; | ||
68 | }; | ||
69 | |||
70 | #define INTC_GROUP(enum_id, ids...) { enum_id, (intc_enum []) { ids, 0 } } | ||
71 | |||
72 | struct intc_mask_reg { | ||
73 | unsigned long set_reg, clr_reg, reg_width; | ||
74 | intc_enum enum_ids[32]; | ||
75 | }; | ||
76 | |||
77 | struct intc_prio_reg { | ||
78 | unsigned long reg, reg_width, field_width; | ||
79 | intc_enum enum_ids[16]; | ||
80 | }; | ||
81 | |||
82 | struct intc_sense_reg { | ||
83 | unsigned long reg, reg_width, field_width; | ||
84 | intc_enum enum_ids[16]; | ||
85 | }; | ||
86 | |||
87 | struct intc_desc { | ||
88 | struct intc_vect *vectors; | ||
89 | unsigned int nr_vectors; | ||
90 | struct intc_group *groups; | ||
91 | unsigned int nr_groups; | ||
92 | struct intc_prio *priorities; | ||
93 | unsigned int nr_priorities; | ||
94 | struct intc_mask_reg *mask_regs; | ||
95 | unsigned int nr_mask_regs; | ||
96 | struct intc_prio_reg *prio_regs; | ||
97 | unsigned int nr_prio_regs; | ||
98 | struct intc_sense_reg *sense_regs; | ||
99 | unsigned int nr_sense_regs; | ||
100 | struct irq_chip chip; | ||
101 | }; | ||
102 | |||
103 | #define _INTC_ARRAY(a) a, sizeof(a)/sizeof(*a) | ||
104 | #define DECLARE_INTC_DESC(symbol, chipname, vectors, groups, \ | ||
105 | priorities, mask_regs, prio_regs, sense_regs) \ | ||
106 | struct intc_desc symbol = { \ | ||
107 | _INTC_ARRAY(vectors), _INTC_ARRAY(groups), \ | ||
108 | _INTC_ARRAY(priorities), \ | ||
109 | _INTC_ARRAY(mask_regs), _INTC_ARRAY(prio_regs), \ | ||
110 | _INTC_ARRAY(sense_regs), \ | ||
111 | .chip.name = chipname, \ | ||
112 | } | ||
113 | |||
114 | void __init register_intc_controller(struct intc_desc *desc); | ||
115 | |||
116 | void __init plat_irq_setup(void); | ||
117 | |||
118 | enum { IRQ_MODE_IRQ, IRQ_MODE_IRL7654, IRQ_MODE_IRL3210 }; | ||
119 | void __init plat_irq_setup_pins(int mode); | ||
49 | 120 | ||
50 | #endif /* __ASM_SH_HW_IRQ_H */ | 121 | #endif /* __ASM_SH_HW_IRQ_H */ |
diff --git a/include/asm-sh/se7722.h b/include/asm-sh/se7722.h index b3b31e4725c6..e0e89fcb8388 100644 --- a/include/asm-sh/se7722.h +++ b/include/asm-sh/se7722.h | |||
@@ -81,36 +81,32 @@ | |||
81 | /* IRQ */ | 81 | /* IRQ */ |
82 | #define IRQ0_IRQ 32 | 82 | #define IRQ0_IRQ 32 |
83 | #define IRQ1_IRQ 33 | 83 | #define IRQ1_IRQ 33 |
84 | #define INTC_ICR0 0xA4140000UL | ||
85 | #define INTC_ICR1 0xA414001CUL | ||
86 | |||
87 | #define INTMSK0 0xa4140044 | ||
88 | #define INTMSKCLR0 0xa4140064 | ||
89 | #define INTC_INTPRI0 0xa4140010 | ||
90 | 84 | ||
91 | #define IRQ01_MODE 0xb1800000 | 85 | #define IRQ01_MODE 0xb1800000 |
92 | #define IRQ01_STS 0xb1800004 | 86 | #define IRQ01_STS 0xb1800004 |
93 | #define IRQ01_MASK 0xb1800008 | 87 | #define IRQ01_MASK 0xb1800008 |
94 | #define EXT_BIT (0x3fc0) /* SH IRQ1 */ | ||
95 | #define MRSHPC_BIT0 (0x0004) /* SH IRQ1 */ | ||
96 | #define MRSHPC_BIT1 (0x0008) /* SH IRQ1 */ | ||
97 | #define MRSHPC_BIT2 (0x0010) /* SH IRQ1 */ | ||
98 | #define MRSHPC_BIT3 (0x0020) /* SH IRQ1 */ | ||
99 | #define SMC_BIT (0x0002) /* SH IRQ0 */ | ||
100 | #define USB_BIT (0x0001) /* SH IRQ0 */ | ||
101 | |||
102 | #define MRSHPC_IRQ3 11 | ||
103 | #define MRSHPC_IRQ2 12 | ||
104 | #define MRSHPC_IRQ1 13 | ||
105 | #define MRSHPC_IRQ0 14 | ||
106 | #define SMC_IRQ 10 | ||
107 | #define EXT_IRQ 5 | ||
108 | #define USB_IRQ 6 | ||
109 | 88 | ||
89 | /* Bits in IRQ01_* registers */ | ||
90 | |||
91 | #define SE7722_FPGA_IRQ_USB 0 /* IRQ0 */ | ||
92 | #define SE7722_FPGA_IRQ_SMC 1 /* IRQ0 */ | ||
93 | #define SE7722_FPGA_IRQ_MRSHPC0 2 /* IRQ1 */ | ||
94 | #define SE7722_FPGA_IRQ_MRSHPC1 3 /* IRQ1 */ | ||
95 | #define SE7722_FPGA_IRQ_MRSHPC2 4 /* IRQ1 */ | ||
96 | #define SE7722_FPGA_IRQ_MRSHPC3 5 /* IRQ1 */ | ||
97 | |||
98 | #define SE7722_FPGA_IRQ_NR 6 | ||
99 | #define SE7722_FPGA_IRQ_BASE 110 | ||
100 | |||
101 | #define MRSHPC_IRQ3 (SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_MRSHPC3) | ||
102 | #define MRSHPC_IRQ2 (SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_MRSHPC2) | ||
103 | #define MRSHPC_IRQ1 (SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_MRSHPC1) | ||
104 | #define MRSHPC_IRQ0 (SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_MRSHPC0) | ||
105 | #define SMC_IRQ (SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_SMC) | ||
106 | #define USB_IRQ (SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_USB) | ||
110 | 107 | ||
111 | /* arch/sh/boards/se/7722/irq.c */ | 108 | /* arch/sh/boards/se/7722/irq.c */ |
112 | void init_se7722_IRQ(void); | 109 | void init_se7722_IRQ(void); |
113 | int se7722_irq_demux(int); | ||
114 | 110 | ||
115 | #define __IO_PREFIX se7722 | 111 | #define __IO_PREFIX se7722 |
116 | #include <asm/io_generic.h> | 112 | #include <asm/io_generic.h> |
diff --git a/include/asm-sh/unistd.h b/include/asm-sh/unistd.h index 77bcb09d6ac8..b182b1cb05fd 100644 --- a/include/asm-sh/unistd.h +++ b/include/asm-sh/unistd.h | |||
@@ -332,8 +332,9 @@ | |||
332 | #define __NR_signalfd 321 | 332 | #define __NR_signalfd 321 |
333 | #define __NR_timerfd 322 | 333 | #define __NR_timerfd 322 |
334 | #define __NR_eventfd 323 | 334 | #define __NR_eventfd 323 |
335 | #define __NR_fallocate 324 | ||
335 | 336 | ||
336 | #define NR_syscalls 324 | 337 | #define NR_syscalls 325 |
337 | 338 | ||
338 | #ifdef __KERNEL__ | 339 | #ifdef __KERNEL__ |
339 | 340 | ||
diff --git a/include/asm-sh64/unistd.h b/include/asm-sh64/unistd.h index ea3adc600b41..1a5197f369b2 100644 --- a/include/asm-sh64/unistd.h +++ b/include/asm-sh64/unistd.h | |||
@@ -374,10 +374,11 @@ | |||
374 | #define __NR_signalfd 349 | 374 | #define __NR_signalfd 349 |
375 | #define __NR_timerfd 350 | 375 | #define __NR_timerfd 350 |
376 | #define __NR_eventfd 351 | 376 | #define __NR_eventfd 351 |
377 | #define __NR_fallocate 352 | ||
377 | 378 | ||
378 | #ifdef __KERNEL__ | 379 | #ifdef __KERNEL__ |
379 | 380 | ||
380 | #define NR_syscalls 352 | 381 | #define NR_syscalls 353 |
381 | 382 | ||
382 | #define __ARCH_WANT_IPC_PARSE_VERSION | 383 | #define __ARCH_WANT_IPC_PARSE_VERSION |
383 | #define __ARCH_WANT_OLD_READDIR | 384 | #define __ARCH_WANT_OLD_READDIR |
diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h index 64471bcd96f9..029b3e0d5e4c 100644 --- a/include/asm-sparc/unistd.h +++ b/include/asm-sparc/unistd.h | |||
@@ -1,4 +1,3 @@ | |||
1 | /* $Id: unistd.h,v 1.74 2002/02/08 03:57:18 davem Exp $ */ | ||
2 | #ifndef _SPARC_UNISTD_H | 1 | #ifndef _SPARC_UNISTD_H |
3 | #define _SPARC_UNISTD_H | 2 | #define _SPARC_UNISTD_H |
4 | 3 | ||
@@ -9,7 +8,7 @@ | |||
9 | * think of right now to force the arguments into fixed registers | 8 | * think of right now to force the arguments into fixed registers |
10 | * before the trap into the system call with gcc 'asm' statements. | 9 | * before the trap into the system call with gcc 'asm' statements. |
11 | * | 10 | * |
12 | * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) | 11 | * Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net) |
13 | * | 12 | * |
14 | * SunOS compatibility based upon preliminary work which is: | 13 | * SunOS compatibility based upon preliminary work which is: |
15 | * | 14 | * |
@@ -330,8 +329,9 @@ | |||
330 | #define __NR_signalfd 311 | 329 | #define __NR_signalfd 311 |
331 | #define __NR_timerfd 312 | 330 | #define __NR_timerfd 312 |
332 | #define __NR_eventfd 313 | 331 | #define __NR_eventfd 313 |
332 | #define __NR_fallocate 314 | ||
333 | 333 | ||
334 | #define NR_SYSCALLS 314 | 334 | #define NR_SYSCALLS 315 |
335 | 335 | ||
336 | #ifdef __KERNEL__ | 336 | #ifdef __KERNEL__ |
337 | #define __ARCH_WANT_IPC_PARSE_VERSION | 337 | #define __ARCH_WANT_IPC_PARSE_VERSION |
diff --git a/include/asm-sparc64/power.h b/include/asm-sparc64/power.h deleted file mode 100644 index 94495c1ac4f6..000000000000 --- a/include/asm-sparc64/power.h +++ /dev/null | |||
@@ -1,7 +0,0 @@ | |||
1 | #ifndef _SPARC64_POWER_H | ||
2 | #define _SPARC64_POWER_H | ||
3 | |||
4 | extern void wake_up_powerd(void); | ||
5 | extern int start_powerd(void); | ||
6 | |||
7 | #endif /* !(_SPARC64_POWER_H) */ | ||
diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h index 53e96ed9c024..cb751b4d0f56 100644 --- a/include/asm-sparc64/unistd.h +++ b/include/asm-sparc64/unistd.h | |||
@@ -1,4 +1,3 @@ | |||
1 | /* $Id: unistd.h,v 1.50 2002/02/08 03:57:18 davem Exp $ */ | ||
2 | #ifndef _SPARC64_UNISTD_H | 1 | #ifndef _SPARC64_UNISTD_H |
3 | #define _SPARC64_UNISTD_H | 2 | #define _SPARC64_UNISTD_H |
4 | 3 | ||
@@ -9,7 +8,7 @@ | |||
9 | * think of right now to force the arguments into fixed registers | 8 | * think of right now to force the arguments into fixed registers |
10 | * before the trap into the system call with gcc 'asm' statements. | 9 | * before the trap into the system call with gcc 'asm' statements. |
11 | * | 10 | * |
12 | * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) | 11 | * Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net) |
13 | * | 12 | * |
14 | * SunOS compatibility based upon preliminary work which is: | 13 | * SunOS compatibility based upon preliminary work which is: |
15 | * | 14 | * |
@@ -332,8 +331,9 @@ | |||
332 | #define __NR_signalfd 311 | 331 | #define __NR_signalfd 311 |
333 | #define __NR_timerfd 312 | 332 | #define __NR_timerfd 312 |
334 | #define __NR_eventfd 313 | 333 | #define __NR_eventfd 313 |
334 | #define __NR_fallocate 314 | ||
335 | 335 | ||
336 | #define NR_SYSCALLS 314 | 336 | #define NR_SYSCALLS 315 |
337 | 337 | ||
338 | #ifdef __KERNEL__ | 338 | #ifdef __KERNEL__ |
339 | /* sysconf options, for SunOS compatibility */ | 339 | /* sysconf options, for SunOS compatibility */ |
diff --git a/include/asm-sparc64/vio.h b/include/asm-sparc64/vio.h index c0a8d4ed5bcb..f7417e91b170 100644 --- a/include/asm-sparc64/vio.h +++ b/include/asm-sparc64/vio.h | |||
@@ -275,6 +275,8 @@ struct vio_dev { | |||
275 | char compat[VIO_MAX_COMPAT_LEN]; | 275 | char compat[VIO_MAX_COMPAT_LEN]; |
276 | int compat_len; | 276 | int compat_len; |
277 | 277 | ||
278 | u64 dev_no; | ||
279 | |||
278 | unsigned long channel_id; | 280 | unsigned long channel_id; |
279 | 281 | ||
280 | unsigned int tx_irq; | 282 | unsigned int tx_irq; |
diff --git a/include/linux/async_tx.h b/include/linux/async_tx.h index ff1255079fa1..bdca3f1b3213 100644 --- a/include/linux/async_tx.h +++ b/include/linux/async_tx.h | |||
@@ -51,10 +51,6 @@ struct dma_chan_ref { | |||
51 | * @ASYNC_TX_ACK: immediately ack the descriptor, precludes setting up a | 51 | * @ASYNC_TX_ACK: immediately ack the descriptor, precludes setting up a |
52 | * dependency chain | 52 | * dependency chain |
53 | * @ASYNC_TX_DEP_ACK: ack the dependency descriptor. Useful for chaining. | 53 | * @ASYNC_TX_DEP_ACK: ack the dependency descriptor. Useful for chaining. |
54 | * @ASYNC_TX_KMAP_SRC: if the transaction is to be performed synchronously | ||
55 | * take an atomic mapping (KM_USER0) on the source page(s) | ||
56 | * @ASYNC_TX_KMAP_DST: if the transaction is to be performed synchronously | ||
57 | * take an atomic mapping (KM_USER0) on the dest page(s) | ||
58 | */ | 54 | */ |
59 | enum async_tx_flags { | 55 | enum async_tx_flags { |
60 | ASYNC_TX_XOR_ZERO_DST = (1 << 0), | 56 | ASYNC_TX_XOR_ZERO_DST = (1 << 0), |
@@ -62,8 +58,6 @@ enum async_tx_flags { | |||
62 | ASYNC_TX_ASSUME_COHERENT = (1 << 2), | 58 | ASYNC_TX_ASSUME_COHERENT = (1 << 2), |
63 | ASYNC_TX_ACK = (1 << 3), | 59 | ASYNC_TX_ACK = (1 << 3), |
64 | ASYNC_TX_DEP_ACK = (1 << 4), | 60 | ASYNC_TX_DEP_ACK = (1 << 4), |
65 | ASYNC_TX_KMAP_SRC = (1 << 5), | ||
66 | ASYNC_TX_KMAP_DST = (1 << 6), | ||
67 | }; | 61 | }; |
68 | 62 | ||
69 | #ifdef CONFIG_DMA_ENGINE | 63 | #ifdef CONFIG_DMA_ENGINE |
diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h index aa83d4163096..b69014865714 100644 --- a/include/linux/i2c-id.h +++ b/include/linux/i2c-id.h | |||
@@ -115,9 +115,10 @@ | |||
115 | #define I2C_DRIVERID_KS0127 86 /* Samsung ks0127 video decoder */ | 115 | #define I2C_DRIVERID_KS0127 86 /* Samsung ks0127 video decoder */ |
116 | #define I2C_DRIVERID_TLV320AIC23B 87 /* TI TLV320AIC23B audio codec */ | 116 | #define I2C_DRIVERID_TLV320AIC23B 87 /* TI TLV320AIC23B audio codec */ |
117 | #define I2C_DRIVERID_ISL1208 88 /* Intersil ISL1208 RTC */ | 117 | #define I2C_DRIVERID_ISL1208 88 /* Intersil ISL1208 RTC */ |
118 | #define I2C_DRIVERID_WM8731 89 /* Wolfson WM8731 audio codec */ | 118 | #define I2C_DRIVERID_WM8731 89 /* Wolfson WM8731 audio codec */ |
119 | #define I2C_DRIVERID_WM8750 90 /* Wolfson WM8750 audio codec */ | 119 | #define I2C_DRIVERID_WM8750 90 /* Wolfson WM8750 audio codec */ |
120 | #define I2C_DRIVERID_WM8753 91 /* Wolfson WM8753 audio codec */ | 120 | #define I2C_DRIVERID_WM8753 91 /* Wolfson WM8753 audio codec */ |
121 | #define I2C_DRIVERID_LM4857 92 /* LM4857 Audio Amplifier */ | ||
121 | 122 | ||
122 | #define I2C_DRIVERID_I2CDEV 900 | 123 | #define I2C_DRIVERID_I2CDEV 900 |
123 | #define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */ | 124 | #define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */ |
diff --git a/include/linux/input.h b/include/linux/input.h index 18c98b543030..e02c6a66b2ba 100644 --- a/include/linux/input.h +++ b/include/linux/input.h | |||
@@ -344,7 +344,8 @@ struct input_absinfo { | |||
344 | #define KEY_BRIGHTNESSUP 225 | 344 | #define KEY_BRIGHTNESSUP 225 |
345 | #define KEY_MEDIA 226 | 345 | #define KEY_MEDIA 226 |
346 | 346 | ||
347 | #define KEY_SWITCHVIDEOMODE 227 | 347 | #define KEY_SWITCHVIDEOMODE 227 /* Cycle between available video |
348 | outputs (Monitor/LCD/TV-out/etc) */ | ||
348 | #define KEY_KBDILLUMTOGGLE 228 | 349 | #define KEY_KBDILLUMTOGGLE 228 |
349 | #define KEY_KBDILLUMDOWN 229 | 350 | #define KEY_KBDILLUMDOWN 229 |
350 | #define KEY_KBDILLUMUP 230 | 351 | #define KEY_KBDILLUMUP 230 |
diff --git a/include/linux/ioprio.h b/include/linux/ioprio.h index 2eaa142cd061..baf29387cab4 100644 --- a/include/linux/ioprio.h +++ b/include/linux/ioprio.h | |||
@@ -53,6 +53,14 @@ static inline int task_ioprio(struct task_struct *task) | |||
53 | return IOPRIO_NORM; | 53 | return IOPRIO_NORM; |
54 | } | 54 | } |
55 | 55 | ||
56 | static inline int task_ioprio_class(struct task_struct *task) | ||
57 | { | ||
58 | if (ioprio_valid(task->ioprio)) | ||
59 | return IOPRIO_PRIO_CLASS(task->ioprio); | ||
60 | |||
61 | return IOPRIO_CLASS_BE; | ||
62 | } | ||
63 | |||
56 | static inline int task_nice_ioprio(struct task_struct *task) | 64 | static inline int task_nice_ioprio(struct task_struct *task) |
57 | { | 65 | { |
58 | return (task_nice(task) + 20) / 5; | 66 | return (task_nice(task) + 20) / 5; |
diff --git a/include/linux/libata.h b/include/linux/libata.h index 47cd2a1c5544..be5a43928c84 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -323,6 +323,7 @@ enum ata_completion_errors { | |||
323 | AC_ERR_INVALID = (1 << 7), /* invalid argument */ | 323 | AC_ERR_INVALID = (1 << 7), /* invalid argument */ |
324 | AC_ERR_OTHER = (1 << 8), /* unknown */ | 324 | AC_ERR_OTHER = (1 << 8), /* unknown */ |
325 | AC_ERR_NODEV_HINT = (1 << 9), /* polling device detection hint */ | 325 | AC_ERR_NODEV_HINT = (1 << 9), /* polling device detection hint */ |
326 | AC_ERR_NCQ = (1 << 10), /* marker for offending NCQ qc */ | ||
326 | }; | 327 | }; |
327 | 328 | ||
328 | /* forward declarations */ | 329 | /* forward declarations */ |
@@ -530,6 +531,7 @@ struct ata_port { | |||
530 | unsigned int cbl; /* cable type; ATA_CBL_xxx */ | 531 | unsigned int cbl; /* cable type; ATA_CBL_xxx */ |
531 | unsigned int hw_sata_spd_limit; | 532 | unsigned int hw_sata_spd_limit; |
532 | unsigned int sata_spd_limit; /* SATA PHY speed limit */ | 533 | unsigned int sata_spd_limit; /* SATA PHY speed limit */ |
534 | unsigned int sata_spd; /* current SATA PHY speed */ | ||
533 | 535 | ||
534 | /* record runtime error info, protected by host lock */ | 536 | /* record runtime error info, protected by host lock */ |
535 | struct ata_eh_info eh_info; | 537 | struct ata_eh_info eh_info; |
@@ -563,6 +565,9 @@ struct ata_port { | |||
563 | pm_message_t pm_mesg; | 565 | pm_message_t pm_mesg; |
564 | int *pm_result; | 566 | int *pm_result; |
565 | 567 | ||
568 | struct timer_list fastdrain_timer; | ||
569 | unsigned long fastdrain_cnt; | ||
570 | |||
566 | void *private_data; | 571 | void *private_data; |
567 | 572 | ||
568 | #ifdef CONFIG_ATA_ACPI | 573 | #ifdef CONFIG_ATA_ACPI |
@@ -619,9 +624,8 @@ struct ata_port_operations { | |||
619 | u8 (*irq_on) (struct ata_port *); | 624 | u8 (*irq_on) (struct ata_port *); |
620 | u8 (*irq_ack) (struct ata_port *ap, unsigned int chk_drq); | 625 | u8 (*irq_ack) (struct ata_port *ap, unsigned int chk_drq); |
621 | 626 | ||
622 | u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg); | 627 | int (*scr_read) (struct ata_port *ap, unsigned int sc_reg, u32 *val); |
623 | void (*scr_write) (struct ata_port *ap, unsigned int sc_reg, | 628 | int (*scr_write) (struct ata_port *ap, unsigned int sc_reg, u32 val); |
624 | u32 val); | ||
625 | 629 | ||
626 | int (*port_suspend) (struct ata_port *ap, pm_message_t mesg); | 630 | int (*port_suspend) (struct ata_port *ap, pm_message_t mesg); |
627 | int (*port_resume) (struct ata_port *ap); | 631 | int (*port_resume) (struct ata_port *ap); |
@@ -764,7 +768,8 @@ extern unsigned int ata_dev_try_classify(struct ata_port *, unsigned int, u8 *); | |||
764 | */ | 768 | */ |
765 | extern void ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf); | 769 | extern void ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf); |
766 | extern void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf); | 770 | extern void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf); |
767 | extern void ata_tf_to_fis(const struct ata_taskfile *tf, u8 *fis, u8 pmp); | 771 | extern void ata_tf_to_fis(const struct ata_taskfile *tf, |
772 | u8 pmp, int is_cmd, u8 *fis); | ||
768 | extern void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf); | 773 | extern void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf); |
769 | extern void ata_noop_dev_select (struct ata_port *ap, unsigned int device); | 774 | extern void ata_noop_dev_select (struct ata_port *ap, unsigned int device); |
770 | extern void ata_std_dev_select (struct ata_port *ap, unsigned int device); | 775 | extern void ata_std_dev_select (struct ata_port *ap, unsigned int device); |
@@ -909,27 +914,21 @@ extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset, | |||
909 | /* | 914 | /* |
910 | * ata_eh_info helpers | 915 | * ata_eh_info helpers |
911 | */ | 916 | */ |
912 | #define ata_ehi_push_desc(ehi, fmt, args...) do { \ | 917 | extern void __ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...); |
913 | (ehi)->desc_len += scnprintf((ehi)->desc + (ehi)->desc_len, \ | 918 | extern void ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...); |
914 | ATA_EH_DESC_LEN - (ehi)->desc_len, \ | 919 | extern void ata_ehi_clear_desc(struct ata_eh_info *ehi); |
915 | fmt , ##args); \ | 920 | |
916 | } while (0) | 921 | static inline void ata_ehi_schedule_probe(struct ata_eh_info *ehi) |
917 | |||
918 | #define ata_ehi_clear_desc(ehi) do { \ | ||
919 | (ehi)->desc[0] = '\0'; \ | ||
920 | (ehi)->desc_len = 0; \ | ||
921 | } while (0) | ||
922 | |||
923 | static inline void __ata_ehi_hotplugged(struct ata_eh_info *ehi) | ||
924 | { | 922 | { |
925 | ehi->flags |= ATA_EHI_HOTPLUGGED | ATA_EHI_RESUME_LINK; | 923 | ehi->flags |= ATA_EHI_RESUME_LINK; |
926 | ehi->action |= ATA_EH_SOFTRESET; | 924 | ehi->action |= ATA_EH_SOFTRESET; |
927 | ehi->probe_mask |= (1 << ATA_MAX_DEVICES) - 1; | 925 | ehi->probe_mask |= (1 << ATA_MAX_DEVICES) - 1; |
928 | } | 926 | } |
929 | 927 | ||
930 | static inline void ata_ehi_hotplugged(struct ata_eh_info *ehi) | 928 | static inline void ata_ehi_hotplugged(struct ata_eh_info *ehi) |
931 | { | 929 | { |
932 | __ata_ehi_hotplugged(ehi); | 930 | ata_ehi_schedule_probe(ehi); |
931 | ehi->flags |= ATA_EHI_HOTPLUGGED; | ||
933 | ehi->err_mask |= AC_ERR_ATA_BUS; | 932 | ehi->err_mask |= AC_ERR_ATA_BUS; |
934 | } | 933 | } |
935 | 934 | ||
diff --git a/include/linux/serio.h b/include/linux/serio.h index d9377ce9ffd1..9f3825014674 100644 --- a/include/linux/serio.h +++ b/include/linux/serio.h | |||
@@ -210,5 +210,6 @@ static inline void serio_unpin_driver(struct serio *serio) | |||
210 | #define SERIO_TOUCHRIGHT 0x32 | 210 | #define SERIO_TOUCHRIGHT 0x32 |
211 | #define SERIO_TOUCHWIN 0x33 | 211 | #define SERIO_TOUCHWIN 0x33 |
212 | #define SERIO_TAOSEVM 0x34 | 212 | #define SERIO_TAOSEVM 0x34 |
213 | #define SERIO_FUJITSU 0x35 | ||
213 | 214 | ||
214 | #endif | 215 | #endif |
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h index 07f7e4cbcee3..124270df8734 100644 --- a/include/linux/slub_def.h +++ b/include/linux/slub_def.h | |||
@@ -160,7 +160,7 @@ static inline struct kmem_cache *kmalloc_slab(size_t size) | |||
160 | #define SLUB_DMA __GFP_DMA | 160 | #define SLUB_DMA __GFP_DMA |
161 | #else | 161 | #else |
162 | /* Disable DMA functionality */ | 162 | /* Disable DMA functionality */ |
163 | #define SLUB_DMA 0 | 163 | #define SLUB_DMA (__force gfp_t)0 |
164 | #endif | 164 | #endif |
165 | 165 | ||
166 | void *kmem_cache_alloc(struct kmem_cache *, gfp_t); | 166 | void *kmem_cache_alloc(struct kmem_cache *, gfp_t); |
diff --git a/include/linux/spi/ads7846.h b/include/linux/spi/ads7846.h index 3387e44dfd13..334d31411629 100644 --- a/include/linux/spi/ads7846.h +++ b/include/linux/spi/ads7846.h | |||
@@ -16,6 +16,20 @@ struct ads7846_platform_data { | |||
16 | u16 vref_delay_usecs; /* 0 for external vref; etc */ | 16 | u16 vref_delay_usecs; /* 0 for external vref; etc */ |
17 | int keep_vref_on:1; /* set to keep vref on for differential | 17 | int keep_vref_on:1; /* set to keep vref on for differential |
18 | * measurements as well */ | 18 | * measurements as well */ |
19 | |||
20 | /* Settling time of the analog signals; a function of Vcc and the | ||
21 | * capacitance on the X/Y drivers. If set to non-zero, two samples | ||
22 | * are taken with settle_delay us apart, and the second one is used. | ||
23 | * ~150 uSec with 0.01uF caps. | ||
24 | */ | ||
25 | u16 settle_delay_usecs; | ||
26 | |||
27 | /* If set to non-zero, after samples are taken this delay is applied | ||
28 | * and penirq is rechecked, to help avoid false events. This value | ||
29 | * is affected by the material used to build the touch layer. | ||
30 | */ | ||
31 | u16 penirq_recheck_delay_usecs; | ||
32 | |||
19 | u16 x_plate_ohms; | 33 | u16 x_plate_ohms; |
20 | u16 y_plate_ohms; | 34 | u16 y_plate_ohms; |
21 | 35 | ||
diff --git a/include/sound/ak4xxx-adda.h b/include/sound/ak4xxx-adda.h index aa49dda4f410..fd0a6c46f497 100644 --- a/include/sound/ak4xxx-adda.h +++ b/include/sound/ak4xxx-adda.h | |||
@@ -43,6 +43,7 @@ struct snd_ak4xxx_ops { | |||
43 | struct snd_akm4xxx_dac_channel { | 43 | struct snd_akm4xxx_dac_channel { |
44 | char *name; /* mixer volume name */ | 44 | char *name; /* mixer volume name */ |
45 | unsigned int num_channels; | 45 | unsigned int num_channels; |
46 | char *switch_name; /* mixer switch*/ | ||
46 | }; | 47 | }; |
47 | 48 | ||
48 | /* ADC labels and channels */ | 49 | /* ADC labels and channels */ |
diff --git a/include/sound/cs46xx.h b/include/sound/cs46xx.h index 685928e6f65a..353910ce9755 100644 --- a/include/sound/cs46xx.h +++ b/include/sound/cs46xx.h | |||
@@ -1723,6 +1723,10 @@ struct snd_cs46xx { | |||
1723 | struct snd_cs46xx_pcm *playback_pcm; | 1723 | struct snd_cs46xx_pcm *playback_pcm; |
1724 | unsigned int play_ctl; | 1724 | unsigned int play_ctl; |
1725 | #endif | 1725 | #endif |
1726 | |||
1727 | #ifdef CONFIG_PM | ||
1728 | u32 *saved_regs; | ||
1729 | #endif | ||
1726 | }; | 1730 | }; |
1727 | 1731 | ||
1728 | int snd_cs46xx_create(struct snd_card *card, | 1732 | int snd_cs46xx_create(struct snd_card *card, |
diff --git a/include/sound/cs46xx_dsp_spos.h b/include/sound/cs46xx_dsp_spos.h index da934def31e9..d9da9e59cf37 100644 --- a/include/sound/cs46xx_dsp_spos.h +++ b/include/sound/cs46xx_dsp_spos.h | |||
@@ -107,6 +107,7 @@ struct dsp_scb_descriptor { | |||
107 | char scb_name[DSP_MAX_SCB_NAME]; | 107 | char scb_name[DSP_MAX_SCB_NAME]; |
108 | u32 address; | 108 | u32 address; |
109 | int index; | 109 | int index; |
110 | u32 *data; | ||
110 | 111 | ||
111 | struct dsp_scb_descriptor * sub_list_ptr; | 112 | struct dsp_scb_descriptor * sub_list_ptr; |
112 | struct dsp_scb_descriptor * next_scb_ptr; | 113 | struct dsp_scb_descriptor * next_scb_ptr; |
@@ -127,6 +128,7 @@ struct dsp_task_descriptor { | |||
127 | int size; | 128 | int size; |
128 | u32 address; | 129 | u32 address; |
129 | int index; | 130 | int index; |
131 | u32 *data; | ||
130 | }; | 132 | }; |
131 | 133 | ||
132 | struct dsp_pcm_channel_descriptor { | 134 | struct dsp_pcm_channel_descriptor { |
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h index 23e45a4cf0e4..529d0a564367 100644 --- a/include/sound/emu10k1.h +++ b/include/sound/emu10k1.h | |||
@@ -1120,6 +1120,16 @@ | |||
1120 | /************************************************************************************************/ | 1120 | /************************************************************************************************/ |
1121 | /* EMU1010m HANA Destinations */ | 1121 | /* EMU1010m HANA Destinations */ |
1122 | /************************************************************************************************/ | 1122 | /************************************************************************************************/ |
1123 | /* 32-bit destinations of signal in the Hana FPGA. Destinations are either | ||
1124 | * physical outputs of Hana, or outputs going to Alice2 (audigy) for capture | ||
1125 | * - 16 x EMU_DST_ALICE2_EMU32_X. | ||
1126 | */ | ||
1127 | /* EMU32 = 32-bit serial channel between Alice2 (audigy) and Hana (FPGA) */ | ||
1128 | /* EMU_DST_ALICE2_EMU32_X - data channels from Hana to Alice2 used for capture. | ||
1129 | * Which data is fed into a EMU_DST_ALICE2_EMU32_X channel in Hana depends on | ||
1130 | * setup of mixer control for each destination - see emumixer.c - | ||
1131 | * snd_emu1010_output_enum_ctls[], snd_emu1010_input_enum_ctls[] | ||
1132 | */ | ||
1123 | #define EMU_DST_ALICE2_EMU32_0 0x000f /* 16 EMU32 channels to Alice2 +0 to +0xf */ | 1133 | #define EMU_DST_ALICE2_EMU32_0 0x000f /* 16 EMU32 channels to Alice2 +0 to +0xf */ |
1124 | #define EMU_DST_ALICE2_EMU32_1 0x0000 /* 16 EMU32 channels to Alice2 +0 to +0xf */ | 1134 | #define EMU_DST_ALICE2_EMU32_1 0x0000 /* 16 EMU32 channels to Alice2 +0 to +0xf */ |
1125 | #define EMU_DST_ALICE2_EMU32_2 0x0001 /* 16 EMU32 channels to Alice2 +0 to +0xf */ | 1135 | #define EMU_DST_ALICE2_EMU32_2 0x0001 /* 16 EMU32 channels to Alice2 +0 to +0xf */ |
@@ -1199,6 +1209,12 @@ | |||
1199 | /************************************************************************************************/ | 1209 | /************************************************************************************************/ |
1200 | /* EMU1010m HANA Sources */ | 1210 | /* EMU1010m HANA Sources */ |
1201 | /************************************************************************************************/ | 1211 | /************************************************************************************************/ |
1212 | /* 32-bit sources of signal in the Hana FPGA. The sources are routed to | ||
1213 | * destinations using mixer control for each destination - see emumixer.c | ||
1214 | * Sources are either physical inputs of FPGA, | ||
1215 | * or outputs from Alice (audigy) - 16 x EMU_SRC_ALICE_EMU32A + | ||
1216 | * 16 x EMU_SRC_ALICE_EMU32B | ||
1217 | */ | ||
1202 | #define EMU_SRC_SILENCE 0x0000 /* Silence */ | 1218 | #define EMU_SRC_SILENCE 0x0000 /* Silence */ |
1203 | #define EMU_SRC_DOCK_MIC_A1 0x0100 /* Audio Dock Mic A, 1st or 48kHz only */ | 1219 | #define EMU_SRC_DOCK_MIC_A1 0x0100 /* Audio Dock Mic A, 1st or 48kHz only */ |
1204 | #define EMU_SRC_DOCK_MIC_A2 0x0101 /* Audio Dock Mic A, 2nd or 96kHz */ | 1220 | #define EMU_SRC_DOCK_MIC_A2 0x0101 /* Audio Dock Mic A, 2nd or 96kHz */ |
diff --git a/include/sound/sb.h b/include/sound/sb.h index 2dd5c8e5b4fe..3ad854b397d2 100644 --- a/include/sound/sb.h +++ b/include/sound/sb.h | |||
@@ -38,6 +38,7 @@ enum sb_hw_type { | |||
38 | SB_HW_ALS100, /* Avance Logic ALS100 chip */ | 38 | SB_HW_ALS100, /* Avance Logic ALS100 chip */ |
39 | SB_HW_ALS4000, /* Avance Logic ALS4000 chip */ | 39 | SB_HW_ALS4000, /* Avance Logic ALS4000 chip */ |
40 | SB_HW_DT019X, /* Diamond Tech. DT-019X / Avance Logic ALS-007 */ | 40 | SB_HW_DT019X, /* Diamond Tech. DT-019X / Avance Logic ALS-007 */ |
41 | SB_HW_CS5530, /* Cyrix/NatSemi 5530 VSA1 */ | ||
41 | }; | 42 | }; |
42 | 43 | ||
43 | #define SB_OPEN_PCM 0x01 | 44 | #define SB_OPEN_PCM 0x01 |
diff --git a/include/sound/version.h b/include/sound/version.h index 8e5b2f0f5946..6bbcfefd2c38 100644 --- a/include/sound/version.h +++ b/include/sound/version.h | |||
@@ -1,3 +1,3 @@ | |||
1 | /* include/version.h. Generated by alsa/ksync script. */ | 1 | /* include/version.h. Generated by alsa/ksync script. */ |
2 | #define CONFIG_SND_VERSION "1.0.14" | 2 | #define CONFIG_SND_VERSION "1.0.14" |
3 | #define CONFIG_SND_DATE " (Thu May 31 09:03:25 2007 UTC)" | 3 | #define CONFIG_SND_DATE " (Fri Jul 20 09:12:58 2007 UTC)" |
diff --git a/include/sound/wavefront_fx.h b/include/sound/wavefront_fx.h deleted file mode 100644 index cec92b141796..000000000000 --- a/include/sound/wavefront_fx.h +++ /dev/null | |||
@@ -1,9 +0,0 @@ | |||
1 | #ifndef __SOUND_WAVEFRONT_FX_H | ||
2 | #define __SOUND_WAVEFRONT_FX_H | ||
3 | |||
4 | extern int snd_wavefront_fx_detect (snd_wavefront_t *); | ||
5 | extern void snd_wavefront_fx_ioctl (snd_synth_t *sdev, | ||
6 | unsigned int cmd, | ||
7 | unsigned long arg); | ||
8 | |||
9 | #endif __SOUND_WAVEFRONT_FX_H | ||
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 43cb3b3e1679..40954fb81598 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -138,7 +138,7 @@ static unsigned long __meminitdata dma_reserve; | |||
138 | #endif /* CONFIG_MEMORY_HOTPLUG_RESERVE */ | 138 | #endif /* CONFIG_MEMORY_HOTPLUG_RESERVE */ |
139 | unsigned long __initdata required_kernelcore; | 139 | unsigned long __initdata required_kernelcore; |
140 | unsigned long __initdata required_movablecore; | 140 | unsigned long __initdata required_movablecore; |
141 | unsigned long __initdata zone_movable_pfn[MAX_NUMNODES]; | 141 | unsigned long __meminitdata zone_movable_pfn[MAX_NUMNODES]; |
142 | 142 | ||
143 | /* movable_zone is the "real" zone pages in ZONE_MOVABLE are taken from */ | 143 | /* movable_zone is the "real" zone pages in ZONE_MOVABLE are taken from */ |
144 | int movable_zone; | 144 | int movable_zone; |
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index b1179dd3d8c3..ca10df40784f 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c | |||
@@ -194,7 +194,7 @@ static struct nf_ct_ext_type helper_extend __read_mostly = { | |||
194 | .id = NF_CT_EXT_HELPER, | 194 | .id = NF_CT_EXT_HELPER, |
195 | }; | 195 | }; |
196 | 196 | ||
197 | int nf_conntrack_helper_init() | 197 | int nf_conntrack_helper_init(void) |
198 | { | 198 | { |
199 | int err; | 199 | int err; |
200 | 200 | ||
@@ -216,7 +216,7 @@ err1: | |||
216 | return err; | 216 | return err; |
217 | } | 217 | } |
218 | 218 | ||
219 | void nf_conntrack_helper_fini() | 219 | void nf_conntrack_helper_fini(void) |
220 | { | 220 | { |
221 | nf_ct_extend_unregister(&helper_extend); | 221 | nf_ct_extend_unregister(&helper_extend); |
222 | nf_ct_free_hashtable(nf_ct_helper_hash, nf_ct_helper_vmalloc, | 222 | nf_ct_free_hashtable(nf_ct_helper_hash, nf_ct_helper_vmalloc, |
diff --git a/scripts/Lindent b/scripts/Lindent index 7d8d8896e309..9468ec7971db 100755 --- a/scripts/Lindent +++ b/scripts/Lindent | |||
@@ -1,2 +1,2 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | indent -npro -kr -i8 -ts8 -sob -l80 -ss -ncs "$@" | 2 | indent -npro -kr -i8 -ts8 -sob -l80 -ss -ncs -cp1 "$@" |
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 04579a517900..5ab7914d30ef 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c | |||
@@ -1076,6 +1076,7 @@ static int initexit_section_ref_ok(const char *name) | |||
1076 | ".plt", /* seen on ARCH=um build on x86_64. Harmless */ | 1076 | ".plt", /* seen on ARCH=um build on x86_64. Harmless */ |
1077 | ".smp_locks", | 1077 | ".smp_locks", |
1078 | ".stab", | 1078 | ".stab", |
1079 | ".m68k_fixup", | ||
1079 | NULL | 1080 | NULL |
1080 | }; | 1081 | }; |
1081 | /* Start of section names */ | 1082 | /* Start of section names */ |
diff --git a/sound/Kconfig b/sound/Kconfig index 9ea473823418..e48b9b37d228 100644 --- a/sound/Kconfig +++ b/sound/Kconfig | |||
@@ -65,6 +65,8 @@ source "sound/arm/Kconfig" | |||
65 | 65 | ||
66 | source "sound/mips/Kconfig" | 66 | source "sound/mips/Kconfig" |
67 | 67 | ||
68 | source "sound/sh/Kconfig" | ||
69 | |||
68 | # the following will depend on the order of config. | 70 | # the following will depend on the order of config. |
69 | # here assuming USB is defined before ALSA | 71 | # here assuming USB is defined before ALSA |
70 | source "sound/usb/Kconfig" | 72 | source "sound/usb/Kconfig" |
diff --git a/sound/Makefile b/sound/Makefile index b7c7fb7c24c8..3ead922bd9c6 100644 --- a/sound/Makefile +++ b/sound/Makefile | |||
@@ -5,7 +5,7 @@ obj-$(CONFIG_SOUND) += soundcore.o | |||
5 | obj-$(CONFIG_SOUND_PRIME) += sound_firmware.o | 5 | obj-$(CONFIG_SOUND_PRIME) += sound_firmware.o |
6 | obj-$(CONFIG_SOUND_PRIME) += oss/ | 6 | obj-$(CONFIG_SOUND_PRIME) += oss/ |
7 | obj-$(CONFIG_DMASOUND) += oss/ | 7 | obj-$(CONFIG_DMASOUND) += oss/ |
8 | obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/ usb/ sparc/ parisc/ pcmcia/ mips/ soc/ | 8 | obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/ usb/ sparc/ parisc/ pcmcia/ mips/ soc/ |
9 | obj-$(CONFIG_SND_AOA) += aoa/ | 9 | obj-$(CONFIG_SND_AOA) += aoa/ |
10 | 10 | ||
11 | # This one must be compilable even if sound is configured out | 11 | # This one must be compilable even if sound is configured out |
diff --git a/sound/aoa/codecs/snd-aoa-codec-onyx.c b/sound/aoa/codecs/snd-aoa-codec-onyx.c index ded516717940..028852374f21 100644 --- a/sound/aoa/codecs/snd-aoa-codec-onyx.c +++ b/sound/aoa/codecs/snd-aoa-codec-onyx.c | |||
@@ -661,7 +661,7 @@ static struct transfer_info onyx_transfers[] = { | |||
661 | .tag = 2, | 661 | .tag = 2, |
662 | }, | 662 | }, |
663 | #ifdef SNDRV_PCM_FMTBIT_COMPRESSED_16BE | 663 | #ifdef SNDRV_PCM_FMTBIT_COMPRESSED_16BE |
664 | Once alsa gets supports for this kind of thing we can add it... | 664 | /* Once alsa gets supports for this kind of thing we can add it... */ |
665 | { | 665 | { |
666 | /* digital compressed output */ | 666 | /* digital compressed output */ |
667 | .formats = SNDRV_PCM_FMTBIT_COMPRESSED_16BE, | 667 | .formats = SNDRV_PCM_FMTBIT_COMPRESSED_16BE, |
@@ -713,7 +713,7 @@ static int onyx_prepare(struct codec_info_item *cii, | |||
713 | if (substream->runtime->format == SNDRV_PCM_FMTBIT_COMPRESSED_16BE) { | 713 | if (substream->runtime->format == SNDRV_PCM_FMTBIT_COMPRESSED_16BE) { |
714 | /* mute and lock analog output */ | 714 | /* mute and lock analog output */ |
715 | onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v); | 715 | onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v); |
716 | if (onyx_write_register(onyx | 716 | if (onyx_write_register(onyx, |
717 | ONYX_REG_DAC_CONTROL, | 717 | ONYX_REG_DAC_CONTROL, |
718 | v | ONYX_MUTE_RIGHT | ONYX_MUTE_LEFT)) | 718 | v | ONYX_MUTE_RIGHT | ONYX_MUTE_LEFT)) |
719 | goto out_unlock; | 719 | goto out_unlock; |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index a96733a5beb8..59b29cd482ae 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -1487,7 +1487,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream) | |||
1487 | 1487 | ||
1488 | snd_pcm_stream_lock_irq(substream); | 1488 | snd_pcm_stream_lock_irq(substream); |
1489 | /* resume pause */ | 1489 | /* resume pause */ |
1490 | if (runtime->status->state == SNDRV_PCM_STATE_PAUSED) | 1490 | if (substream->runtime->status->state == SNDRV_PCM_STATE_PAUSED) |
1491 | snd_pcm_pause(substream, 0); | 1491 | snd_pcm_pause(substream, 0); |
1492 | 1492 | ||
1493 | /* pre-start/stop - all running streams are changed to DRAINING state */ | 1493 | /* pre-start/stop - all running streams are changed to DRAINING state */ |
diff --git a/sound/core/seq/seq_instr.c b/sound/core/seq/seq_instr.c index f30d171b6d96..5efe6523a589 100644 --- a/sound/core/seq/seq_instr.c +++ b/sound/core/seq/seq_instr.c | |||
@@ -109,7 +109,7 @@ void snd_seq_instr_list_free(struct snd_seq_kinstr_list **list_ptr) | |||
109 | spin_lock_irqsave(&list->lock, flags); | 109 | spin_lock_irqsave(&list->lock, flags); |
110 | while (instr->use) { | 110 | while (instr->use) { |
111 | spin_unlock_irqrestore(&list->lock, flags); | 111 | spin_unlock_irqrestore(&list->lock, flags); |
112 | schedule_timeout_interruptible(1); | 112 | schedule_timeout(1); |
113 | spin_lock_irqsave(&list->lock, flags); | 113 | spin_lock_irqsave(&list->lock, flags); |
114 | } | 114 | } |
115 | spin_unlock_irqrestore(&list->lock, flags); | 115 | spin_unlock_irqrestore(&list->lock, flags); |
@@ -199,7 +199,7 @@ int snd_seq_instr_list_free_cond(struct snd_seq_kinstr_list *list, | |||
199 | instr = flist; | 199 | instr = flist; |
200 | flist = instr->next; | 200 | flist = instr->next; |
201 | while (instr->use) | 201 | while (instr->use) |
202 | schedule_timeout_interruptible(1); | 202 | schedule_timeout(1); |
203 | if (snd_seq_instr_free(instr, atomic)<0) | 203 | if (snd_seq_instr_free(instr, atomic)<0) |
204 | snd_printk(KERN_WARNING "instrument free problem\n"); | 204 | snd_printk(KERN_WARNING "instrument free problem\n"); |
205 | instr = next; | 205 | instr = next; |
@@ -555,7 +555,7 @@ static int instr_free(struct snd_seq_kinstr_ops *ops, | |||
555 | SNDRV_SEQ_INSTR_NOTIFY_REMOVE); | 555 | SNDRV_SEQ_INSTR_NOTIFY_REMOVE); |
556 | while (instr->use) { | 556 | while (instr->use) { |
557 | spin_unlock_irqrestore(&list->lock, flags); | 557 | spin_unlock_irqrestore(&list->lock, flags); |
558 | schedule_timeout_interruptible(1); | 558 | schedule_timeout(1); |
559 | spin_lock_irqsave(&list->lock, flags); | 559 | spin_lock_irqsave(&list->lock, flags); |
560 | } | 560 | } |
561 | spin_unlock_irqrestore(&list->lock, flags); | 561 | spin_unlock_irqrestore(&list->lock, flags); |
diff --git a/sound/core/timer.c b/sound/core/timer.c index 67520b3c0042..f2bbacedd567 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c | |||
@@ -1549,9 +1549,11 @@ static int snd_timer_user_info(struct file *file, | |||
1549 | int err = 0; | 1549 | int err = 0; |
1550 | 1550 | ||
1551 | tu = file->private_data; | 1551 | tu = file->private_data; |
1552 | snd_assert(tu->timeri != NULL, return -ENXIO); | 1552 | if (!tu->timeri) |
1553 | return -EBADFD; | ||
1553 | t = tu->timeri->timer; | 1554 | t = tu->timeri->timer; |
1554 | snd_assert(t != NULL, return -ENXIO); | 1555 | if (!t) |
1556 | return -EBADFD; | ||
1555 | 1557 | ||
1556 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 1558 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
1557 | if (! info) | 1559 | if (! info) |
@@ -1579,9 +1581,11 @@ static int snd_timer_user_params(struct file *file, | |||
1579 | int err; | 1581 | int err; |
1580 | 1582 | ||
1581 | tu = file->private_data; | 1583 | tu = file->private_data; |
1582 | snd_assert(tu->timeri != NULL, return -ENXIO); | 1584 | if (!tu->timeri) |
1585 | return -EBADFD; | ||
1583 | t = tu->timeri->timer; | 1586 | t = tu->timeri->timer; |
1584 | snd_assert(t != NULL, return -ENXIO); | 1587 | if (!t) |
1588 | return -EBADFD; | ||
1585 | if (copy_from_user(¶ms, _params, sizeof(params))) | 1589 | if (copy_from_user(¶ms, _params, sizeof(params))) |
1586 | return -EFAULT; | 1590 | return -EFAULT; |
1587 | if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE) && params.ticks < 1) { | 1591 | if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE) && params.ticks < 1) { |
@@ -1675,7 +1679,8 @@ static int snd_timer_user_status(struct file *file, | |||
1675 | struct snd_timer_status status; | 1679 | struct snd_timer_status status; |
1676 | 1680 | ||
1677 | tu = file->private_data; | 1681 | tu = file->private_data; |
1678 | snd_assert(tu->timeri != NULL, return -ENXIO); | 1682 | if (!tu->timeri) |
1683 | return -EBADFD; | ||
1679 | memset(&status, 0, sizeof(status)); | 1684 | memset(&status, 0, sizeof(status)); |
1680 | status.tstamp = tu->tstamp; | 1685 | status.tstamp = tu->tstamp; |
1681 | status.resolution = snd_timer_resolution(tu->timeri); | 1686 | status.resolution = snd_timer_resolution(tu->timeri); |
@@ -1695,7 +1700,8 @@ static int snd_timer_user_start(struct file *file) | |||
1695 | struct snd_timer_user *tu; | 1700 | struct snd_timer_user *tu; |
1696 | 1701 | ||
1697 | tu = file->private_data; | 1702 | tu = file->private_data; |
1698 | snd_assert(tu->timeri != NULL, return -ENXIO); | 1703 | if (!tu->timeri) |
1704 | return -EBADFD; | ||
1699 | snd_timer_stop(tu->timeri); | 1705 | snd_timer_stop(tu->timeri); |
1700 | tu->timeri->lost = 0; | 1706 | tu->timeri->lost = 0; |
1701 | tu->last_resolution = 0; | 1707 | tu->last_resolution = 0; |
@@ -1708,7 +1714,8 @@ static int snd_timer_user_stop(struct file *file) | |||
1708 | struct snd_timer_user *tu; | 1714 | struct snd_timer_user *tu; |
1709 | 1715 | ||
1710 | tu = file->private_data; | 1716 | tu = file->private_data; |
1711 | snd_assert(tu->timeri != NULL, return -ENXIO); | 1717 | if (!tu->timeri) |
1718 | return -EBADFD; | ||
1712 | return (err = snd_timer_stop(tu->timeri)) < 0 ? err : 0; | 1719 | return (err = snd_timer_stop(tu->timeri)) < 0 ? err : 0; |
1713 | } | 1720 | } |
1714 | 1721 | ||
@@ -1718,7 +1725,8 @@ static int snd_timer_user_continue(struct file *file) | |||
1718 | struct snd_timer_user *tu; | 1725 | struct snd_timer_user *tu; |
1719 | 1726 | ||
1720 | tu = file->private_data; | 1727 | tu = file->private_data; |
1721 | snd_assert(tu->timeri != NULL, return -ENXIO); | 1728 | if (!tu->timeri) |
1729 | return -EBADFD; | ||
1722 | tu->timeri->lost = 0; | 1730 | tu->timeri->lost = 0; |
1723 | return (err = snd_timer_continue(tu->timeri)) < 0 ? err : 0; | 1731 | return (err = snd_timer_continue(tu->timeri)) < 0 ? err : 0; |
1724 | } | 1732 | } |
@@ -1729,7 +1737,8 @@ static int snd_timer_user_pause(struct file *file) | |||
1729 | struct snd_timer_user *tu; | 1737 | struct snd_timer_user *tu; |
1730 | 1738 | ||
1731 | tu = file->private_data; | 1739 | tu = file->private_data; |
1732 | snd_assert(tu->timeri != NULL, return -ENXIO); | 1740 | if (!tu->timeri) |
1741 | return -EBADFD; | ||
1733 | return (err = snd_timer_pause(tu->timeri)) < 0 ? err : 0; | 1742 | return (err = snd_timer_pause(tu->timeri)) < 0 ? err : 0; |
1734 | } | 1743 | } |
1735 | 1744 | ||
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c index a0f28f51fc7e..4360ae9de19c 100644 --- a/sound/drivers/dummy.c +++ b/sound/drivers/dummy.c | |||
@@ -659,7 +659,7 @@ static struct platform_driver snd_dummy_driver = { | |||
659 | }, | 659 | }, |
660 | }; | 660 | }; |
661 | 661 | ||
662 | static void __init_or_module snd_dummy_unregister_all(void) | 662 | static void snd_dummy_unregister_all(void) |
663 | { | 663 | { |
664 | int i; | 664 | int i; |
665 | 665 | ||
diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c index 1d563e515c17..67c6e9745418 100644 --- a/sound/drivers/mpu401/mpu401.c +++ b/sound/drivers/mpu401/mpu401.c | |||
@@ -228,7 +228,7 @@ static struct pnp_driver snd_mpu401_pnp_driver = { | |||
228 | static struct pnp_driver snd_mpu401_pnp_driver; | 228 | static struct pnp_driver snd_mpu401_pnp_driver; |
229 | #endif | 229 | #endif |
230 | 230 | ||
231 | static void __init_or_module snd_mpu401_unregister_all(void) | 231 | static void snd_mpu401_unregister_all(void) |
232 | { | 232 | { |
233 | int i; | 233 | int i; |
234 | 234 | ||
diff --git a/sound/drivers/portman2x4.c b/sound/drivers/portman2x4.c index 497cafb57d9b..0eb9b5cebfcd 100644 --- a/sound/drivers/portman2x4.c +++ b/sound/drivers/portman2x4.c | |||
@@ -833,7 +833,7 @@ static struct platform_driver snd_portman_driver = { | |||
833 | /********************************************************************* | 833 | /********************************************************************* |
834 | * module init stuff | 834 | * module init stuff |
835 | *********************************************************************/ | 835 | *********************************************************************/ |
836 | static void __init_or_module snd_portman_unregister_all(void) | 836 | static void snd_portman_unregister_all(void) |
837 | { | 837 | { |
838 | int i; | 838 | int i; |
839 | 839 | ||
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c index 838a4277929d..d3e6a20edd38 100644 --- a/sound/drivers/serial-u16550.c +++ b/sound/drivers/serial-u16550.c | |||
@@ -998,7 +998,7 @@ static struct platform_driver snd_serial_driver = { | |||
998 | }, | 998 | }, |
999 | }; | 999 | }; |
1000 | 1000 | ||
1001 | static void __init_or_module snd_serial_unregister_all(void) | 1001 | static void snd_serial_unregister_all(void) |
1002 | { | 1002 | { |
1003 | int i; | 1003 | int i; |
1004 | 1004 | ||
diff --git a/sound/drivers/virmidi.c b/sound/drivers/virmidi.c index 46f3d3486067..915c86773c21 100644 --- a/sound/drivers/virmidi.c +++ b/sound/drivers/virmidi.c | |||
@@ -145,7 +145,7 @@ static struct platform_driver snd_virmidi_driver = { | |||
145 | }, | 145 | }, |
146 | }; | 146 | }; |
147 | 147 | ||
148 | static void __init_or_module snd_virmidi_unregister_all(void) | 148 | static void snd_virmidi_unregister_all(void) |
149 | { | 149 | { |
150 | int i; | 150 | int i; |
151 | 151 | ||
diff --git a/sound/i2c/other/ak4xxx-adda.c b/sound/i2c/other/ak4xxx-adda.c index 8805110017a7..fd335159f849 100644 --- a/sound/i2c/other/ak4xxx-adda.c +++ b/sound/i2c/other/ak4xxx-adda.c | |||
@@ -481,8 +481,8 @@ static int ak4xxx_switch_get(struct snd_kcontrol *kcontrol, | |||
481 | int addr = AK_GET_ADDR(kcontrol->private_value); | 481 | int addr = AK_GET_ADDR(kcontrol->private_value); |
482 | int shift = AK_GET_SHIFT(kcontrol->private_value); | 482 | int shift = AK_GET_SHIFT(kcontrol->private_value); |
483 | int invert = AK_GET_INVERT(kcontrol->private_value); | 483 | int invert = AK_GET_INVERT(kcontrol->private_value); |
484 | unsigned char val = snd_akm4xxx_get(ak, chip, addr); | 484 | /* we observe the (1<<shift) bit only */ |
485 | 485 | unsigned char val = snd_akm4xxx_get(ak, chip, addr) & (1<<shift); | |
486 | if (invert) | 486 | if (invert) |
487 | val = ! val; | 487 | val = ! val; |
488 | ucontrol->value.integer.value[0] = (val & (1<<shift)) != 0; | 488 | ucontrol->value.integer.value[0] = (val & (1<<shift)) != 0; |
@@ -585,6 +585,26 @@ static int build_dac_controls(struct snd_akm4xxx *ak) | |||
585 | 585 | ||
586 | mixer_ch = 0; | 586 | mixer_ch = 0; |
587 | for (idx = 0; idx < ak->num_dacs; ) { | 587 | for (idx = 0; idx < ak->num_dacs; ) { |
588 | /* mute control for Revolution 7.1 - AK4381 */ | ||
589 | if (ak->type == SND_AK4381 | ||
590 | && ak->dac_info[mixer_ch].switch_name) { | ||
591 | memset(&knew, 0, sizeof(knew)); | ||
592 | knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | ||
593 | knew.count = 1; | ||
594 | knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; | ||
595 | knew.name = ak->dac_info[mixer_ch].switch_name; | ||
596 | knew.info = ak4xxx_switch_info; | ||
597 | knew.get = ak4xxx_switch_get; | ||
598 | knew.put = ak4xxx_switch_put; | ||
599 | knew.access = 0; | ||
600 | /* register 1, bit 0 (SMUTE): 0 = normal operation, | ||
601 | 1 = mute */ | ||
602 | knew.private_value = | ||
603 | AK_COMPOSE(idx/2, 1, 0, 0) | AK_INVERT; | ||
604 | err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak)); | ||
605 | if (err < 0) | ||
606 | return err; | ||
607 | } | ||
588 | memset(&knew, 0, sizeof(knew)); | 608 | memset(&knew, 0, sizeof(knew)); |
589 | if (! ak->dac_info || ! ak->dac_info[mixer_ch].name) { | 609 | if (! ak->dac_info || ! ak->dac_info[mixer_ch].name) { |
590 | knew.name = "DAC Volume"; | 610 | knew.name = "DAC Volume"; |
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig index cf3803cd579c..ea5084abe60f 100644 --- a/sound/isa/Kconfig +++ b/sound/isa/Kconfig | |||
@@ -1,8 +1,5 @@ | |||
1 | # ALSA ISA drivers | 1 | # ALSA ISA drivers |
2 | 2 | ||
3 | menu "ISA devices" | ||
4 | depends on SND!=n && ISA && ISA_DMA_API | ||
5 | |||
6 | config SND_AD1848_LIB | 3 | config SND_AD1848_LIB |
7 | tristate | 4 | tristate |
8 | select SND_PCM | 5 | select SND_PCM |
@@ -11,6 +8,22 @@ config SND_CS4231_LIB | |||
11 | tristate | 8 | tristate |
12 | select SND_PCM | 9 | select SND_PCM |
13 | 10 | ||
11 | config SND_SB_COMMON | ||
12 | tristate | ||
13 | |||
14 | config SND_SB8_DSP | ||
15 | tristate | ||
16 | select SND_PCM | ||
17 | select SND_SB_COMMON | ||
18 | |||
19 | config SND_SB16_DSP | ||
20 | tristate | ||
21 | select SND_PCM | ||
22 | select SND_SB_COMMON | ||
23 | |||
24 | menu "ISA devices" | ||
25 | depends on SND!=n && ISA && ISA_DMA_API | ||
26 | |||
14 | config SND_ADLIB | 27 | config SND_ADLIB |
15 | tristate "AdLib FM card" | 28 | tristate "AdLib FM card" |
16 | depends on SND | 29 | depends on SND |
@@ -55,7 +68,7 @@ config SND_ALS100 | |||
55 | select ISAPNP | 68 | select ISAPNP |
56 | select SND_OPL3_LIB | 69 | select SND_OPL3_LIB |
57 | select SND_MPU401_UART | 70 | select SND_MPU401_UART |
58 | select SND_PCM | 71 | select SND_SB16_DSP |
59 | help | 72 | help |
60 | Say Y here to include support for soundcards based on Avance | 73 | Say Y here to include support for soundcards based on Avance |
61 | Logic ALS100, ALS110, ALS120 and ALS200 chips. | 74 | Logic ALS100, ALS110, ALS120 and ALS200 chips. |
@@ -81,6 +94,7 @@ config SND_CMI8330 | |||
81 | tristate "C-Media CMI8330" | 94 | tristate "C-Media CMI8330" |
82 | depends on SND | 95 | depends on SND |
83 | select SND_AD1848_LIB | 96 | select SND_AD1848_LIB |
97 | select SND_SB16_DSP | ||
84 | help | 98 | help |
85 | Say Y here to include support for soundcards based on the | 99 | Say Y here to include support for soundcards based on the |
86 | C-Media CMI8330 chip. | 100 | C-Media CMI8330 chip. |
@@ -132,7 +146,7 @@ config SND_DT019X | |||
132 | select ISAPNP | 146 | select ISAPNP |
133 | select SND_OPL3_LIB | 147 | select SND_OPL3_LIB |
134 | select SND_MPU401_UART | 148 | select SND_MPU401_UART |
135 | select SND_PCM | 149 | select SND_SB16_DSP |
136 | help | 150 | help |
137 | Say Y here to include support for soundcards based on the | 151 | Say Y here to include support for soundcards based on the |
138 | Diamond Technologies DT-019X or Avance Logic ALS-007 chips. | 152 | Diamond Technologies DT-019X or Avance Logic ALS-007 chips. |
@@ -145,7 +159,7 @@ config SND_ES968 | |||
145 | depends on SND && PNP && ISA | 159 | depends on SND && PNP && ISA |
146 | select ISAPNP | 160 | select ISAPNP |
147 | select SND_MPU401_UART | 161 | select SND_MPU401_UART |
148 | select SND_PCM | 162 | select SND_SB8_DSP |
149 | help | 163 | help |
150 | Say Y here to include support for ESS AudioDrive ES968 chips. | 164 | Say Y here to include support for ESS AudioDrive ES968 chips. |
151 | 165 | ||
@@ -321,7 +335,7 @@ config SND_SB8 | |||
321 | depends on SND | 335 | depends on SND |
322 | select SND_OPL3_LIB | 336 | select SND_OPL3_LIB |
323 | select SND_RAWMIDI | 337 | select SND_RAWMIDI |
324 | select SND_PCM | 338 | select SND_SB8_DSP |
325 | help | 339 | help |
326 | Say Y here to include support for Creative Sound Blaster 1.0/ | 340 | Say Y here to include support for Creative Sound Blaster 1.0/ |
327 | 2.0/Pro (8-bit) or 100% compatible soundcards. | 341 | 2.0/Pro (8-bit) or 100% compatible soundcards. |
@@ -334,7 +348,7 @@ config SND_SB16 | |||
334 | depends on SND | 348 | depends on SND |
335 | select SND_OPL3_LIB | 349 | select SND_OPL3_LIB |
336 | select SND_MPU401_UART | 350 | select SND_MPU401_UART |
337 | select SND_PCM | 351 | select SND_SB16_DSP |
338 | help | 352 | help |
339 | Say Y here to include support for Sound Blaster 16 soundcards | 353 | Say Y here to include support for Sound Blaster 16 soundcards |
340 | (including the Plug and Play version). | 354 | (including the Plug and Play version). |
@@ -347,7 +361,7 @@ config SND_SBAWE | |||
347 | depends on SND | 361 | depends on SND |
348 | select SND_OPL3_LIB | 362 | select SND_OPL3_LIB |
349 | select SND_MPU401_UART | 363 | select SND_MPU401_UART |
350 | select SND_PCM | 364 | select SND_SB16_DSP |
351 | help | 365 | help |
352 | Say Y here to include support for Sound Blaster AWE soundcards | 366 | Say Y here to include support for Sound Blaster AWE soundcards |
353 | (including the Plug and Play version). | 367 | (including the Plug and Play version). |
diff --git a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c index 8094282c2ae1..1bc2e3fd5721 100644 --- a/sound/isa/ad1848/ad1848_lib.c +++ b/sound/isa/ad1848/ad1848_lib.c | |||
@@ -245,7 +245,7 @@ static void snd_ad1848_mce_down(struct snd_ad1848 *chip) | |||
245 | snd_printk(KERN_ERR "mce_down - auto calibration time out (2)\n"); | 245 | snd_printk(KERN_ERR "mce_down - auto calibration time out (2)\n"); |
246 | return; | 246 | return; |
247 | } | 247 | } |
248 | time = schedule_timeout_interruptible(time); | 248 | time = schedule_timeout(time); |
249 | spin_lock_irqsave(&chip->reg_lock, flags); | 249 | spin_lock_irqsave(&chip->reg_lock, flags); |
250 | } | 250 | } |
251 | #if 0 | 251 | #if 0 |
@@ -258,7 +258,7 @@ static void snd_ad1848_mce_down(struct snd_ad1848 *chip) | |||
258 | snd_printk(KERN_ERR "mce_down - auto calibration time out (3)\n"); | 258 | snd_printk(KERN_ERR "mce_down - auto calibration time out (3)\n"); |
259 | return; | 259 | return; |
260 | } | 260 | } |
261 | time = schedule_timeout_interruptible(time); | 261 | time = schedule_timeout(time); |
262 | spin_lock_irqsave(&chip->reg_lock, flags); | 262 | spin_lock_irqsave(&chip->reg_lock, flags); |
263 | } | 263 | } |
264 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 264 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c index 4f6800b43b0e..e70db32991d9 100644 --- a/sound/isa/opl3sa2.c +++ b/sound/isa/opl3sa2.c | |||
@@ -164,6 +164,8 @@ static struct pnp_card_device_id snd_opl3sa2_pnpids[] = { | |||
164 | { .id = "YMH0801", .devs = { { "YMH0021" } } }, | 164 | { .id = "YMH0801", .devs = { { "YMH0021" } } }, |
165 | /* NeoMagic MagicWave 3DX */ | 165 | /* NeoMagic MagicWave 3DX */ |
166 | { .id = "NMX2200", .devs = { { "YMH2210" } } }, | 166 | { .id = "NMX2200", .devs = { { "YMH2210" } } }, |
167 | /* NeoMagic MagicWave 3D */ | ||
168 | { .id = "NMX2200", .devs = { { "NMX2210" } } }, | ||
167 | /* --- */ | 169 | /* --- */ |
168 | { .id = "" } /* end */ | 170 | { .id = "" } /* end */ |
169 | }; | 171 | }; |
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index 60c120ffb9de..049d479ce2b3 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c | |||
@@ -1927,10 +1927,12 @@ static struct snd_card *snd_opti9xx_card_new(void) | |||
1927 | static int __devinit snd_opti9xx_isa_match(struct device *devptr, | 1927 | static int __devinit snd_opti9xx_isa_match(struct device *devptr, |
1928 | unsigned int dev) | 1928 | unsigned int dev) |
1929 | { | 1929 | { |
1930 | #ifdef CONFIG_PNP | ||
1930 | if (snd_opti9xx_pnp_is_probed) | 1931 | if (snd_opti9xx_pnp_is_probed) |
1931 | return 0; | 1932 | return 0; |
1932 | if (isapnp) | 1933 | if (isapnp) |
1933 | return 0; | 1934 | return 0; |
1935 | #endif | ||
1934 | return 1; | 1936 | return 1; |
1935 | } | 1937 | } |
1936 | 1938 | ||
@@ -2096,6 +2098,7 @@ static int __init alsa_card_opti9xx_init(void) | |||
2096 | pnp_register_card_driver(&opti9xx_pnpc_driver); | 2098 | pnp_register_card_driver(&opti9xx_pnpc_driver); |
2097 | if (snd_opti9xx_pnp_is_probed) | 2099 | if (snd_opti9xx_pnp_is_probed) |
2098 | return 0; | 2100 | return 0; |
2101 | pnp_unregister_card_driver(&opti9xx_pnpc_driver); | ||
2099 | #endif | 2102 | #endif |
2100 | return isa_register_driver(&snd_opti9xx_driver, 1); | 2103 | return isa_register_driver(&snd_opti9xx_driver, 1); |
2101 | } | 2104 | } |
diff --git a/sound/isa/sb/Makefile b/sound/isa/sb/Makefile index fd9d9c5726fc..556e66928029 100644 --- a/sound/isa/sb/Makefile +++ b/sound/isa/sb/Makefile | |||
@@ -22,14 +22,13 @@ snd-es968-objs := es968.o | |||
22 | sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1))) | 22 | sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1))) |
23 | 23 | ||
24 | # Toplevel Module Dependency | 24 | # Toplevel Module Dependency |
25 | obj-$(CONFIG_SND_ALS100) += snd-sb16-dsp.o snd-sb-common.o | 25 | obj-$(CONFIG_SND_SB_COMMON) += snd-sb-common.o |
26 | obj-$(CONFIG_SND_CMI8330) += snd-sb16-dsp.o snd-sb-common.o | 26 | obj-$(CONFIG_SND_SB16_DSP) += snd-sb16-dsp.o |
27 | obj-$(CONFIG_SND_DT019X) += snd-sb16-dsp.o snd-sb-common.o | 27 | obj-$(CONFIG_SND_SB8_DSP) += snd-sb8-dsp.o |
28 | obj-$(CONFIG_SND_SB8) += snd-sb8.o snd-sb8-dsp.o snd-sb-common.o | 28 | obj-$(CONFIG_SND_SB8) += snd-sb8.o |
29 | obj-$(CONFIG_SND_SB16) += snd-sb16.o snd-sb16-dsp.o snd-sb-common.o | 29 | obj-$(CONFIG_SND_SB16) += snd-sb16.o |
30 | obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o snd-sb16-dsp.o snd-sb-common.o | 30 | obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o |
31 | obj-$(CONFIG_SND_ES968) += snd-es968.o snd-sb8-dsp.o snd-sb-common.o | 31 | obj-$(CONFIG_SND_ES968) += snd-es968.o |
32 | obj-$(CONFIG_SND_ALS4000) += snd-sb-common.o | ||
33 | ifeq ($(CONFIG_SND_SB16_CSP),y) | 32 | ifeq ($(CONFIG_SND_SB16_CSP),y) |
34 | obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o | 33 | obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o |
35 | obj-$(CONFIG_SND_SBAWE) += snd-sb16-csp.o | 34 | obj-$(CONFIG_SND_SBAWE) += snd-sb16-csp.o |
diff --git a/sound/isa/sb/sb16_main.c b/sound/isa/sb/sb16_main.c index 383911b9e74d..5d4d3aafe2d5 100644 --- a/sound/isa/sb/sb16_main.c +++ b/sound/isa/sb/sb16_main.c | |||
@@ -563,6 +563,11 @@ static int snd_sb16_playback_open(struct snd_pcm_substream *substream) | |||
563 | __open_ok: | 563 | __open_ok: |
564 | if (chip->hardware == SB_HW_ALS100) | 564 | if (chip->hardware == SB_HW_ALS100) |
565 | runtime->hw.rate_max = 48000; | 565 | runtime->hw.rate_max = 48000; |
566 | if (chip->hardware == SB_HW_CS5530) { | ||
567 | runtime->hw.buffer_bytes_max = 32 * 1024; | ||
568 | runtime->hw.periods_min = 2; | ||
569 | runtime->hw.rate_min = 44100; | ||
570 | } | ||
566 | if (chip->mode & SB_RATE_LOCK) | 571 | if (chip->mode & SB_RATE_LOCK) |
567 | runtime->hw.rate_min = runtime->hw.rate_max = chip->locked_rate; | 572 | runtime->hw.rate_min = runtime->hw.rate_max = chip->locked_rate; |
568 | chip->playback_substream = substream; | 573 | chip->playback_substream = substream; |
@@ -633,6 +638,11 @@ static int snd_sb16_capture_open(struct snd_pcm_substream *substream) | |||
633 | __open_ok: | 638 | __open_ok: |
634 | if (chip->hardware == SB_HW_ALS100) | 639 | if (chip->hardware == SB_HW_ALS100) |
635 | runtime->hw.rate_max = 48000; | 640 | runtime->hw.rate_max = 48000; |
641 | if (chip->hardware == SB_HW_CS5530) { | ||
642 | runtime->hw.buffer_bytes_max = 32 * 1024; | ||
643 | runtime->hw.periods_min = 2; | ||
644 | runtime->hw.rate_min = 44100; | ||
645 | } | ||
636 | if (chip->mode & SB_RATE_LOCK) | 646 | if (chip->mode & SB_RATE_LOCK) |
637 | runtime->hw.rate_min = runtime->hw.rate_max = chip->locked_rate; | 647 | runtime->hw.rate_min = runtime->hw.rate_max = chip->locked_rate; |
638 | chip->capture_substream = substream; | 648 | chip->capture_substream = substream; |
diff --git a/sound/isa/sb/sb_common.c b/sound/isa/sb/sb_common.c index 3094f3852167..efa9d5c2558a 100644 --- a/sound/isa/sb/sb_common.c +++ b/sound/isa/sb/sb_common.c | |||
@@ -128,7 +128,7 @@ static int snd_sbdsp_probe(struct snd_sb * chip) | |||
128 | minor = version & 0xff; | 128 | minor = version & 0xff; |
129 | snd_printdd("SB [0x%lx]: DSP chip found, version = %i.%i\n", | 129 | snd_printdd("SB [0x%lx]: DSP chip found, version = %i.%i\n", |
130 | chip->port, major, minor); | 130 | chip->port, major, minor); |
131 | 131 | ||
132 | switch (chip->hardware) { | 132 | switch (chip->hardware) { |
133 | case SB_HW_AUTO: | 133 | case SB_HW_AUTO: |
134 | switch (major) { | 134 | switch (major) { |
@@ -168,6 +168,9 @@ static int snd_sbdsp_probe(struct snd_sb * chip) | |||
168 | case SB_HW_DT019X: | 168 | case SB_HW_DT019X: |
169 | str = "(DT019X/ALS007)"; | 169 | str = "(DT019X/ALS007)"; |
170 | break; | 170 | break; |
171 | case SB_HW_CS5530: | ||
172 | str = "16 (CS5530)"; | ||
173 | break; | ||
171 | default: | 174 | default: |
172 | return -ENODEV; | 175 | return -ENODEV; |
173 | } | 176 | } |
diff --git a/sound/isa/sb/sb_mixer.c b/sound/isa/sb/sb_mixer.c index 490b1ca5cf58..3d4befcff28e 100644 --- a/sound/isa/sb/sb_mixer.c +++ b/sound/isa/sb/sb_mixer.c | |||
@@ -821,6 +821,7 @@ int snd_sbmixer_new(struct snd_sb *chip) | |||
821 | break; | 821 | break; |
822 | case SB_HW_16: | 822 | case SB_HW_16: |
823 | case SB_HW_ALS100: | 823 | case SB_HW_ALS100: |
824 | case SB_HW_CS5530: | ||
824 | if ((err = snd_sbmixer_init(chip, | 825 | if ((err = snd_sbmixer_init(chip, |
825 | snd_sb16_controls, | 826 | snd_sb16_controls, |
826 | ARRAY_SIZE(snd_sb16_controls), | 827 | ARRAY_SIZE(snd_sb16_controls), |
@@ -950,6 +951,7 @@ void snd_sbmixer_suspend(struct snd_sb *chip) | |||
950 | break; | 951 | break; |
951 | case SB_HW_16: | 952 | case SB_HW_16: |
952 | case SB_HW_ALS100: | 953 | case SB_HW_ALS100: |
954 | case SB_HW_CS5530: | ||
953 | save_mixer(chip, sb16_saved_regs, ARRAY_SIZE(sb16_saved_regs)); | 955 | save_mixer(chip, sb16_saved_regs, ARRAY_SIZE(sb16_saved_regs)); |
954 | break; | 956 | break; |
955 | case SB_HW_ALS4000: | 957 | case SB_HW_ALS4000: |
@@ -975,6 +977,7 @@ void snd_sbmixer_resume(struct snd_sb *chip) | |||
975 | break; | 977 | break; |
976 | case SB_HW_16: | 978 | case SB_HW_16: |
977 | case SB_HW_ALS100: | 979 | case SB_HW_ALS100: |
980 | case SB_HW_CS5530: | ||
978 | restore_mixer(chip, sb16_saved_regs, ARRAY_SIZE(sb16_saved_regs)); | 981 | restore_mixer(chip, sb16_saved_regs, ARRAY_SIZE(sb16_saved_regs)); |
979 | break; | 982 | break; |
980 | case SB_HW_ALS4000: | 983 | case SB_HW_ALS4000: |
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c index 9ea417bcf3e5..cbad2a51cbaa 100644 --- a/sound/isa/sscape.c +++ b/sound/isa/sscape.c | |||
@@ -382,7 +382,7 @@ static int obp_startup_ack(struct soundscape *s, unsigned timeout) | |||
382 | unsigned long flags; | 382 | unsigned long flags; |
383 | unsigned char x; | 383 | unsigned char x; |
384 | 384 | ||
385 | schedule_timeout_interruptible(1); | 385 | schedule_timeout(1); |
386 | 386 | ||
387 | spin_lock_irqsave(&s->lock, flags); | 387 | spin_lock_irqsave(&s->lock, flags); |
388 | x = inb(HOST_DATA_IO(s->io_base)); | 388 | x = inb(HOST_DATA_IO(s->io_base)); |
@@ -409,7 +409,7 @@ static int host_startup_ack(struct soundscape *s, unsigned timeout) | |||
409 | unsigned long flags; | 409 | unsigned long flags; |
410 | unsigned char x; | 410 | unsigned char x; |
411 | 411 | ||
412 | schedule_timeout_interruptible(1); | 412 | schedule_timeout(1); |
413 | 413 | ||
414 | spin_lock_irqsave(&s->lock, flags); | 414 | spin_lock_irqsave(&s->lock, flags); |
415 | x = inb(HOST_DATA_IO(s->io_base)); | 415 | x = inb(HOST_DATA_IO(s->io_base)); |
diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c index 78020d832e04..bacc51c86587 100644 --- a/sound/isa/wavefront/wavefront_synth.c +++ b/sound/isa/wavefront/wavefront_synth.c | |||
@@ -1780,7 +1780,7 @@ wavefront_should_cause_interrupt (snd_wavefront_t *dev, | |||
1780 | outb (val,port); | 1780 | outb (val,port); |
1781 | spin_unlock_irq(&dev->irq_lock); | 1781 | spin_unlock_irq(&dev->irq_lock); |
1782 | while (1) { | 1782 | while (1) { |
1783 | if ((timeout = schedule_timeout_interruptible(timeout)) == 0) | 1783 | if ((timeout = schedule_timeout(timeout)) == 0) |
1784 | return; | 1784 | return; |
1785 | if (dev->irq_ok) | 1785 | if (dev->irq_ok) |
1786 | return; | 1786 | return; |
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 61e35ecc57b8..c6b44102aa5b 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig | |||
@@ -33,6 +33,7 @@ config SND_ALS4000 | |||
33 | select SND_OPL3_LIB | 33 | select SND_OPL3_LIB |
34 | select SND_MPU401_UART | 34 | select SND_MPU401_UART |
35 | select SND_PCM | 35 | select SND_PCM |
36 | select SND_SB_COMMON | ||
36 | help | 37 | help |
37 | Say Y here to include support for soundcards based on Avance Logic | 38 | Say Y here to include support for soundcards based on Avance Logic |
38 | ALS4000 chips. | 39 | ALS4000 chips. |
@@ -215,6 +216,16 @@ config SND_CS46XX_NEW_DSP | |||
215 | 216 | ||
216 | This works better than the old code, so say Y. | 217 | This works better than the old code, so say Y. |
217 | 218 | ||
219 | config SND_CS5530 | ||
220 | tristate "CS5530 Audio" | ||
221 | depends on SND && ISA_DMA_API | ||
222 | select SND_SB16_DSP | ||
223 | help | ||
224 | Say Y here to include support for audio on Cyrix/NatSemi CS5530 chips. | ||
225 | |||
226 | To compile this driver as a module, choose M here: the module | ||
227 | will be called snd-cs5530. | ||
228 | |||
218 | config SND_CS5535AUDIO | 229 | config SND_CS5535AUDIO |
219 | tristate "CS5535/CS5536 Audio" | 230 | tristate "CS5535/CS5536 Audio" |
220 | depends on SND && X86 && !X86_64 | 231 | depends on SND && X86 && !X86_64 |
diff --git a/sound/pci/Makefile b/sound/pci/Makefile index e06736da9ef1..cd76e0293d06 100644 --- a/sound/pci/Makefile +++ b/sound/pci/Makefile | |||
@@ -12,6 +12,7 @@ snd-azt3328-objs := azt3328.o | |||
12 | snd-bt87x-objs := bt87x.o | 12 | snd-bt87x-objs := bt87x.o |
13 | snd-cmipci-objs := cmipci.o | 13 | snd-cmipci-objs := cmipci.o |
14 | snd-cs4281-objs := cs4281.o | 14 | snd-cs4281-objs := cs4281.o |
15 | snd-cs5530-objs := cs5530.o | ||
15 | snd-ens1370-objs := ens1370.o | 16 | snd-ens1370-objs := ens1370.o |
16 | snd-ens1371-objs := ens1371.o | 17 | snd-ens1371-objs := ens1371.o |
17 | snd-es1938-objs := es1938.o | 18 | snd-es1938-objs := es1938.o |
@@ -36,6 +37,7 @@ obj-$(CONFIG_SND_AZT3328) += snd-azt3328.o | |||
36 | obj-$(CONFIG_SND_BT87X) += snd-bt87x.o | 37 | obj-$(CONFIG_SND_BT87X) += snd-bt87x.o |
37 | obj-$(CONFIG_SND_CMIPCI) += snd-cmipci.o | 38 | obj-$(CONFIG_SND_CMIPCI) += snd-cmipci.o |
38 | obj-$(CONFIG_SND_CS4281) += snd-cs4281.o | 39 | obj-$(CONFIG_SND_CS4281) += snd-cs4281.o |
40 | obj-$(CONFIG_SND_CS5530) += snd-cs5530.o | ||
39 | obj-$(CONFIG_SND_ENS1370) += snd-ens1370.o | 41 | obj-$(CONFIG_SND_ENS1370) += snd-ens1370.o |
40 | obj-$(CONFIG_SND_ENS1371) += snd-ens1371.o | 42 | obj-$(CONFIG_SND_ENS1371) += snd-ens1371.o |
41 | obj-$(CONFIG_SND_ES1938) += snd-es1938.o | 43 | obj-$(CONFIG_SND_ES1938) += snd-es1938.o |
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c index 41543a4933e7..05b4c8696941 100644 --- a/sound/pci/ali5451/ali5451.c +++ b/sound/pci/ali5451/ali5451.c | |||
@@ -239,7 +239,7 @@ struct snd_ali_image { | |||
239 | 239 | ||
240 | 240 | ||
241 | struct snd_ali { | 241 | struct snd_ali { |
242 | unsigned long irq; | 242 | int irq; |
243 | unsigned long port; | 243 | unsigned long port; |
244 | unsigned char revision; | 244 | unsigned char revision; |
245 | 245 | ||
@@ -731,8 +731,7 @@ static void snd_ali_detect_spdif_rate(struct snd_ali *codec) | |||
731 | return; | 731 | return; |
732 | } | 732 | } |
733 | 733 | ||
734 | count = 0; | 734 | for (count = 0; count <= 50000; count++) { |
735 | while (count++ <= 50000) { | ||
736 | snd_ali_delay(codec, 6); | 735 | snd_ali_delay(codec, 6); |
737 | bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1)); | 736 | bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1)); |
738 | R2 = bval & 0x1F; | 737 | R2 = bval & 0x1F; |
@@ -2343,7 +2342,7 @@ static int __devinit snd_ali_probe(struct pci_dev *pci, | |||
2343 | strcpy(card->driver, "ALI5451"); | 2342 | strcpy(card->driver, "ALI5451"); |
2344 | strcpy(card->shortname, "ALI 5451"); | 2343 | strcpy(card->shortname, "ALI 5451"); |
2345 | 2344 | ||
2346 | sprintf(card->longname, "%s at 0x%lx, irq %li", | 2345 | sprintf(card->longname, "%s at 0x%lx, irq %i", |
2347 | card->shortname, codec->port, codec->irq); | 2346 | card->shortname, codec->port, codec->irq); |
2348 | 2347 | ||
2349 | snd_ali_printk("register card.\n"); | 2348 | snd_ali_printk("register card.\n"); |
diff --git a/sound/pci/als300.c b/sound/pci/als300.c index 8afcb98ca7bb..48cc39b771d9 100644 --- a/sound/pci/als300.c +++ b/sound/pci/als300.c | |||
@@ -88,8 +88,8 @@ | |||
88 | #define PLAYBACK_BLOCK_COUNTER 0x9A | 88 | #define PLAYBACK_BLOCK_COUNTER 0x9A |
89 | #define RECORD_BLOCK_COUNTER 0x9B | 89 | #define RECORD_BLOCK_COUNTER 0x9B |
90 | 90 | ||
91 | #define DEBUG_CALLS 1 | 91 | #define DEBUG_CALLS 0 |
92 | #define DEBUG_PLAY_REC 1 | 92 | #define DEBUG_PLAY_REC 0 |
93 | 93 | ||
94 | #if DEBUG_CALLS | 94 | #if DEBUG_CALLS |
95 | #define snd_als300_dbgcalls(format, args...) printk(format, ##args) | 95 | #define snd_als300_dbgcalls(format, args...) printk(format, ##args) |
@@ -733,7 +733,8 @@ static int __devinit snd_als300_create(struct snd_card *card, | |||
733 | 733 | ||
734 | snd_als300_init(chip); | 734 | snd_als300_init(chip); |
735 | 735 | ||
736 | if (snd_als300_ac97(chip) < 0) { | 736 | err = snd_als300_ac97(chip); |
737 | if (err < 0) { | ||
737 | snd_printk(KERN_WARNING "Could not create ac97\n"); | 738 | snd_printk(KERN_WARNING "Could not create ac97\n"); |
738 | snd_als300_free(chip); | 739 | snd_als300_free(chip); |
739 | return err; | 740 | return err; |
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index 9fd7b8a5b75e..fcab8fb97e38 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c | |||
@@ -168,6 +168,25 @@ MODULE_PARM_DESC(subsystem, "Force card subsystem model."); | |||
168 | #include "ca0106.h" | 168 | #include "ca0106.h" |
169 | 169 | ||
170 | static struct snd_ca0106_details ca0106_chip_details[] = { | 170 | static struct snd_ca0106_details ca0106_chip_details[] = { |
171 | /* Sound Blaster X-Fi Extreme Audio. This does not have an AC97. 53SB079000000 */ | ||
172 | /* It is really just a normal SB Live 24bit. */ | ||
173 | /* | ||
174 | * CTRL:CA0111-WTLF | ||
175 | * ADC: WM8775SEDS | ||
176 | * DAC: CS4382-KQZ | ||
177 | */ | ||
178 | /* Tested: | ||
179 | * Playback on front, rear, center/lfe speakers | ||
180 | * Capture from Mic in. | ||
181 | * Not-Tested: | ||
182 | * Capture from Line in. | ||
183 | * Playback to digital out. | ||
184 | */ | ||
185 | { .serial = 0x10121102, | ||
186 | .name = "X-Fi Extreme Audio [SB0790]", | ||
187 | .gpio_type = 1, | ||
188 | .i2c_adc = 1 } , | ||
189 | /* New Dell Sound Blaster Live! 7.1 24bit. This does not have an AC97. */ | ||
171 | /* AudigyLS[SB0310] */ | 190 | /* AudigyLS[SB0310] */ |
172 | { .serial = 0x10021102, | 191 | { .serial = 0x10021102, |
173 | .name = "AudigyLS [SB0310]", | 192 | .name = "AudigyLS [SB0310]", |
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index bef1f6d1859c..71d7aab9d869 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c | |||
@@ -2897,6 +2897,10 @@ static int snd_cs46xx_free(struct snd_cs46xx *chip) | |||
2897 | } | 2897 | } |
2898 | #endif | 2898 | #endif |
2899 | 2899 | ||
2900 | #ifdef CONFIG_PM | ||
2901 | kfree(chip->saved_regs); | ||
2902 | #endif | ||
2903 | |||
2900 | pci_disable_device(chip->pci); | 2904 | pci_disable_device(chip->pci); |
2901 | kfree(chip); | 2905 | kfree(chip); |
2902 | return 0; | 2906 | return 0; |
@@ -3140,6 +3144,23 @@ static int snd_cs46xx_chip_init(struct snd_cs46xx *chip) | |||
3140 | /* | 3144 | /* |
3141 | * start and load DSP | 3145 | * start and load DSP |
3142 | */ | 3146 | */ |
3147 | |||
3148 | static void cs46xx_enable_stream_irqs(struct snd_cs46xx *chip) | ||
3149 | { | ||
3150 | unsigned int tmp; | ||
3151 | |||
3152 | snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_IEV | HICR_CHGM); | ||
3153 | |||
3154 | tmp = snd_cs46xx_peek(chip, BA1_PFIE); | ||
3155 | tmp &= ~0x0000f03f; | ||
3156 | snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt enable */ | ||
3157 | |||
3158 | tmp = snd_cs46xx_peek(chip, BA1_CIE); | ||
3159 | tmp &= ~0x0000003f; | ||
3160 | tmp |= 0x00000001; | ||
3161 | snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt enable */ | ||
3162 | } | ||
3163 | |||
3143 | int __devinit snd_cs46xx_start_dsp(struct snd_cs46xx *chip) | 3164 | int __devinit snd_cs46xx_start_dsp(struct snd_cs46xx *chip) |
3144 | { | 3165 | { |
3145 | unsigned int tmp; | 3166 | unsigned int tmp; |
@@ -3214,19 +3235,7 @@ int __devinit snd_cs46xx_start_dsp(struct snd_cs46xx *chip) | |||
3214 | 3235 | ||
3215 | snd_cs46xx_proc_start(chip); | 3236 | snd_cs46xx_proc_start(chip); |
3216 | 3237 | ||
3217 | /* | 3238 | cs46xx_enable_stream_irqs(chip); |
3218 | * Enable interrupts on the part. | ||
3219 | */ | ||
3220 | snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_IEV | HICR_CHGM); | ||
3221 | |||
3222 | tmp = snd_cs46xx_peek(chip, BA1_PFIE); | ||
3223 | tmp &= ~0x0000f03f; | ||
3224 | snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt enable */ | ||
3225 | |||
3226 | tmp = snd_cs46xx_peek(chip, BA1_CIE); | ||
3227 | tmp &= ~0x0000003f; | ||
3228 | tmp |= 0x00000001; | ||
3229 | snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt enable */ | ||
3230 | 3239 | ||
3231 | #ifndef CONFIG_SND_CS46XX_NEW_DSP | 3240 | #ifndef CONFIG_SND_CS46XX_NEW_DSP |
3232 | /* set the attenuation to 0dB */ | 3241 | /* set the attenuation to 0dB */ |
@@ -3665,11 +3674,19 @@ static struct cs_card_type __devinitdata cards[] = { | |||
3665 | * APM support | 3674 | * APM support |
3666 | */ | 3675 | */ |
3667 | #ifdef CONFIG_PM | 3676 | #ifdef CONFIG_PM |
3677 | static unsigned int saved_regs[] = { | ||
3678 | BA0_ACOSV, | ||
3679 | BA0_ASER_FADDR, | ||
3680 | BA0_ASER_MASTER, | ||
3681 | BA1_PVOL, | ||
3682 | BA1_CVOL, | ||
3683 | }; | ||
3684 | |||
3668 | int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state) | 3685 | int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state) |
3669 | { | 3686 | { |
3670 | struct snd_card *card = pci_get_drvdata(pci); | 3687 | struct snd_card *card = pci_get_drvdata(pci); |
3671 | struct snd_cs46xx *chip = card->private_data; | 3688 | struct snd_cs46xx *chip = card->private_data; |
3672 | int amp_saved; | 3689 | int i, amp_saved; |
3673 | 3690 | ||
3674 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); | 3691 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); |
3675 | chip->in_suspend = 1; | 3692 | chip->in_suspend = 1; |
@@ -3680,6 +3697,10 @@ int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state) | |||
3680 | snd_ac97_suspend(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); | 3697 | snd_ac97_suspend(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); |
3681 | snd_ac97_suspend(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); | 3698 | snd_ac97_suspend(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); |
3682 | 3699 | ||
3700 | /* save some registers */ | ||
3701 | for (i = 0; i < ARRAY_SIZE(saved_regs); i++) | ||
3702 | chip->saved_regs[i] = snd_cs46xx_peekBA0(chip, saved_regs[i]); | ||
3703 | |||
3683 | amp_saved = chip->amplifier; | 3704 | amp_saved = chip->amplifier; |
3684 | /* turn off amp */ | 3705 | /* turn off amp */ |
3685 | chip->amplifier_ctrl(chip, -chip->amplifier); | 3706 | chip->amplifier_ctrl(chip, -chip->amplifier); |
@@ -3698,7 +3719,7 @@ int snd_cs46xx_resume(struct pci_dev *pci) | |||
3698 | { | 3719 | { |
3699 | struct snd_card *card = pci_get_drvdata(pci); | 3720 | struct snd_card *card = pci_get_drvdata(pci); |
3700 | struct snd_cs46xx *chip = card->private_data; | 3721 | struct snd_cs46xx *chip = card->private_data; |
3701 | int amp_saved; | 3722 | int i, amp_saved; |
3702 | 3723 | ||
3703 | pci_set_power_state(pci, PCI_D0); | 3724 | pci_set_power_state(pci, PCI_D0); |
3704 | pci_restore_state(pci); | 3725 | pci_restore_state(pci); |
@@ -3716,6 +3737,16 @@ int snd_cs46xx_resume(struct pci_dev *pci) | |||
3716 | 3737 | ||
3717 | snd_cs46xx_chip_init(chip); | 3738 | snd_cs46xx_chip_init(chip); |
3718 | 3739 | ||
3740 | snd_cs46xx_reset(chip); | ||
3741 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | ||
3742 | cs46xx_dsp_resume(chip); | ||
3743 | /* restore some registers */ | ||
3744 | for (i = 0; i < ARRAY_SIZE(saved_regs); i++) | ||
3745 | snd_cs46xx_pokeBA0(chip, saved_regs[i], chip->saved_regs[i]); | ||
3746 | #else | ||
3747 | snd_cs46xx_download_image(chip); | ||
3748 | #endif | ||
3749 | |||
3719 | #if 0 | 3750 | #if 0 |
3720 | snd_cs46xx_codec_write(chip, BA0_AC97_GENERAL_PURPOSE, | 3751 | snd_cs46xx_codec_write(chip, BA0_AC97_GENERAL_PURPOSE, |
3721 | chip->ac97_general_purpose); | 3752 | chip->ac97_general_purpose); |
@@ -3730,6 +3761,13 @@ int snd_cs46xx_resume(struct pci_dev *pci) | |||
3730 | snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); | 3761 | snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); |
3731 | snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); | 3762 | snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); |
3732 | 3763 | ||
3764 | /* reset playback/capture */ | ||
3765 | snd_cs46xx_set_play_sample_rate(chip, 8000); | ||
3766 | snd_cs46xx_set_capture_sample_rate(chip, 8000); | ||
3767 | snd_cs46xx_proc_start(chip); | ||
3768 | |||
3769 | cs46xx_enable_stream_irqs(chip); | ||
3770 | |||
3733 | if (amp_saved) | 3771 | if (amp_saved) |
3734 | chip->amplifier_ctrl(chip, 1); /* turn amp on */ | 3772 | chip->amplifier_ctrl(chip, 1); /* turn amp on */ |
3735 | else | 3773 | else |
@@ -3896,6 +3934,15 @@ int __devinit snd_cs46xx_create(struct snd_card *card, | |||
3896 | 3934 | ||
3897 | snd_cs46xx_proc_init(card, chip); | 3935 | snd_cs46xx_proc_init(card, chip); |
3898 | 3936 | ||
3937 | #ifdef CONFIG_PM | ||
3938 | chip->saved_regs = kmalloc(sizeof(*chip->saved_regs) * | ||
3939 | ARRAY_SIZE(saved_regs), GFP_KERNEL); | ||
3940 | if (!chip->saved_regs) { | ||
3941 | snd_cs46xx_free(chip); | ||
3942 | return -ENOMEM; | ||
3943 | } | ||
3944 | #endif | ||
3945 | |||
3899 | chip->active_ctrl(chip, -1); /* disable CLKRUN */ | 3946 | chip->active_ctrl(chip, -1); /* disable CLKRUN */ |
3900 | 3947 | ||
3901 | snd_card_set_dev(card, &pci->dev); | 3948 | snd_card_set_dev(card, &pci->dev); |
diff --git a/sound/pci/cs46xx/cs46xx_lib.h b/sound/pci/cs46xx/cs46xx_lib.h index f75750c2bd24..20dcd72f06c1 100644 --- a/sound/pci/cs46xx/cs46xx_lib.h +++ b/sound/pci/cs46xx/cs46xx_lib.h | |||
@@ -86,6 +86,9 @@ static inline unsigned int snd_cs46xx_peekBA0(struct snd_cs46xx *chip, unsigned | |||
86 | struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip); | 86 | struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip); |
87 | void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip); | 87 | void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip); |
88 | int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * module); | 88 | int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * module); |
89 | #ifdef CONFIG_PM | ||
90 | int cs46xx_dsp_resume(struct snd_cs46xx * chip); | ||
91 | #endif | ||
89 | struct dsp_symbol_entry *cs46xx_dsp_lookup_symbol (struct snd_cs46xx * chip, char * symbol_name, | 92 | struct dsp_symbol_entry *cs46xx_dsp_lookup_symbol (struct snd_cs46xx * chip, char * symbol_name, |
90 | int symbol_type); | 93 | int symbol_type); |
91 | #ifdef CONFIG_PROC_FS | 94 | #ifdef CONFIG_PROC_FS |
diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c index 336e77e2600c..590b35d91df2 100644 --- a/sound/pci/cs46xx/dsp_spos.c +++ b/sound/pci/cs46xx/dsp_spos.c | |||
@@ -306,13 +306,59 @@ void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip) | |||
306 | mutex_unlock(&chip->spos_mutex); | 306 | mutex_unlock(&chip->spos_mutex); |
307 | } | 307 | } |
308 | 308 | ||
309 | static int dsp_load_parameter(struct snd_cs46xx *chip, | ||
310 | struct dsp_segment_desc *parameter) | ||
311 | { | ||
312 | u32 doffset, dsize; | ||
313 | |||
314 | if (!parameter) { | ||
315 | snd_printdd("dsp_spos: module got no parameter segment\n"); | ||
316 | return 0; | ||
317 | } | ||
318 | |||
319 | doffset = (parameter->offset * 4 + DSP_PARAMETER_BYTE_OFFSET); | ||
320 | dsize = parameter->size * 4; | ||
321 | |||
322 | snd_printdd("dsp_spos: " | ||
323 | "downloading parameter data to chip (%08x-%08x)\n", | ||
324 | doffset,doffset + dsize); | ||
325 | if (snd_cs46xx_download (chip, parameter->data, doffset, dsize)) { | ||
326 | snd_printk(KERN_ERR "dsp_spos: " | ||
327 | "failed to download parameter data to DSP\n"); | ||
328 | return -EINVAL; | ||
329 | } | ||
330 | return 0; | ||
331 | } | ||
332 | |||
333 | static int dsp_load_sample(struct snd_cs46xx *chip, | ||
334 | struct dsp_segment_desc *sample) | ||
335 | { | ||
336 | u32 doffset, dsize; | ||
337 | |||
338 | if (!sample) { | ||
339 | snd_printdd("dsp_spos: module got no sample segment\n"); | ||
340 | return 0; | ||
341 | } | ||
342 | |||
343 | doffset = (sample->offset * 4 + DSP_SAMPLE_BYTE_OFFSET); | ||
344 | dsize = sample->size * 4; | ||
345 | |||
346 | snd_printdd("dsp_spos: downloading sample data to chip (%08x-%08x)\n", | ||
347 | doffset,doffset + dsize); | ||
348 | |||
349 | if (snd_cs46xx_download (chip,sample->data,doffset,dsize)) { | ||
350 | snd_printk(KERN_ERR "dsp_spos: failed to sample data to DSP\n"); | ||
351 | return -EINVAL; | ||
352 | } | ||
353 | return 0; | ||
354 | } | ||
355 | |||
309 | int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * module) | 356 | int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * module) |
310 | { | 357 | { |
311 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; | 358 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; |
312 | struct dsp_segment_desc * code = get_segment_desc (module,SEGTYPE_SP_PROGRAM); | 359 | struct dsp_segment_desc * code = get_segment_desc (module,SEGTYPE_SP_PROGRAM); |
313 | struct dsp_segment_desc * parameter = get_segment_desc (module,SEGTYPE_SP_PARAMETER); | ||
314 | struct dsp_segment_desc * sample = get_segment_desc (module,SEGTYPE_SP_SAMPLE); | ||
315 | u32 doffset, dsize; | 360 | u32 doffset, dsize; |
361 | int err; | ||
316 | 362 | ||
317 | if (ins->nmodules == DSP_MAX_MODULES - 1) { | 363 | if (ins->nmodules == DSP_MAX_MODULES - 1) { |
318 | snd_printk(KERN_ERR "dsp_spos: to many modules loaded into DSP\n"); | 364 | snd_printk(KERN_ERR "dsp_spos: to many modules loaded into DSP\n"); |
@@ -326,49 +372,20 @@ int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * m | |||
326 | snd_cs46xx_clear_BA1(chip, DSP_PARAMETER_BYTE_OFFSET, DSP_PARAMETER_BYTE_SIZE); | 372 | snd_cs46xx_clear_BA1(chip, DSP_PARAMETER_BYTE_OFFSET, DSP_PARAMETER_BYTE_SIZE); |
327 | } | 373 | } |
328 | 374 | ||
329 | if (parameter == NULL) { | 375 | err = dsp_load_parameter(chip, get_segment_desc(module, |
330 | snd_printdd("dsp_spos: module got no parameter segment\n"); | 376 | SEGTYPE_SP_PARAMETER)); |
331 | } else { | 377 | if (err < 0) |
332 | if (ins->nmodules > 0) { | 378 | return err; |
333 | snd_printk(KERN_WARNING "dsp_spos: WARNING current parameter data may be overwriten!\n"); | ||
334 | } | ||
335 | |||
336 | doffset = (parameter->offset * 4 + DSP_PARAMETER_BYTE_OFFSET); | ||
337 | dsize = parameter->size * 4; | ||
338 | |||
339 | snd_printdd("dsp_spos: downloading parameter data to chip (%08x-%08x)\n", | ||
340 | doffset,doffset + dsize); | ||
341 | |||
342 | if (snd_cs46xx_download (chip, parameter->data, doffset, dsize)) { | ||
343 | snd_printk(KERN_ERR "dsp_spos: failed to download parameter data to DSP\n"); | ||
344 | return -EINVAL; | ||
345 | } | ||
346 | } | ||
347 | 379 | ||
348 | if (ins->nmodules == 0) { | 380 | if (ins->nmodules == 0) { |
349 | snd_printdd("dsp_spos: clearing sample area\n"); | 381 | snd_printdd("dsp_spos: clearing sample area\n"); |
350 | snd_cs46xx_clear_BA1(chip, DSP_SAMPLE_BYTE_OFFSET, DSP_SAMPLE_BYTE_SIZE); | 382 | snd_cs46xx_clear_BA1(chip, DSP_SAMPLE_BYTE_OFFSET, DSP_SAMPLE_BYTE_SIZE); |
351 | } | 383 | } |
352 | 384 | ||
353 | if (sample == NULL) { | 385 | err = dsp_load_sample(chip, get_segment_desc(module, |
354 | snd_printdd("dsp_spos: module got no sample segment\n"); | 386 | SEGTYPE_SP_SAMPLE)); |
355 | } else { | 387 | if (err < 0) |
356 | if (ins->nmodules > 0) { | 388 | return err; |
357 | snd_printk(KERN_WARNING "dsp_spos: WARNING current sample data may be overwriten\n"); | ||
358 | } | ||
359 | |||
360 | doffset = (sample->offset * 4 + DSP_SAMPLE_BYTE_OFFSET); | ||
361 | dsize = sample->size * 4; | ||
362 | |||
363 | snd_printdd("dsp_spos: downloading sample data to chip (%08x-%08x)\n", | ||
364 | doffset,doffset + dsize); | ||
365 | |||
366 | if (snd_cs46xx_download (chip,sample->data,doffset,dsize)) { | ||
367 | snd_printk(KERN_ERR "dsp_spos: failed to sample data to DSP\n"); | ||
368 | return -EINVAL; | ||
369 | } | ||
370 | } | ||
371 | |||
372 | 389 | ||
373 | if (ins->nmodules == 0) { | 390 | if (ins->nmodules == 0) { |
374 | snd_printdd("dsp_spos: clearing code area\n"); | 391 | snd_printdd("dsp_spos: clearing code area\n"); |
@@ -986,7 +1003,10 @@ _map_task_tree (struct snd_cs46xx *chip, char * name, u32 dest, u32 size) | |||
986 | return NULL; | 1003 | return NULL; |
987 | } | 1004 | } |
988 | 1005 | ||
989 | strcpy(ins->tasks[ins->ntask].task_name,name); | 1006 | if (name) |
1007 | strcpy(ins->tasks[ins->ntask].task_name, name); | ||
1008 | else | ||
1009 | strcpy(ins->tasks[ins->ntask].task_name, "(NULL)"); | ||
990 | ins->tasks[ins->ntask].address = dest; | 1010 | ins->tasks[ins->ntask].address = dest; |
991 | ins->tasks[ins->ntask].size = size; | 1011 | ins->tasks[ins->ntask].size = size; |
992 | 1012 | ||
@@ -995,7 +1015,8 @@ _map_task_tree (struct snd_cs46xx *chip, char * name, u32 dest, u32 size) | |||
995 | desc = (ins->tasks + ins->ntask); | 1015 | desc = (ins->tasks + ins->ntask); |
996 | ins->ntask++; | 1016 | ins->ntask++; |
997 | 1017 | ||
998 | add_symbol (chip,name,dest,SYMBOL_PARAMETER); | 1018 | if (name) |
1019 | add_symbol (chip,name,dest,SYMBOL_PARAMETER); | ||
999 | return desc; | 1020 | return desc; |
1000 | } | 1021 | } |
1001 | 1022 | ||
@@ -1006,6 +1027,7 @@ cs46xx_dsp_create_scb (struct snd_cs46xx *chip, char * name, u32 * scb_data, u32 | |||
1006 | 1027 | ||
1007 | desc = _map_scb (chip,name,dest); | 1028 | desc = _map_scb (chip,name,dest); |
1008 | if (desc) { | 1029 | if (desc) { |
1030 | desc->data = scb_data; | ||
1009 | _dsp_create_scb(chip,scb_data,dest); | 1031 | _dsp_create_scb(chip,scb_data,dest); |
1010 | } else { | 1032 | } else { |
1011 | snd_printk(KERN_ERR "dsp_spos: failed to map SCB\n"); | 1033 | snd_printk(KERN_ERR "dsp_spos: failed to map SCB\n"); |
@@ -1023,6 +1045,7 @@ cs46xx_dsp_create_task_tree (struct snd_cs46xx *chip, char * name, u32 * task_da | |||
1023 | 1045 | ||
1024 | desc = _map_task_tree (chip,name,dest,size); | 1046 | desc = _map_task_tree (chip,name,dest,size); |
1025 | if (desc) { | 1047 | if (desc) { |
1048 | desc->data = task_data; | ||
1026 | _dsp_create_task_tree(chip,task_data,dest,size); | 1049 | _dsp_create_task_tree(chip,task_data,dest,size); |
1027 | } else { | 1050 | } else { |
1028 | snd_printk(KERN_ERR "dsp_spos: failed to map TASK\n"); | 1051 | snd_printk(KERN_ERR "dsp_spos: failed to map TASK\n"); |
@@ -1320,8 +1343,10 @@ int cs46xx_dsp_scb_and_task_init (struct snd_cs46xx *chip) | |||
1320 | 0x0000ffff | 1343 | 0x0000ffff |
1321 | }; | 1344 | }; |
1322 | 1345 | ||
1323 | /* dirty hack ... */ | 1346 | if (!cs46xx_dsp_create_task_tree(chip, NULL, |
1324 | _dsp_create_task_tree (chip,(u32 *)&mix2_ostream_spb,WRITE_BACK_SPB,2); | 1347 | (u32 *)&mix2_ostream_spb, |
1348 | WRITE_BACK_SPB, 2)) | ||
1349 | goto _fail_end; | ||
1325 | } | 1350 | } |
1326 | 1351 | ||
1327 | /* input sample converter */ | 1352 | /* input sample converter */ |
@@ -1622,7 +1647,6 @@ static int cs46xx_dsp_async_init (struct snd_cs46xx *chip, | |||
1622 | return 0; | 1647 | return 0; |
1623 | } | 1648 | } |
1624 | 1649 | ||
1625 | |||
1626 | static void cs46xx_dsp_disable_spdif_hw (struct snd_cs46xx *chip) | 1650 | static void cs46xx_dsp_disable_spdif_hw (struct snd_cs46xx *chip) |
1627 | { | 1651 | { |
1628 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; | 1652 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; |
@@ -1894,3 +1918,61 @@ int cs46xx_dsp_set_iec958_volume (struct snd_cs46xx * chip, u16 left, u16 right) | |||
1894 | 1918 | ||
1895 | return 0; | 1919 | return 0; |
1896 | } | 1920 | } |
1921 | |||
1922 | #ifdef CONFIG_PM | ||
1923 | int cs46xx_dsp_resume(struct snd_cs46xx * chip) | ||
1924 | { | ||
1925 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; | ||
1926 | int i, err; | ||
1927 | |||
1928 | /* clear parameter, sample and code areas */ | ||
1929 | snd_cs46xx_clear_BA1(chip, DSP_PARAMETER_BYTE_OFFSET, | ||
1930 | DSP_PARAMETER_BYTE_SIZE); | ||
1931 | snd_cs46xx_clear_BA1(chip, DSP_SAMPLE_BYTE_OFFSET, | ||
1932 | DSP_SAMPLE_BYTE_SIZE); | ||
1933 | snd_cs46xx_clear_BA1(chip, DSP_CODE_BYTE_OFFSET, DSP_CODE_BYTE_SIZE); | ||
1934 | |||
1935 | for (i = 0; i < ins->nmodules; i++) { | ||
1936 | struct dsp_module_desc *module = &ins->modules[i]; | ||
1937 | struct dsp_segment_desc *seg; | ||
1938 | u32 doffset, dsize; | ||
1939 | |||
1940 | seg = get_segment_desc(module, SEGTYPE_SP_PARAMETER); | ||
1941 | err = dsp_load_parameter(chip, seg); | ||
1942 | if (err < 0) | ||
1943 | return err; | ||
1944 | |||
1945 | seg = get_segment_desc(module, SEGTYPE_SP_SAMPLE); | ||
1946 | err = dsp_load_sample(chip, seg); | ||
1947 | if (err < 0) | ||
1948 | return err; | ||
1949 | |||
1950 | seg = get_segment_desc(module, SEGTYPE_SP_PROGRAM); | ||
1951 | if (!seg) | ||
1952 | continue; | ||
1953 | |||
1954 | doffset = seg->offset * 4 + module->load_address * 4 | ||
1955 | + DSP_CODE_BYTE_OFFSET; | ||
1956 | dsize = seg->size * 4; | ||
1957 | err = snd_cs46xx_download(chip, | ||
1958 | ins->code.data + module->load_address, | ||
1959 | doffset, dsize); | ||
1960 | if (err < 0) | ||
1961 | return err; | ||
1962 | } | ||
1963 | |||
1964 | for (i = 0; i < ins->ntask; i++) { | ||
1965 | struct dsp_task_descriptor *t = &ins->tasks[i]; | ||
1966 | _dsp_create_task_tree(chip, t->data, t->address, t->size); | ||
1967 | } | ||
1968 | |||
1969 | for (i = 0; i < ins->nscb; i++) { | ||
1970 | struct dsp_scb_descriptor *s = &ins->scbs[i]; | ||
1971 | if (s->deleted) | ||
1972 | continue; | ||
1973 | _dsp_create_scb(chip, s->data, s->address); | ||
1974 | } | ||
1975 | |||
1976 | return 0; | ||
1977 | } | ||
1978 | #endif | ||
diff --git a/sound/pci/cs5530.c b/sound/pci/cs5530.c new file mode 100644 index 000000000000..240a0a462209 --- /dev/null +++ b/sound/pci/cs5530.c | |||
@@ -0,0 +1,306 @@ | |||
1 | /* | ||
2 | * cs5530.c - Initialisation code for Cyrix/NatSemi VSA1 softaudio | ||
3 | * | ||
4 | * (C) Copyright 2007 Ash Willis <ashwillis@programmer.net> | ||
5 | * (C) Copyright 2003 Red Hat Inc <alan@redhat.com> | ||
6 | * | ||
7 | * This driver was ported (shamelessly ripped ;) from oss/kahlua.c but I did | ||
8 | * mess with it a bit. The chip seems to have to have trouble with full duplex | ||
9 | * mode. If we're recording in 8bit 8000kHz, say, and we then attempt to | ||
10 | * simultaneously play back audio at 16bit 44100kHz, the device actually plays | ||
11 | * back in the same format in which it is capturing. By forcing the chip to | ||
12 | * always play/capture in 16/44100, we can let alsa-lib convert the samples and | ||
13 | * that way we can hack up some full duplex audio. | ||
14 | * | ||
15 | * XpressAudio(tm) is used on the Cyrix MediaGX (now NatSemi Geode) systems. | ||
16 | * The older version (VSA1) provides fairly good soundblaster emulation | ||
17 | * although there are a couple of bugs: large DMA buffers break record, | ||
18 | * and the MPU event handling seems suspect. VSA2 allows the native driver | ||
19 | * to control the AC97 audio engine directly and requires a different driver. | ||
20 | * | ||
21 | * Thanks to National Semiconductor for providing the needed information | ||
22 | * on the XpressAudio(tm) internals. | ||
23 | * | ||
24 | * This program is free software; you can redistribute it and/or modify it | ||
25 | * under the terms of the GNU General Public License as published by the | ||
26 | * Free Software Foundation; either version 2, or (at your option) any | ||
27 | * later version. | ||
28 | * | ||
29 | * This program is distributed in the hope that it will be useful, but | ||
30 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
31 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
32 | * General Public License for more details. | ||
33 | * | ||
34 | * TO DO: | ||
35 | * Investigate whether we can portably support Cognac (5520) in the | ||
36 | * same manner. | ||
37 | */ | ||
38 | |||
39 | #include <sound/driver.h> | ||
40 | #include <linux/delay.h> | ||
41 | #include <linux/moduleparam.h> | ||
42 | #include <linux/pci.h> | ||
43 | #include <sound/core.h> | ||
44 | #include <sound/sb.h> | ||
45 | #include <sound/initval.h> | ||
46 | |||
47 | MODULE_AUTHOR("Ash Willis"); | ||
48 | MODULE_DESCRIPTION("CS5530 Audio"); | ||
49 | MODULE_LICENSE("GPL"); | ||
50 | |||
51 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; | ||
52 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; | ||
53 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; | ||
54 | |||
55 | struct snd_cs5530 { | ||
56 | struct snd_card *card; | ||
57 | struct pci_dev *pci; | ||
58 | struct snd_sb *sb; | ||
59 | unsigned long pci_base; | ||
60 | }; | ||
61 | |||
62 | static struct pci_device_id snd_cs5530_ids[] = { | ||
63 | {PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_AUDIO, PCI_ANY_ID, | ||
64 | PCI_ANY_ID, 0, 0}, | ||
65 | {0,} | ||
66 | }; | ||
67 | |||
68 | MODULE_DEVICE_TABLE(pci, snd_cs5530_ids); | ||
69 | |||
70 | static int snd_cs5530_free(struct snd_cs5530 *chip) | ||
71 | { | ||
72 | pci_release_regions(chip->pci); | ||
73 | pci_disable_device(chip->pci); | ||
74 | kfree(chip); | ||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | static int snd_cs5530_dev_free(struct snd_device *device) | ||
79 | { | ||
80 | struct snd_cs5530 *chip = device->device_data; | ||
81 | return snd_cs5530_free(chip); | ||
82 | } | ||
83 | |||
84 | static void __devexit snd_cs5530_remove(struct pci_dev *pci) | ||
85 | { | ||
86 | snd_card_free(pci_get_drvdata(pci)); | ||
87 | pci_set_drvdata(pci, NULL); | ||
88 | } | ||
89 | |||
90 | static u8 __devinit snd_cs5530_mixer_read(unsigned long io, u8 reg) | ||
91 | { | ||
92 | outb(reg, io + 4); | ||
93 | udelay(20); | ||
94 | reg = inb(io + 5); | ||
95 | udelay(20); | ||
96 | return reg; | ||
97 | } | ||
98 | |||
99 | static int __devinit snd_cs5530_create(struct snd_card *card, | ||
100 | struct pci_dev *pci, | ||
101 | struct snd_cs5530 **rchip) | ||
102 | { | ||
103 | struct snd_cs5530 *chip; | ||
104 | unsigned long sb_base; | ||
105 | u8 irq, dma8, dma16 = 0; | ||
106 | u16 map; | ||
107 | void __iomem *mem; | ||
108 | int err; | ||
109 | |||
110 | static struct snd_device_ops ops = { | ||
111 | .dev_free = snd_cs5530_dev_free, | ||
112 | }; | ||
113 | *rchip = NULL; | ||
114 | |||
115 | err = pci_enable_device(pci); | ||
116 | if (err < 0) | ||
117 | return err; | ||
118 | |||
119 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | ||
120 | if (chip == NULL) { | ||
121 | pci_disable_device(pci); | ||
122 | return -ENOMEM; | ||
123 | } | ||
124 | |||
125 | chip->card = card; | ||
126 | chip->pci = pci; | ||
127 | |||
128 | err = pci_request_regions(pci, "CS5530"); | ||
129 | if (err < 0) { | ||
130 | kfree(chip); | ||
131 | pci_disable_device(pci); | ||
132 | return err; | ||
133 | } | ||
134 | chip->pci_base = pci_resource_start(pci, 0); | ||
135 | |||
136 | mem = ioremap_nocache(chip->pci_base, pci_resource_len(pci, 0)); | ||
137 | if (mem == NULL) { | ||
138 | kfree(chip); | ||
139 | pci_disable_device(pci); | ||
140 | return -EBUSY; | ||
141 | } | ||
142 | |||
143 | map = readw(mem + 0x18); | ||
144 | iounmap(mem); | ||
145 | |||
146 | /* Map bits | ||
147 | 0:1 * 0x20 + 0x200 = sb base | ||
148 | 2 sb enable | ||
149 | 3 adlib enable | ||
150 | 5 MPU enable 0x330 | ||
151 | 6 MPU enable 0x300 | ||
152 | |||
153 | The other bits may be used internally so must be masked */ | ||
154 | |||
155 | sb_base = 0x220 + 0x20 * (map & 3); | ||
156 | |||
157 | if (map & (1<<2)) | ||
158 | printk(KERN_INFO "CS5530: XpressAudio at 0x%lx\n", sb_base); | ||
159 | else { | ||
160 | printk(KERN_ERR "Could not find XpressAudio!\n"); | ||
161 | snd_cs5530_free(chip); | ||
162 | return -ENODEV; | ||
163 | } | ||
164 | |||
165 | if (map & (1<<5)) | ||
166 | printk(KERN_INFO "CS5530: MPU at 0x300\n"); | ||
167 | else if (map & (1<<6)) | ||
168 | printk(KERN_INFO "CS5530: MPU at 0x330\n"); | ||
169 | |||
170 | irq = snd_cs5530_mixer_read(sb_base, 0x80) & 0x0F; | ||
171 | dma8 = snd_cs5530_mixer_read(sb_base, 0x81); | ||
172 | |||
173 | if (dma8 & 0x20) | ||
174 | dma16 = 5; | ||
175 | else if (dma8 & 0x40) | ||
176 | dma16 = 6; | ||
177 | else if (dma8 & 0x80) | ||
178 | dma16 = 7; | ||
179 | else { | ||
180 | printk(KERN_ERR "CS5530: No 16bit DMA enabled\n"); | ||
181 | snd_cs5530_free(chip); | ||
182 | return -ENODEV; | ||
183 | } | ||
184 | |||
185 | if (dma8 & 0x01) | ||
186 | dma8 = 0; | ||
187 | else if (dma8 & 02) | ||
188 | dma8 = 1; | ||
189 | else if (dma8 & 0x08) | ||
190 | dma8 = 3; | ||
191 | else { | ||
192 | printk(KERN_ERR "CS5530: No 8bit DMA enabled\n"); | ||
193 | snd_cs5530_free(chip); | ||
194 | return -ENODEV; | ||
195 | } | ||
196 | |||
197 | if (irq & 1) | ||
198 | irq = 9; | ||
199 | else if (irq & 2) | ||
200 | irq = 5; | ||
201 | else if (irq & 4) | ||
202 | irq = 7; | ||
203 | else if (irq & 8) | ||
204 | irq = 10; | ||
205 | else { | ||
206 | printk(KERN_ERR "CS5530: SoundBlaster IRQ not set\n"); | ||
207 | snd_cs5530_free(chip); | ||
208 | return -ENODEV; | ||
209 | } | ||
210 | |||
211 | printk(KERN_INFO "CS5530: IRQ: %d DMA8: %d DMA16: %d\n", irq, dma8, | ||
212 | dma16); | ||
213 | |||
214 | err = snd_sbdsp_create(card, sb_base, irq, snd_sb16dsp_interrupt, dma8, | ||
215 | dma16, SB_HW_CS5530, &chip->sb); | ||
216 | if (err < 0) { | ||
217 | printk(KERN_ERR "CS5530: Could not create SoundBlaster\n"); | ||
218 | snd_cs5530_free(chip); | ||
219 | return err; | ||
220 | } | ||
221 | |||
222 | err = snd_sb16dsp_pcm(chip->sb, 0, &chip->sb->pcm); | ||
223 | if (err < 0) { | ||
224 | printk(KERN_ERR "CS5530: Could not create PCM\n"); | ||
225 | snd_cs5530_free(chip); | ||
226 | return err; | ||
227 | } | ||
228 | |||
229 | err = snd_sbmixer_new(chip->sb); | ||
230 | if (err < 0) { | ||
231 | printk(KERN_ERR "CS5530: Could not create Mixer\n"); | ||
232 | snd_cs5530_free(chip); | ||
233 | return err; | ||
234 | } | ||
235 | |||
236 | err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); | ||
237 | if (err < 0) { | ||
238 | snd_cs5530_free(chip); | ||
239 | return err; | ||
240 | } | ||
241 | |||
242 | snd_card_set_dev(card, &pci->dev); | ||
243 | *rchip = chip; | ||
244 | return 0; | ||
245 | } | ||
246 | |||
247 | static int __devinit snd_cs5530_probe(struct pci_dev *pci, | ||
248 | const struct pci_device_id *pci_id) | ||
249 | { | ||
250 | static int dev; | ||
251 | struct snd_card *card; | ||
252 | struct snd_cs5530 *chip = NULL; | ||
253 | int err; | ||
254 | |||
255 | if (dev >= SNDRV_CARDS) | ||
256 | return -ENODEV; | ||
257 | if (!enable[dev]) { | ||
258 | dev++; | ||
259 | return -ENOENT; | ||
260 | } | ||
261 | |||
262 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | ||
263 | |||
264 | if (card == NULL) | ||
265 | return -ENOMEM; | ||
266 | |||
267 | err = snd_cs5530_create(card, pci, &chip); | ||
268 | if (err < 0) { | ||
269 | snd_card_free(card); | ||
270 | return err; | ||
271 | } | ||
272 | |||
273 | strcpy(card->driver, "CS5530"); | ||
274 | strcpy(card->shortname, "CS5530 Audio"); | ||
275 | sprintf(card->longname, "%s at 0x%lx", card->shortname, chip->pci_base); | ||
276 | |||
277 | err = snd_card_register(card); | ||
278 | if (err < 0) { | ||
279 | snd_card_free(card); | ||
280 | return err; | ||
281 | } | ||
282 | pci_set_drvdata(pci, card); | ||
283 | dev++; | ||
284 | return 0; | ||
285 | } | ||
286 | |||
287 | static struct pci_driver driver = { | ||
288 | .name = "CS5530_Audio", | ||
289 | .id_table = snd_cs5530_ids, | ||
290 | .probe = snd_cs5530_probe, | ||
291 | .remove = __devexit_p(snd_cs5530_remove), | ||
292 | }; | ||
293 | |||
294 | static int __init alsa_card_cs5530_init(void) | ||
295 | { | ||
296 | return pci_register_driver(&driver); | ||
297 | } | ||
298 | |||
299 | static void __exit alsa_card_cs5530_exit(void) | ||
300 | { | ||
301 | pci_unregister_driver(&driver); | ||
302 | } | ||
303 | |||
304 | module_init(alsa_card_cs5530_init) | ||
305 | module_exit(alsa_card_cs5530_exit) | ||
306 | |||
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index 4a9b59ad8ab1..404ae1be0a4b 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c | |||
@@ -51,9 +51,15 @@ | |||
51 | 51 | ||
52 | #define HANA_FILENAME "emu/hana.fw" | 52 | #define HANA_FILENAME "emu/hana.fw" |
53 | #define DOCK_FILENAME "emu/audio_dock.fw" | 53 | #define DOCK_FILENAME "emu/audio_dock.fw" |
54 | #define EMU1010B_FILENAME "emu/emu1010b.fw" | ||
55 | #define MICRO_DOCK_FILENAME "emu/micro_dock.fw" | ||
56 | #define EMU1010_NOTEBOOK_FILENAME "emu/emu1010_notebook.fw" | ||
54 | 57 | ||
55 | MODULE_FIRMWARE(HANA_FILENAME); | 58 | MODULE_FIRMWARE(HANA_FILENAME); |
56 | MODULE_FIRMWARE(DOCK_FILENAME); | 59 | MODULE_FIRMWARE(DOCK_FILENAME); |
60 | MODULE_FIRMWARE(EMU1010B_FILENAME); | ||
61 | MODULE_FIRMWARE(MICRO_DOCK_FILENAME); | ||
62 | MODULE_FIRMWARE(EMU1010_NOTEBOOK_FILENAME); | ||
57 | 63 | ||
58 | 64 | ||
59 | /************************************************************************* | 65 | /************************************************************************* |
@@ -660,10 +666,12 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * file | |||
660 | return err; | 666 | return err; |
661 | } | 667 | } |
662 | snd_printk(KERN_INFO "firmware size=0x%zx\n", fw_entry->size); | 668 | snd_printk(KERN_INFO "firmware size=0x%zx\n", fw_entry->size); |
669 | #if 0 | ||
663 | if (fw_entry->size != 0x133a4) { | 670 | if (fw_entry->size != 0x133a4) { |
664 | snd_printk(KERN_ERR "firmware: %s wrong size.\n",filename); | 671 | snd_printk(KERN_ERR "firmware: %s wrong size.\n",filename); |
665 | return -EINVAL; | 672 | return -EINVAL; |
666 | } | 673 | } |
674 | #endif | ||
667 | 675 | ||
668 | /* The FPGA is a Xilinx Spartan IIE XC2S50E */ | 676 | /* The FPGA is a Xilinx Spartan IIE XC2S50E */ |
669 | /* GPIO7 -> FPGA PGMN | 677 | /* GPIO7 -> FPGA PGMN |
@@ -694,6 +702,37 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * file | |||
694 | return 0; | 702 | return 0; |
695 | } | 703 | } |
696 | 704 | ||
705 | /* | ||
706 | * EMU-1010 - details found out from this driver, official MS Win drivers, | ||
707 | * testing the card: | ||
708 | * | ||
709 | * Audigy2 (aka Alice2): | ||
710 | * --------------------- | ||
711 | * * communication over PCI | ||
712 | * * conversion of 32-bit data coming over EMU32 links from HANA FPGA | ||
713 | * to 2 x 16-bit, using internal DSP instructions | ||
714 | * * slave mode, clock supplied by HANA | ||
715 | * * linked to HANA using: | ||
716 | * 32 x 32-bit serial EMU32 output channels | ||
717 | * 16 x EMU32 input channels | ||
718 | * (?) x I2S I/O channels (?) | ||
719 | * | ||
720 | * FPGA (aka HANA): | ||
721 | * --------------- | ||
722 | * * provides all (?) physical inputs and outputs of the card | ||
723 | * (ADC, DAC, SPDIF I/O, ADAT I/O, etc.) | ||
724 | * * provides clock signal for the card and Alice2 | ||
725 | * * two crystals - for 44.1kHz and 48kHz multiples | ||
726 | * * provides internal routing of signal sources to signal destinations | ||
727 | * * inputs/outputs to Alice2 - see above | ||
728 | * | ||
729 | * Current status of the driver: | ||
730 | * ---------------------------- | ||
731 | * * only 44.1/48kHz supported (the MS Win driver supports up to 192 kHz) | ||
732 | * * PCM device nb. 2: | ||
733 | * 16 x 16-bit playback - snd_emu10k1_fx8010_playback_ops | ||
734 | * 16 x 32-bit capture - snd_emu10k1_capture_efx_ops | ||
735 | */ | ||
697 | static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) | 736 | static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) |
698 | { | 737 | { |
699 | unsigned int i; | 738 | unsigned int i; |
@@ -727,7 +766,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) | |||
727 | /* ID, should read & 0x7f = 0x55. (Bit 7 is the IRQ bit) */ | 766 | /* ID, should read & 0x7f = 0x55. (Bit 7 is the IRQ bit) */ |
728 | snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® ); | 767 | snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® ); |
729 | snd_printdd("reg1=0x%x\n",reg); | 768 | snd_printdd("reg1=0x%x\n",reg); |
730 | if (reg == 0x55) { | 769 | if ((reg & 0x3f) == 0x15) { |
731 | /* FPGA netlist already present so clear it */ | 770 | /* FPGA netlist already present so clear it */ |
732 | /* Return to programming mode */ | 771 | /* Return to programming mode */ |
733 | 772 | ||
@@ -735,19 +774,32 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) | |||
735 | } | 774 | } |
736 | snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® ); | 775 | snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® ); |
737 | snd_printdd("reg2=0x%x\n",reg); | 776 | snd_printdd("reg2=0x%x\n",reg); |
738 | if (reg == 0x55) { | 777 | if ((reg & 0x3f) == 0x15) { |
739 | /* FPGA failed to return to programming mode */ | 778 | /* FPGA failed to return to programming mode */ |
779 | snd_printk(KERN_INFO "emu1010: FPGA failed to return to programming mode\n"); | ||
740 | return -ENODEV; | 780 | return -ENODEV; |
741 | } | 781 | } |
742 | snd_printk(KERN_INFO "emu1010: EMU_HANA_ID=0x%x\n",reg); | 782 | snd_printk(KERN_INFO "emu1010: EMU_HANA_ID=0x%x\n",reg); |
743 | if ((err = snd_emu1010_load_firmware(emu, HANA_FILENAME)) != 0) { | 783 | if (emu->card_capabilities->emu1010 == 1) { |
744 | snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file %s failed\n", HANA_FILENAME); | 784 | if ((err = snd_emu1010_load_firmware(emu, HANA_FILENAME)) != 0) { |
745 | return err; | 785 | snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file %s failed\n", HANA_FILENAME); |
786 | return err; | ||
787 | } | ||
788 | } else if (emu->card_capabilities->emu1010 == 2) { | ||
789 | if ((err = snd_emu1010_load_firmware(emu, EMU1010B_FILENAME)) != 0) { | ||
790 | snd_printk(KERN_INFO "emu1010: Loading Firmware file %s failed\n", EMU1010B_FILENAME); | ||
791 | return err; | ||
792 | } | ||
793 | } else if (emu->card_capabilities->emu1010 == 3) { | ||
794 | if ((err = snd_emu1010_load_firmware(emu, EMU1010_NOTEBOOK_FILENAME)) != 0) { | ||
795 | snd_printk(KERN_INFO "emu1010: Loading Firmware file %s failed\n", EMU1010_NOTEBOOK_FILENAME); | ||
796 | return err; | ||
797 | } | ||
746 | } | 798 | } |
747 | 799 | ||
748 | /* ID, should read & 0x7f = 0x55 when FPGA programmed. */ | 800 | /* ID, should read & 0x7f = 0x55 when FPGA programmed. */ |
749 | snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® ); | 801 | snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® ); |
750 | if (reg != 0x55) { | 802 | if ((reg & 0x3f) != 0x15) { |
751 | /* FPGA failed to be programmed */ | 803 | /* FPGA failed to be programmed */ |
752 | snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file failed, reg=0x%x\n", reg); | 804 | snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file failed, reg=0x%x\n", reg); |
753 | return -ENODEV; | 805 | return -ENODEV; |
@@ -850,6 +902,27 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) | |||
850 | EMU_DST_ALICE2_EMU32_6, EMU_SRC_DOCK_ADC2_LEFT1); | 902 | EMU_DST_ALICE2_EMU32_6, EMU_SRC_DOCK_ADC2_LEFT1); |
851 | snd_emu1010_fpga_link_dst_src_write(emu, | 903 | snd_emu1010_fpga_link_dst_src_write(emu, |
852 | EMU_DST_ALICE2_EMU32_7, EMU_SRC_DOCK_ADC2_RIGHT1); | 904 | EMU_DST_ALICE2_EMU32_7, EMU_SRC_DOCK_ADC2_RIGHT1); |
905 | /* Pavel Hofman - setting defaults for 8 more capture channels | ||
906 | * Defaults only, users will set their own values anyways, let's | ||
907 | * just copy/paste. | ||
908 | */ | ||
909 | |||
910 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
911 | EMU_DST_ALICE2_EMU32_8, EMU_SRC_DOCK_MIC_A1); | ||
912 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
913 | EMU_DST_ALICE2_EMU32_9, EMU_SRC_DOCK_MIC_B1); | ||
914 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
915 | EMU_DST_ALICE2_EMU32_A, EMU_SRC_HAMOA_ADC_LEFT2); | ||
916 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
917 | EMU_DST_ALICE2_EMU32_B, EMU_SRC_HAMOA_ADC_LEFT2); | ||
918 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
919 | EMU_DST_ALICE2_EMU32_C, EMU_SRC_DOCK_ADC1_LEFT1); | ||
920 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
921 | EMU_DST_ALICE2_EMU32_D, EMU_SRC_DOCK_ADC1_RIGHT1); | ||
922 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
923 | EMU_DST_ALICE2_EMU32_E, EMU_SRC_DOCK_ADC2_LEFT1); | ||
924 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
925 | EMU_DST_ALICE2_EMU32_F, EMU_SRC_DOCK_ADC2_RIGHT1); | ||
853 | #endif | 926 | #endif |
854 | #if 0 | 927 | #if 0 |
855 | /* Original */ | 928 | /* Original */ |
@@ -943,16 +1016,27 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) | |||
943 | /* Return to Audio Dock programming mode */ | 1016 | /* Return to Audio Dock programming mode */ |
944 | snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n"); | 1017 | snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n"); |
945 | snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK ); | 1018 | snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK ); |
946 | if ((err = snd_emu1010_load_firmware(emu, DOCK_FILENAME)) != 0) { | 1019 | if (emu->card_capabilities->emu1010 == 1) { |
947 | return err; | 1020 | if ((err = snd_emu1010_load_firmware(emu, DOCK_FILENAME)) != 0) { |
1021 | return err; | ||
1022 | } | ||
1023 | } else if (emu->card_capabilities->emu1010 == 2) { | ||
1024 | if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) { | ||
1025 | return err; | ||
1026 | } | ||
1027 | } else if (emu->card_capabilities->emu1010 == 3) { | ||
1028 | if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) { | ||
1029 | return err; | ||
1030 | } | ||
948 | } | 1031 | } |
1032 | |||
949 | snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0 ); | 1033 | snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0 ); |
950 | snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, ® ); | 1034 | snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, ® ); |
951 | snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_IRQ_STATUS=0x%x\n",reg); | 1035 | snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_IRQ_STATUS=0x%x\n",reg); |
952 | /* ID, should read & 0x7f = 0x55 when FPGA programmed. */ | 1036 | /* ID, should read & 0x7f = 0x55 when FPGA programmed. */ |
953 | snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® ); | 1037 | snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® ); |
954 | snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_ID=0x%x\n",reg); | 1038 | snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_ID=0x%x\n",reg); |
955 | if (reg != 0x55) { | 1039 | if ((reg & 0x3f) != 0x15) { |
956 | /* FPGA failed to be programmed */ | 1040 | /* FPGA failed to be programmed */ |
957 | snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware file failed, reg=0x%x\n", reg); | 1041 | snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware file failed, reg=0x%x\n", reg); |
958 | return 0; | 1042 | return 0; |
@@ -1227,9 +1311,15 @@ static struct snd_emu_chip_details emu_chip_details[] = { | |||
1227 | .emu10k2_chip = 1, | 1311 | .emu10k2_chip = 1, |
1228 | .ca0108_chip = 1, | 1312 | .ca0108_chip = 1, |
1229 | .ca_cardbus_chip = 1, | 1313 | .ca_cardbus_chip = 1, |
1230 | .spi_dac = 1, | 1314 | .spk71 = 1 , |
1231 | .i2c_adc = 1, | 1315 | .emu1010 = 3} , |
1232 | .spk71 = 1} , | 1316 | {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40041102, |
1317 | .driver = "Audigy2", .name = "E-mu 1010b PCI [MAEM????]", | ||
1318 | .id = "EMU1010", | ||
1319 | .emu10k2_chip = 1, | ||
1320 | .ca0108_chip = 1, | ||
1321 | .spk71 = 1 , | ||
1322 | .emu1010 = 2} , | ||
1233 | {.vendor = 0x1102, .device = 0x0008, | 1323 | {.vendor = 0x1102, .device = 0x0008, |
1234 | .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]", | 1324 | .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]", |
1235 | .id = "Audigy2", | 1325 | .id = "Audigy2", |
@@ -1663,12 +1753,13 @@ int __devinit snd_emu10k1_create(struct snd_card *card, | |||
1663 | emu->fx8010.extout_mask = extout_mask; | 1753 | emu->fx8010.extout_mask = extout_mask; |
1664 | emu->enable_ir = enable_ir; | 1754 | emu->enable_ir = enable_ir; |
1665 | 1755 | ||
1756 | if (emu->card_capabilities->ca_cardbus_chip) { | ||
1757 | if ((err = snd_emu10k1_cardbus_init(emu)) < 0) | ||
1758 | goto error; | ||
1759 | } | ||
1666 | if (emu->card_capabilities->ecard) { | 1760 | if (emu->card_capabilities->ecard) { |
1667 | if ((err = snd_emu10k1_ecard_init(emu)) < 0) | 1761 | if ((err = snd_emu10k1_ecard_init(emu)) < 0) |
1668 | goto error; | 1762 | goto error; |
1669 | } else if (emu->card_capabilities->ca_cardbus_chip) { | ||
1670 | if ((err = snd_emu10k1_cardbus_init(emu)) < 0) | ||
1671 | goto error; | ||
1672 | } else if (emu->card_capabilities->emu1010) { | 1763 | } else if (emu->card_capabilities->emu1010) { |
1673 | if ((err = snd_emu10k1_emu1010_init(emu)) < 0) { | 1764 | if ((err = snd_emu10k1_emu1010_init(emu)) < 0) { |
1674 | snd_emu10k1_free(emu); | 1765 | snd_emu10k1_free(emu); |
@@ -1814,10 +1905,10 @@ void snd_emu10k1_suspend_regs(struct snd_emu10k1 *emu) | |||
1814 | 1905 | ||
1815 | void snd_emu10k1_resume_init(struct snd_emu10k1 *emu) | 1906 | void snd_emu10k1_resume_init(struct snd_emu10k1 *emu) |
1816 | { | 1907 | { |
1908 | if (emu->card_capabilities->ca_cardbus_chip) | ||
1909 | snd_emu10k1_cardbus_init(emu); | ||
1817 | if (emu->card_capabilities->ecard) | 1910 | if (emu->card_capabilities->ecard) |
1818 | snd_emu10k1_ecard_init(emu); | 1911 | snd_emu10k1_ecard_init(emu); |
1819 | else if (emu->card_capabilities->ca_cardbus_chip) | ||
1820 | snd_emu10k1_cardbus_init(emu); | ||
1821 | else if (emu->card_capabilities->emu1010) | 1912 | else if (emu->card_capabilities->emu1010) |
1822 | snd_emu10k1_emu1010_init(emu); | 1913 | snd_emu10k1_emu1010_init(emu); |
1823 | else | 1914 | else |
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index c02012cccd8e..7206c0fa06f2 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c | |||
@@ -1123,6 +1123,11 @@ snd_emu10k1_init_stereo_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl | |||
1123 | ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF; | 1123 | ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF; |
1124 | } | 1124 | } |
1125 | 1125 | ||
1126 | /* | ||
1127 | * Used for emu1010 - conversion from 32-bit capture inputs from HANA | ||
1128 | * to 2 x 16-bit registers in audigy - their values are read via DMA. | ||
1129 | * Conversion is performed by Audigy DSP instructions of FX8010. | ||
1130 | */ | ||
1126 | static int snd_emu10k1_audigy_dsp_convert_32_to_2x16( | 1131 | static int snd_emu10k1_audigy_dsp_convert_32_to_2x16( |
1127 | struct snd_emu10k1_fx8010_code *icode, | 1132 | struct snd_emu10k1_fx8010_code *icode, |
1128 | u32 *ptr, int tmp, int bit_shifter16, | 1133 | u32 *ptr, int tmp, int bit_shifter16, |
@@ -1193,7 +1198,11 @@ static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu) | |||
1193 | snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP); | 1198 | snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP); |
1194 | 1199 | ||
1195 | #if 1 | 1200 | #if 1 |
1196 | /* PCM front Playback Volume (independent from stereo mix) */ | 1201 | /* PCM front Playback Volume (independent from stereo mix) |
1202 | * playback = 0 + ( gpr * FXBUS_PCM_LEFT_FRONT >> 31) | ||
1203 | * where gpr contains attenuation from corresponding mixer control | ||
1204 | * (snd_emu10k1_init_stereo_control) | ||
1205 | */ | ||
1197 | A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT)); | 1206 | A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT)); |
1198 | A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT)); | 1207 | A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT)); |
1199 | snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100); | 1208 | snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100); |
@@ -1549,7 +1558,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) | |||
1549 | 1558 | ||
1550 | if (emu->card_capabilities->emu1010) { | 1559 | if (emu->card_capabilities->emu1010) { |
1551 | snd_printk("EMU inputs on\n"); | 1560 | snd_printk("EMU inputs on\n"); |
1552 | /* Capture 8 channels of S32_LE sound */ | 1561 | /* Capture 16 (originally 8) channels of S32_LE sound */ |
1553 | 1562 | ||
1554 | /* printk("emufx.c: gpr=0x%x, tmp=0x%x\n",gpr, tmp); */ | 1563 | /* printk("emufx.c: gpr=0x%x, tmp=0x%x\n",gpr, tmp); */ |
1555 | /* For the EMU1010: How to get 32bit values from the DSP. High 16bits into L, low 16bits into R. */ | 1564 | /* For the EMU1010: How to get 32bit values from the DSP. High 16bits into L, low 16bits into R. */ |
@@ -1560,6 +1569,11 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) | |||
1560 | snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_P16VIN(0x0), A_FXBUS2(0) ); | 1569 | snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_P16VIN(0x0), A_FXBUS2(0) ); |
1561 | /* Right ADC in 1 of 2 */ | 1570 | /* Right ADC in 1 of 2 */ |
1562 | gpr_map[gpr++] = 0x00000000; | 1571 | gpr_map[gpr++] = 0x00000000; |
1572 | /* Delaying by one sample: instead of copying the input | ||
1573 | * value A_P16VIN to output A_FXBUS2 as in the first channel, | ||
1574 | * we use an auxiliary register, delaying the value by one | ||
1575 | * sample | ||
1576 | */ | ||
1563 | snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(2) ); | 1577 | snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(2) ); |
1564 | A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x1), A_C_00000000, A_C_00000000); | 1578 | A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x1), A_C_00000000, A_C_00000000); |
1565 | gpr_map[gpr++] = 0x00000000; | 1579 | gpr_map[gpr++] = 0x00000000; |
@@ -1583,6 +1597,66 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) | |||
1583 | gpr_map[gpr++] = 0x00000000; | 1597 | gpr_map[gpr++] = 0x00000000; |
1584 | snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xe) ); | 1598 | snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xe) ); |
1585 | A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x7), A_C_00000000, A_C_00000000); | 1599 | A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x7), A_C_00000000, A_C_00000000); |
1600 | /* Pavel Hofman - we still have voices, A_FXBUS2s, and | ||
1601 | * A_P16VINs available - | ||
1602 | * let's add 8 more capture channels - total of 16 | ||
1603 | */ | ||
1604 | gpr_map[gpr++] = 0x00000000; | ||
1605 | snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, | ||
1606 | bit_shifter16, | ||
1607 | A_GPR(gpr - 1), | ||
1608 | A_FXBUS2(0x10)); | ||
1609 | A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x8), | ||
1610 | A_C_00000000, A_C_00000000); | ||
1611 | gpr_map[gpr++] = 0x00000000; | ||
1612 | snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, | ||
1613 | bit_shifter16, | ||
1614 | A_GPR(gpr - 1), | ||
1615 | A_FXBUS2(0x12)); | ||
1616 | A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x9), | ||
1617 | A_C_00000000, A_C_00000000); | ||
1618 | gpr_map[gpr++] = 0x00000000; | ||
1619 | snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, | ||
1620 | bit_shifter16, | ||
1621 | A_GPR(gpr - 1), | ||
1622 | A_FXBUS2(0x14)); | ||
1623 | A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xa), | ||
1624 | A_C_00000000, A_C_00000000); | ||
1625 | gpr_map[gpr++] = 0x00000000; | ||
1626 | snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, | ||
1627 | bit_shifter16, | ||
1628 | A_GPR(gpr - 1), | ||
1629 | A_FXBUS2(0x16)); | ||
1630 | A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xb), | ||
1631 | A_C_00000000, A_C_00000000); | ||
1632 | gpr_map[gpr++] = 0x00000000; | ||
1633 | snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, | ||
1634 | bit_shifter16, | ||
1635 | A_GPR(gpr - 1), | ||
1636 | A_FXBUS2(0x18)); | ||
1637 | A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xc), | ||
1638 | A_C_00000000, A_C_00000000); | ||
1639 | gpr_map[gpr++] = 0x00000000; | ||
1640 | snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, | ||
1641 | bit_shifter16, | ||
1642 | A_GPR(gpr - 1), | ||
1643 | A_FXBUS2(0x1a)); | ||
1644 | A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xd), | ||
1645 | A_C_00000000, A_C_00000000); | ||
1646 | gpr_map[gpr++] = 0x00000000; | ||
1647 | snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, | ||
1648 | bit_shifter16, | ||
1649 | A_GPR(gpr - 1), | ||
1650 | A_FXBUS2(0x1c)); | ||
1651 | A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xe), | ||
1652 | A_C_00000000, A_C_00000000); | ||
1653 | gpr_map[gpr++] = 0x00000000; | ||
1654 | snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, | ||
1655 | bit_shifter16, | ||
1656 | A_GPR(gpr - 1), | ||
1657 | A_FXBUS2(0x1e)); | ||
1658 | A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xf), | ||
1659 | A_C_00000000, A_C_00000000); | ||
1586 | 1660 | ||
1587 | #if 0 | 1661 | #if 0 |
1588 | for (z = 4; z < 8; z++) { | 1662 | for (z = 4; z < 8; z++) { |
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c index 4db6e1ca1665..7b2c1dcc5337 100644 --- a/sound/pci/emu10k1/emumixer.c +++ b/sound/pci/emu10k1/emumixer.c | |||
@@ -77,6 +77,10 @@ static int snd_emu10k1_spdif_get_mask(struct snd_kcontrol *kcontrol, | |||
77 | return 0; | 77 | return 0; |
78 | } | 78 | } |
79 | 79 | ||
80 | /* | ||
81 | * Items labels in enum mixer controls assigning source data to | ||
82 | * each destination | ||
83 | */ | ||
80 | static char *emu1010_src_texts[] = { | 84 | static char *emu1010_src_texts[] = { |
81 | "Silence", | 85 | "Silence", |
82 | "Dock Mic A", | 86 | "Dock Mic A", |
@@ -133,6 +137,9 @@ static char *emu1010_src_texts[] = { | |||
133 | "DSP 31", | 137 | "DSP 31", |
134 | }; | 138 | }; |
135 | 139 | ||
140 | /* | ||
141 | * List of data sources available for each destination | ||
142 | */ | ||
136 | static unsigned int emu1010_src_regs[] = { | 143 | static unsigned int emu1010_src_regs[] = { |
137 | EMU_SRC_SILENCE,/* 0 */ | 144 | EMU_SRC_SILENCE,/* 0 */ |
138 | EMU_SRC_DOCK_MIC_A1, /* 1 */ | 145 | EMU_SRC_DOCK_MIC_A1, /* 1 */ |
@@ -189,6 +196,10 @@ static unsigned int emu1010_src_regs[] = { | |||
189 | EMU_SRC_ALICE_EMU32B+0xf, /* 52 */ | 196 | EMU_SRC_ALICE_EMU32B+0xf, /* 52 */ |
190 | }; | 197 | }; |
191 | 198 | ||
199 | /* | ||
200 | * Data destinations - physical EMU outputs. | ||
201 | * Each destination has an enum mixer control to choose a data source | ||
202 | */ | ||
192 | static unsigned int emu1010_output_dst[] = { | 203 | static unsigned int emu1010_output_dst[] = { |
193 | EMU_DST_DOCK_DAC1_LEFT1, /* 0 */ | 204 | EMU_DST_DOCK_DAC1_LEFT1, /* 0 */ |
194 | EMU_DST_DOCK_DAC1_RIGHT1, /* 1 */ | 205 | EMU_DST_DOCK_DAC1_RIGHT1, /* 1 */ |
@@ -216,6 +227,11 @@ static unsigned int emu1010_output_dst[] = { | |||
216 | EMU_DST_HANA_ADAT+7, /* 23 */ | 227 | EMU_DST_HANA_ADAT+7, /* 23 */ |
217 | }; | 228 | }; |
218 | 229 | ||
230 | /* | ||
231 | * Data destinations - HANA outputs going to Alice2 (audigy) for | ||
232 | * capture (EMU32 + I2S links) | ||
233 | * Each destination has an enum mixer control to choose a data source | ||
234 | */ | ||
219 | static unsigned int emu1010_input_dst[] = { | 235 | static unsigned int emu1010_input_dst[] = { |
220 | EMU_DST_ALICE2_EMU32_0, | 236 | EMU_DST_ALICE2_EMU32_0, |
221 | EMU_DST_ALICE2_EMU32_1, | 237 | EMU_DST_ALICE2_EMU32_1, |
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c index ab4f5df5241b..eda5cb373ded 100644 --- a/sound/pci/emu10k1/emupcm.c +++ b/sound/pci/emu10k1/emupcm.c | |||
@@ -1233,24 +1233,26 @@ static int snd_emu10k1_capture_efx_open(struct snd_pcm_substream *substream) | |||
1233 | runtime->hw.rate_min = runtime->hw.rate_max = 48000; | 1233 | runtime->hw.rate_min = runtime->hw.rate_max = 48000; |
1234 | spin_lock_irq(&emu->reg_lock); | 1234 | spin_lock_irq(&emu->reg_lock); |
1235 | if (emu->card_capabilities->emu1010) { | 1235 | if (emu->card_capabilities->emu1010) { |
1236 | /* TODO | 1236 | /* Nb. of channels has been increased to 16 */ |
1237 | /* TODO | ||
1237 | * SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE | 1238 | * SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE |
1238 | * SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | | 1239 | * SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | |
1239 | * SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | | 1240 | * SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | |
1240 | * SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000 | 1241 | * SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000 |
1241 | * rate_min = 44100, | 1242 | * rate_min = 44100, |
1242 | * rate_max = 192000, | 1243 | * rate_max = 192000, |
1243 | * channels_min = 8, | 1244 | * channels_min = 16, |
1244 | * channels_max = 8, | 1245 | * channels_max = 16, |
1245 | * Need to add mixer control to fix sample rate | 1246 | * Need to add mixer control to fix sample rate |
1246 | * | 1247 | * |
1247 | * There are 16 mono channels of 16bits each. | 1248 | * There are 32 mono channels of 16bits each. |
1248 | * 24bit Audio uses 2x channels over 16bit | 1249 | * 24bit Audio uses 2x channels over 16bit |
1249 | * 96kHz uses 2x channels over 48kHz | 1250 | * 96kHz uses 2x channels over 48kHz |
1250 | * 192kHz uses 4x channels over 48kHz | 1251 | * 192kHz uses 4x channels over 48kHz |
1251 | * So, for 48kHz 24bit, one has 8 channels | 1252 | * So, for 48kHz 24bit, one has 16 channels |
1252 | * for 96kHz 24bit, one has 4 channels | 1253 | * for 96kHz 24bit, one has 8 channels |
1253 | * for 192kHz 24bit, one has 2 channels | 1254 | * for 192kHz 24bit, one has 4 channels |
1255 | * | ||
1254 | */ | 1256 | */ |
1255 | #if 1 | 1257 | #if 1 |
1256 | switch (emu->emu1010.internal_clock) { | 1258 | switch (emu->emu1010.internal_clock) { |
@@ -1258,13 +1260,15 @@ static int snd_emu10k1_capture_efx_open(struct snd_pcm_substream *substream) | |||
1258 | /* For 44.1kHz */ | 1260 | /* For 44.1kHz */ |
1259 | runtime->hw.rates = SNDRV_PCM_RATE_44100; | 1261 | runtime->hw.rates = SNDRV_PCM_RATE_44100; |
1260 | runtime->hw.rate_min = runtime->hw.rate_max = 44100; | 1262 | runtime->hw.rate_min = runtime->hw.rate_max = 44100; |
1261 | runtime->hw.channels_min = runtime->hw.channels_max = 8; | 1263 | runtime->hw.channels_min = |
1264 | runtime->hw.channels_max = 16; | ||
1262 | break; | 1265 | break; |
1263 | case 1: | 1266 | case 1: |
1264 | /* For 48kHz */ | 1267 | /* For 48kHz */ |
1265 | runtime->hw.rates = SNDRV_PCM_RATE_48000; | 1268 | runtime->hw.rates = SNDRV_PCM_RATE_48000; |
1266 | runtime->hw.rate_min = runtime->hw.rate_max = 48000; | 1269 | runtime->hw.rate_min = runtime->hw.rate_max = 48000; |
1267 | runtime->hw.channels_min = runtime->hw.channels_max = 8; | 1270 | runtime->hw.channels_min = |
1271 | runtime->hw.channels_max = 16; | ||
1268 | break; | 1272 | break; |
1269 | }; | 1273 | }; |
1270 | #endif | 1274 | #endif |
@@ -1282,7 +1286,7 @@ static int snd_emu10k1_capture_efx_open(struct snd_pcm_substream *substream) | |||
1282 | #endif | 1286 | #endif |
1283 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE; | 1287 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE; |
1284 | /* efx_voices_mask[0] is expected to be zero | 1288 | /* efx_voices_mask[0] is expected to be zero |
1285 | * efx_voices_mask[1] is expected to have 16bits set | 1289 | * efx_voices_mask[1] is expected to have 32bits set |
1286 | */ | 1290 | */ |
1287 | } else { | 1291 | } else { |
1288 | runtime->hw.channels_min = runtime->hw.channels_max = 0; | 1292 | runtime->hw.channels_min = runtime->hw.channels_max = 0; |
@@ -1787,11 +1791,24 @@ int __devinit snd_emu10k1_pcm_efx(struct snd_emu10k1 * emu, int device, struct s | |||
1787 | /* emu->efx_voices_mask[0] = FXWC_DEFAULTROUTE_C | FXWC_DEFAULTROUTE_A; */ | 1791 | /* emu->efx_voices_mask[0] = FXWC_DEFAULTROUTE_C | FXWC_DEFAULTROUTE_A; */ |
1788 | if (emu->audigy) { | 1792 | if (emu->audigy) { |
1789 | emu->efx_voices_mask[0] = 0; | 1793 | emu->efx_voices_mask[0] = 0; |
1790 | emu->efx_voices_mask[1] = 0xffff; | 1794 | if (emu->card_capabilities->emu1010) |
1795 | /* Pavel Hofman - 32 voices will be used for | ||
1796 | * capture (write mode) - | ||
1797 | * each bit = corresponding voice | ||
1798 | */ | ||
1799 | emu->efx_voices_mask[1] = 0xffffffff; | ||
1800 | else | ||
1801 | emu->efx_voices_mask[1] = 0xffff; | ||
1791 | } else { | 1802 | } else { |
1792 | emu->efx_voices_mask[0] = 0xffff0000; | 1803 | emu->efx_voices_mask[0] = 0xffff0000; |
1793 | emu->efx_voices_mask[1] = 0; | 1804 | emu->efx_voices_mask[1] = 0; |
1794 | } | 1805 | } |
1806 | /* For emu1010, the control has to set 32 upper bits (voices) | ||
1807 | * out of the 64 bits (voices) to true for the 16-channels capture | ||
1808 | * to work correctly. Correct A_FXWC2 initial value (0xffffffff) | ||
1809 | * is already defined but the snd_emu10k1_pcm_efx_voices_mask | ||
1810 | * control can override this register's value. | ||
1811 | */ | ||
1795 | kctl = snd_ctl_new1(&snd_emu10k1_pcm_efx_voices_mask, emu); | 1812 | kctl = snd_ctl_new1(&snd_emu10k1_pcm_efx_voices_mask, emu); |
1796 | if (!kctl) | 1813 | if (!kctl) |
1797 | return -ENOMEM; | 1814 | return -ENOMEM; |
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c index 7c403965153b..21cb4268a59b 100644 --- a/sound/pci/ens1370.c +++ b/sound/pci/ens1370.c | |||
@@ -1607,8 +1607,8 @@ struct es1371_quirk { | |||
1607 | unsigned char rev; /* revision */ | 1607 | unsigned char rev; /* revision */ |
1608 | }; | 1608 | }; |
1609 | 1609 | ||
1610 | static int __devinit es1371_quirk_lookup(struct ensoniq *ensoniq, | 1610 | static int es1371_quirk_lookup(struct ensoniq *ensoniq, |
1611 | struct es1371_quirk *list) | 1611 | struct es1371_quirk *list) |
1612 | { | 1612 | { |
1613 | while (list->vid != (unsigned short)PCI_ANY_ID) { | 1613 | while (list->vid != (unsigned short)PCI_ANY_ID) { |
1614 | if (ensoniq->pci->vendor == list->vid && | 1614 | if (ensoniq->pci->vendor == list->vid && |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 2fa281cbef91..92bc8b3fa2a0 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -341,6 +341,9 @@ struct azx { | |||
341 | unsigned int single_cmd :1; | 341 | unsigned int single_cmd :1; |
342 | unsigned int polling_mode :1; | 342 | unsigned int polling_mode :1; |
343 | unsigned int msi :1; | 343 | unsigned int msi :1; |
344 | |||
345 | /* for debugging */ | ||
346 | unsigned int last_cmd; /* last issued command (to sync) */ | ||
344 | }; | 347 | }; |
345 | 348 | ||
346 | /* driver types */ | 349 | /* driver types */ |
@@ -466,18 +469,10 @@ static void azx_free_cmd_io(struct azx *chip) | |||
466 | } | 469 | } |
467 | 470 | ||
468 | /* send a command */ | 471 | /* send a command */ |
469 | static int azx_corb_send_cmd(struct hda_codec *codec, hda_nid_t nid, int direct, | 472 | static int azx_corb_send_cmd(struct hda_codec *codec, u32 val) |
470 | unsigned int verb, unsigned int para) | ||
471 | { | 473 | { |
472 | struct azx *chip = codec->bus->private_data; | 474 | struct azx *chip = codec->bus->private_data; |
473 | unsigned int wp; | 475 | unsigned int wp; |
474 | u32 val; | ||
475 | |||
476 | val = (u32)(codec->addr & 0x0f) << 28; | ||
477 | val |= (u32)direct << 27; | ||
478 | val |= (u32)nid << 20; | ||
479 | val |= verb << 8; | ||
480 | val |= para; | ||
481 | 476 | ||
482 | /* add command to corb */ | 477 | /* add command to corb */ |
483 | wp = azx_readb(chip, CORBWP); | 478 | wp = azx_readb(chip, CORBWP); |
@@ -538,12 +533,12 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec) | |||
538 | } | 533 | } |
539 | if (! chip->rirb.cmds) | 534 | if (! chip->rirb.cmds) |
540 | return chip->rirb.res; /* the last value */ | 535 | return chip->rirb.res; /* the last value */ |
541 | schedule_timeout_interruptible(1); | 536 | schedule_timeout(1); |
542 | } while (time_after_eq(timeout, jiffies)); | 537 | } while (time_after_eq(timeout, jiffies)); |
543 | 538 | ||
544 | if (chip->msi) { | 539 | if (chip->msi) { |
545 | snd_printk(KERN_WARNING "hda_intel: No response from codec, " | 540 | snd_printk(KERN_WARNING "hda_intel: No response from codec, " |
546 | "disabling MSI...\n"); | 541 | "disabling MSI: last cmd=0x%08x\n", chip->last_cmd); |
547 | free_irq(chip->irq, chip); | 542 | free_irq(chip->irq, chip); |
548 | chip->irq = -1; | 543 | chip->irq = -1; |
549 | pci_disable_msi(chip->pci); | 544 | pci_disable_msi(chip->pci); |
@@ -555,13 +550,15 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec) | |||
555 | 550 | ||
556 | if (!chip->polling_mode) { | 551 | if (!chip->polling_mode) { |
557 | snd_printk(KERN_WARNING "hda_intel: azx_get_response timeout, " | 552 | snd_printk(KERN_WARNING "hda_intel: azx_get_response timeout, " |
558 | "switching to polling mode...\n"); | 553 | "switching to polling mode: last cmd=0x%08x\n", |
554 | chip->last_cmd); | ||
559 | chip->polling_mode = 1; | 555 | chip->polling_mode = 1; |
560 | goto again; | 556 | goto again; |
561 | } | 557 | } |
562 | 558 | ||
563 | snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, " | 559 | snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, " |
564 | "switching to single_cmd mode...\n"); | 560 | "switching to single_cmd mode: last cmd=0x%08x\n", |
561 | chip->last_cmd); | ||
565 | chip->rirb.rp = azx_readb(chip, RIRBWP); | 562 | chip->rirb.rp = azx_readb(chip, RIRBWP); |
566 | chip->rirb.cmds = 0; | 563 | chip->rirb.cmds = 0; |
567 | /* switch to single_cmd mode */ | 564 | /* switch to single_cmd mode */ |
@@ -581,20 +578,11 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec) | |||
581 | */ | 578 | */ |
582 | 579 | ||
583 | /* send a command */ | 580 | /* send a command */ |
584 | static int azx_single_send_cmd(struct hda_codec *codec, hda_nid_t nid, | 581 | static int azx_single_send_cmd(struct hda_codec *codec, u32 val) |
585 | int direct, unsigned int verb, | ||
586 | unsigned int para) | ||
587 | { | 582 | { |
588 | struct azx *chip = codec->bus->private_data; | 583 | struct azx *chip = codec->bus->private_data; |
589 | u32 val; | ||
590 | int timeout = 50; | 584 | int timeout = 50; |
591 | 585 | ||
592 | val = (u32)(codec->addr & 0x0f) << 28; | ||
593 | val |= (u32)direct << 27; | ||
594 | val |= (u32)nid << 20; | ||
595 | val |= verb << 8; | ||
596 | val |= para; | ||
597 | |||
598 | while (timeout--) { | 586 | while (timeout--) { |
599 | /* check ICB busy bit */ | 587 | /* check ICB busy bit */ |
600 | if (! (azx_readw(chip, IRS) & ICH6_IRS_BUSY)) { | 588 | if (! (azx_readw(chip, IRS) & ICH6_IRS_BUSY)) { |
@@ -639,10 +627,19 @@ static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid, | |||
639 | unsigned int para) | 627 | unsigned int para) |
640 | { | 628 | { |
641 | struct azx *chip = codec->bus->private_data; | 629 | struct azx *chip = codec->bus->private_data; |
630 | u32 val; | ||
631 | |||
632 | val = (u32)(codec->addr & 0x0f) << 28; | ||
633 | val |= (u32)direct << 27; | ||
634 | val |= (u32)nid << 20; | ||
635 | val |= verb << 8; | ||
636 | val |= para; | ||
637 | chip->last_cmd = val; | ||
638 | |||
642 | if (chip->single_cmd) | 639 | if (chip->single_cmd) |
643 | return azx_single_send_cmd(codec, nid, direct, verb, para); | 640 | return azx_single_send_cmd(codec, val); |
644 | else | 641 | else |
645 | return azx_corb_send_cmd(codec, nid, direct, verb, para); | 642 | return azx_corb_send_cmd(codec, val); |
646 | } | 643 | } |
647 | 644 | ||
648 | /* get a response */ | 645 | /* get a response */ |
@@ -1788,6 +1785,12 @@ static struct pci_device_id azx_ids[] = { | |||
1788 | { 0x10de, 0x044b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP65 */ | 1785 | { 0x10de, 0x044b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP65 */ |
1789 | { 0x10de, 0x055c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP67 */ | 1786 | { 0x10de, 0x055c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP67 */ |
1790 | { 0x10de, 0x055d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP67 */ | 1787 | { 0x10de, 0x055d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP67 */ |
1788 | { 0x10de, 0x07fc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP73 */ | ||
1789 | { 0x10de, 0x07fd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP73 */ | ||
1790 | { 0x10de, 0x0774, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP77 */ | ||
1791 | { 0x10de, 0x0775, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP77 */ | ||
1792 | { 0x10de, 0x0776, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP77 */ | ||
1793 | { 0x10de, 0x0777, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP77 */ | ||
1791 | { 0, } | 1794 | { 0, } |
1792 | }; | 1795 | }; |
1793 | MODULE_DEVICE_TABLE(pci, azx_ids); | 1796 | MODULE_DEVICE_TABLE(pci, azx_ids); |
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index e313e685f161..ac15066fd300 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c | |||
@@ -250,6 +250,12 @@ static void print_codec_info(struct snd_info_entry *entry, struct snd_info_buffe | |||
250 | snd_iprintf(buffer, "Vendor Id: 0x%x\n", codec->vendor_id); | 250 | snd_iprintf(buffer, "Vendor Id: 0x%x\n", codec->vendor_id); |
251 | snd_iprintf(buffer, "Subsystem Id: 0x%x\n", codec->subsystem_id); | 251 | snd_iprintf(buffer, "Subsystem Id: 0x%x\n", codec->subsystem_id); |
252 | snd_iprintf(buffer, "Revision Id: 0x%x\n", codec->revision_id); | 252 | snd_iprintf(buffer, "Revision Id: 0x%x\n", codec->revision_id); |
253 | |||
254 | if (codec->mfg) | ||
255 | snd_iprintf(buffer, "Modem Function Group: 0x%x\n", codec->mfg); | ||
256 | else | ||
257 | snd_iprintf(buffer, "No Modem Function Group found\n"); | ||
258 | |||
253 | if (! codec->afg) | 259 | if (! codec->afg) |
254 | return; | 260 | return; |
255 | snd_iprintf(buffer, "Default PCM:\n"); | 261 | snd_iprintf(buffer, "Default PCM:\n"); |
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 0e1a879663fa..4d7f8d11ad75 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -1,7 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * HD audio interface patch for AD1981HD, AD1983, AD1986A, AD1988 | 2 | * HD audio interface patch for AD1882, AD1884, AD1981HD, AD1983, AD1984, |
3 | * AD1986A, AD1988 | ||
3 | * | 4 | * |
4 | * Copyright (c) 2005 Takashi Iwai <tiwai@suse.de> | 5 | * Copyright (c) 2005-2007 Takashi Iwai <tiwai@suse.de> |
5 | * | 6 | * |
6 | * This driver is free software; you can redistribute it and/or modify | 7 | * This driver 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 | * it under the terms of the GNU General Public License as published by |
@@ -61,7 +62,7 @@ struct ad198x_spec { | |||
61 | int num_channel_mode; | 62 | int num_channel_mode; |
62 | 63 | ||
63 | /* PCM information */ | 64 | /* PCM information */ |
64 | struct hda_pcm pcm_rec[2]; /* used in alc_build_pcms() */ | 65 | struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ |
65 | 66 | ||
66 | struct mutex amp_mutex; /* PCM volume/mute control mutex */ | 67 | struct mutex amp_mutex; /* PCM volume/mute control mutex */ |
67 | unsigned int spdif_route; | 68 | unsigned int spdif_route; |
@@ -2775,11 +2776,634 @@ static int patch_ad1988(struct hda_codec *codec) | |||
2775 | 2776 | ||
2776 | 2777 | ||
2777 | /* | 2778 | /* |
2779 | * AD1884 / AD1984 | ||
2780 | * | ||
2781 | * port-B - front line/mic-in | ||
2782 | * port-E - aux in/out | ||
2783 | * port-F - aux in/out | ||
2784 | * port-C - rear line/mic-in | ||
2785 | * port-D - rear line/hp-out | ||
2786 | * port-A - front line/hp-out | ||
2787 | * | ||
2788 | * AD1984 = AD1884 + two digital mic-ins | ||
2789 | * | ||
2790 | * FIXME: | ||
2791 | * For simplicity, we share the single DAC for both HP and line-outs | ||
2792 | * right now. The inidividual playbacks could be easily implemented, | ||
2793 | * but no build-up framework is given, so far. | ||
2794 | */ | ||
2795 | |||
2796 | static hda_nid_t ad1884_dac_nids[1] = { | ||
2797 | 0x04, | ||
2798 | }; | ||
2799 | |||
2800 | static hda_nid_t ad1884_adc_nids[2] = { | ||
2801 | 0x08, 0x09, | ||
2802 | }; | ||
2803 | |||
2804 | static hda_nid_t ad1884_capsrc_nids[2] = { | ||
2805 | 0x0c, 0x0d, | ||
2806 | }; | ||
2807 | |||
2808 | #define AD1884_SPDIF_OUT 0x02 | ||
2809 | |||
2810 | static struct hda_input_mux ad1884_capture_source = { | ||
2811 | .num_items = 4, | ||
2812 | .items = { | ||
2813 | { "Front Mic", 0x0 }, | ||
2814 | { "Mic", 0x1 }, | ||
2815 | { "CD", 0x2 }, | ||
2816 | { "Mix", 0x3 }, | ||
2817 | }, | ||
2818 | }; | ||
2819 | |||
2820 | static struct snd_kcontrol_new ad1884_base_mixers[] = { | ||
2821 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), | ||
2822 | /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */ | ||
2823 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), | ||
2824 | HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT), | ||
2825 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT), | ||
2826 | HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT), | ||
2827 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), | ||
2828 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), | ||
2829 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT), | ||
2830 | HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT), | ||
2831 | HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT), | ||
2832 | HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT), | ||
2833 | /* | ||
2834 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x20, 0x03, HDA_INPUT), | ||
2835 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x20, 0x03, HDA_INPUT), | ||
2836 | HDA_CODEC_VOLUME("Digital Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT), | ||
2837 | HDA_CODEC_MUTE("Digital Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT), | ||
2838 | */ | ||
2839 | HDA_CODEC_VOLUME("Mic Boost", 0x15, 0x0, HDA_INPUT), | ||
2840 | HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT), | ||
2841 | HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
2842 | HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), | ||
2843 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), | ||
2844 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT), | ||
2845 | { | ||
2846 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2847 | /* The multiple "Capture Source" controls confuse alsamixer | ||
2848 | * So call somewhat different.. | ||
2849 | * FIXME: the controls appear in the "playback" view! | ||
2850 | */ | ||
2851 | /* .name = "Capture Source", */ | ||
2852 | .name = "Input Source", | ||
2853 | .count = 2, | ||
2854 | .info = ad198x_mux_enum_info, | ||
2855 | .get = ad198x_mux_enum_get, | ||
2856 | .put = ad198x_mux_enum_put, | ||
2857 | }, | ||
2858 | /* SPDIF controls */ | ||
2859 | HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), | ||
2860 | { | ||
2861 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2862 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", | ||
2863 | /* identical with ad1983 */ | ||
2864 | .info = ad1983_spdif_route_info, | ||
2865 | .get = ad1983_spdif_route_get, | ||
2866 | .put = ad1983_spdif_route_put, | ||
2867 | }, | ||
2868 | { } /* end */ | ||
2869 | }; | ||
2870 | |||
2871 | static struct snd_kcontrol_new ad1984_dmic_mixers[] = { | ||
2872 | HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x05, 0x0, HDA_INPUT), | ||
2873 | HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x05, 0x0, HDA_INPUT), | ||
2874 | HDA_CODEC_VOLUME_IDX("Digital Mic Capture Volume", 1, 0x06, 0x0, | ||
2875 | HDA_INPUT), | ||
2876 | HDA_CODEC_MUTE_IDX("Digital Mic Capture Switch", 1, 0x06, 0x0, | ||
2877 | HDA_INPUT), | ||
2878 | { } /* end */ | ||
2879 | }; | ||
2880 | |||
2881 | /* | ||
2882 | * initialization verbs | ||
2883 | */ | ||
2884 | static struct hda_verb ad1884_init_verbs[] = { | ||
2885 | /* DACs; mute as default */ | ||
2886 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
2887 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
2888 | /* Port-A (HP) mixer */ | ||
2889 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
2890 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
2891 | /* Port-A pin */ | ||
2892 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
2893 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
2894 | /* HP selector - select DAC2 */ | ||
2895 | {0x22, AC_VERB_SET_CONNECT_SEL, 0x1}, | ||
2896 | /* Port-D (Line-out) mixer */ | ||
2897 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
2898 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
2899 | /* Port-D pin */ | ||
2900 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
2901 | {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
2902 | /* Mono-out mixer */ | ||
2903 | {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
2904 | {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
2905 | /* Mono-out pin */ | ||
2906 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
2907 | {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
2908 | /* Mono selector */ | ||
2909 | {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1}, | ||
2910 | /* Port-B (front mic) pin */ | ||
2911 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
2912 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
2913 | /* Port-C (rear mic) pin */ | ||
2914 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
2915 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
2916 | /* Analog mixer; mute as default */ | ||
2917 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2918 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
2919 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
2920 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
2921 | /* Analog Mix output amp */ | ||
2922 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */ | ||
2923 | /* SPDIF output selector */ | ||
2924 | {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */ | ||
2925 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ | ||
2926 | { } /* end */ | ||
2927 | }; | ||
2928 | |||
2929 | static int patch_ad1884(struct hda_codec *codec) | ||
2930 | { | ||
2931 | struct ad198x_spec *spec; | ||
2932 | |||
2933 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
2934 | if (spec == NULL) | ||
2935 | return -ENOMEM; | ||
2936 | |||
2937 | mutex_init(&spec->amp_mutex); | ||
2938 | codec->spec = spec; | ||
2939 | |||
2940 | spec->multiout.max_channels = 2; | ||
2941 | spec->multiout.num_dacs = ARRAY_SIZE(ad1884_dac_nids); | ||
2942 | spec->multiout.dac_nids = ad1884_dac_nids; | ||
2943 | spec->multiout.dig_out_nid = AD1884_SPDIF_OUT; | ||
2944 | spec->num_adc_nids = ARRAY_SIZE(ad1884_adc_nids); | ||
2945 | spec->adc_nids = ad1884_adc_nids; | ||
2946 | spec->capsrc_nids = ad1884_capsrc_nids; | ||
2947 | spec->input_mux = &ad1884_capture_source; | ||
2948 | spec->num_mixers = 1; | ||
2949 | spec->mixers[0] = ad1884_base_mixers; | ||
2950 | spec->num_init_verbs = 1; | ||
2951 | spec->init_verbs[0] = ad1884_init_verbs; | ||
2952 | spec->spdif_route = 0; | ||
2953 | |||
2954 | codec->patch_ops = ad198x_patch_ops; | ||
2955 | |||
2956 | return 0; | ||
2957 | } | ||
2958 | |||
2959 | /* | ||
2960 | * Lenovo Thinkpad T61/X61 | ||
2961 | */ | ||
2962 | static struct hda_input_mux ad1984_thinkpad_capture_source = { | ||
2963 | .num_items = 3, | ||
2964 | .items = { | ||
2965 | { "Mic", 0x0 }, | ||
2966 | { "Internal Mic", 0x1 }, | ||
2967 | { "Mix", 0x3 }, | ||
2968 | }, | ||
2969 | }; | ||
2970 | |||
2971 | static struct snd_kcontrol_new ad1984_thinkpad_mixers[] = { | ||
2972 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), | ||
2973 | /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */ | ||
2974 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), | ||
2975 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT), | ||
2976 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT), | ||
2977 | HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT), | ||
2978 | HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT), | ||
2979 | HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT), | ||
2980 | HDA_CODEC_VOLUME("Docking Mic Playback Volume", 0x20, 0x04, HDA_INPUT), | ||
2981 | HDA_CODEC_MUTE("Docking Mic Playback Switch", 0x20, 0x04, HDA_INPUT), | ||
2982 | HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT), | ||
2983 | HDA_CODEC_VOLUME("Internal Mic Boost", 0x15, 0x0, HDA_INPUT), | ||
2984 | HDA_CODEC_VOLUME("Docking Mic Boost", 0x25, 0x0, HDA_OUTPUT), | ||
2985 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT), | ||
2986 | HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT), | ||
2987 | HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
2988 | HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), | ||
2989 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), | ||
2990 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT), | ||
2991 | { | ||
2992 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2993 | /* The multiple "Capture Source" controls confuse alsamixer | ||
2994 | * So call somewhat different.. | ||
2995 | * FIXME: the controls appear in the "playback" view! | ||
2996 | */ | ||
2997 | /* .name = "Capture Source", */ | ||
2998 | .name = "Input Source", | ||
2999 | .count = 2, | ||
3000 | .info = ad198x_mux_enum_info, | ||
3001 | .get = ad198x_mux_enum_get, | ||
3002 | .put = ad198x_mux_enum_put, | ||
3003 | }, | ||
3004 | { } /* end */ | ||
3005 | }; | ||
3006 | |||
3007 | /* additional verbs */ | ||
3008 | static struct hda_verb ad1984_thinkpad_init_verbs[] = { | ||
3009 | /* Port-E (docking station mic) pin */ | ||
3010 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
3011 | {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
3012 | /* docking mic boost */ | ||
3013 | {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
3014 | /* Analog mixer - docking mic; mute as default */ | ||
3015 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
3016 | /* enable EAPD bit */ | ||
3017 | {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, | ||
3018 | { } /* end */ | ||
3019 | }; | ||
3020 | |||
3021 | /* Digial MIC ADC NID 0x05 + 0x06 */ | ||
3022 | static int ad1984_pcm_dmic_prepare(struct hda_pcm_stream *hinfo, | ||
3023 | struct hda_codec *codec, | ||
3024 | unsigned int stream_tag, | ||
3025 | unsigned int format, | ||
3026 | struct snd_pcm_substream *substream) | ||
3027 | { | ||
3028 | snd_hda_codec_setup_stream(codec, 0x05 + substream->number, | ||
3029 | stream_tag, 0, format); | ||
3030 | return 0; | ||
3031 | } | ||
3032 | |||
3033 | static int ad1984_pcm_dmic_cleanup(struct hda_pcm_stream *hinfo, | ||
3034 | struct hda_codec *codec, | ||
3035 | struct snd_pcm_substream *substream) | ||
3036 | { | ||
3037 | snd_hda_codec_setup_stream(codec, 0x05 + substream->number, | ||
3038 | 0, 0, 0); | ||
3039 | return 0; | ||
3040 | } | ||
3041 | |||
3042 | static struct hda_pcm_stream ad1984_pcm_dmic_capture = { | ||
3043 | .substreams = 2, | ||
3044 | .channels_min = 2, | ||
3045 | .channels_max = 2, | ||
3046 | .nid = 0x05, | ||
3047 | .ops = { | ||
3048 | .prepare = ad1984_pcm_dmic_prepare, | ||
3049 | .cleanup = ad1984_pcm_dmic_cleanup | ||
3050 | }, | ||
3051 | }; | ||
3052 | |||
3053 | static int ad1984_build_pcms(struct hda_codec *codec) | ||
3054 | { | ||
3055 | struct ad198x_spec *spec = codec->spec; | ||
3056 | struct hda_pcm *info; | ||
3057 | int err; | ||
3058 | |||
3059 | err = ad198x_build_pcms(codec); | ||
3060 | if (err < 0) | ||
3061 | return err; | ||
3062 | |||
3063 | info = spec->pcm_rec + codec->num_pcms; | ||
3064 | codec->num_pcms++; | ||
3065 | info->name = "AD1984 Digital Mic"; | ||
3066 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad1984_pcm_dmic_capture; | ||
3067 | return 0; | ||
3068 | } | ||
3069 | |||
3070 | /* models */ | ||
3071 | enum { | ||
3072 | AD1984_BASIC, | ||
3073 | AD1984_THINKPAD, | ||
3074 | AD1984_MODELS | ||
3075 | }; | ||
3076 | |||
3077 | static const char *ad1984_models[AD1984_MODELS] = { | ||
3078 | [AD1984_BASIC] = "basic", | ||
3079 | [AD1984_THINKPAD] = "thinkpad", | ||
3080 | }; | ||
3081 | |||
3082 | static struct snd_pci_quirk ad1984_cfg_tbl[] = { | ||
3083 | /* Lenovo Thinkpad T61/X61 */ | ||
3084 | SND_PCI_QUIRK(0x17aa, 0, "Lenovo Thinkpad", AD1984_THINKPAD), | ||
3085 | {} | ||
3086 | }; | ||
3087 | |||
3088 | static int patch_ad1984(struct hda_codec *codec) | ||
3089 | { | ||
3090 | struct ad198x_spec *spec; | ||
3091 | int board_config, err; | ||
3092 | |||
3093 | err = patch_ad1884(codec); | ||
3094 | if (err < 0) | ||
3095 | return err; | ||
3096 | spec = codec->spec; | ||
3097 | board_config = snd_hda_check_board_config(codec, AD1984_MODELS, | ||
3098 | ad1984_models, ad1984_cfg_tbl); | ||
3099 | switch (board_config) { | ||
3100 | case AD1984_BASIC: | ||
3101 | /* additional digital mics */ | ||
3102 | spec->mixers[spec->num_mixers++] = ad1984_dmic_mixers; | ||
3103 | codec->patch_ops.build_pcms = ad1984_build_pcms; | ||
3104 | break; | ||
3105 | case AD1984_THINKPAD: | ||
3106 | spec->multiout.dig_out_nid = 0; | ||
3107 | spec->input_mux = &ad1984_thinkpad_capture_source; | ||
3108 | spec->mixers[0] = ad1984_thinkpad_mixers; | ||
3109 | spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs; | ||
3110 | break; | ||
3111 | } | ||
3112 | return 0; | ||
3113 | } | ||
3114 | |||
3115 | |||
3116 | /* | ||
3117 | * AD1882 | ||
3118 | * | ||
3119 | * port-A - front hp-out | ||
3120 | * port-B - front mic-in | ||
3121 | * port-C - rear line-in, shared surr-out (3stack) | ||
3122 | * port-D - rear line-out | ||
3123 | * port-E - rear mic-in, shared clfe-out (3stack) | ||
3124 | * port-F - rear surr-out (6stack) | ||
3125 | * port-G - rear clfe-out (6stack) | ||
3126 | */ | ||
3127 | |||
3128 | static hda_nid_t ad1882_dac_nids[3] = { | ||
3129 | 0x04, 0x03, 0x05 | ||
3130 | }; | ||
3131 | |||
3132 | static hda_nid_t ad1882_adc_nids[2] = { | ||
3133 | 0x08, 0x09, | ||
3134 | }; | ||
3135 | |||
3136 | static hda_nid_t ad1882_capsrc_nids[2] = { | ||
3137 | 0x0c, 0x0d, | ||
3138 | }; | ||
3139 | |||
3140 | #define AD1882_SPDIF_OUT 0x02 | ||
3141 | |||
3142 | /* list: 0x11, 0x39, 0x3a, 0x18, 0x3c, 0x3b, 0x12, 0x20 */ | ||
3143 | static struct hda_input_mux ad1882_capture_source = { | ||
3144 | .num_items = 5, | ||
3145 | .items = { | ||
3146 | { "Front Mic", 0x1 }, | ||
3147 | { "Mic", 0x4 }, | ||
3148 | { "Line", 0x2 }, | ||
3149 | { "CD", 0x3 }, | ||
3150 | { "Mix", 0x7 }, | ||
3151 | }, | ||
3152 | }; | ||
3153 | |||
3154 | static struct snd_kcontrol_new ad1882_base_mixers[] = { | ||
3155 | HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), | ||
3156 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
3157 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), | ||
3158 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT), | ||
3159 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), | ||
3160 | HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT), | ||
3161 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT), | ||
3162 | HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT), | ||
3163 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), | ||
3164 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), | ||
3165 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT), | ||
3166 | HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT), | ||
3167 | HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x04, HDA_INPUT), | ||
3168 | HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x04, HDA_INPUT), | ||
3169 | HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT), | ||
3170 | HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT), | ||
3171 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x07, HDA_INPUT), | ||
3172 | HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x07, HDA_INPUT), | ||
3173 | HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT), | ||
3174 | HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT), | ||
3175 | HDA_CODEC_VOLUME("Line-In Boost", 0x3a, 0x0, HDA_OUTPUT), | ||
3176 | HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
3177 | HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), | ||
3178 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), | ||
3179 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT), | ||
3180 | { | ||
3181 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
3182 | /* The multiple "Capture Source" controls confuse alsamixer | ||
3183 | * So call somewhat different.. | ||
3184 | * FIXME: the controls appear in the "playback" view! | ||
3185 | */ | ||
3186 | /* .name = "Capture Source", */ | ||
3187 | .name = "Input Source", | ||
3188 | .count = 2, | ||
3189 | .info = ad198x_mux_enum_info, | ||
3190 | .get = ad198x_mux_enum_get, | ||
3191 | .put = ad198x_mux_enum_put, | ||
3192 | }, | ||
3193 | /* SPDIF controls */ | ||
3194 | HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), | ||
3195 | { | ||
3196 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
3197 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", | ||
3198 | /* identical with ad1983 */ | ||
3199 | .info = ad1983_spdif_route_info, | ||
3200 | .get = ad1983_spdif_route_get, | ||
3201 | .put = ad1983_spdif_route_put, | ||
3202 | }, | ||
3203 | { } /* end */ | ||
3204 | }; | ||
3205 | |||
3206 | static struct snd_kcontrol_new ad1882_3stack_mixers[] = { | ||
3207 | HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
3208 | HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT), | ||
3209 | HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x17, 2, 0x0, HDA_OUTPUT), | ||
3210 | { | ||
3211 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
3212 | .name = "Channel Mode", | ||
3213 | .info = ad198x_ch_mode_info, | ||
3214 | .get = ad198x_ch_mode_get, | ||
3215 | .put = ad198x_ch_mode_put, | ||
3216 | }, | ||
3217 | { } /* end */ | ||
3218 | }; | ||
3219 | |||
3220 | static struct snd_kcontrol_new ad1882_6stack_mixers[] = { | ||
3221 | HDA_CODEC_MUTE("Surround Playback Switch", 0x16, 0x0, HDA_OUTPUT), | ||
3222 | HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x24, 1, 0x0, HDA_OUTPUT), | ||
3223 | HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x24, 2, 0x0, HDA_OUTPUT), | ||
3224 | { } /* end */ | ||
3225 | }; | ||
3226 | |||
3227 | static struct hda_verb ad1882_ch2_init[] = { | ||
3228 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
3229 | {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
3230 | {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
3231 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
3232 | {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
3233 | {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
3234 | { } /* end */ | ||
3235 | }; | ||
3236 | |||
3237 | static struct hda_verb ad1882_ch4_init[] = { | ||
3238 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
3239 | {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
3240 | {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
3241 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
3242 | {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
3243 | {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
3244 | { } /* end */ | ||
3245 | }; | ||
3246 | |||
3247 | static struct hda_verb ad1882_ch6_init[] = { | ||
3248 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
3249 | {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
3250 | {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
3251 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
3252 | {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
3253 | {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
3254 | { } /* end */ | ||
3255 | }; | ||
3256 | |||
3257 | static struct hda_channel_mode ad1882_modes[3] = { | ||
3258 | { 2, ad1882_ch2_init }, | ||
3259 | { 4, ad1882_ch4_init }, | ||
3260 | { 6, ad1882_ch6_init }, | ||
3261 | }; | ||
3262 | |||
3263 | /* | ||
3264 | * initialization verbs | ||
3265 | */ | ||
3266 | static struct hda_verb ad1882_init_verbs[] = { | ||
3267 | /* DACs; mute as default */ | ||
3268 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
3269 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
3270 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
3271 | /* Port-A (HP) mixer */ | ||
3272 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
3273 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
3274 | /* Port-A pin */ | ||
3275 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
3276 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
3277 | /* HP selector - select DAC2 */ | ||
3278 | {0x37, AC_VERB_SET_CONNECT_SEL, 0x1}, | ||
3279 | /* Port-D (Line-out) mixer */ | ||
3280 | {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
3281 | {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
3282 | /* Port-D pin */ | ||
3283 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
3284 | {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
3285 | /* Mono-out mixer */ | ||
3286 | {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
3287 | {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
3288 | /* Mono-out pin */ | ||
3289 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
3290 | {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
3291 | /* Port-B (front mic) pin */ | ||
3292 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
3293 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
3294 | {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */ | ||
3295 | /* Port-C (line-in) pin */ | ||
3296 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
3297 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
3298 | {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */ | ||
3299 | /* Port-C mixer - mute as input */ | ||
3300 | {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
3301 | {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
3302 | /* Port-E (mic-in) pin */ | ||
3303 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
3304 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
3305 | {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */ | ||
3306 | /* Port-E mixer - mute as input */ | ||
3307 | {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
3308 | {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
3309 | /* Port-F (surround) */ | ||
3310 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
3311 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
3312 | /* Port-G (CLFE) */ | ||
3313 | {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
3314 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
3315 | /* Analog mixer; mute as default */ | ||
3316 | /* list: 0x39, 0x3a, 0x11, 0x12, 0x3c, 0x3b, 0x18, 0x1a */ | ||
3317 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
3318 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
3319 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
3320 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
3321 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
3322 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, | ||
3323 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, | ||
3324 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, | ||
3325 | /* Analog Mix output amp */ | ||
3326 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */ | ||
3327 | /* SPDIF output selector */ | ||
3328 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ | ||
3329 | {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */ | ||
3330 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ | ||
3331 | { } /* end */ | ||
3332 | }; | ||
3333 | |||
3334 | /* models */ | ||
3335 | enum { | ||
3336 | AD1882_3STACK, | ||
3337 | AD1882_6STACK, | ||
3338 | AD1882_MODELS | ||
3339 | }; | ||
3340 | |||
3341 | static const char *ad1882_models[AD1986A_MODELS] = { | ||
3342 | [AD1882_3STACK] = "3stack", | ||
3343 | [AD1882_6STACK] = "6stack", | ||
3344 | }; | ||
3345 | |||
3346 | |||
3347 | static int patch_ad1882(struct hda_codec *codec) | ||
3348 | { | ||
3349 | struct ad198x_spec *spec; | ||
3350 | int board_config; | ||
3351 | |||
3352 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
3353 | if (spec == NULL) | ||
3354 | return -ENOMEM; | ||
3355 | |||
3356 | mutex_init(&spec->amp_mutex); | ||
3357 | codec->spec = spec; | ||
3358 | |||
3359 | spec->multiout.max_channels = 6; | ||
3360 | spec->multiout.num_dacs = 3; | ||
3361 | spec->multiout.dac_nids = ad1882_dac_nids; | ||
3362 | spec->multiout.dig_out_nid = AD1882_SPDIF_OUT; | ||
3363 | spec->num_adc_nids = ARRAY_SIZE(ad1882_adc_nids); | ||
3364 | spec->adc_nids = ad1882_adc_nids; | ||
3365 | spec->capsrc_nids = ad1882_capsrc_nids; | ||
3366 | spec->input_mux = &ad1882_capture_source; | ||
3367 | spec->num_mixers = 1; | ||
3368 | spec->mixers[0] = ad1882_base_mixers; | ||
3369 | spec->num_init_verbs = 1; | ||
3370 | spec->init_verbs[0] = ad1882_init_verbs; | ||
3371 | spec->spdif_route = 0; | ||
3372 | |||
3373 | codec->patch_ops = ad198x_patch_ops; | ||
3374 | |||
3375 | /* override some parameters */ | ||
3376 | board_config = snd_hda_check_board_config(codec, AD1882_MODELS, | ||
3377 | ad1882_models, NULL); | ||
3378 | switch (board_config) { | ||
3379 | default: | ||
3380 | case AD1882_3STACK: | ||
3381 | spec->num_mixers = 2; | ||
3382 | spec->mixers[1] = ad1882_3stack_mixers; | ||
3383 | spec->channel_mode = ad1882_modes; | ||
3384 | spec->num_channel_mode = ARRAY_SIZE(ad1882_modes); | ||
3385 | spec->need_dac_fix = 1; | ||
3386 | spec->multiout.max_channels = 2; | ||
3387 | spec->multiout.num_dacs = 1; | ||
3388 | break; | ||
3389 | case AD1882_6STACK: | ||
3390 | spec->num_mixers = 2; | ||
3391 | spec->mixers[1] = ad1882_6stack_mixers; | ||
3392 | break; | ||
3393 | } | ||
3394 | return 0; | ||
3395 | } | ||
3396 | |||
3397 | |||
3398 | /* | ||
2778 | * patch entries | 3399 | * patch entries |
2779 | */ | 3400 | */ |
2780 | struct hda_codec_preset snd_hda_preset_analog[] = { | 3401 | struct hda_codec_preset snd_hda_preset_analog[] = { |
3402 | { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 }, | ||
3403 | { .id = 0x11d41884, .name = "AD1884", .patch = patch_ad1884 }, | ||
2781 | { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 }, | 3404 | { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 }, |
2782 | { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 }, | 3405 | { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 }, |
3406 | { .id = 0x11d41984, .name = "AD1984", .patch = patch_ad1984 }, | ||
2783 | { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a }, | 3407 | { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a }, |
2784 | { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 }, | 3408 | { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 }, |
2785 | { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 }, | 3409 | { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 }, |
diff --git a/sound/pci/hda/patch_atihdmi.c b/sound/pci/hda/patch_atihdmi.c index f8eb4c90f801..72d3ab9751ac 100644 --- a/sound/pci/hda/patch_atihdmi.c +++ b/sound/pci/hda/patch_atihdmi.c | |||
@@ -172,6 +172,7 @@ static int patch_atihdmi(struct hda_codec *codec) | |||
172 | */ | 172 | */ |
173 | struct hda_codec_preset snd_hda_preset_atihdmi[] = { | 173 | struct hda_codec_preset snd_hda_preset_atihdmi[] = { |
174 | { .id = 0x1002793c, .name = "ATI RS600 HDMI", .patch = patch_atihdmi }, | 174 | { .id = 0x1002793c, .name = "ATI RS600 HDMI", .patch = patch_atihdmi }, |
175 | { .id = 0x10027919, .name = "ATI RS600 HDMI", .patch = patch_atihdmi }, | ||
175 | { .id = 0x1002791a, .name = "ATI RS690/780 HDMI", .patch = patch_atihdmi }, | 176 | { .id = 0x1002791a, .name = "ATI RS690/780 HDMI", .patch = patch_atihdmi }, |
176 | { .id = 0x1002aa01, .name = "ATI R600 HDMI", .patch = patch_atihdmi }, | 177 | { .id = 0x1002aa01, .name = "ATI R600 HDMI", .patch = patch_atihdmi }, |
177 | {} /* terminator */ | 178 | {} /* terminator */ |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index bef214bcdddf..4d8e8af5c819 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -801,7 +801,9 @@ static struct snd_pci_quirk cxt5045_cfg_tbl[] = { | |||
801 | SND_PCI_QUIRK(0x103c, 0x30b2, "HP DV Series", CXT5045_LAPTOP), | 801 | SND_PCI_QUIRK(0x103c, 0x30b2, "HP DV Series", CXT5045_LAPTOP), |
802 | SND_PCI_QUIRK(0x103c, 0x30b5, "HP DV2120", CXT5045_LAPTOP), | 802 | SND_PCI_QUIRK(0x103c, 0x30b5, "HP DV2120", CXT5045_LAPTOP), |
803 | SND_PCI_QUIRK(0x103c, 0x30cd, "HP DV Series", CXT5045_LAPTOP), | 803 | SND_PCI_QUIRK(0x103c, 0x30cd, "HP DV Series", CXT5045_LAPTOP), |
804 | SND_PCI_QUIRK(0x103c, 0x30d9, "HP Spartan", CXT5045_LAPTOP), | ||
804 | SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_FUJITSU), | 805 | SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_FUJITSU), |
806 | SND_PCI_QUIRK(0x1734, 0x10cb, "Fujitsu Si3515", CXT5045_LAPTOP), | ||
805 | SND_PCI_QUIRK(0x8086, 0x2111, "Conexant Reference board", CXT5045_LAPTOP), | 807 | SND_PCI_QUIRK(0x8086, 0x2111, "Conexant Reference board", CXT5045_LAPTOP), |
806 | {} | 808 | {} |
807 | }; | 809 | }; |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 4776de93928b..9a47eec5a27b 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -94,10 +94,18 @@ enum { | |||
94 | ALC262_HP_BPC_D7000_WF, | 94 | ALC262_HP_BPC_D7000_WF, |
95 | ALC262_BENQ_ED8, | 95 | ALC262_BENQ_ED8, |
96 | ALC262_SONY_ASSAMD, | 96 | ALC262_SONY_ASSAMD, |
97 | ALC262_BENQ_T31, | ||
97 | ALC262_AUTO, | 98 | ALC262_AUTO, |
98 | ALC262_MODEL_LAST /* last tag */ | 99 | ALC262_MODEL_LAST /* last tag */ |
99 | }; | 100 | }; |
100 | 101 | ||
102 | /* ALC268 models */ | ||
103 | enum { | ||
104 | ALC268_3ST, | ||
105 | ALC268_AUTO, | ||
106 | ALC268_MODEL_LAST /* last tag */ | ||
107 | }; | ||
108 | |||
101 | /* ALC861 models */ | 109 | /* ALC861 models */ |
102 | enum { | 110 | enum { |
103 | ALC861_3ST, | 111 | ALC861_3ST, |
@@ -115,6 +123,7 @@ enum { | |||
115 | /* ALC861-VD models */ | 123 | /* ALC861-VD models */ |
116 | enum { | 124 | enum { |
117 | ALC660VD_3ST, | 125 | ALC660VD_3ST, |
126 | ALC660VD_3ST_DIG, | ||
118 | ALC861VD_3ST, | 127 | ALC861VD_3ST, |
119 | ALC861VD_3ST_DIG, | 128 | ALC861VD_3ST_DIG, |
120 | ALC861VD_6ST_DIG, | 129 | ALC861VD_6ST_DIG, |
@@ -144,6 +153,7 @@ enum { | |||
144 | ALC882_TARGA, | 153 | ALC882_TARGA, |
145 | ALC882_ASUS_A7J, | 154 | ALC882_ASUS_A7J, |
146 | ALC885_MACPRO, | 155 | ALC885_MACPRO, |
156 | ALC885_IMAC24, | ||
147 | ALC882_AUTO, | 157 | ALC882_AUTO, |
148 | ALC882_MODEL_LAST, | 158 | ALC882_MODEL_LAST, |
149 | }; | 159 | }; |
@@ -163,6 +173,8 @@ enum { | |||
163 | ALC883_LENOVO_101E_2ch, | 173 | ALC883_LENOVO_101E_2ch, |
164 | ALC883_LENOVO_NB0763, | 174 | ALC883_LENOVO_NB0763, |
165 | ALC888_LENOVO_MS7195_DIG, | 175 | ALC888_LENOVO_MS7195_DIG, |
176 | ALC888_6ST_HP, | ||
177 | ALC888_3ST_HP, | ||
166 | ALC883_AUTO, | 178 | ALC883_AUTO, |
167 | ALC883_MODEL_LAST, | 179 | ALC883_MODEL_LAST, |
168 | }; | 180 | }; |
@@ -713,6 +725,38 @@ static void alc_subsystem_id(struct hda_codec *codec, | |||
713 | } | 725 | } |
714 | 726 | ||
715 | /* | 727 | /* |
728 | * Fix-up pin default configurations | ||
729 | */ | ||
730 | |||
731 | struct alc_pincfg { | ||
732 | hda_nid_t nid; | ||
733 | u32 val; | ||
734 | }; | ||
735 | |||
736 | static void alc_fix_pincfg(struct hda_codec *codec, | ||
737 | const struct snd_pci_quirk *quirk, | ||
738 | const struct alc_pincfg **pinfix) | ||
739 | { | ||
740 | const struct alc_pincfg *cfg; | ||
741 | |||
742 | quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); | ||
743 | if (!quirk) | ||
744 | return; | ||
745 | |||
746 | cfg = pinfix[quirk->value]; | ||
747 | for (; cfg->nid; cfg++) { | ||
748 | int i; | ||
749 | u32 val = cfg->val; | ||
750 | for (i = 0; i < 4; i++) { | ||
751 | snd_hda_codec_write(codec, cfg->nid, 0, | ||
752 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i, | ||
753 | val & 0xff); | ||
754 | val >>= 8; | ||
755 | } | ||
756 | } | ||
757 | } | ||
758 | |||
759 | /* | ||
716 | * ALC880 3-stack model | 760 | * ALC880 3-stack model |
717 | * | 761 | * |
718 | * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e) | 762 | * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e) |
@@ -1878,31 +1922,53 @@ static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res) | |||
1878 | * Pin assignment: | 1922 | * Pin assignment: |
1879 | * Speaker-out: 0x14 | 1923 | * Speaker-out: 0x14 |
1880 | * Mic-In: 0x18 | 1924 | * Mic-In: 0x18 |
1881 | * Built-in Mic-In: 0x19 (?) | 1925 | * Built-in Mic-In: 0x19 |
1882 | * HP-Out: 0x1b | 1926 | * Line-In: 0x1b |
1927 | * HP-Out: 0x1a | ||
1883 | * SPDIF-Out: 0x1e | 1928 | * SPDIF-Out: 0x1e |
1884 | */ | 1929 | */ |
1885 | 1930 | ||
1886 | /* seems analog CD is not working */ | ||
1887 | static struct hda_input_mux alc880_lg_lw_capture_source = { | 1931 | static struct hda_input_mux alc880_lg_lw_capture_source = { |
1888 | .num_items = 2, | 1932 | .num_items = 3, |
1889 | .items = { | 1933 | .items = { |
1890 | { "Mic", 0x0 }, | 1934 | { "Mic", 0x0 }, |
1891 | { "Internal Mic", 0x1 }, | 1935 | { "Internal Mic", 0x1 }, |
1936 | { "Line In", 0x2 }, | ||
1892 | }, | 1937 | }, |
1893 | }; | 1938 | }; |
1894 | 1939 | ||
1940 | #define alc880_lg_lw_modes alc880_threestack_modes | ||
1941 | |||
1895 | static struct snd_kcontrol_new alc880_lg_lw_mixer[] = { | 1942 | static struct snd_kcontrol_new alc880_lg_lw_mixer[] = { |
1896 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 1943 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
1897 | HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), | 1944 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
1945 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), | ||
1946 | HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), | ||
1947 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | ||
1948 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | ||
1949 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | ||
1950 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | ||
1951 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
1952 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
1898 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 1953 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
1899 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | 1954 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), |
1900 | HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), | 1955 | HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), |
1901 | HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), | 1956 | HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), |
1957 | { | ||
1958 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1959 | .name = "Channel Mode", | ||
1960 | .info = alc_ch_mode_info, | ||
1961 | .get = alc_ch_mode_get, | ||
1962 | .put = alc_ch_mode_put, | ||
1963 | }, | ||
1902 | { } /* end */ | 1964 | { } /* end */ |
1903 | }; | 1965 | }; |
1904 | 1966 | ||
1905 | static struct hda_verb alc880_lg_lw_init_verbs[] = { | 1967 | static struct hda_verb alc880_lg_lw_init_verbs[] = { |
1968 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ | ||
1969 | {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ | ||
1970 | {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ | ||
1971 | |||
1906 | /* set capture source to mic-in */ | 1972 | /* set capture source to mic-in */ |
1907 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 1973 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
1908 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 1974 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
@@ -1912,7 +1978,6 @@ static struct hda_verb alc880_lg_lw_init_verbs[] = { | |||
1912 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 1978 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
1913 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 1979 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
1914 | /* HP-out */ | 1980 | /* HP-out */ |
1915 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
1916 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 1981 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
1917 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 1982 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
1918 | /* mic-in to input */ | 1983 | /* mic-in to input */ |
@@ -2856,11 +2921,11 @@ static struct alc_config_preset alc880_presets[] = { | |||
2856 | .mixers = { alc880_lg_lw_mixer }, | 2921 | .mixers = { alc880_lg_lw_mixer }, |
2857 | .init_verbs = { alc880_volume_init_verbs, | 2922 | .init_verbs = { alc880_volume_init_verbs, |
2858 | alc880_lg_lw_init_verbs }, | 2923 | alc880_lg_lw_init_verbs }, |
2859 | .num_dacs = 1, | 2924 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), |
2860 | .dac_nids = alc880_dac_nids, | 2925 | .dac_nids = alc880_dac_nids, |
2861 | .dig_out_nid = ALC880_DIGOUT_NID, | 2926 | .dig_out_nid = ALC880_DIGOUT_NID, |
2862 | .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), | 2927 | .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes), |
2863 | .channel_mode = alc880_2_jack_modes, | 2928 | .channel_mode = alc880_lg_lw_modes, |
2864 | .input_mux = &alc880_lg_lw_capture_source, | 2929 | .input_mux = &alc880_lg_lw_capture_source, |
2865 | .unsol_event = alc880_lg_lw_unsol_event, | 2930 | .unsol_event = alc880_lg_lw_unsol_event, |
2866 | .init_hook = alc880_lg_lw_automute, | 2931 | .init_hook = alc880_lg_lw_automute, |
@@ -5054,6 +5119,60 @@ static struct hda_verb alc882_macpro_init_verbs[] = { | |||
5054 | { } | 5119 | { } |
5055 | }; | 5120 | }; |
5056 | 5121 | ||
5122 | /* iMac 24 mixer. */ | ||
5123 | static struct snd_kcontrol_new alc885_imac24_mixer[] = { | ||
5124 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT), | ||
5125 | HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT), | ||
5126 | { } /* end */ | ||
5127 | }; | ||
5128 | |||
5129 | /* iMac 24 init verbs. */ | ||
5130 | static struct hda_verb alc885_imac24_init_verbs[] = { | ||
5131 | /* Internal speakers: output 0 (0x0c) */ | ||
5132 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
5133 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
5134 | {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
5135 | /* Internal speakers: output 0 (0x0c) */ | ||
5136 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
5137 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
5138 | {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
5139 | /* Headphone: output 0 (0x0c) */ | ||
5140 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
5141 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
5142 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
5143 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | ||
5144 | /* Front Mic: input vref at 80% */ | ||
5145 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
5146 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
5147 | { } | ||
5148 | }; | ||
5149 | |||
5150 | /* Toggle speaker-output according to the hp-jack state */ | ||
5151 | static void alc885_imac24_automute(struct hda_codec *codec) | ||
5152 | { | ||
5153 | unsigned int present; | ||
5154 | |||
5155 | present = snd_hda_codec_read(codec, 0x14, 0, | ||
5156 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
5157 | snd_hda_codec_amp_update(codec, 0x18, 0, HDA_OUTPUT, 0, | ||
5158 | 0x80, present ? 0x80 : 0); | ||
5159 | snd_hda_codec_amp_update(codec, 0x18, 1, HDA_OUTPUT, 0, | ||
5160 | 0x80, present ? 0x80 : 0); | ||
5161 | snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0, | ||
5162 | 0x80, present ? 0x80 : 0); | ||
5163 | snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0, | ||
5164 | 0x80, present ? 0x80 : 0); | ||
5165 | } | ||
5166 | |||
5167 | /* Processes unsolicited events. */ | ||
5168 | static void alc885_imac24_unsol_event(struct hda_codec *codec, | ||
5169 | unsigned int res) | ||
5170 | { | ||
5171 | /* Headphone insertion or removal. */ | ||
5172 | if ((res >> 26) == ALC880_HP_EVENT) | ||
5173 | alc885_imac24_automute(codec); | ||
5174 | } | ||
5175 | |||
5057 | static struct hda_verb alc882_targa_verbs[] = { | 5176 | static struct hda_verb alc882_targa_verbs[] = { |
5058 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 5177 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
5059 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 5178 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
@@ -5274,6 +5393,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = { | |||
5274 | [ALC882_ARIMA] = "arima", | 5393 | [ALC882_ARIMA] = "arima", |
5275 | [ALC882_W2JC] = "w2jc", | 5394 | [ALC882_W2JC] = "w2jc", |
5276 | [ALC885_MACPRO] = "macpro", | 5395 | [ALC885_MACPRO] = "macpro", |
5396 | [ALC885_IMAC24] = "imac24", | ||
5277 | [ALC882_AUTO] = "auto", | 5397 | [ALC882_AUTO] = "auto", |
5278 | }; | 5398 | }; |
5279 | 5399 | ||
@@ -5284,6 +5404,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { | |||
5284 | SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ | 5404 | SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ |
5285 | SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), | 5405 | SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), |
5286 | SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J), | 5406 | SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J), |
5407 | SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG), | ||
5287 | SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), | 5408 | SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), |
5288 | SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC), | 5409 | SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC), |
5289 | {} | 5410 | {} |
@@ -5345,6 +5466,19 @@ static struct alc_config_preset alc882_presets[] = { | |||
5345 | .channel_mode = alc882_ch_modes, | 5466 | .channel_mode = alc882_ch_modes, |
5346 | .input_mux = &alc882_capture_source, | 5467 | .input_mux = &alc882_capture_source, |
5347 | }, | 5468 | }, |
5469 | [ALC885_IMAC24] = { | ||
5470 | .mixers = { alc885_imac24_mixer }, | ||
5471 | .init_verbs = { alc885_imac24_init_verbs }, | ||
5472 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | ||
5473 | .dac_nids = alc882_dac_nids, | ||
5474 | .dig_out_nid = ALC882_DIGOUT_NID, | ||
5475 | .dig_in_nid = ALC882_DIGIN_NID, | ||
5476 | .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), | ||
5477 | .channel_mode = alc882_ch_modes, | ||
5478 | .input_mux = &alc882_capture_source, | ||
5479 | .unsol_event = alc885_imac24_unsol_event, | ||
5480 | .init_hook = alc885_imac24_automute, | ||
5481 | }, | ||
5348 | [ALC882_TARGA] = { | 5482 | [ALC882_TARGA] = { |
5349 | .mixers = { alc882_targa_mixer, alc882_chmode_mixer, | 5483 | .mixers = { alc882_targa_mixer, alc882_chmode_mixer, |
5350 | alc882_capture_mixer }, | 5484 | alc882_capture_mixer }, |
@@ -5379,6 +5513,29 @@ static struct alc_config_preset alc882_presets[] = { | |||
5379 | 5513 | ||
5380 | 5514 | ||
5381 | /* | 5515 | /* |
5516 | * Pin config fixes | ||
5517 | */ | ||
5518 | enum { | ||
5519 | PINFIX_ABIT_AW9D_MAX | ||
5520 | }; | ||
5521 | |||
5522 | static struct alc_pincfg alc882_abit_aw9d_pinfix[] = { | ||
5523 | { 0x15, 0x01080104 }, /* side */ | ||
5524 | { 0x16, 0x01011012 }, /* rear */ | ||
5525 | { 0x17, 0x01016011 }, /* clfe */ | ||
5526 | { } | ||
5527 | }; | ||
5528 | |||
5529 | static const struct alc_pincfg *alc882_pin_fixes[] = { | ||
5530 | [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix, | ||
5531 | }; | ||
5532 | |||
5533 | static struct snd_pci_quirk alc882_pinfix_tbl[] = { | ||
5534 | SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), | ||
5535 | {} | ||
5536 | }; | ||
5537 | |||
5538 | /* | ||
5382 | * BIOS auto configuration | 5539 | * BIOS auto configuration |
5383 | */ | 5540 | */ |
5384 | static void alc882_auto_set_output_and_unmute(struct hda_codec *codec, | 5541 | static void alc882_auto_set_output_and_unmute(struct hda_codec *codec, |
@@ -5494,6 +5651,9 @@ static int patch_alc882(struct hda_codec *codec) | |||
5494 | case 0x106b0c00: /* Mac Pro */ | 5651 | case 0x106b0c00: /* Mac Pro */ |
5495 | board_config = ALC885_MACPRO; | 5652 | board_config = ALC885_MACPRO; |
5496 | break; | 5653 | break; |
5654 | case 0x106b1000: /* iMac 24 */ | ||
5655 | board_config = ALC885_IMAC24; | ||
5656 | break; | ||
5497 | default: | 5657 | default: |
5498 | printk(KERN_INFO "hda_codec: Unknown model for ALC882, " | 5658 | printk(KERN_INFO "hda_codec: Unknown model for ALC882, " |
5499 | "trying auto-probe from BIOS...\n"); | 5659 | "trying auto-probe from BIOS...\n"); |
@@ -5501,6 +5661,8 @@ static int patch_alc882(struct hda_codec *codec) | |||
5501 | } | 5661 | } |
5502 | } | 5662 | } |
5503 | 5663 | ||
5664 | alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes); | ||
5665 | |||
5504 | if (board_config == ALC882_AUTO) { | 5666 | if (board_config == ALC882_AUTO) { |
5505 | /* automatic parse from the BIOS config */ | 5667 | /* automatic parse from the BIOS config */ |
5506 | err = alc882_parse_auto_config(codec); | 5668 | err = alc882_parse_auto_config(codec); |
@@ -5518,7 +5680,7 @@ static int patch_alc882(struct hda_codec *codec) | |||
5518 | if (board_config != ALC882_AUTO) | 5680 | if (board_config != ALC882_AUTO) |
5519 | setup_preset(spec, &alc882_presets[board_config]); | 5681 | setup_preset(spec, &alc882_presets[board_config]); |
5520 | 5682 | ||
5521 | if (board_config == ALC885_MACPRO) { | 5683 | if (board_config == ALC885_MACPRO || board_config == ALC885_IMAC24) { |
5522 | alc882_gpio_mute(codec, 0, 0); | 5684 | alc882_gpio_mute(codec, 0, 0); |
5523 | alc882_gpio_mute(codec, 1, 0); | 5685 | alc882_gpio_mute(codec, 1, 0); |
5524 | } | 5686 | } |
@@ -5995,6 +6157,84 @@ static struct snd_kcontrol_new alc883_medion_md2_mixer[] = { | |||
5995 | { } /* end */ | 6157 | { } /* end */ |
5996 | }; | 6158 | }; |
5997 | 6159 | ||
6160 | static struct snd_kcontrol_new alc888_6st_hp_mixer[] = { | ||
6161 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
6162 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
6163 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT), | ||
6164 | HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT), | ||
6165 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), | ||
6166 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), | ||
6167 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), | ||
6168 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), | ||
6169 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), | ||
6170 | HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), | ||
6171 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
6172 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
6173 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
6174 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
6175 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
6176 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
6177 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | ||
6178 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
6179 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
6180 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), | ||
6181 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
6182 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
6183 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
6184 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | ||
6185 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | ||
6186 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), | ||
6187 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), | ||
6188 | { | ||
6189 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
6190 | /* .name = "Capture Source", */ | ||
6191 | .name = "Input Source", | ||
6192 | .count = 2, | ||
6193 | .info = alc883_mux_enum_info, | ||
6194 | .get = alc883_mux_enum_get, | ||
6195 | .put = alc883_mux_enum_put, | ||
6196 | }, | ||
6197 | { } /* end */ | ||
6198 | }; | ||
6199 | |||
6200 | static struct snd_kcontrol_new alc888_3st_hp_mixer[] = { | ||
6201 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
6202 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
6203 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT), | ||
6204 | HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT), | ||
6205 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), | ||
6206 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), | ||
6207 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), | ||
6208 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), | ||
6209 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
6210 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
6211 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
6212 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
6213 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
6214 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
6215 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | ||
6216 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
6217 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
6218 | HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), | ||
6219 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
6220 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
6221 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
6222 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | ||
6223 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | ||
6224 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), | ||
6225 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), | ||
6226 | { | ||
6227 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
6228 | /* .name = "Capture Source", */ | ||
6229 | .name = "Input Source", | ||
6230 | .count = 2, | ||
6231 | .info = alc883_mux_enum_info, | ||
6232 | .get = alc883_mux_enum_get, | ||
6233 | .put = alc883_mux_enum_put, | ||
6234 | }, | ||
6235 | { } /* end */ | ||
6236 | }; | ||
6237 | |||
5998 | static struct snd_kcontrol_new alc883_chmode_mixer[] = { | 6238 | static struct snd_kcontrol_new alc883_chmode_mixer[] = { |
5999 | { | 6239 | { |
6000 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 6240 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
@@ -6126,6 +6366,42 @@ static struct hda_verb alc888_lenovo_ms7195_verbs[] = { | |||
6126 | { } /* end */ | 6366 | { } /* end */ |
6127 | }; | 6367 | }; |
6128 | 6368 | ||
6369 | static struct hda_verb alc888_6st_hp_verbs[] = { | ||
6370 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ | ||
6371 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Rear : output 2 (0x0e) */ | ||
6372 | {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* CLFE : output 1 (0x0d) */ | ||
6373 | {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, /* Side : output 3 (0x0f) */ | ||
6374 | { } | ||
6375 | }; | ||
6376 | |||
6377 | static struct hda_verb alc888_3st_hp_verbs[] = { | ||
6378 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ | ||
6379 | {0x18, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */ | ||
6380 | {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */ | ||
6381 | { } | ||
6382 | }; | ||
6383 | |||
6384 | static struct hda_verb alc888_3st_hp_2ch_init[] = { | ||
6385 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | ||
6386 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
6387 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | ||
6388 | { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
6389 | { } | ||
6390 | }; | ||
6391 | |||
6392 | static struct hda_verb alc888_3st_hp_6ch_init[] = { | ||
6393 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
6394 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
6395 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
6396 | { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
6397 | { } | ||
6398 | }; | ||
6399 | |||
6400 | static struct hda_channel_mode alc888_3st_hp_modes[2] = { | ||
6401 | { 2, alc888_3st_hp_2ch_init }, | ||
6402 | { 6, alc888_3st_hp_6ch_init }, | ||
6403 | }; | ||
6404 | |||
6129 | /* toggle front-jack and RCA according to the hp-jack state */ | 6405 | /* toggle front-jack and RCA according to the hp-jack state */ |
6130 | static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec) | 6406 | static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec) |
6131 | { | 6407 | { |
@@ -6368,11 +6644,14 @@ static const char *alc883_models[ALC883_MODEL_LAST] = { | |||
6368 | [ALC883_LENOVO_101E_2ch] = "lenovo-101e", | 6644 | [ALC883_LENOVO_101E_2ch] = "lenovo-101e", |
6369 | [ALC883_LENOVO_NB0763] = "lenovo-nb0763", | 6645 | [ALC883_LENOVO_NB0763] = "lenovo-nb0763", |
6370 | [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig", | 6646 | [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig", |
6647 | [ALC888_6ST_HP] = "6stack-hp", | ||
6648 | [ALC888_3ST_HP] = "3stack-hp", | ||
6371 | [ALC883_AUTO] = "auto", | 6649 | [ALC883_AUTO] = "auto", |
6372 | }; | 6650 | }; |
6373 | 6651 | ||
6374 | static struct snd_pci_quirk alc883_cfg_tbl[] = { | 6652 | static struct snd_pci_quirk alc883_cfg_tbl[] = { |
6375 | SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG), | 6653 | SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG), |
6654 | SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), | ||
6376 | SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), | 6655 | SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), |
6377 | SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD), | 6656 | SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD), |
6378 | SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), | 6657 | SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), |
@@ -6381,6 +6660,8 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { | |||
6381 | SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), | 6660 | SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), |
6382 | SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG), | 6661 | SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG), |
6383 | SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), | 6662 | SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), |
6663 | SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG), | ||
6664 | SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG), | ||
6384 | SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG), | 6665 | SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG), |
6385 | SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG), | 6666 | SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG), |
6386 | SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG), | 6667 | SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG), |
@@ -6400,6 +6681,9 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { | |||
6400 | SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch), | 6681 | SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch), |
6401 | SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763), | 6682 | SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763), |
6402 | SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763), | 6683 | SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763), |
6684 | SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP), | ||
6685 | SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), | ||
6686 | SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), | ||
6403 | SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2), | 6687 | SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2), |
6404 | {} | 6688 | {} |
6405 | }; | 6689 | }; |
@@ -6584,6 +6868,31 @@ static struct alc_config_preset alc883_presets[] = { | |||
6584 | .unsol_event = alc883_lenovo_ms7195_unsol_event, | 6868 | .unsol_event = alc883_lenovo_ms7195_unsol_event, |
6585 | .init_hook = alc888_lenovo_ms7195_front_automute, | 6869 | .init_hook = alc888_lenovo_ms7195_front_automute, |
6586 | }, | 6870 | }, |
6871 | [ALC888_6ST_HP] = { | ||
6872 | .mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer }, | ||
6873 | .init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs }, | ||
6874 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
6875 | .dac_nids = alc883_dac_nids, | ||
6876 | .dig_out_nid = ALC883_DIGOUT_NID, | ||
6877 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), | ||
6878 | .adc_nids = alc883_adc_nids, | ||
6879 | .dig_in_nid = ALC883_DIGIN_NID, | ||
6880 | .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), | ||
6881 | .channel_mode = alc883_sixstack_modes, | ||
6882 | .input_mux = &alc883_capture_source, | ||
6883 | }, | ||
6884 | [ALC888_3ST_HP] = { | ||
6885 | .mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer }, | ||
6886 | .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs }, | ||
6887 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
6888 | .dac_nids = alc883_dac_nids, | ||
6889 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), | ||
6890 | .adc_nids = alc883_adc_nids, | ||
6891 | .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes), | ||
6892 | .channel_mode = alc888_3st_hp_modes, | ||
6893 | .need_dac_fix = 1, | ||
6894 | .input_mux = &alc883_capture_source, | ||
6895 | }, | ||
6587 | }; | 6896 | }; |
6588 | 6897 | ||
6589 | 6898 | ||
@@ -6857,7 +7166,16 @@ static struct snd_kcontrol_new alc262_sony_mixer[] = { | |||
6857 | { } /* end */ | 7166 | { } /* end */ |
6858 | }; | 7167 | }; |
6859 | 7168 | ||
6860 | 7169 | static struct snd_kcontrol_new alc262_benq_t31_mixer[] = { | |
7170 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
7171 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
7172 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
7173 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
7174 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
7175 | HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), | ||
7176 | HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), | ||
7177 | { } /* end */ | ||
7178 | }; | ||
6861 | 7179 | ||
6862 | #define alc262_capture_mixer alc882_capture_mixer | 7180 | #define alc262_capture_mixer alc882_capture_mixer |
6863 | #define alc262_capture_alt_mixer alc882_capture_alt_mixer | 7181 | #define alc262_capture_alt_mixer alc882_capture_alt_mixer |
@@ -7189,6 +7507,15 @@ static struct hda_verb alc262_EAPD_verbs[] = { | |||
7189 | {} | 7507 | {} |
7190 | }; | 7508 | }; |
7191 | 7509 | ||
7510 | static struct hda_verb alc262_benq_t31_EAPD_verbs[] = { | ||
7511 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
7512 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | ||
7513 | |||
7514 | {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, | ||
7515 | {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, | ||
7516 | {} | ||
7517 | }; | ||
7518 | |||
7192 | /* add playback controls from the parsed DAC table */ | 7519 | /* add playback controls from the parsed DAC table */ |
7193 | static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, | 7520 | static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, |
7194 | const struct auto_pin_cfg *cfg) | 7521 | const struct auto_pin_cfg *cfg) |
@@ -7584,7 +7911,8 @@ static const char *alc262_models[ALC262_MODEL_LAST] = { | |||
7584 | [ALC262_HP_BPC] = "hp-bpc", | 7911 | [ALC262_HP_BPC] = "hp-bpc", |
7585 | [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000", | 7912 | [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000", |
7586 | [ALC262_BENQ_ED8] = "benq", | 7913 | [ALC262_BENQ_ED8] = "benq", |
7587 | [ALC262_BENQ_ED8] = "sony-assamd", | 7914 | [ALC262_BENQ_T31] = "benq-t31", |
7915 | [ALC262_SONY_ASSAMD] = "sony-assamd", | ||
7588 | [ALC262_AUTO] = "auto", | 7916 | [ALC262_AUTO] = "auto", |
7589 | }; | 7917 | }; |
7590 | 7918 | ||
@@ -7592,8 +7920,12 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = { | |||
7592 | SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), | 7920 | SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), |
7593 | SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC), | 7921 | SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC), |
7594 | SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC), | 7922 | SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC), |
7923 | SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC), | ||
7924 | SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC), | ||
7595 | SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC), | 7925 | SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC), |
7926 | SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC), | ||
7596 | SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC), | 7927 | SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC), |
7928 | SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC), | ||
7597 | SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL), | 7929 | SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL), |
7598 | SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL), | 7930 | SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL), |
7599 | SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL), | 7931 | SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL), |
@@ -7606,6 +7938,7 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = { | |||
7606 | SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), | 7938 | SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), |
7607 | SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1), | 7939 | SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1), |
7608 | SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), | 7940 | SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), |
7941 | SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31), | ||
7609 | SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD), | 7942 | SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD), |
7610 | SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD), | 7943 | SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD), |
7611 | SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD), | 7944 | SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD), |
@@ -7710,6 +8043,17 @@ static struct alc_config_preset alc262_presets[] = { | |||
7710 | .channel_mode = alc262_modes, | 8043 | .channel_mode = alc262_modes, |
7711 | .input_mux = &alc262_capture_source, | 8044 | .input_mux = &alc262_capture_source, |
7712 | .unsol_event = alc262_hippo_unsol_event, | 8045 | .unsol_event = alc262_hippo_unsol_event, |
8046 | }, | ||
8047 | [ALC262_BENQ_T31] = { | ||
8048 | .mixers = { alc262_benq_t31_mixer }, | ||
8049 | .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs }, | ||
8050 | .num_dacs = ARRAY_SIZE(alc262_dac_nids), | ||
8051 | .dac_nids = alc262_dac_nids, | ||
8052 | .hp_nid = 0x03, | ||
8053 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | ||
8054 | .channel_mode = alc262_modes, | ||
8055 | .input_mux = &alc262_capture_source, | ||
8056 | .unsol_event = alc262_hippo_unsol_event, | ||
7713 | }, | 8057 | }, |
7714 | }; | 8058 | }; |
7715 | 8059 | ||
@@ -7800,6 +8144,515 @@ static int patch_alc262(struct hda_codec *codec) | |||
7800 | } | 8144 | } |
7801 | 8145 | ||
7802 | /* | 8146 | /* |
8147 | * ALC268 channel source setting (2 channel) | ||
8148 | */ | ||
8149 | #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID | ||
8150 | #define alc268_modes alc260_modes | ||
8151 | |||
8152 | static hda_nid_t alc268_dac_nids[2] = { | ||
8153 | /* front, hp */ | ||
8154 | 0x02, 0x03 | ||
8155 | }; | ||
8156 | |||
8157 | static hda_nid_t alc268_adc_nids[2] = { | ||
8158 | /* ADC0-1 */ | ||
8159 | 0x08, 0x07 | ||
8160 | }; | ||
8161 | |||
8162 | static hda_nid_t alc268_adc_nids_alt[1] = { | ||
8163 | /* ADC0 */ | ||
8164 | 0x08 | ||
8165 | }; | ||
8166 | |||
8167 | static struct snd_kcontrol_new alc268_base_mixer[] = { | ||
8168 | /* output mixer control */ | ||
8169 | HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), | ||
8170 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
8171 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), | ||
8172 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
8173 | { } | ||
8174 | }; | ||
8175 | |||
8176 | /* | ||
8177 | * generic initialization of ADC, input mixers and output mixers | ||
8178 | */ | ||
8179 | static struct hda_verb alc268_base_init_verbs[] = { | ||
8180 | /* Unmute DAC0-1 and set vol = 0 */ | ||
8181 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
8182 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
8183 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
8184 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
8185 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
8186 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
8187 | |||
8188 | /* | ||
8189 | * Set up output mixers (0x0c - 0x0e) | ||
8190 | */ | ||
8191 | /* set vol=0 to output mixers */ | ||
8192 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
8193 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
8194 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
8195 | {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
8196 | |||
8197 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
8198 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
8199 | |||
8200 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, | ||
8201 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, | ||
8202 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, | ||
8203 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | ||
8204 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | ||
8205 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | ||
8206 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | ||
8207 | {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | ||
8208 | |||
8209 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
8210 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
8211 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
8212 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
8213 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
8214 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
8215 | {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
8216 | {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
8217 | |||
8218 | /* FIXME: use matrix-type input source selection */ | ||
8219 | /* Mixer elements: 0x18, 19, 1a, 1c, 14, 15, 0b */ | ||
8220 | /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ | ||
8221 | /* Input mixer2 */ | ||
8222 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
8223 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
8224 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, | ||
8225 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, | ||
8226 | |||
8227 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
8228 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
8229 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, | ||
8230 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, | ||
8231 | { } | ||
8232 | }; | ||
8233 | |||
8234 | /* | ||
8235 | * generic initialization of ADC, input mixers and output mixers | ||
8236 | */ | ||
8237 | static struct hda_verb alc268_volume_init_verbs[] = { | ||
8238 | /* set output DAC */ | ||
8239 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
8240 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
8241 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
8242 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
8243 | |||
8244 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | ||
8245 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | ||
8246 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | ||
8247 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | ||
8248 | {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | ||
8249 | |||
8250 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
8251 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
8252 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
8253 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
8254 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
8255 | |||
8256 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
8257 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
8258 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
8259 | {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
8260 | |||
8261 | /* set PCBEEP vol = 0 */ | ||
8262 | {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))}, | ||
8263 | |||
8264 | { } | ||
8265 | }; | ||
8266 | |||
8267 | #define alc268_mux_enum_info alc_mux_enum_info | ||
8268 | #define alc268_mux_enum_get alc_mux_enum_get | ||
8269 | |||
8270 | static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol, | ||
8271 | struct snd_ctl_elem_value *ucontrol) | ||
8272 | { | ||
8273 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
8274 | struct alc_spec *spec = codec->spec; | ||
8275 | const struct hda_input_mux *imux = spec->input_mux; | ||
8276 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
8277 | static hda_nid_t capture_mixers[3] = { 0x23, 0x24 }; | ||
8278 | hda_nid_t nid = capture_mixers[adc_idx]; | ||
8279 | unsigned int *cur_val = &spec->cur_mux[adc_idx]; | ||
8280 | unsigned int i, idx; | ||
8281 | |||
8282 | idx = ucontrol->value.enumerated.item[0]; | ||
8283 | if (idx >= imux->num_items) | ||
8284 | idx = imux->num_items - 1; | ||
8285 | if (*cur_val == idx && !codec->in_resume) | ||
8286 | return 0; | ||
8287 | for (i = 0; i < imux->num_items; i++) { | ||
8288 | unsigned int v = (i == idx) ? 0x7000 : 0x7080; | ||
8289 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
8290 | v | (imux->items[i].index << 8)); | ||
8291 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, | ||
8292 | idx ); | ||
8293 | } | ||
8294 | *cur_val = idx; | ||
8295 | return 1; | ||
8296 | } | ||
8297 | |||
8298 | static struct snd_kcontrol_new alc268_capture_alt_mixer[] = { | ||
8299 | HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), | ||
8300 | HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), | ||
8301 | { | ||
8302 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
8303 | /* The multiple "Capture Source" controls confuse alsamixer | ||
8304 | * So call somewhat different.. | ||
8305 | * FIXME: the controls appear in the "playback" view! | ||
8306 | */ | ||
8307 | /* .name = "Capture Source", */ | ||
8308 | .name = "Input Source", | ||
8309 | .count = 1, | ||
8310 | .info = alc268_mux_enum_info, | ||
8311 | .get = alc268_mux_enum_get, | ||
8312 | .put = alc268_mux_enum_put, | ||
8313 | }, | ||
8314 | { } /* end */ | ||
8315 | }; | ||
8316 | |||
8317 | static struct snd_kcontrol_new alc268_capture_mixer[] = { | ||
8318 | HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), | ||
8319 | HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), | ||
8320 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT), | ||
8321 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT), | ||
8322 | { | ||
8323 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
8324 | /* The multiple "Capture Source" controls confuse alsamixer | ||
8325 | * So call somewhat different.. | ||
8326 | * FIXME: the controls appear in the "playback" view! | ||
8327 | */ | ||
8328 | /* .name = "Capture Source", */ | ||
8329 | .name = "Input Source", | ||
8330 | .count = 2, | ||
8331 | .info = alc268_mux_enum_info, | ||
8332 | .get = alc268_mux_enum_get, | ||
8333 | .put = alc268_mux_enum_put, | ||
8334 | }, | ||
8335 | { } /* end */ | ||
8336 | }; | ||
8337 | |||
8338 | static struct hda_input_mux alc268_capture_source = { | ||
8339 | .num_items = 4, | ||
8340 | .items = { | ||
8341 | { "Mic", 0x0 }, | ||
8342 | { "Front Mic", 0x1 }, | ||
8343 | { "Line", 0x2 }, | ||
8344 | { "CD", 0x3 }, | ||
8345 | }, | ||
8346 | }; | ||
8347 | |||
8348 | /* create input playback/capture controls for the given pin */ | ||
8349 | static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, | ||
8350 | const char *ctlname, int idx) | ||
8351 | { | ||
8352 | char name[32]; | ||
8353 | int err; | ||
8354 | |||
8355 | sprintf(name, "%s Playback Volume", ctlname); | ||
8356 | if (nid == 0x14) { | ||
8357 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, | ||
8358 | HDA_COMPOSE_AMP_VAL(0x02, 3, idx, | ||
8359 | HDA_OUTPUT)); | ||
8360 | if (err < 0) | ||
8361 | return err; | ||
8362 | } else if (nid == 0x15) { | ||
8363 | err = add_control(spec, ALC_CTL_WIDGET_VOL, name, | ||
8364 | HDA_COMPOSE_AMP_VAL(0x03, 3, idx, | ||
8365 | HDA_OUTPUT)); | ||
8366 | if (err < 0) | ||
8367 | return err; | ||
8368 | } else | ||
8369 | return -1; | ||
8370 | sprintf(name, "%s Playback Switch", ctlname); | ||
8371 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, | ||
8372 | HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); | ||
8373 | if (err < 0) | ||
8374 | return err; | ||
8375 | return 0; | ||
8376 | } | ||
8377 | |||
8378 | /* add playback controls from the parsed DAC table */ | ||
8379 | static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec, | ||
8380 | const struct auto_pin_cfg *cfg) | ||
8381 | { | ||
8382 | hda_nid_t nid; | ||
8383 | int err; | ||
8384 | |||
8385 | spec->multiout.num_dacs = 2; /* only use one dac */ | ||
8386 | spec->multiout.dac_nids = spec->private_dac_nids; | ||
8387 | spec->multiout.dac_nids[0] = 2; | ||
8388 | spec->multiout.dac_nids[1] = 3; | ||
8389 | |||
8390 | nid = cfg->line_out_pins[0]; | ||
8391 | if (nid) | ||
8392 | alc268_new_analog_output(spec, nid, "Front", 0); | ||
8393 | |||
8394 | nid = cfg->speaker_pins[0]; | ||
8395 | if (nid == 0x1d) { | ||
8396 | err = add_control(spec, ALC_CTL_WIDGET_VOL, | ||
8397 | "Speaker Playback Volume", | ||
8398 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); | ||
8399 | if (err < 0) | ||
8400 | return err; | ||
8401 | } | ||
8402 | nid = cfg->hp_pins[0]; | ||
8403 | if (nid) | ||
8404 | alc268_new_analog_output(spec, nid, "Headphone", 0); | ||
8405 | |||
8406 | nid = cfg->line_out_pins[1] | cfg->line_out_pins[2]; | ||
8407 | if (nid == 0x16) { | ||
8408 | err = add_control(spec, ALC_CTL_WIDGET_MUTE, | ||
8409 | "Mono Playback Switch", | ||
8410 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT)); | ||
8411 | if (err < 0) | ||
8412 | return err; | ||
8413 | } | ||
8414 | return 0; | ||
8415 | } | ||
8416 | |||
8417 | /* create playback/capture controls for input pins */ | ||
8418 | static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec, | ||
8419 | const struct auto_pin_cfg *cfg) | ||
8420 | { | ||
8421 | struct hda_input_mux *imux = &spec->private_imux; | ||
8422 | int i, idx1; | ||
8423 | |||
8424 | for (i = 0; i < AUTO_PIN_LAST; i++) { | ||
8425 | switch(cfg->input_pins[i]) { | ||
8426 | case 0x18: | ||
8427 | idx1 = 0; /* Mic 1 */ | ||
8428 | break; | ||
8429 | case 0x19: | ||
8430 | idx1 = 1; /* Mic 2 */ | ||
8431 | break; | ||
8432 | case 0x1a: | ||
8433 | idx1 = 2; /* Line In */ | ||
8434 | break; | ||
8435 | case 0x1c: | ||
8436 | idx1 = 3; /* CD */ | ||
8437 | break; | ||
8438 | default: | ||
8439 | continue; | ||
8440 | } | ||
8441 | imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; | ||
8442 | imux->items[imux->num_items].index = idx1; | ||
8443 | imux->num_items++; | ||
8444 | } | ||
8445 | return 0; | ||
8446 | } | ||
8447 | |||
8448 | static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec) | ||
8449 | { | ||
8450 | struct alc_spec *spec = codec->spec; | ||
8451 | hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0]; | ||
8452 | hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; | ||
8453 | hda_nid_t line_nid = spec->autocfg.line_out_pins[0]; | ||
8454 | unsigned int dac_vol1, dac_vol2; | ||
8455 | |||
8456 | if (speaker_nid) { | ||
8457 | snd_hda_codec_write(codec, speaker_nid, 0, | ||
8458 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | ||
8459 | snd_hda_codec_write(codec, 0x0f, 0, | ||
8460 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
8461 | AMP_IN_UNMUTE(1)); | ||
8462 | snd_hda_codec_write(codec, 0x10, 0, | ||
8463 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
8464 | AMP_IN_UNMUTE(1)); | ||
8465 | } else { | ||
8466 | snd_hda_codec_write(codec, 0x0f, 0, | ||
8467 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); | ||
8468 | snd_hda_codec_write(codec, 0x10, 0, | ||
8469 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); | ||
8470 | } | ||
8471 | |||
8472 | dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */ | ||
8473 | if (line_nid == 0x14) | ||
8474 | dac_vol2 = AMP_OUT_ZERO; | ||
8475 | else if (line_nid == 0x15) | ||
8476 | dac_vol1 = AMP_OUT_ZERO; | ||
8477 | if (hp_nid == 0x14) | ||
8478 | dac_vol2 = AMP_OUT_ZERO; | ||
8479 | else if (hp_nid == 0x15) | ||
8480 | dac_vol1 = AMP_OUT_ZERO; | ||
8481 | if (line_nid != 0x16 || hp_nid != 0x16 || | ||
8482 | spec->autocfg.line_out_pins[1] != 0x16 || | ||
8483 | spec->autocfg.line_out_pins[2] != 0x16) | ||
8484 | dac_vol1 = dac_vol2 = AMP_OUT_ZERO; | ||
8485 | |||
8486 | snd_hda_codec_write(codec, 0x02, 0, | ||
8487 | AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1); | ||
8488 | snd_hda_codec_write(codec, 0x03, 0, | ||
8489 | AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2); | ||
8490 | } | ||
8491 | |||
8492 | /* pcm configuration: identiacal with ALC880 */ | ||
8493 | #define alc268_pcm_analog_playback alc880_pcm_analog_playback | ||
8494 | #define alc268_pcm_analog_capture alc880_pcm_analog_capture | ||
8495 | #define alc268_pcm_digital_playback alc880_pcm_digital_playback | ||
8496 | |||
8497 | /* | ||
8498 | * BIOS auto configuration | ||
8499 | */ | ||
8500 | static int alc268_parse_auto_config(struct hda_codec *codec) | ||
8501 | { | ||
8502 | struct alc_spec *spec = codec->spec; | ||
8503 | int err; | ||
8504 | static hda_nid_t alc268_ignore[] = { 0 }; | ||
8505 | |||
8506 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | ||
8507 | alc268_ignore); | ||
8508 | if (err < 0) | ||
8509 | return err; | ||
8510 | if (!spec->autocfg.line_outs) | ||
8511 | return 0; /* can't find valid BIOS pin config */ | ||
8512 | |||
8513 | err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg); | ||
8514 | if (err < 0) | ||
8515 | return err; | ||
8516 | err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg); | ||
8517 | if (err < 0) | ||
8518 | return err; | ||
8519 | |||
8520 | spec->multiout.max_channels = 2; | ||
8521 | |||
8522 | /* digital only support output */ | ||
8523 | if (spec->autocfg.dig_out_pin) | ||
8524 | spec->multiout.dig_out_nid = ALC268_DIGOUT_NID; | ||
8525 | |||
8526 | if (spec->kctl_alloc) | ||
8527 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; | ||
8528 | |||
8529 | spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs; | ||
8530 | spec->num_mux_defs = 1; | ||
8531 | spec->input_mux = &spec->private_imux; | ||
8532 | |||
8533 | return 1; | ||
8534 | } | ||
8535 | |||
8536 | #define alc268_auto_init_multi_out alc882_auto_init_multi_out | ||
8537 | #define alc268_auto_init_hp_out alc882_auto_init_hp_out | ||
8538 | #define alc268_auto_init_analog_input alc882_auto_init_analog_input | ||
8539 | |||
8540 | /* init callback for auto-configuration model -- overriding the default init */ | ||
8541 | static void alc268_auto_init(struct hda_codec *codec) | ||
8542 | { | ||
8543 | alc268_auto_init_multi_out(codec); | ||
8544 | alc268_auto_init_hp_out(codec); | ||
8545 | alc268_auto_init_mono_speaker_out(codec); | ||
8546 | alc268_auto_init_analog_input(codec); | ||
8547 | } | ||
8548 | |||
8549 | /* | ||
8550 | * configuration and preset | ||
8551 | */ | ||
8552 | static const char *alc268_models[ALC268_MODEL_LAST] = { | ||
8553 | [ALC268_3ST] = "3stack", | ||
8554 | [ALC268_AUTO] = "auto", | ||
8555 | }; | ||
8556 | |||
8557 | static struct snd_pci_quirk alc268_cfg_tbl[] = { | ||
8558 | SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), | ||
8559 | {} | ||
8560 | }; | ||
8561 | |||
8562 | static struct alc_config_preset alc268_presets[] = { | ||
8563 | [ALC268_3ST] = { | ||
8564 | .mixers = { alc268_base_mixer, alc268_capture_alt_mixer }, | ||
8565 | .init_verbs = { alc268_base_init_verbs }, | ||
8566 | .num_dacs = ARRAY_SIZE(alc268_dac_nids), | ||
8567 | .dac_nids = alc268_dac_nids, | ||
8568 | .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), | ||
8569 | .adc_nids = alc268_adc_nids_alt, | ||
8570 | .hp_nid = 0x03, | ||
8571 | .dig_out_nid = ALC268_DIGOUT_NID, | ||
8572 | .num_channel_mode = ARRAY_SIZE(alc268_modes), | ||
8573 | .channel_mode = alc268_modes, | ||
8574 | .input_mux = &alc268_capture_source, | ||
8575 | }, | ||
8576 | }; | ||
8577 | |||
8578 | static int patch_alc268(struct hda_codec *codec) | ||
8579 | { | ||
8580 | struct alc_spec *spec; | ||
8581 | int board_config; | ||
8582 | int err; | ||
8583 | |||
8584 | spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); | ||
8585 | if (spec == NULL) | ||
8586 | return -ENOMEM; | ||
8587 | |||
8588 | codec->spec = spec; | ||
8589 | |||
8590 | board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST, | ||
8591 | alc268_models, | ||
8592 | alc268_cfg_tbl); | ||
8593 | |||
8594 | if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { | ||
8595 | printk(KERN_INFO "hda_codec: Unknown model for ALC268, " | ||
8596 | "trying auto-probe from BIOS...\n"); | ||
8597 | board_config = ALC268_AUTO; | ||
8598 | } | ||
8599 | |||
8600 | if (board_config == ALC268_AUTO) { | ||
8601 | /* automatic parse from the BIOS config */ | ||
8602 | err = alc268_parse_auto_config(codec); | ||
8603 | if (err < 0) { | ||
8604 | alc_free(codec); | ||
8605 | return err; | ||
8606 | } else if (!err) { | ||
8607 | printk(KERN_INFO | ||
8608 | "hda_codec: Cannot set up configuration " | ||
8609 | "from BIOS. Using base mode...\n"); | ||
8610 | board_config = ALC268_3ST; | ||
8611 | } | ||
8612 | } | ||
8613 | |||
8614 | if (board_config != ALC268_AUTO) | ||
8615 | setup_preset(spec, &alc268_presets[board_config]); | ||
8616 | |||
8617 | spec->stream_name_analog = "ALC268 Analog"; | ||
8618 | spec->stream_analog_playback = &alc268_pcm_analog_playback; | ||
8619 | spec->stream_analog_capture = &alc268_pcm_analog_capture; | ||
8620 | |||
8621 | spec->stream_name_digital = "ALC268 Digital"; | ||
8622 | spec->stream_digital_playback = &alc268_pcm_digital_playback; | ||
8623 | |||
8624 | if (board_config == ALC268_AUTO) { | ||
8625 | if (!spec->adc_nids && spec->input_mux) { | ||
8626 | /* check whether NID 0x07 is valid */ | ||
8627 | unsigned int wcap = get_wcaps(codec, 0x07); | ||
8628 | |||
8629 | /* get type */ | ||
8630 | wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | ||
8631 | if (wcap != AC_WID_AUD_IN) { | ||
8632 | spec->adc_nids = alc268_adc_nids_alt; | ||
8633 | spec->num_adc_nids = | ||
8634 | ARRAY_SIZE(alc268_adc_nids_alt); | ||
8635 | spec->mixers[spec->num_mixers] = | ||
8636 | alc268_capture_alt_mixer; | ||
8637 | spec->num_mixers++; | ||
8638 | } else { | ||
8639 | spec->adc_nids = alc268_adc_nids; | ||
8640 | spec->num_adc_nids = | ||
8641 | ARRAY_SIZE(alc268_adc_nids); | ||
8642 | spec->mixers[spec->num_mixers] = | ||
8643 | alc268_capture_mixer; | ||
8644 | spec->num_mixers++; | ||
8645 | } | ||
8646 | } | ||
8647 | } | ||
8648 | codec->patch_ops = alc_patch_ops; | ||
8649 | if (board_config == ALC268_AUTO) | ||
8650 | spec->init_hook = alc268_auto_init; | ||
8651 | |||
8652 | return 0; | ||
8653 | } | ||
8654 | |||
8655 | /* | ||
7803 | * ALC861 channel source setting (2/6 channel selection for 3-stack) | 8656 | * ALC861 channel source setting (2/6 channel selection for 3-stack) |
7804 | */ | 8657 | */ |
7805 | 8658 | ||
@@ -8767,13 +9620,21 @@ static struct snd_pci_quirk alc861_cfg_tbl[] = { | |||
8767 | SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), | 9620 | SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), |
8768 | SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), | 9621 | SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), |
8769 | SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP), | 9622 | SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP), |
9623 | SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP), | ||
8770 | SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS), | 9624 | SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS), |
9625 | SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG), | ||
8771 | SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA), | 9626 | SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA), |
8772 | SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), | 9627 | /* FIXME: the entry below breaks Toshiba A100 (model=auto works!) |
9628 | * Any other models that need this preset? | ||
9629 | */ | ||
9630 | /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */ | ||
8773 | SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31), | 9631 | SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31), |
9632 | SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), | ||
8774 | SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31), | 9633 | SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31), |
8775 | SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST), | 9634 | SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST), |
8776 | SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST), | 9635 | SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST), |
9636 | SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST), | ||
9637 | SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST), | ||
8777 | {} | 9638 | {} |
8778 | }; | 9639 | }; |
8779 | 9640 | ||
@@ -9464,6 +10325,7 @@ static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int re | |||
9464 | */ | 10325 | */ |
9465 | static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { | 10326 | static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { |
9466 | [ALC660VD_3ST] = "3stack-660", | 10327 | [ALC660VD_3ST] = "3stack-660", |
10328 | [ALC660VD_3ST_DIG]= "3stack-660-digout", | ||
9467 | [ALC861VD_3ST] = "3stack", | 10329 | [ALC861VD_3ST] = "3stack", |
9468 | [ALC861VD_3ST_DIG] = "3stack-digout", | 10330 | [ALC861VD_3ST_DIG] = "3stack-digout", |
9469 | [ALC861VD_6ST_DIG] = "6stack-digout", | 10331 | [ALC861VD_6ST_DIG] = "6stack-digout", |
@@ -9475,7 +10337,7 @@ static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { | |||
9475 | static struct snd_pci_quirk alc861vd_cfg_tbl[] = { | 10337 | static struct snd_pci_quirk alc861vd_cfg_tbl[] = { |
9476 | SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), | 10338 | SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), |
9477 | SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST), | 10339 | SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST), |
9478 | SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST), | 10340 | SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG), |
9479 | SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), | 10341 | SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), |
9480 | SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), | 10342 | SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), |
9481 | 10343 | ||
@@ -9483,6 +10345,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = { | |||
9483 | SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS), | 10345 | SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS), |
9484 | SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO), | 10346 | SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO), |
9485 | SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO), | 10347 | SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO), |
10348 | SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO), | ||
9486 | {} | 10349 | {} |
9487 | }; | 10350 | }; |
9488 | 10351 | ||
@@ -9499,6 +10362,19 @@ static struct alc_config_preset alc861vd_presets[] = { | |||
9499 | .channel_mode = alc861vd_3stack_2ch_modes, | 10362 | .channel_mode = alc861vd_3stack_2ch_modes, |
9500 | .input_mux = &alc861vd_capture_source, | 10363 | .input_mux = &alc861vd_capture_source, |
9501 | }, | 10364 | }, |
10365 | [ALC660VD_3ST_DIG] = { | ||
10366 | .mixers = { alc861vd_3st_mixer }, | ||
10367 | .init_verbs = { alc861vd_volume_init_verbs, | ||
10368 | alc861vd_3stack_init_verbs }, | ||
10369 | .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), | ||
10370 | .dac_nids = alc660vd_dac_nids, | ||
10371 | .dig_out_nid = ALC861VD_DIGOUT_NID, | ||
10372 | .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), | ||
10373 | .adc_nids = alc861vd_adc_nids, | ||
10374 | .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), | ||
10375 | .channel_mode = alc861vd_3stack_2ch_modes, | ||
10376 | .input_mux = &alc861vd_capture_source, | ||
10377 | }, | ||
9502 | [ALC861VD_3ST] = { | 10378 | [ALC861VD_3ST] = { |
9503 | .mixers = { alc861vd_3st_mixer }, | 10379 | .mixers = { alc861vd_3st_mixer }, |
9504 | .init_verbs = { alc861vd_volume_init_verbs, | 10380 | .init_verbs = { alc861vd_volume_init_verbs, |
@@ -10420,7 +11296,7 @@ static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
10420 | for (i = 0; i < cfg->line_outs; i++) { | 11296 | for (i = 0; i < cfg->line_outs; i++) { |
10421 | if (!spec->multiout.dac_nids[i]) | 11297 | if (!spec->multiout.dac_nids[i]) |
10422 | continue; | 11298 | continue; |
10423 | nid = alc880_idx_to_dac(i); | 11299 | nid = alc880_idx_to_mixer(i); |
10424 | if (i == 2) { | 11300 | if (i == 2) { |
10425 | /* Center/LFE */ | 11301 | /* Center/LFE */ |
10426 | err = add_control(spec, ALC_CTL_WIDGET_VOL, | 11302 | err = add_control(spec, ALC_CTL_WIDGET_VOL, |
@@ -10643,14 +11519,10 @@ static int alc662_parse_auto_config(struct hda_codec *codec) | |||
10643 | spec->num_mux_defs = 1; | 11519 | spec->num_mux_defs = 1; |
10644 | spec->input_mux = &spec->private_imux; | 11520 | spec->input_mux = &spec->private_imux; |
10645 | 11521 | ||
10646 | if (err < 0) | 11522 | spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs; |
10647 | return err; | ||
10648 | else if (err > 0) | ||
10649 | /* hack - override the init verbs */ | ||
10650 | spec->init_verbs[0] = alc662_auto_init_verbs; | ||
10651 | spec->mixers[spec->num_mixers] = alc662_capture_mixer; | 11523 | spec->mixers[spec->num_mixers] = alc662_capture_mixer; |
10652 | spec->num_mixers++; | 11524 | spec->num_mixers++; |
10653 | return err; | 11525 | return 1; |
10654 | } | 11526 | } |
10655 | 11527 | ||
10656 | /* additional initialization for auto-configuration model */ | 11528 | /* additional initialization for auto-configuration model */ |
@@ -10687,7 +11559,7 @@ static int patch_alc662(struct hda_codec *codec) | |||
10687 | if (err < 0) { | 11559 | if (err < 0) { |
10688 | alc_free(codec); | 11560 | alc_free(codec); |
10689 | return err; | 11561 | return err; |
10690 | } else if (err) { | 11562 | } else if (!err) { |
10691 | printk(KERN_INFO | 11563 | printk(KERN_INFO |
10692 | "hda_codec: Cannot set up configuration " | 11564 | "hda_codec: Cannot set up configuration " |
10693 | "from BIOS. Using base mode...\n"); | 11565 | "from BIOS. Using base mode...\n"); |
@@ -10724,6 +11596,7 @@ static int patch_alc662(struct hda_codec *codec) | |||
10724 | struct hda_codec_preset snd_hda_preset_realtek[] = { | 11596 | struct hda_codec_preset snd_hda_preset_realtek[] = { |
10725 | { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, | 11597 | { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, |
10726 | { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, | 11598 | { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, |
11599 | { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 }, | ||
10727 | { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", | 11600 | { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", |
10728 | .patch = patch_alc861 }, | 11601 | .patch = patch_alc861 }, |
10729 | { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, | 11602 | { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, |
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c index 43f537ef40bf..6d2ecc38905c 100644 --- a/sound/pci/hda/patch_si3054.c +++ b/sound/pci/hda/patch_si3054.c | |||
@@ -304,8 +304,12 @@ struct hda_codec_preset snd_hda_preset_si3054[] = { | |||
304 | { .id = 0x10573055, .name = "Si3054", .patch = patch_si3054 }, | 304 | { .id = 0x10573055, .name = "Si3054", .patch = patch_si3054 }, |
305 | { .id = 0x10573057, .name = "Si3054", .patch = patch_si3054 }, | 305 | { .id = 0x10573057, .name = "Si3054", .patch = patch_si3054 }, |
306 | { .id = 0x10573155, .name = "Si3054", .patch = patch_si3054 }, | 306 | { .id = 0x10573155, .name = "Si3054", .patch = patch_si3054 }, |
307 | /* VIA HDA on Clevo m540 */ | ||
308 | { .id = 0x11063288, .name = "Si3054", .patch = patch_si3054 }, | ||
307 | /* Asus A8J Modem (SM56) */ | 309 | /* Asus A8J Modem (SM56) */ |
308 | { .id = 0x15433155, .name = "Si3054", .patch = patch_si3054 }, | 310 | { .id = 0x15433155, .name = "Si3054", .patch = patch_si3054 }, |
311 | /* LG LW20 modem */ | ||
312 | { .id = 0x18540018, .name = "Si3054", .patch = patch_si3054 }, | ||
309 | {} | 313 | {} |
310 | }; | 314 | }; |
311 | 315 | ||
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index e3964fc4c405..3f25de72966b 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -44,6 +44,7 @@ enum { | |||
44 | 44 | ||
45 | enum { | 45 | enum { |
46 | STAC_9205_REF, | 46 | STAC_9205_REF, |
47 | STAC_M43xx, | ||
47 | STAC_9205_MODELS | 48 | STAC_9205_MODELS |
48 | }; | 49 | }; |
49 | 50 | ||
@@ -59,11 +60,19 @@ enum { | |||
59 | STAC_D945_REF, | 60 | STAC_D945_REF, |
60 | STAC_D945GTP3, | 61 | STAC_D945GTP3, |
61 | STAC_D945GTP5, | 62 | STAC_D945GTP5, |
63 | STAC_922X_DELL, | ||
64 | STAC_INTEL_MAC_V1, | ||
65 | STAC_INTEL_MAC_V2, | ||
66 | STAC_INTEL_MAC_V3, | ||
67 | STAC_INTEL_MAC_V4, | ||
68 | STAC_INTEL_MAC_V5, | ||
69 | /* for backward compitability */ | ||
62 | STAC_MACMINI, | 70 | STAC_MACMINI, |
63 | STAC_MACBOOK, | 71 | STAC_MACBOOK, |
64 | STAC_MACBOOK_PRO_V1, | 72 | STAC_MACBOOK_PRO_V1, |
65 | STAC_MACBOOK_PRO_V2, | 73 | STAC_MACBOOK_PRO_V2, |
66 | STAC_IMAC_INTEL, | 74 | STAC_IMAC_INTEL, |
75 | STAC_IMAC_INTEL_20, | ||
67 | STAC_922X_MODELS | 76 | STAC_922X_MODELS |
68 | }; | 77 | }; |
69 | 78 | ||
@@ -210,7 +219,6 @@ static hda_nid_t stac9205_pin_nids[12] = { | |||
210 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, | 219 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, |
211 | 0x0f, 0x14, 0x16, 0x17, 0x18, | 220 | 0x0f, 0x14, 0x16, 0x17, 0x18, |
212 | 0x21, 0x22, | 221 | 0x21, 0x22, |
213 | |||
214 | }; | 222 | }; |
215 | 223 | ||
216 | static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol, | 224 | static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol, |
@@ -326,8 +334,6 @@ static struct snd_kcontrol_new stac9200_mixer[] = { | |||
326 | }; | 334 | }; |
327 | 335 | ||
328 | static struct snd_kcontrol_new stac925x_mixer[] = { | 336 | static struct snd_kcontrol_new stac925x_mixer[] = { |
329 | HDA_CODEC_VOLUME("Master Playback Volume", 0xe, 0, HDA_OUTPUT), | ||
330 | HDA_CODEC_MUTE("Master Playback Switch", 0xe, 0, HDA_OUTPUT), | ||
331 | { | 337 | { |
332 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 338 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
333 | .name = "Input Source", | 339 | .name = "Input Source", |
@@ -549,44 +555,78 @@ static unsigned int d945gtp5_pin_configs[10] = { | |||
549 | 0x02a19320, 0x40000100, | 555 | 0x02a19320, 0x40000100, |
550 | }; | 556 | }; |
551 | 557 | ||
552 | static unsigned int macbook_pro_v1_pin_configs[10] = { | 558 | static unsigned int intel_mac_v1_pin_configs[10] = { |
553 | 0x0321e230, 0x03a1e020, 0x9017e110, 0x01014010, | 559 | 0x0121e21f, 0x400000ff, 0x9017e110, 0x400000fd, |
554 | 0x01a19021, 0x0381e021, 0x1345e240, 0x13c5e22e, | 560 | 0x400000fe, 0x0181e020, 0x1145e030, 0x11c5e240, |
555 | 0x02a19320, 0x400000fb | 561 | 0x400000fc, 0x400000fb, |
562 | }; | ||
563 | |||
564 | static unsigned int intel_mac_v2_pin_configs[10] = { | ||
565 | 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd, | ||
566 | 0x400000fe, 0x0181e020, 0x1145e230, 0x500000fa, | ||
567 | 0x400000fc, 0x400000fb, | ||
568 | }; | ||
569 | |||
570 | static unsigned int intel_mac_v3_pin_configs[10] = { | ||
571 | 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd, | ||
572 | 0x400000fe, 0x0181e020, 0x1145e230, 0x11c5e240, | ||
573 | 0x400000fc, 0x400000fb, | ||
556 | }; | 574 | }; |
557 | 575 | ||
558 | static unsigned int macbook_pro_v2_pin_configs[10] = { | 576 | static unsigned int intel_mac_v4_pin_configs[10] = { |
559 | 0x0221401f, 0x90a70120, 0x01813024, 0x01014010, | 577 | 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f, |
560 | 0x400000fd, 0x01016011, 0x1345e240, 0x13c5e22e, | 578 | 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240, |
561 | 0x400000fc, 0x400000fb, | 579 | 0x400000fc, 0x400000fb, |
562 | }; | 580 | }; |
563 | 581 | ||
564 | static unsigned int imac_intel_pin_configs[10] = { | 582 | static unsigned int intel_mac_v5_pin_configs[10] = { |
565 | 0x0121e230, 0x90a70120, 0x9017e110, 0x400000fe, | 583 | 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f, |
566 | 0x400000fd, 0x0181e021, 0x1145e040, 0x400000fa, | 584 | 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240, |
567 | 0x400000fc, 0x400000fb, | 585 | 0x400000fc, 0x400000fb, |
568 | }; | 586 | }; |
569 | 587 | ||
588 | static unsigned int stac922x_dell_pin_configs[10] = { | ||
589 | 0x0221121e, 0x408103ff, 0x02a1123e, 0x90100310, | ||
590 | 0x408003f1, 0x0221122f, 0x03451340, 0x40c003f2, | ||
591 | 0x50a003f3, 0x405003f4 | ||
592 | }; | ||
593 | |||
570 | static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { | 594 | static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { |
571 | [STAC_D945_REF] = ref922x_pin_configs, | 595 | [STAC_D945_REF] = ref922x_pin_configs, |
572 | [STAC_D945GTP3] = d945gtp3_pin_configs, | 596 | [STAC_D945GTP3] = d945gtp3_pin_configs, |
573 | [STAC_D945GTP5] = d945gtp5_pin_configs, | 597 | [STAC_D945GTP5] = d945gtp5_pin_configs, |
574 | [STAC_MACMINI] = macbook_pro_v1_pin_configs, | 598 | [STAC_922X_DELL] = stac922x_dell_pin_configs, |
575 | [STAC_MACBOOK] = macbook_pro_v1_pin_configs, | 599 | [STAC_INTEL_MAC_V1] = intel_mac_v1_pin_configs, |
576 | [STAC_MACBOOK_PRO_V1] = macbook_pro_v1_pin_configs, | 600 | [STAC_INTEL_MAC_V2] = intel_mac_v2_pin_configs, |
577 | [STAC_MACBOOK_PRO_V2] = macbook_pro_v2_pin_configs, | 601 | [STAC_INTEL_MAC_V3] = intel_mac_v3_pin_configs, |
578 | [STAC_IMAC_INTEL] = imac_intel_pin_configs, | 602 | [STAC_INTEL_MAC_V4] = intel_mac_v4_pin_configs, |
603 | [STAC_INTEL_MAC_V5] = intel_mac_v5_pin_configs, | ||
604 | /* for backward compitability */ | ||
605 | [STAC_MACMINI] = intel_mac_v3_pin_configs, | ||
606 | [STAC_MACBOOK] = intel_mac_v5_pin_configs, | ||
607 | [STAC_MACBOOK_PRO_V1] = intel_mac_v3_pin_configs, | ||
608 | [STAC_MACBOOK_PRO_V2] = intel_mac_v3_pin_configs, | ||
609 | [STAC_IMAC_INTEL] = intel_mac_v2_pin_configs, | ||
610 | [STAC_IMAC_INTEL_20] = intel_mac_v3_pin_configs, | ||
579 | }; | 611 | }; |
580 | 612 | ||
581 | static const char *stac922x_models[STAC_922X_MODELS] = { | 613 | static const char *stac922x_models[STAC_922X_MODELS] = { |
582 | [STAC_D945_REF] = "ref", | 614 | [STAC_D945_REF] = "ref", |
583 | [STAC_D945GTP5] = "5stack", | 615 | [STAC_D945GTP5] = "5stack", |
584 | [STAC_D945GTP3] = "3stack", | 616 | [STAC_D945GTP3] = "3stack", |
617 | [STAC_922X_DELL] = "dell", | ||
618 | [STAC_INTEL_MAC_V1] = "intel-mac-v1", | ||
619 | [STAC_INTEL_MAC_V2] = "intel-mac-v2", | ||
620 | [STAC_INTEL_MAC_V3] = "intel-mac-v3", | ||
621 | [STAC_INTEL_MAC_V4] = "intel-mac-v4", | ||
622 | [STAC_INTEL_MAC_V5] = "intel-mac-v5", | ||
623 | /* for backward compitability */ | ||
585 | [STAC_MACMINI] = "macmini", | 624 | [STAC_MACMINI] = "macmini", |
586 | [STAC_MACBOOK] = "macbook", | 625 | [STAC_MACBOOK] = "macbook", |
587 | [STAC_MACBOOK_PRO_V1] = "macbook-pro-v1", | 626 | [STAC_MACBOOK_PRO_V1] = "macbook-pro-v1", |
588 | [STAC_MACBOOK_PRO_V2] = "macbook-pro", | 627 | [STAC_MACBOOK_PRO_V2] = "macbook-pro", |
589 | [STAC_IMAC_INTEL] = "imac-intel", | 628 | [STAC_IMAC_INTEL] = "imac-intel", |
629 | [STAC_IMAC_INTEL_20] = "imac-intel-20", | ||
590 | }; | 630 | }; |
591 | 631 | ||
592 | static struct snd_pci_quirk stac922x_cfg_tbl[] = { | 632 | static struct snd_pci_quirk stac922x_cfg_tbl[] = { |
@@ -649,7 +689,10 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = { | |||
649 | /* other systems */ | 689 | /* other systems */ |
650 | /* Apple Mac Mini (early 2006) */ | 690 | /* Apple Mac Mini (early 2006) */ |
651 | SND_PCI_QUIRK(0x8384, 0x7680, | 691 | SND_PCI_QUIRK(0x8384, 0x7680, |
652 | "Mac Mini", STAC_MACMINI), | 692 | "Mac Mini", STAC_INTEL_MAC_V3), |
693 | /* Dell */ | ||
694 | SND_PCI_QUIRK(0x1028, 0x01d7, "Dell XPS M1210", STAC_922X_DELL), | ||
695 | |||
653 | {} /* terminator */ | 696 | {} /* terminator */ |
654 | }; | 697 | }; |
655 | 698 | ||
@@ -730,7 +773,8 @@ static unsigned int ref9205_pin_configs[12] = { | |||
730 | }; | 773 | }; |
731 | 774 | ||
732 | static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = { | 775 | static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = { |
733 | ref9205_pin_configs, | 776 | [STAC_REF] = ref9205_pin_configs, |
777 | [STAC_M43xx] = NULL, | ||
734 | }; | 778 | }; |
735 | 779 | ||
736 | static const char *stac9205_models[STAC_9205_MODELS] = { | 780 | static const char *stac9205_models[STAC_9205_MODELS] = { |
@@ -741,6 +785,10 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = { | |||
741 | /* SigmaTel reference board */ | 785 | /* SigmaTel reference board */ |
742 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 786 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
743 | "DFI LanParty", STAC_9205_REF), | 787 | "DFI LanParty", STAC_9205_REF), |
788 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x01f8, | ||
789 | "Dell Precision", STAC_M43xx), | ||
790 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x01ff, | ||
791 | "Dell Precision", STAC_M43xx), | ||
744 | {} /* terminator */ | 792 | {} /* terminator */ |
745 | }; | 793 | }; |
746 | 794 | ||
@@ -770,33 +818,56 @@ static int stac92xx_save_bios_config_regs(struct hda_codec *codec) | |||
770 | return 0; | 818 | return 0; |
771 | } | 819 | } |
772 | 820 | ||
821 | static void stac92xx_set_config_reg(struct hda_codec *codec, | ||
822 | hda_nid_t pin_nid, unsigned int pin_config) | ||
823 | { | ||
824 | int i; | ||
825 | snd_hda_codec_write(codec, pin_nid, 0, | ||
826 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_0, | ||
827 | pin_config & 0x000000ff); | ||
828 | snd_hda_codec_write(codec, pin_nid, 0, | ||
829 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, | ||
830 | (pin_config & 0x0000ff00) >> 8); | ||
831 | snd_hda_codec_write(codec, pin_nid, 0, | ||
832 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, | ||
833 | (pin_config & 0x00ff0000) >> 16); | ||
834 | snd_hda_codec_write(codec, pin_nid, 0, | ||
835 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, | ||
836 | pin_config >> 24); | ||
837 | i = snd_hda_codec_read(codec, pin_nid, 0, | ||
838 | AC_VERB_GET_CONFIG_DEFAULT, | ||
839 | 0x00); | ||
840 | snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x pin config %8.8x\n", | ||
841 | pin_nid, i); | ||
842 | } | ||
843 | |||
773 | static void stac92xx_set_config_regs(struct hda_codec *codec) | 844 | static void stac92xx_set_config_regs(struct hda_codec *codec) |
774 | { | 845 | { |
775 | int i; | 846 | int i; |
776 | struct sigmatel_spec *spec = codec->spec; | 847 | struct sigmatel_spec *spec = codec->spec; |
777 | unsigned int pin_cfg; | ||
778 | 848 | ||
779 | if (! spec->pin_nids || ! spec->pin_configs) | 849 | if (!spec->pin_configs) |
780 | return; | 850 | return; |
781 | 851 | ||
782 | for (i = 0; i < spec->num_pins; i++) { | 852 | for (i = 0; i < spec->num_pins; i++) |
783 | snd_hda_codec_write(codec, spec->pin_nids[i], 0, | 853 | stac92xx_set_config_reg(codec, spec->pin_nids[i], |
784 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_0, | 854 | spec->pin_configs[i]); |
785 | spec->pin_configs[i] & 0x000000ff); | 855 | } |
786 | snd_hda_codec_write(codec, spec->pin_nids[i], 0, | 856 | |
787 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, | 857 | static void stac92xx_enable_gpio_mask(struct hda_codec *codec, |
788 | (spec->pin_configs[i] & 0x0000ff00) >> 8); | 858 | int gpio_mask, int gpio_data) |
789 | snd_hda_codec_write(codec, spec->pin_nids[i], 0, | 859 | { |
790 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, | 860 | /* Configure GPIOx as output */ |
791 | (spec->pin_configs[i] & 0x00ff0000) >> 16); | 861 | snd_hda_codec_write(codec, codec->afg, 0, |
792 | snd_hda_codec_write(codec, spec->pin_nids[i], 0, | 862 | AC_VERB_SET_GPIO_DIRECTION, gpio_mask); |
793 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, | 863 | /* Configure GPIOx as CMOS */ |
794 | spec->pin_configs[i] >> 24); | 864 | snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0x00000000); |
795 | pin_cfg = snd_hda_codec_read(codec, spec->pin_nids[i], 0, | 865 | /* Assert GPIOx */ |
796 | AC_VERB_GET_CONFIG_DEFAULT, | 866 | snd_hda_codec_write(codec, codec->afg, 0, |
797 | 0x00); | 867 | AC_VERB_SET_GPIO_DATA, gpio_data); |
798 | snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x pin config %8.8x\n", spec->pin_nids[i], pin_cfg); | 868 | /* Enable GPIOx */ |
799 | } | 869 | snd_hda_codec_write(codec, codec->afg, 0, |
870 | AC_VERB_SET_GPIO_MASK, gpio_mask); | ||
800 | } | 871 | } |
801 | 872 | ||
802 | /* | 873 | /* |
@@ -1168,7 +1239,7 @@ static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) | |||
1168 | * and 9202/925x. For those, dac_nids[] must be hard-coded. | 1239 | * and 9202/925x. For those, dac_nids[] must be hard-coded. |
1169 | */ | 1240 | */ |
1170 | static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, | 1241 | static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, |
1171 | const struct auto_pin_cfg *cfg) | 1242 | struct auto_pin_cfg *cfg) |
1172 | { | 1243 | { |
1173 | struct sigmatel_spec *spec = codec->spec; | 1244 | struct sigmatel_spec *spec = codec->spec; |
1174 | int i, j, conn_len = 0; | 1245 | int i, j, conn_len = 0; |
@@ -1193,6 +1264,13 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, | |||
1193 | } | 1264 | } |
1194 | 1265 | ||
1195 | if (j == conn_len) { | 1266 | if (j == conn_len) { |
1267 | if (spec->multiout.num_dacs > 0) { | ||
1268 | /* we have already working output pins, | ||
1269 | * so let's drop the broken ones again | ||
1270 | */ | ||
1271 | cfg->line_outs = spec->multiout.num_dacs; | ||
1272 | break; | ||
1273 | } | ||
1196 | /* error out, no available DAC found */ | 1274 | /* error out, no available DAC found */ |
1197 | snd_printk(KERN_ERR | 1275 | snd_printk(KERN_ERR |
1198 | "%s: No available DAC for pin 0x%x\n", | 1276 | "%s: No available DAC for pin 0x%x\n", |
@@ -1334,7 +1412,15 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, | |||
1334 | continue; | 1412 | continue; |
1335 | add_spec_dacs(spec, nid); | 1413 | add_spec_dacs(spec, nid); |
1336 | } | 1414 | } |
1337 | 1415 | for (i = 0; i < cfg->line_outs; i++) { | |
1416 | nid = snd_hda_codec_read(codec, cfg->line_out_pins[i], 0, | ||
1417 | AC_VERB_GET_CONNECT_LIST, 0) & 0xff; | ||
1418 | if (check_in_dac_nids(spec, nid)) | ||
1419 | nid = 0; | ||
1420 | if (! nid) | ||
1421 | continue; | ||
1422 | add_spec_dacs(spec, nid); | ||
1423 | } | ||
1338 | for (i = old_num_dacs; i < spec->multiout.num_dacs; i++) { | 1424 | for (i = old_num_dacs; i < spec->multiout.num_dacs; i++) { |
1339 | static const char *pfxs[] = { | 1425 | static const char *pfxs[] = { |
1340 | "Speaker", "External Speaker", "Speaker2", | 1426 | "Speaker", "External Speaker", "Speaker2", |
@@ -1891,7 +1977,7 @@ static int patch_stac9200(struct hda_codec *codec) | |||
1891 | return -ENOMEM; | 1977 | return -ENOMEM; |
1892 | 1978 | ||
1893 | codec->spec = spec; | 1979 | codec->spec = spec; |
1894 | spec->num_pins = 8; | 1980 | spec->num_pins = ARRAY_SIZE(stac9200_pin_nids); |
1895 | spec->pin_nids = stac9200_pin_nids; | 1981 | spec->pin_nids = stac9200_pin_nids; |
1896 | spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS, | 1982 | spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS, |
1897 | stac9200_models, | 1983 | stac9200_models, |
@@ -1941,7 +2027,7 @@ static int patch_stac925x(struct hda_codec *codec) | |||
1941 | return -ENOMEM; | 2027 | return -ENOMEM; |
1942 | 2028 | ||
1943 | codec->spec = spec; | 2029 | codec->spec = spec; |
1944 | spec->num_pins = 8; | 2030 | spec->num_pins = ARRAY_SIZE(stac925x_pin_nids); |
1945 | spec->pin_nids = stac925x_pin_nids; | 2031 | spec->pin_nids = stac925x_pin_nids; |
1946 | spec->board_config = snd_hda_check_board_config(codec, STAC_925x_MODELS, | 2032 | spec->board_config = snd_hda_check_board_config(codec, STAC_925x_MODELS, |
1947 | stac925x_models, | 2033 | stac925x_models, |
@@ -2013,29 +2099,41 @@ static int patch_stac922x(struct hda_codec *codec) | |||
2013 | return -ENOMEM; | 2099 | return -ENOMEM; |
2014 | 2100 | ||
2015 | codec->spec = spec; | 2101 | codec->spec = spec; |
2016 | spec->num_pins = 10; | 2102 | spec->num_pins = ARRAY_SIZE(stac922x_pin_nids); |
2017 | spec->pin_nids = stac922x_pin_nids; | 2103 | spec->pin_nids = stac922x_pin_nids; |
2018 | spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS, | 2104 | spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS, |
2019 | stac922x_models, | 2105 | stac922x_models, |
2020 | stac922x_cfg_tbl); | 2106 | stac922x_cfg_tbl); |
2021 | if (spec->board_config == STAC_MACMINI) { | 2107 | if (spec->board_config == STAC_INTEL_MAC_V3) { |
2022 | spec->gpio_mute = 1; | 2108 | spec->gpio_mute = 1; |
2023 | /* Intel Macs have all same PCI SSID, so we need to check | 2109 | /* Intel Macs have all same PCI SSID, so we need to check |
2024 | * codec SSID to distinguish the exact models | 2110 | * codec SSID to distinguish the exact models |
2025 | */ | 2111 | */ |
2026 | printk(KERN_INFO "hda_codec: STAC922x, Apple subsys_id=%x\n", codec->subsystem_id); | 2112 | printk(KERN_INFO "hda_codec: STAC922x, Apple subsys_id=%x\n", codec->subsystem_id); |
2027 | switch (codec->subsystem_id) { | 2113 | switch (codec->subsystem_id) { |
2028 | case 0x106b0a00: /* MacBook First generatoin */ | 2114 | |
2029 | spec->board_config = STAC_MACBOOK; | 2115 | case 0x106b0800: |
2116 | spec->board_config = STAC_INTEL_MAC_V1; | ||
2117 | break; | ||
2118 | case 0x106b0600: | ||
2119 | case 0x106b0700: | ||
2120 | spec->board_config = STAC_INTEL_MAC_V2; | ||
2030 | break; | 2121 | break; |
2031 | case 0x106b0200: /* MacBook Pro first generation */ | 2122 | case 0x106b0e00: |
2032 | spec->board_config = STAC_MACBOOK_PRO_V1; | 2123 | case 0x106b0f00: |
2124 | case 0x106b1600: | ||
2125 | case 0x106b1700: | ||
2126 | case 0x106b0200: | ||
2127 | case 0x106b1e00: | ||
2128 | spec->board_config = STAC_INTEL_MAC_V3; | ||
2033 | break; | 2129 | break; |
2034 | case 0x106b1e00: /* MacBook Pro second generation */ | 2130 | case 0x106b1a00: |
2035 | spec->board_config = STAC_MACBOOK_PRO_V2; | 2131 | case 0x00000100: |
2132 | spec->board_config = STAC_INTEL_MAC_V4; | ||
2036 | break; | 2133 | break; |
2037 | case 0x106b0700: /* Intel-based iMac */ | 2134 | case 0x106b0a00: |
2038 | spec->board_config = STAC_IMAC_INTEL; | 2135 | case 0x106b2200: |
2136 | spec->board_config = STAC_INTEL_MAC_V5; | ||
2039 | break; | 2137 | break; |
2040 | } | 2138 | } |
2041 | } | 2139 | } |
@@ -2082,6 +2180,13 @@ static int patch_stac922x(struct hda_codec *codec) | |||
2082 | 2180 | ||
2083 | codec->patch_ops = stac92xx_patch_ops; | 2181 | codec->patch_ops = stac92xx_patch_ops; |
2084 | 2182 | ||
2183 | /* Fix Mux capture level; max to 2 */ | ||
2184 | snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT, | ||
2185 | (0 << AC_AMPCAP_OFFSET_SHIFT) | | ||
2186 | (2 << AC_AMPCAP_NUM_STEPS_SHIFT) | | ||
2187 | (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) | | ||
2188 | (0 << AC_AMPCAP_MUTE_SHIFT)); | ||
2189 | |||
2085 | return 0; | 2190 | return 0; |
2086 | } | 2191 | } |
2087 | 2192 | ||
@@ -2095,7 +2200,7 @@ static int patch_stac927x(struct hda_codec *codec) | |||
2095 | return -ENOMEM; | 2200 | return -ENOMEM; |
2096 | 2201 | ||
2097 | codec->spec = spec; | 2202 | codec->spec = spec; |
2098 | spec->num_pins = 14; | 2203 | spec->num_pins = ARRAY_SIZE(stac927x_pin_nids); |
2099 | spec->pin_nids = stac927x_pin_nids; | 2204 | spec->pin_nids = stac927x_pin_nids; |
2100 | spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS, | 2205 | spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS, |
2101 | stac927x_models, | 2206 | stac927x_models, |
@@ -2141,7 +2246,9 @@ static int patch_stac927x(struct hda_codec *codec) | |||
2141 | } | 2246 | } |
2142 | 2247 | ||
2143 | spec->multiout.dac_nids = spec->dac_nids; | 2248 | spec->multiout.dac_nids = spec->dac_nids; |
2144 | 2249 | /* GPIO0 High = Enable EAPD */ | |
2250 | stac92xx_enable_gpio_mask(codec, 0x00000001, 0x00000001); | ||
2251 | |||
2145 | err = stac92xx_parse_auto_config(codec, 0x1e, 0x20); | 2252 | err = stac92xx_parse_auto_config(codec, 0x1e, 0x20); |
2146 | if (!err) { | 2253 | if (!err) { |
2147 | if (spec->board_config < 0) { | 2254 | if (spec->board_config < 0) { |
@@ -2159,27 +2266,20 @@ static int patch_stac927x(struct hda_codec *codec) | |||
2159 | 2266 | ||
2160 | codec->patch_ops = stac92xx_patch_ops; | 2267 | codec->patch_ops = stac92xx_patch_ops; |
2161 | 2268 | ||
2162 | /* Fix Mux capture level; max to 2 */ | ||
2163 | snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT, | ||
2164 | (0 << AC_AMPCAP_OFFSET_SHIFT) | | ||
2165 | (2 << AC_AMPCAP_NUM_STEPS_SHIFT) | | ||
2166 | (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) | | ||
2167 | (0 << AC_AMPCAP_MUTE_SHIFT)); | ||
2168 | |||
2169 | return 0; | 2269 | return 0; |
2170 | } | 2270 | } |
2171 | 2271 | ||
2172 | static int patch_stac9205(struct hda_codec *codec) | 2272 | static int patch_stac9205(struct hda_codec *codec) |
2173 | { | 2273 | { |
2174 | struct sigmatel_spec *spec; | 2274 | struct sigmatel_spec *spec; |
2175 | int err; | 2275 | int err, gpio_mask, gpio_data; |
2176 | 2276 | ||
2177 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 2277 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
2178 | if (spec == NULL) | 2278 | if (spec == NULL) |
2179 | return -ENOMEM; | 2279 | return -ENOMEM; |
2180 | 2280 | ||
2181 | codec->spec = spec; | 2281 | codec->spec = spec; |
2182 | spec->num_pins = 14; | 2282 | spec->num_pins = ARRAY_SIZE(stac9205_pin_nids); |
2183 | spec->pin_nids = stac9205_pin_nids; | 2283 | spec->pin_nids = stac9205_pin_nids; |
2184 | spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS, | 2284 | spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS, |
2185 | stac9205_models, | 2285 | stac9205_models, |
@@ -2209,19 +2309,21 @@ static int patch_stac9205(struct hda_codec *codec) | |||
2209 | spec->mixer = stac9205_mixer; | 2309 | spec->mixer = stac9205_mixer; |
2210 | 2310 | ||
2211 | spec->multiout.dac_nids = spec->dac_nids; | 2311 | spec->multiout.dac_nids = spec->dac_nids; |
2312 | |||
2313 | if (spec->board_config == STAC_M43xx) { | ||
2314 | /* Enable SPDIF in/out */ | ||
2315 | stac92xx_set_config_reg(codec, 0x1f, 0x01441030); | ||
2316 | stac92xx_set_config_reg(codec, 0x20, 0x1c410030); | ||
2317 | |||
2318 | gpio_mask = 0x00000007; /* GPIO0-2 */ | ||
2319 | /* GPIO0 High = EAPD, GPIO1 Low = DRM, | ||
2320 | * GPIO2 High = Headphone Mute | ||
2321 | */ | ||
2322 | gpio_data = 0x00000005; | ||
2323 | } else | ||
2324 | gpio_mask = gpio_data = 0x00000001; /* GPIO0 High = EAPD */ | ||
2212 | 2325 | ||
2213 | /* Configure GPIO0 as EAPD output */ | 2326 | stac92xx_enable_gpio_mask(codec, gpio_mask, gpio_data); |
2214 | snd_hda_codec_write(codec, codec->afg, 0, | ||
2215 | AC_VERB_SET_GPIO_DIRECTION, 0x00000001); | ||
2216 | /* Configure GPIO0 as CMOS */ | ||
2217 | snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0x00000000); | ||
2218 | /* Assert GPIO0 high */ | ||
2219 | snd_hda_codec_write(codec, codec->afg, 0, | ||
2220 | AC_VERB_SET_GPIO_DATA, 0x00000001); | ||
2221 | /* Enable GPIO0 */ | ||
2222 | snd_hda_codec_write(codec, codec->afg, 0, | ||
2223 | AC_VERB_SET_GPIO_MASK, 0x00000001); | ||
2224 | |||
2225 | err = stac92xx_parse_auto_config(codec, 0x1f, 0x20); | 2327 | err = stac92xx_parse_auto_config(codec, 0x1f, 0x20); |
2226 | if (!err) { | 2328 | if (!err) { |
2227 | if (spec->board_config < 0) { | 2329 | if (spec->board_config < 0) { |
@@ -2256,8 +2358,8 @@ static struct hda_input_mux vaio_mux = { | |||
2256 | .num_items = 2, | 2358 | .num_items = 2, |
2257 | .items = { | 2359 | .items = { |
2258 | /* { "HP", 0x0 }, */ | 2360 | /* { "HP", 0x0 }, */ |
2259 | { "Line", 0x1 }, | 2361 | { "Mic Jack", 0x1 }, |
2260 | { "Mic", 0x2 }, | 2362 | { "Internal Mic", 0x2 }, |
2261 | { "PCM", 0x3 }, | 2363 | { "PCM", 0x3 }, |
2262 | } | 2364 | } |
2263 | }; | 2365 | }; |
@@ -2268,7 +2370,7 @@ static struct hda_verb vaio_init[] = { | |||
2268 | {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */ | 2370 | {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */ |
2269 | {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */ | 2371 | {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */ |
2270 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */ | 2372 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */ |
2271 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x2}, /* mic-sel: 0a,0d,14,02 */ | 2373 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */ |
2272 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */ | 2374 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */ |
2273 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */ | 2375 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */ |
2274 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */ | 2376 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */ |
@@ -2284,7 +2386,7 @@ static struct hda_verb vaio_ar_init[] = { | |||
2284 | {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */ | 2386 | {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */ |
2285 | /* {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },*/ /* Optical Out */ | 2387 | /* {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },*/ /* Optical Out */ |
2286 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */ | 2388 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */ |
2287 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x2}, /* mic-sel: 0a,0d,14,02 */ | 2389 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */ |
2288 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */ | 2390 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */ |
2289 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */ | 2391 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */ |
2290 | /* {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},*/ /* Optical Out */ | 2392 | /* {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},*/ /* Optical Out */ |
diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c index 690ceb340644..d18a31e188a9 100644 --- a/sound/pci/ice1712/revo.c +++ b/sound/pci/ice1712/revo.c | |||
@@ -186,7 +186,12 @@ static int revo51_i2c_init(struct snd_ice1712 *ice, | |||
186 | #define AK_DAC(xname,xch) { .name = xname, .num_channels = xch } | 186 | #define AK_DAC(xname,xch) { .name = xname, .num_channels = xch } |
187 | 187 | ||
188 | static const struct snd_akm4xxx_dac_channel revo71_front[] = { | 188 | static const struct snd_akm4xxx_dac_channel revo71_front[] = { |
189 | AK_DAC("PCM Playback Volume", 2) | 189 | { |
190 | .name = "PCM Playback Volume", | ||
191 | .num_channels = 2, | ||
192 | /* front channels DAC supports muting */ | ||
193 | .switch_name = "PCM Playback Switch", | ||
194 | }, | ||
190 | }; | 195 | }; |
191 | 196 | ||
192 | static const struct snd_akm4xxx_dac_channel revo71_surround[] = { | 197 | static const struct snd_akm4xxx_dac_channel revo71_surround[] = { |
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c index 03b3a4792f73..c7621bd770a6 100644 --- a/sound/pci/nm256/nm256.c +++ b/sound/pci/nm256/nm256.c | |||
@@ -1533,7 +1533,8 @@ snd_nm256_create(struct snd_card *card, struct pci_dev *pci, | |||
1533 | printk(KERN_ERR " force the driver to load by " | 1533 | printk(KERN_ERR " force the driver to load by " |
1534 | "passing in the module parameter\n"); | 1534 | "passing in the module parameter\n"); |
1535 | printk(KERN_ERR " force_ac97=1\n"); | 1535 | printk(KERN_ERR " force_ac97=1\n"); |
1536 | printk(KERN_ERR " or try sb16 or cs423x drivers instead.\n"); | 1536 | printk(KERN_ERR " or try sb16, opl3sa2, or " |
1537 | "cs423x drivers instead.\n"); | ||
1537 | err = -ENXIO; | 1538 | err = -ENXIO; |
1538 | goto __error; | 1539 | goto __error; |
1539 | } | 1540 | } |
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c index bd7dbd267ed1..2de27405a0bd 100644 --- a/sound/pci/rme9652/rme9652.c +++ b/sound/pci/rme9652/rme9652.c | |||
@@ -406,7 +406,7 @@ static snd_pcm_uframes_t rme9652_hw_pointer(struct snd_rme9652 *rme9652) | |||
406 | } else if (!frag) | 406 | } else if (!frag) |
407 | return 0; | 407 | return 0; |
408 | offset -= rme9652->max_jitter; | 408 | offset -= rme9652->max_jitter; |
409 | if (offset < 0) | 409 | if ((int)offset < 0) |
410 | offset += period_size * 2; | 410 | offset += period_size * 2; |
411 | } else { | 411 | } else { |
412 | if (offset > period_size + rme9652->max_jitter) { | 412 | if (offset > period_size + rme9652->max_jitter) { |
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index 50c9f92cfd1b..6ea09df0c73a 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c | |||
@@ -2098,7 +2098,7 @@ static int snd_via82xx_chip_init(struct via82xx *chip) | |||
2098 | pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval); | 2098 | pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval); |
2099 | if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */ | 2099 | if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */ |
2100 | break; | 2100 | break; |
2101 | schedule_timeout_uninterruptible(1); | 2101 | schedule_timeout(1); |
2102 | } while (time_before(jiffies, end_time)); | 2102 | } while (time_before(jiffies, end_time)); |
2103 | 2103 | ||
2104 | if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY) | 2104 | if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY) |
@@ -2117,7 +2117,7 @@ static int snd_via82xx_chip_init(struct via82xx *chip) | |||
2117 | chip->ac97_secondary = 1; | 2117 | chip->ac97_secondary = 1; |
2118 | goto __ac97_ok2; | 2118 | goto __ac97_ok2; |
2119 | } | 2119 | } |
2120 | schedule_timeout_interruptible(1); | 2120 | schedule_timeout(1); |
2121 | } while (time_before(jiffies, end_time)); | 2121 | } while (time_before(jiffies, end_time)); |
2122 | /* This is ok, the most of motherboards have only one codec */ | 2122 | /* This is ok, the most of motherboards have only one codec */ |
2123 | 2123 | ||
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c index 8cbf8eba4ae9..72425e73abae 100644 --- a/sound/pci/via82xx_modem.c +++ b/sound/pci/via82xx_modem.c | |||
@@ -983,7 +983,7 @@ static int snd_via82xx_chip_init(struct via82xx_modem *chip) | |||
983 | pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval); | 983 | pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval); |
984 | if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */ | 984 | if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */ |
985 | break; | 985 | break; |
986 | schedule_timeout_uninterruptible(1); | 986 | schedule_timeout(1); |
987 | } while (time_before(jiffies, end_time)); | 987 | } while (time_before(jiffies, end_time)); |
988 | 988 | ||
989 | if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY) | 989 | if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY) |
@@ -1001,7 +1001,7 @@ static int snd_via82xx_chip_init(struct via82xx_modem *chip) | |||
1001 | chip->ac97_secondary = 1; | 1001 | chip->ac97_secondary = 1; |
1002 | goto __ac97_ok2; | 1002 | goto __ac97_ok2; |
1003 | } | 1003 | } |
1004 | schedule_timeout_interruptible(1); | 1004 | schedule_timeout(1); |
1005 | } while (time_before(jiffies, end_time)); | 1005 | } while (time_before(jiffies, end_time)); |
1006 | /* This is ok, the most of motherboards have only one codec */ | 1006 | /* This is ok, the most of motherboards have only one codec */ |
1007 | 1007 | ||
diff --git a/sound/ppc/Kconfig b/sound/ppc/Kconfig index a3fb1496e4dc..cacb0b136883 100644 --- a/sound/ppc/Kconfig +++ b/sound/ppc/Kconfig | |||
@@ -33,3 +33,23 @@ config SND_POWERMAC_AUTO_DRC | |||
33 | option. | 33 | option. |
34 | 34 | ||
35 | endmenu | 35 | endmenu |
36 | |||
37 | menu "ALSA PowerPC devices" | ||
38 | depends on SND!=n && ( PPC64 || PPC32 ) | ||
39 | |||
40 | config SND_PS3 | ||
41 | tristate "PS3 Audio support" | ||
42 | depends on SND && PS3_PS3AV | ||
43 | select SND_PCM | ||
44 | default m | ||
45 | help | ||
46 | Say Y here to include support for audio on the PS3 | ||
47 | |||
48 | To compile this driver as a module, choose M here: the module | ||
49 | will be called snd_ps3. | ||
50 | |||
51 | config SND_PS3_DEFAULT_START_DELAY | ||
52 | int "Startup delay time in ms" | ||
53 | depends on SND_PS3 | ||
54 | default "2000" | ||
55 | endmenu | ||
diff --git a/sound/ppc/Makefile b/sound/ppc/Makefile index 4d95c652c8ca..eacee2d0675c 100644 --- a/sound/ppc/Makefile +++ b/sound/ppc/Makefile | |||
@@ -6,4 +6,5 @@ | |||
6 | snd-powermac-objs := powermac.o pmac.o awacs.o burgundy.o daca.o tumbler.o keywest.o beep.o | 6 | snd-powermac-objs := powermac.o pmac.o awacs.o burgundy.o daca.o tumbler.o keywest.o beep.o |
7 | 7 | ||
8 | # Toplevel Module Dependency | 8 | # Toplevel Module Dependency |
9 | obj-$(CONFIG_SND_POWERMAC) += snd-powermac.o | 9 | obj-$(CONFIG_SND_POWERMAC) += snd-powermac.o |
10 | obj-$(CONFIG_SND_PS3) += snd_ps3.o | ||
diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c new file mode 100644 index 000000000000..1aa0b467599f --- /dev/null +++ b/sound/ppc/snd_ps3.c | |||
@@ -0,0 +1,1125 @@ | |||
1 | /* | ||
2 | * Audio support for PS3 | ||
3 | * Copyright (C) 2007 Sony Computer Entertainment Inc. | ||
4 | * All rights reserved. | ||
5 | * Copyright 2006, 2007 Sony Corporation | ||
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 | ||
9 | * as published by the Free Software Foundation; version 2 of the Licence. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <linux/init.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/io.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <sound/driver.h> | ||
26 | #include <sound/core.h> | ||
27 | #include <sound/initval.h> | ||
28 | #include <sound/pcm.h> | ||
29 | #include <sound/asound.h> | ||
30 | #include <sound/memalloc.h> | ||
31 | #include <sound/pcm_params.h> | ||
32 | #include <sound/control.h> | ||
33 | #include <linux/dmapool.h> | ||
34 | #include <linux/dma-mapping.h> | ||
35 | #include <asm/firmware.h> | ||
36 | #include <linux/io.h> | ||
37 | #include <asm/dma.h> | ||
38 | #include <asm/lv1call.h> | ||
39 | #include <asm/ps3.h> | ||
40 | #include <asm/ps3av.h> | ||
41 | |||
42 | #include "snd_ps3_reg.h" | ||
43 | #include "snd_ps3.h" | ||
44 | |||
45 | MODULE_LICENSE("GPL v2"); | ||
46 | MODULE_DESCRIPTION("PS3 sound driver"); | ||
47 | MODULE_AUTHOR("Sony Computer Entertainment Inc."); | ||
48 | |||
49 | /* module entries */ | ||
50 | static int __init snd_ps3_init(void); | ||
51 | static void __exit snd_ps3_exit(void); | ||
52 | |||
53 | /* ALSA snd driver ops */ | ||
54 | static int snd_ps3_pcm_open(struct snd_pcm_substream *substream); | ||
55 | static int snd_ps3_pcm_close(struct snd_pcm_substream *substream); | ||
56 | static int snd_ps3_pcm_prepare(struct snd_pcm_substream *substream); | ||
57 | static int snd_ps3_pcm_trigger(struct snd_pcm_substream *substream, | ||
58 | int cmd); | ||
59 | static snd_pcm_uframes_t snd_ps3_pcm_pointer(struct snd_pcm_substream | ||
60 | *substream); | ||
61 | static int snd_ps3_pcm_hw_params(struct snd_pcm_substream *substream, | ||
62 | struct snd_pcm_hw_params *hw_params); | ||
63 | static int snd_ps3_pcm_hw_free(struct snd_pcm_substream *substream); | ||
64 | |||
65 | |||
66 | /* ps3_system_bus_driver entries */ | ||
67 | static int __init snd_ps3_driver_probe(struct ps3_system_bus_device *dev); | ||
68 | static int snd_ps3_driver_remove(struct ps3_system_bus_device *dev); | ||
69 | |||
70 | /* address setup */ | ||
71 | static int snd_ps3_map_mmio(void); | ||
72 | static void snd_ps3_unmap_mmio(void); | ||
73 | static int snd_ps3_allocate_irq(void); | ||
74 | static void snd_ps3_free_irq(void); | ||
75 | static void snd_ps3_audio_set_base_addr(uint64_t ioaddr_start); | ||
76 | |||
77 | /* interrupt handler */ | ||
78 | static irqreturn_t snd_ps3_interrupt(int irq, void *dev_id); | ||
79 | |||
80 | |||
81 | /* set sampling rate/format */ | ||
82 | static int snd_ps3_set_avsetting(struct snd_pcm_substream *substream); | ||
83 | /* take effect parameter change */ | ||
84 | static int snd_ps3_change_avsetting(struct snd_ps3_card_info *card); | ||
85 | /* initialize avsetting and take it effect */ | ||
86 | static int snd_ps3_init_avsetting(struct snd_ps3_card_info *card); | ||
87 | /* setup dma */ | ||
88 | static int snd_ps3_program_dma(struct snd_ps3_card_info *card, | ||
89 | enum snd_ps3_dma_filltype filltype); | ||
90 | static void snd_ps3_wait_for_dma_stop(struct snd_ps3_card_info *card); | ||
91 | |||
92 | static dma_addr_t v_to_bus(struct snd_ps3_card_info *, void *vaddr, int ch); | ||
93 | |||
94 | |||
95 | module_init(snd_ps3_init); | ||
96 | module_exit(snd_ps3_exit); | ||
97 | |||
98 | /* | ||
99 | * global | ||
100 | */ | ||
101 | static struct snd_ps3_card_info the_card; | ||
102 | |||
103 | static int snd_ps3_start_delay = CONFIG_SND_PS3_DEFAULT_START_DELAY; | ||
104 | |||
105 | module_param_named(start_delay, snd_ps3_start_delay, uint, 0644); | ||
106 | MODULE_PARM_DESC(start_delay, "time to insert silent data in milisec"); | ||
107 | |||
108 | static int index = SNDRV_DEFAULT_IDX1; | ||
109 | static char *id = SNDRV_DEFAULT_STR1; | ||
110 | |||
111 | module_param(index, int, 0444); | ||
112 | MODULE_PARM_DESC(index, "Index value for PS3 soundchip."); | ||
113 | module_param(id, charp, 0444); | ||
114 | MODULE_PARM_DESC(id, "ID string for PS3 soundchip."); | ||
115 | |||
116 | |||
117 | /* | ||
118 | * PS3 audio register access | ||
119 | */ | ||
120 | static inline u32 read_reg(unsigned int reg) | ||
121 | { | ||
122 | return in_be32(the_card.mapped_mmio_vaddr + reg); | ||
123 | } | ||
124 | static inline void write_reg(unsigned int reg, u32 val) | ||
125 | { | ||
126 | out_be32(the_card.mapped_mmio_vaddr + reg, val); | ||
127 | } | ||
128 | static inline void update_reg(unsigned int reg, u32 or_val) | ||
129 | { | ||
130 | u32 newval = read_reg(reg) | or_val; | ||
131 | write_reg(reg, newval); | ||
132 | } | ||
133 | static inline void update_mask_reg(unsigned int reg, u32 mask, u32 or_val) | ||
134 | { | ||
135 | u32 newval = (read_reg(reg) & mask) | or_val; | ||
136 | write_reg(reg, newval); | ||
137 | } | ||
138 | |||
139 | /* | ||
140 | * ALSA defs | ||
141 | */ | ||
142 | const static struct snd_pcm_hardware snd_ps3_pcm_hw = { | ||
143 | .info = (SNDRV_PCM_INFO_MMAP | | ||
144 | SNDRV_PCM_INFO_NONINTERLEAVED | | ||
145 | SNDRV_PCM_INFO_MMAP_VALID), | ||
146 | .formats = (SNDRV_PCM_FMTBIT_S16_BE | | ||
147 | SNDRV_PCM_FMTBIT_S24_BE), | ||
148 | .rates = (SNDRV_PCM_RATE_44100 | | ||
149 | SNDRV_PCM_RATE_48000 | | ||
150 | SNDRV_PCM_RATE_88200 | | ||
151 | SNDRV_PCM_RATE_96000), | ||
152 | .rate_min = 44100, | ||
153 | .rate_max = 96000, | ||
154 | |||
155 | .channels_min = 2, /* stereo only */ | ||
156 | .channels_max = 2, | ||
157 | |||
158 | .buffer_bytes_max = PS3_AUDIO_FIFO_SIZE * 64, | ||
159 | |||
160 | /* interrupt by four stages */ | ||
161 | .period_bytes_min = PS3_AUDIO_FIFO_STAGE_SIZE * 4, | ||
162 | .period_bytes_max = PS3_AUDIO_FIFO_STAGE_SIZE * 4, | ||
163 | |||
164 | .periods_min = 16, | ||
165 | .periods_max = 32, /* buffer_size_max/ period_bytes_max */ | ||
166 | |||
167 | .fifo_size = PS3_AUDIO_FIFO_SIZE | ||
168 | }; | ||
169 | |||
170 | static struct snd_pcm_ops snd_ps3_pcm_spdif_ops = | ||
171 | { | ||
172 | .open = snd_ps3_pcm_open, | ||
173 | .close = snd_ps3_pcm_close, | ||
174 | .prepare = snd_ps3_pcm_prepare, | ||
175 | .ioctl = snd_pcm_lib_ioctl, | ||
176 | .trigger = snd_ps3_pcm_trigger, | ||
177 | .pointer = snd_ps3_pcm_pointer, | ||
178 | .hw_params = snd_ps3_pcm_hw_params, | ||
179 | .hw_free = snd_ps3_pcm_hw_free | ||
180 | }; | ||
181 | |||
182 | static int snd_ps3_verify_dma_stop(struct snd_ps3_card_info *card, | ||
183 | int count, int force_stop) | ||
184 | { | ||
185 | int dma_ch, done, retries, stop_forced = 0; | ||
186 | uint32_t status; | ||
187 | |||
188 | for (dma_ch = 0; dma_ch < 8; dma_ch ++) { | ||
189 | retries = count; | ||
190 | do { | ||
191 | status = read_reg(PS3_AUDIO_KICK(dma_ch)) & | ||
192 | PS3_AUDIO_KICK_STATUS_MASK; | ||
193 | switch (status) { | ||
194 | case PS3_AUDIO_KICK_STATUS_DONE: | ||
195 | case PS3_AUDIO_KICK_STATUS_NOTIFY: | ||
196 | case PS3_AUDIO_KICK_STATUS_CLEAR: | ||
197 | case PS3_AUDIO_KICK_STATUS_ERROR: | ||
198 | done = 1; | ||
199 | break; | ||
200 | default: | ||
201 | done = 0; | ||
202 | udelay(10); | ||
203 | } | ||
204 | } while (!done && --retries); | ||
205 | if (!retries && force_stop) { | ||
206 | pr_info("%s: DMA ch %d is not stopped.", | ||
207 | __func__, dma_ch); | ||
208 | /* last resort. force to stop dma. | ||
209 | * NOTE: this cause DMA done interrupts | ||
210 | */ | ||
211 | update_reg(PS3_AUDIO_CONFIG, PS3_AUDIO_CONFIG_CLEAR); | ||
212 | stop_forced = 1; | ||
213 | } | ||
214 | } | ||
215 | return stop_forced; | ||
216 | } | ||
217 | |||
218 | /* | ||
219 | * wait for all dma is done. | ||
220 | * NOTE: caller should reset card->running before call. | ||
221 | * If not, the interrupt handler will re-start DMA, | ||
222 | * then DMA is never stopped. | ||
223 | */ | ||
224 | static void snd_ps3_wait_for_dma_stop(struct snd_ps3_card_info *card) | ||
225 | { | ||
226 | int stop_forced; | ||
227 | /* | ||
228 | * wait for the last dma is done | ||
229 | */ | ||
230 | |||
231 | /* | ||
232 | * expected maximum DMA done time is 5.7ms + something (DMA itself). | ||
233 | * 5.7ms is from 16bit/sample 2ch 44.1Khz; the time next | ||
234 | * DMA kick event would occur. | ||
235 | */ | ||
236 | stop_forced = snd_ps3_verify_dma_stop(card, 700, 1); | ||
237 | |||
238 | /* | ||
239 | * clear outstanding interrupts. | ||
240 | */ | ||
241 | update_reg(PS3_AUDIO_INTR_0, 0); | ||
242 | update_reg(PS3_AUDIO_AX_IS, 0); | ||
243 | |||
244 | /* | ||
245 | *revert CLEAR bit since it will not reset automatically after DMA stop | ||
246 | */ | ||
247 | if (stop_forced) | ||
248 | update_mask_reg(PS3_AUDIO_CONFIG, ~PS3_AUDIO_CONFIG_CLEAR, 0); | ||
249 | /* ensure the hardware sees changes */ | ||
250 | wmb(); | ||
251 | } | ||
252 | |||
253 | static void snd_ps3_kick_dma(struct snd_ps3_card_info *card) | ||
254 | { | ||
255 | |||
256 | update_reg(PS3_AUDIO_KICK(0), PS3_AUDIO_KICK_REQUEST); | ||
257 | /* ensure the hardware sees the change */ | ||
258 | wmb(); | ||
259 | } | ||
260 | |||
261 | /* | ||
262 | * convert virtual addr to ioif bus addr. | ||
263 | */ | ||
264 | static dma_addr_t v_to_bus(struct snd_ps3_card_info *card, | ||
265 | void * paddr, | ||
266 | int ch) | ||
267 | { | ||
268 | return card->dma_start_bus_addr[ch] + | ||
269 | (paddr - card->dma_start_vaddr[ch]); | ||
270 | }; | ||
271 | |||
272 | |||
273 | /* | ||
274 | * increment ring buffer pointer. | ||
275 | * NOTE: caller must hold write spinlock | ||
276 | */ | ||
277 | static void snd_ps3_bump_buffer(struct snd_ps3_card_info *card, | ||
278 | enum snd_ps3_ch ch, size_t byte_count, | ||
279 | int stage) | ||
280 | { | ||
281 | if (!stage) | ||
282 | card->dma_last_transfer_vaddr[ch] = | ||
283 | card->dma_next_transfer_vaddr[ch]; | ||
284 | card->dma_next_transfer_vaddr[ch] += byte_count; | ||
285 | if ((card->dma_start_vaddr[ch] + (card->dma_buffer_size / 2)) <= | ||
286 | card->dma_next_transfer_vaddr[ch]) { | ||
287 | card->dma_next_transfer_vaddr[ch] = card->dma_start_vaddr[ch]; | ||
288 | } | ||
289 | } | ||
290 | /* | ||
291 | * setup dmac to send data to audio and attenuate samples on the ring buffer | ||
292 | */ | ||
293 | static int snd_ps3_program_dma(struct snd_ps3_card_info *card, | ||
294 | enum snd_ps3_dma_filltype filltype) | ||
295 | { | ||
296 | /* this dmac does not support over 4G */ | ||
297 | uint32_t dma_addr; | ||
298 | int fill_stages, dma_ch, stage; | ||
299 | enum snd_ps3_ch ch; | ||
300 | uint32_t ch0_kick_event = 0; /* initialize to mute gcc */ | ||
301 | void *start_vaddr; | ||
302 | unsigned long irqsave; | ||
303 | int silent = 0; | ||
304 | |||
305 | switch (filltype) { | ||
306 | case SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL: | ||
307 | silent = 1; | ||
308 | /* intentionally fall thru */ | ||
309 | case SND_PS3_DMA_FILLTYPE_FIRSTFILL: | ||
310 | ch0_kick_event = PS3_AUDIO_KICK_EVENT_ALWAYS; | ||
311 | break; | ||
312 | |||
313 | case SND_PS3_DMA_FILLTYPE_SILENT_RUNNING: | ||
314 | silent = 1; | ||
315 | /* intentionally fall thru */ | ||
316 | case SND_PS3_DMA_FILLTYPE_RUNNING: | ||
317 | ch0_kick_event = PS3_AUDIO_KICK_EVENT_SERIALOUT0_EMPTY; | ||
318 | break; | ||
319 | } | ||
320 | |||
321 | snd_ps3_verify_dma_stop(card, 700, 0); | ||
322 | fill_stages = 4; | ||
323 | spin_lock_irqsave(&card->dma_lock, irqsave); | ||
324 | for (ch = 0; ch < 2; ch++) { | ||
325 | start_vaddr = card->dma_next_transfer_vaddr[0]; | ||
326 | for (stage = 0; stage < fill_stages; stage ++) { | ||
327 | dma_ch = stage * 2 + ch; | ||
328 | if (silent) | ||
329 | dma_addr = card->null_buffer_start_dma_addr; | ||
330 | else | ||
331 | dma_addr = | ||
332 | v_to_bus(card, | ||
333 | card->dma_next_transfer_vaddr[ch], | ||
334 | ch); | ||
335 | |||
336 | write_reg(PS3_AUDIO_SOURCE(dma_ch), | ||
337 | (PS3_AUDIO_SOURCE_TARGET_SYSTEM_MEMORY | | ||
338 | dma_addr)); | ||
339 | |||
340 | /* dst: fixed to 3wire#0 */ | ||
341 | if (ch == 0) | ||
342 | write_reg(PS3_AUDIO_DEST(dma_ch), | ||
343 | (PS3_AUDIO_DEST_TARGET_AUDIOFIFO | | ||
344 | PS3_AUDIO_AO_3W_LDATA(0))); | ||
345 | else | ||
346 | write_reg(PS3_AUDIO_DEST(dma_ch), | ||
347 | (PS3_AUDIO_DEST_TARGET_AUDIOFIFO | | ||
348 | PS3_AUDIO_AO_3W_RDATA(0))); | ||
349 | |||
350 | /* count always 1 DMA block (1/2 stage = 128 bytes) */ | ||
351 | write_reg(PS3_AUDIO_DMASIZE(dma_ch), 0); | ||
352 | /* bump pointer if needed */ | ||
353 | if (!silent) | ||
354 | snd_ps3_bump_buffer(card, ch, | ||
355 | PS3_AUDIO_DMAC_BLOCK_SIZE, | ||
356 | stage); | ||
357 | |||
358 | /* kick event */ | ||
359 | if (dma_ch == 0) | ||
360 | write_reg(PS3_AUDIO_KICK(dma_ch), | ||
361 | ch0_kick_event); | ||
362 | else | ||
363 | write_reg(PS3_AUDIO_KICK(dma_ch), | ||
364 | PS3_AUDIO_KICK_EVENT_AUDIO_DMA(dma_ch | ||
365 | - 1) | | ||
366 | PS3_AUDIO_KICK_REQUEST); | ||
367 | } | ||
368 | } | ||
369 | /* ensure the hardware sees the change */ | ||
370 | wmb(); | ||
371 | spin_unlock_irqrestore(&card->dma_lock, irqsave); | ||
372 | |||
373 | return 0; | ||
374 | } | ||
375 | |||
376 | /* | ||
377 | * audio mute on/off | ||
378 | * mute_on : 0 output enabled | ||
379 | * 1 mute | ||
380 | */ | ||
381 | static int snd_ps3_mute(int mute_on) | ||
382 | { | ||
383 | return ps3av_audio_mute(mute_on); | ||
384 | } | ||
385 | |||
386 | /* | ||
387 | * PCM operators | ||
388 | */ | ||
389 | static int snd_ps3_pcm_open(struct snd_pcm_substream *substream) | ||
390 | { | ||
391 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
392 | struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream); | ||
393 | int pcm_index; | ||
394 | |||
395 | pcm_index = substream->pcm->device; | ||
396 | /* to retrieve substream/runtime in interrupt handler */ | ||
397 | card->substream = substream; | ||
398 | |||
399 | runtime->hw = snd_ps3_pcm_hw; | ||
400 | |||
401 | card->start_delay = snd_ps3_start_delay; | ||
402 | |||
403 | /* mute off */ | ||
404 | snd_ps3_mute(0); /* this function sleep */ | ||
405 | |||
406 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, | ||
407 | PS3_AUDIO_FIFO_STAGE_SIZE * 4 * 2); | ||
408 | return 0; | ||
409 | }; | ||
410 | |||
411 | static int snd_ps3_pcm_hw_params(struct snd_pcm_substream *substream, | ||
412 | struct snd_pcm_hw_params *hw_params) | ||
413 | { | ||
414 | size_t size; | ||
415 | |||
416 | /* alloc transport buffer */ | ||
417 | size = params_buffer_bytes(hw_params); | ||
418 | snd_pcm_lib_malloc_pages(substream, size); | ||
419 | return 0; | ||
420 | }; | ||
421 | |||
422 | static int snd_ps3_delay_to_bytes(struct snd_pcm_substream *substream, | ||
423 | unsigned int delay_ms) | ||
424 | { | ||
425 | int ret; | ||
426 | int rate ; | ||
427 | |||
428 | rate = substream->runtime->rate; | ||
429 | ret = snd_pcm_format_size(substream->runtime->format, | ||
430 | rate * delay_ms / 1000) | ||
431 | * substream->runtime->channels; | ||
432 | |||
433 | pr_debug(KERN_ERR "%s: time=%d rate=%d bytes=%ld, frames=%d, ret=%d\n", | ||
434 | __func__, | ||
435 | delay_ms, | ||
436 | rate, | ||
437 | snd_pcm_format_size(substream->runtime->format, rate), | ||
438 | rate * delay_ms / 1000, | ||
439 | ret); | ||
440 | |||
441 | return ret; | ||
442 | }; | ||
443 | |||
444 | static int snd_ps3_pcm_prepare(struct snd_pcm_substream *substream) | ||
445 | { | ||
446 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
447 | struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream); | ||
448 | unsigned long irqsave; | ||
449 | |||
450 | if (!snd_ps3_set_avsetting(substream)) { | ||
451 | /* some parameter changed */ | ||
452 | write_reg(PS3_AUDIO_AX_IE, | ||
453 | PS3_AUDIO_AX_IE_ASOBEIE(0) | | ||
454 | PS3_AUDIO_AX_IE_ASOBUIE(0)); | ||
455 | /* | ||
456 | * let SPDIF device re-lock with SPDIF signal, | ||
457 | * start with some silence | ||
458 | */ | ||
459 | card->silent = snd_ps3_delay_to_bytes(substream, | ||
460 | card->start_delay) / | ||
461 | (PS3_AUDIO_FIFO_STAGE_SIZE * 4); /* every 4 times */ | ||
462 | } | ||
463 | |||
464 | /* restart ring buffer pointer */ | ||
465 | spin_lock_irqsave(&card->dma_lock, irqsave); | ||
466 | { | ||
467 | card->dma_buffer_size = runtime->dma_bytes; | ||
468 | |||
469 | card->dma_last_transfer_vaddr[SND_PS3_CH_L] = | ||
470 | card->dma_next_transfer_vaddr[SND_PS3_CH_L] = | ||
471 | card->dma_start_vaddr[SND_PS3_CH_L] = | ||
472 | runtime->dma_area; | ||
473 | card->dma_start_bus_addr[SND_PS3_CH_L] = runtime->dma_addr; | ||
474 | |||
475 | card->dma_last_transfer_vaddr[SND_PS3_CH_R] = | ||
476 | card->dma_next_transfer_vaddr[SND_PS3_CH_R] = | ||
477 | card->dma_start_vaddr[SND_PS3_CH_R] = | ||
478 | runtime->dma_area + (runtime->dma_bytes / 2); | ||
479 | card->dma_start_bus_addr[SND_PS3_CH_R] = | ||
480 | runtime->dma_addr + (runtime->dma_bytes / 2); | ||
481 | |||
482 | pr_debug("%s: vaddr=%p bus=%#lx\n", __func__, | ||
483 | card->dma_start_vaddr[SND_PS3_CH_L], | ||
484 | card->dma_start_bus_addr[SND_PS3_CH_L]); | ||
485 | |||
486 | } | ||
487 | spin_unlock_irqrestore(&card->dma_lock, irqsave); | ||
488 | |||
489 | /* ensure the hardware sees the change */ | ||
490 | mb(); | ||
491 | |||
492 | return 0; | ||
493 | }; | ||
494 | |||
495 | static int snd_ps3_pcm_trigger(struct snd_pcm_substream *substream, | ||
496 | int cmd) | ||
497 | { | ||
498 | struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream); | ||
499 | int ret = 0; | ||
500 | |||
501 | switch (cmd) { | ||
502 | case SNDRV_PCM_TRIGGER_START: | ||
503 | /* clear outstanding interrupts */ | ||
504 | update_reg(PS3_AUDIO_AX_IS, 0); | ||
505 | |||
506 | spin_lock(&card->dma_lock); | ||
507 | { | ||
508 | card->running = 1; | ||
509 | } | ||
510 | spin_unlock(&card->dma_lock); | ||
511 | |||
512 | snd_ps3_program_dma(card, | ||
513 | SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL); | ||
514 | snd_ps3_kick_dma(card); | ||
515 | while (read_reg(PS3_AUDIO_KICK(7)) & | ||
516 | PS3_AUDIO_KICK_STATUS_MASK) { | ||
517 | udelay(1); | ||
518 | } | ||
519 | snd_ps3_program_dma(card, SND_PS3_DMA_FILLTYPE_SILENT_RUNNING); | ||
520 | snd_ps3_kick_dma(card); | ||
521 | break; | ||
522 | |||
523 | case SNDRV_PCM_TRIGGER_STOP: | ||
524 | spin_lock(&card->dma_lock); | ||
525 | { | ||
526 | card->running = 0; | ||
527 | } | ||
528 | spin_unlock(&card->dma_lock); | ||
529 | snd_ps3_wait_for_dma_stop(card); | ||
530 | break; | ||
531 | default: | ||
532 | break; | ||
533 | |||
534 | } | ||
535 | |||
536 | return ret; | ||
537 | }; | ||
538 | |||
539 | /* | ||
540 | * report current pointer | ||
541 | */ | ||
542 | static snd_pcm_uframes_t snd_ps3_pcm_pointer( | ||
543 | struct snd_pcm_substream *substream) | ||
544 | { | ||
545 | struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream); | ||
546 | size_t bytes; | ||
547 | snd_pcm_uframes_t ret; | ||
548 | |||
549 | spin_lock(&card->dma_lock); | ||
550 | { | ||
551 | bytes = (size_t)(card->dma_last_transfer_vaddr[SND_PS3_CH_L] - | ||
552 | card->dma_start_vaddr[SND_PS3_CH_L]); | ||
553 | } | ||
554 | spin_unlock(&card->dma_lock); | ||
555 | |||
556 | ret = bytes_to_frames(substream->runtime, bytes * 2); | ||
557 | |||
558 | return ret; | ||
559 | }; | ||
560 | |||
561 | static int snd_ps3_pcm_hw_free(struct snd_pcm_substream *substream) | ||
562 | { | ||
563 | int ret; | ||
564 | ret = snd_pcm_lib_free_pages(substream); | ||
565 | return ret; | ||
566 | }; | ||
567 | |||
568 | static int snd_ps3_pcm_close(struct snd_pcm_substream *substream) | ||
569 | { | ||
570 | /* mute on */ | ||
571 | snd_ps3_mute(1); | ||
572 | return 0; | ||
573 | }; | ||
574 | |||
575 | static void snd_ps3_audio_fixup(struct snd_ps3_card_info *card) | ||
576 | { | ||
577 | /* | ||
578 | * avsetting driver seems to never change the followings | ||
579 | * so, init them here once | ||
580 | */ | ||
581 | |||
582 | /* no dma interrupt needed */ | ||
583 | write_reg(PS3_AUDIO_INTR_EN_0, 0); | ||
584 | |||
585 | /* use every 4 buffer empty interrupt */ | ||
586 | update_mask_reg(PS3_AUDIO_AX_IC, | ||
587 | PS3_AUDIO_AX_IC_AASOIMD_MASK, | ||
588 | PS3_AUDIO_AX_IC_AASOIMD_EVERY4); | ||
589 | |||
590 | /* enable 3wire clocks */ | ||
591 | update_mask_reg(PS3_AUDIO_AO_3WMCTRL, | ||
592 | ~(PS3_AUDIO_AO_3WMCTRL_ASOBCLKD_DISABLED | | ||
593 | PS3_AUDIO_AO_3WMCTRL_ASOLRCKD_DISABLED), | ||
594 | 0); | ||
595 | update_reg(PS3_AUDIO_AO_3WMCTRL, | ||
596 | PS3_AUDIO_AO_3WMCTRL_ASOPLRCK_DEFAULT); | ||
597 | } | ||
598 | |||
599 | /* | ||
600 | * av setting | ||
601 | * NOTE: calling this function may generate audio interrupt. | ||
602 | */ | ||
603 | static int snd_ps3_change_avsetting(struct snd_ps3_card_info *card) | ||
604 | { | ||
605 | int ret, retries, i; | ||
606 | pr_debug("%s: start\n", __func__); | ||
607 | |||
608 | ret = ps3av_set_audio_mode(card->avs.avs_audio_ch, | ||
609 | card->avs.avs_audio_rate, | ||
610 | card->avs.avs_audio_width, | ||
611 | card->avs.avs_audio_format, | ||
612 | card->avs.avs_audio_source); | ||
613 | /* | ||
614 | * Reset the following unwanted settings: | ||
615 | */ | ||
616 | |||
617 | /* disable all 3wire buffers */ | ||
618 | update_mask_reg(PS3_AUDIO_AO_3WMCTRL, | ||
619 | ~(PS3_AUDIO_AO_3WMCTRL_ASOEN(0) | | ||
620 | PS3_AUDIO_AO_3WMCTRL_ASOEN(1) | | ||
621 | PS3_AUDIO_AO_3WMCTRL_ASOEN(2) | | ||
622 | PS3_AUDIO_AO_3WMCTRL_ASOEN(3)), | ||
623 | 0); | ||
624 | wmb(); /* ensure the hardware sees the change */ | ||
625 | /* wait for actually stopped */ | ||
626 | retries = 1000; | ||
627 | while ((read_reg(PS3_AUDIO_AO_3WMCTRL) & | ||
628 | (PS3_AUDIO_AO_3WMCTRL_ASORUN(0) | | ||
629 | PS3_AUDIO_AO_3WMCTRL_ASORUN(1) | | ||
630 | PS3_AUDIO_AO_3WMCTRL_ASORUN(2) | | ||
631 | PS3_AUDIO_AO_3WMCTRL_ASORUN(3))) && | ||
632 | --retries) { | ||
633 | udelay(1); | ||
634 | } | ||
635 | |||
636 | /* reset buffer pointer */ | ||
637 | for (i = 0; i < 4; i++) { | ||
638 | update_reg(PS3_AUDIO_AO_3WCTRL(i), | ||
639 | PS3_AUDIO_AO_3WCTRL_ASOBRST_RESET); | ||
640 | udelay(10); | ||
641 | } | ||
642 | wmb(); /* ensure the hardware actually start resetting */ | ||
643 | |||
644 | /* enable 3wire#0 buffer */ | ||
645 | update_reg(PS3_AUDIO_AO_3WMCTRL, PS3_AUDIO_AO_3WMCTRL_ASOEN(0)); | ||
646 | |||
647 | |||
648 | /* In 24bit mode,ALSA inserts a zero byte at first byte of per sample */ | ||
649 | update_mask_reg(PS3_AUDIO_AO_3WCTRL(0), | ||
650 | ~PS3_AUDIO_AO_3WCTRL_ASODF, | ||
651 | PS3_AUDIO_AO_3WCTRL_ASODF_LSB); | ||
652 | update_mask_reg(PS3_AUDIO_AO_SPDCTRL(0), | ||
653 | ~PS3_AUDIO_AO_SPDCTRL_SPODF, | ||
654 | PS3_AUDIO_AO_SPDCTRL_SPODF_LSB); | ||
655 | /* ensure all the setting above is written back to register */ | ||
656 | wmb(); | ||
657 | /* avsetting driver altered AX_IE, caller must reset it if you want */ | ||
658 | pr_debug("%s: end\n", __func__); | ||
659 | return ret; | ||
660 | } | ||
661 | |||
662 | static int snd_ps3_init_avsetting(struct snd_ps3_card_info *card) | ||
663 | { | ||
664 | int ret; | ||
665 | pr_debug("%s: start\n", __func__); | ||
666 | card->avs.avs_audio_ch = PS3AV_CMD_AUDIO_NUM_OF_CH_2; | ||
667 | card->avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_48K; | ||
668 | card->avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_16; | ||
669 | card->avs.avs_audio_format = PS3AV_CMD_AUDIO_FORMAT_PCM; | ||
670 | card->avs.avs_audio_source = PS3AV_CMD_AUDIO_SOURCE_SERIAL; | ||
671 | |||
672 | ret = snd_ps3_change_avsetting(card); | ||
673 | |||
674 | snd_ps3_audio_fixup(card); | ||
675 | |||
676 | /* to start to generate SPDIF signal, fill data */ | ||
677 | snd_ps3_program_dma(card, SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL); | ||
678 | snd_ps3_kick_dma(card); | ||
679 | pr_debug("%s: end\n", __func__); | ||
680 | return ret; | ||
681 | } | ||
682 | |||
683 | /* | ||
684 | * set sampling rate according to the substream | ||
685 | */ | ||
686 | static int snd_ps3_set_avsetting(struct snd_pcm_substream *substream) | ||
687 | { | ||
688 | struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream); | ||
689 | struct snd_ps3_avsetting_info avs; | ||
690 | |||
691 | avs = card->avs; | ||
692 | |||
693 | pr_debug("%s: called freq=%d width=%d\n", __func__, | ||
694 | substream->runtime->rate, | ||
695 | snd_pcm_format_width(substream->runtime->format)); | ||
696 | |||
697 | pr_debug("%s: before freq=%d width=%d\n", __func__, | ||
698 | card->avs.avs_audio_rate, card->avs.avs_audio_width); | ||
699 | |||
700 | /* sample rate */ | ||
701 | switch (substream->runtime->rate) { | ||
702 | case 44100: | ||
703 | avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_44K; | ||
704 | break; | ||
705 | case 48000: | ||
706 | avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_48K; | ||
707 | break; | ||
708 | case 88200: | ||
709 | avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_88K; | ||
710 | break; | ||
711 | case 96000: | ||
712 | avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_96K; | ||
713 | break; | ||
714 | default: | ||
715 | pr_info("%s: invalid rate %d\n", __func__, | ||
716 | substream->runtime->rate); | ||
717 | return 1; | ||
718 | } | ||
719 | |||
720 | /* width */ | ||
721 | switch (snd_pcm_format_width(substream->runtime->format)) { | ||
722 | case 16: | ||
723 | avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_16; | ||
724 | break; | ||
725 | case 24: | ||
726 | avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_24; | ||
727 | break; | ||
728 | default: | ||
729 | pr_info("%s: invalid width %d\n", __func__, | ||
730 | snd_pcm_format_width(substream->runtime->format)); | ||
731 | return 1; | ||
732 | } | ||
733 | |||
734 | if ((card->avs.avs_audio_width != avs.avs_audio_width) || | ||
735 | (card->avs.avs_audio_rate != avs.avs_audio_rate)) { | ||
736 | card->avs = avs; | ||
737 | snd_ps3_change_avsetting(card); | ||
738 | |||
739 | pr_debug("%s: after freq=%d width=%d\n", __func__, | ||
740 | card->avs.avs_audio_rate, card->avs.avs_audio_width); | ||
741 | |||
742 | return 0; | ||
743 | } else | ||
744 | return 1; | ||
745 | } | ||
746 | |||
747 | |||
748 | |||
749 | static int snd_ps3_map_mmio(void) | ||
750 | { | ||
751 | the_card.mapped_mmio_vaddr = | ||
752 | ioremap(the_card.ps3_dev->m_region->bus_addr, | ||
753 | the_card.ps3_dev->m_region->len); | ||
754 | |||
755 | if (!the_card.mapped_mmio_vaddr) { | ||
756 | pr_info("%s: ioremap 0 failed p=%#lx l=%#lx \n", | ||
757 | __func__, the_card.ps3_dev->m_region->lpar_addr, | ||
758 | the_card.ps3_dev->m_region->len); | ||
759 | return -ENXIO; | ||
760 | } | ||
761 | |||
762 | return 0; | ||
763 | }; | ||
764 | |||
765 | static void snd_ps3_unmap_mmio(void) | ||
766 | { | ||
767 | iounmap(the_card.mapped_mmio_vaddr); | ||
768 | the_card.mapped_mmio_vaddr = NULL; | ||
769 | } | ||
770 | |||
771 | static int snd_ps3_allocate_irq(void) | ||
772 | { | ||
773 | int ret; | ||
774 | u64 lpar_addr, lpar_size; | ||
775 | u64 __iomem *mapped; | ||
776 | |||
777 | /* FIXME: move this to device_init (H/W probe) */ | ||
778 | |||
779 | /* get irq outlet */ | ||
780 | ret = lv1_gpu_device_map(1, &lpar_addr, &lpar_size); | ||
781 | if (ret) { | ||
782 | pr_info("%s: device map 1 failed %d\n", __func__, | ||
783 | ret); | ||
784 | return -ENXIO; | ||
785 | } | ||
786 | |||
787 | mapped = ioremap(lpar_addr, lpar_size); | ||
788 | if (!mapped) { | ||
789 | pr_info("%s: ioremap 1 failed \n", __func__); | ||
790 | return -ENXIO; | ||
791 | } | ||
792 | |||
793 | the_card.audio_irq_outlet = in_be64(mapped); | ||
794 | |||
795 | iounmap(mapped); | ||
796 | ret = lv1_gpu_device_unmap(1); | ||
797 | if (ret) | ||
798 | pr_info("%s: unmap 1 failed\n", __func__); | ||
799 | |||
800 | /* irq */ | ||
801 | ret = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, | ||
802 | the_card.audio_irq_outlet, | ||
803 | &the_card.irq_no); | ||
804 | if (ret) { | ||
805 | pr_info("%s:ps3_alloc_irq failed (%d)\n", __func__, ret); | ||
806 | return ret; | ||
807 | } | ||
808 | |||
809 | ret = request_irq(the_card.irq_no, snd_ps3_interrupt, IRQF_DISABLED, | ||
810 | SND_PS3_DRIVER_NAME, &the_card); | ||
811 | if (ret) { | ||
812 | pr_info("%s: request_irq failed (%d)\n", __func__, ret); | ||
813 | goto cleanup_irq; | ||
814 | } | ||
815 | |||
816 | return 0; | ||
817 | |||
818 | cleanup_irq: | ||
819 | ps3_irq_plug_destroy(the_card.irq_no); | ||
820 | return ret; | ||
821 | }; | ||
822 | |||
823 | static void snd_ps3_free_irq(void) | ||
824 | { | ||
825 | free_irq(the_card.irq_no, &the_card); | ||
826 | ps3_irq_plug_destroy(the_card.irq_no); | ||
827 | } | ||
828 | |||
829 | static void snd_ps3_audio_set_base_addr(uint64_t ioaddr_start) | ||
830 | { | ||
831 | uint64_t val; | ||
832 | int ret; | ||
833 | |||
834 | val = (ioaddr_start & (0x0fUL << 32)) >> (32 - 20) | | ||
835 | (0x03UL << 24) | | ||
836 | (0x0fUL << 12) | | ||
837 | (PS3_AUDIO_IOID); | ||
838 | |||
839 | ret = lv1_gpu_attribute(0x100, 0x007, val, 0, 0); | ||
840 | if (ret) | ||
841 | pr_info("%s: gpu_attribute failed %d\n", __func__, | ||
842 | ret); | ||
843 | } | ||
844 | |||
845 | static int __init snd_ps3_driver_probe(struct ps3_system_bus_device *dev) | ||
846 | { | ||
847 | int ret; | ||
848 | u64 lpar_addr, lpar_size; | ||
849 | |||
850 | BUG_ON(!firmware_has_feature(FW_FEATURE_PS3_LV1)); | ||
851 | BUG_ON(dev->match_id != PS3_MATCH_ID_SOUND); | ||
852 | |||
853 | the_card.ps3_dev = dev; | ||
854 | |||
855 | ret = ps3_open_hv_device(dev); | ||
856 | |||
857 | if (ret) | ||
858 | return -ENXIO; | ||
859 | |||
860 | /* setup MMIO */ | ||
861 | ret = lv1_gpu_device_map(2, &lpar_addr, &lpar_size); | ||
862 | if (ret) { | ||
863 | pr_info("%s: device map 2 failed %d\n", __func__, ret); | ||
864 | goto clean_open; | ||
865 | } | ||
866 | ps3_mmio_region_init(dev, dev->m_region, lpar_addr, lpar_size, | ||
867 | PAGE_SHIFT); | ||
868 | |||
869 | ret = snd_ps3_map_mmio(); | ||
870 | if (ret) | ||
871 | goto clean_dev_map; | ||
872 | |||
873 | /* setup DMA area */ | ||
874 | ps3_dma_region_init(dev, dev->d_region, | ||
875 | PAGE_SHIFT, /* use system page size */ | ||
876 | 0, /* dma type; not used */ | ||
877 | NULL, | ||
878 | _ALIGN_UP(SND_PS3_DMA_REGION_SIZE, PAGE_SIZE)); | ||
879 | dev->d_region->ioid = PS3_AUDIO_IOID; | ||
880 | |||
881 | ret = ps3_dma_region_create(dev->d_region); | ||
882 | if (ret) { | ||
883 | pr_info("%s: region_create\n", __func__); | ||
884 | goto clean_mmio; | ||
885 | } | ||
886 | |||
887 | snd_ps3_audio_set_base_addr(dev->d_region->bus_addr); | ||
888 | |||
889 | /* CONFIG_SND_PS3_DEFAULT_START_DELAY */ | ||
890 | the_card.start_delay = snd_ps3_start_delay; | ||
891 | |||
892 | /* irq */ | ||
893 | if (snd_ps3_allocate_irq()) { | ||
894 | ret = -ENXIO; | ||
895 | goto clean_dma_region; | ||
896 | } | ||
897 | |||
898 | /* create card instance */ | ||
899 | the_card.card = snd_card_new(index, id, THIS_MODULE, 0); | ||
900 | if (!the_card.card) { | ||
901 | ret = -ENXIO; | ||
902 | goto clean_irq; | ||
903 | } | ||
904 | |||
905 | strcpy(the_card.card->driver, "PS3"); | ||
906 | strcpy(the_card.card->shortname, "PS3"); | ||
907 | strcpy(the_card.card->longname, "PS3 sound"); | ||
908 | /* create PCM devices instance */ | ||
909 | /* NOTE:this driver works assuming pcm:substream = 1:1 */ | ||
910 | ret = snd_pcm_new(the_card.card, | ||
911 | "SPDIF", | ||
912 | 0, /* instance index, will be stored pcm.device*/ | ||
913 | 1, /* output substream */ | ||
914 | 0, /* input substream */ | ||
915 | &(the_card.pcm)); | ||
916 | if (ret) | ||
917 | goto clean_card; | ||
918 | |||
919 | the_card.pcm->private_data = &the_card; | ||
920 | strcpy(the_card.pcm->name, "SPDIF"); | ||
921 | |||
922 | /* set pcm ops */ | ||
923 | snd_pcm_set_ops(the_card.pcm, SNDRV_PCM_STREAM_PLAYBACK, | ||
924 | &snd_ps3_pcm_spdif_ops); | ||
925 | |||
926 | the_card.pcm->info_flags = SNDRV_PCM_INFO_NONINTERLEAVED; | ||
927 | /* pre-alloc PCM DMA buffer*/ | ||
928 | ret = snd_pcm_lib_preallocate_pages_for_all(the_card.pcm, | ||
929 | SNDRV_DMA_TYPE_DEV, | ||
930 | &dev->core, | ||
931 | SND_PS3_PCM_PREALLOC_SIZE, | ||
932 | SND_PS3_PCM_PREALLOC_SIZE); | ||
933 | if (ret < 0) { | ||
934 | pr_info("%s: prealloc failed\n", __func__); | ||
935 | goto clean_card; | ||
936 | } | ||
937 | |||
938 | /* | ||
939 | * allocate null buffer | ||
940 | * its size should be lager than PS3_AUDIO_FIFO_STAGE_SIZE * 2 | ||
941 | * PAGE_SIZE is enogh | ||
942 | */ | ||
943 | if (!(the_card.null_buffer_start_vaddr = | ||
944 | dma_alloc_coherent(&the_card.ps3_dev->core, | ||
945 | PAGE_SIZE, | ||
946 | &the_card.null_buffer_start_dma_addr, | ||
947 | GFP_KERNEL))) { | ||
948 | pr_info("%s: nullbuffer alloc failed\n", __func__); | ||
949 | goto clean_preallocate; | ||
950 | } | ||
951 | pr_debug("%s: null vaddr=%p dma=%#lx\n", __func__, | ||
952 | the_card.null_buffer_start_vaddr, | ||
953 | the_card.null_buffer_start_dma_addr); | ||
954 | /* set default sample rate/word width */ | ||
955 | snd_ps3_init_avsetting(&the_card); | ||
956 | |||
957 | /* register the card */ | ||
958 | ret = snd_card_register(the_card.card); | ||
959 | if (ret < 0) | ||
960 | goto clean_dma_map; | ||
961 | |||
962 | pr_info("%s started. start_delay=%dms\n", | ||
963 | the_card.card->longname, the_card.start_delay); | ||
964 | return 0; | ||
965 | |||
966 | clean_dma_map: | ||
967 | dma_free_coherent(&the_card.ps3_dev->core, | ||
968 | PAGE_SIZE, | ||
969 | the_card.null_buffer_start_vaddr, | ||
970 | the_card.null_buffer_start_dma_addr); | ||
971 | clean_preallocate: | ||
972 | snd_pcm_lib_preallocate_free_for_all(the_card.pcm); | ||
973 | clean_card: | ||
974 | snd_card_free(the_card.card); | ||
975 | clean_irq: | ||
976 | snd_ps3_free_irq(); | ||
977 | clean_dma_region: | ||
978 | ps3_dma_region_free(dev->d_region); | ||
979 | clean_mmio: | ||
980 | snd_ps3_unmap_mmio(); | ||
981 | clean_dev_map: | ||
982 | lv1_gpu_device_unmap(2); | ||
983 | clean_open: | ||
984 | ps3_close_hv_device(dev); | ||
985 | /* | ||
986 | * there is no destructor function to pcm. | ||
987 | * midlayer automatically releases if the card removed | ||
988 | */ | ||
989 | return ret; | ||
990 | }; /* snd_ps3_probe */ | ||
991 | |||
992 | /* called when module removal */ | ||
993 | static int snd_ps3_driver_remove(struct ps3_system_bus_device *dev) | ||
994 | { | ||
995 | int ret; | ||
996 | pr_info("%s:start id=%d\n", __func__, dev->match_id); | ||
997 | if (dev->match_id != PS3_MATCH_ID_SOUND) | ||
998 | return -ENXIO; | ||
999 | |||
1000 | /* | ||
1001 | * ctl and preallocate buffer will be freed in | ||
1002 | * snd_card_free | ||
1003 | */ | ||
1004 | ret = snd_card_free(the_card.card); | ||
1005 | if (ret) | ||
1006 | pr_info("%s: ctl freecard=%d\n", __func__, ret); | ||
1007 | |||
1008 | dma_free_coherent(&dev->core, | ||
1009 | PAGE_SIZE, | ||
1010 | the_card.null_buffer_start_vaddr, | ||
1011 | the_card.null_buffer_start_dma_addr); | ||
1012 | |||
1013 | ps3_dma_region_free(dev->d_region); | ||
1014 | |||
1015 | snd_ps3_free_irq(); | ||
1016 | snd_ps3_unmap_mmio(); | ||
1017 | |||
1018 | lv1_gpu_device_unmap(2); | ||
1019 | ps3_close_hv_device(dev); | ||
1020 | pr_info("%s:end id=%d\n", __func__, dev->match_id); | ||
1021 | return 0; | ||
1022 | } /* snd_ps3_remove */ | ||
1023 | |||
1024 | static struct ps3_system_bus_driver snd_ps3_bus_driver_info = { | ||
1025 | .match_id = PS3_MATCH_ID_SOUND, | ||
1026 | .probe = snd_ps3_driver_probe, | ||
1027 | .remove = snd_ps3_driver_remove, | ||
1028 | .shutdown = snd_ps3_driver_remove, | ||
1029 | .core = { | ||
1030 | .name = SND_PS3_DRIVER_NAME, | ||
1031 | .owner = THIS_MODULE, | ||
1032 | }, | ||
1033 | }; | ||
1034 | |||
1035 | |||
1036 | /* | ||
1037 | * Interrupt handler | ||
1038 | */ | ||
1039 | static irqreturn_t snd_ps3_interrupt(int irq, void *dev_id) | ||
1040 | { | ||
1041 | |||
1042 | uint32_t port_intr; | ||
1043 | int underflow_occured = 0; | ||
1044 | struct snd_ps3_card_info *card = dev_id; | ||
1045 | |||
1046 | if (!card->running) { | ||
1047 | update_reg(PS3_AUDIO_AX_IS, 0); | ||
1048 | update_reg(PS3_AUDIO_INTR_0, 0); | ||
1049 | return IRQ_HANDLED; | ||
1050 | } | ||
1051 | |||
1052 | port_intr = read_reg(PS3_AUDIO_AX_IS); | ||
1053 | /* | ||
1054 | *serial buffer empty detected (every 4 times), | ||
1055 | *program next dma and kick it | ||
1056 | */ | ||
1057 | if (port_intr & PS3_AUDIO_AX_IE_ASOBEIE(0)) { | ||
1058 | write_reg(PS3_AUDIO_AX_IS, PS3_AUDIO_AX_IE_ASOBEIE(0)); | ||
1059 | if (port_intr & PS3_AUDIO_AX_IE_ASOBUIE(0)) { | ||
1060 | write_reg(PS3_AUDIO_AX_IS, port_intr); | ||
1061 | underflow_occured = 1; | ||
1062 | } | ||
1063 | if (card->silent) { | ||
1064 | /* we are still in silent time */ | ||
1065 | snd_ps3_program_dma(card, | ||
1066 | (underflow_occured) ? | ||
1067 | SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL : | ||
1068 | SND_PS3_DMA_FILLTYPE_SILENT_RUNNING); | ||
1069 | snd_ps3_kick_dma(card); | ||
1070 | card->silent --; | ||
1071 | } else { | ||
1072 | snd_ps3_program_dma(card, | ||
1073 | (underflow_occured) ? | ||
1074 | SND_PS3_DMA_FILLTYPE_FIRSTFILL : | ||
1075 | SND_PS3_DMA_FILLTYPE_RUNNING); | ||
1076 | snd_ps3_kick_dma(card); | ||
1077 | snd_pcm_period_elapsed(card->substream); | ||
1078 | } | ||
1079 | } else if (port_intr & PS3_AUDIO_AX_IE_ASOBUIE(0)) { | ||
1080 | write_reg(PS3_AUDIO_AX_IS, PS3_AUDIO_AX_IE_ASOBUIE(0)); | ||
1081 | /* | ||
1082 | * serial out underflow, but buffer empty not detected. | ||
1083 | * in this case, fill fifo with 0 to recover. After | ||
1084 | * filling dummy data, serial automatically start to | ||
1085 | * consume them and then will generate normal buffer | ||
1086 | * empty interrupts. | ||
1087 | * If both buffer underflow and buffer empty are occured, | ||
1088 | * it is better to do nomal data transfer than empty one | ||
1089 | */ | ||
1090 | snd_ps3_program_dma(card, | ||
1091 | SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL); | ||
1092 | snd_ps3_kick_dma(card); | ||
1093 | snd_ps3_program_dma(card, | ||
1094 | SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL); | ||
1095 | snd_ps3_kick_dma(card); | ||
1096 | } | ||
1097 | /* clear interrupt cause */ | ||
1098 | return IRQ_HANDLED; | ||
1099 | }; | ||
1100 | |||
1101 | /* | ||
1102 | * module/subsystem initialize/terminate | ||
1103 | */ | ||
1104 | static int __init snd_ps3_init(void) | ||
1105 | { | ||
1106 | int ret; | ||
1107 | |||
1108 | if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) | ||
1109 | return -ENXIO; | ||
1110 | |||
1111 | memset(&the_card, 0, sizeof(the_card)); | ||
1112 | spin_lock_init(&the_card.dma_lock); | ||
1113 | |||
1114 | /* register systembus DRIVER, this calls our probe() func */ | ||
1115 | ret = ps3_system_bus_driver_register(&snd_ps3_bus_driver_info); | ||
1116 | |||
1117 | return ret; | ||
1118 | } | ||
1119 | |||
1120 | static void __exit snd_ps3_exit(void) | ||
1121 | { | ||
1122 | ps3_system_bus_driver_unregister(&snd_ps3_bus_driver_info); | ||
1123 | } | ||
1124 | |||
1125 | MODULE_ALIAS(PS3_MODULE_ALIAS_SOUND); | ||
diff --git a/sound/ppc/snd_ps3.h b/sound/ppc/snd_ps3.h new file mode 100644 index 000000000000..4b7e6fbbe500 --- /dev/null +++ b/sound/ppc/snd_ps3.h | |||
@@ -0,0 +1,135 @@ | |||
1 | /* | ||
2 | * Audio support for PS3 | ||
3 | * Copyright (C) 2007 Sony Computer Entertainment Inc. | ||
4 | * All rights reserved. | ||
5 | * Copyright 2006, 2007 Sony Corporation | ||
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 | ||
9 | * as published by the Free Software Foundation; version 2 of the Licence. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #if !defined(_SND_PS3_H_) | ||
22 | #define _SND_PS3_H_ | ||
23 | |||
24 | #include <linux/irqreturn.h> | ||
25 | |||
26 | #define SND_PS3_DRIVER_NAME "snd_ps3" | ||
27 | |||
28 | enum snd_ps3_out_channel { | ||
29 | SND_PS3_OUT_SPDIF_0, | ||
30 | SND_PS3_OUT_SPDIF_1, | ||
31 | SND_PS3_OUT_SERIAL_0, | ||
32 | SND_PS3_OUT_DEVS | ||
33 | }; | ||
34 | |||
35 | enum snd_ps3_dma_filltype { | ||
36 | SND_PS3_DMA_FILLTYPE_FIRSTFILL, | ||
37 | SND_PS3_DMA_FILLTYPE_RUNNING, | ||
38 | SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL, | ||
39 | SND_PS3_DMA_FILLTYPE_SILENT_RUNNING | ||
40 | }; | ||
41 | |||
42 | enum snd_ps3_ch { | ||
43 | SND_PS3_CH_L = 0, | ||
44 | SND_PS3_CH_R = 1, | ||
45 | SND_PS3_CH_MAX = 2 | ||
46 | }; | ||
47 | |||
48 | struct snd_ps3_avsetting_info { | ||
49 | uint32_t avs_audio_ch; /* fixed */ | ||
50 | uint32_t avs_audio_rate; | ||
51 | uint32_t avs_audio_width; | ||
52 | uint32_t avs_audio_format; /* fixed */ | ||
53 | uint32_t avs_audio_source; /* fixed */ | ||
54 | }; | ||
55 | /* | ||
56 | * PS3 audio 'card' instance | ||
57 | * there should be only ONE hardware. | ||
58 | */ | ||
59 | struct snd_ps3_card_info { | ||
60 | struct ps3_system_bus_device *ps3_dev; | ||
61 | struct snd_card *card; | ||
62 | |||
63 | struct snd_pcm *pcm; | ||
64 | struct snd_pcm_substream *substream; | ||
65 | |||
66 | /* hvc info */ | ||
67 | u64 audio_lpar_addr; | ||
68 | u64 audio_lpar_size; | ||
69 | |||
70 | /* registers */ | ||
71 | void __iomem *mapped_mmio_vaddr; | ||
72 | |||
73 | /* irq */ | ||
74 | u64 audio_irq_outlet; | ||
75 | unsigned int irq_no; | ||
76 | |||
77 | /* remember avsetting */ | ||
78 | struct snd_ps3_avsetting_info avs; | ||
79 | |||
80 | /* dma buffer management */ | ||
81 | spinlock_t dma_lock; | ||
82 | /* dma_lock start */ | ||
83 | void * dma_start_vaddr[2]; /* 0 for L, 1 for R */ | ||
84 | dma_addr_t dma_start_bus_addr[2]; | ||
85 | size_t dma_buffer_size; | ||
86 | void * dma_last_transfer_vaddr[2]; | ||
87 | void * dma_next_transfer_vaddr[2]; | ||
88 | int silent; | ||
89 | /* dma_lock end */ | ||
90 | |||
91 | int running; | ||
92 | |||
93 | /* null buffer */ | ||
94 | void *null_buffer_start_vaddr; | ||
95 | dma_addr_t null_buffer_start_dma_addr; | ||
96 | |||
97 | /* start delay */ | ||
98 | unsigned int start_delay; | ||
99 | |||
100 | }; | ||
101 | |||
102 | |||
103 | /* PS3 audio DMAC block size in bytes */ | ||
104 | #define PS3_AUDIO_DMAC_BLOCK_SIZE (128) | ||
105 | /* one stage (stereo) of audio FIFO in bytes */ | ||
106 | #define PS3_AUDIO_FIFO_STAGE_SIZE (256) | ||
107 | /* how many stages the fifo have */ | ||
108 | #define PS3_AUDIO_FIFO_STAGE_COUNT (8) | ||
109 | /* fifo size 128 bytes * 8 stages * stereo (2ch) */ | ||
110 | #define PS3_AUDIO_FIFO_SIZE \ | ||
111 | (PS3_AUDIO_FIFO_STAGE_SIZE * PS3_AUDIO_FIFO_STAGE_COUNT) | ||
112 | |||
113 | /* PS3 audio DMAC max block count in one dma shot = 128 (0x80) blocks*/ | ||
114 | #define PS3_AUDIO_DMAC_MAX_BLOCKS (PS3_AUDIO_DMASIZE_BLOCKS_MASK + 1) | ||
115 | |||
116 | #define PS3_AUDIO_NORMAL_DMA_START_CH (0) | ||
117 | #define PS3_AUDIO_NORMAL_DMA_COUNT (8) | ||
118 | #define PS3_AUDIO_NULL_DMA_START_CH \ | ||
119 | (PS3_AUDIO_NORMAL_DMA_START_CH + PS3_AUDIO_NORMAL_DMA_COUNT) | ||
120 | #define PS3_AUDIO_NULL_DMA_COUNT (2) | ||
121 | |||
122 | #define SND_PS3_MAX_VOL (0x0F) | ||
123 | #define SND_PS3_MIN_VOL (0x00) | ||
124 | #define SND_PS3_MIN_ATT SND_PS3_MIN_VOL | ||
125 | #define SND_PS3_MAX_ATT SND_PS3_MAX_VOL | ||
126 | |||
127 | #define SND_PS3_PCM_PREALLOC_SIZE \ | ||
128 | (PS3_AUDIO_DMAC_BLOCK_SIZE * PS3_AUDIO_DMAC_MAX_BLOCKS * 4) | ||
129 | |||
130 | #define SND_PS3_DMA_REGION_SIZE \ | ||
131 | (SND_PS3_PCM_PREALLOC_SIZE + PAGE_SIZE) | ||
132 | |||
133 | #define PS3_AUDIO_IOID (1UL) | ||
134 | |||
135 | #endif /* _SND_PS3_H_ */ | ||
diff --git a/sound/ppc/snd_ps3_reg.h b/sound/ppc/snd_ps3_reg.h new file mode 100644 index 000000000000..03fdee4aaaf2 --- /dev/null +++ b/sound/ppc/snd_ps3_reg.h | |||
@@ -0,0 +1,891 @@ | |||
1 | /* | ||
2 | * Audio support for PS3 | ||
3 | * Copyright (C) 2007 Sony Computer Entertainment Inc. | ||
4 | * Copyright 2006, 2007 Sony Corporation | ||
5 | * All rights reserved. | ||
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 | ||
9 | * as published by the Free Software Foundation; version 2 of the License. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | /* | ||
22 | * interrupt / configure registers | ||
23 | */ | ||
24 | |||
25 | #define PS3_AUDIO_INTR_0 (0x00000100) | ||
26 | #define PS3_AUDIO_INTR_EN_0 (0x00000140) | ||
27 | #define PS3_AUDIO_CONFIG (0x00000200) | ||
28 | |||
29 | /* | ||
30 | * DMAC registers | ||
31 | * n:0..9 | ||
32 | */ | ||
33 | #define PS3_AUDIO_DMAC_REGBASE(x) (0x0000210 + 0x20 * (x)) | ||
34 | |||
35 | #define PS3_AUDIO_KICK(n) (PS3_AUDIO_DMAC_REGBASE(n) + 0x00) | ||
36 | #define PS3_AUDIO_SOURCE(n) (PS3_AUDIO_DMAC_REGBASE(n) + 0x04) | ||
37 | #define PS3_AUDIO_DEST(n) (PS3_AUDIO_DMAC_REGBASE(n) + 0x08) | ||
38 | #define PS3_AUDIO_DMASIZE(n) (PS3_AUDIO_DMAC_REGBASE(n) + 0x0C) | ||
39 | |||
40 | /* | ||
41 | * mute control | ||
42 | */ | ||
43 | #define PS3_AUDIO_AX_MCTRL (0x00004000) | ||
44 | #define PS3_AUDIO_AX_ISBP (0x00004004) | ||
45 | #define PS3_AUDIO_AX_AOBP (0x00004008) | ||
46 | #define PS3_AUDIO_AX_IC (0x00004010) | ||
47 | #define PS3_AUDIO_AX_IE (0x00004014) | ||
48 | #define PS3_AUDIO_AX_IS (0x00004018) | ||
49 | |||
50 | /* | ||
51 | * three wire serial | ||
52 | * n:0..3 | ||
53 | */ | ||
54 | #define PS3_AUDIO_AO_MCTRL (0x00006000) | ||
55 | #define PS3_AUDIO_AO_3WMCTRL (0x00006004) | ||
56 | |||
57 | #define PS3_AUDIO_AO_3WCTRL(n) (0x00006200 + 0x200 * (n)) | ||
58 | |||
59 | /* | ||
60 | * S/PDIF | ||
61 | * n:0..1 | ||
62 | * x:0..11 | ||
63 | * y:0..5 | ||
64 | */ | ||
65 | #define PS3_AUDIO_AO_SPD_REGBASE(n) (0x00007200 + 0x200 * (n)) | ||
66 | |||
67 | #define PS3_AUDIO_AO_SPDCTRL(n) \ | ||
68 | (PS3_AUDIO_AO_SPD_REGBASE(n) + 0x00) | ||
69 | #define PS3_AUDIO_AO_SPDUB(n, x) \ | ||
70 | (PS3_AUDIO_AO_SPD_REGBASE(n) + 0x04 + 0x04 * (x)) | ||
71 | #define PS3_AUDIO_AO_SPDCS(n, y) \ | ||
72 | (PS3_AUDIO_AO_SPD_REGBASE(n) + 0x34 + 0x04 * (y)) | ||
73 | |||
74 | |||
75 | /* | ||
76 | PS3_AUDIO_INTR_0 register tells an interrupt handler which audio | ||
77 | DMA channel triggered the interrupt. The interrupt status for a channel | ||
78 | can be cleared by writing a '1' to the corresponding bit. A new interrupt | ||
79 | cannot be generated until the previous interrupt has been cleared. | ||
80 | |||
81 | Note that the status reported by PS3_AUDIO_INTR_0 is independent of the | ||
82 | value of PS3_AUDIO_INTR_EN_0. | ||
83 | |||
84 | 31 24 23 16 15 8 7 0 | ||
85 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
86 | |0 0 0 0 0 0 0 0 0 0 0 0 0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C| INTR_0 | ||
87 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
88 | */ | ||
89 | #define PS3_AUDIO_INTR_0_CHAN(n) (1 << ((n) * 2)) | ||
90 | #define PS3_AUDIO_INTR_0_CHAN9 PS3_AUDIO_INTR_0_CHAN(9) | ||
91 | #define PS3_AUDIO_INTR_0_CHAN8 PS3_AUDIO_INTR_0_CHAN(8) | ||
92 | #define PS3_AUDIO_INTR_0_CHAN7 PS3_AUDIO_INTR_0_CHAN(7) | ||
93 | #define PS3_AUDIO_INTR_0_CHAN6 PS3_AUDIO_INTR_0_CHAN(6) | ||
94 | #define PS3_AUDIO_INTR_0_CHAN5 PS3_AUDIO_INTR_0_CHAN(5) | ||
95 | #define PS3_AUDIO_INTR_0_CHAN4 PS3_AUDIO_INTR_0_CHAN(4) | ||
96 | #define PS3_AUDIO_INTR_0_CHAN3 PS3_AUDIO_INTR_0_CHAN(3) | ||
97 | #define PS3_AUDIO_INTR_0_CHAN2 PS3_AUDIO_INTR_0_CHAN(2) | ||
98 | #define PS3_AUDIO_INTR_0_CHAN1 PS3_AUDIO_INTR_0_CHAN(1) | ||
99 | #define PS3_AUDIO_INTR_0_CHAN0 PS3_AUDIO_INTR_0_CHAN(0) | ||
100 | |||
101 | /* | ||
102 | The PS3_AUDIO_INTR_EN_0 register specifies which DMA channels can generate | ||
103 | an interrupt to the PU. Each bit of PS3_AUDIO_INTR_EN_0 is ANDed with the | ||
104 | corresponding bit in PS3_AUDIO_INTR_0. The resulting bits are OR'd together | ||
105 | to generate the Audio interrupt. | ||
106 | |||
107 | 31 24 23 16 15 8 7 0 | ||
108 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
109 | |0 0 0 0 0 0 0 0 0 0 0 0 0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C| INTR_EN_0 | ||
110 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
111 | |||
112 | Bit assignments are same as PS3_AUDIO_INTR_0 | ||
113 | */ | ||
114 | |||
115 | /* | ||
116 | PS3_AUDIO_CONFIG | ||
117 | 31 24 23 16 15 8 7 0 | ||
118 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
119 | |0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 C|0 0 0 0 0 0 0 0| CONFIG | ||
120 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
121 | |||
122 | */ | ||
123 | |||
124 | /* The CLEAR field cancels all pending transfers, and stops any running DMA | ||
125 | transfers. Any interrupts associated with the canceled transfers | ||
126 | will occur as if the transfer had finished. | ||
127 | Since this bit is designed to recover from DMA related issues | ||
128 | which are caused by unpredictable situations, it is prefered to wait | ||
129 | for normal DMA transfer end without using this bit. | ||
130 | */ | ||
131 | #define PS3_AUDIO_CONFIG_CLEAR (1 << 8) /* RWIVF */ | ||
132 | |||
133 | /* | ||
134 | PS3_AUDIO_AX_MCTRL: Audio Port Mute Control Register | ||
135 | |||
136 | 31 24 23 16 15 8 7 0 | ||
137 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
138 | |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0|A|A|A|0 0 0 0 0 0 0|S|S|A|A|A|A| AX_MCTRL | ||
139 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
140 | */ | ||
141 | |||
142 | /* 3 Wire Audio Serial Output Channel Mutes (0..3) */ | ||
143 | #define PS3_AUDIO_AX_MCTRL_ASOMT(n) (1 << (3 - (n))) /* RWIVF */ | ||
144 | #define PS3_AUDIO_AX_MCTRL_ASO3MT (1 << 0) /* RWIVF */ | ||
145 | #define PS3_AUDIO_AX_MCTRL_ASO2MT (1 << 1) /* RWIVF */ | ||
146 | #define PS3_AUDIO_AX_MCTRL_ASO1MT (1 << 2) /* RWIVF */ | ||
147 | #define PS3_AUDIO_AX_MCTRL_ASO0MT (1 << 3) /* RWIVF */ | ||
148 | |||
149 | /* S/PDIF mutes (0,1)*/ | ||
150 | #define PS3_AUDIO_AX_MCTRL_SPOMT(n) (1 << (5 - (n))) /* RWIVF */ | ||
151 | #define PS3_AUDIO_AX_MCTRL_SPO1MT (1 << 4) /* RWIVF */ | ||
152 | #define PS3_AUDIO_AX_MCTRL_SPO0MT (1 << 5) /* RWIVF */ | ||
153 | |||
154 | /* All 3 Wire Serial Outputs Mute */ | ||
155 | #define PS3_AUDIO_AX_MCTRL_AASOMT (1 << 13) /* RWIVF */ | ||
156 | |||
157 | /* All S/PDIF Mute */ | ||
158 | #define PS3_AUDIO_AX_MCTRL_ASPOMT (1 << 14) /* RWIVF */ | ||
159 | |||
160 | /* All Audio Outputs Mute */ | ||
161 | #define PS3_AUDIO_AX_MCTRL_AAOMT (1 << 15) /* RWIVF */ | ||
162 | |||
163 | /* | ||
164 | S/PDIF Outputs Buffer Read/Write Pointer Register | ||
165 | |||
166 | 31 24 23 16 15 8 7 0 | ||
167 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
168 | |0 0 0 0 0 0 0 0|0|SPO0B|0|SPO1B|0 0 0 0 0 0 0 0|0|SPO0B|0|SPO1B| AX_ISBP | ||
169 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
170 | |||
171 | */ | ||
172 | /* | ||
173 | S/PDIF Output Channel Read Buffer Numbers | ||
174 | Buffer number is value of field. | ||
175 | Indicates current read access buffer ID from Audio Data | ||
176 | Transfer controller of S/PDIF Output | ||
177 | */ | ||
178 | |||
179 | #define PS3_AUDIO_AX_ISBP_SPOBRN_MASK(n) (0x7 << 4 * (1 - (n))) /* R-IUF */ | ||
180 | #define PS3_AUDIO_AX_ISBP_SPO1BRN_MASK (0x7 << 0) /* R-IUF */ | ||
181 | #define PS3_AUDIO_AX_ISBP_SPO0BRN_MASK (0x7 << 4) /* R-IUF */ | ||
182 | |||
183 | /* | ||
184 | S/PDIF Output Channel Buffer Write Numbers | ||
185 | Indicates current write access buffer ID from bus master. | ||
186 | */ | ||
187 | #define PS3_AUDIO_AX_ISBP_SPOBWN_MASK(n) (0x7 << 4 * (5 - (n))) /* R-IUF */ | ||
188 | #define PS3_AUDIO_AX_ISBP_SPO1BWN_MASK (0x7 << 16) /* R-IUF */ | ||
189 | #define PS3_AUDIO_AX_ISBP_SPO0BWN_MASK (0x7 << 20) /* R-IUF */ | ||
190 | |||
191 | /* | ||
192 | 3 Wire Audio Serial Outputs Buffer Read/Write | ||
193 | Pointer Register | ||
194 | Buffer number is value of field | ||
195 | |||
196 | 31 24 23 16 15 8 7 0 | ||
197 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
198 | |0|ASO0B|0|ASO1B|0|ASO2B|0|ASO3B|0|ASO0B|0|ASO1B|0|ASO2B|0|ASO3B| AX_AOBP | ||
199 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
200 | */ | ||
201 | |||
202 | /* | ||
203 | 3 Wire Audio Serial Output Channel Buffer Read Numbers | ||
204 | Indicates current read access buffer Id from Audio Data Transfer | ||
205 | Controller of 3 Wire Audio Serial Output Channels | ||
206 | */ | ||
207 | #define PS3_AUDIO_AX_AOBP_ASOBRN_MASK(n) (0x7 << 4 * (3 - (n))) /* R-IUF */ | ||
208 | |||
209 | #define PS3_AUDIO_AX_AOBP_ASO3BRN_MASK (0x7 << 0) /* R-IUF */ | ||
210 | #define PS3_AUDIO_AX_AOBP_ASO2BRN_MASK (0x7 << 4) /* R-IUF */ | ||
211 | #define PS3_AUDIO_AX_AOBP_ASO1BRN_MASK (0x7 << 8) /* R-IUF */ | ||
212 | #define PS3_AUDIO_AX_AOBP_ASO0BRN_MASK (0x7 << 12) /* R-IUF */ | ||
213 | |||
214 | /* | ||
215 | 3 Wire Audio Serial Output Channel Buffer Write Numbers | ||
216 | Indicates current write access buffer ID from bus master. | ||
217 | */ | ||
218 | #define PS3_AUDIO_AX_AOBP_ASOBWN_MASK(n) (0x7 << 4 * (7 - (n))) /* R-IUF */ | ||
219 | |||
220 | #define PS3_AUDIO_AX_AOBP_ASO3BWN_MASK (0x7 << 16) /* R-IUF */ | ||
221 | #define PS3_AUDIO_AX_AOBP_ASO2BWN_MASK (0x7 << 20) /* R-IUF */ | ||
222 | #define PS3_AUDIO_AX_AOBP_ASO1BWN_MASK (0x7 << 24) /* R-IUF */ | ||
223 | #define PS3_AUDIO_AX_AOBP_ASO0BWN_MASK (0x7 << 28) /* R-IUF */ | ||
224 | |||
225 | |||
226 | |||
227 | /* | ||
228 | Audio Port Interrupt Condition Register | ||
229 | For the fields in this register, the following values apply: | ||
230 | 0 = Interrupt is generated every interrupt event. | ||
231 | 1 = Interrupt is generated every 2 interrupt events. | ||
232 | 2 = Interrupt is generated every 4 interrupt events. | ||
233 | 3 = Reserved | ||
234 | |||
235 | |||
236 | 31 24 23 16 15 8 7 0 | ||
237 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
238 | |0 0 0 0 0 0 0 0|0 0|SPO|0 0|SPO|0 0|AAS|0 0 0 0 0 0 0 0 0 0 0 0| AX_IC | ||
239 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
240 | */ | ||
241 | /* | ||
242 | All 3-Wire Audio Serial Outputs Interrupt Mode | ||
243 | Configures the Interrupt and Signal Notification | ||
244 | condition of all 3-wire Audio Serial Outputs. | ||
245 | */ | ||
246 | #define PS3_AUDIO_AX_IC_AASOIMD_MASK (0x3 << 12) /* RWIVF */ | ||
247 | #define PS3_AUDIO_AX_IC_AASOIMD_EVERY1 (0x0 << 12) /* RWI-V */ | ||
248 | #define PS3_AUDIO_AX_IC_AASOIMD_EVERY2 (0x1 << 12) /* RW--V */ | ||
249 | #define PS3_AUDIO_AX_IC_AASOIMD_EVERY4 (0x2 << 12) /* RW--V */ | ||
250 | |||
251 | /* | ||
252 | S/PDIF Output Channel Interrupt Modes | ||
253 | Configures the Interrupt and signal Notification | ||
254 | conditions of S/PDIF output channels. | ||
255 | */ | ||
256 | #define PS3_AUDIO_AX_IC_SPO1IMD_MASK (0x3 << 16) /* RWIVF */ | ||
257 | #define PS3_AUDIO_AX_IC_SPO1IMD_EVERY1 (0x0 << 16) /* RWI-V */ | ||
258 | #define PS3_AUDIO_AX_IC_SPO1IMD_EVERY2 (0x1 << 16) /* RW--V */ | ||
259 | #define PS3_AUDIO_AX_IC_SPO1IMD_EVERY4 (0x2 << 16) /* RW--V */ | ||
260 | |||
261 | #define PS3_AUDIO_AX_IC_SPO0IMD_MASK (0x3 << 20) /* RWIVF */ | ||
262 | #define PS3_AUDIO_AX_IC_SPO0IMD_EVERY1 (0x0 << 20) /* RWI-V */ | ||
263 | #define PS3_AUDIO_AX_IC_SPO0IMD_EVERY2 (0x1 << 20) /* RW--V */ | ||
264 | #define PS3_AUDIO_AX_IC_SPO0IMD_EVERY4 (0x2 << 20) /* RW--V */ | ||
265 | |||
266 | /* | ||
267 | Audio Port interrupt Enable Register | ||
268 | Configures whether to enable or disable each Interrupt Generation. | ||
269 | |||
270 | |||
271 | 31 24 23 16 15 8 7 0 | ||
272 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
273 | |0 0 0 0 0 0 0 0|S|S|0 0|A|A|A|A|0 0 0 0|S|S|0 0|S|S|0 0|A|A|A|A| AX_IE | ||
274 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
275 | |||
276 | */ | ||
277 | |||
278 | /* | ||
279 | 3 Wire Audio Serial Output Channel Buffer Underflow | ||
280 | Interrupt Enables | ||
281 | Select enable/disable of Buffer Underflow Interrupts for | ||
282 | 3-Wire Audio Serial Output Channels | ||
283 | DISABLED=Interrupt generation disabled. | ||
284 | */ | ||
285 | #define PS3_AUDIO_AX_IE_ASOBUIE(n) (1 << (3 - (n))) /* RWIVF */ | ||
286 | #define PS3_AUDIO_AX_IE_ASO3BUIE (1 << 0) /* RWIVF */ | ||
287 | #define PS3_AUDIO_AX_IE_ASO2BUIE (1 << 1) /* RWIVF */ | ||
288 | #define PS3_AUDIO_AX_IE_ASO1BUIE (1 << 2) /* RWIVF */ | ||
289 | #define PS3_AUDIO_AX_IE_ASO0BUIE (1 << 3) /* RWIVF */ | ||
290 | |||
291 | /* S/PDIF Output Channel Buffer Underflow Interrupt Enables */ | ||
292 | |||
293 | #define PS3_AUDIO_AX_IE_SPOBUIE(n) (1 << (7 - (n))) /* RWIVF */ | ||
294 | #define PS3_AUDIO_AX_IE_SPO1BUIE (1 << 6) /* RWIVF */ | ||
295 | #define PS3_AUDIO_AX_IE_SPO0BUIE (1 << 7) /* RWIVF */ | ||
296 | |||
297 | /* S/PDIF Output Channel One Block Transfer Completion Interrupt Enables */ | ||
298 | |||
299 | #define PS3_AUDIO_AX_IE_SPOBTCIE(n) (1 << (11 - (n))) /* RWIVF */ | ||
300 | #define PS3_AUDIO_AX_IE_SPO1BTCIE (1 << 10) /* RWIVF */ | ||
301 | #define PS3_AUDIO_AX_IE_SPO0BTCIE (1 << 11) /* RWIVF */ | ||
302 | |||
303 | /* 3-Wire Audio Serial Output Channel Buffer Empty Interrupt Enables */ | ||
304 | |||
305 | #define PS3_AUDIO_AX_IE_ASOBEIE(n) (1 << (19 - (n))) /* RWIVF */ | ||
306 | #define PS3_AUDIO_AX_IE_ASO3BEIE (1 << 16) /* RWIVF */ | ||
307 | #define PS3_AUDIO_AX_IE_ASO2BEIE (1 << 17) /* RWIVF */ | ||
308 | #define PS3_AUDIO_AX_IE_ASO1BEIE (1 << 18) /* RWIVF */ | ||
309 | #define PS3_AUDIO_AX_IE_ASO0BEIE (1 << 19) /* RWIVF */ | ||
310 | |||
311 | /* S/PDIF Output Channel Buffer Empty Interrupt Enables */ | ||
312 | |||
313 | #define PS3_AUDIO_AX_IE_SPOBEIE(n) (1 << (23 - (n))) /* RWIVF */ | ||
314 | #define PS3_AUDIO_AX_IE_SPO1BEIE (1 << 22) /* RWIVF */ | ||
315 | #define PS3_AUDIO_AX_IE_SPO0BEIE (1 << 23) /* RWIVF */ | ||
316 | |||
317 | /* | ||
318 | Audio Port Interrupt Status Register | ||
319 | Indicates Interrupt status, which interrupt has occured, and can clear | ||
320 | each interrupt in this register. | ||
321 | Writing 1b to a field containing 1b clears field and de-asserts interrupt. | ||
322 | Writing 0b to a field has no effect. | ||
323 | Field vaules are the following: | ||
324 | 0 - Interrupt hasn't occured. | ||
325 | 1 - Interrupt has occured. | ||
326 | |||
327 | |||
328 | 31 24 23 16 15 8 7 0 | ||
329 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
330 | |0 0 0 0 0 0 0 0|S|S|0 0|A|A|A|A|0 0 0 0|S|S|0 0|S|S|0 0|A|A|A|A| AX_IS | ||
331 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
332 | |||
333 | Bit assignment are same as AX_IE | ||
334 | */ | ||
335 | |||
336 | /* | ||
337 | Audio Output Master Control Register | ||
338 | Configures Master Clock and other master Audio Output Settings | ||
339 | |||
340 | |||
341 | 31 24 23 16 15 8 7 0 | ||
342 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
343 | |0|SCKSE|0|SCKSE| MR0 | MR1 |MCL|MCL|0 0 0 0|0 0 0 0 0 0 0 0| AO_MCTRL | ||
344 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
345 | */ | ||
346 | |||
347 | /* | ||
348 | MCLK Output Control | ||
349 | Controls mclko[1] output. | ||
350 | 0 - Disable output (fixed at High) | ||
351 | 1 - Output clock produced by clock selected | ||
352 | with scksel1 by mr1 | ||
353 | 2 - Reserved | ||
354 | 3 - Reserved | ||
355 | */ | ||
356 | |||
357 | #define PS3_AUDIO_AO_MCTRL_MCLKC1_MASK (0x3 << 12) /* RWIVF */ | ||
358 | #define PS3_AUDIO_AO_MCTRL_MCLKC1_DISABLED (0x0 << 12) /* RWI-V */ | ||
359 | #define PS3_AUDIO_AO_MCTRL_MCLKC1_ENABLED (0x1 << 12) /* RW--V */ | ||
360 | #define PS3_AUDIO_AO_MCTRL_MCLKC1_RESVD2 (0x2 << 12) /* RW--V */ | ||
361 | #define PS3_AUDIO_AO_MCTRL_MCLKC1_RESVD3 (0x3 << 12) /* RW--V */ | ||
362 | |||
363 | /* | ||
364 | MCLK Output Control | ||
365 | Controls mclko[0] output. | ||
366 | 0 - Disable output (fixed at High) | ||
367 | 1 - Output clock produced by clock selected | ||
368 | with SCKSEL0 by MR0 | ||
369 | 2 - Reserved | ||
370 | 3 - Reserved | ||
371 | */ | ||
372 | #define PS3_AUDIO_AO_MCTRL_MCLKC0_MASK (0x3 << 14) /* RWIVF */ | ||
373 | #define PS3_AUDIO_AO_MCTRL_MCLKC0_DISABLED (0x0 << 14) /* RWI-V */ | ||
374 | #define PS3_AUDIO_AO_MCTRL_MCLKC0_ENABLED (0x1 << 14) /* RW--V */ | ||
375 | #define PS3_AUDIO_AO_MCTRL_MCLKC0_RESVD2 (0x2 << 14) /* RW--V */ | ||
376 | #define PS3_AUDIO_AO_MCTRL_MCLKC0_RESVD3 (0x3 << 14) /* RW--V */ | ||
377 | /* | ||
378 | Master Clock Rate 1 | ||
379 | Sets the divide ration of Master Clock1 (clock output from | ||
380 | mclko[1] for the input clock selected by scksel1. | ||
381 | */ | ||
382 | #define PS3_AUDIO_AO_MCTRL_MR1_MASK (0xf << 16) | ||
383 | #define PS3_AUDIO_AO_MCTRL_MR1_DEFAULT (0x0 << 16) /* RWI-V */ | ||
384 | /* | ||
385 | Master Clock Rate 0 | ||
386 | Sets the divide ratio of Master Clock0 (clock output from | ||
387 | mclko[0] for the input clock selected by scksel0). | ||
388 | */ | ||
389 | #define PS3_AUDIO_AO_MCTRL_MR0_MASK (0xf << 20) /* RWIVF */ | ||
390 | #define PS3_AUDIO_AO_MCTRL_MR0_DEFAULT (0x0 << 20) /* RWI-V */ | ||
391 | /* | ||
392 | System Clock Select 0/1 | ||
393 | Selects the system clock to be used as Master Clock 0/1 | ||
394 | Input the system clock that is appropriate for the sampling | ||
395 | rate. | ||
396 | */ | ||
397 | #define PS3_AUDIO_AO_MCTRL_SCKSEL1_MASK (0x7 << 24) /* RWIVF */ | ||
398 | #define PS3_AUDIO_AO_MCTRL_SCKSEL1_DEFAULT (0x2 << 24) /* RWI-V */ | ||
399 | |||
400 | #define PS3_AUDIO_AO_MCTRL_SCKSEL0_MASK (0x7 << 28) /* RWIVF */ | ||
401 | #define PS3_AUDIO_AO_MCTRL_SCKSEL0_DEFAULT (0x2 << 28) /* RWI-V */ | ||
402 | |||
403 | |||
404 | /* | ||
405 | 3-Wire Audio Output Master Control Register | ||
406 | Configures clock, 3-Wire Audio Serial Output Enable, and | ||
407 | other 3-Wire Audio Serial Output Master Settings | ||
408 | |||
409 | |||
410 | 31 24 23 16 15 8 7 0 | ||
411 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
412 | |A|A|A|A|0 0 0|A| ASOSR |0 0 0 0|A|A|A|A|A|A|0|1|0 0 0 0 0 0 0 0| AO_3WMCTRL | ||
413 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
414 | */ | ||
415 | |||
416 | |||
417 | /* | ||
418 | LRCKO Polarity | ||
419 | 0 - Reserved | ||
420 | 1 - default | ||
421 | */ | ||
422 | #define PS3_AUDIO_AO_3WMCTRL_ASOPLRCK (1 << 8) /* RWIVF */ | ||
423 | #define PS3_AUDIO_AO_3WMCTRL_ASOPLRCK_DEFAULT (1 << 8) /* RW--V */ | ||
424 | |||
425 | /* LRCK Output Disable */ | ||
426 | |||
427 | #define PS3_AUDIO_AO_3WMCTRL_ASOLRCKD (1 << 10) /* RWIVF */ | ||
428 | #define PS3_AUDIO_AO_3WMCTRL_ASOLRCKD_ENABLED (0 << 10) /* RW--V */ | ||
429 | #define PS3_AUDIO_AO_3WMCTRL_ASOLRCKD_DISABLED (1 << 10) /* RWI-V */ | ||
430 | |||
431 | /* Bit Clock Output Disable */ | ||
432 | |||
433 | #define PS3_AUDIO_AO_3WMCTRL_ASOBCLKD (1 << 11) /* RWIVF */ | ||
434 | #define PS3_AUDIO_AO_3WMCTRL_ASOBCLKD_ENABLED (0 << 11) /* RW--V */ | ||
435 | #define PS3_AUDIO_AO_3WMCTRL_ASOBCLKD_DISABLED (1 << 11) /* RWI-V */ | ||
436 | |||
437 | /* | ||
438 | 3-Wire Audio Serial Output Channel 0-3 Operational | ||
439 | Status. Each bit becomes 1 after each 3-Wire Audio | ||
440 | Serial Output Channel N is in action by setting 1 to | ||
441 | asoen. | ||
442 | Each bit becomes 0 after each 3-Wire Audio Serial Output | ||
443 | Channel N is out of action by setting 0 to asoen. | ||
444 | */ | ||
445 | #define PS3_AUDIO_AO_3WMCTRL_ASORUN(n) (1 << (15 - (n))) /* R-IVF */ | ||
446 | #define PS3_AUDIO_AO_3WMCTRL_ASORUN_STOPPED(n) (0 << (15 - (n))) /* R-I-V */ | ||
447 | #define PS3_AUDIO_AO_3WMCTRL_ASORUN_RUNNING(n) (1 << (15 - (n))) /* R---V */ | ||
448 | #define PS3_AUDIO_AO_3WMCTRL_ASORUN0 \ | ||
449 | PS3_AUDIO_AO_3WMCTRL_ASORUN(0) | ||
450 | #define PS3_AUDIO_AO_3WMCTRL_ASORUN0_STOPPED \ | ||
451 | PS3_AUDIO_AO_3WMCTRL_ASORUN_STOPPED(0) | ||
452 | #define PS3_AUDIO_AO_3WMCTRL_ASORUN0_RUNNING \ | ||
453 | PS3_AUDIO_AO_3WMCTRL_ASORUN_RUNNING(0) | ||
454 | #define PS3_AUDIO_AO_3WMCTRL_ASORUN1 \ | ||
455 | PS3_AUDIO_AO_3WMCTRL_ASORUN(1) | ||
456 | #define PS3_AUDIO_AO_3WMCTRL_ASORUN1_STOPPED \ | ||
457 | PS3_AUDIO_AO_3WMCTRL_ASORUN_STOPPED(1) | ||
458 | #define PS3_AUDIO_AO_3WMCTRL_ASORUN1_RUNNING \ | ||
459 | PS3_AUDIO_AO_3WMCTRL_ASORUN_RUNNING(1) | ||
460 | #define PS3_AUDIO_AO_3WMCTRL_ASORUN2 \ | ||
461 | PS3_AUDIO_AO_3WMCTRL_ASORUN(2) | ||
462 | #define PS3_AUDIO_AO_3WMCTRL_ASORUN2_STOPPED \ | ||
463 | PS3_AUDIO_AO_3WMCTRL_ASORUN_STOPPED(2) | ||
464 | #define PS3_AUDIO_AO_3WMCTRL_ASORUN2_RUNNING \ | ||
465 | PS3_AUDIO_AO_3WMCTRL_ASORUN_RUNNING(2) | ||
466 | #define PS3_AUDIO_AO_3WMCTRL_ASORUN3 \ | ||
467 | PS3_AUDIO_AO_3WMCTRL_ASORUN(3) | ||
468 | #define PS3_AUDIO_AO_3WMCTRL_ASORUN3_STOPPED \ | ||
469 | PS3_AUDIO_AO_3WMCTRL_ASORUN_STOPPED(3) | ||
470 | #define PS3_AUDIO_AO_3WMCTRL_ASORUN3_RUNNING \ | ||
471 | PS3_AUDIO_AO_3WMCTRL_ASORUN_RUNNING(3) | ||
472 | |||
473 | /* | ||
474 | Sampling Rate | ||
475 | Specifies the divide ratio of the bit clock (clock output | ||
476 | from bclko) used by the 3-wire Audio Output Clock, whcih | ||
477 | is applied to the master clock selected by mcksel. | ||
478 | Data output is synchronized with this clock. | ||
479 | */ | ||
480 | #define PS3_AUDIO_AO_3WMCTRL_ASOSR_MASK (0xf << 20) /* RWIVF */ | ||
481 | #define PS3_AUDIO_AO_3WMCTRL_ASOSR_DIV2 (0x1 << 20) /* RWI-V */ | ||
482 | #define PS3_AUDIO_AO_3WMCTRL_ASOSR_DIV4 (0x2 << 20) /* RW--V */ | ||
483 | #define PS3_AUDIO_AO_3WMCTRL_ASOSR_DIV8 (0x4 << 20) /* RW--V */ | ||
484 | #define PS3_AUDIO_AO_3WMCTRL_ASOSR_DIV12 (0x6 << 20) /* RW--V */ | ||
485 | |||
486 | /* | ||
487 | Master Clock Select | ||
488 | 0 - Master Clock 0 | ||
489 | 1 - Master Clock 1 | ||
490 | */ | ||
491 | #define PS3_AUDIO_AO_3WMCTRL_ASOMCKSEL (1 << 24) /* RWIVF */ | ||
492 | #define PS3_AUDIO_AO_3WMCTRL_ASOMCKSEL_CLK0 (0 << 24) /* RWI-V */ | ||
493 | #define PS3_AUDIO_AO_3WMCTRL_ASOMCKSEL_CLK1 (1 << 24) /* RW--V */ | ||
494 | |||
495 | /* | ||
496 | Enables and disables 4ch 3-Wire Audio Serial Output | ||
497 | operation. Each Bit from 0 to 3 corresponds to an | ||
498 | output channel, which means that each output channel | ||
499 | can be enabled or disabled individually. When | ||
500 | multiple channels are enabled at the same time, output | ||
501 | operations are performed in synchronization. | ||
502 | Bit 0 - Output Channel 0 (SDOUT[0]) | ||
503 | Bit 1 - Output Channel 1 (SDOUT[1]) | ||
504 | Bit 2 - Output Channel 2 (SDOUT[2]) | ||
505 | Bit 3 - Output Channel 3 (SDOUT[3]) | ||
506 | */ | ||
507 | #define PS3_AUDIO_AO_3WMCTRL_ASOEN(n) (1 << (31 - (n))) /* RWIVF */ | ||
508 | #define PS3_AUDIO_AO_3WMCTRL_ASOEN_DISABLED(n) (0 << (31 - (n))) /* RWI-V */ | ||
509 | #define PS3_AUDIO_AO_3WMCTRL_ASOEN_ENABLED(n) (1 << (31 - (n))) /* RW--V */ | ||
510 | |||
511 | #define PS3_AUDIO_AO_3WMCTRL_ASOEN0 \ | ||
512 | PS3_AUDIO_AO_3WMCTRL_ASOEN(0) /* RWIVF */ | ||
513 | #define PS3_AUDIO_AO_3WMCTRL_ASOEN0_DISABLED \ | ||
514 | PS3_AUDIO_AO_3WMCTRL_ASOEN_DISABLED(0) /* RWI-V */ | ||
515 | #define PS3_AUDIO_AO_3WMCTRL_ASOEN0_ENABLED \ | ||
516 | PS3_AUDIO_AO_3WMCTRL_ASOEN_ENABLED(0) /* RW--V */ | ||
517 | #define PS3_AUDIO_A1_3WMCTRL_ASOEN0 \ | ||
518 | PS3_AUDIO_AO_3WMCTRL_ASOEN(1) /* RWIVF */ | ||
519 | #define PS3_AUDIO_A1_3WMCTRL_ASOEN0_DISABLED \ | ||
520 | PS3_AUDIO_AO_3WMCTRL_ASOEN_DISABLED(1) /* RWI-V */ | ||
521 | #define PS3_AUDIO_A1_3WMCTRL_ASOEN0_ENABLED \ | ||
522 | PS3_AUDIO_AO_3WMCTRL_ASOEN_ENABLED(1) /* RW--V */ | ||
523 | #define PS3_AUDIO_A2_3WMCTRL_ASOEN0 \ | ||
524 | PS3_AUDIO_AO_3WMCTRL_ASOEN(2) /* RWIVF */ | ||
525 | #define PS3_AUDIO_A2_3WMCTRL_ASOEN0_DISABLED \ | ||
526 | PS3_AUDIO_AO_3WMCTRL_ASOEN_DISABLED(2) /* RWI-V */ | ||
527 | #define PS3_AUDIO_A2_3WMCTRL_ASOEN0_ENABLED \ | ||
528 | PS3_AUDIO_AO_3WMCTRL_ASOEN_ENABLED(2) /* RW--V */ | ||
529 | #define PS3_AUDIO_A3_3WMCTRL_ASOEN0 \ | ||
530 | PS3_AUDIO_AO_3WMCTRL_ASOEN(3) /* RWIVF */ | ||
531 | #define PS3_AUDIO_A3_3WMCTRL_ASOEN0_DISABLED \ | ||
532 | PS3_AUDIO_AO_3WMCTRL_ASOEN_DISABLED(3) /* RWI-V */ | ||
533 | #define PS3_AUDIO_A3_3WMCTRL_ASOEN0_ENABLED \ | ||
534 | PS3_AUDIO_AO_3WMCTRL_ASOEN_ENABLED(3) /* RW--V */ | ||
535 | |||
536 | /* | ||
537 | 3-Wire Audio Serial output Channel 0-3 Control Register | ||
538 | Configures settings for 3-Wire Serial Audio Output Channel 0-3 | ||
539 | |||
540 | |||
541 | 31 24 23 16 15 8 7 0 | ||
542 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
543 | |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0|A|0 0 0 0|A|0|ASO|0 0 0|0|0|0|0|0| AO_3WCTRL | ||
544 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
545 | |||
546 | */ | ||
547 | /* | ||
548 | Data Bit Mode | ||
549 | Specifies the number of data bits | ||
550 | 0 - 16 bits | ||
551 | 1 - reserved | ||
552 | 2 - 20 bits | ||
553 | 3 - 24 bits | ||
554 | */ | ||
555 | #define PS3_AUDIO_AO_3WCTRL_ASODB_MASK (0x3 << 8) /* RWIVF */ | ||
556 | #define PS3_AUDIO_AO_3WCTRL_ASODB_16BIT (0x0 << 8) /* RWI-V */ | ||
557 | #define PS3_AUDIO_AO_3WCTRL_ASODB_RESVD (0x1 << 8) /* RWI-V */ | ||
558 | #define PS3_AUDIO_AO_3WCTRL_ASODB_20BIT (0x2 << 8) /* RW--V */ | ||
559 | #define PS3_AUDIO_AO_3WCTRL_ASODB_24BIT (0x3 << 8) /* RW--V */ | ||
560 | /* | ||
561 | Data Format Mode | ||
562 | Specifies the data format where (LSB side or MSB) the data(in 20 bit | ||
563 | or 24 bit resolution mode) is put in a 32 bit field. | ||
564 | 0 - Data put on LSB side | ||
565 | 1 - Data put on MSB side | ||
566 | */ | ||
567 | #define PS3_AUDIO_AO_3WCTRL_ASODF (1 << 11) /* RWIVF */ | ||
568 | #define PS3_AUDIO_AO_3WCTRL_ASODF_LSB (0 << 11) /* RWI-V */ | ||
569 | #define PS3_AUDIO_AO_3WCTRL_ASODF_MSB (1 << 11) /* RW--V */ | ||
570 | /* | ||
571 | Buffer Reset | ||
572 | Performs buffer reset. Writing 1 to this bit initializes the | ||
573 | corresponding 3-Wire Audio Output buffers(both L and R). | ||
574 | */ | ||
575 | #define PS3_AUDIO_AO_3WCTRL_ASOBRST (1 << 16) /* CWIVF */ | ||
576 | #define PS3_AUDIO_AO_3WCTRL_ASOBRST_IDLE (0 << 16) /* -WI-V */ | ||
577 | #define PS3_AUDIO_AO_3WCTRL_ASOBRST_RESET (1 << 16) /* -W--T */ | ||
578 | |||
579 | /* | ||
580 | S/PDIF Audio Output Channel 0/1 Control Register | ||
581 | Configures settings for S/PDIF Audio Output Channel 0/1. | ||
582 | |||
583 | 31 24 23 16 15 8 7 0 | ||
584 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
585 | |S|0 0 0|S|0 0|S| SPOSR |0 0|SPO|0 0 0 0|S|0|SPO|0 0 0 0 0 0 0|S| AO_SPDCTRL | ||
586 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
587 | */ | ||
588 | /* | ||
589 | Buffer reset. Writing 1 to this bit initializes the | ||
590 | corresponding S/PDIF output buffer pointer. | ||
591 | */ | ||
592 | #define PS3_AUDIO_AO_SPDCTRL_SPOBRST (1 << 0) /* CWIVF */ | ||
593 | #define PS3_AUDIO_AO_SPDCTRL_SPOBRST_IDLE (0 << 0) /* -WI-V */ | ||
594 | #define PS3_AUDIO_AO_SPDCTRL_SPOBRST_RESET (1 << 0) /* -W--T */ | ||
595 | |||
596 | /* | ||
597 | Data Bit Mode | ||
598 | Specifies number of data bits | ||
599 | 0 - 16 bits | ||
600 | 1 - Reserved | ||
601 | 2 - 20 bits | ||
602 | 3 - 24 bits | ||
603 | */ | ||
604 | #define PS3_AUDIO_AO_SPDCTRL_SPODB_MASK (0x3 << 8) /* RWIVF */ | ||
605 | #define PS3_AUDIO_AO_SPDCTRL_SPODB_16BIT (0x0 << 8) /* RWI-V */ | ||
606 | #define PS3_AUDIO_AO_SPDCTRL_SPODB_RESVD (0x1 << 8) /* RW--V */ | ||
607 | #define PS3_AUDIO_AO_SPDCTRL_SPODB_20BIT (0x2 << 8) /* RW--V */ | ||
608 | #define PS3_AUDIO_AO_SPDCTRL_SPODB_24BIT (0x3 << 8) /* RW--V */ | ||
609 | /* | ||
610 | Data format Mode | ||
611 | Specifies the data format, where (LSB side or MSB) | ||
612 | the data(in 20 or 24 bit resolution) is put in the | ||
613 | 32 bit field. | ||
614 | 0 - LSB Side | ||
615 | 1 - MSB Side | ||
616 | */ | ||
617 | #define PS3_AUDIO_AO_SPDCTRL_SPODF (1 << 11) /* RWIVF */ | ||
618 | #define PS3_AUDIO_AO_SPDCTRL_SPODF_LSB (0 << 11) /* RWI-V */ | ||
619 | #define PS3_AUDIO_AO_SPDCTRL_SPODF_MSB (1 << 11) /* RW--V */ | ||
620 | /* | ||
621 | Source Select | ||
622 | Specifies the source of the S/PDIF output. When 0, output | ||
623 | operation is controlled by 3wen[0] of AO_3WMCTRL register. | ||
624 | The SR must have the same setting as the a0_3wmctrl reg. | ||
625 | 0 - 3-Wire Audio OUT Ch0 Buffer | ||
626 | 1 - S/PDIF buffer | ||
627 | */ | ||
628 | #define PS3_AUDIO_AO_SPDCTRL_SPOSS_MASK (0x3 << 16) /* RWIVF */ | ||
629 | #define PS3_AUDIO_AO_SPDCTRL_SPOSS_3WEN (0x0 << 16) /* RWI-V */ | ||
630 | #define PS3_AUDIO_AO_SPDCTRL_SPOSS_SPDIF (0x1 << 16) /* RW--V */ | ||
631 | /* | ||
632 | Sampling Rate | ||
633 | Specifies the divide ratio of the bit clock (clock output | ||
634 | from bclko) used by the S/PDIF Output Clock, which | ||
635 | is applied to the master clock selected by mcksel. | ||
636 | */ | ||
637 | #define PS3_AUDIO_AO_SPDCTRL_SPOSR (0xf << 20) /* RWIVF */ | ||
638 | #define PS3_AUDIO_AO_SPDCTRL_SPOSR_DIV2 (0x1 << 20) /* RWI-V */ | ||
639 | #define PS3_AUDIO_AO_SPDCTRL_SPOSR_DIV4 (0x2 << 20) /* RW--V */ | ||
640 | #define PS3_AUDIO_AO_SPDCTRL_SPOSR_DIV8 (0x4 << 20) /* RW--V */ | ||
641 | #define PS3_AUDIO_AO_SPDCTRL_SPOSR_DIV12 (0x6 << 20) /* RW--V */ | ||
642 | /* | ||
643 | Master Clock Select | ||
644 | 0 - Master Clock 0 | ||
645 | 1 - Master Clock 1 | ||
646 | */ | ||
647 | #define PS3_AUDIO_AO_SPDCTRL_SPOMCKSEL (1 << 24) /* RWIVF */ | ||
648 | #define PS3_AUDIO_AO_SPDCTRL_SPOMCKSEL_CLK0 (0 << 24) /* RWI-V */ | ||
649 | #define PS3_AUDIO_AO_SPDCTRL_SPOMCKSEL_CLK1 (1 << 24) /* RW--V */ | ||
650 | |||
651 | /* | ||
652 | S/PDIF Output Channel Operational Status | ||
653 | This bit becomes 1 after S/PDIF Output Channel is in | ||
654 | action by setting 1 to spoen. This bit becomes 0 | ||
655 | after S/PDIF Output Channel is out of action by setting | ||
656 | 0 to spoen. | ||
657 | */ | ||
658 | #define PS3_AUDIO_AO_SPDCTRL_SPORUN (1 << 27) /* R-IVF */ | ||
659 | #define PS3_AUDIO_AO_SPDCTRL_SPORUN_STOPPED (0 << 27) /* R-I-V */ | ||
660 | #define PS3_AUDIO_AO_SPDCTRL_SPORUN_RUNNING (1 << 27) /* R---V */ | ||
661 | |||
662 | /* | ||
663 | S/PDIF Audio Output Channel Output Enable | ||
664 | Enables and disables output operation. This bit is used | ||
665 | only when sposs = 1 | ||
666 | */ | ||
667 | #define PS3_AUDIO_AO_SPDCTRL_SPOEN (1 << 31) /* RWIVF */ | ||
668 | #define PS3_AUDIO_AO_SPDCTRL_SPOEN_DISABLED (0 << 31) /* RWI-V */ | ||
669 | #define PS3_AUDIO_AO_SPDCTRL_SPOEN_ENABLED (1 << 31) /* RW--V */ | ||
670 | |||
671 | /* | ||
672 | S/PDIF Audio Output Channel Channel Status | ||
673 | Setting Registers. | ||
674 | Configures channel status bit settings for each block | ||
675 | (192 bits). | ||
676 | Output is performed from the MSB(AO_SPDCS0 register bit 31). | ||
677 | The same value is added for subframes within the same frame. | ||
678 | 31 24 23 16 15 8 7 0 | ||
679 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
680 | | SPOCS | AO_SPDCS | ||
681 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
682 | |||
683 | S/PDIF Audio Output Channel User Bit Setting | ||
684 | Configures user bit settings for each block (384 bits). | ||
685 | Output is performed from the MSB(ao_spdub0 register bit 31). | ||
686 | |||
687 | |||
688 | 31 24 23 16 15 8 7 0 | ||
689 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
690 | | SPOUB | AO_SPDUB | ||
691 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
692 | */ | ||
693 | /***************************************************************************** | ||
694 | * | ||
695 | * DMAC register | ||
696 | * | ||
697 | *****************************************************************************/ | ||
698 | /* | ||
699 | The PS3_AUDIO_KICK register is used to initiate a DMA transfer and monitor | ||
700 | its status | ||
701 | |||
702 | 31 24 23 16 15 8 7 0 | ||
703 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
704 | |0 0 0 0 0|STATU|0 0 0| EVENT |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0|R| KICK | ||
705 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
706 | */ | ||
707 | /* | ||
708 | The REQUEST field is written to ACTIVE to initiate a DMA request when EVENT | ||
709 | occurs. | ||
710 | It will return to the DONE state when the request is completed. | ||
711 | The registers for a DMA channel should only be written if REQUEST is IDLE. | ||
712 | */ | ||
713 | |||
714 | #define PS3_AUDIO_KICK_REQUEST (1 << 0) /* RWIVF */ | ||
715 | #define PS3_AUDIO_KICK_REQUEST_IDLE (0 << 0) /* RWI-V */ | ||
716 | #define PS3_AUDIO_KICK_REQUEST_ACTIVE (1 << 0) /* -W--T */ | ||
717 | |||
718 | /* | ||
719 | *The EVENT field is used to set the event in which | ||
720 | *the DMA request becomes active. | ||
721 | */ | ||
722 | #define PS3_AUDIO_KICK_EVENT_MASK (0x1f << 16) /* RWIVF */ | ||
723 | #define PS3_AUDIO_KICK_EVENT_ALWAYS (0x00 << 16) /* RWI-V */ | ||
724 | #define PS3_AUDIO_KICK_EVENT_SERIALOUT0_EMPTY (0x01 << 16) /* RW--V */ | ||
725 | #define PS3_AUDIO_KICK_EVENT_SERIALOUT0_UNDERFLOW (0x02 << 16) /* RW--V */ | ||
726 | #define PS3_AUDIO_KICK_EVENT_SERIALOUT1_EMPTY (0x03 << 16) /* RW--V */ | ||
727 | #define PS3_AUDIO_KICK_EVENT_SERIALOUT1_UNDERFLOW (0x04 << 16) /* RW--V */ | ||
728 | #define PS3_AUDIO_KICK_EVENT_SERIALOUT2_EMPTY (0x05 << 16) /* RW--V */ | ||
729 | #define PS3_AUDIO_KICK_EVENT_SERIALOUT2_UNDERFLOW (0x06 << 16) /* RW--V */ | ||
730 | #define PS3_AUDIO_KICK_EVENT_SERIALOUT3_EMPTY (0x07 << 16) /* RW--V */ | ||
731 | #define PS3_AUDIO_KICK_EVENT_SERIALOUT3_UNDERFLOW (0x08 << 16) /* RW--V */ | ||
732 | #define PS3_AUDIO_KICK_EVENT_SPDIF0_BLOCKTRANSFERCOMPLETE \ | ||
733 | (0x09 << 16) /* RW--V */ | ||
734 | #define PS3_AUDIO_KICK_EVENT_SPDIF0_UNDERFLOW (0x0A << 16) /* RW--V */ | ||
735 | #define PS3_AUDIO_KICK_EVENT_SPDIF0_EMPTY (0x0B << 16) /* RW--V */ | ||
736 | #define PS3_AUDIO_KICK_EVENT_SPDIF1_BLOCKTRANSFERCOMPLETE \ | ||
737 | (0x0C << 16) /* RW--V */ | ||
738 | #define PS3_AUDIO_KICK_EVENT_SPDIF1_UNDERFLOW (0x0D << 16) /* RW--V */ | ||
739 | #define PS3_AUDIO_KICK_EVENT_SPDIF1_EMPTY (0x0E << 16) /* RW--V */ | ||
740 | |||
741 | #define PS3_AUDIO_KICK_EVENT_AUDIO_DMA(n) \ | ||
742 | ((0x13 + (n)) << 16) /* RW--V */ | ||
743 | #define PS3_AUDIO_KICK_EVENT_AUDIO_DMA0 (0x13 << 16) /* RW--V */ | ||
744 | #define PS3_AUDIO_KICK_EVENT_AUDIO_DMA1 (0x14 << 16) /* RW--V */ | ||
745 | #define PS3_AUDIO_KICK_EVENT_AUDIO_DMA2 (0x15 << 16) /* RW--V */ | ||
746 | #define PS3_AUDIO_KICK_EVENT_AUDIO_DMA3 (0x16 << 16) /* RW--V */ | ||
747 | #define PS3_AUDIO_KICK_EVENT_AUDIO_DMA4 (0x17 << 16) /* RW--V */ | ||
748 | #define PS3_AUDIO_KICK_EVENT_AUDIO_DMA5 (0x18 << 16) /* RW--V */ | ||
749 | #define PS3_AUDIO_KICK_EVENT_AUDIO_DMA6 (0x19 << 16) /* RW--V */ | ||
750 | #define PS3_AUDIO_KICK_EVENT_AUDIO_DMA7 (0x1A << 16) /* RW--V */ | ||
751 | #define PS3_AUDIO_KICK_EVENT_AUDIO_DMA8 (0x1B << 16) /* RW--V */ | ||
752 | #define PS3_AUDIO_KICK_EVENT_AUDIO_DMA9 (0x1C << 16) /* RW--V */ | ||
753 | |||
754 | /* | ||
755 | The STATUS field can be used to monitor the progress of a DMA request. | ||
756 | DONE indicates the previous request has completed. | ||
757 | EVENT indicates that the DMA engine is waiting for the EVENT to occur. | ||
758 | PENDING indicates that the DMA engine has not started processing this | ||
759 | request, but the EVENT has occured. | ||
760 | DMA indicates that the data transfer is in progress. | ||
761 | NOTIFY indicates that the notifier signalling end of transfer is being written. | ||
762 | CLEAR indicated that the previous transfer was cleared. | ||
763 | ERROR indicates the previous transfer requested an unsupported | ||
764 | source/destination combination. | ||
765 | */ | ||
766 | |||
767 | #define PS3_AUDIO_KICK_STATUS_MASK (0x7 << 24) /* R-IVF */ | ||
768 | #define PS3_AUDIO_KICK_STATUS_DONE (0x0 << 24) /* R-I-V */ | ||
769 | #define PS3_AUDIO_KICK_STATUS_EVENT (0x1 << 24) /* R---V */ | ||
770 | #define PS3_AUDIO_KICK_STATUS_PENDING (0x2 << 24) /* R---V */ | ||
771 | #define PS3_AUDIO_KICK_STATUS_DMA (0x3 << 24) /* R---V */ | ||
772 | #define PS3_AUDIO_KICK_STATUS_NOTIFY (0x4 << 24) /* R---V */ | ||
773 | #define PS3_AUDIO_KICK_STATUS_CLEAR (0x5 << 24) /* R---V */ | ||
774 | #define PS3_AUDIO_KICK_STATUS_ERROR (0x6 << 24) /* R---V */ | ||
775 | |||
776 | /* | ||
777 | The PS3_AUDIO_SOURCE register specifies the source address for transfers. | ||
778 | |||
779 | |||
780 | 31 24 23 16 15 8 7 0 | ||
781 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
782 | | START |0 0 0 0 0|TAR| SOURCE | ||
783 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
784 | */ | ||
785 | |||
786 | /* | ||
787 | The Audio DMA engine uses 128-byte transfers, thus the address must be aligned | ||
788 | to a 128 byte boundary. The low seven bits are assumed to be 0. | ||
789 | */ | ||
790 | |||
791 | #define PS3_AUDIO_SOURCE_START_MASK (0x01FFFFFF << 7) /* RWIUF */ | ||
792 | |||
793 | /* | ||
794 | The TARGET field specifies the memory space containing the source address. | ||
795 | */ | ||
796 | |||
797 | #define PS3_AUDIO_SOURCE_TARGET_MASK (3 << 0) /* RWIVF */ | ||
798 | #define PS3_AUDIO_SOURCE_TARGET_SYSTEM_MEMORY (2 << 0) /* RW--V */ | ||
799 | |||
800 | /* | ||
801 | The PS3_AUDIO_DEST register specifies the destination address for transfers. | ||
802 | |||
803 | |||
804 | 31 24 23 16 15 8 7 0 | ||
805 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
806 | | START |0 0 0 0 0|TAR| DEST | ||
807 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
808 | */ | ||
809 | |||
810 | /* | ||
811 | The Audio DMA engine uses 128-byte transfers, thus the address must be aligned | ||
812 | to a 128 byte boundary. The low seven bits are assumed to be 0. | ||
813 | */ | ||
814 | |||
815 | #define PS3_AUDIO_DEST_START_MASK (0x01FFFFFF << 7) /* RWIUF */ | ||
816 | |||
817 | /* | ||
818 | The TARGET field specifies the memory space containing the destination address | ||
819 | AUDIOFIFO = Audio WriteData FIFO, | ||
820 | */ | ||
821 | |||
822 | #define PS3_AUDIO_DEST_TARGET_MASK (3 << 0) /* RWIVF */ | ||
823 | #define PS3_AUDIO_DEST_TARGET_AUDIOFIFO (1 << 0) /* RW--V */ | ||
824 | |||
825 | /* | ||
826 | PS3_AUDIO_DMASIZE specifies the number of 128-byte blocks + 1 to transfer. | ||
827 | So a value of 0 means 128-bytes will get transfered. | ||
828 | |||
829 | |||
830 | 31 24 23 16 15 8 7 0 | ||
831 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
832 | |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0| BLOCKS | DMASIZE | ||
833 | +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ | ||
834 | */ | ||
835 | |||
836 | |||
837 | #define PS3_AUDIO_DMASIZE_BLOCKS_MASK (0x7f << 0) /* RWIUF */ | ||
838 | |||
839 | /* | ||
840 | * source/destination address for internal fifos | ||
841 | */ | ||
842 | #define PS3_AUDIO_AO_3W_LDATA(n) (0x1000 + (0x100 * (n))) | ||
843 | #define PS3_AUDIO_AO_3W_RDATA(n) (0x1080 + (0x100 * (n))) | ||
844 | |||
845 | #define PS3_AUDIO_AO_SPD_DATA(n) (0x2000 + (0x400 * (n))) | ||
846 | |||
847 | |||
848 | /* | ||
849 | * field attiribute | ||
850 | * | ||
851 | * Read | ||
852 | * ' ' = Other Information | ||
853 | * '-' = Field is part of a write-only register | ||
854 | * 'C' = Value read is always the same, constant value line follows (C) | ||
855 | * 'R' = Value is read | ||
856 | * | ||
857 | * Write | ||
858 | * ' ' = Other Information | ||
859 | * '-' = Must not be written (D), value ignored when written (R,A,F) | ||
860 | * 'W' = Can be written | ||
861 | * | ||
862 | * Internal State | ||
863 | * ' ' = Other Information | ||
864 | * '-' = No internal state | ||
865 | * 'X' = Internal state, initial value is unknown | ||
866 | * 'I' = Internal state, initial value is known and follows (I) | ||
867 | * | ||
868 | * Declaration/Size | ||
869 | * ' ' = Other Information | ||
870 | * '-' = Does Not Apply | ||
871 | * 'V' = Type is void | ||
872 | * 'U' = Type is unsigned integer | ||
873 | * 'S' = Type is signed integer | ||
874 | * 'F' = Type is IEEE floating point | ||
875 | * '1' = Byte size (008) | ||
876 | * '2' = Short size (016) | ||
877 | * '3' = Three byte size (024) | ||
878 | * '4' = Word size (032) | ||
879 | * '8' = Double size (064) | ||
880 | * | ||
881 | * Define Indicator | ||
882 | * ' ' = Other Information | ||
883 | * 'D' = Device | ||
884 | * 'M' = Memory | ||
885 | * 'R' = Register | ||
886 | * 'A' = Array of Registers | ||
887 | * 'F' = Field | ||
888 | * 'V' = Value | ||
889 | * 'T' = Task | ||
890 | */ | ||
891 | |||
diff --git a/sound/sh/Kconfig b/sound/sh/Kconfig new file mode 100644 index 000000000000..b7e08ef22a94 --- /dev/null +++ b/sound/sh/Kconfig | |||
@@ -0,0 +1,14 @@ | |||
1 | # ALSA SH drivers | ||
2 | |||
3 | menu "SUPERH devices" | ||
4 | depends on SND!=n && SUPERH | ||
5 | |||
6 | config SND_AICA | ||
7 | tristate "Dreamcast Yamaha AICA sound" | ||
8 | depends on SH_DREAMCAST && SND | ||
9 | select SND_PCM | ||
10 | help | ||
11 | ALSA Sound driver for the SEGA Dreamcast console. | ||
12 | |||
13 | endmenu | ||
14 | |||
diff --git a/sound/sh/Makefile b/sound/sh/Makefile new file mode 100644 index 000000000000..8fdcb6e26f00 --- /dev/null +++ b/sound/sh/Makefile | |||
@@ -0,0 +1,8 @@ | |||
1 | # | ||
2 | # Makefile for ALSA | ||
3 | # | ||
4 | |||
5 | snd-aica-objs := aica.o | ||
6 | |||
7 | # Toplevel Module Dependency | ||
8 | obj-$(CONFIG_SND_AICA) += snd-aica.o | ||
diff --git a/sound/sh/aica.c b/sound/sh/aica.c new file mode 100644 index 000000000000..739786529ca5 --- /dev/null +++ b/sound/sh/aica.c | |||
@@ -0,0 +1,665 @@ | |||
1 | /* | ||
2 | * This code is licenced under | ||
3 | * the General Public Licence | ||
4 | * version 2 | ||
5 | * | ||
6 | * Copyright Adrian McMenamin 2005, 2006, 2007 | ||
7 | * <adrian@mcmen.demon.co.uk> | ||
8 | * Requires firmware (BSD licenced) available from: | ||
9 | * http://linuxdc.cvs.sourceforge.net/linuxdc/linux-sh-dc/sound/oss/aica/firmware/ | ||
10 | * or the maintainer | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of version 2 of the GNU General Public License as published by | ||
14 | * 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 | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | #include <linux/init.h> | ||
28 | #include <linux/jiffies.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/time.h> | ||
31 | #include <linux/wait.h> | ||
32 | #include <linux/moduleparam.h> | ||
33 | #include <linux/platform_device.h> | ||
34 | #include <linux/firmware.h> | ||
35 | #include <linux/timer.h> | ||
36 | #include <linux/delay.h> | ||
37 | #include <linux/workqueue.h> | ||
38 | #include <sound/driver.h> | ||
39 | #include <sound/core.h> | ||
40 | #include <sound/control.h> | ||
41 | #include <sound/pcm.h> | ||
42 | #include <sound/initval.h> | ||
43 | #include <sound/info.h> | ||
44 | #include <asm/io.h> | ||
45 | #include <asm/dma.h> | ||
46 | #include <asm/dreamcast/sysasic.h> | ||
47 | #include "aica.h" | ||
48 | |||
49 | MODULE_AUTHOR("Adrian McMenamin <adrian@mcmen.demon.co.uk>"); | ||
50 | MODULE_DESCRIPTION("Dreamcast AICA sound (pcm) driver"); | ||
51 | MODULE_LICENSE("GPL"); | ||
52 | MODULE_SUPPORTED_DEVICE("{{Yamaha/SEGA, AICA}}"); | ||
53 | |||
54 | /* module parameters */ | ||
55 | #define CARD_NAME "AICA" | ||
56 | static int index = -1; | ||
57 | static char *id; | ||
58 | static int enable = 1; | ||
59 | module_param(index, int, 0444); | ||
60 | MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard."); | ||
61 | module_param(id, charp, 0444); | ||
62 | MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard."); | ||
63 | module_param(enable, bool, 0644); | ||
64 | MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard."); | ||
65 | |||
66 | /* Use workqueue */ | ||
67 | static struct workqueue_struct *aica_queue; | ||
68 | |||
69 | /* Simple platform device */ | ||
70 | static struct platform_device *pd; | ||
71 | static struct resource aica_memory_space[2] = { | ||
72 | { | ||
73 | .name = "AICA ARM CONTROL", | ||
74 | .start = ARM_RESET_REGISTER, | ||
75 | .flags = IORESOURCE_MEM, | ||
76 | .end = ARM_RESET_REGISTER + 3, | ||
77 | }, | ||
78 | { | ||
79 | .name = "AICA Sound RAM", | ||
80 | .start = SPU_MEMORY_BASE, | ||
81 | .flags = IORESOURCE_MEM, | ||
82 | .end = SPU_MEMORY_BASE + 0x200000 - 1, | ||
83 | }, | ||
84 | }; | ||
85 | |||
86 | /* SPU specific functions */ | ||
87 | /* spu_write_wait - wait for G2-SH FIFO to clear */ | ||
88 | static void spu_write_wait(void) | ||
89 | { | ||
90 | int time_count; | ||
91 | time_count = 0; | ||
92 | while (1) { | ||
93 | if (!(readl(G2_FIFO) & 0x11)) | ||
94 | break; | ||
95 | /* To ensure hardware failure doesn't wedge kernel */ | ||
96 | time_count++; | ||
97 | if (time_count > 0x10000) { | ||
98 | snd_printk | ||
99 | ("WARNING: G2 FIFO appears to be blocked.\n"); | ||
100 | break; | ||
101 | } | ||
102 | } | ||
103 | } | ||
104 | |||
105 | /* spu_memset - write to memory in SPU address space */ | ||
106 | static void spu_memset(u32 toi, u32 what, int length) | ||
107 | { | ||
108 | int i; | ||
109 | snd_assert(length % 4 == 0, return); | ||
110 | for (i = 0; i < length; i++) { | ||
111 | if (!(i % 8)) | ||
112 | spu_write_wait(); | ||
113 | writel(what, toi + SPU_MEMORY_BASE); | ||
114 | toi++; | ||
115 | } | ||
116 | } | ||
117 | |||
118 | /* spu_memload - write to SPU address space */ | ||
119 | static void spu_memload(u32 toi, void *from, int length) | ||
120 | { | ||
121 | u32 *froml = from; | ||
122 | u32 __iomem *to = (u32 __iomem *) (SPU_MEMORY_BASE + toi); | ||
123 | int i; | ||
124 | u32 val; | ||
125 | length = DIV_ROUND_UP(length, 4); | ||
126 | spu_write_wait(); | ||
127 | for (i = 0; i < length; i++) { | ||
128 | if (!(i % 8)) | ||
129 | spu_write_wait(); | ||
130 | val = *froml; | ||
131 | writel(val, to); | ||
132 | froml++; | ||
133 | to++; | ||
134 | } | ||
135 | } | ||
136 | |||
137 | /* spu_disable - set spu registers to stop sound output */ | ||
138 | static void spu_disable(void) | ||
139 | { | ||
140 | int i; | ||
141 | u32 regval; | ||
142 | spu_write_wait(); | ||
143 | regval = readl(ARM_RESET_REGISTER); | ||
144 | regval |= 1; | ||
145 | spu_write_wait(); | ||
146 | writel(regval, ARM_RESET_REGISTER); | ||
147 | for (i = 0; i < 64; i++) { | ||
148 | spu_write_wait(); | ||
149 | regval = readl(SPU_REGISTER_BASE + (i * 0x80)); | ||
150 | regval = (regval & ~0x4000) | 0x8000; | ||
151 | spu_write_wait(); | ||
152 | writel(regval, SPU_REGISTER_BASE + (i * 0x80)); | ||
153 | } | ||
154 | } | ||
155 | |||
156 | /* spu_enable - set spu registers to enable sound output */ | ||
157 | static void spu_enable(void) | ||
158 | { | ||
159 | u32 regval = readl(ARM_RESET_REGISTER); | ||
160 | regval &= ~1; | ||
161 | spu_write_wait(); | ||
162 | writel(regval, ARM_RESET_REGISTER); | ||
163 | } | ||
164 | |||
165 | /* | ||
166 | * Halt the sound processor, clear the memory, | ||
167 | * load some default ARM7 code, and then restart ARM7 | ||
168 | */ | ||
169 | static void spu_reset(void) | ||
170 | { | ||
171 | spu_disable(); | ||
172 | spu_memset(0, 0, 0x200000 / 4); | ||
173 | /* Put ARM7 in endless loop */ | ||
174 | ctrl_outl(0xea000002, SPU_MEMORY_BASE); | ||
175 | spu_enable(); | ||
176 | } | ||
177 | |||
178 | /* aica_chn_start - write to spu to start playback */ | ||
179 | static void aica_chn_start(void) | ||
180 | { | ||
181 | spu_write_wait(); | ||
182 | writel(AICA_CMD_KICK | AICA_CMD_START, (u32 *) AICA_CONTROL_POINT); | ||
183 | } | ||
184 | |||
185 | /* aica_chn_halt - write to spu to halt playback */ | ||
186 | static void aica_chn_halt(void) | ||
187 | { | ||
188 | spu_write_wait(); | ||
189 | writel(AICA_CMD_KICK | AICA_CMD_STOP, (u32 *) AICA_CONTROL_POINT); | ||
190 | } | ||
191 | |||
192 | /* ALSA code below */ | ||
193 | static struct snd_pcm_hardware snd_pcm_aica_playback_hw = { | ||
194 | .info = (SNDRV_PCM_INFO_NONINTERLEAVED), | ||
195 | .formats = | ||
196 | (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | | ||
197 | SNDRV_PCM_FMTBIT_IMA_ADPCM), | ||
198 | .rates = SNDRV_PCM_RATE_8000_48000, | ||
199 | .rate_min = 8000, | ||
200 | .rate_max = 48000, | ||
201 | .channels_min = 1, | ||
202 | .channels_max = 2, | ||
203 | .buffer_bytes_max = AICA_BUFFER_SIZE, | ||
204 | .period_bytes_min = AICA_PERIOD_SIZE, | ||
205 | .period_bytes_max = AICA_PERIOD_SIZE, | ||
206 | .periods_min = AICA_PERIOD_NUMBER, | ||
207 | .periods_max = AICA_PERIOD_NUMBER, | ||
208 | }; | ||
209 | |||
210 | static int aica_dma_transfer(int channels, int buffer_size, | ||
211 | struct snd_pcm_substream *substream) | ||
212 | { | ||
213 | int q, err, period_offset; | ||
214 | struct snd_card_aica *dreamcastcard; | ||
215 | struct snd_pcm_runtime *runtime; | ||
216 | err = 0; | ||
217 | dreamcastcard = substream->pcm->private_data; | ||
218 | period_offset = dreamcastcard->clicks; | ||
219 | period_offset %= (AICA_PERIOD_NUMBER / channels); | ||
220 | runtime = substream->runtime; | ||
221 | for (q = 0; q < channels; q++) { | ||
222 | err = dma_xfer(AICA_DMA_CHANNEL, | ||
223 | (unsigned long) (runtime->dma_area + | ||
224 | (AICA_BUFFER_SIZE * q) / | ||
225 | channels + | ||
226 | AICA_PERIOD_SIZE * | ||
227 | period_offset), | ||
228 | AICA_CHANNEL0_OFFSET + q * CHANNEL_OFFSET + | ||
229 | AICA_PERIOD_SIZE * period_offset, | ||
230 | buffer_size / channels, AICA_DMA_MODE); | ||
231 | if (unlikely(err < 0)) | ||
232 | break; | ||
233 | dma_wait_for_completion(AICA_DMA_CHANNEL); | ||
234 | } | ||
235 | return err; | ||
236 | } | ||
237 | |||
238 | static void startup_aica(struct snd_card_aica *dreamcastcard) | ||
239 | { | ||
240 | spu_memload(AICA_CHANNEL0_CONTROL_OFFSET, | ||
241 | dreamcastcard->channel, sizeof(struct aica_channel)); | ||
242 | aica_chn_start(); | ||
243 | } | ||
244 | |||
245 | static void run_spu_dma(struct work_struct *work) | ||
246 | { | ||
247 | int buffer_size; | ||
248 | struct snd_pcm_runtime *runtime; | ||
249 | struct snd_card_aica *dreamcastcard; | ||
250 | dreamcastcard = | ||
251 | container_of(work, struct snd_card_aica, spu_dma_work); | ||
252 | runtime = dreamcastcard->substream->runtime; | ||
253 | if (unlikely(dreamcastcard->dma_check == 0)) { | ||
254 | buffer_size = | ||
255 | frames_to_bytes(runtime, runtime->buffer_size); | ||
256 | if (runtime->channels > 1) | ||
257 | dreamcastcard->channel->flags |= 0x01; | ||
258 | aica_dma_transfer(runtime->channels, buffer_size, | ||
259 | dreamcastcard->substream); | ||
260 | startup_aica(dreamcastcard); | ||
261 | dreamcastcard->clicks = | ||
262 | buffer_size / (AICA_PERIOD_SIZE * runtime->channels); | ||
263 | return; | ||
264 | } else { | ||
265 | aica_dma_transfer(runtime->channels, | ||
266 | AICA_PERIOD_SIZE * runtime->channels, | ||
267 | dreamcastcard->substream); | ||
268 | snd_pcm_period_elapsed(dreamcastcard->substream); | ||
269 | dreamcastcard->clicks++; | ||
270 | if (unlikely(dreamcastcard->clicks >= AICA_PERIOD_NUMBER)) | ||
271 | dreamcastcard->clicks %= AICA_PERIOD_NUMBER; | ||
272 | mod_timer(&dreamcastcard->timer, jiffies + 1); | ||
273 | } | ||
274 | } | ||
275 | |||
276 | static void aica_period_elapsed(unsigned long timer_var) | ||
277 | { | ||
278 | /*timer function - so cannot sleep */ | ||
279 | int play_period; | ||
280 | struct snd_pcm_runtime *runtime; | ||
281 | struct snd_pcm_substream *substream; | ||
282 | struct snd_card_aica *dreamcastcard; | ||
283 | substream = (struct snd_pcm_substream *) timer_var; | ||
284 | runtime = substream->runtime; | ||
285 | dreamcastcard = substream->pcm->private_data; | ||
286 | /* Have we played out an additional period? */ | ||
287 | play_period = | ||
288 | frames_to_bytes(runtime, | ||
289 | readl | ||
290 | (AICA_CONTROL_CHANNEL_SAMPLE_NUMBER)) / | ||
291 | AICA_PERIOD_SIZE; | ||
292 | if (play_period == dreamcastcard->current_period) { | ||
293 | /* reschedule the timer */ | ||
294 | mod_timer(&(dreamcastcard->timer), jiffies + 1); | ||
295 | return; | ||
296 | } | ||
297 | if (runtime->channels > 1) | ||
298 | dreamcastcard->current_period = play_period; | ||
299 | if (unlikely(dreamcastcard->dma_check == 0)) | ||
300 | dreamcastcard->dma_check = 1; | ||
301 | queue_work(aica_queue, &(dreamcastcard->spu_dma_work)); | ||
302 | } | ||
303 | |||
304 | static void spu_begin_dma(struct snd_pcm_substream *substream) | ||
305 | { | ||
306 | struct snd_card_aica *dreamcastcard; | ||
307 | struct snd_pcm_runtime *runtime; | ||
308 | runtime = substream->runtime; | ||
309 | dreamcastcard = substream->pcm->private_data; | ||
310 | /*get the queue to do the work */ | ||
311 | queue_work(aica_queue, &(dreamcastcard->spu_dma_work)); | ||
312 | /* Timer may already be running */ | ||
313 | if (unlikely(dreamcastcard->timer.data)) { | ||
314 | mod_timer(&dreamcastcard->timer, jiffies + 4); | ||
315 | return; | ||
316 | } | ||
317 | init_timer(&(dreamcastcard->timer)); | ||
318 | dreamcastcard->timer.data = (unsigned long) substream; | ||
319 | dreamcastcard->timer.function = aica_period_elapsed; | ||
320 | dreamcastcard->timer.expires = jiffies + 4; | ||
321 | add_timer(&(dreamcastcard->timer)); | ||
322 | } | ||
323 | |||
324 | static int snd_aicapcm_pcm_open(struct snd_pcm_substream | ||
325 | *substream) | ||
326 | { | ||
327 | struct snd_pcm_runtime *runtime; | ||
328 | struct aica_channel *channel; | ||
329 | struct snd_card_aica *dreamcastcard; | ||
330 | if (!enable) | ||
331 | return -ENOENT; | ||
332 | dreamcastcard = substream->pcm->private_data; | ||
333 | channel = kmalloc(sizeof(struct aica_channel), GFP_KERNEL); | ||
334 | if (!channel) | ||
335 | return -ENOMEM; | ||
336 | /* set defaults for channel */ | ||
337 | channel->sfmt = SM_8BIT; | ||
338 | channel->cmd = AICA_CMD_START; | ||
339 | channel->vol = dreamcastcard->master_volume; | ||
340 | channel->pan = 0x80; | ||
341 | channel->pos = 0; | ||
342 | channel->flags = 0; /* default to mono */ | ||
343 | dreamcastcard->channel = channel; | ||
344 | runtime = substream->runtime; | ||
345 | runtime->hw = snd_pcm_aica_playback_hw; | ||
346 | spu_enable(); | ||
347 | dreamcastcard->clicks = 0; | ||
348 | dreamcastcard->current_period = 0; | ||
349 | dreamcastcard->dma_check = 0; | ||
350 | return 0; | ||
351 | } | ||
352 | |||
353 | static int snd_aicapcm_pcm_close(struct snd_pcm_substream | ||
354 | *substream) | ||
355 | { | ||
356 | struct snd_card_aica *dreamcastcard = substream->pcm->private_data; | ||
357 | flush_workqueue(aica_queue); | ||
358 | if (dreamcastcard->timer.data) | ||
359 | del_timer(&dreamcastcard->timer); | ||
360 | kfree(dreamcastcard->channel); | ||
361 | spu_disable(); | ||
362 | return 0; | ||
363 | } | ||
364 | |||
365 | static int snd_aicapcm_pcm_hw_free(struct snd_pcm_substream | ||
366 | *substream) | ||
367 | { | ||
368 | /* Free the DMA buffer */ | ||
369 | return snd_pcm_lib_free_pages(substream); | ||
370 | } | ||
371 | |||
372 | static int snd_aicapcm_pcm_hw_params(struct snd_pcm_substream | ||
373 | *substream, struct snd_pcm_hw_params | ||
374 | *hw_params) | ||
375 | { | ||
376 | /* Allocate a DMA buffer using ALSA built-ins */ | ||
377 | return | ||
378 | snd_pcm_lib_malloc_pages(substream, | ||
379 | params_buffer_bytes(hw_params)); | ||
380 | } | ||
381 | |||
382 | static int snd_aicapcm_pcm_prepare(struct snd_pcm_substream | ||
383 | *substream) | ||
384 | { | ||
385 | struct snd_card_aica *dreamcastcard = substream->pcm->private_data; | ||
386 | if ((substream->runtime)->format == SNDRV_PCM_FORMAT_S16_LE) | ||
387 | dreamcastcard->channel->sfmt = SM_16BIT; | ||
388 | dreamcastcard->channel->freq = substream->runtime->rate; | ||
389 | dreamcastcard->substream = substream; | ||
390 | return 0; | ||
391 | } | ||
392 | |||
393 | static int snd_aicapcm_pcm_trigger(struct snd_pcm_substream | ||
394 | *substream, int cmd) | ||
395 | { | ||
396 | switch (cmd) { | ||
397 | case SNDRV_PCM_TRIGGER_START: | ||
398 | spu_begin_dma(substream); | ||
399 | break; | ||
400 | case SNDRV_PCM_TRIGGER_STOP: | ||
401 | aica_chn_halt(); | ||
402 | break; | ||
403 | default: | ||
404 | return -EINVAL; | ||
405 | } | ||
406 | return 0; | ||
407 | } | ||
408 | |||
409 | static unsigned long snd_aicapcm_pcm_pointer(struct snd_pcm_substream | ||
410 | *substream) | ||
411 | { | ||
412 | return readl(AICA_CONTROL_CHANNEL_SAMPLE_NUMBER); | ||
413 | } | ||
414 | |||
415 | static struct snd_pcm_ops snd_aicapcm_playback_ops = { | ||
416 | .open = snd_aicapcm_pcm_open, | ||
417 | .close = snd_aicapcm_pcm_close, | ||
418 | .ioctl = snd_pcm_lib_ioctl, | ||
419 | .hw_params = snd_aicapcm_pcm_hw_params, | ||
420 | .hw_free = snd_aicapcm_pcm_hw_free, | ||
421 | .prepare = snd_aicapcm_pcm_prepare, | ||
422 | .trigger = snd_aicapcm_pcm_trigger, | ||
423 | .pointer = snd_aicapcm_pcm_pointer, | ||
424 | }; | ||
425 | |||
426 | /* TO DO: set up to handle more than one pcm instance */ | ||
427 | static int __init snd_aicapcmchip(struct snd_card_aica | ||
428 | *dreamcastcard, int pcm_index) | ||
429 | { | ||
430 | struct snd_pcm *pcm; | ||
431 | int err; | ||
432 | /* AICA has no capture ability */ | ||
433 | err = | ||
434 | snd_pcm_new(dreamcastcard->card, "AICA PCM", pcm_index, 1, 0, | ||
435 | &pcm); | ||
436 | if (unlikely(err < 0)) | ||
437 | return err; | ||
438 | pcm->private_data = dreamcastcard; | ||
439 | strcpy(pcm->name, "AICA PCM"); | ||
440 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, | ||
441 | &snd_aicapcm_playback_ops); | ||
442 | /* Allocate the DMA buffers */ | ||
443 | err = | ||
444 | snd_pcm_lib_preallocate_pages_for_all(pcm, | ||
445 | SNDRV_DMA_TYPE_CONTINUOUS, | ||
446 | snd_dma_continuous_data | ||
447 | (GFP_KERNEL), | ||
448 | AICA_BUFFER_SIZE, | ||
449 | AICA_BUFFER_SIZE); | ||
450 | return err; | ||
451 | } | ||
452 | |||
453 | /* Mixer controls */ | ||
454 | static int aica_pcmswitch_info(struct snd_kcontrol *kcontrol, | ||
455 | struct snd_ctl_elem_info *uinfo) | ||
456 | { | ||
457 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
458 | uinfo->count = 1; | ||
459 | uinfo->value.integer.min = 0; | ||
460 | uinfo->value.integer.max = 1; | ||
461 | return 0; | ||
462 | } | ||
463 | |||
464 | static int aica_pcmswitch_get(struct snd_kcontrol *kcontrol, | ||
465 | struct snd_ctl_elem_value *ucontrol) | ||
466 | { | ||
467 | ucontrol->value.integer.value[0] = 1; /* TO DO: Fix me */ | ||
468 | return 0; | ||
469 | } | ||
470 | |||
471 | static int aica_pcmswitch_put(struct snd_kcontrol *kcontrol, | ||
472 | struct snd_ctl_elem_value *ucontrol) | ||
473 | { | ||
474 | if (ucontrol->value.integer.value[0] == 1) | ||
475 | return 0; /* TO DO: Fix me */ | ||
476 | else | ||
477 | aica_chn_halt(); | ||
478 | return 0; | ||
479 | } | ||
480 | |||
481 | static int aica_pcmvolume_info(struct snd_kcontrol *kcontrol, | ||
482 | struct snd_ctl_elem_info *uinfo) | ||
483 | { | ||
484 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
485 | uinfo->count = 1; | ||
486 | uinfo->value.integer.min = 0; | ||
487 | uinfo->value.integer.max = 0xFF; | ||
488 | return 0; | ||
489 | } | ||
490 | |||
491 | static int aica_pcmvolume_get(struct snd_kcontrol *kcontrol, | ||
492 | struct snd_ctl_elem_value *ucontrol) | ||
493 | { | ||
494 | struct snd_card_aica *dreamcastcard; | ||
495 | dreamcastcard = kcontrol->private_data; | ||
496 | if (unlikely(!dreamcastcard->channel)) | ||
497 | return -ETXTBSY; /* we've not yet been set up */ | ||
498 | ucontrol->value.integer.value[0] = dreamcastcard->channel->vol; | ||
499 | return 0; | ||
500 | } | ||
501 | |||
502 | static int aica_pcmvolume_put(struct snd_kcontrol *kcontrol, | ||
503 | struct snd_ctl_elem_value *ucontrol) | ||
504 | { | ||
505 | struct snd_card_aica *dreamcastcard; | ||
506 | dreamcastcard = kcontrol->private_data; | ||
507 | if (unlikely(!dreamcastcard->channel)) | ||
508 | return -ETXTBSY; | ||
509 | if (unlikely(dreamcastcard->channel->vol == | ||
510 | ucontrol->value.integer.value[0])) | ||
511 | return 0; | ||
512 | dreamcastcard->channel->vol = ucontrol->value.integer.value[0]; | ||
513 | dreamcastcard->master_volume = ucontrol->value.integer.value[0]; | ||
514 | spu_memload(AICA_CHANNEL0_CONTROL_OFFSET, | ||
515 | dreamcastcard->channel, sizeof(struct aica_channel)); | ||
516 | return 1; | ||
517 | } | ||
518 | |||
519 | static struct snd_kcontrol_new snd_aica_pcmswitch_control __devinitdata = { | ||
520 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
521 | .name = "PCM Playback Switch", | ||
522 | .index = 0, | ||
523 | .info = aica_pcmswitch_info, | ||
524 | .get = aica_pcmswitch_get, | ||
525 | .put = aica_pcmswitch_put | ||
526 | }; | ||
527 | |||
528 | static struct snd_kcontrol_new snd_aica_pcmvolume_control __devinitdata = { | ||
529 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
530 | .name = "PCM Playback Volume", | ||
531 | .index = 0, | ||
532 | .info = aica_pcmvolume_info, | ||
533 | .get = aica_pcmvolume_get, | ||
534 | .put = aica_pcmvolume_put | ||
535 | }; | ||
536 | |||
537 | static int load_aica_firmware(void) | ||
538 | { | ||
539 | int err; | ||
540 | const struct firmware *fw_entry; | ||
541 | spu_reset(); | ||
542 | err = request_firmware(&fw_entry, "aica_firmware.bin", &pd->dev); | ||
543 | if (unlikely(err)) | ||
544 | return err; | ||
545 | /* write firware into memory */ | ||
546 | spu_disable(); | ||
547 | spu_memload(0, fw_entry->data, fw_entry->size); | ||
548 | spu_enable(); | ||
549 | release_firmware(fw_entry); | ||
550 | return err; | ||
551 | } | ||
552 | |||
553 | static int __devinit add_aicamixer_controls(struct snd_card_aica | ||
554 | *dreamcastcard) | ||
555 | { | ||
556 | int err; | ||
557 | err = snd_ctl_add | ||
558 | (dreamcastcard->card, | ||
559 | snd_ctl_new1(&snd_aica_pcmvolume_control, dreamcastcard)); | ||
560 | if (unlikely(err < 0)) | ||
561 | return err; | ||
562 | err = snd_ctl_add | ||
563 | (dreamcastcard->card, | ||
564 | snd_ctl_new1(&snd_aica_pcmswitch_control, dreamcastcard)); | ||
565 | if (unlikely(err < 0)) | ||
566 | return err; | ||
567 | return 0; | ||
568 | } | ||
569 | |||
570 | static int snd_aica_remove(struct platform_device *devptr) | ||
571 | { | ||
572 | struct snd_card_aica *dreamcastcard; | ||
573 | dreamcastcard = platform_get_drvdata(devptr); | ||
574 | if (unlikely(!dreamcastcard)) | ||
575 | return -ENODEV; | ||
576 | snd_card_free(dreamcastcard->card); | ||
577 | kfree(dreamcastcard); | ||
578 | platform_set_drvdata(devptr, NULL); | ||
579 | return 0; | ||
580 | } | ||
581 | |||
582 | static int __init snd_aica_probe(struct platform_device *devptr) | ||
583 | { | ||
584 | int err; | ||
585 | struct snd_card_aica *dreamcastcard; | ||
586 | dreamcastcard = kmalloc(sizeof(struct snd_card_aica), GFP_KERNEL); | ||
587 | if (unlikely(!dreamcastcard)) | ||
588 | return -ENOMEM; | ||
589 | dreamcastcard->card = | ||
590 | snd_card_new(index, SND_AICA_DRIVER, THIS_MODULE, 0); | ||
591 | if (unlikely(!dreamcastcard->card)) { | ||
592 | kfree(dreamcastcard); | ||
593 | return -ENODEV; | ||
594 | } | ||
595 | strcpy(dreamcastcard->card->driver, "snd_aica"); | ||
596 | strcpy(dreamcastcard->card->shortname, SND_AICA_DRIVER); | ||
597 | strcpy(dreamcastcard->card->longname, | ||
598 | "Yamaha AICA Super Intelligent Sound Processor for SEGA Dreamcast"); | ||
599 | /* Prepare to use the queue */ | ||
600 | INIT_WORK(&(dreamcastcard->spu_dma_work), run_spu_dma); | ||
601 | /* Load the PCM 'chip' */ | ||
602 | err = snd_aicapcmchip(dreamcastcard, 0); | ||
603 | if (unlikely(err < 0)) | ||
604 | goto freedreamcast; | ||
605 | snd_card_set_dev(dreamcastcard->card, &devptr->dev); | ||
606 | dreamcastcard->timer.data = 0; | ||
607 | dreamcastcard->channel = NULL; | ||
608 | /* Add basic controls */ | ||
609 | err = add_aicamixer_controls(dreamcastcard); | ||
610 | if (unlikely(err < 0)) | ||
611 | goto freedreamcast; | ||
612 | /* Register the card with ALSA subsystem */ | ||
613 | err = snd_card_register(dreamcastcard->card); | ||
614 | if (unlikely(err < 0)) | ||
615 | goto freedreamcast; | ||
616 | platform_set_drvdata(devptr, dreamcastcard); | ||
617 | aica_queue = create_workqueue(CARD_NAME); | ||
618 | if (unlikely(!aica_queue)) | ||
619 | goto freedreamcast; | ||
620 | snd_printk | ||
621 | ("ALSA Driver for Yamaha AICA Super Intelligent Sound Processor\n"); | ||
622 | return 0; | ||
623 | freedreamcast: | ||
624 | snd_card_free(dreamcastcard->card); | ||
625 | kfree(dreamcastcard); | ||
626 | return err; | ||
627 | } | ||
628 | |||
629 | static struct platform_driver snd_aica_driver = { | ||
630 | .probe = snd_aica_probe, | ||
631 | .remove = snd_aica_remove, | ||
632 | .driver = { | ||
633 | .name = SND_AICA_DRIVER}, | ||
634 | }; | ||
635 | |||
636 | static int __init aica_init(void) | ||
637 | { | ||
638 | int err; | ||
639 | err = platform_driver_register(&snd_aica_driver); | ||
640 | if (unlikely(err < 0)) | ||
641 | return err; | ||
642 | pd = platform_device_register_simple(SND_AICA_DRIVER, -1, | ||
643 | aica_memory_space, 2); | ||
644 | if (unlikely(IS_ERR(pd))) { | ||
645 | platform_driver_unregister(&snd_aica_driver); | ||
646 | return PTR_ERR(pd); | ||
647 | } | ||
648 | /* Load the firmware */ | ||
649 | return load_aica_firmware(); | ||
650 | } | ||
651 | |||
652 | static void __exit aica_exit(void) | ||
653 | { | ||
654 | /* Destroy the aica kernel thread * | ||
655 | * being extra cautious to check if it exists*/ | ||
656 | if (likely(aica_queue)) | ||
657 | destroy_workqueue(aica_queue); | ||
658 | platform_device_unregister(pd); | ||
659 | platform_driver_unregister(&snd_aica_driver); | ||
660 | /* Kill any sound still playing and reset ARM7 to safe state */ | ||
661 | spu_reset(); | ||
662 | } | ||
663 | |||
664 | module_init(aica_init); | ||
665 | module_exit(aica_exit); | ||
diff --git a/sound/sh/aica.h b/sound/sh/aica.h new file mode 100644 index 000000000000..8c11e3d10a50 --- /dev/null +++ b/sound/sh/aica.h | |||
@@ -0,0 +1,81 @@ | |||
1 | /* aica.h | ||
2 | * Header file for ALSA driver for | ||
3 | * Sega Dreamcast Yamaha AICA sound | ||
4 | * Copyright Adrian McMenamin | ||
5 | * <adrian@mcmen.demon.co.uk> | ||
6 | * 2006 | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of version 2 of the GNU General Public License as published by | ||
10 | * the Free Software Foundation. | ||
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 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | /* SPU memory and register constants etc */ | ||
24 | #define G2_FIFO 0xa05f688c | ||
25 | #define SPU_MEMORY_BASE 0xA0800000 | ||
26 | #define ARM_RESET_REGISTER 0xA0702C00 | ||
27 | #define SPU_REGISTER_BASE 0xA0700000 | ||
28 | |||
29 | /* AICA channels stuff */ | ||
30 | #define AICA_CONTROL_POINT 0xA0810000 | ||
31 | #define AICA_CONTROL_CHANNEL_SAMPLE_NUMBER 0xA0810008 | ||
32 | #define AICA_CHANNEL0_CONTROL_OFFSET 0x10004 | ||
33 | |||
34 | /* Command values */ | ||
35 | #define AICA_CMD_KICK 0x80000000 | ||
36 | #define AICA_CMD_NONE 0 | ||
37 | #define AICA_CMD_START 1 | ||
38 | #define AICA_CMD_STOP 2 | ||
39 | #define AICA_CMD_VOL 3 | ||
40 | |||
41 | /* Sound modes */ | ||
42 | #define SM_8BIT 1 | ||
43 | #define SM_16BIT 0 | ||
44 | #define SM_ADPCM 2 | ||
45 | |||
46 | /* Buffer and period size */ | ||
47 | #define AICA_BUFFER_SIZE 0x8000 | ||
48 | #define AICA_PERIOD_SIZE 0x800 | ||
49 | #define AICA_PERIOD_NUMBER 16 | ||
50 | |||
51 | #define AICA_CHANNEL0_OFFSET 0x11000 | ||
52 | #define AICA_CHANNEL1_OFFSET 0x21000 | ||
53 | #define CHANNEL_OFFSET 0x10000 | ||
54 | |||
55 | #define AICA_DMA_CHANNEL 0 | ||
56 | #define AICA_DMA_MODE 5 | ||
57 | |||
58 | #define SND_AICA_DRIVER "AICA" | ||
59 | |||
60 | struct aica_channel { | ||
61 | uint32_t cmd; /* Command ID */ | ||
62 | uint32_t pos; /* Sample position */ | ||
63 | uint32_t length; /* Sample length */ | ||
64 | uint32_t freq; /* Frequency */ | ||
65 | uint32_t vol; /* Volume 0-255 */ | ||
66 | uint32_t pan; /* Pan 0-255 */ | ||
67 | uint32_t sfmt; /* Sound format */ | ||
68 | uint32_t flags; /* Bit flags */ | ||
69 | }; | ||
70 | |||
71 | struct snd_card_aica { | ||
72 | struct work_struct spu_dma_work; | ||
73 | struct snd_card *card; | ||
74 | struct aica_channel *channel; | ||
75 | struct snd_pcm_substream *substream; | ||
76 | int clicks; | ||
77 | int current_period; | ||
78 | struct timer_list timer; | ||
79 | int master_volume; | ||
80 | int dma_check; | ||
81 | }; | ||
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index 10cffc087181..97b255233175 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig | |||
@@ -27,6 +27,7 @@ config SND_SOC | |||
27 | source "sound/soc/at91/Kconfig" | 27 | source "sound/soc/at91/Kconfig" |
28 | source "sound/soc/pxa/Kconfig" | 28 | source "sound/soc/pxa/Kconfig" |
29 | source "sound/soc/s3c24xx/Kconfig" | 29 | source "sound/soc/s3c24xx/Kconfig" |
30 | source "sound/soc/sh/Kconfig" | ||
30 | 31 | ||
31 | # Supported codecs | 32 | # Supported codecs |
32 | source "sound/soc/codecs/Kconfig" | 33 | source "sound/soc/codecs/Kconfig" |
diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 0ae2e49036f9..304140377632 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | snd-soc-core-objs := soc-core.o soc-dapm.o | 1 | snd-soc-core-objs := soc-core.o soc-dapm.o |
2 | 2 | ||
3 | obj-$(CONFIG_SND_SOC) += snd-soc-core.o | 3 | obj-$(CONFIG_SND_SOC) += snd-soc-core.o |
4 | obj-$(CONFIG_SND_SOC) += codecs/ at91/ pxa/ s3c24xx/ | 4 | obj-$(CONFIG_SND_SOC) += codecs/ at91/ pxa/ s3c24xx/ sh/ |
diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig index 044a3712077a..e97c68306a9a 100644 --- a/sound/soc/s3c24xx/Kconfig +++ b/sound/soc/s3c24xx/Kconfig | |||
@@ -1,6 +1,7 @@ | |||
1 | config SND_S3C24XX_SOC | 1 | config SND_S3C24XX_SOC |
2 | tristate "SoC Audio for the Samsung S3C24XX chips" | 2 | tristate "SoC Audio for the Samsung S3C24XX chips" |
3 | depends on ARCH_S3C2410 && SND_SOC | 3 | depends on ARCH_S3C2410 && SND_SOC |
4 | select SND_PCM | ||
4 | help | 5 | help |
5 | Say Y or M if you want to add support for codecs attached to | 6 | Say Y or M if you want to add support for codecs attached to |
6 | the S3C24XX AC97, I2S or SSP interface. You will also need | 7 | the S3C24XX AC97, I2S or SSP interface. You will also need |
@@ -8,3 +9,29 @@ config SND_S3C24XX_SOC | |||
8 | 9 | ||
9 | config SND_S3C24XX_SOC_I2S | 10 | config SND_S3C24XX_SOC_I2S |
10 | tristate | 11 | tristate |
12 | |||
13 | config SND_S3C2443_SOC_AC97 | ||
14 | tristate | ||
15 | select AC97_BUS | ||
16 | select SND_AC97_CODEC | ||
17 | select SND_SOC_AC97_BUS | ||
18 | |||
19 | config SND_S3C24XX_SOC_NEO1973_WM8753 | ||
20 | tristate "SoC I2S Audio support for NEO1973 - WM8753" | ||
21 | depends on SND_S3C24XX_SOC && MACH_GTA01 | ||
22 | select SND_S3C24XX_SOC_I2S | ||
23 | select SND_SOC_WM8753 | ||
24 | help | ||
25 | Say Y if you want to add support for SoC audio on smdk2440 | ||
26 | with the WM8753. | ||
27 | |||
28 | config SND_S3C24XX_SOC_SMDK2443_WM9710 | ||
29 | tristate "SoC AC97 Audio support for SMDK2443 - WM9710" | ||
30 | depends on SND_S3C24XX_SOC && MACH_SMDK2443 | ||
31 | select SND_S3C2443_SOC_AC97 | ||
32 | select SND_SOC_AC97_CODEC | ||
33 | help | ||
34 | Say Y if you want to add support for SoC audio on smdk2443 | ||
35 | with the WM9710. | ||
36 | |||
37 | |||
diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile index 6f0fffcb30f5..13c92f0fa1e4 100644 --- a/sound/soc/s3c24xx/Makefile +++ b/sound/soc/s3c24xx/Makefile | |||
@@ -1,6 +1,15 @@ | |||
1 | # S3c24XX Platform Support | 1 | # S3c24XX Platform Support |
2 | snd-soc-s3c24xx-objs := s3c24xx-pcm.o | 2 | snd-soc-s3c24xx-objs := s3c24xx-pcm.o |
3 | snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o | 3 | snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o |
4 | snd-soc-s3c2443-ac97-objs := s3c2443-ac97.o | ||
4 | 5 | ||
5 | obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o | 6 | obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o |
6 | obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o | 7 | obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o |
8 | obj-$(CONFIG_SND_S3C2443_SOC_AC97) += snd-soc-s3c2443-ac97.o | ||
9 | |||
10 | # S3C24XX Machine Support | ||
11 | snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o | ||
12 | snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o | ||
13 | |||
14 | obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o | ||
15 | obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o | ||
diff --git a/sound/soc/s3c24xx/lm4857.h b/sound/soc/s3c24xx/lm4857.h new file mode 100644 index 000000000000..0cf5b7011d6f --- /dev/null +++ b/sound/soc/s3c24xx/lm4857.h | |||
@@ -0,0 +1,32 @@ | |||
1 | /* | ||
2 | * lm4857.h -- ALSA Soc Audio Layer | ||
3 | * | ||
4 | * Copyright 2007 Wolfson Microelectronics PLC. | ||
5 | * Author: Graeme Gregory | ||
6 | * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | * Revision history | ||
14 | * 18th Jun 2007 Initial version. | ||
15 | */ | ||
16 | |||
17 | #ifndef LM4857_H_ | ||
18 | #define LM4857_H_ | ||
19 | |||
20 | /* The register offsets in the cache array */ | ||
21 | #define LM4857_MVOL 0 | ||
22 | #define LM4857_LVOL 1 | ||
23 | #define LM4857_RVOL 2 | ||
24 | #define LM4857_CTRL 3 | ||
25 | |||
26 | /* the shifts required to set these bits */ | ||
27 | #define LM4857_3D 5 | ||
28 | #define LM4857_WAKEUP 5 | ||
29 | #define LM4857_EPGAIN 4 | ||
30 | |||
31 | #endif /*LM4857_H_*/ | ||
32 | |||
diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c new file mode 100644 index 000000000000..d5a8fc2cf8d6 --- /dev/null +++ b/sound/soc/s3c24xx/neo1973_wm8753.c | |||
@@ -0,0 +1,670 @@ | |||
1 | /* | ||
2 | * neo1973_wm8753.c -- SoC audio for Neo1973 | ||
3 | * | ||
4 | * Copyright 2007 Wolfson Microelectronics PLC. | ||
5 | * Author: Graeme Gregory | ||
6 | * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | * Revision history | ||
14 | * 20th Jan 2007 Initial version. | ||
15 | * 05th Feb 2007 Rename all to Neo1973 | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | #include <linux/module.h> | ||
20 | #include <linux/moduleparam.h> | ||
21 | #include <linux/timer.h> | ||
22 | #include <linux/interrupt.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/i2c.h> | ||
25 | #include <sound/driver.h> | ||
26 | #include <sound/core.h> | ||
27 | #include <sound/pcm.h> | ||
28 | #include <sound/soc.h> | ||
29 | #include <sound/soc-dapm.h> | ||
30 | |||
31 | #include <asm/mach-types.h> | ||
32 | #include <asm/hardware/scoop.h> | ||
33 | #include <asm/arch/regs-iis.h> | ||
34 | #include <asm/arch/regs-clock.h> | ||
35 | #include <asm/arch/regs-gpio.h> | ||
36 | #include <asm/hardware.h> | ||
37 | #include <asm/arch/audio.h> | ||
38 | #include <asm/io.h> | ||
39 | #include <asm/arch/spi-gpio.h> | ||
40 | #include "../codecs/wm8753.h" | ||
41 | #include "lm4857.h" | ||
42 | #include "s3c24xx-pcm.h" | ||
43 | #include "s3c24xx-i2s.h" | ||
44 | |||
45 | /* define the scenarios */ | ||
46 | #define NEO_AUDIO_OFF 0 | ||
47 | #define NEO_GSM_CALL_AUDIO_HANDSET 1 | ||
48 | #define NEO_GSM_CALL_AUDIO_HEADSET 2 | ||
49 | #define NEO_GSM_CALL_AUDIO_BLUETOOTH 3 | ||
50 | #define NEO_STEREO_TO_SPEAKERS 4 | ||
51 | #define NEO_STEREO_TO_HEADPHONES 5 | ||
52 | #define NEO_CAPTURE_HANDSET 6 | ||
53 | #define NEO_CAPTURE_HEADSET 7 | ||
54 | #define NEO_CAPTURE_BLUETOOTH 8 | ||
55 | |||
56 | static struct snd_soc_machine neo1973; | ||
57 | static struct i2c_client *i2c; | ||
58 | |||
59 | static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream, | ||
60 | struct snd_pcm_hw_params *params) | ||
61 | { | ||
62 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
63 | struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; | ||
64 | struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; | ||
65 | unsigned int pll_out = 0, bclk = 0; | ||
66 | int ret = 0; | ||
67 | unsigned long iis_clkrate; | ||
68 | |||
69 | iis_clkrate = s3c24xx_i2s_get_clockrate(); | ||
70 | |||
71 | switch (params_rate(params)) { | ||
72 | case 8000: | ||
73 | case 16000: | ||
74 | pll_out = 12288000; | ||
75 | break; | ||
76 | case 48000: | ||
77 | bclk = WM8753_BCLK_DIV_4; | ||
78 | pll_out = 12288000; | ||
79 | break; | ||
80 | case 96000: | ||
81 | bclk = WM8753_BCLK_DIV_2; | ||
82 | pll_out = 12288000; | ||
83 | break; | ||
84 | case 11025: | ||
85 | bclk = WM8753_BCLK_DIV_16; | ||
86 | pll_out = 11289600; | ||
87 | break; | ||
88 | case 22050: | ||
89 | bclk = WM8753_BCLK_DIV_8; | ||
90 | pll_out = 11289600; | ||
91 | break; | ||
92 | case 44100: | ||
93 | bclk = WM8753_BCLK_DIV_4; | ||
94 | pll_out = 11289600; | ||
95 | break; | ||
96 | case 88200: | ||
97 | bclk = WM8753_BCLK_DIV_2; | ||
98 | pll_out = 11289600; | ||
99 | break; | ||
100 | } | ||
101 | |||
102 | /* set codec DAI configuration */ | ||
103 | ret = codec_dai->dai_ops.set_fmt(codec_dai, | ||
104 | SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
105 | SND_SOC_DAIFMT_CBM_CFM); | ||
106 | if (ret < 0) | ||
107 | return ret; | ||
108 | |||
109 | /* set cpu DAI configuration */ | ||
110 | ret = cpu_dai->dai_ops.set_fmt(cpu_dai, | ||
111 | SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
112 | SND_SOC_DAIFMT_CBM_CFM); | ||
113 | if (ret < 0) | ||
114 | return ret; | ||
115 | |||
116 | /* set the codec system clock for DAC and ADC */ | ||
117 | ret = codec_dai->dai_ops.set_sysclk(codec_dai, WM8753_MCLK, pll_out, | ||
118 | SND_SOC_CLOCK_IN); | ||
119 | if (ret < 0) | ||
120 | return ret; | ||
121 | |||
122 | /* set MCLK division for sample rate */ | ||
123 | ret = cpu_dai->dai_ops.set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, | ||
124 | S3C2410_IISMOD_32FS ); | ||
125 | if (ret < 0) | ||
126 | return ret; | ||
127 | |||
128 | /* set codec BCLK division for sample rate */ | ||
129 | ret = codec_dai->dai_ops.set_clkdiv(codec_dai, WM8753_BCLKDIV, bclk); | ||
130 | if (ret < 0) | ||
131 | return ret; | ||
132 | |||
133 | /* set prescaler division for sample rate */ | ||
134 | ret = cpu_dai->dai_ops.set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER, | ||
135 | S3C24XX_PRESCALE(4,4)); | ||
136 | if (ret < 0) | ||
137 | return ret; | ||
138 | |||
139 | /* codec PLL input is PCLK/4 */ | ||
140 | ret = codec_dai->dai_ops.set_pll(codec_dai, WM8753_PLL1, | ||
141 | iis_clkrate / 4, pll_out); | ||
142 | if (ret < 0) | ||
143 | return ret; | ||
144 | |||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream) | ||
149 | { | ||
150 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
151 | struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; | ||
152 | |||
153 | /* disable the PLL */ | ||
154 | return codec_dai->dai_ops.set_pll(codec_dai, WM8753_PLL1, 0, 0); | ||
155 | } | ||
156 | |||
157 | /* | ||
158 | * Neo1973 WM8753 HiFi DAI opserations. | ||
159 | */ | ||
160 | static struct snd_soc_ops neo1973_hifi_ops = { | ||
161 | .hw_params = neo1973_hifi_hw_params, | ||
162 | .hw_free = neo1973_hifi_hw_free, | ||
163 | }; | ||
164 | |||
165 | static int neo1973_voice_hw_params(struct snd_pcm_substream *substream, | ||
166 | struct snd_pcm_hw_params *params) | ||
167 | { | ||
168 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
169 | struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; | ||
170 | unsigned int pcmdiv = 0; | ||
171 | int ret = 0; | ||
172 | unsigned long iis_clkrate; | ||
173 | |||
174 | iis_clkrate = s3c24xx_i2s_get_clockrate(); | ||
175 | |||
176 | if (params_rate(params) != 8000) | ||
177 | return -EINVAL; | ||
178 | if (params_channels(params) != 1) | ||
179 | return -EINVAL; | ||
180 | |||
181 | pcmdiv = WM8753_PCM_DIV_6; /* 2.048 MHz */ | ||
182 | |||
183 | /* todo: gg check mode (DSP_B) against CSR datasheet */ | ||
184 | /* set codec DAI configuration */ | ||
185 | ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B | | ||
186 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); | ||
187 | if (ret < 0) | ||
188 | return ret; | ||
189 | |||
190 | /* set the codec system clock for DAC and ADC */ | ||
191 | ret = codec_dai->dai_ops.set_sysclk(codec_dai, WM8753_PCMCLK, 12288000, | ||
192 | SND_SOC_CLOCK_IN); | ||
193 | if (ret < 0) | ||
194 | return ret; | ||
195 | |||
196 | /* set codec PCM division for sample rate */ | ||
197 | ret = codec_dai->dai_ops.set_clkdiv(codec_dai, WM8753_PCMDIV, pcmdiv); | ||
198 | if (ret < 0) | ||
199 | return ret; | ||
200 | |||
201 | /* configue and enable PLL for 12.288MHz output */ | ||
202 | ret = codec_dai->dai_ops.set_pll(codec_dai, WM8753_PLL2, | ||
203 | iis_clkrate / 4, 12288000); | ||
204 | if (ret < 0) | ||
205 | return ret; | ||
206 | |||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | static int neo1973_voice_hw_free(struct snd_pcm_substream *substream) | ||
211 | { | ||
212 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
213 | struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; | ||
214 | |||
215 | /* disable the PLL */ | ||
216 | return codec_dai->dai_ops.set_pll(codec_dai, WM8753_PLL2, 0, 0); | ||
217 | } | ||
218 | |||
219 | static struct snd_soc_ops neo1973_voice_ops = { | ||
220 | .hw_params = neo1973_voice_hw_params, | ||
221 | .hw_free = neo1973_voice_hw_free, | ||
222 | }; | ||
223 | |||
224 | static int neo1973_scenario = 0; | ||
225 | |||
226 | static int neo1973_get_scenario(struct snd_kcontrol *kcontrol, | ||
227 | struct snd_ctl_elem_value *ucontrol) | ||
228 | { | ||
229 | ucontrol->value.integer.value[0] = neo1973_scenario; | ||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | static int set_scenario_endpoints(struct snd_soc_codec *codec, int scenario) | ||
234 | { | ||
235 | switch(neo1973_scenario) { | ||
236 | case NEO_AUDIO_OFF: | ||
237 | snd_soc_dapm_set_endpoint(codec, "Audio Out", 0); | ||
238 | snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0); | ||
239 | snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0); | ||
240 | snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); | ||
241 | snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); | ||
242 | break; | ||
243 | case NEO_GSM_CALL_AUDIO_HANDSET: | ||
244 | snd_soc_dapm_set_endpoint(codec, "Audio Out", 1); | ||
245 | snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 1); | ||
246 | snd_soc_dapm_set_endpoint(codec, "GSM Line In", 1); | ||
247 | snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); | ||
248 | snd_soc_dapm_set_endpoint(codec, "Call Mic", 1); | ||
249 | break; | ||
250 | case NEO_GSM_CALL_AUDIO_HEADSET: | ||
251 | snd_soc_dapm_set_endpoint(codec, "Audio Out", 1); | ||
252 | snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 1); | ||
253 | snd_soc_dapm_set_endpoint(codec, "GSM Line In", 1); | ||
254 | snd_soc_dapm_set_endpoint(codec, "Headset Mic", 1); | ||
255 | snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); | ||
256 | break; | ||
257 | case NEO_GSM_CALL_AUDIO_BLUETOOTH: | ||
258 | snd_soc_dapm_set_endpoint(codec, "Audio Out", 0); | ||
259 | snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 1); | ||
260 | snd_soc_dapm_set_endpoint(codec, "GSM Line In", 1); | ||
261 | snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); | ||
262 | snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); | ||
263 | break; | ||
264 | case NEO_STEREO_TO_SPEAKERS: | ||
265 | snd_soc_dapm_set_endpoint(codec, "Audio Out", 1); | ||
266 | snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0); | ||
267 | snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0); | ||
268 | snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); | ||
269 | snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); | ||
270 | break; | ||
271 | case NEO_STEREO_TO_HEADPHONES: | ||
272 | snd_soc_dapm_set_endpoint(codec, "Audio Out", 1); | ||
273 | snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0); | ||
274 | snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0); | ||
275 | snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); | ||
276 | snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); | ||
277 | break; | ||
278 | case NEO_CAPTURE_HANDSET: | ||
279 | snd_soc_dapm_set_endpoint(codec, "Audio Out", 0); | ||
280 | snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0); | ||
281 | snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0); | ||
282 | snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); | ||
283 | snd_soc_dapm_set_endpoint(codec, "Call Mic", 1); | ||
284 | break; | ||
285 | case NEO_CAPTURE_HEADSET: | ||
286 | snd_soc_dapm_set_endpoint(codec, "Audio Out", 0); | ||
287 | snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0); | ||
288 | snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0); | ||
289 | snd_soc_dapm_set_endpoint(codec, "Headset Mic", 1); | ||
290 | snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); | ||
291 | break; | ||
292 | case NEO_CAPTURE_BLUETOOTH: | ||
293 | snd_soc_dapm_set_endpoint(codec, "Audio Out", 0); | ||
294 | snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0); | ||
295 | snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0); | ||
296 | snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); | ||
297 | snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); | ||
298 | break; | ||
299 | default: | ||
300 | snd_soc_dapm_set_endpoint(codec, "Audio Out", 0); | ||
301 | snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0); | ||
302 | snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0); | ||
303 | snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); | ||
304 | snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); | ||
305 | } | ||
306 | |||
307 | snd_soc_dapm_sync_endpoints(codec); | ||
308 | |||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | static int neo1973_set_scenario(struct snd_kcontrol *kcontrol, | ||
313 | struct snd_ctl_elem_value *ucontrol) | ||
314 | { | ||
315 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
316 | |||
317 | if (neo1973_scenario == ucontrol->value.integer.value[0]) | ||
318 | return 0; | ||
319 | |||
320 | neo1973_scenario = ucontrol->value.integer.value[0]; | ||
321 | set_scenario_endpoints(codec, neo1973_scenario); | ||
322 | return 1; | ||
323 | } | ||
324 | |||
325 | static u8 lm4857_regs[4] = {0x00, 0x40, 0x80, 0xC0}; | ||
326 | |||
327 | static void lm4857_write_regs(void) | ||
328 | { | ||
329 | if (i2c_master_send(i2c, lm4857_regs, 4) != 4) | ||
330 | printk(KERN_ERR "lm4857: i2c write failed\n"); | ||
331 | } | ||
332 | |||
333 | static int lm4857_get_reg(struct snd_kcontrol *kcontrol, | ||
334 | struct snd_ctl_elem_value *ucontrol) | ||
335 | { | ||
336 | int reg=kcontrol->private_value & 0xFF; | ||
337 | int shift = (kcontrol->private_value >> 8) & 0x0F; | ||
338 | int mask = (kcontrol->private_value >> 16) & 0xFF; | ||
339 | |||
340 | ucontrol->value.integer.value[0] = (lm4857_regs[reg] >> shift) & mask; | ||
341 | return 0; | ||
342 | } | ||
343 | |||
344 | static int lm4857_set_reg(struct snd_kcontrol *kcontrol, | ||
345 | struct snd_ctl_elem_value *ucontrol) | ||
346 | { | ||
347 | int reg = kcontrol->private_value & 0xFF; | ||
348 | int shift = (kcontrol->private_value >> 8) & 0x0F; | ||
349 | int mask = (kcontrol->private_value >> 16) & 0xFF; | ||
350 | |||
351 | if (((lm4857_regs[reg] >> shift ) & mask) == | ||
352 | ucontrol->value.integer.value[0]) | ||
353 | return 0; | ||
354 | |||
355 | lm4857_regs[reg] &= ~ (mask << shift); | ||
356 | lm4857_regs[reg] |= ucontrol->value.integer.value[0] << shift; | ||
357 | lm4857_write_regs(); | ||
358 | return 1; | ||
359 | } | ||
360 | |||
361 | static int lm4857_get_mode(struct snd_kcontrol *kcontrol, | ||
362 | struct snd_ctl_elem_value *ucontrol) | ||
363 | { | ||
364 | u8 value = lm4857_regs[LM4857_CTRL] & 0x0F; | ||
365 | |||
366 | if (value) | ||
367 | value -= 5; | ||
368 | |||
369 | ucontrol->value.integer.value[0] = value; | ||
370 | return 0; | ||
371 | } | ||
372 | |||
373 | static int lm4857_set_mode(struct snd_kcontrol *kcontrol, | ||
374 | struct snd_ctl_elem_value *ucontrol) | ||
375 | { | ||
376 | u8 value = ucontrol->value.integer.value[0]; | ||
377 | |||
378 | if (value) | ||
379 | value += 5; | ||
380 | |||
381 | if ((lm4857_regs[LM4857_CTRL] & 0x0F) == value) | ||
382 | return 0; | ||
383 | |||
384 | lm4857_regs[LM4857_CTRL] &= 0xF0; | ||
385 | lm4857_regs[LM4857_CTRL] |= value; | ||
386 | lm4857_write_regs(); | ||
387 | return 1; | ||
388 | } | ||
389 | |||
390 | static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = { | ||
391 | SND_SOC_DAPM_LINE("Audio Out", NULL), | ||
392 | SND_SOC_DAPM_LINE("GSM Line Out", NULL), | ||
393 | SND_SOC_DAPM_LINE("GSM Line In", NULL), | ||
394 | SND_SOC_DAPM_MIC("Headset Mic", NULL), | ||
395 | SND_SOC_DAPM_MIC("Call Mic", NULL), | ||
396 | }; | ||
397 | |||
398 | |||
399 | /* example machine audio_mapnections */ | ||
400 | static const char* audio_map[][3] = { | ||
401 | |||
402 | /* Connections to the lm4857 amp */ | ||
403 | {"Audio Out", NULL, "LOUT1"}, | ||
404 | {"Audio Out", NULL, "ROUT1"}, | ||
405 | |||
406 | /* Connections to the GSM Module */ | ||
407 | {"GSM Line Out", NULL, "MONO1"}, | ||
408 | {"GSM Line Out", NULL, "MONO2"}, | ||
409 | {"RXP", NULL, "GSM Line In"}, | ||
410 | {"RXN", NULL, "GSM Line In"}, | ||
411 | |||
412 | /* Connections to Headset */ | ||
413 | {"MIC1", NULL, "Mic Bias"}, | ||
414 | {"Mic Bias", NULL, "Headset Mic"}, | ||
415 | |||
416 | /* Call Mic */ | ||
417 | {"MIC2", NULL, "Mic Bias"}, | ||
418 | {"MIC2N", NULL, "Mic Bias"}, | ||
419 | {"Mic Bias", NULL, "Call Mic"}, | ||
420 | |||
421 | /* Connect the ALC pins */ | ||
422 | {"ACIN", NULL, "ACOP"}, | ||
423 | |||
424 | {NULL, NULL, NULL}, | ||
425 | }; | ||
426 | |||
427 | static const char *lm4857_mode[] = { | ||
428 | "Off", | ||
429 | "Call Speaker", | ||
430 | "Stereo Speakers", | ||
431 | "Stereo Speakers + Headphones", | ||
432 | "Headphones" | ||
433 | }; | ||
434 | |||
435 | static const struct soc_enum lm4857_mode_enum[] = { | ||
436 | SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lm4857_mode), lm4857_mode), | ||
437 | }; | ||
438 | |||
439 | static const char *neo_scenarios[] = { | ||
440 | "Off", | ||
441 | "GSM Handset", | ||
442 | "GSM Headset", | ||
443 | "GSM Bluetooth", | ||
444 | "Speakers", | ||
445 | "Headphones", | ||
446 | "Capture Handset", | ||
447 | "Capture Headset", | ||
448 | "Capture Bluetooth" | ||
449 | }; | ||
450 | |||
451 | static const struct soc_enum neo_scenario_enum[] = { | ||
452 | SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(neo_scenarios),neo_scenarios), | ||
453 | }; | ||
454 | |||
455 | static const struct snd_kcontrol_new wm8753_neo1973_controls[] = { | ||
456 | SOC_SINGLE_EXT("Amp Left Playback Volume", LM4857_LVOL, 0, 31, 0, | ||
457 | lm4857_get_reg, lm4857_set_reg), | ||
458 | SOC_SINGLE_EXT("Amp Right Playback Volume", LM4857_RVOL, 0, 31, 0, | ||
459 | lm4857_get_reg, lm4857_set_reg), | ||
460 | SOC_SINGLE_EXT("Amp Mono Playback Volume", LM4857_MVOL, 0, 31, 0, | ||
461 | lm4857_get_reg, lm4857_set_reg), | ||
462 | SOC_ENUM_EXT("Amp Mode", lm4857_mode_enum[0], | ||
463 | lm4857_get_mode, lm4857_set_mode), | ||
464 | SOC_ENUM_EXT("Neo Mode", neo_scenario_enum[0], | ||
465 | neo1973_get_scenario, neo1973_set_scenario), | ||
466 | SOC_SINGLE_EXT("Amp Spk 3D Playback Switch", LM4857_LVOL, 5, 1, 0, | ||
467 | lm4857_get_reg, lm4857_set_reg), | ||
468 | SOC_SINGLE_EXT("Amp HP 3d Playback Switch", LM4857_RVOL, 5, 1, 0, | ||
469 | lm4857_get_reg, lm4857_set_reg), | ||
470 | SOC_SINGLE_EXT("Amp Fast Wakeup Playback Switch", LM4857_CTRL, 5, 1, 0, | ||
471 | lm4857_get_reg, lm4857_set_reg), | ||
472 | SOC_SINGLE_EXT("Amp Earpiece 6dB Playback Switch", LM4857_CTRL, 4, 1, 0, | ||
473 | lm4857_get_reg, lm4857_set_reg), | ||
474 | }; | ||
475 | |||
476 | /* | ||
477 | * This is an example machine initialisation for a wm8753 connected to a | ||
478 | * neo1973 II. It is missing logic to detect hp/mic insertions and logic | ||
479 | * to re-route the audio in such an event. | ||
480 | */ | ||
481 | static int neo1973_wm8753_init(struct snd_soc_codec *codec) | ||
482 | { | ||
483 | int i, err; | ||
484 | |||
485 | /* set up NC codec pins */ | ||
486 | snd_soc_dapm_set_endpoint(codec, "LOUT2", 0); | ||
487 | snd_soc_dapm_set_endpoint(codec, "ROUT2", 0); | ||
488 | snd_soc_dapm_set_endpoint(codec, "OUT3", 0); | ||
489 | snd_soc_dapm_set_endpoint(codec, "OUT4", 0); | ||
490 | snd_soc_dapm_set_endpoint(codec, "LINE1", 0); | ||
491 | snd_soc_dapm_set_endpoint(codec, "LINE2", 0); | ||
492 | |||
493 | |||
494 | /* set endpoints to default mode */ | ||
495 | set_scenario_endpoints(codec, NEO_AUDIO_OFF); | ||
496 | |||
497 | /* Add neo1973 specific widgets */ | ||
498 | for (i = 0; i < ARRAY_SIZE(wm8753_dapm_widgets); i++) | ||
499 | snd_soc_dapm_new_control(codec, &wm8753_dapm_widgets[i]); | ||
500 | |||
501 | /* add neo1973 specific controls */ | ||
502 | for (i = 0; i < ARRAY_SIZE(wm8753_neo1973_controls); i++) { | ||
503 | err = snd_ctl_add(codec->card, | ||
504 | snd_soc_cnew(&wm8753_neo1973_controls[i], | ||
505 | codec, NULL)); | ||
506 | if (err < 0) | ||
507 | return err; | ||
508 | } | ||
509 | |||
510 | /* set up neo1973 specific audio path audio_mapnects */ | ||
511 | for (i = 0; audio_map[i][0] != NULL; i++) { | ||
512 | snd_soc_dapm_connect_input(codec, audio_map[i][0], | ||
513 | audio_map[i][1], audio_map[i][2]); | ||
514 | } | ||
515 | |||
516 | snd_soc_dapm_sync_endpoints(codec); | ||
517 | return 0; | ||
518 | } | ||
519 | |||
520 | /* | ||
521 | * BT Codec DAI | ||
522 | */ | ||
523 | static struct snd_soc_cpu_dai bt_dai = | ||
524 | { .name = "Bluetooth", | ||
525 | .id = 0, | ||
526 | .type = SND_SOC_DAI_PCM, | ||
527 | .playback = { | ||
528 | .channels_min = 1, | ||
529 | .channels_max = 1, | ||
530 | .rates = SNDRV_PCM_RATE_8000, | ||
531 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, | ||
532 | .capture = { | ||
533 | .channels_min = 1, | ||
534 | .channels_max = 1, | ||
535 | .rates = SNDRV_PCM_RATE_8000, | ||
536 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, | ||
537 | }; | ||
538 | |||
539 | static struct snd_soc_dai_link neo1973_dai[] = { | ||
540 | { /* Hifi Playback - for similatious use with voice below */ | ||
541 | .name = "WM8753", | ||
542 | .stream_name = "WM8753 HiFi", | ||
543 | .cpu_dai = &s3c24xx_i2s_dai, | ||
544 | .codec_dai = &wm8753_dai[WM8753_DAI_HIFI], | ||
545 | .init = neo1973_wm8753_init, | ||
546 | .ops = &neo1973_hifi_ops, | ||
547 | }, | ||
548 | { /* Voice via BT */ | ||
549 | .name = "Bluetooth", | ||
550 | .stream_name = "Voice", | ||
551 | .cpu_dai = &bt_dai, | ||
552 | .codec_dai = &wm8753_dai[WM8753_DAI_VOICE], | ||
553 | .ops = &neo1973_voice_ops, | ||
554 | }, | ||
555 | }; | ||
556 | |||
557 | static struct snd_soc_machine neo1973 = { | ||
558 | .name = "neo1973", | ||
559 | .dai_link = neo1973_dai, | ||
560 | .num_links = ARRAY_SIZE(neo1973_dai), | ||
561 | }; | ||
562 | |||
563 | static struct wm8753_setup_data neo1973_wm8753_setup = { | ||
564 | .i2c_address = 0x1a, | ||
565 | }; | ||
566 | |||
567 | static struct snd_soc_device neo1973_snd_devdata = { | ||
568 | .machine = &neo1973, | ||
569 | .platform = &s3c24xx_soc_platform, | ||
570 | .codec_dev = &soc_codec_dev_wm8753, | ||
571 | .codec_data = &neo1973_wm8753_setup, | ||
572 | }; | ||
573 | |||
574 | static struct i2c_client client_template; | ||
575 | |||
576 | static unsigned short normal_i2c[] = { 0x7C, I2C_CLIENT_END }; | ||
577 | |||
578 | /* Magic definition of all other variables and things */ | ||
579 | I2C_CLIENT_INSMOD; | ||
580 | |||
581 | static int lm4857_amp_probe(struct i2c_adapter *adap, int addr, int kind) | ||
582 | { | ||
583 | int ret; | ||
584 | |||
585 | client_template.adapter = adap; | ||
586 | client_template.addr = addr; | ||
587 | |||
588 | i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL); | ||
589 | if (i2c == NULL) | ||
590 | return -ENOMEM; | ||
591 | |||
592 | ret = i2c_attach_client(i2c); | ||
593 | if (ret < 0) { | ||
594 | printk(KERN_ERR "LM4857 failed to attach at addr %x\n", addr); | ||
595 | goto exit_err; | ||
596 | } | ||
597 | |||
598 | lm4857_write_regs(); | ||
599 | return ret; | ||
600 | |||
601 | exit_err: | ||
602 | kfree(i2c); | ||
603 | return ret; | ||
604 | } | ||
605 | |||
606 | static int lm4857_i2c_detach(struct i2c_client *client) | ||
607 | { | ||
608 | i2c_detach_client(client); | ||
609 | kfree(client); | ||
610 | return 0; | ||
611 | } | ||
612 | |||
613 | static int lm4857_i2c_attach(struct i2c_adapter *adap) | ||
614 | { | ||
615 | return i2c_probe(adap, &addr_data, lm4857_amp_probe); | ||
616 | } | ||
617 | |||
618 | /* corgi i2c codec control layer */ | ||
619 | static struct i2c_driver lm4857_i2c_driver = { | ||
620 | .driver = { | ||
621 | .name = "LM4857 I2C Amp", | ||
622 | .owner = THIS_MODULE, | ||
623 | }, | ||
624 | .id = I2C_DRIVERID_LM4857, | ||
625 | .attach_adapter = lm4857_i2c_attach, | ||
626 | .detach_client = lm4857_i2c_detach, | ||
627 | .command = NULL, | ||
628 | }; | ||
629 | |||
630 | static struct i2c_client client_template = { | ||
631 | .name = "LM4857", | ||
632 | .driver = &lm4857_i2c_driver, | ||
633 | }; | ||
634 | |||
635 | static struct platform_device *neo1973_snd_device; | ||
636 | |||
637 | static int __init neo1973_init(void) | ||
638 | { | ||
639 | int ret; | ||
640 | |||
641 | neo1973_snd_device = platform_device_alloc("soc-audio", -1); | ||
642 | if (!neo1973_snd_device) | ||
643 | return -ENOMEM; | ||
644 | |||
645 | platform_set_drvdata(neo1973_snd_device, &neo1973_snd_devdata); | ||
646 | neo1973_snd_devdata.dev = &neo1973_snd_device->dev; | ||
647 | ret = platform_device_add(neo1973_snd_device); | ||
648 | |||
649 | if (ret) | ||
650 | platform_device_put(neo1973_snd_device); | ||
651 | |||
652 | ret = i2c_add_driver(&lm4857_i2c_driver); | ||
653 | if (ret != 0) | ||
654 | printk(KERN_ERR "can't add i2c driver"); | ||
655 | |||
656 | return ret; | ||
657 | } | ||
658 | |||
659 | static void __exit neo1973_exit(void) | ||
660 | { | ||
661 | platform_device_unregister(neo1973_snd_device); | ||
662 | } | ||
663 | |||
664 | module_init(neo1973_init); | ||
665 | module_exit(neo1973_exit); | ||
666 | |||
667 | /* Module information */ | ||
668 | MODULE_AUTHOR("Graeme Gregory, graeme.gregory@wolfsonmicro.com, www.wolfsonmicro.com"); | ||
669 | MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973"); | ||
670 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/s3c24xx/s3c2443-ac97.c b/sound/soc/s3c24xx/s3c2443-ac97.c new file mode 100644 index 000000000000..75acf7ef5528 --- /dev/null +++ b/sound/soc/s3c24xx/s3c2443-ac97.c | |||
@@ -0,0 +1,401 @@ | |||
1 | /* | ||
2 | * s3c2443-ac97.c -- ALSA Soc Audio Layer | ||
3 | * | ||
4 | * (c) 2007 Wolfson Microelectronics PLC. | ||
5 | * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com | ||
6 | * | ||
7 | * Copyright (C) 2005, Sean Choi <sh428.choi@samsung.com> | ||
8 | * All rights reserved. | ||
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 | * Revision history | ||
15 | * 21st Mar 2007 Initial Version | ||
16 | */ | ||
17 | |||
18 | #include <linux/init.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/wait.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/clk.h> | ||
25 | |||
26 | #include <sound/driver.h> | ||
27 | #include <sound/core.h> | ||
28 | #include <sound/pcm.h> | ||
29 | #include <sound/ac97_codec.h> | ||
30 | #include <sound/initval.h> | ||
31 | #include <sound/soc.h> | ||
32 | |||
33 | #include <asm/hardware.h> | ||
34 | #include <asm/io.h> | ||
35 | #include <asm/arch/regs-ac97.h> | ||
36 | #include <asm/arch/regs-gpio.h> | ||
37 | #include <asm/arch/regs-clock.h> | ||
38 | #include <asm/arch/audio.h> | ||
39 | #include <asm/dma.h> | ||
40 | #include <asm/arch/dma.h> | ||
41 | |||
42 | #include "s3c24xx-pcm.h" | ||
43 | #include "s3c24xx-ac97.h" | ||
44 | |||
45 | struct s3c24xx_ac97_info { | ||
46 | void __iomem *regs; | ||
47 | struct clk *ac97_clk; | ||
48 | }; | ||
49 | static struct s3c24xx_ac97_info s3c24xx_ac97; | ||
50 | |||
51 | DECLARE_COMPLETION(ac97_completion); | ||
52 | static u32 codec_ready; | ||
53 | static DECLARE_MUTEX(ac97_mutex); | ||
54 | |||
55 | static unsigned short s3c2443_ac97_read(struct snd_ac97 *ac97, | ||
56 | unsigned short reg) | ||
57 | { | ||
58 | u32 ac_glbctrl; | ||
59 | u32 ac_codec_cmd; | ||
60 | u32 stat, addr, data; | ||
61 | |||
62 | down(&ac97_mutex); | ||
63 | |||
64 | codec_ready = S3C_AC97_GLBSTAT_CODECREADY; | ||
65 | ac_codec_cmd = readl(s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD); | ||
66 | ac_codec_cmd = S3C_AC97_CODEC_CMD_READ | AC_CMD_ADDR(reg); | ||
67 | writel(ac_codec_cmd, s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD); | ||
68 | |||
69 | udelay(50); | ||
70 | |||
71 | ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); | ||
72 | ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE; | ||
73 | writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); | ||
74 | |||
75 | wait_for_completion(&ac97_completion); | ||
76 | |||
77 | stat = readl(s3c24xx_ac97.regs + S3C_AC97_STAT); | ||
78 | addr = (stat >> 16) & 0x7f; | ||
79 | data = (stat & 0xffff); | ||
80 | |||
81 | if (addr != reg) | ||
82 | printk(KERN_ERR "s3c24xx-ac97: req addr = %02x," | ||
83 | " rep addr = %02x\n", reg, addr); | ||
84 | |||
85 | up(&ac97_mutex); | ||
86 | |||
87 | return (unsigned short)data; | ||
88 | } | ||
89 | |||
90 | static void s3c2443_ac97_write(struct snd_ac97 *ac97, unsigned short reg, | ||
91 | unsigned short val) | ||
92 | { | ||
93 | u32 ac_glbctrl; | ||
94 | u32 ac_codec_cmd; | ||
95 | |||
96 | down(&ac97_mutex); | ||
97 | |||
98 | codec_ready = S3C_AC97_GLBSTAT_CODECREADY; | ||
99 | ac_codec_cmd = readl(s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD); | ||
100 | ac_codec_cmd = AC_CMD_ADDR(reg) | AC_CMD_DATA(val); | ||
101 | writel(ac_codec_cmd, s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD); | ||
102 | |||
103 | udelay(50); | ||
104 | |||
105 | ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); | ||
106 | ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE; | ||
107 | writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); | ||
108 | |||
109 | wait_for_completion(&ac97_completion); | ||
110 | |||
111 | ac_codec_cmd = readl(s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD); | ||
112 | ac_codec_cmd |= S3C_AC97_CODEC_CMD_READ; | ||
113 | writel(ac_codec_cmd, s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD); | ||
114 | |||
115 | up(&ac97_mutex); | ||
116 | |||
117 | } | ||
118 | |||
119 | static void s3c2443_ac97_warm_reset(struct snd_ac97 *ac97) | ||
120 | { | ||
121 | u32 ac_glbctrl; | ||
122 | |||
123 | ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); | ||
124 | ac_glbctrl = S3C_AC97_GLBCTRL_WARMRESET; | ||
125 | writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); | ||
126 | msleep(1); | ||
127 | |||
128 | ac_glbctrl = 0; | ||
129 | writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); | ||
130 | msleep(1); | ||
131 | } | ||
132 | |||
133 | static void s3c2443_ac97_cold_reset(struct snd_ac97 *ac97) | ||
134 | { | ||
135 | u32 ac_glbctrl; | ||
136 | |||
137 | ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); | ||
138 | ac_glbctrl = S3C_AC97_GLBCTRL_COLDRESET; | ||
139 | writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); | ||
140 | msleep(1); | ||
141 | |||
142 | ac_glbctrl = 0; | ||
143 | writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); | ||
144 | msleep(1); | ||
145 | |||
146 | ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); | ||
147 | ac_glbctrl = S3C_AC97_GLBCTRL_ACLINKON; | ||
148 | writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); | ||
149 | msleep(1); | ||
150 | |||
151 | ac_glbctrl |= S3C_AC97_GLBCTRL_TRANSFERDATAENABLE; | ||
152 | writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); | ||
153 | msleep(1); | ||
154 | |||
155 | ac_glbctrl |= S3C_AC97_GLBCTRL_PCMOUTTM_DMA | | ||
156 | S3C_AC97_GLBCTRL_PCMINTM_DMA | S3C_AC97_GLBCTRL_MICINTM_DMA; | ||
157 | writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); | ||
158 | } | ||
159 | |||
160 | static irqreturn_t s3c2443_ac97_irq(int irq, void *dev_id) | ||
161 | { | ||
162 | int status; | ||
163 | u32 ac_glbctrl; | ||
164 | |||
165 | status = readl(s3c24xx_ac97.regs + S3C_AC97_GLBSTAT) & codec_ready; | ||
166 | |||
167 | if (status) { | ||
168 | ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); | ||
169 | ac_glbctrl &= ~S3C_AC97_GLBCTRL_CODECREADYIE; | ||
170 | writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); | ||
171 | complete(&ac97_completion); | ||
172 | } | ||
173 | return IRQ_HANDLED; | ||
174 | } | ||
175 | |||
176 | struct snd_ac97_bus_ops soc_ac97_ops = { | ||
177 | .read = s3c2443_ac97_read, | ||
178 | .write = s3c2443_ac97_write, | ||
179 | .warm_reset = s3c2443_ac97_warm_reset, | ||
180 | .reset = s3c2443_ac97_cold_reset, | ||
181 | }; | ||
182 | |||
183 | static struct s3c2410_dma_client s3c2443_dma_client_out = { | ||
184 | .name = "AC97 PCM Stereo out" | ||
185 | }; | ||
186 | |||
187 | static struct s3c2410_dma_client s3c2443_dma_client_in = { | ||
188 | .name = "AC97 PCM Stereo in" | ||
189 | }; | ||
190 | |||
191 | static struct s3c2410_dma_client s3c2443_dma_client_micin = { | ||
192 | .name = "AC97 Mic Mono in" | ||
193 | }; | ||
194 | |||
195 | static struct s3c24xx_pcm_dma_params s3c2443_ac97_pcm_stereo_out = { | ||
196 | .client = &s3c2443_dma_client_out, | ||
197 | .channel = DMACH_PCM_OUT, | ||
198 | .dma_addr = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA, | ||
199 | .dma_size = 4, | ||
200 | }; | ||
201 | |||
202 | static struct s3c24xx_pcm_dma_params s3c2443_ac97_pcm_stereo_in = { | ||
203 | .client = &s3c2443_dma_client_in, | ||
204 | .channel = DMACH_PCM_IN, | ||
205 | .dma_addr = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA, | ||
206 | .dma_size = 4, | ||
207 | }; | ||
208 | |||
209 | static struct s3c24xx_pcm_dma_params s3c2443_ac97_mic_mono_in = { | ||
210 | .client = &s3c2443_dma_client_micin, | ||
211 | .channel = DMACH_MIC_IN, | ||
212 | .dma_addr = S3C2440_PA_AC97 + S3C_AC97_MIC_DATA, | ||
213 | .dma_size = 4, | ||
214 | }; | ||
215 | |||
216 | static int s3c2443_ac97_probe(struct platform_device *pdev) | ||
217 | { | ||
218 | int ret; | ||
219 | u32 ac_glbctrl; | ||
220 | |||
221 | s3c24xx_ac97.regs = ioremap(S3C2440_PA_AC97, 0x100); | ||
222 | if (s3c24xx_ac97.regs == NULL) | ||
223 | return -ENXIO; | ||
224 | |||
225 | s3c24xx_ac97.ac97_clk = clk_get(&pdev->dev, "ac97"); | ||
226 | if (s3c24xx_ac97.ac97_clk == NULL) { | ||
227 | printk(KERN_ERR "s3c2443-ac97 failed to get ac97_clock\n"); | ||
228 | iounmap(s3c24xx_ac97.regs); | ||
229 | return -ENODEV; | ||
230 | } | ||
231 | clk_enable(s3c24xx_ac97.ac97_clk); | ||
232 | |||
233 | s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2443_GPE0_AC_nRESET); | ||
234 | s3c2410_gpio_cfgpin(S3C2410_GPE1, S3C2443_GPE1_AC_SYNC); | ||
235 | s3c2410_gpio_cfgpin(S3C2410_GPE2, S3C2443_GPE2_AC_BITCLK); | ||
236 | s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2443_GPE3_AC_SDI); | ||
237 | s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2443_GPE4_AC_SDO); | ||
238 | |||
239 | ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); | ||
240 | ac_glbctrl = S3C_AC97_GLBCTRL_COLDRESET; | ||
241 | writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); | ||
242 | msleep(1); | ||
243 | |||
244 | ac_glbctrl = 0; | ||
245 | writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); | ||
246 | msleep(1); | ||
247 | |||
248 | ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); | ||
249 | ac_glbctrl = S3C_AC97_GLBCTRL_ACLINKON; | ||
250 | writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); | ||
251 | msleep(1); | ||
252 | |||
253 | ac_glbctrl |= S3C_AC97_GLBCTRL_TRANSFERDATAENABLE; | ||
254 | writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); | ||
255 | |||
256 | ret = request_irq(IRQ_S3C2443_AC97, s3c2443_ac97_irq, | ||
257 | IRQF_DISABLED, "AC97", NULL); | ||
258 | if (ret < 0) { | ||
259 | printk(KERN_ERR "s3c24xx-ac97: interrupt request failed.\n"); | ||
260 | clk_disable(s3c24xx_ac97.ac97_clk); | ||
261 | clk_put(s3c24xx_ac97.ac97_clk); | ||
262 | iounmap(s3c24xx_ac97.regs); | ||
263 | } | ||
264 | return ret; | ||
265 | } | ||
266 | |||
267 | static void s3c2443_ac97_remove(struct platform_device *pdev) | ||
268 | { | ||
269 | free_irq(IRQ_S3C2443_AC97, NULL); | ||
270 | clk_disable(s3c24xx_ac97.ac97_clk); | ||
271 | clk_put(s3c24xx_ac97.ac97_clk); | ||
272 | iounmap(s3c24xx_ac97.regs); | ||
273 | } | ||
274 | |||
275 | static int s3c2443_ac97_hw_params(struct snd_pcm_substream *substream, | ||
276 | struct snd_pcm_hw_params *params) | ||
277 | { | ||
278 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
279 | struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; | ||
280 | |||
281 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
282 | cpu_dai->dma_data = &s3c2443_ac97_pcm_stereo_out; | ||
283 | else | ||
284 | cpu_dai->dma_data = &s3c2443_ac97_pcm_stereo_in; | ||
285 | |||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | static int s3c2443_ac97_trigger(struct snd_pcm_substream *substream, int cmd) | ||
290 | { | ||
291 | u32 ac_glbctrl; | ||
292 | |||
293 | ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); | ||
294 | switch(cmd) { | ||
295 | case SNDRV_PCM_TRIGGER_START: | ||
296 | case SNDRV_PCM_TRIGGER_RESUME: | ||
297 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
298 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) | ||
299 | ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA; | ||
300 | else | ||
301 | ac_glbctrl |= S3C_AC97_GLBCTRL_PCMOUTTM_DMA; | ||
302 | break; | ||
303 | case SNDRV_PCM_TRIGGER_STOP: | ||
304 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
305 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
306 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) | ||
307 | ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK; | ||
308 | else | ||
309 | ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMOUTTM_MASK; | ||
310 | break; | ||
311 | } | ||
312 | writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); | ||
313 | |||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | static int s3c2443_ac97_hw_mic_params(struct snd_pcm_substream *substream, | ||
318 | struct snd_pcm_hw_params *params) | ||
319 | { | ||
320 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
321 | struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; | ||
322 | |||
323 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
324 | return -ENODEV; | ||
325 | else | ||
326 | cpu_dai->dma_data = &s3c2443_ac97_mic_mono_in; | ||
327 | |||
328 | return 0; | ||
329 | } | ||
330 | |||
331 | static int s3c2443_ac97_mic_trigger(struct snd_pcm_substream *substream, | ||
332 | int cmd) | ||
333 | { | ||
334 | u32 ac_glbctrl; | ||
335 | |||
336 | ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); | ||
337 | switch(cmd) { | ||
338 | case SNDRV_PCM_TRIGGER_START: | ||
339 | case SNDRV_PCM_TRIGGER_RESUME: | ||
340 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
341 | ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA; | ||
342 | break; | ||
343 | case SNDRV_PCM_TRIGGER_STOP: | ||
344 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
345 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
346 | ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK; | ||
347 | } | ||
348 | writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); | ||
349 | |||
350 | return 0; | ||
351 | } | ||
352 | |||
353 | #define s3c2443_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ | ||
354 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \ | ||
355 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) | ||
356 | |||
357 | struct snd_soc_cpu_dai s3c2443_ac97_dai[] = { | ||
358 | { | ||
359 | .name = "s3c2443-ac97", | ||
360 | .id = 0, | ||
361 | .type = SND_SOC_DAI_AC97, | ||
362 | .probe = s3c2443_ac97_probe, | ||
363 | .remove = s3c2443_ac97_remove, | ||
364 | .playback = { | ||
365 | .stream_name = "AC97 Playback", | ||
366 | .channels_min = 2, | ||
367 | .channels_max = 2, | ||
368 | .rates = s3c2443_AC97_RATES, | ||
369 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, | ||
370 | .capture = { | ||
371 | .stream_name = "AC97 Capture", | ||
372 | .channels_min = 2, | ||
373 | .channels_max = 2, | ||
374 | .rates = s3c2443_AC97_RATES, | ||
375 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, | ||
376 | .ops = { | ||
377 | .hw_params = s3c2443_ac97_hw_params, | ||
378 | .trigger = s3c2443_ac97_trigger}, | ||
379 | }, | ||
380 | { | ||
381 | .name = "pxa2xx-ac97-mic", | ||
382 | .id = 1, | ||
383 | .type = SND_SOC_DAI_AC97, | ||
384 | .capture = { | ||
385 | .stream_name = "AC97 Mic Capture", | ||
386 | .channels_min = 1, | ||
387 | .channels_max = 1, | ||
388 | .rates = s3c2443_AC97_RATES, | ||
389 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, | ||
390 | .ops = { | ||
391 | .hw_params = s3c2443_ac97_hw_mic_params, | ||
392 | .trigger = s3c2443_ac97_mic_trigger,}, | ||
393 | }, | ||
394 | }; | ||
395 | |||
396 | EXPORT_SYMBOL_GPL(s3c2443_ac97_dai); | ||
397 | EXPORT_SYMBOL_GPL(soc_ac97_ops); | ||
398 | |||
399 | MODULE_AUTHOR("Graeme Gregory"); | ||
400 | MODULE_DESCRIPTION("AC97 driver for the Samsung s3c2443 chip"); | ||
401 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/s3c24xx/s3c24xx-ac97.h b/sound/soc/s3c24xx/s3c24xx-ac97.h new file mode 100644 index 000000000000..2b835e8260fa --- /dev/null +++ b/sound/soc/s3c24xx/s3c24xx-ac97.h | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * s3c24xx-ac97.c -- ALSA Soc Audio Layer | ||
3 | * | ||
4 | * (c) 2007 Wolfson Microelectronics PLC. | ||
5 | * Author: Graeme Gregory | ||
6 | * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | * Revision history | ||
14 | * 10th Nov 2006 Initial version. | ||
15 | */ | ||
16 | |||
17 | #ifndef S3C24XXAC97_H_ | ||
18 | #define S3C24XXAC97_H_ | ||
19 | |||
20 | #define AC_CMD_ADDR(x) (x << 16) | ||
21 | #define AC_CMD_DATA(x) (x & 0xffff) | ||
22 | |||
23 | extern struct snd_soc_cpu_dai s3c2443_ac97_dai[]; | ||
24 | |||
25 | #endif /*S3C24XXAC97_H_*/ | ||
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c index 8ca314dc8891..39f02462e07d 100644 --- a/sound/soc/s3c24xx/s3c24xx-i2s.c +++ b/sound/soc/s3c24xx/s3c24xx-i2s.c | |||
@@ -344,11 +344,11 @@ static int s3c24xx_i2s_set_clkdiv(struct snd_soc_cpu_dai *cpu_dai, | |||
344 | DBG("Entered %s\n", __FUNCTION__); | 344 | DBG("Entered %s\n", __FUNCTION__); |
345 | 345 | ||
346 | switch (div_id) { | 346 | switch (div_id) { |
347 | case S3C24XX_DIV_MCLK: | 347 | case S3C24XX_DIV_BCLK: |
348 | reg = readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & ~S3C2410_IISMOD_FS_MASK; | 348 | reg = readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & ~S3C2410_IISMOD_FS_MASK; |
349 | writel(reg | div, s3c24xx_i2s.regs + S3C2410_IISMOD); | 349 | writel(reg | div, s3c24xx_i2s.regs + S3C2410_IISMOD); |
350 | break; | 350 | break; |
351 | case S3C24XX_DIV_BCLK: | 351 | case S3C24XX_DIV_MCLK: |
352 | reg = readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & ~(S3C2410_IISMOD_384FS); | 352 | reg = readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & ~(S3C2410_IISMOD_384FS); |
353 | writel(reg | div, s3c24xx_i2s.regs + S3C2410_IISMOD); | 353 | writel(reg | div, s3c24xx_i2s.regs + S3C2410_IISMOD); |
354 | break; | 354 | break; |
diff --git a/sound/soc/s3c24xx/smdk2443_wm9710.c b/sound/soc/s3c24xx/smdk2443_wm9710.c new file mode 100644 index 000000000000..d46cd811ceb3 --- /dev/null +++ b/sound/soc/s3c24xx/smdk2443_wm9710.c | |||
@@ -0,0 +1,85 @@ | |||
1 | /* | ||
2 | * smdk2443_wm9710.c -- SoC audio for smdk2443 | ||
3 | * | ||
4 | * Copyright 2007 Wolfson Microelectronics PLC. | ||
5 | * Author: Graeme Gregory | ||
6 | * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | * Revision history | ||
14 | * 8th Mar 2007 Initial version. | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | #include <linux/module.h> | ||
19 | #include <linux/device.h> | ||
20 | #include <sound/driver.h> | ||
21 | #include <sound/core.h> | ||
22 | #include <sound/pcm.h> | ||
23 | #include <sound/soc.h> | ||
24 | #include <sound/soc-dapm.h> | ||
25 | |||
26 | #include "../codecs/ac97.h" | ||
27 | #include "s3c24xx-pcm.h" | ||
28 | #include "s3c24xx-ac97.h" | ||
29 | |||
30 | static struct snd_soc_machine smdk2443; | ||
31 | |||
32 | static struct snd_soc_dai_link smdk2443_dai[] = { | ||
33 | { | ||
34 | .name = "AC97", | ||
35 | .stream_name = "AC97 HiFi", | ||
36 | .cpu_dai = &s3c2443_ac97_dai[0], | ||
37 | .codec_dai = &ac97_dai, | ||
38 | }, | ||
39 | }; | ||
40 | |||
41 | static struct snd_soc_machine smdk2443 = { | ||
42 | .name = "SMDK2443", | ||
43 | .dai_link = smdk2443_dai, | ||
44 | .num_links = ARRAY_SIZE(smdk2443_dai), | ||
45 | }; | ||
46 | |||
47 | static struct snd_soc_device smdk2443_snd_ac97_devdata = { | ||
48 | .machine = &smdk2443, | ||
49 | .platform = &s3c24xx_soc_platform, | ||
50 | .codec_dev = &soc_codec_dev_ac97, | ||
51 | }; | ||
52 | |||
53 | static struct platform_device *smdk2443_snd_ac97_device; | ||
54 | |||
55 | static int __init smdk2443_init(void) | ||
56 | { | ||
57 | int ret; | ||
58 | |||
59 | smdk2443_snd_ac97_device = platform_device_alloc("soc-audio", -1); | ||
60 | if (!smdk2443_snd_ac97_device) | ||
61 | return -ENOMEM; | ||
62 | |||
63 | platform_set_drvdata(smdk2443_snd_ac97_device, | ||
64 | &smdk2443_snd_ac97_devdata); | ||
65 | smdk2443_snd_ac97_devdata.dev = &smdk2443_snd_ac97_device->dev; | ||
66 | ret = platform_device_add(smdk2443_snd_ac97_device); | ||
67 | |||
68 | if (ret) | ||
69 | platform_device_put(smdk2443_snd_ac97_device); | ||
70 | |||
71 | return ret; | ||
72 | } | ||
73 | |||
74 | static void __exit smdk2443_exit(void) | ||
75 | { | ||
76 | platform_device_unregister(smdk2443_snd_ac97_device); | ||
77 | } | ||
78 | |||
79 | module_init(smdk2443_init); | ||
80 | module_exit(smdk2443_exit); | ||
81 | |||
82 | /* Module information */ | ||
83 | MODULE_AUTHOR("Graeme Gregory, graeme.gregory@wolfsonmicro.com, www.wolfsonmicro.com"); | ||
84 | MODULE_DESCRIPTION("ALSA SoC WM9710 SMDK2443"); | ||
85 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig new file mode 100644 index 000000000000..f03220d23e73 --- /dev/null +++ b/sound/soc/sh/Kconfig | |||
@@ -0,0 +1,38 @@ | |||
1 | menu "SoC Audio support for SuperH" | ||
2 | |||
3 | config SND_SOC_PCM_SH7760 | ||
4 | tristate "SoC Audio support for Renesas SH7760" | ||
5 | depends on CPU_SUBTYPE_SH7760 && SND_SOC && SH_DMABRG | ||
6 | help | ||
7 | Enable this option for SH7760 AC97/I2S audio support. | ||
8 | |||
9 | |||
10 | ## | ||
11 | ## Audio unit modules | ||
12 | ## | ||
13 | |||
14 | config SND_SOC_SH4_HAC | ||
15 | select AC97_BUS | ||
16 | select SND_SOC_AC97_BUS | ||
17 | select SND_AC97_CODEC | ||
18 | tristate | ||
19 | |||
20 | config SND_SOC_SH4_SSI | ||
21 | tristate | ||
22 | |||
23 | |||
24 | |||
25 | ## | ||
26 | ## Boards | ||
27 | ## | ||
28 | |||
29 | config SND_SH7760_AC97 | ||
30 | tristate "SH7760 AC97 sound support" | ||
31 | depends on CPU_SUBTYPE_SH7760 && SND_SOC_PCM_SH7760 | ||
32 | select SND_SOC_SH4_HAC | ||
33 | select SND_SOC_AC97_CODEC | ||
34 | help | ||
35 | This option enables generic sound support for the first | ||
36 | AC97 unit of the SH7760. | ||
37 | |||
38 | endmenu | ||
diff --git a/sound/soc/sh/Makefile b/sound/soc/sh/Makefile new file mode 100644 index 000000000000..a8e8ab81cc6a --- /dev/null +++ b/sound/soc/sh/Makefile | |||
@@ -0,0 +1,14 @@ | |||
1 | ## DMA engines | ||
2 | snd-soc-dma-sh7760-objs := dma-sh7760.o | ||
3 | obj-$(CONFIG_SND_SOC_PCM_SH7760) += snd-soc-dma-sh7760.o | ||
4 | |||
5 | ## audio units found on some SH-4 | ||
6 | snd-soc-hac-objs := hac.o | ||
7 | snd-soc-ssi-objs := ssi.o | ||
8 | obj-$(CONFIG_SND_SOC_SH4_HAC) += snd-soc-hac.o | ||
9 | obj-$(CONFIG_SND_SOC_SH4_SSI) += snd-soc-ssi.o | ||
10 | |||
11 | ## boards | ||
12 | snd-soc-sh7760-ac97-objs := sh7760-ac97.o | ||
13 | |||
14 | obj-$(CONFIG_SND_SH7760_AC97) += snd-soc-sh7760-ac97.o | ||
diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c new file mode 100644 index 000000000000..cdee374b843e --- /dev/null +++ b/sound/soc/sh/dma-sh7760.c | |||
@@ -0,0 +1,354 @@ | |||
1 | /* | ||
2 | * SH7760 ("camelot") DMABRG audio DMA unit support | ||
3 | * | ||
4 | * Copyright (C) 2007 Manuel Lauss <mano@roarinelk.homelinux.net> | ||
5 | * licensed under the terms outlined in the file COPYING at the root | ||
6 | * of the linux kernel sources. | ||
7 | * | ||
8 | * The SH7760 DMABRG provides 4 dma channels (2x rec, 2x play), which | ||
9 | * trigger an interrupt when one half of the programmed transfer size | ||
10 | * has been xmitted. | ||
11 | * | ||
12 | * FIXME: little-endian only for now | ||
13 | */ | ||
14 | |||
15 | #include <linux/module.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/dma-mapping.h> | ||
19 | #include <sound/driver.h> | ||
20 | #include <sound/core.h> | ||
21 | #include <sound/pcm.h> | ||
22 | #include <sound/pcm_params.h> | ||
23 | #include <sound/soc.h> | ||
24 | #include <asm/dmabrg.h> | ||
25 | |||
26 | |||
27 | /* registers and bits */ | ||
28 | #define BRGATXSAR 0x00 | ||
29 | #define BRGARXDAR 0x04 | ||
30 | #define BRGATXTCR 0x08 | ||
31 | #define BRGARXTCR 0x0C | ||
32 | #define BRGACR 0x10 | ||
33 | #define BRGATXTCNT 0x14 | ||
34 | #define BRGARXTCNT 0x18 | ||
35 | |||
36 | #define ACR_RAR (1 << 18) | ||
37 | #define ACR_RDS (1 << 17) | ||
38 | #define ACR_RDE (1 << 16) | ||
39 | #define ACR_TAR (1 << 2) | ||
40 | #define ACR_TDS (1 << 1) | ||
41 | #define ACR_TDE (1 << 0) | ||
42 | |||
43 | /* receiver/transmitter data alignment */ | ||
44 | #define ACR_RAM_NONE (0 << 24) | ||
45 | #define ACR_RAM_4BYTE (1 << 24) | ||
46 | #define ACR_RAM_2WORD (2 << 24) | ||
47 | #define ACR_TAM_NONE (0 << 8) | ||
48 | #define ACR_TAM_4BYTE (1 << 8) | ||
49 | #define ACR_TAM_2WORD (2 << 8) | ||
50 | |||
51 | |||
52 | struct camelot_pcm { | ||
53 | unsigned long mmio; /* DMABRG audio channel control reg MMIO */ | ||
54 | unsigned int txid; /* ID of first DMABRG IRQ for this unit */ | ||
55 | |||
56 | struct snd_pcm_substream *tx_ss; | ||
57 | unsigned long tx_period_size; | ||
58 | unsigned int tx_period; | ||
59 | |||
60 | struct snd_pcm_substream *rx_ss; | ||
61 | unsigned long rx_period_size; | ||
62 | unsigned int rx_period; | ||
63 | |||
64 | } cam_pcm_data[2] = { | ||
65 | { | ||
66 | .mmio = 0xFE3C0040, | ||
67 | .txid = DMABRGIRQ_A0TXF, | ||
68 | }, | ||
69 | { | ||
70 | .mmio = 0xFE3C0060, | ||
71 | .txid = DMABRGIRQ_A1TXF, | ||
72 | }, | ||
73 | }; | ||
74 | |||
75 | #define BRGREG(x) (*(unsigned long *)(cam->mmio + (x))) | ||
76 | |||
77 | /* | ||
78 | * set a minimum of 16kb per period, to avoid interrupt-"storm" and | ||
79 | * resulting skipping. In general, the bigger the minimum size, the | ||
80 | * better for overall system performance. (The SH7760 is a puny CPU | ||
81 | * with a slow SDRAM interface and poor internal bus bandwidth, | ||
82 | * *especially* when the LCDC is active). The minimum for the DMAC | ||
83 | * is 8 bytes; 16kbytes are enough to get skip-free playback of a | ||
84 | * 44kHz/16bit/stereo MP3 on a lightly loaded system, and maintain | ||
85 | * reasonable responsiveness in MPlayer. | ||
86 | */ | ||
87 | #define DMABRG_PERIOD_MIN 16 * 1024 | ||
88 | #define DMABRG_PERIOD_MAX 0x03fffffc | ||
89 | #define DMABRG_PREALLOC_BUFFER 32 * 1024 | ||
90 | #define DMABRG_PREALLOC_BUFFER_MAX 32 * 1024 | ||
91 | |||
92 | /* support everything the SSI supports */ | ||
93 | #define DMABRG_RATES \ | ||
94 | SNDRV_PCM_RATE_8000_192000 | ||
95 | |||
96 | #define DMABRG_FMTS \ | ||
97 | (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \ | ||
98 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE | \ | ||
99 | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_U20_3LE | \ | ||
100 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3LE | \ | ||
101 | SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE) | ||
102 | |||
103 | static struct snd_pcm_hardware camelot_pcm_hardware = { | ||
104 | .info = (SNDRV_PCM_INFO_MMAP | | ||
105 | SNDRV_PCM_INFO_INTERLEAVED | | ||
106 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
107 | SNDRV_PCM_INFO_MMAP_VALID), | ||
108 | .formats = DMABRG_FMTS, | ||
109 | .rates = DMABRG_RATES, | ||
110 | .rate_min = 8000, | ||
111 | .rate_max = 192000, | ||
112 | .channels_min = 2, | ||
113 | .channels_max = 8, /* max of the SSI */ | ||
114 | .buffer_bytes_max = DMABRG_PERIOD_MAX, | ||
115 | .period_bytes_min = DMABRG_PERIOD_MIN, | ||
116 | .period_bytes_max = DMABRG_PERIOD_MAX / 2, | ||
117 | .periods_min = 2, | ||
118 | .periods_max = 2, | ||
119 | .fifo_size = 128, | ||
120 | }; | ||
121 | |||
122 | static void camelot_txdma(void *data) | ||
123 | { | ||
124 | struct camelot_pcm *cam = data; | ||
125 | cam->tx_period ^= 1; | ||
126 | snd_pcm_period_elapsed(cam->tx_ss); | ||
127 | } | ||
128 | |||
129 | static void camelot_rxdma(void *data) | ||
130 | { | ||
131 | struct camelot_pcm *cam = data; | ||
132 | cam->rx_period ^= 1; | ||
133 | snd_pcm_period_elapsed(cam->rx_ss); | ||
134 | } | ||
135 | |||
136 | static int camelot_pcm_open(struct snd_pcm_substream *substream) | ||
137 | { | ||
138 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
139 | struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id]; | ||
140 | int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; | ||
141 | int ret, dmairq; | ||
142 | |||
143 | snd_soc_set_runtime_hwparams(substream, &camelot_pcm_hardware); | ||
144 | |||
145 | /* DMABRG buffer half/full events */ | ||
146 | dmairq = (recv) ? cam->txid + 2 : cam->txid; | ||
147 | if (recv) { | ||
148 | cam->rx_ss = substream; | ||
149 | ret = dmabrg_request_irq(dmairq, camelot_rxdma, cam); | ||
150 | if (unlikely(ret)) { | ||
151 | pr_debug("audio unit %d irqs already taken!\n", | ||
152 | rtd->dai->cpu_dai->id); | ||
153 | return -EBUSY; | ||
154 | } | ||
155 | (void)dmabrg_request_irq(dmairq + 1,camelot_rxdma, cam); | ||
156 | } else { | ||
157 | cam->tx_ss = substream; | ||
158 | ret = dmabrg_request_irq(dmairq, camelot_txdma, cam); | ||
159 | if (unlikely(ret)) { | ||
160 | pr_debug("audio unit %d irqs already taken!\n", | ||
161 | rtd->dai->cpu_dai->id); | ||
162 | return -EBUSY; | ||
163 | } | ||
164 | (void)dmabrg_request_irq(dmairq + 1, camelot_txdma, cam); | ||
165 | } | ||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | static int camelot_pcm_close(struct snd_pcm_substream *substream) | ||
170 | { | ||
171 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
172 | struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id]; | ||
173 | int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; | ||
174 | int dmairq; | ||
175 | |||
176 | dmairq = (recv) ? cam->txid + 2 : cam->txid; | ||
177 | |||
178 | if (recv) | ||
179 | cam->rx_ss = NULL; | ||
180 | else | ||
181 | cam->tx_ss = NULL; | ||
182 | |||
183 | dmabrg_free_irq(dmairq + 1); | ||
184 | dmabrg_free_irq(dmairq); | ||
185 | |||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | static int camelot_hw_params(struct snd_pcm_substream *substream, | ||
190 | struct snd_pcm_hw_params *hw_params) | ||
191 | { | ||
192 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
193 | struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id]; | ||
194 | int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; | ||
195 | int ret; | ||
196 | |||
197 | ret = snd_pcm_lib_malloc_pages(substream, | ||
198 | params_buffer_bytes(hw_params)); | ||
199 | if (ret < 0) | ||
200 | return ret; | ||
201 | |||
202 | if (recv) { | ||
203 | cam->rx_period_size = params_period_bytes(hw_params); | ||
204 | cam->rx_period = 0; | ||
205 | } else { | ||
206 | cam->tx_period_size = params_period_bytes(hw_params); | ||
207 | cam->tx_period = 0; | ||
208 | } | ||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | static int camelot_hw_free(struct snd_pcm_substream *substream) | ||
213 | { | ||
214 | return snd_pcm_lib_free_pages(substream); | ||
215 | } | ||
216 | |||
217 | static int camelot_prepare(struct snd_pcm_substream *substream) | ||
218 | { | ||
219 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
220 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
221 | struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id]; | ||
222 | |||
223 | pr_debug("PCM data: addr 0x%08ulx len %d\n", | ||
224 | (u32)runtime->dma_addr, runtime->dma_bytes); | ||
225 | |||
226 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
227 | BRGREG(BRGATXSAR) = (unsigned long)runtime->dma_area; | ||
228 | BRGREG(BRGATXTCR) = runtime->dma_bytes; | ||
229 | } else { | ||
230 | BRGREG(BRGARXDAR) = (unsigned long)runtime->dma_area; | ||
231 | BRGREG(BRGARXTCR) = runtime->dma_bytes; | ||
232 | } | ||
233 | |||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | static inline void dmabrg_play_dma_start(struct camelot_pcm *cam) | ||
238 | { | ||
239 | unsigned long acr = BRGREG(BRGACR) & ~(ACR_TDS | ACR_RDS); | ||
240 | /* start DMABRG engine: XFER start, auto-addr-reload */ | ||
241 | BRGREG(BRGACR) = acr | ACR_TDE | ACR_TAR | ACR_TAM_2WORD; | ||
242 | } | ||
243 | |||
244 | static inline void dmabrg_play_dma_stop(struct camelot_pcm *cam) | ||
245 | { | ||
246 | unsigned long acr = BRGREG(BRGACR) & ~(ACR_TDS | ACR_RDS); | ||
247 | /* forcibly terminate data transmission */ | ||
248 | BRGREG(BRGACR) = acr | ACR_TDS; | ||
249 | } | ||
250 | |||
251 | static inline void dmabrg_rec_dma_start(struct camelot_pcm *cam) | ||
252 | { | ||
253 | unsigned long acr = BRGREG(BRGACR) & ~(ACR_TDS | ACR_RDS); | ||
254 | /* start DMABRG engine: recv start, auto-reload */ | ||
255 | BRGREG(BRGACR) = acr | ACR_RDE | ACR_RAR | ACR_RAM_2WORD; | ||
256 | } | ||
257 | |||
258 | static inline void dmabrg_rec_dma_stop(struct camelot_pcm *cam) | ||
259 | { | ||
260 | unsigned long acr = BRGREG(BRGACR) & ~(ACR_TDS | ACR_RDS); | ||
261 | /* forcibly terminate data receiver */ | ||
262 | BRGREG(BRGACR) = acr | ACR_RDS; | ||
263 | } | ||
264 | |||
265 | static int camelot_trigger(struct snd_pcm_substream *substream, int cmd) | ||
266 | { | ||
267 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
268 | struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id]; | ||
269 | int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; | ||
270 | |||
271 | switch (cmd) { | ||
272 | case SNDRV_PCM_TRIGGER_START: | ||
273 | if (recv) | ||
274 | dmabrg_rec_dma_start(cam); | ||
275 | else | ||
276 | dmabrg_play_dma_start(cam); | ||
277 | break; | ||
278 | case SNDRV_PCM_TRIGGER_STOP: | ||
279 | if (recv) | ||
280 | dmabrg_rec_dma_stop(cam); | ||
281 | else | ||
282 | dmabrg_play_dma_stop(cam); | ||
283 | break; | ||
284 | default: | ||
285 | return -EINVAL; | ||
286 | } | ||
287 | |||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | static snd_pcm_uframes_t camelot_pos(struct snd_pcm_substream *substream) | ||
292 | { | ||
293 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
294 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
295 | struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id]; | ||
296 | int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; | ||
297 | unsigned long pos; | ||
298 | |||
299 | /* cannot use the DMABRG pointer register: under load, by the | ||
300 | * time ALSA comes around to read the register, it is already | ||
301 | * far ahead (or worse, already done with the fragment) of the | ||
302 | * position at the time the IRQ was triggered, which results in | ||
303 | * fast-playback sound in my test application (ScummVM) | ||
304 | */ | ||
305 | if (recv) | ||
306 | pos = cam->rx_period ? cam->rx_period_size : 0; | ||
307 | else | ||
308 | pos = cam->tx_period ? cam->tx_period_size : 0; | ||
309 | |||
310 | return bytes_to_frames(runtime, pos); | ||
311 | } | ||
312 | |||
313 | static struct snd_pcm_ops camelot_pcm_ops = { | ||
314 | .open = camelot_pcm_open, | ||
315 | .close = camelot_pcm_close, | ||
316 | .ioctl = snd_pcm_lib_ioctl, | ||
317 | .hw_params = camelot_hw_params, | ||
318 | .hw_free = camelot_hw_free, | ||
319 | .prepare = camelot_prepare, | ||
320 | .trigger = camelot_trigger, | ||
321 | .pointer = camelot_pos, | ||
322 | }; | ||
323 | |||
324 | static void camelot_pcm_free(struct snd_pcm *pcm) | ||
325 | { | ||
326 | snd_pcm_lib_preallocate_free_for_all(pcm); | ||
327 | } | ||
328 | |||
329 | static int camelot_pcm_new(struct snd_card *card, | ||
330 | struct snd_soc_codec_dai *dai, | ||
331 | struct snd_pcm *pcm) | ||
332 | { | ||
333 | /* dont use SNDRV_DMA_TYPE_DEV, since it will oops the SH kernel | ||
334 | * in MMAP mode (i.e. aplay -M) | ||
335 | */ | ||
336 | snd_pcm_lib_preallocate_pages_for_all(pcm, | ||
337 | SNDRV_DMA_TYPE_CONTINUOUS, | ||
338 | snd_dma_continuous_data(GFP_KERNEL), | ||
339 | DMABRG_PREALLOC_BUFFER, DMABRG_PREALLOC_BUFFER_MAX); | ||
340 | |||
341 | return 0; | ||
342 | } | ||
343 | |||
344 | struct snd_soc_platform sh7760_soc_platform = { | ||
345 | .name = "sh7760-pcm", | ||
346 | .pcm_ops = &camelot_pcm_ops, | ||
347 | .pcm_new = camelot_pcm_new, | ||
348 | .pcm_free = camelot_pcm_free, | ||
349 | }; | ||
350 | EXPORT_SYMBOL_GPL(sh7760_soc_platform); | ||
351 | |||
352 | MODULE_LICENSE("GPL"); | ||
353 | MODULE_DESCRIPTION("SH7760 Audio DMA (DMABRG) driver"); | ||
354 | MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>"); | ||
diff --git a/sound/soc/sh/hac.c b/sound/soc/sh/hac.c new file mode 100644 index 000000000000..8e3f03908cdb --- /dev/null +++ b/sound/soc/sh/hac.c | |||
@@ -0,0 +1,322 @@ | |||
1 | /* | ||
2 | * Hitachi Audio Controller (AC97) support for SH7760/SH7780 | ||
3 | * | ||
4 | * Copyright (c) 2007 Manuel Lauss <mano@roarinelk.homelinux.net> | ||
5 | * licensed under the terms outlined in the file COPYING at the root | ||
6 | * of the linux kernel sources. | ||
7 | * | ||
8 | * dont forget to set IPSEL/OMSEL register bits (in your board code) to | ||
9 | * enable HAC output pins! | ||
10 | */ | ||
11 | |||
12 | /* BIG FAT FIXME: although the SH7760 has 2 independent AC97 units, only | ||
13 | * the FIRST can be used since ASoC does not pass any information to the | ||
14 | * ac97_read/write() functions regarding WHICH unit to use. You'll have | ||
15 | * to edit the code a bit to use the other AC97 unit. --mlau | ||
16 | */ | ||
17 | |||
18 | #include <linux/init.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/wait.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <sound/driver.h> | ||
25 | #include <sound/core.h> | ||
26 | #include <sound/pcm.h> | ||
27 | #include <sound/ac97_codec.h> | ||
28 | #include <sound/initval.h> | ||
29 | #include <sound/soc.h> | ||
30 | |||
31 | /* regs and bits */ | ||
32 | #define HACCR 0x08 | ||
33 | #define HACCSAR 0x20 | ||
34 | #define HACCSDR 0x24 | ||
35 | #define HACPCML 0x28 | ||
36 | #define HACPCMR 0x2C | ||
37 | #define HACTIER 0x50 | ||
38 | #define HACTSR 0x54 | ||
39 | #define HACRIER 0x58 | ||
40 | #define HACRSR 0x5C | ||
41 | #define HACACR 0x60 | ||
42 | |||
43 | #define CR_CR (1 << 15) /* "codec-ready" indicator */ | ||
44 | #define CR_CDRT (1 << 11) /* cold reset */ | ||
45 | #define CR_WMRT (1 << 10) /* warm reset */ | ||
46 | #define CR_B9 (1 << 9) /* the mysterious "bit 9" */ | ||
47 | #define CR_ST (1 << 5) /* AC97 link start bit */ | ||
48 | |||
49 | #define CSAR_RD (1 << 19) /* AC97 data read bit */ | ||
50 | #define CSAR_WR (0) | ||
51 | |||
52 | #define TSR_CMDAMT (1 << 31) | ||
53 | #define TSR_CMDDMT (1 << 30) | ||
54 | |||
55 | #define RSR_STARY (1 << 22) | ||
56 | #define RSR_STDRY (1 << 21) | ||
57 | |||
58 | #define ACR_DMARX16 (1 << 30) | ||
59 | #define ACR_DMATX16 (1 << 29) | ||
60 | #define ACR_TX12ATOM (1 << 26) | ||
61 | #define ACR_DMARX20 ((1 << 24) | (1 << 22)) | ||
62 | #define ACR_DMATX20 ((1 << 23) | (1 << 21)) | ||
63 | |||
64 | #define CSDR_SHIFT 4 | ||
65 | #define CSDR_MASK (0xffff << CSDR_SHIFT) | ||
66 | #define CSAR_SHIFT 12 | ||
67 | #define CSAR_MASK (0x7f << CSAR_SHIFT) | ||
68 | |||
69 | #define AC97_WRITE_RETRY 1 | ||
70 | #define AC97_READ_RETRY 5 | ||
71 | |||
72 | /* manual-suggested AC97 codec access timeouts (us) */ | ||
73 | #define TMO_E1 500 /* 21 < E1 < 1000 */ | ||
74 | #define TMO_E2 13 /* 13 < E2 */ | ||
75 | #define TMO_E3 21 /* 21 < E3 */ | ||
76 | #define TMO_E4 500 /* 21 < E4 < 1000 */ | ||
77 | |||
78 | struct hac_priv { | ||
79 | unsigned long mmio; /* HAC base address */ | ||
80 | } hac_cpu_data[] = { | ||
81 | #if defined(CONFIG_CPU_SUBTYPE_SH7760) | ||
82 | { | ||
83 | .mmio = 0xFE240000, | ||
84 | }, | ||
85 | { | ||
86 | .mmio = 0xFE250000, | ||
87 | }, | ||
88 | #elif defined(CONFIG_CPU_SUBTYPE_SH7780) | ||
89 | { | ||
90 | .mmio = 0xFFE40000, | ||
91 | }, | ||
92 | #else | ||
93 | #error "Unsupported SuperH SoC" | ||
94 | #endif | ||
95 | }; | ||
96 | |||
97 | #define HACREG(reg) (*(unsigned long *)(hac->mmio + (reg))) | ||
98 | |||
99 | /* | ||
100 | * AC97 read/write flow as outlined in the SH7760 manual (pages 903-906) | ||
101 | */ | ||
102 | static int hac_get_codec_data(struct hac_priv *hac, unsigned short r, | ||
103 | unsigned short *v) | ||
104 | { | ||
105 | unsigned int to1, to2, i; | ||
106 | unsigned short adr; | ||
107 | |||
108 | for (i = 0; i < AC97_READ_RETRY; ++i) { | ||
109 | *v = 0; | ||
110 | /* wait for HAC to receive something from the codec */ | ||
111 | for (to1 = TMO_E4; | ||
112 | to1 && !(HACREG(HACRSR) & RSR_STARY); | ||
113 | --to1) | ||
114 | udelay(1); | ||
115 | for (to2 = TMO_E4; | ||
116 | to2 && !(HACREG(HACRSR) & RSR_STDRY); | ||
117 | --to2) | ||
118 | udelay(1); | ||
119 | |||
120 | if (!to1 && !to2) | ||
121 | return 0; /* codec comm is down */ | ||
122 | |||
123 | adr = ((HACREG(HACCSAR) & CSAR_MASK) >> CSAR_SHIFT); | ||
124 | *v = ((HACREG(HACCSDR) & CSDR_MASK) >> CSDR_SHIFT); | ||
125 | |||
126 | HACREG(HACRSR) &= ~(RSR_STDRY | RSR_STARY); | ||
127 | |||
128 | if (r == adr) | ||
129 | break; | ||
130 | |||
131 | /* manual says: wait at least 21 usec before retrying */ | ||
132 | udelay(21); | ||
133 | } | ||
134 | HACREG(HACRSR) &= ~(RSR_STDRY | RSR_STARY); | ||
135 | return (i < AC97_READ_RETRY); | ||
136 | } | ||
137 | |||
138 | static unsigned short hac_read_codec_aux(struct hac_priv *hac, | ||
139 | unsigned short reg) | ||
140 | { | ||
141 | unsigned short val; | ||
142 | unsigned int i, to; | ||
143 | |||
144 | for (i = 0; i < AC97_READ_RETRY; i++) { | ||
145 | /* send_read_request */ | ||
146 | local_irq_disable(); | ||
147 | HACREG(HACTSR) &= ~(TSR_CMDAMT); | ||
148 | HACREG(HACCSAR) = (reg << CSAR_SHIFT) | CSAR_RD; | ||
149 | local_irq_enable(); | ||
150 | |||
151 | for (to = TMO_E3; | ||
152 | to && !(HACREG(HACTSR) & TSR_CMDAMT); | ||
153 | --to) | ||
154 | udelay(1); | ||
155 | |||
156 | HACREG(HACTSR) &= ~TSR_CMDAMT; | ||
157 | val = 0; | ||
158 | if (hac_get_codec_data(hac, reg, &val) != 0) | ||
159 | break; | ||
160 | } | ||
161 | |||
162 | if (i == AC97_READ_RETRY) | ||
163 | return ~0; | ||
164 | |||
165 | return val; | ||
166 | } | ||
167 | |||
168 | static void hac_ac97_write(struct snd_ac97 *ac97, unsigned short reg, | ||
169 | unsigned short val) | ||
170 | { | ||
171 | int unit_id = 0 /* ac97->private_data */; | ||
172 | struct hac_priv *hac = &hac_cpu_data[unit_id]; | ||
173 | unsigned int i, to; | ||
174 | /* write_codec_aux */ | ||
175 | for (i = 0; i < AC97_WRITE_RETRY; i++) { | ||
176 | /* send_write_request */ | ||
177 | local_irq_disable(); | ||
178 | HACREG(HACTSR) &= ~(TSR_CMDDMT | TSR_CMDAMT); | ||
179 | HACREG(HACCSDR) = (val << CSDR_SHIFT); | ||
180 | HACREG(HACCSAR) = (reg << CSAR_SHIFT) & (~CSAR_RD); | ||
181 | local_irq_enable(); | ||
182 | |||
183 | /* poll-wait for CMDAMT and CMDDMT */ | ||
184 | for (to = TMO_E1; | ||
185 | to && !(HACREG(HACTSR) & (TSR_CMDAMT|TSR_CMDDMT)); | ||
186 | --to) | ||
187 | udelay(1); | ||
188 | |||
189 | HACREG(HACTSR) &= ~(TSR_CMDAMT | TSR_CMDDMT); | ||
190 | if (to) | ||
191 | break; | ||
192 | /* timeout, try again */ | ||
193 | } | ||
194 | } | ||
195 | |||
196 | static unsigned short hac_ac97_read(struct snd_ac97 *ac97, | ||
197 | unsigned short reg) | ||
198 | { | ||
199 | int unit_id = 0 /* ac97->private_data */; | ||
200 | struct hac_priv *hac = &hac_cpu_data[unit_id]; | ||
201 | return hac_read_codec_aux(hac, reg); | ||
202 | } | ||
203 | |||
204 | static void hac_ac97_warmrst(struct snd_ac97 *ac97) | ||
205 | { | ||
206 | int unit_id = 0 /* ac97->private_data */; | ||
207 | struct hac_priv *hac = &hac_cpu_data[unit_id]; | ||
208 | unsigned int tmo; | ||
209 | |||
210 | HACREG(HACCR) = CR_WMRT | CR_ST | CR_B9; | ||
211 | msleep(10); | ||
212 | HACREG(HACCR) = CR_ST | CR_B9; | ||
213 | for (tmo = 1000; (tmo > 0) && !(HACREG(HACCR) & CR_CR); tmo--) | ||
214 | udelay(1); | ||
215 | |||
216 | if (!tmo) | ||
217 | printk(KERN_INFO "hac: reset: AC97 link down!\n"); | ||
218 | /* settings this bit lets us have a conversation with codec */ | ||
219 | HACREG(HACACR) |= ACR_TX12ATOM; | ||
220 | } | ||
221 | |||
222 | static void hac_ac97_coldrst(struct snd_ac97 *ac97) | ||
223 | { | ||
224 | int unit_id = 0 /* ac97->private_data */; | ||
225 | struct hac_priv *hac; | ||
226 | hac = &hac_cpu_data[unit_id]; | ||
227 | |||
228 | HACREG(HACCR) = 0; | ||
229 | HACREG(HACCR) = CR_CDRT | CR_ST | CR_B9; | ||
230 | msleep(10); | ||
231 | hac_ac97_warmrst(ac97); | ||
232 | } | ||
233 | |||
234 | struct snd_ac97_bus_ops soc_ac97_ops = { | ||
235 | .read = hac_ac97_read, | ||
236 | .write = hac_ac97_write, | ||
237 | .reset = hac_ac97_coldrst, | ||
238 | .warm_reset = hac_ac97_warmrst, | ||
239 | }; | ||
240 | EXPORT_SYMBOL_GPL(soc_ac97_ops); | ||
241 | |||
242 | static int hac_hw_params(struct snd_pcm_substream *substream, | ||
243 | struct snd_pcm_hw_params *params) | ||
244 | { | ||
245 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
246 | struct hac_priv *hac = &hac_cpu_data[rtd->dai->cpu_dai->id]; | ||
247 | int d = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1; | ||
248 | |||
249 | switch (params->msbits) { | ||
250 | case 16: | ||
251 | HACREG(HACACR) |= d ? ACR_DMARX16 : ACR_DMATX16; | ||
252 | HACREG(HACACR) &= d ? ~ACR_DMARX20 : ~ACR_DMATX20; | ||
253 | break; | ||
254 | case 20: | ||
255 | HACREG(HACACR) &= d ? ~ACR_DMARX16 : ~ACR_DMATX16; | ||
256 | HACREG(HACACR) |= d ? ACR_DMARX20 : ACR_DMATX20; | ||
257 | break; | ||
258 | default: | ||
259 | pr_debug("hac: invalid depth %d bit\n", params->msbits); | ||
260 | return -EINVAL; | ||
261 | break; | ||
262 | } | ||
263 | |||
264 | return 0; | ||
265 | } | ||
266 | |||
267 | #define AC97_RATES \ | ||
268 | SNDRV_PCM_RATE_8000_192000 | ||
269 | |||
270 | #define AC97_FMTS \ | ||
271 | SNDRV_PCM_FMTBIT_S16_LE | ||
272 | |||
273 | struct snd_soc_cpu_dai sh4_hac_dai[] = { | ||
274 | { | ||
275 | .name = "HAC0", | ||
276 | .id = 0, | ||
277 | .type = SND_SOC_DAI_AC97, | ||
278 | .playback = { | ||
279 | .rates = AC97_RATES, | ||
280 | .formats = AC97_FMTS, | ||
281 | .channels_min = 2, | ||
282 | .channels_max = 2, | ||
283 | }, | ||
284 | .capture = { | ||
285 | .rates = AC97_RATES, | ||
286 | .formats = AC97_FMTS, | ||
287 | .channels_min = 2, | ||
288 | .channels_max = 2, | ||
289 | }, | ||
290 | .ops = { | ||
291 | .hw_params = hac_hw_params, | ||
292 | }, | ||
293 | }, | ||
294 | #ifdef CONFIG_CPU_SUBTYPE_SH7760 | ||
295 | { | ||
296 | .name = "HAC1", | ||
297 | .id = 1, | ||
298 | .type = SND_SOC_DAI_AC97, | ||
299 | .playback = { | ||
300 | .rates = AC97_RATES, | ||
301 | .formats = AC97_FMTS, | ||
302 | .channels_min = 2, | ||
303 | .channels_max = 2, | ||
304 | }, | ||
305 | .capture = { | ||
306 | .rates = AC97_RATES, | ||
307 | .formats = AC97_FMTS, | ||
308 | .channels_min = 2, | ||
309 | .channels_max = 2, | ||
310 | }, | ||
311 | .ops = { | ||
312 | .hw_params = hac_hw_params, | ||
313 | }, | ||
314 | |||
315 | }, | ||
316 | #endif | ||
317 | }; | ||
318 | EXPORT_SYMBOL_GPL(sh4_hac_dai); | ||
319 | |||
320 | MODULE_LICENSE("GPL"); | ||
321 | MODULE_DESCRIPTION("SuperH onchip HAC (AC97) audio driver"); | ||
322 | MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>"); | ||
diff --git a/sound/soc/sh/sh7760-ac97.c b/sound/soc/sh/sh7760-ac97.c new file mode 100644 index 000000000000..5563f14511fa --- /dev/null +++ b/sound/soc/sh/sh7760-ac97.c | |||
@@ -0,0 +1,92 @@ | |||
1 | /* | ||
2 | * Generic AC97 sound support for SH7760 | ||
3 | * | ||
4 | * (c) 2007 Manuel Lauss | ||
5 | * | ||
6 | * Licensed under the GPLv2. | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/moduleparam.h> | ||
11 | #include <linux/platform_device.h> | ||
12 | #include <sound/driver.h> | ||
13 | #include <sound/core.h> | ||
14 | #include <sound/pcm.h> | ||
15 | #include <sound/soc.h> | ||
16 | #include <sound/soc-dapm.h> | ||
17 | #include <asm/io.h> | ||
18 | |||
19 | #include "../codecs/ac97.h" | ||
20 | |||
21 | #define IPSEL 0xFE400034 | ||
22 | |||
23 | /* platform specific structs can be declared here */ | ||
24 | extern struct snd_soc_cpu_dai sh4_hac_dai[2]; | ||
25 | extern struct snd_soc_platform sh7760_soc_platform; | ||
26 | |||
27 | static int machine_init(struct snd_soc_codec *codec) | ||
28 | { | ||
29 | snd_soc_dapm_sync_endpoints(codec); | ||
30 | return 0; | ||
31 | } | ||
32 | |||
33 | static struct snd_soc_dai_link sh7760_ac97_dai = { | ||
34 | .name = "AC97", | ||
35 | .stream_name = "AC97 HiFi", | ||
36 | .cpu_dai = &sh4_hac_dai[0], /* HAC0 */ | ||
37 | .codec_dai = &ac97_dai, | ||
38 | .init = machine_init, | ||
39 | .ops = NULL, | ||
40 | }; | ||
41 | |||
42 | static struct snd_soc_machine sh7760_ac97_soc_machine = { | ||
43 | .name = "SH7760 AC97", | ||
44 | .dai_link = &sh7760_ac97_dai, | ||
45 | .num_links = 1, | ||
46 | }; | ||
47 | |||
48 | static struct snd_soc_device sh7760_ac97_snd_devdata = { | ||
49 | .machine = &sh7760_ac97_soc_machine, | ||
50 | .platform = &sh7760_soc_platform, | ||
51 | .codec_dev = &soc_codec_dev_ac97, | ||
52 | }; | ||
53 | |||
54 | static struct platform_device *sh7760_ac97_snd_device; | ||
55 | |||
56 | static int __init sh7760_ac97_init(void) | ||
57 | { | ||
58 | int ret; | ||
59 | unsigned short ipsel; | ||
60 | |||
61 | /* enable both AC97 controllers in pinmux reg */ | ||
62 | ipsel = ctrl_inw(IPSEL); | ||
63 | ctrl_outw(ipsel | (3 << 10), IPSEL); | ||
64 | |||
65 | ret = -ENOMEM; | ||
66 | sh7760_ac97_snd_device = platform_device_alloc("soc-audio", -1); | ||
67 | if (!sh7760_ac97_snd_device) | ||
68 | goto out; | ||
69 | |||
70 | platform_set_drvdata(sh7760_ac97_snd_device, | ||
71 | &sh7760_ac97_snd_devdata); | ||
72 | sh7760_ac97_snd_devdata.dev = &sh7760_ac97_snd_device->dev; | ||
73 | ret = platform_device_add(sh7760_ac97_snd_device); | ||
74 | |||
75 | if (ret) | ||
76 | platform_device_put(sh7760_ac97_snd_device); | ||
77 | |||
78 | out: | ||
79 | return ret; | ||
80 | } | ||
81 | |||
82 | static void __exit sh7760_ac97_exit(void) | ||
83 | { | ||
84 | platform_device_unregister(sh7760_ac97_snd_device); | ||
85 | } | ||
86 | |||
87 | module_init(sh7760_ac97_init); | ||
88 | module_exit(sh7760_ac97_exit); | ||
89 | |||
90 | MODULE_LICENSE("GPL"); | ||
91 | MODULE_DESCRIPTION("Generic SH7760 AC97 sound machine"); | ||
92 | MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>"); | ||
diff --git a/sound/soc/sh/ssi.c b/sound/soc/sh/ssi.c new file mode 100644 index 000000000000..b72bc316cb8e --- /dev/null +++ b/sound/soc/sh/ssi.c | |||
@@ -0,0 +1,400 @@ | |||
1 | /* | ||
2 | * Serial Sound Interface (I2S) support for SH7760/SH7780 | ||
3 | * | ||
4 | * Copyright (c) 2007 Manuel Lauss <mano@roarinelk.homelinux.net> | ||
5 | * | ||
6 | * licensed under the terms outlined in the file COPYING at the root | ||
7 | * of the linux kernel sources. | ||
8 | * | ||
9 | * dont forget to set IPSEL/OMSEL register bits (in your board code) to | ||
10 | * enable SSI output pins! | ||
11 | */ | ||
12 | |||
13 | /* | ||
14 | * LIMITATIONS: | ||
15 | * The SSI unit has only one physical data line, so full duplex is | ||
16 | * impossible. This can be remedied on the SH7760 by using the | ||
17 | * other SSI unit for recording; however the SH7780 has only 1 SSI | ||
18 | * unit, and its pins are shared with the AC97 unit, among others. | ||
19 | * | ||
20 | * FEATURES: | ||
21 | * The SSI features "compressed mode": in this mode it continuously | ||
22 | * streams PCM data over the I2S lines and uses LRCK as a handshake | ||
23 | * signal. Can be used to send compressed data (AC3/DTS) to a DSP. | ||
24 | * The number of bits sent over the wire in a frame can be adjusted | ||
25 | * and can be independent from the actual sample bit depth. This is | ||
26 | * useful to support TDM mode codecs like the AD1939 which have a | ||
27 | * fixed TDM slot size, regardless of sample resolution. | ||
28 | */ | ||
29 | |||
30 | #include <linux/init.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/platform_device.h> | ||
33 | #include <sound/driver.h> | ||
34 | #include <sound/core.h> | ||
35 | #include <sound/pcm.h> | ||
36 | #include <sound/initval.h> | ||
37 | #include <sound/soc.h> | ||
38 | #include <asm/io.h> | ||
39 | |||
40 | #define SSICR 0x00 | ||
41 | #define SSISR 0x04 | ||
42 | |||
43 | #define CR_DMAEN (1 << 28) | ||
44 | #define CR_CHNL_SHIFT 22 | ||
45 | #define CR_CHNL_MASK (3 << CR_CHNL_SHIFT) | ||
46 | #define CR_DWL_SHIFT 19 | ||
47 | #define CR_DWL_MASK (7 << CR_DWL_SHIFT) | ||
48 | #define CR_SWL_SHIFT 16 | ||
49 | #define CR_SWL_MASK (7 << CR_SWL_SHIFT) | ||
50 | #define CR_SCK_MASTER (1 << 15) /* bitclock master bit */ | ||
51 | #define CR_SWS_MASTER (1 << 14) /* wordselect master bit */ | ||
52 | #define CR_SCKP (1 << 13) /* I2Sclock polarity */ | ||
53 | #define CR_SWSP (1 << 12) /* LRCK polarity */ | ||
54 | #define CR_SPDP (1 << 11) | ||
55 | #define CR_SDTA (1 << 10) /* i2s alignment (msb/lsb) */ | ||
56 | #define CR_PDTA (1 << 9) /* fifo data alignment */ | ||
57 | #define CR_DEL (1 << 8) /* delay data by 1 i2sclk */ | ||
58 | #define CR_BREN (1 << 7) /* clock gating in burst mode */ | ||
59 | #define CR_CKDIV_SHIFT 4 | ||
60 | #define CR_CKDIV_MASK (7 << CR_CKDIV_SHIFT) /* bitclock divider */ | ||
61 | #define CR_MUTE (1 << 3) /* SSI mute */ | ||
62 | #define CR_CPEN (1 << 2) /* compressed mode */ | ||
63 | #define CR_TRMD (1 << 1) /* transmit/receive select */ | ||
64 | #define CR_EN (1 << 0) /* enable SSI */ | ||
65 | |||
66 | #define SSIREG(reg) (*(unsigned long *)(ssi->mmio + (reg))) | ||
67 | |||
68 | struct ssi_priv { | ||
69 | unsigned long mmio; | ||
70 | unsigned long sysclk; | ||
71 | int inuse; | ||
72 | } ssi_cpu_data[] = { | ||
73 | #if defined(CONFIG_CPU_SUBTYPE_SH7760) | ||
74 | { | ||
75 | .mmio = 0xFE680000, | ||
76 | }, | ||
77 | { | ||
78 | .mmio = 0xFE690000, | ||
79 | }, | ||
80 | #elif defined(CONFIG_CPU_SUBTYPE_SH7780) | ||
81 | { | ||
82 | .mmio = 0xFFE70000, | ||
83 | }, | ||
84 | #else | ||
85 | #error "Unsupported SuperH SoC" | ||
86 | #endif | ||
87 | }; | ||
88 | |||
89 | /* | ||
90 | * track usage of the SSI; it is simplex-only so prevent attempts of | ||
91 | * concurrent playback + capture. FIXME: any locking required? | ||
92 | */ | ||
93 | static int ssi_startup(struct snd_pcm_substream *substream) | ||
94 | { | ||
95 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
96 | struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id]; | ||
97 | if (ssi->inuse) { | ||
98 | pr_debug("ssi: already in use!\n"); | ||
99 | return -EBUSY; | ||
100 | } else | ||
101 | ssi->inuse = 1; | ||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | static void ssi_shutdown(struct snd_pcm_substream *substream) | ||
106 | { | ||
107 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
108 | struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id]; | ||
109 | |||
110 | ssi->inuse = 0; | ||
111 | } | ||
112 | |||
113 | static int ssi_trigger(struct snd_pcm_substream *substream, int cmd) | ||
114 | { | ||
115 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
116 | struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id]; | ||
117 | |||
118 | switch (cmd) { | ||
119 | case SNDRV_PCM_TRIGGER_START: | ||
120 | SSIREG(SSICR) |= CR_DMAEN | CR_EN; | ||
121 | break; | ||
122 | case SNDRV_PCM_TRIGGER_STOP: | ||
123 | SSIREG(SSICR) &= ~(CR_DMAEN | CR_EN); | ||
124 | break; | ||
125 | default: | ||
126 | return -EINVAL; | ||
127 | } | ||
128 | |||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | static int ssi_hw_params(struct snd_pcm_substream *substream, | ||
133 | struct snd_pcm_hw_params *params) | ||
134 | { | ||
135 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
136 | struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id]; | ||
137 | unsigned long ssicr = SSIREG(SSICR); | ||
138 | unsigned int bits, channels, swl, recv, i; | ||
139 | |||
140 | channels = params_channels(params); | ||
141 | bits = params->msbits; | ||
142 | recv = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 0 : 1; | ||
143 | |||
144 | pr_debug("ssi_hw_params() enter\nssicr was %08lx\n", ssicr); | ||
145 | pr_debug("bits: %d channels: %d\n", bits, channels); | ||
146 | |||
147 | ssicr &= ~(CR_TRMD | CR_CHNL_MASK | CR_DWL_MASK | CR_PDTA | | ||
148 | CR_SWL_MASK); | ||
149 | |||
150 | /* direction (send/receive) */ | ||
151 | if (!recv) | ||
152 | ssicr |= CR_TRMD; /* transmit */ | ||
153 | |||
154 | /* channels */ | ||
155 | if ((channels < 2) || (channels > 8) || (channels & 1)) { | ||
156 | pr_debug("ssi: invalid number of channels\n"); | ||
157 | return -EINVAL; | ||
158 | } | ||
159 | ssicr |= ((channels >> 1) - 1) << CR_CHNL_SHIFT; | ||
160 | |||
161 | /* DATA WORD LENGTH (DWL): databits in audio sample */ | ||
162 | i = 0; | ||
163 | switch (bits) { | ||
164 | case 32: ++i; | ||
165 | case 24: ++i; | ||
166 | case 22: ++i; | ||
167 | case 20: ++i; | ||
168 | case 18: ++i; | ||
169 | case 16: ++i; | ||
170 | ssicr |= i << CR_DWL_SHIFT; | ||
171 | case 8: break; | ||
172 | default: | ||
173 | pr_debug("ssi: invalid sample width\n"); | ||
174 | return -EINVAL; | ||
175 | } | ||
176 | |||
177 | /* | ||
178 | * SYSTEM WORD LENGTH: size in bits of half a frame over the I2S | ||
179 | * wires. This is usually bits_per_sample x channels/2; i.e. in | ||
180 | * Stereo mode the SWL equals DWL. SWL can be bigger than the | ||
181 | * product of (channels_per_slot x samplebits), e.g. for codecs | ||
182 | * like the AD1939 which only accept 32bit wide TDM slots. For | ||
183 | * "standard" I2S operation we set SWL = chans / 2 * DWL here. | ||
184 | * Waiting for ASoC to get TDM support ;-) | ||
185 | */ | ||
186 | if ((bits > 16) && (bits <= 24)) { | ||
187 | bits = 24; /* these are padded by the SSI */ | ||
188 | /*ssicr |= CR_PDTA;*/ /* cpu/data endianness ? */ | ||
189 | } | ||
190 | i = 0; | ||
191 | swl = (bits * channels) / 2; | ||
192 | switch (swl) { | ||
193 | case 256: ++i; | ||
194 | case 128: ++i; | ||
195 | case 64: ++i; | ||
196 | case 48: ++i; | ||
197 | case 32: ++i; | ||
198 | case 16: ++i; | ||
199 | ssicr |= i << CR_SWL_SHIFT; | ||
200 | case 8: break; | ||
201 | default: | ||
202 | pr_debug("ssi: invalid system word length computed\n"); | ||
203 | return -EINVAL; | ||
204 | } | ||
205 | |||
206 | SSIREG(SSICR) = ssicr; | ||
207 | |||
208 | pr_debug("ssi_hw_params() leave\nssicr is now %08lx\n", ssicr); | ||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | static int ssi_set_sysclk(struct snd_soc_cpu_dai *cpu_dai, int clk_id, | ||
213 | unsigned int freq, int dir) | ||
214 | { | ||
215 | struct ssi_priv *ssi = &ssi_cpu_data[cpu_dai->id]; | ||
216 | |||
217 | ssi->sysclk = freq; | ||
218 | |||
219 | return 0; | ||
220 | } | ||
221 | |||
222 | /* | ||
223 | * This divider is used to generate the SSI_SCK (I2S bitclock) from the | ||
224 | * clock at the HAC_BIT_CLK ("oversampling clock") pin. | ||
225 | */ | ||
226 | static int ssi_set_clkdiv(struct snd_soc_cpu_dai *dai, int did, int div) | ||
227 | { | ||
228 | struct ssi_priv *ssi = &ssi_cpu_data[dai->id]; | ||
229 | unsigned long ssicr; | ||
230 | int i; | ||
231 | |||
232 | i = 0; | ||
233 | ssicr = SSIREG(SSICR) & ~CR_CKDIV_MASK; | ||
234 | switch (div) { | ||
235 | case 16: ++i; | ||
236 | case 8: ++i; | ||
237 | case 4: ++i; | ||
238 | case 2: ++i; | ||
239 | SSIREG(SSICR) = ssicr | (i << CR_CKDIV_SHIFT); | ||
240 | case 1: break; | ||
241 | default: | ||
242 | pr_debug("ssi: invalid sck divider %d\n", div); | ||
243 | return -EINVAL; | ||
244 | } | ||
245 | |||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | static int ssi_set_fmt(struct snd_soc_cpu_dai *dai, unsigned int fmt) | ||
250 | { | ||
251 | struct ssi_priv *ssi = &ssi_cpu_data[dai->id]; | ||
252 | unsigned long ssicr = SSIREG(SSICR); | ||
253 | |||
254 | pr_debug("ssi_set_fmt()\nssicr was 0x%08lx\n", ssicr); | ||
255 | |||
256 | ssicr &= ~(CR_DEL | CR_PDTA | CR_BREN | CR_SWSP | CR_SCKP | | ||
257 | CR_SWS_MASTER | CR_SCK_MASTER); | ||
258 | |||
259 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
260 | case SND_SOC_DAIFMT_I2S: | ||
261 | break; | ||
262 | case SND_SOC_DAIFMT_RIGHT_J: | ||
263 | ssicr |= CR_DEL | CR_PDTA; | ||
264 | break; | ||
265 | case SND_SOC_DAIFMT_LEFT_J: | ||
266 | ssicr |= CR_DEL; | ||
267 | break; | ||
268 | default: | ||
269 | pr_debug("ssi: unsupported format\n"); | ||
270 | return -EINVAL; | ||
271 | } | ||
272 | |||
273 | switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) { | ||
274 | case SND_SOC_DAIFMT_CONT: | ||
275 | break; | ||
276 | case SND_SOC_DAIFMT_GATED: | ||
277 | ssicr |= CR_BREN; | ||
278 | break; | ||
279 | } | ||
280 | |||
281 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
282 | case SND_SOC_DAIFMT_NB_NF: | ||
283 | ssicr |= CR_SCKP; /* sample data at low clkedge */ | ||
284 | break; | ||
285 | case SND_SOC_DAIFMT_NB_IF: | ||
286 | ssicr |= CR_SCKP | CR_SWSP; | ||
287 | break; | ||
288 | case SND_SOC_DAIFMT_IB_NF: | ||
289 | break; | ||
290 | case SND_SOC_DAIFMT_IB_IF: | ||
291 | ssicr |= CR_SWSP; /* word select starts low */ | ||
292 | break; | ||
293 | default: | ||
294 | pr_debug("ssi: invalid inversion\n"); | ||
295 | return -EINVAL; | ||
296 | } | ||
297 | |||
298 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
299 | case SND_SOC_DAIFMT_CBM_CFM: | ||
300 | break; | ||
301 | case SND_SOC_DAIFMT_CBS_CFM: | ||
302 | ssicr |= CR_SCK_MASTER; | ||
303 | break; | ||
304 | case SND_SOC_DAIFMT_CBM_CFS: | ||
305 | ssicr |= CR_SWS_MASTER; | ||
306 | break; | ||
307 | case SND_SOC_DAIFMT_CBS_CFS: | ||
308 | ssicr |= CR_SWS_MASTER | CR_SCK_MASTER; | ||
309 | break; | ||
310 | default: | ||
311 | pr_debug("ssi: invalid master/slave configuration\n"); | ||
312 | return -EINVAL; | ||
313 | } | ||
314 | |||
315 | SSIREG(SSICR) = ssicr; | ||
316 | pr_debug("ssi_set_fmt() leave\nssicr is now 0x%08lx\n", ssicr); | ||
317 | |||
318 | return 0; | ||
319 | } | ||
320 | |||
321 | /* the SSI depends on an external clocksource (at HAC_BIT_CLK) even in | ||
322 | * Master mode, so really this is board specific; the SSI can do any | ||
323 | * rate with the right bitclk and divider settings. | ||
324 | */ | ||
325 | #define SSI_RATES \ | ||
326 | SNDRV_PCM_RATE_8000_192000 | ||
327 | |||
328 | /* the SSI can do 8-32 bit samples, with 8 possible channels */ | ||
329 | #define SSI_FMTS \ | ||
330 | (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \ | ||
331 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE | \ | ||
332 | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_U20_3LE | \ | ||
333 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3LE | \ | ||
334 | SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE) | ||
335 | |||
336 | struct snd_soc_cpu_dai sh4_ssi_dai[] = { | ||
337 | { | ||
338 | .name = "SSI0", | ||
339 | .id = 0, | ||
340 | .type = SND_SOC_DAI_I2S, | ||
341 | .playback = { | ||
342 | .rates = SSI_RATES, | ||
343 | .formats = SSI_FMTS, | ||
344 | .channels_min = 2, | ||
345 | .channels_max = 8, | ||
346 | }, | ||
347 | .capture = { | ||
348 | .rates = SSI_RATES, | ||
349 | .formats = SSI_FMTS, | ||
350 | .channels_min = 2, | ||
351 | .channels_max = 8, | ||
352 | }, | ||
353 | .ops = { | ||
354 | .startup = ssi_startup, | ||
355 | .shutdown = ssi_shutdown, | ||
356 | .trigger = ssi_trigger, | ||
357 | .hw_params = ssi_hw_params, | ||
358 | }, | ||
359 | .dai_ops = { | ||
360 | .set_sysclk = ssi_set_sysclk, | ||
361 | .set_clkdiv = ssi_set_clkdiv, | ||
362 | .set_fmt = ssi_set_fmt, | ||
363 | }, | ||
364 | }, | ||
365 | #ifdef CONFIG_CPU_SUBTYPE_SH7760 | ||
366 | { | ||
367 | .name = "SSI1", | ||
368 | .id = 1, | ||
369 | .type = SND_SOC_DAI_I2S, | ||
370 | .playback = { | ||
371 | .rates = SSI_RATES, | ||
372 | .formats = SSI_FMTS, | ||
373 | .channels_min = 2, | ||
374 | .channels_max = 8, | ||
375 | }, | ||
376 | .capture = { | ||
377 | .rates = SSI_RATES, | ||
378 | .formats = SSI_FMTS, | ||
379 | .channels_min = 2, | ||
380 | .channels_max = 8, | ||
381 | }, | ||
382 | .ops = { | ||
383 | .startup = ssi_startup, | ||
384 | .shutdown = ssi_shutdown, | ||
385 | .trigger = ssi_trigger, | ||
386 | .hw_params = ssi_hw_params, | ||
387 | }, | ||
388 | .dai_ops = { | ||
389 | .set_sysclk = ssi_set_sysclk, | ||
390 | .set_clkdiv = ssi_set_clkdiv, | ||
391 | .set_fmt = ssi_set_fmt, | ||
392 | }, | ||
393 | }, | ||
394 | #endif | ||
395 | }; | ||
396 | EXPORT_SYMBOL_GPL(sh4_ssi_dai); | ||
397 | |||
398 | MODULE_LICENSE("GPL"); | ||
399 | MODULE_DESCRIPTION("SuperH onchip SSI (I2S) audio driver"); | ||
400 | MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>"); | ||
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 8ebc1adb5ed9..7bd5852fcc0d 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c | |||
@@ -2350,7 +2350,9 @@ static int is_big_endian_format(struct snd_usb_audio *chip, struct audioformat * | |||
2350 | return 1; | 2350 | return 1; |
2351 | break; | 2351 | break; |
2352 | case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */ | 2352 | case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */ |
2353 | return 1; | 2353 | if (device_setup[chip->index] == 0x00 || |
2354 | fp->altsetting==1 || fp->altsetting==2 || fp->altsetting==3) | ||
2355 | return 1; | ||
2354 | } | 2356 | } |
2355 | return 0; | 2357 | return 0; |
2356 | } | 2358 | } |
@@ -2530,7 +2532,18 @@ static int parse_audio_format_i(struct snd_usb_audio *chip, struct audioformat * | |||
2530 | * but we give normal PCM format to get the existing | 2532 | * but we give normal PCM format to get the existing |
2531 | * apps working... | 2533 | * apps working... |
2532 | */ | 2534 | */ |
2533 | pcm_format = SNDRV_PCM_FORMAT_S16_LE; | 2535 | switch (chip->usb_id) { |
2536 | |||
2537 | case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */ | ||
2538 | if (device_setup[chip->index] == 0x00 && | ||
2539 | fp->altsetting == 6) | ||
2540 | pcm_format = SNDRV_PCM_FORMAT_S16_BE; | ||
2541 | else | ||
2542 | pcm_format = SNDRV_PCM_FORMAT_S16_LE; | ||
2543 | break; | ||
2544 | default: | ||
2545 | pcm_format = SNDRV_PCM_FORMAT_S16_LE; | ||
2546 | } | ||
2534 | } else { | 2547 | } else { |
2535 | pcm_format = parse_audio_format_i_type(chip, fp, format, fmt); | 2548 | pcm_format = parse_audio_format_i_type(chip, fp, format, fmt); |
2536 | if (pcm_format < 0) | 2549 | if (pcm_format < 0) |
@@ -3251,6 +3264,11 @@ static int snd_usb_cm106_boot_quirk(struct usb_device *dev) | |||
3251 | static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip, | 3264 | static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip, |
3252 | int iface, int altno) | 3265 | int iface, int altno) |
3253 | { | 3266 | { |
3267 | /* Reset ALL ifaces to 0 altsetting. | ||
3268 | * Call it for every possible altsetting of every interface. | ||
3269 | */ | ||
3270 | usb_set_interface(chip->dev, iface, 0); | ||
3271 | |||
3254 | if (device_setup[chip->index] & AUDIOPHILE_SET) { | 3272 | if (device_setup[chip->index] & AUDIOPHILE_SET) { |
3255 | if ((device_setup[chip->index] & AUDIOPHILE_SET_DTS) | 3273 | if ((device_setup[chip->index] & AUDIOPHILE_SET_DTS) |
3256 | && altno != 6) | 3274 | && altno != 6) |
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h index 374fbf657a2d..5a2f518c6629 100644 --- a/sound/usb/usbquirks.h +++ b/sound/usb/usbquirks.h | |||
@@ -57,6 +57,24 @@ | |||
57 | USB_DEVICE_ID_MATCH_INT_CLASS | | 57 | USB_DEVICE_ID_MATCH_INT_CLASS | |
58 | USB_DEVICE_ID_MATCH_INT_SUBCLASS, | 58 | USB_DEVICE_ID_MATCH_INT_SUBCLASS, |
59 | .idVendor = 0x046d, | 59 | .idVendor = 0x046d, |
60 | .idProduct = 0x08ae, | ||
61 | .bInterfaceClass = USB_CLASS_AUDIO, | ||
62 | .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL | ||
63 | }, | ||
64 | { | ||
65 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | | ||
66 | USB_DEVICE_ID_MATCH_INT_CLASS | | ||
67 | USB_DEVICE_ID_MATCH_INT_SUBCLASS, | ||
68 | .idVendor = 0x046d, | ||
69 | .idProduct = 0x08c6, | ||
70 | .bInterfaceClass = USB_CLASS_AUDIO, | ||
71 | .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL | ||
72 | }, | ||
73 | { | ||
74 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | | ||
75 | USB_DEVICE_ID_MATCH_INT_CLASS | | ||
76 | USB_DEVICE_ID_MATCH_INT_SUBCLASS, | ||
77 | .idVendor = 0x046d, | ||
60 | .idProduct = 0x08f0, | 78 | .idProduct = 0x08f0, |
61 | .bInterfaceClass = USB_CLASS_AUDIO, | 79 | .bInterfaceClass = USB_CLASS_AUDIO, |
62 | .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL | 80 | .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL |
@@ -1051,7 +1069,15 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
1051 | .type = QUIRK_MIDI_STANDARD_INTERFACE | 1069 | .type = QUIRK_MIDI_STANDARD_INTERFACE |
1052 | } | 1070 | } |
1053 | }, | 1071 | }, |
1054 | /* TODO: add Roland EXR support */ | 1072 | { |
1073 | USB_DEVICE(0x0582, 0x0060), | ||
1074 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
1075 | .vendor_name = "Roland", | ||
1076 | .product_name = "EXR Series", | ||
1077 | .ifnum = 0, | ||
1078 | .type = QUIRK_MIDI_STANDARD_INTERFACE | ||
1079 | } | ||
1080 | }, | ||
1055 | { | 1081 | { |
1056 | /* has ID 0x0067 when not in "Advanced Driver" mode */ | 1082 | /* has ID 0x0067 when not in "Advanced Driver" mode */ |
1057 | USB_DEVICE(0x0582, 0x0065), | 1083 | USB_DEVICE(0x0582, 0x0065), |
@@ -1094,6 +1120,19 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
1094 | } | 1120 | } |
1095 | } | 1121 | } |
1096 | }, | 1122 | }, |
1123 | { | ||
1124 | USB_DEVICE(0x582, 0x00a6), | ||
1125 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
1126 | .vendor_name = "Roland", | ||
1127 | .product_name = "Juno-G", | ||
1128 | .ifnum = 0, | ||
1129 | .type = QUIRK_MIDI_FIXED_ENDPOINT, | ||
1130 | .data = & (const struct snd_usb_midi_endpoint_info) { | ||
1131 | .out_cables = 0x0001, | ||
1132 | .in_cables = 0x0001 | ||
1133 | } | ||
1134 | } | ||
1135 | }, | ||
1097 | { /* | 1136 | { /* |
1098 | * This quirk is for the "Advanced" modes of the Edirol UA-25. | 1137 | * This quirk is for the "Advanced" modes of the Edirol UA-25. |
1099 | * If the switch is not in an advanced setting, the UA-25 has | 1138 | * If the switch is not in an advanced setting, the UA-25 has |
@@ -1230,6 +1269,37 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
1230 | } | 1269 | } |
1231 | }, | 1270 | }, |
1232 | /* TODO: add Edirol MD-P1 support */ | 1271 | /* TODO: add Edirol MD-P1 support */ |
1272 | { | ||
1273 | /* Roland SH-201 */ | ||
1274 | USB_DEVICE(0x0582, 0x00ad), | ||
1275 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
1276 | .vendor_name = "Roland", | ||
1277 | .product_name = "SH-201", | ||
1278 | .ifnum = QUIRK_ANY_INTERFACE, | ||
1279 | .type = QUIRK_COMPOSITE, | ||
1280 | .data = (const struct snd_usb_audio_quirk[]) { | ||
1281 | { | ||
1282 | .ifnum = 0, | ||
1283 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
1284 | }, | ||
1285 | { | ||
1286 | .ifnum = 1, | ||
1287 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
1288 | }, | ||
1289 | { | ||
1290 | .ifnum = 2, | ||
1291 | .type = QUIRK_MIDI_FIXED_ENDPOINT, | ||
1292 | .data = & (const struct snd_usb_midi_endpoint_info) { | ||
1293 | .out_cables = 0x0001, | ||
1294 | .in_cables = 0x0001 | ||
1295 | } | ||
1296 | }, | ||
1297 | { | ||
1298 | .ifnum = -1 | ||
1299 | } | ||
1300 | } | ||
1301 | } | ||
1302 | }, | ||
1233 | 1303 | ||
1234 | /* Guillemot devices */ | 1304 | /* Guillemot devices */ |
1235 | { | 1305 | { |
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c index 0a352e46862f..48e9aa3f18c9 100644 --- a/sound/usb/usx2y/usbusx2yaudio.c +++ b/sound/usb/usx2y/usbusx2yaudio.c | |||
@@ -935,10 +935,9 @@ static struct snd_pcm_ops snd_usX2Y_pcm_ops = | |||
935 | */ | 935 | */ |
936 | static void usX2Y_audio_stream_free(struct snd_usX2Y_substream **usX2Y_substream) | 936 | static void usX2Y_audio_stream_free(struct snd_usX2Y_substream **usX2Y_substream) |
937 | { | 937 | { |
938 | if (NULL != usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]) { | 938 | kfree(usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]); |
939 | kfree(usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]); | 939 | usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK] = NULL; |
940 | usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK] = NULL; | 940 | |
941 | } | ||
942 | kfree(usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE]); | 941 | kfree(usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE]); |
943 | usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE] = NULL; | 942 | usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE] = NULL; |
944 | } | 943 | } |