diff options
72 files changed, 4122 insertions, 787 deletions
diff --git a/Documentation/ABI/testing/configfs-usb-gadget b/Documentation/ABI/testing/configfs-usb-gadget index 37559a06393b..95a36589a66b 100644 --- a/Documentation/ABI/testing/configfs-usb-gadget +++ b/Documentation/ABI/testing/configfs-usb-gadget | |||
@@ -62,6 +62,40 @@ KernelVersion: 3.11 | |||
62 | Description: | 62 | Description: |
63 | This group contains functions available to this USB gadget. | 63 | This group contains functions available to this USB gadget. |
64 | 64 | ||
65 | What: /config/usb-gadget/gadget/functions/<func>.<inst>/interface.<n> | ||
66 | Date: May 2014 | ||
67 | KernelVersion: 3.16 | ||
68 | Description: | ||
69 | This group contains "Feature Descriptors" specific for one | ||
70 | gadget's USB interface or one interface group described | ||
71 | by an IAD. | ||
72 | |||
73 | The attributes: | ||
74 | |||
75 | compatible_id - 8-byte string for "Compatible ID" | ||
76 | sub_compatible_id - 8-byte string for "Sub Compatible ID" | ||
77 | |||
78 | What: /config/usb-gadget/gadget/functions/<func>.<inst>/interface.<n>/<property> | ||
79 | Date: May 2014 | ||
80 | KernelVersion: 3.16 | ||
81 | Description: | ||
82 | This group contains "Extended Property Descriptors" specific for one | ||
83 | gadget's USB interface or one interface group described | ||
84 | by an IAD. | ||
85 | |||
86 | The attributes: | ||
87 | |||
88 | type - value 1..7 for interpreting the data | ||
89 | 1: unicode string | ||
90 | 2: unicode string with environment variable | ||
91 | 3: binary | ||
92 | 4: little-endian 32-bit | ||
93 | 5: big-endian 32-bit | ||
94 | 6: unicode string with a symbolic link | ||
95 | 7: multiple unicode strings | ||
96 | data - blob of data to be interpreted depending on | ||
97 | type | ||
98 | |||
65 | What: /config/usb-gadget/gadget/strings | 99 | What: /config/usb-gadget/gadget/strings |
66 | Date: Jun 2013 | 100 | Date: Jun 2013 |
67 | KernelVersion: 3.11 | 101 | KernelVersion: 3.11 |
@@ -79,3 +113,14 @@ Description: | |||
79 | product - gadget's product description | 113 | product - gadget's product description |
80 | manufacturer - gadget's manufacturer description | 114 | manufacturer - gadget's manufacturer description |
81 | 115 | ||
116 | What: /config/usb-gadget/gadget/os_desc | ||
117 | Date: May 2014 | ||
118 | KernelVersion: 3.16 | ||
119 | Description: | ||
120 | This group contains "OS String" extension handling attributes. | ||
121 | |||
122 | use - flag turning "OS Desctiptors" support on/off | ||
123 | b_vendor_code - one-byte value used for custom per-device and | ||
124 | per-interface requests | ||
125 | qw_sign - an identifier to be reported as "OS String" | ||
126 | proper | ||
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile index b444f2e8fe32..bec06659e0eb 100644 --- a/Documentation/DocBook/Makefile +++ b/Documentation/DocBook/Makefile | |||
@@ -14,7 +14,8 @@ DOCBOOKS := z8530book.xml device-drivers.xml \ | |||
14 | genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \ | 14 | genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \ |
15 | 80211.xml debugobjects.xml sh.xml regulator.xml \ | 15 | 80211.xml debugobjects.xml sh.xml regulator.xml \ |
16 | alsa-driver-api.xml writing-an-alsa-driver.xml \ | 16 | alsa-driver-api.xml writing-an-alsa-driver.xml \ |
17 | tracepoint.xml drm.xml media_api.xml w1.xml | 17 | tracepoint.xml drm.xml media_api.xml w1.xml \ |
18 | writing_musb_glue_layer.xml | ||
18 | 19 | ||
19 | include Documentation/DocBook/media/Makefile | 20 | include Documentation/DocBook/media/Makefile |
20 | 21 | ||
diff --git a/Documentation/DocBook/writing_musb_glue_layer.tmpl b/Documentation/DocBook/writing_musb_glue_layer.tmpl new file mode 100644 index 000000000000..837eca77f274 --- /dev/null +++ b/Documentation/DocBook/writing_musb_glue_layer.tmpl | |||
@@ -0,0 +1,873 @@ | |||
1 | <?xml version="1.0" encoding="UTF-8"?> | ||
2 | <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" | ||
3 | "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []> | ||
4 | |||
5 | <book id="Writing-MUSB-Glue-Layer"> | ||
6 | <bookinfo> | ||
7 | <title>Writing an MUSB Glue Layer</title> | ||
8 | |||
9 | <authorgroup> | ||
10 | <author> | ||
11 | <firstname>Apelete</firstname> | ||
12 | <surname>Seketeli</surname> | ||
13 | <affiliation> | ||
14 | <address> | ||
15 | <email>apelete at seketeli.net</email> | ||
16 | </address> | ||
17 | </affiliation> | ||
18 | </author> | ||
19 | </authorgroup> | ||
20 | |||
21 | <copyright> | ||
22 | <year>2014</year> | ||
23 | <holder>Apelete Seketeli</holder> | ||
24 | </copyright> | ||
25 | |||
26 | <legalnotice> | ||
27 | <para> | ||
28 | This documentation is free software; you can redistribute it | ||
29 | and/or modify it under the terms of the GNU General Public | ||
30 | License as published by the Free Software Foundation; either | ||
31 | version 2 of the License, or (at your option) any later version. | ||
32 | </para> | ||
33 | |||
34 | <para> | ||
35 | This documentation is distributed in the hope that it will be | ||
36 | useful, but WITHOUT ANY WARRANTY; without even the implied | ||
37 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
38 | See the GNU General Public License for more details. | ||
39 | </para> | ||
40 | |||
41 | <para> | ||
42 | You should have received a copy of the GNU General Public License | ||
43 | along with this documentation; if not, write to the Free Software | ||
44 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
45 | 02111-1307 USA | ||
46 | </para> | ||
47 | |||
48 | <para> | ||
49 | For more details see the file COPYING in the Linux kernel source | ||
50 | tree. | ||
51 | </para> | ||
52 | </legalnotice> | ||
53 | </bookinfo> | ||
54 | |||
55 | <toc></toc> | ||
56 | |||
57 | <chapter id="introduction"> | ||
58 | <title>Introduction</title> | ||
59 | <para> | ||
60 | The Linux MUSB subsystem is part of the larger Linux USB | ||
61 | subsystem. It provides support for embedded USB Device Controllers | ||
62 | (UDC) that do not use Universal Host Controller Interface (UHCI) | ||
63 | or Open Host Controller Interface (OHCI). | ||
64 | </para> | ||
65 | <para> | ||
66 | Instead, these embedded UDC rely on the USB On-the-Go (OTG) | ||
67 | specification which they implement at least partially. The silicon | ||
68 | reference design used in most cases is the Multipoint USB | ||
69 | Highspeed Dual-Role Controller (MUSB HDRC) found in the Mentor | ||
70 | Graphics Inventra™ design. | ||
71 | </para> | ||
72 | <para> | ||
73 | As a self-taught exercise I have written an MUSB glue layer for | ||
74 | the Ingenic JZ4740 SoC, modelled after the many MUSB glue layers | ||
75 | in the kernel source tree. This layer can be found at | ||
76 | drivers/usb/musb/jz4740.c. In this documentation I will walk | ||
77 | through the basics of the jz4740.c glue layer, explaining the | ||
78 | different pieces and what needs to be done in order to write your | ||
79 | own device glue layer. | ||
80 | </para> | ||
81 | </chapter> | ||
82 | |||
83 | <chapter id="linux-musb-basics"> | ||
84 | <title>Linux MUSB Basics</title> | ||
85 | <para> | ||
86 | To get started on the topic, please read USB On-the-Go Basics (see | ||
87 | Resources) which provides an introduction of USB OTG operation at | ||
88 | the hardware level. A couple of wiki pages by Texas Instruments | ||
89 | and Analog Devices also provide an overview of the Linux kernel | ||
90 | MUSB configuration, albeit focused on some specific devices | ||
91 | provided by these companies. Finally, getting acquainted with the | ||
92 | USB specification at USB home page may come in handy, with | ||
93 | practical instance provided through the Writing USB Device Drivers | ||
94 | documentation (again, see Resources). | ||
95 | </para> | ||
96 | <para> | ||
97 | Linux USB stack is a layered architecture in which the MUSB | ||
98 | controller hardware sits at the lowest. The MUSB controller driver | ||
99 | abstract the MUSB controller hardware to the Linux USB stack. | ||
100 | </para> | ||
101 | <programlisting> | ||
102 | ------------------------ | ||
103 | | | <------- drivers/usb/gadget | ||
104 | | Linux USB Core Stack | <------- drivers/usb/host | ||
105 | | | <------- drivers/usb/core | ||
106 | ------------------------ | ||
107 | ⬍ | ||
108 | -------------------------- | ||
109 | | | <------ drivers/usb/musb/musb_gadget.c | ||
110 | | MUSB Controller driver | <------ drivers/usb/musb/musb_host.c | ||
111 | | | <------ drivers/usb/musb/musb_core.c | ||
112 | -------------------------- | ||
113 | ⬍ | ||
114 | --------------------------------- | ||
115 | | MUSB Platform Specific Driver | | ||
116 | | | <-- drivers/usb/musb/jz4740.c | ||
117 | | aka "Glue Layer" | | ||
118 | --------------------------------- | ||
119 | ⬍ | ||
120 | --------------------------------- | ||
121 | | MUSB Controller Hardware | | ||
122 | --------------------------------- | ||
123 | </programlisting> | ||
124 | <para> | ||
125 | As outlined above, the glue layer is actually the platform | ||
126 | specific code sitting in between the controller driver and the | ||
127 | controller hardware. | ||
128 | </para> | ||
129 | <para> | ||
130 | Just like a Linux USB driver needs to register itself with the | ||
131 | Linux USB subsystem, the MUSB glue layer needs first to register | ||
132 | itself with the MUSB controller driver. This will allow the | ||
133 | controller driver to know about which device the glue layer | ||
134 | supports and which functions to call when a supported device is | ||
135 | detected or released; remember we are talking about an embedded | ||
136 | controller chip here, so no insertion or removal at run-time. | ||
137 | </para> | ||
138 | <para> | ||
139 | All of this information is passed to the MUSB controller driver | ||
140 | through a platform_driver structure defined in the glue layer as: | ||
141 | </para> | ||
142 | <programlisting linenumbering="numbered"> | ||
143 | static struct platform_driver jz4740_driver = { | ||
144 | .probe = jz4740_probe, | ||
145 | .remove = jz4740_remove, | ||
146 | .driver = { | ||
147 | .name = "musb-jz4740", | ||
148 | }, | ||
149 | }; | ||
150 | </programlisting> | ||
151 | <para> | ||
152 | The probe and remove function pointers are called when a matching | ||
153 | device is detected and, respectively, released. The name string | ||
154 | describes the device supported by this glue layer. In the current | ||
155 | case it matches a platform_device structure declared in | ||
156 | arch/mips/jz4740/platform.c. Note that we are not using device | ||
157 | tree bindings here. | ||
158 | </para> | ||
159 | <para> | ||
160 | In order to register itself to the controller driver, the glue | ||
161 | layer goes through a few steps, basically allocating the | ||
162 | controller hardware resources and initialising a couple of | ||
163 | circuits. To do so, it needs to keep track of the information used | ||
164 | throughout these steps. This is done by defining a private | ||
165 | jz4740_glue structure: | ||
166 | </para> | ||
167 | <programlisting linenumbering="numbered"> | ||
168 | struct jz4740_glue { | ||
169 | struct device *dev; | ||
170 | struct platform_device *musb; | ||
171 | struct clk *clk; | ||
172 | }; | ||
173 | </programlisting> | ||
174 | <para> | ||
175 | The dev and musb members are both device structure variables. The | ||
176 | first one holds generic information about the device, since it's | ||
177 | the basic device structure, and the latter holds information more | ||
178 | closely related to the subsystem the device is registered to. The | ||
179 | clk variable keeps information related to the device clock | ||
180 | operation. | ||
181 | </para> | ||
182 | <para> | ||
183 | Let's go through the steps of the probe function that leads the | ||
184 | glue layer to register itself to the controller driver. | ||
185 | </para> | ||
186 | <para> | ||
187 | N.B.: For the sake of readability each function will be split in | ||
188 | logical parts, each part being shown as if it was independent from | ||
189 | the others. | ||
190 | </para> | ||
191 | <programlisting linenumbering="numbered"> | ||
192 | static int jz4740_probe(struct platform_device *pdev) | ||
193 | { | ||
194 | struct platform_device *musb; | ||
195 | struct jz4740_glue *glue; | ||
196 | struct clk *clk; | ||
197 | int ret; | ||
198 | |||
199 | glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); | ||
200 | if (!glue) | ||
201 | return -ENOMEM; | ||
202 | |||
203 | musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); | ||
204 | if (!musb) { | ||
205 | dev_err(&pdev->dev, "failed to allocate musb device\n"); | ||
206 | return -ENOMEM; | ||
207 | } | ||
208 | |||
209 | clk = devm_clk_get(&pdev->dev, "udc"); | ||
210 | if (IS_ERR(clk)) { | ||
211 | dev_err(&pdev->dev, "failed to get clock\n"); | ||
212 | ret = PTR_ERR(clk); | ||
213 | goto err_platform_device_put; | ||
214 | } | ||
215 | |||
216 | ret = clk_prepare_enable(clk); | ||
217 | if (ret) { | ||
218 | dev_err(&pdev->dev, "failed to enable clock\n"); | ||
219 | goto err_platform_device_put; | ||
220 | } | ||
221 | |||
222 | musb->dev.parent = &pdev->dev; | ||
223 | |||
224 | glue->dev = &pdev->dev; | ||
225 | glue->musb = musb; | ||
226 | glue->clk = clk; | ||
227 | |||
228 | return 0; | ||
229 | |||
230 | err_platform_device_put: | ||
231 | platform_device_put(musb); | ||
232 | return ret; | ||
233 | } | ||
234 | </programlisting> | ||
235 | <para> | ||
236 | The first few lines of the probe function allocate and assign the | ||
237 | glue, musb and clk variables. The GFP_KERNEL flag (line 8) allows | ||
238 | the allocation process to sleep and wait for memory, thus being | ||
239 | usable in a blocking situation. The PLATFORM_DEVID_AUTO flag (line | ||
240 | 12) allows automatic allocation and management of device IDs in | ||
241 | order to avoid device namespace collisions with explicit IDs. With | ||
242 | devm_clk_get() (line 18) the glue layer allocates the clock -- the | ||
243 | <literal>devm_</literal> prefix indicates that clk_get() is | ||
244 | managed: it automatically frees the allocated clock resource data | ||
245 | when the device is released -- and enable it. | ||
246 | </para> | ||
247 | <para> | ||
248 | Then comes the registration steps: | ||
249 | </para> | ||
250 | <programlisting linenumbering="numbered"> | ||
251 | static int jz4740_probe(struct platform_device *pdev) | ||
252 | { | ||
253 | struct musb_hdrc_platform_data *pdata = &jz4740_musb_platform_data; | ||
254 | |||
255 | pdata->platform_ops = &jz4740_musb_ops; | ||
256 | |||
257 | platform_set_drvdata(pdev, glue); | ||
258 | |||
259 | ret = platform_device_add_resources(musb, pdev->resource, | ||
260 | pdev->num_resources); | ||
261 | if (ret) { | ||
262 | dev_err(&pdev->dev, "failed to add resources\n"); | ||
263 | goto err_clk_disable; | ||
264 | } | ||
265 | |||
266 | ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); | ||
267 | if (ret) { | ||
268 | dev_err(&pdev->dev, "failed to add platform_data\n"); | ||
269 | goto err_clk_disable; | ||
270 | } | ||
271 | |||
272 | return 0; | ||
273 | |||
274 | err_clk_disable: | ||
275 | clk_disable_unprepare(clk); | ||
276 | err_platform_device_put: | ||
277 | platform_device_put(musb); | ||
278 | return ret; | ||
279 | } | ||
280 | </programlisting> | ||
281 | <para> | ||
282 | The first step is to pass the device data privately held by the | ||
283 | glue layer on to the controller driver through | ||
284 | platform_set_drvdata() (line 7). Next is passing on the device | ||
285 | resources information, also privately held at that point, through | ||
286 | platform_device_add_resources() (line 9). | ||
287 | </para> | ||
288 | <para> | ||
289 | Finally comes passing on the platform specific data to the | ||
290 | controller driver (line 16). Platform data will be discussed in | ||
291 | <link linkend="device-platform-data">Chapter 4</link>, but here | ||
292 | we are looking at the platform_ops function pointer (line 5) in | ||
293 | musb_hdrc_platform_data structure (line 3). This function | ||
294 | pointer allows the MUSB controller driver to know which function | ||
295 | to call for device operation: | ||
296 | </para> | ||
297 | <programlisting linenumbering="numbered"> | ||
298 | static const struct musb_platform_ops jz4740_musb_ops = { | ||
299 | .init = jz4740_musb_init, | ||
300 | .exit = jz4740_musb_exit, | ||
301 | }; | ||
302 | </programlisting> | ||
303 | <para> | ||
304 | Here we have the minimal case where only init and exit functions | ||
305 | are called by the controller driver when needed. Fact is the | ||
306 | JZ4740 MUSB controller is a basic controller, lacking some | ||
307 | features found in other controllers, otherwise we may also have | ||
308 | pointers to a few other functions like a power management function | ||
309 | or a function to switch between OTG and non-OTG modes, for | ||
310 | instance. | ||
311 | </para> | ||
312 | <para> | ||
313 | At that point of the registration process, the controller driver | ||
314 | actually calls the init function: | ||
315 | </para> | ||
316 | <programlisting linenumbering="numbered"> | ||
317 | static int jz4740_musb_init(struct musb *musb) | ||
318 | { | ||
319 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); | ||
320 | if (!musb->xceiv) { | ||
321 | pr_err("HS UDC: no transceiver configured\n"); | ||
322 | return -ENODEV; | ||
323 | } | ||
324 | |||
325 | /* Silicon does not implement ConfigData register. | ||
326 | * Set dyn_fifo to avoid reading EP config from hardware. | ||
327 | */ | ||
328 | musb->dyn_fifo = true; | ||
329 | |||
330 | musb->isr = jz4740_musb_interrupt; | ||
331 | |||
332 | return 0; | ||
333 | } | ||
334 | </programlisting> | ||
335 | <para> | ||
336 | The goal of jz4740_musb_init() is to get hold of the transceiver | ||
337 | driver data of the MUSB controller hardware and pass it on to the | ||
338 | MUSB controller driver, as usual. The transceiver is the circuitry | ||
339 | inside the controller hardware responsible for sending/receiving | ||
340 | the USB data. Since it is an implementation of the physical layer | ||
341 | of the OSI model, the transceiver is also referred to as PHY. | ||
342 | </para> | ||
343 | <para> | ||
344 | Getting hold of the MUSB PHY driver data is done with | ||
345 | usb_get_phy() which returns a pointer to the structure | ||
346 | containing the driver instance data. The next couple of | ||
347 | instructions (line 12 and 14) are used as a quirk and to setup | ||
348 | IRQ handling respectively. Quirks and IRQ handling will be | ||
349 | discussed later in <link linkend="device-quirks">Chapter | ||
350 | 5</link> and <link linkend="handling-irqs">Chapter 3</link>. | ||
351 | </para> | ||
352 | <programlisting linenumbering="numbered"> | ||
353 | static int jz4740_musb_exit(struct musb *musb) | ||
354 | { | ||
355 | usb_put_phy(musb->xceiv); | ||
356 | |||
357 | return 0; | ||
358 | } | ||
359 | </programlisting> | ||
360 | <para> | ||
361 | Acting as the counterpart of init, the exit function releases the | ||
362 | MUSB PHY driver when the controller hardware itself is about to be | ||
363 | released. | ||
364 | </para> | ||
365 | <para> | ||
366 | Again, note that init and exit are fairly simple in this case due | ||
367 | to the basic set of features of the JZ4740 controller hardware. | ||
368 | When writing an musb glue layer for a more complex controller | ||
369 | hardware, you might need to take care of more processing in those | ||
370 | two functions. | ||
371 | </para> | ||
372 | <para> | ||
373 | Returning from the init function, the MUSB controller driver jumps | ||
374 | back into the probe function: | ||
375 | </para> | ||
376 | <programlisting linenumbering="numbered"> | ||
377 | static int jz4740_probe(struct platform_device *pdev) | ||
378 | { | ||
379 | ret = platform_device_add(musb); | ||
380 | if (ret) { | ||
381 | dev_err(&pdev->dev, "failed to register musb device\n"); | ||
382 | goto err_clk_disable; | ||
383 | } | ||
384 | |||
385 | return 0; | ||
386 | |||
387 | err_clk_disable: | ||
388 | clk_disable_unprepare(clk); | ||
389 | err_platform_device_put: | ||
390 | platform_device_put(musb); | ||
391 | return ret; | ||
392 | } | ||
393 | </programlisting> | ||
394 | <para> | ||
395 | This is the last part of the device registration process where the | ||
396 | glue layer adds the controller hardware device to Linux kernel | ||
397 | device hierarchy: at this stage, all known information about the | ||
398 | device is passed on to the Linux USB core stack. | ||
399 | </para> | ||
400 | <programlisting linenumbering="numbered"> | ||
401 | static int jz4740_remove(struct platform_device *pdev) | ||
402 | { | ||
403 | struct jz4740_glue *glue = platform_get_drvdata(pdev); | ||
404 | |||
405 | platform_device_unregister(glue->musb); | ||
406 | clk_disable_unprepare(glue->clk); | ||
407 | |||
408 | return 0; | ||
409 | } | ||
410 | </programlisting> | ||
411 | <para> | ||
412 | Acting as the counterpart of probe, the remove function unregister | ||
413 | the MUSB controller hardware (line 5) and disable the clock (line | ||
414 | 6), allowing it to be gated. | ||
415 | </para> | ||
416 | </chapter> | ||
417 | |||
418 | <chapter id="handling-irqs"> | ||
419 | <title>Handling IRQs</title> | ||
420 | <para> | ||
421 | Additionally to the MUSB controller hardware basic setup and | ||
422 | registration, the glue layer is also responsible for handling the | ||
423 | IRQs: | ||
424 | </para> | ||
425 | <programlisting linenumbering="numbered"> | ||
426 | static irqreturn_t jz4740_musb_interrupt(int irq, void *__hci) | ||
427 | { | ||
428 | unsigned long flags; | ||
429 | irqreturn_t retval = IRQ_NONE; | ||
430 | struct musb *musb = __hci; | ||
431 | |||
432 | spin_lock_irqsave(&musb->lock, flags); | ||
433 | |||
434 | musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB); | ||
435 | musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX); | ||
436 | musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX); | ||
437 | |||
438 | /* | ||
439 | * The controller is gadget only, the state of the host mode IRQ bits is | ||
440 | * undefined. Mask them to make sure that the musb driver core will | ||
441 | * never see them set | ||
442 | */ | ||
443 | musb->int_usb &= MUSB_INTR_SUSPEND | MUSB_INTR_RESUME | | ||
444 | MUSB_INTR_RESET | MUSB_INTR_SOF; | ||
445 | |||
446 | if (musb->int_usb || musb->int_tx || musb->int_rx) | ||
447 | retval = musb_interrupt(musb); | ||
448 | |||
449 | spin_unlock_irqrestore(&musb->lock, flags); | ||
450 | |||
451 | return retval; | ||
452 | } | ||
453 | </programlisting> | ||
454 | <para> | ||
455 | Here the glue layer mostly has to read the relevant hardware | ||
456 | registers and pass their values on to the controller driver which | ||
457 | will handle the actual event that triggered the IRQ. | ||
458 | </para> | ||
459 | <para> | ||
460 | The interrupt handler critical section is protected by the | ||
461 | spin_lock_irqsave() and counterpart spin_unlock_irqrestore() | ||
462 | functions (line 7 and 24 respectively), which prevent the | ||
463 | interrupt handler code to be run by two different threads at the | ||
464 | same time. | ||
465 | </para> | ||
466 | <para> | ||
467 | Then the relevant interrupt registers are read (line 9 to 11): | ||
468 | </para> | ||
469 | <itemizedlist> | ||
470 | <listitem> | ||
471 | <para> | ||
472 | MUSB_INTRUSB: indicates which USB interrupts are currently | ||
473 | active, | ||
474 | </para> | ||
475 | </listitem> | ||
476 | <listitem> | ||
477 | <para> | ||
478 | MUSB_INTRTX: indicates which of the interrupts for TX | ||
479 | endpoints are currently active, | ||
480 | </para> | ||
481 | </listitem> | ||
482 | <listitem> | ||
483 | <para> | ||
484 | MUSB_INTRRX: indicates which of the interrupts for TX | ||
485 | endpoints are currently active. | ||
486 | </para> | ||
487 | </listitem> | ||
488 | </itemizedlist> | ||
489 | <para> | ||
490 | Note that musb_readb() is used to read 8-bit registers at most, | ||
491 | while musb_readw() allows us to read at most 16-bit registers. | ||
492 | There are other functions that can be used depending on the size | ||
493 | of your device registers. See musb_io.h for more information. | ||
494 | </para> | ||
495 | <para> | ||
496 | Instruction on line 18 is another quirk specific to the JZ4740 | ||
497 | USB device controller, which will be discussed later in <link | ||
498 | linkend="device-quirks">Chapter 5</link>. | ||
499 | </para> | ||
500 | <para> | ||
501 | The glue layer still needs to register the IRQ handler though. | ||
502 | Remember the instruction on line 14 of the init function: | ||
503 | </para> | ||
504 | <programlisting linenumbering="numbered"> | ||
505 | static int jz4740_musb_init(struct musb *musb) | ||
506 | { | ||
507 | musb->isr = jz4740_musb_interrupt; | ||
508 | |||
509 | return 0; | ||
510 | } | ||
511 | </programlisting> | ||
512 | <para> | ||
513 | This instruction sets a pointer to the glue layer IRQ handler | ||
514 | function, in order for the controller hardware to call the handler | ||
515 | back when an IRQ comes from the controller hardware. The interrupt | ||
516 | handler is now implemented and registered. | ||
517 | </para> | ||
518 | </chapter> | ||
519 | |||
520 | <chapter id="device-platform-data"> | ||
521 | <title>Device Platform Data</title> | ||
522 | <para> | ||
523 | In order to write an MUSB glue layer, you need to have some data | ||
524 | describing the hardware capabilities of your controller hardware, | ||
525 | which is called the platform data. | ||
526 | </para> | ||
527 | <para> | ||
528 | Platform data is specific to your hardware, though it may cover a | ||
529 | broad range of devices, and is generally found somewhere in the | ||
530 | arch/ directory, depending on your device architecture. | ||
531 | </para> | ||
532 | <para> | ||
533 | For instance, platform data for the JZ4740 SoC is found in | ||
534 | arch/mips/jz4740/platform.c. In the platform.c file each device of | ||
535 | the JZ4740 SoC is described through a set of structures. | ||
536 | </para> | ||
537 | <para> | ||
538 | Here is the part of arch/mips/jz4740/platform.c that covers the | ||
539 | USB Device Controller (UDC): | ||
540 | </para> | ||
541 | <programlisting linenumbering="numbered"> | ||
542 | /* USB Device Controller */ | ||
543 | struct platform_device jz4740_udc_xceiv_device = { | ||
544 | .name = "usb_phy_gen_xceiv", | ||
545 | .id = 0, | ||
546 | }; | ||
547 | |||
548 | static struct resource jz4740_udc_resources[] = { | ||
549 | [0] = { | ||
550 | .start = JZ4740_UDC_BASE_ADDR, | ||
551 | .end = JZ4740_UDC_BASE_ADDR + 0x10000 - 1, | ||
552 | .flags = IORESOURCE_MEM, | ||
553 | }, | ||
554 | [1] = { | ||
555 | .start = JZ4740_IRQ_UDC, | ||
556 | .end = JZ4740_IRQ_UDC, | ||
557 | .flags = IORESOURCE_IRQ, | ||
558 | .name = "mc", | ||
559 | }, | ||
560 | }; | ||
561 | |||
562 | struct platform_device jz4740_udc_device = { | ||
563 | .name = "musb-jz4740", | ||
564 | .id = -1, | ||
565 | .dev = { | ||
566 | .dma_mask = &jz4740_udc_device.dev.coherent_dma_mask, | ||
567 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
568 | }, | ||
569 | .num_resources = ARRAY_SIZE(jz4740_udc_resources), | ||
570 | .resource = jz4740_udc_resources, | ||
571 | }; | ||
572 | </programlisting> | ||
573 | <para> | ||
574 | The jz4740_udc_xceiv_device platform device structure (line 2) | ||
575 | describes the UDC transceiver with a name and id number. | ||
576 | </para> | ||
577 | <para> | ||
578 | At the time of this writing, note that | ||
579 | "usb_phy_gen_xceiv" is the specific name to be used for | ||
580 | all transceivers that are either built-in with reference USB IP or | ||
581 | autonomous and doesn't require any PHY programming. You will need | ||
582 | to set CONFIG_NOP_USB_XCEIV=y in the kernel configuration to make | ||
583 | use of the corresponding transceiver driver. The id field could be | ||
584 | set to -1 (equivalent to PLATFORM_DEVID_NONE), -2 (equivalent to | ||
585 | PLATFORM_DEVID_AUTO) or start with 0 for the first device of this | ||
586 | kind if we want a specific id number. | ||
587 | </para> | ||
588 | <para> | ||
589 | The jz4740_udc_resources resource structure (line 7) defines the | ||
590 | UDC registers base addresses. | ||
591 | </para> | ||
592 | <para> | ||
593 | The first array (line 9 to 11) defines the UDC registers base | ||
594 | memory addresses: start points to the first register memory | ||
595 | address, end points to the last register memory address and the | ||
596 | flags member defines the type of resource we are dealing with. So | ||
597 | IORESOURCE_MEM is used to define the registers memory addresses. | ||
598 | The second array (line 14 to 17) defines the UDC IRQ registers | ||
599 | addresses. Since there is only one IRQ register available for the | ||
600 | JZ4740 UDC, start and end point at the same address. The | ||
601 | IORESOURCE_IRQ flag tells that we are dealing with IRQ resources, | ||
602 | and the name "mc" is in fact hard-coded in the MUSB core | ||
603 | in order for the controller driver to retrieve this IRQ resource | ||
604 | by querying it by its name. | ||
605 | </para> | ||
606 | <para> | ||
607 | Finally, the jz4740_udc_device platform device structure (line 21) | ||
608 | describes the UDC itself. | ||
609 | </para> | ||
610 | <para> | ||
611 | The "musb-jz4740" name (line 22) defines the MUSB | ||
612 | driver that is used for this device; remember this is in fact | ||
613 | the name that we used in the jz4740_driver platform driver | ||
614 | structure in <link linkend="linux-musb-basics">Chapter | ||
615 | 2</link>. The id field (line 23) is set to -1 (equivalent to | ||
616 | PLATFORM_DEVID_NONE) since we do not need an id for the device: | ||
617 | the MUSB controller driver was already set to allocate an | ||
618 | automatic id in <link linkend="linux-musb-basics">Chapter | ||
619 | 2</link>. In the dev field we care for DMA related information | ||
620 | here. The dma_mask field (line 25) defines the width of the DMA | ||
621 | mask that is going to be used, and coherent_dma_mask (line 26) | ||
622 | has the same purpose but for the alloc_coherent DMA mappings: in | ||
623 | both cases we are using a 32 bits mask. Then the resource field | ||
624 | (line 29) is simply a pointer to the resource structure defined | ||
625 | before, while the num_resources field (line 28) keeps track of | ||
626 | the number of arrays defined in the resource structure (in this | ||
627 | case there were two resource arrays defined before). | ||
628 | </para> | ||
629 | <para> | ||
630 | With this quick overview of the UDC platform data at the arch/ | ||
631 | level now done, let's get back to the MUSB glue layer specific | ||
632 | platform data in drivers/usb/musb/jz4740.c: | ||
633 | </para> | ||
634 | <programlisting linenumbering="numbered"> | ||
635 | static struct musb_hdrc_config jz4740_musb_config = { | ||
636 | /* Silicon does not implement USB OTG. */ | ||
637 | .multipoint = 0, | ||
638 | /* Max EPs scanned, driver will decide which EP can be used. */ | ||
639 | .num_eps = 4, | ||
640 | /* RAMbits needed to configure EPs from table */ | ||
641 | .ram_bits = 9, | ||
642 | .fifo_cfg = jz4740_musb_fifo_cfg, | ||
643 | .fifo_cfg_size = ARRAY_SIZE(jz4740_musb_fifo_cfg), | ||
644 | }; | ||
645 | |||
646 | static struct musb_hdrc_platform_data jz4740_musb_platform_data = { | ||
647 | .mode = MUSB_PERIPHERAL, | ||
648 | .config = &jz4740_musb_config, | ||
649 | }; | ||
650 | </programlisting> | ||
651 | <para> | ||
652 | First the glue layer configures some aspects of the controller | ||
653 | driver operation related to the controller hardware specifics. | ||
654 | This is done through the jz4740_musb_config musb_hdrc_config | ||
655 | structure. | ||
656 | </para> | ||
657 | <para> | ||
658 | Defining the OTG capability of the controller hardware, the | ||
659 | multipoint member (line 3) is set to 0 (equivalent to false) | ||
660 | since the JZ4740 UDC is not OTG compatible. Then num_eps (line | ||
661 | 5) defines the number of USB endpoints of the controller | ||
662 | hardware, including endpoint 0: here we have 3 endpoints + | ||
663 | endpoint 0. Next is ram_bits (line 7) which is the width of the | ||
664 | RAM address bus for the MUSB controller hardware. This | ||
665 | information is needed when the controller driver cannot | ||
666 | automatically configure endpoints by reading the relevant | ||
667 | controller hardware registers. This issue will be discussed when | ||
668 | we get to device quirks in <link linkend="device-quirks">Chapter | ||
669 | 5</link>. Last two fields (line 8 and 9) are also about device | ||
670 | quirks: fifo_cfg points to the USB endpoints configuration table | ||
671 | and fifo_cfg_size keeps track of the size of the number of | ||
672 | entries in that configuration table. More on that later in <link | ||
673 | linkend="device-quirks">Chapter 5</link>. | ||
674 | </para> | ||
675 | <para> | ||
676 | Then this configuration is embedded inside | ||
677 | jz4740_musb_platform_data musb_hdrc_platform_data structure (line | ||
678 | 11): config is a pointer to the configuration structure itself, | ||
679 | and mode tells the controller driver if the controller hardware | ||
680 | may be used as MUSB_HOST only, MUSB_PERIPHERAL only or MUSB_OTG | ||
681 | which is a dual mode. | ||
682 | </para> | ||
683 | <para> | ||
684 | Remember that jz4740_musb_platform_data is then used to convey | ||
685 | platform data information as we have seen in the probe function | ||
686 | in <link linkend="linux-musb-basics">Chapter 2</link> | ||
687 | </para> | ||
688 | </chapter> | ||
689 | |||
690 | <chapter id="device-quirks"> | ||
691 | <title>Device Quirks</title> | ||
692 | <para> | ||
693 | Completing the platform data specific to your device, you may also | ||
694 | need to write some code in the glue layer to work around some | ||
695 | device specific limitations. These quirks may be due to some | ||
696 | hardware bugs, or simply be the result of an incomplete | ||
697 | implementation of the USB On-the-Go specification. | ||
698 | </para> | ||
699 | <para> | ||
700 | The JZ4740 UDC exhibits such quirks, some of which we will discuss | ||
701 | here for the sake of insight even though these might not be found | ||
702 | in the controller hardware you are working on. | ||
703 | </para> | ||
704 | <para> | ||
705 | Let's get back to the init function first: | ||
706 | </para> | ||
707 | <programlisting linenumbering="numbered"> | ||
708 | static int jz4740_musb_init(struct musb *musb) | ||
709 | { | ||
710 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); | ||
711 | if (!musb->xceiv) { | ||
712 | pr_err("HS UDC: no transceiver configured\n"); | ||
713 | return -ENODEV; | ||
714 | } | ||
715 | |||
716 | /* Silicon does not implement ConfigData register. | ||
717 | * Set dyn_fifo to avoid reading EP config from hardware. | ||
718 | */ | ||
719 | musb->dyn_fifo = true; | ||
720 | |||
721 | musb->isr = jz4740_musb_interrupt; | ||
722 | |||
723 | return 0; | ||
724 | } | ||
725 | </programlisting> | ||
726 | <para> | ||
727 | Instruction on line 12 helps the MUSB controller driver to work | ||
728 | around the fact that the controller hardware is missing registers | ||
729 | that are used for USB endpoints configuration. | ||
730 | </para> | ||
731 | <para> | ||
732 | Without these registers, the controller driver is unable to read | ||
733 | the endpoints configuration from the hardware, so we use line 12 | ||
734 | instruction to bypass reading the configuration from silicon, and | ||
735 | rely on a hard-coded table that describes the endpoints | ||
736 | configuration instead: | ||
737 | </para> | ||
738 | <programlisting linenumbering="numbered"> | ||
739 | static struct musb_fifo_cfg jz4740_musb_fifo_cfg[] = { | ||
740 | { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, }, | ||
741 | { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, }, | ||
742 | { .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 64, }, | ||
743 | }; | ||
744 | </programlisting> | ||
745 | <para> | ||
746 | Looking at the configuration table above, we see that each | ||
747 | endpoints is described by three fields: hw_ep_num is the endpoint | ||
748 | number, style is its direction (either FIFO_TX for the controller | ||
749 | driver to send packets in the controller hardware, or FIFO_RX to | ||
750 | receive packets from hardware), and maxpacket defines the maximum | ||
751 | size of each data packet that can be transmitted over that | ||
752 | endpoint. Reading from the table, the controller driver knows that | ||
753 | endpoint 1 can be used to send and receive USB data packets of 512 | ||
754 | bytes at once (this is in fact a bulk in/out endpoint), and | ||
755 | endpoint 2 can be used to send data packets of 64 bytes at once | ||
756 | (this is in fact an interrupt endpoint). | ||
757 | </para> | ||
758 | <para> | ||
759 | Note that there is no information about endpoint 0 here: that one | ||
760 | is implemented by default in every silicon design, with a | ||
761 | predefined configuration according to the USB specification. For | ||
762 | more examples of endpoint configuration tables, see musb_core.c. | ||
763 | </para> | ||
764 | <para> | ||
765 | Let's now get back to the interrupt handler function: | ||
766 | </para> | ||
767 | <programlisting linenumbering="numbered"> | ||
768 | static irqreturn_t jz4740_musb_interrupt(int irq, void *__hci) | ||
769 | { | ||
770 | unsigned long flags; | ||
771 | irqreturn_t retval = IRQ_NONE; | ||
772 | struct musb *musb = __hci; | ||
773 | |||
774 | spin_lock_irqsave(&musb->lock, flags); | ||
775 | |||
776 | musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB); | ||
777 | musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX); | ||
778 | musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX); | ||
779 | |||
780 | /* | ||
781 | * The controller is gadget only, the state of the host mode IRQ bits is | ||
782 | * undefined. Mask them to make sure that the musb driver core will | ||
783 | * never see them set | ||
784 | */ | ||
785 | musb->int_usb &= MUSB_INTR_SUSPEND | MUSB_INTR_RESUME | | ||
786 | MUSB_INTR_RESET | MUSB_INTR_SOF; | ||
787 | |||
788 | if (musb->int_usb || musb->int_tx || musb->int_rx) | ||
789 | retval = musb_interrupt(musb); | ||
790 | |||
791 | spin_unlock_irqrestore(&musb->lock, flags); | ||
792 | |||
793 | return retval; | ||
794 | } | ||
795 | </programlisting> | ||
796 | <para> | ||
797 | Instruction on line 18 above is a way for the controller driver to | ||
798 | work around the fact that some interrupt bits used for USB host | ||
799 | mode operation are missing in the MUSB_INTRUSB register, thus left | ||
800 | in an undefined hardware state, since this MUSB controller | ||
801 | hardware is used in peripheral mode only. As a consequence, the | ||
802 | glue layer masks these missing bits out to avoid parasite | ||
803 | interrupts by doing a logical AND operation between the value read | ||
804 | from MUSB_INTRUSB and the bits that are actually implemented in | ||
805 | the register. | ||
806 | </para> | ||
807 | <para> | ||
808 | These are only a couple of the quirks found in the JZ4740 USB | ||
809 | device controller. Some others were directly addressed in the MUSB | ||
810 | core since the fixes were generic enough to provide a better | ||
811 | handling of the issues for others controller hardware eventually. | ||
812 | </para> | ||
813 | </chapter> | ||
814 | |||
815 | <chapter id="conclusion"> | ||
816 | <title>Conclusion</title> | ||
817 | <para> | ||
818 | Writing a Linux MUSB glue layer should be a more accessible task, | ||
819 | as this documentation tries to show the ins and outs of this | ||
820 | exercise. | ||
821 | </para> | ||
822 | <para> | ||
823 | The JZ4740 USB device controller being fairly simple, I hope its | ||
824 | glue layer serves as a good example for the curious mind. Used | ||
825 | with the current MUSB glue layers, this documentation should | ||
826 | provide enough guidance to get started; should anything gets out | ||
827 | of hand, the linux-usb mailing list archive is another helpful | ||
828 | resource to browse through. | ||
829 | </para> | ||
830 | </chapter> | ||
831 | |||
832 | <chapter id="acknowledgements"> | ||
833 | <title>Acknowledgements</title> | ||
834 | <para> | ||
835 | Many thanks to Lars-Peter Clausen and Maarten ter Huurne for | ||
836 | answering my questions while I was writing the JZ4740 glue layer | ||
837 | and for helping me out getting the code in good shape. | ||
838 | </para> | ||
839 | <para> | ||
840 | I would also like to thank the Qi-Hardware community at large for | ||
841 | its cheerful guidance and support. | ||
842 | </para> | ||
843 | </chapter> | ||
844 | |||
845 | <chapter id="resources"> | ||
846 | <title>Resources</title> | ||
847 | <para> | ||
848 | USB Home Page: | ||
849 | <ulink url="http://www.usb.org">http://www.usb.org</ulink> | ||
850 | </para> | ||
851 | <para> | ||
852 | linux-usb Mailing List Archives: | ||
853 | <ulink url="http://marc.info/?l=linux-usb">http://marc.info/?l=linux-usb</ulink> | ||
854 | </para> | ||
855 | <para> | ||
856 | USB On-the-Go Basics: | ||
857 | <ulink url="http://www.maximintegrated.com/app-notes/index.mvp/id/1822">http://www.maximintegrated.com/app-notes/index.mvp/id/1822</ulink> | ||
858 | </para> | ||
859 | <para> | ||
860 | Writing USB Device Drivers: | ||
861 | <ulink url="https://www.kernel.org/doc/htmldocs/writing_usb_driver/index.html">https://www.kernel.org/doc/htmldocs/writing_usb_driver/index.html</ulink> | ||
862 | </para> | ||
863 | <para> | ||
864 | Texas Instruments USB Configuration Wiki Page: | ||
865 | <ulink url="http://processors.wiki.ti.com/index.php/Usbgeneralpage">http://processors.wiki.ti.com/index.php/Usbgeneralpage</ulink> | ||
866 | </para> | ||
867 | <para> | ||
868 | Analog Devices Blackfin MUSB Configuration: | ||
869 | <ulink url="http://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:drivers:musb">http://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:drivers:musb</ulink> | ||
870 | </para> | ||
871 | </chapter> | ||
872 | |||
873 | </book> | ||
diff --git a/Documentation/devicetree/bindings/usb/gr-udc.txt b/Documentation/devicetree/bindings/usb/gr-udc.txt index 0c5118f7a916..e9445224fabd 100644 --- a/Documentation/devicetree/bindings/usb/gr-udc.txt +++ b/Documentation/devicetree/bindings/usb/gr-udc.txt | |||
@@ -12,17 +12,23 @@ Required properties: | |||
12 | 12 | ||
13 | - reg : Address and length of the register set for the device | 13 | - reg : Address and length of the register set for the device |
14 | 14 | ||
15 | - interrupts : Interrupt numbers for this device | 15 | - interrupts : Interrupt numbers for this device. Either one interrupt number |
16 | for all interrupts, or one for status related interrupts, one for IN | ||
17 | endpoint related interrupts and one for OUT endpoint related interrupts. | ||
16 | 18 | ||
17 | Optional properties: | 19 | Optional properties: |
18 | 20 | ||
19 | - epobufsizes : An array of buffer sizes for OUT endpoints. If the property is | 21 | - epobufsizes : Array of buffer sizes for OUT endpoints when they differ |
20 | not present, or for endpoints outside of the array, 1024 is assumed by | 22 | from the default size of 1024. The array is indexed by the OUT endpoint |
21 | the driver. | 23 | number. If the property is present it typically contains one entry for |
22 | 24 | each OUT endpoint of the core. Fewer entries overrides the default sizes | |
23 | - epibufsizes : An array of buffer sizes for IN endpoints. If the property is | 25 | only for as many endpoints as the array contains. |
24 | not present, or for endpoints outside of the array, 1024 is assumed by | 26 | |
25 | the driver. | 27 | - epibufsizes : Array of buffer sizes for IN endpoints when they differ |
28 | from the default size of 1024. The array is indexed by the IN endpoint | ||
29 | number. If the property is present it typically contains one entry for | ||
30 | each IN endpoint of the core. Fewer entries overrides the default sizes | ||
31 | only for as many endpoints as the array contains. | ||
26 | 32 | ||
27 | For further information look in the documentation for the GLIB IP core library: | 33 | For further information look in the documentation for the GLIB IP core library: |
28 | http://www.gaisler.com/products/grlib/grip.pdf | 34 | http://www.gaisler.com/products/grlib/grip.pdf |
diff --git a/Documentation/devicetree/bindings/usb/msm-hsusb.txt b/Documentation/devicetree/bindings/usb/msm-hsusb.txt index 5ea26c631e3a..2826f2af503a 100644 --- a/Documentation/devicetree/bindings/usb/msm-hsusb.txt +++ b/Documentation/devicetree/bindings/usb/msm-hsusb.txt | |||
@@ -15,3 +15,81 @@ Example EHCI controller device node: | |||
15 | usb-phy = <&usb_otg>; | 15 | usb-phy = <&usb_otg>; |
16 | }; | 16 | }; |
17 | 17 | ||
18 | USB PHY with optional OTG: | ||
19 | |||
20 | Required properties: | ||
21 | - compatible: Should contain: | ||
22 | "qcom,usb-otg-ci" for chipsets with ChipIdea 45nm PHY | ||
23 | "qcom,usb-otg-snps" for chipsets with Synopsys 28nm PHY | ||
24 | |||
25 | - regs: Offset and length of the register set in the memory map | ||
26 | - interrupts: interrupt-specifier for the OTG interrupt. | ||
27 | |||
28 | - clocks: A list of phandle + clock-specifier pairs for the | ||
29 | clocks listed in clock-names | ||
30 | - clock-names: Should contain the following: | ||
31 | "phy" USB PHY reference clock | ||
32 | "core" Protocol engine clock | ||
33 | "iface" Interface bus clock | ||
34 | "alt_core" Protocol engine clock for targets with asynchronous | ||
35 | reset methodology. (optional) | ||
36 | |||
37 | - vdccx-supply: phandle to the regulator for the vdd supply for | ||
38 | digital circuit operation. | ||
39 | - v1p8-supply: phandle to the regulator for the 1.8V supply | ||
40 | - v3p3-supply: phandle to the regulator for the 3.3V supply | ||
41 | |||
42 | - resets: A list of phandle + reset-specifier pairs for the | ||
43 | resets listed in reset-names | ||
44 | - reset-names: Should contain the following: | ||
45 | "phy" USB PHY controller reset | ||
46 | "link" USB LINK controller reset | ||
47 | |||
48 | - qcom,otg-control: OTG control (VBUS and ID notifications) can be one of | ||
49 | 1 - PHY control | ||
50 | 2 - PMIC control | ||
51 | |||
52 | Optional properties: | ||
53 | - dr_mode: One of "host", "peripheral" or "otg". Defaults to "otg" | ||
54 | |||
55 | - qcom,phy-init-sequence: PHY configuration sequence values. This is related to Device | ||
56 | Mode Eye Diagram test. Start address at which these values will be | ||
57 | written is ULPI_EXT_VENDOR_SPECIFIC. Value of -1 is reserved as | ||
58 | "do not overwrite default value at this address". | ||
59 | For example: qcom,phy-init-sequence = < -1 0x63 >; | ||
60 | Will update only value at address ULPI_EXT_VENDOR_SPECIFIC + 1. | ||
61 | |||
62 | - qcom,phy-num: Select number of pyco-phy to use, can be one of | ||
63 | 0 - PHY one, default | ||
64 | 1 - Second PHY | ||
65 | Some platforms may have configuration to allow USB | ||
66 | controller work with any of the two HSPHYs present. | ||
67 | |||
68 | - qcom,vdd-levels: This property must be a list of three integer values | ||
69 | (no, min, max) where each value represents either a voltage | ||
70 | in microvolts or a value corresponding to voltage corner. | ||
71 | |||
72 | Example HSUSB OTG controller device node: | ||
73 | |||
74 | usb@f9a55000 { | ||
75 | compatible = "qcom,usb-otg-snps"; | ||
76 | reg = <0xf9a55000 0x400>; | ||
77 | interrupts = <0 134 0>; | ||
78 | dr_mode = "peripheral"; | ||
79 | |||
80 | clocks = <&gcc GCC_XO_CLK>, <&gcc GCC_USB_HS_SYSTEM_CLK>, | ||
81 | <&gcc GCC_USB_HS_AHB_CLK>; | ||
82 | |||
83 | clock-names = "phy", "core", "iface"; | ||
84 | |||
85 | vddcx-supply = <&pm8841_s2_corner>; | ||
86 | v1p8-supply = <&pm8941_l6>; | ||
87 | v3p3-supply = <&pm8941_l24>; | ||
88 | |||
89 | resets = <&gcc GCC_USB2A_PHY_BCR>, <&gcc GCC_USB_HS_BCR>; | ||
90 | reset-names = "phy", "link"; | ||
91 | |||
92 | qcom,otg-control = <1>; | ||
93 | qcom,phy-init-sequence = < -1 0x63 >; | ||
94 | qcom,vdd-levels = <1 5 7>; | ||
95 | }; | ||
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c index 46de789ad3ae..0c4c200e1221 100644 --- a/arch/arm/mach-msm/board-msm7x30.c +++ b/arch/arm/mach-msm/board-msm7x30.c | |||
@@ -95,7 +95,7 @@ static int hsusb_phy_clk_reset(struct clk *phy_clk) | |||
95 | 95 | ||
96 | static struct msm_otg_platform_data msm_otg_pdata = { | 96 | static struct msm_otg_platform_data msm_otg_pdata = { |
97 | .phy_init_seq = hsusb_phy_init_seq, | 97 | .phy_init_seq = hsusb_phy_init_seq, |
98 | .mode = USB_PERIPHERAL, | 98 | .mode = USB_DR_MODE_PERIPHERAL, |
99 | .otg_control = OTG_PHY_CONTROL, | 99 | .otg_control = OTG_PHY_CONTROL, |
100 | .link_clk_reset = hsusb_link_clk_reset, | 100 | .link_clk_reset = hsusb_link_clk_reset, |
101 | .phy_clk_reset = hsusb_phy_clk_reset, | 101 | .phy_clk_reset = hsusb_phy_clk_reset, |
diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c index 9169ec324a43..4c748616ef47 100644 --- a/arch/arm/mach-msm/board-qsd8x50.c +++ b/arch/arm/mach-msm/board-qsd8x50.c | |||
@@ -116,7 +116,7 @@ static int hsusb_phy_clk_reset(struct clk *phy_clk) | |||
116 | 116 | ||
117 | static struct msm_otg_platform_data msm_otg_pdata = { | 117 | static struct msm_otg_platform_data msm_otg_pdata = { |
118 | .phy_init_seq = hsusb_phy_init_seq, | 118 | .phy_init_seq = hsusb_phy_init_seq, |
119 | .mode = USB_PERIPHERAL, | 119 | .mode = USB_DR_MODE_PERIPHERAL, |
120 | .otg_control = OTG_PHY_CONTROL, | 120 | .otg_control = OTG_PHY_CONTROL, |
121 | .link_clk_reset = hsusb_link_clk_reset, | 121 | .link_clk_reset = hsusb_link_clk_reset, |
122 | .phy_clk_reset = hsusb_phy_clk_reset, | 122 | .phy_clk_reset = hsusb_phy_clk_reset, |
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index d6ed819ff15c..660bfc5a70d7 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <linux/mtd/nand.h> | 33 | #include <linux/mtd/nand.h> |
34 | #include <linux/mmc/host.h> | 34 | #include <linux/mmc/host.h> |
35 | #include <linux/usb/phy.h> | 35 | #include <linux/usb/phy.h> |
36 | #include <linux/usb/usb_phy_gen_xceiv.h> | ||
37 | 36 | ||
38 | #include <linux/regulator/machine.h> | 37 | #include <linux/regulator/machine.h> |
39 | #include <linux/i2c/twl.h> | 38 | #include <linux/i2c/twl.h> |
diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c index 10855eb4ccc1..745367c0c2bb 100644 --- a/arch/arm/mach-omap2/usb-host.c +++ b/arch/arm/mach-omap2/usb-host.c | |||
@@ -28,7 +28,7 @@ | |||
28 | #include <linux/io.h> | 28 | #include <linux/io.h> |
29 | #include <linux/gpio.h> | 29 | #include <linux/gpio.h> |
30 | #include <linux/usb/phy.h> | 30 | #include <linux/usb/phy.h> |
31 | #include <linux/usb/usb_phy_gen_xceiv.h> | 31 | #include <linux/usb/usb_phy_generic.h> |
32 | 32 | ||
33 | #include "soc.h" | 33 | #include "soc.h" |
34 | #include "omap_device.h" | 34 | #include "omap_device.h" |
@@ -349,7 +349,7 @@ static struct fixed_voltage_config hsusb_reg_config = { | |||
349 | /* .init_data filled later */ | 349 | /* .init_data filled later */ |
350 | }; | 350 | }; |
351 | 351 | ||
352 | static const char *nop_name = "usb_phy_gen_xceiv"; /* NOP PHY driver */ | 352 | static const char *nop_name = "usb_phy_generic"; /* NOP PHY driver */ |
353 | static const char *reg_name = "reg-fixed-voltage"; /* Regulator driver */ | 353 | static const char *reg_name = "reg-fixed-voltage"; /* Regulator driver */ |
354 | 354 | ||
355 | /** | 355 | /** |
@@ -435,7 +435,7 @@ int usbhs_init_phys(struct usbhs_phy_data *phy, int num_phys) | |||
435 | struct platform_device *pdev; | 435 | struct platform_device *pdev; |
436 | char *phy_id; | 436 | char *phy_id; |
437 | struct platform_device_info pdevinfo; | 437 | struct platform_device_info pdevinfo; |
438 | struct usb_phy_gen_xceiv_platform_data nop_pdata; | 438 | struct usb_phy_generic_platform_data nop_pdata; |
439 | 439 | ||
440 | for (i = 0; i < num_phys; i++) { | 440 | for (i = 0; i < num_phys; i++) { |
441 | 441 | ||
@@ -469,8 +469,8 @@ int usbhs_init_phys(struct usbhs_phy_data *phy, int num_phys) | |||
469 | pdevinfo.id = phy->port; | 469 | pdevinfo.id = phy->port; |
470 | pdevinfo.data = &nop_pdata; | 470 | pdevinfo.data = &nop_pdata; |
471 | pdevinfo.size_data = | 471 | pdevinfo.size_data = |
472 | sizeof(struct usb_phy_gen_xceiv_platform_data); | 472 | sizeof(struct usb_phy_generic_platform_data); |
473 | scnprintf(phy_id, MAX_STR, "usb_phy_gen_xceiv.%d", | 473 | scnprintf(phy_id, MAX_STR, "usb_phy_generic.%d", |
474 | phy->port); | 474 | phy->port); |
475 | pdev = platform_device_register_full(&pdevinfo); | 475 | pdev = platform_device_register_full(&pdevinfo); |
476 | if (IS_ERR(pdev)) { | 476 | if (IS_ERR(pdev)) { |
diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index e2c730fc9a90..8eb996e4f058 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig | |||
@@ -44,7 +44,7 @@ comment "Platform Glue Driver Support" | |||
44 | 44 | ||
45 | config USB_DWC3_OMAP | 45 | config USB_DWC3_OMAP |
46 | tristate "Texas Instruments OMAP5 and similar Platforms" | 46 | tristate "Texas Instruments OMAP5 and similar Platforms" |
47 | depends on EXTCON | 47 | depends on EXTCON && (ARCH_OMAP2PLUS || COMPILE_TEST) |
48 | default USB_DWC3 | 48 | default USB_DWC3 |
49 | help | 49 | help |
50 | Some platforms from Texas Instruments like OMAP5, DRA7xxx and | 50 | Some platforms from Texas Instruments like OMAP5, DRA7xxx and |
@@ -54,6 +54,7 @@ config USB_DWC3_OMAP | |||
54 | 54 | ||
55 | config USB_DWC3_EXYNOS | 55 | config USB_DWC3_EXYNOS |
56 | tristate "Samsung Exynos Platform" | 56 | tristate "Samsung Exynos Platform" |
57 | depends on ARCH_EXYNOS || COMPILE_TEST | ||
57 | default USB_DWC3 | 58 | default USB_DWC3 |
58 | help | 59 | help |
59 | Recent Exynos5 SoCs ship with one DesignWare Core USB3 IP inside, | 60 | Recent Exynos5 SoCs ship with one DesignWare Core USB3 IP inside, |
@@ -72,6 +73,7 @@ config USB_DWC3_PCI | |||
72 | 73 | ||
73 | config USB_DWC3_KEYSTONE | 74 | config USB_DWC3_KEYSTONE |
74 | tristate "Texas Instruments Keystone2 Platforms" | 75 | tristate "Texas Instruments Keystone2 Platforms" |
76 | depends on ARCH_KEYSTONE || COMPILE_TEST | ||
75 | default USB_DWC3 | 77 | default USB_DWC3 |
76 | help | 78 | help |
77 | Support of USB2/3 functionality in TI Keystone2 platforms. | 79 | Support of USB2/3 functionality in TI Keystone2 platforms. |
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 10aaaae9af25..eb69eb9f06c8 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c | |||
@@ -486,70 +486,20 @@ static void dwc3_core_exit(struct dwc3 *dwc) | |||
486 | phy_exit(dwc->usb3_generic_phy); | 486 | phy_exit(dwc->usb3_generic_phy); |
487 | } | 487 | } |
488 | 488 | ||
489 | #define DWC3_ALIGN_MASK (16 - 1) | 489 | static int dwc3_core_get_phy(struct dwc3 *dwc) |
490 | |||
491 | static int dwc3_probe(struct platform_device *pdev) | ||
492 | { | 490 | { |
493 | struct device *dev = &pdev->dev; | 491 | struct device *dev = dwc->dev; |
494 | struct dwc3_platform_data *pdata = dev_get_platdata(dev); | ||
495 | struct device_node *node = dev->of_node; | 492 | struct device_node *node = dev->of_node; |
496 | struct resource *res; | 493 | int ret; |
497 | struct dwc3 *dwc; | ||
498 | |||
499 | int ret = -ENOMEM; | ||
500 | |||
501 | void __iomem *regs; | ||
502 | void *mem; | ||
503 | |||
504 | mem = devm_kzalloc(dev, sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL); | ||
505 | if (!mem) { | ||
506 | dev_err(dev, "not enough memory\n"); | ||
507 | return -ENOMEM; | ||
508 | } | ||
509 | dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1); | ||
510 | dwc->mem = mem; | ||
511 | |||
512 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
513 | if (!res) { | ||
514 | dev_err(dev, "missing IRQ\n"); | ||
515 | return -ENODEV; | ||
516 | } | ||
517 | dwc->xhci_resources[1].start = res->start; | ||
518 | dwc->xhci_resources[1].end = res->end; | ||
519 | dwc->xhci_resources[1].flags = res->flags; | ||
520 | dwc->xhci_resources[1].name = res->name; | ||
521 | |||
522 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
523 | if (!res) { | ||
524 | dev_err(dev, "missing memory resource\n"); | ||
525 | return -ENODEV; | ||
526 | } | ||
527 | 494 | ||
528 | if (node) { | 495 | if (node) { |
529 | dwc->maximum_speed = of_usb_get_maximum_speed(node); | ||
530 | |||
531 | dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0); | 496 | dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0); |
532 | dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1); | 497 | dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1); |
533 | |||
534 | dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize"); | ||
535 | dwc->dr_mode = of_usb_get_dr_mode(node); | ||
536 | } else if (pdata) { | ||
537 | dwc->maximum_speed = pdata->maximum_speed; | ||
538 | |||
539 | dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); | ||
540 | dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3); | ||
541 | |||
542 | dwc->needs_fifo_resize = pdata->tx_fifo_resize; | ||
543 | dwc->dr_mode = pdata->dr_mode; | ||
544 | } else { | 498 | } else { |
545 | dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); | 499 | dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); |
546 | dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3); | 500 | dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3); |
547 | } | 501 | } |
548 | 502 | ||
549 | /* default to superspeed if no maximum_speed passed */ | ||
550 | if (dwc->maximum_speed == USB_SPEED_UNKNOWN) | ||
551 | dwc->maximum_speed = USB_SPEED_SUPER; | ||
552 | |||
553 | if (IS_ERR(dwc->usb2_phy)) { | 503 | if (IS_ERR(dwc->usb2_phy)) { |
554 | ret = PTR_ERR(dwc->usb2_phy); | 504 | ret = PTR_ERR(dwc->usb2_phy); |
555 | if (ret == -ENXIO || ret == -ENODEV) { | 505 | if (ret == -ENXIO || ret == -ENODEV) { |
@@ -600,6 +550,132 @@ static int dwc3_probe(struct platform_device *pdev) | |||
600 | } | 550 | } |
601 | } | 551 | } |
602 | 552 | ||
553 | return 0; | ||
554 | } | ||
555 | |||
556 | static int dwc3_core_init_mode(struct dwc3 *dwc) | ||
557 | { | ||
558 | struct device *dev = dwc->dev; | ||
559 | int ret; | ||
560 | |||
561 | switch (dwc->dr_mode) { | ||
562 | case USB_DR_MODE_PERIPHERAL: | ||
563 | dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_DEVICE); | ||
564 | ret = dwc3_gadget_init(dwc); | ||
565 | if (ret) { | ||
566 | dev_err(dev, "failed to initialize gadget\n"); | ||
567 | return ret; | ||
568 | } | ||
569 | break; | ||
570 | case USB_DR_MODE_HOST: | ||
571 | dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_HOST); | ||
572 | ret = dwc3_host_init(dwc); | ||
573 | if (ret) { | ||
574 | dev_err(dev, "failed to initialize host\n"); | ||
575 | return ret; | ||
576 | } | ||
577 | break; | ||
578 | case USB_DR_MODE_OTG: | ||
579 | dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_OTG); | ||
580 | ret = dwc3_host_init(dwc); | ||
581 | if (ret) { | ||
582 | dev_err(dev, "failed to initialize host\n"); | ||
583 | return ret; | ||
584 | } | ||
585 | |||
586 | ret = dwc3_gadget_init(dwc); | ||
587 | if (ret) { | ||
588 | dev_err(dev, "failed to initialize gadget\n"); | ||
589 | return ret; | ||
590 | } | ||
591 | break; | ||
592 | default: | ||
593 | dev_err(dev, "Unsupported mode of operation %d\n", dwc->dr_mode); | ||
594 | return -EINVAL; | ||
595 | } | ||
596 | |||
597 | return 0; | ||
598 | } | ||
599 | |||
600 | static void dwc3_core_exit_mode(struct dwc3 *dwc) | ||
601 | { | ||
602 | switch (dwc->dr_mode) { | ||
603 | case USB_DR_MODE_PERIPHERAL: | ||
604 | dwc3_gadget_exit(dwc); | ||
605 | break; | ||
606 | case USB_DR_MODE_HOST: | ||
607 | dwc3_host_exit(dwc); | ||
608 | break; | ||
609 | case USB_DR_MODE_OTG: | ||
610 | dwc3_host_exit(dwc); | ||
611 | dwc3_gadget_exit(dwc); | ||
612 | break; | ||
613 | default: | ||
614 | /* do nothing */ | ||
615 | break; | ||
616 | } | ||
617 | } | ||
618 | |||
619 | #define DWC3_ALIGN_MASK (16 - 1) | ||
620 | |||
621 | static int dwc3_probe(struct platform_device *pdev) | ||
622 | { | ||
623 | struct device *dev = &pdev->dev; | ||
624 | struct dwc3_platform_data *pdata = dev_get_platdata(dev); | ||
625 | struct device_node *node = dev->of_node; | ||
626 | struct resource *res; | ||
627 | struct dwc3 *dwc; | ||
628 | |||
629 | int ret; | ||
630 | |||
631 | void __iomem *regs; | ||
632 | void *mem; | ||
633 | |||
634 | mem = devm_kzalloc(dev, sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL); | ||
635 | if (!mem) { | ||
636 | dev_err(dev, "not enough memory\n"); | ||
637 | return -ENOMEM; | ||
638 | } | ||
639 | dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1); | ||
640 | dwc->mem = mem; | ||
641 | dwc->dev = dev; | ||
642 | |||
643 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
644 | if (!res) { | ||
645 | dev_err(dev, "missing IRQ\n"); | ||
646 | return -ENODEV; | ||
647 | } | ||
648 | dwc->xhci_resources[1].start = res->start; | ||
649 | dwc->xhci_resources[1].end = res->end; | ||
650 | dwc->xhci_resources[1].flags = res->flags; | ||
651 | dwc->xhci_resources[1].name = res->name; | ||
652 | |||
653 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
654 | if (!res) { | ||
655 | dev_err(dev, "missing memory resource\n"); | ||
656 | return -ENODEV; | ||
657 | } | ||
658 | |||
659 | if (node) { | ||
660 | dwc->maximum_speed = of_usb_get_maximum_speed(node); | ||
661 | |||
662 | dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize"); | ||
663 | dwc->dr_mode = of_usb_get_dr_mode(node); | ||
664 | } else if (pdata) { | ||
665 | dwc->maximum_speed = pdata->maximum_speed; | ||
666 | |||
667 | dwc->needs_fifo_resize = pdata->tx_fifo_resize; | ||
668 | dwc->dr_mode = pdata->dr_mode; | ||
669 | } | ||
670 | |||
671 | /* default to superspeed if no maximum_speed passed */ | ||
672 | if (dwc->maximum_speed == USB_SPEED_UNKNOWN) | ||
673 | dwc->maximum_speed = USB_SPEED_SUPER; | ||
674 | |||
675 | ret = dwc3_core_get_phy(dwc); | ||
676 | if (ret) | ||
677 | return ret; | ||
678 | |||
603 | dwc->xhci_resources[0].start = res->start; | 679 | dwc->xhci_resources[0].start = res->start; |
604 | dwc->xhci_resources[0].end = dwc->xhci_resources[0].start + | 680 | dwc->xhci_resources[0].end = dwc->xhci_resources[0].start + |
605 | DWC3_XHCI_REGS_END; | 681 | DWC3_XHCI_REGS_END; |
@@ -621,7 +697,6 @@ static int dwc3_probe(struct platform_device *pdev) | |||
621 | 697 | ||
622 | dwc->regs = regs; | 698 | dwc->regs = regs; |
623 | dwc->regs_size = resource_size(res); | 699 | dwc->regs_size = resource_size(res); |
624 | dwc->dev = dev; | ||
625 | 700 | ||
626 | dev->dma_mask = dev->parent->dma_mask; | 701 | dev->dma_mask = dev->parent->dma_mask; |
627 | dev->dma_parms = dev->parent->dma_parms; | 702 | dev->dma_parms = dev->parent->dma_parms; |
@@ -670,41 +745,9 @@ static int dwc3_probe(struct platform_device *pdev) | |||
670 | goto err_usb3phy_power; | 745 | goto err_usb3phy_power; |
671 | } | 746 | } |
672 | 747 | ||
673 | switch (dwc->dr_mode) { | 748 | ret = dwc3_core_init_mode(dwc); |
674 | case USB_DR_MODE_PERIPHERAL: | 749 | if (ret) |
675 | dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_DEVICE); | ||
676 | ret = dwc3_gadget_init(dwc); | ||
677 | if (ret) { | ||
678 | dev_err(dev, "failed to initialize gadget\n"); | ||
679 | goto err2; | ||
680 | } | ||
681 | break; | ||
682 | case USB_DR_MODE_HOST: | ||
683 | dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_HOST); | ||
684 | ret = dwc3_host_init(dwc); | ||
685 | if (ret) { | ||
686 | dev_err(dev, "failed to initialize host\n"); | ||
687 | goto err2; | ||
688 | } | ||
689 | break; | ||
690 | case USB_DR_MODE_OTG: | ||
691 | dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_OTG); | ||
692 | ret = dwc3_host_init(dwc); | ||
693 | if (ret) { | ||
694 | dev_err(dev, "failed to initialize host\n"); | ||
695 | goto err2; | ||
696 | } | ||
697 | |||
698 | ret = dwc3_gadget_init(dwc); | ||
699 | if (ret) { | ||
700 | dev_err(dev, "failed to initialize gadget\n"); | ||
701 | goto err2; | ||
702 | } | ||
703 | break; | ||
704 | default: | ||
705 | dev_err(dev, "Unsupported mode of operation %d\n", dwc->dr_mode); | ||
706 | goto err2; | 750 | goto err2; |
707 | } | ||
708 | 751 | ||
709 | ret = dwc3_debugfs_init(dwc); | 752 | ret = dwc3_debugfs_init(dwc); |
710 | if (ret) { | 753 | if (ret) { |
@@ -717,21 +760,7 @@ static int dwc3_probe(struct platform_device *pdev) | |||
717 | return 0; | 760 | return 0; |
718 | 761 | ||
719 | err3: | 762 | err3: |
720 | switch (dwc->dr_mode) { | 763 | dwc3_core_exit_mode(dwc); |
721 | case USB_DR_MODE_PERIPHERAL: | ||
722 | dwc3_gadget_exit(dwc); | ||
723 | break; | ||
724 | case USB_DR_MODE_HOST: | ||
725 | dwc3_host_exit(dwc); | ||
726 | break; | ||
727 | case USB_DR_MODE_OTG: | ||
728 | dwc3_host_exit(dwc); | ||
729 | dwc3_gadget_exit(dwc); | ||
730 | break; | ||
731 | default: | ||
732 | /* do nothing */ | ||
733 | break; | ||
734 | } | ||
735 | 764 | ||
736 | err2: | 765 | err2: |
737 | dwc3_event_buffers_cleanup(dwc); | 766 | dwc3_event_buffers_cleanup(dwc); |
@@ -766,23 +795,7 @@ static int dwc3_remove(struct platform_device *pdev) | |||
766 | pm_runtime_disable(&pdev->dev); | 795 | pm_runtime_disable(&pdev->dev); |
767 | 796 | ||
768 | dwc3_debugfs_exit(dwc); | 797 | dwc3_debugfs_exit(dwc); |
769 | 798 | dwc3_core_exit_mode(dwc); | |
770 | switch (dwc->dr_mode) { | ||
771 | case USB_DR_MODE_PERIPHERAL: | ||
772 | dwc3_gadget_exit(dwc); | ||
773 | break; | ||
774 | case USB_DR_MODE_HOST: | ||
775 | dwc3_host_exit(dwc); | ||
776 | break; | ||
777 | case USB_DR_MODE_OTG: | ||
778 | dwc3_host_exit(dwc); | ||
779 | dwc3_gadget_exit(dwc); | ||
780 | break; | ||
781 | default: | ||
782 | /* do nothing */ | ||
783 | break; | ||
784 | } | ||
785 | |||
786 | dwc3_event_buffers_cleanup(dwc); | 799 | dwc3_event_buffers_cleanup(dwc); |
787 | dwc3_free_event_buffers(dwc); | 800 | dwc3_free_event_buffers(dwc); |
788 | dwc3_core_exit(dwc); | 801 | dwc3_core_exit(dwc); |
diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c index 28c8ad79f5e6..f9fb8adb785b 100644 --- a/drivers/usb/dwc3/dwc3-exynos.c +++ b/drivers/usb/dwc3/dwc3-exynos.c | |||
@@ -24,9 +24,10 @@ | |||
24 | #include <linux/dma-mapping.h> | 24 | #include <linux/dma-mapping.h> |
25 | #include <linux/clk.h> | 25 | #include <linux/clk.h> |
26 | #include <linux/usb/otg.h> | 26 | #include <linux/usb/otg.h> |
27 | #include <linux/usb/usb_phy_gen_xceiv.h> | 27 | #include <linux/usb/usb_phy_generic.h> |
28 | #include <linux/of.h> | 28 | #include <linux/of.h> |
29 | #include <linux/of_platform.h> | 29 | #include <linux/of_platform.h> |
30 | #include <linux/regulator/consumer.h> | ||
30 | 31 | ||
31 | struct dwc3_exynos { | 32 | struct dwc3_exynos { |
32 | struct platform_device *usb2_phy; | 33 | struct platform_device *usb2_phy; |
@@ -34,17 +35,19 @@ struct dwc3_exynos { | |||
34 | struct device *dev; | 35 | struct device *dev; |
35 | 36 | ||
36 | struct clk *clk; | 37 | struct clk *clk; |
38 | struct regulator *vdd33; | ||
39 | struct regulator *vdd10; | ||
37 | }; | 40 | }; |
38 | 41 | ||
39 | static int dwc3_exynos_register_phys(struct dwc3_exynos *exynos) | 42 | static int dwc3_exynos_register_phys(struct dwc3_exynos *exynos) |
40 | { | 43 | { |
41 | struct usb_phy_gen_xceiv_platform_data pdata; | 44 | struct usb_phy_generic_platform_data pdata; |
42 | struct platform_device *pdev; | 45 | struct platform_device *pdev; |
43 | int ret; | 46 | int ret; |
44 | 47 | ||
45 | memset(&pdata, 0x00, sizeof(pdata)); | 48 | memset(&pdata, 0x00, sizeof(pdata)); |
46 | 49 | ||
47 | pdev = platform_device_alloc("usb_phy_gen_xceiv", PLATFORM_DEVID_AUTO); | 50 | pdev = platform_device_alloc("usb_phy_generic", PLATFORM_DEVID_AUTO); |
48 | if (!pdev) | 51 | if (!pdev) |
49 | return -ENOMEM; | 52 | return -ENOMEM; |
50 | 53 | ||
@@ -56,7 +59,7 @@ static int dwc3_exynos_register_phys(struct dwc3_exynos *exynos) | |||
56 | if (ret) | 59 | if (ret) |
57 | goto err1; | 60 | goto err1; |
58 | 61 | ||
59 | pdev = platform_device_alloc("usb_phy_gen_xceiv", PLATFORM_DEVID_AUTO); | 62 | pdev = platform_device_alloc("usb_phy_generic", PLATFORM_DEVID_AUTO); |
60 | if (!pdev) { | 63 | if (!pdev) { |
61 | ret = -ENOMEM; | 64 | ret = -ENOMEM; |
62 | goto err1; | 65 | goto err1; |
@@ -107,12 +110,12 @@ static int dwc3_exynos_probe(struct platform_device *pdev) | |||
107 | struct device *dev = &pdev->dev; | 110 | struct device *dev = &pdev->dev; |
108 | struct device_node *node = dev->of_node; | 111 | struct device_node *node = dev->of_node; |
109 | 112 | ||
110 | int ret = -ENOMEM; | 113 | int ret; |
111 | 114 | ||
112 | exynos = devm_kzalloc(dev, sizeof(*exynos), GFP_KERNEL); | 115 | exynos = devm_kzalloc(dev, sizeof(*exynos), GFP_KERNEL); |
113 | if (!exynos) { | 116 | if (!exynos) { |
114 | dev_err(dev, "not enough memory\n"); | 117 | dev_err(dev, "not enough memory\n"); |
115 | goto err1; | 118 | return -ENOMEM; |
116 | } | 119 | } |
117 | 120 | ||
118 | /* | 121 | /* |
@@ -122,21 +125,20 @@ static int dwc3_exynos_probe(struct platform_device *pdev) | |||
122 | */ | 125 | */ |
123 | ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32)); | 126 | ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32)); |
124 | if (ret) | 127 | if (ret) |
125 | goto err1; | 128 | return ret; |
126 | 129 | ||
127 | platform_set_drvdata(pdev, exynos); | 130 | platform_set_drvdata(pdev, exynos); |
128 | 131 | ||
129 | ret = dwc3_exynos_register_phys(exynos); | 132 | ret = dwc3_exynos_register_phys(exynos); |
130 | if (ret) { | 133 | if (ret) { |
131 | dev_err(dev, "couldn't register PHYs\n"); | 134 | dev_err(dev, "couldn't register PHYs\n"); |
132 | goto err1; | 135 | return ret; |
133 | } | 136 | } |
134 | 137 | ||
135 | clk = devm_clk_get(dev, "usbdrd30"); | 138 | clk = devm_clk_get(dev, "usbdrd30"); |
136 | if (IS_ERR(clk)) { | 139 | if (IS_ERR(clk)) { |
137 | dev_err(dev, "couldn't get clock\n"); | 140 | dev_err(dev, "couldn't get clock\n"); |
138 | ret = -EINVAL; | 141 | return -EINVAL; |
139 | goto err1; | ||
140 | } | 142 | } |
141 | 143 | ||
142 | exynos->dev = dev; | 144 | exynos->dev = dev; |
@@ -144,23 +146,48 @@ static int dwc3_exynos_probe(struct platform_device *pdev) | |||
144 | 146 | ||
145 | clk_prepare_enable(exynos->clk); | 147 | clk_prepare_enable(exynos->clk); |
146 | 148 | ||
149 | exynos->vdd33 = devm_regulator_get(dev, "vdd33"); | ||
150 | if (IS_ERR(exynos->vdd33)) { | ||
151 | ret = PTR_ERR(exynos->vdd33); | ||
152 | goto err2; | ||
153 | } | ||
154 | ret = regulator_enable(exynos->vdd33); | ||
155 | if (ret) { | ||
156 | dev_err(dev, "Failed to enable VDD33 supply\n"); | ||
157 | goto err2; | ||
158 | } | ||
159 | |||
160 | exynos->vdd10 = devm_regulator_get(dev, "vdd10"); | ||
161 | if (IS_ERR(exynos->vdd10)) { | ||
162 | ret = PTR_ERR(exynos->vdd10); | ||
163 | goto err3; | ||
164 | } | ||
165 | ret = regulator_enable(exynos->vdd10); | ||
166 | if (ret) { | ||
167 | dev_err(dev, "Failed to enable VDD10 supply\n"); | ||
168 | goto err3; | ||
169 | } | ||
170 | |||
147 | if (node) { | 171 | if (node) { |
148 | ret = of_platform_populate(node, NULL, NULL, dev); | 172 | ret = of_platform_populate(node, NULL, NULL, dev); |
149 | if (ret) { | 173 | if (ret) { |
150 | dev_err(dev, "failed to add dwc3 core\n"); | 174 | dev_err(dev, "failed to add dwc3 core\n"); |
151 | goto err2; | 175 | goto err4; |
152 | } | 176 | } |
153 | } else { | 177 | } else { |
154 | dev_err(dev, "no device node, failed to add dwc3 core\n"); | 178 | dev_err(dev, "no device node, failed to add dwc3 core\n"); |
155 | ret = -ENODEV; | 179 | ret = -ENODEV; |
156 | goto err2; | 180 | goto err4; |
157 | } | 181 | } |
158 | 182 | ||
159 | return 0; | 183 | return 0; |
160 | 184 | ||
185 | err4: | ||
186 | regulator_disable(exynos->vdd10); | ||
187 | err3: | ||
188 | regulator_disable(exynos->vdd33); | ||
161 | err2: | 189 | err2: |
162 | clk_disable_unprepare(clk); | 190 | clk_disable_unprepare(clk); |
163 | err1: | ||
164 | return ret; | 191 | return ret; |
165 | } | 192 | } |
166 | 193 | ||
@@ -174,6 +201,9 @@ static int dwc3_exynos_remove(struct platform_device *pdev) | |||
174 | 201 | ||
175 | clk_disable_unprepare(exynos->clk); | 202 | clk_disable_unprepare(exynos->clk); |
176 | 203 | ||
204 | regulator_disable(exynos->vdd33); | ||
205 | regulator_disable(exynos->vdd10); | ||
206 | |||
177 | return 0; | 207 | return 0; |
178 | } | 208 | } |
179 | 209 | ||
@@ -192,12 +222,27 @@ static int dwc3_exynos_suspend(struct device *dev) | |||
192 | 222 | ||
193 | clk_disable(exynos->clk); | 223 | clk_disable(exynos->clk); |
194 | 224 | ||
225 | regulator_disable(exynos->vdd33); | ||
226 | regulator_disable(exynos->vdd10); | ||
227 | |||
195 | return 0; | 228 | return 0; |
196 | } | 229 | } |
197 | 230 | ||
198 | static int dwc3_exynos_resume(struct device *dev) | 231 | static int dwc3_exynos_resume(struct device *dev) |
199 | { | 232 | { |
200 | struct dwc3_exynos *exynos = dev_get_drvdata(dev); | 233 | struct dwc3_exynos *exynos = dev_get_drvdata(dev); |
234 | int ret; | ||
235 | |||
236 | ret = regulator_enable(exynos->vdd33); | ||
237 | if (ret) { | ||
238 | dev_err(dev, "Failed to enable VDD33 supply\n"); | ||
239 | return ret; | ||
240 | } | ||
241 | ret = regulator_enable(exynos->vdd10); | ||
242 | if (ret) { | ||
243 | dev_err(dev, "Failed to enable VDD10 supply\n"); | ||
244 | return ret; | ||
245 | } | ||
201 | 246 | ||
202 | clk_enable(exynos->clk); | 247 | clk_enable(exynos->clk); |
203 | 248 | ||
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index 1160ff41bed4..4af4c3567656 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c | |||
@@ -393,7 +393,7 @@ static int dwc3_omap_probe(struct platform_device *pdev) | |||
393 | struct extcon_dev *edev; | 393 | struct extcon_dev *edev; |
394 | struct regulator *vbus_reg = NULL; | 394 | struct regulator *vbus_reg = NULL; |
395 | 395 | ||
396 | int ret = -ENOMEM; | 396 | int ret; |
397 | int irq; | 397 | int irq; |
398 | 398 | ||
399 | int utmi_mode = 0; | 399 | int utmi_mode = 0; |
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index f393c183cc69..a60bab7dfa0a 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
24 | 24 | ||
25 | #include <linux/usb/otg.h> | 25 | #include <linux/usb/otg.h> |
26 | #include <linux/usb/usb_phy_gen_xceiv.h> | 26 | #include <linux/usb/usb_phy_generic.h> |
27 | 27 | ||
28 | /* FIXME define these in <linux/pci_ids.h> */ | 28 | /* FIXME define these in <linux/pci_ids.h> */ |
29 | #define PCI_VENDOR_ID_SYNOPSYS 0x16c3 | 29 | #define PCI_VENDOR_ID_SYNOPSYS 0x16c3 |
@@ -40,13 +40,13 @@ struct dwc3_pci { | |||
40 | 40 | ||
41 | static int dwc3_pci_register_phys(struct dwc3_pci *glue) | 41 | static int dwc3_pci_register_phys(struct dwc3_pci *glue) |
42 | { | 42 | { |
43 | struct usb_phy_gen_xceiv_platform_data pdata; | 43 | struct usb_phy_generic_platform_data pdata; |
44 | struct platform_device *pdev; | 44 | struct platform_device *pdev; |
45 | int ret; | 45 | int ret; |
46 | 46 | ||
47 | memset(&pdata, 0x00, sizeof(pdata)); | 47 | memset(&pdata, 0x00, sizeof(pdata)); |
48 | 48 | ||
49 | pdev = platform_device_alloc("usb_phy_gen_xceiv", 0); | 49 | pdev = platform_device_alloc("usb_phy_generic", 0); |
50 | if (!pdev) | 50 | if (!pdev) |
51 | return -ENOMEM; | 51 | return -ENOMEM; |
52 | 52 | ||
@@ -58,7 +58,7 @@ static int dwc3_pci_register_phys(struct dwc3_pci *glue) | |||
58 | if (ret) | 58 | if (ret) |
59 | goto err1; | 59 | goto err1; |
60 | 60 | ||
61 | pdev = platform_device_alloc("usb_phy_gen_xceiv", 1); | 61 | pdev = platform_device_alloc("usb_phy_generic", 1); |
62 | if (!pdev) { | 62 | if (!pdev) { |
63 | ret = -ENOMEM; | 63 | ret = -ENOMEM; |
64 | goto err1; | 64 | goto err1; |
@@ -99,7 +99,7 @@ static int dwc3_pci_probe(struct pci_dev *pci, | |||
99 | struct resource res[2]; | 99 | struct resource res[2]; |
100 | struct platform_device *dwc3; | 100 | struct platform_device *dwc3; |
101 | struct dwc3_pci *glue; | 101 | struct dwc3_pci *glue; |
102 | int ret = -ENOMEM; | 102 | int ret; |
103 | struct device *dev = &pci->dev; | 103 | struct device *dev = &pci->dev; |
104 | 104 | ||
105 | glue = devm_kzalloc(dev, sizeof(*glue), GFP_KERNEL); | 105 | glue = devm_kzalloc(dev, sizeof(*glue), GFP_KERNEL); |
@@ -110,7 +110,7 @@ static int dwc3_pci_probe(struct pci_dev *pci, | |||
110 | 110 | ||
111 | glue->dev = dev; | 111 | glue->dev = dev; |
112 | 112 | ||
113 | ret = pci_enable_device(pci); | 113 | ret = pcim_enable_device(pci); |
114 | if (ret) { | 114 | if (ret) { |
115 | dev_err(dev, "failed to enable pci device\n"); | 115 | dev_err(dev, "failed to enable pci device\n"); |
116 | return -ENODEV; | 116 | return -ENODEV; |
@@ -127,8 +127,7 @@ static int dwc3_pci_probe(struct pci_dev *pci, | |||
127 | dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO); | 127 | dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO); |
128 | if (!dwc3) { | 128 | if (!dwc3) { |
129 | dev_err(dev, "couldn't allocate dwc3 device\n"); | 129 | dev_err(dev, "couldn't allocate dwc3 device\n"); |
130 | ret = -ENOMEM; | 130 | return -ENOMEM; |
131 | goto err1; | ||
132 | } | 131 | } |
133 | 132 | ||
134 | memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res)); | 133 | memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res)); |
@@ -145,7 +144,7 @@ static int dwc3_pci_probe(struct pci_dev *pci, | |||
145 | ret = platform_device_add_resources(dwc3, res, ARRAY_SIZE(res)); | 144 | ret = platform_device_add_resources(dwc3, res, ARRAY_SIZE(res)); |
146 | if (ret) { | 145 | if (ret) { |
147 | dev_err(dev, "couldn't add resources to dwc3 device\n"); | 146 | dev_err(dev, "couldn't add resources to dwc3 device\n"); |
148 | goto err1; | 147 | return ret; |
149 | } | 148 | } |
150 | 149 | ||
151 | pci_set_drvdata(pci, glue); | 150 | pci_set_drvdata(pci, glue); |
@@ -167,9 +166,6 @@ static int dwc3_pci_probe(struct pci_dev *pci, | |||
167 | 166 | ||
168 | err3: | 167 | err3: |
169 | platform_device_put(dwc3); | 168 | platform_device_put(dwc3); |
170 | err1: | ||
171 | pci_disable_device(pci); | ||
172 | |||
173 | return ret; | 169 | return ret; |
174 | } | 170 | } |
175 | 171 | ||
@@ -180,7 +176,6 @@ static void dwc3_pci_remove(struct pci_dev *pci) | |||
180 | platform_device_unregister(glue->dwc3); | 176 | platform_device_unregister(glue->dwc3); |
181 | platform_device_unregister(glue->usb2_phy); | 177 | platform_device_unregister(glue->usb2_phy); |
182 | platform_device_unregister(glue->usb3_phy); | 178 | platform_device_unregister(glue->usb3_phy); |
183 | pci_disable_device(pci); | ||
184 | } | 179 | } |
185 | 180 | ||
186 | static const struct pci_device_id dwc3_pci_id_table[] = { | 181 | static const struct pci_device_id dwc3_pci_id_table[] = { |
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 70715eeededd..9d64dd02c57e 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c | |||
@@ -298,11 +298,76 @@ static const char *dwc3_gadget_ep_cmd_string(u8 cmd) | |||
298 | } | 298 | } |
299 | } | 299 | } |
300 | 300 | ||
301 | static const char *dwc3_gadget_generic_cmd_string(u8 cmd) | ||
302 | { | ||
303 | switch (cmd) { | ||
304 | case DWC3_DGCMD_SET_LMP: | ||
305 | return "Set LMP"; | ||
306 | case DWC3_DGCMD_SET_PERIODIC_PAR: | ||
307 | return "Set Periodic Parameters"; | ||
308 | case DWC3_DGCMD_XMIT_FUNCTION: | ||
309 | return "Transmit Function Wake Device Notification"; | ||
310 | case DWC3_DGCMD_SET_SCRATCHPAD_ADDR_LO: | ||
311 | return "Set Scratchpad Buffer Array Address Lo"; | ||
312 | case DWC3_DGCMD_SET_SCRATCHPAD_ADDR_HI: | ||
313 | return "Set Scratchpad Buffer Array Address Hi"; | ||
314 | case DWC3_DGCMD_SELECTED_FIFO_FLUSH: | ||
315 | return "Selected FIFO Flush"; | ||
316 | case DWC3_DGCMD_ALL_FIFO_FLUSH: | ||
317 | return "All FIFO Flush"; | ||
318 | case DWC3_DGCMD_SET_ENDPOINT_NRDY: | ||
319 | return "Set Endpoint NRDY"; | ||
320 | case DWC3_DGCMD_RUN_SOC_BUS_LOOPBACK: | ||
321 | return "Run SoC Bus Loopback Test"; | ||
322 | default: | ||
323 | return "UNKNOWN"; | ||
324 | } | ||
325 | } | ||
326 | |||
327 | static const char *dwc3_gadget_link_string(enum dwc3_link_state link_state) | ||
328 | { | ||
329 | switch (link_state) { | ||
330 | case DWC3_LINK_STATE_U0: | ||
331 | return "U0"; | ||
332 | case DWC3_LINK_STATE_U1: | ||
333 | return "U1"; | ||
334 | case DWC3_LINK_STATE_U2: | ||
335 | return "U2"; | ||
336 | case DWC3_LINK_STATE_U3: | ||
337 | return "U3"; | ||
338 | case DWC3_LINK_STATE_SS_DIS: | ||
339 | return "SS.Disabled"; | ||
340 | case DWC3_LINK_STATE_RX_DET: | ||
341 | return "RX.Detect"; | ||
342 | case DWC3_LINK_STATE_SS_INACT: | ||
343 | return "SS.Inactive"; | ||
344 | case DWC3_LINK_STATE_POLL: | ||
345 | return "Polling"; | ||
346 | case DWC3_LINK_STATE_RECOV: | ||
347 | return "Recovery"; | ||
348 | case DWC3_LINK_STATE_HRESET: | ||
349 | return "Hot Reset"; | ||
350 | case DWC3_LINK_STATE_CMPLY: | ||
351 | return "Compliance"; | ||
352 | case DWC3_LINK_STATE_LPBK: | ||
353 | return "Loopback"; | ||
354 | case DWC3_LINK_STATE_RESET: | ||
355 | return "Reset"; | ||
356 | case DWC3_LINK_STATE_RESUME: | ||
357 | return "Resume"; | ||
358 | default: | ||
359 | return "UNKNOWN link state\n"; | ||
360 | } | ||
361 | } | ||
362 | |||
301 | int dwc3_send_gadget_generic_command(struct dwc3 *dwc, int cmd, u32 param) | 363 | int dwc3_send_gadget_generic_command(struct dwc3 *dwc, int cmd, u32 param) |
302 | { | 364 | { |
303 | u32 timeout = 500; | 365 | u32 timeout = 500; |
304 | u32 reg; | 366 | u32 reg; |
305 | 367 | ||
368 | dev_vdbg(dwc->dev, "generic cmd '%s' [%d] param %08x\n", | ||
369 | dwc3_gadget_generic_cmd_string(cmd), cmd, param); | ||
370 | |||
306 | dwc3_writel(dwc->regs, DWC3_DGCMDPAR, param); | 371 | dwc3_writel(dwc->regs, DWC3_DGCMDPAR, param); |
307 | dwc3_writel(dwc->regs, DWC3_DGCMD, cmd | DWC3_DGCMD_CMDACT); | 372 | dwc3_writel(dwc->regs, DWC3_DGCMD, cmd | DWC3_DGCMD_CMDACT); |
308 | 373 | ||
@@ -332,9 +397,9 @@ int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep, | |||
332 | u32 timeout = 500; | 397 | u32 timeout = 500; |
333 | u32 reg; | 398 | u32 reg; |
334 | 399 | ||
335 | dev_vdbg(dwc->dev, "%s: cmd '%s' params %08x %08x %08x\n", | 400 | dev_vdbg(dwc->dev, "%s: cmd '%s' [%d] params %08x %08x %08x\n", |
336 | dep->name, | 401 | dep->name, |
337 | dwc3_gadget_ep_cmd_string(cmd), params->param0, | 402 | dwc3_gadget_ep_cmd_string(cmd), cmd, params->param0, |
338 | params->param1, params->param2); | 403 | params->param1, params->param2); |
339 | 404 | ||
340 | dwc3_writel(dwc->regs, DWC3_DEPCMDPAR0(ep), params->param0); | 405 | dwc3_writel(dwc->regs, DWC3_DEPCMDPAR0(ep), params->param0); |
@@ -515,7 +580,7 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep, | |||
515 | { | 580 | { |
516 | struct dwc3 *dwc = dep->dwc; | 581 | struct dwc3 *dwc = dep->dwc; |
517 | u32 reg; | 582 | u32 reg; |
518 | int ret = -ENOMEM; | 583 | int ret; |
519 | 584 | ||
520 | dev_vdbg(dwc->dev, "Enabling %s\n", dep->name); | 585 | dev_vdbg(dwc->dev, "Enabling %s\n", dep->name); |
521 | 586 | ||
@@ -604,6 +669,10 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep) | |||
604 | 669 | ||
605 | dwc3_remove_requests(dwc, dep); | 670 | dwc3_remove_requests(dwc, dep); |
606 | 671 | ||
672 | /* make sure HW endpoint isn't stalled */ | ||
673 | if (dep->flags & DWC3_EP_STALL) | ||
674 | __dwc3_gadget_ep_set_halt(dep, 0); | ||
675 | |||
607 | reg = dwc3_readl(dwc->regs, DWC3_DALEPENA); | 676 | reg = dwc3_readl(dwc->regs, DWC3_DALEPENA); |
608 | reg &= ~DWC3_DALEPENA_EP(dep->number); | 677 | reg &= ~DWC3_DALEPENA_EP(dep->number); |
609 | dwc3_writel(dwc->regs, DWC3_DALEPENA, reg); | 678 | dwc3_writel(dwc->regs, DWC3_DALEPENA, reg); |
@@ -2441,8 +2510,6 @@ static void dwc3_gadget_linksts_change_interrupt(struct dwc3 *dwc, | |||
2441 | } | 2510 | } |
2442 | } | 2511 | } |
2443 | 2512 | ||
2444 | dwc->link_state = next; | ||
2445 | |||
2446 | switch (next) { | 2513 | switch (next) { |
2447 | case DWC3_LINK_STATE_U1: | 2514 | case DWC3_LINK_STATE_U1: |
2448 | if (dwc->speed == USB_SPEED_SUPER) | 2515 | if (dwc->speed == USB_SPEED_SUPER) |
@@ -2460,7 +2527,11 @@ static void dwc3_gadget_linksts_change_interrupt(struct dwc3 *dwc, | |||
2460 | break; | 2527 | break; |
2461 | } | 2528 | } |
2462 | 2529 | ||
2463 | dev_vdbg(dwc->dev, "%s link %d\n", __func__, dwc->link_state); | 2530 | dev_vdbg(dwc->dev, "link change: %s [%d] -> %s [%d]\n", |
2531 | dwc3_gadget_link_string(dwc->link_state), | ||
2532 | dwc->link_state, dwc3_gadget_link_string(next), next); | ||
2533 | |||
2534 | dwc->link_state = next; | ||
2464 | } | 2535 | } |
2465 | 2536 | ||
2466 | static void dwc3_gadget_hibernation_interrupt(struct dwc3 *dwc, | 2537 | static void dwc3_gadget_hibernation_interrupt(struct dwc3 *dwc, |
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index 9f65324f9ae0..76023ce449a3 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c | |||
@@ -1686,7 +1686,7 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) | |||
1686 | reset_all_endpoints(udc); | 1686 | reset_all_endpoints(udc); |
1687 | 1687 | ||
1688 | if (udc->gadget.speed != USB_SPEED_UNKNOWN | 1688 | if (udc->gadget.speed != USB_SPEED_UNKNOWN |
1689 | && udc->driver->disconnect) { | 1689 | && udc->driver && udc->driver->disconnect) { |
1690 | udc->gadget.speed = USB_SPEED_UNKNOWN; | 1690 | udc->gadget.speed = USB_SPEED_UNKNOWN; |
1691 | spin_unlock(&udc->lock); | 1691 | spin_unlock(&udc->lock); |
1692 | udc->driver->disconnect(&udc->gadget); | 1692 | udc->driver->disconnect(&udc->gadget); |
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index fab906429b80..042c66b71df8 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c | |||
@@ -21,6 +21,24 @@ | |||
21 | #include <linux/usb/composite.h> | 21 | #include <linux/usb/composite.h> |
22 | #include <asm/unaligned.h> | 22 | #include <asm/unaligned.h> |
23 | 23 | ||
24 | #include "u_os_desc.h" | ||
25 | |||
26 | /** | ||
27 | * struct usb_os_string - represents OS String to be reported by a gadget | ||
28 | * @bLength: total length of the entire descritor, always 0x12 | ||
29 | * @bDescriptorType: USB_DT_STRING | ||
30 | * @qwSignature: the OS String proper | ||
31 | * @bMS_VendorCode: code used by the host for subsequent requests | ||
32 | * @bPad: not used, must be zero | ||
33 | */ | ||
34 | struct usb_os_string { | ||
35 | __u8 bLength; | ||
36 | __u8 bDescriptorType; | ||
37 | __u8 qwSignature[OS_STRING_QW_SIGN_LEN]; | ||
38 | __u8 bMS_VendorCode; | ||
39 | __u8 bPad; | ||
40 | } __packed; | ||
41 | |||
24 | /* | 42 | /* |
25 | * The code in this file is utility code, used to build a gadget driver | 43 | * The code in this file is utility code, used to build a gadget driver |
26 | * from one or more "function" drivers, one or more "configuration" | 44 | * from one or more "function" drivers, one or more "configuration" |
@@ -422,6 +440,7 @@ static int config_desc(struct usb_composite_dev *cdev, unsigned w_value) | |||
422 | { | 440 | { |
423 | struct usb_gadget *gadget = cdev->gadget; | 441 | struct usb_gadget *gadget = cdev->gadget; |
424 | struct usb_configuration *c; | 442 | struct usb_configuration *c; |
443 | struct list_head *pos; | ||
425 | u8 type = w_value >> 8; | 444 | u8 type = w_value >> 8; |
426 | enum usb_device_speed speed = USB_SPEED_UNKNOWN; | 445 | enum usb_device_speed speed = USB_SPEED_UNKNOWN; |
427 | 446 | ||
@@ -440,7 +459,20 @@ static int config_desc(struct usb_composite_dev *cdev, unsigned w_value) | |||
440 | 459 | ||
441 | /* This is a lookup by config *INDEX* */ | 460 | /* This is a lookup by config *INDEX* */ |
442 | w_value &= 0xff; | 461 | w_value &= 0xff; |
443 | list_for_each_entry(c, &cdev->configs, list) { | 462 | |
463 | pos = &cdev->configs; | ||
464 | c = cdev->os_desc_config; | ||
465 | if (c) | ||
466 | goto check_config; | ||
467 | |||
468 | while ((pos = pos->next) != &cdev->configs) { | ||
469 | c = list_entry(pos, typeof(*c), list); | ||
470 | |||
471 | /* skip OS Descriptors config which is handled separately */ | ||
472 | if (c == cdev->os_desc_config) | ||
473 | continue; | ||
474 | |||
475 | check_config: | ||
444 | /* ignore configs that won't work at this speed */ | 476 | /* ignore configs that won't work at this speed */ |
445 | switch (speed) { | 477 | switch (speed) { |
446 | case USB_SPEED_SUPER: | 478 | case USB_SPEED_SUPER: |
@@ -634,6 +666,7 @@ static int set_config(struct usb_composite_dev *cdev, | |||
634 | if (!c) | 666 | if (!c) |
635 | goto done; | 667 | goto done; |
636 | 668 | ||
669 | usb_gadget_set_state(gadget, USB_STATE_CONFIGURED); | ||
637 | cdev->config = c; | 670 | cdev->config = c; |
638 | 671 | ||
639 | /* Initialize all interfaces by setting them to altsetting zero. */ | 672 | /* Initialize all interfaces by setting them to altsetting zero. */ |
@@ -960,6 +993,19 @@ static int get_string(struct usb_composite_dev *cdev, | |||
960 | return s->bLength; | 993 | return s->bLength; |
961 | } | 994 | } |
962 | 995 | ||
996 | if (cdev->use_os_string && language == 0 && id == OS_STRING_IDX) { | ||
997 | struct usb_os_string *b = buf; | ||
998 | b->bLength = sizeof(*b); | ||
999 | b->bDescriptorType = USB_DT_STRING; | ||
1000 | compiletime_assert( | ||
1001 | sizeof(b->qwSignature) == sizeof(cdev->qw_sign), | ||
1002 | "qwSignature size must be equal to qw_sign"); | ||
1003 | memcpy(&b->qwSignature, cdev->qw_sign, sizeof(b->qwSignature)); | ||
1004 | b->bMS_VendorCode = cdev->b_vendor_code; | ||
1005 | b->bPad = 0; | ||
1006 | return sizeof(*b); | ||
1007 | } | ||
1008 | |||
963 | list_for_each_entry(uc, &cdev->gstrings, list) { | 1009 | list_for_each_entry(uc, &cdev->gstrings, list) { |
964 | struct usb_gadget_strings **sp; | 1010 | struct usb_gadget_strings **sp; |
965 | 1011 | ||
@@ -1206,6 +1252,158 @@ static void composite_setup_complete(struct usb_ep *ep, struct usb_request *req) | |||
1206 | req->status, req->actual, req->length); | 1252 | req->status, req->actual, req->length); |
1207 | } | 1253 | } |
1208 | 1254 | ||
1255 | static int count_ext_compat(struct usb_configuration *c) | ||
1256 | { | ||
1257 | int i, res; | ||
1258 | |||
1259 | res = 0; | ||
1260 | for (i = 0; i < c->next_interface_id; ++i) { | ||
1261 | struct usb_function *f; | ||
1262 | int j; | ||
1263 | |||
1264 | f = c->interface[i]; | ||
1265 | for (j = 0; j < f->os_desc_n; ++j) { | ||
1266 | struct usb_os_desc *d; | ||
1267 | |||
1268 | if (i != f->os_desc_table[j].if_id) | ||
1269 | continue; | ||
1270 | d = f->os_desc_table[j].os_desc; | ||
1271 | if (d && d->ext_compat_id) | ||
1272 | ++res; | ||
1273 | } | ||
1274 | } | ||
1275 | BUG_ON(res > 255); | ||
1276 | return res; | ||
1277 | } | ||
1278 | |||
1279 | static void fill_ext_compat(struct usb_configuration *c, u8 *buf) | ||
1280 | { | ||
1281 | int i, count; | ||
1282 | |||
1283 | count = 16; | ||
1284 | for (i = 0; i < c->next_interface_id; ++i) { | ||
1285 | struct usb_function *f; | ||
1286 | int j; | ||
1287 | |||
1288 | f = c->interface[i]; | ||
1289 | for (j = 0; j < f->os_desc_n; ++j) { | ||
1290 | struct usb_os_desc *d; | ||
1291 | |||
1292 | if (i != f->os_desc_table[j].if_id) | ||
1293 | continue; | ||
1294 | d = f->os_desc_table[j].os_desc; | ||
1295 | if (d && d->ext_compat_id) { | ||
1296 | *buf++ = i; | ||
1297 | *buf++ = 0x01; | ||
1298 | memcpy(buf, d->ext_compat_id, 16); | ||
1299 | buf += 22; | ||
1300 | } else { | ||
1301 | ++buf; | ||
1302 | *buf = 0x01; | ||
1303 | buf += 23; | ||
1304 | } | ||
1305 | count += 24; | ||
1306 | if (count >= 4096) | ||
1307 | return; | ||
1308 | } | ||
1309 | } | ||
1310 | } | ||
1311 | |||
1312 | static int count_ext_prop(struct usb_configuration *c, int interface) | ||
1313 | { | ||
1314 | struct usb_function *f; | ||
1315 | int j, res; | ||
1316 | |||
1317 | res = 0; | ||
1318 | |||
1319 | f = c->interface[interface]; | ||
1320 | for (j = 0; j < f->os_desc_n; ++j) { | ||
1321 | struct usb_os_desc *d; | ||
1322 | |||
1323 | if (interface != f->os_desc_table[j].if_id) | ||
1324 | continue; | ||
1325 | d = f->os_desc_table[j].os_desc; | ||
1326 | if (d && d->ext_compat_id) | ||
1327 | return d->ext_prop_count; | ||
1328 | } | ||
1329 | return res; | ||
1330 | } | ||
1331 | |||
1332 | static int len_ext_prop(struct usb_configuration *c, int interface) | ||
1333 | { | ||
1334 | struct usb_function *f; | ||
1335 | struct usb_os_desc *d; | ||
1336 | int j, res; | ||
1337 | |||
1338 | res = 10; /* header length */ | ||
1339 | f = c->interface[interface]; | ||
1340 | for (j = 0; j < f->os_desc_n; ++j) { | ||
1341 | if (interface != f->os_desc_table[j].if_id) | ||
1342 | continue; | ||
1343 | d = f->os_desc_table[j].os_desc; | ||
1344 | if (d) | ||
1345 | return min(res + d->ext_prop_len, 4096); | ||
1346 | } | ||
1347 | return res; | ||
1348 | } | ||
1349 | |||
1350 | static int fill_ext_prop(struct usb_configuration *c, int interface, u8 *buf) | ||
1351 | { | ||
1352 | struct usb_function *f; | ||
1353 | struct usb_os_desc *d; | ||
1354 | struct usb_os_desc_ext_prop *ext_prop; | ||
1355 | int j, count, n, ret; | ||
1356 | u8 *start = buf; | ||
1357 | |||
1358 | f = c->interface[interface]; | ||
1359 | for (j = 0; j < f->os_desc_n; ++j) { | ||
1360 | if (interface != f->os_desc_table[j].if_id) | ||
1361 | continue; | ||
1362 | d = f->os_desc_table[j].os_desc; | ||
1363 | if (d) | ||
1364 | list_for_each_entry(ext_prop, &d->ext_prop, entry) { | ||
1365 | /* 4kB minus header length */ | ||
1366 | n = buf - start; | ||
1367 | if (n >= 4086) | ||
1368 | return 0; | ||
1369 | |||
1370 | count = ext_prop->data_len + | ||
1371 | ext_prop->name_len + 14; | ||
1372 | if (count > 4086 - n) | ||
1373 | return -EINVAL; | ||
1374 | usb_ext_prop_put_size(buf, count); | ||
1375 | usb_ext_prop_put_type(buf, ext_prop->type); | ||
1376 | ret = usb_ext_prop_put_name(buf, ext_prop->name, | ||
1377 | ext_prop->name_len); | ||
1378 | if (ret < 0) | ||
1379 | return ret; | ||
1380 | switch (ext_prop->type) { | ||
1381 | case USB_EXT_PROP_UNICODE: | ||
1382 | case USB_EXT_PROP_UNICODE_ENV: | ||
1383 | case USB_EXT_PROP_UNICODE_LINK: | ||
1384 | usb_ext_prop_put_unicode(buf, ret, | ||
1385 | ext_prop->data, | ||
1386 | ext_prop->data_len); | ||
1387 | break; | ||
1388 | case USB_EXT_PROP_BINARY: | ||
1389 | usb_ext_prop_put_binary(buf, ret, | ||
1390 | ext_prop->data, | ||
1391 | ext_prop->data_len); | ||
1392 | break; | ||
1393 | case USB_EXT_PROP_LE32: | ||
1394 | /* not implemented */ | ||
1395 | case USB_EXT_PROP_BE32: | ||
1396 | /* not implemented */ | ||
1397 | default: | ||
1398 | return -EINVAL; | ||
1399 | } | ||
1400 | buf += count; | ||
1401 | } | ||
1402 | } | ||
1403 | |||
1404 | return 0; | ||
1405 | } | ||
1406 | |||
1209 | /* | 1407 | /* |
1210 | * The setup() callback implements all the ep0 functionality that's | 1408 | * The setup() callback implements all the ep0 functionality that's |
1211 | * not handled lower down, in hardware or the hardware driver(like | 1409 | * not handled lower down, in hardware or the hardware driver(like |
@@ -1415,6 +1613,91 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
1415 | break; | 1613 | break; |
1416 | default: | 1614 | default: |
1417 | unknown: | 1615 | unknown: |
1616 | /* | ||
1617 | * OS descriptors handling | ||
1618 | */ | ||
1619 | if (cdev->use_os_string && cdev->os_desc_config && | ||
1620 | (ctrl->bRequest & USB_TYPE_VENDOR) && | ||
1621 | ctrl->bRequest == cdev->b_vendor_code) { | ||
1622 | struct usb_request *req; | ||
1623 | struct usb_configuration *os_desc_cfg; | ||
1624 | u8 *buf; | ||
1625 | int interface; | ||
1626 | int count = 0; | ||
1627 | |||
1628 | req = cdev->os_desc_req; | ||
1629 | req->complete = composite_setup_complete; | ||
1630 | buf = req->buf; | ||
1631 | os_desc_cfg = cdev->os_desc_config; | ||
1632 | memset(buf, 0, w_length); | ||
1633 | buf[5] = 0x01; | ||
1634 | switch (ctrl->bRequestType & USB_RECIP_MASK) { | ||
1635 | case USB_RECIP_DEVICE: | ||
1636 | if (w_index != 0x4 || (w_value >> 8)) | ||
1637 | break; | ||
1638 | buf[6] = w_index; | ||
1639 | if (w_length == 0x10) { | ||
1640 | /* Number of ext compat interfaces */ | ||
1641 | count = count_ext_compat(os_desc_cfg); | ||
1642 | buf[8] = count; | ||
1643 | count *= 24; /* 24 B/ext compat desc */ | ||
1644 | count += 16; /* header */ | ||
1645 | put_unaligned_le32(count, buf); | ||
1646 | value = w_length; | ||
1647 | } else { | ||
1648 | /* "extended compatibility ID"s */ | ||
1649 | count = count_ext_compat(os_desc_cfg); | ||
1650 | buf[8] = count; | ||
1651 | count *= 24; /* 24 B/ext compat desc */ | ||
1652 | count += 16; /* header */ | ||
1653 | put_unaligned_le32(count, buf); | ||
1654 | buf += 16; | ||
1655 | fill_ext_compat(os_desc_cfg, buf); | ||
1656 | value = w_length; | ||
1657 | } | ||
1658 | break; | ||
1659 | case USB_RECIP_INTERFACE: | ||
1660 | if (w_index != 0x5 || (w_value >> 8)) | ||
1661 | break; | ||
1662 | interface = w_value & 0xFF; | ||
1663 | buf[6] = w_index; | ||
1664 | if (w_length == 0x0A) { | ||
1665 | count = count_ext_prop(os_desc_cfg, | ||
1666 | interface); | ||
1667 | put_unaligned_le16(count, buf + 8); | ||
1668 | count = len_ext_prop(os_desc_cfg, | ||
1669 | interface); | ||
1670 | put_unaligned_le32(count, buf); | ||
1671 | |||
1672 | value = w_length; | ||
1673 | } else { | ||
1674 | count = count_ext_prop(os_desc_cfg, | ||
1675 | interface); | ||
1676 | put_unaligned_le16(count, buf + 8); | ||
1677 | count = len_ext_prop(os_desc_cfg, | ||
1678 | interface); | ||
1679 | put_unaligned_le32(count, buf); | ||
1680 | buf += 10; | ||
1681 | value = fill_ext_prop(os_desc_cfg, | ||
1682 | interface, buf); | ||
1683 | if (value < 0) | ||
1684 | return value; | ||
1685 | |||
1686 | value = w_length; | ||
1687 | } | ||
1688 | break; | ||
1689 | } | ||
1690 | req->length = value; | ||
1691 | req->zero = value < w_length; | ||
1692 | value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); | ||
1693 | if (value < 0) { | ||
1694 | DBG(cdev, "ep_queue --> %d\n", value); | ||
1695 | req->status = 0; | ||
1696 | composite_setup_complete(gadget->ep0, req); | ||
1697 | } | ||
1698 | return value; | ||
1699 | } | ||
1700 | |||
1418 | VDBG(cdev, | 1701 | VDBG(cdev, |
1419 | "non-core control req%02x.%02x v%04x i%04x l%d\n", | 1702 | "non-core control req%02x.%02x v%04x i%04x l%d\n", |
1420 | ctrl->bRequestType, ctrl->bRequest, | 1703 | ctrl->bRequestType, ctrl->bRequest, |
@@ -1638,6 +1921,29 @@ fail: | |||
1638 | return ret; | 1921 | return ret; |
1639 | } | 1922 | } |
1640 | 1923 | ||
1924 | int composite_os_desc_req_prepare(struct usb_composite_dev *cdev, | ||
1925 | struct usb_ep *ep0) | ||
1926 | { | ||
1927 | int ret = 0; | ||
1928 | |||
1929 | cdev->os_desc_req = usb_ep_alloc_request(ep0, GFP_KERNEL); | ||
1930 | if (!cdev->os_desc_req) { | ||
1931 | ret = PTR_ERR(cdev->os_desc_req); | ||
1932 | goto end; | ||
1933 | } | ||
1934 | |||
1935 | /* OS feature descriptor length <= 4kB */ | ||
1936 | cdev->os_desc_req->buf = kmalloc(4096, GFP_KERNEL); | ||
1937 | if (!cdev->os_desc_req->buf) { | ||
1938 | ret = PTR_ERR(cdev->os_desc_req->buf); | ||
1939 | kfree(cdev->os_desc_req); | ||
1940 | goto end; | ||
1941 | } | ||
1942 | cdev->os_desc_req->complete = composite_setup_complete; | ||
1943 | end: | ||
1944 | return ret; | ||
1945 | } | ||
1946 | |||
1641 | void composite_dev_cleanup(struct usb_composite_dev *cdev) | 1947 | void composite_dev_cleanup(struct usb_composite_dev *cdev) |
1642 | { | 1948 | { |
1643 | struct usb_gadget_string_container *uc, *tmp; | 1949 | struct usb_gadget_string_container *uc, *tmp; |
@@ -1646,6 +1952,10 @@ void composite_dev_cleanup(struct usb_composite_dev *cdev) | |||
1646 | list_del(&uc->list); | 1952 | list_del(&uc->list); |
1647 | kfree(uc); | 1953 | kfree(uc); |
1648 | } | 1954 | } |
1955 | if (cdev->os_desc_req) { | ||
1956 | kfree(cdev->os_desc_req->buf); | ||
1957 | usb_ep_free_request(cdev->gadget->ep0, cdev->os_desc_req); | ||
1958 | } | ||
1649 | if (cdev->req) { | 1959 | if (cdev->req) { |
1650 | kfree(cdev->req->buf); | 1960 | kfree(cdev->req->buf); |
1651 | usb_ep_free_request(cdev->gadget->ep0, cdev->req); | 1961 | usb_ep_free_request(cdev->gadget->ep0, cdev->req); |
@@ -1683,6 +1993,12 @@ static int composite_bind(struct usb_gadget *gadget, | |||
1683 | if (status < 0) | 1993 | if (status < 0) |
1684 | goto fail; | 1994 | goto fail; |
1685 | 1995 | ||
1996 | if (cdev->use_os_string) { | ||
1997 | status = composite_os_desc_req_prepare(cdev, gadget->ep0); | ||
1998 | if (status) | ||
1999 | goto fail; | ||
2000 | } | ||
2001 | |||
1686 | update_unchanged_dev_desc(&cdev->desc, composite->dev); | 2002 | update_unchanged_dev_desc(&cdev->desc, composite->dev); |
1687 | 2003 | ||
1688 | /* has userspace failed to provide a serial number? */ | 2004 | /* has userspace failed to provide a serial number? */ |
diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index 7d1cc01796b6..2ddcd635ca2a 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c | |||
@@ -2,9 +2,12 @@ | |||
2 | #include <linux/module.h> | 2 | #include <linux/module.h> |
3 | #include <linux/slab.h> | 3 | #include <linux/slab.h> |
4 | #include <linux/device.h> | 4 | #include <linux/device.h> |
5 | #include <linux/nls.h> | ||
5 | #include <linux/usb/composite.h> | 6 | #include <linux/usb/composite.h> |
6 | #include <linux/usb/gadget_configfs.h> | 7 | #include <linux/usb/gadget_configfs.h> |
7 | #include "configfs.h" | 8 | #include "configfs.h" |
9 | #include "u_f.h" | ||
10 | #include "u_os_desc.h" | ||
8 | 11 | ||
9 | int check_user_usb_string(const char *name, | 12 | int check_user_usb_string(const char *name, |
10 | struct usb_gadget_strings *stringtab_dev) | 13 | struct usb_gadget_strings *stringtab_dev) |
@@ -43,7 +46,8 @@ struct gadget_info { | |||
43 | struct config_group functions_group; | 46 | struct config_group functions_group; |
44 | struct config_group configs_group; | 47 | struct config_group configs_group; |
45 | struct config_group strings_group; | 48 | struct config_group strings_group; |
46 | struct config_group *default_groups[4]; | 49 | struct config_group os_desc_group; |
50 | struct config_group *default_groups[5]; | ||
47 | 51 | ||
48 | struct mutex lock; | 52 | struct mutex lock; |
49 | struct usb_gadget_strings *gstrings[MAX_USB_STRING_LANGS + 1]; | 53 | struct usb_gadget_strings *gstrings[MAX_USB_STRING_LANGS + 1]; |
@@ -56,6 +60,9 @@ struct gadget_info { | |||
56 | #endif | 60 | #endif |
57 | struct usb_composite_driver composite; | 61 | struct usb_composite_driver composite; |
58 | struct usb_composite_dev cdev; | 62 | struct usb_composite_dev cdev; |
63 | bool use_os_desc; | ||
64 | char b_vendor_code; | ||
65 | char qw_sign[OS_STRING_QW_SIGN_LEN]; | ||
59 | }; | 66 | }; |
60 | 67 | ||
61 | struct config_usb_cfg { | 68 | struct config_usb_cfg { |
@@ -79,6 +86,10 @@ struct gadget_strings { | |||
79 | struct list_head list; | 86 | struct list_head list; |
80 | }; | 87 | }; |
81 | 88 | ||
89 | struct os_desc { | ||
90 | struct config_group group; | ||
91 | }; | ||
92 | |||
82 | struct gadget_config_name { | 93 | struct gadget_config_name { |
83 | struct usb_gadget_strings stringtab_dev; | 94 | struct usb_gadget_strings stringtab_dev; |
84 | struct usb_string strings; | 95 | struct usb_string strings; |
@@ -736,6 +747,525 @@ static void gadget_strings_attr_release(struct config_item *item) | |||
736 | USB_CONFIG_STRING_RW_OPS(gadget_strings); | 747 | USB_CONFIG_STRING_RW_OPS(gadget_strings); |
737 | USB_CONFIG_STRINGS_LANG(gadget_strings, gadget_info); | 748 | USB_CONFIG_STRINGS_LANG(gadget_strings, gadget_info); |
738 | 749 | ||
750 | static inline struct os_desc *to_os_desc(struct config_item *item) | ||
751 | { | ||
752 | return container_of(to_config_group(item), struct os_desc, group); | ||
753 | } | ||
754 | |||
755 | CONFIGFS_ATTR_STRUCT(os_desc); | ||
756 | CONFIGFS_ATTR_OPS(os_desc); | ||
757 | |||
758 | static ssize_t os_desc_use_show(struct os_desc *os_desc, char *page) | ||
759 | { | ||
760 | struct gadget_info *gi; | ||
761 | |||
762 | gi = to_gadget_info(os_desc->group.cg_item.ci_parent); | ||
763 | |||
764 | return sprintf(page, "%d", gi->use_os_desc); | ||
765 | } | ||
766 | |||
767 | static ssize_t os_desc_use_store(struct os_desc *os_desc, const char *page, | ||
768 | size_t len) | ||
769 | { | ||
770 | struct gadget_info *gi; | ||
771 | int ret; | ||
772 | bool use; | ||
773 | |||
774 | gi = to_gadget_info(os_desc->group.cg_item.ci_parent); | ||
775 | |||
776 | mutex_lock(&gi->lock); | ||
777 | ret = strtobool(page, &use); | ||
778 | if (!ret) { | ||
779 | gi->use_os_desc = use; | ||
780 | ret = len; | ||
781 | } | ||
782 | mutex_unlock(&gi->lock); | ||
783 | |||
784 | return ret; | ||
785 | } | ||
786 | |||
787 | static struct os_desc_attribute os_desc_use = | ||
788 | __CONFIGFS_ATTR(use, S_IRUGO | S_IWUSR, | ||
789 | os_desc_use_show, | ||
790 | os_desc_use_store); | ||
791 | |||
792 | static ssize_t os_desc_b_vendor_code_show(struct os_desc *os_desc, char *page) | ||
793 | { | ||
794 | struct gadget_info *gi; | ||
795 | |||
796 | gi = to_gadget_info(os_desc->group.cg_item.ci_parent); | ||
797 | |||
798 | return sprintf(page, "%d", gi->b_vendor_code); | ||
799 | } | ||
800 | |||
801 | static ssize_t os_desc_b_vendor_code_store(struct os_desc *os_desc, | ||
802 | const char *page, size_t len) | ||
803 | { | ||
804 | struct gadget_info *gi; | ||
805 | int ret; | ||
806 | u8 b_vendor_code; | ||
807 | |||
808 | gi = to_gadget_info(os_desc->group.cg_item.ci_parent); | ||
809 | |||
810 | mutex_lock(&gi->lock); | ||
811 | ret = kstrtou8(page, 0, &b_vendor_code); | ||
812 | if (!ret) { | ||
813 | gi->b_vendor_code = b_vendor_code; | ||
814 | ret = len; | ||
815 | } | ||
816 | mutex_unlock(&gi->lock); | ||
817 | |||
818 | return ret; | ||
819 | } | ||
820 | |||
821 | static struct os_desc_attribute os_desc_b_vendor_code = | ||
822 | __CONFIGFS_ATTR(b_vendor_code, S_IRUGO | S_IWUSR, | ||
823 | os_desc_b_vendor_code_show, | ||
824 | os_desc_b_vendor_code_store); | ||
825 | |||
826 | static ssize_t os_desc_qw_sign_show(struct os_desc *os_desc, char *page) | ||
827 | { | ||
828 | struct gadget_info *gi; | ||
829 | |||
830 | gi = to_gadget_info(os_desc->group.cg_item.ci_parent); | ||
831 | |||
832 | memcpy(page, gi->qw_sign, OS_STRING_QW_SIGN_LEN); | ||
833 | |||
834 | return OS_STRING_QW_SIGN_LEN; | ||
835 | } | ||
836 | |||
837 | static ssize_t os_desc_qw_sign_store(struct os_desc *os_desc, const char *page, | ||
838 | size_t len) | ||
839 | { | ||
840 | struct gadget_info *gi; | ||
841 | int res, l; | ||
842 | |||
843 | gi = to_gadget_info(os_desc->group.cg_item.ci_parent); | ||
844 | l = min((int)len, OS_STRING_QW_SIGN_LEN >> 1); | ||
845 | if (page[l - 1] == '\n') | ||
846 | --l; | ||
847 | |||
848 | mutex_lock(&gi->lock); | ||
849 | res = utf8s_to_utf16s(page, l, | ||
850 | UTF16_LITTLE_ENDIAN, (wchar_t *) gi->qw_sign, | ||
851 | OS_STRING_QW_SIGN_LEN); | ||
852 | if (res > 0) | ||
853 | res = len; | ||
854 | mutex_unlock(&gi->lock); | ||
855 | |||
856 | return res; | ||
857 | } | ||
858 | |||
859 | static struct os_desc_attribute os_desc_qw_sign = | ||
860 | __CONFIGFS_ATTR(qw_sign, S_IRUGO | S_IWUSR, | ||
861 | os_desc_qw_sign_show, | ||
862 | os_desc_qw_sign_store); | ||
863 | |||
864 | static struct configfs_attribute *os_desc_attrs[] = { | ||
865 | &os_desc_use.attr, | ||
866 | &os_desc_b_vendor_code.attr, | ||
867 | &os_desc_qw_sign.attr, | ||
868 | NULL, | ||
869 | }; | ||
870 | |||
871 | static void os_desc_attr_release(struct config_item *item) | ||
872 | { | ||
873 | struct os_desc *os_desc = to_os_desc(item); | ||
874 | kfree(os_desc); | ||
875 | } | ||
876 | |||
877 | static int os_desc_link(struct config_item *os_desc_ci, | ||
878 | struct config_item *usb_cfg_ci) | ||
879 | { | ||
880 | struct gadget_info *gi = container_of(to_config_group(os_desc_ci), | ||
881 | struct gadget_info, os_desc_group); | ||
882 | struct usb_composite_dev *cdev = &gi->cdev; | ||
883 | struct config_usb_cfg *c_target = | ||
884 | container_of(to_config_group(usb_cfg_ci), | ||
885 | struct config_usb_cfg, group); | ||
886 | struct usb_configuration *c; | ||
887 | int ret; | ||
888 | |||
889 | mutex_lock(&gi->lock); | ||
890 | list_for_each_entry(c, &cdev->configs, list) { | ||
891 | if (c == &c_target->c) | ||
892 | break; | ||
893 | } | ||
894 | if (c != &c_target->c) { | ||
895 | ret = -EINVAL; | ||
896 | goto out; | ||
897 | } | ||
898 | |||
899 | if (cdev->os_desc_config) { | ||
900 | ret = -EBUSY; | ||
901 | goto out; | ||
902 | } | ||
903 | |||
904 | cdev->os_desc_config = &c_target->c; | ||
905 | ret = 0; | ||
906 | |||
907 | out: | ||
908 | mutex_unlock(&gi->lock); | ||
909 | return ret; | ||
910 | } | ||
911 | |||
912 | static int os_desc_unlink(struct config_item *os_desc_ci, | ||
913 | struct config_item *usb_cfg_ci) | ||
914 | { | ||
915 | struct gadget_info *gi = container_of(to_config_group(os_desc_ci), | ||
916 | struct gadget_info, os_desc_group); | ||
917 | struct usb_composite_dev *cdev = &gi->cdev; | ||
918 | |||
919 | mutex_lock(&gi->lock); | ||
920 | if (gi->udc_name) | ||
921 | unregister_gadget(gi); | ||
922 | cdev->os_desc_config = NULL; | ||
923 | WARN_ON(gi->udc_name); | ||
924 | mutex_unlock(&gi->lock); | ||
925 | return 0; | ||
926 | } | ||
927 | |||
928 | static struct configfs_item_operations os_desc_ops = { | ||
929 | .release = os_desc_attr_release, | ||
930 | .show_attribute = os_desc_attr_show, | ||
931 | .store_attribute = os_desc_attr_store, | ||
932 | .allow_link = os_desc_link, | ||
933 | .drop_link = os_desc_unlink, | ||
934 | }; | ||
935 | |||
936 | static struct config_item_type os_desc_type = { | ||
937 | .ct_item_ops = &os_desc_ops, | ||
938 | .ct_attrs = os_desc_attrs, | ||
939 | .ct_owner = THIS_MODULE, | ||
940 | }; | ||
941 | |||
942 | CONFIGFS_ATTR_STRUCT(usb_os_desc); | ||
943 | CONFIGFS_ATTR_OPS(usb_os_desc); | ||
944 | |||
945 | |||
946 | static inline struct usb_os_desc_ext_prop | ||
947 | *to_usb_os_desc_ext_prop(struct config_item *item) | ||
948 | { | ||
949 | return container_of(item, struct usb_os_desc_ext_prop, item); | ||
950 | } | ||
951 | |||
952 | CONFIGFS_ATTR_STRUCT(usb_os_desc_ext_prop); | ||
953 | CONFIGFS_ATTR_OPS(usb_os_desc_ext_prop); | ||
954 | |||
955 | static ssize_t ext_prop_type_show(struct usb_os_desc_ext_prop *ext_prop, | ||
956 | char *page) | ||
957 | { | ||
958 | return sprintf(page, "%d", ext_prop->type); | ||
959 | } | ||
960 | |||
961 | static ssize_t ext_prop_type_store(struct usb_os_desc_ext_prop *ext_prop, | ||
962 | const char *page, size_t len) | ||
963 | { | ||
964 | struct usb_os_desc *desc = to_usb_os_desc(ext_prop->item.ci_parent); | ||
965 | u8 type; | ||
966 | int ret; | ||
967 | |||
968 | if (desc->opts_mutex) | ||
969 | mutex_lock(desc->opts_mutex); | ||
970 | ret = kstrtou8(page, 0, &type); | ||
971 | if (ret) | ||
972 | goto end; | ||
973 | if (type < USB_EXT_PROP_UNICODE || type > USB_EXT_PROP_UNICODE_MULTI) { | ||
974 | ret = -EINVAL; | ||
975 | goto end; | ||
976 | } | ||
977 | |||
978 | if ((ext_prop->type == USB_EXT_PROP_BINARY || | ||
979 | ext_prop->type == USB_EXT_PROP_LE32 || | ||
980 | ext_prop->type == USB_EXT_PROP_BE32) && | ||
981 | (type == USB_EXT_PROP_UNICODE || | ||
982 | type == USB_EXT_PROP_UNICODE_ENV || | ||
983 | type == USB_EXT_PROP_UNICODE_LINK)) | ||
984 | ext_prop->data_len <<= 1; | ||
985 | else if ((ext_prop->type == USB_EXT_PROP_UNICODE || | ||
986 | ext_prop->type == USB_EXT_PROP_UNICODE_ENV || | ||
987 | ext_prop->type == USB_EXT_PROP_UNICODE_LINK) && | ||
988 | (type == USB_EXT_PROP_BINARY || | ||
989 | type == USB_EXT_PROP_LE32 || | ||
990 | type == USB_EXT_PROP_BE32)) | ||
991 | ext_prop->data_len >>= 1; | ||
992 | ext_prop->type = type; | ||
993 | ret = len; | ||
994 | |||
995 | end: | ||
996 | if (desc->opts_mutex) | ||
997 | mutex_unlock(desc->opts_mutex); | ||
998 | return ret; | ||
999 | } | ||
1000 | |||
1001 | static ssize_t ext_prop_data_show(struct usb_os_desc_ext_prop *ext_prop, | ||
1002 | char *page) | ||
1003 | { | ||
1004 | int len = ext_prop->data_len; | ||
1005 | |||
1006 | if (ext_prop->type == USB_EXT_PROP_UNICODE || | ||
1007 | ext_prop->type == USB_EXT_PROP_UNICODE_ENV || | ||
1008 | ext_prop->type == USB_EXT_PROP_UNICODE_LINK) | ||
1009 | len >>= 1; | ||
1010 | memcpy(page, ext_prop->data, len); | ||
1011 | |||
1012 | return len; | ||
1013 | } | ||
1014 | |||
1015 | static ssize_t ext_prop_data_store(struct usb_os_desc_ext_prop *ext_prop, | ||
1016 | const char *page, size_t len) | ||
1017 | { | ||
1018 | struct usb_os_desc *desc = to_usb_os_desc(ext_prop->item.ci_parent); | ||
1019 | char *new_data; | ||
1020 | size_t ret_len = len; | ||
1021 | |||
1022 | if (page[len - 1] == '\n' || page[len - 1] == '\0') | ||
1023 | --len; | ||
1024 | new_data = kzalloc(len, GFP_KERNEL); | ||
1025 | if (!new_data) | ||
1026 | return -ENOMEM; | ||
1027 | |||
1028 | memcpy(new_data, page, len); | ||
1029 | |||
1030 | if (desc->opts_mutex) | ||
1031 | mutex_lock(desc->opts_mutex); | ||
1032 | kfree(ext_prop->data); | ||
1033 | ext_prop->data = new_data; | ||
1034 | desc->ext_prop_len -= ext_prop->data_len; | ||
1035 | ext_prop->data_len = len; | ||
1036 | desc->ext_prop_len += ext_prop->data_len; | ||
1037 | if (ext_prop->type == USB_EXT_PROP_UNICODE || | ||
1038 | ext_prop->type == USB_EXT_PROP_UNICODE_ENV || | ||
1039 | ext_prop->type == USB_EXT_PROP_UNICODE_LINK) { | ||
1040 | desc->ext_prop_len -= ext_prop->data_len; | ||
1041 | ext_prop->data_len <<= 1; | ||
1042 | ext_prop->data_len += 2; | ||
1043 | desc->ext_prop_len += ext_prop->data_len; | ||
1044 | } | ||
1045 | if (desc->opts_mutex) | ||
1046 | mutex_unlock(desc->opts_mutex); | ||
1047 | return ret_len; | ||
1048 | } | ||
1049 | |||
1050 | static struct usb_os_desc_ext_prop_attribute ext_prop_type = | ||
1051 | __CONFIGFS_ATTR(type, S_IRUGO | S_IWUSR, | ||
1052 | ext_prop_type_show, ext_prop_type_store); | ||
1053 | |||
1054 | static struct usb_os_desc_ext_prop_attribute ext_prop_data = | ||
1055 | __CONFIGFS_ATTR(data, S_IRUGO | S_IWUSR, | ||
1056 | ext_prop_data_show, ext_prop_data_store); | ||
1057 | |||
1058 | static struct configfs_attribute *ext_prop_attrs[] = { | ||
1059 | &ext_prop_type.attr, | ||
1060 | &ext_prop_data.attr, | ||
1061 | NULL, | ||
1062 | }; | ||
1063 | |||
1064 | static void usb_os_desc_ext_prop_release(struct config_item *item) | ||
1065 | { | ||
1066 | struct usb_os_desc_ext_prop *ext_prop = to_usb_os_desc_ext_prop(item); | ||
1067 | |||
1068 | kfree(ext_prop); /* frees a whole chunk */ | ||
1069 | } | ||
1070 | |||
1071 | static struct configfs_item_operations ext_prop_ops = { | ||
1072 | .release = usb_os_desc_ext_prop_release, | ||
1073 | .show_attribute = usb_os_desc_ext_prop_attr_show, | ||
1074 | .store_attribute = usb_os_desc_ext_prop_attr_store, | ||
1075 | }; | ||
1076 | |||
1077 | static struct config_item *ext_prop_make( | ||
1078 | struct config_group *group, | ||
1079 | const char *name) | ||
1080 | { | ||
1081 | struct usb_os_desc_ext_prop *ext_prop; | ||
1082 | struct config_item_type *ext_prop_type; | ||
1083 | struct usb_os_desc *desc; | ||
1084 | char *vlabuf; | ||
1085 | |||
1086 | vla_group(data_chunk); | ||
1087 | vla_item(data_chunk, struct usb_os_desc_ext_prop, ext_prop, 1); | ||
1088 | vla_item(data_chunk, struct config_item_type, ext_prop_type, 1); | ||
1089 | |||
1090 | vlabuf = kzalloc(vla_group_size(data_chunk), GFP_KERNEL); | ||
1091 | if (!vlabuf) | ||
1092 | return ERR_PTR(-ENOMEM); | ||
1093 | |||
1094 | ext_prop = vla_ptr(vlabuf, data_chunk, ext_prop); | ||
1095 | ext_prop_type = vla_ptr(vlabuf, data_chunk, ext_prop_type); | ||
1096 | |||
1097 | desc = container_of(group, struct usb_os_desc, group); | ||
1098 | ext_prop_type->ct_item_ops = &ext_prop_ops; | ||
1099 | ext_prop_type->ct_attrs = ext_prop_attrs; | ||
1100 | ext_prop_type->ct_owner = desc->owner; | ||
1101 | |||
1102 | config_item_init_type_name(&ext_prop->item, name, ext_prop_type); | ||
1103 | |||
1104 | ext_prop->name = kstrdup(name, GFP_KERNEL); | ||
1105 | if (!ext_prop->name) { | ||
1106 | kfree(vlabuf); | ||
1107 | return ERR_PTR(-ENOMEM); | ||
1108 | } | ||
1109 | desc->ext_prop_len += 14; | ||
1110 | ext_prop->name_len = 2 * strlen(ext_prop->name) + 2; | ||
1111 | if (desc->opts_mutex) | ||
1112 | mutex_lock(desc->opts_mutex); | ||
1113 | desc->ext_prop_len += ext_prop->name_len; | ||
1114 | list_add_tail(&ext_prop->entry, &desc->ext_prop); | ||
1115 | ++desc->ext_prop_count; | ||
1116 | if (desc->opts_mutex) | ||
1117 | mutex_unlock(desc->opts_mutex); | ||
1118 | |||
1119 | return &ext_prop->item; | ||
1120 | } | ||
1121 | |||
1122 | static void ext_prop_drop(struct config_group *group, struct config_item *item) | ||
1123 | { | ||
1124 | struct usb_os_desc_ext_prop *ext_prop = to_usb_os_desc_ext_prop(item); | ||
1125 | struct usb_os_desc *desc = to_usb_os_desc(&group->cg_item); | ||
1126 | |||
1127 | if (desc->opts_mutex) | ||
1128 | mutex_lock(desc->opts_mutex); | ||
1129 | list_del(&ext_prop->entry); | ||
1130 | --desc->ext_prop_count; | ||
1131 | kfree(ext_prop->name); | ||
1132 | desc->ext_prop_len -= (ext_prop->name_len + ext_prop->data_len + 14); | ||
1133 | if (desc->opts_mutex) | ||
1134 | mutex_unlock(desc->opts_mutex); | ||
1135 | config_item_put(item); | ||
1136 | } | ||
1137 | |||
1138 | static struct configfs_group_operations interf_grp_ops = { | ||
1139 | .make_item = &ext_prop_make, | ||
1140 | .drop_item = &ext_prop_drop, | ||
1141 | }; | ||
1142 | |||
1143 | static struct configfs_item_operations interf_item_ops = { | ||
1144 | .show_attribute = usb_os_desc_attr_show, | ||
1145 | .store_attribute = usb_os_desc_attr_store, | ||
1146 | }; | ||
1147 | |||
1148 | static ssize_t rndis_grp_compatible_id_show(struct usb_os_desc *desc, | ||
1149 | char *page) | ||
1150 | { | ||
1151 | memcpy(page, desc->ext_compat_id, 8); | ||
1152 | return 8; | ||
1153 | } | ||
1154 | |||
1155 | static ssize_t rndis_grp_compatible_id_store(struct usb_os_desc *desc, | ||
1156 | const char *page, size_t len) | ||
1157 | { | ||
1158 | int l; | ||
1159 | |||
1160 | l = min_t(int, 8, len); | ||
1161 | if (page[l - 1] == '\n') | ||
1162 | --l; | ||
1163 | if (desc->opts_mutex) | ||
1164 | mutex_lock(desc->opts_mutex); | ||
1165 | memcpy(desc->ext_compat_id, page, l); | ||
1166 | desc->ext_compat_id[l] = '\0'; | ||
1167 | |||
1168 | if (desc->opts_mutex) | ||
1169 | mutex_unlock(desc->opts_mutex); | ||
1170 | |||
1171 | return len; | ||
1172 | } | ||
1173 | |||
1174 | static struct usb_os_desc_attribute rndis_grp_attr_compatible_id = | ||
1175 | __CONFIGFS_ATTR(compatible_id, S_IRUGO | S_IWUSR, | ||
1176 | rndis_grp_compatible_id_show, | ||
1177 | rndis_grp_compatible_id_store); | ||
1178 | |||
1179 | static ssize_t rndis_grp_sub_compatible_id_show(struct usb_os_desc *desc, | ||
1180 | char *page) | ||
1181 | { | ||
1182 | memcpy(page, desc->ext_compat_id + 8, 8); | ||
1183 | return 8; | ||
1184 | } | ||
1185 | |||
1186 | static ssize_t rndis_grp_sub_compatible_id_store(struct usb_os_desc *desc, | ||
1187 | const char *page, size_t len) | ||
1188 | { | ||
1189 | int l; | ||
1190 | |||
1191 | l = min_t(int, 8, len); | ||
1192 | if (page[l - 1] == '\n') | ||
1193 | --l; | ||
1194 | if (desc->opts_mutex) | ||
1195 | mutex_lock(desc->opts_mutex); | ||
1196 | memcpy(desc->ext_compat_id + 8, page, l); | ||
1197 | desc->ext_compat_id[l + 8] = '\0'; | ||
1198 | |||
1199 | if (desc->opts_mutex) | ||
1200 | mutex_unlock(desc->opts_mutex); | ||
1201 | |||
1202 | return len; | ||
1203 | } | ||
1204 | |||
1205 | static struct usb_os_desc_attribute rndis_grp_attr_sub_compatible_id = | ||
1206 | __CONFIGFS_ATTR(sub_compatible_id, S_IRUGO | S_IWUSR, | ||
1207 | rndis_grp_sub_compatible_id_show, | ||
1208 | rndis_grp_sub_compatible_id_store); | ||
1209 | |||
1210 | static struct configfs_attribute *interf_grp_attrs[] = { | ||
1211 | &rndis_grp_attr_compatible_id.attr, | ||
1212 | &rndis_grp_attr_sub_compatible_id.attr, | ||
1213 | NULL | ||
1214 | }; | ||
1215 | |||
1216 | int usb_os_desc_prepare_interf_dir(struct config_group *parent, | ||
1217 | int n_interf, | ||
1218 | struct usb_os_desc **desc, | ||
1219 | struct module *owner) | ||
1220 | { | ||
1221 | struct config_group **f_default_groups, *os_desc_group, | ||
1222 | **interface_groups; | ||
1223 | struct config_item_type *os_desc_type, *interface_type; | ||
1224 | |||
1225 | vla_group(data_chunk); | ||
1226 | vla_item(data_chunk, struct config_group *, f_default_groups, 2); | ||
1227 | vla_item(data_chunk, struct config_group, os_desc_group, 1); | ||
1228 | vla_item(data_chunk, struct config_group *, interface_groups, | ||
1229 | n_interf + 1); | ||
1230 | vla_item(data_chunk, struct config_item_type, os_desc_type, 1); | ||
1231 | vla_item(data_chunk, struct config_item_type, interface_type, 1); | ||
1232 | |||
1233 | char *vlabuf = kzalloc(vla_group_size(data_chunk), GFP_KERNEL); | ||
1234 | if (!vlabuf) | ||
1235 | return -ENOMEM; | ||
1236 | |||
1237 | f_default_groups = vla_ptr(vlabuf, data_chunk, f_default_groups); | ||
1238 | os_desc_group = vla_ptr(vlabuf, data_chunk, os_desc_group); | ||
1239 | os_desc_type = vla_ptr(vlabuf, data_chunk, os_desc_type); | ||
1240 | interface_groups = vla_ptr(vlabuf, data_chunk, interface_groups); | ||
1241 | interface_type = vla_ptr(vlabuf, data_chunk, interface_type); | ||
1242 | |||
1243 | parent->default_groups = f_default_groups; | ||
1244 | os_desc_type->ct_owner = owner; | ||
1245 | config_group_init_type_name(os_desc_group, "os_desc", os_desc_type); | ||
1246 | f_default_groups[0] = os_desc_group; | ||
1247 | |||
1248 | os_desc_group->default_groups = interface_groups; | ||
1249 | interface_type->ct_item_ops = &interf_item_ops; | ||
1250 | interface_type->ct_group_ops = &interf_grp_ops; | ||
1251 | interface_type->ct_attrs = interf_grp_attrs; | ||
1252 | interface_type->ct_owner = owner; | ||
1253 | |||
1254 | while (n_interf--) { | ||
1255 | struct usb_os_desc *d; | ||
1256 | |||
1257 | d = desc[n_interf]; | ||
1258 | d->owner = owner; | ||
1259 | config_group_init_type_name(&d->group, "", interface_type); | ||
1260 | config_item_set_name(&d->group.cg_item, "interface.%d", | ||
1261 | n_interf); | ||
1262 | interface_groups[n_interf] = &d->group; | ||
1263 | } | ||
1264 | |||
1265 | return 0; | ||
1266 | } | ||
1267 | EXPORT_SYMBOL(usb_os_desc_prepare_interf_dir); | ||
1268 | |||
739 | static int configfs_do_nothing(struct usb_composite_dev *cdev) | 1269 | static int configfs_do_nothing(struct usb_composite_dev *cdev) |
740 | { | 1270 | { |
741 | WARN_ON(1); | 1271 | WARN_ON(1); |
@@ -745,6 +1275,9 @@ static int configfs_do_nothing(struct usb_composite_dev *cdev) | |||
745 | int composite_dev_prepare(struct usb_composite_driver *composite, | 1275 | int composite_dev_prepare(struct usb_composite_driver *composite, |
746 | struct usb_composite_dev *dev); | 1276 | struct usb_composite_dev *dev); |
747 | 1277 | ||
1278 | int composite_os_desc_req_prepare(struct usb_composite_dev *cdev, | ||
1279 | struct usb_ep *ep0); | ||
1280 | |||
748 | static void purge_configs_funcs(struct gadget_info *gi) | 1281 | static void purge_configs_funcs(struct gadget_info *gi) |
749 | { | 1282 | { |
750 | struct usb_configuration *c; | 1283 | struct usb_configuration *c; |
@@ -793,7 +1326,7 @@ static int configfs_composite_bind(struct usb_gadget *gadget, | |||
793 | ret = -EINVAL; | 1326 | ret = -EINVAL; |
794 | 1327 | ||
795 | if (list_empty(&gi->cdev.configs)) { | 1328 | if (list_empty(&gi->cdev.configs)) { |
796 | pr_err("Need atleast one configuration in %s.\n", | 1329 | pr_err("Need at least one configuration in %s.\n", |
797 | gi->composite.name); | 1330 | gi->composite.name); |
798 | goto err_comp_cleanup; | 1331 | goto err_comp_cleanup; |
799 | } | 1332 | } |
@@ -804,7 +1337,7 @@ static int configfs_composite_bind(struct usb_gadget *gadget, | |||
804 | 1337 | ||
805 | cfg = container_of(c, struct config_usb_cfg, c); | 1338 | cfg = container_of(c, struct config_usb_cfg, c); |
806 | if (list_empty(&cfg->func_list)) { | 1339 | if (list_empty(&cfg->func_list)) { |
807 | pr_err("Config %s/%d of %s needs atleast one function.\n", | 1340 | pr_err("Config %s/%d of %s needs at least one function.\n", |
808 | c->label, c->bConfigurationValue, | 1341 | c->label, c->bConfigurationValue, |
809 | gi->composite.name); | 1342 | gi->composite.name); |
810 | goto err_comp_cleanup; | 1343 | goto err_comp_cleanup; |
@@ -839,6 +1372,12 @@ static int configfs_composite_bind(struct usb_gadget *gadget, | |||
839 | gi->cdev.desc.iSerialNumber = s[USB_GADGET_SERIAL_IDX].id; | 1372 | gi->cdev.desc.iSerialNumber = s[USB_GADGET_SERIAL_IDX].id; |
840 | } | 1373 | } |
841 | 1374 | ||
1375 | if (gi->use_os_desc) { | ||
1376 | cdev->use_os_string = true; | ||
1377 | cdev->b_vendor_code = gi->b_vendor_code; | ||
1378 | memcpy(cdev->qw_sign, gi->qw_sign, OS_STRING_QW_SIGN_LEN); | ||
1379 | } | ||
1380 | |||
842 | /* Go through all configs, attach all functions */ | 1381 | /* Go through all configs, attach all functions */ |
843 | list_for_each_entry(c, &gi->cdev.configs, list) { | 1382 | list_for_each_entry(c, &gi->cdev.configs, list) { |
844 | struct config_usb_cfg *cfg; | 1383 | struct config_usb_cfg *cfg; |
@@ -874,6 +1413,12 @@ static int configfs_composite_bind(struct usb_gadget *gadget, | |||
874 | } | 1413 | } |
875 | usb_ep_autoconfig_reset(cdev->gadget); | 1414 | usb_ep_autoconfig_reset(cdev->gadget); |
876 | } | 1415 | } |
1416 | if (cdev->use_os_string) { | ||
1417 | ret = composite_os_desc_req_prepare(cdev, gadget->ep0); | ||
1418 | if (ret) | ||
1419 | goto err_purge_funcs; | ||
1420 | } | ||
1421 | |||
877 | usb_ep_autoconfig_reset(cdev->gadget); | 1422 | usb_ep_autoconfig_reset(cdev->gadget); |
878 | return 0; | 1423 | return 0; |
879 | 1424 | ||
@@ -929,6 +1474,7 @@ static struct config_group *gadgets_make( | |||
929 | gi->group.default_groups[0] = &gi->functions_group; | 1474 | gi->group.default_groups[0] = &gi->functions_group; |
930 | gi->group.default_groups[1] = &gi->configs_group; | 1475 | gi->group.default_groups[1] = &gi->configs_group; |
931 | gi->group.default_groups[2] = &gi->strings_group; | 1476 | gi->group.default_groups[2] = &gi->strings_group; |
1477 | gi->group.default_groups[3] = &gi->os_desc_group; | ||
932 | 1478 | ||
933 | config_group_init_type_name(&gi->functions_group, "functions", | 1479 | config_group_init_type_name(&gi->functions_group, "functions", |
934 | &functions_type); | 1480 | &functions_type); |
@@ -936,6 +1482,8 @@ static struct config_group *gadgets_make( | |||
936 | &config_desc_type); | 1482 | &config_desc_type); |
937 | config_group_init_type_name(&gi->strings_group, "strings", | 1483 | config_group_init_type_name(&gi->strings_group, "strings", |
938 | &gadget_strings_strings_type); | 1484 | &gadget_strings_strings_type); |
1485 | config_group_init_type_name(&gi->os_desc_group, "os_desc", | ||
1486 | &os_desc_type); | ||
939 | 1487 | ||
940 | gi->composite.bind = configfs_do_nothing; | 1488 | gi->composite.bind = configfs_do_nothing; |
941 | gi->composite.unbind = configfs_do_nothing; | 1489 | gi->composite.unbind = configfs_do_nothing; |
@@ -1005,7 +1553,7 @@ void unregister_gadget_item(struct config_item *item) | |||
1005 | 1553 | ||
1006 | unregister_gadget(gi); | 1554 | unregister_gadget(gi); |
1007 | } | 1555 | } |
1008 | EXPORT_SYMBOL(unregister_gadget_item); | 1556 | EXPORT_SYMBOL_GPL(unregister_gadget_item); |
1009 | 1557 | ||
1010 | static int __init gadget_cfs_init(void) | 1558 | static int __init gadget_cfs_init(void) |
1011 | { | 1559 | { |
diff --git a/drivers/usb/gadget/configfs.h b/drivers/usb/gadget/configfs.h index a7b564a913d1..a14ac792c698 100644 --- a/drivers/usb/gadget/configfs.h +++ b/drivers/usb/gadget/configfs.h | |||
@@ -1,6 +1,18 @@ | |||
1 | #ifndef USB__GADGET__CONFIGFS__H | 1 | #ifndef USB__GADGET__CONFIGFS__H |
2 | #define USB__GADGET__CONFIGFS__H | 2 | #define USB__GADGET__CONFIGFS__H |
3 | 3 | ||
4 | #include <linux/configfs.h> | ||
5 | |||
4 | void unregister_gadget_item(struct config_item *item); | 6 | void unregister_gadget_item(struct config_item *item); |
5 | 7 | ||
8 | int usb_os_desc_prepare_interf_dir(struct config_group *parent, | ||
9 | int n_interf, | ||
10 | struct usb_os_desc **desc, | ||
11 | struct module *owner); | ||
12 | |||
13 | static inline struct usb_os_desc *to_usb_os_desc(struct config_item *item) | ||
14 | { | ||
15 | return container_of(to_config_group(item), struct usb_os_desc, group); | ||
16 | } | ||
17 | |||
6 | #endif /* USB__GADGET__CONFIGFS__H */ | 18 | #endif /* USB__GADGET__CONFIGFS__H */ |
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 1e12b3ee56fd..74202d67f911 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c | |||
@@ -33,36 +33,11 @@ | |||
33 | #include <linux/poll.h> | 33 | #include <linux/poll.h> |
34 | 34 | ||
35 | #include "u_fs.h" | 35 | #include "u_fs.h" |
36 | #include "u_f.h" | ||
36 | #include "configfs.h" | 37 | #include "configfs.h" |
37 | 38 | ||
38 | #define FUNCTIONFS_MAGIC 0xa647361 /* Chosen by a honest dice roll ;) */ | 39 | #define FUNCTIONFS_MAGIC 0xa647361 /* Chosen by a honest dice roll ;) */ |
39 | 40 | ||
40 | /* Variable Length Array Macros **********************************************/ | ||
41 | #define vla_group(groupname) size_t groupname##__next = 0 | ||
42 | #define vla_group_size(groupname) groupname##__next | ||
43 | |||
44 | #define vla_item(groupname, type, name, n) \ | ||
45 | size_t groupname##_##name##__offset = ({ \ | ||
46 | size_t align_mask = __alignof__(type) - 1; \ | ||
47 | size_t offset = (groupname##__next + align_mask) & ~align_mask;\ | ||
48 | size_t size = (n) * sizeof(type); \ | ||
49 | groupname##__next = offset + size; \ | ||
50 | offset; \ | ||
51 | }) | ||
52 | |||
53 | #define vla_item_with_sz(groupname, type, name, n) \ | ||
54 | size_t groupname##_##name##__sz = (n) * sizeof(type); \ | ||
55 | size_t groupname##_##name##__offset = ({ \ | ||
56 | size_t align_mask = __alignof__(type) - 1; \ | ||
57 | size_t offset = (groupname##__next + align_mask) & ~align_mask;\ | ||
58 | size_t size = groupname##_##name##__sz; \ | ||
59 | groupname##__next = offset + size; \ | ||
60 | offset; \ | ||
61 | }) | ||
62 | |||
63 | #define vla_ptr(ptr, groupname, name) \ | ||
64 | ((void *) ((char *)ptr + groupname##_##name##__offset)) | ||
65 | |||
66 | /* Reference counter handling */ | 41 | /* Reference counter handling */ |
67 | static void ffs_data_get(struct ffs_data *ffs); | 42 | static void ffs_data_get(struct ffs_data *ffs); |
68 | static void ffs_data_put(struct ffs_data *ffs); | 43 | static void ffs_data_put(struct ffs_data *ffs); |
@@ -190,7 +165,7 @@ ffs_sb_create_file(struct super_block *sb, const char *name, void *data, | |||
190 | /* Devices management *******************************************************/ | 165 | /* Devices management *******************************************************/ |
191 | 166 | ||
192 | DEFINE_MUTEX(ffs_lock); | 167 | DEFINE_MUTEX(ffs_lock); |
193 | EXPORT_SYMBOL(ffs_lock); | 168 | EXPORT_SYMBOL_GPL(ffs_lock); |
194 | 169 | ||
195 | static struct ffs_dev *_ffs_find_dev(const char *name); | 170 | static struct ffs_dev *_ffs_find_dev(const char *name); |
196 | static struct ffs_dev *_ffs_alloc_dev(void); | 171 | static struct ffs_dev *_ffs_alloc_dev(void); |
@@ -2883,7 +2858,7 @@ int ffs_name_dev(struct ffs_dev *dev, const char *name) | |||
2883 | 2858 | ||
2884 | return ret; | 2859 | return ret; |
2885 | } | 2860 | } |
2886 | EXPORT_SYMBOL(ffs_name_dev); | 2861 | EXPORT_SYMBOL_GPL(ffs_name_dev); |
2887 | 2862 | ||
2888 | int ffs_single_dev(struct ffs_dev *dev) | 2863 | int ffs_single_dev(struct ffs_dev *dev) |
2889 | { | 2864 | { |
@@ -2900,7 +2875,7 @@ int ffs_single_dev(struct ffs_dev *dev) | |||
2900 | ffs_dev_unlock(); | 2875 | ffs_dev_unlock(); |
2901 | return ret; | 2876 | return ret; |
2902 | } | 2877 | } |
2903 | EXPORT_SYMBOL(ffs_single_dev); | 2878 | EXPORT_SYMBOL_GPL(ffs_single_dev); |
2904 | 2879 | ||
2905 | /* | 2880 | /* |
2906 | * ffs_lock must be taken by the caller of this function | 2881 | * ffs_lock must be taken by the caller of this function |
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index 9a4f49dc6ac4..eed3ad878047 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include "u_ether_configfs.h" | 27 | #include "u_ether_configfs.h" |
28 | #include "u_rndis.h" | 28 | #include "u_rndis.h" |
29 | #include "rndis.h" | 29 | #include "rndis.h" |
30 | #include "configfs.h" | ||
30 | 31 | ||
31 | /* | 32 | /* |
32 | * This function is an RNDIS Ethernet port -- a Microsoft protocol that's | 33 | * This function is an RNDIS Ethernet port -- a Microsoft protocol that's |
@@ -682,6 +683,15 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) | |||
682 | 683 | ||
683 | rndis_opts = container_of(f->fi, struct f_rndis_opts, func_inst); | 684 | rndis_opts = container_of(f->fi, struct f_rndis_opts, func_inst); |
684 | 685 | ||
686 | if (cdev->use_os_string) { | ||
687 | f->os_desc_table = kzalloc(sizeof(*f->os_desc_table), | ||
688 | GFP_KERNEL); | ||
689 | if (!f->os_desc_table) | ||
690 | return PTR_ERR(f->os_desc_table); | ||
691 | f->os_desc_n = 1; | ||
692 | f->os_desc_table[0].os_desc = &rndis_opts->rndis_os_desc; | ||
693 | } | ||
694 | |||
685 | /* | 695 | /* |
686 | * in drivers/usb/gadget/configfs.c:configfs_composite_bind() | 696 | * in drivers/usb/gadget/configfs.c:configfs_composite_bind() |
687 | * configurations are bound in sequence with list_for_each_entry, | 697 | * configurations are bound in sequence with list_for_each_entry, |
@@ -693,14 +703,16 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) | |||
693 | gether_set_gadget(rndis_opts->net, cdev->gadget); | 703 | gether_set_gadget(rndis_opts->net, cdev->gadget); |
694 | status = gether_register_netdev(rndis_opts->net); | 704 | status = gether_register_netdev(rndis_opts->net); |
695 | if (status) | 705 | if (status) |
696 | return status; | 706 | goto fail; |
697 | rndis_opts->bound = true; | 707 | rndis_opts->bound = true; |
698 | } | 708 | } |
699 | 709 | ||
700 | us = usb_gstrings_attach(cdev, rndis_strings, | 710 | us = usb_gstrings_attach(cdev, rndis_strings, |
701 | ARRAY_SIZE(rndis_string_defs)); | 711 | ARRAY_SIZE(rndis_string_defs)); |
702 | if (IS_ERR(us)) | 712 | if (IS_ERR(us)) { |
703 | return PTR_ERR(us); | 713 | status = PTR_ERR(us); |
714 | goto fail; | ||
715 | } | ||
704 | rndis_control_intf.iInterface = us[0].id; | 716 | rndis_control_intf.iInterface = us[0].id; |
705 | rndis_data_intf.iInterface = us[1].id; | 717 | rndis_data_intf.iInterface = us[1].id; |
706 | rndis_iad_descriptor.iFunction = us[2].id; | 718 | rndis_iad_descriptor.iFunction = us[2].id; |
@@ -802,6 +814,8 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) | |||
802 | return 0; | 814 | return 0; |
803 | 815 | ||
804 | fail: | 816 | fail: |
817 | kfree(f->os_desc_table); | ||
818 | f->os_desc_n = 0; | ||
805 | usb_free_all_descriptors(f); | 819 | usb_free_all_descriptors(f); |
806 | 820 | ||
807 | if (rndis->notify_req) { | 821 | if (rndis->notify_req) { |
@@ -834,7 +848,7 @@ void rndis_borrow_net(struct usb_function_instance *f, struct net_device *net) | |||
834 | opts->borrowed_net = opts->bound = true; | 848 | opts->borrowed_net = opts->bound = true; |
835 | opts->net = net; | 849 | opts->net = net; |
836 | } | 850 | } |
837 | EXPORT_SYMBOL(rndis_borrow_net); | 851 | EXPORT_SYMBOL_GPL(rndis_borrow_net); |
838 | 852 | ||
839 | static inline struct f_rndis_opts *to_f_rndis_opts(struct config_item *item) | 853 | static inline struct f_rndis_opts *to_f_rndis_opts(struct config_item *item) |
840 | { | 854 | { |
@@ -882,16 +896,21 @@ static void rndis_free_inst(struct usb_function_instance *f) | |||
882 | else | 896 | else |
883 | free_netdev(opts->net); | 897 | free_netdev(opts->net); |
884 | } | 898 | } |
899 | |||
900 | kfree(opts->rndis_os_desc.group.default_groups); /* single VLA chunk */ | ||
885 | kfree(opts); | 901 | kfree(opts); |
886 | } | 902 | } |
887 | 903 | ||
888 | static struct usb_function_instance *rndis_alloc_inst(void) | 904 | static struct usb_function_instance *rndis_alloc_inst(void) |
889 | { | 905 | { |
890 | struct f_rndis_opts *opts; | 906 | struct f_rndis_opts *opts; |
907 | struct usb_os_desc *descs[1]; | ||
891 | 908 | ||
892 | opts = kzalloc(sizeof(*opts), GFP_KERNEL); | 909 | opts = kzalloc(sizeof(*opts), GFP_KERNEL); |
893 | if (!opts) | 910 | if (!opts) |
894 | return ERR_PTR(-ENOMEM); | 911 | return ERR_PTR(-ENOMEM); |
912 | opts->rndis_os_desc.ext_compat_id = opts->rndis_ext_compat_id; | ||
913 | |||
895 | mutex_init(&opts->lock); | 914 | mutex_init(&opts->lock); |
896 | opts->func_inst.free_func_inst = rndis_free_inst; | 915 | opts->func_inst.free_func_inst = rndis_free_inst; |
897 | opts->net = gether_setup_default(); | 916 | opts->net = gether_setup_default(); |
@@ -900,7 +919,11 @@ static struct usb_function_instance *rndis_alloc_inst(void) | |||
900 | kfree(opts); | 919 | kfree(opts); |
901 | return ERR_CAST(net); | 920 | return ERR_CAST(net); |
902 | } | 921 | } |
922 | INIT_LIST_HEAD(&opts->rndis_os_desc.ext_prop); | ||
903 | 923 | ||
924 | descs[0] = &opts->rndis_os_desc; | ||
925 | usb_os_desc_prepare_interf_dir(&opts->func_inst.group, 1, descs, | ||
926 | THIS_MODULE); | ||
904 | config_group_init_type_name(&opts->func_inst.group, "", | 927 | config_group_init_type_name(&opts->func_inst.group, "", |
905 | &rndis_func_type); | 928 | &rndis_func_type); |
906 | 929 | ||
@@ -925,6 +948,8 @@ static void rndis_unbind(struct usb_configuration *c, struct usb_function *f) | |||
925 | { | 948 | { |
926 | struct f_rndis *rndis = func_to_rndis(f); | 949 | struct f_rndis *rndis = func_to_rndis(f); |
927 | 950 | ||
951 | kfree(f->os_desc_table); | ||
952 | f->os_desc_n = 0; | ||
928 | usb_free_all_descriptors(f); | 953 | usb_free_all_descriptors(f); |
929 | 954 | ||
930 | kfree(rndis->notify_req->buf); | 955 | kfree(rndis->notify_req->buf); |
diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c index df4a0dcbc993..1ea8baf33333 100644 --- a/drivers/usb/gadget/f_subset.c +++ b/drivers/usb/gadget/f_subset.c | |||
@@ -276,7 +276,7 @@ static int geth_set_alt(struct usb_function *f, unsigned intf, unsigned alt) | |||
276 | } | 276 | } |
277 | 277 | ||
278 | net = gether_connect(&geth->port); | 278 | net = gether_connect(&geth->port); |
279 | return PTR_RET(net); | 279 | return PTR_ERR_OR_ZERO(net); |
280 | } | 280 | } |
281 | 281 | ||
282 | static void geth_disable(struct usb_function *f) | 282 | static void geth_disable(struct usb_function *f) |
diff --git a/drivers/usb/gadget/f_uac2.c b/drivers/usb/gadget/f_uac2.c index bc23040c7790..6261db4a9910 100644 --- a/drivers/usb/gadget/f_uac2.c +++ b/drivers/usb/gadget/f_uac2.c | |||
@@ -196,7 +196,7 @@ agdev_iso_complete(struct usb_ep *ep, struct usb_request *req) | |||
196 | struct snd_uac2_chip *uac2 = prm->uac2; | 196 | struct snd_uac2_chip *uac2 = prm->uac2; |
197 | 197 | ||
198 | /* i/f shutting down */ | 198 | /* i/f shutting down */ |
199 | if (!prm->ep_enabled) | 199 | if (!prm->ep_enabled || req->status == -ESHUTDOWN) |
200 | return; | 200 | return; |
201 | 201 | ||
202 | /* | 202 | /* |
@@ -974,8 +974,6 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) | |||
974 | prm->rbuf = kzalloc(prm->max_psize * USB_XFERS, GFP_KERNEL); | 974 | prm->rbuf = kzalloc(prm->max_psize * USB_XFERS, GFP_KERNEL); |
975 | if (!prm->rbuf) { | 975 | if (!prm->rbuf) { |
976 | prm->max_psize = 0; | 976 | prm->max_psize = 0; |
977 | dev_err(&uac2->pdev.dev, | ||
978 | "%s:%d Error!\n", __func__, __LINE__); | ||
979 | goto err; | 977 | goto err; |
980 | } | 978 | } |
981 | 979 | ||
@@ -984,8 +982,6 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) | |||
984 | prm->rbuf = kzalloc(prm->max_psize * USB_XFERS, GFP_KERNEL); | 982 | prm->rbuf = kzalloc(prm->max_psize * USB_XFERS, GFP_KERNEL); |
985 | if (!prm->rbuf) { | 983 | if (!prm->rbuf) { |
986 | prm->max_psize = 0; | 984 | prm->max_psize = 0; |
987 | dev_err(&uac2->pdev.dev, | ||
988 | "%s:%d Error!\n", __func__, __LINE__); | ||
989 | goto err; | 985 | goto err; |
990 | } | 986 | } |
991 | 987 | ||
@@ -1298,10 +1294,8 @@ static int audio_bind_config(struct usb_configuration *cfg) | |||
1298 | int res; | 1294 | int res; |
1299 | 1295 | ||
1300 | agdev_g = kzalloc(sizeof *agdev_g, GFP_KERNEL); | 1296 | agdev_g = kzalloc(sizeof *agdev_g, GFP_KERNEL); |
1301 | if (agdev_g == NULL) { | 1297 | if (agdev_g == NULL) |
1302 | printk(KERN_ERR "Unable to allocate audio gadget\n"); | ||
1303 | return -ENOMEM; | 1298 | return -ENOMEM; |
1304 | } | ||
1305 | 1299 | ||
1306 | res = usb_string_ids_tab(cfg->cdev, strings_fn); | 1300 | res = usb_string_ids_tab(cfg->cdev, strings_fn); |
1307 | if (res) | 1301 | if (res) |
diff --git a/drivers/usb/gadget/fotg210-udc.c b/drivers/usb/gadget/fotg210-udc.c index 2d0305280e8c..e143d69f6017 100644 --- a/drivers/usb/gadget/fotg210-udc.c +++ b/drivers/usb/gadget/fotg210-udc.c | |||
@@ -1112,17 +1112,13 @@ static int fotg210_udc_probe(struct platform_device *pdev) | |||
1112 | 1112 | ||
1113 | /* initialize udc */ | 1113 | /* initialize udc */ |
1114 | fotg210 = kzalloc(sizeof(struct fotg210_udc), GFP_KERNEL); | 1114 | fotg210 = kzalloc(sizeof(struct fotg210_udc), GFP_KERNEL); |
1115 | if (fotg210 == NULL) { | 1115 | if (fotg210 == NULL) |
1116 | pr_err("kzalloc error\n"); | ||
1117 | goto err_alloc; | 1116 | goto err_alloc; |
1118 | } | ||
1119 | 1117 | ||
1120 | for (i = 0; i < FOTG210_MAX_NUM_EP; i++) { | 1118 | for (i = 0; i < FOTG210_MAX_NUM_EP; i++) { |
1121 | _ep[i] = kzalloc(sizeof(struct fotg210_ep), GFP_KERNEL); | 1119 | _ep[i] = kzalloc(sizeof(struct fotg210_ep), GFP_KERNEL); |
1122 | if (_ep[i] == NULL) { | 1120 | if (_ep[i] == NULL) |
1123 | pr_err("_ep kzalloc error\n"); | ||
1124 | goto err_alloc; | 1121 | goto err_alloc; |
1125 | } | ||
1126 | fotg210->ep[i] = _ep[i]; | 1122 | fotg210->ep[i] = _ep[i]; |
1127 | } | 1123 | } |
1128 | 1124 | ||
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index a2f26cdb56fe..28e4fc957026 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c | |||
@@ -2256,10 +2256,8 @@ static int __init struct_udc_setup(struct fsl_udc *udc, | |||
2256 | udc->phy_mode = pdata->phy_mode; | 2256 | udc->phy_mode = pdata->phy_mode; |
2257 | 2257 | ||
2258 | udc->eps = kzalloc(sizeof(struct fsl_ep) * udc->max_ep, GFP_KERNEL); | 2258 | udc->eps = kzalloc(sizeof(struct fsl_ep) * udc->max_ep, GFP_KERNEL); |
2259 | if (!udc->eps) { | 2259 | if (!udc->eps) |
2260 | ERR("malloc fsl_ep failed\n"); | ||
2261 | return -1; | 2260 | return -1; |
2262 | } | ||
2263 | 2261 | ||
2264 | /* initialized QHs, take care of alignment */ | 2262 | /* initialized QHs, take care of alignment */ |
2265 | size = udc->max_ep * sizeof(struct ep_queue_head); | 2263 | size = udc->max_ep * sizeof(struct ep_queue_head); |
@@ -2342,10 +2340,8 @@ static int __init fsl_udc_probe(struct platform_device *pdev) | |||
2342 | u32 dccparams; | 2340 | u32 dccparams; |
2343 | 2341 | ||
2344 | udc_controller = kzalloc(sizeof(struct fsl_udc), GFP_KERNEL); | 2342 | udc_controller = kzalloc(sizeof(struct fsl_udc), GFP_KERNEL); |
2345 | if (udc_controller == NULL) { | 2343 | if (udc_controller == NULL) |
2346 | ERR("malloc udc failed\n"); | ||
2347 | return -ENOMEM; | 2344 | return -ENOMEM; |
2348 | } | ||
2349 | 2345 | ||
2350 | pdata = dev_get_platdata(&pdev->dev); | 2346 | pdata = dev_get_platdata(&pdev->dev); |
2351 | udc_controller->pdata = pdata; | 2347 | udc_controller->pdata = pdata; |
diff --git a/drivers/usb/gadget/fusb300_udc.c b/drivers/usb/gadget/fusb300_udc.c index 6423f1840ed9..3deb4e938071 100644 --- a/drivers/usb/gadget/fusb300_udc.c +++ b/drivers/usb/gadget/fusb300_udc.c | |||
@@ -1400,17 +1400,13 @@ static int __init fusb300_probe(struct platform_device *pdev) | |||
1400 | 1400 | ||
1401 | /* initialize udc */ | 1401 | /* initialize udc */ |
1402 | fusb300 = kzalloc(sizeof(struct fusb300), GFP_KERNEL); | 1402 | fusb300 = kzalloc(sizeof(struct fusb300), GFP_KERNEL); |
1403 | if (fusb300 == NULL) { | 1403 | if (fusb300 == NULL) |
1404 | pr_err("kzalloc error\n"); | ||
1405 | goto clean_up; | 1404 | goto clean_up; |
1406 | } | ||
1407 | 1405 | ||
1408 | for (i = 0; i < FUSB300_MAX_NUM_EP; i++) { | 1406 | for (i = 0; i < FUSB300_MAX_NUM_EP; i++) { |
1409 | _ep[i] = kzalloc(sizeof(struct fusb300_ep), GFP_KERNEL); | 1407 | _ep[i] = kzalloc(sizeof(struct fusb300_ep), GFP_KERNEL); |
1410 | if (_ep[i] == NULL) { | 1408 | if (_ep[i] == NULL) |
1411 | pr_err("_ep kzalloc error\n"); | ||
1412 | goto clean_up; | 1409 | goto clean_up; |
1413 | } | ||
1414 | fusb300->ep[i] = _ep[i]; | 1410 | fusb300->ep[i] = _ep[i]; |
1415 | } | 1411 | } |
1416 | 1412 | ||
diff --git a/drivers/usb/gadget/gr_udc.c b/drivers/usb/gadget/gr_udc.c index f984ee75324d..99a37ed03e27 100644 --- a/drivers/usb/gadget/gr_udc.c +++ b/drivers/usb/gadget/gr_udc.c | |||
@@ -143,6 +143,7 @@ static void gr_seq_ep_show(struct seq_file *seq, struct gr_ep *ep) | |||
143 | seq_printf(seq, " wedged = %d\n", ep->wedged); | 143 | seq_printf(seq, " wedged = %d\n", ep->wedged); |
144 | seq_printf(seq, " callback = %d\n", ep->callback); | 144 | seq_printf(seq, " callback = %d\n", ep->callback); |
145 | seq_printf(seq, " maxpacket = %d\n", ep->ep.maxpacket); | 145 | seq_printf(seq, " maxpacket = %d\n", ep->ep.maxpacket); |
146 | seq_printf(seq, " maxpacket_limit = %d\n", ep->ep.maxpacket_limit); | ||
146 | seq_printf(seq, " bytes_per_buffer = %d\n", ep->bytes_per_buffer); | 147 | seq_printf(seq, " bytes_per_buffer = %d\n", ep->bytes_per_buffer); |
147 | if (mode == 1 || mode == 3) | 148 | if (mode == 1 || mode == 3) |
148 | seq_printf(seq, " nt = %d\n", | 149 | seq_printf(seq, " nt = %d\n", |
@@ -1541,6 +1542,10 @@ static int gr_ep_enable(struct usb_ep *_ep, | |||
1541 | } else if (max == 0) { | 1542 | } else if (max == 0) { |
1542 | dev_err(dev->dev, "Max payload cannot be set to 0\n"); | 1543 | dev_err(dev->dev, "Max payload cannot be set to 0\n"); |
1543 | return -EINVAL; | 1544 | return -EINVAL; |
1545 | } else if (max > ep->ep.maxpacket_limit) { | ||
1546 | dev_err(dev->dev, "Requested max payload %d > limit %d\n", | ||
1547 | max, ep->ep.maxpacket_limit); | ||
1548 | return -EINVAL; | ||
1544 | } | 1549 | } |
1545 | 1550 | ||
1546 | spin_lock(&ep->dev->lock); | 1551 | spin_lock(&ep->dev->lock); |
@@ -1679,7 +1684,7 @@ static int gr_queue_ext(struct usb_ep *_ep, struct usb_request *_req, | |||
1679 | if (ep->is_in) | 1684 | if (ep->is_in) |
1680 | gr_dbgprint_request("EXTERN", ep, req); | 1685 | gr_dbgprint_request("EXTERN", ep, req); |
1681 | 1686 | ||
1682 | ret = gr_queue(ep, req, gfp_flags); | 1687 | ret = gr_queue(ep, req, GFP_ATOMIC); |
1683 | 1688 | ||
1684 | spin_unlock(&ep->dev->lock); | 1689 | spin_unlock(&ep->dev->lock); |
1685 | 1690 | ||
@@ -1985,8 +1990,8 @@ static int gr_ep_init(struct gr_udc *dev, int num, int is_in, u32 maxplimit) | |||
1985 | INIT_LIST_HEAD(&ep->queue); | 1990 | INIT_LIST_HEAD(&ep->queue); |
1986 | 1991 | ||
1987 | if (num == 0) { | 1992 | if (num == 0) { |
1988 | _req = gr_alloc_request(&ep->ep, GFP_KERNEL); | 1993 | _req = gr_alloc_request(&ep->ep, GFP_ATOMIC); |
1989 | buf = devm_kzalloc(dev->dev, PAGE_SIZE, GFP_DMA | GFP_KERNEL); | 1994 | buf = devm_kzalloc(dev->dev, PAGE_SIZE, GFP_DMA | GFP_ATOMIC); |
1990 | if (!_req || !buf) { | 1995 | if (!_req || !buf) { |
1991 | /* possible _req freed by gr_probe via gr_remove */ | 1996 | /* possible _req freed by gr_probe via gr_remove */ |
1992 | return -ENOMEM; | 1997 | return -ENOMEM; |
@@ -2020,9 +2025,7 @@ static int gr_udc_init(struct gr_udc *dev) | |||
2020 | u32 dmactrl_val; | 2025 | u32 dmactrl_val; |
2021 | int i; | 2026 | int i; |
2022 | int ret = 0; | 2027 | int ret = 0; |
2023 | u32 *bufsizes; | ||
2024 | u32 bufsize; | 2028 | u32 bufsize; |
2025 | int len; | ||
2026 | 2029 | ||
2027 | gr_set_address(dev, 0); | 2030 | gr_set_address(dev, 0); |
2028 | 2031 | ||
@@ -2033,19 +2036,17 @@ static int gr_udc_init(struct gr_udc *dev) | |||
2033 | INIT_LIST_HEAD(&dev->ep_list); | 2036 | INIT_LIST_HEAD(&dev->ep_list); |
2034 | gr_set_ep0state(dev, GR_EP0_DISCONNECT); | 2037 | gr_set_ep0state(dev, GR_EP0_DISCONNECT); |
2035 | 2038 | ||
2036 | bufsizes = (u32 *)of_get_property(np, "epobufsizes", &len); | ||
2037 | len /= sizeof(u32); | ||
2038 | for (i = 0; i < dev->nepo; i++) { | 2039 | for (i = 0; i < dev->nepo; i++) { |
2039 | bufsize = (bufsizes && i < len) ? bufsizes[i] : 1024; | 2040 | if (of_property_read_u32_index(np, "epobufsizes", i, &bufsize)) |
2041 | bufsize = 1024; | ||
2040 | ret = gr_ep_init(dev, i, 0, bufsize); | 2042 | ret = gr_ep_init(dev, i, 0, bufsize); |
2041 | if (ret) | 2043 | if (ret) |
2042 | return ret; | 2044 | return ret; |
2043 | } | 2045 | } |
2044 | 2046 | ||
2045 | bufsizes = (u32 *)of_get_property(np, "epibufsizes", &len); | ||
2046 | len /= sizeof(u32); | ||
2047 | for (i = 0; i < dev->nepi; i++) { | 2047 | for (i = 0; i < dev->nepi; i++) { |
2048 | bufsize = (bufsizes && i < len) ? bufsizes[i] : 1024; | 2048 | if (of_property_read_u32_index(np, "epibufsizes", i, &bufsize)) |
2049 | bufsize = 1024; | ||
2049 | ret = gr_ep_init(dev, i, 1, bufsize); | 2050 | ret = gr_ep_init(dev, i, 1, bufsize); |
2050 | if (ret) | 2051 | if (ret) |
2051 | return ret; | 2052 | return ret; |
@@ -2065,9 +2066,9 @@ static int gr_udc_init(struct gr_udc *dev) | |||
2065 | return 0; | 2066 | return 0; |
2066 | } | 2067 | } |
2067 | 2068 | ||
2068 | static int gr_remove(struct platform_device *ofdev) | 2069 | static int gr_remove(struct platform_device *pdev) |
2069 | { | 2070 | { |
2070 | struct gr_udc *dev = dev_get_drvdata(&ofdev->dev); | 2071 | struct gr_udc *dev = platform_get_drvdata(pdev); |
2071 | 2072 | ||
2072 | if (dev->added) | 2073 | if (dev->added) |
2073 | usb_del_gadget_udc(&dev->gadget); /* Shuts everything down */ | 2074 | usb_del_gadget_udc(&dev->gadget); /* Shuts everything down */ |
@@ -2077,7 +2078,7 @@ static int gr_remove(struct platform_device *ofdev) | |||
2077 | gr_dfs_delete(dev); | 2078 | gr_dfs_delete(dev); |
2078 | if (dev->desc_pool) | 2079 | if (dev->desc_pool) |
2079 | dma_pool_destroy(dev->desc_pool); | 2080 | dma_pool_destroy(dev->desc_pool); |
2080 | dev_set_drvdata(&ofdev->dev, NULL); | 2081 | platform_set_drvdata(pdev, NULL); |
2081 | 2082 | ||
2082 | gr_free_request(&dev->epi[0].ep, &dev->ep0reqi->req); | 2083 | gr_free_request(&dev->epi[0].ep, &dev->ep0reqi->req); |
2083 | gr_free_request(&dev->epo[0].ep, &dev->ep0reqo->req); | 2084 | gr_free_request(&dev->epo[0].ep, &dev->ep0reqo->req); |
@@ -2090,7 +2091,7 @@ static int gr_request_irq(struct gr_udc *dev, int irq) | |||
2090 | IRQF_SHARED, driver_name, dev); | 2091 | IRQF_SHARED, driver_name, dev); |
2091 | } | 2092 | } |
2092 | 2093 | ||
2093 | static int gr_probe(struct platform_device *ofdev) | 2094 | static int gr_probe(struct platform_device *pdev) |
2094 | { | 2095 | { |
2095 | struct gr_udc *dev; | 2096 | struct gr_udc *dev; |
2096 | struct resource *res; | 2097 | struct resource *res; |
@@ -2098,30 +2099,32 @@ static int gr_probe(struct platform_device *ofdev) | |||
2098 | int retval; | 2099 | int retval; |
2099 | u32 status; | 2100 | u32 status; |
2100 | 2101 | ||
2101 | dev = devm_kzalloc(&ofdev->dev, sizeof(*dev), GFP_KERNEL); | 2102 | dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); |
2102 | if (!dev) | 2103 | if (!dev) |
2103 | return -ENOMEM; | 2104 | return -ENOMEM; |
2104 | dev->dev = &ofdev->dev; | 2105 | dev->dev = &pdev->dev; |
2105 | 2106 | ||
2106 | res = platform_get_resource(ofdev, IORESOURCE_MEM, 0); | 2107 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
2107 | regs = devm_ioremap_resource(dev->dev, res); | 2108 | regs = devm_ioremap_resource(dev->dev, res); |
2108 | if (IS_ERR(regs)) | 2109 | if (IS_ERR(regs)) |
2109 | return PTR_ERR(regs); | 2110 | return PTR_ERR(regs); |
2110 | 2111 | ||
2111 | dev->irq = irq_of_parse_and_map(dev->dev->of_node, 0); | 2112 | dev->irq = platform_get_irq(pdev, 0); |
2112 | if (!dev->irq) { | 2113 | if (dev->irq <= 0) { |
2113 | dev_err(dev->dev, "No irq found\n"); | 2114 | dev_err(dev->dev, "No irq found\n"); |
2114 | return -ENODEV; | 2115 | return -ENODEV; |
2115 | } | 2116 | } |
2116 | 2117 | ||
2117 | /* Some core configurations has separate irqs for IN and OUT events */ | 2118 | /* Some core configurations has separate irqs for IN and OUT events */ |
2118 | dev->irqi = irq_of_parse_and_map(dev->dev->of_node, 1); | 2119 | dev->irqi = platform_get_irq(pdev, 1); |
2119 | if (dev->irqi) { | 2120 | if (dev->irqi > 0) { |
2120 | dev->irqo = irq_of_parse_and_map(dev->dev->of_node, 2); | 2121 | dev->irqo = platform_get_irq(pdev, 2); |
2121 | if (!dev->irqo) { | 2122 | if (dev->irqo <= 0) { |
2122 | dev_err(dev->dev, "Found irqi but not irqo\n"); | 2123 | dev_err(dev->dev, "Found irqi but not irqo\n"); |
2123 | return -ENODEV; | 2124 | return -ENODEV; |
2124 | } | 2125 | } |
2126 | } else { | ||
2127 | dev->irqi = 0; | ||
2125 | } | 2128 | } |
2126 | 2129 | ||
2127 | dev->gadget.name = driver_name; | 2130 | dev->gadget.name = driver_name; |
@@ -2132,7 +2135,7 @@ static int gr_probe(struct platform_device *ofdev) | |||
2132 | spin_lock_init(&dev->lock); | 2135 | spin_lock_init(&dev->lock); |
2133 | dev->regs = regs; | 2136 | dev->regs = regs; |
2134 | 2137 | ||
2135 | dev_set_drvdata(&ofdev->dev, dev); | 2138 | platform_set_drvdata(pdev, dev); |
2136 | 2139 | ||
2137 | /* Determine number of endpoints and data interface mode */ | 2140 | /* Determine number of endpoints and data interface mode */ |
2138 | status = gr_read32(&dev->regs->status); | 2141 | status = gr_read32(&dev->regs->status); |
@@ -2204,7 +2207,7 @@ out: | |||
2204 | spin_unlock(&dev->lock); | 2207 | spin_unlock(&dev->lock); |
2205 | 2208 | ||
2206 | if (retval) | 2209 | if (retval) |
2207 | gr_remove(ofdev); | 2210 | gr_remove(pdev); |
2208 | 2211 | ||
2209 | return retval; | 2212 | return retval; |
2210 | } | 2213 | } |
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index a925d0cbcd41..5b840fb0cce5 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c | |||
@@ -1494,6 +1494,7 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
1494 | */ | 1494 | */ |
1495 | if (value == 0) { | 1495 | if (value == 0) { |
1496 | INFO (dev, "configuration #%d\n", dev->current_config); | 1496 | INFO (dev, "configuration #%d\n", dev->current_config); |
1497 | usb_gadget_set_state(gadget, USB_STATE_CONFIGURED); | ||
1497 | if (dev->usermode_setup) { | 1498 | if (dev->usermode_setup) { |
1498 | dev->setup_can_stall = 0; | 1499 | dev->setup_can_stall = 0; |
1499 | goto delegate; | 1500 | goto delegate; |
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index 8cae01d88597..0d17174b86f8 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c | |||
@@ -1594,7 +1594,6 @@ static int __init m66592_probe(struct platform_device *pdev) | |||
1594 | m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL); | 1594 | m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL); |
1595 | if (m66592 == NULL) { | 1595 | if (m66592 == NULL) { |
1596 | ret = -ENOMEM; | 1596 | ret = -ENOMEM; |
1597 | pr_err("kzalloc error\n"); | ||
1598 | goto clean_up; | 1597 | goto clean_up; |
1599 | } | 1598 | } |
1600 | 1599 | ||
diff --git a/drivers/usb/gadget/mv_u3d_core.c b/drivers/usb/gadget/mv_u3d_core.c index d2ca59e7b477..16248711c152 100644 --- a/drivers/usb/gadget/mv_u3d_core.c +++ b/drivers/usb/gadget/mv_u3d_core.c | |||
@@ -297,10 +297,8 @@ static struct mv_u3d_trb *mv_u3d_build_trb_one(struct mv_u3d_req *req, | |||
297 | u3d = req->ep->u3d; | 297 | u3d = req->ep->u3d; |
298 | 298 | ||
299 | trb = kzalloc(sizeof(*trb), GFP_ATOMIC); | 299 | trb = kzalloc(sizeof(*trb), GFP_ATOMIC); |
300 | if (!trb) { | 300 | if (!trb) |
301 | dev_err(u3d->dev, "%s, trb alloc fail\n", __func__); | ||
302 | return NULL; | 301 | return NULL; |
303 | } | ||
304 | 302 | ||
305 | /* | 303 | /* |
306 | * Be careful that no _GFP_HIGHMEM is set, | 304 | * Be careful that no _GFP_HIGHMEM is set, |
@@ -446,17 +444,12 @@ static int mv_u3d_req_to_trb(struct mv_u3d_req *req) | |||
446 | trb_num++; | 444 | trb_num++; |
447 | 445 | ||
448 | trb = kcalloc(trb_num, sizeof(*trb), GFP_ATOMIC); | 446 | trb = kcalloc(trb_num, sizeof(*trb), GFP_ATOMIC); |
449 | if (!trb) { | 447 | if (!trb) |
450 | dev_err(u3d->dev, | ||
451 | "%s, trb alloc fail\n", __func__); | ||
452 | return -ENOMEM; | 448 | return -ENOMEM; |
453 | } | ||
454 | 449 | ||
455 | trb_hw = kcalloc(trb_num, sizeof(*trb_hw), GFP_ATOMIC); | 450 | trb_hw = kcalloc(trb_num, sizeof(*trb_hw), GFP_ATOMIC); |
456 | if (!trb_hw) { | 451 | if (!trb_hw) { |
457 | kfree(trb); | 452 | kfree(trb); |
458 | dev_err(u3d->dev, | ||
459 | "%s, trb_hw alloc fail\n", __func__); | ||
460 | return -ENOMEM; | 453 | return -ENOMEM; |
461 | } | 454 | } |
462 | 455 | ||
@@ -1811,7 +1804,6 @@ static int mv_u3d_probe(struct platform_device *dev) | |||
1811 | 1804 | ||
1812 | u3d = kzalloc(sizeof(*u3d), GFP_KERNEL); | 1805 | u3d = kzalloc(sizeof(*u3d), GFP_KERNEL); |
1813 | if (!u3d) { | 1806 | if (!u3d) { |
1814 | dev_err(&dev->dev, "failed to allocate memory for u3d\n"); | ||
1815 | retval = -ENOMEM; | 1807 | retval = -ENOMEM; |
1816 | goto err_alloc_private; | 1808 | goto err_alloc_private; |
1817 | } | 1809 | } |
@@ -1905,7 +1897,6 @@ static int mv_u3d_probe(struct platform_device *dev) | |||
1905 | size = u3d->max_eps * sizeof(struct mv_u3d_ep) * 2; | 1897 | size = u3d->max_eps * sizeof(struct mv_u3d_ep) * 2; |
1906 | u3d->eps = kzalloc(size, GFP_KERNEL); | 1898 | u3d->eps = kzalloc(size, GFP_KERNEL); |
1907 | if (!u3d->eps) { | 1899 | if (!u3d->eps) { |
1908 | dev_err(&dev->dev, "allocate ep memory failed\n"); | ||
1909 | retval = -ENOMEM; | 1900 | retval = -ENOMEM; |
1910 | goto err_alloc_eps; | 1901 | goto err_alloc_eps; |
1911 | } | 1902 | } |
@@ -1913,7 +1904,6 @@ static int mv_u3d_probe(struct platform_device *dev) | |||
1913 | /* initialize ep0 status request structure */ | 1904 | /* initialize ep0 status request structure */ |
1914 | u3d->status_req = kzalloc(sizeof(struct mv_u3d_req) + 8, GFP_KERNEL); | 1905 | u3d->status_req = kzalloc(sizeof(struct mv_u3d_req) + 8, GFP_KERNEL); |
1915 | if (!u3d->status_req) { | 1906 | if (!u3d->status_req) { |
1916 | dev_err(&dev->dev, "allocate status_req memory failed\n"); | ||
1917 | retval = -ENOMEM; | 1907 | retval = -ENOMEM; |
1918 | goto err_alloc_status_req; | 1908 | goto err_alloc_status_req; |
1919 | } | 1909 | } |
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index 43e5e2f9888f..300b3a71383b 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c | |||
@@ -1972,7 +1972,9 @@ static int net2280_stop(struct usb_gadget *_gadget, | |||
1972 | device_remove_file (&dev->pdev->dev, &dev_attr_function); | 1972 | device_remove_file (&dev->pdev->dev, &dev_attr_function); |
1973 | device_remove_file (&dev->pdev->dev, &dev_attr_queues); | 1973 | device_remove_file (&dev->pdev->dev, &dev_attr_queues); |
1974 | 1974 | ||
1975 | DEBUG (dev, "unregistered driver '%s'\n", driver->driver.name); | 1975 | DEBUG(dev, "unregistered driver '%s'\n", |
1976 | driver ? driver->driver.name : ""); | ||
1977 | |||
1976 | return 0; | 1978 | return 0; |
1977 | } | 1979 | } |
1978 | 1980 | ||
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index aff0a6718bc6..b698a490cc7d 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c | |||
@@ -1904,7 +1904,6 @@ static int __init r8a66597_probe(struct platform_device *pdev) | |||
1904 | r8a66597 = kzalloc(sizeof(struct r8a66597), GFP_KERNEL); | 1904 | r8a66597 = kzalloc(sizeof(struct r8a66597), GFP_KERNEL); |
1905 | if (r8a66597 == NULL) { | 1905 | if (r8a66597 == NULL) { |
1906 | ret = -ENOMEM; | 1906 | ret = -ENOMEM; |
1907 | dev_err(&pdev->dev, "kzalloc error\n"); | ||
1908 | goto clean_up; | 1907 | goto clean_up; |
1909 | } | 1908 | } |
1910 | 1909 | ||
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index 7ed452d90f4d..95d2324f6977 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c | |||
@@ -761,7 +761,7 @@ int rndis_signal_connect(int configNr) | |||
761 | return rndis_indicate_status_msg(configNr, | 761 | return rndis_indicate_status_msg(configNr, |
762 | RNDIS_STATUS_MEDIA_CONNECT); | 762 | RNDIS_STATUS_MEDIA_CONNECT); |
763 | } | 763 | } |
764 | EXPORT_SYMBOL(rndis_signal_connect); | 764 | EXPORT_SYMBOL_GPL(rndis_signal_connect); |
765 | 765 | ||
766 | int rndis_signal_disconnect(int configNr) | 766 | int rndis_signal_disconnect(int configNr) |
767 | { | 767 | { |
@@ -770,7 +770,7 @@ int rndis_signal_disconnect(int configNr) | |||
770 | return rndis_indicate_status_msg(configNr, | 770 | return rndis_indicate_status_msg(configNr, |
771 | RNDIS_STATUS_MEDIA_DISCONNECT); | 771 | RNDIS_STATUS_MEDIA_DISCONNECT); |
772 | } | 772 | } |
773 | EXPORT_SYMBOL(rndis_signal_disconnect); | 773 | EXPORT_SYMBOL_GPL(rndis_signal_disconnect); |
774 | 774 | ||
775 | void rndis_uninit(int configNr) | 775 | void rndis_uninit(int configNr) |
776 | { | 776 | { |
@@ -785,13 +785,13 @@ void rndis_uninit(int configNr) | |||
785 | while ((buf = rndis_get_next_response(configNr, &length))) | 785 | while ((buf = rndis_get_next_response(configNr, &length))) |
786 | rndis_free_response(configNr, buf); | 786 | rndis_free_response(configNr, buf); |
787 | } | 787 | } |
788 | EXPORT_SYMBOL(rndis_uninit); | 788 | EXPORT_SYMBOL_GPL(rndis_uninit); |
789 | 789 | ||
790 | void rndis_set_host_mac(int configNr, const u8 *addr) | 790 | void rndis_set_host_mac(int configNr, const u8 *addr) |
791 | { | 791 | { |
792 | rndis_per_dev_params[configNr].host_mac = addr; | 792 | rndis_per_dev_params[configNr].host_mac = addr; |
793 | } | 793 | } |
794 | EXPORT_SYMBOL(rndis_set_host_mac); | 794 | EXPORT_SYMBOL_GPL(rndis_set_host_mac); |
795 | 795 | ||
796 | /* | 796 | /* |
797 | * Message Parser | 797 | * Message Parser |
@@ -874,7 +874,7 @@ int rndis_msg_parser(u8 configNr, u8 *buf) | |||
874 | 874 | ||
875 | return -ENOTSUPP; | 875 | return -ENOTSUPP; |
876 | } | 876 | } |
877 | EXPORT_SYMBOL(rndis_msg_parser); | 877 | EXPORT_SYMBOL_GPL(rndis_msg_parser); |
878 | 878 | ||
879 | int rndis_register(void (*resp_avail)(void *v), void *v) | 879 | int rndis_register(void (*resp_avail)(void *v), void *v) |
880 | { | 880 | { |
@@ -896,7 +896,7 @@ int rndis_register(void (*resp_avail)(void *v), void *v) | |||
896 | 896 | ||
897 | return -ENODEV; | 897 | return -ENODEV; |
898 | } | 898 | } |
899 | EXPORT_SYMBOL(rndis_register); | 899 | EXPORT_SYMBOL_GPL(rndis_register); |
900 | 900 | ||
901 | void rndis_deregister(int configNr) | 901 | void rndis_deregister(int configNr) |
902 | { | 902 | { |
@@ -905,7 +905,7 @@ void rndis_deregister(int configNr) | |||
905 | if (configNr >= RNDIS_MAX_CONFIGS) return; | 905 | if (configNr >= RNDIS_MAX_CONFIGS) return; |
906 | rndis_per_dev_params[configNr].used = 0; | 906 | rndis_per_dev_params[configNr].used = 0; |
907 | } | 907 | } |
908 | EXPORT_SYMBOL(rndis_deregister); | 908 | EXPORT_SYMBOL_GPL(rndis_deregister); |
909 | 909 | ||
910 | int rndis_set_param_dev(u8 configNr, struct net_device *dev, u16 *cdc_filter) | 910 | int rndis_set_param_dev(u8 configNr, struct net_device *dev, u16 *cdc_filter) |
911 | { | 911 | { |
@@ -919,7 +919,7 @@ int rndis_set_param_dev(u8 configNr, struct net_device *dev, u16 *cdc_filter) | |||
919 | 919 | ||
920 | return 0; | 920 | return 0; |
921 | } | 921 | } |
922 | EXPORT_SYMBOL(rndis_set_param_dev); | 922 | EXPORT_SYMBOL_GPL(rndis_set_param_dev); |
923 | 923 | ||
924 | int rndis_set_param_vendor(u8 configNr, u32 vendorID, const char *vendorDescr) | 924 | int rndis_set_param_vendor(u8 configNr, u32 vendorID, const char *vendorDescr) |
925 | { | 925 | { |
@@ -932,7 +932,7 @@ int rndis_set_param_vendor(u8 configNr, u32 vendorID, const char *vendorDescr) | |||
932 | 932 | ||
933 | return 0; | 933 | return 0; |
934 | } | 934 | } |
935 | EXPORT_SYMBOL(rndis_set_param_vendor); | 935 | EXPORT_SYMBOL_GPL(rndis_set_param_vendor); |
936 | 936 | ||
937 | int rndis_set_param_medium(u8 configNr, u32 medium, u32 speed) | 937 | int rndis_set_param_medium(u8 configNr, u32 medium, u32 speed) |
938 | { | 938 | { |
@@ -944,7 +944,7 @@ int rndis_set_param_medium(u8 configNr, u32 medium, u32 speed) | |||
944 | 944 | ||
945 | return 0; | 945 | return 0; |
946 | } | 946 | } |
947 | EXPORT_SYMBOL(rndis_set_param_medium); | 947 | EXPORT_SYMBOL_GPL(rndis_set_param_medium); |
948 | 948 | ||
949 | void rndis_add_hdr(struct sk_buff *skb) | 949 | void rndis_add_hdr(struct sk_buff *skb) |
950 | { | 950 | { |
@@ -959,7 +959,7 @@ void rndis_add_hdr(struct sk_buff *skb) | |||
959 | header->DataOffset = cpu_to_le32(36); | 959 | header->DataOffset = cpu_to_le32(36); |
960 | header->DataLength = cpu_to_le32(skb->len - sizeof(*header)); | 960 | header->DataLength = cpu_to_le32(skb->len - sizeof(*header)); |
961 | } | 961 | } |
962 | EXPORT_SYMBOL(rndis_add_hdr); | 962 | EXPORT_SYMBOL_GPL(rndis_add_hdr); |
963 | 963 | ||
964 | void rndis_free_response(int configNr, u8 *buf) | 964 | void rndis_free_response(int configNr, u8 *buf) |
965 | { | 965 | { |
@@ -976,7 +976,7 @@ void rndis_free_response(int configNr, u8 *buf) | |||
976 | } | 976 | } |
977 | } | 977 | } |
978 | } | 978 | } |
979 | EXPORT_SYMBOL(rndis_free_response); | 979 | EXPORT_SYMBOL_GPL(rndis_free_response); |
980 | 980 | ||
981 | u8 *rndis_get_next_response(int configNr, u32 *length) | 981 | u8 *rndis_get_next_response(int configNr, u32 *length) |
982 | { | 982 | { |
@@ -998,7 +998,7 @@ u8 *rndis_get_next_response(int configNr, u32 *length) | |||
998 | 998 | ||
999 | return NULL; | 999 | return NULL; |
1000 | } | 1000 | } |
1001 | EXPORT_SYMBOL(rndis_get_next_response); | 1001 | EXPORT_SYMBOL_GPL(rndis_get_next_response); |
1002 | 1002 | ||
1003 | static rndis_resp_t *rndis_add_response(int configNr, u32 length) | 1003 | static rndis_resp_t *rndis_add_response(int configNr, u32 length) |
1004 | { | 1004 | { |
@@ -1042,7 +1042,7 @@ int rndis_rm_hdr(struct gether *port, | |||
1042 | skb_queue_tail(list, skb); | 1042 | skb_queue_tail(list, skb); |
1043 | return 0; | 1043 | return 0; |
1044 | } | 1044 | } |
1045 | EXPORT_SYMBOL(rndis_rm_hdr); | 1045 | EXPORT_SYMBOL_GPL(rndis_rm_hdr); |
1046 | 1046 | ||
1047 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES | 1047 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES |
1048 | 1048 | ||
diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index dd9678f85c58..7987aa049fab 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c | |||
@@ -117,7 +117,8 @@ static int dprintk(int level, const char *fmt, ...) | |||
117 | sizeof(printk_buf)-len, fmt, args); | 117 | sizeof(printk_buf)-len, fmt, args); |
118 | va_end(args); | 118 | va_end(args); |
119 | 119 | ||
120 | return pr_debug("%s", printk_buf); | 120 | pr_debug("%s", printk_buf); |
121 | return len; | ||
121 | } | 122 | } |
122 | #else | 123 | #else |
123 | static int dprintk(int level, const char *fmt, ...) | 124 | static int dprintk(int level, const char *fmt, ...) |
diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index ec20a1f50c2d..ff205a7bc55c 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c | |||
@@ -43,7 +43,7 @@ struct usb_interface_descriptor fsg_intf_desc = { | |||
43 | .bInterfaceProtocol = USB_PR_BULK, /* Adjusted during fsg_bind() */ | 43 | .bInterfaceProtocol = USB_PR_BULK, /* Adjusted during fsg_bind() */ |
44 | .iInterface = FSG_STRING_INTERFACE, | 44 | .iInterface = FSG_STRING_INTERFACE, |
45 | }; | 45 | }; |
46 | EXPORT_SYMBOL(fsg_intf_desc); | 46 | EXPORT_SYMBOL_GPL(fsg_intf_desc); |
47 | 47 | ||
48 | /* | 48 | /* |
49 | * Three full-speed endpoint descriptors: bulk-in, bulk-out, and | 49 | * Three full-speed endpoint descriptors: bulk-in, bulk-out, and |
@@ -58,7 +58,7 @@ struct usb_endpoint_descriptor fsg_fs_bulk_in_desc = { | |||
58 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 58 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
59 | /* wMaxPacketSize set by autoconfiguration */ | 59 | /* wMaxPacketSize set by autoconfiguration */ |
60 | }; | 60 | }; |
61 | EXPORT_SYMBOL(fsg_fs_bulk_in_desc); | 61 | EXPORT_SYMBOL_GPL(fsg_fs_bulk_in_desc); |
62 | 62 | ||
63 | struct usb_endpoint_descriptor fsg_fs_bulk_out_desc = { | 63 | struct usb_endpoint_descriptor fsg_fs_bulk_out_desc = { |
64 | .bLength = USB_DT_ENDPOINT_SIZE, | 64 | .bLength = USB_DT_ENDPOINT_SIZE, |
@@ -68,7 +68,7 @@ struct usb_endpoint_descriptor fsg_fs_bulk_out_desc = { | |||
68 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 68 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
69 | /* wMaxPacketSize set by autoconfiguration */ | 69 | /* wMaxPacketSize set by autoconfiguration */ |
70 | }; | 70 | }; |
71 | EXPORT_SYMBOL(fsg_fs_bulk_out_desc); | 71 | EXPORT_SYMBOL_GPL(fsg_fs_bulk_out_desc); |
72 | 72 | ||
73 | struct usb_descriptor_header *fsg_fs_function[] = { | 73 | struct usb_descriptor_header *fsg_fs_function[] = { |
74 | (struct usb_descriptor_header *) &fsg_intf_desc, | 74 | (struct usb_descriptor_header *) &fsg_intf_desc, |
@@ -76,7 +76,7 @@ struct usb_descriptor_header *fsg_fs_function[] = { | |||
76 | (struct usb_descriptor_header *) &fsg_fs_bulk_out_desc, | 76 | (struct usb_descriptor_header *) &fsg_fs_bulk_out_desc, |
77 | NULL, | 77 | NULL, |
78 | }; | 78 | }; |
79 | EXPORT_SYMBOL(fsg_fs_function); | 79 | EXPORT_SYMBOL_GPL(fsg_fs_function); |
80 | 80 | ||
81 | 81 | ||
82 | /* | 82 | /* |
@@ -95,7 +95,7 @@ struct usb_endpoint_descriptor fsg_hs_bulk_in_desc = { | |||
95 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 95 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
96 | .wMaxPacketSize = cpu_to_le16(512), | 96 | .wMaxPacketSize = cpu_to_le16(512), |
97 | }; | 97 | }; |
98 | EXPORT_SYMBOL(fsg_hs_bulk_in_desc); | 98 | EXPORT_SYMBOL_GPL(fsg_hs_bulk_in_desc); |
99 | 99 | ||
100 | struct usb_endpoint_descriptor fsg_hs_bulk_out_desc = { | 100 | struct usb_endpoint_descriptor fsg_hs_bulk_out_desc = { |
101 | .bLength = USB_DT_ENDPOINT_SIZE, | 101 | .bLength = USB_DT_ENDPOINT_SIZE, |
@@ -106,7 +106,7 @@ struct usb_endpoint_descriptor fsg_hs_bulk_out_desc = { | |||
106 | .wMaxPacketSize = cpu_to_le16(512), | 106 | .wMaxPacketSize = cpu_to_le16(512), |
107 | .bInterval = 1, /* NAK every 1 uframe */ | 107 | .bInterval = 1, /* NAK every 1 uframe */ |
108 | }; | 108 | }; |
109 | EXPORT_SYMBOL(fsg_hs_bulk_out_desc); | 109 | EXPORT_SYMBOL_GPL(fsg_hs_bulk_out_desc); |
110 | 110 | ||
111 | 111 | ||
112 | struct usb_descriptor_header *fsg_hs_function[] = { | 112 | struct usb_descriptor_header *fsg_hs_function[] = { |
@@ -115,7 +115,7 @@ struct usb_descriptor_header *fsg_hs_function[] = { | |||
115 | (struct usb_descriptor_header *) &fsg_hs_bulk_out_desc, | 115 | (struct usb_descriptor_header *) &fsg_hs_bulk_out_desc, |
116 | NULL, | 116 | NULL, |
117 | }; | 117 | }; |
118 | EXPORT_SYMBOL(fsg_hs_function); | 118 | EXPORT_SYMBOL_GPL(fsg_hs_function); |
119 | 119 | ||
120 | struct usb_endpoint_descriptor fsg_ss_bulk_in_desc = { | 120 | struct usb_endpoint_descriptor fsg_ss_bulk_in_desc = { |
121 | .bLength = USB_DT_ENDPOINT_SIZE, | 121 | .bLength = USB_DT_ENDPOINT_SIZE, |
@@ -125,7 +125,7 @@ struct usb_endpoint_descriptor fsg_ss_bulk_in_desc = { | |||
125 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 125 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
126 | .wMaxPacketSize = cpu_to_le16(1024), | 126 | .wMaxPacketSize = cpu_to_le16(1024), |
127 | }; | 127 | }; |
128 | EXPORT_SYMBOL(fsg_ss_bulk_in_desc); | 128 | EXPORT_SYMBOL_GPL(fsg_ss_bulk_in_desc); |
129 | 129 | ||
130 | struct usb_ss_ep_comp_descriptor fsg_ss_bulk_in_comp_desc = { | 130 | struct usb_ss_ep_comp_descriptor fsg_ss_bulk_in_comp_desc = { |
131 | .bLength = sizeof(fsg_ss_bulk_in_comp_desc), | 131 | .bLength = sizeof(fsg_ss_bulk_in_comp_desc), |
@@ -133,7 +133,7 @@ struct usb_ss_ep_comp_descriptor fsg_ss_bulk_in_comp_desc = { | |||
133 | 133 | ||
134 | /*.bMaxBurst = DYNAMIC, */ | 134 | /*.bMaxBurst = DYNAMIC, */ |
135 | }; | 135 | }; |
136 | EXPORT_SYMBOL(fsg_ss_bulk_in_comp_desc); | 136 | EXPORT_SYMBOL_GPL(fsg_ss_bulk_in_comp_desc); |
137 | 137 | ||
138 | struct usb_endpoint_descriptor fsg_ss_bulk_out_desc = { | 138 | struct usb_endpoint_descriptor fsg_ss_bulk_out_desc = { |
139 | .bLength = USB_DT_ENDPOINT_SIZE, | 139 | .bLength = USB_DT_ENDPOINT_SIZE, |
@@ -143,7 +143,7 @@ struct usb_endpoint_descriptor fsg_ss_bulk_out_desc = { | |||
143 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 143 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
144 | .wMaxPacketSize = cpu_to_le16(1024), | 144 | .wMaxPacketSize = cpu_to_le16(1024), |
145 | }; | 145 | }; |
146 | EXPORT_SYMBOL(fsg_ss_bulk_out_desc); | 146 | EXPORT_SYMBOL_GPL(fsg_ss_bulk_out_desc); |
147 | 147 | ||
148 | struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc = { | 148 | struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc = { |
149 | .bLength = sizeof(fsg_ss_bulk_in_comp_desc), | 149 | .bLength = sizeof(fsg_ss_bulk_in_comp_desc), |
@@ -151,7 +151,7 @@ struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc = { | |||
151 | 151 | ||
152 | /*.bMaxBurst = DYNAMIC, */ | 152 | /*.bMaxBurst = DYNAMIC, */ |
153 | }; | 153 | }; |
154 | EXPORT_SYMBOL(fsg_ss_bulk_out_comp_desc); | 154 | EXPORT_SYMBOL_GPL(fsg_ss_bulk_out_comp_desc); |
155 | 155 | ||
156 | struct usb_descriptor_header *fsg_ss_function[] = { | 156 | struct usb_descriptor_header *fsg_ss_function[] = { |
157 | (struct usb_descriptor_header *) &fsg_intf_desc, | 157 | (struct usb_descriptor_header *) &fsg_intf_desc, |
@@ -161,7 +161,7 @@ struct usb_descriptor_header *fsg_ss_function[] = { | |||
161 | (struct usb_descriptor_header *) &fsg_ss_bulk_out_comp_desc, | 161 | (struct usb_descriptor_header *) &fsg_ss_bulk_out_comp_desc, |
162 | NULL, | 162 | NULL, |
163 | }; | 163 | }; |
164 | EXPORT_SYMBOL(fsg_ss_function); | 164 | EXPORT_SYMBOL_GPL(fsg_ss_function); |
165 | 165 | ||
166 | 166 | ||
167 | /*-------------------------------------------------------------------------*/ | 167 | /*-------------------------------------------------------------------------*/ |
@@ -179,7 +179,7 @@ void fsg_lun_close(struct fsg_lun *curlun) | |||
179 | curlun->filp = NULL; | 179 | curlun->filp = NULL; |
180 | } | 180 | } |
181 | } | 181 | } |
182 | EXPORT_SYMBOL(fsg_lun_close); | 182 | EXPORT_SYMBOL_GPL(fsg_lun_close); |
183 | 183 | ||
184 | int fsg_lun_open(struct fsg_lun *curlun, const char *filename) | 184 | int fsg_lun_open(struct fsg_lun *curlun, const char *filename) |
185 | { | 185 | { |
@@ -278,7 +278,7 @@ out: | |||
278 | fput(filp); | 278 | fput(filp); |
279 | return rc; | 279 | return rc; |
280 | } | 280 | } |
281 | EXPORT_SYMBOL(fsg_lun_open); | 281 | EXPORT_SYMBOL_GPL(fsg_lun_open); |
282 | 282 | ||
283 | 283 | ||
284 | /*-------------------------------------------------------------------------*/ | 284 | /*-------------------------------------------------------------------------*/ |
@@ -295,7 +295,7 @@ int fsg_lun_fsync_sub(struct fsg_lun *curlun) | |||
295 | return 0; | 295 | return 0; |
296 | return vfs_fsync(filp, 1); | 296 | return vfs_fsync(filp, 1); |
297 | } | 297 | } |
298 | EXPORT_SYMBOL(fsg_lun_fsync_sub); | 298 | EXPORT_SYMBOL_GPL(fsg_lun_fsync_sub); |
299 | 299 | ||
300 | void store_cdrom_address(u8 *dest, int msf, u32 addr) | 300 | void store_cdrom_address(u8 *dest, int msf, u32 addr) |
301 | { | 301 | { |
@@ -314,7 +314,7 @@ void store_cdrom_address(u8 *dest, int msf, u32 addr) | |||
314 | put_unaligned_be32(addr, dest); | 314 | put_unaligned_be32(addr, dest); |
315 | } | 315 | } |
316 | } | 316 | } |
317 | EXPORT_SYMBOL(store_cdrom_address); | 317 | EXPORT_SYMBOL_GPL(store_cdrom_address); |
318 | 318 | ||
319 | /*-------------------------------------------------------------------------*/ | 319 | /*-------------------------------------------------------------------------*/ |
320 | 320 | ||
@@ -325,13 +325,13 @@ ssize_t fsg_show_ro(struct fsg_lun *curlun, char *buf) | |||
325 | ? curlun->ro | 325 | ? curlun->ro |
326 | : curlun->initially_ro); | 326 | : curlun->initially_ro); |
327 | } | 327 | } |
328 | EXPORT_SYMBOL(fsg_show_ro); | 328 | EXPORT_SYMBOL_GPL(fsg_show_ro); |
329 | 329 | ||
330 | ssize_t fsg_show_nofua(struct fsg_lun *curlun, char *buf) | 330 | ssize_t fsg_show_nofua(struct fsg_lun *curlun, char *buf) |
331 | { | 331 | { |
332 | return sprintf(buf, "%u\n", curlun->nofua); | 332 | return sprintf(buf, "%u\n", curlun->nofua); |
333 | } | 333 | } |
334 | EXPORT_SYMBOL(fsg_show_nofua); | 334 | EXPORT_SYMBOL_GPL(fsg_show_nofua); |
335 | 335 | ||
336 | ssize_t fsg_show_file(struct fsg_lun *curlun, struct rw_semaphore *filesem, | 336 | ssize_t fsg_show_file(struct fsg_lun *curlun, struct rw_semaphore *filesem, |
337 | char *buf) | 337 | char *buf) |
@@ -357,19 +357,19 @@ ssize_t fsg_show_file(struct fsg_lun *curlun, struct rw_semaphore *filesem, | |||
357 | up_read(filesem); | 357 | up_read(filesem); |
358 | return rc; | 358 | return rc; |
359 | } | 359 | } |
360 | EXPORT_SYMBOL(fsg_show_file); | 360 | EXPORT_SYMBOL_GPL(fsg_show_file); |
361 | 361 | ||
362 | ssize_t fsg_show_cdrom(struct fsg_lun *curlun, char *buf) | 362 | ssize_t fsg_show_cdrom(struct fsg_lun *curlun, char *buf) |
363 | { | 363 | { |
364 | return sprintf(buf, "%u\n", curlun->cdrom); | 364 | return sprintf(buf, "%u\n", curlun->cdrom); |
365 | } | 365 | } |
366 | EXPORT_SYMBOL(fsg_show_cdrom); | 366 | EXPORT_SYMBOL_GPL(fsg_show_cdrom); |
367 | 367 | ||
368 | ssize_t fsg_show_removable(struct fsg_lun *curlun, char *buf) | 368 | ssize_t fsg_show_removable(struct fsg_lun *curlun, char *buf) |
369 | { | 369 | { |
370 | return sprintf(buf, "%u\n", curlun->removable); | 370 | return sprintf(buf, "%u\n", curlun->removable); |
371 | } | 371 | } |
372 | EXPORT_SYMBOL(fsg_show_removable); | 372 | EXPORT_SYMBOL_GPL(fsg_show_removable); |
373 | 373 | ||
374 | /* | 374 | /* |
375 | * The caller must hold fsg->filesem for reading when calling this function. | 375 | * The caller must hold fsg->filesem for reading when calling this function. |
@@ -410,7 +410,7 @@ ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem, | |||
410 | 410 | ||
411 | return rc; | 411 | return rc; |
412 | } | 412 | } |
413 | EXPORT_SYMBOL(fsg_store_ro); | 413 | EXPORT_SYMBOL_GPL(fsg_store_ro); |
414 | 414 | ||
415 | ssize_t fsg_store_nofua(struct fsg_lun *curlun, const char *buf, size_t count) | 415 | ssize_t fsg_store_nofua(struct fsg_lun *curlun, const char *buf, size_t count) |
416 | { | 416 | { |
@@ -429,7 +429,7 @@ ssize_t fsg_store_nofua(struct fsg_lun *curlun, const char *buf, size_t count) | |||
429 | 429 | ||
430 | return count; | 430 | return count; |
431 | } | 431 | } |
432 | EXPORT_SYMBOL(fsg_store_nofua); | 432 | EXPORT_SYMBOL_GPL(fsg_store_nofua); |
433 | 433 | ||
434 | ssize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem, | 434 | ssize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem, |
435 | const char *buf, size_t count) | 435 | const char *buf, size_t count) |
@@ -460,7 +460,7 @@ ssize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem, | |||
460 | up_write(filesem); | 460 | up_write(filesem); |
461 | return (rc < 0 ? rc : count); | 461 | return (rc < 0 ? rc : count); |
462 | } | 462 | } |
463 | EXPORT_SYMBOL(fsg_store_file); | 463 | EXPORT_SYMBOL_GPL(fsg_store_file); |
464 | 464 | ||
465 | ssize_t fsg_store_cdrom(struct fsg_lun *curlun, struct rw_semaphore *filesem, | 465 | ssize_t fsg_store_cdrom(struct fsg_lun *curlun, struct rw_semaphore *filesem, |
466 | const char *buf, size_t count) | 466 | const char *buf, size_t count) |
@@ -483,7 +483,7 @@ ssize_t fsg_store_cdrom(struct fsg_lun *curlun, struct rw_semaphore *filesem, | |||
483 | 483 | ||
484 | return ret; | 484 | return ret; |
485 | } | 485 | } |
486 | EXPORT_SYMBOL(fsg_store_cdrom); | 486 | EXPORT_SYMBOL_GPL(fsg_store_cdrom); |
487 | 487 | ||
488 | ssize_t fsg_store_removable(struct fsg_lun *curlun, const char *buf, | 488 | ssize_t fsg_store_removable(struct fsg_lun *curlun, const char *buf, |
489 | size_t count) | 489 | size_t count) |
@@ -499,6 +499,6 @@ ssize_t fsg_store_removable(struct fsg_lun *curlun, const char *buf, | |||
499 | 499 | ||
500 | return count; | 500 | return count; |
501 | } | 501 | } |
502 | EXPORT_SYMBOL(fsg_store_removable); | 502 | EXPORT_SYMBOL_GPL(fsg_store_removable); |
503 | 503 | ||
504 | MODULE_LICENSE("GPL"); | 504 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/usb/gadget/tcm_usb_gadget.c b/drivers/usb/gadget/tcm_usb_gadget.c index f058c0368d61..49481e0a3382 100644 --- a/drivers/usb/gadget/tcm_usb_gadget.c +++ b/drivers/usb/gadget/tcm_usb_gadget.c | |||
@@ -1383,10 +1383,8 @@ static struct se_node_acl *usbg_alloc_fabric_acl(struct se_portal_group *se_tpg) | |||
1383 | struct usbg_nacl *nacl; | 1383 | struct usbg_nacl *nacl; |
1384 | 1384 | ||
1385 | nacl = kzalloc(sizeof(struct usbg_nacl), GFP_KERNEL); | 1385 | nacl = kzalloc(sizeof(struct usbg_nacl), GFP_KERNEL); |
1386 | if (!nacl) { | 1386 | if (!nacl) |
1387 | printk(KERN_ERR "Unable to allocate struct usbg_nacl\n"); | ||
1388 | return NULL; | 1387 | return NULL; |
1389 | } | ||
1390 | 1388 | ||
1391 | return &nacl->se_node_acl; | 1389 | return &nacl->se_node_acl; |
1392 | } | 1390 | } |
@@ -1561,10 +1559,8 @@ static struct se_portal_group *usbg_make_tpg( | |||
1561 | } | 1559 | } |
1562 | 1560 | ||
1563 | tpg = kzalloc(sizeof(struct usbg_tpg), GFP_KERNEL); | 1561 | tpg = kzalloc(sizeof(struct usbg_tpg), GFP_KERNEL); |
1564 | if (!tpg) { | 1562 | if (!tpg) |
1565 | printk(KERN_ERR "Unable to allocate struct usbg_tpg"); | ||
1566 | return ERR_PTR(-ENOMEM); | 1563 | return ERR_PTR(-ENOMEM); |
1567 | } | ||
1568 | mutex_init(&tpg->tpg_mutex); | 1564 | mutex_init(&tpg->tpg_mutex); |
1569 | atomic_set(&tpg->tpg_port_count, 0); | 1565 | atomic_set(&tpg->tpg_port_count, 0); |
1570 | tpg->workqueue = alloc_workqueue("tcm_usb_gadget", 0, 1); | 1566 | tpg->workqueue = alloc_workqueue("tcm_usb_gadget", 0, 1); |
@@ -1613,10 +1609,8 @@ static struct se_wwn *usbg_make_tport( | |||
1613 | return ERR_PTR(-EINVAL); | 1609 | return ERR_PTR(-EINVAL); |
1614 | 1610 | ||
1615 | tport = kzalloc(sizeof(struct usbg_tport), GFP_KERNEL); | 1611 | tport = kzalloc(sizeof(struct usbg_tport), GFP_KERNEL); |
1616 | if (!(tport)) { | 1612 | if (!(tport)) |
1617 | printk(KERN_ERR "Unable to allocate struct usbg_tport"); | ||
1618 | return ERR_PTR(-ENOMEM); | 1613 | return ERR_PTR(-ENOMEM); |
1619 | } | ||
1620 | tport->tport_wwpn = wwpn; | 1614 | tport->tport_wwpn = wwpn; |
1621 | snprintf(tport->tport_name, sizeof(tport->tport_name), "%s", wnn_name); | 1615 | snprintf(tport->tport_name, sizeof(tport->tport_name), "%s", wnn_name); |
1622 | return &tport->tport_wwn; | 1616 | return &tport->tport_wwn; |
@@ -1727,10 +1721,8 @@ static int tcm_usbg_make_nexus(struct usbg_tpg *tpg, char *name) | |||
1727 | 1721 | ||
1728 | ret = -ENOMEM; | 1722 | ret = -ENOMEM; |
1729 | tv_nexus = kzalloc(sizeof(*tv_nexus), GFP_KERNEL); | 1723 | tv_nexus = kzalloc(sizeof(*tv_nexus), GFP_KERNEL); |
1730 | if (!tv_nexus) { | 1724 | if (!tv_nexus) |
1731 | pr_err("Unable to allocate struct tcm_vhost_nexus\n"); | ||
1732 | goto err_unlock; | 1725 | goto err_unlock; |
1733 | } | ||
1734 | tv_nexus->tvn_se_sess = transport_init_session(TARGET_PROT_NORMAL); | 1726 | tv_nexus->tvn_se_sess = transport_init_session(TARGET_PROT_NORMAL); |
1735 | if (IS_ERR(tv_nexus->tvn_se_sess)) | 1727 | if (IS_ERR(tv_nexus->tvn_se_sess)) |
1736 | goto err_free; | 1728 | goto err_free; |
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index b7d4f82872b7..fe0880d0873e 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c | |||
@@ -818,7 +818,7 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g, | |||
818 | 818 | ||
819 | return dev; | 819 | return dev; |
820 | } | 820 | } |
821 | EXPORT_SYMBOL(gether_setup_name); | 821 | EXPORT_SYMBOL_GPL(gether_setup_name); |
822 | 822 | ||
823 | struct net_device *gether_setup_name_default(const char *netname) | 823 | struct net_device *gether_setup_name_default(const char *netname) |
824 | { | 824 | { |
@@ -855,7 +855,7 @@ struct net_device *gether_setup_name_default(const char *netname) | |||
855 | 855 | ||
856 | return net; | 856 | return net; |
857 | } | 857 | } |
858 | EXPORT_SYMBOL(gether_setup_name_default); | 858 | EXPORT_SYMBOL_GPL(gether_setup_name_default); |
859 | 859 | ||
860 | int gether_register_netdev(struct net_device *net) | 860 | int gether_register_netdev(struct net_device *net) |
861 | { | 861 | { |
@@ -893,7 +893,7 @@ int gether_register_netdev(struct net_device *net) | |||
893 | 893 | ||
894 | return status; | 894 | return status; |
895 | } | 895 | } |
896 | EXPORT_SYMBOL(gether_register_netdev); | 896 | EXPORT_SYMBOL_GPL(gether_register_netdev); |
897 | 897 | ||
898 | void gether_set_gadget(struct net_device *net, struct usb_gadget *g) | 898 | void gether_set_gadget(struct net_device *net, struct usb_gadget *g) |
899 | { | 899 | { |
@@ -903,7 +903,7 @@ void gether_set_gadget(struct net_device *net, struct usb_gadget *g) | |||
903 | dev->gadget = g; | 903 | dev->gadget = g; |
904 | SET_NETDEV_DEV(net, &g->dev); | 904 | SET_NETDEV_DEV(net, &g->dev); |
905 | } | 905 | } |
906 | EXPORT_SYMBOL(gether_set_gadget); | 906 | EXPORT_SYMBOL_GPL(gether_set_gadget); |
907 | 907 | ||
908 | int gether_set_dev_addr(struct net_device *net, const char *dev_addr) | 908 | int gether_set_dev_addr(struct net_device *net, const char *dev_addr) |
909 | { | 909 | { |
@@ -916,7 +916,7 @@ int gether_set_dev_addr(struct net_device *net, const char *dev_addr) | |||
916 | memcpy(dev->dev_mac, new_addr, ETH_ALEN); | 916 | memcpy(dev->dev_mac, new_addr, ETH_ALEN); |
917 | return 0; | 917 | return 0; |
918 | } | 918 | } |
919 | EXPORT_SYMBOL(gether_set_dev_addr); | 919 | EXPORT_SYMBOL_GPL(gether_set_dev_addr); |
920 | 920 | ||
921 | int gether_get_dev_addr(struct net_device *net, char *dev_addr, int len) | 921 | int gether_get_dev_addr(struct net_device *net, char *dev_addr, int len) |
922 | { | 922 | { |
@@ -925,7 +925,7 @@ int gether_get_dev_addr(struct net_device *net, char *dev_addr, int len) | |||
925 | dev = netdev_priv(net); | 925 | dev = netdev_priv(net); |
926 | return get_ether_addr_str(dev->dev_mac, dev_addr, len); | 926 | return get_ether_addr_str(dev->dev_mac, dev_addr, len); |
927 | } | 927 | } |
928 | EXPORT_SYMBOL(gether_get_dev_addr); | 928 | EXPORT_SYMBOL_GPL(gether_get_dev_addr); |
929 | 929 | ||
930 | int gether_set_host_addr(struct net_device *net, const char *host_addr) | 930 | int gether_set_host_addr(struct net_device *net, const char *host_addr) |
931 | { | 931 | { |
@@ -938,7 +938,7 @@ int gether_set_host_addr(struct net_device *net, const char *host_addr) | |||
938 | memcpy(dev->host_mac, new_addr, ETH_ALEN); | 938 | memcpy(dev->host_mac, new_addr, ETH_ALEN); |
939 | return 0; | 939 | return 0; |
940 | } | 940 | } |
941 | EXPORT_SYMBOL(gether_set_host_addr); | 941 | EXPORT_SYMBOL_GPL(gether_set_host_addr); |
942 | 942 | ||
943 | int gether_get_host_addr(struct net_device *net, char *host_addr, int len) | 943 | int gether_get_host_addr(struct net_device *net, char *host_addr, int len) |
944 | { | 944 | { |
@@ -947,7 +947,7 @@ int gether_get_host_addr(struct net_device *net, char *host_addr, int len) | |||
947 | dev = netdev_priv(net); | 947 | dev = netdev_priv(net); |
948 | return get_ether_addr_str(dev->host_mac, host_addr, len); | 948 | return get_ether_addr_str(dev->host_mac, host_addr, len); |
949 | } | 949 | } |
950 | EXPORT_SYMBOL(gether_get_host_addr); | 950 | EXPORT_SYMBOL_GPL(gether_get_host_addr); |
951 | 951 | ||
952 | int gether_get_host_addr_cdc(struct net_device *net, char *host_addr, int len) | 952 | int gether_get_host_addr_cdc(struct net_device *net, char *host_addr, int len) |
953 | { | 953 | { |
@@ -961,7 +961,7 @@ int gether_get_host_addr_cdc(struct net_device *net, char *host_addr, int len) | |||
961 | 961 | ||
962 | return strlen(host_addr); | 962 | return strlen(host_addr); |
963 | } | 963 | } |
964 | EXPORT_SYMBOL(gether_get_host_addr_cdc); | 964 | EXPORT_SYMBOL_GPL(gether_get_host_addr_cdc); |
965 | 965 | ||
966 | void gether_get_host_addr_u8(struct net_device *net, u8 host_mac[ETH_ALEN]) | 966 | void gether_get_host_addr_u8(struct net_device *net, u8 host_mac[ETH_ALEN]) |
967 | { | 967 | { |
@@ -970,7 +970,7 @@ void gether_get_host_addr_u8(struct net_device *net, u8 host_mac[ETH_ALEN]) | |||
970 | dev = netdev_priv(net); | 970 | dev = netdev_priv(net); |
971 | memcpy(host_mac, dev->host_mac, ETH_ALEN); | 971 | memcpy(host_mac, dev->host_mac, ETH_ALEN); |
972 | } | 972 | } |
973 | EXPORT_SYMBOL(gether_get_host_addr_u8); | 973 | EXPORT_SYMBOL_GPL(gether_get_host_addr_u8); |
974 | 974 | ||
975 | void gether_set_qmult(struct net_device *net, unsigned qmult) | 975 | void gether_set_qmult(struct net_device *net, unsigned qmult) |
976 | { | 976 | { |
@@ -979,7 +979,7 @@ void gether_set_qmult(struct net_device *net, unsigned qmult) | |||
979 | dev = netdev_priv(net); | 979 | dev = netdev_priv(net); |
980 | dev->qmult = qmult; | 980 | dev->qmult = qmult; |
981 | } | 981 | } |
982 | EXPORT_SYMBOL(gether_set_qmult); | 982 | EXPORT_SYMBOL_GPL(gether_set_qmult); |
983 | 983 | ||
984 | unsigned gether_get_qmult(struct net_device *net) | 984 | unsigned gether_get_qmult(struct net_device *net) |
985 | { | 985 | { |
@@ -988,7 +988,7 @@ unsigned gether_get_qmult(struct net_device *net) | |||
988 | dev = netdev_priv(net); | 988 | dev = netdev_priv(net); |
989 | return dev->qmult; | 989 | return dev->qmult; |
990 | } | 990 | } |
991 | EXPORT_SYMBOL(gether_get_qmult); | 991 | EXPORT_SYMBOL_GPL(gether_get_qmult); |
992 | 992 | ||
993 | int gether_get_ifname(struct net_device *net, char *name, int len) | 993 | int gether_get_ifname(struct net_device *net, char *name, int len) |
994 | { | 994 | { |
@@ -997,7 +997,7 @@ int gether_get_ifname(struct net_device *net, char *name, int len) | |||
997 | rtnl_unlock(); | 997 | rtnl_unlock(); |
998 | return strlen(name); | 998 | return strlen(name); |
999 | } | 999 | } |
1000 | EXPORT_SYMBOL(gether_get_ifname); | 1000 | EXPORT_SYMBOL_GPL(gether_get_ifname); |
1001 | 1001 | ||
1002 | /** | 1002 | /** |
1003 | * gether_cleanup - remove Ethernet-over-USB device | 1003 | * gether_cleanup - remove Ethernet-over-USB device |
@@ -1014,7 +1014,7 @@ void gether_cleanup(struct eth_dev *dev) | |||
1014 | flush_work(&dev->work); | 1014 | flush_work(&dev->work); |
1015 | free_netdev(dev->net); | 1015 | free_netdev(dev->net); |
1016 | } | 1016 | } |
1017 | EXPORT_SYMBOL(gether_cleanup); | 1017 | EXPORT_SYMBOL_GPL(gether_cleanup); |
1018 | 1018 | ||
1019 | /** | 1019 | /** |
1020 | * gether_connect - notify network layer that USB link is active | 1020 | * gether_connect - notify network layer that USB link is active |
@@ -1095,7 +1095,7 @@ fail0: | |||
1095 | return ERR_PTR(result); | 1095 | return ERR_PTR(result); |
1096 | return dev->net; | 1096 | return dev->net; |
1097 | } | 1097 | } |
1098 | EXPORT_SYMBOL(gether_connect); | 1098 | EXPORT_SYMBOL_GPL(gether_connect); |
1099 | 1099 | ||
1100 | /** | 1100 | /** |
1101 | * gether_disconnect - notify network layer that USB link is inactive | 1101 | * gether_disconnect - notify network layer that USB link is inactive |
@@ -1166,7 +1166,7 @@ void gether_disconnect(struct gether *link) | |||
1166 | dev->port_usb = NULL; | 1166 | dev->port_usb = NULL; |
1167 | spin_unlock(&dev->lock); | 1167 | spin_unlock(&dev->lock); |
1168 | } | 1168 | } |
1169 | EXPORT_SYMBOL(gether_disconnect); | 1169 | EXPORT_SYMBOL_GPL(gether_disconnect); |
1170 | 1170 | ||
1171 | MODULE_LICENSE("GPL"); | 1171 | MODULE_LICENSE("GPL"); |
1172 | MODULE_AUTHOR("David Brownell"); | 1172 | MODULE_AUTHOR("David Brownell"); |
diff --git a/drivers/usb/gadget/u_f.c b/drivers/usb/gadget/u_f.c index 63b6642c162b..c6276f0268ae 100644 --- a/drivers/usb/gadget/u_f.c +++ b/drivers/usb/gadget/u_f.c | |||
@@ -29,4 +29,4 @@ struct usb_request *alloc_ep_req(struct usb_ep *ep, int len, int default_len) | |||
29 | } | 29 | } |
30 | return req; | 30 | return req; |
31 | } | 31 | } |
32 | EXPORT_SYMBOL(alloc_ep_req); | 32 | EXPORT_SYMBOL_GPL(alloc_ep_req); |
diff --git a/drivers/usb/gadget/u_f.h b/drivers/usb/gadget/u_f.h index 71034c061fca..1d5f0eb68552 100644 --- a/drivers/usb/gadget/u_f.h +++ b/drivers/usb/gadget/u_f.h | |||
@@ -16,6 +16,32 @@ | |||
16 | #ifndef __U_F_H__ | 16 | #ifndef __U_F_H__ |
17 | #define __U_F_H__ | 17 | #define __U_F_H__ |
18 | 18 | ||
19 | /* Variable Length Array Macros **********************************************/ | ||
20 | #define vla_group(groupname) size_t groupname##__next = 0 | ||
21 | #define vla_group_size(groupname) groupname##__next | ||
22 | |||
23 | #define vla_item(groupname, type, name, n) \ | ||
24 | size_t groupname##_##name##__offset = ({ \ | ||
25 | size_t align_mask = __alignof__(type) - 1; \ | ||
26 | size_t offset = (groupname##__next + align_mask) & ~align_mask;\ | ||
27 | size_t size = (n) * sizeof(type); \ | ||
28 | groupname##__next = offset + size; \ | ||
29 | offset; \ | ||
30 | }) | ||
31 | |||
32 | #define vla_item_with_sz(groupname, type, name, n) \ | ||
33 | size_t groupname##_##name##__sz = (n) * sizeof(type); \ | ||
34 | size_t groupname##_##name##__offset = ({ \ | ||
35 | size_t align_mask = __alignof__(type) - 1; \ | ||
36 | size_t offset = (groupname##__next + align_mask) & ~align_mask;\ | ||
37 | size_t size = groupname##_##name##__sz; \ | ||
38 | groupname##__next = offset + size; \ | ||
39 | offset; \ | ||
40 | }) | ||
41 | |||
42 | #define vla_ptr(ptr, groupname, name) \ | ||
43 | ((void *) ((char *)ptr + groupname##_##name##__offset)) | ||
44 | |||
19 | struct usb_ep; | 45 | struct usb_ep; |
20 | struct usb_request; | 46 | struct usb_request; |
21 | 47 | ||
diff --git a/drivers/usb/gadget/u_os_desc.h b/drivers/usb/gadget/u_os_desc.h new file mode 100644 index 000000000000..ea5cf8c2da28 --- /dev/null +++ b/drivers/usb/gadget/u_os_desc.h | |||
@@ -0,0 +1,90 @@ | |||
1 | /* | ||
2 | * u_os_desc.h | ||
3 | * | ||
4 | * Utility definitions for "OS Descriptors" support | ||
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 | |||
16 | #ifndef __U_OS_DESC_H__ | ||
17 | #define __U_OS_DESC_H__ | ||
18 | |||
19 | #include <asm/unaligned.h> | ||
20 | #include <linux/nls.h> | ||
21 | |||
22 | #define USB_EXT_PROP_DW_SIZE 0 | ||
23 | #define USB_EXT_PROP_DW_PROPERTY_DATA_TYPE 4 | ||
24 | #define USB_EXT_PROP_W_PROPERTY_NAME_LENGTH 8 | ||
25 | #define USB_EXT_PROP_B_PROPERTY_NAME 10 | ||
26 | #define USB_EXT_PROP_DW_PROPERTY_DATA_LENGTH 10 | ||
27 | #define USB_EXT_PROP_B_PROPERTY_DATA 14 | ||
28 | |||
29 | #define USB_EXT_PROP_RESERVED 0 | ||
30 | #define USB_EXT_PROP_UNICODE 1 | ||
31 | #define USB_EXT_PROP_UNICODE_ENV 2 | ||
32 | #define USB_EXT_PROP_BINARY 3 | ||
33 | #define USB_EXT_PROP_LE32 4 | ||
34 | #define USB_EXT_PROP_BE32 5 | ||
35 | #define USB_EXT_PROP_UNICODE_LINK 6 | ||
36 | #define USB_EXT_PROP_UNICODE_MULTI 7 | ||
37 | |||
38 | static inline void usb_ext_prop_put_size(u8 *buf, int dw_size) | ||
39 | { | ||
40 | put_unaligned_le32(dw_size, &buf[USB_EXT_PROP_DW_SIZE]); | ||
41 | } | ||
42 | |||
43 | static inline void usb_ext_prop_put_type(u8 *buf, int type) | ||
44 | { | ||
45 | put_unaligned_le32(type, &buf[USB_EXT_PROP_DW_PROPERTY_DATA_TYPE]); | ||
46 | } | ||
47 | |||
48 | static inline int usb_ext_prop_put_name(u8 *buf, const char *name, int pnl) | ||
49 | { | ||
50 | int result; | ||
51 | |||
52 | put_unaligned_le16(pnl, &buf[USB_EXT_PROP_W_PROPERTY_NAME_LENGTH]); | ||
53 | result = utf8s_to_utf16s(name, strlen(name), UTF16_LITTLE_ENDIAN, | ||
54 | (wchar_t *) &buf[USB_EXT_PROP_B_PROPERTY_NAME], pnl - 2); | ||
55 | if (result < 0) | ||
56 | return result; | ||
57 | |||
58 | put_unaligned_le16(0, &buf[USB_EXT_PROP_B_PROPERTY_NAME + pnl]); | ||
59 | |||
60 | return pnl; | ||
61 | } | ||
62 | |||
63 | static inline void usb_ext_prop_put_binary(u8 *buf, int pnl, const u8 *data, | ||
64 | int data_len) | ||
65 | { | ||
66 | put_unaligned_le32(data_len, | ||
67 | &buf[USB_EXT_PROP_DW_PROPERTY_DATA_LENGTH + pnl]); | ||
68 | memcpy(&buf[USB_EXT_PROP_B_PROPERTY_DATA + pnl], data, data_len); | ||
69 | } | ||
70 | |||
71 | static inline int usb_ext_prop_put_unicode(u8 *buf, int pnl, const char *string, | ||
72 | int data_len) | ||
73 | { | ||
74 | int result; | ||
75 | put_unaligned_le32(data_len, | ||
76 | &buf[USB_EXT_PROP_DW_PROPERTY_DATA_LENGTH + pnl]); | ||
77 | |||
78 | result = utf8s_to_utf16s(string, data_len >> 1, UTF16_LITTLE_ENDIAN, | ||
79 | (wchar_t *) &buf[USB_EXT_PROP_B_PROPERTY_DATA + pnl], | ||
80 | data_len - 2); | ||
81 | if (result < 0) | ||
82 | return result; | ||
83 | |||
84 | put_unaligned_le16(0, | ||
85 | &buf[USB_EXT_PROP_B_PROPERTY_DATA + pnl + data_len]); | ||
86 | |||
87 | return data_len; | ||
88 | } | ||
89 | |||
90 | #endif /* __U_OS_DESC_H__ */ | ||
diff --git a/drivers/usb/gadget/u_rndis.h b/drivers/usb/gadget/u_rndis.h index 7291b15c9dce..e902aa42a297 100644 --- a/drivers/usb/gadget/u_rndis.h +++ b/drivers/usb/gadget/u_rndis.h | |||
@@ -26,6 +26,9 @@ struct f_rndis_opts { | |||
26 | bool bound; | 26 | bool bound; |
27 | bool borrowed_net; | 27 | bool borrowed_net; |
28 | 28 | ||
29 | struct usb_os_desc rndis_os_desc; | ||
30 | char rndis_ext_compat_id[16]; | ||
31 | |||
29 | /* | 32 | /* |
30 | * Read/write access to configfs attributes is handled by configfs. | 33 | * Read/write access to configfs attributes is handled by configfs. |
31 | * | 34 | * |
diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index 27768a7d986a..b0d98172bc07 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c | |||
@@ -428,6 +428,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
428 | list_for_each_entry(udc, &udc_list, list) | 428 | list_for_each_entry(udc, &udc_list, list) |
429 | if (udc->driver == driver) { | 429 | if (udc->driver == driver) { |
430 | usb_gadget_remove_driver(udc); | 430 | usb_gadget_remove_driver(udc); |
431 | usb_gadget_set_state(udc->gadget, | ||
432 | USB_STATE_NOTATTACHED); | ||
431 | ret = 0; | 433 | ret = 0; |
432 | break; | 434 | break; |
433 | } | 435 | } |
diff --git a/drivers/usb/gadget/uvc_queue.c b/drivers/usb/gadget/uvc_queue.c index 0bb5d50075de..1c29bc954db9 100644 --- a/drivers/usb/gadget/uvc_queue.c +++ b/drivers/usb/gadget/uvc_queue.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/vmalloc.h> | 20 | #include <linux/vmalloc.h> |
21 | #include <linux/wait.h> | 21 | #include <linux/wait.h> |
22 | 22 | ||
23 | #include <media/v4l2-common.h> | ||
23 | #include <media/videobuf2-vmalloc.h> | 24 | #include <media/videobuf2-vmalloc.h> |
24 | 25 | ||
25 | #include "uvc.h" | 26 | #include "uvc.h" |
@@ -136,6 +137,8 @@ static int uvc_queue_init(struct uvc_video_queue *queue, | |||
136 | queue->queue.buf_struct_size = sizeof(struct uvc_buffer); | 137 | queue->queue.buf_struct_size = sizeof(struct uvc_buffer); |
137 | queue->queue.ops = &uvc_queue_qops; | 138 | queue->queue.ops = &uvc_queue_qops; |
138 | queue->queue.mem_ops = &vb2_vmalloc_memops; | 139 | queue->queue.mem_ops = &vb2_vmalloc_memops; |
140 | queue->queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC | ||
141 | | V4L2_BUF_FLAG_TSTAMP_SRC_EOF; | ||
139 | ret = vb2_queue_init(&queue->queue); | 142 | ret = vb2_queue_init(&queue->queue); |
140 | if (ret) | 143 | if (ret) |
141 | return ret; | 144 | return ret; |
@@ -379,14 +382,9 @@ static struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, | |||
379 | else | 382 | else |
380 | nextbuf = NULL; | 383 | nextbuf = NULL; |
381 | 384 | ||
382 | /* | 385 | buf->buf.v4l2_buf.field = V4L2_FIELD_NONE; |
383 | * FIXME: with videobuf2, the sequence number or timestamp fields | ||
384 | * are valid only for video capture devices and the UVC gadget usually | ||
385 | * is a video output device. Keeping these until the specs are clear on | ||
386 | * this aspect. | ||
387 | */ | ||
388 | buf->buf.v4l2_buf.sequence = queue->sequence++; | 386 | buf->buf.v4l2_buf.sequence = queue->sequence++; |
389 | do_gettimeofday(&buf->buf.v4l2_buf.timestamp); | 387 | v4l2_get_timestamp(&buf->buf.v4l2_buf.timestamp); |
390 | 388 | ||
391 | vb2_set_plane_payload(&buf->buf, 0, buf->bytesused); | 389 | vb2_set_plane_payload(&buf->buf, 0, buf->bytesused); |
392 | vb2_buffer_done(&buf->buf, VB2_BUF_STATE_DONE); | 390 | vb2_buffer_done(&buf->buf, VB2_BUF_STATE_DONE); |
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 3d9e54062d62..7a39ae86d5ce 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -170,7 +170,6 @@ config USB_EHCI_MSM | |||
170 | tristate "Support for Qualcomm QSD/MSM on-chip EHCI USB controller" | 170 | tristate "Support for Qualcomm QSD/MSM on-chip EHCI USB controller" |
171 | depends on ARCH_MSM | 171 | depends on ARCH_MSM |
172 | select USB_EHCI_ROOT_HUB_TT | 172 | select USB_EHCI_ROOT_HUB_TT |
173 | select USB_MSM_OTG | ||
174 | ---help--- | 173 | ---help--- |
175 | Enables support for the USB Host controller present on the | 174 | Enables support for the USB Host controller present on the |
176 | Qualcomm chipsets. Root Hub has inbuilt TT. | 175 | Qualcomm chipsets. Root Hub has inbuilt TT. |
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 8b789792f6fa..06cc5d6ea681 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig | |||
@@ -76,7 +76,7 @@ config USB_MUSB_TUSB6010 | |||
76 | 76 | ||
77 | config USB_MUSB_OMAP2PLUS | 77 | config USB_MUSB_OMAP2PLUS |
78 | tristate "OMAP2430 and onwards" | 78 | tristate "OMAP2430 and onwards" |
79 | depends on ARCH_OMAP2PLUS | 79 | depends on ARCH_OMAP2PLUS && USB |
80 | select GENERIC_PHY | 80 | select GENERIC_PHY |
81 | 81 | ||
82 | config USB_MUSB_AM35X | 82 | config USB_MUSB_AM35X |
@@ -141,10 +141,11 @@ config USB_TI_CPPI_DMA | |||
141 | config USB_TI_CPPI41_DMA | 141 | config USB_TI_CPPI41_DMA |
142 | bool 'TI CPPI 4.1 (AM335x)' | 142 | bool 'TI CPPI 4.1 (AM335x)' |
143 | depends on ARCH_OMAP | 143 | depends on ARCH_OMAP |
144 | select TI_CPPI41 | ||
144 | 145 | ||
145 | config USB_TUSB_OMAP_DMA | 146 | config USB_TUSB_OMAP_DMA |
146 | bool 'TUSB 6010' | 147 | bool 'TUSB 6010' |
147 | depends on USB_MUSB_TUSB6010 | 148 | depends on USB_MUSB_TUSB6010 = USB_MUSB_HDRC # both built-in or both modules |
148 | depends on ARCH_OMAP | 149 | depends on ARCH_OMAP |
149 | help | 150 | help |
150 | Enable DMA transfers on TUSB 6010 when OMAP DMA is available. | 151 | Enable DMA transfers on TUSB 6010 when OMAP DMA is available. |
diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index b3aa0184af9a..0a34dd859555 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include <linux/io.h> | 32 | #include <linux/io.h> |
33 | #include <linux/platform_device.h> | 33 | #include <linux/platform_device.h> |
34 | #include <linux/dma-mapping.h> | 34 | #include <linux/dma-mapping.h> |
35 | #include <linux/usb/usb_phy_gen_xceiv.h> | 35 | #include <linux/usb/usb_phy_generic.h> |
36 | #include <linux/platform_data/usb-omap.h> | 36 | #include <linux/platform_data/usb-omap.h> |
37 | 37 | ||
38 | #include "musb_core.h" | 38 | #include "musb_core.h" |
@@ -85,6 +85,7 @@ | |||
85 | struct am35x_glue { | 85 | struct am35x_glue { |
86 | struct device *dev; | 86 | struct device *dev; |
87 | struct platform_device *musb; | 87 | struct platform_device *musb; |
88 | struct platform_device *phy; | ||
88 | struct clk *phy_clk; | 89 | struct clk *phy_clk; |
89 | struct clk *clk; | 90 | struct clk *clk; |
90 | }; | 91 | }; |
@@ -360,7 +361,6 @@ static int am35x_musb_init(struct musb *musb) | |||
360 | if (!rev) | 361 | if (!rev) |
361 | return -ENODEV; | 362 | return -ENODEV; |
362 | 363 | ||
363 | usb_nop_xceiv_register(); | ||
364 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); | 364 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); |
365 | if (IS_ERR_OR_NULL(musb->xceiv)) | 365 | if (IS_ERR_OR_NULL(musb->xceiv)) |
366 | return -EPROBE_DEFER; | 366 | return -EPROBE_DEFER; |
@@ -402,7 +402,6 @@ static int am35x_musb_exit(struct musb *musb) | |||
402 | data->set_phy_power(0); | 402 | data->set_phy_power(0); |
403 | 403 | ||
404 | usb_put_phy(musb->xceiv); | 404 | usb_put_phy(musb->xceiv); |
405 | usb_nop_xceiv_unregister(); | ||
406 | 405 | ||
407 | return 0; | 406 | return 0; |
408 | } | 407 | } |
@@ -505,6 +504,9 @@ static int am35x_probe(struct platform_device *pdev) | |||
505 | 504 | ||
506 | pdata->platform_ops = &am35x_ops; | 505 | pdata->platform_ops = &am35x_ops; |
507 | 506 | ||
507 | glue->phy = usb_phy_generic_register(); | ||
508 | if (IS_ERR(glue->phy)) | ||
509 | goto err7; | ||
508 | platform_set_drvdata(pdev, glue); | 510 | platform_set_drvdata(pdev, glue); |
509 | 511 | ||
510 | pinfo = am35x_dev_info; | 512 | pinfo = am35x_dev_info; |
@@ -518,11 +520,14 @@ static int am35x_probe(struct platform_device *pdev) | |||
518 | if (IS_ERR(musb)) { | 520 | if (IS_ERR(musb)) { |
519 | ret = PTR_ERR(musb); | 521 | ret = PTR_ERR(musb); |
520 | dev_err(&pdev->dev, "failed to register musb device: %d\n", ret); | 522 | dev_err(&pdev->dev, "failed to register musb device: %d\n", ret); |
521 | goto err7; | 523 | goto err8; |
522 | } | 524 | } |
523 | 525 | ||
524 | return 0; | 526 | return 0; |
525 | 527 | ||
528 | err8: | ||
529 | usb_phy_generic_unregister(glue->phy); | ||
530 | |||
526 | err7: | 531 | err7: |
527 | clk_disable(clk); | 532 | clk_disable(clk); |
528 | 533 | ||
@@ -547,6 +552,7 @@ static int am35x_remove(struct platform_device *pdev) | |||
547 | struct am35x_glue *glue = platform_get_drvdata(pdev); | 552 | struct am35x_glue *glue = platform_get_drvdata(pdev); |
548 | 553 | ||
549 | platform_device_unregister(glue->musb); | 554 | platform_device_unregister(glue->musb); |
555 | usb_phy_generic_unregister(glue->phy); | ||
550 | clk_disable(glue->clk); | 556 | clk_disable(glue->clk); |
551 | clk_disable(glue->phy_clk); | 557 | clk_disable(glue->phy_clk); |
552 | clk_put(glue->clk); | 558 | clk_put(glue->clk); |
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index 796677fa9a15..d40d5f0b5528 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | #include <linux/dma-mapping.h> | 19 | #include <linux/dma-mapping.h> |
20 | #include <linux/prefetch.h> | 20 | #include <linux/prefetch.h> |
21 | #include <linux/usb/usb_phy_gen_xceiv.h> | 21 | #include <linux/usb/usb_phy_generic.h> |
22 | 22 | ||
23 | #include <asm/cacheflush.h> | 23 | #include <asm/cacheflush.h> |
24 | 24 | ||
@@ -29,6 +29,7 @@ | |||
29 | struct bfin_glue { | 29 | struct bfin_glue { |
30 | struct device *dev; | 30 | struct device *dev; |
31 | struct platform_device *musb; | 31 | struct platform_device *musb; |
32 | struct platform_device *phy; | ||
32 | }; | 33 | }; |
33 | #define glue_to_musb(g) platform_get_drvdata(g->musb) | 34 | #define glue_to_musb(g) platform_get_drvdata(g->musb) |
34 | 35 | ||
@@ -401,7 +402,6 @@ static int bfin_musb_init(struct musb *musb) | |||
401 | } | 402 | } |
402 | gpio_direction_output(musb->config->gpio_vrsel, 0); | 403 | gpio_direction_output(musb->config->gpio_vrsel, 0); |
403 | 404 | ||
404 | usb_nop_xceiv_register(); | ||
405 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); | 405 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); |
406 | if (IS_ERR_OR_NULL(musb->xceiv)) { | 406 | if (IS_ERR_OR_NULL(musb->xceiv)) { |
407 | gpio_free(musb->config->gpio_vrsel); | 407 | gpio_free(musb->config->gpio_vrsel); |
@@ -424,9 +424,8 @@ static int bfin_musb_init(struct musb *musb) | |||
424 | static int bfin_musb_exit(struct musb *musb) | 424 | static int bfin_musb_exit(struct musb *musb) |
425 | { | 425 | { |
426 | gpio_free(musb->config->gpio_vrsel); | 426 | gpio_free(musb->config->gpio_vrsel); |
427 | |||
428 | usb_put_phy(musb->xceiv); | 427 | usb_put_phy(musb->xceiv); |
429 | usb_nop_xceiv_unregister(); | 428 | |
430 | return 0; | 429 | return 0; |
431 | } | 430 | } |
432 | 431 | ||
@@ -477,6 +476,9 @@ static int bfin_probe(struct platform_device *pdev) | |||
477 | 476 | ||
478 | pdata->platform_ops = &bfin_ops; | 477 | pdata->platform_ops = &bfin_ops; |
479 | 478 | ||
479 | glue->phy = usb_phy_generic_register(); | ||
480 | if (IS_ERR(glue->phy)) | ||
481 | goto err2; | ||
480 | platform_set_drvdata(pdev, glue); | 482 | platform_set_drvdata(pdev, glue); |
481 | 483 | ||
482 | memset(musb_resources, 0x00, sizeof(*musb_resources) * | 484 | memset(musb_resources, 0x00, sizeof(*musb_resources) * |
@@ -514,6 +516,9 @@ static int bfin_probe(struct platform_device *pdev) | |||
514 | return 0; | 516 | return 0; |
515 | 517 | ||
516 | err3: | 518 | err3: |
519 | usb_phy_generic_unregister(glue->phy); | ||
520 | |||
521 | err2: | ||
517 | platform_device_put(musb); | 522 | platform_device_put(musb); |
518 | 523 | ||
519 | err1: | 524 | err1: |
@@ -528,6 +533,7 @@ static int bfin_remove(struct platform_device *pdev) | |||
528 | struct bfin_glue *glue = platform_get_drvdata(pdev); | 533 | struct bfin_glue *glue = platform_get_drvdata(pdev); |
529 | 534 | ||
530 | platform_device_unregister(glue->musb); | 535 | platform_device_unregister(glue->musb); |
536 | usb_phy_generic_unregister(glue->phy); | ||
531 | kfree(glue); | 537 | kfree(glue); |
532 | 538 | ||
533 | return 0; | 539 | return 0; |
diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index e3486de71995..058775e647ad 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include <linux/io.h> | 32 | #include <linux/io.h> |
33 | #include <linux/platform_device.h> | 33 | #include <linux/platform_device.h> |
34 | #include <linux/dma-mapping.h> | 34 | #include <linux/dma-mapping.h> |
35 | #include <linux/usb/usb_phy_gen_xceiv.h> | 35 | #include <linux/usb/usb_phy_generic.h> |
36 | 36 | ||
37 | #include <mach/da8xx.h> | 37 | #include <mach/da8xx.h> |
38 | #include <linux/platform_data/usb-davinci.h> | 38 | #include <linux/platform_data/usb-davinci.h> |
@@ -85,6 +85,7 @@ | |||
85 | struct da8xx_glue { | 85 | struct da8xx_glue { |
86 | struct device *dev; | 86 | struct device *dev; |
87 | struct platform_device *musb; | 87 | struct platform_device *musb; |
88 | struct platform_device *phy; | ||
88 | struct clk *clk; | 89 | struct clk *clk; |
89 | }; | 90 | }; |
90 | 91 | ||
@@ -418,7 +419,6 @@ static int da8xx_musb_init(struct musb *musb) | |||
418 | if (!rev) | 419 | if (!rev) |
419 | goto fail; | 420 | goto fail; |
420 | 421 | ||
421 | usb_nop_xceiv_register(); | ||
422 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); | 422 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); |
423 | if (IS_ERR_OR_NULL(musb->xceiv)) { | 423 | if (IS_ERR_OR_NULL(musb->xceiv)) { |
424 | ret = -EPROBE_DEFER; | 424 | ret = -EPROBE_DEFER; |
@@ -453,7 +453,6 @@ static int da8xx_musb_exit(struct musb *musb) | |||
453 | phy_off(); | 453 | phy_off(); |
454 | 454 | ||
455 | usb_put_phy(musb->xceiv); | 455 | usb_put_phy(musb->xceiv); |
456 | usb_nop_xceiv_unregister(); | ||
457 | 456 | ||
458 | return 0; | 457 | return 0; |
459 | } | 458 | } |
@@ -512,6 +511,11 @@ static int da8xx_probe(struct platform_device *pdev) | |||
512 | 511 | ||
513 | pdata->platform_ops = &da8xx_ops; | 512 | pdata->platform_ops = &da8xx_ops; |
514 | 513 | ||
514 | glue->phy = usb_phy_generic_register(); | ||
515 | if (IS_ERR(glue->phy)) { | ||
516 | ret = PTR_ERR(glue->phy); | ||
517 | goto err5; | ||
518 | } | ||
515 | platform_set_drvdata(pdev, glue); | 519 | platform_set_drvdata(pdev, glue); |
516 | 520 | ||
517 | memset(musb_resources, 0x00, sizeof(*musb_resources) * | 521 | memset(musb_resources, 0x00, sizeof(*musb_resources) * |
@@ -538,11 +542,14 @@ static int da8xx_probe(struct platform_device *pdev) | |||
538 | if (IS_ERR(musb)) { | 542 | if (IS_ERR(musb)) { |
539 | ret = PTR_ERR(musb); | 543 | ret = PTR_ERR(musb); |
540 | dev_err(&pdev->dev, "failed to register musb device: %d\n", ret); | 544 | dev_err(&pdev->dev, "failed to register musb device: %d\n", ret); |
541 | goto err5; | 545 | goto err6; |
542 | } | 546 | } |
543 | 547 | ||
544 | return 0; | 548 | return 0; |
545 | 549 | ||
550 | err6: | ||
551 | usb_phy_generic_unregister(glue->phy); | ||
552 | |||
546 | err5: | 553 | err5: |
547 | clk_disable(clk); | 554 | clk_disable(clk); |
548 | 555 | ||
@@ -561,6 +568,7 @@ static int da8xx_remove(struct platform_device *pdev) | |||
561 | struct da8xx_glue *glue = platform_get_drvdata(pdev); | 568 | struct da8xx_glue *glue = platform_get_drvdata(pdev); |
562 | 569 | ||
563 | platform_device_unregister(glue->musb); | 570 | platform_device_unregister(glue->musb); |
571 | usb_phy_generic_unregister(glue->phy); | ||
564 | clk_disable(glue->clk); | 572 | clk_disable(glue->clk); |
565 | clk_put(glue->clk); | 573 | clk_put(glue->clk); |
566 | kfree(glue); | 574 | kfree(glue); |
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index c259dac9d056..de8492b06e46 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include <linux/gpio.h> | 32 | #include <linux/gpio.h> |
33 | #include <linux/platform_device.h> | 33 | #include <linux/platform_device.h> |
34 | #include <linux/dma-mapping.h> | 34 | #include <linux/dma-mapping.h> |
35 | #include <linux/usb/usb_phy_gen_xceiv.h> | 35 | #include <linux/usb/usb_phy_generic.h> |
36 | 36 | ||
37 | #include <mach/cputype.h> | 37 | #include <mach/cputype.h> |
38 | #include <mach/hardware.h> | 38 | #include <mach/hardware.h> |
@@ -381,7 +381,6 @@ static int davinci_musb_init(struct musb *musb) | |||
381 | u32 revision; | 381 | u32 revision; |
382 | int ret = -ENODEV; | 382 | int ret = -ENODEV; |
383 | 383 | ||
384 | usb_nop_xceiv_register(); | ||
385 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); | 384 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); |
386 | if (IS_ERR_OR_NULL(musb->xceiv)) { | 385 | if (IS_ERR_OR_NULL(musb->xceiv)) { |
387 | ret = -EPROBE_DEFER; | 386 | ret = -EPROBE_DEFER; |
@@ -439,7 +438,7 @@ static int davinci_musb_init(struct musb *musb) | |||
439 | fail: | 438 | fail: |
440 | usb_put_phy(musb->xceiv); | 439 | usb_put_phy(musb->xceiv); |
441 | unregister: | 440 | unregister: |
442 | usb_nop_xceiv_unregister(); | 441 | usb_phy_generic_unregister(); |
443 | return ret; | 442 | return ret; |
444 | } | 443 | } |
445 | 444 | ||
@@ -487,7 +486,6 @@ static int davinci_musb_exit(struct musb *musb) | |||
487 | phy_off(); | 486 | phy_off(); |
488 | 487 | ||
489 | usb_put_phy(musb->xceiv); | 488 | usb_put_phy(musb->xceiv); |
490 | usb_nop_xceiv_unregister(); | ||
491 | 489 | ||
492 | return 0; | 490 | return 0; |
493 | } | 491 | } |
@@ -545,6 +543,7 @@ static int davinci_probe(struct platform_device *pdev) | |||
545 | 543 | ||
546 | pdata->platform_ops = &davinci_ops; | 544 | pdata->platform_ops = &davinci_ops; |
547 | 545 | ||
546 | usb_phy_generic_register(); | ||
548 | platform_set_drvdata(pdev, glue); | 547 | platform_set_drvdata(pdev, glue); |
549 | 548 | ||
550 | memset(musb_resources, 0x00, sizeof(*musb_resources) * | 549 | memset(musb_resources, 0x00, sizeof(*musb_resources) * |
@@ -603,6 +602,7 @@ static int davinci_remove(struct platform_device *pdev) | |||
603 | struct davinci_glue *glue = platform_get_drvdata(pdev); | 602 | struct davinci_glue *glue = platform_get_drvdata(pdev); |
604 | 603 | ||
605 | platform_device_unregister(glue->musb); | 604 | platform_device_unregister(glue->musb); |
605 | usb_phy_generic_unregister(); | ||
606 | clk_disable(glue->clk); | 606 | clk_disable(glue->clk); |
607 | clk_put(glue->clk); | 607 | clk_put(glue->clk); |
608 | kfree(glue); | 608 | kfree(glue); |
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 07576907e2c6..61da471b7aed 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -848,6 +848,10 @@ b_host: | |||
848 | } | 848 | } |
849 | } | 849 | } |
850 | 850 | ||
851 | /* handle babble condition */ | ||
852 | if (int_usb & MUSB_INTR_BABBLE) | ||
853 | schedule_work(&musb->recover_work); | ||
854 | |||
851 | #if 0 | 855 | #if 0 |
852 | /* REVISIT ... this would be for multiplexing periodic endpoints, or | 856 | /* REVISIT ... this would be for multiplexing periodic endpoints, or |
853 | * supporting transfer phasing to prevent exceeding ISO bandwidth | 857 | * supporting transfer phasing to prevent exceeding ISO bandwidth |
@@ -1746,6 +1750,34 @@ static void musb_irq_work(struct work_struct *data) | |||
1746 | } | 1750 | } |
1747 | } | 1751 | } |
1748 | 1752 | ||
1753 | /* Recover from babble interrupt conditions */ | ||
1754 | static void musb_recover_work(struct work_struct *data) | ||
1755 | { | ||
1756 | struct musb *musb = container_of(data, struct musb, recover_work); | ||
1757 | int status; | ||
1758 | |||
1759 | musb_platform_reset(musb); | ||
1760 | |||
1761 | usb_phy_vbus_off(musb->xceiv); | ||
1762 | udelay(100); | ||
1763 | |||
1764 | usb_phy_vbus_on(musb->xceiv); | ||
1765 | udelay(100); | ||
1766 | |||
1767 | /* | ||
1768 | * When a babble condition occurs, the musb controller removes the | ||
1769 | * session bit and the endpoint config is lost. | ||
1770 | */ | ||
1771 | if (musb->dyn_fifo) | ||
1772 | status = ep_config_from_table(musb); | ||
1773 | else | ||
1774 | status = ep_config_from_hw(musb); | ||
1775 | |||
1776 | /* start the session again */ | ||
1777 | if (status == 0) | ||
1778 | musb_start(musb); | ||
1779 | } | ||
1780 | |||
1749 | /* -------------------------------------------------------------------------- | 1781 | /* -------------------------------------------------------------------------- |
1750 | * Init support | 1782 | * Init support |
1751 | */ | 1783 | */ |
@@ -1913,6 +1945,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) | |||
1913 | 1945 | ||
1914 | /* Init IRQ workqueue before request_irq */ | 1946 | /* Init IRQ workqueue before request_irq */ |
1915 | INIT_WORK(&musb->irq_work, musb_irq_work); | 1947 | INIT_WORK(&musb->irq_work, musb_irq_work); |
1948 | INIT_WORK(&musb->recover_work, musb_recover_work); | ||
1916 | INIT_DELAYED_WORK(&musb->deassert_reset_work, musb_deassert_reset); | 1949 | INIT_DELAYED_WORK(&musb->deassert_reset_work, musb_deassert_reset); |
1917 | INIT_DELAYED_WORK(&musb->finish_resume_work, musb_host_finish_resume); | 1950 | INIT_DELAYED_WORK(&musb->finish_resume_work, musb_host_finish_resume); |
1918 | 1951 | ||
@@ -2008,6 +2041,7 @@ fail4: | |||
2008 | 2041 | ||
2009 | fail3: | 2042 | fail3: |
2010 | cancel_work_sync(&musb->irq_work); | 2043 | cancel_work_sync(&musb->irq_work); |
2044 | cancel_work_sync(&musb->recover_work); | ||
2011 | cancel_delayed_work_sync(&musb->finish_resume_work); | 2045 | cancel_delayed_work_sync(&musb->finish_resume_work); |
2012 | cancel_delayed_work_sync(&musb->deassert_reset_work); | 2046 | cancel_delayed_work_sync(&musb->deassert_reset_work); |
2013 | if (musb->dma_controller) | 2047 | if (musb->dma_controller) |
@@ -2073,6 +2107,7 @@ static int musb_remove(struct platform_device *pdev) | |||
2073 | dma_controller_destroy(musb->dma_controller); | 2107 | dma_controller_destroy(musb->dma_controller); |
2074 | 2108 | ||
2075 | cancel_work_sync(&musb->irq_work); | 2109 | cancel_work_sync(&musb->irq_work); |
2110 | cancel_work_sync(&musb->recover_work); | ||
2076 | cancel_delayed_work_sync(&musb->finish_resume_work); | 2111 | cancel_delayed_work_sync(&musb->finish_resume_work); |
2077 | cancel_delayed_work_sync(&musb->deassert_reset_work); | 2112 | cancel_delayed_work_sync(&musb->deassert_reset_work); |
2078 | musb_free(musb); | 2113 | musb_free(musb); |
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 7083e82776ff..d155a156f240 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h | |||
@@ -192,6 +192,7 @@ struct musb_platform_ops { | |||
192 | 192 | ||
193 | int (*set_mode)(struct musb *musb, u8 mode); | 193 | int (*set_mode)(struct musb *musb, u8 mode); |
194 | void (*try_idle)(struct musb *musb, unsigned long timeout); | 194 | void (*try_idle)(struct musb *musb, unsigned long timeout); |
195 | void (*reset)(struct musb *musb); | ||
195 | 196 | ||
196 | int (*vbus_status)(struct musb *musb); | 197 | int (*vbus_status)(struct musb *musb); |
197 | void (*set_vbus)(struct musb *musb, int on); | 198 | void (*set_vbus)(struct musb *musb, int on); |
@@ -296,6 +297,7 @@ struct musb { | |||
296 | 297 | ||
297 | irqreturn_t (*isr)(int, void *); | 298 | irqreturn_t (*isr)(int, void *); |
298 | struct work_struct irq_work; | 299 | struct work_struct irq_work; |
300 | struct work_struct recover_work; | ||
299 | struct delayed_work deassert_reset_work; | 301 | struct delayed_work deassert_reset_work; |
300 | struct delayed_work finish_resume_work; | 302 | struct delayed_work finish_resume_work; |
301 | u16 hwvers; | 303 | u16 hwvers; |
@@ -337,6 +339,7 @@ struct musb { | |||
337 | dma_addr_t async; | 339 | dma_addr_t async; |
338 | dma_addr_t sync; | 340 | dma_addr_t sync; |
339 | void __iomem *sync_va; | 341 | void __iomem *sync_va; |
342 | u8 tusb_revision; | ||
340 | #endif | 343 | #endif |
341 | 344 | ||
342 | /* passed down from chip/board specific irq handlers */ | 345 | /* passed down from chip/board specific irq handlers */ |
@@ -552,6 +555,12 @@ static inline void musb_platform_try_idle(struct musb *musb, | |||
552 | musb->ops->try_idle(musb, timeout); | 555 | musb->ops->try_idle(musb, timeout); |
553 | } | 556 | } |
554 | 557 | ||
558 | static inline void musb_platform_reset(struct musb *musb) | ||
559 | { | ||
560 | if (musb->ops->reset) | ||
561 | musb->ops->reset(musb); | ||
562 | } | ||
563 | |||
555 | static inline int musb_platform_get_vbus_status(struct musb *musb) | 564 | static inline int musb_platform_get_vbus_status(struct musb *musb) |
556 | { | 565 | { |
557 | if (!musb->ops->vbus_status) | 566 | if (!musb->ops->vbus_status) |
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index e2fd263585de..51beb13c7e1a 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include <linux/dma-mapping.h> | 35 | #include <linux/dma-mapping.h> |
36 | #include <linux/pm_runtime.h> | 36 | #include <linux/pm_runtime.h> |
37 | #include <linux/module.h> | 37 | #include <linux/module.h> |
38 | #include <linux/usb/usb_phy_gen_xceiv.h> | 38 | #include <linux/usb/usb_phy_generic.h> |
39 | #include <linux/platform_data/usb-omap.h> | 39 | #include <linux/platform_data/usb-omap.h> |
40 | #include <linux/sizes.h> | 40 | #include <linux/sizes.h> |
41 | 41 | ||
@@ -329,9 +329,21 @@ static irqreturn_t dsps_interrupt(int irq, void *hci) | |||
329 | * value but DEVCTL.BDEVICE is invalid without DEVCTL.SESSION set. | 329 | * value but DEVCTL.BDEVICE is invalid without DEVCTL.SESSION set. |
330 | * Also, DRVVBUS pulses for SRP (but not at 5V) ... | 330 | * Also, DRVVBUS pulses for SRP (but not at 5V) ... |
331 | */ | 331 | */ |
332 | if (is_host_active(musb) && usbintr & MUSB_INTR_BABBLE) | 332 | if (is_host_active(musb) && usbintr & MUSB_INTR_BABBLE) { |
333 | pr_info("CAUTION: musb: Babble Interrupt Occurred\n"); | 333 | pr_info("CAUTION: musb: Babble Interrupt Occurred\n"); |
334 | 334 | ||
335 | /* | ||
336 | * When a babble condition occurs, the musb controller removes | ||
337 | * the session and is no longer in host mode. Hence, all | ||
338 | * devices connected to its root hub get disconnected. | ||
339 | * | ||
340 | * Hand this error down to the musb core isr, so it can | ||
341 | * recover. | ||
342 | */ | ||
343 | musb->int_usb = MUSB_INTR_BABBLE | MUSB_INTR_DISCONNECT; | ||
344 | musb->int_tx = musb->int_rx = 0; | ||
345 | } | ||
346 | |||
335 | if (usbintr & ((1 << wrp->drvvbus) << wrp->usb_shift)) { | 347 | if (usbintr & ((1 << wrp->drvvbus) << wrp->usb_shift)) { |
336 | int drvvbus = dsps_readl(reg_base, wrp->status); | 348 | int drvvbus = dsps_readl(reg_base, wrp->status); |
337 | void __iomem *mregs = musb->mregs; | 349 | void __iomem *mregs = musb->mregs; |
@@ -524,6 +536,16 @@ static int dsps_musb_set_mode(struct musb *musb, u8 mode) | |||
524 | return 0; | 536 | return 0; |
525 | } | 537 | } |
526 | 538 | ||
539 | static void dsps_musb_reset(struct musb *musb) | ||
540 | { | ||
541 | struct device *dev = musb->controller; | ||
542 | struct dsps_glue *glue = dev_get_drvdata(dev->parent); | ||
543 | const struct dsps_musb_wrapper *wrp = glue->wrp; | ||
544 | |||
545 | dsps_writel(musb->ctrl_base, wrp->control, (1 << wrp->reset)); | ||
546 | udelay(100); | ||
547 | } | ||
548 | |||
527 | static struct musb_platform_ops dsps_ops = { | 549 | static struct musb_platform_ops dsps_ops = { |
528 | .init = dsps_musb_init, | 550 | .init = dsps_musb_init, |
529 | .exit = dsps_musb_exit, | 551 | .exit = dsps_musb_exit, |
@@ -533,6 +555,7 @@ static struct musb_platform_ops dsps_ops = { | |||
533 | 555 | ||
534 | .try_idle = dsps_musb_try_idle, | 556 | .try_idle = dsps_musb_try_idle, |
535 | .set_mode = dsps_musb_set_mode, | 557 | .set_mode = dsps_musb_set_mode, |
558 | .reset = dsps_musb_reset, | ||
536 | }; | 559 | }; |
537 | 560 | ||
538 | static u64 musb_dmamask = DMA_BIT_MASK(32); | 561 | static u64 musb_dmamask = DMA_BIT_MASK(32); |
@@ -750,7 +773,7 @@ static const struct of_device_id musb_dsps_of_match[] = { | |||
750 | }; | 773 | }; |
751 | MODULE_DEVICE_TABLE(of, musb_dsps_of_match); | 774 | MODULE_DEVICE_TABLE(of, musb_dsps_of_match); |
752 | 775 | ||
753 | #ifdef CONFIG_PM | 776 | #ifdef CONFIG_PM_SLEEP |
754 | static int dsps_suspend(struct device *dev) | 777 | static int dsps_suspend(struct device *dev) |
755 | { | 778 | { |
756 | struct dsps_glue *glue = dev_get_drvdata(dev); | 779 | struct dsps_glue *glue = dev_get_drvdata(dev); |
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 4e9fb1d08698..159ef4be1ef2 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c | |||
@@ -24,13 +24,14 @@ | |||
24 | #include <linux/io.h> | 24 | #include <linux/io.h> |
25 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
26 | #include <linux/dma-mapping.h> | 26 | #include <linux/dma-mapping.h> |
27 | #include <linux/usb/usb_phy_gen_xceiv.h> | 27 | #include <linux/usb/usb_phy_generic.h> |
28 | 28 | ||
29 | #include "musb_core.h" | 29 | #include "musb_core.h" |
30 | 30 | ||
31 | struct tusb6010_glue { | 31 | struct tusb6010_glue { |
32 | struct device *dev; | 32 | struct device *dev; |
33 | struct platform_device *musb; | 33 | struct platform_device *musb; |
34 | struct platform_device *phy; | ||
34 | }; | 35 | }; |
35 | 36 | ||
36 | static void tusb_musb_set_vbus(struct musb *musb, int is_on); | 37 | static void tusb_musb_set_vbus(struct musb *musb, int is_on); |
@@ -42,7 +43,7 @@ static void tusb_musb_set_vbus(struct musb *musb, int is_on); | |||
42 | * Checks the revision. We need to use the DMA register as 3.0 does not | 43 | * Checks the revision. We need to use the DMA register as 3.0 does not |
43 | * have correct versions for TUSB_PRCM_REV or TUSB_INT_CTRL_REV. | 44 | * have correct versions for TUSB_PRCM_REV or TUSB_INT_CTRL_REV. |
44 | */ | 45 | */ |
45 | u8 tusb_get_revision(struct musb *musb) | 46 | static u8 tusb_get_revision(struct musb *musb) |
46 | { | 47 | { |
47 | void __iomem *tbase = musb->ctrl_base; | 48 | void __iomem *tbase = musb->ctrl_base; |
48 | u32 die_id; | 49 | u32 die_id; |
@@ -58,14 +59,13 @@ u8 tusb_get_revision(struct musb *musb) | |||
58 | 59 | ||
59 | return rev; | 60 | return rev; |
60 | } | 61 | } |
61 | EXPORT_SYMBOL_GPL(tusb_get_revision); | ||
62 | 62 | ||
63 | static int tusb_print_revision(struct musb *musb) | 63 | static void tusb_print_revision(struct musb *musb) |
64 | { | 64 | { |
65 | void __iomem *tbase = musb->ctrl_base; | 65 | void __iomem *tbase = musb->ctrl_base; |
66 | u8 rev; | 66 | u8 rev; |
67 | 67 | ||
68 | rev = tusb_get_revision(musb); | 68 | rev = musb->tusb_revision; |
69 | 69 | ||
70 | pr_info("tusb: %s%i.%i %s%i.%i %s%i.%i %s%i.%i %s%i %s%i.%i\n", | 70 | pr_info("tusb: %s%i.%i %s%i.%i %s%i.%i %s%i.%i %s%i %s%i.%i\n", |
71 | "prcm", | 71 | "prcm", |
@@ -84,8 +84,6 @@ static int tusb_print_revision(struct musb *musb) | |||
84 | TUSB_DIDR1_HI_CHIP_REV(musb_readl(tbase, TUSB_DIDR1_HI)), | 84 | TUSB_DIDR1_HI_CHIP_REV(musb_readl(tbase, TUSB_DIDR1_HI)), |
85 | "rev", | 85 | "rev", |
86 | TUSB_REV_MAJOR(rev), TUSB_REV_MINOR(rev)); | 86 | TUSB_REV_MAJOR(rev), TUSB_REV_MINOR(rev)); |
87 | |||
88 | return tusb_get_revision(musb); | ||
89 | } | 87 | } |
90 | 88 | ||
91 | #define WBUS_QUIRK_MASK (TUSB_PHY_OTG_CTRL_TESTM2 | TUSB_PHY_OTG_CTRL_TESTM1 \ | 89 | #define WBUS_QUIRK_MASK (TUSB_PHY_OTG_CTRL_TESTM2 | TUSB_PHY_OTG_CTRL_TESTM1 \ |
@@ -349,7 +347,7 @@ static void tusb_allow_idle(struct musb *musb, u32 wakeup_enables) | |||
349 | u32 reg; | 347 | u32 reg; |
350 | 348 | ||
351 | if ((wakeup_enables & TUSB_PRCM_WBUS) | 349 | if ((wakeup_enables & TUSB_PRCM_WBUS) |
352 | && (tusb_get_revision(musb) == TUSB_REV_30)) | 350 | && (musb->tusb_revision == TUSB_REV_30)) |
353 | tusb_wbus_quirk(musb, 1); | 351 | tusb_wbus_quirk(musb, 1); |
354 | 352 | ||
355 | tusb_set_clock_source(musb, 0); | 353 | tusb_set_clock_source(musb, 0); |
@@ -797,7 +795,7 @@ static irqreturn_t tusb_musb_interrupt(int irq, void *__hci) | |||
797 | u32 reg; | 795 | u32 reg; |
798 | u32 i; | 796 | u32 i; |
799 | 797 | ||
800 | if (tusb_get_revision(musb) == TUSB_REV_30) | 798 | if (musb->tusb_revision == TUSB_REV_30) |
801 | tusb_wbus_quirk(musb, 0); | 799 | tusb_wbus_quirk(musb, 0); |
802 | 800 | ||
803 | /* there are issues re-locking the PLL on wakeup ... */ | 801 | /* there are issues re-locking the PLL on wakeup ... */ |
@@ -1011,10 +1009,11 @@ static int tusb_musb_start(struct musb *musb) | |||
1011 | goto err; | 1009 | goto err; |
1012 | } | 1010 | } |
1013 | 1011 | ||
1014 | ret = tusb_print_revision(musb); | 1012 | musb->tusb_revision = tusb_get_revision(musb); |
1015 | if (ret < 2) { | 1013 | tusb_print_revision(musb); |
1014 | if (musb->tusb_revision < 2) { | ||
1016 | printk(KERN_ERR "tusb: Unsupported TUSB6010 revision %i\n", | 1015 | printk(KERN_ERR "tusb: Unsupported TUSB6010 revision %i\n", |
1017 | ret); | 1016 | musb->tusb_revision); |
1018 | goto err; | 1017 | goto err; |
1019 | } | 1018 | } |
1020 | 1019 | ||
@@ -1065,7 +1064,6 @@ static int tusb_musb_init(struct musb *musb) | |||
1065 | void __iomem *sync = NULL; | 1064 | void __iomem *sync = NULL; |
1066 | int ret; | 1065 | int ret; |
1067 | 1066 | ||
1068 | usb_nop_xceiv_register(); | ||
1069 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); | 1067 | musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); |
1070 | if (IS_ERR_OR_NULL(musb->xceiv)) | 1068 | if (IS_ERR_OR_NULL(musb->xceiv)) |
1071 | return -EPROBE_DEFER; | 1069 | return -EPROBE_DEFER; |
@@ -1117,7 +1115,6 @@ done: | |||
1117 | iounmap(sync); | 1115 | iounmap(sync); |
1118 | 1116 | ||
1119 | usb_put_phy(musb->xceiv); | 1117 | usb_put_phy(musb->xceiv); |
1120 | usb_nop_xceiv_unregister(); | ||
1121 | } | 1118 | } |
1122 | return ret; | 1119 | return ret; |
1123 | } | 1120 | } |
@@ -1133,7 +1130,6 @@ static int tusb_musb_exit(struct musb *musb) | |||
1133 | iounmap(musb->sync_va); | 1130 | iounmap(musb->sync_va); |
1134 | 1131 | ||
1135 | usb_put_phy(musb->xceiv); | 1132 | usb_put_phy(musb->xceiv); |
1136 | usb_nop_xceiv_unregister(); | ||
1137 | return 0; | 1133 | return 0; |
1138 | } | 1134 | } |
1139 | 1135 | ||
@@ -1176,6 +1172,7 @@ static int tusb_probe(struct platform_device *pdev) | |||
1176 | 1172 | ||
1177 | pdata->platform_ops = &tusb_ops; | 1173 | pdata->platform_ops = &tusb_ops; |
1178 | 1174 | ||
1175 | usb_phy_generic_register(); | ||
1179 | platform_set_drvdata(pdev, glue); | 1176 | platform_set_drvdata(pdev, glue); |
1180 | 1177 | ||
1181 | memset(musb_resources, 0x00, sizeof(*musb_resources) * | 1178 | memset(musb_resources, 0x00, sizeof(*musb_resources) * |
@@ -1224,6 +1221,7 @@ static int tusb_remove(struct platform_device *pdev) | |||
1224 | struct tusb6010_glue *glue = platform_get_drvdata(pdev); | 1221 | struct tusb6010_glue *glue = platform_get_drvdata(pdev); |
1225 | 1222 | ||
1226 | platform_device_unregister(glue->musb); | 1223 | platform_device_unregister(glue->musb); |
1224 | usb_phy_generic_unregister(glue->phy); | ||
1227 | kfree(glue); | 1225 | kfree(glue); |
1228 | 1226 | ||
1229 | return 0; | 1227 | return 0; |
diff --git a/drivers/usb/musb/tusb6010.h b/drivers/usb/musb/tusb6010.h index 35c933a5d991..aec86c86ce32 100644 --- a/drivers/usb/musb/tusb6010.h +++ b/drivers/usb/musb/tusb6010.h | |||
@@ -12,14 +12,6 @@ | |||
12 | #ifndef __TUSB6010_H__ | 12 | #ifndef __TUSB6010_H__ |
13 | #define __TUSB6010_H__ | 13 | #define __TUSB6010_H__ |
14 | 14 | ||
15 | extern u8 tusb_get_revision(struct musb *musb); | ||
16 | |||
17 | #ifdef CONFIG_USB_TUSB6010 | ||
18 | #define musb_in_tusb() 1 | ||
19 | #else | ||
20 | #define musb_in_tusb() 0 | ||
21 | #endif | ||
22 | |||
23 | #ifdef CONFIG_USB_TUSB_OMAP_DMA | 15 | #ifdef CONFIG_USB_TUSB_OMAP_DMA |
24 | #define tusb_dma_omap() 1 | 16 | #define tusb_dma_omap() 1 |
25 | #else | 17 | #else |
diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c index e33b6b2c44c2..3ce152c0408e 100644 --- a/drivers/usb/musb/tusb6010_omap.c +++ b/drivers/usb/musb/tusb6010_omap.c | |||
@@ -677,7 +677,7 @@ struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *ba | |||
677 | tusb_dma->controller.channel_program = tusb_omap_dma_program; | 677 | tusb_dma->controller.channel_program = tusb_omap_dma_program; |
678 | tusb_dma->controller.channel_abort = tusb_omap_dma_abort; | 678 | tusb_dma->controller.channel_abort = tusb_omap_dma_abort; |
679 | 679 | ||
680 | if (tusb_get_revision(musb) >= TUSB_REV_30) | 680 | if (musb->tusb_revision >= TUSB_REV_30) |
681 | tusb_dma->multichannel = 1; | 681 | tusb_dma->multichannel = 1; |
682 | 682 | ||
683 | for (i = 0; i < MAX_DMAREQ; i++) { | 683 | for (i = 0; i < MAX_DMAREQ; i++) { |
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index 33dd6a6c320a..adccdeb996d9 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig | |||
@@ -163,11 +163,12 @@ config USB_ISP1301 | |||
163 | module will be called phy-isp1301. | 163 | module will be called phy-isp1301. |
164 | 164 | ||
165 | config USB_MSM_OTG | 165 | config USB_MSM_OTG |
166 | tristate "OTG support for Qualcomm on-chip USB controller" | 166 | tristate "Qualcomm on-chip USB OTG controller support" |
167 | depends on (USB || USB_GADGET) && ARCH_MSM | 167 | depends on (USB || USB_GADGET) && (ARCH_MSM || ARCH_QCOM || COMPILE_TEST) |
168 | depends on RESET_CONTROLLER | ||
168 | select USB_PHY | 169 | select USB_PHY |
169 | help | 170 | help |
170 | Enable this to support the USB OTG transceiver on MSM chips. It | 171 | Enable this to support the USB OTG transceiver on Qualcomm chips. It |
171 | handles PHY initialization, clock management, and workarounds | 172 | handles PHY initialization, clock management, and workarounds |
172 | required after resetting the hardware and power management. | 173 | required after resetting the hardware and power management. |
173 | This driver is required even for peripheral only or host only | 174 | This driver is required even for peripheral only or host only |
diff --git a/drivers/usb/phy/phy-am335x.c b/drivers/usb/phy/phy-am335x.c index 12fc3468a01e..585e50cb1980 100644 --- a/drivers/usb/phy/phy-am335x.c +++ b/drivers/usb/phy/phy-am335x.c | |||
@@ -2,7 +2,7 @@ | |||
2 | #include <linux/platform_device.h> | 2 | #include <linux/platform_device.h> |
3 | #include <linux/dma-mapping.h> | 3 | #include <linux/dma-mapping.h> |
4 | #include <linux/usb/otg.h> | 4 | #include <linux/usb/otg.h> |
5 | #include <linux/usb/usb_phy_gen_xceiv.h> | 5 | #include <linux/usb/usb_phy_generic.h> |
6 | #include <linux/slab.h> | 6 | #include <linux/slab.h> |
7 | #include <linux/clk.h> | 7 | #include <linux/clk.h> |
8 | #include <linux/regulator/consumer.h> | 8 | #include <linux/regulator/consumer.h> |
@@ -13,7 +13,7 @@ | |||
13 | #include "phy-generic.h" | 13 | #include "phy-generic.h" |
14 | 14 | ||
15 | struct am335x_phy { | 15 | struct am335x_phy { |
16 | struct usb_phy_gen_xceiv usb_phy_gen; | 16 | struct usb_phy_generic usb_phy_gen; |
17 | struct phy_control *phy_ctrl; | 17 | struct phy_control *phy_ctrl; |
18 | int id; | 18 | int id; |
19 | }; | 19 | }; |
diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c index bb394980532b..7594e5069ae5 100644 --- a/drivers/usb/phy/phy-generic.c +++ b/drivers/usb/phy/phy-generic.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include <linux/platform_device.h> | 30 | #include <linux/platform_device.h> |
31 | #include <linux/dma-mapping.h> | 31 | #include <linux/dma-mapping.h> |
32 | #include <linux/usb/otg.h> | 32 | #include <linux/usb/otg.h> |
33 | #include <linux/usb/usb_phy_gen_xceiv.h> | 33 | #include <linux/usb/usb_phy_generic.h> |
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <linux/clk.h> | 35 | #include <linux/clk.h> |
36 | #include <linux/regulator/consumer.h> | 36 | #include <linux/regulator/consumer.h> |
@@ -41,34 +41,25 @@ | |||
41 | 41 | ||
42 | #include "phy-generic.h" | 42 | #include "phy-generic.h" |
43 | 43 | ||
44 | static struct platform_device *pd; | 44 | struct platform_device *usb_phy_generic_register(void) |
45 | |||
46 | void usb_nop_xceiv_register(void) | ||
47 | { | 45 | { |
48 | if (pd) | 46 | return platform_device_register_simple("usb_phy_generic", |
49 | return; | 47 | PLATFORM_DEVID_AUTO, NULL, 0); |
50 | pd = platform_device_register_simple("usb_phy_gen_xceiv", -1, NULL, 0); | ||
51 | if (IS_ERR(pd)) { | ||
52 | pr_err("Unable to register generic usb transceiver\n"); | ||
53 | pd = NULL; | ||
54 | return; | ||
55 | } | ||
56 | } | 48 | } |
57 | EXPORT_SYMBOL(usb_nop_xceiv_register); | 49 | EXPORT_SYMBOL_GPL(usb_phy_generic_register); |
58 | 50 | ||
59 | void usb_nop_xceiv_unregister(void) | 51 | void usb_phy_generic_unregister(struct platform_device *pdev) |
60 | { | 52 | { |
61 | platform_device_unregister(pd); | 53 | platform_device_unregister(pdev); |
62 | pd = NULL; | ||
63 | } | 54 | } |
64 | EXPORT_SYMBOL(usb_nop_xceiv_unregister); | 55 | EXPORT_SYMBOL_GPL(usb_phy_generic_unregister); |
65 | 56 | ||
66 | static int nop_set_suspend(struct usb_phy *x, int suspend) | 57 | static int nop_set_suspend(struct usb_phy *x, int suspend) |
67 | { | 58 | { |
68 | return 0; | 59 | return 0; |
69 | } | 60 | } |
70 | 61 | ||
71 | static void nop_reset_set(struct usb_phy_gen_xceiv *nop, int asserted) | 62 | static void nop_reset_set(struct usb_phy_generic *nop, int asserted) |
72 | { | 63 | { |
73 | int value; | 64 | int value; |
74 | 65 | ||
@@ -87,7 +78,7 @@ static void nop_reset_set(struct usb_phy_gen_xceiv *nop, int asserted) | |||
87 | 78 | ||
88 | int usb_gen_phy_init(struct usb_phy *phy) | 79 | int usb_gen_phy_init(struct usb_phy *phy) |
89 | { | 80 | { |
90 | struct usb_phy_gen_xceiv *nop = dev_get_drvdata(phy->dev); | 81 | struct usb_phy_generic *nop = dev_get_drvdata(phy->dev); |
91 | 82 | ||
92 | if (!IS_ERR(nop->vcc)) { | 83 | if (!IS_ERR(nop->vcc)) { |
93 | if (regulator_enable(nop->vcc)) | 84 | if (regulator_enable(nop->vcc)) |
@@ -106,7 +97,7 @@ EXPORT_SYMBOL_GPL(usb_gen_phy_init); | |||
106 | 97 | ||
107 | void usb_gen_phy_shutdown(struct usb_phy *phy) | 98 | void usb_gen_phy_shutdown(struct usb_phy *phy) |
108 | { | 99 | { |
109 | struct usb_phy_gen_xceiv *nop = dev_get_drvdata(phy->dev); | 100 | struct usb_phy_generic *nop = dev_get_drvdata(phy->dev); |
110 | 101 | ||
111 | /* Assert RESET */ | 102 | /* Assert RESET */ |
112 | nop_reset_set(nop, 1); | 103 | nop_reset_set(nop, 1); |
@@ -150,8 +141,8 @@ static int nop_set_host(struct usb_otg *otg, struct usb_bus *host) | |||
150 | return 0; | 141 | return 0; |
151 | } | 142 | } |
152 | 143 | ||
153 | int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_gen_xceiv *nop, | 144 | int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop, |
154 | struct usb_phy_gen_xceiv_platform_data *pdata) | 145 | struct usb_phy_generic_platform_data *pdata) |
155 | { | 146 | { |
156 | enum usb_phy_type type = USB_PHY_TYPE_USB2; | 147 | enum usb_phy_type type = USB_PHY_TYPE_USB2; |
157 | int err; | 148 | int err; |
@@ -245,10 +236,10 @@ int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_gen_xceiv *nop, | |||
245 | } | 236 | } |
246 | EXPORT_SYMBOL_GPL(usb_phy_gen_create_phy); | 237 | EXPORT_SYMBOL_GPL(usb_phy_gen_create_phy); |
247 | 238 | ||
248 | static int usb_phy_gen_xceiv_probe(struct platform_device *pdev) | 239 | static int usb_phy_generic_probe(struct platform_device *pdev) |
249 | { | 240 | { |
250 | struct device *dev = &pdev->dev; | 241 | struct device *dev = &pdev->dev; |
251 | struct usb_phy_gen_xceiv *nop; | 242 | struct usb_phy_generic *nop; |
252 | int err; | 243 | int err; |
253 | 244 | ||
254 | nop = devm_kzalloc(dev, sizeof(*nop), GFP_KERNEL); | 245 | nop = devm_kzalloc(dev, sizeof(*nop), GFP_KERNEL); |
@@ -274,9 +265,9 @@ static int usb_phy_gen_xceiv_probe(struct platform_device *pdev) | |||
274 | return 0; | 265 | return 0; |
275 | } | 266 | } |
276 | 267 | ||
277 | static int usb_phy_gen_xceiv_remove(struct platform_device *pdev) | 268 | static int usb_phy_generic_remove(struct platform_device *pdev) |
278 | { | 269 | { |
279 | struct usb_phy_gen_xceiv *nop = platform_get_drvdata(pdev); | 270 | struct usb_phy_generic *nop = platform_get_drvdata(pdev); |
280 | 271 | ||
281 | usb_remove_phy(&nop->phy); | 272 | usb_remove_phy(&nop->phy); |
282 | 273 | ||
@@ -290,29 +281,29 @@ static const struct of_device_id nop_xceiv_dt_ids[] = { | |||
290 | 281 | ||
291 | MODULE_DEVICE_TABLE(of, nop_xceiv_dt_ids); | 282 | MODULE_DEVICE_TABLE(of, nop_xceiv_dt_ids); |
292 | 283 | ||
293 | static struct platform_driver usb_phy_gen_xceiv_driver = { | 284 | static struct platform_driver usb_phy_generic_driver = { |
294 | .probe = usb_phy_gen_xceiv_probe, | 285 | .probe = usb_phy_generic_probe, |
295 | .remove = usb_phy_gen_xceiv_remove, | 286 | .remove = usb_phy_generic_remove, |
296 | .driver = { | 287 | .driver = { |
297 | .name = "usb_phy_gen_xceiv", | 288 | .name = "usb_phy_generic", |
298 | .owner = THIS_MODULE, | 289 | .owner = THIS_MODULE, |
299 | .of_match_table = nop_xceiv_dt_ids, | 290 | .of_match_table = nop_xceiv_dt_ids, |
300 | }, | 291 | }, |
301 | }; | 292 | }; |
302 | 293 | ||
303 | static int __init usb_phy_gen_xceiv_init(void) | 294 | static int __init usb_phy_generic_init(void) |
304 | { | 295 | { |
305 | return platform_driver_register(&usb_phy_gen_xceiv_driver); | 296 | return platform_driver_register(&usb_phy_generic_driver); |
306 | } | 297 | } |
307 | subsys_initcall(usb_phy_gen_xceiv_init); | 298 | subsys_initcall(usb_phy_generic_init); |
308 | 299 | ||
309 | static void __exit usb_phy_gen_xceiv_exit(void) | 300 | static void __exit usb_phy_generic_exit(void) |
310 | { | 301 | { |
311 | platform_driver_unregister(&usb_phy_gen_xceiv_driver); | 302 | platform_driver_unregister(&usb_phy_generic_driver); |
312 | } | 303 | } |
313 | module_exit(usb_phy_gen_xceiv_exit); | 304 | module_exit(usb_phy_generic_exit); |
314 | 305 | ||
315 | MODULE_ALIAS("platform:usb_phy_gen_xceiv"); | 306 | MODULE_ALIAS("platform:usb_phy_generic"); |
316 | MODULE_AUTHOR("Texas Instruments Inc"); | 307 | MODULE_AUTHOR("Texas Instruments Inc"); |
317 | MODULE_DESCRIPTION("NOP USB Transceiver driver"); | 308 | MODULE_DESCRIPTION("NOP USB Transceiver driver"); |
318 | MODULE_LICENSE("GPL"); | 309 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/usb/phy/phy-generic.h b/drivers/usb/phy/phy-generic.h index 38a81f307b82..d8feacc0b7fb 100644 --- a/drivers/usb/phy/phy-generic.h +++ b/drivers/usb/phy/phy-generic.h | |||
@@ -1,9 +1,9 @@ | |||
1 | #ifndef _PHY_GENERIC_H_ | 1 | #ifndef _PHY_GENERIC_H_ |
2 | #define _PHY_GENERIC_H_ | 2 | #define _PHY_GENERIC_H_ |
3 | 3 | ||
4 | #include <linux/usb/usb_phy_gen_xceiv.h> | 4 | #include <linux/usb/usb_phy_generic.h> |
5 | 5 | ||
6 | struct usb_phy_gen_xceiv { | 6 | struct usb_phy_generic { |
7 | struct usb_phy phy; | 7 | struct usb_phy phy; |
8 | struct device *dev; | 8 | struct device *dev; |
9 | struct clk *clk; | 9 | struct clk *clk; |
@@ -15,7 +15,7 @@ struct usb_phy_gen_xceiv { | |||
15 | int usb_gen_phy_init(struct usb_phy *phy); | 15 | int usb_gen_phy_init(struct usb_phy *phy); |
16 | void usb_gen_phy_shutdown(struct usb_phy *phy); | 16 | void usb_gen_phy_shutdown(struct usb_phy *phy); |
17 | 17 | ||
18 | int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_gen_xceiv *nop, | 18 | int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop, |
19 | struct usb_phy_gen_xceiv_platform_data *pdata); | 19 | struct usb_phy_generic_platform_data *pdata); |
20 | 20 | ||
21 | #endif | 21 | #endif |
diff --git a/drivers/usb/phy/phy-keystone.c b/drivers/usb/phy/phy-keystone.c index d762003896c0..f4d722de912b 100644 --- a/drivers/usb/phy/phy-keystone.c +++ b/drivers/usb/phy/phy-keystone.c | |||
@@ -18,7 +18,7 @@ | |||
18 | 18 | ||
19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
21 | #include <linux/usb/usb_phy_gen_xceiv.h> | 21 | #include <linux/usb/usb_phy_generic.h> |
22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
23 | #include <linux/of.h> | 23 | #include <linux/of.h> |
24 | 24 | ||
@@ -35,7 +35,7 @@ | |||
35 | #define PHY_REF_SSP_EN BIT(29) | 35 | #define PHY_REF_SSP_EN BIT(29) |
36 | 36 | ||
37 | struct keystone_usbphy { | 37 | struct keystone_usbphy { |
38 | struct usb_phy_gen_xceiv usb_phy_gen; | 38 | struct usb_phy_generic usb_phy_gen; |
39 | void __iomem *phy_ctrl; | 39 | void __iomem *phy_ctrl; |
40 | }; | 40 | }; |
41 | 41 | ||
diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index 5b37b81f2ef6..4f88174aede5 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c | |||
@@ -30,9 +30,13 @@ | |||
30 | #include <linux/debugfs.h> | 30 | #include <linux/debugfs.h> |
31 | #include <linux/seq_file.h> | 31 | #include <linux/seq_file.h> |
32 | #include <linux/pm_runtime.h> | 32 | #include <linux/pm_runtime.h> |
33 | #include <linux/of.h> | ||
34 | #include <linux/of_device.h> | ||
35 | #include <linux/reset.h> | ||
33 | 36 | ||
34 | #include <linux/usb.h> | 37 | #include <linux/usb.h> |
35 | #include <linux/usb/otg.h> | 38 | #include <linux/usb/otg.h> |
39 | #include <linux/usb/of.h> | ||
36 | #include <linux/usb/ulpi.h> | 40 | #include <linux/usb/ulpi.h> |
37 | #include <linux/usb/gadget.h> | 41 | #include <linux/usb/gadget.h> |
38 | #include <linux/usb/hcd.h> | 42 | #include <linux/usb/hcd.h> |
@@ -44,6 +48,7 @@ | |||
44 | #define DRIVER_NAME "msm_otg" | 48 | #define DRIVER_NAME "msm_otg" |
45 | 49 | ||
46 | #define ULPI_IO_TIMEOUT_USEC (10 * 1000) | 50 | #define ULPI_IO_TIMEOUT_USEC (10 * 1000) |
51 | #define LINK_RESET_TIMEOUT_USEC (250 * 1000) | ||
47 | 52 | ||
48 | #define USB_PHY_3P3_VOL_MIN 3050000 /* uV */ | 53 | #define USB_PHY_3P3_VOL_MIN 3050000 /* uV */ |
49 | #define USB_PHY_3P3_VOL_MAX 3300000 /* uV */ | 54 | #define USB_PHY_3P3_VOL_MAX 3300000 /* uV */ |
@@ -57,48 +62,38 @@ | |||
57 | 62 | ||
58 | #define USB_PHY_VDD_DIG_VOL_MIN 1000000 /* uV */ | 63 | #define USB_PHY_VDD_DIG_VOL_MIN 1000000 /* uV */ |
59 | #define USB_PHY_VDD_DIG_VOL_MAX 1320000 /* uV */ | 64 | #define USB_PHY_VDD_DIG_VOL_MAX 1320000 /* uV */ |
65 | #define USB_PHY_SUSP_DIG_VOL 500000 /* uV */ | ||
60 | 66 | ||
61 | static struct regulator *hsusb_3p3; | 67 | enum vdd_levels { |
62 | static struct regulator *hsusb_1p8; | 68 | VDD_LEVEL_NONE = 0, |
63 | static struct regulator *hsusb_vddcx; | 69 | VDD_LEVEL_MIN, |
70 | VDD_LEVEL_MAX, | ||
71 | }; | ||
64 | 72 | ||
65 | static int msm_hsusb_init_vddcx(struct msm_otg *motg, int init) | 73 | static int msm_hsusb_init_vddcx(struct msm_otg *motg, int init) |
66 | { | 74 | { |
67 | int ret = 0; | 75 | int ret = 0; |
68 | 76 | ||
69 | if (init) { | 77 | if (init) { |
70 | hsusb_vddcx = regulator_get(motg->phy.dev, "HSUSB_VDDCX"); | 78 | ret = regulator_set_voltage(motg->vddcx, |
71 | if (IS_ERR(hsusb_vddcx)) { | 79 | motg->vdd_levels[VDD_LEVEL_MIN], |
72 | dev_err(motg->phy.dev, "unable to get hsusb vddcx\n"); | 80 | motg->vdd_levels[VDD_LEVEL_MAX]); |
73 | return PTR_ERR(hsusb_vddcx); | ||
74 | } | ||
75 | |||
76 | ret = regulator_set_voltage(hsusb_vddcx, | ||
77 | USB_PHY_VDD_DIG_VOL_MIN, | ||
78 | USB_PHY_VDD_DIG_VOL_MAX); | ||
79 | if (ret) { | 81 | if (ret) { |
80 | dev_err(motg->phy.dev, "unable to set the voltage " | 82 | dev_err(motg->phy.dev, "Cannot set vddcx voltage\n"); |
81 | "for hsusb vddcx\n"); | ||
82 | regulator_put(hsusb_vddcx); | ||
83 | return ret; | 83 | return ret; |
84 | } | 84 | } |
85 | 85 | ||
86 | ret = regulator_enable(hsusb_vddcx); | 86 | ret = regulator_enable(motg->vddcx); |
87 | if (ret) { | 87 | if (ret) |
88 | dev_err(motg->phy.dev, "unable to enable hsusb vddcx\n"); | 88 | dev_err(motg->phy.dev, "unable to enable hsusb vddcx\n"); |
89 | regulator_put(hsusb_vddcx); | ||
90 | } | ||
91 | } else { | 89 | } else { |
92 | ret = regulator_set_voltage(hsusb_vddcx, 0, | 90 | ret = regulator_set_voltage(motg->vddcx, 0, |
93 | USB_PHY_VDD_DIG_VOL_MAX); | 91 | motg->vdd_levels[VDD_LEVEL_MAX]); |
94 | if (ret) | 92 | if (ret) |
95 | dev_err(motg->phy.dev, "unable to set the voltage " | 93 | dev_err(motg->phy.dev, "Cannot set vddcx voltage\n"); |
96 | "for hsusb vddcx\n"); | 94 | ret = regulator_disable(motg->vddcx); |
97 | ret = regulator_disable(hsusb_vddcx); | ||
98 | if (ret) | 95 | if (ret) |
99 | dev_err(motg->phy.dev, "unable to disable hsusb vddcx\n"); | 96 | dev_err(motg->phy.dev, "unable to disable hsusb vddcx\n"); |
100 | |||
101 | regulator_put(hsusb_vddcx); | ||
102 | } | 97 | } |
103 | 98 | ||
104 | return ret; | 99 | return ret; |
@@ -109,98 +104,67 @@ static int msm_hsusb_ldo_init(struct msm_otg *motg, int init) | |||
109 | int rc = 0; | 104 | int rc = 0; |
110 | 105 | ||
111 | if (init) { | 106 | if (init) { |
112 | hsusb_3p3 = regulator_get(motg->phy.dev, "HSUSB_3p3"); | 107 | rc = regulator_set_voltage(motg->v3p3, USB_PHY_3P3_VOL_MIN, |
113 | if (IS_ERR(hsusb_3p3)) { | ||
114 | dev_err(motg->phy.dev, "unable to get hsusb 3p3\n"); | ||
115 | return PTR_ERR(hsusb_3p3); | ||
116 | } | ||
117 | |||
118 | rc = regulator_set_voltage(hsusb_3p3, USB_PHY_3P3_VOL_MIN, | ||
119 | USB_PHY_3P3_VOL_MAX); | 108 | USB_PHY_3P3_VOL_MAX); |
120 | if (rc) { | 109 | if (rc) { |
121 | dev_err(motg->phy.dev, "unable to set voltage level " | 110 | dev_err(motg->phy.dev, "Cannot set v3p3 voltage\n"); |
122 | "for hsusb 3p3\n"); | 111 | goto exit; |
123 | goto put_3p3; | ||
124 | } | 112 | } |
125 | rc = regulator_enable(hsusb_3p3); | 113 | rc = regulator_enable(motg->v3p3); |
126 | if (rc) { | 114 | if (rc) { |
127 | dev_err(motg->phy.dev, "unable to enable the hsusb 3p3\n"); | 115 | dev_err(motg->phy.dev, "unable to enable the hsusb 3p3\n"); |
128 | goto put_3p3; | 116 | goto exit; |
129 | } | 117 | } |
130 | hsusb_1p8 = regulator_get(motg->phy.dev, "HSUSB_1p8"); | 118 | rc = regulator_set_voltage(motg->v1p8, USB_PHY_1P8_VOL_MIN, |
131 | if (IS_ERR(hsusb_1p8)) { | ||
132 | dev_err(motg->phy.dev, "unable to get hsusb 1p8\n"); | ||
133 | rc = PTR_ERR(hsusb_1p8); | ||
134 | goto disable_3p3; | ||
135 | } | ||
136 | rc = regulator_set_voltage(hsusb_1p8, USB_PHY_1P8_VOL_MIN, | ||
137 | USB_PHY_1P8_VOL_MAX); | 119 | USB_PHY_1P8_VOL_MAX); |
138 | if (rc) { | 120 | if (rc) { |
139 | dev_err(motg->phy.dev, "unable to set voltage level " | 121 | dev_err(motg->phy.dev, "Cannot set v1p8 voltage\n"); |
140 | "for hsusb 1p8\n"); | 122 | goto disable_3p3; |
141 | goto put_1p8; | ||
142 | } | 123 | } |
143 | rc = regulator_enable(hsusb_1p8); | 124 | rc = regulator_enable(motg->v1p8); |
144 | if (rc) { | 125 | if (rc) { |
145 | dev_err(motg->phy.dev, "unable to enable the hsusb 1p8\n"); | 126 | dev_err(motg->phy.dev, "unable to enable the hsusb 1p8\n"); |
146 | goto put_1p8; | 127 | goto disable_3p3; |
147 | } | 128 | } |
148 | 129 | ||
149 | return 0; | 130 | return 0; |
150 | } | 131 | } |
151 | 132 | ||
152 | regulator_disable(hsusb_1p8); | 133 | regulator_disable(motg->v1p8); |
153 | put_1p8: | ||
154 | regulator_put(hsusb_1p8); | ||
155 | disable_3p3: | 134 | disable_3p3: |
156 | regulator_disable(hsusb_3p3); | 135 | regulator_disable(motg->v3p3); |
157 | put_3p3: | 136 | exit: |
158 | regulator_put(hsusb_3p3); | ||
159 | return rc; | 137 | return rc; |
160 | } | 138 | } |
161 | 139 | ||
162 | static int msm_hsusb_ldo_set_mode(int on) | 140 | static int msm_hsusb_ldo_set_mode(struct msm_otg *motg, int on) |
163 | { | 141 | { |
164 | int ret = 0; | 142 | int ret = 0; |
165 | 143 | ||
166 | if (!hsusb_1p8 || IS_ERR(hsusb_1p8)) { | ||
167 | pr_err("%s: HSUSB_1p8 is not initialized\n", __func__); | ||
168 | return -ENODEV; | ||
169 | } | ||
170 | |||
171 | if (!hsusb_3p3 || IS_ERR(hsusb_3p3)) { | ||
172 | pr_err("%s: HSUSB_3p3 is not initialized\n", __func__); | ||
173 | return -ENODEV; | ||
174 | } | ||
175 | |||
176 | if (on) { | 144 | if (on) { |
177 | ret = regulator_set_optimum_mode(hsusb_1p8, | 145 | ret = regulator_set_optimum_mode(motg->v1p8, |
178 | USB_PHY_1P8_HPM_LOAD); | 146 | USB_PHY_1P8_HPM_LOAD); |
179 | if (ret < 0) { | 147 | if (ret < 0) { |
180 | pr_err("%s: Unable to set HPM of the regulator " | 148 | pr_err("Could not set HPM for v1p8\n"); |
181 | "HSUSB_1p8\n", __func__); | ||
182 | return ret; | 149 | return ret; |
183 | } | 150 | } |
184 | ret = regulator_set_optimum_mode(hsusb_3p3, | 151 | ret = regulator_set_optimum_mode(motg->v3p3, |
185 | USB_PHY_3P3_HPM_LOAD); | 152 | USB_PHY_3P3_HPM_LOAD); |
186 | if (ret < 0) { | 153 | if (ret < 0) { |
187 | pr_err("%s: Unable to set HPM of the regulator " | 154 | pr_err("Could not set HPM for v3p3\n"); |
188 | "HSUSB_3p3\n", __func__); | 155 | regulator_set_optimum_mode(motg->v1p8, |
189 | regulator_set_optimum_mode(hsusb_1p8, | ||
190 | USB_PHY_1P8_LPM_LOAD); | 156 | USB_PHY_1P8_LPM_LOAD); |
191 | return ret; | 157 | return ret; |
192 | } | 158 | } |
193 | } else { | 159 | } else { |
194 | ret = regulator_set_optimum_mode(hsusb_1p8, | 160 | ret = regulator_set_optimum_mode(motg->v1p8, |
195 | USB_PHY_1P8_LPM_LOAD); | 161 | USB_PHY_1P8_LPM_LOAD); |
196 | if (ret < 0) | 162 | if (ret < 0) |
197 | pr_err("%s: Unable to set LPM of the regulator " | 163 | pr_err("Could not set LPM for v1p8\n"); |
198 | "HSUSB_1p8\n", __func__); | 164 | ret = regulator_set_optimum_mode(motg->v3p3, |
199 | ret = regulator_set_optimum_mode(hsusb_3p3, | ||
200 | USB_PHY_3P3_LPM_LOAD); | 165 | USB_PHY_3P3_LPM_LOAD); |
201 | if (ret < 0) | 166 | if (ret < 0) |
202 | pr_err("%s: Unable to set LPM of the regulator " | 167 | pr_err("Could not set LPM for v3p3\n"); |
203 | "HSUSB_3p3\n", __func__); | ||
204 | } | 168 | } |
205 | 169 | ||
206 | pr_debug("reg (%s)\n", on ? "HPM" : "LPM"); | 170 | pr_debug("reg (%s)\n", on ? "HPM" : "LPM"); |
@@ -265,27 +229,47 @@ static struct usb_phy_io_ops msm_otg_io_ops = { | |||
265 | static void ulpi_init(struct msm_otg *motg) | 229 | static void ulpi_init(struct msm_otg *motg) |
266 | { | 230 | { |
267 | struct msm_otg_platform_data *pdata = motg->pdata; | 231 | struct msm_otg_platform_data *pdata = motg->pdata; |
268 | int *seq = pdata->phy_init_seq; | 232 | int *seq = pdata->phy_init_seq, idx; |
233 | u32 addr = ULPI_EXT_VENDOR_SPECIFIC; | ||
269 | 234 | ||
270 | if (!seq) | 235 | for (idx = 0; idx < pdata->phy_init_sz; idx++) { |
271 | return; | 236 | if (seq[idx] == -1) |
237 | continue; | ||
272 | 238 | ||
273 | while (seq[0] >= 0) { | ||
274 | dev_vdbg(motg->phy.dev, "ulpi: write 0x%02x to 0x%02x\n", | 239 | dev_vdbg(motg->phy.dev, "ulpi: write 0x%02x to 0x%02x\n", |
275 | seq[0], seq[1]); | 240 | seq[idx], addr + idx); |
276 | ulpi_write(&motg->phy, seq[0], seq[1]); | 241 | ulpi_write(&motg->phy, seq[idx], addr + idx); |
277 | seq += 2; | ||
278 | } | 242 | } |
279 | } | 243 | } |
280 | 244 | ||
245 | static int msm_phy_notify_disconnect(struct usb_phy *phy, | ||
246 | enum usb_device_speed speed) | ||
247 | { | ||
248 | int val; | ||
249 | |||
250 | /* | ||
251 | * Put the transceiver in non-driving mode. Otherwise host | ||
252 | * may not detect soft-disconnection. | ||
253 | */ | ||
254 | val = ulpi_read(phy, ULPI_FUNC_CTRL); | ||
255 | val &= ~ULPI_FUNC_CTRL_OPMODE_MASK; | ||
256 | val |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING; | ||
257 | ulpi_write(phy, val, ULPI_FUNC_CTRL); | ||
258 | |||
259 | return 0; | ||
260 | } | ||
261 | |||
281 | static int msm_otg_link_clk_reset(struct msm_otg *motg, bool assert) | 262 | static int msm_otg_link_clk_reset(struct msm_otg *motg, bool assert) |
282 | { | 263 | { |
283 | int ret = 0; | 264 | int ret; |
284 | 265 | ||
285 | if (!motg->pdata->link_clk_reset) | 266 | if (motg->pdata->link_clk_reset) |
286 | return ret; | 267 | ret = motg->pdata->link_clk_reset(motg->clk, assert); |
268 | else if (assert) | ||
269 | ret = reset_control_assert(motg->link_rst); | ||
270 | else | ||
271 | ret = reset_control_deassert(motg->link_rst); | ||
287 | 272 | ||
288 | ret = motg->pdata->link_clk_reset(motg->clk, assert); | ||
289 | if (ret) | 273 | if (ret) |
290 | dev_err(motg->phy.dev, "usb link clk reset %s failed\n", | 274 | dev_err(motg->phy.dev, "usb link clk reset %s failed\n", |
291 | assert ? "assert" : "deassert"); | 275 | assert ? "assert" : "deassert"); |
@@ -295,111 +279,150 @@ static int msm_otg_link_clk_reset(struct msm_otg *motg, bool assert) | |||
295 | 279 | ||
296 | static int msm_otg_phy_clk_reset(struct msm_otg *motg) | 280 | static int msm_otg_phy_clk_reset(struct msm_otg *motg) |
297 | { | 281 | { |
298 | int ret = 0; | 282 | int ret; |
299 | 283 | ||
300 | if (!motg->pdata->phy_clk_reset) | 284 | if (motg->pdata->phy_clk_reset) |
301 | return ret; | 285 | ret = motg->pdata->phy_clk_reset(motg->phy_reset_clk); |
286 | else | ||
287 | ret = reset_control_reset(motg->phy_rst); | ||
302 | 288 | ||
303 | ret = motg->pdata->phy_clk_reset(motg->phy_reset_clk); | ||
304 | if (ret) | 289 | if (ret) |
305 | dev_err(motg->phy.dev, "usb phy clk reset failed\n"); | 290 | dev_err(motg->phy.dev, "usb phy clk reset failed\n"); |
306 | 291 | ||
307 | return ret; | 292 | return ret; |
308 | } | 293 | } |
309 | 294 | ||
310 | static int msm_otg_phy_reset(struct msm_otg *motg) | 295 | static int msm_link_reset(struct msm_otg *motg) |
311 | { | 296 | { |
312 | u32 val; | 297 | u32 val; |
313 | int ret; | 298 | int ret; |
314 | int retries; | ||
315 | 299 | ||
316 | ret = msm_otg_link_clk_reset(motg, 1); | 300 | ret = msm_otg_link_clk_reset(motg, 1); |
317 | if (ret) | 301 | if (ret) |
318 | return ret; | 302 | return ret; |
319 | ret = msm_otg_phy_clk_reset(motg); | 303 | |
320 | if (ret) | 304 | /* wait for 1ms delay as suggested in HPG. */ |
321 | return ret; | 305 | usleep_range(1000, 1200); |
306 | |||
322 | ret = msm_otg_link_clk_reset(motg, 0); | 307 | ret = msm_otg_link_clk_reset(motg, 0); |
323 | if (ret) | 308 | if (ret) |
324 | return ret; | 309 | return ret; |
325 | 310 | ||
311 | if (motg->phy_number) | ||
312 | writel(readl(USB_PHY_CTRL2) | BIT(16), USB_PHY_CTRL2); | ||
313 | |||
314 | /* put transceiver in serial mode as part of reset */ | ||
326 | val = readl(USB_PORTSC) & ~PORTSC_PTS_MASK; | 315 | val = readl(USB_PORTSC) & ~PORTSC_PTS_MASK; |
327 | writel(val | PORTSC_PTS_ULPI, USB_PORTSC); | 316 | writel(val | PORTSC_PTS_SERIAL, USB_PORTSC); |
328 | 317 | ||
329 | for (retries = 3; retries > 0; retries--) { | 318 | return 0; |
330 | ret = ulpi_write(&motg->phy, ULPI_FUNC_CTRL_SUSPENDM, | 319 | } |
331 | ULPI_CLR(ULPI_FUNC_CTRL)); | ||
332 | if (!ret) | ||
333 | break; | ||
334 | ret = msm_otg_phy_clk_reset(motg); | ||
335 | if (ret) | ||
336 | return ret; | ||
337 | } | ||
338 | if (!retries) | ||
339 | return -ETIMEDOUT; | ||
340 | 320 | ||
341 | /* This reset calibrates the phy, if the above write succeeded */ | 321 | static int msm_otg_reset(struct usb_phy *phy) |
342 | ret = msm_otg_phy_clk_reset(motg); | 322 | { |
343 | if (ret) | 323 | struct msm_otg *motg = container_of(phy, struct msm_otg, phy); |
344 | return ret; | 324 | int cnt = 0; |
345 | 325 | ||
346 | for (retries = 3; retries > 0; retries--) { | 326 | writel(USBCMD_RESET, USB_USBCMD); |
347 | ret = ulpi_read(&motg->phy, ULPI_DEBUG); | 327 | while (cnt < LINK_RESET_TIMEOUT_USEC) { |
348 | if (ret != -ETIMEDOUT) | 328 | if (!(readl(USB_USBCMD) & USBCMD_RESET)) |
349 | break; | 329 | break; |
350 | ret = msm_otg_phy_clk_reset(motg); | 330 | udelay(1); |
351 | if (ret) | 331 | cnt++; |
352 | return ret; | ||
353 | } | 332 | } |
354 | if (!retries) | 333 | if (cnt >= LINK_RESET_TIMEOUT_USEC) |
355 | return -ETIMEDOUT; | 334 | return -ETIMEDOUT; |
356 | 335 | ||
357 | dev_info(motg->phy.dev, "phy_reset: success\n"); | 336 | /* select ULPI phy and clear other status/control bits in PORTSC */ |
337 | writel(PORTSC_PTS_ULPI, USB_PORTSC); | ||
338 | |||
339 | writel(0x0, USB_AHBBURST); | ||
340 | writel(0x08, USB_AHBMODE); | ||
341 | |||
342 | if (motg->phy_number) | ||
343 | writel(readl(USB_PHY_CTRL2) | BIT(16), USB_PHY_CTRL2); | ||
358 | return 0; | 344 | return 0; |
359 | } | 345 | } |
360 | 346 | ||
361 | #define LINK_RESET_TIMEOUT_USEC (250 * 1000) | 347 | static void msm_phy_reset(struct msm_otg *motg) |
362 | static int msm_otg_reset(struct usb_phy *phy) | 348 | { |
349 | void __iomem *addr; | ||
350 | |||
351 | if (motg->pdata->phy_type != SNPS_28NM_INTEGRATED_PHY) { | ||
352 | msm_otg_phy_clk_reset(motg); | ||
353 | return; | ||
354 | } | ||
355 | |||
356 | addr = USB_PHY_CTRL; | ||
357 | if (motg->phy_number) | ||
358 | addr = USB_PHY_CTRL2; | ||
359 | |||
360 | /* Assert USB PHY_POR */ | ||
361 | writel(readl(addr) | PHY_POR_ASSERT, addr); | ||
362 | |||
363 | /* | ||
364 | * wait for minimum 10 microseconds as suggested in HPG. | ||
365 | * Use a slightly larger value since the exact value didn't | ||
366 | * work 100% of the time. | ||
367 | */ | ||
368 | udelay(12); | ||
369 | |||
370 | /* Deassert USB PHY_POR */ | ||
371 | writel(readl(addr) & ~PHY_POR_ASSERT, addr); | ||
372 | } | ||
373 | |||
374 | static int msm_usb_reset(struct usb_phy *phy) | ||
363 | { | 375 | { |
364 | struct msm_otg *motg = container_of(phy, struct msm_otg, phy); | 376 | struct msm_otg *motg = container_of(phy, struct msm_otg, phy); |
365 | struct msm_otg_platform_data *pdata = motg->pdata; | ||
366 | int cnt = 0; | ||
367 | int ret; | 377 | int ret; |
368 | u32 val = 0; | ||
369 | u32 ulpi_val = 0; | ||
370 | 378 | ||
371 | ret = msm_otg_phy_reset(motg); | 379 | if (!IS_ERR(motg->core_clk)) |
380 | clk_prepare_enable(motg->core_clk); | ||
381 | |||
382 | ret = msm_link_reset(motg); | ||
372 | if (ret) { | 383 | if (ret) { |
373 | dev_err(phy->dev, "phy_reset failed\n"); | 384 | dev_err(phy->dev, "phy_reset failed\n"); |
374 | return ret; | 385 | return ret; |
375 | } | 386 | } |
376 | 387 | ||
377 | ulpi_init(motg); | 388 | ret = msm_otg_reset(&motg->phy); |
378 | 389 | if (ret) { | |
379 | writel(USBCMD_RESET, USB_USBCMD); | 390 | dev_err(phy->dev, "link reset failed\n"); |
380 | while (cnt < LINK_RESET_TIMEOUT_USEC) { | 391 | return ret; |
381 | if (!(readl(USB_USBCMD) & USBCMD_RESET)) | ||
382 | break; | ||
383 | udelay(1); | ||
384 | cnt++; | ||
385 | } | 392 | } |
386 | if (cnt >= LINK_RESET_TIMEOUT_USEC) | ||
387 | return -ETIMEDOUT; | ||
388 | |||
389 | /* select ULPI phy */ | ||
390 | writel(0x80000000, USB_PORTSC); | ||
391 | 393 | ||
392 | msleep(100); | 394 | msleep(100); |
393 | 395 | ||
394 | writel(0x0, USB_AHBBURST); | 396 | /* Reset USB PHY after performing USB Link RESET */ |
395 | writel(0x00, USB_AHBMODE); | 397 | msm_phy_reset(motg); |
398 | |||
399 | if (!IS_ERR(motg->core_clk)) | ||
400 | clk_disable_unprepare(motg->core_clk); | ||
401 | |||
402 | return 0; | ||
403 | } | ||
404 | |||
405 | static int msm_phy_init(struct usb_phy *phy) | ||
406 | { | ||
407 | struct msm_otg *motg = container_of(phy, struct msm_otg, phy); | ||
408 | struct msm_otg_platform_data *pdata = motg->pdata; | ||
409 | u32 val, ulpi_val = 0; | ||
410 | |||
411 | /* Program USB PHY Override registers. */ | ||
412 | ulpi_init(motg); | ||
413 | |||
414 | /* | ||
415 | * It is recommended in HPG to reset USB PHY after programming | ||
416 | * USB PHY Override registers. | ||
417 | */ | ||
418 | msm_phy_reset(motg); | ||
396 | 419 | ||
397 | if (pdata->otg_control == OTG_PHY_CONTROL) { | 420 | if (pdata->otg_control == OTG_PHY_CONTROL) { |
398 | val = readl(USB_OTGSC); | 421 | val = readl(USB_OTGSC); |
399 | if (pdata->mode == USB_OTG) { | 422 | if (pdata->mode == USB_DR_MODE_OTG) { |
400 | ulpi_val = ULPI_INT_IDGRD | ULPI_INT_SESS_VALID; | 423 | ulpi_val = ULPI_INT_IDGRD | ULPI_INT_SESS_VALID; |
401 | val |= OTGSC_IDIE | OTGSC_BSVIE; | 424 | val |= OTGSC_IDIE | OTGSC_BSVIE; |
402 | } else if (pdata->mode == USB_PERIPHERAL) { | 425 | } else if (pdata->mode == USB_DR_MODE_PERIPHERAL) { |
403 | ulpi_val = ULPI_INT_SESS_VALID; | 426 | ulpi_val = ULPI_INT_SESS_VALID; |
404 | val |= OTGSC_BSVIE; | 427 | val |= OTGSC_BSVIE; |
405 | } | 428 | } |
@@ -408,6 +431,9 @@ static int msm_otg_reset(struct usb_phy *phy) | |||
408 | ulpi_write(phy, ulpi_val, ULPI_USB_INT_EN_FALL); | 431 | ulpi_write(phy, ulpi_val, ULPI_USB_INT_EN_FALL); |
409 | } | 432 | } |
410 | 433 | ||
434 | if (motg->phy_number) | ||
435 | writel(readl(USB_PHY_CTRL2) | BIT(16), USB_PHY_CTRL2); | ||
436 | |||
411 | return 0; | 437 | return 0; |
412 | } | 438 | } |
413 | 439 | ||
@@ -416,22 +442,20 @@ static int msm_otg_reset(struct usb_phy *phy) | |||
416 | 442 | ||
417 | #ifdef CONFIG_PM | 443 | #ifdef CONFIG_PM |
418 | 444 | ||
419 | #define USB_PHY_SUSP_DIG_VOL 500000 | 445 | static int msm_hsusb_config_vddcx(struct msm_otg *motg, int high) |
420 | static int msm_hsusb_config_vddcx(int high) | ||
421 | { | 446 | { |
422 | int max_vol = USB_PHY_VDD_DIG_VOL_MAX; | 447 | int max_vol = motg->vdd_levels[VDD_LEVEL_MAX]; |
423 | int min_vol; | 448 | int min_vol; |
424 | int ret; | 449 | int ret; |
425 | 450 | ||
426 | if (high) | 451 | if (high) |
427 | min_vol = USB_PHY_VDD_DIG_VOL_MIN; | 452 | min_vol = motg->vdd_levels[VDD_LEVEL_MIN]; |
428 | else | 453 | else |
429 | min_vol = USB_PHY_SUSP_DIG_VOL; | 454 | min_vol = motg->vdd_levels[VDD_LEVEL_NONE]; |
430 | 455 | ||
431 | ret = regulator_set_voltage(hsusb_vddcx, min_vol, max_vol); | 456 | ret = regulator_set_voltage(motg->vddcx, min_vol, max_vol); |
432 | if (ret) { | 457 | if (ret) { |
433 | pr_err("%s: unable to set the voltage for regulator " | 458 | pr_err("Cannot set vddcx voltage\n"); |
434 | "HSUSB_VDDCX\n", __func__); | ||
435 | return ret; | 459 | return ret; |
436 | } | 460 | } |
437 | 461 | ||
@@ -445,6 +469,7 @@ static int msm_otg_suspend(struct msm_otg *motg) | |||
445 | struct usb_phy *phy = &motg->phy; | 469 | struct usb_phy *phy = &motg->phy; |
446 | struct usb_bus *bus = phy->otg->host; | 470 | struct usb_bus *bus = phy->otg->host; |
447 | struct msm_otg_platform_data *pdata = motg->pdata; | 471 | struct msm_otg_platform_data *pdata = motg->pdata; |
472 | void __iomem *addr; | ||
448 | int cnt = 0; | 473 | int cnt = 0; |
449 | 474 | ||
450 | if (atomic_read(&motg->in_lpm)) | 475 | if (atomic_read(&motg->in_lpm)) |
@@ -504,22 +529,23 @@ static int msm_otg_suspend(struct msm_otg *motg) | |||
504 | */ | 529 | */ |
505 | writel(readl(USB_USBCMD) | ASYNC_INTR_CTRL | ULPI_STP_CTRL, USB_USBCMD); | 530 | writel(readl(USB_USBCMD) | ASYNC_INTR_CTRL | ULPI_STP_CTRL, USB_USBCMD); |
506 | 531 | ||
532 | addr = USB_PHY_CTRL; | ||
533 | if (motg->phy_number) | ||
534 | addr = USB_PHY_CTRL2; | ||
535 | |||
507 | if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && | 536 | if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && |
508 | motg->pdata->otg_control == OTG_PMIC_CONTROL) | 537 | motg->pdata->otg_control == OTG_PMIC_CONTROL) |
509 | writel(readl(USB_PHY_CTRL) | PHY_RETEN, USB_PHY_CTRL); | 538 | writel(readl(addr) | PHY_RETEN, addr); |
510 | 539 | ||
511 | clk_disable_unprepare(motg->pclk); | 540 | clk_disable_unprepare(motg->pclk); |
512 | clk_disable_unprepare(motg->clk); | 541 | clk_disable_unprepare(motg->clk); |
513 | if (motg->core_clk) | 542 | if (!IS_ERR(motg->core_clk)) |
514 | clk_disable_unprepare(motg->core_clk); | 543 | clk_disable_unprepare(motg->core_clk); |
515 | 544 | ||
516 | if (!IS_ERR(motg->pclk_src)) | ||
517 | clk_disable_unprepare(motg->pclk_src); | ||
518 | |||
519 | if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && | 545 | if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && |
520 | motg->pdata->otg_control == OTG_PMIC_CONTROL) { | 546 | motg->pdata->otg_control == OTG_PMIC_CONTROL) { |
521 | msm_hsusb_ldo_set_mode(0); | 547 | msm_hsusb_ldo_set_mode(motg, 0); |
522 | msm_hsusb_config_vddcx(0); | 548 | msm_hsusb_config_vddcx(motg, 0); |
523 | } | 549 | } |
524 | 550 | ||
525 | if (device_may_wakeup(phy->dev)) | 551 | if (device_may_wakeup(phy->dev)) |
@@ -539,25 +565,28 @@ static int msm_otg_resume(struct msm_otg *motg) | |||
539 | { | 565 | { |
540 | struct usb_phy *phy = &motg->phy; | 566 | struct usb_phy *phy = &motg->phy; |
541 | struct usb_bus *bus = phy->otg->host; | 567 | struct usb_bus *bus = phy->otg->host; |
568 | void __iomem *addr; | ||
542 | int cnt = 0; | 569 | int cnt = 0; |
543 | unsigned temp; | 570 | unsigned temp; |
544 | 571 | ||
545 | if (!atomic_read(&motg->in_lpm)) | 572 | if (!atomic_read(&motg->in_lpm)) |
546 | return 0; | 573 | return 0; |
547 | 574 | ||
548 | if (!IS_ERR(motg->pclk_src)) | ||
549 | clk_prepare_enable(motg->pclk_src); | ||
550 | |||
551 | clk_prepare_enable(motg->pclk); | 575 | clk_prepare_enable(motg->pclk); |
552 | clk_prepare_enable(motg->clk); | 576 | clk_prepare_enable(motg->clk); |
553 | if (motg->core_clk) | 577 | if (!IS_ERR(motg->core_clk)) |
554 | clk_prepare_enable(motg->core_clk); | 578 | clk_prepare_enable(motg->core_clk); |
555 | 579 | ||
556 | if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && | 580 | if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && |
557 | motg->pdata->otg_control == OTG_PMIC_CONTROL) { | 581 | motg->pdata->otg_control == OTG_PMIC_CONTROL) { |
558 | msm_hsusb_ldo_set_mode(1); | 582 | |
559 | msm_hsusb_config_vddcx(1); | 583 | addr = USB_PHY_CTRL; |
560 | writel(readl(USB_PHY_CTRL) & ~PHY_RETEN, USB_PHY_CTRL); | 584 | if (motg->phy_number) |
585 | addr = USB_PHY_CTRL2; | ||
586 | |||
587 | msm_hsusb_ldo_set_mode(motg, 1); | ||
588 | msm_hsusb_config_vddcx(motg, 1); | ||
589 | writel(readl(addr) & ~PHY_RETEN, addr); | ||
561 | } | 590 | } |
562 | 591 | ||
563 | temp = readl(USB_USBCMD); | 592 | temp = readl(USB_USBCMD); |
@@ -586,8 +615,7 @@ static int msm_otg_resume(struct msm_otg *motg) | |||
586 | * PHY. USB state can not be restored. Re-insertion | 615 | * PHY. USB state can not be restored. Re-insertion |
587 | * of USB cable is the only way to get USB working. | 616 | * of USB cable is the only way to get USB working. |
588 | */ | 617 | */ |
589 | dev_err(phy->dev, "Unable to resume USB." | 618 | dev_err(phy->dev, "Unable to resume USB. Re-plugin the cable\n"); |
590 | "Re-plugin the cable\n"); | ||
591 | msm_otg_reset(phy); | 619 | msm_otg_reset(phy); |
592 | } | 620 | } |
593 | 621 | ||
@@ -687,7 +715,7 @@ static int msm_otg_set_host(struct usb_otg *otg, struct usb_bus *host) | |||
687 | * Fail host registration if this board can support | 715 | * Fail host registration if this board can support |
688 | * only peripheral configuration. | 716 | * only peripheral configuration. |
689 | */ | 717 | */ |
690 | if (motg->pdata->mode == USB_PERIPHERAL) { | 718 | if (motg->pdata->mode == USB_DR_MODE_PERIPHERAL) { |
691 | dev_info(otg->phy->dev, "Host mode is not supported\n"); | 719 | dev_info(otg->phy->dev, "Host mode is not supported\n"); |
692 | return -ENODEV; | 720 | return -ENODEV; |
693 | } | 721 | } |
@@ -716,7 +744,7 @@ static int msm_otg_set_host(struct usb_otg *otg, struct usb_bus *host) | |||
716 | * Kick the state machine work, if peripheral is not supported | 744 | * Kick the state machine work, if peripheral is not supported |
717 | * or peripheral is already registered with us. | 745 | * or peripheral is already registered with us. |
718 | */ | 746 | */ |
719 | if (motg->pdata->mode == USB_HOST || otg->gadget) { | 747 | if (motg->pdata->mode == USB_DR_MODE_HOST || otg->gadget) { |
720 | pm_runtime_get_sync(otg->phy->dev); | 748 | pm_runtime_get_sync(otg->phy->dev); |
721 | schedule_work(&motg->sm_work); | 749 | schedule_work(&motg->sm_work); |
722 | } | 750 | } |
@@ -760,7 +788,7 @@ static int msm_otg_set_peripheral(struct usb_otg *otg, | |||
760 | * Fail peripheral registration if this board can support | 788 | * Fail peripheral registration if this board can support |
761 | * only host configuration. | 789 | * only host configuration. |
762 | */ | 790 | */ |
763 | if (motg->pdata->mode == USB_HOST) { | 791 | if (motg->pdata->mode == USB_DR_MODE_HOST) { |
764 | dev_info(otg->phy->dev, "Peripheral mode is not supported\n"); | 792 | dev_info(otg->phy->dev, "Peripheral mode is not supported\n"); |
765 | return -ENODEV; | 793 | return -ENODEV; |
766 | } | 794 | } |
@@ -785,7 +813,7 @@ static int msm_otg_set_peripheral(struct usb_otg *otg, | |||
785 | * Kick the state machine work, if host is not supported | 813 | * Kick the state machine work, if host is not supported |
786 | * or host is already registered with us. | 814 | * or host is already registered with us. |
787 | */ | 815 | */ |
788 | if (motg->pdata->mode == USB_PERIPHERAL || otg->host) { | 816 | if (motg->pdata->mode == USB_DR_MODE_PERIPHERAL || otg->host) { |
789 | pm_runtime_get_sync(otg->phy->dev); | 817 | pm_runtime_get_sync(otg->phy->dev); |
790 | schedule_work(&motg->sm_work); | 818 | schedule_work(&motg->sm_work); |
791 | } | 819 | } |
@@ -1106,7 +1134,7 @@ static void msm_otg_init_sm(struct msm_otg *motg) | |||
1106 | u32 otgsc = readl(USB_OTGSC); | 1134 | u32 otgsc = readl(USB_OTGSC); |
1107 | 1135 | ||
1108 | switch (pdata->mode) { | 1136 | switch (pdata->mode) { |
1109 | case USB_OTG: | 1137 | case USB_DR_MODE_OTG: |
1110 | if (pdata->otg_control == OTG_PHY_CONTROL) { | 1138 | if (pdata->otg_control == OTG_PHY_CONTROL) { |
1111 | if (otgsc & OTGSC_ID) | 1139 | if (otgsc & OTGSC_ID) |
1112 | set_bit(ID, &motg->inputs); | 1140 | set_bit(ID, &motg->inputs); |
@@ -1118,21 +1146,14 @@ static void msm_otg_init_sm(struct msm_otg *motg) | |||
1118 | else | 1146 | else |
1119 | clear_bit(B_SESS_VLD, &motg->inputs); | 1147 | clear_bit(B_SESS_VLD, &motg->inputs); |
1120 | } else if (pdata->otg_control == OTG_USER_CONTROL) { | 1148 | } else if (pdata->otg_control == OTG_USER_CONTROL) { |
1121 | if (pdata->default_mode == USB_HOST) { | ||
1122 | clear_bit(ID, &motg->inputs); | ||
1123 | } else if (pdata->default_mode == USB_PERIPHERAL) { | ||
1124 | set_bit(ID, &motg->inputs); | ||
1125 | set_bit(B_SESS_VLD, &motg->inputs); | ||
1126 | } else { | ||
1127 | set_bit(ID, &motg->inputs); | 1149 | set_bit(ID, &motg->inputs); |
1128 | clear_bit(B_SESS_VLD, &motg->inputs); | 1150 | clear_bit(B_SESS_VLD, &motg->inputs); |
1129 | } | ||
1130 | } | 1151 | } |
1131 | break; | 1152 | break; |
1132 | case USB_HOST: | 1153 | case USB_DR_MODE_HOST: |
1133 | clear_bit(ID, &motg->inputs); | 1154 | clear_bit(ID, &motg->inputs); |
1134 | break; | 1155 | break; |
1135 | case USB_PERIPHERAL: | 1156 | case USB_DR_MODE_PERIPHERAL: |
1136 | set_bit(ID, &motg->inputs); | 1157 | set_bit(ID, &motg->inputs); |
1137 | if (otgsc & OTGSC_BSV) | 1158 | if (otgsc & OTGSC_BSV) |
1138 | set_bit(B_SESS_VLD, &motg->inputs); | 1159 | set_bit(B_SESS_VLD, &motg->inputs); |
@@ -1282,13 +1303,13 @@ static int msm_otg_mode_show(struct seq_file *s, void *unused) | |||
1282 | 1303 | ||
1283 | switch (otg->phy->state) { | 1304 | switch (otg->phy->state) { |
1284 | case OTG_STATE_A_HOST: | 1305 | case OTG_STATE_A_HOST: |
1285 | seq_printf(s, "host\n"); | 1306 | seq_puts(s, "host\n"); |
1286 | break; | 1307 | break; |
1287 | case OTG_STATE_B_PERIPHERAL: | 1308 | case OTG_STATE_B_PERIPHERAL: |
1288 | seq_printf(s, "peripheral\n"); | 1309 | seq_puts(s, "peripheral\n"); |
1289 | break; | 1310 | break; |
1290 | default: | 1311 | default: |
1291 | seq_printf(s, "none\n"); | 1312 | seq_puts(s, "none\n"); |
1292 | break; | 1313 | break; |
1293 | } | 1314 | } |
1294 | 1315 | ||
@@ -1308,7 +1329,7 @@ static ssize_t msm_otg_mode_write(struct file *file, const char __user *ubuf, | |||
1308 | char buf[16]; | 1329 | char buf[16]; |
1309 | struct usb_otg *otg = motg->phy.otg; | 1330 | struct usb_otg *otg = motg->phy.otg; |
1310 | int status = count; | 1331 | int status = count; |
1311 | enum usb_mode_type req_mode; | 1332 | enum usb_dr_mode req_mode; |
1312 | 1333 | ||
1313 | memset(buf, 0x00, sizeof(buf)); | 1334 | memset(buf, 0x00, sizeof(buf)); |
1314 | 1335 | ||
@@ -1318,18 +1339,18 @@ static ssize_t msm_otg_mode_write(struct file *file, const char __user *ubuf, | |||
1318 | } | 1339 | } |
1319 | 1340 | ||
1320 | if (!strncmp(buf, "host", 4)) { | 1341 | if (!strncmp(buf, "host", 4)) { |
1321 | req_mode = USB_HOST; | 1342 | req_mode = USB_DR_MODE_HOST; |
1322 | } else if (!strncmp(buf, "peripheral", 10)) { | 1343 | } else if (!strncmp(buf, "peripheral", 10)) { |
1323 | req_mode = USB_PERIPHERAL; | 1344 | req_mode = USB_DR_MODE_PERIPHERAL; |
1324 | } else if (!strncmp(buf, "none", 4)) { | 1345 | } else if (!strncmp(buf, "none", 4)) { |
1325 | req_mode = USB_NONE; | 1346 | req_mode = USB_DR_MODE_UNKNOWN; |
1326 | } else { | 1347 | } else { |
1327 | status = -EINVAL; | 1348 | status = -EINVAL; |
1328 | goto out; | 1349 | goto out; |
1329 | } | 1350 | } |
1330 | 1351 | ||
1331 | switch (req_mode) { | 1352 | switch (req_mode) { |
1332 | case USB_NONE: | 1353 | case USB_DR_MODE_UNKNOWN: |
1333 | switch (otg->phy->state) { | 1354 | switch (otg->phy->state) { |
1334 | case OTG_STATE_A_HOST: | 1355 | case OTG_STATE_A_HOST: |
1335 | case OTG_STATE_B_PERIPHERAL: | 1356 | case OTG_STATE_B_PERIPHERAL: |
@@ -1340,7 +1361,7 @@ static ssize_t msm_otg_mode_write(struct file *file, const char __user *ubuf, | |||
1340 | goto out; | 1361 | goto out; |
1341 | } | 1362 | } |
1342 | break; | 1363 | break; |
1343 | case USB_PERIPHERAL: | 1364 | case USB_DR_MODE_PERIPHERAL: |
1344 | switch (otg->phy->state) { | 1365 | switch (otg->phy->state) { |
1345 | case OTG_STATE_B_IDLE: | 1366 | case OTG_STATE_B_IDLE: |
1346 | case OTG_STATE_A_HOST: | 1367 | case OTG_STATE_A_HOST: |
@@ -1351,7 +1372,7 @@ static ssize_t msm_otg_mode_write(struct file *file, const char __user *ubuf, | |||
1351 | goto out; | 1372 | goto out; |
1352 | } | 1373 | } |
1353 | break; | 1374 | break; |
1354 | case USB_HOST: | 1375 | case USB_DR_MODE_HOST: |
1355 | switch (otg->phy->state) { | 1376 | switch (otg->phy->state) { |
1356 | case OTG_STATE_B_IDLE: | 1377 | case OTG_STATE_B_IDLE: |
1357 | case OTG_STATE_B_PERIPHERAL: | 1378 | case OTG_STATE_B_PERIPHERAL: |
@@ -1406,74 +1427,154 @@ static void msm_otg_debugfs_cleanup(void) | |||
1406 | debugfs_remove(msm_otg_dbg_root); | 1427 | debugfs_remove(msm_otg_dbg_root); |
1407 | } | 1428 | } |
1408 | 1429 | ||
1409 | static int __init msm_otg_probe(struct platform_device *pdev) | 1430 | static struct of_device_id msm_otg_dt_match[] = { |
1431 | { | ||
1432 | .compatible = "qcom,usb-otg-ci", | ||
1433 | .data = (void *) CI_45NM_INTEGRATED_PHY | ||
1434 | }, | ||
1435 | { | ||
1436 | .compatible = "qcom,usb-otg-snps", | ||
1437 | .data = (void *) SNPS_28NM_INTEGRATED_PHY | ||
1438 | }, | ||
1439 | { } | ||
1440 | }; | ||
1441 | MODULE_DEVICE_TABLE(of, msm_otg_dt_match); | ||
1442 | |||
1443 | static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg) | ||
1410 | { | 1444 | { |
1445 | struct msm_otg_platform_data *pdata; | ||
1446 | const struct of_device_id *id; | ||
1447 | struct device_node *node = pdev->dev.of_node; | ||
1448 | struct property *prop; | ||
1449 | int len, ret, words; | ||
1450 | u32 val, tmp[3]; | ||
1451 | |||
1452 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
1453 | if (!pdata) | ||
1454 | return -ENOMEM; | ||
1455 | |||
1456 | motg->pdata = pdata; | ||
1457 | |||
1458 | id = of_match_device(msm_otg_dt_match, &pdev->dev); | ||
1459 | pdata->phy_type = (enum msm_usb_phy_type) id->data; | ||
1460 | |||
1461 | motg->link_rst = devm_reset_control_get(&pdev->dev, "link"); | ||
1462 | if (IS_ERR(motg->link_rst)) | ||
1463 | return PTR_ERR(motg->link_rst); | ||
1464 | |||
1465 | motg->phy_rst = devm_reset_control_get(&pdev->dev, "phy"); | ||
1466 | if (IS_ERR(motg->phy_rst)) | ||
1467 | return PTR_ERR(motg->phy_rst); | ||
1468 | |||
1469 | pdata->mode = of_usb_get_dr_mode(node); | ||
1470 | if (pdata->mode == USB_DR_MODE_UNKNOWN) | ||
1471 | pdata->mode = USB_DR_MODE_OTG; | ||
1472 | |||
1473 | pdata->otg_control = OTG_PHY_CONTROL; | ||
1474 | if (!of_property_read_u32(node, "qcom,otg-control", &val)) | ||
1475 | if (val == OTG_PMIC_CONTROL) | ||
1476 | pdata->otg_control = val; | ||
1477 | |||
1478 | if (!of_property_read_u32(node, "qcom,phy-num", &val) && val < 2) | ||
1479 | motg->phy_number = val; | ||
1480 | |||
1481 | motg->vdd_levels[VDD_LEVEL_NONE] = USB_PHY_SUSP_DIG_VOL; | ||
1482 | motg->vdd_levels[VDD_LEVEL_MIN] = USB_PHY_VDD_DIG_VOL_MIN; | ||
1483 | motg->vdd_levels[VDD_LEVEL_MAX] = USB_PHY_VDD_DIG_VOL_MAX; | ||
1484 | |||
1485 | if (of_get_property(node, "qcom,vdd-levels", &len) && | ||
1486 | len == sizeof(tmp)) { | ||
1487 | of_property_read_u32_array(node, "qcom,vdd-levels", | ||
1488 | tmp, len / sizeof(*tmp)); | ||
1489 | motg->vdd_levels[VDD_LEVEL_NONE] = tmp[VDD_LEVEL_NONE]; | ||
1490 | motg->vdd_levels[VDD_LEVEL_MIN] = tmp[VDD_LEVEL_MIN]; | ||
1491 | motg->vdd_levels[VDD_LEVEL_MAX] = tmp[VDD_LEVEL_MAX]; | ||
1492 | } | ||
1493 | |||
1494 | prop = of_find_property(node, "qcom,phy-init-sequence", &len); | ||
1495 | if (!prop || !len) | ||
1496 | return 0; | ||
1497 | |||
1498 | words = len / sizeof(u32); | ||
1499 | |||
1500 | if (words >= ULPI_EXT_VENDOR_SPECIFIC) { | ||
1501 | dev_warn(&pdev->dev, "Too big PHY init sequence %d\n", words); | ||
1502 | return 0; | ||
1503 | } | ||
1504 | |||
1505 | pdata->phy_init_seq = devm_kzalloc(&pdev->dev, len, GFP_KERNEL); | ||
1506 | if (!pdata->phy_init_seq) { | ||
1507 | dev_warn(&pdev->dev, "No space for PHY init sequence\n"); | ||
1508 | return 0; | ||
1509 | } | ||
1510 | |||
1511 | ret = of_property_read_u32_array(node, "qcom,phy-init-sequence", | ||
1512 | pdata->phy_init_seq, words); | ||
1513 | if (!ret) | ||
1514 | pdata->phy_init_sz = words; | ||
1515 | |||
1516 | return 0; | ||
1517 | } | ||
1518 | |||
1519 | static int msm_otg_probe(struct platform_device *pdev) | ||
1520 | { | ||
1521 | struct regulator_bulk_data regs[3]; | ||
1411 | int ret = 0; | 1522 | int ret = 0; |
1523 | struct device_node *np = pdev->dev.of_node; | ||
1524 | struct msm_otg_platform_data *pdata; | ||
1412 | struct resource *res; | 1525 | struct resource *res; |
1413 | struct msm_otg *motg; | 1526 | struct msm_otg *motg; |
1414 | struct usb_phy *phy; | 1527 | struct usb_phy *phy; |
1528 | void __iomem *phy_select; | ||
1415 | 1529 | ||
1416 | dev_info(&pdev->dev, "msm_otg probe\n"); | 1530 | motg = devm_kzalloc(&pdev->dev, sizeof(struct msm_otg), GFP_KERNEL); |
1417 | if (!dev_get_platdata(&pdev->dev)) { | ||
1418 | dev_err(&pdev->dev, "No platform data given. Bailing out\n"); | ||
1419 | return -ENODEV; | ||
1420 | } | ||
1421 | |||
1422 | motg = kzalloc(sizeof(struct msm_otg), GFP_KERNEL); | ||
1423 | if (!motg) { | 1531 | if (!motg) { |
1424 | dev_err(&pdev->dev, "unable to allocate msm_otg\n"); | 1532 | dev_err(&pdev->dev, "unable to allocate msm_otg\n"); |
1425 | return -ENOMEM; | 1533 | return -ENOMEM; |
1426 | } | 1534 | } |
1427 | 1535 | ||
1428 | motg->phy.otg = kzalloc(sizeof(struct usb_otg), GFP_KERNEL); | 1536 | pdata = dev_get_platdata(&pdev->dev); |
1537 | if (!pdata) { | ||
1538 | if (!np) | ||
1539 | return -ENXIO; | ||
1540 | ret = msm_otg_read_dt(pdev, motg); | ||
1541 | if (ret) | ||
1542 | return ret; | ||
1543 | } | ||
1544 | |||
1545 | motg->phy.otg = devm_kzalloc(&pdev->dev, sizeof(struct usb_otg), | ||
1546 | GFP_KERNEL); | ||
1429 | if (!motg->phy.otg) { | 1547 | if (!motg->phy.otg) { |
1430 | dev_err(&pdev->dev, "unable to allocate msm_otg\n"); | 1548 | dev_err(&pdev->dev, "unable to allocate msm_otg\n"); |
1431 | ret = -ENOMEM; | 1549 | return -ENOMEM; |
1432 | goto free_motg; | ||
1433 | } | 1550 | } |
1434 | 1551 | ||
1435 | motg->pdata = dev_get_platdata(&pdev->dev); | ||
1436 | phy = &motg->phy; | 1552 | phy = &motg->phy; |
1437 | phy->dev = &pdev->dev; | 1553 | phy->dev = &pdev->dev; |
1438 | 1554 | ||
1439 | motg->phy_reset_clk = clk_get(&pdev->dev, "usb_phy_clk"); | 1555 | motg->phy_reset_clk = devm_clk_get(&pdev->dev, |
1556 | np ? "phy" : "usb_phy_clk"); | ||
1440 | if (IS_ERR(motg->phy_reset_clk)) { | 1557 | if (IS_ERR(motg->phy_reset_clk)) { |
1441 | dev_err(&pdev->dev, "failed to get usb_phy_clk\n"); | 1558 | dev_err(&pdev->dev, "failed to get usb_phy_clk\n"); |
1442 | ret = PTR_ERR(motg->phy_reset_clk); | 1559 | return PTR_ERR(motg->phy_reset_clk); |
1443 | goto free_motg; | ||
1444 | } | 1560 | } |
1445 | 1561 | ||
1446 | motg->clk = clk_get(&pdev->dev, "usb_hs_clk"); | 1562 | motg->clk = devm_clk_get(&pdev->dev, np ? "core" : "usb_hs_clk"); |
1447 | if (IS_ERR(motg->clk)) { | 1563 | if (IS_ERR(motg->clk)) { |
1448 | dev_err(&pdev->dev, "failed to get usb_hs_clk\n"); | 1564 | dev_err(&pdev->dev, "failed to get usb_hs_clk\n"); |
1449 | ret = PTR_ERR(motg->clk); | 1565 | return PTR_ERR(motg->clk); |
1450 | goto put_phy_reset_clk; | ||
1451 | } | 1566 | } |
1452 | clk_set_rate(motg->clk, 60000000); | ||
1453 | 1567 | ||
1454 | /* | 1568 | /* |
1455 | * If USB Core is running its protocol engine based on CORE CLK, | 1569 | * If USB Core is running its protocol engine based on CORE CLK, |
1456 | * CORE CLK must be running at >55Mhz for correct HSUSB | 1570 | * CORE CLK must be running at >55Mhz for correct HSUSB |
1457 | * operation and USB core cannot tolerate frequency changes on | 1571 | * operation and USB core cannot tolerate frequency changes on |
1458 | * CORE CLK. For such USB cores, vote for maximum clk frequency | 1572 | * CORE CLK. |
1459 | * on pclk source | ||
1460 | */ | 1573 | */ |
1461 | if (motg->pdata->pclk_src_name) { | 1574 | motg->pclk = devm_clk_get(&pdev->dev, np ? "iface" : "usb_hs_pclk"); |
1462 | motg->pclk_src = clk_get(&pdev->dev, | ||
1463 | motg->pdata->pclk_src_name); | ||
1464 | if (IS_ERR(motg->pclk_src)) | ||
1465 | goto put_clk; | ||
1466 | clk_set_rate(motg->pclk_src, INT_MAX); | ||
1467 | clk_prepare_enable(motg->pclk_src); | ||
1468 | } else | ||
1469 | motg->pclk_src = ERR_PTR(-ENOENT); | ||
1470 | |||
1471 | |||
1472 | motg->pclk = clk_get(&pdev->dev, "usb_hs_pclk"); | ||
1473 | if (IS_ERR(motg->pclk)) { | 1575 | if (IS_ERR(motg->pclk)) { |
1474 | dev_err(&pdev->dev, "failed to get usb_hs_pclk\n"); | 1576 | dev_err(&pdev->dev, "failed to get usb_hs_pclk\n"); |
1475 | ret = PTR_ERR(motg->pclk); | 1577 | return PTR_ERR(motg->pclk); |
1476 | goto put_pclk_src; | ||
1477 | } | 1578 | } |
1478 | 1579 | ||
1479 | /* | 1580 | /* |
@@ -1481,69 +1582,88 @@ static int __init msm_otg_probe(struct platform_device *pdev) | |||
1481 | * clock is introduced to remove the dependency on AXI | 1582 | * clock is introduced to remove the dependency on AXI |
1482 | * bus frequency. | 1583 | * bus frequency. |
1483 | */ | 1584 | */ |
1484 | motg->core_clk = clk_get(&pdev->dev, "usb_hs_core_clk"); | 1585 | motg->core_clk = devm_clk_get(&pdev->dev, |
1485 | if (IS_ERR(motg->core_clk)) | 1586 | np ? "alt_core" : "usb_hs_core_clk"); |
1486 | motg->core_clk = NULL; | ||
1487 | 1587 | ||
1488 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1588 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1489 | if (!res) { | 1589 | motg->regs = devm_ioremap_resource(&pdev->dev, res); |
1490 | dev_err(&pdev->dev, "failed to get platform resource mem\n"); | 1590 | if (IS_ERR(motg->regs)) |
1491 | ret = -ENODEV; | 1591 | return PTR_ERR(motg->regs); |
1492 | goto put_core_clk; | ||
1493 | } | ||
1494 | 1592 | ||
1495 | motg->regs = ioremap(res->start, resource_size(res)); | 1593 | /* |
1496 | if (!motg->regs) { | 1594 | * NOTE: The PHYs can be multiplexed between the chipidea controller |
1497 | dev_err(&pdev->dev, "ioremap failed\n"); | 1595 | * and the dwc3 controller, using a single bit. It is important that |
1498 | ret = -ENOMEM; | 1596 | * the dwc3 driver does not set this bit in an incompatible way. |
1499 | goto put_core_clk; | 1597 | */ |
1598 | if (motg->phy_number) { | ||
1599 | phy_select = devm_ioremap_nocache(&pdev->dev, USB2_PHY_SEL, 4); | ||
1600 | if (IS_ERR(phy_select)) | ||
1601 | return PTR_ERR(phy_select); | ||
1602 | /* Enable second PHY with the OTG port */ | ||
1603 | writel(0x1, phy_select); | ||
1500 | } | 1604 | } |
1605 | |||
1501 | dev_info(&pdev->dev, "OTG regs = %p\n", motg->regs); | 1606 | dev_info(&pdev->dev, "OTG regs = %p\n", motg->regs); |
1502 | 1607 | ||
1503 | motg->irq = platform_get_irq(pdev, 0); | 1608 | motg->irq = platform_get_irq(pdev, 0); |
1504 | if (!motg->irq) { | 1609 | if (motg->irq < 0) { |
1505 | dev_err(&pdev->dev, "platform_get_irq failed\n"); | 1610 | dev_err(&pdev->dev, "platform_get_irq failed\n"); |
1506 | ret = -ENODEV; | 1611 | return motg->irq; |
1507 | goto free_regs; | ||
1508 | } | 1612 | } |
1509 | 1613 | ||
1614 | regs[0].supply = "vddcx"; | ||
1615 | regs[1].supply = "v3p3"; | ||
1616 | regs[2].supply = "v1p8"; | ||
1617 | |||
1618 | ret = devm_regulator_bulk_get(motg->phy.dev, ARRAY_SIZE(regs), regs); | ||
1619 | if (ret) | ||
1620 | return ret; | ||
1621 | |||
1622 | motg->vddcx = regs[0].consumer; | ||
1623 | motg->v3p3 = regs[1].consumer; | ||
1624 | motg->v1p8 = regs[2].consumer; | ||
1625 | |||
1626 | clk_set_rate(motg->clk, 60000000); | ||
1627 | |||
1510 | clk_prepare_enable(motg->clk); | 1628 | clk_prepare_enable(motg->clk); |
1511 | clk_prepare_enable(motg->pclk); | 1629 | clk_prepare_enable(motg->pclk); |
1512 | 1630 | ||
1631 | if (!IS_ERR(motg->core_clk)) | ||
1632 | clk_prepare_enable(motg->core_clk); | ||
1633 | |||
1513 | ret = msm_hsusb_init_vddcx(motg, 1); | 1634 | ret = msm_hsusb_init_vddcx(motg, 1); |
1514 | if (ret) { | 1635 | if (ret) { |
1515 | dev_err(&pdev->dev, "hsusb vddcx configuration failed\n"); | 1636 | dev_err(&pdev->dev, "hsusb vddcx configuration failed\n"); |
1516 | goto free_regs; | 1637 | goto disable_clks; |
1517 | } | 1638 | } |
1518 | 1639 | ||
1519 | ret = msm_hsusb_ldo_init(motg, 1); | 1640 | ret = msm_hsusb_ldo_init(motg, 1); |
1520 | if (ret) { | 1641 | if (ret) { |
1521 | dev_err(&pdev->dev, "hsusb vreg configuration failed\n"); | 1642 | dev_err(&pdev->dev, "hsusb vreg configuration failed\n"); |
1522 | goto vddcx_exit; | 1643 | goto disable_vddcx; |
1523 | } | 1644 | } |
1524 | ret = msm_hsusb_ldo_set_mode(1); | 1645 | ret = msm_hsusb_ldo_set_mode(motg, 1); |
1525 | if (ret) { | 1646 | if (ret) { |
1526 | dev_err(&pdev->dev, "hsusb vreg enable failed\n"); | 1647 | dev_err(&pdev->dev, "hsusb vreg enable failed\n"); |
1527 | goto ldo_exit; | 1648 | goto disable_ldo; |
1528 | } | 1649 | } |
1529 | 1650 | ||
1530 | if (motg->core_clk) | ||
1531 | clk_prepare_enable(motg->core_clk); | ||
1532 | |||
1533 | writel(0, USB_USBINTR); | 1651 | writel(0, USB_USBINTR); |
1534 | writel(0, USB_OTGSC); | 1652 | writel(0, USB_OTGSC); |
1535 | 1653 | ||
1536 | INIT_WORK(&motg->sm_work, msm_otg_sm_work); | 1654 | INIT_WORK(&motg->sm_work, msm_otg_sm_work); |
1537 | INIT_DELAYED_WORK(&motg->chg_work, msm_chg_detect_work); | 1655 | INIT_DELAYED_WORK(&motg->chg_work, msm_chg_detect_work); |
1538 | ret = request_irq(motg->irq, msm_otg_irq, IRQF_SHARED, | 1656 | ret = devm_request_irq(&pdev->dev, motg->irq, msm_otg_irq, IRQF_SHARED, |
1539 | "msm_otg", motg); | 1657 | "msm_otg", motg); |
1540 | if (ret) { | 1658 | if (ret) { |
1541 | dev_err(&pdev->dev, "request irq failed\n"); | 1659 | dev_err(&pdev->dev, "request irq failed\n"); |
1542 | goto disable_clks; | 1660 | goto disable_ldo; |
1543 | } | 1661 | } |
1544 | 1662 | ||
1545 | phy->init = msm_otg_reset; | 1663 | phy->init = msm_phy_init; |
1546 | phy->set_power = msm_otg_set_power; | 1664 | phy->set_power = msm_otg_set_power; |
1665 | phy->notify_disconnect = msm_phy_notify_disconnect; | ||
1666 | phy->type = USB_PHY_TYPE_USB2; | ||
1547 | 1667 | ||
1548 | phy->io_ops = &msm_otg_io_ops; | 1668 | phy->io_ops = &msm_otg_io_ops; |
1549 | 1669 | ||
@@ -1551,54 +1671,38 @@ static int __init msm_otg_probe(struct platform_device *pdev) | |||
1551 | phy->otg->set_host = msm_otg_set_host; | 1671 | phy->otg->set_host = msm_otg_set_host; |
1552 | phy->otg->set_peripheral = msm_otg_set_peripheral; | 1672 | phy->otg->set_peripheral = msm_otg_set_peripheral; |
1553 | 1673 | ||
1554 | ret = usb_add_phy(&motg->phy, USB_PHY_TYPE_USB2); | 1674 | msm_usb_reset(phy); |
1675 | |||
1676 | ret = usb_add_phy_dev(&motg->phy); | ||
1555 | if (ret) { | 1677 | if (ret) { |
1556 | dev_err(&pdev->dev, "usb_add_phy failed\n"); | 1678 | dev_err(&pdev->dev, "usb_add_phy failed\n"); |
1557 | goto free_irq; | 1679 | goto disable_ldo; |
1558 | } | 1680 | } |
1559 | 1681 | ||
1560 | platform_set_drvdata(pdev, motg); | 1682 | platform_set_drvdata(pdev, motg); |
1561 | device_init_wakeup(&pdev->dev, 1); | 1683 | device_init_wakeup(&pdev->dev, 1); |
1562 | 1684 | ||
1563 | if (motg->pdata->mode == USB_OTG && | 1685 | if (motg->pdata->mode == USB_DR_MODE_OTG && |
1564 | motg->pdata->otg_control == OTG_USER_CONTROL) { | 1686 | motg->pdata->otg_control == OTG_USER_CONTROL) { |
1565 | ret = msm_otg_debugfs_init(motg); | 1687 | ret = msm_otg_debugfs_init(motg); |
1566 | if (ret) | 1688 | if (ret) |
1567 | dev_dbg(&pdev->dev, "mode debugfs file is" | 1689 | dev_dbg(&pdev->dev, "Can not create mode change file\n"); |
1568 | "not available\n"); | ||
1569 | } | 1690 | } |
1570 | 1691 | ||
1571 | pm_runtime_set_active(&pdev->dev); | 1692 | pm_runtime_set_active(&pdev->dev); |
1572 | pm_runtime_enable(&pdev->dev); | 1693 | pm_runtime_enable(&pdev->dev); |
1573 | 1694 | ||
1574 | return 0; | 1695 | return 0; |
1575 | free_irq: | 1696 | |
1576 | free_irq(motg->irq, motg); | 1697 | disable_ldo: |
1698 | msm_hsusb_ldo_init(motg, 0); | ||
1699 | disable_vddcx: | ||
1700 | msm_hsusb_init_vddcx(motg, 0); | ||
1577 | disable_clks: | 1701 | disable_clks: |
1578 | clk_disable_unprepare(motg->pclk); | 1702 | clk_disable_unprepare(motg->pclk); |
1579 | clk_disable_unprepare(motg->clk); | 1703 | clk_disable_unprepare(motg->clk); |
1580 | ldo_exit: | 1704 | if (!IS_ERR(motg->core_clk)) |
1581 | msm_hsusb_ldo_init(motg, 0); | 1705 | clk_disable_unprepare(motg->core_clk); |
1582 | vddcx_exit: | ||
1583 | msm_hsusb_init_vddcx(motg, 0); | ||
1584 | free_regs: | ||
1585 | iounmap(motg->regs); | ||
1586 | put_core_clk: | ||
1587 | if (motg->core_clk) | ||
1588 | clk_put(motg->core_clk); | ||
1589 | clk_put(motg->pclk); | ||
1590 | put_pclk_src: | ||
1591 | if (!IS_ERR(motg->pclk_src)) { | ||
1592 | clk_disable_unprepare(motg->pclk_src); | ||
1593 | clk_put(motg->pclk_src); | ||
1594 | } | ||
1595 | put_clk: | ||
1596 | clk_put(motg->clk); | ||
1597 | put_phy_reset_clk: | ||
1598 | clk_put(motg->phy_reset_clk); | ||
1599 | free_motg: | ||
1600 | kfree(motg->phy.otg); | ||
1601 | kfree(motg); | ||
1602 | return ret; | 1706 | return ret; |
1603 | } | 1707 | } |
1604 | 1708 | ||
@@ -1621,7 +1725,7 @@ static int msm_otg_remove(struct platform_device *pdev) | |||
1621 | pm_runtime_disable(&pdev->dev); | 1725 | pm_runtime_disable(&pdev->dev); |
1622 | 1726 | ||
1623 | usb_remove_phy(phy); | 1727 | usb_remove_phy(phy); |
1624 | free_irq(motg->irq, motg); | 1728 | disable_irq(motg->irq); |
1625 | 1729 | ||
1626 | /* | 1730 | /* |
1627 | * Put PHY in low power mode. | 1731 | * Put PHY in low power mode. |
@@ -1641,26 +1745,12 @@ static int msm_otg_remove(struct platform_device *pdev) | |||
1641 | 1745 | ||
1642 | clk_disable_unprepare(motg->pclk); | 1746 | clk_disable_unprepare(motg->pclk); |
1643 | clk_disable_unprepare(motg->clk); | 1747 | clk_disable_unprepare(motg->clk); |
1644 | if (motg->core_clk) | 1748 | if (!IS_ERR(motg->core_clk)) |
1645 | clk_disable_unprepare(motg->core_clk); | 1749 | clk_disable_unprepare(motg->core_clk); |
1646 | if (!IS_ERR(motg->pclk_src)) { | ||
1647 | clk_disable_unprepare(motg->pclk_src); | ||
1648 | clk_put(motg->pclk_src); | ||
1649 | } | ||
1650 | msm_hsusb_ldo_init(motg, 0); | 1750 | msm_hsusb_ldo_init(motg, 0); |
1651 | 1751 | ||
1652 | iounmap(motg->regs); | ||
1653 | pm_runtime_set_suspended(&pdev->dev); | 1752 | pm_runtime_set_suspended(&pdev->dev); |
1654 | 1753 | ||
1655 | clk_put(motg->phy_reset_clk); | ||
1656 | clk_put(motg->pclk); | ||
1657 | clk_put(motg->clk); | ||
1658 | if (motg->core_clk) | ||
1659 | clk_put(motg->core_clk); | ||
1660 | |||
1661 | kfree(motg->phy.otg); | ||
1662 | kfree(motg); | ||
1663 | |||
1664 | return 0; | 1754 | return 0; |
1665 | } | 1755 | } |
1666 | 1756 | ||
@@ -1740,15 +1830,17 @@ static const struct dev_pm_ops msm_otg_dev_pm_ops = { | |||
1740 | }; | 1830 | }; |
1741 | 1831 | ||
1742 | static struct platform_driver msm_otg_driver = { | 1832 | static struct platform_driver msm_otg_driver = { |
1833 | .probe = msm_otg_probe, | ||
1743 | .remove = msm_otg_remove, | 1834 | .remove = msm_otg_remove, |
1744 | .driver = { | 1835 | .driver = { |
1745 | .name = DRIVER_NAME, | 1836 | .name = DRIVER_NAME, |
1746 | .owner = THIS_MODULE, | 1837 | .owner = THIS_MODULE, |
1747 | .pm = &msm_otg_dev_pm_ops, | 1838 | .pm = &msm_otg_dev_pm_ops, |
1839 | .of_match_table = msm_otg_dt_match, | ||
1748 | }, | 1840 | }, |
1749 | }; | 1841 | }; |
1750 | 1842 | ||
1751 | module_platform_driver_probe(msm_otg_driver, msm_otg_probe); | 1843 | module_platform_driver(msm_otg_driver); |
1752 | 1844 | ||
1753 | MODULE_LICENSE("GPL v2"); | 1845 | MODULE_LICENSE("GPL v2"); |
1754 | MODULE_DESCRIPTION("MSM USB transceiver driver"); | 1846 | MODULE_DESCRIPTION("MSM USB transceiver driver"); |
diff --git a/drivers/usb/phy/phy-ulpi.c b/drivers/usb/phy/phy-ulpi.c index 17ea3f271bd8..4e3877c329f2 100644 --- a/drivers/usb/phy/phy-ulpi.c +++ b/drivers/usb/phy/phy-ulpi.c | |||
@@ -48,6 +48,7 @@ static struct ulpi_info ulpi_ids[] = { | |||
48 | ULPI_INFO(ULPI_ID(0x04cc, 0x1504), "NXP ISP1504"), | 48 | ULPI_INFO(ULPI_ID(0x04cc, 0x1504), "NXP ISP1504"), |
49 | ULPI_INFO(ULPI_ID(0x0424, 0x0006), "SMSC USB331x"), | 49 | ULPI_INFO(ULPI_ID(0x0424, 0x0006), "SMSC USB331x"), |
50 | ULPI_INFO(ULPI_ID(0x0424, 0x0007), "SMSC USB3320"), | 50 | ULPI_INFO(ULPI_ID(0x0424, 0x0007), "SMSC USB3320"), |
51 | ULPI_INFO(ULPI_ID(0x0424, 0x0009), "SMSC USB334x"), | ||
51 | ULPI_INFO(ULPI_ID(0x0451, 0x1507), "TI TUSB1210"), | 52 | ULPI_INFO(ULPI_ID(0x0451, 0x1507), "TI TUSB1210"), |
52 | }; | 53 | }; |
53 | 54 | ||
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index d3ca3b53837c..7373203140e7 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h | |||
@@ -57,6 +57,61 @@ | |||
57 | struct usb_configuration; | 57 | struct usb_configuration; |
58 | 58 | ||
59 | /** | 59 | /** |
60 | * struct usb_os_desc_ext_prop - describes one "Extended Property" | ||
61 | * @entry: used to keep a list of extended properties | ||
62 | * @type: Extended Property type | ||
63 | * @name_len: Extended Property unicode name length, including terminating '\0' | ||
64 | * @name: Extended Property name | ||
65 | * @data_len: Length of Extended Property blob (for unicode store double len) | ||
66 | * @data: Extended Property blob | ||
67 | * @item: Represents this Extended Property in configfs | ||
68 | */ | ||
69 | struct usb_os_desc_ext_prop { | ||
70 | struct list_head entry; | ||
71 | u8 type; | ||
72 | int name_len; | ||
73 | char *name; | ||
74 | int data_len; | ||
75 | char *data; | ||
76 | struct config_item item; | ||
77 | }; | ||
78 | |||
79 | /** | ||
80 | * struct usb_os_desc - describes OS descriptors associated with one interface | ||
81 | * @ext_compat_id: 16 bytes of "Compatible ID" and "Subcompatible ID" | ||
82 | * @ext_prop: Extended Properties list | ||
83 | * @ext_prop_len: Total length of Extended Properties blobs | ||
84 | * @ext_prop_count: Number of Extended Properties | ||
85 | * @opts_mutex: Optional mutex protecting config data of a usb_function_instance | ||
86 | * @group: Represents OS descriptors associated with an interface in configfs | ||
87 | * @owner: Module associated with this OS descriptor | ||
88 | */ | ||
89 | struct usb_os_desc { | ||
90 | char *ext_compat_id; | ||
91 | struct list_head ext_prop; | ||
92 | int ext_prop_len; | ||
93 | int ext_prop_count; | ||
94 | struct mutex *opts_mutex; | ||
95 | struct config_group group; | ||
96 | struct module *owner; | ||
97 | }; | ||
98 | |||
99 | /** | ||
100 | * struct usb_os_desc_table - describes OS descriptors associated with one | ||
101 | * interface of a usb_function | ||
102 | * @if_id: Interface id | ||
103 | * @os_desc: "Extended Compatibility ID" and "Extended Properties" of the | ||
104 | * interface | ||
105 | * | ||
106 | * Each interface can have at most one "Extended Compatibility ID" and a | ||
107 | * number of "Extended Properties". | ||
108 | */ | ||
109 | struct usb_os_desc_table { | ||
110 | int if_id; | ||
111 | struct usb_os_desc *os_desc; | ||
112 | }; | ||
113 | |||
114 | /** | ||
60 | * struct usb_function - describes one function of a configuration | 115 | * struct usb_function - describes one function of a configuration |
61 | * @name: For diagnostics, identifies the function. | 116 | * @name: For diagnostics, identifies the function. |
62 | * @strings: tables of strings, keyed by identifiers assigned during bind() | 117 | * @strings: tables of strings, keyed by identifiers assigned during bind() |
@@ -73,6 +128,10 @@ struct usb_configuration; | |||
73 | * be available at super speed. | 128 | * be available at super speed. |
74 | * @config: assigned when @usb_add_function() is called; this is the | 129 | * @config: assigned when @usb_add_function() is called; this is the |
75 | * configuration with which this function is associated. | 130 | * configuration with which this function is associated. |
131 | * @os_desc_table: Table of (interface id, os descriptors) pairs. The function | ||
132 | * can expose more than one interface. If an interface is a member of | ||
133 | * an IAD, only the first interface of IAD has its entry in the table. | ||
134 | * @os_desc_n: Number of entries in os_desc_table | ||
76 | * @bind: Before the gadget can register, all of its functions bind() to the | 135 | * @bind: Before the gadget can register, all of its functions bind() to the |
77 | * available resources including string and interface identifiers used | 136 | * available resources including string and interface identifiers used |
78 | * in interface or class descriptors; endpoints; I/O buffers; and so on. | 137 | * in interface or class descriptors; endpoints; I/O buffers; and so on. |
@@ -129,6 +188,9 @@ struct usb_function { | |||
129 | 188 | ||
130 | struct usb_configuration *config; | 189 | struct usb_configuration *config; |
131 | 190 | ||
191 | struct usb_os_desc_table *os_desc_table; | ||
192 | unsigned os_desc_n; | ||
193 | |||
132 | /* REVISIT: bind() functions can be marked __init, which | 194 | /* REVISIT: bind() functions can be marked __init, which |
133 | * makes trouble for section mismatch analysis. See if | 195 | * makes trouble for section mismatch analysis. See if |
134 | * we can't restructure things to avoid mismatching. | 196 | * we can't restructure things to avoid mismatching. |
@@ -327,6 +389,8 @@ extern void usb_composite_unregister(struct usb_composite_driver *driver); | |||
327 | extern void usb_composite_setup_continue(struct usb_composite_dev *cdev); | 389 | extern void usb_composite_setup_continue(struct usb_composite_dev *cdev); |
328 | extern int composite_dev_prepare(struct usb_composite_driver *composite, | 390 | extern int composite_dev_prepare(struct usb_composite_driver *composite, |
329 | struct usb_composite_dev *cdev); | 391 | struct usb_composite_dev *cdev); |
392 | extern int composite_os_desc_req_prepare(struct usb_composite_dev *cdev, | ||
393 | struct usb_ep *ep0); | ||
330 | void composite_dev_cleanup(struct usb_composite_dev *cdev); | 394 | void composite_dev_cleanup(struct usb_composite_dev *cdev); |
331 | 395 | ||
332 | static inline struct usb_composite_driver *to_cdriver( | 396 | static inline struct usb_composite_driver *to_cdriver( |
@@ -335,11 +399,19 @@ static inline struct usb_composite_driver *to_cdriver( | |||
335 | return container_of(gdrv, struct usb_composite_driver, gadget_driver); | 399 | return container_of(gdrv, struct usb_composite_driver, gadget_driver); |
336 | } | 400 | } |
337 | 401 | ||
402 | #define OS_STRING_QW_SIGN_LEN 14 | ||
403 | #define OS_STRING_IDX 0xEE | ||
404 | |||
338 | /** | 405 | /** |
339 | * struct usb_composite_device - represents one composite usb gadget | 406 | * struct usb_composite_device - represents one composite usb gadget |
340 | * @gadget: read-only, abstracts the gadget's usb peripheral controller | 407 | * @gadget: read-only, abstracts the gadget's usb peripheral controller |
341 | * @req: used for control responses; buffer is pre-allocated | 408 | * @req: used for control responses; buffer is pre-allocated |
409 | * @os_desc_req: used for OS descriptors responses; buffer is pre-allocated | ||
342 | * @config: the currently active configuration | 410 | * @config: the currently active configuration |
411 | * @qw_sign: qwSignature part of the OS string | ||
412 | * @b_vendor_code: bMS_VendorCode part of the OS string | ||
413 | * @use_os_string: false by default, interested gadgets set it | ||
414 | * @os_desc_config: the configuration to be used with OS descriptors | ||
343 | * | 415 | * |
344 | * One of these devices is allocated and initialized before the | 416 | * One of these devices is allocated and initialized before the |
345 | * associated device driver's bind() is called. | 417 | * associated device driver's bind() is called. |
@@ -369,9 +441,16 @@ static inline struct usb_composite_driver *to_cdriver( | |||
369 | struct usb_composite_dev { | 441 | struct usb_composite_dev { |
370 | struct usb_gadget *gadget; | 442 | struct usb_gadget *gadget; |
371 | struct usb_request *req; | 443 | struct usb_request *req; |
444 | struct usb_request *os_desc_req; | ||
372 | 445 | ||
373 | struct usb_configuration *config; | 446 | struct usb_configuration *config; |
374 | 447 | ||
448 | /* OS String is a custom (yet popular) extension to the USB standard. */ | ||
449 | u8 qw_sign[OS_STRING_QW_SIGN_LEN]; | ||
450 | u8 b_vendor_code; | ||
451 | struct usb_configuration *os_desc_config; | ||
452 | unsigned int use_os_string:1; | ||
453 | |||
375 | /* private: */ | 454 | /* private: */ |
376 | /* internals */ | 455 | /* internals */ |
377 | unsigned int suspended:1; | 456 | unsigned int suspended:1; |
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h index 32754835a39b..b0a39243295a 100644 --- a/include/linux/usb/msm_hsusb.h +++ b/include/linux/usb/msm_hsusb.h | |||
@@ -23,21 +23,6 @@ | |||
23 | #include <linux/clk.h> | 23 | #include <linux/clk.h> |
24 | 24 | ||
25 | /** | 25 | /** |
26 | * Supported USB modes | ||
27 | * | ||
28 | * USB_PERIPHERAL Only peripheral mode is supported. | ||
29 | * USB_HOST Only host mode is supported. | ||
30 | * USB_OTG OTG mode is supported. | ||
31 | * | ||
32 | */ | ||
33 | enum usb_mode_type { | ||
34 | USB_NONE = 0, | ||
35 | USB_PERIPHERAL, | ||
36 | USB_HOST, | ||
37 | USB_OTG, | ||
38 | }; | ||
39 | |||
40 | /** | ||
41 | * OTG control | 26 | * OTG control |
42 | * | 27 | * |
43 | * OTG_NO_CONTROL Id/VBUS notifications not required. Useful in host | 28 | * OTG_NO_CONTROL Id/VBUS notifications not required. Useful in host |
@@ -115,27 +100,23 @@ enum usb_chg_type { | |||
115 | /** | 100 | /** |
116 | * struct msm_otg_platform_data - platform device data | 101 | * struct msm_otg_platform_data - platform device data |
117 | * for msm_otg driver. | 102 | * for msm_otg driver. |
118 | * @phy_init_seq: PHY configuration sequence. val, reg pairs | 103 | * @phy_init_seq: PHY configuration sequence values. Value of -1 is reserved as |
119 | * terminated by -1. | 104 | * "do not overwrite default vaule at this address". |
105 | * @phy_init_sz: PHY configuration sequence size. | ||
120 | * @vbus_power: VBUS power on/off routine. | 106 | * @vbus_power: VBUS power on/off routine. |
121 | * @power_budget: VBUS power budget in mA (0 will be treated as 500mA). | 107 | * @power_budget: VBUS power budget in mA (0 will be treated as 500mA). |
122 | * @mode: Supported mode (OTG/peripheral/host). | 108 | * @mode: Supported mode (OTG/peripheral/host). |
123 | * @otg_control: OTG switch controlled by user/Id pin | 109 | * @otg_control: OTG switch controlled by user/Id pin |
124 | * @default_mode: Default operational mode. Applicable only if | ||
125 | * OTG switch is controller by user. | ||
126 | * @pclk_src_name: pclk is derived from ebi1_usb_clk in case of 7x27 and 8k | ||
127 | * dfab_usb_hs_clk in case of 8660 and 8960. | ||
128 | */ | 110 | */ |
129 | struct msm_otg_platform_data { | 111 | struct msm_otg_platform_data { |
130 | int *phy_init_seq; | 112 | int *phy_init_seq; |
113 | int phy_init_sz; | ||
131 | void (*vbus_power)(bool on); | 114 | void (*vbus_power)(bool on); |
132 | unsigned power_budget; | 115 | unsigned power_budget; |
133 | enum usb_mode_type mode; | 116 | enum usb_dr_mode mode; |
134 | enum otg_control_type otg_control; | 117 | enum otg_control_type otg_control; |
135 | enum usb_mode_type default_mode; | ||
136 | enum msm_usb_phy_type phy_type; | 118 | enum msm_usb_phy_type phy_type; |
137 | void (*setup_gpio)(enum usb_otg_state state); | 119 | void (*setup_gpio)(enum usb_otg_state state); |
138 | char *pclk_src_name; | ||
139 | int (*link_clk_reset)(struct clk *link_clk, bool assert); | 120 | int (*link_clk_reset)(struct clk *link_clk, bool assert); |
140 | int (*phy_clk_reset)(struct clk *phy_clk); | 121 | int (*phy_clk_reset)(struct clk *phy_clk); |
141 | }; | 122 | }; |
@@ -147,7 +128,6 @@ struct msm_otg_platform_data { | |||
147 | * @irq: IRQ number assigned for HSUSB controller. | 128 | * @irq: IRQ number assigned for HSUSB controller. |
148 | * @clk: clock struct of usb_hs_clk. | 129 | * @clk: clock struct of usb_hs_clk. |
149 | * @pclk: clock struct of usb_hs_pclk. | 130 | * @pclk: clock struct of usb_hs_pclk. |
150 | * @pclk_src: pclk source for voting. | ||
151 | * @phy_reset_clk: clock struct of usb_phy_clk. | 131 | * @phy_reset_clk: clock struct of usb_phy_clk. |
152 | * @core_clk: clock struct of usb_hs_core_clk. | 132 | * @core_clk: clock struct of usb_hs_core_clk. |
153 | * @regs: ioremapped register base address. | 133 | * @regs: ioremapped register base address. |
@@ -168,7 +148,6 @@ struct msm_otg { | |||
168 | int irq; | 148 | int irq; |
169 | struct clk *clk; | 149 | struct clk *clk; |
170 | struct clk *pclk; | 150 | struct clk *pclk; |
171 | struct clk *pclk_src; | ||
172 | struct clk *phy_reset_clk; | 151 | struct clk *phy_reset_clk; |
173 | struct clk *core_clk; | 152 | struct clk *core_clk; |
174 | void __iomem *regs; | 153 | void __iomem *regs; |
@@ -179,10 +158,18 @@ struct msm_otg { | |||
179 | atomic_t in_lpm; | 158 | atomic_t in_lpm; |
180 | int async_int; | 159 | int async_int; |
181 | unsigned cur_power; | 160 | unsigned cur_power; |
161 | int phy_number; | ||
182 | struct delayed_work chg_work; | 162 | struct delayed_work chg_work; |
183 | enum usb_chg_state chg_state; | 163 | enum usb_chg_state chg_state; |
184 | enum usb_chg_type chg_type; | 164 | enum usb_chg_type chg_type; |
185 | u8 dcd_retries; | 165 | u8 dcd_retries; |
166 | struct regulator *v3p3; | ||
167 | struct regulator *v1p8; | ||
168 | struct regulator *vddcx; | ||
169 | |||
170 | struct reset_control *phy_rst; | ||
171 | struct reset_control *link_rst; | ||
172 | int vdd_levels[3]; | ||
186 | }; | 173 | }; |
187 | 174 | ||
188 | #endif | 175 | #endif |
diff --git a/include/linux/usb/msm_hsusb_hw.h b/include/linux/usb/msm_hsusb_hw.h index 6e97a2d3d39f..a29f6030afb1 100644 --- a/include/linux/usb/msm_hsusb_hw.h +++ b/include/linux/usb/msm_hsusb_hw.h | |||
@@ -16,6 +16,9 @@ | |||
16 | #ifndef __LINUX_USB_GADGET_MSM72K_UDC_H__ | 16 | #ifndef __LINUX_USB_GADGET_MSM72K_UDC_H__ |
17 | #define __LINUX_USB_GADGET_MSM72K_UDC_H__ | 17 | #define __LINUX_USB_GADGET_MSM72K_UDC_H__ |
18 | 18 | ||
19 | /* USB phy selector - in TCSR address range */ | ||
20 | #define USB2_PHY_SEL 0xfd4ab000 | ||
21 | |||
19 | #define USB_AHBBURST (MSM_USB_BASE + 0x0090) | 22 | #define USB_AHBBURST (MSM_USB_BASE + 0x0090) |
20 | #define USB_AHBMODE (MSM_USB_BASE + 0x0098) | 23 | #define USB_AHBMODE (MSM_USB_BASE + 0x0098) |
21 | #define USB_CAPLENGTH (MSM_USB_BASE + 0x0100) /* 8 bit */ | 24 | #define USB_CAPLENGTH (MSM_USB_BASE + 0x0100) /* 8 bit */ |
@@ -25,13 +28,15 @@ | |||
25 | #define USB_OTGSC (MSM_USB_BASE + 0x01A4) | 28 | #define USB_OTGSC (MSM_USB_BASE + 0x01A4) |
26 | #define USB_USBMODE (MSM_USB_BASE + 0x01A8) | 29 | #define USB_USBMODE (MSM_USB_BASE + 0x01A8) |
27 | #define USB_PHY_CTRL (MSM_USB_BASE + 0x0240) | 30 | #define USB_PHY_CTRL (MSM_USB_BASE + 0x0240) |
31 | #define USB_PHY_CTRL2 (MSM_USB_BASE + 0x0278) | ||
28 | 32 | ||
29 | #define USBCMD_RESET 2 | 33 | #define USBCMD_RESET 2 |
30 | #define USB_USBINTR (MSM_USB_BASE + 0x0148) | 34 | #define USB_USBINTR (MSM_USB_BASE + 0x0148) |
31 | 35 | ||
32 | #define PORTSC_PHCD (1 << 23) /* phy suspend mode */ | 36 | #define PORTSC_PHCD (1 << 23) /* phy suspend mode */ |
33 | #define PORTSC_PTS_MASK (3 << 30) | 37 | #define PORTSC_PTS_MASK (3 << 30) |
34 | #define PORTSC_PTS_ULPI (3 << 30) | 38 | #define PORTSC_PTS_ULPI (2 << 30) |
39 | #define PORTSC_PTS_SERIAL (3 << 30) | ||
35 | 40 | ||
36 | #define USB_ULPI_VIEWPORT (MSM_USB_BASE + 0x0170) | 41 | #define USB_ULPI_VIEWPORT (MSM_USB_BASE + 0x0170) |
37 | #define ULPI_RUN (1 << 30) | 42 | #define ULPI_RUN (1 << 30) |
@@ -41,9 +46,14 @@ | |||
41 | #define ULPI_DATA(n) ((n) & 255) | 46 | #define ULPI_DATA(n) ((n) & 255) |
42 | #define ULPI_DATA_READ(n) (((n) >> 8) & 255) | 47 | #define ULPI_DATA_READ(n) (((n) >> 8) & 255) |
43 | 48 | ||
49 | /* synopsys 28nm phy registers */ | ||
50 | #define ULPI_PWR_CLK_MNG_REG 0x88 | ||
51 | #define OTG_COMP_DISABLE BIT(0) | ||
52 | |||
44 | #define ASYNC_INTR_CTRL (1 << 29) /* Enable async interrupt */ | 53 | #define ASYNC_INTR_CTRL (1 << 29) /* Enable async interrupt */ |
45 | #define ULPI_STP_CTRL (1 << 30) /* Block communication with PHY */ | 54 | #define ULPI_STP_CTRL (1 << 30) /* Block communication with PHY */ |
46 | #define PHY_RETEN (1 << 1) /* PHY retention enable/disable */ | 55 | #define PHY_RETEN (1 << 1) /* PHY retention enable/disable */ |
56 | #define PHY_POR_ASSERT (1 << 0) /* USB2 28nm PHY POR ASSERT */ | ||
47 | 57 | ||
48 | /* OTG definitions */ | 58 | /* OTG definitions */ |
49 | #define OTGSC_INTSTS_MASK (0x7f << 16) | 59 | #define OTGSC_INTSTS_MASK (0x7f << 16) |
diff --git a/include/linux/usb/usb_phy_gen_xceiv.h b/include/linux/usb/usb_phy_generic.h index cc8d818a83be..68adae83affc 100644 --- a/include/linux/usb/usb_phy_gen_xceiv.h +++ b/include/linux/usb/usb_phy_generic.h | |||
@@ -3,7 +3,7 @@ | |||
3 | 3 | ||
4 | #include <linux/usb/otg.h> | 4 | #include <linux/usb/otg.h> |
5 | 5 | ||
6 | struct usb_phy_gen_xceiv_platform_data { | 6 | struct usb_phy_generic_platform_data { |
7 | enum usb_phy_type type; | 7 | enum usb_phy_type type; |
8 | unsigned long clk_rate; | 8 | unsigned long clk_rate; |
9 | 9 | ||
@@ -13,16 +13,17 @@ struct usb_phy_gen_xceiv_platform_data { | |||
13 | int gpio_reset; | 13 | int gpio_reset; |
14 | }; | 14 | }; |
15 | 15 | ||
16 | #if defined(CONFIG_NOP_USB_XCEIV) || (defined(CONFIG_NOP_USB_XCEIV_MODULE) && defined(MODULE)) | 16 | #if IS_ENABLED(CONFIG_NOP_USB_XCEIV) |
17 | /* sometimes transceivers are accessed only through e.g. ULPI */ | 17 | /* sometimes transceivers are accessed only through e.g. ULPI */ |
18 | extern void usb_nop_xceiv_register(void); | 18 | extern struct platform_device *usb_phy_generic_register(void); |
19 | extern void usb_nop_xceiv_unregister(void); | 19 | extern void usb_phy_generic_unregister(struct platform_device *); |
20 | #else | 20 | #else |
21 | static inline void usb_nop_xceiv_register(void) | 21 | static inline struct platform_device *usb_phy_generic_register(void) |
22 | { | 22 | { |
23 | return NULL; | ||
23 | } | 24 | } |
24 | 25 | ||
25 | static inline void usb_nop_xceiv_unregister(void) | 26 | static inline void usb_phy_generic_unregister(struct platform_device *pdev) |
26 | { | 27 | { |
27 | } | 28 | } |
28 | #endif | 29 | #endif |
diff --git a/tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c b/tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c new file mode 100644 index 000000000000..87216a0c4a8b --- /dev/null +++ b/tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c | |||
@@ -0,0 +1,349 @@ | |||
1 | #define _BSD_SOURCE /* for endian.h */ | ||
2 | |||
3 | #include <endian.h> | ||
4 | #include <errno.h> | ||
5 | #include <fcntl.h> | ||
6 | #include <stdarg.h> | ||
7 | #include <stdio.h> | ||
8 | #include <stdlib.h> | ||
9 | #include <string.h> | ||
10 | #include <sys/ioctl.h> | ||
11 | #include <sys/stat.h> | ||
12 | #include <sys/types.h> | ||
13 | #include <sys/poll.h> | ||
14 | #include <unistd.h> | ||
15 | #include <stdbool.h> | ||
16 | #include <sys/eventfd.h> | ||
17 | |||
18 | #include "libaio.h" | ||
19 | #define IOCB_FLAG_RESFD (1 << 0) | ||
20 | |||
21 | #include <linux/usb/functionfs.h> | ||
22 | |||
23 | #define BUF_LEN 8192 | ||
24 | #define BUFS_MAX 128 | ||
25 | #define AIO_MAX (BUFS_MAX*2) | ||
26 | |||
27 | /******************** Descriptors and Strings *******************************/ | ||
28 | |||
29 | static const struct { | ||
30 | struct usb_functionfs_descs_head header; | ||
31 | struct { | ||
32 | struct usb_interface_descriptor intf; | ||
33 | struct usb_endpoint_descriptor_no_audio bulk_sink; | ||
34 | struct usb_endpoint_descriptor_no_audio bulk_source; | ||
35 | } __attribute__ ((__packed__)) fs_descs, hs_descs; | ||
36 | } __attribute__ ((__packed__)) descriptors = { | ||
37 | .header = { | ||
38 | .magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC), | ||
39 | .length = htole32(sizeof(descriptors)), | ||
40 | .fs_count = 3, | ||
41 | .hs_count = 3, | ||
42 | }, | ||
43 | .fs_descs = { | ||
44 | .intf = { | ||
45 | .bLength = sizeof(descriptors.fs_descs.intf), | ||
46 | .bDescriptorType = USB_DT_INTERFACE, | ||
47 | .bNumEndpoints = 2, | ||
48 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, | ||
49 | .iInterface = 1, | ||
50 | }, | ||
51 | .bulk_sink = { | ||
52 | .bLength = sizeof(descriptors.fs_descs.bulk_sink), | ||
53 | .bDescriptorType = USB_DT_ENDPOINT, | ||
54 | .bEndpointAddress = 1 | USB_DIR_IN, | ||
55 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
56 | }, | ||
57 | .bulk_source = { | ||
58 | .bLength = sizeof(descriptors.fs_descs.bulk_source), | ||
59 | .bDescriptorType = USB_DT_ENDPOINT, | ||
60 | .bEndpointAddress = 2 | USB_DIR_OUT, | ||
61 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
62 | }, | ||
63 | }, | ||
64 | .hs_descs = { | ||
65 | .intf = { | ||
66 | .bLength = sizeof(descriptors.hs_descs.intf), | ||
67 | .bDescriptorType = USB_DT_INTERFACE, | ||
68 | .bNumEndpoints = 2, | ||
69 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, | ||
70 | .iInterface = 1, | ||
71 | }, | ||
72 | .bulk_sink = { | ||
73 | .bLength = sizeof(descriptors.hs_descs.bulk_sink), | ||
74 | .bDescriptorType = USB_DT_ENDPOINT, | ||
75 | .bEndpointAddress = 1 | USB_DIR_IN, | ||
76 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
77 | .wMaxPacketSize = htole16(512), | ||
78 | }, | ||
79 | .bulk_source = { | ||
80 | .bLength = sizeof(descriptors.hs_descs.bulk_source), | ||
81 | .bDescriptorType = USB_DT_ENDPOINT, | ||
82 | .bEndpointAddress = 2 | USB_DIR_OUT, | ||
83 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
84 | .wMaxPacketSize = htole16(512), | ||
85 | }, | ||
86 | }, | ||
87 | }; | ||
88 | |||
89 | #define STR_INTERFACE "AIO Test" | ||
90 | |||
91 | static const struct { | ||
92 | struct usb_functionfs_strings_head header; | ||
93 | struct { | ||
94 | __le16 code; | ||
95 | const char str1[sizeof(STR_INTERFACE)]; | ||
96 | } __attribute__ ((__packed__)) lang0; | ||
97 | } __attribute__ ((__packed__)) strings = { | ||
98 | .header = { | ||
99 | .magic = htole32(FUNCTIONFS_STRINGS_MAGIC), | ||
100 | .length = htole32(sizeof(strings)), | ||
101 | .str_count = htole32(1), | ||
102 | .lang_count = htole32(1), | ||
103 | }, | ||
104 | .lang0 = { | ||
105 | htole16(0x0409), /* en-us */ | ||
106 | STR_INTERFACE, | ||
107 | }, | ||
108 | }; | ||
109 | |||
110 | /********************** Buffer structure *******************************/ | ||
111 | |||
112 | struct io_buffer { | ||
113 | struct iocb **iocb; | ||
114 | unsigned char **buf; | ||
115 | unsigned cnt; | ||
116 | unsigned len; | ||
117 | unsigned requested; | ||
118 | }; | ||
119 | |||
120 | /******************** Endpoints handling *******************************/ | ||
121 | |||
122 | static void display_event(struct usb_functionfs_event *event) | ||
123 | { | ||
124 | static const char *const names[] = { | ||
125 | [FUNCTIONFS_BIND] = "BIND", | ||
126 | [FUNCTIONFS_UNBIND] = "UNBIND", | ||
127 | [FUNCTIONFS_ENABLE] = "ENABLE", | ||
128 | [FUNCTIONFS_DISABLE] = "DISABLE", | ||
129 | [FUNCTIONFS_SETUP] = "SETUP", | ||
130 | [FUNCTIONFS_SUSPEND] = "SUSPEND", | ||
131 | [FUNCTIONFS_RESUME] = "RESUME", | ||
132 | }; | ||
133 | switch (event->type) { | ||
134 | case FUNCTIONFS_BIND: | ||
135 | case FUNCTIONFS_UNBIND: | ||
136 | case FUNCTIONFS_ENABLE: | ||
137 | case FUNCTIONFS_DISABLE: | ||
138 | case FUNCTIONFS_SETUP: | ||
139 | case FUNCTIONFS_SUSPEND: | ||
140 | case FUNCTIONFS_RESUME: | ||
141 | printf("Event %s\n", names[event->type]); | ||
142 | } | ||
143 | } | ||
144 | |||
145 | static void handle_ep0(int ep0, bool *ready) | ||
146 | { | ||
147 | int ret; | ||
148 | struct usb_functionfs_event event; | ||
149 | |||
150 | ret = read(ep0, &event, sizeof(event)); | ||
151 | if (!ret) { | ||
152 | perror("unable to read event from ep0"); | ||
153 | return; | ||
154 | } | ||
155 | display_event(&event); | ||
156 | switch (event.type) { | ||
157 | case FUNCTIONFS_SETUP: | ||
158 | if (event.u.setup.bRequestType & USB_DIR_IN) | ||
159 | write(ep0, NULL, 0); | ||
160 | else | ||
161 | read(ep0, NULL, 0); | ||
162 | break; | ||
163 | |||
164 | case FUNCTIONFS_ENABLE: | ||
165 | *ready = true; | ||
166 | break; | ||
167 | |||
168 | case FUNCTIONFS_DISABLE: | ||
169 | *ready = false; | ||
170 | break; | ||
171 | |||
172 | default: | ||
173 | break; | ||
174 | } | ||
175 | } | ||
176 | |||
177 | void init_bufs(struct io_buffer *iobuf, unsigned n, unsigned len) | ||
178 | { | ||
179 | unsigned i; | ||
180 | iobuf->buf = malloc(n*sizeof(*iobuf->buf)); | ||
181 | iobuf->iocb = malloc(n*sizeof(*iobuf->iocb)); | ||
182 | iobuf->cnt = n; | ||
183 | iobuf->len = len; | ||
184 | iobuf->requested = 0; | ||
185 | for (i = 0; i < n; ++i) { | ||
186 | iobuf->buf[i] = malloc(len*sizeof(**iobuf->buf)); | ||
187 | iobuf->iocb[i] = malloc(sizeof(**iobuf->iocb)); | ||
188 | } | ||
189 | iobuf->cnt = n; | ||
190 | } | ||
191 | |||
192 | void delete_bufs(struct io_buffer *iobuf) | ||
193 | { | ||
194 | unsigned i; | ||
195 | for (i = 0; i < iobuf->cnt; ++i) { | ||
196 | free(iobuf->buf[i]); | ||
197 | free(iobuf->iocb[i]); | ||
198 | } | ||
199 | free(iobuf->buf); | ||
200 | free(iobuf->iocb); | ||
201 | } | ||
202 | |||
203 | int main(int argc, char *argv[]) | ||
204 | { | ||
205 | int ret; | ||
206 | unsigned i, j; | ||
207 | char *ep_path; | ||
208 | |||
209 | int ep0, ep1; | ||
210 | |||
211 | io_context_t ctx; | ||
212 | |||
213 | int evfd; | ||
214 | fd_set rfds; | ||
215 | |||
216 | struct io_buffer iobuf[2]; | ||
217 | int actual = 0; | ||
218 | bool ready; | ||
219 | |||
220 | if (argc != 2) { | ||
221 | printf("ffs directory not specified!\n"); | ||
222 | return 1; | ||
223 | } | ||
224 | |||
225 | ep_path = malloc(strlen(argv[1]) + 4 /* "/ep#" */ + 1 /* '\0' */); | ||
226 | if (!ep_path) { | ||
227 | perror("malloc"); | ||
228 | return 1; | ||
229 | } | ||
230 | |||
231 | /* open endpoint files */ | ||
232 | sprintf(ep_path, "%s/ep0", argv[1]); | ||
233 | ep0 = open(ep_path, O_RDWR); | ||
234 | if (ep0 < 0) { | ||
235 | perror("unable to open ep0"); | ||
236 | return 1; | ||
237 | } | ||
238 | if (write(ep0, &descriptors, sizeof(descriptors)) < 0) { | ||
239 | perror("unable do write descriptors"); | ||
240 | return 1; | ||
241 | } | ||
242 | if (write(ep0, &strings, sizeof(strings)) < 0) { | ||
243 | perror("unable to write strings"); | ||
244 | return 1; | ||
245 | } | ||
246 | sprintf(ep_path, "%s/ep1", argv[1]); | ||
247 | ep1 = open(ep_path, O_RDWR); | ||
248 | if (ep1 < 0) { | ||
249 | perror("unable to open ep1"); | ||
250 | return 1; | ||
251 | } | ||
252 | |||
253 | free(ep_path); | ||
254 | |||
255 | memset(&ctx, 0, sizeof(ctx)); | ||
256 | /* setup aio context to handle up to AIO_MAX requests */ | ||
257 | if (io_setup(AIO_MAX, &ctx) < 0) { | ||
258 | perror("unable to setup aio"); | ||
259 | return 1; | ||
260 | } | ||
261 | |||
262 | evfd = eventfd(0, 0); | ||
263 | if (evfd < 0) { | ||
264 | perror("unable to open eventfd"); | ||
265 | return 1; | ||
266 | } | ||
267 | |||
268 | for (i = 0; i < sizeof(iobuf)/sizeof(*iobuf); ++i) | ||
269 | init_bufs(&iobuf[i], BUFS_MAX, BUF_LEN); | ||
270 | |||
271 | while (1) { | ||
272 | FD_ZERO(&rfds); | ||
273 | FD_SET(ep0, &rfds); | ||
274 | FD_SET(evfd, &rfds); | ||
275 | |||
276 | ret = select(((ep0 > evfd) ? ep0 : evfd)+1, | ||
277 | &rfds, NULL, NULL, NULL); | ||
278 | if (ret < 0) { | ||
279 | if (errno == EINTR) | ||
280 | continue; | ||
281 | perror("select"); | ||
282 | break; | ||
283 | } | ||
284 | |||
285 | if (FD_ISSET(ep0, &rfds)) | ||
286 | handle_ep0(ep0, &ready); | ||
287 | |||
288 | /* we are waiting for function ENABLE */ | ||
289 | if (!ready) | ||
290 | continue; | ||
291 | |||
292 | /* | ||
293 | * when we're preparing new data to submit, | ||
294 | * second buffer being transmitted | ||
295 | */ | ||
296 | for (i = 0; i < sizeof(iobuf)/sizeof(*iobuf); ++i) { | ||
297 | if (iobuf[i].requested) | ||
298 | continue; | ||
299 | /* prepare requests */ | ||
300 | for (j = 0; j < iobuf[i].cnt; ++j) { | ||
301 | io_prep_pwrite(iobuf[i].iocb[j], ep1, | ||
302 | iobuf[i].buf[j], | ||
303 | iobuf[i].len, 0); | ||
304 | /* enable eventfd notification */ | ||
305 | iobuf[i].iocb[j]->u.c.flags |= IOCB_FLAG_RESFD; | ||
306 | iobuf[i].iocb[j]->u.c.resfd = evfd; | ||
307 | } | ||
308 | /* submit table of requests */ | ||
309 | ret = io_submit(ctx, iobuf[i].cnt, iobuf[i].iocb); | ||
310 | if (ret >= 0) { | ||
311 | iobuf[i].requested = ret; | ||
312 | printf("submit: %d requests buf: %d\n", ret, i); | ||
313 | } else | ||
314 | perror("unable to submit reqests"); | ||
315 | } | ||
316 | |||
317 | /* if event is ready to read */ | ||
318 | if (!FD_ISSET(evfd, &rfds)) | ||
319 | continue; | ||
320 | |||
321 | uint64_t ev_cnt; | ||
322 | ret = read(evfd, &ev_cnt, sizeof(ev_cnt)); | ||
323 | if (ret < 0) { | ||
324 | perror("unable to read eventfd"); | ||
325 | break; | ||
326 | } | ||
327 | |||
328 | struct io_event e[BUFS_MAX]; | ||
329 | /* we read aio events */ | ||
330 | ret = io_getevents(ctx, 1, BUFS_MAX, e, NULL); | ||
331 | if (ret > 0) /* if we got events */ | ||
332 | iobuf[actual].requested -= ret; | ||
333 | |||
334 | /* if all req's from iocb completed */ | ||
335 | if (!iobuf[actual].requested) | ||
336 | actual = (actual + 1)%(sizeof(iobuf)/sizeof(*iobuf)); | ||
337 | } | ||
338 | |||
339 | /* free resources */ | ||
340 | |||
341 | for (i = 0; i < sizeof(iobuf)/sizeof(*iobuf); ++i) | ||
342 | delete_bufs(&iobuf[i]); | ||
343 | io_destroy(ctx); | ||
344 | |||
345 | close(ep1); | ||
346 | close(ep0); | ||
347 | |||
348 | return 0; | ||
349 | } | ||
diff --git a/tools/usb/ffs-aio-example/multibuff/host_app/Makefile b/tools/usb/ffs-aio-example/multibuff/host_app/Makefile new file mode 100644 index 000000000000..8c4a6f0aa82d --- /dev/null +++ b/tools/usb/ffs-aio-example/multibuff/host_app/Makefile | |||
@@ -0,0 +1,13 @@ | |||
1 | CC = gcc | ||
2 | LIBUSB_CFLAGS = $(shell pkg-config --cflags libusb-1.0) | ||
3 | LIBUSB_LIBS = $(shell pkg-config --libs libusb-1.0) | ||
4 | WARNINGS = -Wall -Wextra | ||
5 | CFLAGS = $(LIBUSB_CFLAGS) $(WARNINGS) | ||
6 | LDFLAGS = $(LIBUSB_LIBS) | ||
7 | |||
8 | all: test | ||
9 | %: %.c | ||
10 | $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) | ||
11 | |||
12 | clean: | ||
13 | $(RM) test | ||
diff --git a/tools/usb/ffs-aio-example/multibuff/host_app/test.c b/tools/usb/ffs-aio-example/multibuff/host_app/test.c new file mode 100644 index 000000000000..b0ad8747d03f --- /dev/null +++ b/tools/usb/ffs-aio-example/multibuff/host_app/test.c | |||
@@ -0,0 +1,146 @@ | |||
1 | #include <libusb.h> | ||
2 | #include <stdio.h> | ||
3 | #include <string.h> | ||
4 | #include <unistd.h> | ||
5 | |||
6 | #define VENDOR 0x1d6b | ||
7 | #define PRODUCT 0x0105 | ||
8 | |||
9 | /* endpoints indexes */ | ||
10 | |||
11 | #define EP_BULK_IN (1 | LIBUSB_ENDPOINT_IN) | ||
12 | #define EP_BULK_OUT (2 | LIBUSB_ENDPOINT_OUT) | ||
13 | |||
14 | #define BUF_LEN 8192 | ||
15 | |||
16 | /* | ||
17 | * struct test_state - describes test program state | ||
18 | * @list: list of devices returned by libusb_get_device_list function | ||
19 | * @found: pointer to struct describing tested device | ||
20 | * @ctx: context, set to NULL | ||
21 | * @handle: handle of tested device | ||
22 | * @attached: indicates that device was attached to kernel, and has to be | ||
23 | * reattached at the end of test program | ||
24 | */ | ||
25 | |||
26 | struct test_state { | ||
27 | libusb_device *found; | ||
28 | libusb_context *ctx; | ||
29 | libusb_device_handle *handle; | ||
30 | int attached; | ||
31 | }; | ||
32 | |||
33 | /* | ||
34 | * test_init - initialize test program | ||
35 | */ | ||
36 | |||
37 | int test_init(struct test_state *state) | ||
38 | { | ||
39 | int i, ret; | ||
40 | ssize_t cnt; | ||
41 | libusb_device **list; | ||
42 | |||
43 | state->found = NULL; | ||
44 | state->ctx = NULL; | ||
45 | state->handle = NULL; | ||
46 | state->attached = 0; | ||
47 | |||
48 | ret = libusb_init(&state->ctx); | ||
49 | if (ret) { | ||
50 | printf("cannot init libusb: %s\n", libusb_error_name(ret)); | ||
51 | return 1; | ||
52 | } | ||
53 | |||
54 | cnt = libusb_get_device_list(state->ctx, &list); | ||
55 | if (cnt <= 0) { | ||
56 | printf("no devices found\n"); | ||
57 | goto error1; | ||
58 | } | ||
59 | |||
60 | for (i = 0; i < cnt; ++i) { | ||
61 | libusb_device *dev = list[i]; | ||
62 | struct libusb_device_descriptor desc; | ||
63 | ret = libusb_get_device_descriptor(dev, &desc); | ||
64 | if (ret) { | ||
65 | printf("unable to get device descriptor: %s\n", | ||
66 | libusb_error_name(ret)); | ||
67 | goto error2; | ||
68 | } | ||
69 | if (desc.idVendor == VENDOR && desc.idProduct == PRODUCT) { | ||
70 | state->found = dev; | ||
71 | break; | ||
72 | } | ||
73 | } | ||
74 | |||
75 | if (!state->found) { | ||
76 | printf("no devices found\n"); | ||
77 | goto error2; | ||
78 | } | ||
79 | |||
80 | ret = libusb_open(state->found, &state->handle); | ||
81 | if (ret) { | ||
82 | printf("cannot open device: %s\n", libusb_error_name(ret)); | ||
83 | goto error2; | ||
84 | } | ||
85 | |||
86 | if (libusb_claim_interface(state->handle, 0)) { | ||
87 | ret = libusb_detach_kernel_driver(state->handle, 0); | ||
88 | if (ret) { | ||
89 | printf("unable to detach kernel driver: %s\n", | ||
90 | libusb_error_name(ret)); | ||
91 | goto error3; | ||
92 | } | ||
93 | state->attached = 1; | ||
94 | ret = libusb_claim_interface(state->handle, 0); | ||
95 | if (ret) { | ||
96 | printf("cannot claim interface: %s\n", | ||
97 | libusb_error_name(ret)); | ||
98 | goto error4; | ||
99 | } | ||
100 | } | ||
101 | |||
102 | return 0; | ||
103 | |||
104 | error4: | ||
105 | if (state->attached == 1) | ||
106 | libusb_attach_kernel_driver(state->handle, 0); | ||
107 | |||
108 | error3: | ||
109 | libusb_close(state->handle); | ||
110 | |||
111 | error2: | ||
112 | libusb_free_device_list(list, 1); | ||
113 | |||
114 | error1: | ||
115 | libusb_exit(state->ctx); | ||
116 | return 1; | ||
117 | } | ||
118 | |||
119 | /* | ||
120 | * test_exit - cleanup test program | ||
121 | */ | ||
122 | |||
123 | void test_exit(struct test_state *state) | ||
124 | { | ||
125 | libusb_release_interface(state->handle, 0); | ||
126 | if (state->attached == 1) | ||
127 | libusb_attach_kernel_driver(state->handle, 0); | ||
128 | libusb_close(state->handle); | ||
129 | libusb_exit(state->ctx); | ||
130 | } | ||
131 | |||
132 | int main(void) | ||
133 | { | ||
134 | struct test_state state; | ||
135 | |||
136 | if (test_init(&state)) | ||
137 | return 1; | ||
138 | |||
139 | while (1) { | ||
140 | static unsigned char buffer[BUF_LEN]; | ||
141 | int bytes; | ||
142 | libusb_bulk_transfer(state.handle, EP_BULK_IN, buffer, BUF_LEN, | ||
143 | &bytes, 500); | ||
144 | } | ||
145 | test_exit(&state); | ||
146 | } | ||
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 new file mode 100644 index 000000000000..f558664a3317 --- /dev/null +++ b/tools/usb/ffs-aio-example/simple/device_app/aio_simple.c | |||
@@ -0,0 +1,335 @@ | |||
1 | #define _BSD_SOURCE /* for endian.h */ | ||
2 | |||
3 | #include <endian.h> | ||
4 | #include <errno.h> | ||
5 | #include <fcntl.h> | ||
6 | #include <stdarg.h> | ||
7 | #include <stdio.h> | ||
8 | #include <stdlib.h> | ||
9 | #include <string.h> | ||
10 | #include <sys/ioctl.h> | ||
11 | #include <sys/stat.h> | ||
12 | #include <sys/types.h> | ||
13 | #include <sys/poll.h> | ||
14 | #include <unistd.h> | ||
15 | #include <stdbool.h> | ||
16 | #include <sys/eventfd.h> | ||
17 | |||
18 | #include "libaio.h" | ||
19 | #define IOCB_FLAG_RESFD (1 << 0) | ||
20 | |||
21 | #include <linux/usb/functionfs.h> | ||
22 | |||
23 | #define BUF_LEN 8192 | ||
24 | |||
25 | /******************** Descriptors and Strings *******************************/ | ||
26 | |||
27 | static const struct { | ||
28 | struct usb_functionfs_descs_head header; | ||
29 | struct { | ||
30 | struct usb_interface_descriptor intf; | ||
31 | struct usb_endpoint_descriptor_no_audio bulk_sink; | ||
32 | struct usb_endpoint_descriptor_no_audio bulk_source; | ||
33 | } __attribute__ ((__packed__)) fs_descs, hs_descs; | ||
34 | } __attribute__ ((__packed__)) descriptors = { | ||
35 | .header = { | ||
36 | .magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC), | ||
37 | .length = htole32(sizeof(descriptors)), | ||
38 | .fs_count = 3, | ||
39 | .hs_count = 3, | ||
40 | }, | ||
41 | .fs_descs = { | ||
42 | .intf = { | ||
43 | .bLength = sizeof(descriptors.fs_descs.intf), | ||
44 | .bDescriptorType = USB_DT_INTERFACE, | ||
45 | .bNumEndpoints = 2, | ||
46 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, | ||
47 | .iInterface = 1, | ||
48 | }, | ||
49 | .bulk_sink = { | ||
50 | .bLength = sizeof(descriptors.fs_descs.bulk_sink), | ||
51 | .bDescriptorType = USB_DT_ENDPOINT, | ||
52 | .bEndpointAddress = 1 | USB_DIR_IN, | ||
53 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
54 | }, | ||
55 | .bulk_source = { | ||
56 | .bLength = sizeof(descriptors.fs_descs.bulk_source), | ||
57 | .bDescriptorType = USB_DT_ENDPOINT, | ||
58 | .bEndpointAddress = 2 | USB_DIR_OUT, | ||
59 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
60 | }, | ||
61 | }, | ||
62 | .hs_descs = { | ||
63 | .intf = { | ||
64 | .bLength = sizeof(descriptors.hs_descs.intf), | ||
65 | .bDescriptorType = USB_DT_INTERFACE, | ||
66 | .bNumEndpoints = 2, | ||
67 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, | ||
68 | .iInterface = 1, | ||
69 | }, | ||
70 | .bulk_sink = { | ||
71 | .bLength = sizeof(descriptors.hs_descs.bulk_sink), | ||
72 | .bDescriptorType = USB_DT_ENDPOINT, | ||
73 | .bEndpointAddress = 1 | USB_DIR_IN, | ||
74 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
75 | }, | ||
76 | .bulk_source = { | ||
77 | .bLength = sizeof(descriptors.hs_descs.bulk_source), | ||
78 | .bDescriptorType = USB_DT_ENDPOINT, | ||
79 | .bEndpointAddress = 2 | USB_DIR_OUT, | ||
80 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
81 | }, | ||
82 | }, | ||
83 | }; | ||
84 | |||
85 | #define STR_INTERFACE "AIO Test" | ||
86 | |||
87 | static const struct { | ||
88 | struct usb_functionfs_strings_head header; | ||
89 | struct { | ||
90 | __le16 code; | ||
91 | const char str1[sizeof(STR_INTERFACE)]; | ||
92 | } __attribute__ ((__packed__)) lang0; | ||
93 | } __attribute__ ((__packed__)) strings = { | ||
94 | .header = { | ||
95 | .magic = htole32(FUNCTIONFS_STRINGS_MAGIC), | ||
96 | .length = htole32(sizeof(strings)), | ||
97 | .str_count = htole32(1), | ||
98 | .lang_count = htole32(1), | ||
99 | }, | ||
100 | .lang0 = { | ||
101 | htole16(0x0409), /* en-us */ | ||
102 | STR_INTERFACE, | ||
103 | }, | ||
104 | }; | ||
105 | |||
106 | /******************** Endpoints handling *******************************/ | ||
107 | |||
108 | static void display_event(struct usb_functionfs_event *event) | ||
109 | { | ||
110 | static const char *const names[] = { | ||
111 | [FUNCTIONFS_BIND] = "BIND", | ||
112 | [FUNCTIONFS_UNBIND] = "UNBIND", | ||
113 | [FUNCTIONFS_ENABLE] = "ENABLE", | ||
114 | [FUNCTIONFS_DISABLE] = "DISABLE", | ||
115 | [FUNCTIONFS_SETUP] = "SETUP", | ||
116 | [FUNCTIONFS_SUSPEND] = "SUSPEND", | ||
117 | [FUNCTIONFS_RESUME] = "RESUME", | ||
118 | }; | ||
119 | switch (event->type) { | ||
120 | case FUNCTIONFS_BIND: | ||
121 | case FUNCTIONFS_UNBIND: | ||
122 | case FUNCTIONFS_ENABLE: | ||
123 | case FUNCTIONFS_DISABLE: | ||
124 | case FUNCTIONFS_SETUP: | ||
125 | case FUNCTIONFS_SUSPEND: | ||
126 | case FUNCTIONFS_RESUME: | ||
127 | printf("Event %s\n", names[event->type]); | ||
128 | } | ||
129 | } | ||
130 | |||
131 | static void handle_ep0(int ep0, bool *ready) | ||
132 | { | ||
133 | struct usb_functionfs_event event; | ||
134 | int ret; | ||
135 | |||
136 | struct pollfd pfds[1]; | ||
137 | pfds[0].fd = ep0; | ||
138 | pfds[0].events = POLLIN; | ||
139 | |||
140 | ret = poll(pfds, 1, 0); | ||
141 | |||
142 | if (ret && (pfds[0].revents & POLLIN)) { | ||
143 | ret = read(ep0, &event, sizeof(event)); | ||
144 | if (!ret) { | ||
145 | perror("unable to read event from ep0"); | ||
146 | return; | ||
147 | } | ||
148 | display_event(&event); | ||
149 | switch (event.type) { | ||
150 | case FUNCTIONFS_SETUP: | ||
151 | if (event.u.setup.bRequestType & USB_DIR_IN) | ||
152 | write(ep0, NULL, 0); | ||
153 | else | ||
154 | read(ep0, NULL, 0); | ||
155 | break; | ||
156 | |||
157 | case FUNCTIONFS_ENABLE: | ||
158 | *ready = true; | ||
159 | break; | ||
160 | |||
161 | case FUNCTIONFS_DISABLE: | ||
162 | *ready = false; | ||
163 | break; | ||
164 | |||
165 | default: | ||
166 | break; | ||
167 | } | ||
168 | } | ||
169 | } | ||
170 | |||
171 | int main(int argc, char *argv[]) | ||
172 | { | ||
173 | int i, ret; | ||
174 | char *ep_path; | ||
175 | |||
176 | int ep0; | ||
177 | int ep[2]; | ||
178 | |||
179 | io_context_t ctx; | ||
180 | |||
181 | int evfd; | ||
182 | fd_set rfds; | ||
183 | |||
184 | char *buf_in, *buf_out; | ||
185 | struct iocb *iocb_in, *iocb_out; | ||
186 | int req_in = 0, req_out = 0; | ||
187 | bool ready; | ||
188 | |||
189 | if (argc != 2) { | ||
190 | printf("ffs directory not specified!\n"); | ||
191 | return 1; | ||
192 | } | ||
193 | |||
194 | ep_path = malloc(strlen(argv[1]) + 4 /* "/ep#" */ + 1 /* '\0' */); | ||
195 | if (!ep_path) { | ||
196 | perror("malloc"); | ||
197 | return 1; | ||
198 | } | ||
199 | |||
200 | /* open endpoint files */ | ||
201 | sprintf(ep_path, "%s/ep0", argv[1]); | ||
202 | ep0 = open(ep_path, O_RDWR); | ||
203 | if (ep0 < 0) { | ||
204 | perror("unable to open ep0"); | ||
205 | return 1; | ||
206 | } | ||
207 | if (write(ep0, &descriptors, sizeof(descriptors)) < 0) { | ||
208 | perror("unable do write descriptors"); | ||
209 | return 1; | ||
210 | } | ||
211 | if (write(ep0, &strings, sizeof(strings)) < 0) { | ||
212 | perror("unable to write strings"); | ||
213 | return 1; | ||
214 | } | ||
215 | for (i = 0; i < 2; ++i) { | ||
216 | sprintf(ep_path, "%s/ep%d", argv[1], i+1); | ||
217 | ep[i] = open(ep_path, O_RDWR); | ||
218 | if (ep[i] < 0) { | ||
219 | printf("unable to open ep%d: %s\n", i+1, | ||
220 | strerror(errno)); | ||
221 | return 1; | ||
222 | } | ||
223 | } | ||
224 | |||
225 | free(ep_path); | ||
226 | |||
227 | memset(&ctx, 0, sizeof(ctx)); | ||
228 | /* setup aio context to handle up to 2 requests */ | ||
229 | if (io_setup(2, &ctx) < 0) { | ||
230 | perror("unable to setup aio"); | ||
231 | return 1; | ||
232 | } | ||
233 | |||
234 | evfd = eventfd(0, 0); | ||
235 | if (evfd < 0) { | ||
236 | perror("unable to open eventfd"); | ||
237 | return 1; | ||
238 | } | ||
239 | |||
240 | /* alloc buffers and requests */ | ||
241 | buf_in = malloc(BUF_LEN); | ||
242 | buf_out = malloc(BUF_LEN); | ||
243 | iocb_in = malloc(sizeof(*iocb_in)); | ||
244 | iocb_out = malloc(sizeof(*iocb_out)); | ||
245 | |||
246 | while (1) { | ||
247 | FD_ZERO(&rfds); | ||
248 | FD_SET(ep0, &rfds); | ||
249 | FD_SET(evfd, &rfds); | ||
250 | |||
251 | ret = select(((ep0 > evfd) ? ep0 : evfd)+1, | ||
252 | &rfds, NULL, NULL, NULL); | ||
253 | if (ret < 0) { | ||
254 | if (errno == EINTR) | ||
255 | continue; | ||
256 | perror("select"); | ||
257 | break; | ||
258 | } | ||
259 | |||
260 | if (FD_ISSET(ep0, &rfds)) | ||
261 | handle_ep0(ep0, &ready); | ||
262 | |||
263 | /* we are waiting for function ENABLE */ | ||
264 | if (!ready) | ||
265 | continue; | ||
266 | |||
267 | /* if something was submitted we wait for event */ | ||
268 | if (FD_ISSET(evfd, &rfds)) { | ||
269 | uint64_t ev_cnt; | ||
270 | ret = read(evfd, &ev_cnt, sizeof(ev_cnt)); | ||
271 | if (ret < 0) { | ||
272 | perror("unable to read eventfd"); | ||
273 | break; | ||
274 | } | ||
275 | |||
276 | struct io_event e[2]; | ||
277 | /* we wait for one event */ | ||
278 | ret = io_getevents(ctx, 1, 2, e, NULL); | ||
279 | /* if we got event */ | ||
280 | for (i = 0; i < ret; ++i) { | ||
281 | if (e[i].obj->aio_fildes == ep[0]) { | ||
282 | printf("ev=in; ret=%lu\n", e[i].res); | ||
283 | req_in = 0; | ||
284 | } else if (e[i].obj->aio_fildes == ep[1]) { | ||
285 | printf("ev=out; ret=%lu\n", e[i].res); | ||
286 | req_out = 0; | ||
287 | } | ||
288 | } | ||
289 | } | ||
290 | |||
291 | if (!req_in) { /* if IN transfer not requested*/ | ||
292 | /* prepare write request */ | ||
293 | io_prep_pwrite(iocb_in, ep[0], buf_in, BUF_LEN, 0); | ||
294 | /* enable eventfd notification */ | ||
295 | iocb_in->u.c.flags |= IOCB_FLAG_RESFD; | ||
296 | iocb_in->u.c.resfd = evfd; | ||
297 | /* submit table of requests */ | ||
298 | ret = io_submit(ctx, 1, &iocb_in); | ||
299 | if (ret >= 0) { /* if ret > 0 request is queued */ | ||
300 | req_in = 1; | ||
301 | printf("submit: in\n"); | ||
302 | } else | ||
303 | perror("unable to submit request"); | ||
304 | } | ||
305 | if (!req_out) { /* if OUT transfer not requested */ | ||
306 | /* prepare read request */ | ||
307 | io_prep_pread(iocb_out, ep[1], buf_out, BUF_LEN, 0); | ||
308 | /* enable eventfs notification */ | ||
309 | iocb_out->u.c.flags |= IOCB_FLAG_RESFD; | ||
310 | iocb_out->u.c.resfd = evfd; | ||
311 | /* submit table of requests */ | ||
312 | ret = io_submit(ctx, 1, &iocb_out); | ||
313 | if (ret >= 0) { /* if ret > 0 request is queued */ | ||
314 | req_out = 1; | ||
315 | printf("submit: out\n"); | ||
316 | } else | ||
317 | perror("unable to submit request"); | ||
318 | } | ||
319 | } | ||
320 | |||
321 | /* free resources */ | ||
322 | |||
323 | io_destroy(ctx); | ||
324 | |||
325 | free(buf_in); | ||
326 | free(buf_out); | ||
327 | free(iocb_in); | ||
328 | free(iocb_out); | ||
329 | |||
330 | for (i = 0; i < 2; ++i) | ||
331 | close(ep[i]); | ||
332 | close(ep0); | ||
333 | |||
334 | return 0; | ||
335 | } | ||
diff --git a/tools/usb/ffs-aio-example/simple/host_app/Makefile b/tools/usb/ffs-aio-example/simple/host_app/Makefile new file mode 100644 index 000000000000..8c4a6f0aa82d --- /dev/null +++ b/tools/usb/ffs-aio-example/simple/host_app/Makefile | |||
@@ -0,0 +1,13 @@ | |||
1 | CC = gcc | ||
2 | LIBUSB_CFLAGS = $(shell pkg-config --cflags libusb-1.0) | ||
3 | LIBUSB_LIBS = $(shell pkg-config --libs libusb-1.0) | ||
4 | WARNINGS = -Wall -Wextra | ||
5 | CFLAGS = $(LIBUSB_CFLAGS) $(WARNINGS) | ||
6 | LDFLAGS = $(LIBUSB_LIBS) | ||
7 | |||
8 | all: test | ||
9 | %: %.c | ||
10 | $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) | ||
11 | |||
12 | clean: | ||
13 | $(RM) test | ||
diff --git a/tools/usb/ffs-aio-example/simple/host_app/test.c b/tools/usb/ffs-aio-example/simple/host_app/test.c new file mode 100644 index 000000000000..64b6a57d8ca3 --- /dev/null +++ b/tools/usb/ffs-aio-example/simple/host_app/test.c | |||
@@ -0,0 +1,148 @@ | |||
1 | #include <libusb.h> | ||
2 | #include <stdio.h> | ||
3 | #include <string.h> | ||
4 | #include <unistd.h> | ||
5 | |||
6 | #define VENDOR 0x1d6b | ||
7 | #define PRODUCT 0x0105 | ||
8 | |||
9 | /* endpoints indexes */ | ||
10 | |||
11 | #define EP_BULK_IN (1 | LIBUSB_ENDPOINT_IN) | ||
12 | #define EP_BULK_OUT (2 | LIBUSB_ENDPOINT_OUT) | ||
13 | |||
14 | #define BUF_LEN 8192 | ||
15 | |||
16 | /* | ||
17 | * struct test_state - describes test program state | ||
18 | * @list: list of devices returned by libusb_get_device_list function | ||
19 | * @found: pointer to struct describing tested device | ||
20 | * @ctx: context, set to NULL | ||
21 | * @handle: handle of tested device | ||
22 | * @attached: indicates that device was attached to kernel, and has to be | ||
23 | * reattached at the end of test program | ||
24 | */ | ||
25 | |||
26 | struct test_state { | ||
27 | libusb_device *found; | ||
28 | libusb_context *ctx; | ||
29 | libusb_device_handle *handle; | ||
30 | int attached; | ||
31 | }; | ||
32 | |||
33 | /* | ||
34 | * test_init - initialize test program | ||
35 | */ | ||
36 | |||
37 | int test_init(struct test_state *state) | ||
38 | { | ||
39 | int i, ret; | ||
40 | ssize_t cnt; | ||
41 | libusb_device **list; | ||
42 | |||
43 | state->found = NULL; | ||
44 | state->ctx = NULL; | ||
45 | state->handle = NULL; | ||
46 | state->attached = 0; | ||
47 | |||
48 | ret = libusb_init(&state->ctx); | ||
49 | if (ret) { | ||
50 | printf("cannot init libusb: %s\n", libusb_error_name(ret)); | ||
51 | return 1; | ||
52 | } | ||
53 | |||
54 | cnt = libusb_get_device_list(state->ctx, &list); | ||
55 | if (cnt <= 0) { | ||
56 | printf("no devices found\n"); | ||
57 | goto error1; | ||
58 | } | ||
59 | |||
60 | for (i = 0; i < cnt; ++i) { | ||
61 | libusb_device *dev = list[i]; | ||
62 | struct libusb_device_descriptor desc; | ||
63 | ret = libusb_get_device_descriptor(dev, &desc); | ||
64 | if (ret) { | ||
65 | printf("unable to get device descriptor: %s\n", | ||
66 | libusb_error_name(ret)); | ||
67 | goto error2; | ||
68 | } | ||
69 | if (desc.idVendor == VENDOR && desc.idProduct == PRODUCT) { | ||
70 | state->found = dev; | ||
71 | break; | ||
72 | } | ||
73 | } | ||
74 | |||
75 | if (!state->found) { | ||
76 | printf("no devices found\n"); | ||
77 | goto error2; | ||
78 | } | ||
79 | |||
80 | ret = libusb_open(state->found, &state->handle); | ||
81 | if (ret) { | ||
82 | printf("cannot open device: %s\n", libusb_error_name(ret)); | ||
83 | goto error2; | ||
84 | } | ||
85 | |||
86 | if (libusb_claim_interface(state->handle, 0)) { | ||
87 | ret = libusb_detach_kernel_driver(state->handle, 0); | ||
88 | if (ret) { | ||
89 | printf("unable to detach kernel driver: %s\n", | ||
90 | libusb_error_name(ret)); | ||
91 | goto error3; | ||
92 | } | ||
93 | state->attached = 1; | ||
94 | ret = libusb_claim_interface(state->handle, 0); | ||
95 | if (ret) { | ||
96 | printf("cannot claim interface: %s\n", | ||
97 | libusb_error_name(ret)); | ||
98 | goto error4; | ||
99 | } | ||
100 | } | ||
101 | |||
102 | return 0; | ||
103 | |||
104 | error4: | ||
105 | if (state->attached == 1) | ||
106 | libusb_attach_kernel_driver(state->handle, 0); | ||
107 | |||
108 | error3: | ||
109 | libusb_close(state->handle); | ||
110 | |||
111 | error2: | ||
112 | libusb_free_device_list(list, 1); | ||
113 | |||
114 | error1: | ||
115 | libusb_exit(state->ctx); | ||
116 | return 1; | ||
117 | } | ||
118 | |||
119 | /* | ||
120 | * test_exit - cleanup test program | ||
121 | */ | ||
122 | |||
123 | void test_exit(struct test_state *state) | ||
124 | { | ||
125 | libusb_release_interface(state->handle, 0); | ||
126 | if (state->attached == 1) | ||
127 | libusb_attach_kernel_driver(state->handle, 0); | ||
128 | libusb_close(state->handle); | ||
129 | libusb_exit(state->ctx); | ||
130 | } | ||
131 | |||
132 | int main(void) | ||
133 | { | ||
134 | struct test_state state; | ||
135 | |||
136 | if (test_init(&state)) | ||
137 | return 1; | ||
138 | |||
139 | while (1) { | ||
140 | static unsigned char buffer[BUF_LEN]; | ||
141 | int bytes; | ||
142 | libusb_bulk_transfer(state.handle, EP_BULK_IN, buffer, BUF_LEN, | ||
143 | &bytes, 500); | ||
144 | libusb_bulk_transfer(state.handle, EP_BULK_OUT, buffer, BUF_LEN, | ||
145 | &bytes, 500); | ||
146 | } | ||
147 | test_exit(&state); | ||
148 | } | ||