aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/chipidea
diff options
context:
space:
mode:
authorPeter Chen <peter.chen@freescale.com>2013-08-14 05:44:10 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-08-14 15:37:19 -0400
commitcbec6bd55a45fa88218ec5ea5ae91f9b96d158d0 (patch)
treee4fc86b0461913278f152ba9a2d6e562a8708ae7 /drivers/usb/chipidea
parentc344b518008ada3170349d1c06e8a30224400b29 (diff)
usb: chipidea: move otg related things to otg file
Move otg related things to otg file. 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')
-rw-r--r--drivers/usb/chipidea/core.c63
-rw-r--r--drivers/usb/chipidea/otg.c57
-rw-r--r--drivers/usb/chipidea/otg.h2
3 files changed, 70 insertions, 52 deletions
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index e9cfd3193d65..ec6c984d2a6e 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -294,40 +294,6 @@ int hw_device_reset(struct ci_hdrc *ci, u32 mode)
294 return 0; 294 return 0;
295} 295}
296 296
297/**
298 * ci_otg_role - pick role based on ID pin state
299 * @ci: the controller
300 */
301static enum ci_role ci_otg_role(struct ci_hdrc *ci)
302{
303 u32 sts = hw_read(ci, OP_OTGSC, ~0);
304 enum ci_role role = sts & OTGSC_ID
305 ? CI_ROLE_GADGET
306 : CI_ROLE_HOST;
307
308 return role;
309}
310
311/**
312 * ci_role_work - perform role changing based on ID pin
313 * @work: work struct
314 */
315static void ci_role_work(struct work_struct *work)
316{
317 struct ci_hdrc *ci = container_of(work, struct ci_hdrc, work);
318 enum ci_role role = ci_otg_role(ci);
319
320 if (role != ci->role) {
321 dev_dbg(ci->dev, "switching from %s to %s\n",
322 ci_role(ci)->name, ci->roles[role]->name);
323
324 ci_role_stop(ci);
325 ci_role_start(ci, role);
326 }
327
328 enable_irq(ci->irq);
329}
330
331static irqreturn_t ci_irq(int irq, void *data) 297static irqreturn_t ci_irq(int irq, void *data)
332{ 298{
333 struct ci_hdrc *ci = data; 299 struct ci_hdrc *ci = data;
@@ -430,6 +396,8 @@ static inline void ci_role_destroy(struct ci_hdrc *ci)
430{ 396{
431 ci_hdrc_gadget_destroy(ci); 397 ci_hdrc_gadget_destroy(ci);
432 ci_hdrc_host_destroy(ci); 398 ci_hdrc_host_destroy(ci);
399 if (ci->is_otg)
400 ci_hdrc_otg_destroy(ci);
433} 401}
434 402
435static void ci_get_otg_capable(struct ci_hdrc *ci) 403static void ci_get_otg_capable(struct ci_hdrc *ci)
@@ -494,13 +462,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
494 return -ENODEV; 462 return -ENODEV;
495 } 463 }
496 464
497 INIT_WORK(&ci->work, ci_role_work);
498 ci->wq = create_singlethread_workqueue("ci_otg");
499 if (!ci->wq) {
500 dev_err(dev, "can't create workqueue\n");
501 return -ENODEV;
502 }
503
504 ci_get_otg_capable(ci); 465 ci_get_otg_capable(ci);
505 466
506 if (!ci->platdata->phy_mode) 467 if (!ci->platdata->phy_mode)
@@ -530,8 +491,15 @@ static int ci_hdrc_probe(struct platform_device *pdev)
530 491
531 if (!ci->roles[CI_ROLE_HOST] && !ci->roles[CI_ROLE_GADGET]) { 492 if (!ci->roles[CI_ROLE_HOST] && !ci->roles[CI_ROLE_GADGET]) {
532 dev_err(dev, "no supported roles\n"); 493 dev_err(dev, "no supported roles\n");
533 ret = -ENODEV; 494 return -ENODEV;
534 goto rm_wq; 495 }
496
497 if (ci->is_otg) {
498 ret = ci_hdrc_otg_init(ci);
499 if (ret) {
500 dev_err(dev, "init otg fails, ret = %d\n", ret);
501 goto stop;
502 }
535 } 503 }
536 504
537 if (ci->roles[CI_ROLE_HOST] && ci->roles[CI_ROLE_GADGET]) { 505 if (ci->roles[CI_ROLE_HOST] && ci->roles[CI_ROLE_GADGET]) {
@@ -542,7 +510,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
542 */ 510 */
543 mdelay(2); 511 mdelay(2);
544 ci->role = ci_otg_role(ci); 512 ci->role = ci_otg_role(ci);
545 ci_hdrc_otg_init(ci); 513 ci_enable_otg_interrupt(ci, OTGSC_IDIE);
546 } else { 514 } else {
547 /* 515 /*
548 * If the controller is not OTG capable, but support 516 * If the controller is not OTG capable, but support
@@ -560,7 +528,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
560 ret = ci_role_start(ci, ci->role); 528 ret = ci_role_start(ci, ci->role);
561 if (ret) { 529 if (ret) {
562 dev_err(dev, "can't start %s role\n", ci_role(ci)->name); 530 dev_err(dev, "can't start %s role\n", ci_role(ci)->name);
563 goto rm_wq; 531 goto stop;
564 } 532 }
565 533
566 platform_set_drvdata(pdev, ci); 534 platform_set_drvdata(pdev, ci);
@@ -576,9 +544,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
576 free_irq(ci->irq, ci); 544 free_irq(ci->irq, ci);
577stop: 545stop:
578 ci_role_destroy(ci); 546 ci_role_destroy(ci);
579rm_wq:
580 flush_workqueue(ci->wq);
581 destroy_workqueue(ci->wq);
582 547
583 return ret; 548 return ret;
584} 549}
@@ -588,8 +553,6 @@ static int ci_hdrc_remove(struct platform_device *pdev)
588 struct ci_hdrc *ci = platform_get_drvdata(pdev); 553 struct ci_hdrc *ci = platform_get_drvdata(pdev);
589 554
590 dbg_remove_files(ci); 555 dbg_remove_files(ci);
591 flush_workqueue(ci->wq);
592 destroy_workqueue(ci->wq);
593 free_irq(ci->irq, ci); 556 free_irq(ci->irq, ci);
594 ci_role_destroy(ci); 557 ci_role_destroy(ci);
595 558
diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
index 999a085491d7..3b66cbe58d52 100644
--- a/drivers/usb/chipidea/otg.c
+++ b/drivers/usb/chipidea/otg.c
@@ -24,12 +24,65 @@
24#include "otg.h" 24#include "otg.h"
25 25
26/** 26/**
27 * ci_hdrc_otg_init - initialize otgsc bits 27 * ci_otg_role - pick role based on ID pin state
28 * @ci: the controller
29 */
30enum ci_role ci_otg_role(struct ci_hdrc *ci)
31{
32 u32 sts = hw_read(ci, OP_OTGSC, ~0);
33 enum ci_role role = sts & OTGSC_ID
34 ? CI_ROLE_GADGET
35 : CI_ROLE_HOST;
36
37 return role;
38}
39
40/**
41 * ci_role_work - perform role changing based on ID pin
42 * @work: work struct
43 */
44static void ci_role_work(struct work_struct *work)
45{
46 struct ci_hdrc *ci = container_of(work, struct ci_hdrc, work);
47 enum ci_role role = ci_otg_role(ci);
48
49 if (role != ci->role) {
50 dev_dbg(ci->dev, "switching from %s to %s\n",
51 ci_role(ci)->name, ci->roles[role]->name);
52
53 ci_role_stop(ci);
54 ci_role_start(ci, role);
55 }
56
57 enable_irq(ci->irq);
58}
59
60/**
61 * ci_hdrc_otg_init - initialize otg struct
28 * ci: the controller 62 * ci: the controller
29 */ 63 */
30int ci_hdrc_otg_init(struct ci_hdrc *ci) 64int ci_hdrc_otg_init(struct ci_hdrc *ci)
31{ 65{
32 ci_enable_otg_interrupt(ci, OTGSC_IDIE); 66 INIT_WORK(&ci->work, ci_role_work);
67 ci->wq = create_singlethread_workqueue("ci_otg");
68 if (!ci->wq) {
69 dev_err(ci->dev, "can't create workqueue\n");
70 return -ENODEV;
71 }
33 72
34 return 0; 73 return 0;
35} 74}
75
76/**
77 * ci_hdrc_otg_destroy - destroy otg struct
78 * ci: the controller
79 */
80void ci_hdrc_otg_destroy(struct ci_hdrc *ci)
81{
82 if (ci->wq) {
83 flush_workqueue(ci->wq);
84 destroy_workqueue(ci->wq);
85 }
86 ci_disable_otg_interrupt(ci, OTGSC_INT_EN_BITS);
87 ci_clear_otg_interrupt(ci, OTGSC_INT_STATUS_BITS);
88}
diff --git a/drivers/usb/chipidea/otg.h b/drivers/usb/chipidea/otg.h
index 376eaee73042..8acf3df4e3e5 100644
--- a/drivers/usb/chipidea/otg.h
+++ b/drivers/usb/chipidea/otg.h
@@ -28,5 +28,7 @@ static inline void ci_disable_otg_interrupt(struct ci_hdrc *ci, u32 bits)
28} 28}
29 29
30int ci_hdrc_otg_init(struct ci_hdrc *ci); 30int ci_hdrc_otg_init(struct ci_hdrc *ci);
31void ci_hdrc_otg_destroy(struct ci_hdrc *ci);
32enum ci_role ci_otg_role(struct ci_hdrc *ci);
31 33
32#endif /* __DRIVERS_USB_CHIPIDEA_OTG_H */ 34#endif /* __DRIVERS_USB_CHIPIDEA_OTG_H */