diff options
author | Bin Liu <b-liu@ti.com> | 2017-01-10 11:46:00 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-01-19 14:18:01 -0500 |
commit | dfd48efcde844cd3710e05caf734484a974f32ea (patch) | |
tree | a0733a304ef1424288d6ada511940795d5f43eda | |
parent | 88d3670a1de4246cd40dfacdc21289b313caf5ed (diff) |
usb: musb: fix runtime PM in debugfs
commit 7b6c1b4c0e1e44544aa18161dba6a741c080a7ef upstream.
MUSB driver now has runtime PM support, but the debugfs driver misses
the PM _get/_put() calls, which could cause MUSB register access
failure.
Acked-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Bin Liu <b-liu@ti.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/usb/musb/musb_debugfs.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/drivers/usb/musb/musb_debugfs.c b/drivers/usb/musb/musb_debugfs.c index 9b22d946c089..534a3f6fa89c 100644 --- a/drivers/usb/musb/musb_debugfs.c +++ b/drivers/usb/musb/musb_debugfs.c | |||
@@ -114,6 +114,7 @@ static int musb_regdump_show(struct seq_file *s, void *unused) | |||
114 | unsigned i; | 114 | unsigned i; |
115 | 115 | ||
116 | seq_printf(s, "MUSB (M)HDRC Register Dump\n"); | 116 | seq_printf(s, "MUSB (M)HDRC Register Dump\n"); |
117 | pm_runtime_get_sync(musb->controller); | ||
117 | 118 | ||
118 | for (i = 0; i < ARRAY_SIZE(musb_regmap); i++) { | 119 | for (i = 0; i < ARRAY_SIZE(musb_regmap); i++) { |
119 | switch (musb_regmap[i].size) { | 120 | switch (musb_regmap[i].size) { |
@@ -132,6 +133,8 @@ static int musb_regdump_show(struct seq_file *s, void *unused) | |||
132 | } | 133 | } |
133 | } | 134 | } |
134 | 135 | ||
136 | pm_runtime_mark_last_busy(musb->controller); | ||
137 | pm_runtime_put_autosuspend(musb->controller); | ||
135 | return 0; | 138 | return 0; |
136 | } | 139 | } |
137 | 140 | ||
@@ -145,7 +148,10 @@ static int musb_test_mode_show(struct seq_file *s, void *unused) | |||
145 | struct musb *musb = s->private; | 148 | struct musb *musb = s->private; |
146 | unsigned test; | 149 | unsigned test; |
147 | 150 | ||
151 | pm_runtime_get_sync(musb->controller); | ||
148 | test = musb_readb(musb->mregs, MUSB_TESTMODE); | 152 | test = musb_readb(musb->mregs, MUSB_TESTMODE); |
153 | pm_runtime_mark_last_busy(musb->controller); | ||
154 | pm_runtime_put_autosuspend(musb->controller); | ||
149 | 155 | ||
150 | if (test & MUSB_TEST_FORCE_HOST) | 156 | if (test & MUSB_TEST_FORCE_HOST) |
151 | seq_printf(s, "force host\n"); | 157 | seq_printf(s, "force host\n"); |
@@ -194,11 +200,12 @@ static ssize_t musb_test_mode_write(struct file *file, | |||
194 | u8 test; | 200 | u8 test; |
195 | char buf[18]; | 201 | char buf[18]; |
196 | 202 | ||
203 | pm_runtime_get_sync(musb->controller); | ||
197 | test = musb_readb(musb->mregs, MUSB_TESTMODE); | 204 | test = musb_readb(musb->mregs, MUSB_TESTMODE); |
198 | if (test) { | 205 | if (test) { |
199 | dev_err(musb->controller, "Error: test mode is already set. " | 206 | dev_err(musb->controller, "Error: test mode is already set. " |
200 | "Please do USB Bus Reset to start a new test.\n"); | 207 | "Please do USB Bus Reset to start a new test.\n"); |
201 | return count; | 208 | goto ret; |
202 | } | 209 | } |
203 | 210 | ||
204 | memset(buf, 0x00, sizeof(buf)); | 211 | memset(buf, 0x00, sizeof(buf)); |
@@ -234,6 +241,9 @@ static ssize_t musb_test_mode_write(struct file *file, | |||
234 | 241 | ||
235 | musb_writeb(musb->mregs, MUSB_TESTMODE, test); | 242 | musb_writeb(musb->mregs, MUSB_TESTMODE, test); |
236 | 243 | ||
244 | ret: | ||
245 | pm_runtime_mark_last_busy(musb->controller); | ||
246 | pm_runtime_put_autosuspend(musb->controller); | ||
237 | return count; | 247 | return count; |
238 | } | 248 | } |
239 | 249 | ||
@@ -254,8 +264,13 @@ static int musb_softconnect_show(struct seq_file *s, void *unused) | |||
254 | switch (musb->xceiv->otg->state) { | 264 | switch (musb->xceiv->otg->state) { |
255 | case OTG_STATE_A_HOST: | 265 | case OTG_STATE_A_HOST: |
256 | case OTG_STATE_A_WAIT_BCON: | 266 | case OTG_STATE_A_WAIT_BCON: |
267 | pm_runtime_get_sync(musb->controller); | ||
268 | |||
257 | reg = musb_readb(musb->mregs, MUSB_DEVCTL); | 269 | reg = musb_readb(musb->mregs, MUSB_DEVCTL); |
258 | connect = reg & MUSB_DEVCTL_SESSION ? 1 : 0; | 270 | connect = reg & MUSB_DEVCTL_SESSION ? 1 : 0; |
271 | |||
272 | pm_runtime_mark_last_busy(musb->controller); | ||
273 | pm_runtime_put_autosuspend(musb->controller); | ||
259 | break; | 274 | break; |
260 | default: | 275 | default: |
261 | connect = -1; | 276 | connect = -1; |
@@ -284,6 +299,7 @@ static ssize_t musb_softconnect_write(struct file *file, | |||
284 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) | 299 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) |
285 | return -EFAULT; | 300 | return -EFAULT; |
286 | 301 | ||
302 | pm_runtime_get_sync(musb->controller); | ||
287 | if (!strncmp(buf, "0", 1)) { | 303 | if (!strncmp(buf, "0", 1)) { |
288 | switch (musb->xceiv->otg->state) { | 304 | switch (musb->xceiv->otg->state) { |
289 | case OTG_STATE_A_HOST: | 305 | case OTG_STATE_A_HOST: |
@@ -314,6 +330,8 @@ static ssize_t musb_softconnect_write(struct file *file, | |||
314 | } | 330 | } |
315 | } | 331 | } |
316 | 332 | ||
333 | pm_runtime_mark_last_busy(musb->controller); | ||
334 | pm_runtime_put_autosuspend(musb->controller); | ||
317 | return count; | 335 | return count; |
318 | } | 336 | } |
319 | 337 | ||