diff options
184 files changed, 9309 insertions, 3050 deletions
diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uvc b/Documentation/ABI/testing/configfs-usb-gadget-uvc new file mode 100644 index 000000000000..2f4a0051b32d --- /dev/null +++ b/Documentation/ABI/testing/configfs-usb-gadget-uvc | |||
@@ -0,0 +1,265 @@ | |||
1 | What: /config/usb-gadget/gadget/functions/uvc.name | ||
2 | Date: Dec 2014 | ||
3 | KernelVersion: 3.20 | ||
4 | Description: UVC function directory | ||
5 | |||
6 | streaming_maxburst - 0..15 (ss only) | ||
7 | streaming_maxpacket - 1..1023 (fs), 1..3072 (hs/ss) | ||
8 | streaming_interval - 1..16 | ||
9 | |||
10 | What: /config/usb-gadget/gadget/functions/uvc.name/control | ||
11 | Date: Dec 2014 | ||
12 | KernelVersion: 3.20 | ||
13 | Description: Control descriptors | ||
14 | |||
15 | What: /config/usb-gadget/gadget/functions/uvc.name/control/class | ||
16 | Date: Dec 2014 | ||
17 | KernelVersion: 3.20 | ||
18 | Description: Class descriptors | ||
19 | |||
20 | What: /config/usb-gadget/gadget/functions/uvc.name/control/class/ss | ||
21 | Date: Dec 2014 | ||
22 | KernelVersion: 3.20 | ||
23 | Description: Super speed control class descriptors | ||
24 | |||
25 | What: /config/usb-gadget/gadget/functions/uvc.name/control/class/fs | ||
26 | Date: Dec 2014 | ||
27 | KernelVersion: 3.20 | ||
28 | Description: Full speed control class descriptors | ||
29 | |||
30 | What: /config/usb-gadget/gadget/functions/uvc.name/control/terminal | ||
31 | Date: Dec 2014 | ||
32 | KernelVersion: 3.20 | ||
33 | Description: Terminal descriptors | ||
34 | |||
35 | What: /config/usb-gadget/gadget/functions/uvc.name/control/terminal/output | ||
36 | Date: Dec 2014 | ||
37 | KernelVersion: 3.20 | ||
38 | Description: Output terminal descriptors | ||
39 | |||
40 | What: /config/usb-gadget/gadget/functions/uvc.name/control/terminal/output/default | ||
41 | Date: Dec 2014 | ||
42 | KernelVersion: 3.20 | ||
43 | Description: Default output terminal descriptors | ||
44 | |||
45 | All attributes read only: | ||
46 | iTerminal - index of string descriptor | ||
47 | bSourceID - id of the terminal to which this terminal | ||
48 | is connected | ||
49 | bAssocTerminal - id of the input terminal to which this output | ||
50 | terminal is associated | ||
51 | wTerminalType - terminal type | ||
52 | bTerminalID - a non-zero id of this terminal | ||
53 | |||
54 | What: /config/usb-gadget/gadget/functions/uvc.name/control/terminal/camera | ||
55 | Date: Dec 2014 | ||
56 | KernelVersion: 3.20 | ||
57 | Description: Camera terminal descriptors | ||
58 | |||
59 | What: /config/usb-gadget/gadget/functions/uvc.name/control/terminal/camera/default | ||
60 | Date: Dec 2014 | ||
61 | KernelVersion: 3.20 | ||
62 | Description: Default camera terminal descriptors | ||
63 | |||
64 | All attributes read only: | ||
65 | bmControls - bitmap specifying which controls are | ||
66 | supported for the video stream | ||
67 | wOcularFocalLength - the value of Locular | ||
68 | wObjectiveFocalLengthMax- the value of Lmin | ||
69 | wObjectiveFocalLengthMin- the value of Lmax | ||
70 | iTerminal - index of string descriptor | ||
71 | bAssocTerminal - id of the output terminal to which | ||
72 | this terminal is connected | ||
73 | wTerminalType - terminal type | ||
74 | bTerminalID - a non-zero id of this terminal | ||
75 | |||
76 | What: /config/usb-gadget/gadget/functions/uvc.name/control/processing | ||
77 | Date: Dec 2014 | ||
78 | KernelVersion: 3.20 | ||
79 | Description: Processing unit descriptors | ||
80 | |||
81 | What: /config/usb-gadget/gadget/functions/uvc.name/control/processing/default | ||
82 | Date: Dec 2014 | ||
83 | KernelVersion: 3.20 | ||
84 | Description: Default processing unit descriptors | ||
85 | |||
86 | All attributes read only: | ||
87 | iProcessing - index of string descriptor | ||
88 | bmControls - bitmap specifying which controls are | ||
89 | supported for the video stream | ||
90 | wMaxMultiplier - maximum digital magnification x100 | ||
91 | bSourceID - id of the terminal to which this unit is | ||
92 | connected | ||
93 | bUnitID - a non-zero id of this unit | ||
94 | |||
95 | What: /config/usb-gadget/gadget/functions/uvc.name/control/header | ||
96 | Date: Dec 2014 | ||
97 | KernelVersion: 3.20 | ||
98 | Description: Control header descriptors | ||
99 | |||
100 | What: /config/usb-gadget/gadget/functions/uvc.name/control/header/name | ||
101 | Date: Dec 2014 | ||
102 | KernelVersion: 3.20 | ||
103 | Description: Specific control header descriptors | ||
104 | |||
105 | dwClockFrequency | ||
106 | bcdUVC | ||
107 | What: /config/usb-gadget/gadget/functions/uvc.name/streaming | ||
108 | Date: Dec 2014 | ||
109 | KernelVersion: 3.20 | ||
110 | Description: Streaming descriptors | ||
111 | |||
112 | What: /config/usb-gadget/gadget/functions/uvc.name/streaming/class | ||
113 | Date: Dec 2014 | ||
114 | KernelVersion: 3.20 | ||
115 | Description: Streaming class descriptors | ||
116 | |||
117 | What: /config/usb-gadget/gadget/functions/uvc.name/streaming/class/ss | ||
118 | Date: Dec 2014 | ||
119 | KernelVersion: 3.20 | ||
120 | Description: Super speed streaming class descriptors | ||
121 | |||
122 | What: /config/usb-gadget/gadget/functions/uvc.name/streaming/class/hs | ||
123 | Date: Dec 2014 | ||
124 | KernelVersion: 3.20 | ||
125 | Description: High speed streaming class descriptors | ||
126 | |||
127 | What: /config/usb-gadget/gadget/functions/uvc.name/streaming/class/fs | ||
128 | Date: Dec 2014 | ||
129 | KernelVersion: 3.20 | ||
130 | Description: Full speed streaming class descriptors | ||
131 | |||
132 | What: /config/usb-gadget/gadget/functions/uvc.name/streaming/color_matching | ||
133 | Date: Dec 2014 | ||
134 | KernelVersion: 3.20 | ||
135 | Description: Color matching descriptors | ||
136 | |||
137 | What: /config/usb-gadget/gadget/functions/uvc.name/streaming/color_matching/default | ||
138 | Date: Dec 2014 | ||
139 | KernelVersion: 3.20 | ||
140 | Description: Default color matching descriptors | ||
141 | |||
142 | All attributes read only: | ||
143 | bMatrixCoefficients - matrix used to compute luma and | ||
144 | chroma values from the color primaries | ||
145 | bTransferCharacteristics- optoelectronic transfer | ||
146 | characteristic of the source picutre, | ||
147 | also called the gamma function | ||
148 | bColorPrimaries - color primaries and the reference | ||
149 | white | ||
150 | |||
151 | What: /config/usb-gadget/gadget/functions/uvc.name/streaming/mjpeg | ||
152 | Date: Dec 2014 | ||
153 | KernelVersion: 3.20 | ||
154 | Description: MJPEG format descriptors | ||
155 | |||
156 | What: /config/usb-gadget/gadget/functions/uvc.name/streaming/mjpeg/name | ||
157 | Date: Dec 2014 | ||
158 | KernelVersion: 3.20 | ||
159 | Description: Specific MJPEG format descriptors | ||
160 | |||
161 | All attributes read only, | ||
162 | except bmaControls and bDefaultFrameIndex: | ||
163 | bmaControls - this format's data for bmaControls in | ||
164 | the streaming header | ||
165 | bmInterfaceFlags - specifies interlace information, | ||
166 | read-only | ||
167 | bAspectRatioY - the X dimension of the picture aspect | ||
168 | ratio, read-only | ||
169 | bAspectRatioX - the Y dimension of the picture aspect | ||
170 | ratio, read-only | ||
171 | bmFlags - characteristics of this format, | ||
172 | read-only | ||
173 | bDefaultFrameIndex - optimum frame index for this stream | ||
174 | |||
175 | What: /config/usb-gadget/gadget/functions/uvc.name/streaming/mjpeg/name/name | ||
176 | Date: Dec 2014 | ||
177 | KernelVersion: 3.20 | ||
178 | Description: Specific MJPEG frame descriptors | ||
179 | |||
180 | dwFrameInterval - indicates how frame interval can be | ||
181 | programmed; a number of values | ||
182 | separated by newline can be specified | ||
183 | dwDefaultFrameInterval - the frame interval the device would | ||
184 | like to use as default | ||
185 | dwMaxVideoFrameBufferSize- the maximum number of bytes the | ||
186 | compressor will produce for a video | ||
187 | frame or still image | ||
188 | dwMaxBitRate - the maximum bit rate at the shortest | ||
189 | frame interval in bps | ||
190 | dwMinBitRate - the minimum bit rate at the longest | ||
191 | frame interval in bps | ||
192 | wHeight - height of decoded bitmap frame in px | ||
193 | wWidth - width of decoded bitmam frame in px | ||
194 | bmCapabilities - still image support, fixed frame-rate | ||
195 | support | ||
196 | |||
197 | What: /config/usb-gadget/gadget/functions/uvc.name/streaming/uncompressed | ||
198 | Date: Dec 2014 | ||
199 | KernelVersion: 3.20 | ||
200 | Description: Uncompressed format descriptors | ||
201 | |||
202 | What: /config/usb-gadget/gadget/functions/uvc.name/streaming/uncompressed/name | ||
203 | Date: Dec 2014 | ||
204 | KernelVersion: 3.20 | ||
205 | Description: Specific uncompressed format descriptors | ||
206 | |||
207 | bmaControls - this format's data for bmaControls in | ||
208 | the streaming header | ||
209 | bmInterfaceFlags - specifies interlace information, | ||
210 | read-only | ||
211 | bAspectRatioY - the X dimension of the picture aspect | ||
212 | ratio, read-only | ||
213 | bAspectRatioX - the Y dimension of the picture aspect | ||
214 | ratio, read-only | ||
215 | bDefaultFrameIndex - optimum frame index for this stream | ||
216 | bBitsPerPixel - number of bits per pixel used to | ||
217 | specify color in the decoded video | ||
218 | frame | ||
219 | guidFormat - globally unique id used to identify | ||
220 | stream-encoding format | ||
221 | |||
222 | What: /config/usb-gadget/gadget/functions/uvc.name/streaming/uncompressed/name/name | ||
223 | Date: Dec 2014 | ||
224 | KernelVersion: 3.20 | ||
225 | Description: Specific uncompressed frame descriptors | ||
226 | |||
227 | dwFrameInterval - indicates how frame interval can be | ||
228 | programmed; a number of values | ||
229 | separated by newline can be specified | ||
230 | dwDefaultFrameInterval - the frame interval the device would | ||
231 | like to use as default | ||
232 | dwMaxVideoFrameBufferSize- the maximum number of bytes the | ||
233 | compressor will produce for a video | ||
234 | frame or still image | ||
235 | dwMaxBitRate - the maximum bit rate at the shortest | ||
236 | frame interval in bps | ||
237 | dwMinBitRate - the minimum bit rate at the longest | ||
238 | frame interval in bps | ||
239 | wHeight - height of decoded bitmap frame in px | ||
240 | wWidth - width of decoded bitmam frame in px | ||
241 | bmCapabilities - still image support, fixed frame-rate | ||
242 | support | ||
243 | |||
244 | What: /config/usb-gadget/gadget/functions/uvc.name/streaming/header | ||
245 | Date: Dec 2014 | ||
246 | KernelVersion: 3.20 | ||
247 | Description: Streaming header descriptors | ||
248 | |||
249 | What: /config/usb-gadget/gadget/functions/uvc.name/streaming/header/name | ||
250 | Date: Dec 2014 | ||
251 | KernelVersion: 3.20 | ||
252 | Description: Specific streaming header descriptors | ||
253 | |||
254 | All attributes read only: | ||
255 | bTriggerUsage - how the host software will respond to | ||
256 | a hardware trigger interrupt event | ||
257 | bTriggerSupport - flag specifying if hardware | ||
258 | triggering is supported | ||
259 | bStillCaptureMethod - method of still image caputre | ||
260 | supported | ||
261 | bTerminalLink - id of the output terminal to which | ||
262 | the video endpoint of this interface | ||
263 | is connected | ||
264 | bmInfo - capabilities of this video streaming | ||
265 | interface | ||
diff --git a/Documentation/devicetree/bindings/phy/phy-miphy28lp.txt b/Documentation/devicetree/bindings/phy/phy-miphy28lp.txt index 46a135dae6b3..89caa885d08c 100644 --- a/Documentation/devicetree/bindings/phy/phy-miphy28lp.txt +++ b/Documentation/devicetree/bindings/phy/phy-miphy28lp.txt | |||
@@ -26,6 +26,7 @@ Required properties (port (child) node): | |||
26 | filled in "reg". It can also contain the offset of the system configuration | 26 | filled in "reg". It can also contain the offset of the system configuration |
27 | registers used as glue-logic to setup the device for SATA/PCIe or USB3 | 27 | registers used as glue-logic to setup the device for SATA/PCIe or USB3 |
28 | devices. | 28 | devices. |
29 | - st,syscfg : Offset of the parent configuration register. | ||
29 | - resets : phandle to the parent reset controller. | 30 | - resets : phandle to the parent reset controller. |
30 | - reset-names : Associated name must be "miphy-sw-rst". | 31 | - reset-names : Associated name must be "miphy-sw-rst". |
31 | 32 | ||
@@ -54,18 +55,12 @@ example: | |||
54 | phy_port0: port@9b22000 { | 55 | phy_port0: port@9b22000 { |
55 | reg = <0x9b22000 0xff>, | 56 | reg = <0x9b22000 0xff>, |
56 | <0x9b09000 0xff>, | 57 | <0x9b09000 0xff>, |
57 | <0x9b04000 0xff>, | 58 | <0x9b04000 0xff>; |
58 | <0x114 0x4>, /* sysctrl MiPHY cntrl */ | ||
59 | <0x818 0x4>, /* sysctrl MiPHY status*/ | ||
60 | <0xe0 0x4>, /* sysctrl PCIe */ | ||
61 | <0xec 0x4>; /* sysctrl SATA */ | ||
62 | reg-names = "sata-up", | 59 | reg-names = "sata-up", |
63 | "pcie-up", | 60 | "pcie-up", |
64 | "pipew", | 61 | "pipew"; |
65 | "miphy-ctrl-glue", | 62 | |
66 | "miphy-status-glue", | 63 | st,syscfg = <0x114 0x818 0xe0 0xec>; |
67 | "pcie-glue", | ||
68 | "sata-glue"; | ||
69 | #phy-cells = <1>; | 64 | #phy-cells = <1>; |
70 | st,osc-rdy; | 65 | st,osc-rdy; |
71 | reset-names = "miphy-sw-rst"; | 66 | reset-names = "miphy-sw-rst"; |
@@ -75,18 +70,13 @@ example: | |||
75 | phy_port1: port@9b2a000 { | 70 | phy_port1: port@9b2a000 { |
76 | reg = <0x9b2a000 0xff>, | 71 | reg = <0x9b2a000 0xff>, |
77 | <0x9b19000 0xff>, | 72 | <0x9b19000 0xff>, |
78 | <0x9b14000 0xff>, | 73 | <0x9b14000 0xff>; |
79 | <0x118 0x4>, | ||
80 | <0x81c 0x4>, | ||
81 | <0xe4 0x4>, | ||
82 | <0xf0 0x4>; | ||
83 | reg-names = "sata-up", | 74 | reg-names = "sata-up", |
84 | "pcie-up", | 75 | "pcie-up", |
85 | "pipew", | 76 | "pipew"; |
86 | "miphy-ctrl-glue", | 77 | |
87 | "miphy-status-glue", | 78 | st,syscfg = <0x118 0x81c 0xe4 0xf0>; |
88 | "pcie-glue", | 79 | |
89 | "sata-glue"; | ||
90 | #phy-cells = <1>; | 80 | #phy-cells = <1>; |
91 | st,osc-force-ext; | 81 | st,osc-force-ext; |
92 | reset-names = "miphy-sw-rst"; | 82 | reset-names = "miphy-sw-rst"; |
@@ -95,13 +85,12 @@ example: | |||
95 | 85 | ||
96 | phy_port2: port@8f95000 { | 86 | phy_port2: port@8f95000 { |
97 | reg = <0x8f95000 0xff>, | 87 | reg = <0x8f95000 0xff>, |
98 | <0x8f90000 0xff>, | 88 | <0x8f90000 0xff>; |
99 | <0x11c 0x4>, | ||
100 | <0x820 0x4>; | ||
101 | reg-names = "pipew", | 89 | reg-names = "pipew", |
102 | "usb3-up", | 90 | "usb3-up"; |
103 | "miphy-ctrl-glue", | 91 | |
104 | "miphy-status-glue"; | 92 | st,syscfg = <0x11c 0x820>; |
93 | |||
105 | #phy-cells = <1>; | 94 | #phy-cells = <1>; |
106 | reset-names = "miphy-sw-rst"; | 95 | reset-names = "miphy-sw-rst"; |
107 | resets = <&softreset STIH407_MIPHY2_SOFTRESET>; | 96 | resets = <&softreset STIH407_MIPHY2_SOFTRESET>; |
@@ -125,4 +114,4 @@ example: | |||
125 | 114 | ||
126 | Macro definitions for the supported miphy configuration can be found in: | 115 | Macro definitions for the supported miphy configuration can be found in: |
127 | 116 | ||
128 | include/dt-bindings/phy/phy-miphy28lp.h | 117 | include/dt-bindings/phy/phy.h |
diff --git a/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt b/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt new file mode 100644 index 000000000000..826454ac43bb --- /dev/null +++ b/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt | |||
@@ -0,0 +1,37 @@ | |||
1 | ROCKCHIP USB2 PHY | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: rockchip,rk3288-usb-phy | ||
5 | - rockchip,grf : phandle to the syscon managing the "general | ||
6 | register files" | ||
7 | - #address-cells: should be 1 | ||
8 | - #size-cells: should be 0 | ||
9 | |||
10 | Sub-nodes: | ||
11 | Each PHY should be represented as a sub-node. | ||
12 | |||
13 | Sub-nodes | ||
14 | required properties: | ||
15 | - #phy-cells: should be 0 | ||
16 | - reg: PHY configure reg address offset in GRF | ||
17 | "0x320" - for PHY attach to OTG controller | ||
18 | "0x334" - for PHY attach to HOST0 controller | ||
19 | "0x348" - for PHY attach to HOST1 controller | ||
20 | |||
21 | Optional Properties: | ||
22 | - clocks : phandle + clock specifier for the phy clocks | ||
23 | - clock-names: string, clock name, must be "phyclk" | ||
24 | |||
25 | Example: | ||
26 | |||
27 | usbphy: phy { | ||
28 | compatible = "rockchip,rk3288-usb-phy"; | ||
29 | rockchip,grf = <&grf>; | ||
30 | #address-cells = <1>; | ||
31 | #size-cells = <0>; | ||
32 | |||
33 | usbphy0: usb-phy0 { | ||
34 | #phy-cells = <0>; | ||
35 | reg = <0x320>; | ||
36 | }; | ||
37 | }; | ||
diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt index d5bad920827f..91e38cfe1f8f 100644 --- a/Documentation/devicetree/bindings/phy/samsung-phy.txt +++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt | |||
@@ -3,8 +3,8 @@ Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY | |||
3 | 3 | ||
4 | Required properties: | 4 | Required properties: |
5 | - compatible : should be "samsung,s5pv210-mipi-video-phy"; | 5 | - compatible : should be "samsung,s5pv210-mipi-video-phy"; |
6 | - reg : offset and length of the MIPI DPHY register set; | ||
7 | - #phy-cells : from the generic phy bindings, must be 1; | 6 | - #phy-cells : from the generic phy bindings, must be 1; |
7 | - syscon - phandle to the PMU system controller; | ||
8 | 8 | ||
9 | For "samsung,s5pv210-mipi-video-phy" compatible PHYs the second cell in | 9 | For "samsung,s5pv210-mipi-video-phy" compatible PHYs the second cell in |
10 | the PHY specifier identifies the PHY and its meaning is as follows: | 10 | the PHY specifier identifies the PHY and its meaning is as follows: |
diff --git a/Documentation/devicetree/bindings/usb/atmel-usb.txt b/Documentation/devicetree/bindings/usb/atmel-usb.txt index bc2222ca3f2a..38fee0f66c12 100644 --- a/Documentation/devicetree/bindings/usb/atmel-usb.txt +++ b/Documentation/devicetree/bindings/usb/atmel-usb.txt | |||
@@ -51,7 +51,10 @@ usb1: gadget@fffa4000 { | |||
51 | Atmel High-Speed USB device controller | 51 | Atmel High-Speed USB device controller |
52 | 52 | ||
53 | Required properties: | 53 | Required properties: |
54 | - compatible: Should be "atmel,at91sam9rl-udc" | 54 | - compatible: Should be one of the following |
55 | "at91sam9rl-udc" | ||
56 | "at91sam9g45-udc" | ||
57 | "sama5d3-udc" | ||
55 | - reg: Address and length of the register set for the device | 58 | - reg: Address and length of the register set for the device |
56 | - interrupts: Should contain usba interrupt | 59 | - interrupts: Should contain usba interrupt |
57 | - ep childnode: To specify the number of endpoints and their properties. | 60 | - ep childnode: To specify the number of endpoints and their properties. |
diff --git a/Documentation/devicetree/bindings/usb/dwc2.txt b/Documentation/devicetree/bindings/usb/dwc2.txt index 482f815363ef..fd132cbee70e 100644 --- a/Documentation/devicetree/bindings/usb/dwc2.txt +++ b/Documentation/devicetree/bindings/usb/dwc2.txt | |||
@@ -20,6 +20,10 @@ Optional properties: | |||
20 | Refer to phy/phy-bindings.txt for generic phy consumer properties | 20 | Refer to phy/phy-bindings.txt for generic phy consumer properties |
21 | - dr_mode: shall be one of "host", "peripheral" and "otg" | 21 | - dr_mode: shall be one of "host", "peripheral" and "otg" |
22 | Refer to usb/generic.txt | 22 | Refer to usb/generic.txt |
23 | - g-use-dma: enable dma usage in gadget driver. | ||
24 | - g-rx-fifo-size: size of rx fifo size in gadget mode. | ||
25 | - g-np-tx-fifo-size: size of non-periodic tx fifo size in gadget mode. | ||
26 | - g-tx-fifo-size: size of periodic tx fifo per endpoint (except ep0) in gadget mode. | ||
23 | 27 | ||
24 | Example: | 28 | Example: |
25 | 29 | ||
diff --git a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt index b08c903f8668..61b045b6d50e 100644 --- a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt +++ b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt | |||
@@ -14,6 +14,8 @@ Optional properties: | |||
14 | function should be enabled | 14 | function should be enabled |
15 | - phys: phandle + phy specifier pair | 15 | - phys: phandle + phy specifier pair |
16 | - phy-names: must be "usb" | 16 | - phy-names: must be "usb" |
17 | - dmas: Must contain a list of references to DMA specifiers. | ||
18 | - dma-names : Must contain a list of DMA names, "tx" or "rx". | ||
17 | 19 | ||
18 | Example: | 20 | Example: |
19 | usbhs: usb@e6590000 { | 21 | usbhs: usb@e6590000 { |
diff --git a/Documentation/devicetree/bindings/usb/usb-ehci.txt b/Documentation/devicetree/bindings/usb/usb-ehci.txt index 43c1a4e06767..0b04fdff9d5a 100644 --- a/Documentation/devicetree/bindings/usb/usb-ehci.txt +++ b/Documentation/devicetree/bindings/usb/usb-ehci.txt | |||
@@ -12,6 +12,7 @@ Optional properties: | |||
12 | - big-endian-regs : boolean, set this for hcds with big-endian registers | 12 | - big-endian-regs : boolean, set this for hcds with big-endian registers |
13 | - big-endian-desc : boolean, set this for hcds with big-endian descriptors | 13 | - big-endian-desc : boolean, set this for hcds with big-endian descriptors |
14 | - big-endian : boolean, for hcds with big-endian-regs + big-endian-desc | 14 | - big-endian : boolean, for hcds with big-endian-regs + big-endian-desc |
15 | - needs-reset-on-resume : boolean, set this to force EHCI reset after resume | ||
15 | - clocks : a list of phandle + clock specifier pairs | 16 | - clocks : a list of phandle + clock specifier pairs |
16 | - phys : phandle + phy specifier pair | 17 | - phys : phandle + phy specifier pair |
17 | - phy-names : "usb" | 18 | - phy-names : "usb" |
diff --git a/Documentation/devicetree/bindings/usb/usb-nop-xceiv.txt b/Documentation/devicetree/bindings/usb/usb-nop-xceiv.txt index 1bd37faba05b..5be01c859b7a 100644 --- a/Documentation/devicetree/bindings/usb/usb-nop-xceiv.txt +++ b/Documentation/devicetree/bindings/usb/usb-nop-xceiv.txt | |||
@@ -13,10 +13,15 @@ Optional properties: | |||
13 | - clock-frequency: the clock frequency (in Hz) that the PHY clock must | 13 | - clock-frequency: the clock frequency (in Hz) that the PHY clock must |
14 | be configured to. | 14 | be configured to. |
15 | 15 | ||
16 | - vcc-supply: phandle to the regulator that provides RESET to the PHY. | 16 | - vcc-supply: phandle to the regulator that provides power to the PHY. |
17 | 17 | ||
18 | - reset-gpios: Should specify the GPIO for reset. | 18 | - reset-gpios: Should specify the GPIO for reset. |
19 | 19 | ||
20 | - vbus-detect-gpio: should specify the GPIO detecting a VBus insertion | ||
21 | (see Documentation/devicetree/bindings/gpio/gpio.txt) | ||
22 | - vbus-regulator : should specifiy the regulator supplying current drawn from | ||
23 | the VBus line (see Documentation/devicetree/bindings/regulator/regulator.txt). | ||
24 | |||
20 | Example: | 25 | Example: |
21 | 26 | ||
22 | hsusb1_phy { | 27 | hsusb1_phy { |
@@ -26,8 +31,11 @@ Example: | |||
26 | clock-names = "main_clk"; | 31 | clock-names = "main_clk"; |
27 | vcc-supply = <&hsusb1_vcc_regulator>; | 32 | vcc-supply = <&hsusb1_vcc_regulator>; |
28 | reset-gpios = <&gpio1 7 GPIO_ACTIVE_LOW>; | 33 | reset-gpios = <&gpio1 7 GPIO_ACTIVE_LOW>; |
34 | vbus-detect-gpio = <&gpio2 13 GPIO_ACTIVE_HIGH>; | ||
35 | vbus-regulator = <&vbus_regulator>; | ||
29 | }; | 36 | }; |
30 | 37 | ||
31 | hsusb1_phy is a NOP USB PHY device that gets its clock from an oscillator | 38 | hsusb1_phy is a NOP USB PHY device that gets its clock from an oscillator |
32 | and expects that clock to be configured to 19.2MHz by the NOP PHY driver. | 39 | and expects that clock to be configured to 19.2MHz by the NOP PHY driver. |
33 | hsusb1_vcc_regulator provides power to the PHY and GPIO 7 controls RESET. | 40 | hsusb1_vcc_regulator provides power to the PHY and GPIO 7 controls RESET. |
41 | GPIO 13 detects VBus insertion, and accordingly notifies the vbus-regulator. | ||
diff --git a/Documentation/usb/gadget-testing.txt b/Documentation/usb/gadget-testing.txt new file mode 100644 index 000000000000..076ac7ba7f93 --- /dev/null +++ b/Documentation/usb/gadget-testing.txt | |||
@@ -0,0 +1,728 @@ | |||
1 | This file summarizes information on basic testing of USB functions | ||
2 | provided by gadgets. | ||
3 | |||
4 | 1. ACM function | ||
5 | 2. ECM function | ||
6 | 3. ECM subset function | ||
7 | 4. EEM function | ||
8 | 5. FFS function | ||
9 | 6. HID function | ||
10 | 7. LOOPBACK function | ||
11 | 8. MASS STORAGE function | ||
12 | 9. MIDI function | ||
13 | 10. NCM function | ||
14 | 11. OBEX function | ||
15 | 12. PHONET function | ||
16 | 13. RNDIS function | ||
17 | 14. SERIAL function | ||
18 | 15. SOURCESINK function | ||
19 | 16. UAC1 function | ||
20 | 17. UAC2 function | ||
21 | 18. UVC function | ||
22 | |||
23 | |||
24 | 1. ACM function | ||
25 | =============== | ||
26 | |||
27 | The function is provided by usb_f_acm.ko module. | ||
28 | |||
29 | Function-specific configfs interface | ||
30 | ------------------------------------ | ||
31 | |||
32 | The function name to use when creating the function directory is "acm". | ||
33 | The ACM function provides just one attribute in its function directory: | ||
34 | |||
35 | port_num | ||
36 | |||
37 | The attribute is read-only. | ||
38 | |||
39 | There can be at most 4 ACM/generic serial/OBEX ports in the system. | ||
40 | |||
41 | |||
42 | Testing the ACM function | ||
43 | ------------------------ | ||
44 | |||
45 | On the host: cat > /dev/ttyACM<X> | ||
46 | On the device : cat /dev/ttyGS<Y> | ||
47 | |||
48 | then the other way round | ||
49 | |||
50 | On the device: cat > /dev/ttyGS<Y> | ||
51 | On the host: cat /dev/ttyACM<X> | ||
52 | |||
53 | 2. ECM function | ||
54 | =============== | ||
55 | |||
56 | The function is provided by usb_f_ecm.ko module. | ||
57 | |||
58 | Function-specific configfs interface | ||
59 | ------------------------------------ | ||
60 | |||
61 | The function name to use when creating the function directory is "ecm". | ||
62 | The ECM function provides these attributes in its function directory: | ||
63 | |||
64 | ifname - network device interface name associated with this | ||
65 | function instance | ||
66 | qmult - queue length multiplier for high and super speed | ||
67 | host_addr - MAC address of host's end of this | ||
68 | Ethernet over USB link | ||
69 | dev_addr - MAC address of device's end of this | ||
70 | Ethernet over USB link | ||
71 | |||
72 | and after creating the functions/ecm.<instance name> they contain default | ||
73 | values: qmult is 5, dev_addr and host_addr are randomly selected. | ||
74 | Except for ifname they can be written to until the function is linked to a | ||
75 | configuration. The ifname is read-only and contains the name of the interface | ||
76 | which was assigned by the net core, e. g. usb0. | ||
77 | |||
78 | Testing the ECM function | ||
79 | ------------------------ | ||
80 | |||
81 | Configure IP addresses of the device and the host. Then: | ||
82 | |||
83 | On the device: ping <host's IP> | ||
84 | On the host: ping <device's IP> | ||
85 | |||
86 | 3. ECM subset function | ||
87 | ====================== | ||
88 | |||
89 | The function is provided by usb_f_ecm_subset.ko module. | ||
90 | |||
91 | Function-specific configfs interface | ||
92 | ------------------------------------ | ||
93 | |||
94 | The function name to use when creating the function directory is "geth". | ||
95 | The ECM subset function provides these attributes in its function directory: | ||
96 | |||
97 | ifname - network device interface name associated with this | ||
98 | function instance | ||
99 | qmult - queue length multiplier for high and super speed | ||
100 | host_addr - MAC address of host's end of this | ||
101 | Ethernet over USB link | ||
102 | dev_addr - MAC address of device's end of this | ||
103 | Ethernet over USB link | ||
104 | |||
105 | and after creating the functions/ecm.<instance name> they contain default | ||
106 | values: qmult is 5, dev_addr and host_addr are randomly selected. | ||
107 | Except for ifname they can be written to until the function is linked to a | ||
108 | configuration. The ifname is read-only and contains the name of the interface | ||
109 | which was assigned by the net core, e. g. usb0. | ||
110 | |||
111 | Testing the ECM subset function | ||
112 | ------------------------------- | ||
113 | |||
114 | Configure IP addresses of the device and the host. Then: | ||
115 | |||
116 | On the device: ping <host's IP> | ||
117 | On the host: ping <device's IP> | ||
118 | |||
119 | 4. EEM function | ||
120 | =============== | ||
121 | |||
122 | The function is provided by usb_f_eem.ko module. | ||
123 | |||
124 | Function-specific configfs interface | ||
125 | ------------------------------------ | ||
126 | |||
127 | The function name to use when creating the function directory is "eem". | ||
128 | The EEM function provides these attributes in its function directory: | ||
129 | |||
130 | ifname - network device interface name associated with this | ||
131 | function instance | ||
132 | qmult - queue length multiplier for high and super speed | ||
133 | host_addr - MAC address of host's end of this | ||
134 | Ethernet over USB link | ||
135 | dev_addr - MAC address of device's end of this | ||
136 | Ethernet over USB link | ||
137 | |||
138 | and after creating the functions/eem.<instance name> they contain default | ||
139 | values: qmult is 5, dev_addr and host_addr are randomly selected. | ||
140 | Except for ifname they can be written to until the function is linked to a | ||
141 | configuration. The ifname is read-only and contains the name of the interface | ||
142 | which was assigned by the net core, e. g. usb0. | ||
143 | |||
144 | Testing the EEM function | ||
145 | ------------------------ | ||
146 | |||
147 | Configure IP addresses of the device and the host. Then: | ||
148 | |||
149 | On the device: ping <host's IP> | ||
150 | On the host: ping <device's IP> | ||
151 | |||
152 | 5. FFS function | ||
153 | =============== | ||
154 | |||
155 | The function is provided by usb_f_fs.ko module. | ||
156 | |||
157 | Function-specific configfs interface | ||
158 | ------------------------------------ | ||
159 | |||
160 | The function name to use when creating the function directory is "ffs". | ||
161 | The function directory is intentionally empty and not modifiable. | ||
162 | |||
163 | After creating the directory there is a new instance (a "device") of FunctionFS | ||
164 | available in the system. Once a "device" is available, the user should follow | ||
165 | the standard procedure for using FunctionFS (mount it, run the userspace | ||
166 | process which implements the function proper). The gadget should be enabled | ||
167 | by writing a suitable string to usb_gadget/<gadget>/UDC. | ||
168 | |||
169 | Testing the FFS function | ||
170 | ------------------------ | ||
171 | |||
172 | On the device: start the function's userspace daemon, enable the gadget | ||
173 | On the host: use the USB function provided by the device | ||
174 | |||
175 | 6. HID function | ||
176 | =============== | ||
177 | |||
178 | The function is provided by usb_f_hid.ko module. | ||
179 | |||
180 | Function-specific configfs interface | ||
181 | ------------------------------------ | ||
182 | |||
183 | The function name to use when creating the function directory is "hid". | ||
184 | The HID function provides these attributes in its function directory: | ||
185 | |||
186 | protocol - HID protocol to use | ||
187 | report_desc - data to be used in HID reports, except data | ||
188 | passed with /dev/hidg<X> | ||
189 | report_length - HID report length | ||
190 | subclass - HID subclass to use | ||
191 | |||
192 | For a keyboard the protocol and the subclass are 1, the report_length is 8, | ||
193 | while the report_desc is: | ||
194 | |||
195 | $ hd my_report_desc | ||
196 | 00000000 05 01 09 06 a1 01 05 07 19 e0 29 e7 15 00 25 01 |..........)...%.| | ||
197 | 00000010 75 01 95 08 81 02 95 01 75 08 81 03 95 05 75 01 |u.......u.....u.| | ||
198 | 00000020 05 08 19 01 29 05 91 02 95 01 75 03 91 03 95 06 |....).....u.....| | ||
199 | 00000030 75 08 15 00 25 65 05 07 19 00 29 65 81 00 c0 |u...%e....)e...| | ||
200 | 0000003f | ||
201 | |||
202 | Such a sequence of bytes can be stored to the attribute with echo: | ||
203 | |||
204 | $ echo -ne \\x05\\x01\\x09\\x06\\xa1..... | ||
205 | |||
206 | Testing the HID function | ||
207 | ------------------------ | ||
208 | |||
209 | Device: | ||
210 | - create the gadget | ||
211 | - connect the gadget to a host, preferably not the one used | ||
212 | to control the gadget | ||
213 | - run a program which writes to /dev/hidg<N>, e.g. | ||
214 | a userspace program found in Documentation/usb/gadget_hid.txt: | ||
215 | |||
216 | $ ./hid_gadget_test /dev/hidg0 keyboard | ||
217 | |||
218 | Host: | ||
219 | - observe the keystrokes from the gadget | ||
220 | |||
221 | 7. LOOPBACK function | ||
222 | ==================== | ||
223 | |||
224 | The function is provided by usb_f_ss_lb.ko module. | ||
225 | |||
226 | Function-specific configfs interface | ||
227 | ------------------------------------ | ||
228 | |||
229 | The function name to use when creating the function directory is "Loopback". | ||
230 | The LOOPBACK function provides these attributes in its function directory: | ||
231 | |||
232 | qlen - depth of loopback queue | ||
233 | bulk_buflen - buffer length | ||
234 | |||
235 | Testing the LOOPBACK function | ||
236 | ----------------------------- | ||
237 | |||
238 | device: run the gadget | ||
239 | host: test-usb | ||
240 | |||
241 | http://www.linux-usb.org/usbtest/testusb.c | ||
242 | |||
243 | 8. MASS STORAGE function | ||
244 | ======================== | ||
245 | |||
246 | The function is provided by usb_f_mass_storage.ko module. | ||
247 | |||
248 | Function-specific configfs interface | ||
249 | ------------------------------------ | ||
250 | |||
251 | The function name to use when creating the function directory is "mass_storage". | ||
252 | The MASS STORAGE function provides these attributes in its directory: | ||
253 | files: | ||
254 | |||
255 | stall - Set to permit function to halt bulk endpoints. | ||
256 | Disabled on some USB devices known not to work | ||
257 | correctly. You should set it to true. | ||
258 | num_buffers - Number of pipeline buffers. Valid numbers | ||
259 | are 2..4. Available only if | ||
260 | CONFIG_USB_GADGET_DEBUG_FILES is set. | ||
261 | |||
262 | and a default lun.0 directory corresponding to SCSI LUN #0. | ||
263 | |||
264 | A new lun can be added with mkdir: | ||
265 | |||
266 | $ mkdir functions/mass_storage.0/partition.5 | ||
267 | |||
268 | Lun numbering does not have to be continuous, except for lun #0 which is | ||
269 | created by default. A maximum of 8 luns can be specified and they all must be | ||
270 | named following the <name>.<number> scheme. The numbers can be 0..8. | ||
271 | Probably a good convention is to name the luns "lun.<number>", | ||
272 | although it is not mandatory. | ||
273 | |||
274 | In each lun directory there are the following attribute files: | ||
275 | |||
276 | file - The path to the backing file for the LUN. | ||
277 | Required if LUN is not marked as removable. | ||
278 | ro - Flag specifying access to the LUN shall be | ||
279 | read-only. This is implied if CD-ROM emulation | ||
280 | is enabled as well as when it was impossible | ||
281 | to open "filename" in R/W mode. | ||
282 | removable - Flag specifying that LUN shall be indicated as | ||
283 | being removable. | ||
284 | cdrom - Flag specifying that LUN shall be reported as | ||
285 | being a CD-ROM. | ||
286 | nofua - Flag specifying that FUA flag | ||
287 | in SCSI WRITE(10,12) | ||
288 | |||
289 | Testing the MASS STORAGE function | ||
290 | --------------------------------- | ||
291 | |||
292 | device: connect the gadget, enable it | ||
293 | host: dmesg, see the USB drives appear (if system configured to automatically | ||
294 | mount) | ||
295 | |||
296 | 9. MIDI function | ||
297 | ================ | ||
298 | |||
299 | The function is provided by usb_f_midi.ko module. | ||
300 | |||
301 | Function-specific configfs interface | ||
302 | ------------------------------------ | ||
303 | |||
304 | The function name to use when creating the function directory is "midi". | ||
305 | The MIDI function provides these attributes in its function directory: | ||
306 | |||
307 | buflen - MIDI buffer length | ||
308 | id - ID string for the USB MIDI adapter | ||
309 | in_ports - number of MIDI input ports | ||
310 | index - index value for the USB MIDI adapter | ||
311 | out_ports - number of MIDI output ports | ||
312 | qlen - USB read request queue length | ||
313 | |||
314 | Testing the MIDI function | ||
315 | ------------------------- | ||
316 | |||
317 | There are two cases: playing a mid from the gadget to | ||
318 | the host and playing a mid from the host to the gadget. | ||
319 | |||
320 | 1) Playing a mid from the gadget to the host | ||
321 | host) | ||
322 | |||
323 | $ arecordmidi -l | ||
324 | Port Client name Port name | ||
325 | 14:0 Midi Through Midi Through Port-0 | ||
326 | 24:0 MIDI Gadget MIDI Gadget MIDI 1 | ||
327 | $ arecordmidi -p 24:0 from_gadget.mid | ||
328 | |||
329 | gadget) | ||
330 | |||
331 | $ aplaymidi -l | ||
332 | Port Client name Port name | ||
333 | 20:0 f_midi f_midi | ||
334 | |||
335 | $ aplaymidi -p 20:0 to_host.mid | ||
336 | |||
337 | 2) Playing a mid from the host to the gadget | ||
338 | gadget) | ||
339 | |||
340 | $ arecordmidi -l | ||
341 | Port Client name Port name | ||
342 | 20:0 f_midi f_midi | ||
343 | |||
344 | $ arecordmidi -p 20:0 from_host.mid | ||
345 | |||
346 | host) | ||
347 | |||
348 | $ aplaymidi -l | ||
349 | Port Client name Port name | ||
350 | 14:0 Midi Through Midi Through Port-0 | ||
351 | 24:0 MIDI Gadget MIDI Gadget MIDI 1 | ||
352 | |||
353 | $ aplaymidi -p24:0 to_gadget.mid | ||
354 | |||
355 | The from_gadget.mid should sound identical to the to_host.mid. | ||
356 | The from_host.id should sound identical to the to_gadget.mid. | ||
357 | |||
358 | MIDI files can be played to speakers/headphones with e.g. timidity installed | ||
359 | |||
360 | $ aplaymidi -l | ||
361 | Port Client name Port name | ||
362 | 14:0 Midi Through Midi Through Port-0 | ||
363 | 24:0 MIDI Gadget MIDI Gadget MIDI 1 | ||
364 | 128:0 TiMidity TiMidity port 0 | ||
365 | 128:1 TiMidity TiMidity port 1 | ||
366 | 128:2 TiMidity TiMidity port 2 | ||
367 | 128:3 TiMidity TiMidity port 3 | ||
368 | |||
369 | $ aplaymidi -p 128:0 file.mid | ||
370 | |||
371 | MIDI ports can be logically connected using the aconnect utility, e.g.: | ||
372 | |||
373 | $ aconnect 24:0 128:0 # try it on the host | ||
374 | |||
375 | After the gadget's MIDI port is connected to timidity's MIDI port, | ||
376 | whatever is played at the gadget side with aplaymidi -l is audible | ||
377 | in host's speakers/headphones. | ||
378 | |||
379 | 10. NCM function | ||
380 | ================ | ||
381 | |||
382 | The function is provided by usb_f_ncm.ko module. | ||
383 | |||
384 | Function-specific configfs interface | ||
385 | ------------------------------------ | ||
386 | |||
387 | The function name to use when creating the function directory is "ncm". | ||
388 | The NCM function provides these attributes in its function directory: | ||
389 | |||
390 | ifname - network device interface name associated with this | ||
391 | function instance | ||
392 | qmult - queue length multiplier for high and super speed | ||
393 | host_addr - MAC address of host's end of this | ||
394 | Ethernet over USB link | ||
395 | dev_addr - MAC address of device's end of this | ||
396 | Ethernet over USB link | ||
397 | |||
398 | and after creating the functions/ncm.<instance name> they contain default | ||
399 | values: qmult is 5, dev_addr and host_addr are randomly selected. | ||
400 | Except for ifname they can be written to until the function is linked to a | ||
401 | configuration. The ifname is read-only and contains the name of the interface | ||
402 | which was assigned by the net core, e. g. usb0. | ||
403 | |||
404 | Testing the NCM function | ||
405 | ------------------------ | ||
406 | |||
407 | Configure IP addresses of the device and the host. Then: | ||
408 | |||
409 | On the device: ping <host's IP> | ||
410 | On the host: ping <device's IP> | ||
411 | |||
412 | 11. OBEX function | ||
413 | ================= | ||
414 | |||
415 | The function is provided by usb_f_obex.ko module. | ||
416 | |||
417 | Function-specific configfs interface | ||
418 | ------------------------------------ | ||
419 | |||
420 | The function name to use when creating the function directory is "obex". | ||
421 | The OBEX function provides just one attribute in its function directory: | ||
422 | |||
423 | port_num | ||
424 | |||
425 | The attribute is read-only. | ||
426 | |||
427 | There can be at most 4 ACM/generic serial/OBEX ports in the system. | ||
428 | |||
429 | Testing the OBEX function | ||
430 | ------------------------- | ||
431 | |||
432 | On device: seriald -f /dev/ttyGS<Y> -s 1024 | ||
433 | On host: serialc -v <vendorID> -p <productID> -i<interface#> -a1 -s1024 \ | ||
434 | -t<out endpoint addr> -r<in endpoint addr> | ||
435 | |||
436 | where seriald and serialc are Felipe's utilities found here: | ||
437 | |||
438 | https://git.gitorious.org/usb/usb-tools.git master | ||
439 | |||
440 | 12. PHONET function | ||
441 | =================== | ||
442 | |||
443 | The function is provided by usb_f_phonet.ko module. | ||
444 | |||
445 | Function-specific configfs interface | ||
446 | ------------------------------------ | ||
447 | |||
448 | The function name to use when creating the function directory is "phonet". | ||
449 | The PHONET function provides just one attribute in its function directory: | ||
450 | |||
451 | ifname - network device interface name associated with this | ||
452 | function instance | ||
453 | |||
454 | Testing the PHONET function | ||
455 | --------------------------- | ||
456 | |||
457 | It is not possible to test the SOCK_STREAM protocol without a specific piece | ||
458 | of hardware, so only SOCK_DGRAM has been tested. For the latter to work, | ||
459 | in the past I had to apply the patch mentioned here: | ||
460 | |||
461 | http://www.spinics.net/lists/linux-usb/msg85689.html | ||
462 | |||
463 | These tools are required: | ||
464 | |||
465 | git://git.gitorious.org/meego-cellular/phonet-utils.git | ||
466 | |||
467 | On the host: | ||
468 | |||
469 | $ ./phonet -a 0x10 -i usbpn0 | ||
470 | $ ./pnroute add 0x6c usbpn0 | ||
471 | $./pnroute add 0x10 usbpn0 | ||
472 | $ ifconfig usbpn0 up | ||
473 | |||
474 | On the device: | ||
475 | |||
476 | $ ./phonet -a 0x6c -i upnlink0 | ||
477 | $ ./pnroute add 0x10 upnlink0 | ||
478 | $ ifconfig upnlink0 up | ||
479 | |||
480 | Then a test program can be used: | ||
481 | |||
482 | http://www.spinics.net/lists/linux-usb/msg85690.html | ||
483 | |||
484 | On the device: | ||
485 | |||
486 | $ ./pnxmit -a 0x6c -r | ||
487 | |||
488 | On the host: | ||
489 | |||
490 | $ ./pnxmit -a 0x10 -s 0x6c | ||
491 | |||
492 | As a result some data should be sent from host to device. | ||
493 | Then the other way round: | ||
494 | |||
495 | On the host: | ||
496 | |||
497 | $ ./pnxmit -a 0x10 -r | ||
498 | |||
499 | On the device: | ||
500 | |||
501 | $ ./pnxmit -a 0x6c -s 0x10 | ||
502 | |||
503 | 13. RNDIS function | ||
504 | ================== | ||
505 | |||
506 | The function is provided by usb_f_rndis.ko module. | ||
507 | |||
508 | Function-specific configfs interface | ||
509 | ------------------------------------ | ||
510 | |||
511 | The function name to use when creating the function directory is "rndis". | ||
512 | The RNDIS function provides these attributes in its function directory: | ||
513 | |||
514 | ifname - network device interface name associated with this | ||
515 | function instance | ||
516 | qmult - queue length multiplier for high and super speed | ||
517 | host_addr - MAC address of host's end of this | ||
518 | Ethernet over USB link | ||
519 | dev_addr - MAC address of device's end of this | ||
520 | Ethernet over USB link | ||
521 | |||
522 | and after creating the functions/rndis.<instance name> they contain default | ||
523 | values: qmult is 5, dev_addr and host_addr are randomly selected. | ||
524 | Except for ifname they can be written to until the function is linked to a | ||
525 | configuration. The ifname is read-only and contains the name of the interface | ||
526 | which was assigned by the net core, e. g. usb0. | ||
527 | |||
528 | By default there can be only 1 RNDIS interface in the system. | ||
529 | |||
530 | Testing the RNDIS function | ||
531 | -------------------------- | ||
532 | |||
533 | Configure IP addresses of the device and the host. Then: | ||
534 | |||
535 | On the device: ping <host's IP> | ||
536 | On the host: ping <device's IP> | ||
537 | |||
538 | 14. SERIAL function | ||
539 | =================== | ||
540 | |||
541 | The function is provided by usb_f_gser.ko module. | ||
542 | |||
543 | Function-specific configfs interface | ||
544 | ------------------------------------ | ||
545 | |||
546 | The function name to use when creating the function directory is "gser". | ||
547 | The SERIAL function provides just one attribute in its function directory: | ||
548 | |||
549 | port_num | ||
550 | |||
551 | The attribute is read-only. | ||
552 | |||
553 | There can be at most 4 ACM/generic serial/OBEX ports in the system. | ||
554 | |||
555 | Testing the SERIAL function | ||
556 | --------------------------- | ||
557 | |||
558 | On host: insmod usbserial | ||
559 | echo VID PID >/sys/bus/usb-serial/drivers/generic/new_id | ||
560 | On host: cat > /dev/ttyUSB<X> | ||
561 | On target: cat /dev/ttyGS<Y> | ||
562 | |||
563 | then the other way round | ||
564 | |||
565 | On target: cat > /dev/ttyGS<Y> | ||
566 | On host: cat /dev/ttyUSB<X> | ||
567 | |||
568 | 15. SOURCESINK function | ||
569 | ======================= | ||
570 | |||
571 | The function is provided by usb_f_ss_lb.ko module. | ||
572 | |||
573 | Function-specific configfs interface | ||
574 | ------------------------------------ | ||
575 | |||
576 | The function name to use when creating the function directory is "SourceSink". | ||
577 | The SOURCESINK function provides these attributes in its function directory: | ||
578 | |||
579 | pattern - 0 (all zeros), 1 (mod63), 2 (none) | ||
580 | isoc_interval - 1..16 | ||
581 | isoc_maxpacket - 0 - 1023 (fs), 0 - 1024 (hs/ss) | ||
582 | isoc_mult - 0..2 (hs/ss only) | ||
583 | isoc_maxburst - 0..15 (ss only) | ||
584 | bulk_buflen - buffer length | ||
585 | |||
586 | Testing the SOURCESINK function | ||
587 | ------------------------------- | ||
588 | |||
589 | device: run the gadget | ||
590 | host: test-usb | ||
591 | |||
592 | http://www.linux-usb.org/usbtest/testusb.c | ||
593 | |||
594 | 16. UAC1 function | ||
595 | ================= | ||
596 | |||
597 | The function is provided by usb_f_uac1.ko module. | ||
598 | |||
599 | Function-specific configfs interface | ||
600 | ------------------------------------ | ||
601 | |||
602 | The function name to use when creating the function directory is "uac1". | ||
603 | The uac1 function provides these attributes in its function directory: | ||
604 | |||
605 | audio_buf_size - audio buffer size | ||
606 | fn_cap - capture pcm device file name | ||
607 | fn_cntl - control device file name | ||
608 | fn_play - playback pcm device file name | ||
609 | req_buf_size - ISO OUT endpoint request buffer size | ||
610 | req_count - ISO OUT endpoint request count | ||
611 | |||
612 | The attributes have sane default values. | ||
613 | |||
614 | Testing the UAC1 function | ||
615 | ------------------------- | ||
616 | |||
617 | device: run the gadget | ||
618 | host: aplay -l # should list our USB Audio Gadget | ||
619 | |||
620 | 17. UAC2 function | ||
621 | ================= | ||
622 | |||
623 | The function is provided by usb_f_uac2.ko module. | ||
624 | |||
625 | Function-specific configfs interface | ||
626 | ------------------------------------ | ||
627 | |||
628 | The function name to use when creating the function directory is "uac2". | ||
629 | The uac2 function provides these attributes in its function directory: | ||
630 | |||
631 | chmask - capture channel mask | ||
632 | c_srate - capture sampling rate | ||
633 | c_ssize - capture sample size (bytes) | ||
634 | p_chmask - playback channel mask | ||
635 | p_srate - playback sampling rate | ||
636 | p_ssize - playback sample size (bytes) | ||
637 | |||
638 | The attributes have sane default values. | ||
639 | |||
640 | Testing the UAC2 function | ||
641 | ------------------------- | ||
642 | |||
643 | device: run the gadget | ||
644 | host: aplay -l # should list our USB Audio Gadget | ||
645 | |||
646 | This function does not require real hardware support, it just | ||
647 | sends a stream of audio data to/from the host. In order to | ||
648 | actually hear something at the device side, a command similar | ||
649 | to this must be used at the device side: | ||
650 | |||
651 | $ arecord -f dat -t wav -D hw:2,0 | aplay -D hw:0,0 & | ||
652 | |||
653 | e.g.: | ||
654 | |||
655 | $ arecord -f dat -t wav -D hw:CARD=UAC2Gadget,DEV=0 | \ | ||
656 | aplay -D default:CARD=OdroidU3 | ||
657 | |||
658 | 18. UVC function | ||
659 | ================ | ||
660 | |||
661 | The function is provided by usb_f_uvc.ko module. | ||
662 | |||
663 | Function-specific configfs interface | ||
664 | ------------------------------------ | ||
665 | |||
666 | The function name to use when creating the function directory is "uvc". | ||
667 | The uvc function provides these attributes in its function directory: | ||
668 | |||
669 | streaming_interval - interval for polling endpoint for data transfers | ||
670 | streaming_maxburst - bMaxBurst for super speed companion descriptor | ||
671 | streaming_maxpacket - maximum packet size this endpoint is capable of | ||
672 | sending or receiving when this configuration is | ||
673 | selected | ||
674 | |||
675 | There are also "control" and "streaming" subdirectories, each of which contain | ||
676 | a number of their subdirectories. There are some sane defaults provided, but | ||
677 | the user must provide the following: | ||
678 | |||
679 | control header - create in control/header, link from control/class/fs | ||
680 | and/or control/class/ss | ||
681 | streaming header - create in streaming/header, link from | ||
682 | streaming/class/fs and/or streaming/class/hs and/or | ||
683 | streaming/class/ss | ||
684 | format description - create in streaming/mjpeg and/or | ||
685 | streaming/uncompressed | ||
686 | frame description - create in streaming/mjpeg/<format> and/or in | ||
687 | streaming/uncompressed/<format> | ||
688 | |||
689 | Each frame description contains frame interval specification, and each | ||
690 | such specification consists of a number of lines with an inverval value | ||
691 | in each line. The rules stated above are best illustrated with an example: | ||
692 | |||
693 | # mkdir functions/uvc.usb0/control/header/h | ||
694 | # cd functions/uvc.usb0/control/header/h | ||
695 | # ln -s header/h class/fs | ||
696 | # ln -s header/h class/ss | ||
697 | # mkdir -p functions/uvc.usb0/streaming/uncompressed/u/360p | ||
698 | # cat <<EOF > functions/uvc.usb0/streaming/uncompressed/u/360p/dwFrameInterval | ||
699 | 666666 | ||
700 | 1000000 | ||
701 | 5000000 | ||
702 | EOF | ||
703 | # cd $GADGET_CONFIGFS_ROOT | ||
704 | # mkdir functions/uvc.usb0/streaming/header/h | ||
705 | # cd functions/uvc.usb0/streaming/header/h | ||
706 | # ln -s ../../uncompressed/u | ||
707 | # cd ../../class/fs | ||
708 | # ln -s ../../header/h | ||
709 | # cd ../../class/hs | ||
710 | # ln -s ../../header/h | ||
711 | # cd ../../class/ss | ||
712 | # ln -s ../../header/h | ||
713 | |||
714 | |||
715 | Testing the UVC function | ||
716 | ------------------------ | ||
717 | |||
718 | device: run the gadget, modprobe vivid | ||
719 | |||
720 | # uvc-gadget -u /dev/video<uvc video node #> -v /dev/video<vivid video node #> | ||
721 | |||
722 | where uvc-gadget is this program: | ||
723 | http://git.ideasonboard.org/uvc-gadget.git | ||
724 | |||
725 | with these patches: | ||
726 | http://www.spinics.net/lists/linux-usb/msg99220.html | ||
727 | |||
728 | host: luvcview -f yuv | ||
diff --git a/Documentation/usb/gadget_serial.txt b/Documentation/usb/gadget_serial.txt index 61e67f6a20a0..6b4a88a8c8e3 100644 --- a/Documentation/usb/gadget_serial.txt +++ b/Documentation/usb/gadget_serial.txt | |||
@@ -236,8 +236,12 @@ I: If#= 0 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=serial | |||
236 | E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms | 236 | E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms |
237 | E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms | 237 | E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms |
238 | 238 | ||
239 | You must explicitly load the usbserial driver with parameters to | 239 | You must load the usbserial driver and explicitly set its parameters |
240 | configure it to recognize the gadget serial device, like this: | 240 | to configure it to recognize the gadget serial device, like this: |
241 | |||
242 | echo 0x0525 0xA4A6 >/sys/bus/usb-serial/drivers/generic/new_id | ||
243 | |||
244 | The legacy way is to use module parameters: | ||
241 | 245 | ||
242 | modprobe usbserial vendor=0x0525 product=0xA4A6 | 246 | modprobe usbserial vendor=0x0525 product=0xA4A6 |
243 | 247 | ||
diff --git a/Documentation/usb/usbmon.txt b/Documentation/usb/usbmon.txt index 7587d84ebd16..28425f736756 100644 --- a/Documentation/usb/usbmon.txt +++ b/Documentation/usb/usbmon.txt | |||
@@ -72,7 +72,7 @@ to listen on a single bus, otherwise, to listen on all buses, type: | |||
72 | 72 | ||
73 | # cat /sys/kernel/debug/usb/usbmon/0u > /tmp/1.mon.out | 73 | # cat /sys/kernel/debug/usb/usbmon/0u > /tmp/1.mon.out |
74 | 74 | ||
75 | This process will be reading until killed. Naturally, the output can be | 75 | This process will read until it is killed. Naturally, the output can be |
76 | redirected to a desirable location. This is preferred, because it is going | 76 | redirected to a desirable location. This is preferred, because it is going |
77 | to be quite long. | 77 | to be quite long. |
78 | 78 | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 1c7e321f77b8..d854959aa519 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -3048,7 +3048,7 @@ S: Maintained | |||
3048 | F: drivers/platform/x86/dell-wmi.c | 3048 | F: drivers/platform/x86/dell-wmi.c |
3049 | 3049 | ||
3050 | DESIGNWARE USB2 DRD IP DRIVER | 3050 | DESIGNWARE USB2 DRD IP DRIVER |
3051 | M: Paul Zimmerman <paulz@synopsys.com> | 3051 | M: John Youn <johnyoun@synopsys.com> |
3052 | L: linux-usb@vger.kernel.org | 3052 | L: linux-usb@vger.kernel.org |
3053 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git | 3053 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git |
3054 | S: Maintained | 3054 | S: Maintained |
diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c index b67ddf0f8bcd..12410a2788d8 100644 --- a/arch/mips/cavium-octeon/octeon-platform.c +++ b/arch/mips/cavium-octeon/octeon-platform.c | |||
@@ -77,7 +77,7 @@ static DEFINE_MUTEX(octeon2_usb_clocks_mutex); | |||
77 | 77 | ||
78 | static int octeon2_usb_clock_start_cnt; | 78 | static int octeon2_usb_clock_start_cnt; |
79 | 79 | ||
80 | static void octeon2_usb_clocks_start(void) | 80 | static void octeon2_usb_clocks_start(struct device *dev) |
81 | { | 81 | { |
82 | u64 div; | 82 | u64 div; |
83 | union cvmx_uctlx_if_ena if_ena; | 83 | union cvmx_uctlx_if_ena if_ena; |
@@ -86,6 +86,8 @@ static void octeon2_usb_clocks_start(void) | |||
86 | union cvmx_uctlx_uphy_portx_ctl_status port_ctl_status; | 86 | union cvmx_uctlx_uphy_portx_ctl_status port_ctl_status; |
87 | int i; | 87 | int i; |
88 | unsigned long io_clk_64_to_ns; | 88 | unsigned long io_clk_64_to_ns; |
89 | u32 clock_rate = 12000000; | ||
90 | bool is_crystal_clock = false; | ||
89 | 91 | ||
90 | 92 | ||
91 | mutex_lock(&octeon2_usb_clocks_mutex); | 93 | mutex_lock(&octeon2_usb_clocks_mutex); |
@@ -96,6 +98,28 @@ static void octeon2_usb_clocks_start(void) | |||
96 | 98 | ||
97 | io_clk_64_to_ns = 64000000000ull / octeon_get_io_clock_rate(); | 99 | io_clk_64_to_ns = 64000000000ull / octeon_get_io_clock_rate(); |
98 | 100 | ||
101 | if (dev->of_node) { | ||
102 | struct device_node *uctl_node; | ||
103 | const char *clock_type; | ||
104 | |||
105 | uctl_node = of_get_parent(dev->of_node); | ||
106 | if (!uctl_node) { | ||
107 | dev_err(dev, "No UCTL device node\n"); | ||
108 | goto exit; | ||
109 | } | ||
110 | i = of_property_read_u32(uctl_node, | ||
111 | "refclk-frequency", &clock_rate); | ||
112 | if (i) { | ||
113 | dev_err(dev, "No UCTL \"refclk-frequency\"\n"); | ||
114 | goto exit; | ||
115 | } | ||
116 | i = of_property_read_string(uctl_node, | ||
117 | "refclk-type", &clock_type); | ||
118 | |||
119 | if (!i && strcmp("crystal", clock_type) == 0) | ||
120 | is_crystal_clock = true; | ||
121 | } | ||
122 | |||
99 | /* | 123 | /* |
100 | * Step 1: Wait for voltages stable. That surely happened | 124 | * Step 1: Wait for voltages stable. That surely happened |
101 | * before starting the kernel. | 125 | * before starting the kernel. |
@@ -126,9 +150,22 @@ static void octeon2_usb_clocks_start(void) | |||
126 | cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); | 150 | cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); |
127 | 151 | ||
128 | /* 3b */ | 152 | /* 3b */ |
129 | /* 12MHz crystal. */ | 153 | clk_rst_ctl.s.p_refclk_sel = is_crystal_clock ? 0 : 1; |
130 | clk_rst_ctl.s.p_refclk_sel = 0; | 154 | switch (clock_rate) { |
131 | clk_rst_ctl.s.p_refclk_div = 0; | 155 | default: |
156 | pr_err("Invalid UCTL clock rate of %u, using 12000000 instead\n", | ||
157 | clock_rate); | ||
158 | /* Fall through */ | ||
159 | case 12000000: | ||
160 | clk_rst_ctl.s.p_refclk_div = 0; | ||
161 | break; | ||
162 | case 24000000: | ||
163 | clk_rst_ctl.s.p_refclk_div = 1; | ||
164 | break; | ||
165 | case 48000000: | ||
166 | clk_rst_ctl.s.p_refclk_div = 2; | ||
167 | break; | ||
168 | } | ||
132 | cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); | 169 | cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); |
133 | 170 | ||
134 | /* 3c */ | 171 | /* 3c */ |
@@ -259,7 +296,7 @@ static void octeon2_usb_clocks_stop(void) | |||
259 | 296 | ||
260 | static int octeon_ehci_power_on(struct platform_device *pdev) | 297 | static int octeon_ehci_power_on(struct platform_device *pdev) |
261 | { | 298 | { |
262 | octeon2_usb_clocks_start(); | 299 | octeon2_usb_clocks_start(&pdev->dev); |
263 | return 0; | 300 | return 0; |
264 | } | 301 | } |
265 | 302 | ||
@@ -273,15 +310,16 @@ static struct usb_ehci_pdata octeon_ehci_pdata = { | |||
273 | #ifdef __BIG_ENDIAN | 310 | #ifdef __BIG_ENDIAN |
274 | .big_endian_mmio = 1, | 311 | .big_endian_mmio = 1, |
275 | #endif | 312 | #endif |
313 | .dma_mask_64 = 1, | ||
276 | .power_on = octeon_ehci_power_on, | 314 | .power_on = octeon_ehci_power_on, |
277 | .power_off = octeon_ehci_power_off, | 315 | .power_off = octeon_ehci_power_off, |
278 | }; | 316 | }; |
279 | 317 | ||
280 | static void __init octeon_ehci_hw_start(void) | 318 | static void __init octeon_ehci_hw_start(struct device *dev) |
281 | { | 319 | { |
282 | union cvmx_uctlx_ehci_ctl ehci_ctl; | 320 | union cvmx_uctlx_ehci_ctl ehci_ctl; |
283 | 321 | ||
284 | octeon2_usb_clocks_start(); | 322 | octeon2_usb_clocks_start(dev); |
285 | 323 | ||
286 | ehci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_EHCI_CTL(0)); | 324 | ehci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_EHCI_CTL(0)); |
287 | /* Use 64-bit addressing. */ | 325 | /* Use 64-bit addressing. */ |
@@ -294,64 +332,30 @@ static void __init octeon_ehci_hw_start(void) | |||
294 | octeon2_usb_clocks_stop(); | 332 | octeon2_usb_clocks_stop(); |
295 | } | 333 | } |
296 | 334 | ||
297 | static u64 octeon_ehci_dma_mask = DMA_BIT_MASK(64); | ||
298 | |||
299 | static int __init octeon_ehci_device_init(void) | 335 | static int __init octeon_ehci_device_init(void) |
300 | { | 336 | { |
301 | struct platform_device *pd; | 337 | struct platform_device *pd; |
338 | struct device_node *ehci_node; | ||
302 | int ret = 0; | 339 | int ret = 0; |
303 | 340 | ||
304 | struct resource usb_resources[] = { | 341 | ehci_node = of_find_node_by_name(NULL, "ehci"); |
305 | { | 342 | if (!ehci_node) |
306 | .flags = IORESOURCE_MEM, | ||
307 | }, { | ||
308 | .flags = IORESOURCE_IRQ, | ||
309 | } | ||
310 | }; | ||
311 | |||
312 | /* Only Octeon2 has ehci/ohci */ | ||
313 | if (!OCTEON_IS_MODEL(OCTEON_CN63XX)) | ||
314 | return 0; | 343 | return 0; |
315 | 344 | ||
316 | if (octeon_is_simulation() || usb_disabled()) | 345 | pd = of_find_device_by_node(ehci_node); |
317 | return 0; /* No USB in the simulator. */ | 346 | if (!pd) |
318 | 347 | return 0; | |
319 | pd = platform_device_alloc("ehci-platform", 0); | ||
320 | if (!pd) { | ||
321 | ret = -ENOMEM; | ||
322 | goto out; | ||
323 | } | ||
324 | |||
325 | usb_resources[0].start = 0x00016F0000000000ULL; | ||
326 | usb_resources[0].end = usb_resources[0].start + 0x100; | ||
327 | |||
328 | usb_resources[1].start = OCTEON_IRQ_USB0; | ||
329 | usb_resources[1].end = OCTEON_IRQ_USB0; | ||
330 | |||
331 | ret = platform_device_add_resources(pd, usb_resources, | ||
332 | ARRAY_SIZE(usb_resources)); | ||
333 | if (ret) | ||
334 | goto fail; | ||
335 | 348 | ||
336 | pd->dev.dma_mask = &octeon_ehci_dma_mask; | ||
337 | pd->dev.platform_data = &octeon_ehci_pdata; | 349 | pd->dev.platform_data = &octeon_ehci_pdata; |
338 | octeon_ehci_hw_start(); | 350 | octeon_ehci_hw_start(&pd->dev); |
339 | 351 | ||
340 | ret = platform_device_add(pd); | ||
341 | if (ret) | ||
342 | goto fail; | ||
343 | |||
344 | return ret; | ||
345 | fail: | ||
346 | platform_device_put(pd); | ||
347 | out: | ||
348 | return ret; | 352 | return ret; |
349 | } | 353 | } |
350 | device_initcall(octeon_ehci_device_init); | 354 | device_initcall(octeon_ehci_device_init); |
351 | 355 | ||
352 | static int octeon_ohci_power_on(struct platform_device *pdev) | 356 | static int octeon_ohci_power_on(struct platform_device *pdev) |
353 | { | 357 | { |
354 | octeon2_usb_clocks_start(); | 358 | octeon2_usb_clocks_start(&pdev->dev); |
355 | return 0; | 359 | return 0; |
356 | } | 360 | } |
357 | 361 | ||
@@ -369,11 +373,11 @@ static struct usb_ohci_pdata octeon_ohci_pdata = { | |||
369 | .power_off = octeon_ohci_power_off, | 373 | .power_off = octeon_ohci_power_off, |
370 | }; | 374 | }; |
371 | 375 | ||
372 | static void __init octeon_ohci_hw_start(void) | 376 | static void __init octeon_ohci_hw_start(struct device *dev) |
373 | { | 377 | { |
374 | union cvmx_uctlx_ohci_ctl ohci_ctl; | 378 | union cvmx_uctlx_ohci_ctl ohci_ctl; |
375 | 379 | ||
376 | octeon2_usb_clocks_start(); | 380 | octeon2_usb_clocks_start(dev); |
377 | 381 | ||
378 | ohci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_OHCI_CTL(0)); | 382 | ohci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_OHCI_CTL(0)); |
379 | ohci_ctl.s.l2c_addr_msb = 0; | 383 | ohci_ctl.s.l2c_addr_msb = 0; |
@@ -387,57 +391,27 @@ static void __init octeon_ohci_hw_start(void) | |||
387 | static int __init octeon_ohci_device_init(void) | 391 | static int __init octeon_ohci_device_init(void) |
388 | { | 392 | { |
389 | struct platform_device *pd; | 393 | struct platform_device *pd; |
394 | struct device_node *ohci_node; | ||
390 | int ret = 0; | 395 | int ret = 0; |
391 | 396 | ||
392 | struct resource usb_resources[] = { | 397 | ohci_node = of_find_node_by_name(NULL, "ohci"); |
393 | { | 398 | if (!ohci_node) |
394 | .flags = IORESOURCE_MEM, | ||
395 | }, { | ||
396 | .flags = IORESOURCE_IRQ, | ||
397 | } | ||
398 | }; | ||
399 | |||
400 | /* Only Octeon2 has ehci/ohci */ | ||
401 | if (!OCTEON_IS_MODEL(OCTEON_CN63XX)) | ||
402 | return 0; | 399 | return 0; |
403 | 400 | ||
404 | if (octeon_is_simulation() || usb_disabled()) | 401 | pd = of_find_device_by_node(ohci_node); |
405 | return 0; /* No USB in the simulator. */ | 402 | if (!pd) |
406 | 403 | return 0; | |
407 | pd = platform_device_alloc("ohci-platform", 0); | ||
408 | if (!pd) { | ||
409 | ret = -ENOMEM; | ||
410 | goto out; | ||
411 | } | ||
412 | |||
413 | usb_resources[0].start = 0x00016F0000000400ULL; | ||
414 | usb_resources[0].end = usb_resources[0].start + 0x100; | ||
415 | |||
416 | usb_resources[1].start = OCTEON_IRQ_USB0; | ||
417 | usb_resources[1].end = OCTEON_IRQ_USB0; | ||
418 | |||
419 | ret = platform_device_add_resources(pd, usb_resources, | ||
420 | ARRAY_SIZE(usb_resources)); | ||
421 | if (ret) | ||
422 | goto fail; | ||
423 | 404 | ||
424 | pd->dev.platform_data = &octeon_ohci_pdata; | 405 | pd->dev.platform_data = &octeon_ohci_pdata; |
425 | octeon_ohci_hw_start(); | 406 | octeon_ohci_hw_start(&pd->dev); |
426 | |||
427 | ret = platform_device_add(pd); | ||
428 | if (ret) | ||
429 | goto fail; | ||
430 | 407 | ||
431 | return ret; | 408 | return ret; |
432 | fail: | ||
433 | platform_device_put(pd); | ||
434 | out: | ||
435 | return ret; | ||
436 | } | 409 | } |
437 | device_initcall(octeon_ohci_device_init); | 410 | device_initcall(octeon_ohci_device_init); |
438 | 411 | ||
439 | #endif /* CONFIG_USB */ | 412 | #endif /* CONFIG_USB */ |
440 | 413 | ||
414 | |||
441 | static struct of_device_id __initdata octeon_ids[] = { | 415 | static struct of_device_id __initdata octeon_ids[] = { |
442 | { .compatible = "simple-bus", }, | 416 | { .compatible = "simple-bus", }, |
443 | { .compatible = "cavium,octeon-6335-uctl", }, | 417 | { .compatible = "cavium,octeon-6335-uctl", }, |
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 26a7623e551e..2962de205ba7 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig | |||
@@ -239,6 +239,13 @@ config PHY_QCOM_IPQ806X_SATA | |||
239 | depends on OF | 239 | depends on OF |
240 | select GENERIC_PHY | 240 | select GENERIC_PHY |
241 | 241 | ||
242 | config PHY_ROCKCHIP_USB | ||
243 | tristate "Rockchip USB2 PHY Driver" | ||
244 | depends on ARCH_ROCKCHIP && OF | ||
245 | select GENERIC_PHY | ||
246 | help | ||
247 | Enable this to support the Rockchip USB 2.0 PHY. | ||
248 | |||
242 | config PHY_ST_SPEAR1310_MIPHY | 249 | config PHY_ST_SPEAR1310_MIPHY |
243 | tristate "ST SPEAR1310-MIPHY driver" | 250 | tristate "ST SPEAR1310-MIPHY driver" |
244 | select GENERIC_PHY | 251 | select GENERIC_PHY |
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index cfbb72064516..f080e1bb2a74 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile | |||
@@ -28,6 +28,7 @@ phy-exynos-usb2-$(CONFIG_PHY_EXYNOS5250_USB2) += phy-exynos5250-usb2.o | |||
28 | phy-exynos-usb2-$(CONFIG_PHY_S5PV210_USB2) += phy-s5pv210-usb2.o | 28 | phy-exynos-usb2-$(CONFIG_PHY_S5PV210_USB2) += phy-s5pv210-usb2.o |
29 | obj-$(CONFIG_PHY_EXYNOS5_USBDRD) += phy-exynos5-usbdrd.o | 29 | obj-$(CONFIG_PHY_EXYNOS5_USBDRD) += phy-exynos5-usbdrd.o |
30 | obj-$(CONFIG_PHY_QCOM_APQ8064_SATA) += phy-qcom-apq8064-sata.o | 30 | obj-$(CONFIG_PHY_QCOM_APQ8064_SATA) += phy-qcom-apq8064-sata.o |
31 | obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o | ||
31 | obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o | 32 | obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o |
32 | obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY) += phy-spear1310-miphy.o | 33 | obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY) += phy-spear1310-miphy.o |
33 | obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY) += phy-spear1340-miphy.o | 34 | obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY) += phy-spear1340-miphy.o |
diff --git a/drivers/phy/phy-armada375-usb2.c b/drivers/phy/phy-armada375-usb2.c index ac7d99d01cb3..7c99ca256f05 100644 --- a/drivers/phy/phy-armada375-usb2.c +++ b/drivers/phy/phy-armada375-usb2.c | |||
@@ -118,8 +118,8 @@ static int armada375_usb_phy_probe(struct platform_device *pdev) | |||
118 | 118 | ||
119 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 119 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
120 | usb_cluster_base = devm_ioremap_resource(&pdev->dev, res); | 120 | usb_cluster_base = devm_ioremap_resource(&pdev->dev, res); |
121 | if (!usb_cluster_base) | 121 | if (IS_ERR(usb_cluster_base)) |
122 | return -ENOMEM; | 122 | return PTR_ERR(usb_cluster_base); |
123 | 123 | ||
124 | phy = devm_phy_create(dev, NULL, &armada375_usb_phy_ops); | 124 | phy = devm_phy_create(dev, NULL, &armada375_usb_phy_ops); |
125 | if (IS_ERR(phy)) { | 125 | if (IS_ERR(phy)) { |
diff --git a/drivers/phy/phy-exynos-mipi-video.c b/drivers/phy/phy-exynos-mipi-video.c index 943e0f88a120..f017b2f2a54e 100644 --- a/drivers/phy/phy-exynos-mipi-video.c +++ b/drivers/phy/phy-exynos-mipi-video.c | |||
@@ -12,19 +12,18 @@ | |||
12 | #include <linux/err.h> | 12 | #include <linux/err.h> |
13 | #include <linux/io.h> | 13 | #include <linux/io.h> |
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/mfd/syscon/exynos4-pmu.h> | ||
15 | #include <linux/module.h> | 16 | #include <linux/module.h> |
16 | #include <linux/of.h> | 17 | #include <linux/of.h> |
17 | #include <linux/of_address.h> | 18 | #include <linux/of_address.h> |
18 | #include <linux/phy/phy.h> | 19 | #include <linux/phy/phy.h> |
19 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
21 | #include <linux/regmap.h> | ||
20 | #include <linux/spinlock.h> | 22 | #include <linux/spinlock.h> |
23 | #include <linux/mfd/syscon.h> | ||
21 | 24 | ||
22 | /* MIPI_PHYn_CONTROL register offset: n = 0..1 */ | 25 | /* MIPI_PHYn_CONTROL reg. offset (for base address from ioremap): n = 0..1 */ |
23 | #define EXYNOS_MIPI_PHY_CONTROL(n) ((n) * 4) | 26 | #define EXYNOS_MIPI_PHY_CONTROL(n) ((n) * 4) |
24 | #define EXYNOS_MIPI_PHY_ENABLE (1 << 0) | ||
25 | #define EXYNOS_MIPI_PHY_SRESETN (1 << 1) | ||
26 | #define EXYNOS_MIPI_PHY_MRESETN (1 << 2) | ||
27 | #define EXYNOS_MIPI_PHY_RESET_MASK (3 << 1) | ||
28 | 27 | ||
29 | enum exynos_mipi_phy_id { | 28 | enum exynos_mipi_phy_id { |
30 | EXYNOS_MIPI_PHY_ID_CSIS0, | 29 | EXYNOS_MIPI_PHY_ID_CSIS0, |
@@ -38,43 +37,62 @@ enum exynos_mipi_phy_id { | |||
38 | ((id) == EXYNOS_MIPI_PHY_ID_DSIM0 || (id) == EXYNOS_MIPI_PHY_ID_DSIM1) | 37 | ((id) == EXYNOS_MIPI_PHY_ID_DSIM0 || (id) == EXYNOS_MIPI_PHY_ID_DSIM1) |
39 | 38 | ||
40 | struct exynos_mipi_video_phy { | 39 | struct exynos_mipi_video_phy { |
41 | spinlock_t slock; | ||
42 | struct video_phy_desc { | 40 | struct video_phy_desc { |
43 | struct phy *phy; | 41 | struct phy *phy; |
44 | unsigned int index; | 42 | unsigned int index; |
45 | } phys[EXYNOS_MIPI_PHYS_NUM]; | 43 | } phys[EXYNOS_MIPI_PHYS_NUM]; |
44 | spinlock_t slock; | ||
46 | void __iomem *regs; | 45 | void __iomem *regs; |
46 | struct mutex mutex; | ||
47 | struct regmap *regmap; | ||
47 | }; | 48 | }; |
48 | 49 | ||
49 | static int __set_phy_state(struct exynos_mipi_video_phy *state, | 50 | static int __set_phy_state(struct exynos_mipi_video_phy *state, |
50 | enum exynos_mipi_phy_id id, unsigned int on) | 51 | enum exynos_mipi_phy_id id, unsigned int on) |
51 | { | 52 | { |
53 | const unsigned int offset = EXYNOS4_MIPI_PHY_CONTROL(id / 2); | ||
52 | void __iomem *addr; | 54 | void __iomem *addr; |
53 | u32 reg, reset; | 55 | u32 val, reset; |
54 | |||
55 | addr = state->regs + EXYNOS_MIPI_PHY_CONTROL(id / 2); | ||
56 | 56 | ||
57 | if (is_mipi_dsim_phy_id(id)) | 57 | if (is_mipi_dsim_phy_id(id)) |
58 | reset = EXYNOS_MIPI_PHY_MRESETN; | 58 | reset = EXYNOS4_MIPI_PHY_MRESETN; |
59 | else | ||
60 | reset = EXYNOS_MIPI_PHY_SRESETN; | ||
61 | |||
62 | spin_lock(&state->slock); | ||
63 | reg = readl(addr); | ||
64 | if (on) | ||
65 | reg |= reset; | ||
66 | else | 59 | else |
67 | reg &= ~reset; | 60 | reset = EXYNOS4_MIPI_PHY_SRESETN; |
68 | writel(reg, addr); | 61 | |
69 | 62 | if (state->regmap) { | |
70 | /* Clear ENABLE bit only if MRESETN, SRESETN bits are not set. */ | 63 | mutex_lock(&state->mutex); |
71 | if (on) | 64 | regmap_read(state->regmap, offset, &val); |
72 | reg |= EXYNOS_MIPI_PHY_ENABLE; | 65 | if (on) |
73 | else if (!(reg & EXYNOS_MIPI_PHY_RESET_MASK)) | 66 | val |= reset; |
74 | reg &= ~EXYNOS_MIPI_PHY_ENABLE; | 67 | else |
68 | val &= ~reset; | ||
69 | regmap_write(state->regmap, offset, val); | ||
70 | if (on) | ||
71 | val |= EXYNOS4_MIPI_PHY_ENABLE; | ||
72 | else if (!(val & EXYNOS4_MIPI_PHY_RESET_MASK)) | ||
73 | val &= ~EXYNOS4_MIPI_PHY_ENABLE; | ||
74 | regmap_write(state->regmap, offset, val); | ||
75 | mutex_unlock(&state->mutex); | ||
76 | } else { | ||
77 | addr = state->regs + EXYNOS_MIPI_PHY_CONTROL(id / 2); | ||
78 | |||
79 | spin_lock(&state->slock); | ||
80 | val = readl(addr); | ||
81 | if (on) | ||
82 | val |= reset; | ||
83 | else | ||
84 | val &= ~reset; | ||
85 | writel(val, addr); | ||
86 | /* Clear ENABLE bit only if MRESETN, SRESETN bits are not set */ | ||
87 | if (on) | ||
88 | val |= EXYNOS4_MIPI_PHY_ENABLE; | ||
89 | else if (!(val & EXYNOS4_MIPI_PHY_RESET_MASK)) | ||
90 | val &= ~EXYNOS4_MIPI_PHY_ENABLE; | ||
91 | |||
92 | writel(val, addr); | ||
93 | spin_unlock(&state->slock); | ||
94 | } | ||
75 | 95 | ||
76 | writel(reg, addr); | ||
77 | spin_unlock(&state->slock); | ||
78 | return 0; | 96 | return 0; |
79 | } | 97 | } |
80 | 98 | ||
@@ -118,7 +136,6 @@ static int exynos_mipi_video_phy_probe(struct platform_device *pdev) | |||
118 | { | 136 | { |
119 | struct exynos_mipi_video_phy *state; | 137 | struct exynos_mipi_video_phy *state; |
120 | struct device *dev = &pdev->dev; | 138 | struct device *dev = &pdev->dev; |
121 | struct resource *res; | ||
122 | struct phy_provider *phy_provider; | 139 | struct phy_provider *phy_provider; |
123 | unsigned int i; | 140 | unsigned int i; |
124 | 141 | ||
@@ -126,14 +143,22 @@ static int exynos_mipi_video_phy_probe(struct platform_device *pdev) | |||
126 | if (!state) | 143 | if (!state) |
127 | return -ENOMEM; | 144 | return -ENOMEM; |
128 | 145 | ||
129 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 146 | state->regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon"); |
147 | if (IS_ERR(state->regmap)) { | ||
148 | struct resource *res; | ||
130 | 149 | ||
131 | state->regs = devm_ioremap_resource(dev, res); | 150 | dev_info(dev, "regmap lookup failed: %ld\n", |
132 | if (IS_ERR(state->regs)) | 151 | PTR_ERR(state->regmap)); |
133 | return PTR_ERR(state->regs); | 152 | |
153 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
154 | state->regs = devm_ioremap_resource(dev, res); | ||
155 | if (IS_ERR(state->regs)) | ||
156 | return PTR_ERR(state->regs); | ||
157 | } | ||
134 | 158 | ||
135 | dev_set_drvdata(dev, state); | 159 | dev_set_drvdata(dev, state); |
136 | spin_lock_init(&state->slock); | 160 | spin_lock_init(&state->slock); |
161 | mutex_init(&state->mutex); | ||
137 | 162 | ||
138 | for (i = 0; i < EXYNOS_MIPI_PHYS_NUM; i++) { | 163 | for (i = 0; i < EXYNOS_MIPI_PHYS_NUM; i++) { |
139 | struct phy *phy = devm_phy_create(dev, NULL, | 164 | struct phy *phy = devm_phy_create(dev, NULL, |
diff --git a/drivers/phy/phy-miphy28lp.c b/drivers/phy/phy-miphy28lp.c index 27fa62ce6136..9b2848e6115d 100644 --- a/drivers/phy/phy-miphy28lp.c +++ b/drivers/phy/phy-miphy28lp.c | |||
@@ -194,6 +194,14 @@ | |||
194 | #define MIPHY_SATA_BANK_NB 3 | 194 | #define MIPHY_SATA_BANK_NB 3 |
195 | #define MIPHY_PCIE_BANK_NB 2 | 195 | #define MIPHY_PCIE_BANK_NB 2 |
196 | 196 | ||
197 | enum { | ||
198 | SYSCFG_CTRL, | ||
199 | SYSCFG_STATUS, | ||
200 | SYSCFG_PCI, | ||
201 | SYSCFG_SATA, | ||
202 | SYSCFG_REG_MAX, | ||
203 | }; | ||
204 | |||
197 | struct miphy28lp_phy { | 205 | struct miphy28lp_phy { |
198 | struct phy *phy; | 206 | struct phy *phy; |
199 | struct miphy28lp_dev *phydev; | 207 | struct miphy28lp_dev *phydev; |
@@ -211,10 +219,7 @@ struct miphy28lp_phy { | |||
211 | u32 sata_gen; | 219 | u32 sata_gen; |
212 | 220 | ||
213 | /* Sysconfig registers offsets needed to configure the device */ | 221 | /* Sysconfig registers offsets needed to configure the device */ |
214 | u32 syscfg_miphy_ctrl; | 222 | u32 syscfg_reg[SYSCFG_REG_MAX]; |
215 | u32 syscfg_miphy_status; | ||
216 | u32 syscfg_pci; | ||
217 | u32 syscfg_sata; | ||
218 | u8 type; | 223 | u8 type; |
219 | }; | 224 | }; |
220 | 225 | ||
@@ -834,12 +839,12 @@ static int miphy_osc_is_ready(struct miphy28lp_phy *miphy_phy) | |||
834 | if (!miphy_phy->osc_rdy) | 839 | if (!miphy_phy->osc_rdy) |
835 | return 0; | 840 | return 0; |
836 | 841 | ||
837 | if (!miphy_phy->syscfg_miphy_status) | 842 | if (!miphy_phy->syscfg_reg[SYSCFG_STATUS]) |
838 | return -EINVAL; | 843 | return -EINVAL; |
839 | 844 | ||
840 | do { | 845 | do { |
841 | regmap_read(miphy_dev->regmap, miphy_phy->syscfg_miphy_status, | 846 | regmap_read(miphy_dev->regmap, |
842 | &val); | 847 | miphy_phy->syscfg_reg[SYSCFG_STATUS], &val); |
843 | 848 | ||
844 | if ((val & MIPHY_OSC_RDY) != MIPHY_OSC_RDY) | 849 | if ((val & MIPHY_OSC_RDY) != MIPHY_OSC_RDY) |
845 | cpu_relax(); | 850 | cpu_relax(); |
@@ -888,7 +893,7 @@ static int miphy28lp_setup(struct miphy28lp_phy *miphy_phy, u32 miphy_val) | |||
888 | int err; | 893 | int err; |
889 | struct miphy28lp_dev *miphy_dev = miphy_phy->phydev; | 894 | struct miphy28lp_dev *miphy_dev = miphy_phy->phydev; |
890 | 895 | ||
891 | if (!miphy_phy->syscfg_miphy_ctrl) | 896 | if (!miphy_phy->syscfg_reg[SYSCFG_CTRL]) |
892 | return -EINVAL; | 897 | return -EINVAL; |
893 | 898 | ||
894 | err = reset_control_assert(miphy_phy->miphy_rst); | 899 | err = reset_control_assert(miphy_phy->miphy_rst); |
@@ -900,7 +905,8 @@ static int miphy28lp_setup(struct miphy28lp_phy *miphy_phy, u32 miphy_val) | |||
900 | if (miphy_phy->osc_force_ext) | 905 | if (miphy_phy->osc_force_ext) |
901 | miphy_val |= MIPHY_OSC_FORCE_EXT; | 906 | miphy_val |= MIPHY_OSC_FORCE_EXT; |
902 | 907 | ||
903 | regmap_update_bits(miphy_dev->regmap, miphy_phy->syscfg_miphy_ctrl, | 908 | regmap_update_bits(miphy_dev->regmap, |
909 | miphy_phy->syscfg_reg[SYSCFG_CTRL], | ||
904 | MIPHY_CTRL_MASK, miphy_val); | 910 | MIPHY_CTRL_MASK, miphy_val); |
905 | 911 | ||
906 | err = reset_control_deassert(miphy_phy->miphy_rst); | 912 | err = reset_control_deassert(miphy_phy->miphy_rst); |
@@ -917,8 +923,9 @@ static int miphy28lp_init_sata(struct miphy28lp_phy *miphy_phy) | |||
917 | struct miphy28lp_dev *miphy_dev = miphy_phy->phydev; | 923 | struct miphy28lp_dev *miphy_dev = miphy_phy->phydev; |
918 | int err, sata_conf = SATA_CTRL_SELECT_SATA; | 924 | int err, sata_conf = SATA_CTRL_SELECT_SATA; |
919 | 925 | ||
920 | if ((!miphy_phy->syscfg_sata) || (!miphy_phy->syscfg_pci) | 926 | if ((!miphy_phy->syscfg_reg[SYSCFG_SATA]) || |
921 | || (!miphy_phy->base)) | 927 | (!miphy_phy->syscfg_reg[SYSCFG_PCI]) || |
928 | (!miphy_phy->base)) | ||
922 | return -EINVAL; | 929 | return -EINVAL; |
923 | 930 | ||
924 | dev_info(miphy_dev->dev, "sata-up mode, addr 0x%p\n", miphy_phy->base); | 931 | dev_info(miphy_dev->dev, "sata-up mode, addr 0x%p\n", miphy_phy->base); |
@@ -926,10 +933,11 @@ static int miphy28lp_init_sata(struct miphy28lp_phy *miphy_phy) | |||
926 | /* Configure the glue-logic */ | 933 | /* Configure the glue-logic */ |
927 | sata_conf |= ((miphy_phy->sata_gen - SATA_GEN1) << SATA_SPDMODE); | 934 | sata_conf |= ((miphy_phy->sata_gen - SATA_GEN1) << SATA_SPDMODE); |
928 | 935 | ||
929 | regmap_update_bits(miphy_dev->regmap, miphy_phy->syscfg_sata, | 936 | regmap_update_bits(miphy_dev->regmap, |
937 | miphy_phy->syscfg_reg[SYSCFG_SATA], | ||
930 | SATA_CTRL_MASK, sata_conf); | 938 | SATA_CTRL_MASK, sata_conf); |
931 | 939 | ||
932 | regmap_update_bits(miphy_dev->regmap, miphy_phy->syscfg_pci, | 940 | regmap_update_bits(miphy_dev->regmap, miphy_phy->syscfg_reg[SYSCFG_PCI], |
933 | PCIE_CTRL_MASK, SATA_CTRL_SELECT_PCIE); | 941 | PCIE_CTRL_MASK, SATA_CTRL_SELECT_PCIE); |
934 | 942 | ||
935 | /* MiPHY path and clocking init */ | 943 | /* MiPHY path and clocking init */ |
@@ -951,17 +959,19 @@ static int miphy28lp_init_pcie(struct miphy28lp_phy *miphy_phy) | |||
951 | struct miphy28lp_dev *miphy_dev = miphy_phy->phydev; | 959 | struct miphy28lp_dev *miphy_dev = miphy_phy->phydev; |
952 | int err; | 960 | int err; |
953 | 961 | ||
954 | if ((!miphy_phy->syscfg_sata) || (!miphy_phy->syscfg_pci) | 962 | if ((!miphy_phy->syscfg_reg[SYSCFG_SATA]) || |
963 | (!miphy_phy->syscfg_reg[SYSCFG_PCI]) | ||
955 | || (!miphy_phy->base) || (!miphy_phy->pipebase)) | 964 | || (!miphy_phy->base) || (!miphy_phy->pipebase)) |
956 | return -EINVAL; | 965 | return -EINVAL; |
957 | 966 | ||
958 | dev_info(miphy_dev->dev, "pcie-up mode, addr 0x%p\n", miphy_phy->base); | 967 | dev_info(miphy_dev->dev, "pcie-up mode, addr 0x%p\n", miphy_phy->base); |
959 | 968 | ||
960 | /* Configure the glue-logic */ | 969 | /* Configure the glue-logic */ |
961 | regmap_update_bits(miphy_dev->regmap, miphy_phy->syscfg_sata, | 970 | regmap_update_bits(miphy_dev->regmap, |
971 | miphy_phy->syscfg_reg[SYSCFG_SATA], | ||
962 | SATA_CTRL_MASK, SATA_CTRL_SELECT_PCIE); | 972 | SATA_CTRL_MASK, SATA_CTRL_SELECT_PCIE); |
963 | 973 | ||
964 | regmap_update_bits(miphy_dev->regmap, miphy_phy->syscfg_pci, | 974 | regmap_update_bits(miphy_dev->regmap, miphy_phy->syscfg_reg[SYSCFG_PCI], |
965 | PCIE_CTRL_MASK, SYSCFG_PCIE_PCIE_VAL); | 975 | PCIE_CTRL_MASK, SYSCFG_PCIE_PCIE_VAL); |
966 | 976 | ||
967 | /* MiPHY path and clocking init */ | 977 | /* MiPHY path and clocking init */ |
@@ -1156,7 +1166,8 @@ static int miphy28lp_probe_resets(struct device_node *node, | |||
1156 | static int miphy28lp_of_probe(struct device_node *np, | 1166 | static int miphy28lp_of_probe(struct device_node *np, |
1157 | struct miphy28lp_phy *miphy_phy) | 1167 | struct miphy28lp_phy *miphy_phy) |
1158 | { | 1168 | { |
1159 | struct resource res; | 1169 | int i; |
1170 | u32 ctrlreg; | ||
1160 | 1171 | ||
1161 | miphy_phy->osc_force_ext = | 1172 | miphy_phy->osc_force_ext = |
1162 | of_property_read_bool(np, "st,osc-force-ext"); | 1173 | of_property_read_bool(np, "st,osc-force-ext"); |
@@ -1175,18 +1186,10 @@ static int miphy28lp_of_probe(struct device_node *np, | |||
1175 | if (!miphy_phy->sata_gen) | 1186 | if (!miphy_phy->sata_gen) |
1176 | miphy_phy->sata_gen = SATA_GEN1; | 1187 | miphy_phy->sata_gen = SATA_GEN1; |
1177 | 1188 | ||
1178 | if (!miphy28lp_get_resource_byname(np, "miphy-ctrl-glue", &res)) | 1189 | for (i = 0; i < SYSCFG_REG_MAX; i++) { |
1179 | miphy_phy->syscfg_miphy_ctrl = res.start; | 1190 | if (!of_property_read_u32_index(np, "st,syscfg", i, &ctrlreg)) |
1180 | 1191 | miphy_phy->syscfg_reg[i] = ctrlreg; | |
1181 | if (!miphy28lp_get_resource_byname(np, "miphy-status-glue", &res)) | 1192 | } |
1182 | miphy_phy->syscfg_miphy_status = res.start; | ||
1183 | |||
1184 | if (!miphy28lp_get_resource_byname(np, "pcie-glue", &res)) | ||
1185 | miphy_phy->syscfg_pci = res.start; | ||
1186 | |||
1187 | if (!miphy28lp_get_resource_byname(np, "sata-glue", &res)) | ||
1188 | miphy_phy->syscfg_sata = res.start; | ||
1189 | |||
1190 | 1193 | ||
1191 | return 0; | 1194 | return 0; |
1192 | } | 1195 | } |
diff --git a/drivers/phy/phy-rockchip-usb.c b/drivers/phy/phy-rockchip-usb.c new file mode 100644 index 000000000000..22011c3b6a4b --- /dev/null +++ b/drivers/phy/phy-rockchip-usb.c | |||
@@ -0,0 +1,158 @@ | |||
1 | /* | ||
2 | * Rockchip usb PHY driver | ||
3 | * | ||
4 | * Copyright (C) 2014 Yunzhi Li <lyz@rock-chips.com> | ||
5 | * Copyright (C) 2014 ROCKCHIP, Inc. | ||
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. | ||
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 | |||
17 | #include <linux/clk.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/mutex.h> | ||
22 | #include <linux/of.h> | ||
23 | #include <linux/of_address.h> | ||
24 | #include <linux/phy/phy.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/regulator/consumer.h> | ||
27 | #include <linux/reset.h> | ||
28 | #include <linux/regmap.h> | ||
29 | #include <linux/mfd/syscon.h> | ||
30 | |||
31 | /* | ||
32 | * The higher 16-bit of this register is used for write protection | ||
33 | * only if BIT(13 + 16) set to 1 the BIT(13) can be written. | ||
34 | */ | ||
35 | #define SIDDQ_WRITE_ENA BIT(29) | ||
36 | #define SIDDQ_ON BIT(13) | ||
37 | #define SIDDQ_OFF (0 << 13) | ||
38 | |||
39 | struct rockchip_usb_phy { | ||
40 | unsigned int reg_offset; | ||
41 | struct regmap *reg_base; | ||
42 | struct clk *clk; | ||
43 | struct phy *phy; | ||
44 | }; | ||
45 | |||
46 | static int rockchip_usb_phy_power(struct rockchip_usb_phy *phy, | ||
47 | bool siddq) | ||
48 | { | ||
49 | return regmap_write(phy->reg_base, phy->reg_offset, | ||
50 | SIDDQ_WRITE_ENA | (siddq ? SIDDQ_ON : SIDDQ_OFF)); | ||
51 | } | ||
52 | |||
53 | static int rockchip_usb_phy_power_off(struct phy *_phy) | ||
54 | { | ||
55 | struct rockchip_usb_phy *phy = phy_get_drvdata(_phy); | ||
56 | int ret = 0; | ||
57 | |||
58 | /* Power down usb phy analog blocks by set siddq 1 */ | ||
59 | ret = rockchip_usb_phy_power(phy, 1); | ||
60 | if (ret) | ||
61 | return ret; | ||
62 | |||
63 | clk_disable_unprepare(phy->clk); | ||
64 | if (ret) | ||
65 | return ret; | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | static int rockchip_usb_phy_power_on(struct phy *_phy) | ||
71 | { | ||
72 | struct rockchip_usb_phy *phy = phy_get_drvdata(_phy); | ||
73 | int ret = 0; | ||
74 | |||
75 | ret = clk_prepare_enable(phy->clk); | ||
76 | if (ret) | ||
77 | return ret; | ||
78 | |||
79 | /* Power up usb phy analog blocks by set siddq 0 */ | ||
80 | ret = rockchip_usb_phy_power(phy, 0); | ||
81 | if (ret) | ||
82 | return ret; | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | static struct phy_ops ops = { | ||
88 | .power_on = rockchip_usb_phy_power_on, | ||
89 | .power_off = rockchip_usb_phy_power_off, | ||
90 | .owner = THIS_MODULE, | ||
91 | }; | ||
92 | |||
93 | static int rockchip_usb_phy_probe(struct platform_device *pdev) | ||
94 | { | ||
95 | struct device *dev = &pdev->dev; | ||
96 | struct rockchip_usb_phy *rk_phy; | ||
97 | struct phy_provider *phy_provider; | ||
98 | struct device_node *child; | ||
99 | struct regmap *grf; | ||
100 | unsigned int reg_offset; | ||
101 | |||
102 | grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf"); | ||
103 | if (IS_ERR(grf)) { | ||
104 | dev_err(&pdev->dev, "Missing rockchip,grf property\n"); | ||
105 | return PTR_ERR(grf); | ||
106 | } | ||
107 | |||
108 | for_each_available_child_of_node(dev->of_node, child) { | ||
109 | rk_phy = devm_kzalloc(dev, sizeof(*rk_phy), GFP_KERNEL); | ||
110 | if (!rk_phy) | ||
111 | return -ENOMEM; | ||
112 | |||
113 | if (of_property_read_u32(child, "reg", ®_offset)) { | ||
114 | dev_err(dev, "missing reg property in node %s\n", | ||
115 | child->name); | ||
116 | return -EINVAL; | ||
117 | } | ||
118 | |||
119 | rk_phy->reg_offset = reg_offset; | ||
120 | rk_phy->reg_base = grf; | ||
121 | |||
122 | rk_phy->clk = of_clk_get_by_name(child, "phyclk"); | ||
123 | if (IS_ERR(rk_phy->clk)) | ||
124 | rk_phy->clk = NULL; | ||
125 | |||
126 | rk_phy->phy = devm_phy_create(dev, child, &ops); | ||
127 | if (IS_ERR(rk_phy->phy)) { | ||
128 | dev_err(dev, "failed to create PHY\n"); | ||
129 | return PTR_ERR(rk_phy->phy); | ||
130 | } | ||
131 | phy_set_drvdata(rk_phy->phy, rk_phy); | ||
132 | } | ||
133 | |||
134 | phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); | ||
135 | return PTR_ERR_OR_ZERO(phy_provider); | ||
136 | } | ||
137 | |||
138 | static const struct of_device_id rockchip_usb_phy_dt_ids[] = { | ||
139 | { .compatible = "rockchip,rk3288-usb-phy" }, | ||
140 | {} | ||
141 | }; | ||
142 | |||
143 | MODULE_DEVICE_TABLE(of, rockchip_usb_phy_dt_ids); | ||
144 | |||
145 | static struct platform_driver rockchip_usb_driver = { | ||
146 | .probe = rockchip_usb_phy_probe, | ||
147 | .driver = { | ||
148 | .name = "rockchip-usb-phy", | ||
149 | .owner = THIS_MODULE, | ||
150 | .of_match_table = rockchip_usb_phy_dt_ids, | ||
151 | }, | ||
152 | }; | ||
153 | |||
154 | module_platform_driver(rockchip_usb_driver); | ||
155 | |||
156 | MODULE_AUTHOR("Yunzhi Li <lyz@rock-chips.com>"); | ||
157 | MODULE_DESCRIPTION("Rockchip USB 2.0 PHY driver"); | ||
158 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/phy/phy-ti-pipe3.c b/drivers/phy/phy-ti-pipe3.c index 465de2c800f2..95c88f929f27 100644 --- a/drivers/phy/phy-ti-pipe3.c +++ b/drivers/phy/phy-ti-pipe3.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
29 | #include <linux/phy/omap_control_phy.h> | 29 | #include <linux/phy/omap_control_phy.h> |
30 | #include <linux/of_platform.h> | 30 | #include <linux/of_platform.h> |
31 | #include <linux/spinlock.h> | ||
31 | 32 | ||
32 | #define PLL_STATUS 0x00000004 | 33 | #define PLL_STATUS 0x00000004 |
33 | #define PLL_GO 0x00000008 | 34 | #define PLL_GO 0x00000008 |
@@ -82,6 +83,10 @@ struct ti_pipe3 { | |||
82 | struct clk *refclk; | 83 | struct clk *refclk; |
83 | struct clk *div_clk; | 84 | struct clk *div_clk; |
84 | struct pipe3_dpll_map *dpll_map; | 85 | struct pipe3_dpll_map *dpll_map; |
86 | bool enabled; | ||
87 | spinlock_t lock; /* serialize clock enable/disable */ | ||
88 | /* the below flag is needed specifically for SATA */ | ||
89 | bool refclk_enabled; | ||
85 | }; | 90 | }; |
86 | 91 | ||
87 | static struct pipe3_dpll_map dpll_map_usb[] = { | 92 | static struct pipe3_dpll_map dpll_map_usb[] = { |
@@ -307,6 +312,7 @@ static int ti_pipe3_probe(struct platform_device *pdev) | |||
307 | return -ENOMEM; | 312 | return -ENOMEM; |
308 | 313 | ||
309 | phy->dev = &pdev->dev; | 314 | phy->dev = &pdev->dev; |
315 | spin_lock_init(&phy->lock); | ||
310 | 316 | ||
311 | if (!of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { | 317 | if (!of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { |
312 | match = of_match_device(of_match_ptr(ti_pipe3_id_table), | 318 | match = of_match_device(of_match_ptr(ti_pipe3_id_table), |
@@ -333,21 +339,24 @@ static int ti_pipe3_probe(struct platform_device *pdev) | |||
333 | } | 339 | } |
334 | } | 340 | } |
335 | 341 | ||
342 | phy->refclk = devm_clk_get(phy->dev, "refclk"); | ||
343 | if (IS_ERR(phy->refclk)) { | ||
344 | dev_err(&pdev->dev, "unable to get refclk\n"); | ||
345 | /* older DTBs have missing refclk in SATA PHY | ||
346 | * so don't bail out in case of SATA PHY. | ||
347 | */ | ||
348 | if (!of_device_is_compatible(node, "ti,phy-pipe3-sata")) | ||
349 | return PTR_ERR(phy->refclk); | ||
350 | } | ||
351 | |||
336 | if (!of_device_is_compatible(node, "ti,phy-pipe3-sata")) { | 352 | if (!of_device_is_compatible(node, "ti,phy-pipe3-sata")) { |
337 | phy->wkupclk = devm_clk_get(phy->dev, "wkupclk"); | 353 | phy->wkupclk = devm_clk_get(phy->dev, "wkupclk"); |
338 | if (IS_ERR(phy->wkupclk)) { | 354 | if (IS_ERR(phy->wkupclk)) { |
339 | dev_err(&pdev->dev, "unable to get wkupclk\n"); | 355 | dev_err(&pdev->dev, "unable to get wkupclk\n"); |
340 | return PTR_ERR(phy->wkupclk); | 356 | return PTR_ERR(phy->wkupclk); |
341 | } | 357 | } |
342 | |||
343 | phy->refclk = devm_clk_get(phy->dev, "refclk"); | ||
344 | if (IS_ERR(phy->refclk)) { | ||
345 | dev_err(&pdev->dev, "unable to get refclk\n"); | ||
346 | return PTR_ERR(phy->refclk); | ||
347 | } | ||
348 | } else { | 358 | } else { |
349 | phy->wkupclk = ERR_PTR(-ENODEV); | 359 | phy->wkupclk = ERR_PTR(-ENODEV); |
350 | phy->refclk = ERR_PTR(-ENODEV); | ||
351 | } | 360 | } |
352 | 361 | ||
353 | if (of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { | 362 | if (of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { |
@@ -426,33 +435,42 @@ static int ti_pipe3_remove(struct platform_device *pdev) | |||
426 | } | 435 | } |
427 | 436 | ||
428 | #ifdef CONFIG_PM | 437 | #ifdef CONFIG_PM |
429 | 438 | static int ti_pipe3_enable_refclk(struct ti_pipe3 *phy) | |
430 | static int ti_pipe3_runtime_suspend(struct device *dev) | ||
431 | { | 439 | { |
432 | struct ti_pipe3 *phy = dev_get_drvdata(dev); | 440 | if (!IS_ERR(phy->refclk) && !phy->refclk_enabled) { |
441 | int ret; | ||
433 | 442 | ||
434 | if (!IS_ERR(phy->wkupclk)) | 443 | ret = clk_prepare_enable(phy->refclk); |
435 | clk_disable_unprepare(phy->wkupclk); | 444 | if (ret) { |
445 | dev_err(phy->dev, "Failed to enable refclk %d\n", ret); | ||
446 | return ret; | ||
447 | } | ||
448 | phy->refclk_enabled = true; | ||
449 | } | ||
450 | |||
451 | return 0; | ||
452 | } | ||
453 | |||
454 | static void ti_pipe3_disable_refclk(struct ti_pipe3 *phy) | ||
455 | { | ||
436 | if (!IS_ERR(phy->refclk)) | 456 | if (!IS_ERR(phy->refclk)) |
437 | clk_disable_unprepare(phy->refclk); | 457 | clk_disable_unprepare(phy->refclk); |
438 | if (!IS_ERR(phy->div_clk)) | ||
439 | clk_disable_unprepare(phy->div_clk); | ||
440 | 458 | ||
441 | return 0; | 459 | phy->refclk_enabled = false; |
442 | } | 460 | } |
443 | 461 | ||
444 | static int ti_pipe3_runtime_resume(struct device *dev) | 462 | static int ti_pipe3_enable_clocks(struct ti_pipe3 *phy) |
445 | { | 463 | { |
446 | u32 ret = 0; | 464 | int ret = 0; |
447 | struct ti_pipe3 *phy = dev_get_drvdata(dev); | 465 | unsigned long flags; |
448 | 466 | ||
449 | if (!IS_ERR(phy->refclk)) { | 467 | spin_lock_irqsave(&phy->lock, flags); |
450 | ret = clk_prepare_enable(phy->refclk); | 468 | if (phy->enabled) |
451 | if (ret) { | 469 | goto err1; |
452 | dev_err(phy->dev, "Failed to enable refclk %d\n", ret); | 470 | |
453 | goto err1; | 471 | ret = ti_pipe3_enable_refclk(phy); |
454 | } | 472 | if (ret) |
455 | } | 473 | goto err1; |
456 | 474 | ||
457 | if (!IS_ERR(phy->wkupclk)) { | 475 | if (!IS_ERR(phy->wkupclk)) { |
458 | ret = clk_prepare_enable(phy->wkupclk); | 476 | ret = clk_prepare_enable(phy->wkupclk); |
@@ -469,6 +487,9 @@ static int ti_pipe3_runtime_resume(struct device *dev) | |||
469 | goto err3; | 487 | goto err3; |
470 | } | 488 | } |
471 | } | 489 | } |
490 | |||
491 | phy->enabled = true; | ||
492 | spin_unlock_irqrestore(&phy->lock, flags); | ||
472 | return 0; | 493 | return 0; |
473 | 494 | ||
474 | err3: | 495 | err3: |
@@ -479,20 +500,80 @@ err2: | |||
479 | if (!IS_ERR(phy->refclk)) | 500 | if (!IS_ERR(phy->refclk)) |
480 | clk_disable_unprepare(phy->refclk); | 501 | clk_disable_unprepare(phy->refclk); |
481 | 502 | ||
503 | ti_pipe3_disable_refclk(phy); | ||
482 | err1: | 504 | err1: |
505 | spin_unlock_irqrestore(&phy->lock, flags); | ||
483 | return ret; | 506 | return ret; |
484 | } | 507 | } |
485 | 508 | ||
509 | static void ti_pipe3_disable_clocks(struct ti_pipe3 *phy) | ||
510 | { | ||
511 | unsigned long flags; | ||
512 | |||
513 | spin_lock_irqsave(&phy->lock, flags); | ||
514 | if (!phy->enabled) { | ||
515 | spin_unlock_irqrestore(&phy->lock, flags); | ||
516 | return; | ||
517 | } | ||
518 | |||
519 | if (!IS_ERR(phy->wkupclk)) | ||
520 | clk_disable_unprepare(phy->wkupclk); | ||
521 | /* Don't disable refclk for SATA PHY due to Errata i783 */ | ||
522 | if (!of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-sata")) | ||
523 | ti_pipe3_disable_refclk(phy); | ||
524 | if (!IS_ERR(phy->div_clk)) | ||
525 | clk_disable_unprepare(phy->div_clk); | ||
526 | phy->enabled = false; | ||
527 | spin_unlock_irqrestore(&phy->lock, flags); | ||
528 | } | ||
529 | |||
530 | static int ti_pipe3_runtime_suspend(struct device *dev) | ||
531 | { | ||
532 | struct ti_pipe3 *phy = dev_get_drvdata(dev); | ||
533 | |||
534 | ti_pipe3_disable_clocks(phy); | ||
535 | return 0; | ||
536 | } | ||
537 | |||
538 | static int ti_pipe3_runtime_resume(struct device *dev) | ||
539 | { | ||
540 | struct ti_pipe3 *phy = dev_get_drvdata(dev); | ||
541 | int ret = 0; | ||
542 | |||
543 | ret = ti_pipe3_enable_clocks(phy); | ||
544 | return ret; | ||
545 | } | ||
546 | |||
547 | static int ti_pipe3_suspend(struct device *dev) | ||
548 | { | ||
549 | struct ti_pipe3 *phy = dev_get_drvdata(dev); | ||
550 | |||
551 | ti_pipe3_disable_clocks(phy); | ||
552 | return 0; | ||
553 | } | ||
554 | |||
555 | static int ti_pipe3_resume(struct device *dev) | ||
556 | { | ||
557 | struct ti_pipe3 *phy = dev_get_drvdata(dev); | ||
558 | int ret; | ||
559 | |||
560 | ret = ti_pipe3_enable_clocks(phy); | ||
561 | if (ret) | ||
562 | return ret; | ||
563 | |||
564 | pm_runtime_disable(dev); | ||
565 | pm_runtime_set_active(dev); | ||
566 | pm_runtime_enable(dev); | ||
567 | return 0; | ||
568 | } | ||
569 | #endif | ||
570 | |||
486 | static const struct dev_pm_ops ti_pipe3_pm_ops = { | 571 | static const struct dev_pm_ops ti_pipe3_pm_ops = { |
487 | SET_RUNTIME_PM_OPS(ti_pipe3_runtime_suspend, | 572 | SET_RUNTIME_PM_OPS(ti_pipe3_runtime_suspend, |
488 | ti_pipe3_runtime_resume, NULL) | 573 | ti_pipe3_runtime_resume, NULL) |
574 | SET_SYSTEM_SLEEP_PM_OPS(ti_pipe3_suspend, ti_pipe3_resume) | ||
489 | }; | 575 | }; |
490 | 576 | ||
491 | #define DEV_PM_OPS (&ti_pipe3_pm_ops) | ||
492 | #else | ||
493 | #define DEV_PM_OPS NULL | ||
494 | #endif | ||
495 | |||
496 | #ifdef CONFIG_OF | 577 | #ifdef CONFIG_OF |
497 | static const struct of_device_id ti_pipe3_id_table[] = { | 578 | static const struct of_device_id ti_pipe3_id_table[] = { |
498 | { | 579 | { |
@@ -520,7 +601,7 @@ static struct platform_driver ti_pipe3_driver = { | |||
520 | .remove = ti_pipe3_remove, | 601 | .remove = ti_pipe3_remove, |
521 | .driver = { | 602 | .driver = { |
522 | .name = "ti-pipe3", | 603 | .name = "ti-pipe3", |
523 | .pm = DEV_PM_OPS, | 604 | .pm = &ti_pipe3_pm_ops, |
524 | .of_match_table = of_match_ptr(ti_pipe3_id_table), | 605 | .of_match_table = of_match_ptr(ti_pipe3_id_table), |
525 | }, | 606 | }, |
526 | }; | 607 | }; |
diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c index eb178fcb7954..bd70ea05708b 100644 --- a/drivers/staging/emxx_udc/emxx_udc.c +++ b/drivers/staging/emxx_udc/emxx_udc.c | |||
@@ -1608,7 +1608,7 @@ static int std_req_get_status(struct nbu2ss_udc *udc) | |||
1608 | switch (recipient) { | 1608 | switch (recipient) { |
1609 | case USB_RECIP_DEVICE: | 1609 | case USB_RECIP_DEVICE: |
1610 | if (udc->ctrl.wIndex == 0x0000) { | 1610 | if (udc->ctrl.wIndex == 0x0000) { |
1611 | if (udc->self_powered) | 1611 | if (udc->gadget.is_selfpowered) |
1612 | status_data |= (1 << USB_DEVICE_SELF_POWERED); | 1612 | status_data |= (1 << USB_DEVICE_SELF_POWERED); |
1613 | 1613 | ||
1614 | if (udc->remote_wakeup) | 1614 | if (udc->remote_wakeup) |
@@ -3117,7 +3117,7 @@ static int nbu2ss_gad_wakeup(struct usb_gadget *pgadget) | |||
3117 | static int nbu2ss_gad_set_selfpowered(struct usb_gadget *pgadget, | 3117 | static int nbu2ss_gad_set_selfpowered(struct usb_gadget *pgadget, |
3118 | int is_selfpowered) | 3118 | int is_selfpowered) |
3119 | { | 3119 | { |
3120 | struct nbu2ss_udc *udc; | 3120 | struct nbu2ss_udc *udc; |
3121 | unsigned long flags; | 3121 | unsigned long flags; |
3122 | 3122 | ||
3123 | /* INFO("=== %s()\n", __func__); */ | 3123 | /* INFO("=== %s()\n", __func__); */ |
@@ -3130,7 +3130,7 @@ static int nbu2ss_gad_set_selfpowered(struct usb_gadget *pgadget, | |||
3130 | udc = container_of(pgadget, struct nbu2ss_udc, gadget); | 3130 | udc = container_of(pgadget, struct nbu2ss_udc, gadget); |
3131 | 3131 | ||
3132 | spin_lock_irqsave(&udc->lock, flags); | 3132 | spin_lock_irqsave(&udc->lock, flags); |
3133 | udc->self_powered = (is_selfpowered != 0); | 3133 | pgadget->is_selfpowered = (is_selfpowered != 0); |
3134 | spin_unlock_irqrestore(&udc->lock, flags); | 3134 | spin_unlock_irqrestore(&udc->lock, flags); |
3135 | 3135 | ||
3136 | return 0; | 3136 | return 0; |
@@ -3308,7 +3308,7 @@ static int __init nbu2ss_drv_contest_init( | |||
3308 | spin_lock_init(&udc->lock); | 3308 | spin_lock_init(&udc->lock); |
3309 | udc->dev = &pdev->dev; | 3309 | udc->dev = &pdev->dev; |
3310 | 3310 | ||
3311 | udc->self_powered = 1; | 3311 | udc->gadget.is_selfpowered = 1; |
3312 | udc->devstate = USB_STATE_NOTATTACHED; | 3312 | udc->devstate = USB_STATE_NOTATTACHED; |
3313 | udc->pdev = pdev; | 3313 | udc->pdev = pdev; |
3314 | udc->mA = 0; | 3314 | udc->mA = 0; |
diff --git a/drivers/staging/emxx_udc/emxx_udc.h b/drivers/staging/emxx_udc/emxx_udc.h index ee1b80d705fa..202e2dc72bba 100644 --- a/drivers/staging/emxx_udc/emxx_udc.h +++ b/drivers/staging/emxx_udc/emxx_udc.h | |||
@@ -624,7 +624,6 @@ struct nbu2ss_udc { | |||
624 | unsigned linux_suspended:1; | 624 | unsigned linux_suspended:1; |
625 | unsigned linux_resume:1; | 625 | unsigned linux_resume:1; |
626 | unsigned usb_suspended:1; | 626 | unsigned usb_suspended:1; |
627 | unsigned self_powered:1; | ||
628 | unsigned remote_wakeup:1; | 627 | unsigned remote_wakeup:1; |
629 | unsigned udc_enabled:1; | 628 | unsigned udc_enabled:1; |
630 | 629 | ||
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index ae481c37a208..8ed451dd651e 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig | |||
@@ -104,6 +104,8 @@ source "drivers/usb/dwc2/Kconfig" | |||
104 | 104 | ||
105 | source "drivers/usb/chipidea/Kconfig" | 105 | source "drivers/usb/chipidea/Kconfig" |
106 | 106 | ||
107 | source "drivers/usb/isp1760/Kconfig" | ||
108 | |||
107 | comment "USB port drivers" | 109 | comment "USB port drivers" |
108 | 110 | ||
109 | if USB | 111 | if USB |
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index d7be71778059..2f1e2aa42b44 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile | |||
@@ -8,6 +8,7 @@ obj-$(CONFIG_USB) += core/ | |||
8 | 8 | ||
9 | obj-$(CONFIG_USB_DWC3) += dwc3/ | 9 | obj-$(CONFIG_USB_DWC3) += dwc3/ |
10 | obj-$(CONFIG_USB_DWC2) += dwc2/ | 10 | obj-$(CONFIG_USB_DWC2) += dwc2/ |
11 | obj-$(CONFIG_USB_ISP1760) += isp1760/ | ||
11 | 12 | ||
12 | obj-$(CONFIG_USB_MON) += mon/ | 13 | obj-$(CONFIG_USB_MON) += mon/ |
13 | 14 | ||
@@ -23,7 +24,6 @@ obj-$(CONFIG_USB_ISP1362_HCD) += host/ | |||
23 | obj-$(CONFIG_USB_U132_HCD) += host/ | 24 | obj-$(CONFIG_USB_U132_HCD) += host/ |
24 | obj-$(CONFIG_USB_R8A66597_HCD) += host/ | 25 | obj-$(CONFIG_USB_R8A66597_HCD) += host/ |
25 | obj-$(CONFIG_USB_HWA_HCD) += host/ | 26 | obj-$(CONFIG_USB_HWA_HCD) += host/ |
26 | obj-$(CONFIG_USB_ISP1760_HCD) += host/ | ||
27 | obj-$(CONFIG_USB_IMX21_HCD) += host/ | 27 | obj-$(CONFIG_USB_IMX21_HCD) += host/ |
28 | obj-$(CONFIG_USB_FSL_MPH_DR_OF) += host/ | 28 | obj-$(CONFIG_USB_FSL_MPH_DR_OF) += host/ |
29 | obj-$(CONFIG_USB_FUSBH200_HCD) += host/ | 29 | obj-$(CONFIG_USB_FUSBH200_HCD) += host/ |
diff --git a/drivers/usb/chipidea/ci_hdrc_pci.c b/drivers/usb/chipidea/ci_hdrc_pci.c index 241ae3444fde..4df669437211 100644 --- a/drivers/usb/chipidea/ci_hdrc_pci.c +++ b/drivers/usb/chipidea/ci_hdrc_pci.c | |||
@@ -111,6 +111,9 @@ static void ci_hdrc_pci_remove(struct pci_dev *pdev) | |||
111 | * PCI device structure | 111 | * PCI device structure |
112 | * | 112 | * |
113 | * Check "pci.h" for details | 113 | * Check "pci.h" for details |
114 | * | ||
115 | * Note: ehci-pci driver may try to probe the device first. You have to add an | ||
116 | * ID to the bypass_pci_id_table in ehci-pci driver to prevent this. | ||
114 | */ | 117 | */ |
115 | static const struct pci_device_id ci_hdrc_pci_id_table[] = { | 118 | static const struct pci_device_id ci_hdrc_pci_id_table[] = { |
116 | { | 119 | { |
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 4fe18ce3bd5a..ff451048c1ac 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c | |||
@@ -819,8 +819,8 @@ __acquires(hwep->lock) | |||
819 | } | 819 | } |
820 | 820 | ||
821 | if ((setup->bRequestType & USB_RECIP_MASK) == USB_RECIP_DEVICE) { | 821 | if ((setup->bRequestType & USB_RECIP_MASK) == USB_RECIP_DEVICE) { |
822 | /* Assume that device is bus powered for now. */ | 822 | *(u16 *)req->buf = (ci->remote_wakeup << 1) | |
823 | *(u16 *)req->buf = ci->remote_wakeup << 1; | 823 | ci->gadget.is_selfpowered; |
824 | } else if ((setup->bRequestType & USB_RECIP_MASK) \ | 824 | } else if ((setup->bRequestType & USB_RECIP_MASK) \ |
825 | == USB_RECIP_ENDPOINT) { | 825 | == USB_RECIP_ENDPOINT) { |
826 | dir = (le16_to_cpu(setup->wIndex) & USB_ENDPOINT_DIR_MASK) ? | 826 | dir = (le16_to_cpu(setup->wIndex) & USB_ENDPOINT_DIR_MASK) ? |
@@ -1520,6 +1520,19 @@ static int ci_udc_vbus_draw(struct usb_gadget *_gadget, unsigned ma) | |||
1520 | return -ENOTSUPP; | 1520 | return -ENOTSUPP; |
1521 | } | 1521 | } |
1522 | 1522 | ||
1523 | static int ci_udc_selfpowered(struct usb_gadget *_gadget, int is_on) | ||
1524 | { | ||
1525 | struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget); | ||
1526 | struct ci_hw_ep *hwep = ci->ep0in; | ||
1527 | unsigned long flags; | ||
1528 | |||
1529 | spin_lock_irqsave(hwep->lock, flags); | ||
1530 | _gadget->is_selfpowered = (is_on != 0); | ||
1531 | spin_unlock_irqrestore(hwep->lock, flags); | ||
1532 | |||
1533 | return 0; | ||
1534 | } | ||
1535 | |||
1523 | /* Change Data+ pullup status | 1536 | /* Change Data+ pullup status |
1524 | * this func is used by usb_gadget_connect/disconnet | 1537 | * this func is used by usb_gadget_connect/disconnet |
1525 | */ | 1538 | */ |
@@ -1549,6 +1562,7 @@ static int ci_udc_stop(struct usb_gadget *gadget); | |||
1549 | static const struct usb_gadget_ops usb_gadget_ops = { | 1562 | static const struct usb_gadget_ops usb_gadget_ops = { |
1550 | .vbus_session = ci_udc_vbus_session, | 1563 | .vbus_session = ci_udc_vbus_session, |
1551 | .wakeup = ci_udc_wakeup, | 1564 | .wakeup = ci_udc_wakeup, |
1565 | .set_selfpowered = ci_udc_selfpowered, | ||
1552 | .pullup = ci_udc_pullup, | 1566 | .pullup = ci_udc_pullup, |
1553 | .vbus_draw = ci_udc_vbus_draw, | 1567 | .vbus_draw = ci_udc_vbus_draw, |
1554 | .udc_start = ci_udc_start, | 1568 | .udc_start = ci_udc_start, |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 546a17e8ad5b..e78720b59d67 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -1091,6 +1091,7 @@ static int acm_probe(struct usb_interface *intf, | |||
1091 | unsigned long quirks; | 1091 | unsigned long quirks; |
1092 | int num_rx_buf; | 1092 | int num_rx_buf; |
1093 | int i; | 1093 | int i; |
1094 | unsigned int elength = 0; | ||
1094 | int combined_interfaces = 0; | 1095 | int combined_interfaces = 0; |
1095 | struct device *tty_dev; | 1096 | struct device *tty_dev; |
1096 | int rv = -ENOMEM; | 1097 | int rv = -ENOMEM; |
@@ -1136,9 +1137,12 @@ static int acm_probe(struct usb_interface *intf, | |||
1136 | dev_err(&intf->dev, "skipping garbage\n"); | 1137 | dev_err(&intf->dev, "skipping garbage\n"); |
1137 | goto next_desc; | 1138 | goto next_desc; |
1138 | } | 1139 | } |
1140 | elength = buffer[0]; | ||
1139 | 1141 | ||
1140 | switch (buffer[2]) { | 1142 | switch (buffer[2]) { |
1141 | case USB_CDC_UNION_TYPE: /* we've found it */ | 1143 | case USB_CDC_UNION_TYPE: /* we've found it */ |
1144 | if (elength < sizeof(struct usb_cdc_union_desc)) | ||
1145 | goto next_desc; | ||
1142 | if (union_header) { | 1146 | if (union_header) { |
1143 | dev_err(&intf->dev, "More than one " | 1147 | dev_err(&intf->dev, "More than one " |
1144 | "union descriptor, skipping ...\n"); | 1148 | "union descriptor, skipping ...\n"); |
@@ -1147,29 +1151,36 @@ static int acm_probe(struct usb_interface *intf, | |||
1147 | union_header = (struct usb_cdc_union_desc *)buffer; | 1151 | union_header = (struct usb_cdc_union_desc *)buffer; |
1148 | break; | 1152 | break; |
1149 | case USB_CDC_COUNTRY_TYPE: /* export through sysfs*/ | 1153 | case USB_CDC_COUNTRY_TYPE: /* export through sysfs*/ |
1154 | if (elength < sizeof(struct usb_cdc_country_functional_desc)) | ||
1155 | goto next_desc; | ||
1150 | cfd = (struct usb_cdc_country_functional_desc *)buffer; | 1156 | cfd = (struct usb_cdc_country_functional_desc *)buffer; |
1151 | break; | 1157 | break; |
1152 | case USB_CDC_HEADER_TYPE: /* maybe check version */ | 1158 | case USB_CDC_HEADER_TYPE: /* maybe check version */ |
1153 | break; /* for now we ignore it */ | 1159 | break; /* for now we ignore it */ |
1154 | case USB_CDC_ACM_TYPE: | 1160 | case USB_CDC_ACM_TYPE: |
1161 | if (elength < 4) | ||
1162 | goto next_desc; | ||
1155 | ac_management_function = buffer[3]; | 1163 | ac_management_function = buffer[3]; |
1156 | break; | 1164 | break; |
1157 | case USB_CDC_CALL_MANAGEMENT_TYPE: | 1165 | case USB_CDC_CALL_MANAGEMENT_TYPE: |
1166 | if (elength < 5) | ||
1167 | goto next_desc; | ||
1158 | call_management_function = buffer[3]; | 1168 | call_management_function = buffer[3]; |
1159 | call_interface_num = buffer[4]; | 1169 | call_interface_num = buffer[4]; |
1160 | break; | 1170 | break; |
1161 | default: | 1171 | default: |
1162 | /* there are LOTS more CDC descriptors that | 1172 | /* |
1173 | * there are LOTS more CDC descriptors that | ||
1163 | * could legitimately be found here. | 1174 | * could legitimately be found here. |
1164 | */ | 1175 | */ |
1165 | dev_dbg(&intf->dev, "Ignoring descriptor: " | 1176 | dev_dbg(&intf->dev, "Ignoring descriptor: " |
1166 | "type %02x, length %d\n", | 1177 | "type %02x, length %ud\n", |
1167 | buffer[2], buffer[0]); | 1178 | buffer[2], elength); |
1168 | break; | 1179 | break; |
1169 | } | 1180 | } |
1170 | next_desc: | 1181 | next_desc: |
1171 | buflen -= buffer[0]; | 1182 | buflen -= elength; |
1172 | buffer += buffer[0]; | 1183 | buffer += elength; |
1173 | } | 1184 | } |
1174 | 1185 | ||
1175 | if (!union_header) { | 1186 | if (!union_header) { |
@@ -1287,10 +1298,8 @@ made_compressed_probe: | |||
1287 | dev_dbg(&intf->dev, "interfaces are valid\n"); | 1298 | dev_dbg(&intf->dev, "interfaces are valid\n"); |
1288 | 1299 | ||
1289 | acm = kzalloc(sizeof(struct acm), GFP_KERNEL); | 1300 | acm = kzalloc(sizeof(struct acm), GFP_KERNEL); |
1290 | if (acm == NULL) { | 1301 | if (acm == NULL) |
1291 | dev_err(&intf->dev, "out of memory (acm kzalloc)\n"); | ||
1292 | goto alloc_fail; | 1302 | goto alloc_fail; |
1293 | } | ||
1294 | 1303 | ||
1295 | minor = acm_alloc_minor(acm); | 1304 | minor = acm_alloc_minor(acm); |
1296 | if (minor == ACM_TTY_MINORS) { | 1305 | if (minor == ACM_TTY_MINORS) { |
@@ -1329,42 +1338,32 @@ made_compressed_probe: | |||
1329 | acm->quirks = quirks; | 1338 | acm->quirks = quirks; |
1330 | 1339 | ||
1331 | buf = usb_alloc_coherent(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma); | 1340 | buf = usb_alloc_coherent(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma); |
1332 | if (!buf) { | 1341 | if (!buf) |
1333 | dev_err(&intf->dev, "out of memory (ctrl buffer alloc)\n"); | ||
1334 | goto alloc_fail2; | 1342 | goto alloc_fail2; |
1335 | } | ||
1336 | acm->ctrl_buffer = buf; | 1343 | acm->ctrl_buffer = buf; |
1337 | 1344 | ||
1338 | if (acm_write_buffers_alloc(acm) < 0) { | 1345 | if (acm_write_buffers_alloc(acm) < 0) |
1339 | dev_err(&intf->dev, "out of memory (write buffer alloc)\n"); | ||
1340 | goto alloc_fail4; | 1346 | goto alloc_fail4; |
1341 | } | ||
1342 | 1347 | ||
1343 | acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL); | 1348 | acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL); |
1344 | if (!acm->ctrlurb) { | 1349 | if (!acm->ctrlurb) |
1345 | dev_err(&intf->dev, "out of memory (ctrlurb kmalloc)\n"); | ||
1346 | goto alloc_fail5; | 1350 | goto alloc_fail5; |
1347 | } | 1351 | |
1348 | for (i = 0; i < num_rx_buf; i++) { | 1352 | for (i = 0; i < num_rx_buf; i++) { |
1349 | struct acm_rb *rb = &(acm->read_buffers[i]); | 1353 | struct acm_rb *rb = &(acm->read_buffers[i]); |
1350 | struct urb *urb; | 1354 | struct urb *urb; |
1351 | 1355 | ||
1352 | rb->base = usb_alloc_coherent(acm->dev, readsize, GFP_KERNEL, | 1356 | rb->base = usb_alloc_coherent(acm->dev, readsize, GFP_KERNEL, |
1353 | &rb->dma); | 1357 | &rb->dma); |
1354 | if (!rb->base) { | 1358 | if (!rb->base) |
1355 | dev_err(&intf->dev, "out of memory " | ||
1356 | "(read bufs usb_alloc_coherent)\n"); | ||
1357 | goto alloc_fail6; | 1359 | goto alloc_fail6; |
1358 | } | ||
1359 | rb->index = i; | 1360 | rb->index = i; |
1360 | rb->instance = acm; | 1361 | rb->instance = acm; |
1361 | 1362 | ||
1362 | urb = usb_alloc_urb(0, GFP_KERNEL); | 1363 | urb = usb_alloc_urb(0, GFP_KERNEL); |
1363 | if (!urb) { | 1364 | if (!urb) |
1364 | dev_err(&intf->dev, | ||
1365 | "out of memory (read urbs usb_alloc_urb)\n"); | ||
1366 | goto alloc_fail6; | 1365 | goto alloc_fail6; |
1367 | } | 1366 | |
1368 | urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 1367 | urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
1369 | urb->transfer_dma = rb->dma; | 1368 | urb->transfer_dma = rb->dma; |
1370 | if (acm->is_int_ep) { | 1369 | if (acm->is_int_ep) { |
@@ -1389,11 +1388,8 @@ made_compressed_probe: | |||
1389 | struct acm_wb *snd = &(acm->wb[i]); | 1388 | struct acm_wb *snd = &(acm->wb[i]); |
1390 | 1389 | ||
1391 | snd->urb = usb_alloc_urb(0, GFP_KERNEL); | 1390 | snd->urb = usb_alloc_urb(0, GFP_KERNEL); |
1392 | if (snd->urb == NULL) { | 1391 | if (snd->urb == NULL) |
1393 | dev_err(&intf->dev, | ||
1394 | "out of memory (write urbs usb_alloc_urb)\n"); | ||
1395 | goto alloc_fail7; | 1392 | goto alloc_fail7; |
1396 | } | ||
1397 | 1393 | ||
1398 | if (usb_endpoint_xfer_int(epwrite)) | 1394 | if (usb_endpoint_xfer_int(epwrite)) |
1399 | usb_fill_int_urb(snd->urb, usb_dev, | 1395 | usb_fill_int_urb(snd->urb, usb_dev, |
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c index 684ef70dc09d..506b969ea7fd 100644 --- a/drivers/usb/core/buffer.c +++ b/drivers/usb/core/buffer.c | |||
@@ -22,17 +22,25 @@ | |||
22 | */ | 22 | */ |
23 | 23 | ||
24 | /* FIXME tune these based on pool statistics ... */ | 24 | /* FIXME tune these based on pool statistics ... */ |
25 | static const size_t pool_max[HCD_BUFFER_POOLS] = { | 25 | static size_t pool_max[HCD_BUFFER_POOLS] = { |
26 | /* platforms without dma-friendly caches might need to | 26 | 32, 128, 512, 2048, |
27 | * prevent cacheline sharing... | ||
28 | */ | ||
29 | 32, | ||
30 | 128, | ||
31 | 512, | ||
32 | PAGE_SIZE / 2 | ||
33 | /* bigger --> allocate pages */ | ||
34 | }; | 27 | }; |
35 | 28 | ||
29 | void __init usb_init_pool_max(void) | ||
30 | { | ||
31 | /* | ||
32 | * The pool_max values must never be smaller than | ||
33 | * ARCH_KMALLOC_MINALIGN. | ||
34 | */ | ||
35 | if (ARCH_KMALLOC_MINALIGN <= 32) | ||
36 | ; /* Original value is okay */ | ||
37 | else if (ARCH_KMALLOC_MINALIGN <= 64) | ||
38 | pool_max[0] = 64; | ||
39 | else if (ARCH_KMALLOC_MINALIGN <= 128) | ||
40 | pool_max[0] = 0; /* Don't use this pool */ | ||
41 | else | ||
42 | BUILD_BUG(); /* We don't allow this */ | ||
43 | } | ||
36 | 44 | ||
37 | /* SETUP primitives */ | 45 | /* SETUP primitives */ |
38 | 46 | ||
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 0b59731c3021..66abdbcfbfa5 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -1689,7 +1689,7 @@ static struct async *reap_as(struct usb_dev_state *ps) | |||
1689 | for (;;) { | 1689 | for (;;) { |
1690 | __set_current_state(TASK_INTERRUPTIBLE); | 1690 | __set_current_state(TASK_INTERRUPTIBLE); |
1691 | as = async_getcompleted(ps); | 1691 | as = async_getcompleted(ps); |
1692 | if (as) | 1692 | if (as || !connected(ps)) |
1693 | break; | 1693 | break; |
1694 | if (signal_pending(current)) | 1694 | if (signal_pending(current)) |
1695 | break; | 1695 | break; |
@@ -1712,7 +1712,7 @@ static int proc_reapurb(struct usb_dev_state *ps, void __user *arg) | |||
1712 | } | 1712 | } |
1713 | if (signal_pending(current)) | 1713 | if (signal_pending(current)) |
1714 | return -EINTR; | 1714 | return -EINTR; |
1715 | return -EIO; | 1715 | return -ENODEV; |
1716 | } | 1716 | } |
1717 | 1717 | ||
1718 | static int proc_reapurbnonblock(struct usb_dev_state *ps, void __user *arg) | 1718 | static int proc_reapurbnonblock(struct usb_dev_state *ps, void __user *arg) |
@@ -1721,10 +1721,11 @@ static int proc_reapurbnonblock(struct usb_dev_state *ps, void __user *arg) | |||
1721 | struct async *as; | 1721 | struct async *as; |
1722 | 1722 | ||
1723 | as = async_getcompleted(ps); | 1723 | as = async_getcompleted(ps); |
1724 | retval = -EAGAIN; | ||
1725 | if (as) { | 1724 | if (as) { |
1726 | retval = processcompl(as, (void __user * __user *)arg); | 1725 | retval = processcompl(as, (void __user * __user *)arg); |
1727 | free_async(as); | 1726 | free_async(as); |
1727 | } else { | ||
1728 | retval = (connected(ps) ? -EAGAIN : -ENODEV); | ||
1728 | } | 1729 | } |
1729 | return retval; | 1730 | return retval; |
1730 | } | 1731 | } |
@@ -1854,7 +1855,7 @@ static int proc_reapurb_compat(struct usb_dev_state *ps, void __user *arg) | |||
1854 | } | 1855 | } |
1855 | if (signal_pending(current)) | 1856 | if (signal_pending(current)) |
1856 | return -EINTR; | 1857 | return -EINTR; |
1857 | return -EIO; | 1858 | return -ENODEV; |
1858 | } | 1859 | } |
1859 | 1860 | ||
1860 | static int proc_reapurbnonblock_compat(struct usb_dev_state *ps, void __user *arg) | 1861 | static int proc_reapurbnonblock_compat(struct usb_dev_state *ps, void __user *arg) |
@@ -1862,11 +1863,12 @@ static int proc_reapurbnonblock_compat(struct usb_dev_state *ps, void __user *ar | |||
1862 | int retval; | 1863 | int retval; |
1863 | struct async *as; | 1864 | struct async *as; |
1864 | 1865 | ||
1865 | retval = -EAGAIN; | ||
1866 | as = async_getcompleted(ps); | 1866 | as = async_getcompleted(ps); |
1867 | if (as) { | 1867 | if (as) { |
1868 | retval = processcompl_compat(as, (void __user * __user *)arg); | 1868 | retval = processcompl_compat(as, (void __user * __user *)arg); |
1869 | free_async(as); | 1869 | free_async(as); |
1870 | } else { | ||
1871 | retval = (connected(ps) ? -EAGAIN : -ENODEV); | ||
1870 | } | 1872 | } |
1871 | return retval; | 1873 | return retval; |
1872 | } | 1874 | } |
@@ -2038,7 +2040,8 @@ static int proc_get_capabilities(struct usb_dev_state *ps, void __user *arg) | |||
2038 | { | 2040 | { |
2039 | __u32 caps; | 2041 | __u32 caps; |
2040 | 2042 | ||
2041 | caps = USBDEVFS_CAP_ZERO_PACKET | USBDEVFS_CAP_NO_PACKET_SIZE_LIM; | 2043 | caps = USBDEVFS_CAP_ZERO_PACKET | USBDEVFS_CAP_NO_PACKET_SIZE_LIM | |
2044 | USBDEVFS_CAP_REAP_AFTER_DISCONNECT; | ||
2042 | if (!ps->dev->bus->no_stop_on_short) | 2045 | if (!ps->dev->bus->no_stop_on_short) |
2043 | caps |= USBDEVFS_CAP_BULK_CONTINUATION; | 2046 | caps |= USBDEVFS_CAP_BULK_CONTINUATION; |
2044 | if (ps->dev->bus->sg_tablesize) | 2047 | if (ps->dev->bus->sg_tablesize) |
@@ -2138,6 +2141,32 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd, | |||
2138 | return -EPERM; | 2141 | return -EPERM; |
2139 | 2142 | ||
2140 | usb_lock_device(dev); | 2143 | usb_lock_device(dev); |
2144 | |||
2145 | /* Reap operations are allowed even after disconnection */ | ||
2146 | switch (cmd) { | ||
2147 | case USBDEVFS_REAPURB: | ||
2148 | snoop(&dev->dev, "%s: REAPURB\n", __func__); | ||
2149 | ret = proc_reapurb(ps, p); | ||
2150 | goto done; | ||
2151 | |||
2152 | case USBDEVFS_REAPURBNDELAY: | ||
2153 | snoop(&dev->dev, "%s: REAPURBNDELAY\n", __func__); | ||
2154 | ret = proc_reapurbnonblock(ps, p); | ||
2155 | goto done; | ||
2156 | |||
2157 | #ifdef CONFIG_COMPAT | ||
2158 | case USBDEVFS_REAPURB32: | ||
2159 | snoop(&dev->dev, "%s: REAPURB32\n", __func__); | ||
2160 | ret = proc_reapurb_compat(ps, p); | ||
2161 | goto done; | ||
2162 | |||
2163 | case USBDEVFS_REAPURBNDELAY32: | ||
2164 | snoop(&dev->dev, "%s: REAPURBNDELAY32\n", __func__); | ||
2165 | ret = proc_reapurbnonblock_compat(ps, p); | ||
2166 | goto done; | ||
2167 | #endif | ||
2168 | } | ||
2169 | |||
2141 | if (!connected(ps)) { | 2170 | if (!connected(ps)) { |
2142 | usb_unlock_device(dev); | 2171 | usb_unlock_device(dev); |
2143 | return -ENODEV; | 2172 | return -ENODEV; |
@@ -2231,16 +2260,6 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd, | |||
2231 | inode->i_mtime = CURRENT_TIME; | 2260 | inode->i_mtime = CURRENT_TIME; |
2232 | break; | 2261 | break; |
2233 | 2262 | ||
2234 | case USBDEVFS_REAPURB32: | ||
2235 | snoop(&dev->dev, "%s: REAPURB32\n", __func__); | ||
2236 | ret = proc_reapurb_compat(ps, p); | ||
2237 | break; | ||
2238 | |||
2239 | case USBDEVFS_REAPURBNDELAY32: | ||
2240 | snoop(&dev->dev, "%s: REAPURBNDELAY32\n", __func__); | ||
2241 | ret = proc_reapurbnonblock_compat(ps, p); | ||
2242 | break; | ||
2243 | |||
2244 | case USBDEVFS_IOCTL32: | 2263 | case USBDEVFS_IOCTL32: |
2245 | snoop(&dev->dev, "%s: IOCTL32\n", __func__); | 2264 | snoop(&dev->dev, "%s: IOCTL32\n", __func__); |
2246 | ret = proc_ioctl_compat(ps, ptr_to_compat(p)); | 2265 | ret = proc_ioctl_compat(ps, ptr_to_compat(p)); |
@@ -2252,16 +2271,6 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd, | |||
2252 | ret = proc_unlinkurb(ps, p); | 2271 | ret = proc_unlinkurb(ps, p); |
2253 | break; | 2272 | break; |
2254 | 2273 | ||
2255 | case USBDEVFS_REAPURB: | ||
2256 | snoop(&dev->dev, "%s: REAPURB\n", __func__); | ||
2257 | ret = proc_reapurb(ps, p); | ||
2258 | break; | ||
2259 | |||
2260 | case USBDEVFS_REAPURBNDELAY: | ||
2261 | snoop(&dev->dev, "%s: REAPURBNDELAY\n", __func__); | ||
2262 | ret = proc_reapurbnonblock(ps, p); | ||
2263 | break; | ||
2264 | |||
2265 | case USBDEVFS_DISCSIGNAL: | 2274 | case USBDEVFS_DISCSIGNAL: |
2266 | snoop(&dev->dev, "%s: DISCSIGNAL\n", __func__); | 2275 | snoop(&dev->dev, "%s: DISCSIGNAL\n", __func__); |
2267 | ret = proc_disconnectsignal(ps, p); | 2276 | ret = proc_disconnectsignal(ps, p); |
@@ -2304,6 +2313,8 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd, | |||
2304 | ret = proc_free_streams(ps, p); | 2313 | ret = proc_free_streams(ps, p); |
2305 | break; | 2314 | break; |
2306 | } | 2315 | } |
2316 | |||
2317 | done: | ||
2307 | usb_unlock_device(dev); | 2318 | usb_unlock_device(dev); |
2308 | if (ret >= 0) | 2319 | if (ret >= 0) |
2309 | inode->i_atime = CURRENT_TIME; | 2320 | inode->i_atime = CURRENT_TIME; |
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 874dec31a111..818369afff63 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
@@ -275,21 +275,6 @@ static int usb_unbind_device(struct device *dev) | |||
275 | return 0; | 275 | return 0; |
276 | } | 276 | } |
277 | 277 | ||
278 | /* | ||
279 | * Cancel any pending scheduled resets | ||
280 | * | ||
281 | * [see usb_queue_reset_device()] | ||
282 | * | ||
283 | * Called after unconfiguring / when releasing interfaces. See | ||
284 | * comments in __usb_queue_reset_device() regarding | ||
285 | * udev->reset_running. | ||
286 | */ | ||
287 | static void usb_cancel_queued_reset(struct usb_interface *iface) | ||
288 | { | ||
289 | if (iface->reset_running == 0) | ||
290 | cancel_work_sync(&iface->reset_ws); | ||
291 | } | ||
292 | |||
293 | /* called from driver core with dev locked */ | 278 | /* called from driver core with dev locked */ |
294 | static int usb_probe_interface(struct device *dev) | 279 | static int usb_probe_interface(struct device *dev) |
295 | { | 280 | { |
@@ -380,7 +365,6 @@ static int usb_probe_interface(struct device *dev) | |||
380 | usb_set_intfdata(intf, NULL); | 365 | usb_set_intfdata(intf, NULL); |
381 | intf->needs_remote_wakeup = 0; | 366 | intf->needs_remote_wakeup = 0; |
382 | intf->condition = USB_INTERFACE_UNBOUND; | 367 | intf->condition = USB_INTERFACE_UNBOUND; |
383 | usb_cancel_queued_reset(intf); | ||
384 | 368 | ||
385 | /* If the LPM disable succeeded, balance the ref counts. */ | 369 | /* If the LPM disable succeeded, balance the ref counts. */ |
386 | if (!lpm_disable_error) | 370 | if (!lpm_disable_error) |
@@ -425,7 +409,6 @@ static int usb_unbind_interface(struct device *dev) | |||
425 | usb_disable_interface(udev, intf, false); | 409 | usb_disable_interface(udev, intf, false); |
426 | 410 | ||
427 | driver->disconnect(intf); | 411 | driver->disconnect(intf); |
428 | usb_cancel_queued_reset(intf); | ||
429 | 412 | ||
430 | /* Free streams */ | 413 | /* Free streams */ |
431 | for (i = 0, j = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) { | 414 | for (i = 0, j = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) { |
@@ -1797,6 +1780,18 @@ static int autosuspend_check(struct usb_device *udev) | |||
1797 | dev_dbg(&udev->dev, "remote wakeup needed for autosuspend\n"); | 1780 | dev_dbg(&udev->dev, "remote wakeup needed for autosuspend\n"); |
1798 | return -EOPNOTSUPP; | 1781 | return -EOPNOTSUPP; |
1799 | } | 1782 | } |
1783 | |||
1784 | /* | ||
1785 | * If the device is a direct child of the root hub and the HCD | ||
1786 | * doesn't handle wakeup requests, don't allow autosuspend when | ||
1787 | * wakeup is needed. | ||
1788 | */ | ||
1789 | if (w && udev->parent == udev->bus->root_hub && | ||
1790 | bus_to_hcd(udev->bus)->cant_recv_wakeups) { | ||
1791 | dev_dbg(&udev->dev, "HCD doesn't handle wakeup requests\n"); | ||
1792 | return -EOPNOTSUPP; | ||
1793 | } | ||
1794 | |||
1800 | udev->do_remote_wakeup = w; | 1795 | udev->do_remote_wakeup = w; |
1801 | return 0; | 1796 | return 0; |
1802 | } | 1797 | } |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 11cee55ae397..45a915ccd71c 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -1618,6 +1618,7 @@ static int unlink1(struct usb_hcd *hcd, struct urb *urb, int status) | |||
1618 | int usb_hcd_unlink_urb (struct urb *urb, int status) | 1618 | int usb_hcd_unlink_urb (struct urb *urb, int status) |
1619 | { | 1619 | { |
1620 | struct usb_hcd *hcd; | 1620 | struct usb_hcd *hcd; |
1621 | struct usb_device *udev = urb->dev; | ||
1621 | int retval = -EIDRM; | 1622 | int retval = -EIDRM; |
1622 | unsigned long flags; | 1623 | unsigned long flags; |
1623 | 1624 | ||
@@ -1629,20 +1630,19 @@ int usb_hcd_unlink_urb (struct urb *urb, int status) | |||
1629 | spin_lock_irqsave(&hcd_urb_unlink_lock, flags); | 1630 | spin_lock_irqsave(&hcd_urb_unlink_lock, flags); |
1630 | if (atomic_read(&urb->use_count) > 0) { | 1631 | if (atomic_read(&urb->use_count) > 0) { |
1631 | retval = 0; | 1632 | retval = 0; |
1632 | usb_get_dev(urb->dev); | 1633 | usb_get_dev(udev); |
1633 | } | 1634 | } |
1634 | spin_unlock_irqrestore(&hcd_urb_unlink_lock, flags); | 1635 | spin_unlock_irqrestore(&hcd_urb_unlink_lock, flags); |
1635 | if (retval == 0) { | 1636 | if (retval == 0) { |
1636 | hcd = bus_to_hcd(urb->dev->bus); | 1637 | hcd = bus_to_hcd(urb->dev->bus); |
1637 | retval = unlink1(hcd, urb, status); | 1638 | retval = unlink1(hcd, urb, status); |
1638 | usb_put_dev(urb->dev); | 1639 | if (retval == 0) |
1640 | retval = -EINPROGRESS; | ||
1641 | else if (retval != -EIDRM && retval != -EBUSY) | ||
1642 | dev_dbg(&udev->dev, "hcd_unlink_urb %p fail %d\n", | ||
1643 | urb, retval); | ||
1644 | usb_put_dev(udev); | ||
1639 | } | 1645 | } |
1640 | |||
1641 | if (retval == 0) | ||
1642 | retval = -EINPROGRESS; | ||
1643 | else if (retval != -EIDRM && retval != -EBUSY) | ||
1644 | dev_dbg(&urb->dev->dev, "hcd_unlink_urb %p fail %d\n", | ||
1645 | urb, retval); | ||
1646 | return retval; | 1646 | return retval; |
1647 | } | 1647 | } |
1648 | 1648 | ||
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index eaffb0248de1..d7c3d5a35946 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -2896,10 +2896,12 @@ static int port_is_suspended(struct usb_hub *hub, unsigned portstatus) | |||
2896 | */ | 2896 | */ |
2897 | static int check_port_resume_type(struct usb_device *udev, | 2897 | static int check_port_resume_type(struct usb_device *udev, |
2898 | struct usb_hub *hub, int port1, | 2898 | struct usb_hub *hub, int port1, |
2899 | int status, unsigned portchange, unsigned portstatus) | 2899 | int status, u16 portchange, u16 portstatus) |
2900 | { | 2900 | { |
2901 | struct usb_port *port_dev = hub->ports[port1 - 1]; | 2901 | struct usb_port *port_dev = hub->ports[port1 - 1]; |
2902 | int retries = 3; | ||
2902 | 2903 | ||
2904 | retry: | ||
2903 | /* Is a warm reset needed to recover the connection? */ | 2905 | /* Is a warm reset needed to recover the connection? */ |
2904 | if (status == 0 && udev->reset_resume | 2906 | if (status == 0 && udev->reset_resume |
2905 | && hub_port_warm_reset_required(hub, port1, portstatus)) { | 2907 | && hub_port_warm_reset_required(hub, port1, portstatus)) { |
@@ -2907,10 +2909,17 @@ static int check_port_resume_type(struct usb_device *udev, | |||
2907 | } | 2909 | } |
2908 | /* Is the device still present? */ | 2910 | /* Is the device still present? */ |
2909 | else if (status || port_is_suspended(hub, portstatus) || | 2911 | else if (status || port_is_suspended(hub, portstatus) || |
2910 | !port_is_power_on(hub, portstatus) || | 2912 | !port_is_power_on(hub, portstatus)) { |
2911 | !(portstatus & USB_PORT_STAT_CONNECTION)) { | ||
2912 | if (status >= 0) | 2913 | if (status >= 0) |
2913 | status = -ENODEV; | 2914 | status = -ENODEV; |
2915 | } else if (!(portstatus & USB_PORT_STAT_CONNECTION)) { | ||
2916 | if (retries--) { | ||
2917 | usleep_range(200, 300); | ||
2918 | status = hub_port_status(hub, port1, &portstatus, | ||
2919 | &portchange); | ||
2920 | goto retry; | ||
2921 | } | ||
2922 | status = -ENODEV; | ||
2914 | } | 2923 | } |
2915 | 2924 | ||
2916 | /* Can't do a normal resume if the port isn't enabled, | 2925 | /* Can't do a normal resume if the port isn't enabled, |
@@ -4643,9 +4652,13 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus, | |||
4643 | if (!(portstatus & USB_PORT_STAT_CONNECTION) || | 4652 | if (!(portstatus & USB_PORT_STAT_CONNECTION) || |
4644 | test_bit(port1, hub->removed_bits)) { | 4653 | test_bit(port1, hub->removed_bits)) { |
4645 | 4654 | ||
4646 | /* maybe switch power back on (e.g. root hub was reset) */ | 4655 | /* |
4656 | * maybe switch power back on (e.g. root hub was reset) | ||
4657 | * but only if the port isn't owned by someone else. | ||
4658 | */ | ||
4647 | if (hub_is_port_power_switchable(hub) | 4659 | if (hub_is_port_power_switchable(hub) |
4648 | && !port_is_power_on(hub, portstatus)) | 4660 | && !port_is_power_on(hub, portstatus) |
4661 | && !port_dev->port_owner) | ||
4649 | set_port_feature(hdev, port1, USB_PORT_FEAT_POWER); | 4662 | set_port_feature(hdev, port1, USB_PORT_FEAT_POWER); |
4650 | 4663 | ||
4651 | if (portstatus & USB_PORT_STAT_ENABLE) | 4664 | if (portstatus & USB_PORT_STAT_ENABLE) |
@@ -4870,7 +4883,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
4870 | static void port_event(struct usb_hub *hub, int port1) | 4883 | static void port_event(struct usb_hub *hub, int port1) |
4871 | __must_hold(&port_dev->status_lock) | 4884 | __must_hold(&port_dev->status_lock) |
4872 | { | 4885 | { |
4873 | int connect_change, reset_device = 0; | 4886 | int connect_change; |
4874 | struct usb_port *port_dev = hub->ports[port1 - 1]; | 4887 | struct usb_port *port_dev = hub->ports[port1 - 1]; |
4875 | struct usb_device *udev = port_dev->child; | 4888 | struct usb_device *udev = port_dev->child; |
4876 | struct usb_device *hdev = hub->hdev; | 4889 | struct usb_device *hdev = hub->hdev; |
@@ -4958,30 +4971,14 @@ static void port_event(struct usb_hub *hub, int port1) | |||
4958 | if (hub_port_reset(hub, port1, NULL, | 4971 | if (hub_port_reset(hub, port1, NULL, |
4959 | HUB_BH_RESET_TIME, true) < 0) | 4972 | HUB_BH_RESET_TIME, true) < 0) |
4960 | hub_port_disable(hub, port1, 1); | 4973 | hub_port_disable(hub, port1, 1); |
4961 | } else | 4974 | } else { |
4962 | reset_device = 1; | 4975 | usb_unlock_port(port_dev); |
4963 | } | 4976 | usb_lock_device(udev); |
4964 | 4977 | usb_reset_device(udev); | |
4965 | /* | 4978 | usb_unlock_device(udev); |
4966 | * On disconnect USB3 protocol ports transit from U0 to | 4979 | usb_lock_port(port_dev); |
4967 | * SS.Inactive to Rx.Detect. If this happens a warm- | 4980 | connect_change = 0; |
4968 | * reset is not needed, but a (re)connect may happen | 4981 | } |
4969 | * before hub_wq runs and sees the disconnect, and the | ||
4970 | * device may be an unknown state. | ||
4971 | * | ||
4972 | * If the port went through SS.Inactive without hub_wq | ||
4973 | * seeing it the C_LINK_STATE change flag will be set, | ||
4974 | * and we reset the dev to put it in a known state. | ||
4975 | */ | ||
4976 | if (reset_device || (udev && hub_is_superspeed(hub->hdev) | ||
4977 | && (portchange & USB_PORT_STAT_C_LINK_STATE) | ||
4978 | && (portstatus & USB_PORT_STAT_CONNECTION))) { | ||
4979 | usb_unlock_port(port_dev); | ||
4980 | usb_lock_device(udev); | ||
4981 | usb_reset_device(udev); | ||
4982 | usb_unlock_device(udev); | ||
4983 | usb_lock_port(port_dev); | ||
4984 | connect_change = 0; | ||
4985 | } | 4982 | } |
4986 | 4983 | ||
4987 | if (connect_change) | 4984 | if (connect_change) |
@@ -5577,26 +5574,19 @@ EXPORT_SYMBOL_GPL(usb_reset_device); | |||
5577 | * possible; depending on how the driver attached to each interface | 5574 | * possible; depending on how the driver attached to each interface |
5578 | * handles ->pre_reset(), the second reset might happen or not. | 5575 | * handles ->pre_reset(), the second reset might happen or not. |
5579 | * | 5576 | * |
5580 | * - If a driver is unbound and it had a pending reset, the reset will | 5577 | * - If the reset is delayed so long that the interface is unbound from |
5581 | * be cancelled. | 5578 | * its driver, the reset will be skipped. |
5582 | * | ||
5583 | * - This function can be called during .probe() or .disconnect() | ||
5584 | * times. On return from .disconnect(), any pending resets will be | ||
5585 | * cancelled. | ||
5586 | * | ||
5587 | * There is no no need to lock/unlock the @reset_ws as schedule_work() | ||
5588 | * does its own. | ||
5589 | * | 5579 | * |
5590 | * NOTE: We don't do any reference count tracking because it is not | 5580 | * - This function can be called during .probe(). It can also be called |
5591 | * needed. The lifecycle of the work_struct is tied to the | 5581 | * during .disconnect(), but doing so is pointless because the reset |
5592 | * usb_interface. Before destroying the interface we cancel the | 5582 | * will not occur. If you really want to reset the device during |
5593 | * work_struct, so the fact that work_struct is queued and or | 5583 | * .disconnect(), call usb_reset_device() directly -- but watch out |
5594 | * running means the interface (and thus, the device) exist and | 5584 | * for nested unbinding issues! |
5595 | * are referenced. | ||
5596 | */ | 5585 | */ |
5597 | void usb_queue_reset_device(struct usb_interface *iface) | 5586 | void usb_queue_reset_device(struct usb_interface *iface) |
5598 | { | 5587 | { |
5599 | schedule_work(&iface->reset_ws); | 5588 | if (schedule_work(&iface->reset_ws)) |
5589 | usb_get_intf(iface); | ||
5600 | } | 5590 | } |
5601 | EXPORT_SYMBOL_GPL(usb_queue_reset_device); | 5591 | EXPORT_SYMBOL_GPL(usb_queue_reset_device); |
5602 | 5592 | ||
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index f7b7713cfb2a..f368d2053da5 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -1551,6 +1551,7 @@ static void usb_release_interface(struct device *dev) | |||
1551 | altsetting_to_usb_interface_cache(intf->altsetting); | 1551 | altsetting_to_usb_interface_cache(intf->altsetting); |
1552 | 1552 | ||
1553 | kref_put(&intfc->ref, usb_release_interface_cache); | 1553 | kref_put(&intfc->ref, usb_release_interface_cache); |
1554 | usb_put_dev(interface_to_usbdev(intf)); | ||
1554 | kfree(intf); | 1555 | kfree(intf); |
1555 | } | 1556 | } |
1556 | 1557 | ||
@@ -1626,24 +1627,6 @@ static struct usb_interface_assoc_descriptor *find_iad(struct usb_device *dev, | |||
1626 | 1627 | ||
1627 | /* | 1628 | /* |
1628 | * Internal function to queue a device reset | 1629 | * Internal function to queue a device reset |
1629 | * | ||
1630 | * This is initialized into the workstruct in 'struct | ||
1631 | * usb_device->reset_ws' that is launched by | ||
1632 | * message.c:usb_set_configuration() when initializing each 'struct | ||
1633 | * usb_interface'. | ||
1634 | * | ||
1635 | * It is safe to get the USB device without reference counts because | ||
1636 | * the life cycle of @iface is bound to the life cycle of @udev. Then, | ||
1637 | * this function will be ran only if @iface is alive (and before | ||
1638 | * freeing it any scheduled instances of it will have been cancelled). | ||
1639 | * | ||
1640 | * We need to set a flag (usb_dev->reset_running) because when we call | ||
1641 | * the reset, the interfaces might be unbound. The current interface | ||
1642 | * cannot try to remove the queued work as it would cause a deadlock | ||
1643 | * (you cannot remove your work from within your executing | ||
1644 | * workqueue). This flag lets it know, so that | ||
1645 | * usb_cancel_queued_reset() doesn't try to do it. | ||
1646 | * | ||
1647 | * See usb_queue_reset_device() for more details | 1630 | * See usb_queue_reset_device() for more details |
1648 | */ | 1631 | */ |
1649 | static void __usb_queue_reset_device(struct work_struct *ws) | 1632 | static void __usb_queue_reset_device(struct work_struct *ws) |
@@ -1655,11 +1638,10 @@ static void __usb_queue_reset_device(struct work_struct *ws) | |||
1655 | 1638 | ||
1656 | rc = usb_lock_device_for_reset(udev, iface); | 1639 | rc = usb_lock_device_for_reset(udev, iface); |
1657 | if (rc >= 0) { | 1640 | if (rc >= 0) { |
1658 | iface->reset_running = 1; | ||
1659 | usb_reset_device(udev); | 1641 | usb_reset_device(udev); |
1660 | iface->reset_running = 0; | ||
1661 | usb_unlock_device(udev); | 1642 | usb_unlock_device(udev); |
1662 | } | 1643 | } |
1644 | usb_put_intf(iface); /* Undo _get_ in usb_queue_reset_device() */ | ||
1663 | } | 1645 | } |
1664 | 1646 | ||
1665 | 1647 | ||
@@ -1854,6 +1836,7 @@ free_interfaces: | |||
1854 | dev_set_name(&intf->dev, "%d-%s:%d.%d", | 1836 | dev_set_name(&intf->dev, "%d-%s:%d.%d", |
1855 | dev->bus->busnum, dev->devpath, | 1837 | dev->bus->busnum, dev->devpath, |
1856 | configuration, alt->desc.bInterfaceNumber); | 1838 | configuration, alt->desc.bInterfaceNumber); |
1839 | usb_get_dev(dev); | ||
1857 | } | 1840 | } |
1858 | kfree(new_interfaces); | 1841 | kfree(new_interfaces); |
1859 | 1842 | ||
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 2a92b97f0144..b1fb9aef0f5b 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -1049,6 +1049,7 @@ static int __init usb_init(void) | |||
1049 | pr_info("%s: USB support disabled\n", usbcore_name); | 1049 | pr_info("%s: USB support disabled\n", usbcore_name); |
1050 | return 0; | 1050 | return 0; |
1051 | } | 1051 | } |
1052 | usb_init_pool_max(); | ||
1052 | 1053 | ||
1053 | retval = usb_debugfs_init(); | 1054 | retval = usb_debugfs_init(); |
1054 | if (retval) | 1055 | if (retval) |
diff --git a/drivers/usb/dwc2/Kconfig b/drivers/usb/dwc2/Kconfig index b323c4c11b0a..76b9ba4dc925 100644 --- a/drivers/usb/dwc2/Kconfig +++ b/drivers/usb/dwc2/Kconfig | |||
@@ -23,7 +23,7 @@ choice | |||
23 | 23 | ||
24 | config USB_DWC2_HOST | 24 | config USB_DWC2_HOST |
25 | bool "Host only mode" | 25 | bool "Host only mode" |
26 | depends on USB | 26 | depends on USB=y || (USB_DWC2=m && USB) |
27 | help | 27 | help |
28 | The Designware USB2.0 high-speed host controller | 28 | The Designware USB2.0 high-speed host controller |
29 | integrated into many SoCs. Select this option if you want the | 29 | integrated into many SoCs. Select this option if you want the |
@@ -42,7 +42,7 @@ config USB_DWC2_PERIPHERAL | |||
42 | 42 | ||
43 | config USB_DWC2_DUAL_ROLE | 43 | config USB_DWC2_DUAL_ROLE |
44 | bool "Dual Role mode" | 44 | bool "Dual Role mode" |
45 | depends on (USB=y || USB=USB_DWC2) && (USB_GADGET=y || USB_GADGET=USB_DWC2) | 45 | depends on (USB=y && USB_GADGET=y) || (USB_DWC2=m && USB && USB_GADGET) |
46 | help | 46 | help |
47 | Select this option if you want the driver to work in a dual-role | 47 | Select this option if you want the driver to work in a dual-role |
48 | mode. In this mode both host and gadget features are enabled, and | 48 | mode. In this mode both host and gadget features are enabled, and |
diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index 7605850b7a9c..d5197d492e21 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c | |||
@@ -462,7 +462,7 @@ int dwc2_core_init(struct dwc2_hsotg *hsotg, bool select_phy, int irq) | |||
462 | dwc2_enable_common_interrupts(hsotg); | 462 | dwc2_enable_common_interrupts(hsotg); |
463 | 463 | ||
464 | /* | 464 | /* |
465 | * Do device or host intialization based on mode during PCD and | 465 | * Do device or host initialization based on mode during PCD and |
466 | * HCD initialization | 466 | * HCD initialization |
467 | */ | 467 | */ |
468 | if (dwc2_is_host_mode(hsotg)) { | 468 | if (dwc2_is_host_mode(hsotg)) { |
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 7a70a1349334..f74304b12652 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h | |||
@@ -108,7 +108,7 @@ struct s3c_hsotg_req; | |||
108 | * @halted: Set if the endpoint has been halted. | 108 | * @halted: Set if the endpoint has been halted. |
109 | * @periodic: Set if this is a periodic ep, such as Interrupt | 109 | * @periodic: Set if this is a periodic ep, such as Interrupt |
110 | * @isochronous: Set if this is a isochronous ep | 110 | * @isochronous: Set if this is a isochronous ep |
111 | * @sent_zlp: Set if we've sent a zero-length packet. | 111 | * @send_zlp: Set if we need to send a zero-length packet. |
112 | * @total_data: The total number of data bytes done. | 112 | * @total_data: The total number of data bytes done. |
113 | * @fifo_size: The size of the FIFO (for periodic IN endpoints) | 113 | * @fifo_size: The size of the FIFO (for periodic IN endpoints) |
114 | * @fifo_load: The amount of data loaded into the FIFO (periodic IN) | 114 | * @fifo_load: The amount of data loaded into the FIFO (periodic IN) |
@@ -149,7 +149,7 @@ struct s3c_hsotg_ep { | |||
149 | unsigned int halted:1; | 149 | unsigned int halted:1; |
150 | unsigned int periodic:1; | 150 | unsigned int periodic:1; |
151 | unsigned int isochronous:1; | 151 | unsigned int isochronous:1; |
152 | unsigned int sent_zlp:1; | 152 | unsigned int send_zlp:1; |
153 | 153 | ||
154 | char name[10]; | 154 | char name[10]; |
155 | }; | 155 | }; |
@@ -158,14 +158,12 @@ struct s3c_hsotg_ep { | |||
158 | * struct s3c_hsotg_req - data transfer request | 158 | * struct s3c_hsotg_req - data transfer request |
159 | * @req: The USB gadget request | 159 | * @req: The USB gadget request |
160 | * @queue: The list of requests for the endpoint this is queued for. | 160 | * @queue: The list of requests for the endpoint this is queued for. |
161 | * @in_progress: Has already had size/packets written to core | 161 | * @saved_req_buf: variable to save req.buf when bounce buffers are used. |
162 | * @mapped: DMA buffer for this request has been mapped via dma_map_single(). | ||
163 | */ | 162 | */ |
164 | struct s3c_hsotg_req { | 163 | struct s3c_hsotg_req { |
165 | struct usb_request req; | 164 | struct usb_request req; |
166 | struct list_head queue; | 165 | struct list_head queue; |
167 | unsigned char in_progress; | 166 | void *saved_req_buf; |
168 | unsigned char mapped; | ||
169 | }; | 167 | }; |
170 | 168 | ||
171 | #if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) | 169 | #if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) |
@@ -193,6 +191,22 @@ enum dwc2_lx_state { | |||
193 | DWC2_L3, /* Off state */ | 191 | DWC2_L3, /* Off state */ |
194 | }; | 192 | }; |
195 | 193 | ||
194 | /* | ||
195 | * Gadget periodic tx fifo sizes as used by legacy driver | ||
196 | * EP0 is not included | ||
197 | */ | ||
198 | #define DWC2_G_P_LEGACY_TX_FIFO_SIZE {256, 256, 256, 256, 768, 768, 768, \ | ||
199 | 768, 0, 0, 0, 0, 0, 0, 0} | ||
200 | |||
201 | /* Gadget ep0 states */ | ||
202 | enum dwc2_ep0_state { | ||
203 | DWC2_EP0_SETUP, | ||
204 | DWC2_EP0_DATA_IN, | ||
205 | DWC2_EP0_DATA_OUT, | ||
206 | DWC2_EP0_STATUS_IN, | ||
207 | DWC2_EP0_STATUS_OUT, | ||
208 | }; | ||
209 | |||
196 | /** | 210 | /** |
197 | * struct dwc2_core_params - Parameters for configuring the core | 211 | * struct dwc2_core_params - Parameters for configuring the core |
198 | * | 212 | * |
@@ -381,7 +395,7 @@ struct dwc2_core_params { | |||
381 | * @power_optimized Are power optimizations enabled? | 395 | * @power_optimized Are power optimizations enabled? |
382 | * @num_dev_ep Number of device endpoints available | 396 | * @num_dev_ep Number of device endpoints available |
383 | * @num_dev_perio_in_ep Number of device periodic IN endpoints | 397 | * @num_dev_perio_in_ep Number of device periodic IN endpoints |
384 | * avaialable | 398 | * available |
385 | * @dev_token_q_depth Device Mode IN Token Sequence Learning Queue | 399 | * @dev_token_q_depth Device Mode IN Token Sequence Learning Queue |
386 | * Depth | 400 | * Depth |
387 | * 0 to 30 | 401 | * 0 to 30 |
@@ -434,6 +448,9 @@ struct dwc2_hw_params { | |||
434 | u32 snpsid; | 448 | u32 snpsid; |
435 | }; | 449 | }; |
436 | 450 | ||
451 | /* Size of control and EP0 buffers */ | ||
452 | #define DWC2_CTRL_BUFF_SIZE 8 | ||
453 | |||
437 | /** | 454 | /** |
438 | * struct dwc2_hsotg - Holds the state of the driver, including the non-periodic | 455 | * struct dwc2_hsotg - Holds the state of the driver, including the non-periodic |
439 | * and periodic schedules | 456 | * and periodic schedules |
@@ -552,14 +569,20 @@ struct dwc2_hw_params { | |||
552 | * @num_of_eps: Number of available EPs (excluding EP0) | 569 | * @num_of_eps: Number of available EPs (excluding EP0) |
553 | * @debug_root: Root directrory for debugfs. | 570 | * @debug_root: Root directrory for debugfs. |
554 | * @debug_file: Main status file for debugfs. | 571 | * @debug_file: Main status file for debugfs. |
572 | * @debug_testmode: Testmode status file for debugfs. | ||
555 | * @debug_fifo: FIFO status file for debugfs. | 573 | * @debug_fifo: FIFO status file for debugfs. |
556 | * @ep0_reply: Request used for ep0 reply. | 574 | * @ep0_reply: Request used for ep0 reply. |
557 | * @ep0_buff: Buffer for EP0 reply data, if needed. | 575 | * @ep0_buff: Buffer for EP0 reply data, if needed. |
558 | * @ctrl_buff: Buffer for EP0 control requests. | 576 | * @ctrl_buff: Buffer for EP0 control requests. |
559 | * @ctrl_req: Request for EP0 control packets. | 577 | * @ctrl_req: Request for EP0 control packets. |
560 | * @setup: NAK management for EP0 SETUP | 578 | * @ep0_state: EP0 control transfers state |
579 | * @test_mode: USB test mode requested by the host | ||
561 | * @last_rst: Time of last reset | 580 | * @last_rst: Time of last reset |
562 | * @eps: The endpoints being supplied to the gadget framework | 581 | * @eps: The endpoints being supplied to the gadget framework |
582 | * @g_using_dma: Indicate if dma usage is enabled | ||
583 | * @g_rx_fifo_sz: Contains rx fifo size value | ||
584 | * @g_np_g_tx_fifo_sz: Contains Non-Periodic tx fifo size value | ||
585 | * @g_tx_fifo_sz: Contains tx fifo size value per endpoints | ||
563 | */ | 586 | */ |
564 | struct dwc2_hsotg { | 587 | struct dwc2_hsotg { |
565 | struct device *dev; | 588 | struct device *dev; |
@@ -591,6 +614,7 @@ struct dwc2_hsotg { | |||
591 | 614 | ||
592 | struct dentry *debug_root; | 615 | struct dentry *debug_root; |
593 | struct dentry *debug_file; | 616 | struct dentry *debug_file; |
617 | struct dentry *debug_testmode; | ||
594 | struct dentry *debug_fifo; | 618 | struct dentry *debug_fifo; |
595 | 619 | ||
596 | /* DWC OTG HW Release versions */ | 620 | /* DWC OTG HW Release versions */ |
@@ -684,15 +708,21 @@ struct dwc2_hsotg { | |||
684 | 708 | ||
685 | struct usb_request *ep0_reply; | 709 | struct usb_request *ep0_reply; |
686 | struct usb_request *ctrl_req; | 710 | struct usb_request *ctrl_req; |
687 | u8 ep0_buff[8]; | 711 | void *ep0_buff; |
688 | u8 ctrl_buff[8]; | 712 | void *ctrl_buff; |
713 | enum dwc2_ep0_state ep0_state; | ||
714 | u8 test_mode; | ||
689 | 715 | ||
690 | struct usb_gadget gadget; | 716 | struct usb_gadget gadget; |
691 | unsigned int enabled:1; | 717 | unsigned int enabled:1; |
692 | unsigned int connected:1; | 718 | unsigned int connected:1; |
693 | unsigned int setup:1; | ||
694 | unsigned long last_rst; | 719 | unsigned long last_rst; |
695 | struct s3c_hsotg_ep *eps; | 720 | struct s3c_hsotg_ep *eps_in[MAX_EPS_CHANNELS]; |
721 | struct s3c_hsotg_ep *eps_out[MAX_EPS_CHANNELS]; | ||
722 | u32 g_using_dma; | ||
723 | u32 g_rx_fifo_sz; | ||
724 | u32 g_np_g_tx_fifo_sz; | ||
725 | u32 g_tx_fifo_sz[MAX_EPS_CHANNELS]; | ||
696 | #endif /* CONFIG_USB_DWC2_PERIPHERAL || CONFIG_USB_DWC2_DUAL_ROLE */ | 726 | #endif /* CONFIG_USB_DWC2_PERIPHERAL || CONFIG_USB_DWC2_DUAL_ROLE */ |
697 | }; | 727 | }; |
698 | 728 | ||
@@ -969,7 +999,8 @@ extern int s3c_hsotg_remove(struct dwc2_hsotg *hsotg); | |||
969 | extern int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2); | 999 | extern int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2); |
970 | extern int s3c_hsotg_resume(struct dwc2_hsotg *dwc2); | 1000 | extern int s3c_hsotg_resume(struct dwc2_hsotg *dwc2); |
971 | extern int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq); | 1001 | extern int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq); |
972 | extern void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2); | 1002 | extern void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2, |
1003 | bool reset); | ||
973 | extern void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg); | 1004 | extern void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg); |
974 | extern void s3c_hsotg_disconnect(struct dwc2_hsotg *dwc2); | 1005 | extern void s3c_hsotg_disconnect(struct dwc2_hsotg *dwc2); |
975 | #else | 1006 | #else |
@@ -981,7 +1012,8 @@ static inline int s3c_hsotg_resume(struct dwc2_hsotg *dwc2) | |||
981 | { return 0; } | 1012 | { return 0; } |
982 | static inline int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) | 1013 | static inline int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) |
983 | { return 0; } | 1014 | { return 0; } |
984 | static inline void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2) {} | 1015 | static inline void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2, |
1016 | bool reset) {} | ||
985 | static inline void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg) {} | 1017 | static inline void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg) {} |
986 | static inline void s3c_hsotg_disconnect(struct dwc2_hsotg *dwc2) {} | 1018 | static inline void s3c_hsotg_disconnect(struct dwc2_hsotg *dwc2) {} |
987 | #endif | 1019 | #endif |
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 79242008085b..6a30887082cd 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/usb/gadget.h> | 35 | #include <linux/usb/gadget.h> |
36 | #include <linux/usb/phy.h> | 36 | #include <linux/usb/phy.h> |
37 | #include <linux/platform_data/s3c-hsotg.h> | 37 | #include <linux/platform_data/s3c-hsotg.h> |
38 | #include <linux/uaccess.h> | ||
38 | 39 | ||
39 | #include "core.h" | 40 | #include "core.h" |
40 | #include "hw.h" | 41 | #include "hw.h" |
@@ -65,7 +66,16 @@ static inline void __bic32(void __iomem *ptr, u32 val) | |||
65 | writel(readl(ptr) & ~val, ptr); | 66 | writel(readl(ptr) & ~val, ptr); |
66 | } | 67 | } |
67 | 68 | ||
68 | /* forward decleration of functions */ | 69 | static inline struct s3c_hsotg_ep *index_to_ep(struct dwc2_hsotg *hsotg, |
70 | u32 ep_index, u32 dir_in) | ||
71 | { | ||
72 | if (dir_in) | ||
73 | return hsotg->eps_in[ep_index]; | ||
74 | else | ||
75 | return hsotg->eps_out[ep_index]; | ||
76 | } | ||
77 | |||
78 | /* forward declaration of functions */ | ||
69 | static void s3c_hsotg_dump(struct dwc2_hsotg *hsotg); | 79 | static void s3c_hsotg_dump(struct dwc2_hsotg *hsotg); |
70 | 80 | ||
71 | /** | 81 | /** |
@@ -85,11 +95,11 @@ static void s3c_hsotg_dump(struct dwc2_hsotg *hsotg); | |||
85 | * a core reset. This means we either need to fix the gadgets to take | 95 | * a core reset. This means we either need to fix the gadgets to take |
86 | * account of DMA alignment, or add bounce buffers (yuerk). | 96 | * account of DMA alignment, or add bounce buffers (yuerk). |
87 | * | 97 | * |
88 | * Until this issue is sorted out, we always return 'false'. | 98 | * g_using_dma is set depending on dts flag. |
89 | */ | 99 | */ |
90 | static inline bool using_dma(struct dwc2_hsotg *hsotg) | 100 | static inline bool using_dma(struct dwc2_hsotg *hsotg) |
91 | { | 101 | { |
92 | return false; /* support is not complete */ | 102 | return hsotg->g_using_dma; |
93 | } | 103 | } |
94 | 104 | ||
95 | /** | 105 | /** |
@@ -165,15 +175,18 @@ static void s3c_hsotg_init_fifo(struct dwc2_hsotg *hsotg) | |||
165 | { | 175 | { |
166 | unsigned int ep; | 176 | unsigned int ep; |
167 | unsigned int addr; | 177 | unsigned int addr; |
168 | unsigned int size; | ||
169 | int timeout; | 178 | int timeout; |
170 | u32 val; | 179 | u32 val; |
171 | 180 | ||
172 | /* set FIFO sizes to 2048/1024 */ | 181 | /* Reset fifo map if not correctly cleared during previous session */ |
182 | WARN_ON(hsotg->fifo_map); | ||
183 | hsotg->fifo_map = 0; | ||
173 | 184 | ||
174 | writel(2048, hsotg->regs + GRXFSIZ); | 185 | /* set RX/NPTX FIFO sizes */ |
175 | writel((2048 << FIFOSIZE_STARTADDR_SHIFT) | | 186 | writel(hsotg->g_rx_fifo_sz, hsotg->regs + GRXFSIZ); |
176 | (1024 << FIFOSIZE_DEPTH_SHIFT), hsotg->regs + GNPTXFSIZ); | 187 | writel((hsotg->g_rx_fifo_sz << FIFOSIZE_STARTADDR_SHIFT) | |
188 | (hsotg->g_np_g_tx_fifo_sz << FIFOSIZE_DEPTH_SHIFT), | ||
189 | hsotg->regs + GNPTXFSIZ); | ||
177 | 190 | ||
178 | /* | 191 | /* |
179 | * arange all the rest of the TX FIFOs, as some versions of this | 192 | * arange all the rest of the TX FIFOs, as some versions of this |
@@ -183,35 +196,21 @@ static void s3c_hsotg_init_fifo(struct dwc2_hsotg *hsotg) | |||
183 | */ | 196 | */ |
184 | 197 | ||
185 | /* start at the end of the GNPTXFSIZ, rounded up */ | 198 | /* start at the end of the GNPTXFSIZ, rounded up */ |
186 | addr = 2048 + 1024; | 199 | addr = hsotg->g_rx_fifo_sz + hsotg->g_np_g_tx_fifo_sz; |
187 | 200 | ||
188 | /* | 201 | /* |
189 | * Because we have not enough memory to have each TX FIFO of size at | 202 | * Configure fifos sizes from provided configuration and assign |
190 | * least 3072 bytes (the maximum single packet size), we create four | ||
191 | * FIFOs of lenght 1024, and four of length 3072 bytes, and assing | ||
192 | * them to endpoints dynamically according to maxpacket size value of | 203 | * them to endpoints dynamically according to maxpacket size value of |
193 | * given endpoint. | 204 | * given endpoint. |
194 | */ | 205 | */ |
195 | 206 | for (ep = 1; ep < MAX_EPS_CHANNELS; ep++) { | |
196 | /* 256*4=1024 bytes FIFO length */ | 207 | if (!hsotg->g_tx_fifo_sz[ep]) |
197 | size = 256; | 208 | continue; |
198 | for (ep = 1; ep <= 4; ep++) { | ||
199 | val = addr; | ||
200 | val |= size << FIFOSIZE_DEPTH_SHIFT; | ||
201 | WARN_ONCE(addr + size > hsotg->fifo_mem, | ||
202 | "insufficient fifo memory"); | ||
203 | addr += size; | ||
204 | |||
205 | writel(val, hsotg->regs + DPTXFSIZN(ep)); | ||
206 | } | ||
207 | /* 768*4=3072 bytes FIFO length */ | ||
208 | size = 768; | ||
209 | for (ep = 5; ep <= 8; ep++) { | ||
210 | val = addr; | 209 | val = addr; |
211 | val |= size << FIFOSIZE_DEPTH_SHIFT; | 210 | val |= hsotg->g_tx_fifo_sz[ep] << FIFOSIZE_DEPTH_SHIFT; |
212 | WARN_ONCE(addr + size > hsotg->fifo_mem, | 211 | WARN_ONCE(addr + hsotg->g_tx_fifo_sz[ep] > hsotg->fifo_mem, |
213 | "insufficient fifo memory"); | 212 | "insufficient fifo memory"); |
214 | addr += size; | 213 | addr += hsotg->g_tx_fifo_sz[ep]; |
215 | 214 | ||
216 | writel(val, hsotg->regs + DPTXFSIZN(ep)); | 215 | writel(val, hsotg->regs + DPTXFSIZN(ep)); |
217 | } | 216 | } |
@@ -236,6 +235,7 @@ static void s3c_hsotg_init_fifo(struct dwc2_hsotg *hsotg) | |||
236 | dev_err(hsotg->dev, | 235 | dev_err(hsotg->dev, |
237 | "%s: timeout flushing fifos (GRSTCTL=%08x)\n", | 236 | "%s: timeout flushing fifos (GRSTCTL=%08x)\n", |
238 | __func__, val); | 237 | __func__, val); |
238 | break; | ||
239 | } | 239 | } |
240 | 240 | ||
241 | udelay(1); | 241 | udelay(1); |
@@ -566,11 +566,6 @@ static void s3c_hsotg_start_req(struct dwc2_hsotg *hsotg, | |||
566 | length = ureq->length - ureq->actual; | 566 | length = ureq->length - ureq->actual; |
567 | dev_dbg(hsotg->dev, "ureq->length:%d ureq->actual:%d\n", | 567 | dev_dbg(hsotg->dev, "ureq->length:%d ureq->actual:%d\n", |
568 | ureq->length, ureq->actual); | 568 | ureq->length, ureq->actual); |
569 | if (0) | ||
570 | dev_dbg(hsotg->dev, | ||
571 | "REQ buf %p len %d dma %pad noi=%d zp=%d snok=%d\n", | ||
572 | ureq->buf, length, &ureq->dma, | ||
573 | ureq->no_interrupt, ureq->zero, ureq->short_not_ok); | ||
574 | 569 | ||
575 | maxreq = get_ep_limit(hs_ep); | 570 | maxreq = get_ep_limit(hs_ep); |
576 | if (length > maxreq) { | 571 | if (length > maxreq) { |
@@ -604,14 +599,15 @@ static void s3c_hsotg_start_req(struct dwc2_hsotg *hsotg, | |||
604 | else | 599 | else |
605 | epsize = 0; | 600 | epsize = 0; |
606 | 601 | ||
607 | if (index != 0 && ureq->zero) { | 602 | /* |
608 | /* | 603 | * zero length packet should be programmed on its own and should not |
609 | * test for the packets being exactly right for the | 604 | * be counted in DIEPTSIZ.PktCnt with other packets. |
610 | * transfer | 605 | */ |
611 | */ | 606 | if (dir_in && ureq->zero && !continuing) { |
612 | 607 | /* Test if zlp is actually required. */ | |
613 | if (length == (packets * hs_ep->ep.maxpacket)) | 608 | if ((ureq->length >= hs_ep->ep.maxpacket) && |
614 | packets++; | 609 | !(ureq->length % hs_ep->ep.maxpacket)) |
610 | hs_ep->send_zlp = 1; | ||
615 | } | 611 | } |
616 | 612 | ||
617 | epsize |= DXEPTSIZ_PKTCNT(packets); | 613 | epsize |= DXEPTSIZ_PKTCNT(packets); |
@@ -644,15 +640,12 @@ static void s3c_hsotg_start_req(struct dwc2_hsotg *hsotg, | |||
644 | ctrl |= DXEPCTL_EPENA; /* ensure ep enabled */ | 640 | ctrl |= DXEPCTL_EPENA; /* ensure ep enabled */ |
645 | ctrl |= DXEPCTL_USBACTEP; | 641 | ctrl |= DXEPCTL_USBACTEP; |
646 | 642 | ||
647 | dev_dbg(hsotg->dev, "setup req:%d\n", hsotg->setup); | 643 | dev_dbg(hsotg->dev, "ep0 state:%d\n", hsotg->ep0_state); |
648 | 644 | ||
649 | /* For Setup request do not clear NAK */ | 645 | /* For Setup request do not clear NAK */ |
650 | if (hsotg->setup && index == 0) | 646 | if (!(index == 0 && hsotg->ep0_state == DWC2_EP0_SETUP)) |
651 | hsotg->setup = 0; | ||
652 | else | ||
653 | ctrl |= DXEPCTL_CNAK; /* clear NAK set by core */ | 647 | ctrl |= DXEPCTL_CNAK; /* clear NAK set by core */ |
654 | 648 | ||
655 | |||
656 | dev_dbg(hsotg->dev, "%s: DxEPCTL=0x%08x\n", __func__, ctrl); | 649 | dev_dbg(hsotg->dev, "%s: DxEPCTL=0x%08x\n", __func__, ctrl); |
657 | writel(ctrl, hsotg->regs + epctrl_reg); | 650 | writel(ctrl, hsotg->regs + epctrl_reg); |
658 | 651 | ||
@@ -686,7 +679,7 @@ static void s3c_hsotg_start_req(struct dwc2_hsotg *hsotg, | |||
686 | 679 | ||
687 | /* check ep is enabled */ | 680 | /* check ep is enabled */ |
688 | if (!(readl(hsotg->regs + epctrl_reg) & DXEPCTL_EPENA)) | 681 | if (!(readl(hsotg->regs + epctrl_reg) & DXEPCTL_EPENA)) |
689 | dev_warn(hsotg->dev, | 682 | dev_dbg(hsotg->dev, |
690 | "ep%d: failed to become enabled (DXEPCTL=0x%08x)?\n", | 683 | "ep%d: failed to become enabled (DXEPCTL=0x%08x)?\n", |
691 | index, readl(hsotg->regs + epctrl_reg)); | 684 | index, readl(hsotg->regs + epctrl_reg)); |
692 | 685 | ||
@@ -733,6 +726,59 @@ dma_error: | |||
733 | return -EIO; | 726 | return -EIO; |
734 | } | 727 | } |
735 | 728 | ||
729 | static int s3c_hsotg_handle_unaligned_buf_start(struct dwc2_hsotg *hsotg, | ||
730 | struct s3c_hsotg_ep *hs_ep, struct s3c_hsotg_req *hs_req) | ||
731 | { | ||
732 | void *req_buf = hs_req->req.buf; | ||
733 | |||
734 | /* If dma is not being used or buffer is aligned */ | ||
735 | if (!using_dma(hsotg) || !((long)req_buf & 3)) | ||
736 | return 0; | ||
737 | |||
738 | WARN_ON(hs_req->saved_req_buf); | ||
739 | |||
740 | dev_dbg(hsotg->dev, "%s: %s: buf=%p length=%d\n", __func__, | ||
741 | hs_ep->ep.name, req_buf, hs_req->req.length); | ||
742 | |||
743 | hs_req->req.buf = kmalloc(hs_req->req.length, GFP_ATOMIC); | ||
744 | if (!hs_req->req.buf) { | ||
745 | hs_req->req.buf = req_buf; | ||
746 | dev_err(hsotg->dev, | ||
747 | "%s: unable to allocate memory for bounce buffer\n", | ||
748 | __func__); | ||
749 | return -ENOMEM; | ||
750 | } | ||
751 | |||
752 | /* Save actual buffer */ | ||
753 | hs_req->saved_req_buf = req_buf; | ||
754 | |||
755 | if (hs_ep->dir_in) | ||
756 | memcpy(hs_req->req.buf, req_buf, hs_req->req.length); | ||
757 | return 0; | ||
758 | } | ||
759 | |||
760 | static void s3c_hsotg_handle_unaligned_buf_complete(struct dwc2_hsotg *hsotg, | ||
761 | struct s3c_hsotg_ep *hs_ep, struct s3c_hsotg_req *hs_req) | ||
762 | { | ||
763 | /* If dma is not being used or buffer was aligned */ | ||
764 | if (!using_dma(hsotg) || !hs_req->saved_req_buf) | ||
765 | return; | ||
766 | |||
767 | dev_dbg(hsotg->dev, "%s: %s: status=%d actual-length=%d\n", __func__, | ||
768 | hs_ep->ep.name, hs_req->req.status, hs_req->req.actual); | ||
769 | |||
770 | /* Copy data from bounce buffer on successful out transfer */ | ||
771 | if (!hs_ep->dir_in && !hs_req->req.status) | ||
772 | memcpy(hs_req->saved_req_buf, hs_req->req.buf, | ||
773 | hs_req->req.actual); | ||
774 | |||
775 | /* Free bounce buffer */ | ||
776 | kfree(hs_req->req.buf); | ||
777 | |||
778 | hs_req->req.buf = hs_req->saved_req_buf; | ||
779 | hs_req->saved_req_buf = NULL; | ||
780 | } | ||
781 | |||
736 | static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, | 782 | static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, |
737 | gfp_t gfp_flags) | 783 | gfp_t gfp_flags) |
738 | { | 784 | { |
@@ -740,6 +786,7 @@ static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, | |||
740 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); | 786 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); |
741 | struct dwc2_hsotg *hs = hs_ep->parent; | 787 | struct dwc2_hsotg *hs = hs_ep->parent; |
742 | bool first; | 788 | bool first; |
789 | int ret; | ||
743 | 790 | ||
744 | dev_dbg(hs->dev, "%s: req %p: %d@%p, noi=%d, zero=%d, snok=%d\n", | 791 | dev_dbg(hs->dev, "%s: req %p: %d@%p, noi=%d, zero=%d, snok=%d\n", |
745 | ep->name, req, req->length, req->buf, req->no_interrupt, | 792 | ep->name, req, req->length, req->buf, req->no_interrupt, |
@@ -750,9 +797,13 @@ static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, | |||
750 | req->actual = 0; | 797 | req->actual = 0; |
751 | req->status = -EINPROGRESS; | 798 | req->status = -EINPROGRESS; |
752 | 799 | ||
800 | ret = s3c_hsotg_handle_unaligned_buf_start(hs, hs_ep, hs_req); | ||
801 | if (ret) | ||
802 | return ret; | ||
803 | |||
753 | /* if we're using DMA, sync the buffers as necessary */ | 804 | /* if we're using DMA, sync the buffers as necessary */ |
754 | if (using_dma(hs)) { | 805 | if (using_dma(hs)) { |
755 | int ret = s3c_hsotg_map_dma(hs, hs_ep, req); | 806 | ret = s3c_hsotg_map_dma(hs, hs_ep, req); |
756 | if (ret) | 807 | if (ret) |
757 | return ret; | 808 | return ret; |
758 | } | 809 | } |
@@ -819,7 +870,7 @@ static void s3c_hsotg_complete_oursetup(struct usb_ep *ep, | |||
819 | static struct s3c_hsotg_ep *ep_from_windex(struct dwc2_hsotg *hsotg, | 870 | static struct s3c_hsotg_ep *ep_from_windex(struct dwc2_hsotg *hsotg, |
820 | u32 windex) | 871 | u32 windex) |
821 | { | 872 | { |
822 | struct s3c_hsotg_ep *ep = &hsotg->eps[windex & 0x7F]; | 873 | struct s3c_hsotg_ep *ep; |
823 | int dir = (windex & USB_DIR_IN) ? 1 : 0; | 874 | int dir = (windex & USB_DIR_IN) ? 1 : 0; |
824 | int idx = windex & 0x7F; | 875 | int idx = windex & 0x7F; |
825 | 876 | ||
@@ -829,6 +880,8 @@ static struct s3c_hsotg_ep *ep_from_windex(struct dwc2_hsotg *hsotg, | |||
829 | if (idx > hsotg->num_of_eps) | 880 | if (idx > hsotg->num_of_eps) |
830 | return NULL; | 881 | return NULL; |
831 | 882 | ||
883 | ep = index_to_ep(hsotg, idx, dir); | ||
884 | |||
832 | if (idx && ep->dir_in != dir) | 885 | if (idx && ep->dir_in != dir) |
833 | return NULL; | 886 | return NULL; |
834 | 887 | ||
@@ -836,6 +889,32 @@ static struct s3c_hsotg_ep *ep_from_windex(struct dwc2_hsotg *hsotg, | |||
836 | } | 889 | } |
837 | 890 | ||
838 | /** | 891 | /** |
892 | * s3c_hsotg_set_test_mode - Enable usb Test Modes | ||
893 | * @hsotg: The driver state. | ||
894 | * @testmode: requested usb test mode | ||
895 | * Enable usb Test Mode requested by the Host. | ||
896 | */ | ||
897 | static int s3c_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode) | ||
898 | { | ||
899 | int dctl = readl(hsotg->regs + DCTL); | ||
900 | |||
901 | dctl &= ~DCTL_TSTCTL_MASK; | ||
902 | switch (testmode) { | ||
903 | case TEST_J: | ||
904 | case TEST_K: | ||
905 | case TEST_SE0_NAK: | ||
906 | case TEST_PACKET: | ||
907 | case TEST_FORCE_EN: | ||
908 | dctl |= testmode << DCTL_TSTCTL_SHIFT; | ||
909 | break; | ||
910 | default: | ||
911 | return -EINVAL; | ||
912 | } | ||
913 | writel(dctl, hsotg->regs + DCTL); | ||
914 | return 0; | ||
915 | } | ||
916 | |||
917 | /** | ||
839 | * s3c_hsotg_send_reply - send reply to control request | 918 | * s3c_hsotg_send_reply - send reply to control request |
840 | * @hsotg: The device state | 919 | * @hsotg: The device state |
841 | * @ep: Endpoint 0 | 920 | * @ep: Endpoint 0 |
@@ -864,13 +943,15 @@ static int s3c_hsotg_send_reply(struct dwc2_hsotg *hsotg, | |||
864 | 943 | ||
865 | req->buf = hsotg->ep0_buff; | 944 | req->buf = hsotg->ep0_buff; |
866 | req->length = length; | 945 | req->length = length; |
867 | req->zero = 1; /* always do zero-length final transfer */ | 946 | /* |
947 | * zero flag is for sending zlp in DATA IN stage. It has no impact on | ||
948 | * STATUS stage. | ||
949 | */ | ||
950 | req->zero = 0; | ||
868 | req->complete = s3c_hsotg_complete_oursetup; | 951 | req->complete = s3c_hsotg_complete_oursetup; |
869 | 952 | ||
870 | if (length) | 953 | if (length) |
871 | memcpy(req->buf, buff, length); | 954 | memcpy(req->buf, buff, length); |
872 | else | ||
873 | ep->sent_zlp = 1; | ||
874 | 955 | ||
875 | ret = s3c_hsotg_ep_queue(&ep->ep, req, GFP_ATOMIC); | 956 | ret = s3c_hsotg_ep_queue(&ep->ep, req, GFP_ATOMIC); |
876 | if (ret) { | 957 | if (ret) { |
@@ -889,7 +970,7 @@ static int s3c_hsotg_send_reply(struct dwc2_hsotg *hsotg, | |||
889 | static int s3c_hsotg_process_req_status(struct dwc2_hsotg *hsotg, | 970 | static int s3c_hsotg_process_req_status(struct dwc2_hsotg *hsotg, |
890 | struct usb_ctrlrequest *ctrl) | 971 | struct usb_ctrlrequest *ctrl) |
891 | { | 972 | { |
892 | struct s3c_hsotg_ep *ep0 = &hsotg->eps[0]; | 973 | struct s3c_hsotg_ep *ep0 = hsotg->eps_out[0]; |
893 | struct s3c_hsotg_ep *ep; | 974 | struct s3c_hsotg_ep *ep; |
894 | __le16 reply; | 975 | __le16 reply; |
895 | int ret; | 976 | int ret; |
@@ -953,33 +1034,62 @@ static struct s3c_hsotg_req *get_ep_head(struct s3c_hsotg_ep *hs_ep) | |||
953 | } | 1034 | } |
954 | 1035 | ||
955 | /** | 1036 | /** |
956 | * s3c_hsotg_process_req_featire - process request {SET,CLEAR}_FEATURE | 1037 | * s3c_hsotg_process_req_feature - process request {SET,CLEAR}_FEATURE |
957 | * @hsotg: The device state | 1038 | * @hsotg: The device state |
958 | * @ctrl: USB control request | 1039 | * @ctrl: USB control request |
959 | */ | 1040 | */ |
960 | static int s3c_hsotg_process_req_feature(struct dwc2_hsotg *hsotg, | 1041 | static int s3c_hsotg_process_req_feature(struct dwc2_hsotg *hsotg, |
961 | struct usb_ctrlrequest *ctrl) | 1042 | struct usb_ctrlrequest *ctrl) |
962 | { | 1043 | { |
963 | struct s3c_hsotg_ep *ep0 = &hsotg->eps[0]; | 1044 | struct s3c_hsotg_ep *ep0 = hsotg->eps_out[0]; |
964 | struct s3c_hsotg_req *hs_req; | 1045 | struct s3c_hsotg_req *hs_req; |
965 | bool restart; | 1046 | bool restart; |
966 | bool set = (ctrl->bRequest == USB_REQ_SET_FEATURE); | 1047 | bool set = (ctrl->bRequest == USB_REQ_SET_FEATURE); |
967 | struct s3c_hsotg_ep *ep; | 1048 | struct s3c_hsotg_ep *ep; |
968 | int ret; | 1049 | int ret; |
969 | bool halted; | 1050 | bool halted; |
1051 | u32 recip; | ||
1052 | u32 wValue; | ||
1053 | u32 wIndex; | ||
970 | 1054 | ||
971 | dev_dbg(hsotg->dev, "%s: %s_FEATURE\n", | 1055 | dev_dbg(hsotg->dev, "%s: %s_FEATURE\n", |
972 | __func__, set ? "SET" : "CLEAR"); | 1056 | __func__, set ? "SET" : "CLEAR"); |
973 | 1057 | ||
974 | if (ctrl->bRequestType == USB_RECIP_ENDPOINT) { | 1058 | wValue = le16_to_cpu(ctrl->wValue); |
975 | ep = ep_from_windex(hsotg, le16_to_cpu(ctrl->wIndex)); | 1059 | wIndex = le16_to_cpu(ctrl->wIndex); |
1060 | recip = ctrl->bRequestType & USB_RECIP_MASK; | ||
1061 | |||
1062 | switch (recip) { | ||
1063 | case USB_RECIP_DEVICE: | ||
1064 | switch (wValue) { | ||
1065 | case USB_DEVICE_TEST_MODE: | ||
1066 | if ((wIndex & 0xff) != 0) | ||
1067 | return -EINVAL; | ||
1068 | if (!set) | ||
1069 | return -EINVAL; | ||
1070 | |||
1071 | hsotg->test_mode = wIndex >> 8; | ||
1072 | ret = s3c_hsotg_send_reply(hsotg, ep0, NULL, 0); | ||
1073 | if (ret) { | ||
1074 | dev_err(hsotg->dev, | ||
1075 | "%s: failed to send reply\n", __func__); | ||
1076 | return ret; | ||
1077 | } | ||
1078 | break; | ||
1079 | default: | ||
1080 | return -ENOENT; | ||
1081 | } | ||
1082 | break; | ||
1083 | |||
1084 | case USB_RECIP_ENDPOINT: | ||
1085 | ep = ep_from_windex(hsotg, wIndex); | ||
976 | if (!ep) { | 1086 | if (!ep) { |
977 | dev_dbg(hsotg->dev, "%s: no endpoint for 0x%04x\n", | 1087 | dev_dbg(hsotg->dev, "%s: no endpoint for 0x%04x\n", |
978 | __func__, le16_to_cpu(ctrl->wIndex)); | 1088 | __func__, wIndex); |
979 | return -ENOENT; | 1089 | return -ENOENT; |
980 | } | 1090 | } |
981 | 1091 | ||
982 | switch (le16_to_cpu(ctrl->wValue)) { | 1092 | switch (wValue) { |
983 | case USB_ENDPOINT_HALT: | 1093 | case USB_ENDPOINT_HALT: |
984 | halted = ep->halted; | 1094 | halted = ep->halted; |
985 | 1095 | ||
@@ -1006,16 +1116,22 @@ static int s3c_hsotg_process_req_feature(struct dwc2_hsotg *hsotg, | |||
1006 | hs_req = ep->req; | 1116 | hs_req = ep->req; |
1007 | ep->req = NULL; | 1117 | ep->req = NULL; |
1008 | list_del_init(&hs_req->queue); | 1118 | list_del_init(&hs_req->queue); |
1009 | usb_gadget_giveback_request(&ep->ep, | 1119 | if (hs_req->req.complete) { |
1010 | &hs_req->req); | 1120 | spin_unlock(&hsotg->lock); |
1121 | usb_gadget_giveback_request( | ||
1122 | &ep->ep, &hs_req->req); | ||
1123 | spin_lock(&hsotg->lock); | ||
1124 | } | ||
1011 | } | 1125 | } |
1012 | 1126 | ||
1013 | /* If we have pending request, then start it */ | 1127 | /* If we have pending request, then start it */ |
1014 | restart = !list_empty(&ep->queue); | 1128 | if (!ep->req) { |
1015 | if (restart) { | 1129 | restart = !list_empty(&ep->queue); |
1016 | hs_req = get_ep_head(ep); | 1130 | if (restart) { |
1017 | s3c_hsotg_start_req(hsotg, ep, | 1131 | hs_req = get_ep_head(ep); |
1018 | hs_req, false); | 1132 | s3c_hsotg_start_req(hsotg, ep, |
1133 | hs_req, false); | ||
1134 | } | ||
1019 | } | 1135 | } |
1020 | } | 1136 | } |
1021 | 1137 | ||
@@ -1024,9 +1140,10 @@ static int s3c_hsotg_process_req_feature(struct dwc2_hsotg *hsotg, | |||
1024 | default: | 1140 | default: |
1025 | return -ENOENT; | 1141 | return -ENOENT; |
1026 | } | 1142 | } |
1027 | } else | 1143 | break; |
1028 | return -ENOENT; /* currently only deal with endpoint */ | 1144 | default: |
1029 | 1145 | return -ENOENT; | |
1146 | } | ||
1030 | return 1; | 1147 | return 1; |
1031 | } | 1148 | } |
1032 | 1149 | ||
@@ -1040,7 +1157,7 @@ static void s3c_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg); | |||
1040 | */ | 1157 | */ |
1041 | static void s3c_hsotg_stall_ep0(struct dwc2_hsotg *hsotg) | 1158 | static void s3c_hsotg_stall_ep0(struct dwc2_hsotg *hsotg) |
1042 | { | 1159 | { |
1043 | struct s3c_hsotg_ep *ep0 = &hsotg->eps[0]; | 1160 | struct s3c_hsotg_ep *ep0 = hsotg->eps_out[0]; |
1044 | u32 reg; | 1161 | u32 reg; |
1045 | u32 ctrl; | 1162 | u32 ctrl; |
1046 | 1163 | ||
@@ -1080,34 +1197,29 @@ static void s3c_hsotg_stall_ep0(struct dwc2_hsotg *hsotg) | |||
1080 | static void s3c_hsotg_process_control(struct dwc2_hsotg *hsotg, | 1197 | static void s3c_hsotg_process_control(struct dwc2_hsotg *hsotg, |
1081 | struct usb_ctrlrequest *ctrl) | 1198 | struct usb_ctrlrequest *ctrl) |
1082 | { | 1199 | { |
1083 | struct s3c_hsotg_ep *ep0 = &hsotg->eps[0]; | 1200 | struct s3c_hsotg_ep *ep0 = hsotg->eps_out[0]; |
1084 | int ret = 0; | 1201 | int ret = 0; |
1085 | u32 dcfg; | 1202 | u32 dcfg; |
1086 | 1203 | ||
1087 | ep0->sent_zlp = 0; | ||
1088 | |||
1089 | dev_dbg(hsotg->dev, "ctrl Req=%02x, Type=%02x, V=%04x, L=%04x\n", | 1204 | dev_dbg(hsotg->dev, "ctrl Req=%02x, Type=%02x, V=%04x, L=%04x\n", |
1090 | ctrl->bRequest, ctrl->bRequestType, | 1205 | ctrl->bRequest, ctrl->bRequestType, |
1091 | ctrl->wValue, ctrl->wLength); | 1206 | ctrl->wValue, ctrl->wLength); |
1092 | 1207 | ||
1093 | /* | 1208 | if (ctrl->wLength == 0) { |
1094 | * record the direction of the request, for later use when enquing | ||
1095 | * packets onto EP0. | ||
1096 | */ | ||
1097 | |||
1098 | ep0->dir_in = (ctrl->bRequestType & USB_DIR_IN) ? 1 : 0; | ||
1099 | dev_dbg(hsotg->dev, "ctrl: dir_in=%d\n", ep0->dir_in); | ||
1100 | |||
1101 | /* | ||
1102 | * if we've no data with this request, then the last part of the | ||
1103 | * transaction is going to implicitly be IN. | ||
1104 | */ | ||
1105 | if (ctrl->wLength == 0) | ||
1106 | ep0->dir_in = 1; | 1209 | ep0->dir_in = 1; |
1210 | hsotg->ep0_state = DWC2_EP0_STATUS_IN; | ||
1211 | } else if (ctrl->bRequestType & USB_DIR_IN) { | ||
1212 | ep0->dir_in = 1; | ||
1213 | hsotg->ep0_state = DWC2_EP0_DATA_IN; | ||
1214 | } else { | ||
1215 | ep0->dir_in = 0; | ||
1216 | hsotg->ep0_state = DWC2_EP0_DATA_OUT; | ||
1217 | } | ||
1107 | 1218 | ||
1108 | if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) { | 1219 | if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) { |
1109 | switch (ctrl->bRequest) { | 1220 | switch (ctrl->bRequest) { |
1110 | case USB_REQ_SET_ADDRESS: | 1221 | case USB_REQ_SET_ADDRESS: |
1222 | hsotg->connected = 1; | ||
1111 | dcfg = readl(hsotg->regs + DCFG); | 1223 | dcfg = readl(hsotg->regs + DCFG); |
1112 | dcfg &= ~DCFG_DEVADDR_MASK; | 1224 | dcfg &= ~DCFG_DEVADDR_MASK; |
1113 | dcfg |= (le16_to_cpu(ctrl->wValue) << | 1225 | dcfg |= (le16_to_cpu(ctrl->wValue) << |
@@ -1201,9 +1313,11 @@ static void s3c_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg) | |||
1201 | return; | 1313 | return; |
1202 | } | 1314 | } |
1203 | 1315 | ||
1204 | hsotg->eps[0].dir_in = 0; | 1316 | hsotg->eps_out[0]->dir_in = 0; |
1317 | hsotg->eps_out[0]->send_zlp = 0; | ||
1318 | hsotg->ep0_state = DWC2_EP0_SETUP; | ||
1205 | 1319 | ||
1206 | ret = s3c_hsotg_ep_queue(&hsotg->eps[0].ep, req, GFP_ATOMIC); | 1320 | ret = s3c_hsotg_ep_queue(&hsotg->eps_out[0]->ep, req, GFP_ATOMIC); |
1207 | if (ret < 0) { | 1321 | if (ret < 0) { |
1208 | dev_err(hsotg->dev, "%s: failed queue (%d)\n", __func__, ret); | 1322 | dev_err(hsotg->dev, "%s: failed queue (%d)\n", __func__, ret); |
1209 | /* | 1323 | /* |
@@ -1213,6 +1327,32 @@ static void s3c_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg) | |||
1213 | } | 1327 | } |
1214 | } | 1328 | } |
1215 | 1329 | ||
1330 | static void s3c_hsotg_program_zlp(struct dwc2_hsotg *hsotg, | ||
1331 | struct s3c_hsotg_ep *hs_ep) | ||
1332 | { | ||
1333 | u32 ctrl; | ||
1334 | u8 index = hs_ep->index; | ||
1335 | u32 epctl_reg = hs_ep->dir_in ? DIEPCTL(index) : DOEPCTL(index); | ||
1336 | u32 epsiz_reg = hs_ep->dir_in ? DIEPTSIZ(index) : DOEPTSIZ(index); | ||
1337 | |||
1338 | if (hs_ep->dir_in) | ||
1339 | dev_dbg(hsotg->dev, "Sending zero-length packet on ep%d\n", | ||
1340 | index); | ||
1341 | else | ||
1342 | dev_dbg(hsotg->dev, "Receiving zero-length packet on ep%d\n", | ||
1343 | index); | ||
1344 | |||
1345 | writel(DXEPTSIZ_MC(1) | DXEPTSIZ_PKTCNT(1) | | ||
1346 | DXEPTSIZ_XFERSIZE(0), hsotg->regs + | ||
1347 | epsiz_reg); | ||
1348 | |||
1349 | ctrl = readl(hsotg->regs + epctl_reg); | ||
1350 | ctrl |= DXEPCTL_CNAK; /* clear NAK set by core */ | ||
1351 | ctrl |= DXEPCTL_EPENA; /* ensure ep enabled */ | ||
1352 | ctrl |= DXEPCTL_USBACTEP; | ||
1353 | writel(ctrl, hsotg->regs + epctl_reg); | ||
1354 | } | ||
1355 | |||
1216 | /** | 1356 | /** |
1217 | * s3c_hsotg_complete_request - complete a request given to us | 1357 | * s3c_hsotg_complete_request - complete a request given to us |
1218 | * @hsotg: The device state. | 1358 | * @hsotg: The device state. |
@@ -1249,6 +1389,8 @@ static void s3c_hsotg_complete_request(struct dwc2_hsotg *hsotg, | |||
1249 | if (hs_req->req.status == -EINPROGRESS) | 1389 | if (hs_req->req.status == -EINPROGRESS) |
1250 | hs_req->req.status = result; | 1390 | hs_req->req.status = result; |
1251 | 1391 | ||
1392 | s3c_hsotg_handle_unaligned_buf_complete(hsotg, hs_ep, hs_req); | ||
1393 | |||
1252 | hs_ep->req = NULL; | 1394 | hs_ep->req = NULL; |
1253 | list_del_init(&hs_req->queue); | 1395 | list_del_init(&hs_req->queue); |
1254 | 1396 | ||
@@ -1293,7 +1435,7 @@ static void s3c_hsotg_complete_request(struct dwc2_hsotg *hsotg, | |||
1293 | */ | 1435 | */ |
1294 | static void s3c_hsotg_rx_data(struct dwc2_hsotg *hsotg, int ep_idx, int size) | 1436 | static void s3c_hsotg_rx_data(struct dwc2_hsotg *hsotg, int ep_idx, int size) |
1295 | { | 1437 | { |
1296 | struct s3c_hsotg_ep *hs_ep = &hsotg->eps[ep_idx]; | 1438 | struct s3c_hsotg_ep *hs_ep = hsotg->eps_out[ep_idx]; |
1297 | struct s3c_hsotg_req *hs_req = hs_ep->req; | 1439 | struct s3c_hsotg_req *hs_req = hs_ep->req; |
1298 | void __iomem *fifo = hsotg->regs + EPFIFO(ep_idx); | 1440 | void __iomem *fifo = hsotg->regs + EPFIFO(ep_idx); |
1299 | int to_read; | 1441 | int to_read; |
@@ -1305,7 +1447,7 @@ static void s3c_hsotg_rx_data(struct dwc2_hsotg *hsotg, int ep_idx, int size) | |||
1305 | u32 epctl = readl(hsotg->regs + DOEPCTL(ep_idx)); | 1447 | u32 epctl = readl(hsotg->regs + DOEPCTL(ep_idx)); |
1306 | int ptr; | 1448 | int ptr; |
1307 | 1449 | ||
1308 | dev_warn(hsotg->dev, | 1450 | dev_dbg(hsotg->dev, |
1309 | "%s: FIFO %d bytes on ep%d but no req (DXEPCTl=0x%08x)\n", | 1451 | "%s: FIFO %d bytes on ep%d but no req (DXEPCTl=0x%08x)\n", |
1310 | __func__, size, ep_idx, epctl); | 1452 | __func__, size, ep_idx, epctl); |
1311 | 1453 | ||
@@ -1345,9 +1487,9 @@ static void s3c_hsotg_rx_data(struct dwc2_hsotg *hsotg, int ep_idx, int size) | |||
1345 | } | 1487 | } |
1346 | 1488 | ||
1347 | /** | 1489 | /** |
1348 | * s3c_hsotg_send_zlp - send zero-length packet on control endpoint | 1490 | * s3c_hsotg_ep0_zlp - send/receive zero-length packet on control endpoint |
1349 | * @hsotg: The device instance | 1491 | * @hsotg: The device instance |
1350 | * @req: The request currently on this endpoint | 1492 | * @dir_in: If IN zlp |
1351 | * | 1493 | * |
1352 | * Generate a zero-length IN packet request for terminating a SETUP | 1494 | * Generate a zero-length IN packet request for terminating a SETUP |
1353 | * transaction. | 1495 | * transaction. |
@@ -1356,53 +1498,28 @@ static void s3c_hsotg_rx_data(struct dwc2_hsotg *hsotg, int ep_idx, int size) | |||
1356 | * currently believed that we do not need to wait for any space in | 1498 | * currently believed that we do not need to wait for any space in |
1357 | * the TxFIFO. | 1499 | * the TxFIFO. |
1358 | */ | 1500 | */ |
1359 | static void s3c_hsotg_send_zlp(struct dwc2_hsotg *hsotg, | 1501 | static void s3c_hsotg_ep0_zlp(struct dwc2_hsotg *hsotg, bool dir_in) |
1360 | struct s3c_hsotg_req *req) | ||
1361 | { | 1502 | { |
1362 | u32 ctrl; | 1503 | /* eps_out[0] is used in both directions */ |
1504 | hsotg->eps_out[0]->dir_in = dir_in; | ||
1505 | hsotg->ep0_state = dir_in ? DWC2_EP0_STATUS_IN : DWC2_EP0_STATUS_OUT; | ||
1363 | 1506 | ||
1364 | if (!req) { | 1507 | s3c_hsotg_program_zlp(hsotg, hsotg->eps_out[0]); |
1365 | dev_warn(hsotg->dev, "%s: no request?\n", __func__); | ||
1366 | return; | ||
1367 | } | ||
1368 | |||
1369 | if (req->req.length == 0) { | ||
1370 | hsotg->eps[0].sent_zlp = 1; | ||
1371 | s3c_hsotg_enqueue_setup(hsotg); | ||
1372 | return; | ||
1373 | } | ||
1374 | |||
1375 | hsotg->eps[0].dir_in = 1; | ||
1376 | hsotg->eps[0].sent_zlp = 1; | ||
1377 | |||
1378 | dev_dbg(hsotg->dev, "sending zero-length packet\n"); | ||
1379 | |||
1380 | /* issue a zero-sized packet to terminate this */ | ||
1381 | writel(DXEPTSIZ_MC(1) | DXEPTSIZ_PKTCNT(1) | | ||
1382 | DXEPTSIZ_XFERSIZE(0), hsotg->regs + DIEPTSIZ(0)); | ||
1383 | |||
1384 | ctrl = readl(hsotg->regs + DIEPCTL0); | ||
1385 | ctrl |= DXEPCTL_CNAK; /* clear NAK set by core */ | ||
1386 | ctrl |= DXEPCTL_EPENA; /* ensure ep enabled */ | ||
1387 | ctrl |= DXEPCTL_USBACTEP; | ||
1388 | writel(ctrl, hsotg->regs + DIEPCTL0); | ||
1389 | } | 1508 | } |
1390 | 1509 | ||
1391 | /** | 1510 | /** |
1392 | * s3c_hsotg_handle_outdone - handle receiving OutDone/SetupDone from RXFIFO | 1511 | * s3c_hsotg_handle_outdone - handle receiving OutDone/SetupDone from RXFIFO |
1393 | * @hsotg: The device instance | 1512 | * @hsotg: The device instance |
1394 | * @epnum: The endpoint received from | 1513 | * @epnum: The endpoint received from |
1395 | * @was_setup: Set if processing a SetupDone event. | ||
1396 | * | 1514 | * |
1397 | * The RXFIFO has delivered an OutDone event, which means that the data | 1515 | * The RXFIFO has delivered an OutDone event, which means that the data |
1398 | * transfer for an OUT endpoint has been completed, either by a short | 1516 | * transfer for an OUT endpoint has been completed, either by a short |
1399 | * packet or by the finish of a transfer. | 1517 | * packet or by the finish of a transfer. |
1400 | */ | 1518 | */ |
1401 | static void s3c_hsotg_handle_outdone(struct dwc2_hsotg *hsotg, | 1519 | static void s3c_hsotg_handle_outdone(struct dwc2_hsotg *hsotg, int epnum) |
1402 | int epnum, bool was_setup) | ||
1403 | { | 1520 | { |
1404 | u32 epsize = readl(hsotg->regs + DOEPTSIZ(epnum)); | 1521 | u32 epsize = readl(hsotg->regs + DOEPTSIZ(epnum)); |
1405 | struct s3c_hsotg_ep *hs_ep = &hsotg->eps[epnum]; | 1522 | struct s3c_hsotg_ep *hs_ep = hsotg->eps_out[epnum]; |
1406 | struct s3c_hsotg_req *hs_req = hs_ep->req; | 1523 | struct s3c_hsotg_req *hs_req = hs_ep->req; |
1407 | struct usb_request *req = &hs_req->req; | 1524 | struct usb_request *req = &hs_req->req; |
1408 | unsigned size_left = DXEPTSIZ_XFERSIZE_GET(epsize); | 1525 | unsigned size_left = DXEPTSIZ_XFERSIZE_GET(epsize); |
@@ -1413,6 +1530,13 @@ static void s3c_hsotg_handle_outdone(struct dwc2_hsotg *hsotg, | |||
1413 | return; | 1530 | return; |
1414 | } | 1531 | } |
1415 | 1532 | ||
1533 | if (epnum == 0 && hsotg->ep0_state == DWC2_EP0_STATUS_OUT) { | ||
1534 | dev_dbg(hsotg->dev, "zlp packet received\n"); | ||
1535 | s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, 0); | ||
1536 | s3c_hsotg_enqueue_setup(hsotg); | ||
1537 | return; | ||
1538 | } | ||
1539 | |||
1416 | if (using_dma(hsotg)) { | 1540 | if (using_dma(hsotg)) { |
1417 | unsigned size_done; | 1541 | unsigned size_done; |
1418 | 1542 | ||
@@ -1435,12 +1559,6 @@ static void s3c_hsotg_handle_outdone(struct dwc2_hsotg *hsotg, | |||
1435 | if (req->actual < req->length && size_left == 0) { | 1559 | if (req->actual < req->length && size_left == 0) { |
1436 | s3c_hsotg_start_req(hsotg, hs_ep, hs_req, true); | 1560 | s3c_hsotg_start_req(hsotg, hs_ep, hs_req, true); |
1437 | return; | 1561 | return; |
1438 | } else if (epnum == 0) { | ||
1439 | /* | ||
1440 | * After was_setup = 1 => | ||
1441 | * set CNAK for non Setup requests | ||
1442 | */ | ||
1443 | hsotg->setup = was_setup ? 0 : 1; | ||
1444 | } | 1562 | } |
1445 | 1563 | ||
1446 | if (req->actual < req->length && req->short_not_ok) { | 1564 | if (req->actual < req->length && req->short_not_ok) { |
@@ -1453,13 +1571,10 @@ static void s3c_hsotg_handle_outdone(struct dwc2_hsotg *hsotg, | |||
1453 | */ | 1571 | */ |
1454 | } | 1572 | } |
1455 | 1573 | ||
1456 | if (epnum == 0) { | 1574 | if (epnum == 0 && hsotg->ep0_state == DWC2_EP0_DATA_OUT) { |
1457 | /* | 1575 | /* Move to STATUS IN */ |
1458 | * Condition req->complete != s3c_hsotg_complete_setup says: | 1576 | s3c_hsotg_ep0_zlp(hsotg, true); |
1459 | * send ZLP when we have an asynchronous request from gadget | 1577 | return; |
1460 | */ | ||
1461 | if (!was_setup && req->complete != s3c_hsotg_complete_setup) | ||
1462 | s3c_hsotg_send_zlp(hsotg, hs_req); | ||
1463 | } | 1578 | } |
1464 | 1579 | ||
1465 | s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, result); | 1580 | s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, result); |
@@ -1511,8 +1626,7 @@ static void s3c_hsotg_handle_rx(struct dwc2_hsotg *hsotg) | |||
1511 | size = grxstsr & GRXSTS_BYTECNT_MASK; | 1626 | size = grxstsr & GRXSTS_BYTECNT_MASK; |
1512 | size >>= GRXSTS_BYTECNT_SHIFT; | 1627 | size >>= GRXSTS_BYTECNT_SHIFT; |
1513 | 1628 | ||
1514 | if (1) | 1629 | dev_dbg(hsotg->dev, "%s: GRXSTSP=0x%08x (%d@%d)\n", |
1515 | dev_dbg(hsotg->dev, "%s: GRXSTSP=0x%08x (%d@%d)\n", | ||
1516 | __func__, grxstsr, size, epnum); | 1630 | __func__, grxstsr, size, epnum); |
1517 | 1631 | ||
1518 | switch ((status & GRXSTS_PKTSTS_MASK) >> GRXSTS_PKTSTS_SHIFT) { | 1632 | switch ((status & GRXSTS_PKTSTS_MASK) >> GRXSTS_PKTSTS_SHIFT) { |
@@ -1525,7 +1639,7 @@ static void s3c_hsotg_handle_rx(struct dwc2_hsotg *hsotg) | |||
1525 | s3c_hsotg_read_frameno(hsotg)); | 1639 | s3c_hsotg_read_frameno(hsotg)); |
1526 | 1640 | ||
1527 | if (!using_dma(hsotg)) | 1641 | if (!using_dma(hsotg)) |
1528 | s3c_hsotg_handle_outdone(hsotg, epnum, false); | 1642 | s3c_hsotg_handle_outdone(hsotg, epnum); |
1529 | break; | 1643 | break; |
1530 | 1644 | ||
1531 | case GRXSTS_PKTSTS_SETUPDONE: | 1645 | case GRXSTS_PKTSTS_SETUPDONE: |
@@ -1533,8 +1647,13 @@ static void s3c_hsotg_handle_rx(struct dwc2_hsotg *hsotg) | |||
1533 | "SetupDone (Frame=0x%08x, DOPEPCTL=0x%08x)\n", | 1647 | "SetupDone (Frame=0x%08x, DOPEPCTL=0x%08x)\n", |
1534 | s3c_hsotg_read_frameno(hsotg), | 1648 | s3c_hsotg_read_frameno(hsotg), |
1535 | readl(hsotg->regs + DOEPCTL(0))); | 1649 | readl(hsotg->regs + DOEPCTL(0))); |
1536 | 1650 | /* | |
1537 | s3c_hsotg_handle_outdone(hsotg, epnum, true); | 1651 | * Call s3c_hsotg_handle_outdone here if it was not called from |
1652 | * GRXSTS_PKTSTS_OUTDONE. That is, if the core didn't | ||
1653 | * generate GRXSTS_PKTSTS_OUTDONE for setup packet. | ||
1654 | */ | ||
1655 | if (hsotg->ep0_state == DWC2_EP0_SETUP) | ||
1656 | s3c_hsotg_handle_outdone(hsotg, epnum); | ||
1538 | break; | 1657 | break; |
1539 | 1658 | ||
1540 | case GRXSTS_PKTSTS_OUTRX: | 1659 | case GRXSTS_PKTSTS_OUTRX: |
@@ -1547,6 +1666,8 @@ static void s3c_hsotg_handle_rx(struct dwc2_hsotg *hsotg) | |||
1547 | s3c_hsotg_read_frameno(hsotg), | 1666 | s3c_hsotg_read_frameno(hsotg), |
1548 | readl(hsotg->regs + DOEPCTL(0))); | 1667 | readl(hsotg->regs + DOEPCTL(0))); |
1549 | 1668 | ||
1669 | WARN_ON(hsotg->ep0_state != DWC2_EP0_SETUP); | ||
1670 | |||
1550 | s3c_hsotg_rx_data(hsotg, epnum, size); | 1671 | s3c_hsotg_rx_data(hsotg, epnum, size); |
1551 | break; | 1672 | break; |
1552 | 1673 | ||
@@ -1591,14 +1712,18 @@ static u32 s3c_hsotg_ep0_mps(unsigned int mps) | |||
1591 | * the hardware control registers to reflect this. | 1712 | * the hardware control registers to reflect this. |
1592 | */ | 1713 | */ |
1593 | static void s3c_hsotg_set_ep_maxpacket(struct dwc2_hsotg *hsotg, | 1714 | static void s3c_hsotg_set_ep_maxpacket(struct dwc2_hsotg *hsotg, |
1594 | unsigned int ep, unsigned int mps) | 1715 | unsigned int ep, unsigned int mps, unsigned int dir_in) |
1595 | { | 1716 | { |
1596 | struct s3c_hsotg_ep *hs_ep = &hsotg->eps[ep]; | 1717 | struct s3c_hsotg_ep *hs_ep; |
1597 | void __iomem *regs = hsotg->regs; | 1718 | void __iomem *regs = hsotg->regs; |
1598 | u32 mpsval; | 1719 | u32 mpsval; |
1599 | u32 mcval; | 1720 | u32 mcval; |
1600 | u32 reg; | 1721 | u32 reg; |
1601 | 1722 | ||
1723 | hs_ep = index_to_ep(hsotg, ep, dir_in); | ||
1724 | if (!hs_ep) | ||
1725 | return; | ||
1726 | |||
1602 | if (ep == 0) { | 1727 | if (ep == 0) { |
1603 | /* EP0 is a special case */ | 1728 | /* EP0 is a special case */ |
1604 | mpsval = s3c_hsotg_ep0_mps(mps); | 1729 | mpsval = s3c_hsotg_ep0_mps(mps); |
@@ -1617,17 +1742,12 @@ static void s3c_hsotg_set_ep_maxpacket(struct dwc2_hsotg *hsotg, | |||
1617 | hs_ep->ep.maxpacket = mpsval; | 1742 | hs_ep->ep.maxpacket = mpsval; |
1618 | } | 1743 | } |
1619 | 1744 | ||
1620 | /* | 1745 | if (dir_in) { |
1621 | * update both the in and out endpoint controldir_ registers, even | 1746 | reg = readl(regs + DIEPCTL(ep)); |
1622 | * if one of the directions may not be in use. | 1747 | reg &= ~DXEPCTL_MPS_MASK; |
1623 | */ | 1748 | reg |= mpsval; |
1624 | 1749 | writel(reg, regs + DIEPCTL(ep)); | |
1625 | reg = readl(regs + DIEPCTL(ep)); | 1750 | } else { |
1626 | reg &= ~DXEPCTL_MPS_MASK; | ||
1627 | reg |= mpsval; | ||
1628 | writel(reg, regs + DIEPCTL(ep)); | ||
1629 | |||
1630 | if (ep) { | ||
1631 | reg = readl(regs + DOEPCTL(ep)); | 1751 | reg = readl(regs + DOEPCTL(ep)); |
1632 | reg &= ~DXEPCTL_MPS_MASK; | 1752 | reg &= ~DXEPCTL_MPS_MASK; |
1633 | reg |= mpsval; | 1753 | reg |= mpsval; |
@@ -1727,9 +1847,21 @@ static void s3c_hsotg_complete_in(struct dwc2_hsotg *hsotg, | |||
1727 | } | 1847 | } |
1728 | 1848 | ||
1729 | /* Finish ZLP handling for IN EP0 transactions */ | 1849 | /* Finish ZLP handling for IN EP0 transactions */ |
1730 | if (hsotg->eps[0].sent_zlp) { | 1850 | if (hs_ep->index == 0 && hsotg->ep0_state == DWC2_EP0_STATUS_IN) { |
1731 | dev_dbg(hsotg->dev, "zlp packet received\n"); | 1851 | dev_dbg(hsotg->dev, "zlp packet sent\n"); |
1732 | s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, 0); | 1852 | s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, 0); |
1853 | if (hsotg->test_mode) { | ||
1854 | int ret; | ||
1855 | |||
1856 | ret = s3c_hsotg_set_test_mode(hsotg, hsotg->test_mode); | ||
1857 | if (ret < 0) { | ||
1858 | dev_dbg(hsotg->dev, "Invalid Test #%d\n", | ||
1859 | hsotg->test_mode); | ||
1860 | s3c_hsotg_stall_ep0(hsotg); | ||
1861 | return; | ||
1862 | } | ||
1863 | } | ||
1864 | s3c_hsotg_enqueue_setup(hsotg); | ||
1733 | return; | 1865 | return; |
1734 | } | 1866 | } |
1735 | 1867 | ||
@@ -1756,31 +1888,27 @@ static void s3c_hsotg_complete_in(struct dwc2_hsotg *hsotg, | |||
1756 | dev_dbg(hsotg->dev, "req->length:%d req->actual:%d req->zero:%d\n", | 1888 | dev_dbg(hsotg->dev, "req->length:%d req->actual:%d req->zero:%d\n", |
1757 | hs_req->req.length, hs_req->req.actual, hs_req->req.zero); | 1889 | hs_req->req.length, hs_req->req.actual, hs_req->req.zero); |
1758 | 1890 | ||
1759 | /* | 1891 | if (!size_left && hs_req->req.actual < hs_req->req.length) { |
1760 | * Check if dealing with Maximum Packet Size(MPS) IN transfer at EP0 | 1892 | dev_dbg(hsotg->dev, "%s trying more for req...\n", __func__); |
1761 | * When sent data is a multiple MPS size (e.g. 64B ,128B ,192B | 1893 | s3c_hsotg_start_req(hsotg, hs_ep, hs_req, true); |
1762 | * ,256B ... ), after last MPS sized packet send IN ZLP packet to | 1894 | return; |
1763 | * inform the host that no more data is available. | 1895 | } |
1764 | * The state of req.zero member is checked to be sure that the value to | ||
1765 | * send is smaller than wValue expected from host. | ||
1766 | * Check req.length to NOT send another ZLP when the current one is | ||
1767 | * under completion (the one for which this completion has been called). | ||
1768 | */ | ||
1769 | if (hs_req->req.length && hs_ep->index == 0 && hs_req->req.zero && | ||
1770 | hs_req->req.length == hs_req->req.actual && | ||
1771 | !(hs_req->req.length % hs_ep->ep.maxpacket)) { | ||
1772 | 1896 | ||
1773 | dev_dbg(hsotg->dev, "ep0 zlp IN packet sent\n"); | 1897 | /* Zlp for all endpoints, for ep0 only in DATA IN stage */ |
1774 | s3c_hsotg_send_zlp(hsotg, hs_req); | 1898 | if (hs_ep->send_zlp) { |
1899 | s3c_hsotg_program_zlp(hsotg, hs_ep); | ||
1900 | hs_ep->send_zlp = 0; | ||
1901 | /* transfer will be completed on next complete interrupt */ | ||
1902 | return; | ||
1903 | } | ||
1775 | 1904 | ||
1905 | if (hs_ep->index == 0 && hsotg->ep0_state == DWC2_EP0_DATA_IN) { | ||
1906 | /* Move to STATUS OUT */ | ||
1907 | s3c_hsotg_ep0_zlp(hsotg, false); | ||
1776 | return; | 1908 | return; |
1777 | } | 1909 | } |
1778 | 1910 | ||
1779 | if (!size_left && hs_req->req.actual < hs_req->req.length) { | 1911 | s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, 0); |
1780 | dev_dbg(hsotg->dev, "%s trying more for req...\n", __func__); | ||
1781 | s3c_hsotg_start_req(hsotg, hs_ep, hs_req, true); | ||
1782 | } else | ||
1783 | s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, 0); | ||
1784 | } | 1912 | } |
1785 | 1913 | ||
1786 | /** | 1914 | /** |
@@ -1794,7 +1922,7 @@ static void s3c_hsotg_complete_in(struct dwc2_hsotg *hsotg, | |||
1794 | static void s3c_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx, | 1922 | static void s3c_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx, |
1795 | int dir_in) | 1923 | int dir_in) |
1796 | { | 1924 | { |
1797 | struct s3c_hsotg_ep *hs_ep = &hsotg->eps[idx]; | 1925 | struct s3c_hsotg_ep *hs_ep = index_to_ep(hsotg, idx, dir_in); |
1798 | u32 epint_reg = dir_in ? DIEPINT(idx) : DOEPINT(idx); | 1926 | u32 epint_reg = dir_in ? DIEPINT(idx) : DOEPINT(idx); |
1799 | u32 epctl_reg = dir_in ? DIEPCTL(idx) : DOEPCTL(idx); | 1927 | u32 epctl_reg = dir_in ? DIEPCTL(idx) : DOEPCTL(idx); |
1800 | u32 epsiz_reg = dir_in ? DIEPTSIZ(idx) : DOEPTSIZ(idx); | 1928 | u32 epsiz_reg = dir_in ? DIEPTSIZ(idx) : DOEPTSIZ(idx); |
@@ -1807,9 +1935,19 @@ static void s3c_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx, | |||
1807 | /* Clear endpoint interrupts */ | 1935 | /* Clear endpoint interrupts */ |
1808 | writel(ints, hsotg->regs + epint_reg); | 1936 | writel(ints, hsotg->regs + epint_reg); |
1809 | 1937 | ||
1938 | if (!hs_ep) { | ||
1939 | dev_err(hsotg->dev, "%s:Interrupt for unconfigured ep%d(%s)\n", | ||
1940 | __func__, idx, dir_in ? "in" : "out"); | ||
1941 | return; | ||
1942 | } | ||
1943 | |||
1810 | dev_dbg(hsotg->dev, "%s: ep%d(%s) DxEPINT=0x%08x\n", | 1944 | dev_dbg(hsotg->dev, "%s: ep%d(%s) DxEPINT=0x%08x\n", |
1811 | __func__, idx, dir_in ? "in" : "out", ints); | 1945 | __func__, idx, dir_in ? "in" : "out", ints); |
1812 | 1946 | ||
1947 | /* Don't process XferCompl interrupt if it is a setup packet */ | ||
1948 | if (idx == 0 && (ints & (DXEPINT_SETUP | DXEPINT_SETUP_RCVD))) | ||
1949 | ints &= ~DXEPINT_XFERCOMPL; | ||
1950 | |||
1813 | if (ints & DXEPINT_XFERCOMPL) { | 1951 | if (ints & DXEPINT_XFERCOMPL) { |
1814 | if (hs_ep->isochronous && hs_ep->interval == 1) { | 1952 | if (hs_ep->isochronous && hs_ep->interval == 1) { |
1815 | if (ctrl & DXEPCTL_EOFRNUM) | 1953 | if (ctrl & DXEPCTL_EOFRNUM) |
@@ -1839,7 +1977,7 @@ static void s3c_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx, | |||
1839 | * as we ignore the RXFIFO. | 1977 | * as we ignore the RXFIFO. |
1840 | */ | 1978 | */ |
1841 | 1979 | ||
1842 | s3c_hsotg_handle_outdone(hsotg, idx, false); | 1980 | s3c_hsotg_handle_outdone(hsotg, idx); |
1843 | } | 1981 | } |
1844 | } | 1982 | } |
1845 | 1983 | ||
@@ -1878,7 +2016,7 @@ static void s3c_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx, | |||
1878 | if (dir_in) | 2016 | if (dir_in) |
1879 | WARN_ON_ONCE(1); | 2017 | WARN_ON_ONCE(1); |
1880 | else | 2018 | else |
1881 | s3c_hsotg_handle_outdone(hsotg, 0, true); | 2019 | s3c_hsotg_handle_outdone(hsotg, 0); |
1882 | } | 2020 | } |
1883 | } | 2021 | } |
1884 | 2022 | ||
@@ -1969,9 +2107,15 @@ static void s3c_hsotg_irq_enumdone(struct dwc2_hsotg *hsotg) | |||
1969 | 2107 | ||
1970 | if (ep0_mps) { | 2108 | if (ep0_mps) { |
1971 | int i; | 2109 | int i; |
1972 | s3c_hsotg_set_ep_maxpacket(hsotg, 0, ep0_mps); | 2110 | /* Initialize ep0 for both in and out directions */ |
1973 | for (i = 1; i < hsotg->num_of_eps; i++) | 2111 | s3c_hsotg_set_ep_maxpacket(hsotg, 0, ep0_mps, 1); |
1974 | s3c_hsotg_set_ep_maxpacket(hsotg, i, ep_mps); | 2112 | s3c_hsotg_set_ep_maxpacket(hsotg, 0, ep0_mps, 0); |
2113 | for (i = 1; i < hsotg->num_of_eps; i++) { | ||
2114 | if (hsotg->eps_in[i]) | ||
2115 | s3c_hsotg_set_ep_maxpacket(hsotg, i, ep_mps, 1); | ||
2116 | if (hsotg->eps_out[i]) | ||
2117 | s3c_hsotg_set_ep_maxpacket(hsotg, i, ep_mps, 0); | ||
2118 | } | ||
1975 | } | 2119 | } |
1976 | 2120 | ||
1977 | /* ensure after enumeration our EP0 is active */ | 2121 | /* ensure after enumeration our EP0 is active */ |
@@ -1988,30 +2132,23 @@ static void s3c_hsotg_irq_enumdone(struct dwc2_hsotg *hsotg) | |||
1988 | * @hsotg: The device state. | 2132 | * @hsotg: The device state. |
1989 | * @ep: The endpoint the requests may be on. | 2133 | * @ep: The endpoint the requests may be on. |
1990 | * @result: The result code to use. | 2134 | * @result: The result code to use. |
1991 | * @force: Force removal of any current requests | ||
1992 | * | 2135 | * |
1993 | * Go through the requests on the given endpoint and mark them | 2136 | * Go through the requests on the given endpoint and mark them |
1994 | * completed with the given result code. | 2137 | * completed with the given result code. |
1995 | */ | 2138 | */ |
1996 | static void kill_all_requests(struct dwc2_hsotg *hsotg, | 2139 | static void kill_all_requests(struct dwc2_hsotg *hsotg, |
1997 | struct s3c_hsotg_ep *ep, | 2140 | struct s3c_hsotg_ep *ep, |
1998 | int result, bool force) | 2141 | int result) |
1999 | { | 2142 | { |
2000 | struct s3c_hsotg_req *req, *treq; | 2143 | struct s3c_hsotg_req *req, *treq; |
2001 | unsigned size; | 2144 | unsigned size; |
2002 | 2145 | ||
2003 | list_for_each_entry_safe(req, treq, &ep->queue, queue) { | 2146 | ep->req = NULL; |
2004 | /* | ||
2005 | * currently, we can't do much about an already | ||
2006 | * running request on an in endpoint | ||
2007 | */ | ||
2008 | |||
2009 | if (ep->req == req && ep->dir_in && !force) | ||
2010 | continue; | ||
2011 | 2147 | ||
2148 | list_for_each_entry_safe(req, treq, &ep->queue, queue) | ||
2012 | s3c_hsotg_complete_request(hsotg, ep, req, | 2149 | s3c_hsotg_complete_request(hsotg, ep, req, |
2013 | result); | 2150 | result); |
2014 | } | 2151 | |
2015 | if (!hsotg->dedicated_fifos) | 2152 | if (!hsotg->dedicated_fifos) |
2016 | return; | 2153 | return; |
2017 | size = (readl(hsotg->regs + DTXFSTS(ep->index)) & 0xffff) * 4; | 2154 | size = (readl(hsotg->regs + DTXFSTS(ep->index)) & 0xffff) * 4; |
@@ -2035,8 +2172,16 @@ void s3c_hsotg_disconnect(struct dwc2_hsotg *hsotg) | |||
2035 | return; | 2172 | return; |
2036 | 2173 | ||
2037 | hsotg->connected = 0; | 2174 | hsotg->connected = 0; |
2038 | for (ep = 0; ep < hsotg->num_of_eps; ep++) | 2175 | hsotg->test_mode = 0; |
2039 | kill_all_requests(hsotg, &hsotg->eps[ep], -ESHUTDOWN, true); | 2176 | |
2177 | for (ep = 0; ep < hsotg->num_of_eps; ep++) { | ||
2178 | if (hsotg->eps_in[ep]) | ||
2179 | kill_all_requests(hsotg, hsotg->eps_in[ep], | ||
2180 | -ESHUTDOWN); | ||
2181 | if (hsotg->eps_out[ep]) | ||
2182 | kill_all_requests(hsotg, hsotg->eps_out[ep], | ||
2183 | -ESHUTDOWN); | ||
2184 | } | ||
2040 | 2185 | ||
2041 | call_gadget(hsotg, disconnect); | 2186 | call_gadget(hsotg, disconnect); |
2042 | } | 2187 | } |
@@ -2053,9 +2198,11 @@ static void s3c_hsotg_irq_fifoempty(struct dwc2_hsotg *hsotg, bool periodic) | |||
2053 | int epno, ret; | 2198 | int epno, ret; |
2054 | 2199 | ||
2055 | /* look through for any more data to transmit */ | 2200 | /* look through for any more data to transmit */ |
2056 | |||
2057 | for (epno = 0; epno < hsotg->num_of_eps; epno++) { | 2201 | for (epno = 0; epno < hsotg->num_of_eps; epno++) { |
2058 | ep = &hsotg->eps[epno]; | 2202 | ep = index_to_ep(hsotg, epno, 1); |
2203 | |||
2204 | if (!ep) | ||
2205 | continue; | ||
2059 | 2206 | ||
2060 | if (!ep->dir_in) | 2207 | if (!ep->dir_in) |
2061 | continue; | 2208 | continue; |
@@ -2129,9 +2276,13 @@ static int s3c_hsotg_corereset(struct dwc2_hsotg *hsotg) | |||
2129 | * | 2276 | * |
2130 | * Issue a soft reset to the core, and await the core finishing it. | 2277 | * Issue a soft reset to the core, and await the core finishing it. |
2131 | */ | 2278 | */ |
2132 | void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg) | 2279 | void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, |
2280 | bool is_usb_reset) | ||
2133 | { | 2281 | { |
2134 | s3c_hsotg_corereset(hsotg); | 2282 | u32 val; |
2283 | |||
2284 | if (!is_usb_reset) | ||
2285 | s3c_hsotg_corereset(hsotg); | ||
2135 | 2286 | ||
2136 | /* | 2287 | /* |
2137 | * we must now enable ep0 ready for host detection and then | 2288 | * we must now enable ep0 ready for host detection and then |
@@ -2139,14 +2290,16 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg) | |||
2139 | */ | 2290 | */ |
2140 | 2291 | ||
2141 | /* set the PLL on, remove the HNP/SRP and set the PHY */ | 2292 | /* set the PLL on, remove the HNP/SRP and set the PHY */ |
2293 | val = (hsotg->phyif == GUSBCFG_PHYIF8) ? 9 : 5; | ||
2142 | writel(hsotg->phyif | GUSBCFG_TOUTCAL(7) | | 2294 | writel(hsotg->phyif | GUSBCFG_TOUTCAL(7) | |
2143 | (0x5 << 10), hsotg->regs + GUSBCFG); | 2295 | (val << GUSBCFG_USBTRDTIM_SHIFT), hsotg->regs + GUSBCFG); |
2144 | 2296 | ||
2145 | s3c_hsotg_init_fifo(hsotg); | 2297 | s3c_hsotg_init_fifo(hsotg); |
2146 | 2298 | ||
2147 | __orr32(hsotg->regs + DCTL, DCTL_SFTDISCON); | 2299 | if (!is_usb_reset) |
2300 | __orr32(hsotg->regs + DCTL, DCTL_SFTDISCON); | ||
2148 | 2301 | ||
2149 | writel(1 << 18 | DCFG_DEVSPD_HS, hsotg->regs + DCFG); | 2302 | writel(DCFG_EPMISCNT(1) | DCFG_DEVSPD_HS, hsotg->regs + DCFG); |
2150 | 2303 | ||
2151 | /* Clear any pending OTG interrupts */ | 2304 | /* Clear any pending OTG interrupts */ |
2152 | writel(0xffffffff, hsotg->regs + GOTGINT); | 2305 | writel(0xffffffff, hsotg->regs + GOTGINT); |
@@ -2163,7 +2316,7 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg) | |||
2163 | 2316 | ||
2164 | if (using_dma(hsotg)) | 2317 | if (using_dma(hsotg)) |
2165 | writel(GAHBCFG_GLBL_INTR_EN | GAHBCFG_DMA_EN | | 2318 | writel(GAHBCFG_GLBL_INTR_EN | GAHBCFG_DMA_EN | |
2166 | GAHBCFG_HBSTLEN_INCR4, | 2319 | (GAHBCFG_HBSTLEN_INCR4 << GAHBCFG_HBSTLEN_SHIFT), |
2167 | hsotg->regs + GAHBCFG); | 2320 | hsotg->regs + GAHBCFG); |
2168 | else | 2321 | else |
2169 | writel(((hsotg->dedicated_fifos) ? (GAHBCFG_NP_TXF_EMP_LVL | | 2322 | writel(((hsotg->dedicated_fifos) ? (GAHBCFG_NP_TXF_EMP_LVL | |
@@ -2177,8 +2330,8 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg) | |||
2177 | * interrupts. | 2330 | * interrupts. |
2178 | */ | 2331 | */ |
2179 | 2332 | ||
2180 | writel(((hsotg->dedicated_fifos) ? DIEPMSK_TXFIFOEMPTY | | 2333 | writel(((hsotg->dedicated_fifos && !using_dma(hsotg)) ? |
2181 | DIEPMSK_INTKNTXFEMPMSK : 0) | | 2334 | DIEPMSK_TXFIFOEMPTY | DIEPMSK_INTKNTXFEMPMSK : 0) | |
2182 | DIEPMSK_EPDISBLDMSK | DIEPMSK_XFERCOMPLMSK | | 2335 | DIEPMSK_EPDISBLDMSK | DIEPMSK_XFERCOMPLMSK | |
2183 | DIEPMSK_TIMEOUTMSK | DIEPMSK_AHBERRMSK | | 2336 | DIEPMSK_TIMEOUTMSK | DIEPMSK_AHBERRMSK | |
2184 | DIEPMSK_INTKNEPMISMSK, | 2337 | DIEPMSK_INTKNEPMISMSK, |
@@ -2215,9 +2368,11 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg) | |||
2215 | s3c_hsotg_ctrl_epint(hsotg, 0, 0, 1); | 2368 | s3c_hsotg_ctrl_epint(hsotg, 0, 0, 1); |
2216 | s3c_hsotg_ctrl_epint(hsotg, 0, 1, 1); | 2369 | s3c_hsotg_ctrl_epint(hsotg, 0, 1, 1); |
2217 | 2370 | ||
2218 | __orr32(hsotg->regs + DCTL, DCTL_PWRONPRGDONE); | 2371 | if (!is_usb_reset) { |
2219 | udelay(10); /* see openiboot */ | 2372 | __orr32(hsotg->regs + DCTL, DCTL_PWRONPRGDONE); |
2220 | __bic32(hsotg->regs + DCTL, DCTL_PWRONPRGDONE); | 2373 | udelay(10); /* see openiboot */ |
2374 | __bic32(hsotg->regs + DCTL, DCTL_PWRONPRGDONE); | ||
2375 | } | ||
2221 | 2376 | ||
2222 | dev_dbg(hsotg->dev, "DCTL=0x%08x\n", readl(hsotg->regs + DCTL)); | 2377 | dev_dbg(hsotg->dev, "DCTL=0x%08x\n", readl(hsotg->regs + DCTL)); |
2223 | 2378 | ||
@@ -2230,13 +2385,13 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg) | |||
2230 | writel(DXEPTSIZ_MC(1) | DXEPTSIZ_PKTCNT(1) | | 2385 | writel(DXEPTSIZ_MC(1) | DXEPTSIZ_PKTCNT(1) | |
2231 | DXEPTSIZ_XFERSIZE(8), hsotg->regs + DOEPTSIZ0); | 2386 | DXEPTSIZ_XFERSIZE(8), hsotg->regs + DOEPTSIZ0); |
2232 | 2387 | ||
2233 | writel(s3c_hsotg_ep0_mps(hsotg->eps[0].ep.maxpacket) | | 2388 | writel(s3c_hsotg_ep0_mps(hsotg->eps_out[0]->ep.maxpacket) | |
2234 | DXEPCTL_CNAK | DXEPCTL_EPENA | | 2389 | DXEPCTL_CNAK | DXEPCTL_EPENA | |
2235 | DXEPCTL_USBACTEP, | 2390 | DXEPCTL_USBACTEP, |
2236 | hsotg->regs + DOEPCTL0); | 2391 | hsotg->regs + DOEPCTL0); |
2237 | 2392 | ||
2238 | /* enable, but don't activate EP0in */ | 2393 | /* enable, but don't activate EP0in */ |
2239 | writel(s3c_hsotg_ep0_mps(hsotg->eps[0].ep.maxpacket) | | 2394 | writel(s3c_hsotg_ep0_mps(hsotg->eps_out[0]->ep.maxpacket) | |
2240 | DXEPCTL_USBACTEP, hsotg->regs + DIEPCTL0); | 2395 | DXEPCTL_USBACTEP, hsotg->regs + DIEPCTL0); |
2241 | 2396 | ||
2242 | s3c_hsotg_enqueue_setup(hsotg); | 2397 | s3c_hsotg_enqueue_setup(hsotg); |
@@ -2246,8 +2401,10 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg) | |||
2246 | readl(hsotg->regs + DOEPCTL0)); | 2401 | readl(hsotg->regs + DOEPCTL0)); |
2247 | 2402 | ||
2248 | /* clear global NAKs */ | 2403 | /* clear global NAKs */ |
2249 | writel(DCTL_CGOUTNAK | DCTL_CGNPINNAK | DCTL_SFTDISCON, | 2404 | val = DCTL_CGOUTNAK | DCTL_CGNPINNAK; |
2250 | hsotg->regs + DCTL); | 2405 | if (!is_usb_reset) |
2406 | val |= DCTL_SFTDISCON; | ||
2407 | __orr32(hsotg->regs + DCTL, val); | ||
2251 | 2408 | ||
2252 | /* must be at-least 3ms to allow bus to see disconnect */ | 2409 | /* must be at-least 3ms to allow bus to see disconnect */ |
2253 | mdelay(3); | 2410 | mdelay(3); |
@@ -2293,7 +2450,6 @@ irq_retry: | |||
2293 | writel(GINTSTS_ENUMDONE, hsotg->regs + GINTSTS); | 2450 | writel(GINTSTS_ENUMDONE, hsotg->regs + GINTSTS); |
2294 | 2451 | ||
2295 | s3c_hsotg_irq_enumdone(hsotg); | 2452 | s3c_hsotg_irq_enumdone(hsotg); |
2296 | hsotg->connected = 1; | ||
2297 | } | 2453 | } |
2298 | 2454 | ||
2299 | if (gintsts & (GINTSTS_OEPINT | GINTSTS_IEPINT)) { | 2455 | if (gintsts & (GINTSTS_OEPINT | GINTSTS_IEPINT)) { |
@@ -2308,12 +2464,14 @@ irq_retry: | |||
2308 | 2464 | ||
2309 | dev_dbg(hsotg->dev, "%s: daint=%08x\n", __func__, daint); | 2465 | dev_dbg(hsotg->dev, "%s: daint=%08x\n", __func__, daint); |
2310 | 2466 | ||
2311 | for (ep = 0; ep < 15 && daint_out; ep++, daint_out >>= 1) { | 2467 | for (ep = 0; ep < hsotg->num_of_eps && daint_out; |
2468 | ep++, daint_out >>= 1) { | ||
2312 | if (daint_out & 1) | 2469 | if (daint_out & 1) |
2313 | s3c_hsotg_epint(hsotg, ep, 0); | 2470 | s3c_hsotg_epint(hsotg, ep, 0); |
2314 | } | 2471 | } |
2315 | 2472 | ||
2316 | for (ep = 0; ep < 15 && daint_in; ep++, daint_in >>= 1) { | 2473 | for (ep = 0; ep < hsotg->num_of_eps && daint_in; |
2474 | ep++, daint_in >>= 1) { | ||
2317 | if (daint_in & 1) | 2475 | if (daint_in & 1) |
2318 | s3c_hsotg_epint(hsotg, ep, 1); | 2476 | s3c_hsotg_epint(hsotg, ep, 1); |
2319 | } | 2477 | } |
@@ -2329,15 +2487,17 @@ irq_retry: | |||
2329 | 2487 | ||
2330 | writel(GINTSTS_USBRST, hsotg->regs + GINTSTS); | 2488 | writel(GINTSTS_USBRST, hsotg->regs + GINTSTS); |
2331 | 2489 | ||
2490 | /* Report disconnection if it is not already done. */ | ||
2491 | s3c_hsotg_disconnect(hsotg); | ||
2492 | |||
2332 | if (usb_status & GOTGCTL_BSESVLD) { | 2493 | if (usb_status & GOTGCTL_BSESVLD) { |
2333 | if (time_after(jiffies, hsotg->last_rst + | 2494 | if (time_after(jiffies, hsotg->last_rst + |
2334 | msecs_to_jiffies(200))) { | 2495 | msecs_to_jiffies(200))) { |
2335 | 2496 | ||
2336 | kill_all_requests(hsotg, &hsotg->eps[0], | 2497 | kill_all_requests(hsotg, hsotg->eps_out[0], |
2337 | -ECONNRESET, true); | 2498 | -ECONNRESET); |
2338 | 2499 | ||
2339 | s3c_hsotg_core_init_disconnected(hsotg); | 2500 | s3c_hsotg_core_init_disconnected(hsotg, true); |
2340 | s3c_hsotg_core_connect(hsotg); | ||
2341 | } | 2501 | } |
2342 | } | 2502 | } |
2343 | } | 2503 | } |
@@ -2429,12 +2589,12 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep, | |||
2429 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); | 2589 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); |
2430 | struct dwc2_hsotg *hsotg = hs_ep->parent; | 2590 | struct dwc2_hsotg *hsotg = hs_ep->parent; |
2431 | unsigned long flags; | 2591 | unsigned long flags; |
2432 | int index = hs_ep->index; | 2592 | unsigned int index = hs_ep->index; |
2433 | u32 epctrl_reg; | 2593 | u32 epctrl_reg; |
2434 | u32 epctrl; | 2594 | u32 epctrl; |
2435 | u32 mps; | 2595 | u32 mps; |
2436 | int dir_in; | 2596 | unsigned int dir_in; |
2437 | int i, val, size; | 2597 | unsigned int i, val, size; |
2438 | int ret = 0; | 2598 | int ret = 0; |
2439 | 2599 | ||
2440 | dev_dbg(hsotg->dev, | 2600 | dev_dbg(hsotg->dev, |
@@ -2482,7 +2642,7 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep, | |||
2482 | epctrl |= DXEPCTL_SNAK; | 2642 | epctrl |= DXEPCTL_SNAK; |
2483 | 2643 | ||
2484 | /* update the endpoint state */ | 2644 | /* update the endpoint state */ |
2485 | s3c_hsotg_set_ep_maxpacket(hsotg, hs_ep->index, mps); | 2645 | s3c_hsotg_set_ep_maxpacket(hsotg, hs_ep->index, mps, dir_in); |
2486 | 2646 | ||
2487 | /* default, set to non-periodic */ | 2647 | /* default, set to non-periodic */ |
2488 | hs_ep->isochronous = 0; | 2648 | hs_ep->isochronous = 0; |
@@ -2518,30 +2678,48 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep, | |||
2518 | break; | 2678 | break; |
2519 | } | 2679 | } |
2520 | 2680 | ||
2681 | /* If fifo is already allocated for this ep */ | ||
2682 | if (hs_ep->fifo_index) { | ||
2683 | size = hs_ep->ep.maxpacket * hs_ep->mc; | ||
2684 | /* If bigger fifo is required deallocate current one */ | ||
2685 | if (size > hs_ep->fifo_size) { | ||
2686 | hsotg->fifo_map &= ~(1 << hs_ep->fifo_index); | ||
2687 | hs_ep->fifo_index = 0; | ||
2688 | hs_ep->fifo_size = 0; | ||
2689 | } | ||
2690 | } | ||
2691 | |||
2521 | /* | 2692 | /* |
2522 | * if the hardware has dedicated fifos, we must give each IN EP | 2693 | * if the hardware has dedicated fifos, we must give each IN EP |
2523 | * a unique tx-fifo even if it is non-periodic. | 2694 | * a unique tx-fifo even if it is non-periodic. |
2524 | */ | 2695 | */ |
2525 | if (dir_in && hsotg->dedicated_fifos) { | 2696 | if (dir_in && hsotg->dedicated_fifos && !hs_ep->fifo_index) { |
2697 | u32 fifo_index = 0; | ||
2698 | u32 fifo_size = UINT_MAX; | ||
2526 | size = hs_ep->ep.maxpacket*hs_ep->mc; | 2699 | size = hs_ep->ep.maxpacket*hs_ep->mc; |
2527 | for (i = 1; i <= 8; ++i) { | 2700 | for (i = 1; i < hsotg->num_of_eps; ++i) { |
2528 | if (hsotg->fifo_map & (1<<i)) | 2701 | if (hsotg->fifo_map & (1<<i)) |
2529 | continue; | 2702 | continue; |
2530 | val = readl(hsotg->regs + DPTXFSIZN(i)); | 2703 | val = readl(hsotg->regs + DPTXFSIZN(i)); |
2531 | val = (val >> FIFOSIZE_DEPTH_SHIFT)*4; | 2704 | val = (val >> FIFOSIZE_DEPTH_SHIFT)*4; |
2532 | if (val < size) | 2705 | if (val < size) |
2533 | continue; | 2706 | continue; |
2534 | hsotg->fifo_map |= 1<<i; | 2707 | /* Search for smallest acceptable fifo */ |
2535 | 2708 | if (val < fifo_size) { | |
2536 | epctrl |= DXEPCTL_TXFNUM(i); | 2709 | fifo_size = val; |
2537 | hs_ep->fifo_index = i; | 2710 | fifo_index = i; |
2538 | hs_ep->fifo_size = val; | 2711 | } |
2539 | break; | ||
2540 | } | 2712 | } |
2541 | if (i == 8) { | 2713 | if (!fifo_index) { |
2714 | dev_err(hsotg->dev, | ||
2715 | "%s: No suitable fifo found\n", __func__); | ||
2542 | ret = -ENOMEM; | 2716 | ret = -ENOMEM; |
2543 | goto error; | 2717 | goto error; |
2544 | } | 2718 | } |
2719 | hsotg->fifo_map |= 1 << fifo_index; | ||
2720 | epctrl |= DXEPCTL_TXFNUM(fifo_index); | ||
2721 | hs_ep->fifo_index = fifo_index; | ||
2722 | hs_ep->fifo_size = fifo_size; | ||
2545 | } | 2723 | } |
2546 | 2724 | ||
2547 | /* for non control endpoints, set PID to D0 */ | 2725 | /* for non control endpoints, set PID to D0 */ |
@@ -2579,7 +2757,7 @@ static int s3c_hsotg_ep_disable_force(struct usb_ep *ep, bool force) | |||
2579 | 2757 | ||
2580 | dev_dbg(hsotg->dev, "%s(ep %p)\n", __func__, ep); | 2758 | dev_dbg(hsotg->dev, "%s(ep %p)\n", __func__, ep); |
2581 | 2759 | ||
2582 | if (ep == &hsotg->eps[0].ep) { | 2760 | if (ep == &hsotg->eps_out[0]->ep) { |
2583 | dev_err(hsotg->dev, "%s: called for ep0\n", __func__); | 2761 | dev_err(hsotg->dev, "%s: called for ep0\n", __func__); |
2584 | return -EINVAL; | 2762 | return -EINVAL; |
2585 | } | 2763 | } |
@@ -2587,8 +2765,6 @@ static int s3c_hsotg_ep_disable_force(struct usb_ep *ep, bool force) | |||
2587 | epctrl_reg = dir_in ? DIEPCTL(index) : DOEPCTL(index); | 2765 | epctrl_reg = dir_in ? DIEPCTL(index) : DOEPCTL(index); |
2588 | 2766 | ||
2589 | spin_lock_irqsave(&hsotg->lock, flags); | 2767 | spin_lock_irqsave(&hsotg->lock, flags); |
2590 | /* terminate all requests with shutdown */ | ||
2591 | kill_all_requests(hsotg, hs_ep, -ESHUTDOWN, force); | ||
2592 | 2768 | ||
2593 | hsotg->fifo_map &= ~(1<<hs_ep->fifo_index); | 2769 | hsotg->fifo_map &= ~(1<<hs_ep->fifo_index); |
2594 | hs_ep->fifo_index = 0; | 2770 | hs_ep->fifo_index = 0; |
@@ -2605,6 +2781,9 @@ static int s3c_hsotg_ep_disable_force(struct usb_ep *ep, bool force) | |||
2605 | /* disable endpoint interrupts */ | 2781 | /* disable endpoint interrupts */ |
2606 | s3c_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 0); | 2782 | s3c_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 0); |
2607 | 2783 | ||
2784 | /* terminate all requests with shutdown */ | ||
2785 | kill_all_requests(hsotg, hs_ep, -ESHUTDOWN); | ||
2786 | |||
2608 | spin_unlock_irqrestore(&hsotg->lock, flags); | 2787 | spin_unlock_irqrestore(&hsotg->lock, flags); |
2609 | return 0; | 2788 | return 0; |
2610 | } | 2789 | } |
@@ -2682,40 +2861,39 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value) | |||
2682 | return 0; | 2861 | return 0; |
2683 | } | 2862 | } |
2684 | 2863 | ||
2685 | /* write both IN and OUT control registers */ | 2864 | if (hs_ep->dir_in) { |
2686 | 2865 | epreg = DIEPCTL(index); | |
2687 | epreg = DIEPCTL(index); | 2866 | epctl = readl(hs->regs + epreg); |
2688 | epctl = readl(hs->regs + epreg); | 2867 | |
2689 | 2868 | if (value) { | |
2690 | if (value) { | 2869 | epctl |= DXEPCTL_STALL + DXEPCTL_SNAK; |
2691 | epctl |= DXEPCTL_STALL + DXEPCTL_SNAK; | 2870 | if (epctl & DXEPCTL_EPENA) |
2692 | if (epctl & DXEPCTL_EPENA) | 2871 | epctl |= DXEPCTL_EPDIS; |
2693 | epctl |= DXEPCTL_EPDIS; | 2872 | } else { |
2873 | epctl &= ~DXEPCTL_STALL; | ||
2874 | xfertype = epctl & DXEPCTL_EPTYPE_MASK; | ||
2875 | if (xfertype == DXEPCTL_EPTYPE_BULK || | ||
2876 | xfertype == DXEPCTL_EPTYPE_INTERRUPT) | ||
2877 | epctl |= DXEPCTL_SETD0PID; | ||
2878 | } | ||
2879 | writel(epctl, hs->regs + epreg); | ||
2694 | } else { | 2880 | } else { |
2695 | epctl &= ~DXEPCTL_STALL; | ||
2696 | xfertype = epctl & DXEPCTL_EPTYPE_MASK; | ||
2697 | if (xfertype == DXEPCTL_EPTYPE_BULK || | ||
2698 | xfertype == DXEPCTL_EPTYPE_INTERRUPT) | ||
2699 | epctl |= DXEPCTL_SETD0PID; | ||
2700 | } | ||
2701 | |||
2702 | writel(epctl, hs->regs + epreg); | ||
2703 | 2881 | ||
2704 | epreg = DOEPCTL(index); | 2882 | epreg = DOEPCTL(index); |
2705 | epctl = readl(hs->regs + epreg); | 2883 | epctl = readl(hs->regs + epreg); |
2706 | 2884 | ||
2707 | if (value) | 2885 | if (value) |
2708 | epctl |= DXEPCTL_STALL; | 2886 | epctl |= DXEPCTL_STALL; |
2709 | else { | 2887 | else { |
2710 | epctl &= ~DXEPCTL_STALL; | 2888 | epctl &= ~DXEPCTL_STALL; |
2711 | xfertype = epctl & DXEPCTL_EPTYPE_MASK; | 2889 | xfertype = epctl & DXEPCTL_EPTYPE_MASK; |
2712 | if (xfertype == DXEPCTL_EPTYPE_BULK || | 2890 | if (xfertype == DXEPCTL_EPTYPE_BULK || |
2713 | xfertype == DXEPCTL_EPTYPE_INTERRUPT) | 2891 | xfertype == DXEPCTL_EPTYPE_INTERRUPT) |
2714 | epctl |= DXEPCTL_SETD0PID; | 2892 | epctl |= DXEPCTL_SETD0PID; |
2893 | } | ||
2894 | writel(epctl, hs->regs + epreg); | ||
2715 | } | 2895 | } |
2716 | 2896 | ||
2717 | writel(epctl, hs->regs + epreg); | ||
2718 | |||
2719 | hs_ep->halted = value; | 2897 | hs_ep->halted = value; |
2720 | 2898 | ||
2721 | return 0; | 2899 | return 0; |
@@ -2801,6 +2979,7 @@ static void s3c_hsotg_phy_disable(struct dwc2_hsotg *hsotg) | |||
2801 | */ | 2979 | */ |
2802 | static void s3c_hsotg_init(struct dwc2_hsotg *hsotg) | 2980 | static void s3c_hsotg_init(struct dwc2_hsotg *hsotg) |
2803 | { | 2981 | { |
2982 | u32 trdtim; | ||
2804 | /* unmask subset of endpoint interrupts */ | 2983 | /* unmask subset of endpoint interrupts */ |
2805 | 2984 | ||
2806 | writel(DIEPMSK_TIMEOUTMSK | DIEPMSK_AHBERRMSK | | 2985 | writel(DIEPMSK_TIMEOUTMSK | DIEPMSK_AHBERRMSK | |
@@ -2816,12 +2995,6 @@ static void s3c_hsotg_init(struct dwc2_hsotg *hsotg) | |||
2816 | /* Be in disconnected state until gadget is registered */ | 2995 | /* Be in disconnected state until gadget is registered */ |
2817 | __orr32(hsotg->regs + DCTL, DCTL_SFTDISCON); | 2996 | __orr32(hsotg->regs + DCTL, DCTL_SFTDISCON); |
2818 | 2997 | ||
2819 | if (0) { | ||
2820 | /* post global nak until we're ready */ | ||
2821 | writel(DCTL_SGNPINNAK | DCTL_SGOUTNAK, | ||
2822 | hsotg->regs + DCTL); | ||
2823 | } | ||
2824 | |||
2825 | /* setup fifos */ | 2998 | /* setup fifos */ |
2826 | 2999 | ||
2827 | dev_dbg(hsotg->dev, "GRXFSIZ=0x%08x, GNPTXFSIZ=0x%08x\n", | 3000 | dev_dbg(hsotg->dev, "GRXFSIZ=0x%08x, GNPTXFSIZ=0x%08x\n", |
@@ -2831,11 +3004,13 @@ static void s3c_hsotg_init(struct dwc2_hsotg *hsotg) | |||
2831 | s3c_hsotg_init_fifo(hsotg); | 3004 | s3c_hsotg_init_fifo(hsotg); |
2832 | 3005 | ||
2833 | /* set the PLL on, remove the HNP/SRP and set the PHY */ | 3006 | /* set the PLL on, remove the HNP/SRP and set the PHY */ |
2834 | writel(GUSBCFG_PHYIF16 | GUSBCFG_TOUTCAL(7) | (0x5 << 10), | 3007 | trdtim = (hsotg->phyif == GUSBCFG_PHYIF8) ? 9 : 5; |
2835 | hsotg->regs + GUSBCFG); | 3008 | writel(hsotg->phyif | GUSBCFG_TOUTCAL(7) | |
3009 | (trdtim << GUSBCFG_USBTRDTIM_SHIFT), | ||
3010 | hsotg->regs + GUSBCFG); | ||
2836 | 3011 | ||
2837 | writel(using_dma(hsotg) ? GAHBCFG_DMA_EN : 0x0, | 3012 | if (using_dma(hsotg)) |
2838 | hsotg->regs + GAHBCFG); | 3013 | __orr32(hsotg->regs + GAHBCFG, GAHBCFG_DMA_EN); |
2839 | } | 3014 | } |
2840 | 3015 | ||
2841 | /** | 3016 | /** |
@@ -2889,10 +3064,12 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget, | |||
2889 | } | 3064 | } |
2890 | 3065 | ||
2891 | s3c_hsotg_phy_enable(hsotg); | 3066 | s3c_hsotg_phy_enable(hsotg); |
3067 | if (!IS_ERR_OR_NULL(hsotg->uphy)) | ||
3068 | otg_set_peripheral(hsotg->uphy->otg, &hsotg->gadget); | ||
2892 | 3069 | ||
2893 | spin_lock_irqsave(&hsotg->lock, flags); | 3070 | spin_lock_irqsave(&hsotg->lock, flags); |
2894 | s3c_hsotg_init(hsotg); | 3071 | s3c_hsotg_init(hsotg); |
2895 | s3c_hsotg_core_init_disconnected(hsotg); | 3072 | s3c_hsotg_core_init_disconnected(hsotg, false); |
2896 | hsotg->enabled = 0; | 3073 | hsotg->enabled = 0; |
2897 | spin_unlock_irqrestore(&hsotg->lock, flags); | 3074 | spin_unlock_irqrestore(&hsotg->lock, flags); |
2898 | 3075 | ||
@@ -2927,8 +3104,12 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget) | |||
2927 | mutex_lock(&hsotg->init_mutex); | 3104 | mutex_lock(&hsotg->init_mutex); |
2928 | 3105 | ||
2929 | /* all endpoints should be shutdown */ | 3106 | /* all endpoints should be shutdown */ |
2930 | for (ep = 1; ep < hsotg->num_of_eps; ep++) | 3107 | for (ep = 1; ep < hsotg->num_of_eps; ep++) { |
2931 | s3c_hsotg_ep_disable_force(&hsotg->eps[ep].ep, true); | 3108 | if (hsotg->eps_in[ep]) |
3109 | s3c_hsotg_ep_disable(&hsotg->eps_in[ep]->ep); | ||
3110 | if (hsotg->eps_out[ep]) | ||
3111 | s3c_hsotg_ep_disable(&hsotg->eps_out[ep]->ep); | ||
3112 | } | ||
2932 | 3113 | ||
2933 | spin_lock_irqsave(&hsotg->lock, flags); | 3114 | spin_lock_irqsave(&hsotg->lock, flags); |
2934 | 3115 | ||
@@ -2938,6 +3119,8 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget) | |||
2938 | 3119 | ||
2939 | spin_unlock_irqrestore(&hsotg->lock, flags); | 3120 | spin_unlock_irqrestore(&hsotg->lock, flags); |
2940 | 3121 | ||
3122 | if (!IS_ERR_OR_NULL(hsotg->uphy)) | ||
3123 | otg_set_peripheral(hsotg->uphy->otg, NULL); | ||
2941 | s3c_hsotg_phy_disable(hsotg); | 3124 | s3c_hsotg_phy_disable(hsotg); |
2942 | 3125 | ||
2943 | regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); | 3126 | regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); |
@@ -2979,9 +3162,11 @@ static int s3c_hsotg_pullup(struct usb_gadget *gadget, int is_on) | |||
2979 | if (is_on) { | 3162 | if (is_on) { |
2980 | clk_enable(hsotg->clk); | 3163 | clk_enable(hsotg->clk); |
2981 | hsotg->enabled = 1; | 3164 | hsotg->enabled = 1; |
3165 | s3c_hsotg_core_init_disconnected(hsotg, false); | ||
2982 | s3c_hsotg_core_connect(hsotg); | 3166 | s3c_hsotg_core_connect(hsotg); |
2983 | } else { | 3167 | } else { |
2984 | s3c_hsotg_core_disconnect(hsotg); | 3168 | s3c_hsotg_core_disconnect(hsotg); |
3169 | s3c_hsotg_disconnect(hsotg); | ||
2985 | hsotg->enabled = 0; | 3170 | hsotg->enabled = 0; |
2986 | clk_disable(hsotg->clk); | 3171 | clk_disable(hsotg->clk); |
2987 | } | 3172 | } |
@@ -2993,11 +3178,52 @@ static int s3c_hsotg_pullup(struct usb_gadget *gadget, int is_on) | |||
2993 | return 0; | 3178 | return 0; |
2994 | } | 3179 | } |
2995 | 3180 | ||
3181 | static int s3c_hsotg_vbus_session(struct usb_gadget *gadget, int is_active) | ||
3182 | { | ||
3183 | struct dwc2_hsotg *hsotg = to_hsotg(gadget); | ||
3184 | unsigned long flags; | ||
3185 | |||
3186 | dev_dbg(hsotg->dev, "%s: is_active: %d\n", __func__, is_active); | ||
3187 | spin_lock_irqsave(&hsotg->lock, flags); | ||
3188 | |||
3189 | if (is_active) { | ||
3190 | /* Kill any ep0 requests as controller will be reinitialized */ | ||
3191 | kill_all_requests(hsotg, hsotg->eps_out[0], -ECONNRESET); | ||
3192 | s3c_hsotg_core_init_disconnected(hsotg, false); | ||
3193 | if (hsotg->enabled) | ||
3194 | s3c_hsotg_core_connect(hsotg); | ||
3195 | } else { | ||
3196 | s3c_hsotg_core_disconnect(hsotg); | ||
3197 | s3c_hsotg_disconnect(hsotg); | ||
3198 | } | ||
3199 | |||
3200 | spin_unlock_irqrestore(&hsotg->lock, flags); | ||
3201 | return 0; | ||
3202 | } | ||
3203 | |||
3204 | /** | ||
3205 | * s3c_hsotg_vbus_draw - report bMaxPower field | ||
3206 | * @gadget: The usb gadget state | ||
3207 | * @mA: Amount of current | ||
3208 | * | ||
3209 | * Report how much power the device may consume to the phy. | ||
3210 | */ | ||
3211 | static int s3c_hsotg_vbus_draw(struct usb_gadget *gadget, unsigned mA) | ||
3212 | { | ||
3213 | struct dwc2_hsotg *hsotg = to_hsotg(gadget); | ||
3214 | |||
3215 | if (IS_ERR_OR_NULL(hsotg->uphy)) | ||
3216 | return -ENOTSUPP; | ||
3217 | return usb_phy_set_power(hsotg->uphy, mA); | ||
3218 | } | ||
3219 | |||
2996 | static const struct usb_gadget_ops s3c_hsotg_gadget_ops = { | 3220 | static const struct usb_gadget_ops s3c_hsotg_gadget_ops = { |
2997 | .get_frame = s3c_hsotg_gadget_getframe, | 3221 | .get_frame = s3c_hsotg_gadget_getframe, |
2998 | .udc_start = s3c_hsotg_udc_start, | 3222 | .udc_start = s3c_hsotg_udc_start, |
2999 | .udc_stop = s3c_hsotg_udc_stop, | 3223 | .udc_stop = s3c_hsotg_udc_stop, |
3000 | .pullup = s3c_hsotg_pullup, | 3224 | .pullup = s3c_hsotg_pullup, |
3225 | .vbus_session = s3c_hsotg_vbus_session, | ||
3226 | .vbus_draw = s3c_hsotg_vbus_draw, | ||
3001 | }; | 3227 | }; |
3002 | 3228 | ||
3003 | /** | 3229 | /** |
@@ -3012,19 +3238,19 @@ static const struct usb_gadget_ops s3c_hsotg_gadget_ops = { | |||
3012 | */ | 3238 | */ |
3013 | static void s3c_hsotg_initep(struct dwc2_hsotg *hsotg, | 3239 | static void s3c_hsotg_initep(struct dwc2_hsotg *hsotg, |
3014 | struct s3c_hsotg_ep *hs_ep, | 3240 | struct s3c_hsotg_ep *hs_ep, |
3015 | int epnum) | 3241 | int epnum, |
3242 | bool dir_in) | ||
3016 | { | 3243 | { |
3017 | char *dir; | 3244 | char *dir; |
3018 | 3245 | ||
3019 | if (epnum == 0) | 3246 | if (epnum == 0) |
3020 | dir = ""; | 3247 | dir = ""; |
3021 | else if ((epnum % 2) == 0) { | 3248 | else if (dir_in) |
3022 | dir = "out"; | ||
3023 | } else { | ||
3024 | dir = "in"; | 3249 | dir = "in"; |
3025 | hs_ep->dir_in = 1; | 3250 | else |
3026 | } | 3251 | dir = "out"; |
3027 | 3252 | ||
3253 | hs_ep->dir_in = dir_in; | ||
3028 | hs_ep->index = epnum; | 3254 | hs_ep->index = epnum; |
3029 | 3255 | ||
3030 | snprintf(hs_ep->name, sizeof(hs_ep->name), "ep%d%s", epnum, dir); | 3256 | snprintf(hs_ep->name, sizeof(hs_ep->name), "ep%d%s", epnum, dir); |
@@ -3048,8 +3274,10 @@ static void s3c_hsotg_initep(struct dwc2_hsotg *hsotg, | |||
3048 | 3274 | ||
3049 | if (using_dma(hsotg)) { | 3275 | if (using_dma(hsotg)) { |
3050 | u32 next = DXEPCTL_NEXTEP((epnum + 1) % 15); | 3276 | u32 next = DXEPCTL_NEXTEP((epnum + 1) % 15); |
3051 | writel(next, hsotg->regs + DIEPCTL(epnum)); | 3277 | if (dir_in) |
3052 | writel(next, hsotg->regs + DOEPCTL(epnum)); | 3278 | writel(next, hsotg->regs + DIEPCTL(epnum)); |
3279 | else | ||
3280 | writel(next, hsotg->regs + DOEPCTL(epnum)); | ||
3053 | } | 3281 | } |
3054 | } | 3282 | } |
3055 | 3283 | ||
@@ -3059,24 +3287,56 @@ static void s3c_hsotg_initep(struct dwc2_hsotg *hsotg, | |||
3059 | * | 3287 | * |
3060 | * Read the USB core HW configuration registers | 3288 | * Read the USB core HW configuration registers |
3061 | */ | 3289 | */ |
3062 | static void s3c_hsotg_hw_cfg(struct dwc2_hsotg *hsotg) | 3290 | static int s3c_hsotg_hw_cfg(struct dwc2_hsotg *hsotg) |
3063 | { | 3291 | { |
3064 | u32 cfg2, cfg3, cfg4; | 3292 | u32 cfg; |
3293 | u32 ep_type; | ||
3294 | u32 i; | ||
3295 | |||
3065 | /* check hardware configuration */ | 3296 | /* check hardware configuration */ |
3066 | 3297 | ||
3067 | cfg2 = readl(hsotg->regs + 0x48); | 3298 | cfg = readl(hsotg->regs + GHWCFG2); |
3068 | hsotg->num_of_eps = (cfg2 >> 10) & 0xF; | 3299 | hsotg->num_of_eps = (cfg >> GHWCFG2_NUM_DEV_EP_SHIFT) & 0xF; |
3300 | /* Add ep0 */ | ||
3301 | hsotg->num_of_eps++; | ||
3302 | |||
3303 | hsotg->eps_in[0] = devm_kzalloc(hsotg->dev, sizeof(struct s3c_hsotg_ep), | ||
3304 | GFP_KERNEL); | ||
3305 | if (!hsotg->eps_in[0]) | ||
3306 | return -ENOMEM; | ||
3307 | /* Same s3c_hsotg_ep is used in both directions for ep0 */ | ||
3308 | hsotg->eps_out[0] = hsotg->eps_in[0]; | ||
3309 | |||
3310 | cfg = readl(hsotg->regs + GHWCFG1); | ||
3311 | for (i = 1, cfg >>= 2; i < hsotg->num_of_eps; i++, cfg >>= 2) { | ||
3312 | ep_type = cfg & 3; | ||
3313 | /* Direction in or both */ | ||
3314 | if (!(ep_type & 2)) { | ||
3315 | hsotg->eps_in[i] = devm_kzalloc(hsotg->dev, | ||
3316 | sizeof(struct s3c_hsotg_ep), GFP_KERNEL); | ||
3317 | if (!hsotg->eps_in[i]) | ||
3318 | return -ENOMEM; | ||
3319 | } | ||
3320 | /* Direction out or both */ | ||
3321 | if (!(ep_type & 1)) { | ||
3322 | hsotg->eps_out[i] = devm_kzalloc(hsotg->dev, | ||
3323 | sizeof(struct s3c_hsotg_ep), GFP_KERNEL); | ||
3324 | if (!hsotg->eps_out[i]) | ||
3325 | return -ENOMEM; | ||
3326 | } | ||
3327 | } | ||
3069 | 3328 | ||
3070 | cfg3 = readl(hsotg->regs + 0x4C); | 3329 | cfg = readl(hsotg->regs + GHWCFG3); |
3071 | hsotg->fifo_mem = (cfg3 >> 16); | 3330 | hsotg->fifo_mem = (cfg >> GHWCFG3_DFIFO_DEPTH_SHIFT); |
3072 | 3331 | ||
3073 | cfg4 = readl(hsotg->regs + 0x50); | 3332 | cfg = readl(hsotg->regs + GHWCFG4); |
3074 | hsotg->dedicated_fifos = (cfg4 >> 25) & 1; | 3333 | hsotg->dedicated_fifos = (cfg >> GHWCFG4_DED_FIFO_SHIFT) & 1; |
3075 | 3334 | ||
3076 | dev_info(hsotg->dev, "EPs: %d, %s fifos, %d entries in SPRAM\n", | 3335 | dev_info(hsotg->dev, "EPs: %d, %s fifos, %d entries in SPRAM\n", |
3077 | hsotg->num_of_eps, | 3336 | hsotg->num_of_eps, |
3078 | hsotg->dedicated_fifos ? "dedicated" : "shared", | 3337 | hsotg->dedicated_fifos ? "dedicated" : "shared", |
3079 | hsotg->fifo_mem); | 3338 | hsotg->fifo_mem); |
3339 | return 0; | ||
3080 | } | 3340 | } |
3081 | 3341 | ||
3082 | /** | 3342 | /** |
@@ -3095,22 +3355,22 @@ static void s3c_hsotg_dump(struct dwc2_hsotg *hsotg) | |||
3095 | readl(regs + DCFG), readl(regs + DCTL), | 3355 | readl(regs + DCFG), readl(regs + DCTL), |
3096 | readl(regs + DIEPMSK)); | 3356 | readl(regs + DIEPMSK)); |
3097 | 3357 | ||
3098 | dev_info(dev, "GAHBCFG=0x%08x, 0x44=0x%08x\n", | 3358 | dev_info(dev, "GAHBCFG=0x%08x, GHWCFG1=0x%08x\n", |
3099 | readl(regs + GAHBCFG), readl(regs + 0x44)); | 3359 | readl(regs + GAHBCFG), readl(regs + GHWCFG1)); |
3100 | 3360 | ||
3101 | dev_info(dev, "GRXFSIZ=0x%08x, GNPTXFSIZ=0x%08x\n", | 3361 | dev_info(dev, "GRXFSIZ=0x%08x, GNPTXFSIZ=0x%08x\n", |
3102 | readl(regs + GRXFSIZ), readl(regs + GNPTXFSIZ)); | 3362 | readl(regs + GRXFSIZ), readl(regs + GNPTXFSIZ)); |
3103 | 3363 | ||
3104 | /* show periodic fifo settings */ | 3364 | /* show periodic fifo settings */ |
3105 | 3365 | ||
3106 | for (idx = 1; idx <= 15; idx++) { | 3366 | for (idx = 1; idx < hsotg->num_of_eps; idx++) { |
3107 | val = readl(regs + DPTXFSIZN(idx)); | 3367 | val = readl(regs + DPTXFSIZN(idx)); |
3108 | dev_info(dev, "DPTx[%d] FSize=%d, StAddr=0x%08x\n", idx, | 3368 | dev_info(dev, "DPTx[%d] FSize=%d, StAddr=0x%08x\n", idx, |
3109 | val >> FIFOSIZE_DEPTH_SHIFT, | 3369 | val >> FIFOSIZE_DEPTH_SHIFT, |
3110 | val & FIFOSIZE_STARTADDR_MASK); | 3370 | val & FIFOSIZE_STARTADDR_MASK); |
3111 | } | 3371 | } |
3112 | 3372 | ||
3113 | for (idx = 0; idx < 15; idx++) { | 3373 | for (idx = 0; idx < hsotg->num_of_eps; idx++) { |
3114 | dev_info(dev, | 3374 | dev_info(dev, |
3115 | "ep%d-in: EPCTL=0x%08x, SIZ=0x%08x, DMA=0x%08x\n", idx, | 3375 | "ep%d-in: EPCTL=0x%08x, SIZ=0x%08x, DMA=0x%08x\n", idx, |
3116 | readl(regs + DIEPCTL(idx)), | 3376 | readl(regs + DIEPCTL(idx)), |
@@ -3132,6 +3392,103 @@ static void s3c_hsotg_dump(struct dwc2_hsotg *hsotg) | |||
3132 | } | 3392 | } |
3133 | 3393 | ||
3134 | /** | 3394 | /** |
3395 | * testmode_write - debugfs: change usb test mode | ||
3396 | * @seq: The seq file to write to. | ||
3397 | * @v: Unused parameter. | ||
3398 | * | ||
3399 | * This debugfs entry modify the current usb test mode. | ||
3400 | */ | ||
3401 | static ssize_t testmode_write(struct file *file, const char __user *ubuf, size_t | ||
3402 | count, loff_t *ppos) | ||
3403 | { | ||
3404 | struct seq_file *s = file->private_data; | ||
3405 | struct dwc2_hsotg *hsotg = s->private; | ||
3406 | unsigned long flags; | ||
3407 | u32 testmode = 0; | ||
3408 | char buf[32]; | ||
3409 | |||
3410 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) | ||
3411 | return -EFAULT; | ||
3412 | |||
3413 | if (!strncmp(buf, "test_j", 6)) | ||
3414 | testmode = TEST_J; | ||
3415 | else if (!strncmp(buf, "test_k", 6)) | ||
3416 | testmode = TEST_K; | ||
3417 | else if (!strncmp(buf, "test_se0_nak", 12)) | ||
3418 | testmode = TEST_SE0_NAK; | ||
3419 | else if (!strncmp(buf, "test_packet", 11)) | ||
3420 | testmode = TEST_PACKET; | ||
3421 | else if (!strncmp(buf, "test_force_enable", 17)) | ||
3422 | testmode = TEST_FORCE_EN; | ||
3423 | else | ||
3424 | testmode = 0; | ||
3425 | |||
3426 | spin_lock_irqsave(&hsotg->lock, flags); | ||
3427 | s3c_hsotg_set_test_mode(hsotg, testmode); | ||
3428 | spin_unlock_irqrestore(&hsotg->lock, flags); | ||
3429 | return count; | ||
3430 | } | ||
3431 | |||
3432 | /** | ||
3433 | * testmode_show - debugfs: show usb test mode state | ||
3434 | * @seq: The seq file to write to. | ||
3435 | * @v: Unused parameter. | ||
3436 | * | ||
3437 | * This debugfs entry shows which usb test mode is currently enabled. | ||
3438 | */ | ||
3439 | static int testmode_show(struct seq_file *s, void *unused) | ||
3440 | { | ||
3441 | struct dwc2_hsotg *hsotg = s->private; | ||
3442 | unsigned long flags; | ||
3443 | int dctl; | ||
3444 | |||
3445 | spin_lock_irqsave(&hsotg->lock, flags); | ||
3446 | dctl = readl(hsotg->regs + DCTL); | ||
3447 | dctl &= DCTL_TSTCTL_MASK; | ||
3448 | dctl >>= DCTL_TSTCTL_SHIFT; | ||
3449 | spin_unlock_irqrestore(&hsotg->lock, flags); | ||
3450 | |||
3451 | switch (dctl) { | ||
3452 | case 0: | ||
3453 | seq_puts(s, "no test\n"); | ||
3454 | break; | ||
3455 | case TEST_J: | ||
3456 | seq_puts(s, "test_j\n"); | ||
3457 | break; | ||
3458 | case TEST_K: | ||
3459 | seq_puts(s, "test_k\n"); | ||
3460 | break; | ||
3461 | case TEST_SE0_NAK: | ||
3462 | seq_puts(s, "test_se0_nak\n"); | ||
3463 | break; | ||
3464 | case TEST_PACKET: | ||
3465 | seq_puts(s, "test_packet\n"); | ||
3466 | break; | ||
3467 | case TEST_FORCE_EN: | ||
3468 | seq_puts(s, "test_force_enable\n"); | ||
3469 | break; | ||
3470 | default: | ||
3471 | seq_printf(s, "UNKNOWN %d\n", dctl); | ||
3472 | } | ||
3473 | |||
3474 | return 0; | ||
3475 | } | ||
3476 | |||
3477 | static int testmode_open(struct inode *inode, struct file *file) | ||
3478 | { | ||
3479 | return single_open(file, testmode_show, inode->i_private); | ||
3480 | } | ||
3481 | |||
3482 | static const struct file_operations testmode_fops = { | ||
3483 | .owner = THIS_MODULE, | ||
3484 | .open = testmode_open, | ||
3485 | .write = testmode_write, | ||
3486 | .read = seq_read, | ||
3487 | .llseek = seq_lseek, | ||
3488 | .release = single_release, | ||
3489 | }; | ||
3490 | |||
3491 | /** | ||
3135 | * state_show - debugfs: show overall driver and device state. | 3492 | * state_show - debugfs: show overall driver and device state. |
3136 | * @seq: The seq file to write to. | 3493 | * @seq: The seq file to write to. |
3137 | * @v: Unused parameter. | 3494 | * @v: Unused parameter. |
@@ -3168,7 +3525,7 @@ static int state_show(struct seq_file *seq, void *v) | |||
3168 | 3525 | ||
3169 | seq_puts(seq, "\nEndpoint status:\n"); | 3526 | seq_puts(seq, "\nEndpoint status:\n"); |
3170 | 3527 | ||
3171 | for (idx = 0; idx < 15; idx++) { | 3528 | for (idx = 0; idx < hsotg->num_of_eps; idx++) { |
3172 | u32 in, out; | 3529 | u32 in, out; |
3173 | 3530 | ||
3174 | in = readl(regs + DIEPCTL(idx)); | 3531 | in = readl(regs + DIEPCTL(idx)); |
@@ -3227,7 +3584,7 @@ static int fifo_show(struct seq_file *seq, void *v) | |||
3227 | 3584 | ||
3228 | seq_puts(seq, "\nPeriodic TXFIFOs:\n"); | 3585 | seq_puts(seq, "\nPeriodic TXFIFOs:\n"); |
3229 | 3586 | ||
3230 | for (idx = 1; idx <= 15; idx++) { | 3587 | for (idx = 1; idx < hsotg->num_of_eps; idx++) { |
3231 | val = readl(regs + DPTXFSIZN(idx)); | 3588 | val = readl(regs + DPTXFSIZN(idx)); |
3232 | 3589 | ||
3233 | seq_printf(seq, "\tDPTXFIFO%2d: Size %d, Start 0x%08x\n", idx, | 3590 | seq_printf(seq, "\tDPTXFIFO%2d: Size %d, Start 0x%08x\n", idx, |
@@ -3359,29 +3716,53 @@ static void s3c_hsotg_create_debug(struct dwc2_hsotg *hsotg) | |||
3359 | 3716 | ||
3360 | /* create general state file */ | 3717 | /* create general state file */ |
3361 | 3718 | ||
3362 | hsotg->debug_file = debugfs_create_file("state", 0444, root, | 3719 | hsotg->debug_file = debugfs_create_file("state", S_IRUGO, root, |
3363 | hsotg, &state_fops); | 3720 | hsotg, &state_fops); |
3364 | 3721 | ||
3365 | if (IS_ERR(hsotg->debug_file)) | 3722 | if (IS_ERR(hsotg->debug_file)) |
3366 | dev_err(hsotg->dev, "%s: failed to create state\n", __func__); | 3723 | dev_err(hsotg->dev, "%s: failed to create state\n", __func__); |
3367 | 3724 | ||
3368 | hsotg->debug_fifo = debugfs_create_file("fifo", 0444, root, | 3725 | hsotg->debug_testmode = debugfs_create_file("testmode", |
3726 | S_IRUGO | S_IWUSR, root, | ||
3727 | hsotg, &testmode_fops); | ||
3728 | |||
3729 | if (IS_ERR(hsotg->debug_testmode)) | ||
3730 | dev_err(hsotg->dev, "%s: failed to create testmode\n", | ||
3731 | __func__); | ||
3732 | |||
3733 | hsotg->debug_fifo = debugfs_create_file("fifo", S_IRUGO, root, | ||
3369 | hsotg, &fifo_fops); | 3734 | hsotg, &fifo_fops); |
3370 | 3735 | ||
3371 | if (IS_ERR(hsotg->debug_fifo)) | 3736 | if (IS_ERR(hsotg->debug_fifo)) |
3372 | dev_err(hsotg->dev, "%s: failed to create fifo\n", __func__); | 3737 | dev_err(hsotg->dev, "%s: failed to create fifo\n", __func__); |
3373 | 3738 | ||
3374 | /* create one file for each endpoint */ | 3739 | /* Create one file for each out endpoint */ |
3375 | |||
3376 | for (epidx = 0; epidx < hsotg->num_of_eps; epidx++) { | 3740 | for (epidx = 0; epidx < hsotg->num_of_eps; epidx++) { |
3377 | struct s3c_hsotg_ep *ep = &hsotg->eps[epidx]; | 3741 | struct s3c_hsotg_ep *ep; |
3378 | 3742 | ||
3379 | ep->debugfs = debugfs_create_file(ep->name, 0444, | 3743 | ep = hsotg->eps_out[epidx]; |
3380 | root, ep, &ep_fops); | 3744 | if (ep) { |
3745 | ep->debugfs = debugfs_create_file(ep->name, S_IRUGO, | ||
3746 | root, ep, &ep_fops); | ||
3381 | 3747 | ||
3382 | if (IS_ERR(ep->debugfs)) | 3748 | if (IS_ERR(ep->debugfs)) |
3383 | dev_err(hsotg->dev, "failed to create %s debug file\n", | 3749 | dev_err(hsotg->dev, "failed to create %s debug file\n", |
3384 | ep->name); | 3750 | ep->name); |
3751 | } | ||
3752 | } | ||
3753 | /* Create one file for each in endpoint. EP0 is handled with out eps */ | ||
3754 | for (epidx = 1; epidx < hsotg->num_of_eps; epidx++) { | ||
3755 | struct s3c_hsotg_ep *ep; | ||
3756 | |||
3757 | ep = hsotg->eps_in[epidx]; | ||
3758 | if (ep) { | ||
3759 | ep->debugfs = debugfs_create_file(ep->name, S_IRUGO, | ||
3760 | root, ep, &ep_fops); | ||
3761 | |||
3762 | if (IS_ERR(ep->debugfs)) | ||
3763 | dev_err(hsotg->dev, "failed to create %s debug file\n", | ||
3764 | ep->name); | ||
3765 | } | ||
3385 | } | 3766 | } |
3386 | } | 3767 | } |
3387 | 3768 | ||
@@ -3396,15 +3777,63 @@ static void s3c_hsotg_delete_debug(struct dwc2_hsotg *hsotg) | |||
3396 | unsigned epidx; | 3777 | unsigned epidx; |
3397 | 3778 | ||
3398 | for (epidx = 0; epidx < hsotg->num_of_eps; epidx++) { | 3779 | for (epidx = 0; epidx < hsotg->num_of_eps; epidx++) { |
3399 | struct s3c_hsotg_ep *ep = &hsotg->eps[epidx]; | 3780 | if (hsotg->eps_in[epidx]) |
3400 | debugfs_remove(ep->debugfs); | 3781 | debugfs_remove(hsotg->eps_in[epidx]->debugfs); |
3782 | if (hsotg->eps_out[epidx]) | ||
3783 | debugfs_remove(hsotg->eps_out[epidx]->debugfs); | ||
3401 | } | 3784 | } |
3402 | 3785 | ||
3403 | debugfs_remove(hsotg->debug_file); | 3786 | debugfs_remove(hsotg->debug_file); |
3787 | debugfs_remove(hsotg->debug_testmode); | ||
3404 | debugfs_remove(hsotg->debug_fifo); | 3788 | debugfs_remove(hsotg->debug_fifo); |
3405 | debugfs_remove(hsotg->debug_root); | 3789 | debugfs_remove(hsotg->debug_root); |
3406 | } | 3790 | } |
3407 | 3791 | ||
3792 | #ifdef CONFIG_OF | ||
3793 | static void s3c_hsotg_of_probe(struct dwc2_hsotg *hsotg) | ||
3794 | { | ||
3795 | struct device_node *np = hsotg->dev->of_node; | ||
3796 | u32 len = 0; | ||
3797 | u32 i = 0; | ||
3798 | |||
3799 | /* Enable dma if requested in device tree */ | ||
3800 | hsotg->g_using_dma = of_property_read_bool(np, "g-use-dma"); | ||
3801 | |||
3802 | /* | ||
3803 | * Register TX periodic fifo size per endpoint. | ||
3804 | * EP0 is excluded since it has no fifo configuration. | ||
3805 | */ | ||
3806 | if (!of_find_property(np, "g-tx-fifo-size", &len)) | ||
3807 | goto rx_fifo; | ||
3808 | |||
3809 | len /= sizeof(u32); | ||
3810 | |||
3811 | /* Read tx fifo sizes other than ep0 */ | ||
3812 | if (of_property_read_u32_array(np, "g-tx-fifo-size", | ||
3813 | &hsotg->g_tx_fifo_sz[1], len)) | ||
3814 | goto rx_fifo; | ||
3815 | |||
3816 | /* Add ep0 */ | ||
3817 | len++; | ||
3818 | |||
3819 | /* Make remaining TX fifos unavailable */ | ||
3820 | if (len < MAX_EPS_CHANNELS) { | ||
3821 | for (i = len; i < MAX_EPS_CHANNELS; i++) | ||
3822 | hsotg->g_tx_fifo_sz[i] = 0; | ||
3823 | } | ||
3824 | |||
3825 | rx_fifo: | ||
3826 | /* Register RX fifo size */ | ||
3827 | of_property_read_u32(np, "g-rx-fifo-size", &hsotg->g_rx_fifo_sz); | ||
3828 | |||
3829 | /* Register NPTX fifo size */ | ||
3830 | of_property_read_u32(np, "g-np-tx-fifo-size", | ||
3831 | &hsotg->g_np_g_tx_fifo_sz); | ||
3832 | } | ||
3833 | #else | ||
3834 | static inline void s3c_hsotg_of_probe(struct dwc2_hsotg *hsotg) { } | ||
3835 | #endif | ||
3836 | |||
3408 | /** | 3837 | /** |
3409 | * dwc2_gadget_init - init function for gadget | 3838 | * dwc2_gadget_init - init function for gadget |
3410 | * @dwc2: The data structure for the DWC2 driver. | 3839 | * @dwc2: The data structure for the DWC2 driver. |
@@ -3414,41 +3843,47 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) | |||
3414 | { | 3843 | { |
3415 | struct device *dev = hsotg->dev; | 3844 | struct device *dev = hsotg->dev; |
3416 | struct s3c_hsotg_plat *plat = dev->platform_data; | 3845 | struct s3c_hsotg_plat *plat = dev->platform_data; |
3417 | struct phy *phy; | ||
3418 | struct usb_phy *uphy; | ||
3419 | struct s3c_hsotg_ep *eps; | ||
3420 | int epnum; | 3846 | int epnum; |
3421 | int ret; | 3847 | int ret; |
3422 | int i; | 3848 | int i; |
3849 | u32 p_tx_fifo[] = DWC2_G_P_LEGACY_TX_FIFO_SIZE; | ||
3423 | 3850 | ||
3424 | /* Set default UTMI width */ | 3851 | /* Set default UTMI width */ |
3425 | hsotg->phyif = GUSBCFG_PHYIF16; | 3852 | hsotg->phyif = GUSBCFG_PHYIF16; |
3426 | 3853 | ||
3854 | s3c_hsotg_of_probe(hsotg); | ||
3855 | |||
3856 | /* Initialize to legacy fifo configuration values */ | ||
3857 | hsotg->g_rx_fifo_sz = 2048; | ||
3858 | hsotg->g_np_g_tx_fifo_sz = 1024; | ||
3859 | memcpy(&hsotg->g_tx_fifo_sz[1], p_tx_fifo, sizeof(p_tx_fifo)); | ||
3860 | /* Device tree specific probe */ | ||
3861 | s3c_hsotg_of_probe(hsotg); | ||
3862 | /* Dump fifo information */ | ||
3863 | dev_dbg(dev, "NonPeriodic TXFIFO size: %d\n", | ||
3864 | hsotg->g_np_g_tx_fifo_sz); | ||
3865 | dev_dbg(dev, "RXFIFO size: %d\n", hsotg->g_rx_fifo_sz); | ||
3866 | for (i = 0; i < MAX_EPS_CHANNELS; i++) | ||
3867 | dev_dbg(dev, "Periodic TXFIFO%2d size: %d\n", i, | ||
3868 | hsotg->g_tx_fifo_sz[i]); | ||
3427 | /* | 3869 | /* |
3428 | * Attempt to find a generic PHY, then look for an old style | 3870 | * If platform probe couldn't find a generic PHY or an old style |
3429 | * USB PHY, finally fall back to pdata | 3871 | * USB PHY, fall back to pdata |
3430 | */ | 3872 | */ |
3431 | phy = devm_phy_get(dev, "usb2-phy"); | 3873 | if (IS_ERR_OR_NULL(hsotg->phy) && IS_ERR_OR_NULL(hsotg->uphy)) { |
3432 | if (IS_ERR(phy)) { | 3874 | plat = dev_get_platdata(dev); |
3433 | uphy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); | 3875 | if (!plat) { |
3434 | if (IS_ERR(uphy)) { | 3876 | dev_err(dev, |
3435 | /* Fallback for pdata */ | 3877 | "no platform data or transceiver defined\n"); |
3436 | plat = dev_get_platdata(dev); | 3878 | return -EPROBE_DEFER; |
3437 | if (!plat) { | 3879 | } |
3438 | dev_err(dev, | 3880 | hsotg->plat = plat; |
3439 | "no platform data or transceiver defined\n"); | 3881 | } else if (hsotg->phy) { |
3440 | return -EPROBE_DEFER; | ||
3441 | } | ||
3442 | hsotg->plat = plat; | ||
3443 | } else | ||
3444 | hsotg->uphy = uphy; | ||
3445 | } else { | ||
3446 | hsotg->phy = phy; | ||
3447 | /* | 3882 | /* |
3448 | * If using the generic PHY framework, check if the PHY bus | 3883 | * If using the generic PHY framework, check if the PHY bus |
3449 | * width is 8-bit and set the phyif appropriately. | 3884 | * width is 8-bit and set the phyif appropriately. |
3450 | */ | 3885 | */ |
3451 | if (phy_get_bus_width(phy) == 8) | 3886 | if (phy_get_bus_width(hsotg->phy) == 8) |
3452 | hsotg->phyif = GUSBCFG_PHYIF8; | 3887 | hsotg->phyif = GUSBCFG_PHYIF8; |
3453 | } | 3888 | } |
3454 | 3889 | ||
@@ -3488,16 +3923,53 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) | |||
3488 | 3923 | ||
3489 | if (ret) { | 3924 | if (ret) { |
3490 | dev_err(dev, "failed to enable supplies: %d\n", ret); | 3925 | dev_err(dev, "failed to enable supplies: %d\n", ret); |
3491 | goto err_supplies; | 3926 | goto err_clk; |
3492 | } | 3927 | } |
3493 | 3928 | ||
3494 | /* usb phy enable */ | 3929 | /* usb phy enable */ |
3495 | s3c_hsotg_phy_enable(hsotg); | 3930 | s3c_hsotg_phy_enable(hsotg); |
3496 | 3931 | ||
3932 | /* | ||
3933 | * Force Device mode before initialization. | ||
3934 | * This allows correctly configuring fifo for device mode. | ||
3935 | */ | ||
3936 | __bic32(hsotg->regs + GUSBCFG, GUSBCFG_FORCEHOSTMODE); | ||
3937 | __orr32(hsotg->regs + GUSBCFG, GUSBCFG_FORCEDEVMODE); | ||
3938 | |||
3939 | /* | ||
3940 | * According to Synopsys databook, this sleep is needed for the force | ||
3941 | * device mode to take effect. | ||
3942 | */ | ||
3943 | msleep(25); | ||
3944 | |||
3497 | s3c_hsotg_corereset(hsotg); | 3945 | s3c_hsotg_corereset(hsotg); |
3498 | s3c_hsotg_hw_cfg(hsotg); | 3946 | ret = s3c_hsotg_hw_cfg(hsotg); |
3947 | if (ret) { | ||
3948 | dev_err(hsotg->dev, "Hardware configuration failed: %d\n", ret); | ||
3949 | goto err_clk; | ||
3950 | } | ||
3951 | |||
3499 | s3c_hsotg_init(hsotg); | 3952 | s3c_hsotg_init(hsotg); |
3500 | 3953 | ||
3954 | /* Switch back to default configuration */ | ||
3955 | __bic32(hsotg->regs + GUSBCFG, GUSBCFG_FORCEDEVMODE); | ||
3956 | |||
3957 | hsotg->ctrl_buff = devm_kzalloc(hsotg->dev, | ||
3958 | DWC2_CTRL_BUFF_SIZE, GFP_KERNEL); | ||
3959 | if (!hsotg->ctrl_buff) { | ||
3960 | dev_err(dev, "failed to allocate ctrl request buff\n"); | ||
3961 | ret = -ENOMEM; | ||
3962 | goto err_supplies; | ||
3963 | } | ||
3964 | |||
3965 | hsotg->ep0_buff = devm_kzalloc(hsotg->dev, | ||
3966 | DWC2_CTRL_BUFF_SIZE, GFP_KERNEL); | ||
3967 | if (!hsotg->ep0_buff) { | ||
3968 | dev_err(dev, "failed to allocate ctrl reply buff\n"); | ||
3969 | ret = -ENOMEM; | ||
3970 | goto err_supplies; | ||
3971 | } | ||
3972 | |||
3501 | ret = devm_request_irq(hsotg->dev, irq, s3c_hsotg_irq, IRQF_SHARED, | 3973 | ret = devm_request_irq(hsotg->dev, irq, s3c_hsotg_irq, IRQF_SHARED, |
3502 | dev_name(hsotg->dev), hsotg); | 3974 | dev_name(hsotg->dev), hsotg); |
3503 | if (ret < 0) { | 3975 | if (ret < 0) { |
@@ -3506,7 +3978,7 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) | |||
3506 | regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), | 3978 | regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), |
3507 | hsotg->supplies); | 3979 | hsotg->supplies); |
3508 | dev_err(dev, "cannot claim IRQ for gadget\n"); | 3980 | dev_err(dev, "cannot claim IRQ for gadget\n"); |
3509 | goto err_clk; | 3981 | goto err_supplies; |
3510 | } | 3982 | } |
3511 | 3983 | ||
3512 | /* hsotg->num_of_eps holds number of EPs other than ep0 */ | 3984 | /* hsotg->num_of_eps holds number of EPs other than ep0 */ |
@@ -3517,33 +3989,30 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) | |||
3517 | goto err_supplies; | 3989 | goto err_supplies; |
3518 | } | 3990 | } |
3519 | 3991 | ||
3520 | eps = kcalloc(hsotg->num_of_eps + 1, sizeof(struct s3c_hsotg_ep), | ||
3521 | GFP_KERNEL); | ||
3522 | if (!eps) { | ||
3523 | ret = -ENOMEM; | ||
3524 | goto err_supplies; | ||
3525 | } | ||
3526 | |||
3527 | hsotg->eps = eps; | ||
3528 | |||
3529 | /* setup endpoint information */ | 3992 | /* setup endpoint information */ |
3530 | 3993 | ||
3531 | INIT_LIST_HEAD(&hsotg->gadget.ep_list); | 3994 | INIT_LIST_HEAD(&hsotg->gadget.ep_list); |
3532 | hsotg->gadget.ep0 = &hsotg->eps[0].ep; | 3995 | hsotg->gadget.ep0 = &hsotg->eps_out[0]->ep; |
3533 | 3996 | ||
3534 | /* allocate EP0 request */ | 3997 | /* allocate EP0 request */ |
3535 | 3998 | ||
3536 | hsotg->ctrl_req = s3c_hsotg_ep_alloc_request(&hsotg->eps[0].ep, | 3999 | hsotg->ctrl_req = s3c_hsotg_ep_alloc_request(&hsotg->eps_out[0]->ep, |
3537 | GFP_KERNEL); | 4000 | GFP_KERNEL); |
3538 | if (!hsotg->ctrl_req) { | 4001 | if (!hsotg->ctrl_req) { |
3539 | dev_err(dev, "failed to allocate ctrl req\n"); | 4002 | dev_err(dev, "failed to allocate ctrl req\n"); |
3540 | ret = -ENOMEM; | 4003 | ret = -ENOMEM; |
3541 | goto err_ep_mem; | 4004 | goto err_supplies; |
3542 | } | 4005 | } |
3543 | 4006 | ||
3544 | /* initialise the endpoints now the core has been initialised */ | 4007 | /* initialise the endpoints now the core has been initialised */ |
3545 | for (epnum = 0; epnum < hsotg->num_of_eps; epnum++) | 4008 | for (epnum = 0; epnum < hsotg->num_of_eps; epnum++) { |
3546 | s3c_hsotg_initep(hsotg, &hsotg->eps[epnum], epnum); | 4009 | if (hsotg->eps_in[epnum]) |
4010 | s3c_hsotg_initep(hsotg, hsotg->eps_in[epnum], | ||
4011 | epnum, 1); | ||
4012 | if (hsotg->eps_out[epnum]) | ||
4013 | s3c_hsotg_initep(hsotg, hsotg->eps_out[epnum], | ||
4014 | epnum, 0); | ||
4015 | } | ||
3547 | 4016 | ||
3548 | /* disable power and clock */ | 4017 | /* disable power and clock */ |
3549 | s3c_hsotg_phy_disable(hsotg); | 4018 | s3c_hsotg_phy_disable(hsotg); |
@@ -3552,12 +4021,12 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) | |||
3552 | hsotg->supplies); | 4021 | hsotg->supplies); |
3553 | if (ret) { | 4022 | if (ret) { |
3554 | dev_err(dev, "failed to disable supplies: %d\n", ret); | 4023 | dev_err(dev, "failed to disable supplies: %d\n", ret); |
3555 | goto err_ep_mem; | 4024 | goto err_supplies; |
3556 | } | 4025 | } |
3557 | 4026 | ||
3558 | ret = usb_add_gadget_udc(dev, &hsotg->gadget); | 4027 | ret = usb_add_gadget_udc(dev, &hsotg->gadget); |
3559 | if (ret) | 4028 | if (ret) |
3560 | goto err_ep_mem; | 4029 | goto err_supplies; |
3561 | 4030 | ||
3562 | s3c_hsotg_create_debug(hsotg); | 4031 | s3c_hsotg_create_debug(hsotg); |
3563 | 4032 | ||
@@ -3565,8 +4034,6 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) | |||
3565 | 4034 | ||
3566 | return 0; | 4035 | return 0; |
3567 | 4036 | ||
3568 | err_ep_mem: | ||
3569 | kfree(eps); | ||
3570 | err_supplies: | 4037 | err_supplies: |
3571 | s3c_hsotg_phy_disable(hsotg); | 4038 | s3c_hsotg_phy_disable(hsotg); |
3572 | err_clk: | 4039 | err_clk: |
@@ -3612,8 +4079,12 @@ int s3c_hsotg_suspend(struct dwc2_hsotg *hsotg) | |||
3612 | 4079 | ||
3613 | s3c_hsotg_phy_disable(hsotg); | 4080 | s3c_hsotg_phy_disable(hsotg); |
3614 | 4081 | ||
3615 | for (ep = 0; ep < hsotg->num_of_eps; ep++) | 4082 | for (ep = 0; ep < hsotg->num_of_eps; ep++) { |
3616 | s3c_hsotg_ep_disable(&hsotg->eps[ep].ep); | 4083 | if (hsotg->eps_in[ep]) |
4084 | s3c_hsotg_ep_disable(&hsotg->eps_in[ep]->ep); | ||
4085 | if (hsotg->eps_out[ep]) | ||
4086 | s3c_hsotg_ep_disable(&hsotg->eps_out[ep]->ep); | ||
4087 | } | ||
3617 | 4088 | ||
3618 | ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), | 4089 | ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), |
3619 | hsotg->supplies); | 4090 | hsotg->supplies); |
@@ -3644,7 +4115,7 @@ int s3c_hsotg_resume(struct dwc2_hsotg *hsotg) | |||
3644 | s3c_hsotg_phy_enable(hsotg); | 4115 | s3c_hsotg_phy_enable(hsotg); |
3645 | 4116 | ||
3646 | spin_lock_irqsave(&hsotg->lock, flags); | 4117 | spin_lock_irqsave(&hsotg->lock, flags); |
3647 | s3c_hsotg_core_init_disconnected(hsotg); | 4118 | s3c_hsotg_core_init_disconnected(hsotg, false); |
3648 | if (hsotg->enabled) | 4119 | if (hsotg->enabled) |
3649 | s3c_hsotg_core_connect(hsotg); | 4120 | s3c_hsotg_core_connect(hsotg); |
3650 | spin_unlock_irqrestore(&hsotg->lock, flags); | 4121 | spin_unlock_irqrestore(&hsotg->lock, flags); |
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index a0cd9db6f4cd..c78c8740db1d 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c | |||
@@ -316,10 +316,12 @@ void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg) | |||
316 | */ | 316 | */ |
317 | static void dwc2_hcd_rem_wakeup(struct dwc2_hsotg *hsotg) | 317 | static void dwc2_hcd_rem_wakeup(struct dwc2_hsotg *hsotg) |
318 | { | 318 | { |
319 | if (hsotg->lx_state == DWC2_L2) | 319 | if (hsotg->lx_state == DWC2_L2) { |
320 | hsotg->flags.b.port_suspend_change = 1; | 320 | hsotg->flags.b.port_suspend_change = 1; |
321 | else | 321 | usb_hcd_resume_root_hub(hsotg->priv); |
322 | } else { | ||
322 | hsotg->flags.b.port_l1_change = 1; | 323 | hsotg->flags.b.port_l1_change = 1; |
324 | } | ||
323 | } | 325 | } |
324 | 326 | ||
325 | /** | 327 | /** |
@@ -1371,7 +1373,7 @@ static void dwc2_conn_id_status_change(struct work_struct *work) | |||
1371 | hsotg->op_state = OTG_STATE_B_PERIPHERAL; | 1373 | hsotg->op_state = OTG_STATE_B_PERIPHERAL; |
1372 | dwc2_core_init(hsotg, false, -1); | 1374 | dwc2_core_init(hsotg, false, -1); |
1373 | dwc2_enable_global_interrupts(hsotg); | 1375 | dwc2_enable_global_interrupts(hsotg); |
1374 | s3c_hsotg_core_init_disconnected(hsotg); | 1376 | s3c_hsotg_core_init_disconnected(hsotg, false); |
1375 | s3c_hsotg_core_connect(hsotg); | 1377 | s3c_hsotg_core_connect(hsotg); |
1376 | } else { | 1378 | } else { |
1377 | /* A-Device connector (Host Mode) */ | 1379 | /* A-Device connector (Host Mode) */ |
@@ -1473,30 +1475,6 @@ static void dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex) | |||
1473 | } | 1475 | } |
1474 | } | 1476 | } |
1475 | 1477 | ||
1476 | static void dwc2_port_resume(struct dwc2_hsotg *hsotg) | ||
1477 | { | ||
1478 | u32 hprt0; | ||
1479 | |||
1480 | /* After clear the Stop PHY clock bit, we should wait for a moment | ||
1481 | * for PLL work stable with clock output. | ||
1482 | */ | ||
1483 | writel(0, hsotg->regs + PCGCTL); | ||
1484 | usleep_range(2000, 4000); | ||
1485 | |||
1486 | hprt0 = dwc2_read_hprt0(hsotg); | ||
1487 | hprt0 |= HPRT0_RES; | ||
1488 | writel(hprt0, hsotg->regs + HPRT0); | ||
1489 | hprt0 &= ~HPRT0_SUSP; | ||
1490 | /* according to USB2.0 Spec 7.1.7.7, the host must send the resume | ||
1491 | * signal for at least 20ms | ||
1492 | */ | ||
1493 | usleep_range(20000, 25000); | ||
1494 | |||
1495 | hprt0 &= ~HPRT0_RES; | ||
1496 | writel(hprt0, hsotg->regs + HPRT0); | ||
1497 | hsotg->lx_state = DWC2_L0; | ||
1498 | } | ||
1499 | |||
1500 | /* Handles hub class-specific requests */ | 1478 | /* Handles hub class-specific requests */ |
1501 | static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, | 1479 | static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, |
1502 | u16 wvalue, u16 windex, char *buf, u16 wlength) | 1480 | u16 wvalue, u16 windex, char *buf, u16 wlength) |
@@ -1542,7 +1520,17 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, | |||
1542 | case USB_PORT_FEAT_SUSPEND: | 1520 | case USB_PORT_FEAT_SUSPEND: |
1543 | dev_dbg(hsotg->dev, | 1521 | dev_dbg(hsotg->dev, |
1544 | "ClearPortFeature USB_PORT_FEAT_SUSPEND\n"); | 1522 | "ClearPortFeature USB_PORT_FEAT_SUSPEND\n"); |
1545 | dwc2_port_resume(hsotg); | 1523 | writel(0, hsotg->regs + PCGCTL); |
1524 | usleep_range(20000, 40000); | ||
1525 | |||
1526 | hprt0 = dwc2_read_hprt0(hsotg); | ||
1527 | hprt0 |= HPRT0_RES; | ||
1528 | writel(hprt0, hsotg->regs + HPRT0); | ||
1529 | hprt0 &= ~HPRT0_SUSP; | ||
1530 | usleep_range(100000, 150000); | ||
1531 | |||
1532 | hprt0 &= ~HPRT0_RES; | ||
1533 | writel(hprt0, hsotg->regs + HPRT0); | ||
1546 | break; | 1534 | break; |
1547 | 1535 | ||
1548 | case USB_PORT_FEAT_POWER: | 1536 | case USB_PORT_FEAT_POWER: |
@@ -1622,7 +1610,9 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, | |||
1622 | hub_desc->bDescLength = 9; | 1610 | hub_desc->bDescLength = 9; |
1623 | hub_desc->bDescriptorType = 0x29; | 1611 | hub_desc->bDescriptorType = 0x29; |
1624 | hub_desc->bNbrPorts = 1; | 1612 | hub_desc->bNbrPorts = 1; |
1625 | hub_desc->wHubCharacteristics = cpu_to_le16(0x08); | 1613 | hub_desc->wHubCharacteristics = |
1614 | cpu_to_le16(HUB_CHAR_COMMON_LPSM | | ||
1615 | HUB_CHAR_INDV_PORT_OCPM); | ||
1626 | hub_desc->bPwrOn2PwrGood = 1; | 1616 | hub_desc->bPwrOn2PwrGood = 1; |
1627 | hub_desc->bHubContrCurrent = 0; | 1617 | hub_desc->bHubContrCurrent = 0; |
1628 | hub_desc->u.hs.DeviceRemovable[0] = 0; | 1618 | hub_desc->u.hs.DeviceRemovable[0] = 0; |
@@ -2315,55 +2305,6 @@ static void _dwc2_hcd_stop(struct usb_hcd *hcd) | |||
2315 | usleep_range(1000, 3000); | 2305 | usleep_range(1000, 3000); |
2316 | } | 2306 | } |
2317 | 2307 | ||
2318 | static int _dwc2_hcd_suspend(struct usb_hcd *hcd) | ||
2319 | { | ||
2320 | struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); | ||
2321 | u32 hprt0; | ||
2322 | |||
2323 | if (!((hsotg->op_state == OTG_STATE_B_HOST) || | ||
2324 | (hsotg->op_state == OTG_STATE_A_HOST))) | ||
2325 | return 0; | ||
2326 | |||
2327 | /* TODO: We get into suspend from 'on' state, maybe we need to do | ||
2328 | * something if we get here from DWC2_L1(LPM sleep) state one day. | ||
2329 | */ | ||
2330 | if (hsotg->lx_state != DWC2_L0) | ||
2331 | return 0; | ||
2332 | |||
2333 | hprt0 = dwc2_read_hprt0(hsotg); | ||
2334 | if (hprt0 & HPRT0_CONNSTS) { | ||
2335 | dwc2_port_suspend(hsotg, 1); | ||
2336 | } else { | ||
2337 | u32 pcgctl = readl(hsotg->regs + PCGCTL); | ||
2338 | |||
2339 | pcgctl |= PCGCTL_STOPPCLK; | ||
2340 | writel(pcgctl, hsotg->regs + PCGCTL); | ||
2341 | } | ||
2342 | |||
2343 | return 0; | ||
2344 | } | ||
2345 | |||
2346 | static int _dwc2_hcd_resume(struct usb_hcd *hcd) | ||
2347 | { | ||
2348 | struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); | ||
2349 | u32 hprt0; | ||
2350 | |||
2351 | if (!((hsotg->op_state == OTG_STATE_B_HOST) || | ||
2352 | (hsotg->op_state == OTG_STATE_A_HOST))) | ||
2353 | return 0; | ||
2354 | |||
2355 | if (hsotg->lx_state != DWC2_L2) | ||
2356 | return 0; | ||
2357 | |||
2358 | hprt0 = dwc2_read_hprt0(hsotg); | ||
2359 | if ((hprt0 & HPRT0_CONNSTS) && (hprt0 & HPRT0_SUSP)) | ||
2360 | dwc2_port_resume(hsotg); | ||
2361 | else | ||
2362 | writel(0, hsotg->regs + PCGCTL); | ||
2363 | |||
2364 | return 0; | ||
2365 | } | ||
2366 | |||
2367 | /* Returns the current frame number */ | 2308 | /* Returns the current frame number */ |
2368 | static int _dwc2_hcd_get_frame_number(struct usb_hcd *hcd) | 2309 | static int _dwc2_hcd_get_frame_number(struct usb_hcd *hcd) |
2369 | { | 2310 | { |
@@ -2734,9 +2675,6 @@ static struct hc_driver dwc2_hc_driver = { | |||
2734 | .hub_status_data = _dwc2_hcd_hub_status_data, | 2675 | .hub_status_data = _dwc2_hcd_hub_status_data, |
2735 | .hub_control = _dwc2_hcd_hub_control, | 2676 | .hub_control = _dwc2_hcd_hub_control, |
2736 | .clear_tt_buffer_complete = _dwc2_hcd_clear_tt_buffer_complete, | 2677 | .clear_tt_buffer_complete = _dwc2_hcd_clear_tt_buffer_complete, |
2737 | |||
2738 | .bus_suspend = _dwc2_hcd_suspend, | ||
2739 | .bus_resume = _dwc2_hcd_resume, | ||
2740 | }; | 2678 | }; |
2741 | 2679 | ||
2742 | /* | 2680 | /* |
diff --git a/drivers/usb/dwc2/hw.h b/drivers/usb/dwc2/hw.h index 51248b935493..d0a5ed8fa15a 100644 --- a/drivers/usb/dwc2/hw.h +++ b/drivers/usb/dwc2/hw.h | |||
@@ -294,6 +294,7 @@ | |||
294 | #define GHWCFG4_NUM_IN_EPS_MASK (0xf << 26) | 294 | #define GHWCFG4_NUM_IN_EPS_MASK (0xf << 26) |
295 | #define GHWCFG4_NUM_IN_EPS_SHIFT 26 | 295 | #define GHWCFG4_NUM_IN_EPS_SHIFT 26 |
296 | #define GHWCFG4_DED_FIFO_EN (1 << 25) | 296 | #define GHWCFG4_DED_FIFO_EN (1 << 25) |
297 | #define GHWCFG4_DED_FIFO_SHIFT 25 | ||
297 | #define GHWCFG4_SESSION_END_FILT_EN (1 << 24) | 298 | #define GHWCFG4_SESSION_END_FILT_EN (1 << 24) |
298 | #define GHWCFG4_B_VALID_FILT_EN (1 << 23) | 299 | #define GHWCFG4_B_VALID_FILT_EN (1 << 23) |
299 | #define GHWCFG4_A_VALID_FILT_EN (1 << 22) | 300 | #define GHWCFG4_A_VALID_FILT_EN (1 << 22) |
@@ -541,6 +542,7 @@ | |||
541 | 542 | ||
542 | #define DIEPINT(_a) HSOTG_REG(0x908 + ((_a) * 0x20)) | 543 | #define DIEPINT(_a) HSOTG_REG(0x908 + ((_a) * 0x20)) |
543 | #define DOEPINT(_a) HSOTG_REG(0xB08 + ((_a) * 0x20)) | 544 | #define DOEPINT(_a) HSOTG_REG(0xB08 + ((_a) * 0x20)) |
545 | #define DXEPINT_SETUP_RCVD (1 << 15) | ||
544 | #define DXEPINT_INEPNAKEFF (1 << 6) | 546 | #define DXEPINT_INEPNAKEFF (1 << 6) |
545 | #define DXEPINT_BACK2BACKSETUP (1 << 6) | 547 | #define DXEPINT_BACK2BACKSETUP (1 << 6) |
546 | #define DXEPINT_INTKNEPMIS (1 << 5) | 548 | #define DXEPINT_INTKNEPMIS (1 << 5) |
diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 6a795aa2ff05..ae095f009b4f 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c | |||
@@ -155,6 +155,8 @@ static int dwc2_driver_probe(struct platform_device *dev) | |||
155 | struct dwc2_core_params defparams; | 155 | struct dwc2_core_params defparams; |
156 | struct dwc2_hsotg *hsotg; | 156 | struct dwc2_hsotg *hsotg; |
157 | struct resource *res; | 157 | struct resource *res; |
158 | struct phy *phy; | ||
159 | struct usb_phy *uphy; | ||
158 | int retval; | 160 | int retval; |
159 | int irq; | 161 | int irq; |
160 | 162 | ||
@@ -212,6 +214,24 @@ static int dwc2_driver_probe(struct platform_device *dev) | |||
212 | 214 | ||
213 | hsotg->dr_mode = of_usb_get_dr_mode(dev->dev.of_node); | 215 | hsotg->dr_mode = of_usb_get_dr_mode(dev->dev.of_node); |
214 | 216 | ||
217 | /* | ||
218 | * Attempt to find a generic PHY, then look for an old style | ||
219 | * USB PHY | ||
220 | */ | ||
221 | phy = devm_phy_get(&dev->dev, "usb2-phy"); | ||
222 | if (IS_ERR(phy)) { | ||
223 | hsotg->phy = NULL; | ||
224 | uphy = devm_usb_get_phy(&dev->dev, USB_PHY_TYPE_USB2); | ||
225 | if (IS_ERR(uphy)) | ||
226 | hsotg->uphy = NULL; | ||
227 | else | ||
228 | hsotg->uphy = uphy; | ||
229 | } else { | ||
230 | hsotg->phy = phy; | ||
231 | phy_power_on(hsotg->phy); | ||
232 | phy_init(hsotg->phy); | ||
233 | } | ||
234 | |||
215 | spin_lock_init(&hsotg->lock); | 235 | spin_lock_init(&hsotg->lock); |
216 | mutex_init(&hsotg->init_mutex); | 236 | mutex_init(&hsotg->init_mutex); |
217 | retval = dwc2_gadget_init(hsotg, irq); | 237 | retval = dwc2_gadget_init(hsotg, irq); |
@@ -231,8 +251,15 @@ static int __maybe_unused dwc2_suspend(struct device *dev) | |||
231 | struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); | 251 | struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); |
232 | int ret = 0; | 252 | int ret = 0; |
233 | 253 | ||
234 | if (dwc2_is_device_mode(dwc2)) | 254 | if (dwc2_is_device_mode(dwc2)) { |
235 | ret = s3c_hsotg_suspend(dwc2); | 255 | ret = s3c_hsotg_suspend(dwc2); |
256 | } else { | ||
257 | if (dwc2->lx_state == DWC2_L0) | ||
258 | return 0; | ||
259 | phy_exit(dwc2->phy); | ||
260 | phy_power_off(dwc2->phy); | ||
261 | |||
262 | } | ||
236 | return ret; | 263 | return ret; |
237 | } | 264 | } |
238 | 265 | ||
@@ -241,8 +268,13 @@ static int __maybe_unused dwc2_resume(struct device *dev) | |||
241 | struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); | 268 | struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); |
242 | int ret = 0; | 269 | int ret = 0; |
243 | 270 | ||
244 | if (dwc2_is_device_mode(dwc2)) | 271 | if (dwc2_is_device_mode(dwc2)) { |
245 | ret = s3c_hsotg_resume(dwc2); | 272 | ret = s3c_hsotg_resume(dwc2); |
273 | } else { | ||
274 | phy_power_on(dwc2->phy); | ||
275 | phy_init(dwc2->phy); | ||
276 | |||
277 | } | ||
246 | return ret; | 278 | return ret; |
247 | } | 279 | } |
248 | 280 | ||
diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 58b5b2cde4c5..edbf9c85af7e 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig | |||
@@ -104,12 +104,6 @@ config USB_DWC3_DEBUG | |||
104 | help | 104 | help |
105 | Say Y here to enable debugging messages on DWC3 Driver. | 105 | Say Y here to enable debugging messages on DWC3 Driver. |
106 | 106 | ||
107 | config USB_DWC3_VERBOSE | ||
108 | bool "Enable Verbose Debugging Messages" | ||
109 | depends on USB_DWC3_DEBUG | ||
110 | help | ||
111 | Say Y here to enable verbose debugging messages on DWC3 Driver. | ||
112 | |||
113 | config DWC3_HOST_USB3_LPM_ENABLE | 107 | config DWC3_HOST_USB3_LPM_ENABLE |
114 | bool "Enable USB3 LPM Capability" | 108 | bool "Enable USB3 LPM Capability" |
115 | depends on USB_DWC3_HOST=y || USB_DWC3_DUAL_ROLE=y | 109 | depends on USB_DWC3_HOST=y || USB_DWC3_DUAL_ROLE=y |
diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile index bb34fbcfeab3..46172f47f02d 100644 --- a/drivers/usb/dwc3/Makefile +++ b/drivers/usb/dwc3/Makefile | |||
@@ -2,7 +2,6 @@ | |||
2 | CFLAGS_trace.o := -I$(src) | 2 | CFLAGS_trace.o := -I$(src) |
3 | 3 | ||
4 | ccflags-$(CONFIG_USB_DWC3_DEBUG) := -DDEBUG | 4 | ccflags-$(CONFIG_USB_DWC3_DEBUG) := -DDEBUG |
5 | ccflags-$(CONFIG_USB_DWC3_VERBOSE) += -DVERBOSE_DEBUG | ||
6 | 5 | ||
7 | obj-$(CONFIG_USB_DWC3) += dwc3.o | 6 | obj-$(CONFIG_USB_DWC3) += dwc3.o |
8 | 7 | ||
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 25ddc39efad8..9f0e209b8f6c 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c | |||
@@ -345,7 +345,7 @@ static void dwc3_core_num_eps(struct dwc3 *dwc) | |||
345 | dwc->num_in_eps = DWC3_NUM_IN_EPS(parms); | 345 | dwc->num_in_eps = DWC3_NUM_IN_EPS(parms); |
346 | dwc->num_out_eps = DWC3_NUM_EPS(parms) - dwc->num_in_eps; | 346 | dwc->num_out_eps = DWC3_NUM_EPS(parms) - dwc->num_in_eps; |
347 | 347 | ||
348 | dev_vdbg(dwc->dev, "found %d IN and %d OUT endpoints\n", | 348 | dwc3_trace(trace_dwc3_core, "found %d IN and %d OUT endpoints", |
349 | dwc->num_in_eps, dwc->num_out_eps); | 349 | dwc->num_in_eps, dwc->num_out_eps); |
350 | } | 350 | } |
351 | 351 | ||
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 4bb9aa696ede..d201910b892f 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h | |||
@@ -431,7 +431,6 @@ struct dwc3_event_buffer { | |||
431 | * @dwc: pointer to DWC controller | 431 | * @dwc: pointer to DWC controller |
432 | * @saved_state: ep state saved during hibernation | 432 | * @saved_state: ep state saved during hibernation |
433 | * @flags: endpoint flags (wedged, stalled, ...) | 433 | * @flags: endpoint flags (wedged, stalled, ...) |
434 | * @current_trb: index of current used trb | ||
435 | * @number: endpoint number (1 - 15) | 434 | * @number: endpoint number (1 - 15) |
436 | * @type: set to bmAttributes & USB_ENDPOINT_XFERTYPE_MASK | 435 | * @type: set to bmAttributes & USB_ENDPOINT_XFERTYPE_MASK |
437 | * @resource_index: Resource transfer index | 436 | * @resource_index: Resource transfer index |
@@ -464,8 +463,6 @@ struct dwc3_ep { | |||
464 | /* This last one is specific to EP0 */ | 463 | /* This last one is specific to EP0 */ |
465 | #define DWC3_EP0_DIR_IN (1 << 31) | 464 | #define DWC3_EP0_DIR_IN (1 << 31) |
466 | 465 | ||
467 | unsigned current_trb; | ||
468 | |||
469 | u8 number; | 466 | u8 number; |
470 | u8 type; | 467 | u8 type; |
471 | u8 resource_index; | 468 | u8 resource_index; |
@@ -685,7 +682,6 @@ struct dwc3_scratchpad_array { | |||
685 | * @is_utmi_l1_suspend: the core asserts output signal | 682 | * @is_utmi_l1_suspend: the core asserts output signal |
686 | * 0 - utmi_sleep_n | 683 | * 0 - utmi_sleep_n |
687 | * 1 - utmi_l1_suspend_n | 684 | * 1 - utmi_l1_suspend_n |
688 | * @is_selfpowered: true when we are selfpowered | ||
689 | * @is_fpga: true when we are using the FPGA board | 685 | * @is_fpga: true when we are using the FPGA board |
690 | * @needs_fifo_resize: not all users might want fifo resizing, flag it | 686 | * @needs_fifo_resize: not all users might want fifo resizing, flag it |
691 | * @pullups_connected: true when Run/Stop bit is set | 687 | * @pullups_connected: true when Run/Stop bit is set |
@@ -809,7 +805,6 @@ struct dwc3 { | |||
809 | unsigned has_hibernation:1; | 805 | unsigned has_hibernation:1; |
810 | unsigned has_lpm_erratum:1; | 806 | unsigned has_lpm_erratum:1; |
811 | unsigned is_utmi_l1_suspend:1; | 807 | unsigned is_utmi_l1_suspend:1; |
812 | unsigned is_selfpowered:1; | ||
813 | unsigned is_fpga:1; | 808 | unsigned is_fpga:1; |
814 | unsigned needs_fifo_resize:1; | 809 | unsigned needs_fifo_resize:1; |
815 | unsigned pullups_connected:1; | 810 | unsigned pullups_connected:1; |
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index b642a2f998f9..8d950569d557 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c | |||
@@ -22,9 +22,6 @@ | |||
22 | #include <linux/pci.h> | 22 | #include <linux/pci.h> |
23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
24 | 24 | ||
25 | #include <linux/usb/otg.h> | ||
26 | #include <linux/usb/usb_phy_generic.h> | ||
27 | |||
28 | #include "platform_data.h" | 25 | #include "platform_data.h" |
29 | 26 | ||
30 | /* FIXME define these in <linux/pci_ids.h> */ | 27 | /* FIXME define these in <linux/pci_ids.h> */ |
@@ -36,66 +33,41 @@ | |||
36 | #define PCI_DEVICE_ID_INTEL_SPTLP 0x9d30 | 33 | #define PCI_DEVICE_ID_INTEL_SPTLP 0x9d30 |
37 | #define PCI_DEVICE_ID_INTEL_SPTH 0xa130 | 34 | #define PCI_DEVICE_ID_INTEL_SPTH 0xa130 |
38 | 35 | ||
39 | struct dwc3_pci { | 36 | static int dwc3_pci_quirks(struct pci_dev *pdev) |
40 | struct device *dev; | ||
41 | struct platform_device *dwc3; | ||
42 | struct platform_device *usb2_phy; | ||
43 | struct platform_device *usb3_phy; | ||
44 | }; | ||
45 | |||
46 | static int dwc3_pci_register_phys(struct dwc3_pci *glue) | ||
47 | { | 37 | { |
48 | struct usb_phy_generic_platform_data pdata; | 38 | if (pdev->vendor == PCI_VENDOR_ID_AMD && |
49 | struct platform_device *pdev; | 39 | pdev->device == PCI_DEVICE_ID_AMD_NL_USB) { |
50 | int ret; | 40 | struct dwc3_platform_data pdata; |
51 | 41 | ||
52 | memset(&pdata, 0x00, sizeof(pdata)); | 42 | memset(&pdata, 0, sizeof(pdata)); |
53 | 43 | ||
54 | pdev = platform_device_alloc("usb_phy_generic", 0); | 44 | pdata.has_lpm_erratum = true; |
55 | if (!pdev) | 45 | pdata.lpm_nyet_threshold = 0xf; |
56 | return -ENOMEM; | ||
57 | |||
58 | glue->usb2_phy = pdev; | ||
59 | pdata.type = USB_PHY_TYPE_USB2; | ||
60 | pdata.gpio_reset = -1; | ||
61 | 46 | ||
62 | ret = platform_device_add_data(glue->usb2_phy, &pdata, sizeof(pdata)); | 47 | pdata.u2exit_lfps_quirk = true; |
63 | if (ret) | 48 | pdata.u2ss_inp3_quirk = true; |
64 | goto err1; | 49 | pdata.req_p1p2p3_quirk = true; |
50 | pdata.del_p1p2p3_quirk = true; | ||
51 | pdata.del_phy_power_chg_quirk = true; | ||
52 | pdata.lfps_filter_quirk = true; | ||
53 | pdata.rx_detect_poll_quirk = true; | ||
65 | 54 | ||
66 | pdev = platform_device_alloc("usb_phy_generic", 1); | 55 | pdata.tx_de_emphasis_quirk = true; |
67 | if (!pdev) { | 56 | pdata.tx_de_emphasis = 1; |
68 | ret = -ENOMEM; | ||
69 | goto err1; | ||
70 | } | ||
71 | 57 | ||
72 | glue->usb3_phy = pdev; | 58 | /* |
73 | pdata.type = USB_PHY_TYPE_USB3; | 59 | * FIXME these quirks should be removed when AMD NL |
74 | 60 | * taps out | |
75 | ret = platform_device_add_data(glue->usb3_phy, &pdata, sizeof(pdata)); | 61 | */ |
76 | if (ret) | 62 | pdata.disable_scramble_quirk = true; |
77 | goto err2; | 63 | pdata.dis_u3_susphy_quirk = true; |
78 | 64 | pdata.dis_u2_susphy_quirk = true; | |
79 | ret = platform_device_add(glue->usb2_phy); | ||
80 | if (ret) | ||
81 | goto err2; | ||
82 | 65 | ||
83 | ret = platform_device_add(glue->usb3_phy); | 66 | return platform_device_add_data(pci_get_drvdata(pdev), &pdata, |
84 | if (ret) | 67 | sizeof(pdata)); |
85 | goto err3; | 68 | } |
86 | 69 | ||
87 | return 0; | 70 | return 0; |
88 | |||
89 | err3: | ||
90 | platform_device_del(glue->usb2_phy); | ||
91 | |||
92 | err2: | ||
93 | platform_device_put(glue->usb3_phy); | ||
94 | |||
95 | err1: | ||
96 | platform_device_put(glue->usb2_phy); | ||
97 | |||
98 | return ret; | ||
99 | } | 71 | } |
100 | 72 | ||
101 | static int dwc3_pci_probe(struct pci_dev *pci, | 73 | static int dwc3_pci_probe(struct pci_dev *pci, |
@@ -103,18 +75,8 @@ static int dwc3_pci_probe(struct pci_dev *pci, | |||
103 | { | 75 | { |
104 | struct resource res[2]; | 76 | struct resource res[2]; |
105 | struct platform_device *dwc3; | 77 | struct platform_device *dwc3; |
106 | struct dwc3_pci *glue; | ||
107 | int ret; | 78 | int ret; |
108 | struct device *dev = &pci->dev; | 79 | struct device *dev = &pci->dev; |
109 | struct dwc3_platform_data dwc3_pdata; | ||
110 | |||
111 | memset(&dwc3_pdata, 0x00, sizeof(dwc3_pdata)); | ||
112 | |||
113 | glue = devm_kzalloc(dev, sizeof(*glue), GFP_KERNEL); | ||
114 | if (!glue) | ||
115 | return -ENOMEM; | ||
116 | |||
117 | glue->dev = dev; | ||
118 | 80 | ||
119 | ret = pcim_enable_device(pci); | 81 | ret = pcim_enable_device(pci); |
120 | if (ret) { | 82 | if (ret) { |
@@ -124,12 +86,6 @@ static int dwc3_pci_probe(struct pci_dev *pci, | |||
124 | 86 | ||
125 | pci_set_master(pci); | 87 | pci_set_master(pci); |
126 | 88 | ||
127 | ret = dwc3_pci_register_phys(glue); | ||
128 | if (ret) { | ||
129 | dev_err(dev, "couldn't register PHYs\n"); | ||
130 | return ret; | ||
131 | } | ||
132 | |||
133 | dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO); | 89 | dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO); |
134 | if (!dwc3) { | 90 | if (!dwc3) { |
135 | dev_err(dev, "couldn't allocate dwc3 device\n"); | 91 | dev_err(dev, "couldn't allocate dwc3 device\n"); |
@@ -147,70 +103,34 @@ static int dwc3_pci_probe(struct pci_dev *pci, | |||
147 | res[1].name = "dwc_usb3"; | 103 | res[1].name = "dwc_usb3"; |
148 | res[1].flags = IORESOURCE_IRQ; | 104 | res[1].flags = IORESOURCE_IRQ; |
149 | 105 | ||
150 | if (pci->vendor == PCI_VENDOR_ID_AMD && | ||
151 | pci->device == PCI_DEVICE_ID_AMD_NL_USB) { | ||
152 | dwc3_pdata.has_lpm_erratum = true; | ||
153 | dwc3_pdata.lpm_nyet_threshold = 0xf; | ||
154 | |||
155 | dwc3_pdata.u2exit_lfps_quirk = true; | ||
156 | dwc3_pdata.u2ss_inp3_quirk = true; | ||
157 | dwc3_pdata.req_p1p2p3_quirk = true; | ||
158 | dwc3_pdata.del_p1p2p3_quirk = true; | ||
159 | dwc3_pdata.del_phy_power_chg_quirk = true; | ||
160 | dwc3_pdata.lfps_filter_quirk = true; | ||
161 | dwc3_pdata.rx_detect_poll_quirk = true; | ||
162 | |||
163 | dwc3_pdata.tx_de_emphasis_quirk = true; | ||
164 | dwc3_pdata.tx_de_emphasis = 1; | ||
165 | |||
166 | /* | ||
167 | * FIXME these quirks should be removed when AMD NL | ||
168 | * taps out | ||
169 | */ | ||
170 | dwc3_pdata.disable_scramble_quirk = true; | ||
171 | dwc3_pdata.dis_u3_susphy_quirk = true; | ||
172 | dwc3_pdata.dis_u2_susphy_quirk = true; | ||
173 | } | ||
174 | |||
175 | ret = platform_device_add_resources(dwc3, res, ARRAY_SIZE(res)); | 106 | ret = platform_device_add_resources(dwc3, res, ARRAY_SIZE(res)); |
176 | if (ret) { | 107 | if (ret) { |
177 | dev_err(dev, "couldn't add resources to dwc3 device\n"); | 108 | dev_err(dev, "couldn't add resources to dwc3 device\n"); |
178 | return ret; | 109 | return ret; |
179 | } | 110 | } |
180 | 111 | ||
181 | pci_set_drvdata(pci, glue); | 112 | pci_set_drvdata(pci, dwc3); |
182 | 113 | ret = dwc3_pci_quirks(pci); | |
183 | ret = platform_device_add_data(dwc3, &dwc3_pdata, sizeof(dwc3_pdata)); | ||
184 | if (ret) | 114 | if (ret) |
185 | goto err3; | 115 | goto err; |
186 | |||
187 | dma_set_coherent_mask(&dwc3->dev, dev->coherent_dma_mask); | ||
188 | 116 | ||
189 | dwc3->dev.dma_mask = dev->dma_mask; | ||
190 | dwc3->dev.dma_parms = dev->dma_parms; | ||
191 | dwc3->dev.parent = dev; | 117 | dwc3->dev.parent = dev; |
192 | glue->dwc3 = dwc3; | ||
193 | 118 | ||
194 | ret = platform_device_add(dwc3); | 119 | ret = platform_device_add(dwc3); |
195 | if (ret) { | 120 | if (ret) { |
196 | dev_err(dev, "failed to register dwc3 device\n"); | 121 | dev_err(dev, "failed to register dwc3 device\n"); |
197 | goto err3; | 122 | goto err; |
198 | } | 123 | } |
199 | 124 | ||
200 | return 0; | 125 | return 0; |
201 | 126 | err: | |
202 | err3: | ||
203 | platform_device_put(dwc3); | 127 | platform_device_put(dwc3); |
204 | return ret; | 128 | return ret; |
205 | } | 129 | } |
206 | 130 | ||
207 | static void dwc3_pci_remove(struct pci_dev *pci) | 131 | static void dwc3_pci_remove(struct pci_dev *pci) |
208 | { | 132 | { |
209 | struct dwc3_pci *glue = pci_get_drvdata(pci); | 133 | platform_device_unregister(pci_get_drvdata(pci)); |
210 | |||
211 | platform_device_unregister(glue->dwc3); | ||
212 | platform_device_unregister(glue->usb2_phy); | ||
213 | platform_device_unregister(glue->usb3_phy); | ||
214 | } | 134 | } |
215 | 135 | ||
216 | static const struct pci_device_id dwc3_pci_id_table[] = { | 136 | static const struct pci_device_id dwc3_pci_id_table[] = { |
@@ -228,45 +148,11 @@ static const struct pci_device_id dwc3_pci_id_table[] = { | |||
228 | }; | 148 | }; |
229 | MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table); | 149 | MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table); |
230 | 150 | ||
231 | #ifdef CONFIG_PM_SLEEP | ||
232 | static int dwc3_pci_suspend(struct device *dev) | ||
233 | { | ||
234 | struct pci_dev *pci = to_pci_dev(dev); | ||
235 | |||
236 | pci_disable_device(pci); | ||
237 | |||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | static int dwc3_pci_resume(struct device *dev) | ||
242 | { | ||
243 | struct pci_dev *pci = to_pci_dev(dev); | ||
244 | int ret; | ||
245 | |||
246 | ret = pci_enable_device(pci); | ||
247 | if (ret) { | ||
248 | dev_err(dev, "can't re-enable device --> %d\n", ret); | ||
249 | return ret; | ||
250 | } | ||
251 | |||
252 | pci_set_master(pci); | ||
253 | |||
254 | return 0; | ||
255 | } | ||
256 | #endif /* CONFIG_PM_SLEEP */ | ||
257 | |||
258 | static const struct dev_pm_ops dwc3_pci_dev_pm_ops = { | ||
259 | SET_SYSTEM_SLEEP_PM_OPS(dwc3_pci_suspend, dwc3_pci_resume) | ||
260 | }; | ||
261 | |||
262 | static struct pci_driver dwc3_pci_driver = { | 151 | static struct pci_driver dwc3_pci_driver = { |
263 | .name = "dwc3-pci", | 152 | .name = "dwc3-pci", |
264 | .id_table = dwc3_pci_id_table, | 153 | .id_table = dwc3_pci_id_table, |
265 | .probe = dwc3_pci_probe, | 154 | .probe = dwc3_pci_probe, |
266 | .remove = dwc3_pci_remove, | 155 | .remove = dwc3_pci_remove, |
267 | .driver = { | ||
268 | .pm = &dwc3_pci_dev_pm_ops, | ||
269 | }, | ||
270 | }; | 156 | }; |
271 | 157 | ||
272 | MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>"); | 158 | MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>"); |
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 1bc77a3b4997..2ef3c8d6a9db 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c | |||
@@ -344,7 +344,7 @@ static int dwc3_ep0_handle_status(struct dwc3 *dwc, | |||
344 | /* | 344 | /* |
345 | * LTM will be set once we know how to set this in HW. | 345 | * LTM will be set once we know how to set this in HW. |
346 | */ | 346 | */ |
347 | usb_status |= dwc->is_selfpowered << USB_DEVICE_SELF_POWERED; | 347 | usb_status |= dwc->gadget.is_selfpowered; |
348 | 348 | ||
349 | if (dwc->speed == DWC3_DSTS_SUPERSPEED) { | 349 | if (dwc->speed == DWC3_DSTS_SUPERSPEED) { |
350 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | 350 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); |
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 8f65ab3a3b92..a03a485205c7 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c | |||
@@ -139,7 +139,8 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state) | |||
139 | udelay(5); | 139 | udelay(5); |
140 | } | 140 | } |
141 | 141 | ||
142 | dev_vdbg(dwc->dev, "link state change request timed out\n"); | 142 | dwc3_trace(trace_dwc3_gadget, |
143 | "link state change request timed out"); | ||
143 | 144 | ||
144 | return -ETIMEDOUT; | 145 | return -ETIMEDOUT; |
145 | } | 146 | } |
@@ -219,7 +220,7 @@ int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc) | |||
219 | 220 | ||
220 | fifo_size |= (last_fifo_depth << 16); | 221 | fifo_size |= (last_fifo_depth << 16); |
221 | 222 | ||
222 | dev_vdbg(dwc->dev, "%s: Fifo Addr %04x Size %d\n", | 223 | dwc3_trace(trace_dwc3_gadget, "%s: Fifo Addr %04x Size %d", |
223 | dep->name, last_fifo_depth, fifo_size & 0xffff); | 224 | dep->name, last_fifo_depth, fifo_size & 0xffff); |
224 | 225 | ||
225 | dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(num), fifo_size); | 226 | dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(num), fifo_size); |
@@ -287,7 +288,8 @@ int dwc3_send_gadget_generic_command(struct dwc3 *dwc, unsigned cmd, u32 param) | |||
287 | do { | 288 | do { |
288 | reg = dwc3_readl(dwc->regs, DWC3_DGCMD); | 289 | reg = dwc3_readl(dwc->regs, DWC3_DGCMD); |
289 | if (!(reg & DWC3_DGCMD_CMDACT)) { | 290 | if (!(reg & DWC3_DGCMD_CMDACT)) { |
290 | dev_vdbg(dwc->dev, "Command Complete --> %d\n", | 291 | dwc3_trace(trace_dwc3_gadget, |
292 | "Command Complete --> %d", | ||
291 | DWC3_DGCMD_STATUS(reg)); | 293 | DWC3_DGCMD_STATUS(reg)); |
292 | return 0; | 294 | return 0; |
293 | } | 295 | } |
@@ -297,8 +299,11 @@ int dwc3_send_gadget_generic_command(struct dwc3 *dwc, unsigned cmd, u32 param) | |||
297 | * interrupt context. | 299 | * interrupt context. |
298 | */ | 300 | */ |
299 | timeout--; | 301 | timeout--; |
300 | if (!timeout) | 302 | if (!timeout) { |
303 | dwc3_trace(trace_dwc3_gadget, | ||
304 | "Command Timed Out"); | ||
301 | return -ETIMEDOUT; | 305 | return -ETIMEDOUT; |
306 | } | ||
302 | udelay(1); | 307 | udelay(1); |
303 | } while (1); | 308 | } while (1); |
304 | } | 309 | } |
@@ -320,7 +325,8 @@ int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep, | |||
320 | do { | 325 | do { |
321 | reg = dwc3_readl(dwc->regs, DWC3_DEPCMD(ep)); | 326 | reg = dwc3_readl(dwc->regs, DWC3_DEPCMD(ep)); |
322 | if (!(reg & DWC3_DEPCMD_CMDACT)) { | 327 | if (!(reg & DWC3_DEPCMD_CMDACT)) { |
323 | dev_vdbg(dwc->dev, "Command Complete --> %d\n", | 328 | dwc3_trace(trace_dwc3_gadget, |
329 | "Command Complete --> %d", | ||
324 | DWC3_DEPCMD_STATUS(reg)); | 330 | DWC3_DEPCMD_STATUS(reg)); |
325 | return 0; | 331 | return 0; |
326 | } | 332 | } |
@@ -330,8 +336,11 @@ int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep, | |||
330 | * interrupt context. | 336 | * interrupt context. |
331 | */ | 337 | */ |
332 | timeout--; | 338 | timeout--; |
333 | if (!timeout) | 339 | if (!timeout) { |
340 | dwc3_trace(trace_dwc3_gadget, | ||
341 | "Command Timed Out"); | ||
334 | return -ETIMEDOUT; | 342 | return -ETIMEDOUT; |
343 | } | ||
335 | 344 | ||
336 | udelay(1); | 345 | udelay(1); |
337 | } while (1); | 346 | } while (1); |
@@ -352,9 +361,6 @@ static int dwc3_alloc_trb_pool(struct dwc3_ep *dep) | |||
352 | if (dep->trb_pool) | 361 | if (dep->trb_pool) |
353 | return 0; | 362 | return 0; |
354 | 363 | ||
355 | if (dep->number == 0 || dep->number == 1) | ||
356 | return 0; | ||
357 | |||
358 | dep->trb_pool = dma_alloc_coherent(dwc->dev, | 364 | dep->trb_pool = dma_alloc_coherent(dwc->dev, |
359 | sizeof(struct dwc3_trb) * DWC3_TRB_NUM, | 365 | sizeof(struct dwc3_trb) * DWC3_TRB_NUM, |
360 | &dep->trb_pool_dma, GFP_KERNEL); | 366 | &dep->trb_pool_dma, GFP_KERNEL); |
@@ -492,7 +498,7 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep, | |||
492 | u32 reg; | 498 | u32 reg; |
493 | int ret; | 499 | int ret; |
494 | 500 | ||
495 | dev_vdbg(dwc->dev, "Enabling %s\n", dep->name); | 501 | dwc3_trace(trace_dwc3_gadget, "Enabling %s", dep->name); |
496 | 502 | ||
497 | if (!(dep->flags & DWC3_EP_ENABLED)) { | 503 | if (!(dep->flags & DWC3_EP_ENABLED)) { |
498 | ret = dwc3_gadget_start_config(dwc, dep); | 504 | ret = dwc3_gadget_start_config(dwc, dep); |
@@ -729,10 +735,9 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, | |||
729 | struct dwc3_request *req, dma_addr_t dma, | 735 | struct dwc3_request *req, dma_addr_t dma, |
730 | unsigned length, unsigned last, unsigned chain, unsigned node) | 736 | unsigned length, unsigned last, unsigned chain, unsigned node) |
731 | { | 737 | { |
732 | struct dwc3 *dwc = dep->dwc; | ||
733 | struct dwc3_trb *trb; | 738 | struct dwc3_trb *trb; |
734 | 739 | ||
735 | dev_vdbg(dwc->dev, "%s: req %p dma %08llx length %d%s%s\n", | 740 | dwc3_trace(trace_dwc3_gadget, "%s: req %p dma %08llx length %d%s%s", |
736 | dep->name, req, (unsigned long long) dma, | 741 | dep->name, req, (unsigned long long) dma, |
737 | length, last ? " last" : "", | 742 | length, last ? " last" : "", |
738 | chain ? " chain" : ""); | 743 | chain ? " chain" : ""); |
@@ -934,7 +939,7 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param, | |||
934 | u32 cmd; | 939 | u32 cmd; |
935 | 940 | ||
936 | if (start_new && (dep->flags & DWC3_EP_BUSY)) { | 941 | if (start_new && (dep->flags & DWC3_EP_BUSY)) { |
937 | dev_vdbg(dwc->dev, "%s: endpoint busy\n", dep->name); | 942 | dwc3_trace(trace_dwc3_gadget, "%s: endpoint busy", dep->name); |
938 | return -EBUSY; | 943 | return -EBUSY; |
939 | } | 944 | } |
940 | dep->flags &= ~DWC3_EP_PENDING_REQUEST; | 945 | dep->flags &= ~DWC3_EP_PENDING_REQUEST; |
@@ -1005,8 +1010,9 @@ static void __dwc3_gadget_start_isoc(struct dwc3 *dwc, | |||
1005 | u32 uf; | 1010 | u32 uf; |
1006 | 1011 | ||
1007 | if (list_empty(&dep->request_list)) { | 1012 | if (list_empty(&dep->request_list)) { |
1008 | dev_vdbg(dwc->dev, "ISOC ep %s run out for requests.\n", | 1013 | dwc3_trace(trace_dwc3_gadget, |
1009 | dep->name); | 1014 | "ISOC ep %s run out for requests", |
1015 | dep->name); | ||
1010 | dep->flags |= DWC3_EP_PENDING_REQUEST; | 1016 | dep->flags |= DWC3_EP_PENDING_REQUEST; |
1011 | return; | 1017 | return; |
1012 | } | 1018 | } |
@@ -1113,15 +1119,10 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) | |||
1113 | * handled. | 1119 | * handled. |
1114 | */ | 1120 | */ |
1115 | if (dep->stream_capable) { | 1121 | if (dep->stream_capable) { |
1116 | int ret; | ||
1117 | |||
1118 | ret = __dwc3_gadget_kick_transfer(dep, 0, true); | 1122 | ret = __dwc3_gadget_kick_transfer(dep, 0, true); |
1119 | if (ret && ret != -EBUSY) { | 1123 | if (ret && ret != -EBUSY) |
1120 | struct dwc3 *dwc = dep->dwc; | ||
1121 | |||
1122 | dev_dbg(dwc->dev, "%s: failed to kick transfers\n", | 1124 | dev_dbg(dwc->dev, "%s: failed to kick transfers\n", |
1123 | dep->name); | 1125 | dep->name); |
1124 | } | ||
1125 | } | 1126 | } |
1126 | 1127 | ||
1127 | return 0; | 1128 | return 0; |
@@ -1152,8 +1153,6 @@ static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request, | |||
1152 | goto out; | 1153 | goto out; |
1153 | } | 1154 | } |
1154 | 1155 | ||
1155 | dev_vdbg(dwc->dev, "queing request %p to %s length %d\n", | ||
1156 | request, ep->name, request->length); | ||
1157 | trace_dwc3_ep_queue(req); | 1156 | trace_dwc3_ep_queue(req); |
1158 | 1157 | ||
1159 | ret = __dwc3_gadget_ep_queue(dep, req); | 1158 | ret = __dwc3_gadget_ep_queue(dep, req); |
@@ -1416,7 +1415,7 @@ static int dwc3_gadget_set_selfpowered(struct usb_gadget *g, | |||
1416 | unsigned long flags; | 1415 | unsigned long flags; |
1417 | 1416 | ||
1418 | spin_lock_irqsave(&dwc->lock, flags); | 1417 | spin_lock_irqsave(&dwc->lock, flags); |
1419 | dwc->is_selfpowered = !!is_selfpowered; | 1418 | g->is_selfpowered = !!is_selfpowered; |
1420 | spin_unlock_irqrestore(&dwc->lock, flags); | 1419 | spin_unlock_irqrestore(&dwc->lock, flags); |
1421 | 1420 | ||
1422 | return 0; | 1421 | return 0; |
@@ -1468,7 +1467,7 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend) | |||
1468 | udelay(1); | 1467 | udelay(1); |
1469 | } while (1); | 1468 | } while (1); |
1470 | 1469 | ||
1471 | dev_vdbg(dwc->dev, "gadget %s data soft-%s\n", | 1470 | dwc3_trace(trace_dwc3_gadget, "gadget %s data soft-%s", |
1472 | dwc->gadget_driver | 1471 | dwc->gadget_driver |
1473 | ? dwc->gadget_driver->function : "no-function", | 1472 | ? dwc->gadget_driver->function : "no-function", |
1474 | is_on ? "connect" : "disconnect"); | 1473 | is_on ? "connect" : "disconnect"); |
@@ -1688,7 +1687,7 @@ static int dwc3_gadget_init_hw_endpoints(struct dwc3 *dwc, | |||
1688 | 1687 | ||
1689 | dep->endpoint.name = dep->name; | 1688 | dep->endpoint.name = dep->name; |
1690 | 1689 | ||
1691 | dev_vdbg(dwc->dev, "initializing %s\n", dep->name); | 1690 | dwc3_trace(trace_dwc3_gadget, "initializing %s", dep->name); |
1692 | 1691 | ||
1693 | if (epnum == 0 || epnum == 1) { | 1692 | if (epnum == 0 || epnum == 1) { |
1694 | usb_ep_set_maxpacket_limit(&dep->endpoint, 512); | 1693 | usb_ep_set_maxpacket_limit(&dep->endpoint, 512); |
@@ -1725,13 +1724,15 @@ static int dwc3_gadget_init_endpoints(struct dwc3 *dwc) | |||
1725 | 1724 | ||
1726 | ret = dwc3_gadget_init_hw_endpoints(dwc, dwc->num_out_eps, 0); | 1725 | ret = dwc3_gadget_init_hw_endpoints(dwc, dwc->num_out_eps, 0); |
1727 | if (ret < 0) { | 1726 | if (ret < 0) { |
1728 | dev_vdbg(dwc->dev, "failed to allocate OUT endpoints\n"); | 1727 | dwc3_trace(trace_dwc3_gadget, |
1728 | "failed to allocate OUT endpoints"); | ||
1729 | return ret; | 1729 | return ret; |
1730 | } | 1730 | } |
1731 | 1731 | ||
1732 | ret = dwc3_gadget_init_hw_endpoints(dwc, dwc->num_in_eps, 1); | 1732 | ret = dwc3_gadget_init_hw_endpoints(dwc, dwc->num_in_eps, 1); |
1733 | if (ret < 0) { | 1733 | if (ret < 0) { |
1734 | dev_vdbg(dwc->dev, "failed to allocate IN endpoints\n"); | 1734 | dwc3_trace(trace_dwc3_gadget, |
1735 | "failed to allocate IN endpoints"); | ||
1735 | return ret; | 1736 | return ret; |
1736 | } | 1737 | } |
1737 | 1738 | ||
@@ -1977,7 +1978,7 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, | |||
1977 | } else { | 1978 | } else { |
1978 | int ret; | 1979 | int ret; |
1979 | 1980 | ||
1980 | dev_vdbg(dwc->dev, "%s: reason %s\n", | 1981 | dwc3_trace(trace_dwc3_gadget, "%s: reason %s", |
1981 | dep->name, event->status & | 1982 | dep->name, event->status & |
1982 | DEPEVT_STATUS_TRANSFER_ACTIVE | 1983 | DEPEVT_STATUS_TRANSFER_ACTIVE |
1983 | ? "Transfer Active" | 1984 | ? "Transfer Active" |
@@ -2001,7 +2002,8 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, | |||
2001 | 2002 | ||
2002 | switch (event->status) { | 2003 | switch (event->status) { |
2003 | case DEPEVT_STREAMEVT_FOUND: | 2004 | case DEPEVT_STREAMEVT_FOUND: |
2004 | dev_vdbg(dwc->dev, "Stream %d found and started\n", | 2005 | dwc3_trace(trace_dwc3_gadget, |
2006 | "Stream %d found and started", | ||
2005 | event->parameters); | 2007 | event->parameters); |
2006 | 2008 | ||
2007 | break; | 2009 | break; |
@@ -2015,7 +2017,7 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, | |||
2015 | dev_dbg(dwc->dev, "%s FIFO Overrun\n", dep->name); | 2017 | dev_dbg(dwc->dev, "%s FIFO Overrun\n", dep->name); |
2016 | break; | 2018 | break; |
2017 | case DWC3_DEPEVT_EPCMDCMPLT: | 2019 | case DWC3_DEPEVT_EPCMDCMPLT: |
2018 | dev_vdbg(dwc->dev, "Endpoint Command Complete\n"); | 2020 | dwc3_trace(trace_dwc3_gadget, "Endpoint Command Complete"); |
2019 | break; | 2021 | break; |
2020 | } | 2022 | } |
2021 | } | 2023 | } |
@@ -2043,6 +2045,7 @@ static void dwc3_resume_gadget(struct dwc3 *dwc) | |||
2043 | if (dwc->gadget_driver && dwc->gadget_driver->resume) { | 2045 | if (dwc->gadget_driver && dwc->gadget_driver->resume) { |
2044 | spin_unlock(&dwc->lock); | 2046 | spin_unlock(&dwc->lock); |
2045 | dwc->gadget_driver->resume(&dwc->gadget); | 2047 | dwc->gadget_driver->resume(&dwc->gadget); |
2048 | spin_lock(&dwc->lock); | ||
2046 | } | 2049 | } |
2047 | } | 2050 | } |
2048 | 2051 | ||
@@ -2079,7 +2082,7 @@ static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum, bool force) | |||
2079 | * We have discussed this with the IP Provider and it was | 2082 | * We have discussed this with the IP Provider and it was |
2080 | * suggested to giveback all requests here, but give HW some | 2083 | * suggested to giveback all requests here, but give HW some |
2081 | * extra time to synchronize with the interconnect. We're using | 2084 | * extra time to synchronize with the interconnect. We're using |
2082 | * an arbitraty 100us delay for that. | 2085 | * an arbitrary 100us delay for that. |
2083 | * | 2086 | * |
2084 | * Note also that a similar handling was tested by Synopsys | 2087 | * Note also that a similar handling was tested by Synopsys |
2085 | * (thanks a lot Paul) and nothing bad has come out of it. | 2088 | * (thanks a lot Paul) and nothing bad has come out of it. |
@@ -2389,7 +2392,8 @@ static void dwc3_gadget_linksts_change_interrupt(struct dwc3 *dwc, | |||
2389 | (pwropt != DWC3_GHWPARAMS1_EN_PWROPT_HIB)) { | 2392 | (pwropt != DWC3_GHWPARAMS1_EN_PWROPT_HIB)) { |
2390 | if ((dwc->link_state == DWC3_LINK_STATE_U3) && | 2393 | if ((dwc->link_state == DWC3_LINK_STATE_U3) && |
2391 | (next == DWC3_LINK_STATE_RESUME)) { | 2394 | (next == DWC3_LINK_STATE_RESUME)) { |
2392 | dev_vdbg(dwc->dev, "ignoring transition U3 -> Resume\n"); | 2395 | dwc3_trace(trace_dwc3_gadget, |
2396 | "ignoring transition U3 -> Resume"); | ||
2393 | return; | 2397 | return; |
2394 | } | 2398 | } |
2395 | } | 2399 | } |
@@ -2511,22 +2515,22 @@ static void dwc3_gadget_interrupt(struct dwc3 *dwc, | |||
2511 | dwc3_gadget_linksts_change_interrupt(dwc, event->event_info); | 2515 | dwc3_gadget_linksts_change_interrupt(dwc, event->event_info); |
2512 | break; | 2516 | break; |
2513 | case DWC3_DEVICE_EVENT_EOPF: | 2517 | case DWC3_DEVICE_EVENT_EOPF: |
2514 | dev_vdbg(dwc->dev, "End of Periodic Frame\n"); | 2518 | dwc3_trace(trace_dwc3_gadget, "End of Periodic Frame"); |
2515 | break; | 2519 | break; |
2516 | case DWC3_DEVICE_EVENT_SOF: | 2520 | case DWC3_DEVICE_EVENT_SOF: |
2517 | dev_vdbg(dwc->dev, "Start of Periodic Frame\n"); | 2521 | dwc3_trace(trace_dwc3_gadget, "Start of Periodic Frame"); |
2518 | break; | 2522 | break; |
2519 | case DWC3_DEVICE_EVENT_ERRATIC_ERROR: | 2523 | case DWC3_DEVICE_EVENT_ERRATIC_ERROR: |
2520 | dev_vdbg(dwc->dev, "Erratic Error\n"); | 2524 | dwc3_trace(trace_dwc3_gadget, "Erratic Error"); |
2521 | break; | 2525 | break; |
2522 | case DWC3_DEVICE_EVENT_CMD_CMPL: | 2526 | case DWC3_DEVICE_EVENT_CMD_CMPL: |
2523 | dev_vdbg(dwc->dev, "Command Complete\n"); | 2527 | dwc3_trace(trace_dwc3_gadget, "Command Complete"); |
2524 | break; | 2528 | break; |
2525 | case DWC3_DEVICE_EVENT_OVERFLOW: | 2529 | case DWC3_DEVICE_EVENT_OVERFLOW: |
2526 | dev_vdbg(dwc->dev, "Overflow\n"); | 2530 | dwc3_trace(trace_dwc3_gadget, "Overflow"); |
2527 | break; | 2531 | break; |
2528 | default: | 2532 | default: |
2529 | dev_dbg(dwc->dev, "UNKNOWN IRQ %d\n", event->type); | 2533 | dev_WARN(dwc->dev, "UNKNOWN IRQ %d\n", event->type); |
2530 | } | 2534 | } |
2531 | } | 2535 | } |
2532 | 2536 | ||
diff --git a/drivers/usb/dwc3/trace.h b/drivers/usb/dwc3/trace.h index 9fc20b33dd8e..9c10669ab91f 100644 --- a/drivers/usb/dwc3/trace.h +++ b/drivers/usb/dwc3/trace.h | |||
@@ -47,6 +47,16 @@ DEFINE_EVENT(dwc3_log_msg, dwc3_writel, | |||
47 | TP_ARGS(vaf) | 47 | TP_ARGS(vaf) |
48 | ); | 48 | ); |
49 | 49 | ||
50 | DEFINE_EVENT(dwc3_log_msg, dwc3_gadget, | ||
51 | TP_PROTO(struct va_format *vaf), | ||
52 | TP_ARGS(vaf) | ||
53 | ); | ||
54 | |||
55 | DEFINE_EVENT(dwc3_log_msg, dwc3_core, | ||
56 | TP_PROTO(struct va_format *vaf), | ||
57 | TP_ARGS(vaf) | ||
58 | ); | ||
59 | |||
50 | DEFINE_EVENT(dwc3_log_msg, dwc3_ep0, | 60 | DEFINE_EVENT(dwc3_log_msg, dwc3_ep0, |
51 | TP_PROTO(struct va_format *vaf), | 61 | TP_PROTO(struct va_format *vaf), |
52 | TP_ARGS(vaf) | 62 | TP_ARGS(vaf) |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 747ef53bda14..96539038c03a 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -423,6 +423,17 @@ config USB_CONFIGFS_F_HID | |||
423 | 423 | ||
424 | For more information, see Documentation/usb/gadget_hid.txt. | 424 | For more information, see Documentation/usb/gadget_hid.txt. |
425 | 425 | ||
426 | config USB_CONFIGFS_F_UVC | ||
427 | bool "USB Webcam function" | ||
428 | depends on USB_CONFIGFS | ||
429 | depends on VIDEO_DEV | ||
430 | select VIDEOBUF2_VMALLOC | ||
431 | select USB_F_UVC | ||
432 | help | ||
433 | The Webcam function acts as a composite USB Audio and Video Class | ||
434 | device. It provides a userspace API to process UVC control requests | ||
435 | and stream video data to the host. | ||
436 | |||
426 | source "drivers/usb/gadget/legacy/Kconfig" | 437 | source "drivers/usb/gadget/legacy/Kconfig" |
427 | 438 | ||
428 | endchoice | 439 | endchoice |
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 617835348569..13adfd1a3f54 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c | |||
@@ -1655,7 +1655,7 @@ unknown: | |||
1655 | * OS descriptors handling | 1655 | * OS descriptors handling |
1656 | */ | 1656 | */ |
1657 | if (cdev->use_os_string && cdev->os_desc_config && | 1657 | if (cdev->use_os_string && cdev->os_desc_config && |
1658 | (ctrl->bRequest & USB_TYPE_VENDOR) && | 1658 | (ctrl->bRequestType & USB_TYPE_VENDOR) && |
1659 | ctrl->bRequest == cdev->b_vendor_code) { | 1659 | ctrl->bRequest == cdev->b_vendor_code) { |
1660 | struct usb_request *req; | 1660 | struct usb_request *req; |
1661 | struct usb_configuration *os_desc_cfg; | 1661 | struct usb_configuration *os_desc_cfg; |
diff --git a/drivers/usb/gadget/function/Makefile b/drivers/usb/gadget/function/Makefile index dd68091d92f0..f71b1aaa0edf 100644 --- a/drivers/usb/gadget/function/Makefile +++ b/drivers/usb/gadget/function/Makefile | |||
@@ -36,7 +36,7 @@ usb_f_uac1-y := f_uac1.o u_uac1.o | |||
36 | obj-$(CONFIG_USB_F_UAC1) += usb_f_uac1.o | 36 | obj-$(CONFIG_USB_F_UAC1) += usb_f_uac1.o |
37 | usb_f_uac2-y := f_uac2.o | 37 | usb_f_uac2-y := f_uac2.o |
38 | obj-$(CONFIG_USB_F_UAC2) += usb_f_uac2.o | 38 | obj-$(CONFIG_USB_F_UAC2) += usb_f_uac2.o |
39 | usb_f_uvc-y := f_uvc.o uvc_queue.o uvc_v4l2.o uvc_video.o | 39 | usb_f_uvc-y := f_uvc.o uvc_queue.o uvc_v4l2.o uvc_video.o uvc_configfs.o |
40 | obj-$(CONFIG_USB_F_UVC) += usb_f_uvc.o | 40 | obj-$(CONFIG_USB_F_UVC) += usb_f_uvc.o |
41 | usb_f_midi-y := f_midi.o | 41 | usb_f_midi-y := f_midi.o |
42 | obj-$(CONFIG_USB_F_MIDI) += usb_f_midi.o | 42 | obj-$(CONFIG_USB_F_MIDI) += usb_f_midi.o |
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 63314ede7ba6..af98b096af2f 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/aio.h> | 31 | #include <linux/aio.h> |
32 | #include <linux/mmu_context.h> | 32 | #include <linux/mmu_context.h> |
33 | #include <linux/poll.h> | 33 | #include <linux/poll.h> |
34 | #include <linux/eventfd.h> | ||
34 | 35 | ||
35 | #include "u_fs.h" | 36 | #include "u_fs.h" |
36 | #include "u_f.h" | 37 | #include "u_f.h" |
@@ -153,6 +154,8 @@ struct ffs_io_data { | |||
153 | 154 | ||
154 | struct usb_ep *ep; | 155 | struct usb_ep *ep; |
155 | struct usb_request *req; | 156 | struct usb_request *req; |
157 | |||
158 | struct ffs_data *ffs; | ||
156 | }; | 159 | }; |
157 | 160 | ||
158 | struct ffs_desc_helper { | 161 | struct ffs_desc_helper { |
@@ -390,17 +393,20 @@ done_spin: | |||
390 | return ret; | 393 | return ret; |
391 | } | 394 | } |
392 | 395 | ||
396 | /* Called with ffs->ev.waitq.lock and ffs->mutex held, both released on exit. */ | ||
393 | static ssize_t __ffs_ep0_read_events(struct ffs_data *ffs, char __user *buf, | 397 | static ssize_t __ffs_ep0_read_events(struct ffs_data *ffs, char __user *buf, |
394 | size_t n) | 398 | size_t n) |
395 | { | 399 | { |
396 | /* | 400 | /* |
397 | * We are holding ffs->ev.waitq.lock and ffs->mutex and we need | 401 | * n cannot be bigger than ffs->ev.count, which cannot be bigger than |
398 | * to release them. | 402 | * size of ffs->ev.types array (which is four) so that's how much space |
403 | * we reserve. | ||
399 | */ | 404 | */ |
400 | struct usb_functionfs_event events[n]; | 405 | struct usb_functionfs_event events[ARRAY_SIZE(ffs->ev.types)]; |
406 | const size_t size = n * sizeof *events; | ||
401 | unsigned i = 0; | 407 | unsigned i = 0; |
402 | 408 | ||
403 | memset(events, 0, sizeof events); | 409 | memset(events, 0, size); |
404 | 410 | ||
405 | do { | 411 | do { |
406 | events[i].type = ffs->ev.types[i]; | 412 | events[i].type = ffs->ev.types[i]; |
@@ -410,19 +416,15 @@ static ssize_t __ffs_ep0_read_events(struct ffs_data *ffs, char __user *buf, | |||
410 | } | 416 | } |
411 | } while (++i < n); | 417 | } while (++i < n); |
412 | 418 | ||
413 | if (n < ffs->ev.count) { | 419 | ffs->ev.count -= n; |
414 | ffs->ev.count -= n; | 420 | if (ffs->ev.count) |
415 | memmove(ffs->ev.types, ffs->ev.types + n, | 421 | memmove(ffs->ev.types, ffs->ev.types + n, |
416 | ffs->ev.count * sizeof *ffs->ev.types); | 422 | ffs->ev.count * sizeof *ffs->ev.types); |
417 | } else { | ||
418 | ffs->ev.count = 0; | ||
419 | } | ||
420 | 423 | ||
421 | spin_unlock_irq(&ffs->ev.waitq.lock); | 424 | spin_unlock_irq(&ffs->ev.waitq.lock); |
422 | mutex_unlock(&ffs->mutex); | 425 | mutex_unlock(&ffs->mutex); |
423 | 426 | ||
424 | return unlikely(__copy_to_user(buf, events, sizeof events)) | 427 | return unlikely(__copy_to_user(buf, events, size)) ? -EFAULT : size; |
425 | ? -EFAULT : sizeof events; | ||
426 | } | 428 | } |
427 | 429 | ||
428 | static ssize_t ffs_ep0_read(struct file *file, char __user *buf, | 430 | static ssize_t ffs_ep0_read(struct file *file, char __user *buf, |
@@ -606,6 +608,8 @@ static unsigned int ffs_ep0_poll(struct file *file, poll_table *wait) | |||
606 | } | 608 | } |
607 | case FFS_CLOSING: | 609 | case FFS_CLOSING: |
608 | break; | 610 | break; |
611 | case FFS_DEACTIVATED: | ||
612 | break; | ||
609 | } | 613 | } |
610 | 614 | ||
611 | mutex_unlock(&ffs->mutex); | 615 | mutex_unlock(&ffs->mutex); |
@@ -673,6 +677,9 @@ static void ffs_user_copy_worker(struct work_struct *work) | |||
673 | 677 | ||
674 | aio_complete(io_data->kiocb, ret, ret); | 678 | aio_complete(io_data->kiocb, ret, ret); |
675 | 679 | ||
680 | if (io_data->ffs->ffs_eventfd && !io_data->kiocb->ki_eventfd) | ||
681 | eventfd_signal(io_data->ffs->ffs_eventfd, 1); | ||
682 | |||
676 | usb_ep_free_request(io_data->ep, io_data->req); | 683 | usb_ep_free_request(io_data->ep, io_data->req); |
677 | 684 | ||
678 | io_data->kiocb->private = NULL; | 685 | io_data->kiocb->private = NULL; |
@@ -826,6 +833,7 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) | |||
826 | io_data->buf = data; | 833 | io_data->buf = data; |
827 | io_data->ep = ep->ep; | 834 | io_data->ep = ep->ep; |
828 | io_data->req = req; | 835 | io_data->req = req; |
836 | io_data->ffs = epfile->ffs; | ||
829 | 837 | ||
830 | req->context = io_data; | 838 | req->context = io_data; |
831 | req->complete = ffs_epfile_async_io_complete; | 839 | req->complete = ffs_epfile_async_io_complete; |
@@ -1180,6 +1188,7 @@ struct ffs_sb_fill_data { | |||
1180 | struct ffs_file_perms perms; | 1188 | struct ffs_file_perms perms; |
1181 | umode_t root_mode; | 1189 | umode_t root_mode; |
1182 | const char *dev_name; | 1190 | const char *dev_name; |
1191 | bool no_disconnect; | ||
1183 | struct ffs_data *ffs_data; | 1192 | struct ffs_data *ffs_data; |
1184 | }; | 1193 | }; |
1185 | 1194 | ||
@@ -1250,6 +1259,12 @@ static int ffs_fs_parse_opts(struct ffs_sb_fill_data *data, char *opts) | |||
1250 | 1259 | ||
1251 | /* Interpret option */ | 1260 | /* Interpret option */ |
1252 | switch (eq - opts) { | 1261 | switch (eq - opts) { |
1262 | case 13: | ||
1263 | if (!memcmp(opts, "no_disconnect", 13)) | ||
1264 | data->no_disconnect = !!value; | ||
1265 | else | ||
1266 | goto invalid; | ||
1267 | break; | ||
1253 | case 5: | 1268 | case 5: |
1254 | if (!memcmp(opts, "rmode", 5)) | 1269 | if (!memcmp(opts, "rmode", 5)) |
1255 | data->root_mode = (value & 0555) | S_IFDIR; | 1270 | data->root_mode = (value & 0555) | S_IFDIR; |
@@ -1314,6 +1329,7 @@ ffs_fs_mount(struct file_system_type *t, int flags, | |||
1314 | .gid = GLOBAL_ROOT_GID, | 1329 | .gid = GLOBAL_ROOT_GID, |
1315 | }, | 1330 | }, |
1316 | .root_mode = S_IFDIR | 0500, | 1331 | .root_mode = S_IFDIR | 0500, |
1332 | .no_disconnect = false, | ||
1317 | }; | 1333 | }; |
1318 | struct dentry *rv; | 1334 | struct dentry *rv; |
1319 | int ret; | 1335 | int ret; |
@@ -1330,6 +1346,7 @@ ffs_fs_mount(struct file_system_type *t, int flags, | |||
1330 | if (unlikely(!ffs)) | 1346 | if (unlikely(!ffs)) |
1331 | return ERR_PTR(-ENOMEM); | 1347 | return ERR_PTR(-ENOMEM); |
1332 | ffs->file_perms = data.perms; | 1348 | ffs->file_perms = data.perms; |
1349 | ffs->no_disconnect = data.no_disconnect; | ||
1333 | 1350 | ||
1334 | ffs->dev_name = kstrdup(dev_name, GFP_KERNEL); | 1351 | ffs->dev_name = kstrdup(dev_name, GFP_KERNEL); |
1335 | if (unlikely(!ffs->dev_name)) { | 1352 | if (unlikely(!ffs->dev_name)) { |
@@ -1361,6 +1378,7 @@ ffs_fs_kill_sb(struct super_block *sb) | |||
1361 | kill_litter_super(sb); | 1378 | kill_litter_super(sb); |
1362 | if (sb->s_fs_info) { | 1379 | if (sb->s_fs_info) { |
1363 | ffs_release_dev(sb->s_fs_info); | 1380 | ffs_release_dev(sb->s_fs_info); |
1381 | ffs_data_closed(sb->s_fs_info); | ||
1364 | ffs_data_put(sb->s_fs_info); | 1382 | ffs_data_put(sb->s_fs_info); |
1365 | } | 1383 | } |
1366 | } | 1384 | } |
@@ -1417,7 +1435,11 @@ static void ffs_data_opened(struct ffs_data *ffs) | |||
1417 | ENTER(); | 1435 | ENTER(); |
1418 | 1436 | ||
1419 | atomic_inc(&ffs->ref); | 1437 | atomic_inc(&ffs->ref); |
1420 | atomic_inc(&ffs->opened); | 1438 | if (atomic_add_return(1, &ffs->opened) == 1 && |
1439 | ffs->state == FFS_DEACTIVATED) { | ||
1440 | ffs->state = FFS_CLOSING; | ||
1441 | ffs_data_reset(ffs); | ||
1442 | } | ||
1421 | } | 1443 | } |
1422 | 1444 | ||
1423 | static void ffs_data_put(struct ffs_data *ffs) | 1445 | static void ffs_data_put(struct ffs_data *ffs) |
@@ -1439,6 +1461,21 @@ static void ffs_data_closed(struct ffs_data *ffs) | |||
1439 | ENTER(); | 1461 | ENTER(); |
1440 | 1462 | ||
1441 | if (atomic_dec_and_test(&ffs->opened)) { | 1463 | if (atomic_dec_and_test(&ffs->opened)) { |
1464 | if (ffs->no_disconnect) { | ||
1465 | ffs->state = FFS_DEACTIVATED; | ||
1466 | if (ffs->epfiles) { | ||
1467 | ffs_epfiles_destroy(ffs->epfiles, | ||
1468 | ffs->eps_count); | ||
1469 | ffs->epfiles = NULL; | ||
1470 | } | ||
1471 | if (ffs->setup_state == FFS_SETUP_PENDING) | ||
1472 | __ffs_ep0_stall(ffs); | ||
1473 | } else { | ||
1474 | ffs->state = FFS_CLOSING; | ||
1475 | ffs_data_reset(ffs); | ||
1476 | } | ||
1477 | } | ||
1478 | if (atomic_read(&ffs->opened) < 0) { | ||
1442 | ffs->state = FFS_CLOSING; | 1479 | ffs->state = FFS_CLOSING; |
1443 | ffs_data_reset(ffs); | 1480 | ffs_data_reset(ffs); |
1444 | } | 1481 | } |
@@ -1480,6 +1517,9 @@ static void ffs_data_clear(struct ffs_data *ffs) | |||
1480 | if (ffs->epfiles) | 1517 | if (ffs->epfiles) |
1481 | ffs_epfiles_destroy(ffs->epfiles, ffs->eps_count); | 1518 | ffs_epfiles_destroy(ffs->epfiles, ffs->eps_count); |
1482 | 1519 | ||
1520 | if (ffs->ffs_eventfd) | ||
1521 | eventfd_ctx_put(ffs->ffs_eventfd); | ||
1522 | |||
1483 | kfree(ffs->raw_descs_data); | 1523 | kfree(ffs->raw_descs_data); |
1484 | kfree(ffs->raw_strings); | 1524 | kfree(ffs->raw_strings); |
1485 | kfree(ffs->stringtabs); | 1525 | kfree(ffs->stringtabs); |
@@ -1581,10 +1621,10 @@ static int ffs_epfiles_create(struct ffs_data *ffs) | |||
1581 | mutex_init(&epfile->mutex); | 1621 | mutex_init(&epfile->mutex); |
1582 | init_waitqueue_head(&epfile->wait); | 1622 | init_waitqueue_head(&epfile->wait); |
1583 | if (ffs->user_flags & FUNCTIONFS_VIRTUAL_ADDR) | 1623 | if (ffs->user_flags & FUNCTIONFS_VIRTUAL_ADDR) |
1584 | sprintf(epfiles->name, "ep%02x", ffs->eps_addrmap[i]); | 1624 | sprintf(epfile->name, "ep%02x", ffs->eps_addrmap[i]); |
1585 | else | 1625 | else |
1586 | sprintf(epfiles->name, "ep%u", i); | 1626 | sprintf(epfile->name, "ep%u", i); |
1587 | epfile->dentry = ffs_sb_create_file(ffs->sb, epfiles->name, | 1627 | epfile->dentry = ffs_sb_create_file(ffs->sb, epfile->name, |
1588 | epfile, | 1628 | epfile, |
1589 | &ffs_epfile_operations); | 1629 | &ffs_epfile_operations); |
1590 | if (unlikely(!epfile->dentry)) { | 1630 | if (unlikely(!epfile->dentry)) { |
@@ -1616,7 +1656,6 @@ static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count) | |||
1616 | kfree(epfiles); | 1656 | kfree(epfiles); |
1617 | } | 1657 | } |
1618 | 1658 | ||
1619 | |||
1620 | static void ffs_func_eps_disable(struct ffs_function *func) | 1659 | static void ffs_func_eps_disable(struct ffs_function *func) |
1621 | { | 1660 | { |
1622 | struct ffs_ep *ep = func->eps; | 1661 | struct ffs_ep *ep = func->eps; |
@@ -1629,10 +1668,12 @@ static void ffs_func_eps_disable(struct ffs_function *func) | |||
1629 | /* pending requests get nuked */ | 1668 | /* pending requests get nuked */ |
1630 | if (likely(ep->ep)) | 1669 | if (likely(ep->ep)) |
1631 | usb_ep_disable(ep->ep); | 1670 | usb_ep_disable(ep->ep); |
1632 | epfile->ep = NULL; | ||
1633 | |||
1634 | ++ep; | 1671 | ++ep; |
1635 | ++epfile; | 1672 | |
1673 | if (epfile) { | ||
1674 | epfile->ep = NULL; | ||
1675 | ++epfile; | ||
1676 | } | ||
1636 | } while (--count); | 1677 | } while (--count); |
1637 | spin_unlock_irqrestore(&func->ffs->eps_lock, flags); | 1678 | spin_unlock_irqrestore(&func->ffs->eps_lock, flags); |
1638 | } | 1679 | } |
@@ -2138,7 +2179,8 @@ static int __ffs_data_got_descs(struct ffs_data *ffs, | |||
2138 | FUNCTIONFS_HAS_HS_DESC | | 2179 | FUNCTIONFS_HAS_HS_DESC | |
2139 | FUNCTIONFS_HAS_SS_DESC | | 2180 | FUNCTIONFS_HAS_SS_DESC | |
2140 | FUNCTIONFS_HAS_MS_OS_DESC | | 2181 | FUNCTIONFS_HAS_MS_OS_DESC | |
2141 | FUNCTIONFS_VIRTUAL_ADDR)) { | 2182 | FUNCTIONFS_VIRTUAL_ADDR | |
2183 | FUNCTIONFS_EVENTFD)) { | ||
2142 | ret = -ENOSYS; | 2184 | ret = -ENOSYS; |
2143 | goto error; | 2185 | goto error; |
2144 | } | 2186 | } |
@@ -2149,6 +2191,20 @@ static int __ffs_data_got_descs(struct ffs_data *ffs, | |||
2149 | goto error; | 2191 | goto error; |
2150 | } | 2192 | } |
2151 | 2193 | ||
2194 | if (flags & FUNCTIONFS_EVENTFD) { | ||
2195 | if (len < 4) | ||
2196 | goto error; | ||
2197 | ffs->ffs_eventfd = | ||
2198 | eventfd_ctx_fdget((int)get_unaligned_le32(data)); | ||
2199 | if (IS_ERR(ffs->ffs_eventfd)) { | ||
2200 | ret = PTR_ERR(ffs->ffs_eventfd); | ||
2201 | ffs->ffs_eventfd = NULL; | ||
2202 | goto error; | ||
2203 | } | ||
2204 | data += 4; | ||
2205 | len -= 4; | ||
2206 | } | ||
2207 | |||
2152 | /* Read fs_count, hs_count and ss_count (if present) */ | 2208 | /* Read fs_count, hs_count and ss_count (if present) */ |
2153 | for (i = 0; i < 3; ++i) { | 2209 | for (i = 0; i < 3; ++i) { |
2154 | if (!(flags & (1 << i))) { | 2210 | if (!(flags & (1 << i))) { |
@@ -2377,6 +2433,13 @@ static void __ffs_event_add(struct ffs_data *ffs, | |||
2377 | if (ffs->setup_state == FFS_SETUP_PENDING) | 2433 | if (ffs->setup_state == FFS_SETUP_PENDING) |
2378 | ffs->setup_state = FFS_SETUP_CANCELLED; | 2434 | ffs->setup_state = FFS_SETUP_CANCELLED; |
2379 | 2435 | ||
2436 | /* | ||
2437 | * Logic of this function guarantees that there are at most four pending | ||
2438 | * evens on ffs->ev.types queue. This is important because the queue | ||
2439 | * has space for four elements only and __ffs_ep0_read_events function | ||
2440 | * depends on that limit as well. If more event types are added, those | ||
2441 | * limits have to be revisited or guaranteed to still hold. | ||
2442 | */ | ||
2380 | switch (type) { | 2443 | switch (type) { |
2381 | case FUNCTIONFS_RESUME: | 2444 | case FUNCTIONFS_RESUME: |
2382 | rem_type2 = FUNCTIONFS_SUSPEND; | 2445 | rem_type2 = FUNCTIONFS_SUSPEND; |
@@ -2416,6 +2479,8 @@ static void __ffs_event_add(struct ffs_data *ffs, | |||
2416 | pr_vdebug("adding event %d\n", type); | 2479 | pr_vdebug("adding event %d\n", type); |
2417 | ffs->ev.types[ffs->ev.count++] = type; | 2480 | ffs->ev.types[ffs->ev.count++] = type; |
2418 | wake_up_locked(&ffs->ev.waitq); | 2481 | wake_up_locked(&ffs->ev.waitq); |
2482 | if (ffs->ffs_eventfd) | ||
2483 | eventfd_signal(ffs->ffs_eventfd, 1); | ||
2419 | } | 2484 | } |
2420 | 2485 | ||
2421 | static void ffs_event_add(struct ffs_data *ffs, | 2486 | static void ffs_event_add(struct ffs_data *ffs, |
@@ -2888,6 +2953,13 @@ static int ffs_func_bind(struct usb_configuration *c, | |||
2888 | 2953 | ||
2889 | /* Other USB function hooks *************************************************/ | 2954 | /* Other USB function hooks *************************************************/ |
2890 | 2955 | ||
2956 | static void ffs_reset_work(struct work_struct *work) | ||
2957 | { | ||
2958 | struct ffs_data *ffs = container_of(work, | ||
2959 | struct ffs_data, reset_work); | ||
2960 | ffs_data_reset(ffs); | ||
2961 | } | ||
2962 | |||
2891 | static int ffs_func_set_alt(struct usb_function *f, | 2963 | static int ffs_func_set_alt(struct usb_function *f, |
2892 | unsigned interface, unsigned alt) | 2964 | unsigned interface, unsigned alt) |
2893 | { | 2965 | { |
@@ -2904,6 +2976,13 @@ static int ffs_func_set_alt(struct usb_function *f, | |||
2904 | if (ffs->func) | 2976 | if (ffs->func) |
2905 | ffs_func_eps_disable(ffs->func); | 2977 | ffs_func_eps_disable(ffs->func); |
2906 | 2978 | ||
2979 | if (ffs->state == FFS_DEACTIVATED) { | ||
2980 | ffs->state = FFS_CLOSING; | ||
2981 | INIT_WORK(&ffs->reset_work, ffs_reset_work); | ||
2982 | schedule_work(&ffs->reset_work); | ||
2983 | return -ENODEV; | ||
2984 | } | ||
2985 | |||
2907 | if (ffs->state != FFS_ACTIVE) | 2986 | if (ffs->state != FFS_ACTIVE) |
2908 | return -ENODEV; | 2987 | return -ENODEV; |
2909 | 2988 | ||
diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index a1bc3e3a0b09..426d69a9c018 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c | |||
@@ -759,7 +759,7 @@ static struct f_hid_opts_attribute f_hid_opts_##name = \ | |||
759 | 759 | ||
760 | F_HID_OPT(subclass, 8, 255); | 760 | F_HID_OPT(subclass, 8, 255); |
761 | F_HID_OPT(protocol, 8, 255); | 761 | F_HID_OPT(protocol, 8, 255); |
762 | F_HID_OPT(report_length, 16, 65536); | 762 | F_HID_OPT(report_length, 16, 65535); |
763 | 763 | ||
764 | static ssize_t f_hid_opts_report_desc_show(struct f_hid_opts *opts, char *page) | 764 | static ssize_t f_hid_opts_report_desc_show(struct f_hid_opts *opts, char *page) |
765 | { | 765 | { |
diff --git a/drivers/usb/gadget/function/f_sourcesink.c b/drivers/usb/gadget/function/f_sourcesink.c index 80be25b32cd7..e07c50ced64d 100644 --- a/drivers/usb/gadget/function/f_sourcesink.c +++ b/drivers/usb/gadget/function/f_sourcesink.c | |||
@@ -1214,7 +1214,7 @@ static ssize_t f_ss_opts_pattern_show(struct f_ss_opts *opts, char *page) | |||
1214 | int result; | 1214 | int result; |
1215 | 1215 | ||
1216 | mutex_lock(&opts->lock); | 1216 | mutex_lock(&opts->lock); |
1217 | result = sprintf(page, "%d", opts->pattern); | 1217 | result = sprintf(page, "%u", opts->pattern); |
1218 | mutex_unlock(&opts->lock); | 1218 | mutex_unlock(&opts->lock); |
1219 | 1219 | ||
1220 | return result; | 1220 | return result; |
@@ -1258,7 +1258,7 @@ static ssize_t f_ss_opts_isoc_interval_show(struct f_ss_opts *opts, char *page) | |||
1258 | int result; | 1258 | int result; |
1259 | 1259 | ||
1260 | mutex_lock(&opts->lock); | 1260 | mutex_lock(&opts->lock); |
1261 | result = sprintf(page, "%d", opts->isoc_interval); | 1261 | result = sprintf(page, "%u", opts->isoc_interval); |
1262 | mutex_unlock(&opts->lock); | 1262 | mutex_unlock(&opts->lock); |
1263 | 1263 | ||
1264 | return result; | 1264 | return result; |
@@ -1302,7 +1302,7 @@ static ssize_t f_ss_opts_isoc_maxpacket_show(struct f_ss_opts *opts, char *page) | |||
1302 | int result; | 1302 | int result; |
1303 | 1303 | ||
1304 | mutex_lock(&opts->lock); | 1304 | mutex_lock(&opts->lock); |
1305 | result = sprintf(page, "%d", opts->isoc_maxpacket); | 1305 | result = sprintf(page, "%u", opts->isoc_maxpacket); |
1306 | mutex_unlock(&opts->lock); | 1306 | mutex_unlock(&opts->lock); |
1307 | 1307 | ||
1308 | return result; | 1308 | return result; |
@@ -1346,7 +1346,7 @@ static ssize_t f_ss_opts_isoc_mult_show(struct f_ss_opts *opts, char *page) | |||
1346 | int result; | 1346 | int result; |
1347 | 1347 | ||
1348 | mutex_lock(&opts->lock); | 1348 | mutex_lock(&opts->lock); |
1349 | result = sprintf(page, "%d", opts->isoc_mult); | 1349 | result = sprintf(page, "%u", opts->isoc_mult); |
1350 | mutex_unlock(&opts->lock); | 1350 | mutex_unlock(&opts->lock); |
1351 | 1351 | ||
1352 | return result; | 1352 | return result; |
@@ -1390,7 +1390,7 @@ static ssize_t f_ss_opts_isoc_maxburst_show(struct f_ss_opts *opts, char *page) | |||
1390 | int result; | 1390 | int result; |
1391 | 1391 | ||
1392 | mutex_lock(&opts->lock); | 1392 | mutex_lock(&opts->lock); |
1393 | result = sprintf(page, "%d", opts->isoc_maxburst); | 1393 | result = sprintf(page, "%u", opts->isoc_maxburst); |
1394 | mutex_unlock(&opts->lock); | 1394 | mutex_unlock(&opts->lock); |
1395 | 1395 | ||
1396 | return result; | 1396 | return result; |
@@ -1434,7 +1434,7 @@ static ssize_t f_ss_opts_bulk_buflen_show(struct f_ss_opts *opts, char *page) | |||
1434 | int result; | 1434 | int result; |
1435 | 1435 | ||
1436 | mutex_lock(&opts->lock); | 1436 | mutex_lock(&opts->lock); |
1437 | result = sprintf(page, "%d", opts->bulk_buflen); | 1437 | result = sprintf(page, "%u", opts->bulk_buflen); |
1438 | mutex_unlock(&opts->lock); | 1438 | mutex_unlock(&opts->lock); |
1439 | 1439 | ||
1440 | return result; | 1440 | return result; |
@@ -1473,7 +1473,7 @@ static ssize_t f_ss_opts_int_interval_show(struct f_ss_opts *opts, char *page) | |||
1473 | int result; | 1473 | int result; |
1474 | 1474 | ||
1475 | mutex_lock(&opts->lock); | 1475 | mutex_lock(&opts->lock); |
1476 | result = sprintf(page, "%d", opts->int_interval); | 1476 | result = sprintf(page, "%u", opts->int_interval); |
1477 | mutex_unlock(&opts->lock); | 1477 | mutex_unlock(&opts->lock); |
1478 | 1478 | ||
1479 | return result; | 1479 | return result; |
@@ -1517,7 +1517,7 @@ static ssize_t f_ss_opts_int_maxpacket_show(struct f_ss_opts *opts, char *page) | |||
1517 | int result; | 1517 | int result; |
1518 | 1518 | ||
1519 | mutex_lock(&opts->lock); | 1519 | mutex_lock(&opts->lock); |
1520 | result = sprintf(page, "%d", opts->int_maxpacket); | 1520 | result = sprintf(page, "%u", opts->int_maxpacket); |
1521 | mutex_unlock(&opts->lock); | 1521 | mutex_unlock(&opts->lock); |
1522 | 1522 | ||
1523 | return result; | 1523 | return result; |
@@ -1561,7 +1561,7 @@ static ssize_t f_ss_opts_int_mult_show(struct f_ss_opts *opts, char *page) | |||
1561 | int result; | 1561 | int result; |
1562 | 1562 | ||
1563 | mutex_lock(&opts->lock); | 1563 | mutex_lock(&opts->lock); |
1564 | result = sprintf(page, "%d", opts->int_mult); | 1564 | result = sprintf(page, "%u", opts->int_mult); |
1565 | mutex_unlock(&opts->lock); | 1565 | mutex_unlock(&opts->lock); |
1566 | 1566 | ||
1567 | return result; | 1567 | return result; |
@@ -1605,7 +1605,7 @@ static ssize_t f_ss_opts_int_maxburst_show(struct f_ss_opts *opts, char *page) | |||
1605 | int result; | 1605 | int result; |
1606 | 1606 | ||
1607 | mutex_lock(&opts->lock); | 1607 | mutex_lock(&opts->lock); |
1608 | result = sprintf(page, "%d", opts->int_maxburst); | 1608 | result = sprintf(page, "%u", opts->int_maxburst); |
1609 | mutex_unlock(&opts->lock); | 1609 | mutex_unlock(&opts->lock); |
1610 | 1610 | ||
1611 | return result; | 1611 | return result; |
diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index e9715845f82e..9719abfb6145 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c | |||
@@ -31,7 +31,7 @@ static int generic_get_cmd(struct usb_audio_control *con, u8 cmd); | |||
31 | */ | 31 | */ |
32 | #define F_AUDIO_AC_INTERFACE 0 | 32 | #define F_AUDIO_AC_INTERFACE 0 |
33 | #define F_AUDIO_AS_INTERFACE 1 | 33 | #define F_AUDIO_AS_INTERFACE 1 |
34 | #define F_AUDIO_NUM_INTERFACES 2 | 34 | #define F_AUDIO_NUM_INTERFACES 1 |
35 | 35 | ||
36 | /* B.3.1 Standard AC Interface Descriptor */ | 36 | /* B.3.1 Standard AC Interface Descriptor */ |
37 | static struct usb_interface_descriptor ac_interface_desc = { | 37 | static struct usb_interface_descriptor ac_interface_desc = { |
@@ -42,14 +42,18 @@ static struct usb_interface_descriptor ac_interface_desc = { | |||
42 | .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, | 42 | .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, |
43 | }; | 43 | }; |
44 | 44 | ||
45 | DECLARE_UAC_AC_HEADER_DESCRIPTOR(2); | 45 | /* |
46 | * The number of AudioStreaming and MIDIStreaming interfaces | ||
47 | * in the Audio Interface Collection | ||
48 | */ | ||
49 | DECLARE_UAC_AC_HEADER_DESCRIPTOR(1); | ||
46 | 50 | ||
47 | #define UAC_DT_AC_HEADER_LENGTH UAC_DT_AC_HEADER_SIZE(F_AUDIO_NUM_INTERFACES) | 51 | #define UAC_DT_AC_HEADER_LENGTH UAC_DT_AC_HEADER_SIZE(F_AUDIO_NUM_INTERFACES) |
48 | /* 1 input terminal, 1 output terminal and 1 feature unit */ | 52 | /* 1 input terminal, 1 output terminal and 1 feature unit */ |
49 | #define UAC_DT_TOTAL_LENGTH (UAC_DT_AC_HEADER_LENGTH + UAC_DT_INPUT_TERMINAL_SIZE \ | 53 | #define UAC_DT_TOTAL_LENGTH (UAC_DT_AC_HEADER_LENGTH + UAC_DT_INPUT_TERMINAL_SIZE \ |
50 | + UAC_DT_OUTPUT_TERMINAL_SIZE + UAC_DT_FEATURE_UNIT_SIZE(0)) | 54 | + UAC_DT_OUTPUT_TERMINAL_SIZE + UAC_DT_FEATURE_UNIT_SIZE(0)) |
51 | /* B.3.2 Class-Specific AC Interface Descriptor */ | 55 | /* B.3.2 Class-Specific AC Interface Descriptor */ |
52 | static struct uac1_ac_header_descriptor_2 ac_header_desc = { | 56 | static struct uac1_ac_header_descriptor_1 ac_header_desc = { |
53 | .bLength = UAC_DT_AC_HEADER_LENGTH, | 57 | .bLength = UAC_DT_AC_HEADER_LENGTH, |
54 | .bDescriptorType = USB_DT_CS_INTERFACE, | 58 | .bDescriptorType = USB_DT_CS_INTERFACE, |
55 | .bDescriptorSubtype = UAC_HEADER, | 59 | .bDescriptorSubtype = UAC_HEADER, |
@@ -57,8 +61,8 @@ static struct uac1_ac_header_descriptor_2 ac_header_desc = { | |||
57 | .wTotalLength = __constant_cpu_to_le16(UAC_DT_TOTAL_LENGTH), | 61 | .wTotalLength = __constant_cpu_to_le16(UAC_DT_TOTAL_LENGTH), |
58 | .bInCollection = F_AUDIO_NUM_INTERFACES, | 62 | .bInCollection = F_AUDIO_NUM_INTERFACES, |
59 | .baInterfaceNr = { | 63 | .baInterfaceNr = { |
60 | [0] = F_AUDIO_AC_INTERFACE, | 64 | /* Interface number of the first AudioStream interface */ |
61 | [1] = F_AUDIO_AS_INTERFACE, | 65 | [0] = 1, |
62 | } | 66 | } |
63 | }; | 67 | }; |
64 | 68 | ||
@@ -584,6 +588,7 @@ static int f_audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt) | |||
584 | 588 | ||
585 | if (intf == 1) { | 589 | if (intf == 1) { |
586 | if (alt == 1) { | 590 | if (alt == 1) { |
591 | config_ep_by_speed(cdev->gadget, f, out_ep); | ||
587 | usb_ep_enable(out_ep); | 592 | usb_ep_enable(out_ep); |
588 | out_ep->driver_data = audio; | 593 | out_ep->driver_data = audio; |
589 | audio->copy_buf = f_audio_buffer_alloc(audio_buf_size); | 594 | audio->copy_buf = f_audio_buffer_alloc(audio_buf_size); |
@@ -669,7 +674,6 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f) | |||
669 | 674 | ||
670 | audio_opts = container_of(f->fi, struct f_uac1_opts, func_inst); | 675 | audio_opts = container_of(f->fi, struct f_uac1_opts, func_inst); |
671 | audio->card.gadget = c->cdev->gadget; | 676 | audio->card.gadget = c->cdev->gadget; |
672 | audio_opts->card = &audio->card; | ||
673 | /* set up ASLA audio devices */ | 677 | /* set up ASLA audio devices */ |
674 | if (!audio_opts->bound) { | 678 | if (!audio_opts->bound) { |
675 | status = gaudio_setup(&audio->card); | 679 | status = gaudio_setup(&audio->card); |
diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index 945b3bd2ca98..76891adfba7a 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c | |||
@@ -27,10 +27,11 @@ | |||
27 | #include <media/v4l2-dev.h> | 27 | #include <media/v4l2-dev.h> |
28 | #include <media/v4l2-event.h> | 28 | #include <media/v4l2-event.h> |
29 | 29 | ||
30 | #include "u_uvc.h" | ||
30 | #include "uvc.h" | 31 | #include "uvc.h" |
32 | #include "uvc_configfs.h" | ||
31 | #include "uvc_v4l2.h" | 33 | #include "uvc_v4l2.h" |
32 | #include "uvc_video.h" | 34 | #include "uvc_video.h" |
33 | #include "u_uvc.h" | ||
34 | 35 | ||
35 | unsigned int uvc_gadget_trace_param; | 36 | unsigned int uvc_gadget_trace_param; |
36 | 37 | ||
@@ -509,6 +510,9 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed) | |||
509 | break; | 510 | break; |
510 | } | 511 | } |
511 | 512 | ||
513 | if (!uvc_control_desc || !uvc_streaming_cls) | ||
514 | return ERR_PTR(-ENODEV); | ||
515 | |||
512 | /* Descriptors layout | 516 | /* Descriptors layout |
513 | * | 517 | * |
514 | * uvc_iad | 518 | * uvc_iad |
@@ -605,7 +609,7 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) | |||
605 | 609 | ||
606 | INFO(cdev, "uvc_function_bind\n"); | 610 | INFO(cdev, "uvc_function_bind\n"); |
607 | 611 | ||
608 | opts = to_f_uvc_opts(f->fi); | 612 | opts = fi_to_f_uvc_opts(f->fi); |
609 | /* Sanity check the streaming endpoint module parameters. | 613 | /* Sanity check the streaming endpoint module parameters. |
610 | */ | 614 | */ |
611 | opts->streaming_interval = clamp(opts->streaming_interval, 1U, 16U); | 615 | opts->streaming_interval = clamp(opts->streaming_interval, 1U, 16U); |
@@ -700,10 +704,27 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) | |||
700 | 704 | ||
701 | /* Copy descriptors */ | 705 | /* Copy descriptors */ |
702 | f->fs_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_FULL); | 706 | f->fs_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_FULL); |
703 | if (gadget_is_dualspeed(cdev->gadget)) | 707 | if (IS_ERR(f->fs_descriptors)) { |
708 | ret = PTR_ERR(f->fs_descriptors); | ||
709 | f->fs_descriptors = NULL; | ||
710 | goto error; | ||
711 | } | ||
712 | if (gadget_is_dualspeed(cdev->gadget)) { | ||
704 | f->hs_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_HIGH); | 713 | f->hs_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_HIGH); |
705 | if (gadget_is_superspeed(c->cdev->gadget)) | 714 | if (IS_ERR(f->hs_descriptors)) { |
715 | ret = PTR_ERR(f->hs_descriptors); | ||
716 | f->hs_descriptors = NULL; | ||
717 | goto error; | ||
718 | } | ||
719 | } | ||
720 | if (gadget_is_superspeed(c->cdev->gadget)) { | ||
706 | f->ss_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_SUPER); | 721 | f->ss_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_SUPER); |
722 | if (IS_ERR(f->ss_descriptors)) { | ||
723 | ret = PTR_ERR(f->ss_descriptors); | ||
724 | f->ss_descriptors = NULL; | ||
725 | goto error; | ||
726 | } | ||
727 | } | ||
707 | 728 | ||
708 | /* Preallocate control endpoint request. */ | 729 | /* Preallocate control endpoint request. */ |
709 | uvc->control_req = usb_ep_alloc_request(cdev->gadget->ep0, GFP_KERNEL); | 730 | uvc->control_req = usb_ep_alloc_request(cdev->gadget->ep0, GFP_KERNEL); |
@@ -766,27 +787,106 @@ error: | |||
766 | 787 | ||
767 | static void uvc_free_inst(struct usb_function_instance *f) | 788 | static void uvc_free_inst(struct usb_function_instance *f) |
768 | { | 789 | { |
769 | struct f_uvc_opts *opts = to_f_uvc_opts(f); | 790 | struct f_uvc_opts *opts = fi_to_f_uvc_opts(f); |
770 | 791 | ||
792 | mutex_destroy(&opts->lock); | ||
771 | kfree(opts); | 793 | kfree(opts); |
772 | } | 794 | } |
773 | 795 | ||
774 | static struct usb_function_instance *uvc_alloc_inst(void) | 796 | static struct usb_function_instance *uvc_alloc_inst(void) |
775 | { | 797 | { |
776 | struct f_uvc_opts *opts; | 798 | struct f_uvc_opts *opts; |
799 | struct uvc_camera_terminal_descriptor *cd; | ||
800 | struct uvc_processing_unit_descriptor *pd; | ||
801 | struct uvc_output_terminal_descriptor *od; | ||
802 | struct uvc_color_matching_descriptor *md; | ||
803 | struct uvc_descriptor_header **ctl_cls; | ||
777 | 804 | ||
778 | opts = kzalloc(sizeof(*opts), GFP_KERNEL); | 805 | opts = kzalloc(sizeof(*opts), GFP_KERNEL); |
779 | if (!opts) | 806 | if (!opts) |
780 | return ERR_PTR(-ENOMEM); | 807 | return ERR_PTR(-ENOMEM); |
781 | opts->func_inst.free_func_inst = uvc_free_inst; | 808 | opts->func_inst.free_func_inst = uvc_free_inst; |
782 | 809 | mutex_init(&opts->lock); | |
810 | |||
811 | cd = &opts->uvc_camera_terminal; | ||
812 | cd->bLength = UVC_DT_CAMERA_TERMINAL_SIZE(3); | ||
813 | cd->bDescriptorType = USB_DT_CS_INTERFACE; | ||
814 | cd->bDescriptorSubType = UVC_VC_INPUT_TERMINAL; | ||
815 | cd->bTerminalID = 1; | ||
816 | cd->wTerminalType = cpu_to_le16(0x0201); | ||
817 | cd->bAssocTerminal = 0; | ||
818 | cd->iTerminal = 0; | ||
819 | cd->wObjectiveFocalLengthMin = cpu_to_le16(0); | ||
820 | cd->wObjectiveFocalLengthMax = cpu_to_le16(0); | ||
821 | cd->wOcularFocalLength = cpu_to_le16(0); | ||
822 | cd->bControlSize = 3; | ||
823 | cd->bmControls[0] = 2; | ||
824 | cd->bmControls[1] = 0; | ||
825 | cd->bmControls[2] = 0; | ||
826 | |||
827 | pd = &opts->uvc_processing; | ||
828 | pd->bLength = UVC_DT_PROCESSING_UNIT_SIZE(2); | ||
829 | pd->bDescriptorType = USB_DT_CS_INTERFACE; | ||
830 | pd->bDescriptorSubType = UVC_VC_PROCESSING_UNIT; | ||
831 | pd->bUnitID = 2; | ||
832 | pd->bSourceID = 1; | ||
833 | pd->wMaxMultiplier = cpu_to_le16(16*1024); | ||
834 | pd->bControlSize = 2; | ||
835 | pd->bmControls[0] = 1; | ||
836 | pd->bmControls[1] = 0; | ||
837 | pd->iProcessing = 0; | ||
838 | |||
839 | od = &opts->uvc_output_terminal; | ||
840 | od->bLength = UVC_DT_OUTPUT_TERMINAL_SIZE; | ||
841 | od->bDescriptorType = USB_DT_CS_INTERFACE; | ||
842 | od->bDescriptorSubType = UVC_VC_OUTPUT_TERMINAL; | ||
843 | od->bTerminalID = 3; | ||
844 | od->wTerminalType = cpu_to_le16(0x0101); | ||
845 | od->bAssocTerminal = 0; | ||
846 | od->bSourceID = 2; | ||
847 | od->iTerminal = 0; | ||
848 | |||
849 | md = &opts->uvc_color_matching; | ||
850 | md->bLength = UVC_DT_COLOR_MATCHING_SIZE; | ||
851 | md->bDescriptorType = USB_DT_CS_INTERFACE; | ||
852 | md->bDescriptorSubType = UVC_VS_COLORFORMAT; | ||
853 | md->bColorPrimaries = 1; | ||
854 | md->bTransferCharacteristics = 1; | ||
855 | md->bMatrixCoefficients = 4; | ||
856 | |||
857 | /* Prepare fs control class descriptors for configfs-based gadgets */ | ||
858 | ctl_cls = opts->uvc_fs_control_cls; | ||
859 | ctl_cls[0] = NULL; /* assigned elsewhere by configfs */ | ||
860 | ctl_cls[1] = (struct uvc_descriptor_header *)cd; | ||
861 | ctl_cls[2] = (struct uvc_descriptor_header *)pd; | ||
862 | ctl_cls[3] = (struct uvc_descriptor_header *)od; | ||
863 | ctl_cls[4] = NULL; /* NULL-terminate */ | ||
864 | opts->fs_control = | ||
865 | (const struct uvc_descriptor_header * const *)ctl_cls; | ||
866 | |||
867 | /* Prepare hs control class descriptors for configfs-based gadgets */ | ||
868 | ctl_cls = opts->uvc_ss_control_cls; | ||
869 | ctl_cls[0] = NULL; /* assigned elsewhere by configfs */ | ||
870 | ctl_cls[1] = (struct uvc_descriptor_header *)cd; | ||
871 | ctl_cls[2] = (struct uvc_descriptor_header *)pd; | ||
872 | ctl_cls[3] = (struct uvc_descriptor_header *)od; | ||
873 | ctl_cls[4] = NULL; /* NULL-terminate */ | ||
874 | opts->ss_control = | ||
875 | (const struct uvc_descriptor_header * const *)ctl_cls; | ||
876 | |||
877 | opts->streaming_interval = 1; | ||
878 | opts->streaming_maxpacket = 1024; | ||
879 | |||
880 | uvcg_attach_configfs(opts); | ||
783 | return &opts->func_inst; | 881 | return &opts->func_inst; |
784 | } | 882 | } |
785 | 883 | ||
786 | static void uvc_free(struct usb_function *f) | 884 | static void uvc_free(struct usb_function *f) |
787 | { | 885 | { |
788 | struct uvc_device *uvc = to_uvc(f); | 886 | struct uvc_device *uvc = to_uvc(f); |
789 | 887 | struct f_uvc_opts *opts = container_of(f->fi, struct f_uvc_opts, | |
888 | func_inst); | ||
889 | --opts->refcnt; | ||
790 | kfree(uvc); | 890 | kfree(uvc); |
791 | } | 891 | } |
792 | 892 | ||
@@ -812,19 +912,39 @@ static struct usb_function *uvc_alloc(struct usb_function_instance *fi) | |||
812 | { | 912 | { |
813 | struct uvc_device *uvc; | 913 | struct uvc_device *uvc; |
814 | struct f_uvc_opts *opts; | 914 | struct f_uvc_opts *opts; |
915 | struct uvc_descriptor_header **strm_cls; | ||
815 | 916 | ||
816 | uvc = kzalloc(sizeof(*uvc), GFP_KERNEL); | 917 | uvc = kzalloc(sizeof(*uvc), GFP_KERNEL); |
817 | if (uvc == NULL) | 918 | if (uvc == NULL) |
818 | return ERR_PTR(-ENOMEM); | 919 | return ERR_PTR(-ENOMEM); |
819 | 920 | ||
820 | uvc->state = UVC_STATE_DISCONNECTED; | 921 | uvc->state = UVC_STATE_DISCONNECTED; |
821 | opts = to_f_uvc_opts(fi); | 922 | opts = fi_to_f_uvc_opts(fi); |
923 | |||
924 | mutex_lock(&opts->lock); | ||
925 | if (opts->uvc_fs_streaming_cls) { | ||
926 | strm_cls = opts->uvc_fs_streaming_cls; | ||
927 | opts->fs_streaming = | ||
928 | (const struct uvc_descriptor_header * const *)strm_cls; | ||
929 | } | ||
930 | if (opts->uvc_hs_streaming_cls) { | ||
931 | strm_cls = opts->uvc_hs_streaming_cls; | ||
932 | opts->hs_streaming = | ||
933 | (const struct uvc_descriptor_header * const *)strm_cls; | ||
934 | } | ||
935 | if (opts->uvc_ss_streaming_cls) { | ||
936 | strm_cls = opts->uvc_ss_streaming_cls; | ||
937 | opts->ss_streaming = | ||
938 | (const struct uvc_descriptor_header * const *)strm_cls; | ||
939 | } | ||
822 | 940 | ||
823 | uvc->desc.fs_control = opts->fs_control; | 941 | uvc->desc.fs_control = opts->fs_control; |
824 | uvc->desc.ss_control = opts->ss_control; | 942 | uvc->desc.ss_control = opts->ss_control; |
825 | uvc->desc.fs_streaming = opts->fs_streaming; | 943 | uvc->desc.fs_streaming = opts->fs_streaming; |
826 | uvc->desc.hs_streaming = opts->hs_streaming; | 944 | uvc->desc.hs_streaming = opts->hs_streaming; |
827 | uvc->desc.ss_streaming = opts->ss_streaming; | 945 | uvc->desc.ss_streaming = opts->ss_streaming; |
946 | ++opts->refcnt; | ||
947 | mutex_unlock(&opts->lock); | ||
828 | 948 | ||
829 | /* Register the function. */ | 949 | /* Register the function. */ |
830 | uvc->func.name = "uvc"; | 950 | uvc->func.name = "uvc"; |
diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c index 6e6f87656e7b..f1fd777ef4ec 100644 --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c | |||
@@ -729,9 +729,7 @@ static int get_ether_addr_str(u8 dev_addr[ETH_ALEN], char *str, int len) | |||
729 | if (len < 18) | 729 | if (len < 18) |
730 | return -EINVAL; | 730 | return -EINVAL; |
731 | 731 | ||
732 | snprintf(str, len, "%02x:%02x:%02x:%02x:%02x:%02x", | 732 | snprintf(str, len, "%pM", dev_addr); |
733 | dev_addr[0], dev_addr[1], dev_addr[2], | ||
734 | dev_addr[3], dev_addr[4], dev_addr[5]); | ||
735 | return 18; | 733 | return 18; |
736 | } | 734 | } |
737 | 735 | ||
diff --git a/drivers/usb/gadget/function/u_fs.h b/drivers/usb/gadget/function/u_fs.h index cd128e31f808..60139854e0b1 100644 --- a/drivers/usb/gadget/function/u_fs.h +++ b/drivers/usb/gadget/function/u_fs.h | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/usb/composite.h> | 19 | #include <linux/usb/composite.h> |
20 | #include <linux/list.h> | 20 | #include <linux/list.h> |
21 | #include <linux/mutex.h> | 21 | #include <linux/mutex.h> |
22 | #include <linux/workqueue.h> | ||
22 | 23 | ||
23 | #ifdef VERBOSE_DEBUG | 24 | #ifdef VERBOSE_DEBUG |
24 | #ifndef pr_vdebug | 25 | #ifndef pr_vdebug |
@@ -93,6 +94,26 @@ enum ffs_state { | |||
93 | FFS_ACTIVE, | 94 | FFS_ACTIVE, |
94 | 95 | ||
95 | /* | 96 | /* |
97 | * Function is visible to host, but it's not functional. All | ||
98 | * setup requests are stalled and transfers on another endpoints | ||
99 | * are refused. All epfiles, except ep0, are deleted so there | ||
100 | * is no way to perform any operations on them. | ||
101 | * | ||
102 | * This state is set after closing all functionfs files, when | ||
103 | * mount parameter "no_disconnect=1" has been set. Function will | ||
104 | * remain in deactivated state until filesystem is umounted or | ||
105 | * ep0 is opened again. In the second case functionfs state will | ||
106 | * be reset, and it will be ready for descriptors and strings | ||
107 | * writing. | ||
108 | * | ||
109 | * This is useful only when functionfs is composed to gadget | ||
110 | * with another function which can perform some critical | ||
111 | * operations, and it's strongly desired to have this operations | ||
112 | * completed, even after functionfs files closure. | ||
113 | */ | ||
114 | FFS_DEACTIVATED, | ||
115 | |||
116 | /* | ||
96 | * All endpoints have been closed. This state is also set if | 117 | * All endpoints have been closed. This state is also set if |
97 | * we encounter an unrecoverable error. The only | 118 | * we encounter an unrecoverable error. The only |
98 | * unrecoverable error is situation when after reading strings | 119 | * unrecoverable error is situation when after reading strings |
@@ -251,6 +272,10 @@ struct ffs_data { | |||
251 | kgid_t gid; | 272 | kgid_t gid; |
252 | } file_perms; | 273 | } file_perms; |
253 | 274 | ||
275 | struct eventfd_ctx *ffs_eventfd; | ||
276 | bool no_disconnect; | ||
277 | struct work_struct reset_work; | ||
278 | |||
254 | /* | 279 | /* |
255 | * The endpoint files, filled by ffs_epfiles_create(), | 280 | * The endpoint files, filled by ffs_epfiles_create(), |
256 | * destroyed by ffs_epfiles_destroy(). | 281 | * destroyed by ffs_epfiles_destroy(). |
diff --git a/drivers/usb/gadget/function/u_uac1.c b/drivers/usb/gadget/function/u_uac1.c index 53842a1b947f..c78c84138a28 100644 --- a/drivers/usb/gadget/function/u_uac1.c +++ b/drivers/usb/gadget/function/u_uac1.c | |||
@@ -308,8 +308,7 @@ int gaudio_setup(struct gaudio *card) | |||
308 | */ | 308 | */ |
309 | void gaudio_cleanup(struct gaudio *the_card) | 309 | void gaudio_cleanup(struct gaudio *the_card) |
310 | { | 310 | { |
311 | if (the_card) { | 311 | if (the_card) |
312 | gaudio_close_snd_dev(the_card); | 312 | gaudio_close_snd_dev(the_card); |
313 | } | ||
314 | } | 313 | } |
315 | 314 | ||
diff --git a/drivers/usb/gadget/function/u_uac1.h b/drivers/usb/gadget/function/u_uac1.h index f8b17fe82efe..fe386df6dd3e 100644 --- a/drivers/usb/gadget/function/u_uac1.h +++ b/drivers/usb/gadget/function/u_uac1.h | |||
@@ -70,7 +70,6 @@ struct f_uac1_opts { | |||
70 | unsigned fn_play_alloc:1; | 70 | unsigned fn_play_alloc:1; |
71 | unsigned fn_cap_alloc:1; | 71 | unsigned fn_cap_alloc:1; |
72 | unsigned fn_cntl_alloc:1; | 72 | unsigned fn_cntl_alloc:1; |
73 | struct gaudio *card; | ||
74 | struct mutex lock; | 73 | struct mutex lock; |
75 | int refcnt; | 74 | int refcnt; |
76 | }; | 75 | }; |
diff --git a/drivers/usb/gadget/function/u_uvc.h b/drivers/usb/gadget/function/u_uvc.h index 2a8dfdff0332..4676b60a5063 100644 --- a/drivers/usb/gadget/function/u_uvc.h +++ b/drivers/usb/gadget/function/u_uvc.h | |||
@@ -17,8 +17,9 @@ | |||
17 | #define U_UVC_H | 17 | #define U_UVC_H |
18 | 18 | ||
19 | #include <linux/usb/composite.h> | 19 | #include <linux/usb/composite.h> |
20 | #include <linux/usb/video.h> | ||
20 | 21 | ||
21 | #define to_f_uvc_opts(f) container_of(f, struct f_uvc_opts, func_inst) | 22 | #define fi_to_f_uvc_opts(f) container_of(f, struct f_uvc_opts, func_inst) |
22 | 23 | ||
23 | struct f_uvc_opts { | 24 | struct f_uvc_opts { |
24 | struct usb_function_instance func_inst; | 25 | struct usb_function_instance func_inst; |
@@ -26,11 +27,60 @@ struct f_uvc_opts { | |||
26 | unsigned int streaming_interval; | 27 | unsigned int streaming_interval; |
27 | unsigned int streaming_maxpacket; | 28 | unsigned int streaming_maxpacket; |
28 | unsigned int streaming_maxburst; | 29 | unsigned int streaming_maxburst; |
30 | |||
31 | /* | ||
32 | * Control descriptors array pointers for full-/high-speed and | ||
33 | * super-speed. They point by default to the uvc_fs_control_cls and | ||
34 | * uvc_ss_control_cls arrays respectively. Legacy gadgets must | ||
35 | * override them in their gadget bind callback. | ||
36 | */ | ||
29 | const struct uvc_descriptor_header * const *fs_control; | 37 | const struct uvc_descriptor_header * const *fs_control; |
30 | const struct uvc_descriptor_header * const *ss_control; | 38 | const struct uvc_descriptor_header * const *ss_control; |
39 | |||
40 | /* | ||
41 | * Streaming descriptors array pointers for full-speed, high-speed and | ||
42 | * super-speed. They will point to the uvc_[fhs]s_streaming_cls arrays | ||
43 | * for configfs-based gadgets. Legacy gadgets must initialize them in | ||
44 | * their gadget bind callback. | ||
45 | */ | ||
31 | const struct uvc_descriptor_header * const *fs_streaming; | 46 | const struct uvc_descriptor_header * const *fs_streaming; |
32 | const struct uvc_descriptor_header * const *hs_streaming; | 47 | const struct uvc_descriptor_header * const *hs_streaming; |
33 | const struct uvc_descriptor_header * const *ss_streaming; | 48 | const struct uvc_descriptor_header * const *ss_streaming; |
49 | |||
50 | /* Default control descriptors for configfs-based gadgets. */ | ||
51 | struct uvc_camera_terminal_descriptor uvc_camera_terminal; | ||
52 | struct uvc_processing_unit_descriptor uvc_processing; | ||
53 | struct uvc_output_terminal_descriptor uvc_output_terminal; | ||
54 | struct uvc_color_matching_descriptor uvc_color_matching; | ||
55 | |||
56 | /* | ||
57 | * Control descriptors pointers arrays for full-/high-speed and | ||
58 | * super-speed. The first element is a configurable control header | ||
59 | * descriptor, the other elements point to the fixed default control | ||
60 | * descriptors. Used by configfs only, must not be touched by legacy | ||
61 | * gadgets. | ||
62 | */ | ||
63 | struct uvc_descriptor_header *uvc_fs_control_cls[5]; | ||
64 | struct uvc_descriptor_header *uvc_ss_control_cls[5]; | ||
65 | |||
66 | /* | ||
67 | * Streaming descriptors for full-speed, high-speed and super-speed. | ||
68 | * Used by configfs only, must not be touched by legacy gadgets. The | ||
69 | * arrays are allocated at runtime as the number of descriptors isn't | ||
70 | * known in advance. | ||
71 | */ | ||
72 | struct uvc_descriptor_header **uvc_fs_streaming_cls; | ||
73 | struct uvc_descriptor_header **uvc_hs_streaming_cls; | ||
74 | struct uvc_descriptor_header **uvc_ss_streaming_cls; | ||
75 | |||
76 | /* | ||
77 | * Read/write access to configfs attributes is handled by configfs. | ||
78 | * | ||
79 | * This lock protects the descriptors from concurrent access by | ||
80 | * read/write and symlink creation/removal. | ||
81 | */ | ||
82 | struct mutex lock; | ||
83 | int refcnt; | ||
34 | }; | 84 | }; |
35 | 85 | ||
36 | void uvc_set_trace_param(unsigned int trace); | 86 | void uvc_set_trace_param(unsigned int trace); |
diff --git a/drivers/usb/gadget/function/uvc_configfs.c b/drivers/usb/gadget/function/uvc_configfs.c new file mode 100644 index 000000000000..3c0467bcb14f --- /dev/null +++ b/drivers/usb/gadget/function/uvc_configfs.c | |||
@@ -0,0 +1,2468 @@ | |||
1 | /* | ||
2 | * uvc_configfs.c | ||
3 | * | ||
4 | * Configfs support for the uvc function. | ||
5 | * | ||
6 | * Copyright (c) 2014 Samsung Electronics Co., Ltd. | ||
7 | * http://www.samsung.com | ||
8 | * | ||
9 | * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * published by the Free Software Foundation. | ||
14 | */ | ||
15 | #include "u_uvc.h" | ||
16 | #include "uvc_configfs.h" | ||
17 | |||
18 | #define UVCG_STREAMING_CONTROL_SIZE 1 | ||
19 | |||
20 | #define CONFIGFS_ATTR_OPS_RO(_item) \ | ||
21 | static ssize_t _item##_attr_show(struct config_item *item, \ | ||
22 | struct configfs_attribute *attr, \ | ||
23 | char *page) \ | ||
24 | { \ | ||
25 | struct _item *_item = to_##_item(item); \ | ||
26 | struct _item##_attribute *_item##_attr = \ | ||
27 | container_of(attr, struct _item##_attribute, attr); \ | ||
28 | ssize_t ret = 0; \ | ||
29 | \ | ||
30 | if (_item##_attr->show) \ | ||
31 | ret = _item##_attr->show(_item, page); \ | ||
32 | return ret; \ | ||
33 | } | ||
34 | |||
35 | static inline struct f_uvc_opts *to_f_uvc_opts(struct config_item *item); | ||
36 | |||
37 | /* control/header/<NAME> */ | ||
38 | DECLARE_UVC_HEADER_DESCRIPTOR(1); | ||
39 | |||
40 | struct uvcg_control_header { | ||
41 | struct config_item item; | ||
42 | struct UVC_HEADER_DESCRIPTOR(1) desc; | ||
43 | unsigned linked; | ||
44 | }; | ||
45 | |||
46 | static struct uvcg_control_header *to_uvcg_control_header(struct config_item *item) | ||
47 | { | ||
48 | return container_of(item, struct uvcg_control_header, item); | ||
49 | } | ||
50 | |||
51 | CONFIGFS_ATTR_STRUCT(uvcg_control_header); | ||
52 | CONFIGFS_ATTR_OPS(uvcg_control_header); | ||
53 | |||
54 | static struct configfs_item_operations uvcg_control_header_item_ops = { | ||
55 | .show_attribute = uvcg_control_header_attr_show, | ||
56 | .store_attribute = uvcg_control_header_attr_store, | ||
57 | }; | ||
58 | |||
59 | #define UVCG_CTRL_HDR_ATTR(cname, aname, conv, str2u, uxx, vnoc, limit) \ | ||
60 | static ssize_t uvcg_control_header_##cname##_show( \ | ||
61 | struct uvcg_control_header *ch, char *page) \ | ||
62 | { \ | ||
63 | struct f_uvc_opts *opts; \ | ||
64 | struct config_item *opts_item; \ | ||
65 | struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex;\ | ||
66 | int result; \ | ||
67 | \ | ||
68 | mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ | ||
69 | \ | ||
70 | opts_item = ch->item.ci_parent->ci_parent->ci_parent; \ | ||
71 | opts = to_f_uvc_opts(opts_item); \ | ||
72 | \ | ||
73 | mutex_lock(&opts->lock); \ | ||
74 | result = sprintf(page, "%d\n", conv(ch->desc.aname)); \ | ||
75 | mutex_unlock(&opts->lock); \ | ||
76 | \ | ||
77 | mutex_unlock(su_mutex); \ | ||
78 | return result; \ | ||
79 | } \ | ||
80 | \ | ||
81 | static ssize_t \ | ||
82 | uvcg_control_header_##cname##_store(struct uvcg_control_header *ch, \ | ||
83 | const char *page, size_t len) \ | ||
84 | { \ | ||
85 | struct f_uvc_opts *opts; \ | ||
86 | struct config_item *opts_item; \ | ||
87 | struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex;\ | ||
88 | int ret; \ | ||
89 | uxx num; \ | ||
90 | \ | ||
91 | mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ | ||
92 | \ | ||
93 | opts_item = ch->item.ci_parent->ci_parent->ci_parent; \ | ||
94 | opts = to_f_uvc_opts(opts_item); \ | ||
95 | \ | ||
96 | mutex_lock(&opts->lock); \ | ||
97 | if (ch->linked || opts->refcnt) { \ | ||
98 | ret = -EBUSY; \ | ||
99 | goto end; \ | ||
100 | } \ | ||
101 | \ | ||
102 | ret = str2u(page, 0, &num); \ | ||
103 | if (ret) \ | ||
104 | goto end; \ | ||
105 | \ | ||
106 | if (num > limit) { \ | ||
107 | ret = -EINVAL; \ | ||
108 | goto end; \ | ||
109 | } \ | ||
110 | ch->desc.aname = vnoc(num); \ | ||
111 | ret = len; \ | ||
112 | end: \ | ||
113 | mutex_unlock(&opts->lock); \ | ||
114 | mutex_unlock(su_mutex); \ | ||
115 | return ret; \ | ||
116 | } \ | ||
117 | \ | ||
118 | static struct uvcg_control_header_attribute \ | ||
119 | uvcg_control_header_##cname = \ | ||
120 | __CONFIGFS_ATTR(aname, S_IRUGO | S_IWUSR, \ | ||
121 | uvcg_control_header_##cname##_show, \ | ||
122 | uvcg_control_header_##cname##_store) | ||
123 | |||
124 | UVCG_CTRL_HDR_ATTR(bcd_uvc, bcdUVC, le16_to_cpu, kstrtou16, u16, cpu_to_le16, | ||
125 | 0xffff); | ||
126 | |||
127 | UVCG_CTRL_HDR_ATTR(dw_clock_frequency, dwClockFrequency, le32_to_cpu, kstrtou32, | ||
128 | u32, cpu_to_le32, 0x7fffffff); | ||
129 | |||
130 | #undef UVCG_CTRL_HDR_ATTR | ||
131 | |||
132 | static struct configfs_attribute *uvcg_control_header_attrs[] = { | ||
133 | &uvcg_control_header_bcd_uvc.attr, | ||
134 | &uvcg_control_header_dw_clock_frequency.attr, | ||
135 | NULL, | ||
136 | }; | ||
137 | |||
138 | static struct config_item_type uvcg_control_header_type = { | ||
139 | .ct_item_ops = &uvcg_control_header_item_ops, | ||
140 | .ct_attrs = uvcg_control_header_attrs, | ||
141 | .ct_owner = THIS_MODULE, | ||
142 | }; | ||
143 | |||
144 | static struct config_item *uvcg_control_header_make(struct config_group *group, | ||
145 | const char *name) | ||
146 | { | ||
147 | struct uvcg_control_header *h; | ||
148 | |||
149 | h = kzalloc(sizeof(*h), GFP_KERNEL); | ||
150 | if (!h) | ||
151 | return ERR_PTR(-ENOMEM); | ||
152 | |||
153 | h->desc.bLength = UVC_DT_HEADER_SIZE(1); | ||
154 | h->desc.bDescriptorType = USB_DT_CS_INTERFACE; | ||
155 | h->desc.bDescriptorSubType = UVC_VC_HEADER; | ||
156 | h->desc.bcdUVC = cpu_to_le16(0x0100); | ||
157 | h->desc.dwClockFrequency = cpu_to_le32(48000000); | ||
158 | |||
159 | config_item_init_type_name(&h->item, name, &uvcg_control_header_type); | ||
160 | |||
161 | return &h->item; | ||
162 | } | ||
163 | |||
164 | static void uvcg_control_header_drop(struct config_group *group, | ||
165 | struct config_item *item) | ||
166 | { | ||
167 | struct uvcg_control_header *h = to_uvcg_control_header(item); | ||
168 | |||
169 | kfree(h); | ||
170 | } | ||
171 | |||
172 | /* control/header */ | ||
173 | static struct uvcg_control_header_grp { | ||
174 | struct config_group group; | ||
175 | } uvcg_control_header_grp; | ||
176 | |||
177 | static struct configfs_group_operations uvcg_control_header_grp_ops = { | ||
178 | .make_item = uvcg_control_header_make, | ||
179 | .drop_item = uvcg_control_header_drop, | ||
180 | }; | ||
181 | |||
182 | static struct config_item_type uvcg_control_header_grp_type = { | ||
183 | .ct_group_ops = &uvcg_control_header_grp_ops, | ||
184 | .ct_owner = THIS_MODULE, | ||
185 | }; | ||
186 | |||
187 | /* control/processing/default */ | ||
188 | static struct uvcg_default_processing { | ||
189 | struct config_group group; | ||
190 | } uvcg_default_processing; | ||
191 | |||
192 | static inline struct uvcg_default_processing | ||
193 | *to_uvcg_default_processing(struct config_item *item) | ||
194 | { | ||
195 | return container_of(to_config_group(item), | ||
196 | struct uvcg_default_processing, group); | ||
197 | } | ||
198 | |||
199 | CONFIGFS_ATTR_STRUCT(uvcg_default_processing); | ||
200 | CONFIGFS_ATTR_OPS_RO(uvcg_default_processing); | ||
201 | |||
202 | static struct configfs_item_operations uvcg_default_processing_item_ops = { | ||
203 | .show_attribute = uvcg_default_processing_attr_show, | ||
204 | }; | ||
205 | |||
206 | #define UVCG_DEFAULT_PROCESSING_ATTR(cname, aname, conv) \ | ||
207 | static ssize_t uvcg_default_processing_##cname##_show( \ | ||
208 | struct uvcg_default_processing *dp, char *page) \ | ||
209 | { \ | ||
210 | struct f_uvc_opts *opts; \ | ||
211 | struct config_item *opts_item; \ | ||
212 | struct mutex *su_mutex = &dp->group.cg_subsys->su_mutex; \ | ||
213 | struct uvc_processing_unit_descriptor *pd; \ | ||
214 | int result; \ | ||
215 | \ | ||
216 | mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ | ||
217 | \ | ||
218 | opts_item = dp->group.cg_item.ci_parent->ci_parent->ci_parent; \ | ||
219 | opts = to_f_uvc_opts(opts_item); \ | ||
220 | pd = &opts->uvc_processing; \ | ||
221 | \ | ||
222 | mutex_lock(&opts->lock); \ | ||
223 | result = sprintf(page, "%d\n", conv(pd->aname)); \ | ||
224 | mutex_unlock(&opts->lock); \ | ||
225 | \ | ||
226 | mutex_unlock(su_mutex); \ | ||
227 | return result; \ | ||
228 | } \ | ||
229 | \ | ||
230 | static struct uvcg_default_processing_attribute \ | ||
231 | uvcg_default_processing_##cname = \ | ||
232 | __CONFIGFS_ATTR_RO(aname, uvcg_default_processing_##cname##_show) | ||
233 | |||
234 | #define identity_conv(x) (x) | ||
235 | |||
236 | UVCG_DEFAULT_PROCESSING_ATTR(b_unit_id, bUnitID, identity_conv); | ||
237 | UVCG_DEFAULT_PROCESSING_ATTR(b_source_id, bSourceID, identity_conv); | ||
238 | UVCG_DEFAULT_PROCESSING_ATTR(w_max_multiplier, wMaxMultiplier, le16_to_cpu); | ||
239 | UVCG_DEFAULT_PROCESSING_ATTR(i_processing, iProcessing, identity_conv); | ||
240 | |||
241 | #undef identity_conv | ||
242 | |||
243 | #undef UVCG_DEFAULT_PROCESSING_ATTR | ||
244 | |||
245 | static ssize_t uvcg_default_processing_bm_controls_show( | ||
246 | struct uvcg_default_processing *dp, char *page) | ||
247 | { | ||
248 | struct f_uvc_opts *opts; | ||
249 | struct config_item *opts_item; | ||
250 | struct mutex *su_mutex = &dp->group.cg_subsys->su_mutex; | ||
251 | struct uvc_processing_unit_descriptor *pd; | ||
252 | int result, i; | ||
253 | char *pg = page; | ||
254 | |||
255 | mutex_lock(su_mutex); /* for navigating configfs hierarchy */ | ||
256 | |||
257 | opts_item = dp->group.cg_item.ci_parent->ci_parent->ci_parent; | ||
258 | opts = to_f_uvc_opts(opts_item); | ||
259 | pd = &opts->uvc_processing; | ||
260 | |||
261 | mutex_lock(&opts->lock); | ||
262 | for (result = 0, i = 0; i < pd->bControlSize; ++i) { | ||
263 | result += sprintf(pg, "%d\n", pd->bmControls[i]); | ||
264 | pg = page + result; | ||
265 | } | ||
266 | mutex_unlock(&opts->lock); | ||
267 | |||
268 | mutex_unlock(su_mutex); | ||
269 | |||
270 | return result; | ||
271 | } | ||
272 | |||
273 | static struct uvcg_default_processing_attribute | ||
274 | uvcg_default_processing_bm_controls = | ||
275 | __CONFIGFS_ATTR_RO(bmControls, | ||
276 | uvcg_default_processing_bm_controls_show); | ||
277 | |||
278 | static struct configfs_attribute *uvcg_default_processing_attrs[] = { | ||
279 | &uvcg_default_processing_b_unit_id.attr, | ||
280 | &uvcg_default_processing_b_source_id.attr, | ||
281 | &uvcg_default_processing_w_max_multiplier.attr, | ||
282 | &uvcg_default_processing_bm_controls.attr, | ||
283 | &uvcg_default_processing_i_processing.attr, | ||
284 | NULL, | ||
285 | }; | ||
286 | |||
287 | static struct config_item_type uvcg_default_processing_type = { | ||
288 | .ct_item_ops = &uvcg_default_processing_item_ops, | ||
289 | .ct_attrs = uvcg_default_processing_attrs, | ||
290 | .ct_owner = THIS_MODULE, | ||
291 | }; | ||
292 | |||
293 | /* struct uvcg_processing {}; */ | ||
294 | |||
295 | static struct config_group *uvcg_processing_default_groups[] = { | ||
296 | &uvcg_default_processing.group, | ||
297 | NULL, | ||
298 | }; | ||
299 | |||
300 | /* control/processing */ | ||
301 | static struct uvcg_processing_grp { | ||
302 | struct config_group group; | ||
303 | } uvcg_processing_grp; | ||
304 | |||
305 | static struct config_item_type uvcg_processing_grp_type = { | ||
306 | .ct_owner = THIS_MODULE, | ||
307 | }; | ||
308 | |||
309 | /* control/terminal/camera/default */ | ||
310 | static struct uvcg_default_camera { | ||
311 | struct config_group group; | ||
312 | } uvcg_default_camera; | ||
313 | |||
314 | static inline struct uvcg_default_camera | ||
315 | *to_uvcg_default_camera(struct config_item *item) | ||
316 | { | ||
317 | return container_of(to_config_group(item), | ||
318 | struct uvcg_default_camera, group); | ||
319 | } | ||
320 | |||
321 | CONFIGFS_ATTR_STRUCT(uvcg_default_camera); | ||
322 | CONFIGFS_ATTR_OPS_RO(uvcg_default_camera); | ||
323 | |||
324 | static struct configfs_item_operations uvcg_default_camera_item_ops = { | ||
325 | .show_attribute = uvcg_default_camera_attr_show, | ||
326 | }; | ||
327 | |||
328 | #define UVCG_DEFAULT_CAMERA_ATTR(cname, aname, conv) \ | ||
329 | static ssize_t uvcg_default_camera_##cname##_show( \ | ||
330 | struct uvcg_default_camera *dc, char *page) \ | ||
331 | { \ | ||
332 | struct f_uvc_opts *opts; \ | ||
333 | struct config_item *opts_item; \ | ||
334 | struct mutex *su_mutex = &dc->group.cg_subsys->su_mutex; \ | ||
335 | struct uvc_camera_terminal_descriptor *cd; \ | ||
336 | int result; \ | ||
337 | \ | ||
338 | mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ | ||
339 | \ | ||
340 | opts_item = dc->group.cg_item.ci_parent->ci_parent->ci_parent-> \ | ||
341 | ci_parent; \ | ||
342 | opts = to_f_uvc_opts(opts_item); \ | ||
343 | cd = &opts->uvc_camera_terminal; \ | ||
344 | \ | ||
345 | mutex_lock(&opts->lock); \ | ||
346 | result = sprintf(page, "%d\n", conv(cd->aname)); \ | ||
347 | mutex_unlock(&opts->lock); \ | ||
348 | \ | ||
349 | mutex_unlock(su_mutex); \ | ||
350 | \ | ||
351 | return result; \ | ||
352 | } \ | ||
353 | \ | ||
354 | static struct uvcg_default_camera_attribute \ | ||
355 | uvcg_default_camera_##cname = \ | ||
356 | __CONFIGFS_ATTR_RO(aname, uvcg_default_camera_##cname##_show) | ||
357 | |||
358 | #define identity_conv(x) (x) | ||
359 | |||
360 | UVCG_DEFAULT_CAMERA_ATTR(b_terminal_id, bTerminalID, identity_conv); | ||
361 | UVCG_DEFAULT_CAMERA_ATTR(w_terminal_type, wTerminalType, le16_to_cpu); | ||
362 | UVCG_DEFAULT_CAMERA_ATTR(b_assoc_terminal, bAssocTerminal, identity_conv); | ||
363 | UVCG_DEFAULT_CAMERA_ATTR(i_terminal, iTerminal, identity_conv); | ||
364 | UVCG_DEFAULT_CAMERA_ATTR(w_objective_focal_length_min, wObjectiveFocalLengthMin, | ||
365 | le16_to_cpu); | ||
366 | UVCG_DEFAULT_CAMERA_ATTR(w_objective_focal_length_max, wObjectiveFocalLengthMax, | ||
367 | le16_to_cpu); | ||
368 | UVCG_DEFAULT_CAMERA_ATTR(w_ocular_focal_length, wOcularFocalLength, | ||
369 | le16_to_cpu); | ||
370 | |||
371 | #undef identity_conv | ||
372 | |||
373 | #undef UVCG_DEFAULT_CAMERA_ATTR | ||
374 | |||
375 | static ssize_t uvcg_default_camera_bm_controls_show( | ||
376 | struct uvcg_default_camera *dc, char *page) | ||
377 | { | ||
378 | struct f_uvc_opts *opts; | ||
379 | struct config_item *opts_item; | ||
380 | struct mutex *su_mutex = &dc->group.cg_subsys->su_mutex; | ||
381 | struct uvc_camera_terminal_descriptor *cd; | ||
382 | int result, i; | ||
383 | char *pg = page; | ||
384 | |||
385 | mutex_lock(su_mutex); /* for navigating configfs hierarchy */ | ||
386 | |||
387 | opts_item = dc->group.cg_item.ci_parent->ci_parent->ci_parent-> | ||
388 | ci_parent; | ||
389 | opts = to_f_uvc_opts(opts_item); | ||
390 | cd = &opts->uvc_camera_terminal; | ||
391 | |||
392 | mutex_lock(&opts->lock); | ||
393 | for (result = 0, i = 0; i < cd->bControlSize; ++i) { | ||
394 | result += sprintf(pg, "%d\n", cd->bmControls[i]); | ||
395 | pg = page + result; | ||
396 | } | ||
397 | mutex_unlock(&opts->lock); | ||
398 | |||
399 | mutex_unlock(su_mutex); | ||
400 | return result; | ||
401 | } | ||
402 | |||
403 | static struct uvcg_default_camera_attribute | ||
404 | uvcg_default_camera_bm_controls = | ||
405 | __CONFIGFS_ATTR_RO(bmControls, uvcg_default_camera_bm_controls_show); | ||
406 | |||
407 | static struct configfs_attribute *uvcg_default_camera_attrs[] = { | ||
408 | &uvcg_default_camera_b_terminal_id.attr, | ||
409 | &uvcg_default_camera_w_terminal_type.attr, | ||
410 | &uvcg_default_camera_b_assoc_terminal.attr, | ||
411 | &uvcg_default_camera_i_terminal.attr, | ||
412 | &uvcg_default_camera_w_objective_focal_length_min.attr, | ||
413 | &uvcg_default_camera_w_objective_focal_length_max.attr, | ||
414 | &uvcg_default_camera_w_ocular_focal_length.attr, | ||
415 | &uvcg_default_camera_bm_controls.attr, | ||
416 | NULL, | ||
417 | }; | ||
418 | |||
419 | static struct config_item_type uvcg_default_camera_type = { | ||
420 | .ct_item_ops = &uvcg_default_camera_item_ops, | ||
421 | .ct_attrs = uvcg_default_camera_attrs, | ||
422 | .ct_owner = THIS_MODULE, | ||
423 | }; | ||
424 | |||
425 | /* struct uvcg_camera {}; */ | ||
426 | |||
427 | static struct config_group *uvcg_camera_default_groups[] = { | ||
428 | &uvcg_default_camera.group, | ||
429 | NULL, | ||
430 | }; | ||
431 | |||
432 | /* control/terminal/camera */ | ||
433 | static struct uvcg_camera_grp { | ||
434 | struct config_group group; | ||
435 | } uvcg_camera_grp; | ||
436 | |||
437 | static struct config_item_type uvcg_camera_grp_type = { | ||
438 | .ct_owner = THIS_MODULE, | ||
439 | }; | ||
440 | |||
441 | /* control/terminal/output/default */ | ||
442 | static struct uvcg_default_output { | ||
443 | struct config_group group; | ||
444 | } uvcg_default_output; | ||
445 | |||
446 | static inline struct uvcg_default_output | ||
447 | *to_uvcg_default_output(struct config_item *item) | ||
448 | { | ||
449 | return container_of(to_config_group(item), | ||
450 | struct uvcg_default_output, group); | ||
451 | } | ||
452 | |||
453 | CONFIGFS_ATTR_STRUCT(uvcg_default_output); | ||
454 | CONFIGFS_ATTR_OPS_RO(uvcg_default_output); | ||
455 | |||
456 | static struct configfs_item_operations uvcg_default_output_item_ops = { | ||
457 | .show_attribute = uvcg_default_output_attr_show, | ||
458 | }; | ||
459 | |||
460 | #define UVCG_DEFAULT_OUTPUT_ATTR(cname, aname, conv) \ | ||
461 | static ssize_t uvcg_default_output_##cname##_show( \ | ||
462 | struct uvcg_default_output *dout, char *page) \ | ||
463 | { \ | ||
464 | struct f_uvc_opts *opts; \ | ||
465 | struct config_item *opts_item; \ | ||
466 | struct mutex *su_mutex = &dout->group.cg_subsys->su_mutex; \ | ||
467 | struct uvc_output_terminal_descriptor *cd; \ | ||
468 | int result; \ | ||
469 | \ | ||
470 | mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ | ||
471 | \ | ||
472 | opts_item = dout->group.cg_item.ci_parent->ci_parent-> \ | ||
473 | ci_parent->ci_parent; \ | ||
474 | opts = to_f_uvc_opts(opts_item); \ | ||
475 | cd = &opts->uvc_output_terminal; \ | ||
476 | \ | ||
477 | mutex_lock(&opts->lock); \ | ||
478 | result = sprintf(page, "%d\n", conv(cd->aname)); \ | ||
479 | mutex_unlock(&opts->lock); \ | ||
480 | \ | ||
481 | mutex_unlock(su_mutex); \ | ||
482 | \ | ||
483 | return result; \ | ||
484 | } \ | ||
485 | \ | ||
486 | static struct uvcg_default_output_attribute \ | ||
487 | uvcg_default_output_##cname = \ | ||
488 | __CONFIGFS_ATTR_RO(aname, uvcg_default_output_##cname##_show) | ||
489 | |||
490 | #define identity_conv(x) (x) | ||
491 | |||
492 | UVCG_DEFAULT_OUTPUT_ATTR(b_terminal_id, bTerminalID, identity_conv); | ||
493 | UVCG_DEFAULT_OUTPUT_ATTR(w_terminal_type, wTerminalType, le16_to_cpu); | ||
494 | UVCG_DEFAULT_OUTPUT_ATTR(b_assoc_terminal, bAssocTerminal, identity_conv); | ||
495 | UVCG_DEFAULT_OUTPUT_ATTR(b_source_id, bSourceID, identity_conv); | ||
496 | UVCG_DEFAULT_OUTPUT_ATTR(i_terminal, iTerminal, identity_conv); | ||
497 | |||
498 | #undef identity_conv | ||
499 | |||
500 | #undef UVCG_DEFAULT_OUTPUT_ATTR | ||
501 | |||
502 | static struct configfs_attribute *uvcg_default_output_attrs[] = { | ||
503 | &uvcg_default_output_b_terminal_id.attr, | ||
504 | &uvcg_default_output_w_terminal_type.attr, | ||
505 | &uvcg_default_output_b_assoc_terminal.attr, | ||
506 | &uvcg_default_output_b_source_id.attr, | ||
507 | &uvcg_default_output_i_terminal.attr, | ||
508 | NULL, | ||
509 | }; | ||
510 | |||
511 | static struct config_item_type uvcg_default_output_type = { | ||
512 | .ct_item_ops = &uvcg_default_output_item_ops, | ||
513 | .ct_attrs = uvcg_default_output_attrs, | ||
514 | .ct_owner = THIS_MODULE, | ||
515 | }; | ||
516 | |||
517 | /* struct uvcg_output {}; */ | ||
518 | |||
519 | static struct config_group *uvcg_output_default_groups[] = { | ||
520 | &uvcg_default_output.group, | ||
521 | NULL, | ||
522 | }; | ||
523 | |||
524 | /* control/terminal/output */ | ||
525 | static struct uvcg_output_grp { | ||
526 | struct config_group group; | ||
527 | } uvcg_output_grp; | ||
528 | |||
529 | static struct config_item_type uvcg_output_grp_type = { | ||
530 | .ct_owner = THIS_MODULE, | ||
531 | }; | ||
532 | |||
533 | static struct config_group *uvcg_terminal_default_groups[] = { | ||
534 | &uvcg_camera_grp.group, | ||
535 | &uvcg_output_grp.group, | ||
536 | NULL, | ||
537 | }; | ||
538 | |||
539 | /* control/terminal */ | ||
540 | static struct uvcg_terminal_grp { | ||
541 | struct config_group group; | ||
542 | } uvcg_terminal_grp; | ||
543 | |||
544 | static struct config_item_type uvcg_terminal_grp_type = { | ||
545 | .ct_owner = THIS_MODULE, | ||
546 | }; | ||
547 | |||
548 | /* control/class/{fs} */ | ||
549 | static struct uvcg_control_class { | ||
550 | struct config_group group; | ||
551 | } uvcg_control_class_fs, uvcg_control_class_ss; | ||
552 | |||
553 | |||
554 | static inline struct uvc_descriptor_header | ||
555 | **uvcg_get_ctl_class_arr(struct config_item *i, struct f_uvc_opts *o) | ||
556 | { | ||
557 | struct uvcg_control_class *cl = container_of(to_config_group(i), | ||
558 | struct uvcg_control_class, group); | ||
559 | |||
560 | if (cl == &uvcg_control_class_fs) | ||
561 | return o->uvc_fs_control_cls; | ||
562 | |||
563 | if (cl == &uvcg_control_class_ss) | ||
564 | return o->uvc_ss_control_cls; | ||
565 | |||
566 | return NULL; | ||
567 | } | ||
568 | |||
569 | static int uvcg_control_class_allow_link(struct config_item *src, | ||
570 | struct config_item *target) | ||
571 | { | ||
572 | struct config_item *control, *header; | ||
573 | struct f_uvc_opts *opts; | ||
574 | struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; | ||
575 | struct uvc_descriptor_header **class_array; | ||
576 | struct uvcg_control_header *target_hdr; | ||
577 | int ret = -EINVAL; | ||
578 | |||
579 | mutex_lock(su_mutex); /* for navigating configfs hierarchy */ | ||
580 | |||
581 | control = src->ci_parent->ci_parent; | ||
582 | header = config_group_find_item(to_config_group(control), "header"); | ||
583 | if (!header || target->ci_parent != header) | ||
584 | goto out; | ||
585 | |||
586 | opts = to_f_uvc_opts(control->ci_parent); | ||
587 | |||
588 | mutex_lock(&opts->lock); | ||
589 | |||
590 | class_array = uvcg_get_ctl_class_arr(src, opts); | ||
591 | if (!class_array) | ||
592 | goto unlock; | ||
593 | if (opts->refcnt || class_array[0]) { | ||
594 | ret = -EBUSY; | ||
595 | goto unlock; | ||
596 | } | ||
597 | |||
598 | target_hdr = to_uvcg_control_header(target); | ||
599 | ++target_hdr->linked; | ||
600 | class_array[0] = (struct uvc_descriptor_header *)&target_hdr->desc; | ||
601 | ret = 0; | ||
602 | |||
603 | unlock: | ||
604 | mutex_unlock(&opts->lock); | ||
605 | out: | ||
606 | mutex_unlock(su_mutex); | ||
607 | return ret; | ||
608 | } | ||
609 | |||
610 | static int uvcg_control_class_drop_link(struct config_item *src, | ||
611 | struct config_item *target) | ||
612 | { | ||
613 | struct config_item *control, *header; | ||
614 | struct f_uvc_opts *opts; | ||
615 | struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; | ||
616 | struct uvc_descriptor_header **class_array; | ||
617 | struct uvcg_control_header *target_hdr; | ||
618 | int ret = -EINVAL; | ||
619 | |||
620 | mutex_lock(su_mutex); /* for navigating configfs hierarchy */ | ||
621 | |||
622 | control = src->ci_parent->ci_parent; | ||
623 | header = config_group_find_item(to_config_group(control), "header"); | ||
624 | if (!header || target->ci_parent != header) | ||
625 | goto out; | ||
626 | |||
627 | opts = to_f_uvc_opts(control->ci_parent); | ||
628 | |||
629 | mutex_lock(&opts->lock); | ||
630 | |||
631 | class_array = uvcg_get_ctl_class_arr(src, opts); | ||
632 | if (!class_array) | ||
633 | goto unlock; | ||
634 | if (opts->refcnt) { | ||
635 | ret = -EBUSY; | ||
636 | goto unlock; | ||
637 | } | ||
638 | |||
639 | target_hdr = to_uvcg_control_header(target); | ||
640 | --target_hdr->linked; | ||
641 | class_array[0] = NULL; | ||
642 | ret = 0; | ||
643 | |||
644 | unlock: | ||
645 | mutex_unlock(&opts->lock); | ||
646 | out: | ||
647 | mutex_unlock(su_mutex); | ||
648 | return ret; | ||
649 | } | ||
650 | |||
651 | static struct configfs_item_operations uvcg_control_class_item_ops = { | ||
652 | .allow_link = uvcg_control_class_allow_link, | ||
653 | .drop_link = uvcg_control_class_drop_link, | ||
654 | }; | ||
655 | |||
656 | static struct config_item_type uvcg_control_class_type = { | ||
657 | .ct_item_ops = &uvcg_control_class_item_ops, | ||
658 | .ct_owner = THIS_MODULE, | ||
659 | }; | ||
660 | |||
661 | static struct config_group *uvcg_control_class_default_groups[] = { | ||
662 | &uvcg_control_class_fs.group, | ||
663 | &uvcg_control_class_ss.group, | ||
664 | NULL, | ||
665 | }; | ||
666 | |||
667 | /* control/class */ | ||
668 | static struct uvcg_control_class_grp { | ||
669 | struct config_group group; | ||
670 | } uvcg_control_class_grp; | ||
671 | |||
672 | static struct config_item_type uvcg_control_class_grp_type = { | ||
673 | .ct_owner = THIS_MODULE, | ||
674 | }; | ||
675 | |||
676 | static struct config_group *uvcg_control_default_groups[] = { | ||
677 | &uvcg_control_header_grp.group, | ||
678 | &uvcg_processing_grp.group, | ||
679 | &uvcg_terminal_grp.group, | ||
680 | &uvcg_control_class_grp.group, | ||
681 | NULL, | ||
682 | }; | ||
683 | |||
684 | /* control */ | ||
685 | static struct uvcg_control_grp { | ||
686 | struct config_group group; | ||
687 | } uvcg_control_grp; | ||
688 | |||
689 | static struct config_item_type uvcg_control_grp_type = { | ||
690 | .ct_owner = THIS_MODULE, | ||
691 | }; | ||
692 | |||
693 | /* streaming/uncompressed */ | ||
694 | static struct uvcg_uncompressed_grp { | ||
695 | struct config_group group; | ||
696 | } uvcg_uncompressed_grp; | ||
697 | |||
698 | /* streaming/mjpeg */ | ||
699 | static struct uvcg_mjpeg_grp { | ||
700 | struct config_group group; | ||
701 | } uvcg_mjpeg_grp; | ||
702 | |||
703 | static struct config_item *fmt_parent[] = { | ||
704 | &uvcg_uncompressed_grp.group.cg_item, | ||
705 | &uvcg_mjpeg_grp.group.cg_item, | ||
706 | }; | ||
707 | |||
708 | enum uvcg_format_type { | ||
709 | UVCG_UNCOMPRESSED = 0, | ||
710 | UVCG_MJPEG, | ||
711 | }; | ||
712 | |||
713 | struct uvcg_format { | ||
714 | struct config_group group; | ||
715 | enum uvcg_format_type type; | ||
716 | unsigned linked; | ||
717 | unsigned num_frames; | ||
718 | __u8 bmaControls[UVCG_STREAMING_CONTROL_SIZE]; | ||
719 | }; | ||
720 | |||
721 | static struct uvcg_format *to_uvcg_format(struct config_item *item) | ||
722 | { | ||
723 | return container_of(to_config_group(item), struct uvcg_format, group); | ||
724 | } | ||
725 | |||
726 | static ssize_t uvcg_format_bma_controls_show(struct uvcg_format *f, char *page) | ||
727 | { | ||
728 | struct f_uvc_opts *opts; | ||
729 | struct config_item *opts_item; | ||
730 | struct mutex *su_mutex = &f->group.cg_subsys->su_mutex; | ||
731 | int result, i; | ||
732 | char *pg = page; | ||
733 | |||
734 | mutex_lock(su_mutex); /* for navigating configfs hierarchy */ | ||
735 | |||
736 | opts_item = f->group.cg_item.ci_parent->ci_parent->ci_parent; | ||
737 | opts = to_f_uvc_opts(opts_item); | ||
738 | |||
739 | mutex_lock(&opts->lock); | ||
740 | result = sprintf(pg, "0x"); | ||
741 | pg += result; | ||
742 | for (i = 0; i < UVCG_STREAMING_CONTROL_SIZE; ++i) { | ||
743 | result += sprintf(pg, "%x\n", f->bmaControls[i]); | ||
744 | pg = page + result; | ||
745 | } | ||
746 | mutex_unlock(&opts->lock); | ||
747 | |||
748 | mutex_unlock(su_mutex); | ||
749 | return result; | ||
750 | } | ||
751 | |||
752 | static ssize_t uvcg_format_bma_controls_store(struct uvcg_format *ch, | ||
753 | const char *page, size_t len) | ||
754 | { | ||
755 | struct f_uvc_opts *opts; | ||
756 | struct config_item *opts_item; | ||
757 | struct mutex *su_mutex = &ch->group.cg_subsys->su_mutex; | ||
758 | int ret = -EINVAL; | ||
759 | |||
760 | mutex_lock(su_mutex); /* for navigating configfs hierarchy */ | ||
761 | |||
762 | opts_item = ch->group.cg_item.ci_parent->ci_parent->ci_parent; | ||
763 | opts = to_f_uvc_opts(opts_item); | ||
764 | |||
765 | mutex_lock(&opts->lock); | ||
766 | if (ch->linked || opts->refcnt) { | ||
767 | ret = -EBUSY; | ||
768 | goto end; | ||
769 | } | ||
770 | |||
771 | if (len < 4 || *page != '0' || | ||
772 | (*(page + 1) != 'x' && *(page + 1) != 'X')) | ||
773 | goto end; | ||
774 | ret = hex2bin(ch->bmaControls, page + 2, 1); | ||
775 | if (ret < 0) | ||
776 | goto end; | ||
777 | ret = len; | ||
778 | end: | ||
779 | mutex_unlock(&opts->lock); | ||
780 | mutex_unlock(su_mutex); | ||
781 | return ret; | ||
782 | } | ||
783 | |||
784 | struct uvcg_format_ptr { | ||
785 | struct uvcg_format *fmt; | ||
786 | struct list_head entry; | ||
787 | }; | ||
788 | |||
789 | /* streaming/header/<NAME> */ | ||
790 | struct uvcg_streaming_header { | ||
791 | struct config_item item; | ||
792 | struct uvc_input_header_descriptor desc; | ||
793 | unsigned linked; | ||
794 | struct list_head formats; | ||
795 | unsigned num_fmt; | ||
796 | }; | ||
797 | |||
798 | static struct uvcg_streaming_header *to_uvcg_streaming_header(struct config_item *item) | ||
799 | { | ||
800 | return container_of(item, struct uvcg_streaming_header, item); | ||
801 | } | ||
802 | |||
803 | CONFIGFS_ATTR_STRUCT(uvcg_streaming_header); | ||
804 | CONFIGFS_ATTR_OPS(uvcg_streaming_header); | ||
805 | |||
806 | static int uvcg_streaming_header_allow_link(struct config_item *src, | ||
807 | struct config_item *target) | ||
808 | { | ||
809 | struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; | ||
810 | struct config_item *opts_item; | ||
811 | struct f_uvc_opts *opts; | ||
812 | struct uvcg_streaming_header *src_hdr; | ||
813 | struct uvcg_format *target_fmt = NULL; | ||
814 | struct uvcg_format_ptr *format_ptr; | ||
815 | int i, ret = -EINVAL; | ||
816 | |||
817 | src_hdr = to_uvcg_streaming_header(src); | ||
818 | mutex_lock(su_mutex); /* for navigating configfs hierarchy */ | ||
819 | |||
820 | opts_item = src->ci_parent->ci_parent->ci_parent; | ||
821 | opts = to_f_uvc_opts(opts_item); | ||
822 | |||
823 | mutex_lock(&opts->lock); | ||
824 | |||
825 | if (src_hdr->linked) { | ||
826 | ret = -EBUSY; | ||
827 | goto out; | ||
828 | } | ||
829 | |||
830 | for (i = 0; i < ARRAY_SIZE(fmt_parent); ++i) | ||
831 | if (target->ci_parent == fmt_parent[i]) | ||
832 | break; | ||
833 | if (i == ARRAY_SIZE(fmt_parent)) | ||
834 | goto out; | ||
835 | |||
836 | target_fmt = container_of(to_config_group(target), struct uvcg_format, | ||
837 | group); | ||
838 | if (!target_fmt) | ||
839 | goto out; | ||
840 | |||
841 | format_ptr = kzalloc(sizeof(*format_ptr), GFP_KERNEL); | ||
842 | if (!format_ptr) { | ||
843 | ret = -ENOMEM; | ||
844 | goto out; | ||
845 | } | ||
846 | ret = 0; | ||
847 | format_ptr->fmt = target_fmt; | ||
848 | list_add_tail(&format_ptr->entry, &src_hdr->formats); | ||
849 | ++src_hdr->num_fmt; | ||
850 | |||
851 | out: | ||
852 | mutex_unlock(&opts->lock); | ||
853 | mutex_unlock(su_mutex); | ||
854 | return ret; | ||
855 | } | ||
856 | |||
857 | static int uvcg_streaming_header_drop_link(struct config_item *src, | ||
858 | struct config_item *target) | ||
859 | { | ||
860 | struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; | ||
861 | struct config_item *opts_item; | ||
862 | struct f_uvc_opts *opts; | ||
863 | struct uvcg_streaming_header *src_hdr; | ||
864 | struct uvcg_format *target_fmt = NULL; | ||
865 | struct uvcg_format_ptr *format_ptr, *tmp; | ||
866 | int ret = -EINVAL; | ||
867 | |||
868 | src_hdr = to_uvcg_streaming_header(src); | ||
869 | mutex_lock(su_mutex); /* for navigating configfs hierarchy */ | ||
870 | |||
871 | opts_item = src->ci_parent->ci_parent->ci_parent; | ||
872 | opts = to_f_uvc_opts(opts_item); | ||
873 | |||
874 | mutex_lock(&opts->lock); | ||
875 | target_fmt = container_of(to_config_group(target), struct uvcg_format, | ||
876 | group); | ||
877 | if (!target_fmt) | ||
878 | goto out; | ||
879 | |||
880 | list_for_each_entry_safe(format_ptr, tmp, &src_hdr->formats, entry) | ||
881 | if (format_ptr->fmt == target_fmt) { | ||
882 | list_del(&format_ptr->entry); | ||
883 | kfree(format_ptr); | ||
884 | --src_hdr->num_fmt; | ||
885 | break; | ||
886 | } | ||
887 | |||
888 | out: | ||
889 | mutex_unlock(&opts->lock); | ||
890 | mutex_unlock(su_mutex); | ||
891 | return ret; | ||
892 | |||
893 | } | ||
894 | |||
895 | static struct configfs_item_operations uvcg_streaming_header_item_ops = { | ||
896 | .show_attribute = uvcg_streaming_header_attr_show, | ||
897 | .store_attribute = uvcg_streaming_header_attr_store, | ||
898 | .allow_link = uvcg_streaming_header_allow_link, | ||
899 | .drop_link = uvcg_streaming_header_drop_link, | ||
900 | }; | ||
901 | |||
902 | #define UVCG_STREAMING_HEADER_ATTR(cname, aname, conv) \ | ||
903 | static ssize_t uvcg_streaming_header_##cname##_show( \ | ||
904 | struct uvcg_streaming_header *sh, char *page) \ | ||
905 | { \ | ||
906 | struct f_uvc_opts *opts; \ | ||
907 | struct config_item *opts_item; \ | ||
908 | struct mutex *su_mutex = &sh->item.ci_group->cg_subsys->su_mutex;\ | ||
909 | int result; \ | ||
910 | \ | ||
911 | mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ | ||
912 | \ | ||
913 | opts_item = sh->item.ci_parent->ci_parent->ci_parent; \ | ||
914 | opts = to_f_uvc_opts(opts_item); \ | ||
915 | \ | ||
916 | mutex_lock(&opts->lock); \ | ||
917 | result = sprintf(page, "%d\n", conv(sh->desc.aname)); \ | ||
918 | mutex_unlock(&opts->lock); \ | ||
919 | \ | ||
920 | mutex_unlock(su_mutex); \ | ||
921 | return result; \ | ||
922 | } \ | ||
923 | \ | ||
924 | static struct uvcg_streaming_header_attribute \ | ||
925 | uvcg_streaming_header_##cname = \ | ||
926 | __CONFIGFS_ATTR_RO(aname, uvcg_streaming_header_##cname##_show) | ||
927 | |||
928 | #define identity_conv(x) (x) | ||
929 | |||
930 | UVCG_STREAMING_HEADER_ATTR(bm_info, bmInfo, identity_conv); | ||
931 | UVCG_STREAMING_HEADER_ATTR(b_terminal_link, bTerminalLink, identity_conv); | ||
932 | UVCG_STREAMING_HEADER_ATTR(b_still_capture_method, bStillCaptureMethod, | ||
933 | identity_conv); | ||
934 | UVCG_STREAMING_HEADER_ATTR(b_trigger_support, bTriggerSupport, identity_conv); | ||
935 | UVCG_STREAMING_HEADER_ATTR(b_trigger_usage, bTriggerUsage, identity_conv); | ||
936 | |||
937 | #undef identity_conv | ||
938 | |||
939 | #undef UVCG_STREAMING_HEADER_ATTR | ||
940 | |||
941 | static struct configfs_attribute *uvcg_streaming_header_attrs[] = { | ||
942 | &uvcg_streaming_header_bm_info.attr, | ||
943 | &uvcg_streaming_header_b_terminal_link.attr, | ||
944 | &uvcg_streaming_header_b_still_capture_method.attr, | ||
945 | &uvcg_streaming_header_b_trigger_support.attr, | ||
946 | &uvcg_streaming_header_b_trigger_usage.attr, | ||
947 | NULL, | ||
948 | }; | ||
949 | |||
950 | static struct config_item_type uvcg_streaming_header_type = { | ||
951 | .ct_item_ops = &uvcg_streaming_header_item_ops, | ||
952 | .ct_attrs = uvcg_streaming_header_attrs, | ||
953 | .ct_owner = THIS_MODULE, | ||
954 | }; | ||
955 | |||
956 | static struct config_item | ||
957 | *uvcg_streaming_header_make(struct config_group *group, const char *name) | ||
958 | { | ||
959 | struct uvcg_streaming_header *h; | ||
960 | |||
961 | h = kzalloc(sizeof(*h), GFP_KERNEL); | ||
962 | if (!h) | ||
963 | return ERR_PTR(-ENOMEM); | ||
964 | |||
965 | INIT_LIST_HEAD(&h->formats); | ||
966 | h->desc.bDescriptorType = USB_DT_CS_INTERFACE; | ||
967 | h->desc.bDescriptorSubType = UVC_VS_INPUT_HEADER; | ||
968 | h->desc.bTerminalLink = 3; | ||
969 | h->desc.bControlSize = UVCG_STREAMING_CONTROL_SIZE; | ||
970 | |||
971 | config_item_init_type_name(&h->item, name, &uvcg_streaming_header_type); | ||
972 | |||
973 | return &h->item; | ||
974 | } | ||
975 | |||
976 | static void uvcg_streaming_header_drop(struct config_group *group, | ||
977 | struct config_item *item) | ||
978 | { | ||
979 | struct uvcg_streaming_header *h = to_uvcg_streaming_header(item); | ||
980 | |||
981 | kfree(h); | ||
982 | } | ||
983 | |||
984 | /* streaming/header */ | ||
985 | static struct uvcg_streaming_header_grp { | ||
986 | struct config_group group; | ||
987 | } uvcg_streaming_header_grp; | ||
988 | |||
989 | static struct configfs_group_operations uvcg_streaming_header_grp_ops = { | ||
990 | .make_item = uvcg_streaming_header_make, | ||
991 | .drop_item = uvcg_streaming_header_drop, | ||
992 | }; | ||
993 | |||
994 | static struct config_item_type uvcg_streaming_header_grp_type = { | ||
995 | .ct_group_ops = &uvcg_streaming_header_grp_ops, | ||
996 | .ct_owner = THIS_MODULE, | ||
997 | }; | ||
998 | |||
999 | /* streaming/<mode>/<format>/<NAME> */ | ||
1000 | struct uvcg_frame { | ||
1001 | struct { | ||
1002 | u8 b_length; | ||
1003 | u8 b_descriptor_type; | ||
1004 | u8 b_descriptor_subtype; | ||
1005 | u8 b_frame_index; | ||
1006 | u8 bm_capabilities; | ||
1007 | u16 w_width; | ||
1008 | u16 w_height; | ||
1009 | u32 dw_min_bit_rate; | ||
1010 | u32 dw_max_bit_rate; | ||
1011 | u32 dw_max_video_frame_buffer_size; | ||
1012 | u32 dw_default_frame_interval; | ||
1013 | u8 b_frame_interval_type; | ||
1014 | } __attribute__((packed)) frame; | ||
1015 | u32 *dw_frame_interval; | ||
1016 | enum uvcg_format_type fmt_type; | ||
1017 | struct config_item item; | ||
1018 | }; | ||
1019 | |||
1020 | static struct uvcg_frame *to_uvcg_frame(struct config_item *item) | ||
1021 | { | ||
1022 | return container_of(item, struct uvcg_frame, item); | ||
1023 | } | ||
1024 | |||
1025 | CONFIGFS_ATTR_STRUCT(uvcg_frame); | ||
1026 | CONFIGFS_ATTR_OPS(uvcg_frame); | ||
1027 | |||
1028 | static struct configfs_item_operations uvcg_frame_item_ops = { | ||
1029 | .show_attribute = uvcg_frame_attr_show, | ||
1030 | .store_attribute = uvcg_frame_attr_store, | ||
1031 | }; | ||
1032 | |||
1033 | #define UVCG_FRAME_ATTR(cname, aname, to_cpu_endian, to_little_endian, bits) \ | ||
1034 | static ssize_t uvcg_frame_##cname##_show(struct uvcg_frame *f, char *page)\ | ||
1035 | { \ | ||
1036 | struct f_uvc_opts *opts; \ | ||
1037 | struct config_item *opts_item; \ | ||
1038 | struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\ | ||
1039 | int result; \ | ||
1040 | \ | ||
1041 | mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ | ||
1042 | \ | ||
1043 | opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent; \ | ||
1044 | opts = to_f_uvc_opts(opts_item); \ | ||
1045 | \ | ||
1046 | mutex_lock(&opts->lock); \ | ||
1047 | result = sprintf(page, "%d\n", to_cpu_endian(f->frame.cname)); \ | ||
1048 | mutex_unlock(&opts->lock); \ | ||
1049 | \ | ||
1050 | mutex_unlock(su_mutex); \ | ||
1051 | return result; \ | ||
1052 | } \ | ||
1053 | \ | ||
1054 | static ssize_t uvcg_frame_##cname##_store(struct uvcg_frame *f, \ | ||
1055 | const char *page, size_t len)\ | ||
1056 | { \ | ||
1057 | struct f_uvc_opts *opts; \ | ||
1058 | struct config_item *opts_item; \ | ||
1059 | struct uvcg_format *fmt; \ | ||
1060 | struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\ | ||
1061 | int ret; \ | ||
1062 | u##bits num; \ | ||
1063 | \ | ||
1064 | ret = kstrtou##bits(page, 0, &num); \ | ||
1065 | if (ret) \ | ||
1066 | return ret; \ | ||
1067 | \ | ||
1068 | mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ | ||
1069 | \ | ||
1070 | opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent; \ | ||
1071 | opts = to_f_uvc_opts(opts_item); \ | ||
1072 | fmt = to_uvcg_format(f->item.ci_parent); \ | ||
1073 | \ | ||
1074 | mutex_lock(&opts->lock); \ | ||
1075 | if (fmt->linked || opts->refcnt) { \ | ||
1076 | ret = -EBUSY; \ | ||
1077 | goto end; \ | ||
1078 | } \ | ||
1079 | \ | ||
1080 | f->frame.cname = to_little_endian(num); \ | ||
1081 | ret = len; \ | ||
1082 | end: \ | ||
1083 | mutex_unlock(&opts->lock); \ | ||
1084 | mutex_unlock(su_mutex); \ | ||
1085 | return ret; \ | ||
1086 | } \ | ||
1087 | \ | ||
1088 | static struct uvcg_frame_attribute \ | ||
1089 | uvcg_frame_##cname = \ | ||
1090 | __CONFIGFS_ATTR(aname, S_IRUGO | S_IWUSR, \ | ||
1091 | uvcg_frame_##cname##_show, \ | ||
1092 | uvcg_frame_##cname##_store) | ||
1093 | |||
1094 | #define noop_conversion(x) (x) | ||
1095 | |||
1096 | UVCG_FRAME_ATTR(bm_capabilities, bmCapabilities, noop_conversion, | ||
1097 | noop_conversion, 8); | ||
1098 | UVCG_FRAME_ATTR(w_width, wWidth, le16_to_cpu, cpu_to_le16, 16); | ||
1099 | UVCG_FRAME_ATTR(w_height, wHeight, le16_to_cpu, cpu_to_le16, 16); | ||
1100 | UVCG_FRAME_ATTR(dw_min_bit_rate, dwMinBitRate, le32_to_cpu, cpu_to_le32, 32); | ||
1101 | UVCG_FRAME_ATTR(dw_max_bit_rate, dwMaxBitRate, le32_to_cpu, cpu_to_le32, 32); | ||
1102 | UVCG_FRAME_ATTR(dw_max_video_frame_buffer_size, dwMaxVideoFrameBufferSize, | ||
1103 | le32_to_cpu, cpu_to_le32, 32); | ||
1104 | UVCG_FRAME_ATTR(dw_default_frame_interval, dwDefaultFrameInterval, | ||
1105 | le32_to_cpu, cpu_to_le32, 32); | ||
1106 | |||
1107 | #undef noop_conversion | ||
1108 | |||
1109 | #undef UVCG_FRAME_ATTR | ||
1110 | |||
1111 | static ssize_t uvcg_frame_dw_frame_interval_show(struct uvcg_frame *frm, | ||
1112 | char *page) | ||
1113 | { | ||
1114 | struct f_uvc_opts *opts; | ||
1115 | struct config_item *opts_item; | ||
1116 | struct mutex *su_mutex = &frm->item.ci_group->cg_subsys->su_mutex; | ||
1117 | int result, i; | ||
1118 | char *pg = page; | ||
1119 | |||
1120 | mutex_lock(su_mutex); /* for navigating configfs hierarchy */ | ||
1121 | |||
1122 | opts_item = frm->item.ci_parent->ci_parent->ci_parent->ci_parent; | ||
1123 | opts = to_f_uvc_opts(opts_item); | ||
1124 | |||
1125 | mutex_lock(&opts->lock); | ||
1126 | for (result = 0, i = 0; i < frm->frame.b_frame_interval_type; ++i) { | ||
1127 | result += sprintf(pg, "%d\n", | ||
1128 | le32_to_cpu(frm->dw_frame_interval[i])); | ||
1129 | pg = page + result; | ||
1130 | } | ||
1131 | mutex_unlock(&opts->lock); | ||
1132 | |||
1133 | mutex_unlock(su_mutex); | ||
1134 | return result; | ||
1135 | } | ||
1136 | |||
1137 | static inline int __uvcg_count_frm_intrv(char *buf, void *priv) | ||
1138 | { | ||
1139 | ++*((int *)priv); | ||
1140 | return 0; | ||
1141 | } | ||
1142 | |||
1143 | static inline int __uvcg_fill_frm_intrv(char *buf, void *priv) | ||
1144 | { | ||
1145 | u32 num, **interv; | ||
1146 | int ret; | ||
1147 | |||
1148 | ret = kstrtou32(buf, 0, &num); | ||
1149 | if (ret) | ||
1150 | return ret; | ||
1151 | |||
1152 | interv = priv; | ||
1153 | **interv = cpu_to_le32(num); | ||
1154 | ++*interv; | ||
1155 | |||
1156 | return 0; | ||
1157 | } | ||
1158 | |||
1159 | static int __uvcg_iter_frm_intrv(const char *page, size_t len, | ||
1160 | int (*fun)(char *, void *), void *priv) | ||
1161 | { | ||
1162 | /* sign, base 2 representation, newline, terminator */ | ||
1163 | char buf[1 + sizeof(u32) * 8 + 1 + 1]; | ||
1164 | const char *pg = page; | ||
1165 | int i, ret; | ||
1166 | |||
1167 | if (!fun) | ||
1168 | return -EINVAL; | ||
1169 | |||
1170 | while (pg - page < len) { | ||
1171 | i = 0; | ||
1172 | while (i < sizeof(buf) && (pg - page < len) && | ||
1173 | *pg != '\0' && *pg != '\n') | ||
1174 | buf[i++] = *pg++; | ||
1175 | if (i == sizeof(buf)) | ||
1176 | return -EINVAL; | ||
1177 | while ((pg - page < len) && (*pg == '\0' || *pg == '\n')) | ||
1178 | ++pg; | ||
1179 | buf[i] = '\0'; | ||
1180 | ret = fun(buf, priv); | ||
1181 | if (ret) | ||
1182 | return ret; | ||
1183 | } | ||
1184 | |||
1185 | return 0; | ||
1186 | } | ||
1187 | |||
1188 | static ssize_t uvcg_frame_dw_frame_interval_store(struct uvcg_frame *ch, | ||
1189 | const char *page, size_t len) | ||
1190 | { | ||
1191 | struct f_uvc_opts *opts; | ||
1192 | struct config_item *opts_item; | ||
1193 | struct uvcg_format *fmt; | ||
1194 | struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex; | ||
1195 | int ret = 0, n = 0; | ||
1196 | u32 *frm_intrv, *tmp; | ||
1197 | |||
1198 | mutex_lock(su_mutex); /* for navigating configfs hierarchy */ | ||
1199 | |||
1200 | opts_item = ch->item.ci_parent->ci_parent->ci_parent->ci_parent; | ||
1201 | opts = to_f_uvc_opts(opts_item); | ||
1202 | fmt = to_uvcg_format(ch->item.ci_parent); | ||
1203 | |||
1204 | mutex_lock(&opts->lock); | ||
1205 | if (fmt->linked || opts->refcnt) { | ||
1206 | ret = -EBUSY; | ||
1207 | goto end; | ||
1208 | } | ||
1209 | |||
1210 | ret = __uvcg_iter_frm_intrv(page, len, __uvcg_count_frm_intrv, &n); | ||
1211 | if (ret) | ||
1212 | goto end; | ||
1213 | |||
1214 | tmp = frm_intrv = kcalloc(n, sizeof(u32), GFP_KERNEL); | ||
1215 | if (!frm_intrv) { | ||
1216 | ret = -ENOMEM; | ||
1217 | goto end; | ||
1218 | } | ||
1219 | |||
1220 | ret = __uvcg_iter_frm_intrv(page, len, __uvcg_fill_frm_intrv, &tmp); | ||
1221 | if (ret) { | ||
1222 | kfree(frm_intrv); | ||
1223 | goto end; | ||
1224 | } | ||
1225 | |||
1226 | kfree(ch->dw_frame_interval); | ||
1227 | ch->dw_frame_interval = frm_intrv; | ||
1228 | ch->frame.b_frame_interval_type = n; | ||
1229 | ret = len; | ||
1230 | |||
1231 | end: | ||
1232 | mutex_unlock(&opts->lock); | ||
1233 | mutex_unlock(su_mutex); | ||
1234 | return ret; | ||
1235 | } | ||
1236 | |||
1237 | static struct uvcg_frame_attribute | ||
1238 | uvcg_frame_dw_frame_interval = | ||
1239 | __CONFIGFS_ATTR(dwFrameInterval, S_IRUGO | S_IWUSR, | ||
1240 | uvcg_frame_dw_frame_interval_show, | ||
1241 | uvcg_frame_dw_frame_interval_store); | ||
1242 | |||
1243 | static struct configfs_attribute *uvcg_frame_attrs[] = { | ||
1244 | &uvcg_frame_bm_capabilities.attr, | ||
1245 | &uvcg_frame_w_width.attr, | ||
1246 | &uvcg_frame_w_height.attr, | ||
1247 | &uvcg_frame_dw_min_bit_rate.attr, | ||
1248 | &uvcg_frame_dw_max_bit_rate.attr, | ||
1249 | &uvcg_frame_dw_max_video_frame_buffer_size.attr, | ||
1250 | &uvcg_frame_dw_default_frame_interval.attr, | ||
1251 | &uvcg_frame_dw_frame_interval.attr, | ||
1252 | NULL, | ||
1253 | }; | ||
1254 | |||
1255 | static struct config_item_type uvcg_frame_type = { | ||
1256 | .ct_item_ops = &uvcg_frame_item_ops, | ||
1257 | .ct_attrs = uvcg_frame_attrs, | ||
1258 | .ct_owner = THIS_MODULE, | ||
1259 | }; | ||
1260 | |||
1261 | static struct config_item *uvcg_frame_make(struct config_group *group, | ||
1262 | const char *name) | ||
1263 | { | ||
1264 | struct uvcg_frame *h; | ||
1265 | struct uvcg_format *fmt; | ||
1266 | struct f_uvc_opts *opts; | ||
1267 | struct config_item *opts_item; | ||
1268 | |||
1269 | h = kzalloc(sizeof(*h), GFP_KERNEL); | ||
1270 | if (!h) | ||
1271 | return ERR_PTR(-ENOMEM); | ||
1272 | |||
1273 | h->frame.b_descriptor_type = USB_DT_CS_INTERFACE; | ||
1274 | h->frame.b_frame_index = 1; | ||
1275 | h->frame.w_width = cpu_to_le16(640); | ||
1276 | h->frame.w_height = cpu_to_le16(360); | ||
1277 | h->frame.dw_min_bit_rate = cpu_to_le32(18432000); | ||
1278 | h->frame.dw_max_bit_rate = cpu_to_le32(55296000); | ||
1279 | h->frame.dw_max_video_frame_buffer_size = cpu_to_le32(460800); | ||
1280 | h->frame.dw_default_frame_interval = cpu_to_le32(666666); | ||
1281 | |||
1282 | opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; | ||
1283 | opts = to_f_uvc_opts(opts_item); | ||
1284 | |||
1285 | mutex_lock(&opts->lock); | ||
1286 | fmt = to_uvcg_format(&group->cg_item); | ||
1287 | if (fmt->type == UVCG_UNCOMPRESSED) { | ||
1288 | h->frame.b_descriptor_subtype = UVC_VS_FRAME_UNCOMPRESSED; | ||
1289 | h->fmt_type = UVCG_UNCOMPRESSED; | ||
1290 | } else if (fmt->type == UVCG_MJPEG) { | ||
1291 | h->frame.b_descriptor_subtype = UVC_VS_FRAME_MJPEG; | ||
1292 | h->fmt_type = UVCG_MJPEG; | ||
1293 | } else { | ||
1294 | mutex_unlock(&opts->lock); | ||
1295 | kfree(h); | ||
1296 | return ERR_PTR(-EINVAL); | ||
1297 | } | ||
1298 | ++fmt->num_frames; | ||
1299 | mutex_unlock(&opts->lock); | ||
1300 | |||
1301 | config_item_init_type_name(&h->item, name, &uvcg_frame_type); | ||
1302 | |||
1303 | return &h->item; | ||
1304 | } | ||
1305 | |||
1306 | static void uvcg_frame_drop(struct config_group *group, struct config_item *item) | ||
1307 | { | ||
1308 | struct uvcg_frame *h = to_uvcg_frame(item); | ||
1309 | struct uvcg_format *fmt; | ||
1310 | struct f_uvc_opts *opts; | ||
1311 | struct config_item *opts_item; | ||
1312 | |||
1313 | opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; | ||
1314 | opts = to_f_uvc_opts(opts_item); | ||
1315 | |||
1316 | mutex_lock(&opts->lock); | ||
1317 | fmt = to_uvcg_format(&group->cg_item); | ||
1318 | --fmt->num_frames; | ||
1319 | kfree(h); | ||
1320 | mutex_unlock(&opts->lock); | ||
1321 | } | ||
1322 | |||
1323 | /* streaming/uncompressed/<NAME> */ | ||
1324 | struct uvcg_uncompressed { | ||
1325 | struct uvcg_format fmt; | ||
1326 | struct uvc_format_uncompressed desc; | ||
1327 | }; | ||
1328 | |||
1329 | static struct uvcg_uncompressed *to_uvcg_uncompressed(struct config_item *item) | ||
1330 | { | ||
1331 | return container_of( | ||
1332 | container_of(to_config_group(item), struct uvcg_format, group), | ||
1333 | struct uvcg_uncompressed, fmt); | ||
1334 | } | ||
1335 | |||
1336 | CONFIGFS_ATTR_STRUCT(uvcg_uncompressed); | ||
1337 | CONFIGFS_ATTR_OPS(uvcg_uncompressed); | ||
1338 | |||
1339 | static struct configfs_item_operations uvcg_uncompressed_item_ops = { | ||
1340 | .show_attribute = uvcg_uncompressed_attr_show, | ||
1341 | .store_attribute = uvcg_uncompressed_attr_store, | ||
1342 | }; | ||
1343 | |||
1344 | static struct configfs_group_operations uvcg_uncompressed_group_ops = { | ||
1345 | .make_item = uvcg_frame_make, | ||
1346 | .drop_item = uvcg_frame_drop, | ||
1347 | }; | ||
1348 | |||
1349 | static ssize_t uvcg_uncompressed_guid_format_show(struct uvcg_uncompressed *ch, | ||
1350 | char *page) | ||
1351 | { | ||
1352 | struct f_uvc_opts *opts; | ||
1353 | struct config_item *opts_item; | ||
1354 | struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex; | ||
1355 | |||
1356 | mutex_lock(su_mutex); /* for navigating configfs hierarchy */ | ||
1357 | |||
1358 | opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent; | ||
1359 | opts = to_f_uvc_opts(opts_item); | ||
1360 | |||
1361 | mutex_lock(&opts->lock); | ||
1362 | memcpy(page, ch->desc.guidFormat, sizeof(ch->desc.guidFormat)); | ||
1363 | mutex_unlock(&opts->lock); | ||
1364 | |||
1365 | mutex_unlock(su_mutex); | ||
1366 | |||
1367 | return sizeof(ch->desc.guidFormat); | ||
1368 | } | ||
1369 | |||
1370 | static ssize_t uvcg_uncompressed_guid_format_store(struct uvcg_uncompressed *ch, | ||
1371 | const char *page, size_t len) | ||
1372 | { | ||
1373 | struct f_uvc_opts *opts; | ||
1374 | struct config_item *opts_item; | ||
1375 | struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex; | ||
1376 | int ret; | ||
1377 | |||
1378 | mutex_lock(su_mutex); /* for navigating configfs hierarchy */ | ||
1379 | |||
1380 | opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent; | ||
1381 | opts = to_f_uvc_opts(opts_item); | ||
1382 | |||
1383 | mutex_lock(&opts->lock); | ||
1384 | if (ch->fmt.linked || opts->refcnt) { | ||
1385 | ret = -EBUSY; | ||
1386 | goto end; | ||
1387 | } | ||
1388 | |||
1389 | memcpy(ch->desc.guidFormat, page, | ||
1390 | min(sizeof(ch->desc.guidFormat), len)); | ||
1391 | ret = sizeof(ch->desc.guidFormat); | ||
1392 | |||
1393 | end: | ||
1394 | mutex_unlock(&opts->lock); | ||
1395 | mutex_unlock(su_mutex); | ||
1396 | return ret; | ||
1397 | } | ||
1398 | |||
1399 | static struct uvcg_uncompressed_attribute uvcg_uncompressed_guid_format = | ||
1400 | __CONFIGFS_ATTR(guidFormat, S_IRUGO | S_IWUSR, | ||
1401 | uvcg_uncompressed_guid_format_show, | ||
1402 | uvcg_uncompressed_guid_format_store); | ||
1403 | |||
1404 | |||
1405 | #define UVCG_UNCOMPRESSED_ATTR_RO(cname, aname, conv) \ | ||
1406 | static ssize_t uvcg_uncompressed_##cname##_show( \ | ||
1407 | struct uvcg_uncompressed *u, char *page) \ | ||
1408 | { \ | ||
1409 | struct f_uvc_opts *opts; \ | ||
1410 | struct config_item *opts_item; \ | ||
1411 | struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ | ||
1412 | int result; \ | ||
1413 | \ | ||
1414 | mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ | ||
1415 | \ | ||
1416 | opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ | ||
1417 | opts = to_f_uvc_opts(opts_item); \ | ||
1418 | \ | ||
1419 | mutex_lock(&opts->lock); \ | ||
1420 | result = sprintf(page, "%d\n", conv(u->desc.aname)); \ | ||
1421 | mutex_unlock(&opts->lock); \ | ||
1422 | \ | ||
1423 | mutex_unlock(su_mutex); \ | ||
1424 | return result; \ | ||
1425 | } \ | ||
1426 | \ | ||
1427 | static struct uvcg_uncompressed_attribute \ | ||
1428 | uvcg_uncompressed_##cname = \ | ||
1429 | __CONFIGFS_ATTR_RO(aname, uvcg_uncompressed_##cname##_show) | ||
1430 | |||
1431 | #define UVCG_UNCOMPRESSED_ATTR(cname, aname, conv) \ | ||
1432 | static ssize_t uvcg_uncompressed_##cname##_show( \ | ||
1433 | struct uvcg_uncompressed *u, char *page) \ | ||
1434 | { \ | ||
1435 | struct f_uvc_opts *opts; \ | ||
1436 | struct config_item *opts_item; \ | ||
1437 | struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ | ||
1438 | int result; \ | ||
1439 | \ | ||
1440 | mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ | ||
1441 | \ | ||
1442 | opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ | ||
1443 | opts = to_f_uvc_opts(opts_item); \ | ||
1444 | \ | ||
1445 | mutex_lock(&opts->lock); \ | ||
1446 | result = sprintf(page, "%d\n", conv(u->desc.aname)); \ | ||
1447 | mutex_unlock(&opts->lock); \ | ||
1448 | \ | ||
1449 | mutex_unlock(su_mutex); \ | ||
1450 | return result; \ | ||
1451 | } \ | ||
1452 | \ | ||
1453 | static ssize_t \ | ||
1454 | uvcg_uncompressed_##cname##_store(struct uvcg_uncompressed *u, \ | ||
1455 | const char *page, size_t len) \ | ||
1456 | { \ | ||
1457 | struct f_uvc_opts *opts; \ | ||
1458 | struct config_item *opts_item; \ | ||
1459 | struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ | ||
1460 | int ret; \ | ||
1461 | u8 num; \ | ||
1462 | \ | ||
1463 | mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ | ||
1464 | \ | ||
1465 | opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ | ||
1466 | opts = to_f_uvc_opts(opts_item); \ | ||
1467 | \ | ||
1468 | mutex_lock(&opts->lock); \ | ||
1469 | if (u->fmt.linked || opts->refcnt) { \ | ||
1470 | ret = -EBUSY; \ | ||
1471 | goto end; \ | ||
1472 | } \ | ||
1473 | \ | ||
1474 | ret = kstrtou8(page, 0, &num); \ | ||
1475 | if (ret) \ | ||
1476 | goto end; \ | ||
1477 | \ | ||
1478 | if (num > 255) { \ | ||
1479 | ret = -EINVAL; \ | ||
1480 | goto end; \ | ||
1481 | } \ | ||
1482 | u->desc.aname = num; \ | ||
1483 | ret = len; \ | ||
1484 | end: \ | ||
1485 | mutex_unlock(&opts->lock); \ | ||
1486 | mutex_unlock(su_mutex); \ | ||
1487 | return ret; \ | ||
1488 | } \ | ||
1489 | \ | ||
1490 | static struct uvcg_uncompressed_attribute \ | ||
1491 | uvcg_uncompressed_##cname = \ | ||
1492 | __CONFIGFS_ATTR(aname, S_IRUGO | S_IWUSR, \ | ||
1493 | uvcg_uncompressed_##cname##_show, \ | ||
1494 | uvcg_uncompressed_##cname##_store) | ||
1495 | |||
1496 | #define identity_conv(x) (x) | ||
1497 | |||
1498 | UVCG_UNCOMPRESSED_ATTR(b_bits_per_pixel, bBitsPerPixel, identity_conv); | ||
1499 | UVCG_UNCOMPRESSED_ATTR(b_default_frame_index, bDefaultFrameIndex, | ||
1500 | identity_conv); | ||
1501 | UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, identity_conv); | ||
1502 | UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, identity_conv); | ||
1503 | UVCG_UNCOMPRESSED_ATTR_RO(bm_interface_flags, bmInterfaceFlags, identity_conv); | ||
1504 | |||
1505 | #undef identity_conv | ||
1506 | |||
1507 | #undef UVCG_UNCOMPRESSED_ATTR | ||
1508 | #undef UVCG_UNCOMPRESSED_ATTR_RO | ||
1509 | |||
1510 | static inline ssize_t | ||
1511 | uvcg_uncompressed_bma_controls_show(struct uvcg_uncompressed *unc, char *page) | ||
1512 | { | ||
1513 | return uvcg_format_bma_controls_show(&unc->fmt, page); | ||
1514 | } | ||
1515 | |||
1516 | static inline ssize_t | ||
1517 | uvcg_uncompressed_bma_controls_store(struct uvcg_uncompressed *ch, | ||
1518 | const char *page, size_t len) | ||
1519 | { | ||
1520 | return uvcg_format_bma_controls_store(&ch->fmt, page, len); | ||
1521 | } | ||
1522 | |||
1523 | static struct uvcg_uncompressed_attribute uvcg_uncompressed_bma_controls = | ||
1524 | __CONFIGFS_ATTR(bmaControls, S_IRUGO | S_IWUSR, | ||
1525 | uvcg_uncompressed_bma_controls_show, | ||
1526 | uvcg_uncompressed_bma_controls_store); | ||
1527 | |||
1528 | static struct configfs_attribute *uvcg_uncompressed_attrs[] = { | ||
1529 | &uvcg_uncompressed_guid_format.attr, | ||
1530 | &uvcg_uncompressed_b_bits_per_pixel.attr, | ||
1531 | &uvcg_uncompressed_b_default_frame_index.attr, | ||
1532 | &uvcg_uncompressed_b_aspect_ratio_x.attr, | ||
1533 | &uvcg_uncompressed_b_aspect_ratio_y.attr, | ||
1534 | &uvcg_uncompressed_bm_interface_flags.attr, | ||
1535 | &uvcg_uncompressed_bma_controls.attr, | ||
1536 | NULL, | ||
1537 | }; | ||
1538 | |||
1539 | static struct config_item_type uvcg_uncompressed_type = { | ||
1540 | .ct_item_ops = &uvcg_uncompressed_item_ops, | ||
1541 | .ct_group_ops = &uvcg_uncompressed_group_ops, | ||
1542 | .ct_attrs = uvcg_uncompressed_attrs, | ||
1543 | .ct_owner = THIS_MODULE, | ||
1544 | }; | ||
1545 | |||
1546 | static struct config_group *uvcg_uncompressed_make(struct config_group *group, | ||
1547 | const char *name) | ||
1548 | { | ||
1549 | static char guid[] = { | ||
1550 | 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, | ||
1551 | 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 | ||
1552 | }; | ||
1553 | struct uvcg_uncompressed *h; | ||
1554 | |||
1555 | h = kzalloc(sizeof(*h), GFP_KERNEL); | ||
1556 | if (!h) | ||
1557 | return ERR_PTR(-ENOMEM); | ||
1558 | |||
1559 | h->desc.bLength = UVC_DT_FORMAT_UNCOMPRESSED_SIZE; | ||
1560 | h->desc.bDescriptorType = USB_DT_CS_INTERFACE; | ||
1561 | h->desc.bDescriptorSubType = UVC_VS_FORMAT_UNCOMPRESSED; | ||
1562 | memcpy(h->desc.guidFormat, guid, sizeof(guid)); | ||
1563 | h->desc.bBitsPerPixel = 16; | ||
1564 | h->desc.bDefaultFrameIndex = 1; | ||
1565 | h->desc.bAspectRatioX = 0; | ||
1566 | h->desc.bAspectRatioY = 0; | ||
1567 | h->desc.bmInterfaceFlags = 0; | ||
1568 | h->desc.bCopyProtect = 0; | ||
1569 | |||
1570 | h->fmt.type = UVCG_UNCOMPRESSED; | ||
1571 | config_group_init_type_name(&h->fmt.group, name, | ||
1572 | &uvcg_uncompressed_type); | ||
1573 | |||
1574 | return &h->fmt.group; | ||
1575 | } | ||
1576 | |||
1577 | static void uvcg_uncompressed_drop(struct config_group *group, | ||
1578 | struct config_item *item) | ||
1579 | { | ||
1580 | struct uvcg_uncompressed *h = to_uvcg_uncompressed(item); | ||
1581 | |||
1582 | kfree(h); | ||
1583 | } | ||
1584 | |||
1585 | static struct configfs_group_operations uvcg_uncompressed_grp_ops = { | ||
1586 | .make_group = uvcg_uncompressed_make, | ||
1587 | .drop_item = uvcg_uncompressed_drop, | ||
1588 | }; | ||
1589 | |||
1590 | static struct config_item_type uvcg_uncompressed_grp_type = { | ||
1591 | .ct_group_ops = &uvcg_uncompressed_grp_ops, | ||
1592 | .ct_owner = THIS_MODULE, | ||
1593 | }; | ||
1594 | |||
1595 | /* streaming/mjpeg/<NAME> */ | ||
1596 | struct uvcg_mjpeg { | ||
1597 | struct uvcg_format fmt; | ||
1598 | struct uvc_format_mjpeg desc; | ||
1599 | }; | ||
1600 | |||
1601 | static struct uvcg_mjpeg *to_uvcg_mjpeg(struct config_item *item) | ||
1602 | { | ||
1603 | return container_of( | ||
1604 | container_of(to_config_group(item), struct uvcg_format, group), | ||
1605 | struct uvcg_mjpeg, fmt); | ||
1606 | } | ||
1607 | |||
1608 | CONFIGFS_ATTR_STRUCT(uvcg_mjpeg); | ||
1609 | CONFIGFS_ATTR_OPS(uvcg_mjpeg); | ||
1610 | |||
1611 | static struct configfs_item_operations uvcg_mjpeg_item_ops = { | ||
1612 | .show_attribute = uvcg_mjpeg_attr_show, | ||
1613 | .store_attribute = uvcg_mjpeg_attr_store, | ||
1614 | }; | ||
1615 | |||
1616 | static struct configfs_group_operations uvcg_mjpeg_group_ops = { | ||
1617 | .make_item = uvcg_frame_make, | ||
1618 | .drop_item = uvcg_frame_drop, | ||
1619 | }; | ||
1620 | |||
1621 | #define UVCG_MJPEG_ATTR_RO(cname, aname, conv) \ | ||
1622 | static ssize_t uvcg_mjpeg_##cname##_show(struct uvcg_mjpeg *u, char *page)\ | ||
1623 | { \ | ||
1624 | struct f_uvc_opts *opts; \ | ||
1625 | struct config_item *opts_item; \ | ||
1626 | struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ | ||
1627 | int result; \ | ||
1628 | \ | ||
1629 | mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ | ||
1630 | \ | ||
1631 | opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ | ||
1632 | opts = to_f_uvc_opts(opts_item); \ | ||
1633 | \ | ||
1634 | mutex_lock(&opts->lock); \ | ||
1635 | result = sprintf(page, "%d\n", conv(u->desc.aname)); \ | ||
1636 | mutex_unlock(&opts->lock); \ | ||
1637 | \ | ||
1638 | mutex_unlock(su_mutex); \ | ||
1639 | return result; \ | ||
1640 | } \ | ||
1641 | \ | ||
1642 | static struct uvcg_mjpeg_attribute \ | ||
1643 | uvcg_mjpeg_##cname = \ | ||
1644 | __CONFIGFS_ATTR_RO(aname, uvcg_mjpeg_##cname##_show) | ||
1645 | |||
1646 | #define UVCG_MJPEG_ATTR(cname, aname, conv) \ | ||
1647 | static ssize_t uvcg_mjpeg_##cname##_show(struct uvcg_mjpeg *u, char *page)\ | ||
1648 | { \ | ||
1649 | struct f_uvc_opts *opts; \ | ||
1650 | struct config_item *opts_item; \ | ||
1651 | struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ | ||
1652 | int result; \ | ||
1653 | \ | ||
1654 | mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ | ||
1655 | \ | ||
1656 | opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ | ||
1657 | opts = to_f_uvc_opts(opts_item); \ | ||
1658 | \ | ||
1659 | mutex_lock(&opts->lock); \ | ||
1660 | result = sprintf(page, "%d\n", conv(u->desc.aname)); \ | ||
1661 | mutex_unlock(&opts->lock); \ | ||
1662 | \ | ||
1663 | mutex_unlock(su_mutex); \ | ||
1664 | return result; \ | ||
1665 | } \ | ||
1666 | \ | ||
1667 | static ssize_t \ | ||
1668 | uvcg_mjpeg_##cname##_store(struct uvcg_mjpeg *u, \ | ||
1669 | const char *page, size_t len) \ | ||
1670 | { \ | ||
1671 | struct f_uvc_opts *opts; \ | ||
1672 | struct config_item *opts_item; \ | ||
1673 | struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ | ||
1674 | int ret; \ | ||
1675 | u8 num; \ | ||
1676 | \ | ||
1677 | mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ | ||
1678 | \ | ||
1679 | opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ | ||
1680 | opts = to_f_uvc_opts(opts_item); \ | ||
1681 | \ | ||
1682 | mutex_lock(&opts->lock); \ | ||
1683 | if (u->fmt.linked || opts->refcnt) { \ | ||
1684 | ret = -EBUSY; \ | ||
1685 | goto end; \ | ||
1686 | } \ | ||
1687 | \ | ||
1688 | ret = kstrtou8(page, 0, &num); \ | ||
1689 | if (ret) \ | ||
1690 | goto end; \ | ||
1691 | \ | ||
1692 | if (num > 255) { \ | ||
1693 | ret = -EINVAL; \ | ||
1694 | goto end; \ | ||
1695 | } \ | ||
1696 | u->desc.aname = num; \ | ||
1697 | ret = len; \ | ||
1698 | end: \ | ||
1699 | mutex_unlock(&opts->lock); \ | ||
1700 | mutex_unlock(su_mutex); \ | ||
1701 | return ret; \ | ||
1702 | } \ | ||
1703 | \ | ||
1704 | static struct uvcg_mjpeg_attribute \ | ||
1705 | uvcg_mjpeg_##cname = \ | ||
1706 | __CONFIGFS_ATTR(aname, S_IRUGO | S_IWUSR, \ | ||
1707 | uvcg_mjpeg_##cname##_show, \ | ||
1708 | uvcg_mjpeg_##cname##_store) | ||
1709 | |||
1710 | #define identity_conv(x) (x) | ||
1711 | |||
1712 | UVCG_MJPEG_ATTR(b_default_frame_index, bDefaultFrameIndex, | ||
1713 | identity_conv); | ||
1714 | UVCG_MJPEG_ATTR_RO(bm_flags, bmFlags, identity_conv); | ||
1715 | UVCG_MJPEG_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, identity_conv); | ||
1716 | UVCG_MJPEG_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, identity_conv); | ||
1717 | UVCG_MJPEG_ATTR_RO(bm_interface_flags, bmInterfaceFlags, identity_conv); | ||
1718 | |||
1719 | #undef identity_conv | ||
1720 | |||
1721 | #undef UVCG_MJPEG_ATTR | ||
1722 | #undef UVCG_MJPEG_ATTR_RO | ||
1723 | |||
1724 | static inline ssize_t | ||
1725 | uvcg_mjpeg_bma_controls_show(struct uvcg_mjpeg *unc, char *page) | ||
1726 | { | ||
1727 | return uvcg_format_bma_controls_show(&unc->fmt, page); | ||
1728 | } | ||
1729 | |||
1730 | static inline ssize_t | ||
1731 | uvcg_mjpeg_bma_controls_store(struct uvcg_mjpeg *ch, | ||
1732 | const char *page, size_t len) | ||
1733 | { | ||
1734 | return uvcg_format_bma_controls_store(&ch->fmt, page, len); | ||
1735 | } | ||
1736 | |||
1737 | static struct uvcg_mjpeg_attribute uvcg_mjpeg_bma_controls = | ||
1738 | __CONFIGFS_ATTR(bmaControls, S_IRUGO | S_IWUSR, | ||
1739 | uvcg_mjpeg_bma_controls_show, | ||
1740 | uvcg_mjpeg_bma_controls_store); | ||
1741 | |||
1742 | static struct configfs_attribute *uvcg_mjpeg_attrs[] = { | ||
1743 | &uvcg_mjpeg_b_default_frame_index.attr, | ||
1744 | &uvcg_mjpeg_bm_flags.attr, | ||
1745 | &uvcg_mjpeg_b_aspect_ratio_x.attr, | ||
1746 | &uvcg_mjpeg_b_aspect_ratio_y.attr, | ||
1747 | &uvcg_mjpeg_bm_interface_flags.attr, | ||
1748 | &uvcg_mjpeg_bma_controls.attr, | ||
1749 | NULL, | ||
1750 | }; | ||
1751 | |||
1752 | static struct config_item_type uvcg_mjpeg_type = { | ||
1753 | .ct_item_ops = &uvcg_mjpeg_item_ops, | ||
1754 | .ct_group_ops = &uvcg_mjpeg_group_ops, | ||
1755 | .ct_attrs = uvcg_mjpeg_attrs, | ||
1756 | .ct_owner = THIS_MODULE, | ||
1757 | }; | ||
1758 | |||
1759 | static struct config_group *uvcg_mjpeg_make(struct config_group *group, | ||
1760 | const char *name) | ||
1761 | { | ||
1762 | struct uvcg_mjpeg *h; | ||
1763 | |||
1764 | h = kzalloc(sizeof(*h), GFP_KERNEL); | ||
1765 | if (!h) | ||
1766 | return ERR_PTR(-ENOMEM); | ||
1767 | |||
1768 | h->desc.bLength = UVC_DT_FORMAT_MJPEG_SIZE; | ||
1769 | h->desc.bDescriptorType = USB_DT_CS_INTERFACE; | ||
1770 | h->desc.bDescriptorSubType = UVC_VS_FORMAT_MJPEG; | ||
1771 | h->desc.bDefaultFrameIndex = 1; | ||
1772 | h->desc.bAspectRatioX = 0; | ||
1773 | h->desc.bAspectRatioY = 0; | ||
1774 | h->desc.bmInterfaceFlags = 0; | ||
1775 | h->desc.bCopyProtect = 0; | ||
1776 | |||
1777 | h->fmt.type = UVCG_MJPEG; | ||
1778 | config_group_init_type_name(&h->fmt.group, name, | ||
1779 | &uvcg_mjpeg_type); | ||
1780 | |||
1781 | return &h->fmt.group; | ||
1782 | } | ||
1783 | |||
1784 | static void uvcg_mjpeg_drop(struct config_group *group, | ||
1785 | struct config_item *item) | ||
1786 | { | ||
1787 | struct uvcg_mjpeg *h = to_uvcg_mjpeg(item); | ||
1788 | |||
1789 | kfree(h); | ||
1790 | } | ||
1791 | |||
1792 | static struct configfs_group_operations uvcg_mjpeg_grp_ops = { | ||
1793 | .make_group = uvcg_mjpeg_make, | ||
1794 | .drop_item = uvcg_mjpeg_drop, | ||
1795 | }; | ||
1796 | |||
1797 | static struct config_item_type uvcg_mjpeg_grp_type = { | ||
1798 | .ct_group_ops = &uvcg_mjpeg_grp_ops, | ||
1799 | .ct_owner = THIS_MODULE, | ||
1800 | }; | ||
1801 | |||
1802 | /* streaming/color_matching/default */ | ||
1803 | static struct uvcg_default_color_matching { | ||
1804 | struct config_group group; | ||
1805 | } uvcg_default_color_matching; | ||
1806 | |||
1807 | static inline struct uvcg_default_color_matching | ||
1808 | *to_uvcg_default_color_matching(struct config_item *item) | ||
1809 | { | ||
1810 | return container_of(to_config_group(item), | ||
1811 | struct uvcg_default_color_matching, group); | ||
1812 | } | ||
1813 | |||
1814 | CONFIGFS_ATTR_STRUCT(uvcg_default_color_matching); | ||
1815 | CONFIGFS_ATTR_OPS_RO(uvcg_default_color_matching); | ||
1816 | |||
1817 | static struct configfs_item_operations uvcg_default_color_matching_item_ops = { | ||
1818 | .show_attribute = uvcg_default_color_matching_attr_show, | ||
1819 | }; | ||
1820 | |||
1821 | #define UVCG_DEFAULT_COLOR_MATCHING_ATTR(cname, aname, conv) \ | ||
1822 | static ssize_t uvcg_default_color_matching_##cname##_show( \ | ||
1823 | struct uvcg_default_color_matching *dc, char *page) \ | ||
1824 | { \ | ||
1825 | struct f_uvc_opts *opts; \ | ||
1826 | struct config_item *opts_item; \ | ||
1827 | struct mutex *su_mutex = &dc->group.cg_subsys->su_mutex; \ | ||
1828 | struct uvc_color_matching_descriptor *cd; \ | ||
1829 | int result; \ | ||
1830 | \ | ||
1831 | mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ | ||
1832 | \ | ||
1833 | opts_item = dc->group.cg_item.ci_parent->ci_parent->ci_parent; \ | ||
1834 | opts = to_f_uvc_opts(opts_item); \ | ||
1835 | cd = &opts->uvc_color_matching; \ | ||
1836 | \ | ||
1837 | mutex_lock(&opts->lock); \ | ||
1838 | result = sprintf(page, "%d\n", conv(cd->aname)); \ | ||
1839 | mutex_unlock(&opts->lock); \ | ||
1840 | \ | ||
1841 | mutex_unlock(su_mutex); \ | ||
1842 | return result; \ | ||
1843 | } \ | ||
1844 | \ | ||
1845 | static struct uvcg_default_color_matching_attribute \ | ||
1846 | uvcg_default_color_matching_##cname = \ | ||
1847 | __CONFIGFS_ATTR_RO(aname, uvcg_default_color_matching_##cname##_show) | ||
1848 | |||
1849 | #define identity_conv(x) (x) | ||
1850 | |||
1851 | UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_color_primaries, bColorPrimaries, | ||
1852 | identity_conv); | ||
1853 | UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_transfer_characteristics, | ||
1854 | bTransferCharacteristics, identity_conv); | ||
1855 | UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_matrix_coefficients, bMatrixCoefficients, | ||
1856 | identity_conv); | ||
1857 | |||
1858 | #undef identity_conv | ||
1859 | |||
1860 | #undef UVCG_DEFAULT_COLOR_MATCHING_ATTR | ||
1861 | |||
1862 | static struct configfs_attribute *uvcg_default_color_matching_attrs[] = { | ||
1863 | &uvcg_default_color_matching_b_color_primaries.attr, | ||
1864 | &uvcg_default_color_matching_b_transfer_characteristics.attr, | ||
1865 | &uvcg_default_color_matching_b_matrix_coefficients.attr, | ||
1866 | NULL, | ||
1867 | }; | ||
1868 | |||
1869 | static struct config_item_type uvcg_default_color_matching_type = { | ||
1870 | .ct_item_ops = &uvcg_default_color_matching_item_ops, | ||
1871 | .ct_attrs = uvcg_default_color_matching_attrs, | ||
1872 | .ct_owner = THIS_MODULE, | ||
1873 | }; | ||
1874 | |||
1875 | /* struct uvcg_color_matching {}; */ | ||
1876 | |||
1877 | static struct config_group *uvcg_color_matching_default_groups[] = { | ||
1878 | &uvcg_default_color_matching.group, | ||
1879 | NULL, | ||
1880 | }; | ||
1881 | |||
1882 | /* streaming/color_matching */ | ||
1883 | static struct uvcg_color_matching_grp { | ||
1884 | struct config_group group; | ||
1885 | } uvcg_color_matching_grp; | ||
1886 | |||
1887 | static struct config_item_type uvcg_color_matching_grp_type = { | ||
1888 | .ct_owner = THIS_MODULE, | ||
1889 | }; | ||
1890 | |||
1891 | /* streaming/class/{fs|hs|ss} */ | ||
1892 | static struct uvcg_streaming_class { | ||
1893 | struct config_group group; | ||
1894 | } uvcg_streaming_class_fs, uvcg_streaming_class_hs, uvcg_streaming_class_ss; | ||
1895 | |||
1896 | |||
1897 | static inline struct uvc_descriptor_header | ||
1898 | ***__uvcg_get_stream_class_arr(struct config_item *i, struct f_uvc_opts *o) | ||
1899 | { | ||
1900 | struct uvcg_streaming_class *cl = container_of(to_config_group(i), | ||
1901 | struct uvcg_streaming_class, group); | ||
1902 | |||
1903 | if (cl == &uvcg_streaming_class_fs) | ||
1904 | return &o->uvc_fs_streaming_cls; | ||
1905 | |||
1906 | if (cl == &uvcg_streaming_class_hs) | ||
1907 | return &o->uvc_hs_streaming_cls; | ||
1908 | |||
1909 | if (cl == &uvcg_streaming_class_ss) | ||
1910 | return &o->uvc_ss_streaming_cls; | ||
1911 | |||
1912 | return NULL; | ||
1913 | } | ||
1914 | |||
1915 | enum uvcg_strm_type { | ||
1916 | UVCG_HEADER = 0, | ||
1917 | UVCG_FORMAT, | ||
1918 | UVCG_FRAME | ||
1919 | }; | ||
1920 | |||
1921 | /* | ||
1922 | * Iterate over a hierarchy of streaming descriptors' config items. | ||
1923 | * The items are created by the user with configfs. | ||
1924 | * | ||
1925 | * It "processes" the header pointed to by @priv1, then for each format | ||
1926 | * that follows the header "processes" the format itself and then for | ||
1927 | * each frame inside a format "processes" the frame. | ||
1928 | * | ||
1929 | * As a "processing" function the @fun is used. | ||
1930 | * | ||
1931 | * __uvcg_iter_strm_cls() is used in two context: first, to calculate | ||
1932 | * the amount of memory needed for an array of streaming descriptors | ||
1933 | * and second, to actually fill the array. | ||
1934 | * | ||
1935 | * @h: streaming header pointer | ||
1936 | * @priv2: an "inout" parameter (the caller might want to see the changes to it) | ||
1937 | * @priv3: an "inout" parameter (the caller might want to see the changes to it) | ||
1938 | * @fun: callback function for processing each level of the hierarchy | ||
1939 | */ | ||
1940 | static int __uvcg_iter_strm_cls(struct uvcg_streaming_header *h, | ||
1941 | void *priv2, void *priv3, | ||
1942 | int (*fun)(void *, void *, void *, int, enum uvcg_strm_type type)) | ||
1943 | { | ||
1944 | struct uvcg_format_ptr *f; | ||
1945 | struct config_group *grp; | ||
1946 | struct config_item *item; | ||
1947 | struct uvcg_frame *frm; | ||
1948 | int ret, i, j; | ||
1949 | |||
1950 | if (!fun) | ||
1951 | return -EINVAL; | ||
1952 | |||
1953 | i = j = 0; | ||
1954 | ret = fun(h, priv2, priv3, 0, UVCG_HEADER); | ||
1955 | if (ret) | ||
1956 | return ret; | ||
1957 | list_for_each_entry(f, &h->formats, entry) { | ||
1958 | ret = fun(f->fmt, priv2, priv3, i++, UVCG_FORMAT); | ||
1959 | if (ret) | ||
1960 | return ret; | ||
1961 | grp = &f->fmt->group; | ||
1962 | list_for_each_entry(item, &grp->cg_children, ci_entry) { | ||
1963 | frm = to_uvcg_frame(item); | ||
1964 | ret = fun(frm, priv2, priv3, j++, UVCG_FRAME); | ||
1965 | if (ret) | ||
1966 | return ret; | ||
1967 | } | ||
1968 | } | ||
1969 | |||
1970 | return ret; | ||
1971 | } | ||
1972 | |||
1973 | /* | ||
1974 | * Count how many bytes are needed for an array of streaming descriptors. | ||
1975 | * | ||
1976 | * @priv1: pointer to a header, format or frame | ||
1977 | * @priv2: inout parameter, accumulated size of the array | ||
1978 | * @priv3: inout parameter, accumulated number of the array elements | ||
1979 | * @n: unused, this function's prototype must match @fun in __uvcg_iter_strm_cls | ||
1980 | */ | ||
1981 | static int __uvcg_cnt_strm(void *priv1, void *priv2, void *priv3, int n, | ||
1982 | enum uvcg_strm_type type) | ||
1983 | { | ||
1984 | size_t *size = priv2; | ||
1985 | size_t *count = priv3; | ||
1986 | |||
1987 | switch (type) { | ||
1988 | case UVCG_HEADER: { | ||
1989 | struct uvcg_streaming_header *h = priv1; | ||
1990 | |||
1991 | *size += sizeof(h->desc); | ||
1992 | /* bmaControls */ | ||
1993 | *size += h->num_fmt * UVCG_STREAMING_CONTROL_SIZE; | ||
1994 | } | ||
1995 | break; | ||
1996 | case UVCG_FORMAT: { | ||
1997 | struct uvcg_format *fmt = priv1; | ||
1998 | |||
1999 | if (fmt->type == UVCG_UNCOMPRESSED) { | ||
2000 | struct uvcg_uncompressed *u = | ||
2001 | container_of(fmt, struct uvcg_uncompressed, | ||
2002 | fmt); | ||
2003 | |||
2004 | *size += sizeof(u->desc); | ||
2005 | } else if (fmt->type == UVCG_MJPEG) { | ||
2006 | struct uvcg_mjpeg *m = | ||
2007 | container_of(fmt, struct uvcg_mjpeg, fmt); | ||
2008 | |||
2009 | *size += sizeof(m->desc); | ||
2010 | } else { | ||
2011 | return -EINVAL; | ||
2012 | } | ||
2013 | } | ||
2014 | break; | ||
2015 | case UVCG_FRAME: { | ||
2016 | struct uvcg_frame *frm = priv1; | ||
2017 | int sz = sizeof(frm->dw_frame_interval); | ||
2018 | |||
2019 | *size += sizeof(frm->frame); | ||
2020 | *size += frm->frame.b_frame_interval_type * sz; | ||
2021 | } | ||
2022 | break; | ||
2023 | } | ||
2024 | |||
2025 | ++*count; | ||
2026 | |||
2027 | return 0; | ||
2028 | } | ||
2029 | |||
2030 | /* | ||
2031 | * Fill an array of streaming descriptors. | ||
2032 | * | ||
2033 | * @priv1: pointer to a header, format or frame | ||
2034 | * @priv2: inout parameter, pointer into a block of memory | ||
2035 | * @priv3: inout parameter, pointer to a 2-dimensional array | ||
2036 | */ | ||
2037 | static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n, | ||
2038 | enum uvcg_strm_type type) | ||
2039 | { | ||
2040 | void **dest = priv2; | ||
2041 | struct uvc_descriptor_header ***array = priv3; | ||
2042 | size_t sz; | ||
2043 | |||
2044 | **array = *dest; | ||
2045 | ++*array; | ||
2046 | |||
2047 | switch (type) { | ||
2048 | case UVCG_HEADER: { | ||
2049 | struct uvc_input_header_descriptor *ihdr = *dest; | ||
2050 | struct uvcg_streaming_header *h = priv1; | ||
2051 | struct uvcg_format_ptr *f; | ||
2052 | |||
2053 | memcpy(*dest, &h->desc, sizeof(h->desc)); | ||
2054 | *dest += sizeof(h->desc); | ||
2055 | sz = UVCG_STREAMING_CONTROL_SIZE; | ||
2056 | list_for_each_entry(f, &h->formats, entry) { | ||
2057 | memcpy(*dest, f->fmt->bmaControls, sz); | ||
2058 | *dest += sz; | ||
2059 | } | ||
2060 | ihdr->bLength = sizeof(h->desc) + h->num_fmt * sz; | ||
2061 | ihdr->bNumFormats = h->num_fmt; | ||
2062 | } | ||
2063 | break; | ||
2064 | case UVCG_FORMAT: { | ||
2065 | struct uvcg_format *fmt = priv1; | ||
2066 | |||
2067 | if (fmt->type == UVCG_UNCOMPRESSED) { | ||
2068 | struct uvc_format_uncompressed *unc = *dest; | ||
2069 | struct uvcg_uncompressed *u = | ||
2070 | container_of(fmt, struct uvcg_uncompressed, | ||
2071 | fmt); | ||
2072 | |||
2073 | memcpy(*dest, &u->desc, sizeof(u->desc)); | ||
2074 | *dest += sizeof(u->desc); | ||
2075 | unc->bNumFrameDescriptors = fmt->num_frames; | ||
2076 | unc->bFormatIndex = n + 1; | ||
2077 | } else if (fmt->type == UVCG_MJPEG) { | ||
2078 | struct uvc_format_mjpeg *mjp = *dest; | ||
2079 | struct uvcg_mjpeg *m = | ||
2080 | container_of(fmt, struct uvcg_mjpeg, fmt); | ||
2081 | |||
2082 | memcpy(*dest, &m->desc, sizeof(m->desc)); | ||
2083 | *dest += sizeof(m->desc); | ||
2084 | mjp->bNumFrameDescriptors = fmt->num_frames; | ||
2085 | mjp->bFormatIndex = n + 1; | ||
2086 | } else { | ||
2087 | return -EINVAL; | ||
2088 | } | ||
2089 | } | ||
2090 | break; | ||
2091 | case UVCG_FRAME: { | ||
2092 | struct uvcg_frame *frm = priv1; | ||
2093 | struct uvc_descriptor_header *h = *dest; | ||
2094 | |||
2095 | sz = sizeof(frm->frame); | ||
2096 | memcpy(*dest, &frm->frame, sz); | ||
2097 | *dest += sz; | ||
2098 | sz = frm->frame.b_frame_interval_type * | ||
2099 | sizeof(*frm->dw_frame_interval); | ||
2100 | memcpy(*dest, frm->dw_frame_interval, sz); | ||
2101 | *dest += sz; | ||
2102 | if (frm->fmt_type == UVCG_UNCOMPRESSED) | ||
2103 | h->bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE( | ||
2104 | frm->frame.b_frame_interval_type); | ||
2105 | else if (frm->fmt_type == UVCG_MJPEG) | ||
2106 | h->bLength = UVC_DT_FRAME_MJPEG_SIZE( | ||
2107 | frm->frame.b_frame_interval_type); | ||
2108 | } | ||
2109 | break; | ||
2110 | } | ||
2111 | |||
2112 | return 0; | ||
2113 | } | ||
2114 | |||
2115 | static int uvcg_streaming_class_allow_link(struct config_item *src, | ||
2116 | struct config_item *target) | ||
2117 | { | ||
2118 | struct config_item *streaming, *header; | ||
2119 | struct f_uvc_opts *opts; | ||
2120 | struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; | ||
2121 | struct uvc_descriptor_header ***class_array, **cl_arr; | ||
2122 | struct uvcg_streaming_header *target_hdr; | ||
2123 | void *data, *data_save; | ||
2124 | size_t size = 0, count = 0; | ||
2125 | int ret = -EINVAL; | ||
2126 | |||
2127 | mutex_lock(su_mutex); /* for navigating configfs hierarchy */ | ||
2128 | |||
2129 | streaming = src->ci_parent->ci_parent; | ||
2130 | header = config_group_find_item(to_config_group(streaming), "header"); | ||
2131 | if (!header || target->ci_parent != header) | ||
2132 | goto out; | ||
2133 | |||
2134 | opts = to_f_uvc_opts(streaming->ci_parent); | ||
2135 | |||
2136 | mutex_lock(&opts->lock); | ||
2137 | |||
2138 | class_array = __uvcg_get_stream_class_arr(src, opts); | ||
2139 | if (!class_array || *class_array || opts->refcnt) { | ||
2140 | ret = -EBUSY; | ||
2141 | goto unlock; | ||
2142 | } | ||
2143 | |||
2144 | target_hdr = to_uvcg_streaming_header(target); | ||
2145 | ret = __uvcg_iter_strm_cls(target_hdr, &size, &count, __uvcg_cnt_strm); | ||
2146 | if (ret) | ||
2147 | goto unlock; | ||
2148 | |||
2149 | count += 2; /* color_matching, NULL */ | ||
2150 | *class_array = kcalloc(count, sizeof(void *), GFP_KERNEL); | ||
2151 | if (!*class_array) { | ||
2152 | ret = -ENOMEM; | ||
2153 | goto unlock; | ||
2154 | } | ||
2155 | |||
2156 | data = data_save = kzalloc(size, GFP_KERNEL); | ||
2157 | if (!data) { | ||
2158 | kfree(*class_array); | ||
2159 | *class_array = NULL; | ||
2160 | ret = PTR_ERR(data); | ||
2161 | goto unlock; | ||
2162 | } | ||
2163 | cl_arr = *class_array; | ||
2164 | ret = __uvcg_iter_strm_cls(target_hdr, &data, &cl_arr, | ||
2165 | __uvcg_fill_strm); | ||
2166 | if (ret) { | ||
2167 | kfree(*class_array); | ||
2168 | *class_array = NULL; | ||
2169 | /* | ||
2170 | * __uvcg_fill_strm() called from __uvcg_iter_stream_cls() | ||
2171 | * might have advanced the "data", so use a backup copy | ||
2172 | */ | ||
2173 | kfree(data_save); | ||
2174 | goto unlock; | ||
2175 | } | ||
2176 | *cl_arr = (struct uvc_descriptor_header *)&opts->uvc_color_matching; | ||
2177 | |||
2178 | ++target_hdr->linked; | ||
2179 | ret = 0; | ||
2180 | |||
2181 | unlock: | ||
2182 | mutex_unlock(&opts->lock); | ||
2183 | out: | ||
2184 | mutex_unlock(su_mutex); | ||
2185 | return ret; | ||
2186 | } | ||
2187 | |||
2188 | static int uvcg_streaming_class_drop_link(struct config_item *src, | ||
2189 | struct config_item *target) | ||
2190 | { | ||
2191 | struct config_item *streaming, *header; | ||
2192 | struct f_uvc_opts *opts; | ||
2193 | struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; | ||
2194 | struct uvc_descriptor_header ***class_array; | ||
2195 | struct uvcg_streaming_header *target_hdr; | ||
2196 | int ret = -EINVAL; | ||
2197 | |||
2198 | mutex_lock(su_mutex); /* for navigating configfs hierarchy */ | ||
2199 | |||
2200 | streaming = src->ci_parent->ci_parent; | ||
2201 | header = config_group_find_item(to_config_group(streaming), "header"); | ||
2202 | if (!header || target->ci_parent != header) | ||
2203 | goto out; | ||
2204 | |||
2205 | opts = to_f_uvc_opts(streaming->ci_parent); | ||
2206 | |||
2207 | mutex_lock(&opts->lock); | ||
2208 | |||
2209 | class_array = __uvcg_get_stream_class_arr(src, opts); | ||
2210 | if (!class_array || !*class_array) | ||
2211 | goto unlock; | ||
2212 | |||
2213 | if (opts->refcnt) { | ||
2214 | ret = -EBUSY; | ||
2215 | goto unlock; | ||
2216 | } | ||
2217 | |||
2218 | target_hdr = to_uvcg_streaming_header(target); | ||
2219 | --target_hdr->linked; | ||
2220 | kfree(**class_array); | ||
2221 | kfree(*class_array); | ||
2222 | *class_array = NULL; | ||
2223 | ret = 0; | ||
2224 | |||
2225 | unlock: | ||
2226 | mutex_unlock(&opts->lock); | ||
2227 | out: | ||
2228 | mutex_unlock(su_mutex); | ||
2229 | return ret; | ||
2230 | } | ||
2231 | |||
2232 | static struct configfs_item_operations uvcg_streaming_class_item_ops = { | ||
2233 | .allow_link = uvcg_streaming_class_allow_link, | ||
2234 | .drop_link = uvcg_streaming_class_drop_link, | ||
2235 | }; | ||
2236 | |||
2237 | static struct config_item_type uvcg_streaming_class_type = { | ||
2238 | .ct_item_ops = &uvcg_streaming_class_item_ops, | ||
2239 | .ct_owner = THIS_MODULE, | ||
2240 | }; | ||
2241 | |||
2242 | static struct config_group *uvcg_streaming_class_default_groups[] = { | ||
2243 | &uvcg_streaming_class_fs.group, | ||
2244 | &uvcg_streaming_class_hs.group, | ||
2245 | &uvcg_streaming_class_ss.group, | ||
2246 | NULL, | ||
2247 | }; | ||
2248 | |||
2249 | /* streaming/class */ | ||
2250 | static struct uvcg_streaming_class_grp { | ||
2251 | struct config_group group; | ||
2252 | } uvcg_streaming_class_grp; | ||
2253 | |||
2254 | static struct config_item_type uvcg_streaming_class_grp_type = { | ||
2255 | .ct_owner = THIS_MODULE, | ||
2256 | }; | ||
2257 | |||
2258 | static struct config_group *uvcg_streaming_default_groups[] = { | ||
2259 | &uvcg_streaming_header_grp.group, | ||
2260 | &uvcg_uncompressed_grp.group, | ||
2261 | &uvcg_mjpeg_grp.group, | ||
2262 | &uvcg_color_matching_grp.group, | ||
2263 | &uvcg_streaming_class_grp.group, | ||
2264 | NULL, | ||
2265 | }; | ||
2266 | |||
2267 | /* streaming */ | ||
2268 | static struct uvcg_streaming_grp { | ||
2269 | struct config_group group; | ||
2270 | } uvcg_streaming_grp; | ||
2271 | |||
2272 | static struct config_item_type uvcg_streaming_grp_type = { | ||
2273 | .ct_owner = THIS_MODULE, | ||
2274 | }; | ||
2275 | |||
2276 | static struct config_group *uvcg_default_groups[] = { | ||
2277 | &uvcg_control_grp.group, | ||
2278 | &uvcg_streaming_grp.group, | ||
2279 | NULL, | ||
2280 | }; | ||
2281 | |||
2282 | static inline struct f_uvc_opts *to_f_uvc_opts(struct config_item *item) | ||
2283 | { | ||
2284 | return container_of(to_config_group(item), struct f_uvc_opts, | ||
2285 | func_inst.group); | ||
2286 | } | ||
2287 | |||
2288 | CONFIGFS_ATTR_STRUCT(f_uvc_opts); | ||
2289 | CONFIGFS_ATTR_OPS(f_uvc_opts); | ||
2290 | |||
2291 | static void uvc_attr_release(struct config_item *item) | ||
2292 | { | ||
2293 | struct f_uvc_opts *opts = to_f_uvc_opts(item); | ||
2294 | |||
2295 | usb_put_function_instance(&opts->func_inst); | ||
2296 | } | ||
2297 | |||
2298 | static struct configfs_item_operations uvc_item_ops = { | ||
2299 | .release = uvc_attr_release, | ||
2300 | .show_attribute = f_uvc_opts_attr_show, | ||
2301 | .store_attribute = f_uvc_opts_attr_store, | ||
2302 | }; | ||
2303 | |||
2304 | #define UVCG_OPTS_ATTR(cname, conv, str2u, uxx, vnoc, limit) \ | ||
2305 | static ssize_t f_uvc_opts_##cname##_show( \ | ||
2306 | struct f_uvc_opts *opts, char *page) \ | ||
2307 | { \ | ||
2308 | int result; \ | ||
2309 | \ | ||
2310 | mutex_lock(&opts->lock); \ | ||
2311 | result = sprintf(page, "%d\n", conv(opts->cname)); \ | ||
2312 | mutex_unlock(&opts->lock); \ | ||
2313 | \ | ||
2314 | return result; \ | ||
2315 | } \ | ||
2316 | \ | ||
2317 | static ssize_t \ | ||
2318 | f_uvc_opts_##cname##_store(struct f_uvc_opts *opts, \ | ||
2319 | const char *page, size_t len) \ | ||
2320 | { \ | ||
2321 | int ret; \ | ||
2322 | uxx num; \ | ||
2323 | \ | ||
2324 | mutex_lock(&opts->lock); \ | ||
2325 | if (opts->refcnt) { \ | ||
2326 | ret = -EBUSY; \ | ||
2327 | goto end; \ | ||
2328 | } \ | ||
2329 | \ | ||
2330 | ret = str2u(page, 0, &num); \ | ||
2331 | if (ret) \ | ||
2332 | goto end; \ | ||
2333 | \ | ||
2334 | if (num > limit) { \ | ||
2335 | ret = -EINVAL; \ | ||
2336 | goto end; \ | ||
2337 | } \ | ||
2338 | opts->cname = vnoc(num); \ | ||
2339 | ret = len; \ | ||
2340 | end: \ | ||
2341 | mutex_unlock(&opts->lock); \ | ||
2342 | return ret; \ | ||
2343 | } \ | ||
2344 | \ | ||
2345 | static struct f_uvc_opts_attribute \ | ||
2346 | f_uvc_opts_attribute_##cname = \ | ||
2347 | __CONFIGFS_ATTR(cname, S_IRUGO | S_IWUSR, \ | ||
2348 | f_uvc_opts_##cname##_show, \ | ||
2349 | f_uvc_opts_##cname##_store) | ||
2350 | |||
2351 | #define identity_conv(x) (x) | ||
2352 | |||
2353 | UVCG_OPTS_ATTR(streaming_interval, identity_conv, kstrtou8, u8, identity_conv, | ||
2354 | 16); | ||
2355 | UVCG_OPTS_ATTR(streaming_maxpacket, le16_to_cpu, kstrtou16, u16, le16_to_cpu, | ||
2356 | 3072); | ||
2357 | UVCG_OPTS_ATTR(streaming_maxburst, identity_conv, kstrtou8, u8, identity_conv, | ||
2358 | 15); | ||
2359 | |||
2360 | #undef identity_conv | ||
2361 | |||
2362 | #undef UVCG_OPTS_ATTR | ||
2363 | |||
2364 | static struct configfs_attribute *uvc_attrs[] = { | ||
2365 | &f_uvc_opts_attribute_streaming_interval.attr, | ||
2366 | &f_uvc_opts_attribute_streaming_maxpacket.attr, | ||
2367 | &f_uvc_opts_attribute_streaming_maxburst.attr, | ||
2368 | NULL, | ||
2369 | }; | ||
2370 | |||
2371 | static struct config_item_type uvc_func_type = { | ||
2372 | .ct_item_ops = &uvc_item_ops, | ||
2373 | .ct_attrs = uvc_attrs, | ||
2374 | .ct_owner = THIS_MODULE, | ||
2375 | }; | ||
2376 | |||
2377 | static inline void uvcg_init_group(struct config_group *g, | ||
2378 | struct config_group **default_groups, | ||
2379 | const char *name, | ||
2380 | struct config_item_type *type) | ||
2381 | { | ||
2382 | g->default_groups = default_groups; | ||
2383 | config_group_init_type_name(g, name, type); | ||
2384 | } | ||
2385 | |||
2386 | int uvcg_attach_configfs(struct f_uvc_opts *opts) | ||
2387 | { | ||
2388 | config_group_init_type_name(&uvcg_control_header_grp.group, | ||
2389 | "header", | ||
2390 | &uvcg_control_header_grp_type); | ||
2391 | config_group_init_type_name(&uvcg_default_processing.group, | ||
2392 | "default", | ||
2393 | &uvcg_default_processing_type); | ||
2394 | uvcg_init_group(&uvcg_processing_grp.group, | ||
2395 | uvcg_processing_default_groups, | ||
2396 | "processing", | ||
2397 | &uvcg_processing_grp_type); | ||
2398 | config_group_init_type_name(&uvcg_default_camera.group, | ||
2399 | "default", | ||
2400 | &uvcg_default_camera_type); | ||
2401 | uvcg_init_group(&uvcg_camera_grp.group, | ||
2402 | uvcg_camera_default_groups, | ||
2403 | "camera", | ||
2404 | &uvcg_camera_grp_type); | ||
2405 | config_group_init_type_name(&uvcg_default_output.group, | ||
2406 | "default", | ||
2407 | &uvcg_default_output_type); | ||
2408 | uvcg_init_group(&uvcg_output_grp.group, | ||
2409 | uvcg_output_default_groups, | ||
2410 | "output", | ||
2411 | &uvcg_output_grp_type); | ||
2412 | uvcg_init_group(&uvcg_terminal_grp.group, | ||
2413 | uvcg_terminal_default_groups, | ||
2414 | "terminal", | ||
2415 | &uvcg_terminal_grp_type); | ||
2416 | config_group_init_type_name(&uvcg_control_class_fs.group, | ||
2417 | "fs", | ||
2418 | &uvcg_control_class_type); | ||
2419 | config_group_init_type_name(&uvcg_control_class_ss.group, | ||
2420 | "ss", | ||
2421 | &uvcg_control_class_type); | ||
2422 | uvcg_init_group(&uvcg_control_class_grp.group, | ||
2423 | uvcg_control_class_default_groups, | ||
2424 | "class", | ||
2425 | &uvcg_control_class_grp_type); | ||
2426 | uvcg_init_group(&uvcg_control_grp.group, | ||
2427 | uvcg_control_default_groups, | ||
2428 | "control", | ||
2429 | &uvcg_control_grp_type); | ||
2430 | config_group_init_type_name(&uvcg_streaming_header_grp.group, | ||
2431 | "header", | ||
2432 | &uvcg_streaming_header_grp_type); | ||
2433 | config_group_init_type_name(&uvcg_uncompressed_grp.group, | ||
2434 | "uncompressed", | ||
2435 | &uvcg_uncompressed_grp_type); | ||
2436 | config_group_init_type_name(&uvcg_mjpeg_grp.group, | ||
2437 | "mjpeg", | ||
2438 | &uvcg_mjpeg_grp_type); | ||
2439 | config_group_init_type_name(&uvcg_default_color_matching.group, | ||
2440 | "default", | ||
2441 | &uvcg_default_color_matching_type); | ||
2442 | uvcg_init_group(&uvcg_color_matching_grp.group, | ||
2443 | uvcg_color_matching_default_groups, | ||
2444 | "color_matching", | ||
2445 | &uvcg_color_matching_grp_type); | ||
2446 | config_group_init_type_name(&uvcg_streaming_class_fs.group, | ||
2447 | "fs", | ||
2448 | &uvcg_streaming_class_type); | ||
2449 | config_group_init_type_name(&uvcg_streaming_class_hs.group, | ||
2450 | "hs", | ||
2451 | &uvcg_streaming_class_type); | ||
2452 | config_group_init_type_name(&uvcg_streaming_class_ss.group, | ||
2453 | "ss", | ||
2454 | &uvcg_streaming_class_type); | ||
2455 | uvcg_init_group(&uvcg_streaming_class_grp.group, | ||
2456 | uvcg_streaming_class_default_groups, | ||
2457 | "class", | ||
2458 | &uvcg_streaming_class_grp_type); | ||
2459 | uvcg_init_group(&uvcg_streaming_grp.group, | ||
2460 | uvcg_streaming_default_groups, | ||
2461 | "streaming", | ||
2462 | &uvcg_streaming_grp_type); | ||
2463 | uvcg_init_group(&opts->func_inst.group, | ||
2464 | uvcg_default_groups, | ||
2465 | "", | ||
2466 | &uvc_func_type); | ||
2467 | return 0; | ||
2468 | } | ||
diff --git a/drivers/usb/gadget/function/uvc_configfs.h b/drivers/usb/gadget/function/uvc_configfs.h new file mode 100644 index 000000000000..085e67be7c71 --- /dev/null +++ b/drivers/usb/gadget/function/uvc_configfs.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * uvc_configfs.h | ||
3 | * | ||
4 | * Configfs support for the uvc function. | ||
5 | * | ||
6 | * Copyright (c) 2014 Samsung Electronics Co., Ltd. | ||
7 | * http://www.samsung.com | ||
8 | * | ||
9 | * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * published by the Free Software Foundation. | ||
14 | */ | ||
15 | #ifndef UVC_CONFIGFS_H | ||
16 | #define UVC_CONFIGFS_H | ||
17 | |||
18 | struct f_uvc_opts; | ||
19 | |||
20 | int uvcg_attach_configfs(struct f_uvc_opts *opts); | ||
21 | |||
22 | #endif /* UVC_CONFIGFS_H */ | ||
diff --git a/drivers/usb/gadget/udc/at91_udc.c b/drivers/usb/gadget/udc/at91_udc.c index c862656d18b8..c0ec5f71f16f 100644 --- a/drivers/usb/gadget/udc/at91_udc.c +++ b/drivers/usb/gadget/udc/at91_udc.c | |||
@@ -176,7 +176,7 @@ static int proc_udc_show(struct seq_file *s, void *unused) | |||
176 | udc->enabled | 176 | udc->enabled |
177 | ? (udc->vbus ? "active" : "enabled") | 177 | ? (udc->vbus ? "active" : "enabled") |
178 | : "disabled", | 178 | : "disabled", |
179 | udc->selfpowered ? "self" : "VBUS", | 179 | udc->gadget.is_selfpowered ? "self" : "VBUS", |
180 | udc->suspended ? ", suspended" : "", | 180 | udc->suspended ? ", suspended" : "", |
181 | udc->driver ? udc->driver->driver.name : "(none)"); | 181 | udc->driver ? udc->driver->driver.name : "(none)"); |
182 | 182 | ||
@@ -1000,7 +1000,7 @@ static int at91_set_selfpowered(struct usb_gadget *gadget, int is_on) | |||
1000 | unsigned long flags; | 1000 | unsigned long flags; |
1001 | 1001 | ||
1002 | spin_lock_irqsave(&udc->lock, flags); | 1002 | spin_lock_irqsave(&udc->lock, flags); |
1003 | udc->selfpowered = (is_on != 0); | 1003 | gadget->is_selfpowered = (is_on != 0); |
1004 | spin_unlock_irqrestore(&udc->lock, flags); | 1004 | spin_unlock_irqrestore(&udc->lock, flags); |
1005 | return 0; | 1005 | return 0; |
1006 | } | 1006 | } |
@@ -1149,7 +1149,7 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr) | |||
1149 | */ | 1149 | */ |
1150 | case ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8) | 1150 | case ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8) |
1151 | | USB_REQ_GET_STATUS: | 1151 | | USB_REQ_GET_STATUS: |
1152 | tmp = (udc->selfpowered << USB_DEVICE_SELF_POWERED); | 1152 | tmp = (udc->gadget.is_selfpowered << USB_DEVICE_SELF_POWERED); |
1153 | if (at91_udp_read(udc, AT91_UDP_GLB_STAT) & AT91_UDP_ESR) | 1153 | if (at91_udp_read(udc, AT91_UDP_GLB_STAT) & AT91_UDP_ESR) |
1154 | tmp |= (1 << USB_DEVICE_REMOTE_WAKEUP); | 1154 | tmp |= (1 << USB_DEVICE_REMOTE_WAKEUP); |
1155 | PACKET("get device status\n"); | 1155 | PACKET("get device status\n"); |
@@ -1653,7 +1653,7 @@ static int at91_start(struct usb_gadget *gadget, | |||
1653 | udc->driver = driver; | 1653 | udc->driver = driver; |
1654 | udc->gadget.dev.of_node = udc->pdev->dev.of_node; | 1654 | udc->gadget.dev.of_node = udc->pdev->dev.of_node; |
1655 | udc->enabled = 1; | 1655 | udc->enabled = 1; |
1656 | udc->selfpowered = 1; | 1656 | udc->gadget.is_selfpowered = 1; |
1657 | 1657 | ||
1658 | return 0; | 1658 | return 0; |
1659 | } | 1659 | } |
diff --git a/drivers/usb/gadget/udc/at91_udc.h b/drivers/usb/gadget/udc/at91_udc.h index 017524663381..467dcfb74a51 100644 --- a/drivers/usb/gadget/udc/at91_udc.h +++ b/drivers/usb/gadget/udc/at91_udc.h | |||
@@ -122,7 +122,6 @@ struct at91_udc { | |||
122 | unsigned req_pending:1; | 122 | unsigned req_pending:1; |
123 | unsigned wait_for_addr_ack:1; | 123 | unsigned wait_for_addr_ack:1; |
124 | unsigned wait_for_config_ack:1; | 124 | unsigned wait_for_config_ack:1; |
125 | unsigned selfpowered:1; | ||
126 | unsigned active_suspend:1; | 125 | unsigned active_suspend:1; |
127 | u8 addr; | 126 | u8 addr; |
128 | struct at91_udc_data board; | 127 | struct at91_udc_data board; |
diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index 9f93bed42052..c0410862c2a1 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c | |||
@@ -8,6 +8,7 @@ | |||
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | #include <linux/clk.h> | 10 | #include <linux/clk.h> |
11 | #include <linux/clk/at91_pmc.h> | ||
11 | #include <linux/module.h> | 12 | #include <linux/module.h> |
12 | #include <linux/init.h> | 13 | #include <linux/init.h> |
13 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
@@ -315,6 +316,17 @@ static inline void usba_cleanup_debugfs(struct usba_udc *udc) | |||
315 | } | 316 | } |
316 | #endif | 317 | #endif |
317 | 318 | ||
319 | static inline u32 usba_int_enb_get(struct usba_udc *udc) | ||
320 | { | ||
321 | return udc->int_enb_cache; | ||
322 | } | ||
323 | |||
324 | static inline void usba_int_enb_set(struct usba_udc *udc, u32 val) | ||
325 | { | ||
326 | usba_writel(udc, INT_ENB, val); | ||
327 | udc->int_enb_cache = val; | ||
328 | } | ||
329 | |||
318 | static int vbus_is_present(struct usba_udc *udc) | 330 | static int vbus_is_present(struct usba_udc *udc) |
319 | { | 331 | { |
320 | if (gpio_is_valid(udc->vbus_pin)) | 332 | if (gpio_is_valid(udc->vbus_pin)) |
@@ -324,27 +336,22 @@ static int vbus_is_present(struct usba_udc *udc) | |||
324 | return 1; | 336 | return 1; |
325 | } | 337 | } |
326 | 338 | ||
327 | #if defined(CONFIG_ARCH_AT91SAM9RL) | 339 | static void toggle_bias(struct usba_udc *udc, int is_on) |
328 | |||
329 | #include <linux/clk/at91_pmc.h> | ||
330 | |||
331 | static void toggle_bias(int is_on) | ||
332 | { | 340 | { |
333 | unsigned int uckr = at91_pmc_read(AT91_CKGR_UCKR); | 341 | if (udc->errata && udc->errata->toggle_bias) |
334 | 342 | udc->errata->toggle_bias(udc, is_on); | |
335 | if (is_on) | ||
336 | at91_pmc_write(AT91_CKGR_UCKR, uckr | AT91_PMC_BIASEN); | ||
337 | else | ||
338 | at91_pmc_write(AT91_CKGR_UCKR, uckr & ~(AT91_PMC_BIASEN)); | ||
339 | } | 343 | } |
340 | 344 | ||
341 | #else | 345 | static void generate_bias_pulse(struct usba_udc *udc) |
342 | |||
343 | static void toggle_bias(int is_on) | ||
344 | { | 346 | { |
345 | } | 347 | if (!udc->bias_pulse_needed) |
348 | return; | ||
349 | |||
350 | if (udc->errata && udc->errata->pulse_bias) | ||
351 | udc->errata->pulse_bias(udc); | ||
346 | 352 | ||
347 | #endif /* CONFIG_ARCH_AT91SAM9RL */ | 353 | udc->bias_pulse_needed = false; |
354 | } | ||
348 | 355 | ||
349 | static void next_fifo_transaction(struct usba_ep *ep, struct usba_request *req) | 356 | static void next_fifo_transaction(struct usba_ep *ep, struct usba_request *req) |
350 | { | 357 | { |
@@ -601,16 +608,14 @@ usba_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | |||
601 | if (ep->can_dma) { | 608 | if (ep->can_dma) { |
602 | u32 ctrl; | 609 | u32 ctrl; |
603 | 610 | ||
604 | usba_writel(udc, INT_ENB, | 611 | usba_int_enb_set(udc, usba_int_enb_get(udc) | |
605 | (usba_readl(udc, INT_ENB) | 612 | USBA_BF(EPT_INT, 1 << ep->index) | |
606 | | USBA_BF(EPT_INT, 1 << ep->index) | 613 | USBA_BF(DMA_INT, 1 << ep->index)); |
607 | | USBA_BF(DMA_INT, 1 << ep->index))); | ||
608 | ctrl = USBA_AUTO_VALID | USBA_INTDIS_DMA; | 614 | ctrl = USBA_AUTO_VALID | USBA_INTDIS_DMA; |
609 | usba_ep_writel(ep, CTL_ENB, ctrl); | 615 | usba_ep_writel(ep, CTL_ENB, ctrl); |
610 | } else { | 616 | } else { |
611 | usba_writel(udc, INT_ENB, | 617 | usba_int_enb_set(udc, usba_int_enb_get(udc) | |
612 | (usba_readl(udc, INT_ENB) | 618 | USBA_BF(EPT_INT, 1 << ep->index)); |
613 | | USBA_BF(EPT_INT, 1 << ep->index))); | ||
614 | } | 619 | } |
615 | 620 | ||
616 | spin_unlock_irqrestore(&udc->lock, flags); | 621 | spin_unlock_irqrestore(&udc->lock, flags); |
@@ -618,7 +623,7 @@ usba_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | |||
618 | DBG(DBG_HW, "EPT_CFG%d after init: %#08lx\n", ep->index, | 623 | DBG(DBG_HW, "EPT_CFG%d after init: %#08lx\n", ep->index, |
619 | (unsigned long)usba_ep_readl(ep, CFG)); | 624 | (unsigned long)usba_ep_readl(ep, CFG)); |
620 | DBG(DBG_HW, "INT_ENB after init: %#08lx\n", | 625 | DBG(DBG_HW, "INT_ENB after init: %#08lx\n", |
621 | (unsigned long)usba_readl(udc, INT_ENB)); | 626 | (unsigned long)usba_int_enb_get(udc)); |
622 | 627 | ||
623 | return 0; | 628 | return 0; |
624 | } | 629 | } |
@@ -654,9 +659,8 @@ static int usba_ep_disable(struct usb_ep *_ep) | |||
654 | usba_dma_readl(ep, STATUS); | 659 | usba_dma_readl(ep, STATUS); |
655 | } | 660 | } |
656 | usba_ep_writel(ep, CTL_DIS, USBA_EPT_ENABLE); | 661 | usba_ep_writel(ep, CTL_DIS, USBA_EPT_ENABLE); |
657 | usba_writel(udc, INT_ENB, | 662 | usba_int_enb_set(udc, usba_int_enb_get(udc) & |
658 | usba_readl(udc, INT_ENB) | 663 | ~USBA_BF(EPT_INT, 1 << ep->index)); |
659 | & ~USBA_BF(EPT_INT, 1 << ep->index)); | ||
660 | 664 | ||
661 | request_complete_list(ep, &req_list, -ESHUTDOWN); | 665 | request_complete_list(ep, &req_list, -ESHUTDOWN); |
662 | 666 | ||
@@ -985,6 +989,7 @@ usba_udc_set_selfpowered(struct usb_gadget *gadget, int is_selfpowered) | |||
985 | struct usba_udc *udc = to_usba_udc(gadget); | 989 | struct usba_udc *udc = to_usba_udc(gadget); |
986 | unsigned long flags; | 990 | unsigned long flags; |
987 | 991 | ||
992 | gadget->is_selfpowered = (is_selfpowered != 0); | ||
988 | spin_lock_irqsave(&udc->lock, flags); | 993 | spin_lock_irqsave(&udc->lock, flags); |
989 | if (is_selfpowered) | 994 | if (is_selfpowered) |
990 | udc->devstatus |= 1 << USB_DEVICE_SELF_POWERED; | 995 | udc->devstatus |= 1 << USB_DEVICE_SELF_POWERED; |
@@ -1619,18 +1624,21 @@ static void usba_dma_irq(struct usba_udc *udc, struct usba_ep *ep) | |||
1619 | static irqreturn_t usba_udc_irq(int irq, void *devid) | 1624 | static irqreturn_t usba_udc_irq(int irq, void *devid) |
1620 | { | 1625 | { |
1621 | struct usba_udc *udc = devid; | 1626 | struct usba_udc *udc = devid; |
1622 | u32 status; | 1627 | u32 status, int_enb; |
1623 | u32 dma_status; | 1628 | u32 dma_status; |
1624 | u32 ep_status; | 1629 | u32 ep_status; |
1625 | 1630 | ||
1626 | spin_lock(&udc->lock); | 1631 | spin_lock(&udc->lock); |
1627 | 1632 | ||
1628 | status = usba_readl(udc, INT_STA); | 1633 | int_enb = usba_int_enb_get(udc); |
1634 | status = usba_readl(udc, INT_STA) & int_enb; | ||
1629 | DBG(DBG_INT, "irq, status=%#08x\n", status); | 1635 | DBG(DBG_INT, "irq, status=%#08x\n", status); |
1630 | 1636 | ||
1631 | if (status & USBA_DET_SUSPEND) { | 1637 | if (status & USBA_DET_SUSPEND) { |
1632 | toggle_bias(0); | 1638 | toggle_bias(udc, 0); |
1633 | usba_writel(udc, INT_CLR, USBA_DET_SUSPEND); | 1639 | usba_writel(udc, INT_CLR, USBA_DET_SUSPEND); |
1640 | usba_int_enb_set(udc, int_enb | USBA_WAKE_UP); | ||
1641 | udc->bias_pulse_needed = true; | ||
1634 | DBG(DBG_BUS, "Suspend detected\n"); | 1642 | DBG(DBG_BUS, "Suspend detected\n"); |
1635 | if (udc->gadget.speed != USB_SPEED_UNKNOWN | 1643 | if (udc->gadget.speed != USB_SPEED_UNKNOWN |
1636 | && udc->driver && udc->driver->suspend) { | 1644 | && udc->driver && udc->driver->suspend) { |
@@ -1641,13 +1649,15 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) | |||
1641 | } | 1649 | } |
1642 | 1650 | ||
1643 | if (status & USBA_WAKE_UP) { | 1651 | if (status & USBA_WAKE_UP) { |
1644 | toggle_bias(1); | 1652 | toggle_bias(udc, 1); |
1645 | usba_writel(udc, INT_CLR, USBA_WAKE_UP); | 1653 | usba_writel(udc, INT_CLR, USBA_WAKE_UP); |
1654 | usba_int_enb_set(udc, int_enb & ~USBA_WAKE_UP); | ||
1646 | DBG(DBG_BUS, "Wake Up CPU detected\n"); | 1655 | DBG(DBG_BUS, "Wake Up CPU detected\n"); |
1647 | } | 1656 | } |
1648 | 1657 | ||
1649 | if (status & USBA_END_OF_RESUME) { | 1658 | if (status & USBA_END_OF_RESUME) { |
1650 | usba_writel(udc, INT_CLR, USBA_END_OF_RESUME); | 1659 | usba_writel(udc, INT_CLR, USBA_END_OF_RESUME); |
1660 | generate_bias_pulse(udc); | ||
1651 | DBG(DBG_BUS, "Resume detected\n"); | 1661 | DBG(DBG_BUS, "Resume detected\n"); |
1652 | if (udc->gadget.speed != USB_SPEED_UNKNOWN | 1662 | if (udc->gadget.speed != USB_SPEED_UNKNOWN |
1653 | && udc->driver && udc->driver->resume) { | 1663 | && udc->driver && udc->driver->resume) { |
@@ -1683,6 +1693,7 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) | |||
1683 | struct usba_ep *ep0; | 1693 | struct usba_ep *ep0; |
1684 | 1694 | ||
1685 | usba_writel(udc, INT_CLR, USBA_END_OF_RESET); | 1695 | usba_writel(udc, INT_CLR, USBA_END_OF_RESET); |
1696 | generate_bias_pulse(udc); | ||
1686 | reset_all_endpoints(udc); | 1697 | reset_all_endpoints(udc); |
1687 | 1698 | ||
1688 | if (udc->gadget.speed != USB_SPEED_UNKNOWN && udc->driver) { | 1699 | if (udc->gadget.speed != USB_SPEED_UNKNOWN && udc->driver) { |
@@ -1708,11 +1719,8 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) | |||
1708 | | USBA_BF(BK_NUMBER, USBA_BK_NUMBER_ONE))); | 1719 | | USBA_BF(BK_NUMBER, USBA_BK_NUMBER_ONE))); |
1709 | usba_ep_writel(ep0, CTL_ENB, | 1720 | usba_ep_writel(ep0, CTL_ENB, |
1710 | USBA_EPT_ENABLE | USBA_RX_SETUP); | 1721 | USBA_EPT_ENABLE | USBA_RX_SETUP); |
1711 | usba_writel(udc, INT_ENB, | 1722 | usba_int_enb_set(udc, int_enb | USBA_BF(EPT_INT, 1) | |
1712 | (usba_readl(udc, INT_ENB) | 1723 | USBA_DET_SUSPEND | USBA_END_OF_RESUME); |
1713 | | USBA_BF(EPT_INT, 1) | ||
1714 | | USBA_DET_SUSPEND | ||
1715 | | USBA_END_OF_RESUME)); | ||
1716 | 1724 | ||
1717 | /* | 1725 | /* |
1718 | * Unclear why we hit this irregularly, e.g. in usbtest, | 1726 | * Unclear why we hit this irregularly, e.g. in usbtest, |
@@ -1745,13 +1753,13 @@ static irqreturn_t usba_vbus_irq(int irq, void *devid) | |||
1745 | vbus = vbus_is_present(udc); | 1753 | vbus = vbus_is_present(udc); |
1746 | if (vbus != udc->vbus_prev) { | 1754 | if (vbus != udc->vbus_prev) { |
1747 | if (vbus) { | 1755 | if (vbus) { |
1748 | toggle_bias(1); | 1756 | toggle_bias(udc, 1); |
1749 | usba_writel(udc, CTRL, USBA_ENABLE_MASK); | 1757 | usba_writel(udc, CTRL, USBA_ENABLE_MASK); |
1750 | usba_writel(udc, INT_ENB, USBA_END_OF_RESET); | 1758 | usba_int_enb_set(udc, USBA_END_OF_RESET); |
1751 | } else { | 1759 | } else { |
1752 | udc->gadget.speed = USB_SPEED_UNKNOWN; | 1760 | udc->gadget.speed = USB_SPEED_UNKNOWN; |
1753 | reset_all_endpoints(udc); | 1761 | reset_all_endpoints(udc); |
1754 | toggle_bias(0); | 1762 | toggle_bias(udc, 0); |
1755 | usba_writel(udc, CTRL, USBA_DISABLE_MASK); | 1763 | usba_writel(udc, CTRL, USBA_DISABLE_MASK); |
1756 | if (udc->driver->disconnect) { | 1764 | if (udc->driver->disconnect) { |
1757 | spin_unlock(&udc->lock); | 1765 | spin_unlock(&udc->lock); |
@@ -1797,9 +1805,9 @@ static int atmel_usba_start(struct usb_gadget *gadget, | |||
1797 | /* If Vbus is present, enable the controller and wait for reset */ | 1805 | /* If Vbus is present, enable the controller and wait for reset */ |
1798 | spin_lock_irqsave(&udc->lock, flags); | 1806 | spin_lock_irqsave(&udc->lock, flags); |
1799 | if (vbus_is_present(udc) && udc->vbus_prev == 0) { | 1807 | if (vbus_is_present(udc) && udc->vbus_prev == 0) { |
1800 | toggle_bias(1); | 1808 | toggle_bias(udc, 1); |
1801 | usba_writel(udc, CTRL, USBA_ENABLE_MASK); | 1809 | usba_writel(udc, CTRL, USBA_ENABLE_MASK); |
1802 | usba_writel(udc, INT_ENB, USBA_END_OF_RESET); | 1810 | usba_int_enb_set(udc, USBA_END_OF_RESET); |
1803 | } | 1811 | } |
1804 | spin_unlock_irqrestore(&udc->lock, flags); | 1812 | spin_unlock_irqrestore(&udc->lock, flags); |
1805 | 1813 | ||
@@ -1820,7 +1828,7 @@ static int atmel_usba_stop(struct usb_gadget *gadget) | |||
1820 | spin_unlock_irqrestore(&udc->lock, flags); | 1828 | spin_unlock_irqrestore(&udc->lock, flags); |
1821 | 1829 | ||
1822 | /* This will also disable the DP pullup */ | 1830 | /* This will also disable the DP pullup */ |
1823 | toggle_bias(0); | 1831 | toggle_bias(udc, 0); |
1824 | usba_writel(udc, CTRL, USBA_DISABLE_MASK); | 1832 | usba_writel(udc, CTRL, USBA_DISABLE_MASK); |
1825 | 1833 | ||
1826 | clk_disable_unprepare(udc->hclk); | 1834 | clk_disable_unprepare(udc->hclk); |
@@ -1832,6 +1840,41 @@ static int atmel_usba_stop(struct usb_gadget *gadget) | |||
1832 | } | 1840 | } |
1833 | 1841 | ||
1834 | #ifdef CONFIG_OF | 1842 | #ifdef CONFIG_OF |
1843 | static void at91sam9rl_toggle_bias(struct usba_udc *udc, int is_on) | ||
1844 | { | ||
1845 | unsigned int uckr = at91_pmc_read(AT91_CKGR_UCKR); | ||
1846 | |||
1847 | if (is_on) | ||
1848 | at91_pmc_write(AT91_CKGR_UCKR, uckr | AT91_PMC_BIASEN); | ||
1849 | else | ||
1850 | at91_pmc_write(AT91_CKGR_UCKR, uckr & ~(AT91_PMC_BIASEN)); | ||
1851 | } | ||
1852 | |||
1853 | static void at91sam9g45_pulse_bias(struct usba_udc *udc) | ||
1854 | { | ||
1855 | unsigned int uckr = at91_pmc_read(AT91_CKGR_UCKR); | ||
1856 | |||
1857 | at91_pmc_write(AT91_CKGR_UCKR, uckr & ~(AT91_PMC_BIASEN)); | ||
1858 | at91_pmc_write(AT91_CKGR_UCKR, uckr | AT91_PMC_BIASEN); | ||
1859 | } | ||
1860 | |||
1861 | static const struct usba_udc_errata at91sam9rl_errata = { | ||
1862 | .toggle_bias = at91sam9rl_toggle_bias, | ||
1863 | }; | ||
1864 | |||
1865 | static const struct usba_udc_errata at91sam9g45_errata = { | ||
1866 | .pulse_bias = at91sam9g45_pulse_bias, | ||
1867 | }; | ||
1868 | |||
1869 | static const struct of_device_id atmel_udc_dt_ids[] = { | ||
1870 | { .compatible = "atmel,at91sam9rl-udc", .data = &at91sam9rl_errata }, | ||
1871 | { .compatible = "atmel,at91sam9g45-udc", .data = &at91sam9g45_errata }, | ||
1872 | { .compatible = "atmel,sama5d3-udc" }, | ||
1873 | { /* sentinel */ } | ||
1874 | }; | ||
1875 | |||
1876 | MODULE_DEVICE_TABLE(of, atmel_udc_dt_ids); | ||
1877 | |||
1835 | static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev, | 1878 | static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev, |
1836 | struct usba_udc *udc) | 1879 | struct usba_udc *udc) |
1837 | { | 1880 | { |
@@ -1839,10 +1882,17 @@ static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev, | |||
1839 | const char *name; | 1882 | const char *name; |
1840 | enum of_gpio_flags flags; | 1883 | enum of_gpio_flags flags; |
1841 | struct device_node *np = pdev->dev.of_node; | 1884 | struct device_node *np = pdev->dev.of_node; |
1885 | const struct of_device_id *match; | ||
1842 | struct device_node *pp; | 1886 | struct device_node *pp; |
1843 | int i, ret; | 1887 | int i, ret; |
1844 | struct usba_ep *eps, *ep; | 1888 | struct usba_ep *eps, *ep; |
1845 | 1889 | ||
1890 | match = of_match_node(atmel_udc_dt_ids, np); | ||
1891 | if (!match) | ||
1892 | return ERR_PTR(-EINVAL); | ||
1893 | |||
1894 | udc->errata = match->data; | ||
1895 | |||
1846 | udc->num_ep = 0; | 1896 | udc->num_ep = 0; |
1847 | 1897 | ||
1848 | udc->vbus_pin = of_get_named_gpio_flags(np, "atmel,vbus-gpio", 0, | 1898 | udc->vbus_pin = of_get_named_gpio_flags(np, "atmel,vbus-gpio", 0, |
@@ -2033,7 +2083,7 @@ static int usba_udc_probe(struct platform_device *pdev) | |||
2033 | dev_err(&pdev->dev, "Unable to enable pclk, aborting.\n"); | 2083 | dev_err(&pdev->dev, "Unable to enable pclk, aborting.\n"); |
2034 | return ret; | 2084 | return ret; |
2035 | } | 2085 | } |
2036 | toggle_bias(0); | 2086 | |
2037 | usba_writel(udc, CTRL, USBA_DISABLE_MASK); | 2087 | usba_writel(udc, CTRL, USBA_DISABLE_MASK); |
2038 | clk_disable_unprepare(pclk); | 2088 | clk_disable_unprepare(pclk); |
2039 | 2089 | ||
@@ -2042,6 +2092,8 @@ static int usba_udc_probe(struct platform_device *pdev) | |||
2042 | else | 2092 | else |
2043 | udc->usba_ep = usba_udc_pdata(pdev, udc); | 2093 | udc->usba_ep = usba_udc_pdata(pdev, udc); |
2044 | 2094 | ||
2095 | toggle_bias(udc, 0); | ||
2096 | |||
2045 | if (IS_ERR(udc->usba_ep)) | 2097 | if (IS_ERR(udc->usba_ep)) |
2046 | return PTR_ERR(udc->usba_ep); | 2098 | return PTR_ERR(udc->usba_ep); |
2047 | 2099 | ||
@@ -2101,15 +2153,6 @@ static int __exit usba_udc_remove(struct platform_device *pdev) | |||
2101 | return 0; | 2153 | return 0; |
2102 | } | 2154 | } |
2103 | 2155 | ||
2104 | #if defined(CONFIG_OF) | ||
2105 | static const struct of_device_id atmel_udc_dt_ids[] = { | ||
2106 | { .compatible = "atmel,at91sam9rl-udc" }, | ||
2107 | { /* sentinel */ } | ||
2108 | }; | ||
2109 | |||
2110 | MODULE_DEVICE_TABLE(of, atmel_udc_dt_ids); | ||
2111 | #endif | ||
2112 | |||
2113 | static struct platform_driver udc_driver = { | 2156 | static struct platform_driver udc_driver = { |
2114 | .remove = __exit_p(usba_udc_remove), | 2157 | .remove = __exit_p(usba_udc_remove), |
2115 | .driver = { | 2158 | .driver = { |
diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.h b/drivers/usb/gadget/udc/atmel_usba_udc.h index a70706e8cb02..497cd18836f3 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.h +++ b/drivers/usb/gadget/udc/atmel_usba_udc.h | |||
@@ -304,6 +304,11 @@ struct usba_request { | |||
304 | unsigned int mapped:1; | 304 | unsigned int mapped:1; |
305 | }; | 305 | }; |
306 | 306 | ||
307 | struct usba_udc_errata { | ||
308 | void (*toggle_bias)(struct usba_udc *udc, int is_on); | ||
309 | void (*pulse_bias)(struct usba_udc *udc); | ||
310 | }; | ||
311 | |||
307 | struct usba_udc { | 312 | struct usba_udc { |
308 | /* Protect hw registers from concurrent modifications */ | 313 | /* Protect hw registers from concurrent modifications */ |
309 | spinlock_t lock; | 314 | spinlock_t lock; |
@@ -314,6 +319,7 @@ struct usba_udc { | |||
314 | struct usb_gadget gadget; | 319 | struct usb_gadget gadget; |
315 | struct usb_gadget_driver *driver; | 320 | struct usb_gadget_driver *driver; |
316 | struct platform_device *pdev; | 321 | struct platform_device *pdev; |
322 | const struct usba_udc_errata *errata; | ||
317 | int irq; | 323 | int irq; |
318 | int vbus_pin; | 324 | int vbus_pin; |
319 | int vbus_pin_inverted; | 325 | int vbus_pin_inverted; |
@@ -321,12 +327,15 @@ struct usba_udc { | |||
321 | struct clk *pclk; | 327 | struct clk *pclk; |
322 | struct clk *hclk; | 328 | struct clk *hclk; |
323 | struct usba_ep *usba_ep; | 329 | struct usba_ep *usba_ep; |
330 | bool bias_pulse_needed; | ||
324 | 331 | ||
325 | u16 devstatus; | 332 | u16 devstatus; |
326 | 333 | ||
327 | u16 test_mode; | 334 | u16 test_mode; |
328 | int vbus_prev; | 335 | int vbus_prev; |
329 | 336 | ||
337 | u32 int_enb_cache; | ||
338 | |||
330 | #ifdef CONFIG_USB_GADGET_DEBUG_FS | 339 | #ifdef CONFIG_USB_GADGET_DEBUG_FS |
331 | struct dentry *debugfs_root; | 340 | struct dentry *debugfs_root; |
332 | struct dentry *debugfs_regs; | 341 | struct dentry *debugfs_regs; |
diff --git a/drivers/usb/gadget/udc/bdc/bdc_core.c b/drivers/usb/gadget/udc/bdc/bdc_core.c index c6dfef8c7bbc..5c8f4effb62a 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_core.c +++ b/drivers/usb/gadget/udc/bdc/bdc_core.c | |||
@@ -521,7 +521,6 @@ static int bdc_remove(struct platform_device *pdev) | |||
521 | static struct platform_driver bdc_driver = { | 521 | static struct platform_driver bdc_driver = { |
522 | .driver = { | 522 | .driver = { |
523 | .name = BRCM_BDC_NAME, | 523 | .name = BRCM_BDC_NAME, |
524 | .owner = THIS_MODULE | ||
525 | }, | 524 | }, |
526 | .probe = bdc_probe, | 525 | .probe = bdc_probe, |
527 | .remove = bdc_remove, | 526 | .remove = bdc_remove, |
diff --git a/drivers/usb/gadget/udc/bdc/bdc_ep.c b/drivers/usb/gadget/udc/bdc/bdc_ep.c index d4fe8d769bd6..b04980cf6dc4 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_ep.c +++ b/drivers/usb/gadget/udc/bdc/bdc_ep.c | |||
@@ -718,7 +718,7 @@ static int ep_queue(struct bdc_ep *ep, struct bdc_req *req) | |||
718 | struct bdc *bdc; | 718 | struct bdc *bdc; |
719 | int ret = 0; | 719 | int ret = 0; |
720 | 720 | ||
721 | if (!req || !ep || !ep->usb_ep.desc) | 721 | if (!req || !ep->usb_ep.desc) |
722 | return -EINVAL; | 722 | return -EINVAL; |
723 | 723 | ||
724 | bdc = ep->bdc; | 724 | bdc = ep->bdc; |
@@ -882,8 +882,8 @@ static int ep_set_halt(struct bdc_ep *ep, u32 value) | |||
882 | 882 | ||
883 | ret = bdc_ep_set_stall(bdc, ep->ep_num); | 883 | ret = bdc_ep_set_stall(bdc, ep->ep_num); |
884 | if (ret) | 884 | if (ret) |
885 | dev_err(bdc->dev, "failed to %s STALL on %s\n", | 885 | dev_err(bdc->dev, "failed to set STALL on %s\n", |
886 | value ? "set" : "clear", ep->name); | 886 | ep->name); |
887 | else | 887 | else |
888 | ep->flags |= BDC_EP_STALL; | 888 | ep->flags |= BDC_EP_STALL; |
889 | } else { | 889 | } else { |
@@ -891,8 +891,8 @@ static int ep_set_halt(struct bdc_ep *ep, u32 value) | |||
891 | dev_dbg(bdc->dev, "Before Clear\n"); | 891 | dev_dbg(bdc->dev, "Before Clear\n"); |
892 | ret = bdc_ep_clear_stall(bdc, ep->ep_num); | 892 | ret = bdc_ep_clear_stall(bdc, ep->ep_num); |
893 | if (ret) | 893 | if (ret) |
894 | dev_err(bdc->dev, "failed to %s STALL on %s\n", | 894 | dev_err(bdc->dev, "failed to clear STALL on %s\n", |
895 | value ? "set" : "clear", ep->name); | 895 | ep->name); |
896 | else | 896 | else |
897 | ep->flags &= ~BDC_EP_STALL; | 897 | ep->flags &= ~BDC_EP_STALL; |
898 | dev_dbg(bdc->dev, "After Clear\n"); | 898 | dev_dbg(bdc->dev, "After Clear\n"); |
diff --git a/drivers/usb/gadget/udc/bdc/bdc_udc.c b/drivers/usb/gadget/udc/bdc/bdc_udc.c index 3700ce70b0be..7f77db5d1278 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_udc.c +++ b/drivers/usb/gadget/udc/bdc/bdc_udc.c | |||
@@ -454,6 +454,7 @@ static int bdc_udc_set_selfpowered(struct usb_gadget *gadget, | |||
454 | unsigned long flags; | 454 | unsigned long flags; |
455 | 455 | ||
456 | dev_dbg(bdc->dev, "%s()\n", __func__); | 456 | dev_dbg(bdc->dev, "%s()\n", __func__); |
457 | gadget->is_selfpowered = (is_self != 0); | ||
457 | spin_lock_irqsave(&bdc->lock, flags); | 458 | spin_lock_irqsave(&bdc->lock, flags); |
458 | if (!is_self) | 459 | if (!is_self) |
459 | bdc->devstatus |= 1 << USB_DEVICE_SELF_POWERED; | 460 | bdc->devstatus |= 1 << USB_DEVICE_SELF_POWERED; |
diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index 9c598801404c..8dda48445f6f 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c | |||
@@ -802,6 +802,7 @@ static int dummy_set_selfpowered(struct usb_gadget *_gadget, int value) | |||
802 | { | 802 | { |
803 | struct dummy *dum; | 803 | struct dummy *dum; |
804 | 804 | ||
805 | _gadget->is_selfpowered = (value != 0); | ||
805 | dum = gadget_to_dummy_hcd(_gadget)->dum; | 806 | dum = gadget_to_dummy_hcd(_gadget)->dum; |
806 | if (value) | 807 | if (value) |
807 | dum->devstatus |= (1 << USB_DEVICE_SELF_POWERED); | 808 | dum->devstatus |= (1 << USB_DEVICE_SELF_POWERED); |
@@ -1924,7 +1925,9 @@ ss_hub_descriptor(struct usb_hub_descriptor *desc) | |||
1924 | memset(desc, 0, sizeof *desc); | 1925 | memset(desc, 0, sizeof *desc); |
1925 | desc->bDescriptorType = 0x2a; | 1926 | desc->bDescriptorType = 0x2a; |
1926 | desc->bDescLength = 12; | 1927 | desc->bDescLength = 12; |
1927 | desc->wHubCharacteristics = cpu_to_le16(0x0001); | 1928 | desc->wHubCharacteristics = cpu_to_le16( |
1929 | HUB_CHAR_INDV_PORT_LPSM | | ||
1930 | HUB_CHAR_COMMON_OCPM); | ||
1928 | desc->bNbrPorts = 1; | 1931 | desc->bNbrPorts = 1; |
1929 | desc->u.ss.bHubHdrDecLat = 0x04; /* Worst case: 0.4 micro sec*/ | 1932 | desc->u.ss.bHubHdrDecLat = 0x04; /* Worst case: 0.4 micro sec*/ |
1930 | desc->u.ss.DeviceRemovable = 0xffff; | 1933 | desc->u.ss.DeviceRemovable = 0xffff; |
@@ -1935,7 +1938,9 @@ static inline void hub_descriptor(struct usb_hub_descriptor *desc) | |||
1935 | memset(desc, 0, sizeof *desc); | 1938 | memset(desc, 0, sizeof *desc); |
1936 | desc->bDescriptorType = 0x29; | 1939 | desc->bDescriptorType = 0x29; |
1937 | desc->bDescLength = 9; | 1940 | desc->bDescLength = 9; |
1938 | desc->wHubCharacteristics = cpu_to_le16(0x0001); | 1941 | desc->wHubCharacteristics = cpu_to_le16( |
1942 | HUB_CHAR_INDV_PORT_LPSM | | ||
1943 | HUB_CHAR_COMMON_OCPM); | ||
1939 | desc->bNbrPorts = 1; | 1944 | desc->bNbrPorts = 1; |
1940 | desc->u.hs.DeviceRemovable[0] = 0xff; | 1945 | desc->u.hs.DeviceRemovable[0] = 0xff; |
1941 | desc->u.hs.DeviceRemovable[1] = 0xff; | 1946 | desc->u.hs.DeviceRemovable[1] = 0xff; |
diff --git a/drivers/usb/gadget/udc/fsl_qe_udc.c b/drivers/usb/gadget/udc/fsl_qe_udc.c index 795c99c77697..e0822f1b6639 100644 --- a/drivers/usb/gadget/udc/fsl_qe_udc.c +++ b/drivers/usb/gadget/udc/fsl_qe_udc.c | |||
@@ -2630,7 +2630,7 @@ static int qe_udc_remove(struct platform_device *ofdev) | |||
2630 | struct qe_udc *udc = platform_get_drvdata(ofdev); | 2630 | struct qe_udc *udc = platform_get_drvdata(ofdev); |
2631 | struct qe_ep *ep; | 2631 | struct qe_ep *ep; |
2632 | unsigned int size; | 2632 | unsigned int size; |
2633 | DECLARE_COMPLETION(done); | 2633 | DECLARE_COMPLETION_ONSTACK(done); |
2634 | 2634 | ||
2635 | usb_del_gadget_udc(&udc->gadget); | 2635 | usb_del_gadget_udc(&udc->gadget); |
2636 | 2636 | ||
diff --git a/drivers/usb/gadget/udc/fsl_udc_core.c b/drivers/usb/gadget/udc/fsl_udc_core.c index 2df807403f22..55fcb930f92e 100644 --- a/drivers/usb/gadget/udc/fsl_udc_core.c +++ b/drivers/usb/gadget/udc/fsl_udc_core.c | |||
@@ -1337,7 +1337,7 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value, | |||
1337 | 1337 | ||
1338 | if ((request_type & USB_RECIP_MASK) == USB_RECIP_DEVICE) { | 1338 | if ((request_type & USB_RECIP_MASK) == USB_RECIP_DEVICE) { |
1339 | /* Get device status */ | 1339 | /* Get device status */ |
1340 | tmp = 1 << USB_DEVICE_SELF_POWERED; | 1340 | tmp = udc->gadget.is_selfpowered; |
1341 | tmp |= udc->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP; | 1341 | tmp |= udc->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP; |
1342 | } else if ((request_type & USB_RECIP_MASK) == USB_RECIP_INTERFACE) { | 1342 | } else if ((request_type & USB_RECIP_MASK) == USB_RECIP_INTERFACE) { |
1343 | /* Get interface status */ | 1343 | /* Get interface status */ |
@@ -1948,6 +1948,7 @@ static int fsl_udc_start(struct usb_gadget *g, | |||
1948 | /* hook up the driver */ | 1948 | /* hook up the driver */ |
1949 | udc_controller->driver = driver; | 1949 | udc_controller->driver = driver; |
1950 | spin_unlock_irqrestore(&udc_controller->lock, flags); | 1950 | spin_unlock_irqrestore(&udc_controller->lock, flags); |
1951 | g->is_selfpowered = 1; | ||
1951 | 1952 | ||
1952 | if (!IS_ERR_OR_NULL(udc_controller->transceiver)) { | 1953 | if (!IS_ERR_OR_NULL(udc_controller->transceiver)) { |
1953 | /* Suspend the controller until OTG enable it */ | 1954 | /* Suspend the controller until OTG enable it */ |
@@ -2529,7 +2530,7 @@ static int __exit fsl_udc_remove(struct platform_device *pdev) | |||
2529 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2530 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
2530 | struct fsl_usb2_platform_data *pdata = dev_get_platdata(&pdev->dev); | 2531 | struct fsl_usb2_platform_data *pdata = dev_get_platdata(&pdev->dev); |
2531 | 2532 | ||
2532 | DECLARE_COMPLETION(done); | 2533 | DECLARE_COMPLETION_ONSTACK(done); |
2533 | 2534 | ||
2534 | if (!udc_controller) | 2535 | if (!udc_controller) |
2535 | return -ENODEV; | 2536 | return -ENODEV; |
diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c index 34d9b7b831b3..27fd41333f71 100644 --- a/drivers/usb/gadget/udc/lpc32xx_udc.c +++ b/drivers/usb/gadget/udc/lpc32xx_udc.c | |||
@@ -191,7 +191,6 @@ struct lpc32xx_udc { | |||
191 | bool enabled; | 191 | bool enabled; |
192 | bool clocked; | 192 | bool clocked; |
193 | bool suspended; | 193 | bool suspended; |
194 | bool selfpowered; | ||
195 | int ep0state; | 194 | int ep0state; |
196 | atomic_t enabled_ep_cnt; | 195 | atomic_t enabled_ep_cnt; |
197 | wait_queue_head_t ep_disable_wait_queue; | 196 | wait_queue_head_t ep_disable_wait_queue; |
@@ -547,7 +546,7 @@ static int proc_udc_show(struct seq_file *s, void *unused) | |||
547 | udc->vbus ? "present" : "off", | 546 | udc->vbus ? "present" : "off", |
548 | udc->enabled ? (udc->vbus ? "active" : "enabled") : | 547 | udc->enabled ? (udc->vbus ? "active" : "enabled") : |
549 | "disabled", | 548 | "disabled", |
550 | udc->selfpowered ? "self" : "VBUS", | 549 | udc->gadget.is_selfpowered ? "self" : "VBUS", |
551 | udc->suspended ? ", suspended" : "", | 550 | udc->suspended ? ", suspended" : "", |
552 | udc->driver ? udc->driver->driver.name : "(none)"); | 551 | udc->driver ? udc->driver->driver.name : "(none)"); |
553 | 552 | ||
@@ -2212,7 +2211,7 @@ static int udc_get_status(struct lpc32xx_udc *udc, u16 reqtype, u16 wIndex) | |||
2212 | break; /* Not supported */ | 2211 | break; /* Not supported */ |
2213 | 2212 | ||
2214 | case USB_RECIP_DEVICE: | 2213 | case USB_RECIP_DEVICE: |
2215 | ep0buff = (udc->selfpowered << USB_DEVICE_SELF_POWERED); | 2214 | ep0buff = udc->gadget.is_selfpowered; |
2216 | if (udc->dev_status & (1 << USB_DEVICE_REMOTE_WAKEUP)) | 2215 | if (udc->dev_status & (1 << USB_DEVICE_REMOTE_WAKEUP)) |
2217 | ep0buff |= (1 << USB_DEVICE_REMOTE_WAKEUP); | 2216 | ep0buff |= (1 << USB_DEVICE_REMOTE_WAKEUP); |
2218 | break; | 2217 | break; |
@@ -2498,10 +2497,7 @@ static int lpc32xx_wakeup(struct usb_gadget *gadget) | |||
2498 | 2497 | ||
2499 | static int lpc32xx_set_selfpowered(struct usb_gadget *gadget, int is_on) | 2498 | static int lpc32xx_set_selfpowered(struct usb_gadget *gadget, int is_on) |
2500 | { | 2499 | { |
2501 | struct lpc32xx_udc *udc = to_udc(gadget); | 2500 | gadget->is_selfpowered = (is_on != 0); |
2502 | |||
2503 | /* Always self-powered */ | ||
2504 | udc->selfpowered = (is_on != 0); | ||
2505 | 2501 | ||
2506 | return 0; | 2502 | return 0; |
2507 | } | 2503 | } |
@@ -2946,7 +2942,7 @@ static int lpc32xx_start(struct usb_gadget *gadget, | |||
2946 | udc->driver = driver; | 2942 | udc->driver = driver; |
2947 | udc->gadget.dev.of_node = udc->dev->of_node; | 2943 | udc->gadget.dev.of_node = udc->dev->of_node; |
2948 | udc->enabled = 1; | 2944 | udc->enabled = 1; |
2949 | udc->selfpowered = 1; | 2945 | udc->gadget.is_selfpowered = 1; |
2950 | udc->vbus = 0; | 2946 | udc->vbus = 0; |
2951 | 2947 | ||
2952 | /* Force VBUS process once to check for cable insertion */ | 2948 | /* Force VBUS process once to check for cable insertion */ |
diff --git a/drivers/usb/gadget/udc/mv_udc_core.c b/drivers/usb/gadget/udc/mv_udc_core.c index 253f3df8326a..d32160d6463f 100644 --- a/drivers/usb/gadget/udc/mv_udc_core.c +++ b/drivers/usb/gadget/udc/mv_udc_core.c | |||
@@ -1378,9 +1378,6 @@ static int mv_udc_start(struct usb_gadget *gadget, | |||
1378 | } | 1378 | } |
1379 | } | 1379 | } |
1380 | 1380 | ||
1381 | /* pullup is always on */ | ||
1382 | mv_udc_pullup(&udc->gadget, 1); | ||
1383 | |||
1384 | /* When boot with cable attached, there will be no vbus irq occurred */ | 1381 | /* When boot with cable attached, there will be no vbus irq occurred */ |
1385 | if (udc->qwork) | 1382 | if (udc->qwork) |
1386 | queue_work(udc->qwork, &udc->vbus_work); | 1383 | queue_work(udc->qwork, &udc->vbus_work); |
diff --git a/drivers/usb/gadget/udc/net2272.c b/drivers/usb/gadget/udc/net2272.c index d20de1fab08e..195baf3e1fcd 100644 --- a/drivers/usb/gadget/udc/net2272.c +++ b/drivers/usb/gadget/udc/net2272.c | |||
@@ -1132,13 +1132,10 @@ net2272_wakeup(struct usb_gadget *_gadget) | |||
1132 | static int | 1132 | static int |
1133 | net2272_set_selfpowered(struct usb_gadget *_gadget, int value) | 1133 | net2272_set_selfpowered(struct usb_gadget *_gadget, int value) |
1134 | { | 1134 | { |
1135 | struct net2272 *dev; | ||
1136 | |||
1137 | if (!_gadget) | 1135 | if (!_gadget) |
1138 | return -ENODEV; | 1136 | return -ENODEV; |
1139 | dev = container_of(_gadget, struct net2272, gadget); | ||
1140 | 1137 | ||
1141 | dev->is_selfpowered = value; | 1138 | _gadget->is_selfpowered = (value != 0); |
1142 | 1139 | ||
1143 | return 0; | 1140 | return 0; |
1144 | } | 1141 | } |
@@ -1844,7 +1841,7 @@ net2272_handle_stat0_irqs(struct net2272 *dev, u8 stat) | |||
1844 | case USB_RECIP_DEVICE: | 1841 | case USB_RECIP_DEVICE: |
1845 | if (u.r.wLength > 2) | 1842 | if (u.r.wLength > 2) |
1846 | goto do_stall; | 1843 | goto do_stall; |
1847 | if (dev->is_selfpowered) | 1844 | if (dev->gadget.is_selfpowered) |
1848 | status = (1 << USB_DEVICE_SELF_POWERED); | 1845 | status = (1 << USB_DEVICE_SELF_POWERED); |
1849 | 1846 | ||
1850 | /* don't bother with a request object! */ | 1847 | /* don't bother with a request object! */ |
diff --git a/drivers/usb/gadget/udc/net2272.h b/drivers/usb/gadget/udc/net2272.h index e59505789359..127ab03fcde3 100644 --- a/drivers/usb/gadget/udc/net2272.h +++ b/drivers/usb/gadget/udc/net2272.h | |||
@@ -458,7 +458,6 @@ struct net2272 { | |||
458 | struct usb_gadget_driver *driver; | 458 | struct usb_gadget_driver *driver; |
459 | unsigned protocol_stall:1, | 459 | unsigned protocol_stall:1, |
460 | softconnect:1, | 460 | softconnect:1, |
461 | is_selfpowered:1, | ||
462 | wakeup:1, | 461 | wakeup:1, |
463 | dma_eot_polarity:1, | 462 | dma_eot_polarity:1, |
464 | dma_dack_polarity:1, | 463 | dma_dack_polarity:1, |
diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c index d6411e0a8e03..d2c0bf65e345 100644 --- a/drivers/usb/gadget/udc/net2280.c +++ b/drivers/usb/gadget/udc/net2280.c | |||
@@ -12,11 +12,7 @@ | |||
12 | * the Mass Storage, Serial, and Ethernet/RNDIS gadget drivers | 12 | * the Mass Storage, Serial, and Ethernet/RNDIS gadget drivers |
13 | * as well as Gadget Zero and Gadgetfs. | 13 | * as well as Gadget Zero and Gadgetfs. |
14 | * | 14 | * |
15 | * DMA is enabled by default. Drivers using transfer queues might use | 15 | * DMA is enabled by default. |
16 | * DMA chaining to remove IRQ latencies between transfers. (Except when | ||
17 | * short OUT transfers happen.) Drivers can use the req->no_interrupt | ||
18 | * hint to completely eliminate some IRQs, if a later IRQ is guaranteed | ||
19 | * and DMA chaining is enabled. | ||
20 | * | 16 | * |
21 | * MSI is enabled by default. The legacy IRQ is used if MSI couldn't | 17 | * MSI is enabled by default. The legacy IRQ is used if MSI couldn't |
22 | * be enabled. | 18 | * be enabled. |
@@ -84,23 +80,6 @@ static const char *const ep_name[] = { | |||
84 | "ep-e", "ep-f", "ep-g", "ep-h", | 80 | "ep-e", "ep-f", "ep-g", "ep-h", |
85 | }; | 81 | }; |
86 | 82 | ||
87 | /* use_dma -- general goodness, fewer interrupts, less cpu load (vs PIO) | ||
88 | * use_dma_chaining -- dma descriptor queueing gives even more irq reduction | ||
89 | * | ||
90 | * The net2280 DMA engines are not tightly integrated with their FIFOs; | ||
91 | * not all cases are (yet) handled well in this driver or the silicon. | ||
92 | * Some gadget drivers work better with the dma support here than others. | ||
93 | * These two parameters let you use PIO or more aggressive DMA. | ||
94 | */ | ||
95 | static bool use_dma = true; | ||
96 | static bool use_dma_chaining; | ||
97 | static bool use_msi = true; | ||
98 | |||
99 | /* "modprobe net2280 use_dma=n" etc */ | ||
100 | module_param(use_dma, bool, 0444); | ||
101 | module_param(use_dma_chaining, bool, 0444); | ||
102 | module_param(use_msi, bool, 0444); | ||
103 | |||
104 | /* mode 0 == ep-{a,b,c,d} 1K fifo each | 83 | /* mode 0 == ep-{a,b,c,d} 1K fifo each |
105 | * mode 1 == ep-{a,b} 2K fifo each, ep-{c,d} unavailable | 84 | * mode 1 == ep-{a,b} 2K fifo each, ep-{c,d} unavailable |
106 | * mode 2 == ep-a 2K fifo, ep-{b,c} 1K each, ep-d unavailable | 85 | * mode 2 == ep-a 2K fifo, ep-{b,c} 1K each, ep-d unavailable |
@@ -120,11 +99,6 @@ static bool enable_suspend; | |||
120 | /* "modprobe net2280 enable_suspend=1" etc */ | 99 | /* "modprobe net2280 enable_suspend=1" etc */ |
121 | module_param(enable_suspend, bool, 0444); | 100 | module_param(enable_suspend, bool, 0444); |
122 | 101 | ||
123 | /* force full-speed operation */ | ||
124 | static bool full_speed; | ||
125 | module_param(full_speed, bool, 0444); | ||
126 | MODULE_PARM_DESC(full_speed, "force full-speed mode -- for testing only!"); | ||
127 | |||
128 | #define DIR_STRING(bAddress) (((bAddress) & USB_DIR_IN) ? "in" : "out") | 102 | #define DIR_STRING(bAddress) (((bAddress) & USB_DIR_IN) ? "in" : "out") |
129 | 103 | ||
130 | static char *type_string(u8 bmAttributes) | 104 | static char *type_string(u8 bmAttributes) |
@@ -202,15 +176,6 @@ net2280_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | |||
202 | /* set speed-dependent max packet; may kick in high bandwidth */ | 176 | /* set speed-dependent max packet; may kick in high bandwidth */ |
203 | set_max_speed(ep, max); | 177 | set_max_speed(ep, max); |
204 | 178 | ||
205 | /* FIFO lines can't go to different packets. PIO is ok, so | ||
206 | * use it instead of troublesome (non-bulk) multi-packet DMA. | ||
207 | */ | ||
208 | if (ep->dma && (max % 4) != 0 && use_dma_chaining) { | ||
209 | ep_dbg(ep->dev, "%s, no dma for maxpacket %d\n", | ||
210 | ep->ep.name, ep->ep.maxpacket); | ||
211 | ep->dma = NULL; | ||
212 | } | ||
213 | |||
214 | /* set type, direction, address; reset fifo counters */ | 179 | /* set type, direction, address; reset fifo counters */ |
215 | writel(BIT(FIFO_FLUSH), &ep->regs->ep_stat); | 180 | writel(BIT(FIFO_FLUSH), &ep->regs->ep_stat); |
216 | tmp = (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK); | 181 | tmp = (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK); |
@@ -478,7 +443,7 @@ static int net2280_disable(struct usb_ep *_ep) | |||
478 | /* synch memory views with the device */ | 443 | /* synch memory views with the device */ |
479 | (void)readl(&ep->cfg->ep_cfg); | 444 | (void)readl(&ep->cfg->ep_cfg); |
480 | 445 | ||
481 | if (use_dma && !ep->dma && ep->num >= 1 && ep->num <= 4) | 446 | if (!ep->dma && ep->num >= 1 && ep->num <= 4) |
482 | ep->dma = &ep->dev->dma[ep->num - 1]; | 447 | ep->dma = &ep->dev->dma[ep->num - 1]; |
483 | 448 | ||
484 | spin_unlock_irqrestore(&ep->dev->lock, flags); | 449 | spin_unlock_irqrestore(&ep->dev->lock, flags); |
@@ -610,9 +575,15 @@ static void out_flush(struct net2280_ep *ep) | |||
610 | u32 __iomem *statp; | 575 | u32 __iomem *statp; |
611 | u32 tmp; | 576 | u32 tmp; |
612 | 577 | ||
613 | ASSERT_OUT_NAKING(ep); | ||
614 | |||
615 | statp = &ep->regs->ep_stat; | 578 | statp = &ep->regs->ep_stat; |
579 | |||
580 | tmp = readl(statp); | ||
581 | if (tmp & BIT(NAK_OUT_PACKETS)) { | ||
582 | ep_dbg(ep->dev, "%s %s %08x !NAK\n", | ||
583 | ep->ep.name, __func__, tmp); | ||
584 | writel(BIT(SET_NAK_OUT_PACKETS), &ep->regs->ep_rsp); | ||
585 | } | ||
586 | |||
616 | writel(BIT(DATA_OUT_PING_TOKEN_INTERRUPT) | | 587 | writel(BIT(DATA_OUT_PING_TOKEN_INTERRUPT) | |
617 | BIT(DATA_PACKET_RECEIVED_INTERRUPT), | 588 | BIT(DATA_PACKET_RECEIVED_INTERRUPT), |
618 | statp); | 589 | statp); |
@@ -747,8 +718,7 @@ static void fill_dma_desc(struct net2280_ep *ep, | |||
747 | req->valid = valid; | 718 | req->valid = valid; |
748 | if (valid) | 719 | if (valid) |
749 | dmacount |= BIT(VALID_BIT); | 720 | dmacount |= BIT(VALID_BIT); |
750 | if (likely(!req->req.no_interrupt || !use_dma_chaining)) | 721 | dmacount |= BIT(DMA_DONE_INTERRUPT_ENABLE); |
751 | dmacount |= BIT(DMA_DONE_INTERRUPT_ENABLE); | ||
752 | 722 | ||
753 | /* td->dmadesc = previously set by caller */ | 723 | /* td->dmadesc = previously set by caller */ |
754 | td->dmaaddr = cpu_to_le32 (req->req.dma); | 724 | td->dmaaddr = cpu_to_le32 (req->req.dma); |
@@ -862,27 +832,11 @@ static void start_dma(struct net2280_ep *ep, struct net2280_request *req) | |||
862 | req->td->dmadesc = cpu_to_le32 (ep->td_dma); | 832 | req->td->dmadesc = cpu_to_le32 (ep->td_dma); |
863 | fill_dma_desc(ep, req, 1); | 833 | fill_dma_desc(ep, req, 1); |
864 | 834 | ||
865 | if (!use_dma_chaining) | 835 | req->td->dmacount |= cpu_to_le32(BIT(END_OF_CHAIN)); |
866 | req->td->dmacount |= cpu_to_le32(BIT(END_OF_CHAIN)); | ||
867 | 836 | ||
868 | start_queue(ep, tmp, req->td_dma); | 837 | start_queue(ep, tmp, req->td_dma); |
869 | } | 838 | } |
870 | 839 | ||
871 | static inline void resume_dma(struct net2280_ep *ep) | ||
872 | { | ||
873 | writel(readl(&ep->dma->dmactl) | BIT(DMA_ENABLE), &ep->dma->dmactl); | ||
874 | |||
875 | ep->dma_started = true; | ||
876 | } | ||
877 | |||
878 | static inline void ep_stop_dma(struct net2280_ep *ep) | ||
879 | { | ||
880 | writel(readl(&ep->dma->dmactl) & ~BIT(DMA_ENABLE), &ep->dma->dmactl); | ||
881 | spin_stop_dma(ep->dma); | ||
882 | |||
883 | ep->dma_started = false; | ||
884 | } | ||
885 | |||
886 | static inline void | 840 | static inline void |
887 | queue_dma(struct net2280_ep *ep, struct net2280_request *req, int valid) | 841 | queue_dma(struct net2280_ep *ep, struct net2280_request *req, int valid) |
888 | { | 842 | { |
@@ -973,10 +927,8 @@ net2280_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | |||
973 | return ret; | 927 | return ret; |
974 | } | 928 | } |
975 | 929 | ||
976 | #if 0 | ||
977 | ep_vdbg(dev, "%s queue req %p, len %d buf %p\n", | 930 | ep_vdbg(dev, "%s queue req %p, len %d buf %p\n", |
978 | _ep->name, _req, _req->length, _req->buf); | 931 | _ep->name, _req, _req->length, _req->buf); |
979 | #endif | ||
980 | 932 | ||
981 | spin_lock_irqsave(&dev->lock, flags); | 933 | spin_lock_irqsave(&dev->lock, flags); |
982 | 934 | ||
@@ -984,24 +936,12 @@ net2280_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | |||
984 | _req->actual = 0; | 936 | _req->actual = 0; |
985 | 937 | ||
986 | /* kickstart this i/o queue? */ | 938 | /* kickstart this i/o queue? */ |
987 | if (list_empty(&ep->queue) && !ep->stopped) { | 939 | if (list_empty(&ep->queue) && !ep->stopped && |
988 | /* DMA request while EP halted */ | 940 | !((dev->quirks & PLX_SUPERSPEED) && ep->dma && |
989 | if (ep->dma && | 941 | (readl(&ep->regs->ep_rsp) & BIT(CLEAR_ENDPOINT_HALT)))) { |
990 | (readl(&ep->regs->ep_rsp) & BIT(CLEAR_ENDPOINT_HALT)) && | 942 | |
991 | (dev->quirks & PLX_SUPERSPEED)) { | ||
992 | int valid = 1; | ||
993 | if (ep->is_in) { | ||
994 | int expect; | ||
995 | expect = likely(req->req.zero || | ||
996 | ((req->req.length % | ||
997 | ep->ep.maxpacket) != 0)); | ||
998 | if (expect != ep->in_fifo_validate) | ||
999 | valid = 0; | ||
1000 | } | ||
1001 | queue_dma(ep, req, valid); | ||
1002 | } | ||
1003 | /* use DMA if the endpoint supports it, else pio */ | 943 | /* use DMA if the endpoint supports it, else pio */ |
1004 | else if (ep->dma) | 944 | if (ep->dma) |
1005 | start_dma(ep, req); | 945 | start_dma(ep, req); |
1006 | else { | 946 | else { |
1007 | /* maybe there's no control data, just status ack */ | 947 | /* maybe there's no control data, just status ack */ |
@@ -1084,8 +1024,6 @@ dma_done(struct net2280_ep *ep, struct net2280_request *req, u32 dmacount, | |||
1084 | done(ep, req, status); | 1024 | done(ep, req, status); |
1085 | } | 1025 | } |
1086 | 1026 | ||
1087 | static void restart_dma(struct net2280_ep *ep); | ||
1088 | |||
1089 | static void scan_dma_completions(struct net2280_ep *ep) | 1027 | static void scan_dma_completions(struct net2280_ep *ep) |
1090 | { | 1028 | { |
1091 | /* only look at descriptors that were "naturally" retired, | 1029 | /* only look at descriptors that were "naturally" retired, |
@@ -1117,9 +1055,8 @@ static void scan_dma_completions(struct net2280_ep *ep) | |||
1117 | dma_done(ep, req, tmp, 0); | 1055 | dma_done(ep, req, tmp, 0); |
1118 | break; | 1056 | break; |
1119 | } else if (!ep->is_in && | 1057 | } else if (!ep->is_in && |
1120 | (req->req.length % ep->ep.maxpacket) != 0) { | 1058 | (req->req.length % ep->ep.maxpacket) && |
1121 | if (ep->dev->quirks & PLX_SUPERSPEED) | 1059 | !(ep->dev->quirks & PLX_SUPERSPEED)) { |
1122 | return dma_done(ep, req, tmp, 0); | ||
1123 | 1060 | ||
1124 | tmp = readl(&ep->regs->ep_stat); | 1061 | tmp = readl(&ep->regs->ep_stat); |
1125 | /* AVOID TROUBLE HERE by not issuing short reads from | 1062 | /* AVOID TROUBLE HERE by not issuing short reads from |
@@ -1150,67 +1087,15 @@ static void scan_dma_completions(struct net2280_ep *ep) | |||
1150 | static void restart_dma(struct net2280_ep *ep) | 1087 | static void restart_dma(struct net2280_ep *ep) |
1151 | { | 1088 | { |
1152 | struct net2280_request *req; | 1089 | struct net2280_request *req; |
1153 | u32 dmactl = dmactl_default; | ||
1154 | 1090 | ||
1155 | if (ep->stopped) | 1091 | if (ep->stopped) |
1156 | return; | 1092 | return; |
1157 | req = list_entry(ep->queue.next, struct net2280_request, queue); | 1093 | req = list_entry(ep->queue.next, struct net2280_request, queue); |
1158 | 1094 | ||
1159 | if (!use_dma_chaining) { | 1095 | start_dma(ep, req); |
1160 | start_dma(ep, req); | ||
1161 | return; | ||
1162 | } | ||
1163 | |||
1164 | /* the 2280 will be processing the queue unless queue hiccups after | ||
1165 | * the previous transfer: | ||
1166 | * IN: wanted automagic zlp, head doesn't (or vice versa) | ||
1167 | * DMA_FIFO_VALIDATE doesn't init from dma descriptors. | ||
1168 | * OUT: was "usb-short", we must restart. | ||
1169 | */ | ||
1170 | if (ep->is_in && !req->valid) { | ||
1171 | struct net2280_request *entry, *prev = NULL; | ||
1172 | int reqmode, done = 0; | ||
1173 | |||
1174 | ep_dbg(ep->dev, "%s dma hiccup td %p\n", ep->ep.name, req->td); | ||
1175 | ep->in_fifo_validate = likely(req->req.zero || | ||
1176 | (req->req.length % ep->ep.maxpacket) != 0); | ||
1177 | if (ep->in_fifo_validate) | ||
1178 | dmactl |= BIT(DMA_FIFO_VALIDATE); | ||
1179 | list_for_each_entry(entry, &ep->queue, queue) { | ||
1180 | __le32 dmacount; | ||
1181 | |||
1182 | if (entry == req) | ||
1183 | continue; | ||
1184 | dmacount = entry->td->dmacount; | ||
1185 | if (!done) { | ||
1186 | reqmode = likely(entry->req.zero || | ||
1187 | (entry->req.length % ep->ep.maxpacket)); | ||
1188 | if (reqmode == ep->in_fifo_validate) { | ||
1189 | entry->valid = 1; | ||
1190 | dmacount |= valid_bit; | ||
1191 | entry->td->dmacount = dmacount; | ||
1192 | prev = entry; | ||
1193 | continue; | ||
1194 | } else { | ||
1195 | /* force a hiccup */ | ||
1196 | prev->td->dmacount |= dma_done_ie; | ||
1197 | done = 1; | ||
1198 | } | ||
1199 | } | ||
1200 | |||
1201 | /* walk the rest of the queue so unlinks behave */ | ||
1202 | entry->valid = 0; | ||
1203 | dmacount &= ~valid_bit; | ||
1204 | entry->td->dmacount = dmacount; | ||
1205 | prev = entry; | ||
1206 | } | ||
1207 | } | ||
1208 | |||
1209 | writel(0, &ep->dma->dmactl); | ||
1210 | start_queue(ep, dmactl, req->td_dma); | ||
1211 | } | 1096 | } |
1212 | 1097 | ||
1213 | static void abort_dma_228x(struct net2280_ep *ep) | 1098 | static void abort_dma(struct net2280_ep *ep) |
1214 | { | 1099 | { |
1215 | /* abort the current transfer */ | 1100 | /* abort the current transfer */ |
1216 | if (likely(!list_empty(&ep->queue))) { | 1101 | if (likely(!list_empty(&ep->queue))) { |
@@ -1222,19 +1107,6 @@ static void abort_dma_228x(struct net2280_ep *ep) | |||
1222 | scan_dma_completions(ep); | 1107 | scan_dma_completions(ep); |
1223 | } | 1108 | } |
1224 | 1109 | ||
1225 | static void abort_dma_338x(struct net2280_ep *ep) | ||
1226 | { | ||
1227 | writel(BIT(DMA_ABORT), &ep->dma->dmastat); | ||
1228 | spin_stop_dma(ep->dma); | ||
1229 | } | ||
1230 | |||
1231 | static void abort_dma(struct net2280_ep *ep) | ||
1232 | { | ||
1233 | if (ep->dev->quirks & PLX_LEGACY) | ||
1234 | return abort_dma_228x(ep); | ||
1235 | return abort_dma_338x(ep); | ||
1236 | } | ||
1237 | |||
1238 | /* dequeue ALL requests */ | 1110 | /* dequeue ALL requests */ |
1239 | static void nuke(struct net2280_ep *ep) | 1111 | static void nuke(struct net2280_ep *ep) |
1240 | { | 1112 | { |
@@ -1306,25 +1178,6 @@ static int net2280_dequeue(struct usb_ep *_ep, struct usb_request *_req) | |||
1306 | done(ep, req, -ECONNRESET); | 1178 | done(ep, req, -ECONNRESET); |
1307 | } | 1179 | } |
1308 | req = NULL; | 1180 | req = NULL; |
1309 | |||
1310 | /* patch up hardware chaining data */ | ||
1311 | } else if (ep->dma && use_dma_chaining) { | ||
1312 | if (req->queue.prev == ep->queue.next) { | ||
1313 | writel(le32_to_cpu(req->td->dmadesc), | ||
1314 | &ep->dma->dmadesc); | ||
1315 | if (req->td->dmacount & dma_done_ie) | ||
1316 | writel(readl(&ep->dma->dmacount) | | ||
1317 | le32_to_cpu(dma_done_ie), | ||
1318 | &ep->dma->dmacount); | ||
1319 | } else { | ||
1320 | struct net2280_request *prev; | ||
1321 | |||
1322 | prev = list_entry(req->queue.prev, | ||
1323 | struct net2280_request, queue); | ||
1324 | prev->td->dmadesc = req->td->dmadesc; | ||
1325 | if (req->td->dmacount & dma_done_ie) | ||
1326 | prev->td->dmacount |= dma_done_ie; | ||
1327 | } | ||
1328 | } | 1181 | } |
1329 | 1182 | ||
1330 | if (req) | 1183 | if (req) |
@@ -1512,10 +1365,10 @@ static int net2280_set_selfpowered(struct usb_gadget *_gadget, int value) | |||
1512 | tmp = readl(&dev->usb->usbctl); | 1365 | tmp = readl(&dev->usb->usbctl); |
1513 | if (value) { | 1366 | if (value) { |
1514 | tmp |= BIT(SELF_POWERED_STATUS); | 1367 | tmp |= BIT(SELF_POWERED_STATUS); |
1515 | dev->selfpowered = 1; | 1368 | _gadget->is_selfpowered = 1; |
1516 | } else { | 1369 | } else { |
1517 | tmp &= ~BIT(SELF_POWERED_STATUS); | 1370 | tmp &= ~BIT(SELF_POWERED_STATUS); |
1518 | dev->selfpowered = 0; | 1371 | _gadget->is_selfpowered = 0; |
1519 | } | 1372 | } |
1520 | writel(tmp, &dev->usb->usbctl); | 1373 | writel(tmp, &dev->usb->usbctl); |
1521 | spin_unlock_irqrestore(&dev->lock, flags); | 1374 | spin_unlock_irqrestore(&dev->lock, flags); |
@@ -1604,14 +1457,11 @@ static ssize_t registers_show(struct device *_dev, | |||
1604 | 1457 | ||
1605 | /* Main Control Registers */ | 1458 | /* Main Control Registers */ |
1606 | t = scnprintf(next, size, "%s version " DRIVER_VERSION | 1459 | t = scnprintf(next, size, "%s version " DRIVER_VERSION |
1607 | ", chiprev %04x, dma %s\n\n" | 1460 | ", chiprev %04x\n\n" |
1608 | "devinit %03x fifoctl %08x gadget '%s'\n" | 1461 | "devinit %03x fifoctl %08x gadget '%s'\n" |
1609 | "pci irqenb0 %02x irqenb1 %08x " | 1462 | "pci irqenb0 %02x irqenb1 %08x " |
1610 | "irqstat0 %04x irqstat1 %08x\n", | 1463 | "irqstat0 %04x irqstat1 %08x\n", |
1611 | driver_name, dev->chiprev, | 1464 | driver_name, dev->chiprev, |
1612 | use_dma | ||
1613 | ? (use_dma_chaining ? "chaining" : "enabled") | ||
1614 | : "disabled", | ||
1615 | readl(&dev->regs->devinit), | 1465 | readl(&dev->regs->devinit), |
1616 | readl(&dev->regs->fifoctl), | 1466 | readl(&dev->regs->fifoctl), |
1617 | s, | 1467 | s, |
@@ -1913,76 +1763,73 @@ static void defect7374_disable_data_eps(struct net2280 *dev) | |||
1913 | static void defect7374_enable_data_eps_zero(struct net2280 *dev) | 1763 | static void defect7374_enable_data_eps_zero(struct net2280 *dev) |
1914 | { | 1764 | { |
1915 | u32 tmp = 0, tmp_reg; | 1765 | u32 tmp = 0, tmp_reg; |
1916 | u32 fsmvalue, scratch; | 1766 | u32 scratch; |
1917 | int i; | 1767 | int i; |
1918 | unsigned char ep_sel; | 1768 | unsigned char ep_sel; |
1919 | 1769 | ||
1920 | scratch = get_idx_reg(dev->regs, SCRATCH); | 1770 | scratch = get_idx_reg(dev->regs, SCRATCH); |
1921 | fsmvalue = scratch & (0xf << DEFECT7374_FSM_FIELD); | 1771 | |
1772 | WARN_ON((scratch & (0xf << DEFECT7374_FSM_FIELD)) | ||
1773 | == DEFECT7374_FSM_SS_CONTROL_READ); | ||
1774 | |||
1922 | scratch &= ~(0xf << DEFECT7374_FSM_FIELD); | 1775 | scratch &= ~(0xf << DEFECT7374_FSM_FIELD); |
1923 | 1776 | ||
1924 | /*See if firmware needs to set up for workaround*/ | 1777 | ep_warn(dev, "Operate Defect 7374 workaround soft this time"); |
1925 | if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ) { | 1778 | ep_warn(dev, "It will operate on cold-reboot and SS connect"); |
1926 | ep_warn(dev, "Operate Defect 7374 workaround soft this time"); | ||
1927 | ep_warn(dev, "It will operate on cold-reboot and SS connect"); | ||
1928 | |||
1929 | /*GPEPs:*/ | ||
1930 | tmp = ((0 << ENDPOINT_NUMBER) | BIT(ENDPOINT_DIRECTION) | | ||
1931 | (2 << OUT_ENDPOINT_TYPE) | (2 << IN_ENDPOINT_TYPE) | | ||
1932 | ((dev->enhanced_mode) ? | ||
1933 | BIT(OUT_ENDPOINT_ENABLE) : BIT(ENDPOINT_ENABLE)) | | ||
1934 | BIT(IN_ENDPOINT_ENABLE)); | ||
1935 | |||
1936 | for (i = 1; i < 5; i++) | ||
1937 | writel(tmp, &dev->ep[i].cfg->ep_cfg); | ||
1938 | |||
1939 | /* CSRIN, PCIIN, STATIN, RCIN*/ | ||
1940 | tmp = ((0 << ENDPOINT_NUMBER) | BIT(ENDPOINT_ENABLE)); | ||
1941 | writel(tmp, &dev->dep[1].dep_cfg); | ||
1942 | writel(tmp, &dev->dep[3].dep_cfg); | ||
1943 | writel(tmp, &dev->dep[4].dep_cfg); | ||
1944 | writel(tmp, &dev->dep[5].dep_cfg); | ||
1945 | |||
1946 | /*Implemented for development and debug. | ||
1947 | * Can be refined/tuned later.*/ | ||
1948 | for (ep_sel = 0; ep_sel <= 21; ep_sel++) { | ||
1949 | /* Select an endpoint for subsequent operations: */ | ||
1950 | tmp_reg = readl(&dev->plregs->pl_ep_ctrl); | ||
1951 | writel(((tmp_reg & ~0x1f) | ep_sel), | ||
1952 | &dev->plregs->pl_ep_ctrl); | ||
1953 | |||
1954 | if (ep_sel == 1) { | ||
1955 | tmp = | ||
1956 | (readl(&dev->plregs->pl_ep_ctrl) | | ||
1957 | BIT(CLEAR_ACK_ERROR_CODE) | 0); | ||
1958 | writel(tmp, &dev->plregs->pl_ep_ctrl); | ||
1959 | continue; | ||
1960 | } | ||
1961 | 1779 | ||
1962 | if (ep_sel == 0 || (ep_sel > 9 && ep_sel < 14) || | 1780 | /*GPEPs:*/ |
1963 | ep_sel == 18 || ep_sel == 20) | 1781 | tmp = ((0 << ENDPOINT_NUMBER) | BIT(ENDPOINT_DIRECTION) | |
1964 | continue; | 1782 | (2 << OUT_ENDPOINT_TYPE) | (2 << IN_ENDPOINT_TYPE) | |
1783 | ((dev->enhanced_mode) ? | ||
1784 | BIT(OUT_ENDPOINT_ENABLE) : BIT(ENDPOINT_ENABLE)) | | ||
1785 | BIT(IN_ENDPOINT_ENABLE)); | ||
1965 | 1786 | ||
1966 | tmp = (readl(&dev->plregs->pl_ep_cfg_4) | | 1787 | for (i = 1; i < 5; i++) |
1967 | BIT(NON_CTRL_IN_TOLERATE_BAD_DIR) | 0); | 1788 | writel(tmp, &dev->ep[i].cfg->ep_cfg); |
1968 | writel(tmp, &dev->plregs->pl_ep_cfg_4); | ||
1969 | 1789 | ||
1970 | tmp = readl(&dev->plregs->pl_ep_ctrl) & | 1790 | /* CSRIN, PCIIN, STATIN, RCIN*/ |
1971 | ~BIT(EP_INITIALIZED); | 1791 | tmp = ((0 << ENDPOINT_NUMBER) | BIT(ENDPOINT_ENABLE)); |
1972 | writel(tmp, &dev->plregs->pl_ep_ctrl); | 1792 | writel(tmp, &dev->dep[1].dep_cfg); |
1793 | writel(tmp, &dev->dep[3].dep_cfg); | ||
1794 | writel(tmp, &dev->dep[4].dep_cfg); | ||
1795 | writel(tmp, &dev->dep[5].dep_cfg); | ||
1796 | |||
1797 | /*Implemented for development and debug. | ||
1798 | * Can be refined/tuned later.*/ | ||
1799 | for (ep_sel = 0; ep_sel <= 21; ep_sel++) { | ||
1800 | /* Select an endpoint for subsequent operations: */ | ||
1801 | tmp_reg = readl(&dev->plregs->pl_ep_ctrl); | ||
1802 | writel(((tmp_reg & ~0x1f) | ep_sel), | ||
1803 | &dev->plregs->pl_ep_ctrl); | ||
1973 | 1804 | ||
1805 | if (ep_sel == 1) { | ||
1806 | tmp = | ||
1807 | (readl(&dev->plregs->pl_ep_ctrl) | | ||
1808 | BIT(CLEAR_ACK_ERROR_CODE) | 0); | ||
1809 | writel(tmp, &dev->plregs->pl_ep_ctrl); | ||
1810 | continue; | ||
1974 | } | 1811 | } |
1975 | 1812 | ||
1976 | /* Set FSM to focus on the first Control Read: | 1813 | if (ep_sel == 0 || (ep_sel > 9 && ep_sel < 14) || |
1977 | * - Tip: Connection speed is known upon the first | 1814 | ep_sel == 18 || ep_sel == 20) |
1978 | * setup request.*/ | 1815 | continue; |
1979 | scratch |= DEFECT7374_FSM_WAITING_FOR_CONTROL_READ; | 1816 | |
1980 | set_idx_reg(dev->regs, SCRATCH, scratch); | 1817 | tmp = (readl(&dev->plregs->pl_ep_cfg_4) | |
1818 | BIT(NON_CTRL_IN_TOLERATE_BAD_DIR) | 0); | ||
1819 | writel(tmp, &dev->plregs->pl_ep_cfg_4); | ||
1820 | |||
1821 | tmp = readl(&dev->plregs->pl_ep_ctrl) & | ||
1822 | ~BIT(EP_INITIALIZED); | ||
1823 | writel(tmp, &dev->plregs->pl_ep_ctrl); | ||
1981 | 1824 | ||
1982 | } else{ | ||
1983 | ep_warn(dev, "Defect 7374 workaround soft will NOT operate"); | ||
1984 | ep_warn(dev, "It will operate on cold-reboot and SS connect"); | ||
1985 | } | 1825 | } |
1826 | |||
1827 | /* Set FSM to focus on the first Control Read: | ||
1828 | * - Tip: Connection speed is known upon the first | ||
1829 | * setup request.*/ | ||
1830 | scratch |= DEFECT7374_FSM_WAITING_FOR_CONTROL_READ; | ||
1831 | set_idx_reg(dev->regs, SCRATCH, scratch); | ||
1832 | |||
1986 | } | 1833 | } |
1987 | 1834 | ||
1988 | /* keeping it simple: | 1835 | /* keeping it simple: |
@@ -2033,21 +1880,13 @@ static void usb_reset_228x(struct net2280 *dev) | |||
2033 | static void usb_reset_338x(struct net2280 *dev) | 1880 | static void usb_reset_338x(struct net2280 *dev) |
2034 | { | 1881 | { |
2035 | u32 tmp; | 1882 | u32 tmp; |
2036 | u32 fsmvalue; | ||
2037 | 1883 | ||
2038 | dev->gadget.speed = USB_SPEED_UNKNOWN; | 1884 | dev->gadget.speed = USB_SPEED_UNKNOWN; |
2039 | (void)readl(&dev->usb->usbctl); | 1885 | (void)readl(&dev->usb->usbctl); |
2040 | 1886 | ||
2041 | net2280_led_init(dev); | 1887 | net2280_led_init(dev); |
2042 | 1888 | ||
2043 | fsmvalue = get_idx_reg(dev->regs, SCRATCH) & | 1889 | if (dev->bug7734_patched) { |
2044 | (0xf << DEFECT7374_FSM_FIELD); | ||
2045 | |||
2046 | /* See if firmware needs to set up for workaround: */ | ||
2047 | if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ) { | ||
2048 | ep_info(dev, "%s: Defect 7374 FsmValue 0x%08x\n", __func__, | ||
2049 | fsmvalue); | ||
2050 | } else { | ||
2051 | /* disable automatic responses, and irqs */ | 1890 | /* disable automatic responses, and irqs */ |
2052 | writel(0, &dev->usb->stdrsp); | 1891 | writel(0, &dev->usb->stdrsp); |
2053 | writel(0, &dev->regs->pciirqenb0); | 1892 | writel(0, &dev->regs->pciirqenb0); |
@@ -2064,7 +1903,7 @@ static void usb_reset_338x(struct net2280 *dev) | |||
2064 | 1903 | ||
2065 | writel(~0, &dev->regs->irqstat0), writel(~0, &dev->regs->irqstat1); | 1904 | writel(~0, &dev->regs->irqstat0), writel(~0, &dev->regs->irqstat1); |
2066 | 1905 | ||
2067 | if (fsmvalue == DEFECT7374_FSM_SS_CONTROL_READ) { | 1906 | if (dev->bug7734_patched) { |
2068 | /* reset, and enable pci */ | 1907 | /* reset, and enable pci */ |
2069 | tmp = readl(&dev->regs->devinit) | | 1908 | tmp = readl(&dev->regs->devinit) | |
2070 | BIT(PCI_ENABLE) | | 1909 | BIT(PCI_ENABLE) | |
@@ -2093,10 +1932,6 @@ static void usb_reset(struct net2280 *dev) | |||
2093 | static void usb_reinit_228x(struct net2280 *dev) | 1932 | static void usb_reinit_228x(struct net2280 *dev) |
2094 | { | 1933 | { |
2095 | u32 tmp; | 1934 | u32 tmp; |
2096 | int init_dma; | ||
2097 | |||
2098 | /* use_dma changes are ignored till next device re-init */ | ||
2099 | init_dma = use_dma; | ||
2100 | 1935 | ||
2101 | /* basic endpoint init */ | 1936 | /* basic endpoint init */ |
2102 | for (tmp = 0; tmp < 7; tmp++) { | 1937 | for (tmp = 0; tmp < 7; tmp++) { |
@@ -2108,8 +1943,7 @@ static void usb_reinit_228x(struct net2280 *dev) | |||
2108 | 1943 | ||
2109 | if (tmp > 0 && tmp <= 4) { | 1944 | if (tmp > 0 && tmp <= 4) { |
2110 | ep->fifo_size = 1024; | 1945 | ep->fifo_size = 1024; |
2111 | if (init_dma) | 1946 | ep->dma = &dev->dma[tmp - 1]; |
2112 | ep->dma = &dev->dma[tmp - 1]; | ||
2113 | } else | 1947 | } else |
2114 | ep->fifo_size = 64; | 1948 | ep->fifo_size = 64; |
2115 | ep->regs = &dev->epregs[tmp]; | 1949 | ep->regs = &dev->epregs[tmp]; |
@@ -2133,17 +1967,12 @@ static void usb_reinit_228x(struct net2280 *dev) | |||
2133 | 1967 | ||
2134 | static void usb_reinit_338x(struct net2280 *dev) | 1968 | static void usb_reinit_338x(struct net2280 *dev) |
2135 | { | 1969 | { |
2136 | int init_dma; | ||
2137 | int i; | 1970 | int i; |
2138 | u32 tmp, val; | 1971 | u32 tmp, val; |
2139 | u32 fsmvalue; | ||
2140 | static const u32 ne[9] = { 0, 1, 2, 3, 4, 1, 2, 3, 4 }; | 1972 | static const u32 ne[9] = { 0, 1, 2, 3, 4, 1, 2, 3, 4 }; |
2141 | static const u32 ep_reg_addr[9] = { 0x00, 0xC0, 0x00, 0xC0, 0x00, | 1973 | static const u32 ep_reg_addr[9] = { 0x00, 0xC0, 0x00, 0xC0, 0x00, |
2142 | 0x00, 0xC0, 0x00, 0xC0 }; | 1974 | 0x00, 0xC0, 0x00, 0xC0 }; |
2143 | 1975 | ||
2144 | /* use_dma changes are ignored till next device re-init */ | ||
2145 | init_dma = use_dma; | ||
2146 | |||
2147 | /* basic endpoint init */ | 1976 | /* basic endpoint init */ |
2148 | for (i = 0; i < dev->n_ep; i++) { | 1977 | for (i = 0; i < dev->n_ep; i++) { |
2149 | struct net2280_ep *ep = &dev->ep[i]; | 1978 | struct net2280_ep *ep = &dev->ep[i]; |
@@ -2152,7 +1981,7 @@ static void usb_reinit_338x(struct net2280 *dev) | |||
2152 | ep->dev = dev; | 1981 | ep->dev = dev; |
2153 | ep->num = i; | 1982 | ep->num = i; |
2154 | 1983 | ||
2155 | if (i > 0 && i <= 4 && init_dma) | 1984 | if (i > 0 && i <= 4) |
2156 | ep->dma = &dev->dma[i - 1]; | 1985 | ep->dma = &dev->dma[i - 1]; |
2157 | 1986 | ||
2158 | if (dev->enhanced_mode) { | 1987 | if (dev->enhanced_mode) { |
@@ -2177,14 +2006,7 @@ static void usb_reinit_338x(struct net2280 *dev) | |||
2177 | dev->ep[0].stopped = 0; | 2006 | dev->ep[0].stopped = 0; |
2178 | 2007 | ||
2179 | /* Link layer set up */ | 2008 | /* Link layer set up */ |
2180 | fsmvalue = get_idx_reg(dev->regs, SCRATCH) & | 2009 | if (dev->bug7734_patched) { |
2181 | (0xf << DEFECT7374_FSM_FIELD); | ||
2182 | |||
2183 | /* See if driver needs to set up for workaround: */ | ||
2184 | if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ) | ||
2185 | ep_info(dev, "%s: Defect 7374 FsmValue %08x\n", | ||
2186 | __func__, fsmvalue); | ||
2187 | else { | ||
2188 | tmp = readl(&dev->usb_ext->usbctl2) & | 2010 | tmp = readl(&dev->usb_ext->usbctl2) & |
2189 | ~(BIT(U1_ENABLE) | BIT(U2_ENABLE) | BIT(LTM_ENABLE)); | 2011 | ~(BIT(U1_ENABLE) | BIT(U2_ENABLE) | BIT(LTM_ENABLE)); |
2190 | writel(tmp, &dev->usb_ext->usbctl2); | 2012 | writel(tmp, &dev->usb_ext->usbctl2); |
@@ -2291,15 +2113,8 @@ static void ep0_start_228x(struct net2280 *dev) | |||
2291 | 2113 | ||
2292 | static void ep0_start_338x(struct net2280 *dev) | 2114 | static void ep0_start_338x(struct net2280 *dev) |
2293 | { | 2115 | { |
2294 | u32 fsmvalue; | ||
2295 | |||
2296 | fsmvalue = get_idx_reg(dev->regs, SCRATCH) & | ||
2297 | (0xf << DEFECT7374_FSM_FIELD); | ||
2298 | 2116 | ||
2299 | if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ) | 2117 | if (dev->bug7734_patched) |
2300 | ep_info(dev, "%s: Defect 7374 FsmValue %08x\n", __func__, | ||
2301 | fsmvalue); | ||
2302 | else | ||
2303 | writel(BIT(CLEAR_NAK_OUT_PACKETS_MODE) | | 2118 | writel(BIT(CLEAR_NAK_OUT_PACKETS_MODE) | |
2304 | BIT(SET_EP_HIDE_STATUS_PHASE), | 2119 | BIT(SET_EP_HIDE_STATUS_PHASE), |
2305 | &dev->epregs[0].ep_rsp); | 2120 | &dev->epregs[0].ep_rsp); |
@@ -2382,16 +2197,12 @@ static int net2280_start(struct usb_gadget *_gadget, | |||
2382 | if (retval) | 2197 | if (retval) |
2383 | goto err_func; | 2198 | goto err_func; |
2384 | 2199 | ||
2385 | /* Enable force-full-speed testing mode, if desired */ | 2200 | /* enable host detection and ep0; and we're ready |
2386 | if (full_speed && (dev->quirks & PLX_LEGACY)) | ||
2387 | writel(BIT(FORCE_FULL_SPEED_MODE), &dev->usb->xcvrdiag); | ||
2388 | |||
2389 | /* ... then enable host detection and ep0; and we're ready | ||
2390 | * for set_configuration as well as eventual disconnect. | 2201 | * for set_configuration as well as eventual disconnect. |
2391 | */ | 2202 | */ |
2392 | net2280_led_active(dev, 1); | 2203 | net2280_led_active(dev, 1); |
2393 | 2204 | ||
2394 | if (dev->quirks & PLX_SUPERSPEED) | 2205 | if ((dev->quirks & PLX_SUPERSPEED) && !dev->bug7734_patched) |
2395 | defect7374_enable_data_eps_zero(dev); | 2206 | defect7374_enable_data_eps_zero(dev); |
2396 | 2207 | ||
2397 | ep0_start(dev); | 2208 | ep0_start(dev); |
@@ -2444,10 +2255,6 @@ static int net2280_stop(struct usb_gadget *_gadget) | |||
2444 | 2255 | ||
2445 | net2280_led_active(dev, 0); | 2256 | net2280_led_active(dev, 0); |
2446 | 2257 | ||
2447 | /* Disable full-speed test mode */ | ||
2448 | if (dev->quirks & PLX_LEGACY) | ||
2449 | writel(0, &dev->usb->xcvrdiag); | ||
2450 | |||
2451 | device_remove_file(&dev->pdev->dev, &dev_attr_function); | 2258 | device_remove_file(&dev->pdev->dev, &dev_attr_function); |
2452 | device_remove_file(&dev->pdev->dev, &dev_attr_queues); | 2259 | device_remove_file(&dev->pdev->dev, &dev_attr_queues); |
2453 | 2260 | ||
@@ -2478,10 +2285,10 @@ static void handle_ep_small(struct net2280_ep *ep) | |||
2478 | /* ack all, and handle what we care about */ | 2285 | /* ack all, and handle what we care about */ |
2479 | t = readl(&ep->regs->ep_stat); | 2286 | t = readl(&ep->regs->ep_stat); |
2480 | ep->irqs++; | 2287 | ep->irqs++; |
2481 | #if 0 | 2288 | |
2482 | ep_vdbg(ep->dev, "%s ack ep_stat %08x, req %p\n", | 2289 | ep_vdbg(ep->dev, "%s ack ep_stat %08x, req %p\n", |
2483 | ep->ep.name, t, req ? &req->req : 0); | 2290 | ep->ep.name, t, req ? &req->req : NULL); |
2484 | #endif | 2291 | |
2485 | if (!ep->is_in || (ep->dev->quirks & PLX_2280)) | 2292 | if (!ep->is_in || (ep->dev->quirks & PLX_2280)) |
2486 | writel(t & ~BIT(NAK_OUT_PACKETS), &ep->regs->ep_stat); | 2293 | writel(t & ~BIT(NAK_OUT_PACKETS), &ep->regs->ep_stat); |
2487 | else | 2294 | else |
@@ -2717,6 +2524,7 @@ static void defect7374_workaround(struct net2280 *dev, struct usb_ctrlrequest r) | |||
2717 | * run after the next USB connection. | 2524 | * run after the next USB connection. |
2718 | */ | 2525 | */ |
2719 | scratch |= DEFECT7374_FSM_NON_SS_CONTROL_READ; | 2526 | scratch |= DEFECT7374_FSM_NON_SS_CONTROL_READ; |
2527 | dev->bug7734_patched = 1; | ||
2720 | goto restore_data_eps; | 2528 | goto restore_data_eps; |
2721 | } | 2529 | } |
2722 | 2530 | ||
@@ -2730,6 +2538,7 @@ static void defect7374_workaround(struct net2280 *dev, struct usb_ctrlrequest r) | |||
2730 | if ((state >= (ACK_GOOD_NORMAL << STATE)) && | 2538 | if ((state >= (ACK_GOOD_NORMAL << STATE)) && |
2731 | (state <= (ACK_GOOD_MORE_ACKS_TO_COME << STATE))) { | 2539 | (state <= (ACK_GOOD_MORE_ACKS_TO_COME << STATE))) { |
2732 | scratch |= DEFECT7374_FSM_SS_CONTROL_READ; | 2540 | scratch |= DEFECT7374_FSM_SS_CONTROL_READ; |
2541 | dev->bug7734_patched = 1; | ||
2733 | break; | 2542 | break; |
2734 | } | 2543 | } |
2735 | 2544 | ||
@@ -2766,80 +2575,19 @@ restore_data_eps: | |||
2766 | return; | 2575 | return; |
2767 | } | 2576 | } |
2768 | 2577 | ||
2769 | static void ep_stall(struct net2280_ep *ep, int stall) | 2578 | static void ep_clear_seqnum(struct net2280_ep *ep) |
2770 | { | 2579 | { |
2771 | struct net2280 *dev = ep->dev; | 2580 | struct net2280 *dev = ep->dev; |
2772 | u32 val; | 2581 | u32 val; |
2773 | static const u32 ep_pl[9] = { 0, 3, 4, 7, 8, 2, 5, 6, 9 }; | 2582 | static const u32 ep_pl[9] = { 0, 3, 4, 7, 8, 2, 5, 6, 9 }; |
2774 | 2583 | ||
2775 | if (stall) { | 2584 | val = readl(&dev->plregs->pl_ep_ctrl) & ~0x1f; |
2776 | writel(BIT(SET_ENDPOINT_HALT) | | 2585 | val |= ep_pl[ep->num]; |
2777 | /* BIT(SET_NAK_PACKETS) | */ | 2586 | writel(val, &dev->plregs->pl_ep_ctrl); |
2778 | BIT(CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE), | 2587 | val |= BIT(SEQUENCE_NUMBER_RESET); |
2779 | &ep->regs->ep_rsp); | 2588 | writel(val, &dev->plregs->pl_ep_ctrl); |
2780 | ep->is_halt = 1; | ||
2781 | } else { | ||
2782 | if (dev->gadget.speed == USB_SPEED_SUPER) { | ||
2783 | /* | ||
2784 | * Workaround for SS SeqNum not cleared via | ||
2785 | * Endpoint Halt (Clear) bit. select endpoint | ||
2786 | */ | ||
2787 | val = readl(&dev->plregs->pl_ep_ctrl); | ||
2788 | val = (val & ~0x1f) | ep_pl[ep->num]; | ||
2789 | writel(val, &dev->plregs->pl_ep_ctrl); | ||
2790 | |||
2791 | val |= BIT(SEQUENCE_NUMBER_RESET); | ||
2792 | writel(val, &dev->plregs->pl_ep_ctrl); | ||
2793 | } | ||
2794 | val = readl(&ep->regs->ep_rsp); | ||
2795 | val |= BIT(CLEAR_ENDPOINT_HALT) | | ||
2796 | BIT(CLEAR_ENDPOINT_TOGGLE); | ||
2797 | writel(val, | ||
2798 | /* | BIT(CLEAR_NAK_PACKETS),*/ | ||
2799 | &ep->regs->ep_rsp); | ||
2800 | ep->is_halt = 0; | ||
2801 | val = readl(&ep->regs->ep_rsp); | ||
2802 | } | ||
2803 | } | ||
2804 | |||
2805 | static void ep_stdrsp(struct net2280_ep *ep, int value, int wedged) | ||
2806 | { | ||
2807 | /* set/clear, then synch memory views with the device */ | ||
2808 | if (value) { | ||
2809 | ep->stopped = 1; | ||
2810 | if (ep->num == 0) | ||
2811 | ep->dev->protocol_stall = 1; | ||
2812 | else { | ||
2813 | if (ep->dma) | ||
2814 | ep_stop_dma(ep); | ||
2815 | ep_stall(ep, true); | ||
2816 | } | ||
2817 | |||
2818 | if (wedged) | ||
2819 | ep->wedged = 1; | ||
2820 | } else { | ||
2821 | ep->stopped = 0; | ||
2822 | ep->wedged = 0; | ||
2823 | |||
2824 | ep_stall(ep, false); | ||
2825 | 2589 | ||
2826 | /* Flush the queue */ | 2590 | return; |
2827 | if (!list_empty(&ep->queue)) { | ||
2828 | struct net2280_request *req = | ||
2829 | list_entry(ep->queue.next, struct net2280_request, | ||
2830 | queue); | ||
2831 | if (ep->dma) | ||
2832 | resume_dma(ep); | ||
2833 | else { | ||
2834 | if (ep->is_in) | ||
2835 | write_fifo(ep, &req->req); | ||
2836 | else { | ||
2837 | if (read_fifo(ep, req)) | ||
2838 | done(ep, req, 0); | ||
2839 | } | ||
2840 | } | ||
2841 | } | ||
2842 | } | ||
2843 | } | 2591 | } |
2844 | 2592 | ||
2845 | static void handle_stat0_irqs_superspeed(struct net2280 *dev, | 2593 | static void handle_stat0_irqs_superspeed(struct net2280 *dev, |
@@ -2863,7 +2611,7 @@ static void handle_stat0_irqs_superspeed(struct net2280 *dev, | |||
2863 | switch (r.bRequestType) { | 2611 | switch (r.bRequestType) { |
2864 | case (USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE): | 2612 | case (USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE): |
2865 | status = dev->wakeup_enable ? 0x02 : 0x00; | 2613 | status = dev->wakeup_enable ? 0x02 : 0x00; |
2866 | if (dev->selfpowered) | 2614 | if (dev->gadget.is_selfpowered) |
2867 | status |= BIT(0); | 2615 | status |= BIT(0); |
2868 | status |= (dev->u1_enable << 2 | dev->u2_enable << 3 | | 2616 | status |= (dev->u1_enable << 2 | dev->u2_enable << 3 | |
2869 | dev->ltm_enable << 4); | 2617 | dev->ltm_enable << 4); |
@@ -2940,7 +2688,12 @@ static void handle_stat0_irqs_superspeed(struct net2280 *dev, | |||
2940 | if (w_value != USB_ENDPOINT_HALT) | 2688 | if (w_value != USB_ENDPOINT_HALT) |
2941 | goto do_stall3; | 2689 | goto do_stall3; |
2942 | ep_vdbg(dev, "%s clear halt\n", e->ep.name); | 2690 | ep_vdbg(dev, "%s clear halt\n", e->ep.name); |
2943 | ep_stall(e, false); | 2691 | /* |
2692 | * Workaround for SS SeqNum not cleared via | ||
2693 | * Endpoint Halt (Clear) bit. select endpoint | ||
2694 | */ | ||
2695 | ep_clear_seqnum(e); | ||
2696 | clear_halt(e); | ||
2944 | if (!list_empty(&e->queue) && e->td_dma) | 2697 | if (!list_empty(&e->queue) && e->td_dma) |
2945 | restart_dma(e); | 2698 | restart_dma(e); |
2946 | allow_status(ep); | 2699 | allow_status(ep); |
@@ -2998,7 +2751,14 @@ static void handle_stat0_irqs_superspeed(struct net2280 *dev, | |||
2998 | e = get_ep_by_addr(dev, w_index); | 2751 | e = get_ep_by_addr(dev, w_index); |
2999 | if (!e || (w_value != USB_ENDPOINT_HALT)) | 2752 | if (!e || (w_value != USB_ENDPOINT_HALT)) |
3000 | goto do_stall3; | 2753 | goto do_stall3; |
3001 | ep_stdrsp(e, true, false); | 2754 | ep->stopped = 1; |
2755 | if (ep->num == 0) | ||
2756 | ep->dev->protocol_stall = 1; | ||
2757 | else { | ||
2758 | if (ep->dma) | ||
2759 | abort_dma(ep); | ||
2760 | set_halt(ep); | ||
2761 | } | ||
3002 | allow_status_338x(ep); | 2762 | allow_status_338x(ep); |
3003 | break; | 2763 | break; |
3004 | 2764 | ||
@@ -3026,7 +2786,7 @@ do_stall3: | |||
3026 | r.bRequestType, r.bRequest, tmp); | 2786 | r.bRequestType, r.bRequest, tmp); |
3027 | dev->protocol_stall = 1; | 2787 | dev->protocol_stall = 1; |
3028 | /* TD 9.9 Halt Endpoint test. TD 9.22 Set feature test */ | 2788 | /* TD 9.9 Halt Endpoint test. TD 9.22 Set feature test */ |
3029 | ep_stall(ep, true); | 2789 | set_halt(ep); |
3030 | } | 2790 | } |
3031 | 2791 | ||
3032 | next_endpoints3: | 2792 | next_endpoints3: |
@@ -3091,9 +2851,7 @@ static void handle_stat0_irqs(struct net2280 *dev, u32 stat) | |||
3091 | } | 2851 | } |
3092 | ep->stopped = 0; | 2852 | ep->stopped = 0; |
3093 | dev->protocol_stall = 0; | 2853 | dev->protocol_stall = 0; |
3094 | if (dev->quirks & PLX_SUPERSPEED) | 2854 | if (!(dev->quirks & PLX_SUPERSPEED)) { |
3095 | ep->is_halt = 0; | ||
3096 | else{ | ||
3097 | if (ep->dev->quirks & PLX_2280) | 2855 | if (ep->dev->quirks & PLX_2280) |
3098 | tmp = BIT(FIFO_OVERFLOW) | | 2856 | tmp = BIT(FIFO_OVERFLOW) | |
3099 | BIT(FIFO_UNDERFLOW); | 2857 | BIT(FIFO_UNDERFLOW); |
@@ -3120,7 +2878,7 @@ static void handle_stat0_irqs(struct net2280 *dev, u32 stat) | |||
3120 | cpu_to_le32s(&u.raw[0]); | 2878 | cpu_to_le32s(&u.raw[0]); |
3121 | cpu_to_le32s(&u.raw[1]); | 2879 | cpu_to_le32s(&u.raw[1]); |
3122 | 2880 | ||
3123 | if (dev->quirks & PLX_SUPERSPEED) | 2881 | if ((dev->quirks & PLX_SUPERSPEED) && !dev->bug7734_patched) |
3124 | defect7374_workaround(dev, u.r); | 2882 | defect7374_workaround(dev, u.r); |
3125 | 2883 | ||
3126 | tmp = 0; | 2884 | tmp = 0; |
@@ -3423,17 +3181,12 @@ static void handle_stat1_irqs(struct net2280 *dev, u32 stat) | |||
3423 | continue; | 3181 | continue; |
3424 | } | 3182 | } |
3425 | 3183 | ||
3426 | /* chaining should stop on abort, short OUT from fifo, | 3184 | if (!(tmp & BIT(DMA_TRANSACTION_DONE_INTERRUPT))) { |
3427 | * or (stat0 codepath) short OUT transfer. | 3185 | ep_dbg(ep->dev, "%s no xact done? %08x\n", |
3428 | */ | 3186 | ep->ep.name, tmp); |
3429 | if (!use_dma_chaining) { | 3187 | continue; |
3430 | if (!(tmp & BIT(DMA_TRANSACTION_DONE_INTERRUPT))) { | ||
3431 | ep_dbg(ep->dev, "%s no xact done? %08x\n", | ||
3432 | ep->ep.name, tmp); | ||
3433 | continue; | ||
3434 | } | ||
3435 | stop_dma(ep->dma); | ||
3436 | } | 3188 | } |
3189 | stop_dma(ep->dma); | ||
3437 | 3190 | ||
3438 | /* OUT transfers terminate when the data from the | 3191 | /* OUT transfers terminate when the data from the |
3439 | * host is in our memory. Process whatever's done. | 3192 | * host is in our memory. Process whatever's done. |
@@ -3448,30 +3201,9 @@ static void handle_stat1_irqs(struct net2280 *dev, u32 stat) | |||
3448 | scan_dma_completions(ep); | 3201 | scan_dma_completions(ep); |
3449 | 3202 | ||
3450 | /* disable dma on inactive queues; else maybe restart */ | 3203 | /* disable dma on inactive queues; else maybe restart */ |
3451 | if (list_empty(&ep->queue)) { | 3204 | if (!list_empty(&ep->queue)) { |
3452 | if (use_dma_chaining) | ||
3453 | stop_dma(ep->dma); | ||
3454 | } else { | ||
3455 | tmp = readl(&dma->dmactl); | 3205 | tmp = readl(&dma->dmactl); |
3456 | if (!use_dma_chaining || (tmp & BIT(DMA_ENABLE)) == 0) | 3206 | restart_dma(ep); |
3457 | restart_dma(ep); | ||
3458 | else if (ep->is_in && use_dma_chaining) { | ||
3459 | struct net2280_request *req; | ||
3460 | __le32 dmacount; | ||
3461 | |||
3462 | /* the descriptor at the head of the chain | ||
3463 | * may still have VALID_BIT clear; that's | ||
3464 | * used to trigger changing DMA_FIFO_VALIDATE | ||
3465 | * (affects automagic zlp writes). | ||
3466 | */ | ||
3467 | req = list_entry(ep->queue.next, | ||
3468 | struct net2280_request, queue); | ||
3469 | dmacount = req->td->dmacount; | ||
3470 | dmacount &= cpu_to_le32(BIT(VALID_BIT) | | ||
3471 | DMA_BYTE_COUNT_MASK); | ||
3472 | if (dmacount && (dmacount & valid_bit) == 0) | ||
3473 | restart_dma(ep); | ||
3474 | } | ||
3475 | } | 3207 | } |
3476 | ep->irqs++; | 3208 | ep->irqs++; |
3477 | } | 3209 | } |
@@ -3556,7 +3288,7 @@ static void net2280_remove(struct pci_dev *pdev) | |||
3556 | } | 3288 | } |
3557 | if (dev->got_irq) | 3289 | if (dev->got_irq) |
3558 | free_irq(pdev->irq, dev); | 3290 | free_irq(pdev->irq, dev); |
3559 | if (use_msi && dev->quirks & PLX_SUPERSPEED) | 3291 | if (dev->quirks & PLX_SUPERSPEED) |
3560 | pci_disable_msi(pdev); | 3292 | pci_disable_msi(pdev); |
3561 | if (dev->regs) | 3293 | if (dev->regs) |
3562 | iounmap(dev->regs); | 3294 | iounmap(dev->regs); |
@@ -3581,9 +3313,6 @@ static int net2280_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
3581 | void __iomem *base = NULL; | 3313 | void __iomem *base = NULL; |
3582 | int retval, i; | 3314 | int retval, i; |
3583 | 3315 | ||
3584 | if (!use_dma) | ||
3585 | use_dma_chaining = 0; | ||
3586 | |||
3587 | /* alloc, and start init */ | 3316 | /* alloc, and start init */ |
3588 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 3317 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
3589 | if (dev == NULL) { | 3318 | if (dev == NULL) { |
@@ -3663,9 +3392,12 @@ static int net2280_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
3663 | fsmvalue = get_idx_reg(dev->regs, SCRATCH) & | 3392 | fsmvalue = get_idx_reg(dev->regs, SCRATCH) & |
3664 | (0xf << DEFECT7374_FSM_FIELD); | 3393 | (0xf << DEFECT7374_FSM_FIELD); |
3665 | /* See if firmware needs to set up for workaround: */ | 3394 | /* See if firmware needs to set up for workaround: */ |
3666 | if (fsmvalue == DEFECT7374_FSM_SS_CONTROL_READ) | 3395 | if (fsmvalue == DEFECT7374_FSM_SS_CONTROL_READ) { |
3396 | dev->bug7734_patched = 1; | ||
3667 | writel(0, &dev->usb->usbctl); | 3397 | writel(0, &dev->usb->usbctl); |
3668 | } else{ | 3398 | } else |
3399 | dev->bug7734_patched = 0; | ||
3400 | } else { | ||
3669 | dev->enhanced_mode = 0; | 3401 | dev->enhanced_mode = 0; |
3670 | dev->n_ep = 7; | 3402 | dev->n_ep = 7; |
3671 | /* put into initial config, link up all endpoints */ | 3403 | /* put into initial config, link up all endpoints */ |
@@ -3682,7 +3414,7 @@ static int net2280_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
3682 | goto done; | 3414 | goto done; |
3683 | } | 3415 | } |
3684 | 3416 | ||
3685 | if (use_msi && (dev->quirks & PLX_SUPERSPEED)) | 3417 | if (dev->quirks & PLX_SUPERSPEED) |
3686 | if (pci_enable_msi(pdev)) | 3418 | if (pci_enable_msi(pdev)) |
3687 | ep_err(dev, "Failed to enable MSI mode\n"); | 3419 | ep_err(dev, "Failed to enable MSI mode\n"); |
3688 | 3420 | ||
@@ -3741,9 +3473,7 @@ static int net2280_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
3741 | ep_info(dev, "%s\n", driver_desc); | 3473 | ep_info(dev, "%s\n", driver_desc); |
3742 | ep_info(dev, "irq %d, pci mem %p, chip rev %04x\n", | 3474 | ep_info(dev, "irq %d, pci mem %p, chip rev %04x\n", |
3743 | pdev->irq, base, dev->chiprev); | 3475 | pdev->irq, base, dev->chiprev); |
3744 | ep_info(dev, "version: " DRIVER_VERSION "; dma %s %s\n", | 3476 | ep_info(dev, "version: " DRIVER_VERSION "; %s\n", |
3745 | use_dma ? (use_dma_chaining ? "chaining" : "enabled") | ||
3746 | : "disabled", | ||
3747 | dev->enhanced_mode ? "enhanced mode" : "legacy mode"); | 3477 | dev->enhanced_mode ? "enhanced mode" : "legacy mode"); |
3748 | retval = device_create_file(&pdev->dev, &dev_attr_registers); | 3478 | retval = device_create_file(&pdev->dev, &dev_attr_registers); |
3749 | if (retval) | 3479 | if (retval) |
@@ -3776,9 +3506,6 @@ static void net2280_shutdown(struct pci_dev *pdev) | |||
3776 | /* disable the pullup so the host will think we're gone */ | 3506 | /* disable the pullup so the host will think we're gone */ |
3777 | writel(0, &dev->usb->usbctl); | 3507 | writel(0, &dev->usb->usbctl); |
3778 | 3508 | ||
3779 | /* Disable full-speed test mode */ | ||
3780 | if (dev->quirks & PLX_LEGACY) | ||
3781 | writel(0, &dev->usb->xcvrdiag); | ||
3782 | } | 3509 | } |
3783 | 3510 | ||
3784 | 3511 | ||
diff --git a/drivers/usb/gadget/udc/net2280.h b/drivers/usb/gadget/udc/net2280.h index 03f15242d794..ac8d5a20a378 100644 --- a/drivers/usb/gadget/udc/net2280.h +++ b/drivers/usb/gadget/udc/net2280.h | |||
@@ -100,7 +100,6 @@ struct net2280_ep { | |||
100 | dma_addr_t td_dma; /* of dummy */ | 100 | dma_addr_t td_dma; /* of dummy */ |
101 | struct net2280 *dev; | 101 | struct net2280 *dev; |
102 | unsigned long irqs; | 102 | unsigned long irqs; |
103 | unsigned is_halt:1, dma_started:1; | ||
104 | 103 | ||
105 | /* analogous to a host-side qh */ | 104 | /* analogous to a host-side qh */ |
106 | struct list_head queue; | 105 | struct list_head queue; |
@@ -126,7 +125,7 @@ static inline void allow_status(struct net2280_ep *ep) | |||
126 | ep->stopped = 1; | 125 | ep->stopped = 1; |
127 | } | 126 | } |
128 | 127 | ||
129 | static void allow_status_338x(struct net2280_ep *ep) | 128 | static inline void allow_status_338x(struct net2280_ep *ep) |
130 | { | 129 | { |
131 | /* | 130 | /* |
132 | * Control Status Phase Handshake was set by the chip when the setup | 131 | * Control Status Phase Handshake was set by the chip when the setup |
@@ -165,8 +164,8 @@ struct net2280 { | |||
165 | u2_enable:1, | 164 | u2_enable:1, |
166 | ltm_enable:1, | 165 | ltm_enable:1, |
167 | wakeup_enable:1, | 166 | wakeup_enable:1, |
168 | selfpowered:1, | 167 | addressed_state:1, |
169 | addressed_state:1; | 168 | bug7734_patched:1; |
170 | u16 chiprev; | 169 | u16 chiprev; |
171 | int enhanced_mode; | 170 | int enhanced_mode; |
172 | int n_ep; | 171 | int n_ep; |
@@ -356,23 +355,6 @@ static inline void start_out_naking(struct net2280_ep *ep) | |||
356 | readl(&ep->regs->ep_rsp); | 355 | readl(&ep->regs->ep_rsp); |
357 | } | 356 | } |
358 | 357 | ||
359 | #ifdef DEBUG | ||
360 | static inline void assert_out_naking(struct net2280_ep *ep, const char *where) | ||
361 | { | ||
362 | u32 tmp = readl(&ep->regs->ep_stat); | ||
363 | |||
364 | if ((tmp & BIT(NAK_OUT_PACKETS)) == 0) { | ||
365 | ep_dbg(ep->dev, "%s %s %08x !NAK\n", | ||
366 | ep->ep.name, where, tmp); | ||
367 | writel(BIT(SET_NAK_OUT_PACKETS), | ||
368 | &ep->regs->ep_rsp); | ||
369 | } | ||
370 | } | ||
371 | #define ASSERT_OUT_NAKING(ep) assert_out_naking(ep, __func__) | ||
372 | #else | ||
373 | #define ASSERT_OUT_NAKING(ep) do {} while (0) | ||
374 | #endif | ||
375 | |||
376 | static inline void stop_out_naking(struct net2280_ep *ep) | 358 | static inline void stop_out_naking(struct net2280_ep *ep) |
377 | { | 359 | { |
378 | u32 tmp; | 360 | u32 tmp; |
diff --git a/drivers/usb/gadget/udc/omap_udc.c b/drivers/usb/gadget/udc/omap_udc.c index 288c087220a8..e2fcdb8e5596 100644 --- a/drivers/usb/gadget/udc/omap_udc.c +++ b/drivers/usb/gadget/udc/omap_udc.c | |||
@@ -1171,6 +1171,7 @@ omap_set_selfpowered(struct usb_gadget *gadget, int is_selfpowered) | |||
1171 | unsigned long flags; | 1171 | unsigned long flags; |
1172 | u16 syscon1; | 1172 | u16 syscon1; |
1173 | 1173 | ||
1174 | gadget->is_selfpowered = (is_selfpowered != 0); | ||
1174 | udc = container_of(gadget, struct omap_udc, gadget); | 1175 | udc = container_of(gadget, struct omap_udc, gadget); |
1175 | spin_lock_irqsave(&udc->lock, flags); | 1176 | spin_lock_irqsave(&udc->lock, flags); |
1176 | syscon1 = omap_readw(UDC_SYSCON1); | 1177 | syscon1 = omap_readw(UDC_SYSCON1); |
diff --git a/drivers/usb/gadget/udc/pch_udc.c b/drivers/usb/gadget/udc/pch_udc.c index 1c7379ac2379..613547f07828 100644 --- a/drivers/usb/gadget/udc/pch_udc.c +++ b/drivers/usb/gadget/udc/pch_udc.c | |||
@@ -1161,6 +1161,7 @@ static int pch_udc_pcd_selfpowered(struct usb_gadget *gadget, int value) | |||
1161 | 1161 | ||
1162 | if (!gadget) | 1162 | if (!gadget) |
1163 | return -EINVAL; | 1163 | return -EINVAL; |
1164 | gadget->is_selfpowered = (value != 0); | ||
1164 | dev = container_of(gadget, struct pch_udc_dev, gadget); | 1165 | dev = container_of(gadget, struct pch_udc_dev, gadget); |
1165 | if (value) | 1166 | if (value) |
1166 | pch_udc_set_selfpowered(dev); | 1167 | pch_udc_set_selfpowered(dev); |
diff --git a/drivers/usb/gadget/udc/pxa25x_udc.c b/drivers/usb/gadget/udc/pxa25x_udc.c index 8550b2d5db32..f6cbe667ce39 100644 --- a/drivers/usb/gadget/udc/pxa25x_udc.c +++ b/drivers/usb/gadget/udc/pxa25x_udc.c | |||
@@ -1272,7 +1272,6 @@ static int pxa25x_udc_start(struct usb_gadget *g, | |||
1272 | goto bind_fail; | 1272 | goto bind_fail; |
1273 | } | 1273 | } |
1274 | 1274 | ||
1275 | pullup(dev); | ||
1276 | dump_state(dev); | 1275 | dump_state(dev); |
1277 | return 0; | 1276 | return 0; |
1278 | bind_fail: | 1277 | bind_fail: |
@@ -1339,7 +1338,6 @@ static int pxa25x_udc_stop(struct usb_gadget*g) | |||
1339 | 1338 | ||
1340 | local_irq_disable(); | 1339 | local_irq_disable(); |
1341 | dev->pullup = 0; | 1340 | dev->pullup = 0; |
1342 | pullup(dev); | ||
1343 | stop_activity(dev, NULL); | 1341 | stop_activity(dev, NULL); |
1344 | local_irq_enable(); | 1342 | local_irq_enable(); |
1345 | 1343 | ||
diff --git a/drivers/usb/gadget/udc/pxa27x_udc.c b/drivers/usb/gadget/udc/pxa27x_udc.c index c61a896061fa..6a855fc9bd84 100644 --- a/drivers/usb/gadget/udc/pxa27x_udc.c +++ b/drivers/usb/gadget/udc/pxa27x_udc.c | |||
@@ -1809,7 +1809,6 @@ static int pxa27x_udc_start(struct usb_gadget *g, | |||
1809 | 1809 | ||
1810 | /* first hook up the driver ... */ | 1810 | /* first hook up the driver ... */ |
1811 | udc->driver = driver; | 1811 | udc->driver = driver; |
1812 | dplus_pullup(udc, 1); | ||
1813 | 1812 | ||
1814 | if (!IS_ERR_OR_NULL(udc->transceiver)) { | 1813 | if (!IS_ERR_OR_NULL(udc->transceiver)) { |
1815 | retval = otg_set_peripheral(udc->transceiver->otg, | 1814 | retval = otg_set_peripheral(udc->transceiver->otg, |
@@ -1862,7 +1861,6 @@ static int pxa27x_udc_stop(struct usb_gadget *g) | |||
1862 | 1861 | ||
1863 | stop_activity(udc, NULL); | 1862 | stop_activity(udc, NULL); |
1864 | udc_disable(udc); | 1863 | udc_disable(udc); |
1865 | dplus_pullup(udc, 0); | ||
1866 | 1864 | ||
1867 | udc->driver = NULL; | 1865 | udc->driver = NULL; |
1868 | 1866 | ||
diff --git a/drivers/usb/gadget/udc/r8a66597-udc.c b/drivers/usb/gadget/udc/r8a66597-udc.c index 06870da0b988..2495fe9c95c5 100644 --- a/drivers/usb/gadget/udc/r8a66597-udc.c +++ b/drivers/usb/gadget/udc/r8a66597-udc.c | |||
@@ -1803,6 +1803,7 @@ static int r8a66597_set_selfpowered(struct usb_gadget *gadget, int is_self) | |||
1803 | { | 1803 | { |
1804 | struct r8a66597 *r8a66597 = gadget_to_r8a66597(gadget); | 1804 | struct r8a66597 *r8a66597 = gadget_to_r8a66597(gadget); |
1805 | 1805 | ||
1806 | gadget->is_selfpowered = (is_self != 0); | ||
1806 | if (is_self) | 1807 | if (is_self) |
1807 | r8a66597->device_status |= 1 << USB_DEVICE_SELF_POWERED; | 1808 | r8a66597->device_status |= 1 << USB_DEVICE_SELF_POWERED; |
1808 | else | 1809 | else |
diff --git a/drivers/usb/gadget/udc/s3c2410_udc.c b/drivers/usb/gadget/udc/s3c2410_udc.c index 824cf12e9add..b808951491cc 100644 --- a/drivers/usb/gadget/udc/s3c2410_udc.c +++ b/drivers/usb/gadget/udc/s3c2410_udc.c | |||
@@ -238,14 +238,6 @@ static inline void s3c2410_udc_set_ep0_de_out(void __iomem *base) | |||
238 | S3C2410_UDC_EP0_CSR_REG); | 238 | S3C2410_UDC_EP0_CSR_REG); |
239 | } | 239 | } |
240 | 240 | ||
241 | static inline void s3c2410_udc_set_ep0_sse_out(void __iomem *base) | ||
242 | { | ||
243 | udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG); | ||
244 | udc_writeb(base, (S3C2410_UDC_EP0_CSR_SOPKTRDY | ||
245 | | S3C2410_UDC_EP0_CSR_SSE), | ||
246 | S3C2410_UDC_EP0_CSR_REG); | ||
247 | } | ||
248 | |||
249 | static inline void s3c2410_udc_set_ep0_de_in(void __iomem *base) | 241 | static inline void s3c2410_udc_set_ep0_de_in(void __iomem *base) |
250 | { | 242 | { |
251 | udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG); | 243 | udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG); |
@@ -291,18 +283,6 @@ static void s3c2410_udc_nuke(struct s3c2410_udc *udc, | |||
291 | } | 283 | } |
292 | } | 284 | } |
293 | 285 | ||
294 | static inline void s3c2410_udc_clear_ep_state(struct s3c2410_udc *dev) | ||
295 | { | ||
296 | unsigned i; | ||
297 | |||
298 | /* hardware SET_{CONFIGURATION,INTERFACE} automagic resets endpoint | ||
299 | * fifos, and pending transactions mustn't be continued in any case. | ||
300 | */ | ||
301 | |||
302 | for (i = 1; i < S3C2410_ENDPOINTS; i++) | ||
303 | s3c2410_udc_nuke(dev, &dev->ep[i], -ECONNABORTED); | ||
304 | } | ||
305 | |||
306 | static inline int s3c2410_udc_fifo_count_out(void) | 286 | static inline int s3c2410_udc_fifo_count_out(void) |
307 | { | 287 | { |
308 | int tmp; | 288 | int tmp; |
@@ -1454,6 +1434,7 @@ static int s3c2410_udc_set_selfpowered(struct usb_gadget *gadget, int value) | |||
1454 | 1434 | ||
1455 | dprintk(DEBUG_NORMAL, "%s()\n", __func__); | 1435 | dprintk(DEBUG_NORMAL, "%s()\n", __func__); |
1456 | 1436 | ||
1437 | gadget->is_selfpowered = (value != 0); | ||
1457 | if (value) | 1438 | if (value) |
1458 | udc->devstatus |= (1 << USB_DEVICE_SELF_POWERED); | 1439 | udc->devstatus |= (1 << USB_DEVICE_SELF_POWERED); |
1459 | else | 1440 | else |
diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c index e31d574d8860..5a81cb086b99 100644 --- a/drivers/usb/gadget/udc/udc-core.c +++ b/drivers/usb/gadget/udc/udc-core.c | |||
@@ -564,6 +564,7 @@ static USB_UDC_ATTR(is_a_peripheral); | |||
564 | static USB_UDC_ATTR(b_hnp_enable); | 564 | static USB_UDC_ATTR(b_hnp_enable); |
565 | static USB_UDC_ATTR(a_hnp_support); | 565 | static USB_UDC_ATTR(a_hnp_support); |
566 | static USB_UDC_ATTR(a_alt_hnp_support); | 566 | static USB_UDC_ATTR(a_alt_hnp_support); |
567 | static USB_UDC_ATTR(is_selfpowered); | ||
567 | 568 | ||
568 | static struct attribute *usb_udc_attrs[] = { | 569 | static struct attribute *usb_udc_attrs[] = { |
569 | &dev_attr_srp.attr, | 570 | &dev_attr_srp.attr, |
@@ -577,6 +578,7 @@ static struct attribute *usb_udc_attrs[] = { | |||
577 | &dev_attr_b_hnp_enable.attr, | 578 | &dev_attr_b_hnp_enable.attr, |
578 | &dev_attr_a_hnp_support.attr, | 579 | &dev_attr_a_hnp_support.attr, |
579 | &dev_attr_a_alt_hnp_support.attr, | 580 | &dev_attr_a_alt_hnp_support.attr, |
581 | &dev_attr_is_selfpowered.attr, | ||
580 | NULL, | 582 | NULL, |
581 | }; | 583 | }; |
582 | 584 | ||
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index fafc628480e0..5ad60e46dc2b 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -219,7 +219,7 @@ config USB_EHCI_TEGRA | |||
219 | 219 | ||
220 | config USB_EHCI_HCD_PPC_OF | 220 | config USB_EHCI_HCD_PPC_OF |
221 | bool "EHCI support for PPC USB controller on OF platform bus" | 221 | bool "EHCI support for PPC USB controller on OF platform bus" |
222 | depends on PPC_OF | 222 | depends on PPC |
223 | default y | 223 | default y |
224 | ---help--- | 224 | ---help--- |
225 | Enables support for the USB controller present on the PowerPC | 225 | Enables support for the USB controller present on the PowerPC |
@@ -331,20 +331,6 @@ config USB_ISP116X_HCD | |||
331 | To compile this driver as a module, choose M here: the | 331 | To compile this driver as a module, choose M here: the |
332 | module will be called isp116x-hcd. | 332 | module will be called isp116x-hcd. |
333 | 333 | ||
334 | config USB_ISP1760_HCD | ||
335 | tristate "ISP 1760 HCD support" | ||
336 | ---help--- | ||
337 | The ISP1760 chip is a USB 2.0 host controller. | ||
338 | |||
339 | This driver does not support isochronous transfers or OTG. | ||
340 | This USB controller is usually attached to a non-DMA-Master | ||
341 | capable bus. NXP's eval kit brings this chip on PCI card | ||
342 | where the chip itself is behind a PLB to simulate such | ||
343 | a bus. | ||
344 | |||
345 | To compile this driver as a module, choose M here: the | ||
346 | module will be called isp1760. | ||
347 | |||
348 | config USB_ISP1362_HCD | 334 | config USB_ISP1362_HCD |
349 | tristate "ISP1362 HCD support" | 335 | tristate "ISP1362 HCD support" |
350 | ---help--- | 336 | ---help--- |
@@ -494,7 +480,7 @@ config USB_OHCI_ATH79 | |||
494 | 480 | ||
495 | config USB_OHCI_HCD_PPC_OF_BE | 481 | config USB_OHCI_HCD_PPC_OF_BE |
496 | bool "OHCI support for OF platform bus (big endian)" | 482 | bool "OHCI support for OF platform bus (big endian)" |
497 | depends on PPC_OF | 483 | depends on PPC |
498 | select USB_OHCI_BIG_ENDIAN_DESC | 484 | select USB_OHCI_BIG_ENDIAN_DESC |
499 | select USB_OHCI_BIG_ENDIAN_MMIO | 485 | select USB_OHCI_BIG_ENDIAN_MMIO |
500 | ---help--- | 486 | ---help--- |
@@ -503,7 +489,7 @@ config USB_OHCI_HCD_PPC_OF_BE | |||
503 | 489 | ||
504 | config USB_OHCI_HCD_PPC_OF_LE | 490 | config USB_OHCI_HCD_PPC_OF_LE |
505 | bool "OHCI support for OF platform bus (little endian)" | 491 | bool "OHCI support for OF platform bus (little endian)" |
506 | depends on PPC_OF | 492 | depends on PPC |
507 | select USB_OHCI_LITTLE_ENDIAN | 493 | select USB_OHCI_LITTLE_ENDIAN |
508 | ---help--- | 494 | ---help--- |
509 | Enables support for little-endian USB controllers present on the | 495 | Enables support for little-endian USB controllers present on the |
@@ -511,7 +497,7 @@ config USB_OHCI_HCD_PPC_OF_LE | |||
511 | 497 | ||
512 | config USB_OHCI_HCD_PPC_OF | 498 | config USB_OHCI_HCD_PPC_OF |
513 | bool | 499 | bool |
514 | depends on PPC_OF | 500 | depends on PPC |
515 | default USB_OHCI_HCD_PPC_OF_BE || USB_OHCI_HCD_PPC_OF_LE | 501 | default USB_OHCI_HCD_PPC_OF_BE || USB_OHCI_HCD_PPC_OF_LE |
516 | 502 | ||
517 | config USB_OHCI_HCD_PCI | 503 | config USB_OHCI_HCD_PCI |
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index d6216a493bab..65b0b6a58599 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile | |||
@@ -5,8 +5,6 @@ | |||
5 | # tell define_trace.h where to find the xhci trace header | 5 | # tell define_trace.h where to find the xhci trace header |
6 | CFLAGS_xhci-trace.o := -I$(src) | 6 | CFLAGS_xhci-trace.o := -I$(src) |
7 | 7 | ||
8 | isp1760-y := isp1760-hcd.o isp1760-if.o | ||
9 | |||
10 | fhci-y := fhci-hcd.o fhci-hub.o fhci-q.o | 8 | fhci-y := fhci-hcd.o fhci-hub.o fhci-q.o |
11 | fhci-y += fhci-mem.o fhci-tds.o fhci-sched.o | 9 | fhci-y += fhci-mem.o fhci-tds.o fhci-sched.o |
12 | 10 | ||
@@ -69,7 +67,6 @@ obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o | |||
69 | obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o | 67 | obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o |
70 | obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o | 68 | obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o |
71 | obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o | 69 | obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o |
72 | obj-$(CONFIG_USB_ISP1760_HCD) += isp1760.o | ||
73 | obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o | 70 | obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o |
74 | obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o | 71 | obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o |
75 | obj-$(CONFIG_USB_FSL_MPH_DR_OF) += fsl-mph-dr-of.o | 72 | obj-$(CONFIG_USB_FSL_MPH_DR_OF) += fsl-mph-dr-of.o |
diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c index 56a88506febe..663f7908b15c 100644 --- a/drivers/usb/host/ehci-atmel.c +++ b/drivers/usb/host/ehci-atmel.c | |||
@@ -27,44 +27,66 @@ | |||
27 | #define DRIVER_DESC "EHCI Atmel driver" | 27 | #define DRIVER_DESC "EHCI Atmel driver" |
28 | 28 | ||
29 | static const char hcd_name[] = "ehci-atmel"; | 29 | static const char hcd_name[] = "ehci-atmel"; |
30 | static struct hc_driver __read_mostly ehci_atmel_hc_driver; | ||
31 | 30 | ||
32 | /* interface and function clocks */ | 31 | /* interface and function clocks */ |
33 | static struct clk *iclk, *fclk, *uclk; | 32 | #define hcd_to_atmel_ehci_priv(h) \ |
34 | static int clocked; | 33 | ((struct atmel_ehci_priv *)hcd_to_ehci(h)->priv) |
34 | |||
35 | struct atmel_ehci_priv { | ||
36 | struct clk *iclk; | ||
37 | struct clk *fclk; | ||
38 | struct clk *uclk; | ||
39 | bool clocked; | ||
40 | }; | ||
41 | |||
42 | static struct hc_driver __read_mostly ehci_atmel_hc_driver; | ||
43 | |||
44 | static const struct ehci_driver_overrides ehci_atmel_drv_overrides __initconst = { | ||
45 | .extra_priv_size = sizeof(struct atmel_ehci_priv), | ||
46 | }; | ||
35 | 47 | ||
36 | /*-------------------------------------------------------------------------*/ | 48 | /*-------------------------------------------------------------------------*/ |
37 | 49 | ||
38 | static void atmel_start_clock(void) | 50 | static void atmel_start_clock(struct atmel_ehci_priv *atmel_ehci) |
39 | { | 51 | { |
52 | if (atmel_ehci->clocked) | ||
53 | return; | ||
40 | if (IS_ENABLED(CONFIG_COMMON_CLK)) { | 54 | if (IS_ENABLED(CONFIG_COMMON_CLK)) { |
41 | clk_set_rate(uclk, 48000000); | 55 | clk_set_rate(atmel_ehci->uclk, 48000000); |
42 | clk_prepare_enable(uclk); | 56 | clk_prepare_enable(atmel_ehci->uclk); |
43 | } | 57 | } |
44 | clk_prepare_enable(iclk); | 58 | clk_prepare_enable(atmel_ehci->iclk); |
45 | clk_prepare_enable(fclk); | 59 | clk_prepare_enable(atmel_ehci->fclk); |
46 | clocked = 1; | 60 | atmel_ehci->clocked = true; |
47 | } | 61 | } |
48 | 62 | ||
49 | static void atmel_stop_clock(void) | 63 | static void atmel_stop_clock(struct atmel_ehci_priv *atmel_ehci) |
50 | { | 64 | { |
51 | clk_disable_unprepare(fclk); | 65 | if (!atmel_ehci->clocked) |
52 | clk_disable_unprepare(iclk); | 66 | return; |
67 | clk_disable_unprepare(atmel_ehci->fclk); | ||
68 | clk_disable_unprepare(atmel_ehci->iclk); | ||
53 | if (IS_ENABLED(CONFIG_COMMON_CLK)) | 69 | if (IS_ENABLED(CONFIG_COMMON_CLK)) |
54 | clk_disable_unprepare(uclk); | 70 | clk_disable_unprepare(atmel_ehci->uclk); |
55 | clocked = 0; | 71 | atmel_ehci->clocked = false; |
56 | } | 72 | } |
57 | 73 | ||
58 | static void atmel_start_ehci(struct platform_device *pdev) | 74 | static void atmel_start_ehci(struct platform_device *pdev) |
59 | { | 75 | { |
76 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
77 | struct atmel_ehci_priv *atmel_ehci = hcd_to_atmel_ehci_priv(hcd); | ||
78 | |||
60 | dev_dbg(&pdev->dev, "start\n"); | 79 | dev_dbg(&pdev->dev, "start\n"); |
61 | atmel_start_clock(); | 80 | atmel_start_clock(atmel_ehci); |
62 | } | 81 | } |
63 | 82 | ||
64 | static void atmel_stop_ehci(struct platform_device *pdev) | 83 | static void atmel_stop_ehci(struct platform_device *pdev) |
65 | { | 84 | { |
85 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
86 | struct atmel_ehci_priv *atmel_ehci = hcd_to_atmel_ehci_priv(hcd); | ||
87 | |||
66 | dev_dbg(&pdev->dev, "stop\n"); | 88 | dev_dbg(&pdev->dev, "stop\n"); |
67 | atmel_stop_clock(); | 89 | atmel_stop_clock(atmel_ehci); |
68 | } | 90 | } |
69 | 91 | ||
70 | /*-------------------------------------------------------------------------*/ | 92 | /*-------------------------------------------------------------------------*/ |
@@ -75,6 +97,7 @@ static int ehci_atmel_drv_probe(struct platform_device *pdev) | |||
75 | const struct hc_driver *driver = &ehci_atmel_hc_driver; | 97 | const struct hc_driver *driver = &ehci_atmel_hc_driver; |
76 | struct resource *res; | 98 | struct resource *res; |
77 | struct ehci_hcd *ehci; | 99 | struct ehci_hcd *ehci; |
100 | struct atmel_ehci_priv *atmel_ehci; | ||
78 | int irq; | 101 | int irq; |
79 | int retval; | 102 | int retval; |
80 | 103 | ||
@@ -105,6 +128,7 @@ static int ehci_atmel_drv_probe(struct platform_device *pdev) | |||
105 | retval = -ENOMEM; | 128 | retval = -ENOMEM; |
106 | goto fail_create_hcd; | 129 | goto fail_create_hcd; |
107 | } | 130 | } |
131 | atmel_ehci = hcd_to_atmel_ehci_priv(hcd); | ||
108 | 132 | ||
109 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 133 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
110 | hcd->regs = devm_ioremap_resource(&pdev->dev, res); | 134 | hcd->regs = devm_ioremap_resource(&pdev->dev, res); |
@@ -116,23 +140,23 @@ static int ehci_atmel_drv_probe(struct platform_device *pdev) | |||
116 | hcd->rsrc_start = res->start; | 140 | hcd->rsrc_start = res->start; |
117 | hcd->rsrc_len = resource_size(res); | 141 | hcd->rsrc_len = resource_size(res); |
118 | 142 | ||
119 | iclk = devm_clk_get(&pdev->dev, "ehci_clk"); | 143 | atmel_ehci->iclk = devm_clk_get(&pdev->dev, "ehci_clk"); |
120 | if (IS_ERR(iclk)) { | 144 | if (IS_ERR(atmel_ehci->iclk)) { |
121 | dev_err(&pdev->dev, "Error getting interface clock\n"); | 145 | dev_err(&pdev->dev, "Error getting interface clock\n"); |
122 | retval = -ENOENT; | 146 | retval = -ENOENT; |
123 | goto fail_request_resource; | 147 | goto fail_request_resource; |
124 | } | 148 | } |
125 | fclk = devm_clk_get(&pdev->dev, "uhpck"); | 149 | atmel_ehci->fclk = devm_clk_get(&pdev->dev, "uhpck"); |
126 | if (IS_ERR(fclk)) { | 150 | if (IS_ERR(atmel_ehci->fclk)) { |
127 | dev_err(&pdev->dev, "Error getting function clock\n"); | 151 | dev_err(&pdev->dev, "Error getting function clock\n"); |
128 | retval = -ENOENT; | 152 | retval = -ENOENT; |
129 | goto fail_request_resource; | 153 | goto fail_request_resource; |
130 | } | 154 | } |
131 | if (IS_ENABLED(CONFIG_COMMON_CLK)) { | 155 | if (IS_ENABLED(CONFIG_COMMON_CLK)) { |
132 | uclk = devm_clk_get(&pdev->dev, "usb_clk"); | 156 | atmel_ehci->uclk = devm_clk_get(&pdev->dev, "usb_clk"); |
133 | if (IS_ERR(uclk)) { | 157 | if (IS_ERR(atmel_ehci->uclk)) { |
134 | dev_err(&pdev->dev, "failed to get uclk\n"); | 158 | dev_err(&pdev->dev, "failed to get uclk\n"); |
135 | retval = PTR_ERR(uclk); | 159 | retval = PTR_ERR(atmel_ehci->uclk); |
136 | goto fail_request_resource; | 160 | goto fail_request_resource; |
137 | } | 161 | } |
138 | } | 162 | } |
@@ -169,11 +193,35 @@ static int ehci_atmel_drv_remove(struct platform_device *pdev) | |||
169 | usb_put_hcd(hcd); | 193 | usb_put_hcd(hcd); |
170 | 194 | ||
171 | atmel_stop_ehci(pdev); | 195 | atmel_stop_ehci(pdev); |
172 | fclk = iclk = NULL; | ||
173 | 196 | ||
174 | return 0; | 197 | return 0; |
175 | } | 198 | } |
176 | 199 | ||
200 | #ifdef CONFIG_PM | ||
201 | static int ehci_atmel_drv_suspend(struct device *dev) | ||
202 | { | ||
203 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
204 | struct atmel_ehci_priv *atmel_ehci = hcd_to_atmel_ehci_priv(hcd); | ||
205 | int ret; | ||
206 | |||
207 | ret = ehci_suspend(hcd, false); | ||
208 | if (ret) | ||
209 | return ret; | ||
210 | |||
211 | atmel_stop_clock(atmel_ehci); | ||
212 | return 0; | ||
213 | } | ||
214 | |||
215 | static int ehci_atmel_drv_resume(struct device *dev) | ||
216 | { | ||
217 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
218 | struct atmel_ehci_priv *atmel_ehci = hcd_to_atmel_ehci_priv(hcd); | ||
219 | |||
220 | atmel_start_clock(atmel_ehci); | ||
221 | return ehci_resume(hcd, false); | ||
222 | } | ||
223 | #endif | ||
224 | |||
177 | #ifdef CONFIG_OF | 225 | #ifdef CONFIG_OF |
178 | static const struct of_device_id atmel_ehci_dt_ids[] = { | 226 | static const struct of_device_id atmel_ehci_dt_ids[] = { |
179 | { .compatible = "atmel,at91sam9g45-ehci" }, | 227 | { .compatible = "atmel,at91sam9g45-ehci" }, |
@@ -183,12 +231,16 @@ static const struct of_device_id atmel_ehci_dt_ids[] = { | |||
183 | MODULE_DEVICE_TABLE(of, atmel_ehci_dt_ids); | 231 | MODULE_DEVICE_TABLE(of, atmel_ehci_dt_ids); |
184 | #endif | 232 | #endif |
185 | 233 | ||
234 | static SIMPLE_DEV_PM_OPS(ehci_atmel_pm_ops, ehci_atmel_drv_suspend, | ||
235 | ehci_atmel_drv_resume); | ||
236 | |||
186 | static struct platform_driver ehci_atmel_driver = { | 237 | static struct platform_driver ehci_atmel_driver = { |
187 | .probe = ehci_atmel_drv_probe, | 238 | .probe = ehci_atmel_drv_probe, |
188 | .remove = ehci_atmel_drv_remove, | 239 | .remove = ehci_atmel_drv_remove, |
189 | .shutdown = usb_hcd_platform_shutdown, | 240 | .shutdown = usb_hcd_platform_shutdown, |
190 | .driver = { | 241 | .driver = { |
191 | .name = "atmel-ehci", | 242 | .name = "atmel-ehci", |
243 | .pm = &ehci_atmel_pm_ops, | ||
192 | .of_match_table = of_match_ptr(atmel_ehci_dt_ids), | 244 | .of_match_table = of_match_ptr(atmel_ehci_dt_ids), |
193 | }, | 245 | }, |
194 | }; | 246 | }; |
@@ -199,7 +251,7 @@ static int __init ehci_atmel_init(void) | |||
199 | return -ENODEV; | 251 | return -ENODEV; |
200 | 252 | ||
201 | pr_info("%s: " DRIVER_DESC "\n", hcd_name); | 253 | pr_info("%s: " DRIVER_DESC "\n", hcd_name); |
202 | ehci_init_driver(&ehci_atmel_hc_driver, NULL); | 254 | ehci_init_driver(&ehci_atmel_hc_driver, &ehci_atmel_drv_overrides); |
203 | return platform_driver_register(&ehci_atmel_driver); | 255 | return platform_driver_register(&ehci_atmel_driver); |
204 | } | 256 | } |
205 | module_init(ehci_atmel_init); | 257 | module_init(ehci_atmel_init); |
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index fb7bd0c7dc15..ab4eee3df97a 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c | |||
@@ -709,7 +709,6 @@ static struct platform_driver ehci_fsl_driver = { | |||
709 | .shutdown = usb_hcd_platform_shutdown, | 709 | .shutdown = usb_hcd_platform_shutdown, |
710 | .driver = { | 710 | .driver = { |
711 | .name = "fsl-ehci", | 711 | .name = "fsl-ehci", |
712 | .owner = THIS_MODULE, | ||
713 | .pm = EHCI_FSL_PM_OPS, | 712 | .pm = EHCI_FSL_PM_OPS, |
714 | }, | 713 | }, |
715 | }; | 714 | }; |
diff --git a/drivers/usb/host/ehci-grlib.c b/drivers/usb/host/ehci-grlib.c index 495b6fbcbcd9..21650044b09e 100644 --- a/drivers/usb/host/ehci-grlib.c +++ b/drivers/usb/host/ehci-grlib.c | |||
@@ -187,7 +187,6 @@ static struct platform_driver ehci_grlib_driver = { | |||
187 | .shutdown = usb_hcd_platform_shutdown, | 187 | .shutdown = usb_hcd_platform_shutdown, |
188 | .driver = { | 188 | .driver = { |
189 | .name = "grlib-ehci", | 189 | .name = "grlib-ehci", |
190 | .owner = THIS_MODULE, | ||
191 | .of_match_table = ehci_hcd_grlib_of_match, | 190 | .of_match_table = ehci_hcd_grlib_of_match, |
192 | }, | 191 | }, |
193 | }; | 192 | }; |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 38bfeedae1d0..85e56d1abd23 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -1110,7 +1110,7 @@ int ehci_suspend(struct usb_hcd *hcd, bool do_wakeup) | |||
1110 | EXPORT_SYMBOL_GPL(ehci_suspend); | 1110 | EXPORT_SYMBOL_GPL(ehci_suspend); |
1111 | 1111 | ||
1112 | /* Returns 0 if power was preserved, 1 if power was lost */ | 1112 | /* Returns 0 if power was preserved, 1 if power was lost */ |
1113 | int ehci_resume(struct usb_hcd *hcd, bool hibernated) | 1113 | int ehci_resume(struct usb_hcd *hcd, bool force_reset) |
1114 | { | 1114 | { |
1115 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | 1115 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
1116 | 1116 | ||
@@ -1124,12 +1124,12 @@ int ehci_resume(struct usb_hcd *hcd, bool hibernated) | |||
1124 | return 0; /* Controller is dead */ | 1124 | return 0; /* Controller is dead */ |
1125 | 1125 | ||
1126 | /* | 1126 | /* |
1127 | * If CF is still set and we aren't resuming from hibernation | 1127 | * If CF is still set and reset isn't forced |
1128 | * then we maintained suspend power. | 1128 | * then we maintained suspend power. |
1129 | * Just undo the effect of ehci_suspend(). | 1129 | * Just undo the effect of ehci_suspend(). |
1130 | */ | 1130 | */ |
1131 | if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF && | 1131 | if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF && |
1132 | !hibernated) { | 1132 | !force_reset) { |
1133 | int mask = INTR_MASK; | 1133 | int mask = INTR_MASK; |
1134 | 1134 | ||
1135 | ehci_prepare_ports_for_controller_resume(ehci); | 1135 | ehci_prepare_ports_for_controller_resume(ehci); |
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 118edb7bdca2..87cf86f38b36 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
@@ -700,15 +700,15 @@ ehci_hub_descriptor ( | |||
700 | memset(&desc->u.hs.DeviceRemovable[0], 0, temp); | 700 | memset(&desc->u.hs.DeviceRemovable[0], 0, temp); |
701 | memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp); | 701 | memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp); |
702 | 702 | ||
703 | temp = 0x0008; /* per-port overcurrent reporting */ | 703 | temp = HUB_CHAR_INDV_PORT_OCPM; /* per-port overcurrent reporting */ |
704 | if (HCS_PPC (ehci->hcs_params)) | 704 | if (HCS_PPC (ehci->hcs_params)) |
705 | temp |= 0x0001; /* per-port power control */ | 705 | temp |= HUB_CHAR_INDV_PORT_LPSM; /* per-port power control */ |
706 | else | 706 | else |
707 | temp |= 0x0002; /* no power switching */ | 707 | temp |= HUB_CHAR_NO_LPSM; /* no power switching */ |
708 | #if 0 | 708 | #if 0 |
709 | // re-enable when we support USB_PORT_FEAT_INDICATOR below. | 709 | // re-enable when we support USB_PORT_FEAT_INDICATOR below. |
710 | if (HCS_INDICATOR (ehci->hcs_params)) | 710 | if (HCS_INDICATOR (ehci->hcs_params)) |
711 | temp |= 0x0080; /* per-port indicators (LEDs) */ | 711 | temp |= HUB_CHAR_PORTIND; /* per-port indicators (LEDs) */ |
712 | #endif | 712 | #endif |
713 | desc->wHubCharacteristics = cpu_to_le16(temp); | 713 | desc->wHubCharacteristics = cpu_to_le16(temp); |
714 | } | 714 | } |
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 851006a0d97b..2a5d2fd76040 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c | |||
@@ -43,6 +43,24 @@ static inline bool is_intel_quark_x1000(struct pci_dev *pdev) | |||
43 | } | 43 | } |
44 | 44 | ||
45 | /* | 45 | /* |
46 | * This is the list of PCI IDs for the devices that have EHCI USB class and | ||
47 | * specific drivers for that. One of the example is a ChipIdea device installed | ||
48 | * on some Intel MID platforms. | ||
49 | */ | ||
50 | static const struct pci_device_id bypass_pci_id_table[] = { | ||
51 | /* ChipIdea on Intel MID platform */ | ||
52 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0811), }, | ||
53 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0829), }, | ||
54 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe006), }, | ||
55 | {} | ||
56 | }; | ||
57 | |||
58 | static inline bool is_bypassed_id(struct pci_dev *pdev) | ||
59 | { | ||
60 | return !!pci_match_id(bypass_pci_id_table, pdev); | ||
61 | } | ||
62 | |||
63 | /* | ||
46 | * 0x84 is the offset of in/out threshold register, | 64 | * 0x84 is the offset of in/out threshold register, |
47 | * and it is the same offset as the register of 'hostpc'. | 65 | * and it is the same offset as the register of 'hostpc'. |
48 | */ | 66 | */ |
@@ -352,6 +370,13 @@ static const struct ehci_driver_overrides pci_overrides __initconst = { | |||
352 | 370 | ||
353 | /*-------------------------------------------------------------------------*/ | 371 | /*-------------------------------------------------------------------------*/ |
354 | 372 | ||
373 | static int ehci_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | ||
374 | { | ||
375 | if (is_bypassed_id(pdev)) | ||
376 | return -ENODEV; | ||
377 | return usb_hcd_pci_probe(pdev, id); | ||
378 | } | ||
379 | |||
355 | /* PCI driver selection metadata; PCI hotplugging uses this */ | 380 | /* PCI driver selection metadata; PCI hotplugging uses this */ |
356 | static const struct pci_device_id pci_ids [] = { { | 381 | static const struct pci_device_id pci_ids [] = { { |
357 | /* handle any USB 2.0 EHCI controller */ | 382 | /* handle any USB 2.0 EHCI controller */ |
@@ -370,7 +395,7 @@ static struct pci_driver ehci_pci_driver = { | |||
370 | .name = (char *) hcd_name, | 395 | .name = (char *) hcd_name, |
371 | .id_table = pci_ids, | 396 | .id_table = pci_ids, |
372 | 397 | ||
373 | .probe = usb_hcd_pci_probe, | 398 | .probe = ehci_pci_probe, |
374 | .remove = usb_hcd_pci_remove, | 399 | .remove = usb_hcd_pci_remove, |
375 | .shutdown = usb_hcd_pci_shutdown, | 400 | .shutdown = usb_hcd_pci_shutdown, |
376 | 401 | ||
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index 8557803e6154..d8a75a51d6d4 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c | |||
@@ -43,7 +43,8 @@ | |||
43 | struct ehci_platform_priv { | 43 | struct ehci_platform_priv { |
44 | struct clk *clks[EHCI_MAX_CLKS]; | 44 | struct clk *clks[EHCI_MAX_CLKS]; |
45 | struct reset_control *rst; | 45 | struct reset_control *rst; |
46 | struct phy *phy; | 46 | struct phy **phys; |
47 | int num_phys; | ||
47 | }; | 48 | }; |
48 | 49 | ||
49 | static const char hcd_name[] = "ehci-platform"; | 50 | static const char hcd_name[] = "ehci-platform"; |
@@ -78,7 +79,7 @@ static int ehci_platform_power_on(struct platform_device *dev) | |||
78 | { | 79 | { |
79 | struct usb_hcd *hcd = platform_get_drvdata(dev); | 80 | struct usb_hcd *hcd = platform_get_drvdata(dev); |
80 | struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd); | 81 | struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd); |
81 | int clk, ret; | 82 | int clk, ret, phy_num; |
82 | 83 | ||
83 | for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++) { | 84 | for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++) { |
84 | ret = clk_prepare_enable(priv->clks[clk]); | 85 | ret = clk_prepare_enable(priv->clks[clk]); |
@@ -86,20 +87,28 @@ static int ehci_platform_power_on(struct platform_device *dev) | |||
86 | goto err_disable_clks; | 87 | goto err_disable_clks; |
87 | } | 88 | } |
88 | 89 | ||
89 | if (priv->phy) { | 90 | for (phy_num = 0; phy_num < priv->num_phys; phy_num++) { |
90 | ret = phy_init(priv->phy); | 91 | if (priv->phys[phy_num]) { |
91 | if (ret) | 92 | ret = phy_init(priv->phys[phy_num]); |
92 | goto err_disable_clks; | 93 | if (ret) |
93 | 94 | goto err_exit_phy; | |
94 | ret = phy_power_on(priv->phy); | 95 | ret = phy_power_on(priv->phys[phy_num]); |
95 | if (ret) | 96 | if (ret) { |
96 | goto err_exit_phy; | 97 | phy_exit(priv->phys[phy_num]); |
98 | goto err_exit_phy; | ||
99 | } | ||
100 | } | ||
97 | } | 101 | } |
98 | 102 | ||
99 | return 0; | 103 | return 0; |
100 | 104 | ||
101 | err_exit_phy: | 105 | err_exit_phy: |
102 | phy_exit(priv->phy); | 106 | while (--phy_num >= 0) { |
107 | if (priv->phys[phy_num]) { | ||
108 | phy_power_off(priv->phys[phy_num]); | ||
109 | phy_exit(priv->phys[phy_num]); | ||
110 | } | ||
111 | } | ||
103 | err_disable_clks: | 112 | err_disable_clks: |
104 | while (--clk >= 0) | 113 | while (--clk >= 0) |
105 | clk_disable_unprepare(priv->clks[clk]); | 114 | clk_disable_unprepare(priv->clks[clk]); |
@@ -111,11 +120,13 @@ static void ehci_platform_power_off(struct platform_device *dev) | |||
111 | { | 120 | { |
112 | struct usb_hcd *hcd = platform_get_drvdata(dev); | 121 | struct usb_hcd *hcd = platform_get_drvdata(dev); |
113 | struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd); | 122 | struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd); |
114 | int clk; | 123 | int clk, phy_num; |
115 | 124 | ||
116 | if (priv->phy) { | 125 | for (phy_num = 0; phy_num < priv->num_phys; phy_num++) { |
117 | phy_power_off(priv->phy); | 126 | if (priv->phys[phy_num]) { |
118 | phy_exit(priv->phy); | 127 | phy_power_off(priv->phys[phy_num]); |
128 | phy_exit(priv->phys[phy_num]); | ||
129 | } | ||
119 | } | 130 | } |
120 | 131 | ||
121 | for (clk = EHCI_MAX_CLKS - 1; clk >= 0; clk--) | 132 | for (clk = EHCI_MAX_CLKS - 1; clk >= 0; clk--) |
@@ -143,7 +154,8 @@ static int ehci_platform_probe(struct platform_device *dev) | |||
143 | struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev); | 154 | struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev); |
144 | struct ehci_platform_priv *priv; | 155 | struct ehci_platform_priv *priv; |
145 | struct ehci_hcd *ehci; | 156 | struct ehci_hcd *ehci; |
146 | int err, irq, clk = 0; | 157 | const char *phy_name; |
158 | int err, irq, phy_num, clk = 0; | ||
147 | 159 | ||
148 | if (usb_disabled()) | 160 | if (usb_disabled()) |
149 | return -ENODEV; | 161 | return -ENODEV; |
@@ -155,7 +167,8 @@ static int ehci_platform_probe(struct platform_device *dev) | |||
155 | if (!pdata) | 167 | if (!pdata) |
156 | pdata = &ehci_platform_defaults; | 168 | pdata = &ehci_platform_defaults; |
157 | 169 | ||
158 | err = dma_coerce_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32)); | 170 | err = dma_coerce_mask_and_coherent(&dev->dev, |
171 | pdata->dma_mask_64 ? DMA_BIT_MASK(64) : DMA_BIT_MASK(32)); | ||
159 | if (err) | 172 | if (err) |
160 | return err; | 173 | return err; |
161 | 174 | ||
@@ -185,12 +198,42 @@ static int ehci_platform_probe(struct platform_device *dev) | |||
185 | if (of_property_read_bool(dev->dev.of_node, "big-endian")) | 198 | if (of_property_read_bool(dev->dev.of_node, "big-endian")) |
186 | ehci->big_endian_mmio = ehci->big_endian_desc = 1; | 199 | ehci->big_endian_mmio = ehci->big_endian_desc = 1; |
187 | 200 | ||
188 | priv->phy = devm_phy_get(&dev->dev, "usb"); | 201 | if (of_property_read_bool(dev->dev.of_node, |
189 | if (IS_ERR(priv->phy)) { | 202 | "needs-reset-on-resume")) |
190 | err = PTR_ERR(priv->phy); | 203 | pdata->reset_on_resume = 1; |
191 | if (err == -EPROBE_DEFER) | 204 | |
192 | goto err_put_hcd; | 205 | priv->num_phys = of_count_phandle_with_args(dev->dev.of_node, |
193 | priv->phy = NULL; | 206 | "phys", "#phy-cells"); |
207 | priv->num_phys = priv->num_phys > 0 ? priv->num_phys : 1; | ||
208 | |||
209 | priv->phys = devm_kcalloc(&dev->dev, priv->num_phys, | ||
210 | sizeof(struct phy *), GFP_KERNEL); | ||
211 | if (!priv->phys) | ||
212 | return -ENOMEM; | ||
213 | |||
214 | for (phy_num = 0; phy_num < priv->num_phys; phy_num++) { | ||
215 | err = of_property_read_string_index( | ||
216 | dev->dev.of_node, | ||
217 | "phy-names", phy_num, | ||
218 | &phy_name); | ||
219 | |||
220 | if (err < 0) { | ||
221 | if (priv->num_phys > 1) { | ||
222 | dev_err(&dev->dev, "phy-names not provided"); | ||
223 | goto err_put_hcd; | ||
224 | } else | ||
225 | phy_name = "usb"; | ||
226 | } | ||
227 | |||
228 | priv->phys[phy_num] = devm_phy_get(&dev->dev, | ||
229 | phy_name); | ||
230 | if (IS_ERR(priv->phys[phy_num])) { | ||
231 | err = PTR_ERR(priv->phys[phy_num]); | ||
232 | if ((priv->num_phys > 1) || | ||
233 | (err == -EPROBE_DEFER)) | ||
234 | goto err_put_hcd; | ||
235 | priv->phys[phy_num] = NULL; | ||
236 | } | ||
194 | } | 237 | } |
195 | 238 | ||
196 | for (clk = 0; clk < EHCI_MAX_CLKS; clk++) { | 239 | for (clk = 0; clk < EHCI_MAX_CLKS; clk++) { |
@@ -340,7 +383,7 @@ static int ehci_platform_resume(struct device *dev) | |||
340 | return err; | 383 | return err; |
341 | } | 384 | } |
342 | 385 | ||
343 | ehci_resume(hcd, false); | 386 | ehci_resume(hcd, pdata->reset_on_resume); |
344 | return 0; | 387 | return 0; |
345 | } | 388 | } |
346 | #endif /* CONFIG_PM_SLEEP */ | 389 | #endif /* CONFIG_PM_SLEEP */ |
@@ -349,6 +392,7 @@ static const struct of_device_id vt8500_ehci_ids[] = { | |||
349 | { .compatible = "via,vt8500-ehci", }, | 392 | { .compatible = "via,vt8500-ehci", }, |
350 | { .compatible = "wm,prizm-ehci", }, | 393 | { .compatible = "wm,prizm-ehci", }, |
351 | { .compatible = "generic-ehci", }, | 394 | { .compatible = "generic-ehci", }, |
395 | { .compatible = "cavium,octeon-6335-ehci", }, | ||
352 | {} | 396 | {} |
353 | }; | 397 | }; |
354 | MODULE_DEVICE_TABLE(of, vt8500_ehci_ids); | 398 | MODULE_DEVICE_TABLE(of, vt8500_ehci_ids); |
diff --git a/drivers/usb/host/ehci-pmcmsp.c b/drivers/usb/host/ehci-pmcmsp.c index 7d75465d97c7..342816a7f8b1 100644 --- a/drivers/usb/host/ehci-pmcmsp.c +++ b/drivers/usb/host/ehci-pmcmsp.c | |||
@@ -325,6 +325,5 @@ static struct platform_driver ehci_hcd_msp_driver = { | |||
325 | .remove = ehci_hcd_msp_drv_remove, | 325 | .remove = ehci_hcd_msp_drv_remove, |
326 | .driver = { | 326 | .driver = { |
327 | .name = "pmcmsp-ehci", | 327 | .name = "pmcmsp-ehci", |
328 | .owner = THIS_MODULE, | ||
329 | }, | 328 | }, |
330 | }; | 329 | }; |
diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c index 547924796d29..1a10c8d542ca 100644 --- a/drivers/usb/host/ehci-ppc-of.c +++ b/drivers/usb/host/ehci-ppc-of.c | |||
@@ -234,7 +234,6 @@ static struct platform_driver ehci_hcd_ppc_of_driver = { | |||
234 | .shutdown = usb_hcd_platform_shutdown, | 234 | .shutdown = usb_hcd_platform_shutdown, |
235 | .driver = { | 235 | .driver = { |
236 | .name = "ppc-of-ehci", | 236 | .name = "ppc-of-ehci", |
237 | .owner = THIS_MODULE, | ||
238 | .of_match_table = ehci_hcd_ppc_of_match, | 237 | .of_match_table = ehci_hcd_ppc_of_match, |
239 | }, | 238 | }, |
240 | }; | 239 | }; |
diff --git a/drivers/usb/host/ehci-sead3.c b/drivers/usb/host/ehci-sead3.c index 9b6e8d0eac43..3d86cc2ffe68 100644 --- a/drivers/usb/host/ehci-sead3.c +++ b/drivers/usb/host/ehci-sead3.c | |||
@@ -178,7 +178,6 @@ static struct platform_driver ehci_hcd_sead3_driver = { | |||
178 | .shutdown = usb_hcd_platform_shutdown, | 178 | .shutdown = usb_hcd_platform_shutdown, |
179 | .driver = { | 179 | .driver = { |
180 | .name = "sead3-ehci", | 180 | .name = "sead3-ehci", |
181 | .owner = THIS_MODULE, | ||
182 | .pm = SEAD3_EHCI_PMOPS, | 181 | .pm = SEAD3_EHCI_PMOPS, |
183 | } | 182 | } |
184 | }; | 183 | }; |
diff --git a/drivers/usb/host/ehci-sh.c b/drivers/usb/host/ehci-sh.c index 0e0ce684aff3..5caf88d679e4 100644 --- a/drivers/usb/host/ehci-sh.c +++ b/drivers/usb/host/ehci-sh.c | |||
@@ -189,7 +189,6 @@ static struct platform_driver ehci_hcd_sh_driver = { | |||
189 | .shutdown = ehci_hcd_sh_shutdown, | 189 | .shutdown = ehci_hcd_sh_shutdown, |
190 | .driver = { | 190 | .driver = { |
191 | .name = "sh_ehci", | 191 | .name = "sh_ehci", |
192 | .owner = THIS_MODULE, | ||
193 | }, | 192 | }, |
194 | }; | 193 | }; |
195 | 194 | ||
diff --git a/drivers/usb/host/ehci-tilegx.c b/drivers/usb/host/ehci-tilegx.c index 0d247673c3ca..bdb93b6a356f 100644 --- a/drivers/usb/host/ehci-tilegx.c +++ b/drivers/usb/host/ehci-tilegx.c | |||
@@ -210,7 +210,6 @@ static struct platform_driver ehci_hcd_tilegx_driver = { | |||
210 | .shutdown = ehci_hcd_tilegx_drv_shutdown, | 210 | .shutdown = ehci_hcd_tilegx_drv_shutdown, |
211 | .driver = { | 211 | .driver = { |
212 | .name = "tilegx-ehci", | 212 | .name = "tilegx-ehci", |
213 | .owner = THIS_MODULE, | ||
214 | } | 213 | } |
215 | }; | 214 | }; |
216 | 215 | ||
diff --git a/drivers/usb/host/ehci-xilinx-of.c b/drivers/usb/host/ehci-xilinx-of.c index a2328361dc80..f54480850bb8 100644 --- a/drivers/usb/host/ehci-xilinx-of.c +++ b/drivers/usb/host/ehci-xilinx-of.c | |||
@@ -236,7 +236,6 @@ static struct platform_driver ehci_hcd_xilinx_of_driver = { | |||
236 | .shutdown = usb_hcd_platform_shutdown, | 236 | .shutdown = usb_hcd_platform_shutdown, |
237 | .driver = { | 237 | .driver = { |
238 | .name = "xilinx-of-ehci", | 238 | .name = "xilinx-of-ehci", |
239 | .owner = THIS_MODULE, | ||
240 | .of_match_table = ehci_hcd_xilinx_of_match, | 239 | .of_match_table = ehci_hcd_xilinx_of_match, |
241 | }, | 240 | }, |
242 | }; | 241 | }; |
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 6f0577b0a5ae..52ef0844a180 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
@@ -871,7 +871,7 @@ extern int ehci_handshake(struct ehci_hcd *ehci, void __iomem *ptr, | |||
871 | 871 | ||
872 | #ifdef CONFIG_PM | 872 | #ifdef CONFIG_PM |
873 | extern int ehci_suspend(struct usb_hcd *hcd, bool do_wakeup); | 873 | extern int ehci_suspend(struct usb_hcd *hcd, bool do_wakeup); |
874 | extern int ehci_resume(struct usb_hcd *hcd, bool hibernated); | 874 | extern int ehci_resume(struct usb_hcd *hcd, bool force_reset); |
875 | #endif /* CONFIG_PM */ | 875 | #endif /* CONFIG_PM */ |
876 | 876 | ||
877 | extern int ehci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | 877 | extern int ehci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, |
diff --git a/drivers/usb/host/fhci-hub.c b/drivers/usb/host/fhci-hub.c index 6af2512f8378..70116a65262c 100644 --- a/drivers/usb/host/fhci-hub.c +++ b/drivers/usb/host/fhci-hub.c | |||
@@ -32,8 +32,8 @@ static u8 root_hub_des[] = { | |||
32 | 0x09, /* blength */ | 32 | 0x09, /* blength */ |
33 | 0x29, /* bDescriptorType;hub-descriptor */ | 33 | 0x29, /* bDescriptorType;hub-descriptor */ |
34 | 0x01, /* bNbrPorts */ | 34 | 0x01, /* bNbrPorts */ |
35 | 0x00, /* wHubCharacteristics */ | 35 | HUB_CHAR_INDV_PORT_LPSM | HUB_CHAR_NO_OCPM, /* wHubCharacteristics */ |
36 | 0x00, | 36 | 0x00, /* per-port power, no overcurrent */ |
37 | 0x01, /* bPwrOn2pwrGood;2ms */ | 37 | 0x01, /* bPwrOn2pwrGood;2ms */ |
38 | 0x00, /* bHubContrCurrent;0mA */ | 38 | 0x00, /* bHubContrCurrent;0mA */ |
39 | 0x00, /* DeviceRemoveable */ | 39 | 0x00, /* DeviceRemoveable */ |
@@ -208,7 +208,6 @@ int fhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
208 | { | 208 | { |
209 | struct fhci_hcd *fhci = hcd_to_fhci(hcd); | 209 | struct fhci_hcd *fhci = hcd_to_fhci(hcd); |
210 | int retval = 0; | 210 | int retval = 0; |
211 | int len = 0; | ||
212 | struct usb_hub_status *hub_status; | 211 | struct usb_hub_status *hub_status; |
213 | struct usb_port_status *port_status; | 212 | struct usb_port_status *port_status; |
214 | unsigned long flags; | 213 | unsigned long flags; |
@@ -272,8 +271,6 @@ int fhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
272 | break; | 271 | break; |
273 | case GetHubDescriptor: | 272 | case GetHubDescriptor: |
274 | memcpy(buf, root_hub_des, sizeof(root_hub_des)); | 273 | memcpy(buf, root_hub_des, sizeof(root_hub_des)); |
275 | buf[3] = 0x11; /* per-port power, no ovrcrnt */ | ||
276 | len = (buf[0] < wLength) ? buf[0] : wLength; | ||
277 | break; | 274 | break; |
278 | case GetHubStatus: | 275 | case GetHubStatus: |
279 | hub_status = (struct usb_hub_status *)buf; | 276 | hub_status = (struct usb_hub_status *)buf; |
@@ -281,7 +278,6 @@ int fhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
281 | cpu_to_le16(fhci->vroot_hub->hub.wHubStatus); | 278 | cpu_to_le16(fhci->vroot_hub->hub.wHubStatus); |
282 | hub_status->wHubChange = | 279 | hub_status->wHubChange = |
283 | cpu_to_le16(fhci->vroot_hub->hub.wHubChange); | 280 | cpu_to_le16(fhci->vroot_hub->hub.wHubChange); |
284 | len = 4; | ||
285 | break; | 281 | break; |
286 | case GetPortStatus: | 282 | case GetPortStatus: |
287 | port_status = (struct usb_port_status *)buf; | 283 | port_status = (struct usb_port_status *)buf; |
@@ -289,7 +285,6 @@ int fhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
289 | cpu_to_le16(fhci->vroot_hub->port.wPortStatus); | 285 | cpu_to_le16(fhci->vroot_hub->port.wPortStatus); |
290 | port_status->wPortChange = | 286 | port_status->wPortChange = |
291 | cpu_to_le16(fhci->vroot_hub->port.wPortChange); | 287 | cpu_to_le16(fhci->vroot_hub->port.wPortChange); |
292 | len = 4; | ||
293 | break; | 288 | break; |
294 | case SetHubFeature: | 289 | case SetHubFeature: |
295 | switch (wValue) { | 290 | switch (wValue) { |
diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c index ecf02b2623e8..475b21fd373b 100644 --- a/drivers/usb/host/fotg210-hcd.c +++ b/drivers/usb/host/fotg210-hcd.c | |||
@@ -1521,8 +1521,8 @@ fotg210_hub_descriptor( | |||
1521 | memset(&desc->u.hs.DeviceRemovable[0], 0, temp); | 1521 | memset(&desc->u.hs.DeviceRemovable[0], 0, temp); |
1522 | memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp); | 1522 | memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp); |
1523 | 1523 | ||
1524 | temp = 0x0008; /* per-port overcurrent reporting */ | 1524 | temp = HUB_CHAR_INDV_PORT_OCPM; /* per-port overcurrent reporting */ |
1525 | temp |= 0x0002; /* no power switching */ | 1525 | temp |= HUB_CHAR_NO_LPSM; /* no power switching */ |
1526 | desc->wHubCharacteristics = cpu_to_le16(temp); | 1526 | desc->wHubCharacteristics = cpu_to_le16(temp); |
1527 | } | 1527 | } |
1528 | 1528 | ||
diff --git a/drivers/usb/host/fusbh200-hcd.c b/drivers/usb/host/fusbh200-hcd.c index 664d2aa1239c..a83eefefffda 100644 --- a/drivers/usb/host/fusbh200-hcd.c +++ b/drivers/usb/host/fusbh200-hcd.c | |||
@@ -1479,8 +1479,8 @@ fusbh200_hub_descriptor ( | |||
1479 | memset(&desc->u.hs.DeviceRemovable[0], 0, temp); | 1479 | memset(&desc->u.hs.DeviceRemovable[0], 0, temp); |
1480 | memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp); | 1480 | memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp); |
1481 | 1481 | ||
1482 | temp = 0x0008; /* per-port overcurrent reporting */ | 1482 | temp = HUB_CHAR_INDV_PORT_OCPM; /* per-port overcurrent reporting */ |
1483 | temp |= 0x0002; /* no power switching */ | 1483 | temp |= HUB_CHAR_NO_LPSM; /* no power switching */ |
1484 | desc->wHubCharacteristics = cpu_to_le16(temp); | 1484 | desc->wHubCharacteristics = cpu_to_le16(temp); |
1485 | } | 1485 | } |
1486 | 1486 | ||
diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c index eb4efba9f1ad..6a2ad550b120 100644 --- a/drivers/usb/host/imx21-hcd.c +++ b/drivers/usb/host/imx21-hcd.c | |||
@@ -1482,9 +1482,8 @@ static int get_hub_descriptor(struct usb_hcd *hcd, | |||
1482 | desc->bDescLength = 9; | 1482 | desc->bDescLength = 9; |
1483 | desc->bPwrOn2PwrGood = 0; | 1483 | desc->bPwrOn2PwrGood = 0; |
1484 | desc->wHubCharacteristics = (__force __u16) cpu_to_le16( | 1484 | desc->wHubCharacteristics = (__force __u16) cpu_to_le16( |
1485 | 0x0002 | /* No power switching */ | 1485 | HUB_CHAR_NO_LPSM | /* No power switching */ |
1486 | 0x0010 | /* No over current protection */ | 1486 | HUB_CHAR_NO_OCPM); /* No over current protection */ |
1487 | 0); | ||
1488 | 1487 | ||
1489 | desc->u.hs.DeviceRemovable[0] = 1 << 1; | 1488 | desc->u.hs.DeviceRemovable[0] = 1 << 1; |
1490 | desc->u.hs.DeviceRemovable[1] = ~0; | 1489 | desc->u.hs.DeviceRemovable[1] = ~0; |
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 31c9c4d0fa0b..113d0cc6cc43 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c | |||
@@ -948,7 +948,10 @@ static void isp116x_hub_descriptor(struct isp116x *isp116x, | |||
948 | desc->bHubContrCurrent = 0; | 948 | desc->bHubContrCurrent = 0; |
949 | desc->bNbrPorts = (u8) (reg & 0x3); | 949 | desc->bNbrPorts = (u8) (reg & 0x3); |
950 | /* Power switching, device type, overcurrent. */ | 950 | /* Power switching, device type, overcurrent. */ |
951 | desc->wHubCharacteristics = cpu_to_le16((u16) ((reg >> 8) & 0x1f)); | 951 | desc->wHubCharacteristics = cpu_to_le16((u16) ((reg >> 8) & |
952 | (HUB_CHAR_LPSM | | ||
953 | HUB_CHAR_COMPOUND | | ||
954 | HUB_CHAR_OCPM))); | ||
952 | desc->bPwrOn2PwrGood = (u8) ((reg >> 24) & 0xff); | 955 | desc->bPwrOn2PwrGood = (u8) ((reg >> 24) & 0xff); |
953 | /* ports removable, and legacy PortPwrCtrlMask */ | 956 | /* ports removable, and legacy PortPwrCtrlMask */ |
954 | desc->u.hs.DeviceRemovable[0] = 0; | 957 | desc->u.hs.DeviceRemovable[0] = 0; |
diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c index 75e5876f9d7c..b32ab60cad1e 100644 --- a/drivers/usb/host/isp1362-hcd.c +++ b/drivers/usb/host/isp1362-hcd.c | |||
@@ -1543,8 +1543,12 @@ static void isp1362_hub_descriptor(struct isp1362_hcd *isp1362_hcd, | |||
1543 | desc->bHubContrCurrent = 0; | 1543 | desc->bHubContrCurrent = 0; |
1544 | desc->bNbrPorts = reg & 0x3; | 1544 | desc->bNbrPorts = reg & 0x3; |
1545 | /* Power switching, device type, overcurrent. */ | 1545 | /* Power switching, device type, overcurrent. */ |
1546 | desc->wHubCharacteristics = cpu_to_le16((reg >> 8) & 0x1f); | 1546 | desc->wHubCharacteristics = cpu_to_le16((reg >> 8) & |
1547 | DBG(0, "%s: hubcharacteristics = %02x\n", __func__, cpu_to_le16((reg >> 8) & 0x1f)); | 1547 | (HUB_CHAR_LPSM | |
1548 | HUB_CHAR_COMPOUND | | ||
1549 | HUB_CHAR_OCPM)); | ||
1550 | DBG(0, "%s: hubcharacteristics = %02x\n", __func__, | ||
1551 | desc->wHubCharacteristics); | ||
1548 | desc->bPwrOn2PwrGood = (reg >> 24) & 0xff; | 1552 | desc->bPwrOn2PwrGood = (reg >> 24) & 0xff; |
1549 | /* ports removable, and legacy PortPwrCtrlMask */ | 1553 | /* ports removable, and legacy PortPwrCtrlMask */ |
1550 | desc->u.hs.DeviceRemovable[0] = desc->bNbrPorts == 1 ? 1 << 1 : 3 << 1; | 1554 | desc->u.hs.DeviceRemovable[0] = desc->bNbrPorts == 1 ? 1 << 1 : 3 << 1; |
diff --git a/drivers/usb/host/isp1760-hcd.h b/drivers/usb/host/isp1760-hcd.h deleted file mode 100644 index 33dc79ccaa6b..000000000000 --- a/drivers/usb/host/isp1760-hcd.h +++ /dev/null | |||
@@ -1,208 +0,0 @@ | |||
1 | #ifndef _ISP1760_HCD_H_ | ||
2 | #define _ISP1760_HCD_H_ | ||
3 | |||
4 | /* exports for if */ | ||
5 | struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len, | ||
6 | int irq, unsigned long irqflags, | ||
7 | int rst_gpio, | ||
8 | struct device *dev, const char *busname, | ||
9 | unsigned int devflags); | ||
10 | int init_kmem_once(void); | ||
11 | void deinit_kmem_cache(void); | ||
12 | |||
13 | /* EHCI capability registers */ | ||
14 | #define HC_CAPLENGTH 0x00 | ||
15 | #define HC_HCSPARAMS 0x04 | ||
16 | #define HC_HCCPARAMS 0x08 | ||
17 | |||
18 | /* EHCI operational registers */ | ||
19 | #define HC_USBCMD 0x20 | ||
20 | #define HC_USBSTS 0x24 | ||
21 | #define HC_FRINDEX 0x2c | ||
22 | #define HC_CONFIGFLAG 0x60 | ||
23 | #define HC_PORTSC1 0x64 | ||
24 | #define HC_ISO_PTD_DONEMAP_REG 0x130 | ||
25 | #define HC_ISO_PTD_SKIPMAP_REG 0x134 | ||
26 | #define HC_ISO_PTD_LASTPTD_REG 0x138 | ||
27 | #define HC_INT_PTD_DONEMAP_REG 0x140 | ||
28 | #define HC_INT_PTD_SKIPMAP_REG 0x144 | ||
29 | #define HC_INT_PTD_LASTPTD_REG 0x148 | ||
30 | #define HC_ATL_PTD_DONEMAP_REG 0x150 | ||
31 | #define HC_ATL_PTD_SKIPMAP_REG 0x154 | ||
32 | #define HC_ATL_PTD_LASTPTD_REG 0x158 | ||
33 | |||
34 | /* Configuration Register */ | ||
35 | #define HC_HW_MODE_CTRL 0x300 | ||
36 | #define ALL_ATX_RESET (1 << 31) | ||
37 | #define HW_ANA_DIGI_OC (1 << 15) | ||
38 | #define HW_DATA_BUS_32BIT (1 << 8) | ||
39 | #define HW_DACK_POL_HIGH (1 << 6) | ||
40 | #define HW_DREQ_POL_HIGH (1 << 5) | ||
41 | #define HW_INTR_HIGH_ACT (1 << 2) | ||
42 | #define HW_INTR_EDGE_TRIG (1 << 1) | ||
43 | #define HW_GLOBAL_INTR_EN (1 << 0) | ||
44 | |||
45 | #define HC_CHIP_ID_REG 0x304 | ||
46 | #define HC_SCRATCH_REG 0x308 | ||
47 | |||
48 | #define HC_RESET_REG 0x30c | ||
49 | #define SW_RESET_RESET_HC (1 << 1) | ||
50 | #define SW_RESET_RESET_ALL (1 << 0) | ||
51 | |||
52 | #define HC_BUFFER_STATUS_REG 0x334 | ||
53 | #define ISO_BUF_FILL (1 << 2) | ||
54 | #define INT_BUF_FILL (1 << 1) | ||
55 | #define ATL_BUF_FILL (1 << 0) | ||
56 | |||
57 | #define HC_MEMORY_REG 0x33c | ||
58 | #define ISP_BANK(x) ((x) << 16) | ||
59 | |||
60 | #define HC_PORT1_CTRL 0x374 | ||
61 | #define PORT1_POWER (3 << 3) | ||
62 | #define PORT1_INIT1 (1 << 7) | ||
63 | #define PORT1_INIT2 (1 << 23) | ||
64 | #define HW_OTG_CTRL_SET 0x374 | ||
65 | #define HW_OTG_CTRL_CLR 0x376 | ||
66 | |||
67 | /* Interrupt Register */ | ||
68 | #define HC_INTERRUPT_REG 0x310 | ||
69 | |||
70 | #define HC_INTERRUPT_ENABLE 0x314 | ||
71 | #define HC_ISO_INT (1 << 9) | ||
72 | #define HC_ATL_INT (1 << 8) | ||
73 | #define HC_INTL_INT (1 << 7) | ||
74 | #define HC_EOT_INT (1 << 3) | ||
75 | #define HC_SOT_INT (1 << 1) | ||
76 | #define INTERRUPT_ENABLE_MASK (HC_INTL_INT | HC_ATL_INT) | ||
77 | |||
78 | #define HC_ISO_IRQ_MASK_OR_REG 0x318 | ||
79 | #define HC_INT_IRQ_MASK_OR_REG 0x31C | ||
80 | #define HC_ATL_IRQ_MASK_OR_REG 0x320 | ||
81 | #define HC_ISO_IRQ_MASK_AND_REG 0x324 | ||
82 | #define HC_INT_IRQ_MASK_AND_REG 0x328 | ||
83 | #define HC_ATL_IRQ_MASK_AND_REG 0x32C | ||
84 | |||
85 | /* urb state*/ | ||
86 | #define DELETE_URB (0x0008) | ||
87 | #define NO_TRANSFER_ACTIVE (0xffffffff) | ||
88 | |||
89 | /* Philips Proprietary Transfer Descriptor (PTD) */ | ||
90 | typedef __u32 __bitwise __dw; | ||
91 | struct ptd { | ||
92 | __dw dw0; | ||
93 | __dw dw1; | ||
94 | __dw dw2; | ||
95 | __dw dw3; | ||
96 | __dw dw4; | ||
97 | __dw dw5; | ||
98 | __dw dw6; | ||
99 | __dw dw7; | ||
100 | }; | ||
101 | #define PTD_OFFSET 0x0400 | ||
102 | #define ISO_PTD_OFFSET 0x0400 | ||
103 | #define INT_PTD_OFFSET 0x0800 | ||
104 | #define ATL_PTD_OFFSET 0x0c00 | ||
105 | #define PAYLOAD_OFFSET 0x1000 | ||
106 | |||
107 | struct slotinfo { | ||
108 | struct isp1760_qh *qh; | ||
109 | struct isp1760_qtd *qtd; | ||
110 | unsigned long timestamp; | ||
111 | }; | ||
112 | |||
113 | |||
114 | typedef void (packet_enqueue)(struct usb_hcd *hcd, struct isp1760_qh *qh, | ||
115 | struct isp1760_qtd *qtd); | ||
116 | |||
117 | /* | ||
118 | * Device flags that can vary from board to board. All of these | ||
119 | * indicate the most "atypical" case, so that a devflags of 0 is | ||
120 | * a sane default configuration. | ||
121 | */ | ||
122 | #define ISP1760_FLAG_BUS_WIDTH_16 0x00000002 /* 16-bit data bus width */ | ||
123 | #define ISP1760_FLAG_OTG_EN 0x00000004 /* Port 1 supports OTG */ | ||
124 | #define ISP1760_FLAG_ANALOG_OC 0x00000008 /* Analog overcurrent */ | ||
125 | #define ISP1760_FLAG_DACK_POL_HIGH 0x00000010 /* DACK active high */ | ||
126 | #define ISP1760_FLAG_DREQ_POL_HIGH 0x00000020 /* DREQ active high */ | ||
127 | #define ISP1760_FLAG_ISP1761 0x00000040 /* Chip is ISP1761 */ | ||
128 | #define ISP1760_FLAG_INTR_POL_HIGH 0x00000080 /* Interrupt polarity active high */ | ||
129 | #define ISP1760_FLAG_INTR_EDGE_TRIG 0x00000100 /* Interrupt edge triggered */ | ||
130 | #define ISP1760_FLAG_RESET_ACTIVE_HIGH 0x80000000 /* RESET GPIO active high */ | ||
131 | |||
132 | /* chip memory management */ | ||
133 | struct memory_chunk { | ||
134 | unsigned int start; | ||
135 | unsigned int size; | ||
136 | unsigned int free; | ||
137 | }; | ||
138 | |||
139 | /* | ||
140 | * 60kb divided in: | ||
141 | * - 32 blocks @ 256 bytes | ||
142 | * - 20 blocks @ 1024 bytes | ||
143 | * - 4 blocks @ 8192 bytes | ||
144 | */ | ||
145 | |||
146 | #define BLOCK_1_NUM 32 | ||
147 | #define BLOCK_2_NUM 20 | ||
148 | #define BLOCK_3_NUM 4 | ||
149 | |||
150 | #define BLOCK_1_SIZE 256 | ||
151 | #define BLOCK_2_SIZE 1024 | ||
152 | #define BLOCK_3_SIZE 8192 | ||
153 | #define BLOCKS (BLOCK_1_NUM + BLOCK_2_NUM + BLOCK_3_NUM) | ||
154 | #define MAX_PAYLOAD_SIZE BLOCK_3_SIZE | ||
155 | #define PAYLOAD_AREA_SIZE 0xf000 | ||
156 | |||
157 | /* ATL */ | ||
158 | /* DW0 */ | ||
159 | #define DW0_VALID_BIT 1 | ||
160 | #define FROM_DW0_VALID(x) ((x) & 0x01) | ||
161 | #define TO_DW0_LENGTH(x) (((u32) x) << 3) | ||
162 | #define TO_DW0_MAXPACKET(x) (((u32) x) << 18) | ||
163 | #define TO_DW0_MULTI(x) (((u32) x) << 29) | ||
164 | #define TO_DW0_ENDPOINT(x) (((u32) x) << 31) | ||
165 | /* DW1 */ | ||
166 | #define TO_DW1_DEVICE_ADDR(x) (((u32) x) << 3) | ||
167 | #define TO_DW1_PID_TOKEN(x) (((u32) x) << 10) | ||
168 | #define DW1_TRANS_BULK ((u32) 2 << 12) | ||
169 | #define DW1_TRANS_INT ((u32) 3 << 12) | ||
170 | #define DW1_TRANS_SPLIT ((u32) 1 << 14) | ||
171 | #define DW1_SE_USB_LOSPEED ((u32) 2 << 16) | ||
172 | #define TO_DW1_PORT_NUM(x) (((u32) x) << 18) | ||
173 | #define TO_DW1_HUB_NUM(x) (((u32) x) << 25) | ||
174 | /* DW2 */ | ||
175 | #define TO_DW2_DATA_START_ADDR(x) (((u32) x) << 8) | ||
176 | #define TO_DW2_RL(x) ((x) << 25) | ||
177 | #define FROM_DW2_RL(x) (((x) >> 25) & 0xf) | ||
178 | /* DW3 */ | ||
179 | #define FROM_DW3_NRBYTESTRANSFERRED(x) ((x) & 0x7fff) | ||
180 | #define FROM_DW3_SCS_NRBYTESTRANSFERRED(x) ((x) & 0x07ff) | ||
181 | #define TO_DW3_NAKCOUNT(x) ((x) << 19) | ||
182 | #define FROM_DW3_NAKCOUNT(x) (((x) >> 19) & 0xf) | ||
183 | #define TO_DW3_CERR(x) ((x) << 23) | ||
184 | #define FROM_DW3_CERR(x) (((x) >> 23) & 0x3) | ||
185 | #define TO_DW3_DATA_TOGGLE(x) ((x) << 25) | ||
186 | #define FROM_DW3_DATA_TOGGLE(x) (((x) >> 25) & 0x1) | ||
187 | #define TO_DW3_PING(x) ((x) << 26) | ||
188 | #define FROM_DW3_PING(x) (((x) >> 26) & 0x1) | ||
189 | #define DW3_ERROR_BIT (1 << 28) | ||
190 | #define DW3_BABBLE_BIT (1 << 29) | ||
191 | #define DW3_HALT_BIT (1 << 30) | ||
192 | #define DW3_ACTIVE_BIT (1 << 31) | ||
193 | #define FROM_DW3_ACTIVE(x) (((x) >> 31) & 0x01) | ||
194 | |||
195 | #define INT_UNDERRUN (1 << 2) | ||
196 | #define INT_BABBLE (1 << 1) | ||
197 | #define INT_EXACT (1 << 0) | ||
198 | |||
199 | #define SETUP_PID (2) | ||
200 | #define IN_PID (1) | ||
201 | #define OUT_PID (0) | ||
202 | |||
203 | /* Errata 1 */ | ||
204 | #define RL_COUNTER (0) | ||
205 | #define NAK_COUNTER (0) | ||
206 | #define ERR_COUNTER (2) | ||
207 | |||
208 | #endif /* _ISP1760_HCD_H_ */ | ||
diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c deleted file mode 100644 index 09254a43bc01..000000000000 --- a/drivers/usb/host/isp1760-if.c +++ /dev/null | |||
@@ -1,477 +0,0 @@ | |||
1 | /* | ||
2 | * Glue code for the ISP1760 driver and bus | ||
3 | * Currently there is support for | ||
4 | * - OpenFirmware | ||
5 | * - PCI | ||
6 | * - PDEV (generic platform device centralized driver model) | ||
7 | * | ||
8 | * (c) 2007 Sebastian Siewior <bigeasy@linutronix.de> | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/usb.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/usb/isp1760.h> | ||
17 | #include <linux/usb/hcd.h> | ||
18 | |||
19 | #include "isp1760-hcd.h" | ||
20 | |||
21 | #if defined(CONFIG_OF) && defined(CONFIG_OF_IRQ) | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/of.h> | ||
24 | #include <linux/of_platform.h> | ||
25 | #include <linux/of_address.h> | ||
26 | #include <linux/of_irq.h> | ||
27 | #include <linux/of_gpio.h> | ||
28 | #endif | ||
29 | |||
30 | #ifdef CONFIG_PCI | ||
31 | #include <linux/pci.h> | ||
32 | #endif | ||
33 | |||
34 | #if defined(CONFIG_OF) && defined(CONFIG_OF_IRQ) | ||
35 | struct isp1760 { | ||
36 | struct usb_hcd *hcd; | ||
37 | int rst_gpio; | ||
38 | }; | ||
39 | |||
40 | static int of_isp1760_probe(struct platform_device *dev) | ||
41 | { | ||
42 | struct isp1760 *drvdata; | ||
43 | struct device_node *dp = dev->dev.of_node; | ||
44 | struct resource *res; | ||
45 | struct resource memory; | ||
46 | int virq; | ||
47 | resource_size_t res_len; | ||
48 | int ret; | ||
49 | unsigned int devflags = 0; | ||
50 | enum of_gpio_flags gpio_flags; | ||
51 | u32 bus_width = 0; | ||
52 | |||
53 | drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); | ||
54 | if (!drvdata) | ||
55 | return -ENOMEM; | ||
56 | |||
57 | ret = of_address_to_resource(dp, 0, &memory); | ||
58 | if (ret) { | ||
59 | ret = -ENXIO; | ||
60 | goto free_data; | ||
61 | } | ||
62 | |||
63 | res_len = resource_size(&memory); | ||
64 | |||
65 | res = request_mem_region(memory.start, res_len, dev_name(&dev->dev)); | ||
66 | if (!res) { | ||
67 | ret = -EBUSY; | ||
68 | goto free_data; | ||
69 | } | ||
70 | |||
71 | virq = irq_of_parse_and_map(dp, 0); | ||
72 | if (!virq) { | ||
73 | ret = -ENODEV; | ||
74 | goto release_reg; | ||
75 | } | ||
76 | |||
77 | if (of_device_is_compatible(dp, "nxp,usb-isp1761")) | ||
78 | devflags |= ISP1760_FLAG_ISP1761; | ||
79 | |||
80 | /* Some systems wire up only 16 of the 32 data lines */ | ||
81 | of_property_read_u32(dp, "bus-width", &bus_width); | ||
82 | if (bus_width == 16) | ||
83 | devflags |= ISP1760_FLAG_BUS_WIDTH_16; | ||
84 | |||
85 | if (of_get_property(dp, "port1-otg", NULL) != NULL) | ||
86 | devflags |= ISP1760_FLAG_OTG_EN; | ||
87 | |||
88 | if (of_get_property(dp, "analog-oc", NULL) != NULL) | ||
89 | devflags |= ISP1760_FLAG_ANALOG_OC; | ||
90 | |||
91 | if (of_get_property(dp, "dack-polarity", NULL) != NULL) | ||
92 | devflags |= ISP1760_FLAG_DACK_POL_HIGH; | ||
93 | |||
94 | if (of_get_property(dp, "dreq-polarity", NULL) != NULL) | ||
95 | devflags |= ISP1760_FLAG_DREQ_POL_HIGH; | ||
96 | |||
97 | drvdata->rst_gpio = of_get_gpio_flags(dp, 0, &gpio_flags); | ||
98 | if (gpio_is_valid(drvdata->rst_gpio)) { | ||
99 | ret = gpio_request(drvdata->rst_gpio, dev_name(&dev->dev)); | ||
100 | if (!ret) { | ||
101 | if (!(gpio_flags & OF_GPIO_ACTIVE_LOW)) { | ||
102 | devflags |= ISP1760_FLAG_RESET_ACTIVE_HIGH; | ||
103 | gpio_direction_output(drvdata->rst_gpio, 0); | ||
104 | } else { | ||
105 | gpio_direction_output(drvdata->rst_gpio, 1); | ||
106 | } | ||
107 | } else { | ||
108 | drvdata->rst_gpio = ret; | ||
109 | } | ||
110 | } | ||
111 | |||
112 | drvdata->hcd = isp1760_register(memory.start, res_len, virq, | ||
113 | IRQF_SHARED, drvdata->rst_gpio, | ||
114 | &dev->dev, dev_name(&dev->dev), | ||
115 | devflags); | ||
116 | if (IS_ERR(drvdata->hcd)) { | ||
117 | ret = PTR_ERR(drvdata->hcd); | ||
118 | goto free_gpio; | ||
119 | } | ||
120 | |||
121 | platform_set_drvdata(dev, drvdata); | ||
122 | return ret; | ||
123 | |||
124 | free_gpio: | ||
125 | if (gpio_is_valid(drvdata->rst_gpio)) | ||
126 | gpio_free(drvdata->rst_gpio); | ||
127 | release_reg: | ||
128 | release_mem_region(memory.start, res_len); | ||
129 | free_data: | ||
130 | kfree(drvdata); | ||
131 | return ret; | ||
132 | } | ||
133 | |||
134 | static int of_isp1760_remove(struct platform_device *dev) | ||
135 | { | ||
136 | struct isp1760 *drvdata = platform_get_drvdata(dev); | ||
137 | |||
138 | usb_remove_hcd(drvdata->hcd); | ||
139 | iounmap(drvdata->hcd->regs); | ||
140 | release_mem_region(drvdata->hcd->rsrc_start, drvdata->hcd->rsrc_len); | ||
141 | usb_put_hcd(drvdata->hcd); | ||
142 | |||
143 | if (gpio_is_valid(drvdata->rst_gpio)) | ||
144 | gpio_free(drvdata->rst_gpio); | ||
145 | |||
146 | kfree(drvdata); | ||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | static const struct of_device_id of_isp1760_match[] = { | ||
151 | { | ||
152 | .compatible = "nxp,usb-isp1760", | ||
153 | }, | ||
154 | { | ||
155 | .compatible = "nxp,usb-isp1761", | ||
156 | }, | ||
157 | { }, | ||
158 | }; | ||
159 | MODULE_DEVICE_TABLE(of, of_isp1760_match); | ||
160 | |||
161 | static struct platform_driver isp1760_of_driver = { | ||
162 | .driver = { | ||
163 | .name = "nxp-isp1760", | ||
164 | .of_match_table = of_isp1760_match, | ||
165 | }, | ||
166 | .probe = of_isp1760_probe, | ||
167 | .remove = of_isp1760_remove, | ||
168 | }; | ||
169 | #endif | ||
170 | |||
171 | #ifdef CONFIG_PCI | ||
172 | static int isp1761_pci_probe(struct pci_dev *dev, | ||
173 | const struct pci_device_id *id) | ||
174 | { | ||
175 | u8 latency, limit; | ||
176 | __u32 reg_data; | ||
177 | int retry_count; | ||
178 | struct usb_hcd *hcd; | ||
179 | unsigned int devflags = 0; | ||
180 | int ret_status = 0; | ||
181 | |||
182 | resource_size_t pci_mem_phy0; | ||
183 | resource_size_t memlength; | ||
184 | |||
185 | u8 __iomem *chip_addr; | ||
186 | u8 __iomem *iobase; | ||
187 | resource_size_t nxp_pci_io_base; | ||
188 | resource_size_t iolength; | ||
189 | |||
190 | if (usb_disabled()) | ||
191 | return -ENODEV; | ||
192 | |||
193 | if (pci_enable_device(dev) < 0) | ||
194 | return -ENODEV; | ||
195 | |||
196 | if (!dev->irq) | ||
197 | return -ENODEV; | ||
198 | |||
199 | /* Grab the PLX PCI mem maped port start address we need */ | ||
200 | nxp_pci_io_base = pci_resource_start(dev, 0); | ||
201 | iolength = pci_resource_len(dev, 0); | ||
202 | |||
203 | if (!request_mem_region(nxp_pci_io_base, iolength, "ISP1761 IO MEM")) { | ||
204 | printk(KERN_ERR "request region #1\n"); | ||
205 | return -EBUSY; | ||
206 | } | ||
207 | |||
208 | iobase = ioremap_nocache(nxp_pci_io_base, iolength); | ||
209 | if (!iobase) { | ||
210 | printk(KERN_ERR "ioremap #1\n"); | ||
211 | ret_status = -ENOMEM; | ||
212 | goto cleanup1; | ||
213 | } | ||
214 | /* Grab the PLX PCI shared memory of the ISP 1761 we need */ | ||
215 | pci_mem_phy0 = pci_resource_start(dev, 3); | ||
216 | memlength = pci_resource_len(dev, 3); | ||
217 | if (memlength < 0xffff) { | ||
218 | printk(KERN_ERR "memory length for this resource is wrong\n"); | ||
219 | ret_status = -ENOMEM; | ||
220 | goto cleanup2; | ||
221 | } | ||
222 | |||
223 | if (!request_mem_region(pci_mem_phy0, memlength, "ISP-PCI")) { | ||
224 | printk(KERN_ERR "host controller already in use\n"); | ||
225 | ret_status = -EBUSY; | ||
226 | goto cleanup2; | ||
227 | } | ||
228 | |||
229 | /* map available memory */ | ||
230 | chip_addr = ioremap_nocache(pci_mem_phy0,memlength); | ||
231 | if (!chip_addr) { | ||
232 | printk(KERN_ERR "Error ioremap failed\n"); | ||
233 | ret_status = -ENOMEM; | ||
234 | goto cleanup3; | ||
235 | } | ||
236 | |||
237 | /* bad pci latencies can contribute to overruns */ | ||
238 | pci_read_config_byte(dev, PCI_LATENCY_TIMER, &latency); | ||
239 | if (latency) { | ||
240 | pci_read_config_byte(dev, PCI_MAX_LAT, &limit); | ||
241 | if (limit && limit < latency) | ||
242 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, limit); | ||
243 | } | ||
244 | |||
245 | /* Try to check whether we can access Scratch Register of | ||
246 | * Host Controller or not. The initial PCI access is retried until | ||
247 | * local init for the PCI bridge is completed | ||
248 | */ | ||
249 | retry_count = 20; | ||
250 | reg_data = 0; | ||
251 | while ((reg_data != 0xFACE) && retry_count) { | ||
252 | /*by default host is in 16bit mode, so | ||
253 | * io operations at this stage must be 16 bit | ||
254 | * */ | ||
255 | writel(0xface, chip_addr + HC_SCRATCH_REG); | ||
256 | udelay(100); | ||
257 | reg_data = readl(chip_addr + HC_SCRATCH_REG) & 0x0000ffff; | ||
258 | retry_count--; | ||
259 | } | ||
260 | |||
261 | iounmap(chip_addr); | ||
262 | |||
263 | /* Host Controller presence is detected by writing to scratch register | ||
264 | * and reading back and checking the contents are same or not | ||
265 | */ | ||
266 | if (reg_data != 0xFACE) { | ||
267 | dev_err(&dev->dev, "scratch register mismatch %x\n", reg_data); | ||
268 | ret_status = -ENOMEM; | ||
269 | goto cleanup3; | ||
270 | } | ||
271 | |||
272 | pci_set_master(dev); | ||
273 | |||
274 | /* configure PLX PCI chip to pass interrupts */ | ||
275 | #define PLX_INT_CSR_REG 0x68 | ||
276 | reg_data = readl(iobase + PLX_INT_CSR_REG); | ||
277 | reg_data |= 0x900; | ||
278 | writel(reg_data, iobase + PLX_INT_CSR_REG); | ||
279 | |||
280 | dev->dev.dma_mask = NULL; | ||
281 | hcd = isp1760_register(pci_mem_phy0, memlength, dev->irq, | ||
282 | IRQF_SHARED, -ENOENT, &dev->dev, dev_name(&dev->dev), | ||
283 | devflags); | ||
284 | if (IS_ERR(hcd)) { | ||
285 | ret_status = -ENODEV; | ||
286 | goto cleanup3; | ||
287 | } | ||
288 | |||
289 | /* done with PLX IO access */ | ||
290 | iounmap(iobase); | ||
291 | release_mem_region(nxp_pci_io_base, iolength); | ||
292 | |||
293 | pci_set_drvdata(dev, hcd); | ||
294 | return 0; | ||
295 | |||
296 | cleanup3: | ||
297 | release_mem_region(pci_mem_phy0, memlength); | ||
298 | cleanup2: | ||
299 | iounmap(iobase); | ||
300 | cleanup1: | ||
301 | release_mem_region(nxp_pci_io_base, iolength); | ||
302 | return ret_status; | ||
303 | } | ||
304 | |||
305 | static void isp1761_pci_remove(struct pci_dev *dev) | ||
306 | { | ||
307 | struct usb_hcd *hcd; | ||
308 | |||
309 | hcd = pci_get_drvdata(dev); | ||
310 | |||
311 | usb_remove_hcd(hcd); | ||
312 | iounmap(hcd->regs); | ||
313 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
314 | usb_put_hcd(hcd); | ||
315 | |||
316 | pci_disable_device(dev); | ||
317 | } | ||
318 | |||
319 | static void isp1761_pci_shutdown(struct pci_dev *dev) | ||
320 | { | ||
321 | printk(KERN_ERR "ips1761_pci_shutdown\n"); | ||
322 | } | ||
323 | |||
324 | static const struct pci_device_id isp1760_plx [] = { | ||
325 | { | ||
326 | .class = PCI_CLASS_BRIDGE_OTHER << 8, | ||
327 | .class_mask = ~0, | ||
328 | .vendor = PCI_VENDOR_ID_PLX, | ||
329 | .device = 0x5406, | ||
330 | .subvendor = PCI_VENDOR_ID_PLX, | ||
331 | .subdevice = 0x9054, | ||
332 | }, | ||
333 | { } | ||
334 | }; | ||
335 | MODULE_DEVICE_TABLE(pci, isp1760_plx); | ||
336 | |||
337 | static struct pci_driver isp1761_pci_driver = { | ||
338 | .name = "isp1760", | ||
339 | .id_table = isp1760_plx, | ||
340 | .probe = isp1761_pci_probe, | ||
341 | .remove = isp1761_pci_remove, | ||
342 | .shutdown = isp1761_pci_shutdown, | ||
343 | }; | ||
344 | #endif | ||
345 | |||
346 | static int isp1760_plat_probe(struct platform_device *pdev) | ||
347 | { | ||
348 | int ret = 0; | ||
349 | struct usb_hcd *hcd; | ||
350 | struct resource *mem_res; | ||
351 | struct resource *irq_res; | ||
352 | resource_size_t mem_size; | ||
353 | struct isp1760_platform_data *priv = dev_get_platdata(&pdev->dev); | ||
354 | unsigned int devflags = 0; | ||
355 | unsigned long irqflags = IRQF_SHARED; | ||
356 | |||
357 | mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
358 | if (!mem_res) { | ||
359 | pr_warning("isp1760: Memory resource not available\n"); | ||
360 | ret = -ENODEV; | ||
361 | goto out; | ||
362 | } | ||
363 | mem_size = resource_size(mem_res); | ||
364 | if (!request_mem_region(mem_res->start, mem_size, "isp1760")) { | ||
365 | pr_warning("isp1760: Cannot reserve the memory resource\n"); | ||
366 | ret = -EBUSY; | ||
367 | goto out; | ||
368 | } | ||
369 | |||
370 | irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
371 | if (!irq_res) { | ||
372 | pr_warning("isp1760: IRQ resource not available\n"); | ||
373 | ret = -ENODEV; | ||
374 | goto cleanup; | ||
375 | } | ||
376 | |||
377 | irqflags |= irq_res->flags & IRQF_TRIGGER_MASK; | ||
378 | |||
379 | if (priv) { | ||
380 | if (priv->is_isp1761) | ||
381 | devflags |= ISP1760_FLAG_ISP1761; | ||
382 | if (priv->bus_width_16) | ||
383 | devflags |= ISP1760_FLAG_BUS_WIDTH_16; | ||
384 | if (priv->port1_otg) | ||
385 | devflags |= ISP1760_FLAG_OTG_EN; | ||
386 | if (priv->analog_oc) | ||
387 | devflags |= ISP1760_FLAG_ANALOG_OC; | ||
388 | if (priv->dack_polarity_high) | ||
389 | devflags |= ISP1760_FLAG_DACK_POL_HIGH; | ||
390 | if (priv->dreq_polarity_high) | ||
391 | devflags |= ISP1760_FLAG_DREQ_POL_HIGH; | ||
392 | } | ||
393 | |||
394 | hcd = isp1760_register(mem_res->start, mem_size, irq_res->start, | ||
395 | irqflags, -ENOENT, | ||
396 | &pdev->dev, dev_name(&pdev->dev), devflags); | ||
397 | |||
398 | platform_set_drvdata(pdev, hcd); | ||
399 | |||
400 | if (IS_ERR(hcd)) { | ||
401 | pr_warning("isp1760: Failed to register the HCD device\n"); | ||
402 | ret = -ENODEV; | ||
403 | goto cleanup; | ||
404 | } | ||
405 | |||
406 | pr_info("ISP1760 USB device initialised\n"); | ||
407 | return ret; | ||
408 | |||
409 | cleanup: | ||
410 | release_mem_region(mem_res->start, mem_size); | ||
411 | out: | ||
412 | return ret; | ||
413 | } | ||
414 | |||
415 | static int isp1760_plat_remove(struct platform_device *pdev) | ||
416 | { | ||
417 | struct resource *mem_res; | ||
418 | resource_size_t mem_size; | ||
419 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
420 | |||
421 | usb_remove_hcd(hcd); | ||
422 | |||
423 | mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
424 | mem_size = resource_size(mem_res); | ||
425 | release_mem_region(mem_res->start, mem_size); | ||
426 | |||
427 | usb_put_hcd(hcd); | ||
428 | |||
429 | return 0; | ||
430 | } | ||
431 | |||
432 | static struct platform_driver isp1760_plat_driver = { | ||
433 | .probe = isp1760_plat_probe, | ||
434 | .remove = isp1760_plat_remove, | ||
435 | .driver = { | ||
436 | .name = "isp1760", | ||
437 | }, | ||
438 | }; | ||
439 | |||
440 | static int __init isp1760_init(void) | ||
441 | { | ||
442 | int ret, any_ret = -ENODEV; | ||
443 | |||
444 | init_kmem_once(); | ||
445 | |||
446 | ret = platform_driver_register(&isp1760_plat_driver); | ||
447 | if (!ret) | ||
448 | any_ret = 0; | ||
449 | #if defined(CONFIG_OF) && defined(CONFIG_OF_IRQ) | ||
450 | ret = platform_driver_register(&isp1760_of_driver); | ||
451 | if (!ret) | ||
452 | any_ret = 0; | ||
453 | #endif | ||
454 | #ifdef CONFIG_PCI | ||
455 | ret = pci_register_driver(&isp1761_pci_driver); | ||
456 | if (!ret) | ||
457 | any_ret = 0; | ||
458 | #endif | ||
459 | |||
460 | if (any_ret) | ||
461 | deinit_kmem_cache(); | ||
462 | return any_ret; | ||
463 | } | ||
464 | module_init(isp1760_init); | ||
465 | |||
466 | static void __exit isp1760_exit(void) | ||
467 | { | ||
468 | platform_driver_unregister(&isp1760_plat_driver); | ||
469 | #if defined(CONFIG_OF) && defined(CONFIG_OF_IRQ) | ||
470 | platform_driver_unregister(&isp1760_of_driver); | ||
471 | #endif | ||
472 | #ifdef CONFIG_PCI | ||
473 | pci_unregister_driver(&isp1761_pci_driver); | ||
474 | #endif | ||
475 | deinit_kmem_cache(); | ||
476 | } | ||
477 | module_exit(isp1760_exit); | ||
diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c index 6234c75da33f..a98833cbfcf3 100644 --- a/drivers/usb/host/max3421-hcd.c +++ b/drivers/usb/host/max3421-hcd.c | |||
@@ -55,6 +55,7 @@ | |||
55 | * single thread (max3421_spi_thread). | 55 | * single thread (max3421_spi_thread). |
56 | */ | 56 | */ |
57 | 57 | ||
58 | #include <linux/jiffies.h> | ||
58 | #include <linux/module.h> | 59 | #include <linux/module.h> |
59 | #include <linux/spi/spi.h> | 60 | #include <linux/spi/spi.h> |
60 | #include <linux/usb.h> | 61 | #include <linux/usb.h> |
@@ -1291,7 +1292,7 @@ max3421_handle_irqs(struct usb_hcd *hcd) | |||
1291 | char sbuf[16 * 16], *dp, *end; | 1292 | char sbuf[16 * 16], *dp, *end; |
1292 | int i; | 1293 | int i; |
1293 | 1294 | ||
1294 | if (jiffies - last_time > 5*HZ) { | 1295 | if (time_after(jiffies, last_time + 5*HZ)) { |
1295 | dp = sbuf; | 1296 | dp = sbuf; |
1296 | end = sbuf + sizeof(sbuf); | 1297 | end = sbuf + sizeof(sbuf); |
1297 | *dp = '\0'; | 1298 | *dp = '\0'; |
@@ -1660,7 +1661,8 @@ hub_descriptor(struct usb_hub_descriptor *desc) | |||
1660 | */ | 1661 | */ |
1661 | desc->bDescriptorType = 0x29; /* hub descriptor */ | 1662 | desc->bDescriptorType = 0x29; /* hub descriptor */ |
1662 | desc->bDescLength = 9; | 1663 | desc->bDescLength = 9; |
1663 | desc->wHubCharacteristics = cpu_to_le16(0x0001); | 1664 | desc->wHubCharacteristics = cpu_to_le16(HUB_CHAR_INDV_PORT_LPSM | |
1665 | HUB_CHAR_COMMON_OCPM); | ||
1664 | desc->bNbrPorts = 1; | 1666 | desc->bNbrPorts = 1; |
1665 | } | 1667 | } |
1666 | 1668 | ||
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index dc9e4e61f1c8..7cce85a1f7dc 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c | |||
@@ -33,7 +33,17 @@ | |||
33 | for ((index) = 0; (index) < AT91_MAX_USBH_PORTS; (index)++) | 33 | for ((index) = 0; (index) < AT91_MAX_USBH_PORTS; (index)++) |
34 | 34 | ||
35 | /* interface, function and usb clocks; sometimes also an AHB clock */ | 35 | /* interface, function and usb clocks; sometimes also an AHB clock */ |
36 | static struct clk *iclk, *fclk, *uclk, *hclk; | 36 | #define hcd_to_ohci_at91_priv(h) \ |
37 | ((struct ohci_at91_priv *)hcd_to_ohci(h)->priv) | ||
38 | |||
39 | struct ohci_at91_priv { | ||
40 | struct clk *iclk; | ||
41 | struct clk *fclk; | ||
42 | struct clk *uclk; | ||
43 | struct clk *hclk; | ||
44 | bool clocked; | ||
45 | bool wakeup; /* Saved wake-up state for resume */ | ||
46 | }; | ||
37 | /* interface and function clocks; sometimes also an AHB clock */ | 47 | /* interface and function clocks; sometimes also an AHB clock */ |
38 | 48 | ||
39 | #define DRIVER_DESC "OHCI Atmel driver" | 49 | #define DRIVER_DESC "OHCI Atmel driver" |
@@ -41,45 +51,53 @@ static struct clk *iclk, *fclk, *uclk, *hclk; | |||
41 | static const char hcd_name[] = "ohci-atmel"; | 51 | static const char hcd_name[] = "ohci-atmel"; |
42 | 52 | ||
43 | static struct hc_driver __read_mostly ohci_at91_hc_driver; | 53 | static struct hc_driver __read_mostly ohci_at91_hc_driver; |
44 | static int clocked; | 54 | |
55 | static const struct ohci_driver_overrides ohci_at91_drv_overrides __initconst = { | ||
56 | .extra_priv_size = sizeof(struct ohci_at91_priv), | ||
57 | }; | ||
45 | 58 | ||
46 | extern int usb_disabled(void); | 59 | extern int usb_disabled(void); |
47 | 60 | ||
48 | /*-------------------------------------------------------------------------*/ | 61 | /*-------------------------------------------------------------------------*/ |
49 | 62 | ||
50 | static void at91_start_clock(void) | 63 | static void at91_start_clock(struct ohci_at91_priv *ohci_at91) |
51 | { | 64 | { |
65 | if (ohci_at91->clocked) | ||
66 | return; | ||
52 | if (IS_ENABLED(CONFIG_COMMON_CLK)) { | 67 | if (IS_ENABLED(CONFIG_COMMON_CLK)) { |
53 | clk_set_rate(uclk, 48000000); | 68 | clk_set_rate(ohci_at91->uclk, 48000000); |
54 | clk_prepare_enable(uclk); | 69 | clk_prepare_enable(ohci_at91->uclk); |
55 | } | 70 | } |
56 | clk_prepare_enable(hclk); | 71 | clk_prepare_enable(ohci_at91->hclk); |
57 | clk_prepare_enable(iclk); | 72 | clk_prepare_enable(ohci_at91->iclk); |
58 | clk_prepare_enable(fclk); | 73 | clk_prepare_enable(ohci_at91->fclk); |
59 | clocked = 1; | 74 | ohci_at91->clocked = true; |
60 | } | 75 | } |
61 | 76 | ||
62 | static void at91_stop_clock(void) | 77 | static void at91_stop_clock(struct ohci_at91_priv *ohci_at91) |
63 | { | 78 | { |
64 | clk_disable_unprepare(fclk); | 79 | if (!ohci_at91->clocked) |
65 | clk_disable_unprepare(iclk); | 80 | return; |
66 | clk_disable_unprepare(hclk); | 81 | clk_disable_unprepare(ohci_at91->fclk); |
82 | clk_disable_unprepare(ohci_at91->iclk); | ||
83 | clk_disable_unprepare(ohci_at91->hclk); | ||
67 | if (IS_ENABLED(CONFIG_COMMON_CLK)) | 84 | if (IS_ENABLED(CONFIG_COMMON_CLK)) |
68 | clk_disable_unprepare(uclk); | 85 | clk_disable_unprepare(ohci_at91->uclk); |
69 | clocked = 0; | 86 | ohci_at91->clocked = false; |
70 | } | 87 | } |
71 | 88 | ||
72 | static void at91_start_hc(struct platform_device *pdev) | 89 | static void at91_start_hc(struct platform_device *pdev) |
73 | { | 90 | { |
74 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | 91 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
75 | struct ohci_regs __iomem *regs = hcd->regs; | 92 | struct ohci_regs __iomem *regs = hcd->regs; |
93 | struct ohci_at91_priv *ohci_at91 = hcd_to_ohci_at91_priv(hcd); | ||
76 | 94 | ||
77 | dev_dbg(&pdev->dev, "start\n"); | 95 | dev_dbg(&pdev->dev, "start\n"); |
78 | 96 | ||
79 | /* | 97 | /* |
80 | * Start the USB clocks. | 98 | * Start the USB clocks. |
81 | */ | 99 | */ |
82 | at91_start_clock(); | 100 | at91_start_clock(ohci_at91); |
83 | 101 | ||
84 | /* | 102 | /* |
85 | * The USB host controller must remain in reset. | 103 | * The USB host controller must remain in reset. |
@@ -91,6 +109,7 @@ static void at91_stop_hc(struct platform_device *pdev) | |||
91 | { | 109 | { |
92 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | 110 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
93 | struct ohci_regs __iomem *regs = hcd->regs; | 111 | struct ohci_regs __iomem *regs = hcd->regs; |
112 | struct ohci_at91_priv *ohci_at91 = hcd_to_ohci_at91_priv(hcd); | ||
94 | 113 | ||
95 | dev_dbg(&pdev->dev, "stop\n"); | 114 | dev_dbg(&pdev->dev, "stop\n"); |
96 | 115 | ||
@@ -102,7 +121,7 @@ static void at91_stop_hc(struct platform_device *pdev) | |||
102 | /* | 121 | /* |
103 | * Stop the USB clocks. | 122 | * Stop the USB clocks. |
104 | */ | 123 | */ |
105 | at91_stop_clock(); | 124 | at91_stop_clock(ohci_at91); |
106 | } | 125 | } |
107 | 126 | ||
108 | 127 | ||
@@ -128,7 +147,8 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver, | |||
128 | struct at91_usbh_data *board; | 147 | struct at91_usbh_data *board; |
129 | struct ohci_hcd *ohci; | 148 | struct ohci_hcd *ohci; |
130 | int retval; | 149 | int retval; |
131 | struct usb_hcd *hcd = NULL; | 150 | struct usb_hcd *hcd; |
151 | struct ohci_at91_priv *ohci_at91; | ||
132 | struct device *dev = &pdev->dev; | 152 | struct device *dev = &pdev->dev; |
133 | struct resource *res; | 153 | struct resource *res; |
134 | int irq; | 154 | int irq; |
@@ -142,6 +162,7 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver, | |||
142 | hcd = usb_create_hcd(driver, dev, "at91"); | 162 | hcd = usb_create_hcd(driver, dev, "at91"); |
143 | if (!hcd) | 163 | if (!hcd) |
144 | return -ENOMEM; | 164 | return -ENOMEM; |
165 | ohci_at91 = hcd_to_ohci_at91_priv(hcd); | ||
145 | 166 | ||
146 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 167 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
147 | hcd->regs = devm_ioremap_resource(dev, res); | 168 | hcd->regs = devm_ioremap_resource(dev, res); |
@@ -152,29 +173,29 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver, | |||
152 | hcd->rsrc_start = res->start; | 173 | hcd->rsrc_start = res->start; |
153 | hcd->rsrc_len = resource_size(res); | 174 | hcd->rsrc_len = resource_size(res); |
154 | 175 | ||
155 | iclk = devm_clk_get(dev, "ohci_clk"); | 176 | ohci_at91->iclk = devm_clk_get(dev, "ohci_clk"); |
156 | if (IS_ERR(iclk)) { | 177 | if (IS_ERR(ohci_at91->iclk)) { |
157 | dev_err(dev, "failed to get ohci_clk\n"); | 178 | dev_err(dev, "failed to get ohci_clk\n"); |
158 | retval = PTR_ERR(iclk); | 179 | retval = PTR_ERR(ohci_at91->iclk); |
159 | goto err; | 180 | goto err; |
160 | } | 181 | } |
161 | fclk = devm_clk_get(dev, "uhpck"); | 182 | ohci_at91->fclk = devm_clk_get(dev, "uhpck"); |
162 | if (IS_ERR(fclk)) { | 183 | if (IS_ERR(ohci_at91->fclk)) { |
163 | dev_err(dev, "failed to get uhpck\n"); | 184 | dev_err(dev, "failed to get uhpck\n"); |
164 | retval = PTR_ERR(fclk); | 185 | retval = PTR_ERR(ohci_at91->fclk); |
165 | goto err; | 186 | goto err; |
166 | } | 187 | } |
167 | hclk = devm_clk_get(dev, "hclk"); | 188 | ohci_at91->hclk = devm_clk_get(dev, "hclk"); |
168 | if (IS_ERR(hclk)) { | 189 | if (IS_ERR(ohci_at91->hclk)) { |
169 | dev_err(dev, "failed to get hclk\n"); | 190 | dev_err(dev, "failed to get hclk\n"); |
170 | retval = PTR_ERR(hclk); | 191 | retval = PTR_ERR(ohci_at91->hclk); |
171 | goto err; | 192 | goto err; |
172 | } | 193 | } |
173 | if (IS_ENABLED(CONFIG_COMMON_CLK)) { | 194 | if (IS_ENABLED(CONFIG_COMMON_CLK)) { |
174 | uclk = devm_clk_get(dev, "usb_clk"); | 195 | ohci_at91->uclk = devm_clk_get(dev, "usb_clk"); |
175 | if (IS_ERR(uclk)) { | 196 | if (IS_ERR(ohci_at91->uclk)) { |
176 | dev_err(dev, "failed to get uclk\n"); | 197 | dev_err(dev, "failed to get uclk\n"); |
177 | retval = PTR_ERR(uclk); | 198 | retval = PTR_ERR(ohci_at91->uclk); |
178 | goto err; | 199 | goto err; |
179 | } | 200 | } |
180 | } | 201 | } |
@@ -347,11 +368,13 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
347 | */ | 368 | */ |
348 | 369 | ||
349 | desc->wHubCharacteristics &= ~cpu_to_le16(HUB_CHAR_LPSM); | 370 | desc->wHubCharacteristics &= ~cpu_to_le16(HUB_CHAR_LPSM); |
350 | desc->wHubCharacteristics |= cpu_to_le16(0x0001); | 371 | desc->wHubCharacteristics |= |
372 | cpu_to_le16(HUB_CHAR_INDV_PORT_LPSM); | ||
351 | 373 | ||
352 | if (pdata->overcurrent_supported) { | 374 | if (pdata->overcurrent_supported) { |
353 | desc->wHubCharacteristics &= ~cpu_to_le16(HUB_CHAR_OCPM); | 375 | desc->wHubCharacteristics &= ~cpu_to_le16(HUB_CHAR_OCPM); |
354 | desc->wHubCharacteristics |= cpu_to_le16(0x0008|0x0001); | 376 | desc->wHubCharacteristics |= |
377 | cpu_to_le16(HUB_CHAR_INDV_PORT_OCPM); | ||
355 | } | 378 | } |
356 | 379 | ||
357 | dev_dbg(hcd->self.controller, "wHubCharacteristics after 0x%04x\n", | 380 | dev_dbg(hcd->self.controller, "wHubCharacteristics after 0x%04x\n", |
@@ -593,19 +616,27 @@ static int ohci_hcd_at91_drv_remove(struct platform_device *pdev) | |||
593 | #ifdef CONFIG_PM | 616 | #ifdef CONFIG_PM |
594 | 617 | ||
595 | static int | 618 | static int |
596 | ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg) | 619 | ohci_hcd_at91_drv_suspend(struct device *dev) |
597 | { | 620 | { |
598 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | 621 | struct usb_hcd *hcd = dev_get_drvdata(dev); |
599 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | 622 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); |
600 | bool do_wakeup = device_may_wakeup(&pdev->dev); | 623 | struct ohci_at91_priv *ohci_at91 = hcd_to_ohci_at91_priv(hcd); |
601 | int ret; | 624 | int ret; |
602 | 625 | ||
603 | if (do_wakeup) | 626 | /* |
627 | * Disable wakeup if we are going to sleep with slow clock mode | ||
628 | * enabled. | ||
629 | */ | ||
630 | ohci_at91->wakeup = device_may_wakeup(dev) | ||
631 | && !at91_suspend_entering_slow_clock(); | ||
632 | |||
633 | if (ohci_at91->wakeup) | ||
604 | enable_irq_wake(hcd->irq); | 634 | enable_irq_wake(hcd->irq); |
605 | 635 | ||
606 | ret = ohci_suspend(hcd, do_wakeup); | 636 | ret = ohci_suspend(hcd, ohci_at91->wakeup); |
607 | if (ret) { | 637 | if (ret) { |
608 | disable_irq_wake(hcd->irq); | 638 | if (ohci_at91->wakeup) |
639 | disable_irq_wake(hcd->irq); | ||
609 | return ret; | 640 | return ret; |
610 | } | 641 | } |
611 | /* | 642 | /* |
@@ -615,7 +646,7 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg) | |||
615 | * | 646 | * |
616 | * REVISIT: some boards will be able to turn VBUS off... | 647 | * REVISIT: some boards will be able to turn VBUS off... |
617 | */ | 648 | */ |
618 | if (at91_suspend_entering_slow_clock()) { | 649 | if (!ohci_at91->wakeup) { |
619 | ohci->hc_control = ohci_readl(ohci, &ohci->regs->control); | 650 | ohci->hc_control = ohci_readl(ohci, &ohci->regs->control); |
620 | ohci->hc_control &= OHCI_CTRL_RWC; | 651 | ohci->hc_control &= OHCI_CTRL_RWC; |
621 | ohci_writel(ohci, ohci->hc_control, &ohci->regs->control); | 652 | ohci_writel(ohci, ohci->hc_control, &ohci->regs->control); |
@@ -623,38 +654,37 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg) | |||
623 | 654 | ||
624 | /* flush the writes */ | 655 | /* flush the writes */ |
625 | (void) ohci_readl (ohci, &ohci->regs->control); | 656 | (void) ohci_readl (ohci, &ohci->regs->control); |
626 | at91_stop_clock(); | 657 | at91_stop_clock(ohci_at91); |
627 | } | 658 | } |
628 | 659 | ||
629 | return ret; | 660 | return ret; |
630 | } | 661 | } |
631 | 662 | ||
632 | static int ohci_hcd_at91_drv_resume(struct platform_device *pdev) | 663 | static int ohci_hcd_at91_drv_resume(struct device *dev) |
633 | { | 664 | { |
634 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | 665 | struct usb_hcd *hcd = dev_get_drvdata(dev); |
666 | struct ohci_at91_priv *ohci_at91 = hcd_to_ohci_at91_priv(hcd); | ||
635 | 667 | ||
636 | if (device_may_wakeup(&pdev->dev)) | 668 | if (ohci_at91->wakeup) |
637 | disable_irq_wake(hcd->irq); | 669 | disable_irq_wake(hcd->irq); |
638 | 670 | ||
639 | if (!clocked) | 671 | at91_start_clock(ohci_at91); |
640 | at91_start_clock(); | ||
641 | 672 | ||
642 | ohci_resume(hcd, false); | 673 | ohci_resume(hcd, false); |
643 | return 0; | 674 | return 0; |
644 | } | 675 | } |
645 | #else | ||
646 | #define ohci_hcd_at91_drv_suspend NULL | ||
647 | #define ohci_hcd_at91_drv_resume NULL | ||
648 | #endif | 676 | #endif |
649 | 677 | ||
678 | static SIMPLE_DEV_PM_OPS(ohci_hcd_at91_pm_ops, ohci_hcd_at91_drv_suspend, | ||
679 | ohci_hcd_at91_drv_resume); | ||
680 | |||
650 | static struct platform_driver ohci_hcd_at91_driver = { | 681 | static struct platform_driver ohci_hcd_at91_driver = { |
651 | .probe = ohci_hcd_at91_drv_probe, | 682 | .probe = ohci_hcd_at91_drv_probe, |
652 | .remove = ohci_hcd_at91_drv_remove, | 683 | .remove = ohci_hcd_at91_drv_remove, |
653 | .shutdown = usb_hcd_platform_shutdown, | 684 | .shutdown = usb_hcd_platform_shutdown, |
654 | .suspend = ohci_hcd_at91_drv_suspend, | ||
655 | .resume = ohci_hcd_at91_drv_resume, | ||
656 | .driver = { | 685 | .driver = { |
657 | .name = "at91_ohci", | 686 | .name = "at91_ohci", |
687 | .pm = &ohci_hcd_at91_pm_ops, | ||
658 | .of_match_table = of_match_ptr(at91_ohci_dt_ids), | 688 | .of_match_table = of_match_ptr(at91_ohci_dt_ids), |
659 | }, | 689 | }, |
660 | }; | 690 | }; |
@@ -665,7 +695,7 @@ static int __init ohci_at91_init(void) | |||
665 | return -ENODEV; | 695 | return -ENODEV; |
666 | 696 | ||
667 | pr_info("%s: " DRIVER_DESC "\n", hcd_name); | 697 | pr_info("%s: " DRIVER_DESC "\n", hcd_name); |
668 | ohci_init_driver(&ohci_at91_hc_driver, NULL); | 698 | ohci_init_driver(&ohci_at91_hc_driver, &ohci_at91_drv_overrides); |
669 | 699 | ||
670 | /* | 700 | /* |
671 | * The Atmel HW has some unusual quirks, which require Atmel-specific | 701 | * The Atmel HW has some unusual quirks, which require Atmel-specific |
diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c index 1c76999b2184..e5c33bc98ea4 100644 --- a/drivers/usb/host/ohci-da8xx.c +++ b/drivers/usb/host/ohci-da8xx.c | |||
@@ -431,7 +431,6 @@ static struct platform_driver ohci_hcd_da8xx_driver = { | |||
431 | .resume = ohci_da8xx_resume, | 431 | .resume = ohci_da8xx_resume, |
432 | #endif | 432 | #endif |
433 | .driver = { | 433 | .driver = { |
434 | .owner = THIS_MODULE, | ||
435 | .name = "ohci", | 434 | .name = "ohci", |
436 | }, | 435 | }, |
437 | }; | 436 | }; |
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 0aa17c937115..fe2aedd8a54d 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c | |||
@@ -544,15 +544,15 @@ ohci_hub_descriptor ( | |||
544 | temp = 1 + (ohci->num_ports / 8); | 544 | temp = 1 + (ohci->num_ports / 8); |
545 | desc->bDescLength = 7 + 2 * temp; | 545 | desc->bDescLength = 7 + 2 * temp; |
546 | 546 | ||
547 | temp = 0; | 547 | temp = HUB_CHAR_COMMON_LPSM | HUB_CHAR_COMMON_OCPM; |
548 | if (rh & RH_A_NPS) /* no power switching? */ | 548 | if (rh & RH_A_NPS) /* no power switching? */ |
549 | temp |= 0x0002; | 549 | temp |= HUB_CHAR_NO_LPSM; |
550 | if (rh & RH_A_PSM) /* per-port power switching? */ | 550 | if (rh & RH_A_PSM) /* per-port power switching? */ |
551 | temp |= 0x0001; | 551 | temp |= HUB_CHAR_INDV_PORT_LPSM; |
552 | if (rh & RH_A_NOCP) /* no overcurrent reporting? */ | 552 | if (rh & RH_A_NOCP) /* no overcurrent reporting? */ |
553 | temp |= 0x0010; | 553 | temp |= HUB_CHAR_NO_OCPM; |
554 | else if (rh & RH_A_OCPM) /* per-port overcurrent reporting? */ | 554 | else if (rh & RH_A_OCPM) /* per-port overcurrent reporting? */ |
555 | temp |= 0x0008; | 555 | temp |= HUB_CHAR_INDV_PORT_OCPM; |
556 | desc->wHubCharacteristics = cpu_to_le16(temp); | 556 | desc->wHubCharacteristics = cpu_to_le16(temp); |
557 | 557 | ||
558 | /* ports removable, and usb 1.0 legacy PortPwrCtrlMask */ | 558 | /* ports removable, and usb 1.0 legacy PortPwrCtrlMask */ |
diff --git a/drivers/usb/host/ohci-jz4740.c b/drivers/usb/host/ohci-jz4740.c index 8ddd8f5470cb..4db78f169256 100644 --- a/drivers/usb/host/ohci-jz4740.c +++ b/drivers/usb/host/ohci-jz4740.c | |||
@@ -239,7 +239,6 @@ static struct platform_driver ohci_hcd_jz4740_driver = { | |||
239 | .remove = jz4740_ohci_remove, | 239 | .remove = jz4740_ohci_remove, |
240 | .driver = { | 240 | .driver = { |
241 | .name = "jz4740-ohci", | 241 | .name = "jz4740-ohci", |
242 | .owner = THIS_MODULE, | ||
243 | }, | 242 | }, |
244 | }; | 243 | }; |
245 | 244 | ||
diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c index b81d202b15a2..185ceee52d47 100644 --- a/drivers/usb/host/ohci-platform.c +++ b/drivers/usb/host/ohci-platform.c | |||
@@ -38,7 +38,8 @@ | |||
38 | struct ohci_platform_priv { | 38 | struct ohci_platform_priv { |
39 | struct clk *clks[OHCI_MAX_CLKS]; | 39 | struct clk *clks[OHCI_MAX_CLKS]; |
40 | struct reset_control *rst; | 40 | struct reset_control *rst; |
41 | struct phy *phy; | 41 | struct phy **phys; |
42 | int num_phys; | ||
42 | }; | 43 | }; |
43 | 44 | ||
44 | static const char hcd_name[] = "ohci-platform"; | 45 | static const char hcd_name[] = "ohci-platform"; |
@@ -47,7 +48,7 @@ static int ohci_platform_power_on(struct platform_device *dev) | |||
47 | { | 48 | { |
48 | struct usb_hcd *hcd = platform_get_drvdata(dev); | 49 | struct usb_hcd *hcd = platform_get_drvdata(dev); |
49 | struct ohci_platform_priv *priv = hcd_to_ohci_priv(hcd); | 50 | struct ohci_platform_priv *priv = hcd_to_ohci_priv(hcd); |
50 | int clk, ret; | 51 | int clk, ret, phy_num; |
51 | 52 | ||
52 | for (clk = 0; clk < OHCI_MAX_CLKS && priv->clks[clk]; clk++) { | 53 | for (clk = 0; clk < OHCI_MAX_CLKS && priv->clks[clk]; clk++) { |
53 | ret = clk_prepare_enable(priv->clks[clk]); | 54 | ret = clk_prepare_enable(priv->clks[clk]); |
@@ -55,20 +56,28 @@ static int ohci_platform_power_on(struct platform_device *dev) | |||
55 | goto err_disable_clks; | 56 | goto err_disable_clks; |
56 | } | 57 | } |
57 | 58 | ||
58 | if (priv->phy) { | 59 | for (phy_num = 0; phy_num < priv->num_phys; phy_num++) { |
59 | ret = phy_init(priv->phy); | 60 | if (priv->phys[phy_num]) { |
60 | if (ret) | 61 | ret = phy_init(priv->phys[phy_num]); |
61 | goto err_disable_clks; | 62 | if (ret) |
62 | 63 | goto err_exit_phy; | |
63 | ret = phy_power_on(priv->phy); | 64 | ret = phy_power_on(priv->phys[phy_num]); |
64 | if (ret) | 65 | if (ret) { |
65 | goto err_exit_phy; | 66 | phy_exit(priv->phys[phy_num]); |
67 | goto err_exit_phy; | ||
68 | } | ||
69 | } | ||
66 | } | 70 | } |
67 | 71 | ||
68 | return 0; | 72 | return 0; |
69 | 73 | ||
70 | err_exit_phy: | 74 | err_exit_phy: |
71 | phy_exit(priv->phy); | 75 | while (--phy_num >= 0) { |
76 | if (priv->phys[phy_num]) { | ||
77 | phy_power_off(priv->phys[phy_num]); | ||
78 | phy_exit(priv->phys[phy_num]); | ||
79 | } | ||
80 | } | ||
72 | err_disable_clks: | 81 | err_disable_clks: |
73 | while (--clk >= 0) | 82 | while (--clk >= 0) |
74 | clk_disable_unprepare(priv->clks[clk]); | 83 | clk_disable_unprepare(priv->clks[clk]); |
@@ -80,11 +89,13 @@ static void ohci_platform_power_off(struct platform_device *dev) | |||
80 | { | 89 | { |
81 | struct usb_hcd *hcd = platform_get_drvdata(dev); | 90 | struct usb_hcd *hcd = platform_get_drvdata(dev); |
82 | struct ohci_platform_priv *priv = hcd_to_ohci_priv(hcd); | 91 | struct ohci_platform_priv *priv = hcd_to_ohci_priv(hcd); |
83 | int clk; | 92 | int clk, phy_num; |
84 | 93 | ||
85 | if (priv->phy) { | 94 | for (phy_num = 0; phy_num < priv->num_phys; phy_num++) { |
86 | phy_power_off(priv->phy); | 95 | if (priv->phys[phy_num]) { |
87 | phy_exit(priv->phy); | 96 | phy_power_off(priv->phys[phy_num]); |
97 | phy_exit(priv->phys[phy_num]); | ||
98 | } | ||
88 | } | 99 | } |
89 | 100 | ||
90 | for (clk = OHCI_MAX_CLKS - 1; clk >= 0; clk--) | 101 | for (clk = OHCI_MAX_CLKS - 1; clk >= 0; clk--) |
@@ -112,7 +123,8 @@ static int ohci_platform_probe(struct platform_device *dev) | |||
112 | struct usb_ohci_pdata *pdata = dev_get_platdata(&dev->dev); | 123 | struct usb_ohci_pdata *pdata = dev_get_platdata(&dev->dev); |
113 | struct ohci_platform_priv *priv; | 124 | struct ohci_platform_priv *priv; |
114 | struct ohci_hcd *ohci; | 125 | struct ohci_hcd *ohci; |
115 | int err, irq, clk = 0; | 126 | const char *phy_name; |
127 | int err, irq, phy_num, clk = 0; | ||
116 | 128 | ||
117 | if (usb_disabled()) | 129 | if (usb_disabled()) |
118 | return -ENODEV; | 130 | return -ENODEV; |
@@ -160,12 +172,38 @@ static int ohci_platform_probe(struct platform_device *dev) | |||
160 | of_property_read_u32(dev->dev.of_node, "num-ports", | 172 | of_property_read_u32(dev->dev.of_node, "num-ports", |
161 | &ohci->num_ports); | 173 | &ohci->num_ports); |
162 | 174 | ||
163 | priv->phy = devm_phy_get(&dev->dev, "usb"); | 175 | priv->num_phys = of_count_phandle_with_args(dev->dev.of_node, |
164 | if (IS_ERR(priv->phy)) { | 176 | "phys", "#phy-cells"); |
165 | err = PTR_ERR(priv->phy); | 177 | priv->num_phys = priv->num_phys > 0 ? priv->num_phys : 1; |
166 | if (err == -EPROBE_DEFER) | 178 | |
167 | goto err_put_hcd; | 179 | priv->phys = devm_kcalloc(&dev->dev, priv->num_phys, |
168 | priv->phy = NULL; | 180 | sizeof(struct phy *), GFP_KERNEL); |
181 | if (!priv->phys) | ||
182 | return -ENOMEM; | ||
183 | |||
184 | for (phy_num = 0; phy_num < priv->num_phys; phy_num++) { | ||
185 | err = of_property_read_string_index( | ||
186 | dev->dev.of_node, | ||
187 | "phy-names", phy_num, | ||
188 | &phy_name); | ||
189 | |||
190 | if (err < 0) { | ||
191 | if (priv->num_phys > 1) { | ||
192 | dev_err(&dev->dev, "phy-names not provided"); | ||
193 | goto err_put_hcd; | ||
194 | } else | ||
195 | phy_name = "usb"; | ||
196 | } | ||
197 | |||
198 | priv->phys[phy_num] = devm_phy_get(&dev->dev, | ||
199 | phy_name); | ||
200 | if (IS_ERR(priv->phys[phy_num])) { | ||
201 | err = PTR_ERR(priv->phys[phy_num]); | ||
202 | if ((priv->num_phys > 1) || | ||
203 | (err == -EPROBE_DEFER)) | ||
204 | goto err_put_hcd; | ||
205 | priv->phys[phy_num] = NULL; | ||
206 | } | ||
169 | } | 207 | } |
170 | 208 | ||
171 | for (clk = 0; clk < OHCI_MAX_CLKS; clk++) { | 209 | for (clk = 0; clk < OHCI_MAX_CLKS; clk++) { |
@@ -328,6 +366,7 @@ static int ohci_platform_resume(struct device *dev) | |||
328 | 366 | ||
329 | static const struct of_device_id ohci_platform_ids[] = { | 367 | static const struct of_device_id ohci_platform_ids[] = { |
330 | { .compatible = "generic-ohci", }, | 368 | { .compatible = "generic-ohci", }, |
369 | { .compatible = "cavium,octeon-6335-ohci", }, | ||
331 | { } | 370 | { } |
332 | }; | 371 | }; |
333 | MODULE_DEVICE_TABLE(of, ohci_platform_ids); | 372 | MODULE_DEVICE_TABLE(of, ohci_platform_ids); |
diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c index 965e3e9e688a..4f87a5c61b08 100644 --- a/drivers/usb/host/ohci-ppc-of.c +++ b/drivers/usb/host/ohci-ppc-of.c | |||
@@ -229,7 +229,6 @@ static struct platform_driver ohci_hcd_ppc_of_driver = { | |||
229 | .shutdown = usb_hcd_platform_shutdown, | 229 | .shutdown = usb_hcd_platform_shutdown, |
230 | .driver = { | 230 | .driver = { |
231 | .name = "ppc-of-ohci", | 231 | .name = "ppc-of-ohci", |
232 | .owner = THIS_MODULE, | ||
233 | .of_match_table = ohci_hcd_ppc_of_match, | 232 | .of_match_table = ohci_hcd_ppc_of_match, |
234 | }, | 233 | }, |
235 | }; | 234 | }; |
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index 095113ea1fcb..7a1919ca543a 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c | |||
@@ -249,14 +249,14 @@ static int ohci_s3c2410_hub_control( | |||
249 | */ | 249 | */ |
250 | 250 | ||
251 | desc->wHubCharacteristics &= ~cpu_to_le16(HUB_CHAR_LPSM); | 251 | desc->wHubCharacteristics &= ~cpu_to_le16(HUB_CHAR_LPSM); |
252 | desc->wHubCharacteristics |= cpu_to_le16(0x0001); | 252 | desc->wHubCharacteristics |= cpu_to_le16( |
253 | HUB_CHAR_INDV_PORT_LPSM); | ||
253 | 254 | ||
254 | if (info->enable_oc) { | 255 | if (info->enable_oc) { |
255 | desc->wHubCharacteristics &= ~cpu_to_le16( | 256 | desc->wHubCharacteristics &= ~cpu_to_le16( |
256 | HUB_CHAR_OCPM); | 257 | HUB_CHAR_OCPM); |
257 | desc->wHubCharacteristics |= cpu_to_le16( | 258 | desc->wHubCharacteristics |= cpu_to_le16( |
258 | 0x0008 | | 259 | HUB_CHAR_INDV_PORT_OCPM); |
259 | 0x0001); | ||
260 | } | 260 | } |
261 | 261 | ||
262 | dev_dbg(hcd->self.controller, "wHubCharacteristics after 0x%04x\n", | 262 | dev_dbg(hcd->self.controller, "wHubCharacteristics after 0x%04x\n", |
diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c index 4e81c804c73e..a8b8d8b8d9f3 100644 --- a/drivers/usb/host/ohci-sm501.c +++ b/drivers/usb/host/ohci-sm501.c | |||
@@ -265,7 +265,6 @@ static struct platform_driver ohci_hcd_sm501_driver = { | |||
265 | .suspend = ohci_sm501_suspend, | 265 | .suspend = ohci_sm501_suspend, |
266 | .resume = ohci_sm501_resume, | 266 | .resume = ohci_sm501_resume, |
267 | .driver = { | 267 | .driver = { |
268 | .owner = THIS_MODULE, | ||
269 | .name = "sm501-usb", | 268 | .name = "sm501-usb", |
270 | }, | 269 | }, |
271 | }; | 270 | }; |
diff --git a/drivers/usb/host/ohci-tilegx.c b/drivers/usb/host/ohci-tilegx.c index bef6dfb0405a..e1b208da460a 100644 --- a/drivers/usb/host/ohci-tilegx.c +++ b/drivers/usb/host/ohci-tilegx.c | |||
@@ -199,7 +199,6 @@ static struct platform_driver ohci_hcd_tilegx_driver = { | |||
199 | .shutdown = ohci_hcd_tilegx_drv_shutdown, | 199 | .shutdown = ohci_hcd_tilegx_drv_shutdown, |
200 | .driver = { | 200 | .driver = { |
201 | .name = "tilegx-ohci", | 201 | .name = "tilegx-ohci", |
202 | .owner = THIS_MODULE, | ||
203 | } | 202 | } |
204 | }; | 203 | }; |
205 | 204 | ||
diff --git a/drivers/usb/host/ohci-tmio.c b/drivers/usb/host/ohci-tmio.c index bb409588d39c..e9a6eec39142 100644 --- a/drivers/usb/host/ohci-tmio.c +++ b/drivers/usb/host/ohci-tmio.c | |||
@@ -368,6 +368,5 @@ static struct platform_driver ohci_hcd_tmio_driver = { | |||
368 | .resume = ohci_hcd_tmio_drv_resume, | 368 | .resume = ohci_hcd_tmio_drv_resume, |
369 | .driver = { | 369 | .driver = { |
370 | .name = "tmio-ohci", | 370 | .name = "tmio-ohci", |
371 | .owner = THIS_MODULE, | ||
372 | }, | 371 | }, |
373 | }; | 372 | }; |
diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c index 036924e640f5..ef7efb278b15 100644 --- a/drivers/usb/host/oxu210hp-hcd.c +++ b/drivers/usb/host/oxu210hp-hcd.c | |||
@@ -457,11 +457,11 @@ static void ehci_hub_descriptor(struct oxu_hcd *oxu, | |||
457 | memset(&desc->u.hs.DeviceRemovable[0], 0, temp); | 457 | memset(&desc->u.hs.DeviceRemovable[0], 0, temp); |
458 | memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp); | 458 | memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp); |
459 | 459 | ||
460 | temp = 0x0008; /* per-port overcurrent reporting */ | 460 | temp = HUB_CHAR_INDV_PORT_OCPM; /* per-port overcurrent reporting */ |
461 | if (HCS_PPC(oxu->hcs_params)) | 461 | if (HCS_PPC(oxu->hcs_params)) |
462 | temp |= 0x0001; /* per-port power control */ | 462 | temp |= HUB_CHAR_INDV_PORT_LPSM; /* per-port power control */ |
463 | else | 463 | else |
464 | temp |= 0x0002; /* no power switching */ | 464 | temp |= HUB_CHAR_NO_LPSM; /* no power switching */ |
465 | desc->wHubCharacteristics = (__force __u16)cpu_to_le16(temp); | 465 | desc->wHubCharacteristics = (__force __u16)cpu_to_le16(temp); |
466 | } | 466 | } |
467 | 467 | ||
@@ -2598,9 +2598,7 @@ static int oxu_hcd_init(struct usb_hcd *hcd) | |||
2598 | 2598 | ||
2599 | spin_lock_init(&oxu->lock); | 2599 | spin_lock_init(&oxu->lock); |
2600 | 2600 | ||
2601 | init_timer(&oxu->watchdog); | 2601 | setup_timer(&oxu->watchdog, oxu_watchdog, (unsigned long)oxu); |
2602 | oxu->watchdog.function = oxu_watchdog; | ||
2603 | oxu->watchdog.data = (unsigned long) oxu; | ||
2604 | 2602 | ||
2605 | /* | 2603 | /* |
2606 | * hw default: 1K periodic list heads, one per frame. | 2604 | * hw default: 1K periodic list heads, one per frame. |
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index ce636466edb7..f9400564cb72 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c | |||
@@ -603,9 +603,9 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev) | |||
603 | msleep(10); | 603 | msleep(10); |
604 | } | 604 | } |
605 | if (wait_time <= 0) | 605 | if (wait_time <= 0) |
606 | dev_warn(&pdev->dev, "OHCI: BIOS handoff failed" | 606 | dev_warn(&pdev->dev, |
607 | " (BIOS bug?) %08x\n", | 607 | "OHCI: BIOS handoff failed (BIOS bug?) %08x\n", |
608 | readl(base + OHCI_CONTROL)); | 608 | readl(base + OHCI_CONTROL)); |
609 | } | 609 | } |
610 | #endif | 610 | #endif |
611 | 611 | ||
@@ -733,8 +733,9 @@ static void ehci_bios_handoff(struct pci_dev *pdev, | |||
733 | * and hope nothing goes too wrong | 733 | * and hope nothing goes too wrong |
734 | */ | 734 | */ |
735 | if (try_handoff) | 735 | if (try_handoff) |
736 | dev_warn(&pdev->dev, "EHCI: BIOS handoff failed" | 736 | dev_warn(&pdev->dev, |
737 | " (BIOS bug?) %08x\n", cap); | 737 | "EHCI: BIOS handoff failed (BIOS bug?) %08x\n", |
738 | cap); | ||
738 | pci_write_config_byte(pdev, offset + 2, 0); | 739 | pci_write_config_byte(pdev, offset + 2, 0); |
739 | } | 740 | } |
740 | 741 | ||
@@ -781,8 +782,9 @@ static void quirk_usb_disable_ehci(struct pci_dev *pdev) | |||
781 | case 0: /* Illegal reserved cap, set cap=0 so we exit */ | 782 | case 0: /* Illegal reserved cap, set cap=0 so we exit */ |
782 | cap = 0; /* then fallthrough... */ | 783 | cap = 0; /* then fallthrough... */ |
783 | default: | 784 | default: |
784 | dev_warn(&pdev->dev, "EHCI: unrecognized capability " | 785 | dev_warn(&pdev->dev, |
785 | "%02x\n", cap & 0xff); | 786 | "EHCI: unrecognized capability %02x\n", |
787 | cap & 0xff); | ||
786 | } | 788 | } |
787 | offset = (cap >> 8) & 0xff; | 789 | offset = (cap >> 8) & 0xff; |
788 | } | 790 | } |
@@ -893,8 +895,7 @@ void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev) | |||
893 | */ | 895 | */ |
894 | if (!IS_ENABLED(CONFIG_USB_XHCI_HCD)) { | 896 | if (!IS_ENABLED(CONFIG_USB_XHCI_HCD)) { |
895 | dev_warn(&xhci_pdev->dev, | 897 | dev_warn(&xhci_pdev->dev, |
896 | "CONFIG_USB_XHCI_HCD is turned off, " | 898 | "CONFIG_USB_XHCI_HCD is turned off, defaulting to EHCI.\n"); |
897 | "defaulting to EHCI.\n"); | ||
898 | dev_warn(&xhci_pdev->dev, | 899 | dev_warn(&xhci_pdev->dev, |
899 | "USB 3.0 devices will work at USB 2.0 speeds.\n"); | 900 | "USB 3.0 devices will work at USB 2.0 speeds.\n"); |
900 | usb_disable_xhci_ports(xhci_pdev); | 901 | usb_disable_xhci_ports(xhci_pdev); |
@@ -919,8 +920,9 @@ void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev) | |||
919 | 920 | ||
920 | pci_read_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN, | 921 | pci_read_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN, |
921 | &ports_available); | 922 | &ports_available); |
922 | dev_dbg(&xhci_pdev->dev, "USB 3.0 ports that are now enabled " | 923 | dev_dbg(&xhci_pdev->dev, |
923 | "under xHCI: 0x%x\n", ports_available); | 924 | "USB 3.0 ports that are now enabled under xHCI: 0x%x\n", |
925 | ports_available); | ||
924 | 926 | ||
925 | /* Read XUSB2PRM, xHCI USB 2.0 Port Routing Mask Register | 927 | /* Read XUSB2PRM, xHCI USB 2.0 Port Routing Mask Register |
926 | * Indicate the USB 2.0 ports to be controlled by the xHCI host. | 928 | * Indicate the USB 2.0 ports to be controlled by the xHCI host. |
@@ -941,8 +943,9 @@ void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev) | |||
941 | 943 | ||
942 | pci_read_config_dword(xhci_pdev, USB_INTEL_XUSB2PR, | 944 | pci_read_config_dword(xhci_pdev, USB_INTEL_XUSB2PR, |
943 | &ports_available); | 945 | &ports_available); |
944 | dev_dbg(&xhci_pdev->dev, "USB 2.0 ports that are now switched over " | 946 | dev_dbg(&xhci_pdev->dev, |
945 | "to xHCI: 0x%x\n", ports_available); | 947 | "USB 2.0 ports that are now switched over to xHCI: 0x%x\n", |
948 | ports_available); | ||
946 | } | 949 | } |
947 | EXPORT_SYMBOL_GPL(usb_enable_intel_xhci_ports); | 950 | EXPORT_SYMBOL_GPL(usb_enable_intel_xhci_ports); |
948 | 951 | ||
@@ -1010,8 +1013,9 @@ static void quirk_usb_handoff_xhci(struct pci_dev *pdev) | |||
1010 | 1013 | ||
1011 | /* Assume a buggy BIOS and take HC ownership anyway */ | 1014 | /* Assume a buggy BIOS and take HC ownership anyway */ |
1012 | if (timeout) { | 1015 | if (timeout) { |
1013 | dev_warn(&pdev->dev, "xHCI BIOS handoff failed" | 1016 | dev_warn(&pdev->dev, |
1014 | " (BIOS bug ?) %08x\n", val); | 1017 | "xHCI BIOS handoff failed (BIOS bug ?) %08x\n", |
1018 | val); | ||
1015 | writel(val & ~XHCI_HC_BIOS_OWNED, base + ext_cap_offset); | 1019 | writel(val & ~XHCI_HC_BIOS_OWNED, base + ext_cap_offset); |
1016 | } | 1020 | } |
1017 | } | 1021 | } |
@@ -1039,8 +1043,8 @@ hc_init: | |||
1039 | if (timeout) { | 1043 | if (timeout) { |
1040 | val = readl(op_reg_base + XHCI_STS_OFFSET); | 1044 | val = readl(op_reg_base + XHCI_STS_OFFSET); |
1041 | dev_warn(&pdev->dev, | 1045 | dev_warn(&pdev->dev, |
1042 | "xHCI HW not ready after 5 sec (HC bug?) " | 1046 | "xHCI HW not ready after 5 sec (HC bug?) status = 0x%x\n", |
1043 | "status = 0x%x\n", val); | 1047 | val); |
1044 | } | 1048 | } |
1045 | 1049 | ||
1046 | /* Send the halt and disable interrupts command */ | 1050 | /* Send the halt and disable interrupts command */ |
@@ -1054,8 +1058,8 @@ hc_init: | |||
1054 | if (timeout) { | 1058 | if (timeout) { |
1055 | val = readl(op_reg_base + XHCI_STS_OFFSET); | 1059 | val = readl(op_reg_base + XHCI_STS_OFFSET); |
1056 | dev_warn(&pdev->dev, | 1060 | dev_warn(&pdev->dev, |
1057 | "xHCI HW did not halt within %d usec " | 1061 | "xHCI HW did not halt within %d usec status = 0x%x\n", |
1058 | "status = 0x%x\n", XHCI_MAX_HALT_USEC, val); | 1062 | XHCI_MAX_HALT_USEC, val); |
1059 | } | 1063 | } |
1060 | 1064 | ||
1061 | iounmap(base); | 1065 | iounmap(base); |
@@ -1075,8 +1079,8 @@ static void quirk_usb_early_handoff(struct pci_dev *pdev) | |||
1075 | return; | 1079 | return; |
1076 | 1080 | ||
1077 | if (pci_enable_device(pdev) < 0) { | 1081 | if (pci_enable_device(pdev) < 0) { |
1078 | dev_warn(&pdev->dev, "Can't enable PCI device, " | 1082 | dev_warn(&pdev->dev, |
1079 | "BIOS handoff failed.\n"); | 1083 | "Can't enable PCI device, BIOS handoff failed.\n"); |
1080 | return; | 1084 | return; |
1081 | } | 1085 | } |
1082 | if (pdev->class == PCI_CLASS_SERIAL_USB_UHCI) | 1086 | if (pdev->class == PCI_CLASS_SERIAL_USB_UHCI) |
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index c4bcfaedeec9..bdc82fea0a1f 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c | |||
@@ -2141,7 +2141,8 @@ static void r8a66597_hub_descriptor(struct r8a66597 *r8a66597, | |||
2141 | desc->bNbrPorts = r8a66597->max_root_hub; | 2141 | desc->bNbrPorts = r8a66597->max_root_hub; |
2142 | desc->bDescLength = 9; | 2142 | desc->bDescLength = 9; |
2143 | desc->bPwrOn2PwrGood = 0; | 2143 | desc->bPwrOn2PwrGood = 0; |
2144 | desc->wHubCharacteristics = cpu_to_le16(0x0011); | 2144 | desc->wHubCharacteristics = |
2145 | cpu_to_le16(HUB_CHAR_INDV_PORT_LPSM | HUB_CHAR_NO_OCPM); | ||
2145 | desc->u.hs.DeviceRemovable[0] = | 2146 | desc->u.hs.DeviceRemovable[0] = |
2146 | ((1 << r8a66597->max_root_hub) - 1) << 1; | 2147 | ((1 << r8a66597->max_root_hub) - 1) << 1; |
2147 | desc->u.hs.DeviceRemovable[1] = ~0; | 2148 | desc->u.hs.DeviceRemovable[1] = ~0; |
@@ -2483,9 +2484,8 @@ static int r8a66597_probe(struct platform_device *pdev) | |||
2483 | r8a66597->max_root_hub = 2; | 2484 | r8a66597->max_root_hub = 2; |
2484 | 2485 | ||
2485 | spin_lock_init(&r8a66597->lock); | 2486 | spin_lock_init(&r8a66597->lock); |
2486 | init_timer(&r8a66597->rh_timer); | 2487 | setup_timer(&r8a66597->rh_timer, r8a66597_timer, |
2487 | r8a66597->rh_timer.function = r8a66597_timer; | 2488 | (unsigned long)r8a66597); |
2488 | r8a66597->rh_timer.data = (unsigned long)r8a66597; | ||
2489 | r8a66597->reg = reg; | 2489 | r8a66597->reg = reg; |
2490 | 2490 | ||
2491 | /* make sure no interrupts are pending */ | 2491 | /* make sure no interrupts are pending */ |
@@ -2496,9 +2496,8 @@ static int r8a66597_probe(struct platform_device *pdev) | |||
2496 | 2496 | ||
2497 | for (i = 0; i < R8A66597_MAX_NUM_PIPE; i++) { | 2497 | for (i = 0; i < R8A66597_MAX_NUM_PIPE; i++) { |
2498 | INIT_LIST_HEAD(&r8a66597->pipe_queue[i]); | 2498 | INIT_LIST_HEAD(&r8a66597->pipe_queue[i]); |
2499 | init_timer(&r8a66597->td_timer[i]); | 2499 | setup_timer(&r8a66597->td_timer[i], r8a66597_td_timer, |
2500 | r8a66597->td_timer[i].function = r8a66597_td_timer; | 2500 | (unsigned long)r8a66597); |
2501 | r8a66597->td_timer[i].data = (unsigned long)r8a66597; | ||
2502 | setup_timer(&r8a66597->interval_timer[i], | 2501 | setup_timer(&r8a66597->interval_timer[i], |
2503 | r8a66597_interval_timer, | 2502 | r8a66597_interval_timer, |
2504 | (unsigned long)r8a66597); | 2503 | (unsigned long)r8a66597); |
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index 25fb1da8d3d7..4f4ba1ea9e9b 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c | |||
@@ -1103,12 +1103,12 @@ sl811h_hub_descriptor ( | |||
1103 | desc->bPwrOn2PwrGood = sl811->board->potpg; | 1103 | desc->bPwrOn2PwrGood = sl811->board->potpg; |
1104 | if (!desc->bPwrOn2PwrGood) | 1104 | if (!desc->bPwrOn2PwrGood) |
1105 | desc->bPwrOn2PwrGood = 10; | 1105 | desc->bPwrOn2PwrGood = 10; |
1106 | temp = 0x0001; | 1106 | temp = HUB_CHAR_INDV_PORT_LPSM; |
1107 | } else | 1107 | } else |
1108 | temp = 0x0002; | 1108 | temp = HUB_CHAR_NO_LPSM; |
1109 | 1109 | ||
1110 | /* no overcurrent errors detection/handling */ | 1110 | /* no overcurrent errors detection/handling */ |
1111 | temp |= 0x0010; | 1111 | temp |= HUB_CHAR_NO_OCPM; |
1112 | 1112 | ||
1113 | desc->wHubCharacteristics = cpu_to_le16(temp); | 1113 | desc->wHubCharacteristics = cpu_to_le16(temp); |
1114 | 1114 | ||
@@ -1691,9 +1691,7 @@ sl811h_probe(struct platform_device *dev) | |||
1691 | spin_lock_init(&sl811->lock); | 1691 | spin_lock_init(&sl811->lock); |
1692 | INIT_LIST_HEAD(&sl811->async); | 1692 | INIT_LIST_HEAD(&sl811->async); |
1693 | sl811->board = dev_get_platdata(&dev->dev); | 1693 | sl811->board = dev_get_platdata(&dev->dev); |
1694 | init_timer(&sl811->timer); | 1694 | setup_timer(&sl811->timer, sl811h_timer, (unsigned long)sl811); |
1695 | sl811->timer.function = sl811h_timer; | ||
1696 | sl811->timer.data = (unsigned long) sl811; | ||
1697 | sl811->addr_reg = addr_reg; | 1695 | sl811->addr_reg = addr_reg; |
1698 | sl811->data_reg = data_reg; | 1696 | sl811->data_reg = data_reg; |
1699 | 1697 | ||
diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index 2894e54e5b9c..ad97e8a1ad1c 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c | |||
@@ -2590,15 +2590,15 @@ static int u132_roothub_descriptor(struct u132 *u132, | |||
2590 | desc->bNbrPorts = u132->num_ports; | 2590 | desc->bNbrPorts = u132->num_ports; |
2591 | temp = 1 + (u132->num_ports / 8); | 2591 | temp = 1 + (u132->num_ports / 8); |
2592 | desc->bDescLength = 7 + 2 * temp; | 2592 | desc->bDescLength = 7 + 2 * temp; |
2593 | temp = 0; | 2593 | temp = HUB_CHAR_COMMON_LPSM | HUB_CHAR_COMMON_OCPM; |
2594 | if (rh_a & RH_A_NPS) | 2594 | if (rh_a & RH_A_NPS) |
2595 | temp |= 0x0002; | 2595 | temp |= HUB_CHAR_NO_LPSM; |
2596 | if (rh_a & RH_A_PSM) | 2596 | if (rh_a & RH_A_PSM) |
2597 | temp |= 0x0001; | 2597 | temp |= HUB_CHAR_INDV_PORT_LPSM; |
2598 | if (rh_a & RH_A_NOCP) | 2598 | if (rh_a & RH_A_NOCP) |
2599 | temp |= 0x0010; | 2599 | temp |= HUB_CHAR_NO_OCPM; |
2600 | else if (rh_a & RH_A_OCPM) | 2600 | else if (rh_a & RH_A_OCPM) |
2601 | temp |= 0x0008; | 2601 | temp |= HUB_CHAR_INDV_PORT_OCPM; |
2602 | desc->wHubCharacteristics = cpu_to_le16(temp); | 2602 | desc->wHubCharacteristics = cpu_to_le16(temp); |
2603 | retval = u132_read_pcimem(u132, roothub.b, &rh_b); | 2603 | retval = u132_read_pcimem(u132, roothub.b, &rh_b); |
2604 | if (retval) | 2604 | if (retval) |
diff --git a/drivers/usb/host/uhci-grlib.c b/drivers/usb/host/uhci-grlib.c index 05f57ffdf9ab..0342991c9507 100644 --- a/drivers/usb/host/uhci-grlib.c +++ b/drivers/usb/host/uhci-grlib.c | |||
@@ -188,7 +188,6 @@ static struct platform_driver uhci_grlib_driver = { | |||
188 | .shutdown = uhci_hcd_grlib_shutdown, | 188 | .shutdown = uhci_hcd_grlib_shutdown, |
189 | .driver = { | 189 | .driver = { |
190 | .name = "grlib-uhci", | 190 | .name = "grlib-uhci", |
191 | .owner = THIS_MODULE, | ||
192 | .of_match_table = uhci_hcd_grlib_of_match, | 191 | .of_match_table = uhci_hcd_grlib_of_match, |
193 | }, | 192 | }, |
194 | }; | 193 | }; |
diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c index 93e17b12fb33..19ba5eafb31e 100644 --- a/drivers/usb/host/uhci-hub.c +++ b/drivers/usb/host/uhci-hub.c | |||
@@ -17,8 +17,9 @@ static const __u8 root_hub_hub_des[] = | |||
17 | 0x09, /* __u8 bLength; */ | 17 | 0x09, /* __u8 bLength; */ |
18 | 0x29, /* __u8 bDescriptorType; Hub-descriptor */ | 18 | 0x29, /* __u8 bDescriptorType; Hub-descriptor */ |
19 | 0x02, /* __u8 bNbrPorts; */ | 19 | 0x02, /* __u8 bNbrPorts; */ |
20 | 0x0a, /* __u16 wHubCharacteristics; */ | 20 | HUB_CHAR_NO_LPSM | /* __u16 wHubCharacteristics; */ |
21 | 0x00, /* (per-port OC, no power switching) */ | 21 | HUB_CHAR_INDV_PORT_OCPM, /* (per-port OC, no power switching) */ |
22 | 0x00, | ||
22 | 0x01, /* __u8 bPwrOn2pwrGood; 2ms */ | 23 | 0x01, /* __u8 bPwrOn2pwrGood; 2ms */ |
23 | 0x00, /* __u8 bHubContrCurrent; 0 mA */ | 24 | 0x00, /* __u8 bHubContrCurrent; 0 mA */ |
24 | 0x00, /* __u8 DeviceRemovable; *** 7 Ports max */ | 25 | 0x00, /* __u8 DeviceRemovable; *** 7 Ports max */ |
diff --git a/drivers/usb/host/uhci-platform.c b/drivers/usb/host/uhci-platform.c index cf8f46003f62..3a3e3eeba291 100644 --- a/drivers/usb/host/uhci-platform.c +++ b/drivers/usb/host/uhci-platform.c | |||
@@ -147,7 +147,6 @@ static struct platform_driver uhci_platform_driver = { | |||
147 | .shutdown = uhci_hcd_platform_shutdown, | 147 | .shutdown = uhci_hcd_platform_shutdown, |
148 | .driver = { | 148 | .driver = { |
149 | .name = "platform-uhci", | 149 | .name = "platform-uhci", |
150 | .owner = THIS_MODULE, | ||
151 | .of_match_table = platform_uhci_ids, | 150 | .of_match_table = platform_uhci_ids, |
152 | }, | 151 | }, |
153 | }; | 152 | }; |
diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c index bb89175ca6e5..745717ec9c89 100644 --- a/drivers/usb/host/xhci-dbg.c +++ b/drivers/usb/host/xhci-dbg.c | |||
@@ -552,7 +552,7 @@ void xhci_dbg_ctx(struct xhci_hcd *xhci, | |||
552 | 552 | ||
553 | if (ctx->type == XHCI_CTX_TYPE_INPUT) { | 553 | if (ctx->type == XHCI_CTX_TYPE_INPUT) { |
554 | struct xhci_input_control_ctx *ctrl_ctx = | 554 | struct xhci_input_control_ctx *ctrl_ctx = |
555 | xhci_get_input_control_ctx(xhci, ctx); | 555 | xhci_get_input_control_ctx(ctx); |
556 | if (!ctrl_ctx) { | 556 | if (!ctrl_ctx) { |
557 | xhci_warn(xhci, "Could not get input context, bad type.\n"); | 557 | xhci_warn(xhci, "Could not get input context, bad type.\n"); |
558 | return; | 558 | return; |
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 5cb3d7a10017..f8336408ef07 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
@@ -535,7 +535,7 @@ static void xhci_free_container_ctx(struct xhci_hcd *xhci, | |||
535 | kfree(ctx); | 535 | kfree(ctx); |
536 | } | 536 | } |
537 | 537 | ||
538 | struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_hcd *xhci, | 538 | struct xhci_input_control_ctx *xhci_get_input_control_ctx( |
539 | struct xhci_container_ctx *ctx) | 539 | struct xhci_container_ctx *ctx) |
540 | { | 540 | { |
541 | if (ctx->type != XHCI_CTX_TYPE_INPUT) | 541 | if (ctx->type != XHCI_CTX_TYPE_INPUT) |
@@ -784,8 +784,7 @@ void xhci_setup_streams_ep_input_ctx(struct xhci_hcd *xhci, | |||
784 | * Reinstalls the "normal" endpoint ring (at its previous dequeue mark, | 784 | * Reinstalls the "normal" endpoint ring (at its previous dequeue mark, |
785 | * not at the beginning of the ring). | 785 | * not at the beginning of the ring). |
786 | */ | 786 | */ |
787 | void xhci_setup_no_streams_ep_input_ctx(struct xhci_hcd *xhci, | 787 | void xhci_setup_no_streams_ep_input_ctx(struct xhci_ep_ctx *ep_ctx, |
788 | struct xhci_ep_ctx *ep_ctx, | ||
789 | struct xhci_virt_ep *ep) | 788 | struct xhci_virt_ep *ep) |
790 | { | 789 | { |
791 | dma_addr_t addr; | 790 | dma_addr_t addr; |
@@ -833,9 +832,8 @@ void xhci_free_stream_info(struct xhci_hcd *xhci, | |||
833 | static void xhci_init_endpoint_timer(struct xhci_hcd *xhci, | 832 | static void xhci_init_endpoint_timer(struct xhci_hcd *xhci, |
834 | struct xhci_virt_ep *ep) | 833 | struct xhci_virt_ep *ep) |
835 | { | 834 | { |
836 | init_timer(&ep->stop_cmd_timer); | 835 | setup_timer(&ep->stop_cmd_timer, xhci_stop_endpoint_command_watchdog, |
837 | ep->stop_cmd_timer.data = (unsigned long) ep; | 836 | (unsigned long)ep); |
838 | ep->stop_cmd_timer.function = xhci_stop_endpoint_command_watchdog; | ||
839 | ep->xhci = xhci; | 837 | ep->xhci = xhci; |
840 | } | 838 | } |
841 | 839 | ||
@@ -1342,8 +1340,7 @@ static u32 xhci_get_endpoint_mult(struct usb_device *udev, | |||
1342 | return ep->ss_ep_comp.bmAttributes; | 1340 | return ep->ss_ep_comp.bmAttributes; |
1343 | } | 1341 | } |
1344 | 1342 | ||
1345 | static u32 xhci_get_endpoint_type(struct usb_device *udev, | 1343 | static u32 xhci_get_endpoint_type(struct usb_host_endpoint *ep) |
1346 | struct usb_host_endpoint *ep) | ||
1347 | { | 1344 | { |
1348 | int in; | 1345 | int in; |
1349 | u32 type; | 1346 | u32 type; |
@@ -1376,8 +1373,7 @@ static u32 xhci_get_endpoint_type(struct usb_device *udev, | |||
1376 | * Basically, this is the maxpacket size, multiplied by the burst size | 1373 | * Basically, this is the maxpacket size, multiplied by the burst size |
1377 | * and mult size. | 1374 | * and mult size. |
1378 | */ | 1375 | */ |
1379 | static u32 xhci_get_max_esit_payload(struct xhci_hcd *xhci, | 1376 | static u32 xhci_get_max_esit_payload(struct usb_device *udev, |
1380 | struct usb_device *udev, | ||
1381 | struct usb_host_endpoint *ep) | 1377 | struct usb_host_endpoint *ep) |
1382 | { | 1378 | { |
1383 | int max_burst; | 1379 | int max_burst; |
@@ -1418,7 +1414,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, | |||
1418 | ep_index = xhci_get_endpoint_index(&ep->desc); | 1414 | ep_index = xhci_get_endpoint_index(&ep->desc); |
1419 | ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index); | 1415 | ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index); |
1420 | 1416 | ||
1421 | endpoint_type = xhci_get_endpoint_type(udev, ep); | 1417 | endpoint_type = xhci_get_endpoint_type(ep); |
1422 | if (!endpoint_type) | 1418 | if (!endpoint_type) |
1423 | return -EINVAL; | 1419 | return -EINVAL; |
1424 | ep_ctx->ep_info2 = cpu_to_le32(endpoint_type); | 1420 | ep_ctx->ep_info2 = cpu_to_le32(endpoint_type); |
@@ -1484,7 +1480,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, | |||
1484 | } | 1480 | } |
1485 | ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet) | | 1481 | ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet) | |
1486 | MAX_BURST(max_burst)); | 1482 | MAX_BURST(max_burst)); |
1487 | max_esit_payload = xhci_get_max_esit_payload(xhci, udev, ep); | 1483 | max_esit_payload = xhci_get_max_esit_payload(udev, ep); |
1488 | ep_ctx->tx_info = cpu_to_le32(MAX_ESIT_PAYLOAD_FOR_EP(max_esit_payload)); | 1484 | ep_ctx->tx_info = cpu_to_le32(MAX_ESIT_PAYLOAD_FOR_EP(max_esit_payload)); |
1489 | 1485 | ||
1490 | /* | 1486 | /* |
@@ -1773,7 +1769,7 @@ struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci, | |||
1773 | return command; | 1769 | return command; |
1774 | } | 1770 | } |
1775 | 1771 | ||
1776 | void xhci_urb_free_priv(struct xhci_hcd *xhci, struct urb_priv *urb_priv) | 1772 | void xhci_urb_free_priv(struct urb_priv *urb_priv) |
1777 | { | 1773 | { |
1778 | if (urb_priv) { | 1774 | if (urb_priv) { |
1779 | kfree(urb_priv->td[0]); | 1775 | kfree(urb_priv->td[0]); |
@@ -1926,7 +1922,7 @@ static int xhci_test_trb_in_td(struct xhci_hcd *xhci, | |||
1926 | } | 1922 | } |
1927 | 1923 | ||
1928 | /* TRB math checks for xhci_trb_in_td(), using the command and event rings. */ | 1924 | /* TRB math checks for xhci_trb_in_td(), using the command and event rings. */ |
1929 | static int xhci_check_trb_in_td_math(struct xhci_hcd *xhci, gfp_t mem_flags) | 1925 | static int xhci_check_trb_in_td_math(struct xhci_hcd *xhci) |
1930 | { | 1926 | { |
1931 | struct { | 1927 | struct { |
1932 | dma_addr_t input_dma; | 1928 | dma_addr_t input_dma; |
@@ -2452,7 +2448,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) | |||
2452 | flags); | 2448 | flags); |
2453 | if (!xhci->event_ring) | 2449 | if (!xhci->event_ring) |
2454 | goto fail; | 2450 | goto fail; |
2455 | if (xhci_check_trb_in_td_math(xhci, flags) < 0) | 2451 | if (xhci_check_trb_in_td_math(xhci) < 0) |
2456 | goto fail; | 2452 | goto fail; |
2457 | 2453 | ||
2458 | xhci->erst.entries = dma_alloc_coherent(dev, | 2454 | xhci->erst.entries = dma_alloc_coherent(dev, |
@@ -2509,9 +2505,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) | |||
2509 | xhci_print_ir_set(xhci, 0); | 2505 | xhci_print_ir_set(xhci, 0); |
2510 | 2506 | ||
2511 | /* init command timeout timer */ | 2507 | /* init command timeout timer */ |
2512 | init_timer(&xhci->cmd_timer); | 2508 | setup_timer(&xhci->cmd_timer, xhci_handle_command_timeout, |
2513 | xhci->cmd_timer.data = (unsigned long) xhci; | 2509 | (unsigned long)xhci); |
2514 | xhci->cmd_timer.function = xhci_handle_command_timeout; | ||
2515 | 2510 | ||
2516 | /* | 2511 | /* |
2517 | * XXX: Might need to set the Interrupter Moderation Register to | 2512 | * XXX: Might need to set the Interrupter Moderation Register to |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index e692e769c50c..88da8d629820 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -299,7 +299,7 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci) | |||
299 | * seconds), then it should assume that the there are | 299 | * seconds), then it should assume that the there are |
300 | * larger problems with the xHC and assert HCRST. | 300 | * larger problems with the xHC and assert HCRST. |
301 | */ | 301 | */ |
302 | ret = xhci_handshake(xhci, &xhci->op_regs->cmd_ring, | 302 | ret = xhci_handshake(&xhci->op_regs->cmd_ring, |
303 | CMD_RING_RUNNING, 0, 5 * 1000 * 1000); | 303 | CMD_RING_RUNNING, 0, 5 * 1000 * 1000); |
304 | if (ret < 0) { | 304 | if (ret < 0) { |
305 | xhci_err(xhci, "Stopped the command ring failed, " | 305 | xhci_err(xhci, "Stopped the command ring failed, " |
@@ -609,7 +609,7 @@ static void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci, | |||
609 | 609 | ||
610 | spin_unlock(&xhci->lock); | 610 | spin_unlock(&xhci->lock); |
611 | usb_hcd_giveback_urb(hcd, urb, status); | 611 | usb_hcd_giveback_urb(hcd, urb, status); |
612 | xhci_urb_free_priv(xhci, urb_priv); | 612 | xhci_urb_free_priv(urb_priv); |
613 | spin_lock(&xhci->lock); | 613 | spin_lock(&xhci->lock); |
614 | } | 614 | } |
615 | } | 615 | } |
@@ -1110,7 +1110,7 @@ static void xhci_handle_cmd_config_ep(struct xhci_hcd *xhci, int slot_id, | |||
1110 | * is not waiting on the configure endpoint command. | 1110 | * is not waiting on the configure endpoint command. |
1111 | */ | 1111 | */ |
1112 | virt_dev = xhci->devs[slot_id]; | 1112 | virt_dev = xhci->devs[slot_id]; |
1113 | ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); | 1113 | ctrl_ctx = xhci_get_input_control_ctx(virt_dev->in_ctx); |
1114 | if (!ctrl_ctx) { | 1114 | if (!ctrl_ctx) { |
1115 | xhci_warn(xhci, "Could not get input context, bad type.\n"); | 1115 | xhci_warn(xhci, "Could not get input context, bad type.\n"); |
1116 | return; | 1116 | return; |
@@ -2354,8 +2354,8 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
2354 | status = 0; | 2354 | status = 0; |
2355 | break; | 2355 | break; |
2356 | } | 2356 | } |
2357 | xhci_warn(xhci, "ERROR Unknown event condition, HC probably " | 2357 | xhci_warn(xhci, "ERROR Unknown event condition %u, HC probably busted\n", |
2358 | "busted\n"); | 2358 | trb_comp_code); |
2359 | goto cleanup; | 2359 | goto cleanup; |
2360 | } | 2360 | } |
2361 | 2361 | ||
@@ -2497,7 +2497,7 @@ cleanup: | |||
2497 | urb = td->urb; | 2497 | urb = td->urb; |
2498 | urb_priv = urb->hcpriv; | 2498 | urb_priv = urb->hcpriv; |
2499 | 2499 | ||
2500 | xhci_urb_free_priv(xhci, urb_priv); | 2500 | xhci_urb_free_priv(urb_priv); |
2501 | 2501 | ||
2502 | usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb); | 2502 | usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb); |
2503 | if ((urb->actual_length != urb->transfer_buffer_length && | 2503 | if ((urb->actual_length != urb->transfer_buffer_length && |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index c50d8d202618..ec8ac1674854 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -60,8 +60,7 @@ MODULE_PARM_DESC(quirks, "Bit flags for quirks to be enabled as default"); | |||
60 | * handshake done). There are two failure modes: "usec" have passed (major | 60 | * handshake done). There are two failure modes: "usec" have passed (major |
61 | * hardware flakeout), or the register reads as all-ones (hardware removed). | 61 | * hardware flakeout), or the register reads as all-ones (hardware removed). |
62 | */ | 62 | */ |
63 | int xhci_handshake(struct xhci_hcd *xhci, void __iomem *ptr, | 63 | int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, int usec) |
64 | u32 mask, u32 done, int usec) | ||
65 | { | 64 | { |
66 | u32 result; | 65 | u32 result; |
67 | 66 | ||
@@ -111,7 +110,7 @@ int xhci_halt(struct xhci_hcd *xhci) | |||
111 | xhci_dbg_trace(xhci, trace_xhci_dbg_init, "// Halt the HC"); | 110 | xhci_dbg_trace(xhci, trace_xhci_dbg_init, "// Halt the HC"); |
112 | xhci_quiesce(xhci); | 111 | xhci_quiesce(xhci); |
113 | 112 | ||
114 | ret = xhci_handshake(xhci, &xhci->op_regs->status, | 113 | ret = xhci_handshake(&xhci->op_regs->status, |
115 | STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC); | 114 | STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC); |
116 | if (!ret) { | 115 | if (!ret) { |
117 | xhci->xhc_state |= XHCI_STATE_HALTED; | 116 | xhci->xhc_state |= XHCI_STATE_HALTED; |
@@ -140,7 +139,7 @@ static int xhci_start(struct xhci_hcd *xhci) | |||
140 | * Wait for the HCHalted Status bit to be 0 to indicate the host is | 139 | * Wait for the HCHalted Status bit to be 0 to indicate the host is |
141 | * running. | 140 | * running. |
142 | */ | 141 | */ |
143 | ret = xhci_handshake(xhci, &xhci->op_regs->status, | 142 | ret = xhci_handshake(&xhci->op_regs->status, |
144 | STS_HALT, 0, XHCI_MAX_HALT_USEC); | 143 | STS_HALT, 0, XHCI_MAX_HALT_USEC); |
145 | if (ret == -ETIMEDOUT) | 144 | if (ret == -ETIMEDOUT) |
146 | xhci_err(xhci, "Host took too long to start, " | 145 | xhci_err(xhci, "Host took too long to start, " |
@@ -175,7 +174,7 @@ int xhci_reset(struct xhci_hcd *xhci) | |||
175 | command |= CMD_RESET; | 174 | command |= CMD_RESET; |
176 | writel(command, &xhci->op_regs->command); | 175 | writel(command, &xhci->op_regs->command); |
177 | 176 | ||
178 | ret = xhci_handshake(xhci, &xhci->op_regs->command, | 177 | ret = xhci_handshake(&xhci->op_regs->command, |
179 | CMD_RESET, 0, 10 * 1000 * 1000); | 178 | CMD_RESET, 0, 10 * 1000 * 1000); |
180 | if (ret) | 179 | if (ret) |
181 | return ret; | 180 | return ret; |
@@ -186,7 +185,7 @@ int xhci_reset(struct xhci_hcd *xhci) | |||
186 | * xHCI cannot write to any doorbells or operational registers other | 185 | * xHCI cannot write to any doorbells or operational registers other |
187 | * than status until the "Controller Not Ready" flag is cleared. | 186 | * than status until the "Controller Not Ready" flag is cleared. |
188 | */ | 187 | */ |
189 | ret = xhci_handshake(xhci, &xhci->op_regs->status, | 188 | ret = xhci_handshake(&xhci->op_regs->status, |
190 | STS_CNR, 0, 10 * 1000 * 1000); | 189 | STS_CNR, 0, 10 * 1000 * 1000); |
191 | 190 | ||
192 | for (i = 0; i < 2; ++i) { | 191 | for (i = 0; i < 2; ++i) { |
@@ -473,10 +472,8 @@ static void compliance_mode_recovery(unsigned long arg) | |||
473 | static void compliance_mode_recovery_timer_init(struct xhci_hcd *xhci) | 472 | static void compliance_mode_recovery_timer_init(struct xhci_hcd *xhci) |
474 | { | 473 | { |
475 | xhci->port_status_u0 = 0; | 474 | xhci->port_status_u0 = 0; |
476 | init_timer(&xhci->comp_mode_recovery_timer); | 475 | setup_timer(&xhci->comp_mode_recovery_timer, |
477 | 476 | compliance_mode_recovery, (unsigned long)xhci); | |
478 | xhci->comp_mode_recovery_timer.data = (unsigned long) xhci; | ||
479 | xhci->comp_mode_recovery_timer.function = compliance_mode_recovery; | ||
480 | xhci->comp_mode_recovery_timer.expires = jiffies + | 477 | xhci->comp_mode_recovery_timer.expires = jiffies + |
481 | msecs_to_jiffies(COMP_MODE_RCVRY_MSECS); | 478 | msecs_to_jiffies(COMP_MODE_RCVRY_MSECS); |
482 | 479 | ||
@@ -929,7 +926,7 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup) | |||
929 | /* Some chips from Fresco Logic need an extraordinary delay */ | 926 | /* Some chips from Fresco Logic need an extraordinary delay */ |
930 | delay *= (xhci->quirks & XHCI_SLOW_SUSPEND) ? 10 : 1; | 927 | delay *= (xhci->quirks & XHCI_SLOW_SUSPEND) ? 10 : 1; |
931 | 928 | ||
932 | if (xhci_handshake(xhci, &xhci->op_regs->status, | 929 | if (xhci_handshake(&xhci->op_regs->status, |
933 | STS_HALT, STS_HALT, delay)) { | 930 | STS_HALT, STS_HALT, delay)) { |
934 | xhci_warn(xhci, "WARN: xHC CMD_RUN timeout\n"); | 931 | xhci_warn(xhci, "WARN: xHC CMD_RUN timeout\n"); |
935 | spin_unlock_irq(&xhci->lock); | 932 | spin_unlock_irq(&xhci->lock); |
@@ -944,7 +941,7 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup) | |||
944 | command = readl(&xhci->op_regs->command); | 941 | command = readl(&xhci->op_regs->command); |
945 | command |= CMD_CSS; | 942 | command |= CMD_CSS; |
946 | writel(command, &xhci->op_regs->command); | 943 | writel(command, &xhci->op_regs->command); |
947 | if (xhci_handshake(xhci, &xhci->op_regs->status, | 944 | if (xhci_handshake(&xhci->op_regs->status, |
948 | STS_SAVE, 0, 10 * 1000)) { | 945 | STS_SAVE, 0, 10 * 1000)) { |
949 | xhci_warn(xhci, "WARN: xHC save state timeout\n"); | 946 | xhci_warn(xhci, "WARN: xHC save state timeout\n"); |
950 | spin_unlock_irq(&xhci->lock); | 947 | spin_unlock_irq(&xhci->lock); |
@@ -1011,7 +1008,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) | |||
1011 | command = readl(&xhci->op_regs->command); | 1008 | command = readl(&xhci->op_regs->command); |
1012 | command |= CMD_CRS; | 1009 | command |= CMD_CRS; |
1013 | writel(command, &xhci->op_regs->command); | 1010 | writel(command, &xhci->op_regs->command); |
1014 | if (xhci_handshake(xhci, &xhci->op_regs->status, | 1011 | if (xhci_handshake(&xhci->op_regs->status, |
1015 | STS_RESTORE, 0, 10 * 1000)) { | 1012 | STS_RESTORE, 0, 10 * 1000)) { |
1016 | xhci_warn(xhci, "WARN: xHC restore state timeout\n"); | 1013 | xhci_warn(xhci, "WARN: xHC restore state timeout\n"); |
1017 | spin_unlock_irq(&xhci->lock); | 1014 | spin_unlock_irq(&xhci->lock); |
@@ -1082,7 +1079,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) | |||
1082 | command = readl(&xhci->op_regs->command); | 1079 | command = readl(&xhci->op_regs->command); |
1083 | command |= CMD_RUN; | 1080 | command |= CMD_RUN; |
1084 | writel(command, &xhci->op_regs->command); | 1081 | writel(command, &xhci->op_regs->command); |
1085 | xhci_handshake(xhci, &xhci->op_regs->status, STS_HALT, | 1082 | xhci_handshake(&xhci->op_regs->status, STS_HALT, |
1086 | 0, 250 * 1000); | 1083 | 0, 250 * 1000); |
1087 | 1084 | ||
1088 | /* step 5: walk topology and initialize portsc, | 1085 | /* step 5: walk topology and initialize portsc, |
@@ -1276,7 +1273,7 @@ static int xhci_check_maxpacket(struct xhci_hcd *xhci, unsigned int slot_id, | |||
1276 | return -ENOMEM; | 1273 | return -ENOMEM; |
1277 | 1274 | ||
1278 | command->in_ctx = xhci->devs[slot_id]->in_ctx; | 1275 | command->in_ctx = xhci->devs[slot_id]->in_ctx; |
1279 | ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx); | 1276 | ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx); |
1280 | if (!ctrl_ctx) { | 1277 | if (!ctrl_ctx) { |
1281 | xhci_warn(xhci, "%s: Could not get input context, bad type.\n", | 1278 | xhci_warn(xhci, "%s: Could not get input context, bad type.\n", |
1282 | __func__); | 1279 | __func__); |
@@ -1374,7 +1371,7 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) | |||
1374 | ret = xhci_check_maxpacket(xhci, slot_id, | 1371 | ret = xhci_check_maxpacket(xhci, slot_id, |
1375 | ep_index, urb); | 1372 | ep_index, urb); |
1376 | if (ret < 0) { | 1373 | if (ret < 0) { |
1377 | xhci_urb_free_priv(xhci, urb_priv); | 1374 | xhci_urb_free_priv(urb_priv); |
1378 | urb->hcpriv = NULL; | 1375 | urb->hcpriv = NULL; |
1379 | return ret; | 1376 | return ret; |
1380 | } | 1377 | } |
@@ -1440,7 +1437,7 @@ dying: | |||
1440 | urb->ep->desc.bEndpointAddress, urb); | 1437 | urb->ep->desc.bEndpointAddress, urb); |
1441 | ret = -ESHUTDOWN; | 1438 | ret = -ESHUTDOWN; |
1442 | free_priv: | 1439 | free_priv: |
1443 | xhci_urb_free_priv(xhci, urb_priv); | 1440 | xhci_urb_free_priv(urb_priv); |
1444 | urb->hcpriv = NULL; | 1441 | urb->hcpriv = NULL; |
1445 | spin_unlock_irqrestore(&xhci->lock, flags); | 1442 | spin_unlock_irqrestore(&xhci->lock, flags); |
1446 | return ret; | 1443 | return ret; |
@@ -1553,7 +1550,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
1553 | usb_hcd_unlink_urb_from_ep(hcd, urb); | 1550 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
1554 | spin_unlock_irqrestore(&xhci->lock, flags); | 1551 | spin_unlock_irqrestore(&xhci->lock, flags); |
1555 | usb_hcd_giveback_urb(hcd, urb, -ESHUTDOWN); | 1552 | usb_hcd_giveback_urb(hcd, urb, -ESHUTDOWN); |
1556 | xhci_urb_free_priv(xhci, urb_priv); | 1553 | xhci_urb_free_priv(urb_priv); |
1557 | return ret; | 1554 | return ret; |
1558 | } | 1555 | } |
1559 | if ((xhci->xhc_state & XHCI_STATE_DYING) || | 1556 | if ((xhci->xhc_state & XHCI_STATE_DYING) || |
@@ -1660,7 +1657,7 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
1660 | 1657 | ||
1661 | in_ctx = xhci->devs[udev->slot_id]->in_ctx; | 1658 | in_ctx = xhci->devs[udev->slot_id]->in_ctx; |
1662 | out_ctx = xhci->devs[udev->slot_id]->out_ctx; | 1659 | out_ctx = xhci->devs[udev->slot_id]->out_ctx; |
1663 | ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); | 1660 | ctrl_ctx = xhci_get_input_control_ctx(in_ctx); |
1664 | if (!ctrl_ctx) { | 1661 | if (!ctrl_ctx) { |
1665 | xhci_warn(xhci, "%s: Could not get input context, bad type.\n", | 1662 | xhci_warn(xhci, "%s: Could not get input context, bad type.\n", |
1666 | __func__); | 1663 | __func__); |
@@ -1676,8 +1673,10 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
1676 | cpu_to_le32(EP_STATE_DISABLED)) || | 1673 | cpu_to_le32(EP_STATE_DISABLED)) || |
1677 | le32_to_cpu(ctrl_ctx->drop_flags) & | 1674 | le32_to_cpu(ctrl_ctx->drop_flags) & |
1678 | xhci_get_endpoint_flag(&ep->desc)) { | 1675 | xhci_get_endpoint_flag(&ep->desc)) { |
1679 | xhci_warn(xhci, "xHCI %s called with disabled ep %p\n", | 1676 | /* Do not warn when called after a usb_device_reset */ |
1680 | __func__, ep); | 1677 | if (xhci->devs[udev->slot_id]->eps[ep_index].ring != NULL) |
1678 | xhci_warn(xhci, "xHCI %s called with disabled ep %p\n", | ||
1679 | __func__, ep); | ||
1681 | return 0; | 1680 | return 0; |
1682 | } | 1681 | } |
1683 | 1682 | ||
@@ -1714,7 +1713,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
1714 | struct usb_host_endpoint *ep) | 1713 | struct usb_host_endpoint *ep) |
1715 | { | 1714 | { |
1716 | struct xhci_hcd *xhci; | 1715 | struct xhci_hcd *xhci; |
1717 | struct xhci_container_ctx *in_ctx, *out_ctx; | 1716 | struct xhci_container_ctx *in_ctx; |
1718 | unsigned int ep_index; | 1717 | unsigned int ep_index; |
1719 | struct xhci_input_control_ctx *ctrl_ctx; | 1718 | struct xhci_input_control_ctx *ctrl_ctx; |
1720 | u32 added_ctxs; | 1719 | u32 added_ctxs; |
@@ -1745,8 +1744,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
1745 | 1744 | ||
1746 | virt_dev = xhci->devs[udev->slot_id]; | 1745 | virt_dev = xhci->devs[udev->slot_id]; |
1747 | in_ctx = virt_dev->in_ctx; | 1746 | in_ctx = virt_dev->in_ctx; |
1748 | out_ctx = virt_dev->out_ctx; | 1747 | ctrl_ctx = xhci_get_input_control_ctx(in_ctx); |
1749 | ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); | ||
1750 | if (!ctrl_ctx) { | 1748 | if (!ctrl_ctx) { |
1751 | xhci_warn(xhci, "%s: Could not get input context, bad type.\n", | 1749 | xhci_warn(xhci, "%s: Could not get input context, bad type.\n", |
1752 | __func__); | 1750 | __func__); |
@@ -1758,8 +1756,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
1758 | * to add it again without dropping it, reject the addition. | 1756 | * to add it again without dropping it, reject the addition. |
1759 | */ | 1757 | */ |
1760 | if (virt_dev->eps[ep_index].ring && | 1758 | if (virt_dev->eps[ep_index].ring && |
1761 | !(le32_to_cpu(ctrl_ctx->drop_flags) & | 1759 | !(le32_to_cpu(ctrl_ctx->drop_flags) & added_ctxs)) { |
1762 | xhci_get_endpoint_flag(&ep->desc))) { | ||
1763 | xhci_warn(xhci, "Trying to add endpoint 0x%x " | 1760 | xhci_warn(xhci, "Trying to add endpoint 0x%x " |
1764 | "without dropping it.\n", | 1761 | "without dropping it.\n", |
1765 | (unsigned int) ep->desc.bEndpointAddress); | 1762 | (unsigned int) ep->desc.bEndpointAddress); |
@@ -1769,8 +1766,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
1769 | /* If the HCD has already noted the endpoint is enabled, | 1766 | /* If the HCD has already noted the endpoint is enabled, |
1770 | * ignore this request. | 1767 | * ignore this request. |
1771 | */ | 1768 | */ |
1772 | if (le32_to_cpu(ctrl_ctx->add_flags) & | 1769 | if (le32_to_cpu(ctrl_ctx->add_flags) & added_ctxs) { |
1773 | xhci_get_endpoint_flag(&ep->desc)) { | ||
1774 | xhci_warn(xhci, "xHCI %s called with enabled ep %p\n", | 1770 | xhci_warn(xhci, "xHCI %s called with enabled ep %p\n", |
1775 | __func__, ep); | 1771 | __func__, ep); |
1776 | return 0; | 1772 | return 0; |
@@ -1816,7 +1812,7 @@ static void xhci_zero_in_ctx(struct xhci_hcd *xhci, struct xhci_virt_device *vir | |||
1816 | struct xhci_slot_ctx *slot_ctx; | 1812 | struct xhci_slot_ctx *slot_ctx; |
1817 | int i; | 1813 | int i; |
1818 | 1814 | ||
1819 | ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); | 1815 | ctrl_ctx = xhci_get_input_control_ctx(virt_dev->in_ctx); |
1820 | if (!ctrl_ctx) { | 1816 | if (!ctrl_ctx) { |
1821 | xhci_warn(xhci, "%s: Could not get input context, bad type.\n", | 1817 | xhci_warn(xhci, "%s: Could not get input context, bad type.\n", |
1822 | __func__); | 1818 | __func__); |
@@ -2542,7 +2538,7 @@ static int xhci_reserve_bandwidth(struct xhci_hcd *xhci, | |||
2542 | if (virt_dev->tt_info) | 2538 | if (virt_dev->tt_info) |
2543 | old_active_eps = virt_dev->tt_info->active_eps; | 2539 | old_active_eps = virt_dev->tt_info->active_eps; |
2544 | 2540 | ||
2545 | ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); | 2541 | ctrl_ctx = xhci_get_input_control_ctx(in_ctx); |
2546 | if (!ctrl_ctx) { | 2542 | if (!ctrl_ctx) { |
2547 | xhci_warn(xhci, "%s: Could not get input context, bad type.\n", | 2543 | xhci_warn(xhci, "%s: Could not get input context, bad type.\n", |
2548 | __func__); | 2544 | __func__); |
@@ -2639,7 +2635,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, | |||
2639 | spin_lock_irqsave(&xhci->lock, flags); | 2635 | spin_lock_irqsave(&xhci->lock, flags); |
2640 | virt_dev = xhci->devs[udev->slot_id]; | 2636 | virt_dev = xhci->devs[udev->slot_id]; |
2641 | 2637 | ||
2642 | ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx); | 2638 | ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx); |
2643 | if (!ctrl_ctx) { | 2639 | if (!ctrl_ctx) { |
2644 | spin_unlock_irqrestore(&xhci->lock, flags); | 2640 | spin_unlock_irqrestore(&xhci->lock, flags); |
2645 | xhci_warn(xhci, "%s: Could not get input context, bad type.\n", | 2641 | xhci_warn(xhci, "%s: Could not get input context, bad type.\n", |
@@ -2758,7 +2754,7 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) | |||
2758 | command->in_ctx = virt_dev->in_ctx; | 2754 | command->in_ctx = virt_dev->in_ctx; |
2759 | 2755 | ||
2760 | /* See section 4.6.6 - A0 = 1; A1 = D0 = D1 = 0 */ | 2756 | /* See section 4.6.6 - A0 = 1; A1 = D0 = D1 = 0 */ |
2761 | ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx); | 2757 | ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx); |
2762 | if (!ctrl_ctx) { | 2758 | if (!ctrl_ctx) { |
2763 | xhci_warn(xhci, "%s: Could not get input context, bad type.\n", | 2759 | xhci_warn(xhci, "%s: Could not get input context, bad type.\n", |
2764 | __func__); | 2760 | __func__); |
@@ -2883,7 +2879,7 @@ static void xhci_setup_input_ctx_for_quirk(struct xhci_hcd *xhci, | |||
2883 | dma_addr_t addr; | 2879 | dma_addr_t addr; |
2884 | 2880 | ||
2885 | in_ctx = xhci->devs[slot_id]->in_ctx; | 2881 | in_ctx = xhci->devs[slot_id]->in_ctx; |
2886 | ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); | 2882 | ctrl_ctx = xhci_get_input_control_ctx(in_ctx); |
2887 | if (!ctrl_ctx) { | 2883 | if (!ctrl_ctx) { |
2888 | xhci_warn(xhci, "%s: Could not get input context, bad type.\n", | 2884 | xhci_warn(xhci, "%s: Could not get input context, bad type.\n", |
2889 | __func__); | 2885 | __func__); |
@@ -3173,7 +3169,7 @@ int xhci_alloc_streams(struct usb_hcd *hcd, struct usb_device *udev, | |||
3173 | xhci_dbg(xhci, "Could not allocate xHCI command structure.\n"); | 3169 | xhci_dbg(xhci, "Could not allocate xHCI command structure.\n"); |
3174 | return -ENOMEM; | 3170 | return -ENOMEM; |
3175 | } | 3171 | } |
3176 | ctrl_ctx = xhci_get_input_control_ctx(xhci, config_cmd->in_ctx); | 3172 | ctrl_ctx = xhci_get_input_control_ctx(config_cmd->in_ctx); |
3177 | if (!ctrl_ctx) { | 3173 | if (!ctrl_ctx) { |
3178 | xhci_warn(xhci, "%s: Could not get input context, bad type.\n", | 3174 | xhci_warn(xhci, "%s: Could not get input context, bad type.\n", |
3179 | __func__); | 3175 | __func__); |
@@ -3328,7 +3324,7 @@ int xhci_free_streams(struct usb_hcd *hcd, struct usb_device *udev, | |||
3328 | */ | 3324 | */ |
3329 | ep_index = xhci_get_endpoint_index(&eps[0]->desc); | 3325 | ep_index = xhci_get_endpoint_index(&eps[0]->desc); |
3330 | command = vdev->eps[ep_index].stream_info->free_streams_command; | 3326 | command = vdev->eps[ep_index].stream_info->free_streams_command; |
3331 | ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx); | 3327 | ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx); |
3332 | if (!ctrl_ctx) { | 3328 | if (!ctrl_ctx) { |
3333 | spin_unlock_irqrestore(&xhci->lock, flags); | 3329 | spin_unlock_irqrestore(&xhci->lock, flags); |
3334 | xhci_warn(xhci, "%s: Could not get input context, bad type.\n", | 3330 | xhci_warn(xhci, "%s: Could not get input context, bad type.\n", |
@@ -3346,7 +3342,7 @@ int xhci_free_streams(struct usb_hcd *hcd, struct usb_device *udev, | |||
3346 | 3342 | ||
3347 | xhci_endpoint_copy(xhci, command->in_ctx, | 3343 | xhci_endpoint_copy(xhci, command->in_ctx, |
3348 | vdev->out_ctx, ep_index); | 3344 | vdev->out_ctx, ep_index); |
3349 | xhci_setup_no_streams_ep_input_ctx(xhci, ep_ctx, | 3345 | xhci_setup_no_streams_ep_input_ctx(ep_ctx, |
3350 | &vdev->eps[ep_index]); | 3346 | &vdev->eps[ep_index]); |
3351 | } | 3347 | } |
3352 | xhci_setup_input_ctx_for_config_ep(xhci, command->in_ctx, | 3348 | xhci_setup_input_ctx_for_config_ep(xhci, command->in_ctx, |
@@ -3820,7 +3816,7 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, | |||
3820 | command->completion = &xhci->addr_dev; | 3816 | command->completion = &xhci->addr_dev; |
3821 | 3817 | ||
3822 | slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); | 3818 | slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); |
3823 | ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); | 3819 | ctrl_ctx = xhci_get_input_control_ctx(virt_dev->in_ctx); |
3824 | if (!ctrl_ctx) { | 3820 | if (!ctrl_ctx) { |
3825 | xhci_warn(xhci, "%s: Could not get input context, bad type.\n", | 3821 | xhci_warn(xhci, "%s: Could not get input context, bad type.\n", |
3826 | __func__); | 3822 | __func__); |
@@ -4003,7 +3999,7 @@ static int __maybe_unused xhci_change_max_exit_latency(struct xhci_hcd *xhci, | |||
4003 | 3999 | ||
4004 | /* Attempt to issue an Evaluate Context command to change the MEL. */ | 4000 | /* Attempt to issue an Evaluate Context command to change the MEL. */ |
4005 | command = xhci->lpm_command; | 4001 | command = xhci->lpm_command; |
4006 | ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx); | 4002 | ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx); |
4007 | if (!ctrl_ctx) { | 4003 | if (!ctrl_ctx) { |
4008 | spin_unlock_irqrestore(&xhci->lock, flags); | 4004 | spin_unlock_irqrestore(&xhci->lock, flags); |
4009 | xhci_warn(xhci, "%s: Could not get input context, bad type.\n", | 4005 | xhci_warn(xhci, "%s: Could not get input context, bad type.\n", |
@@ -4741,7 +4737,7 @@ int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev, | |||
4741 | xhci_dbg(xhci, "Could not allocate xHCI command structure.\n"); | 4737 | xhci_dbg(xhci, "Could not allocate xHCI command structure.\n"); |
4742 | return -ENOMEM; | 4738 | return -ENOMEM; |
4743 | } | 4739 | } |
4744 | ctrl_ctx = xhci_get_input_control_ctx(xhci, config_cmd->in_ctx); | 4740 | ctrl_ctx = xhci_get_input_control_ctx(config_cmd->in_ctx); |
4745 | if (!ctrl_ctx) { | 4741 | if (!ctrl_ctx) { |
4746 | xhci_warn(xhci, "%s: Could not get input context, bad type.\n", | 4742 | xhci_warn(xhci, "%s: Could not get input context, bad type.\n", |
4747 | __func__); | 4743 | __func__); |
@@ -4910,6 +4906,10 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) | |||
4910 | if (retval) | 4906 | if (retval) |
4911 | goto error; | 4907 | goto error; |
4912 | xhci_dbg(xhci, "Called HCD init\n"); | 4908 | xhci_dbg(xhci, "Called HCD init\n"); |
4909 | |||
4910 | xhci_info(xhci, "hcc params 0x%08x hci version 0x%x quirks 0x%08x\n", | ||
4911 | xhci->hcc_params, xhci->hci_version, xhci->quirks); | ||
4912 | |||
4913 | return 0; | 4913 | return 0; |
4914 | error: | 4914 | error: |
4915 | kfree(xhci); | 4915 | kfree(xhci); |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index cc7c5bb7cbcf..974514762a14 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -1605,6 +1605,8 @@ static inline struct usb_hcd *xhci_to_hcd(struct xhci_hcd *xhci) | |||
1605 | dev_warn(xhci_to_hcd(xhci)->self.controller , fmt , ## args) | 1605 | dev_warn(xhci_to_hcd(xhci)->self.controller , fmt , ## args) |
1606 | #define xhci_warn_ratelimited(xhci, fmt, args...) \ | 1606 | #define xhci_warn_ratelimited(xhci, fmt, args...) \ |
1607 | dev_warn_ratelimited(xhci_to_hcd(xhci)->self.controller , fmt , ## args) | 1607 | dev_warn_ratelimited(xhci_to_hcd(xhci)->self.controller , fmt , ## args) |
1608 | #define xhci_info(xhci, fmt, args...) \ | ||
1609 | dev_info(xhci_to_hcd(xhci)->self.controller , fmt , ## args) | ||
1608 | 1610 | ||
1609 | /* | 1611 | /* |
1610 | * Registers should always be accessed with double word or quad word accesses. | 1612 | * Registers should always be accessed with double word or quad word accesses. |
@@ -1712,8 +1714,7 @@ void xhci_free_stream_info(struct xhci_hcd *xhci, | |||
1712 | void xhci_setup_streams_ep_input_ctx(struct xhci_hcd *xhci, | 1714 | void xhci_setup_streams_ep_input_ctx(struct xhci_hcd *xhci, |
1713 | struct xhci_ep_ctx *ep_ctx, | 1715 | struct xhci_ep_ctx *ep_ctx, |
1714 | struct xhci_stream_info *stream_info); | 1716 | struct xhci_stream_info *stream_info); |
1715 | void xhci_setup_no_streams_ep_input_ctx(struct xhci_hcd *xhci, | 1717 | void xhci_setup_no_streams_ep_input_ctx(struct xhci_ep_ctx *ep_ctx, |
1716 | struct xhci_ep_ctx *ep_ctx, | ||
1717 | struct xhci_virt_ep *ep); | 1718 | struct xhci_virt_ep *ep); |
1718 | void xhci_free_device_endpoint_resources(struct xhci_hcd *xhci, | 1719 | void xhci_free_device_endpoint_resources(struct xhci_hcd *xhci, |
1719 | struct xhci_virt_device *virt_dev, bool drop_control_ep); | 1720 | struct xhci_virt_device *virt_dev, bool drop_control_ep); |
@@ -1727,14 +1728,13 @@ struct xhci_ring *xhci_stream_id_to_ring( | |||
1727 | struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci, | 1728 | struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci, |
1728 | bool allocate_in_ctx, bool allocate_completion, | 1729 | bool allocate_in_ctx, bool allocate_completion, |
1729 | gfp_t mem_flags); | 1730 | gfp_t mem_flags); |
1730 | void xhci_urb_free_priv(struct xhci_hcd *xhci, struct urb_priv *urb_priv); | 1731 | void xhci_urb_free_priv(struct urb_priv *urb_priv); |
1731 | void xhci_free_command(struct xhci_hcd *xhci, | 1732 | void xhci_free_command(struct xhci_hcd *xhci, |
1732 | struct xhci_command *command); | 1733 | struct xhci_command *command); |
1733 | 1734 | ||
1734 | /* xHCI host controller glue */ | 1735 | /* xHCI host controller glue */ |
1735 | typedef void (*xhci_get_quirks_t)(struct device *, struct xhci_hcd *); | 1736 | typedef void (*xhci_get_quirks_t)(struct device *, struct xhci_hcd *); |
1736 | int xhci_handshake(struct xhci_hcd *xhci, void __iomem *ptr, | 1737 | int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, int usec); |
1737 | u32 mask, u32 done, int usec); | ||
1738 | void xhci_quiesce(struct xhci_hcd *xhci); | 1738 | void xhci_quiesce(struct xhci_hcd *xhci); |
1739 | int xhci_halt(struct xhci_hcd *xhci); | 1739 | int xhci_halt(struct xhci_hcd *xhci); |
1740 | int xhci_reset(struct xhci_hcd *xhci); | 1740 | int xhci_reset(struct xhci_hcd *xhci); |
@@ -1864,7 +1864,7 @@ int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci, | |||
1864 | void xhci_ring_device(struct xhci_hcd *xhci, int slot_id); | 1864 | void xhci_ring_device(struct xhci_hcd *xhci, int slot_id); |
1865 | 1865 | ||
1866 | /* xHCI contexts */ | 1866 | /* xHCI contexts */ |
1867 | struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx); | 1867 | struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_container_ctx *ctx); |
1868 | struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx); | 1868 | struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx); |
1869 | struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int ep_index); | 1869 | struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int ep_index); |
1870 | 1870 | ||
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index 37b44b04a701..6431d08c8d9d 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c | |||
@@ -299,9 +299,7 @@ static inline void mts_show_command(struct scsi_cmnd *srb) | |||
299 | MTS_DEBUG( "Command %s (%d bytes)\n", what, srb->cmd_len); | 299 | MTS_DEBUG( "Command %s (%d bytes)\n", what, srb->cmd_len); |
300 | 300 | ||
301 | out: | 301 | out: |
302 | MTS_DEBUG( " %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", | 302 | MTS_DEBUG( " %10ph\n", srb->cmnd); |
303 | srb->cmnd[0], srb->cmnd[1], srb->cmnd[2], srb->cmnd[3], srb->cmnd[4], srb->cmnd[5], | ||
304 | srb->cmnd[6], srb->cmnd[7], srb->cmnd[8], srb->cmnd[9]); | ||
305 | } | 303 | } |
306 | 304 | ||
307 | #else | 305 | #else |
diff --git a/drivers/usb/isp1760/Kconfig b/drivers/usb/isp1760/Kconfig new file mode 100644 index 000000000000..c94b7d953399 --- /dev/null +++ b/drivers/usb/isp1760/Kconfig | |||
@@ -0,0 +1,59 @@ | |||
1 | config USB_ISP1760 | ||
2 | tristate "NXP ISP 1760/1761 support" | ||
3 | depends on USB || USB_GADGET | ||
4 | help | ||
5 | Say Y or M here if your system as an ISP1760 USB host controller | ||
6 | or an ISP1761 USB dual-role controller. | ||
7 | |||
8 | This driver does not support isochronous transfers or OTG. | ||
9 | This USB controller is usually attached to a non-DMA-Master | ||
10 | capable bus. NXP's eval kit brings this chip on PCI card | ||
11 | where the chip itself is behind a PLB to simulate such | ||
12 | a bus. | ||
13 | |||
14 | To compile this driver as a module, choose M here: the | ||
15 | module will be called isp1760. | ||
16 | |||
17 | config USB_ISP1760_HCD | ||
18 | bool | ||
19 | |||
20 | config USB_ISP1761_UDC | ||
21 | bool | ||
22 | |||
23 | if USB_ISP1760 | ||
24 | |||
25 | choice | ||
26 | bool "ISP1760 Mode Selection" | ||
27 | default USB_ISP1760_DUAL_ROLE if (USB && USB_GADGET) | ||
28 | default USB_ISP1760_HOST_ROLE if (USB && !USB_GADGET) | ||
29 | default USB_ISP1760_GADGET_ROLE if (!USB && USB_GADGET) | ||
30 | |||
31 | config USB_ISP1760_HOST_ROLE | ||
32 | bool "Host only mode" | ||
33 | depends on USB=y || USB=USB_ISP1760 | ||
34 | select USB_ISP1760_HCD | ||
35 | help | ||
36 | Select this if you want to use the ISP1760 in host mode only. The | ||
37 | gadget function will be disabled. | ||
38 | |||
39 | config USB_ISP1760_GADGET_ROLE | ||
40 | bool "Gadget only mode" | ||
41 | depends on USB_GADGET=y || USB_GADGET=USB_ISP1760 | ||
42 | select USB_ISP1761_UDC | ||
43 | help | ||
44 | Select this if you want to use the ISP1760 in peripheral mode only. | ||
45 | The host function will be disabled. | ||
46 | |||
47 | config USB_ISP1760_DUAL_ROLE | ||
48 | bool "Dual Role mode" | ||
49 | depends on USB=y || USB=USB_ISP1760 | ||
50 | depends on USB_GADGET=y || USB_GADGET=USB_ISP1760 | ||
51 | select USB_ISP1760_HCD | ||
52 | select USB_ISP1761_UDC | ||
53 | help | ||
54 | Select this if you want to use the ISP1760 in both host and | ||
55 | peripheral modes. | ||
56 | |||
57 | endchoice | ||
58 | |||
59 | endif | ||
diff --git a/drivers/usb/isp1760/Makefile b/drivers/usb/isp1760/Makefile new file mode 100644 index 000000000000..2b741074ad2b --- /dev/null +++ b/drivers/usb/isp1760/Makefile | |||
@@ -0,0 +1,5 @@ | |||
1 | isp1760-y := isp1760-core.o isp1760-if.o | ||
2 | isp1760-$(CONFIG_USB_ISP1760_HCD) += isp1760-hcd.o | ||
3 | isp1760-$(CONFIG_USB_ISP1761_UDC) += isp1760-udc.o | ||
4 | |||
5 | obj-$(CONFIG_USB_ISP1760) += isp1760.o | ||
diff --git a/drivers/usb/isp1760/isp1760-core.c b/drivers/usb/isp1760/isp1760-core.c new file mode 100644 index 000000000000..b9827556455f --- /dev/null +++ b/drivers/usb/isp1760/isp1760-core.c | |||
@@ -0,0 +1,177 @@ | |||
1 | /* | ||
2 | * Driver for the NXP ISP1760 chip | ||
3 | * | ||
4 | * Copyright 2014 Laurent Pinchart | ||
5 | * Copyright 2007 Sebastian Siewior | ||
6 | * | ||
7 | * Contacts: | ||
8 | * Sebastian Siewior <bigeasy@linutronix.de> | ||
9 | * Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License | ||
13 | * version 2 as published by the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | #include <linux/delay.h> | ||
17 | #include <linux/gpio/consumer.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/usb.h> | ||
23 | |||
24 | #include "isp1760-core.h" | ||
25 | #include "isp1760-hcd.h" | ||
26 | #include "isp1760-regs.h" | ||
27 | #include "isp1760-udc.h" | ||
28 | |||
29 | static void isp1760_init_core(struct isp1760_device *isp) | ||
30 | { | ||
31 | u32 otgctrl; | ||
32 | u32 hwmode; | ||
33 | |||
34 | /* Low-level chip reset */ | ||
35 | if (isp->rst_gpio) { | ||
36 | gpiod_set_value_cansleep(isp->rst_gpio, 1); | ||
37 | mdelay(50); | ||
38 | gpiod_set_value_cansleep(isp->rst_gpio, 0); | ||
39 | } | ||
40 | |||
41 | /* | ||
42 | * Reset the host controller, including the CPU interface | ||
43 | * configuration. | ||
44 | */ | ||
45 | isp1760_write32(isp->regs, HC_RESET_REG, SW_RESET_RESET_ALL); | ||
46 | msleep(100); | ||
47 | |||
48 | /* Setup HW Mode Control: This assumes a level active-low interrupt */ | ||
49 | hwmode = HW_DATA_BUS_32BIT; | ||
50 | |||
51 | if (isp->devflags & ISP1760_FLAG_BUS_WIDTH_16) | ||
52 | hwmode &= ~HW_DATA_BUS_32BIT; | ||
53 | if (isp->devflags & ISP1760_FLAG_ANALOG_OC) | ||
54 | hwmode |= HW_ANA_DIGI_OC; | ||
55 | if (isp->devflags & ISP1760_FLAG_DACK_POL_HIGH) | ||
56 | hwmode |= HW_DACK_POL_HIGH; | ||
57 | if (isp->devflags & ISP1760_FLAG_DREQ_POL_HIGH) | ||
58 | hwmode |= HW_DREQ_POL_HIGH; | ||
59 | if (isp->devflags & ISP1760_FLAG_INTR_POL_HIGH) | ||
60 | hwmode |= HW_INTR_HIGH_ACT; | ||
61 | if (isp->devflags & ISP1760_FLAG_INTR_EDGE_TRIG) | ||
62 | hwmode |= HW_INTR_EDGE_TRIG; | ||
63 | |||
64 | /* | ||
65 | * The ISP1761 has a dedicated DC IRQ line but supports sharing the HC | ||
66 | * IRQ line for both the host and device controllers. Hardcode IRQ | ||
67 | * sharing for now and disable the DC interrupts globally to avoid | ||
68 | * spurious interrupts during HCD registration. | ||
69 | */ | ||
70 | if (isp->devflags & ISP1760_FLAG_ISP1761) { | ||
71 | isp1760_write32(isp->regs, DC_MODE, 0); | ||
72 | hwmode |= HW_COMN_IRQ; | ||
73 | } | ||
74 | |||
75 | /* | ||
76 | * We have to set this first in case we're in 16-bit mode. | ||
77 | * Write it twice to ensure correct upper bits if switching | ||
78 | * to 16-bit mode. | ||
79 | */ | ||
80 | isp1760_write32(isp->regs, HC_HW_MODE_CTRL, hwmode); | ||
81 | isp1760_write32(isp->regs, HC_HW_MODE_CTRL, hwmode); | ||
82 | |||
83 | /* | ||
84 | * PORT 1 Control register of the ISP1760 is the OTG control register | ||
85 | * on ISP1761. | ||
86 | * | ||
87 | * TODO: Really support OTG. For now we configure port 1 in device mode | ||
88 | * when OTG is requested. | ||
89 | */ | ||
90 | if ((isp->devflags & ISP1760_FLAG_ISP1761) && | ||
91 | (isp->devflags & ISP1760_FLAG_OTG_EN)) | ||
92 | otgctrl = ((HW_DM_PULLDOWN | HW_DP_PULLDOWN) << 16) | ||
93 | | HW_OTG_DISABLE; | ||
94 | else | ||
95 | otgctrl = (HW_SW_SEL_HC_DC << 16) | ||
96 | | (HW_VBUS_DRV | HW_SEL_CP_EXT); | ||
97 | |||
98 | isp1760_write32(isp->regs, HC_PORT1_CTRL, otgctrl); | ||
99 | |||
100 | dev_info(isp->dev, "bus width: %u, oc: %s\n", | ||
101 | isp->devflags & ISP1760_FLAG_BUS_WIDTH_16 ? 16 : 32, | ||
102 | isp->devflags & ISP1760_FLAG_ANALOG_OC ? "analog" : "digital"); | ||
103 | } | ||
104 | |||
105 | void isp1760_set_pullup(struct isp1760_device *isp, bool enable) | ||
106 | { | ||
107 | isp1760_write32(isp->regs, HW_OTG_CTRL_SET, | ||
108 | enable ? HW_DP_PULLUP : HW_DP_PULLUP << 16); | ||
109 | } | ||
110 | |||
111 | int isp1760_register(struct resource *mem, int irq, unsigned long irqflags, | ||
112 | struct device *dev, unsigned int devflags) | ||
113 | { | ||
114 | struct isp1760_device *isp; | ||
115 | bool udc_disabled = !(devflags & ISP1760_FLAG_ISP1761); | ||
116 | int ret; | ||
117 | |||
118 | /* | ||
119 | * If neither the HCD not the UDC is enabled return an error, as no | ||
120 | * device would be registered. | ||
121 | */ | ||
122 | if ((!IS_ENABLED(CONFIG_USB_ISP1760_HCD) || usb_disabled()) && | ||
123 | (!IS_ENABLED(CONFIG_USB_ISP1761_UDC) || udc_disabled)) | ||
124 | return -ENODEV; | ||
125 | |||
126 | /* prevent usb-core allocating DMA pages */ | ||
127 | dev->dma_mask = NULL; | ||
128 | |||
129 | isp = devm_kzalloc(dev, sizeof(*isp), GFP_KERNEL); | ||
130 | if (!isp) | ||
131 | return -ENOMEM; | ||
132 | |||
133 | isp->dev = dev; | ||
134 | isp->devflags = devflags; | ||
135 | |||
136 | isp->rst_gpio = devm_gpiod_get_optional(dev, NULL, GPIOD_OUT_HIGH); | ||
137 | if (IS_ERR(isp->rst_gpio)) | ||
138 | return PTR_ERR(isp->rst_gpio); | ||
139 | |||
140 | isp->regs = devm_ioremap_resource(dev, mem); | ||
141 | if (IS_ERR(isp->regs)) | ||
142 | return PTR_ERR(isp->regs); | ||
143 | |||
144 | isp1760_init_core(isp); | ||
145 | |||
146 | if (IS_ENABLED(CONFIG_USB_ISP1760_HCD) && !usb_disabled()) { | ||
147 | ret = isp1760_hcd_register(&isp->hcd, isp->regs, mem, irq, | ||
148 | irqflags | IRQF_SHARED, dev); | ||
149 | if (ret < 0) | ||
150 | return ret; | ||
151 | } | ||
152 | |||
153 | if (IS_ENABLED(CONFIG_USB_ISP1761_UDC) && !udc_disabled) { | ||
154 | ret = isp1760_udc_register(isp, irq, irqflags | IRQF_SHARED | | ||
155 | IRQF_DISABLED); | ||
156 | if (ret < 0) { | ||
157 | isp1760_hcd_unregister(&isp->hcd); | ||
158 | return ret; | ||
159 | } | ||
160 | } | ||
161 | |||
162 | dev_set_drvdata(dev, isp); | ||
163 | |||
164 | return 0; | ||
165 | } | ||
166 | |||
167 | void isp1760_unregister(struct device *dev) | ||
168 | { | ||
169 | struct isp1760_device *isp = dev_get_drvdata(dev); | ||
170 | |||
171 | isp1760_udc_unregister(isp); | ||
172 | isp1760_hcd_unregister(&isp->hcd); | ||
173 | } | ||
174 | |||
175 | MODULE_DESCRIPTION("Driver for the ISP1760 USB-controller from NXP"); | ||
176 | MODULE_AUTHOR("Sebastian Siewior <bigeasy@linuxtronix.de>"); | ||
177 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/usb/isp1760/isp1760-core.h b/drivers/usb/isp1760/isp1760-core.h new file mode 100644 index 000000000000..c70f8368a794 --- /dev/null +++ b/drivers/usb/isp1760/isp1760-core.h | |||
@@ -0,0 +1,68 @@ | |||
1 | /* | ||
2 | * Driver for the NXP ISP1760 chip | ||
3 | * | ||
4 | * Copyright 2014 Laurent Pinchart | ||
5 | * Copyright 2007 Sebastian Siewior | ||
6 | * | ||
7 | * Contacts: | ||
8 | * Sebastian Siewior <bigeasy@linutronix.de> | ||
9 | * Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License | ||
13 | * version 2 as published by the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | #ifndef _ISP1760_CORE_H_ | ||
17 | #define _ISP1760_CORE_H_ | ||
18 | |||
19 | #include <linux/ioport.h> | ||
20 | |||
21 | #include "isp1760-hcd.h" | ||
22 | #include "isp1760-udc.h" | ||
23 | |||
24 | struct device; | ||
25 | struct gpio_desc; | ||
26 | |||
27 | /* | ||
28 | * Device flags that can vary from board to board. All of these | ||
29 | * indicate the most "atypical" case, so that a devflags of 0 is | ||
30 | * a sane default configuration. | ||
31 | */ | ||
32 | #define ISP1760_FLAG_BUS_WIDTH_16 0x00000002 /* 16-bit data bus width */ | ||
33 | #define ISP1760_FLAG_OTG_EN 0x00000004 /* Port 1 supports OTG */ | ||
34 | #define ISP1760_FLAG_ANALOG_OC 0x00000008 /* Analog overcurrent */ | ||
35 | #define ISP1760_FLAG_DACK_POL_HIGH 0x00000010 /* DACK active high */ | ||
36 | #define ISP1760_FLAG_DREQ_POL_HIGH 0x00000020 /* DREQ active high */ | ||
37 | #define ISP1760_FLAG_ISP1761 0x00000040 /* Chip is ISP1761 */ | ||
38 | #define ISP1760_FLAG_INTR_POL_HIGH 0x00000080 /* Interrupt polarity active high */ | ||
39 | #define ISP1760_FLAG_INTR_EDGE_TRIG 0x00000100 /* Interrupt edge triggered */ | ||
40 | |||
41 | struct isp1760_device { | ||
42 | struct device *dev; | ||
43 | |||
44 | void __iomem *regs; | ||
45 | unsigned int devflags; | ||
46 | struct gpio_desc *rst_gpio; | ||
47 | |||
48 | struct isp1760_hcd hcd; | ||
49 | struct isp1760_udc udc; | ||
50 | }; | ||
51 | |||
52 | int isp1760_register(struct resource *mem, int irq, unsigned long irqflags, | ||
53 | struct device *dev, unsigned int devflags); | ||
54 | void isp1760_unregister(struct device *dev); | ||
55 | |||
56 | void isp1760_set_pullup(struct isp1760_device *isp, bool enable); | ||
57 | |||
58 | static inline u32 isp1760_read32(void __iomem *base, u32 reg) | ||
59 | { | ||
60 | return readl(base + reg); | ||
61 | } | ||
62 | |||
63 | static inline void isp1760_write32(void __iomem *base, u32 reg, u32 val) | ||
64 | { | ||
65 | writel(val, base + reg); | ||
66 | } | ||
67 | |||
68 | #endif | ||
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/isp1760/isp1760-hcd.c index 395649f357aa..eba9b82e2d70 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/isp1760/isp1760-hcd.c | |||
@@ -11,6 +11,7 @@ | |||
11 | * (c) 2011 Arvid Brodin <arvid.brodin@enea.com> | 11 | * (c) 2011 Arvid Brodin <arvid.brodin@enea.com> |
12 | * | 12 | * |
13 | */ | 13 | */ |
14 | #include <linux/gpio/consumer.h> | ||
14 | #include <linux/module.h> | 15 | #include <linux/module.h> |
15 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
16 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
@@ -24,73 +25,96 @@ | |||
24 | #include <linux/timer.h> | 25 | #include <linux/timer.h> |
25 | #include <asm/unaligned.h> | 26 | #include <asm/unaligned.h> |
26 | #include <asm/cacheflush.h> | 27 | #include <asm/cacheflush.h> |
27 | #include <linux/gpio.h> | ||
28 | 28 | ||
29 | #include "isp1760-core.h" | ||
29 | #include "isp1760-hcd.h" | 30 | #include "isp1760-hcd.h" |
31 | #include "isp1760-regs.h" | ||
30 | 32 | ||
31 | static struct kmem_cache *qtd_cachep; | 33 | static struct kmem_cache *qtd_cachep; |
32 | static struct kmem_cache *qh_cachep; | 34 | static struct kmem_cache *qh_cachep; |
33 | static struct kmem_cache *urb_listitem_cachep; | 35 | static struct kmem_cache *urb_listitem_cachep; |
34 | 36 | ||
35 | enum queue_head_types { | 37 | typedef void (packet_enqueue)(struct usb_hcd *hcd, struct isp1760_qh *qh, |
36 | QH_CONTROL, | 38 | struct isp1760_qtd *qtd); |
37 | QH_BULK, | ||
38 | QH_INTERRUPT, | ||
39 | QH_END | ||
40 | }; | ||
41 | |||
42 | struct isp1760_hcd { | ||
43 | u32 hcs_params; | ||
44 | spinlock_t lock; | ||
45 | struct slotinfo atl_slots[32]; | ||
46 | int atl_done_map; | ||
47 | struct slotinfo int_slots[32]; | ||
48 | int int_done_map; | ||
49 | struct memory_chunk memory_pool[BLOCKS]; | ||
50 | struct list_head qh_list[QH_END]; | ||
51 | |||
52 | /* periodic schedule support */ | ||
53 | #define DEFAULT_I_TDPS 1024 | ||
54 | unsigned periodic_size; | ||
55 | unsigned i_thresh; | ||
56 | unsigned long reset_done; | ||
57 | unsigned long next_statechange; | ||
58 | unsigned int devflags; | ||
59 | |||
60 | int rst_gpio; | ||
61 | }; | ||
62 | 39 | ||
63 | static inline struct isp1760_hcd *hcd_to_priv(struct usb_hcd *hcd) | 40 | static inline struct isp1760_hcd *hcd_to_priv(struct usb_hcd *hcd) |
64 | { | 41 | { |
65 | return (struct isp1760_hcd *) (hcd->hcd_priv); | 42 | return *(struct isp1760_hcd **)hcd->hcd_priv; |
66 | } | 43 | } |
67 | 44 | ||
68 | /* Section 2.2 Host Controller Capability Registers */ | 45 | /* urb state*/ |
69 | #define HC_LENGTH(p) (((p)>>00)&0x00ff) /* bits 7:0 */ | 46 | #define DELETE_URB (0x0008) |
70 | #define HC_VERSION(p) (((p)>>16)&0xffff) /* bits 31:16 */ | 47 | #define NO_TRANSFER_ACTIVE (0xffffffff) |
71 | #define HCS_INDICATOR(p) ((p)&(1 << 16)) /* true: has port indicators */ | 48 | |
72 | #define HCS_PPC(p) ((p)&(1 << 4)) /* true: port power control */ | 49 | /* Philips Proprietary Transfer Descriptor (PTD) */ |
73 | #define HCS_N_PORTS(p) (((p)>>0)&0xf) /* bits 3:0, ports on HC */ | 50 | typedef __u32 __bitwise __dw; |
74 | #define HCC_ISOC_CACHE(p) ((p)&(1 << 7)) /* true: can cache isoc frame */ | 51 | struct ptd { |
75 | #define HCC_ISOC_THRES(p) (((p)>>4)&0x7) /* bits 6:4, uframes cached */ | 52 | __dw dw0; |
76 | 53 | __dw dw1; | |
77 | /* Section 2.3 Host Controller Operational Registers */ | 54 | __dw dw2; |
78 | #define CMD_LRESET (1<<7) /* partial reset (no ports, etc) */ | 55 | __dw dw3; |
79 | #define CMD_RESET (1<<1) /* reset HC not bus */ | 56 | __dw dw4; |
80 | #define CMD_RUN (1<<0) /* start/stop HC */ | 57 | __dw dw5; |
81 | #define STS_PCD (1<<2) /* port change detect */ | 58 | __dw dw6; |
82 | #define FLAG_CF (1<<0) /* true: we'll support "high speed" */ | 59 | __dw dw7; |
83 | 60 | }; | |
84 | #define PORT_OWNER (1<<13) /* true: companion hc owns this port */ | 61 | #define PTD_OFFSET 0x0400 |
85 | #define PORT_POWER (1<<12) /* true: has power (see PPC) */ | 62 | #define ISO_PTD_OFFSET 0x0400 |
86 | #define PORT_USB11(x) (((x) & (3 << 10)) == (1 << 10)) /* USB 1.1 device */ | 63 | #define INT_PTD_OFFSET 0x0800 |
87 | #define PORT_RESET (1<<8) /* reset port */ | 64 | #define ATL_PTD_OFFSET 0x0c00 |
88 | #define PORT_SUSPEND (1<<7) /* suspend port */ | 65 | #define PAYLOAD_OFFSET 0x1000 |
89 | #define PORT_RESUME (1<<6) /* resume it */ | 66 | |
90 | #define PORT_PE (1<<2) /* port enable */ | 67 | |
91 | #define PORT_CSC (1<<1) /* connect status change */ | 68 | /* ATL */ |
92 | #define PORT_CONNECT (1<<0) /* device connected */ | 69 | /* DW0 */ |
93 | #define PORT_RWC_BITS (PORT_CSC) | 70 | #define DW0_VALID_BIT 1 |
71 | #define FROM_DW0_VALID(x) ((x) & 0x01) | ||
72 | #define TO_DW0_LENGTH(x) (((u32) x) << 3) | ||
73 | #define TO_DW0_MAXPACKET(x) (((u32) x) << 18) | ||
74 | #define TO_DW0_MULTI(x) (((u32) x) << 29) | ||
75 | #define TO_DW0_ENDPOINT(x) (((u32) x) << 31) | ||
76 | /* DW1 */ | ||
77 | #define TO_DW1_DEVICE_ADDR(x) (((u32) x) << 3) | ||
78 | #define TO_DW1_PID_TOKEN(x) (((u32) x) << 10) | ||
79 | #define DW1_TRANS_BULK ((u32) 2 << 12) | ||
80 | #define DW1_TRANS_INT ((u32) 3 << 12) | ||
81 | #define DW1_TRANS_SPLIT ((u32) 1 << 14) | ||
82 | #define DW1_SE_USB_LOSPEED ((u32) 2 << 16) | ||
83 | #define TO_DW1_PORT_NUM(x) (((u32) x) << 18) | ||
84 | #define TO_DW1_HUB_NUM(x) (((u32) x) << 25) | ||
85 | /* DW2 */ | ||
86 | #define TO_DW2_DATA_START_ADDR(x) (((u32) x) << 8) | ||
87 | #define TO_DW2_RL(x) ((x) << 25) | ||
88 | #define FROM_DW2_RL(x) (((x) >> 25) & 0xf) | ||
89 | /* DW3 */ | ||
90 | #define FROM_DW3_NRBYTESTRANSFERRED(x) ((x) & 0x7fff) | ||
91 | #define FROM_DW3_SCS_NRBYTESTRANSFERRED(x) ((x) & 0x07ff) | ||
92 | #define TO_DW3_NAKCOUNT(x) ((x) << 19) | ||
93 | #define FROM_DW3_NAKCOUNT(x) (((x) >> 19) & 0xf) | ||
94 | #define TO_DW3_CERR(x) ((x) << 23) | ||
95 | #define FROM_DW3_CERR(x) (((x) >> 23) & 0x3) | ||
96 | #define TO_DW3_DATA_TOGGLE(x) ((x) << 25) | ||
97 | #define FROM_DW3_DATA_TOGGLE(x) (((x) >> 25) & 0x1) | ||
98 | #define TO_DW3_PING(x) ((x) << 26) | ||
99 | #define FROM_DW3_PING(x) (((x) >> 26) & 0x1) | ||
100 | #define DW3_ERROR_BIT (1 << 28) | ||
101 | #define DW3_BABBLE_BIT (1 << 29) | ||
102 | #define DW3_HALT_BIT (1 << 30) | ||
103 | #define DW3_ACTIVE_BIT (1 << 31) | ||
104 | #define FROM_DW3_ACTIVE(x) (((x) >> 31) & 0x01) | ||
105 | |||
106 | #define INT_UNDERRUN (1 << 2) | ||
107 | #define INT_BABBLE (1 << 1) | ||
108 | #define INT_EXACT (1 << 0) | ||
109 | |||
110 | #define SETUP_PID (2) | ||
111 | #define IN_PID (1) | ||
112 | #define OUT_PID (0) | ||
113 | |||
114 | /* Errata 1 */ | ||
115 | #define RL_COUNTER (0) | ||
116 | #define NAK_COUNTER (0) | ||
117 | #define ERR_COUNTER (2) | ||
94 | 118 | ||
95 | struct isp1760_qtd { | 119 | struct isp1760_qtd { |
96 | u8 packet_type; | 120 | u8 packet_type; |
@@ -137,12 +161,12 @@ struct urb_listitem { | |||
137 | */ | 161 | */ |
138 | static u32 reg_read32(void __iomem *base, u32 reg) | 162 | static u32 reg_read32(void __iomem *base, u32 reg) |
139 | { | 163 | { |
140 | return readl(base + reg); | 164 | return isp1760_read32(base, reg); |
141 | } | 165 | } |
142 | 166 | ||
143 | static void reg_write32(void __iomem *base, u32 reg, u32 val) | 167 | static void reg_write32(void __iomem *base, u32 reg, u32 val) |
144 | { | 168 | { |
145 | writel(val, base + reg); | 169 | isp1760_write32(base, reg, val); |
146 | } | 170 | } |
147 | 171 | ||
148 | /* | 172 | /* |
@@ -443,42 +467,6 @@ static int isp1760_hc_setup(struct usb_hcd *hcd) | |||
443 | int result; | 467 | int result; |
444 | u32 scratch, hwmode; | 468 | u32 scratch, hwmode; |
445 | 469 | ||
446 | /* low-level chip reset */ | ||
447 | if (gpio_is_valid(priv->rst_gpio)) { | ||
448 | unsigned int rst_lvl; | ||
449 | |||
450 | rst_lvl = (priv->devflags & | ||
451 | ISP1760_FLAG_RESET_ACTIVE_HIGH) ? 1 : 0; | ||
452 | |||
453 | gpio_set_value(priv->rst_gpio, rst_lvl); | ||
454 | mdelay(50); | ||
455 | gpio_set_value(priv->rst_gpio, !rst_lvl); | ||
456 | } | ||
457 | |||
458 | /* Setup HW Mode Control: This assumes a level active-low interrupt */ | ||
459 | hwmode = HW_DATA_BUS_32BIT; | ||
460 | |||
461 | if (priv->devflags & ISP1760_FLAG_BUS_WIDTH_16) | ||
462 | hwmode &= ~HW_DATA_BUS_32BIT; | ||
463 | if (priv->devflags & ISP1760_FLAG_ANALOG_OC) | ||
464 | hwmode |= HW_ANA_DIGI_OC; | ||
465 | if (priv->devflags & ISP1760_FLAG_DACK_POL_HIGH) | ||
466 | hwmode |= HW_DACK_POL_HIGH; | ||
467 | if (priv->devflags & ISP1760_FLAG_DREQ_POL_HIGH) | ||
468 | hwmode |= HW_DREQ_POL_HIGH; | ||
469 | if (priv->devflags & ISP1760_FLAG_INTR_POL_HIGH) | ||
470 | hwmode |= HW_INTR_HIGH_ACT; | ||
471 | if (priv->devflags & ISP1760_FLAG_INTR_EDGE_TRIG) | ||
472 | hwmode |= HW_INTR_EDGE_TRIG; | ||
473 | |||
474 | /* | ||
475 | * We have to set this first in case we're in 16-bit mode. | ||
476 | * Write it twice to ensure correct upper bits if switching | ||
477 | * to 16-bit mode. | ||
478 | */ | ||
479 | reg_write32(hcd->regs, HC_HW_MODE_CTRL, hwmode); | ||
480 | reg_write32(hcd->regs, HC_HW_MODE_CTRL, hwmode); | ||
481 | |||
482 | reg_write32(hcd->regs, HC_SCRATCH_REG, 0xdeadbabe); | 470 | reg_write32(hcd->regs, HC_SCRATCH_REG, 0xdeadbabe); |
483 | /* Change bus pattern */ | 471 | /* Change bus pattern */ |
484 | scratch = reg_read32(hcd->regs, HC_CHIP_ID_REG); | 472 | scratch = reg_read32(hcd->regs, HC_CHIP_ID_REG); |
@@ -488,46 +476,33 @@ static int isp1760_hc_setup(struct usb_hcd *hcd) | |||
488 | return -ENODEV; | 476 | return -ENODEV; |
489 | } | 477 | } |
490 | 478 | ||
491 | /* pre reset */ | 479 | /* |
480 | * The RESET_HC bit in the SW_RESET register is supposed to reset the | ||
481 | * host controller without touching the CPU interface registers, but at | ||
482 | * least on the ISP1761 it seems to behave as the RESET_ALL bit and | ||
483 | * reset the whole device. We thus can't use it here, so let's reset | ||
484 | * the host controller through the EHCI USB Command register. The device | ||
485 | * has been reset in core code anyway, so this shouldn't matter. | ||
486 | */ | ||
492 | reg_write32(hcd->regs, HC_BUFFER_STATUS_REG, 0); | 487 | reg_write32(hcd->regs, HC_BUFFER_STATUS_REG, 0); |
493 | reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, NO_TRANSFER_ACTIVE); | 488 | reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, NO_TRANSFER_ACTIVE); |
494 | reg_write32(hcd->regs, HC_INT_PTD_SKIPMAP_REG, NO_TRANSFER_ACTIVE); | 489 | reg_write32(hcd->regs, HC_INT_PTD_SKIPMAP_REG, NO_TRANSFER_ACTIVE); |
495 | reg_write32(hcd->regs, HC_ISO_PTD_SKIPMAP_REG, NO_TRANSFER_ACTIVE); | 490 | reg_write32(hcd->regs, HC_ISO_PTD_SKIPMAP_REG, NO_TRANSFER_ACTIVE); |
496 | 491 | ||
497 | /* reset */ | ||
498 | reg_write32(hcd->regs, HC_RESET_REG, SW_RESET_RESET_ALL); | ||
499 | mdelay(100); | ||
500 | |||
501 | reg_write32(hcd->regs, HC_RESET_REG, SW_RESET_RESET_HC); | ||
502 | mdelay(100); | ||
503 | |||
504 | result = ehci_reset(hcd); | 492 | result = ehci_reset(hcd); |
505 | if (result) | 493 | if (result) |
506 | return result; | 494 | return result; |
507 | 495 | ||
508 | /* Step 11 passed */ | 496 | /* Step 11 passed */ |
509 | 497 | ||
510 | dev_info(hcd->self.controller, "bus width: %d, oc: %s\n", | ||
511 | (priv->devflags & ISP1760_FLAG_BUS_WIDTH_16) ? | ||
512 | 16 : 32, (priv->devflags & ISP1760_FLAG_ANALOG_OC) ? | ||
513 | "analog" : "digital"); | ||
514 | |||
515 | /* ATL reset */ | 498 | /* ATL reset */ |
499 | hwmode = reg_read32(hcd->regs, HC_HW_MODE_CTRL) & ~ALL_ATX_RESET; | ||
516 | reg_write32(hcd->regs, HC_HW_MODE_CTRL, hwmode | ALL_ATX_RESET); | 500 | reg_write32(hcd->regs, HC_HW_MODE_CTRL, hwmode | ALL_ATX_RESET); |
517 | mdelay(10); | 501 | mdelay(10); |
518 | reg_write32(hcd->regs, HC_HW_MODE_CTRL, hwmode); | 502 | reg_write32(hcd->regs, HC_HW_MODE_CTRL, hwmode); |
519 | 503 | ||
520 | reg_write32(hcd->regs, HC_INTERRUPT_ENABLE, INTERRUPT_ENABLE_MASK); | 504 | reg_write32(hcd->regs, HC_INTERRUPT_ENABLE, INTERRUPT_ENABLE_MASK); |
521 | 505 | ||
522 | /* | ||
523 | * PORT 1 Control register of the ISP1760 is the OTG control | ||
524 | * register on ISP1761. Since there is no OTG or device controller | ||
525 | * support in this driver, we use port 1 as a "normal" USB host port on | ||
526 | * both chips. | ||
527 | */ | ||
528 | reg_write32(hcd->regs, HC_PORT1_CTRL, PORT1_POWER | PORT1_INIT2); | ||
529 | mdelay(10); | ||
530 | |||
531 | priv->hcs_params = reg_read32(hcd->regs, HC_HCSPARAMS); | 506 | priv->hcs_params = reg_read32(hcd->regs, HC_HCSPARAMS); |
532 | 507 | ||
533 | return priv_init(hcd); | 508 | return priv_init(hcd); |
@@ -743,8 +718,9 @@ static void qtd_free(struct isp1760_qtd *qtd) | |||
743 | } | 718 | } |
744 | 719 | ||
745 | static void start_bus_transfer(struct usb_hcd *hcd, u32 ptd_offset, int slot, | 720 | static void start_bus_transfer(struct usb_hcd *hcd, u32 ptd_offset, int slot, |
746 | struct slotinfo *slots, struct isp1760_qtd *qtd, | 721 | struct isp1760_slotinfo *slots, |
747 | struct isp1760_qh *qh, struct ptd *ptd) | 722 | struct isp1760_qtd *qtd, struct isp1760_qh *qh, |
723 | struct ptd *ptd) | ||
748 | { | 724 | { |
749 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | 725 | struct isp1760_hcd *priv = hcd_to_priv(hcd); |
750 | int skip_map; | 726 | int skip_map; |
@@ -857,7 +833,7 @@ static void enqueue_qtds(struct usb_hcd *hcd, struct isp1760_qh *qh) | |||
857 | { | 833 | { |
858 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | 834 | struct isp1760_hcd *priv = hcd_to_priv(hcd); |
859 | int ptd_offset; | 835 | int ptd_offset; |
860 | struct slotinfo *slots; | 836 | struct isp1760_slotinfo *slots; |
861 | int curr_slot, free_slot; | 837 | int curr_slot, free_slot; |
862 | int n; | 838 | int n; |
863 | struct ptd ptd; | 839 | struct ptd ptd; |
@@ -1097,7 +1073,7 @@ static void handle_done_ptds(struct usb_hcd *hcd) | |||
1097 | struct isp1760_qh *qh; | 1073 | struct isp1760_qh *qh; |
1098 | int slot; | 1074 | int slot; |
1099 | int state; | 1075 | int state; |
1100 | struct slotinfo *slots; | 1076 | struct isp1760_slotinfo *slots; |
1101 | u32 ptd_offset; | 1077 | u32 ptd_offset; |
1102 | struct isp1760_qtd *qtd; | 1078 | struct isp1760_qtd *qtd; |
1103 | int modified; | 1079 | int modified; |
@@ -1359,9 +1335,7 @@ static int isp1760_run(struct usb_hcd *hcd) | |||
1359 | if (retval) | 1335 | if (retval) |
1360 | return retval; | 1336 | return retval; |
1361 | 1337 | ||
1362 | init_timer(&errata2_timer); | 1338 | setup_timer(&errata2_timer, errata2_function, (unsigned long)hcd); |
1363 | errata2_timer.function = errata2_function; | ||
1364 | errata2_timer.data = (unsigned long) hcd; | ||
1365 | errata2_timer.expires = jiffies + SLOT_CHECK_PERIOD * HZ / 1000; | 1339 | errata2_timer.expires = jiffies + SLOT_CHECK_PERIOD * HZ / 1000; |
1366 | add_timer(&errata2_timer); | 1340 | add_timer(&errata2_timer); |
1367 | 1341 | ||
@@ -1798,13 +1772,13 @@ static void isp1760_hub_descriptor(struct isp1760_hcd *priv, | |||
1798 | memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp); | 1772 | memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp); |
1799 | 1773 | ||
1800 | /* per-port overcurrent reporting */ | 1774 | /* per-port overcurrent reporting */ |
1801 | temp = 0x0008; | 1775 | temp = HUB_CHAR_INDV_PORT_OCPM; |
1802 | if (HCS_PPC(priv->hcs_params)) | 1776 | if (HCS_PPC(priv->hcs_params)) |
1803 | /* per-port power control */ | 1777 | /* per-port power control */ |
1804 | temp |= 0x0001; | 1778 | temp |= HUB_CHAR_INDV_PORT_LPSM; |
1805 | else | 1779 | else |
1806 | /* no power switching */ | 1780 | /* no power switching */ |
1807 | temp |= 0x0002; | 1781 | temp |= HUB_CHAR_NO_LPSM; |
1808 | desc->wHubCharacteristics = cpu_to_le16(temp); | 1782 | desc->wHubCharacteristics = cpu_to_le16(temp); |
1809 | } | 1783 | } |
1810 | 1784 | ||
@@ -2163,7 +2137,7 @@ static void isp1760_clear_tt_buffer_complete(struct usb_hcd *hcd, | |||
2163 | static const struct hc_driver isp1760_hc_driver = { | 2137 | static const struct hc_driver isp1760_hc_driver = { |
2164 | .description = "isp1760-hcd", | 2138 | .description = "isp1760-hcd", |
2165 | .product_desc = "NXP ISP1760 USB Host Controller", | 2139 | .product_desc = "NXP ISP1760 USB Host Controller", |
2166 | .hcd_priv_size = sizeof(struct isp1760_hcd), | 2140 | .hcd_priv_size = sizeof(struct isp1760_hcd *), |
2167 | .irq = isp1760_irq, | 2141 | .irq = isp1760_irq, |
2168 | .flags = HCD_MEMORY | HCD_USB2, | 2142 | .flags = HCD_MEMORY | HCD_USB2, |
2169 | .reset = isp1760_hc_setup, | 2143 | .reset = isp1760_hc_setup, |
@@ -2179,7 +2153,7 @@ static const struct hc_driver isp1760_hc_driver = { | |||
2179 | .clear_tt_buffer_complete = isp1760_clear_tt_buffer_complete, | 2153 | .clear_tt_buffer_complete = isp1760_clear_tt_buffer_complete, |
2180 | }; | 2154 | }; |
2181 | 2155 | ||
2182 | int __init init_kmem_once(void) | 2156 | int __init isp1760_init_kmem_once(void) |
2183 | { | 2157 | { |
2184 | urb_listitem_cachep = kmem_cache_create("isp1760_urb_listitem", | 2158 | urb_listitem_cachep = kmem_cache_create("isp1760_urb_listitem", |
2185 | sizeof(struct urb_listitem), 0, SLAB_TEMPORARY | | 2159 | sizeof(struct urb_listitem), 0, SLAB_TEMPORARY | |
@@ -2206,63 +2180,56 @@ int __init init_kmem_once(void) | |||
2206 | return 0; | 2180 | return 0; |
2207 | } | 2181 | } |
2208 | 2182 | ||
2209 | void deinit_kmem_cache(void) | 2183 | void isp1760_deinit_kmem_cache(void) |
2210 | { | 2184 | { |
2211 | kmem_cache_destroy(qtd_cachep); | 2185 | kmem_cache_destroy(qtd_cachep); |
2212 | kmem_cache_destroy(qh_cachep); | 2186 | kmem_cache_destroy(qh_cachep); |
2213 | kmem_cache_destroy(urb_listitem_cachep); | 2187 | kmem_cache_destroy(urb_listitem_cachep); |
2214 | } | 2188 | } |
2215 | 2189 | ||
2216 | struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len, | 2190 | int isp1760_hcd_register(struct isp1760_hcd *priv, void __iomem *regs, |
2217 | int irq, unsigned long irqflags, | 2191 | struct resource *mem, int irq, unsigned long irqflags, |
2218 | int rst_gpio, | 2192 | struct device *dev) |
2219 | struct device *dev, const char *busname, | ||
2220 | unsigned int devflags) | ||
2221 | { | 2193 | { |
2222 | struct usb_hcd *hcd; | 2194 | struct usb_hcd *hcd; |
2223 | struct isp1760_hcd *priv; | ||
2224 | int ret; | 2195 | int ret; |
2225 | 2196 | ||
2226 | if (usb_disabled()) | ||
2227 | return ERR_PTR(-ENODEV); | ||
2228 | |||
2229 | /* prevent usb-core allocating DMA pages */ | ||
2230 | dev->dma_mask = NULL; | ||
2231 | |||
2232 | hcd = usb_create_hcd(&isp1760_hc_driver, dev, dev_name(dev)); | 2197 | hcd = usb_create_hcd(&isp1760_hc_driver, dev, dev_name(dev)); |
2233 | if (!hcd) | 2198 | if (!hcd) |
2234 | return ERR_PTR(-ENOMEM); | 2199 | return -ENOMEM; |
2200 | |||
2201 | *(struct isp1760_hcd **)hcd->hcd_priv = priv; | ||
2202 | |||
2203 | priv->hcd = hcd; | ||
2235 | 2204 | ||
2236 | priv = hcd_to_priv(hcd); | ||
2237 | priv->devflags = devflags; | ||
2238 | priv->rst_gpio = rst_gpio; | ||
2239 | init_memory(priv); | 2205 | init_memory(priv); |
2240 | hcd->regs = ioremap(res_start, res_len); | ||
2241 | if (!hcd->regs) { | ||
2242 | ret = -EIO; | ||
2243 | goto err_put; | ||
2244 | } | ||
2245 | 2206 | ||
2246 | hcd->irq = irq; | 2207 | hcd->irq = irq; |
2247 | hcd->rsrc_start = res_start; | 2208 | hcd->regs = regs; |
2248 | hcd->rsrc_len = res_len; | 2209 | hcd->rsrc_start = mem->start; |
2210 | hcd->rsrc_len = resource_size(mem); | ||
2211 | |||
2212 | /* This driver doesn't support wakeup requests */ | ||
2213 | hcd->cant_recv_wakeups = 1; | ||
2249 | 2214 | ||
2250 | ret = usb_add_hcd(hcd, irq, irqflags); | 2215 | ret = usb_add_hcd(hcd, irq, irqflags); |
2251 | if (ret) | 2216 | if (ret) |
2252 | goto err_unmap; | 2217 | goto error; |
2218 | |||
2253 | device_wakeup_enable(hcd->self.controller); | 2219 | device_wakeup_enable(hcd->self.controller); |
2254 | 2220 | ||
2255 | return hcd; | 2221 | return 0; |
2256 | 2222 | ||
2257 | err_unmap: | 2223 | error: |
2258 | iounmap(hcd->regs); | 2224 | usb_put_hcd(hcd); |
2225 | return ret; | ||
2226 | } | ||
2259 | 2227 | ||
2260 | err_put: | 2228 | void isp1760_hcd_unregister(struct isp1760_hcd *priv) |
2261 | usb_put_hcd(hcd); | 2229 | { |
2230 | if (!priv->hcd) | ||
2231 | return; | ||
2262 | 2232 | ||
2263 | return ERR_PTR(ret); | 2233 | usb_remove_hcd(priv->hcd); |
2234 | usb_put_hcd(priv->hcd); | ||
2264 | } | 2235 | } |
2265 | |||
2266 | MODULE_DESCRIPTION("Driver for the ISP1760 USB-controller from NXP"); | ||
2267 | MODULE_AUTHOR("Sebastian Siewior <bigeasy@linuxtronix.de>"); | ||
2268 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/usb/isp1760/isp1760-hcd.h b/drivers/usb/isp1760/isp1760-hcd.h new file mode 100644 index 000000000000..0c1c98d6ea08 --- /dev/null +++ b/drivers/usb/isp1760/isp1760-hcd.h | |||
@@ -0,0 +1,102 @@ | |||
1 | #ifndef _ISP1760_HCD_H_ | ||
2 | #define _ISP1760_HCD_H_ | ||
3 | |||
4 | #include <linux/spinlock.h> | ||
5 | |||
6 | struct isp1760_qh; | ||
7 | struct isp1760_qtd; | ||
8 | struct resource; | ||
9 | struct usb_hcd; | ||
10 | |||
11 | /* | ||
12 | * 60kb divided in: | ||
13 | * - 32 blocks @ 256 bytes | ||
14 | * - 20 blocks @ 1024 bytes | ||
15 | * - 4 blocks @ 8192 bytes | ||
16 | */ | ||
17 | |||
18 | #define BLOCK_1_NUM 32 | ||
19 | #define BLOCK_2_NUM 20 | ||
20 | #define BLOCK_3_NUM 4 | ||
21 | |||
22 | #define BLOCK_1_SIZE 256 | ||
23 | #define BLOCK_2_SIZE 1024 | ||
24 | #define BLOCK_3_SIZE 8192 | ||
25 | #define BLOCKS (BLOCK_1_NUM + BLOCK_2_NUM + BLOCK_3_NUM) | ||
26 | #define MAX_PAYLOAD_SIZE BLOCK_3_SIZE | ||
27 | #define PAYLOAD_AREA_SIZE 0xf000 | ||
28 | |||
29 | struct isp1760_slotinfo { | ||
30 | struct isp1760_qh *qh; | ||
31 | struct isp1760_qtd *qtd; | ||
32 | unsigned long timestamp; | ||
33 | }; | ||
34 | |||
35 | /* chip memory management */ | ||
36 | struct isp1760_memory_chunk { | ||
37 | unsigned int start; | ||
38 | unsigned int size; | ||
39 | unsigned int free; | ||
40 | }; | ||
41 | |||
42 | enum isp1760_queue_head_types { | ||
43 | QH_CONTROL, | ||
44 | QH_BULK, | ||
45 | QH_INTERRUPT, | ||
46 | QH_END | ||
47 | }; | ||
48 | |||
49 | struct isp1760_hcd { | ||
50 | #ifdef CONFIG_USB_ISP1760_HCD | ||
51 | struct usb_hcd *hcd; | ||
52 | |||
53 | u32 hcs_params; | ||
54 | spinlock_t lock; | ||
55 | struct isp1760_slotinfo atl_slots[32]; | ||
56 | int atl_done_map; | ||
57 | struct isp1760_slotinfo int_slots[32]; | ||
58 | int int_done_map; | ||
59 | struct isp1760_memory_chunk memory_pool[BLOCKS]; | ||
60 | struct list_head qh_list[QH_END]; | ||
61 | |||
62 | /* periodic schedule support */ | ||
63 | #define DEFAULT_I_TDPS 1024 | ||
64 | unsigned periodic_size; | ||
65 | unsigned i_thresh; | ||
66 | unsigned long reset_done; | ||
67 | unsigned long next_statechange; | ||
68 | #endif | ||
69 | }; | ||
70 | |||
71 | #ifdef CONFIG_USB_ISP1760_HCD | ||
72 | int isp1760_hcd_register(struct isp1760_hcd *priv, void __iomem *regs, | ||
73 | struct resource *mem, int irq, unsigned long irqflags, | ||
74 | struct device *dev); | ||
75 | void isp1760_hcd_unregister(struct isp1760_hcd *priv); | ||
76 | |||
77 | int isp1760_init_kmem_once(void); | ||
78 | void isp1760_deinit_kmem_cache(void); | ||
79 | #else | ||
80 | static inline int isp1760_hcd_register(struct isp1760_hcd *priv, | ||
81 | void __iomem *regs, struct resource *mem, | ||
82 | int irq, unsigned long irqflags, | ||
83 | struct device *dev) | ||
84 | { | ||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | static inline void isp1760_hcd_unregister(struct isp1760_hcd *priv) | ||
89 | { | ||
90 | } | ||
91 | |||
92 | static inline int isp1760_init_kmem_once(void) | ||
93 | { | ||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | static inline void isp1760_deinit_kmem_cache(void) | ||
98 | { | ||
99 | } | ||
100 | #endif | ||
101 | |||
102 | #endif /* _ISP1760_HCD_H_ */ | ||
diff --git a/drivers/usb/isp1760/isp1760-if.c b/drivers/usb/isp1760/isp1760-if.c new file mode 100644 index 000000000000..264be4d21706 --- /dev/null +++ b/drivers/usb/isp1760/isp1760-if.c | |||
@@ -0,0 +1,309 @@ | |||
1 | /* | ||
2 | * Glue code for the ISP1760 driver and bus | ||
3 | * Currently there is support for | ||
4 | * - OpenFirmware | ||
5 | * - PCI | ||
6 | * - PDEV (generic platform device centralized driver model) | ||
7 | * | ||
8 | * (c) 2007 Sebastian Siewior <bigeasy@linutronix.de> | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/usb.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/of.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/slab.h> | ||
18 | #include <linux/usb/isp1760.h> | ||
19 | #include <linux/usb/hcd.h> | ||
20 | |||
21 | #include "isp1760-core.h" | ||
22 | #include "isp1760-regs.h" | ||
23 | |||
24 | #ifdef CONFIG_PCI | ||
25 | #include <linux/pci.h> | ||
26 | #endif | ||
27 | |||
28 | #ifdef CONFIG_PCI | ||
29 | static int isp1761_pci_init(struct pci_dev *dev) | ||
30 | { | ||
31 | resource_size_t mem_start; | ||
32 | resource_size_t mem_length; | ||
33 | u8 __iomem *iobase; | ||
34 | u8 latency, limit; | ||
35 | int retry_count; | ||
36 | u32 reg_data; | ||
37 | |||
38 | /* Grab the PLX PCI shared memory of the ISP 1761 we need */ | ||
39 | mem_start = pci_resource_start(dev, 3); | ||
40 | mem_length = pci_resource_len(dev, 3); | ||
41 | if (mem_length < 0xffff) { | ||
42 | printk(KERN_ERR "memory length for this resource is wrong\n"); | ||
43 | return -ENOMEM; | ||
44 | } | ||
45 | |||
46 | if (!request_mem_region(mem_start, mem_length, "ISP-PCI")) { | ||
47 | printk(KERN_ERR "host controller already in use\n"); | ||
48 | return -EBUSY; | ||
49 | } | ||
50 | |||
51 | /* map available memory */ | ||
52 | iobase = ioremap_nocache(mem_start, mem_length); | ||
53 | if (!iobase) { | ||
54 | printk(KERN_ERR "Error ioremap failed\n"); | ||
55 | release_mem_region(mem_start, mem_length); | ||
56 | return -ENOMEM; | ||
57 | } | ||
58 | |||
59 | /* bad pci latencies can contribute to overruns */ | ||
60 | pci_read_config_byte(dev, PCI_LATENCY_TIMER, &latency); | ||
61 | if (latency) { | ||
62 | pci_read_config_byte(dev, PCI_MAX_LAT, &limit); | ||
63 | if (limit && limit < latency) | ||
64 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, limit); | ||
65 | } | ||
66 | |||
67 | /* Try to check whether we can access Scratch Register of | ||
68 | * Host Controller or not. The initial PCI access is retried until | ||
69 | * local init for the PCI bridge is completed | ||
70 | */ | ||
71 | retry_count = 20; | ||
72 | reg_data = 0; | ||
73 | while ((reg_data != 0xFACE) && retry_count) { | ||
74 | /*by default host is in 16bit mode, so | ||
75 | * io operations at this stage must be 16 bit | ||
76 | * */ | ||
77 | writel(0xface, iobase + HC_SCRATCH_REG); | ||
78 | udelay(100); | ||
79 | reg_data = readl(iobase + HC_SCRATCH_REG) & 0x0000ffff; | ||
80 | retry_count--; | ||
81 | } | ||
82 | |||
83 | iounmap(iobase); | ||
84 | release_mem_region(mem_start, mem_length); | ||
85 | |||
86 | /* Host Controller presence is detected by writing to scratch register | ||
87 | * and reading back and checking the contents are same or not | ||
88 | */ | ||
89 | if (reg_data != 0xFACE) { | ||
90 | dev_err(&dev->dev, "scratch register mismatch %x\n", reg_data); | ||
91 | return -ENOMEM; | ||
92 | } | ||
93 | |||
94 | /* Grab the PLX PCI mem maped port start address we need */ | ||
95 | mem_start = pci_resource_start(dev, 0); | ||
96 | mem_length = pci_resource_len(dev, 0); | ||
97 | |||
98 | if (!request_mem_region(mem_start, mem_length, "ISP1761 IO MEM")) { | ||
99 | printk(KERN_ERR "request region #1\n"); | ||
100 | return -EBUSY; | ||
101 | } | ||
102 | |||
103 | iobase = ioremap_nocache(mem_start, mem_length); | ||
104 | if (!iobase) { | ||
105 | printk(KERN_ERR "ioremap #1\n"); | ||
106 | release_mem_region(mem_start, mem_length); | ||
107 | return -ENOMEM; | ||
108 | } | ||
109 | |||
110 | /* configure PLX PCI chip to pass interrupts */ | ||
111 | #define PLX_INT_CSR_REG 0x68 | ||
112 | reg_data = readl(iobase + PLX_INT_CSR_REG); | ||
113 | reg_data |= 0x900; | ||
114 | writel(reg_data, iobase + PLX_INT_CSR_REG); | ||
115 | |||
116 | /* done with PLX IO access */ | ||
117 | iounmap(iobase); | ||
118 | release_mem_region(mem_start, mem_length); | ||
119 | |||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | static int isp1761_pci_probe(struct pci_dev *dev, | ||
124 | const struct pci_device_id *id) | ||
125 | { | ||
126 | unsigned int devflags = 0; | ||
127 | int ret; | ||
128 | |||
129 | if (!dev->irq) | ||
130 | return -ENODEV; | ||
131 | |||
132 | if (pci_enable_device(dev) < 0) | ||
133 | return -ENODEV; | ||
134 | |||
135 | ret = isp1761_pci_init(dev); | ||
136 | if (ret < 0) | ||
137 | goto error; | ||
138 | |||
139 | pci_set_master(dev); | ||
140 | |||
141 | dev->dev.dma_mask = NULL; | ||
142 | ret = isp1760_register(&dev->resource[3], dev->irq, 0, &dev->dev, | ||
143 | devflags); | ||
144 | if (ret < 0) | ||
145 | goto error; | ||
146 | |||
147 | return 0; | ||
148 | |||
149 | error: | ||
150 | pci_disable_device(dev); | ||
151 | return ret; | ||
152 | } | ||
153 | |||
154 | static void isp1761_pci_remove(struct pci_dev *dev) | ||
155 | { | ||
156 | isp1760_unregister(&dev->dev); | ||
157 | |||
158 | pci_disable_device(dev); | ||
159 | } | ||
160 | |||
161 | static void isp1761_pci_shutdown(struct pci_dev *dev) | ||
162 | { | ||
163 | printk(KERN_ERR "ips1761_pci_shutdown\n"); | ||
164 | } | ||
165 | |||
166 | static const struct pci_device_id isp1760_plx [] = { | ||
167 | { | ||
168 | .class = PCI_CLASS_BRIDGE_OTHER << 8, | ||
169 | .class_mask = ~0, | ||
170 | .vendor = PCI_VENDOR_ID_PLX, | ||
171 | .device = 0x5406, | ||
172 | .subvendor = PCI_VENDOR_ID_PLX, | ||
173 | .subdevice = 0x9054, | ||
174 | }, | ||
175 | { } | ||
176 | }; | ||
177 | MODULE_DEVICE_TABLE(pci, isp1760_plx); | ||
178 | |||
179 | static struct pci_driver isp1761_pci_driver = { | ||
180 | .name = "isp1760", | ||
181 | .id_table = isp1760_plx, | ||
182 | .probe = isp1761_pci_probe, | ||
183 | .remove = isp1761_pci_remove, | ||
184 | .shutdown = isp1761_pci_shutdown, | ||
185 | }; | ||
186 | #endif | ||
187 | |||
188 | static int isp1760_plat_probe(struct platform_device *pdev) | ||
189 | { | ||
190 | unsigned long irqflags; | ||
191 | unsigned int devflags = 0; | ||
192 | struct resource *mem_res; | ||
193 | struct resource *irq_res; | ||
194 | int ret; | ||
195 | |||
196 | mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
197 | |||
198 | irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
199 | if (!irq_res) { | ||
200 | pr_warning("isp1760: IRQ resource not available\n"); | ||
201 | return -ENODEV; | ||
202 | } | ||
203 | irqflags = irq_res->flags & IRQF_TRIGGER_MASK; | ||
204 | |||
205 | if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) { | ||
206 | struct device_node *dp = pdev->dev.of_node; | ||
207 | u32 bus_width = 0; | ||
208 | |||
209 | if (of_device_is_compatible(dp, "nxp,usb-isp1761")) | ||
210 | devflags |= ISP1760_FLAG_ISP1761; | ||
211 | |||
212 | /* Some systems wire up only 16 of the 32 data lines */ | ||
213 | of_property_read_u32(dp, "bus-width", &bus_width); | ||
214 | if (bus_width == 16) | ||
215 | devflags |= ISP1760_FLAG_BUS_WIDTH_16; | ||
216 | |||
217 | if (of_property_read_bool(dp, "port1-otg")) | ||
218 | devflags |= ISP1760_FLAG_OTG_EN; | ||
219 | |||
220 | if (of_property_read_bool(dp, "analog-oc")) | ||
221 | devflags |= ISP1760_FLAG_ANALOG_OC; | ||
222 | |||
223 | if (of_property_read_bool(dp, "dack-polarity")) | ||
224 | devflags |= ISP1760_FLAG_DACK_POL_HIGH; | ||
225 | |||
226 | if (of_property_read_bool(dp, "dreq-polarity")) | ||
227 | devflags |= ISP1760_FLAG_DREQ_POL_HIGH; | ||
228 | } else if (dev_get_platdata(&pdev->dev)) { | ||
229 | struct isp1760_platform_data *pdata = | ||
230 | dev_get_platdata(&pdev->dev); | ||
231 | |||
232 | if (pdata->is_isp1761) | ||
233 | devflags |= ISP1760_FLAG_ISP1761; | ||
234 | if (pdata->bus_width_16) | ||
235 | devflags |= ISP1760_FLAG_BUS_WIDTH_16; | ||
236 | if (pdata->port1_otg) | ||
237 | devflags |= ISP1760_FLAG_OTG_EN; | ||
238 | if (pdata->analog_oc) | ||
239 | devflags |= ISP1760_FLAG_ANALOG_OC; | ||
240 | if (pdata->dack_polarity_high) | ||
241 | devflags |= ISP1760_FLAG_DACK_POL_HIGH; | ||
242 | if (pdata->dreq_polarity_high) | ||
243 | devflags |= ISP1760_FLAG_DREQ_POL_HIGH; | ||
244 | } | ||
245 | |||
246 | ret = isp1760_register(mem_res, irq_res->start, irqflags, &pdev->dev, | ||
247 | devflags); | ||
248 | if (ret < 0) | ||
249 | return ret; | ||
250 | |||
251 | pr_info("ISP1760 USB device initialised\n"); | ||
252 | return 0; | ||
253 | } | ||
254 | |||
255 | static int isp1760_plat_remove(struct platform_device *pdev) | ||
256 | { | ||
257 | isp1760_unregister(&pdev->dev); | ||
258 | |||
259 | return 0; | ||
260 | } | ||
261 | |||
262 | #ifdef CONFIG_OF | ||
263 | static const struct of_device_id isp1760_of_match[] = { | ||
264 | { .compatible = "nxp,usb-isp1760", }, | ||
265 | { .compatible = "nxp,usb-isp1761", }, | ||
266 | { }, | ||
267 | }; | ||
268 | MODULE_DEVICE_TABLE(of, isp1760_of_match); | ||
269 | #endif | ||
270 | |||
271 | static struct platform_driver isp1760_plat_driver = { | ||
272 | .probe = isp1760_plat_probe, | ||
273 | .remove = isp1760_plat_remove, | ||
274 | .driver = { | ||
275 | .name = "isp1760", | ||
276 | .of_match_table = of_match_ptr(isp1760_of_match), | ||
277 | }, | ||
278 | }; | ||
279 | |||
280 | static int __init isp1760_init(void) | ||
281 | { | ||
282 | int ret, any_ret = -ENODEV; | ||
283 | |||
284 | isp1760_init_kmem_once(); | ||
285 | |||
286 | ret = platform_driver_register(&isp1760_plat_driver); | ||
287 | if (!ret) | ||
288 | any_ret = 0; | ||
289 | #ifdef CONFIG_PCI | ||
290 | ret = pci_register_driver(&isp1761_pci_driver); | ||
291 | if (!ret) | ||
292 | any_ret = 0; | ||
293 | #endif | ||
294 | |||
295 | if (any_ret) | ||
296 | isp1760_deinit_kmem_cache(); | ||
297 | return any_ret; | ||
298 | } | ||
299 | module_init(isp1760_init); | ||
300 | |||
301 | static void __exit isp1760_exit(void) | ||
302 | { | ||
303 | platform_driver_unregister(&isp1760_plat_driver); | ||
304 | #ifdef CONFIG_PCI | ||
305 | pci_unregister_driver(&isp1761_pci_driver); | ||
306 | #endif | ||
307 | isp1760_deinit_kmem_cache(); | ||
308 | } | ||
309 | module_exit(isp1760_exit); | ||
diff --git a/drivers/usb/isp1760/isp1760-regs.h b/drivers/usb/isp1760/isp1760-regs.h new file mode 100644 index 000000000000..b67095c9a9d4 --- /dev/null +++ b/drivers/usb/isp1760/isp1760-regs.h | |||
@@ -0,0 +1,230 @@ | |||
1 | /* | ||
2 | * Driver for the NXP ISP1760 chip | ||
3 | * | ||
4 | * Copyright 2014 Laurent Pinchart | ||
5 | * Copyright 2007 Sebastian Siewior | ||
6 | * | ||
7 | * Contacts: | ||
8 | * Sebastian Siewior <bigeasy@linutronix.de> | ||
9 | * Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License | ||
13 | * version 2 as published by the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | #ifndef _ISP1760_REGS_H_ | ||
17 | #define _ISP1760_REGS_H_ | ||
18 | |||
19 | /* ----------------------------------------------------------------------------- | ||
20 | * Host Controller | ||
21 | */ | ||
22 | |||
23 | /* EHCI capability registers */ | ||
24 | #define HC_CAPLENGTH 0x000 | ||
25 | #define HC_LENGTH(p) (((p) >> 00) & 0x00ff) /* bits 7:0 */ | ||
26 | #define HC_VERSION(p) (((p) >> 16) & 0xffff) /* bits 31:16 */ | ||
27 | |||
28 | #define HC_HCSPARAMS 0x004 | ||
29 | #define HCS_INDICATOR(p) ((p) & (1 << 16)) /* true: has port indicators */ | ||
30 | #define HCS_PPC(p) ((p) & (1 << 4)) /* true: port power control */ | ||
31 | #define HCS_N_PORTS(p) (((p) >> 0) & 0xf) /* bits 3:0, ports on HC */ | ||
32 | |||
33 | #define HC_HCCPARAMS 0x008 | ||
34 | #define HCC_ISOC_CACHE(p) ((p) & (1 << 7)) /* true: can cache isoc frame */ | ||
35 | #define HCC_ISOC_THRES(p) (((p) >> 4) & 0x7) /* bits 6:4, uframes cached */ | ||
36 | |||
37 | /* EHCI operational registers */ | ||
38 | #define HC_USBCMD 0x020 | ||
39 | #define CMD_LRESET (1 << 7) /* partial reset (no ports, etc) */ | ||
40 | #define CMD_RESET (1 << 1) /* reset HC not bus */ | ||
41 | #define CMD_RUN (1 << 0) /* start/stop HC */ | ||
42 | |||
43 | #define HC_USBSTS 0x024 | ||
44 | #define STS_PCD (1 << 2) /* port change detect */ | ||
45 | |||
46 | #define HC_FRINDEX 0x02c | ||
47 | |||
48 | #define HC_CONFIGFLAG 0x060 | ||
49 | #define FLAG_CF (1 << 0) /* true: we'll support "high speed" */ | ||
50 | |||
51 | #define HC_PORTSC1 0x064 | ||
52 | #define PORT_OWNER (1 << 13) /* true: companion hc owns this port */ | ||
53 | #define PORT_POWER (1 << 12) /* true: has power (see PPC) */ | ||
54 | #define PORT_USB11(x) (((x) & (3 << 10)) == (1 << 10)) /* USB 1.1 device */ | ||
55 | #define PORT_RESET (1 << 8) /* reset port */ | ||
56 | #define PORT_SUSPEND (1 << 7) /* suspend port */ | ||
57 | #define PORT_RESUME (1 << 6) /* resume it */ | ||
58 | #define PORT_PE (1 << 2) /* port enable */ | ||
59 | #define PORT_CSC (1 << 1) /* connect status change */ | ||
60 | #define PORT_CONNECT (1 << 0) /* device connected */ | ||
61 | #define PORT_RWC_BITS (PORT_CSC) | ||
62 | |||
63 | #define HC_ISO_PTD_DONEMAP_REG 0x130 | ||
64 | #define HC_ISO_PTD_SKIPMAP_REG 0x134 | ||
65 | #define HC_ISO_PTD_LASTPTD_REG 0x138 | ||
66 | #define HC_INT_PTD_DONEMAP_REG 0x140 | ||
67 | #define HC_INT_PTD_SKIPMAP_REG 0x144 | ||
68 | #define HC_INT_PTD_LASTPTD_REG 0x148 | ||
69 | #define HC_ATL_PTD_DONEMAP_REG 0x150 | ||
70 | #define HC_ATL_PTD_SKIPMAP_REG 0x154 | ||
71 | #define HC_ATL_PTD_LASTPTD_REG 0x158 | ||
72 | |||
73 | /* Configuration Register */ | ||
74 | #define HC_HW_MODE_CTRL 0x300 | ||
75 | #define ALL_ATX_RESET (1 << 31) | ||
76 | #define HW_ANA_DIGI_OC (1 << 15) | ||
77 | #define HW_DEV_DMA (1 << 11) | ||
78 | #define HW_COMN_IRQ (1 << 10) | ||
79 | #define HW_COMN_DMA (1 << 9) | ||
80 | #define HW_DATA_BUS_32BIT (1 << 8) | ||
81 | #define HW_DACK_POL_HIGH (1 << 6) | ||
82 | #define HW_DREQ_POL_HIGH (1 << 5) | ||
83 | #define HW_INTR_HIGH_ACT (1 << 2) | ||
84 | #define HW_INTR_EDGE_TRIG (1 << 1) | ||
85 | #define HW_GLOBAL_INTR_EN (1 << 0) | ||
86 | |||
87 | #define HC_CHIP_ID_REG 0x304 | ||
88 | #define HC_SCRATCH_REG 0x308 | ||
89 | |||
90 | #define HC_RESET_REG 0x30c | ||
91 | #define SW_RESET_RESET_HC (1 << 1) | ||
92 | #define SW_RESET_RESET_ALL (1 << 0) | ||
93 | |||
94 | #define HC_BUFFER_STATUS_REG 0x334 | ||
95 | #define ISO_BUF_FILL (1 << 2) | ||
96 | #define INT_BUF_FILL (1 << 1) | ||
97 | #define ATL_BUF_FILL (1 << 0) | ||
98 | |||
99 | #define HC_MEMORY_REG 0x33c | ||
100 | #define ISP_BANK(x) ((x) << 16) | ||
101 | |||
102 | #define HC_PORT1_CTRL 0x374 | ||
103 | #define PORT1_POWER (3 << 3) | ||
104 | #define PORT1_INIT1 (1 << 7) | ||
105 | #define PORT1_INIT2 (1 << 23) | ||
106 | #define HW_OTG_CTRL_SET 0x374 | ||
107 | #define HW_OTG_CTRL_CLR 0x376 | ||
108 | #define HW_OTG_DISABLE (1 << 10) | ||
109 | #define HW_OTG_SE0_EN (1 << 9) | ||
110 | #define HW_BDIS_ACON_EN (1 << 8) | ||
111 | #define HW_SW_SEL_HC_DC (1 << 7) | ||
112 | #define HW_VBUS_CHRG (1 << 6) | ||
113 | #define HW_VBUS_DISCHRG (1 << 5) | ||
114 | #define HW_VBUS_DRV (1 << 4) | ||
115 | #define HW_SEL_CP_EXT (1 << 3) | ||
116 | #define HW_DM_PULLDOWN (1 << 2) | ||
117 | #define HW_DP_PULLDOWN (1 << 1) | ||
118 | #define HW_DP_PULLUP (1 << 0) | ||
119 | |||
120 | /* Interrupt Register */ | ||
121 | #define HC_INTERRUPT_REG 0x310 | ||
122 | |||
123 | #define HC_INTERRUPT_ENABLE 0x314 | ||
124 | #define HC_ISO_INT (1 << 9) | ||
125 | #define HC_ATL_INT (1 << 8) | ||
126 | #define HC_INTL_INT (1 << 7) | ||
127 | #define HC_EOT_INT (1 << 3) | ||
128 | #define HC_SOT_INT (1 << 1) | ||
129 | #define INTERRUPT_ENABLE_MASK (HC_INTL_INT | HC_ATL_INT) | ||
130 | |||
131 | #define HC_ISO_IRQ_MASK_OR_REG 0x318 | ||
132 | #define HC_INT_IRQ_MASK_OR_REG 0x31c | ||
133 | #define HC_ATL_IRQ_MASK_OR_REG 0x320 | ||
134 | #define HC_ISO_IRQ_MASK_AND_REG 0x324 | ||
135 | #define HC_INT_IRQ_MASK_AND_REG 0x328 | ||
136 | #define HC_ATL_IRQ_MASK_AND_REG 0x32c | ||
137 | |||
138 | /* ----------------------------------------------------------------------------- | ||
139 | * Peripheral Controller | ||
140 | */ | ||
141 | |||
142 | /* Initialization Registers */ | ||
143 | #define DC_ADDRESS 0x0200 | ||
144 | #define DC_DEVEN (1 << 7) | ||
145 | |||
146 | #define DC_MODE 0x020c | ||
147 | #define DC_DMACLKON (1 << 9) | ||
148 | #define DC_VBUSSTAT (1 << 8) | ||
149 | #define DC_CLKAON (1 << 7) | ||
150 | #define DC_SNDRSU (1 << 6) | ||
151 | #define DC_GOSUSP (1 << 5) | ||
152 | #define DC_SFRESET (1 << 4) | ||
153 | #define DC_GLINTENA (1 << 3) | ||
154 | #define DC_WKUPCS (1 << 2) | ||
155 | |||
156 | #define DC_INTCONF 0x0210 | ||
157 | #define DC_CDBGMOD_ACK_NAK (0 << 6) | ||
158 | #define DC_CDBGMOD_ACK (1 << 6) | ||
159 | #define DC_CDBGMOD_ACK_1NAK (2 << 6) | ||
160 | #define DC_DDBGMODIN_ACK_NAK (0 << 4) | ||
161 | #define DC_DDBGMODIN_ACK (1 << 4) | ||
162 | #define DC_DDBGMODIN_ACK_1NAK (2 << 4) | ||
163 | #define DC_DDBGMODOUT_ACK_NYET_NAK (0 << 2) | ||
164 | #define DC_DDBGMODOUT_ACK_NYET (1 << 2) | ||
165 | #define DC_DDBGMODOUT_ACK_NYET_1NAK (2 << 2) | ||
166 | #define DC_INTLVL (1 << 1) | ||
167 | #define DC_INTPOL (1 << 0) | ||
168 | |||
169 | #define DC_DEBUG 0x0212 | ||
170 | #define DC_INTENABLE 0x0214 | ||
171 | #define DC_IEPTX(n) (1 << (11 + 2 * (n))) | ||
172 | #define DC_IEPRX(n) (1 << (10 + 2 * (n))) | ||
173 | #define DC_IEPRXTX(n) (3 << (10 + 2 * (n))) | ||
174 | #define DC_IEP0SETUP (1 << 8) | ||
175 | #define DC_IEVBUS (1 << 7) | ||
176 | #define DC_IEDMA (1 << 6) | ||
177 | #define DC_IEHS_STA (1 << 5) | ||
178 | #define DC_IERESM (1 << 4) | ||
179 | #define DC_IESUSP (1 << 3) | ||
180 | #define DC_IEPSOF (1 << 2) | ||
181 | #define DC_IESOF (1 << 1) | ||
182 | #define DC_IEBRST (1 << 0) | ||
183 | |||
184 | /* Data Flow Registers */ | ||
185 | #define DC_EPINDEX 0x022c | ||
186 | #define DC_EP0SETUP (1 << 5) | ||
187 | #define DC_ENDPIDX(n) ((n) << 1) | ||
188 | #define DC_EPDIR (1 << 0) | ||
189 | |||
190 | #define DC_CTRLFUNC 0x0228 | ||
191 | #define DC_CLBUF (1 << 4) | ||
192 | #define DC_VENDP (1 << 3) | ||
193 | #define DC_DSEN (1 << 2) | ||
194 | #define DC_STATUS (1 << 1) | ||
195 | #define DC_STALL (1 << 0) | ||
196 | |||
197 | #define DC_DATAPORT 0x0220 | ||
198 | #define DC_BUFLEN 0x021c | ||
199 | #define DC_DATACOUNT_MASK 0xffff | ||
200 | #define DC_BUFSTAT 0x021e | ||
201 | #define DC_EPMAXPKTSZ 0x0204 | ||
202 | |||
203 | #define DC_EPTYPE 0x0208 | ||
204 | #define DC_NOEMPKT (1 << 4) | ||
205 | #define DC_EPENABLE (1 << 3) | ||
206 | #define DC_DBLBUF (1 << 2) | ||
207 | #define DC_ENDPTYP_ISOC (1 << 0) | ||
208 | #define DC_ENDPTYP_BULK (2 << 0) | ||
209 | #define DC_ENDPTYP_INTERRUPT (3 << 0) | ||
210 | |||
211 | /* DMA Registers */ | ||
212 | #define DC_DMACMD 0x0230 | ||
213 | #define DC_DMATXCOUNT 0x0234 | ||
214 | #define DC_DMACONF 0x0238 | ||
215 | #define DC_DMAHW 0x023c | ||
216 | #define DC_DMAINTREASON 0x0250 | ||
217 | #define DC_DMAINTEN 0x0254 | ||
218 | #define DC_DMAEP 0x0258 | ||
219 | #define DC_DMABURSTCOUNT 0x0264 | ||
220 | |||
221 | /* General Registers */ | ||
222 | #define DC_INTERRUPT 0x0218 | ||
223 | #define DC_CHIPID 0x0270 | ||
224 | #define DC_FRAMENUM 0x0274 | ||
225 | #define DC_SCRATCH 0x0278 | ||
226 | #define DC_UNLOCKDEV 0x027c | ||
227 | #define DC_INTPULSEWIDTH 0x0280 | ||
228 | #define DC_TESTMODE 0x0284 | ||
229 | |||
230 | #endif | ||
diff --git a/drivers/usb/isp1760/isp1760-udc.c b/drivers/usb/isp1760/isp1760-udc.c new file mode 100644 index 000000000000..9612d7990565 --- /dev/null +++ b/drivers/usb/isp1760/isp1760-udc.c | |||
@@ -0,0 +1,1498 @@ | |||
1 | /* | ||
2 | * Driver for the NXP ISP1761 device controller | ||
3 | * | ||
4 | * Copyright 2014 Ideas on Board Oy | ||
5 | * | ||
6 | * Contacts: | ||
7 | * Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License | ||
11 | * version 2 as published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/list.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/timer.h> | ||
21 | #include <linux/usb.h> | ||
22 | |||
23 | #include "isp1760-core.h" | ||
24 | #include "isp1760-regs.h" | ||
25 | #include "isp1760-udc.h" | ||
26 | |||
27 | #define ISP1760_VBUS_POLL_INTERVAL msecs_to_jiffies(500) | ||
28 | |||
29 | struct isp1760_request { | ||
30 | struct usb_request req; | ||
31 | struct list_head queue; | ||
32 | struct isp1760_ep *ep; | ||
33 | unsigned int packet_size; | ||
34 | }; | ||
35 | |||
36 | static inline struct isp1760_udc *gadget_to_udc(struct usb_gadget *gadget) | ||
37 | { | ||
38 | return container_of(gadget, struct isp1760_udc, gadget); | ||
39 | } | ||
40 | |||
41 | static inline struct isp1760_ep *ep_to_udc_ep(struct usb_ep *ep) | ||
42 | { | ||
43 | return container_of(ep, struct isp1760_ep, ep); | ||
44 | } | ||
45 | |||
46 | static inline struct isp1760_request *req_to_udc_req(struct usb_request *req) | ||
47 | { | ||
48 | return container_of(req, struct isp1760_request, req); | ||
49 | } | ||
50 | |||
51 | static inline u32 isp1760_udc_read(struct isp1760_udc *udc, u16 reg) | ||
52 | { | ||
53 | return isp1760_read32(udc->regs, reg); | ||
54 | } | ||
55 | |||
56 | static inline void isp1760_udc_write(struct isp1760_udc *udc, u16 reg, u32 val) | ||
57 | { | ||
58 | isp1760_write32(udc->regs, reg, val); | ||
59 | } | ||
60 | |||
61 | /* ----------------------------------------------------------------------------- | ||
62 | * Endpoint Management | ||
63 | */ | ||
64 | |||
65 | static struct isp1760_ep *isp1760_udc_find_ep(struct isp1760_udc *udc, | ||
66 | u16 index) | ||
67 | { | ||
68 | unsigned int i; | ||
69 | |||
70 | if (index == 0) | ||
71 | return &udc->ep[0]; | ||
72 | |||
73 | for (i = 1; i < ARRAY_SIZE(udc->ep); ++i) { | ||
74 | if (udc->ep[i].addr == index) | ||
75 | return udc->ep[i].desc ? &udc->ep[i] : NULL; | ||
76 | } | ||
77 | |||
78 | return NULL; | ||
79 | } | ||
80 | |||
81 | static void __isp1760_udc_select_ep(struct isp1760_ep *ep, int dir) | ||
82 | { | ||
83 | isp1760_udc_write(ep->udc, DC_EPINDEX, | ||
84 | DC_ENDPIDX(ep->addr & USB_ENDPOINT_NUMBER_MASK) | | ||
85 | (dir == USB_DIR_IN ? DC_EPDIR : 0)); | ||
86 | } | ||
87 | |||
88 | /** | ||
89 | * isp1760_udc_select_ep - Select an endpoint for register access | ||
90 | * @ep: The endpoint | ||
91 | * | ||
92 | * The ISP1761 endpoint registers are banked. This function selects the target | ||
93 | * endpoint for banked register access. The selection remains valid until the | ||
94 | * next call to this function, the next direct access to the EPINDEX register | ||
95 | * or the next reset, whichever comes first. | ||
96 | * | ||
97 | * Called with the UDC spinlock held. | ||
98 | */ | ||
99 | static void isp1760_udc_select_ep(struct isp1760_ep *ep) | ||
100 | { | ||
101 | __isp1760_udc_select_ep(ep, ep->addr & USB_ENDPOINT_DIR_MASK); | ||
102 | } | ||
103 | |||
104 | /* Called with the UDC spinlock held. */ | ||
105 | static void isp1760_udc_ctrl_send_status(struct isp1760_ep *ep, int dir) | ||
106 | { | ||
107 | struct isp1760_udc *udc = ep->udc; | ||
108 | |||
109 | /* | ||
110 | * Proceed to the status stage. The status stage data packet flows in | ||
111 | * the direction opposite to the data stage data packets, we thus need | ||
112 | * to select the OUT/IN endpoint for IN/OUT transfers. | ||
113 | */ | ||
114 | isp1760_udc_write(udc, DC_EPINDEX, DC_ENDPIDX(0) | | ||
115 | (dir == USB_DIR_IN ? 0 : DC_EPDIR)); | ||
116 | isp1760_udc_write(udc, DC_CTRLFUNC, DC_STATUS); | ||
117 | |||
118 | /* | ||
119 | * The hardware will terminate the request automatically and go back to | ||
120 | * the setup stage without notifying us. | ||
121 | */ | ||
122 | udc->ep0_state = ISP1760_CTRL_SETUP; | ||
123 | } | ||
124 | |||
125 | /* Called without the UDC spinlock held. */ | ||
126 | static void isp1760_udc_request_complete(struct isp1760_ep *ep, | ||
127 | struct isp1760_request *req, | ||
128 | int status) | ||
129 | { | ||
130 | struct isp1760_udc *udc = ep->udc; | ||
131 | unsigned long flags; | ||
132 | |||
133 | dev_dbg(ep->udc->isp->dev, "completing request %p with status %d\n", | ||
134 | req, status); | ||
135 | |||
136 | req->ep = NULL; | ||
137 | req->req.status = status; | ||
138 | req->req.complete(&ep->ep, &req->req); | ||
139 | |||
140 | spin_lock_irqsave(&udc->lock, flags); | ||
141 | |||
142 | /* | ||
143 | * When completing control OUT requests, move to the status stage after | ||
144 | * calling the request complete callback. This gives the gadget an | ||
145 | * opportunity to stall the control transfer if needed. | ||
146 | */ | ||
147 | if (status == 0 && ep->addr == 0 && udc->ep0_dir == USB_DIR_OUT) | ||
148 | isp1760_udc_ctrl_send_status(ep, USB_DIR_OUT); | ||
149 | |||
150 | spin_unlock_irqrestore(&udc->lock, flags); | ||
151 | } | ||
152 | |||
153 | static void isp1760_udc_ctrl_send_stall(struct isp1760_ep *ep) | ||
154 | { | ||
155 | struct isp1760_udc *udc = ep->udc; | ||
156 | unsigned long flags; | ||
157 | |||
158 | dev_dbg(ep->udc->isp->dev, "%s(ep%02x)\n", __func__, ep->addr); | ||
159 | |||
160 | spin_lock_irqsave(&udc->lock, flags); | ||
161 | |||
162 | /* Stall both the IN and OUT endpoints. */ | ||
163 | __isp1760_udc_select_ep(ep, USB_DIR_OUT); | ||
164 | isp1760_udc_write(udc, DC_CTRLFUNC, DC_STALL); | ||
165 | __isp1760_udc_select_ep(ep, USB_DIR_IN); | ||
166 | isp1760_udc_write(udc, DC_CTRLFUNC, DC_STALL); | ||
167 | |||
168 | /* A protocol stall completes the control transaction. */ | ||
169 | udc->ep0_state = ISP1760_CTRL_SETUP; | ||
170 | |||
171 | spin_unlock_irqrestore(&udc->lock, flags); | ||
172 | } | ||
173 | |||
174 | /* ----------------------------------------------------------------------------- | ||
175 | * Data Endpoints | ||
176 | */ | ||
177 | |||
178 | /* Called with the UDC spinlock held. */ | ||
179 | static bool isp1760_udc_receive(struct isp1760_ep *ep, | ||
180 | struct isp1760_request *req) | ||
181 | { | ||
182 | struct isp1760_udc *udc = ep->udc; | ||
183 | unsigned int len; | ||
184 | u32 *buf; | ||
185 | int i; | ||
186 | |||
187 | isp1760_udc_select_ep(ep); | ||
188 | len = isp1760_udc_read(udc, DC_BUFLEN) & DC_DATACOUNT_MASK; | ||
189 | |||
190 | dev_dbg(udc->isp->dev, "%s: received %u bytes (%u/%u done)\n", | ||
191 | __func__, len, req->req.actual, req->req.length); | ||
192 | |||
193 | len = min(len, req->req.length - req->req.actual); | ||
194 | |||
195 | if (!len) { | ||
196 | /* | ||
197 | * There's no data to be read from the FIFO, acknowledge the RX | ||
198 | * interrupt by clearing the buffer. | ||
199 | * | ||
200 | * TODO: What if another packet arrives in the meantime ? The | ||
201 | * datasheet doesn't clearly document how this should be | ||
202 | * handled. | ||
203 | */ | ||
204 | isp1760_udc_write(udc, DC_CTRLFUNC, DC_CLBUF); | ||
205 | return false; | ||
206 | } | ||
207 | |||
208 | buf = req->req.buf + req->req.actual; | ||
209 | |||
210 | /* | ||
211 | * Make sure not to read more than one extra byte, otherwise data from | ||
212 | * the next packet might be removed from the FIFO. | ||
213 | */ | ||
214 | for (i = len; i > 2; i -= 4, ++buf) | ||
215 | *buf = le32_to_cpu(isp1760_udc_read(udc, DC_DATAPORT)); | ||
216 | if (i > 0) | ||
217 | *(u16 *)buf = le16_to_cpu(readw(udc->regs + DC_DATAPORT)); | ||
218 | |||
219 | req->req.actual += len; | ||
220 | |||
221 | /* | ||
222 | * TODO: The short_not_ok flag isn't supported yet, but isn't used by | ||
223 | * any gadget driver either. | ||
224 | */ | ||
225 | |||
226 | dev_dbg(udc->isp->dev, | ||
227 | "%s: req %p actual/length %u/%u maxpacket %u packet size %u\n", | ||
228 | __func__, req, req->req.actual, req->req.length, ep->maxpacket, | ||
229 | len); | ||
230 | |||
231 | ep->rx_pending = false; | ||
232 | |||
233 | /* | ||
234 | * Complete the request if all data has been received or if a short | ||
235 | * packet has been received. | ||
236 | */ | ||
237 | if (req->req.actual == req->req.length || len < ep->maxpacket) { | ||
238 | list_del(&req->queue); | ||
239 | return true; | ||
240 | } | ||
241 | |||
242 | return false; | ||
243 | } | ||
244 | |||
245 | static void isp1760_udc_transmit(struct isp1760_ep *ep, | ||
246 | struct isp1760_request *req) | ||
247 | { | ||
248 | struct isp1760_udc *udc = ep->udc; | ||
249 | u32 *buf = req->req.buf + req->req.actual; | ||
250 | int i; | ||
251 | |||
252 | req->packet_size = min(req->req.length - req->req.actual, | ||
253 | ep->maxpacket); | ||
254 | |||
255 | dev_dbg(udc->isp->dev, "%s: transferring %u bytes (%u/%u done)\n", | ||
256 | __func__, req->packet_size, req->req.actual, | ||
257 | req->req.length); | ||
258 | |||
259 | __isp1760_udc_select_ep(ep, USB_DIR_IN); | ||
260 | |||
261 | if (req->packet_size) | ||
262 | isp1760_udc_write(udc, DC_BUFLEN, req->packet_size); | ||
263 | |||
264 | /* | ||
265 | * Make sure not to write more than one extra byte, otherwise extra data | ||
266 | * will stay in the FIFO and will be transmitted during the next control | ||
267 | * request. The endpoint control CLBUF bit is supposed to allow flushing | ||
268 | * the FIFO for this kind of conditions, but doesn't seem to work. | ||
269 | */ | ||
270 | for (i = req->packet_size; i > 2; i -= 4, ++buf) | ||
271 | isp1760_udc_write(udc, DC_DATAPORT, cpu_to_le32(*buf)); | ||
272 | if (i > 0) | ||
273 | writew(cpu_to_le16(*(u16 *)buf), udc->regs + DC_DATAPORT); | ||
274 | |||
275 | if (ep->addr == 0) | ||
276 | isp1760_udc_write(udc, DC_CTRLFUNC, DC_DSEN); | ||
277 | if (!req->packet_size) | ||
278 | isp1760_udc_write(udc, DC_CTRLFUNC, DC_VENDP); | ||
279 | } | ||
280 | |||
281 | static void isp1760_ep_rx_ready(struct isp1760_ep *ep) | ||
282 | { | ||
283 | struct isp1760_udc *udc = ep->udc; | ||
284 | struct isp1760_request *req; | ||
285 | bool complete; | ||
286 | |||
287 | spin_lock(&udc->lock); | ||
288 | |||
289 | if (ep->addr == 0 && udc->ep0_state != ISP1760_CTRL_DATA_OUT) { | ||
290 | spin_unlock(&udc->lock); | ||
291 | dev_dbg(udc->isp->dev, "%s: invalid ep0 state %u\n", __func__, | ||
292 | udc->ep0_state); | ||
293 | return; | ||
294 | } | ||
295 | |||
296 | if (ep->addr != 0 && !ep->desc) { | ||
297 | spin_unlock(&udc->lock); | ||
298 | dev_dbg(udc->isp->dev, "%s: ep%02x is disabled\n", __func__, | ||
299 | ep->addr); | ||
300 | return; | ||
301 | } | ||
302 | |||
303 | if (list_empty(&ep->queue)) { | ||
304 | ep->rx_pending = true; | ||
305 | spin_unlock(&udc->lock); | ||
306 | dev_dbg(udc->isp->dev, "%s: ep%02x (%p) has no request queued\n", | ||
307 | __func__, ep->addr, ep); | ||
308 | return; | ||
309 | } | ||
310 | |||
311 | req = list_first_entry(&ep->queue, struct isp1760_request, | ||
312 | queue); | ||
313 | complete = isp1760_udc_receive(ep, req); | ||
314 | |||
315 | spin_unlock(&udc->lock); | ||
316 | |||
317 | if (complete) | ||
318 | isp1760_udc_request_complete(ep, req, 0); | ||
319 | } | ||
320 | |||
321 | static void isp1760_ep_tx_complete(struct isp1760_ep *ep) | ||
322 | { | ||
323 | struct isp1760_udc *udc = ep->udc; | ||
324 | struct isp1760_request *complete = NULL; | ||
325 | struct isp1760_request *req; | ||
326 | bool need_zlp; | ||
327 | |||
328 | spin_lock(&udc->lock); | ||
329 | |||
330 | if (ep->addr == 0 && udc->ep0_state != ISP1760_CTRL_DATA_IN) { | ||
331 | spin_unlock(&udc->lock); | ||
332 | dev_dbg(udc->isp->dev, "TX IRQ: invalid endpoint state %u\n", | ||
333 | udc->ep0_state); | ||
334 | return; | ||
335 | } | ||
336 | |||
337 | if (list_empty(&ep->queue)) { | ||
338 | /* | ||
339 | * This can happen for the control endpoint when the reply to | ||
340 | * the GET_STATUS IN control request is sent directly by the | ||
341 | * setup IRQ handler. Just proceed to the status stage. | ||
342 | */ | ||
343 | if (ep->addr == 0) { | ||
344 | isp1760_udc_ctrl_send_status(ep, USB_DIR_IN); | ||
345 | spin_unlock(&udc->lock); | ||
346 | return; | ||
347 | } | ||
348 | |||
349 | spin_unlock(&udc->lock); | ||
350 | dev_dbg(udc->isp->dev, "%s: ep%02x has no request queued\n", | ||
351 | __func__, ep->addr); | ||
352 | return; | ||
353 | } | ||
354 | |||
355 | req = list_first_entry(&ep->queue, struct isp1760_request, | ||
356 | queue); | ||
357 | req->req.actual += req->packet_size; | ||
358 | |||
359 | need_zlp = req->req.actual == req->req.length && | ||
360 | !(req->req.length % ep->maxpacket) && | ||
361 | req->packet_size && req->req.zero; | ||
362 | |||
363 | dev_dbg(udc->isp->dev, | ||
364 | "TX IRQ: req %p actual/length %u/%u maxpacket %u packet size %u zero %u need zlp %u\n", | ||
365 | req, req->req.actual, req->req.length, ep->maxpacket, | ||
366 | req->packet_size, req->req.zero, need_zlp); | ||
367 | |||
368 | /* | ||
369 | * Complete the request if all data has been sent and we don't need to | ||
370 | * transmit a zero length packet. | ||
371 | */ | ||
372 | if (req->req.actual == req->req.length && !need_zlp) { | ||
373 | complete = req; | ||
374 | list_del(&req->queue); | ||
375 | |||
376 | if (ep->addr == 0) | ||
377 | isp1760_udc_ctrl_send_status(ep, USB_DIR_IN); | ||
378 | |||
379 | if (!list_empty(&ep->queue)) | ||
380 | req = list_first_entry(&ep->queue, | ||
381 | struct isp1760_request, queue); | ||
382 | else | ||
383 | req = NULL; | ||
384 | } | ||
385 | |||
386 | /* | ||
387 | * Transmit the next packet or start the next request, if any. | ||
388 | * | ||
389 | * TODO: If the endpoint is stalled the next request shouldn't be | ||
390 | * started, but what about the next packet ? | ||
391 | */ | ||
392 | if (req) | ||
393 | isp1760_udc_transmit(ep, req); | ||
394 | |||
395 | spin_unlock(&udc->lock); | ||
396 | |||
397 | if (complete) | ||
398 | isp1760_udc_request_complete(ep, complete, 0); | ||
399 | } | ||
400 | |||
401 | static int __isp1760_udc_set_halt(struct isp1760_ep *ep, bool halt) | ||
402 | { | ||
403 | struct isp1760_udc *udc = ep->udc; | ||
404 | |||
405 | dev_dbg(udc->isp->dev, "%s: %s halt on ep%02x\n", __func__, | ||
406 | halt ? "set" : "clear", ep->addr); | ||
407 | |||
408 | if (ep->desc && usb_endpoint_xfer_isoc(ep->desc)) { | ||
409 | dev_dbg(udc->isp->dev, "%s: ep%02x is isochronous\n", __func__, | ||
410 | ep->addr); | ||
411 | return -EINVAL; | ||
412 | } | ||
413 | |||
414 | isp1760_udc_select_ep(ep); | ||
415 | isp1760_udc_write(udc, DC_CTRLFUNC, halt ? DC_STALL : 0); | ||
416 | |||
417 | if (ep->addr == 0) { | ||
418 | /* When halting the control endpoint, stall both IN and OUT. */ | ||
419 | __isp1760_udc_select_ep(ep, USB_DIR_IN); | ||
420 | isp1760_udc_write(udc, DC_CTRLFUNC, halt ? DC_STALL : 0); | ||
421 | } else if (!halt) { | ||
422 | /* Reset the data PID by cycling the endpoint enable bit. */ | ||
423 | u16 eptype = isp1760_udc_read(udc, DC_EPTYPE); | ||
424 | |||
425 | isp1760_udc_write(udc, DC_EPTYPE, eptype & ~DC_EPENABLE); | ||
426 | isp1760_udc_write(udc, DC_EPTYPE, eptype); | ||
427 | |||
428 | /* | ||
429 | * Disabling the endpoint emptied the transmit FIFO, fill it | ||
430 | * again if a request is pending. | ||
431 | * | ||
432 | * TODO: Does the gadget framework require synchronizatino with | ||
433 | * the TX IRQ handler ? | ||
434 | */ | ||
435 | if ((ep->addr & USB_DIR_IN) && !list_empty(&ep->queue)) { | ||
436 | struct isp1760_request *req; | ||
437 | |||
438 | req = list_first_entry(&ep->queue, | ||
439 | struct isp1760_request, queue); | ||
440 | isp1760_udc_transmit(ep, req); | ||
441 | } | ||
442 | } | ||
443 | |||
444 | ep->halted = halt; | ||
445 | |||
446 | return 0; | ||
447 | } | ||
448 | |||
449 | /* ----------------------------------------------------------------------------- | ||
450 | * Control Endpoint | ||
451 | */ | ||
452 | |||
453 | static int isp1760_udc_get_status(struct isp1760_udc *udc, | ||
454 | const struct usb_ctrlrequest *req) | ||
455 | { | ||
456 | struct isp1760_ep *ep; | ||
457 | u16 status; | ||
458 | |||
459 | if (req->wLength != cpu_to_le16(2) || req->wValue != cpu_to_le16(0)) | ||
460 | return -EINVAL; | ||
461 | |||
462 | switch (req->bRequestType) { | ||
463 | case USB_DIR_IN | USB_RECIP_DEVICE: | ||
464 | status = udc->devstatus; | ||
465 | break; | ||
466 | |||
467 | case USB_DIR_IN | USB_RECIP_INTERFACE: | ||
468 | status = 0; | ||
469 | break; | ||
470 | |||
471 | case USB_DIR_IN | USB_RECIP_ENDPOINT: | ||
472 | ep = isp1760_udc_find_ep(udc, le16_to_cpu(req->wIndex)); | ||
473 | if (!ep) | ||
474 | return -EINVAL; | ||
475 | |||
476 | status = 0; | ||
477 | if (ep->halted) | ||
478 | status |= 1 << USB_ENDPOINT_HALT; | ||
479 | break; | ||
480 | |||
481 | default: | ||
482 | return -EINVAL; | ||
483 | } | ||
484 | |||
485 | isp1760_udc_write(udc, DC_EPINDEX, DC_ENDPIDX(0) | DC_EPDIR); | ||
486 | isp1760_udc_write(udc, DC_BUFLEN, 2); | ||
487 | |||
488 | writew(cpu_to_le16(status), udc->regs + DC_DATAPORT); | ||
489 | |||
490 | isp1760_udc_write(udc, DC_CTRLFUNC, DC_DSEN); | ||
491 | |||
492 | dev_dbg(udc->isp->dev, "%s: status 0x%04x\n", __func__, status); | ||
493 | |||
494 | return 0; | ||
495 | } | ||
496 | |||
497 | static int isp1760_udc_set_address(struct isp1760_udc *udc, u16 addr) | ||
498 | { | ||
499 | if (addr > 127) { | ||
500 | dev_dbg(udc->isp->dev, "invalid device address %u\n", addr); | ||
501 | return -EINVAL; | ||
502 | } | ||
503 | |||
504 | if (udc->gadget.state != USB_STATE_DEFAULT && | ||
505 | udc->gadget.state != USB_STATE_ADDRESS) { | ||
506 | dev_dbg(udc->isp->dev, "can't set address in state %u\n", | ||
507 | udc->gadget.state); | ||
508 | return -EINVAL; | ||
509 | } | ||
510 | |||
511 | usb_gadget_set_state(&udc->gadget, addr ? USB_STATE_ADDRESS : | ||
512 | USB_STATE_DEFAULT); | ||
513 | |||
514 | isp1760_udc_write(udc, DC_ADDRESS, DC_DEVEN | addr); | ||
515 | |||
516 | spin_lock(&udc->lock); | ||
517 | isp1760_udc_ctrl_send_status(&udc->ep[0], USB_DIR_OUT); | ||
518 | spin_unlock(&udc->lock); | ||
519 | |||
520 | return 0; | ||
521 | } | ||
522 | |||
523 | static bool isp1760_ep0_setup_standard(struct isp1760_udc *udc, | ||
524 | struct usb_ctrlrequest *req) | ||
525 | { | ||
526 | bool stall; | ||
527 | |||
528 | switch (req->bRequest) { | ||
529 | case USB_REQ_GET_STATUS: | ||
530 | return isp1760_udc_get_status(udc, req); | ||
531 | |||
532 | case USB_REQ_CLEAR_FEATURE: | ||
533 | switch (req->bRequestType) { | ||
534 | case USB_DIR_OUT | USB_RECIP_DEVICE: { | ||
535 | /* TODO: Handle remote wakeup feature. */ | ||
536 | return true; | ||
537 | } | ||
538 | |||
539 | case USB_DIR_OUT | USB_RECIP_ENDPOINT: { | ||
540 | u16 index = le16_to_cpu(req->wIndex); | ||
541 | struct isp1760_ep *ep; | ||
542 | |||
543 | if (req->wLength != cpu_to_le16(0) || | ||
544 | req->wValue != cpu_to_le16(USB_ENDPOINT_HALT)) | ||
545 | return true; | ||
546 | |||
547 | ep = isp1760_udc_find_ep(udc, index); | ||
548 | if (!ep) | ||
549 | return true; | ||
550 | |||
551 | spin_lock(&udc->lock); | ||
552 | |||
553 | /* | ||
554 | * If the endpoint is wedged only the gadget can clear | ||
555 | * the halt feature. Pretend success in that case, but | ||
556 | * keep the endpoint halted. | ||
557 | */ | ||
558 | if (!ep->wedged) | ||
559 | stall = __isp1760_udc_set_halt(ep, false); | ||
560 | else | ||
561 | stall = false; | ||
562 | |||
563 | if (!stall) | ||
564 | isp1760_udc_ctrl_send_status(&udc->ep[0], | ||
565 | USB_DIR_OUT); | ||
566 | |||
567 | spin_unlock(&udc->lock); | ||
568 | return stall; | ||
569 | } | ||
570 | |||
571 | default: | ||
572 | return true; | ||
573 | } | ||
574 | break; | ||
575 | |||
576 | case USB_REQ_SET_FEATURE: | ||
577 | switch (req->bRequestType) { | ||
578 | case USB_DIR_OUT | USB_RECIP_DEVICE: { | ||
579 | /* TODO: Handle remote wakeup and test mode features */ | ||
580 | return true; | ||
581 | } | ||
582 | |||
583 | case USB_DIR_OUT | USB_RECIP_ENDPOINT: { | ||
584 | u16 index = le16_to_cpu(req->wIndex); | ||
585 | struct isp1760_ep *ep; | ||
586 | |||
587 | if (req->wLength != cpu_to_le16(0) || | ||
588 | req->wValue != cpu_to_le16(USB_ENDPOINT_HALT)) | ||
589 | return true; | ||
590 | |||
591 | ep = isp1760_udc_find_ep(udc, index); | ||
592 | if (!ep) | ||
593 | return true; | ||
594 | |||
595 | spin_lock(&udc->lock); | ||
596 | |||
597 | stall = __isp1760_udc_set_halt(ep, true); | ||
598 | if (!stall) | ||
599 | isp1760_udc_ctrl_send_status(&udc->ep[0], | ||
600 | USB_DIR_OUT); | ||
601 | |||
602 | spin_unlock(&udc->lock); | ||
603 | return stall; | ||
604 | } | ||
605 | |||
606 | default: | ||
607 | return true; | ||
608 | } | ||
609 | break; | ||
610 | |||
611 | case USB_REQ_SET_ADDRESS: | ||
612 | if (req->bRequestType != (USB_DIR_OUT | USB_RECIP_DEVICE)) | ||
613 | return true; | ||
614 | |||
615 | return isp1760_udc_set_address(udc, le16_to_cpu(req->wValue)); | ||
616 | |||
617 | case USB_REQ_SET_CONFIGURATION: | ||
618 | if (req->bRequestType != (USB_DIR_OUT | USB_RECIP_DEVICE)) | ||
619 | return true; | ||
620 | |||
621 | if (udc->gadget.state != USB_STATE_ADDRESS && | ||
622 | udc->gadget.state != USB_STATE_CONFIGURED) | ||
623 | return true; | ||
624 | |||
625 | stall = udc->driver->setup(&udc->gadget, req) < 0; | ||
626 | if (stall) | ||
627 | return true; | ||
628 | |||
629 | usb_gadget_set_state(&udc->gadget, req->wValue ? | ||
630 | USB_STATE_CONFIGURED : USB_STATE_ADDRESS); | ||
631 | |||
632 | /* | ||
633 | * SET_CONFIGURATION (and SET_INTERFACE) must reset the halt | ||
634 | * feature on all endpoints. There is however no need to do so | ||
635 | * explicitly here as the gadget driver will disable and | ||
636 | * reenable endpoints, clearing the halt feature. | ||
637 | */ | ||
638 | return false; | ||
639 | |||
640 | default: | ||
641 | return udc->driver->setup(&udc->gadget, req) < 0; | ||
642 | } | ||
643 | } | ||
644 | |||
645 | static void isp1760_ep0_setup(struct isp1760_udc *udc) | ||
646 | { | ||
647 | union { | ||
648 | struct usb_ctrlrequest r; | ||
649 | u32 data[2]; | ||
650 | } req; | ||
651 | unsigned int count; | ||
652 | bool stall = false; | ||
653 | |||
654 | spin_lock(&udc->lock); | ||
655 | |||
656 | isp1760_udc_write(udc, DC_EPINDEX, DC_EP0SETUP); | ||
657 | |||
658 | count = isp1760_udc_read(udc, DC_BUFLEN) & DC_DATACOUNT_MASK; | ||
659 | if (count != sizeof(req)) { | ||
660 | spin_unlock(&udc->lock); | ||
661 | |||
662 | dev_err(udc->isp->dev, "invalid length %u for setup packet\n", | ||
663 | count); | ||
664 | |||
665 | isp1760_udc_ctrl_send_stall(&udc->ep[0]); | ||
666 | return; | ||
667 | } | ||
668 | |||
669 | req.data[0] = isp1760_udc_read(udc, DC_DATAPORT); | ||
670 | req.data[1] = isp1760_udc_read(udc, DC_DATAPORT); | ||
671 | |||
672 | if (udc->ep0_state != ISP1760_CTRL_SETUP) { | ||
673 | spin_unlock(&udc->lock); | ||
674 | dev_dbg(udc->isp->dev, "unexpected SETUP packet\n"); | ||
675 | return; | ||
676 | } | ||
677 | |||
678 | /* Move to the data stage. */ | ||
679 | if (!req.r.wLength) | ||
680 | udc->ep0_state = ISP1760_CTRL_STATUS; | ||
681 | else if (req.r.bRequestType & USB_DIR_IN) | ||
682 | udc->ep0_state = ISP1760_CTRL_DATA_IN; | ||
683 | else | ||
684 | udc->ep0_state = ISP1760_CTRL_DATA_OUT; | ||
685 | |||
686 | udc->ep0_dir = req.r.bRequestType & USB_DIR_IN; | ||
687 | udc->ep0_length = le16_to_cpu(req.r.wLength); | ||
688 | |||
689 | spin_unlock(&udc->lock); | ||
690 | |||
691 | dev_dbg(udc->isp->dev, | ||
692 | "%s: bRequestType 0x%02x bRequest 0x%02x wValue 0x%04x wIndex 0x%04x wLength 0x%04x\n", | ||
693 | __func__, req.r.bRequestType, req.r.bRequest, | ||
694 | le16_to_cpu(req.r.wValue), le16_to_cpu(req.r.wIndex), | ||
695 | le16_to_cpu(req.r.wLength)); | ||
696 | |||
697 | if ((req.r.bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) | ||
698 | stall = isp1760_ep0_setup_standard(udc, &req.r); | ||
699 | else | ||
700 | stall = udc->driver->setup(&udc->gadget, &req.r) < 0; | ||
701 | |||
702 | if (stall) | ||
703 | isp1760_udc_ctrl_send_stall(&udc->ep[0]); | ||
704 | } | ||
705 | |||
706 | /* ----------------------------------------------------------------------------- | ||
707 | * Gadget Endpoint Operations | ||
708 | */ | ||
709 | |||
710 | static int isp1760_ep_enable(struct usb_ep *ep, | ||
711 | const struct usb_endpoint_descriptor *desc) | ||
712 | { | ||
713 | struct isp1760_ep *uep = ep_to_udc_ep(ep); | ||
714 | struct isp1760_udc *udc = uep->udc; | ||
715 | unsigned long flags; | ||
716 | unsigned int type; | ||
717 | |||
718 | dev_dbg(uep->udc->isp->dev, "%s\n", __func__); | ||
719 | |||
720 | /* | ||
721 | * Validate the descriptor. The control endpoint can't be enabled | ||
722 | * manually. | ||
723 | */ | ||
724 | if (desc->bDescriptorType != USB_DT_ENDPOINT || | ||
725 | desc->bEndpointAddress == 0 || | ||
726 | desc->bEndpointAddress != uep->addr || | ||
727 | le16_to_cpu(desc->wMaxPacketSize) > ep->maxpacket) { | ||
728 | dev_dbg(udc->isp->dev, | ||
729 | "%s: invalid descriptor type %u addr %02x ep addr %02x max packet size %u/%u\n", | ||
730 | __func__, desc->bDescriptorType, | ||
731 | desc->bEndpointAddress, uep->addr, | ||
732 | le16_to_cpu(desc->wMaxPacketSize), ep->maxpacket); | ||
733 | return -EINVAL; | ||
734 | } | ||
735 | |||
736 | switch (usb_endpoint_type(desc)) { | ||
737 | case USB_ENDPOINT_XFER_ISOC: | ||
738 | type = DC_ENDPTYP_ISOC; | ||
739 | break; | ||
740 | case USB_ENDPOINT_XFER_BULK: | ||
741 | type = DC_ENDPTYP_BULK; | ||
742 | break; | ||
743 | case USB_ENDPOINT_XFER_INT: | ||
744 | type = DC_ENDPTYP_INTERRUPT; | ||
745 | break; | ||
746 | case USB_ENDPOINT_XFER_CONTROL: | ||
747 | default: | ||
748 | dev_dbg(udc->isp->dev, "%s: control endpoints unsupported\n", | ||
749 | __func__); | ||
750 | return -EINVAL; | ||
751 | } | ||
752 | |||
753 | spin_lock_irqsave(&udc->lock, flags); | ||
754 | |||
755 | uep->desc = desc; | ||
756 | uep->maxpacket = le16_to_cpu(desc->wMaxPacketSize); | ||
757 | uep->rx_pending = false; | ||
758 | uep->halted = false; | ||
759 | uep->wedged = false; | ||
760 | |||
761 | isp1760_udc_select_ep(uep); | ||
762 | isp1760_udc_write(udc, DC_EPMAXPKTSZ, uep->maxpacket); | ||
763 | isp1760_udc_write(udc, DC_BUFLEN, uep->maxpacket); | ||
764 | isp1760_udc_write(udc, DC_EPTYPE, DC_EPENABLE | type); | ||
765 | |||
766 | spin_unlock_irqrestore(&udc->lock, flags); | ||
767 | |||
768 | return 0; | ||
769 | } | ||
770 | |||
771 | static int isp1760_ep_disable(struct usb_ep *ep) | ||
772 | { | ||
773 | struct isp1760_ep *uep = ep_to_udc_ep(ep); | ||
774 | struct isp1760_udc *udc = uep->udc; | ||
775 | struct isp1760_request *req, *nreq; | ||
776 | LIST_HEAD(req_list); | ||
777 | unsigned long flags; | ||
778 | |||
779 | dev_dbg(udc->isp->dev, "%s\n", __func__); | ||
780 | |||
781 | spin_lock_irqsave(&udc->lock, flags); | ||
782 | |||
783 | if (!uep->desc) { | ||
784 | dev_dbg(udc->isp->dev, "%s: endpoint not enabled\n", __func__); | ||
785 | spin_unlock_irqrestore(&udc->lock, flags); | ||
786 | return -EINVAL; | ||
787 | } | ||
788 | |||
789 | uep->desc = NULL; | ||
790 | uep->maxpacket = 0; | ||
791 | |||
792 | isp1760_udc_select_ep(uep); | ||
793 | isp1760_udc_write(udc, DC_EPTYPE, 0); | ||
794 | |||
795 | /* TODO Synchronize with the IRQ handler */ | ||
796 | |||
797 | list_splice_init(&uep->queue, &req_list); | ||
798 | |||
799 | spin_unlock_irqrestore(&udc->lock, flags); | ||
800 | |||
801 | list_for_each_entry_safe(req, nreq, &req_list, queue) { | ||
802 | list_del(&req->queue); | ||
803 | isp1760_udc_request_complete(uep, req, -ESHUTDOWN); | ||
804 | } | ||
805 | |||
806 | return 0; | ||
807 | } | ||
808 | |||
809 | static struct usb_request *isp1760_ep_alloc_request(struct usb_ep *ep, | ||
810 | gfp_t gfp_flags) | ||
811 | { | ||
812 | struct isp1760_request *req; | ||
813 | |||
814 | req = kzalloc(sizeof(*req), gfp_flags); | ||
815 | |||
816 | return &req->req; | ||
817 | } | ||
818 | |||
819 | static void isp1760_ep_free_request(struct usb_ep *ep, struct usb_request *_req) | ||
820 | { | ||
821 | struct isp1760_request *req = req_to_udc_req(_req); | ||
822 | |||
823 | kfree(req); | ||
824 | } | ||
825 | |||
826 | static int isp1760_ep_queue(struct usb_ep *ep, struct usb_request *_req, | ||
827 | gfp_t gfp_flags) | ||
828 | { | ||
829 | struct isp1760_request *req = req_to_udc_req(_req); | ||
830 | struct isp1760_ep *uep = ep_to_udc_ep(ep); | ||
831 | struct isp1760_udc *udc = uep->udc; | ||
832 | bool complete = false; | ||
833 | unsigned long flags; | ||
834 | int ret = 0; | ||
835 | |||
836 | _req->status = -EINPROGRESS; | ||
837 | _req->actual = 0; | ||
838 | |||
839 | spin_lock_irqsave(&udc->lock, flags); | ||
840 | |||
841 | dev_dbg(udc->isp->dev, | ||
842 | "%s: req %p (%u bytes%s) ep %p(0x%02x)\n", __func__, _req, | ||
843 | _req->length, _req->zero ? " (zlp)" : "", uep, uep->addr); | ||
844 | |||
845 | req->ep = uep; | ||
846 | |||
847 | if (uep->addr == 0) { | ||
848 | if (_req->length != udc->ep0_length && | ||
849 | udc->ep0_state != ISP1760_CTRL_DATA_IN) { | ||
850 | dev_dbg(udc->isp->dev, | ||
851 | "%s: invalid length %u for req %p\n", | ||
852 | __func__, _req->length, req); | ||
853 | ret = -EINVAL; | ||
854 | goto done; | ||
855 | } | ||
856 | |||
857 | switch (udc->ep0_state) { | ||
858 | case ISP1760_CTRL_DATA_IN: | ||
859 | dev_dbg(udc->isp->dev, "%s: transmitting req %p\n", | ||
860 | __func__, req); | ||
861 | |||
862 | list_add_tail(&req->queue, &uep->queue); | ||
863 | isp1760_udc_transmit(uep, req); | ||
864 | break; | ||
865 | |||
866 | case ISP1760_CTRL_DATA_OUT: | ||
867 | list_add_tail(&req->queue, &uep->queue); | ||
868 | __isp1760_udc_select_ep(uep, USB_DIR_OUT); | ||
869 | isp1760_udc_write(udc, DC_CTRLFUNC, DC_DSEN); | ||
870 | break; | ||
871 | |||
872 | case ISP1760_CTRL_STATUS: | ||
873 | complete = true; | ||
874 | break; | ||
875 | |||
876 | default: | ||
877 | dev_dbg(udc->isp->dev, "%s: invalid ep0 state\n", | ||
878 | __func__); | ||
879 | ret = -EINVAL; | ||
880 | break; | ||
881 | } | ||
882 | } else if (uep->desc) { | ||
883 | bool empty = list_empty(&uep->queue); | ||
884 | |||
885 | list_add_tail(&req->queue, &uep->queue); | ||
886 | if ((uep->addr & USB_DIR_IN) && !uep->halted && empty) | ||
887 | isp1760_udc_transmit(uep, req); | ||
888 | else if (!(uep->addr & USB_DIR_IN) && uep->rx_pending) | ||
889 | complete = isp1760_udc_receive(uep, req); | ||
890 | } else { | ||
891 | dev_dbg(udc->isp->dev, | ||
892 | "%s: can't queue request to disabled ep%02x\n", | ||
893 | __func__, uep->addr); | ||
894 | ret = -ESHUTDOWN; | ||
895 | } | ||
896 | |||
897 | done: | ||
898 | if (ret < 0) | ||
899 | req->ep = NULL; | ||
900 | |||
901 | spin_unlock_irqrestore(&udc->lock, flags); | ||
902 | |||
903 | if (complete) | ||
904 | isp1760_udc_request_complete(uep, req, 0); | ||
905 | |||
906 | return ret; | ||
907 | } | ||
908 | |||
909 | static int isp1760_ep_dequeue(struct usb_ep *ep, struct usb_request *_req) | ||
910 | { | ||
911 | struct isp1760_request *req = req_to_udc_req(_req); | ||
912 | struct isp1760_ep *uep = ep_to_udc_ep(ep); | ||
913 | struct isp1760_udc *udc = uep->udc; | ||
914 | unsigned long flags; | ||
915 | |||
916 | dev_dbg(uep->udc->isp->dev, "%s(ep%02x)\n", __func__, uep->addr); | ||
917 | |||
918 | spin_lock_irqsave(&udc->lock, flags); | ||
919 | |||
920 | if (req->ep != uep) | ||
921 | req = NULL; | ||
922 | else | ||
923 | list_del(&req->queue); | ||
924 | |||
925 | spin_unlock_irqrestore(&udc->lock, flags); | ||
926 | |||
927 | if (!req) | ||
928 | return -EINVAL; | ||
929 | |||
930 | isp1760_udc_request_complete(uep, req, -ECONNRESET); | ||
931 | return 0; | ||
932 | } | ||
933 | |||
934 | static int __isp1760_ep_set_halt(struct isp1760_ep *uep, bool stall, bool wedge) | ||
935 | { | ||
936 | struct isp1760_udc *udc = uep->udc; | ||
937 | int ret; | ||
938 | |||
939 | if (!uep->addr) { | ||
940 | /* | ||
941 | * Halting the control endpoint is only valid as a delayed error | ||
942 | * response to a SETUP packet. Make sure EP0 is in the right | ||
943 | * stage and that the gadget isn't trying to clear the halt | ||
944 | * condition. | ||
945 | */ | ||
946 | if (WARN_ON(udc->ep0_state == ISP1760_CTRL_SETUP || !stall || | ||
947 | wedge)) { | ||
948 | return -EINVAL; | ||
949 | } | ||
950 | } | ||
951 | |||
952 | if (uep->addr && !uep->desc) { | ||
953 | dev_dbg(udc->isp->dev, "%s: ep%02x is disabled\n", __func__, | ||
954 | uep->addr); | ||
955 | return -EINVAL; | ||
956 | } | ||
957 | |||
958 | if (uep->addr & USB_DIR_IN) { | ||
959 | /* Refuse to halt IN endpoints with active transfers. */ | ||
960 | if (!list_empty(&uep->queue)) { | ||
961 | dev_dbg(udc->isp->dev, | ||
962 | "%s: ep%02x has request pending\n", __func__, | ||
963 | uep->addr); | ||
964 | return -EAGAIN; | ||
965 | } | ||
966 | } | ||
967 | |||
968 | ret = __isp1760_udc_set_halt(uep, stall); | ||
969 | if (ret < 0) | ||
970 | return ret; | ||
971 | |||
972 | if (!uep->addr) { | ||
973 | /* | ||
974 | * Stalling EP0 completes the control transaction, move back to | ||
975 | * the SETUP state. | ||
976 | */ | ||
977 | udc->ep0_state = ISP1760_CTRL_SETUP; | ||
978 | return 0; | ||
979 | } | ||
980 | |||
981 | if (wedge) | ||
982 | uep->wedged = true; | ||
983 | else if (!stall) | ||
984 | uep->wedged = false; | ||
985 | |||
986 | return 0; | ||
987 | } | ||
988 | |||
989 | static int isp1760_ep_set_halt(struct usb_ep *ep, int value) | ||
990 | { | ||
991 | struct isp1760_ep *uep = ep_to_udc_ep(ep); | ||
992 | unsigned long flags; | ||
993 | int ret; | ||
994 | |||
995 | dev_dbg(uep->udc->isp->dev, "%s: %s halt on ep%02x\n", __func__, | ||
996 | value ? "set" : "clear", uep->addr); | ||
997 | |||
998 | spin_lock_irqsave(&uep->udc->lock, flags); | ||
999 | ret = __isp1760_ep_set_halt(uep, value, false); | ||
1000 | spin_unlock_irqrestore(&uep->udc->lock, flags); | ||
1001 | |||
1002 | return ret; | ||
1003 | } | ||
1004 | |||
1005 | static int isp1760_ep_set_wedge(struct usb_ep *ep) | ||
1006 | { | ||
1007 | struct isp1760_ep *uep = ep_to_udc_ep(ep); | ||
1008 | unsigned long flags; | ||
1009 | int ret; | ||
1010 | |||
1011 | dev_dbg(uep->udc->isp->dev, "%s: set wedge on ep%02x)\n", __func__, | ||
1012 | uep->addr); | ||
1013 | |||
1014 | spin_lock_irqsave(&uep->udc->lock, flags); | ||
1015 | ret = __isp1760_ep_set_halt(uep, true, true); | ||
1016 | spin_unlock_irqrestore(&uep->udc->lock, flags); | ||
1017 | |||
1018 | return ret; | ||
1019 | } | ||
1020 | |||
1021 | static void isp1760_ep_fifo_flush(struct usb_ep *ep) | ||
1022 | { | ||
1023 | struct isp1760_ep *uep = ep_to_udc_ep(ep); | ||
1024 | struct isp1760_udc *udc = uep->udc; | ||
1025 | unsigned long flags; | ||
1026 | |||
1027 | spin_lock_irqsave(&udc->lock, flags); | ||
1028 | |||
1029 | isp1760_udc_select_ep(uep); | ||
1030 | |||
1031 | /* | ||
1032 | * Set the CLBUF bit twice to flush both buffers in case double | ||
1033 | * buffering is enabled. | ||
1034 | */ | ||
1035 | isp1760_udc_write(udc, DC_CTRLFUNC, DC_CLBUF); | ||
1036 | isp1760_udc_write(udc, DC_CTRLFUNC, DC_CLBUF); | ||
1037 | |||
1038 | spin_unlock_irqrestore(&udc->lock, flags); | ||
1039 | } | ||
1040 | |||
1041 | static const struct usb_ep_ops isp1760_ep_ops = { | ||
1042 | .enable = isp1760_ep_enable, | ||
1043 | .disable = isp1760_ep_disable, | ||
1044 | .alloc_request = isp1760_ep_alloc_request, | ||
1045 | .free_request = isp1760_ep_free_request, | ||
1046 | .queue = isp1760_ep_queue, | ||
1047 | .dequeue = isp1760_ep_dequeue, | ||
1048 | .set_halt = isp1760_ep_set_halt, | ||
1049 | .set_wedge = isp1760_ep_set_wedge, | ||
1050 | .fifo_flush = isp1760_ep_fifo_flush, | ||
1051 | }; | ||
1052 | |||
1053 | /* ----------------------------------------------------------------------------- | ||
1054 | * Device States | ||
1055 | */ | ||
1056 | |||
1057 | /* Called with the UDC spinlock held. */ | ||
1058 | static void isp1760_udc_connect(struct isp1760_udc *udc) | ||
1059 | { | ||
1060 | usb_gadget_set_state(&udc->gadget, USB_STATE_POWERED); | ||
1061 | mod_timer(&udc->vbus_timer, jiffies + ISP1760_VBUS_POLL_INTERVAL); | ||
1062 | } | ||
1063 | |||
1064 | /* Called with the UDC spinlock held. */ | ||
1065 | static void isp1760_udc_disconnect(struct isp1760_udc *udc) | ||
1066 | { | ||
1067 | if (udc->gadget.state < USB_STATE_POWERED) | ||
1068 | return; | ||
1069 | |||
1070 | dev_dbg(udc->isp->dev, "Device disconnected in state %u\n", | ||
1071 | udc->gadget.state); | ||
1072 | |||
1073 | udc->gadget.speed = USB_SPEED_UNKNOWN; | ||
1074 | usb_gadget_set_state(&udc->gadget, USB_STATE_ATTACHED); | ||
1075 | |||
1076 | if (udc->driver->disconnect) | ||
1077 | udc->driver->disconnect(&udc->gadget); | ||
1078 | |||
1079 | del_timer(&udc->vbus_timer); | ||
1080 | |||
1081 | /* TODO Reset all endpoints ? */ | ||
1082 | } | ||
1083 | |||
1084 | static void isp1760_udc_init_hw(struct isp1760_udc *udc) | ||
1085 | { | ||
1086 | /* | ||
1087 | * The device controller currently shares its interrupt with the host | ||
1088 | * controller, the DC_IRQ polarity and signaling mode are ignored. Set | ||
1089 | * the to active-low level-triggered. | ||
1090 | * | ||
1091 | * Configure the control, in and out pipes to generate interrupts on | ||
1092 | * ACK tokens only (and NYET for the out pipe). The default | ||
1093 | * configuration also generates an interrupt on the first NACK token. | ||
1094 | */ | ||
1095 | isp1760_udc_write(udc, DC_INTCONF, DC_CDBGMOD_ACK | DC_DDBGMODIN_ACK | | ||
1096 | DC_DDBGMODOUT_ACK_NYET); | ||
1097 | |||
1098 | isp1760_udc_write(udc, DC_INTENABLE, DC_IEPRXTX(7) | DC_IEPRXTX(6) | | ||
1099 | DC_IEPRXTX(5) | DC_IEPRXTX(4) | DC_IEPRXTX(3) | | ||
1100 | DC_IEPRXTX(2) | DC_IEPRXTX(1) | DC_IEPRXTX(0) | | ||
1101 | DC_IEP0SETUP | DC_IEVBUS | DC_IERESM | DC_IESUSP | | ||
1102 | DC_IEHS_STA | DC_IEBRST); | ||
1103 | |||
1104 | if (udc->connected) | ||
1105 | isp1760_set_pullup(udc->isp, true); | ||
1106 | |||
1107 | isp1760_udc_write(udc, DC_ADDRESS, DC_DEVEN); | ||
1108 | } | ||
1109 | |||
1110 | static void isp1760_udc_reset(struct isp1760_udc *udc) | ||
1111 | { | ||
1112 | unsigned long flags; | ||
1113 | |||
1114 | spin_lock_irqsave(&udc->lock, flags); | ||
1115 | |||
1116 | /* | ||
1117 | * The bus reset has reset most registers to their default value, | ||
1118 | * reinitialize the UDC hardware. | ||
1119 | */ | ||
1120 | isp1760_udc_init_hw(udc); | ||
1121 | |||
1122 | udc->ep0_state = ISP1760_CTRL_SETUP; | ||
1123 | udc->gadget.speed = USB_SPEED_FULL; | ||
1124 | |||
1125 | usb_gadget_udc_reset(&udc->gadget, udc->driver); | ||
1126 | |||
1127 | spin_unlock_irqrestore(&udc->lock, flags); | ||
1128 | } | ||
1129 | |||
1130 | static void isp1760_udc_suspend(struct isp1760_udc *udc) | ||
1131 | { | ||
1132 | if (udc->gadget.state < USB_STATE_DEFAULT) | ||
1133 | return; | ||
1134 | |||
1135 | if (udc->driver->suspend) | ||
1136 | udc->driver->suspend(&udc->gadget); | ||
1137 | } | ||
1138 | |||
1139 | static void isp1760_udc_resume(struct isp1760_udc *udc) | ||
1140 | { | ||
1141 | if (udc->gadget.state < USB_STATE_DEFAULT) | ||
1142 | return; | ||
1143 | |||
1144 | if (udc->driver->resume) | ||
1145 | udc->driver->resume(&udc->gadget); | ||
1146 | } | ||
1147 | |||
1148 | /* ----------------------------------------------------------------------------- | ||
1149 | * Gadget Operations | ||
1150 | */ | ||
1151 | |||
1152 | static int isp1760_udc_get_frame(struct usb_gadget *gadget) | ||
1153 | { | ||
1154 | struct isp1760_udc *udc = gadget_to_udc(gadget); | ||
1155 | |||
1156 | return isp1760_udc_read(udc, DC_FRAMENUM) & ((1 << 11) - 1); | ||
1157 | } | ||
1158 | |||
1159 | static int isp1760_udc_wakeup(struct usb_gadget *gadget) | ||
1160 | { | ||
1161 | struct isp1760_udc *udc = gadget_to_udc(gadget); | ||
1162 | |||
1163 | dev_dbg(udc->isp->dev, "%s\n", __func__); | ||
1164 | return -ENOTSUPP; | ||
1165 | } | ||
1166 | |||
1167 | static int isp1760_udc_set_selfpowered(struct usb_gadget *gadget, | ||
1168 | int is_selfpowered) | ||
1169 | { | ||
1170 | struct isp1760_udc *udc = gadget_to_udc(gadget); | ||
1171 | |||
1172 | if (is_selfpowered) | ||
1173 | udc->devstatus |= 1 << USB_DEVICE_SELF_POWERED; | ||
1174 | else | ||
1175 | udc->devstatus &= ~(1 << USB_DEVICE_SELF_POWERED); | ||
1176 | |||
1177 | return 0; | ||
1178 | } | ||
1179 | |||
1180 | static int isp1760_udc_pullup(struct usb_gadget *gadget, int is_on) | ||
1181 | { | ||
1182 | struct isp1760_udc *udc = gadget_to_udc(gadget); | ||
1183 | |||
1184 | isp1760_set_pullup(udc->isp, is_on); | ||
1185 | udc->connected = is_on; | ||
1186 | |||
1187 | return 0; | ||
1188 | } | ||
1189 | |||
1190 | static int isp1760_udc_start(struct usb_gadget *gadget, | ||
1191 | struct usb_gadget_driver *driver) | ||
1192 | { | ||
1193 | struct isp1760_udc *udc = gadget_to_udc(gadget); | ||
1194 | |||
1195 | /* The hardware doesn't support low speed. */ | ||
1196 | if (driver->max_speed < USB_SPEED_FULL) { | ||
1197 | dev_err(udc->isp->dev, "Invalid gadget driver\n"); | ||
1198 | return -EINVAL; | ||
1199 | } | ||
1200 | |||
1201 | spin_lock(&udc->lock); | ||
1202 | |||
1203 | if (udc->driver) { | ||
1204 | dev_err(udc->isp->dev, "UDC already has a gadget driver\n"); | ||
1205 | spin_unlock(&udc->lock); | ||
1206 | return -EBUSY; | ||
1207 | } | ||
1208 | |||
1209 | udc->driver = driver; | ||
1210 | |||
1211 | spin_unlock(&udc->lock); | ||
1212 | |||
1213 | dev_dbg(udc->isp->dev, "starting UDC with driver %s\n", | ||
1214 | driver->function); | ||
1215 | |||
1216 | udc->devstatus = 0; | ||
1217 | udc->connected = true; | ||
1218 | |||
1219 | usb_gadget_set_state(&udc->gadget, USB_STATE_ATTACHED); | ||
1220 | |||
1221 | /* DMA isn't supported yet, don't enable the DMA clock. */ | ||
1222 | isp1760_udc_write(udc, DC_MODE, DC_GLINTENA); | ||
1223 | |||
1224 | isp1760_udc_init_hw(udc); | ||
1225 | |||
1226 | dev_dbg(udc->isp->dev, "UDC started with driver %s\n", | ||
1227 | driver->function); | ||
1228 | |||
1229 | return 0; | ||
1230 | } | ||
1231 | |||
1232 | static int isp1760_udc_stop(struct usb_gadget *gadget) | ||
1233 | { | ||
1234 | struct isp1760_udc *udc = gadget_to_udc(gadget); | ||
1235 | |||
1236 | dev_dbg(udc->isp->dev, "%s\n", __func__); | ||
1237 | |||
1238 | del_timer_sync(&udc->vbus_timer); | ||
1239 | |||
1240 | isp1760_udc_write(udc, DC_MODE, 0); | ||
1241 | |||
1242 | spin_lock(&udc->lock); | ||
1243 | udc->driver = NULL; | ||
1244 | spin_unlock(&udc->lock); | ||
1245 | |||
1246 | return 0; | ||
1247 | } | ||
1248 | |||
1249 | static struct usb_gadget_ops isp1760_udc_ops = { | ||
1250 | .get_frame = isp1760_udc_get_frame, | ||
1251 | .wakeup = isp1760_udc_wakeup, | ||
1252 | .set_selfpowered = isp1760_udc_set_selfpowered, | ||
1253 | .pullup = isp1760_udc_pullup, | ||
1254 | .udc_start = isp1760_udc_start, | ||
1255 | .udc_stop = isp1760_udc_stop, | ||
1256 | }; | ||
1257 | |||
1258 | /* ----------------------------------------------------------------------------- | ||
1259 | * Interrupt Handling | ||
1260 | */ | ||
1261 | |||
1262 | static irqreturn_t isp1760_udc_irq(int irq, void *dev) | ||
1263 | { | ||
1264 | struct isp1760_udc *udc = dev; | ||
1265 | unsigned int i; | ||
1266 | u32 status; | ||
1267 | |||
1268 | status = isp1760_udc_read(udc, DC_INTERRUPT) | ||
1269 | & isp1760_udc_read(udc, DC_INTENABLE); | ||
1270 | isp1760_udc_write(udc, DC_INTERRUPT, status); | ||
1271 | |||
1272 | if (status & DC_IEVBUS) { | ||
1273 | dev_dbg(udc->isp->dev, "%s(VBUS)\n", __func__); | ||
1274 | /* The VBUS interrupt is only triggered when VBUS appears. */ | ||
1275 | spin_lock(&udc->lock); | ||
1276 | isp1760_udc_connect(udc); | ||
1277 | spin_unlock(&udc->lock); | ||
1278 | } | ||
1279 | |||
1280 | if (status & DC_IEBRST) { | ||
1281 | dev_dbg(udc->isp->dev, "%s(BRST)\n", __func__); | ||
1282 | |||
1283 | isp1760_udc_reset(udc); | ||
1284 | } | ||
1285 | |||
1286 | for (i = 0; i <= 7; ++i) { | ||
1287 | struct isp1760_ep *ep = &udc->ep[i*2]; | ||
1288 | |||
1289 | if (status & DC_IEPTX(i)) { | ||
1290 | dev_dbg(udc->isp->dev, "%s(EPTX%u)\n", __func__, i); | ||
1291 | isp1760_ep_tx_complete(ep); | ||
1292 | } | ||
1293 | |||
1294 | if (status & DC_IEPRX(i)) { | ||
1295 | dev_dbg(udc->isp->dev, "%s(EPRX%u)\n", __func__, i); | ||
1296 | isp1760_ep_rx_ready(i ? ep - 1 : ep); | ||
1297 | } | ||
1298 | } | ||
1299 | |||
1300 | if (status & DC_IEP0SETUP) { | ||
1301 | dev_dbg(udc->isp->dev, "%s(EP0SETUP)\n", __func__); | ||
1302 | |||
1303 | isp1760_ep0_setup(udc); | ||
1304 | } | ||
1305 | |||
1306 | if (status & DC_IERESM) { | ||
1307 | dev_dbg(udc->isp->dev, "%s(RESM)\n", __func__); | ||
1308 | isp1760_udc_resume(udc); | ||
1309 | } | ||
1310 | |||
1311 | if (status & DC_IESUSP) { | ||
1312 | dev_dbg(udc->isp->dev, "%s(SUSP)\n", __func__); | ||
1313 | |||
1314 | spin_lock(&udc->lock); | ||
1315 | if (!(isp1760_udc_read(udc, DC_MODE) & DC_VBUSSTAT)) | ||
1316 | isp1760_udc_disconnect(udc); | ||
1317 | else | ||
1318 | isp1760_udc_suspend(udc); | ||
1319 | spin_unlock(&udc->lock); | ||
1320 | } | ||
1321 | |||
1322 | if (status & DC_IEHS_STA) { | ||
1323 | dev_dbg(udc->isp->dev, "%s(HS_STA)\n", __func__); | ||
1324 | udc->gadget.speed = USB_SPEED_HIGH; | ||
1325 | } | ||
1326 | |||
1327 | return status ? IRQ_HANDLED : IRQ_NONE; | ||
1328 | } | ||
1329 | |||
1330 | static void isp1760_udc_vbus_poll(unsigned long data) | ||
1331 | { | ||
1332 | struct isp1760_udc *udc = (struct isp1760_udc *)data; | ||
1333 | unsigned long flags; | ||
1334 | |||
1335 | spin_lock_irqsave(&udc->lock, flags); | ||
1336 | |||
1337 | if (!(isp1760_udc_read(udc, DC_MODE) & DC_VBUSSTAT)) | ||
1338 | isp1760_udc_disconnect(udc); | ||
1339 | else if (udc->gadget.state >= USB_STATE_POWERED) | ||
1340 | mod_timer(&udc->vbus_timer, | ||
1341 | jiffies + ISP1760_VBUS_POLL_INTERVAL); | ||
1342 | |||
1343 | spin_unlock_irqrestore(&udc->lock, flags); | ||
1344 | } | ||
1345 | |||
1346 | /* ----------------------------------------------------------------------------- | ||
1347 | * Registration | ||
1348 | */ | ||
1349 | |||
1350 | static void isp1760_udc_init_eps(struct isp1760_udc *udc) | ||
1351 | { | ||
1352 | unsigned int i; | ||
1353 | |||
1354 | INIT_LIST_HEAD(&udc->gadget.ep_list); | ||
1355 | |||
1356 | for (i = 0; i < ARRAY_SIZE(udc->ep); ++i) { | ||
1357 | struct isp1760_ep *ep = &udc->ep[i]; | ||
1358 | unsigned int ep_num = (i + 1) / 2; | ||
1359 | bool is_in = !(i & 1); | ||
1360 | |||
1361 | ep->udc = udc; | ||
1362 | |||
1363 | INIT_LIST_HEAD(&ep->queue); | ||
1364 | |||
1365 | ep->addr = (ep_num && is_in ? USB_DIR_IN : USB_DIR_OUT) | ||
1366 | | ep_num; | ||
1367 | ep->desc = NULL; | ||
1368 | |||
1369 | sprintf(ep->name, "ep%u%s", ep_num, | ||
1370 | ep_num ? (is_in ? "in" : "out") : ""); | ||
1371 | |||
1372 | ep->ep.ops = &isp1760_ep_ops; | ||
1373 | ep->ep.name = ep->name; | ||
1374 | |||
1375 | /* | ||
1376 | * Hardcode the maximum packet sizes for now, to 64 bytes for | ||
1377 | * the control endpoint and 512 bytes for all other endpoints. | ||
1378 | * This fits in the 8kB FIFO without double-buffering. | ||
1379 | */ | ||
1380 | if (ep_num == 0) { | ||
1381 | ep->ep.maxpacket = 64; | ||
1382 | ep->maxpacket = 64; | ||
1383 | udc->gadget.ep0 = &ep->ep; | ||
1384 | } else { | ||
1385 | ep->ep.maxpacket = 512; | ||
1386 | ep->maxpacket = 0; | ||
1387 | list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list); | ||
1388 | } | ||
1389 | } | ||
1390 | } | ||
1391 | |||
1392 | static int isp1760_udc_init(struct isp1760_udc *udc) | ||
1393 | { | ||
1394 | u16 scratch; | ||
1395 | u32 chipid; | ||
1396 | |||
1397 | /* | ||
1398 | * Check that the controller is present by writing to the scratch | ||
1399 | * register, modifying the bus pattern by reading from the chip ID | ||
1400 | * register, and reading the scratch register value back. The chip ID | ||
1401 | * and scratch register contents must match the expected values. | ||
1402 | */ | ||
1403 | isp1760_udc_write(udc, DC_SCRATCH, 0xbabe); | ||
1404 | chipid = isp1760_udc_read(udc, DC_CHIPID); | ||
1405 | scratch = isp1760_udc_read(udc, DC_SCRATCH); | ||
1406 | |||
1407 | if (scratch != 0xbabe) { | ||
1408 | dev_err(udc->isp->dev, | ||
1409 | "udc: scratch test failed (0x%04x/0x%08x)\n", | ||
1410 | scratch, chipid); | ||
1411 | return -ENODEV; | ||
1412 | } | ||
1413 | |||
1414 | if (chipid != 0x00011582) { | ||
1415 | dev_err(udc->isp->dev, "udc: invalid chip ID 0x%08x\n", chipid); | ||
1416 | return -ENODEV; | ||
1417 | } | ||
1418 | |||
1419 | /* Reset the device controller. */ | ||
1420 | isp1760_udc_write(udc, DC_MODE, DC_SFRESET); | ||
1421 | usleep_range(10000, 11000); | ||
1422 | isp1760_udc_write(udc, DC_MODE, 0); | ||
1423 | usleep_range(10000, 11000); | ||
1424 | |||
1425 | return 0; | ||
1426 | } | ||
1427 | |||
1428 | int isp1760_udc_register(struct isp1760_device *isp, int irq, | ||
1429 | unsigned long irqflags) | ||
1430 | { | ||
1431 | struct isp1760_udc *udc = &isp->udc; | ||
1432 | const char *devname; | ||
1433 | int ret; | ||
1434 | |||
1435 | udc->irq = -1; | ||
1436 | udc->isp = isp; | ||
1437 | udc->regs = isp->regs; | ||
1438 | |||
1439 | spin_lock_init(&udc->lock); | ||
1440 | setup_timer(&udc->vbus_timer, isp1760_udc_vbus_poll, | ||
1441 | (unsigned long)udc); | ||
1442 | |||
1443 | ret = isp1760_udc_init(udc); | ||
1444 | if (ret < 0) | ||
1445 | return ret; | ||
1446 | |||
1447 | devname = dev_name(isp->dev); | ||
1448 | udc->irqname = kmalloc(strlen(devname) + 7, GFP_KERNEL); | ||
1449 | if (!udc->irqname) | ||
1450 | return -ENOMEM; | ||
1451 | |||
1452 | sprintf(udc->irqname, "%s (udc)", devname); | ||
1453 | |||
1454 | ret = request_irq(irq, isp1760_udc_irq, IRQF_SHARED | IRQF_DISABLED | | ||
1455 | irqflags, udc->irqname, udc); | ||
1456 | if (ret < 0) | ||
1457 | goto error; | ||
1458 | |||
1459 | udc->irq = irq; | ||
1460 | |||
1461 | /* | ||
1462 | * Initialize the gadget static fields and register its device. Gadget | ||
1463 | * fields that vary during the life time of the gadget are initialized | ||
1464 | * by the UDC core. | ||
1465 | */ | ||
1466 | udc->gadget.ops = &isp1760_udc_ops; | ||
1467 | udc->gadget.speed = USB_SPEED_UNKNOWN; | ||
1468 | udc->gadget.max_speed = USB_SPEED_HIGH; | ||
1469 | udc->gadget.name = "isp1761_udc"; | ||
1470 | |||
1471 | isp1760_udc_init_eps(udc); | ||
1472 | |||
1473 | ret = usb_add_gadget_udc(isp->dev, &udc->gadget); | ||
1474 | if (ret < 0) | ||
1475 | goto error; | ||
1476 | |||
1477 | return 0; | ||
1478 | |||
1479 | error: | ||
1480 | if (udc->irq >= 0) | ||
1481 | free_irq(udc->irq, udc); | ||
1482 | kfree(udc->irqname); | ||
1483 | |||
1484 | return ret; | ||
1485 | } | ||
1486 | |||
1487 | void isp1760_udc_unregister(struct isp1760_device *isp) | ||
1488 | { | ||
1489 | struct isp1760_udc *udc = &isp->udc; | ||
1490 | |||
1491 | if (!udc->isp) | ||
1492 | return; | ||
1493 | |||
1494 | usb_del_gadget_udc(&udc->gadget); | ||
1495 | |||
1496 | free_irq(udc->irq, udc); | ||
1497 | kfree(udc->irqname); | ||
1498 | } | ||
diff --git a/drivers/usb/isp1760/isp1760-udc.h b/drivers/usb/isp1760/isp1760-udc.h new file mode 100644 index 000000000000..26899ed81145 --- /dev/null +++ b/drivers/usb/isp1760/isp1760-udc.h | |||
@@ -0,0 +1,106 @@ | |||
1 | /* | ||
2 | * Driver for the NXP ISP1761 device controller | ||
3 | * | ||
4 | * Copyright 2014 Ideas on Board Oy | ||
5 | * | ||
6 | * Contacts: | ||
7 | * Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License | ||
11 | * version 2 as published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #ifndef _ISP1760_UDC_H_ | ||
15 | #define _ISP1760_UDC_H_ | ||
16 | |||
17 | #include <linux/ioport.h> | ||
18 | #include <linux/list.h> | ||
19 | #include <linux/spinlock.h> | ||
20 | #include <linux/timer.h> | ||
21 | #include <linux/usb/gadget.h> | ||
22 | |||
23 | struct isp1760_device; | ||
24 | struct isp1760_udc; | ||
25 | |||
26 | enum isp1760_ctrl_state { | ||
27 | ISP1760_CTRL_SETUP, /* Waiting for a SETUP transaction */ | ||
28 | ISP1760_CTRL_DATA_IN, /* Setup received, data IN stage */ | ||
29 | ISP1760_CTRL_DATA_OUT, /* Setup received, data OUT stage */ | ||
30 | ISP1760_CTRL_STATUS, /* 0-length request in status stage */ | ||
31 | }; | ||
32 | |||
33 | struct isp1760_ep { | ||
34 | struct isp1760_udc *udc; | ||
35 | struct usb_ep ep; | ||
36 | |||
37 | struct list_head queue; | ||
38 | |||
39 | unsigned int addr; | ||
40 | unsigned int maxpacket; | ||
41 | char name[7]; | ||
42 | |||
43 | const struct usb_endpoint_descriptor *desc; | ||
44 | |||
45 | bool rx_pending; | ||
46 | bool halted; | ||
47 | bool wedged; | ||
48 | }; | ||
49 | |||
50 | /** | ||
51 | * struct isp1760_udc - UDC state information | ||
52 | * irq: IRQ number | ||
53 | * irqname: IRQ name (as passed to request_irq) | ||
54 | * regs: Base address of the UDC registers | ||
55 | * driver: Gadget driver | ||
56 | * gadget: Gadget device | ||
57 | * lock: Protects driver, vbus_timer, ep, ep0_*, DC_EPINDEX register | ||
58 | * ep: Array of endpoints | ||
59 | * ep0_state: Control request state for endpoint 0 | ||
60 | * ep0_dir: Direction of the current control request | ||
61 | * ep0_length: Length of the current control request | ||
62 | * connected: Tracks gadget driver bus connection state | ||
63 | */ | ||
64 | struct isp1760_udc { | ||
65 | #ifdef CONFIG_USB_ISP1761_UDC | ||
66 | struct isp1760_device *isp; | ||
67 | |||
68 | int irq; | ||
69 | char *irqname; | ||
70 | void __iomem *regs; | ||
71 | |||
72 | struct usb_gadget_driver *driver; | ||
73 | struct usb_gadget gadget; | ||
74 | |||
75 | spinlock_t lock; | ||
76 | struct timer_list vbus_timer; | ||
77 | |||
78 | struct isp1760_ep ep[15]; | ||
79 | |||
80 | enum isp1760_ctrl_state ep0_state; | ||
81 | u8 ep0_dir; | ||
82 | u16 ep0_length; | ||
83 | |||
84 | bool connected; | ||
85 | |||
86 | unsigned int devstatus; | ||
87 | #endif | ||
88 | }; | ||
89 | |||
90 | #ifdef CONFIG_USB_ISP1761_UDC | ||
91 | int isp1760_udc_register(struct isp1760_device *isp, int irq, | ||
92 | unsigned long irqflags); | ||
93 | void isp1760_udc_unregister(struct isp1760_device *isp); | ||
94 | #else | ||
95 | static inline int isp1760_udc_register(struct isp1760_device *isp, int irq, | ||
96 | unsigned long irqflags) | ||
97 | { | ||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | static inline void isp1760_udc_unregister(struct isp1760_device *isp) | ||
102 | { | ||
103 | } | ||
104 | #endif | ||
105 | |||
106 | #endif | ||
diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c index 40ef40affe83..588d62a73e1a 100644 --- a/drivers/usb/misc/uss720.c +++ b/drivers/usb/misc/uss720.c | |||
@@ -124,12 +124,8 @@ static void async_complete(struct urb *urb) | |||
124 | } else if (rq->dr->bRequest == 3) { | 124 | } else if (rq->dr->bRequest == 3) { |
125 | memcpy(priv->reg, rq->reg, sizeof(priv->reg)); | 125 | memcpy(priv->reg, rq->reg, sizeof(priv->reg)); |
126 | #if 0 | 126 | #if 0 |
127 | dev_dbg(&priv->usbdev->dev, | 127 | dev_dbg(&priv->usbdev->dev, "async_complete regs %7ph\n", |
128 | "async_complete regs %02x %02x %02x %02x %02x %02x %02x\n", | 128 | priv->reg); |
129 | (unsigned int)priv->reg[0], (unsigned int)priv->reg[1], | ||
130 | (unsigned int)priv->reg[2], (unsigned int)priv->reg[3], | ||
131 | (unsigned int)priv->reg[4], (unsigned int)priv->reg[5], | ||
132 | (unsigned int)priv->reg[6]); | ||
133 | #endif | 129 | #endif |
134 | /* if nAck interrupts are enabled and we have an interrupt, call the interrupt procedure */ | 130 | /* if nAck interrupts are enabled and we have an interrupt, call the interrupt procedure */ |
135 | if (rq->reg[2] & rq->reg[1] & 0x10 && pp) | 131 | if (rq->reg[2] & rq->reg[1] & 0x10 && pp) |
@@ -742,9 +738,7 @@ static int uss720_probe(struct usb_interface *intf, | |||
742 | set_1284_register(pp, 2, 0x0c, GFP_KERNEL); | 738 | set_1284_register(pp, 2, 0x0c, GFP_KERNEL); |
743 | /* debugging */ | 739 | /* debugging */ |
744 | get_1284_register(pp, 0, ®, GFP_KERNEL); | 740 | get_1284_register(pp, 0, ®, GFP_KERNEL); |
745 | dev_dbg(&intf->dev, "reg: %02x %02x %02x %02x %02x %02x %02x\n", | 741 | dev_dbg(&intf->dev, "reg: %7ph\n", priv->reg); |
746 | priv->reg[0], priv->reg[1], priv->reg[2], priv->reg[3], | ||
747 | priv->reg[4], priv->reg[5], priv->reg[6]); | ||
748 | 742 | ||
749 | endpoint = &interface->endpoint[2]; | 743 | endpoint = &interface->endpoint[2]; |
750 | dev_dbg(&intf->dev, "epaddr %d interval %d\n", | 744 | dev_dbg(&intf->dev, "epaddr %d interval %d\n", |
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index b005010240e5..14e1628483d9 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig | |||
@@ -63,11 +63,13 @@ comment "Platform Glue Layer" | |||
63 | config USB_MUSB_DAVINCI | 63 | config USB_MUSB_DAVINCI |
64 | tristate "DaVinci" | 64 | tristate "DaVinci" |
65 | depends on ARCH_DAVINCI_DMx | 65 | depends on ARCH_DAVINCI_DMx |
66 | depends on NOP_USB_XCEIV | ||
66 | depends on BROKEN | 67 | depends on BROKEN |
67 | 68 | ||
68 | config USB_MUSB_DA8XX | 69 | config USB_MUSB_DA8XX |
69 | tristate "DA8xx/OMAP-L1x" | 70 | tristate "DA8xx/OMAP-L1x" |
70 | depends on ARCH_DAVINCI_DA8XX | 71 | depends on ARCH_DAVINCI_DA8XX |
72 | depends on NOP_USB_XCEIV | ||
71 | depends on BROKEN | 73 | depends on BROKEN |
72 | 74 | ||
73 | config USB_MUSB_TUSB6010 | 75 | config USB_MUSB_TUSB6010 |
@@ -77,12 +79,13 @@ config USB_MUSB_TUSB6010 | |||
77 | 79 | ||
78 | config USB_MUSB_OMAP2PLUS | 80 | config USB_MUSB_OMAP2PLUS |
79 | tristate "OMAP2430 and onwards" | 81 | tristate "OMAP2430 and onwards" |
80 | depends on ARCH_OMAP2PLUS && USB | 82 | depends on ARCH_OMAP2PLUS && USB && OMAP_CONTROL_PHY |
81 | select GENERIC_PHY | 83 | select GENERIC_PHY |
82 | 84 | ||
83 | config USB_MUSB_AM35X | 85 | config USB_MUSB_AM35X |
84 | tristate "AM35x" | 86 | tristate "AM35x" |
85 | depends on ARCH_OMAP | 87 | depends on ARCH_OMAP |
88 | depends on NOP_USB_XCEIV | ||
86 | 89 | ||
87 | config USB_MUSB_DSPS | 90 | config USB_MUSB_DSPS |
88 | tristate "TI DSPS platforms" | 91 | tristate "TI DSPS platforms" |
@@ -93,6 +96,7 @@ config USB_MUSB_DSPS | |||
93 | config USB_MUSB_BLACKFIN | 96 | config USB_MUSB_BLACKFIN |
94 | tristate "Blackfin" | 97 | tristate "Blackfin" |
95 | depends on (BF54x && !BF544) || (BF52x && ! BF522 && !BF523) | 98 | depends on (BF54x && !BF544) || (BF52x && ! BF522 && !BF523) |
99 | depends on NOP_USB_XCEIV | ||
96 | 100 | ||
97 | config USB_MUSB_UX500 | 101 | config USB_MUSB_UX500 |
98 | tristate "Ux500 platforms" | 102 | tristate "Ux500 platforms" |
@@ -100,6 +104,7 @@ config USB_MUSB_UX500 | |||
100 | 104 | ||
101 | config USB_MUSB_JZ4740 | 105 | config USB_MUSB_JZ4740 |
102 | tristate "JZ4740" | 106 | tristate "JZ4740" |
107 | depends on NOP_USB_XCEIV | ||
103 | depends on MACH_JZ4740 || COMPILE_TEST | 108 | depends on MACH_JZ4740 || COMPILE_TEST |
104 | depends on USB_MUSB_GADGET | 109 | depends on USB_MUSB_GADGET |
105 | depends on USB_OTG_BLACKLIST_HUB | 110 | depends on USB_OTG_BLACKLIST_HUB |
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index 178250145613..6123b748d262 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c | |||
@@ -608,7 +608,7 @@ static SIMPLE_DEV_PM_OPS(bfin_pm_ops, bfin_suspend, bfin_resume); | |||
608 | 608 | ||
609 | static struct platform_driver bfin_driver = { | 609 | static struct platform_driver bfin_driver = { |
610 | .probe = bfin_probe, | 610 | .probe = bfin_probe, |
611 | .remove = __exit_p(bfin_remove), | 611 | .remove = bfin_remove, |
612 | .driver = { | 612 | .driver = { |
613 | .name = "musb-blackfin", | 613 | .name = "musb-blackfin", |
614 | .pm = &bfin_pm_ops, | 614 | .pm = &bfin_pm_ops, |
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 34cce3e38c49..e6f4cbfeed97 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -567,6 +567,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | |||
567 | 567 | ||
568 | musb->xceiv->otg->state = OTG_STATE_A_HOST; | 568 | musb->xceiv->otg->state = OTG_STATE_A_HOST; |
569 | musb->is_active = 1; | 569 | musb->is_active = 1; |
570 | musb_host_resume_root_hub(musb); | ||
570 | break; | 571 | break; |
571 | case OTG_STATE_B_WAIT_ACON: | 572 | case OTG_STATE_B_WAIT_ACON: |
572 | musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL; | 573 | musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL; |
@@ -2500,6 +2501,12 @@ static int musb_runtime_resume(struct device *dev) | |||
2500 | musb_restore_context(musb); | 2501 | musb_restore_context(musb); |
2501 | first = 0; | 2502 | first = 0; |
2502 | 2503 | ||
2504 | if (musb->need_finish_resume) { | ||
2505 | musb->need_finish_resume = 0; | ||
2506 | schedule_delayed_work(&musb->finish_resume_work, | ||
2507 | msecs_to_jiffies(20)); | ||
2508 | } | ||
2509 | |||
2503 | return 0; | 2510 | return 0; |
2504 | } | 2511 | } |
2505 | 2512 | ||
diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c index c39a16ad7832..be84562d021b 100644 --- a/drivers/usb/musb/musb_cppi41.c +++ b/drivers/usb/musb/musb_cppi41.c | |||
@@ -9,9 +9,9 @@ | |||
9 | 9 | ||
10 | #define RNDIS_REG(x) (0x80 + ((x - 1) * 4)) | 10 | #define RNDIS_REG(x) (0x80 + ((x - 1) * 4)) |
11 | 11 | ||
12 | #define EP_MODE_AUTOREG_NONE 0 | 12 | #define EP_MODE_AUTOREQ_NONE 0 |
13 | #define EP_MODE_AUTOREG_ALL_NEOP 1 | 13 | #define EP_MODE_AUTOREQ_ALL_NEOP 1 |
14 | #define EP_MODE_AUTOREG_ALWAYS 3 | 14 | #define EP_MODE_AUTOREQ_ALWAYS 3 |
15 | 15 | ||
16 | #define EP_MODE_DMA_TRANSPARENT 0 | 16 | #define EP_MODE_DMA_TRANSPARENT 0 |
17 | #define EP_MODE_DMA_RNDIS 1 | 17 | #define EP_MODE_DMA_RNDIS 1 |
@@ -404,19 +404,19 @@ static bool cppi41_configure_channel(struct dma_channel *channel, | |||
404 | 404 | ||
405 | /* auto req */ | 405 | /* auto req */ |
406 | cppi41_set_autoreq_mode(cppi41_channel, | 406 | cppi41_set_autoreq_mode(cppi41_channel, |
407 | EP_MODE_AUTOREG_ALL_NEOP); | 407 | EP_MODE_AUTOREQ_ALL_NEOP); |
408 | } else { | 408 | } else { |
409 | musb_writel(musb->ctrl_base, | 409 | musb_writel(musb->ctrl_base, |
410 | RNDIS_REG(cppi41_channel->port_num), 0); | 410 | RNDIS_REG(cppi41_channel->port_num), 0); |
411 | cppi41_set_dma_mode(cppi41_channel, | 411 | cppi41_set_dma_mode(cppi41_channel, |
412 | EP_MODE_DMA_TRANSPARENT); | 412 | EP_MODE_DMA_TRANSPARENT); |
413 | cppi41_set_autoreq_mode(cppi41_channel, | 413 | cppi41_set_autoreq_mode(cppi41_channel, |
414 | EP_MODE_AUTOREG_NONE); | 414 | EP_MODE_AUTOREQ_NONE); |
415 | } | 415 | } |
416 | } else { | 416 | } else { |
417 | /* fallback mode */ | 417 | /* fallback mode */ |
418 | cppi41_set_dma_mode(cppi41_channel, EP_MODE_DMA_TRANSPARENT); | 418 | cppi41_set_dma_mode(cppi41_channel, EP_MODE_DMA_TRANSPARENT); |
419 | cppi41_set_autoreq_mode(cppi41_channel, EP_MODE_AUTOREG_NONE); | 419 | cppi41_set_autoreq_mode(cppi41_channel, EP_MODE_AUTOREQ_NONE); |
420 | len = min_t(u32, packet_sz, len); | 420 | len = min_t(u32, packet_sz, len); |
421 | } | 421 | } |
422 | cppi41_channel->prog_len = len; | 422 | cppi41_channel->prog_len = len; |
@@ -549,10 +549,15 @@ static int cppi41_dma_channel_abort(struct dma_channel *channel) | |||
549 | csr &= ~MUSB_TXCSR_DMAENAB; | 549 | csr &= ~MUSB_TXCSR_DMAENAB; |
550 | musb_writew(epio, MUSB_TXCSR, csr); | 550 | musb_writew(epio, MUSB_TXCSR, csr); |
551 | } else { | 551 | } else { |
552 | cppi41_set_autoreq_mode(cppi41_channel, EP_MODE_AUTOREQ_NONE); | ||
553 | |||
552 | csr = musb_readw(epio, MUSB_RXCSR); | 554 | csr = musb_readw(epio, MUSB_RXCSR); |
553 | csr &= ~(MUSB_RXCSR_H_REQPKT | MUSB_RXCSR_DMAENAB); | 555 | csr &= ~(MUSB_RXCSR_H_REQPKT | MUSB_RXCSR_DMAENAB); |
554 | musb_writew(epio, MUSB_RXCSR, csr); | 556 | musb_writew(epio, MUSB_RXCSR, csr); |
555 | 557 | ||
558 | /* wait to drain cppi dma pipe line */ | ||
559 | udelay(50); | ||
560 | |||
556 | csr = musb_readw(epio, MUSB_RXCSR); | 561 | csr = musb_readw(epio, MUSB_RXCSR); |
557 | if (csr & MUSB_RXCSR_RXPKTRDY) { | 562 | if (csr & MUSB_RXCSR_RXPKTRDY) { |
558 | csr |= MUSB_RXCSR_FLUSHFIFO; | 563 | csr |= MUSB_RXCSR_FLUSHFIFO; |
@@ -566,13 +571,14 @@ static int cppi41_dma_channel_abort(struct dma_channel *channel) | |||
566 | tdbit <<= 16; | 571 | tdbit <<= 16; |
567 | 572 | ||
568 | do { | 573 | do { |
569 | musb_writel(musb->ctrl_base, USB_TDOWN, tdbit); | 574 | if (is_tx) |
575 | musb_writel(musb->ctrl_base, USB_TDOWN, tdbit); | ||
570 | ret = dmaengine_terminate_all(cppi41_channel->dc); | 576 | ret = dmaengine_terminate_all(cppi41_channel->dc); |
571 | } while (ret == -EAGAIN); | 577 | } while (ret == -EAGAIN); |
572 | 578 | ||
573 | musb_writel(musb->ctrl_base, USB_TDOWN, tdbit); | ||
574 | |||
575 | if (is_tx) { | 579 | if (is_tx) { |
580 | musb_writel(musb->ctrl_base, USB_TDOWN, tdbit); | ||
581 | |||
576 | csr = musb_readw(epio, MUSB_TXCSR); | 582 | csr = musb_readw(epio, MUSB_TXCSR); |
577 | if (csr & MUSB_TXCSR_TXPKTRDY) { | 583 | if (csr & MUSB_TXCSR_TXPKTRDY) { |
578 | csr |= MUSB_TXCSR_FLUSHFIFO; | 584 | csr |= MUSB_TXCSR_FLUSHFIFO; |
diff --git a/drivers/usb/musb/musb_debugfs.c b/drivers/usb/musb/musb_debugfs.c index 48131aa8472c..78a283e9ce40 100644 --- a/drivers/usb/musb/musb_debugfs.c +++ b/drivers/usb/musb/musb_debugfs.c | |||
@@ -196,7 +196,7 @@ static ssize_t musb_test_mode_write(struct file *file, | |||
196 | 196 | ||
197 | memset(buf, 0x00, sizeof(buf)); | 197 | memset(buf, 0x00, sizeof(buf)); |
198 | 198 | ||
199 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) | 199 | if (copy_from_user(buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) |
200 | return -EFAULT; | 200 | return -EFAULT; |
201 | 201 | ||
202 | if (strstarts(buf, "force host")) | 202 | if (strstarts(buf, "force host")) |
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 49b04cb6f5ca..b2d9040c7685 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
@@ -1612,9 +1612,7 @@ done: | |||
1612 | static int | 1612 | static int |
1613 | musb_gadget_set_self_powered(struct usb_gadget *gadget, int is_selfpowered) | 1613 | musb_gadget_set_self_powered(struct usb_gadget *gadget, int is_selfpowered) |
1614 | { | 1614 | { |
1615 | struct musb *musb = gadget_to_musb(gadget); | 1615 | gadget->is_selfpowered = !!is_selfpowered; |
1616 | |||
1617 | musb->is_self_powered = !!is_selfpowered; | ||
1618 | return 0; | 1616 | return 0; |
1619 | } | 1617 | } |
1620 | 1618 | ||
diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c index 2af45a0c8930..10d30afe4a3c 100644 --- a/drivers/usb/musb/musb_gadget_ep0.c +++ b/drivers/usb/musb/musb_gadget_ep0.c | |||
@@ -85,7 +85,7 @@ static int service_tx_status_request( | |||
85 | 85 | ||
86 | switch (recip) { | 86 | switch (recip) { |
87 | case USB_RECIP_DEVICE: | 87 | case USB_RECIP_DEVICE: |
88 | result[0] = musb->is_self_powered << USB_DEVICE_SELF_POWERED; | 88 | result[0] = musb->g.is_selfpowered << USB_DEVICE_SELF_POWERED; |
89 | result[0] |= musb->may_wakeup << USB_DEVICE_REMOTE_WAKEUP; | 89 | result[0] |= musb->may_wakeup << USB_DEVICE_REMOTE_WAKEUP; |
90 | if (musb->g.is_otg) { | 90 | if (musb->g.is_otg) { |
91 | result[0] |= musb->g.b_hnp_enable | 91 | result[0] |= musb->g.b_hnp_enable |
diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c index b072420e44f5..294e159f4afe 100644 --- a/drivers/usb/musb/musb_virthub.c +++ b/drivers/usb/musb/musb_virthub.c | |||
@@ -72,7 +72,6 @@ void musb_host_finish_resume(struct work_struct *work) | |||
72 | musb->xceiv->otg->state = OTG_STATE_A_HOST; | 72 | musb->xceiv->otg->state = OTG_STATE_A_HOST; |
73 | 73 | ||
74 | spin_unlock_irqrestore(&musb->lock, flags); | 74 | spin_unlock_irqrestore(&musb->lock, flags); |
75 | musb_host_resume_root_hub(musb); | ||
76 | } | 75 | } |
77 | 76 | ||
78 | void musb_port_suspend(struct musb *musb, bool do_suspend) | 77 | void musb_port_suspend(struct musb *musb, bool do_suspend) |
@@ -349,9 +348,9 @@ int musb_hub_control( | |||
349 | desc->bDescriptorType = 0x29; | 348 | desc->bDescriptorType = 0x29; |
350 | desc->bNbrPorts = 1; | 349 | desc->bNbrPorts = 1; |
351 | desc->wHubCharacteristics = cpu_to_le16( | 350 | desc->wHubCharacteristics = cpu_to_le16( |
352 | 0x0001 /* per-port power switching */ | 351 | HUB_CHAR_INDV_PORT_LPSM /* per-port power switching */ |
353 | | 0x0010 /* no overcurrent reporting */ | 352 | | HUB_CHAR_NO_OCPM /* no overcurrent reporting */ |
354 | ); | 353 | ); |
355 | desc->bPwrOn2PwrGood = 5; /* msec/2 */ | 354 | desc->bPwrOn2PwrGood = 5; /* msec/2 */ |
356 | desc->bHubContrCurrent = 0; | 355 | desc->bHubContrCurrent = 0; |
357 | 356 | ||
diff --git a/drivers/usb/phy/phy-fsl-usb.c b/drivers/usb/phy/phy-fsl-usb.c index ab38aa32a6c1..94eb2923afed 100644 --- a/drivers/usb/phy/phy-fsl-usb.c +++ b/drivers/usb/phy/phy-fsl-usb.c | |||
@@ -107,19 +107,6 @@ static void (*_fsl_writel)(u32 v, unsigned __iomem *p); | |||
107 | #define fsl_writel(val, addr) writel(val, addr) | 107 | #define fsl_writel(val, addr) writel(val, addr) |
108 | #endif /* CONFIG_PPC32 */ | 108 | #endif /* CONFIG_PPC32 */ |
109 | 109 | ||
110 | /* Routines to access transceiver ULPI registers */ | ||
111 | u8 view_ulpi(u8 addr) | ||
112 | { | ||
113 | u32 temp; | ||
114 | |||
115 | temp = 0x40000000 | (addr << 16); | ||
116 | fsl_writel(temp, &usb_dr_regs->ulpiview); | ||
117 | udelay(1000); | ||
118 | while (temp & 0x40) | ||
119 | temp = fsl_readl(&usb_dr_regs->ulpiview); | ||
120 | return (le32_to_cpu(temp) & 0x0000ff00) >> 8; | ||
121 | } | ||
122 | |||
123 | int write_ulpi(u8 addr, u8 data) | 110 | int write_ulpi(u8 addr, u8 data) |
124 | { | 111 | { |
125 | u32 temp; | 112 | u32 temp; |
@@ -460,28 +447,6 @@ static void fsl_otg_fsm_del_timer(struct otg_fsm *fsm, enum otg_fsm_timer t) | |||
460 | fsl_otg_del_timer(fsm, timer); | 447 | fsl_otg_del_timer(fsm, timer); |
461 | } | 448 | } |
462 | 449 | ||
463 | /* | ||
464 | * Reduce timer count by 1, and find timeout conditions. | ||
465 | * Called by fsl_otg 1ms timer interrupt | ||
466 | */ | ||
467 | int fsl_otg_tick_timer(void) | ||
468 | { | ||
469 | struct fsl_otg_timer *tmp_timer, *del_tmp; | ||
470 | int expired = 0; | ||
471 | |||
472 | list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list) { | ||
473 | tmp_timer->count--; | ||
474 | /* check if timer expires */ | ||
475 | if (!tmp_timer->count) { | ||
476 | list_del(&tmp_timer->list); | ||
477 | tmp_timer->function(tmp_timer->data); | ||
478 | expired = 1; | ||
479 | } | ||
480 | } | ||
481 | |||
482 | return expired; | ||
483 | } | ||
484 | |||
485 | /* Reset controller, not reset the bus */ | 450 | /* Reset controller, not reset the bus */ |
486 | void otg_reset_controller(void) | 451 | void otg_reset_controller(void) |
487 | { | 452 | { |
diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c index f1b719b45a53..70be50b734b2 100644 --- a/drivers/usb/phy/phy-generic.c +++ b/drivers/usb/phy/phy-generic.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
29 | #include <linux/dma-mapping.h> | 29 | #include <linux/dma-mapping.h> |
30 | #include <linux/usb/gadget.h> | ||
30 | #include <linux/usb/otg.h> | 31 | #include <linux/usb/otg.h> |
31 | #include <linux/usb/usb_phy_generic.h> | 32 | #include <linux/usb/usb_phy_generic.h> |
32 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
@@ -39,6 +40,10 @@ | |||
39 | 40 | ||
40 | #include "phy-generic.h" | 41 | #include "phy-generic.h" |
41 | 42 | ||
43 | #define VBUS_IRQ_FLAGS \ | ||
44 | (IRQF_SHARED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | \ | ||
45 | IRQF_ONESHOT) | ||
46 | |||
42 | struct platform_device *usb_phy_generic_register(void) | 47 | struct platform_device *usb_phy_generic_register(void) |
43 | { | 48 | { |
44 | return platform_device_register_simple("usb_phy_generic", | 49 | return platform_device_register_simple("usb_phy_generic", |
@@ -59,19 +64,79 @@ static int nop_set_suspend(struct usb_phy *x, int suspend) | |||
59 | 64 | ||
60 | static void nop_reset_set(struct usb_phy_generic *nop, int asserted) | 65 | static void nop_reset_set(struct usb_phy_generic *nop, int asserted) |
61 | { | 66 | { |
62 | int value; | 67 | if (!nop->gpiod_reset) |
68 | return; | ||
69 | |||
70 | gpiod_direction_output(nop->gpiod_reset, !asserted); | ||
71 | usleep_range(10000, 20000); | ||
72 | gpiod_set_value(nop->gpiod_reset, asserted); | ||
73 | } | ||
74 | |||
75 | /* interface to regulator framework */ | ||
76 | static void nop_set_vbus_draw(struct usb_phy_generic *nop, unsigned mA) | ||
77 | { | ||
78 | struct regulator *vbus_draw = nop->vbus_draw; | ||
79 | int enabled; | ||
80 | int ret; | ||
63 | 81 | ||
64 | if (!gpio_is_valid(nop->gpio_reset)) | 82 | if (!vbus_draw) |
65 | return; | 83 | return; |
66 | 84 | ||
67 | value = asserted; | 85 | enabled = nop->vbus_draw_enabled; |
68 | if (nop->reset_active_low) | 86 | if (mA) { |
69 | value = !value; | 87 | regulator_set_current_limit(vbus_draw, 0, 1000 * mA); |
88 | if (!enabled) { | ||
89 | ret = regulator_enable(vbus_draw); | ||
90 | if (ret < 0) | ||
91 | return; | ||
92 | nop->vbus_draw_enabled = 1; | ||
93 | } | ||
94 | } else { | ||
95 | if (enabled) { | ||
96 | ret = regulator_disable(vbus_draw); | ||
97 | if (ret < 0) | ||
98 | return; | ||
99 | nop->vbus_draw_enabled = 0; | ||
100 | } | ||
101 | } | ||
102 | nop->mA = mA; | ||
103 | } | ||
104 | |||
105 | |||
106 | static irqreturn_t nop_gpio_vbus_thread(int irq, void *data) | ||
107 | { | ||
108 | struct usb_phy_generic *nop = data; | ||
109 | struct usb_otg *otg = nop->phy.otg; | ||
110 | int vbus, status; | ||
111 | |||
112 | vbus = gpiod_get_value(nop->gpiod_vbus); | ||
113 | if ((vbus ^ nop->vbus) == 0) | ||
114 | return IRQ_HANDLED; | ||
115 | nop->vbus = vbus; | ||
116 | |||
117 | if (vbus) { | ||
118 | status = USB_EVENT_VBUS; | ||
119 | otg->state = OTG_STATE_B_PERIPHERAL; | ||
120 | nop->phy.last_event = status; | ||
121 | usb_gadget_vbus_connect(otg->gadget); | ||
122 | |||
123 | /* drawing a "unit load" is *always* OK, except for OTG */ | ||
124 | nop_set_vbus_draw(nop, 100); | ||
125 | |||
126 | atomic_notifier_call_chain(&nop->phy.notifier, status, | ||
127 | otg->gadget); | ||
128 | } else { | ||
129 | nop_set_vbus_draw(nop, 0); | ||
70 | 130 | ||
71 | gpio_set_value_cansleep(nop->gpio_reset, value); | 131 | usb_gadget_vbus_disconnect(otg->gadget); |
132 | status = USB_EVENT_NONE; | ||
133 | otg->state = OTG_STATE_B_IDLE; | ||
134 | nop->phy.last_event = status; | ||
72 | 135 | ||
73 | if (!asserted) | 136 | atomic_notifier_call_chain(&nop->phy.notifier, status, |
74 | usleep_range(10000, 20000); | 137 | otg->gadget); |
138 | } | ||
139 | return IRQ_HANDLED; | ||
75 | } | 140 | } |
76 | 141 | ||
77 | int usb_gen_phy_init(struct usb_phy *phy) | 142 | int usb_gen_phy_init(struct usb_phy *phy) |
@@ -143,36 +208,47 @@ int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop, | |||
143 | struct usb_phy_generic_platform_data *pdata) | 208 | struct usb_phy_generic_platform_data *pdata) |
144 | { | 209 | { |
145 | enum usb_phy_type type = USB_PHY_TYPE_USB2; | 210 | enum usb_phy_type type = USB_PHY_TYPE_USB2; |
146 | int err; | 211 | int err = 0; |
147 | 212 | ||
148 | u32 clk_rate = 0; | 213 | u32 clk_rate = 0; |
149 | bool needs_vcc = false; | 214 | bool needs_vcc = false; |
150 | 215 | ||
151 | nop->reset_active_low = true; /* default behaviour */ | ||
152 | |||
153 | if (dev->of_node) { | 216 | if (dev->of_node) { |
154 | struct device_node *node = dev->of_node; | 217 | struct device_node *node = dev->of_node; |
155 | enum of_gpio_flags flags = 0; | ||
156 | 218 | ||
157 | if (of_property_read_u32(node, "clock-frequency", &clk_rate)) | 219 | if (of_property_read_u32(node, "clock-frequency", &clk_rate)) |
158 | clk_rate = 0; | 220 | clk_rate = 0; |
159 | 221 | ||
160 | needs_vcc = of_property_read_bool(node, "vcc-supply"); | 222 | needs_vcc = of_property_read_bool(node, "vcc-supply"); |
161 | nop->gpio_reset = of_get_named_gpio_flags(node, "reset-gpios", | 223 | nop->gpiod_reset = devm_gpiod_get_optional(dev, "reset"); |
162 | 0, &flags); | 224 | err = PTR_ERR_OR_ZERO(nop->gpiod_reset); |
163 | if (nop->gpio_reset == -EPROBE_DEFER) | 225 | if (!err) { |
164 | return -EPROBE_DEFER; | 226 | nop->gpiod_vbus = devm_gpiod_get_optional(dev, |
165 | 227 | "vbus-detect"); | |
166 | nop->reset_active_low = flags & OF_GPIO_ACTIVE_LOW; | 228 | err = PTR_ERR_OR_ZERO(nop->gpiod_vbus); |
167 | 229 | } | |
168 | } else if (pdata) { | 230 | } else if (pdata) { |
169 | type = pdata->type; | 231 | type = pdata->type; |
170 | clk_rate = pdata->clk_rate; | 232 | clk_rate = pdata->clk_rate; |
171 | needs_vcc = pdata->needs_vcc; | 233 | needs_vcc = pdata->needs_vcc; |
172 | nop->gpio_reset = pdata->gpio_reset; | 234 | if (gpio_is_valid(pdata->gpio_reset)) { |
173 | } else { | 235 | err = devm_gpio_request_one(dev, pdata->gpio_reset, 0, |
174 | nop->gpio_reset = -1; | 236 | dev_name(dev)); |
237 | if (!err) | ||
238 | nop->gpiod_reset = | ||
239 | gpio_to_desc(pdata->gpio_reset); | ||
240 | } | ||
241 | nop->gpiod_vbus = pdata->gpiod_vbus; | ||
242 | } | ||
243 | |||
244 | if (err == -EPROBE_DEFER) | ||
245 | return -EPROBE_DEFER; | ||
246 | if (err) { | ||
247 | dev_err(dev, "Error requesting RESET or VBUS GPIO\n"); | ||
248 | return err; | ||
175 | } | 249 | } |
250 | if (nop->gpiod_reset) | ||
251 | gpiod_direction_output(nop->gpiod_reset, 1); | ||
176 | 252 | ||
177 | nop->phy.otg = devm_kzalloc(dev, sizeof(*nop->phy.otg), | 253 | nop->phy.otg = devm_kzalloc(dev, sizeof(*nop->phy.otg), |
178 | GFP_KERNEL); | 254 | GFP_KERNEL); |
@@ -201,24 +277,6 @@ int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop, | |||
201 | return -EPROBE_DEFER; | 277 | return -EPROBE_DEFER; |
202 | } | 278 | } |
203 | 279 | ||
204 | if (gpio_is_valid(nop->gpio_reset)) { | ||
205 | unsigned long gpio_flags; | ||
206 | |||
207 | /* Assert RESET */ | ||
208 | if (nop->reset_active_low) | ||
209 | gpio_flags = GPIOF_OUT_INIT_LOW; | ||
210 | else | ||
211 | gpio_flags = GPIOF_OUT_INIT_HIGH; | ||
212 | |||
213 | err = devm_gpio_request_one(dev, nop->gpio_reset, | ||
214 | gpio_flags, dev_name(dev)); | ||
215 | if (err) { | ||
216 | dev_err(dev, "Error requesting RESET GPIO %d\n", | ||
217 | nop->gpio_reset); | ||
218 | return err; | ||
219 | } | ||
220 | } | ||
221 | |||
222 | nop->dev = dev; | 280 | nop->dev = dev; |
223 | nop->phy.dev = nop->dev; | 281 | nop->phy.dev = nop->dev; |
224 | nop->phy.label = "nop-xceiv"; | 282 | nop->phy.label = "nop-xceiv"; |
@@ -247,6 +305,18 @@ static int usb_phy_generic_probe(struct platform_device *pdev) | |||
247 | err = usb_phy_gen_create_phy(dev, nop, dev_get_platdata(&pdev->dev)); | 305 | err = usb_phy_gen_create_phy(dev, nop, dev_get_platdata(&pdev->dev)); |
248 | if (err) | 306 | if (err) |
249 | return err; | 307 | return err; |
308 | if (nop->gpiod_vbus) { | ||
309 | err = devm_request_threaded_irq(&pdev->dev, | ||
310 | gpiod_to_irq(nop->gpiod_vbus), | ||
311 | NULL, nop_gpio_vbus_thread, | ||
312 | VBUS_IRQ_FLAGS, "vbus_detect", | ||
313 | nop); | ||
314 | if (err) { | ||
315 | dev_err(&pdev->dev, "can't request irq %i, err: %d\n", | ||
316 | gpiod_to_irq(nop->gpiod_vbus), err); | ||
317 | return err; | ||
318 | } | ||
319 | } | ||
250 | 320 | ||
251 | nop->phy.init = usb_gen_phy_init; | 321 | nop->phy.init = usb_gen_phy_init; |
252 | nop->phy.shutdown = usb_gen_phy_shutdown; | 322 | nop->phy.shutdown = usb_gen_phy_shutdown; |
diff --git a/drivers/usb/phy/phy-generic.h b/drivers/usb/phy/phy-generic.h index d8feacc0b7fb..0d0eadd54ed9 100644 --- a/drivers/usb/phy/phy-generic.h +++ b/drivers/usb/phy/phy-generic.h | |||
@@ -2,14 +2,20 @@ | |||
2 | #define _PHY_GENERIC_H_ | 2 | #define _PHY_GENERIC_H_ |
3 | 3 | ||
4 | #include <linux/usb/usb_phy_generic.h> | 4 | #include <linux/usb/usb_phy_generic.h> |
5 | #include <linux/gpio/consumer.h> | ||
6 | #include <linux/regulator/consumer.h> | ||
5 | 7 | ||
6 | struct usb_phy_generic { | 8 | struct usb_phy_generic { |
7 | struct usb_phy phy; | 9 | struct usb_phy phy; |
8 | struct device *dev; | 10 | struct device *dev; |
9 | struct clk *clk; | 11 | struct clk *clk; |
10 | struct regulator *vcc; | 12 | struct regulator *vcc; |
11 | int gpio_reset; | 13 | struct gpio_desc *gpiod_reset; |
12 | bool reset_active_low; | 14 | struct gpio_desc *gpiod_vbus; |
15 | struct regulator *vbus_draw; | ||
16 | bool vbus_draw_enabled; | ||
17 | unsigned long mA; | ||
18 | unsigned int vbus; | ||
13 | }; | 19 | }; |
14 | 20 | ||
15 | int usb_gen_phy_init(struct usb_phy *phy); | 21 | int usb_gen_phy_init(struct usb_phy *phy); |
diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c index b9589f663683..8f7cb068d29b 100644 --- a/drivers/usb/phy/phy-mxs-usb.c +++ b/drivers/usb/phy/phy-mxs-usb.c | |||
@@ -40,6 +40,7 @@ | |||
40 | 40 | ||
41 | #define BM_USBPHY_CTRL_SFTRST BIT(31) | 41 | #define BM_USBPHY_CTRL_SFTRST BIT(31) |
42 | #define BM_USBPHY_CTRL_CLKGATE BIT(30) | 42 | #define BM_USBPHY_CTRL_CLKGATE BIT(30) |
43 | #define BM_USBPHY_CTRL_OTG_ID_VALUE BIT(27) | ||
43 | #define BM_USBPHY_CTRL_ENAUTOSET_USBCLKS BIT(26) | 44 | #define BM_USBPHY_CTRL_ENAUTOSET_USBCLKS BIT(26) |
44 | #define BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE BIT(25) | 45 | #define BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE BIT(25) |
45 | #define BM_USBPHY_CTRL_ENVBUSCHG_WKUP BIT(23) | 46 | #define BM_USBPHY_CTRL_ENVBUSCHG_WKUP BIT(23) |
@@ -69,6 +70,9 @@ | |||
69 | #define ANADIG_USB2_LOOPBACK_SET 0x244 | 70 | #define ANADIG_USB2_LOOPBACK_SET 0x244 |
70 | #define ANADIG_USB2_LOOPBACK_CLR 0x248 | 71 | #define ANADIG_USB2_LOOPBACK_CLR 0x248 |
71 | 72 | ||
73 | #define ANADIG_USB1_MISC 0x1f0 | ||
74 | #define ANADIG_USB2_MISC 0x250 | ||
75 | |||
72 | #define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG BIT(12) | 76 | #define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG BIT(12) |
73 | #define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG_SL BIT(11) | 77 | #define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG_SL BIT(11) |
74 | 78 | ||
@@ -80,6 +84,11 @@ | |||
80 | #define BM_ANADIG_USB2_LOOPBACK_UTMI_DIG_TST1 BIT(2) | 84 | #define BM_ANADIG_USB2_LOOPBACK_UTMI_DIG_TST1 BIT(2) |
81 | #define BM_ANADIG_USB2_LOOPBACK_TSTI_TX_EN BIT(5) | 85 | #define BM_ANADIG_USB2_LOOPBACK_TSTI_TX_EN BIT(5) |
82 | 86 | ||
87 | #define BM_ANADIG_USB1_MISC_RX_VPIN_FS BIT(29) | ||
88 | #define BM_ANADIG_USB1_MISC_RX_VMIN_FS BIT(28) | ||
89 | #define BM_ANADIG_USB2_MISC_RX_VPIN_FS BIT(29) | ||
90 | #define BM_ANADIG_USB2_MISC_RX_VMIN_FS BIT(28) | ||
91 | |||
83 | #define to_mxs_phy(p) container_of((p), struct mxs_phy, phy) | 92 | #define to_mxs_phy(p) container_of((p), struct mxs_phy, phy) |
84 | 93 | ||
85 | /* Do disconnection between PHY and controller without vbus */ | 94 | /* Do disconnection between PHY and controller without vbus */ |
@@ -131,8 +140,7 @@ static const struct mxs_phy_data vf610_phy_data = { | |||
131 | }; | 140 | }; |
132 | 141 | ||
133 | static const struct mxs_phy_data imx6sx_phy_data = { | 142 | static const struct mxs_phy_data imx6sx_phy_data = { |
134 | .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS | | 143 | .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS, |
135 | MXS_PHY_NEED_IP_FIX, | ||
136 | }; | 144 | }; |
137 | 145 | ||
138 | static const struct of_device_id mxs_phy_dt_ids[] = { | 146 | static const struct of_device_id mxs_phy_dt_ids[] = { |
@@ -256,6 +264,18 @@ static void __mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool disconnect) | |||
256 | usleep_range(500, 1000); | 264 | usleep_range(500, 1000); |
257 | } | 265 | } |
258 | 266 | ||
267 | static bool mxs_phy_is_otg_host(struct mxs_phy *mxs_phy) | ||
268 | { | ||
269 | void __iomem *base = mxs_phy->phy.io_priv; | ||
270 | u32 phyctrl = readl(base + HW_USBPHY_CTRL); | ||
271 | |||
272 | if (IS_ENABLED(CONFIG_USB_OTG) && | ||
273 | !(phyctrl & BM_USBPHY_CTRL_OTG_ID_VALUE)) | ||
274 | return true; | ||
275 | |||
276 | return false; | ||
277 | } | ||
278 | |||
259 | static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on) | 279 | static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on) |
260 | { | 280 | { |
261 | bool vbus_is_on = false; | 281 | bool vbus_is_on = false; |
@@ -270,7 +290,7 @@ static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on) | |||
270 | 290 | ||
271 | vbus_is_on = mxs_phy_get_vbus_status(mxs_phy); | 291 | vbus_is_on = mxs_phy_get_vbus_status(mxs_phy); |
272 | 292 | ||
273 | if (on && !vbus_is_on) | 293 | if (on && !vbus_is_on && !mxs_phy_is_otg_host(mxs_phy)) |
274 | __mxs_phy_disconnect_line(mxs_phy, true); | 294 | __mxs_phy_disconnect_line(mxs_phy, true); |
275 | else | 295 | else |
276 | __mxs_phy_disconnect_line(mxs_phy, false); | 296 | __mxs_phy_disconnect_line(mxs_phy, false); |
@@ -293,6 +313,17 @@ static int mxs_phy_init(struct usb_phy *phy) | |||
293 | static void mxs_phy_shutdown(struct usb_phy *phy) | 313 | static void mxs_phy_shutdown(struct usb_phy *phy) |
294 | { | 314 | { |
295 | struct mxs_phy *mxs_phy = to_mxs_phy(phy); | 315 | struct mxs_phy *mxs_phy = to_mxs_phy(phy); |
316 | u32 value = BM_USBPHY_CTRL_ENVBUSCHG_WKUP | | ||
317 | BM_USBPHY_CTRL_ENDPDMCHG_WKUP | | ||
318 | BM_USBPHY_CTRL_ENIDCHG_WKUP | | ||
319 | BM_USBPHY_CTRL_ENAUTOSET_USBCLKS | | ||
320 | BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE | | ||
321 | BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD | | ||
322 | BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE | | ||
323 | BM_USBPHY_CTRL_ENAUTO_PWRON_PLL; | ||
324 | |||
325 | writel(value, phy->io_priv + HW_USBPHY_CTRL_CLR); | ||
326 | writel(0xffffffff, phy->io_priv + HW_USBPHY_PWD); | ||
296 | 327 | ||
297 | writel(BM_USBPHY_CTRL_CLKGATE, | 328 | writel(BM_USBPHY_CTRL_CLKGATE, |
298 | phy->io_priv + HW_USBPHY_CTRL_SET); | 329 | phy->io_priv + HW_USBPHY_CTRL_SET); |
@@ -300,13 +331,56 @@ static void mxs_phy_shutdown(struct usb_phy *phy) | |||
300 | clk_disable_unprepare(mxs_phy->clk); | 331 | clk_disable_unprepare(mxs_phy->clk); |
301 | } | 332 | } |
302 | 333 | ||
334 | static bool mxs_phy_is_low_speed_connection(struct mxs_phy *mxs_phy) | ||
335 | { | ||
336 | unsigned int line_state; | ||
337 | /* bit definition is the same for all controllers */ | ||
338 | unsigned int dp_bit = BM_ANADIG_USB1_MISC_RX_VPIN_FS, | ||
339 | dm_bit = BM_ANADIG_USB1_MISC_RX_VMIN_FS; | ||
340 | unsigned int reg = ANADIG_USB1_MISC; | ||
341 | |||
342 | /* If the SoCs don't have anatop, quit */ | ||
343 | if (!mxs_phy->regmap_anatop) | ||
344 | return false; | ||
345 | |||
346 | if (mxs_phy->port_id == 0) | ||
347 | reg = ANADIG_USB1_MISC; | ||
348 | else if (mxs_phy->port_id == 1) | ||
349 | reg = ANADIG_USB2_MISC; | ||
350 | |||
351 | regmap_read(mxs_phy->regmap_anatop, reg, &line_state); | ||
352 | |||
353 | if ((line_state & (dp_bit | dm_bit)) == dm_bit) | ||
354 | return true; | ||
355 | else | ||
356 | return false; | ||
357 | } | ||
358 | |||
303 | static int mxs_phy_suspend(struct usb_phy *x, int suspend) | 359 | static int mxs_phy_suspend(struct usb_phy *x, int suspend) |
304 | { | 360 | { |
305 | int ret; | 361 | int ret; |
306 | struct mxs_phy *mxs_phy = to_mxs_phy(x); | 362 | struct mxs_phy *mxs_phy = to_mxs_phy(x); |
363 | bool low_speed_connection, vbus_is_on; | ||
364 | |||
365 | low_speed_connection = mxs_phy_is_low_speed_connection(mxs_phy); | ||
366 | vbus_is_on = mxs_phy_get_vbus_status(mxs_phy); | ||
307 | 367 | ||
308 | if (suspend) { | 368 | if (suspend) { |
309 | writel(0xffffffff, x->io_priv + HW_USBPHY_PWD); | 369 | /* |
370 | * FIXME: Do not power down RXPWD1PT1 bit for low speed | ||
371 | * connect. The low speed connection will have problem at | ||
372 | * very rare cases during usb suspend and resume process. | ||
373 | */ | ||
374 | if (low_speed_connection & vbus_is_on) { | ||
375 | /* | ||
376 | * If value to be set as pwd value is not 0xffffffff, | ||
377 | * several 32Khz cycles are needed. | ||
378 | */ | ||
379 | mxs_phy_clock_switch_delay(); | ||
380 | writel(0xffbfffff, x->io_priv + HW_USBPHY_PWD); | ||
381 | } else { | ||
382 | writel(0xffffffff, x->io_priv + HW_USBPHY_PWD); | ||
383 | } | ||
310 | writel(BM_USBPHY_CTRL_CLKGATE, | 384 | writel(BM_USBPHY_CTRL_CLKGATE, |
311 | x->io_priv + HW_USBPHY_CTRL_SET); | 385 | x->io_priv + HW_USBPHY_CTRL_SET); |
312 | clk_disable_unprepare(mxs_phy->clk); | 386 | clk_disable_unprepare(mxs_phy->clk); |
@@ -359,7 +433,9 @@ static int mxs_phy_on_disconnect(struct usb_phy *phy, | |||
359 | dev_dbg(phy->dev, "%s device has disconnected\n", | 433 | dev_dbg(phy->dev, "%s device has disconnected\n", |
360 | (speed == USB_SPEED_HIGH) ? "HS" : "FS/LS"); | 434 | (speed == USB_SPEED_HIGH) ? "HS" : "FS/LS"); |
361 | 435 | ||
362 | if (speed == USB_SPEED_HIGH) | 436 | /* Sometimes, the speed is not high speed when the error occurs */ |
437 | if (readl(phy->io_priv + HW_USBPHY_CTRL) & | ||
438 | BM_USBPHY_CTRL_ENHOSTDISCONDETECT) | ||
363 | writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, | 439 | writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, |
364 | phy->io_priv + HW_USBPHY_CTRL_CLR); | 440 | phy->io_priv + HW_USBPHY_CTRL_CLR); |
365 | 441 | ||
diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index 371478704899..4cf77d3c3bd2 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c | |||
@@ -363,6 +363,7 @@ static void usbhsc_hotplug(struct usbhs_priv *priv) | |||
363 | struct usbhs_mod *mod = usbhs_mod_get_current(priv); | 363 | struct usbhs_mod *mod = usbhs_mod_get_current(priv); |
364 | int id; | 364 | int id; |
365 | int enable; | 365 | int enable; |
366 | int cable; | ||
366 | int ret; | 367 | int ret; |
367 | 368 | ||
368 | /* | 369 | /* |
@@ -376,6 +377,16 @@ static void usbhsc_hotplug(struct usbhs_priv *priv) | |||
376 | id = usbhs_platform_call(priv, get_id, pdev); | 377 | id = usbhs_platform_call(priv, get_id, pdev); |
377 | 378 | ||
378 | if (enable && !mod) { | 379 | if (enable && !mod) { |
380 | if (priv->edev) { | ||
381 | cable = extcon_get_cable_state(priv->edev, "USB-HOST"); | ||
382 | if ((cable > 0 && id != USBHS_HOST) || | ||
383 | (!cable && id != USBHS_GADGET)) { | ||
384 | dev_info(&pdev->dev, | ||
385 | "USB cable plugged in doesn't match the selected role!\n"); | ||
386 | return; | ||
387 | } | ||
388 | } | ||
389 | |||
379 | ret = usbhs_mod_change(priv, id); | 390 | ret = usbhs_mod_change(priv, id); |
380 | if (ret < 0) | 391 | if (ret < 0) |
381 | return; | 392 | return; |
@@ -514,6 +525,12 @@ static int usbhs_probe(struct platform_device *pdev) | |||
514 | if (IS_ERR(priv->base)) | 525 | if (IS_ERR(priv->base)) |
515 | return PTR_ERR(priv->base); | 526 | return PTR_ERR(priv->base); |
516 | 527 | ||
528 | if (of_property_read_bool(pdev->dev.of_node, "extcon")) { | ||
529 | priv->edev = extcon_get_edev_by_phandle(&pdev->dev, 0); | ||
530 | if (IS_ERR(priv->edev)) | ||
531 | return PTR_ERR(priv->edev); | ||
532 | } | ||
533 | |||
517 | /* | 534 | /* |
518 | * care platform info | 535 | * care platform info |
519 | */ | 536 | */ |
@@ -615,7 +632,7 @@ static int usbhs_probe(struct platform_device *pdev) | |||
615 | */ | 632 | */ |
616 | ret = usbhs_platform_call(priv, hardware_init, pdev); | 633 | ret = usbhs_platform_call(priv, hardware_init, pdev); |
617 | if (ret < 0) { | 634 | if (ret < 0) { |
618 | dev_err(&pdev->dev, "platform prove failed.\n"); | 635 | dev_err(&pdev->dev, "platform init failed.\n"); |
619 | goto probe_end_mod_exit; | 636 | goto probe_end_mod_exit; |
620 | } | 637 | } |
621 | 638 | ||
@@ -632,16 +649,12 @@ static int usbhs_probe(struct platform_device *pdev) | |||
632 | /* | 649 | /* |
633 | * manual call notify_hotplug for cold plug | 650 | * manual call notify_hotplug for cold plug |
634 | */ | 651 | */ |
635 | ret = usbhsc_drvcllbck_notify_hotplug(pdev); | 652 | usbhsc_drvcllbck_notify_hotplug(pdev); |
636 | if (ret < 0) | ||
637 | goto probe_end_call_remove; | ||
638 | 653 | ||
639 | dev_info(&pdev->dev, "probed\n"); | 654 | dev_info(&pdev->dev, "probed\n"); |
640 | 655 | ||
641 | return ret; | 656 | return ret; |
642 | 657 | ||
643 | probe_end_call_remove: | ||
644 | usbhs_platform_call(priv, hardware_exit, pdev); | ||
645 | probe_end_mod_exit: | 658 | probe_end_mod_exit: |
646 | usbhs_mod_remove(priv); | 659 | usbhs_mod_remove(priv); |
647 | probe_end_fifo_exit: | 660 | probe_end_fifo_exit: |
diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h index 0427cdd1a483..fc96e924edc4 100644 --- a/drivers/usb/renesas_usbhs/common.h +++ b/drivers/usb/renesas_usbhs/common.h | |||
@@ -17,6 +17,7 @@ | |||
17 | #ifndef RENESAS_USB_DRIVER_H | 17 | #ifndef RENESAS_USB_DRIVER_H |
18 | #define RENESAS_USB_DRIVER_H | 18 | #define RENESAS_USB_DRIVER_H |
19 | 19 | ||
20 | #include <linux/extcon.h> | ||
20 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
21 | #include <linux/usb/renesas_usbhs.h> | 22 | #include <linux/usb/renesas_usbhs.h> |
22 | 23 | ||
@@ -254,6 +255,8 @@ struct usbhs_priv { | |||
254 | struct delayed_work notify_hotplug_work; | 255 | struct delayed_work notify_hotplug_work; |
255 | struct platform_device *pdev; | 256 | struct platform_device *pdev; |
256 | 257 | ||
258 | struct extcon_dev *edev; | ||
259 | |||
257 | spinlock_t lock; | 260 | spinlock_t lock; |
258 | 261 | ||
259 | u32 flags; | 262 | u32 flags; |
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index f46271ce1b15..d891bff39d66 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c | |||
@@ -1054,10 +1054,8 @@ static void usbhsf_dma_quit(struct usbhs_priv *priv, struct usbhs_fifo *fifo) | |||
1054 | fifo->rx_chan = NULL; | 1054 | fifo->rx_chan = NULL; |
1055 | } | 1055 | } |
1056 | 1056 | ||
1057 | static void usbhsf_dma_init(struct usbhs_priv *priv, | 1057 | static void usbhsf_dma_init_pdev(struct usbhs_fifo *fifo) |
1058 | struct usbhs_fifo *fifo) | ||
1059 | { | 1058 | { |
1060 | struct device *dev = usbhs_priv_to_dev(priv); | ||
1061 | dma_cap_mask_t mask; | 1059 | dma_cap_mask_t mask; |
1062 | 1060 | ||
1063 | dma_cap_zero(mask); | 1061 | dma_cap_zero(mask); |
@@ -1069,6 +1067,27 @@ static void usbhsf_dma_init(struct usbhs_priv *priv, | |||
1069 | dma_cap_set(DMA_SLAVE, mask); | 1067 | dma_cap_set(DMA_SLAVE, mask); |
1070 | fifo->rx_chan = dma_request_channel(mask, usbhsf_dma_filter, | 1068 | fifo->rx_chan = dma_request_channel(mask, usbhsf_dma_filter, |
1071 | &fifo->rx_slave); | 1069 | &fifo->rx_slave); |
1070 | } | ||
1071 | |||
1072 | static void usbhsf_dma_init_dt(struct device *dev, struct usbhs_fifo *fifo) | ||
1073 | { | ||
1074 | fifo->tx_chan = dma_request_slave_channel_reason(dev, "tx"); | ||
1075 | if (IS_ERR(fifo->tx_chan)) | ||
1076 | fifo->tx_chan = NULL; | ||
1077 | fifo->rx_chan = dma_request_slave_channel_reason(dev, "rx"); | ||
1078 | if (IS_ERR(fifo->rx_chan)) | ||
1079 | fifo->rx_chan = NULL; | ||
1080 | } | ||
1081 | |||
1082 | static void usbhsf_dma_init(struct usbhs_priv *priv, | ||
1083 | struct usbhs_fifo *fifo) | ||
1084 | { | ||
1085 | struct device *dev = usbhs_priv_to_dev(priv); | ||
1086 | |||
1087 | if (dev->of_node) | ||
1088 | usbhsf_dma_init_dt(dev, fifo); | ||
1089 | else | ||
1090 | usbhsf_dma_init_pdev(fifo); | ||
1072 | 1091 | ||
1073 | if (fifo->tx_chan || fifo->rx_chan) | 1092 | if (fifo->tx_chan || fifo->rx_chan) |
1074 | dev_dbg(dev, "enable DMAEngine (%s%s%s)\n", | 1093 | dev_dbg(dev, "enable DMAEngine (%s%s%s)\n", |
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index 8697e6efcabf..e0384af77e56 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c | |||
@@ -926,6 +926,8 @@ static int usbhsg_set_selfpowered(struct usb_gadget *gadget, int is_self) | |||
926 | else | 926 | else |
927 | usbhsg_status_clr(gpriv, USBHSG_STATUS_SELF_POWERED); | 927 | usbhsg_status_clr(gpriv, USBHSG_STATUS_SELF_POWERED); |
928 | 928 | ||
929 | gadget->is_selfpowered = (is_self != 0); | ||
930 | |||
929 | return 0; | 931 | return 0; |
930 | } | 932 | } |
931 | 933 | ||
diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c index f0d323125871..96eead619282 100644 --- a/drivers/usb/renesas_usbhs/mod_host.c +++ b/drivers/usb/renesas_usbhs/mod_host.c | |||
@@ -1234,7 +1234,8 @@ static int __usbhsh_hub_get_status(struct usbhsh_hpriv *hpriv, | |||
1234 | desc->bNbrPorts = roothub_id; | 1234 | desc->bNbrPorts = roothub_id; |
1235 | desc->bDescLength = 9; | 1235 | desc->bDescLength = 9; |
1236 | desc->bPwrOn2PwrGood = 0; | 1236 | desc->bPwrOn2PwrGood = 0; |
1237 | desc->wHubCharacteristics = cpu_to_le16(0x0011); | 1237 | desc->wHubCharacteristics = |
1238 | cpu_to_le16(HUB_CHAR_INDV_PORT_LPSM | HUB_CHAR_NO_OCPM); | ||
1238 | desc->u.hs.DeviceRemovable[0] = (roothub_id << 1); | 1239 | desc->u.hs.DeviceRemovable[0] = (roothub_id << 1); |
1239 | desc->u.hs.DeviceRemovable[1] = ~0; | 1240 | desc->u.hs.DeviceRemovable[1] = ~0; |
1240 | dev_dbg(dev, "%s :: GetHubDescriptor\n", __func__); | 1241 | dev_dbg(dev, "%s :: GetHubDescriptor\n", __func__); |
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index f4c56fc1a9f6..f40c856ff758 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c | |||
@@ -56,6 +56,7 @@ static const struct usb_device_id id_table[] = { | |||
56 | { USB_DEVICE(0x0846, 0x1100) }, /* NetGear Managed Switch M4100 series, M5300 series, M7100 series */ | 56 | { USB_DEVICE(0x0846, 0x1100) }, /* NetGear Managed Switch M4100 series, M5300 series, M7100 series */ |
57 | { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */ | 57 | { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */ |
58 | { USB_DEVICE(0x08FD, 0x000A) }, /* Digianswer A/S , ZigBee/802.15.4 MAC Device */ | 58 | { USB_DEVICE(0x08FD, 0x000A) }, /* Digianswer A/S , ZigBee/802.15.4 MAC Device */ |
59 | { USB_DEVICE(0x0908, 0x01FF) }, /* Siemens RUGGEDCOM USB Serial Console */ | ||
59 | { USB_DEVICE(0x0BED, 0x1100) }, /* MEI (TM) Cashflow-SC Bill/Voucher Acceptor */ | 60 | { USB_DEVICE(0x0BED, 0x1100) }, /* MEI (TM) Cashflow-SC Bill/Voucher Acceptor */ |
60 | { USB_DEVICE(0x0BED, 0x1101) }, /* MEI series 2000 Combo Acceptor */ | 61 | { USB_DEVICE(0x0BED, 0x1101) }, /* MEI series 2000 Combo Acceptor */ |
61 | { USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */ | 62 | { USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */ |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 220b4be89641..e4473a9109cf 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -1309,35 +1309,6 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
1309 | const unsigned char *current_position = data; | 1309 | const unsigned char *current_position = data; |
1310 | unsigned char *data1; | 1310 | unsigned char *data1; |
1311 | 1311 | ||
1312 | #ifdef NOTMOS7840 | ||
1313 | Data = 0x00; | ||
1314 | status = mos7840_get_uart_reg(port, LINE_CONTROL_REGISTER, &Data); | ||
1315 | mos7840_port->shadowLCR = Data; | ||
1316 | dev_dbg(&port->dev, "%s: LINE_CONTROL_REGISTER is %x\n", __func__, Data); | ||
1317 | dev_dbg(&port->dev, "%s: mos7840_port->shadowLCR is %x\n", __func__, mos7840_port->shadowLCR); | ||
1318 | |||
1319 | /* Data = 0x03; */ | ||
1320 | /* status = mos7840_set_uart_reg(port,LINE_CONTROL_REGISTER,Data); */ | ||
1321 | /* mos7840_port->shadowLCR=Data;//Need to add later */ | ||
1322 | |||
1323 | Data |= SERIAL_LCR_DLAB; /* data latch enable in LCR 0x80 */ | ||
1324 | status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data); | ||
1325 | |||
1326 | /* Data = 0x0c; */ | ||
1327 | /* status = mos7840_set_uart_reg(port,DIVISOR_LATCH_LSB,Data); */ | ||
1328 | Data = 0x00; | ||
1329 | status = mos7840_get_uart_reg(port, DIVISOR_LATCH_LSB, &Data); | ||
1330 | dev_dbg(&port->dev, "%s: DLL value is %x\n", __func__, Data); | ||
1331 | |||
1332 | Data = 0x0; | ||
1333 | status = mos7840_get_uart_reg(port, DIVISOR_LATCH_MSB, &Data); | ||
1334 | dev_dbg(&port->dev, "%s: DLM value is %x\n", __func__, Data); | ||
1335 | |||
1336 | Data = Data & ~SERIAL_LCR_DLAB; | ||
1337 | dev_dbg(&port->dev, "%s: mos7840_port->shadowLCR is %x\n", __func__, mos7840_port->shadowLCR); | ||
1338 | status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data); | ||
1339 | #endif | ||
1340 | |||
1341 | if (mos7840_port_paranoia_check(port, __func__)) | 1312 | if (mos7840_port_paranoia_check(port, __func__)) |
1342 | return -1; | 1313 | return -1; |
1343 | 1314 | ||
@@ -1614,37 +1585,6 @@ static int mos7840_calc_baud_rate_divisor(struct usb_serial_port *port, | |||
1614 | *clk_sel_val = 0x70; | 1585 | *clk_sel_val = 0x70; |
1615 | } | 1586 | } |
1616 | return 0; | 1587 | return 0; |
1617 | |||
1618 | #ifdef NOTMCS7840 | ||
1619 | |||
1620 | for (i = 0; i < ARRAY_SIZE(mos7840_divisor_table); i++) { | ||
1621 | if (mos7840_divisor_table[i].BaudRate == baudrate) { | ||
1622 | *divisor = mos7840_divisor_table[i].Divisor; | ||
1623 | return 0; | ||
1624 | } | ||
1625 | } | ||
1626 | |||
1627 | /* After trying for all the standard baud rates * | ||
1628 | * Try calculating the divisor for this baud rate */ | ||
1629 | |||
1630 | if (baudrate > 75 && baudrate < 230400) { | ||
1631 | /* get the divisor */ | ||
1632 | custom = (__u16) (230400L / baudrate); | ||
1633 | |||
1634 | /* Check for round off */ | ||
1635 | round1 = (__u16) (2304000L / baudrate); | ||
1636 | round = (__u16) (round1 - (custom * 10)); | ||
1637 | if (round > 4) | ||
1638 | custom++; | ||
1639 | *divisor = custom; | ||
1640 | |||
1641 | dev_dbg(&port->dev, " Baud %d = %d\n", baudrate, custom); | ||
1642 | return 0; | ||
1643 | } | ||
1644 | |||
1645 | dev_dbg(&port->dev, "%s", " Baud calculation Failed...\n"); | ||
1646 | return -1; | ||
1647 | #endif | ||
1648 | } | 1588 | } |
1649 | 1589 | ||
1650 | /***************************************************************************** | 1590 | /***************************************************************************** |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index efdcee15b520..f0c0c53359ad 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -507,18 +507,10 @@ static void option_instat_callback(struct urb *urb); | |||
507 | #define VIATELECOM_VENDOR_ID 0x15eb | 507 | #define VIATELECOM_VENDOR_ID 0x15eb |
508 | #define VIATELECOM_PRODUCT_CDS7 0x0001 | 508 | #define VIATELECOM_PRODUCT_CDS7 0x0001 |
509 | 509 | ||
510 | /* some devices interfaces need special handling due to a number of reasons */ | ||
511 | enum option_blacklist_reason { | ||
512 | OPTION_BLACKLIST_NONE = 0, | ||
513 | OPTION_BLACKLIST_SENDSETUP = 1, | ||
514 | OPTION_BLACKLIST_RESERVED_IF = 2 | ||
515 | }; | ||
516 | |||
517 | #define MAX_BL_NUM 11 | ||
518 | struct option_blacklist_info { | 510 | struct option_blacklist_info { |
519 | /* bitfield of interface numbers for OPTION_BLACKLIST_SENDSETUP */ | 511 | /* bitmask of interface numbers blacklisted for send_setup */ |
520 | const unsigned long sendsetup; | 512 | const unsigned long sendsetup; |
521 | /* bitfield of interface numbers for OPTION_BLACKLIST_RESERVED_IF */ | 513 | /* bitmask of interface numbers that are reserved */ |
522 | const unsigned long reserved; | 514 | const unsigned long reserved; |
523 | }; | 515 | }; |
524 | 516 | ||
@@ -1822,36 +1814,13 @@ struct option_private { | |||
1822 | 1814 | ||
1823 | module_usb_serial_driver(serial_drivers, option_ids); | 1815 | module_usb_serial_driver(serial_drivers, option_ids); |
1824 | 1816 | ||
1825 | static bool is_blacklisted(const u8 ifnum, enum option_blacklist_reason reason, | ||
1826 | const struct option_blacklist_info *blacklist) | ||
1827 | { | ||
1828 | unsigned long num; | ||
1829 | const unsigned long *intf_list; | ||
1830 | |||
1831 | if (blacklist) { | ||
1832 | if (reason == OPTION_BLACKLIST_SENDSETUP) | ||
1833 | intf_list = &blacklist->sendsetup; | ||
1834 | else if (reason == OPTION_BLACKLIST_RESERVED_IF) | ||
1835 | intf_list = &blacklist->reserved; | ||
1836 | else { | ||
1837 | BUG_ON(reason); | ||
1838 | return false; | ||
1839 | } | ||
1840 | |||
1841 | for_each_set_bit(num, intf_list, MAX_BL_NUM + 1) { | ||
1842 | if (num == ifnum) | ||
1843 | return true; | ||
1844 | } | ||
1845 | } | ||
1846 | return false; | ||
1847 | } | ||
1848 | |||
1849 | static int option_probe(struct usb_serial *serial, | 1817 | static int option_probe(struct usb_serial *serial, |
1850 | const struct usb_device_id *id) | 1818 | const struct usb_device_id *id) |
1851 | { | 1819 | { |
1852 | struct usb_interface_descriptor *iface_desc = | 1820 | struct usb_interface_descriptor *iface_desc = |
1853 | &serial->interface->cur_altsetting->desc; | 1821 | &serial->interface->cur_altsetting->desc; |
1854 | struct usb_device_descriptor *dev_desc = &serial->dev->descriptor; | 1822 | struct usb_device_descriptor *dev_desc = &serial->dev->descriptor; |
1823 | const struct option_blacklist_info *blacklist; | ||
1855 | 1824 | ||
1856 | /* Never bind to the CD-Rom emulation interface */ | 1825 | /* Never bind to the CD-Rom emulation interface */ |
1857 | if (iface_desc->bInterfaceClass == 0x08) | 1826 | if (iface_desc->bInterfaceClass == 0x08) |
@@ -1862,10 +1831,9 @@ static int option_probe(struct usb_serial *serial, | |||
1862 | * the same class/subclass/protocol as the serial interfaces. Look at | 1831 | * the same class/subclass/protocol as the serial interfaces. Look at |
1863 | * the Windows driver .INF files for reserved interface numbers. | 1832 | * the Windows driver .INF files for reserved interface numbers. |
1864 | */ | 1833 | */ |
1865 | if (is_blacklisted( | 1834 | blacklist = (void *)id->driver_info; |
1866 | iface_desc->bInterfaceNumber, | 1835 | if (blacklist && test_bit(iface_desc->bInterfaceNumber, |
1867 | OPTION_BLACKLIST_RESERVED_IF, | 1836 | &blacklist->reserved)) |
1868 | (const struct option_blacklist_info *) id->driver_info)) | ||
1869 | return -ENODEV; | 1837 | return -ENODEV; |
1870 | /* | 1838 | /* |
1871 | * Don't bind network interface on Samsung GT-B3730, it is handled by | 1839 | * Don't bind network interface on Samsung GT-B3730, it is handled by |
@@ -1876,8 +1844,8 @@ static int option_probe(struct usb_serial *serial, | |||
1876 | iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA) | 1844 | iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA) |
1877 | return -ENODEV; | 1845 | return -ENODEV; |
1878 | 1846 | ||
1879 | /* Store device id so we can use it during attach. */ | 1847 | /* Store the blacklist info so we can use it during attach. */ |
1880 | usb_set_serial_data(serial, (void *)id); | 1848 | usb_set_serial_data(serial, (void *)blacklist); |
1881 | 1849 | ||
1882 | return 0; | 1850 | return 0; |
1883 | } | 1851 | } |
@@ -1885,7 +1853,7 @@ static int option_probe(struct usb_serial *serial, | |||
1885 | static int option_attach(struct usb_serial *serial) | 1853 | static int option_attach(struct usb_serial *serial) |
1886 | { | 1854 | { |
1887 | struct usb_interface_descriptor *iface_desc; | 1855 | struct usb_interface_descriptor *iface_desc; |
1888 | const struct usb_device_id *id; | 1856 | const struct option_blacklist_info *blacklist; |
1889 | struct usb_wwan_intf_private *data; | 1857 | struct usb_wwan_intf_private *data; |
1890 | struct option_private *priv; | 1858 | struct option_private *priv; |
1891 | 1859 | ||
@@ -1899,16 +1867,16 @@ static int option_attach(struct usb_serial *serial) | |||
1899 | return -ENOMEM; | 1867 | return -ENOMEM; |
1900 | } | 1868 | } |
1901 | 1869 | ||
1902 | /* Retrieve device id stored at probe. */ | 1870 | /* Retrieve blacklist info stored at probe. */ |
1903 | id = usb_get_serial_data(serial); | 1871 | blacklist = usb_get_serial_data(serial); |
1872 | |||
1904 | iface_desc = &serial->interface->cur_altsetting->desc; | 1873 | iface_desc = &serial->interface->cur_altsetting->desc; |
1905 | 1874 | ||
1906 | priv->bInterfaceNumber = iface_desc->bInterfaceNumber; | 1875 | priv->bInterfaceNumber = iface_desc->bInterfaceNumber; |
1907 | data->private = priv; | 1876 | data->private = priv; |
1908 | 1877 | ||
1909 | if (!is_blacklisted(iface_desc->bInterfaceNumber, | 1878 | if (!blacklist || !test_bit(iface_desc->bInterfaceNumber, |
1910 | OPTION_BLACKLIST_SENDSETUP, | 1879 | &blacklist->sendsetup)) { |
1911 | (struct option_blacklist_info *)id->driver_info)) { | ||
1912 | data->send_setup = option_send_setup; | 1880 | data->send_setup = option_send_setup; |
1913 | } | 1881 | } |
1914 | spin_lock_init(&data->susp_lock); | 1882 | spin_lock_init(&data->susp_lock); |
diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 1ae9d40f96bf..11f6f61c2381 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c | |||
@@ -218,7 +218,8 @@ static inline void hub_descriptor(struct usb_hub_descriptor *desc) | |||
218 | memset(desc, 0, sizeof(*desc)); | 218 | memset(desc, 0, sizeof(*desc)); |
219 | desc->bDescriptorType = 0x29; | 219 | desc->bDescriptorType = 0x29; |
220 | desc->bDescLength = 9; | 220 | desc->bDescLength = 9; |
221 | desc->wHubCharacteristics = (__constant_cpu_to_le16(0x0001)); | 221 | desc->wHubCharacteristics = __constant_cpu_to_le16( |
222 | HUB_CHAR_INDV_PORT_LPSM | HUB_CHAR_COMMON_OCPM); | ||
222 | desc->bNbrPorts = VHCI_NPORTS; | 223 | desc->bNbrPorts = VHCI_NPORTS; |
223 | desc->u.hs.DeviceRemovable[0] = 0xff; | 224 | desc->u.hs.DeviceRemovable[0] = 0xff; |
224 | desc->u.hs.DeviceRemovable[1] = 0xff; | 225 | desc->u.hs.DeviceRemovable[1] = 0xff; |
diff --git a/drivers/usb/wusbcore/rh.c b/drivers/usb/wusbcore/rh.c index fe8bc777ab88..aa5af817f31c 100644 --- a/drivers/usb/wusbcore/rh.c +++ b/drivers/usb/wusbcore/rh.c | |||
@@ -185,9 +185,9 @@ static int wusbhc_rh_get_hub_descr(struct wusbhc *wusbhc, u16 wValue, | |||
185 | descr->bDescriptorType = 0x29; /* HUB type */ | 185 | descr->bDescriptorType = 0x29; /* HUB type */ |
186 | descr->bNbrPorts = wusbhc->ports_max; | 186 | descr->bNbrPorts = wusbhc->ports_max; |
187 | descr->wHubCharacteristics = cpu_to_le16( | 187 | descr->wHubCharacteristics = cpu_to_le16( |
188 | 0x00 /* All ports power at once */ | 188 | HUB_CHAR_COMMON_LPSM /* All ports power at once */ |
189 | | 0x00 /* not part of compound device */ | 189 | | 0x00 /* not part of compound device */ |
190 | | 0x10 /* No overcurrent protection */ | 190 | | HUB_CHAR_NO_OCPM /* No overcurrent protection */ |
191 | | 0x00 /* 8 FS think time FIXME ?? */ | 191 | | 0x00 /* 8 FS think time FIXME ?? */ |
192 | | 0x00); /* No port indicators */ | 192 | | 0x00); /* No port indicators */ |
193 | descr->bPwrOn2PwrGood = 0; | 193 | descr->bPwrOn2PwrGood = 0; |
diff --git a/drivers/uwb/lc-dev.c b/drivers/uwb/lc-dev.c index 8c7cfab5cee3..72033589db19 100644 --- a/drivers/uwb/lc-dev.c +++ b/drivers/uwb/lc-dev.c | |||
@@ -43,13 +43,6 @@ static inline void uwb_mac_addr_init(struct uwb_mac_addr *addr) | |||
43 | memset(&addr->data, 0xff, sizeof(addr->data)); | 43 | memset(&addr->data, 0xff, sizeof(addr->data)); |
44 | } | 44 | } |
45 | 45 | ||
46 | /* @returns !0 if a device @addr is a broadcast address */ | ||
47 | static inline int uwb_dev_addr_bcast(const struct uwb_dev_addr *addr) | ||
48 | { | ||
49 | static const struct uwb_dev_addr bcast = { .data = { 0xff, 0xff } }; | ||
50 | return !uwb_dev_addr_cmp(addr, &bcast); | ||
51 | } | ||
52 | |||
53 | /* | 46 | /* |
54 | * Add callback @new to be called when an event occurs in @rc. | 47 | * Add callback @new to be called when an event occurs in @rc. |
55 | */ | 48 | */ |
diff --git a/include/linux/mfd/syscon/exynos4-pmu.h b/include/linux/mfd/syscon/exynos4-pmu.h new file mode 100644 index 000000000000..278b1b1549e9 --- /dev/null +++ b/include/linux/mfd/syscon/exynos4-pmu.h | |||
@@ -0,0 +1,21 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2015 Samsung Electronics Co., Ltd. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #ifndef _LINUX_MFD_SYSCON_PMU_EXYNOS4_H_ | ||
10 | #define _LINUX_MFD_SYSCON_PMU_EXYNOS4_H_ | ||
11 | |||
12 | /* Exynos4 PMU register definitions */ | ||
13 | |||
14 | /* MIPI_PHYn_CONTROL register offset: n = 0..1 */ | ||
15 | #define EXYNOS4_MIPI_PHY_CONTROL(n) (0x710 + (n) * 4) | ||
16 | #define EXYNOS4_MIPI_PHY_ENABLE (1 << 0) | ||
17 | #define EXYNOS4_MIPI_PHY_SRESETN (1 << 1) | ||
18 | #define EXYNOS4_MIPI_PHY_MRESETN (1 << 2) | ||
19 | #define EXYNOS4_MIPI_PHY_RESET_MASK (3 << 1) | ||
20 | |||
21 | #endif /* _LINUX_MFD_SYSCON_PMU_EXYNOS4_H_ */ | ||
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index bbf85d612be5..2e75ab00dbf2 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h | |||
@@ -53,9 +53,9 @@ struct ieee1394_device_id { | |||
53 | 53 | ||
54 | /** | 54 | /** |
55 | * struct usb_device_id - identifies USB devices for probing and hotplugging | 55 | * struct usb_device_id - identifies USB devices for probing and hotplugging |
56 | * @match_flags: Bit mask controlling of the other fields are used to match | 56 | * @match_flags: Bit mask controlling which of the other fields are used to |
57 | * against new devices. Any field except for driver_info may be used, | 57 | * match against new devices. Any field except for driver_info may be |
58 | * although some only make sense in conjunction with other fields. | 58 | * used, although some only make sense in conjunction with other fields. |
59 | * This is usually set by a USB_DEVICE_*() macro, which sets all | 59 | * This is usually set by a USB_DEVICE_*() macro, which sets all |
60 | * other fields in this structure except for driver_info. | 60 | * other fields in this structure except for driver_info. |
61 | * @idVendor: USB vendor ID for a device; numbers are assigned | 61 | * @idVendor: USB vendor ID for a device; numbers are assigned |
diff --git a/include/linux/usb.h b/include/linux/usb.h index f89c24a03bd9..7ee1b5c3b4cb 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h | |||
@@ -82,7 +82,7 @@ struct usb_host_interface { | |||
82 | int extralen; | 82 | int extralen; |
83 | unsigned char *extra; /* Extra descriptors */ | 83 | unsigned char *extra; /* Extra descriptors */ |
84 | 84 | ||
85 | /* array of desc.bNumEndpoint endpoints associated with this | 85 | /* array of desc.bNumEndpoints endpoints associated with this |
86 | * interface setting. these will be in no particular order. | 86 | * interface setting. these will be in no particular order. |
87 | */ | 87 | */ |
88 | struct usb_host_endpoint *endpoint; | 88 | struct usb_host_endpoint *endpoint; |
@@ -127,10 +127,6 @@ enum usb_interface_condition { | |||
127 | * to the sysfs representation for that device. | 127 | * to the sysfs representation for that device. |
128 | * @pm_usage_cnt: PM usage counter for this interface | 128 | * @pm_usage_cnt: PM usage counter for this interface |
129 | * @reset_ws: Used for scheduling resets from atomic context. | 129 | * @reset_ws: Used for scheduling resets from atomic context. |
130 | * @reset_running: set to 1 if the interface is currently running a | ||
131 | * queued reset so that usb_cancel_queued_reset() doesn't try to | ||
132 | * remove from the workqueue when running inside the worker | ||
133 | * thread. See __usb_queue_reset_device(). | ||
134 | * @resetting_device: USB core reset the device, so use alt setting 0 as | 130 | * @resetting_device: USB core reset the device, so use alt setting 0 as |
135 | * current; needs bandwidth alloc after reset. | 131 | * current; needs bandwidth alloc after reset. |
136 | * | 132 | * |
@@ -181,7 +177,6 @@ struct usb_interface { | |||
181 | unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */ | 177 | unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */ |
182 | unsigned needs_altsetting0:1; /* switch to altsetting 0 is pending */ | 178 | unsigned needs_altsetting0:1; /* switch to altsetting 0 is pending */ |
183 | unsigned needs_binding:1; /* needs delayed unbind/rebind */ | 179 | unsigned needs_binding:1; /* needs delayed unbind/rebind */ |
184 | unsigned reset_running:1; | ||
185 | unsigned resetting_device:1; /* true: bandwidth alloc after reset */ | 180 | unsigned resetting_device:1; /* true: bandwidth alloc after reset */ |
186 | 181 | ||
187 | struct device dev; /* interface specific device info */ | 182 | struct device dev; /* interface specific device info */ |
diff --git a/include/linux/usb/ehci_pdriver.h b/include/linux/usb/ehci_pdriver.h index 7eb4dcd0d386..db0431b39a63 100644 --- a/include/linux/usb/ehci_pdriver.h +++ b/include/linux/usb/ehci_pdriver.h | |||
@@ -34,6 +34,8 @@ struct usb_hcd; | |||
34 | * after initialization. | 34 | * after initialization. |
35 | * @no_io_watchdog: set to 1 if the controller does not need the I/O | 35 | * @no_io_watchdog: set to 1 if the controller does not need the I/O |
36 | * watchdog to run. | 36 | * watchdog to run. |
37 | * @reset_on_resume: set to 1 if the controller needs to be reset after | ||
38 | * a suspend / resume cycle (but can't detect that itself). | ||
37 | * | 39 | * |
38 | * These are general configuration options for the EHCI controller. All of | 40 | * These are general configuration options for the EHCI controller. All of |
39 | * these options are activating more or less workarounds for some hardware. | 41 | * these options are activating more or less workarounds for some hardware. |
@@ -45,6 +47,8 @@ struct usb_ehci_pdata { | |||
45 | unsigned big_endian_desc:1; | 47 | unsigned big_endian_desc:1; |
46 | unsigned big_endian_mmio:1; | 48 | unsigned big_endian_mmio:1; |
47 | unsigned no_io_watchdog:1; | 49 | unsigned no_io_watchdog:1; |
50 | unsigned reset_on_resume:1; | ||
51 | unsigned dma_mask_64:1; | ||
48 | 52 | ||
49 | /* Turn on all power and clocks */ | 53 | /* Turn on all power and clocks */ |
50 | int (*power_on)(struct platform_device *pdev); | 54 | int (*power_on)(struct platform_device *pdev); |
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 70ddb3943b62..e2f00fd8cd47 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h | |||
@@ -523,6 +523,7 @@ struct usb_gadget_ops { | |||
523 | * enabled HNP support. | 523 | * enabled HNP support. |
524 | * @quirk_ep_out_aligned_size: epout requires buffer size to be aligned to | 524 | * @quirk_ep_out_aligned_size: epout requires buffer size to be aligned to |
525 | * MaxPacketSize. | 525 | * MaxPacketSize. |
526 | * @is_selfpowered: if the gadget is self-powered. | ||
526 | * | 527 | * |
527 | * Gadgets have a mostly-portable "gadget driver" implementing device | 528 | * Gadgets have a mostly-portable "gadget driver" implementing device |
528 | * functions, handling all usb configurations and interfaces. Gadget | 529 | * functions, handling all usb configurations and interfaces. Gadget |
@@ -563,6 +564,7 @@ struct usb_gadget { | |||
563 | unsigned a_hnp_support:1; | 564 | unsigned a_hnp_support:1; |
564 | unsigned a_alt_hnp_support:1; | 565 | unsigned a_alt_hnp_support:1; |
565 | unsigned quirk_ep_out_aligned_size:1; | 566 | unsigned quirk_ep_out_aligned_size:1; |
567 | unsigned is_selfpowered:1; | ||
566 | }; | 568 | }; |
567 | #define work_to_gadget(w) (container_of((w), struct usb_gadget, work)) | 569 | #define work_to_gadget(w) (container_of((w), struct usb_gadget, work)) |
568 | 570 | ||
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 086bf13307e6..68b1e836dff1 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h | |||
@@ -146,6 +146,8 @@ struct usb_hcd { | |||
146 | unsigned amd_resume_bug:1; /* AMD remote wakeup quirk */ | 146 | unsigned amd_resume_bug:1; /* AMD remote wakeup quirk */ |
147 | unsigned can_do_streams:1; /* HC supports streams */ | 147 | unsigned can_do_streams:1; /* HC supports streams */ |
148 | unsigned tpl_support:1; /* OTG & EH TPL support */ | 148 | unsigned tpl_support:1; /* OTG & EH TPL support */ |
149 | unsigned cant_recv_wakeups:1; | ||
150 | /* wakeup requests from downstream aren't received */ | ||
149 | 151 | ||
150 | unsigned int irq; /* irq allocated */ | 152 | unsigned int irq; /* irq allocated */ |
151 | void __iomem *regs; /* device memory/io */ | 153 | void __iomem *regs; /* device memory/io */ |
@@ -453,6 +455,7 @@ extern const struct dev_pm_ops usb_hcd_pci_pm_ops; | |||
453 | #endif /* CONFIG_PCI */ | 455 | #endif /* CONFIG_PCI */ |
454 | 456 | ||
455 | /* pci-ish (pdev null is ok) buffer alloc/mapping support */ | 457 | /* pci-ish (pdev null is ok) buffer alloc/mapping support */ |
458 | void usb_init_pool_max(void); | ||
456 | int hcd_buffer_create(struct usb_hcd *hcd); | 459 | int hcd_buffer_create(struct usb_hcd *hcd); |
457 | void hcd_buffer_destroy(struct usb_hcd *hcd); | 460 | void hcd_buffer_destroy(struct usb_hcd *hcd); |
458 | 461 | ||
diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h index f499c23e6342..bc91b5d380fd 100644 --- a/include/linux/usb/phy.h +++ b/include/linux/usb/phy.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* USB OTG (On The Go) defines */ | ||
2 | /* | 1 | /* |
2 | * USB PHY defines | ||
3 | * | 3 | * |
4 | * These APIs may be used between USB controllers. USB device drivers | 4 | * These APIs may be used between USB controllers. USB device drivers |
5 | * (for either host or peripheral roles) don't use these calls; they | 5 | * (for either host or peripheral roles) don't use these calls; they |
@@ -106,7 +106,7 @@ struct usb_phy { | |||
106 | int (*set_power)(struct usb_phy *x, | 106 | int (*set_power)(struct usb_phy *x, |
107 | unsigned mA); | 107 | unsigned mA); |
108 | 108 | ||
109 | /* for non-OTG B devices: set transceiver into suspend mode */ | 109 | /* Set transceiver into suspend mode */ |
110 | int (*set_suspend)(struct usb_phy *x, | 110 | int (*set_suspend)(struct usb_phy *x, |
111 | int suspend); | 111 | int suspend); |
112 | 112 | ||
diff --git a/include/linux/usb/usb_phy_generic.h b/include/linux/usb/usb_phy_generic.h index 68adae83affc..c13632d5292e 100644 --- a/include/linux/usb/usb_phy_generic.h +++ b/include/linux/usb/usb_phy_generic.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define __LINUX_USB_NOP_XCEIV_H | 2 | #define __LINUX_USB_NOP_XCEIV_H |
3 | 3 | ||
4 | #include <linux/usb/otg.h> | 4 | #include <linux/usb/otg.h> |
5 | #include <linux/gpio/consumer.h> | ||
5 | 6 | ||
6 | struct usb_phy_generic_platform_data { | 7 | struct usb_phy_generic_platform_data { |
7 | enum usb_phy_type type; | 8 | enum usb_phy_type type; |
@@ -11,6 +12,7 @@ struct usb_phy_generic_platform_data { | |||
11 | unsigned int needs_vcc:1; | 12 | unsigned int needs_vcc:1; |
12 | unsigned int needs_reset:1; /* deprecated */ | 13 | unsigned int needs_reset:1; /* deprecated */ |
13 | int gpio_reset; | 14 | int gpio_reset; |
15 | struct gpio_desc *gpiod_vbus; | ||
14 | }; | 16 | }; |
15 | 17 | ||
16 | #if IS_ENABLED(CONFIG_NOP_USB_XCEIV) | 18 | #if IS_ENABLED(CONFIG_NOP_USB_XCEIV) |
diff --git a/include/uapi/linux/usb/functionfs.h b/include/uapi/linux/usb/functionfs.h index 295ba299e7bd..108dd7997014 100644 --- a/include/uapi/linux/usb/functionfs.h +++ b/include/uapi/linux/usb/functionfs.h | |||
@@ -20,6 +20,7 @@ enum functionfs_flags { | |||
20 | FUNCTIONFS_HAS_SS_DESC = 4, | 20 | FUNCTIONFS_HAS_SS_DESC = 4, |
21 | FUNCTIONFS_HAS_MS_OS_DESC = 8, | 21 | FUNCTIONFS_HAS_MS_OS_DESC = 8, |
22 | FUNCTIONFS_VIRTUAL_ADDR = 16, | 22 | FUNCTIONFS_VIRTUAL_ADDR = 16, |
23 | FUNCTIONFS_EVENTFD = 32, | ||
23 | }; | 24 | }; |
24 | 25 | ||
25 | /* Descriptor of an non-audio endpoint */ | 26 | /* Descriptor of an non-audio endpoint */ |
diff --git a/include/uapi/linux/usbdevice_fs.h b/include/uapi/linux/usbdevice_fs.h index abe5f4bd4d82..019ba1e0799a 100644 --- a/include/uapi/linux/usbdevice_fs.h +++ b/include/uapi/linux/usbdevice_fs.h | |||
@@ -128,11 +128,12 @@ struct usbdevfs_hub_portinfo { | |||
128 | char port [127]; /* e.g. port 3 connects to device 27 */ | 128 | char port [127]; /* e.g. port 3 connects to device 27 */ |
129 | }; | 129 | }; |
130 | 130 | ||
131 | /* Device capability flags */ | 131 | /* System and bus capability flags */ |
132 | #define USBDEVFS_CAP_ZERO_PACKET 0x01 | 132 | #define USBDEVFS_CAP_ZERO_PACKET 0x01 |
133 | #define USBDEVFS_CAP_BULK_CONTINUATION 0x02 | 133 | #define USBDEVFS_CAP_BULK_CONTINUATION 0x02 |
134 | #define USBDEVFS_CAP_NO_PACKET_SIZE_LIM 0x04 | 134 | #define USBDEVFS_CAP_NO_PACKET_SIZE_LIM 0x04 |
135 | #define USBDEVFS_CAP_BULK_SCATTER_GATHER 0x08 | 135 | #define USBDEVFS_CAP_BULK_SCATTER_GATHER 0x08 |
136 | #define USBDEVFS_CAP_REAP_AFTER_DISCONNECT 0x10 | ||
136 | 137 | ||
137 | /* USBDEVFS_DISCONNECT_CLAIM flags & struct */ | 138 | /* USBDEVFS_DISCONNECT_CLAIM flags & struct */ |
138 | 139 | ||
diff --git a/tools/usb/ffs-aio-example/multibuff/host_app/test.c b/tools/usb/ffs-aio-example/multibuff/host_app/test.c index daa3abe6bebd..2cbcce6e8dd7 100644 --- a/tools/usb/ffs-aio-example/multibuff/host_app/test.c +++ b/tools/usb/ffs-aio-example/multibuff/host_app/test.c | |||
@@ -33,11 +33,6 @@ | |||
33 | #define VENDOR 0x1d6b | 33 | #define VENDOR 0x1d6b |
34 | #define PRODUCT 0x0105 | 34 | #define PRODUCT 0x0105 |
35 | 35 | ||
36 | /* endpoints indexes */ | ||
37 | |||
38 | #define EP_BULK_IN (1 | LIBUSB_ENDPOINT_IN) | ||
39 | #define EP_BULK_OUT (2 | LIBUSB_ENDPOINT_OUT) | ||
40 | |||
41 | #define BUF_LEN 8192 | 36 | #define BUF_LEN 8192 |
42 | 37 | ||
43 | /* | 38 | /* |
@@ -159,14 +154,21 @@ void test_exit(struct test_state *state) | |||
159 | int main(void) | 154 | int main(void) |
160 | { | 155 | { |
161 | struct test_state state; | 156 | struct test_state state; |
157 | struct libusb_config_descriptor *conf; | ||
158 | struct libusb_interface_descriptor const *iface; | ||
159 | unsigned char addr; | ||
162 | 160 | ||
163 | if (test_init(&state)) | 161 | if (test_init(&state)) |
164 | return 1; | 162 | return 1; |
165 | 163 | ||
164 | libusb_get_config_descriptor(state.found, 0, &conf); | ||
165 | iface = &conf->interface[0].altsetting[0]; | ||
166 | addr = iface->endpoint[0].bEndpointAddress; | ||
167 | |||
166 | while (1) { | 168 | while (1) { |
167 | static unsigned char buffer[BUF_LEN]; | 169 | static unsigned char buffer[BUF_LEN]; |
168 | int bytes; | 170 | int bytes; |
169 | libusb_bulk_transfer(state.handle, EP_BULK_IN, buffer, BUF_LEN, | 171 | libusb_bulk_transfer(state.handle, addr, buffer, BUF_LEN, |
170 | &bytes, 500); | 172 | &bytes, 500); |
171 | } | 173 | } |
172 | test_exit(&state); | 174 | test_exit(&state); |
diff --git a/tools/usb/ffs-aio-example/simple/device_app/aio_simple.c b/tools/usb/ffs-aio-example/simple/device_app/aio_simple.c index adc310a6d489..1f44a29818bf 100644 --- a/tools/usb/ffs-aio-example/simple/device_app/aio_simple.c +++ b/tools/usb/ffs-aio-example/simple/device_app/aio_simple.c | |||
@@ -103,12 +103,14 @@ static const struct { | |||
103 | .bDescriptorType = USB_DT_ENDPOINT, | 103 | .bDescriptorType = USB_DT_ENDPOINT, |
104 | .bEndpointAddress = 1 | USB_DIR_IN, | 104 | .bEndpointAddress = 1 | USB_DIR_IN, |
105 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 105 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
106 | .wMaxPacketSize = htole16(512), | ||
106 | }, | 107 | }, |
107 | .bulk_source = { | 108 | .bulk_source = { |
108 | .bLength = sizeof(descriptors.hs_descs.bulk_source), | 109 | .bLength = sizeof(descriptors.hs_descs.bulk_source), |
109 | .bDescriptorType = USB_DT_ENDPOINT, | 110 | .bDescriptorType = USB_DT_ENDPOINT, |
110 | .bEndpointAddress = 2 | USB_DIR_OUT, | 111 | .bEndpointAddress = 2 | USB_DIR_OUT, |
111 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 112 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
113 | .wMaxPacketSize = htole16(512), | ||
112 | }, | 114 | }, |
113 | }, | 115 | }, |
114 | }; | 116 | }; |
diff --git a/tools/usb/ffs-aio-example/simple/host_app/test.c b/tools/usb/ffs-aio-example/simple/host_app/test.c index acd6332811f3..aed86ffff280 100644 --- a/tools/usb/ffs-aio-example/simple/host_app/test.c +++ b/tools/usb/ffs-aio-example/simple/host_app/test.c | |||
@@ -33,11 +33,6 @@ | |||
33 | #define VENDOR 0x1d6b | 33 | #define VENDOR 0x1d6b |
34 | #define PRODUCT 0x0105 | 34 | #define PRODUCT 0x0105 |
35 | 35 | ||
36 | /* endpoints indexes */ | ||
37 | |||
38 | #define EP_BULK_IN (1 | LIBUSB_ENDPOINT_IN) | ||
39 | #define EP_BULK_OUT (2 | LIBUSB_ENDPOINT_OUT) | ||
40 | |||
41 | #define BUF_LEN 8192 | 36 | #define BUF_LEN 8192 |
42 | 37 | ||
43 | /* | 38 | /* |
@@ -159,16 +154,24 @@ void test_exit(struct test_state *state) | |||
159 | int main(void) | 154 | int main(void) |
160 | { | 155 | { |
161 | struct test_state state; | 156 | struct test_state state; |
157 | struct libusb_config_descriptor *conf; | ||
158 | struct libusb_interface_descriptor const *iface; | ||
159 | unsigned char in_addr, out_addr; | ||
162 | 160 | ||
163 | if (test_init(&state)) | 161 | if (test_init(&state)) |
164 | return 1; | 162 | return 1; |
165 | 163 | ||
164 | libusb_get_config_descriptor(state.found, 0, &conf); | ||
165 | iface = &conf->interface[0].altsetting[0]; | ||
166 | in_addr = iface->endpoint[0].bEndpointAddress; | ||
167 | out_addr = iface->endpoint[1].bEndpointAddress; | ||
168 | |||
166 | while (1) { | 169 | while (1) { |
167 | static unsigned char buffer[BUF_LEN]; | 170 | static unsigned char buffer[BUF_LEN]; |
168 | int bytes; | 171 | int bytes; |
169 | libusb_bulk_transfer(state.handle, EP_BULK_IN, buffer, BUF_LEN, | 172 | libusb_bulk_transfer(state.handle, in_addr, buffer, BUF_LEN, |
170 | &bytes, 500); | 173 | &bytes, 500); |
171 | libusb_bulk_transfer(state.handle, EP_BULK_OUT, buffer, BUF_LEN, | 174 | libusb_bulk_transfer(state.handle, out_addr, buffer, BUF_LEN, |
172 | &bytes, 500); | 175 | &bytes, 500); |
173 | } | 176 | } |
174 | test_exit(&state); | 177 | test_exit(&state); |