diff options
author | Peter Chen <peter.chen@freescale.com> | 2013-08-14 05:44:11 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-08-14 15:37:20 -0400 |
commit | a107f8c505cd8606ae192d24c70b380e980fbe67 (patch) | |
tree | c1451c9051588fe93537c83c034d62def233ed8f /drivers/usb/chipidea/core.c | |
parent | cbec6bd55a45fa88218ec5ea5ae91f9b96d158d0 (diff) |
usb: chipidea: add vbus interrupt handler
We add vbus interrupt handler at ci_otg_work, it uses OTGSC_BSV(at otgsc)
to know it is connect or disconnet event.
Meanwhile, we introduce two flags id_event and b_sess_valid_event to
indicate it is an id interrupt or a vbus interrupt.
Tested-by: Marek Vasut <marex@denx.de>
Signed-off-by: Peter Chen <peter.chen@freescale.com>
Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/chipidea/core.c')
-rw-r--r-- | drivers/usb/chipidea/core.c | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index ec6c984d2a6e..c95e098fe9db 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c | |||
@@ -303,16 +303,34 @@ static irqreturn_t ci_irq(int irq, void *data) | |||
303 | if (ci->is_otg) | 303 | if (ci->is_otg) |
304 | otgsc = hw_read(ci, OP_OTGSC, ~0); | 304 | otgsc = hw_read(ci, OP_OTGSC, ~0); |
305 | 305 | ||
306 | if (ci->role != CI_ROLE_END) | 306 | /* |
307 | ret = ci_role(ci)->irq(ci); | 307 | * Handle id change interrupt, it indicates device/host function |
308 | * switch. | ||
309 | */ | ||
310 | if (ci->is_otg && (otgsc & OTGSC_IDIE) && (otgsc & OTGSC_IDIS)) { | ||
311 | ci->id_event = true; | ||
312 | ci_clear_otg_interrupt(ci, OTGSC_IDIS); | ||
313 | disable_irq_nosync(ci->irq); | ||
314 | queue_work(ci->wq, &ci->work); | ||
315 | return IRQ_HANDLED; | ||
316 | } | ||
308 | 317 | ||
309 | if (ci->is_otg && (otgsc & OTGSC_IDIS)) { | 318 | /* |
310 | hw_write(ci, OP_OTGSC, OTGSC_IDIS, OTGSC_IDIS); | 319 | * Handle vbus change interrupt, it indicates device connection |
320 | * and disconnection events. | ||
321 | */ | ||
322 | if (ci->is_otg && (otgsc & OTGSC_BSVIE) && (otgsc & OTGSC_BSVIS)) { | ||
323 | ci->b_sess_valid_event = true; | ||
324 | ci_clear_otg_interrupt(ci, OTGSC_BSVIS); | ||
311 | disable_irq_nosync(ci->irq); | 325 | disable_irq_nosync(ci->irq); |
312 | queue_work(ci->wq, &ci->work); | 326 | queue_work(ci->wq, &ci->work); |
313 | ret = IRQ_HANDLED; | 327 | return IRQ_HANDLED; |
314 | } | 328 | } |
315 | 329 | ||
330 | /* Handle device/host interrupt */ | ||
331 | if (ci->role != CI_ROLE_END) | ||
332 | ret = ci_role(ci)->irq(ci); | ||
333 | |||
316 | return ret; | 334 | return ret; |
317 | } | 335 | } |
318 | 336 | ||