diff options
author | Peter Chen <peter.chen@freescale.com> | 2013-08-14 05:44:10 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-08-14 15:37:19 -0400 |
commit | cbec6bd55a45fa88218ec5ea5ae91f9b96d158d0 (patch) | |
tree | e4fc86b0461913278f152ba9a2d6e562a8708ae7 /drivers/usb/chipidea | |
parent | c344b518008ada3170349d1c06e8a30224400b29 (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.c | 63 | ||||
-rw-r--r-- | drivers/usb/chipidea/otg.c | 57 | ||||
-rw-r--r-- | drivers/usb/chipidea/otg.h | 2 |
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 | */ | ||
301 | static 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 | */ | ||
315 | static 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 | |||
331 | static irqreturn_t ci_irq(int irq, void *data) | 297 | static 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 | ||
435 | static void ci_get_otg_capable(struct ci_hdrc *ci) | 403 | static 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); |
577 | stop: | 545 | stop: |
578 | ci_role_destroy(ci); | 546 | ci_role_destroy(ci); |
579 | rm_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 | */ | ||
30 | enum 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 | */ | ||
44 | static 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 | */ |
30 | int ci_hdrc_otg_init(struct ci_hdrc *ci) | 64 | int 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 | */ | ||
80 | void 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 | ||
30 | int ci_hdrc_otg_init(struct ci_hdrc *ci); | 30 | int ci_hdrc_otg_init(struct ci_hdrc *ci); |
31 | void ci_hdrc_otg_destroy(struct ci_hdrc *ci); | ||
32 | enum 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 */ |