Commit | Line | Data |
---|---|---|
e8d548d5 KM |
1 | /* |
2 | * Renesas USB driver | |
3 | * | |
4 | * Copyright (C) 2011 Renesas Solutions Corp. | |
5 | * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | |
6 | * | |
7 | * This program is distributed in the hope that it will be useful, | |
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
10 | * GNU General Public License for more details. | |
11 | * | |
12 | * You should have received a copy of the GNU General Public License | |
13 | * along with this program; if not, write to the Free Software | |
14 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
15 | * | |
16 | */ | |
17 | #include <linux/delay.h> | |
18 | #include <linux/io.h> | |
19 | #include "./common.h" | |
20 | #include "./pipe.h" | |
21 | ||
d3af90a5 KM |
22 | #define usbhsf_get_cfifo(p) (&((p)->fifo_info.cfifo)) |
23 | ||
4bd04811 KM |
24 | /* |
25 | * packet info function | |
26 | */ | |
97664a20 | 27 | static int usbhsf_null_handle(struct usbhs_pkt *pkt, int *is_done) |
dad67397 KM |
28 | { |
29 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pkt->pipe); | |
30 | struct device *dev = usbhs_priv_to_dev(priv); | |
31 | ||
32 | dev_err(dev, "null handler\n"); | |
33 | ||
34 | return -EINVAL; | |
35 | } | |
36 | ||
37 | static struct usbhs_pkt_handle usbhsf_null_handler = { | |
38 | .prepare = usbhsf_null_handle, | |
39 | .try_run = usbhsf_null_handle, | |
40 | }; | |
41 | ||
6acb95d4 KM |
42 | void usbhs_pkt_init(struct usbhs_pkt *pkt) |
43 | { | |
44 | INIT_LIST_HEAD(&pkt->node); | |
45 | } | |
46 | ||
659d4954 | 47 | void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt, |
dad67397 | 48 | struct usbhs_pkt_handle *handler, |
659d4954 | 49 | void *buf, int len, int zero) |
6acb95d4 | 50 | { |
dad67397 KM |
51 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); |
52 | struct device *dev = usbhs_priv_to_dev(priv); | |
97664a20 KM |
53 | unsigned long flags; |
54 | ||
55 | /******************** spin lock ********************/ | |
56 | usbhs_lock(priv, flags); | |
dad67397 KM |
57 | |
58 | if (!handler) { | |
59 | dev_err(dev, "no handler function\n"); | |
60 | handler = &usbhsf_null_handler; | |
61 | } | |
62 | ||
6acb95d4 KM |
63 | list_del_init(&pkt->node); |
64 | list_add_tail(&pkt->node, &pipe->list); | |
65 | ||
659d4954 KM |
66 | pkt->pipe = pipe; |
67 | pkt->buf = buf; | |
dad67397 | 68 | pkt->handler = handler; |
659d4954 KM |
69 | pkt->length = len; |
70 | pkt->zero = zero; | |
71 | pkt->actual = 0; | |
97664a20 KM |
72 | |
73 | usbhs_unlock(priv, flags); | |
74 | /******************** spin unlock ******************/ | |
6acb95d4 KM |
75 | } |
76 | ||
97664a20 | 77 | static void __usbhsf_pkt_del(struct usbhs_pkt *pkt) |
6acb95d4 KM |
78 | { |
79 | list_del_init(&pkt->node); | |
80 | } | |
81 | ||
97664a20 | 82 | static struct usbhs_pkt *__usbhsf_pkt_get(struct usbhs_pipe *pipe) |
6acb95d4 KM |
83 | { |
84 | if (list_empty(&pipe->list)) | |
85 | return NULL; | |
86 | ||
87 | return list_entry(pipe->list.next, struct usbhs_pkt, node); | |
88 | } | |
89 | ||
97664a20 KM |
90 | struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt) |
91 | { | |
92 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); | |
93 | unsigned long flags; | |
94 | ||
95 | /******************** spin lock ********************/ | |
96 | usbhs_lock(priv, flags); | |
97 | ||
98 | if (!pkt) | |
99 | pkt = __usbhsf_pkt_get(pipe); | |
100 | ||
101 | if (pkt) | |
102 | __usbhsf_pkt_del(pkt); | |
103 | ||
104 | usbhs_unlock(priv, flags); | |
105 | /******************** spin unlock ******************/ | |
106 | ||
107 | return pkt; | |
108 | } | |
109 | ||
110 | int __usbhs_pkt_handler(struct usbhs_pipe *pipe, int type) | |
111 | { | |
112 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); | |
113 | struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv); | |
114 | struct usbhs_pkt *pkt; | |
115 | struct device *dev = usbhs_priv_to_dev(priv); | |
116 | int (*func)(struct usbhs_pkt *pkt, int *is_done); | |
117 | unsigned long flags; | |
118 | int ret = 0; | |
119 | int is_done = 0; | |
120 | ||
121 | /******************** spin lock ********************/ | |
122 | usbhs_lock(priv, flags); | |
123 | ||
124 | pkt = __usbhsf_pkt_get(pipe); | |
125 | if (!pkt) | |
126 | goto __usbhs_pkt_handler_end; | |
127 | ||
128 | switch (type) { | |
129 | case USBHSF_PKT_PREPARE: | |
130 | func = pkt->handler->prepare; | |
131 | break; | |
132 | case USBHSF_PKT_TRY_RUN: | |
133 | func = pkt->handler->try_run; | |
134 | break; | |
135 | default: | |
136 | dev_err(dev, "unknown pkt hander\n"); | |
137 | goto __usbhs_pkt_handler_end; | |
138 | } | |
139 | ||
140 | ret = func(pkt, &is_done); | |
141 | ||
142 | if (is_done) | |
143 | __usbhsf_pkt_del(pkt); | |
144 | ||
145 | __usbhs_pkt_handler_end: | |
146 | usbhs_unlock(priv, flags); | |
147 | /******************** spin unlock ******************/ | |
148 | ||
149 | if (is_done) | |
150 | info->done(pkt); | |
151 | ||
152 | return ret; | |
153 | } | |
154 | ||
659d4954 KM |
155 | /* |
156 | * irq enable/disable function | |
157 | */ | |
158 | #define usbhsf_irq_empty_ctrl(p, e) usbhsf_irq_callback_ctrl(p, bempsts, e) | |
159 | #define usbhsf_irq_ready_ctrl(p, e) usbhsf_irq_callback_ctrl(p, brdysts, e) | |
160 | #define usbhsf_irq_callback_ctrl(pipe, status, enable) \ | |
161 | ({ \ | |
162 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); \ | |
163 | struct usbhs_mod *mod = usbhs_mod_get_current(priv); \ | |
164 | u16 status = (1 << usbhs_pipe_number(pipe)); \ | |
165 | if (!mod) \ | |
166 | return; \ | |
167 | if (enable) \ | |
168 | mod->irq_##status |= status; \ | |
169 | else \ | |
170 | mod->irq_##status &= ~status; \ | |
171 | usbhs_irq_callback_update(priv, mod); \ | |
172 | }) | |
173 | ||
174 | static void usbhsf_tx_irq_ctrl(struct usbhs_pipe *pipe, int enable) | |
175 | { | |
176 | /* | |
177 | * And DCP pipe can NOT use "ready interrupt" for "send" | |
178 | * it should use "empty" interrupt. | |
179 | * see | |
180 | * "Operation" - "Interrupt Function" - "BRDY Interrupt" | |
181 | * | |
182 | * on the other hand, normal pipe can use "ready interrupt" for "send" | |
183 | * even though it is single/double buffer | |
184 | */ | |
185 | if (usbhs_pipe_is_dcp(pipe)) | |
186 | usbhsf_irq_empty_ctrl(pipe, enable); | |
187 | else | |
188 | usbhsf_irq_ready_ctrl(pipe, enable); | |
189 | } | |
190 | ||
191 | static void usbhsf_rx_irq_ctrl(struct usbhs_pipe *pipe, int enable) | |
192 | { | |
193 | usbhsf_irq_ready_ctrl(pipe, enable); | |
194 | } | |
195 | ||
e8d548d5 KM |
196 | /* |
197 | * FIFO ctrl | |
198 | */ | |
d3af90a5 KM |
199 | static void usbhsf_send_terminator(struct usbhs_pipe *pipe, |
200 | struct usbhs_fifo *fifo) | |
e8d548d5 KM |
201 | { |
202 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); | |
203 | ||
d3af90a5 | 204 | usbhs_bset(priv, fifo->ctr, BVAL, BVAL); |
e8d548d5 KM |
205 | } |
206 | ||
d3af90a5 KM |
207 | static int usbhsf_fifo_barrier(struct usbhs_priv *priv, |
208 | struct usbhs_fifo *fifo) | |
e8d548d5 KM |
209 | { |
210 | int timeout = 1024; | |
211 | ||
212 | do { | |
213 | /* The FIFO port is accessible */ | |
d3af90a5 | 214 | if (usbhs_read(priv, fifo->ctr) & FRDY) |
e8d548d5 KM |
215 | return 0; |
216 | ||
217 | udelay(10); | |
218 | } while (timeout--); | |
219 | ||
220 | return -EBUSY; | |
221 | } | |
222 | ||
d3af90a5 KM |
223 | static void usbhsf_fifo_clear(struct usbhs_pipe *pipe, |
224 | struct usbhs_fifo *fifo) | |
e8d548d5 KM |
225 | { |
226 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); | |
227 | ||
228 | if (!usbhs_pipe_is_dcp(pipe)) | |
d3af90a5 | 229 | usbhsf_fifo_barrier(priv, fifo); |
e8d548d5 | 230 | |
d3af90a5 | 231 | usbhs_write(priv, fifo->ctr, BCLR); |
e8d548d5 KM |
232 | } |
233 | ||
d3af90a5 KM |
234 | static int usbhsf_fifo_rcv_len(struct usbhs_priv *priv, |
235 | struct usbhs_fifo *fifo) | |
e8d548d5 | 236 | { |
d3af90a5 | 237 | return usbhs_read(priv, fifo->ctr) & DTLN_MASK; |
e8d548d5 KM |
238 | } |
239 | ||
d3af90a5 KM |
240 | static int usbhsf_fifo_select(struct usbhs_pipe *pipe, |
241 | struct usbhs_fifo *fifo, | |
242 | int write) | |
e8d548d5 KM |
243 | { |
244 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); | |
245 | struct device *dev = usbhs_priv_to_dev(priv); | |
246 | int timeout = 1024; | |
247 | u16 mask = ((1 << 5) | 0xF); /* mask of ISEL | CURPIPE */ | |
248 | u16 base = usbhs_pipe_number(pipe); /* CURPIPE */ | |
249 | ||
250 | if (usbhs_pipe_is_dcp(pipe)) | |
251 | base |= (1 == write) << 5; /* ISEL */ | |
252 | ||
253 | /* "base" will be used below */ | |
d3af90a5 | 254 | usbhs_write(priv, fifo->sel, base | MBW_32); |
e8d548d5 KM |
255 | |
256 | /* check ISEL and CURPIPE value */ | |
257 | while (timeout--) { | |
d3af90a5 | 258 | if (base == (mask & usbhs_read(priv, fifo->sel))) |
e8d548d5 KM |
259 | return 0; |
260 | udelay(10); | |
261 | } | |
262 | ||
263 | dev_err(dev, "fifo select error\n"); | |
264 | ||
265 | return -EIO; | |
266 | } | |
267 | ||
268 | /* | |
269 | * PIO fifo functions | |
270 | */ | |
97664a20 | 271 | static int usbhsf_try_push(struct usbhs_pkt *pkt, int *is_done) |
e8d548d5 | 272 | { |
4bd04811 | 273 | struct usbhs_pipe *pipe = pkt->pipe; |
e8d548d5 | 274 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); |
659d4954 | 275 | struct device *dev = usbhs_priv_to_dev(priv); |
d3af90a5 KM |
276 | struct usbhs_fifo *fifo = usbhsf_get_cfifo(priv); /* CFIFO */ |
277 | void __iomem *addr = priv->base + fifo->port; | |
659d4954 | 278 | u8 *buf; |
e8d548d5 KM |
279 | int maxp = usbhs_pipe_get_maxpacket(pipe); |
280 | int total_len; | |
4bd04811 | 281 | int i, ret, len; |
97664a20 | 282 | int is_short; |
e8d548d5 | 283 | |
d3af90a5 | 284 | ret = usbhsf_fifo_select(pipe, fifo, 1); |
e8d548d5 | 285 | if (ret < 0) |
659d4954 | 286 | goto usbhs_fifo_write_busy; |
e8d548d5 | 287 | |
dad67397 | 288 | ret = usbhs_pipe_is_accessible(pipe); |
e8d548d5 | 289 | if (ret < 0) |
659d4954 | 290 | goto usbhs_fifo_write_busy; |
e8d548d5 | 291 | |
d3af90a5 | 292 | ret = usbhsf_fifo_barrier(priv, fifo); |
e8d548d5 | 293 | if (ret < 0) |
659d4954 | 294 | goto usbhs_fifo_write_busy; |
e8d548d5 | 295 | |
659d4954 KM |
296 | buf = pkt->buf + pkt->actual; |
297 | len = pkt->length - pkt->actual; | |
298 | len = min(len, maxp); | |
299 | total_len = len; | |
300 | is_short = total_len < maxp; | |
e8d548d5 KM |
301 | |
302 | /* | |
303 | * FIXME | |
304 | * | |
305 | * 32-bit access only | |
306 | */ | |
659d4954 | 307 | if (len >= 4 && !((unsigned long)buf & 0x03)) { |
e8d548d5 KM |
308 | iowrite32_rep(addr, buf, len / 4); |
309 | len %= 4; | |
310 | buf += total_len - len; | |
311 | } | |
312 | ||
313 | /* the rest operation */ | |
314 | for (i = 0; i < len; i++) | |
315 | iowrite8(buf[i], addr + (0x03 - (i & 0x03))); | |
316 | ||
659d4954 KM |
317 | /* |
318 | * variable update | |
319 | */ | |
320 | pkt->actual += total_len; | |
321 | ||
322 | if (pkt->actual < pkt->length) | |
97664a20 | 323 | *is_done = 0; /* there are remainder data */ |
659d4954 | 324 | else if (is_short) |
97664a20 | 325 | *is_done = 1; /* short packet */ |
659d4954 | 326 | else |
97664a20 | 327 | *is_done = !pkt->zero; /* send zero packet ? */ |
659d4954 KM |
328 | |
329 | /* | |
330 | * pipe/irq handling | |
331 | */ | |
332 | if (is_short) | |
d3af90a5 | 333 | usbhsf_send_terminator(pipe, fifo); |
e8d548d5 | 334 | |
97664a20 | 335 | usbhsf_tx_irq_ctrl(pipe, !*is_done); |
4bd04811 KM |
336 | usbhs_pipe_enable(pipe); |
337 | ||
659d4954 KM |
338 | dev_dbg(dev, " send %d (%d/ %d/ %d/ %d)\n", |
339 | usbhs_pipe_number(pipe), | |
97664a20 | 340 | pkt->length, pkt->actual, *is_done, pkt->zero); |
659d4954 KM |
341 | |
342 | /* | |
343 | * Transmission end | |
344 | */ | |
97664a20 | 345 | if (*is_done) { |
659d4954 KM |
346 | if (usbhs_pipe_is_dcp(pipe)) |
347 | usbhs_dcp_control_transfer_done(pipe); | |
4bd04811 KM |
348 | } |
349 | ||
350 | return 0; | |
659d4954 KM |
351 | |
352 | usbhs_fifo_write_busy: | |
353 | /* | |
354 | * pipe is busy. | |
355 | * retry in interrupt | |
356 | */ | |
357 | usbhsf_tx_irq_ctrl(pipe, 1); | |
358 | ||
359 | return ret; | |
e8d548d5 KM |
360 | } |
361 | ||
dad67397 KM |
362 | struct usbhs_pkt_handle usbhs_fifo_push_handler = { |
363 | .prepare = usbhsf_try_push, | |
364 | .try_run = usbhsf_try_push, | |
365 | }; | |
366 | ||
97664a20 | 367 | static int usbhsf_prepare_pop(struct usbhs_pkt *pkt, int *is_done) |
e8d548d5 | 368 | { |
dad67397 | 369 | struct usbhs_pipe *pipe = pkt->pipe; |
d3af90a5 KM |
370 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); |
371 | struct usbhs_fifo *fifo = usbhsf_get_cfifo(priv); /* CFIFO */ | |
e8d548d5 KM |
372 | int ret; |
373 | ||
374 | /* | |
375 | * select pipe and enable it to prepare packet receive | |
376 | */ | |
d3af90a5 | 377 | ret = usbhsf_fifo_select(pipe, fifo, 0); |
e8d548d5 KM |
378 | if (ret < 0) |
379 | return ret; | |
380 | ||
381 | usbhs_pipe_enable(pipe); | |
659d4954 | 382 | usbhsf_rx_irq_ctrl(pipe, 1); |
e8d548d5 | 383 | |
d3af90a5 | 384 | return 0; |
e8d548d5 KM |
385 | } |
386 | ||
97664a20 | 387 | static int usbhsf_try_pop(struct usbhs_pkt *pkt, int *is_done) |
e8d548d5 | 388 | { |
4bd04811 | 389 | struct usbhs_pipe *pipe = pkt->pipe; |
e8d548d5 | 390 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); |
659d4954 | 391 | struct device *dev = usbhs_priv_to_dev(priv); |
d3af90a5 KM |
392 | struct usbhs_fifo *fifo = usbhsf_get_cfifo(priv); /* CFIFO */ |
393 | void __iomem *addr = priv->base + fifo->port; | |
659d4954 KM |
394 | u8 *buf; |
395 | u32 data = 0; | |
396 | int maxp = usbhs_pipe_get_maxpacket(pipe); | |
4bd04811 | 397 | int rcv_len, len; |
e8d548d5 | 398 | int i, ret; |
4bd04811 | 399 | int total_len = 0; |
e8d548d5 | 400 | |
d3af90a5 | 401 | ret = usbhsf_fifo_select(pipe, fifo, 0); |
e8d548d5 KM |
402 | if (ret < 0) |
403 | return ret; | |
404 | ||
d3af90a5 | 405 | ret = usbhsf_fifo_barrier(priv, fifo); |
e8d548d5 KM |
406 | if (ret < 0) |
407 | return ret; | |
408 | ||
d3af90a5 | 409 | rcv_len = usbhsf_fifo_rcv_len(priv, fifo); |
e8d548d5 | 410 | |
659d4954 KM |
411 | buf = pkt->buf + pkt->actual; |
412 | len = pkt->length - pkt->actual; | |
413 | len = min(len, rcv_len); | |
414 | total_len = len; | |
415 | ||
e8d548d5 KM |
416 | /* |
417 | * Buffer clear if Zero-Length packet | |
418 | * | |
419 | * see | |
420 | * "Operation" - "FIFO Buffer Memory" - "FIFO Port Function" | |
421 | */ | |
422 | if (0 == rcv_len) { | |
d3af90a5 | 423 | usbhsf_fifo_clear(pipe, fifo); |
4bd04811 | 424 | goto usbhs_fifo_read_end; |
e8d548d5 KM |
425 | } |
426 | ||
e8d548d5 KM |
427 | /* |
428 | * FIXME | |
429 | * | |
430 | * 32-bit access only | |
431 | */ | |
659d4954 | 432 | if (len >= 4 && !((unsigned long)buf & 0x03)) { |
e8d548d5 KM |
433 | ioread32_rep(addr, buf, len / 4); |
434 | len %= 4; | |
659d4954 | 435 | buf += total_len - len; |
e8d548d5 KM |
436 | } |
437 | ||
438 | /* the rest operation */ | |
439 | for (i = 0; i < len; i++) { | |
440 | if (!(i & 0x03)) | |
441 | data = ioread32(addr); | |
442 | ||
443 | buf[i] = (data >> ((i & 0x03) * 8)) & 0xff; | |
444 | } | |
445 | ||
659d4954 KM |
446 | pkt->actual += total_len; |
447 | ||
4bd04811 | 448 | usbhs_fifo_read_end: |
659d4954 | 449 | if ((pkt->actual == pkt->length) || /* receive all data */ |
97664a20 KM |
450 | (total_len < maxp)) { /* short packet */ |
451 | *is_done = 1; | |
659d4954 KM |
452 | usbhsf_rx_irq_ctrl(pipe, 0); |
453 | usbhs_pipe_disable(pipe); | |
4bd04811 KM |
454 | } |
455 | ||
97664a20 KM |
456 | dev_dbg(dev, " recv %d (%d/ %d/ %d/ %d)\n", |
457 | usbhs_pipe_number(pipe), | |
458 | pkt->length, pkt->actual, *is_done, pkt->zero); | |
459 | ||
4bd04811 | 460 | return 0; |
e8d548d5 | 461 | } |
dad67397 KM |
462 | |
463 | struct usbhs_pkt_handle usbhs_fifo_pop_handler = { | |
464 | .prepare = usbhsf_prepare_pop, | |
465 | .try_run = usbhsf_try_pop, | |
466 | }; | |
467 | ||
468 | /* | |
469 | * handler function | |
470 | */ | |
97664a20 | 471 | static int usbhsf_ctrl_stage_end(struct usbhs_pkt *pkt, int *is_done) |
dad67397 | 472 | { |
97664a20 | 473 | usbhs_dcp_control_transfer_done(pkt->pipe); |
dad67397 | 474 | |
97664a20 | 475 | *is_done = 1; |
dad67397 KM |
476 | |
477 | return 0; | |
478 | } | |
479 | ||
480 | struct usbhs_pkt_handle usbhs_ctrl_stage_end_handler = { | |
481 | .prepare = usbhsf_ctrl_stage_end, | |
482 | .try_run = usbhsf_ctrl_stage_end, | |
483 | }; | |
484 | ||
485 | /* | |
486 | * irq functions | |
487 | */ | |
488 | static int usbhsf_irq_empty(struct usbhs_priv *priv, | |
489 | struct usbhs_irq_state *irq_state) | |
490 | { | |
491 | struct usbhs_pipe *pipe; | |
dad67397 KM |
492 | struct device *dev = usbhs_priv_to_dev(priv); |
493 | int i, ret; | |
494 | ||
495 | if (!irq_state->bempsts) { | |
496 | dev_err(dev, "debug %s !!\n", __func__); | |
497 | return -EIO; | |
498 | } | |
499 | ||
500 | dev_dbg(dev, "irq empty [0x%04x]\n", irq_state->bempsts); | |
501 | ||
502 | /* | |
503 | * search interrupted "pipe" | |
504 | * not "uep". | |
505 | */ | |
506 | usbhs_for_each_pipe_with_dcp(pipe, priv, i) { | |
507 | if (!(irq_state->bempsts & (1 << i))) | |
508 | continue; | |
509 | ||
97664a20 | 510 | ret = usbhs_pkt_run(pipe); |
dad67397 KM |
511 | if (ret < 0) |
512 | dev_err(dev, "irq_empty run_error %d : %d\n", i, ret); | |
513 | } | |
514 | ||
515 | return 0; | |
516 | } | |
517 | ||
518 | static int usbhsf_irq_ready(struct usbhs_priv *priv, | |
519 | struct usbhs_irq_state *irq_state) | |
520 | { | |
521 | struct usbhs_pipe *pipe; | |
dad67397 KM |
522 | struct device *dev = usbhs_priv_to_dev(priv); |
523 | int i, ret; | |
524 | ||
525 | if (!irq_state->brdysts) { | |
526 | dev_err(dev, "debug %s !!\n", __func__); | |
527 | return -EIO; | |
528 | } | |
529 | ||
530 | dev_dbg(dev, "irq ready [0x%04x]\n", irq_state->brdysts); | |
531 | ||
532 | /* | |
533 | * search interrupted "pipe" | |
534 | * not "uep". | |
535 | */ | |
536 | usbhs_for_each_pipe_with_dcp(pipe, priv, i) { | |
537 | if (!(irq_state->brdysts & (1 << i))) | |
538 | continue; | |
539 | ||
97664a20 | 540 | ret = usbhs_pkt_run(pipe); |
dad67397 KM |
541 | if (ret < 0) |
542 | dev_err(dev, "irq_ready run_error %d : %d\n", i, ret); | |
543 | } | |
544 | ||
545 | return 0; | |
546 | } | |
547 | ||
548 | /* | |
549 | * fifo init | |
550 | */ | |
551 | void usbhs_fifo_init(struct usbhs_priv *priv) | |
552 | { | |
553 | struct usbhs_mod *mod = usbhs_mod_get_current(priv); | |
554 | ||
555 | mod->irq_empty = usbhsf_irq_empty; | |
556 | mod->irq_ready = usbhsf_irq_ready; | |
557 | mod->irq_bempsts = 0; | |
558 | mod->irq_brdysts = 0; | |
559 | } | |
560 | ||
561 | void usbhs_fifo_quit(struct usbhs_priv *priv) | |
562 | { | |
563 | struct usbhs_mod *mod = usbhs_mod_get_current(priv); | |
564 | ||
565 | mod->irq_empty = NULL; | |
566 | mod->irq_ready = NULL; | |
567 | mod->irq_bempsts = 0; | |
568 | mod->irq_brdysts = 0; | |
569 | } | |
d3af90a5 KM |
570 | |
571 | int usbhs_fifo_probe(struct usbhs_priv *priv) | |
572 | { | |
573 | struct usbhs_fifo *fifo; | |
574 | ||
575 | /* CFIFO */ | |
576 | fifo = usbhsf_get_cfifo(priv); | |
577 | fifo->port = CFIFO; | |
578 | fifo->sel = CFIFOSEL; | |
579 | fifo->ctr = CFIFOCTR; | |
580 | ||
581 | return 0; | |
582 | } | |
583 | ||
584 | void usbhs_fifo_remove(struct usbhs_priv *priv) | |
585 | { | |
586 | } |