usb: chipidea: OTG HNP and SRP fsm implementation
[linux-2.6-block.git] / drivers / usb / chipidea / otg_fsm.c
CommitLineData
57677be5
LJ
1/*
2 * otg_fsm.c - ChipIdea USB IP core OTG FSM driver
3 *
4 * Copyright (C) 2014 Freescale Semiconductor, Inc.
5 *
6 * Author: Jun Li
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13/*
14 * This file mainly handles OTG fsm, it includes OTG fsm operations
15 * for HNP and SRP.
4dcf720c
LJ
16 *
17 * TODO List
18 * - ADP
19 * - OTG test device
57677be5
LJ
20 */
21
22#include <linux/usb/otg.h>
23#include <linux/usb/gadget.h>
24#include <linux/usb/hcd.h>
25#include <linux/usb/chipidea.h>
826cfe75 26#include <linux/regulator/consumer.h>
57677be5
LJ
27
28#include "ci.h"
29#include "bits.h"
30#include "otg.h"
31#include "otg_fsm.h"
32
e287b67b
LJ
33static struct ci_otg_fsm_timer *otg_timer_initializer
34(struct ci_hdrc *ci, void (*function)(void *, unsigned long),
35 unsigned long expires, unsigned long data)
36{
37 struct ci_otg_fsm_timer *timer;
38
39 timer = devm_kzalloc(ci->dev, sizeof(struct ci_otg_fsm_timer),
40 GFP_KERNEL);
41 if (!timer)
42 return NULL;
43 timer->function = function;
44 timer->expires = expires;
45 timer->data = data;
46 return timer;
47}
48
826cfe75
LJ
49/*
50 * Add timer to active timer list
51 */
52static void ci_otg_add_timer(struct ci_hdrc *ci, enum ci_otg_fsm_timer_index t)
53{
54 struct ci_otg_fsm_timer *tmp_timer;
55 struct ci_otg_fsm_timer *timer = ci->fsm_timer->timer_list[t];
56 struct list_head *active_timers = &ci->fsm_timer->active_timers;
57
58 if (t >= NUM_CI_OTG_FSM_TIMERS)
59 return;
60
61 /*
62 * Check if the timer is already in the active list,
63 * if so update timer count
64 */
65 list_for_each_entry(tmp_timer, active_timers, list)
66 if (tmp_timer == timer) {
67 timer->count = timer->expires;
68 return;
69 }
70
71 timer->count = timer->expires;
72 list_add_tail(&timer->list, active_timers);
73
74 /* Enable 1ms irq */
75 if (!(hw_read_otgsc(ci, OTGSC_1MSIE)))
76 hw_write_otgsc(ci, OTGSC_1MSIE, OTGSC_1MSIE);
77}
78
79/*
80 * Remove timer from active timer list
81 */
82static void ci_otg_del_timer(struct ci_hdrc *ci, enum ci_otg_fsm_timer_index t)
83{
84 struct ci_otg_fsm_timer *tmp_timer, *del_tmp;
85 struct ci_otg_fsm_timer *timer = ci->fsm_timer->timer_list[t];
86 struct list_head *active_timers = &ci->fsm_timer->active_timers;
87
88 if (t >= NUM_CI_OTG_FSM_TIMERS)
89 return;
90
91 list_for_each_entry_safe(tmp_timer, del_tmp, active_timers, list)
92 if (tmp_timer == timer)
93 list_del(&timer->list);
94
95 /* Disable 1ms irq if there is no any active timer */
96 if (list_empty(active_timers))
97 hw_write_otgsc(ci, OTGSC_1MSIE, 0);
98}
99
4dcf720c
LJ
100/*
101 * Reduce timer count by 1, and find timeout conditions.
102 * Called by otg 1ms timer interrupt
103 */
104static inline int ci_otg_tick_timer(struct ci_hdrc *ci)
105{
106 struct ci_otg_fsm_timer *tmp_timer, *del_tmp;
107 struct list_head *active_timers = &ci->fsm_timer->active_timers;
108 int expired = 0;
109
110 list_for_each_entry_safe(tmp_timer, del_tmp, active_timers, list) {
111 tmp_timer->count--;
112 /* check if timer expires */
113 if (!tmp_timer->count) {
114 list_del(&tmp_timer->list);
115 tmp_timer->function(ci, tmp_timer->data);
116 expired = 1;
117 }
118 }
119
120 /* disable 1ms irq if there is no any timer active */
121 if ((expired == 1) && list_empty(active_timers))
122 hw_write_otgsc(ci, OTGSC_1MSIE, 0);
123
124 return expired;
125}
126
e287b67b
LJ
127/* The timeout callback function to set time out bit */
128static void set_tmout(void *ptr, unsigned long indicator)
129{
130 *(int *)indicator = 1;
131}
132
133static void set_tmout_and_fsm(void *ptr, unsigned long indicator)
134{
135 struct ci_hdrc *ci = (struct ci_hdrc *)ptr;
136
137 set_tmout(ci, indicator);
138
139 disable_irq_nosync(ci->irq);
140 queue_work(ci->wq, &ci->work);
141}
142
143static void a_wait_vfall_tmout_func(void *ptr, unsigned long indicator)
144{
145 struct ci_hdrc *ci = (struct ci_hdrc *)ptr;
146
147 set_tmout(ci, indicator);
148 /* Disable port power */
149 hw_write(ci, OP_PORTSC, PORTSC_W1C_BITS | PORTSC_PP, 0);
150 /* Clear exsiting DP irq */
151 hw_write_otgsc(ci, OTGSC_DPIS, OTGSC_DPIS);
152 /* Enable data pulse irq */
153 hw_write_otgsc(ci, OTGSC_DPIE, OTGSC_DPIE);
154 disable_irq_nosync(ci->irq);
155 queue_work(ci->wq, &ci->work);
156}
157
158static void b_ase0_brst_tmout_func(void *ptr, unsigned long indicator)
159{
160 struct ci_hdrc *ci = (struct ci_hdrc *)ptr;
161
162 set_tmout(ci, indicator);
163 if (!hw_read_otgsc(ci, OTGSC_BSV))
164 ci->fsm.b_sess_vld = 0;
165
166 disable_irq_nosync(ci->irq);
167 queue_work(ci->wq, &ci->work);
168}
169
170static void b_ssend_srp_tmout_func(void *ptr, unsigned long indicator)
171{
172 struct ci_hdrc *ci = (struct ci_hdrc *)ptr;
173
174 set_tmout(ci, indicator);
175
176 /* only vbus fall below B_sess_vld in b_idle state */
177 if (ci->transceiver->state == OTG_STATE_B_IDLE) {
178 disable_irq_nosync(ci->irq);
179 queue_work(ci->wq, &ci->work);
180 }
181}
182
183static void b_sess_vld_tmout_func(void *ptr, unsigned long indicator)
184{
185 struct ci_hdrc *ci = (struct ci_hdrc *)ptr;
186
187 /* Check if A detached */
188 if (!(hw_read_otgsc(ci, OTGSC_BSV))) {
189 ci->fsm.b_sess_vld = 0;
190 ci_otg_add_timer(ci, B_SSEND_SRP);
191 disable_irq_nosync(ci->irq);
192 queue_work(ci->wq, &ci->work);
193 }
194}
195
196static void b_data_pulse_end(void *ptr, unsigned long indicator)
197{
198 struct ci_hdrc *ci = (struct ci_hdrc *)ptr;
199
200 ci->fsm.b_srp_done = 1;
201 ci->fsm.b_bus_req = 0;
202 if (ci->fsm.power_up)
203 ci->fsm.power_up = 0;
204
205 hw_write_otgsc(ci, OTGSC_HABA, 0);
206
207 disable_irq_nosync(ci->irq);
208 queue_work(ci->wq, &ci->work);
209}
210
211/* Initialize timers */
212static int ci_otg_init_timers(struct ci_hdrc *ci)
213{
214 struct otg_fsm *fsm = &ci->fsm;
215
216 /* FSM used timers */
217 ci->fsm_timer->timer_list[A_WAIT_VRISE] =
218 otg_timer_initializer(ci, &set_tmout_and_fsm, TA_WAIT_VRISE,
219 (unsigned long)&fsm->a_wait_vrise_tmout);
220 if (ci->fsm_timer->timer_list[A_WAIT_VRISE] == NULL)
221 return -ENOMEM;
222
223 ci->fsm_timer->timer_list[A_WAIT_VFALL] =
224 otg_timer_initializer(ci, &a_wait_vfall_tmout_func,
225 TA_WAIT_VFALL, (unsigned long)&fsm->a_wait_vfall_tmout);
226 if (ci->fsm_timer->timer_list[A_WAIT_VFALL] == NULL)
227 return -ENOMEM;
228
229 ci->fsm_timer->timer_list[A_WAIT_BCON] =
230 otg_timer_initializer(ci, &set_tmout_and_fsm, TA_WAIT_BCON,
231 (unsigned long)&fsm->a_wait_bcon_tmout);
232 if (ci->fsm_timer->timer_list[A_WAIT_BCON] == NULL)
233 return -ENOMEM;
234
235 ci->fsm_timer->timer_list[A_AIDL_BDIS] =
236 otg_timer_initializer(ci, &set_tmout_and_fsm, TA_AIDL_BDIS,
237 (unsigned long)&fsm->a_aidl_bdis_tmout);
238 if (ci->fsm_timer->timer_list[A_AIDL_BDIS] == NULL)
239 return -ENOMEM;
240
241 ci->fsm_timer->timer_list[A_BIDL_ADIS] =
242 otg_timer_initializer(ci, &set_tmout_and_fsm, TA_BIDL_ADIS,
243 (unsigned long)&fsm->a_bidl_adis_tmout);
244 if (ci->fsm_timer->timer_list[A_BIDL_ADIS] == NULL)
245 return -ENOMEM;
246
247 ci->fsm_timer->timer_list[B_ASE0_BRST] =
248 otg_timer_initializer(ci, &b_ase0_brst_tmout_func, TB_ASE0_BRST,
249 (unsigned long)&fsm->b_ase0_brst_tmout);
250 if (ci->fsm_timer->timer_list[B_ASE0_BRST] == NULL)
251 return -ENOMEM;
252
253 ci->fsm_timer->timer_list[B_SE0_SRP] =
254 otg_timer_initializer(ci, &set_tmout_and_fsm, TB_SE0_SRP,
255 (unsigned long)&fsm->b_se0_srp);
256 if (ci->fsm_timer->timer_list[B_SE0_SRP] == NULL)
257 return -ENOMEM;
258
259 ci->fsm_timer->timer_list[B_SSEND_SRP] =
260 otg_timer_initializer(ci, &b_ssend_srp_tmout_func, TB_SSEND_SRP,
261 (unsigned long)&fsm->b_ssend_srp);
262 if (ci->fsm_timer->timer_list[B_SSEND_SRP] == NULL)
263 return -ENOMEM;
264
265 ci->fsm_timer->timer_list[B_SRP_FAIL] =
266 otg_timer_initializer(ci, &set_tmout, TB_SRP_FAIL,
267 (unsigned long)&fsm->b_srp_done);
268 if (ci->fsm_timer->timer_list[B_SRP_FAIL] == NULL)
269 return -ENOMEM;
270
271 ci->fsm_timer->timer_list[B_DATA_PLS] =
272 otg_timer_initializer(ci, &b_data_pulse_end, TB_DATA_PLS, 0);
273 if (ci->fsm_timer->timer_list[B_DATA_PLS] == NULL)
274 return -ENOMEM;
275
276 ci->fsm_timer->timer_list[B_SESS_VLD] = otg_timer_initializer(ci,
277 &b_sess_vld_tmout_func, TB_SESS_VLD, 0);
278 if (ci->fsm_timer->timer_list[B_SESS_VLD] == NULL)
279 return -ENOMEM;
280
281 return 0;
282}
283
826cfe75
LJ
284/* -------------------------------------------------------------*/
285/* Operations that will be called from OTG Finite State Machine */
286/* -------------------------------------------------------------*/
287static void ci_otg_fsm_add_timer(struct otg_fsm *fsm, enum otg_fsm_timer t)
288{
289 struct ci_hdrc *ci = container_of(fsm, struct ci_hdrc, fsm);
290
291 if (t < NUM_OTG_FSM_TIMERS)
292 ci_otg_add_timer(ci, t);
293 return;
294}
295
296static void ci_otg_fsm_del_timer(struct otg_fsm *fsm, enum otg_fsm_timer t)
297{
298 struct ci_hdrc *ci = container_of(fsm, struct ci_hdrc, fsm);
299
300 if (t < NUM_OTG_FSM_TIMERS)
301 ci_otg_del_timer(ci, t);
302 return;
303}
304
305/*
306 * A-device drive vbus: turn on vbus regulator and enable port power
307 * Data pulse irq should be disabled while vbus is on.
308 */
309static void ci_otg_drv_vbus(struct otg_fsm *fsm, int on)
310{
311 int ret;
312 struct ci_hdrc *ci = container_of(fsm, struct ci_hdrc, fsm);
313
314 if (on) {
315 /* Enable power power */
316 hw_write(ci, OP_PORTSC, PORTSC_W1C_BITS | PORTSC_PP,
317 PORTSC_PP);
318 if (ci->platdata->reg_vbus) {
319 ret = regulator_enable(ci->platdata->reg_vbus);
320 if (ret) {
321 dev_err(ci->dev,
322 "Failed to enable vbus regulator, ret=%d\n",
323 ret);
324 return;
325 }
326 }
327 /* Disable data pulse irq */
328 hw_write_otgsc(ci, OTGSC_DPIE, 0);
329
330 fsm->a_srp_det = 0;
331 fsm->power_up = 0;
332 } else {
333 if (ci->platdata->reg_vbus)
334 regulator_disable(ci->platdata->reg_vbus);
335
336 fsm->a_bus_drop = 1;
337 fsm->a_bus_req = 0;
338 }
339}
340
341/*
342 * Control data line by Run Stop bit.
343 */
344static void ci_otg_loc_conn(struct otg_fsm *fsm, int on)
345{
346 struct ci_hdrc *ci = container_of(fsm, struct ci_hdrc, fsm);
347
348 if (on)
349 hw_write(ci, OP_USBCMD, USBCMD_RS, USBCMD_RS);
350 else
351 hw_write(ci, OP_USBCMD, USBCMD_RS, 0);
352}
353
354/*
355 * Generate SOF by host.
356 * This is controlled through suspend/resume the port.
357 * In host mode, controller will automatically send SOF.
358 * Suspend will block the data on the port.
359 */
360static void ci_otg_loc_sof(struct otg_fsm *fsm, int on)
361{
362 struct ci_hdrc *ci = container_of(fsm, struct ci_hdrc, fsm);
363
364 if (on)
365 hw_write(ci, OP_PORTSC, PORTSC_W1C_BITS | PORTSC_FPR,
366 PORTSC_FPR);
367 else
368 hw_write(ci, OP_PORTSC, PORTSC_W1C_BITS | PORTSC_SUSP,
369 PORTSC_SUSP);
370}
371
372/*
373 * Start SRP pulsing by data-line pulsing,
374 * no v-bus pulsing followed
375 */
376static void ci_otg_start_pulse(struct otg_fsm *fsm)
377{
378 struct ci_hdrc *ci = container_of(fsm, struct ci_hdrc, fsm);
379
380 /* Hardware Assistant Data pulse */
381 hw_write_otgsc(ci, OTGSC_HADP, OTGSC_HADP);
382
383 ci_otg_add_timer(ci, B_DATA_PLS);
384}
385
386static int ci_otg_start_host(struct otg_fsm *fsm, int on)
387{
388 struct ci_hdrc *ci = container_of(fsm, struct ci_hdrc, fsm);
389
390 mutex_unlock(&fsm->lock);
391 if (on) {
392 ci_role_stop(ci);
393 ci_role_start(ci, CI_ROLE_HOST);
394 } else {
395 ci_role_stop(ci);
396 hw_device_reset(ci, USBMODE_CM_DC);
397 ci_role_start(ci, CI_ROLE_GADGET);
398 }
399 mutex_lock(&fsm->lock);
400 return 0;
401}
402
403static int ci_otg_start_gadget(struct otg_fsm *fsm, int on)
404{
405 struct ci_hdrc *ci = container_of(fsm, struct ci_hdrc, fsm);
406
407 mutex_unlock(&fsm->lock);
408 if (on)
409 usb_gadget_vbus_connect(&ci->gadget);
410 else
411 usb_gadget_vbus_disconnect(&ci->gadget);
412 mutex_lock(&fsm->lock);
413
414 return 0;
415}
416
417static struct otg_fsm_ops ci_otg_ops = {
418 .drv_vbus = ci_otg_drv_vbus,
419 .loc_conn = ci_otg_loc_conn,
420 .loc_sof = ci_otg_loc_sof,
421 .start_pulse = ci_otg_start_pulse,
422 .add_timer = ci_otg_fsm_add_timer,
423 .del_timer = ci_otg_fsm_del_timer,
424 .start_host = ci_otg_start_host,
425 .start_gadget = ci_otg_start_gadget,
426};
427
4dcf720c
LJ
428int ci_otg_fsm_work(struct ci_hdrc *ci)
429{
430 /*
431 * Don't do fsm transition for B device
432 * when there is no gadget class driver
433 */
434 if (ci->fsm.id && !(ci->driver) &&
435 ci->transceiver->state < OTG_STATE_A_IDLE)
436 return 0;
437
438 if (otg_statemachine(&ci->fsm)) {
439 if (ci->transceiver->state == OTG_STATE_A_IDLE) {
440 /*
441 * Further state change for cases:
442 * a_idle to b_idle; or
443 * a_idle to a_wait_vrise due to ID change(1->0), so
444 * B-dev becomes A-dev can try to start new session
445 * consequently; or
446 * a_idle to a_wait_vrise when power up
447 */
448 if ((ci->fsm.id) || (ci->id_event) ||
449 (ci->fsm.power_up)) {
450 disable_irq_nosync(ci->irq);
451 queue_work(ci->wq, &ci->work);
452 }
453 if (ci->id_event)
454 ci->id_event = false;
455 } else if (ci->transceiver->state == OTG_STATE_B_IDLE) {
456 if (ci->fsm.b_sess_vld) {
457 ci->fsm.power_up = 0;
458 /*
459 * Further transite to b_periphearl state
460 * when register gadget driver with vbus on
461 */
462 disable_irq_nosync(ci->irq);
463 queue_work(ci->wq, &ci->work);
464 }
465 }
466 }
467 return 0;
468}
469
470/*
471 * Update fsm variables in each state if catching expected interrupts,
472 * called by otg fsm isr.
473 */
474static void ci_otg_fsm_event(struct ci_hdrc *ci)
475{
476 u32 intr_sts, otg_bsess_vld, port_conn;
477 struct otg_fsm *fsm = &ci->fsm;
478
479 intr_sts = hw_read_intr_status(ci);
480 otg_bsess_vld = hw_read_otgsc(ci, OTGSC_BSV);
481 port_conn = hw_read(ci, OP_PORTSC, PORTSC_CCS);
482
483 switch (ci->transceiver->state) {
484 case OTG_STATE_A_WAIT_BCON:
485 if (port_conn) {
486 fsm->b_conn = 1;
487 fsm->a_bus_req = 1;
488 disable_irq_nosync(ci->irq);
489 queue_work(ci->wq, &ci->work);
490 }
491 break;
492 case OTG_STATE_B_IDLE:
493 if (otg_bsess_vld && (intr_sts & USBi_PCI) && port_conn) {
494 fsm->b_sess_vld = 1;
495 disable_irq_nosync(ci->irq);
496 queue_work(ci->wq, &ci->work);
497 }
498 break;
499 case OTG_STATE_B_PERIPHERAL:
500 if ((intr_sts & USBi_SLI) && port_conn && otg_bsess_vld) {
501 fsm->a_bus_suspend = 1;
502 disable_irq_nosync(ci->irq);
503 queue_work(ci->wq, &ci->work);
504 } else if (intr_sts & USBi_PCI) {
505 if (fsm->a_bus_suspend == 1)
506 fsm->a_bus_suspend = 0;
507 }
508 break;
509 case OTG_STATE_B_HOST:
510 if ((intr_sts & USBi_PCI) && !port_conn) {
511 fsm->a_conn = 0;
512 fsm->b_bus_req = 0;
513 disable_irq_nosync(ci->irq);
514 queue_work(ci->wq, &ci->work);
515 ci_otg_add_timer(ci, B_SESS_VLD);
516 }
517 break;
518 case OTG_STATE_A_PERIPHERAL:
519 if (intr_sts & USBi_SLI) {
520 fsm->b_bus_suspend = 1;
521 /*
522 * Init a timer to know how long this suspend
523 * will contine, if time out, indicates B no longer
524 * wants to be host role
525 */
526 ci_otg_add_timer(ci, A_BIDL_ADIS);
527 }
528
529 if (intr_sts & USBi_URI)
530 ci_otg_del_timer(ci, A_BIDL_ADIS);
531
532 if (intr_sts & USBi_PCI) {
533 if (fsm->b_bus_suspend == 1) {
534 ci_otg_del_timer(ci, A_BIDL_ADIS);
535 fsm->b_bus_suspend = 0;
536 }
537 }
538 break;
539 case OTG_STATE_A_SUSPEND:
540 if ((intr_sts & USBi_PCI) && !port_conn) {
541 fsm->b_conn = 0;
542
543 /* if gadget driver is binded */
544 if (ci->driver) {
545 /* A device to be peripheral mode */
546 ci->gadget.is_a_peripheral = 1;
547 }
548 disable_irq_nosync(ci->irq);
549 queue_work(ci->wq, &ci->work);
550 }
551 break;
552 case OTG_STATE_A_HOST:
553 if ((intr_sts & USBi_PCI) && !port_conn) {
554 fsm->b_conn = 0;
555 disable_irq_nosync(ci->irq);
556 queue_work(ci->wq, &ci->work);
557 }
558 break;
559 case OTG_STATE_B_WAIT_ACON:
560 if ((intr_sts & USBi_PCI) && port_conn) {
561 fsm->a_conn = 1;
562 disable_irq_nosync(ci->irq);
563 queue_work(ci->wq, &ci->work);
564 }
565 break;
566 default:
567 break;
568 }
569}
570
571/*
572 * ci_otg_irq - otg fsm related irq handling
573 * and also update otg fsm variable by monitoring usb host and udc
574 * state change interrupts.
575 * @ci: ci_hdrc
576 */
577irqreturn_t ci_otg_fsm_irq(struct ci_hdrc *ci)
578{
579 irqreturn_t retval = IRQ_NONE;
580 u32 otgsc, otg_int_src = 0;
581 struct otg_fsm *fsm = &ci->fsm;
582
583 otgsc = hw_read_otgsc(ci, ~0);
584 otg_int_src = otgsc & OTGSC_INT_STATUS_BITS & (otgsc >> 8);
585 fsm->id = (otgsc & OTGSC_ID) ? 1 : 0;
586
587 if (otg_int_src) {
588 if (otg_int_src & OTGSC_1MSIS) {
589 hw_write_otgsc(ci, OTGSC_1MSIS, OTGSC_1MSIS);
590 retval = ci_otg_tick_timer(ci);
591 return IRQ_HANDLED;
592 } else if (otg_int_src & OTGSC_DPIS) {
593 hw_write_otgsc(ci, OTGSC_DPIS, OTGSC_DPIS);
594 fsm->a_srp_det = 1;
595 fsm->a_bus_drop = 0;
596 } else if (otg_int_src & OTGSC_IDIS) {
597 hw_write_otgsc(ci, OTGSC_IDIS, OTGSC_IDIS);
598 if (fsm->id == 0) {
599 fsm->a_bus_drop = 0;
600 fsm->a_bus_req = 1;
601 ci->id_event = true;
602 }
603 } else if (otg_int_src & OTGSC_BSVIS) {
604 hw_write_otgsc(ci, OTGSC_BSVIS, OTGSC_BSVIS);
605 if (otgsc & OTGSC_BSV) {
606 fsm->b_sess_vld = 1;
607 ci_otg_del_timer(ci, B_SSEND_SRP);
608 ci_otg_del_timer(ci, B_SRP_FAIL);
609 fsm->b_ssend_srp = 0;
610 } else {
611 fsm->b_sess_vld = 0;
612 if (fsm->id)
613 ci_otg_add_timer(ci, B_SSEND_SRP);
614 }
615 } else if (otg_int_src & OTGSC_AVVIS) {
616 hw_write_otgsc(ci, OTGSC_AVVIS, OTGSC_AVVIS);
617 if (otgsc & OTGSC_AVV) {
618 fsm->a_vbus_vld = 1;
619 } else {
620 fsm->a_vbus_vld = 0;
621 fsm->b_conn = 0;
622 }
623 }
624 disable_irq_nosync(ci->irq);
625 queue_work(ci->wq, &ci->work);
626 return IRQ_HANDLED;
627 }
628
629 ci_otg_fsm_event(ci);
630
631 return retval;
632}
633
634void ci_hdrc_otg_fsm_start(struct ci_hdrc *ci)
635{
636 disable_irq_nosync(ci->irq);
637 queue_work(ci->wq, &ci->work);
638}
639
57677be5
LJ
640int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci)
641{
e287b67b 642 int retval = 0;
57677be5
LJ
643 struct usb_otg *otg;
644
645 otg = devm_kzalloc(ci->dev,
646 sizeof(struct usb_otg), GFP_KERNEL);
647 if (!otg) {
648 dev_err(ci->dev,
649 "Failed to allocate usb_otg structure for ci hdrc otg!\n");
650 return -ENOMEM;
651 }
652
653 otg->phy = ci->transceiver;
654 otg->gadget = &ci->gadget;
655 ci->fsm.otg = otg;
656 ci->transceiver->otg = ci->fsm.otg;
657 ci->fsm.power_up = 1;
658 ci->fsm.id = hw_read_otgsc(ci, OTGSC_ID) ? 1 : 0;
659 ci->transceiver->state = OTG_STATE_UNDEFINED;
826cfe75 660 ci->fsm.ops = &ci_otg_ops;
57677be5
LJ
661
662 mutex_init(&ci->fsm.lock);
663
e287b67b
LJ
664 ci->fsm_timer = devm_kzalloc(ci->dev,
665 sizeof(struct ci_otg_fsm_timer_list), GFP_KERNEL);
666 if (!ci->fsm_timer) {
667 dev_err(ci->dev,
668 "Failed to allocate timer structure for ci hdrc otg!\n");
669 return -ENOMEM;
670 }
671
672 INIT_LIST_HEAD(&ci->fsm_timer->active_timers);
673 retval = ci_otg_init_timers(ci);
674 if (retval) {
675 dev_err(ci->dev, "Couldn't init OTG timers\n");
676 return retval;
677 }
678
57677be5
LJ
679 /* Enable A vbus valid irq */
680 hw_write_otgsc(ci, OTGSC_AVVIE, OTGSC_AVVIE);
681
682 if (ci->fsm.id) {
683 ci->fsm.b_ssend_srp =
684 hw_read_otgsc(ci, OTGSC_BSV) ? 0 : 1;
685 ci->fsm.b_sess_vld =
686 hw_read_otgsc(ci, OTGSC_BSV) ? 1 : 0;
687 /* Enable BSV irq */
688 hw_write_otgsc(ci, OTGSC_BSVIE, OTGSC_BSVIE);
689 }
690
691 return 0;
692}