aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/chipidea/core.c
diff options
context:
space:
mode:
authorPeter Chen <peter.chen@freescale.com>2013-08-14 05:44:11 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-08-14 15:37:20 -0400
commita107f8c505cd8606ae192d24c70b380e980fbe67 (patch)
treec1451c9051588fe93537c83c034d62def233ed8f /drivers/usb/chipidea/core.c
parentcbec6bd55a45fa88218ec5ea5ae91f9b96d158d0 (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.c28
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