1 | // SPDX-License-Identifier: GPL-1.0+ |
2 | /* |
3 | * Renesas USB driver |
4 | * |
5 | * Copyright (C) 2011 Renesas Solutions Corp. |
6 | * Copyright (C) 2019 Renesas Electronics Corporation |
7 | * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> |
8 | */ |
9 | #include <linux/delay.h> |
10 | #include <linux/dma-mapping.h> |
11 | #include <linux/io.h> |
12 | #include <linux/module.h> |
13 | #include <linux/platform_device.h> |
14 | #include <linux/usb/ch9.h> |
15 | #include <linux/usb/gadget.h> |
16 | #include <linux/usb/otg.h> |
17 | #include "common.h" |
18 | |
19 | /* |
20 | * struct |
21 | */ |
22 | struct usbhsg_request { |
23 | struct usb_request req; |
24 | struct usbhs_pkt pkt; |
25 | }; |
26 | |
27 | #define EP_NAME_SIZE 8 |
28 | struct usbhsg_gpriv; |
29 | struct usbhsg_uep { |
30 | struct usb_ep ep; |
31 | struct usbhs_pipe *pipe; |
32 | spinlock_t lock; /* protect the pipe */ |
33 | |
34 | char ep_name[EP_NAME_SIZE]; |
35 | |
36 | struct usbhsg_gpriv *gpriv; |
37 | }; |
38 | |
39 | struct usbhsg_gpriv { |
40 | struct usb_gadget gadget; |
41 | struct usbhs_mod mod; |
42 | |
43 | struct usbhsg_uep *uep; |
44 | int uep_size; |
45 | |
46 | struct usb_gadget_driver *driver; |
47 | struct usb_phy *transceiver; |
48 | bool vbus_active; |
49 | |
50 | u32 status; |
51 | #define USBHSG_STATUS_STARTED (1 << 0) |
52 | #define USBHSG_STATUS_REGISTERD (1 << 1) |
53 | #define USBHSG_STATUS_WEDGE (1 << 2) |
54 | #define USBHSG_STATUS_SELF_POWERED (1 << 3) |
55 | #define USBHSG_STATUS_SOFT_CONNECT (1 << 4) |
56 | }; |
57 | |
58 | struct usbhsg_recip_handle { |
59 | char *name; |
60 | int (*device)(struct usbhs_priv *priv, struct usbhsg_uep *uep, |
61 | struct usb_ctrlrequest *ctrl); |
62 | int (*interface)(struct usbhs_priv *priv, struct usbhsg_uep *uep, |
63 | struct usb_ctrlrequest *ctrl); |
64 | int (*endpoint)(struct usbhs_priv *priv, struct usbhsg_uep *uep, |
65 | struct usb_ctrlrequest *ctrl); |
66 | }; |
67 | |
68 | /* |
69 | * macro |
70 | */ |
71 | #define usbhsg_priv_to_gpriv(priv) \ |
72 | container_of( \ |
73 | usbhs_mod_get(priv, USBHS_GADGET), \ |
74 | struct usbhsg_gpriv, mod) |
75 | |
76 | #define __usbhsg_for_each_uep(start, pos, g, i) \ |
77 | for ((i) = start; \ |
78 | ((i) < (g)->uep_size) && ((pos) = (g)->uep + (i)); \ |
79 | (i)++) |
80 | |
81 | #define usbhsg_for_each_uep(pos, gpriv, i) \ |
82 | __usbhsg_for_each_uep(1, pos, gpriv, i) |
83 | |
84 | #define usbhsg_for_each_uep_with_dcp(pos, gpriv, i) \ |
85 | __usbhsg_for_each_uep(0, pos, gpriv, i) |
86 | |
87 | #define usbhsg_gadget_to_gpriv(g)\ |
88 | container_of(g, struct usbhsg_gpriv, gadget) |
89 | |
90 | #define usbhsg_req_to_ureq(r)\ |
91 | container_of(r, struct usbhsg_request, req) |
92 | |
93 | #define usbhsg_ep_to_uep(e) container_of(e, struct usbhsg_uep, ep) |
94 | #define usbhsg_gpriv_to_dev(gp) usbhs_priv_to_dev((gp)->mod.priv) |
95 | #define usbhsg_gpriv_to_priv(gp) ((gp)->mod.priv) |
96 | #define usbhsg_gpriv_to_dcp(gp) ((gp)->uep) |
97 | #define usbhsg_gpriv_to_nth_uep(gp, i) ((gp)->uep + i) |
98 | #define usbhsg_uep_to_gpriv(u) ((u)->gpriv) |
99 | #define usbhsg_uep_to_pipe(u) ((u)->pipe) |
100 | #define usbhsg_pipe_to_uep(p) ((p)->mod_private) |
101 | #define usbhsg_is_dcp(u) ((u) == usbhsg_gpriv_to_dcp((u)->gpriv)) |
102 | |
103 | #define usbhsg_ureq_to_pkt(u) (&(u)->pkt) |
104 | #define usbhsg_pkt_to_ureq(i) \ |
105 | container_of(i, struct usbhsg_request, pkt) |
106 | |
107 | #define usbhsg_is_not_connected(gp) ((gp)->gadget.speed == USB_SPEED_UNKNOWN) |
108 | |
109 | /* status */ |
110 | #define usbhsg_status_init(gp) do {(gp)->status = 0; } while (0) |
111 | #define usbhsg_status_set(gp, b) (gp->status |= b) |
112 | #define usbhsg_status_clr(gp, b) (gp->status &= ~b) |
113 | #define usbhsg_status_has(gp, b) (gp->status & b) |
114 | |
115 | /* |
116 | * queue push/pop |
117 | */ |
118 | static void __usbhsg_queue_pop(struct usbhsg_uep *uep, |
119 | struct usbhsg_request *ureq, |
120 | int status) |
121 | { |
122 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); |
123 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); |
124 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); |
125 | struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); |
126 | |
127 | if (pipe) |
128 | dev_dbg(dev, "pipe %d : queue pop\n" , usbhs_pipe_number(pipe)); |
129 | |
130 | ureq->req.status = status; |
131 | spin_unlock(usbhs_priv_to_lock(priv)); |
132 | usb_gadget_giveback_request(ep: &uep->ep, req: &ureq->req); |
133 | spin_lock(usbhs_priv_to_lock(priv)); |
134 | } |
135 | |
136 | static void usbhsg_queue_pop(struct usbhsg_uep *uep, |
137 | struct usbhsg_request *ureq, |
138 | int status) |
139 | { |
140 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); |
141 | struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); |
142 | unsigned long flags; |
143 | |
144 | usbhs_lock(priv, flags); |
145 | __usbhsg_queue_pop(uep, ureq, status); |
146 | usbhs_unlock(priv, flags); |
147 | } |
148 | |
149 | static void usbhsg_queue_done(struct usbhs_priv *priv, struct usbhs_pkt *pkt) |
150 | { |
151 | struct usbhs_pipe *pipe = pkt->pipe; |
152 | struct usbhsg_uep *uep = usbhsg_pipe_to_uep(pipe); |
153 | struct usbhsg_request *ureq = usbhsg_pkt_to_ureq(pkt); |
154 | unsigned long flags; |
155 | |
156 | ureq->req.actual = pkt->actual; |
157 | |
158 | usbhs_lock(priv, flags); |
159 | if (uep) |
160 | __usbhsg_queue_pop(uep, ureq, status: 0); |
161 | usbhs_unlock(priv, flags); |
162 | } |
163 | |
164 | static void usbhsg_queue_push(struct usbhsg_uep *uep, |
165 | struct usbhsg_request *ureq) |
166 | { |
167 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); |
168 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); |
169 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); |
170 | struct usbhs_pkt *pkt = usbhsg_ureq_to_pkt(ureq); |
171 | struct usb_request *req = &ureq->req; |
172 | |
173 | req->actual = 0; |
174 | req->status = -EINPROGRESS; |
175 | usbhs_pkt_push(pipe, pkt, done: usbhsg_queue_done, |
176 | buf: req->buf, len: req->length, zero: req->zero, sequence: -1); |
177 | usbhs_pkt_start(pipe); |
178 | |
179 | dev_dbg(dev, "pipe %d : queue push (%d)\n" , |
180 | usbhs_pipe_number(pipe), |
181 | req->length); |
182 | } |
183 | |
184 | /* |
185 | * dma map/unmap |
186 | */ |
187 | static int usbhsg_dma_map_ctrl(struct device *dma_dev, struct usbhs_pkt *pkt, |
188 | int map) |
189 | { |
190 | struct usbhsg_request *ureq = usbhsg_pkt_to_ureq(pkt); |
191 | struct usb_request *req = &ureq->req; |
192 | struct usbhs_pipe *pipe = pkt->pipe; |
193 | enum dma_data_direction dir; |
194 | int ret = 0; |
195 | |
196 | dir = usbhs_pipe_is_dir_host(pipe); |
197 | |
198 | if (map) { |
199 | /* it can not use scatter/gather */ |
200 | WARN_ON(req->num_sgs); |
201 | |
202 | ret = usb_gadget_map_request_by_dev(dev: dma_dev, req, is_in: dir); |
203 | if (ret < 0) |
204 | return ret; |
205 | |
206 | pkt->dma = req->dma; |
207 | } else { |
208 | usb_gadget_unmap_request_by_dev(dev: dma_dev, req, is_in: dir); |
209 | } |
210 | |
211 | return ret; |
212 | } |
213 | |
214 | /* |
215 | * USB_TYPE_STANDARD / clear feature functions |
216 | */ |
217 | static int usbhsg_recip_handler_std_control_done(struct usbhs_priv *priv, |
218 | struct usbhsg_uep *uep, |
219 | struct usb_ctrlrequest *ctrl) |
220 | { |
221 | struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); |
222 | struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); |
223 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(dcp); |
224 | |
225 | usbhs_dcp_control_transfer_done(pipe); |
226 | |
227 | return 0; |
228 | } |
229 | |
230 | static int usbhsg_recip_handler_std_clear_endpoint(struct usbhs_priv *priv, |
231 | struct usbhsg_uep *uep, |
232 | struct usb_ctrlrequest *ctrl) |
233 | { |
234 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); |
235 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); |
236 | |
237 | if (!usbhsg_status_has(gpriv, USBHSG_STATUS_WEDGE)) { |
238 | usbhs_pipe_disable(pipe); |
239 | usbhs_pipe_sequence_data0(pipe); |
240 | usbhs_pipe_enable(pipe); |
241 | } |
242 | |
243 | usbhsg_recip_handler_std_control_done(priv, uep, ctrl); |
244 | |
245 | usbhs_pkt_start(pipe); |
246 | |
247 | return 0; |
248 | } |
249 | |
250 | static struct usbhsg_recip_handle req_clear_feature = { |
251 | .name = "clear feature" , |
252 | .device = usbhsg_recip_handler_std_control_done, |
253 | .interface = usbhsg_recip_handler_std_control_done, |
254 | .endpoint = usbhsg_recip_handler_std_clear_endpoint, |
255 | }; |
256 | |
257 | /* |
258 | * USB_TYPE_STANDARD / set feature functions |
259 | */ |
260 | static int usbhsg_recip_handler_std_set_device(struct usbhs_priv *priv, |
261 | struct usbhsg_uep *uep, |
262 | struct usb_ctrlrequest *ctrl) |
263 | { |
264 | switch (le16_to_cpu(ctrl->wValue)) { |
265 | case USB_DEVICE_TEST_MODE: |
266 | usbhsg_recip_handler_std_control_done(priv, uep, ctrl); |
267 | udelay(100); |
268 | usbhs_sys_set_test_mode(priv, le16_to_cpu(ctrl->wIndex) >> 8); |
269 | break; |
270 | default: |
271 | usbhsg_recip_handler_std_control_done(priv, uep, ctrl); |
272 | break; |
273 | } |
274 | |
275 | return 0; |
276 | } |
277 | |
278 | static int usbhsg_recip_handler_std_set_endpoint(struct usbhs_priv *priv, |
279 | struct usbhsg_uep *uep, |
280 | struct usb_ctrlrequest *ctrl) |
281 | { |
282 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); |
283 | |
284 | usbhs_pipe_stall(pipe); |
285 | |
286 | usbhsg_recip_handler_std_control_done(priv, uep, ctrl); |
287 | |
288 | return 0; |
289 | } |
290 | |
291 | static struct usbhsg_recip_handle req_set_feature = { |
292 | .name = "set feature" , |
293 | .device = usbhsg_recip_handler_std_set_device, |
294 | .interface = usbhsg_recip_handler_std_control_done, |
295 | .endpoint = usbhsg_recip_handler_std_set_endpoint, |
296 | }; |
297 | |
298 | /* |
299 | * USB_TYPE_STANDARD / get status functions |
300 | */ |
301 | static void __usbhsg_recip_send_complete(struct usb_ep *ep, |
302 | struct usb_request *req) |
303 | { |
304 | struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); |
305 | |
306 | /* free allocated recip-buffer/usb_request */ |
307 | kfree(objp: ureq->pkt.buf); |
308 | usb_ep_free_request(ep, req); |
309 | } |
310 | |
311 | static void __usbhsg_recip_send_status(struct usbhsg_gpriv *gpriv, |
312 | unsigned short status) |
313 | { |
314 | struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); |
315 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(dcp); |
316 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); |
317 | struct usb_request *req; |
318 | __le16 *buf; |
319 | |
320 | /* alloc new usb_request for recip */ |
321 | req = usb_ep_alloc_request(ep: &dcp->ep, GFP_ATOMIC); |
322 | if (!req) { |
323 | dev_err(dev, "recip request allocation fail\n" ); |
324 | return; |
325 | } |
326 | |
327 | /* alloc recip data buffer */ |
328 | buf = kmalloc(size: sizeof(*buf), GFP_ATOMIC); |
329 | if (!buf) { |
330 | usb_ep_free_request(ep: &dcp->ep, req); |
331 | return; |
332 | } |
333 | |
334 | /* recip data is status */ |
335 | *buf = cpu_to_le16(status); |
336 | |
337 | /* allocated usb_request/buffer will be freed */ |
338 | req->complete = __usbhsg_recip_send_complete; |
339 | req->buf = buf; |
340 | req->length = sizeof(*buf); |
341 | req->zero = 0; |
342 | |
343 | /* push packet */ |
344 | pipe->handler = &usbhs_fifo_pio_push_handler; |
345 | usbhsg_queue_push(uep: dcp, usbhsg_req_to_ureq(req)); |
346 | } |
347 | |
348 | static int usbhsg_recip_handler_std_get_device(struct usbhs_priv *priv, |
349 | struct usbhsg_uep *uep, |
350 | struct usb_ctrlrequest *ctrl) |
351 | { |
352 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); |
353 | unsigned short status = 0; |
354 | |
355 | if (usbhsg_status_has(gpriv, USBHSG_STATUS_SELF_POWERED)) |
356 | status = 1 << USB_DEVICE_SELF_POWERED; |
357 | |
358 | __usbhsg_recip_send_status(gpriv, status); |
359 | |
360 | return 0; |
361 | } |
362 | |
363 | static int usbhsg_recip_handler_std_get_interface(struct usbhs_priv *priv, |
364 | struct usbhsg_uep *uep, |
365 | struct usb_ctrlrequest *ctrl) |
366 | { |
367 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); |
368 | unsigned short status = 0; |
369 | |
370 | __usbhsg_recip_send_status(gpriv, status); |
371 | |
372 | return 0; |
373 | } |
374 | |
375 | static int usbhsg_recip_handler_std_get_endpoint(struct usbhs_priv *priv, |
376 | struct usbhsg_uep *uep, |
377 | struct usb_ctrlrequest *ctrl) |
378 | { |
379 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); |
380 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); |
381 | unsigned short status = 0; |
382 | |
383 | if (usbhs_pipe_is_stall(pipe)) |
384 | status = 1 << USB_ENDPOINT_HALT; |
385 | |
386 | __usbhsg_recip_send_status(gpriv, status); |
387 | |
388 | return 0; |
389 | } |
390 | |
391 | static struct usbhsg_recip_handle req_get_status = { |
392 | .name = "get status" , |
393 | .device = usbhsg_recip_handler_std_get_device, |
394 | .interface = usbhsg_recip_handler_std_get_interface, |
395 | .endpoint = usbhsg_recip_handler_std_get_endpoint, |
396 | }; |
397 | |
398 | /* |
399 | * USB_TYPE handler |
400 | */ |
401 | static int usbhsg_recip_run_handle(struct usbhs_priv *priv, |
402 | struct usbhsg_recip_handle *handler, |
403 | struct usb_ctrlrequest *ctrl) |
404 | { |
405 | struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); |
406 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); |
407 | struct usbhsg_uep *uep; |
408 | struct usbhs_pipe *pipe; |
409 | int recip = ctrl->bRequestType & USB_RECIP_MASK; |
410 | int nth = le16_to_cpu(ctrl->wIndex) & USB_ENDPOINT_NUMBER_MASK; |
411 | int ret = 0; |
412 | int (*func)(struct usbhs_priv *priv, struct usbhsg_uep *uep, |
413 | struct usb_ctrlrequest *ctrl); |
414 | char *msg; |
415 | |
416 | uep = usbhsg_gpriv_to_nth_uep(gpriv, nth); |
417 | pipe = usbhsg_uep_to_pipe(uep); |
418 | if (!pipe) { |
419 | dev_err(dev, "wrong recip request\n" ); |
420 | return -EINVAL; |
421 | } |
422 | |
423 | switch (recip) { |
424 | case USB_RECIP_DEVICE: |
425 | msg = "DEVICE" ; |
426 | func = handler->device; |
427 | break; |
428 | case USB_RECIP_INTERFACE: |
429 | msg = "INTERFACE" ; |
430 | func = handler->interface; |
431 | break; |
432 | case USB_RECIP_ENDPOINT: |
433 | msg = "ENDPOINT" ; |
434 | func = handler->endpoint; |
435 | break; |
436 | default: |
437 | dev_warn(dev, "unsupported RECIP(%d)\n" , recip); |
438 | func = NULL; |
439 | ret = -EINVAL; |
440 | } |
441 | |
442 | if (func) { |
443 | dev_dbg(dev, "%s (pipe %d :%s)\n" , handler->name, nth, msg); |
444 | ret = func(priv, uep, ctrl); |
445 | } |
446 | |
447 | return ret; |
448 | } |
449 | |
450 | /* |
451 | * irq functions |
452 | * |
453 | * it will be called from usbhs_interrupt |
454 | */ |
455 | static int usbhsg_irq_dev_state(struct usbhs_priv *priv, |
456 | struct usbhs_irq_state *irq_state) |
457 | { |
458 | struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); |
459 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); |
460 | int state = usbhs_status_get_device_state(irq_state); |
461 | |
462 | gpriv->gadget.speed = usbhs_bus_get_speed(priv); |
463 | |
464 | dev_dbg(dev, "state = %x : speed : %d\n" , state, gpriv->gadget.speed); |
465 | |
466 | if (gpriv->gadget.speed != USB_SPEED_UNKNOWN && |
467 | (state & SUSPENDED_STATE)) { |
468 | if (gpriv->driver && gpriv->driver->suspend) |
469 | gpriv->driver->suspend(&gpriv->gadget); |
470 | usb_gadget_set_state(gadget: &gpriv->gadget, state: USB_STATE_SUSPENDED); |
471 | } |
472 | |
473 | return 0; |
474 | } |
475 | |
476 | static int usbhsg_irq_ctrl_stage(struct usbhs_priv *priv, |
477 | struct usbhs_irq_state *irq_state) |
478 | { |
479 | struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); |
480 | struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); |
481 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(dcp); |
482 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); |
483 | struct usb_ctrlrequest ctrl; |
484 | struct usbhsg_recip_handle *recip_handler = NULL; |
485 | int stage = usbhs_status_get_ctrl_stage(irq_state); |
486 | int ret = 0; |
487 | |
488 | dev_dbg(dev, "stage = %d\n" , stage); |
489 | |
490 | /* |
491 | * see Manual |
492 | * |
493 | * "Operation" |
494 | * - "Interrupt Function" |
495 | * - "Control Transfer Stage Transition Interrupt" |
496 | * - Fig. "Control Transfer Stage Transitions" |
497 | */ |
498 | |
499 | switch (stage) { |
500 | case READ_DATA_STAGE: |
501 | pipe->handler = &usbhs_fifo_pio_push_handler; |
502 | break; |
503 | case WRITE_DATA_STAGE: |
504 | pipe->handler = &usbhs_fifo_pio_pop_handler; |
505 | break; |
506 | case NODATA_STATUS_STAGE: |
507 | pipe->handler = &usbhs_ctrl_stage_end_handler; |
508 | break; |
509 | case READ_STATUS_STAGE: |
510 | case WRITE_STATUS_STAGE: |
511 | usbhs_dcp_control_transfer_done(pipe); |
512 | fallthrough; |
513 | default: |
514 | return ret; |
515 | } |
516 | |
517 | /* |
518 | * get usb request |
519 | */ |
520 | usbhs_usbreq_get_val(priv, req: &ctrl); |
521 | |
522 | switch (ctrl.bRequestType & USB_TYPE_MASK) { |
523 | case USB_TYPE_STANDARD: |
524 | switch (ctrl.bRequest) { |
525 | case USB_REQ_CLEAR_FEATURE: |
526 | recip_handler = &req_clear_feature; |
527 | break; |
528 | case USB_REQ_SET_FEATURE: |
529 | recip_handler = &req_set_feature; |
530 | break; |
531 | case USB_REQ_GET_STATUS: |
532 | recip_handler = &req_get_status; |
533 | break; |
534 | } |
535 | } |
536 | |
537 | /* |
538 | * setup stage / run recip |
539 | */ |
540 | if (recip_handler) |
541 | ret = usbhsg_recip_run_handle(priv, handler: recip_handler, ctrl: &ctrl); |
542 | else |
543 | ret = gpriv->driver->setup(&gpriv->gadget, &ctrl); |
544 | |
545 | if (ret < 0) |
546 | usbhs_pipe_stall(pipe); |
547 | |
548 | return ret; |
549 | } |
550 | |
551 | /* |
552 | * |
553 | * usb_dcp_ops |
554 | * |
555 | */ |
556 | static int usbhsg_pipe_disable(struct usbhsg_uep *uep) |
557 | { |
558 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); |
559 | struct usbhs_pkt *pkt; |
560 | |
561 | while (1) { |
562 | pkt = usbhs_pkt_pop(pipe, NULL); |
563 | if (!pkt) |
564 | break; |
565 | |
566 | usbhsg_queue_pop(uep, usbhsg_pkt_to_ureq(pkt), status: -ESHUTDOWN); |
567 | } |
568 | |
569 | usbhs_pipe_disable(pipe); |
570 | |
571 | return 0; |
572 | } |
573 | |
574 | /* |
575 | * |
576 | * usb_ep_ops |
577 | * |
578 | */ |
579 | static int usbhsg_ep_enable(struct usb_ep *ep, |
580 | const struct usb_endpoint_descriptor *desc) |
581 | { |
582 | struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); |
583 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); |
584 | struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); |
585 | struct usbhs_pipe *pipe; |
586 | int ret = -EIO; |
587 | unsigned long flags; |
588 | |
589 | usbhs_lock(priv, flags); |
590 | |
591 | /* |
592 | * if it already have pipe, |
593 | * nothing to do |
594 | */ |
595 | if (uep->pipe) { |
596 | usbhs_pipe_clear(pipe: uep->pipe); |
597 | usbhs_pipe_sequence_data0(uep->pipe); |
598 | ret = 0; |
599 | goto usbhsg_ep_enable_end; |
600 | } |
601 | |
602 | pipe = usbhs_pipe_malloc(priv, |
603 | endpoint_type: usb_endpoint_type(epd: desc), |
604 | dir_in: usb_endpoint_dir_in(epd: desc)); |
605 | if (pipe) { |
606 | uep->pipe = pipe; |
607 | pipe->mod_private = uep; |
608 | |
609 | /* set epnum / maxp */ |
610 | usbhs_pipe_config_update(pipe, devsel: 0, |
611 | epnum: usb_endpoint_num(epd: desc), |
612 | maxp: usb_endpoint_maxp(epd: desc)); |
613 | |
614 | /* |
615 | * usbhs_fifo_dma_push/pop_handler try to |
616 | * use dmaengine if possible. |
617 | * It will use pio handler if impossible. |
618 | */ |
619 | if (usb_endpoint_dir_in(epd: desc)) { |
620 | pipe->handler = &usbhs_fifo_dma_push_handler; |
621 | } else { |
622 | pipe->handler = &usbhs_fifo_dma_pop_handler; |
623 | usbhs_xxxsts_clear(priv, BRDYSTS, |
624 | usbhs_pipe_number(pipe)); |
625 | } |
626 | |
627 | ret = 0; |
628 | } |
629 | |
630 | usbhsg_ep_enable_end: |
631 | usbhs_unlock(priv, flags); |
632 | |
633 | return ret; |
634 | } |
635 | |
636 | static int usbhsg_ep_disable(struct usb_ep *ep) |
637 | { |
638 | struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); |
639 | struct usbhs_pipe *pipe; |
640 | unsigned long flags; |
641 | |
642 | spin_lock_irqsave(&uep->lock, flags); |
643 | pipe = usbhsg_uep_to_pipe(uep); |
644 | if (!pipe) |
645 | goto out; |
646 | |
647 | usbhsg_pipe_disable(uep); |
648 | usbhs_pipe_free(pipe); |
649 | |
650 | uep->pipe->mod_private = NULL; |
651 | uep->pipe = NULL; |
652 | |
653 | out: |
654 | spin_unlock_irqrestore(lock: &uep->lock, flags); |
655 | |
656 | return 0; |
657 | } |
658 | |
659 | static struct usb_request *usbhsg_ep_alloc_request(struct usb_ep *ep, |
660 | gfp_t gfp_flags) |
661 | { |
662 | struct usbhsg_request *ureq; |
663 | |
664 | ureq = kzalloc(size: sizeof *ureq, flags: gfp_flags); |
665 | if (!ureq) |
666 | return NULL; |
667 | |
668 | usbhs_pkt_init(usbhsg_ureq_to_pkt(ureq)); |
669 | |
670 | return &ureq->req; |
671 | } |
672 | |
673 | static void usbhsg_ep_free_request(struct usb_ep *ep, |
674 | struct usb_request *req) |
675 | { |
676 | struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); |
677 | |
678 | WARN_ON(!list_empty(&ureq->pkt.node)); |
679 | kfree(objp: ureq); |
680 | } |
681 | |
682 | static int usbhsg_ep_queue(struct usb_ep *ep, struct usb_request *req, |
683 | gfp_t gfp_flags) |
684 | { |
685 | struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); |
686 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); |
687 | struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); |
688 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); |
689 | |
690 | /* param check */ |
691 | if (usbhsg_is_not_connected(gpriv) || |
692 | unlikely(!gpriv->driver) || |
693 | unlikely(!pipe)) |
694 | return -ESHUTDOWN; |
695 | |
696 | usbhsg_queue_push(uep, ureq); |
697 | |
698 | return 0; |
699 | } |
700 | |
701 | static int usbhsg_ep_dequeue(struct usb_ep *ep, struct usb_request *req) |
702 | { |
703 | struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); |
704 | struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); |
705 | struct usbhs_pipe *pipe; |
706 | unsigned long flags; |
707 | |
708 | spin_lock_irqsave(&uep->lock, flags); |
709 | pipe = usbhsg_uep_to_pipe(uep); |
710 | if (pipe) |
711 | usbhs_pkt_pop(pipe, usbhsg_ureq_to_pkt(ureq)); |
712 | |
713 | /* |
714 | * To dequeue a request, this driver should call the usbhsg_queue_pop() |
715 | * even if the pipe is NULL. |
716 | */ |
717 | usbhsg_queue_pop(uep, ureq, status: -ECONNRESET); |
718 | spin_unlock_irqrestore(lock: &uep->lock, flags); |
719 | |
720 | return 0; |
721 | } |
722 | |
723 | static int __usbhsg_ep_set_halt_wedge(struct usb_ep *ep, int halt, int wedge) |
724 | { |
725 | struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); |
726 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); |
727 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); |
728 | struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); |
729 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); |
730 | unsigned long flags; |
731 | int ret = 0; |
732 | |
733 | dev_dbg(dev, "set halt %d (pipe %d)\n" , |
734 | halt, usbhs_pipe_number(pipe)); |
735 | |
736 | /******************** spin lock ********************/ |
737 | usbhs_lock(priv, flags); |
738 | |
739 | /* |
740 | * According to usb_ep_set_halt()'s description, this function should |
741 | * return -EAGAIN if the IN endpoint has any queue or data. Note |
742 | * that the usbhs_pipe_is_dir_in() returns false if the pipe is an |
743 | * IN endpoint in the gadget mode. |
744 | */ |
745 | if (!usbhs_pipe_is_dir_in(pipe) && (__usbhsf_pkt_get(pipe) || |
746 | usbhs_pipe_contains_transmittable_data(pipe))) { |
747 | ret = -EAGAIN; |
748 | goto out; |
749 | } |
750 | |
751 | if (halt) |
752 | usbhs_pipe_stall(pipe); |
753 | else |
754 | usbhs_pipe_disable(pipe); |
755 | |
756 | if (halt && wedge) |
757 | usbhsg_status_set(gpriv, USBHSG_STATUS_WEDGE); |
758 | else |
759 | usbhsg_status_clr(gpriv, USBHSG_STATUS_WEDGE); |
760 | |
761 | out: |
762 | usbhs_unlock(priv, flags); |
763 | /******************** spin unlock ******************/ |
764 | |
765 | return ret; |
766 | } |
767 | |
768 | static int usbhsg_ep_set_halt(struct usb_ep *ep, int value) |
769 | { |
770 | return __usbhsg_ep_set_halt_wedge(ep, halt: value, wedge: 0); |
771 | } |
772 | |
773 | static int usbhsg_ep_set_wedge(struct usb_ep *ep) |
774 | { |
775 | return __usbhsg_ep_set_halt_wedge(ep, halt: 1, wedge: 1); |
776 | } |
777 | |
778 | static const struct usb_ep_ops usbhsg_ep_ops = { |
779 | .enable = usbhsg_ep_enable, |
780 | .disable = usbhsg_ep_disable, |
781 | |
782 | .alloc_request = usbhsg_ep_alloc_request, |
783 | .free_request = usbhsg_ep_free_request, |
784 | |
785 | .queue = usbhsg_ep_queue, |
786 | .dequeue = usbhsg_ep_dequeue, |
787 | |
788 | .set_halt = usbhsg_ep_set_halt, |
789 | .set_wedge = usbhsg_ep_set_wedge, |
790 | }; |
791 | |
792 | /* |
793 | * pullup control |
794 | */ |
795 | static int usbhsg_can_pullup(struct usbhs_priv *priv) |
796 | { |
797 | struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); |
798 | |
799 | return gpriv->driver && |
800 | usbhsg_status_has(gpriv, USBHSG_STATUS_SOFT_CONNECT); |
801 | } |
802 | |
803 | static void usbhsg_update_pullup(struct usbhs_priv *priv) |
804 | { |
805 | if (usbhsg_can_pullup(priv)) |
806 | usbhs_sys_function_pullup(priv, enable: 1); |
807 | else |
808 | usbhs_sys_function_pullup(priv, enable: 0); |
809 | } |
810 | |
811 | /* |
812 | * usb module start/end |
813 | */ |
814 | static int usbhsg_try_start(struct usbhs_priv *priv, u32 status) |
815 | { |
816 | struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); |
817 | struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); |
818 | struct usbhs_mod *mod = usbhs_mod_get_current(priv); |
819 | struct device *dev = usbhs_priv_to_dev(priv); |
820 | unsigned long flags; |
821 | int ret = 0; |
822 | |
823 | /******************** spin lock ********************/ |
824 | usbhs_lock(priv, flags); |
825 | |
826 | usbhsg_status_set(gpriv, status); |
827 | if (!(usbhsg_status_has(gpriv, USBHSG_STATUS_STARTED) && |
828 | usbhsg_status_has(gpriv, USBHSG_STATUS_REGISTERD))) |
829 | ret = -1; /* not ready */ |
830 | |
831 | usbhs_unlock(priv, flags); |
832 | /******************** spin unlock ********************/ |
833 | |
834 | if (ret < 0) |
835 | return 0; /* not ready is not error */ |
836 | |
837 | /* |
838 | * enable interrupt and systems if ready |
839 | */ |
840 | dev_dbg(dev, "start gadget\n" ); |
841 | |
842 | /* |
843 | * pipe initialize and enable DCP |
844 | */ |
845 | usbhs_fifo_init(priv); |
846 | usbhs_pipe_init(priv, |
847 | dma_map_ctrl: usbhsg_dma_map_ctrl); |
848 | |
849 | /* dcp init instead of usbhsg_ep_enable() */ |
850 | dcp->pipe = usbhs_dcp_malloc(priv); |
851 | dcp->pipe->mod_private = dcp; |
852 | usbhs_pipe_config_update(pipe: dcp->pipe, devsel: 0, epnum: 0, maxp: 64); |
853 | |
854 | /* |
855 | * system config enble |
856 | * - HI speed |
857 | * - function |
858 | * - usb module |
859 | */ |
860 | usbhs_sys_function_ctrl(priv, enable: 1); |
861 | usbhsg_update_pullup(priv); |
862 | |
863 | /* |
864 | * enable irq callback |
865 | */ |
866 | mod->irq_dev_state = usbhsg_irq_dev_state; |
867 | mod->irq_ctrl_stage = usbhsg_irq_ctrl_stage; |
868 | usbhs_irq_callback_update(priv, mod); |
869 | |
870 | return 0; |
871 | } |
872 | |
873 | static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status) |
874 | { |
875 | struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); |
876 | struct usbhs_mod *mod = usbhs_mod_get_current(priv); |
877 | struct usbhsg_uep *uep; |
878 | struct device *dev = usbhs_priv_to_dev(priv); |
879 | unsigned long flags; |
880 | int ret = 0, i; |
881 | |
882 | /******************** spin lock ********************/ |
883 | usbhs_lock(priv, flags); |
884 | |
885 | usbhsg_status_clr(gpriv, status); |
886 | if (!usbhsg_status_has(gpriv, USBHSG_STATUS_STARTED) && |
887 | !usbhsg_status_has(gpriv, USBHSG_STATUS_REGISTERD)) |
888 | ret = -1; /* already done */ |
889 | |
890 | usbhs_unlock(priv, flags); |
891 | /******************** spin unlock ********************/ |
892 | |
893 | if (ret < 0) |
894 | return 0; /* already done is not error */ |
895 | |
896 | /* |
897 | * disable interrupt and systems if 1st try |
898 | */ |
899 | usbhs_fifo_quit(priv); |
900 | |
901 | /* disable all irq */ |
902 | mod->irq_dev_state = NULL; |
903 | mod->irq_ctrl_stage = NULL; |
904 | usbhs_irq_callback_update(priv, mod); |
905 | |
906 | gpriv->gadget.speed = USB_SPEED_UNKNOWN; |
907 | |
908 | /* disable sys */ |
909 | usbhs_sys_set_test_mode(priv, mode: 0); |
910 | usbhs_sys_function_ctrl(priv, enable: 0); |
911 | |
912 | /* disable all eps */ |
913 | usbhsg_for_each_uep_with_dcp(uep, gpriv, i) |
914 | usbhsg_ep_disable(ep: &uep->ep); |
915 | |
916 | dev_dbg(dev, "stop gadget\n" ); |
917 | |
918 | return 0; |
919 | } |
920 | |
921 | /* |
922 | * VBUS provided by the PHY |
923 | */ |
924 | static int usbhsm_phy_get_vbus(struct platform_device *pdev) |
925 | { |
926 | struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); |
927 | struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); |
928 | |
929 | return gpriv->vbus_active; |
930 | } |
931 | |
932 | static void usbhs_mod_phy_mode(struct usbhs_priv *priv) |
933 | { |
934 | struct usbhs_mod_info *info = &priv->mod_info; |
935 | |
936 | info->irq_vbus = NULL; |
937 | info->get_vbus = usbhsm_phy_get_vbus; |
938 | |
939 | usbhs_irq_callback_update(priv, NULL); |
940 | } |
941 | |
942 | /* |
943 | * |
944 | * linux usb function |
945 | * |
946 | */ |
947 | static int usbhsg_gadget_start(struct usb_gadget *gadget, |
948 | struct usb_gadget_driver *driver) |
949 | { |
950 | struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); |
951 | struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); |
952 | struct device *dev = usbhs_priv_to_dev(priv); |
953 | int ret; |
954 | |
955 | if (!driver || |
956 | !driver->setup || |
957 | driver->max_speed < USB_SPEED_FULL) |
958 | return -EINVAL; |
959 | |
960 | /* connect to bus through transceiver */ |
961 | if (!IS_ERR_OR_NULL(ptr: gpriv->transceiver)) { |
962 | ret = otg_set_peripheral(otg: gpriv->transceiver->otg, |
963 | periph: &gpriv->gadget); |
964 | if (ret) { |
965 | dev_err(dev, "%s: can't bind to transceiver\n" , |
966 | gpriv->gadget.name); |
967 | return ret; |
968 | } |
969 | |
970 | /* get vbus using phy versions */ |
971 | usbhs_mod_phy_mode(priv); |
972 | } |
973 | |
974 | /* first hook up the driver ... */ |
975 | gpriv->driver = driver; |
976 | |
977 | return usbhsg_try_start(priv, USBHSG_STATUS_REGISTERD); |
978 | } |
979 | |
980 | static int usbhsg_gadget_stop(struct usb_gadget *gadget) |
981 | { |
982 | struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); |
983 | struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); |
984 | |
985 | usbhsg_try_stop(priv, USBHSG_STATUS_REGISTERD); |
986 | |
987 | if (!IS_ERR_OR_NULL(ptr: gpriv->transceiver)) |
988 | otg_set_peripheral(otg: gpriv->transceiver->otg, NULL); |
989 | |
990 | gpriv->driver = NULL; |
991 | |
992 | return 0; |
993 | } |
994 | |
995 | /* |
996 | * usb gadget ops |
997 | */ |
998 | static int usbhsg_get_frame(struct usb_gadget *gadget) |
999 | { |
1000 | struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); |
1001 | struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); |
1002 | |
1003 | return usbhs_frame_get_num(priv); |
1004 | } |
1005 | |
1006 | static int usbhsg_pullup(struct usb_gadget *gadget, int is_on) |
1007 | { |
1008 | struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); |
1009 | struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); |
1010 | unsigned long flags; |
1011 | |
1012 | usbhs_lock(priv, flags); |
1013 | if (is_on) |
1014 | usbhsg_status_set(gpriv, USBHSG_STATUS_SOFT_CONNECT); |
1015 | else |
1016 | usbhsg_status_clr(gpriv, USBHSG_STATUS_SOFT_CONNECT); |
1017 | usbhsg_update_pullup(priv); |
1018 | usbhs_unlock(priv, flags); |
1019 | |
1020 | return 0; |
1021 | } |
1022 | |
1023 | static int usbhsg_set_selfpowered(struct usb_gadget *gadget, int is_self) |
1024 | { |
1025 | struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); |
1026 | |
1027 | if (is_self) |
1028 | usbhsg_status_set(gpriv, USBHSG_STATUS_SELF_POWERED); |
1029 | else |
1030 | usbhsg_status_clr(gpriv, USBHSG_STATUS_SELF_POWERED); |
1031 | |
1032 | gadget->is_selfpowered = (is_self != 0); |
1033 | |
1034 | return 0; |
1035 | } |
1036 | |
1037 | static int usbhsg_vbus_session(struct usb_gadget *gadget, int is_active) |
1038 | { |
1039 | struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); |
1040 | struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); |
1041 | struct platform_device *pdev = usbhs_priv_to_pdev(priv); |
1042 | |
1043 | gpriv->vbus_active = !!is_active; |
1044 | |
1045 | usbhsc_schedule_notify_hotplug(pdev); |
1046 | |
1047 | return 0; |
1048 | } |
1049 | |
1050 | static const struct usb_gadget_ops usbhsg_gadget_ops = { |
1051 | .get_frame = usbhsg_get_frame, |
1052 | .set_selfpowered = usbhsg_set_selfpowered, |
1053 | .udc_start = usbhsg_gadget_start, |
1054 | .udc_stop = usbhsg_gadget_stop, |
1055 | .pullup = usbhsg_pullup, |
1056 | .vbus_session = usbhsg_vbus_session, |
1057 | }; |
1058 | |
1059 | static int usbhsg_start(struct usbhs_priv *priv) |
1060 | { |
1061 | return usbhsg_try_start(priv, USBHSG_STATUS_STARTED); |
1062 | } |
1063 | |
1064 | static int usbhsg_stop(struct usbhs_priv *priv) |
1065 | { |
1066 | struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); |
1067 | |
1068 | /* cable disconnect */ |
1069 | if (gpriv->driver && |
1070 | gpriv->driver->disconnect) |
1071 | gpriv->driver->disconnect(&gpriv->gadget); |
1072 | |
1073 | return usbhsg_try_stop(priv, USBHSG_STATUS_STARTED); |
1074 | } |
1075 | |
1076 | int usbhs_mod_gadget_probe(struct usbhs_priv *priv) |
1077 | { |
1078 | struct usbhsg_gpriv *gpriv; |
1079 | struct usbhsg_uep *uep; |
1080 | struct device *dev = usbhs_priv_to_dev(priv); |
1081 | struct renesas_usbhs_driver_pipe_config *pipe_configs = |
1082 | usbhs_get_dparam(priv, pipe_configs); |
1083 | int pipe_size = usbhs_get_dparam(priv, pipe_size); |
1084 | int i; |
1085 | int ret; |
1086 | |
1087 | gpriv = kzalloc(size: sizeof(struct usbhsg_gpriv), GFP_KERNEL); |
1088 | if (!gpriv) |
1089 | return -ENOMEM; |
1090 | |
1091 | uep = kcalloc(n: pipe_size, size: sizeof(struct usbhsg_uep), GFP_KERNEL); |
1092 | if (!uep) { |
1093 | ret = -ENOMEM; |
1094 | goto usbhs_mod_gadget_probe_err_gpriv; |
1095 | } |
1096 | |
1097 | gpriv->transceiver = usb_get_phy(type: USB_PHY_TYPE_UNDEFINED); |
1098 | dev_info(dev, "%stransceiver found\n" , |
1099 | !IS_ERR(gpriv->transceiver) ? "" : "no " ); |
1100 | |
1101 | /* |
1102 | * CAUTION |
1103 | * |
1104 | * There is no guarantee that it is possible to access usb module here. |
1105 | * Don't accesses to it. |
1106 | * The accesse will be enable after "usbhsg_start" |
1107 | */ |
1108 | |
1109 | /* |
1110 | * register itself |
1111 | */ |
1112 | usbhs_mod_register(priv, usb: &gpriv->mod, id: USBHS_GADGET); |
1113 | |
1114 | /* init gpriv */ |
1115 | gpriv->mod.name = "gadget" ; |
1116 | gpriv->mod.start = usbhsg_start; |
1117 | gpriv->mod.stop = usbhsg_stop; |
1118 | gpriv->uep = uep; |
1119 | gpriv->uep_size = pipe_size; |
1120 | usbhsg_status_init(gpriv); |
1121 | |
1122 | /* |
1123 | * init gadget |
1124 | */ |
1125 | gpriv->gadget.dev.parent = dev; |
1126 | gpriv->gadget.name = "renesas_usbhs_udc" ; |
1127 | gpriv->gadget.ops = &usbhsg_gadget_ops; |
1128 | gpriv->gadget.max_speed = USB_SPEED_HIGH; |
1129 | gpriv->gadget.quirk_avoids_skb_reserve = usbhs_get_dparam(priv, |
1130 | has_usb_dmac); |
1131 | |
1132 | INIT_LIST_HEAD(list: &gpriv->gadget.ep_list); |
1133 | |
1134 | /* |
1135 | * init usb_ep |
1136 | */ |
1137 | usbhsg_for_each_uep_with_dcp(uep, gpriv, i) { |
1138 | uep->gpriv = gpriv; |
1139 | uep->pipe = NULL; |
1140 | snprintf(buf: uep->ep_name, EP_NAME_SIZE, fmt: "ep%d" , i); |
1141 | |
1142 | uep->ep.name = uep->ep_name; |
1143 | uep->ep.ops = &usbhsg_ep_ops; |
1144 | INIT_LIST_HEAD(list: &uep->ep.ep_list); |
1145 | spin_lock_init(&uep->lock); |
1146 | |
1147 | /* init DCP */ |
1148 | if (usbhsg_is_dcp(uep)) { |
1149 | gpriv->gadget.ep0 = &uep->ep; |
1150 | usb_ep_set_maxpacket_limit(ep: &uep->ep, maxpacket_limit: 64); |
1151 | uep->ep.caps.type_control = true; |
1152 | } else { |
1153 | /* init normal pipe */ |
1154 | if (pipe_configs[i].type == USB_ENDPOINT_XFER_ISOC) |
1155 | uep->ep.caps.type_iso = true; |
1156 | if (pipe_configs[i].type == USB_ENDPOINT_XFER_BULK) |
1157 | uep->ep.caps.type_bulk = true; |
1158 | if (pipe_configs[i].type == USB_ENDPOINT_XFER_INT) |
1159 | uep->ep.caps.type_int = true; |
1160 | usb_ep_set_maxpacket_limit(ep: &uep->ep, |
1161 | maxpacket_limit: pipe_configs[i].bufsize); |
1162 | list_add_tail(new: &uep->ep.ep_list, head: &gpriv->gadget.ep_list); |
1163 | } |
1164 | uep->ep.caps.dir_in = true; |
1165 | uep->ep.caps.dir_out = true; |
1166 | } |
1167 | |
1168 | ret = usb_add_gadget_udc(parent: dev, gadget: &gpriv->gadget); |
1169 | if (ret) |
1170 | goto err_add_udc; |
1171 | |
1172 | |
1173 | dev_info(dev, "gadget probed\n" ); |
1174 | |
1175 | return 0; |
1176 | |
1177 | err_add_udc: |
1178 | kfree(objp: gpriv->uep); |
1179 | |
1180 | usbhs_mod_gadget_probe_err_gpriv: |
1181 | kfree(objp: gpriv); |
1182 | |
1183 | return ret; |
1184 | } |
1185 | |
1186 | void usbhs_mod_gadget_remove(struct usbhs_priv *priv) |
1187 | { |
1188 | struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); |
1189 | |
1190 | usb_del_gadget_udc(gadget: &gpriv->gadget); |
1191 | |
1192 | kfree(objp: gpriv->uep); |
1193 | kfree(objp: gpriv); |
1194 | } |
1195 | |