]>
Commit | Line | Data |
---|---|---|
7b6513bc GKH |
1 | From 082df8be455ade361748f0385aa6c9c8d07be167 Mon Sep 17 00:00:00 2001 |
2 | From: Johan Hovold <johan@kernel.org> | |
3 | Date: Thu, 24 Aug 2017 11:38:36 -0500 | |
4 | Subject: USB: musb: fix external abort on suspend | |
5 | ||
6 | From: Johan Hovold <johan@kernel.org> | |
7 | ||
8 | commit 082df8be455ade361748f0385aa6c9c8d07be167 upstream. | |
9 | ||
10 | Make sure that the controller is runtime resumed when system suspending | |
11 | to avoid an external abort when accessing the interrupt registers: | |
12 | ||
13 | Unhandled fault: external abort on non-linefetch (0x1008) at 0xd025840a | |
14 | ... | |
15 | [<c05481a4>] (musb_default_readb) from [<c0545abc>] (musb_disable_interrupts+0x84/0xa8) | |
16 | [<c0545abc>] (musb_disable_interrupts) from [<c0546b08>] (musb_suspend+0x38/0xb8) | |
17 | [<c0546b08>] (musb_suspend) from [<c04a57f8>] (platform_pm_suspend+0x3c/0x64) | |
18 | ||
19 | This is easily reproduced on a BBB by enabling the peripheral port only | |
20 | (as the host port may enable the shared clock) and keeping it | |
21 | disconnected so that the controller is runtime suspended. (Well, you | |
22 | would also need to the not-yet-merged am33xx-suspend patches by Dave | |
23 | Gerlach to be able to suspend the BBB.) | |
24 | ||
25 | This is a regression that was introduced by commit 1c4d0b4e1806 ("usb: | |
26 | musb: Remove pm_runtime_set_irq_safe") which allowed the parent glue | |
27 | device to runtime suspend and thereby exposed a couple of older issues: | |
28 | ||
29 | Register accesses without explicitly making sure the controller is | |
30 | runtime resumed during suspend was first introduced by commit c338412b5ded | |
31 | ("usb: musb: unconditionally save and restore the context on suspend") | |
32 | in 3.14. | |
33 | ||
34 | Commit a1fc1920aaaa ("usb: musb: core: make sure musb is in RPM_ACTIVE on | |
35 | resume") later started setting the RPM status to active during resume, | |
36 | and this was also implicitly relying on the parent always being active. | |
37 | Since commit 71723f95463d ("PM / runtime: print error when activating a | |
38 | child to unactive parent") this now also results in the following | |
39 | warning: | |
40 | ||
41 | musb-hdrc musb-hdrc.0: runtime PM trying to activate child device | |
42 | musb-hdrc.0 but parent (47401400.usb) is not active | |
43 | ||
44 | This patch has been verified on 4.13-rc2, 4.12 and 4.9 using a BBB | |
45 | (the dsps glue would always be active also in 4.8). | |
46 | ||
47 | Fixes: c338412b5ded ("usb: musb: unconditionally save and restore the context on suspend") | |
48 | Fixes: a1fc1920aaaa ("usb: musb: core: make sure musb is in RPM_ACTIVE on resume") | |
49 | Fixes: 1c4d0b4e1806 ("usb: musb: Remove pm_runtime_set_irq_safe") | |
50 | Cc: Alan Stern <stern@rowland.harvard.edu> | |
51 | Cc: Daniel Mack <zonque@gmail.com> | |
52 | Cc: Dave Gerlach <d-gerlach@ti.com> | |
53 | Cc: Rafael J. Wysocki <rjw@rjwysocki.net> | |
54 | Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de> | |
55 | Cc: Tony Lindgren <tony@atomide.com> | |
56 | Signed-off-by: Johan Hovold <johan@kernel.org> | |
57 | Signed-off-by: Bin Liu <b-liu@ti.com> | |
58 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
59 | ||
60 | --- | |
61 | drivers/usb/musb/musb_core.c | 18 ++++++++++-------- | |
62 | 1 file changed, 10 insertions(+), 8 deletions(-) | |
63 | ||
64 | --- a/drivers/usb/musb/musb_core.c | |
65 | +++ b/drivers/usb/musb/musb_core.c | |
66 | @@ -2655,6 +2655,13 @@ static int musb_suspend(struct device *d | |
67 | { | |
68 | struct musb *musb = dev_to_musb(dev); | |
69 | unsigned long flags; | |
70 | + int ret; | |
71 | + | |
72 | + ret = pm_runtime_get_sync(dev); | |
73 | + if (ret < 0) { | |
74 | + pm_runtime_put_noidle(dev); | |
75 | + return ret; | |
76 | + } | |
77 | ||
78 | musb_platform_disable(musb); | |
79 | musb_generic_disable(musb); | |
80 | @@ -2703,14 +2710,6 @@ static int musb_resume(struct device *de | |
81 | if ((devctl & mask) != (musb->context.devctl & mask)) | |
82 | musb->port1_status = 0; | |
83 | ||
84 | - /* | |
85 | - * The USB HUB code expects the device to be in RPM_ACTIVE once it came | |
86 | - * out of suspend | |
87 | - */ | |
88 | - pm_runtime_disable(dev); | |
89 | - pm_runtime_set_active(dev); | |
90 | - pm_runtime_enable(dev); | |
91 | - | |
92 | musb_start(musb); | |
93 | ||
94 | spin_lock_irqsave(&musb->lock, flags); | |
95 | @@ -2720,6 +2719,9 @@ static int musb_resume(struct device *de | |
96 | error); | |
97 | spin_unlock_irqrestore(&musb->lock, flags); | |
98 | ||
99 | + pm_runtime_mark_last_busy(dev); | |
100 | + pm_runtime_put_autosuspend(dev); | |
101 | + | |
102 | return 0; | |
103 | } | |
104 |